27#ifdef SAF_ENABLE_EXAMPLES_TESTS
30 int nSH, i, ch, framesize;
32 float leftEarEnergy, rightEarEnergy, direction_deg[2];
34 float** shSig, **binSig, **shSig_frame, **binSig_frame;
39 const int signalLength = fs*2;
63 inSig =
malloc1d(signalLength*
sizeof(
float));
64 shSig = (
float**)
malloc2d(nSH,signalLength,
sizeof(
float));
66 memset(inSig, 0, signalLength*
sizeof(
float));
69 direction_deg[0] = -90.0f;
70 direction_deg[1] = 0.0f;
72 getRSH(order, (
float*)direction_deg, 1, y);
73 cblas_sgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, nSH, signalLength, 1, 1.0f,
75 inSig, signalLength, 0.0f,
81 shSig_frame = (
float**)
malloc1d(nSH*
sizeof(
float*));
83 for(i=0; i<(int)((
float)signalLength/(float)framesize); i++){
84 for(ch=0; ch<nSH; ch++)
85 shSig_frame[ch] = &shSig[ch][i*framesize];
87 binSig_frame[ch] = &binSig[ch][i*framesize];
93 leftEarEnergy = rightEarEnergy = 0.0f;
94 for(i=0; i<signalLength; i++){
95 leftEarEnergy += powf(fabsf(binSig[0][i]), 2.0f);
96 rightEarEnergy += powf(fabsf(binSig[1][i]), 2.0f);
98 TEST_ASSERT_TRUE(leftEarEnergy>=rightEarEnergy);
99 TEST_ASSERT_TRUE(leftEarEnergy>=0.f);
100 TEST_ASSERT_TRUE(leftEarEnergy<=10.f);
113 int nSH, i, j, ch, max_ind, framesize;
115 float loudspeakerEnergy[22], direction_deg[2];
117 float** shSig, **lsSig, **shSig_frame, **lsSig_frame;
121 const int fs = 48000;
122 const int signalLength = fs*2;
147 inSig =
malloc1d(signalLength*
sizeof(
float));
148 shSig = (
float**)
malloc2d(nSH,signalLength,
sizeof(
float));
152 direction_deg[0] = 90.0f;
153 direction_deg[1] = 0.0f;
155 getRSH(order, (
float*)direction_deg, 1, y);
156 cblas_sgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, nSH, signalLength, 1, 1.0f,
158 inSig, signalLength, 0.0f,
163 lsSig = (
float**)
calloc2d(22,signalLength,
sizeof(
float));
164 shSig_frame = (
float**)
malloc1d(nSH*
sizeof(
float*));
165 lsSig_frame = (
float**)
malloc1d(22*
sizeof(
float*));
166 for(i=0; i<(int)((
float)signalLength/(float)framesize); i++){
167 for(ch=0; ch<nSH; ch++)
168 shSig_frame[ch] = &shSig[ch][i*framesize];
169 for(ch=0; ch<22; ch++)
170 lsSig_frame[ch] = &lsSig[ch][i*framesize];
172 ambi_dec_process(hAmbi, (
const float*
const*)shSig_frame, lsSig_frame, nSH, 22, framesize);
177 memset(loudspeakerEnergy, 0, 22*
sizeof(
float));
178 for(i=0; i<signalLength; i++){
180 loudspeakerEnergy[j] += powf(fabsf(lsSig[j][i]), 2.0f);
183 TEST_ASSERT_TRUE(max_ind==7);
196 int nSH, i, ch, framesize, j, delay;
198 float direction_deg[2][2];
200 float** shSig, **shSig_ref, **inSig_frame, **shSig_frame;
203 const float acceptedTolerance = 0.000001f;
205 const int fs = 48000;
206 const int signalLength = fs*2;
207 direction_deg[0][0] = 90.0f;
208 direction_deg[0][1] = 0.0f;
209 direction_deg[1][0] = 20.0f;
210 direction_deg[1][1] = -45.0f;
229 inSig = (
float**)
malloc2d(2,signalLength,
sizeof(
float));
230 shSig_ref = (
float**)
malloc2d(nSH,signalLength,
sizeof(
float));
235 getRSH(order, (
float*)direction_deg, 2, y);
236 cblas_sgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, nSH, signalLength, 2, 1.0f,
243 shSig = (
float**)
calloc2d(nSH,signalLength,
sizeof(
float));
244 inSig_frame = (
float**)
malloc1d(2*
sizeof(
float*));
245 shSig_frame = (
float**)
malloc1d(nSH*
sizeof(
float*));
246 for(i=0; i<(int)((
float)signalLength/(float)framesize); i++){
247 for(ch=0; ch<2; ch++)
248 inSig_frame[ch] = &inSig[ch][i*framesize];
249 for(ch=0; ch<nSH; ch++)
250 shSig_frame[ch] = &shSig[ch][i*framesize];
252 ambi_enc_process(hAmbi, (
const float*
const*)inSig_frame, shSig_frame, 2, nSH, framesize);
257 for(j=0; j<signalLength-delay; j++)
258 TEST_ASSERT_FLOAT_WITHIN(acceptedTolerance, shSig_ref[i][j], shSig[i][j+delay]);
269 int nSH, i, j, framesize, ch;
270 void* hA2sh, *safFFT, *hMC;
271 float direction_deg[2], radius;
273 float** shSig, **inSig_32, **micSig, **h_array, **micSig_frame, **shSig_frame;
275 float_complex* tmp_H;
276 float_complex*** H_array;
280 const int fs = 48000;
281 const int signalLength = fs*2;
282 const int nFFT = 1024;
283 const int nBins = nFFT/2+1;
293 inSig =
malloc1d(signalLength*
sizeof(
float));
298 kr =
malloc1d(nBins*
sizeof(
double));
302 for(i=0; i<nBins; i++)
303 kr[i] = 2.0*
SAF_PId*(f[i])*(radius)/343.0f;
304 direction_deg[0] = 90.0f;
305 direction_deg[1] = 0.0f;
306 H_array = (float_complex***)
malloc3d(nBins, 32, 1,
sizeof(float_complex));
311 tmp_H =
malloc1d(nBins*
sizeof(float_complex));
312 h_array = (
float**)
malloc2d(32, nFFT,
sizeof(
float));
315 for(j=0; j<nBins; j++)
316 tmp_H[j] = H_array[j][i][0];
322 micSig = (
float**)
calloc2d(32, signalLength,
sizeof(
float));
323 inSig_32 = (
float**)
malloc2d(32, signalLength,
sizeof(
float));
325 memcpy(inSig_32[i], inSig, signalLength*
sizeof(
float));
327 for(i=0; i<(int)((
float)signalLength/256.0f); i++)
332 shSig = (
float**)
malloc2d(nSH,signalLength,
sizeof(
float));
333 micSig_frame = (
float**)
malloc1d(32*
sizeof(
float*));
334 shSig_frame = (
float**)
malloc1d(nSH*
sizeof(
float*));
335 for(i=0; i<(int)((
float)signalLength/(float)framesize); i++){
336 for(ch=0; ch<32; ch++)
337 micSig_frame[ch] = &micSig[ch][i*framesize];
338 for(ch=0; ch<nSH; ch++)
339 shSig_frame[ch] = &shSig[ch][i*framesize];
341 array2sh_process(hA2sh, (
const float*
const*)micSig_frame, shSig_frame, 32, nSH, framesize);
361 int ch, nSH, i, j, delay, framesize;
363 float direction_deg[2], ypr[3], Rzyx[3][3];
364 float** inSig, *y, **shSig_frame, **shSig_rot_frame;
365 float** shSig, **shSig_rot, **shSig_rot_ref, **Mrot;
368 const float acceptedTolerance = 0.000001f;
370 const int fs = 48000;
371 const int signalLength = fs*2;
372 direction_deg[0] = 90.0f;
373 direction_deg[1] = 0.0f;
392 inSig = (
float**)
malloc2d(1,signalLength,
sizeof(
float));
393 shSig = (
float**)
malloc2d(nSH,signalLength,
sizeof(
float));
398 getRSH(order, (
float*)direction_deg, 1, y);
399 cblas_sgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, nSH, signalLength, 1, 1.0f,
405 Mrot = (
float**)
malloc2d(nSH, nSH,
sizeof(
float));
408 shSig_rot_ref = (
float**)
malloc2d(nSH,signalLength,
sizeof(
float));
409 cblas_sgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, nSH, signalLength, nSH, 1.0f,
416 shSig_rot = (
float**)
malloc2d(nSH,signalLength,
sizeof(
float));
417 shSig_frame = (
float**)
malloc1d(nSH*
sizeof(
float*));
418 shSig_rot_frame = (
float**)
malloc1d(nSH*
sizeof(
float*));
419 for(i=0; i<(int)((
float)signalLength/(float)framesize); i++){
420 for(ch=0; ch<nSH; ch++)
421 shSig_frame[ch] = &shSig[ch][i*framesize];
422 for(ch=0; ch<nSH; ch++)
423 shSig_rot_frame[ch] = &shSig_rot[ch][i*framesize];
425 rotator_process(hRot, (
const float*
const*)shSig_frame, shSig_rot_frame, nSH, nSH, framesize);
431 for(j=0; j<signalLength-delay; j++)
432 TEST_ASSERT_FLOAT_WITHIN(acceptedTolerance, shSig_rot_ref[i][j], shSig_rot[i][j+delay]);
442 free(shSig_rot_frame);
446 int i, ch, framesize, nOutputs;
448 float** inSigs, **outSigs;
449 float** inSig_frame, **outSig_frame;
452 const int fs = 48000;
453 const int nInputs = 1;
454 const int signalLength = fs*2;
468 inSigs = (
float**)
malloc2d(nInputs,signalLength,
sizeof(
float));
469 outSigs = (
float**)
malloc2d(nOutputs,signalLength,
sizeof(
float));
474 inSig_frame = (
float**)
malloc1d(nInputs*
sizeof(
float*));
475 outSig_frame = (
float**)
malloc1d(nOutputs*
sizeof(
float*));
476 for(i=0; i<(int)((
float)signalLength/(float)framesize); i++){
477 for(ch=0; ch<nInputs; ch++)
478 inSig_frame[ch] = &inSigs[ch][i*framesize];
479 for(ch=0; ch<nOutputs; ch++)
480 outSig_frame[ch] = &outSigs[ch][i*framesize];
482 spreader_process(hSpr, (
const float*
const*)inSig_frame, outSig_frame, nInputs, nOutputs, framesize);
@ NORM_N3D
orthonormalised (N3D)
SH_ORDERS
Available spherical harmonic (SH) input/output order options.
void ambi_bin_setInputOrderPreset(void *const hAmbi, SH_ORDERS newPreset)
Sets the decoding order (see SH_ORDERS enum)
void ambi_bin_create(void **const phAmbi)
Creates an instance of ambi_bin.
void ambi_bin_initCodec(void *const hAmbi)
Intialises the codec variables, based on current global/user parameters.
void ambi_bin_process(void *const hAmbi, const float *const *inputs, float *const *const outputs, int nInputs, int nOutputs, int nSamples)
Decodes input spherical harmonic signals to the binaural channels.
void ambi_bin_setNormType(void *const hAmbi, int newType)
Sets the Ambisonic normalisation convention to decode with, in order to match with the convention emp...
void ambi_bin_setEnableRotation(void *const hAmbi, int newState)
Sets the flag to enable/disable (1 or 0) sound-field rotation.
void ambi_bin_setYaw(void *const hAmbi, float newYaw_deg)
Sets the 'yaw' rotation angle, in degrees.
int ambi_bin_getFrameSize(void)
Returns the processing framesize (i.e., number of samples processed with every _process() call )
void ambi_bin_destroy(void **const phAmbi)
Destroys an instance of ambi_bin.
void ambi_bin_init(void *const hAmbi, int samplerate)
Initialises ambi_bin with default settings, and samplerate.
void ambi_dec_create(void **const phAmbi)
Creates an instance of the ambi_dec.
void ambi_dec_init(void *const hAmbi, int samplerate)
Initialises an instance of ambi_dec with default settings.
int ambi_dec_getFrameSize(void)
Returns the processing framesize (i.e., number of samples processed with every _process() call )
void ambi_dec_initCodec(void *const hAmbi)
Intialises the codec variables, based on current global/user parameters.
void ambi_dec_process(void *const hAmbi, const float *const *inputs, float *const *outputs, int nInputs, int nOutputs, int nSamples)
Decodes input spherical harmonic signals to the loudspeaker channels.
void ambi_dec_setOutputConfigPreset(void *const hAmbi, int newPresetID)
Sets the output loudspeaker preset.
@ DECODING_METHOD_SAD
Sampling Ambisonic Decoder (SAD)
void ambi_dec_setDecMethod(void *const hAmbi, int index, int newID)
Sets the decoding method for a specific decoder.
void ambi_dec_setMasterDecOrder(void *const hAmbi, int newValue)
Sets the master decoding order.
void ambi_dec_setNormType(void *const hAmbi, int newType)
Sets the Ambisonic normalisation convention to decode with, in order to match with the convention emp...
void ambi_dec_destroy(void **const phAmbi)
Destroys an instance of the ambi_dec.
void ambi_enc_setEnablePostScaling(void *const hAmbi, int newStatus)
By default, ambi_enc will scale the output signals by the number of input signals.
int ambi_enc_getFrameSize(void)
Returns the processing framesize (i.e., number of samples processed with every _process() call )
void ambi_enc_setOutputOrder(void *const hAmbi, int newValue)
Sets the encoding order (see SH_ORDERS enum)
int ambi_enc_getProcessingDelay(void)
Returns the processing delay in samples (may be used for delay compensation features)
void ambi_enc_setSourceElev_deg(void *const hAmbi, int index, float newElev_deg)
Sets the elevation for a specific source index.
void ambi_enc_setNormType(void *const hAmbi, int newType)
Sets the Ambisonic normalisation convention to encode with (see NORM_TYPES enum)
void ambi_enc_init(void *const hAmbi, int samplerate)
Initialises an instance of ambi_enc with default settings.
void ambi_enc_setNumSources(void *const hAmbi, int new_nSources)
Sets the number of input signals/sources to encode.
void ambi_enc_setSourceAzi_deg(void *const hAmbi, int index, float newAzi_deg)
Sets the azimuth for a specific source index.
void ambi_enc_destroy(void **const phAmbi)
Destroys an instance of ambi_enc.
void ambi_enc_process(void *const hAmbi, const float *const *inputs, float *const *outputs, int nInputs, int nOutputs, int nSamples)
Encodes input signals into spherical harmonic signals, at the specified encoding directions.
void ambi_enc_create(void **const phAmbi)
Creates an instance of ambi_enc.
void array2sh_setNormType(void *const hA2sh, int newType)
Sets the Ambisonic normalisation convention to encode with, in order to match with the convention emp...
void array2sh_destroy(void **const phA2sh)
Destroys an instance of array2sh.
void array2sh_create(void **const phA2sh)
Creates an instance of array2sh.
void array2sh_setPreset(void *const hA2sh, ARRAY2SH_MICROPHONE_ARRAY_PRESETS preset)
Sets a pre-defined microphone/hydrophone array preset (See ARRAY2SH_MICROPHONE_ARRAY_PRESETS enum)
void array2sh_init(void *const hA2sh, int samplerate)
Initialises an instance of array2sh with default settings.
void array2sh_process(void *const hA2sh, const float *const *inputs, float *const *outputs, int nInputs, int nOutputs, int nSamples)
Spatially encode microphone/hydrophone array signals into spherical harmonic signals.
int array2sh_getFrameSize(void)
Returns the processing framesize (i.e., number of samples processed with every _process() call )
void getRSH(int N, float *dirs_deg, int nDirs, float *Y)
Computes real-valued spherical harmonics [1] for each given direction on the unit sphere.
#define ORDER2NSH(order)
Converts spherical harmonic order to number of spherical harmonic components i.e: (order+1)^2.
void simulateSphArray(int order, double *kr, double *kR, int nBands, float *sensor_dirs_rad, int N_sensors, float *src_dirs_deg, int N_srcs, ARRAY_CONSTRUCTION_TYPES arrayType, double dirCoeff, float_complex *H_array)
Simulates a spherical microphone array, returning the transfer functions for each (plane wave) source...
void getSHrotMtxReal(float Rxyz[3][3], float *RotMtx, int L)
Generates a real-valued spherical harmonic rotation matrix [1] based on a 3x3 rotation matrix (see qu...
@ ARRAY_CONSTRUCTION_RIGID
Rigid baffle, omni-directional sensors.
void saf_multiConv_destroy(void **const phMC)
Destroys an instance of multiConv.
#define SAF_PI
pi constant (single precision)
const float __Eigenmike32_coords_rad[32][2]
Sensor array coordinates for the Eigenmike32.
void saf_multiConv_apply(void *const hMC, float *inputSig, float *outputSig)
Performs the multi-channel convolution.
#define NUM_EARS
2 (true for most humans)
#define SAF_PId
pi constant (double precision)
void saf_rfft_create(void **const phFFT, int N)
Creates an instance of saf_rfft; real<->half-complex (conjugate-symmetric) FFT.
void saf_multiConv_create(void **const phMC, int hopSize, float *H, int length_h, int nCH, int usePartFLAG)
Creates an instance of multiConv.
void getUniformFreqVector(int fftSize, float fs, float *freqVector)
Calculates the frequencies (in Hz) of uniformly spaced bins, for a given FFT size and sampling rate.
void saf_rfft_backward(void *const hFFT, float_complex *inputFD, float *outputTD)
Performs the backward-FFT operation; use for complex (conjugate symmetric) to real transformations.
void saf_rfft_destroy(void **const phFFT)
Destroys an instance of saf_rfft.
void yawPitchRoll2Rzyx(float yaw, float pitch, float roll, int rollPitchYawFLAG, float R[3][3])
Constructs a 3x3 rotation matrix from the Euler angles, using the yaw-pitch-roll (zyx) convention.
void rand_m1_1(float *vector, int length)
Generates random numbers between -1 and 1 and stores them in the input vector.
void utility_simaxv(const float *a, const int len, int *index)
Single-precision, index of maximum absolute value in a vector, i.e.
void ** malloc2d(size_t dim1, size_t dim2, size_t data_size)
2-D malloc (contiguously allocated, so use free() as usual to deallocate)
void * malloc1d(size_t dim1_data_size)
1-D malloc (same as malloc, but with error checking)
void *** malloc3d(size_t dim1, size_t dim2, size_t dim3, size_t data_size)
3-D malloc (contiguously allocated, so use free() as usual to deallocate)
void ** calloc2d(size_t dim1, size_t dim2, size_t data_size)
2-D calloc (contiguously allocated, so use free() as usual to deallocate)
#define FLATTEN2D(A)
Use this macro when passing a 2-D dynamic multi-dimensional array to memset, memcpy or any other func...
#define FLATTEN3D(A)
Use this macro when passing a 3-D dynamic multi-dimensional array to memset, memcpy or any other func...
int rotator_getFrameSize(void)
Returns the processing framesize (i.e., number of samples processed with every _process() call )
void rotator_setPitch(void *const hRot, float newPitch)
Sets the 'pitch' rotation angle, in DEGREES.
void rotator_create(void **const phRot)
Creates an instance of rotator.
int rotator_getProcessingDelay(void)
Returns the processing delay in samples (may be used for delay compensation features)
void rotator_init(void *const hRot, int samplerate)
Initialises an instance of rotator with default settings.
void rotator_destroy(void **const phRot)
Destroys an instance of rotator.
void rotator_setRoll(void *const hRot, float newRoll)
Sets the 'roll' rotation angle , in DEGREES.
void rotator_setNormType(void *const hRot, int newType)
Sets the Ambisonic normalisation convention to decode with, in order to match with the convention emp...
void rotator_process(void *const hRot, const float *const *inputs, float *const *outputs, int nInputs, int nOutputs, int nSamples)
Rotates the input spherical harmonic signals.
void rotator_setYaw(void *const hRot, float newYaw)
Sets the 'yaw' rotation angle, in DEGREES.
void rotator_setOrder(void *const hRot, int newOrder)
Sets the input/output order (see SH_ORDERS enum)
Unit test program for the Spatial_Audio_Framework.
void spreader_init(void *const hSpr, int samplerate)
Initialises an instance of spreader with default settings.
void spreader_create(void **const phSpr)
Creates an instance of the spreader.
int spreader_getFrameSize(void)
Returns the processing framesize (i.e., number of samples processed with every _process() call )
void spreader_initCodec(void *const hSpr)
Intialises the codec variables, based on current global/user parameters.
void spreader_setNumSources(void *const hSpr, int new_nSources)
Sets the number of input channels/sources to binauralise.
void spreader_destroy(void **const phSpr)
Destroys an instance of the spreader.
void spreader_setUseDefaultHRIRsflag(void *const hSpr, int newState)
Sets flag to dictate whether the default HRIRs in the Spatial_Audio_Framework should be used (1),...
void spreader_process(void *const hSpr, const float *const *inputs, float *const *outputs, int nInputs, int nOutputs, int nSamples)
Spatialises and spreads the input signals in the user specified directions.
void test__saf_example_array2sh(void)
Testing the SAF array2sh.h example (this may also serve as a tutorial on how to use it)
void test__saf_example_rotator(void)
Testing the SAF rotator.h example (this may also serve as a tutorial on how to use it)
void test__saf_example_ambi_enc(void)
Testing the SAF ambi_enc.h example (this may also serve as a tutorial on how to use it)
void test__saf_example_ambi_bin(void)
Testing the SAF ambi_bin.h example (this may also serve as a tutorial on how to use it)
void test__saf_example_spreader(void)
Testing the SAF spreader.h example (this may also serve as a tutorial on how to use it)
void test__saf_example_ambi_dec(void)
Testing the SAF ambi_dec.h example (this may also serve as a tutorial on how to use it)