Audacity 3.2.0
Public Member Functions | Private Member Functions | Private Attributes | List of all members
EQCurveReader Class Reference

Deserializer of curves from XML files. More...

#include <EqualizationCurves.h>

Inheritance diagram for EQCurveReader:
[legend]
Collaboration diagram for EQCurveReader:
[legend]

Public Member Functions

 EQCurveReader (EQCurveArray &curves, const TranslatableString &name, int options)
 
bool HandleXMLTag (const std::string_view &tag, const AttributesList &attrs) override
 
XMLTagHandlerHandleXMLChild (const std::string_view &tag) override
 
void LoadCurves (const wxString &fileName={}, bool append=false)
 
- Public Member Functions inherited from XMLTagHandler
 XMLTagHandler ()
 
virtual ~XMLTagHandler ()
 
virtual bool HandleXMLTag (const std::string_view &tag, const AttributesList &attrs)=0
 
virtual void HandleXMLEndTag (const std::string_view &WXUNUSED(tag))
 
virtual void HandleXMLContent (const std::string_view &WXUNUSED(content))
 
virtual XMLTagHandlerHandleXMLChild (const std::string_view &tag)=0
 
void ReadXMLEndTag (const char *tag)
 
void ReadXMLContent (const char *s, int len)
 
XMLTagHandlerReadXMLChild (const char *tag)
 

Private Member Functions

bool GetDefaultFileName (wxFileName &fileName)
 
wxString GetPrefsPrefix ()
 
void UpdateDefaultCurves (bool updateAll=false)
 

Private Attributes

EQCurveArraymCurves
 
const TranslatableString mName
 
const int mOptions
 

Detailed Description

Deserializer of curves from XML files.

Definition at line 74 of file EqualizationCurves.h.

Constructor & Destructor Documentation

◆ EQCurveReader()

EQCurveReader::EQCurveReader ( EQCurveArray curves,
const TranslatableString name,
int  options 
)
inline

Definition at line 76 of file EqualizationCurves.h.

78 : mCurves{ curves }, mName{ name }, mOptions{ options } {}
const TranslatableString name
Definition: Distortion.cpp:76
const TranslatableString mName
EQCurveArray & mCurves

Member Function Documentation

◆ GetDefaultFileName()

bool EQCurveReader::GetDefaultFileName ( wxFileName &  fileName)
private

Definition at line 267 of file EqualizationCurves.cpp.

268{
269 // look in data dir first, in case the user has their own defaults (maybe downloaded ones)
270 fileName = wxFileName( FileNames::DataDir(), wxT("EQDefaultCurves.xml") );
271 if( !fileName.FileExists() )
272 { // Default file not found in the data dir. Fall back to Resources dir.
273 // See http://docs.wxwidgets.org/trunk/classwx_standard_paths.html#5514bf6288ee9f5a0acaf065762ad95d
274 fileName = wxFileName( FileNames::ResourcesDir(), wxT("EQDefaultCurves.xml") );
275 }
276 if( !fileName.FileExists() )
277 {
278 // LLL: Is there really a need for an error message at all???
279 //auto errorMessage = XO("EQCurves.xml and EQDefaultCurves.xml were not found on your system.\nPlease press 'help' to visit the download page.\n\nSave the curves at %s")
280 // .Format( FileNames::DataDir() );
281 //BasicUI::ShowErrorDialog( wxWidgetsWindowPlacement{ mUIParent },
282 // XO("EQCurves.xml and EQDefaultCurves.xml missing"),
283 // errorMessage, wxT("http://wiki.audacityteam.org/wiki/EQCurvesDownload"), false);
284
285 // Have another go at finding EQCurves.xml in the data dir, in case 'help' helped
286 fileName = wxFileName( FileNames::DataDir(), wxT("EQDefaultCurves.xml") );
287 }
288 return (fileName.FileExists());
289}
wxT("CloseDown"))
FILES_API FilePath ResourcesDir()
FILES_API FilePath DataDir()
Audacity user data directory.

References FileNames::DataDir(), FileNames::ResourcesDir(), and wxT().

Referenced by LoadCurves().

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

◆ GetPrefsPrefix()

wxString EQCurveReader::GetPrefsPrefix ( )
private

Definition at line 28 of file EqualizationCurves.cpp.

29{
30 wxString base = wxT("/Effects/Equalization/");
32 base = wxT("/Effects/GraphicEq/");
33 else if( mOptions == kEqOptionCurve )
34 base = wxT("/Effects/FilterCurve/");
35 return base;
36}
const int kEqOptionCurve
const int kEqOptionGraphic

References kEqOptionCurve, kEqOptionGraphic, mOptions, and wxT().

