-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcompressor.c
81 lines (69 loc) · 2.01 KB
/
compressor.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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#include "compressor.h"
float gainComputedComp;
float gainSmootedComp;
dynamic_compressor_t generate_compressor(
float threshold,
float ratio,
float width,
float attack,
float release,
float gain,
uint16_t samplerate)
{
float glin = powf(10.0f, (gain / 20.0f)) - 1.0f;
double lnine = log10(9.0f);
float alphaA = expf(-lnine / (attack * samplerate));
float alphaR = expf(-lnine / (release * samplerate));
float OMalphaA = (1 - alphaA);
float OMalphaR = (1 - alphaR);
dynamic_compressor_t c = {
.alphaA = alphaA,
.alphaR = alphaR,
.OMalphaA = OMalphaA,
.OMalphaR = OMalphaR,
.ratio = ratio,
.width = width,
.gain = glin,
.threshold = threshold,
.gs = 1.0f,
};
return c;
}
void dynamic_compressor(sample_t *s, dynamic_compressor_t *c)
{
float xnormal = fabsf(*s);
float xdb = 20.0f * log10f(xnormal);
// gain computer
float xsc = 0.0f;
if (xdb < (c->threshold - (c->width / 2)))
{
xsc = xdb;
}
else if (((c->threshold - (c->width / 2)) <= xdb) && (xdb <= (c->threshold + (c->width / 2))))
{
xsc = xdb + (((1 / c->ratio) - 1) * \
( (xdb - c->threshold + (c->width / 2)) * (xdb - c->threshold + (c->width / 2)) ) ) / \
(2 * c->width);
}
else if (xdb > (c->threshold + (c->width / 2)))
{
xsc = c->threshold + ((xdb - c->threshold) / c->ratio);
}
gainComputedComp = xsc - xdb;
// smoothing
if (gainComputedComp <= gainSmootedComp)
{
gainSmootedComp = c->alphaA * gainSmootedComp + c->OMalphaA * gainComputedComp;
}
else if (gainComputedComp > gainSmootedComp)
{
gainSmootedComp = c->alphaR * gainSmootedComp + c->OMalphaR * gainComputedComp;
}
// makeup
c->gs = gainSmootedComp;
gainSmootedComp += c->gain;
// apply
float glin = powFastLookup(gainSmootedComp / 20.0f, BASE10);
// float glin = powf(10.0f, gainSmootedComp / 20.0f);
*s = (*s) * glin;
}