-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathCompressor.h
129 lines (105 loc) · 3.18 KB
/
Compressor.h
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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#pragma once
#include <cmath>
#include "Commons.h"
/**
* https://git.iem.at/audioplugins/IEMPluginSuite/blob/master/resources/Compressor.h
*/
class Compressor
{
private:
float sampleRate_;
float threshold_;
float ratio_, expo_;
float attack_;
float release_;
// Internal variables
float thrlin_, thrlinr_;
float cteAT_;
float cteRL_;
// State variables
float leftS1_ = 0.f, rightS1_ = 0.f;
public:
Compressor(float sampleRate)
{
sampleRate_ = sampleRate;
setRatio(4.f);
setAttack(1.f);
setRelease(100.f);
setThreshold(-10.f);
};
~Compressor()
{
};
static Compressor* create(float sampleRate)
{
return new Compressor(sampleRate);
}
static void destroy(Compressor* obj)
{
delete obj;
}
void setThreshold(float value)
{
if (fabs(value - threshold_) < 1.f)
{
return;
}
threshold_ = value;
thrlin_ = Db2A(threshold_);
thrlinr_ = 1.f / thrlin_;
}
void setRatio(float value)
{
ratio_ = value;
expo_ = 1.f / ratio_ - 1.f;
}
void setAttack(float value)
{
attack_ = value;
cteAT_ = exp (-2.f * M_PI * 1000.f / attack_ / sampleRate_);
}
void setRelease(float value)
{
release_ = value;
cteRL_ = exp (-2.f * M_PI * 1000.f / release_ / sampleRate_);
}
float process(float input)
{
float leftSideInput = fabs(input);
// Ballistics filter and envelope generation
float leftCte = (leftSideInput >= leftS1_ ? cteAT_ : cteRL_);
float leftEnv = leftSideInput + leftCte * (leftS1_ - leftSideInput);
leftS1_ = leftEnv;
// Compressor transfer function
float leftCv = (leftEnv <= thrlin_ ? 1.f : fast_powf(leftEnv * thrlinr_, expo_));
// Processing
return input * leftCv;
}
void process(AudioBuffer &input, AudioBuffer &output)
{
int size = input.getSize();
FloatArray leftIn = input.getSamples(0);
FloatArray rightIn = input.getSamples(1);
FloatArray leftOut = output.getSamples(0);
FloatArray rightOut = output.getSamples(1);
for (int i = 0; i < size; i++)
{
// Detector (peak)
float leftSideInput = abs(leftIn[i]);
float rightSideInput = abs(rightIn[i]);
// Ballistics filter and envelope generation
float leftCte = (leftSideInput >= leftS1_ ? cteAT_ : cteRL_);
float leftEnv = leftSideInput + leftCte * (leftS1_ - leftSideInput);
leftS1_ = leftEnv;
float rightCte = (rightSideInput >= rightS1_ ? cteAT_ : cteRL_);
float rightEnv = rightSideInput + rightCte * (rightS1_ - rightSideInput);
rightS1_ = rightEnv;
// Compressor transfer function
float leftCv = (leftEnv <= thrlin_ ? 1.f : fast_powf(leftEnv / thrlin_, expo_));
float rightCv = (rightEnv <= thrlin_ ? 1.f : fast_powf(rightEnv / thrlin_, expo_));
// Processing
leftOut[i] = leftIn[i] * leftCv;
rightOut[i] = rightIn[i] * rightCv;
}
}
};