Referenced by LoadCurves(), and UpdateDefaultCurves().

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

◆ HandleXMLChild()

XMLTagHandler * EQCurveReader::HandleXMLChild ( const std::string_view &  tag)
overridevirtual

Implements XMLTagHandler.

Definition at line 432 of file EqualizationCurves.cpp.

433{
434 if (tag == "equalizationeffect")
435 {
436 return this;
437 }
438
439 if (tag == "curve")
440 {
441 return this;
442 }
443
444 if (tag == "point")
445 {
446 return this;
447 }
448
449 return NULL;
450}

◆ HandleXMLTag()

bool EQCurveReader::HandleXMLTag ( const std::string_view &  tag,
const AttributesList attrs 
)
overridevirtual

Implements XMLTagHandler.

Definition at line 337 of file EqualizationCurves.cpp.

339{
340 // May want to add a version strings...
341 if (tag == "equalizationeffect")
342 {
343 return true;
344 }
345
346 // Located a NEW curve
347 if (tag == "curve")
348 {
349 // Process the attributes
350 for (auto pair : attrs)
351 {
352 auto attr = pair.first;
353 auto value = pair.second;
354
355 // Create a NEW curve and name it
356 if( attr == "name" )
357 {
358 const wxString strValue = value.ToWString();
359 // check for a duplicate name and add (n) if there is one
360 int n = 0;
361 wxString strValueTemp = strValue;
362 bool exists;
363 do
364 {
365 exists = false;
366 for(size_t i = 0; i < mCurves.size(); i++)
367 {
368 if(n>0)
369 strValueTemp.Printf(wxT("%s (%d)"),strValue,n);
370 if(mCurves[i].Name == strValueTemp)
371 {
372 exists = true;
373 break;
374 }
375 }
376 n++;
377 }
378 while(exists == true);
379
380 mCurves.push_back( EQCurve( strValueTemp ) );
381 }
382 }
383
384 // Tell caller it was processed
385 return true;
386 }
387
388 // Located a NEW point
389 if(tag == "point")
390 {
391 // Set defaults in case attributes are missing
392 double f = 0.0;
393 double d = 0.0;
394
395 // Process the attributes
396 double dblValue;
397 for (auto pair : attrs)
398 {
399 auto attr = pair.first;
400 auto value = pair.second;
401
402 // Get the frequency
403 if( attr == "f" )
404 {
405 if (!value.TryGet(dblValue))
406 return false;
407 f = dblValue;
408 }
409 // Get the dB
410 else if( attr == "d" )
411 {
412 if (!value.TryGet(dblValue))
413 return false;
414 d = dblValue;
415 }
416 }
417
418 // Create a NEW point
419 mCurves[ mCurves.size() - 1 ].points.push_back( EQPoint( f, d ) );
420
421 // Tell caller it was processed
422 return true;
423 }
424
425 // Tell caller we didn't understand the tag
426 return false;
427}
One curve in a list.
One point in a curve.

References mCurves, and wxT().

Here is the call graph for this function:

◆ LoadCurves()

void EQCurveReader::LoadCurves ( const wxString &  fileName = {},
bool  append = false 
)

Definition at line 54 of file EqualizationCurves.cpp.

