From 1dffeace938125554bde676325982ebcd075af80 Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Sat, 13 Jun 2015 12:13:55 -0400 Subject: [PATCH] Access SpectrogramSettings via WaveTrack, which may be nondefault (no UI yet)... ... and add accessors to SpectrogramSettings, and remove TrackArtist functions for getting and setting the globals. --- src/TrackArtist.cpp | 117 +++---------------- src/TrackArtist.h | 10 -- src/TrackPanel.cpp | 183 +++++++++++++++--------------- src/TrackPanel.h | 16 +-- src/WaveClip.cpp | 4 +- src/WaveTrack.cpp | 47 +++++++- src/WaveTrack.h | 8 ++ src/prefs/SpectrogramSettings.cpp | 56 +++++++++ src/prefs/SpectrogramSettings.h | 14 ++- 9 files changed, 232 insertions(+), 223 deletions(-) diff --git a/src/TrackArtist.cpp b/src/TrackArtist.cpp index 2fa5cd651..4dc811d20 100644 --- a/src/TrackArtist.cpp +++ b/src/TrackArtist.cpp @@ -692,7 +692,7 @@ void TrackArtist::UpdateVRuler(Track *t, wxRect & rect) // All waves have a ruler in the info panel // The ruler needs a bevelled surround. if (t->GetKind() == Track::Wave) { - WaveTrack *wt = (WaveTrack *)t; + WaveTrack *wt = static_cast(t); int display = wt->GetDisplay(); if (display == WaveTrack::WaveformDisplay) { @@ -802,16 +802,10 @@ void TrackArtist::UpdateVRuler(Track *t, wxRect & rect) if (rect.height < 60) return; - double rate = wt->GetRate(); - int freq = lrint(rate/2.); - - int maxFreq = GetSpectrumMaxFreq(freq); - if(maxFreq > freq) - maxFreq = freq; - - int minFreq = GetSpectrumMinFreq(0); - if(minFreq < 0) - minFreq = 0; + 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 @@ -842,16 +836,10 @@ void TrackArtist::UpdateVRuler(Track *t, wxRect & rect) if (rect.height < 10) return; - double rate = wt->GetRate(); - int freq = lrint(rate/2.); - - int maxFreq = GetSpectrumLogMaxFreq(freq); - if(maxFreq > freq) - maxFreq = freq; - - int minFreq = GetSpectrumLogMinFreq(freq/1000.0); - if(minFreq < 1) - minFreq = 1; + 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 @@ -2042,6 +2030,8 @@ void TrackArtist::DrawClipSpectrum(WaveTrackCache &waveTrackCache, #endif const WaveTrack *const track = waveTrackCache.GetTrack(); + const SpectrogramSettings &settings = track->GetSpectrogramSettings(); + const int display = track->GetDisplay(); const bool autocorrelation = (WaveTrack::PitchDisplay == display); const bool logF = (WaveTrack::SpectrumLogDisplay == display @@ -2079,7 +2069,6 @@ void TrackArtist::DrawClipSpectrum(WaveTrackCache &waveTrackCache, } #endif - const SpectrogramSettings &settings = SpectrogramSettings::defaults(); const bool &isGrayscale = settings.isGrayscale; const int &range = settings.range; const int &gain = settings.gain; @@ -2115,28 +2104,8 @@ void TrackArtist::DrawClipSpectrum(WaveTrackCache &waveTrackCache, t0, pps, autocorrelation); } - int ifreq = lrint(rate / 2); - - int maxFreq; - if (!logF) - maxFreq = GetSpectrumMaxFreq(ifreq); - else - maxFreq = GetSpectrumLogMaxFreq(ifreq); - if(maxFreq > ifreq) - maxFreq = ifreq; - - int minFreq; - if (!logF) { - minFreq = GetSpectrumMinFreq(0); - if(minFreq < 0) - minFreq = 0; - } - else { - minFreq = GetSpectrumLogMinFreq(ifreq/1000.0); - if(minFreq < 1) - // Paul L: I suspect this line is now unreachable - minFreq = 1.0; - } + const int minFreq = logF ? settings.GetLogMinFreq(rate) : settings.GetMinFreq(rate); + const int maxFreq = logF ? settings.GetLogMaxFreq(rate) : settings.GetMaxFreq(rate); float minBin = ((double)minFreq / binUnit); float maxBin = ((double)maxFreq / binUnit); @@ -3217,66 +3186,6 @@ void TrackArtist::UpdatePrefs() gPrefs->Flush(); } -// Get various preference values -int TrackArtist::GetSpectrumMinFreq(int deffreq) -{ - const int &minFreq = SpectrogramSettings::defaults().minFreq; - return minFreq < 0 ? deffreq : minFreq; -} - -int TrackArtist::GetSpectrumMaxFreq(int deffreq) -{ - const int &maxFreq = SpectrogramSettings::defaults().maxFreq; - return maxFreq < 0 ? deffreq : maxFreq; -} - -int TrackArtist::GetSpectrumLogMinFreq(int deffreq) -{ - const int &logMinFreq = SpectrogramSettings::defaults().logMinFreq; - return logMinFreq < 0 ? deffreq : logMinFreq; -} - -int TrackArtist::GetSpectrumLogMaxFreq(int deffreq) -{ - const int &logMaxFreq = SpectrogramSettings::defaults().logMaxFreq; - return logMaxFreq < 0 ? deffreq : logMaxFreq; -} - -int TrackArtist::GetSpectrumWindowSize(bool includeZeroPadding) -{ - includeZeroPadding; - const int &windowSize = SpectrogramSettings::defaults().windowSize; -#ifdef EXPERIMENTAL_ZERO_PADDED_SPECTROGRAMS - if (includeZeroPadding) { - const int &zeroPaddingFactor = SpectrogramSettings::defaults().zeroPaddingFactor; - return windowSize * zeroPaddingFactor; - } - else -#endif - return windowSize; -} - -// Set various preference values -void TrackArtist::SetSpectrumMinFreq(int freq) -{ - SpectrogramSettings::defaults().minFreq = freq; -} - -void TrackArtist::SetSpectrumMaxFreq(int freq) -{ - SpectrogramSettings::defaults().maxFreq = freq; -} - -void TrackArtist::SetSpectrumLogMinFreq(int freq) -{ - SpectrogramSettings::defaults().logMinFreq = freq; -} - -void TrackArtist::SetSpectrumLogMaxFreq(int freq) -{ - SpectrogramSettings::defaults().logMaxFreq = freq; -} - // Draws the sync-lock bitmap, tiled; always draws stationary relative to the DC // // AWD: now that the tiles don't link together, we're drawing a tilted grid, at diff --git a/src/TrackArtist.h b/src/TrackArtist.h index 5001e294c..b0deb0fe8 100644 --- a/src/TrackArtist.h +++ b/src/TrackArtist.h @@ -73,16 +73,6 @@ class AUDACITY_DLL_API TrackArtist { void InvalidateSpectrumCache(TrackList *tracks); void InvalidateSpectrumCache(WaveTrack *track); - int GetSpectrumMinFreq(int deffreq); - int GetSpectrumMaxFreq(int deffreq); - int GetSpectrumLogMinFreq(int deffreq); - int GetSpectrumLogMaxFreq(int deffreq); - int GetSpectrumWindowSize(bool includeZeroPadding); - - void SetSpectrumMinFreq(int freq); - void SetSpectrumMaxFreq(int freq); - void SetSpectrumLogMinFreq(int freq); - void SetSpectrumLogMaxFreq(int freq); void SetBackgroundBrushes(wxBrush unselectedBrush, wxBrush selectedBrush, wxPen unselectedPen, wxPen selectedPen) { diff --git a/src/TrackPanel.cpp b/src/TrackPanel.cpp index 4ec237db2..066c2702c 100644 --- a/src/TrackPanel.cpp +++ b/src/TrackPanel.cpp @@ -230,7 +230,7 @@ is time to refresh some aspect of the screen. #include -#define ZOOMLIMIT 0.001 +#define ZOOMLIMIT 0.001f WX_DEFINE_OBJARRAY(TrackClipArray); @@ -2992,10 +2992,10 @@ inline double findMaxRatio(double center, double rate) } -void TrackPanel::SnapCenterOnce(WaveTrack *pTrack, bool up) +void TrackPanel::SnapCenterOnce(const WaveTrack *pTrack, bool up) { - // Always spectrogram, never pitch view, pass true - const int windowSize = mTrackArtist->GetSpectrumWindowSize(true); + const SpectrogramSettings &settings = pTrack->GetSpectrogramSettings(); + const int windowSize = settings.GetFFTLength(false); const double rate = pTrack->GetRate(); const double nyq = rate / 2.0; const double binFrequency = rate / windowSize; @@ -3032,7 +3032,7 @@ void TrackPanel::SnapCenterOnce(WaveTrack *pTrack, bool up) (snappedFrequency / ratio, snappedFrequency * ratio); } -void TrackPanel::StartSnappingFreqSelection (WaveTrack *pTrack) +void TrackPanel::StartSnappingFreqSelection (const WaveTrack *pTrack) { static const sampleCount minLength = 8; @@ -3057,12 +3057,13 @@ void TrackPanel::StartSnappingFreqSelection (WaveTrack *pTrack) // Use same settings as are now used for spectrogram display, // except, shrink the window as needed so we get some answers - // Always spectrogram, never pitch view, pass true - int windowSize = mTrackArtist->GetSpectrumWindowSize(true); + const SpectrogramSettings &settings = pTrack->GetSpectrogramSettings(); + int windowSize = settings.GetFFTLength(false); while(windowSize > effectiveLength) windowSize >>= 1; - const int windowType = SpectrogramSettings::defaults().windowType; + const int windowType = settings.windowType; + mFrequencySnapper->Calculate( SpectrumAnalyst::Spectrum, windowType, windowSize, rate, &frequencySnappingData[0], length); @@ -3087,8 +3088,8 @@ void TrackPanel::MoveSnappingFreqSelection (int mouseYCoordinate, // I am not worrying about that odd case. const double rate = wt->GetRate(); const double frequency = - PositionToFrequency(false, mouseYCoordinate, - trackTopEdge, trackHeight, rate, logF); + PositionToFrequency(wt, false, mouseYCoordinate, + trackTopEdge, trackHeight, logF); const double snappedFrequency = mFrequencySnapper->FindPeak(frequency, NULL); const double maxRatio = findMaxRatio(snappedFrequency, rate); @@ -3124,10 +3125,9 @@ void TrackPanel::StartFreqSelection (int mouseYCoordinate, int trackTopEdge, if (isSpectrogramTrack(pTrack, &logF)) { mFreqSelTrack = static_cast(pTrack); mFreqSelMode = FREQ_SEL_FREE; - const double rate = mFreqSelTrack->GetRate(); mFreqSelPin = - PositionToFrequency(false, mouseYCoordinate, - trackTopEdge, trackHeight, rate, logF); + PositionToFrequency(mFreqSelTrack, false, mouseYCoordinate, + trackTopEdge, trackHeight, logF); mViewInfo->selectedRegion.setFrequencies(mFreqSelPin, mFreqSelPin); } } @@ -3152,8 +3152,8 @@ void TrackPanel::ExtendFreqSelection(int mouseYCoordinate, int trackTopEdge, ; const double rate = wt->GetRate(); const double frequency = - PositionToFrequency(true, mouseYCoordinate, - trackTopEdge, trackHeight, rate, logF); + PositionToFrequency(wt, true, mouseYCoordinate, + trackTopEdge, trackHeight, logF); // Dragging center? if (mFreqSelMode == FREQ_SEL_DRAG_CENTER) { @@ -3528,13 +3528,15 @@ enum { FREQ_SNAP_DISTANCE = 10 }; /// Converts a position (mouse Y coordinate) to /// frequency, in Hz. -double TrackPanel::PositionToFrequency(bool maySnap, +double TrackPanel::PositionToFrequency(const WaveTrack *wt, + bool maySnap, wxInt64 mouseYCoordinate, wxInt64 trackTopEdge, int trackHeight, - double rate, bool logF) const { + const double rate = wt->GetRate(); + // Handle snapping if (maySnap && mouseYCoordinate - trackTopEdge < FREQ_SNAP_DISTANCE) @@ -3544,42 +3546,38 @@ double TrackPanel::PositionToFrequency(bool maySnap, return -1; const double p = double(mouseYCoordinate - trackTopEdge) / trackHeight; - const int freq = lrint(rate/2.); if (logF) { - const double maxFreq = - std::min(freq, mTrackArtist->GetSpectrumLogMaxFreq(freq)); - const double minFreq = - std::max(1, mTrackArtist->GetSpectrumLogMinFreq(1)); + const SpectrogramSettings &settings = wt->GetSpectrogramSettings(); + const double maxFreq = settings.GetLogMaxFreq(rate); + const double minFreq = settings.GetLogMinFreq(rate); return exp(p * log(minFreq) + (1.0 - p) * log(maxFreq)); } else { - const double maxFreq = - std::min(freq, mTrackArtist->GetSpectrumMaxFreq(freq)); - const double minFreq = - std::max(0, mTrackArtist->GetSpectrumMinFreq(0)); + const SpectrogramSettings &settings = wt->GetSpectrogramSettings(); + const double maxFreq = settings.GetMaxFreq(rate); + const double minFreq = settings.GetMinFreq(rate); return p * minFreq + (1.0 - p) * maxFreq; } } /// Converts a frequency to screen y position. -wxInt64 TrackPanel::FrequencyToPosition(double frequency, +wxInt64 TrackPanel::FrequencyToPosition(const WaveTrack *wt, + double frequency, wxInt64 trackTopEdge, int trackHeight, - double rate, bool logF) const { - const int freq = lrint(rate/2.); + const double rate = wt->GetRate(); double p = 0; if (logF) { - const double maxFreq = - std::min(freq, mTrackArtist->GetSpectrumLogMaxFreq(freq)); - const double minFreq = - std::max(1, mTrackArtist->GetSpectrumLogMinFreq(1)); + const SpectrogramSettings &settings = wt->GetSpectrogramSettings(); + const double maxFreq = settings.GetLogMaxFreq(rate); + const double minFreq = settings.GetLogMinFreq(rate); if (maxFreq > minFreq) { const double @@ -3591,10 +3589,9 @@ wxInt64 TrackPanel::FrequencyToPosition(double frequency, } else { - const double maxFreq = - std::min(freq, mTrackArtist->GetSpectrumMaxFreq(freq)); - const double minFreq = - std::max(0, mTrackArtist->GetSpectrumMinFreq(0)); + const SpectrogramSettings &settings = wt->GetSpectrogramSettings(); + const double maxFreq = settings.GetMaxFreq(rate); + const double minFreq = settings.GetMinFreq(rate); if (maxFreq > minFreq) p = (frequency - minFreq) / (maxFreq - minFreq); } @@ -3687,12 +3684,10 @@ bool mayDragWidth, bool onlyWithinSnapDistance, isSpectrogramTrack(pTrack, &logF)) { const WaveTrack *const wt = static_cast(pTrack); const wxInt64 bottomSel = (f0 >= 0) - ? FrequencyToPosition(f0, rect.y, rect.height, - wt->GetRate(), logF) + ? FrequencyToPosition(wt, f0, rect.y, rect.height, logF) : rect.y + rect.height; const wxInt64 topSel = (f1 >= 0) - ? FrequencyToPosition(f1, rect.y, rect.height, - wt->GetRate(), logF) + ? FrequencyToPosition(wt, f1, rect.y, rect.height, logF) : rect.y; wxInt64 signedBottomDist = int(event.m_y - bottomSel); wxInt64 verticalDist = abs(signedBottomDist); @@ -3710,8 +3705,7 @@ bool mayDragWidth, bool onlyWithinSnapDistance, #endif ) { const wxInt64 centerSel = - FrequencyToPosition(fc, rect.y, rect.height, - wt->GetRate(), logF); + FrequencyToPosition(wt, fc, rect.y, rect.height, logF); const wxInt64 centerDist = abs(int(event.m_y - centerSel)); if (centerDist < verticalDist) chooseCenter = true, verticalDist = centerDist, @@ -4682,8 +4676,8 @@ void TrackPanel::HandleVZoomButtonUp( wxMouseEvent & event ) // don't do anything if track is not wave if (mCapturedTrack->GetKind() != Track::Wave) return; - WaveTrack *track = (WaveTrack *)mCapturedTrack; - WaveTrack *partner = (WaveTrack *)mTracks->GetLink(track); + WaveTrack *track = static_cast(mCapturedTrack); + WaveTrack *partner = static_cast(mTracks->GetLink(track)); int height = track->GetHeight(); int ypos = mCapturedRect.y; @@ -4695,40 +4689,27 @@ void TrackPanel::HandleVZoomButtonUp( wxMouseEvent & event ) } float min, max, c, l, binSize = 0.0; - bool spectrum, spectrumLog; - int windowSize; - double rate = ((WaveTrack *)track)->GetRate(); - spectrum = (((WaveTrack *) track)->GetDisplay() == WaveTrack::SpectrumDisplay) || - (((WaveTrack *) track)->GetDisplay() == WaveTrack::SpectralSelectionDisplay) ; - spectrumLog=(((WaveTrack *) track)->GetDisplay() == WaveTrack::SpectrumLogDisplay) || - (((WaveTrack *) track)->GetDisplay() == WaveTrack::SpectralSelectionLogDisplay) - ; + 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) { - min = mTrackArtist->GetSpectrumMinFreq(0); - if(min < 0) - min = 0; - max = mTrackArtist->GetSpectrumMaxFreq(8000); - if(max > rate/2.) - max = rate/2.; - - // Always spectrogram, never pitch view, pass true - windowSize = mTrackArtist->GetSpectrumWindowSize(true); - binSize = rate / windowSize; - minBins = wxMin(10, windowSize/2); //minimum 10 freq bins, unless there are less + const SpectrogramSettings &settings = track->GetSpectrogramSettings(); + min = settings.GetMinFreq(rate); + max = settings.GetMaxFreq(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) { - min = mTrackArtist->GetSpectrumLogMinFreq(lrint(rate/1000.0)); - if(min < 1) - min = 1; - max = mTrackArtist->GetSpectrumLogMaxFreq(lrint(rate/2.)); - if(max > rate/2.) - max = rate/2.; - - // Always spectrogram, never pitch view, pass true - windowSize = mTrackArtist->GetSpectrumWindowSize(true); - binSize = rate / windowSize; - minBins = wxMin(10, windowSize/2); //minimum 10 freq bins, unless there are less + 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); @@ -4743,8 +4724,8 @@ void TrackPanel::HandleVZoomButtonUp( wxMouseEvent & event ) double xmax = 1-(mZoomStart - ypos) / (float)height; double lmin=log10(tmin), lmax=log10(tmax); double d=lmax-lmin; - min=wxMax(1.0, pow(10, xmin*d+lmin)); - max=wxMin(rate/2.0, pow(10, xmax*d+lmin)); + min=std::max(1.0, pow(10, xmin*d+lmin)); + max=std::min(rate/2.0, pow(10, xmax*d+lmin)); // Enforce vertical zoom limits // done in the linear freq domain for now, but not too far out if(max < min + minBins * binSize) @@ -4798,11 +4779,11 @@ void TrackPanel::HandleVZoomButtonUp( wxMouseEvent & event ) l = (c - min); if(c - 2*l <= 0) { min = 0.0; - max = wxMin( rate/2., 2. * max); + max = std::min( rate/2., 2. * max); } else { - min = wxMax( 0.0, c - 2*l); - max = wxMin( rate/2., c + 2*l); + min = std::max( 0.0f, c - 2*l); + max = std::min( float(rate)/2, c + 2*l); } } } @@ -4822,8 +4803,8 @@ void TrackPanel::HandleVZoomButtonUp( wxMouseEvent & event ) double xmax = c + 1.; double lmin = log10(min), lmax = log10(max); double d = lmax-lmin; - min = wxMax(1,pow(10, xmin*d+lmin)); - max = wxMin(rate/2., pow(10, xmax*d+lmin)); + min = std::max(1.0f,float(pow(10, xmin*d+lmin))); + max = std::min(rate/2., pow(10, xmax*d+lmin)); } } else { @@ -4845,8 +4826,8 @@ void TrackPanel::HandleVZoomButtonUp( wxMouseEvent & event ) float minRange = (min < -1) ? -2.0 : -1.0; float maxRange = (max > 1) ? 2.0 : 1.0; // and enforce vertical zoom limits. - min = wxMin(maxRange - ZOOMLIMIT, wxMax(minRange, c - 2*l)); - max = wxMax(minRange + ZOOMLIMIT, wxMin(maxRange, c + 2*l)); + min = std::min(maxRange - ZOOMLIMIT, std::max(minRange, c - 2*l)); + max = std::max(minRange + ZOOMLIMIT, std::min(maxRange, c + 2*l)); } } } @@ -4858,12 +4839,12 @@ void TrackPanel::HandleVZoomButtonUp( wxMouseEvent & event ) if(spectrum) { c = 0.5*(min+max); // Enforce maximum vertical zoom - l = wxMax( minBins * binSize, (c - min)); + l = std::max( minBins * binSize, (c - min)); p1 = (mZoomStart - ypos) / (float)height; c = (max * (1.0-p1) + min * p1); - min = wxMax( 0.0, c - 0.5*l); - max = wxMin( rate/2., min + l); + min = std::max( 0.0, c - 0.5*l); + max = std::min( float(rate)/2, min + l); } else { if(spectrumLog) { @@ -4873,8 +4854,8 @@ void TrackPanel::HandleVZoomButtonUp( wxMouseEvent & event ) double xmax = c + 0.25; double lmin = log10(min), lmax = log10(max); double d = lmax-lmin; - min = wxMax(1,pow(10, xmin*d+lmin)); - max = wxMin(rate/2., pow(10, xmax*d+lmin)); + min = std::max(1.0f, float(pow(10, xmin*d+lmin))); + max = std::min(rate/2., pow(10, xmax*d+lmin)); // Enforce vertical zoom limits // done in the linear freq domain for now, but not too far out if(max < min + minBins * binSize) @@ -4893,7 +4874,7 @@ void TrackPanel::HandleVZoomButtonUp( wxMouseEvent & event ) else { c = 0.5*(min+max); // Enforce maximum vertical zoom - l = wxMax( ZOOMLIMIT, (c - min)); + l = std::max( ZOOMLIMIT, (c - min)); p1 = (mZoomStart - ypos) / (float)height; c = (max * (1.0-p1) + min * p1); @@ -4905,13 +4886,27 @@ void TrackPanel::HandleVZoomButtonUp( wxMouseEvent & event ) } if(spectrum) { - mTrackArtist->SetSpectrumMaxFreq(max); - mTrackArtist->SetSpectrumMinFreq(min); + SpectrogramSettings &settings = track->GetSpectrogramSettings(); + settings.SetMinFreq(min); + settings.SetMaxFreq(max); + if (partner) { + // To do: share memory with reference counting? + SpectrogramSettings &settings = partner->GetSpectrogramSettings(); + settings.SetMinFreq(min); + settings.SetMaxFreq(max); + } mTrackArtist->InvalidateSpectrumCache(mTracks); } else if(spectrumLog) { - mTrackArtist->SetSpectrumLogMaxFreq(max); - mTrackArtist->SetSpectrumLogMinFreq(min); + SpectrogramSettings &settings = track->GetSpectrogramSettings(); + settings.SetLogMinFreq(min); + settings.SetLogMaxFreq(max); + if (partner) { + // To do: share memory with reference counting? + SpectrogramSettings &settings = partner->GetSpectrogramSettings(); + settings.SetLogMinFreq(min); + settings.SetLogMaxFreq(max); + } mTrackArtist->InvalidateSpectrumCache(mTracks); } else { diff --git a/src/TrackPanel.h b/src/TrackPanel.h index 6dddc2ce0..02e9eb4aa 100644 --- a/src/TrackPanel.h +++ b/src/TrackPanel.h @@ -337,9 +337,9 @@ protected: #ifdef EXPERIMENTAL_SPECTRAL_EDITING public: - void SnapCenterOnce (WaveTrack *pTrack, bool up); + void SnapCenterOnce (const WaveTrack *pTrack, bool up); protected: - void StartSnappingFreqSelection (WaveTrack *pTrack); + void StartSnappingFreqSelection (const WaveTrack *pTrack); void MoveSnappingFreqSelection (int mouseYCoordinate, int trackTopEdge, int trackHeight, Track *pTrack); @@ -494,9 +494,9 @@ protected: virtual wxRect FindTrackRect(Track * target, bool label); virtual int GetVRulerWidth() const; - virtual int GetVRulerOffset() const { return mTrackInfo.GetTrackInfoWidth(); }; + virtual int GetVRulerOffset() const { return mTrackInfo.GetTrackInfoWidth(); } - virtual int GetLabelWidth() const { return mTrackInfo.GetTrackInfoWidth() + GetVRulerWidth(); }; + virtual int GetLabelWidth() const { return mTrackInfo.GetTrackInfoWidth() + GetVRulerWidth(); } // JKC Nov-2011: These four functions only used from within a dll such as mod-track-panel // They work around some messy problems with constructors. @@ -693,16 +693,16 @@ protected: void HandleCenterFrequencyClick (bool shiftDown, Track *pTrack, double value); - double PositionToFrequency(bool maySnap, + double PositionToFrequency(const WaveTrack *wt, + bool maySnap, wxInt64 mouseYCoordinate, wxInt64 trackTopEdge, int trackHeight, - double rate, bool logF) const; - wxInt64 FrequencyToPosition(double frequency, + wxInt64 FrequencyToPosition(const WaveTrack *wt, + double frequency, wxInt64 trackTopEdge, int trackHeight, - double rate, bool logF) const; #endif diff --git a/src/WaveClip.cpp b/src/WaveClip.cpp index f4501ddde..a8f8cb400 100644 --- a/src/WaveClip.cpp +++ b/src/WaveClip.cpp @@ -902,8 +902,8 @@ bool WaveClip::GetSpectrogram(WaveTrackCache &waveTrackCache, double t0, double pixelsPerSecond, bool autocorrelation) { - const SpectrogramSettings &settings = SpectrogramSettings::defaults(); - + const WaveTrack *const track = waveTrackCache.GetTrack(); + const SpectrogramSettings &settings = track->GetSpectrogramSettings(); const int &frequencyGain = settings.frequencyGain; const int &windowSize = settings.windowSize; const int &windowType = settings.windowType; diff --git a/src/WaveTrack.cpp b/src/WaveTrack.cpp index fd7902858..44f3c5cf5 100644 --- a/src/WaveTrack.cpp +++ b/src/WaveTrack.cpp @@ -54,6 +54,7 @@ Track classes. #include "ondemand/ODManager.h" #include "effects/TimeWarper.h" +#include "prefs/SpectrumPrefs.h" using std::max; @@ -74,6 +75,7 @@ WaveTrack *TrackFactory::NewWaveTrack(sampleFormat format, double rate) WaveTrack::WaveTrack(DirManager *projDirManager, sampleFormat format, double rate): Track(projDirManager) + , mpSpectrumSettings(0) { if (format == (sampleFormat)0) { @@ -105,6 +107,9 @@ WaveTrack::WaveTrack(DirManager *projDirManager, sampleFormat format, double rat WaveTrack::WaveTrack(WaveTrack &orig): Track(orig) + , mpSpectrumSettings(orig.mpSpectrumSettings + ? new SpectrogramSettings(*orig.mpSpectrumSettings) : 0 + ) { mDisplay = FindDefaultViewMode(); mLastDisplay = -1; @@ -139,9 +144,12 @@ void WaveTrack::Merge(const Track &orig) { if (orig.GetKind() == Wave) { - mDisplay = ((WaveTrack &)orig).mDisplay; - mGain = ((WaveTrack &)orig).mGain; - mPan = ((WaveTrack &)orig).mPan; + const WaveTrack &wt = static_cast(orig); + mDisplay = wt.mDisplay; + mGain = wt.mGain; + mPan = wt.mPan; + SetSpectrogramSettings(wt.mpSpectrumSettings + ? new SpectrogramSettings(*wt.mpSpectrumSettings) : 0); } Track::Merge(orig); } @@ -159,6 +167,7 @@ WaveTrack::~WaveTrack() if (mDisplayLocations) delete [] mDisplayLocations; + delete mpSpectrumSettings; } double WaveTrack::GetOffset() const @@ -624,6 +633,38 @@ bool WaveTrack::ClearAndAddCutLine(double t0, double t1) return HandleClear(t0, t1, true, false); } +const SpectrogramSettings &WaveTrack::GetSpectrogramSettings() const +{ + if (mpSpectrumSettings) + return *mpSpectrumSettings; + else + return SpectrogramSettings::defaults(); +} + +SpectrogramSettings &WaveTrack::GetSpectrogramSettings() +{ + if (mpSpectrumSettings) + return *mpSpectrumSettings; + else + return SpectrogramSettings::defaults(); +} + +SpectrogramSettings &WaveTrack::GetIndependentSpectrogramSettings() +{ + if (!mpSpectrumSettings) + mpSpectrumSettings = + new SpectrogramSettings(SpectrogramSettings::defaults()); + return *mpSpectrumSettings; +} + +void WaveTrack::SetSpectrogramSettings(SpectrogramSettings *pSettings) +{ + if (mpSpectrumSettings != pSettings) { + delete mpSpectrumSettings; + mpSpectrumSettings = pSettings; + } +} + // // ClearAndPaste() is a specialized version of HandleClear() // followed by Paste() and is used mostly by effects that diff --git a/src/WaveTrack.h b/src/WaveTrack.h index 065f64948..3e72dfb04 100644 --- a/src/WaveTrack.h +++ b/src/WaveTrack.h @@ -22,6 +22,7 @@ #include #include +class SpectrogramSettings; class TimeWarper; // @@ -145,6 +146,11 @@ class AUDACITY_DLL_API WaveTrack: public Track { sampleFormat GetSampleFormat() { return mFormat; } bool ConvertToSampleFormat(sampleFormat format); + const SpectrogramSettings &GetSpectrogramSettings() const; + SpectrogramSettings &GetSpectrogramSettings(); + SpectrogramSettings &GetIndependentSpectrogramSettings(); + void SetSpectrogramSettings(SpectrogramSettings *pSettings); + // // High-level editing // @@ -490,6 +496,8 @@ class AUDACITY_DLL_API WaveTrack: public Track { wxCriticalSection mAppendCriticalSection; double mLegacyProjectFileOffset; int mAutoSaveIdent; + + SpectrogramSettings *mpSpectrumSettings; }; // This is meant to be a short-lived object, during whose lifetime, diff --git a/src/prefs/SpectrogramSettings.cpp b/src/prefs/SpectrogramSettings.cpp index 269561899..ceffd4471 100644 --- a/src/prefs/SpectrogramSettings.cpp +++ b/src/prefs/SpectrogramSettings.cpp @@ -19,6 +19,9 @@ Paul Licameli #include "../Prefs.h" #include "../RealFFTf.h" +#include +#include + SpectrogramSettings::SpectrogramSettings() : hFFT(0) , window(0) @@ -254,6 +257,59 @@ void SpectrogramSettings::CacheWindows() const #endif // EXPERIMENTAL_USE_REALFFTF } +int SpectrogramSettings::GetMinFreq(double rate) const +{ + const int top = lrint(rate / 2.); + return std::max(0, std::min(top, minFreq)); +} + +int SpectrogramSettings::GetMaxFreq(double rate) const +{ + const int top = lrint(rate / 2.); + if (maxFreq < 0) + return top; + else + return std::max(0, std::min(top, maxFreq)); +} + +int SpectrogramSettings::GetLogMinFreq(double rate) const +{ + const int top = lrint(rate / 2.); + if (logMinFreq < 0) + return top / 1000.0; + else + return std::max(1, std::min(top, logMinFreq)); +} + +int SpectrogramSettings::GetLogMaxFreq(double rate) const +{ + const int top = lrint(rate / 2.); + if (logMaxFreq < 0) + return top; + else + return std::max(1, std::min(top, logMaxFreq)); +} + +void SpectrogramSettings::SetMinFreq(int freq) +{ + minFreq = freq; +} + +void SpectrogramSettings::SetMaxFreq(int freq) +{ + maxFreq = freq; +} + +void SpectrogramSettings::SetLogMinFreq(int freq) +{ + logMinFreq = freq; +} + +void SpectrogramSettings::SetLogMaxFreq(int freq) +{ + logMaxFreq = freq; +} + int SpectrogramSettings::GetFFTLength(bool autocorrelation) const { return windowSize diff --git a/src/prefs/SpectrogramSettings.h b/src/prefs/SpectrogramSettings.h index b7775c8a5..3d13aa528 100644 --- a/src/prefs/SpectrogramSettings.h +++ b/src/prefs/SpectrogramSettings.h @@ -28,12 +28,23 @@ public: void DestroyWindows(); void CacheWindows() const; +private: int minFreq; int maxFreq; - int logMinFreq; int logMaxFreq; +public: + int GetMinFreq(double rate) const; + int GetMaxFreq(double rate) const; + int GetLogMinFreq(double rate) const; + int GetLogMaxFreq(double rate) const; + void SetMinFreq(int freq); + void SetMaxFreq(int freq); + void SetLogMinFreq(int freq); + void SetLogMaxFreq(int freq); + +public: int range; int gain; int frequencyGain; @@ -67,5 +78,4 @@ public: mutable float *window; #endif }; - #endif