1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-07-31 16:09:28 +02:00

Just one view type for Spectrum...

... Instead preferences or View Settings controls scale type and spectral
selection enablement
This commit is contained in:
Paul Licameli 2015-07-27 22:52:55 -04:00
commit 6b9cbbe50a
14 changed files with 304 additions and 186 deletions

View File

@ -93,6 +93,7 @@ It handles initialization and termination by subclassing wxApp.
#include "commands/Keyboard.h"
#include "widgets/ErrorDialog.h"
#include "prefs/DirectoriesPrefs.h"
#include "prefs/SpectrogramSettings.h"
//temporarilly commented out till it is added to all projects
//#include "Profiler.h"
@ -1011,7 +1012,11 @@ void AudacityApp::InitLang( const wxString & lang )
//
// This must go _after_ creating the wxLocale instance because
// creating the wxLocale instance sets the application-wide locale.
Internat::Init();
// Some static arrays unconnected with any project want to be informed of language changes.
SpectrogramSettings::InvalidateNames();
}
void AudacityApp::OnFatalException()

View File

@ -4765,12 +4765,7 @@ void AudacityProject::DoNextPeakFrequency(bool up)
for (Track *t = iter.First(); t; t = iter.Next()) {
WaveTrack *const wt = static_cast<WaveTrack*>(t);
const int display = wt->GetDisplay();
if (display == WaveTrack::SpectrumDisplay ||
display == WaveTrack::SpectrumLogDisplay ||
display == WaveTrack::SpectralSelectionDisplay ||
display == WaveTrack::SpectralSelectionLogDisplay
) {
if (display == WaveTrack::Spectrum) {
pTrack = wt;
break;
}

View File

@ -464,10 +464,7 @@ void TrackArtist::DrawTrack(const Track * t,
DrawWaveform(wt, dc, rect, selectedRegion, zoomInfo,
drawEnvelope, bigPoints, drawSliders, true, muted);
break;
case WaveTrack::SpectrumDisplay:
case WaveTrack::SpectrumLogDisplay:
case WaveTrack::SpectralSelectionDisplay:
case WaveTrack::SpectralSelectionLogDisplay:
case WaveTrack::Spectrum:
case WaveTrack::PitchDisplay:
DrawSpectrum(wt, dc, rect, selectedRegion, zoomInfo);
break;
@ -793,66 +790,71 @@ void TrackArtist::UpdateVRuler(Track *t, wxRect & rect)
vruler->SetLabelEdges(true);
vruler->SetLog(false);
}
else if (
(display == WaveTrack::SpectrumDisplay) ||
(display == WaveTrack::SpectralSelectionDisplay) )
{
// Spectrum
else if (display == WaveTrack::Spectrum) {
switch (wt->GetSpectrogramSettings().scaleType) {
default:
wxASSERT(false);
case SpectrogramSettings::stLinear:
{
// Spectrum
if (rect.height < 60)
return;
if (rect.height < 60)
return;
const SpectrogramSettings &settings = wt->GetSpectrogramSettings();
const double rate = wt->GetRate();
const int maxFreq = settings.GetMaxFreq(rate);
const int minFreq = settings.GetMinFreq(rate);
const SpectrogramSettings &settings = wt->GetSpectrogramSettings();
const double rate = wt->GetRate();
const int maxFreq = settings.GetMaxFreq(rate);
const int minFreq = settings.GetMinFreq(rate);
/*
/*
draw the ruler
we will use Hz if maxFreq is < 2000, otherwise we represent kHz,
and append to the numbers a "k"
*/
vruler->SetBounds(rect.x, rect.y+1, rect.x + rect.width, rect.y + rect.height-1);
vruler->SetOrientation(wxVERTICAL);
vruler->SetFormat(Ruler::RealFormat);
vruler->SetLabelEdges(true);
// use kHz in scale, if appropriate
if (maxFreq>=2000) {
vruler->SetRange((maxFreq/1000.), (minFreq/1000.));
vruler->SetUnits(wxT("k"));
} else {
// use Hz
vruler->SetRange(int(maxFreq), int(minFreq));
vruler->SetUnits(wxT(""));
*/
vruler->SetBounds(rect.x, rect.y + 1, rect.x + rect.width, rect.y + rect.height - 1);
vruler->SetOrientation(wxVERTICAL);
vruler->SetFormat(Ruler::RealFormat);
vruler->SetLabelEdges(true);
// use kHz in scale, if appropriate
if (maxFreq >= 2000) {
vruler->SetRange((maxFreq / 1000.), (minFreq / 1000.));
vruler->SetUnits(wxT("k"));
}
else {
// use Hz
vruler->SetRange(int(maxFreq), int(minFreq));
vruler->SetUnits(wxT(""));
}
vruler->SetLog(false);
}
vruler->SetLog(false);
}
else if (
(display == WaveTrack::SpectrumLogDisplay) ||
(display == WaveTrack::SpectralSelectionLogDisplay) )
{
// SpectrumLog
break;
case SpectrogramSettings::stLogarithmic:
{
// SpectrumLog
if (rect.height < 10)
return;
if (rect.height < 10)
return;
const SpectrogramSettings &settings = wt->GetSpectrogramSettings();
const double rate = wt->GetRate();
const int maxFreq = settings.GetLogMaxFreq(rate);
const int minFreq = settings.GetLogMinFreq(rate);
const SpectrogramSettings &settings = wt->GetSpectrogramSettings();
const double rate = wt->GetRate();
const int maxFreq = settings.GetLogMaxFreq(rate);
const int minFreq = settings.GetLogMinFreq(rate);
/*
/*
draw the ruler
we will use Hz if maxFreq is < 2000, otherwise we represent kHz,
and append to the numbers a "k"
*/
vruler->SetBounds(rect.x, rect.y+1, rect.x + rect.width, rect.y + rect.height-1);
vruler->SetOrientation(wxVERTICAL);
vruler->SetFormat(Ruler::IntFormat);
vruler->SetLabelEdges(true);
vruler->SetRange(maxFreq, minFreq);
vruler->SetUnits(wxT(""));
vruler->SetLog(true);
*/
vruler->SetBounds(rect.x, rect.y + 1, rect.x + rect.width, rect.y + rect.height - 1);
vruler->SetOrientation(wxVERTICAL);
vruler->SetFormat(Ruler::IntFormat);
vruler->SetLabelEdges(true);
vruler->SetRange(maxFreq, minFreq);
vruler->SetUnits(wxT(""));
vruler->SetLog(true);
}
break;
}
}
else if (display == WaveTrack::PitchDisplay) {
// Pitch
@ -2034,8 +2036,8 @@ void TrackArtist::DrawClipSpectrum(WaveTrackCache &waveTrackCache,
const int display = track->GetDisplay();
const bool autocorrelation = (WaveTrack::PitchDisplay == display);
const bool logF = (WaveTrack::SpectrumLogDisplay == display
|| WaveTrack::SpectralSelectionLogDisplay == display);
const bool logF = settings.scaleType == SpectrogramSettings::stLogarithmic;
enum { DASH_LENGTH = 10 /* pixels */ };
const ClipParameters params(true, track, clip, rect, selectedRegion, zoomInfo);
@ -2104,8 +2106,14 @@ void TrackArtist::DrawClipSpectrum(WaveTrackCache &waveTrackCache,
t0, pps, autocorrelation);
}
const int minFreq = logF ? settings.GetLogMinFreq(rate) : settings.GetMinFreq(rate);
const int maxFreq = logF ? settings.GetLogMaxFreq(rate) : settings.GetMaxFreq(rate);
// Legacy special-case treatment of log scale
const SpectrogramSettings::ScaleType scaleType = settings.scaleType;
const int minFreq =
scaleType == SpectrogramSettings::stLinear
? settings.GetMinFreq(rate) : settings.GetLogMinFreq(rate);
const int maxFreq =
scaleType == SpectrogramSettings::stLinear
? settings.GetMaxFreq(rate) : settings.GetLogMaxFreq(rate);
float minBin = ((double)minFreq / binUnit);
float maxBin = ((double)maxFreq / binUnit);
@ -2140,7 +2148,8 @@ void TrackArtist::DrawClipSpectrum(WaveTrackCache &waveTrackCache,
#endif //EXPERIMENTAL_FFT_Y_GRID
if (!updated && clip->mSpecPxCache->valid &&
(clip->mSpecPxCache->len == hiddenMid.height * hiddenMid.width)
(clip->mSpecPxCache->len == hiddenMid.height * hiddenMid.width)
&& scaleType == clip->mSpecPxCache->scaleType
&& gain == clip->mSpecPxCache->gain
&& range == clip->mSpecPxCache->range
&& minFreq == clip->mSpecPxCache->minFreq
@ -2163,6 +2172,7 @@ void TrackArtist::DrawClipSpectrum(WaveTrackCache &waveTrackCache,
delete clip->mSpecPxCache;
clip->mSpecPxCache = new SpecPxCache(hiddenMid.width * hiddenMid.height);
clip->mSpecPxCache->valid = true;
clip->mSpecPxCache->scaleType = scaleType;
clip->mSpecPxCache->gain = gain;
clip->mSpecPxCache->range = range;
clip->mSpecPxCache->minFreq = minFreq;
@ -2334,6 +2344,7 @@ void TrackArtist::DrawClipSpectrum(WaveTrackCache &waveTrackCache,
(zoomInfo.PositionToTime(0, -leftOffset) - tOffset)
);
const bool isSpectral = settings.SpectralSelectionEnabled();
const bool hidden = (ZoomInfo::HIDDEN == zoomInfo.GetFisheyeState());
const int begin = hidden
? 0
@ -2389,12 +2400,8 @@ void TrackArtist::DrawClipSpectrum(WaveTrackCache &waveTrackCache,
AColor::ColorGradientUnselected;
// If we are in the time selected range, then we may use a different color set.
if (ssel0 <= w0 && w1 < ssel1)
{
bool isSpectral = ((track->GetDisplay() == WaveTrack::SpectralSelectionDisplay) ||
(track->GetDisplay() == WaveTrack::SpectralSelectionLogDisplay));
selected = ChooseColorSet(bin0, bin1, selBinLo, selBinCenter, selBinHi,
(xx + leftOffset - hiddenLeftOffset) / DASH_LENGTH, isSpectral);
}
unsigned char rv, gv, bv;
const float value = uncached
@ -2429,13 +2436,9 @@ void TrackArtist::DrawClipSpectrum(WaveTrackCache &waveTrackCache,
AColor::ColorGradientChoice selected = AColor::ColorGradientUnselected;
// If we are in the time selected range, then we may use a different color set.
if (ssel0 <= w0 && w1 < ssel1)
{
bool isSpectral = ((track->GetDisplay() == WaveTrack::SpectralSelectionDisplay) ||
(track->GetDisplay() == WaveTrack::SpectralSelectionLogDisplay));
selected = ChooseColorSet(
bin0, bin1, selBinLo, selBinCenter, selBinHi,
(xx + leftOffset - hiddenLeftOffset) / DASH_LENGTH, isSpectral);
}
unsigned char rv, gv, bv;
const float value = uncached
@ -2475,23 +2478,6 @@ void TrackArtist::DrawClipSpectrum(WaveTrackCache &waveTrackCache,
#endif //EXPERIMENTAL_FFT_Y_GRID
}
void TrackArtist::InvalidateSpectrumCache(TrackList *tracks)
{
TrackListOfKindIterator iter(Track::Wave, tracks);
for (Track *t = iter.First(); t; t = iter.Next()) {
InvalidateSpectrumCache((WaveTrack *)t);
}
}
void TrackArtist::InvalidateSpectrumCache(WaveTrack *track)
{
WaveClipList::compatibility_iterator it;
for (it = track->GetClipIterator(); it; it = it->GetNext()) {
it->GetData()->mSpecPxCache->valid = false;
}
}
#ifdef USE_MIDI
/*
Note: recall that Allegro attributes end in a type identifying letter.

View File

@ -71,9 +71,6 @@ class AUDACITY_DLL_API TrackArtist {
void UpdatePrefs();
void InvalidateSpectrumCache(TrackList *tracks);
void InvalidateSpectrumCache(WaveTrack *track);
void SetBackgroundBrushes(wxBrush unselectedBrush, wxBrush selectedBrush,
wxPen unselectedPen, wxPen selectedPen) {
this->unselectedBrush = unselectedBrush;

View File

@ -327,9 +327,6 @@ enum {
OnWaveformID,
OnWaveformDBID,
OnSpectrumID,
OnSpectrumLogID,
OnSpectralSelID,
OnSpectralSelLogID,
OnPitchID,
OnViewSettingsID,
@ -727,13 +724,7 @@ void TrackPanel::BuildMenus(void)
BuildCommonDropMenuItems(mWaveTrackMenu); // does name, up/down etc
mWaveTrackMenu->Append(OnWaveformID, _("Wa&veform"));
mWaveTrackMenu->Append(OnWaveformDBID, _("&Waveform (dB)"));
mWaveTrackMenu->Append(OnSpectrumID, _("&Spectrogram"));
/* i18n-hint: short form of 'logarithm'*/
mWaveTrackMenu->Append(OnSpectrumLogID, _("Spectrogram l&og(f)"));
/* i18n-hint: Spectral Selection is spectrogram with ability to select frequencies too'*/
mWaveTrackMenu->Append(OnSpectralSelID, _("S&pectral Selection"));
/* i18n-hint: short form of 'logarithm'*/
mWaveTrackMenu->Append(OnSpectralSelLogID, _("Spectral Selection lo&g(f)"));
mWaveTrackMenu->Append(OnSpectrumID, _("&Spectrum"));
mWaveTrackMenu->Append(OnPitchID, _("Pitc&h (EAC)"));
mWaveTrackMenu->Append(OnViewSettingsID, _("View& Settings...")); // PRL: all the other letters already taken for accelerators!
mWaveTrackMenu->AppendSeparator();
@ -1811,16 +1802,18 @@ void TrackPanel::SetCursorAndTipWhenInLabelTrack( LabelTrack * pLT,
namespace {
// This returns true if we're a spectral editing track.
inline bool isSpectrogramTrack(const Track *pTrack, bool *pLogf = NULL) {
inline bool isSpectralSelectionTrack(const Track *pTrack, bool *pLogf = NULL) {
if (pTrack &&
pTrack->GetKind() == Track::Wave) {
const int display =
static_cast<const WaveTrack*>(pTrack)->GetDisplay();
const bool logF = (display == WaveTrack::SpectrumLogDisplay) ||
(display == WaveTrack::SpectralSelectionLogDisplay);
if (pLogf)
const WaveTrack *const wt = static_cast<const WaveTrack*>(pTrack);
const SpectrogramSettings &settings = wt->GetSpectrogramSettings();
const int display = wt->GetDisplay();
if (pLogf) {
const bool logF =
settings.scaleType == SpectrogramSettings::stLogarithmic;
*pLogf = logF;
return (display == WaveTrack::SpectralSelectionLogDisplay) || (display == WaveTrack::SpectralSelectionDisplay);
}
return (display == WaveTrack::Spectrum) && settings.SpectralSelectionEnabled();
}
else {
if (pLogf)
@ -1950,7 +1943,7 @@ void TrackPanel::SetCursorAndTipWhenSelectTool( Track * t,
#ifdef EXPERIMENTAL_SPECTRAL_EDITING
bool logF;
if ( (mFreqSelMode == FREQ_SEL_SNAPPING_CENTER) &&
isSpectrogramTrack(t, &logF) ) {
isSpectralSelectionTrack(t, &logF)) {
// Not shift-down, but center frequency snapping toggle is on
*ppTip = _("Click and drag to set frequency bandwidth.");
*ppCursor = mEnvelopeCursor;
@ -2688,7 +2681,7 @@ void TrackPanel::SelectionHandleClick(wxMouseEvent & event,
#ifdef EXPERIMENTAL_SPECTRAL_EDITING
bool logF;
if (mFreqSelMode == FREQ_SEL_SNAPPING_CENTER &&
isSpectrogramTrack(pTrack, &logF)) {
isSpectralSelectionTrack(pTrack, &logF)) {
// Ignore whether we are inside the time selection.
// Exit center-snapping, start dragging the width.
mFreqSelMode = FREQ_SEL_PINNED_CENTER;
@ -3082,7 +3075,7 @@ void TrackPanel::MoveSnappingFreqSelection (int mouseYCoordinate,
bool logF;
if (pTrack &&
pTrack->GetSelected() &&
isSpectrogramTrack(pTrack, &logF)) {
isSpectralSelectionTrack(pTrack, &logF)) {
WaveTrack *const wt = static_cast<WaveTrack*>(pTrack);
// PRL:
// What happens if center snapping selection began in one spectrogram track,
@ -3126,7 +3119,7 @@ void TrackPanel::StartFreqSelection (int mouseYCoordinate, int trackTopEdge,
mFreqSelPin = SelectedRegion::UndefinedFrequency;
bool logF;
if (isSpectrogramTrack(pTrack, &logF)) {
if (isSpectralSelectionTrack(pTrack, &logF)) {
mFreqSelTrack = static_cast<WaveTrack*>(pTrack);
mFreqSelMode = FREQ_SEL_FREE;
mFreqSelPin =
@ -3150,10 +3143,8 @@ void TrackPanel::ExtendFreqSelection(int mouseYCoordinate, int trackTopEdge,
// started, and that is of a spectrogram display type.
const WaveTrack* wt = mFreqSelTrack;
const int display = wt->GetDisplay();
const bool logF = (display == WaveTrack::SpectrumLogDisplay) ||
(display == WaveTrack::SpectralSelectionLogDisplay)
;
const bool logF =
wt->GetSpectrogramSettings().scaleType == SpectrogramSettings::stLogarithmic;
const double rate = wt->GetRate();
const double frequency =
PositionToFrequency(wt, true, mouseYCoordinate,
@ -3685,7 +3676,7 @@ bool mayDragWidth, bool onlyWithinSnapDistance,
// within the time boundaries
if (!mViewInfo->selectedRegion.isPoint() &&
t0 <= selend && selend < t1 &&
isSpectrogramTrack(pTrack, &logF)) {
isSpectralSelectionTrack(pTrack, &logF)) {
const WaveTrack *const wt = static_cast<const WaveTrack*>(pTrack);
const wxInt64 bottomSel = (f0 >= 0)
? FrequencyToPosition(wt, f0, rect.y, rect.height, logF)
@ -4694,11 +4685,12 @@ void TrackPanel::HandleVZoomButtonUp( wxMouseEvent & event )
float min, max, c, l, binSize = 0.0;
const double rate = track->GetRate();
const bool spectrum = (track->GetDisplay() == WaveTrack::SpectrumDisplay) ||
(track->GetDisplay() == WaveTrack::SpectralSelectionDisplay);
const bool spectrumLog = (track->GetDisplay() == WaveTrack::SpectrumLogDisplay) ||
(track->GetDisplay() == WaveTrack::SpectralSelectionLogDisplay);
if(spectrum) {
const bool spectral = (track->GetDisplay() == WaveTrack::Spectrum);
const bool spectrumLinear = spectral &&
(track->GetSpectrogramSettings().scaleType == SpectrogramSettings::stLinear);
const bool spectrumLog = spectral &&
(track->GetSpectrogramSettings().scaleType == SpectrogramSettings::stLogarithmic);
if (spectrumLinear) {
const SpectrogramSettings &settings = track->GetSpectrogramSettings();
min = settings.GetMinFreq(rate);
max = settings.GetMaxFreq(rate);
@ -4706,17 +4698,16 @@ void TrackPanel::HandleVZoomButtonUp( wxMouseEvent & event )
binSize = rate / fftLength;
minBins = std::min(10, fftLength / 2); //minimum 10 freq bins, unless there are less
}
else if (spectrumLog) {
const SpectrogramSettings &settings = track->GetSpectrogramSettings();
min = settings.GetLogMinFreq(rate);
max = settings.GetLogMaxFreq(rate);
const int fftLength = settings.GetFFTLength(false);
binSize = rate / fftLength;
minBins = std::min(10, fftLength / 2); //minimum 10 freq bins, unless there are less
}
else
if(spectrumLog) {
const SpectrogramSettings &settings = track->GetSpectrogramSettings();
min = settings.GetLogMinFreq(rate);
max = settings.GetLogMaxFreq(rate);
const int fftLength = settings.GetFFTLength(false);
binSize = rate / fftLength;
minBins = std::min(10, fftLength / 2); //minimum 10 freq bins, unless there are less
}
else
track->GetDisplayBounds(&min, &max);
track->GetDisplayBounds(&min, &max);
if (IsDragZooming()) {
// Drag Zoom
float p1, p2, tmin, tmax;
@ -4746,7 +4737,7 @@ void TrackPanel::HandleVZoomButtonUp( wxMouseEvent & event )
min = (tmax * (1.0-p2) + tmin * p2);
// Enforce vertical zoom limits
if(spectrum) {
if(spectrumLinear) {
if(min < 0.)
min = 0.;
if(max < min + minBins * binSize)
@ -4771,7 +4762,7 @@ void TrackPanel::HandleVZoomButtonUp( wxMouseEvent & event )
// Zoom out to -1.0...1.0 first, then, and only
// then, if they click again, allow one more
// zoom out.
if(spectrum) {
if (spectrumLinear) {
if (event.ShiftDown() && event.RightUp()) {
// Zoom out full
min = 0.0;
@ -4840,7 +4831,7 @@ void TrackPanel::HandleVZoomButtonUp( wxMouseEvent & event )
else {
// Zoom IN
float p1;
if(spectrum) {
if (spectrumLinear) {
c = 0.5*(min+max);
// Enforce maximum vertical zoom
l = std::max( minBins * binSize, (c - min));
@ -4889,7 +4880,7 @@ void TrackPanel::HandleVZoomButtonUp( wxMouseEvent & event )
}
}
if(spectrum) {
if (spectrumLinear) {
SpectrogramSettings &settings = track->GetSpectrogramSettings();
settings.SetMinFreq(min);
settings.SetMaxFreq(max);
@ -4899,7 +4890,6 @@ void TrackPanel::HandleVZoomButtonUp( wxMouseEvent & event )
settings.SetMinFreq(min);
settings.SetMaxFreq(max);
}
mTrackArtist->InvalidateSpectrumCache(mTracks);
}
else if(spectrumLog) {
SpectrogramSettings &settings = track->GetSpectrogramSettings();
@ -4911,7 +4901,6 @@ void TrackPanel::HandleVZoomButtonUp( wxMouseEvent & event )
settings.SetLogMinFreq(min);
settings.SetLogMaxFreq(max);
}
mTrackArtist->InvalidateSpectrumCache(mTracks);
}
else {
track->SetDisplayBounds(min, max);
@ -8568,10 +8557,7 @@ void TrackPanel::OnTrackMenu(Track *t)
theMenu->Enable(OnWaveformID, display != WaveTrack::WaveformDisplay);
theMenu->Enable(OnWaveformDBID,
display != WaveTrack::WaveformDBDisplay);
theMenu->Enable(OnSpectrumID, display != WaveTrack::SpectrumDisplay);
theMenu->Enable(OnSpectrumLogID, display != WaveTrack::SpectrumLogDisplay);
theMenu->Enable(OnSpectralSelID, display != WaveTrack::SpectralSelectionDisplay);
theMenu->Enable(OnSpectralSelLogID, display != WaveTrack::SpectralSelectionLogDisplay);
theMenu->Enable(OnSpectrumID, display != WaveTrack::Spectrum);
theMenu->Enable(OnPitchID, display != WaveTrack::PitchDisplay);
theMenu->Enable(OnViewSettingsID, true);
@ -9087,26 +9073,17 @@ void TrackPanel::OnSetDisplay(wxCommandEvent & event)
case OnWaveformDBID:
id = WaveTrack::WaveformDBDisplay; break;
case OnSpectrumID:
id = WaveTrack::SpectrumDisplay; break;
case OnSpectrumLogID:
id = WaveTrack::SpectrumLogDisplay; break;
case OnSpectralSelID:
id = WaveTrack::SpectralSelectionDisplay; break;
case OnSpectralSelLogID:
id = WaveTrack::SpectralSelectionLogDisplay; break;
id = WaveTrack::Spectrum; break;
case OnPitchID:
id = WaveTrack::PitchDisplay; break;
}
WaveTrack *wt = (WaveTrack *) mPopupMenuTarget;
if (wt->GetDisplay() != id) {
wt->SetDisplay(WaveTrack::WaveTrackDisplay(id));
mTrackArtist->InvalidateSpectrumCache(wt);
WaveTrack *l = (WaveTrack *) wt->GetLink();
if (l) {
WaveTrack *l = static_cast<WaveTrack *>(wt->GetLink());
if (l)
l->SetDisplay(WaveTrack::WaveTrackDisplay(id));
mTrackArtist->InvalidateSpectrumCache(l);
}
#ifdef EXPERIMENTAL_OUTPUT_DISPLAY
if (wt->GetDisplay() == WaveTrack::WaveformDisplay) {
wt->SetVirtualState(false);

View File

@ -127,6 +127,7 @@ public:
len = cacheLen;
values = new float[len];
valid = false;
scaleType = 0;
range = gain = -1;
minFreq = maxFreq = -1;
}
@ -140,6 +141,7 @@ public:
float *values;
bool valid;
int scaleType;
int range;
int gain;
int minFreq;

View File

@ -235,9 +235,12 @@ WaveTrack::ConvertLegacyDisplayValue(int oldValue)
case WaveformDB:
newValue = WaveTrack::WaveformDBDisplay; break;
case Spectrogram:
newValue = WaveTrack::SpectrumDisplay; break;
case SpectrogramLogF:
newValue = WaveTrack::Spectrum; break;
/*
case SpectrogramLogF:
newValue = WaveTrack::SpectrumLogDisplay; break;
*/
case Pitch:
newValue = WaveTrack::PitchDisplay; break;
}
@ -248,11 +251,24 @@ WaveTrack::ConvertLegacyDisplayValue(int oldValue)
WaveTrack::WaveTrackDisplay
WaveTrack::ValidateWaveTrackDisplay(WaveTrackDisplay display)
{
// To do, in future: detect obsolete values between min and max
if (display >= int(MinDisplay) && display <= int(MaxDisplay))
switch (display) {
// non-obsolete codes
case WaveformDisplay:
case WaveformDBDisplay:
case Spectrum:
case PitchDisplay:
return display;
else
// obsolete codes
case obsolete1: // was SpectrumLogDisplay
case obsolete2: // was SpectralSelectionDisplay
case obsolete3: // was SpectralSelectionLogDisplay
return Spectrum;
// codes out of bounds (from future prefs files?)
default:
return MinDisplay;
}
}
void WaveTrack::GetDisplayBounds(float *min, float *max)

View File

@ -418,10 +418,12 @@ class AUDACITY_DLL_API WaveTrack: public Track {
MinDisplay = WaveformDisplay,
WaveformDBDisplay,
SpectrumDisplay,
SpectrumLogDisplay,
SpectralSelectionDisplay,
SpectralSelectionLogDisplay,
Spectrum,
obsolete1, // was SpectrumLogDisplay
obsolete2, // was SpectralSelectionDisplay
obsolete3, // was SpectralSelectionLogDisplay
PitchDisplay,
// Add values here, and update MaxDisplay.
@ -441,14 +443,10 @@ class AUDACITY_DLL_API WaveTrack: public Track {
static WaveTrackDisplay ValidateWaveTrackDisplay(WaveTrackDisplay display);
void SetDisplay(WaveTrackDisplay display) {
if(mDisplay < 2)
if (mDisplay < Spectrum)
// remember last display mode for wave and wavedb so they can remap the vertical ruler
mLastDisplay = mDisplay;
mDisplay = display;
if( mDisplay == SpectralSelectionDisplay ){
}
if( mDisplay == SpectralSelectionLogDisplay ){
}
}
WaveTrackDisplay GetDisplay() const { return mDisplay; }
int GetLastDisplay() {return mLastDisplay;}

View File

@ -45,6 +45,7 @@ effects from this one class.
#include "../../FileNames.h"
#include "../../Internat.h"
#include "../../LabelTrack.h"
#include "../../prefs/SpectrogramSettings.h"
#include "../../Project.h"
#include "../../ShuttleGui.h"
#include "../../WaveClip.h"
@ -603,8 +604,8 @@ bool NyquistEffect::Process()
const WaveTrack::WaveTrackDisplay display = mCurTrack[0]->GetDisplay();
const bool bAllowSpectralEditing =
(display == WaveTrack::SpectralSelectionDisplay) ||
(display == WaveTrack::SpectralSelectionLogDisplay);
(display == WaveTrack::Spectrum) &&
mCurTrack[0]->GetSpectrogramSettings().SpectralSelectionEnabled();
if (bAllowSpectralEditing) {
#if defined(EXPERIMENTAL_SPECTRAL_EDITING)
@ -790,10 +791,7 @@ bool NyquistEffect::ProcessOne()
{
case WaveTrack::WaveformDisplay: view = wxT("\"Waveform\""); break;
case WaveTrack::WaveformDBDisplay: view = wxT("\"Waveform (dB)\""); break;
case WaveTrack::SpectrumDisplay: view = wxT("\"Spectrogram\""); break;
case WaveTrack::SpectrumLogDisplay: view = wxT("\"Spectrogram log(f)\""); break;
case WaveTrack::SpectralSelectionDisplay: view = wxT("\"Spectral Selection\""); break;
case WaveTrack::SpectralSelectionLogDisplay: view = wxT("\"Spectral Selection log(f)\""); break;
case WaveTrack::Spectrum: view = wxT("\"Spectrum\""); break;
case WaveTrack::PitchDisplay: view = wxT("\"Pitch (EAC)\""); break;
default: view = wxT("NIL"); break;
}

View File

@ -26,6 +26,33 @@ Paul Licameli
#include <algorithm>
#include <cmath>
SpectrogramSettings::Globals::Globals()
{
LoadPrefs();
}
void SpectrogramSettings::Globals::SavePrefs()
{
#ifdef SPECTRAL_SELECTION_GLOBAL_SWITCH
gPrefs->Write(wxT("/Spectrum/EnableSpectralSelection"), spectralSelection);
#endif
}
void SpectrogramSettings::Globals::LoadPrefs()
{
#ifdef SPECTRAL_SELECTION_GLOBAL_SWITCH
spectralSelection
= (gPrefs->Read(wxT("/Spectrum/EnableSpectralSelection"), 0L) != 0);
#endif
}
SpectrogramSettings::Globals
&SpectrogramSettings::Globals::Get()
{
static Globals instance;
return instance;
}
SpectrogramSettings::SpectrogramSettings()
: hFFT(0)
, window(0)
@ -47,6 +74,10 @@ SpectrogramSettings::SpectrogramSettings(const SpectrogramSettings &other)
, zeroPaddingFactor(other.zeroPaddingFactor)
#endif
, isGrayscale(other.isGrayscale)
, scaleType(other.scaleType)
#ifndef SPECTRAL_SELECTION_GLOBAL_SWITCH
, spectralSelection(other.spectralSelection)
#endif
#ifdef EXPERIMENTAL_FFT_Y_GRID
, fftYGrid(other.fftYGrid)
#endif
@ -79,6 +110,10 @@ SpectrogramSettings &SpectrogramSettings::operator= (const SpectrogramSettings &
zeroPaddingFactor = other.zeroPaddingFactor;
#endif
isGrayscale = other.isGrayscale;
scaleType = other.scaleType;
#ifndef SPECTRAL_SELECTION_GLOBAL_SWITCH
spectralSelection = other.spectralSelection;
#endif
#ifdef EXPERIMENTAL_FFT_Y_GRID
fftYGrid = other.fftYGrid;
#endif
@ -102,6 +137,35 @@ SpectrogramSettings& SpectrogramSettings::defaults()
return instance;
}
namespace
{
wxArrayString &scaleNamesArray()
{
static wxArrayString theArray;
return theArray;
}
}
//static
void SpectrogramSettings::InvalidateNames()
{
scaleNamesArray().Clear();
}
//static
const wxArrayString &SpectrogramSettings::GetScaleNames()
{
wxArrayString &theArray = scaleNamesArray();
if (theArray.IsEmpty()) {
// Keep in correspondence with enum SpectrogramSettings::ScaleType:
theArray.Add(_("Linear"));
theArray.Add(_("Logarithmic"));
}
return theArray;
}
bool SpectrogramSettings::Validate(bool quiet)
{
if (!quiet &&
@ -155,6 +219,10 @@ bool SpectrogramSettings::Validate(bool quiet)
// preference files, which could be or from future versions. Validate quietly.
windowType =
std::max(0, std::min(NumWindowFuncs() - 1, windowType));
scaleType =
ScaleType(std::max(0,
std::min(int(SpectrogramSettings::stNumScaleTypes) - 1,
int(scaleType))));
ConvertToEnumeratedWindowSizes();
ConvertToActualWindowSizes();
@ -181,6 +249,12 @@ void SpectrogramSettings::LoadPrefs()
isGrayscale = (gPrefs->Read(wxT("/Spectrum/Grayscale"), 0L) != 0);
scaleType = ScaleType(gPrefs->Read(wxT("/Spectrum/ScaleType"), 0L));
#ifndef SPECTRAL_SELECTION_GLOBAL_SWITCH
spectralSelection = (gPrefs->Read(wxT("/Spectrum/EnableSpectralSelection"), 0L) != 0);
#endif
#ifdef EXPERIMENTAL_FFT_Y_GRID
fftYGrid = (gPrefs->Read(wxT("/Spectrum/FFTYGrid"), 0L) != 0);
#endif //EXPERIMENTAL_FFT_Y_GRID
@ -235,6 +309,12 @@ void SpectrogramSettings::SavePrefs()
gPrefs->Write(wxT("/Spectrum/Grayscale"), isGrayscale);
gPrefs->Write(wxT("/Spectrum/ScaleType"), scaleType);
#ifndef SPECTRAL_SELECTION_GLOBAL_SWITCH
gPrefs->Write(wxT("/Spectrum/EnableSpectralSelection"), spectralSelection);
#endif
#ifdef EXPERIMENTAL_FFT_Y_GRID
gPrefs->Write(wxT("/Spectrum/FFTYGrid"), fftYGrid);
#endif //EXPERIMENTAL_FFT_Y_GRID
@ -443,3 +523,12 @@ int SpectrogramSettings::GetFFTLength(bool autocorrelation) const
#endif
;
}
bool SpectrogramSettings::SpectralSelectionEnabled() const
{
#ifdef SPECTRAL_SELECTION_GLOBAL_SWITCH
return Globals::Get().spectralSelection;
#else
return spectralSelection;
#endif
}

View File

@ -13,14 +13,33 @@ Paul Licameli
#include "../Experimental.h"
#undef SPECTRAL_SELECTION_GLOBAL_SWITCH
struct FFTParam;
class SpectrumPrefs;
class wxArrayString;
class SpectrogramSettings
{
friend class SpectrumPrefs;
public:
// Singleton for settings that are not per-track
class Globals
{
public:
static Globals &Get();
void SavePrefs();
#ifdef SPECTRAL_SELECTION_GLOBAL_SWITCH
bool spectralSelection;
#endif
private:
Globals();
void LoadPrefs();
};
enum {
LogMinWindowSize = 3,
LogMaxWindowSize = 15,
@ -28,6 +47,19 @@ public:
NumWindowSizes = LogMaxWindowSize - LogMinWindowSize + 1,
};
// Do not assume that this enumeration will remain the
// same as NumberScaleType in future. That enum may become
// more general purpose.
enum ScaleType {
stLinear,
stLogarithmic,
stNumScaleTypes,
};
static void InvalidateNames(); // in case of language change
static const wxArrayString &GetScaleNames();
static SpectrogramSettings &defaults();
SpectrogramSettings();
SpectrogramSettings(const SpectrogramSettings &other);
@ -58,6 +90,7 @@ public:
int GetMaxFreq(double rate) const;
int GetLogMinFreq(double rate) const;
int GetLogMaxFreq(double rate) const;
bool SpectralSelectionEnabled() const;
void SetMinFreq(int freq);
void SetMaxFreq(int freq);
@ -79,6 +112,12 @@ public:
bool isGrayscale;
ScaleType scaleType;
#ifndef SPECTRAL_SELECTION_GLOBAL_SWITCH
bool spectralSelection; // But should this vary per track? -- PRL
#endif
#ifdef EXPERIMENTAL_FFT_Y_GRID
bool fftYGrid;
#endif //EXPERIMENTAL_FFT_Y_GRID
@ -98,5 +137,4 @@ public:
mutable float *window;
#endif
};
#endif

View File

@ -59,12 +59,14 @@ enum {
#ifdef EXPERIMENTAL_ZERO_PADDED_SPECTROGRAMS
ID_WINDOW_TYPE,
ID_PADDING_SIZE,
ID_SCALE,
ID_MINIMUM,
ID_MAXIMUM,
ID_GAIN,
ID_RANGE,
ID_FREQUENCY_GAIN,
ID_GRAYSCALE,
ID_SPECTRAL_SELECTION,
#endif
ID_DEFAULTS,
ID_APPLY,
@ -93,6 +95,7 @@ void SpectrumPrefs::Populate(int windowSize)
mTypeChoices.Add(WindowFuncName(i));
}
mScaleChoices = SpectrogramSettings::GetScaleNames();
//------------------------- Main section --------------------
// Now construct the GUI itself.
@ -182,6 +185,10 @@ void SpectrumPrefs::PopulateOrExchange(ShuttleGui & S)
{
S.StartTwoColumn();
{
S.Id(ID_SCALE).TieChoice(_("S&cale") + wxString(wxT(":")),
*(int*)&mTempSettings.scaleType,
&mScaleChoices);
mMinFreq =
S.Id(ID_MINIMUM).TieNumericTextBox(_("Mi&nimum Frequency (Hz):"),
mTempSettings.minFreq,
@ -212,6 +219,11 @@ void SpectrumPrefs::PopulateOrExchange(ShuttleGui & S)
S.Id(ID_GRAYSCALE).TieCheckBox(_("S&how the spectrum using grayscale colors"),
mTempSettings.isGrayscale);
#ifndef SPECTRAL_SELECTION_GLOBAL_SWITCH
S.Id(ID_SPECTRAL_SELECTION).TieCheckBox(_("Ena&ble spectral selection"),
mTempSettings.spectralSelection);
#endif
#ifdef EXPERIMENTAL_FFT_Y_GRID
S.TieCheckBox(_("Show a grid along the &Y-axis"),
mTempSettings.fftYGrid);
@ -248,6 +260,15 @@ void SpectrumPrefs::PopulateOrExchange(ShuttleGui & S)
}
// S.EndStatic();
#ifdef SPECTRAL_SELECTION_GLOBAL_SWITCH
S.StartStatic(_("Global settings"));
{
S.TieCheckBox(_("Ena&ble spectral selection"),
SpectrogramSettings::Globals::Get().spectralSelection);
}
S.EndStatic();
#endif
S.StartMultiColumn(2, wxALIGN_RIGHT);
{
S.Id(ID_APPLY).AddButton(_("Appl&y"));
@ -331,7 +352,10 @@ bool SpectrumPrefs::Apply()
ShuttleGui S(this, eIsGettingFromDialog);
PopulateOrExchange(S);
mTempSettings.ConvertToActualWindowSizes();
SpectrogramSettings::Globals::Get().SavePrefs(); // always
if (mWt) {
if (mDefaulted) {
mWt->SetSpectrogramSettings(NULL);
@ -358,11 +382,9 @@ bool SpectrumPrefs::Apply()
if (mWt && isOpenPage) {
// Future: open page will determine the track view type
/*
mWt->SetDisplay(WaveTrack::Spectrum);
if (partner)
partner->SetDisplay(WaveTrack::Spectrum);
*/
}
return true;
@ -421,14 +443,17 @@ BEGIN_EVENT_TABLE(SpectrumPrefs, PrefsPanel)
// 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_CHOICE(ID_SCALE, 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_CHECKBOX(ID_SPECTRAL_SELECTION, SpectrumPrefs::OnControl)
EVT_BUTTON(ID_APPLY, SpectrumPrefs::OnApply)
END_EVENT_TABLE()
SpectrumPrefsFactory::SpectrumPrefsFactory(WaveTrack *wt)

View File

@ -74,6 +74,7 @@ class SpectrumPrefs:public PrefsPanel
#endif
wxArrayString mTypeChoices;
wxArrayString mScaleChoices;
#ifdef EXPERIMENTAL_FIND_NOTES

View File

@ -65,17 +65,8 @@ void TracksPrefs::Populate()
mViewChoices.Add(_("Waveform (dB)"));
mViewCodes.Add(int(WaveTrack::WaveformDBDisplay));
mViewChoices.Add(_("Spectrogram"));
mViewCodes.Add(int(WaveTrack::SpectrumDisplay));
mViewChoices.Add(_("Spectrogram log(f)"));
mViewCodes.Add(int(WaveTrack::SpectrumLogDisplay));
mViewChoices.Add(_("Spectral Selection"));
mViewCodes.Add(int(WaveTrack::SpectralSelectionDisplay));
mViewChoices.Add(_("Spectral Selection log(f)"));
mViewCodes.Add(int(WaveTrack::SpectralSelectionLogDisplay));
mViewChoices.Add(_("Spectrum"));
mViewCodes.Add(WaveTrack::Spectrum);
mViewChoices.Add(_("Pitch (EAC)"));
mViewCodes.Add(int(WaveTrack::PitchDisplay));