1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-06-25 08:38:39 +02:00

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

Track control "View Settings..." makes alternative SpectrumPrefs accessible
  Apply button for Spectrograms Preferences and View Settings
  Checkbox for defaulting track spectrogram settings (not seen in Preferences)
  Static boxes distinguish the panel in Preferences from that in View Settings
  SpectrumPrefs takes SpectrogramSettings object as parameter, and...
This commit is contained in:
Paul Licameli 2015-06-20 23:12:43 -04:00
commit 5e1ac0a06d
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,7 +192,63 @@ void SpectrogramSettings::UpdatePrefs()
findNotesQuantize = (gPrefs->Read(wxT("/Spectrum/FindNotesQuantize"), 0L) != 0);
#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();
}
@ -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,32 +143,34 @@ void SpectrumPrefs::PopulatePaddingChoices(int windowSize)
void SpectrumPrefs::PopulateOrExchange(ShuttleGui & S)
{
mPopulating = true;
S.SetBorder(2);
// S.StartStatic(_("Track Settings"));
{
mDefaultsCheckbox = 0;
if (mWt) {
mDefaultsCheckbox = S.Id(ID_DEFAULTS).TieCheckBox(_("Defaults"), mDefaulted);
}
S.StartStatic(_("FFT Window"));
{
S.StartMultiColumn(2);
{
S.Id(ID_WINDOW_SIZE).TieChoice(_("Window &size:"),
wxT("/Spectrum/FFTSize"),
256,
mSizeChoices,
mSizeCodes);
mTempSettings.windowSize,
&mSizeChoices);
S.SetSizeHints(mSizeChoices);
S.TieChoice(_("Window &type:"),
wxT("/Spectrum/WindowType"),
3,
mTypeChoices,
mTypeCodes);
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);
mTempSettings.zeroPaddingFactor,
&mZeroPaddingChoices);
S.SetSizeHints(mZeroPaddingChoices);
#endif
}
@ -169,45 +183,38 @@ void SpectrumPrefs::PopulateOrExchange(ShuttleGui & S)
S.StartTwoColumn();
{
mMinFreq =
S.TieNumericTextBox(_("Mi&nimum Frequency (Hz):"),
wxT("/Spectrum/MinFreq"),
0,
S.Id(ID_MINIMUM).TieNumericTextBox(_("Mi&nimum Frequency (Hz):"),
mTempSettings.minFreq,
12);
mMaxFreq =
S.TieNumericTextBox(_("Ma&ximum Frequency (Hz):"),
wxT("/Spectrum/MaxFreq"),
8000,
S.Id(ID_MAXIMUM).TieNumericTextBox(_("Ma&ximum Frequency (Hz):"),
mTempSettings.maxFreq,
12);
mGain =
S.TieNumericTextBox(_("&Gain (dB):"),
wxT("/Spectrum/Gain"),
20,
S.Id(ID_GAIN).TieNumericTextBox(_("&Gain (dB):"),
mTempSettings.gain,
8);
mRange =
S.TieNumericTextBox(_("&Range (dB):"),
wxT("/Spectrum/Range"),
80,
S.Id(ID_RANGE).TieNumericTextBox(_("&Range (dB):"),
mTempSettings.range,
8);
mFrequencyGain =
S.TieNumericTextBox(_("Frequency g&ain (dB/dec):"),
wxT("/Spectrum/FrequencyGain"),
0,
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);
mTempSettings.fftYGrid);
#endif //EXPERIMENTAL_FFT_Y_GRID
}
S.EndStatic();
@ -220,85 +227,72 @@ void SpectrumPrefs::PopulateOrExchange(ShuttleGui & S)
{
mFindNotesMinA =
S.TieNumericTextBox(_("Minimum Amplitude (dB):"),
wxT("/Spectrum/FindNotesMinA"),
-30L,
mTempSettings.fftFindNotes,
8);
mFindNotesN =
S.TieNumericTextBox(_("Max. Number of Notes (1..128):"),
wxT("/Spectrum/FindNotesN"),
5L,
mTempSettings.findNotesMinA,
8);
}
S.EndTwoColumn();
S.TieCheckBox(_("&Find Notes"),
wxT("/Spectrum/FFTFindNotes"),
false);
mTempSettings.numberOfMaxima);
S.TieCheckBox(_("&Quantize Notes"),
wxT("/Spectrum/FindNotesQuantize"),
false);
mTempSettings.findNotesQuantize);
}
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