SAF
Loading...
Searching...
No Matches
test__resources.c
Go to the documentation of this file.
1/*
2 * Copyright 2020-2021 Leo McCormack
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
9 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
10 * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
11 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
12 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
13 * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
14 * PERFORMANCE OF THIS SOFTWARE.
15 */
16
25#include "saf_test.h"
26
27void test__afSTFT(void){
28 int frame, nFrames, ch, i, nBands, procDelay, band, nHops;
29 void* hSTFT;
30 float* freqVector;
31 float** insig, **outsig, **inframe, **outframe;
32 float_complex*** inspec, ***outspec;
33
34 /* prep */
35 const float acceptedTolerance = 0.01f;
36 const int fs = 48000;
37 const int signalLength = 1*fs;
38 const int framesize = 512;
39 const int hopsize = 128;
40 const int nCHin = 60;
41 const int hybridMode = 1;
42 const int nCHout = 64;
43 insig = (float**)malloc2d(nCHin,signalLength,sizeof(float)); /* One second long */
44 outsig = (float**)malloc2d(nCHout,signalLength,sizeof(float));
45 inframe = (float**)malloc2d(nCHin,framesize,sizeof(float));
46 outframe = (float**)malloc2d(nCHout,framesize,sizeof(float));
47 rand_m1_1(FLATTEN2D(insig), nCHin*signalLength); /* populate with random numbers */
48
49 /* Set-up */
50 nHops = framesize/hopsize;
51 afSTFT_create(&hSTFT, nCHin, nCHout, hopsize, 0, hybridMode, AFSTFT_BANDS_CH_TIME);
52 procDelay = afSTFT_getProcDelay(hSTFT);
53 nBands = afSTFT_getNBands(hSTFT);
54 freqVector = malloc1d(nBands*sizeof(float));
55 afSTFT_getCentreFreqs(hSTFT, (float)fs, nBands, freqVector);
56 inspec = (float_complex***)malloc3d(nBands, nCHin, nHops, sizeof(float_complex));
57 //inspec = (float_complex***)malloc3d(nBands, nCHin+12, nHops+10, sizeof(float_complex));
58 outspec = (float_complex***)malloc3d(nBands, nCHout, nHops, sizeof(float_complex));
59
60 /* just some messing around... */
61 afSTFT_channelChange(hSTFT, 100, 5);
63 afSTFT_channelChange(hSTFT, 39, 81);
64 afSTFT_channelChange(hSTFT, nCHin, nCHout); /* back to original config */
66
67 /* Pass insig through the QMF filterbank, block-wise processing */
68 nFrames = (int)((float)signalLength/(float)framesize);
69 for(frame = 0; frame<nFrames; frame++){
70 /* Forward transform */
71 for(ch=0; ch<nCHin; ch++)
72 memcpy(inframe[ch], &insig[ch][frame*framesize], framesize*sizeof(float));
73 afSTFT_forward(hSTFT, inframe, framesize, inspec);
74 //afSTFT_forward_knownSize(hSTFT, inframe, framesize, nCHin+12, nHops+10, inspec);
75
76 /* Copy first channel of inspec to all outspec channels */
77 for(band=0; band<nBands; band++)
78 for(ch=0; ch<nCHout; ch++)
79 memcpy(outspec[band][ch], inspec[band][0], nHops*sizeof(float_complex));
80
81 /* Backwards transform */
82 afSTFT_backward(hSTFT, outspec, framesize, outframe);
83 for(ch=0; ch<nCHout; ch++)
84 memcpy(&outsig[ch][frame*framesize], outframe[ch], framesize*sizeof(float));
85 }
86
87 /* Check that input==output (given some numerical precision) - channel 0 */
88 for(i=0; i<signalLength-procDelay-framesize; i++)
89 TEST_ASSERT_TRUE( fabsf(insig[0][i] - outsig[0][i+procDelay]) <= acceptedTolerance );
90
91 /* Clean-up */
92 afSTFT_destroy(&hSTFT);
93 free(insig);
94 free(outsig);
95 free(inframe);
96 free(outframe);
97 free(inspec);
98 free(outspec);
99 free(freqVector);
100}
101
103 int s, r, i, j, k;
104 typedef struct _test_data{
105 int ID;
106 float val1, val2;
107 }test_data;
108 test_data** test;
109
110 /* Configure reference data structures */
111 test_data reference[6][6];
112 for(i=0, k=0; i<6; i++){
113 for(j=0; j<6; j++, k++){
114 reference[i][j].ID = k;
115 rand_m1_1(&reference[i][j].val1,1);
116 rand_m1_1(&reference[i][j].val2,1);
117 }
118 }
119
120 /* Starting size */
121 test = (test_data**)malloc2d(1,3,sizeof(test_data));
122 for(s=0; s<1; s++)
123 for(r=0; r<3; r++)
124 memcpy(&test[s][r], &reference[s][r], sizeof(test_data));
125
126 /* Check that increasing the size of the array, still retains the previous data */
127 test = (test_data**)realloc2d_r((void**)test, 4, 3, 1, 3, sizeof(test_data));
128 for(i=0; i<1; i++){
129 for(j=0; j<3; j++){
130 TEST_ASSERT_TRUE(test[i][j].ID==reference[i][j].ID);
131 TEST_ASSERT_TRUE(test[i][j].val1==reference[i][j].val1);
132 TEST_ASSERT_TRUE(test[i][j].val2==reference[i][j].val2);
133 }
134 }
135
136 /* Check that new data can then be added and indexed correctly */
137 for(s=1; s<4; s++)
138 for(r=0; r<3; r++)
139 memcpy(&test[s][r], &reference[s][r], sizeof(test_data));
140 for(i=0; i<4; i++){
141 for(j=0; j<3; j++){
142 TEST_ASSERT_TRUE(test[i][j].ID==reference[i][j].ID);
143 TEST_ASSERT_TRUE(test[i][j].val1==reference[i][j].val1);
144 TEST_ASSERT_TRUE(test[i][j].val2==reference[i][j].val2);
145 }
146 }
147
148 /* Check that the array can be shrunk, but still retain the original data (except truncated) */
149 test = (test_data**)realloc2d_r((void**)test, 4, 2, 4, 3, sizeof(test_data));
150 for(i=0; i<4; i++){
151 for(j=0; j<2; j++){
152 TEST_ASSERT_TRUE(test[i][j].ID==reference[i][j].ID);
153 TEST_ASSERT_TRUE(test[i][j].val1==reference[i][j].val1);
154 TEST_ASSERT_TRUE(test[i][j].val2==reference[i][j].val2);
155 }
156 }
157
158 /* clean-up */
159 free(test);
160}
161
162void test__malloc4d(void){
163 int i,j,k,l;
164 int REF[3][4][2][5];
165 int CPY[3][4][2][5];
166 int**** test_malloc_4d;
167 test_malloc_4d = (int****)malloc4d(3, 4, 2, 5, sizeof(int));
168
169 /* Fill the reference static 4D array, and the dynamically allocated 4D array with the same values */
170 for(i=0; i<3; i++){
171 for(j=0; j<4; j++){
172 for(k=0; k<2; k++){
173 for(l=0; l<5; l++){
174 test_malloc_4d[i][j][k][l] = i*4*2*5 + j*2*5 + k*5 + l;
175 REF[i][j][k][l] = i*4*2*5 + j*2*5 + k*5 + l;
176 }
177 }
178 }
179 }
180
181 /* Copy the dynamically allocated array to a static copy (to check that the data has actually been contiguously allocated) */
182 memcpy(CPY, FLATTEN4D(test_malloc_4d), 3*4*2*5*sizeof(int));
183 for(i=0; i<3; i++)
184 for(j=0; j<4; j++)
185 for(k=0; k<2; k++)
186 for(l=0; l<5; l++) /* The copy should be identical to the reference */
187 TEST_ASSERT_TRUE(CPY[i][j][k][l] == REF[i][j][k][l]);
188
189 /* Clean-up */
190 free(test_malloc_4d);
191}
192
193void test__malloc5d(void){
194 int i,j,k,l,p;
195 int REF[2][4][3][5][2];
196 int CPY[2][4][3][5][2];
197 int***** test_malloc_5d;
198 test_malloc_5d = (int*****)malloc5d(2, 4, 3, 5, 2, sizeof(int));
199
200 /* Fill the reference static 5D array, and the dynamically allocated 5D array with the same values */
201 for(i=0; i<2; i++){
202 for(j=0; j<4; j++){
203 for(k=0; k<3; k++){
204 for(l=0; l<5; l++){
205 for(p=0; p<2; p++){
206 test_malloc_5d[i][j][k][l][p] = i*4*3*5*2 + j*3*5*2 + k*5*2 + l*2 + p;
207 REF[i][j][k][l][p] = i*4*3*5*2 + j*3*5*2 + k*5*2 + l*2 + p;
208 }
209 }
210 }
211 }
212 }
213
214 /* Copy the dynamically allocated array to a static copy (to check that the data has actually been contiguously allocated) */
215 memcpy(CPY, FLATTEN5D(test_malloc_5d), 2*4*3*5*2*sizeof(int));
216 for(i=0; i<2; i++)
217 for(j=0; j<4; j++)
218 for(k=0; k<3; k++)
219 for(l=0; l<5; l++)
220 for(p=0; p<2; p++)/* The copy should be identical to the reference */
221 TEST_ASSERT_TRUE(CPY[i][j][k][l][p] == REF[i][j][k][l][p]);
222
223 /* Clean-up */
224 free(test_malloc_5d);
225}
226
227void test__malloc6d(void){
228 int i,j,k,l,p,o;
229 int REF[2][3][2][4][2][3];
230 int CPY[2][3][2][4][2][3];
231 int****** test_malloc_6d;
232 test_malloc_6d = (int******)malloc6d(2, 3, 2, 4, 2, 3, sizeof(int));
233
234 /* Fill the reference static 5D array, and the dynamically allocated 5D array with the same values */
235 for(i=0; i<2; i++){
236 for(j=0; j<3; j++){
237 for(k=0; k<2; k++){
238 for(l=0; l<4; l++){
239 for(p=0; p<2; p++){
240 for(o=0; o<3; o++){
241 test_malloc_6d[i][j][k][l][p][o] = i*3*2*4*2*3 + j*2*4*2*3 + k*4*2*3 + l*2*3 + p*3 + o;
242 REF[i][j][k][l][p][o] = i*3*2*4*2*3 + j*2*4*2*3 + k*4*2*3 + l*2*3 + p*3 + o;
243 }
244 }
245 }
246 }
247 }
248 }
249
250 /* Copy the dynamically allocated array to a static copy (to check that the data has actually been contiguously allocated) */
251 memcpy(CPY, FLATTEN6D(test_malloc_6d), 2*3*2*4*2*3*sizeof(int));
252 for(i=0; i<2; i++)
253 for(j=0; j<3; j++)
254 for(k=0; k<2; k++)
255 for(l=0; l<4; l++)
256 for(p=0; p<2; p++)
257 for(o=0; o<3; o++)/* The copy should be identical to the reference */
258 TEST_ASSERT_TRUE(CPY[i][j][k][l][p][o] == REF[i][j][k][l][p][o]);
259
260 /* Clean-up */
261 free(test_malloc_6d);
262}
int afSTFT_getNBands(void *const hSTFT)
Returns number of frequency bands.
Definition afSTFTlib.c:528
void afSTFT_clearBuffers(void *const hSTFT)
Flushes time-domain buffers with zeros.
Definition afSTFTlib.c:519
void afSTFT_create(void **const phSTFT, int nCHin, int nCHout, int hopsize, int lowDelayMode, int hybridmode, AFSTFT_FDDATA_FORMAT format)
Creates an instance of afSTFT.
Definition afSTFTlib.c:143
int afSTFT_getProcDelay(void *const hSTFT)
Returns current processing delay, in samples.
Definition afSTFTlib.c:537
void afSTFT_forward(void *const hSTFT, float **dataTD, int framesize, float_complex ***dataFD)
Performs forward afSTFT transform.
Definition afSTFTlib.c:230
void afSTFT_getCentreFreqs(void *const hSTFT, float fs, int nBands, float *freqVector)
Returns current frequency vector.
Definition afSTFTlib.c:546
void afSTFT_destroy(void **const phSTFT)
Destroys an instance of afSTFT.
Definition afSTFTlib.c:199
void afSTFT_channelChange(void *const hSTFT, int new_nCHin, int new_nCHout)
Re-allocates memory to support a change in the number of input/output channels.
Definition afSTFTlib.c:477
void afSTFT_backward(void *const hSTFT, float_complex ***dataFD, int framesize, float **dataTD)
Performs backward afSTFT transform.
Definition afSTFTlib.c:348
@ AFSTFT_BANDS_CH_TIME
nBands x nChannels x nTimeHops
Definition afSTFTlib.h:80
void rand_m1_1(float *vector, int length)
Generates random numbers between -1 and 1 and stores them in the input vector.
void ** malloc2d(size_t dim1, size_t dim2, size_t data_size)
2-D malloc (contiguously allocated, so use free() as usual to deallocate)
Definition md_malloc.c:89
void * malloc1d(size_t dim1_data_size)
1-D malloc (same as malloc, but with error checking)
Definition md_malloc.c:59
void ****** malloc6d(size_t dim1, size_t dim2, size_t dim3, size_t dim4, size_t dim5, size_t dim6, size_t data_size)
6-D malloc (contiguously allocated, so use free() as usual to deallocate)
Definition md_malloc.c:416
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)
Definition md_malloc.c:151
void **** malloc4d(size_t dim1, size_t dim2, size_t dim3, size_t dim4, size_t data_size)
4-D malloc (contiguously allocated, so use free() as usual to deallocate)
Definition md_malloc.c:238
void ** realloc2d_r(void **ptr, size_t new_dim1, size_t new_dim2, size_t prev_dim1, size_t prev_dim2, size_t data_size)
2-D realloc which does retain previous data order
Definition md_malloc.c:127
void ***** malloc5d(size_t dim1, size_t dim2, size_t dim3, size_t dim4, size_t dim5, size_t data_size)
5-D malloc (contiguously allocated, so use free() as usual to deallocate)
Definition md_malloc.c:315
#define FLATTEN6D(A)
Use this macro when passing a 6-D dynamic multi-dimensional array to memset, memcpy or any other func...
Definition md_malloc.h:93
#define FLATTEN4D(A)
Use this macro when passing a 4-D dynamic multi-dimensional array to memset, memcpy or any other func...
Definition md_malloc.h:79
#define FLATTEN2D(A)
Use this macro when passing a 2-D dynamic multi-dimensional array to memset, memcpy or any other func...
Definition md_malloc.h:65
#define FLATTEN5D(A)
Use this macro when passing a 5-D dynamic multi-dimensional array to memset, memcpy or any other func...
Definition md_malloc.h:86
Unit test program for the Spatial_Audio_Framework.
void test__realloc2d_r(void)
Testing the realloc2d_r() function (reallocating 2-D array, while retaining the previous data order; ...
void test__malloc6d(void)
Testing that malloc6d() works, and is truely contiguously allocated.
void test__afSTFT(void)
Testing the alias-free STFT filterbank (near)-perfect reconstruction performance.
void test__malloc5d(void)
Testing that malloc5d() works, and is truely contiguously allocated.
void test__malloc4d(void)
Testing that malloc4d() works, and is truely contiguously allocated.