SAF
Loading...
Searching...
No Matches
ambi_drc.c
Go to the documentation of this file.
1/*
2 * Copyright 2017-2018 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
40#include "ambi_drc.h"
41#include "ambi_drc_internal.h"
42
44(
45 void ** const phAmbi
46)
47{
49 *phAmbi = (void*)pData;
50
51 /* afSTFT stuff and audio buffers*/
52 pData->hSTFT = NULL;
53 pData->frameTD = (float**)malloc2d(MAX_NUM_SH_SIGNALS, AMBI_DRC_FRAME_SIZE, sizeof(float));
54 pData->inputFrameTF = (float_complex***)malloc3d(HYBRID_BANDS, MAX_NUM_SH_SIGNALS, TIME_SLOTS, sizeof(float_complex));
55 pData->outputFrameTF = (float_complex***)malloc3d(HYBRID_BANDS, MAX_NUM_SH_SIGNALS, TIME_SLOTS, sizeof(float_complex));
56
57 /* internal */
58 pData->fs = 48000;
59#ifdef ENABLE_TF_DISPLAY
60 pData->gainsTF_bank0 = (float**)malloc2d(HYBRID_BANDS, AMBI_DRC_NUM_DISPLAY_TIME_SLOTS, sizeof(float));
61 pData->gainsTF_bank1 = (float**)malloc2d(HYBRID_BANDS, AMBI_DRC_NUM_DISPLAY_TIME_SLOTS, sizeof(float));
62#endif
63
64 /* Default user parameters */
65 pData->theshold = 0.0f;
66 pData->ratio = 8.0f;
67 pData->knee = 0.0f;
68 pData->inGain = 0.0f;
69 pData->outGain = 0.0f;
70 pData->attack_ms = 50.0f;
71 pData->release_ms = 100.0f;
72 pData->chOrdering = CH_ACN;
73 pData->norm = NORM_SN3D;
75
76 /* for dynamically allocating the number of channels */
78 pData->nSH = pData->new_nSH;
79 pData->reInitTFT = 1;
80}
81
83(
84 void ** const phAmbi
85)
86{
87 ambi_drc_data *pData = (ambi_drc_data*)(*phAmbi);
88
89 if (pData != NULL) {
90 if (pData->hSTFT != NULL)
91 afSTFT_destroy(&(pData->hSTFT));
92 free(pData->frameTD);
93 free(pData->inputFrameTF);
94 free(pData->outputFrameTF);
95#ifdef ENABLE_TF_DISPLAY
96 free(pData->gainsTF_bank0);
97 free(pData->gainsTF_bank1);
98#endif
99 free(pData);
100 pData = NULL;
101 *phAmbi = NULL;
102 }
103}
104
106(
107 void * const hAmbi,
108 int sampleRate
109)
110{
111 ambi_drc_data *pData = (ambi_drc_data*)(hAmbi);
112 int band;
113
114 pData->fs = (float)sampleRate;
115 memset(pData->yL_z1, 0, HYBRID_BANDS * sizeof(float));
116 afSTFT_getCentreFreqs(pData->hSTFT, (float)sampleRate, HYBRID_BANDS, pData->freqVector);
117
118#ifdef ENABLE_TF_DISPLAY
119 pData->rIdx = 0;
120 pData->wIdx = 1;
121 pData->storeIdx = 0;
122 for (band = 0; band < HYBRID_BANDS; band++) {
123 memset(pData->gainsTF_bank0[band], 0, AMBI_DRC_NUM_DISPLAY_TIME_SLOTS * sizeof(float));
124 memset(pData->gainsTF_bank1[band], 0, AMBI_DRC_NUM_DISPLAY_TIME_SLOTS * sizeof(float));
125 }
126#endif
127
128 /* reinitialise if needed */
129 if (pData->reInitTFT == 1) {
130 pData->reInitTFT = 2;
131 ambi_drc_initTFT(hAmbi);
132 pData->reInitTFT = 0;
133 }
134}
135
137(
138 void * const hAmbi,
139 const float *const * inputs,
140 float* const* const outputs,
141 int nCh,
142 int nSamples
143)
144{
145 ambi_drc_data *pData = (ambi_drc_data*)(hAmbi);
146 int i, t, ch, band;
147 float xG, yG, xL, yL, cdB, alpha_a, alpha_r;
148 float makeup, boost, theshold, ratio, knee;
149
150 /* reinitialise if needed */
151 if(pData->reInitTFT==1){
152 pData->reInitTFT = 2;
153 ambi_drc_initTFT(hAmbi);
154 pData->reInitTFT = 0;
155 }
156
157 /* local copies of user parameters */
158 alpha_a = expf(-1.0f / ( (pData->attack_ms / ((float)AMBI_DRC_FRAME_SIZE / (float)TIME_SLOTS)) * pData->fs * 0.001f));
159 alpha_r = expf(-1.0f / ( (pData->release_ms / ((float)AMBI_DRC_FRAME_SIZE / (float)TIME_SLOTS)) * pData->fs * 0.001f));
160 boost = powf(10.0f, pData->inGain / 20.0f);
161 makeup = powf(10.0f, pData->outGain / 20.0f);
162 theshold = pData->theshold;
163 ratio = pData->ratio;
164 knee = pData->knee;
165
166 /* Main processing loop */
167 if (nSamples == AMBI_DRC_FRAME_SIZE && pData->reInitTFT == 0) {
168
169 /* Load time-domain data */
170 for(i=0; i < SAF_MIN(pData->nSH, nCh); i++)
171 utility_svvcopy(inputs[i], AMBI_DRC_FRAME_SIZE, pData->frameTD[i]);
172 for(; i<pData->nSH; i++)
173 memset(pData->frameTD[i], 0, AMBI_DRC_FRAME_SIZE * sizeof(float));
174
175 /* Apply time-frequency transform */
177
178 /* Main processing: */
179 /* Calculate the dynamic range compression gain factors per frequency band based on the omnidirectional component.
180 * McCormack, L., & Välimäki, V. (2017). "FFT-Based Dynamic Range Compression". in Proceedings of the 14th
181 * Sound and Music Computing Conference, July 5-8, Espoo, Finland.*/
182 for (t = 0; t < TIME_SLOTS; t++) {
183 for (band = 0; band < HYBRID_BANDS; band++) {
184 /* apply input boost */
185 for (ch = 0; ch < pData->nSH; ch++)
186 pData->inputFrameTF[band][ch][t] = crmulf(pData->inputFrameTF[band][ch][t], boost);
187
188 /* calculate gain factor for this frequency based on the omni component */
189 xG = 10.0f*log10f(powf(cabsf(pData->inputFrameTF[band][0/* omni */][t]), 2.0f) + 2e-13f);
190 yG = ambi_drc_gainComputer(xG, theshold, ratio, knee);
191 xL = xG - yG;
192 yL = ambi_drc_smoothPeakDetector(xL, pData->yL_z1[band], alpha_a, alpha_r);
193 pData->yL_z1[band] = yL;
194 cdB = -yL;
195 cdB = SAF_MAX(AMBI_DRC_SPECTRAL_FLOOR, sqrtf(powf(10.0f, cdB / 20.0f)));
196
197#ifdef ENABLE_TF_DISPLAY
198 /* store gain factors in circular buffer for plotting */
199 if(pData->storeIdx==0)
200 pData->gainsTF_bank0[band][pData->wIdx] = cdB;
201 else
202 pData->gainsTF_bank1[band][pData->wIdx] = cdB;
203#endif
204 /* apply same gain factor to all SH components, the spatial characteristics will be preserved
205 * (although, ones perception of them may of course change) */
206 for (ch = 0; ch < pData->nSH; ch++)
207 pData->outputFrameTF[band][ch][t] = crmulf(pData->inputFrameTF[band][ch][t], cdB*makeup);
208 }
209#ifdef ENABLE_TF_DISPLAY
210 /* increment circular buffer indices */
211 pData->wIdx++;
212 pData->rIdx++;
213 if (pData->wIdx >= AMBI_DRC_NUM_DISPLAY_TIME_SLOTS){
214 pData->wIdx = 0;
215 pData->storeIdx = pData->storeIdx == 0 ? 1 : 0;
216 }
217 if (pData->rIdx >= AMBI_DRC_NUM_DISPLAY_TIME_SLOTS)
218 pData->rIdx = 0;
219#endif
220 }
221
222 /* Inverse time-frequency transform */
224
225 /* Copy to output */
226 for(ch = 0; ch < SAF_MIN(pData->nSH, nCh); ch++)
227 utility_svvcopy(pData->frameTD[ch], AMBI_DRC_FRAME_SIZE, outputs[ch]);
228 for (; ch < nCh; ch++)
229 memset(outputs[ch], 0, AMBI_DRC_FRAME_SIZE*sizeof(float));
230 }
231 else {
232 for (ch=0; ch < nCh; ch++)
233 memset(outputs[ch], 0, AMBI_DRC_FRAME_SIZE*sizeof(float));
234 }
235}
236
237/* SETS */
238
239void ambi_drc_refreshSettings(void* const hAmbi)
240{
241 ambi_drc_data *pData = (ambi_drc_data*)(hAmbi);
242 pData->reInitTFT = 1;
243}
244
245void ambi_drc_setThreshold(void* const hAmbi, float newValue)
246{
247 ambi_drc_data *pData = (ambi_drc_data*)(hAmbi);
249}
250
251void ambi_drc_setRatio(void* const hAmbi, float newValue)
252{
253 ambi_drc_data *pData = (ambi_drc_data*)(hAmbi);
255}
256
257void ambi_drc_setKnee(void* const hAmbi, float newValue)
258{
259 ambi_drc_data *pData = (ambi_drc_data*)(hAmbi);
261}
262
263void ambi_drc_setInGain(void* const hAmbi, float newValue)
264{
265 ambi_drc_data *pData = (ambi_drc_data*)(hAmbi);
267}
268
269void ambi_drc_setOutGain(void* const hAmbi, float newValue)
270{
271 ambi_drc_data *pData = (ambi_drc_data*)(hAmbi);
273}
274
275void ambi_drc_setAttack(void* const hAmbi, float newValue)
276{
277 ambi_drc_data *pData = (ambi_drc_data*)(hAmbi);
279}
280
281void ambi_drc_setRelease(void* const hAmbi, float newValue)
282{
283 ambi_drc_data *pData = (ambi_drc_data*)(hAmbi);
285}
286
287void ambi_drc_setChOrder(void* const hAmbi, int newOrder)
288{
289 ambi_drc_data *pData = (ambi_drc_data*)(hAmbi);
290 if((CH_ORDER)newOrder != CH_FUMA || pData->currentOrder==SH_ORDER_FIRST)/* FUMA only supports 1st order */
291 pData->chOrdering = (CH_ORDER)newOrder;
292}
293
294void ambi_drc_setNormType(void* const hAmbi, int newType)
295{
296 ambi_drc_data *pData = (ambi_drc_data*)hAmbi;
297 if((NORM_TYPES)newType != NORM_FUMA || pData->currentOrder==SH_ORDER_FIRST)/* FUMA only supports 1st order */
298 pData->norm = (NORM_TYPES)newType;
299}
300
301void ambi_drc_setInputPreset(void* const hAmbi, SH_ORDERS newPreset)
302{
303 ambi_drc_data *pData = (ambi_drc_data*)hAmbi;
304 ambi_drc_setInputOrder(newPreset, &(pData->new_nSH));
305 pData->currentOrder = newPreset;
306 if(pData->new_nSH!=pData->nSH)
307 pData->reInitTFT = 1;
308 /* FUMA only supports 1st order */
309 if(pData->currentOrder!=SH_ORDER_FIRST && pData->chOrdering == CH_FUMA)
310 pData->chOrdering = CH_ACN;
311 if(pData->currentOrder!=SH_ORDER_FIRST && pData->norm == NORM_FUMA)
312 pData->norm = NORM_SN3D;
313}
314
315
316/* GETS */
317
319{
320 return AMBI_DRC_FRAME_SIZE;
321}
322
323#ifdef ENABLE_TF_DISPLAY
324float** ambi_drc_getGainTF(void* const hAmbi)
325{
326 ambi_drc_data *pData = (ambi_drc_data*)(hAmbi);
327 if(pData->storeIdx==0)
328 return pData->gainsTF_bank0;
329 else
330 return pData->gainsTF_bank1;
331}
332
333int ambi_drc_getGainTFwIdx(void* const hAmbi)
334{
335 ambi_drc_data *pData = (ambi_drc_data*)(hAmbi);
336 return pData->wIdx;
337}
338
339int ambi_drc_getGainTFrIdx(void* const hAmbi)
340{
341 ambi_drc_data *pData = (ambi_drc_data*)(hAmbi);
342 return pData->rIdx;
343}
344
345float* ambi_drc_getFreqVector(void* const hAmbi, int* nFreqPoints)
346{
347 ambi_drc_data *pData = (ambi_drc_data*)(hAmbi);
348 (*nFreqPoints) = HYBRID_BANDS;
349 return pData->freqVector;
350}
351#endif
352
353float ambi_drc_getThreshold(void* const hAmbi)
354{
355 ambi_drc_data *pData = (ambi_drc_data*)(hAmbi);
356 return pData->theshold;
357}
358
359float ambi_drc_getRatio(void* const hAmbi)
360{
361 ambi_drc_data *pData = (ambi_drc_data*)(hAmbi);
362 return pData->ratio;
363}
364
365float ambi_drc_getKnee(void* const hAmbi)
366{
367 ambi_drc_data *pData = (ambi_drc_data*)(hAmbi);
368 return pData->knee;
369}
370
371float ambi_drc_getInGain(void* const hAmbi)
372{
373 ambi_drc_data *pData = (ambi_drc_data*)(hAmbi);
374 return pData->inGain;
375}
376
377float ambi_drc_getOutGain(void* const hAmbi)
378{
379 ambi_drc_data *pData = (ambi_drc_data*)(hAmbi);
380 return pData->outGain;
381}
382
383float ambi_drc_getAttack(void* const hAmbi)
384{
385 ambi_drc_data *pData = (ambi_drc_data*)(hAmbi);
386 return pData->attack_ms;
387}
388
389float ambi_drc_getRelease(void* const hAmbi)
390{
391 ambi_drc_data *pData = (ambi_drc_data*)(hAmbi);
392 return pData->release_ms;
393}
394
395int ambi_drc_getChOrder(void* const hAmbi)
396{
397 ambi_drc_data *pData = (ambi_drc_data*)(hAmbi);
398 return (int)pData->chOrdering;
399}
400
401int ambi_drc_getNormType(void* const hAmbi)
402{
403 ambi_drc_data *pData = (ambi_drc_data*)(hAmbi);
404 return (int)pData->norm;
405}
406
408{
409 ambi_drc_data *pData = (ambi_drc_data*)(hAmbi);
410 return pData->currentOrder;
411}
412
413int ambi_drc_getNSHrequired(void* const hAmbi)
414{
415 ambi_drc_data *pData = (ambi_drc_data*)(hAmbi);
416 return pData->nSH;
417}
418
419int ambi_drc_getSamplerate(void* const hAmbi)
420{
421 ambi_drc_data *pData = (ambi_drc_data*)(hAmbi);
422 return (int)(pData->fs+0.5f);
423}
424
426{
427 return 12*HOP_SIZE;
428}
429
NORM_TYPES
Available Ambisonic normalisation conventions.
Definition _common.h:74
@ NORM_SN3D
Schmidt semi-normalisation (SN3D)
Definition _common.h:76
@ NORM_FUMA
(Legacy) Furse-Malham scaling
Definition _common.h:77
CH_ORDER
Available Ambisonic channel ordering conventions.
Definition _common.h:59
@ CH_ACN
Ambisonic Channel Numbering (ACN)
Definition _common.h:60
@ CH_FUMA
(Legacy) Furse-Malham/B-format (WXYZ)
Definition _common.h:61
#define MAX_NUM_SH_SIGNALS
Maximum number of spherical harmonic components/signals supported.
Definition _common.h:239
SH_ORDERS
Available spherical harmonic (SH) input/output order options.
Definition _common.h:38
@ SH_ORDER_FIRST
First-order (4 channels)
Definition _common.h:39
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_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
void afSTFT_destroy(void **const phSTFT)
Destroys an instance of afSTFT.
Definition afSTFTlib.c:199
#define TIME_SLOTS
Number of STFT timeslots.
#define HOP_SIZE
STFT hop size.
#define HYBRID_BANDS
Number of frequency bands.
void ambi_drc_setKnee(void *const hAmbi, float newValue)
Sets the compressor knee value; 0: hard knee, >0: soft knee, in DECIBELS.
Definition ambi_drc.c:257
void ambi_drc_init(void *const hAmbi, int sampleRate)
Initialises an instance of ambi_drc with default settings.
Definition ambi_drc.c:106
int ambi_drc_getChOrder(void *const hAmbi)
Returns the Ambisonic channel ordering convention currently being used to decode with,...
Definition ambi_drc.c:395
int ambi_drc_getNormType(void *const hAmbi)
Returns the Ambisonic normalisation convention currently being usedto decode with,...
Definition ambi_drc.c:401
int ambi_drc_getProcessingDelay()
Returns the processing delay in samples; may be used for delay compensation features.
Definition ambi_drc.c:425
float ambi_drc_getThreshold(void *const hAmbi)
Returns the compressor threshold value, in DECIBELS.
Definition ambi_drc.c:353
void ambi_drc_destroy(void **const phAmbi)
Destroys an instance of the ambi_drc.
Definition ambi_drc.c:83
void ambi_drc_process(void *const hAmbi, const float *const *inputs, float *const *const outputs, int nCh, int nSamples)
Applies the frequency-dependent dynamic range compression to the input spherical harmonic signals.
Definition ambi_drc.c:137
void ambi_drc_setChOrder(void *const hAmbi, int newOrder)
Sets the Ambisonic channel ordering convention to decode with, in order to match the convention emplo...
Definition ambi_drc.c:287
void ambi_drc_create(void **const phAmbi)
Creates an instance of the ambi_drc.
Definition ambi_drc.c:44
float ambi_drc_getKnee(void *const hAmbi)
Returns the compressor knee value 0: hard knee, >0: soft knee, in DECIBELS.
Definition ambi_drc.c:365
void ambi_drc_setOutGain(void *const hAmbi, float newValue)
Sets the compressor output gain value, in DECIBELS.
Definition ambi_drc.c:269
void ambi_drc_setRelease(void *const hAmbi, float newValue)
Sets the compressor envelope release time, in miliseconds.
Definition ambi_drc.c:281
void ambi_drc_setNormType(void *const hAmbi, int newType)
Sets the Ambisonic normalisation convention to decode with, in order to match with the convention emp...
Definition ambi_drc.c:294
int ambi_drc_getNSHrequired(void *const hAmbi)
Returns the number of spherical harmonic signals required by the current decoding order: (current_ord...
Definition ambi_drc.c:413
float ambi_drc_getOutGain(void *const hAmbi)
Returns the compressor output gain value, in DECIBELS.
Definition ambi_drc.c:377
void ambi_drc_setRatio(void *const hAmbi, float newValue)
Sets the compression ratio.
Definition ambi_drc.c:251
void ambi_drc_setInputPreset(void *const hAmbi, SH_ORDERS newPreset)
Sets processing order.
Definition ambi_drc.c:301
void ambi_drc_setThreshold(void *const hAmbi, float newValue)
Sets the compressor threshold value in DECIBELS.
Definition ambi_drc.c:245
void ambi_drc_refreshSettings(void *const hAmbi)
Sets all intialisation flags to 1; re-initialising all settings/variables as ambi_drc is currently co...
Definition ambi_drc.c:239
float ambi_drc_getAttack(void *const hAmbi)
Returns the compressor envelope attack time, in miliseconds.
Definition ambi_drc.c:383
SH_ORDERS ambi_drc_getInputPreset(void *const hAmbi)
Returns the current processing order (see SH_ORDERS enum)
Definition ambi_drc.c:407
float ambi_drc_getRelease(void *const hAmbi)
Returns the compressor envelope release time, in miliseconds.
Definition ambi_drc.c:389
int ambi_drc_getSamplerate(void *const hAmbi)
Returns the DAW/Host sample rate.
Definition ambi_drc.c:419
float ambi_drc_getInGain(void *const hAmbi)
Returns the compressor input gain value, in DECIBELS.
Definition ambi_drc.c:371
void ambi_drc_setAttack(void *const hAmbi, float newValue)
Sets the compressor envelope attack time, in miliseconds.
Definition ambi_drc.c:275
void ambi_drc_setInGain(void *const hAmbi, float newValue)
Sets the compressor input gain value, in DECIBELS.
Definition ambi_drc.c:263
int ambi_drc_getFrameSize(void)
Returns the processing framesize (i.e., number of samples processed with every _process() call )
Definition ambi_drc.c:318
float ambi_drc_getRatio(void *const hAmbi)
Returns the compression ratio.
Definition ambi_drc.c:359
A frequency-dependent Ambisonic sound scene dynamic range compressor (DRC)
float * ambi_drc_getFreqVector(void *const hAmbi, int *nFreqPoints)
Returns the frequency vector used by the processing.
float ** ambi_drc_getGainTF(void *const hAmbi)
Returns pointers to historic time-frequency data, which may be used for plotting purposes.
#define AMBI_DRC_THRESHOLD_MIN_VAL
Minimum threshold, dB.
Definition ambi_drc.h:80
#define AMBI_DRC_NUM_DISPLAY_TIME_SLOTS
Number of time slots of historic TF data.
Definition ambi_drc.h:69
#define AMBI_DRC_OUT_GAIN_MAX_VAL
Maximum output gain, dB.
Definition ambi_drc.h:91
#define AMBI_DRC_IN_GAIN_MAX_VAL
Maximum input gain, dB.
Definition ambi_drc.h:79
#define AMBI_DRC_KNEE_MIN_VAL
Minimum knee, dB.
Definition ambi_drc.h:84
#define AMBI_DRC_ATTACK_MIN_VAL
Minimum attack time, ms.
Definition ambi_drc.h:86
int ambi_drc_getGainTFwIdx(void *const hAmbi)
Returns current TF gain data write index.
int ambi_drc_getGainTFrIdx(void *const hAmbi)
Returns current TF gain data read index.
#define AMBI_DRC_THRESHOLD_MAX_VAL
Maximum threshold, dB.
Definition ambi_drc.h:81
#define AMBI_DRC_ATTACK_MAX_VAL
Maximum attack time, ms.
Definition ambi_drc.h:87
#define AMBI_DRC_IN_GAIN_MIN_VAL
Minimum input gain, dB.
Definition ambi_drc.h:78
#define AMBI_DRC_RELEASE_MIN_VAL
Minimum release time, ms.
Definition ambi_drc.h:88
#define AMBI_DRC_SPECTRAL_FLOOR
-16dB, maximum gain reduction for a given frequency band
Definition ambi_drc.h:76
#define AMBI_DRC_KNEE_MAX_VAL
Maximum knee, dB.
Definition ambi_drc.h:85
#define AMBI_DRC_RATIO_MIN_VAL
Minimum ratio, X:1.
Definition ambi_drc.h:82
#define AMBI_DRC_RELEASE_MAX_VAL
Maximum release time, ms.
Definition ambi_drc.h:89
#define AMBI_DRC_RATIO_MAX_VAL
Maximum ratio, X:1.
Definition ambi_drc.h:83
#define AMBI_DRC_OUT_GAIN_MIN_VAL
Minimum output gain, dB.
Definition ambi_drc.h:90
void ambi_drc_setInputOrder(SH_ORDERS inOrder, int *nSH)
Sets the internal input order.
float ambi_drc_gainComputer(float xG, float T, float R, float W)
The DRC gain computer.
void ambi_drc_initTFT(void *const hAmbi)
Initialise the filterbank used by ambi_drc.
float ambi_drc_smoothPeakDetector(float xL, float yL_z1, float alpha_a, float alpha_r)
The envelope detector.
A frequency-dependent Ambisonic sound scene dynamic range compressor (DRC)
#define AMBI_DRC_FRAME_SIZE
Framesize, in time-domain samples.
#define SAF_CLAMP(a, min, max)
Ensures value "a" is clamped between the "min" and "max" values.
#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.
#define SAF_MIN(a, b)
Returns the minimum of the two values.
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 *** 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
Main structure for ambi_drc.
float ratio
Compression ratio.
float attack_ms
Attack time, in ms.
float knee
Knee width, in dB.
NORM_TYPES norm
Ambisonic normalisation convention (see NORM_TYPES)
int reInitTFT
0: no init required, 1: init required, 2: init in progress
SH_ORDERS currentOrder
Current input SH order.
void * hSTFT
Time-frequency transform handle.
float yL_z1[HYBRID_BANDS]
Delay elements.
float ** frameTD
Input/output SH signals, in the time-domain; MAX_NUM_SH_SIGNALS x AMBI_DRC_FRAME_SIZE.
float_complex *** inputFrameTF
Input SH signals, in the time-frequency domain; HYBRID_BANDS x MAX_NUM_SH_SIGNALS x TIME_SLOTS.
float freqVector[HYBRID_BANDS]
Frequency vector.
CH_ORDER chOrdering
Ambisonic channel order convention (see CH_ORDER)
float theshold
Threshold parameter, in dB.
float_complex *** outputFrameTF
Output SH signals, in the time-frequency domain; HYBRID_BANDS x MAX_NUM_SH_SIGNALS x TIME_SLOTS.
float outGain
Post-gain, in dB.
float inGain
Pre-gain, in dB.
int nSH
Current number of SH signals.
float release_ms
Release time, in ms.
int new_nSH
New number of SH signals (current value will be replaced by this after next re-init)
float fs
Host sampling rate, in Hz.