mirror of
https://github.com/cookiengineer/audacity
synced 2025-10-26 23:33:49 +01:00
SpectrumPrefs takes SpectrogramSettings object as parameter, and...
... writes global preferences explicitly, and only when it is the default settings object. Also impose validation of settings when constructing from preferences.
This commit is contained in:
@@ -15,6 +15,10 @@ Paul Licameli
|
|||||||
|
|
||||||
#include "../Audacity.h"
|
#include "../Audacity.h"
|
||||||
#include "SpectrogramSettings.h"
|
#include "SpectrogramSettings.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <wx/msgdlg.h>
|
||||||
|
|
||||||
#include "../FFT.h"
|
#include "../FFT.h"
|
||||||
#include "../Prefs.h"
|
#include "../Prefs.h"
|
||||||
#include "../RealFFTf.h"
|
#include "../RealFFTf.h"
|
||||||
@@ -26,7 +30,7 @@ SpectrogramSettings::SpectrogramSettings()
|
|||||||
: hFFT(0)
|
: hFFT(0)
|
||||||
, window(0)
|
, window(0)
|
||||||
{
|
{
|
||||||
UpdatePrefs();
|
LoadPrefs();
|
||||||
}
|
}
|
||||||
|
|
||||||
SpectrogramSettings::SpectrogramSettings(const SpectrogramSettings &other)
|
SpectrogramSettings::SpectrogramSettings(const SpectrogramSettings &other)
|
||||||
@@ -98,49 +102,82 @@ SpectrogramSettings& SpectrogramSettings::defaults()
|
|||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpectrogramSettings::UpdatePrefs()
|
bool SpectrogramSettings::Validate(bool quiet)
|
||||||
{
|
{
|
||||||
bool destroy = false;
|
if (!quiet &&
|
||||||
|
maxFreq < 100) {
|
||||||
|
wxMessageBox(_("Maximum frequency must be 100 Hz or above"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
maxFreq = std::max(100, maxFreq);
|
||||||
|
|
||||||
|
if (!quiet &&
|
||||||
|
minFreq < 0) {
|
||||||
|
wxMessageBox(_("Minimum frequency must be at least 0 Hz"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
minFreq = std::max(0, minFreq);
|
||||||
|
|
||||||
|
if (!quiet &&
|
||||||
|
maxFreq <= minFreq) {
|
||||||
|
wxMessageBox(_("Minimum frequency must be less than maximum frequency"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
maxFreq = std::max(1 + minFreq, maxFreq);
|
||||||
|
|
||||||
|
if (!quiet &&
|
||||||
|
range <= 0) {
|
||||||
|
wxMessageBox(_("The range must be at least 1 dB"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
range = std::max(1, range);
|
||||||
|
|
||||||
|
if (!quiet &&
|
||||||
|
frequencyGain < 0) {
|
||||||
|
wxMessageBox(_("The frequency gain cannot be negative"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if (!quiet &&
|
||||||
|
frequencyGain > 60) {
|
||||||
|
wxMessageBox(_("The frequency gain must be no more than 60 dB/dec"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
frequencyGain =
|
||||||
|
std::max(0, std::min(60, frequencyGain));
|
||||||
|
|
||||||
|
// The rest are controlled by drop-down menus so they can't go wrong
|
||||||
|
// in the Preferences dialog, but we also come here after reading fom saved
|
||||||
|
// preference files, which could be or from future versions. Validate quietly.
|
||||||
|
windowType =
|
||||||
|
std::max(0, std::min(NumWindowFuncs() - 1, windowType));
|
||||||
|
ConvertToEnumeratedWindowSizes();
|
||||||
|
ConvertToActualWindowSizes();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpectrogramSettings::LoadPrefs()
|
||||||
|
{
|
||||||
|
minFreq = gPrefs->Read(wxT("/Spectrum/MinFreq"), 0L);
|
||||||
|
|
||||||
minFreq = gPrefs->Read(wxT("/Spectrum/MinFreq"), -1L);
|
|
||||||
maxFreq = gPrefs->Read(wxT("/Spectrum/MaxFreq"), 8000L);
|
maxFreq = gPrefs->Read(wxT("/Spectrum/MaxFreq"), 8000L);
|
||||||
|
|
||||||
// These preferences are not written anywhere in the program as of now,
|
|
||||||
// but I keep this legacy here. Who knows, someone might edit prefs files
|
|
||||||
// directly. PRL
|
|
||||||
logMaxFreq = gPrefs->Read(wxT("/SpectrumLog/MaxFreq"), -1);
|
|
||||||
if (logMaxFreq < 0)
|
|
||||||
logMaxFreq = maxFreq;
|
|
||||||
logMinFreq = gPrefs->Read(wxT("/SpectrumLog/MinFreq"), -1);
|
|
||||||
if (logMinFreq < 0)
|
|
||||||
logMinFreq = minFreq;
|
|
||||||
if (logMinFreq < 1)
|
|
||||||
logMinFreq = 1;
|
|
||||||
|
|
||||||
range = gPrefs->Read(wxT("/Spectrum/Range"), 80L);
|
range = gPrefs->Read(wxT("/Spectrum/Range"), 80L);
|
||||||
gain = gPrefs->Read(wxT("/Spectrum/Gain"), 20L);
|
gain = gPrefs->Read(wxT("/Spectrum/Gain"), 20L);
|
||||||
frequencyGain = gPrefs->Read(wxT("/Spectrum/FrequencyGain"), 0L);
|
frequencyGain = gPrefs->Read(wxT("/Spectrum/FrequencyGain"), 0L);
|
||||||
|
|
||||||
const int newWindowSize = gPrefs->Read(wxT("/Spectrum/FFTSize"), 256);
|
windowSize = gPrefs->Read(wxT("/Spectrum/FFTSize"), 256);
|
||||||
if (newWindowSize != windowSize) {
|
|
||||||
destroy = true;
|
|
||||||
windowSize = newWindowSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef EXPERIMENTAL_ZERO_PADDED_SPECTROGRAMS
|
#ifdef EXPERIMENTAL_ZERO_PADDED_SPECTROGRAMS
|
||||||
const int newZeroPaddingFactor = gPrefs->Read(wxT("/Spectrum/ZeroPaddingFactor"), 1);
|
zeroPaddingFactor = gPrefs->Read(wxT("/Spectrum/ZeroPaddingFactor"), 1);
|
||||||
if (newZeroPaddingFactor != zeroPaddingFactor) {
|
|
||||||
destroy = true;
|
|
||||||
zeroPaddingFactor = newZeroPaddingFactor;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int newWindowType;
|
gPrefs->Read(wxT("/Spectrum/WindowType"), &windowType, eWinFuncHanning);
|
||||||
gPrefs->Read(wxT("/Spectrum/WindowType"), &newWindowType, 3);
|
|
||||||
if (newWindowType != windowType) {
|
|
||||||
destroy = true;
|
|
||||||
windowType = newWindowType;
|
|
||||||
}
|
|
||||||
|
|
||||||
isGrayscale = (gPrefs->Read(wxT("/Spectrum/Grayscale"), 0L) != 0);
|
isGrayscale = (gPrefs->Read(wxT("/Spectrum/Grayscale"), 0L) != 0);
|
||||||
|
|
||||||
@@ -155,7 +192,63 @@ void SpectrogramSettings::UpdatePrefs()
|
|||||||
findNotesQuantize = (gPrefs->Read(wxT("/Spectrum/FindNotesQuantize"), 0L) != 0);
|
findNotesQuantize = (gPrefs->Read(wxT("/Spectrum/FindNotesQuantize"), 0L) != 0);
|
||||||
#endif //EXPERIMENTAL_FIND_NOTES
|
#endif //EXPERIMENTAL_FIND_NOTES
|
||||||
|
|
||||||
if (destroy)
|
// Enforce legal values
|
||||||
|
Validate(true);
|
||||||
|
|
||||||
|
// These preferences are not written anywhere in the program as of now,
|
||||||
|
// but I keep this legacy here. Who knows, someone might edit prefs files
|
||||||
|
// directly. PRL
|
||||||
|
logMinFreq = gPrefs->Read(wxT("/SpectrumLog/MinFreq"), -1);
|
||||||
|
if (logMinFreq < 0)
|
||||||
|
logMinFreq = minFreq;
|
||||||
|
if (logMinFreq < 1)
|
||||||
|
logMinFreq = 1;
|
||||||
|
logMaxFreq = gPrefs->Read(wxT("/SpectrumLog/MaxFreq"), -1);
|
||||||
|
if (logMaxFreq < 0)
|
||||||
|
logMaxFreq = maxFreq;
|
||||||
|
logMaxFreq =
|
||||||
|
std::max(logMinFreq + 1, logMaxFreq);
|
||||||
|
|
||||||
|
InvalidateCaches();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpectrogramSettings::SavePrefs()
|
||||||
|
{
|
||||||
|
gPrefs->Write(wxT("/Spectrum/MinFreq"), minFreq);
|
||||||
|
gPrefs->Write(wxT("/Spectrum/MaxFreq"), maxFreq);
|
||||||
|
|
||||||
|
// Nothing wrote these. They only varied from the linear scale bounds in-session. -- PRL
|
||||||
|
// gPrefs->Write(wxT("/SpectrumLog/MaxFreq"), logMinFreq);
|
||||||
|
// gPrefs->Write(wxT("/SpectrumLog/MinFreq"), logMaxFreq);
|
||||||
|
|
||||||
|
gPrefs->Write(wxT("/Spectrum/Range"), range);
|
||||||
|
gPrefs->Write(wxT("/Spectrum/Gain"), gain);
|
||||||
|
gPrefs->Write(wxT("/Spectrum/FrequencyGain"), frequencyGain);
|
||||||
|
|
||||||
|
gPrefs->Write(wxT("/Spectrum/FFTSize"), windowSize);
|
||||||
|
|
||||||
|
#ifdef EXPERIMENTAL_ZERO_PADDED_SPECTROGRAMS
|
||||||
|
gPrefs->Write(wxT("/Spectrum/ZeroPaddingFactor"), zeroPaddingFactor);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
gPrefs->Write(wxT("/Spectrum/WindowType"), windowType);
|
||||||
|
|
||||||
|
gPrefs->Write(wxT("/Spectrum/Grayscale"), isGrayscale);
|
||||||
|
|
||||||
|
#ifdef EXPERIMENTAL_FFT_Y_GRID
|
||||||
|
gPrefs->Write(wxT("/Spectrum/FFTYGrid"), fftYGrid);
|
||||||
|
#endif //EXPERIMENTAL_FFT_Y_GRID
|
||||||
|
|
||||||
|
#ifdef EXPERIMENTAL_FIND_NOTES
|
||||||
|
gPrefs->Write(wxT("/Spectrum/FFTFindNotes"), fftFindNotes);
|
||||||
|
gPrefs->Write(wxT("/Spectrum/FindNotesMinA"), findNotesMinA);
|
||||||
|
gPrefs->Write(wxT("/Spectrum/FindNotesN"), numberOfMaxima);
|
||||||
|
gPrefs->Write(wxT("/Spectrum/FindNotesQuantize"), findNotesQuantize);
|
||||||
|
#endif //EXPERIMENTAL_FIND_NOTES
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpectrogramSettings::InvalidateCaches()
|
||||||
|
{
|
||||||
DestroyWindows();
|
DestroyWindows();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -257,6 +350,38 @@ void SpectrogramSettings::CacheWindows() const
|
|||||||
#endif // EXPERIMENTAL_USE_REALFFTF
|
#endif // EXPERIMENTAL_USE_REALFFTF
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SpectrogramSettings::ConvertToEnumeratedWindowSizes()
|
||||||
|
{
|
||||||
|
unsigned size;
|
||||||
|
int logarithm;
|
||||||
|
|
||||||
|
logarithm = -LogMinWindowSize;
|
||||||
|
size = unsigned(windowSize);
|
||||||
|
while (size > 1)
|
||||||
|
size >>= 1, ++logarithm;
|
||||||
|
windowSize = std::max(0, std::min(NumWindowSizes - 1, logarithm));
|
||||||
|
|
||||||
|
#ifdef EXPERIMENTAL_ZERO_PADDED_SPECTROGRAMS
|
||||||
|
// Choices for zero padding begin at 1
|
||||||
|
logarithm = 0;
|
||||||
|
size = unsigned(zeroPaddingFactor);
|
||||||
|
while (zeroPaddingFactor > 1)
|
||||||
|
zeroPaddingFactor >>= 1, ++logarithm;
|
||||||
|
zeroPaddingFactor = std::max(0,
|
||||||
|
std::min(LogMaxWindowSize - (windowSize + LogMinWindowSize),
|
||||||
|
logarithm
|
||||||
|
));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpectrogramSettings::ConvertToActualWindowSizes()
|
||||||
|
{
|
||||||
|
windowSize = 1 << (windowSize + LogMinWindowSize);
|
||||||
|
#ifdef EXPERIMENTAL_ZERO_PADDED_SPECTROGRAMS
|
||||||
|
zeroPaddingFactor = 1 << zeroPaddingFactor;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
int SpectrogramSettings::GetMinFreq(double rate) const
|
int SpectrogramSettings::GetMinFreq(double rate) const
|
||||||
{
|
{
|
||||||
const int top = lrint(rate / 2.);
|
const int top = lrint(rate / 2.);
|
||||||
|
|||||||
@@ -14,19 +14,39 @@ Paul Licameli
|
|||||||
#include "../Experimental.h"
|
#include "../Experimental.h"
|
||||||
|
|
||||||
struct FFTParam;
|
struct FFTParam;
|
||||||
|
class SpectrumPrefs;
|
||||||
|
|
||||||
class SpectrogramSettings
|
class SpectrogramSettings
|
||||||
{
|
{
|
||||||
|
friend class SpectrumPrefs;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
enum {
|
||||||
|
LogMinWindowSize = 3,
|
||||||
|
LogMaxWindowSize = 15,
|
||||||
|
|
||||||
|
NumWindowSizes = LogMaxWindowSize - LogMinWindowSize + 1,
|
||||||
|
};
|
||||||
|
|
||||||
static SpectrogramSettings &defaults();
|
static SpectrogramSettings &defaults();
|
||||||
SpectrogramSettings();
|
SpectrogramSettings();
|
||||||
SpectrogramSettings(const SpectrogramSettings &other);
|
SpectrogramSettings(const SpectrogramSettings &other);
|
||||||
SpectrogramSettings& operator= (const SpectrogramSettings &other);
|
SpectrogramSettings& operator= (const SpectrogramSettings &other);
|
||||||
~SpectrogramSettings();
|
~SpectrogramSettings();
|
||||||
|
|
||||||
void UpdatePrefs();
|
bool IsDefault() const
|
||||||
|
{
|
||||||
|
return this == &defaults();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Validate(bool quiet);
|
||||||
|
void LoadPrefs();
|
||||||
|
void SavePrefs();
|
||||||
|
void InvalidateCaches();
|
||||||
void DestroyWindows();
|
void DestroyWindows();
|
||||||
void CacheWindows() const;
|
void CacheWindows() const;
|
||||||
|
void ConvertToEnumeratedWindowSizes();
|
||||||
|
void ConvertToActualWindowSizes();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int minFreq;
|
int minFreq;
|
||||||
@@ -78,4 +98,5 @@ public:
|
|||||||
mutable float *window;
|
mutable float *window;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -21,26 +21,30 @@
|
|||||||
#include <wx/intl.h>
|
#include <wx/intl.h>
|
||||||
#include <wx/msgdlg.h>
|
#include <wx/msgdlg.h>
|
||||||
|
|
||||||
#include "../Prefs.h"
|
#include "../FFT.h"
|
||||||
#include "../Project.h"
|
#include "../Project.h"
|
||||||
#include "../ShuttleGui.h"
|
#include "../ShuttleGui.h"
|
||||||
#include "../FFT.h"
|
#include "../WaveTrack.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
SpectrumPrefs::SpectrumPrefs(wxWindow * parent)
|
SpectrumPrefs::SpectrumPrefs(wxWindow * parent, WaveTrack *wt)
|
||||||
: PrefsPanel(parent, _("Spectrograms"))
|
: PrefsPanel(parent, _("Spectrograms"))
|
||||||
|
, mWt(wt)
|
||||||
{
|
{
|
||||||
int windowSize = gPrefs->Read(wxT("/Spectrum/FFTSize"), 256);
|
SpectrogramSettings *const pSettings = mWt
|
||||||
Populate(windowSize);
|
? &mWt->GetIndependentSpectrogramSettings()
|
||||||
|
: &SpectrogramSettings::defaults();
|
||||||
|
|
||||||
|
mTempSettings = *pSettings;
|
||||||
|
mTempSettings.ConvertToEnumeratedWindowSizes();
|
||||||
|
Populate(pSettings->windowSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
SpectrumPrefs::~SpectrumPrefs()
|
SpectrumPrefs::~SpectrumPrefs()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
enum { maxWindowSize = 32768 };
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
ID_WINDOW_SIZE = 10001,
|
ID_WINDOW_SIZE = 10001,
|
||||||
#ifdef EXPERIMENTAL_ZERO_PADDED_SPECTROGRAMS
|
#ifdef EXPERIMENTAL_ZERO_PADDED_SPECTROGRAMS
|
||||||
@@ -63,26 +67,18 @@ void SpectrumPrefs::Populate(int windowSize)
|
|||||||
mSizeChoices.Add(wxT("8192"));
|
mSizeChoices.Add(wxT("8192"));
|
||||||
mSizeChoices.Add(wxT("16384"));
|
mSizeChoices.Add(wxT("16384"));
|
||||||
mSizeChoices.Add(_("32768 - most narrowband"));
|
mSizeChoices.Add(_("32768 - most narrowband"));
|
||||||
|
wxASSERT(mSizeChoices.size() == SpectrogramSettings::NumWindowSizes);
|
||||||
int lastCode = 0;
|
|
||||||
for (size_t i = 0; i < mSizeChoices.GetCount(); i++) {
|
|
||||||
mSizeCodes.Add(lastCode = 1 << (i + 3));
|
|
||||||
}
|
|
||||||
wxASSERT(lastCode == maxWindowSize);
|
|
||||||
|
|
||||||
PopulatePaddingChoices(windowSize);
|
PopulatePaddingChoices(windowSize);
|
||||||
|
|
||||||
for (int i = 0; i < NumWindowFuncs(); i++) {
|
for (int i = 0; i < NumWindowFuncs(); i++) {
|
||||||
mTypeChoices.Add(WindowFuncName(i));
|
mTypeChoices.Add(WindowFuncName(i));
|
||||||
mTypeCodes.Add(i);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//------------------------- Main section --------------------
|
//------------------------- Main section --------------------
|
||||||
// Now construct the GUI itself.
|
// Now construct the GUI itself.
|
||||||
// Use 'eIsCreatingFromPrefs' so that the GUI is
|
ShuttleGui S(this, eIsCreating);
|
||||||
// initialised with values from gPrefs.
|
|
||||||
ShuttleGui S(this, eIsCreatingFromPrefs);
|
|
||||||
PopulateOrExchange(S);
|
PopulateOrExchange(S);
|
||||||
// ----------------------- End of main section --------------
|
// ----------------------- End of main section --------------
|
||||||
}
|
}
|
||||||
@@ -107,14 +103,12 @@ void SpectrumPrefs::PopulatePaddingChoices(int windowSize)
|
|||||||
pPaddingSizeControl->Clear();
|
pPaddingSizeControl->Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
mZeroPaddingCodes.Clear();
|
|
||||||
|
|
||||||
int padding = 1;
|
int padding = 1;
|
||||||
int numChoices = 0;
|
int numChoices = 0;
|
||||||
|
const int maxWindowSize = 1 << (SpectrogramSettings::LogMaxWindowSize);
|
||||||
while (windowSize <= maxWindowSize) {
|
while (windowSize <= maxWindowSize) {
|
||||||
const wxString numeral = wxString::Format(wxT("%d"), padding);
|
const wxString numeral = wxString::Format(wxT("%d"), padding);
|
||||||
mZeroPaddingChoices.Add(numeral);
|
mZeroPaddingChoices.Add(numeral);
|
||||||
mZeroPaddingCodes.Add(padding);
|
|
||||||
if (pPaddingSizeControl)
|
if (pPaddingSizeControl)
|
||||||
pPaddingSizeControl->Append(numeral);
|
pPaddingSizeControl->Append(numeral);
|
||||||
windowSize <<= 1;
|
windowSize <<= 1;
|
||||||
@@ -138,25 +132,19 @@ void SpectrumPrefs::PopulateOrExchange(ShuttleGui & S)
|
|||||||
S.StartMultiColumn(2);
|
S.StartMultiColumn(2);
|
||||||
{
|
{
|
||||||
S.Id(ID_WINDOW_SIZE).TieChoice(_("Window &size:"),
|
S.Id(ID_WINDOW_SIZE).TieChoice(_("Window &size:"),
|
||||||
wxT("/Spectrum/FFTSize"),
|
mTempSettings.windowSize,
|
||||||
256,
|
&mSizeChoices);
|
||||||
mSizeChoices,
|
|
||||||
mSizeCodes);
|
|
||||||
S.SetSizeHints(mSizeChoices);
|
S.SetSizeHints(mSizeChoices);
|
||||||
|
|
||||||
S.TieChoice(_("Window &type:"),
|
S.TieChoice(_("Window &type:"),
|
||||||
wxT("/Spectrum/WindowType"),
|
mTempSettings.windowType,
|
||||||
3,
|
&mTypeChoices);
|
||||||
mTypeChoices,
|
|
||||||
mTypeCodes);
|
|
||||||
S.SetSizeHints(mTypeChoices);
|
S.SetSizeHints(mTypeChoices);
|
||||||
|
|
||||||
#ifdef EXPERIMENTAL_ZERO_PADDED_SPECTROGRAMS
|
#ifdef EXPERIMENTAL_ZERO_PADDED_SPECTROGRAMS
|
||||||
S.Id(ID_PADDING_SIZE).TieChoice(_("&Zero padding factor") + wxString(wxT(":")),
|
S.Id(ID_PADDING_SIZE).TieChoice(_("&Zero padding factor") + wxString(wxT(":")),
|
||||||
wxT("/Spectrum/ZeroPaddingFactor"),
|
mTempSettings.zeroPaddingFactor,
|
||||||
mZeroPaddingChoice,
|
&mZeroPaddingChoices);
|
||||||
mZeroPaddingChoices,
|
|
||||||
mZeroPaddingCodes);
|
|
||||||
S.SetSizeHints(mZeroPaddingChoices);
|
S.SetSizeHints(mZeroPaddingChoices);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -170,44 +158,37 @@ void SpectrumPrefs::PopulateOrExchange(ShuttleGui & S)
|
|||||||
{
|
{
|
||||||
mMinFreq =
|
mMinFreq =
|
||||||
S.TieNumericTextBox(_("Mi&nimum Frequency (Hz):"),
|
S.TieNumericTextBox(_("Mi&nimum Frequency (Hz):"),
|
||||||
wxT("/Spectrum/MinFreq"),
|
mTempSettings.minFreq,
|
||||||
0,
|
|
||||||
12);
|
12);
|
||||||
|
|
||||||
mMaxFreq =
|
mMaxFreq =
|
||||||
S.TieNumericTextBox(_("Ma&ximum Frequency (Hz):"),
|
S.TieNumericTextBox(_("Ma&ximum Frequency (Hz):"),
|
||||||
wxT("/Spectrum/MaxFreq"),
|
mTempSettings.maxFreq,
|
||||||
8000,
|
|
||||||
12);
|
12);
|
||||||
|
|
||||||
mGain =
|
mGain =
|
||||||
S.TieNumericTextBox(_("&Gain (dB):"),
|
S.TieNumericTextBox(_("&Gain (dB):"),
|
||||||
wxT("/Spectrum/Gain"),
|
mTempSettings.gain,
|
||||||
20,
|
|
||||||
8);
|
8);
|
||||||
|
|
||||||
mRange =
|
mRange =
|
||||||
S.TieNumericTextBox(_("&Range (dB):"),
|
S.TieNumericTextBox(_("&Range (dB):"),
|
||||||
wxT("/Spectrum/Range"),
|
mTempSettings.range,
|
||||||
80,
|
|
||||||
8);
|
8);
|
||||||
|
|
||||||
mFrequencyGain =
|
mFrequencyGain =
|
||||||
S.TieNumericTextBox(_("Frequency g&ain (dB/dec):"),
|
S.TieNumericTextBox(_("Frequency g&ain (dB/dec):"),
|
||||||
wxT("/Spectrum/FrequencyGain"),
|
mTempSettings.frequencyGain,
|
||||||
0,
|
|
||||||
4);
|
4);
|
||||||
}
|
}
|
||||||
S.EndTwoColumn();
|
S.EndTwoColumn();
|
||||||
|
|
||||||
S.TieCheckBox(_("S&how the spectrum using grayscale colors"),
|
S.TieCheckBox(_("S&how the spectrum using grayscale colors"),
|
||||||
wxT("/Spectrum/Grayscale"),
|
mTempSettings.isGrayscale);
|
||||||
false);
|
|
||||||
|
|
||||||
#ifdef EXPERIMENTAL_FFT_Y_GRID
|
#ifdef EXPERIMENTAL_FFT_Y_GRID
|
||||||
S.TieCheckBox(_("Show a grid along the &Y-axis"),
|
S.TieCheckBox(_("Show a grid along the &Y-axis"),
|
||||||
wxT("/Spectrum/FFTYGrid"),
|
mTempSettings.fftYGrid);
|
||||||
false);
|
|
||||||
#endif //EXPERIMENTAL_FFT_Y_GRID
|
#endif //EXPERIMENTAL_FFT_Y_GRID
|
||||||
}
|
}
|
||||||
S.EndStatic();
|
S.EndStatic();
|
||||||
@@ -220,25 +201,21 @@ void SpectrumPrefs::PopulateOrExchange(ShuttleGui & S)
|
|||||||
{
|
{
|
||||||
mFindNotesMinA =
|
mFindNotesMinA =
|
||||||
S.TieNumericTextBox(_("Minimum Amplitude (dB):"),
|
S.TieNumericTextBox(_("Minimum Amplitude (dB):"),
|
||||||
wxT("/Spectrum/FindNotesMinA"),
|
mTempSettings.fftFindNotes,
|
||||||
-30L,
|
|
||||||
8);
|
8);
|
||||||
|
|
||||||
mFindNotesN =
|
mFindNotesN =
|
||||||
S.TieNumericTextBox(_("Max. Number of Notes (1..128):"),
|
S.TieNumericTextBox(_("Max. Number of Notes (1..128):"),
|
||||||
wxT("/Spectrum/FindNotesN"),
|
mTempSettings.findNotesMinA,
|
||||||
5L,
|
|
||||||
8);
|
8);
|
||||||
}
|
}
|
||||||
S.EndTwoColumn();
|
S.EndTwoColumn();
|
||||||
|
|
||||||
S.TieCheckBox(_("&Find Notes"),
|
S.TieCheckBox(_("&Find Notes"),
|
||||||
wxT("/Spectrum/FFTFindNotes"),
|
mTempSettings.numberOfMaxima);
|
||||||
false);
|
|
||||||
|
|
||||||
S.TieCheckBox(_("&Quantize Notes"),
|
S.TieCheckBox(_("&Quantize Notes"),
|
||||||
wxT("/Spectrum/FindNotesQuantize"),
|
mTempSettings.findNotesQuantize);
|
||||||
false);
|
|
||||||
}
|
}
|
||||||
S.EndStatic();
|
S.EndStatic();
|
||||||
#endif //EXPERIMENTAL_FIND_NOTES
|
#endif //EXPERIMENTAL_FIND_NOTES
|
||||||
@@ -246,59 +223,40 @@ void SpectrumPrefs::PopulateOrExchange(ShuttleGui & S)
|
|||||||
|
|
||||||
bool SpectrumPrefs::Validate()
|
bool SpectrumPrefs::Validate()
|
||||||
{
|
{
|
||||||
|
// Do checking for whole numbers
|
||||||
|
|
||||||
|
// ToDo: use wxIntegerValidator<unsigned> when available
|
||||||
|
|
||||||
long maxFreq;
|
long maxFreq;
|
||||||
if (!mMaxFreq->GetValue().ToLong(&maxFreq)) {
|
if (!mMaxFreq->GetValue().ToLong(&maxFreq)) {
|
||||||
wxMessageBox(_("The maximum frequency must be an integer"));
|
wxMessageBox(_("The maximum frequency must be an integer"));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (maxFreq < 100) {
|
|
||||||
wxMessageBox(_("Maximum frequency must be 100 Hz or above"));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
long minFreq;
|
long minFreq;
|
||||||
if (!mMinFreq->GetValue().ToLong(&minFreq)) {
|
if (!mMinFreq->GetValue().ToLong(&minFreq)) {
|
||||||
wxMessageBox(_("The minimum frequency must be an integer"));
|
wxMessageBox(_("The minimum frequency must be an integer"));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (minFreq < 0) {
|
|
||||||
wxMessageBox(_("Minimum frequency must be at least 0 Hz"));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (maxFreq < minFreq) {
|
|
||||||
wxMessageBox(_("Minimum frequency must be less than maximum frequency"));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
long gain;
|
long gain;
|
||||||
if (!mGain->GetValue().ToLong(&gain)) {
|
if (!mGain->GetValue().ToLong(&gain)) {
|
||||||
wxMessageBox(_("The gain must be an integer"));
|
wxMessageBox(_("The gain must be an integer"));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
long range;
|
long range;
|
||||||
if (!mRange->GetValue().ToLong(&range)) {
|
if (!mRange->GetValue().ToLong(&range)) {
|
||||||
wxMessageBox(_("The range must be a positive integer"));
|
wxMessageBox(_("The range must be a positive integer"));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (range <= 0) {
|
|
||||||
wxMessageBox(_("The range must be at least 1 dB"));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
long frequencygain;
|
long frequencygain;
|
||||||
if (!mFrequencyGain->GetValue().ToLong(&frequencygain)) {
|
if (!mFrequencyGain->GetValue().ToLong(&frequencygain)) {
|
||||||
wxMessageBox(_("The frequency gain must be an integer"));
|
wxMessageBox(_("The frequency gain must be an integer"));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (frequencygain < 0) {
|
|
||||||
wxMessageBox(_("The frequency gain cannot be negative"));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (frequencygain > 60) {
|
|
||||||
wxMessageBox(_("The frequency gain must be no more than 60 dB/dec"));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
#ifdef EXPERIMENTAL_FIND_NOTES
|
#ifdef EXPERIMENTAL_FIND_NOTES
|
||||||
long findNotesMinA;
|
long findNotesMinA;
|
||||||
if (!mFindNotesMinA->GetValue().ToLong(&findNotesMinA)) {
|
if (!mFindNotesMinA->GetValue().ToLong(&findNotesMinA)) {
|
||||||
@@ -317,15 +275,52 @@ bool SpectrumPrefs::Validate()
|
|||||||
}
|
}
|
||||||
#endif //EXPERIMENTAL_FIND_NOTES
|
#endif //EXPERIMENTAL_FIND_NOTES
|
||||||
|
|
||||||
return true;
|
ShuttleGui S(this, eIsGettingFromDialog);
|
||||||
|
PopulateOrExchange(S);
|
||||||
|
|
||||||
|
// Delegate range checking to SpectrogramSettings class
|
||||||
|
mTempSettings.ConvertToActualWindowSizes();
|
||||||
|
const bool result = mTempSettings.Validate(false);
|
||||||
|
mTempSettings.ConvertToEnumeratedWindowSizes();
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SpectrumPrefs::Apply()
|
bool SpectrumPrefs::Apply()
|
||||||
{
|
{
|
||||||
ShuttleGui S(this, eIsSavingToPrefs);
|
const bool isOpenPage = this->IsShown();
|
||||||
|
|
||||||
|
WaveTrack *const partner =
|
||||||
|
mWt ? static_cast<WaveTrack*>(mWt->GetLink()) : 0;
|
||||||
|
|
||||||
|
ShuttleGui S(this, eIsGettingFromDialog);
|
||||||
PopulateOrExchange(S);
|
PopulateOrExchange(S);
|
||||||
|
|
||||||
SpectrogramSettings::defaults().UpdatePrefs();
|
mTempSettings.ConvertToActualWindowSizes();
|
||||||
|
if (mWt) {
|
||||||
|
SpectrogramSettings *pSettings =
|
||||||
|
&mWt->GetIndependentSpectrogramSettings();
|
||||||
|
*pSettings = mTempSettings;
|
||||||
|
if (partner) {
|
||||||
|
pSettings = &partner->GetIndependentSpectrogramSettings();
|
||||||
|
*pSettings = mTempSettings;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
SpectrogramSettings *const pSettings =
|
||||||
|
&SpectrogramSettings::defaults();
|
||||||
|
*pSettings = mTempSettings;
|
||||||
|
pSettings->SavePrefs();
|
||||||
|
}
|
||||||
|
mTempSettings.ConvertToEnumeratedWindowSizes();
|
||||||
|
|
||||||
|
if (mWt && isOpenPage) {
|
||||||
|
// Future: open page will determine the track view type
|
||||||
|
/*
|
||||||
|
mWt->SetDisplay(WaveTrack::Spectrum);
|
||||||
|
if (partner)
|
||||||
|
partner->SetDisplay(WaveTrack::Spectrum);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -334,7 +329,8 @@ void SpectrumPrefs::OnWindowSize(wxCommandEvent &)
|
|||||||
{
|
{
|
||||||
wxChoice *const pWindowSizeControl =
|
wxChoice *const pWindowSizeControl =
|
||||||
static_cast<wxChoice*>(wxWindow::FindWindowById(ID_WINDOW_SIZE, this));
|
static_cast<wxChoice*>(wxWindow::FindWindowById(ID_WINDOW_SIZE, this));
|
||||||
int windowSize = 1 << (pWindowSizeControl->GetSelection() + 3);
|
int windowSize = 1 <<
|
||||||
|
(pWindowSizeControl->GetSelection() + SpectrogramSettings::LogMinWindowSize);
|
||||||
PopulatePaddingChoices(windowSize);
|
PopulatePaddingChoices(windowSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -342,7 +338,12 @@ BEGIN_EVENT_TABLE(SpectrumPrefs, PrefsPanel)
|
|||||||
EVT_CHOICE(ID_WINDOW_SIZE, SpectrumPrefs::OnWindowSize)
|
EVT_CHOICE(ID_WINDOW_SIZE, SpectrumPrefs::OnWindowSize)
|
||||||
END_EVENT_TABLE()
|
END_EVENT_TABLE()
|
||||||
|
|
||||||
|
SpectrumPrefsFactory::SpectrumPrefsFactory(WaveTrack *wt)
|
||||||
|
: mWt(wt)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
PrefsPanel *SpectrumPrefsFactory::Create(wxWindow *parent)
|
PrefsPanel *SpectrumPrefsFactory::Create(wxWindow *parent)
|
||||||
{
|
{
|
||||||
return new SpectrumPrefs(parent);
|
return new SpectrumPrefs(parent, mWt);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,11 +33,13 @@
|
|||||||
class wxTextCtrl;
|
class wxTextCtrl;
|
||||||
struct FFTParam;
|
struct FFTParam;
|
||||||
class ShuttleGui;
|
class ShuttleGui;
|
||||||
|
class SpectrogramSettings;
|
||||||
|
class WaveTrack;
|
||||||
|
|
||||||
class SpectrumPrefs:public PrefsPanel
|
class SpectrumPrefs:public PrefsPanel
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SpectrumPrefs(wxWindow * parent);
|
SpectrumPrefs(wxWindow * parent, WaveTrack *wt);
|
||||||
virtual ~SpectrumPrefs();
|
virtual ~SpectrumPrefs();
|
||||||
virtual bool Apply();
|
virtual bool Apply();
|
||||||
virtual bool Validate();
|
virtual bool Validate();
|
||||||
@@ -50,6 +52,8 @@ class SpectrumPrefs:public PrefsPanel
|
|||||||
void OnWindowSize(wxCommandEvent &event);
|
void OnWindowSize(wxCommandEvent &event);
|
||||||
DECLARE_EVENT_TABLE()
|
DECLARE_EVENT_TABLE()
|
||||||
|
|
||||||
|
WaveTrack *const mWt;
|
||||||
|
|
||||||
wxTextCtrl *mMinFreq;
|
wxTextCtrl *mMinFreq;
|
||||||
wxTextCtrl *mMaxFreq;
|
wxTextCtrl *mMaxFreq;
|
||||||
wxTextCtrl *mGain;
|
wxTextCtrl *mGain;
|
||||||
@@ -57,28 +61,31 @@ class SpectrumPrefs:public PrefsPanel
|
|||||||
wxTextCtrl *mFrequencyGain;
|
wxTextCtrl *mFrequencyGain;
|
||||||
|
|
||||||
wxArrayString mSizeChoices;
|
wxArrayString mSizeChoices;
|
||||||
wxArrayInt mSizeCodes;
|
|
||||||
|
|
||||||
#ifdef EXPERIMENTAL_ZERO_PADDED_SPECTROGRAMS
|
#ifdef EXPERIMENTAL_ZERO_PADDED_SPECTROGRAMS
|
||||||
int mZeroPaddingChoice;
|
int mZeroPaddingChoice;
|
||||||
wxArrayString mZeroPaddingChoices;
|
wxArrayString mZeroPaddingChoices;
|
||||||
wxArrayInt mZeroPaddingCodes;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
wxArrayString mTypeChoices;
|
wxArrayString mTypeChoices;
|
||||||
wxArrayInt mTypeCodes;
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef EXPERIMENTAL_FIND_NOTES
|
#ifdef EXPERIMENTAL_FIND_NOTES
|
||||||
wxTextCtrl *mFindNotesMinA;
|
wxTextCtrl *mFindNotesMinA;
|
||||||
wxTextCtrl *mFindNotesN;
|
wxTextCtrl *mFindNotesN;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
SpectrogramSettings mTempSettings;
|
||||||
};
|
};
|
||||||
|
|
||||||
class SpectrumPrefsFactory : public PrefsPanelFactory
|
class SpectrumPrefsFactory : public PrefsPanelFactory
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
explicit SpectrumPrefsFactory(WaveTrack *wt = 0);
|
||||||
virtual PrefsPanel *Create(wxWindow *parent);
|
virtual PrefsPanel *Create(wxWindow *parent);
|
||||||
|
|
||||||
|
private:
|
||||||
|
WaveTrack *const mWt;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user