SAF
Loading...
Searching...
No Matches
afSTFTlib.c
Go to the documentation of this file.
1/*
2 Copyright (c) 2015 Juha Vilkamo
3
4 Permission is hereby granted, free of charge, to any person obtaining a copy
5 of this software and associated documentation files (the "Software"), to deal
6 in the Software without restriction, including without limitation the rights
7 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 copies of the Software, and to permit persons to whom the Software is
9 furnished to do so, subject to the following conditions:
10
11 The above copyright notice and this permission notice shall be included in
12 all copies or substantial portions of the Software.
13
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 THE SOFTWARE.
21 */
22
50#include "afSTFTlib.h"
51#include "afSTFT_internal.h"
52
54static const double __afCenterFreq48e3[133] =
55{ 0.000000000, 140.644316361, 234.355478108, 328.144332285, 421.855497937, 515.644326841, 609.355515147, 703.144330614, 796.855543885, 937.500032020, 1125.000017338, 1312.500035449, 1500.000075751, 1687.500031782, 1875.000024239, 2062.499975101, 2250.000053703, 2437.500044271, 2625.000002315, 2812.500019782, 3000.000041692, 3187.499983930, 3374.999995137, 3562.499994173, 3750.000018557, 3937.500021643, 4125.000009859, 4312.500011528, 4500.000010423, 4687.500014446, 4875.000013588, 5062.500013570, 5250.000007575, 5437.500010288, 5625.000004178, 5812.500003421, 6000.000005158, 6187.500003404, 6375.000003488, 6562.500007191, 6750.000005972, 6937.500008499, 7125.000006936, 7312.500008549, 7500.000005032, 7687.500004875, 7875.000004878, 8062.500007586, 8250.000006218, 8437.499999805, 8625.000000113, 8812.499997984, 9000.000008860, 9187.500004401, 9375.000001529, 9562.500006565, 9750.000006335, 9937.499999557, 10125.000002928, 10312.500002384, 10500.000004406, 10687.500002820, 10875.000001403, 11062.500002219, 11250.000001097, 11437.500001292, 11625.000000815, 11812.500000140, 12000.000000000, 12187.499999584, 12374.999999473, 12562.499999294, 12749.999998799, 12937.499997514, 13124.999998543, 13312.499997602, 13499.999995904, 13687.499996961, 13874.999996550, 14062.500000495, 14249.999993960, 14437.499993440, 14624.999997861, 14812.499995461, 14999.999991137, 15187.500001756, 15374.999999428, 15562.500000999, 15749.999993809, 15937.499992382, 16124.999995683, 16312.499995240, 16499.999994365, 16687.499991354, 16874.999992234, 17062.499991361, 17249.999994298, 17437.499992410, 17624.999995960, 17812.499995945, 17999.999994836, 18187.499996913, 18374.999996125, 18562.499990092, 18749.999991865, 18937.499986965, 19124.999985762, 19312.499985261, 19499.999989766, 19687.499988292, 19874.999989851, 20062.499978542, 20249.999981602, 20437.500005879, 20625.000004853, 20812.500015815, 20999.999958305, 21187.499980259, 21374.999997733, 21562.499955794, 21749.999946298, 21937.500025004, 22124.999975461, 22312.499968567, 22499.999924162, 22687.499964503, 22874.999982475, 23062.499968048, 23249.999976609, 23437.499982579, 23624.999922020, 23812.499893152, 24000.000000000 };
56
58static const double __afCenterFreq44100[133] =
59{ 0.000000000, 129.216965656, 215.314095512, 301.482605287, 387.579738729, 473.748225285, 559.845379541, 646.013853751, 732.111030944, 861.328154418, 1033.593765929, 1205.859407569, 1378.125069596, 1550.390654200, 1722.656272269, 1894.921852124, 2067.187549340, 2239.453165674, 2411.718752127, 2583.984393174, 2756.250038304, 2928.515610236, 3100.781245532, 3273.046869646, 3445.312517049, 3617.578144885, 3789.843759058, 3962.109385592, 4134.375009576, 4306.640638272, 4478.906262484, 4651.171887467, 4823.437506959, 4995.703134452, 5167.968753839, 5340.234378143, 5512.500004739, 5684.765628127, 5857.031253205, 6029.296881607, 6201.562505487, 6373.828132809, 6546.093756373, 6718.359382855, 6890.625004623, 7062.890629479, 7235.156254481, 7407.421881970, 7579.687505713, 7751.953124821, 7924.218750103, 8096.484373148, 8268.750008140, 8441.015629043, 8613.281251405, 8785.546881031, 8957.812505821, 9130.078124593, 9302.343752690, 9474.609377190, 9646.875004048, 9819.140627591, 9991.406251289, 10163.671877038, 10335.937501008, 10508.203126187, 10680.468750748, 10852.734375129, 11025.000000000, 11197.265624618, 11369.531249516, 11541.796874351, 11714.062498897, 11886.328122716, 12058.593748662, 12230.859372797, 12403.124996237, 12575.390622207, 12747.656246830, 12919.921875455, 13092.187494451, 13264.453118973, 13436.718748035, 13608.984370830, 13781.249991857, 13953.515626614, 14125.781249475, 14298.046875918, 14470.312494312, 14642.578118001, 14814.843746034, 14987.109370627, 15159.374994823, 15331.640617057, 15503.906242865, 15676.171867063, 15848.437494762, 16020.703118027, 16192.968746288, 16365.234371274, 16537.499995256, 16709.765622164, 16882.031246440, 17054.296865897, 17226.562492526, 17398.828113024, 17571.093736919, 17743.359361459, 17915.624990597, 18087.890614243, 18260.156240676, 18432.421855285, 18604.687483097, 18776.953130401, 18949.218754459, 19121.484389530, 19293.749961692, 19466.015606863, 19638.281247918, 19810.546834386, 19982.812450661, 20155.078147972, 20327.343727455, 20499.609346121, 20671.874930324, 20844.140592387, 21016.406233899, 21188.671845644, 21360.937478510, 21533.203108994, 21705.468678356, 21877.734276834, 22050.000000000 };
60
65static const float __stft2hybCentreFreq[9][5] =
66{ { 1.0f, 0.0f, 0.0f, 0.0f, 0.0f },
67 { 0.0f, 0.7501f, 0.0f, 0.0f, 0.0f },
68 { 0.0f, 1.2499f, 0.0f, 0.0f, 0.0f },
69 { 0.0f, 0.0f, 0.8751f, 0.0f, 0.0f },
70 { 0.0f, 0.0f, 1.1249f, 0.0f, 0.0f },
71 { 0.0f, 0.0f, 0.0f, 0.9167f, 0.0f },
72 { 0.0f, 0.0f, 0.0f, 1.0833f, 0.0f },
73 { 0.0f, 0.0f, 0.0f, 0.0f, 0.9375f },
74 { 0.0f, 0.0f, 0.0f, 0.0f, 1.0625f } };
75
78static void afAnalyse
79(
80 float* inTD/* nSamplesTD x nCH */,
81 int nSamplesTD,
82 int nCH,
83 int hopSize,
84 int LDmode,
85 int hybridmode,
86 float_complex* outTF /* out_nBands x nTimeslots x nCH */
87)
88{
89 int t, ch, sample, band;
90 void* hSTFT;
91 float_complex*** FrameTF;
92 float** tempFrameTD;
93 int nTimeSlots, nBands;
94
95 nBands = hopSize + (hybridmode ? 5 : 1);
96 nTimeSlots = (int)((float)nSamplesTD/(float)hopSize + 0.9999f); /*ceil*/
97
98 /* allocate memory */
99 afSTFT_create(&(hSTFT), nCH, 1, hopSize, LDmode, hybridmode, AFSTFT_TIME_CH_BANDS);
100 FrameTF = (float_complex***)malloc3d(nTimeSlots, nCH, nBands, sizeof(float_complex));
101 tempFrameTD = (float**)calloc2d(nCH, nTimeSlots*hopSize, sizeof(float));
102
103 /* perform TF transform */
104 for(ch=0; ch<nCH; ch++)
105 for(sample=0; sample<nSamplesTD; sample++)
106 tempFrameTD[ch][sample] = inTD[sample* nCH + ch];
107 afSTFT_forward(hSTFT, tempFrameTD, nTimeSlots*hopSize, FrameTF);
108
109 /* save result to output */
110 for (band = 0; band < nBands; band++)
111 for (t = 0; t < nTimeSlots; t++)
112 for (ch = 0; ch < nCH; ch++)
113 outTF[band * nTimeSlots * nCH + t * nCH + ch] = FrameTF[t][ch][band];
114
115 /* clean-up */
116 afSTFT_destroy(&hSTFT);
117 free(FrameTF);
118 free(tempFrameTD);
119}
120
136
137
138/* ========================================================================== */
139/* Main functions */
140/* ========================================================================== */
141
143(
144 void ** const phSTFT,
145 int nCHin,
146 int nCHout,
147 int hopsize,
148 int lowDelayMode,
149 int hybridmode,
151)
152{
153 *phSTFT = malloc1d(sizeof(afSTFT_data));
154 afSTFT_data *h = (afSTFT_data*)(*phSTFT);
155 int ch;
156
157 if(hybridmode)
158 assert(hopsize==64 || hopsize==128 || hopsize==256);
159 assert(1024 % hopsize == 0 );
160
161 h->nCHin = nCHin;
162 h->nCHout = nCHout;
163 h->hopsize = hopsize;
164 h->hybridmode = hybridmode;
165 h->nBands = hybridmode ? hopsize+5 : hopsize+1; /* hybrid mode incurs an additional 4 bands */
166 if(lowDelayMode)
167 h->afSTFTdelay = hybridmode ? 7*hopsize : 4*hopsize; /* hybrid mode incurs 3 additional hops of latency */
168 else
169 h->afSTFTdelay = hybridmode ? 12*hopsize : 9*hopsize; /* hybrid mode incurs 3 additional hops of latency */
170 h->format = format;
171
172 /* init afSTFT core */
173 afSTFTlib_init(&(h->hInt), hopsize, nCHin, nCHout, lowDelayMode, hybridmode);
174
175 /* temp buffers */
176 if(nCHout>0){
177 h->STFTOutputFrameTF = malloc1d(nCHout * sizeof(complexVector));
178 for(ch=0; ch < nCHout; ch++) {
179 h->STFTOutputFrameTF[ch].re = (float*)calloc1d(h->nBands, sizeof(float));
180 h->STFTOutputFrameTF[ch].im = (float*)calloc1d(h->nBands, sizeof(float));
181 }
182 }
183 else
184 h->STFTOutputFrameTF = NULL;
185 if(nCHout > 0 || nCHin > 0)
186 h->tempHopFrameTD = (float**)malloc2d( SAF_MAX(nCHin, nCHout), hopsize, sizeof(float));
187 if(nCHin>0){
188 h->STFTInputFrameTF = malloc1d(nCHin * sizeof(complexVector));
189 for(ch=0; ch < nCHin; ch++) {
190 h->STFTInputFrameTF[ch].re = (float*)calloc1d(h->nBands, sizeof(float));
191 h->STFTInputFrameTF[ch].im = (float*)calloc1d(h->nBands, sizeof(float));
192 }
193 }
194 else
195 h->STFTInputFrameTF = NULL;
196}
197
199(
200 void ** const phSTFT
201)
202{
203 afSTFT_data *h = (afSTFT_data*)(*phSTFT);
204 int ch;
205
206 if(h!=NULL){
207 /* For run-time */
209 if(h->STFTInputFrameTF!=NULL){
210 for (ch = 0; ch< h->nCHin; ch++) {
211 free(h->STFTInputFrameTF[ch].re);
212 free(h->STFTInputFrameTF[ch].im);
213 }
214 }
215 for (ch = 0; ch< h->nCHout; ch++) {
216 free(h->STFTOutputFrameTF[ch].re);
217 free(h->STFTOutputFrameTF[ch].im);
218 }
219 free(h->STFTInputFrameTF);
220 free(h->STFTOutputFrameTF);
221 free(h->tempHopFrameTD);
222
223 free(h);
224 h=NULL;
225 *phSTFT = NULL;
226 }
227}
228
230(
231 void * const hSTFT,
232 float** dataTD,
233 int framesize,
234 float_complex*** dataFD
235)
236{
237 afSTFT_data *h = (afSTFT_data*)(hSTFT);
238 int ch, t, nHops, band;
239
240 assert(framesize % h->hopsize == 0); /* framesize must be multiple of hopsize */
241 nHops = framesize/h->hopsize;
242
243 /* Loop over hops */
244 for(t=0; t < nHops; t++) {
245 /* forward transform */
246 for(ch = 0; ch < h->nCHin; ch++)
247 utility_svvcopy(&(dataTD[ch][t*(h->hopsize)]), (h->hopsize), h->tempHopFrameTD[ch]);
249
250 /* store */
251 switch(h->format){
253 for(band=0; band<h->nBands; band++)
254 for(ch=0; ch < h->nCHin; ch++)
255 dataFD[band][ch][t] = cmplxf(h->STFTInputFrameTF[ch].re[band], h->STFTInputFrameTF[ch].im[band]);
256 break;
258 for(ch=0; ch < h->nCHin; ch++){
259 cblas_scopy(h->nBands, h->STFTInputFrameTF[ch].re, 1, (float*)dataFD[t][ch], 2);
260 cblas_scopy(h->nBands, h->STFTInputFrameTF[ch].im, 1, &((float*)dataFD[t][ch])[1], 2);
261 }
262 break;
263 }
264 }
265}
266
268(
269 void * const hSTFT,
270 float** dataTD,
271 int framesize,
272 int dataFD_nCH,
273 int dataFD_nHops,
274 float_complex*** dataFD
275)
276{
277 afSTFT_data *h = (afSTFT_data*)(hSTFT);
278 int ch, t, nHops;
279 float_complex* pDataFD;
280
281 assert(framesize % h->hopsize == 0); /* framesize must be multiple of hopsize */
282 nHops = framesize/h->hopsize;
283 pDataFD = &dataFD[0][0][0];
284
285 /* Loop over hops */
286 for(t=0; t < nHops; t++) {
287 /* forward transform */
288 for(ch = 0; ch < h->nCHin; ch++)
289 utility_svvcopy(&(dataTD[ch][t*(h->hopsize)]), (h->hopsize), h->tempHopFrameTD[ch]);
291
292 /* store */
293 switch(h->format){
295 for(ch=0; ch < h->nCHin; ch++){
296 cblas_scopy(h->nBands, h->STFTInputFrameTF[ch].re, 1, (float*)&pDataFD[0*dataFD_nCH*nHops + ch*dataFD_nHops + t], dataFD_nCH*dataFD_nHops*2);
297 cblas_scopy(h->nBands, h->STFTInputFrameTF[ch].im, 1, &((float*)&pDataFD[0*dataFD_nCH*nHops + ch*dataFD_nHops + t])[1], dataFD_nCH*dataFD_nHops*2);
298 }
299 break;
301 for(ch=0; ch < h->nCHin; ch++){
302 cblas_scopy(h->nBands, h->STFTInputFrameTF[ch].re, 1, (float*)dataFD[t][ch], 2);
303 cblas_scopy(h->nBands, h->STFTInputFrameTF[ch].im, 1, &((float*)dataFD[t][ch])[1], 2);
304 }
305 break;
306 }
307 }
308}
309
311(
312 void * const hSTFT,
313 float* dataTD,
314 int framesize,
315 float_complex* dataFD
316)
317{
318 afSTFT_data *h = (afSTFT_data*)(hSTFT);
319 int ch, t, nHops, band;
320
321 assert(framesize % h->hopsize == 0); /* framesize must be multiple of hopsize */
322 nHops = framesize/h->hopsize;
323
324 /* Loop over hops */
325 for(t=0; t < nHops; t++) {
326 /* forward transform */
327 for(ch = 0; ch < h->nCHin; ch++)
328 utility_svvcopy(&(dataTD[ch * framesize + t*(h->hopsize)]), (h->hopsize), h->tempHopFrameTD[ch]);
330
331 /* store */
332 switch(h->format){
334 for(band=0; band<h->nBands; band++)
335 for(ch=0; ch < h->nCHin; ch++)
336 dataFD[band * (h->nCHin) * nHops + ch * nHops + t] = cmplxf(h->STFTInputFrameTF[ch].re[band], h->STFTInputFrameTF[ch].im[band]);
337 break;
339 for(ch=0; ch < h->nCHin; ch++)
340 for(band=0; band<h->nBands; band++)
341 dataFD[t * (h->nCHin) * (h->nBands) + ch * (h->nBands) + band] = cmplxf(h->STFTInputFrameTF[ch].re[band], h->STFTInputFrameTF[ch].im[band]);
342 break;
343 }
344 }
345}
346
348(
349 void * const hSTFT,
350 float_complex*** dataFD,
351 int framesize,
352 float** dataTD
353)
354{
355 afSTFT_data *h = (afSTFT_data*)(hSTFT);
356 int ch, t, nHops, band;
357
358 assert(framesize % h->hopsize == 0); /* framesize must be multiple of hopsize */
359 nHops = framesize/h->hopsize;
360
361 /* Loop over hops */
362 for(t = 0; t < nHops; t++) {
363 /* backward transform */
364 switch(h->format){
366 for(band = 0; band < h->nBands; band++) {
367 for(ch = 0; ch < h->nCHout; ch++) {
368 h->STFTOutputFrameTF[ch].re[band] = crealf(dataFD[band][ch][t]);
369 h->STFTOutputFrameTF[ch].im[band] = cimagf(dataFD[band][ch][t]);
370 }
371 }
372 break;
374 for(band = 0; band < h->nBands; band++) {
375 for(ch = 0; ch < h->nCHout; ch++) {
376 h->STFTOutputFrameTF[ch].re[band] = crealf(dataFD[t][ch][band]);
377 h->STFTOutputFrameTF[ch].im[band] = cimagf(dataFD[t][ch][band]);
378 }
379 }
380 break;
381 }
383
384 /* store */
385 for (ch = 0; ch < h->nCHout; ch++)
386 memcpy(&(dataTD[ch][t*(h->hopsize)]), h->tempHopFrameTD[ch], h->hopsize*sizeof(float));
387 }
388}
389
391(
392 void * const hSTFT,
393 float_complex*** dataFD,
394 int framesize,
395 int dataFD_nCH,
396 int dataFD_nHops,
397 float** dataTD
398)
399{
400 afSTFT_data *h = (afSTFT_data*)(hSTFT);
401 int ch, t, nHops;
402 float_complex* pDataFD;
403
404 assert(framesize % h->hopsize == 0); /* framesize must be multiple of hopsize */
405 nHops = framesize/h->hopsize;
406 pDataFD = &dataFD[0][0][0];
407
408 /* Loop over hops */
409 for(t = 0; t < nHops; t++) {
410 /* backward transform */
411 switch(h->format){
413 for(ch=0; ch < h->nCHout; ch++){
414 cblas_scopy(h->nBands, (float*)&pDataFD[0*dataFD_nCH*nHops + ch*dataFD_nHops + t], dataFD_nCH*dataFD_nHops*2, h->STFTOutputFrameTF[ch].re, 1);
415 cblas_scopy(h->nBands, &((float*)&pDataFD[0*dataFD_nCH*nHops + ch*dataFD_nHops + t])[1], dataFD_nCH*dataFD_nHops*2, h->STFTOutputFrameTF[ch].im, 1);
416 }
417 break;
419 for(ch = 0; ch < h->nCHout; ch++) {
420 cblas_scopy(h->nBands, (float*)dataFD[t][ch], 2, h->STFTOutputFrameTF[ch].re, 1);
421 cblas_scopy(h->nBands, &((float*)dataFD[t][ch])[1], 2, h->STFTOutputFrameTF[ch].im, 1);
422 }
423 break;
424 }
426
427 /* store */
428 for (ch = 0; ch < h->nCHout; ch++)
429 memcpy(&(dataTD[ch][t*(h->hopsize)]), h->tempHopFrameTD[ch], h->hopsize*sizeof(float));
430 }
431}
432
434(
435 void * const hSTFT,
436 float_complex* dataFD,
437 int framesize,
438 float* dataTD
439)
440{
441 afSTFT_data *h = (afSTFT_data*)(hSTFT);
442 int ch, t, nHops, band;
443
444 assert(framesize % h->hopsize == 0); /* framesize must be multiple of hopsize */
445 nHops = framesize/h->hopsize;
446
447 /* Loop over hops */
448 for(t = 0; t < nHops; t++) {
449 /* backward transform */
450 switch(h->format){
452 for(band = 0; band < h->nBands; band++) {
453 for(ch = 0; ch < h->nCHout; ch++) {
454 h->STFTOutputFrameTF[ch].re[band] = crealf(dataFD[band * (h->nCHout) * nHops + ch * nHops + t]);
455 h->STFTOutputFrameTF[ch].im[band] = cimagf(dataFD[band * (h->nCHout) * nHops + ch * nHops + t]);
456 }
457 }
458 break;
460 for(band = 0; band < h->nBands; band++) {
461 for(ch = 0; ch < h->nCHout; ch++) {
462 h->STFTOutputFrameTF[ch].re[band] = crealf(dataFD[t * (h->nCHout) * (h->nBands) + ch * (h->nBands) + band]);
463 h->STFTOutputFrameTF[ch].im[band] = cimagf(dataFD[t * (h->nCHout) * (h->nBands) + ch * (h->nBands) + band]);
464 }
465 }
466 break;
467 }
469
470 /* store */
471 for (ch = 0; ch < h->nCHout; ch++)
472 memcpy(&(dataTD[ch * framesize + t*(h->hopsize)]), h->tempHopFrameTD[ch], h->hopsize*sizeof(float));
473 }
474}
475
477(
478 void * const hSTFT,
479 int new_nCHin,
480 int new_nCHout
481)
482{
483 afSTFT_data *h = (afSTFT_data*)(hSTFT);
484 int i;
485
486 afSTFTlib_channelChange(h->hInt, new_nCHin, new_nCHout);
487
488 /* resize buffers */
489 if(h->nCHin!=new_nCHin){
490 for(i=new_nCHin; i<h->nCHin; i++){
491 free(h->STFTInputFrameTF[i].re);
492 free(h->STFTInputFrameTF[i].im);
493 }
494 h->STFTInputFrameTF = realloc1d(h->STFTInputFrameTF, sizeof(complexVector)*new_nCHin);
495 for(i=h->nCHin; i<new_nCHin; i++){
496 h->STFTInputFrameTF[i].re = (float*)calloc1d(h->nBands, sizeof(float));
497 h->STFTInputFrameTF[i].im = (float*)calloc1d(h->nBands, sizeof(float));
498 }
499 }
500 if(h->nCHout!=new_nCHout){
501 for(i=new_nCHout; i<h->nCHout; i++){
502 free(h->STFTOutputFrameTF[i].re);
503 free(h->STFTOutputFrameTF[i].im);
504 }
505 h->STFTOutputFrameTF = realloc1d(h->STFTOutputFrameTF, sizeof(complexVector)*new_nCHout);
506 for(i=h->nCHout; i<new_nCHout; i++){
507 h->STFTOutputFrameTF[i].re = (float*)calloc1d(h->nBands, sizeof(float));
508 h->STFTOutputFrameTF[i].im = (float*)calloc1d(h->nBands, sizeof(float));
509 }
510 }
511 if( SAF_MAX(h->nCHin, h->nCHout) != SAF_MAX(new_nCHin, new_nCHout))
512 h->tempHopFrameTD = (float**)realloc2d((void**)h->tempHopFrameTD, SAF_MAX(new_nCHin, new_nCHout), h->hopsize, sizeof(float));
513
514 h->nCHin = new_nCHin;
515 h->nCHout = new_nCHout;
516}
517
519(
520 void * const hSTFT
521)
522{
523 afSTFT_data *h = (afSTFT_data*)(hSTFT);
525}
526
528(
529 void * const hSTFT
530)
531{
532 afSTFT_data *h = (afSTFT_data*)(hSTFT);
533 return h->nBands;
534}
535
537(
538 void * const hSTFT
539)
540{
541 afSTFT_data *h = (afSTFT_data*)(hSTFT);
542 return h->afSTFTdelay;
543}
544
546(
547 void * const hSTFT,
548 float fs,
549 int nBands,
550 float* freqVector
551)
552{
553 int band;
554 if(hSTFT==NULL){
555 assert(nBands>=133);
556 for(band=0; band < nBands; band++){
557 if(fs==44100.0f)
558 freqVector[band] = (float)__afCenterFreq44100[band];
559 else /* assume 48e3 */
560 freqVector[band] = (float)__afCenterFreq48e3[band];
561 }
562 return;
563 }
564
565 afSTFT_data *h = (afSTFT_data*)(hSTFT);
566 float* centreFreq_tmp;
567 int i, j;
568
569 assert(nBands >= h->nBands); /* just to check that "centreFreq" is of sufficient length */
570
571 if(h->hybridmode){
572 /* uniform frequency vector: */
573 centreFreq_tmp = malloc1d((h->hopsize+1)*sizeof(float));
574 getUniformFreqVector(h->hopsize*2, fs, centreFreq_tmp);
575
576 /* convert first 5 to hybrid centre frequencies */
577 cblas_sgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, 9, 1, 5, 1.0f,
578 (const float*)__stft2hybCentreFreq, 5,
579 centreFreq_tmp, 1, 0.0f,
580 freqVector, 1);
581
582 /* Remaining centre frequencies are then the uniform centre frequencies 6:end */
583 for(i=9, j=5; i<h->nBands; i++, j++)
584 freqVector[i] = centreFreq_tmp[j];
585
586 free(centreFreq_tmp);
587 }
588 else
589 getUniformFreqVector(h->hopsize*2, fs, freqVector);
590}
591
593(
594 float* hIR /*N_dirs x nCH x ir_len*/,
595 int N_dirs,
596 int nCH,
597 int ir_len,
598 int hopSize,
599 int LDmode,
600 int hybridmode,
601 float_complex* hFB /* nBands x nCH x N_dirs */
602)
603{
604 int i, j, t, nd, nm, nTimeSlots, ir_pad, nBands;
605 int* maxIdx;
606 float maxVal, idxDel, irFB_energy, irFB_gain, phase;
607 float* centerImpulse, *centerImpulseFB_energy, *ir;
608 float_complex cross;
609 float_complex* centerImpulseFB, *irFB;
610
611 nBands = hopSize + (hybridmode ? 5 : 1);
612 ir_pad = 1024;//+512;
613 nTimeSlots = (int)((float)(SAF_MAX(ir_len,hopSize)+ir_pad)/(float)hopSize + 0.9999f); /*ceil*/
614 maxIdx = calloc1d(nCH,sizeof(int));
615 centerImpulse = calloc1d(SAF_MAX(ir_len,hopSize)+ir_pad, sizeof(float));
616
617 /* pick a direction to estimate the center of FIR delays */
618 for(j=0; j<nCH; j++){
619 maxVal = 2.23e-13f;
620 for(i=0; i<ir_len; i++){
621 if(hIR[j*ir_len + i] > maxVal){
622 maxVal = hIR[j*ir_len + i];
623 maxIdx[j] = i;
624 }
625 }
626 }
627 idxDel = 0.0f;
628 for(j=0; j<nCH; j++)
629 idxDel += (float)maxIdx[j];
630 idxDel /= (float)nCH;
631 idxDel = (idxDel + 1.5f);
632
633 /* ideal impulse at mean delay */
634 centerImpulse[(int)idxDel] = 1.0f;
635
636 /* analyse impulse with the filterbank */
637 centerImpulseFB = malloc1d(nBands*nTimeSlots*1*sizeof(float_complex));
638 afAnalyse(centerImpulse, SAF_MAX(ir_len,hopSize)+ir_pad, 1, hopSize, LDmode, hybridmode, centerImpulseFB);
639 centerImpulseFB_energy = calloc1d(nBands, sizeof(float));
640 for(i=0; i<nBands; i++)
641 for(t=0; t<nTimeSlots; t++)
642 centerImpulseFB_energy[i] += powf(cabsf(centerImpulseFB[i*nTimeSlots + t]), 2.0f);
643
644 /* initialise FB coefficients */
645 ir = calloc1d( (SAF_MAX(ir_len,hopSize)+ir_pad) * nCH, sizeof(float));
646 irFB = calloc1d(nBands*nTimeSlots*nCH,sizeof(float_complex));
647 for(nd=0; nd<N_dirs; nd++){
648 for(j=0; j<ir_len; j++)
649 for(i=0; i<nCH; i++)
650 ir[j*nCH+i] = hIR[nd*nCH*ir_len + i*ir_len + j];
651 afAnalyse(ir, SAF_MAX(ir_len,hopSize)+ir_pad, nCH, hopSize, LDmode, hybridmode, irFB);
652 for(nm=0; nm<nCH; nm++){
653 for(i=0; i<nBands; i++){
654 irFB_energy = 0;
655 for(t=0; t<nTimeSlots; t++)
656 irFB_energy += powf(cabsf(irFB[i*nTimeSlots*nCH + t*nCH + nm]), 2.0f); /* out_nBands x nTimeslots x nCH */
657 irFB_gain = sqrtf(irFB_energy/SAF_MAX(centerImpulseFB_energy[i], 2.23e-8f));
658 cross = cmplxf(0.0f,0.0f);
659 for(t=0; t<nTimeSlots; t++)
660 cross = ccaddf(cross, ccmulf(irFB[i*nTimeSlots*nCH + t*nCH + nm], conjf(centerImpulseFB[i*nTimeSlots + t])));
661 phase = atan2f(cimagf(cross), crealf(cross));
662 hFB[i*nCH*N_dirs + nm*N_dirs + nd] = crmulf( cexpf(cmplxf(0.0f, phase)), irFB_gain);
663 }
664 }
665 }
666
667 /* clean-up */
668 free(maxIdx);
669 free(centerImpulse);
670 free(centerImpulseFB_energy);
671 free(centerImpulseFB);
672 free(ir);
673 free(irFB);
674}
675
void afSTFTlib_channelChange(void *handle, int new_inChannels, int new_outChannels)
Re-allocates memory to support a change in the number of input/output channels.
void afSTFTlib_clearBuffers(void *handle)
Flushes time-domain buffers with zeros.
void afSTFTlib_forward(void *handle, float **inTD, complexVector *outFD)
Applies the forward afSTFT transform.
void afSTFTlib_inverse(void *handle, complexVector *inFD, float **outTD)
Applies the backward afSTFT transform.
void afSTFTlib_free(void *handle)
Destroys an instance of afSTFTlib.
void afSTFTlib_init(void **handle, int hopSize, int inChannels, int outChannels, int LDmode, int hybridMode)
Initialises an instance of afSTFTlib [1].
A modified version of afSTFTlib.
static const float __stft2hybCentreFreq[9][5]
Matrix for converting the centre frequencies of the first 5 stft bins into the centre frequencies for...
Definition afSTFTlib.c:65
void afSTFT_backward_flat(void *const hSTFT, float_complex *dataFD, int framesize, float *dataTD)
Performs backward afSTFT transform (flattened arrays)
Definition afSTFTlib.c:434
void afSTFT_FIRtoFilterbankCoeffs(float *hIR, int N_dirs, int nCH, int ir_len, int hopSize, int LDmode, int hybridmode, float_complex *hFB)
Converts FIR filters into Filterbank Coefficients by passing them through the afSTFT filterbank.
Definition afSTFTlib.c:593
void afSTFT_forward_flat(void *const hSTFT, float *dataTD, int framesize, float_complex *dataFD)
Performs forward afSTFT transform (flattened arrays)
Definition afSTFTlib.c:311
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_backward_knownDimensions(void *const hSTFT, float_complex ***dataFD, int framesize, int dataFD_nCH, int dataFD_nHops, float **dataTD)
Performs backward afSTFT transform (dataFD dimensions are known)
Definition afSTFTlib.c:391
void afSTFT_forward(void *const hSTFT, float **dataTD, int framesize, float_complex ***dataFD)
Performs forward afSTFT transform.
Definition afSTFTlib.c:230
static const double __afCenterFreq48e3[133]
afSTFT centre frequencies for 128 hop size, hybrid-mode enabled, 48kHz
Definition afSTFTlib.c:54
void afSTFT_forward_knownDimensions(void *const hSTFT, float **dataTD, int framesize, int dataFD_nCH, int dataFD_nHops, float_complex ***dataFD)
Performs forward afSTFT transform (dataFD dimensions are known)
Definition afSTFTlib.c:268
void afSTFT_getCentreFreqs(void *const hSTFT, float fs, int nBands, float *freqVector)
Returns current frequency vector.
Definition afSTFTlib.c:546
static const double __afCenterFreq44100[133]
afSTFT centre frequencies for 128 hop size, hybrid-mode enabled, 44.1kHz
Definition afSTFTlib.c:58
static void afAnalyse(float *inTD, int nSamplesTD, int nCH, int hopSize, int LDmode, int hybridmode, float_complex *outTF)
Passes input time-domain data through the afSTFT filterbank.
Definition afSTFTlib.c:79
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
A modified version of afSTFTlib.
AFSTFT_FDDATA_FORMAT
Options for how the frequency domain data is permuted when using afSTFT.
Definition afSTFTlib.h:79
@ AFSTFT_TIME_CH_BANDS
nTimeHops x nChannels x nBands
Definition afSTFTlib.h:81
@ AFSTFT_BANDS_CH_TIME
nBands x nChannels x nTimeHops
Definition afSTFTlib.h:80
#define SAF_MAX(a, b)
Returns the maximum of the two values.
void utility_svvcopy(const float *a, const int len, float *c)
Single-precision, vector-vector copy, i.e.
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 ** 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 ** realloc2d(void **ptr, size_t dim1, size_t dim2, size_t data_size)
2-D realloc which does NOT retain previous data order
Definition md_malloc.c:115
void * malloc1d(size_t dim1_data_size)
1-D malloc (same as malloc, but with error checking)
Definition md_malloc.c:59
void * calloc1d(size_t dim1, size_t data_size)
1-D calloc (same as calloc, but with error checking)
Definition md_malloc.c:69
void * realloc1d(void *ptr, size_t dim1_data_size)
1-D realloc (same as realloc, but with error checking)
Definition md_malloc.c:79
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 ** calloc2d(size_t dim1, size_t dim2, size_t data_size)
2-D calloc (contiguously allocated, so use free() as usual to deallocate)
Definition md_malloc.c:102
Data structure for the afSTFT filterbank.
Definition afSTFTlib.c:122
int nCHout
Number of output channels.
Definition afSTFTlib.c:126
int nBands
Number of frequency bands.
Definition afSTFTlib.c:127
float ** tempHopFrameTD
temporary multi-channel time-domain buffer of size "HOP_SIZE".
Definition afSTFTlib.c:133
complexVector * STFTOutputFrameTF
Internal output complex buffer.
Definition afSTFTlib.c:131
AFSTFT_FDDATA_FORMAT format
see AFSTFT_FDDATA_FORMAT
Definition afSTFTlib.c:128
int hybridmode
1: hybrid filtering enabled; 0: disabled
Definition afSTFTlib.c:124
int afSTFTdelay
Processing delay in samples.
Definition afSTFTlib.c:132
int hopsize
Hop size in samples.
Definition afSTFTlib.c:123
complexVector * STFTInputFrameTF
Internal input complex buffer.
Definition afSTFTlib.c:130
void * hInt
Internal handle for afSTFT.
Definition afSTFTlib.c:129
int nCHin
Number of input channels.
Definition afSTFTlib.c:125
Complex data type used by afSTFTlib.