1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-07-03 14:13:11 +02:00

Add "View Settings..." to track drop-down and Apply button to Spectrogram prefs

This commit is contained in:
Paul Licameli 2015-07-26 21:38:14 -04:00
commit 504d4b5331
6 changed files with 472 additions and 178 deletions

View File

@ -217,7 +217,8 @@ is time to refresh some aspect of the screen.
#include "ondemand/ODManager.h"
#include "prefs/SpectrogramSettings.h"
#include "prefs/PrefsDialog.h"
#include "prefs/SpectrumPrefs.h"
#include "toolbars/ControlToolBar.h"
#include "toolbars/ToolManager.h"
@ -330,6 +331,7 @@ enum {
OnSpectralSelID,
OnSpectralSelLogID,
OnPitchID,
OnViewSettingsID,
OnSplitStereoID,
OnSplitStereoMonoID,
@ -369,6 +371,7 @@ BEGIN_EVENT_TABLE(TrackPanel, wxWindow)
EVT_MENU_RANGE(OnChannelLeftID, OnChannelMonoID,
TrackPanel::OnChannelChange)
EVT_MENU_RANGE(OnWaveformID, OnPitchID, TrackPanel::OnSetDisplay)
EVT_MENU(OnViewSettingsID, TrackPanel::OnViewSettings)
EVT_MENU_RANGE(OnRate8ID, OnRate384ID, TrackPanel::OnRateChange)
EVT_MENU_RANGE(On16BitID, OnFloatID, TrackPanel::OnFormatChange)
EVT_MENU(OnRateOtherID, TrackPanel::OnRateOther)
@ -731,9 +734,10 @@ void TrackPanel::BuildMenus(void)
mWaveTrackMenu->Append(OnSpectralSelID, _("S&pectral Selection"));
/* i18n-hint: short form of 'logarithm'*/
mWaveTrackMenu->Append(OnSpectralSelLogID, _("Spectral Selection lo&g(f)"));
mWaveTrackMenu->Append(OnPitchID, _("Pitc&h (EAC)"));
mWaveTrackMenu->Append(OnViewSettingsID, _("View& Settings...")); // PRL: all the other letters already taken for accelerators!
mWaveTrackMenu->AppendSeparator();
mWaveTrackMenu->AppendRadioItem(OnChannelMonoID, _("&Mono"));
mWaveTrackMenu->AppendRadioItem(OnChannelLeftID, _("&Left Channel"));
mWaveTrackMenu->AppendRadioItem(OnChannelRightID, _("&Right Channel"));
@ -8569,6 +8573,7 @@ void TrackPanel::OnTrackMenu(Track *t)
theMenu->Enable(OnSpectralSelID, display != WaveTrack::SpectralSelectionDisplay);
theMenu->Enable(OnSpectralSelLogID, display != WaveTrack::SpectralSelectionLogDisplay);
theMenu->Enable(OnPitchID, display != WaveTrack::PitchDisplay);
theMenu->Enable(OnViewSettingsID, true);
WaveTrack * track = (WaveTrack *)t;
SetMenuCheck(*mRateMenu, IdOfRate((int) track->GetRate()));
@ -9030,6 +9035,37 @@ void TrackPanel::OnMergeStereo(wxCommandEvent & WXUNUSED(event))
Refresh(false);
}
class ViewSettingsDialog : public PrefsDialog
{
public:
ViewSettingsDialog(wxWindow *parent, PrefsDialog::Factories &factories)
: PrefsDialog(parent, _("View Settings: "), factories)
{
}
virtual long GetPreferredPage()
{
// Future: choose Spectrum or Waveform page
return 0;
}
virtual void SavePreferredPage()
{
}
};
void TrackPanel::OnViewSettings(wxCommandEvent &)
{
WaveTrack *const wt = static_cast<WaveTrack*>(mPopupMenuTarget);
SpectrumPrefsFactory spectrumFactory(wt);
PrefsDialog::Factories factories;
factories.push_back(&spectrumFactory);
ViewSettingsDialog dialog(this, factories);
if (0 != dialog.ShowModal())
// Redraw
Refresh(false);
}
/// Set the Display mode based on the menu choice in the Track Menu.
/// Note that gModes MUST BE IN THE SAME ORDER AS THE MENU CHOICES!!
/// const wxChar *gModes[] = { wxT("waveform"), wxT("waveformDB"),

View File

