Audacity 3.2.0
Public Member Functions | Public Attributes | Private Member Functions | List of all members
EqualizationCurvesList Struct Reference

Maintains a list of preset curves for Equalization effects. More...

#include <EqualizationCurvesList.h>

Collaboration diagram for EqualizationCurvesList:
[legend]

Public Member Functions

 EqualizationCurvesList (EqualizationFilter &params)
 
void EnvelopeUpdated ()
 
void EnvelopeUpdated (const Envelope &env, bool lin)
 
void Select (int sel)
 
void ForceRecalc ()
 
void setCurve (int currentCurve)
 
void setCurve (const wxString &curveName)
 

Public Attributes

EQCurveArray mCurves
 
EqualizationFiltermParameters
 
bool mRecalcRequired { false }
 

Private Member Functions

void setCurve ()
 

Detailed Description

Maintains a list of preset curves for Equalization effects.

Definition at line 22 of file EqualizationCurvesList.h.

Constructor & Destructor Documentation

◆ EqualizationCurvesList()

EqualizationCurvesList::EqualizationCurvesList ( EqualizationFilter params)
inlineexplicit

Definition at line 23 of file EqualizationCurvesList.h.

25 {}
EffectDistortionSettings params
EqualizationFilter & mParameters

Member Function Documentation

◆ EnvelopeUpdated() [1/2]

void EqualizationCurvesList::EnvelopeUpdated ( )

Definition at line 31 of file EqualizationCurvesList.cpp.

References EnvelopeUpdated(), EqualizationParameters::IsLinear(), EqualizationFilter::mLinEnvelope, EqualizationFilter::mLogEnvelope, and mParameters.

Referenced by EnvelopeUpdated(), EqualizationBandSliders::EnvLinToLog(), EqualizationBandSliders::ErrMin(), EqualizationBandSliders::Flatten(), EqualizationBandSliders::Invert(), EqualizationUI::OnInterp(), EqualizationPanel::OnMouseEvent(), EqualizationBandSliders::OnSlider(), and EqualizationUI::UpdateDraw().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ EnvelopeUpdated() [2/2]

void EqualizationCurvesList::EnvelopeUpdated ( const Envelope env,
bool  lin 
)

Definition at line 39 of file EqualizationCurvesList.cpp.

40{
41 const auto &hiFreq = mParameters.mHiFreq;
42 const auto &drawMode = mParameters.mDrawMode;
43 auto &logEnvelope = mParameters.mLogEnvelope;
44
45 // Allocate and populate point arrays
46 size_t numPoints = env.GetNumberOfPoints();
47 Doubles when{ numPoints };
48 Doubles value{ numPoints };
49 env.GetPoints( when.get(), value.get(), numPoints );
50
51 // Clear the unnamed curve
52 int curve = mCurves.size() - 1;
53 mCurves[ curve ].points.clear();
54
55 if(lin)
56 {
57 // Copy and convert points
58 for (size_t point = 0; point < numPoints; point++)
59 {
60 double freq = when[ point ] * hiFreq;
61 double db = value[ point ];
62
63 // Add it to the curve
64 mCurves[ curve ].points.push_back( EQPoint( freq, db ) );
65 }
66 }
67 else
68 {
69 double loLog = log10( 20. );
70 double hiLog = log10( hiFreq );
71 double denom = hiLog - loLog;
72
73 // Copy and convert points
74 for (size_t point = 0; point < numPoints; point++)
75 {
76 double freq = pow( 10., ( ( when[ point ] * denom ) + loLog ));
77 double db = value[ point ];
78
79 // Add it to the curve
80 mCurves[ curve ].points.push_back( EQPoint( freq, db ) );
81 }
82 }
83
84 // Update unnamed curve (so it's there for next time)
85 //(done in a hurry, may not be the neatest -MJS)
86 if (!drawMode)
87 {
88 size_t numPoints = logEnvelope.GetNumberOfPoints();
89 Doubles when{ numPoints };
90 Doubles value{ numPoints };
91 logEnvelope.GetPoints(when.get(), value.get(), numPoints);
92 for (size_t i = 0, j = 0; j + 2 < numPoints; i++, j++)
93 {
94 if ((value[i] < value[i + 1] + .05) && (value[i] > value[i + 1] - .05) &&
95 (value[i + 1] < value[i + 2] + .05) && (value[i + 1] > value[i + 2] - .05))
96 { // within < 0.05 dB?
97 logEnvelope.Delete(j + 1);
98 numPoints--;
99 j--;
100 }
101 }
102 Select((int) mCurves.size() - 1);
103 }
104
105 // set 'unnamed' as the selected curve
106 Select( (int) mCurves.size() - 1 );
107}
One point in a curve.
size_t GetNumberOfPoints() const
Return number of points.
Definition: Envelope.cpp:723
void GetPoints(double *bufferWhen, double *bufferValue, int bufferLen) const
Returns the sets of when and value pairs.
Definition: Envelope.cpp:738

