Audacity 3.2.0
PhaserBase.cpp
Go to the documentation of this file.
1/**********************************************************************
2
3 Audacity: A Digital Audio Editor
4
5 PhaserBase.cpp
6
7 Nasca Octavian Paul (Paul Nasca)
8
9*******************************************************************//*******************************************************************/
15#include "PhaserBase.h"
16#include "EffectInterface.h"
17
19{
20 static CapturedParameters<
22 parameters {
23
25 bool updating) {
26 if (updating)
27 e.mStages &= ~1; // must be even, but don't complain about it
28 return true;
29 },
30 };
31 return parameters;
32}
33
34//
35#define phaserlfoshape 4.0
36
37// How many samples are processed before recomputing the lfo value again
38#define lfoskipsamples 20
39
40//
41// PhaserBase
42//
43
45
46std::shared_ptr<EffectInstance> PhaserBase::MakeInstance() const
47{
48 return std::make_shared<Instance>(*this);
49}
50
52{
54}
55
57{
58}
59
60// ComponentInterface implementation
61
63{
64 return Symbol;
65}
66
68{
69 return XO("Combines phase-shifted signals with the original signal");
70}
71
73{
74 return L"Phaser";
75}
76
77// EffectDefinitionInterface implementation
78
80{
81 return EffectTypeProcess;
82}
83
85{
87}
88
90{
91 return 1;
92}
93
95{
96 return 1;
97}
98
101{
102 InstanceInit(settings, mState, sampleRate);
103 if (chanMap[0] == ChannelNameFrontRight)
104 mState.phase += M_PI;
105 return true;
106}
107
109 EffectSettings& settings, const float* const* inBlock,
110 float* const* outBlock, size_t blockLen)
111{
112 return InstanceProcess(settings, mState, inBlock, outBlock, blockLen);
113}
114
116{
117 SetBlockSize(512);
118 mSlaves.clear();
119 return true;
120}
121
124{
125 PhaserBase::Instance slave(mProcessor);
126
127 InstanceInit(settings, slave.mState, sampleRate);
128
129 mSlaves.push_back(slave);
130
131 return true;
132}
133
135{
136 mSlaves.clear();
137
138 return true;
139}
140
142 size_t group, EffectSettings& settings, const float* const* inbuf,
143 float* const* outbuf, size_t numSamples)
144{
145 if (group >= mSlaves.size())
146 return 0;
147 return InstanceProcess(
148 settings, mSlaves[group].mState, inbuf, outbuf, numSamples);
149}
150
151// PhaserBase implementation
152
155{
156 auto& ms = GetSettings(settings);
157
158 data.samplerate = sampleRate;
159
160 for (int j = 0; j < ms.mStages; j++)
161 {
162 data.old[j] = 0;
163 }
164
165 data.skipcount = 0;
166 data.gain = 0;
167 data.fbout = 0;
168 data.laststages = 0;
169 data.outgain = 0;
170
171 return;
172}
173
176 const float* const* inBlock, float* const* outBlock, size_t blockLen)
177{
178 auto& ms = GetSettings(settings);
179
180 const float* ibuf = inBlock[0];
181 float* obuf = outBlock[0];
182
183 for (int j = data.laststages; j < ms.mStages; j++)
184 {
185 data.old[j] = 0;
186 }
187 data.laststages = ms.mStages;
188
189 data.lfoskip = ms.mFreq * 2 * M_PI / data.samplerate;
190 data.phase = ms.mPhase * M_PI / 180;
191 data.outgain = DB_TO_LINEAR(ms.mOutGain);
192
193 for (decltype(blockLen) i = 0; i < blockLen; i++)
194 {
195 double in = ibuf[i];
196
197 double m =
198 in + data.fbout * ms.mFeedback /
199 101; // Feedback must be less than 100% to avoid infinite gain.
200
201 if (((data.skipcount++) % lfoskipsamples) == 0)
202 {
203 // compute sine between 0 and 1
204 data.gain =
205 (1.0 +
206 cos(data.skipcount.as_double() * data.lfoskip + data.phase)) /
207 2.0;
208
209 // change lfo shape
210 data.gain = expm1(data.gain * phaserlfoshape) / expm1(phaserlfoshape);
211
212 // attenuate the lfo
213 data.gain = 1.0 - data.gain / 255.0 * ms.mDepth;
214 }
215
216 // phasing routine
217 for (int j = 0; j < ms.mStages; j++)
218 {
219 double tmp = data.old[j];
220 data.old[j] = data.gain * tmp + m;
221 m = tmp - data.gain * data.old[j];
222 }
223 data.fbout = m;
224
225 obuf[i] =
226 (float)(data.outgain * (m * ms.mDryWet + in * (255 - ms.mDryWet)) / 255);
227 }
228
229 return blockLen;
230}
#define M_PI
Definition: Distortion.cpp:22
struct State mState
EffectType
@ EffectTypeProcess
ChannelName
@ ChannelNameFrontRight
XO("Cut/Copy/Paste")
#define DB_TO_LINEAR(x)
Definition: MemoryX.h:338
#define phaserlfoshape
Definition: PhaserBase.cpp:35
#define lfoskipsamples
Definition: PhaserBase.cpp:38
static Settings & settings()
Definition: TrackInfo.cpp:51
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.
double old[NUM_STAGES]
Definition: PhaserBase.h:29
sampleCount skipcount
Definition: PhaserBase.h:28
static EffectPhaserSettings & GetSettings(EffectSettings &settings)
Assume settings originated from MakeSettings() and copies thereof.
Definition: Effect.h:166
An Effect that changes frequencies in a time varying manner.
Definition: PhaserBase.h:71
static constexpr EffectParameter Depth
Definition: PhaserBase.h:178
const EffectParameterMethods & Parameters() const override
Definition: PhaserBase.cpp:18
TranslatableString GetDescription() const override
Definition: PhaserBase.cpp:67
static constexpr EffectParameter DryWet
Definition: PhaserBase.h:155
std::shared_ptr< EffectInstance > MakeInstance() const override
Make an object maintaining short-term state of an Effect.
Definition: PhaserBase.cpp:46
RealtimeSince RealtimeSupport() const override
Since which version of Audacity has the effect supported realtime?
Definition: PhaserBase.cpp:84
static constexpr EffectParameter Feedback
Definition: PhaserBase.h:185
static constexpr EffectParameter Freq
Definition: PhaserBase.h:164
static constexpr EffectParameter Phase
Definition: PhaserBase.h:171
static const ComponentInterfaceSymbol Symbol
Definition: PhaserBase.h:73
static constexpr EffectParameter Stages
Definition: PhaserBase.h:146
virtual ~PhaserBase()
Definition: PhaserBase.cpp:56
static constexpr EffectParameter OutGain
Definition: PhaserBase.h:194
ManualPageID ManualPage() const override
Name of a page in the Audacity alpha manual, default is empty.
Definition: PhaserBase.cpp:72
ComponentInterfaceSymbol GetSymbol() const override
Definition: PhaserBase.cpp:62
EffectType GetType() const override
Type determines how it behaves.
Definition: PhaserBase.cpp:79
Holds a msgid for the translation catalog; may also bind format arguments.
double as_double() const
Definition: SampleCount.h:46
Externalized state of a plug-in.
bool RealtimeAddProcessor(EffectSettings &settings, EffectOutputs *pOutputs, unsigned numChannels, float sampleRate) override
Definition: PhaserBase.cpp:122
bool RealtimeFinalize(EffectSettings &settings) noexcept override
Definition: PhaserBase.cpp:134
unsigned GetAudioInCount() const override
How many input buffers to allocate at once.
Definition: PhaserBase.cpp:89
bool RealtimeInitialize(EffectSettings &settings, double) override
Definition: PhaserBase.cpp:115
EffectPhaserState mState
Definition: PhaserBase.h:138
bool ProcessInitialize(EffectSettings &settings, double sampleRate, ChannelNames chanMap) override
Definition: PhaserBase.cpp:99
void InstanceInit(EffectSettings &settings, EffectPhaserState &data, float sampleRate)
Definition: PhaserBase.cpp:153
size_t ProcessBlock(EffectSettings &settings, const float *const *inBlock, float *const *outBlock, size_t blockLen) override
Called for destructive effect computation.
Definition: PhaserBase.cpp:108
unsigned GetAudioOutCount() const override
How many output buffers to allocate at once.
Definition: PhaserBase.cpp:94
size_t RealtimeProcess(size_t group, EffectSettings &settings, const float *const *inbuf, float *const *outbuf, size_t numSamples) override
Definition: PhaserBase.cpp:141
size_t InstanceProcess(EffectSettings &settings, EffectPhaserState &data, const float *const *inBlock, float *const *outBlock, size_t blockLen)
Definition: PhaserBase.cpp:174