@ -459,6 +459,7 @@ protected:
virtual void MoveTrack(Track* target, int eventId);
virtual void OnChangeOctave (wxCommandEvent &event);
virtual void OnChannelChange(wxCommandEvent &event);
virtual void OnViewSettings(wxCommandEvent &event);
virtual void OnSetDisplay (wxCommandEvent &event);
virtual void OnSetTimeTrackRange (wxCommandEvent &event);
virtual void OnTimeTrackLin(wxCommandEvent &event);

View File

@ -15,6 +15,10 @@ Paul Licameli
#include "../Audacity.h"
#include "SpectrogramSettings.h"
#include <algorithm>
#include <wx/msgdlg.h>
#include "../FFT.h"
#include "../Prefs.h"
#include "../RealFFTf.h"
@ -26,7 +30,7 @@ SpectrogramSettings::SpectrogramSettings()
: hFFT(0)
, window(0)
{
UpdatePrefs();
LoadPrefs();
}
SpectrogramSettings::SpectrogramSettings(const SpectrogramSettings &other)
@ -98,49 +102,82 @@ SpectrogramSettings& SpectrogramSettings::defaults()
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);
// 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);
gain = gPrefs->Read(wxT("/Spectrum/Gain"), 20L);
frequencyGain = gPrefs->Read(wxT("/Spectrum/FrequencyGain"), 0L);
const int newWindowSize = gPrefs->Read(wxT("/Spectrum/FFTSize"), 256);
if (newWindowSize != windowSize) {
destroy = true;
windowSize = newWindowSize;
}
windowSize = gPrefs->Read(wxT("/Spectrum/FFTSize"), 256);
#ifdef EXPERIMENTAL_ZERO_PADDED_SPECTROGRAMS
const int newZeroPaddingFactor = gPrefs->Read(wxT("/Spectrum/ZeroPaddingFactor"), 1);
if (newZeroPaddingFactor != zeroPaddingFactor) {
destroy = true;
zeroPaddingFactor = newZeroPaddingFactor;
}
zeroPaddingFactor = gPrefs->Read(wxT("/Spectrum/ZeroPaddingFactor"), 1);
#endif
int newWindowType;
gPrefs->Read(wxT("/Spectrum/WindowType"), &newWindowType, 3);
if (newWindowType != windowType) {
destroy = true;
windowType = newWindowType;
}
gPrefs->Read(wxT("/Spectrum/WindowType"), &windowType, eWinFuncHanning);
isGrayscale = (gPrefs->Read(wxT("/Spectrum/Grayscale"), 0L) != 0);
@ -155,8 +192,64 @@ void SpectrogramSettings::UpdatePrefs()
findNotesQuantize = (gPrefs->Read(wxT("/Spectrum/FindNotesQuantize"), 0L) != 0);
#endif //EXPERIMENTAL_FIND_NOTES
if (destroy)
DestroyWindows();
// 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();
}
SpectrogramSettings::~SpectrogramSettings()
@ -257,6 +350,38 @@ void SpectrogramSettings::CacheWindows() const
#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
{
const int top = lrint(rate / 2.);

View File

@ -14,19 +14,39 @@ Paul Licameli
#include "../Experimental.h"
struct FFTParam;
class SpectrumPrefs;
class SpectrogramSettings
{
friend class SpectrumPrefs;
public:
enum {
LogMinWindowSize = 3,
LogMaxWindowSize = 15,
NumWindowSizes = LogMaxWindowSize - LogMinWindowSize + 1,
};
static SpectrogramSettings &defaults();
SpectrogramSettings();
SpectrogramSettings(const SpectrogramSettings &other);
SpectrogramSettings& operator= (const SpectrogramSettings &other);
~SpectrogramSettings();
void UpdatePrefs();
bool IsDefault() const
{
return this == &defaults();
}
bool Validate(bool quiet);
void LoadPrefs();
void SavePrefs();
void InvalidateCaches();
void DestroyWindows();
void CacheWindows() const;
void ConvertToEnumeratedWindowSizes();
void ConvertToActualWindowSizes();
private:
int minFreq;
@ -78,4 +98,5 @@ public:
mutable float *window;
#endif
};
#endif

View File

@ -20,18 +20,33 @@
#include <wx/defs.h>
#include <wx/intl.h>
#include <wx/msgdlg.h>
#include <wx/checkbox.h>
#include "../Prefs.h"
#include "../FFT.h"
#include "../Project.h"
#include "../ShuttleGui.h"
#include "../FFT.h"
#include "../WaveTrack.h"
#include "../TrackPanel.h"
#include <algorithm>
SpectrumPrefs::SpectrumPrefs(wxWindow * parent)
SpectrumPrefs::SpectrumPrefs(wxWindow * parent, WaveTrack *wt)
: PrefsPanel(parent, _("Spectrograms"))
, mWt(wt)
, mPopulating(false)
{
int windowSize = gPrefs->Read(wxT("/Spectrum/FFTSize"), 256);
if (mWt) {
SpectrogramSettings &settings = wt->GetSpectrogramSettings();
mDefaulted = (&SpectrogramSettings::defaults() == &settings);
mTempSettings = settings;
}
else {
mTempSettings = SpectrogramSettings::defaults();
mDefaulted = false;
}
const int windowSize = mTempSettings.windowSize;
mTempSettings.ConvertToEnumeratedWindowSizes();
Populate(windowSize);
}
@ -39,13 +54,20 @@ SpectrumPrefs::~SpectrumPrefs()
{
}
enum { maxWindowSize = 32768 };
enum {
ID_WINDOW_SIZE = 10001,
#ifdef EXPERIMENTAL_ZERO_PADDED_SPECTROGRAMS
ID_PADDING_SIZE = 10002,
ID_WINDOW_TYPE,
ID_PADDING_SIZE,
ID_MINIMUM,
ID_MAXIMUM,
ID_GAIN,
ID_RANGE,
ID_FREQUENCY_GAIN,
ID_GRAYSCALE,
#endif
ID_DEFAULTS,
ID_APPLY,
};
void SpectrumPrefs::Populate(int windowSize)
@ -63,26 +85,18 @@ void SpectrumPrefs::Populate(int windowSize)
mSizeChoices.Add(wxT("8192"));
mSizeChoices.Add(wxT("16384"));
mSizeChoices.Add(_("32768 - most narrowband"));
int lastCode = 0;
for (size_t i = 0; i < mSizeChoices.GetCount(); i++) {
mSizeCodes.Add(lastCode = 1 << (i + 3));
}
wxASSERT(lastCode == maxWindowSize);
wxASSERT(mSizeChoices.size() == SpectrogramSettings::NumWindowSizes);
PopulatePaddingChoices(windowSize);
for (int i = 0; i < NumWindowFuncs(); i++) {
mTypeChoices.Add(WindowFuncName(i));
mTypeCodes.Add(i);
}
//------------------------- Main section --------------------
// Now construct the GUI itself.
// Use 'eIsCreatingFromPrefs' so that the GUI is
// initialised with values from gPrefs.
ShuttleGui S(this, eIsCreatingFromPrefs);
ShuttleGui S(this, eIsCreating);
PopulateOrExchange(S);
// ----------------------- End of main section --------------
}
@ -107,14 +121,12 @@ void SpectrumPrefs::PopulatePaddingChoices(int windowSize)
pPaddingSizeControl->Clear();
}
mZeroPaddingCodes.Clear();
int padding = 1;
int numChoices = 0;
const int maxWindowSize = 1 << (SpectrogramSettings::LogMaxWindowSize);
while (windowSize <= maxWindowSize) {
const wxString numeral = wxString::Format(wxT("%d"), padding);
mZeroPaddingChoices.Add(numeral);
mZeroPaddingCodes.Add(padding);
if (pPaddingSizeControl)
pPaddingSizeControl->Append(numeral);
windowSize <<= 1;
@ -131,174 +143,156 @@ void SpectrumPrefs::PopulatePaddingChoices(int windowSize)
void SpectrumPrefs::PopulateOrExchange(ShuttleGui & S)
{
mPopulating = true;
S.SetBorder(2);
S.StartStatic(_("FFT Window"));
// S.StartStatic(_("Track Settings"));
{
S.StartMultiColumn(2);
mDefaultsCheckbox = 0;
if (mWt) {
mDefaultsCheckbox = S.Id(ID_DEFAULTS).TieCheckBox(_("Defaults"), mDefaulted);
}
S.StartStatic(_("FFT Window"));
{
S.Id(ID_WINDOW_SIZE).TieChoice(_("Window &size:"),
wxT("/Spectrum/FFTSize"),
256,
mSizeChoices,
mSizeCodes);
S.SetSizeHints(mSizeChoices);
S.StartMultiColumn(2);
{
S.Id(ID_WINDOW_SIZE).TieChoice(_("Window &size:"),
mTempSettings.windowSize,
&mSizeChoices);
S.SetSizeHints(mSizeChoices);
S.TieChoice(_("Window &type:"),
wxT("/Spectrum/WindowType"),
3,
mTypeChoices,
mTypeCodes);
S.SetSizeHints(mTypeChoices);
S.Id(ID_WINDOW_TYPE).TieChoice(_("Window &type:"),
mTempSettings.windowType,
&mTypeChoices);
S.SetSizeHints(mTypeChoices);
#ifdef EXPERIMENTAL_ZERO_PADDED_SPECTROGRAMS
S.Id(ID_PADDING_SIZE).TieChoice(_("&Zero padding factor") + wxString(wxT(":")),
wxT("/Spectrum/ZeroPaddingFactor"),
mZeroPaddingChoice,
mZeroPaddingChoices,
mZeroPaddingCodes);
S.SetSizeHints(mZeroPaddingChoices);
S.Id(ID_PADDING_SIZE).TieChoice(_("&Zero padding factor") + wxString(wxT(":")),
mTempSettings.zeroPaddingFactor,
&mZeroPaddingChoices);
S.SetSizeHints(mZeroPaddingChoices);
#endif
}
S.EndMultiColumn();
}
S.EndMultiColumn();
}
S.EndStatic();
S.EndStatic();
S.StartStatic(_("Display"));
{
S.StartTwoColumn();
S.StartStatic(_("Display"));
{
mMinFreq =
S.TieNumericTextBox(_("Mi&nimum Frequency (Hz):"),
wxT("/Spectrum/MinFreq"),
0,
12);
S.StartTwoColumn();
{
mMinFreq =
S.Id(ID_MINIMUM).TieNumericTextBox(_("Mi&nimum Frequency (Hz):"),
mTempSettings.minFreq,
12);
mMaxFreq =
S.TieNumericTextBox(_("Ma&ximum Frequency (Hz):"),
wxT("/Spectrum/MaxFreq"),
8000,
12);
mMaxFreq =
S.Id(ID_MAXIMUM).TieNumericTextBox(_("Ma&ximum Frequency (Hz):"),
mTempSettings.maxFreq,
12);
mGain =
S.TieNumericTextBox(_("&Gain (dB):"),
wxT("/Spectrum/Gain"),
20,
8);
mGain =
S.Id(ID_GAIN).TieNumericTextBox(_("&Gain (dB):"),
mTempSettings.gain,
8);
mRange =
S.TieNumericTextBox(_("&Range (dB):"),
wxT("/Spectrum/Range"),
80,
8);
mRange =
S.Id(ID_RANGE).TieNumericTextBox(_("&Range (dB):"),
mTempSettings.range,
8);
mFrequencyGain =
S.TieNumericTextBox(_("Frequency g&ain (dB/dec):"),
wxT("/Spectrum/FrequencyGain"),
0,
4);
}
S.EndTwoColumn();
mFrequencyGain =
S.Id(ID_FREQUENCY_GAIN).TieNumericTextBox(_("Frequency g&ain (dB/dec):"),
mTempSettings.frequencyGain,
4);
}
S.EndTwoColumn();
S.TieCheckBox(_("S&how the spectrum using grayscale colors"),
wxT("/Spectrum/Grayscale"),
false);
S.Id(ID_GRAYSCALE).TieCheckBox(_("S&how the spectrum using grayscale colors"),
mTempSettings.isGrayscale);
#ifdef EXPERIMENTAL_FFT_Y_GRID
S.TieCheckBox(_("Show a grid along the &Y-axis"),
wxT("/Spectrum/FFTYGrid"),
false);
S.TieCheckBox(_("Show a grid along the &Y-axis"),
mTempSettings.fftYGrid);
#endif //EXPERIMENTAL_FFT_Y_GRID
}
S.EndStatic();
}
S.EndStatic();
#ifdef EXPERIMENTAL_FIND_NOTES
/* i18n-hint: FFT stands for Fast Fourier Transform and probably shouldn't be translated*/
S.StartStatic(_("FFT Find Notes"));
{
S.StartTwoColumn();
/* i18n-hint: FFT stands for Fast Fourier Transform and probably shouldn't be translated*/
S.StartStatic(_("FFT Find Notes"));
{
mFindNotesMinA =
S.TieNumericTextBox(_("Minimum Amplitude (dB):"),
wxT("/Spectrum/FindNotesMinA"),
-30L,
8);
S.StartTwoColumn();
{
mFindNotesMinA =
S.TieNumericTextBox(_("Minimum Amplitude (dB):"),
mTempSettings.fftFindNotes,
8);
mFindNotesN =
S.TieNumericTextBox(_("Max. Number of Notes (1..128):"),
wxT("/Spectrum/FindNotesN"),
5L,
8);
mFindNotesN =
S.TieNumericTextBox(_("Max. Number of Notes (1..128):"),
mTempSettings.findNotesMinA,
8);
}
S.EndTwoColumn();
S.TieCheckBox(_("&Find Notes"),
mTempSettings.numberOfMaxima);
S.TieCheckBox(_("&Quantize Notes"),
mTempSettings.findNotesQuantize);
}
S.EndTwoColumn();
S.TieCheckBox(_("&Find Notes"),
wxT("/Spectrum/FFTFindNotes"),
false);
S.TieCheckBox(_("&Quantize Notes"),
wxT("/Spectrum/FindNotesQuantize"),
false);
}
S.EndStatic();
S.EndStatic();
#endif //EXPERIMENTAL_FIND_NOTES
}
// S.EndStatic();
S.StartMultiColumn(2, wxALIGN_RIGHT);
{
S.Id(ID_APPLY).AddButton(_("Appl&y"));
}
S.EndMultiColumn();
mPopulating = false;
}
bool SpectrumPrefs::Validate()
{
// Do checking for whole numbers
// ToDo: use wxIntegerValidator<unsigned> when available
long maxFreq;
if (!mMaxFreq->GetValue().ToLong(&maxFreq)) {
wxMessageBox(_("The maximum frequency must be an integer"));
return false;
}
if (maxFreq < 100) {
wxMessageBox(_("Maximum frequency must be 100 Hz or above"));
return false;
}
long minFreq;
if (!mMinFreq->GetValue().ToLong(&minFreq)) {
wxMessageBox(_("The minimum frequency must be an integer"));
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;
if (!mGain->GetValue().ToLong(&gain)) {
wxMessageBox(_("The gain must be an integer"));
return false;
}
long range;
if (!mRange->GetValue().ToLong(&range)) {
wxMessageBox(_("The range must be a positive integer"));
return false;
}
if (range <= 0) {
wxMessageBox(_("The range must be at least 1 dB"));
return false;
}
long frequencygain;
if (!mFrequencyGain->GetValue().ToLong(&frequencygain)) {
wxMessageBox(_("The frequency gain must be an integer"));
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
long findNotesMinA;
if (!mFindNotesMinA->GetValue().ToLong(&findNotesMinA)) {
@ -317,32 +311,132 @@ bool SpectrumPrefs::Validate()
}
#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()
{
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);
SpectrogramSettings::defaults().UpdatePrefs();
mTempSettings.ConvertToActualWindowSizes();
if (mWt) {
if (mDefaulted) {
mWt->SetSpectrogramSettings(NULL);
if (partner)
partner->SetSpectrogramSettings(NULL);
}
else {
SpectrogramSettings *pSettings =
&mWt->GetIndependentSpectrogramSettings();
*pSettings = mTempSettings;
if (partner) {
pSettings = &partner->GetIndependentSpectrogramSettings();
*pSettings = mTempSettings;
}
}
}
if (!mWt || mDefaulted) {
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;
}
void SpectrumPrefs::OnWindowSize(wxCommandEvent &)
void SpectrumPrefs::OnControl(wxCommandEvent&)
{
// Common routine for most controls
// If any per-track setting is changed, break the association with defaults
// Skip this, and View Settings... will be able to change defaults instead
// when the checkbox is on, as in the original design.
if (mDefaultsCheckbox && !mPopulating) {
mDefaulted = false;
mDefaultsCheckbox->SetValue(false);
}
}
void SpectrumPrefs::OnWindowSize(wxCommandEvent &evt)
{
// Restrict choice of zero padding, so that product of window
// size and padding may not exceed the largest window size.
wxChoice *const pWindowSizeControl =
static_cast<wxChoice*>(wxWindow::FindWindowById(ID_WINDOW_SIZE, this));
int windowSize = 1 << (pWindowSizeControl->GetSelection() + 3);
int windowSize = 1 <<
(pWindowSizeControl->GetSelection() + SpectrogramSettings::LogMinWindowSize);
PopulatePaddingChoices(windowSize);
// Do the common part
OnControl(evt);
}
void SpectrumPrefs::OnDefaults(wxCommandEvent &)
{
if (mDefaultsCheckbox->IsChecked()) {
mTempSettings = SpectrogramSettings::defaults();
mTempSettings.ConvertToEnumeratedWindowSizes();
mDefaulted = true;
ShuttleGui S(this, eIsSettingToDialog);
PopulateOrExchange(S);
}
}
void SpectrumPrefs::OnApply(wxCommandEvent &)
{
if (Validate()) {
Apply();
::GetActiveProject()->GetTrackPanel()->Refresh(false);
}
}
BEGIN_EVENT_TABLE(SpectrumPrefs, PrefsPanel)
EVT_CHOICE(ID_WINDOW_SIZE, SpectrumPrefs::OnWindowSize)
EVT_CHECKBOX(ID_DEFAULTS, SpectrumPrefs::OnDefaults)
// Several controls with common routine that unchecks the default box
EVT_CHOICE(ID_WINDOW_TYPE, SpectrumPrefs::OnControl)
EVT_CHOICE(ID_PADDING_SIZE, SpectrumPrefs::OnControl)
EVT_TEXT(ID_MINIMUM, SpectrumPrefs::OnControl)
EVT_TEXT(ID_MAXIMUM, SpectrumPrefs::OnControl)
EVT_TEXT(ID_GAIN, SpectrumPrefs::OnControl)
EVT_TEXT(ID_RANGE, SpectrumPrefs::OnControl)
EVT_TEXT(ID_FREQUENCY_GAIN, SpectrumPrefs::OnControl)
EVT_CHECKBOX(ID_GRAYSCALE, SpectrumPrefs::OnControl)
EVT_BUTTON(ID_APPLY, SpectrumPrefs::OnApply)
END_EVENT_TABLE()
SpectrumPrefsFactory::SpectrumPrefsFactory(WaveTrack *wt)
: mWt(wt)
{
}
PrefsPanel *SpectrumPrefsFactory::Create(wxWindow *parent)
{
return new SpectrumPrefs(parent);
return new SpectrumPrefs(parent, mWt);
}

View File

@ -30,14 +30,18 @@
#include "PrefsPanel.h"
#include "SpectrogramSettings.h"
class wxChoice;
class wxCheckBox;
class wxTextCtrl;
struct FFTParam;
class ShuttleGui;
class SpectrogramSettings;
class WaveTrack;
class SpectrumPrefs:public PrefsPanel
{
public:
SpectrumPrefs(wxWindow * parent);
SpectrumPrefs(wxWindow * parent, WaveTrack *wt);
virtual ~SpectrumPrefs();
virtual bool Apply();
virtual bool Validate();
@ -47,9 +51,15 @@ class SpectrumPrefs:public PrefsPanel
void PopulatePaddingChoices(int windowSize);
void PopulateOrExchange(ShuttleGui & S);
void OnControl(wxCommandEvent &event);
void OnWindowSize(wxCommandEvent &event);
void OnDefaults(wxCommandEvent&);
void OnApply(wxCommandEvent &);
DECLARE_EVENT_TABLE()
WaveTrack *const mWt;
bool mDefaulted;
wxTextCtrl *mMinFreq;
wxTextCtrl *mMaxFreq;
wxTextCtrl *mGain;
@ -57,28 +67,35 @@ class SpectrumPrefs:public PrefsPanel
wxTextCtrl *mFrequencyGain;
wxArrayString mSizeChoices;
wxArrayInt mSizeCodes;
#ifdef EXPERIMENTAL_ZERO_PADDED_SPECTROGRAMS
int mZeroPaddingChoice;
wxArrayString mZeroPaddingChoices;
wxArrayInt mZeroPaddingCodes;
#endif
wxArrayString mTypeChoices;
wxArrayInt mTypeCodes;
#ifdef EXPERIMENTAL_FIND_NOTES
wxTextCtrl *mFindNotesMinA;
wxTextCtrl *mFindNotesN;
#endif
wxCheckBox *mDefaultsCheckbox;
SpectrogramSettings mTempSettings;
bool mPopulating;
};
class SpectrumPrefsFactory : public PrefsPanelFactory
{
public:
explicit SpectrumPrefsFactory(WaveTrack *wt = 0);
virtual PrefsPanel *Create(wxWindow *parent);
private:
WaveTrack *const mWt;
};
#endif