CSL  6.0
Test_Panners.cpp
Go to the documentation of this file.
1 //
2 // Test_Panners.cpp -- C main functions for the basic CSL panner and mixer tests.
3 // See the copyright notice and acknowledgment of authors in the file COPYRIGHT
4 //
5 // This program simply reads the run_tests() function (at the bottom of this file)
6 // and executes a list of basic CSL tests
7 //
8 
9 #ifdef USE_JUCE
10  #include "Test_Support.h"
11 #else
12  #define USE_TEST_MAIN // use the main() function in test_support.h
13  #include "Test_Support.cpp" // include all of CSL core and the test support functions
14 #endif
15 
16 #define USE_CONVOLVER
17 
18 #ifdef USE_CONVOLVER
19 #include "Convolver.h" // FFT-based convolver
20 #include "Convolver2.h" // FFT-based convolver
21 #endif
22 
23 #include <unistd.h>
24 
25 /////////////////////// Here are the actual unit tests ////////////////////
26 
27 /// Pan a sine to stereo
28 
29 void testPan() {
30  Osc vox(440); // src sine
31  Osc lfo(0.2, 1, 0, CSL_PI); // position LFO
32  vox.setScale(0.3);
33  Panner pan(vox, lfo); // panner
34  logMsg("playing a panning sine...");
35  runTest(pan, 8);
36  logMsg("done.\n");
37 }
38 
39 /// Pan a sine to "N" channels
40 
41 void testN2MPan() {
42  Osc vox(440);
43  Osc lfoX(0.2, 1, 0, CSL_PI);
44  Osc lfoY(0.2, 1, 0, 0);
45  vox.setScale(0.3);
46  // NtoMPanner(UnitGenerator & i, UnitGenerator & pX, UnitGenerator & pY, float a, unsigned in_c, unsigned out_c, float spr);
47  NtoMPanner pan(vox, lfoX, lfoY, 1, 1, 2, 2); // a panner
48  logMsg("playing N-channel panning sine...");
49  runTest(pan, 5);
50  logMsg("done.\n");
51 }
52 
53 /// Test mixer -- really slow additive synthesis
54 
55 void testSineMixer() {
56  Osc vox1(431, 0.3); // create 4 scaled sine waves
57  Osc vox2(540, 0.1);
58  Osc vox3(890, 0.03);
59  Osc vox4(1280, 0.01);
60 // AR vol(5, 1, 1); // amplitude envelope
61 // Mixer mix(2, vol); // stereo mixer with envelope
62  Mixer mix(2); // create a stereo mixer
63  mix.addInput(vox1); // add the sines to the mixer
64  mix.addInput(vox2);
65  mix.addInput(vox3);
66  mix.addInput(vox4);
67  logMsg("playing mix of 4 sines...");
68  runTest(mix);
69  logMsg("mix done.\n");
70 }
71 
72 /// Pan and mix 2 sines
73 
74 void testPanMix() {
75  Osc vox1, vox2; // sources oscs
76  RandEnvelope env1(0.5, 80, 180); // random freq envelopes
77  RandEnvelope env2(0.5, 80, 180); // (frq, amp, offset, step)
78  vox1.setFrequency(env1); // set osc freq and scale
79  vox1.setScale(0.3);
80  vox2.setFrequency(env2);
81  vox2.setScale(0.3);
82  Osc lfo1(0.3), lfo2(0.5, 1, 0, CSL_PI);// position LFOs (out of phase)
83  Panner pan1(vox1, lfo1); // 2 panners
84  Panner pan2(vox2, lfo2);
85  Mixer mix(2); // stereo mixer
86  mix.addInput(pan1);
87  mix.addInput(pan2);
88  logMsg("playing mix of panning sins...");
89 #ifndef CSL_WINDOWS
90  srand(getpid()); // seed the rand generator -- UNIX SPECIFIC CODE HERE
91 #endif
92  runTest(mix, 15);
93  logMsg("done.\n");
94 }
95 
96 /// Pan and mix many sines
97 
98 void testBigPanMix() {
99  int num = 64; // # of layers
100  float scale = 3.0f / (float) num; // ampl scale
101  Mixer mix(2); // stereo mixer
102  for (int i = 0; i < num; i++) { // loop to add a panning, LFO-controlled osc to the mix
103  Osc * vox = new Osc();
104  RandEnvelope * env = new RandEnvelope(0.5, 80, 180);
105  vox->setFrequency(*env);
106  vox->setScale(scale);
107  Osc * lfo = new Osc(fRandM(0.5, 0.9), 1, 0, fRandM(0, CSL_PI));
108  Panner * pan = new Panner(*vox, *lfo);
109  mix.addInput(*pan);
110  }
111  logMsg("playing mix of %d panning sins...", num);
112 #ifndef CSL_WINDOWS
113  srand(getpid()); // seed the rand generator -- UNIX SPECIFIC CODE HERE
114 #endif
115  runTest(mix, 60);
116  logMsg("done.\n");
117  mix.deleteInputs(); // clean up
118 }
119 
120 /// Make a bank or 50 sines with random walk panners and glissandi
121 
122 void testOscBank() {
123  Mixer mix(2); // stereo mixer
124  for (unsigned i = 0; i < 50; i++) { // RandEnvelope(float frequency, float amplitude, float offset, float step);
125  RandEnvelope * pos = new RandEnvelope;
126  RandEnvelope * freq = new RandEnvelope(0.8, 200, 300, 20);
127 // Sine * vox = new Sine(110.0, 0.01); // use computed sine
128  Osc * vox = new Osc(110.0, 0.01); // use stored look-up table
129  vox->setFrequency(* freq);
130  Panner * pan = new Panner(* vox, * pos);
131  mix.addInput(pan);
132  }
133  logMsg("playing mix of panning sines...");
134 #ifndef CSL_WINDOWS
135  srand(getpid()); // seed the rand generator so we get different results -- UNIX SPECIFIC CODE HERE
136 #endif
137  runTest(mix, 60);
138  logMsg("done.\n");
139  mix.deleteInputs(); // clean up
140 }
141 
142 /// swap sound channels with a ChannelMappedBuffer InOut
143 /// Constructor: InOut(input, inChan, outChan, [ch-1 ... ch-outChan]);
144 
145 #include "InOut.h" /// Copy in-out plug
146 
147 void testCMapIO() {
148  Osc osc(220); // carrier to be enveloped
149  AR a_env(2, 0.6, 1.0); // AR constructor dur, att, rel
150  osc.setScale(a_env); // amplitude modulate the sine
151  Panner pan(osc, 0.0); // panner
152  InOut chanMap(pan, 2, 2, kNoProc, 2, 1); // swap stereo channels
153  logMsg("playing swapped sin...");
154  runTest(chanMap);
155  logMsg("done.\n");
156 }
157 
158 ////////// Convolution
159 
160 #ifdef USE_CONVOLVER_OLD
161 
162 void testConvolver() {
163  JSoundFile fi(CGestalt::dataFolder(), "rim3_L.aiff");
164  try {
165  fi.openForRead();
166  } catch (CException) {
167  logMsg(kLogError, "Cannot read sound file...");
168  return;
169  }
170  logMsg("playing sound file...");
171  fi.trigger();
172  runTest(fi);
173  logMsg("sound file player done.\n");
174  // Create convolver; FFT size will be block size * 2
175  Convolver cv(CGestalt::dataFolder(), "Quadraverb_large_L.aiff");
176  cv.setInput(fi);
177  logMsg("playing convolver...");
178  fi.trigger();
179  runTest(cv);
180  fi.trigger();
181  runTest(cv);
182  fi.close();
183  logMsg("convolver done.\n");
184 }
185 
186 #define IRLEN (44100 * 4) // 4 sec. IR
187 
188 void testConvolver2() {
189  WhiteNoise nois; // amplitude, offset
190  AR env(0.05, 0.0001, 0.049); // AR constructor dur, att, rel
191  nois.setScale(env); // amplitude modulate the sine
192 
193  logMsg("playing noise burst...");
194  env.trigger();
195  runTest(nois);
196  logMsg("done.\n");
197  // make a simple IR with a few echoes
198  Buffer buf(1, IRLEN);
199  buf.allocateBuffers();
200  float * samp = buf.buffer(0);
201  for (unsigned i = 0; i < IRLEN; i += 5000)
202  samp[i] = 1 / (1 + (sqrt(i) / 5000));
203  // Create convolver; FFT size will be block size * 2
204  Convolver cv(buf);
205  cv.setInput(nois);
206  logMsg("playing convolver...");
207  env.trigger();
208  runTest(cv);
209  env.trigger();
210  runTest(cv);
211  logMsg("convolver done.\n");
212 }
213 
214 void testConvolver3() {
215  WhiteNoise nois; // amplitude, offset
216  AR env(0.05, 0.0001, 0.049); // AR constructor dur, att, rel
217  nois.setScale(env); // amplitude modulate the sine
218 
219  logMsg("playing noise burst...");
220  env.trigger();
221  runTest(nois);
222  logMsg("done.\n");
223  Convolver cv(CGestalt::dataFolder(), "3.3s_LargeCathedral_mono.aiff");
224  cv.setInput(nois);
225  logMsg("playing convolver...");
226  env.trigger();
227  runTest(cv);
228  env.trigger();
229  runTest(nois);
230  env.trigger();
231  runTest(cv);
232  logMsg("convolver done.\n");
233 }
234 
235 #endif
236 
237 #ifndef CSL_WINDOWS
238 
239 /// Spatializer with HRTF
240 
241 #include "SpatialAudio.h"
242 #include "Binaural.h"
243 
244 /// Repeat a short test file moving in circles around the horizontal plane
245 
247  // Open a mono soundfile
248  SoundFile sndfile(CGestalt::dataFolder() + "splash_mono.aiff");
249  sndfile.dump();
250 
251  char folder[CSL_NAME_LEN]; // create HRTF data location
252  strcpy(folder, CGestalt::dataFolder().c_str()); // CSL data folder location
253  strcat(folder, "IRCAM_HRTF/512_DB/HRTF_1047.dat"); // HRTF data location
254  HRTFDatabase::Reload(folder); // Load the HRTF data
255  HRTFDatabase::Database()->dump();
256 
257  // make the sound "Positionable"
258  SpatialSource source(sndfile);
259  // Create a spatializer.
260  Spatializer panner(kBinaural);
261  // Add the sound source to it
262  panner.addSource(source);
263  // loop to play transpositions
264  logMsg("playing HRTF-spatialized rotating sound source (horizontal plane)...");
265  theIO->setRoot(panner); // make some sound
266 
267  for (int i = 0; i < 30; i++) {
268  source.setPosition('s', (float) (i * 24), 0.0f, 2.0f); // rotate in small steps
269  source.dump();
270  sndfile.trigger();
271  sleepSec(0.8);
272  }
273  theIO->clearRoot();
274  logMsg("done.");
275 }
276 
277 /// Repeat a short test file moving in circles around the vertical plane at AZ = CSL_PIHALF
278 /// (axial plane in line with your ears, easy to localize)
279 
281  // Open a mono soundfile
282  SoundFile sndfile(CGestalt::dataFolder() + "guanno_mono.aiff");
283  sndfile.dump();
284  // make the sound "Positionable"
285  SpatialSource source(sndfile);
286  // Create a spatializer.
287  Spatializer panner(kBinaural);
288  // Add the sound source to it
289  panner.addSource(source);
290  // loop to play transpositions
291  logMsg("playing HRTF-spatialized rotating sound source (vertical plane)...");
292  theIO->setRoot(panner); // make some sound
293  for (int i = 30; i > 6; i--) {
294  source.setPosition('s', CSL_PIHALF, (float) (i * 15), 2.0f); // rotate in small steps
295  source.dump();
296  sndfile.trigger();
297  sleepSec(0.8);
298  }
299  theIO->clearRoot();
300  logMsg("done.");
301 }
302 
303 /// Repeat a short test file moving in circles around the vertical plane at AZ = 0
304 /// (median plane between your ears, hard to localize)
305 
307  // Open a mono soundfile
308  SoundFile sndfile(CGestalt::dataFolder() + "triangle_mono.aiff");
309  sndfile.openForRead(true);
310  sndfile.dump();
311  sndfile.setToEnd();
312  // make the sound "Positionable"
313  SpatialSource source(sndfile);
314  // Create a spatializer.
315  Spatializer panner(kBinaural);
316  // Add the sound source to it
317  panner.addSource(source);
318  // loop to play transpositions
319  logMsg("playing HRTF-spatialized rotating sound source (medial plane)...");
320  theIO->setRoot(panner); // make some sound
321  for (int i = 30; i > 6; i--) {
322  source.setPosition('s', 0.0f, (float) (i * 15), 2.0f); // rotate in small steps
323  source.dump();
324  sndfile.trigger();
325  sleepSec(0.8);
326  }
327  theIO->clearRoot();
328  logMsg("done.");
329 }
330 
331 /// Spatializer with Ambisonics
332 
334  // Open a mono soundfile
335  SoundFile sndfile(CGestalt::dataFolder() + "triangle_mono.aiff");
336  sndfile.dump();
337  // make the sound "Positionable"
338  SpatialSource source(sndfile);
339  // Create a spatializer.
340  Spatializer panner(kAmbisonic);
341  // Add the sound source to it
342  panner.addSource(source);
343  // loop to play transpositions
344  logMsg("playing Ambisonic-spatialized rotating sound source (horizontal plane)...");
345  theIO->setRoot(panner); // make some sound
346  for (int i = 0; i < 30; i++) {
347  source.setPosition('s', (float) (i * 24), 0.0f, 2.0f); // rotate in small steps
348  source.dump();
349  sndfile.trigger();
350  sleepSec(0.8);
351  }
352  theIO->clearRoot();
353  logMsg("done.");
354 }
355 
356 /// Spatializer with simple panners & filters and/or reverb
357 
358 void test_SimpleP() {
359  // Open a mono soundfile
360  SoundFile sndfile(CGestalt::dataFolder() + "Piano_A5_mf_mono.aiff");
361  sndfile.dump();
362  // make the sound "Positionable"
363  SpatialSource source(sndfile);
364  // Create a "simple" spatializer.
365  Spatializer panner(kSimple);
366  // Add the sound source to it
367  panner.addSource(source);
368  // loop to play transpositions
369  logMsg("playing simply spatialized rotating sound source...");
370  Mixer mix(2);
371  mix.addInput(panner);
372  theIO->setRoot(mix); // make some sound
373  for (int i = 0; i < 30; i++) {
374  // rotate in small steps, getting farther away
375  source.setPosition('s', (float) (i * 24.0f), 0.0f, (2.0f + (i * 0.15f)));
376  source.dump();
377  sndfile.trigger();
378  sleepSec(0.9);
379  }
380  theIO->clearRoot();
381  logMsg("done.");
382 }
383 
384 /// Spatializer with VBAP
385 
387  // Open a mono soundfile
388  SoundFile sndfile(CGestalt::dataFolder() + "triangle_mono.aiff");
389  sndfile.openForRead(true);
390  sndfile.dump();
391  sndfile.setToEnd();
392  // make the sound "Positionable"
393  SpatialSource source(sndfile);
394  // Create a spatializer.
395  Spatializer panner(kVBAP);
396  // Add the sound source to it
397  panner.addSource(source);
398  // loop to play transpositions
399  logMsg("playing VBAP-spatialized rotating sound source (horizontal plane)...");
400  theIO->setRoot(panner); // make some sound
401  for (int i = 0; i < 30; i++) {
402  source.setPosition('s', (float) (i * 24), 0.0f, 2.0f); // rotate in small steps
403  source.dump();
404  sndfile.trigger();
405  sleepSec(0.8);
406  }
407  theIO->clearRoot();
408  logMsg("done.");
409 }
410 
411 /// NEW (1905) Convolver
412 
413 //#define IR_FILE "/Content/Code/CSL/CSL_Data/impulse.aiff"
414 //#define IR_FILE "/Content/Code/CSL/CSL_Data/impulse2.aiff"
415 //#define IR_FILE "/Content/Code/CSL/CSL_Data/Large3.3sCathedral_mono.aiff"
416 //#define IR_FILE "/Content/Code/CSL/CSL_Data/5.6s_Gothic Church.aiff" // stereo IR
417 #define IR_FILE "/Content/Code/CSL/CSL_Data/7.0s_Cathedral C.aiff"
418 
419 // 400-tap 800-1200 Hz BPF
420 
421 float test_IR[400] = {
422  0.000115321, 3.6737e-05, 4.1587e-05, 4.60227e-05, 4.98864e-05, 5.29159e-05, 5.49895e-05, 5.58942e-05, 5.55457e-05,
423  5.36663e-05, 5.01198e-05, 4.46702e-05, 3.75496e-05, 2.84695e-05, 1.72398e-05, 4.32139e-06, -1.05814e-05, -2.70865e-05,
424  -4.5164e-05, -6.44729e-05, -8.47828e-05, -0.000105662, -0.0001268, -0.00014773, -0.000168014, -0.000187043, -0.000204465,
425  -0.00021964, -0.000232086, -0.000241318, -0.000246827, -0.000248233, -0.000245146, -0.000237276, -0.000224392, -0.0002064,
426  -0.000183281, -0.000155108, -0.000122088, -8.45941e-05, -4.30158e-05, 2.01944e-06, 4.98645e-05, 9.97062e-05, 0.000150644,
427  0.000201698, 0.000251824, 0.000299918, 0.000344833, 0.000385437, 0.000420621, 0.000449288, 0.000470436, 0.000483164,
428  0.000486657, 0.000480307, 0.000463611, 0.000436301, 0.00039829, 0.000349742, 0.000291022, 0.000222748, 0.000145778,
429  6.12089e-05, -2.96601e-05, -0.000125284, -0.000223972, -0.000323836, -0.000422867, -0.000518974, -0.000609991, -0.000693752,
430  -0.000768108, -0.000831012, -0.000880526, -0.000914892, -0.000932579, -0.000932317, -0.00091314, -0.000874445, -0.000815971,
431  -0.000737887, -0.000640763, -0.000525601, -0.000393824, -0.000247279, -8.82151e-05, 8.07491e-05, 0.000256652, 0.000436239,
432  0.000616023, 0.000792325, 0.000961359, 0.00111931, 0.0012624, 0.00138695, 0.00148951, 0.00156691, 0.00161633, 0.0016354,
433  0.00162226, 0.00157561, 0.00149478, 0.00137979, 0.00123132, 0.00105081, 0.000840386, 0.000602914, 0.000341936, 6.16378e-05,
434  -0.000233194, -0.000537263, -0.000844827, -0.00114981, -0.0014459, -0.00172668, -0.00198573, -0.00221678, -0.00241383,
435  -0.00257131, -0.00268415, -0.00274799, -0.00275922, -0.00271515, -0.00261406, -0.00245529, -0.00223935, -0.00196787,
436  -0.00164369, -0.00127085, -0.000854537, -0.000401045, 8.22805e-05, 0.000587166, 0.00110451, 0.00162453, 0.00213693,
437  0.00263108, 0.00309619, 0.00352153, 0.00389664, 0.0042115, 0.00445684, 0.00462426, 0.00470647, 0.00469748, 0.00459276,
438  0.00438943, 0.00408636, 0.00368426, 0.00318581, 0.00259565, 0.00192042, 0.00116873, 0.000351074, -0.000520217, -0.00143115,
439  -0.00236624, -0.00330864, -0.00424048, -0.00514303, -0.00599699, -0.00678285, -0.00748112, -0.00807269, -0.00853916,
440  -0.00886316, -0.00902861, -0.00902113, -0.00882822, -0.00843959, -0.00784736, -0.00704628, -0.00603386, -0.00481056,
441  -0.0033798, -0.00174805, 7.5225e-05, 0.00207758, 0.00424374, 0.0065557, 0.00899298, 0.0115328, 0.0141505, 0.0168196,
442  0.0195123, 0.0222, 0.0248534, 0.0274431, 0.0299398, 0.032315, 0.0345414, 0.0365927, 0.0384449, 0.040076, 0.0414664,
443  0.0425994, 0.0434614, 0.044042, 0.044334, 0.044334, 0.044042, 0.0434614, 0.0425994, 0.0414664, 0.040076, 0.0384449,
444  0.0365927, 0.0345414, 0.032315, 0.0299398, 0.0274431, 0.0248534, 0.0222, 0.0195123, 0.0168196, 0.0141505, 0.0115328,
445  0.00899298, 0.0065557, 0.00424374, 0.00207758, 7.5225e-05, -0.00174805, -0.0033798, -0.00481056, -0.00603386, -0.00704628,
446  -0.00784736, -0.00843959, -0.00882822, -0.00902113, -0.00902861, -0.00886316, -0.00853916, -0.00807269, -0.00748112,
447  -0.00678285, -0.00599699, -0.00514303, -0.00424048, -0.00330864, -0.00236624, -0.00143115, -0.000520217, 0.000351074,
448  0.00116873, 0.00192042, 0.00259565, 0.00318581, 0.00368426, 0.00408636, 0.00438943, 0.00459276, 0.00469748, 0.00470647,
449  0.00462426, 0.00445684, 0.0042115, 0.00389664, 0.00352153, 0.00309619, 0.00263108, 0.00213693, 0.00162453, 0.00110451,
450  0.000587166, 8.22805e-05, -0.000401045, -0.000854537, -0.00127085, -0.00164369, -0.00196787, -0.00223935, -0.00245529,
451  -0.00261406, -0.00271515, -0.00275922, -0.00274799, -0.00268415, -0.00257131, -0.00241383, -0.00221678, -0.00198573,
452  -0.00172668, -0.0014459, -0.00114981, -0.000844827, -0.000537263, -0.000233194, 6.16378e-05, 0.000341936, 0.000602914,
453  0.000840386, 0.00105081, 0.00123132, 0.00137979, 0.00149478, 0.00157561, 0.00162226, 0.0016354, 0.00161633, 0.00156691,
454  0.00148951, 0.00138695, 0.0012624, 0.00111931, 0.000961359, 0.000792325, 0.000616023, 0.000436239, 0.000256652, 8.07491e-05,
455  -8.82151e-05, -0.000247279, -0.000393824, -0.000525601, -0.000640763, -0.000737887, -0.000815971, -0.000874445, -0.00091314,
456  -0.000932317, -0.000932579, -0.000914892, -0.000880526, -0.000831012, -0.000768108, -0.000693752, -0.000609991, -0.000518974,
457  -0.000422867, -0.000323836, -0.000223972, -0.000125284, -2.96601e-05, 6.12089e-05, 0.000145778, 0.000222748, 0.000291022,
458  0.000349742, 0.00039829, 0.000436301, 0.000463611, 0.000480307, 0.000486657, 0.000483164, 0.000470436, 0.000449288,
459  0.000420621, 0.000385437, 0.000344833, 0.000299918, 0.000251824, 0.000201698, 0.000150644, 9.97062e-05, 4.98645e-05,
460  2.01944e-06, -4.30158e-05, -8.45941e-05, -0.000122088, -0.000155108, -0.000183281, -0.0002064, -0.000224392, -0.000237276,
461  -0.000245146, -0.000248233, -0.000246827, -0.000241318, -0.000232086, -0.00021964, -0.000204465, -0.000187043, -0.000168014,
462  -0.00014773, -0.0001268, -0.000105662, -8.47828e-05, -6.44729e-05, -4.5164e-05, -2.70865e-05, -1.05814e-05, 4.32139e-06,
463  1.72398e-05, 2.84695e-05, 3.75496e-05, 4.46702e-05, 5.01198e-05, 5.36663e-05, 5.55457e-05, 5.58942e-05, 5.49895e-05,
464  5.29159e-05, 4.98864e-05, 4.60227e-05, 4.1587e-05, 3.6737e-05, 0.000115321
465 };
466 
467 #define USE_SND_FILES
468 
469 void test_convolution() { // Make dual-mono soundfile chain
470  // drum rim shot as input
471  JSoundFile * sndfile1 = JSoundFile::openSndfile(string(CGestalt::dataFolder() + "rim3_L.aiff"));
472  JSoundFile * sndfile2 = JSoundFile::openSndfile(string(CGestalt::dataFolder() + "rim3_L.aiff"));
473 #ifdef USE_SND_FILES // read IR from a file - long reverb tail
474  Convolver2 conv1(*sndfile1, IR_FILE, 0, CGestalt::blockSize() * 2, true);
475  Convolver2 conv2(*sndfile2, IR_FILE, 1, CGestalt::blockSize() * 2, true);
476 #else // use a block of data (above) as the IR - narrow BP filter
477  Convolver2 conv1(*sndfile1, test_IR, 400, CGestalt::blockSize() * 2, true);
478  Convolver2 conv2(*sndfile2, test_IR, 400, CGestalt::blockSize() * 2, true);
479 #endif
480  Joiner join(conv1, conv2); // mono-to-stereo joiner
481  // loop to play transpositions
482  logMsg("playing convolved sound source...");
483  theIO->setRoot(join); // make some sound
484  for (int i = 0; i < 1000; i++) { // play a long time...
485  sndfile1->trigger();
486  sndfile2->trigger();
487  sleepSec(6.0);
488  }
489  theIO->clearRoot();
490  logMsg("done.");
491  delete sndfile1;
492  delete sndfile2;
493 }
494 
495 // ------------------------------------
496 
497 // helper fcn to load data from IR files - loads all the data for now - ToDo: load on-demand
498 
499 float * load_filter_data(char * fname, unsigned & siz) {
500  char * pos = strrchr(fname, '.');
501  if ( ! pos) {
502  logMsg(kLogError, "Can't parse filter file name %s ", fname);
503  return 0;
504  }
505  pos++;
506  if (strcmp(pos, "wav") == 0) { // 32-bit float WAV file
507  JSoundFile * inFile = JSoundFile::openSndfile(string(fname));
508  unsigned frames = inFile->duration(); // # of frames in IR
509  if ( ! frames) {
510  logMsg(kLogFatal, "Can't find IR file %s", fname);
511  }
512  inFile->mWavetable.mDidIAllocateBuffers = false;
513  SampleBuffer bfr = inFile->buffer(0);
514  siz = frames;
515  return bfr;
516  }
517  FILE * inF = fopen(fname, "rb");
518  fseek(inF, 0L, SEEK_END);
519  unsigned sz = (unsigned) ftell(inF);
520  rewind(inF);
521  if (strcmp(pos, "ir") == 0) { // raw data with text header
522  unsigned len, rat;
523  char lin[CSL_WORD_LEN];
524  fgets(lin, CSL_WORD_LEN, inF); // read/parse the simple header
525  int got = sscanf(lin, "%d %d", & len, & rat);
526  if (got != 2) {
527  logMsg(kLogError, "Can't read filter file header %s ", fname);
528  return 0;
529  }
530  SampleBuffer bfr;
531  SAFE_MALLOC(bfr, sample, len);
532  unsigned d0 = (unsigned) ftell(inF);
533  fread(bfr, sizeof(float), len, inF); // read float data
534  fclose(inF);
535  siz = len;
536  return bfr;
537  }
538  if (strcmp(pos, "bin") == 0) { // raw data
539  unsigned len = sz / sizeof(float);
540  SampleBuffer bfr;
541  SAFE_MALLOC(bfr, sample, len);
542  fread(bfr, sizeof(float), len, inF); // read float data
543  fclose(inF);
544  siz = len;
545  return bfr;
546  }
547  logMsg(kLogError, "Can't parse filter file name %s ", fname);
548  return 0;
549 }
550 
551 // test of IR file normalization
552 
553 void test_convolution_file(float * data, unsigned len) { // Make dual-mono soundfile chain
554  // drum rim shot as input
555  PinkNoise noise1(20.0f); // the sound source
556  PinkNoise noise2(20.0f); // the sound source
557  Joiner join(noise1, noise2); // mono-to-stereo joiner
558 // Convolver2 conv1(noise1, data, len, CGestalt::blockSize() * 2, true);
559 // Convolver2 conv2(noise2, data, len, CGestalt::blockSize() * 2, true);
560 // Joiner join(conv1, conv2); // mono-to-stereo joiner
561  // loop to play transpositions
562  logMsg("playing convolved sound source...");
563  theIO->capture_on(2.2);
564  theIO->setRoot(join); // make some sound
565  sleepSec(2.0);
566  theIO->clearRoot();
567  Buffer * bfr = theIO->get_capture();
568  float rms = bfr->rms(0, 0, theIO->mOffset);
569  theIO->capture_off();
570  logMsg("done: RMS = %g", rms);
571 }
572 
574  unsigned len;
575  float * data;
576  data = load_filter_data("/Content/Code/RoCoCo/App/RoCoCo/Source/IR_data/akg_k240s_44.wav", len);
577  test_convolution_file(data, len);
578  data = load_filter_data("/Content/Code/RoCoCo/App/RoCoCo/Source/IR_data/BD_DT880_44.wav", len);
579  test_convolution_file(data, len);
580  data = load_filter_data("/Content/Code/RoCoCo/App/RoCoCo/Source/IR_data/bp250_44.wav", len);
581  test_convolution_file(data, len);
582  data = load_filter_data("/Content/Code/RoCoCo/App/RoCoCo/Source/IR_data/bp250b_44.wav", len);
583  test_convolution_file(data, len);
584  data = load_filter_data("/Content/Code/RoCoCo/App/RoCoCo/Source/IR_data/bp1500_44.wav", len);
585  test_convolution_file(data, len);
586  data = load_filter_data("/Content/Code/RoCoCo/App/RoCoCo/Source/IR_data/bp1500b_44.wav", len);
587  test_convolution_file(data, len);
588 }
589 
590 // 0.00410895
591 // 0.0182053
592 // 0.0191255
593 // 0.0114013
594 // 0.101001
595 // 0.125591
596 
597 #endif // CSL_WINDOWS
598 
599 //////// RUN_TESTS Function ////////
600 
601 #ifndef USE_JUCE
602 
603 void runTests() {
604 // testPan();
605 // testN2MPan();
606 // testSineMixer();
607 // testPanMix();
608 // testConvolver();
609 // testConvolver2();
610 // testConvolver3();
611 // testOscBank();
612 // testCMapIO();
614 // test_Binaural_vertAxial();
615 // test_Binaural_vertMedian();
616 }
617 
618 #else
619 
620 // test list for Juce GUI
621 
623  "Stereo panner", testPan, "Demonstrate the stero panner",
624 // "N2M panner", testN2MPan,
625  "Mixer", testSineMixer, "Mixer with 4 sine inputs (slow sum-of-sines)",
626  "Panning mixer", testPanMix, "Play a panning stereo mixer",
627  "Bigger panning mixer", testBigPanMix, "Test a mixer with many inputs",
628 #ifdef USE_CONVOLVER_OLD
629  "Test convolver", testConvolver, "Test a convolver",
630  "Test convolver 2", testConvolver2, "Test a convolver",
631  "Test convolver 3", testConvolver3, "Test a convolver",
632 #endif
633  "Osc bank", testOscBank, "Mix a bank of oscillators",
634  "Channel-mapped IO", testCMapIO, "Demonstrate channel-mapped IO",
635 #ifndef CSL_WINDOWS
636  "HRTF horiz circles", test_Binaural_horiz, "Test the HRTF-based binaural panner",
637  "HRTF axial circles", test_Binaural_vertAxial,"Play a HRTF-panner with axial circles",
638  "HRTF median circles", test_Binaural_vertMedian,"Play a HRTF-panner with median circles",
639  "Ambisonics", test_Ambi_horiz, "Test the Ambisonic-based spatial panner",
640  "Simple", test_SimpleP, "Test the simple spatial panner",
641  "VBAP", test_VBAP_horiz, "Test the VBAP-based spatial panner",
642  "Convolver", test_convolution, "Test a convolver",
643  "Convolver Norm", test_convolution_files, "Test IR normalization",
644 #endif
645 NULL, NULL, NULL
646 };
647 
648 #endif
649 
sample * SampleBuffer
1-channel buffer data type, vector of (sample)
Definition: CSL_Types.h:194
InOut class copies the IO port's input buffer to the output buffer, possibly with channel remap and s...
Definition: InOut.h:37
void logMsg(const char *format,...)
These are the public logging messages.
Definition: CGestalt.cpp:292
void test_convolution()
void testOscBank()
Make a bank or 50 sines with random walk panners and glissandi.
void testPanMix()
Pan and mix 2 sines.
#define kNoProc
Definition: InOut.h:25
IO * theIO
Simple panning/filtering spatializer.
Definition: SpatialAudio.h:23
void testSineMixer()
Test mixer – really slow additive synthesis.
void test_Binaural_vertMedian()
Repeat a short test file moving in circles around the vertical plane at AZ = 0 (median plane between ...
void test_Ambi_horiz()
Spatializer with Ambisonics.
void addSource(SpatialSource &s)
Add a sound souce to the list of inputs to be processed.
#define IR_FILE
NEW (1905) Convolver.
unsigned duration() const
number of frames in the sound file
Definition: SoundFileJ.cpp:94
void test_convolution_files()
virtual void trigger()
reset to start
Definition: SoundFile.cpp:322
Vector Base Amplitude Panning.
Definition: SpatialAudio.h:21
White noise – equal power per frequency.
Definition: Noise.h:45
void test_convolution_file(float *data, unsigned len)
void runTests()
void test_Binaural_horiz()
Spatializer with HRTF.
struct used for the JUCE pop-up menu of tests (see the test files)
Definition: CSL_Types.h:265
void testPan()
Pan a sine to stereo.
#define CSL_PI
Definition: CSL_Types.h:334
JUCE sound file.
Definition: SoundFileJ.h:19
void testN2MPan()
Pan a sine to "N" channels.
void testBigPanMix()
Pan and mix many sines.
#define CSL_NAME_LEN
default string length
Definition: CSL_Types.h:121
float fRandM(float minV, float maxV)
min - max (min/max)
Definition: CGestalt.cpp:426
Temp Spatial Sound Source.
Definition: SpatialSource.h:29
float sample
(could be changed to int, or double)
Definition: CSL_Types.h:191
The Convolver is a CSL Effect.
Definition: Convolver.h:24
float rms(unsigned chan, unsigned from, unsigned to)
Buffer Sample Processing (optional). One could also easily add Buffer operators, such as (Buffer + Bu...
Definition: CSL_Core.cpp:465
#define Osc
Definition: CSL_Types.h:169
float test_IR[400]
bool sleepSec(float dur)
Definition: CGestalt.cpp:379
static unsigned len
Definition: fft_N.c:39
virtual SampleBuffer buffer(unsigned bufNum)
Definition: SoundFile.h:134
Buffer mWavetable
the stored wave form
Definition: Oscillator.h:84
void test_VBAP_horiz()
Spatializer with VBAP.
unsigned mOffset
used for capture offset
Definition: CSL_Core.h:793
void runTest(UnitGenerator &vox, double dur)
#define CSL_WORD_LEN
default short string length
Definition: CSL_Types.h:119
virtual void capture_off()
end output capture
Definition: CSL_Core.cpp:1544
float * load_filter_data(char *fname, unsigned &siz)
void test_SimpleP()
Spatializer with simple panners & filters and/or reverb.
RandEnvelope envelope class – makes random control signals using a single line segment.
Definition: Envelope.h:247
bool mDidIAllocateBuffers
who allocated my data buffers?
Definition: CSL_Core.h:121
void setRoot(UnitGenerator &root)
set/clear my graph root generator
Definition: CSL_Core.cpp:1405
Buffer – the multi-channel sample buffer class (passed around between generators and IO guys)...
Definition: CSL_Core.h:106
void testCMapIO()
swap sound channels with a ChannelMappedBuffer InOut Constructor: InOut(input, inChan, outChan, [ch-1 ... ch-outChan]);
The Convolver2 is a CSL Effect.
Definition: Convolver2.h:24
Mixer – The n-input m-channel mixer class.
Definition: Mixer.h:21
void test_Binaural_vertAxial()
Repeat a short test file moving in circles around the vertical plane at AZ = CSL_PIHALF (axial plane ...
virtual void setPosition(CPoint pos)
Set the sound source position in cartesian coordinates.
void clearRoot()
Definition: CSL_Core.cpp:1410
Joiner class – a multiplexer for multi-channel signals.
Definition: CSL_Core.h:648
AR = 3-segment attack/release envelope class.
Definition: Envelope.h:199
The CSL mono-to-stereo L/R panner class.
Definition: Mixer.h:66
#define CSL_PIHALF
Definition: CSL_Types.h:337
void addInput(UnitGenerator &inp)
Definition: Mixer.cpp:43
testStruct panTestList[]
void setScale(UnitGenerator &scale)
set the receiver's scale member to a UGen or a float
Definition: CSL_Core.cpp:1039
virtual void capture_on(float dur)
test the IO's graph
Definition: CSL_Core.cpp:1536
void deleteInputs()
Definition: Mixer.cpp:114
void dump()
pretty-print the receiver
Container class that simplifies the spatial audio interface. This layer hides most of the inner-worki...
Definition: SpatialAudio.h:31
Full 3D Ambisonics.
Definition: SpatialAudio.h:22
virtual Buffer * get_capture()
answer the capture buffer
Definition: CSL_Core.cpp:1550
#define SAFE_MALLOC(ptr, type, len)
Useful Macros.
Definition: CGestalt.h:103
Pink noise – equal power per octave.
Definition: Noise.h:66
Base class of CSL exceptions (written upper-case). Has a string message.
HRTF 2-channel panning.
Definition: SpatialAudio.h:20