Audacity 3.2.0
ScienFilterBase.cpp
Go to the documentation of this file.
1/**********************************************************************
2
3 Audacity: A Digital Audio Editor
4
5 ScienFilterBase.cpp
6
7 Norm C
8 Mitch Golden
9 Vaughan Johnson (Preview)
10
11*******************************************************************//*******************************************************************/
23#include "ScienFilterBase.h"
24#include "BasicUI.h"
25#include "Prefs.h"
26#include "Project.h"
27#include "WaveTrack.h"
28#include <cmath>
29
30#if !defined(M_PI)
31# define PI = 3.1415926535897932384626433832795
32#else
33# define PI M_PI
34#endif
35#define square(a) ((a) * (a))
36
38 /*i18n-hint: Butterworth is the name of the person after whom the filter type
39 is named.*/
40 { XO("Butterworth") },
41 /*i18n-hint: Chebyshev is the name of the person after whom the filter type
42 is named.*/
43 { XO("Chebyshev Type I") },
44 /*i18n-hint: Chebyshev is the name of the person after whom the filter type
45 is named.*/
46 { XO("Chebyshev Type II") }
47};
48
50 // These are acceptable dual purpose internal/visible names
51 { XO("Lowpass") },
52 { XO("Highpass") }
53};
54
56{
57 static CapturedParameters<
59 parameters {
61 bool updating) {
62 if (updating)
63 {
64 e.mOrderIndex = e.mOrder - 1;
65 e.CalcFilter();
66 }
67 return true;
68 },
69 };
70 return parameters;
71}
72
73//----------------------------------------------------------------------------
74// ScienFilterBase
75//----------------------------------------------------------------------------
76
78 "Classic Filters") };
79
81{
82 Parameters().Reset(*this);
84
85 mOrderIndex = mOrder - 1;
86
87 mdBMin = -30.0;
88 mdBMax = 30.0;
89
90 mLoFreq = 20; // Lowest frequency to display in response graph
91 mNyquist =
92 44100.0 /
93 2.0; // only used during initialization, updated when effect is used
94}
95
97{
98}
99
100// ComponentInterface implementation
101
103{
104 return Symbol;
105}
106
108{
109 /* i18n-hint: "infinite impulse response" */
110 return XO("Performs IIR filtering that emulates analog filters");
111}
112
114{
115 return L"Classic_Filters";
116}
117
118// EffectDefinitionInterface implementation
119
121{
122 return EffectTypeProcess;
123}
124
126{
127 return 1;
128}
129
131{
132 return 1;
133}
134
136 EffectSettings&, double, ChannelNames chanMap)
137{
138 for (int iPair = 0; iPair < (mOrder + 1) / 2; iPair++)
139 mpBiquad[iPair].Reset();
140 return true;
141}
142
144 EffectSettings&, const float* const* inBlock, float* const* outBlock,
145 size_t blockLen)
146{
147 const float* ibuf = inBlock[0];
148 for (int iPair = 0; iPair < (mOrder + 1) / 2; iPair++)
149 {
150 mpBiquad[iPair].Process(ibuf, outBlock[0], blockLen);
151 ibuf = outBlock[0];
152 }
153
154 return blockLen;
155}
156
157// Effect implementation
158
160{
161 int selcount = 0;
162 double rate = 0.0;
163
164 auto trackRange = inputTracks()->Selected<const WaveTrack>();
165
166 {
167 auto t = *trackRange.begin();
168 mNyquist = (t ? t->GetRate() : mProjectRate) / 2.0;
169 }
170
171 for (auto t : trackRange)
172 {
173 if (selcount == 0)
174 rate = t->GetRate();
175 else
176 {
177 if (t->GetRate() != rate)
178 {
180 "To apply a filter, all selected tracks must have the same sample rate."));
181 return false;
182 }
183 }
184 ++selcount;
185 }
186
187 return true;
188}
189
191{
192 switch (mFilterType)
193 {
194 case kButterworth:
197 break;
198 case kChebyshevTypeI:
201 break;
202 case kChebyshevTypeII:
205 break;
206 }
207}
208
210{
211 float Magn;
212 if (Freq >= mNyquist)
213 Freq = mNyquist - 1; // prevent tan(PI/2)
214 float FreqWarped = tan(PI * Freq / (2 * mNyquist));
215 if (mCutoff >= mNyquist)
216 mCutoff = mNyquist - 1;
217 float CutoffWarped = tan(PI * mCutoff / (2 * mNyquist));
218 float fOverflowThresh =
219 pow(10.0, 12.0 / (2 * mOrder)); // once we exceed 10^12 there's not much
220 // to be gained and overflow could happen
221
222 switch (mFilterType)
223 {
224 case kButterworth: // Butterworth
225 default:
226 switch (mFilterSubtype)
227 {
228 case kLowPass: // lowpass
229 default:
230 if (FreqWarped / CutoffWarped > fOverflowThresh) // prevent pow()
231 // overflow
232 Magn = 0;
233 else
234 Magn = sqrt(1 / (1 + pow(FreqWarped / CutoffWarped, 2 * mOrder)));
235 break;
236 case kHighPass: // highpass
237 if (FreqWarped / CutoffWarped > fOverflowThresh)
238 Magn = 1;
239 else
240 Magn = sqrt(
241 pow(FreqWarped / CutoffWarped, 2 * mOrder) /
242 (1 + pow(FreqWarped / CutoffWarped, 2 * mOrder)));
243 break;
244 }
245 break;
246
247 case kChebyshevTypeI: // Chebyshev Type 1
248 double eps;
249 eps = sqrt(pow(10.0, std::max<double>(0.001, mRipple) / 10.0) - 1);
250 double chebyPolyVal;
251 switch (mFilterSubtype)
252 {
253 case 0: // lowpass
254 default:
255 chebyPolyVal = Biquad::ChebyPoly(mOrder, FreqWarped / CutoffWarped);
256 Magn = sqrt(1 / (1 + square(eps) * square(chebyPolyVal)));
257 break;
258 case 1:
259 chebyPolyVal = Biquad::ChebyPoly(mOrder, CutoffWarped / FreqWarped);
260 Magn = sqrt(1 / (1 + square(eps) * square(chebyPolyVal)));
261 break;
262 }
263 break;
264
265 case kChebyshevTypeII: // Chebyshev Type 2
266 eps = 1 / sqrt(pow(10.0, std::max<double>(0.001, mStopbandRipple) / 10.0) - 1);
267 switch (mFilterSubtype)
268 {
269 case kLowPass: // lowpass
270 default:
271 chebyPolyVal = Biquad::ChebyPoly(mOrder, CutoffWarped / FreqWarped);
272 Magn = sqrt(1 / (1 + 1 / (square(eps) * square(chebyPolyVal))));
273 break;
274 case kHighPass:
275 chebyPolyVal = Biquad::ChebyPoly(mOrder, FreqWarped / CutoffWarped);
276 Magn = sqrt(1 / (1 + 1 / (square(eps) * square(chebyPolyVal))));
277 break;
278 }
279 break;
280 }
281
282 return Magn;
283}
Toolkit-neutral facade for basic user interface services.
EffectType
@ EffectTypeProcess
ChannelName
XO("Cut/Copy/Paste")
@ nTypes
#define square(a)
#define PI
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
const TrackList * inputTracks() const
Definition: EffectBase.h:102
double mProjectRate
Definition: EffectBase.h:119
Interface for manipulations of an Effect's settings.
virtual void Reset(Effect &effect) const =0
An Effect that applies 'classical' IIR filters.
static const EnumValueSymbol kTypeStrings[nTypes]
unsigned GetAudioInCount() const override
How many input buffers to allocate at once.
float FilterMagnAtFreq(float Freq)
static constexpr EnumParameter Subtype
size_t ProcessBlock(EffectSettings &settings, const float *const *inBlock, float *const *outBlock, size_t blockLen) override
Called for destructive effect computation.
static constexpr EffectParameter Stopband
ComponentInterfaceSymbol GetSymbol() const override
ManualPageID ManualPage() const override
Name of a page in the Audacity alpha manual, default is empty.
TranslatableString GetDescription() const override
ArrayOf< Biquad > mpBiquad
bool Init() override
bool ProcessInitialize(EffectSettings &settings, double sampleRate, ChannelNames chanMap) override
static const ComponentInterfaceSymbol Symbol
static constexpr EffectParameter Cutoff
static constexpr EffectParameter Order
EffectType GetType() const override
Type determines how it behaves.
virtual ~ScienFilterBase()
unsigned GetAudioOutCount() const override
How many output buffers to allocate at once.
static const EnumValueSymbol kSubTypeStrings[nSubTypes]
static constexpr EnumParameter Type
static constexpr EffectParameter Passband
const EffectParameterMethods & Parameters() const override
auto Selected() -> TrackIterRange< TrackType >
Definition: Track.h:967
Holds a msgid for the translation catalog; may also bind format arguments.
A Track that contains audio waveform data.
Definition: WaveTrack.h:203
MessageBoxResult ShowMessageBox(const TranslatableString &message, MessageBoxOptions options={})
Show a modal message box with either Ok or Yes and No, and optionally Cancel.
Definition: BasicUI.h:287
__finl float_x4 __vecc sqrt(const float_x4 &a)
static ArrayOf< Biquad > CalcButterworthFilter(int order, double fn, double fc, int type)
Definition: Biquad.cpp:64
static ArrayOf< Biquad > CalcChebyshevType2Filter(int order, double fn, double fc, double ripple, int type)
Definition: Biquad.cpp:228
static double ChebyPoly(int Order, double NormFreq)
Definition: Biquad.cpp:329
static ArrayOf< Biquad > CalcChebyshevType1Filter(int order, double fn, double fc, double ripple, int type)
Definition: Biquad.cpp:146
Externalized state of a plug-in.