summaryrefslogtreecommitdiff
path: root/lib/rbcodec/dsp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/rbcodec/dsp')
-rw-r--r--lib/rbcodec/dsp/compressor.c379
-rw-r--r--lib/rbcodec/dsp/compressor.h1
2 files changed, 292 insertions, 88 deletions
diff --git a/lib/rbcodec/dsp/compressor.c b/lib/rbcodec/dsp/compressor.c
index a222caed7f..685851ec29 100644
--- a/lib/rbcodec/dsp/compressor.c
+++ b/lib/rbcodec/dsp/compressor.c
@@ -23,44 +23,155 @@
23#include "fracmul.h" 23#include "fracmul.h"
24#include <string.h> 24#include <string.h>
25 25
26/* Define LOGF_ENABLE to enable logf output in this file */ 26/* Define LOGF_ENABLE to enable logf output in this file
27/*#define LOGF_ENABLE*/ 27 * #define LOGF_ENABLE
28 */
28#include "logf.h" 29#include "logf.h"
29#include "dsp_proc_entry.h" 30#include "dsp_proc_entry.h"
30#include "compressor.h" 31#include "compressor.h"
31#include "dsp_misc.h" 32#include "dsp_misc.h"
32 33
34#define UNITY (1L << 24) /* unity gain in S7.24 format */
35#define MAX_DLY 960 /* Max number of samples to delay
36 output (960 = 5ms @ 192 kHz)
37 */
38#define MAX_CH 4 /* Is there a good malloc() or equal
39 for rockbox?
40 */
41#define DLY_TIME 3 /* milliseconds */
42
33static struct compressor_settings curr_set; /* Cached settings */ 43static struct compressor_settings curr_set; /* Cached settings */
34 44
35static int32_t comp_rel_slope IBSS_ATTR; /* S7.24 format */ 45static int32_t comp_makeup_gain IBSS_ATTR; /* S7.24 format */
36static int32_t comp_makeup_gain IBSS_ATTR; /* S7.24 format */ 46static int32_t comp_curve[66] IBSS_ATTR; /* S7.24 format */
37static int32_t comp_curve[66] IBSS_ATTR; /* S7.24 format */ 47static int32_t release_gain IBSS_ATTR; /* S7.24 format */
38static int32_t release_gain IBSS_ATTR; /* S7.24 format */ 48static int32_t release_holdoff IBSS_ATTR; /* S7.24 format */
49
50/* 1-pole filter coefficients for exponential attack/release times */
51static int32_t rlsca IBSS_ATTR; /* Release 'alpha' */
52static int32_t rlscb IBSS_ATTR; /* Release 'beta' */
53
54static int32_t attca IBSS_ATTR; /* Attack 'alpha' */
55static int32_t attcb IBSS_ATTR; /* Attack 'beta' */
56
57static int32_t limitca IBSS_ATTR; /* Limiter Attack 'alpha' */
58
59/* 1-pole filter coefficients for sidechain pre-emphasis filters */
60static int32_t hp1ca IBSS_ATTR; /* hpf1 'alpha' */
61static int32_t hp2ca IBSS_ATTR; /* hpf2 'beta' */
62
63/* 1-pole hp filter state variables for pre-emphasis filters */
64static int32_t hpfx1 IBSS_ATTR; /* hpf1 and hpf2 x[n-1] */
65static int32_t hp1y1 IBSS_ATTR; /* hpf2 y[n-1] */
66static int32_t hp2y1 IBSS_ATTR; /* hpf2 y[n-1] */
67
68/* Delay Line for look-ahead compression */
69static int32_t labuf[MAX_CH][MAX_DLY]; /* look-ahead buffer */
70static int32_t delay_time;
71static int32_t delay_write;
72static int32_t delay_read;
73
74/** 1-Pole LP Filter first coefficient computation
75 * Returns S7.24 format integer used for "a" coefficient
76 * rc: "RC Time Constant", or time to decay to 1/e
77 * fs: Sampling Rate
78 * Interpret attack and release time as an RC time constant
79 * (time to decay to 1/e)
80 * 1-pole filters use approximation
81 * a0 = 1/(fs*rc + 1)
82 * b1 = 1.0 - a0
83 * fs = Sampling Rate
84 * rc = Time to decay to 1/e
85 * y[n] = a0*x[n] + b1*y[n-1]
86 *
87 * According to simulation on Intel hardware
88 * this algorithm produces < 2% error for rc < ~100ms
89 * For rc 100ms - 1000ms, error approaches 0%
90 * For compressor attack/release times, this is more than adequate.
91 *
92 * Error was measured against the more rigorous computation:
93 * a0 = 1.0 - e^(-1.0/(fs*rc))
94 */
95
96int32_t get_lpf_coeff(int32_t rc, int32_t fs, int32_t rc_units)
97{
98 int32_t c = fs*rc;
99 c /= rc_units;
100 c += 1;
101 c = UNITY/c;
102 return c;
103}
39 104
40#define UNITY (1L << 24) /* unity gain in S7.24 format */ 105/** Coefficients to get 10dB change per time period "rc"
106 * from 1-pole LP filter topology
107 * This function is better used to match behavior of
108 * linear release which was implemented prior to implementation
109 * of exponential attack/release function
110 */
111
112int32_t get_att_rls_coeff(int32_t rc, int32_t fs)
113{
114 int32_t c = UNITY/fs;
115 c *= 1152; /* 1000 * 10/( 20*log10( 1/e ) ) */
116 c /= rc;
117 return c;
118}
41 119
42/** COMPRESSOR UPDATE 120/** COMPRESSOR UPDATE
43 * Called via the menu system to configure the compressor process */ 121 * Called via the menu system to configure the compressor process
122 */
44static bool compressor_update(struct dsp_config *dsp, 123static bool compressor_update(struct dsp_config *dsp,
45 const struct compressor_settings *settings) 124 const struct compressor_settings *settings)
46{ 125{
47 /* make settings values useful */ 126 /* make settings values useful */
48 int threshold = settings->threshold; 127 int threshold = settings->threshold;
49 bool auto_gain = settings->makeup_gain == 1; 128 bool auto_gain = settings->makeup_gain == 1;
50 static const int comp_ratios[] = { 2, 4, 6, 10, 0 }; 129 static const int comp_ratios[] = { 2, 4, 6, 10, 0 };
51 int ratio = comp_ratios[settings->ratio]; 130 int ratio = comp_ratios[settings->ratio];
52 bool soft_knee = settings->knee == 1; 131 bool soft_knee = settings->knee == 1;
53 int release = settings->release_time * 132 int32_t release = settings->release_time;
54 dsp_get_output_frequency(dsp) / 1000; 133 int32_t attack = settings->attack_time;
134
135 /* Compute Attack and Release Coefficients */
136 int32_t fs = dsp_get_output_frequency(dsp);
137
138 /* Release */
139 rlsca = get_att_rls_coeff(release, fs);
140 rlscb = UNITY - rlsca ;
141
142 /* Attack */
143 if(attack > 0)
144 {
145 attca = get_att_rls_coeff(attack, fs);
146 attcb = UNITY - attca ;
147 }
148 else {
149 attca = UNITY;
150 attcb = 0;
151 }
55 152
56 bool changed = settings == &curr_set; /* If frequency change */ 153
154 /* Sidechain pre-emphasis filter coefficients */
155 hp1ca = fs + 0x003C1; /** The "magic" constant is 1/RC. This filter
156 * cut-off is approximately 237 Hz
157 */
158 hp1ca = UNITY/hp1ca;
159 hp1ca *= fs;
160
161 hp2ca = fs + 0x02065; /* The "magic" constant is 1/RC. This filter
162 * cut-off is approximately 2.18 kHz
163 */
164 hp2ca = UNITY/hp2ca;
165 hp2ca *= fs;
166
167 bool changed = settings == &curr_set; /* If frequency changes */
57 bool active = threshold < 0; 168 bool active = threshold < 0;
58 169
59 if (memcmp(settings, &curr_set, sizeof (curr_set))) 170 if (memcmp(settings, &curr_set, sizeof (curr_set)))
60 { 171 {
61 /* Compressor settings have changed since last call */ 172 /* Compressor settings have changed since last call */
62 changed = true; 173 changed = true;
63 174
64#if defined(ROCKBOX_HAS_LOGF) && defined(LOGF_ENABLE) 175#if defined(ROCKBOX_HAS_LOGF) && defined(LOGF_ENABLE)
65 if (settings->threshold != curr_set.threshold) 176 if (settings->threshold != curr_set.threshold)
66 { 177 {
@@ -91,6 +202,10 @@ static bool compressor_update(struct dsp_config *dsp,
91 { 202 {
92 logf(" Compressor Release: %d", release); 203 logf(" Compressor Release: %d", release);
93 } 204 }
205 if (settings->attack_time != cur_set.attack_time)
206 {
207 logf(" Compressor Attack: %d", attack);
208 }
94#endif 209#endif
95 210
96 curr_set = *settings; 211 curr_set = *settings;
@@ -125,18 +240,18 @@ static bool compressor_update(struct dsp_config *dsp,
125 int32_t offset; /* S15.16 format */ 240 int32_t offset; /* S15.16 format */
126 } db_curve[5]; 241 } db_curve[5];
127 242
128 /** Set up the shape of the compression curve first as decibel 243 /** Set up the shape of the compression curve first as decibel values
129 values */ 244 * db_curve[0] = bottom of knee
130 /* db_curve[0] = bottom of knee 245 * [1] = threshold
131 [1] = threshold 246 * [2] = top of knee
132 [2] = top of knee 247 * [3] = 0 db input
133 [3] = 0 db input 248 * [4] = ~+12db input (2 bits clipping overhead)
134 [4] = ~+12db input (2 bits clipping overhead) */ 249 */
135 250
136 db_curve[1].db = threshold << 16; 251 db_curve[1].db = threshold << 16;
137 if (soft_knee) 252 if (soft_knee)
138 { 253 {
139 /* bottom of knee is 3dB below the threshold for soft knee*/ 254 /* bottom of knee is 3dB below the threshold for soft knee */
140 db_curve[0].db = db_curve[1].db - (3 << 16); 255 db_curve[0].db = db_curve[1].db - (3 << 16);
141 /* top of knee is 3dB above the threshold for soft knee */ 256 /* top of knee is 3dB above the threshold for soft knee */
142 db_curve[2].db = db_curve[1].db + (3 << 16); 257 db_curve[2].db = db_curve[1].db + (3 << 16);
@@ -175,24 +290,28 @@ static bool compressor_update(struct dsp_config *dsp,
175 } 290 }
176 291
177 /** Now set up the comp_curve table with compression offsets in the 292 /** Now set up the comp_curve table with compression offsets in the
178 form of gain factors in S7.24 format */ 293 * form of gain factors in S7.24 format
179 /* comp_curve[0] is 0 (-infinity db) input */ 294 * comp_curve[0] is 0 (-infinity db) input
295 */
180 comp_curve[0] = UNITY; 296 comp_curve[0] = UNITY;
181 /* comp_curve[1 to 63] are intermediate compression values 297 /** comp_curve[1 to 63] are intermediate compression values
182 corresponding to the 6 MSB of the input values of a non-clipped 298 * corresponding to the 6 MSB of the input values of a non-clipped
183 signal */ 299 * signal
300 */
184 for (int i = 1; i < 64; i++) 301 for (int i = 1; i < 64; i++)
185 { 302 {
186 /* db constants are stored as positive numbers; 303 /** db constants are stored as positive numbers;
187 make them negative here */ 304 * make them negative here
305 */
188 int32_t this_db = -db[i]; 306 int32_t this_db = -db[i];
189 307
190 /* no compression below the knee */ 308 /* no compression below the knee */
191 if (this_db <= db_curve[0].db) 309 if (this_db <= db_curve[0].db)
192 comp_curve[i] = UNITY; 310 comp_curve[i] = UNITY;
193 311
194 /* if soft knee and below top of knee, 312 /** if soft knee and below top of knee,
195 interpolate along soft knee slope */ 313 * interpolate along soft knee slope
314 */
196 else if (soft_knee && (this_db <= db_curve[2].db)) 315 else if (soft_knee && (this_db <= db_curve[2].db))
197 comp_curve[i] = fp_factor(fp_mul( 316 comp_curve[i] = fp_factor(fp_mul(
198 ((this_db - db_curve[0].db) / 6), 317 ((this_db - db_curve[0].db) / 6),
@@ -204,14 +323,22 @@ static bool compressor_update(struct dsp_config *dsp,
204 fp_div((db_curve[1].db - this_db), db_curve[1].db, 16), 323 fp_div((db_curve[1].db - this_db), db_curve[1].db, 16),
205 db_curve[3].offset, 16), 16) << 8; 324 db_curve[3].offset, 16), 16) << 8;
206 } 325 }
207 /* comp_curve[64] is the compression level of a maximum level, 326 /** comp_curve[64] is the compression level of a maximum level,
208 non-clipped signal */ 327 * non-clipped signal
328 */
209 comp_curve[64] = fp_factor(db_curve[3].offset, 16) << 8; 329 comp_curve[64] = fp_factor(db_curve[3].offset, 16) << 8;
210 330
211 /* comp_curve[65] is the compression level of a maximum level, 331 /** comp_curve[65] is the compression level of a maximum level,
212 clipped signal */ 332 * clipped signal
333 */
213 comp_curve[65] = fp_factor(db_curve[4].offset, 16) << 8; 334 comp_curve[65] = fp_factor(db_curve[4].offset, 16) << 8;
214 335
336 /** if using auto peak, then makeup gain is max offset -
337 * 3dB headroom
338 */
339 comp_makeup_gain = auto_gain ?
340 fp_factor(-(db_curve[3].offset) - 0x4AC4, 16) << 8 : UNITY;
341
215#if defined(ROCKBOX_HAS_LOGF) && defined(LOGF_ENABLE) 342#if defined(ROCKBOX_HAS_LOGF) && defined(LOGF_ENABLE)
216 logf("\n *** Compression Offsets ***"); 343 logf("\n *** Compression Offsets ***");
217 /* some settings for display only, not used in calculations */ 344 /* some settings for display only, not used in calculations */
@@ -233,20 +360,10 @@ static bool compressor_update(struct dsp_config *dsp,
233 if (i % 4 == 0) DEBUGF("\n"); 360 if (i % 4 == 0) DEBUGF("\n");
234 } 361 }
235 DEBUGF("\n"); 362 DEBUGF("\n");
236#endif
237 363
238 /* if using auto peak, then makeup gain is max offset -
239 .1dB headroom */
240 comp_makeup_gain = auto_gain ?
241 fp_factor(-(db_curve[3].offset) - 0x199A, 16) << 8 : UNITY;
242 logf("Makeup gain:\t%.6f", (float)comp_makeup_gain / UNITY); 364 logf("Makeup gain:\t%.6f", (float)comp_makeup_gain / UNITY);
365#endif
243 366
244 /* calculate per-sample gain change a rate of 10db over release time
245 */
246 comp_rel_slope = 0xAF0BB2 / release;
247 logf("Release slope:\t%.6f", (float)comp_rel_slope / UNITY);
248
249 release_gain = UNITY;
250 return active; 367 return active;
251} 368}
252 369
@@ -258,39 +375,41 @@ static inline int32_t get_compression_gain(struct sample_format *format,
258 int32_t sample) 375 int32_t sample)
259{ 376{
260 const int frac_bits_offset = format->frac_bits - 15; 377 const int frac_bits_offset = format->frac_bits - 15;
261 378
262 /* sample must be positive */ 379 /* sample must be positive */
263 if (sample < 0) 380 if (sample < 0)
264 sample = -(sample + 1); 381 sample = -(sample + 1);
265 382
266 /* shift sample into 15 frac bit range */ 383 /* shift sample into 15 frac bit range */
267 if (frac_bits_offset > 0) 384 if (frac_bits_offset > 0)
268 sample >>= frac_bits_offset; 385 sample >>= frac_bits_offset;
269 if (frac_bits_offset < 0) 386 if (frac_bits_offset < 0)
270 sample <<= -frac_bits_offset; 387 sample <<= -frac_bits_offset;
271 388
272 /* normal case: sample isn't clipped */ 389 /* normal case: sample isn't clipped */
273 if (sample < (1 << 15)) 390 if (sample < (1 << 15))
274 { 391 {
275 /* index is 6 MSB, rem is 9 LSB */ 392 /* index is 6 MSB, rem is 9 LSB */
276 int index = sample >> 9; 393 int index = sample >> 9;
277 int32_t rem = (sample & 0x1FF) << 22; 394 int32_t rem = (sample & 0x1FF) << 22;
278 395
279 /* interpolate from the compression curve: 396 /** interpolate from the compression curve:
280 higher gain - ((rem / (1 << 31)) * (higher gain - lower gain)) */ 397 * higher gain - ((rem / (1 << 31)) * (higher gain - lower gain))
398 */
281 return comp_curve[index] - (FRACMUL(rem, 399 return comp_curve[index] - (FRACMUL(rem,
282 (comp_curve[index] - comp_curve[index + 1]))); 400 (comp_curve[index] - comp_curve[index + 1])));
283 } 401 }
284 /* sample is somewhat clipped, up to 2 bits of overhead */ 402 /* sample is somewhat clipped, up to 2 bits of overhead */
285 if (sample < (1 << 17)) 403 if (sample < (1 << 17))
286 { 404 {
287 /* straight interpolation: 405 /** straight interpolation:
288 higher gain - ((clipped portion of sample * 4/3 406 * higher gain - ((clipped portion of sample * 4/3
289 / (1 << 31)) * (higher gain - lower gain)) */ 407 * / (1 << 31)) * (higher gain - lower gain))
408 */
290 return comp_curve[64] - (FRACMUL(((sample - (1 << 15)) / 3) << 16, 409 return comp_curve[64] - (FRACMUL(((sample - (1 << 15)) / 3) << 16,
291 (comp_curve[64] - comp_curve[65]))); 410 (comp_curve[64] - comp_curve[65])));
292 } 411 }
293 412
294 /* sample is too clipped, return invalid value */ 413 /* sample is too clipped, return invalid value */
295 return -1; 414 return -1;
296} 415}
@@ -322,55 +441,115 @@ static void compressor_process(struct dsp_proc_entry *this,
322 441
323 while (count-- > 0) 442 while (count-- > 0)
324 { 443 {
325 /* use lowest (most compressed) gain factor of the output buffer 444
326 sample pair for both samples (mono is also handled correctly here) 445 /* Use the average of the channels */
327 */ 446
328 int32_t sample_gain = UNITY; 447 int32_t sample_gain = UNITY;
448 int32_t x = 0;
449 int32_t tmpx = 0;
450 int32_t in_buf_max_level = 0;
329 for (int ch = 0; ch < num_chan; ch++) 451 for (int ch = 0; ch < num_chan; ch++)
330 { 452 {
331 int32_t this_gain = get_compression_gain(&buf->format, *in_buf[ch]); 453 tmpx = *in_buf[ch];
332 if (this_gain < sample_gain) 454 x += tmpx;
333 sample_gain = this_gain; 455 labuf[ch][delay_write] = tmpx;
456 /* Limiter detection */
457 if(tmpx < 0) tmpx = -(tmpx + 1);
458 if(tmpx > in_buf_max_level) in_buf_max_level = tmpx;
334 } 459 }
335 460
336 /* perform release slope; skip if no compression and no release slope 461 /** Divide it by the number of channels, roughly
462 * It will be exact if the number of channels a power of 2
463 * it will be imperfect otherwise. Real division costs too
464 * much here, and most of the time it will be 2 channels (stereo)
337 */ 465 */
338 if ((sample_gain != UNITY) || (release_gain != UNITY)) 466 x >>= (num_chan >> 1);
339 { 467
340 /* if larger offset than previous slope, start new release slope 468 /** 1p HP Filters: y[n] = a*(y[n-1] + x - x[n-1])
341 */ 469 * Zero and Pole in the same place to reduce computation
342 if ((sample_gain <= release_gain) && (sample_gain > 0)) 470 * Run the first pre-emphasis filter
343 { 471 */
472 int32_t tmp1 = x - hpfx1 + hp1y1;
473 hp1y1 = FRACMUL_SHL(hp1ca, tmp1, 7);
474
475 /* Run the second pre-emphasis filter */
476 tmp1 = x - hpfx1 + hp2y1;
477 hp2y1 = FRACMUL_SHL(hp2ca, tmp1, 7);
478 hpfx1 = x;
479
480 /* Apply weighted sum to the pre-emphasis network */
481 sample_gain = (x>>1) + hp1y1 + (hp2y1<<1); /* x/2 + hp1 + 2*hp2 */
482 sample_gain >>= 1;
483 sample_gain += sample_gain >> 1;
484 sample_gain = get_compression_gain(&buf->format, sample_gain);
485
486 /* Exponential Attack and Release */
487
488 if ((sample_gain <= release_gain) && (sample_gain > 0))
489 {
490 /* Attack */
491 if(attca != UNITY)
492 {
493 int32_t this_gain = FRACMUL_SHL(release_gain, attcb, 7);
494 this_gain += FRACMUL_SHL(sample_gain, attca, 7);
495 release_gain = this_gain;
496 }
497 else
498 {
344 release_gain = sample_gain; 499 release_gain = sample_gain;
500 }
501 /** reset it to delay time so it cannot release before the
502 * delayed signal releases
503 */
504 release_holdoff = delay_time;
505 }
506 else
507 /* Reverse exponential decay to current gain value */
508 {
509 /* Don't start release while output is still above thresh */
510 if(release_holdoff > 0)
511 {
512 release_holdoff--;
345 } 513 }
346 else 514 else
347 /* keep sloping towards unity gain (and ignore invalid value) */
348 { 515 {
349 release_gain += comp_rel_slope; 516 /* Release */
350 if (release_gain > UNITY) 517 int32_t this_gain = FRACMUL_SHL(release_gain, rlscb, 7);
351 { 518 this_gain += FRACMUL_SHL(sample_gain,rlsca,7);
352 release_gain = UNITY; 519 release_gain = this_gain;
353 }
354 } 520 }
521
522 }
523
524 /** total gain factor is the product of release gain and makeup gain,
525 * but avoid computation if possible
526 */
527
528 int32_t total_gain = FRACMUL_SHL(release_gain, comp_makeup_gain, 7);
529
530 /* Look-ahead limiter */
531 int32_t test_gain = FRACMUL_SHL(total_gain, in_buf_max_level, 3);
532 if( test_gain > UNITY)
533 {
534 release_gain -= limitca;
355 } 535 }
356 536
357 /* total gain factor is the product of release gain and makeup gain, 537 /** Implement the compressor: apply total gain factor (if any) to the
358 but avoid computation if possible */ 538 * output buffer sample pair/mono sample
359 int32_t total_gain = ((release_gain == UNITY) ? comp_makeup_gain : 539 */
360 (comp_makeup_gain == UNITY) ? release_gain :
361 FRACMUL_SHL(release_gain, comp_makeup_gain, 7));
362
363 /* Implement the compressor: apply total gain factor (if any) to the
364 output buffer sample pair/mono sample */
365 if (total_gain != UNITY) 540 if (total_gain != UNITY)
366 { 541 {
367 for (int ch = 0; ch < num_chan; ch++) 542 for (int ch = 0; ch < num_chan; ch++)
368 { 543 {
369 *in_buf[ch] = FRACMUL_SHL(total_gain, *in_buf[ch], 7); 544 *in_buf[ch] = FRACMUL_SHL(total_gain, labuf[ch][delay_read], 7);
370 } 545 }
371 } 546 }
372 in_buf[0]++; 547 in_buf[0]++;
373 in_buf[1]++; 548 in_buf[1]++;
549 delay_write++;
550 delay_read++;
551 if(delay_write >= MAX_DLY) delay_write = 0;
552 if(delay_read >= MAX_DLY) delay_read = 0;
374 } 553 }
375 554
376 (void)this; 555 (void)this;
@@ -382,6 +561,8 @@ static intptr_t compressor_configure(struct dsp_proc_entry *this,
382 unsigned int setting, 561 unsigned int setting,
383 intptr_t value) 562 intptr_t value)
384{ 563{
564 int i,j;
565
385 switch (setting) 566 switch (setting)
386 { 567 {
387 case DSP_PROC_INIT: 568 case DSP_PROC_INIT:
@@ -394,7 +575,29 @@ static intptr_t compressor_configure(struct dsp_proc_entry *this,
394 /* Fall-through */ 575 /* Fall-through */
395 case DSP_RESET: 576 case DSP_RESET:
396 case DSP_FLUSH: 577 case DSP_FLUSH:
578
397 release_gain = UNITY; 579 release_gain = UNITY;
580 for(i=0; i<MAX_CH; i++)
581 {
582 for(j=0; j<MAX_DLY; j++)
583 {
584 labuf[i][j] = 0; /* All Silence */
585 }
586 }
587
588 /* Delay Line Read/Write Pointers */
589 int32_t fs = dsp_get_output_frequency(dsp);
590 delay_read = 0;
591 delay_write = (DLY_TIME*fs/1000);
592 if(delay_write >= MAX_DLY) {
593 delay_write = MAX_DLY - 1; /* Limit to the max allocated buffer */
594 }
595
596 delay_time = delay_write;
597 release_holdoff = delay_write;
598 limitca = get_att_rls_coeff(DLY_TIME, fs); /** Attack time for
599 * look-ahead limiter
600 */
398 break; 601 break;
399 602
400 case DSP_SET_OUT_FREQUENCY: 603 case DSP_SET_OUT_FREQUENCY:
diff --git a/lib/rbcodec/dsp/compressor.h b/lib/rbcodec/dsp/compressor.h
index e41950926e..35aa0eeb65 100644
--- a/lib/rbcodec/dsp/compressor.h
+++ b/lib/rbcodec/dsp/compressor.h
@@ -28,6 +28,7 @@ struct compressor_settings
28 int ratio; 28 int ratio;
29 int knee; 29 int knee;
30 int release_time; 30 int release_time;
31 int attack_time;
31}; 32};
32 33
33void dsp_set_compressor(const struct compressor_settings *settings); 34void dsp_set_compressor(const struct compressor_settings *settings);