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 66 of file EqualizationCurves.h.

Constructor & Destructor Documentation

◆ EQCurveReader()

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

Definition at line 68 of file EqualizationCurves.h.

70 : mCurves{ curves }, mName{ name }, mOptions{ options } {}
wxString name
Definition: TagsEditor.cpp:166
const TranslatableString mName
EQCurveArray & mCurves

Member Function Documentation

◆ GetDefaultFileName()

bool EQCurveReader::GetDefaultFileName ( wxFileName &  fileName)
private

Definition at line 254 of file EqualizationCurves.cpp.

255{
256 // look in data dir first, in case the user has their own defaults (maybe downloaded ones)
257 fileName = wxFileName( FileNames::DataDir(), wxT("EQDefaultCurves.xml") );
258 if( !fileName.FileExists() )
259 { // Default file not found in the data dir. Fall back to Resources dir.
260 // See http://docs.wxwidgets.org/trunk/classwx_standard_paths.html#5514bf6288ee9f5a0acaf065762ad95d
261 fileName = wxFileName( FileNames::ResourcesDir(), wxT("EQDefaultCurves.xml") );
262 }
263 if( !fileName.FileExists() )
264 {
265 // LLL: Is there really a need for an error message at all???
266 //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")
267 // .Format( FileNames::DataDir() );
268 //BasicUI::ShowErrorDialog( wxWidgetsWindowPlacement{ mUIParent },
269 // XO("EQCurves.xml and EQDefaultCurves.xml missing"),
270 // errorMessage, wxT("http://wiki.audacityteam.org/wiki/EQCurvesDownload"), false);
271
272 // Have another go at finding EQCurves.xml in the data dir, in case 'help' helped
273 fileName = wxFileName( FileNames::DataDir(), wxT("EQDefaultCurves.xml") );
274 }
275 return (fileName.FileExists());
276}
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 27 of file EqualizationCurves.cpp.

28{
29 wxString base = wxT("/Effects/Equalization/");
31 base = wxT("/Effects/GraphicEq/");
32 else if( mOptions == kEqOptionCurve )
33 base = wxT("/Effects/FilterCurve/");
34 return base;
35}
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 419 of file EqualizationCurves.cpp.

420{
421 if (tag == "equalizationeffect")
422 {
423 return this;
424 }
425
426 if (tag == "curve")
427 {
428 return this;
429 }
430
431 if (tag == "point")
432 {
433 return this;
434 }
435
436 return NULL;
437}

◆ HandleXMLTag()

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

Implements XMLTagHandler.

Definition at line 324 of file EqualizationCurves.cpp.

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

41{
42// We've disabled the XML management of curves.
43// Just going via .cfg files now.
44#ifndef LEGACY_EQ
45 (void)fileName;
46 (void)append;
47 mCurves.clear();
48 mCurves.push_back( wxT("unnamed") ); // we still need a default curve to use
49#else
50 // Construct normal curve filename
51 //
52 // LLL: Wouldn't you know that as of WX 2.6.2, there is a conflict
53 // between wxStandardPaths and wxConfig under Linux. The latter
54 // creates a normal file as "$HOME/.audacity", while the former
55 // expects the ".audacity" portion to be a directory.
56 // MJS: I don't know what the above means, or if I have broken it.
57 wxFileName fn;
58
59 if(fileName.empty()) {
60 // Check if presets are up to date.
61 wxString eqCurvesCurrentVersion = wxString::Format(wxT("%d.%d"), EQCURVES_VERSION, EQCURVES_REVISION);
62 wxString eqCurvesInstalledVersion;
63 gPrefs->Read(GetPrefsPrefix() + "PresetVersion", &eqCurvesInstalledVersion, wxT(""));
64
65 bool needUpdate = (eqCurvesCurrentVersion != eqCurvesInstalledVersion);
66
67 // UpdateDefaultCurves allows us to import NEW factory presets only,
68 // or update all factory preset curves.
69 if (needUpdate)
71 fn = wxFileName( FileNames::DataDir(), wxT("EQCurves.xml") );
72 }
73 else
74 fn = fileName; // user is loading a specific set of curves
75
76 // If requested file doesn't exist...
77 if( !fn.FileExists() && !GetDefaultFileName(fn) ) {
78 mCurves.clear();
79 /* i18n-hint: name of the 'unnamed' custom curve */
80 mCurves.push_back( _("unnamed") ); // we still need a default curve to use
81 return;
82 }
83
84 EQCurve tempCustom(wxT("temp"));
85 if( append == false ) // Start from scratch
86 mCurves.clear();
87 else // appending so copy and remove 'unnamed', to replace later
88 {
89 tempCustom.points = mCurves.back().points;
90 mCurves.pop_back();
91 }
92
93 // Load the curves
94 XMLFileReader reader;
95 const wxString fullPath{ fn.GetFullPath() };
96 if( !reader.Parse( this, fullPath ) )
97 {
98 /* i18n-hint: EQ stands for 'Equalization'.*/
99 auto msg = XO("Error Loading EQ Curves from file:\n%s\nError message says:\n%s")
100 .Format( fullPath, reader.GetErrorStr() );
101 // Inform user of load failure
102 using namespace BasicUI;
103 ShowMessageBox(msg, MessageBoxOptions{}.IconStyle(Icon::Error));
104 mCurves.push_back( _("unnamed") ); // we always need a default curve to use
105 return;
106 }
107
108 // Move "unnamed" to end, if it exists in current language.
109 int numCurves = mCurves.size();
110 int curve;
111 EQCurve tempUnnamed(wxT("tempUnnamed"));
112 for( curve = 0; curve < numCurves-1; curve++ )
113 {
114 if( mCurves[curve].Name == _("unnamed") )
115 {
116 tempUnnamed.points = mCurves[curve].points;
117 mCurves.erase(mCurves.begin() + curve);
118 mCurves.push_back( _("unnamed") ); // add 'unnamed' back at the end
119 mCurves.back().points = tempUnnamed.points;
120 }
121 }
122
123 if( mCurves.back().Name != _("unnamed") )
124 mCurves.push_back( _("unnamed") ); // we always need a default curve to use
125 if( append == true )
126 {
127 mCurves.back().points = tempCustom.points;
128 }
129#endif
130 return;
131}
#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
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
void append(std::basic_string< Elem > &dest, First &&first, Others &&...others)
MessageBoxOptions && IconStyle(Icon style) &&
Definition: BasicUI.h:104

References _, audacity::cloud::audiocom::anonymous_namespace{OAuthService.cpp}::append(), FileNames::DataDir(), EQCURVES_REVISION, EQCURVES_VERSION, fn, GetDefaultFileName(), XMLFileReader::GetErrorStr(), GetPrefsPrefix(), gPrefs, BasicUI::MessageBoxOptions::IconStyle(), mCurves, XMLFileReader::Parse(), EQCurve::points, audacity::BasicSettings::Read(), BasicUI::ShowMessageBox(), 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 136 of file EqualizationCurves.cpp.

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

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

◆ mName

const TranslatableString EQCurveReader::mName
private

Definition at line 85 of file EqualizationCurves.h.

◆ mOptions

const int EQCurveReader::mOptions
private

Definition at line 86 of file EqualizationCurves.h.

Referenced by GetPrefsPrefix().


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