Audacity 3.2.0
BassTrebleBase.cpp
Go to the documentation of this file.
1/**********************************************************************
2
3 Audacity: A Digital Audio Editor
4 Audacity(R) is copyright (c) 1999-2016 Audacity Team.
5 License: GPL v2 or later. See License.txt.
6
7 BassTreble.cpp
8 Steve Daulton
9
10**********************************************************************/
11#include "BassTrebleBase.h"
12#include "ShuttleAutomation.h"
13
15{
17 parameters;
18 return parameters;
19}
20
21const ComponentInterfaceSymbol BassTrebleBase::Symbol { XO("Bass and Treble") };
22
24{
26}
27
29{
30}
31
32// ComponentInterface implementation
33
35{
36 return Symbol;
37}
38
40{
41 return XO("Simple tone control effect");
42}
43
45{
46 return L"Bass_and_Treble";
47}
48
49// EffectDefinitionInterface implementation
50
52{
53 return EffectTypeProcess;
54}
55
57{
59}
60
62{
63 return 1;
64}
65
67{
68 return 1;
69}
70
73{
74 InstanceInit(settings, mState, sampleRate);
75 return true;
76}
77
79 EffectSettings& settings, const float* const* inBlock,
80 float* const* outBlock, size_t blockLen)
81{
82 return InstanceProcess(settings, mState, inBlock, outBlock, blockLen);
83}
84
86{
87 SetBlockSize(512);
88 mSlaves.clear();
89 return true;
90}
91
93 EffectSettings& settings, EffectOutputs* pOutputs, unsigned numChannels,
94 float sampleRate)
95{
96 BassTrebleBase::Instance slave(mProcessor);
97
98 InstanceInit(settings, slave.mState, sampleRate);
99
100 mSlaves.push_back(slave);
101
102 return true;
103}
104
106{
107 mSlaves.clear();
108
109 return true;
110}
111
113 size_t group, EffectSettings& settings, const float* const* inbuf,
114 float* const* outbuf, size_t numSamples)
115{
116 if (group >= mSlaves.size())
117 return 0;
118 return InstanceProcess(
119 settings, mSlaves[group].mState, inbuf, outbuf, numSamples);
120}
121
123 EffectSettings& settings, BassTrebleState& data, const float* const* inBlock,
124 float* const* outBlock, size_t blockLen)
125{
126 auto& ms = GetSettings(settings);
127
128 const float* ibuf = inBlock[0];
129 float* obuf = outBlock[0];
130
131 // Set value to ensure correct rounding
132 double oldBass = DB_TO_LINEAR(ms.mBass);
133 double oldTreble = DB_TO_LINEAR(ms.mTreble);
134
135 data.gain = DB_TO_LINEAR(ms.mGain);
136
137 // Compute coefficients of the low shelf biquand IIR filter
138 if (data.bass != oldBass)
139 Coefficients(
140 data.hzBass, data.slope, ms.mBass, data.samplerate, kBass, data.a0Bass,
141 data.a1Bass, data.a2Bass, data.b0Bass, data.b1Bass, data.b2Bass);
142
143 // Compute coefficients of the high shelf biquand IIR filter
144 if (data.treble != oldTreble)
145 Coefficients(
146 data.hzTreble, data.slope, ms.mTreble, data.samplerate, kTreble,
147 data.a0Treble, data.a1Treble, data.a2Treble, data.b0Treble,
148 data.b1Treble, data.b2Treble);
149
150 for (decltype(blockLen) i = 0; i < blockLen; i++)
151 {
152 obuf[i] = DoFilter(data, ibuf[i]) * data.gain;
153 }
154
155 return blockLen;
156}
157
159 double hz, double slope, double gain, double samplerate, int type,
160 double& a0, double& a1, double& a2, double& b0, double& b1, double& b2)
161{
162 double w = 2 * M_PI * hz / samplerate;
163 double a = exp(log(10.0) * gain / 40);
164 double b = sqrt((a * a + 1) / slope - (pow((a - 1), 2)));
165
166 if (type == kBass)
167 {
168 b0 = a * ((a + 1) - (a - 1) * cos(w) + b * sin(w));
169 b1 = 2 * a * ((a - 1) - (a + 1) * cos(w));
170 b2 = a * ((a + 1) - (a - 1) * cos(w) - b * sin(w));
171 a0 = ((a + 1) + (a - 1) * cos(w) + b * sin(w));
172 a1 = -2 * ((a - 1) + (a + 1) * cos(w));
173 a2 = (a + 1) + (a - 1) * cos(w) - b * sin(w);
174 }
175 else // assumed kTreble
176 {
177 b0 = a * ((a + 1) + (a - 1) * cos(w) + b * sin(w));
178 b1 = -2 * a * ((a - 1) + (a + 1) * cos(w));
179 b2 = a * ((a + 1) + (a - 1) * cos(w) - b * sin(w));
180 a0 = ((a + 1) - (a - 1) * cos(w) + b * sin(w));
181 a1 = 2 * ((a - 1) - (a + 1) * cos(w));
182 a2 = (a + 1) - (a - 1) * cos(w) - b * sin(w);
183 }
184}
185
187{
188 // Bass filter
189 float out = (data.b0Bass * in + data.b1Bass * data.xn1Bass +
190 data.b2Bass * data.xn2Bass - data.a1Bass * data.yn1Bass -
191 data.a2Bass * data.yn2Bass) /
192 data.a0Bass;
193 data.xn2Bass = data.xn1Bass;
194 data.xn1Bass = in;
195 data.yn2Bass = data.yn1Bass;
196 data.yn1Bass = out;
197
198 // Treble filter
199 in = out;
200 out = (data.b0Treble * in + data.b1Treble * data.xn1Treble +
201 data.b2Treble * data.xn2Treble - data.a1Treble * data.yn1Treble -
202 data.a2Treble * data.yn2Treble) /
203 data.a0Treble;
204 data.xn2Treble = data.xn1Treble;
205 data.xn1Treble = in;
206 data.yn2Treble = data.yn1Treble;
207 data.yn1Treble = out;
208
209 return out;
210}
211
214{
215 auto& ms = GetSettings(settings);
216
217 data.samplerate = sampleRate;
218 data.slope = 0.4f; // same slope for both filters
219 data.hzBass = 250.0f; // could be tunable in a more advanced version
220 data.hzTreble = 4000.0f; // could be tunable in a more advanced version
221
222 data.a0Bass = 1;
223 data.a1Bass = 0;
224 data.a2Bass = 0;
225 data.b0Bass = 0;
226 data.b1Bass = 0;
227 data.b2Bass = 0;
228
229 data.a0Treble = 1;
230 data.a1Treble = 0;
231 data.a2Treble = 0;
232 data.b0Treble = 0;
233 data.b1Treble = 0;
234 data.b2Treble = 0;
235
236 data.xn1Bass = 0;
237 data.xn2Bass = 0;
238 data.yn1Bass = 0;
239 data.yn2Bass = 0;
240
241 data.xn1Treble = 0;
242 data.xn2Treble = 0;
243 data.yn1Treble = 0;
244 data.yn2Treble = 0;
245
246 data.bass = -1;
247 data.treble = -1;
248 data.gain = DB_TO_LINEAR(ms.mGain);
249}
250
252 const EffectSettings& settings) const
253{
254 auto& ms = GetSettings(settings);
255
256 return (ms.mBass == 0.0 && ms.mTreble == 0.0 && ms.mGain == 0.0);
257}
@ kBass
@ kTreble
#define M_PI
Definition: Distortion.cpp:30
struct State mState
EffectType
@ EffectTypeProcess
ChannelName
XO("Cut/Copy/Paste")
#define DB_TO_LINEAR(x)
Definition: MemoryX.h:338
static Settings & settings()
Definition: TrackInfo.cpp:51
EffectType GetType() const override
Type determines how it behaves.
const EffectParameterMethods & Parameters() const override
TranslatableString GetDescription() const override
static const ComponentInterfaceSymbol Symbol
RealtimeSince RealtimeSupport() const override
Since which version of Audacity has the effect supported realtime?
bool CheckWhetherSkipEffect(const EffectSettings &settings) const override
After Init(), tell whether Process() should be skipped.
ManualPageID ManualPage() const override
Name of a page in the Audacity alpha manual, default is empty.
virtual ~BassTrebleBase()
ComponentInterfaceSymbol GetSymbol() const override
Generates EffectParameterMethods overrides from variadic template arguments.
ComponentInterfaceSymbol pairs a persistent string identifier used internally with an optional,...
void SetLinearEffectFlag(bool linearEffectFlag)
Definition: EffectBase.cpp:210
RealtimeSince
In which versions of Audacity was an effect realtime capable?
Hold values to send to effect output meters.
Interface for manipulations of an Effect's settings.
static BassTrebleSettings & GetSettings(EffectSettings &settings)
Assume settings originated from MakeSettings() and copies thereof.
Definition: Effect.h:166
Holds a msgid for the translation catalog; may also bind format arguments.
__finl float_x4 __vecc sqrt(const float_x4 &a)
bool RealtimeInitialize(EffectSettings &settings, double) override
static size_t InstanceProcess(EffectSettings &settings, BassTrebleState &data, const float *const *inBlock, float *const *outBlock, size_t blockLen)
static void Coefficients(double hz, double slope, double gain, double samplerate, int type, double &a0, double &a1, double &a2, double &b0, double &b1, double &b2)
static void InstanceInit(EffectSettings &settings, BassTrebleState &data, float sampleRate)
size_t RealtimeProcess(size_t group, EffectSettings &settings, const float *const *inbuf, float *const *outbuf, size_t numSamples) override
static float DoFilter(BassTrebleState &data, float in)
size_t ProcessBlock(EffectSettings &settings, const float *const *inBlock, float *const *outBlock, size_t blockLen) override
Called for destructive effect computation.
bool RealtimeFinalize(EffectSettings &settings) noexcept override
bool ProcessInitialize(EffectSettings &settings, double sampleRate, ChannelNames chanMap) override
bool RealtimeAddProcessor(EffectSettings &settings, EffectOutputs *pOutputs, unsigned numChannels, float sampleRate) override
unsigned GetAudioInCount() const override
How many input buffers to allocate at once.
unsigned GetAudioOutCount() const override
How many output buffers to allocate at once.
Externalized state of a plug-in.