1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-08-10 09:01:13 +02:00

WaveTrack::WaveTrackDisplay does not encode scale or spectral selection...

... SpectrogramSettings does that instead, and Preferences or View Settings
are the user interface for changing it.

Handle invalidation of spectrogram pixel cache for scale type changes,
just as for other changes of settings.  No more
TrackArtist::InvalidateSpectrumCache().

View type of track now switches to Spectrum when applying or OKing the
View Settings... dialog and the Spectrogram page is open (and for now
it is still the only page)
This commit is contained in:
Paul Licameli 2015-06-16 00:55:34 -04:00
parent 5928ac88b9
commit f74713f020
14 changed files with 222 additions and 185 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.spectralSelection;
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.spectralSelection;
}
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().spectralSelection;
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

@ -47,6 +47,8 @@ SpectrogramSettings::SpectrogramSettings(const SpectrogramSettings &other)
, zeroPaddingFactor(other.zeroPaddingFactor)
#endif
, isGrayscale(other.isGrayscale)
, scaleType(other.scaleType)
, spectralSelection(other.spectralSelection)
#ifdef EXPERIMENTAL_FFT_Y_GRID
, fftYGrid(other.fftYGrid)
#endif
@ -79,6 +81,8 @@ SpectrogramSettings &SpectrogramSettings::operator= (const SpectrogramSettings &
zeroPaddingFactor = other.zeroPaddingFactor;
#endif
isGrayscale = other.isGrayscale;
scaleType = other.scaleType;
spectralSelection = other.spectralSelection;
#ifdef EXPERIMENTAL_FFT_Y_GRID
fftYGrid = other.fftYGrid;
#endif
@ -102,6 +106,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 +188,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 +218,9 @@ void SpectrogramSettings::LoadPrefs()
isGrayscale = (gPrefs->Read(wxT("/Spectrum/Grayscale"), 0L) != 0);
scaleType = ScaleType(gPrefs->Read(wxT("/Spectrum/ScaleType"), 0L));
spectralSelection = (gPrefs->Read(wxT("/Spectrum/EnableSpectralSelection"), 0L) != 0);
#ifdef EXPERIMENTAL_FFT_Y_GRID
fftYGrid = (gPrefs->Read(wxT("/Spectrum/FFTYGrid"), 0L) != 0);
#endif //EXPERIMENTAL_FFT_Y_GRID
@ -235,6 +275,9 @@ void SpectrogramSettings::SavePrefs()
gPrefs->Write(wxT("/Spectrum/Grayscale"), isGrayscale);
gPrefs->Write(wxT("/Spectrum/ScaleType"), scaleType);
gPrefs->Write(wxT("/Spectrum/EnableSpectralSelection"), spectralSelection);
#ifdef EXPERIMENTAL_FFT_Y_GRID
gPrefs->Write(wxT("/Spectrum/FFTYGrid"), fftYGrid);
#endif //EXPERIMENTAL_FFT_Y_GRID

View File

@ -15,6 +15,7 @@ Paul Licameli
struct FFTParam;
class SpectrumPrefs;
class wxArrayString;
class SpectrogramSettings
{
@ -28,6 +29,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);
@ -79,6 +93,10 @@ public:
bool isGrayscale;
ScaleType scaleType;
bool spectralSelection; // But should this vary per track? -- PRL
#ifdef EXPERIMENTAL_FFT_Y_GRID
bool fftYGrid;
#endif //EXPERIMENTAL_FFT_Y_GRID

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,
@ -211,6 +218,8 @@ void SpectrumPrefs::PopulateOrExchange(ShuttleGui & S)
S.Id(ID_GRAYSCALE).TieCheckBox(_("S&how the spectrum using grayscale colors"),
mTempSettings.isGrayscale);
S.Id(ID_SPECTRAL_SELECTION).TieCheckBox(_("Ena&ble spectral selection"),
mTempSettings.spectralSelection);
#ifdef EXPERIMENTAL_FFT_Y_GRID
S.TieCheckBox(_("Show a grid along the &Y-axis"),
@ -358,11 +367,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 +428,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));