From d831318132b577925f4b89603682aef2f13f9f0f Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Fri, 10 Feb 2017 13:56:31 -0500 Subject: [PATCH] simplify SpectrogramSettings::GetScale; abstract frequency-to-bin... ... this is a preparation for the constant-q feature, if we want it. --- src/NumberScale.h | 56 +++++++++++++------------------ src/TrackArtist.cpp | 23 +++++++------ src/TrackPanel.cpp | 8 ++--- src/prefs/SpectrogramSettings.cpp | 16 ++++++--- src/prefs/SpectrogramSettings.h | 7 ++-- src/widgets/Ruler.cpp | 2 +- 6 files changed, 57 insertions(+), 55 deletions(-) diff --git a/src/NumberScale.h b/src/NumberScale.h index e8529d3e2..513bae4f6 100644 --- a/src/NumberScale.h +++ b/src/NumberScale.h @@ -32,54 +32,47 @@ class NumberScale { public: NumberScale() - : mType(nstLinear), mValue0(0), mValue1(1), mUnit(1) + : mType(nstLinear), mValue0(0), mValue1(1) {} - NumberScale(NumberScaleType type, - float value0, float value1, float unit) + NumberScale(NumberScaleType type, float value0, float value1) : mType(type) { switch (mType) { case nstLinear: { - mValue0 = value0 / unit; - mValue1 = value1 / unit; - mUnit = 1.0; + mValue0 = value0; + mValue1 = value1; } break; case nstLogarithmic: { - mValue0 = logf(value0 / unit); - mValue1 = logf(value1 / unit); - mUnit = 1.0; + mValue0 = logf(value0); + mValue1 = logf(value1); } break; case nstMel: { mValue0 = hzToMel(value0); mValue1 = hzToMel(value1); - mUnit = unit; } break; case nstBark: { mValue0 = hzToBark(value0); mValue1 = hzToBark(value1); - mUnit = unit; } break; case nstErb: { mValue0 = hzToErb(value0); mValue1 = hzToErb(value1); - mUnit = unit; } break; case nstPeriod: { mValue0 = hzToPeriod(value0); mValue1 = hzToPeriod(value1); - mUnit = unit; } break; default: @@ -98,8 +91,7 @@ public: { return mType == other.mType && mValue0 == other.mValue0 - && mValue1 == other.mValue1 - && mUnit == other.mUnit; + && mValue1 == other.mValue1; } bool operator != (const NumberScale &other) const @@ -169,13 +161,13 @@ public: case nstLogarithmic: return exp(mValue0 + pp * (mValue1 - mValue0)); case nstMel: - return melToHz(mValue0 + pp * (mValue1 - mValue0)) / mUnit; + return melToHz(mValue0 + pp * (mValue1 - mValue0)); case nstBark: - return barkToHz(mValue0 + pp * (mValue1 - mValue0)) / mUnit; + return barkToHz(mValue0 + pp * (mValue1 - mValue0)); case nstErb: - return erbToHz(mValue0 + pp * (mValue1 - mValue0)) / mUnit; + return erbToHz(mValue0 + pp * (mValue1 - mValue0)); case nstPeriod: - return periodToHz(mValue0 + pp * (mValue1 - mValue0)) / mUnit; + return periodToHz(mValue0 + pp * (mValue1 - mValue0)); } } @@ -184,8 +176,8 @@ public: class Iterator { public: - Iterator(NumberScaleType type, float step, float value, float unit) - : mType(type), mStep(step), mValue(value), mUnit(unit) + Iterator(NumberScaleType type, float step, float value) + : mType(type), mStep(step), mValue(value) { } @@ -198,13 +190,13 @@ public: case nstLogarithmic: return mValue; case nstMel: - return melToHz(mValue) / mUnit; + return melToHz(mValue); case nstBark: - return barkToHz(mValue) / mUnit; + return barkToHz(mValue); case nstErb: - return erbToHz(mValue) / mUnit; + return erbToHz(mValue); case nstPeriod: - return periodToHz(mValue) / mUnit; + return periodToHz(mValue); } } @@ -231,7 +223,6 @@ public: const NumberScaleType mType; const float mStep; float mValue; - float mUnit; }; Iterator begin(float nPositions) const @@ -247,12 +238,12 @@ public: return Iterator (mType, nPositions == 1 ? 0 : (mValue1 - mValue0) / (nPositions - 1), - mValue0, mUnit); + mValue0); case nstLogarithmic: return Iterator (mType, nPositions == 1 ? 1 : exp((mValue1 - mValue0) / (nPositions - 1)), - exp(mValue0), mUnit); + exp(mValue0)); } } @@ -267,13 +258,13 @@ public: case nstLogarithmic: return ((log(val) - mValue0) / (mValue1 - mValue0)); case nstMel: - return ((hzToMel(val * mUnit) - mValue0) / (mValue1 - mValue0)); + return ((hzToMel(val) - mValue0) / (mValue1 - mValue0)); case nstBark: - return ((hzToBark(val * mUnit) - mValue0) / (mValue1 - mValue0)); + return ((hzToBark(val) - mValue0) / (mValue1 - mValue0)); case nstErb: - return ((hzToErb(val * mUnit) - mValue0) / (mValue1 - mValue0)); + return ((hzToErb(val) - mValue0) / (mValue1 - mValue0)); case nstPeriod: - return ((hzToPeriod(val * mUnit) - mValue0) / (mValue1 - mValue0)); + return ((hzToPeriod(val) - mValue0) / (mValue1 - mValue0)); } } @@ -281,7 +272,6 @@ private: NumberScaleType mType; float mValue0; float mValue1; - float mUnit; }; #endif diff --git a/src/TrackArtist.cpp b/src/TrackArtist.cpp index 1873280a8..b35c118c5 100644 --- a/src/TrackArtist.cpp +++ b/src/TrackArtist.cpp @@ -893,9 +893,9 @@ void TrackArtist::UpdateVRuler(const Track *t, wxRect & rect) vruler->SetRange(maxFreq, minFreq); vruler->SetUnits(wxT("")); vruler->SetLog(true); - NumberScale scale - (wt->GetSpectrogramSettings().GetScale - (minFreq, maxFreq, wt->GetRate(), false).Reversal()); + NumberScale scale( + wt->GetSpectrogramSettings().GetScale( minFreq, maxFreq ) + .Reversal() ); vruler->SetNumberScale(&scale); } break; @@ -2194,15 +2194,17 @@ void TrackArtist::DrawClipSpectrum(WaveTrackCache &waveTrackCache, // the desired fft bin(s) for display on that row float *bins = (float*)alloca(sizeof(*bins)*(hiddenMid.height + 1)); { - const NumberScale numberScale(settings.GetScale(minFreq, maxFreq, rate, true)); + const NumberScale numberScale( settings.GetScale( minFreq, maxFreq ) ); NumberScale::Iterator it = numberScale.begin(mid.height); - float nextBin = std::max(0.0f, std::min(float(half - 1), *it)); + float nextBin = std::max( 0.0f, std::min( float(half - 1), + settings.findBin( *it, binUnit ) ) ); int yy; for (yy = 0; yy < hiddenMid.height; ++yy) { bins[yy] = nextBin; - nextBin = std::max(0.0f, std::min(float(half - 1), *++it)); + nextBin = std::max( 0.0f, std::min( float(half - 1), + settings.findBin( *++it, binUnit ) ) ); } bins[yy] = nextBin; } @@ -2407,10 +2409,11 @@ void TrackArtist::DrawClipSpectrum(WaveTrackCache &waveTrackCache, } // each xx } // updating cache - float selBinLo = freqLo / binUnit; - float selBinHi = freqHi / binUnit; - float selBinCenter = - ((freqLo < 0 || freqHi < 0) ? -1 : sqrt(freqLo * freqHi)) / binUnit; + float selBinLo = settings.findBin( freqLo, binUnit); + float selBinHi = settings.findBin( freqHi, binUnit); + float selBinCenter = (freqLo < 0 || freqHi < 0) + ? -1 + : settings.findBin( sqrt(freqLo * freqHi), binUnit ); const bool isSpectral = settings.SpectralSelectionEnabled(); const bool hidden = (ZoomInfo::HIDDEN == zoomInfo.GetFisheyeState()); diff --git a/src/TrackPanel.cpp b/src/TrackPanel.cpp index 43e912956..b9946ab6a 100644 --- a/src/TrackPanel.cpp +++ b/src/TrackPanel.cpp @@ -2988,7 +2988,7 @@ double TrackPanel::PositionToFrequency(const WaveTrack *wt, const SpectrogramSettings &settings = wt->GetSpectrogramSettings(); float minFreq, maxFreq; wt->GetSpectrumBounds(&minFreq, &maxFreq); - const NumberScale numberScale(settings.GetScale(minFreq, maxFreq, rate, false)); + const NumberScale numberScale( settings.GetScale( minFreq, maxFreq ) ); const double p = double(mouseYCoordinate - trackTopEdge) / trackHeight; return numberScale.PositionToValue(1.0 - p); } @@ -3004,7 +3004,7 @@ wxInt64 TrackPanel::FrequencyToPosition(const WaveTrack *wt, const SpectrogramSettings &settings = wt->GetSpectrogramSettings(); float minFreq, maxFreq; wt->GetSpectrumBounds(&minFreq, &maxFreq); - const NumberScale numberScale(settings.GetScale(minFreq, maxFreq, rate, false)); + const NumberScale numberScale( settings.GetScale( minFreq, maxFreq ) ); const float p = numberScale.ValueToPosition(frequency); return trackTopEdge + wxInt64((1.0 - p) * trackHeight); } @@ -4232,7 +4232,7 @@ void TrackPanel::HandleWaveTrackVZoom if (spectral) { track->GetSpectrumBounds(&min, &max); - scale = (settings.GetScale(min, max, rate, false)); + scale = settings.GetScale( min, max ); const auto fftLength = settings.GetFFTLength(); const float binSize = rate / fftLength; @@ -5865,7 +5865,7 @@ void TrackPanel::HandleWheelRotationInVRuler wt->GetSpectrumBounds(&bottom, &top); const double rate = wt->GetRate(); const float bound = rate / 2; - const NumberScale numberScale(settings.GetScale(bottom, top, rate, false)); + const NumberScale numberScale( settings.GetScale( bottom, top ) ); float newTop = std::min(bound, numberScale.PositionToValue(1.0f + delta)); const float newBottom = diff --git a/src/prefs/SpectrogramSettings.cpp b/src/prefs/SpectrogramSettings.cpp index 194b6cdf2..c46370027 100644 --- a/src/prefs/SpectrogramSettings.cpp +++ b/src/prefs/SpectrogramSettings.cpp @@ -475,6 +475,15 @@ void SpectrogramSettings::ConvertToActualWindowSizes() #endif } +float SpectrogramSettings::findBin( float frequency, float binUnit ) const +{ + float linearBin = frequency / binUnit; + if (linearBin < 0) + return -1; + else + return linearBin; +} + size_t SpectrogramSettings::GetFFTLength() const { return windowSize @@ -484,11 +493,9 @@ size_t SpectrogramSettings::GetFFTLength() const ; } -NumberScale SpectrogramSettings::GetScale -(float minFreq, float maxFreq, double rate, bool bins) const +NumberScale SpectrogramSettings::GetScale( float minFreq, float maxFreq ) const { NumberScaleType type = nstLinear; - const auto half = GetFFTLength() / 2; // Don't assume the correspondence of the enums will remain direct in the future. // Do this switch. @@ -509,8 +516,7 @@ NumberScale SpectrogramSettings::GetScale type = nstPeriod; break; } - return NumberScale(type, minFreq, maxFreq, - bins ? rate / (2 * half) : 1.0f); + return NumberScale(type, minFreq, maxFreq); } bool SpectrogramSettings::SpectralSelectionEnabled() const diff --git a/src/prefs/SpectrogramSettings.h b/src/prefs/SpectrogramSettings.h index 5eb8eea3c..30510b811 100644 --- a/src/prefs/SpectrogramSettings.h +++ b/src/prefs/SpectrogramSettings.h @@ -85,9 +85,12 @@ public: void ConvertToEnumeratedWindowSizes(); void ConvertToActualWindowSizes(); + // Need to be told what the bin unit is, as this structure does not know + // the rate + float findBin( float frequency, float binUnit ) const; + // If "bins" is false, units are Hz - NumberScale GetScale - (float minFreq, float maxFreq, double rate, bool bins) const; + NumberScale GetScale( float minFreq, float maxFreq ) const; int minFreq; int maxFreq; diff --git a/src/widgets/Ruler.cpp b/src/widgets/Ruler.cpp index 927e9428d..938231845 100644 --- a/src/widgets/Ruler.cpp +++ b/src/widgets/Ruler.cpp @@ -1183,7 +1183,7 @@ void Ruler::Update(const TimeTrack* timetrack)// Envelope *speedEnv, long minSpe NumberScale numberScale(mpNumberScale ? *mpNumberScale - : NumberScale(nstLogarithmic, mMin, mMax, 1.0f) + : NumberScale(nstLogarithmic, mMin, mMax) ); mDigits=2; //TODO: implement dynamic digit computation