55{
56// We've disabled the XML management of curves.
57// Just going via .cfg files now.
58#ifndef LEGACY_EQ
59 (void)fileName;
60 (void)append;
61 mCurves.clear();
62 mCurves.push_back( wxT("unnamed") ); // we still need a default curve to use
63#else
64 // Construct normal curve filename
65 //
66 // LLL: Wouldn't you know that as of WX 2.6.2, there is a conflict
67 // between wxStandardPaths and wxConfig under Linux. The latter
68 // creates a normal file as "$HOME/.audacity", while the former
69 // expects the ".audacity" portion to be a directory.
70 // MJS: I don't know what the above means, or if I have broken it.
71 wxFileName fn;
72
73 if(fileName.empty()) {
74 // Check if presets are up to date.
75 wxString eqCurvesCurrentVersion = wxString::Format(wxT("%d.%d"), EQCURVES_VERSION, EQCURVES_REVISION);
76 wxString eqCurvesInstalledVersion;
77 gPrefs->Read(GetPrefsPrefix() + "PresetVersion", &eqCurvesInstalledVersion, wxT(""));
78
79 bool needUpdate = (eqCurvesCurrentVersion != eqCurvesInstalledVersion);
80
81 // UpdateDefaultCurves allows us to import NEW factory presets only,
82 // or update all factory preset curves.
83 if (needUpdate)
85 fn = wxFileName( FileNames::DataDir(), wxT("EQCurves.xml") );
86 }
87 else
88 fn = fileName; // user is loading a specific set of curves
89
90 // If requested file doesn't exist...
91 if( !fn.FileExists() && !GetDefaultFileName(fn) ) {
92 mCurves.clear();
93 /* i18n-hint: name of the 'unnamed' custom curve */
94 mCurves.push_back( _("unnamed") ); // we still need a default curve to use
95 return;
96 }
97
98 EQCurve tempCustom(wxT("temp"));
99 if( append == false ) // Start from scratch
100 mCurves.clear();
101 else // appending so copy and remove 'unnamed', to replace later
102 {
103 tempCustom.points = mCurves.back().points;
104 mCurves.pop_back();
105 }
106
107 // Load the curves
108 XMLFileReader reader;
109 const wxString fullPath{ fn.GetFullPath() };
110 if( !reader.Parse( this, fullPath ) )
111 {
112 /* i18n-hint: EQ stands for 'Equalization'.*/
113 auto msg = XO("Error Loading EQ Curves from file:\n%s\nError message says:\n%s")
114 .Format( fullPath, reader.GetErrorStr() );
115 // Inform user of load failure
116 EQUtils::DoMessageBox(mName, msg, XO("Error Loading EQ Curves"));
117 mCurves.push_back( _("unnamed") ); // we always need a default curve to use
118 return;
119 }
120
121 // Move "unnamed" to end, if it exists in current language.
122 int numCurves = mCurves.size();
123 int curve;
124 EQCurve tempUnnamed(wxT("tempUnnamed"));
125 for( curve = 0; curve < numCurves-1; curve++ )
126 {
127 if( mCurves[curve].Name == _("unnamed") )
128 {
129 tempUnnamed.points = mCurves[curve].points;
130 mCurves.erase(mCurves.begin() + curve);
131 mCurves.push_back( _("unnamed") ); // add 'unnamed' back at the end
132 mCurves.back().points = tempUnnamed.points;
133 }
134 }
135
136 if( mCurves.back().Name != _("unnamed") )
137 mCurves.push_back( _("unnamed") ); // we always need a default curve to use
138 if( append == true )
139 {
140 mCurves.back().points = tempCustom.points;
141 }
142#endif
143 return;
144}
#define EQCURVES_REVISION
#define UPDATE_ALL
#define EQCURVES_VERSION
XO("Cut/Copy/Paste")
#define _(s)
Definition: Internat.h:73
audacity::BasicSettings * gPrefs
Definition: Prefs.cpp:68
static const auto fn
wxString GetPrefsPrefix()
bool GetDefaultFileName(wxFileName &fileName)
void UpdateDefaultCurves(bool updateAll=false)
Reads a file and passes the results through an XMLTagHandler.
Definition: XMLFileReader.h:19
const TranslatableString & GetErrorStr() const
bool Parse(XMLTagHandler *baseHandler, const FilePath &fname)
virtual bool Read(const wxString &key, bool *value) const =0
int DoMessageBox(const TranslatableString &name, const TranslatableString &msg, const TranslatableString &titleStr, long style=wxOK|wxCENTRE)

References _, FileNames::DataDir(), EQUtils::DoMessageBox(), EQCURVES_REVISION, EQCURVES_VERSION, fn, GetDefaultFileName(), XMLFileReader::GetErrorStr(), GetPrefsPrefix(), gPrefs, mCurves, mName, XMLFileReader::Parse(), EQCurve::points, audacity::BasicSettings::Read(), UPDATE_ALL, UpdateDefaultCurves(), wxT(), and XO().

Here is the call graph for this function:

◆ UpdateDefaultCurves()

void EQCurveReader::UpdateDefaultCurves ( bool  updateAll = false)
private

Definition at line 149 of file EqualizationCurves.cpp.

