From 8b66fc4b05adb1709c6f20a09656a39f38ac27bb Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Fri, 28 Oct 2016 11:56:15 -0400 Subject: [PATCH] Restore change of Waveform dB scale with change of magnification... ... This is done with Shift+Ctrl+wheel and pointer in the vertical ruler, and the pointer y coordinate near the bottom of the dB scale. If y coordinate is far from there, then Shift+Ctrl+wheel changes dB level without change of magnification (as before this commit). --- src/TrackArtist.cpp | 10 ++++++---- src/TrackArtist.h | 1 + src/TrackPanel.cpp | 28 ++++++++++++++++++++-------- src/WaveTrack.cpp | 6 ++++++ src/WaveTrack.h | 4 ++++ 5 files changed, 37 insertions(+), 12 deletions(-) diff --git a/src/TrackArtist.cpp b/src/TrackArtist.cpp index 34bf44b1c..7d4385d33 100644 --- a/src/TrackArtist.cpp +++ b/src/TrackArtist.cpp @@ -1028,6 +1028,7 @@ void TrackArtist::DrawNegativeOffsetTrackArrows(wxDC &dc, const wxRect &rect) void TrackArtist::DrawWaveformBackground(wxDC &dc, int leftOffset, const wxRect &rect, const double env[], float zoomMin, float zoomMax, + int zeroLevelYCoordinate, bool dB, float dBRange, double t0, double t1, const ZoomInfo &zoomInfo, @@ -1134,11 +1135,11 @@ void TrackArtist::DrawWaveformBackground(wxDC &dc, int leftOffset, const wxRect //OK, the display bounds are between min and max, which //is spread across rect.height. Draw the line at the proper place. - - if (zoomMin < 0 && zoomMax > 0) { - int half = (int)((zoomMax / (zoomMax - zoomMin)) * h); + if (zeroLevelYCoordinate >= rect.GetTop() && + zeroLevelYCoordinate <= rect.GetBottom()) { dc.SetPen(*wxBLACK_PEN); - AColor::Line(dc, rect.x, rect.y + half, rect.x + rect.width, rect.y + half); + AColor::Line(dc, rect.x, zeroLevelYCoordinate, + rect.x + rect.width, zeroLevelYCoordinate); } } @@ -1788,6 +1789,7 @@ void TrackArtist::DrawClipWaveform(const WaveTrack *track, DrawWaveformBackground(dc, leftOffset, mid, env, zoomMin, zoomMax, + track->ZeroLevelYCoordinate(mid), dB, dBRange, t0, t1, zoomInfo, drawEnvelope, !track->GetSelected()); diff --git a/src/TrackArtist.h b/src/TrackArtist.h index 97720a328..f5c76ae4e 100644 --- a/src/TrackArtist.h +++ b/src/TrackArtist.h @@ -142,6 +142,7 @@ class AUDACITY_DLL_API TrackArtist { void DrawWaveformBackground(wxDC & dc, int leftOffset, const wxRect &rect, const double env[], float zoomMin, float zoomMax, + int zeroLevelYCoordinate, bool dB, float dBRange, double t0, double t1, const ZoomInfo &zoomInfo, bool drawEnvelope, bool bIsSyncLockSelected); diff --git a/src/TrackPanel.cpp b/src/TrackPanel.cpp index a97333119..f9153e614 100644 --- a/src/TrackPanel.cpp +++ b/src/TrackPanel.cpp @@ -5861,14 +5861,26 @@ void TrackPanel::HandleWheelRotationInVRuler else settings.NextHigherDBRange(); } - const float extreme = (LINEAR_TO_DB(2) + newdBRange) / newdBRange; - max = std::min(extreme, max * olddBRange / newdBRange); - min = std::max(-extreme, min * olddBRange / newdBRange); - wt->SetLastdBRange(); - wt->SetDisplayBounds(min, max); - if (partner) { - partner->SetLastdBRange(); - partner->SetDisplayBounds(min, max); + + // Is y coordinate within the rectangle half-height centered about + // the zero level? + const auto zeroLevel = wt->ZeroLevelYCoordinate(rect); + const bool fixedMagnification = + (4 * std::abs(event.GetY() - zeroLevel) < rect.GetHeight()); + + if (fixedMagnification) { + // Vary the db limit without changing + // magnification; that is, peaks and troughs move up and down + // rigidly, as parts of the wave near zero are exposed or hidden. + const float extreme = (LINEAR_TO_DB(2) + newdBRange) / newdBRange; + max = std::min(extreme, max * olddBRange / newdBRange); + min = std::max(-extreme, min * olddBRange / newdBRange); + wt->SetLastdBRange(); + wt->SetDisplayBounds(min, max); + if (partner) { + partner->SetLastdBRange(); + partner->SetDisplayBounds(min, max); + } } } } diff --git a/src/WaveTrack.cpp b/src/WaveTrack.cpp index ae6f4f8a1..4c55d6228 100644 --- a/src/WaveTrack.cpp +++ b/src/WaveTrack.cpp @@ -350,6 +350,12 @@ void WaveTrack::SetSpectrumBounds(float min, float max) const mSpectrumMax = max; } +int WaveTrack::ZeroLevelYCoordinate(wxRect rect) const +{ + return rect.GetTop() + + (int)((mDisplayMax / (mDisplayMax - mDisplayMin)) * rect.height); +} + Track::Holder WaveTrack::Duplicate() const { return Track::Holder{ safenew WaveTrack{ *this } }; diff --git a/src/WaveTrack.h b/src/WaveTrack.h index 616f024fc..96acb034c 100644 --- a/src/WaveTrack.h +++ b/src/WaveTrack.h @@ -550,6 +550,10 @@ class AUDACITY_DLL_API WaveTrack final : public Track { void GetSpectrumBounds(float *min, float *max) const; void SetSpectrumBounds(float min, float max) const; + // For display purposes, calculate the y coordinate where the midline of + // the wave should be drawn, if display minimum and maximum map to the + // bottom and top. Maybe that is out of bounds. + int ZeroLevelYCoordinate(wxRect rect) const; protected: //