32typedef struct _latticeAPF{
36 float_complex* buffer;
42typedef struct _latticeDecor_data{
55 float_complex*** delayBuffers;
63typedef struct _transientDucker_data{
66 float** transientDetector1;
67 float** transientDetector2;
84 float maxMilliseconds, nChannelsf;
85 float* delayRangeMax, *delayRangeMin, *tmp_delays, *delays;
87 nChannelsf = (float)nChannels;
88 randperm_nCH =
malloc1d(nChannels*
sizeof(
int));
89 delayRangeMax =
malloc1d(nFreqs*
sizeof(
float));
90 delayRangeMin =
malloc1d(nFreqs*
sizeof(
float));
91 tmp_delays =
malloc1d(nChannels*
sizeof(
float));
92 delays =
malloc1d(nFreqs*nChannels*
sizeof(
float));
93 maxMilliseconds =
SAF_MIN(80.0f, (maxTFdelay-1.0f)*(
float)hopSize/fs*1000.0f);
94 for(band=0; band<nFreqs; band++){
95 delayRangeMax[band] =
SAF_MAX(7.0f,
SAF_MIN(maxMilliseconds, 50.0f*1000.0f/(freqs[band]+2.23e-9f)));
96 delayRangeMin[band] =
SAF_MAX(3.0f,
SAF_MIN(20.0f, 10.0f*1000.0f/(freqs[band]+2.23e-9f)));
98 for(band=0; band<nFreqs; band++)
99 for(ch=0; ch<nChannels; ch++)
100 delays[band*nChannels+ch] = (
float)ch/nChannelsf + ((float)rand()/(float)RAND_MAX)/nChannelsf;
101 for(band=0; band<nFreqs; band++){
103 memcpy(tmp_delays, &delays[band*nChannels], nChannels*
sizeof(
float));
104 for(ch=0; ch<nChannels; ch++)
105 delays[band*nChannels+ch] = tmp_delays[randperm_nCH[ch]];
107 for(band=0; band<nFreqs; band++){
108 for(ch=0; ch<nChannels; ch++){
109 delays[band*nChannels+ch] = delays[band*nChannels+ch]*(delayRangeMax[band]-delayRangeMin[band])+delayRangeMin[band];
110 delayTF[band*nChannels+ch] =
SAF_MAX((
int)(delays[band*nChannels+ch]/1000.0f*fs/(
float)hopSize + 0.5f)-1,0);
133 int i, j, k, rir_filt_len, rir_filt_lout, filterOrder;
134 float alpha, max_t60, t;
135 float *rir, *fcut, *h_filt, *rir_filt_tmp;
141 for(i=0; i<nBands; i++)
142 max_t60 = max_t60 < t60[i] ? t60[i] : max_t60;
143 rir_filt_len = (int)(max_t60*fs+0.5f);
144 rir_filt_lout = rir_filt_len + filterOrder/2;
147 rir =
calloc1d(nCH*nBands*rir_filt_lout,
sizeof(
float));
148 for(i=0; i<nCH; i++){
149 for(j=0; j<nBands; j++){
151 alpha = 3.0f*logf(10.0f)/t60[j];
152 for(k=0, t=0.0f; k<rir_filt_len; k++, t+=1.0f/fs)
153 rir[i*nBands*rir_filt_lout + j*rir_filt_lout + k] = expf(-t*alpha) *
154 2.0f * ((float)rand()/(float)RAND_MAX-0.5f);
159 fcut =
malloc1d((nBands-1)*
sizeof(
float));
160 h_filt =
malloc1d(nBands*(filterOrder+1)*
sizeof(
float));
165 (*rir_filt) =
realloc1d((*rir_filt), nCH*rir_filt_lout*
sizeof(
float));
166 memset((*rir_filt), 0, nCH*rir_filt_lout*
sizeof(
float));
167 rir_filt_tmp =
malloc1d(nBands*rir_filt_lout*
sizeof(
float));
168 for(i=0; i<nCH; i++){
169 fftfilt(&rir[i*nBands*rir_filt_lout], h_filt, rir_filt_lout, filterOrder+1, nBands, rir_filt_tmp);
171 for(j=0; j<nBands; j++){
172 for(k=0; k<rir_filt_lout; k++)
173 (*rir_filt)[i*rir_filt_lout+k] += rir_filt_tmp[j*rir_filt_lout+k];
184 memcpy(&((*rir_filt)[i*rir_filt_len]), &((*rir_filt)[i*rir_filt_lout + filterOrder/2]), rir_filt_len*
sizeof(
float));
185 (*rir_len) = rir_filt_len;
212 int i, band, ch, o, filterIdx;
215 h->nCutoffs = nCutoffs;
219 h->orders =
malloc1d(nCutoffs*
sizeof(
int));
220 memcpy(h->orders, orders, nCutoffs*
sizeof(
int));
221 h->TF_delays =
malloc1d(nBands * nCH *
sizeof(
int));
223 h->enComp_coeff = enComp_coeff;
224 h->in_energy = (
float**)
calloc2d(nBands, nCH,
sizeof(
float));
225 h->decor_energy = (
float**)
calloc2d(nBands, nCH,
sizeof(
float));
232 for(i=0; i<nBands*nCH; i++)
233 maxDelay = h->TF_delays[i] > maxDelay ? h->TF_delays[i] : maxDelay;
236 for(band=0; band<nBands; band++){
240 for(o=0; o<nCutoffs; o++){
241 if(freqVector[band]<freqCutoffs[o]){
248 for(ch=0; ch<nCH; ch++){
251 h->lttc_apf[band][ch].order = -1;
252 h->lttc_apf[band][ch].filterLength = 0;
253 h->lttc_apf[band][ch].coeffs = NULL;
254 h->lttc_apf[band][ch].buffer = NULL;
257 h->lttc_apf[band][ch].order = h->orders[filterIdx];
258 h->lttc_apf[band][ch].coeffs = (
float**)
malloc2d(2, h->orders[filterIdx],
sizeof(
float));
259 h->lttc_apf[band][ch].buffer =
calloc1d(h->lttc_apf[band][ch].order,
sizeof(float_complex));
262 switch(orders[filterIdx]){
263 case 20: memcpy(h->lttc_apf[band][ch].coeffs[0],
__lattice_coeffs_o20[ch+lookupOffset], (h->orders[filterIdx])*
sizeof(
float));
break;
264 case 18: memcpy(h->lttc_apf[band][ch].coeffs[0],
__lattice_coeffs_o18[ch+lookupOffset], (h->orders[filterIdx])*
sizeof(
float));
break;
265 case 16: memcpy(h->lttc_apf[band][ch].coeffs[0],
__lattice_coeffs_o16[ch+lookupOffset], (h->orders[filterIdx])*
sizeof(
float));
break;
266 case 15: memcpy(h->lttc_apf[band][ch].coeffs[0],
__lattice_coeffs_o15[ch+lookupOffset], (h->orders[filterIdx])*
sizeof(
float));
break;
267 case 14: memcpy(h->lttc_apf[band][ch].coeffs[0],
__lattice_coeffs_o14[ch+lookupOffset], (h->orders[filterIdx])*
sizeof(
float));
break;
268 case 12: memcpy(h->lttc_apf[band][ch].coeffs[0],
__lattice_coeffs_o12[ch+lookupOffset], (h->orders[filterIdx])*
sizeof(
float));
break;
269 case 10: memcpy(h->lttc_apf[band][ch].coeffs[0],
__lattice_coeffs_o10[ch+lookupOffset], (h->orders[filterIdx])*
sizeof(
float));
break;
270 case 8: memcpy(h->lttc_apf[band][ch].coeffs[0],
__lattice_coeffs_o8[ch+lookupOffset], (h->orders[filterIdx])*
sizeof(
float));
break;
271 case 6: memcpy(h->lttc_apf[band][ch].coeffs[0],
__lattice_coeffs_o6[ch+lookupOffset], (h->orders[filterIdx])*
sizeof(
float));
break;
272 case 4: memcpy(h->lttc_apf[band][ch].coeffs[0],
__lattice_coeffs_o4[ch+lookupOffset], (h->orders[filterIdx])*
sizeof(
float));
break;
273 case 3: memcpy(h->lttc_apf[band][ch].coeffs[0],
__lattice_coeffs_o3[ch+lookupOffset], (h->orders[filterIdx])*
sizeof(
float));
break;
274 case 2: memcpy(h->lttc_apf[band][ch].coeffs[0],
__lattice_coeffs_o2[ch+lookupOffset], (h->orders[filterIdx])*
sizeof(
float));
break;
275 default:
saf_print_error(
"Unsupported filter order was specified");
break;
279 for(i=0; i<orders[filterIdx]; i++)
280 h->lttc_apf[band][ch].coeffs[1][i] = h->lttc_apf[band][ch].coeffs[0][orders[filterIdx]-i-1];
286 h->maxBufferLen = maxDelay+1;
287 h->delayBuffers = (float_complex***)
calloc3d(nBands, nCH, h->maxBufferLen,
sizeof(float_complex));
288 h->wIdx =
malloc1d(nBands*nCH*
sizeof(
int));
289 for(band=0; band<nBands; band++)
290 for(ch=0; ch<nCH; ch++)
291 h->wIdx[band*nCH+ch] = h->TF_delays[band*nCH+ch];
292 h->rIdx =
calloc1d(nBands*nCH,
sizeof(
int));
306 for(band=0; band <h->nBands; band++){
307 for(ch=0; ch<h->nCH; ch++){
308 free(h->lttc_apf[band][ch].buffer);
309 free(h->lttc_apf[band][ch].coeffs);
314 free(h->delayBuffers);
331 memset(
FLATTEN3D(h->delayBuffers), 0, h->nBands * h->nCH * h->maxBufferLen *
sizeof(float_complex));
332 for(band=0; band<h->nBands; band++)
333 for(ch=0; ch<h->nCH; ch++)
334 if(h->lttc_apf[band][ch].buffer!=NULL)
335 memset(h->lttc_apf[band][ch].buffer, 0, h->lttc_apf[band][ch].order *
sizeof(float_complex));
336 memset(
FLATTEN2D(h->in_energy), 0, h->nBands*h->nCH*
sizeof(
float));
337 memset(
FLATTEN2D(h->decor_energy), 0, h->nBands*h->nCH*
sizeof(
float));
343 float_complex*** inFrame,
345 float_complex*** decorFrame
350 float_complex ytmp, xtmp;
352 for(t=0; t<nTimeSlots; t++){
353 for(band=0; band <h->nBands; band++){
354 for(ch=0; ch<h->nCH; ch++){
356 h->delayBuffers[band][ch][h->wIdx[band*(h->nCH) + ch]] = inFrame[band][ch][t];
357 decorFrame[band][ch][t] = h->delayBuffers[band][ch][h->rIdx[band*(h->nCH) + ch]];
360 h->rIdx[band*(h->nCH) + ch]++;
361 h->wIdx[band*(h->nCH) + ch]++;
362 if( h->rIdx[band*(h->nCH) + ch] > h->TF_delays[band*(h->nCH) + ch] )
363 h->rIdx[band*(h->nCH) + ch] = 0;
364 if( h->wIdx[band*(h->nCH) + ch] > h->TF_delays[band*(h->nCH) + ch] )
365 h->wIdx[band*(h->nCH) + ch] = 0;
372 for(band=0; band <h->nBands; band++){
373 for(ch=0; ch<h->nCH; ch++){
374 if(h->lttc_apf[band][ch].buffer!=NULL){
375 for(t=0; t<nTimeSlots; t++){
377 h->in_energy[band][ch] = (1.0f-h->enComp_coeff)*powf(cabsf(inFrame[band][ch][t]),2.0f) + (h->enComp_coeff)*h->in_energy[band][ch];
380 xtmp = decorFrame[band][ch][t];
381 ytmp = ccaddf(h->lttc_apf[band][ch].buffer[0], crmulf(xtmp, (h->lttc_apf[band][ch].coeffs[0][0])));
382 decorFrame[band][ch][t] = ytmp;
385 h->decor_energy[band][ch] = (1.0f-h->enComp_coeff)*powf(cabsf(decorFrame[band][ch][t]),2.0f) + (h->enComp_coeff)*h->decor_energy[band][ch];
386 decorFrame[band][ch][t] = crmulf(decorFrame[band][ch][t],
SAF_MIN(sqrtf(h->in_energy[band][ch]/(h->decor_energy[band][ch]+2.23e-9f)), 1.0f));
389 for(i=0; i<h->lttc_apf[band][ch].order-1; i++){
390 h->lttc_apf[band][ch].buffer[i] = ccaddf(h->lttc_apf[band][ch].buffer[i+1],
391 ccsubf(crmulf(xtmp, h->lttc_apf[band][ch].coeffs[0][i+1]),
392 crmulf(ytmp, h->lttc_apf[band][ch].coeffs[1][i+1])));
399 for(band=0; band <h->nBands; band++){
400 for(ch=0; ch<h->nCH; ch++){
401 if(h->lttc_apf[band][ch].buffer!=NULL){
402 for(t=0; t<nTimeSlots; t++){
404 h->in_energy[band][ch] = (1.0f-h->enComp_coeff)*powf(cabsf(inFrame[band][ch][t]),2.0f) + (h->enComp_coeff)*h->in_energy[band][ch];
407 xtmp = decorFrame[band][ch][t];
408 ytmp = xtmp * (h->lttc_apf[band][ch].coeffs[0][0]) + h->lttc_apf[band][ch].buffer[0];
409 decorFrame[band][ch][t] = ytmp;
412 h->decor_energy[band][ch] = (1.0f-h->enComp_coeff)*powf(cabsf(decorFrame[band][ch][t]), 2.0f) + (h->enComp_coeff)*(h->decor_energy[band][ch]);
413 decorFrame[band][ch][t] *=
SAF_MIN(sqrtf(h->in_energy[band][ch]/(h->decor_energy[band][ch]+2.23e-9f)), 1.0f);
416 for(i=0; i<h->lttc_apf[band][ch].order-1; i++){
417 h->lttc_apf[band][ch].buffer[i] = h->lttc_apf[band][ch].buffer[i+1] +
418 h->lttc_apf[band][ch].coeffs[0][i+1] * xtmp -
419 h->lttc_apf[band][ch].coeffs[1][i+1] * ytmp;
440 h->transientDetector1 = (
float**)
calloc2d(nBands, nCH,
sizeof(
float));
441 h->transientDetector2 = (
float**)
calloc2d(nBands, nCH,
sizeof(
float));
452 free(h->transientDetector1);
453 free(h->transientDetector2);
463 float_complex*** inFrame,
467 float_complex*** residualFrame,
468 float_complex*** transientFrame
473 float detectorEne, transientEQ;
477 for(band=0; band<h->nBands; band++){
478 for(i=0; i<h->nCH; i++){
479 for(t=0; t<nTimeSlots; t++){
480 detectorEne = cabsf(inFrame[band][i][t]);
481 detectorEne = detectorEne*detectorEne;
482 h->transientDetector1[band][i] *= alpha;
483 if(h->transientDetector1[band][i]<detectorEne)
484 h->transientDetector1[band][i] = detectorEne;
485 h->transientDetector2[band][i] = h->transientDetector2[band][i]*beta + (1.0f-beta)*(h->transientDetector1[band][i]);
486 if(h->transientDetector2[band][i] > h->transientDetector1[band][i])
487 h->transientDetector2[band][i] = h->transientDetector1[band][i];
488 transientEQ =
SAF_MIN(1.0f, 4.0f * (h->transientDetector2[band][i])/(h->transientDetector1[band][i]+2.23e-9f));
490 if(residualFrame!=NULL)
491 residualFrame[band][i][t] = crmulf(inFrame[band][i][t], transientEQ);
492 if(transientFrame!=NULL)
493 transientFrame[band][i][t] = crmulf(inFrame[band][i][t], 1.0f-transientEQ);
495 if(residualFrame!=NULL)
496 residualFrame[band][i][t] = inFrame[band][i][t] * transientEQ;
497 if(transientFrame!=NULL)
498 transientFrame[band][i][t] = inFrame[band][i][t] * (1.0f-transientEQ);
#define saf_print_error(message)
Macro to print a error message along with the filename and line number.
void fftfilt(float *x, float *h, int x_len, int h_len, int nCH, float *y)
FFT-based convolution for FIR filters.
void transientDucker_destroy(void **phDucker)
Destroys an instance of the transient ducker.
#define SAF_MAX(a, b)
Returns the maximum of the two values.
const float __lattice_coeffs_o3[256][3]
Lattice all-pass filter coeffs (numerator) for 256 channels, 3rd order.
void transientDucker_apply(void *hDucker, float_complex ***inFrame, int nTimeSlots, float alpha, float beta, float_complex ***residualFrame, float_complex ***transientFrame)
Applies the transient ducker, returning either the "ducked" input frame, or the transient part of the...
const float __lattice_coeffs_o14[256][14]
Lattice all-pass filter coeffs (numerator) for 256 channels, 14th order.
void FIRFilterbank(int order, float *fc, int nCutoffFreq, float sampleRate, WINDOWING_FUNCTION_TYPES windowType, int scalingFLAG, float *filterbank)
Computes a bank of FIR filter coefficients required to divide a signal into frequency bands.
const float __lattice_coeffs_o20[256][20]
Lattice all-pass filter coeffs (numerator) for 256 channels, 20th order.
const float __lattice_coeffs_o8[256][8]
Lattice all-pass filter coeffs (numerator) for 256 channels, 8th order.
void flattenMinphase(float *x, int len)
Equalises input sequence by its minimum phase form, in order to bring its magnitude response to unity...
void randperm(int len, int *randperm)
Returns the indices required to randomly permute a vector of length 'len'.
const float __lattice_coeffs_o4[256][4]
Lattice all-pass filter coeffs (numerator) for 256 channels, 4th order.
const float __lattice_coeffs_o15[256][15]
Lattice all-pass filter coeffs (numerator) for 256 channels, 15th order.
const float __lattice_coeffs_o16[256][16]
Lattice all-pass filter coeffs (numerator) for 256 channels, 16th order.
void latticeDecorrelator_reset(void *hDecor)
Sets the internal buffers to zero.
void latticeDecorrelator_apply(void *hDecor, float_complex ***inFrame, int nTimeSlots, float_complex ***decorFrame)
Applies the lattice all-pass-filter-based multi-channel signal decorrelator.
#define SAF_MIN(a, b)
Returns the minimum of the two values.
const float __lattice_coeffs_o10[256][10]
Lattice all-pass filter coeffs (numerator) for 256 channels, 10th order.
const float __lattice_coeffs_o18[256][18]
Lattice all-pass filter coeffs (numerator) for 256 channels, 18th order.
void latticeDecorrelator_create(void **phDecor, float fs, int hopsize, float *freqVector, int nBands, int nCH, int *orders, float *freqCutoffs, int nCutoffs, int maxDelay, int lookupOffset, float enComp_coeff)
Creates an instance of the lattice all-pass-filter-based multi-channel signal decorrelator.
const float __lattice_coeffs_o2[256][2]
Lattice all-pass filter coeffs (numerator) for 256 channels, 2nd order.
void latticeDecorrelator_destroy(void **phDecor)
Destroys an instance of the lattice all-pass-filter-based multi-channel signal decorrelator.
const float __lattice_coeffs_o12[256][12]
Lattice all-pass filter coeffs (numerator) for 256 channels, 12th order.
void synthesiseNoiseReverb(int nCH, float fs, float *t60, float *fcen_oct, int nBands, int flattenFLAG, float **rir_filt, int *rir_len)
Returns quick and dirty exponentially decaying noise bursts.
const float __lattice_coeffs_o6[256][6]
Lattice all-pass filter coeffs (numerator) for 256 channels, 6th order.
void transientDucker_create(void **phDucker, int nCH, int nBands)
Creates an instance of the transient ducker/extractor.
void getDecorrelationDelays(int nChannels, float *freqs, int nFreqs, float fs, int maxTFdelay, int hopSize, int *delayTF)
Returns delay values for multiple channels per frequency, such that once applied to an input signal (...
void getOctaveBandCutoffFreqs(float *centreFreqs, int nCentreFreqs, float *cutoffFreqs)
Converts octave band CENTRE frequencies into CUTOFF frequencies.
@ WINDOWING_FUNCTION_HAMMING
Hamming.
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 * calloc1d(size_t dim1, size_t data_size)
1-D calloc (same as calloc, but with error checking)
void * realloc1d(void *ptr, size_t dim1_data_size)
1-D realloc (same as realloc, but with error checking)
void ** calloc2d(size_t dim1, size_t dim2, size_t data_size)
2-D calloc (contiguously allocated, so use free() as usual to deallocate)
void *** calloc3d(size_t dim1, size_t dim2, size_t dim3, size_t data_size)
3-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...
Include header for SAF externals.
Main header for the utilities module (SAF_UTILITIES_MODULE)
Internal Lattice all-pass filter structure.
Internal Lattice all-pass filter based decorrelator structure.
Internal structure used by the transient Ducker.