References Envelope::GetNumberOfPoints(), Envelope::GetPoints(), mCurves, EqualizationParameters::mDrawMode, EqualizationFilter::mHiFreq, EqualizationFilter::mLogEnvelope, mParameters, and Select().

Here is the call graph for this function:

◆ ForceRecalc()

void EqualizationCurvesList::ForceRecalc ( )
inline

Definition at line 31 of file EqualizationCurvesList.h.

Referenced by EqualizationBandSliders::Flatten(), EqualizationBandSliders::GraphicEQ(), EqualizationBandSliders::Invert(), EqualizationUI::OnLinFreq(), EqualizationPanel::OnMouseEvent(), EqualizationUI::OnSliderM(), EqualizationUI::PopulateOrExchange(), setCurve(), and EqualizationUI::UpdateDraw().

Here is the caller graph for this function:

◆ Select()

void EqualizationCurvesList::Select ( int  sel)

Definition at line 23 of file EqualizationCurvesList.cpp.

24{
25 mParameters.mCurveName = mCurves[ curve ].Name;
26}

References EqualizationParameters::mCurveName, mCurves, and mParameters.

Referenced by EnvelopeUpdated(), EqualizationBandSliders::ErrMin(), and setCurve().

Here is the caller graph for this function:

◆ setCurve() [1/3]

void EqualizationCurvesList::setCurve ( )
private

Definition at line 274 of file EqualizationCurvesList.cpp.

275{
276 setCurve((int) mCurves.size() - 1);
277}

References mCurves, and setCurve().

Referenced by setCurve().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ setCurve() [2/3]

void EqualizationCurvesList::setCurve ( const wxString &  curveName)

Definition at line 279 of file EqualizationCurvesList.cpp.

280{
281 unsigned i = 0;
282 for( i = 0; i < mCurves.size(); i++ )
283 if( curveName == mCurves[ i ].Name )
284 break;
285 if( i == mCurves.size())
286 {
287 using namespace BasicUI;
289 XO("Requested curve not found, using 'unnamed'"),
290 MessageBoxOptions {}.IconStyle(Icon::Error));
291 setCurve();
292 }
293 else
294 setCurve( i );
295}
XO("Cut/Copy/Paste")
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
MessageBoxOptions && IconStyle(Icon style) &&
Definition: BasicUI.h:104

References BasicUI::MessageBoxOptions::IconStyle(), mCurves, setCurve(), BasicUI::ShowMessageBox(), and XO().

Here is the call graph for this function:

◆ setCurve() [3/3]

void EqualizationCurvesList::setCurve ( int  currentCurve)

Definition at line 112 of file EqualizationCurvesList.cpp.