150{
151 if (mCurves.size() == 0)
152 return;
153
154 wxString unnamed = wxT("unnamed");
155
156 // Save the "unnamed" curve and remove it so we can add it back as the final curve.
157 EQCurve userUnnamed(wxT("temp"));
158 userUnnamed = mCurves.back();
159 mCurves.pop_back();
160
161 EQCurveArray userCurves = mCurves;
162 mCurves.clear();
163 // We only wamt to look for the shipped EQDefaultCurves.xml
164 wxFileName fn = wxFileName(FileNames::ResourcesDir(), wxT("EQDefaultCurves.xml"));
165 wxLogDebug(wxT("Attempting to load EQDefaultCurves.xml from %s"),fn.GetFullPath());
166 XMLFileReader reader;
167
168 if(!reader.Parse(this, fn.GetFullPath())) {
169 wxLogError(wxT("EQDefaultCurves.xml could not be read."));
170 return;
171 }
172 else {
173 wxLogDebug(wxT("Loading EQDefaultCurves.xml successful."));
174 }
175
176 EQCurveArray defaultCurves = mCurves;
177 mCurves.clear(); // clear now so that we can sort then add back.
178
179 // Remove "unnamed" if it exists.
180 if (defaultCurves.back().Name == unnamed) {
181 defaultCurves.pop_back();
182 }
183 else {
184 wxLogError(wxT("Error in EQDefaultCurves.xml"));
185 }
186
187 int numUserCurves = userCurves.size();
188 int numDefaultCurves = defaultCurves.size();
189 EQCurve tempCurve(wxT("test"));
190
191 if (updateAll) {
192 // Update all factory preset curves.
193 // Sort and add factory defaults first;
194 mCurves = defaultCurves;
195 std::sort(mCurves.begin(), mCurves.end());
196 // then add remaining user curves:
197 for (int curveCount = 0; curveCount < numUserCurves; curveCount++) {
198 bool isCustom = true;
199 tempCurve = userCurves[curveCount];
200 // is the name in the default set?
201 for (int defCurveCount = 0; defCurveCount < numDefaultCurves; defCurveCount++) {
202 if (tempCurve.Name == mCurves[defCurveCount].Name) {
203 isCustom = false;
204 break;
205 }
206 }
207 // if tempCurve is not in the default set, add it to mCurves.
208 if (isCustom) {
209 mCurves.push_back(tempCurve);
210 }
211 }
212 }
213 else {
214 // Import NEW factory defaults but retain all user modified curves.
215 for (int defCurveCount = 0; defCurveCount < numDefaultCurves; defCurveCount++) {
216 bool isUserCurve = false;
217 // Add if the curve is in the user's set (preserve user's copy)
218 for (int userCurveCount = 0; userCurveCount < numUserCurves; userCurveCount++) {
219 if (userCurves[userCurveCount].Name == defaultCurves[defCurveCount].Name) {
220 isUserCurve = true;
221 mCurves.push_back(userCurves[userCurveCount]);
222 break;
223 }
224 }
225 if (!isUserCurve) {
226 mCurves.push_back(defaultCurves[defCurveCount]);
227 }
228 }
229 std::sort(mCurves.begin(), mCurves.end());
230 // now add the rest of the user's curves.
231 for (int userCurveCount = 0; userCurveCount < numUserCurves; userCurveCount++) {
232 bool isDefaultCurve = false;
233 tempCurve = userCurves[userCurveCount];
234 for (int defCurveCount = 0; defCurveCount < numDefaultCurves; defCurveCount++) {
235 if (tempCurve.Name == defaultCurves[defCurveCount].Name) {
236 isDefaultCurve = true;
237 break;
238 }
239 }
240 if (!isDefaultCurve) {
241 mCurves.push_back(tempCurve);
242 }
243 }
244 }
245 defaultCurves.clear();
246 userCurves.clear();
247
248 // Add back old "unnamed"
249 if(userUnnamed.Name == unnamed) {
250 mCurves.push_back( userUnnamed ); // we always need a default curve to use
251 }
252
253 EQCurveWriter{ mCurves }.SaveCurves();
254
255 // Write current EqCurve version number
256 // TODO: Probably better if we used pluginregistry.cfg
257 wxString eqCurvesCurrentVersion = wxString::Format(wxT("%d.%d"), EQCURVES_VERSION, EQCURVES_REVISION);
258 gPrefs->Write(GetPrefsPrefix()+"PresetVersion", eqCurvesCurrentVersion);
259 gPrefs->Flush();
260
261 return;
262}
std::vector< EQCurve > EQCurveArray
Serializer of curves into XML files.
virtual bool Flush() noexcept=0
virtual bool Write(const wxString &key, bool value)=0

References EQCURVES_REVISION, EQCURVES_VERSION, audacity::BasicSettings::Flush(), fn, GetPrefsPrefix(), gPrefs, mCurves, EQCurve::Name, XMLFileReader::Parse(), FileNames::ResourcesDir(), audacity::BasicSettings::Write(), and wxT().

Referenced by LoadCurves().

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

Member Data Documentation

◆ mCurves

EQCurveArray& EQCurveReader::mCurves
private

Definition at line 92 of file EqualizationCurves.h.

Referenced by HandleXMLTag(), LoadCurves(), and UpdateDefaultCurves().

◆ mName

const TranslatableString EQCurveReader::mName
private

Definition at line 93 of file EqualizationCurves.h.

Referenced by LoadCurves().

◆ mOptions

const int EQCurveReader::mOptions
private

Definition at line 94 of file EqualizationCurves.h.

Referenced by GetPrefsPrefix().


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