mirror of
https://github.com/cookiengineer/audacity
synced 2025-07-03 06:03:13 +02:00
Add "View Settings..." to track drop-down and Apply button to Spectrogram prefs
This commit is contained in:
commit
504d4b5331
@ -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"),
|
||||
|
@ -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);
|
||||
|
@ -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.);
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user