11namespace tracktion {
inline namespace engine
19 bool isGain_,
bool isFreq_,
bool isQ_)
21 equaliser (p), paramNumber (paramNumberToUse),
22 isGain (isGain_), isFreq (isFreq_), isQ (isQ_)
28 notifyListenersOfDeletion();
48 return dbStringToDb (str);
53 void parameterChanged (
float,
bool )
override
55 equaliser.needToUpdateFilters[paramNumber] =
true;
60 bool isGain, isFreq, isQ;
64const char* EqualiserPlugin::xmlTypeName =
"4bandEq";
68 for (
int i = 4; --i >= 0;)
69 needToUpdateFilters[i] =
true;
71 addAutomatableParameter (loFreq =
new EQAutomatableParameter (*
this,
"Low-pass freq",
TRANS(
"Low-shelf freq"), *
this, { minFreq, maxFreq }, 0,
false,
true,
false));
72 addAutomatableParameter (loGain =
new EQAutomatableParameter (*
this,
"Low-pass gain",
TRANS(
"Low-shelf gain"), *
this, { minGain, maxGain }, 0,
true,
false,
false));
73 addAutomatableParameter (loQ =
new EQAutomatableParameter (*
this,
"Low-pass Q",
TRANS(
"Low-shelf Q"), *
this, { minQ, maxQ }, 0,
false,
false,
true));
75 addAutomatableParameter (midFreq1 =
new EQAutomatableParameter (*
this,
"Mid freq 1",
TRANS(
"Mid freq 1"), *
this, { minFreq, maxFreq }, 1,
false,
true,
false));
76 addAutomatableParameter (midGain1 =
new EQAutomatableParameter (*
this,
"Mid gain 1",
TRANS(
"Mid gain 1"), *
this, { minGain, maxGain }, 1,
true,
false,
false));
77 addAutomatableParameter (midQ1 =
new EQAutomatableParameter (*
this,
"Mid Q 1",
TRANS(
"Mid Q 1"), *
this, { minQ, maxQ }, 1,
false,
false,
true));
79 addAutomatableParameter (midFreq2 =
new EQAutomatableParameter (*
this,
"Mid freq 2",
TRANS(
"Mid freq 2"), *
this, { minFreq, maxFreq }, 2,
false,
true,
false));
80 addAutomatableParameter (midGain2 =
new EQAutomatableParameter (*
this,
"Mid gain 2",
TRANS(
"Mid gain 2"), *
this, { minGain, maxGain }, 2,
true,
false,
false));
81 addAutomatableParameter (midQ2 =
new EQAutomatableParameter (*
this,
"Mid Q 2",
TRANS(
"Mid Q 2"), *
this, { minQ, maxQ }, 2,
false,
false,
true));
83 addAutomatableParameter (hiFreq =
new EQAutomatableParameter (*
this,
"High-pass freq",
TRANS(
"High-shelf freq"), *
this, { minFreq, maxFreq }, 3,
false,
true,
false));
84 addAutomatableParameter (hiGain =
new EQAutomatableParameter (*
this,
"High-pass gain",
TRANS(
"High-shelf gain"), *
this, { minGain, maxGain }, 3,
true,
false,
false));
85 addAutomatableParameter (hiQ =
new EQAutomatableParameter (*
this,
"High-pass Q",
TRANS(
"High-shelf Q"), *
this, { minQ, maxQ }, 3,
false,
false,
true));
87 auto um = getUndoManager();
89 loFreqValue.referTo (state, IDs::loFreq, um, 80.0f);
90 loGainValue.referTo (state, IDs::loGain, um);
91 loQValue.referTo (state, IDs::loQ, um, 0.5f);
93 hiFreqValue.referTo (state, IDs::hiFreq, um, 17000.0f);
94 hiGainValue.referTo (state, IDs::hiGain, um);
95 hiQValue.referTo (state, IDs::hiQ, um, 0.5f);
97 midFreqValue1.referTo (state, IDs::midFreq1, um, 3000.0f);
98 midGainValue1.referTo (state, IDs::midGain1, um);
99 midQValue1.referTo (state, IDs::midQ1, um, 0.5f);
101 midFreqValue2.referTo (state, IDs::midFreq2, um, 5000.0f);
102 midGainValue2.referTo (state, IDs::midGain2, um);
103 midQValue2.referTo (state, IDs::midQ2, um, 0.5f);
105 phaseInvert.referTo (state, IDs::phaseInvert, um);
107 loFreq->attachToCurrentValue (loFreqValue);
108 loGain->attachToCurrentValue (loGainValue);
109 loQ->attachToCurrentValue (loQValue);
111 midFreq1->attachToCurrentValue (midFreqValue1);
112 midGain1->attachToCurrentValue (midGainValue1);
113 midQ1->attachToCurrentValue (midQValue1);
115 midFreq2->attachToCurrentValue (midFreqValue2);
116 midGain2->attachToCurrentValue (midGainValue2);
117 midQ2->attachToCurrentValue (midQValue2);
119 hiFreq->attachToCurrentValue (hiFreqValue);
120 hiGain->attachToCurrentValue (hiGainValue);
121 hiQ->attachToCurrentValue (hiQValue);
124EqualiserPlugin::~EqualiserPlugin()
126 notifyListenersOfDeletion();
128 loFreq->detachFromCurrentValue();
129 loGain->detachFromCurrentValue();
130 loQ->detachFromCurrentValue();
132 midFreq1->detachFromCurrentValue();
133 midGain1->detachFromCurrentValue();
134 midQ1->detachFromCurrentValue();
136 midFreq2->detachFromCurrentValue();
137 midGain2->detachFromCurrentValue();
138 midQ2->detachFromCurrentValue();
140 hiFreq->detachFromCurrentValue();
141 hiGain->detachFromCurrentValue();
142 hiQ->detachFromCurrentValue();
147 return getName() +
"$equaliserplugin";
150void EqualiserPlugin::resetToDefault()
168 curveNeedsUpdating =
true;
171void EqualiserPlugin::restorePluginStateFromValueTree (
const juce::ValueTree& v)
173 copyPropertiesToCachedValues (v, loFreqValue, loGainValue, loQValue, hiFreqValue, hiGainValue,
174 hiQValue, midFreqValue1, midGainValue1, midQValue1, midFreqValue2,
175 midGainValue2, midQValue2, phaseInvert);
177 for (
auto p : getAutomatableParameters())
178 p->updateFromAttachedValue();
183 curveNeedsUpdating =
true;
184 Plugin::valueTreePropertyChanged (parent, prop);
187static float convertEQLevelToGain (
double db)
189 return (
float)
pow (10.0, db / 20.0);
192void EqualiserPlugin::updateIIRFilters()
196 if (needToUpdateFilters[0])
198 needToUpdateFilters[0] =
false;
201 convertEQLevelToGain (loGain->getCurrentValue()));
203 for (
int i = EQ_CHANS; --i >= 0;)
204 low[i].setCoefficients (c);
207 if (needToUpdateFilters[1])
209 needToUpdateFilters[1] =
false;
212 convertEQLevelToGain (midGain1->getCurrentValue()));
214 for (
int i = EQ_CHANS; --i >= 0;)
215 mid1[i].setCoefficients (c);
218 if (needToUpdateFilters[2])
220 needToUpdateFilters[2] =
false;
223 convertEQLevelToGain (midGain2->getCurrentValue()));
225 for (
int i = EQ_CHANS; --i >= 0;)
226 mid2[i].setCoefficients (c);
229 if (needToUpdateFilters[3])
231 needToUpdateFilters[3] =
false;
234 convertEQLevelToGain (hiGain->getCurrentValue()));
236 for (
int i = EQ_CHANS; --i >= 0;)
237 high[i].setCoefficients (c);
243 for (
int i = EQ_CHANS; --i >= 0;)
251 if (lastSampleRate != sampleRate)
252 curveNeedsUpdating =
true;
254 lastSampleRate = (
float)sampleRate;
256 for (
int i = 4; --i >= 0;)
257 needToUpdateFilters[i] =
true;
270 SCOPED_REALTIME_CHECK
286 if (loGain->getCurrentValue() != 0) low[i] .processSamples (data, fc.
bufferNumSamples);
287 if (midGain1->getCurrentValue() != 0) mid1[i].processSamples (data, fc.
bufferNumSamples);
288 if (midGain2->getCurrentValue() != 0) mid2[i].processSamples (data, fc.
bufferNumSamples);
289 if (hiGain->getCurrentValue() != 0) high[i].processSamples (data, fc.
bufferNumSamples);
299 if (curveNeedsUpdating)
305 if (loGain->getCurrentValue() == 0 && midGain1->getCurrentValue() == 0
306 && midGain2->getCurrentValue() == 0 && hiGain->getCurrentValue() == 0)
309 const int sampSize = (1 << fftOrder);
311 float samps[sampSize * 2 + 8] = {};
321 for (
int i = 0; i < sampSize / 2;)
323 curve.addPoint (i / (
float)(sampSize / 2),
326 if (i < sampSize / 8)
328 else if (i < sampSize / 4)
334 curveNeedsUpdating =
false;
338 return curve.getY (f / (lastSampleRate / 2));
Type * getWritePointer(int channelNumber) noexcept
int getNumChannels() const noexcept
int getNumSamples() const noexcept
void applyGain(int channel, int startSample, int numSamples, Type gain) noexcept
static String toString(Type decibels, int decimalPlaces=2, Type minusInfinityDb=Type(defaultMinusInfinitydB), bool shouldIncludeSuffix=true, StringRef customMinusInfinityString={})
static IIRCoefficients makePeakFilter(double sampleRate, double centreFrequency, double Q, float gainFactor) noexcept
static IIRCoefficients makeHighShelf(double sampleRate, double cutOffFrequency, double Q, float gainFactor) noexcept
static IIRCoefficients makeLowShelf(double sampleRate, double cutOffFrequency, double Q, float gainFactor) noexcept
void processSamples(float *samples, int numSamples) noexcept
float getFloatValue() const noexcept
String retainCharacters(StringRef charactersToRetain) const
void performRealOnlyForwardTransform(float *inputOutputData, bool onlyCalculateNonNegativeFrequencies=false) const noexcept
void deinitialise() override
Called after play stops to release resources.
juce::String getName() const override
The name of the type, e.g.
void applyToBuffer(const PluginRenderContext &) override
Process the next block of data.
juce::String getTooltip() override
default returns the name, others can return special stuff if needed
float getDBGainAtFrequency(float f)
Finds the gain at a frequency - used to plot the EQ graph.
#define TRANS(stringLiteral)
Type jlimit(Type lowerLimit, Type upperLimit, Type valueToConstrain) noexcept
int roundToInt(const FloatType value) noexcept
Passed into Plugins when they are being initialised, to give them useful contextual information that ...
The context passed to plugin render methods to provide it with buffers to fill.
int bufferNumSamples
The number of samples to write into the audio buffer.
juce::AudioBuffer< float > * destBuffer
The target audio buffer which needs to be filled.
int bufferStartSample
The index of the start point in the audio buffer from which data must be written.