Does anybody know of good (3D) ambisonics extensions for Pure Data?
I'm trying to setup some ambisonics examples for students in a small studio (8 speaker cube), so a simple 1st order panner and decoder object should be fine.
It seems like there are ambisonics libraries available in pd-extended, but I can't see how they actually work - i.e. where is the b-format encoder and decoder objects?
Check out the hoalibrary
You can download it here
I'm still looking for example projects -- I'll update if I find any.
Update 1:
Ambilib
This pd library is sweet. It comes with a bunch of good sample projects in the help folder.
Here's basic 1st order ambisonic panner and decoder objects for an 8 speaker cube configuration. I've also put these objects on GitHub with some examples. The code snippets below should be put into separate .pd files!
Panner:
#N canvas 66 87 448 490 10;
#X obj 32 421 outlet~;
#X obj 141 421 outlet~;
#X obj 244 421 outlet~;
#X obj 324 421 outlet~;
#X obj 27 61 inlet~;
#X obj 32 336 /~ 1.41421;
#X obj 131 61 inlet;
#X obj 304 61 inlet;
#X text 27 37 signal;
#X text 131 37 azimuth (theta);
#X text 304 37 elevation (phi);
#X text 32 446 W;
#X text 141 446 X;
#X text 244 446 Y;
#X text 324 446 Z;
#X obj 134 179 cos;
#X obj 173 179 sin;
#X obj 307 179 cos;
#X obj 336 179 sin;
#X obj 141 336 *~;
#X obj 243 336 *~;
#X obj 324 336 *~;
#X obj 219 64 loadbang;
#X obj 131 87 \$1;
#X obj 304 87 \$2;
#X obj 141 362 *~;
#X obj 243 362 *~;
#X obj 131 123 * 3.14159;
#X obj 304 120 * 1.57079;
#X connect 4 0 5 0;
#X connect 4 0 19 0;
#X connect 4 0 21 0;
#X connect 4 0 20 0;
#X connect 5 0 0 0;
#X connect 6 0 23 0;
#X connect 7 0 24 0;
#X connect 15 0 19 1;
#X connect 16 0 20 1;
#X connect 17 0 25 1;
#X connect 17 0 26 1;
#X connect 18 0 21 1;
#X connect 19 0 25 0;
#X connect 20 0 26 0;
#X connect 21 0 3 0;
#X connect 22 0 23 0;
#X connect 22 0 24 0;
#X connect 23 0 27 0;
#X connect 24 0 28 0;
#X connect 25 0 1 0;
#X connect 26 0 2 0;
#X connect 27 0 15 0;
#X connect 27 0 16 0;
#X connect 28 0 17 0;
#X connect 28 0 18 0;
Decoder:
#N canvas 42 77 788 411 10;
#X obj 199 25 inlet~;
#X obj 303 29 inlet~;
#X obj 415 29 inlet~;
#X obj 538 26 inlet~;
#X text 199 5 W;
#X text 303 9 X;
#X text 415 9 Y;
#X text 538 6 Z;
#X obj 21 333 outlet~;
#X obj 123 333 outlet~;
#X obj 219 331 outlet~;
#X obj 318 331 outlet~;
#X obj 21 177 +~;
#X obj 215 177 -~;
#X obj 404 331 outlet~;
#X obj 506 331 outlet~;
#X obj 602 329 outlet~;
#X obj 701 329 outlet~;
#X text 21 359 LFU;
#X text 123 359 LBU;
#X text 219 357 RBU;
#X text 318 357 RFU;
#X text 404 357 LFD;
#X text 506 357 LBD;
#X text 602 355 RBD;
#X text 701 355 RFD;
#X obj 403 180 +~;
#X obj 600 180 -~;
#X obj 404 220 +~;
#X obj 601 220 -~;
#X obj 21 217 +~;
#X obj 215 217 -~;
#X obj 21 269 +~;
#X obj 122 177 -~;
#X obj 303 56 *~ 0.25;
#X obj 414 58 *~ 0.25;
#X obj 538 56 *~ 0.1768;
#X obj 199 55 *~ 0.1768;
#X obj 124 269 +~;
#X obj 219 269 +~;
#X obj 317 269 +~;
#X obj 404 267 -~;
#X obj 507 267 -~;
#X obj 602 267 -~;
#X obj 700 267 -~;
#X obj 317 217 -~;
#X obj 507 220 +~;
#X obj 695 220 -~;
#X obj 122 217 +~;
#X obj 317 177 +~;
#X obj 506 180 -~;
#X obj 694 180 +~;
#X connect 0 0 37 0;
#X connect 1 0 34 0;
#X connect 2 0 35 0;
#X connect 3 0 36 0;
#X connect 12 0 30 0;
#X connect 13 0 31 0;
#X connect 26 0 28 0;
#X connect 27 0 29 0;
#X connect 28 0 41 0;
#X connect 29 0 43 0;
#X connect 30 0 32 0;
#X connect 31 0 39 0;
#X connect 32 0 8 0;
#X connect 33 0 48 0;
#X connect 34 0 12 1;
#X connect 34 0 13 1;
#X connect 34 0 26 1;
#X connect 34 0 27 1;
#X connect 34 0 33 1;
#X connect 34 0 49 1;
#X connect 34 0 50 1;
#X connect 34 0 51 1;
#X connect 35 0 30 1;
#X connect 35 0 31 1;
#X connect 35 0 28 1;
#X connect 35 0 29 1;
#X connect 35 0 45 1;
#X connect 35 0 46 1;
#X connect 35 0 47 1;
#X connect 35 0 48 1;
#X connect 36 0 32 1;
#X connect 36 0 38 1;
#X connect 36 0 39 1;
#X connect 36 0 40 1;
#X connect 36 0 41 1;
#X connect 36 0 42 1;
#X connect 36 0 43 1;
#X connect 36 0 44 1;
#X connect 37 0 12 0;
#X connect 37 0 13 0;
#X connect 37 0 26 0;
#X connect 37 0 27 0;
#X connect 37 0 33 0;
#X connect 37 0 49 0;
#X connect 37 0 50 0;
#X connect 37 0 51 0;
#X connect 38 0 9 0;
#X connect 39 0 10 0;
#X connect 40 0 11 0;
#X connect 41 0 14 0;
#X connect 42 0 15 0;
#X connect 43 0 16 0;
#X connect 44 0 17 0;
#X connect 45 0 40 0;
#X connect 46 0 42 0;
#X connect 47 0 44 0;
#X connect 48 0 38 0;
#X connect 49 0 45 0;
#X connect 50 0 46 0;
#X connect 51 0 47 0;
There's helpful discussions about making ambisonic decoders in this paper:
Heller, Aaron, Richard Lee, and Eric Benjamin. "Is my decoder ambisonic?." Audio Engineering Society Convention 125. Audio Engineering Society, 2008.
APA
I've put the code from that paper ("Is My Decoder...") and a number of newer design techniques into a MATLAB/Octave toolbox. The toolbox writes out ambisonic decoders in the Faust DSP specification language, which can then be compiled to Pd externals (and many other plugin formats, like VST, Max/MSP, LV2, ...). The code is in a git repo at
https://bitbucket.org/ambidecodertoolbox/adt. I'm sorry that there are no simple-to-follow instructions for the code, but feel free to contact me with questions. The toolbox is described in our LAC2014 paper.
Related
I have used the unique command to get the unique pixel intensities from my image. Then I tried to make a histogram using them, but it doesn't use all of the intensity values
I = imread('pout.tif');
[rows, columns] = size(I);
UniquePixels=unique(I);
hist=histogram(UniquePixels)
An alternative approach would be to use accumarray combined with unique. I would specifically use the third output of unique to transform your data into a consecutive sequence of 1 up to N where N is the total number of unique intensities, then leverage the first output of unique that will give you the list of unique intensities. Therefore, if the first output of unique is A and the output of accumarray is B, the effect is that at location B(i), this gives the total number of intensities of A(i).
Therefore:
[UniquePixels, ~, id] = unique(I);
histo = accumarray(id, 1);
UniquePixels gives you all unique pixels while histo gives you the counts of each unique pixel corresponding to each element in UniquePixels.
Here's a quick example:
>> I = randi(255, 10, 10)
I =
42 115 28 111 218 107 199 60 140 237
203 22 246 233 159 13 100 91 76 198
80 59 2 47 90 231 62 210 190 125
135 233 198 68 131 241 103 4 49 112
43 39 209 38 103 126 25 11 176 114
154 211 222 35 20 125 34 44 47 79
68 138 22 222 62 87 241 166 94 130
167 255 102 148 32 230 244 187 160 131
176 20 67 141 47 95 147 166 199 209
191 113 205 37 62 29 16 115 21 203
>> [UniquePixels, ~, id] = unique(I);
>> histo = accumarray(id, 1);
>> [UniquePixels histo]
ans =
2 1
4 1
11 1
13 1
16 1
20 2
21 1
22 2
25 1
28 1
29 1
32 1
34 1
35 1
37 1
38 1
39 1
42 1
43 1
44 1
47 3
49 1
59 1
60 1
62 3
67 1
68 2
76 1
79 1
80 1
87 1
90 1
91 1
94 1
95 1
100 1
102 1
103 2
107 1
111 1
112 1
113 1
114 1
115 2
125 2
126 1
130 1
131 2
135 1
138 1
140 1
141 1
147 1
148 1
154 1
159 1
160 1
166 2
167 1
176 2
187 1
190 1
191 1
198 2
199 2
203 2
205 1
209 2
210 1
211 1
218 1
222 2
230 1
231 1
233 2
237 1
241 2
244 1
246 1
255 1
If you double check the input example and the final output, you will see that only the unique pixels are shown combined with their counts. Any bins that were zero in count are not shown.
I have this matrix:
A =[22 22 142 142 142 92 92 92 0 0
0 109 109 151 151 151 23 23 149 149
0 0 0 152 152 152 38 38 0 0
0 13 13 113 113 113 119 119 119 0
0 8 8 8 84 84 14 14 14 0
0 0 144 144 144 0 0 0 66 66
139 139 139 34 34 34 0 0 0 0
0 0 64 64 64 128 128 59 59 59
83 83 83 65 65 65 67 67 67 0];
How can I find indices (row, column) from matrix with zero value respectively 2 or more?
You can use find as follows:
[r,c] = find(A==0)
[rows,cols] = ind2sub(size(A),find(A==0))
find gives you the indices and ind2sub converts them in column-row format.
I matrix
A = [123 123 123 99 99 99 32 32 32 40
40 40 22 22 34 34 34 152 152 152
92 92 92 91 91 91 146 146 146 119
3 3 96 96 96 136 136 136 68 68
]
B = [40 68 119]
How can I replace with zero value from A that have same value with B. required result:
C = [123 123 123 99 99 99 32 32 32 0
0 0 22 22 34 34 34 152 152 152
92 92 92 91 91 91 146 146 146 0
3 3 96 96 96 136 136 136 0 0
]
thank you...
Use ismember to obtain a logical mask of values of A that are in B, and then use that as a logical index to make those entries zero:
C = A; % define C equal to A
C(ismember(A,B)) = 0; % make elements from B equal to 0
Or, in a single line: multiply A by a mask that equals 1 for elements not in B and 0 for elements in B:
C = A.*~ismember(A,B); % multiply A by a mask to make elements from B equal to 0
I'd start down this road:
C = A;
for i = 1:numel(B)
C(C == B(i)) = 0;
end
The third line uses logical indexing - C == 20 is a logical matrix, true where the element is 20, false otherwise, and C(C == 20) = 0 sets the true elements to 0.
I have two matrices in matlab,
> IRwindow =
>
> **183** 171 150 125 137
138 167 184 173 152
105 114 141 167 185
148 113 105 115 141
186 183 147 112 105
>
> ILwindow =
>
> **201** 170 165 177 203
181 174 167 169 189
154 150 156 168 181
187 175 158 131 144
173 186 183 167 141
I want to subtract these two matrices element-wise and get the result; for example for first element (183 - 201= -18 ) BUT the output for this element gives zero. the outcome result will be as below:
> IRwindow - ILwindow
ans =
**0** 1 0 0 0
0 0 17 4 0
0 0 0 0 4
0 0 0 0 0
13 0 0 0 0
how could I keep the real results? without getting zero for negatives in my result-matrix
Run the following example code:
%# Create random matrices
X = randi(100, 5, 5);
Y = randi(100, 5, 5);
%# Convert to strictly non-negative format
X = uint8(X);
Y = uint8(Y);
%# Perform subtractions
A = X - Y;
%# Convert to double format
X = double(X);
Y = double(Y);
%# Perform subtraction
B = X - Y;
For a given sample run:
A =
0 15 36 0 0
0 0 0 0 3
0 0 0 25 0
13 0 15 0 0
0 49 0 0 14
while:
B =
-8 15 36 -4 -65
0 -47 -45 -11 3
-18 -17 -11 25 -52
13 -53 15 -15 -1
-35 49 -47 -8 14
You will notice that all the negative numbers in A have been replaced by 0, while the negative numbers in B are displayed correctly.
Stated simply: if you use a numerical format that is not able to store negative numbers, then Matlab truncates at 0. The solution is to convert to a format that is able to accomodate "real" numbers (or a close approximation thereof) such as double, or perhaps in your case one of the int formats may be more appropriate, such as int8, int16, int32 or int64.
Another option is to use single or double on the subtraction in one line as follows:
ans=double(IRwindow-ILwindow)
I dont get the same problem as you: I have this code:
IRwindow = [
183 171 150 125 137
138 167 184 173 152
105 114 141 167 185
148 113 105 115 141
186 183 147 112 105]
ILwindow = [
201 170 165 177 203
181 174 167 169 189
154 150 156 168 181
187 175 158 131 144
173 186 183 167 141]
IRwindow - ILwindow
and i get this output:
IRwindow =
183 171 150 125 137
138 167 184 173 152
105 114 141 167 185
148 113 105 115 141
186 183 147 112 105
ILwindow =
201 170 165 177 203
181 174 167 169 189
154 150 156 168 181
187 175 158 131 144
173 186 183 167 141
ans =
-18 1 -15 -52 -66
-43 -7 17 4 -37
-49 -36 -15 -1 4
-39 -62 -53 -16 -3
13 -3 -36 -55 -36
Check that you are creating your matrices are being created properly (as doubles and not as unsigned integers).
I have a matrix 'eff_tot' with dimension (m x n) which I want to rearrange according to a matrix called 'matches' (e.g. [n2 n3; n4 n5]) and put all the collumns not specified in 'matches' at the end.
That is, I want to have [eff_tot(:,n2) eff_tot(:,n3) ; eff_tot(:,n4) eff_tot(:,n5) ; eff_tot(:,n1)].
That's all folks!
Taking the example in the first answer, what I would like to have is:
eff_tot =
81 15 45 15 24
44 86 11 14 42
92 63 97 87 5
19 36 1 58 91
27 52 78 55 95
82 41 0 0 0
87 8 0 0 0
9 24 0 0 0
40 13 0 0 0
26 19 0 0 0
Regards.
Create a vector listing the indices of all the columns in eff_tot and then use SETDIFF to determine which columns do not occur in [n2 n3 n4 n5]. These columns are the unmatched ones. Now concatenate the matched and unmatched column indices to create your column-reordered eff_tot matrix.
>> eff_tot = randi(100, 5, 7)
eff_tot =
45 82 81 15 15 41 24
11 87 44 14 86 8 42
97 9 92 87 63 24 5
1 40 19 58 36 13 91
78 26 27 55 52 19 95
>> n2 = 3; n3 = 5; n4 = 2; n5 = 6;
>> missingColumn = setdiff(1:size(eff_tot, 2), [n2 n3 n4 n5])
missingColumn =
1 4 7
>> eff_tot = [eff_tot(:,n2) eff_tot(:,n3) eff_tot(:,missingIndex); eff_tot(:,n4) eff_tot(:,n5) zeros(size(eff_tot, 1), length(missingIndex))];
eff_tot =
81 15 45 15 24
44 86 11 14 42
92 63 97 87 5
19 36 1 58 91
27 52 78 55 95
82 41 0 0 0
87 8 0 0 0
9 24 0 0 0
40 13 0 0 0
26 19 0 0 0