From c929932f30446c3697d883ee2055e27f15cf3924 Mon Sep 17 00:00:00 2001 From: James Crook Date: Thu, 16 Jul 2015 17:17:50 +0100 Subject: [PATCH 01/36] IsAlpha1 and now 2.1.2. --- src/Audacity.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Audacity.h b/src/Audacity.h index e4341cc0d..7b934bca4 100644 --- a/src/Audacity.h +++ b/src/Audacity.h @@ -27,12 +27,12 @@ // We only do alpha builds and release versions. // Most of the time we're in development, so IS_ALPHA should be defined // to 1. -#define IS_ALPHA 0 +#define IS_ALPHA 1 // Increment as appropriate every time we release a new version. #define AUDACITY_VERSION 2 #define AUDACITY_RELEASE 1 -#define AUDACITY_REVISION 1 +#define AUDACITY_REVISION 2 #define AUDACITY_MODLEVEL 0 #if IS_ALPHA From 94851d5238113120a1ca5682314ec2965d6ae2c6 Mon Sep 17 00:00:00 2001 From: James Crook Date: Thu, 16 Jul 2015 20:08:52 +0100 Subject: [PATCH 02/36] Now on 2.1.2 --- audacity.dox | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/audacity.dox b/audacity.dox index 30eeb0b90..b78fec492 100644 --- a/audacity.dox +++ b/audacity.dox @@ -31,7 +31,7 @@ PROJECT_NAME = Audacity # This could be handy for archiving the generated documentation or # if some version control system is used. -PROJECT_NUMBER = 2.1.1 +PROJECT_NUMBER = 2.1.2 # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. From fd958cfea349e94dfa1c11f148e20c0a92a0f3a8 Mon Sep 17 00:00:00 2001 From: James Crook Date: Thu, 16 Jul 2015 20:11:59 +0100 Subject: [PATCH 03/36] Updated for 2.1.2 --- win/compile.txt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/win/compile.txt b/win/compile.txt index 3bff26950..176eb9c61 100644 --- a/win/compile.txt +++ b/win/compile.txt @@ -14,7 +14,7 @@ Authors: Martyn Shaw ======================================================================== -This document is for Audacity version 2.1.0. +This document is for Audacity version 2.1.2. If the advice here is inaccurate or incomplete, email audacity-devel@lists.sourceforge.net. @@ -41,7 +41,8 @@ To simplify the implementation of a near-identical user interface across platforms, Audacity uses wxWidgets, a GUI framework. -Audacity 2.1.0 requires wxWidgets 2.8.12. +Audacity 2.1.2 currently requires wxWidgets 2.8.12. +(we're transitioning to wxWidgets 3.0.2. during this release...) To be able to build Audacity for Windows, download and install wxWidgets from http://www.wxwidgets.org/. From c43936f63018133525c26170fa9fbda65bac4dcf Mon Sep 17 00:00:00 2001 From: James Crook Date: Sat, 18 Jul 2015 12:49:10 +0100 Subject: [PATCH 04/36] Bug1085 - Play-at-Speed key-binding broken Caused by fix to Bug 844 not initialising mIsCapturing to false. So play-at-apeed could mistakenly think recording was in progress, and so prevent play-at-speed. --- src/Project.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Project.cpp b/src/Project.cpp index 791d5e456..7bd975546 100644 --- a/src/Project.cpp +++ b/src/Project.cpp @@ -772,6 +772,7 @@ AudacityProject::AudacityProject(wxWindow * parent, wxWindowID id, mImportXMLTagHandler(NULL), mAutoSaving(false), mIsRecovered(false), + mIsCapturing(false), mRecordingRecoveryHandler(NULL), mImportedDependencies(false), mWantSaveCompressed(false), From 78d0347be2adf3bfcd785afdcb08b6a301a65f31 Mon Sep 17 00:00:00 2001 From: Steve Daulton Date: Sat, 18 Jul 2015 18:31:36 +0100 Subject: [PATCH 05/36] More complete fix for bug 1060 issues --- src/effects/Effect.cpp | 5 +++++ src/effects/Effect.h | 1 + src/effects/Repeat.cpp | 43 ++++++++++++++++++++++++++---------------- src/effects/Repeat.h | 1 + 4 files changed, 34 insertions(+), 16 deletions(-) diff --git a/src/effects/Effect.cpp b/src/effects/Effect.cpp index 1e89a9779..a1dd1f2b0 100644 --- a/src/effects/Effect.cpp +++ b/src/effects/Effect.cpp @@ -724,6 +724,11 @@ wxString Effect::GetDurationFormat() return mDurationFormat; } +wxString Effect::GetSelectionFormat() +{ + return GetActiveProject()->GetSelectionFormat(); +} + void Effect::SetDuration(double seconds) { if (seconds < 0.0) diff --git a/src/effects/Effect.h b/src/effects/Effect.h index 0fcc070f7..350300ca4 100644 --- a/src/effects/Effect.h +++ b/src/effects/Effect.h @@ -146,6 +146,7 @@ class AUDACITY_DLL_API Effect : public wxEvtHandler, virtual double GetDefaultDuration(); virtual double GetDuration(); virtual wxString GetDurationFormat(); + virtual wxString GetSelectionFormat(); // time format in Selection toolbar virtual void SetDuration(double duration); virtual bool Apply(); diff --git a/src/effects/Repeat.cpp b/src/effects/Repeat.cpp index 4e82c67c7..e7422727d 100644 --- a/src/effects/Repeat.cpp +++ b/src/effects/Repeat.cpp @@ -38,7 +38,7 @@ // Define keys, defaults, minimums, and maximums for the effect parameters // // Name Type Key Def Min Max Scale -Param( Count, int, XO("Count"), 10, 1, INT_MAX, 1 ); +Param( Count, int, XO("Count"), 1, 1, INT_MAX, 1 ); BEGIN_EVENT_TABLE(EffectRepeat, wxEvtHandler) EVT_TEXT(wxID_ANY, EffectRepeat::OnRepeatTextChange) @@ -46,7 +46,7 @@ END_EVENT_TABLE() EffectRepeat::EffectRepeat() { - repeatCount = 10; + repeatCount = DEF_Count; SetLinearEffectFlag(true); } @@ -175,16 +175,17 @@ void EffectRepeat::PopulateOrExchange(ShuttleGui & S) { IntegerValidator vldRepeatCount(&repeatCount); vldRepeatCount.SetRange(MIN_Count, 2147483647 / mProjectRate); - mRepeatCount = S.AddTextBox(_("Number of times to repeat:"), wxT(""), 12); + mRepeatCount = S.AddTextBox(_("Number of repeats to add:"), wxT(""), 12); mRepeatCount->SetValidator(vldRepeatCount); } S.EndHorizontalLay(); - S.StartHorizontalLay(wxCENTER, true); + S.StartMultiColumn(1, wxCENTER); { + mCurrentTime = S.AddVariableText(_("Current selection length: dd:hh:mm:ss")); mTotalTime = S.AddVariableText(_("New selection length: dd:hh:mm:ss")); } - S.EndHorizontalLay(); + S.EndMultiColumn(); } bool EffectRepeat::TransferDataToWindow() @@ -215,22 +216,32 @@ bool EffectRepeat::TransferDataFromWindow() void EffectRepeat::DisplayNewTime() { long l; + wxString str; mRepeatCount->GetValue().ToLong(&l); - if (l > 0) - { + NumericConverter nc(NumericConverter::TIME, + GetSelectionFormat(), + mT1 - mT0, + mProjectRate); + + str = _("Current selection length: ") + nc.GetString(); + + mCurrentTime->SetLabel(str); + mCurrentTime->SetName(str); // fix for bug 577 (NVDA/Narrator screen readers do not read static text in dialogs) + + if (l > 0) { + EnableApply(true); repeatCount = l; - NumericConverter nc(NumericConverter::TIME, - _("hh:mm:ss"), - (mT1 - mT0) * (repeatCount + 1), - mProjectRate); - - wxString str = _("New selection length: ") + nc.GetString(); - - mTotalTime->SetLabel(str); - mTotalTime->SetName(str); // fix for bug 577 (NVDA/Narrator screen readers do not read static text in dialogs) + nc.SetValue((mT1 - mT0) * (repeatCount + 1)); + str = _("New selection length: ") + nc.GetString(); } + else { + str = _("Warning: No repeats."); + EnableApply(false); + } + mTotalTime->SetLabel(str); + mTotalTime->SetName(str); // fix for bug 577 (NVDA/Narrator screen readers do not read static text in dialogs) } void EffectRepeat::OnRepeatTextChange(wxCommandEvent & WXUNUSED(evt)) diff --git a/src/effects/Repeat.h b/src/effects/Repeat.h index dd0be1405..1f5284d45 100644 --- a/src/effects/Repeat.h +++ b/src/effects/Repeat.h @@ -59,6 +59,7 @@ private: int repeatCount; wxTextCtrl *mRepeatCount; + wxStaticText *mCurrentTime; wxStaticText *mTotalTime; DECLARE_EVENT_TABLE(); From b25994a82d4e11163c39518d0f3d83c5c0b3371f Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Sat, 13 Jun 2015 09:16:32 -0400 Subject: [PATCH 06/36] Throw away EXPERIMENTAL_FFT_SKIP_POINTS... ... with James' consent. --- src/Experimental.h | 4 --- src/TrackArtist.cpp | 38 ----------------------- src/TrackArtist.h | 4 --- src/TrackPanel.cpp | 9 ------ src/WaveClip.cpp | 62 +------------------------------------ src/prefs/SpectrumPrefs.cpp | 33 -------------------- src/prefs/SpectrumPrefs.h | 4 --- 7 files changed, 1 insertion(+), 153 deletions(-) diff --git a/src/Experimental.h b/src/Experimental.h index 3f271f1f2..f2589b621 100644 --- a/src/Experimental.h +++ b/src/Experimental.h @@ -86,10 +86,6 @@ // to activate it instead of the Spectrum log(f) mode. //#define EXPERIMENTAL_FIND_NOTES -// AM, 22.Nov 2007 -// Skip Points support in the spectrum view mode. -//#define EXPERIMENTAL_FFT_SKIP_POINTS - // AM, 22.Nov 2007: // A Frequency Grid for the Spectrum Log(f) & Find Notes modes //#define EXPERIMENTAL_FFT_Y_GRID diff --git a/src/TrackArtist.cpp b/src/TrackArtist.cpp index ab0874291..2f832ac3f 100644 --- a/src/TrackArtist.cpp +++ b/src/TrackArtist.cpp @@ -665,10 +665,6 @@ void TrackArtist::DrawVRuler(Track *t, wxDC * dc, wxRect & r) void TrackArtist::UpdateVRuler(Track *t, wxRect & r) { -#ifdef EXPERIMENTAL_FFT_SKIP_POINTS - const int fftSkipPoints = SpectrogramSettings::defaults().fftSkipPoints; -#endif //EXPERIMENTAL_FFT_SKIP_POINTS - // Label tracks do not have a vruler if (t->GetKind() == Track::Label) { return; @@ -807,16 +803,10 @@ void TrackArtist::UpdateVRuler(Track *t, wxRect & r) int freq = lrint(rate/2.); int maxFreq = GetSpectrumMaxFreq(freq); -#ifdef EXPERIMENTAL_FFT_SKIP_POINTS - maxFreq/=(fftSkipPoints+1); -#endif //EXPERIMENTAL_FFT_SKIP_POINTS if(maxFreq > freq) maxFreq = freq; int minFreq = GetSpectrumMinFreq(0); -#ifdef EXPERIMENTAL_FFT_SKIP_POINTS - minFreq/=(fftSkipPoints+1); -#endif //EXPERIMENTAL_FFT_SKIP_POINTS if(minFreq < 0) minFreq = 0; @@ -853,16 +843,10 @@ void TrackArtist::UpdateVRuler(Track *t, wxRect & r) int freq = lrint(rate/2.); int maxFreq = GetSpectrumLogMaxFreq(freq); -#ifdef EXPERIMENTAL_FFT_SKIP_POINTS - maxFreq/=(fftSkipPoints+1); -#endif //EXPERIMENTAL_FFT_SKIP_POINTS if(maxFreq > freq) maxFreq = freq; int minFreq = GetSpectrumLogMinFreq(freq/1000.0); -#ifdef EXPERIMENTAL_FFT_SKIP_POINTS - minFreq/=(fftSkipPoints+1); -#endif //EXPERIMENTAL_FFT_SKIP_POINTS if(minFreq < 1) minFreq = 1; @@ -1964,11 +1948,6 @@ void TrackArtist::DrawClipSpectrum(WaveTrackCache &cache, bool updated = clip->GetSpectrogram(cache, freq, where, mid.width, t0, pps, autocorrelation); -#ifdef EXPERIMENTAL_FFT_SKIP_POINTS - int fftSkipPoints = SpectrogramSettings::defaults().fftSkipPoints; - int fftSkipPoints1 = fftSkipPoints + 1; -#endif //EXPERIMENTAL_FFT_SKIP_POINTS - int ifreq = lrint(rate/2); int maxFreq; @@ -2057,14 +2036,8 @@ void TrackArtist::DrawClipSpectrum(WaveTrackCache &cache, #endif #ifdef EXPERIMENTAL_FIND_NOTES -#ifdef EXPERIMENTAL_FFT_SKIP_POINTS - const float - lmins = logf(float(minFreq) / (fftSkipPoints + 1)), - lmaxs = logf(float(maxFreq) / (fftSkipPoints + 1)) -#else //!EXPERIMENTAL_FFT_SKIP_POINTS lmins = lmin, lmaxs = lmax -#endif //EXPERIMENTAL_FFT_SKIP_POINTS ; #endif //EXPERIMENTAL_FIND_NOTES @@ -2072,11 +2045,7 @@ void TrackArtist::DrawClipSpectrum(WaveTrackCache &cache, int maxima[128]; float maxima0[128], maxima1[128]; const float -#ifdef EXPERIMENTAL_FFT_SKIP_POINTS - f2bin = half / (rate / 2.0f / (fftSkipPoints + 1)), -#else //!EXPERIMENTAL_FFT_SKIP_POINTS f2bin = half / (rate / 2.0f), -#endif //EXPERIMENTAL_FFT_SKIP_POINTS bin2f = 1.0f / f2bin, minDistance = powf(2.0f, 2.0f / 12.0f), i0 = expf(lmin) / binUnit, @@ -3086,13 +3055,6 @@ int TrackArtist::GetSpectrumWindowSize(bool includeZeroPadding) return windowSize; } -#ifdef EXPERIMENTAL_FFT_SKIP_POINTS -int TrackArtist::GetSpectrumFftSkipPoints() -{ - return SpectrogramSettings::defaults().fftSkipPoints; -} -#endif - // Set various preference values void TrackArtist::SetSpectrumMinFreq(int freq) { diff --git a/src/TrackArtist.h b/src/TrackArtist.h index a192d0998..1fa32dd8e 100644 --- a/src/TrackArtist.h +++ b/src/TrackArtist.h @@ -76,10 +76,6 @@ class AUDACITY_DLL_API TrackArtist { int GetSpectrumLogMaxFreq(int deffreq); int GetSpectrumWindowSize(bool includeZeroPadding); -#ifdef EXPERIMENTAL_FFT_SKIP_POINTS - int GetSpectrumFftSkipPoints(); -#endif - void SetSpectrumMinFreq(int freq); void SetSpectrumMaxFreq(int freq); void SetSpectrumLogMinFreq(int freq); diff --git a/src/TrackPanel.cpp b/src/TrackPanel.cpp index fbbdc285d..120d85ab7 100644 --- a/src/TrackPanel.cpp +++ b/src/TrackPanel.cpp @@ -4714,9 +4714,6 @@ void TrackPanel::HandleVZoomButtonUp( wxMouseEvent & event ) float min, max, c, l, binSize = 0.0; bool spectrum, spectrumLog; int windowSize; -#ifdef EXPERIMENTAL_FFT_SKIP_POINTS - int fftSkipPoints=0; -#endif //EXPERIMENTAL_FFT_SKIP_POINTS double rate = ((WaveTrack *)track)->GetRate(); spectrum = (((WaveTrack *) track)->GetDisplay() == WaveTrack::SpectrumDisplay) || (((WaveTrack *) track)->GetDisplay() == WaveTrack::SpectralSelectionDisplay) ; @@ -4733,9 +4730,6 @@ void TrackPanel::HandleVZoomButtonUp( wxMouseEvent & event ) // Always spectrogram, never pitch view, pass true windowSize = mTrackArtist->GetSpectrumWindowSize(true); -#ifdef EXPERIMENTAL_FFT_SKIP_POINTS - fftSkipPoints = SpectrogramSettings::defaults().fftSkipPoints; -#endif //EXPERIMENTAL_FFT_SKIP_POINTS binSize = rate / windowSize; minBins = wxMin(10, windowSize/2); //minimum 10 freq bins, unless there are less } @@ -4750,9 +4744,6 @@ void TrackPanel::HandleVZoomButtonUp( wxMouseEvent & event ) // Always spectrogram, never pitch view, pass true windowSize = mTrackArtist->GetSpectrumWindowSize(true); -#ifdef EXPERIMENTAL_FFT_SKIP_POINTS - fftSkipPoints = SpectrogramSettings::defaults().fftSkipPoints; -#endif //EXPERIMENTAL_FFT_SKIP_POINTS binSize = rate / windowSize; minBins = wxMin(10, windowSize/2); //minimum 10 freq bins, unless there are less } diff --git a/src/WaveClip.cpp b/src/WaveClip.cpp index cd6a1b22d..fd66e7c4c 100644 --- a/src/WaveClip.cpp +++ b/src/WaveClip.cpp @@ -276,9 +276,6 @@ public: , windowSize(-1) , zeroPaddingFactor(-1) , frequencyGain(-1) -#ifdef EXPERIMENTAL_FFT_SKIP_POINTS - , fftSkipPoints(-1) -#endif //EXPERIMENTAL_FFT_SKIP_POINTS , freq(NULL) , where(NULL) @@ -291,10 +288,7 @@ public: SpecCache(int cacheLen, bool autocorrelation, double pps_, double start_, int windowType_, int windowSize_, int zeroPaddingFactor_, int frequencyGain_ -#ifdef EXPERIMENTAL_FFT_SKIP_POINTS - , int fftSkipPoints_ -#endif - ) + ) : len(cacheLen) , ac(autocorrelation) , pps(pps_) @@ -303,9 +297,6 @@ public: , windowSize(windowSize_) , zeroPaddingFactor(zeroPaddingFactor_) , frequencyGain(frequencyGain_) -#ifdef EXPERIMENTAL_FFT_SKIP_POINTS - , fftSkipPoints(fftSkipPoints_) -#endif //EXPERIMENTAL_FFT_SKIP_POINTS // len columns, and so many rows, column-major. // Don't take column literally -- this isn't pixel data yet, it's the @@ -350,9 +341,6 @@ public: const int windowSize; const int zeroPaddingFactor; const int frequencyGain; -#ifdef EXPERIMENTAL_FFT_SKIP_POINTS - const int fftSkipPoints; -#endif //EXPERIMENTAL_FFT_SKIP_POINTS std::vector freq; std::vector where; @@ -833,9 +821,6 @@ bool SpecCache::Matches windowSize == settings.windowSize && zeroPaddingFactor == settings.zeroPaddingFactor && frequencyGain == settings.frequencyGain && -#ifdef EXPERIMENTAL_FFT_SKIP_POINTS - fftSkipPoints == settings.fftSkipPoints && -#endif //EXPERIMENTAL_FFT_SKIP_POINTS ac == autocorrelation; } @@ -847,11 +832,6 @@ void SpecCache::CalculateOneSpectrum bool autocorrelation, const std::vector &gainFactors, float *scratch) { -#ifdef EXPERIMENTAL_FFT_SKIP_POINTS - int fftSkipPoints = settings.fftSkipPoints; - int fftSkipPoints1 = fftSkipPoints + 1; -#endif //EXPERIMENTAL_FFT_SKIP_POINTS - const int windowSize = settings.windowSize; sampleCount start = where[xx]; const int zeroPaddingFactor = (autocorrelation ? 1 : settings.zeroPaddingFactor); @@ -881,15 +861,6 @@ void SpecCache::CalculateOneSpectrum start = 0; copy = true; } -#ifdef EXPERIMENTAL_FFT_SKIP_POINTS - copy = true; - if (start + len*fftSkipPoints1 > numSamples) { - int newlen = (numSamples - start) / fftSkipPoints1; - for (int i = newlen*fftSkipPoints1; i < (sampleCount)len*fftSkipPoints1; i++) - adj[i] = 0; - len = newlen; - } -#else //!EXPERIMENTAL_FFT_SKIP_POINTS if (start + len > numSamples) { // Near the end of the clip, pad right with zeroes as needed. int newlen = numSamples - start; @@ -898,28 +869,13 @@ void SpecCache::CalculateOneSpectrum len = newlen; copy = true; } -#endif //EXPERIMENTAL_FFT_SKIP_POINTS if (len > 0) { // Copy samples out of the track. -#ifdef EXPERIMENTAL_FFT_SKIP_POINTS - useBuffer = (float*)(waveTrackCache.Get(floatSample, - floor(0.5 + start + offset * rate), len*fftSkipPoints1)); - memcpy(adj, useBuffer, len * fftSkipPoints1 * sizeof(float)); - if (fftSkipPoints) { - // TODO: (maybe) alternatively change Get to include skipping of points - int j = 0; - for (int i = 0; i < len; i++) { - adj[i] = adj[j]; - j += fftSkipPoints1; - } - } -#else //!EXPERIMENTAL_FFT_SKIP_POINTS useBuffer = (float*)(waveTrackCache.Get(floatSample, floor(0.5 + start + offset * rate), len)); if (copy) memcpy(adj, useBuffer, len * sizeof(float)); -#endif //EXPERIMENTAL_FFT_SKIP_POINTS } if (copy) @@ -961,11 +917,6 @@ void SpecCache::Populate settings.CacheWindows(); #endif -#ifdef EXPERIMENTAL_FFT_SKIP_POINTS - int fftSkipPoints = settings.fftSkipPoints; - int fftSkipPoints1 = fftSkipPoints + 1; -#endif //EXPERIMENTAL_FFT_SKIP_POINTS - const int &frequencyGain = settings.frequencyGain; const int &windowSize = settings.windowSize; #ifdef EXPERIMENTAL_ZERO_PADDED_SPECTROGRAMS @@ -979,11 +930,7 @@ void SpecCache::Populate const int fftLen = windowSize * zeroPaddingFactor; std::vector buffer( -#ifdef EXPERIMENTAL_FFT_SKIP_POINTS - fftLen*fftSkipPoints1 -#else //!EXPERIMENTAL_FFT_SKIP_POINTS fftLen -#endif //EXPERIMENTAL_FFT_SKIP_POINTS ); std::vector gainFactors; @@ -1009,10 +956,6 @@ bool WaveClip::GetSpectrogram(WaveTrackCache &waveTrackCache, { const SpectrogramSettings &settings = SpectrogramSettings::defaults(); -#ifdef EXPERIMENTAL_FFT_SKIP_POINTS - int fftSkipPoints = settings.fftSkipPoints; -#endif //EXPERIMENTAL_FFT_SKIP_POINTS - const int &frequencyGain = settings.frequencyGain; const int &windowSize = settings.windowSize; const int &windowType = settings.windowType; @@ -1070,9 +1013,6 @@ bool WaveClip::GetSpectrogram(WaveTrackCache &waveTrackCache, mSpecCache = new SpecCache( numPixels, autocorrelation, pixelsPerSecond, t0, windowType, windowSize, zeroPaddingFactor, frequencyGain -#ifdef EXPERIMENTAL_FFT_SKIP_POINTS - , fftSkipPoints -#endif ); fillWhere(mSpecCache->where, numPixels, 0.5, correction, diff --git a/src/prefs/SpectrumPrefs.cpp b/src/prefs/SpectrumPrefs.cpp index 6d3f405ac..118df5a38 100644 --- a/src/prefs/SpectrumPrefs.cpp +++ b/src/prefs/SpectrumPrefs.cpp @@ -164,35 +164,6 @@ void SpectrumPrefs::PopulateOrExchange(ShuttleGui & S) } S.EndStatic(); -#ifdef EXPERIMENTAL_FFT_SKIP_POINTS -// Search and replace with _ if you want translation. -#define TRANSLATABLE( x ) wxT(x) - wxArrayString wskipn; - wxArrayInt wskipv; - - for (size_t i = 0; i < 7; i++) { - wskipn.Add(wxString::Format(wxT("%d"), (1 << i) - 1)); - wskipv.Add((1 << i) - 1); - } - - /* /////i18n-hint: (noun) Experimental. Don't know what it does. Don't translate.*/ - S.StartStatic(TRANSLATABLE("FFT Skip Points")); - { - S.StartMultiColumn(2); - { - /* /////i18n-hint: (noun) here the user chooses points to skip.*/ - S.TieChoice(TRANSLATABLE("Skip Points:"), - wxT("/Spectrum/FFTSkipPoints"), - 0, - wskipn, - wskipv); - S.SetSizeHints(wskipn); - } - S.EndMultiColumn(); - } - S.EndStatic(); -#endif //EXPERIMENTAL_FFT_SKIP_POINTS - S.StartStatic(_("Display")); { S.StartTwoColumn(); @@ -430,10 +401,6 @@ void SpectrogramSettings::UpdatePrefs() isGrayscale = (gPrefs->Read(wxT("/Spectrum/Grayscale"), 0L) != 0); -#ifdef EXPERIMENTAL_FFT_SKIP_POINTS - fftSkipPoints = gPrefs->Read(wxT("/Spectrum/FFTSkipPoints"), 0L); -#endif - #ifdef EXPERIMENTAL_FFT_Y_GRID fftYGrid = (gPrefs->Read(wxT("/Spectrum/FFTYGrid"), 0L) != 0); #endif //EXPERIMENTAL_FFT_Y_GRID diff --git a/src/prefs/SpectrumPrefs.h b/src/prefs/SpectrumPrefs.h index 61cc0f89b..2fb9c8fa8 100644 --- a/src/prefs/SpectrumPrefs.h +++ b/src/prefs/SpectrumPrefs.h @@ -103,10 +103,6 @@ public: bool isGrayscale; -#ifdef EXPERIMENTAL_FFT_SKIP_POINTS - int fftSkipPoints; -#endif - #ifdef EXPERIMENTAL_FFT_Y_GRID bool fftYGrid; #endif //EXPERIMENTAL_FFT_Y_GRID From 508abda309b570d156cc6b1bd7b25661cdd4ea37 Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Tue, 23 Jun 2015 10:49:45 -0400 Subject: [PATCH 07/36] Bugs 1043, 1044 -- Even better fix... ... With a careful sweep of uses of WaveTrack::GetDisplay() to remove assumptions about the ordering of the values. Using < and <= on enum values is mostly a bad idea. --- src/TrackPanel.cpp | 37 ++++++++++++++++++++++++++++--------- src/WaveTrack.h | 2 +- src/prefs/TracksPrefs.cpp | 24 +++++++++++++++--------- 3 files changed, 44 insertions(+), 19 deletions(-) diff --git a/src/TrackPanel.cpp b/src/TrackPanel.cpp index 120d85ab7..4b790b268 100644 --- a/src/TrackPanel.cpp +++ b/src/TrackPanel.cpp @@ -1732,7 +1732,7 @@ void TrackPanel::SetCursorAndTipWhenInLabel( Track * t, { if (event.m_x >= GetVRulerOffset() && (t->GetKind() == Track::Wave) && - ( ((WaveTrack *) t)->GetDisplay() <= WaveTrack::SpectralSelectionLogDisplay) ) + ( ((WaveTrack *) t)->GetDisplay() != WaveTrack::PitchDisplay) ) { *ppTip = _("Click to vertically zoom in. Shift-click to zoom out. Drag to specify a zoom region."); SetCursor(event.ShiftDown()? *mZoomOutCursor : *mZoomInCursor); @@ -3854,8 +3854,8 @@ void TrackPanel::ForwardEventToWaveTrackEnvelope(wxMouseEvent & event) // AS: If we're using the right type of display for envelope operations // ie one of the Wave displays - if (display <= 1) { - bool dB = (display == 1); + const bool dB = (display == WaveTrack::WaveformDBDisplay); + if (dB || (display == WaveTrack::WaveformDisplay)) { bool needUpdate; // AS: Then forward our mouse event to the envelope. @@ -4629,7 +4629,7 @@ void TrackPanel::HandleVZoomClick( wxMouseEvent & event ) // don't do anything if track is not wave or Spectrum/log Spectrum if (((mCapturedTrack->GetKind() == Track::Wave) && - (((WaveTrack*)mCapturedTrack)->GetDisplay() <= WaveTrack::SpectralSelectionLogDisplay)) + (((WaveTrack*)mCapturedTrack)->GetDisplay() != WaveTrack::PitchDisplay)) #ifdef USE_MIDI || mCapturedTrack->GetKind() == Track::Note #endif @@ -7016,11 +7016,13 @@ bool TrackPanel::HitTestEnvelope(Track *track, wxRect &r, wxMouseEvent & event) int displayType = wavetrack->GetDisplay(); // Not an envelope hit, unless we're using a type of wavetrack display // suitable for envelopes operations, ie one of the Wave displays. - if ( displayType > 1) + const bool dB = (displayType == WaveTrack::WaveformDBDisplay); + if (! + (dB || (displayType == WaveTrack::WaveformDisplay)) + ) return false; // No envelope, not a hit, so return. // Get envelope point, range 0.0 to 1.0 - bool dB = (displayType == 1); double envValue = envelope->GetValueAtX( event.m_x, r, mViewInfo->h, mViewInfo->zoom ); @@ -8979,12 +8981,29 @@ void TrackPanel::OnMergeStereo(wxCommandEvent & WXUNUSED(event)) /// wxT("spectrum"), wxT("pitch") }; void TrackPanel::OnSetDisplay(wxCommandEvent & event) { - int id = event.GetId(); - wxASSERT(id >= OnWaveformID && id <= OnPitchID); + int idInt = event.GetId(); + wxASSERT(idInt >= OnWaveformID && idInt <= OnPitchID); wxASSERT(mPopupMenuTarget && mPopupMenuTarget->GetKind() == Track::Wave); - id -= OnWaveformID; + WaveTrack::WaveTrackDisplay id; + switch (idInt) { + default: + case OnWaveformID: + id = WaveTrack::WaveformDisplay; break; + case OnWaveformDBID: + id = WaveTrack::WaveformDBDisplay; break; + case OnSpectrumID: + id = WaveTrack::SpectralSelectionDisplay; break; + case OnSpectrumLogID: + id = WaveTrack::SpectralSelectionLogDisplay; break; + case OnSpectralSelID: + id = WaveTrack::SpectralSelectionDisplay; break; + case OnSpectralSelLogID: + id = WaveTrack::SpectralSelectionLogDisplay; break; + case OnPitchID: + id = WaveTrack::PitchDisplay; break; + } WaveTrack *wt = (WaveTrack *) mPopupMenuTarget; if (wt->GetDisplay() != id) { wt->SetDisplay(WaveTrack::WaveTrackDisplay(id)); diff --git a/src/WaveTrack.h b/src/WaveTrack.h index 5132addd5..065f64948 100644 --- a/src/WaveTrack.h +++ b/src/WaveTrack.h @@ -444,7 +444,7 @@ class AUDACITY_DLL_API WaveTrack: public Track { if( mDisplay == SpectralSelectionLogDisplay ){ } } - int GetDisplay() const {return mDisplay;} + WaveTrackDisplay GetDisplay() const { return mDisplay; } int GetLastDisplay() {return mLastDisplay;} void GetDisplayBounds(float *min, float *max); diff --git a/src/prefs/TracksPrefs.cpp b/src/prefs/TracksPrefs.cpp index 37ec58fb3..925c20888 100644 --- a/src/prefs/TracksPrefs.cpp +++ b/src/prefs/TracksPrefs.cpp @@ -56,23 +56,29 @@ void TracksPrefs::Populate() mSoloChoices.Add(_("None")); - // Keep the same order as in TrackPanel.cpp menu: OnWaveformID, OnWaveformDBID, OnSpectrumID, OnSpectrumLogID, - // OnSpectralSelID, OnSpectralSelLogID, OnPitchID - mViewCodes.Add(0); - mViewCodes.Add(1); - mViewCodes.Add(2); - mViewCodes.Add(3); - mViewCodes.Add(4); - mViewCodes.Add(5); - mViewCodes.Add(6); + // Keep view choices and codes in proper correspondence -- + // we don't display them by increasing integer values. mViewChoices.Add(_("Waveform")); + mViewCodes.Add(int(WaveTrack::WaveformDisplay)); + 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(_("Pitch (EAC)")); + mViewCodes.Add(int(WaveTrack::PitchDisplay)); //------------------------- Main section -------------------- // Now construct the GUI itself. From a8af55d805282accedd751e1a01008103eeee932 Mon Sep 17 00:00:00 2001 From: James Crook Date: Sun, 19 Jul 2015 11:13:39 +0100 Subject: [PATCH 08/36] Added two more wxWidgets DLLs. --- win/compile.txt | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/win/compile.txt b/win/compile.txt index 176eb9c61..3a0a7855b 100644 --- a/win/compile.txt +++ b/win/compile.txt @@ -101,16 +101,18 @@ MSVC++ STEP 2: Build wxWidgets See "MSVC++ STEP 6: Build Audacity" for the differences between these versions of Audacity. - For Audacity, you need only the following five projects + For Audacity, you need only the following seven projects to build (not the whole solution) for each configuration: * adv * base * core * html * net + * qa + * xml Building only these will give you a faster build, and possibly smaller wxWidgets DLLs. - To do this, Ctrl-select those 5 projects in the Solution Explorer. + To do this, Ctrl-select those 7 projects in the Solution Explorer. Then right-click and choose Build Selection (or Rebuild Selection). Because of dependencies, this should also build the @@ -263,7 +265,7 @@ command. MSVC++ STEP 7: Provide Access to the wxWidgets DLLs ------------------------------------------------------------------------ -Each Audacity executable needs access to five specific wxWidgets +Each Audacity executable needs access to seven specific wxWidgets DLLs from those you built in "MSVC++ STEP 2: Build wxWidgets" above. You can copy them to your Windows PATH, or more simply, to the same directory as the executable. If you are building @@ -276,7 +278,9 @@ are at "C:\wxWidgets-2.8.12\lib\vc_dll": wxmsw28*_adv_vc_custom.dll wxmsw28*_core_vc_custom.dll wxmsw28*_html_vc_custom.dll - + wxbase28*_xml_vc_custom.dll + wxmsw28*_qa_vc_custom.dll + The "*" in the file names above is replaced in the actual files by a suffix specific to its Widgets configuration. You can identify the DLLs needed for each Audacity version as follows: @@ -291,6 +295,8 @@ So for instance, a Debug version of Audacity should have: wxmsw28ud_adv_vc_custom.dll wxmsw28ud_core_vc_custom.dll wxmsw28ud_html_vc_custom.dll + wxbase28ud_xml_vc_custom.dll + wxmsw28ud_qa_vc_custom.dll in the "audacity\win\Debug" directory. From b759cc5483b3aa720879fac9a6a8fe612337f621 Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Tue, 9 Jun 2015 15:37:28 -0400 Subject: [PATCH 09/36] collapse some repeated code into a loop --- src/widgets/Ruler.cpp | 71 +++++++++++++++---------------------------- 1 file changed, 25 insertions(+), 46 deletions(-) diff --git a/src/widgets/Ruler.cpp b/src/widgets/Ruler.cpp index 81f0308c6..0c4455f0e 100644 --- a/src/widgets/Ruler.cpp +++ b/src/widgets/Ruler.cpp @@ -79,7 +79,7 @@ array of Ruler::Label. #include "../Prefs.h" #include "../Snap.h" -#define max(a,b) ( (a 0.0? 1.0: -1.0; - // Major ticks - double d, warpedD; - d = mMin - UPP/2; - if(timetrack) - warpedD = timetrack->ComputeWarpedLength(0.0, d); - else - warpedD = d; - // using ints for majorint doesn't work, as - // majorint will overflow and be negative at high zoom. - double majorInt = floor(sg * warpedD / mMajor); - i = -1; - while(i <= mLength) { - i++; - if(timetrack) - warpedD += timetrack->ComputeWarpedLength(d, d + UPP); + // Major and minor ticks + for (int jj = 0; jj < 2; ++jj) { + const double denom = jj == 0 ? mMajor : mMinor; + double d, warpedD; + d = mMin - UPP / 2; + if (timetrack) + warpedD = timetrack->ComputeWarpedLength(0.0, d); else - warpedD += UPP; - d += UPP; + warpedD = d; + // using ints doesn't work, as + // this will overflow and be negative at high zoom. + double step = floor(sg * warpedD / denom); + i = -1; + while (i <= mLength) { + i++; + if (timetrack) + warpedD += timetrack->ComputeWarpedLength(d, d + UPP); + else + warpedD += UPP; + d += UPP; - if (floor(sg * warpedD / mMajor) > majorInt) { - majorInt = floor(sg * warpedD / mMajor); - Tick(i, sg * majorInt * mMajor, true, false); - } - } - - // Minor ticks - d = mMin - UPP/2; - if(timetrack) - warpedD = timetrack->ComputeWarpedLength(0.0, d); - else - warpedD = d; - // using ints for majorint doesn't work, as - // majorint will overflow and be negative at high zoom. - // MB: I assume the same applies to minorInt - double minorInt = floor(sg * warpedD / mMinor); - i = -1; - while(i <= mLength) { - i++; - if(timetrack) - warpedD += timetrack->ComputeWarpedLength(d, d + UPP); - else - warpedD += UPP; - d += UPP; - - if (floor(sg * warpedD / mMinor) > minorInt) { - minorInt = floor(sg * warpedD / mMinor); - Tick(i, sg * minorInt * mMinor, false, true); + if (floor(sg * warpedD / denom) > step) { + step = floor(sg * warpedD / denom); + bool major = jj == 0; + Tick(i, sg * step * denom, major, !major); + } } } From 68174ad657be9cd3ff83c68645e7a13db1646378 Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Tue, 9 Jun 2015 10:58:09 -0400 Subject: [PATCH 10/36] Envelope::GetValue works faster when called in a loop with increasing arugments --- src/Envelope.cpp | 36 +++++++++++++++++++++++++++++++++--- src/Envelope.h | 2 ++ 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/src/Envelope.cpp b/src/Envelope.cpp index 61b719e47..91f6edda5 100644 --- a/src/Envelope.cpp +++ b/src/Envelope.cpp @@ -65,6 +65,8 @@ Envelope::Envelope() mMaxValue = 2.0; mButton = wxMOUSE_BTN_NONE; + + mSearchGuess = -1; } Envelope::~Envelope() @@ -1023,6 +1025,7 @@ void Envelope::SetTrackLen(double trackLen) // Accessors double Envelope::GetValue(double t) const { + // t is absolute time double temp; GetValues(&temp, 1, t, 1.0); @@ -1037,14 +1040,38 @@ double Envelope::GetValueAtX(int x, const wxRect & r, double h, double pps) return GetValue(t); } -/// @param Lo returns index before this time. -/// @param Hi returns index after this time. +/// @param Lo returns last index at or before this time. +/// @param Hi returns first index after this time. void Envelope::BinarySearchForTime( int &Lo, int &Hi, double t ) const { Lo = 0; Hi = mEnv.Count() - 1; // JC: Do we have a problem if the envelope only has one point?? - wxASSERT( Hi > Lo ); + wxASSERT(Hi > Lo); + + // Optimizations for the usual pattern of repeated calls with + // small increases of t. + { + if (mSearchGuess >= 0 && mSearchGuess < int(mEnv.Count()) - 1) { + if (t >= mEnv[mSearchGuess]->GetT() && + t < mEnv[1 + mSearchGuess]->GetT()) { + Lo = mSearchGuess; + Hi = 1 + mSearchGuess; + return; + } + } + + ++mSearchGuess; + if (mSearchGuess >= 0 && mSearchGuess < int(mEnv.Count()) - 1) { + if (t >= mEnv[mSearchGuess]->GetT() && + t < mEnv[1 + mSearchGuess]->GetT()) { + Lo = mSearchGuess; + Hi = 1 + mSearchGuess; + return; + } + } + } + while (Hi > (Lo + 1)) { int mid = (Lo + Hi) / 2; if (t < mEnv[mid]->GetT()) @@ -1053,6 +1080,8 @@ void Envelope::BinarySearchForTime( int &Lo, int &Hi, double t ) const Lo = mid; } wxASSERT( Hi == ( Lo+1 )); + + mSearchGuess = Lo; } /// GetInterpolationStartValueAtPoint() is used to select either the @@ -1072,6 +1101,7 @@ double Envelope::GetInterpolationStartValueAtPoint( int iPoint ) const void Envelope::GetValues(double *buffer, int bufferLen, double t0, double tstep) const { + // Convert t0 from absolute to clip-relative time t0 -= mOffset; // JC: If bufferLen ==0 we have probably just allocated a zero sized buffer. diff --git a/src/Envelope.h b/src/Envelope.h index c1e25bc59..6d33ec9cf 100644 --- a/src/Envelope.h +++ b/src/Envelope.h @@ -248,6 +248,8 @@ private: double lastIntegral_t1; double lastIntegral_result; + mutable int mSearchGuess; + }; inline double EnvPoint::ClampValue(double val) From 9a22b94d99f8a3c88839ab231445f5681b996987 Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Mon, 8 Jun 2015 21:19:41 -0400 Subject: [PATCH 11/36] Change some argument names. I don't like one-letter variable names. --- src/TrackArtist.cpp | 484 ++++++++++++++++++++++---------------------- src/TrackArtist.h | 54 ++--- 2 files changed, 269 insertions(+), 269 deletions(-) diff --git a/src/TrackArtist.cpp b/src/TrackArtist.cpp index 2f832ac3f..b7502b68f 100644 --- a/src/TrackArtist.cpp +++ b/src/TrackArtist.cpp @@ -247,10 +247,10 @@ const int notePos[12] = { 1, 6, 11, 16, 21, 27, // IPITCH_TO_Y above, which computes coordinates relative to GetBottom() // Note the -NOTE_MARGIN, which leaves a little margin to draw notes that // are out of bounds. I'm not sure why the -2 is necessary. -int TrackArtist::GetBottom(NoteTrack *t, const wxRect &r) +int TrackArtist::GetBottom(NoteTrack *t, const wxRect &rect) { int bottomNote = t->GetBottomNote(); - int bottom = r.y + r.height - 2 - t->GetNoteMargin() + + int bottom = rect.y + rect.height - 2 - t->GetNoteMargin() + ((bottomNote / 12) * octaveHeight + notePos[bottomNote % 12]); return bottom; @@ -316,14 +316,14 @@ void TrackArtist::DrawTracks(TrackList * tracks, Track * start, wxDC & dc, wxRegion & reg, - wxRect & r, + wxRect & rect, wxRect & clip, ViewInfo * viewInfo, bool drawEnvelope, - bool drawSamples, + bool bigPoints, bool drawSliders) { - wxRect trackRect = r; + wxRect trackRect = rect; wxRect stereoTrackRect; TrackListIterator iter(tracks); @@ -344,7 +344,7 @@ void TrackArtist::DrawTracks(TrackList * tracks, // This just show what the passed in rectanges enclose dc.SetPen(wxColour(*wxGREEN)); dc.SetBrush(*wxTRANSPARENT_BRUSH); - dc.DrawRectangle(r); + dc.DrawRectangle(rect); dc.SetPen(wxColour(*wxBLUE)); dc.SetBrush(*wxTRANSPARENT_BRUSH); dc.DrawRectangle(clip); @@ -406,7 +406,7 @@ void TrackArtist::DrawTracks(TrackList * tracks, rr.width -= (mInsetLeft + mInsetRight); rr.height -= (mInsetTop + mInsetBottom); DrawTrack(t, dc, rr, viewInfo, - drawEnvelope, drawSamples, drawSliders, hasSolo); + drawEnvelope, bigPoints, drawSliders, hasSolo); } #ifdef EXPERIMENTAL_OUTPUT_DISPLAY @@ -424,7 +424,7 @@ void TrackArtist::DrawTracks(TrackList * tracks, rr.width -= (mInsetLeft + mInsetRight); rr.height -= (mInsetTop + mInsetBottom); DrawTrack(t, dc, rr, viewInfo, - drawEnvelope, drawSamples, drawSliders, hasSolo); + drawEnvelope, bigPoints, drawSliders, hasSolo); } } #endif @@ -435,10 +435,10 @@ void TrackArtist::DrawTracks(TrackList * tracks, void TrackArtist::DrawTrack(const Track * t, wxDC & dc, - const wxRect & r, + const wxRect & rect, const ViewInfo * viewInfo, bool drawEnvelope, - bool drawSamples, + bool bigPoints, bool drawSliders, bool hasSolo) { @@ -454,19 +454,19 @@ void TrackArtist::DrawTrack(const Track * t, switch (wt->GetDisplay()) { case WaveTrack::WaveformDisplay: - DrawWaveform(wt, dc, r, viewInfo, - drawEnvelope, drawSamples, drawSliders, false, muted); + DrawWaveform(wt, dc, rect, viewInfo, + drawEnvelope, bigPoints, drawSliders, false, muted); break; case WaveTrack::WaveformDBDisplay: - DrawWaveform(wt, dc, r, viewInfo, - drawEnvelope, drawSamples, drawSliders, true, muted); + DrawWaveform(wt, dc, rect, viewInfo, + drawEnvelope, bigPoints, drawSliders, true, muted); break; case WaveTrack::SpectrumDisplay: case WaveTrack::SpectrumLogDisplay: case WaveTrack::SpectralSelectionDisplay: case WaveTrack::SpectralSelectionLogDisplay: case WaveTrack::PitchDisplay: - DrawSpectrum(wt, dc, r, viewInfo); + DrawSpectrum(wt, dc, rect, viewInfo); break; } if (mbShowTrackNameInWaveform && @@ -475,7 +475,7 @@ void TrackArtist::DrawTrack(const Track * t, wxFont labelFont(12, wxSWISS, wxNORMAL, wxNORMAL); dc.SetFont(labelFont); dc.SetTextForeground(wxColour(255, 255, 0)); - dc.DrawText (wt->GetName(), r.x+10, r.y); // move right 10 pixels to avoid overwriting <- symbol + dc.DrawText (wt->GetName(), rect.x+10, rect.y); // move right 10 pixels to avoid overwriting <- symbol } break; // case Wave } @@ -483,27 +483,27 @@ void TrackArtist::DrawTrack(const Track * t, case Track::Note: { bool muted = (hasSolo || t->GetMute()) && !t->GetSolo(); - DrawNoteTrack((NoteTrack *)t, dc, r, viewInfo, muted); + DrawNoteTrack((NoteTrack *)t, dc, rect, viewInfo, muted); break; } #endif // USE_MIDI case Track::Label: - DrawLabelTrack((LabelTrack *)t, dc, r, viewInfo); + DrawLabelTrack((LabelTrack *)t, dc, rect, viewInfo); break; case Track::Time: - DrawTimeTrack((TimeTrack *)t, dc, r, viewInfo); + DrawTimeTrack((TimeTrack *)t, dc, rect, viewInfo); break; } } -void TrackArtist::DrawVRuler(Track *t, wxDC * dc, wxRect & r) +void TrackArtist::DrawVRuler(Track *t, wxDC * dc, wxRect & rect) { int kind = t->GetKind(); // Label and Time tracks do not have a vruler // But give it a beveled area if (kind == Track::Label) { - wxRect bev = r; + wxRect bev = rect; bev.Inflate(-1, -1); bev.width += 1; AColor::BevelTrackInfo(*dc, true, bev); @@ -513,15 +513,15 @@ void TrackArtist::DrawVRuler(Track *t, wxDC * dc, wxRect & r) // Time tracks if (kind == Track::Time) { - wxRect bev = r; + wxRect bev = rect; bev.Inflate(-1, -1); bev.width += 1; AColor::BevelTrackInfo(*dc, true, bev); // Right align the ruler - wxRect rr = r; + wxRect rr = rect; rr.width--; - if (t->vrulerSize.GetWidth() < r.GetWidth()) { + if (t->vrulerSize.GetWidth() < rect.GetWidth()) { int adj = rr.GetWidth() - t->vrulerSize.GetWidth(); rr.x += adj; rr.width -= adj; @@ -537,7 +537,7 @@ void TrackArtist::DrawVRuler(Track *t, wxDC * dc, wxRect & r) // All waves have a ruler in the info panel // The ruler needs a bevelled surround. if (kind == Track::Wave) { - wxRect bev = r; + wxRect bev = rect; bev.Inflate(-1, -1); bev.width += 1; AColor::BevelTrackInfo(*dc, true, bev); @@ -548,9 +548,9 @@ void TrackArtist::DrawVRuler(Track *t, wxDC * dc, wxRect & r) } // Right align the ruler - wxRect rr = r; + wxRect rr = rect; rr.width--; - if (t->vrulerSize.GetWidth() < r.GetWidth()) { + if (t->vrulerSize.GetWidth() < rect.GetWidth()) { int adj = rr.GetWidth() - t->vrulerSize.GetWidth(); rr.x += adj; rr.width -= adj; @@ -566,23 +566,23 @@ void TrackArtist::DrawVRuler(Track *t, wxDC * dc, wxRect & r) #ifdef USE_MIDI // The note track draws a vertical keyboard to label pitches if (kind == Track::Note) { - UpdateVRuler(t, r); + UpdateVRuler(t, rect); dc->SetPen(*wxTRANSPARENT_PEN); dc->SetBrush(*wxWHITE_BRUSH); - wxRect bev = r; + wxRect bev = rect; bev.x++; bev.y++; bev.width--; bev.height--; dc->DrawRectangle(bev); - r.y += 2; - r.height -= 2; + rect.y += 2; + rect.height -= 2; - //int bottom = GetBottom((NoteTrack *) t, r); + //int bottom = GetBottom((NoteTrack *) t, rect); NoteTrack *track = (NoteTrack *) t; - track->PrepareIPitchToY(r); + track->PrepareIPitchToY(rect); wxPen hilitePen; hilitePen.SetColour(120, 120, 120); @@ -603,23 +603,23 @@ void TrackArtist::DrawVRuler(Track *t, wxDC * dc, wxRect & r) int obottom = track->GetOctaveBottom(octave); int marg = track->GetNoteMargin(); //IPITCH_TO_Y(octave * 12) + PITCH_HEIGHT + 1; - while (obottom >= r.y) { + while (obottom >= rect.y) { dc->SetPen(*wxBLACK_PEN); for (int white = 0; white < 7; white++) { int pos = track->GetWhitePos(white); - if (obottom - pos > r.y + marg + 1 && + if (obottom - pos > rect.y + marg + 1 && // don't draw too close to margin line -- it's annoying - obottom - pos < r.y + r.height - marg - 3) - AColor::Line(*dc, r.x, obottom - pos, - r.x + r.width, obottom - pos); + obottom - pos < rect.y + rect.height - marg - 3) + AColor::Line(*dc, rect.x, obottom - pos, + rect.x + rect.width, obottom - pos); } - wxRect br = r; + wxRect br = rect; br.height = track->GetPitchHeight(); br.x++; br.width = 17; for (int black = 0; black < 5; black++) { br.y = obottom - track->GetBlackPos(black); - if (br.y > r.y + marg - 2 && br.y + br.height < r.y + r.height - marg) { + if (br.y > rect.y + marg - 2 && br.y + br.height < rect.y + rect.height - marg) { dc->SetPen(hilitePen); dc->DrawRectangle(br); dc->SetPen(*wxBLACK_PEN); @@ -639,10 +639,10 @@ void TrackArtist::DrawVRuler(Track *t, wxDC * dc, wxRect & r) s.Printf(wxT("C%d"), octave - 1); wxCoord width, height; dc->GetTextExtent(s, &width, &height); - if (obottom - height + 4 > r.y && - obottom + 4 < r.y + r.height) { + if (obottom - height + 4 > rect.y && + obottom + 4 < rect.y + rect.height) { dc->SetTextForeground(wxColour(60, 60, 255)); - dc->DrawText(s, r.x + r.width - width, + dc->DrawText(s, rect.x + rect.width - width, obottom - height + 2); } } @@ -651,19 +651,19 @@ void TrackArtist::DrawVRuler(Track *t, wxDC * dc, wxRect & r) // draw lines delineating the out-of-bounds margins dc->SetPen(*wxBLACK_PEN); // you would think the -1 offset here should be -2 to match the - // adjustment to r.y (see above), but -1 produces correct output - AColor::Line(*dc, r.x, r.y + marg - 1, r.x + r.width, r.y + marg - 1); + // adjustment to rect.y (see above), but -1 produces correct output + AColor::Line(*dc, rect.x, rect.y + marg - 1, rect.x + rect.width, rect.y + marg - 1); // since the margin gives us the bottom of the line, // the extra -1 gets us to the top - AColor::Line(*dc, r.x, r.y + r.height - marg - 1, - r.x + r.width, r.y + r.height - marg - 1); + AColor::Line(*dc, rect.x, rect.y + rect.height - marg - 1, + rect.x + rect.width, rect.y + rect.height - marg - 1); } #endif // USE_MIDI } -void TrackArtist::UpdateVRuler(Track *t, wxRect & r) +void TrackArtist::UpdateVRuler(Track *t, wxRect & rect) { // Label tracks do not have a vruler if (t->GetKind() == Track::Label) { @@ -677,7 +677,7 @@ void TrackArtist::UpdateVRuler(Track *t, wxRect & r) min = tt->GetRangeLower() * 100.0; max = tt->GetRangeUpper() * 100.0; - vruler->SetBounds(r.x, r.y+1, r.x + r.width, r.y + r.height-1); + vruler->SetBounds(rect.x, rect.y+1, rect.x + rect.width, rect.y + rect.height-1); vruler->SetOrientation(wxVERTICAL); vruler->SetRange(max, min); vruler->SetFormat((tt->GetDisplayLog()) ? Ruler::RealLogFormat : Ruler::RealFormat); @@ -719,7 +719,7 @@ void TrackArtist::UpdateVRuler(Track *t, wxRect & r) wt->SetDisplayBounds(min, max); } - vruler->SetBounds(r.x, r.y+1, r.x + r.width, r.y + r.height-1); + vruler->SetBounds(rect.x, rect.y+1, rect.x + rect.width, rect.y + rect.height-1); vruler->SetOrientation(wxVERTICAL); vruler->SetRange(max, min); vruler->SetFormat(Ruler::RealFormat); @@ -760,7 +760,7 @@ void TrackArtist::UpdateVRuler(Track *t, wxRect & r) if (max > 0) { int top = 0; float topval = 0; - int bot = r.height; + int bot = rect.height; float botval = -mdBrange; if (min < 0) { @@ -780,7 +780,7 @@ void TrackArtist::UpdateVRuler(Track *t, wxRect & r) botval = -((1-min)*mdBrange); } - vruler->SetBounds(r.x, r.y+top+1, r.x + r.width, r.y + bot-1); + vruler->SetBounds(rect.x, rect.y+top+1, rect.x + rect.width, rect.y + bot-1); vruler->SetOrientation(wxVERTICAL); vruler->SetRange(topval, botval); } @@ -796,7 +796,7 @@ void TrackArtist::UpdateVRuler(Track *t, wxRect & r) { // Spectrum - if (r.height < 60) + if (rect.height < 60) return; double rate = wt->GetRate(); @@ -815,7 +815,7 @@ void TrackArtist::UpdateVRuler(Track *t, wxRect & r) we will use Hz if maxFreq is < 2000, otherwise we represent kHz, and append to the numbers a "k" */ - vruler->SetBounds(r.x, r.y+1, r.x + r.width, r.y + r.height-1); + 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); @@ -836,7 +836,7 @@ void TrackArtist::UpdateVRuler(Track *t, wxRect & r) { // SpectrumLog - if (r.height < 10) + if (rect.height < 10) return; double rate = wt->GetRate(); @@ -855,7 +855,7 @@ void TrackArtist::UpdateVRuler(Track *t, wxRect & r) we will use Hz if maxFreq is < 2000, otherwise we represent kHz, and append to the numbers a "k" */ - vruler->SetBounds(r.x, r.y+1, r.x + r.width, r.y + r.height-1); + 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); @@ -872,7 +872,7 @@ void TrackArtist::UpdateVRuler(Track *t, wxRect & r) // The note track isn't drawing a ruler at all! // But it needs to! else if (t->GetKind() == Track::Note) { - vruler->SetBounds(r.x, r.y+1, r.x + 1, r.y + r.height-1); + vruler->SetBounds(rect.x, rect.y+1, rect.x + 1, rect.y + rect.height-1); vruler->SetOrientation(wxVERTICAL); } #endif // USE_MIDI @@ -959,7 +959,7 @@ float ValueOfPixel(int y, int height, bool offset, return v; } -void TrackArtist::DrawNegativeOffsetTrackArrows(wxDC &dc, const wxRect &r) +void TrackArtist::DrawNegativeOffsetTrackArrows(wxDC &dc, const wxRect &rect) { // Draws two black arrows on the left side of the track to // indicate the user that the track has been time-shifted @@ -967,26 +967,26 @@ void TrackArtist::DrawNegativeOffsetTrackArrows(wxDC &dc, const wxRect &r) dc.SetPen(*wxBLACK_PEN); AColor::Line(dc, - r.x + 2, r.y + 6, - r.x + 8, r.y + 6); + rect.x + 2, rect.y + 6, + rect.x + 8, rect.y + 6); AColor::Line(dc, - r.x + 2, r.y + 6, - r.x + 6, r.y + 2); + rect.x + 2, rect.y + 6, + rect.x + 6, rect.y + 2); AColor::Line(dc, - r.x + 2, r.y + 6, - r.x + 6, r.y + 10); + rect.x + 2, rect.y + 6, + rect.x + 6, rect.y + 10); AColor::Line(dc, - r.x + 2, r.y + r.height - 8, - r.x + 8, r.y + r.height - 8); + rect.x + 2, rect.y + rect.height - 8, + rect.x + 8, rect.y + rect.height - 8); AColor::Line(dc, - r.x + 2, r.y + r.height - 8, - r.x + 6, r.y + r.height - 4); + rect.x + 2, rect.y + rect.height - 8, + rect.x + 6, rect.y + rect.height - 4); AColor::Line(dc, - r.x + 2, r.y + r.height - 8, - r.x + 6, r.y + r.height - 12); + rect.x + 2, rect.y + rect.height - 8, + rect.x + 6, rect.y + rect.height - 12); } -void TrackArtist::DrawWaveformBackground(wxDC &dc, const wxRect &r, const double env[], +void TrackArtist::DrawWaveformBackground(wxDC &dc, const wxRect &rect, const double env[], float zoomMin, float zoomMax, bool dB, const sampleCount where[], sampleCount ssel0, sampleCount ssel1, @@ -1001,7 +1001,7 @@ void TrackArtist::DrawWaveformBackground(wxDC &dc, const wxRect &r, const double // | | | | // maxtop maxbot mintop minbot - int h = r.height; + int h = rect.height; int halfHeight = wxMax(h / 2, 1); int maxtop, lmaxtop = 0; int mintop, lmintop = 0; @@ -1013,9 +1013,9 @@ void TrackArtist::DrawWaveformBackground(wxDC &dc, const wxRect &r, const double dc.SetPen(*wxTRANSPARENT_PEN); dc.SetBrush(blankBrush); - dc.DrawRectangle(r); + dc.DrawRectangle(rect); - for (x = 0; x < r.width; x++) { + for (x = 0; x < rect.width; x++) { // First we compute the truncated shape of the waveform background. // If drawEnvelope is true, then we compute the lower border of the // envelope. @@ -1052,14 +1052,14 @@ void TrackArtist::DrawWaveformBackground(wxDC &dc, const wxRect &r, const double dc.SetBrush(lsel ? selectedBrush : unselectedBrush); - l = r.x + lx; + l = rect.x + lx; w = x - lx; if (lmaxbot < lmintop - 1) { - dc.DrawRectangle(l, r.y + lmaxtop, w, lmaxbot - lmaxtop); - dc.DrawRectangle(l, r.y + lmintop, w, lminbot - lmintop); + dc.DrawRectangle(l, rect.y + lmaxtop, w, lmaxbot - lmaxtop); + dc.DrawRectangle(l, rect.y + lmintop, w, lminbot - lmintop); } else { - dc.DrawRectangle(l, r.y + lmaxtop, w, lminbot - lmaxtop); + dc.DrawRectangle(l, rect.y + lmaxtop, w, lminbot - lmaxtop); } lmaxtop = maxtop; @@ -1071,39 +1071,39 @@ void TrackArtist::DrawWaveformBackground(wxDC &dc, const wxRect &r, const double } dc.SetBrush(lsel ? selectedBrush : unselectedBrush); - l = r.x + lx; + l = rect.x + lx; w = x - lx; if (lmaxbot < lmintop - 1) { - dc.DrawRectangle(l, r.y + lmaxtop, w, lmaxbot - lmaxtop); - dc.DrawRectangle(l, r.y + lmintop, w, lminbot - lmintop); + dc.DrawRectangle(l, rect.y + lmaxtop, w, lmaxbot - lmaxtop); + dc.DrawRectangle(l, rect.y + lmintop, w, lminbot - lmintop); } else { - dc.DrawRectangle(l, r.y + lmaxtop, w, lminbot - lmaxtop); + dc.DrawRectangle(l, rect.y + lmaxtop, w, lminbot - lmaxtop); } // If sync-lock selected, draw in linked graphics. if (bIsSyncLockSelected && ssel0 < ssel1) { // Find the beginning/end of the selection int begin, end; - for (x = 0; x < r.width && where[x] < ssel0; ++x); + for (x = 0; x < rect.width && where[x] < ssel0; ++x); begin = x; - for (; x < r.width && where[x] < ssel1; ++x); + for (; x < rect.width && where[x] < ssel1; ++x); end = x; - DrawSyncLockTiles(&dc, wxRect(r.x + begin, r.y, end - 1 - begin, r.height)); + DrawSyncLockTiles(&dc, wxRect(rect.x + begin, rect.y, end - 1 - begin, rect.height)); } //OK, the display bounds are between min and max, which - //is spread across r.height. Draw the line at the proper place. + //is spread across rect.height. Draw the line at the proper place. if (zoomMin < 0 && zoomMax > 0) { int half = (int)((zoomMax / (zoomMax - zoomMin)) * h); dc.SetPen(*wxBLACK_PEN); - AColor::Line(dc, r.x, r.y + half, r.x + r.width, r.y + half); + AColor::Line(dc, rect.x, rect.y + half, rect.x + rect.width, rect.y + half); } } -void TrackArtist::DrawMinMaxRMS(wxDC &dc, const wxRect &r, const double env[], +void TrackArtist::DrawMinMaxRMS(wxDC &dc, const wxRect &rect, const double env[], float zoomMin, float zoomMax, bool dB, const WaveDisplay &display, bool /* showProgress */, bool muted #ifdef EXPERIMENTAL_OUTPUT_DISPLAY @@ -1122,14 +1122,14 @@ void TrackArtist::DrawMinMaxRMS(wxDC &dc, const wxRect &r, const double env[], int lasth2 = std::numeric_limits::min(); int h1; int h2; - int *r1 = new int[r.width]; - int *r2 = new int[r.width]; + int *r1 = new int[rect.width]; + int *r2 = new int[rect.width]; int *clipped = NULL; int clipcnt = 0; int x; if (mShowClipping) { - clipped = new int[r.width]; + clipped = new int[rect.width]; } long pixAnimOffset = (long)fabs((double)(wxDateTime::Now().GetTicks() * -10)) + @@ -1139,8 +1139,8 @@ void TrackArtist::DrawMinMaxRMS(wxDC &dc, const wxRect &r, const double env[], bool drawWaveform = true; dc.SetPen(muted ? muteSamplePen : samplePen); - for (x = 0; x < r.width; x++) { - int xx = r.x + x; + for (x = 0; x < rect.width; x++) { + int xx = rect.x + x; double v; #ifdef EXPERIMENTAL_OUTPUT_DISPLAY //JWA: "gain" variable passed to function includes the pan value and is used below 4/14/13 @@ -1155,7 +1155,7 @@ void TrackArtist::DrawMinMaxRMS(wxDC &dc, const wxRect &r, const double env[], } } h1 = GetWaveYPos(v, zoomMin, zoomMax, - r.height, dB, true, mdBrange, true); + rect.height, dB, true, mdBrange, true); #ifdef EXPERIMENTAL_OUTPUT_DISPLAY v = max[x] * env[x] * gain; @@ -1169,7 +1169,7 @@ void TrackArtist::DrawMinMaxRMS(wxDC &dc, const wxRect &r, const double env[], } } h2 = GetWaveYPos(v, zoomMin, zoomMax, - r.height, dB, true, mdBrange, true); + rect.height, dB, true, mdBrange, true); // JKC: This adjustment to h1 and h2 ensures that the drawn // waveform is continuous. @@ -1186,14 +1186,14 @@ void TrackArtist::DrawMinMaxRMS(wxDC &dc, const wxRect &r, const double env[], #ifdef EXPERIMENTAL_OUTPUT_DISPLAY r1[x] = GetWaveYPos(-rms[x] * env[x]*gain, zoomMin, zoomMax, - r.height, dB, true, mdBrange, true); + rect.height, dB, true, mdBrange, true); r2[x] = GetWaveYPos(rms[x] * env[x]*gain, zoomMin, zoomMax, - r.height, dB, true, mdBrange, true); + rect.height, dB, true, mdBrange, true); #else r1[x] = GetWaveYPos(-rms[x] * env[x], zoomMin, zoomMax, - r.height, dB, true, mdBrange, true); + rect.height, dB, true, mdBrange, true); r2[x] = GetWaveYPos(rms[x] * env[x], zoomMin, zoomMax, - r.height, dB, true, mdBrange, true); + rect.height, dB, true, mdBrange, true); #endif // Make sure the rms isn't larger than the waveform min/max if (r1[x] > h1 - 1) { @@ -1210,13 +1210,13 @@ void TrackArtist::DrawMinMaxRMS(wxDC &dc, const wxRect &r, const double env[], if (drawStripes) { // TODO:unify with buffer drawing. dc.SetPen((bl[x] % 2) ? muteSamplePen : samplePen); - for (int y = 0; y < r.height / 25 + 1; y++) { + for (int y = 0; y < rect.height / 25 + 1; y++) { // we are drawing over the buffer, but I think DrawLine takes care of this. AColor::Line(dc, xx, - r.y + 25 * y + (x /*+pixAnimOffset*/) % 25, + rect.y + 25 * y + (x /*+pixAnimOffset*/) % 25, xx, - r.y + 25 * y + (x /*+pixAnimOffset*/) % 25 + 6); //take the min so we don't draw past the edge + rect.y + 25 * y + (x /*+pixAnimOffset*/) % 25 + 6); //take the min so we don't draw past the edge } } @@ -1225,10 +1225,10 @@ void TrackArtist::DrawMinMaxRMS(wxDC &dc, const wxRect &r, const double env[], if (drawWaveform) { int triX; dc.SetPen(samplePen); - triX = fabs((double)((x + pixAnimOffset) % (2 * r.height)) - r.height) + r.height; - for (int y = 0; y < r.height; y++) { - if ((y + triX) % r.height == 0) { - dc.DrawPoint(xx, r.y + y); + triX = fabs((double)((x + pixAnimOffset) % (2 * rect.height)) - rect.height) + rect.height; + for (int y = 0; y < rect.height; y++) { + if ((y + triX) % rect.height == 0) { + dc.DrawPoint(xx, rect.y + y); } } } @@ -1237,18 +1237,18 @@ void TrackArtist::DrawMinMaxRMS(wxDC &dc, const wxRect &r, const double env[], dc.SetPen(muted ? muteSamplePen : samplePen); } else { - AColor::Line(dc, xx, r.y + h2, xx, r.y + h1); + AColor::Line(dc, xx, rect.y + h2, xx, rect.y + h1); } } // Stroke rms over the min-max dc.SetPen(muted ? muteRmsPen : rmsPen); - for (int x = 0; x < r.width; x++) { - int xx = r.x + x; + for (int x = 0; x < rect.width; x++) { + int xx = rect.x + x; if (bl[x] <= -1) { } else if (r1[x] != r2[x]) { - AColor::Line(dc, xx, r.y + r2[x], xx, r.y + r1[x]); + AColor::Line(dc, xx, rect.y + r2[x], xx, rect.y + r1[x]); } } @@ -1257,7 +1257,7 @@ void TrackArtist::DrawMinMaxRMS(wxDC &dc, const wxRect &r, const double env[], dc.SetPen(muted ? muteClippedPen : clippedPen); while (--clipcnt >= 0) { int xx = clipped[clipcnt]; - AColor::Line(dc, xx, r.y, xx, r.y + r.height); + AColor::Line(dc, xx, rect.y, xx, rect.y + rect.height); } } @@ -1269,15 +1269,15 @@ void TrackArtist::DrawMinMaxRMS(wxDC &dc, const wxRect &r, const double env[], delete [] r2; } -void TrackArtist::DrawIndividualSamples(wxDC &dc, const wxRect &r, +void TrackArtist::DrawIndividualSamples(wxDC &dc, const wxRect &rect, float zoomMin, float zoomMax, bool dB, WaveClip *clip, double t0, double pps, double WXUNUSED(h), - bool drawSamples, bool showPoints, bool muted) + bool bigPoints, bool showPoints, bool muted) { double rate = clip->GetRate(); sampleCount s0 = (sampleCount) (t0 * rate + 0.5); - sampleCount slen = (sampleCount) (r.width * rate / pps + 0.5); + sampleCount slen = (sampleCount) (rect.width * rate / pps + 0.5); sampleCount snSamples = clip->GetNumSamples(); slen += 4; @@ -1321,39 +1321,39 @@ void TrackArtist::DrawIndividualSamples(wxDC &dc, const wxRect &r, xpos[s] = xx; - // t0 + clip->GetOffset() is 'h' (the absolute time of the left edge) for 'r'. - tt = buffer[s] * clip->GetEnvelope()->GetValueAtX(xx + r.x, r, t0 + clip->GetOffset(), pps); + // t0 + clip->GetOffset() is 'h' (the absolute time of the left edge) for 'rect'. + tt = buffer[s] * clip->GetEnvelope()->GetValueAtX(xx + rect.x, rect, t0 + clip->GetOffset(), pps); if (clipped && mShowClipping && ((tt <= -MAX_AUDIO) || (tt >= MAX_AUDIO))) clipped[clipcnt++] = xx; ypos[s] = GetWaveYPos(tt, zoomMin, zoomMax, - r.height, dB, true, mdBrange, false); + rect.height, dB, true, mdBrange, false); if (ypos[s] < -1) { ypos[s] = -1; } - if (ypos[s] > r.height) { - ypos[s] = r.height; + if (ypos[s] > rect.height) { + ypos[s] = rect.height; } } // Draw lines for (s = 0; s < slen - 1; s++) { AColor::Line(dc, - r.x + xpos[s], r.y + ypos[s], - r.x + xpos[s + 1], r.y + ypos[s + 1]); + rect.x + xpos[s], rect.y + ypos[s], + rect.x + xpos[s + 1], rect.y + ypos[s + 1]); } if (showPoints) { // Draw points - int tickSize= drawSamples ? 4 : 3;// Bigger ellipses when draggable. + int tickSize= bigPoints ? 4 : 3;// Bigger ellipses when draggable. wxRect pr; pr.width = tickSize; pr.height = tickSize; //different colour when draggable. - dc.SetBrush( drawSamples ? dragsampleBrush : sampleBrush); + dc.SetBrush( bigPoints ? dragsampleBrush : sampleBrush); for (s = 0; s < slen; s++) { - if (ypos[s] >= 0 && ypos[s] < r.height) { - pr.x = r.x + xpos[s] - tickSize/2; - pr.y = r.y + ypos[s] - tickSize/2; + if (ypos[s] >= 0 && ypos[s] < rect.height) { + pr.x = rect.x + xpos[s] - tickSize/2; + pr.y = rect.y + ypos[s] - tickSize/2; dc.DrawEllipse(pr); } } @@ -1364,7 +1364,7 @@ void TrackArtist::DrawIndividualSamples(wxDC &dc, const wxRect &r, dc.SetPen(muted ? muteClippedPen : clippedPen); while (--clipcnt >= 0) { s = clipped[clipcnt]; - AColor::Line(dc, r.x + s, r.y, r.x + s, r.y + r.height); + AColor::Line(dc, rect.x + s, rect.y, rect.x + s, rect.y + rect.height); } } @@ -1377,14 +1377,14 @@ void TrackArtist::DrawIndividualSamples(wxDC &dc, const wxRect &r, delete[]ypos; } -void TrackArtist::DrawEnvelope(wxDC &dc, const wxRect &r, const double env[], +void TrackArtist::DrawEnvelope(wxDC &dc, const wxRect &rect, const double env[], float zoomMin, float zoomMax, bool dB) { - int h = r.height; + int h = rect.height; dc.SetPen(AColor::envelopePen); - for (int x = 0; x < r.width; x++) { + for (int x = 0; x < rect.width; x++) { int cenvTop = GetWaveYPos(env[x], zoomMin, zoomMax, h, dB, true, mdBrange, true); @@ -1404,22 +1404,22 @@ void TrackArtist::DrawEnvelope(wxDC &dc, const wxRect &r, const double env[], cenvBot = value + 4; } - DrawEnvLine(dc, r, x, envTop, cenvTop, true); - DrawEnvLine(dc, r, x, envBot, cenvBot, false); + DrawEnvLine(dc, rect, x, envTop, cenvTop, true); + DrawEnvLine(dc, rect, x, envBot, cenvBot, false); } } -void TrackArtist::DrawEnvLine(wxDC &dc, const wxRect &r, int x, int y, int cy, bool top) +void TrackArtist::DrawEnvLine(wxDC &dc, const wxRect &rect, int x, int y, int cy, bool top) { - int xx = r.x + x; - int yy = r.y + cy; + int xx = rect.x + x; + int yy = rect.y + cy; if (y < 0) { if (x % 4 != 3) { AColor::Line(dc, xx, yy, xx, yy + 3); } } - else if (y > r.height) { + else if (y > rect.height) { if (x % 4 != 3) { AColor::Line(dc, xx, yy - 3, xx, yy); } @@ -1436,21 +1436,21 @@ void TrackArtist::DrawEnvLine(wxDC &dc, const wxRect &r, int x, int y, int cy, b void TrackArtist::DrawWaveform(WaveTrack *track, wxDC & dc, - const wxRect & r, + const wxRect & rect, const ViewInfo *viewInfo, bool drawEnvelope, - bool drawSamples, + bool bigPoints, bool drawSliders, bool dB, bool muted) { - DrawBackgroundWithSelection(&dc, r, track, blankSelectedBrush, blankBrush, + DrawBackgroundWithSelection(&dc, rect, track, blankSelectedBrush, blankBrush, viewInfo->selectedRegion.t0(), viewInfo->selectedRegion.t1(), viewInfo->h, viewInfo->zoom); for (WaveClipList::compatibility_iterator it = track->GetClipIterator(); it; it = it->GetNext()) - DrawClipWaveform(track, it->GetData(), dc, r, viewInfo, - drawEnvelope, drawSamples, + DrawClipWaveform(track, it->GetData(), dc, rect, viewInfo, + drawEnvelope, bigPoints, dB, muted); // Update cache for locations, e.g. cutlines and merge points @@ -1459,24 +1459,24 @@ void TrackArtist::DrawWaveform(WaveTrack *track, for (int i = 0; iGetNumCachedLocations(); i++) { WaveTrack::Location loc = track->GetCachedLocation(i); double x = (loc.pos - viewInfo->h) * viewInfo->zoom; - if (x >= 0 && x < r.width) { + if (x >= 0 && x < rect.width) { dc.SetPen(*wxGREY_PEN); - AColor::Line(dc, (int) (r.x + x - 1), r.y, (int) (r.x + x - 1), r.y + r.height); + AColor::Line(dc, (int) (rect.x + x - 1), rect.y, (int) (rect.x + x - 1), rect.y + rect.height); if (loc.typ == WaveTrack::locationCutLine) { dc.SetPen(*wxRED_PEN); } else { dc.SetPen(*wxBLACK_PEN); } - AColor::Line(dc, (int) (r.x + x), r.y, (int) (r.x + x), r.y + r.height); + AColor::Line(dc, (int) (rect.x + x), rect.y, (int) (rect.x + x), rect.y + rect.height); dc.SetPen(*wxGREY_PEN); - AColor::Line(dc, (int) (r.x + x + 1), r.y, (int) (r.x + x + 1), r.y + r.height); + AColor::Line(dc, (int) (rect.x + x + 1), rect.y, (int) (rect.x + x + 1), rect.y + rect.height); } } if (drawSliders) { - DrawTimeSlider(dc, r, true); // directed right - DrawTimeSlider(dc, r, false); // directed left + DrawTimeSlider(dc, rect, true); // directed right + DrawTimeSlider(dc, rect, false); // directed left } } @@ -1486,7 +1486,7 @@ struct ClipParameters { // Do a bunch of calculations common to waveform and spectrum drawing. ClipParameters - (bool spectrum, const WaveTrack *track, const WaveClip *clip, const wxRect &r, + (bool spectrum, const WaveTrack *track, const WaveClip *clip, const wxRect &rect, const SelectedRegion &selectedRegion, const ViewInfo &viewInfo) { selectedRegion; @@ -1511,7 +1511,7 @@ struct ClipParameters tstep = 1.0 / pps; // Seconds per point tpre = h - tOffset; // offset corrected time of // left edge of display - tpost = tpre + (r.width * tstep); // offset corrected time of + tpost = tpre + (rect.width * tstep); // offset corrected time of // right edge of display const double sps = 1. / rate; //seconds-per-sample @@ -1559,7 +1559,7 @@ struct ClipParameters // The variable "mid" will be the rectangle containing the // actual waveform, as opposed to any blank area before // or after the track. - mid = r; + mid = rect; // If the left edge of the track is to the right of the left // edge of the display, then there's some blank area to the @@ -1567,7 +1567,7 @@ struct ClipParameters // rect by size of the blank area. if (tpre < 0) { // Fill in the area to the left of the track - double delta = r.width; + double delta = rect.width; if (t0 < tpost) { delta = (int)((t0 - tpre) * pps); } @@ -1583,11 +1583,11 @@ struct ClipParameters // of the track. Reduce the "mid" rect by the // size of the blank area. if (tpost > t1) { - wxRect post = r; + wxRect post = rect; if (t1 > tpre) { post.x += (int)((t1 - tpre) * pps); } - post.width = r.width - (post.x - r.x); + post.width = rect.width - (post.x - rect.x); // Reduce the rectangle containing the waveform by the width // of the area we just erased. mid.width -= post.width; @@ -1620,10 +1620,10 @@ struct ClipParameters void TrackArtist::DrawClipWaveform(WaveTrack *track, WaveClip *clip, wxDC & dc, - const wxRect & r, + const wxRect & rect, const ViewInfo *viewInfo, bool drawEnvelope, - bool drawSamples, + bool bigPoints, bool dB, bool muted) { @@ -1631,7 +1631,7 @@ void TrackArtist::DrawClipWaveform(WaveTrack *track, Profiler profiler; #endif - const ClipParameters params(false, track, clip, r, viewInfo->selectedRegion, *viewInfo); + const ClipParameters params(false, track, clip, rect, viewInfo->selectedRegion, *viewInfo); const wxRect &mid = params.mid; // The "mid" rect contains the part of the display actually // containing the waveform. If it's empty, we're done. @@ -1703,12 +1703,12 @@ void TrackArtist::DrawClipWaveform(WaveTrack *track, else { DrawIndividualSamples(dc, mid, zoomMin, zoomMax, dB, clip, t0, pps, h, - drawSamples, showPoints, muted); + bigPoints, showPoints, muted); } if (drawEnvelope) { DrawEnvelope(dc, mid, envValues, zoomMin, zoomMax, dB); - clip->GetEnvelope()->DrawPoints(dc, r, h, pps, dB, zoomMin, zoomMax); + clip->GetEnvelope()->DrawPoints(dc, rect, h, pps, dB, zoomMin, zoomMax); } delete[] envValues; @@ -1716,7 +1716,7 @@ void TrackArtist::DrawClipWaveform(WaveTrack *track, // Draw arrows on the left side if the track extends to the left of the // beginning of time. :) if (h == 0.0 && tOffset < 0.0) { - DrawNegativeOffsetTrackArrows(dc, r); + DrawNegativeOffsetTrackArrows(dc, rect); } // Draw clip edges @@ -1724,18 +1724,18 @@ void TrackArtist::DrawClipWaveform(WaveTrack *track, if (tpre < 0) { AColor::Line(dc, mid.x - 1, mid.y, - mid.x - 1, mid.y + r.height); + mid.x - 1, mid.y + rect.height); } if (tpost > t1) { AColor::Line(dc, mid.x + mid.width, mid.y, - mid.x + mid.width, mid.y + r.height); + mid.x + mid.width, mid.y + rect.height); } } void TrackArtist::DrawTimeSlider(wxDC & dc, - const wxRect & r, + const wxRect & rect, bool rightwards) { const int border = 3; // 3 pixels all round. @@ -1746,10 +1746,10 @@ void TrackArtist::DrawTimeSlider(wxDC & dc, const int xFlat = 3; //Enough space to draw in? - if (r.height <= ((taper+border + barSpacing) * 2)) { + if (rect.height <= ((taper+border + barSpacing) * 2)) { return; } - if (r.width <= (width * 2 + border * 3)) { + if (rect.width <= (width * 2 + border * 3)) { return; } @@ -1757,10 +1757,10 @@ void TrackArtist::DrawTimeSlider(wxDC & dc, int leftTaper = rightwards ? 0 : 6; int rightTaper = rightwards ? 6 : 0; - int xLeft = rightwards ? (r.x + border - 2) - : (r.x + r.width + 1 - (border + width)); - int yTop = r.y + border; - int yBot = r.y + r.height - border - 1; + int xLeft = rightwards ? (rect.x + border - 2) + : (rect.x + rect.width + 1 - (border + width)); + int yTop = rect.y + border; + int yBot = rect.y + rect.height - border - 1; AColor::Light(&dc, false); AColor::Line(dc, xLeft, yBot - leftTaper, xLeft, yTop + leftTaper); @@ -1793,16 +1793,16 @@ void TrackArtist::DrawTimeSlider(wxDC & dc, void TrackArtist::DrawSpectrum(WaveTrack *track, wxDC & dc, - const wxRect & r, + const wxRect & rect, const ViewInfo *viewInfo) { - DrawBackgroundWithSelection(&dc, r, track, blankSelectedBrush, blankBrush, + DrawBackgroundWithSelection(&dc, rect, track, blankSelectedBrush, blankBrush, viewInfo->selectedRegion.t0(), viewInfo->selectedRegion.t1(), viewInfo->h, viewInfo->zoom); WaveTrackCache cache(track); for (WaveClipList::compatibility_iterator it = track->GetClipIterator(); it; it = it->GetNext()) { - DrawClipSpectrum(cache, it->GetData(), dc, r, viewInfo); + DrawClipSpectrum(cache, it->GetData(), dc, rect, viewInfo); } } @@ -1876,7 +1876,7 @@ AColor::ColorGradientChoice ChooseColorSet( float bin0, float bin1, float selBin void TrackArtist::DrawClipSpectrum(WaveTrackCache &cache, WaveClip *clip, wxDC & dc, - const wxRect & r, + const wxRect & rect, const ViewInfo *viewInfo) { #ifdef PROFILE_WAVEFORM @@ -1892,7 +1892,7 @@ void TrackArtist::DrawClipSpectrum(WaveTrackCache &cache, enum { MONOCHROME_LINE = 230, COLORED_LINE = 0 }; enum { DASH_LENGTH = 10 /* pixels */ }; - const ClipParameters params(true, track, clip, r, viewInfo->selectedRegion, *viewInfo); + const ClipParameters params(true, track, clip, rect, viewInfo->selectedRegion, *viewInfo); const wxRect &mid = params.mid; // The "mid" rect contains the part of the display actually // containing the waveform. If it's empty, we're done. @@ -2466,8 +2466,8 @@ const char *LookupAtomAttribute(Alg_note_ptr note, Alg_attribute attr, char *def return def; } -#define TIME_TO_X(t) (r.x + (int) (((t) - h) * pps)) -#define X_TO_TIME(xx) (((xx) - r.x) / pps + h) +#define TIME_TO_X(t) (rect.x + (int) (((t) - h) * pps)) +#define X_TO_TIME(xx) (((xx) - rect.x) / pps + h) // CLIP(x) changes x to lie between +/- CLIP_MAX due to graphics display problems // with very large coordinate values (this happens when you zoom in very far) @@ -2484,7 +2484,7 @@ const char *LookupAtomAttribute(Alg_note_ptr note, Alg_attribute attr, char *def #define GREEN(i) ( unsigned char )( (((i) >> 8) & 0xff) ) #define BLUE(i) ( unsigned char )( ((i) & 0xff) ) -//#define PITCH_TO_Y(p) (r.y + r.height - int(pitchht * ((p) + 0.5 - pitch0) + 0.5)) +//#define PITCH_TO_Y(p) (rect.y + rect.height - int(pitchht * ((p) + 0.5 - pitch0) + 0.5)) /* int PitchToY(double p, int bottom) @@ -2500,13 +2500,13 @@ int PitchToY(double p, int bottom) /* DrawNoteBackground is called by DrawNoteTrack twice: once to draw the unselected background, and once to draw the selected background. The selected background is the same except for the horizontal range - and the colors. The background rectangle region is given by r; the + and the colors. The background rectangle region is given by rect; the selected region is given by sel. The first time this is called, - sel is equal to r, and the entire region is drawn with unselected + sel is equal to rect, and the entire region is drawn with unselected background colors. */ void TrackArtist::DrawNoteBackground(NoteTrack *track, wxDC &dc, - const wxRect &r, const wxRect &sel, + const wxRect &rect, const wxRect &sel, const ViewInfo *viewInfo, const wxBrush &wb, const wxPen &wp, const wxBrush &bb, const wxPen &bp, @@ -2534,16 +2534,16 @@ void TrackArtist::DrawNoteBackground(NoteTrack *track, wxDC &dc, // eOffset is for the line between E and F; there's another line // between B and C, hence the offset of 2 for two line thicknesses int eOffset = track->GetPitchHeight() * 5 + 2; - while (obottom > r.y + track->GetNoteMargin() + 3) { + while (obottom > rect.y + track->GetNoteMargin() + 3) { // draw a black line separating octaves if this octave botton is visible - if (obottom < r.y + r.height - track->GetNoteMargin()) { + if (obottom < rect.y + rect.height - track->GetNoteMargin()) { dc.SetPen(*wxBLACK_PEN); // obottom - 1 because obottom is at the bottom of the line AColor::Line(dc, left, obottom - 1, right, obottom - 1); } dc.SetPen(bp); // draw a black-key stripe colored line separating E and F if visible - if (obottom - eOffset > r.y && obottom - eOffset < r.y + r.height) { + if (obottom - eOffset > rect.y && obottom - eOffset < rect.y + rect.height) { AColor::Line(dc, left, obottom - eOffset, right, obottom - eOffset); } @@ -2555,7 +2555,7 @@ void TrackArtist::DrawNoteBackground(NoteTrack *track, wxDC &dc, br.height = track->GetPitchHeight(); for (int black = 0; black < 5; black++) { br.y = obottom - track->GetBlackPos(black); - if (br.y > r.y && br.y + br.height < r.y + r.height) { + if (br.y > rect.y && br.y + br.height < rect.y + rect.height) { dc.DrawRectangle(br); // draw each black key background stripe } } @@ -2603,7 +2603,7 @@ window and draw out-of-bounds notes here instead. */ void TrackArtist::DrawNoteTrack(NoteTrack *track, wxDC & dc, - const wxRect & r, + const wxRect & rect, const ViewInfo *viewInfo, bool muted) { @@ -2613,7 +2613,7 @@ void TrackArtist::DrawNoteTrack(NoteTrack *track, double sel0 = viewInfo->selectedRegion.t0(); double sel1 = viewInfo->selectedRegion.t1(); - double h1 = X_TO_TIME(r.x + r.width); + double h1 = X_TO_TIME(rect.x + rect.width); Alg_seq_ptr seq = track->mSeq; if (!seq) { @@ -2636,14 +2636,14 @@ void TrackArtist::DrawNoteTrack(NoteTrack *track, // reserve 1/2 note height at top and bottom of track for // out-of-bounds notes - int numPitches = (r.height) / track->GetPitchHeight(); + int numPitches = (rect.height) / track->GetPitchHeight(); if (numPitches < 0) numPitches = 0; // cannot be negative // bottom is the hypothetical location of the bottom of pitch 0 relative to - // the top of the clipping region r: r.height - PITCH_HEIGHT/2 is where the + // the top of the clipping region rect: rect.height - PITCH_HEIGHT/2 is where the // bottomNote is displayed, and to that // we add the height of bottomNote from the position of pitch 0 - track->PrepareIPitchToY(r); + track->PrepareIPitchToY(rect); // Background comes in 6 colors: // 214, 214,214 -- unselected white keys @@ -2659,17 +2659,17 @@ void TrackArtist::DrawNoteTrack(NoteTrack *track, wxPen barLinePen; barLinePen.SetColour(170, 170, 170); - DrawNoteBackground(track, dc, r, r, viewInfo, blankBrush, blankPen, + DrawNoteBackground(track, dc, rect, rect, viewInfo, blankBrush, blankPen, blackStripeBrush, blackStripePen, barLinePen); - dc.SetClippingRegion(r); + dc.SetClippingRegion(rect); // Draw the selection background // First, the white keys, as a single rectangle // In other words fill the selection area with selectedWhiteKeyPen wxRect selBG; - selBG.y = r.y; - selBG.height = r.height; + selBG.y = rect.y; + selBG.height = rect.height; selBG.x = TIME_TO_X(sel0); selBG.width = TIME_TO_X(sel1) - TIME_TO_X(sel0); @@ -2687,7 +2687,7 @@ void TrackArtist::DrawNoteTrack(NoteTrack *track, wxPen selectedBarLinePen; selectedBarLinePen.SetColour(131, 131, 150); - DrawNoteBackground(track, dc, r, selBG, viewInfo, + DrawNoteBackground(track, dc, rect, selBG, viewInfo, selectedWhiteKeyBrush, selectedWhiteKeyPen, selectedBlackKeyBrush, selectedBlackKeyPen, selectedBarLinePen); @@ -2742,40 +2742,40 @@ void TrackArtist::DrawNoteTrack(NoteTrack *track, nr.y = track->PitchToY(note->pitch); nr.height = track->GetPitchHeight(); - nr.x = r.x + (int) ((x - h) * pps); + nr.x = rect.x + (int) ((x - h) * pps); nr.width = (int) ((note->dur * pps) + 0.5); - if (nr.x + nr.width >= r.x && nr.x < r.x + r.width) { - if (nr.x < r.x) { - nr.width -= (r.x - nr.x); - nr.x = r.x; + if (nr.x + nr.width >= rect.x && nr.x < rect.x + rect.width) { + if (nr.x < rect.x) { + nr.width -= (rect.x - nr.x); + nr.x = rect.x; } - if (nr.x + nr.width > r.x + r.width) // clip on right - nr.width = r.x + r.width - nr.x; + if (nr.x + nr.width > rect.x + rect.width) // clip on right + nr.width = rect.x + rect.width - nr.x; - if (nr.y + nr.height < r.y + marg + 3) { + if (nr.y + nr.height < rect.y + marg + 3) { // too high for window - nr.y = r.y; + nr.y = rect.y; nr.height = marg; dc.SetBrush(*wxBLACK_BRUSH); dc.SetPen(*wxBLACK_PEN); dc.DrawRectangle(nr); - } else if (nr.y >= r.y + r.height - marg - 1) { + } else if (nr.y >= rect.y + rect.height - marg - 1) { // too low for window - nr.y = r.y + r.height - marg; + nr.y = rect.y + rect.height - marg; nr.height = marg; dc.SetBrush(*wxBLACK_BRUSH); dc.SetPen(*wxBLACK_PEN); dc.DrawRectangle(nr); } else { - if (nr.y + nr.height > r.y + r.height - marg) - nr.height = r.y + r.height - nr.y; - if (nr.y < r.y + marg) { - int offset = r.y + marg - nr.y; + if (nr.y + nr.height > rect.y + rect.height - marg) + nr.height = rect.y + rect.height - nr.y; + if (nr.y < rect.y + marg) { + int offset = rect.y + marg - nr.y; nr.height -= offset; nr.y += offset; } - // nr.y += r.y; + // nr.y += rect.y; if (muted) AColor::LightMIDIChannel(&dc, note->chan + 1); else @@ -2961,12 +2961,12 @@ void TrackArtist::DrawNoteTrack(NoteTrack *track, iterator.end(); // draw black line between top/bottom margins and the track dc.SetPen(*wxBLACK_PEN); - AColor::Line(dc, r.x, r.y + marg, r.x + r.width, r.y + marg); - AColor::Line(dc, r.x, r.y + r.height - marg - 1, // subtract 1 to get - r.x + r.width, r.y + r.height - marg - 1); // top of line + AColor::Line(dc, rect.x, rect.y + marg, rect.x + rect.width, rect.y + marg); + AColor::Line(dc, rect.x, rect.y + rect.height - marg - 1, // subtract 1 to get + rect.x + rect.width, rect.y + rect.height - marg - 1); // top of line if (h == 0.0 && track->GetOffset() < 0.0) { - DrawNegativeOffsetTrackArrows(dc, r); + DrawNegativeOffsetTrackArrows(dc, rect); } dc.DestroyClippingRegion(); @@ -2977,7 +2977,7 @@ void TrackArtist::DrawNoteTrack(NoteTrack *track, void TrackArtist::DrawLabelTrack(LabelTrack *track, wxDC & dc, - const wxRect & r, + const wxRect & rect, const ViewInfo *viewInfo) { double sel0 = viewInfo->selectedRegion.t0(); @@ -2986,16 +2986,16 @@ void TrackArtist::DrawLabelTrack(LabelTrack *track, if (!track->GetSelected() && !track->IsSyncLockSelected()) sel0 = sel1 = 0.0; - track->Draw(dc, r, viewInfo->h, viewInfo->zoom, sel0, sel1); + track->Draw(dc, rect, viewInfo->h, viewInfo->zoom, sel0, sel1); } void TrackArtist::DrawTimeTrack(TimeTrack *track, wxDC & dc, - const wxRect & r, + const wxRect & rect, const ViewInfo *viewInfo) { - track->Draw(dc, r, viewInfo->h, viewInfo->zoom); - wxRect envRect = r; + track->Draw(dc, rect, viewInfo->h, viewInfo->zoom); + wxRect envRect = rect; envRect.height -= 2; double lower = track->GetRangeLower(), upper = track->GetRangeUpper(); if(track->GetDisplayLog()) { @@ -3089,7 +3089,7 @@ void TrackArtist::SetSpectrumLogMaxFreq(int freq) // 5x5 box. // // There may be a better way to do this, or a more appealing pattern. -void TrackArtist::DrawSyncLockTiles(wxDC *dc, wxRect r) +void TrackArtist::DrawSyncLockTiles(wxDC *dc, wxRect rect) { wxBitmap syncLockBitmap(theTheme.Image(bmpSyncLockSelTile)); @@ -3098,10 +3098,10 @@ void TrackArtist::DrawSyncLockTiles(wxDC *dc, wxRect r) int gridH = syncLockBitmap.GetHeight() - 8; // Horizontal position within the grid, modulo its period - int blockX = (r.x / gridW) % 5; + int blockX = (rect.x / gridW) % 5; // Amount to offset drawing of first column - int xOffset = r.x % gridW; + int xOffset = rect.x % gridW; if (xOffset < 0) xOffset += gridW; // Check if we're missing an extra column to the left (this can happen @@ -3116,20 +3116,20 @@ void TrackArtist::DrawSyncLockTiles(wxDC *dc, wxRect r) if (blockX < 0) blockX += 5; int x = 0; - while (x < r.width) { + while (x < rect.width) { int width = syncLockBitmap.GetWidth() - xOffset; - if (x + width > r.width) - width = r.width - x; + if (x + width > rect.width) + width = rect.width - x; // // Draw each row in this column // // Vertical position in the grid, modulo its period - int blockY = (r.y / gridH) % 5; + int blockY = (rect.y / gridH) % 5; // Amount to offset drawing of first row - int yOffset = r.y % gridH; + int yOffset = rect.y % gridH; if (yOffset < 0) yOffset += gridH; // Check if we're missing an extra row on top (this can happen because @@ -3144,11 +3144,11 @@ void TrackArtist::DrawSyncLockTiles(wxDC *dc, wxRect r) if (blockY < 0) blockY += 5; int y = 0; - while (y < r.height) + while (y < rect.height) { int height = syncLockBitmap.GetHeight() - yOffset; - if (y + height > r.height) - height = r.height - y; + if (y + height > rect.height) + height = rect.height - y; // AWD: draw blocks according to our pattern if ((blockX == 0 && blockY == 0) || (blockX == 2 && blockY == 1) || @@ -3160,10 +3160,10 @@ void TrackArtist::DrawSyncLockTiles(wxDC *dc, wxRect r) if (width != syncLockBitmap.GetWidth() || height != syncLockBitmap.GetHeight()) { wxBitmap subSyncLockBitmap = syncLockBitmap.GetSubBitmap(wxRect(xOffset, yOffset, width, height)); - dc->DrawBitmap(subSyncLockBitmap, r.x + x, r.y + y, true); + dc->DrawBitmap(subSyncLockBitmap, rect.x + x, rect.y + y, true); } else { - dc->DrawBitmap(syncLockBitmap, r.x + x, r.y + y, true); + dc->DrawBitmap(syncLockBitmap, rect.x + x, rect.y + y, true); } } @@ -3196,7 +3196,7 @@ void TrackArtist::DrawSyncLockTiles(wxDC *dc, wxRect r) } } -void TrackArtist::DrawBackgroundWithSelection(wxDC *dc, const wxRect &r, +void TrackArtist::DrawBackgroundWithSelection(wxDC *dc, const wxRect &rect, Track *track, wxBrush &selBrush, wxBrush &unselBrush, double sel0, double sel1, double h, double pps) { @@ -3209,13 +3209,13 @@ void TrackArtist::DrawBackgroundWithSelection(wxDC *dc, const wxRect &r, if (track->GetSelected() || track->IsSyncLockSelected()) { // Rectangles before, within, after the selction - wxRect before = r; - wxRect within = r; - wxRect after = r; + wxRect before = rect; + wxRect within = rect; + wxRect after = rect; before.width = int ((sel0 - h) * pps + 2.5); - if (before.GetRight() > r.GetRight()) { - before.width = r.width; + if (before.GetRight() > rect.GetRight()) { + before.width = rect.width; } if (before.width > 0) { @@ -3224,10 +3224,10 @@ void TrackArtist::DrawBackgroundWithSelection(wxDC *dc, const wxRect &r, within.x = before.GetRight(); } - within.width = r.x + int ((sel1 - h) * pps + 2.5) - within.x; + within.width = rect.x + int ((sel1 - h) * pps + 2.5) - within.x; - if (within.GetRight() > r.GetRight()) { - within.width = r.GetRight() - within.x; + if (within.GetRight() > rect.GetRight()) { + within.width = rect.GetRight() - within.x; } if (within.width > 0) { @@ -3249,7 +3249,7 @@ void TrackArtist::DrawBackgroundWithSelection(wxDC *dc, const wxRect &r, after.x = within.x; } - after.width = r.GetRight() - after.x; + after.width = rect.GetRight() - after.x; if (after.width > 0) { dc->SetBrush(unselBrush); dc->DrawRectangle(after); @@ -3259,7 +3259,7 @@ void TrackArtist::DrawBackgroundWithSelection(wxDC *dc, const wxRect &r, { // Track not selected; just draw background dc->SetBrush(unselBrush); - dc->DrawRectangle(r); + dc->DrawRectangle(rect); } } diff --git a/src/TrackArtist.h b/src/TrackArtist.h index 1fa32dd8e..471bdd191 100644 --- a/src/TrackArtist.h +++ b/src/TrackArtist.h @@ -52,17 +52,17 @@ class AUDACITY_DLL_API TrackArtist { void SetColours(); void DrawTracks(TrackList *tracks, Track *start, wxDC & dc, wxRegion & reg, - wxRect & r, wxRect & clip, ViewInfo *viewInfo, - bool drawEnvelope, bool drawSamples, bool drawSliders); + wxRect & rect, wxRect & clip, ViewInfo *viewInfo, + bool drawEnvelope, bool bigPoints, bool drawSliders); void DrawTrack(const Track *t, - wxDC & dc, const wxRect & r, const ViewInfo *viewInfo, - bool drawEnvelope, bool drawSamples, bool drawSliders, + wxDC & dc, const wxRect & rect, const ViewInfo *viewInfo, + bool drawEnvelope, bool bigPoints, bool drawSliders, bool hasSolo); - void DrawVRuler(Track *t, wxDC *dc, wxRect & r); + void DrawVRuler(Track *t, wxDC *dc, wxRect & rect); - void UpdateVRuler(Track *t, wxRect & r); + void UpdateVRuler(Track *t, wxRect & rect); void SetInset(int left, int top, int right, int bottom); @@ -90,10 +90,10 @@ class AUDACITY_DLL_API TrackArtist { } // Helper: draws the "sync-locked" watermark tiled to a rectangle - static void DrawSyncLockTiles(wxDC *dc, wxRect r); + static void DrawSyncLockTiles(wxDC *dc, wxRect rect); // Helper: draws background with selection rect - static void DrawBackgroundWithSelection(wxDC *dc, const wxRect &r, + static void DrawBackgroundWithSelection(wxDC *dc, const wxRect &rect, Track *track, wxBrush &selBrush, wxBrush &unselBrush, double sel0, double sel1, double h, double pps); @@ -104,67 +104,67 @@ class AUDACITY_DLL_API TrackArtist { // void DrawWaveform(WaveTrack *track, - wxDC & dc, const wxRect & r, const ViewInfo *viewInfo, - bool drawEnvelope, bool drawSamples, bool drawSliders, + wxDC & dc, const wxRect & rect, const ViewInfo *viewInfo, + bool drawEnvelope, bool bigPoints, bool drawSliders, bool dB, bool muted); void DrawSpectrum(WaveTrack *track, - wxDC & dc, const wxRect & r, const ViewInfo *viewInfo); + wxDC & dc, const wxRect & rect, const ViewInfo *viewInfo); #ifdef USE_MIDI - int GetBottom(NoteTrack *t, const wxRect &r); + int GetBottom(NoteTrack *t, const wxRect &rect); void DrawNoteBackground(NoteTrack *track, wxDC &dc, - const wxRect &r, const wxRect &sel, + const wxRect &rect, const wxRect &sel, const ViewInfo *viewInfo, const wxBrush &wb, const wxPen &wp, const wxBrush &bb, const wxPen &bp, const wxPen &mp); void DrawNoteTrack(NoteTrack *track, - wxDC & dc, const wxRect & r, const ViewInfo *viewInfo, + wxDC & dc, const wxRect & rect, const ViewInfo *viewInfo, bool muted); #endif // USE_MIDI void DrawLabelTrack(LabelTrack *track, - wxDC & dc, const wxRect & r, const ViewInfo *viewInfo); + wxDC & dc, const wxRect & rect, const ViewInfo *viewInfo); void DrawTimeTrack(TimeTrack *track, - wxDC & dc, const wxRect & r, const ViewInfo *viewInfo); + wxDC & dc, const wxRect & rect, const ViewInfo *viewInfo); - void DrawTimeSlider(wxDC & dc, const wxRect & r, + void DrawTimeSlider(wxDC & dc, const wxRect & rect, bool rightwards); void DrawClipWaveform(WaveTrack *track, WaveClip *clip, - wxDC & dc, const wxRect & r, const ViewInfo *viewInfo, - bool drawEnvelope, bool drawSamples, + wxDC & dc, const wxRect & rect, const ViewInfo *viewInfo, + bool drawEnvelope, bool bigPoints, bool dB, bool muted); void DrawClipSpectrum(WaveTrackCache &cache, WaveClip *clip, - wxDC & dc, const wxRect & r, const ViewInfo *viewInfo); + wxDC & dc, const wxRect & rect, const ViewInfo *viewInfo); // Waveform utility functions - void DrawWaveformBackground(wxDC & dc, const wxRect &r, const double env[], + void DrawWaveformBackground(wxDC & dc, const wxRect &rect, const double env[], float zoomMin, float zoomMax, bool dB, const sampleCount where[], sampleCount ssel0, sampleCount ssel1, bool drawEnvelope, bool bIsSyncLockSelected); - void DrawMinMaxRMS(wxDC &dc, const wxRect &r, const double env[], + void DrawMinMaxRMS(wxDC &dc, const wxRect &rect, const double env[], float zoomMin, float zoomMax, bool dB, const WaveDisplay &display, bool /* showProgress */, bool muted #ifdef EXPERIMENTAL_OUTPUT_DISPLAY , const float gain #endif ); - void DrawIndividualSamples(wxDC & dc, const wxRect & r, + void DrawIndividualSamples(wxDC & dc, const wxRect & rect, float zoomMin, float zoomMax, bool dB, WaveClip *clip, double t0, double pps, double h, - bool drawSamples, bool showPoints, bool muted); + bool bigPoints, bool showPoints, bool muted); - void DrawNegativeOffsetTrackArrows(wxDC & dc, const wxRect & r); + void DrawNegativeOffsetTrackArrows(wxDC & dc, const wxRect & rect); - void DrawEnvelope(wxDC & dc, const wxRect & r, const double env[], + void DrawEnvelope(wxDC & dc, const wxRect & rect, const double env[], float zoomMin, float zoomMax, bool dB); - void DrawEnvLine(wxDC & dc, const wxRect & r, int x, int y, int cy, bool top); + void DrawEnvLine(wxDC & dc, const wxRect & rect, int x, int y, int cy, bool top); // Preference values float mdBrange; // "/GUI/EnvdBRange" From 1b125f8fe3fd0c111e2a8840c74621c9bf9b66a2 Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Tue, 9 Jun 2015 21:43:00 -0400 Subject: [PATCH 12/36] more variable name changes --- src/TrackArtist.cpp | 239 ++++++++++++++++++++++---------------------- src/TrackArtist.h | 4 +- 2 files changed, 121 insertions(+), 122 deletions(-) diff --git a/src/TrackArtist.cpp b/src/TrackArtist.cpp index b7502b68f..5eeafb298 100644 --- a/src/TrackArtist.cpp +++ b/src/TrackArtist.cpp @@ -941,11 +941,11 @@ float FromDB(float value, double dBRange) return pow(10.0, ((fabs(value) * dBRange) - dBRange) / 20.0)*sign; } -float ValueOfPixel(int y, int height, bool offset, +float ValueOfPixel(int yy, int height, bool offset, bool dB, double dBRange, float zoomMin, float zoomMax) { wxASSERT(height > 0); - float v = zoomMax - (y / (float)height) * (zoomMax - zoomMin); + float v = zoomMax - (yy / (float)height) * (zoomMax - zoomMin); if (offset) { if (v > 0.0) v += .5; @@ -1008,26 +1008,26 @@ void TrackArtist::DrawWaveformBackground(wxDC &dc, const wxRect &rect, const dou int maxbot, lmaxbot = 0; int minbot, lminbot = 0; bool sel, lsel = false; - int x, lx = 0; + int xx, lx = 0; int l, w; dc.SetPen(*wxTRANSPARENT_PEN); dc.SetBrush(blankBrush); dc.DrawRectangle(rect); - for (x = 0; x < rect.width; x++) { + for (xx = 0; xx < rect.width; ++xx) { // First we compute the truncated shape of the waveform background. // If drawEnvelope is true, then we compute the lower border of the // envelope. - maxtop = GetWaveYPos(env[x], zoomMin, zoomMax, + maxtop = GetWaveYPos(env[xx], zoomMin, zoomMax, h, dB, true, mdBrange, true); - maxbot = GetWaveYPos(env[x], zoomMin, zoomMax, + maxbot = GetWaveYPos(env[xx], zoomMin, zoomMax, h, dB, false, mdBrange, true); - mintop = GetWaveYPos(-env[x], zoomMin, zoomMax, + mintop = GetWaveYPos(-env[xx], zoomMin, zoomMax, h, dB, false, mdBrange, true); - minbot = GetWaveYPos(-env[x], zoomMin, zoomMax, + minbot = GetWaveYPos(-env[xx], zoomMin, zoomMax, h, dB, true, mdBrange, true); // Make sure it's odd so that a that max and min mirror each other @@ -1040,7 +1040,7 @@ void TrackArtist::DrawWaveformBackground(wxDC &dc, const wxRect &rect, const dou } // We don't draw selection color for sync-lock selected tracks. - sel = (ssel0 <= where[x] && where[x + 1] < ssel1) && !bIsSyncLockSelected; + sel = (ssel0 <= where[xx] && where[xx + 1] < ssel1) && !bIsSyncLockSelected; if (lmaxtop == maxtop && lmintop == mintop && @@ -1053,7 +1053,7 @@ void TrackArtist::DrawWaveformBackground(wxDC &dc, const wxRect &rect, const dou dc.SetBrush(lsel ? selectedBrush : unselectedBrush); l = rect.x + lx; - w = x - lx; + w = xx - lx; if (lmaxbot < lmintop - 1) { dc.DrawRectangle(l, rect.y + lmaxtop, w, lmaxbot - lmaxtop); dc.DrawRectangle(l, rect.y + lmintop, w, lminbot - lmintop); @@ -1067,12 +1067,12 @@ void TrackArtist::DrawWaveformBackground(wxDC &dc, const wxRect &rect, const dou lmaxbot = maxbot; lminbot = minbot; lsel = sel; - lx = x; + lx = xx; } dc.SetBrush(lsel ? selectedBrush : unselectedBrush); l = rect.x + lx; - w = x - lx; + w = xx - lx; if (lmaxbot < lmintop - 1) { dc.DrawRectangle(l, rect.y + lmaxtop, w, lmaxbot - lmaxtop); dc.DrawRectangle(l, rect.y + lmintop, w, lminbot - lmintop); @@ -1085,10 +1085,10 @@ void TrackArtist::DrawWaveformBackground(wxDC &dc, const wxRect &rect, const dou if (bIsSyncLockSelected && ssel0 < ssel1) { // Find the beginning/end of the selection int begin, end; - for (x = 0; x < rect.width && where[x] < ssel0; ++x); - begin = x; - for (; x < rect.width && where[x] < ssel1; ++x); - end = x; + for (xx = 0; xx < rect.width && where[xx] < ssel0; ++xx); + begin = xx; + for (; xx < rect.width && where[xx] < ssel1; ++xx); + end = xx; DrawSyncLockTiles(&dc, wxRect(rect.x + begin, rect.y, end - 1 - begin, rect.height)); } @@ -1126,7 +1126,6 @@ void TrackArtist::DrawMinMaxRMS(wxDC &dc, const wxRect &rect, const double env[] int *r2 = new int[rect.width]; int *clipped = NULL; int clipcnt = 0; - int x; if (mShowClipping) { clipped = new int[rect.width]; @@ -1139,14 +1138,14 @@ void TrackArtist::DrawMinMaxRMS(wxDC &dc, const wxRect &rect, const double env[] bool drawWaveform = true; dc.SetPen(muted ? muteSamplePen : samplePen); - for (x = 0; x < rect.width; x++) { - int xx = rect.x + x; + for (int x0 = 0; x0 < rect.width; ++x0) { + int xx = rect.x + x0; double v; #ifdef EXPERIMENTAL_OUTPUT_DISPLAY //JWA: "gain" variable passed to function includes the pan value and is used below 4/14/13 - v = min[x] * env[x] * gain; + v = min[x0] * env[x0] * gain; #else - v = min[x] * env[x]; + v = min[x0] * env[x0]; #endif if (clipped && mShowClipping && (v <= -MAX_AUDIO)) { @@ -1158,9 +1157,9 @@ void TrackArtist::DrawMinMaxRMS(wxDC &dc, const wxRect &rect, const double env[] rect.height, dB, true, mdBrange, true); #ifdef EXPERIMENTAL_OUTPUT_DISPLAY - v = max[x] * env[x] * gain; + v = max[x0] * env[x0] * gain; #else - v = max[x] * env[x]; + v = max[x0] * env[x0]; #endif if (clipped && mShowClipping && (v >= MAX_AUDIO)) { @@ -1173,7 +1172,7 @@ void TrackArtist::DrawMinMaxRMS(wxDC &dc, const wxRect &rect, const double env[] // JKC: This adjustment to h1 and h2 ensures that the drawn // waveform is continuous. - if (x > 0) { + if (x0 > 0) { if (h1 < lasth2) { h1 = lasth2 - 1; } @@ -1185,38 +1184,38 @@ void TrackArtist::DrawMinMaxRMS(wxDC &dc, const wxRect &rect, const double env[] lasth2 = h2; #ifdef EXPERIMENTAL_OUTPUT_DISPLAY - r1[x] = GetWaveYPos(-rms[x] * env[x]*gain, zoomMin, zoomMax, + r1[x0] = GetWaveYPos(-rms[x0] * env[x0]*gain, zoomMin, zoomMax, rect.height, dB, true, mdBrange, true); - r2[x] = GetWaveYPos(rms[x] * env[x]*gain, zoomMin, zoomMax, + r2[x0] = GetWaveYPos(rms[xx0 * env[x0]*gain, zoomMin, zoomMax, rect.height, dB, true, mdBrange, true); #else - r1[x] = GetWaveYPos(-rms[x] * env[x], zoomMin, zoomMax, + r1[x0] = GetWaveYPos(-rms[x0] * env[x0], zoomMin, zoomMax, rect.height, dB, true, mdBrange, true); - r2[x] = GetWaveYPos(rms[x] * env[x], zoomMin, zoomMax, + r2[x0] = GetWaveYPos(rms[x0] * env[x0], zoomMin, zoomMax, rect.height, dB, true, mdBrange, true); #endif // Make sure the rms isn't larger than the waveform min/max - if (r1[x] > h1 - 1) { - r1[x] = h1 - 1; + if (r1[x0] > h1 - 1) { + r1[x0] = h1 - 1; } - if (r2[x] < h2 + 1) { - r2[x] = h2 + 1; + if (r2[x0] < h2 + 1) { + r2[x0] = h2 + 1; } - if (r2[x] > r1[x]) { - r2[x] = r1[x]; + if (r2[x0] > r1[x0]) { + r2[x0] = r1[x0]; } - if (bl[x] <= -1) { + if (bl[x0] <= -1) { if (drawStripes) { // TODO:unify with buffer drawing. - dc.SetPen((bl[x] % 2) ? muteSamplePen : samplePen); - for (int y = 0; y < rect.height / 25 + 1; y++) { + dc.SetPen((bl[x0] % 2) ? muteSamplePen : samplePen); + for (int yy = 0; yy < rect.height / 25 + 1; ++yy) { // we are drawing over the buffer, but I think DrawLine takes care of this. AColor::Line(dc, xx, - rect.y + 25 * y + (x /*+pixAnimOffset*/) % 25, + rect.y + 25 * yy + (x0 /*+pixAnimOffset*/) % 25, xx, - rect.y + 25 * y + (x /*+pixAnimOffset*/) % 25 + 6); //take the min so we don't draw past the edge + rect.y + 25 * yy + (x0 /*+pixAnimOffset*/) % 25 + 6); //take the min so we don't draw past the edge } } @@ -1225,10 +1224,10 @@ void TrackArtist::DrawMinMaxRMS(wxDC &dc, const wxRect &rect, const double env[] if (drawWaveform) { int triX; dc.SetPen(samplePen); - triX = fabs((double)((x + pixAnimOffset) % (2 * rect.height)) - rect.height) + rect.height; - for (int y = 0; y < rect.height; y++) { - if ((y + triX) % rect.height == 0) { - dc.DrawPoint(xx, rect.y + y); + triX = fabs((double)((x0 + pixAnimOffset) % (2 * rect.height)) - rect.height) + rect.height; + for (int yy = 0; yy < rect.height; ++yy) { + if ((yy + triX) % rect.height == 0) { + dc.DrawPoint(xx, rect.y + yy); } } } @@ -1243,12 +1242,12 @@ void TrackArtist::DrawMinMaxRMS(wxDC &dc, const wxRect &rect, const double env[] // Stroke rms over the min-max dc.SetPen(muted ? muteRmsPen : rmsPen); - for (int x = 0; x < rect.width; x++) { - int xx = rect.x + x; - if (bl[x] <= -1) { + for (int x0 = 0; x0 < rect.width; ++x0) { + int xx = rect.x + x0; + if (bl[x0] <= -1) { } - else if (r1[x] != r2[x]) { - AColor::Line(dc, xx, rect.y + r2[x], xx, rect.y + r1[x]); + else if (r1[x0] != r2[x0]) { + AColor::Line(dc, xx, rect.y + r2[x0], xx, rect.y + r1[x0]); } } @@ -1384,17 +1383,17 @@ void TrackArtist::DrawEnvelope(wxDC &dc, const wxRect &rect, const double env[], dc.SetPen(AColor::envelopePen); - for (int x = 0; x < rect.width; x++) { - int cenvTop = GetWaveYPos(env[x], zoomMin, zoomMax, + for (int x0 = 0; x0 < rect.width; ++x0) { + int cenvTop = GetWaveYPos(env[x0], zoomMin, zoomMax, h, dB, true, mdBrange, true); - int cenvBot = GetWaveYPos(-env[x], zoomMin, zoomMax, + int cenvBot = GetWaveYPos(-env[x0], zoomMin, zoomMax, h, dB, true, mdBrange, true); - int envTop = GetWaveYPos(env[x], zoomMin, zoomMax, + int envTop = GetWaveYPos(env[x0], zoomMin, zoomMax, h, dB, true, mdBrange, false); - int envBot = GetWaveYPos(-env[x], zoomMin, zoomMax, + int envBot = GetWaveYPos(-env[x0], zoomMin, zoomMax, h, dB, true, mdBrange, false); // Make the collision at zero actually look solid @@ -1404,23 +1403,23 @@ void TrackArtist::DrawEnvelope(wxDC &dc, const wxRect &rect, const double env[], cenvBot = value + 4; } - DrawEnvLine(dc, rect, x, envTop, cenvTop, true); - DrawEnvLine(dc, rect, x, envBot, cenvBot, false); + DrawEnvLine(dc, rect, x0, envTop, cenvTop, true); + DrawEnvLine(dc, rect, x0, envBot, cenvBot, false); } } -void TrackArtist::DrawEnvLine(wxDC &dc, const wxRect &rect, int x, int y, int cy, bool top) +void TrackArtist::DrawEnvLine(wxDC &dc, const wxRect &rect, int x0, int y0, int cy, bool top) { - int xx = rect.x + x; + int xx = rect.x + x0; int yy = rect.y + cy; - if (y < 0) { - if (x % 4 != 3) { + if (y0 < 0) { + if (x0 % 4 != 3) { AColor::Line(dc, xx, yy, xx, yy + 3); } } - else if (y > rect.height) { - if (x % 4 != 3) { + else if (y0 > rect.height) { + if (x0 % 4 != 3) { AColor::Line(dc, xx, yy - 3, xx, yy); } } @@ -1458,19 +1457,19 @@ void TrackArtist::DrawWaveform(WaveTrack *track, for (int i = 0; iGetNumCachedLocations(); i++) { WaveTrack::Location loc = track->GetCachedLocation(i); - double x = (loc.pos - viewInfo->h) * viewInfo->zoom; - if (x >= 0 && x < rect.width) { + double xx = (loc.pos - viewInfo->h) * viewInfo->zoom; + if (xx >= 0 && xx < rect.width) { dc.SetPen(*wxGREY_PEN); - AColor::Line(dc, (int) (rect.x + x - 1), rect.y, (int) (rect.x + x - 1), rect.y + rect.height); + AColor::Line(dc, (int) (rect.x + xx - 1), rect.y, (int) (rect.x + xx - 1), rect.y + rect.height); if (loc.typ == WaveTrack::locationCutLine) { dc.SetPen(*wxRED_PEN); } else { dc.SetPen(*wxBLACK_PEN); } - AColor::Line(dc, (int) (rect.x + x), rect.y, (int) (rect.x + x), rect.y + rect.height); + AColor::Line(dc, (int) (rect.x + xx), rect.y, (int) (rect.x + xx), rect.y + rect.height); dc.SetPen(*wxGREY_PEN); - AColor::Line(dc, (int) (rect.x + x + 1), rect.y, (int) (rect.x + x + 1), rect.y + rect.height); + AColor::Line(dc, (int) (rect.x + xx + 1), rect.y, (int) (rect.x + xx + 1), rect.y + rect.height); } } @@ -1775,18 +1774,18 @@ void TrackArtist::DrawTimeSlider(wxDC & dc, int firstBar = yTop + taper + taper / 2; int nBars = (yBot - yTop - taper * 3) / barSpacing + 1; xLeft += (width - barWidth + 1) / 2; - int y; + int yy; int i; AColor::Light(&dc, false); for (i = 0;i < nBars; i++) { - y = firstBar + barSpacing * i; - AColor::Line(dc, xLeft, y, xLeft + barWidth, y); + yy = firstBar + barSpacing * i; + AColor::Line(dc, xLeft, yy, xLeft + barWidth, yy); } AColor::Dark(&dc, false); for(i = 0;i < nBars; i++){ - y = firstBar + barSpacing * i + 1; - AColor::Line(dc, xLeft, y, xLeft + barWidth, y); + yy = firstBar + barSpacing * i + 1; + AColor::Line(dc, xLeft, yy, xLeft + barWidth, yy); } } @@ -1989,17 +1988,17 @@ void TrackArtist::DrawClipSpectrum(WaveTrackCache &cache, bool *yGrid; yGrid = new bool[mid.height]; - for (int y = 0; y < mid.height; y++) { - float n = (float(y) / mid.height*scale2 - lmin2) * 12; - float n2 = (float(y + 1) / mid.height*scale2 - lmin2) * 12; + for (int yy = 0; yy < mid.height; ++yy) { + float n = (float(yy) / mid.height*scale2 - lmin2) * 12; + float n2 = (float(yy + 1) / mid.height*scale2 - lmin2) * 12; float f = float(minFreq) / (fftSkipPoints + 1)*powf(2.0f, n / 12.0f + lmin2); float f2 = float(minFreq) / (fftSkipPoints + 1)*powf(2.0f, n2 / 12.0f + lmin2); n = logf(f / 440) / log2 * 12; n2 = logf(f2 / 440) / log2 * 12; if (floor(n) < floor(n2)) - yGrid[y] = true; + yGrid[yy] = true; else - yGrid[y] = false; + yGrid[yy] = false; } #endif //EXPERIMENTAL_FFT_Y_GRID @@ -2180,7 +2179,7 @@ void TrackArtist::DrawClipSpectrum(WaveTrackCache &cache, } clip->mSpecPxCache->values[xx * mid.height + yy] = value; yy2 = yy2_base; - } // each y + } // each yy } // is logF } // each xx @@ -2282,7 +2281,7 @@ void TrackArtist::DrawClipSpectrum(WaveTrackCache &cache, data[px++] = rv; data[px++] = gv; data[px] = bv; - } // each y + } // each yy } // logF } // each xx @@ -2477,8 +2476,8 @@ const char *LookupAtomAttribute(Alg_note_ptr note, Alg_attribute attr, char *def // particular, line plots will be correct at any zoom (limited by floating point // precision). #define CLIP_MAX 16000 -#define CLIP(x) { long c = (x); if (c < -CLIP_MAX) c = -CLIP_MAX; \ - if (c > CLIP_MAX) c = CLIP_MAX; (x) = c; } +#define CLIP(xx) { long c = (xx); if (c < -CLIP_MAX) c = -CLIP_MAX; \ + if (c > CLIP_MAX) c = CLIP_MAX; (xx) = c; } #define RED(i) ( unsigned char )( (((i) >> 16) & 0xff) ) #define GREEN(i) ( unsigned char )( (((i) >> 8) & 0xff) ) @@ -2588,9 +2587,9 @@ void TrackArtist::DrawNoteBackground(NoteTrack *track, wxDC &dc, // map beat to time double t = seq->get_time_map()->beat_to_time(next_bar_beat); // map time to position - int x = TIME_TO_X(t + track->GetOffset()); - if (x > right) break; - AColor::Line(dc, x, sel.y, x, sel.y + sel.height); + int xx = TIME_TO_X(t + track->GetOffset()); + if (xx > right) break; + AColor::Line(dc, xx, sel.y, xx, sel.y + sel.height); next_bar_beat += beats_per_measure; } } @@ -2733,16 +2732,16 @@ void TrackArtist::DrawNoteTrack(NoteTrack *track, Alg_note_ptr note = (Alg_note_ptr) evt; // if the note's channel is visible if (visibleChannels & (1 << (evt->chan & 15))) { - double x = note->time + track->GetOffset(); - double x1 = x + note->dur; - if (x < h1 && x1 > h) { // omit if outside box + double xx = note->time + track->GetOffset(); + double x1 = xx + note->dur; + if (xx < h1 && x1 > h) { // omit if outside box const char *shape = NULL; if (note->loud > 0.0 || 0 == (shape = IsShape(note))) { wxRect nr; // "note rectangle" nr.y = track->PitchToY(note->pitch); nr.height = track->GetPitchHeight(); - nr.x = rect.x + (int) ((x - h) * pps); + nr.x = rect.x + (int) ((xx - h) * pps); nr.width = (int) ((note->dur * pps) + 0.5); if (nr.x + nr.width >= rect.x && nr.x < rect.x + rect.width) { @@ -2799,7 +2798,7 @@ void TrackArtist::DrawNoteTrack(NoteTrack *track, // add 0.5 to pitch because pitches are plotted with // height = PITCH_HEIGHT; thus, the center is raised // by PITCH_HEIGHT * 0.5 - int y = track->PitchToY(note->pitch); + int yy = track->PitchToY(note->pitch); long linecolor = LookupIntAttribute(note, linecolori, -1); long linethick = LookupIntAttribute(note, linethicki, 1); long fillcolor = -1; @@ -2829,44 +2828,44 @@ void TrackArtist::DrawNoteTrack(NoteTrack *track, if (shape == line) { // extreme zooms caues problems under windows, so we have to do some // clipping before calling display routine - if (x < h) { // clip line on left - y = int((y + (y1 - y) * (h - x) / (x1 - x)) + 0.5); - x = h; + if (xx < h) { // clip line on left + yy = int((yy + (y1 - yy) * (h - xx) / (x1 - xx)) + 0.5); + xx = h; } if (x1 > h1) { // clip line on right - y1 = int((y + (y1 - y) * (h1 - x) / (x1 - x)) + 0.5); + y1 = int((yy + (y1 - yy) * (h1 - xx) / (x1 - xx)) + 0.5); x1 = h1; } - AColor::Line(dc, TIME_TO_X(x), y, TIME_TO_X(x1), y1); + AColor::Line(dc, TIME_TO_X(xx), yy, TIME_TO_X(x1), y1); } else if (shape == rectangle) { - if (x < h) { // clip on left, leave 10 pixels to spare - x = h - (linethick + 10) / pps; + if (xx < h) { // clip on left, leave 10 pixels to spare + xx = h - (linethick + 10) / pps; } if (x1 > h1) { // clip on right, leave 10 pixels to spare x1 = h1 + (linethick + 10) / pps; } - dc.DrawRectangle(TIME_TO_X(x), y, int((x1 - x) * pps + 0.5), y1 - y + 1); + dc.DrawRectangle(TIME_TO_X(xx), yy, int((x1 - xx) * pps + 0.5), y1 - yy + 1); } else if (shape == triangle) { wxPoint points[3]; - points[0].x = TIME_TO_X(x); + points[0].x = TIME_TO_X(xx); CLIP(points[0].x); - points[0].y = y; + points[0].y = yy; points[1].x = TIME_TO_X(LookupRealAttribute(note, x1r, note->pitch)); CLIP(points[1].x); points[1].y = y1; - points[2].x = TIME_TO_X(LookupRealAttribute(note, x2r, x)); + points[2].x = TIME_TO_X(LookupRealAttribute(note, x2r, xx)); CLIP(points[2].x); points[2].y = track->PitchToY(LookupRealAttribute(note, y2r, note->pitch)); dc.DrawPolygon(3, points); } else if (shape == polygon) { wxPoint points[20]; // upper bound of 20 sides - points[0].x = TIME_TO_X(x); + points[0].x = TIME_TO_X(xx); CLIP(points[0].x); - points[0].y = y; - points[1].x = TIME_TO_X(LookupRealAttribute(note, x1r, x)); + points[0].y = yy; + points[1].x = TIME_TO_X(LookupRealAttribute(note, x1r, xx)); CLIP(points[1].x); points[1].y = y1; - points[2].x = TIME_TO_X(LookupRealAttribute(note, x2r, x)); + points[2].x = TIME_TO_X(LookupRealAttribute(note, x2r, xx)); CLIP(points[2].x); points[2].y = track->PitchToY(LookupRealAttribute(note, y2r, note->pitch)); int n = 3; @@ -2887,11 +2886,11 @@ void TrackArtist::DrawNoteTrack(NoteTrack *track, } dc.DrawPolygon(n, points); } else if (shape == oval) { - int ix = TIME_TO_X(x); + int ix = TIME_TO_X(xx); CLIP(ix); - int ix1 = int((x1 - x) * pps + 0.5); + int ix1 = int((x1 - xx) * pps + 0.5); if (ix1 > CLIP_MAX * 2) ix1 = CLIP_MAX * 2; // CLIP a width - dc.DrawEllipse(ix, y, ix1, y1 - y + 1); + dc.DrawEllipse(ix, yy, ix1, y1 - yy + 1); } else if (shape == text) { if (linecolor != -1) dc.SetTextForeground(wxColour(RED(linecolor), @@ -2948,10 +2947,10 @@ void TrackArtist::DrawNoteTrack(NoteTrack *track, GREEN(fillcolor), BLUE(fillcolor)), 1, wxSOLID)); - dc.DrawRectangle(TIME_TO_X(x) + hoffset, y + voffset, + dc.DrawRectangle(TIME_TO_X(xx) + hoffset, yy + voffset, textWidth, textHeight); } - dc.DrawText(LAT1CTOWX(s), TIME_TO_X(x) + hoffset, y + voffset); + dc.DrawText(LAT1CTOWX(s), TIME_TO_X(xx) + hoffset, yy + voffset); } } } @@ -3115,11 +3114,11 @@ void TrackArtist::DrawSyncLockTiles(wxDC *dc, wxRect rect) // Make sure blockX is non-negative if (blockX < 0) blockX += 5; - int x = 0; - while (x < rect.width) { + int xx = 0; + while (xx < rect.width) { int width = syncLockBitmap.GetWidth() - xOffset; - if (x + width > rect.width) - width = rect.width - x; + if (xx + width > rect.width) + width = rect.width - xx; // // Draw each row in this column @@ -3143,12 +3142,12 @@ void TrackArtist::DrawSyncLockTiles(wxDC *dc, wxRect rect) // Make sure blockY is non-negative if (blockY < 0) blockY += 5; - int y = 0; - while (y < rect.height) + int yy = 0; + while (yy < rect.height) { int height = syncLockBitmap.GetHeight() - yOffset; - if (y + height > rect.height) - height = rect.height - y; + if (yy + height > rect.height) + height = rect.height - yy; // AWD: draw blocks according to our pattern if ((blockX == 0 && blockY == 0) || (blockX == 2 && blockY == 1) || @@ -3160,10 +3159,10 @@ void TrackArtist::DrawSyncLockTiles(wxDC *dc, wxRect rect) if (width != syncLockBitmap.GetWidth() || height != syncLockBitmap.GetHeight()) { wxBitmap subSyncLockBitmap = syncLockBitmap.GetSubBitmap(wxRect(xOffset, yOffset, width, height)); - dc->DrawBitmap(subSyncLockBitmap, rect.x + x, rect.y + y, true); + dc->DrawBitmap(subSyncLockBitmap, rect.x + xx, rect.y + yy, true); } else { - dc->DrawBitmap(syncLockBitmap, rect.x + x, rect.y + y, true); + dc->DrawBitmap(syncLockBitmap, rect.x + xx, rect.y + yy, true); } } @@ -3175,7 +3174,7 @@ void TrackArtist::DrawSyncLockTiles(wxDC *dc, wxRect rect) } else { // Move on in y, no more offset rows - y += gridH - yOffset; + yy += gridH - yOffset; yOffset = 0; } blockY = (blockY + 1) % 5; @@ -3189,7 +3188,7 @@ void TrackArtist::DrawSyncLockTiles(wxDC *dc, wxRect rect) } else { // Move on in x, no more offset rows - x += gridW - xOffset; + xx += gridW - xOffset; xOffset = 0; } blockX = (blockX + 1) % 5; diff --git a/src/TrackArtist.h b/src/TrackArtist.h index 471bdd191..9aa2a4d87 100644 --- a/src/TrackArtist.h +++ b/src/TrackArtist.h @@ -164,7 +164,7 @@ class AUDACITY_DLL_API TrackArtist { void DrawEnvelope(wxDC & dc, const wxRect & rect, const double env[], float zoomMin, float zoomMax, bool dB); - void DrawEnvLine(wxDC & dc, const wxRect & rect, int x, int y, int cy, bool top); + void DrawEnvLine(wxDC & dc, const wxRect & rect, int x0, int y0, int cy, bool top); // Preference values float mdBrange; // "/GUI/EnvdBRange" @@ -217,7 +217,7 @@ extern int GetWaveYPos(float value, float min, float max, int height, bool dB, bool outer, float dBr, bool clip); extern float FromDB(float value, double dBRange); -extern float ValueOfPixel(int y, int height, bool offset, +extern float ValueOfPixel(int yy, int height, bool offset, bool dB, double dBRange, float zoomMin, float zoomMax); #endif // define __AUDACITY_TRACKARTIST__ From 35e0897bf7a076e30b8d31f89e2a8c969ab57234 Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Mon, 8 Jun 2015 15:19:18 -0400 Subject: [PATCH 13/36] Avoid needless mix/max/rms calculation when showing individual samples. --- src/TrackArtist.cpp | 42 ++++++++++++++++++++++++------------------ src/TrackArtist.h | 4 ++-- src/WaveClip.cpp | 9 +++++---- 3 files changed, 31 insertions(+), 24 deletions(-) diff --git a/src/TrackArtist.cpp b/src/TrackArtist.cpp index 5eeafb298..d8f14be8e 100644 --- a/src/TrackArtist.cpp +++ b/src/TrackArtist.cpp @@ -988,7 +988,7 @@ void TrackArtist::DrawNegativeOffsetTrackArrows(wxDC &dc, const wxRect &rect) void TrackArtist::DrawWaveformBackground(wxDC &dc, const wxRect &rect, const double env[], float zoomMin, float zoomMax, bool dB, - const sampleCount where[], + const ViewInfo &viewInfo, double t0, double rate, sampleCount ssel0, sampleCount ssel1, bool drawEnvelope, bool bIsSyncLockSelected) { @@ -1015,7 +1015,10 @@ void TrackArtist::DrawWaveformBackground(wxDC &dc, const wxRect &rect, const dou dc.SetBrush(blankBrush); dc.DrawRectangle(rect); - for (xx = 0; xx < rect.width; ++xx) { + const double samplesPerPixel = rate / viewInfo.zoom; + double where = t0 * rate; + for (xx = 0; xx < rect.width; ++xx, where += samplesPerPixel) { + // First we compute the truncated shape of the waveform background. // If drawEnvelope is true, then we compute the lower border of the // envelope. @@ -1040,7 +1043,7 @@ void TrackArtist::DrawWaveformBackground(wxDC &dc, const wxRect &rect, const dou } // We don't draw selection color for sync-lock selected tracks. - sel = (ssel0 <= where[xx] && where[xx + 1] < ssel1) && !bIsSyncLockSelected; + sel = (ssel0 <= where && where + samplesPerPixel < ssel1) && !bIsSyncLockSelected; if (lmaxtop == maxtop && lmintop == mintop && @@ -1085,9 +1088,10 @@ void TrackArtist::DrawWaveformBackground(wxDC &dc, const wxRect &rect, const dou if (bIsSyncLockSelected && ssel0 < ssel1) { // Find the beginning/end of the selection int begin, end; - for (xx = 0; xx < rect.width && where[xx] < ssel0; ++xx); + double where = t0 * rate; + for (xx = 0; xx < rect.width && where < ssel0; ++xx, where += samplesPerPixel); begin = xx; - for (; xx < rect.width && where[xx] < ssel1; ++xx); + for (; xx < rect.width && where < ssel1; ++xx, where += samplesPerPixel); end = xx; DrawSyncLockTiles(&dc, wxRect(rect.x + begin, rect.y, end - 1 - begin, rect.height)); } @@ -1650,6 +1654,7 @@ void TrackArtist::DrawClipWaveform(WaveTrack *track, const double &tpre = params.tpre; const double &tpost = params.tpost; const double &t1 = params.t1; + const double &rate = params.rate; // Calculate sample-based offset-corrected selection @@ -1664,18 +1669,6 @@ void TrackArtist::DrawClipWaveform(WaveTrack *track, float zoomMin, zoomMax; track->GetDisplayBounds(&zoomMin, &zoomMax); - WaveDisplay display(mid.width); - bool isLoadingOD = false;//true if loading on demand block in sequence. - - // The WaveClip class handles the details of computing the shape - // of the waveform. The only way GetWaveDisplay will fail is if - // there's a serious error, like some of the waveform data can't - // be loaded. So if the function returns false, we can just exit. - if (!clip->GetWaveDisplay(display, - t0, pps, isLoadingOD)) { - return; - } - // Get the values of the envelope corresponding to each pixel // in the display, and use these to compute the height of the // track at each pixel @@ -1687,10 +1680,23 @@ void TrackArtist::DrawClipWaveform(WaveTrack *track, // the envelope and using a colored pen for the selected // part of the waveform DrawWaveformBackground(dc, mid, envValues, zoomMin, zoomMax, dB, - &display.where[0], ssel0, ssel1, drawEnvelope, + *viewInfo, t0, rate, + ssel0, ssel1, drawEnvelope, !track->GetSelected()); if (!showIndividualSamples) { + WaveDisplay display(mid.width); + bool isLoadingOD = false;//true if loading on demand block in sequence. + + // The WaveClip class handles the details of computing the shape + // of the waveform. The only way GetWaveDisplay will fail is if + // there's a serious error, like some of the waveform data can't + // be loaded. So if the function returns false, we can just exit. + if (!clip->GetWaveDisplay(display, + t0, pps, isLoadingOD)) { + return; + } + #ifdef EXPERIMENTAL_OUTPUT_DISPLAY DrawMinMaxRMS(dc, mid, envValues, zoomMin, zoomMax, dB, min, max, rms, bl, isLoadingOD, muted, track->GetChannelGain(track->GetChannel())); diff --git a/src/TrackArtist.h b/src/TrackArtist.h index 9aa2a4d87..9173a2f04 100644 --- a/src/TrackArtist.h +++ b/src/TrackArtist.h @@ -21,7 +21,7 @@ #include #include #include "Experimental.h" -#include "Sequence.h" +#include "audacity/Types.h" class wxDC; class wxRect; @@ -144,7 +144,7 @@ class AUDACITY_DLL_API TrackArtist { void DrawWaveformBackground(wxDC & dc, const wxRect &rect, const double env[], float zoomMin, float zoomMax, bool dB, - const sampleCount where[], + const ViewInfo &viewInfo, double t0, double rate, sampleCount ssel0, sampleCount ssel1, bool drawEnvelope, bool bIsSyncLockSelected); void DrawMinMaxRMS(wxDC &dc, const wxRect &rect, const double env[], diff --git a/src/WaveClip.cpp b/src/WaveClip.cpp index fd66e7c4c..3103f2001 100644 --- a/src/WaveClip.cpp +++ b/src/WaveClip.cpp @@ -349,7 +349,8 @@ public: #ifdef EXPERIMENTAL_USE_REALFFTF #include "FFT.h" -static void ComputeSpectrumUsingRealFFTf(float *buffer, HFFT hFFT, const float *window, int len, float *out) +static void ComputeSpectrumUsingRealFFTf + (float *buffer, HFFT hFFT, const float *window, int len, float *out) { int i; if(len > hFFT->Points*2) @@ -568,11 +569,11 @@ fillWhere(std::vector &where, int len, double bias, double correcti double t0, double rate, double samplesPerPixel) { // Be careful to make the first value non-negative - correction += 0.5 + bias; - where[0] = sampleCount(std::max(0.0, floor(correction + t0 * rate))); + const double w0 = 0.5 + correction + bias + t0 * rate; + where[0] = sampleCount(std::max(0.0, floor(w0))); for (sampleCount x = 1; x < len + 1; x++) where[x] = sampleCount( - floor(correction + t0 * rate + double(x) * samplesPerPixel) + floor(w0 + double(x) * samplesPerPixel) ); } From ab21f75c7737cc95659f73e692cf9b131e1d1ed0 Mon Sep 17 00:00:00 2001 From: Paul-Licameli Date: Sun, 19 Apr 2015 12:21:31 -0400 Subject: [PATCH 14/36] ViewInfo is becoming a smart class, not a dumb struct Now it has: A constructor XML attribute serializer functions (but no XML tag of its own) Also removed unused lastZoom --- src/LabelDialog.h | 2 +- src/Printing.cpp | 11 ++---- src/Project.cpp | 49 +++++------------------ src/ShuttleGui.h | 2 +- src/TrackArtist.h | 2 +- src/TrackPanel.h | 2 +- src/ViewInfo.cpp | 66 +++++++++++++++++++++++++++++++ src/ViewInfo.h | 9 ++++- src/widgets/AttachableScrollBar.h | 2 +- src/widgets/Ruler.h | 2 +- 10 files changed, 92 insertions(+), 55 deletions(-) diff --git a/src/LabelDialog.h b/src/LabelDialog.h index 29640d620..1aa46b7f2 100644 --- a/src/LabelDialog.h +++ b/src/LabelDialog.h @@ -25,7 +25,7 @@ class TrackList; class RowData; class EmptyLabelRenderer; class LabelTrack; -struct ViewInfo; +class ViewInfo; WX_DEFINE_ARRAY(RowData *, RowDataArray); diff --git a/src/Printing.cpp b/src/Printing.cpp index 0ce8710df..aa56d1960 100644 --- a/src/Printing.cpp +++ b/src/Printing.cpp @@ -15,6 +15,7 @@ #include "Audacity.h" +#include "Printing.h" #include #include @@ -29,7 +30,6 @@ #include "ViewInfo.h" #include "WaveTrack.h" #include "widgets/Ruler.h" -#include "Printing.h" // Globals, so that we remember settings from session to session static wxPrintData *gPrintData = NULL; @@ -80,13 +80,8 @@ bool AudacityPrintout::OnPrintPage(int WXUNUSED(page)) TrackArtist artist; artist.SetBackgroundBrushes(*wxWHITE_BRUSH, *wxWHITE_BRUSH, *wxWHITE_PEN, *wxWHITE_PEN); - ViewInfo viewInfo; - viewInfo.selectedRegion = SelectedRegion(); - viewInfo.vpos = 0; - viewInfo.h = 0.0; - viewInfo.screen = mTracks->GetEndTime() - viewInfo.h; - viewInfo.total = viewInfo.screen; - viewInfo.zoom = width / viewInfo.screen; + const double screenDuration = mTracks->GetEndTime(); + ViewInfo viewInfo(0.0, screenDuration, width / screenDuration); int y = rulerPageHeight; TrackListIterator iter(mTracks); diff --git a/src/Project.cpp b/src/Project.cpp index 7bd975546..ad61d1e10 100644 --- a/src/Project.cpp +++ b/src/Project.cpp @@ -780,6 +780,7 @@ AudacityProject::AudacityProject(wxWindow * parent, wxWindowID id, mTimerRecordCanceled(false), mMenuClose(false) , mbInitializingScrollbar(false) + , mViewInfo(0.0, 1.0, (44100.0 / 512.0)) { // Note that the first field of the status bar is a dummy, and it's width is set // to zero latter in the code. This field is needed for wxWidgets 2.8.12 because @@ -810,26 +811,6 @@ AudacityProject::AudacityProject(wxWindow * parent, wxWindowID id, // Initialize view info (shared with TrackPanel) // - // Selection - mViewInfo.selectedRegion = SelectedRegion(); - - // Horizontal scrollbar - mViewInfo.total = 1.0; - mViewInfo.screen = 1.0; - mViewInfo.h = 0.0; - mViewInfo.zoom = 44100.0 / 512.0; - - // Vertical scrollbar - mViewInfo.track = NULL; - mViewInfo.vpos = 0; - - mViewInfo.scrollStep = 16; - - mViewInfo.sbarH = 0; - mViewInfo.sbarScreen = 1; - mViewInfo.sbarTotal = 1; - mViewInfo.sbarScale = 1.0; - UpdatePrefs(); mLockPlayRegion = false; @@ -2902,6 +2883,12 @@ bool AudacityProject::HandleXMLTag(const wxChar *tag, const wxChar **attrs) if (!value || !XMLValueChecker::IsGoodString(value)) break; + if (mViewInfo.ReadXMLAttribute(attr, value)) { + // We need to save vpos now and restore it below + longVpos = std::max(longVpos, long(mViewInfo.vpos)); + continue; + } + if (!wxStrcmp(attr, wxT("datadir"))) { // @@ -2995,20 +2982,6 @@ bool AudacityProject::HandleXMLTag(const wxChar *tag, const wxChar **attrs) requiredTags++; } - else if (mViewInfo.selectedRegion - .HandleXMLAttribute(attr, value, wxT("sel0"), wxT("sel1"))) { - } - - else if (!wxStrcmp(attr, wxT("vpos"))) - // Just assign a variable, put the value in its place later - wxString(value).ToLong(&longVpos); - - else if (!wxStrcmp(attr, wxT("h"))) - Internat::CompatibleToDouble(value, &mViewInfo.h); - - else if (!wxStrcmp(attr, wxT("zoom"))) - Internat::CompatibleToDouble(value, &mViewInfo.zoom); - else if (!wxStrcmp(attr, wxT("rate"))) { Internat::CompatibleToDouble(value, &mRate); GetSelectionBar()->SetRate(mRate); @@ -3202,12 +3175,8 @@ void AudacityProject::WriteXML(XMLWriter &xmlFile) xmlFile.WriteAttr(wxT("projname"), projName); xmlFile.WriteAttr(wxT("version"), wxT(AUDACITY_FILE_FORMAT_VERSION)); xmlFile.WriteAttr(wxT("audacityversion"), AUDACITY_VERSION_STRING); - mViewInfo.selectedRegion - .WriteXMLAttributes(xmlFile, wxT("sel0"), wxT("sel1")); - // PRL: to do: persistence of other fields of the selection - xmlFile.WriteAttr(wxT("vpos"), mViewInfo.vpos); - xmlFile.WriteAttr(wxT("h"), mViewInfo.h, 10); - xmlFile.WriteAttr(wxT("zoom"), mViewInfo.zoom, 10); + + mViewInfo.WriteXMLAttributes(xmlFile); xmlFile.WriteAttr(wxT("rate"), mRate); xmlFile.WriteAttr(wxT("snapto"), GetSnapTo() ? wxT("on") : wxT("off")); xmlFile.WriteAttr(wxT("selectionformat"), GetSelectionFormat()); diff --git a/src/ShuttleGui.h b/src/ShuttleGui.h index 4885b64c5..3839c7ab0 100644 --- a/src/ShuttleGui.h +++ b/src/ShuttleGui.h @@ -325,7 +325,7 @@ class GuiWaveTrack; class AdornedRulerPanel; class RulerPanel; class AttachableScrollBar; -struct ViewInfo; +class ViewInfo; #include // to get wxSB_HORIZONTAL // CreateStdButtonSizer defs...should probably move to widgets subdir diff --git a/src/TrackArtist.h b/src/TrackArtist.h index 9173a2f04..49d4e347d 100644 --- a/src/TrackArtist.h +++ b/src/TrackArtist.h @@ -37,7 +37,7 @@ class LabelTrack; class TimeTrack; class TrackList; class Ruler; -struct ViewInfo; +class ViewInfo; #ifndef uchar typedef unsigned char uchar; diff --git a/src/TrackPanel.h b/src/TrackPanel.h index 80800b03c..1918142c4 100644 --- a/src/TrackPanel.h +++ b/src/TrackPanel.h @@ -45,7 +45,7 @@ class AudacityProject; class TrackPanelAx; -struct ViewInfo; +class ViewInfo; WX_DEFINE_ARRAY(LWSlider *, LWSliderArray); diff --git a/src/ViewInfo.cpp b/src/ViewInfo.cpp index e69de29bb..041570665 100644 --- a/src/ViewInfo.cpp +++ b/src/ViewInfo.cpp @@ -0,0 +1,66 @@ +/********************************************************************** + +Audacity: A Digital Audio Editor + +ViewInfo.cpp + +Paul Licameli + +**********************************************************************/ + +#include "ViewInfo.h" + +#include "Internat.h" +#include "xml/XMLWriter.h" + +ViewInfo::ViewInfo(double start, double screenDuration, double pixelsPerSecond) + : selectedRegion() + , track(0) + , vpos(0) + , h(start) + , screen(screenDuration) + , total(screen) + , zoom(pixelsPerSecond) + + , sbarH(0) + , sbarScreen(1) + , sbarTotal(1) + , sbarScale(1.0) + , scrollStep(16) + + , bUpdateTrackIndicator(true) +{ +} + +void ViewInfo::WriteXMLAttributes(XMLWriter &xmlFile) +{ + selectedRegion.WriteXMLAttributes(xmlFile, wxT("sel0"), wxT("sel1")); + xmlFile.WriteAttr(wxT("vpos"), vpos); + xmlFile.WriteAttr(wxT("h"), h, 10); + xmlFile.WriteAttr(wxT("zoom"), zoom, 10); +} + +bool ViewInfo::ReadXMLAttribute(const wxChar *attr, const wxChar *value) +{ + if (selectedRegion.HandleXMLAttribute(attr, value, wxT("sel0"), wxT("sel1"))) + return true; + + if (!wxStrcmp(attr, wxT("vpos"))) { + long longVpos; + wxString(value).ToLong(&longVpos); + vpos = int(longVpos); + return true; + } + + if (!wxStrcmp(attr, wxT("h"))) { + Internat::CompatibleToDouble(value, &h); + return true; + } + + if (!wxStrcmp(attr, wxT("zoom"))) { + Internat::CompatibleToDouble(value, &zoom); + return true; + } + + return false; +} diff --git a/src/ViewInfo.h b/src/ViewInfo.h index d27965aa3..a39cd296c 100644 --- a/src/ViewInfo.h +++ b/src/ViewInfo.h @@ -18,7 +18,11 @@ const double gMaxZoom = 6000000, class Track; -struct ViewInfo { +class AUDACITY_DLL_API ViewInfo +{ +public: + + ViewInfo(double start, double screenDuration, double pixelsPerSecond); // Current selection @@ -52,6 +56,9 @@ struct ViewInfo { // drawing the waveform. Maybe this should be put somewhere else? bool bUpdateTrackIndicator; + + void WriteXMLAttributes(XMLWriter &xmlFile); + bool ReadXMLAttribute(const wxChar *attr, const wxChar *value); }; #endif diff --git a/src/widgets/AttachableScrollBar.h b/src/widgets/AttachableScrollBar.h index a05f180bd..eb20ea575 100644 --- a/src/widgets/AttachableScrollBar.h +++ b/src/widgets/AttachableScrollBar.h @@ -19,7 +19,7 @@ #include -struct ViewInfo; +class ViewInfo; class AUDACITY_DLL_API AttachableScrollBar : public wxScrollBar diff --git a/src/widgets/Ruler.h b/src/widgets/Ruler.h index d1133f22d..d5b542af3 100644 --- a/src/widgets/Ruler.h +++ b/src/widgets/Ruler.h @@ -19,7 +19,7 @@ #include "../Envelope.h" #include "../Experimental.h" -struct ViewInfo; +class ViewInfo; class AudacityProject; class TimeTrack; class SnapManager; From 8ba9ea5621941f3f5aa8162508eb81743ff2ada4 Mon Sep 17 00:00:00 2001 From: Paul-Licameli Date: Sun, 19 Apr 2015 11:14:02 -0400 Subject: [PATCH 15/36] ViewInfo has a base class, ZoomInfo, containing only what TrackArtist needs besides the SelectedRegion --- src/ViewInfo.cpp | 20 ++++++++++++++------ src/ViewInfo.h | 25 +++++++++++++++++++------ 2 files changed, 33 insertions(+), 12 deletions(-) diff --git a/src/ViewInfo.cpp b/src/ViewInfo.cpp index 041570665..33b2ad78e 100644 --- a/src/ViewInfo.cpp +++ b/src/ViewInfo.cpp @@ -13,21 +13,29 @@ Paul Licameli #include "Internat.h" #include "xml/XMLWriter.h" -ViewInfo::ViewInfo(double start, double screenDuration, double pixelsPerSecond) - : selectedRegion() - , track(0) - , vpos(0) +ZoomInfo::ZoomInfo(double start, double screenDuration, double pixelsPerSecond) + : vpos(0) , h(start) , screen(screenDuration) - , total(screen) , zoom(pixelsPerSecond) +{ +} +ZoomInfo::~ZoomInfo() +{ +} + + +ViewInfo::ViewInfo(double start, double screenDuration, double pixelsPerSecond) + : ZoomInfo(start, screenDuration, pixelsPerSecond) + , selectedRegion() + , track(NULL) + , total(screen) , sbarH(0) , sbarScreen(1) , sbarTotal(1) , sbarScale(1.0) , scrollStep(16) - , bUpdateTrackIndicator(true) { } diff --git a/src/ViewInfo.h b/src/ViewInfo.h index a39cd296c..013006b3d 100644 --- a/src/ViewInfo.h +++ b/src/ViewInfo.h @@ -18,10 +18,28 @@ const double gMaxZoom = 6000000, class Track; -class AUDACITY_DLL_API ViewInfo + +// The subset of ViewInfo information (other than selection) +// that is sufficient for purposes of TrackArtist, +// and for computing conversions between track times and pixel positions. +class AUDACITY_DLL_API ZoomInfo { public: + ZoomInfo(double start, double duration, double pixelsPerSecond); + ~ZoomInfo(); + int vpos; // vertical scroll pos + + double h; // h pos in secs + + double screen; // screen width in secs + double zoom; // pixels per second +}; + +class AUDACITY_DLL_API ViewInfo + : public ZoomInfo +{ +public: ViewInfo(double start, double screenDuration, double pixelsPerSecond); // Current selection @@ -31,13 +49,8 @@ public: // Scroll info Track *track; // first visible track - int vpos; // vertical scroll pos - double h; // h pos in secs - double screen; // screen width in secs double total; // total width in secs - double zoom; // pixels per second - // Current horizontal scroll bar positions, in pixels wxInt64 sbarH; wxInt64 sbarScreen; From 5a6d5d1443e7ecfff167825dcd1d75e2a96ca6d9 Mon Sep 17 00:00:00 2001 From: Paul-Licameli Date: Sun, 19 Apr 2015 19:26:36 -0400 Subject: [PATCH 16/36] Add and use some ZoomInfo and ViewInfo member functions, so we can eliminate... ... miscellaneous direct uses of ZoomInfo::zoom to test and set zoom level. This includes all the remaining assignments to it. But moving TrackInfo::PositionToTime and TrackInfo::TimeToPosition into ZoomInfo and using them is needed to eliminate many more uses. Also #if'd out the unused AudacityProject::OnZoomToggle(). --- src/Menus.cpp | 19 +++++---- src/Menus.h | 2 +- src/Project.cpp | 41 +++++++++----------- src/Project.h | 4 +- src/Screenshot.cpp | 2 +- src/TrackPanel.cpp | 34 ++++++++-------- src/ViewInfo.cpp | 55 ++++++++++++++++++++++++++ src/ViewInfo.h | 60 ++++++++++++++++++++++++++++- src/import/ImportLOF.cpp | 5 +-- src/toolbars/EditToolBar.cpp | 7 ++-- src/widgets/AttachableScrollBar.cpp | 18 +++------ 11 files changed, 174 insertions(+), 73 deletions(-) diff --git a/src/Menus.cpp b/src/Menus.cpp index b969785ce..2352113de 100644 --- a/src/Menus.cpp +++ b/src/Menus.cpp @@ -1770,10 +1770,10 @@ wxUint32 AudacityProject::GetUpdateFlags() if (mUndoManager.RedoAvailable()) flags |= RedoAvailableFlag; - if (GetZoom() < gMaxZoom && (flags & TracksExistFlag)) + if (ZoomInAvailable() && (flags & TracksExistFlag)) flags |= ZoomInAvailableFlag; - if (GetZoom() > gMinZoom && (flags & TracksExistFlag)) + if (ZoomOutAvailable() && (flags & TracksExistFlag)) flags |= ZoomOutAvailableFlag; if ((flags & LabelTracksExistFlag) && LabelTrack::IsTextClipSupported()) @@ -4882,7 +4882,7 @@ void AudacityProject::ZoomInByFactor( double ZoomFactor ) { // LLL: Handling positioning differently when audio is active if (gAudioIO->IsStreamActive(GetAudioIOToken()) != 0) { - Zoom(mViewInfo.zoom * ZoomFactor); + ZoomBy(ZoomFactor); mTrackPanel->ScrollIntoView(gAudioIO->GetStreamTime()); mTrackPanel->Refresh(false); return; @@ -4915,7 +4915,7 @@ void AudacityProject::ZoomInByFactor( double ZoomFactor ) (mViewInfo.h + mViewInfo.screen - mViewInfo.selectedRegion.t0()) / 2; // Zoom in - Zoom(mViewInfo.zoom *= ZoomFactor); + ZoomBy(ZoomFactor); // Recenter on selCenter TP_ScrollWindow(selCenter - mViewInfo.screen / 2); @@ -4925,7 +4925,7 @@ void AudacityProject::ZoomInByFactor( double ZoomFactor ) double origLeft = mViewInfo.h; double origWidth = mViewInfo.screen; - Zoom(mViewInfo.zoom *= ZoomFactor); + ZoomBy(ZoomFactor); double newh = origLeft + (origWidth - mViewInfo.screen) / 2; @@ -4957,7 +4957,7 @@ void AudacityProject::ZoomOutByFactor( double ZoomFactor ) double origLeft = mViewInfo.h; double origWidth = mViewInfo.screen; - Zoom(mViewInfo.zoom *=ZoomFactor); + ZoomBy(ZoomFactor); double newh = origLeft + (origWidth - mViewInfo.screen) / 2; // newh = (newh > 0) ? newh : 0; @@ -4965,6 +4965,8 @@ void AudacityProject::ZoomOutByFactor( double ZoomFactor ) } +// this is unused: +#if 0 static double OldZooms[2]={ 44100.0/512.0, 4410.0/512.0 }; void AudacityProject::OnZoomToggle() { @@ -4984,11 +4986,12 @@ void AudacityProject::OnZoomToggle() double newh = origLeft + (origWidth - mViewInfo.screen) / 2; TP_ScrollWindow(newh); } +#endif void AudacityProject::OnZoomNormal() { - Zoom(44100.0 / 512.0); + Zoom(ZoomInfo::GetDefaultZoom()); mTrackPanel->Refresh(false); } @@ -5074,7 +5077,7 @@ void AudacityProject::OnZoomSel() // where the selected region may be scrolled off the left of the screen. // I know this isn't right, but until the real rounding or 1-off issue is // found, this will have to work. - Zoom(((mViewInfo.zoom * mViewInfo.screen) - 1) / denom); + Zoom((mViewInfo.GetScreenWidth() - 1) / denom); TP_ScrollWindow(mViewInfo.selectedRegion.t0()); } diff --git a/src/Menus.h b/src/Menus.h index ad0e47cc3..2b5fe80e0 100644 --- a/src/Menus.h +++ b/src/Menus.h @@ -259,7 +259,7 @@ void OnSelectAllTracks(); void OnZoomIn(); void OnZoomOut(); -void OnZoomToggle(); +// void OnZoomToggle(); void OnZoomNormal(); void OnZoomFit(); void OnZoomFitV(); diff --git a/src/Project.cpp b/src/Project.cpp index ad61d1e10..51b53a068 100644 --- a/src/Project.cpp +++ b/src/Project.cpp @@ -780,7 +780,7 @@ AudacityProject::AudacityProject(wxWindow * parent, wxWindowID id, mTimerRecordCanceled(false), mMenuClose(false) , mbInitializingScrollbar(false) - , mViewInfo(0.0, 1.0, (44100.0 / 512.0)) + , mViewInfo(0.0, 1.0, ZoomInfo::GetDefaultZoom()) { // Note that the first field of the status bar is a dummy, and it's width is set // to zero latter in the code. This field is needed for wxWidgets 2.8.12 because @@ -1527,7 +1527,7 @@ void AudacityProject::FixScrollbars() double LastTime = std::max(mTracks->GetEndTime(), mViewInfo.selectedRegion.t1()); - mViewInfo.screen = ((double) panelWidth) / mViewInfo.zoom; + mViewInfo.SetScreenWidth(panelWidth); const double halfScreen = mViewInfo.screen / 2.0; // If we can scroll beyond zero, @@ -1551,9 +1551,9 @@ void AudacityProject::FixScrollbars() rescroll = true; } - mViewInfo.sbarTotal = (wxInt64) (mViewInfo.total * mViewInfo.zoom); - mViewInfo.sbarScreen = (wxInt64) (mViewInfo.screen * mViewInfo.zoom); - mViewInfo.sbarH = (wxInt64) (mViewInfo.h * mViewInfo.zoom); + mViewInfo.sbarTotal = (wxInt64) (mViewInfo.GetTotalWidth()); + mViewInfo.sbarScreen = (wxInt64) (mViewInfo.GetScreenWidth()); + mViewInfo.sbarH = (wxInt64) (mViewInfo.GetBeforeScreenWidth()); int lastv = mViewInfo.vpos; // PRL: Can someone else find a more elegant solution to bug 812, than @@ -1574,7 +1574,7 @@ void AudacityProject::FixScrollbars() bool oldhstate; bool oldvstate; - bool newhstate = mViewInfo.screen < mViewInfo.total; + bool newhstate = !mViewInfo.ZoomedAll(); bool newvstate = panelHeight < totalHeight; #ifdef __WXGTK__ @@ -1585,7 +1585,7 @@ void AudacityProject::FixScrollbars() #else oldhstate = mHsbar->IsEnabled(); oldvstate = mVsbar->IsEnabled(); - mHsbar->Enable(mViewInfo.screen < mViewInfo.total); + mHsbar->Enable(!mViewInfo.ZoomedAll()); mVsbar->Enable(panelHeight < totalHeight); #endif @@ -1595,7 +1595,7 @@ void AudacityProject::FixScrollbars() refresh = true; rescroll = false; } - if (mViewInfo.screen >= mViewInfo.total && mViewInfo.sbarH != 0) { + if (mViewInfo.ZoomedAll() && mViewInfo.sbarH != 0) { mViewInfo.sbarH = 0; refresh = true; @@ -1638,7 +1638,7 @@ void AudacityProject::FixScrollbars() panelHeight / mViewInfo.scrollStep, TRUE); mVsbar->Refresh(); - if (refresh || (rescroll && mViewInfo.screen < mViewInfo.total)) { + if (refresh || (rescroll && !mViewInfo.ZoomedAll())) { mTrackPanel->Refresh(false); } @@ -1821,15 +1821,8 @@ void AudacityProject::OnScroll(wxScrollEvent & WXUNUSED(event)) mViewInfo.sbarH = (wxInt64)(mHsbar->GetThumbPosition() / mViewInfo.sbarScale) - offset; - if (mViewInfo.sbarH != hlast) { - mViewInfo.h = mViewInfo.sbarH / mViewInfo.zoom; - - if (mViewInfo.h > mViewInfo.total - mViewInfo.screen) - mViewInfo.h = mViewInfo.total - mViewInfo.screen; - - if (mViewInfo.h < lowerBound) - mViewInfo.h = lowerBound; - } + if (mViewInfo.sbarH != hlast) + mViewInfo.SetBeforeScreenWidth(mViewInfo.sbarH, lowerBound); if (mScrollBeyondZero) { @@ -4117,12 +4110,14 @@ void AudacityProject::SelectNone() // Utility function called by other zoom methods void AudacityProject::Zoom(double level) { - if (level > gMaxZoom) - level = gMaxZoom; - if (level <= gMinZoom) - level = gMinZoom; + mViewInfo.SetZoom(level); + FixScrollbars(); +} - mViewInfo.zoom = level; +// Utility function called by other zoom methods +void AudacityProject::ZoomBy(double multiplier) +{ + mViewInfo.ZoomBy(multiplier); FixScrollbars(); } diff --git a/src/Project.h b/src/Project.h index c741eac83..bd9b1fa12 100644 --- a/src/Project.h +++ b/src/Project.h @@ -152,7 +152,8 @@ class AUDACITY_DLL_API AudacityProject: public wxFrame, sampleFormat GetDefaultFormat() { return mDefaultFormat; } double GetRate() { return mRate; } - double GetZoom() { return mViewInfo.zoom; } + bool ZoomInAvailable() const { return mViewInfo.ZoomInAvailable(); } + bool ZoomOutAvailable() const { return mViewInfo.ZoomOutAvailable(); } double GetSel0() { return mViewInfo.selectedRegion.t0(); } double GetSel1() { return mViewInfo.selectedRegion.t1(); } @@ -308,6 +309,7 @@ class AUDACITY_DLL_API AudacityProject: public wxFrame, void SelectNone(); void SelectAllIfNone(); void Zoom(double level); + void ZoomBy(double multiplier); void Rewind(bool shift); void SkipEnd(bool shift); void EditByLabel( WaveTrack::EditFunction action, bool bSyncLockedTracks ); diff --git a/src/Screenshot.cpp b/src/Screenshot.cpp index 890416132..94fc80c33 100644 --- a/src/Screenshot.cpp +++ b/src/Screenshot.cpp @@ -661,7 +661,7 @@ void ScreenFrame::TimeZoom(double seconds) { int width, height; mContext.GetProject()->GetClientSize(&width, &height); - mContext.GetProject()->mViewInfo.zoom = (0.75 * width) / seconds; + mContext.GetProject()->mViewInfo.SetZoom((0.75 * width) / seconds); mContext.GetProject()->RedrawProject(); } diff --git a/src/TrackPanel.cpp b/src/TrackPanel.cpp index 4b790b268..5027100f6 100644 --- a/src/TrackPanel.cpp +++ b/src/TrackPanel.cpp @@ -4568,15 +4568,11 @@ void TrackPanel::DragZoom(wxMouseEvent & event, int trackLeftEdge) double left = PositionToTime(mZoomStart, trackLeftEdge); double right = PositionToTime(mZoomEnd, trackLeftEdge); + double multiplier = mViewInfo->screen / (right - left); if (event.ShiftDown()) - mViewInfo->zoom /= mViewInfo->screen / (right - left); - else - mViewInfo->zoom *= mViewInfo->screen / (right - left); + multiplier = 1.0 / multiplier; - if (mViewInfo->zoom > gMaxZoom) - mViewInfo->zoom = gMaxZoom; - if (mViewInfo->zoom <= gMinZoom) - mViewInfo->zoom = gMinZoom; + mViewInfo->ZoomBy(multiplier); mViewInfo->h = left; } @@ -4588,13 +4584,13 @@ void TrackPanel::DoZoomInOut(wxMouseEvent & event, int trackLeftEdge) { double center_h = PositionToTime(event.m_x, trackLeftEdge); - if (event.RightUp() || event.RightDClick() || event.ShiftDown()) - mViewInfo->zoom = wxMax(mViewInfo->zoom / 2.0, gMinZoom); - else - mViewInfo->zoom = wxMin(mViewInfo->zoom * 2.0, gMaxZoom); + const double multiplier = + (event.RightUp() || event.RightDClick() || event.ShiftDown()) + ? 0.5 : 2.0; + mViewInfo->ZoomBy(multiplier); if (event.MiddleUp() || event.MiddleDClick()) - mViewInfo->zoom = 44100.0 / 512.0; // AS: Reset zoom. + mViewInfo->SetZoom(ZoomInfo::GetDefaultZoom()); // AS: Reset zoom. double new_center_h = PositionToTime(event.m_x, trackLeftEdge); @@ -5301,7 +5297,7 @@ void TrackPanel::UpdateViewIfNoTracks() { // BG: There are no more tracks on screen //BG: Set zoom to normal - mViewInfo->zoom = 44100.0 / 512.0; + mViewInfo->SetZoom(ZoomInfo::GetDefaultZoom()); //STM: Set selection to 0,0 //PRL: and default the rest of the selection information @@ -6322,8 +6318,7 @@ void TrackPanel::HandleWheelRotation(wxMouseEvent & event) center_h = audioEndTime; } - // Constrain maximum as well as minimum zoom. - mViewInfo->zoom = wxMax( gMinZoom, wxMin(mViewInfo->zoom * pow(2.0, steps), gMaxZoom)); + mViewInfo->ZoomBy(pow(2.0, steps)); double new_center_h = PositionToTime(xx, trackLeftEdge); mViewInfo->h += (center_h - new_center_h); @@ -8007,11 +8002,14 @@ void TrackPanel::OnToggle() // Make sure selection edge is in view void TrackPanel::ScrollIntoView(double pos) { + const int screenWidth = rint(mViewInfo->GetScreenWidth()); + int w, h; GetTracksUsableArea( &w, &h ); + // Or should we just set w = screenWidth ? - if( ( pos < mViewInfo->h ) || - ( pos > mViewInfo->h + ( ( w - 1 ) / mViewInfo->zoom ) ) ) + int pixel = mViewInfo->TimeToPosition(pos); + if (pixel < 0 || pixel >= screenWidth) { mListener->TP_ScrollWindow( pos - ( ( w / 2 ) / mViewInfo->zoom ) ); Refresh(false); @@ -8620,7 +8618,7 @@ void TrackPanel::OnTrackClose() if( mTracks->IsEmpty() ) { //BG: Set zoom to normal - mViewInfo->zoom = 44100.0 / 512.0; + mViewInfo->SetZoom(ZoomInfo::GetDefaultZoom()); //STM: Set selection to 0,0 //PRL: and default the rest of the selection information diff --git a/src/ViewInfo.cpp b/src/ViewInfo.cpp index 33b2ad78e..fbd4e8d46 100644 --- a/src/ViewInfo.cpp +++ b/src/ViewInfo.cpp @@ -10,9 +10,16 @@ Paul Licameli #include "ViewInfo.h" +#include + #include "Internat.h" #include "xml/XMLWriter.h" +namespace { +static const double gMaxZoom = 6000000; +static const double gMinZoom = 0.001; +} + ZoomInfo::ZoomInfo(double start, double screenDuration, double pixelsPerSecond) : vpos(0) , h(start) @@ -25,6 +32,46 @@ ZoomInfo::~ZoomInfo() { } +/// Converts a position (mouse X coordinate) to +/// project time, in seconds. Needs the left edge of +/// the track as an additional parameter. +double ZoomInfo::PositionToTime(wxInt64 position, + wxInt64 origin + ) const +{ + return h + (position - origin) / zoom; +} + + +/// STM: Converts a project time to screen x position. +wxInt64 ZoomInfo::TimeToPosition(double projectTime, + wxInt64 origin + ) const +{ + return floor(0.5 + + zoom * (projectTime - h) + origin + ); +} + +bool ZoomInfo::ZoomInAvailable() const +{ + return zoom < gMaxZoom; +} + +bool ZoomInfo::ZoomOutAvailable() const +{ + return zoom > gMinZoom; +} + +void ZoomInfo::SetZoom(double pixelsPerSecond) +{ + zoom = std::max(gMinZoom, std::min(gMaxZoom, pixelsPerSecond)); +} + +void ZoomInfo::ZoomBy(double multiplier) +{ + SetZoom(zoom * multiplier); +} ViewInfo::ViewInfo(double start, double screenDuration, double pixelsPerSecond) : ZoomInfo(start, screenDuration, pixelsPerSecond) @@ -40,6 +87,14 @@ ViewInfo::ViewInfo(double start, double screenDuration, double pixelsPerSecond) { } +void ViewInfo::SetBeforeScreenWidth(wxInt64 width, double lowerBoundTime) +{ + h = + std::max(lowerBoundTime, + std::min(total - screen, + width / zoom)); +} + void ViewInfo::WriteXMLAttributes(XMLWriter &xmlFile) { selectedRegion.WriteXMLAttributes(xmlFile, wxT("sel0"), wxT("sel1")); diff --git a/src/ViewInfo.h b/src/ViewInfo.h index 013006b3d..b9bffac91 100644 --- a/src/ViewInfo.h +++ b/src/ViewInfo.h @@ -13,8 +13,6 @@ #include "SelectedRegion.h" -const double gMaxZoom = 6000000, - gMinZoom = 0.001; class Track; @@ -34,6 +32,52 @@ public: double screen; // screen width in secs double zoom; // pixels per second + +public: + + // do NOT use this once to convert a pixel width to a duration! + // Instead, call twice to convert start and end times, + // and take the difference. + // origin specifies the pixel corresponding to time h + double PositionToTime(wxInt64 position, + wxInt64 origin = 0 + ) const; + + // do NOT use this once to convert a duration to a pixel width! + // Instead, call twice to convert start and end positions, + // and take the difference. + // origin specifies the pixel corresponding to time h + wxInt64 TimeToPosition(double time, + wxInt64 origin = 0 + ) const; + + double OffsetTimeByPixels(double time, wxInt64 offset) const + { + return PositionToTime(offset + TimeToPosition(time)); + } + + bool ZoomInAvailable() const; + bool ZoomOutAvailable() const; + + // Return pixels, but maybe not a whole number + double GetScreenWidth() const + { return screen * zoom; } + + void SetScreenWidth(wxInt64 width) + { screen = width / zoom; } + + static double GetDefaultZoom() + { return 44100.0 / 512.0; } + + // There is NO GetZoom()! + // Use TimeToPosition and PositionToTime and OffsetTimeByPixels! + + // Limits zoom to certain bounds + void SetZoom(double pixelsPerSecond); + + // Limits zoom to certain bounds + // multipliers above 1.0 zoom in, below out + void ZoomBy(double multiplier); }; class AUDACITY_DLL_API ViewInfo @@ -42,6 +86,18 @@ class AUDACITY_DLL_API ViewInfo public: ViewInfo(double start, double screenDuration, double pixelsPerSecond); + double GetBeforeScreenWidth() const + { + return h * zoom; + } + void SetBeforeScreenWidth(wxInt64 width, double lowerBoundTime = 0.0); + + double GetTotalWidth() const + { return total * zoom; } + + bool ZoomedAll() const + { return screen >= total; } + // Current selection SelectedRegion selectedRegion; diff --git a/src/import/ImportLOF.cpp b/src/import/ImportLOF.cpp index 9bd2d999f..fb1d0ad1c 100644 --- a/src/import/ImportLOF.cpp +++ b/src/import/ImportLOF.cpp @@ -70,6 +70,7 @@ *//*******************************************************************/ #include "../Audacity.h" +#include "ImportLOF.h" #include #include @@ -78,7 +79,6 @@ #include #include -#include "ImportLOF.h" #ifdef USE_MIDI #include "ImportMIDI.h" #endif // USE_MIDI @@ -485,8 +485,7 @@ void LOFImportFileHandle::doDuration() if (callDurationFactor) { double longestDuration = mProject->GetTracks()->GetEndTime(); - double realZoomValue = ((longestDuration/durationFactor)*(mProject->GetZoom())); - mProject->Zoom(realZoomValue); + mProject->ZoomBy(longestDuration / durationFactor); callDurationFactor = false; } } diff --git a/src/toolbars/EditToolBar.cpp b/src/toolbars/EditToolBar.cpp index b314388d9..16237ed01 100644 --- a/src/toolbars/EditToolBar.cpp +++ b/src/toolbars/EditToolBar.cpp @@ -32,6 +32,7 @@ #include "../Audacity.h" +#include "EditToolBar.h" // For compilers that support precompilation, includes "wx/wx.h". #include @@ -44,8 +45,6 @@ #include #endif -#include "EditToolBar.h" - #include "../AllThemeResources.h" #include "../AudioIO.h" #include "../ImageManipulation.h" @@ -308,8 +307,8 @@ void EditToolBar::EnableDisableButtons() bool tracks = (!p->GetTracks()->IsEmpty()); - mButtons[ETBZoomInID]->SetEnabled(tracks && (p->GetZoom() < gMaxZoom)); - mButtons[ETBZoomOutID]->SetEnabled(tracks && (p->GetZoom() > gMinZoom) ); + mButtons[ETBZoomInID]->SetEnabled(tracks && (p->ZoomInAvailable())); + mButtons[ETBZoomOutID]->SetEnabled(tracks && (p->ZoomOutAvailable()) ); #if 0 // Disabled for version 1.2.0 since it doesn't work quite right... mButtons[ETBZoomToggleID]->SetEnabled(tracks); diff --git a/src/widgets/AttachableScrollBar.cpp b/src/widgets/AttachableScrollBar.cpp index 241201254..5ffb2fefd 100644 --- a/src/widgets/AttachableScrollBar.cpp +++ b/src/widgets/AttachableScrollBar.cpp @@ -28,9 +28,9 @@ internally, not ints, allowing for (external) control of zooming. *//*******************************************************************/ #include "../Audacity.h" +#include "AttachableScrollBar.h" #include -#include "AttachableScrollBar.h" #include "../ViewInfo.h" @@ -58,9 +58,9 @@ void AttachableScrollBar::SetScrollBarFromViewInfo() { ViewInfo & mViewInfo = *mpViewInfo; - mViewInfo.sbarTotal = (int) (mViewInfo.total * mViewInfo.zoom); - mViewInfo.sbarScreen = (int) (mViewInfo.screen * mViewInfo.zoom); - mViewInfo.sbarH = (int) (mViewInfo.h * mViewInfo.zoom); + mViewInfo.sbarTotal = (int) (mViewInfo.GetTotalWidth()); + mViewInfo.sbarScreen = (int) (mViewInfo.GetScreenWidth()); + mViewInfo.sbarH = (int) (mViewInfo.GetBeforeScreenWidth()); SetScrollbar(mViewInfo.sbarH, mViewInfo.sbarScreen, mViewInfo.sbarTotal, mViewInfo.sbarScreen, TRUE); @@ -75,14 +75,8 @@ void AttachableScrollBar::SetViewInfoFromScrollBar() mViewInfo.sbarH = GetThumbPosition(); - if (mViewInfo.sbarH != hlast) { - mViewInfo.h = mViewInfo.sbarH / mViewInfo.zoom; - - if (mViewInfo.h > mViewInfo.total - mViewInfo.screen) - mViewInfo.h = mViewInfo.total - mViewInfo.screen; - if (mViewInfo.h < 0.0) - mViewInfo.h = 0.0; - } + if (mViewInfo.sbarH != hlast) + mViewInfo.SetBeforeScreenWidth(mViewInfo.sbarH); } // Used to associated a ViewInfo structure with a scrollbar. From 5418ce377b5efe97d22491d9b4ef9c51e7595610 Mon Sep 17 00:00:00 2001 From: Paul-Licameli Date: Sun, 19 Apr 2015 17:12:06 -0400 Subject: [PATCH 17/36] Move PositionToTime, TimeToPosition into class ZoomInfo ... ... and use them in many more places in TrackPanel.cpp, so there are fewer direct uses of ZoomInfo::zoom. Also use then in horizontal scrolling code --- src/Project.cpp | 32 ++-- src/Project.h | 2 + src/TrackPanel.cpp | 368 +++++++++++++++++++++++++-------------------- src/TrackPanel.h | 22 +-- 4 files changed, 229 insertions(+), 195 deletions(-) diff --git a/src/Project.cpp b/src/Project.cpp index 51b53a068..b0d851db3 100644 --- a/src/Project.cpp +++ b/src/Project.cpp @@ -1451,19 +1451,20 @@ double AudacityProject::ScrollingLowerBoundTime() const : 0; } +wxInt64 AudacityProject::PixelWidthBeforeTime(double scrollto) const +{ + const double lowerBound = ScrollingLowerBoundTime(); + return + mViewInfo.TimeToPosition(scrollto, 0 + ) - + mViewInfo.TimeToPosition(lowerBound, 0 + ); +} + void AudacityProject::SetHorizontalThumb(double scrollto) { - const double timeOffset = -ScrollingLowerBoundTime(); - int pos = (int) ( - (scrollto + timeOffset) * mViewInfo.zoom * mViewInfo.sbarScale - ); - int max = mHsbar->GetRange() - mHsbar->GetThumbSize(); - - if (pos > max) - pos = max; - else if (pos < 0) - pos = 0; - + wxInt64 max = mHsbar->GetRange() - mHsbar->GetThumbSize(); + int pos = std::min(max, std::max(wxInt64(0), PixelWidthBeforeTime(scrollto))); mHsbar->SetThumbPosition(pos); } @@ -1623,8 +1624,7 @@ void AudacityProject::FixScrollbars() int scaledSbarH = (int)(mViewInfo.sbarH * mViewInfo.sbarScale); int scaledSbarScreen = (int)(mViewInfo.sbarScreen * mViewInfo.sbarScale); int scaledSbarTotal = (int)(mViewInfo.sbarTotal * mViewInfo.sbarScale); - int offset; - offset = -lowerBound * mViewInfo.zoom * mViewInfo.sbarScale; + const int offset = mViewInfo.sbarScale * PixelWidthBeforeTime(0.0); mHsbar->SetScrollbar(scaledSbarH + offset, scaledSbarScreen, scaledSbarTotal, scaledSbarScreen, TRUE); @@ -1816,7 +1816,7 @@ void AudacityProject::OnScroll(wxScrollEvent & WXUNUSED(event)) const wxInt64 hlast = mViewInfo.sbarH; const double lowerBound = ScrollingLowerBoundTime(); - const wxInt64 offset = 0.5 + -lowerBound * mViewInfo.zoom; + const wxInt64 offset = PixelWidthBeforeTime(0.0); mViewInfo.sbarH = (wxInt64)(mHsbar->GetThumbPosition() / mViewInfo.sbarScale) - offset; @@ -1824,10 +1824,10 @@ void AudacityProject::OnScroll(wxScrollEvent & WXUNUSED(event)) if (mViewInfo.sbarH != hlast) mViewInfo.SetBeforeScreenWidth(mViewInfo.sbarH, lowerBound); - if (mScrollBeyondZero) { enum { SCROLL_PIXEL_TOLERANCE = 10 }; - if (fabs(mViewInfo.h * mViewInfo.zoom) < SCROLL_PIXEL_TOLERANCE) { + if (abs(mViewInfo.TimeToPosition(0.0, 0 + )) < SCROLL_PIXEL_TOLERANCE) { // Snap the scrollbar to 0 mViewInfo.h = 0; SetHorizontalThumb(0.0); diff --git a/src/Project.h b/src/Project.h index bd9b1fa12..3121f63fa 100644 --- a/src/Project.h +++ b/src/Project.h @@ -356,6 +356,8 @@ class AUDACITY_DLL_API AudacityProject: public wxFrame, void SafeDisplayStatusMessage(const wxChar *msg); double ScrollingLowerBoundTime() const; + // How many pixels are covered by the period from lowermost scrollable time, to the given time: + wxInt64 PixelWidthBeforeTime(double scrollto) const; void SetHorizontalThumb(double scrollto); // TrackPanel access diff --git a/src/TrackPanel.cpp b/src/TrackPanel.cpp index 5027100f6..5c891984a 100644 --- a/src/TrackPanel.cpp +++ b/src/TrackPanel.cpp @@ -848,21 +848,21 @@ void TrackPanel::UpdatePrefs() #endif mdBr = gPrefs->Read(wxT("/GUI/EnvdBRange"), ENV_DB_RANGE); gPrefs->Read(wxT("/GUI/AutoScroll"), &mViewInfo->bUpdateTrackIndicator, - true); + true); gPrefs->Read(wxT("/GUI/AdjustSelectionEdges"), &mAdjustSelectionEdges, - true); + true); gPrefs->Read(wxT("/GUI/CircularTrackNavigation"), &mCircularTrackNavigation, - false); + false); gPrefs->Read(wxT("/GUI/Solo"), &mSoloPref, wxT("Standard") ); gPrefs->Read(wxT("/AudioIO/SeekShortPeriod"), &mSeekShort, - 1.0); + 1.0); gPrefs->Read(wxT("/AudioIO/SeekLongPeriod"), &mSeekLong, - 15.0); + 15.0); #ifdef EXPERIMENTAL_OUTPUT_DISPLAY bool temp = WaveTrack::mMonoAsVirtualStereo; gPrefs->Read(wxT("/GUI/MonoAsVirtualStereo"), &WaveTrack::mMonoAsVirtualStereo, - false); + false); if(WaveTrack::mMonoAsVirtualStereo != temp) UpdateVirtualStereoOrder(); @@ -1252,7 +1252,7 @@ void TrackPanel::DoDrawIndicator mViewInfo->h + mViewInfo->screen ); if( onScreen ) { - x = GetLeftOffset() + int ( ( mLastIndicator - mViewInfo->h) * mViewInfo->zoom ); + x = mViewInfo->TimeToPosition(mLastIndicator, GetLeftOffset()); // LL: Keep from trying to blit outsize of the source DC. This results in a crash on // OSX due to allocating memory using negative sizes and can be caused by resizing @@ -1321,7 +1321,7 @@ void TrackPanel::DoDrawIndicator AColor::IndicatorColor( &dc, !rec); // Calculate the horizontal position of the indicator - x = GetLeftOffset() + int ( ( pos - mViewInfo->h ) * mViewInfo->zoom ); + x = mViewInfo->TimeToPosition(pos, GetLeftOffset()); mRuler->DrawIndicator( pos, rec ); @@ -1380,7 +1380,7 @@ void TrackPanel::DoDrawCursor(wxDC & dc) mViewInfo->h + mViewInfo->screen ); if( onScreen ) { - x = GetLeftOffset() + int ( ( mLastCursor - mViewInfo->h) * mViewInfo->zoom ); + x = mViewInfo->TimeToPosition(mLastCursor, GetLeftOffset()); dc.Blit( x, 0, 1, mBacking->GetHeight(), &mBackingDC, x, 0 ); } @@ -1401,8 +1401,7 @@ void TrackPanel::DoDrawCursor(wxDC & dc) AColor::CursorColor( &dc ); - x = GetLeftOffset() + - int ( ( mLastCursor - mViewInfo->h ) * mViewInfo->zoom ); + x = mViewInfo->TimeToPosition(mLastCursor, GetLeftOffset()); // Draw cursor in all selected tracks VisibleTrackIterator iter( GetProject() ); @@ -1547,9 +1546,9 @@ void TrackPanel::OnPaint(wxPaintEvent & /* event */) DoDrawCursor(cdc); #if DEBUG_DRAW_TIMING - sw.Pause(); - wxLogDebug(wxT("Total: %ld milliseconds"), sw.Time()); - wxPrintf(wxT("Total: %ld milliseconds\n"), sw.Time()); + sw.Pause(); + wxLogDebug(wxT("Total: %ld milliseconds"), sw.Time()); + wxPrintf(wxT("Total: %ld milliseconds\n"), sw.Time()); #endif } @@ -1905,13 +1904,13 @@ void TrackPanel::SetCursorAndTipWhenSelectTool( Track * t, // (Don't assume it's the default!) wxString keyStr (GetProject()->GetCommandManager()->GetKeyFromName(wxT("Preferences"))); - // Must compose a string that survives the function call, hence static. if (keyStr.IsEmpty()) // No keyboard preference defined for opening Preferences dialog /* i18n-hint: These are the names of a menu and a command in that menu */ keyStr = _("Edit, Preferences..."); else keyStr = KeyStringDisplay(keyStr); + // Must compose a string that survives the function call, hence static. static wxString result; /* i18n-hint: %s is usually replaced by "Ctrl+P" for Windows/Linux, "Command+," for Mac */ result = wxString::Format( @@ -1933,11 +1932,13 @@ void TrackPanel::SetCursorAndTipWhenSelectTool( Track * t, MaySetOnDemandTip( t, ppTip ); return; } - wxInt64 leftSel = TimeToPosition(mViewInfo->selectedRegion.t0(), r.x); - wxInt64 rightSel = TimeToPosition(mViewInfo->selectedRegion.t1(), r.x); - // Something is wrong if right edge comes before left edge - wxASSERT(!(rightSel < leftSel)); + { + wxInt64 leftSel = mViewInfo->TimeToPosition(mViewInfo->selectedRegion.t0(), r.x); + wxInt64 rightSel = mViewInfo->TimeToPosition(mViewInfo->selectedRegion.t1(), r.x); + // Something is wrong if right edge comes before left edge + wxASSERT(!(rightSel < leftSel)); + } const bool bShiftDown = event.ShiftDown(); @@ -2124,7 +2125,7 @@ void TrackPanel::HandleCursor(wxMouseEvent & event) // practice (on a P500). int tool = DetermineToolToUse( ttb, event ); - tip = ttb->GetMessageForTool( tool ); + tip = ttb->GetMessageForTool(tool); // We don't include the select tool in // SetCursorAndTipByTool() because it's more complex than @@ -2261,7 +2262,7 @@ void TrackPanel::StartOrJumpPlayback(wxMouseEvent &event) { AudacityProject *p = GetActiveProject(); if (p) { - double clicktime = PositionToTime(event.m_x, GetLeftOffset()); + double clicktime = mViewInfo->PositionToTime(event.m_x, GetLeftOffset()); const double t1 = mViewInfo->selectedRegion.t1(); // Play to end of selection, or if that is not right of the pick, end of track double endtime = clicktime < t1 ? t1 : mViewInfo->total; @@ -2427,9 +2428,14 @@ bool TrackPanel::MaybeStartScrubbing(wxMouseEvent &event) abs(mScrubStartPosition - position) >= SCRUBBING_PIXEL_TOLERANCE) { ControlToolBar * ctb = p->GetControlToolBar(); double maxTime = p->GetTracks()->GetEndTime(); - double time0 = std::min(maxTime, PositionToTime(mScrubStartPosition, GetLeftOffset())); - double time1 = std::min(maxTime, PositionToTime(position, GetLeftOffset())); - if (time1 != time0) { + double time0 = std::min(maxTime, + mViewInfo->PositionToTime(mScrubStartPosition, GetLeftOffset()) + ); + double time1 = std::min(maxTime, + mViewInfo->PositionToTime(position, GetLeftOffset()) + ); + if (time1 != time0) + { if (busy) ctb->StopPlaying(); @@ -2483,7 +2489,7 @@ bool TrackPanel::ContinueScrubbing(wxCoord position, bool hasFocus, bool seek) if (!hasFocus) return gAudioIO->EnqueueScrubBySignedSpeed(0, mMaxScrubSpeed, false); - const double time = PositionToTime(position, GetLeftOffset()); + const double time = mViewInfo->PositionToTime(position, GetLeftOffset()); if (seek) // Cause OnTimer() to suppress the speed display @@ -2638,9 +2644,9 @@ void TrackPanel::SelectionHandleClick(wxMouseEvent & event, else if(event.CmdDown() #ifdef USE_MIDI - && !stretch + && !stretch #endif - ) { + ) { #ifdef EXPERIMENTAL_SCRUBBING_BASIC if ( @@ -2781,7 +2787,7 @@ void TrackPanel::SelectionHandleClick(wxMouseEvent & event, if (startNewSelection) { // mouse is not at an edge, but after // quantization, we could be indicating the selection edge mSelStartValid = true; - mSelStart = std::max(0.0, PositionToTime(event.m_x, r.x)); + mSelStart = std::max(0.0, mViewInfo->PositionToTime(event.m_x, r.x)); mStretchStart = nt->NearestBeatTime(mSelStart, ¢erBeat); if (within(qBeat0, centerBeat, 0.1)) { mListener->TP_DisplayStatusMessage( @@ -2872,10 +2878,7 @@ void TrackPanel::SelectionHandleClick(wxMouseEvent & event, void TrackPanel::StartSelection(int mouseXCoordinate, int trackLeftEdge) { mSelStartValid = true; - mSelStart = - std::max(0.0, - mViewInfo->h + ((mouseXCoordinate - trackLeftEdge) - / mViewInfo->zoom)); + mSelStart = std::max(0.0, mViewInfo->PositionToTime(mouseXCoordinate, trackLeftEdge)); double s = mSelStart; @@ -2886,7 +2889,7 @@ void TrackPanel::StartSelection(int mouseXCoordinate, int trackLeftEdge) if (mSnapManager->Snap(mCapturedTrack, mSelStart, false, &s, &snappedPoint, &snappedTime)) { if (snappedPoint) - mSnapLeft = TimeToPosition(s, trackLeftEdge); + mSnapLeft = mViewInfo->TimeToPosition(s, trackLeftEdge); } } @@ -2905,7 +2908,7 @@ void TrackPanel::ExtendSelection(int mouseXCoordinate, int trackLeftEdge, // Must be dragging frequency bounds only. return; - double selend = std::max(0.0, PositionToTime(mouseXCoordinate, trackLeftEdge)); + double selend = std::max(0.0, mViewInfo->PositionToTime(mouseXCoordinate, trackLeftEdge)); clip_bottom(selend, 0.0); double origSel0, origSel1; @@ -2933,12 +2936,12 @@ void TrackPanel::ExtendSelection(int mouseXCoordinate, int trackLeftEdge, if (mSnapManager->Snap(mCapturedTrack, sel0, false, &sel0, &snappedPoint, &snappedTime)) { if (snappedPoint) - mSnapLeft = TimeToPosition(sel0, trackLeftEdge); + mSnapLeft = mViewInfo->TimeToPosition(sel0, trackLeftEdge); } if (mSnapManager->Snap(mCapturedTrack, sel1, true, &sel1, &snappedPoint, &snappedTime)) { if (snappedPoint) - mSnapRight = TimeToPosition(sel1, trackLeftEdge); + mSnapRight = mViewInfo->TimeToPosition(sel1, trackLeftEdge); } // Check if selection endpoints are too close together to snap (unless @@ -3342,7 +3345,7 @@ void TrackPanel::Stretch(int mouseXCoordinate, int trackLeftEdge, } NoteTrack *pNt = (NoteTrack *) pTrack; - double moveto = std::max(0.0, PositionToTime(mouseXCoordinate, trackLeftEdge)); + double moveto = std::max(0.0, mViewInfo->PositionToTime(mouseXCoordinate, trackLeftEdge)); // check to make sure tempo is not higher than 20 beats per second // (In principle, tempo can be higher, but not infinity.) @@ -3462,7 +3465,7 @@ void TrackPanel::SelectionHandleDrag(wxMouseEvent & event, Track *clickedTrack) // Might be dragging frequency bounds only, test if (mSelStartValid) { - wxInt64 SelStart=TimeToPosition( mSelStart, r.x); //cvt time to pixels. + wxInt64 SelStart = mViewInfo->TimeToPosition(mSelStart, r.x); //cvt time to pixels. // Abandon this drag if selecting < 5 pixels. if (wxLongLong(SelStart-x).Abs() < minimumSizedSelection #ifdef USE_MIDI // limiting selection size is good, and not starting @@ -3519,26 +3522,6 @@ void TrackPanel::SelectionHandleDrag(wxMouseEvent & event, Track *clickedTrack) UpdateSelectionDisplay(); } -/// Converts a position (mouse X coordinate) to -/// project time, in seconds. Needs the left edge of -/// the track as an additional parameter. -double TrackPanel::PositionToTime(wxInt64 mouseXCoordinate, - wxInt64 trackLeftEdge) const -{ - return mViewInfo->h + ((mouseXCoordinate - trackLeftEdge) - / mViewInfo->zoom); -} - - -/// STM: Converts a project time to screen x position. -wxInt64 TrackPanel::TimeToPosition(double projectTime, - wxInt64 trackLeftEdge) const -{ - return static_cast < - wxInt64 >(mViewInfo->zoom * (projectTime - mViewInfo->h) + - trackLeftEdge); -} - #ifdef EXPERIMENTAL_SPECTRAL_EDITING // Seems 4 is too small to work at the top. Why? enum { FREQ_SNAP_DISTANCE = 10 }; @@ -3635,7 +3618,9 @@ TrackPanel::SelectionBoundary TrackPanel::ChooseTimeBoundary { const double t0 = mViewInfo->selectedRegion.t0(); const double t1 = mViewInfo->selectedRegion.t1(); - wxInt64 pixelDist = mViewInfo->zoom * fabs(selend - t0); + const wxInt64 posS = mViewInfo->TimeToPosition(selend); + const wxInt64 pos0 = mViewInfo->TimeToPosition(t0); + wxInt64 pixelDist = abs(posS - pos0); bool chooseLeft = true; if (mViewInfo->selectedRegion.isPoint()) @@ -3643,7 +3628,8 @@ TrackPanel::SelectionBoundary TrackPanel::ChooseTimeBoundary // and right distances are the same chooseLeft = (selend < t0); else { - const wxInt64 rightDist = mViewInfo->zoom * fabs(selend - t1); + const wxInt64 pos1 = mViewInfo->TimeToPosition(t1); + const wxInt64 rightDist = abs(posS - pos1); if (rightDist < pixelDist) chooseLeft = false, pixelDist = rightDist; } @@ -3676,7 +3662,7 @@ bool mayDragWidth, bool onlyWithinSnapDistance, // within the time boundaries. // May choose no boundary if onlyWithinSnapDistance is true. // Otherwise choose the eligible boundary nearest the mouse click. - const double selend = PositionToTime(event.m_x, rect.x); + const double selend = mViewInfo->PositionToTime(event.m_x, rect.x); wxInt64 pixelDist = 0; SelectionBoundary boundary = ChooseTimeBoundary(selend, onlyWithinSnapDistance, @@ -4037,7 +4023,7 @@ void TrackPanel::StartSlide(wxMouseEvent & event) mCapturedClipArray.Clear(); double clickTime = - PositionToTime(event.m_x, GetLeftOffset()); + mViewInfo->PositionToTime(event.m_x, GetLeftOffset()); bool clickedInSelection = (vt->GetSelected() && clickTime > mViewInfo->selectedRegion.t0() && @@ -4065,8 +4051,7 @@ void TrackPanel::StartSlide(wxMouseEvent & event) // WaveClip::GetClipAtX doesn't work unless the clip is on the screen and can return bad info otherwise // instead calculate the time manually double rate = ((WaveTrack*)partner)->GetRate(); - double pps = mViewInfo->zoom; - double tt = (event.m_x - GetLeftOffset()) / pps + mViewInfo->h; + const double tt = mViewInfo->PositionToTime(event.m_x, GetLeftOffset()); sampleCount s0 = (sampleCount)(tt * rate + 0.5); if (s0 >= 0) { @@ -4129,7 +4114,7 @@ void TrackPanel::StartSlide(wxMouseEvent & event) mMouseClickY = event.m_y; mSelStartValid = true; - mSelStart = mViewInfo->h + ((event.m_x - r.x) / mViewInfo->zoom); + mSelStart = mViewInfo->PositionToTime(event.m_x, r.x); if (mSnapManager) delete mSnapManager; @@ -4267,7 +4252,9 @@ void TrackPanel::DoSlide(wxMouseEvent & event) } mHSlideAmount = 0.0; - double desiredSlideAmount = (event.m_x - mMouseClickX) / mViewInfo->zoom; + double desiredSlideAmount = + mViewInfo->PositionToTime(event.m_x) - + mViewInfo->PositionToTime(mMouseClickX); #ifdef USE_MIDI if (mouseTrack->GetKind() == Track::Wave) { WaveTrack *mtw = (WaveTrack *) mouseTrack; @@ -4317,12 +4304,12 @@ void TrackPanel::DoSlide(wxMouseEvent & event) if (newClipLeft != clipLeft) { double difference = (newClipLeft - clipLeft); desiredSlideAmount += difference; - mSnapLeft = TimeToPosition(newClipLeft, GetLeftOffset()); + mSnapLeft = mViewInfo->TimeToPosition(newClipLeft, GetLeftOffset()); } else if (newClipRight != clipRight) { double difference = (newClipRight - clipRight); desiredSlideAmount += difference; - mSnapRight = TimeToPosition(newClipRight, GetLeftOffset()); + mSnapRight = mViewInfo->TimeToPosition(newClipRight, GetLeftOffset()); } } @@ -4565,8 +4552,8 @@ bool TrackPanel::IsMouseCaptured() /// a drag zoom. void TrackPanel::DragZoom(wxMouseEvent & event, int trackLeftEdge) { - double left = PositionToTime(mZoomStart, trackLeftEdge); - double right = PositionToTime(mZoomEnd, trackLeftEdge); + double left = mViewInfo->PositionToTime(mZoomStart, trackLeftEdge); + double right = mViewInfo->PositionToTime(mZoomEnd, trackLeftEdge); double multiplier = mViewInfo->screen / (right - left); if (event.ShiftDown()) @@ -4582,7 +4569,7 @@ void TrackPanel::DragZoom(wxMouseEvent & event, int trackLeftEdge) /// \todo MAGIC NUMBER: We've got several in this method. void TrackPanel::DoZoomInOut(wxMouseEvent & event, int trackLeftEdge) { - double center_h = PositionToTime(event.m_x, trackLeftEdge); + double center_h = mViewInfo->PositionToTime(event.m_x, trackLeftEdge); const double multiplier = (event.RightUp() || event.RightDClick() || event.ShiftDown()) @@ -4592,7 +4579,7 @@ void TrackPanel::DoZoomInOut(wxMouseEvent & event, int trackLeftEdge) if (event.MiddleUp() || event.MiddleDClick()) mViewInfo->SetZoom(ZoomInfo::GetDefaultZoom()); // AS: Reset zoom. - double new_center_h = PositionToTime(event.m_x, trackLeftEdge); + double new_center_h = mViewInfo->PositionToTime(event.m_x, trackLeftEdge); mViewInfo->h += (center_h - new_center_h); } @@ -5050,7 +5037,7 @@ void TrackPanel::HandleSampleEditingClick( wxMouseEvent & event ) //If we are still around, we are drawing in earnest. Set some member data structures up: //First, calculate the starting sample. To get this, we need the time - double t0 = PositionToTime(event.m_x, GetLeftOffset()); + double t0 = mViewInfo->PositionToTime(event.m_x, GetLeftOffset()); //convert t0 to samples mDrawingStartSample = mDrawingTrack->TimeToLongSamples(t0); @@ -5189,7 +5176,7 @@ void TrackPanel::HandleSampleEditingDrag( wxMouseEvent & event ) //Otherwise, adjust the sample you are dragging over right now. //convert this to samples - const double t = PositionToTime(event.m_x, GetLeftOffset()); + const double t = mViewInfo->PositionToTime(event.m_x, GetLeftOffset()); s0 = mDrawingTrack->TimeToLongSamples(t); } @@ -6267,22 +6254,22 @@ void TrackPanel::HandleWheelRotation(wxMouseEvent & event) { // MM: Scroll left/right when used with Shift key down mListener->TP_ScrollWindow( - mViewInfo->h + - 50.0 * -steps / mViewInfo->zoom); + mViewInfo->OffsetTimeByPixels( + mViewInfo->PositionToTime(0), 50.0 * -steps)); } else if (event.CmdDown()) { #if 0 - // JKC: Alternative scroll wheel zooming code - // using AudacityProject zooming, which is smarter, - // it keeps selections on screen and centred if it can, - // also this ensures mousewheel and zoom buttons give same result. - double ZoomFactor = pow(2.0, steps); - AudacityProject *p = GetProject(); - if( steps > 0 ) - p->ZoomInByFactor( ZoomFactor ); - else - p->ZoomOutByFactor( ZoomFactor ); + // JKC: Alternative scroll wheel zooming code + // using AudacityProject zooming, which is smarter, + // it keeps selections on screen and centred if it can, + // also this ensures mousewheel and zoom buttons give same result. + double ZoomFactor = pow(2.0, steps); + AudacityProject *p = GetProject(); + if( steps > 0 ) + p->ZoomInByFactor( ZoomFactor ); + else + p->ZoomOutByFactor( ZoomFactor ); #endif // MM: Zoom in/out when used with Control key down // We're converting pixel positions to times, @@ -6296,13 +6283,13 @@ void TrackPanel::HandleWheelRotation(wxMouseEvent & event) if (mSmoothScrollingScrub) { // Expand or contract about the center, ignoring mouse position center_h = mViewInfo->h + mViewInfo->screen / 2.0; - xx = TimeToPosition(center_h, trackLeftEdge); + xx = mViewInfo->TimeToPosition(center_h, trackLeftEdge); } else #endif { xx = event.m_x; - center_h = PositionToTime(xx, trackLeftEdge); + center_h = mViewInfo->PositionToTime(xx, trackLeftEdge); } // Time corresponding to last (most far right) audio. double audioEndTime = mTracks->GetEndTime(); @@ -6310,17 +6297,17 @@ void TrackPanel::HandleWheelRotation(wxMouseEvent & event) // When zooming in in empty space, it's easy to 'lose' the waveform. // This prevents it. // IF zooming in - if( steps > 0) + if (steps > 0) { // IF mouse is to right of audio - if( center_h > audioEndTime ) + if (center_h > audioEndTime) // Zooming brings far right of audio to mouse. center_h = audioEndTime; } mViewInfo->ZoomBy(pow(2.0, steps)); - double new_center_h = PositionToTime(xx, trackLeftEdge); + double new_center_h = mViewInfo->PositionToTime(xx, trackLeftEdge); mViewInfo->h += (center_h - new_center_h); MakeParentRedrawScrollbars(); @@ -6654,7 +6641,7 @@ bool TrackPanel::HandleTrackLocationMouseEvent(WaveTrack * track, wxRect &r, wxM { WaveTrack::Location loc = track->GetCachedLocation(i); - double x = (loc.pos - mViewInfo->h) * mViewInfo->zoom; + const double x = mViewInfo->TimeToPosition(loc.pos); if (x >= 0 && x < r.width) { wxRect locRect; @@ -6871,27 +6858,29 @@ void TrackPanel::HandleTrackSpecificMouseEvent(wxMouseEvent & event) if( pTtb == NULL ) return; - int toolToUse = DetermineToolToUse(pTtb, event); + { + int toolToUse = DetermineToolToUse(pTtb, event); - switch (toolToUse) { - case selectTool: - HandleSelect(event); - break; - case envelopeTool: - if (!unsafe) - HandleEnvelope(event); - break; - case slideTool: - if (!unsafe) - HandleSlide(event); - break; - case zoomTool: - HandleZoom(event); - break; - case drawTool: - if (!unsafe) - HandleSampleEditing(event); - break; + switch (toolToUse) { + case selectTool: + HandleSelect(event); + break; + case envelopeTool: + if (!unsafe) + HandleEnvelope(event); + break; + case slideTool: + if (!unsafe) + HandleSlide(event); + break; + case zoomTool: + HandleZoom(event); + break; + case drawTool: + if (!unsafe) + HandleSampleEditing(event); + break; + } } if ((event.Moving() || event.LeftUp()) && @@ -6942,7 +6931,8 @@ int TrackPanel::DetermineToolToUse( ToolsToolBar * pTtb, wxMouseEvent & event) if (event.ButtonIsDown(wxMOUSE_BTN_RIGHT) || event.RightUp()){ currentTool = zoomTool; - } else if( trackKind == Track::Time ){ + } + else if (trackKind == Track::Time){ currentTool = envelopeTool; } else if( trackKind == Track::Label ){ currentTool = selectTool; @@ -6985,8 +6975,8 @@ bool TrackPanel::HitTestStretch(Track *track, wxRect &r, wxMouseEvent & event) int center = r.y + r.height / 2; int distance = abs(event.m_y - center); const int yTolerance = 10; - wxInt64 leftSel = TimeToPosition(mViewInfo->selectedRegion.t0(), r.x); - wxInt64 rightSel = TimeToPosition(mViewInfo->selectedRegion.t1(), r.x); + wxInt64 leftSel = mViewInfo->TimeToPosition(mViewInfo->selectedRegion.t0(), r.x); + wxInt64 rightSel = mViewInfo->TimeToPosition(mViewInfo->selectedRegion.t1(), r.x); // Something is wrong if right edge comes before left edge wxASSERT(!(rightSel < leftSel)); return (leftSel <= event.m_x && event.m_x <= rightSel && @@ -7086,8 +7076,7 @@ bool TrackPanel::HitTestSamples(Track *track, wxRect &r, wxMouseEvent & event) return false; // Not a wave, so return. float oneSample; - double pps = mViewInfo->zoom; - double tt = (event.m_x - r.x) / pps + mViewInfo->h; + const double tt = mViewInfo->PositionToTime(event.m_x, r.x); sampleCount s0 = (sampleCount)(tt * rate + 0.5); // Just get one sample. @@ -7139,8 +7128,7 @@ bool TrackPanel::HitTestSlide(Track * WXUNUSED(track), wxRect &r, wxMouseEvent & double TrackPanel::GetMostRecentXPos() { - return mViewInfo->h + - (mMouseMostRecentX - GetLabelWidth()) / mViewInfo->zoom; + return mViewInfo->PositionToTime(mMouseMostRecentX, GetLabelWidth()); } void TrackPanel::RefreshTrack(Track *trk, bool refreshbacking) @@ -7404,8 +7392,8 @@ void TrackPanel::DrawScrubSpeed(wxDC &dc) #ifdef EXPERIMENTAL_SCRUBBING_SMOOTH_SCROLL mSmoothScrollingScrub ? seeking - ? FindSeekSpeed(PositionToTime(xx, GetLeftOffset())) - : FindScrubSpeed(PositionToTime(xx, GetLeftOffset())) + ? FindSeekSpeed(mViewInfo->PositionToTime(xx, GetLeftOffset())) + : FindScrubSpeed(mViewInfo->PositionToTime(xx, GetLeftOffset())) : #endif mMaxScrubSpeed; @@ -8011,14 +7999,15 @@ void TrackPanel::ScrollIntoView(double pos) int pixel = mViewInfo->TimeToPosition(pos); if (pixel < 0 || pixel >= screenWidth) { - mListener->TP_ScrollWindow( pos - ( ( w / 2 ) / mViewInfo->zoom ) ); + mListener->TP_ScrollWindow + (mViewInfo->OffsetTimeByPixels(pos, -(w / 2))); Refresh(false); } } void TrackPanel::ScrollIntoView(int x) { - ScrollIntoView(PositionToTime(x, GetLeftOffset())); + ScrollIntoView(mViewInfo->PositionToTime(x, GetLeftOffset())); } void TrackPanel::OnCursorLeft( bool shift, bool ctrl, bool keyup ) @@ -8028,11 +8017,12 @@ void TrackPanel::OnCursorLeft( bool shift, bool ctrl, bool keyup ) // and does not vary if the key is held // Else: jump depends on the zoom and gets bigger if the key is held int snapToTime = GetActiveProject()->GetSnapTo(); - double quietSeekStepPositive = 1.0 / mViewInfo->zoom; + double quietSeekStepPositive = 1.0; // pixels double audioSeekStepPositive = shift ? mSeekLong : mSeekShort; SeekLeftOrRight (true, shift, ctrl, keyup, snapToTime, true, false, - quietSeekStepPositive, audioSeekStepPositive); + quietSeekStepPositive, true, + audioSeekStepPositive, false); } void TrackPanel::OnCursorRight(bool shift, bool ctrl, bool keyup) @@ -8042,18 +8032,20 @@ void TrackPanel::OnCursorRight(bool shift, bool ctrl, bool keyup) // and does not vary if the key is held // Else: jump depends on the zoom and gets bigger if the key is held int snapToTime = GetActiveProject()->GetSnapTo(); - double quietSeekStepPositive = 1.0 / mViewInfo->zoom; + double quietSeekStepPositive = 1.0; // pixels double audioSeekStepPositive = shift ? mSeekLong : mSeekShort; SeekLeftOrRight (false, shift, ctrl, keyup, snapToTime, true, false, - quietSeekStepPositive, audioSeekStepPositive); + quietSeekStepPositive, true, + audioSeekStepPositive, false); } // Handle small cursor and play head movements void TrackPanel::SeekLeftOrRight (bool leftward, bool shift, bool ctrl, bool keyup, int snapToTime, bool mayAccelerateQuiet, bool mayAccelerateAudio, - double quietSeekStepPositive, double audioSeekStepPositive) + double quietSeekStepPositive, bool quietStepIsPixels, + double audioSeekStepPositive, bool audioStepIsPixels) { if (keyup) { @@ -8085,26 +8077,34 @@ void TrackPanel::SeekLeftOrRight { mLastSelectionAdjustment = curtime; - // Contract selection + // Contract selection // Reduce and constrain (counter-intuitive) if (leftward) { + const double t1 = mViewInfo->selectedRegion.t1(); mViewInfo->selectedRegion.setT1( std::max(mViewInfo->selectedRegion.t0(), - snapToTime - ? GridMove(mViewInfo->selectedRegion.t1(), multiplier) - : mViewInfo->selectedRegion.t1() + - multiplier * quietSeekStepPositive)); + snapToTime + ? GridMove(t1, multiplier) + : quietStepIsPixels + ? mViewInfo->OffsetTimeByPixels( + t1, int(multiplier * quietSeekStepPositive)) + : t1 + multiplier * quietSeekStepPositive + )); // Make sure it's visible. ScrollIntoView(mViewInfo->selectedRegion.t1()); } else { + const double t0 = mViewInfo->selectedRegion.t0(); mViewInfo->selectedRegion.setT0( std::min(mViewInfo->selectedRegion.t1(), snapToTime - ? GridMove(mViewInfo->selectedRegion.t0(), multiplier) - : mViewInfo->selectedRegion.t0() + - multiplier * quietSeekStepPositive)); + ? GridMove(t0, multiplier) + : quietStepIsPixels + ? mViewInfo->OffsetTimeByPixels( + t0, int(multiplier * quietSeekStepPositive)) + : t0 + multiplier * quietSeekStepPositive + )); // Make sure new position is in view. ScrollIntoView(mViewInfo->selectedRegion.t0()); @@ -8128,7 +8128,16 @@ void TrackPanel::SeekLeftOrRight multiplier = -multiplier; // If playing, reposition - gAudioIO->SeekStream(multiplier * audioSeekStepPositive); + double seconds; + if (audioStepIsPixels) { + const double streamTime = gAudioIO->GetStreamTime(); + const double newTime = + mViewInfo->OffsetTimeByPixels(streamTime, int(audioSeekStepPositive)); + seconds = newTime - streamTime; + } + else + seconds = multiplier * audioSeekStepPositive; + gAudioIO->SeekStream(seconds); return; } else if (shift) @@ -8138,24 +8147,33 @@ void TrackPanel::SeekLeftOrRight // Extend selection // Expand and constrain if (leftward) { + const double t0 = mViewInfo->selectedRegion.t0(); mViewInfo->selectedRegion.setT0( std::max(0.0, snapToTime - ? GridMove(mViewInfo->selectedRegion.t0(), multiplier) - : mViewInfo->selectedRegion.t0() + - multiplier * quietSeekStepPositive)); + ? GridMove(t0, multiplier) + : quietStepIsPixels + ? mViewInfo->OffsetTimeByPixels( + t0, int(multiplier * quietSeekStepPositive)) + : t0 + multiplier * quietSeekStepPositive + )); // Make sure it's visible. ScrollIntoView(mViewInfo->selectedRegion.t0()); } else { double end = mTracks->GetEndTime(); + + const double t1 = mViewInfo->selectedRegion.t1(); mViewInfo->selectedRegion.setT1( std::min(end, snapToTime - ? GridMove(mViewInfo->selectedRegion.t1(), multiplier) - : mViewInfo->selectedRegion.t1() + - multiplier * quietSeekStepPositive)); + ? GridMove(t1, multiplier) + : quietStepIsPixels + ? mViewInfo->OffsetTimeByPixels( + t1, int(multiplier * quietSeekStepPositive)) + : t1 + multiplier * quietSeekStepPositive + )); // Make sure new position is in view. ScrollIntoView(mViewInfo->selectedRegion.t1()); @@ -8172,15 +8190,18 @@ void TrackPanel::SeekLeftOrRight { // Move and constrain double end = mTracks->GetEndTime(); + const double t0 = mViewInfo->selectedRegion.t0(); mViewInfo->selectedRegion.setT0( std::max(0.0, std::min(end, snapToTime - ? GridMove(mViewInfo->selectedRegion.t0(), multiplier) - : mViewInfo->selectedRegion.t0() + multiplier * quietSeekStepPositive - ) - ), - false); + ? GridMove(t0, multiplier) + : quietStepIsPixels + ? mViewInfo->OffsetTimeByPixels( + t0, int(multiplier * quietSeekStepPositive)) + : t0 + multiplier * quietSeekStepPositive)), + false // do not swap selection boundaries + ); mViewInfo->selectedRegion.collapseToT0(); // Move the visual cursor @@ -8216,12 +8237,12 @@ double TrackPanel::GridMove(double t, int minPix) double result; minPix >= 0 ? ttc.Increment() : ttc.Decrement(); result = ttc.GetValue(); - if (fabs(result - t) * mViewInfo->zoom >= fabs((double)minPix)) { - return result; - } + if (abs(mViewInfo->TimeToPosition(result) - mViewInfo->TimeToPosition(t)) + >= abs(minPix)) + return result; // Otherwise, move minPix pixels, then snap to the time. - result = t + minPix / mViewInfo->zoom; + result = mViewInfo->OffsetTimeByPixels(t, minPix); ttc.SetValue(result); result = ttc.GetValue(); return result; @@ -8236,10 +8257,10 @@ void TrackPanel::OnBoundaryMove(bool left, bool boundaryContract) // If the last adjustment was very recent, we are // holding the key down and should move faster. wxLongLong curtime = ::wxGetLocalTimeMillis(); - int multiplier = 1; + int pixels = 1; if( curtime - mLastSelectionAdjustment < 50 ) { - multiplier = 4; + pixels = 4; } mLastSelectionAdjustment = curtime; @@ -8266,10 +8287,13 @@ void TrackPanel::OnBoundaryMove(bool left, bool boundaryContract) { if (left) { // Reduce and constrain left boundary (counter-intuitive) + // Move the left boundary by at most the desired number of pixels, + // but not past the right mViewInfo->selectedRegion.setT0( std::min(mViewInfo->selectedRegion.t1(), - mViewInfo->selectedRegion.t0() + - multiplier / mViewInfo->zoom)); + mViewInfo->OffsetTimeByPixels( + mViewInfo->selectedRegion.t0(), + pixels))); // Make sure it's visible ScrollIntoView( mViewInfo->selectedRegion.t0() ); @@ -8277,10 +8301,14 @@ void TrackPanel::OnBoundaryMove(bool left, bool boundaryContract) else { // Reduce and constrain right boundary (counter-intuitive) + // Move the left boundary by at most the desired number of pixels, + // but not past the left mViewInfo->selectedRegion.setT1( std::max(mViewInfo->selectedRegion.t0(), - mViewInfo->selectedRegion.t1() - - multiplier / mViewInfo->zoom)); + mViewInfo->OffsetTimeByPixels( + mViewInfo->selectedRegion.t1(), + -pixels))); + // Make sure it's visible ScrollIntoView( mViewInfo->selectedRegion.t1() ); } @@ -8293,8 +8321,10 @@ void TrackPanel::OnBoundaryMove(bool left, bool boundaryContract) // Expand and constrain left boundary mViewInfo->selectedRegion.setT0( std::max(0.0, - mViewInfo->selectedRegion.t0() - - multiplier / mViewInfo->zoom)); + mViewInfo->OffsetTimeByPixels( + mViewInfo->selectedRegion.t0(), + -pixels))); + // Make sure it's visible ScrollIntoView( mViewInfo->selectedRegion.t0() ); } @@ -8304,10 +8334,14 @@ void TrackPanel::OnBoundaryMove(bool left, bool boundaryContract) double end = mTracks->GetEndTime(); mViewInfo->selectedRegion.setT1( std::min(end, - mViewInfo->selectedRegion.t1() + - multiplier/mViewInfo->zoom)); - } + mViewInfo->OffsetTimeByPixels( + mViewInfo->selectedRegion.t1(), + pixels))); + + // Make sure it's visible + ScrollIntoView(mViewInfo->selectedRegion.t1()); } + } Refresh( false ); MakeParentModifyState(false); } @@ -8322,20 +8356,24 @@ void TrackPanel::OnCursorMove(bool forward, bool jump, bool longjump ) // PRL: nobody calls this yet with !jump double positiveSeekStep; + bool byPixels; if (jump) { if (!longjump) { positiveSeekStep = mSeekShort; } else { positiveSeekStep = mSeekLong; } + byPixels = false; } else { - positiveSeekStep = 1.0 / mViewInfo->zoom; + positiveSeekStep = 1.0; + byPixels = true; } bool mayAccelerate = !jump; SeekLeftOrRight (!forward, false, false, false, 0, mayAccelerate, mayAccelerate, - positiveSeekStep, positiveSeekStep); + positiveSeekStep, byPixels, + positiveSeekStep, byPixels); MakeParentModifyState(false); } diff --git a/src/TrackPanel.h b/src/TrackPanel.h index 1918142c4..6dddc2ce0 100644 --- a/src/TrackPanel.h +++ b/src/TrackPanel.h @@ -331,8 +331,9 @@ protected: // Handle small cursor and play head movements void SeekLeftOrRight (bool left, bool shift, bool ctrl, bool keyup, - int snapToTime, bool mayAccelerateQuiet, bool mayAccelerateAudio, - double quietSeekStepPositive, double audioSeekStepPositive); + int snapToTime, bool mayAccelerateQuiet, bool mayAccelerateAudio, + double quietSeekStepPositive, bool quietStepIsPixels, + double audioSeekStepPositive, bool audioStepIsPixels); #ifdef EXPERIMENTAL_SPECTRAL_EDITING public: @@ -500,10 +501,10 @@ protected: // 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. public: - TrackList * GetTracks(){ return mTracks;}; - ViewInfo * GetViewInfo(){ return mViewInfo;}; - TrackPanelListener * GetListener(){ return mListener;}; - AdornedRulerPanel * GetRuler(){ return mRuler;}; + TrackList * GetTracks(){ return mTracks;} + ViewInfo * GetViewInfo(){ return mViewInfo;} + TrackPanelListener * GetListener(){ return mListener;} + AdornedRulerPanel * GetRuler(){ return mRuler;} // JKC and here is a factory function which just does 'new' in standard Audacity. static TrackPanel *(*FactoryFunction)(wxWindow * parent, wxWindowID id, @@ -538,7 +539,7 @@ protected: void UpdateVirtualStereoOrder(); #endif // Accessors... - virtual bool HasSoloButton(){ return mSoloPref!=wxT("None");}; + virtual bool HasSoloButton(){ return mSoloPref!=wxT("None");} //JKC: These two belong in the label track. int mLabelTrackStartXPos; @@ -691,14 +692,7 @@ protected: void HandleCenterFrequencyClick (bool shiftDown, Track *pTrack, double value); -#endif - double PositionToTime(wxInt64 mouseXCoordinate, - wxInt64 trackLeftEdge) const; - wxInt64 TimeToPosition(double time, - wxInt64 trackLeftEdge) const; - -#ifdef EXPERIMENTAL_SPECTRAL_EDITING double PositionToFrequency(bool maySnap, wxInt64 mouseYCoordinate, wxInt64 trackTopEdge, From fe36b636cb04d7e51b1787a36c163ca7870440e3 Mon Sep 17 00:00:00 2001 From: Paul-Licameli Date: Mon, 20 Apr 2015 00:04:04 -0400 Subject: [PATCH 18/36] Rewrite SnapManager to avoid using ZoomInfo::zoom --- src/Snap.cpp | 33 ++++++++++++++++----------------- src/Snap.h | 26 ++++++++++++++------------ src/TrackPanel.cpp | 4 ++-- src/widgets/Ruler.cpp | 2 +- 4 files changed, 33 insertions(+), 32 deletions(-) diff --git a/src/Snap.cpp b/src/Snap.cpp index c28f27d50..951c81197 100644 --- a/src/Snap.cpp +++ b/src/Snap.cpp @@ -8,14 +8,14 @@ **********************************************************************/ +#include "Snap.h" + +#include #include #include "LabelTrack.h" -#include "Prefs.h" #include "Project.h" -#include "Snap.h" #include "TrackPanel.h" -#include "WaveTrack.h" #include "widgets/NumericTextCtrl.h" // Change this to "true" to snap to nearest and "false" to snap to previous @@ -29,8 +29,10 @@ static int CompareSnapPoints(SnapPoint *s1, SnapPoint *s2) } SnapManager::SnapManager(TrackList *tracks, TrackClipArray *exclusions, - double zoom, int pixelTolerance, bool noTimeSnap) + const ZoomInfo &zoomInfo, int pixelTolerance, bool noTimeSnap) : mConverter(NumericConverter::TIME) + , mPixelTolerance(std::max(0, pixelTolerance)) + , mZoomInfo(zoomInfo) { int i; @@ -50,13 +52,7 @@ SnapManager::SnapManager(TrackList *tracks, TrackClipArray *exclusions, } mSnapPoints = new SnapPointArray(CompareSnapPoints); - if (zoom > 0 && pixelTolerance > 0) - mTolerance = pixelTolerance / zoom; - else { - // This shouldn't happen, but we don't want to crash if we get - // illegal values. The net effect of this is to never snap. - mTolerance = 0.0; - } + // Two time points closer than this are considered the same mEpsilon = 1 / 44100.0; @@ -135,9 +131,12 @@ double SnapManager::Get(int index) } // Returns the difference in time between t and the point at a given index -double SnapManager::Diff(double t, int index) +wxInt64 SnapManager::PixelDiff(double t, int index) { - return fabs(t - Get(index)); + return abs( + mZoomInfo.TimeToPosition(t, 0) - + mZoomInfo.TimeToPosition(Get(index), 0) + ); } // Find the index where this SnapPoint should go in @@ -168,7 +167,7 @@ int SnapManager::Find(double t) next++; // Now return whichever one is closer to time t - if (next < len && Diff(t, next) < Diff(t, index)) + if (next < len && PixelDiff(t, next) < PixelDiff(t, index)) return next; else return index; @@ -189,7 +188,7 @@ bool SnapManager::SnapToPoints(Track *currentTrack, int index = Find(t); // If it's too far away, just give up now - if (Diff(t, index) >= mTolerance) + if (PixelDiff(t, index) >= mPixelTolerance) return false; // Otherwise, search left and right for all of the points @@ -198,10 +197,10 @@ bool SnapManager::SnapToPoints(Track *currentTrack, int right = index; int i; - while(left > 0 && Diff(t, left-1) < mTolerance) + while(left > 0 && PixelDiff(t, left-1) < mPixelTolerance) left--; - while(right < len-1 && Diff(t, right+1) < mTolerance) + while(right < len-1 && PixelDiff(t, right+1) < mPixelTolerance) right++; if (left == index && right == index) { diff --git a/src/Snap.h b/src/Snap.h index a4d32ca7c..a3e9fe82c 100644 --- a/src/Snap.h +++ b/src/Snap.h @@ -22,6 +22,7 @@ #include "widgets/NumericTextCtrl.h" class TrackClipArray; +class ZoomInfo; enum { @@ -43,9 +44,9 @@ class SnapPoint { WX_DEFINE_SORTED_ARRAY(SnapPoint *, SnapPointArray); class SnapManager { - public: +public: SnapManager(TrackList *tracks, TrackClipArray *exclusions, - double zoom, int pixelTolerance, bool noTimeSnap = false); + const ZoomInfo &zoomInfo, int pixelTolerance, bool noTimeSnap = false); ~SnapManager(); @@ -54,34 +55,35 @@ class SnapManager { // Pass rightEdge=true if this is the right edge of a selection, // and false if it's the left edge. bool Snap(Track *currentTrack, - double t, - bool rightEdge, - double *out_t, - bool *snappedPoint, - bool *snappedTime); + double t, + bool rightEdge, + double *out_t, + bool *snappedPoint, + bool *snappedTime); static wxArrayString GetSnapLabels(); static wxArrayString GetSnapValues(); static const wxString & GetSnapValue(int index); static int GetSnapIndex(const wxString & value); - private: +private: void CondListAdd(double t, Track *tr); double Get(int index); - double Diff(double t, int index); + wxInt64 PixelDiff(double t, int index); int Find(double t, int i0, int i1); int Find(double t); bool SnapToPoints(Track *currentTrack, double t, bool rightEdge, - double *out_t); + double *out_t); double mEpsilon; - double mTolerance; - double mZoom; SnapPointArray *mSnapPoints; // Info for snap-to-time NumericConverter mConverter; bool mSnapToTime; + + const wxInt64 mPixelTolerance; + const ZoomInfo &mZoomInfo; }; #endif diff --git a/src/TrackPanel.cpp b/src/TrackPanel.cpp index 5c891984a..d73ba2f57 100644 --- a/src/TrackPanel.cpp +++ b/src/TrackPanel.cpp @@ -2570,7 +2570,7 @@ void TrackPanel::SelectionHandleClick(wxMouseEvent & event, delete mSnapManager; mSnapManager = new SnapManager(mTracks, NULL, - mViewInfo->zoom, + *mViewInfo, 4); // pixel tolerance mSnapLeft = -1; @@ -4120,7 +4120,7 @@ void TrackPanel::StartSlide(wxMouseEvent & event) delete mSnapManager; mSnapManager = new SnapManager(mTracks, &mCapturedClipArray, - mViewInfo->zoom, + *mViewInfo, 4, // pixel tolerance true); // don't snap to time mSnapLeft = -1; diff --git a/src/widgets/Ruler.cpp b/src/widgets/Ruler.cpp index 0c4455f0e..5b737c2a9 100644 --- a/src/widgets/Ruler.cpp +++ b/src/widgets/Ruler.cpp @@ -2204,7 +2204,7 @@ void AdornedRulerPanel::HandleSnapping() delete mSnapManager; } mSnapManager = new SnapManager(mProject->GetTracks(), NULL, - mViewInfo->zoom, + *mViewInfo, QUICK_PLAY_SNAP_PIXEL); bool snappedPoint, snappedTime; mIsSnapped = (mSnapManager->Snap(NULL, mQuickPlayPos, false, From 1f9113f5cc211aa47ef3bbe832a243d010ad0da3 Mon Sep 17 00:00:00 2001 From: Paul-Licameli Date: Mon, 20 Apr 2015 00:17:26 -0400 Subject: [PATCH 19/36] Label track event handler does not directly use zoom (pps) values --- src/LabelTrack.cpp | 8 ++++---- src/LabelTrack.h | 3 ++- src/TrackPanel.cpp | 4 ++-- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/LabelTrack.cpp b/src/LabelTrack.cpp index b688f86db..4e10313bb 100644 --- a/src/LabelTrack.cpp +++ b/src/LabelTrack.cpp @@ -1382,7 +1382,7 @@ static int Constrain( int value, int min, int max ) /// HandleMouse gets called with every mouse move or click. /// bool LabelTrack::HandleMouse(const wxMouseEvent & evt, - wxRect & r, double h, double pps, + wxRect & r, const ZoomInfo &zoomInfo, SelectedRegion *newSel) { if(evt.LeftUp()) @@ -1454,7 +1454,7 @@ bool LabelTrack::HandleMouse(const wxMouseEvent & evt, bool bLabelMoving = mbIsMoving; bLabelMoving ^= evt.ShiftDown(); bLabelMoving |= mMouseOverLabelLeft==mMouseOverLabelRight; - double fNewX = h + x / pps; + double fNewX = zoomInfo.PositionToTime(x, 0); if( bLabelMoving ) { MayMoveLabel( mMouseOverLabelLeft, -1, fNewX ); @@ -1552,7 +1552,7 @@ bool LabelTrack::HandleMouse(const wxMouseEvent & evt, { t = mLabels[mMouseOverLabelLeft]->getT0(); } - mxMouseDisplacement = (int)((((t-h) * pps) + r.x )-evt.m_x); + mxMouseDisplacement = zoomInfo.TimeToPosition(t, r.x) - evt.m_x; return false; } @@ -1584,7 +1584,7 @@ bool LabelTrack::HandleMouse(const wxMouseEvent & evt, if (mSelIndex != -1) { if (!OverTextBox(mLabels[mSelIndex], evt.m_x, evt.m_y)) mSelIndex = -1; - double t = h + (evt.m_x - r.x) / pps; + double t = zoomInfo.PositionToTime(evt.m_x, r.x); *newSel = SelectedRegion(t, t); } diff --git a/src/LabelTrack.h b/src/LabelTrack.h index 6129b06cc..c80a1cb06 100644 --- a/src/LabelTrack.h +++ b/src/LabelTrack.h @@ -36,6 +36,7 @@ class TrackList; class AudacityProject; class DirManager; class TimeWarper; +class ZoomInfo; class LabelStruct @@ -177,7 +178,7 @@ class AUDACITY_DLL_API LabelTrack : public Track void SetWrongDragging(bool rightFlag) { mRightDragging = rightFlag; } void SetDrawCursor(bool drawCursorFlag) { mDrawCursor = drawCursorFlag; } - bool HandleMouse(const wxMouseEvent & evt, wxRect & r, double h, double pps, + bool HandleMouse(const wxMouseEvent & evt, wxRect & r, const ZoomInfo &zoomInfo, SelectedRegion *newSel); bool CaptureKey(wxKeyEvent & event); diff --git a/src/TrackPanel.cpp b/src/TrackPanel.cpp index d73ba2f57..12ea5948a 100644 --- a/src/TrackPanel.cpp +++ b/src/TrackPanel.cpp @@ -2750,7 +2750,7 @@ void TrackPanel::SelectionHandleClick(wxMouseEvent & event, { LabelTrack *lt = (LabelTrack *) pTrack; if (lt->HandleMouse(event, r,//mCapturedRect, - mViewInfo->h, mViewInfo->zoom, + *mViewInfo, &mViewInfo->selectedRegion)) { MakeParentPushState(_("Modified Label"), _("Label Edit"), @@ -6699,7 +6699,7 @@ bool TrackPanel::HandleLabelTrackMouseEvent(LabelTrack * lTrack, wxRect &r, wxMo } if (lTrack->HandleMouse(event, mCapturedRect, - mViewInfo->h, mViewInfo->zoom, &mViewInfo->selectedRegion)) { + *mViewInfo, &mViewInfo->selectedRegion)) { MakeParentPushState(_("Modified Label"), _("Label Edit"), From bd08c7c7786a733bf73dac9eb8fc6226ba0bfd0c Mon Sep 17 00:00:00 2001 From: Paul-Licameli Date: Mon, 20 Apr 2015 00:35:06 -0400 Subject: [PATCH 20/36] Envelope event handlers do not directly use zoom (pps) values --- src/Envelope.cpp | 70 +++++++++++++++++------------------- src/Envelope.h | 16 ++++----- src/TrackPanel.cpp | 10 +++--- src/effects/Equalization.cpp | 2 +- 4 files changed, 46 insertions(+), 52 deletions(-) diff --git a/src/Envelope.cpp b/src/Envelope.cpp index 91f6edda5..b570f1cba 100644 --- a/src/Envelope.cpp +++ b/src/Envelope.cpp @@ -27,6 +27,7 @@ a draggable point type. *//*******************************************************************/ #include "Envelope.h" +#include "ViewInfo.h" #include @@ -319,9 +320,10 @@ void Envelope::WriteXML(XMLWriter &xmlFile) xmlFile.EndTag(wxT("envelope")); } -#ifndef SQR -#define SQR(X) ((X)*(X)) -#endif +namespace +{ +inline int SQR(int x) { return x * x; } +} /// ValueOfPixel() converts a y position on screen to an envelope value. /// @param y - y position, usually of the mouse.relative to the clip. @@ -355,7 +357,7 @@ float Envelope::ValueOfPixel( int y, int height, bool upper, bool dB, /// We have an upper and lower envelope line. /// Also we may be showing an inner envelope (at 0.5 the range). bool Envelope::HandleMouseButtonDown(wxMouseEvent & event, wxRect & r, - double h, double pps, bool dB, + const ZoomInfo &zoomInfo, bool dB, float zoomMin, float zoomMax) { int ctr = (int)(r.height * zoomMax / (zoomMax - zoomMin)); @@ -365,10 +367,8 @@ bool Envelope::HandleMouseButtonDown(wxMouseEvent & event, wxRect & r, if(clip_y < 0) clip_y = 0; //keeps point in rect r, even if mouse isn't if(clip_y > r.GetBottom()) clip_y = r.GetBottom(); - double tleft = h - mOffset; - double tright = tleft + (r.width / pps); int bestNum = -1; - int bestDist = 10; // Must be within 10 pixel radius. + int bestDistSqr = 100; // Must be within 10 pixel radius. // TODO: Cache the gPrefs value. Reading it every time is inefficient. double dBr = gPrefs->Read(wxT("/GUI/EnvdBRange"), ENV_DB_RANGE); @@ -384,22 +384,25 @@ bool Envelope::HandleMouseButtonDown(wxMouseEvent & event, wxRect & r, // TODO: extract this into a function FindNearestControlPoint() // TODO: also fix it so that we can drag the last point on an envelope. for (int i = 0; i < len; i++) { //search for control point nearest click - if (mEnv[i]->GetT() >= tleft && mEnv[i]->GetT() <= tright) { + const double time = mEnv[i]->GetT() + mOffset; + const wxInt64 position = zoomInfo.TimeToPosition(time); + if (position >= 0 && position < r.width) { - int x = int ((mEnv[i]->GetT() + mOffset - h) * pps) + r.x; + int x = int (position); int y[4]; int numControlPoints; // Outer control points - y[0] = GetWaveYPos( mEnv[i]->GetVal(), zoomMin, zoomMax, r.height, + double value = mEnv[i]->GetVal(); + y[0] = GetWaveYPos(value, zoomMin, zoomMax, r.height, dB, true, dBr, false); - y[1] = GetWaveYPos( -mEnv[i]->GetVal(), zoomMin, zoomMax, r.height, + y[1] = GetWaveYPos(-value, zoomMin, zoomMax, r.height, dB, true, dBr, false); // Inner control points(contour) - y[2] = GetWaveYPos( mEnv[i]->GetVal(), zoomMin, zoomMax, r.height, + y[2] = GetWaveYPos(value, zoomMin, zoomMax, r.height, dB, false, dBr, false); - y[3] = GetWaveYPos( -mEnv[i]->GetVal()-.00000001, zoomMin, zoomMax, + y[3] = GetWaveYPos(-value -.00000001, zoomMin, zoomMax, r.height, dB, false, dBr, false); numControlPoints = 4; @@ -410,12 +413,13 @@ bool Envelope::HandleMouseButtonDown(wxMouseEvent & event, wxRect & r, if (!mMirror) numControlPoints = 1; + const int deltaXSquared = SQR(x - (event.m_x - r.x)); for(int j=0; j 1); } } @@ -427,12 +431,12 @@ bool Envelope::HandleMouseButtonDown(wxMouseEvent & event, wxRect & r, } else { // TODO: Extract this into a function CreateNewPoint - double when = h + (event.m_x - r.x) / pps - mOffset; + const double when = zoomInfo.PositionToTime(event.m_x, r.x); // if (when <= 0 || when >= mTrackLen) // return false; - double v = GetValueAtX( event.m_x, r, h, pps ); + const double v = GetValue( when ); int ct = GetWaveYPos( v, zoomMin, zoomMax, r.height, dB, false, dBr, false) ; @@ -458,16 +462,14 @@ bool Envelope::HandleMouseButtonDown(wxMouseEvent & event, wxRect & r, double newVal = ValueOfPixel(clip_y, r.height, upper, dB, zoomMin, zoomMax); - mDragPoint = Insert(when, newVal); + mDragPoint = Insert(when - mOffset, newVal); mDirty = true; } mUpper = upper; - mInitialWhen = mEnv[mDragPoint]->GetT(); mInitialVal = mEnv[mDragPoint]->GetVal(); - mInitialX = event.m_x; mInitialY = event.m_y+mContourOffset; return true; @@ -502,8 +504,8 @@ void Envelope::MarkDragPointForDeletion() } void Envelope::MoveDraggedPoint( wxMouseEvent & event, wxRect & r, - double WXUNUSED(h), double pps, bool dB, - float zoomMin, float zoomMax) + const ZoomInfo &zoomInfo, bool dB, + float zoomMin, float zoomMax) { int clip_y = event.m_y - r.y; if(clip_y < 0) clip_y = 0; @@ -511,13 +513,12 @@ void Envelope::MoveDraggedPoint( wxMouseEvent & event, wxRect & r, double newVal = ValueOfPixel(clip_y, r.height, mUpper, dB, zoomMin, zoomMax); - wxASSERT( pps > 0 ); // We no longer tolerate multiple envelope points at the same t. // epsilon is less than the time offset of a single sample // TODO: However because mTrackEpsilon assumes 200KHz this use // of epsilon is a tad bogus. What we need to do instead is delete // a duplicated point on a mouse up. - double newWhen = mInitialWhen + (event.m_x - mInitialX) / pps; + double newWhen = zoomInfo.PositionToTime(event.m_x, r.x) - mOffset; // We'll limit the drag point time to be between those of the preceding // and next envelope point. @@ -538,7 +539,7 @@ void Envelope::MoveDraggedPoint( wxMouseEvent & event, wxRect & r, } bool Envelope::HandleDragging( wxMouseEvent & event, wxRect & r, - double h, double pps, bool dB, + const ZoomInfo &zoomInfo, bool dB, float zoomMin, float zoomMax, float WXUNUSED(eMin), float WXUNUSED(eMax)) { @@ -552,7 +553,7 @@ bool Envelope::HandleDragging( wxMouseEvent & event, wxRect & r, // IF we're in the rect THEN we're not deleting this point (anymore). mIsDeleting = false; // ...we're dragging it. - MoveDraggedPoint( event, r,h,pps,dB, zoomMin, zoomMax); + MoveDraggedPoint( event, r, zoomInfo, dB, zoomMin, zoomMax); return true; } @@ -565,11 +566,7 @@ bool Envelope::HandleDragging( wxMouseEvent & event, wxRect & r, } // Exit dragging mode and deletes dragged point if neccessary. -bool Envelope::HandleMouseButtonUp( wxMouseEvent & WXUNUSED(event), wxRect & WXUNUSED(r), - double WXUNUSED(h), - double WXUNUSED(pps), bool WXUNUSED(dB), - float WXUNUSED(zoomMin), - float WXUNUSED(zoomMax) ) +bool Envelope::HandleMouseButtonUp() { if (mIsDeleting) { delete mEnv[mDragPoint]; @@ -588,18 +585,17 @@ void Envelope::Delete( int point ) // Returns true if parent needs to be redrawn bool Envelope::MouseEvent(wxMouseEvent & event, wxRect & r, - double h, double pps, bool dB, + const ZoomInfo &zoomInfo, bool dB, float zoomMin, float zoomMax) { if (event.ButtonDown() && mButton == wxMOUSE_BTN_NONE) - return HandleMouseButtonDown( event, r, h, pps,dB, + return HandleMouseButtonDown( event, r, zoomInfo,dB, zoomMin, zoomMax); if (event.Dragging() && mDragPoint >= 0) - return HandleDragging( event, r, h, pps,dB, + return HandleDragging( event, r, zoomInfo,dB, zoomMin, zoomMax); if (event.ButtonUp() && event.GetButton() == mButton) - return HandleMouseButtonUp( event, r, h, pps, dB, - zoomMin, zoomMax); + return HandleMouseButtonUp(); return false; } diff --git a/src/Envelope.h b/src/Envelope.h index 6d33ec9cf..f1fdb102f 100644 --- a/src/Envelope.h +++ b/src/Envelope.h @@ -29,6 +29,8 @@ class wxTextFile; class DirManager; class Envelope; +class ZoomInfo; + #define ENV_DB_RANGE 60 class EnvPoint : public XMLTagHandler { @@ -122,17 +124,15 @@ class Envelope : public XMLTagHandler { // Event Handlers // Each ofthese returns true if parents needs to be redrawn bool MouseEvent(wxMouseEvent & event, wxRect & r, - double h, double pps, bool dB, + const ZoomInfo &zoomInfo, bool dB, float zoomMin=-1.0, float zoomMax=1.0); bool HandleMouseButtonDown( wxMouseEvent & event, wxRect & r, - double h, double pps, bool dB, + const ZoomInfo &zoomInfo, bool dB, float zoomMin=-1.0, float zoomMax=1.0); bool HandleDragging( wxMouseEvent & event, wxRect & r, - double h, double pps, bool dB, + const ZoomInfo &zoomInfo, bool dB, float zoomMin=-1.0, float zoomMax=1.0, float eMin=0., float eMax=2.); - bool HandleMouseButtonUp( wxMouseEvent & event, wxRect & r, - double h, double pps, bool dB, - float zoomMin=-1.0, float zoomMax=1.0); + bool HandleMouseButtonUp(); void GetEventParams( int &height, bool &upper, bool dB, wxMouseEvent & event, wxRect & r, float &zoomMin, float &zoomMax); @@ -202,7 +202,7 @@ private: void BinarySearchForTime( int &Lo, int &Hi, double t ) const; double GetInterpolationStartValueAtPoint( int iPoint ) const; void MoveDraggedPoint( wxMouseEvent & event, wxRect & r, - double h, double pps, bool dB, + const ZoomInfo &zoomInfo, bool dB, float zoomMin, float zoomMax); // Possibly inline functions: @@ -228,12 +228,10 @@ private: /** \brief Number of pixels contour is from the true envelope. */ int mContourOffset; - double mInitialWhen; double mInitialVal; // These are used in dragging. int mDragPoint; - int mInitialX; int mInitialY; bool mUpper; bool mIsDeleting; diff --git a/src/TrackPanel.cpp b/src/TrackPanel.cpp index 12ea5948a..937383c2c 100644 --- a/src/TrackPanel.cpp +++ b/src/TrackPanel.cpp @@ -3815,7 +3815,7 @@ void TrackPanel::ForwardEventToTimeTrackEnvelope(wxMouseEvent & event) bool needUpdate = pspeedenvelope->MouseEvent( event, envRect, - mViewInfo->h, mViewInfo->zoom, + *mViewInfo, ptimetrack->GetDisplayLog(), lower, upper); if (needUpdate) { RefreshTrack(mCapturedTrack); @@ -3853,7 +3853,7 @@ void TrackPanel::ForwardEventToWaveTrackEnvelope(wxMouseEvent & event) pwavetrack->GetDisplayBounds(&zoomMin, &zoomMax); needUpdate = penvelope->MouseEvent( event, envRect, - mViewInfo->h, mViewInfo->zoom, + *mViewInfo, dB, zoomMin, zoomMax); // If this track is linked to another track, make the identical @@ -3871,8 +3871,8 @@ void TrackPanel::ForwardEventToWaveTrackEnvelope(wxMouseEvent & event) float zoomMin, zoomMax; pwavetrack->GetDisplayBounds(&zoomMin, &zoomMax); updateNeeded = e2->MouseEvent(event, envRect, - mViewInfo->h, mViewInfo->zoom, dB, - zoomMin, zoomMax); + *mViewInfo, dB, + zoomMin, zoomMax); needUpdate |= updateNeeded; } if(!e2 || !updateNeeded) // no envelope found at this x point, or found but not updated @@ -3885,7 +3885,7 @@ void TrackPanel::ForwardEventToWaveTrackEnvelope(wxMouseEvent & event) float zoomMin, zoomMax; pwavetrack->GetDisplayBounds(&zoomMin, &zoomMax); needUpdate |= e2->MouseEvent(event, envRect, - mViewInfo->h, mViewInfo->zoom, dB, + *mViewInfo, dB, zoomMin, zoomMax); } } diff --git a/src/effects/Equalization.cpp b/src/effects/Equalization.cpp index 97ac092e1..8d45a2078 100644 --- a/src/effects/Equalization.cpp +++ b/src/effects/Equalization.cpp @@ -2822,7 +2822,7 @@ void EqualizationPanel::OnMouseEvent(wxMouseEvent & event) CaptureMouse(); } - if (mEffect->mEnvelope->MouseEvent(event, mEnvRect, 0.0, mEnvRect.width, false, + if (mEffect->mEnvelope->MouseEvent(event, mEnvRect, ZoomInfo(0.0, 1.0, mEnvRect.width), false, mEffect->mdBMin, mEffect->mdBMax)) { mEffect->EnvelopeUpdated(); From c4386f4dc8f47f0c9d6493b1d95a8f706fe507d2 Mon Sep 17 00:00:00 2001 From: Paul-Licameli Date: Mon, 20 Apr 2015 00:50:21 -0400 Subject: [PATCH 21/36] Ruler event handler does not directly use zoom (pps) value --- src/widgets/Ruler.cpp | 15 ++++++--------- src/widgets/Ruler.h | 1 - 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/src/widgets/Ruler.cpp b/src/widgets/Ruler.cpp index 5b737c2a9..7b6ac4c4b 100644 --- a/src/widgets/Ruler.cpp +++ b/src/widgets/Ruler.cpp @@ -1803,17 +1803,12 @@ void AdornedRulerPanel::OnSize(wxSizeEvent & WXUNUSED(evt)) double AdornedRulerPanel::Pos2Time(int p) { - return (p-mLeftOffset) / mViewInfo->zoom + mViewInfo->h; + return mViewInfo->PositionToTime(p, mLeftOffset); } int AdornedRulerPanel::Time2Pos(double t) { - return mLeftOffset + Seconds2Pixels(t-mViewInfo->h); -} - -int AdornedRulerPanel::Seconds2Pixels(double t) -{ - return (int)(t * mViewInfo->zoom + 0.5); + return mViewInfo->TimeToPosition(t, mLeftOffset); } @@ -1903,7 +1898,6 @@ void AdornedRulerPanel::OnMouseEvents(wxMouseEvent &evt) if (!mQuickPlayEnabled) return; - HandleSnapping(); if (evt.LeftDown()) @@ -1924,7 +1918,10 @@ void AdornedRulerPanel::OnMouseEvents(wxMouseEvent &evt) mMouseEventState = mesSelectingPlayRegionClick; // otherwise check which marker is nearer else { - if (fabs(mQuickPlayPos - mOldPlayRegionStart) < fabs(mQuickPlayPos - mOldPlayRegionEnd)) + // Don't compare times, compare positions. + //if (fabs(mQuickPlayPos - mPlayRegionStart) < fabs(mQuickPlayPos - mPlayRegionEnd)) + if (abs(Time2Pos(mQuickPlayPos) - Time2Pos(mPlayRegionStart)) < + abs(Time2Pos(mQuickPlayPos) - Time2Pos(mPlayRegionEnd))) mMouseEventState = mesDraggingPlayRegionStart; else mMouseEventState = mesDraggingPlayRegionEnd; diff --git a/src/widgets/Ruler.h b/src/widgets/Ruler.h index d5b542af3..0e14cba94 100644 --- a/src/widgets/Ruler.h +++ b/src/widgets/Ruler.h @@ -299,7 +299,6 @@ private: double Pos2Time(int p); int Time2Pos(double t); - int Seconds2Pixels(double t); bool IsWithinMarker(int mousePosX, double markerTime); From 5316032fee3794b16e64ecc287eebfee3c6d8c80 Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Tue, 9 Jun 2015 11:42:38 -0400 Subject: [PATCH 22/36] An overload of Envelope::GetValues for nonuniform time steps, taking ZoomInfo --- src/Envelope.cpp | 7 +++++++ src/Envelope.h | 5 +++++ 2 files changed, 12 insertions(+) diff --git a/src/Envelope.cpp b/src/Envelope.cpp index b570f1cba..1a13e8e4a 100644 --- a/src/Envelope.cpp +++ b/src/Envelope.cpp @@ -1180,6 +1180,13 @@ void Envelope::GetValues(double *buffer, int bufferLen, } } +void Envelope::GetValues + (double *buffer, int bufferLen, int leftOffset, const ZoomInfo &zoomInfo) const +{ + for (int xx = 0; xx < bufferLen; ++xx) + buffer[xx] = GetValue(zoomInfo.PositionToTime(xx, -leftOffset)); +} + int Envelope::NumberOfPointsAfter(double t) { if( t >= mEnv[mEnv.Count()-1]->GetT() ) diff --git a/src/Envelope.h b/src/Envelope.h index f1fdb102f..3d49197e0 100644 --- a/src/Envelope.h +++ b/src/Envelope.h @@ -160,6 +160,11 @@ class Envelope : public XMLTagHandler { * more than one value in a row. */ void GetValues(double *buffer, int len, double t0, double tstep) const; + /** \brief Get many envelope points at once, but don't assume uniform time step. + */ + void GetValues + (double *buffer, int bufferLen, int leftOffset, const ZoomInfo &zoomInfo) const; + int NumberOfPointsAfter(double t); double NextPointAfter(double t); From e0f459548525f42ff1e57bbb80ffd2cf49b96016 Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Tue, 9 Jun 2015 10:45:14 -0400 Subject: [PATCH 23/36] TrackArtist, LabelTrack, TimeTrack, Envelope functions take ZoomInfo... ... and SelectedRegion, and not ViewInfo or zoom level as a double. Also some leftOffset arguments. Assumptions of uniform zoom level persist in TrackArtist::DrawClipSpectrum and in TrackArtist::DrawClipWaveform but no longer in the rest. --- src/Envelope.cpp | 12 +- src/Envelope.h | 2 +- src/LabelTrack.cpp | 23 +-- src/LabelTrack.h | 7 +- src/Printing.cpp | 4 +- src/TimeTrack.cpp | 29 ++-- src/TimeTrack.h | 3 +- src/TrackArtist.cpp | 296 +++++++++++++++++------------------ src/TrackArtist.h | 48 +++--- src/TrackPanel.cpp | 7 +- src/effects/Equalization.cpp | 3 +- 11 files changed, 215 insertions(+), 219 deletions(-) diff --git a/src/Envelope.cpp b/src/Envelope.cpp index 1a13e8e4a..18f84d190 100644 --- a/src/Envelope.cpp +++ b/src/Envelope.cpp @@ -202,13 +202,9 @@ static void DrawPoint(wxDC & dc, const wxRect & r, int x, int y, bool top) } /// TODO: This should probably move to track artist. -void Envelope::DrawPoints(wxDC & dc, const wxRect & r, double h, double pps, bool dB, +void Envelope::DrawPoints(wxDC & dc, const wxRect & r, const ZoomInfo &zoomInfo, bool dB, float zoomMin, float zoomMax) { - h -= mOffset; - - wxASSERT( pps > 0 ); - double tright = h + (r.width / pps); // TODO: Cache the gPrefs value. Reading it every time is inefficient. double dBRange = gPrefs->Read(wxT("/GUI/EnvdBRange"), ENV_DB_RANGE); @@ -216,7 +212,9 @@ void Envelope::DrawPoints(wxDC & dc, const wxRect & r, double h, double pps, boo dc.SetBrush(*wxWHITE_BRUSH); for (int i = 0; i < (int)mEnv.Count(); i++) { - if (mEnv[i]->GetT() >= h && mEnv[i]->GetT() <= tright) { + const double time = mEnv[i]->GetT() + mOffset; + const wxInt64 position = zoomInfo.TimeToPosition(time); + if (position >= 0 && position < r.width) { // Change colour if this is the draggable point... if (i == mDragPoint) { dc.SetPen(AColor::envelopePen); @@ -224,7 +222,7 @@ void Envelope::DrawPoints(wxDC & dc, const wxRect & r, double h, double pps, boo } double v = mEnv[i]->GetVal(); - int x = int ((mEnv[i]->GetT() - h) * pps); + int x = int(position); int y, y2; y = GetWaveYPos(v, zoomMin, zoomMax, r.height, dB, diff --git a/src/Envelope.h b/src/Envelope.h index 3d49197e0..47c42375e 100644 --- a/src/Envelope.h +++ b/src/Envelope.h @@ -118,7 +118,7 @@ class Envelope : public XMLTagHandler { virtual XMLTagHandler *HandleXMLChild(const wxChar *tag); virtual void WriteXML(XMLWriter &xmlFile); - void DrawPoints(wxDC & dc, const wxRect & r, double h, double pps, bool dB, + void DrawPoints(wxDC & dc, const wxRect & r, const ZoomInfo &zoomInfo, bool dB, float zoomMin=-1.0, float zoomMax=1.0); // Event Handlers diff --git a/src/LabelTrack.cpp b/src/LabelTrack.cpp index 4e10313bb..c8c786c03 100644 --- a/src/LabelTrack.cpp +++ b/src/LabelTrack.cpp @@ -444,7 +444,7 @@ void LabelTrack::ComputeTextPosition(const wxRect & r, int index) /// ComputeLayout determines which row each label /// should be placed on, and reserves space for it. /// Function assumes that the labels are sorted. -void LabelTrack::ComputeLayout(const wxRect & r, double h, double pps) +void LabelTrack::ComputeLayout(const wxRect & r, const ZoomInfo &zoomInfo) { int i; int iRow; @@ -461,15 +461,17 @@ void LabelTrack::ComputeLayout(const wxRect & r, double h, double pps) const int nRows = wxMin((r.height / yRowHeight) + 1, MAX_NUM_ROWS); // Initially none of the rows have been used. // So set a value that is less than any valid value. - const int xStart = r.x -(int)(h*pps) -100; - for(i=0;igetT0() - h) * pps); - int x1 = r.x + (int) ((mLabels[i]->getT1() - h) * pps); + const int x = zoomInfo.TimeToPosition(mLabels[i]->getT0(), r.x); + const int x1 = zoomInfo.TimeToPosition(mLabels[i]->getT1(), r.x); int y = r.y; mLabels[i]->x=x; @@ -727,8 +729,9 @@ bool LabelTrack::CalcCursorX(wxWindow * parent, int * x) /// Draw calls other functions to draw the LabelTrack. /// @param dc the device context /// @param r the LabelTrack rectangle. -void LabelTrack::Draw(wxDC & dc, const wxRect & r, double h, double pps, - double sel0, double sel1) +void LabelTrack::Draw(wxDC & dc, const wxRect & r, + const SelectedRegion &selectedRegion, + const ZoomInfo &zoomInfo) { if(msFont.Ok()) dc.SetFont(msFont); @@ -738,7 +741,7 @@ void LabelTrack::Draw(wxDC & dc, const wxRect & r, double h, double pps, TrackArtist::DrawBackgroundWithSelection(&dc, r, this, AColor::labelSelectedBrush, AColor::labelUnselectedBrush, - sel0, sel1, h, pps); + selectedRegion, zoomInfo); int i; @@ -765,7 +768,7 @@ void LabelTrack::Draw(wxDC & dc, const wxRect & r, double h, double pps, // happens with a new label track. dc.GetTextExtent(wxT("Demo Text x^y"), &textWidth, &textHeight); mTextHeight = (int)textHeight; - ComputeLayout( r, h , pps ); + ComputeLayout( r, zoomInfo ); dc.SetTextForeground(theTheme.Colour( clrLabelTrackText)); dc.SetBackgroundMode(wxTRANSPARENT); dc.SetBrush(AColor::labelTextNormalBrush); diff --git a/src/LabelTrack.h b/src/LabelTrack.h index c80a1cb06..f270760db 100644 --- a/src/LabelTrack.h +++ b/src/LabelTrack.h @@ -126,8 +126,9 @@ class AUDACITY_DLL_API LabelTrack : public Track static void ResetFont(); - void Draw(wxDC & dc, const wxRect & r, double h, double pps, - double sel0, double sel1); + void Draw(wxDC & dc, const wxRect & r, + const SelectedRegion &selectedRegion, + const ZoomInfo &zoomInfo); int getSelectedIndex() const { return mSelIndex; } @@ -261,7 +262,7 @@ class AUDACITY_DLL_API LabelTrack : public Track // Set in copied label tracks double mClipLen; - void ComputeLayout(const wxRect & r, double h, double pps); + void ComputeLayout(const wxRect & r, const ZoomInfo &zoomInfo); void ComputeTextPosition(const wxRect & r, int index); void SetCurrentCursorPosition(wxDC & dc, int xPos); diff --git a/src/Printing.cpp b/src/Printing.cpp index aa56d1960..3e9f8974d 100644 --- a/src/Printing.cpp +++ b/src/Printing.cpp @@ -81,7 +81,7 @@ bool AudacityPrintout::OnPrintPage(int WXUNUSED(page)) artist.SetBackgroundBrushes(*wxWHITE_BRUSH, *wxWHITE_BRUSH, *wxWHITE_PEN, *wxWHITE_PEN); const double screenDuration = mTracks->GetEndTime(); - ViewInfo viewInfo(0.0, screenDuration, width / screenDuration); + ZoomInfo zoomInfo(0.0, screenDuration, width / screenDuration); int y = rulerPageHeight; TrackListIterator iter(mTracks); @@ -93,7 +93,7 @@ bool AudacityPrintout::OnPrintPage(int WXUNUSED(page)) r.width = width; r.height = (int)(n->GetHeight() * scale); - artist.DrawTrack(n, *dc, r, &viewInfo, false, false, false, false); + artist.DrawTrack(n, *dc, r, SelectedRegion(), zoomInfo, false, false, false, false); dc->SetPen(*wxBLACK_PEN); AColor::Line(*dc, 0, r.y, width, r.y); diff --git a/src/TimeTrack.cpp b/src/TimeTrack.cpp index ee8fb0465..5bf349ffc 100644 --- a/src/TimeTrack.cpp +++ b/src/TimeTrack.cpp @@ -13,15 +13,16 @@ *//*******************************************************************/ +#include "Audacity.h" +#include "TimeTrack.h" #include -#include "Audacity.h" #include "AColor.h" -#include "TimeTrack.h" #include "widgets/Ruler.h" #include "Prefs.h" #include "Internat.h" #include "Resample.h" +#include "ViewInfo.h" //TODO-MB: are these sensible values? #define TIMETRACK_MIN 0.01 @@ -223,19 +224,15 @@ void TimeTrack::WriteXML(XMLWriter &xmlFile) xmlFile.EndTag(wxT("timetrack")); } -void TimeTrack::Draw(wxDC & dc, const wxRect & r, double h, double pps) +void TimeTrack::Draw(wxDC & dc, const wxRect & r, const ZoomInfo &zoomInfo) { - double tstep = 1.0 / pps; // Seconds per point - double t0 = h; - double t1 = h + (r.width * tstep); - - //Make sure t1 (the right bound) is greater than 0 - if (t1 < 0.0) - t1 = 0.0; - - //make sure t1 is greater than t0 - if (t0 > t1) - t0 = t1; + double min = zoomInfo.PositionToTime(0); + double max = zoomInfo.PositionToTime(r.width); + if (min > max) + { + wxASSERT(false); + min = max; + } dc.SetBrush(blankBrush); dc.SetPen(blankPen); @@ -246,8 +243,6 @@ void TimeTrack::Draw(wxDC & dc, const wxRect & r, double h, double pps) // Draw the Ruler mRuler->SetBounds(r.x, r.y, r.x + r.width - 1, r.y + r.height - 1); - double min = t0; - double max = min + r.width / pps; mRuler->SetRange(min, max); mRuler->SetFlip(false); // If we don't do this, the Ruler doesn't redraw itself when the envelope is modified. // I have no idea why! @@ -258,7 +253,7 @@ void TimeTrack::Draw(wxDC & dc, const wxRect & r, double h, double pps) mRuler->Draw(dc, this); double *envValues = new double[mid.width]; - GetEnvelope()->GetValues(envValues, mid.width, t0, tstep); + GetEnvelope()->GetValues(envValues, mid.width, 0, zoomInfo); dc.SetPen(AColor::envelopePen); diff --git a/src/TimeTrack.h b/src/TimeTrack.h index 4525c99df..26ba7d022 100644 --- a/src/TimeTrack.h +++ b/src/TimeTrack.h @@ -21,6 +21,7 @@ class wxRect; class wxDC; class Envelope; class Ruler; +class ZoomInfo; class TimeTrack: public Track { @@ -49,7 +50,7 @@ class TimeTrack: public Track { virtual double GetStartTime() const { return 0.0; } virtual double GetEndTime() const { return 0.0; } - void Draw(wxDC & dc, const wxRect & r, double h, double pps); + void Draw(wxDC & dc, const wxRect & r, const ZoomInfo &zoomInfo); // XMLTagHandler callback methods for loading and saving diff --git a/src/TrackArtist.cpp b/src/TrackArtist.cpp index d8f14be8e..cecb2b137 100644 --- a/src/TrackArtist.cpp +++ b/src/TrackArtist.cpp @@ -99,7 +99,7 @@ TrackPanel::DoDrawIndicator(); AdornedRulerPanel::DrawIndicator(); [not part of TrackPanel graphics] draw indicator on each track TrackPanel::DoDrawCursor(); - draw cursor on each track [at mviewInfo->selectedRegion.t0()] + draw cursor on each track [at selectedRegion.t0()] AdornedRulerPanel::DrawCursor(); [not part of TrackPanel graphics] TrackPanel::DisplaySelection(); \endcode @@ -270,7 +270,7 @@ TrackArtist::TrackArtist() UpdatePrefs(); SetColours(); - vruler = new Ruler(); + vruler = new Ruler; } TrackArtist::~TrackArtist() @@ -318,7 +318,8 @@ void TrackArtist::DrawTracks(TrackList * tracks, wxRegion & reg, wxRect & rect, wxRect & clip, - ViewInfo * viewInfo, + const SelectedRegion &selectedRegion, + const ZoomInfo &zoomInfo, bool drawEnvelope, bool bigPoints, bool drawSliders) @@ -341,7 +342,7 @@ void TrackArtist::DrawTracks(TrackList * tracks, // Change the +0 to +1 or +2 to see the bounding box mInsetLeft = 1+0; mInsetTop = 5+0; mInsetRight = 6+0; mInsetBottom = 2+0; - // This just show what the passed in rectanges enclose + // This just shows what the passed in rectangles enclose dc.SetPen(wxColour(*wxGREEN)); dc.SetBrush(*wxTRANSPARENT_BRUSH); dc.DrawRectangle(rect); @@ -354,7 +355,7 @@ void TrackArtist::DrawTracks(TrackList * tracks, t = iter.StartWith(start); while (t) { - trackRect.y = t->GetY() - viewInfo->vpos; + trackRect.y = t->GetY() - zoomInfo.vpos; trackRect.height = t->GetHeight(); if (trackRect.y > clip.GetBottom() && !t->GetLinked()) { @@ -405,13 +406,14 @@ void TrackArtist::DrawTracks(TrackList * tracks, rr.y += mInsetTop; rr.width -= (mInsetLeft + mInsetRight); rr.height -= (mInsetTop + mInsetBottom); - DrawTrack(t, dc, rr, viewInfo, + DrawTrack(t, dc, rr, + selectedRegion, zoomInfo, drawEnvelope, bigPoints, drawSliders, hasSolo); } #ifdef EXPERIMENTAL_OUTPUT_DISPLAY if(MONO_WAVE_PAN(t)){ - trackRect.y = t->GetY(true) - viewInfo->vpos; + trackRect.y = t->GetY(true) - zoomInfo.vpos; trackRect.height = t->GetHeight(true); stereoTrackRect = trackRect; stereoTrackRect.y -= t->GetHeight(); @@ -423,7 +425,7 @@ void TrackArtist::DrawTracks(TrackList * tracks, rr.y += mInsetTop; rr.width -= (mInsetLeft + mInsetRight); rr.height -= (mInsetTop + mInsetBottom); - DrawTrack(t, dc, rr, viewInfo, + DrawTrack(t, dc, rr, zoomInfo, drawEnvelope, bigPoints, drawSliders, hasSolo); } } @@ -436,7 +438,8 @@ void TrackArtist::DrawTracks(TrackList * tracks, void TrackArtist::DrawTrack(const Track * t, wxDC & dc, const wxRect & rect, - const ViewInfo * viewInfo, + const SelectedRegion &selectedRegion, + const ZoomInfo &zoomInfo, bool drawEnvelope, bool bigPoints, bool drawSliders, @@ -454,11 +457,11 @@ void TrackArtist::DrawTrack(const Track * t, switch (wt->GetDisplay()) { case WaveTrack::WaveformDisplay: - DrawWaveform(wt, dc, rect, viewInfo, + DrawWaveform(wt, dc, rect, selectedRegion, zoomInfo, drawEnvelope, bigPoints, drawSliders, false, muted); break; case WaveTrack::WaveformDBDisplay: - DrawWaveform(wt, dc, rect, viewInfo, + DrawWaveform(wt, dc, rect, selectedRegion, zoomInfo, drawEnvelope, bigPoints, drawSliders, true, muted); break; case WaveTrack::SpectrumDisplay: @@ -466,7 +469,7 @@ void TrackArtist::DrawTrack(const Track * t, case WaveTrack::SpectralSelectionDisplay: case WaveTrack::SpectralSelectionLogDisplay: case WaveTrack::PitchDisplay: - DrawSpectrum(wt, dc, rect, viewInfo); + DrawSpectrum(wt, dc, rect, selectedRegion, zoomInfo); break; } if (mbShowTrackNameInWaveform && @@ -483,15 +486,15 @@ void TrackArtist::DrawTrack(const Track * t, case Track::Note: { bool muted = (hasSolo || t->GetMute()) && !t->GetSolo(); - DrawNoteTrack((NoteTrack *)t, dc, rect, viewInfo, muted); + DrawNoteTrack((NoteTrack *)t, dc, rect, selectedRegion, zoomInfo, muted); break; } #endif // USE_MIDI case Track::Label: - DrawLabelTrack((LabelTrack *)t, dc, rect, viewInfo); + DrawLabelTrack((LabelTrack *)t, dc, rect, selectedRegion, zoomInfo); break; case Track::Time: - DrawTimeTrack((TimeTrack *)t, dc, rect, viewInfo); + DrawTimeTrack((TimeTrack *)t, dc, rect, zoomInfo); break; } } @@ -986,12 +989,15 @@ void TrackArtist::DrawNegativeOffsetTrackArrows(wxDC &dc, const wxRect &rect) rect.x + 6, rect.y + rect.height - 12); } -void TrackArtist::DrawWaveformBackground(wxDC &dc, const wxRect &rect, const double env[], +void TrackArtist::DrawWaveformBackground(wxDC &dc, int leftOffset, const wxRect &rect, + const double env[], float zoomMin, float zoomMax, bool dB, - const ViewInfo &viewInfo, double t0, double rate, - sampleCount ssel0, sampleCount ssel1, + const SelectedRegion &selectedRegion, + const ZoomInfo &zoomInfo, bool drawEnvelope, bool bIsSyncLockSelected) { + const double t0 = selectedRegion.t0(), t1 = selectedRegion.t1(); + // Visually (one vertical slice of the waveform background, on its side; // the "*" is the actual waveform background we're drawing // @@ -1015,10 +1021,9 @@ void TrackArtist::DrawWaveformBackground(wxDC &dc, const wxRect &rect, const dou dc.SetBrush(blankBrush); dc.DrawRectangle(rect); - const double samplesPerPixel = rate / viewInfo.zoom; - double where = t0 * rate; - for (xx = 0; xx < rect.width; ++xx, where += samplesPerPixel) { - + double time = zoomInfo.PositionToTime(0, -leftOffset), nextTime; + for (xx = 0; xx < rect.width; ++xx, time = nextTime) { + nextTime = zoomInfo.PositionToTime(xx + 1, -leftOffset); // First we compute the truncated shape of the waveform background. // If drawEnvelope is true, then we compute the lower border of the // envelope. @@ -1043,7 +1048,7 @@ void TrackArtist::DrawWaveformBackground(wxDC &dc, const wxRect &rect, const dou } // We don't draw selection color for sync-lock selected tracks. - sel = (ssel0 <= where && where + samplesPerPixel < ssel1) && !bIsSyncLockSelected; + sel = (t0 <= time && nextTime < t1) && !bIsSyncLockSelected; if (lmaxtop == maxtop && lmintop == mintop && @@ -1085,14 +1090,9 @@ void TrackArtist::DrawWaveformBackground(wxDC &dc, const wxRect &rect, const dou } // If sync-lock selected, draw in linked graphics. - if (bIsSyncLockSelected && ssel0 < ssel1) { - // Find the beginning/end of the selection - int begin, end; - double where = t0 * rate; - for (xx = 0; xx < rect.width && where < ssel0; ++xx, where += samplesPerPixel); - begin = xx; - for (; xx < rect.width && where < ssel1; ++xx, where += samplesPerPixel); - end = xx; + if (bIsSyncLockSelected && t0 < t1) { + const int begin = std::max(0, std::min(rect.width, int(zoomInfo.TimeToPosition(t0, -leftOffset)))); + const int end = std::max(0, std::min(rect.width, int(zoomInfo.TimeToPosition(t1, -leftOffset)))); DrawSyncLockTiles(&dc, wxRect(rect.x + begin, rect.y, end - 1 - begin, rect.height)); } @@ -1107,19 +1107,15 @@ void TrackArtist::DrawWaveformBackground(wxDC &dc, const wxRect &rect, const dou } -void TrackArtist::DrawMinMaxRMS(wxDC &dc, const wxRect &rect, const double env[], - float zoomMin, float zoomMax, bool dB, - const WaveDisplay &display, bool /* showProgress */, bool muted +void TrackArtist::DrawMinMaxRMS(wxDC &dc, const wxRect & rect, const double env[], + float zoomMin, float zoomMax, bool dB, + const float *min, const float *max, const float *rms, const int *bl, + bool /* showProgress */, bool muted #ifdef EXPERIMENTAL_OUTPUT_DISPLAY - , const float gain + , const float gain #endif - ) +) { - const float *const min = display.min; - const float *const max = display.max; - const float *const rms = display.rms; - const int *const bl = display.bl; - // Display a line representing the // min and max of the samples in this region int lasth1 = std::numeric_limits::max(); @@ -1132,7 +1128,7 @@ void TrackArtist::DrawMinMaxRMS(wxDC &dc, const wxRect &rect, const double env[] int clipcnt = 0; if (mShowClipping) { - clipped = new int[rect.width]; + clipped = new int[rect.width]; } long pixAnimOffset = (long)fabs((double)(wxDateTime::Now().GetTicks() * -10)) + @@ -1272,26 +1268,25 @@ void TrackArtist::DrawMinMaxRMS(wxDC &dc, const wxRect &rect, const double env[] delete [] r2; } -void TrackArtist::DrawIndividualSamples(wxDC &dc, const wxRect &rect, +void TrackArtist::DrawIndividualSamples(wxDC &dc, int leftOffset, const wxRect &rect, float zoomMin, float zoomMax, bool dB, WaveClip *clip, - double t0, double pps, double WXUNUSED(h), + const ZoomInfo &zoomInfo, bool bigPoints, bool showPoints, bool muted) { + const double toffset = clip->GetOffset(); double rate = clip->GetRate(); - sampleCount s0 = (sampleCount) (t0 * rate + 0.5); - sampleCount slen = (sampleCount) (rect.width * rate / pps + 0.5); - sampleCount snSamples = clip->GetNumSamples(); - - slen += 4; - - if (s0 > snSamples) { + const double t0 = std::max(0.0, zoomInfo.PositionToTime(0, -leftOffset) - toffset); + const sampleCount s0 = sampleCount(floor(t0 * rate)); + const sampleCount snSamples = clip->GetNumSamples(); + if (s0 > snSamples) return; - } - if (s0 + slen > snSamples) { - slen = snSamples - s0; - } + const double t1 = zoomInfo.PositionToTime(rect.width - 1, -leftOffset) - toffset; + const sampleCount s1 = sampleCount(ceil(t1 * rate)); + const sampleCount slen = std::min(snSamples - s0, s1 - s0 + 1); + if (slen <= 0) + return; float *buffer = new float[slen]; clip->GetSamples((samplePtr)buffer, floatSample, s0, slen); @@ -1302,40 +1297,27 @@ void TrackArtist::DrawIndividualSamples(wxDC &dc, const wxRect &rect, int clipcnt = 0; sampleCount s; - if (mShowClipping) { + if (mShowClipping) clipped = new int[slen]; - } dc.SetPen(muted ? muteSamplePen : samplePen); for (s = 0; s < slen; s++) { - double tt = (s / rate); - - // MB: (s0/rate - t0) is the distance from the left edge of the screen - // to the first sample. - int xx = (int)rint((tt + s0 / rate - t0) * pps); - - if (xx < -10000) { - xx = -10000; - } - if (xx > 10000) { - xx = 10000; - } - + const double time = toffset + (s + s0) / rate; + const int xx = // An offset into the rectangle rect + std::max(-10000, std::min(10000, + int(zoomInfo.TimeToPosition(time, -leftOffset)))); xpos[s] = xx; - // t0 + clip->GetOffset() is 'h' (the absolute time of the left edge) for 'rect'. - tt = buffer[s] * clip->GetEnvelope()->GetValueAtX(xx + rect.x, rect, t0 + clip->GetOffset(), pps); + const double tt = buffer[s] * clip->GetEnvelope()->GetValue(time); + if (clipped && mShowClipping && ((tt <= -MAX_AUDIO) || (tt >= MAX_AUDIO))) clipped[clipcnt++] = xx; - ypos[s] = GetWaveYPos(tt, zoomMin, zoomMax, - rect.height, dB, true, mdBrange, false); - if (ypos[s] < -1) { - ypos[s] = -1; - } - if (ypos[s] > rect.height) { - ypos[s] = rect.height; - } + ypos[s] = + std::max(-1, + std::min(rect.height, + GetWaveYPos(tt, zoomMin, zoomMax, + rect.height, dB, true, mdBrange, false))); } // Draw lines @@ -1345,9 +1327,10 @@ void TrackArtist::DrawIndividualSamples(wxDC &dc, const wxRect &rect, rect.x + xpos[s + 1], rect.y + ypos[s + 1]); } - if (showPoints) { - // Draw points - int tickSize= bigPoints ? 4 : 3;// Bigger ellipses when draggable. + if (showPoints) + { + // Draw points where spacing is enough + const int tickSize = bigPoints ? 4 : 3;// Bigger ellipses when draggable. wxRect pr; pr.width = tickSize; pr.height = tickSize; @@ -1440,7 +1423,8 @@ void TrackArtist::DrawEnvLine(wxDC &dc, const wxRect &rect, int x0, int y0, int void TrackArtist::DrawWaveform(WaveTrack *track, wxDC & dc, const wxRect & rect, - const ViewInfo *viewInfo, + const SelectedRegion &selectedRegion, + const ZoomInfo &zoomInfo, bool drawEnvelope, bool bigPoints, bool drawSliders, @@ -1448,11 +1432,10 @@ void TrackArtist::DrawWaveform(WaveTrack *track, bool muted) { DrawBackgroundWithSelection(&dc, rect, track, blankSelectedBrush, blankBrush, - viewInfo->selectedRegion.t0(), viewInfo->selectedRegion.t1(), - viewInfo->h, viewInfo->zoom); + selectedRegion, zoomInfo); for (WaveClipList::compatibility_iterator it = track->GetClipIterator(); it; it = it->GetNext()) - DrawClipWaveform(track, it->GetData(), dc, rect, viewInfo, + DrawClipWaveform(track, it->GetData(), dc, rect, selectedRegion, zoomInfo, drawEnvelope, bigPoints, dB, muted); @@ -1461,7 +1444,7 @@ void TrackArtist::DrawWaveform(WaveTrack *track, for (int i = 0; iGetNumCachedLocations(); i++) { WaveTrack::Location loc = track->GetCachedLocation(i); - double xx = (loc.pos - viewInfo->h) * viewInfo->zoom; + const int xx = zoomInfo.TimeToPosition(loc.pos); if (xx >= 0 && xx < rect.width) { dc.SetPen(*wxGREY_PEN); AColor::Line(dc, (int) (rect.x + xx - 1), rect.y, (int) (rect.x + xx - 1), rect.y + rect.height); @@ -1490,18 +1473,18 @@ struct ClipParameters // Do a bunch of calculations common to waveform and spectrum drawing. ClipParameters (bool spectrum, const WaveTrack *track, const WaveClip *clip, const wxRect &rect, - const SelectedRegion &selectedRegion, const ViewInfo &viewInfo) + const SelectedRegion &selectedRegion, const ZoomInfo &zoomInfo) { selectedRegion; tOffset = clip->GetOffset(); rate = clip->GetRate(); - h = viewInfo.h; //The horizontal position in seconds - pps = viewInfo.zoom; //points-per-second--the zoom level + h = zoomInfo.h; //The horizontal position in seconds + pps = zoomInfo.zoom; //points-per-second--the zoom level - double sel0 = viewInfo.selectedRegion.t0(); //left selection bound - double sel1 = viewInfo.selectedRegion.t1(); //right selection bound + double sel0 = selectedRegion.t0(); //left selection bound + double sel1 = selectedRegion.t1(); //right selection bound //If the track isn't selected, make the selection empty if (!track->GetSelected() && @@ -1624,7 +1607,8 @@ void TrackArtist::DrawClipWaveform(WaveTrack *track, WaveClip *clip, wxDC & dc, const wxRect & rect, - const ViewInfo *viewInfo, + const SelectedRegion &selectedRegion, + const ZoomInfo &zoomInfo, bool drawEnvelope, bool bigPoints, bool dB, @@ -1634,7 +1618,7 @@ void TrackArtist::DrawClipWaveform(WaveTrack *track, Profiler profiler; #endif - const ClipParameters params(false, track, clip, rect, viewInfo->selectedRegion, *viewInfo); + const ClipParameters params(false, track, clip, rect, selectedRegion, zoomInfo); const wxRect &mid = params.mid; // The "mid" rect contains the part of the display actually // containing the waveform. If it's empty, we're done. @@ -1646,15 +1630,12 @@ void TrackArtist::DrawClipWaveform(WaveTrack *track, const double &pps = params.pps; const double &tOffset = params.tOffset; const double &tstep = params.tstep; - const double &ssel0 = params.ssel0; - const double &ssel1 = params.ssel1; const bool &showIndividualSamples = params.showIndividualSamples; const bool &showPoints = params.showPoints; const double &h = params.h; const double &tpre = params.tpre; const double &tpost = params.tpost; const double &t1 = params.t1; - const double &rate = params.rate; // Calculate sample-based offset-corrected selection @@ -1679,10 +1660,11 @@ void TrackArtist::DrawClipWaveform(WaveTrack *track, // Draw the background of the track, outlining the shape of // the envelope and using a colored pen for the selected // part of the waveform - DrawWaveformBackground(dc, mid, envValues, zoomMin, zoomMax, dB, - *viewInfo, t0, rate, - ssel0, ssel1, drawEnvelope, - !track->GetSelected()); + DrawWaveformBackground(dc, mid.x - rect.x, mid, + envValues, + zoomMin, zoomMax, dB, + selectedRegion, zoomInfo, drawEnvelope, + !track->GetSelected()); if (!showIndividualSamples) { WaveDisplay display(mid.width); @@ -1697,23 +1679,24 @@ void TrackArtist::DrawClipWaveform(WaveTrack *track, return; } + DrawMinMaxRMS(dc, mid, envValues, + zoomMin, zoomMax, dB, + display.min, display.max, display.rms, display.bl, + isLoadingOD, muted #ifdef EXPERIMENTAL_OUTPUT_DISPLAY - DrawMinMaxRMS(dc, mid, envValues, zoomMin, zoomMax, dB, - min, max, rms, bl, isLoadingOD, muted, track->GetChannelGain(track->GetChannel())); -#else - DrawMinMaxRMS(dc, mid, envValues, zoomMin, zoomMax, dB, - display, isLoadingOD, muted); + , track->GetChannelGain(track->GetChannel()) #endif + ); } else { - DrawIndividualSamples(dc, mid, zoomMin, zoomMax, dB, - clip, t0, pps, h, - bigPoints, showPoints, muted); + DrawIndividualSamples(dc, mid.x - rect.x, mid, + zoomMin, zoomMax, dB, + clip, zoomInfo, bigPoints, showPoints, muted); } if (drawEnvelope) { DrawEnvelope(dc, mid, envValues, zoomMin, zoomMax, dB); - clip->GetEnvelope()->DrawPoints(dc, rect, h, pps, dB, zoomMin, zoomMax); + clip->GetEnvelope()->DrawPoints(dc, rect, zoomInfo, dB, zoomMin, zoomMax); } delete[] envValues; @@ -1799,15 +1782,15 @@ void TrackArtist::DrawTimeSlider(wxDC & dc, void TrackArtist::DrawSpectrum(WaveTrack *track, wxDC & dc, const wxRect & rect, - const ViewInfo *viewInfo) + const SelectedRegion &selectedRegion, + const ZoomInfo &zoomInfo) { DrawBackgroundWithSelection(&dc, rect, track, blankSelectedBrush, blankBrush, - viewInfo->selectedRegion.t0(), viewInfo->selectedRegion.t1(), - viewInfo->h, viewInfo->zoom); + selectedRegion, zoomInfo); WaveTrackCache cache(track); for (WaveClipList::compatibility_iterator it = track->GetClipIterator(); it; it = it->GetNext()) { - DrawClipSpectrum(cache, it->GetData(), dc, rect, viewInfo); + DrawClipSpectrum(cache, it->GetData(), dc, rect, selectedRegion, zoomInfo); } } @@ -1878,26 +1861,25 @@ AColor::ColorGradientChoice ChooseColorSet( float bin0, float bin1, float selBin } -void TrackArtist::DrawClipSpectrum(WaveTrackCache &cache, +void TrackArtist::DrawClipSpectrum(WaveTrackCache &waveTrackCache, WaveClip *clip, wxDC & dc, const wxRect & rect, - const ViewInfo *viewInfo) + const SelectedRegion &selectedRegion, + const ZoomInfo &zoomInfo) { #ifdef PROFILE_WAVEFORM Profiler profiler; #endif - const WaveTrack *const track = cache.GetTrack(); + const WaveTrack *const track = waveTrackCache.GetTrack(); const int display = track->GetDisplay(); const bool autocorrelation = (WaveTrack::PitchDisplay == display); const bool logF = (WaveTrack::SpectrumLogDisplay == display || WaveTrack::SpectralSelectionLogDisplay == display); - - enum { MONOCHROME_LINE = 230, COLORED_LINE = 0 }; enum { DASH_LENGTH = 10 /* pixels */ }; - const ClipParameters params(true, track, clip, rect, viewInfo->selectedRegion, *viewInfo); + const ClipParameters params(true, track, clip, rect, selectedRegion, zoomInfo); const wxRect &mid = params.mid; // The "mid" rect contains the part of the display actually // containing the waveform. If it's empty, we're done. @@ -1916,8 +1898,8 @@ void TrackArtist::DrawClipSpectrum(WaveTrackCache &cache, double freqHi = SelectedRegion::UndefinedFrequency; #ifdef EXPERIMENTAL_SPECTRAL_EDITING if (!autocorrelation) { - freqLo = viewInfo->selectedRegion.f0(); - freqHi = viewInfo->selectedRegion.f1(); + freqLo = selectedRegion.f0(); + freqHi = selectedRegion.f1(); } #endif @@ -1950,7 +1932,7 @@ void TrackArtist::DrawClipSpectrum(WaveTrackCache &cache, const float *freq = 0; const sampleCount *where = 0; - bool updated = clip->GetSpectrogram(cache, freq, where, mid.width, + bool updated = clip->GetSpectrogram(waveTrackCache, freq, where, mid.width, t0, pps, autocorrelation); int ifreq = lrint(rate/2); @@ -2023,9 +2005,11 @@ void TrackArtist::DrawClipSpectrum(WaveTrackCache &cache, && findNotesQuantize==findNotesQuantizeOld #endif ) { - // cache is up to date + // Wave clip's spectrum cache is up to date, + // and so is the spectrum pixel cache } else { + // Update the spectrum pixel cache delete clip->mSpecPxCache; clip->mSpecPxCache = new SpecPxCache(mid.width * mid.height); clip->mSpecPxCache->valid = true; @@ -2471,8 +2455,8 @@ const char *LookupAtomAttribute(Alg_note_ptr note, Alg_attribute attr, char *def return def; } -#define TIME_TO_X(t) (rect.x + (int) (((t) - h) * pps)) -#define X_TO_TIME(xx) (((xx) - rect.x) / pps + h) +#define TIME_TO_X(t) (zoomInfo.TimeToPosition((t), rect.x)) +#define X_TO_TIME(xx) (zoomInfo.PositionToTime((xx), rect.x)) // CLIP(x) changes x to lie between +/- CLIP_MAX due to graphics display problems // with very large coordinate values (this happens when you zoom in very far) @@ -2512,7 +2496,7 @@ int PitchToY(double p, int bottom) */ void TrackArtist::DrawNoteBackground(NoteTrack *track, wxDC &dc, const wxRect &rect, const wxRect &sel, - const ViewInfo *viewInfo, + const ZoomInfo &zoomInfo, const wxBrush &wb, const wxPen &wp, const wxBrush &bb, const wxPen &bp, const wxPen &mp) @@ -2520,8 +2504,6 @@ void TrackArtist::DrawNoteBackground(NoteTrack *track, wxDC &dc, dc.SetBrush(wb); dc.SetPen(wp); dc.DrawRectangle(sel); // fill rectangle with white keys background - double h = viewInfo->h; - double pps = viewInfo->zoom; int left = TIME_TO_X(track->GetOffset()); if (left < sel.x) left = sel.x; // clip on left @@ -2609,16 +2591,16 @@ window and draw out-of-bounds notes here instead. void TrackArtist::DrawNoteTrack(NoteTrack *track, wxDC & dc, const wxRect & rect, - const ViewInfo *viewInfo, + const SelectedRegion &selectedRegion, + const ZoomInfo &zoomInfo, bool muted) { SonifyBeginNoteBackground(); - double h = viewInfo->h; - double pps = viewInfo->zoom; - double sel0 = viewInfo->selectedRegion.t0(); - double sel1 = viewInfo->selectedRegion.t1(); + double sel0 = selectedRegion.t0(); + double sel1 = selectedRegion.t1(); - double h1 = X_TO_TIME(rect.x + rect.width); + const double h = X_TO_TIME(rect.x); + const double h1 = X_TO_TIME(rect.x + rect.width); Alg_seq_ptr seq = track->mSeq; if (!seq) { @@ -2664,7 +2646,7 @@ void TrackArtist::DrawNoteTrack(NoteTrack *track, wxPen barLinePen; barLinePen.SetColour(170, 170, 170); - DrawNoteBackground(track, dc, rect, rect, viewInfo, blankBrush, blankPen, + DrawNoteBackground(track, dc, rect, rect, zoomInfo, blankBrush, blankPen, blackStripeBrush, blackStripePen, barLinePen); dc.SetClippingRegion(rect); @@ -2692,7 +2674,7 @@ void TrackArtist::DrawNoteTrack(NoteTrack *track, wxPen selectedBarLinePen; selectedBarLinePen.SetColour(131, 131, 150); - DrawNoteBackground(track, dc, rect, selBG, viewInfo, + DrawNoteBackground(track, dc, rect, selBG, zoomInfo, selectedWhiteKeyBrush, selectedWhiteKeyPen, selectedBlackKeyBrush, selectedBlackKeyPen, selectedBarLinePen); @@ -2747,8 +2729,8 @@ void TrackArtist::DrawNoteTrack(NoteTrack *track, nr.y = track->PitchToY(note->pitch); nr.height = track->GetPitchHeight(); - nr.x = rect.x + (int) ((xx - h) * pps); - nr.width = (int) ((note->dur * pps) + 0.5); + nr.x = TIME_TO_X(xx); + nr.width = TIME_TO_X(x1) - nr.x; if (nr.x + nr.width >= rect.x && nr.x < rect.x + rect.width) { if (nr.x < rect.x) { @@ -2845,12 +2827,12 @@ void TrackArtist::DrawNoteTrack(NoteTrack *track, AColor::Line(dc, TIME_TO_X(xx), yy, TIME_TO_X(x1), y1); } else if (shape == rectangle) { if (xx < h) { // clip on left, leave 10 pixels to spare - xx = h - (linethick + 10) / pps; + xx = X_TO_TIME(rect.x - (linethick + 10)); } if (x1 > h1) { // clip on right, leave 10 pixels to spare - x1 = h1 + (linethick + 10) / pps; + xx = X_TO_TIME(rect.x + rect.width + linethick + 10); } - dc.DrawRectangle(TIME_TO_X(xx), yy, int((x1 - xx) * pps + 0.5), y1 - yy + 1); + dc.DrawRectangle(TIME_TO_X(xx), yy, TIME_TO_X(x1) - TIME_TO_X(xx), y1 - yy + 1); } else if (shape == triangle) { wxPoint points[3]; points[0].x = TIME_TO_X(xx); @@ -2894,7 +2876,7 @@ void TrackArtist::DrawNoteTrack(NoteTrack *track, } else if (shape == oval) { int ix = TIME_TO_X(xx); CLIP(ix); - int ix1 = int((x1 - xx) * pps + 0.5); + int ix1 = TIME_TO_X(x1) - TIME_TO_X(xx); if (ix1 > CLIP_MAX * 2) ix1 = CLIP_MAX * 2; // CLIP a width dc.DrawEllipse(ix, yy, ix1, y1 - yy + 1); } else if (shape == text) { @@ -2983,23 +2965,24 @@ void TrackArtist::DrawNoteTrack(NoteTrack *track, void TrackArtist::DrawLabelTrack(LabelTrack *track, wxDC & dc, const wxRect & rect, - const ViewInfo *viewInfo) + const SelectedRegion &selectedRegion, + const ZoomInfo &zoomInfo) { - double sel0 = viewInfo->selectedRegion.t0(); - double sel1 = viewInfo->selectedRegion.t1(); + double sel0 = selectedRegion.t0(); + double sel1 = selectedRegion.t1(); if (!track->GetSelected() && !track->IsSyncLockSelected()) sel0 = sel1 = 0.0; - track->Draw(dc, rect, viewInfo->h, viewInfo->zoom, sel0, sel1); + track->Draw(dc, rect, SelectedRegion(sel0, sel1), zoomInfo); } void TrackArtist::DrawTimeTrack(TimeTrack *track, wxDC & dc, const wxRect & rect, - const ViewInfo *viewInfo) + const ZoomInfo &zoomInfo) { - track->Draw(dc, rect, viewInfo->h, viewInfo->zoom); + track->Draw(dc, rect, zoomInfo); wxRect envRect = rect; envRect.height -= 2; double lower = track->GetRangeLower(), upper = track->GetRangeUpper(); @@ -3009,7 +2992,7 @@ void TrackArtist::DrawTimeTrack(TimeTrack *track, lower = 20.0 * log10(std::max(1.0e-7, lower)) / dBRange + 1.0; upper = 20.0 * log10(std::max(1.0e-7, upper)) / dBRange + 1.0; } - track->GetEnvelope()->DrawPoints(dc, envRect, viewInfo->h, viewInfo->zoom, + track->GetEnvelope()->DrawPoints(dc, envRect, zoomInfo, track->GetDisplayLog(), lower, upper); } @@ -3202,14 +3185,17 @@ void TrackArtist::DrawSyncLockTiles(wxDC *dc, wxRect rect) } void TrackArtist::DrawBackgroundWithSelection(wxDC *dc, const wxRect &rect, - Track *track, wxBrush &selBrush, wxBrush &unselBrush, - double sel0, double sel1, double h, double pps) + Track *track, wxBrush &selBrush, wxBrush &unselBrush, + const SelectedRegion &selectedRegion, const ZoomInfo &zoomInfo) { //MM: Draw background. We should optimize that a bit more. //AWD: "+ 1.5" and "+ 2.5" throughout match code in //AdornedRulerPanel::DoDrawSelection() and make selection line up with ruler. //I don't know if/why this is correct. + const double sel0 = selectedRegion.t0(); + const double sel1 = selectedRegion.t1(); + dc->SetPen(*wxTRANSPARENT_PEN); if (track->GetSelected() || track->IsSyncLockSelected()) { @@ -3218,7 +3204,7 @@ void TrackArtist::DrawBackgroundWithSelection(wxDC *dc, const wxRect &rect, wxRect within = rect; wxRect after = rect; - before.width = int ((sel0 - h) * pps + 2.5); + before.width = int(zoomInfo.TimeToPosition(sel0) + 2); if (before.GetRight() > rect.GetRight()) { before.width = rect.width; } @@ -3229,7 +3215,7 @@ void TrackArtist::DrawBackgroundWithSelection(wxDC *dc, const wxRect &rect, within.x = before.GetRight(); } - within.width = rect.x + int ((sel1 - h) * pps + 2.5) - within.x; + within.width = rect.x + int(zoomInfo.TimeToPosition(sel1) + 2) - within.x; if (within.GetRight() > rect.GetRight()) { within.width = rect.GetRight() - within.x; diff --git a/src/TrackArtist.h b/src/TrackArtist.h index 49d4e347d..5c96ca38a 100644 --- a/src/TrackArtist.h +++ b/src/TrackArtist.h @@ -37,7 +37,8 @@ class LabelTrack; class TimeTrack; class TrackList; class Ruler; -class ViewInfo; +class SelectedRegion; +class ZoomInfo; #ifndef uchar typedef unsigned char uchar; @@ -52,11 +53,13 @@ class AUDACITY_DLL_API TrackArtist { void SetColours(); void DrawTracks(TrackList *tracks, Track *start, wxDC & dc, wxRegion & reg, - wxRect & rect, wxRect & clip, ViewInfo *viewInfo, + wxRect & rect, wxRect & clip, + const SelectedRegion &selectedRegion, const ZoomInfo &zoomInfo, bool drawEnvelope, bool bigPoints, bool drawSliders); void DrawTrack(const Track *t, - wxDC & dc, const wxRect & rect, const ViewInfo *viewInfo, + wxDC & dc, const wxRect & rect, + const SelectedRegion &selectedRegion, const ZoomInfo &zoomInfo, bool drawEnvelope, bool bigPoints, bool drawSliders, bool hasSolo); @@ -95,7 +98,7 @@ class AUDACITY_DLL_API TrackArtist { // Helper: draws background with selection rect static void DrawBackgroundWithSelection(wxDC *dc, const wxRect &rect, Track *track, wxBrush &selBrush, wxBrush &unselBrush, - double sel0, double sel1, double h, double pps); + const SelectedRegion &selectedRegion, const ZoomInfo &zoomInfo); private: @@ -104,60 +107,67 @@ class AUDACITY_DLL_API TrackArtist { // void DrawWaveform(WaveTrack *track, - wxDC & dc, const wxRect & rect, const ViewInfo *viewInfo, + wxDC & dc, const wxRect & rect, + const SelectedRegion &selectedRegion, const ZoomInfo &zoomInfo, bool drawEnvelope, bool bigPoints, bool drawSliders, bool dB, bool muted); void DrawSpectrum(WaveTrack *track, - wxDC & dc, const wxRect & rect, const ViewInfo *viewInfo); + wxDC & dc, const wxRect & rect, + const SelectedRegion &selectedRegion, const ZoomInfo &zoomInfo); #ifdef USE_MIDI int GetBottom(NoteTrack *t, const wxRect &rect); void DrawNoteBackground(NoteTrack *track, wxDC &dc, const wxRect &rect, const wxRect &sel, - const ViewInfo *viewInfo, + const ZoomInfo &zoomInfo, const wxBrush &wb, const wxPen &wp, const wxBrush &bb, const wxPen &bp, const wxPen &mp); void DrawNoteTrack(NoteTrack *track, - wxDC & dc, const wxRect & rect, const ViewInfo *viewInfo, + wxDC & dc, const wxRect & rect, + const SelectedRegion &selectedRegion, const ZoomInfo &zoomInfo, bool muted); #endif // USE_MIDI void DrawLabelTrack(LabelTrack *track, - wxDC & dc, const wxRect & rect, const ViewInfo *viewInfo); + wxDC & dc, const wxRect & rect, + const SelectedRegion &selectedRegion, const ZoomInfo &zoomInfo); void DrawTimeTrack(TimeTrack *track, - wxDC & dc, const wxRect & rect, const ViewInfo *viewInfo); + wxDC & dc, const wxRect & rect, const ZoomInfo &zoomInfo); void DrawTimeSlider(wxDC & dc, const wxRect & rect, bool rightwards); void DrawClipWaveform(WaveTrack *track, WaveClip *clip, - wxDC & dc, const wxRect & rect, const ViewInfo *viewInfo, + wxDC & dc, const wxRect & rect, + const SelectedRegion &selectedRegion, const ZoomInfo &zoomInfo, bool drawEnvelope, bool bigPoints, bool dB, bool muted); void DrawClipSpectrum(WaveTrackCache &cache, WaveClip *clip, - wxDC & dc, const wxRect & rect, const ViewInfo *viewInfo); + wxDC & dc, const wxRect & rect, + const SelectedRegion &selectedRegion, const ZoomInfo &zoomInfo); // Waveform utility functions - void DrawWaveformBackground(wxDC & dc, const wxRect &rect, const double env[], + void DrawWaveformBackground(wxDC & dc, int leftOffset, const wxRect &rect, + const double env[], float zoomMin, float zoomMax, bool dB, - const ViewInfo &viewInfo, double t0, double rate, - sampleCount ssel0, sampleCount ssel1, + const SelectedRegion &selectedRegion, const ZoomInfo &zoomInfo, bool drawEnvelope, bool bIsSyncLockSelected); - void DrawMinMaxRMS(wxDC &dc, const wxRect &rect, const double env[], + void DrawMinMaxRMS(wxDC &dc, const wxRect & rect, const double env[], float zoomMin, float zoomMax, bool dB, - const WaveDisplay &display, bool /* showProgress */, bool muted + const float *min, const float *max, const float *rms, const int *bl, + bool /* showProgress */, bool muted #ifdef EXPERIMENTAL_OUTPUT_DISPLAY , const float gain #endif ); - void DrawIndividualSamples(wxDC & dc, const wxRect & rect, + void DrawIndividualSamples(wxDC & dc, int leftOffset, const wxRect & rect, float zoomMin, float zoomMax, bool dB, WaveClip *clip, - double t0, double pps, double h, + const ZoomInfo &zoomInfo, bool bigPoints, bool showPoints, bool muted); void DrawNegativeOffsetTrackArrows(wxDC & dc, const wxRect & rect); diff --git a/src/TrackPanel.cpp b/src/TrackPanel.cpp index 937383c2c..5ad6180d8 100644 --- a/src/TrackPanel.cpp +++ b/src/TrackPanel.cpp @@ -7207,13 +7207,14 @@ void TrackPanel::DrawTracks(wxDC * dc) ToolsToolBar *pTtb = mListener->TP_GetToolsToolBar(); bool bMultiToolDown = pTtb->IsDown(multiTool); bool envelopeFlag = pTtb->IsDown(envelopeTool) || bMultiToolDown; - bool samplesFlag = pTtb->IsDown(drawTool) || bMultiToolDown; + bool bigPointsFlag = pTtb->IsDown(drawTool) || bMultiToolDown; bool sliderFlag = bMultiToolDown; // The track artist actually draws the stuff inside each track mTrackArtist->DrawTracks(mTracks, GetProject()->GetFirstVisible(), - *dc, region, tracksRect, clip, mViewInfo, - envelopeFlag, samplesFlag, sliderFlag); + *dc, region, tracksRect, clip, + mViewInfo->selectedRegion, *mViewInfo, + envelopeFlag, bigPointsFlag, sliderFlag); DrawEverythingElse(dc, region, clip); } diff --git a/src/effects/Equalization.cpp b/src/effects/Equalization.cpp index 8d45a2078..ac81f46ea 100644 --- a/src/effects/Equalization.cpp +++ b/src/effects/Equalization.cpp @@ -2804,7 +2804,8 @@ void EqualizationPanel::OnPaint(wxPaintEvent & WXUNUSED(event)) memDC.SetPen(*wxBLACK_PEN); if( mEffect->mDraw->GetValue() ) - mEffect->mEnvelope->DrawPoints(memDC, mEnvRect, 0.0, mEnvRect.width-1, false, mEffect->mdBMin, mEffect->mdBMax); + mEffect->mEnvelope->DrawPoints(memDC, mEnvRect, ZoomInfo(0.0, 1.0, mEnvRect.width-1), false, + mEffect->mdBMin, mEffect->mdBMax); dc.Blit(0, 0, mWidth, mHeight, &memDC, 0, 0, wxCOPY, FALSE); From c14b3269137c9e6b3913a98ee3e0b66e216ad8ae Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Tue, 9 Jun 2015 14:01:44 -0400 Subject: [PATCH 24/36] Publicize class SpecCache. TrackArtist will re-use it. --- src/WaveClip.cpp | 90 ------------------------------------------------ src/WaveClip.h | 86 ++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 85 insertions(+), 91 deletions(-) diff --git a/src/WaveClip.cpp b/src/WaveClip.cpp index 3103f2001..ff27c7b40 100644 --- a/src/WaveClip.cpp +++ b/src/WaveClip.cpp @@ -17,12 +17,6 @@ \class WaveCache \brief Cache used with WaveClip to cache wave information (for drawing). -*//****************************************************************//** - -\class SpecCache -\brief Cache used with WaveClip to cache spectrum information (for -drawing). Cache's the Spectrogram frequency samples. - *//*******************************************************************/ #include "WaveClip.h" @@ -263,90 +257,6 @@ protected: }; -class SpecCache { -public: - - // Make invalid cache - SpecCache() - : len(-1) - , ac(false) - , pps(-1.0) - , start(-1.0) - , windowType(-1) - , windowSize(-1) - , zeroPaddingFactor(-1) - , frequencyGain(-1) - - , freq(NULL) - , where(NULL) - - , dirty(-1) - { - } - - // Make valid cache, to be filled in - SpecCache(int cacheLen, bool autocorrelation, - double pps_, double start_, int windowType_, int windowSize_, - int zeroPaddingFactor_, int frequencyGain_ - ) - : len(cacheLen) - , ac(autocorrelation) - , pps(pps_) - , start(start_) - , windowType(windowType_) - , windowSize(windowSize_) - , zeroPaddingFactor(zeroPaddingFactor_) - , frequencyGain(frequencyGain_) - - // len columns, and so many rows, column-major. - // Don't take column literally -- this isn't pixel data yet, it's the - // raw data to be mapped onto the display. - , freq(len * ((windowSize * zeroPaddingFactor) / 2)) - - // Sample counts corresponding to the columns, and to one past the end. - , where(len + 1) - - , dirty(-1) - { - where[0] = 0; - } - - ~SpecCache() - { - } - - bool Matches(int dirty_, bool autocorrelation, double pixelsPerSecond, - const SpectrogramSettings &settings, double rate) const; - - void CalculateOneSpectrum - (const SpectrogramSettings &settings, - WaveTrackCache &waveTrackCache, - int xx, sampleCount numSamples, - double offset, double rate, - bool autocorrelation, const std::vector &gainFactors, - float *scratch); - - void Populate - (const SpectrogramSettings &settings, WaveTrackCache &waveTrackCache, - int copyBegin, int copyEnd, int numPixels, - sampleCount numSamples, - double offset, double rate, - bool autocorrelation); - - const int len; // counts pixels, not samples - const bool ac; - const double pps; - const double start; - const int windowType; - const int windowSize; - const int zeroPaddingFactor; - const int frequencyGain; - std::vector freq; - std::vector where; - - int dirty; -}; - #ifdef EXPERIMENTAL_USE_REALFFTF #include "FFT.h" static void ComputeSpectrumUsingRealFFTf diff --git a/src/WaveClip.h b/src/WaveClip.h index 42e435e30..1f55bbf55 100644 --- a/src/WaveClip.h +++ b/src/WaveClip.h @@ -32,9 +32,93 @@ #include class Envelope; +class SpectrogramSettings; class WaveCache; class WaveTrackCache; -class SpecCache; + +class SpecCache { +public: + + // Make invalid cache + SpecCache() + : len(-1) + , ac(false) + , pps(-1.0) + , start(-1.0) + , windowType(-1) + , windowSize(-1) + , zeroPaddingFactor(-1) + , frequencyGain(-1) + + , freq(NULL) + , where(NULL) + + , dirty(-1) + { + } + + // Make valid cache, to be filled in + SpecCache(int cacheLen, bool autocorrelation, + double pps_, double start_, int windowType_, int windowSize_, + int zeroPaddingFactor_, int frequencyGain_ + ) + : len(cacheLen) + , ac(autocorrelation) + , pps(pps_) + , start(start_) + , windowType(windowType_) + , windowSize(windowSize_) + , zeroPaddingFactor(zeroPaddingFactor_) + , frequencyGain(frequencyGain_) + + // len columns, and so many rows, column-major. + // Don't take column literally -- this isn't pixel data yet, it's the + // raw data to be mapped onto the display. + , freq(len * ((windowSize * zeroPaddingFactor) / 2)) + + // Sample counts corresponding to the columns, and to one past the end. + , where(len + 1) + + , dirty(-1) + { + where[0] = 0; + } + + ~SpecCache() + { + } + + bool Matches(int dirty_, bool autocorrelation, double pixelsPerSecond, + const SpectrogramSettings &settings, double rate) const; + + void CalculateOneSpectrum + (const SpectrogramSettings &settings, + WaveTrackCache &waveTrackCache, + int xx, sampleCount numSamples, + double offset, double rate, + bool autocorrelation, const std::vector &gainFactors, + float *scratch); + + void Populate + (const SpectrogramSettings &settings, WaveTrackCache &waveTrackCache, + int copyBegin, int copyEnd, int numPixels, + sampleCount numSamples, + double offset, double rate, + bool autocorrelation); + + const int len; // counts pixels, not samples + const bool ac; + const double pps; + const double start; + const int windowType; + const int windowSize; + const int zeroPaddingFactor; + const int frequencyGain; + std::vector freq; + std::vector where; + + int dirty; +}; class SpecPxCache { public: From 8664c877ba3ba4f3cf5182a6a86f6a7f9759e757 Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Tue, 9 Jun 2015 14:12:28 -0400 Subject: [PATCH 25/36] WaveDisplay may or may not manage its own memory. --- src/WaveClip.cpp | 217 +++++++++++++++++++++++++++-------------------- src/WaveClip.h | 29 +++++++ 2 files changed, 156 insertions(+), 90 deletions(-) diff --git a/src/WaveClip.cpp b/src/WaveClip.cpp index ff27c7b40..762683782 100644 --- a/src/WaveClip.cpp +++ b/src/WaveClip.cpp @@ -55,8 +55,8 @@ public: { } - WaveCache(int len_, double pixelsPerSecond, double rate_, double t0) - : dirty(-1) + WaveCache(int len_, double pixelsPerSecond, double rate_, double t0, int dirty_) + : dirty(dirty_) , len(len_) , start(t0) , pps(pixelsPerSecond) @@ -497,110 +497,137 @@ fillWhere(std::vector &where, int len, double bias, double correcti bool WaveClip::GetWaveDisplay(WaveDisplay &display, double t0, double pixelsPerSecond, bool &isLoadingOD) { - int numPixels = display.width; + const bool allocated = (display.where != 0); - ODLocker locker(mWaveCacheMutex); + const int numPixels = display.width; - const double tstep = 1.0 / pixelsPerSecond; - const double samplesPerPixel = mRate * tstep; + int p0 = 0; // least column requiring computation + int p1 = numPixels; // greatest column requiring computation, plus one - // Make a tolerant comparison of the pps values in this wise: - // accumulated difference of times over the number of pixels is less than - // a sample period. - const bool ppsMatch = mWaveCache && - (fabs(tstep - 1.0 / mWaveCache->pps) * numPixels < (1.0 / mRate)); + float *min; + float *max; + float *rms; + int *bl; + std::vector *pWhere; - const bool match = - mWaveCache && - ppsMatch && - mWaveCache->len > 0 && - mWaveCache->dirty == mDirty; - - if (match && - mWaveCache->start == t0 && - mWaveCache->len >= numPixels) { - mWaveCache->LoadInvalidRegions(mSequence, true); - mWaveCache->ClearInvalidRegions(); - - // Satisfy the request completely from the cache - display.min = &mWaveCache->min[0]; - display.max = &mWaveCache->max[0]; - display.rms = &mWaveCache->rms[0]; - display.bl = &mWaveCache->bl[0]; - display.where = &mWaveCache->where[0]; - isLoadingOD = mWaveCache->numODPixels > 0; - return true; + if (allocated) { + // assume ownWhere is filled. + min = &display.min[0]; + max = &display.max[0]; + rms = &display.rms[0]; + bl = &display.bl[0]; + pWhere = &display.ownWhere; } + else { + // Lock the list of invalid regions + ODLocker locker(mWaveCacheMutex); - std::auto_ptr oldCache(mWaveCache); - mWaveCache = 0; + const double tstep = 1.0 / pixelsPerSecond; + const double samplesPerPixel = mRate * tstep; - int oldX0 = 0; - double correction = 0.0; + // Make a tolerant comparison of the pps values in this wise: + // accumulated difference of times over the number of pixels is less than + // a sample period. + const bool ppsMatch = mWaveCache && + (fabs(tstep - 1.0 / mWaveCache->pps) * numPixels < (1.0 / mRate)); - int copyBegin = 0, copyEnd = 0; - if (match) { - findCorrection(oldCache->where, oldCache->len, numPixels, - t0, mRate, samplesPerPixel, - oldX0, correction); - // Remember our first pixel maps to oldX0 in the old cache, - // possibly out of bounds. - // For what range of pixels can data be copied? - copyBegin = std::min(numPixels, std::max(0, -oldX0)); - copyEnd = std::min(numPixels, - copyBegin + oldCache->len - std::max(0, oldX0) - ); - } + const bool match = + mWaveCache && + ppsMatch && + mWaveCache->len > 0 && + mWaveCache->dirty == mDirty; - if (!(copyEnd > copyBegin)) - oldCache.reset(0); + if (match && + mWaveCache->start == t0 && + mWaveCache->len >= numPixels) { + mWaveCache->LoadInvalidRegions(mSequence, true); + mWaveCache->ClearInvalidRegions(); - mWaveCache = new WaveCache(numPixels, pixelsPerSecond, mRate, t0); - float *const min = &mWaveCache->min[0]; - float *const max = &mWaveCache->max[0]; - float *const rms = &mWaveCache->rms[0]; - int *const bl = &mWaveCache->bl[0]; - std::vector &where = mWaveCache->where; + // Satisfy the request completely from the cache + display.min = &mWaveCache->min[0]; + display.max = &mWaveCache->max[0]; + display.rms = &mWaveCache->rms[0]; + display.bl = &mWaveCache->bl[0]; + display.where = &mWaveCache->where[0]; + isLoadingOD = mWaveCache->numODPixels > 0; + return true; + } - fillWhere(where, numPixels, 0.0, correction, - t0, mRate, samplesPerPixel); + std::auto_ptr oldCache(mWaveCache); + mWaveCache = 0; - // The range of pixels we must fetch from the Sequence: - const int p0 = (copyBegin > 0) ? 0 : copyEnd; - int p1 = (copyEnd >= numPixels) ? copyBegin : numPixels; + int oldX0 = 0; + double correction = 0.0; + int copyBegin = 0, copyEnd = 0; + if (match) { + findCorrection(oldCache->where, oldCache->len, numPixels, + t0, mRate, samplesPerPixel, + oldX0, correction); + // Remember our first pixel maps to oldX0 in the old cache, + // possibly out of bounds. + // For what range of pixels can data be copied? + copyBegin = std::min(numPixels, std::max(0, -oldX0)); + copyEnd = std::min(numPixels, + copyBegin + oldCache->len - std::max(0, oldX0) + ); + } + if (!(copyEnd > copyBegin)) + oldCache.reset(0); - // Optimization: if the old cache is good and overlaps - // with the current one, re-use as much of the cache as - // possible + mWaveCache = new WaveCache(numPixels, pixelsPerSecond, mRate, t0, mDirty); + min = &mWaveCache->min[0]; + max = &mWaveCache->max[0]; + rms = &mWaveCache->rms[0]; + bl = &mWaveCache->bl[0]; + pWhere = &mWaveCache->where; - if (oldCache.get()) { + fillWhere(*pWhere, numPixels, 0.0, correction, + t0, mRate, samplesPerPixel); - //TODO: only load inval regions if - //necessary. (usually is the case, so no rush.) - //also, we should be updating the NEW cache, but here we are patching the old one up. - oldCache->LoadInvalidRegions(mSequence, false); - oldCache->ClearInvalidRegions(); + // The range of pixels we must fetch from the Sequence: + p0 = (copyBegin > 0) ? 0 : copyEnd; + p1 = (copyEnd >= numPixels) ? copyBegin : numPixels; - // Copy what we can from the old cache. - const int length = copyEnd - copyBegin; - const size_t sizeFloats = length * sizeof(float); - const int srcIdx = copyBegin + oldX0; - memcpy(&min[copyBegin], &oldCache->min[srcIdx], sizeFloats); - memcpy(&max[copyBegin], &oldCache->max[srcIdx], sizeFloats); - memcpy(&rms[copyBegin], &oldCache->rms[srcIdx], sizeFloats); - memcpy(&bl[copyBegin], &oldCache->bl[srcIdx], length * sizeof(int)); + // Optimization: if the old cache is good and overlaps + // with the current one, re-use as much of the cache as + // possible + + if (oldCache.get()) { + + //TODO: only load inval regions if + //necessary. (usually is the case, so no rush.) + //also, we should be updating the NEW cache, but here we are patching the old one up. + oldCache->LoadInvalidRegions(mSequence, false); + oldCache->ClearInvalidRegions(); + + // Copy what we can from the old cache. + const int length = copyEnd - copyBegin; + const size_t sizeFloats = length * sizeof(float); + const int srcIdx = copyBegin + oldX0; + memcpy(&min[copyBegin], &oldCache->min[srcIdx], sizeFloats); + memcpy(&max[copyBegin], &oldCache->max[srcIdx], sizeFloats); + memcpy(&rms[copyBegin], &oldCache->rms[srcIdx], sizeFloats); + memcpy(&bl[copyBegin], &oldCache->bl[srcIdx], length * sizeof(int)); + } } if (p1 > p0) { + // Cache was not used or did not satisfy the whole request + std::vector &where = *pWhere; /* handle values in the append buffer */ int numSamples = mSequence->GetNumSamples(); int a; - for(a = p0; a < p1; ++a) - if (where[a+1] > numSamples) - break; + // Not all of the required columns might be in the sequence. + // Some might be in the append buffer. + for (a = p0; a < p1; ++a) { + if (where[a + 1] > numSamples) + break; + } + + // Handle the columns that land in the append buffer. //compute the values that are outside the overlap from scratch. if (a < p1) { int i; @@ -611,7 +638,7 @@ bool WaveClip::GetWaveDisplay(WaveDisplay &display, double t0, sampleCount left; left = where[i] - numSamples; sampleCount right; - right = where[i+1] - numSamples; + right = where[i + 1] - numSamples; //wxCriticalSectionLocker locker(mAppendCriticalSection); @@ -664,6 +691,8 @@ bool WaveClip::GetWaveDisplay(WaveDisplay &display, double t0, p1 = a; } + // Done with append buffer, now fetch the rest of the cache miss + // from the sequence if (p1 > p0) { if (!mSequence->GetWaveDisplay(&min[p0], &max[p0], @@ -678,15 +707,23 @@ bool WaveClip::GetWaveDisplay(WaveDisplay &display, double t0, } } - mWaveCache->dirty = mDirty; + //find the number of OD pixels - the only way to do this is by recounting + if (!allocated) { + // Now report the results + display.min = min; + display.max = max; + display.rms = rms; + display.bl = bl; + display.where = &(*pWhere)[0]; + isLoadingOD = mWaveCache->numODPixels > 0; + } + else { + using namespace std; + isLoadingOD = + count_if(display.ownBl.begin(), display.ownBl.end(), + bind2nd(less(), 0)) > 0; + } - // Now report the results - display.min = min; - display.max = max; - display.rms = rms; - display.bl = bl; - display.where = &where[0]; - isLoadingOD = mWaveCache->numODPixels > 0; return true; } diff --git a/src/WaveClip.h b/src/WaveClip.h index 1f55bbf55..07bd5230b 100644 --- a/src/WaveClip.h +++ b/src/WaveClip.h @@ -151,6 +151,8 @@ class WaveClip; WX_DECLARE_USER_EXPORTED_LIST(WaveClip, WaveClipList, AUDACITY_DLL_API); WX_DEFINE_USER_EXPORTED_ARRAY_PTR(WaveClip*, WaveClipArray, class AUDACITY_DLL_API); +// A bundle of arrays needed for drawing waveforms. The object may or may not +// own the storage for those arrays. If it does, it destroys them. class WaveDisplay { public: @@ -159,11 +161,38 @@ public: float *min, *max, *rms; int* bl; + std::vector ownWhere; + std::vector ownMin, ownMax, ownRms; + std::vector ownBl; + +public: WaveDisplay(int w) : width(w), where(0), min(0), max(0), rms(0), bl(0) { } + // Create "own" arrays. + void Allocate() + { + ownWhere.resize(width + 1); + ownMin.resize(width); + ownMax.resize(width); + ownRms.resize(width); + ownBl.resize(width); + + where = &ownWhere[0]; + if (width > 0) { + min = &ownMin[0]; + max = &ownMax[0]; + rms = &ownRms[0]; + bl = &ownBl[0]; + } + else { + min = max = rms = 0; + bl = 0; + } + } + ~WaveDisplay() { } From 6b9e7506ddc54d5a8baa4d5bf3c98fe5f23397b0 Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Tue, 9 Jun 2015 16:11:02 -0400 Subject: [PATCH 26/36] Ruler-drawing does not assume uniform zoom, ... ... and AdornedRulerPanel exposes an invalidation function for later use --- src/Project.h | 1 + src/TimeTrack.cpp | 6 ++- src/widgets/Ruler.cpp | 108 ++++++++++++++++++++++++++++-------------- src/widgets/Ruler.h | 25 ++++++---- 4 files changed, 94 insertions(+), 46 deletions(-) diff --git a/src/Project.h b/src/Project.h index 3121f63fa..8793bde25 100644 --- a/src/Project.h +++ b/src/Project.h @@ -156,6 +156,7 @@ class AUDACITY_DLL_API AudacityProject: public wxFrame, bool ZoomOutAvailable() const { return mViewInfo.ZoomOutAvailable(); } double GetSel0() { return mViewInfo.selectedRegion.t0(); } double GetSel1() { return mViewInfo.selectedRegion.t1(); } + const ZoomInfo &GetZoomInfo() const { return mViewInfo; } Track *GetFirstVisible(); void UpdateFirstVisible(); diff --git a/src/TimeTrack.cpp b/src/TimeTrack.cpp index 5bf349ffc..ea121cf4a 100644 --- a/src/TimeTrack.cpp +++ b/src/TimeTrack.cpp @@ -53,7 +53,8 @@ TimeTrack::TimeTrack(DirManager *projDirManager): SetDefaultName(_("Time Track")); SetName(GetDefaultName()); - mRuler = new Ruler(); + mRuler = new Ruler; + mRuler->SetUseZoomInfo(0); mRuler->SetLabelEdges(false); mRuler->SetFormat(Ruler::TimeFormat); @@ -77,7 +78,8 @@ TimeTrack::TimeTrack(TimeTrack &orig): mEnvelope->Paste(0.0, orig.mEnvelope); ///@TODO: Give Ruler:: a copy-constructor instead of this? - mRuler = new Ruler(); + mRuler = new Ruler; + mRuler->SetUseZoomInfo(0); mRuler->SetLabelEdges(false); mRuler->SetFormat(Ruler::TimeFormat); diff --git a/src/widgets/Ruler.cpp b/src/widgets/Ruler.cpp index 7b6ac4c4b..49ce486f3 100644 --- a/src/widgets/Ruler.cpp +++ b/src/widgets/Ruler.cpp @@ -79,6 +79,7 @@ array of Ruler::Label. #include "../Prefs.h" #include "../Snap.h" +using std::min; using std::max; #define SELECT_TOLERANCE_PIXEL 4 @@ -157,6 +158,8 @@ Ruler::Ruler() mMinorGrid = false; mTwoTone = false; + + mUseZoomInfo = false; } Ruler::~Ruler() @@ -947,6 +950,10 @@ void Ruler::Update() void Ruler::Update(TimeTrack* timetrack)// Envelope *speedEnv, long minSpeed, long maxSpeed ) { + const ZoomInfo *zoomInfo = NULL; + if (mUseZoomInfo && !mLog && mOrientation == wxHORIZONTAL) + zoomInfo = &GetActiveProject()->GetZoomInfo(); + // This gets called when something has been changed // (i.e. we've been invalidated). Recompute all // tick positions and font size. @@ -1074,8 +1081,14 @@ void Ruler::Update(TimeTrack* timetrack)// Envelope *speedEnv, long minSpeed, lo // Zero (if it's in the middle somewhere) if (mMin * mMax < 0.0) { - int mid = (int)(mLength*(mMin/(mMin-mMax)) + 0.5); - Tick(mid, 0.0, true, false); + int mid; + if (zoomInfo != NULL) + mid = int(zoomInfo->TimeToPosition(0.0, mLeftOffset)); + else + mid = (int)(mLength*(mMin / (mMin - mMax)) + 0.5); + const int iMaxPos = (mOrientation == wxHORIZONTAL) ? mRight : mBottom - 5; + if (mid >= 0 && mid < iMaxPos) + Tick(mid, 0.0, true, false); } double sg = UPP > 0.0? 1.0: -1.0; @@ -1083,8 +1096,18 @@ void Ruler::Update(TimeTrack* timetrack)// Envelope *speedEnv, long minSpeed, lo // Major and minor ticks for (int jj = 0; jj < 2; ++jj) { const double denom = jj == 0 ? mMajor : mMinor; - double d, warpedD; - d = mMin - UPP / 2; + i = -1; j = 0; + double d, warpedD, nextD; + + double prevTime = 0.0, time = 0.0; + if (zoomInfo != NULL) { + j = zoomInfo->TimeToPosition(mMin); + prevTime = zoomInfo->PositionToTime(--j); + time = zoomInfo->PositionToTime(++j); + d = (prevTime + time) / 2.0; + } + else + d = mMin - UPP / 2; if (timetrack) warpedD = timetrack->ComputeWarpedLength(0.0, d); else @@ -1092,14 +1115,22 @@ void Ruler::Update(TimeTrack* timetrack)// Envelope *speedEnv, long minSpeed, lo // using ints doesn't work, as // this will overflow and be negative at high zoom. double step = floor(sg * warpedD / denom); - i = -1; while (i <= mLength) { i++; - if (timetrack) - warpedD += timetrack->ComputeWarpedLength(d, d + UPP); + if (zoomInfo) + { + prevTime = time; + time = zoomInfo->PositionToTime(++j); + nextD = (prevTime + time) / 2.0; + // wxASSERT(time >= prevTime); + } else - warpedD += UPP; - d += UPP; + nextD = d + UPP; + if (timetrack) + warpedD += timetrack->ComputeWarpedLength(d, nextD); + else + warpedD = nextD; + d = nextD; if (floor(sg * warpedD / denom) > step) { step = floor(sg * warpedD / denom); @@ -1114,7 +1145,6 @@ void Ruler::Update(TimeTrack* timetrack)// Envelope *speedEnv, long minSpeed, lo Tick(0, mMin, true, false); Tick(mLength, mMax, true, false); } - } else { // log case @@ -1517,6 +1547,12 @@ void Ruler::Label::Draw(wxDC&dc, bool twoTone) const } } +void Ruler::SetUseZoomInfo(int leftOffset) +{ + mLeftOffset = leftOffset; + mUseZoomInfo = true; +} + // // RulerPanel // @@ -1620,8 +1656,8 @@ AdornedRulerPanel::AdornedRulerPanel(wxWindow* parent, SetName(GetLabel()); mLeftOffset = 0; - mCurPos = -1; - mIndPos = -1; + mCurTime = -1; + mIndTime = -1; mIndType = -1; mQuickPlayInd = false; mPlayRegionStart = -1; @@ -1644,6 +1680,7 @@ AdornedRulerPanel::AdornedRulerPanel(wxWindow* parent, mInner.width -= 2; // -2 for left and right bevels mInner.height -= 3; // -3 for top and bottom bevels and bottom line + ruler.SetUseZoomInfo(mLeftOffset); ruler.SetBounds( mInner.GetLeft(), mInner.GetTop(), mInner.GetRight(), @@ -1698,6 +1735,11 @@ void AdornedRulerPanel::UpdatePrefs() RegenerateTooltips(); } +void AdornedRulerPanel::InvalidateRuler() +{ + ruler.Invalidate(); +} + void AdornedRulerPanel::RegenerateTooltips() { #if wxUSE_TOOLTIPS @@ -2317,8 +2359,8 @@ void AdornedRulerPanel::DoDrawBorder(wxDC * dc) void AdornedRulerPanel::DoDrawMarks(wxDC * dc, bool /*text */ ) { - double min = mViewInfo->h - mLeftOffset / mViewInfo->zoom; - double max = min + mInner.width / mViewInfo->zoom; + const double min = Pos2Time(0); + const double max = Pos2Time(mInner.width); ruler.SetTickColour( theTheme.Colour( clrTrackPanelText ) ); ruler.SetRange( min, max ); @@ -2333,20 +2375,8 @@ void AdornedRulerPanel::DrawSelection() void AdornedRulerPanel::DoDrawSelection(wxDC * dc) { // Draw selection - double zoom = mViewInfo->zoom; - double sel0 = - mViewInfo->selectedRegion.t0() - mViewInfo->h + mLeftOffset / zoom; - double sel1 = - mViewInfo->selectedRegion.t1() - mViewInfo->h + mLeftOffset / zoom; - - if( sel0 < 0.0 ) - sel0 = 0.0; - - if( sel1 > ( mInner.width / zoom ) ) - sel1 = mInner.width / zoom; - - int p0 = int ( sel0 * zoom + 1.5 ); - int p1 = int ( sel1 * zoom + 2.5 ); + const int p0 = 1 + max(0, Time2Pos(mViewInfo->selectedRegion.t0())); + const int p1 = 2 + min(mInner.width, Time2Pos(mViewInfo->selectedRegion.t1())); dc->SetBrush( wxBrush( theTheme.Colour( clrRulerBackground )) ); dc->SetPen( wxPen( theTheme.Colour( clrRulerBackground )) ); @@ -2359,16 +2389,22 @@ void AdornedRulerPanel::DoDrawSelection(wxDC * dc) dc->DrawRectangle( r ); } -void AdornedRulerPanel::DrawCursor(double pos) +void AdornedRulerPanel::SetLeftOffset(int offset) { - mCurPos = pos; + mLeftOffset = offset; + ruler.SetUseZoomInfo(offset); +} + +void AdornedRulerPanel::DrawCursor(double time) +{ + mCurTime = time; Refresh(false); } void AdornedRulerPanel::DoDrawCursor(wxDC * dc) { - int x = mLeftOffset + int ( ( mCurPos - mViewInfo->h ) * mViewInfo->zoom ); + const int x = Time2Pos(mCurTime); // Draw cursor in ruler dc->DrawLine( x, 1, x, mInner.height ); @@ -2385,11 +2421,11 @@ void AdornedRulerPanel::ClearIndicator() Refresh(false); } -void AdornedRulerPanel::DrawIndicator( double pos, bool rec ) +void AdornedRulerPanel::DrawIndicator( double time, bool rec ) { - mIndPos = pos; + mIndTime = time; - if( mIndPos < 0 ) + if (mIndTime < 0) { ClearIndicator(); return; @@ -2408,7 +2444,7 @@ void AdornedRulerPanel::DoDrawIndicator(wxDC * dc) } int indsize = 6; - int x = mLeftOffset + int ( ( mIndPos - mViewInfo->h ) * mViewInfo->zoom ); + const int x = Time2Pos(mIndTime); wxPoint tri[ 3 ]; tri[ 0 ].x = x - indsize; @@ -2435,7 +2471,7 @@ void AdornedRulerPanel::DrawQuickPlayIndicator(wxDC * dc, bool clear) } int indsize = 4; - int x = mLeftOffset + int((mQuickPlayPos - mViewInfo->h) * mViewInfo->zoom); + int x = Time2Pos(mQuickPlayPos); wxPoint tri[3]; tri[0].x = -indsize; diff --git a/src/widgets/Ruler.h b/src/widgets/Ruler.h index 0e14cba94..5d52cda2b 100644 --- a/src/widgets/Ruler.h +++ b/src/widgets/Ruler.h @@ -114,6 +114,8 @@ class AUDACITY_DLL_API Ruler { void SetCustomMajorLabels(wxArrayString *label, int numLabel, int start, int step); void SetCustomMinorLabels(wxArrayString *label, int numLabel, int start, int step); + void SetUseZoomInfo(int leftOffset); + // // Drawing // @@ -130,8 +132,10 @@ class AUDACITY_DLL_API Ruler { void SetTickColour( const wxColour & colour) { mTickColour = colour; mPen.SetColour( colour );} - private: + // Force regeneration of labels at next draw time void Invalidate(); + + private: void Update(); void Update(TimeTrack* timetrack); void FindTickSizes(); @@ -213,6 +217,8 @@ private: int mGridLineLength; // end wxString mUnits; bool mTwoTone; + bool mUseZoomInfo; + int mLeftOffset; }; class AUDACITY_DLL_API RulerPanel : public wxPanel { @@ -262,10 +268,10 @@ public: public: static int GetRulerHeight() { return 28; } - void SetLeftOffset(int offset){ mLeftOffset = offset; } + void SetLeftOffset(int offset); - void DrawCursor(double pos); - void DrawIndicator(double pos, bool rec); + void DrawCursor(double time); + void DrawIndicator(double time, bool rec); void DrawSelection(); void ClearIndicator(); @@ -273,9 +279,11 @@ public: void ClearPlayRegion(); void GetPlayRegion(double* playRegionStart, double* playRegionEnd); - void SetProject(AudacityProject* project) {mProject = project;}; + void SetProject(AudacityProject* project) {mProject = project;} void GetMaxSize(wxCoord *width, wxCoord *height); + void InvalidateRuler(); + void UpdatePrefs(); void RegenerateTooltips(); @@ -313,10 +321,11 @@ private: int mLeftOffset; // Number of pixels before we hit the 'zero position'. - double mCurPos; + double mCurTime; - int mIndType; // -1 = No indicator, 0 = Play, 1 = Record - double mIndPos; + + int mIndType; // -1 = No indicator, 0 = Play, 1 = Record + double mIndTime; bool mQuickPlayInd; double mQuickPlayPos; SnapManager *mSnapManager; From c5754ee751b415eaaf244d8dc7ca4650a2dd41cf Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Tue, 9 Jun 2015 16:21:29 -0400 Subject: [PATCH 27/36] Remove Envelope::GetValueAtX --- src/Envelope.cpp | 8 -------- src/Envelope.h | 2 -- src/TrackPanel.cpp | 4 ++-- 3 files changed, 2 insertions(+), 12 deletions(-) diff --git a/src/Envelope.cpp b/src/Envelope.cpp index 18f84d190..e2eec3ffd 100644 --- a/src/Envelope.cpp +++ b/src/Envelope.cpp @@ -1026,14 +1026,6 @@ double Envelope::GetValue(double t) const return temp; } -// 'X' is in pixels and relative to track. -double Envelope::GetValueAtX(int x, const wxRect & r, double h, double pps) -{ - // Convert x to time. - double t = (x - r.x) / pps + h ;//-mOffset; - return GetValue(t); -} - /// @param Lo returns last index at or before this time. /// @param Hi returns first index after this time. void Envelope::BinarySearchForTime( int &Lo, int &Hi, double t ) const diff --git a/src/Envelope.h b/src/Envelope.h index 47c42375e..508c5c76d 100644 --- a/src/Envelope.h +++ b/src/Envelope.h @@ -151,8 +151,6 @@ class Envelope : public XMLTagHandler { // Accessors /** \brief Get envelope value at time t */ double GetValue(double t) const; - /** \brief Get envelope value at pixel X */ - double GetValueAtX(int x, const wxRect & r, double h, double pps); /** \brief Get many envelope points at once. * diff --git a/src/TrackPanel.cpp b/src/TrackPanel.cpp index 5ad6180d8..54dbad149 100644 --- a/src/TrackPanel.cpp +++ b/src/TrackPanel.cpp @@ -7008,8 +7008,8 @@ bool TrackPanel::HitTestEnvelope(Track *track, wxRect &r, wxMouseEvent & event) return false; // No envelope, not a hit, so return. // Get envelope point, range 0.0 to 1.0 - double envValue = envelope->GetValueAtX( - event.m_x, r, mViewInfo->h, mViewInfo->zoom ); + // Convert x to time. + const double envValue = envelope->GetValue(mViewInfo->PositionToTime(event.m_x, r.x)); float zoomMin, zoomMax; wavetrack->GetDisplayBounds(&zoomMin, &zoomMax); From a4482aa3afe84dd390cb9ecf455786a0c1f652e6 Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Thu, 11 Jun 2015 11:26:26 -0400 Subject: [PATCH 28/36] Stubs needed to eliminate remaining direct uses of ViewInfo::zoom ... ... and anticipate a problems fisheye will introduce with time ruler display and horizontal scrolling past zero. Will be used in waveform and spectrogram drawing, and in hit-test for sample editing. Those things will no longer make the assumption of uniform zoom level across the width of the screen, though that does remain true without the rest of the fisheye project. --- src/ViewInfo.cpp | 23 +++++++++++++++++++++-- src/ViewInfo.h | 43 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+), 2 deletions(-) diff --git a/src/ViewInfo.cpp b/src/ViewInfo.cpp index fbd4e8d46..f0f439a42 100644 --- a/src/ViewInfo.cpp +++ b/src/ViewInfo.cpp @@ -37,7 +37,8 @@ ZoomInfo::~ZoomInfo() /// the track as an additional parameter. double ZoomInfo::PositionToTime(wxInt64 position, wxInt64 origin - ) const + , bool // ignoreFisheye +) const { return h + (position - origin) / zoom; } @@ -46,7 +47,8 @@ double ZoomInfo::PositionToTime(wxInt64 position, /// STM: Converts a project time to screen x position. wxInt64 ZoomInfo::TimeToPosition(double projectTime, wxInt64 origin - ) const + , bool // ignoreFisheye +) const { return floor(0.5 + zoom * (projectTime - h) + origin @@ -73,6 +75,23 @@ void ZoomInfo::ZoomBy(double multiplier) SetZoom(zoom * multiplier); } +void ZoomInfo::FindIntervals + (double /*rate*/, Intervals &results, wxInt64 origin) const +{ + results.clear(); + results.reserve(2); + + const wxInt64 rightmost(origin + (0.5 + screen * zoom)); + wxASSERT(origin <= rightmost); + { + results.push_back(Interval(origin, zoom, false)); + } + + if (origin < rightmost) + results.push_back(Interval(rightmost, 0, false)); + wxASSERT(!results.empty() && results[0].position == origin); +} + ViewInfo::ViewInfo(double start, double screenDuration, double pixelsPerSecond) : ZoomInfo(start, screenDuration, pixelsPerSecond) , selectedRegion() diff --git a/src/ViewInfo.h b/src/ViewInfo.h index b9bffac91..0d769cd48 100644 --- a/src/ViewInfo.h +++ b/src/ViewInfo.h @@ -11,6 +11,7 @@ #ifndef __AUDACITY_VIEWINFO__ #define __AUDACITY_VIEWINFO__ +#include #include "SelectedRegion.h" @@ -41,6 +42,7 @@ public: // origin specifies the pixel corresponding to time h double PositionToTime(wxInt64 position, wxInt64 origin = 0 + , bool ignoreFisheye = false ) const; // do NOT use this once to convert a duration to a pixel width! @@ -49,6 +51,7 @@ public: // origin specifies the pixel corresponding to time h wxInt64 TimeToPosition(double time, wxInt64 origin = 0 + , bool ignoreFisheye = false ) const; double OffsetTimeByPixels(double time, wxInt64 offset) const @@ -78,6 +81,46 @@ public: // Limits zoom to certain bounds // multipliers above 1.0 zoom in, below out void ZoomBy(double multiplier); + + struct Interval { + const wxInt64 position; const double averageZoom; const bool inFisheye; + Interval(wxInt64 p, double z, bool i) + : position(p), averageZoom(z), inFisheye(i) {} + }; + typedef std::vector Intervals; + + // Find an increasing sequence of pixel positions. Each is the start + // of an interval, or is the end position. + // Each of the disjoint intervals should be drawn + // separately. + // It is guaranteed that there is at least one entry and the position of the + // first entry equals origin. + // @param origin specifies the pixel position corresponding to time ViewInfo::h. + void FindIntervals + (double rate, Intervals &results, wxInt64 origin = 0) const; + + enum FisheyeState { + HIDDEN, + PINNED, + + NUM_STATES, + }; + FisheyeState GetFisheyeState() const + { return HIDDEN; } // stub + + // Return true if the mouse position is anywhere in the fisheye + // origin specifies the pixel corresponding to time h + bool InFisheye(wxInt64 position, wxInt64 origin = 0) const + {origin; return false;} // stub + + // These accessors ignore the fisheye hiding state. + // Inclusive: + wxInt64 GetFisheyeLeftBoundary(wxInt64 origin = 0) const + {origin; return 0;} // stub + // Exclusive: + wxInt64 GetFisheyeRightBoundary(wxInt64 origin = 0) const + {origin; return 0;} // stub + }; class AUDACITY_DLL_API ViewInfo From 79e9f2b5dd8dfe19e21381c3c879138975ad3081 Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Thu, 11 Jun 2015 13:34:23 -0400 Subject: [PATCH 29/36] Scrolling left of zero will work right with fisheye present. --- src/Project.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Project.cpp b/src/Project.cpp index b0d851db3..f77e89872 100644 --- a/src/Project.cpp +++ b/src/Project.cpp @@ -1456,8 +1456,10 @@ wxInt64 AudacityProject::PixelWidthBeforeTime(double scrollto) const const double lowerBound = ScrollingLowerBoundTime(); return mViewInfo.TimeToPosition(scrollto, 0 + , true ) - mViewInfo.TimeToPosition(lowerBound, 0 + , true ); } From e3a03ff07ed534f6f67c2e1caa43bf6f46e20894 Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Tue, 9 Jun 2015 19:46:03 -0400 Subject: [PATCH 30/36] Tick size on the time ruler will not jump when fisheye approaches ends --- src/widgets/Ruler.cpp | 43 +++++++++++++++++++++++++++++++++---------- src/widgets/Ruler.h | 12 ++++++++++-- 2 files changed, 43 insertions(+), 12 deletions(-) diff --git a/src/widgets/Ruler.cpp b/src/widgets/Ruler.cpp index 49ce486f3..994e15fe8 100644 --- a/src/widgets/Ruler.cpp +++ b/src/widgets/Ruler.cpp @@ -98,8 +98,8 @@ using std::max; Ruler::Ruler() { - mMin = 0.0; - mMax = 100.0; + mMin = mHiddenMin = 0.0; + mMax = mHiddenMax = 100.0; mOrientation = wxHORIZONTAL; mSpacing = 6; mHasSetSpacing = false; @@ -233,14 +233,27 @@ void Ruler::SetOrientation(int orient) } void Ruler::SetRange(double min, double max) +{ + SetRange(min, max, min, max); +} + +void Ruler::SetRange + (double min, double max, double hiddenMin, double hiddenMax) { // For a horizontal ruler, // min is the value in the center of pixel "left", // max is the value in the center of pixel "right". - if (mMin != min || mMax != max) { + // In the special case of a time ruler, + // hiddenMin and hiddenMax are values that would be shown with the fisheye + // turned off. In other cases they equal min and max respectively. + + if (mMin != min || mMax != max || + mHiddenMin != hiddenMin || mHiddenMax != hiddenMax) { mMin = min; mMax = max; + mHiddenMin = hiddenMin; + mHiddenMax = hiddenMax; Invalidate(); } @@ -1070,7 +1083,11 @@ void Ruler::Update(TimeTrack* timetrack)// Envelope *speedEnv, long minSpeed, lo } else if(mLog==false) { - double UPP = (mMax-mMin)/mLength; // Units per pixel + // Use the "hidden" min and max to determine the tick size. + // That may make a difference with fisheye. + // Otherwise you may see the tick size for the whole ruler change + // when the fisheye approaches start or end. + double UPP = (mHiddenMax-mHiddenMin)/mLength; // Units per pixel FindLinearTickSizes(UPP); // Left and Right Edges @@ -1148,7 +1165,7 @@ void Ruler::Update(TimeTrack* timetrack)// Envelope *speedEnv, long minSpeed, lo } else { // log case - mDigits=2; //TODO: implement dynamic digit computation + mDigits=2; //TODO: implement dynamic digit computation double loLog = log10(mMin); double hiLog = log10(mMax); double scale = mLength/(hiLog - loLog); @@ -1843,14 +1860,18 @@ void AdornedRulerPanel::OnSize(wxSizeEvent & WXUNUSED(evt)) Refresh( false ); } -double AdornedRulerPanel::Pos2Time(int p) +double AdornedRulerPanel::Pos2Time(int p, bool ignoreFisheye) { - return mViewInfo->PositionToTime(p, mLeftOffset); + return mViewInfo->PositionToTime(p, mLeftOffset + , ignoreFisheye + ); } -int AdornedRulerPanel::Time2Pos(double t) +int AdornedRulerPanel::Time2Pos(double t, bool ignoreFisheye) { - return mViewInfo->TimeToPosition(t, mLeftOffset); + return mViewInfo->TimeToPosition(t, mLeftOffset + , ignoreFisheye + ); } @@ -2360,10 +2381,12 @@ void AdornedRulerPanel::DoDrawBorder(wxDC * dc) void AdornedRulerPanel::DoDrawMarks(wxDC * dc, bool /*text */ ) { const double min = Pos2Time(0); + const double hiddenMin = Pos2Time(0, true); const double max = Pos2Time(mInner.width); + const double hiddenMax = Pos2Time(mInner.width, true); ruler.SetTickColour( theTheme.Colour( clrTrackPanelText ) ); - ruler.SetRange( min, max ); + ruler.SetRange( min, max, hiddenMin, hiddenMax ); ruler.Draw( *dc ); } diff --git a/src/widgets/Ruler.h b/src/widgets/Ruler.h index 5d52cda2b..935659e81 100644 --- a/src/widgets/Ruler.h +++ b/src/widgets/Ruler.h @@ -56,6 +56,13 @@ class AUDACITY_DLL_API Ruler { // (at the center of the pixel, in both cases) void SetRange(double min, double max); + // An overload needed for the special case of fisheye + // min is the value at (x, y) + // max is the value at (x+width, y+height) + // hiddenMin, hiddenMax are the values that would be shown without the fisheye. + // (at the center of the pixel, in both cases) + void SetRange(double min, double max, double hiddenMin, double hiddenMax); + // // Optional Ruler Parameters // @@ -167,6 +174,7 @@ private: bool mUserFonts; double mMin, mMax; + double mHiddenMin, mHiddenMax; double mMajor; double mMinor; @@ -305,8 +313,8 @@ private: void DrawQuickPlayIndicator(wxDC * dc, bool clear /*delete old only*/); void DoDrawPlayRegion(wxDC * dc); - double Pos2Time(int p); - int Time2Pos(double t); + double Pos2Time(int p, bool ignoreFisheye = false); + int Time2Pos(double t, bool ignoreFisheye = false); bool IsWithinMarker(int mousePosX, double markerTime); From 57e0ce56ed583e18cede5dd3d5276feeabb6e229 Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Thu, 11 Jun 2015 11:01:09 -0400 Subject: [PATCH 31/36] Draw tool does not assume editing is allowed all-or-none across the whole screen --- src/TrackPanel.cpp | 47 ++++++++++++++++++++++++++++++++++------------ 1 file changed, 35 insertions(+), 12 deletions(-) diff --git a/src/TrackPanel.cpp b/src/TrackPanel.cpp index 54dbad149..6ef30d837 100644 --- a/src/TrackPanel.cpp +++ b/src/TrackPanel.cpp @@ -4927,10 +4927,31 @@ void TrackPanel::HandleVZoomButtonUp( wxMouseEvent & event ) MakeParentModifyState(true); } +namespace { +// Is the sample horizontally nearest to the cursor sufficiently separated from +// its neighbors that the pencil tool should be allowed to drag it? +bool SampleResolutionTest(const ViewInfo &viewInfo, const WaveTrack *wt, double time, double rate) +{ + // Require more than 3 pixels per sample + // Round to an exact sample time + const double adjustedTime = wt->LongSamplesToTime(wt->TimeToLongSamples(time)); + const wxInt64 xx = std::max(wxInt64(0), viewInfo.TimeToPosition(adjustedTime)); + ZoomInfo::Intervals intervals; + viewInfo.FindIntervals(rate, intervals); + ZoomInfo::Intervals::const_iterator it = intervals.begin(), end = intervals.end(), prev; + wxASSERT(it != end && it->position == 0); + do + prev = it++; + while (it != end && it->position <= xx); + const double threshold = 3 * rate; // three times as many pixels per second, as samples + return prev->averageZoom > threshold; +} +} + /// Determines if we can edit samples in a wave track. /// Also pops up warning messages in certain cases where we can't. /// @return true if we can edit the samples, false otherwise. -bool TrackPanel::IsSampleEditingPossible( wxMouseEvent & WXUNUSED(event), Track * t ) +bool TrackPanel::IsSampleEditingPossible( wxMouseEvent &event, Track * t ) { //Exit if we don't have a track if(!t) @@ -4959,10 +4980,15 @@ bool TrackPanel::IsSampleEditingPossible( wxMouseEvent & WXUNUSED(event), Track } #endif - //Get rate in order to calculate the critical zoom threshold - //Find out the zoom level - const double rate = wt->GetRate(); - const bool showPoints = (mViewInfo->zoom / rate > 3.0); + bool showPoints; + { + wxRect r; + FindTrack(event.m_x, event.m_y, false, false, &r); + WaveTrack *const wt = static_cast(t); + const double rate = wt->GetRate(); + const double time = mViewInfo->PositionToTime(event.m_x, r.x); + showPoints = SampleResolutionTest(*mViewInfo, wt, time, rate); + } //If we aren't zoomed in far enough, show a message dialog. if(!showPoints) @@ -7065,21 +7091,18 @@ bool TrackPanel::HitTestSamples(Track *track, wxRect &r, wxMouseEvent & event) //Get rate in order to calculate the critical zoom threshold double rate = wavetrack->GetRate(); - //Find out the zoom level - bool showPoints = (mViewInfo->zoom / rate > 3.0); - if( !showPoints ) - return false; - int displayType = wavetrack->GetDisplay(); bool dB = (WaveTrack::WaveformDBDisplay == displayType); if (!(WaveTrack::WaveformDisplay == displayType || dB)) return false; // Not a wave, so return. - float oneSample; const double tt = mViewInfo->PositionToTime(event.m_x, r.x); - sampleCount s0 = (sampleCount)(tt * rate + 0.5); + if (!SampleResolutionTest(*mViewInfo, wavetrack, tt, rate)) + return false; // Just get one sample. + float oneSample; + sampleCount s0 = (sampleCount)(tt * rate + 0.5); wavetrack->Get((samplePtr)&oneSample, floatSample, s0, 1); // Get y distance of envelope point from center line (in pixels). From c02652b3ab4d47890ca4df4a5d0c5de949173ce8 Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Tue, 9 Jun 2015 16:48:42 -0400 Subject: [PATCH 32/36] rest of fisheye drawing code... And finally, make ZoomInfo::zoom protected! --- src/TrackArtist.cpp | 441 ++++++++++++++++++++++++++++++++------------ src/ViewInfo.h | 2 + 2 files changed, 322 insertions(+), 121 deletions(-) diff --git a/src/TrackArtist.cpp b/src/TrackArtist.cpp index cecb2b137..78422e7f5 100644 --- a/src/TrackArtist.cpp +++ b/src/TrackArtist.cpp @@ -1475,13 +1475,15 @@ struct ClipParameters (bool spectrum, const WaveTrack *track, const WaveClip *clip, const wxRect &rect, const SelectedRegion &selectedRegion, const ZoomInfo &zoomInfo) { - selectedRegion; - tOffset = clip->GetOffset(); rate = clip->GetRate(); - h = zoomInfo.h; //The horizontal position in seconds - pps = zoomInfo.zoom; //points-per-second--the zoom level + h = zoomInfo.PositionToTime(0, 0 + , true + ); + h1 = zoomInfo.PositionToTime(rect.width, 0 + , true + ); double sel0 = selectedRegion.t0(); //left selection bound double sel1 = selectedRegion.t1(); //right selection bound @@ -1494,18 +1496,17 @@ struct ClipParameters const double trackLen = clip->GetEndTime() - clip->GetStartTime(); - tstep = 1.0 / pps; // Seconds per point tpre = h - tOffset; // offset corrected time of // left edge of display - tpost = tpre + (rect.width * tstep); // offset corrected time of + tpost = h1 - tOffset; // offset corrected time of // right edge of display const double sps = 1. / rate; //seconds-per-sample // Determine whether we should show individual samples // or draw circular points as well - showIndividualSamples = (pps / rate > 0.5); //zoomed in a lot - showPoints = (pps / rate > 3.0); //zoomed in even more + averagePixelsPerSample = rect.width / (rate * (h1 - h)); + showIndividualSamples = averagePixelsPerSample > 0.5; // Calculate actual selection bounds so that t0 > 0 and t1 < the // end of the track @@ -1514,7 +1515,7 @@ struct ClipParameters if (showIndividualSamples) { // adjustment so that the last circular point doesn't appear // to be hanging off the end - t1 += 2. / pps; + t1 += 2. / (averagePixelsPerSample * rate); } // Make sure t1 (the right bound) is greater than 0 @@ -1542,50 +1543,76 @@ struct ClipParameters ssel1 = (sampleCount)(0.5 + trackLen * rate); } - // The variable "mid" will be the rectangle containing the + // The variable "hiddenMid" will be the rectangle containing the // actual waveform, as opposed to any blank area before - // or after the track. - mid = rect; + // or after the track, as it would appear without the fisheye. + hiddenMid = rect; // If the left edge of the track is to the right of the left // edge of the display, then there's some blank area to the - // left of the track. Reduce the "mid" - // rect by size of the blank area. + // left of the track. Reduce the "hiddenMid" + hiddenLeftOffset = 0; if (tpre < 0) { - // Fill in the area to the left of the track - double delta = rect.width; - if (t0 < tpost) { - delta = (int)((t0 - tpre) * pps); - } - - // Offset the rectangle containing the waveform by the width - // of the area we just erased. - mid.x += (int)delta; - mid.width -= (int)delta; + hiddenLeftOffset = std::min(rect.width, int( + zoomInfo.TimeToPosition(tOffset, 0 + , true + ) + )); + hiddenMid.x += hiddenLeftOffset; + hiddenMid.width -= hiddenLeftOffset; } // If the right edge of the track is to the left of the the right // edge of the display, then there's some blank area to the right - // of the track. Reduce the "mid" rect by the + // of the track. Reduce the "hiddenMid" rect by the // size of the blank area. if (tpost > t1) { - wxRect post = rect; - if (t1 > tpre) { - post.x += (int)((t1 - tpre) * pps); - } - post.width = rect.width - (post.x - rect.x); - // Reduce the rectangle containing the waveform by the width - // of the area we just erased. - mid.width -= post.width; + const int hiddenRightOffset = std::min(rect.width, int( + zoomInfo.TimeToPosition(tOffset + t1, 0 + , true + ) + )); + hiddenMid.width = std::max(0, hiddenRightOffset - hiddenLeftOffset); + } + + // The variable "mid" will be the rectangle containing the + // actual waveform, as distorted by the fisheye, + // as opposed to any blank area before or after the track. + mid = rect; + + // If the left edge of the track is to the right of the left + // edge of the display, then there's some blank area to the + // left of the track. Reduce the "hiddenMid" + leftOffset = 0; + if (tpre < 0) { + leftOffset = std::min(rect.width, int( + zoomInfo.TimeToPosition(tOffset, 0 + , false + ) + )); + mid.x += leftOffset; + mid.width -= leftOffset; + } + + // If the right edge of the track is to the left of the the right + // edge of the display, then there's some blank area to the right + // of the track. Reduce the "hiddenMid" rect by the + // size of the blank area. + if (tpost > t1) { + const int distortedRightOffset = std::min(rect.width, int( + zoomInfo.TimeToPosition(tOffset + t1, 0 + , false + ) + )); + mid.width = std::max(0, distortedRightOffset - leftOffset); } } double tOffset; double rate; double h; // absolute time of left edge of display - double tstep; double tpre; // offset corrected time of left edge of display - // double h1; + double h1; double tpost; // offset corrected time of right edge of display // Calculate actual selection bounds so that t0 > 0 and t1 < the @@ -1593,16 +1620,61 @@ struct ClipParameters double t0; double t1; - double pps; - bool showIndividualSamples, showPoints; + double averagePixelsPerSample; + bool showIndividualSamples; sampleCount ssel0; sampleCount ssel1; + wxRect hiddenMid; + int hiddenLeftOffset; + wxRect mid; + int leftOffset; }; } +namespace { +struct WavePortion { + wxRect rect; + const double averageZoom; + const bool inFisheye; + WavePortion(int x, int y, int w, int h, double zoom, bool i) + : rect(x, y, w, h), averageZoom(zoom), inFisheye(i) + {} +}; + +void FindWavePortions + (std::vector &portions, const wxRect &rect, const ZoomInfo &zoomInfo, + const ClipParameters ¶ms) +{ + // If there is no fisheye, then only one rectangle has nonzero width. + // If there is a fisheye, make rectangles for before and after + // (except when they are squeezed to zero width), and at least one for inside + // the fisheye. + + ZoomInfo::Intervals intervals; + zoomInfo.FindIntervals(params.rate, intervals, rect.x); + ZoomInfo::Intervals::const_iterator it = intervals.begin(), end = intervals.end(), prev; + wxASSERT(it != end && it->position == rect.x); + const int rightmost = rect.x + rect.width; + for (int left = rect.x; left < rightmost;) { + while (it != end && it->position <= left) + prev = it++; + const int right = std::max(left, int( + it != end ? it->position : rightmost + )); + const int width = right - left; + if (width > 0) + portions.push_back( + WavePortion(left, rect.y, width, rect.height, + prev->averageZoom, prev->inFisheye) + ); + left = right; + } +} +} + void TrackArtist::DrawClipWaveform(WaveTrack *track, WaveClip *clip, wxDC & dc, @@ -1619,88 +1691,171 @@ void TrackArtist::DrawClipWaveform(WaveTrack *track, #endif const ClipParameters params(false, track, clip, rect, selectedRegion, zoomInfo); - const wxRect &mid = params.mid; - // The "mid" rect contains the part of the display actually - // containing the waveform. If it's empty, we're done. - if (mid.width <= 0) { + const wxRect &hiddenMid = params.hiddenMid; + // The "hiddenMid" rect contains the part of the display actually + // containing the waveform, as it appears without the fisheye. If it's empty, we're done. + if (hiddenMid.width <= 0) { return; } const double &t0 = params.t0; - const double &pps = params.pps; const double &tOffset = params.tOffset; - const double &tstep = params.tstep; - const bool &showIndividualSamples = params.showIndividualSamples; - const bool &showPoints = params.showPoints; const double &h = params.h; const double &tpre = params.tpre; const double &tpost = params.tpost; const double &t1 = params.t1; + const double &averagePixelsPerSample = params.averagePixelsPerSample; + const double &rate = params.rate; + double leftOffset = params.leftOffset; + const wxRect &mid = params.mid; - // Calculate sample-based offset-corrected selection dc.SetPen(*wxTRANSPARENT_PEN); // If we get to this point, the clip is actually visible on the // screen, so remember the display rectangle. - clip->SetDisplayRect(mid); + clip->SetDisplayRect(hiddenMid); // The bounds (controlled by vertical zooming; -1.0...1.0 // by default) float zoomMin, zoomMax; track->GetDisplayBounds(&zoomMin, &zoomMax); - // Get the values of the envelope corresponding to each pixel - // in the display, and use these to compute the height of the - // track at each pixel - - double *envValues = new double[mid.width]; - clip->GetEnvelope()->GetValues(envValues, mid.width, t0 + tOffset, tstep); + std::vector vEnv(mid.width); + double *const env = &vEnv[0]; + clip->GetEnvelope()->GetValues(env, mid.width, leftOffset, zoomInfo); // Draw the background of the track, outlining the shape of // the envelope and using a colored pen for the selected // part of the waveform - DrawWaveformBackground(dc, mid.x - rect.x, mid, - envValues, + DrawWaveformBackground(dc, leftOffset, mid, + env, zoomMin, zoomMax, dB, selectedRegion, zoomInfo, drawEnvelope, !track->GetSelected()); - if (!showIndividualSamples) { - WaveDisplay display(mid.width); - bool isLoadingOD = false;//true if loading on demand block in sequence. + WaveDisplay display(hiddenMid.width); + bool isLoadingOD = false;//true if loading on demand block in sequence. + const double pps = + averagePixelsPerSample * rate; + if (!params.showIndividualSamples) { // The WaveClip class handles the details of computing the shape // of the waveform. The only way GetWaveDisplay will fail is if // there's a serious error, like some of the waveform data can't // be loaded. So if the function returns false, we can just exit. + + // Note that we compute the full width display even if there is a + // fisheye hiding part of it, because of the caching. If the + // fisheye moves over the background, there is then less to do when + // redrawing. + if (!clip->GetWaveDisplay(display, - t0, pps, isLoadingOD)) { + t0, pps, isLoadingOD)) return; + } + + // For each portion separately, we will decide to draw + // it as min/max/rms or as individual samples. + std::vector portions; + FindWavePortions(portions, rect, zoomInfo, params); + const unsigned nPortions = portions.size(); + + // Require at least 1/2 pixel per sample for drawing individual samples. + const double threshold1 = 0.5 * rate; + // Require at least 3 pixels per sample for drawing the draggable points. + const double threshold2 = 3 * rate; + for (unsigned ii = 0; ii < nPortions; ++ii) { + WavePortion &portion = portions[ii]; + const bool showIndividualSamples = portion.averageZoom > threshold1; + const bool showPoints = portion.averageZoom > threshold2; + wxRect& rect = portion.rect; + rect.Intersect(mid); + wxASSERT(rect.width >= 0); + + float *useMin = 0, *useMax = 0, *useRms = 0; + int *useBl = 0; + WaveDisplay fisheyeDisplay(rect.width); + int skipped = 0, skippedLeft = 0, skippedRight = 0; + if (portion.inFisheye) { + if (!showIndividualSamples) { + fisheyeDisplay.Allocate(); + const sampleCount numSamples = clip->GetNumSamples(); + // Get wave display data for different magnification + int jj = 0; + for (; jj < rect.width; ++jj) { + const double time = + zoomInfo.PositionToTime(jj, -leftOffset) - tOffset; + const sampleCount sample = (sampleCount)floor(time * rate + 0.5); + if (sample < 0) { + ++rect.x; + ++skippedLeft; + continue; + } + if (sample >= numSamples) + break; + fisheyeDisplay.where[jj - skippedLeft] = sample; + } + + skippedRight = rect.width - jj; + skipped = skippedRight + skippedLeft; + rect.width -= skipped; + + // where needs a sentinel + if (jj > 0) + fisheyeDisplay.where[jj - skippedLeft] = + 1 + fisheyeDisplay.where[jj - skippedLeft - 1]; + fisheyeDisplay.width -= skipped; + // Get a wave display for the fisheye, uncached. + if (rect.width > 0) + if (!clip->GetWaveDisplay( + fisheyeDisplay, t0, -1.0, // ignored + isLoadingOD)) + continue; // serious error. just don't draw?? + useMin = fisheyeDisplay.min; + useMax = fisheyeDisplay.max; + useRms = fisheyeDisplay.rms; + useBl = fisheyeDisplay.bl; + } + } + else { + const int pos = leftOffset - params.hiddenLeftOffset; + useMin = display.min + pos; + useMax = display.max + pos; + useRms = display.rms + pos; + useBl = display.bl + pos; } - DrawMinMaxRMS(dc, mid, envValues, - zoomMin, zoomMax, dB, - display.min, display.max, display.rms, display.bl, - isLoadingOD, muted + leftOffset += skippedLeft; + + if (rect.width > 0) { + if (!showIndividualSamples) { + std::vector vEnv2(rect.width); + double *const env2 = &vEnv2[0]; + clip->GetEnvelope()->GetValues(env2, rect.width, leftOffset, zoomInfo); + DrawMinMaxRMS(dc, rect, env2, + zoomMin, zoomMax, dB, + useMin, useMax, useRms, useBl, + isLoadingOD, muted #ifdef EXPERIMENTAL_OUTPUT_DISPLAY - , track->GetChannelGain(track->GetChannel()) + , track->GetChannelGain(track->GetChannel()) #endif - ); - } - else { - DrawIndividualSamples(dc, mid.x - rect.x, mid, - zoomMin, zoomMax, dB, - clip, zoomInfo, bigPoints, showPoints, muted); + ); + } + else + DrawIndividualSamples(dc, leftOffset, rect, zoomMin, zoomMax, dB, + clip, zoomInfo, + bigPoints, showPoints, muted); + } + + leftOffset += rect.width + skippedRight; } if (drawEnvelope) { - DrawEnvelope(dc, mid, envValues, zoomMin, zoomMax, dB); + DrawEnvelope(dc, mid, env, zoomMin, zoomMax, dB); clip->GetEnvelope()->DrawPoints(dc, rect, zoomInfo, dB, zoomMin, zoomMax); } - delete[] envValues; - // Draw arrows on the left side if the track extends to the left of the // beginning of time. :) if (h == 0.0 && tOffset < 0.0) { @@ -1880,19 +2035,26 @@ void TrackArtist::DrawClipSpectrum(WaveTrackCache &waveTrackCache, enum { DASH_LENGTH = 10 /* pixels */ }; const ClipParameters params(true, track, clip, rect, selectedRegion, zoomInfo); - const wxRect &mid = params.mid; - // The "mid" rect contains the part of the display actually - // containing the waveform. If it's empty, we're done. - if (mid.width <= 0) { + const wxRect &hiddenMid = params.hiddenMid; + // The "hiddenMid" rect contains the part of the display actually + // containing the waveform, as it appears without the fisheye. If it's empty, we're done. + if (hiddenMid.width <= 0) { return; } const double &t0 = params.t0; - const double &pps = params.pps; - const double &tstep = params.tstep; + const double &tOffset = params.tOffset; const double &ssel0 = params.ssel0; const double &ssel1 = params.ssel1; + const double &averagePixelsPerSample = params.averagePixelsPerSample; const double &rate = params.rate; + const double &hiddenLeftOffset = params.hiddenLeftOffset; + const double &leftOffset = params.leftOffset; + const wxRect &mid = params.mid; + + // If we get to this point, the clip is actually visible on the + // screen, so remember the display rectangle. + clip->SetDisplayRect(hiddenMid); double freqLo = SelectedRegion::UndefinedFrequency; double freqHi = SelectedRegion::UndefinedFrequency; @@ -1923,19 +2085,23 @@ void TrackArtist::DrawClipSpectrum(WaveTrackCache &waveTrackCache, // and then paint this directly to our offscreen // bitmap. Note that this could be optimized even // more, but for now this is not bad. -dmazzoni - wxImage *image = new wxImage((int) mid.width, (int) mid.height); - if (!image)return; + wxImage *image = new wxImage((int)mid.width, (int)mid.height); + if (!image) + return; unsigned char *data = image->GetData(); const int half = GetSpectrumWindowSize(!autocorrelation) / 2; const double binUnit = rate / (2 * half); const float *freq = 0; const sampleCount *where = 0; + bool updated; + { + const double pps = averagePixelsPerSample * rate; + updated = clip->GetSpectrogram(waveTrackCache, freq, where, hiddenMid.width, + t0, pps, autocorrelation); + } - bool updated = clip->GetSpectrogram(waveTrackCache, freq, where, mid.width, - t0, pps, autocorrelation); - - int ifreq = lrint(rate/2); + int ifreq = lrint(rate / 2); int maxFreq; if (!logF) @@ -1990,7 +2156,8 @@ void TrackArtist::DrawClipSpectrum(WaveTrackCache &waveTrackCache, } #endif //EXPERIMENTAL_FFT_Y_GRID - if (!updated && clip->mSpecPxCache->valid && (clip->mSpecPxCache->len == mid.height * mid.width) + if (!updated && clip->mSpecPxCache->valid && + (clip->mSpecPxCache->len == hiddenMid.height * hiddenMid.width) && gain == clip->mSpecPxCache->gain && range == clip->mSpecPxCache->range && minFreq == clip->mSpecPxCache->minFreq @@ -2011,7 +2178,7 @@ void TrackArtist::DrawClipSpectrum(WaveTrackCache &waveTrackCache, else { // Update the spectrum pixel cache delete clip->mSpecPxCache; - clip->mSpecPxCache = new SpecPxCache(mid.width * mid.height); + clip->mSpecPxCache = new SpecPxCache(hiddenMid.width * hiddenMid.height); clip->mSpecPxCache->valid = true; clip->mSpecPxCache->gain = gain; clip->mSpecPxCache->range = range; @@ -2044,15 +2211,15 @@ void TrackArtist::DrawClipSpectrum(WaveTrackCache &waveTrackCache, int *indexes = new int[maxTableSize]; #endif //EXPERIMENTAL_FIND_NOTES - for (int xx = 0; xx < mid.width; ++xx) + for (int xx = 0; xx < hiddenMid.width; ++xx) { if (!logF) { - for (int yy = 0; yy < mid.height; ++yy) { + for (int yy = 0; yy < hiddenMid.height; ++yy) { float bin0 = float(yy) * binPerPx + minBin; float bin1 = float(yy + 1) * binPerPx + minBin; const float value = findValue (freq + half * xx, bin0, bin1, half, autocorrelation, gain, range); - clip->mSpecPxCache->values[xx * mid.height + yy] = value; + clip->mSpecPxCache->values[xx * hiddenMid.height + yy] = value; } } else { @@ -2099,7 +2266,7 @@ void TrackArtist::DrawClipSpectrum(WaveTrackCache &waveTrackCache, } // The f2pix helper macro converts a frequency into a pixel coordinate. -#define f2pix(f) (logf(f)-lmins)/(lmaxs-lmins)*mid.height +#define f2pix(f) (logf(f)-lmins)/(lmaxs-lmins)*hiddenMid.height // Possibly quantize the maxima frequencies and create the pixel block limits. for (int i=0; i < maximas; i++) { @@ -2122,8 +2289,8 @@ void TrackArtist::DrawClipSpectrum(WaveTrackCache &waveTrackCache, double yy2_base = exp(lmin) / binUnit; float yy2 = yy2_base; - double exp_scale_per_height = exp(scale / mid.height); - for (int yy = 0; yy < mid.height; ++yy) { + double exp_scale_per_height = exp(scale / hiddenMid.height); + for (int yy = 0; yy < hiddenMid.height; ++yy) { if (int(yy2) >= half) yy2=half-1; if (yy2<0) @@ -2167,13 +2334,12 @@ void TrackArtist::DrawClipSpectrum(WaveTrackCache &waveTrackCache, value = findValue (freq + half * xx, bin0, bin1, half, autocorrelation, gain, range); } - clip->mSpecPxCache->values[xx * mid.height + yy] = value; + clip->mSpecPxCache->values[xx * hiddenMid.height + yy] = value; yy2 = yy2_base; } // each yy } // is logF } // each xx - } // updating cache float selBinLo = freqLo / binUnit; @@ -2181,24 +2347,56 @@ void TrackArtist::DrawClipSpectrum(WaveTrackCache &waveTrackCache, float selBinCenter = ((freqLo < 0 || freqHi < 0) ? -1 : sqrt(freqLo * freqHi)) / binUnit; - sampleCount w1 = sampleCount(0.5 + rate * - t0 + sampleCount w1(0.5 + rate * + (zoomInfo.PositionToTime(0, -leftOffset) - tOffset) ); - for (int xx = 0; xx < mid.width; ++xx) + const bool hidden = (ZoomInfo::HIDDEN == zoomInfo.GetFisheyeState()); + const int begin = hidden + ? 0 + : std::max(0, int(zoomInfo.GetFisheyeLeftBoundary(-leftOffset))); + const int end = hidden + ? 0 + : std::min(mid.width, int(zoomInfo.GetFisheyeRightBoundary(-leftOffset))); + const int numPixels = std::max(0, end - begin); + const int zeroPaddingFactor = autocorrelation ? 1 : settings.zeroPaddingFactor; + SpecCache specCache + (numPixels, autocorrelation, -1, + t0, settings.windowType, + settings.windowSize, zeroPaddingFactor, settings.frequencyGain); + if (numPixels > 0) { + for (int ii = begin; ii < end; ++ii) { + const double time = zoomInfo.PositionToTime(ii, -leftOffset) - tOffset; + specCache.where[ii - begin] = sampleCount(0.5 + rate * time); + } + specCache.Populate + (settings, waveTrackCache, + 0, 0, numPixels, + clip->GetNumSamples(), + tOffset, rate, + autocorrelation); + } + + int correctedX = leftOffset - hiddenLeftOffset; + int fisheyeColumn = 0; + for (int xx = 0; xx < mid.width; ++xx, ++correctedX) { + const bool inFisheye = zoomInfo.InFisheye(xx, -leftOffset); + float *const uncached = + inFisheye ? &specCache.freq[(fisheyeColumn++) * half] : 0; + sampleCount w0 = w1; w1 = sampleCount(0.5 + rate * - (t0 + (xx+1) * tstep) + (zoomInfo.PositionToTime(xx + 1, -leftOffset) - tOffset) ); // TODO: The logF and non-logF case are very similar. // They should be merged and simplified. if (!logF) { - for (int yy = 0; yy < mid.height; ++yy) { - float bin0 = float (yy) * binPerPx + minBin; - float bin1 = float (yy + 1) * binPerPx + minBin; + for (int yy = 0; yy < hiddenMid.height; ++yy) { + float bin0 = float(yy) * binPerPx + minBin; + float bin1 = float(yy + 1) * binPerPx + minBin; // For spectral selection, determine what colour // set to use. We use a darker selection if @@ -2210,13 +2408,15 @@ void TrackArtist::DrawClipSpectrum(WaveTrackCache &waveTrackCache, if (ssel0 <= w0 && w1 < ssel1) { bool isSpectral = ((track->GetDisplay() == WaveTrack::SpectralSelectionDisplay) || - (track->GetDisplay() == WaveTrack::SpectralSelectionLogDisplay)); - selected = ChooseColorSet( bin0, bin1, selBinLo, selBinCenter, selBinHi, xx/DASH_LENGTH, isSpectral ); + (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 = - clip->mSpecPxCache->values[xx * mid.height + yy]; + const float value = uncached + ? findValue(uncached, bin0, bin1, half, autocorrelation, gain, range) + : clip->mSpecPxCache->values[correctedX * hiddenMid.height + yy]; GetColorGradient(value, selected, isGrayscale, &rv, &gv, &bv); int px = ((mid.height - 1 - yy) * mid.width + xx) * 3; data[px++] = rv; @@ -2228,8 +2428,8 @@ void TrackArtist::DrawClipSpectrum(WaveTrackCache &waveTrackCache, { double yy2_base=exp(lmin)/binUnit; float yy2 = yy2_base; - double exp_scale_per_height = exp(scale/mid.height); - for (int yy = 0; yy < mid.height; ++yy) { + double exp_scale_per_height = exp(scale / hiddenMid.height); + for (int yy = 0; yy < hiddenMid.height; ++yy) { if (int(yy2)>=half) yy2=half-1; if (yy2<0) @@ -2243,20 +2443,21 @@ void TrackArtist::DrawClipSpectrum(WaveTrackCache &waveTrackCache, yy3=0; float bin1 = float(yy3); - AColor::ColorGradientChoice selected = - AColor::ColorGradientUnselected; + 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/DASH_LENGTH, isSpectral ); + (track->GetDisplay() == WaveTrack::SpectralSelectionLogDisplay)); + selected = ChooseColorSet( + bin0, bin1, selBinLo, selBinCenter, selBinHi, + (xx + leftOffset - hiddenLeftOffset) / DASH_LENGTH, isSpectral); } - const float value = clip->mSpecPxCache->values[xx * mid.height + yy]; - yy2 = yy2_base; - unsigned char rv, gv, bv; + const float value = uncached + ? findValue(uncached, bin0, bin1, half, autocorrelation, gain, range) + : clip->mSpecPxCache->values[correctedX * hiddenMid.height + yy]; GetColorGradient(value, selected, isGrayscale, &rv, &gv, &bv); #ifdef EXPERIMENTAL_FFT_Y_GRID @@ -2271,13 +2472,11 @@ void TrackArtist::DrawClipSpectrum(WaveTrackCache &waveTrackCache, data[px++] = rv; data[px++] = gv; data[px] = bv; - } // each yy - } // logF - } // each xx - // If we get to this point, the clip is actually visible on the - // screen, so remember the display rectangle. - clip->SetDisplayRect(mid); + yy2 = yy2_base; + } + } + } wxBitmap converted = wxBitmap(*image); diff --git a/src/ViewInfo.h b/src/ViewInfo.h index 0d769cd48..03040a64f 100644 --- a/src/ViewInfo.h +++ b/src/ViewInfo.h @@ -32,6 +32,8 @@ public: double h; // h pos in secs double screen; // screen width in secs + +protected: double zoom; // pixels per second public: From e70f91c64e52f363a60c45034387d22ced2c75f5 Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Thu, 18 Jun 2015 10:24:36 -0400 Subject: [PATCH 33/36] Removed ShuttleGui.h from other headers --- src/AboutDialog.h | 2 +- src/AutoRecovery.cpp | 1 + src/BatchProcessDialog.cpp | 3 ++- src/BatchProcessDialog.h | 2 +- src/Benchmark.cpp | 3 ++- src/FreqWindow.cpp | 4 ++-- src/LabelDialog.cpp | 3 ++- src/TimerRecordDialog.cpp | 3 ++- src/TimerRecordDialog.h | 4 +++- src/TrackPanel.cpp | 1 + src/effects/Amplify.cpp | 4 ++-- src/effects/Amplify.h | 4 ++-- src/effects/AutoDuck.cpp | 4 ++-- src/effects/AutoDuck.h | 2 +- src/effects/BassTreble.cpp | 4 ++-- src/effects/BassTreble.h | 4 ++-- src/effects/ChangePitch.cpp | 5 +++-- src/effects/ChangePitch.h | 4 ++-- src/effects/ChangeSpeed.h | 3 ++- src/effects/ChangeTempo.h | 4 ++-- src/effects/ClickRemoval.cpp | 4 ++-- src/effects/ClickRemoval.h | 3 ++- src/effects/Compressor.cpp | 4 ++-- src/effects/Compressor.h | 3 +-- src/effects/Contrast.cpp | 5 +++-- src/effects/Contrast.h | 1 + src/effects/DtmfGen.cpp | 3 ++- src/effects/DtmfGen.h | 3 ++- src/effects/Echo.cpp | 4 ++-- src/effects/Echo.h | 4 ++-- src/effects/Effect.cpp | 3 ++- src/effects/Effect.h | 6 +++++- src/effects/FindClipping.cpp | 4 ++-- src/effects/Leveller.cpp | 4 ++-- src/effects/Leveller.h | 4 ++-- src/effects/Noise.cpp | 4 ++-- src/effects/Noise.h | 3 ++- src/effects/NoiseReduction.cpp | 1 + src/effects/Normalize.h | 3 ++- src/effects/Paulstretch.cpp | 4 ++-- src/effects/Paulstretch.h | 3 ++- src/effects/Phaser.cpp | 3 ++- src/effects/Phaser.h | 4 ++-- src/effects/Repeat.h | 4 ++-- src/effects/Reverb.cpp | 3 ++- src/effects/Reverb.h | 4 ++-- src/effects/ScienFilter.cpp | 3 ++- src/effects/ScienFilter.h | 4 +++- src/effects/Silence.cpp | 3 ++- src/effects/TimeScale.cpp | 4 +++- src/effects/TimeScale.h | 4 ++-- src/effects/ToneGen.cpp | 4 ++-- src/effects/ToneGen.h | 3 ++- src/effects/TruncSilence.cpp | 4 ++-- src/effects/TruncSilence.h | 4 ++-- src/effects/Wahwah.cpp | 4 ++-- src/effects/Wahwah.h | 4 ++-- src/effects/vamp/VampEffect.cpp | 1 + src/export/Export.cpp | 6 ++++-- src/export/ExportCL.cpp | 3 ++- src/export/ExportFLAC.cpp | 3 ++- src/export/ExportMP2.cpp | 3 ++- src/export/ExportMP3.cpp | 6 ++++-- src/export/ExportMultiple.cpp | 3 ++- src/export/ExportOGG.cpp | 3 ++- src/export/ExportPCM.cpp | 6 ++++-- src/prefs/BatchPrefs.h | 4 ++-- src/prefs/DevicePrefs.h | 6 +++--- src/prefs/DirectoriesPrefs.h | 6 +++--- src/prefs/EffectsPrefs.h | 6 +++--- src/prefs/ExtImportPrefs.h | 4 ++-- src/prefs/GUIPrefs.h | 6 +++--- src/prefs/ImportExportPrefs.h | 6 +++--- src/prefs/KeyConfigPrefs.h | 6 +++--- src/prefs/LibraryPrefs.h | 6 +++--- src/prefs/MidiIOPrefs.h | 5 +++-- src/prefs/ModulePrefs.h | 4 ++-- src/prefs/MousePrefs.h | 6 +++--- src/prefs/PlaybackPrefs.h | 6 +++--- src/prefs/PrefsDialog.cpp | 1 + src/prefs/ProjectsPrefs.h | 6 +++--- src/prefs/QualityPrefs.h | 6 +++--- src/prefs/RecordingPrefs.h | 6 +++--- src/prefs/SpectrumPrefs.h | 3 ++- src/prefs/ThemePrefs.h | 6 +++--- src/prefs/TracksPrefs.h | 6 +++--- src/prefs/WarningsPrefs.h | 6 +++--- src/toolbars/DeviceToolBar.cpp | 3 ++- src/widgets/Meter.cpp | 4 ++-- 89 files changed, 198 insertions(+), 150 deletions(-) diff --git a/src/AboutDialog.h b/src/AboutDialog.h index c9ab1169c..87093f14e 100644 --- a/src/AboutDialog.h +++ b/src/AboutDialog.h @@ -16,7 +16,7 @@ #include #include -#include "ShuttleGui.h" +class ShuttleGui; struct AboutDialogCreditItem { wxString description; diff --git a/src/AutoRecovery.cpp b/src/AutoRecovery.cpp index 29f434aa1..6b7976232 100644 --- a/src/AutoRecovery.cpp +++ b/src/AutoRecovery.cpp @@ -19,6 +19,7 @@ recover previous Audacity projects that were closed incorrectly. #include "AudacityApp.h" #include "FileNames.h" #include "blockfile/SimpleBlockFile.h" +#include "ShuttleGui.h" #include #include diff --git a/src/BatchProcessDialog.cpp b/src/BatchProcessDialog.cpp index 4b7beb32d..5700a9777 100644 --- a/src/BatchProcessDialog.cpp +++ b/src/BatchProcessDialog.cpp @@ -15,6 +15,7 @@ *//*******************************************************************/ #include "Audacity.h" +#include "BatchProcessDialog.h" #include #include @@ -32,9 +33,9 @@ #include #include +#include "ShuttleGui.h" #include "Prefs.h" #include "Project.h" -#include "BatchProcessDialog.h" #include "Internat.h" #include "commands/CommandManager.h" #include "effects/Effect.h" diff --git a/src/BatchProcessDialog.h b/src/BatchProcessDialog.h index a5146764c..1b00236eb 100644 --- a/src/BatchProcessDialog.h +++ b/src/BatchProcessDialog.h @@ -25,7 +25,6 @@ #include #include -#include "ShuttleGui.h" #include "BatchCommands.h" class wxWindow; @@ -37,6 +36,7 @@ class wxRadioButton; class wxListCtrl; class wxListEvent; class wxButton; +class ShuttleGui; class BatchProcessDialog:public wxDialog { public: diff --git a/src/Benchmark.cpp b/src/Benchmark.cpp index be4c1c39b..14e5ae4e2 100644 --- a/src/Benchmark.cpp +++ b/src/Benchmark.cpp @@ -16,6 +16,7 @@ of the BlockFile system. #include "Audacity.h" +#include "Benchmark.h" #include #include @@ -33,7 +34,7 @@ of the BlockFile system. #include #include -#include "Benchmark.h" +#include "ShuttleGui.h" #include "Project.h" #include "WaveTrack.h" #include "Sequence.h" diff --git a/src/FreqWindow.cpp b/src/FreqWindow.cpp index 0ad678476..b98cccfaf 100644 --- a/src/FreqWindow.cpp +++ b/src/FreqWindow.cpp @@ -41,6 +41,7 @@ and in the spectrogram spectral selection. #include "Audacity.h" +#include "FreqWindow.h" // For compilers that support precompilation, includes "wx/wx.h". #include @@ -70,8 +71,7 @@ and in the spectrogram spectral selection. #include -#include "FreqWindow.h" - +#include "ShuttleGui.h" #include "AColor.h" #include "FFT.h" #include "Internat.h" diff --git a/src/LabelDialog.cpp b/src/LabelDialog.cpp index c1979e899..590781693 100644 --- a/src/LabelDialog.cpp +++ b/src/LabelDialog.cpp @@ -14,6 +14,7 @@ *//*******************************************************************/ #include "Audacity.h" +#include "LabelDialog.h" #include #include @@ -29,8 +30,8 @@ #include #include +#include "ShuttleGui.h" #include "Internat.h" -#include "LabelDialog.h" #include "LabelTrack.h" #include "Prefs.h" #include "Project.h" diff --git a/src/TimerRecordDialog.cpp b/src/TimerRecordDialog.cpp index 1671a3b2e..1aa195420 100644 --- a/src/TimerRecordDialog.cpp +++ b/src/TimerRecordDialog.cpp @@ -19,6 +19,7 @@ *//*******************************************************************/ #include "Audacity.h" +#include "TimerRecordDialog.h" #include #include @@ -29,7 +30,7 @@ #include #include // #include #include +#include -#include "ShuttleGui.h" +class wxTimerEvent; class NumericTextCtrl; +class ShuttleGui; class TimerRecordDialog : public wxDialog { diff --git a/src/TrackPanel.cpp b/src/TrackPanel.cpp index 6ef30d837..05d36fa36 100644 --- a/src/TrackPanel.cpp +++ b/src/TrackPanel.cpp @@ -204,6 +204,7 @@ is time to refresh some aspect of the screen. #include "Prefs.h" #include "Project.h" #include "Snap.h" +#include "ShuttleGui.h" #include "Theme.h" #include "TimeTrack.h" #include "Track.h" diff --git a/src/effects/Amplify.cpp b/src/effects/Amplify.cpp index b807d6a34..ce9dea880 100644 --- a/src/effects/Amplify.cpp +++ b/src/effects/Amplify.cpp @@ -19,6 +19,7 @@ *//*******************************************************************/ #include "../Audacity.h" +#include "Amplify.h" #include #include @@ -32,11 +33,10 @@ #include #include +#include "../ShuttleGui.h" #include "../WaveTrack.h" #include "../widgets/valnum.h" -#include "Amplify.h" - enum { diff --git a/src/effects/Amplify.h b/src/effects/Amplify.h index 15b9b8e88..f4ef85d26 100644 --- a/src/effects/Amplify.h +++ b/src/effects/Amplify.h @@ -21,12 +21,12 @@ #include #include -#include "../ShuttleGui.h" - #include "Effect.h" #define AMPLIFY_PLUGIN_SYMBOL XO("Amplify") +class ShuttleGui; + class EffectAmplify : public Effect { public: diff --git a/src/effects/AutoDuck.cpp b/src/effects/AutoDuck.cpp index 7510d7b1e..a582c3800 100644 --- a/src/effects/AutoDuck.cpp +++ b/src/effects/AutoDuck.cpp @@ -14,6 +14,7 @@ *******************************************************************/ #include "../Audacity.h" +#include "AutoDuck.h" #include #include @@ -28,11 +29,10 @@ #include "../AllThemeResources.h" #include "../Internat.h" #include "../Prefs.h" +#include "../ShuttleGui.h" #include "../Theme.h" #include "../widgets/valnum.h" -#include "AutoDuck.h" - // Define keys, defaults, minimums, and maximums for the effect parameters // // Name Type Key Def Min Max Scale diff --git a/src/effects/AutoDuck.h b/src/effects/AutoDuck.h index b36f4ee9b..45a8878d1 100644 --- a/src/effects/AutoDuck.h +++ b/src/effects/AutoDuck.h @@ -19,12 +19,12 @@ #include #include -#include "../ShuttleGui.h" #include "../WaveTrack.h" #include "Effect.h" class EffectAutoDuckPanel; +class ShuttleGui; #define AUTO_DUCK_PANEL_NUM_CONTROL_POINTS 5 diff --git a/src/effects/BassTreble.cpp b/src/effects/BassTreble.cpp index 1ff376016..131cc153c 100644 --- a/src/effects/BassTreble.cpp +++ b/src/effects/BassTreble.cpp @@ -19,6 +19,7 @@ *//*******************************************************************/ #include "../Audacity.h" +#include "BassTreble.h" #include @@ -28,11 +29,10 @@ #include #include "../Prefs.h" +#include "../ShuttleGui.h" #include "../WaveTrack.h" #include "../widgets/valnum.h" -#include "BassTreble.h" - enum { ID_Bass = 10000, diff --git a/src/effects/BassTreble.h b/src/effects/BassTreble.h index fa328d6c7..f5dc9f814 100644 --- a/src/effects/BassTreble.h +++ b/src/effects/BassTreble.h @@ -19,10 +19,10 @@ #include #include -#include "../ShuttleGui.h" - #include "Effect.h" +class ShuttleGui; + #define BASSTREBLE_PLUGIN_SYMBOL XO("Bass and Treble") class EffectBassTreble : public Effect diff --git a/src/effects/ChangePitch.cpp b/src/effects/ChangePitch.cpp index ce3ad7c81..669b4273a 100644 --- a/src/effects/ChangePitch.cpp +++ b/src/effects/ChangePitch.cpp @@ -19,6 +19,8 @@ the pitch without changing the tempo. #if USE_SOUNDTOUCH +#include "ChangePitch.h" + #include #include @@ -26,13 +28,12 @@ the pitch without changing the tempo. #include #include "../PitchName.h" +#include "../ShuttleGui.h" #include "../Spectrum.h" #include "../WaveTrack.h" #include "../widgets/valnum.h" #include "TimeWarper.h" -#include "ChangePitch.h" - enum { ID_PercentChange = 10000, ID_FromPitch, diff --git a/src/effects/ChangePitch.h b/src/effects/ChangePitch.h index 5accb4545..236f5e420 100644 --- a/src/effects/ChangePitch.h +++ b/src/effects/ChangePitch.h @@ -27,10 +27,10 @@ the pitch without changing the tempo. #include #include -#include "../ShuttleGui.h" - #include "SoundTouchEffect.h" +class ShuttleGui; + #define CHANGEPITCH_PLUGIN_SYMBOL XO("Change Pitch") class EffectChangePitch : public EffectSoundTouch diff --git a/src/effects/ChangeSpeed.h b/src/effects/ChangeSpeed.h index 3f449c23b..67a6c912b 100644 --- a/src/effects/ChangeSpeed.h +++ b/src/effects/ChangeSpeed.h @@ -19,13 +19,14 @@ #include #include -#include "../ShuttleGui.h" #include "../Track.h" #include "../WaveTrack.h" #include "../widgets/NumericTextCtrl.h" #include "Effect.h" +class ShuttleGui; + #define CHANGESPEED_PLUGIN_SYMBOL XO("Change Speed") class EffectChangeSpeed : public Effect diff --git a/src/effects/ChangeTempo.h b/src/effects/ChangeTempo.h index 023154e4c..d20b98dfd 100644 --- a/src/effects/ChangeTempo.h +++ b/src/effects/ChangeTempo.h @@ -21,10 +21,10 @@ #include #include -#include "../ShuttleGui.h" - #include "SoundTouchEffect.h" +class ShuttleGui; + #define CHANGETEMPO_PLUGIN_SYMBOL XO("Change Tempo") class EffectChangeTempo : public EffectSoundTouch diff --git a/src/effects/ClickRemoval.cpp b/src/effects/ClickRemoval.cpp index 6b164dafa..81e616f65 100644 --- a/src/effects/ClickRemoval.cpp +++ b/src/effects/ClickRemoval.cpp @@ -25,6 +25,7 @@ *//*******************************************************************/ #include "../Audacity.h" +#include "ClickRemoval.h" #include @@ -33,10 +34,9 @@ #include #include "../Prefs.h" +#include "../ShuttleGui.h" #include "../widgets/valnum.h" -#include "ClickRemoval.h" - enum { ID_Thresh = 10000, diff --git a/src/effects/ClickRemoval.h b/src/effects/ClickRemoval.h index 7066a72d4..5723f09d5 100644 --- a/src/effects/ClickRemoval.h +++ b/src/effects/ClickRemoval.h @@ -22,11 +22,12 @@ #include #include "../Envelope.h" -#include "../ShuttleGui.h" #include "../WaveTrack.h" #include "Effect.h" +class ShuttleGui; + #define CLICKREMOVAL_PLUGIN_SYMBOL XO("Click Removal") class EffectClickRemoval : public Effect diff --git a/src/effects/Compressor.cpp b/src/effects/Compressor.cpp index bff3e71e4..0d8e8752e 100644 --- a/src/effects/Compressor.cpp +++ b/src/effects/Compressor.cpp @@ -25,6 +25,7 @@ *//*******************************************************************/ #include "../Audacity.h" +#include "Compressor.h" #include @@ -36,11 +37,10 @@ #include "../AColor.h" #include "../Prefs.h" +#include "../ShuttleGui.h" #include "../float_cast.h" #include "../widgets/Ruler.h" -#include "Compressor.h" - enum { ID_Threshold = 10000, diff --git a/src/effects/Compressor.h b/src/effects/Compressor.h index 72944476b..43fa457c5 100644 --- a/src/effects/Compressor.h +++ b/src/effects/Compressor.h @@ -21,11 +21,10 @@ #include #include -#include "../ShuttleGui.h" - #include "TwoPassSimpleMono.h" class EffectCompressorPanel; +class ShuttleGui; #define COMPRESSOR_PLUGIN_SYMBOL XO("Compressor") diff --git a/src/effects/Contrast.cpp b/src/effects/Contrast.cpp index ab55f324e..3d9ffacc3 100644 --- a/src/effects/Contrast.cpp +++ b/src/effects/Contrast.cpp @@ -10,15 +10,16 @@ *//*******************************************************************/ #include "../Audacity.h" -#include "../AudacityApp.h" - #include "Contrast.h" +#include "../AudacityApp.h" + #include "../Envelope.h" #include "../FFT.h" #include "../WaveTrack.h" #include "../Prefs.h" #include "../Project.h" +#include "../ShuttleGui.h" #include "../FileNames.h" #include "../widgets/LinkingHtmlWindow.h" #include "../widgets/HelpSystem.h" diff --git a/src/effects/Contrast.h b/src/effects/Contrast.h index 456e2faa1..9f143d276 100644 --- a/src/effects/Contrast.h +++ b/src/effects/Contrast.h @@ -15,6 +15,7 @@ class wxButton; class wxSizer; class wxString; +class wxTextCtrl; class Envelope; class NumericTextCtrl; diff --git a/src/effects/DtmfGen.cpp b/src/effects/DtmfGen.cpp index 98b9de60f..893126281 100644 --- a/src/effects/DtmfGen.cpp +++ b/src/effects/DtmfGen.cpp @@ -14,15 +14,16 @@ *//*******************************************************************/ #include "../Audacity.h" +#include "DtmfGen.h" #include #include #include #include "../Prefs.h" +#include "../ShuttleGui.h" #include "../widgets/valnum.h" -#include "DtmfGen.h" enum { diff --git a/src/effects/DtmfGen.h b/src/effects/DtmfGen.h index 0010a973d..a8c259e53 100644 --- a/src/effects/DtmfGen.h +++ b/src/effects/DtmfGen.h @@ -19,11 +19,12 @@ #include #include -#include "../ShuttleGui.h" #include "../widgets/NumericTextCtrl.h" #include "Effect.h" +class ShuttleGui; + #define DTMFTONES_PLUGIN_SYMBOL XO("DTMF Tones") class EffectDtmf : public Effect diff --git a/src/effects/Echo.cpp b/src/effects/Echo.cpp index b956a4252..8a5fd7248 100644 --- a/src/effects/Echo.cpp +++ b/src/effects/Echo.cpp @@ -20,15 +20,15 @@ *//*******************************************************************/ #include "../Audacity.h" +#include "Echo.h" #include #include +#include "../ShuttleGui.h" #include "../widgets/valnum.h" -#include "Echo.h" - // Define keys, defaults, minimums, and maximums for the effect parameters // // Name Type Key Def Min Max Scale diff --git a/src/effects/Echo.h b/src/effects/Echo.h index 40e38ded2..652453ad0 100644 --- a/src/effects/Echo.h +++ b/src/effects/Echo.h @@ -16,10 +16,10 @@ #include #include -#include "../ShuttleGui.h" - #include "Effect.h" +class ShuttleGui; + #define ECHO_PLUGIN_SYMBOL XO("Echo") class EffectEcho : public Effect diff --git a/src/effects/Effect.cpp b/src/effects/Effect.cpp index a1dd1f2b0..73d873e80 100644 --- a/src/effects/Effect.cpp +++ b/src/effects/Effect.cpp @@ -22,6 +22,7 @@ greater use in future. *//*******************************************************************/ #include "../Audacity.h" +#include "Effect.h" #include #include @@ -36,11 +37,11 @@ greater use in future. #include "audacity/ConfigInterface.h" -#include "Effect.h" #include "../AudioIO.h" #include "../Mix.h" #include "../Prefs.h" #include "../Project.h" +#include "../ShuttleGui.h" #include "../WaveTrack.h" #include "../toolbars/ControlToolBar.h" #include "../widgets/AButton.h" diff --git a/src/effects/Effect.h b/src/effects/Effect.h index 350300ca4..973e3d33e 100644 --- a/src/effects/Effect.h +++ b/src/effects/Effect.h @@ -20,7 +20,10 @@ #include #include +class wxCheckBox; +class wxChoice; class wxDialog; +class wxListBox; class wxWindow; #include "audacity/ConfigInterface.h" @@ -30,10 +33,11 @@ class wxWindow; #include "../WaveTrack.h" #include "../SelectedRegion.h" #include "../Shuttle.h" -#include "../ShuttleGui.h" #include "../Internat.h" #include "../widgets/ProgressDialog.h" +class ShuttleGui; + #define BUILTIN_EFFECT_PREFIX wxT("Built-in Effect: ") class SelectedRegion; diff --git a/src/effects/FindClipping.cpp b/src/effects/FindClipping.cpp index f95976619..864e499b8 100644 --- a/src/effects/FindClipping.cpp +++ b/src/effects/FindClipping.cpp @@ -20,16 +20,16 @@ #include "../Audacity.h" +#include "FindClipping.h" #include #include #include "../AudacityApp.h" +#include "../ShuttleGui.h" #include "../widgets/valnum.h" -#include "FindClipping.h" - // Define keys, defaults, minimums, and maximums for the effect parameters // // Name Type Key Def Min Max Scale diff --git a/src/effects/Leveller.cpp b/src/effects/Leveller.cpp index 8b2860f02..65ee5c0ac 100644 --- a/src/effects/Leveller.cpp +++ b/src/effects/Leveller.cpp @@ -14,6 +14,7 @@ *//*******************************************************************/ #include "../Audacity.h" +#include "Leveller.h" #include @@ -22,8 +23,7 @@ #include #include "../Prefs.h" - -#include "Leveller.h" +#include "../ShuttleGui.h" enum kPasses { diff --git a/src/effects/Leveller.h b/src/effects/Leveller.h index 1d4e310be..1019bf563 100644 --- a/src/effects/Leveller.h +++ b/src/effects/Leveller.h @@ -14,10 +14,10 @@ #include #include -#include "../ShuttleGui.h" - #include "Effect.h" +class ShuttleGui; + #define LEVELLER_PLUGIN_SYMBOL XO("Leveller") class EffectLeveller : public Effect diff --git a/src/effects/Noise.cpp b/src/effects/Noise.cpp index 7bf3ebbd2..398358035 100644 --- a/src/effects/Noise.cpp +++ b/src/effects/Noise.cpp @@ -14,6 +14,7 @@ *//*******************************************************************/ #include "../Audacity.h" +#include "Noise.h" #include @@ -23,10 +24,9 @@ #include #include "../Prefs.h" +#include "../ShuttleGui.h" #include "../widgets/valnum.h" -#include "Noise.h" - enum kTypes { kWhite, diff --git a/src/effects/Noise.h b/src/effects/Noise.h index 879ec948b..636aa6b5a 100644 --- a/src/effects/Noise.h +++ b/src/effects/Noise.h @@ -15,11 +15,12 @@ #include -#include "../ShuttleGui.h" #include "../widgets/NumericTextCtrl.h" #include "Effect.h" +class ShuttleGui; + #define NOISE_PLUGIN_SYMBOL XO("Noise") class EffectNoise : public Effect diff --git a/src/effects/NoiseReduction.cpp b/src/effects/NoiseReduction.cpp index 1436f4208..d02985d0b 100644 --- a/src/effects/NoiseReduction.cpp +++ b/src/effects/NoiseReduction.cpp @@ -40,6 +40,7 @@ #include "../Experimental.h" #include "NoiseReduction.h" +#include "../ShuttleGui.h" #include "../Prefs.h" #include diff --git a/src/effects/Normalize.h b/src/effects/Normalize.h index ead3b1675..a5ab075c5 100644 --- a/src/effects/Normalize.h +++ b/src/effects/Normalize.h @@ -18,11 +18,12 @@ #include #include -#include "../ShuttleGui.h" #include "../WaveTrack.h" #include "Effect.h" +class ShuttleGui; + #define NORMALIZE_PLUGIN_SYMBOL XO("Normalize") class EffectNormalize : public Effect diff --git a/src/effects/Paulstretch.cpp b/src/effects/Paulstretch.cpp index e2e7f77cd..5b1c98a40 100644 --- a/src/effects/Paulstretch.cpp +++ b/src/effects/Paulstretch.cpp @@ -15,6 +15,7 @@ *//*******************************************************************/ #include "../Audacity.h" +#include "Paulstretch.h" #include #include @@ -22,11 +23,10 @@ #include #include +#include "../ShuttleGui.h" #include "../FFT.h" #include "../widgets/valnum.h" -#include "Paulstretch.h" - // Define keys, defaults, minimums, and maximums for the effect parameters // // Name Type Key Def Min Max Scale diff --git a/src/effects/Paulstretch.h b/src/effects/Paulstretch.h index 7a195f9fa..44dbd69fd 100644 --- a/src/effects/Paulstretch.h +++ b/src/effects/Paulstretch.h @@ -12,11 +12,12 @@ #include -#include "../ShuttleGui.h" #include "../WaveTrack.h" #include "Effect.h" +class ShuttleGui; + #define PAULSTRETCH_PLUGIN_SYMBOL XO("Paulstretch") class EffectPaulstretch : public Effect diff --git a/src/effects/Phaser.cpp b/src/effects/Phaser.cpp index c3bc2425b..260a1dec0 100644 --- a/src/effects/Phaser.cpp +++ b/src/effects/Phaser.cpp @@ -20,14 +20,15 @@ #include "../Audacity.h" +#include "Phaser.h" #include #include +#include "../ShuttleGui.h" #include "../widgets/valnum.h" -#include "Phaser.h" enum { diff --git a/src/effects/Phaser.h b/src/effects/Phaser.h index 4a5773012..8619b36d8 100644 --- a/src/effects/Phaser.h +++ b/src/effects/Phaser.h @@ -21,10 +21,10 @@ #include #include -#include "../ShuttleGui.h" - #include "Effect.h" +class ShuttleGui; + #define NUM_STAGES 24 #define PHASER_PLUGIN_SYMBOL XO("Phaser") diff --git a/src/effects/Repeat.h b/src/effects/Repeat.h index 1f5284d45..766556c3a 100644 --- a/src/effects/Repeat.h +++ b/src/effects/Repeat.h @@ -16,10 +16,10 @@ #include #include -#include "../ShuttleGui.h" - #include "Effect.h" +class ShuttleGui; + #define REPEAT_PLUGIN_SYMBOL XO("Repeat") class EffectRepeat : public Effect diff --git a/src/effects/Reverb.cpp b/src/effects/Reverb.cpp index 7ccd3e9e1..f7a9f492d 100644 --- a/src/effects/Reverb.cpp +++ b/src/effects/Reverb.cpp @@ -15,16 +15,17 @@ *//*******************************************************************/ #include "../Audacity.h" +#include "Reverb.h" #include #include #include "../Audacity.h" #include "../Prefs.h" +#include "../ShuttleGui.h" #include "../widgets/valnum.h" #include "Reverb_libSoX.h" -#include "Reverb.h" enum { diff --git a/src/effects/Reverb.h b/src/effects/Reverb.h index be2213d46..d821470c9 100644 --- a/src/effects/Reverb.h +++ b/src/effects/Reverb.h @@ -18,10 +18,10 @@ #include #include -#include "../ShuttleGui.h" - #include "Effect.h" +class ShuttleGui; + #define REVERB_PLUGIN_SYMBOL XO("Reverb") struct Reverb_priv_t; diff --git a/src/effects/ScienFilter.cpp b/src/effects/ScienFilter.cpp index 7f5b8de35..838e8273e 100644 --- a/src/effects/ScienFilter.cpp +++ b/src/effects/ScienFilter.cpp @@ -33,6 +33,7 @@ a graph for EffectScienFilter. *//*******************************************************************/ #include "../Audacity.h" +#include "ScienFilter.h" #include #include @@ -50,12 +51,12 @@ a graph for EffectScienFilter. #include "../PlatformCompatibility.h" #include "../Prefs.h" #include "../Project.h" +#include "../ShuttleGui.h" #include "../Theme.h" #include "../WaveTrack.h" #include "../widgets/valnum.h" #include "Equalization.h" // For SliderAx -#include "ScienFilter.h" #if !defined(M_PI) #define PI = 3.1415926535897932384626433832795 diff --git a/src/effects/ScienFilter.h b/src/effects/ScienFilter.h index 65558a81a..a276b2e3b 100644 --- a/src/effects/ScienFilter.h +++ b/src/effects/ScienFilter.h @@ -23,12 +23,14 @@ Vaughan Johnson (Preview) #include #include -#include "../ShuttleGui.h" #include "../widgets/Ruler.h" #include "Biquad.h" #include "Effect.h" +class wxTextCtrl; +class ShuttleGui; + #define CLASSICFILTERS_PLUGIN_SYMBOL XO("Classic Filters") class EffectScienFilterPanel; diff --git a/src/effects/Silence.cpp b/src/effects/Silence.cpp index bf2707ab6..39b30d0d7 100644 --- a/src/effects/Silence.cpp +++ b/src/effects/Silence.cpp @@ -14,10 +14,11 @@ *//*******************************************************************/ #include "../Audacity.h" +#include "Silence.h" #include -#include "Silence.h" +#include "../ShuttleGui.h" EffectSilence::EffectSilence() { diff --git a/src/effects/TimeScale.cpp b/src/effects/TimeScale.cpp index c14609752..103474cb8 100644 --- a/src/effects/TimeScale.cpp +++ b/src/effects/TimeScale.cpp @@ -17,13 +17,15 @@ #if USE_SBSMS +#include "TimeScale.h" + #include #include +#include "../ShuttleGui.h" #include "../widgets/valnum.h" -#include "TimeScale.h" #include "sbsms.h" enum diff --git a/src/effects/TimeScale.h b/src/effects/TimeScale.h index 262cdf611..f684a50d8 100644 --- a/src/effects/TimeScale.h +++ b/src/effects/TimeScale.h @@ -20,10 +20,10 @@ #include #include -#include "../ShuttleGui.h" - #include "SBSMSEffect.h" +class ShuttleGui; + #define TIMESCALE_PLUGIN_SYMBOL XO("Time Scale") class EffectTimeScale : public EffectSBSMS diff --git a/src/effects/ToneGen.cpp b/src/effects/ToneGen.cpp index ca64e26c9..fef31fafb 100644 --- a/src/effects/ToneGen.cpp +++ b/src/effects/ToneGen.cpp @@ -19,6 +19,7 @@ frequency changes smoothly during the tone. *//*******************************************************************/ #include "../Audacity.h" +#include "ToneGen.h" #include #include @@ -27,11 +28,10 @@ frequency changes smoothly during the tone. #include #include "../Project.h" +#include "../ShuttleGui.h" #include "../widgets/NumericTextCtrl.h" #include "../widgets/valnum.h" -#include "ToneGen.h" - enum kInterpolations { kLinear, diff --git a/src/effects/ToneGen.h b/src/effects/ToneGen.h index 9d2ef61a3..337e01e25 100644 --- a/src/effects/ToneGen.h +++ b/src/effects/ToneGen.h @@ -16,11 +16,12 @@ #include #include -#include "../ShuttleGui.h" #include "../widgets/NumericTextCtrl.h" #include "Effect.h" +class ShuttleGui; + #define CHIRP_PLUGIN_SYMBOL XO("Chirp") #define TONE_PLUGIN_SYMBOL XO("Tone") diff --git a/src/effects/TruncSilence.cpp b/src/effects/TruncSilence.cpp index b29d20c3e..3f8f27f48 100644 --- a/src/effects/TruncSilence.cpp +++ b/src/effects/TruncSilence.cpp @@ -16,6 +16,7 @@ *//*******************************************************************/ #include "../Audacity.h" +#include "TruncSilence.h" #include #include @@ -23,11 +24,10 @@ #include #include "../Prefs.h" +#include "../ShuttleGui.h" #include "../WaveTrack.h" #include "../widgets/valnum.h" -#include "TruncSilence.h" - enum kActions { kTruncate, diff --git a/src/effects/TruncSilence.h b/src/effects/TruncSilence.h index c086318a4..2c2c0d7fc 100644 --- a/src/effects/TruncSilence.h +++ b/src/effects/TruncSilence.h @@ -24,10 +24,10 @@ #include #include -#include "../ShuttleGui.h" - #include "Effect.h" +class ShuttleGui; + #define TRUNCATESILENCE_PLUGIN_SYMBOL XO("Truncate Silence") // Declaration of RegionList diff --git a/src/effects/Wahwah.cpp b/src/effects/Wahwah.cpp index 3d81e487c..a14213c32 100644 --- a/src/effects/Wahwah.cpp +++ b/src/effects/Wahwah.cpp @@ -19,15 +19,15 @@ *//*******************************************************************/ #include "../Audacity.h" +#include "Wahwah.h" #include #include +#include "../ShuttleGui.h" #include "../widgets/valnum.h" -#include "Wahwah.h" - enum { ID_Freq = 10000, diff --git a/src/effects/Wahwah.h b/src/effects/Wahwah.h index c0fe56a73..0e39cd501 100644 --- a/src/effects/Wahwah.h +++ b/src/effects/Wahwah.h @@ -21,10 +21,10 @@ #include #include -#include "../ShuttleGui.h" - #include "Effect.h" +class ShuttleGui; + #define WAHWAH_PLUGIN_SYMBOL XO("Wahwah") class EffectWahwah : public Effect diff --git a/src/effects/vamp/VampEffect.cpp b/src/effects/vamp/VampEffect.cpp index b003c75ad..058b1afca 100644 --- a/src/effects/vamp/VampEffect.cpp +++ b/src/effects/vamp/VampEffect.cpp @@ -37,6 +37,7 @@ #include +#include "../../ShuttleGui.h" #include "../../widgets/valnum.h" enum diff --git a/src/export/Export.cpp b/src/export/Export.cpp index b76c49979..206d007c8 100644 --- a/src/export/Export.cpp +++ b/src/export/Export.cpp @@ -28,6 +28,9 @@ *//********************************************************************/ +#include "../Audacity.h" +#include "Export.h" + // For compilers that support precompilation, includes "wx/wx.h". #include @@ -48,7 +51,6 @@ #include #include -#include "Export.h" #include "ExportPCM.h" #include "ExportMP3.h" #include "ExportOGG.h" @@ -61,7 +63,6 @@ #include "FileDialog.h" -#include "../Audacity.h" #include "../DirManager.h" #include "../FileFormats.h" #include "../Internat.h" @@ -69,6 +70,7 @@ #include "../Mix.h" #include "../Prefs.h" #include "../Project.h" +#include "../ShuttleGui.h" #include "../Track.h" #include "../WaveTrack.h" #include "../widgets/Warning.h" diff --git a/src/export/ExportCL.cpp b/src/export/ExportCL.cpp index f831784e0..34e77f9a6 100644 --- a/src/export/ExportCL.cpp +++ b/src/export/ExportCL.cpp @@ -12,6 +12,7 @@ **********************************************************************/ #include "../Audacity.h" +#include "ExportCL.h" #include "../Project.h" #include @@ -22,10 +23,10 @@ #include #include #include "Export.h" -#include "ExportCL.h" #include "../Mix.h" #include "../Prefs.h" +#include "../ShuttleGui.h" #include "../Internat.h" #include "../float_cast.h" #include "../widgets/FileHistory.h" diff --git a/src/export/ExportFLAC.cpp b/src/export/ExportFLAC.cpp index 715ad5317..159779bb3 100644 --- a/src/export/ExportFLAC.cpp +++ b/src/export/ExportFLAC.cpp @@ -22,8 +22,8 @@ and libvorbis examples, Monty #ifdef USE_LIBFLAC -#include "Export.h" #include "ExportFLAC.h" +#include "Export.h" #include #include @@ -36,6 +36,7 @@ and libvorbis examples, Monty #include "../Project.h" #include "../Mix.h" #include "../Prefs.h" +#include "../ShuttleGui.h" #include "../Internat.h" #include "../Tags.h" diff --git a/src/export/ExportMP2.cpp b/src/export/ExportMP2.cpp index cfc6d9aa6..352bb5f9f 100644 --- a/src/export/ExportMP2.cpp +++ b/src/export/ExportMP2.cpp @@ -33,6 +33,7 @@ */ #include "../Audacity.h" +#include "ExportMP2.h" #ifdef USE_LIBTWOLAME @@ -47,12 +48,12 @@ #include #include "Export.h" -#include "ExportMP2.h" #include "../FileIO.h" #include "../Internat.h" #include "../Mix.h" #include "../Prefs.h" #include "../Project.h" +#include "../ShuttleGui.h" #include "../Tags.h" #include "../WaveTrack.h" diff --git a/src/export/ExportMP3.cpp b/src/export/ExportMP3.cpp index f93d1693a..ff9a2b886 100644 --- a/src/export/ExportMP3.cpp +++ b/src/export/ExportMP3.cpp @@ -59,6 +59,9 @@ *//********************************************************************/ +#include "../Audacity.h" +#include "ExportMP3.h" + #include #include @@ -75,13 +78,13 @@ #include #include -#include "../Audacity.h" #include "../FileNames.h" #include "../float_cast.h" #include "../Internat.h" #include "../Mix.h" #include "../Prefs.h" #include "../Project.h" +#include "../ShuttleGui.h" #include "../Tags.h" #include "../WaveTrack.h" #include "../widgets/LinkingHtmlWindow.h" @@ -89,7 +92,6 @@ #include "FileDialog.h" #include "Export.h" -#include "ExportMP3.h" #include diff --git a/src/export/ExportMultiple.cpp b/src/export/ExportMultiple.cpp index 3302c9985..deeb7f30c 100644 --- a/src/export/ExportMultiple.cpp +++ b/src/export/ExportMultiple.cpp @@ -16,6 +16,7 @@ *//********************************************************************/ #include "../Audacity.h" +#include "ExportMultiple.h" #include #include @@ -38,7 +39,6 @@ #include #include "Export.h" -#include "ExportMultiple.h" #include "../Internat.h" #include "../FileFormats.h" @@ -46,6 +46,7 @@ #include "../LabelTrack.h" #include "../Project.h" #include "../Prefs.h" +#include "../ShuttleGui.h" #include "../Tags.h" #include "../widgets/HelpSystem.h" diff --git a/src/export/ExportOGG.cpp b/src/export/ExportOGG.cpp index 091ac85ca..eafd27c1a 100644 --- a/src/export/ExportOGG.cpp +++ b/src/export/ExportOGG.cpp @@ -19,8 +19,8 @@ #ifdef USE_LIBVORBIS -#include "Export.h" #include "ExportOGG.h" +#include "Export.h" #include #include @@ -31,6 +31,7 @@ #include "../Project.h" #include "../Mix.h" #include "../Prefs.h" +#include "../ShuttleGui.h" #include "../Internat.h" #include "../Tags.h" diff --git a/src/export/ExportPCM.cpp b/src/export/ExportPCM.cpp index 4789b679f..51a2f79ab 100644 --- a/src/export/ExportPCM.cpp +++ b/src/export/ExportPCM.cpp @@ -8,6 +8,9 @@ **********************************************************************/ +#include "../Audacity.h" +#include "ExportPCM.h" + #include #include @@ -23,20 +26,19 @@ #include "sndfile.h" -#include "../Audacity.h" #include "../FileFormats.h" #include "../Internat.h" #include "../LabelTrack.h" #include "../Mix.h" #include "../Prefs.h" #include "../Project.h" +#include "../ShuttleGui.h" #include "../Tags.h" #include "../Track.h" #include "../WaveTrack.h" #include "../ondemand/ODManager.h" #include "Export.h" -#include "ExportPCM.h" #ifdef USE_LIBID3TAG #include diff --git a/src/prefs/BatchPrefs.h b/src/prefs/BatchPrefs.h index 3b2936f04..427e7233c 100644 --- a/src/prefs/BatchPrefs.h +++ b/src/prefs/BatchPrefs.h @@ -16,10 +16,10 @@ #include -#include "../ShuttleGui.h" - #include "PrefsPanel.h" +class ShuttleGui; + class BatchPrefs : public PrefsPanel { public: diff --git a/src/prefs/DevicePrefs.h b/src/prefs/DevicePrefs.h index 06f3143f6..67d3bef24 100644 --- a/src/prefs/DevicePrefs.h +++ b/src/prefs/DevicePrefs.h @@ -19,11 +19,11 @@ #include #include -#include "../ShuttleGui.h" - #include "PrefsPanel.h" -class DevicePrefs:public PrefsPanel +class ShuttleGui; + +class DevicePrefs :public PrefsPanel { public: DevicePrefs(wxWindow * parent); diff --git a/src/prefs/DirectoriesPrefs.h b/src/prefs/DirectoriesPrefs.h index 4793420ed..404071857 100644 --- a/src/prefs/DirectoriesPrefs.h +++ b/src/prefs/DirectoriesPrefs.h @@ -14,11 +14,11 @@ #include #include -#include "../ShuttleGui.h" - #include "PrefsPanel.h" -class DirectoriesPrefs:public PrefsPanel +class ShuttleGui; + +class DirectoriesPrefs :public PrefsPanel { public: DirectoriesPrefs(wxWindow * parent); diff --git a/src/prefs/EffectsPrefs.h b/src/prefs/EffectsPrefs.h index 845e101cb..0d096c042 100644 --- a/src/prefs/EffectsPrefs.h +++ b/src/prefs/EffectsPrefs.h @@ -18,11 +18,11 @@ #include #include -#include "../ShuttleGui.h" - #include "PrefsPanel.h" -class EffectsPrefs:public PrefsPanel +class ShuttleGui; + +class EffectsPrefs :public PrefsPanel { public: EffectsPrefs(wxWindow * parent); diff --git a/src/prefs/ExtImportPrefs.h b/src/prefs/ExtImportPrefs.h index f859cc3c0..d97f29b69 100644 --- a/src/prefs/ExtImportPrefs.h +++ b/src/prefs/ExtImportPrefs.h @@ -16,15 +16,15 @@ #include #include "../widgets/Grid.h" -#include "../ShuttleGui.h" - #include "PrefsPanel.h" #include "../import/Import.h" #include "../import/ImportPlugin.h" +class wxButton; class wxListEvent; class ExtImportPrefs; +class ShuttleGui; class ExtImportPrefsDropTarget: public wxDropTarget { diff --git a/src/prefs/GUIPrefs.h b/src/prefs/GUIPrefs.h index 0fe055f67..e3af2b7f3 100644 --- a/src/prefs/GUIPrefs.h +++ b/src/prefs/GUIPrefs.h @@ -18,11 +18,11 @@ #include #include -#include "../ShuttleGui.h" - #include "PrefsPanel.h" -class GUIPrefs:public PrefsPanel +class ShuttleGui; + +class GUIPrefs :public PrefsPanel { public: GUIPrefs(wxWindow * parent); diff --git a/src/prefs/ImportExportPrefs.h b/src/prefs/ImportExportPrefs.h index 9c67ff1b2..9ba891ea7 100644 --- a/src/prefs/ImportExportPrefs.h +++ b/src/prefs/ImportExportPrefs.h @@ -17,11 +17,11 @@ #include -#include "../ShuttleGui.h" - #include "PrefsPanel.h" -class ImportExportPrefs:public PrefsPanel +class ShuttleGui; + +class ImportExportPrefs :public PrefsPanel { public: ImportExportPrefs(wxWindow * parent); diff --git a/src/prefs/KeyConfigPrefs.h b/src/prefs/KeyConfigPrefs.h index bacb99d35..36f869ec4 100644 --- a/src/prefs/KeyConfigPrefs.h +++ b/src/prefs/KeyConfigPrefs.h @@ -12,6 +12,8 @@ #ifndef __AUDACITY_KEY_CONFIG_PREFS__ #define __AUDACITY_KEY_CONFIG_PREFS__ +class ShuttleGui; + #if defined(EXPERIMENTAL_KEY_VIEW) #include @@ -23,13 +25,12 @@ #include #include -#include "../ShuttleGui.h" #include "../commands/CommandManager.h" #include "../widgets/KeyView.h" #include "PrefsPanel.h" -class KeyConfigPrefs:public PrefsPanel +class KeyConfigPrefs :public PrefsPanel { public: KeyConfigPrefs(wxWindow * parent); @@ -93,7 +94,6 @@ private: #include #include -#include "../ShuttleGui.h" #include "../commands/CommandManager.h" #include "PrefsPanel.h" diff --git a/src/prefs/LibraryPrefs.h b/src/prefs/LibraryPrefs.h index 1ff51adde..15e54a98f 100644 --- a/src/prefs/LibraryPrefs.h +++ b/src/prefs/LibraryPrefs.h @@ -18,11 +18,11 @@ #include #include -#include "../ShuttleGui.h" - #include "PrefsPanel.h" -class LibraryPrefs:public PrefsPanel +class ShuttleGui; + +class LibraryPrefs :public PrefsPanel { public: LibraryPrefs(wxWindow * parent); diff --git a/src/prefs/MidiIOPrefs.h b/src/prefs/MidiIOPrefs.h index 97b5e60c4..81da992c3 100644 --- a/src/prefs/MidiIOPrefs.h +++ b/src/prefs/MidiIOPrefs.h @@ -10,6 +10,9 @@ **********************************************************************/ #include "../Experimental.h" + +class ShuttleGui; + #ifdef EXPERIMENTAL_MIDI_OUT #ifndef __AUDACITY_MIDI_IO_PREFS__ @@ -21,8 +24,6 @@ #include #include -#include "../ShuttleGui.h" - #include "PrefsPanel.h" class MidiIOPrefs:public PrefsPanel diff --git a/src/prefs/ModulePrefs.h b/src/prefs/ModulePrefs.h index 107a87fe5..9014e96a5 100644 --- a/src/prefs/ModulePrefs.h +++ b/src/prefs/ModulePrefs.h @@ -17,11 +17,11 @@ #include -#include "../ShuttleGui.h" - #include "PrefsPanel.h" +class ShuttleGui; + enum { kModuleDisabled = 0, kModuleEnabled = 1, diff --git a/src/prefs/MousePrefs.h b/src/prefs/MousePrefs.h index e4efb35ed..33f5254ea 100644 --- a/src/prefs/MousePrefs.h +++ b/src/prefs/MousePrefs.h @@ -15,11 +15,11 @@ #include #include -#include "../ShuttleGui.h" - #include "PrefsPanel.h" -class MousePrefs:public PrefsPanel +class ShuttleGui; + +class MousePrefs :public PrefsPanel { public: MousePrefs(wxWindow * parent); diff --git a/src/prefs/PlaybackPrefs.h b/src/prefs/PlaybackPrefs.h index ecb966617..8384fb584 100644 --- a/src/prefs/PlaybackPrefs.h +++ b/src/prefs/PlaybackPrefs.h @@ -16,11 +16,11 @@ #include -#include "../ShuttleGui.h" - #include "PrefsPanel.h" -class PlaybackPrefs:public PrefsPanel +class ShuttleGui; + +class PlaybackPrefs :public PrefsPanel { public: PlaybackPrefs(wxWindow * parent); diff --git a/src/prefs/PrefsDialog.cpp b/src/prefs/PrefsDialog.cpp index c842eda5d..91f18bc65 100644 --- a/src/prefs/PrefsDialog.cpp +++ b/src/prefs/PrefsDialog.cpp @@ -39,6 +39,7 @@ #include "../Experimental.h" #include "../Project.h" #include "../Prefs.h" +#include "../ShuttleGui.h" #include "PrefsDialog.h" #include "PrefsPanel.h" diff --git a/src/prefs/ProjectsPrefs.h b/src/prefs/ProjectsPrefs.h index 065dab57c..3f1a00791 100644 --- a/src/prefs/ProjectsPrefs.h +++ b/src/prefs/ProjectsPrefs.h @@ -17,11 +17,11 @@ #include -#include "../ShuttleGui.h" - #include "PrefsPanel.h" -class ProjectsPrefs:public PrefsPanel +class ShuttleGui; + +class ProjectsPrefs :public PrefsPanel { public: ProjectsPrefs(wxWindow * parent); diff --git a/src/prefs/QualityPrefs.h b/src/prefs/QualityPrefs.h index 4cfd924c1..726da2490 100644 --- a/src/prefs/QualityPrefs.h +++ b/src/prefs/QualityPrefs.h @@ -19,11 +19,11 @@ #include #include -#include "../ShuttleGui.h" - #include "PrefsPanel.h" -class QualityPrefs:public PrefsPanel +class ShuttleGui; + +class QualityPrefs :public PrefsPanel { public: QualityPrefs(wxWindow * parent); diff --git a/src/prefs/RecordingPrefs.h b/src/prefs/RecordingPrefs.h index dc2533c8b..d4f1dd122 100644 --- a/src/prefs/RecordingPrefs.h +++ b/src/prefs/RecordingPrefs.h @@ -16,11 +16,11 @@ #include -#include "../ShuttleGui.h" - #include "PrefsPanel.h" -class RecordingPrefs:public PrefsPanel +class ShuttleGui; + +class RecordingPrefs :public PrefsPanel { public: RecordingPrefs(wxWindow * parent); diff --git a/src/prefs/SpectrumPrefs.h b/src/prefs/SpectrumPrefs.h index 2fb9c8fa8..20a1e7385 100644 --- a/src/prefs/SpectrumPrefs.h +++ b/src/prefs/SpectrumPrefs.h @@ -26,11 +26,12 @@ #include #include "../Experimental.h" -#include "../ShuttleGui.h" #include "PrefsPanel.h" +class wxTextCtrl; struct FFTParam; +class ShuttleGui; class SpectrumPrefs:public PrefsPanel { diff --git a/src/prefs/ThemePrefs.h b/src/prefs/ThemePrefs.h index 168ce9d0b..40d080c8c 100644 --- a/src/prefs/ThemePrefs.h +++ b/src/prefs/ThemePrefs.h @@ -17,11 +17,11 @@ #include #include -#include "../ShuttleGui.h" - #include "PrefsPanel.h" -class ThemePrefs:public PrefsPanel +class ShuttleGui; + +class ThemePrefs :public PrefsPanel { public: ThemePrefs(wxWindow * parent); diff --git a/src/prefs/TracksPrefs.h b/src/prefs/TracksPrefs.h index 649537767..aa0f54272 100644 --- a/src/prefs/TracksPrefs.h +++ b/src/prefs/TracksPrefs.h @@ -18,11 +18,11 @@ #include #include -#include "../ShuttleGui.h" - #include "PrefsPanel.h" -class TracksPrefs:public PrefsPanel +class ShuttleGui; + +class TracksPrefs :public PrefsPanel { public: TracksPrefs(wxWindow * parent); diff --git a/src/prefs/WarningsPrefs.h b/src/prefs/WarningsPrefs.h index f8d198838..8f789e163 100644 --- a/src/prefs/WarningsPrefs.h +++ b/src/prefs/WarningsPrefs.h @@ -17,11 +17,11 @@ #include -#include "../ShuttleGui.h" - #include "PrefsPanel.h" -class WarningsPrefs:public PrefsPanel +class ShuttleGui; + +class WarningsPrefs :public PrefsPanel { public: WarningsPrefs(wxWindow * parent); diff --git a/src/toolbars/DeviceToolBar.cpp b/src/toolbars/DeviceToolBar.cpp index f7a48b35e..ab5862f84 100644 --- a/src/toolbars/DeviceToolBar.cpp +++ b/src/toolbars/DeviceToolBar.cpp @@ -15,6 +15,7 @@ #include "../Audacity.h" +#include "DeviceToolBar.h" // For compilers that support precompilation, includes "wx/wx.h". #include @@ -31,7 +32,6 @@ #include "../AudacityApp.h" -#include "DeviceToolBar.h" #include "ToolDock.h" #include "../TrackPanel.h" @@ -41,6 +41,7 @@ #include "../ImageManipulation.h" #include "../Prefs.h" #include "../Project.h" +#include "../ShuttleGui.h" #include "../Theme.h" #include "../widgets/Grabber.h" #include "../DeviceManager.h" diff --git a/src/widgets/Meter.cpp b/src/widgets/Meter.cpp index eb43dd175..fabc0cba8 100644 --- a/src/widgets/Meter.cpp +++ b/src/widgets/Meter.cpp @@ -39,6 +39,7 @@ *//******************************************************************/ #include "../Audacity.h" +#include "Meter.h" #include "../AudacityApp.h" #include @@ -57,8 +58,6 @@ #include -#include "Meter.h" - #include "../AudioIO.h" #include "../AColor.h" #include "../ImageManipulation.h" @@ -66,6 +65,7 @@ #include "../toolbars/MeterToolBar.h" #include "../toolbars/ControlToolBar.h" #include "../Prefs.h" +#include "../ShuttleGui.h" #include "../Theme.h" #include "../AllThemeResources.h" From c4825967de430b8de9b29bed0fabdb49f79bdc6b Mon Sep 17 00:00:00 2001 From: James Crook Date: Sun, 19 Jul 2015 18:43:49 +0100 Subject: [PATCH 34/36] Bug844 - Shortcuts that activate play abort recording Six shortcuts for play after/before selection now added to shortcuts that are disabled if Audio is recording. --- src/Menus.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Menus.cpp b/src/Menus.cpp index 2352113de..5ecfcce68 100644 --- a/src/Menus.cpp +++ b/src/Menus.cpp @@ -1126,6 +1126,9 @@ void AudacityProject::CreateMenusAndCommands() c->AddCommand(wxT("Stop"), _("Stop"), FN(OnStop), AudioIOBusyFlag, AudioIOBusyFlag); + + c->SetDefaultFlags(CaptureNotBusyFlag, CaptureNotBusyFlag); + c->AddCommand(wxT("PlayOneSec"), _("Play One Second"), FN(OnPlayOneSecond), wxT("1"), CaptureNotBusyFlag, CaptureNotBusyFlag); @@ -1142,6 +1145,9 @@ void AudacityProject::CreateMenusAndCommands() CaptureNotBusyFlag, CaptureNotBusyFlag); + c->SetDefaultFlags(AlwaysEnabledFlag, AlwaysEnabledFlag); + + c->AddCommand(wxT("SelStart"), _("Selection to Start"), FN(OnSelToStart), wxT("Shift+Home")); c->AddCommand(wxT("SelEnd"), _("Selection to End"), FN(OnSelToEnd), wxT("Shift+End")); From 13c17d3d5da5fdaf5d0f0ea99886b06194f4fc41 Mon Sep 17 00:00:00 2001 From: James Crook Date: Sun, 19 Jul 2015 19:01:15 +0100 Subject: [PATCH 35/36] Fix Travis Build (const in structure) Not supported by version of gcc used by travis. --- src/TrackArtist.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/TrackArtist.cpp b/src/TrackArtist.cpp index 78422e7f5..88dbf69e1 100644 --- a/src/TrackArtist.cpp +++ b/src/TrackArtist.cpp @@ -1637,8 +1637,8 @@ struct ClipParameters namespace { struct WavePortion { wxRect rect; - const double averageZoom; - const bool inFisheye; + /*const*/ double averageZoom; + /*const*/ bool inFisheye; WavePortion(int x, int y, int w, int h, double zoom, bool i) : rect(x, y, w, h), averageZoom(zoom), inFisheye(i) {} From 90d03f835179c407d32d046c060ec96606abdab1 Mon Sep 17 00:00:00 2001 From: James Crook Date: Sun, 19 Jul 2015 19:51:30 +0100 Subject: [PATCH 36/36] More deconsting to satisfy Travis const in struct not supported by Travis version of gcc. --- src/ViewInfo.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ViewInfo.h b/src/ViewInfo.h index 03040a64f..bba107215 100644 --- a/src/ViewInfo.h +++ b/src/ViewInfo.h @@ -85,7 +85,7 @@ public: void ZoomBy(double multiplier); struct Interval { - const wxInt64 position; const double averageZoom; const bool inFisheye; + /* const */ wxInt64 position; /* const */ double averageZoom; /* const */ bool inFisheye; Interval(wxInt64 p, double z, bool i) : position(p), averageZoom(z), inFisheye(i) {} };