-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathlimiter.c
39 lines (33 loc) · 1.3 KB
/
limiter.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <math.h>
#include "limiter.h"
#define MAX(x,y) ((x)>(y)?(x):(y))
limiter_state init_limiter(float attack_coeff, float release_coeff, int delay_len) {
limiter_state state;
state.attack_coeff = attack_coeff;
state.release_coeff = release_coeff;
state.delay_index = 0;
state.envelope = 0;
state.current_gain = 1;
state.delay_length = delay_len;
return state;
}
void limit(float *signal, int block_length, float threshold,
float *delay_line, limiter_state *state) {
for(int i=0; i<block_length; i++) {
delay_line[state->delay_index] = signal[i];
state->delay_index = (state->delay_index + 1) % state->delay_length;
// calculate an envelope of the signal
state->envelope *= state->release_coeff;
state->envelope = MAX(fabs(signal[i]), state->envelope);
// have current_gain go towards a desired limiter target_gain
float target_gain;
if (state->envelope > threshold)
target_gain = (1+threshold-state->envelope);
else
target_gain = 1.0;
state->current_gain = state->current_gain*state->attack_coeff +
target_gain*(1-state->attack_coeff);
// limit the delayed signal
signal[i] = delay_line[state->delay_index] * state->current_gain;
}
}