113{
114 constexpr auto loFreqI = EqualizationFilter::loFreqI;
115
116 const auto &lin = mParameters.mLin;
117 const auto &hiFreq = mParameters.mHiFreq;
118
119 // Set current choice
120 wxASSERT( currentCurve < (int) mCurves.size() );
121 Select(currentCurve);
122
123 int numPoints = (int) mCurves[currentCurve].points.size();
124
125 auto &env = mParameters.ChooseEnvelope();
126 env.Flatten(0.);
127 env.SetTrackLen(1.0);
128
129 // Handle special case of no points.
130 if (numPoints == 0) {
131 ForceRecalc();
132 return;
133 }
134
135 double when, value;
136
137 // Handle special case 1 point.
138 if (numPoints == 1) {
139 // only one point, so ensure it is in range then return.
140 when = mCurves[currentCurve].points[0].Freq;
141 if (lin) {
142 when = when / hiFreq;
143 }
144 else { // log scale
145 // We don't go below loFreqI (20 Hz) in log view.
146 double loLog = log10((double)loFreqI);
147 double hiLog = log10(hiFreq);
148 double denom = hiLog - loLog;
149 when =
150 (log10(std::max<double>(loFreqI, when))
151 - loLog) / denom;
152 }
153 value = mCurves[currentCurve].points[0].dB;
154 env.Insert(std::min(1.0, std::max(0.0, when)), value);
155 ForceRecalc();
156 return;
157 }
158
159 // We have at least two points, so ensure they are in frequency order.
160 std::sort(mCurves[currentCurve].points.begin(),
161 mCurves[currentCurve].points.end());
162
163 if (mCurves[currentCurve].points[0].Freq < 0) {
164 // Corrupt or invalid curve, so bail.
165 ForceRecalc();
166 return;
167 }
168
169 if(lin) { // linear Hz scale
170 for(int pointCount = 0; pointCount < numPoints; pointCount++) {
171 when = mCurves[currentCurve].points[pointCount].Freq / hiFreq;
172 value = mCurves[currentCurve].points[pointCount].dB;
173 if(when <= 1) {
174 env.Insert(when, value);
175 if (when == 1)
176 break;
177 }
178 else {
179 // There are more points at higher freqs,
180 // so interpolate next one then stop.
181 when = 1.0;
182 double nextDB = mCurves[currentCurve].points[pointCount].dB;
183 if (pointCount > 0) {
184 double nextF = mCurves[currentCurve].points[pointCount].Freq;
185 double lastF = mCurves[currentCurve].points[pointCount-1].Freq;
186 double lastDB = mCurves[currentCurve].points[pointCount-1].dB;
187 value = lastDB +
188 ((nextDB - lastDB) *
189 ((hiFreq - lastF) / (nextF - lastF)));
190 }
191 else
192 value = nextDB;
193 env.Insert(when, value);
194 break;
195 }
196 }
197 }
198 else { // log Hz scale
199 double loLog = log10((double) loFreqI);
200 double hiLog = log10(hiFreq);
201 double denom = hiLog - loLog;
202 int firstAbove20Hz;
203
204 // log scale EQ starts at 20 Hz (threshold of hearing).
205 // so find the first point (if any) above 20 Hz.
206 for (firstAbove20Hz = 0; firstAbove20Hz < numPoints; firstAbove20Hz++) {
207 if (mCurves[currentCurve].points[firstAbove20Hz].Freq > loFreqI)
208 break;
209 }
210
211 if (firstAbove20Hz == numPoints) {
212 // All points below 20 Hz, so just use final point.
213 when = 0.0;
214 value = mCurves[currentCurve].points[numPoints-1].dB;
215 env.Insert(when, value);
216 ForceRecalc();
217 return;
218 }
219
220 if (firstAbove20Hz > 0) {
221 // At least one point is before 20 Hz and there are more
222 // beyond 20 Hz, so interpolate the first
223 double prevF = mCurves[currentCurve].points[firstAbove20Hz-1].Freq;
224 prevF = log10(std::max(1.0, prevF)); // log zero is bad.
225 double prevDB = mCurves[currentCurve].points[firstAbove20Hz-1].dB;
226 double nextF = log10(mCurves[currentCurve].points[firstAbove20Hz].Freq);
227 double nextDB = mCurves[currentCurve].points[firstAbove20Hz].dB;
228 when = 0.0;
229 value = nextDB - ((nextDB - prevDB) * ((nextF - loLog) / (nextF - prevF)));
230 env.Insert(when, value);
231 }
232
233 // Now get the rest.
234 for(int pointCount = firstAbove20Hz; pointCount < numPoints; pointCount++)
235 {
236 double flog = log10(mCurves[currentCurve].points[pointCount].Freq);
237 wxASSERT(mCurves[currentCurve].points[pointCount].Freq >= loFreqI);
238
239 when = (flog - loLog)/denom;
240 value = mCurves[currentCurve].points[pointCount].dB;
241 if(when <= 1.0) {
242 env.Insert(when, value);
243 }
244 else {
245 // This looks weird when adjusting curve in Draw mode if
246 // there is a point off-screen.
247
248 /*
249 // we have a point beyond fs/2. Insert it so that env code can use it.
250 // but just this one, we have no use for the rest
251 env.SetTrackLen(when); // can't Insert if the envelope isn't long enough
252 env.Insert(when, value);
253 break;
254 */
255
256 // interpolate the final point instead
257 when = 1.0;
258 if (pointCount > 0) {
259 double lastDB = mCurves[currentCurve].points[pointCount-1].dB;
260 double logLastF =
261 log10(mCurves[currentCurve].points[pointCount-1].Freq);
262 value = lastDB +
263 ((value - lastDB) *
264 ((log10(hiFreq) - logLastF) / (flog - logLastF)));
265 }
266 env.Insert(when, value);
267 break;
268 }
269 }
270 }
271 ForceRecalc();
272}
int min(int a, int b)
void Flatten(double value)
Definition: Envelope.cpp:140
static constexpr int loFreqI
const Envelope & ChooseEnvelope() const

References EqualizationFilter::ChooseEnvelope(), Envelope::Flatten(), ForceRecalc(), EqualizationFilter::loFreqI, mCurves, EqualizationFilter::mHiFreq, min(), EqualizationParameters::mLin, mParameters, and Select().

Referenced by EqualizationBase::Init(), EqualizationUI::OnCurve(), EqualizationUI::OnManage(), EqualizationUI::UpdateCurves(), and EqualizationBase::VisitSettings().

Here is the call graph for this function:
Here is the caller graph for this function:

Member Data Documentation

◆ mCurves

EQCurveArray EqualizationCurvesList::mCurves

◆ mParameters

EqualizationFilter& EqualizationCurvesList::mParameters

◆ mRecalcRequired

bool EqualizationCurvesList::mRecalcRequired { false }

Definition at line 38 of file EqualizationCurvesList.h.

Referenced by EqualizationPanel::OnIdle().


The documentation for this struct was generated from the following files: