From aa4b80871473c2528043905db46f97ae1b8385b6 Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Wed, 9 Sep 2020 08:04:40 -0400 Subject: [PATCH] More constructors for SnapManager... one taking candidate list directly, the others delegating to it. Some members removed, some in-class initializers. The special constructor for TimeShift only has extra arguments. It will go away. --- src/Snap.cpp | 179 +++++++++++++++++++++++++++++++-------------------- src/Snap.h | 29 ++++++--- 2 files changed, 128 insertions(+), 80 deletions(-) diff --git a/src/Snap.cpp b/src/Snap.cpp index df4fd20e9..2753b22a0 100644 --- a/src/Snap.cpp +++ b/src/Snap.cpp @@ -39,6 +39,108 @@ TrackClip::~TrackClip() } +SnapManager::SnapManager(const AudacityProject &project, + SnapPointArray candidates, + const ZoomInfo &zoomInfo, + bool noTimeSnap, + int pixelTolerance) +: mProject{ &project } +, mZoomInfo{ &zoomInfo } +, mPixelTolerance{ pixelTolerance } +, mNoTimeSnap{ noTimeSnap } +, mCandidates{ std::move( candidates ) } +, mSnapPoints{} +, mConverter{ NumericConverter::TIME } +{ + Reinit(); +} + +namespace { +SnapPointArray FindCandidates( const TrackList &tracks ) +{ + SnapPointArray candidates; + for ( const auto track : tracks.Any() ) { + auto intervals = track->GetIntervals(); + for (const auto &interval : intervals) { + candidates.emplace_back( interval.Start(), track ); + if ( interval.Start() != interval.End() ) + candidates.emplace_back( interval.End(), track ); + } + } + return candidates; +} + +SnapPointArray FindCandidates( + const TrackList &tracks, + const TrackClipArray *clipExclusions, const TrackArray *trackExclusions ) +{ + // Special case restricted candidates for time shift + SnapPointArray candidates; + auto trackRange = + tracks.Any() + - [&](const Track *pTrack){ + return trackExclusions && + make_iterator_range( *trackExclusions ).contains( pTrack ); + }; + trackRange.Visit( + [&](const LabelTrack *labelTrack) { + for (int i = 0, cnt = labelTrack->GetNumLabels(); i < cnt; ++i) + { + const LabelStruct *label = labelTrack->GetLabel(i); + const double t0 = label->getT0(); + const double t1 = label->getT1(); + candidates.emplace_back(t0, labelTrack); + if (t1 != t0) + candidates.emplace_back(t1, labelTrack); + } + }, + [&](const WaveTrack *waveTrack) { + for (const auto &clip: waveTrack->GetClips()) + { + if (clipExclusions) + { + bool skip = false; + for (size_t j = 0, cnt = clipExclusions->size(); j < cnt; ++j) + { + if ((*clipExclusions)[j].track == waveTrack && + (*clipExclusions)[j].clip == clip.get()) + { + skip = true; + break; + } + } + + if (skip) + continue; + } + + candidates.emplace_back(clip->GetStartTime(), waveTrack); + candidates.emplace_back(clip->GetEndTime(), waveTrack); + } + } +#ifdef USE_MIDI + , + [&](const NoteTrack *track) { + candidates.emplace_back(track->GetStartTime(), track); + candidates.emplace_back(track->GetEndTime(), track); + } +#endif + ); + return candidates; +} +} + +SnapManager::SnapManager(const AudacityProject &project, + const TrackList &tracks, + const ZoomInfo &zoomInfo, + bool noTimeSnap, + int pixelTolerance) + : SnapManager{ project, + FindCandidates( tracks ), + zoomInfo, noTimeSnap, pixelTolerance } +{ +} + SnapManager::SnapManager(const AudacityProject &project, const TrackList &tracks, const ZoomInfo &zoomInfo, @@ -46,26 +148,10 @@ SnapManager::SnapManager(const AudacityProject &project, int pixelTolerance, const TrackClipArray *clipExclusions, const TrackArray *trackExclusions) -: mConverter(NumericConverter::TIME) + : SnapManager{ project, + FindCandidates( tracks, clipExclusions, trackExclusions ), + zoomInfo, noTimeSnap, pixelTolerance } { - mTracks = &tracks; - mZoomInfo = &zoomInfo; - mClipExclusions = clipExclusions; - mTrackExclusions = trackExclusions; - mPixelTolerance = pixelTolerance; - mNoTimeSnap = noTimeSnap; - - mProject = &project; - wxASSERT(mProject); - - mSnapTo = 0; - mRate = 0.0; - mFormat = {}; - - // Two time points closer than this are considered the same - mEpsilon = 1 / 44100.0; - - Reinit(); } SnapManager::~SnapManager() @@ -106,58 +192,9 @@ void SnapManager::Reinit() // Add a SnapPoint at t=0 mSnapPoints.push_back(SnapPoint{}); - auto trackRange = - mTracks->Any() - - [&](const Track *pTrack){ - return mTrackExclusions && - make_iterator_range( *mTrackExclusions ).contains( pTrack ); - }; - trackRange.Visit( - [&](const LabelTrack *labelTrack) { - for (int i = 0, cnt = labelTrack->GetNumLabels(); i < cnt; ++i) - { - const LabelStruct *label = labelTrack->GetLabel(i); - const double t0 = label->getT0(); - const double t1 = label->getT1(); - CondListAdd(t0, labelTrack); - if (t1 != t0) - { - CondListAdd(t1, labelTrack); - } - } - }, - [&](const WaveTrack *waveTrack) { - for (const auto &clip: waveTrack->GetClips()) - { - if (mClipExclusions) - { - bool skip = false; - for (size_t j = 0, cnt = mClipExclusions->size(); j < cnt; ++j) - { - if ((*mClipExclusions)[j].track == waveTrack && - (*mClipExclusions)[j].clip == clip.get()) - { - skip = true; - break; - } - } - - if (skip) - continue; - } - - CondListAdd(clip->GetStartTime(), waveTrack); - CondListAdd(clip->GetEndTime(), waveTrack); - } - } -#ifdef USE_MIDI - , - [&](const NoteTrack *track) { - CondListAdd(track->GetStartTime(), track); - CondListAdd(track->GetEndTime(), track); - } -#endif - ); + // Adjust and filter the candidate points + for (const auto &candidate : mCandidates) + CondListAdd( candidate.t, candidate.track ); // Sort all by time std::sort(mSnapPoints.begin(), mSnapPoints.end()); diff --git a/src/Snap.h b/src/Snap.h index 5a962c88e..50679d244 100644 --- a/src/Snap.h +++ b/src/Snap.h @@ -77,11 +77,23 @@ struct SnapResults { class SnapManager { public: + SnapManager(const AudacityProject &project, + SnapPointArray candidates, + const ZoomInfo &zoomInfo, + bool noTimeSnap = false, + int pixelTolerance = kPixelTolerance); + SnapManager(const AudacityProject &project, const TrackList &tracks, const ZoomInfo &zoomInfo, bool noTimeSnap = false, - int pixelTolerance = kPixelTolerance, + int pixelTolerance = kPixelTolerance); + + SnapManager(const AudacityProject &project, + const TrackList &tracks, + const ZoomInfo &zoomInfo, + bool noTimeSnap, + int pixelTolerance, const TrackClipArray *clipExclusions = NULL, const TrackArray *trackExclusions = NULL); ~SnapManager(); @@ -112,23 +124,22 @@ private: private: const AudacityProject *mProject; - const TrackList *mTracks; - const TrackClipArray *mClipExclusions; - const TrackArray *mTrackExclusions; const ZoomInfo *mZoomInfo; int mPixelTolerance; bool mNoTimeSnap; - double mEpsilon; + //! Two time points closer than this are considered the same + double mEpsilon{ 1 / 44100.0 }; + SnapPointArray mCandidates; SnapPointArray mSnapPoints; // Info for snap-to-time NumericConverter mConverter; - bool mSnapToTime; + bool mSnapToTime{ false }; - int mSnapTo; - double mRate; - NumericFormatSymbol mFormat; + int mSnapTo{ 0 }; + double mRate{ 0.0 }; + NumericFormatSymbol mFormat{}; }; #endif