Audacity  2.2.2
Track.h
Go to the documentation of this file.
1 /**********************************************************************
2 
3  Audacity: A Digital Audio Editor
4 
5  Track.h
6 
7  Dominic Mazzoni
8 
9 **********************************************************************/
10 
11 #ifndef __AUDACITY_TRACK__
12 #define __AUDACITY_TRACK__
13 
14 #include "Audacity.h"
15 
16 #include "MemoryX.h"
17 #include <vector>
18 #include <list>
19 #include <functional>
20 #include <wx/event.h>
21 #include <wx/gdicmn.h>
22 #include <wx/longlong.h>
23 #include <wx/string.h>
24 
25 #include "Experimental.h"
26 #include "SampleFormat.h"
28 #include "xml/XMLTagHandler.h"
29 
30 #ifdef __WXMSW__
31 #pragma warning(disable:4284)
32 #endif
33 
34 class wxTextFile;
35 class DirManager;
36 class Track;
37 class LabelTrack;
38 class TimeTrack;
39 class TrackControls;
42 class WaveTrack;
43 class NoteTrack;
44 class AudacityProject;
45 class ZoomInfo;
46 
47 class SelectHandle;
48 class TimeShiftHandle;
49 
50 WX_DEFINE_USER_EXPORTED_ARRAY(Track*, TrackArray, class AUDACITY_DLL_API);
51 using WaveTrackArray = std::vector < std::shared_ptr< WaveTrack > > ;
52 using WaveTrackConstArray = std::vector < std::shared_ptr < const WaveTrack > >;
53 
54 using NoteTrackConstArray = std::vector < std::shared_ptr< const NoteTrack > >;
55 
56 #if defined(USE_MIDI)
57 class NoteTrack;
58 #endif
59 
60 class TrackList;
61 
62 using ListOfTracks = std::list< std::shared_ptr< Track > >;
63 
64 using TrackNodePointer =
65 std::pair< ListOfTracks::iterator, ListOfTracks* >;
66 
67 inline bool operator == (const TrackNodePointer &a, const TrackNodePointer &b)
68 { return a.second == b.second && a.first == b.first; }
69 
70 inline bool operator != (const TrackNodePointer &a, const TrackNodePointer &b)
71 { return !(a == b); }
72 
73 class ViewInfo;
74 
75 // This is an in-session identifier of track objects across undo states
76 // It does not persist between sessions
77 // Default constructed value is not equal to the id of any track that has ever
78 // been added to a TrackList, or (directly or transitively) copied from such
79 // (A pending additional track that is not yet applied is not considered added)
80 // TrackIds are assigned uniquely across projects
81 class TrackId
82 {
83 public:
84  TrackId() : mValue(-1) {}
85  explicit TrackId (long value) : mValue(value) {}
86 
87  bool operator == (const TrackId &other) const
88  { return mValue == other.mValue; }
89 
90  bool operator != (const TrackId &other) const
91  { return mValue != other.mValue; }
92 
93  // Define this in case you want to key a std::map on TrackId
94  // The operator does not mean anything else
95  bool operator < (const TrackId &other) const
96  { return mValue < other.mValue; }
97 
98 private:
99  long mValue;
100 };
101 
102 class AUDACITY_DLL_API Track /* not final */
103  : public CommonTrackPanelCell, public XMLTagHandler
104 {
105  friend class TrackList;
106  friend class TrackListIterator;
108 
109  // To be TrackDisplay
110  private:
112 
113  protected:
114  std::weak_ptr<TrackList> mList;
116  int mIndex;
117  int mY;
118  int mHeight;
119  wxString mName;
120  wxString mDefaultName;
121 
122  bool mSelected;
123 
124  bool mLinked;
126 
127  public:
128 
129  TrackId GetId() const { return mId; }
130  private:
131  void SetId( TrackId id ) { mId = id; }
132  public:
133 
134  // Given a bare pointer, find a shared_ptr. But this is not possible for
135  // a track not owned by any project, so the result can be null.
136  template<typename Subclass = Track>
137  inline static std::shared_ptr<Subclass> Pointer( Track *t )
138  {
139  if (t) {
140  auto pList = t->mList.lock();
141  if (pList)
142  return std::static_pointer_cast<Subclass>(*t->mNode.first);
143  }
144  return {};
145  }
146 
147  template<typename Subclass = const Track>
148  inline static std::shared_ptr<Subclass> Pointer( const Track *t )
149  {
150  if (t) {
151  auto pList = t->mList.lock();
152  if (pList) {
153  std::shared_ptr<const Track> p{ *t->mNode.first };
154  // Let you change the type, but not cast away the const
155  return std::static_pointer_cast<Subclass>(p);
156  }
157  }
158  return {};
159  }
160 
161  // Find anything registered with TrackList::RegisterPendingChangedTrack and
162  // not yet cleared or applied; if no such exists, return this track
163  std::shared_ptr<const Track> SubstitutePendingChangedTrack() const;
164 
165  // Cause certain overriding tool modes (Zoom; future ones?) to behave
166  // uniformly in all tracks, disregarding track contents.
167  // Do not further override this...
168  std::vector<UIHandlePtr> HitTest
169  (const TrackPanelMouseState &, const AudacityProject *pProject)
170  final override;
171 
172  // Delegates the handling to the related TCP cell
173  std::shared_ptr<TrackPanelCell> ContextMenuDelegate() override
174  { return GetTrackControl(); }
175 
176  public:
177 
178  // Rather override this for subclasses:
179  virtual std::vector<UIHandlePtr> DetailedHitTest
180  (const TrackPanelMouseState &,
181  const AudacityProject *pProject, int currentTool, bool bMultiTool)
182  = 0;
183 
184  mutable wxSize vrulerSize;
185 
186  // Return another, associated TrackPanelCell object that implements the
187  // drop-down, close and minimize buttons, etc.
188  std::shared_ptr<TrackPanelCell> GetTrackControl();
189 
190  // Return another, associated TrackPanelCell object that implements the
191  // mouse actions for the vertical ruler
192  std::shared_ptr<TrackPanelCell> GetVRulerControl();
193 
194  // Return another, associated TrackPanelCell object that implements the
195  // click and drag to resize
196  std::shared_ptr<TrackPanelCell> GetResizer();
197 
198  // This just returns a constant and can be overriden by subclasses
199  // to specify a different height for the case that the track is minimized.
200  virtual int GetMinimizedHeight() const;
201  int GetActualHeight() const { return mHeight; }
202 
203  int GetIndex() const;
204  void SetIndex(int index);
205 
206  int GetY() const;
207 private:
208  // Always maintain a strictly contiguous layout of tracks.
209  // So client code is not permitted to modify this attribute directly.
210  void SetY(int y);
211  // No need yet to make this virtual
212  void DoSetY(int y);
213 public:
214 
215  int GetHeight() const;
216  void SetHeight(int h);
217 protected:
218  virtual void DoSetHeight(int h);
219 public:
220 
221  bool GetMinimized() const;
222  void SetMinimized(bool isMinimized);
223 protected:
224  virtual void DoSetMinimized(bool isMinimized);
225 public:
226 
227  Track *GetLink() const;
228 
229  private:
230  TrackNodePointer GetNode() const;
231  void SetOwner
232  (const std::weak_ptr<TrackList> &list, TrackNodePointer node);
233 
234  // Keep in Track
235 
236  protected:
237  int mChannel;
238  double mOffset;
239 
240  mutable std::shared_ptr<DirManager> mDirManager;
241 
242  public:
243 
244  enum
245  {
246  LeftChannel = 0,
247  RightChannel = 1,
248  MonoChannel = 2
249  };
250 
252  {
255 #if defined(USE_MIDI)
256  Note,
257 #endif
260  All
261  };
262 
263  enum : unsigned { DefaultHeight = 150 };
264 
265  Track(const std::shared_ptr<DirManager> &projDirManager);
266  Track(const Track &orig);
267 
268  virtual ~ Track();
269 
270  void Init(const Track &orig);
271 
272  using Holder = std::unique_ptr<Track>;
273  virtual Holder Duplicate() const = 0;
274 
275  // Called when this track is merged to stereo with another, and should
276  // take on some paramaters of its partner.
277  virtual void Merge(const Track &orig);
278 
279  wxString GetName() const { return mName; }
280  void SetName( const wxString &n ) { mName = n; }
281  wxString GetDefaultName() const { return mDefaultName; }
282  void SetDefaultName( const wxString &n ) { mDefaultName = n; }
283 
284  bool GetSelected() const { return mSelected; }
285  virtual void SetSelected(bool s);
286 
287  bool GetLinked () const { return mLinked; }
288  void SetLinked (bool l);
289 private:
290  // No need yet to make this virtual
291  void DoSetLinked(bool l);
292 public:
293 
294  virtual int GetChannel() const { return mChannel;};
295  virtual double GetOffset() const = 0;
296 
297  void Offset(double t) { SetOffset(GetOffset() + t); }
298  virtual void SetOffset (double o) { mOffset = o; }
299 
300  void SetChannel(int c) { mChannel = c; }
301  virtual void SetPan( float ){ ;}
302  virtual void SetPanFromChannelType(){ ;};
303 
304  // AS: Note that the dirManager is mutable. This is
305  // mostly to support "Duplicate" of const objects,
306  // but in general, mucking with the dir manager is
307  // separate from the Track.
308  const std::shared_ptr<DirManager> &GetDirManager() const { return mDirManager; }
309 
310  // Create a NEW track and modify this track
311  // Return non-NULL or else throw
312  // May assume precondition: t0 <= t1
313  virtual Holder Cut(double WXUNUSED(t0), double WXUNUSED(t1)) = 0;
314 
315  // Create a NEW track and don't modify this track
316  // Return non-NULL or else throw
317  // Note that subclasses may want to distinguish tracks stored in a clipboard
318  // from those stored in a project
319  // May assume precondition: t0 <= t1
320  virtual Holder Copy
321  (double WXUNUSED(t0), double WXUNUSED(t1), bool forClipboard = true) const = 0;
322 
323  // May assume precondition: t0 <= t1
324  virtual void Clear(double WXUNUSED(t0), double WXUNUSED(t1)) = 0;
325 
326  virtual void Paste(double WXUNUSED(t), const Track * WXUNUSED(src)) = 0;
327 
328  // This can be used to adjust a sync-lock selected track when the selection
329  // is replaced by one of a different length.
330  virtual void SyncLockAdjust(double oldT1, double newT1);
331 
332  // May assume precondition: t0 <= t1
333  virtual void Silence(double WXUNUSED(t0), double WXUNUSED(t1)) = 0;
334 
335  // May assume precondition: t0 <= t1
336  virtual void InsertSilence(double WXUNUSED(t), double WXUNUSED(len)) = 0;
337 
338  virtual int GetKind() const { return None; }
339 
340  // XMLTagHandler callback methods -- NEW virtual for writing
341  virtual void WriteXML(XMLWriter &xmlFile) const = 0;
342 
343  // Returns true if an error was encountered while trying to
344  // open the track from XML
345  virtual bool GetErrorOpening() { return false; }
346 
347  virtual double GetStartTime() const = 0;
348  virtual double GetEndTime() const = 0;
349 
350  // Checks if sync-lock is on and any track in its sync-lock group is selected.
351  bool IsSyncLockSelected() const;
352 
353 protected:
354  std::shared_ptr<Track> FindTrack() override;
355 
356  // These are called to create controls on demand:
357  virtual std::shared_ptr<TrackControls> GetControls() = 0;
358  virtual std::shared_ptr<TrackVRulerControls> GetVRulerControls() = 0;
359 
360  // These hold the controls:
361  std::shared_ptr<TrackControls> mpControls;
362  std::shared_ptr<TrackVRulerControls> mpVRulerContols;
363  std::shared_ptr<TrackPanelResizerCell> mpResizer;
364 
365  std::weak_ptr<SelectHandle> mSelectHandle;
366  std::weak_ptr<TimeShiftHandle> mTimeShiftHandle;
367 };
368 
369 class AUDACITY_DLL_API AudioTrack /* not final */ : public Track
370 {
371 public:
372  AudioTrack(const std::shared_ptr<DirManager> &projDirManager)
373  : Track{ projDirManager } {}
374  AudioTrack(const Track &orig) : Track{ orig } {}
375 
376  // Serialize, not with tags of its own, but as attributes within a tag.
377  void WriteXMLAttributes(XMLWriter &WXUNUSED(xmlFile)) const {}
378 
379  // Return true iff the attribute is recognized.
380  bool HandleXMLAttribute(const wxChar * /*attr*/, const wxChar * /*value*/)
381  { return false; }
382 };
383 
384 class AUDACITY_DLL_API PlayableTrack /* not final */ : public AudioTrack
385 {
386 public:
387  PlayableTrack(const std::shared_ptr<DirManager> &projDirManager)
388  : AudioTrack{ projDirManager } {}
389  PlayableTrack(const Track &orig) : AudioTrack{ orig } {}
390 
391  bool GetMute () const { return mMute; }
392  bool GetSolo () const { return mSolo; }
393  void SetMute (bool m) { mMute = m; }
394  void SetSolo (bool s) { mSolo = s; }
395 
396  void Init( const PlayableTrack &init );
397  void Merge( const Track &init ) override;
398 
399  // Serialize, not with tags of its own, but as attributes within a tag.
400  void WriteXMLAttributes(XMLWriter &xmlFile) const;
401 
402  // Return true iff the attribute is recognized.
403  bool HandleXMLAttribute(const wxChar *attr, const wxChar *value);
404 
405 protected:
406  bool mMute { false };
407  bool mSolo { false };
408 };
409 
410 class AUDACITY_DLL_API TrackListIterator /* not final */
411 : public std::iterator< std::forward_iterator_tag, Track *const >
412 {
413  public:
414  // The default-constructed value can serve as the end iterator for
415  // traversal over any track list.
417  explicit TrackListIterator(TrackList * val);
418  explicit TrackListIterator(TrackList * val, TrackNodePointer p);
419  TrackListIterator(const TrackListIterator&) = default;
420  TrackListIterator& operator=(const TrackListIterator&) = default;
421  virtual ~TrackListIterator() {}
422 
423  // Iterate functions
424  virtual Track *First(TrackList * val = nullptr);
425  virtual Track *StartWith(Track * val);
426  virtual Track *Next(bool skiplinked = false);
427  virtual Track *Prev(bool skiplinked = false);
428  virtual Track *Last(bool skiplinked = false);
429 
430  Track *RemoveCurrent(); // deletes track, returns next
431 
432  // Provide minimal STL forward-iterator idiom:
433 
434  // unlike Next, this is non-mutating.
435  // An end iterator may be safely dereferenced, returning nullptr.
436  Track *operator * () const;
437 
438  TrackListIterator &operator++ () { (void) Next(); return *this; }
440  { auto copy = *this; operator++(); return copy; }
441 
442  bool operator == (const TrackListIterator &other) const;
443  bool operator != (const TrackListIterator &other) const
444  { return !(*this == other); }
445 
446  protected:
447  friend TrackList;
448 
449  TrackList *l {};
451 };
452 
453 class AUDACITY_DLL_API TrackListConstIterator
454 : public std::iterator< std::forward_iterator_tag, const Track *const >
455 {
456 public:
457  // The default-constructed value can serve as the end iterator for
458  // traversal over any track list.
461  const TrackList * val, TrackNodePointer p)
462  : mIter(const_cast<TrackList*>(val), p)
463  {}
465  const TrackList * val)
466  : mIter(const_cast<TrackList*>(val))
467  {}
469  TrackListConstIterator& operator=(const TrackListConstIterator&) = default;
471 
472  // Iterate functions
473  const Track *First(const TrackList * val = NULL)
474  { return mIter.First(const_cast<TrackList*>(val)); }
475  const Track *StartWith(const Track * val)
476  { return mIter.StartWith(const_cast<Track*>(val)); }
477  const Track *Next(bool skiplinked = false)
478  { return mIter.Next(skiplinked); }
479  const Track *Prev(bool skiplinked = false)
480  { return mIter.Prev(skiplinked); }
481  const Track *Last(bool skiplinked = false)
482  { return mIter.Last(skiplinked); }
483 
484  // Provide minimal STL forward-iterator idiom:
485 
486  // unlike Next, this is non-mutating.
487  // An end iterator may be safely dereferenced, returning nullptr.
488  const Track *operator * () const { return *mIter; }
489 
490  TrackListConstIterator &operator++ () { (void) Next(); return *this; }
492  { auto copy = *this; operator++(); return copy; }
493 
494  bool operator == (const TrackListConstIterator &other) const
495  { return mIter == other.mIter; }
496  bool operator != (const TrackListConstIterator &other) const
497  { return !(*this == other); }
498 
499 private:
501 };
502 
503 // TrackListCondIterator (base class for iterators that iterate over all tracks)
504 // that meet a condition)
505 class AUDACITY_DLL_API TrackListCondIterator /* not final */ : public TrackListIterator
506 {
507  public:
509  : TrackListIterator(val) {}
511 
512  // Iteration functions
513  Track *First(TrackList *val = NULL) override;
514  Track *StartWith(Track *val) override;
515  Track *Next(bool skiplinked = false) override;
516  Track *Prev(bool skiplinked = false) override;
517  Track *Last(bool skiplinked = false) override;
518 
519  protected:
520  // NEW virtual
521  virtual bool Condition(Track *t) = 0;
522 };
523 
524 //
525 // TrackListOfKindIterator
526 //
527 // Based on TrackListIterator and returns only tracks of the specified type.
528 //
529 class AUDACITY_DLL_API TrackListOfKindIterator /* not final */ : public TrackListCondIterator
530 {
531  public:
532  TrackListOfKindIterator(int kind, TrackList * val = NULL);
534 
535  protected:
536  virtual bool Condition(Track *t) override;
537 
538  private:
539  int kind;
540 };
541 
542 //
543 // SelectedTrackListOfKindIterator
544 //
545 // Based on TrackListOfKindIterator and returns only tracks selected.
546 //
547 class AUDACITY_DLL_API SelectedTrackListOfKindIterator final : public TrackListOfKindIterator
548 {
549  public:
550  SelectedTrackListOfKindIterator(int kind, TrackList * val = NULL) : TrackListOfKindIterator(kind, val) {}
552 
553  protected:
554  bool Condition(Track *t) override;
555 };
556 
557 //
558 // VisibleTrackIterator
559 //
560 // Based on TrackListIterator returns only the currently visible tracks.
561 //
562 class AUDACITY_DLL_API VisibleTrackIterator final : public TrackListCondIterator
563 {
564  public:
567 
568  protected:
569  bool Condition(Track *t) override;
570 
571  private:
573  wxRect mPanelRect;
574 };
575 
576 
577 // SyncLockedTracksIterator returns only tracks belonging to the sync-locked tracks
578 // in which the starting track is a member.
579 class AUDACITY_DLL_API SyncLockedTracksIterator final : public TrackListIterator
580 {
581  public:
584 
585  // Iterate functions
586  Track *StartWith(Track *member) override;
587  Track *Next(bool skiplinked = false) override;
588  Track *Prev(bool skiplinked = false) override;
589  Track *Last(bool skiplinked = false) override;
590 
591  private:
592  bool IsGoodNextTrack(const Track *t) const;
594 };
595 
596 
601 struct TrackListEvent : public wxCommandEvent
602 {
603  TrackListEvent(wxEventType commandType = wxEVT_NULL, int winid = 0)
604  : wxCommandEvent{ commandType, winid } {}
605 
606  TrackListEvent( const TrackListEvent& ) = default;
607 
608  wxEvent *Clone() const override { return new TrackListEvent(*this); }
609 
610  std::weak_ptr<Track> mpTrack;
611 };
612 
613 // Posted when tracks are reordered but otherwise unchanged.
614 wxDECLARE_EXPORTED_EVENT(AUDACITY_DLL_API,
615  EVT_TRACKLIST_PERMUTED, wxCommandEvent);
616 
617 // Posted when some track was added or changed its height.
618 // Cast to TrackListEvent and examine mpTrack to retrieve it.
619 wxDECLARE_EXPORTED_EVENT(AUDACITY_DLL_API,
620  EVT_TRACKLIST_RESIZING, wxCommandEvent);
621 
622 // Posted when a track has been deleted from a tracklist.
623 // Also posted when one track replaces another
624 wxDECLARE_EXPORTED_EVENT(AUDACITY_DLL_API,
625  EVT_TRACKLIST_DELETION, wxCommandEvent);
626 
627 class TrackList final : public wxEvtHandler, public ListOfTracks
628 {
629  // privatize this, make you use Swap instead:
630  using ListOfTracks::swap;
631 
632  // Create an empty TrackList
633  TrackList();
634 
635  // Disallow copy
636  TrackList(const TrackList &that) = delete;
637  TrackList &operator= (const TrackList&) = delete;
638 
639  // Allow move
640  TrackList(TrackList &&that) : TrackList() { Swap(that); }
642 
643  void clear() = delete;
644 
645  public:
646  // Create an empty TrackList
647  static std::shared_ptr<TrackList> Create();
648 
649  // Move is defined in terms of Swap
650  void Swap(TrackList &that);
651 
652  // Destructor
653  virtual ~TrackList();
654 
655  // Hide the inherited begin() and end()
658  using value_type = Track *;
659  iterator begin() { return iterator{
660  this, { ListOfTracks::begin(), this } }; }
661  iterator end() { return {}; }
662  const_iterator begin() const { return const_iterator{ this }; }
663  const_iterator end() const { return {}; }
664  const_iterator cbegin() const { return begin(); }
665  const_iterator cend() const { return end(); }
666 
667  friend class Track;
668  friend class TrackListIterator;
670 
672  void Permute(const std::vector<TrackNodePointer> &permutation);
673 
674  Track *FindById( TrackId id );
675 
677  template<typename TrackKind>
678  Track *Add(std::unique_ptr<TrackKind> &&t);
679 
681  template<typename TrackKind>
682  Track *AddToHead(std::unique_ptr<TrackKind> &&t);
683 
685  template<typename TrackKind>
686  Track *Add(std::shared_ptr<TrackKind> &&t);
687 
690  ListOfTracks::value_type Replace(Track * t, ListOfTracks::value_type &&with);
691 
695 
697  void Clear(bool sendEvent = true);
698 
700  void Select(Track * t, bool selected = true);
701 
702  Track *GetPrev(Track * t, bool linked = false) const;
703 
708  Track *GetNext(Track * t, bool linked = false) const;
709  int GetGroupHeight(const Track * t) const;
710 
711  bool CanMoveUp(Track * t) const;
712  bool CanMoveDown(Track * t) const;
713 
714  bool MoveUp(Track * t);
715  bool MoveDown(Track * t);
716  bool Move(Track * t, bool up) { return up ? MoveUp(t) : MoveDown(t); }
717 
719  const TimeTrack *GetTimeTrack() const;
720 
727  unsigned GetNumExportChannels(bool selectionOnly) const;
728 
729  WaveTrackArray GetWaveTrackArray(bool selectionOnly, bool includeMuted = true);
730  WaveTrackConstArray GetWaveTrackConstArray(bool selectionOnly, bool includeMuted = true) const;
731 
732 #if defined(USE_MIDI)
733  NoteTrackConstArray GetNoteTrackConstArray(bool selectionOnly) const;
734 #endif
735 
737  bool Contains(const Track * t) const;
738 
739  // Return non-null only if the weak pointer is not, and the track is
740  // owned by this list; constant time.
741  template <typename Subclass>
742  std::shared_ptr<Subclass> Lock(const std::weak_ptr<Subclass> &wTrack)
743  {
744  auto pTrack = wTrack.lock();
745  if (pTrack) {
746  auto pList = pTrack->mList.lock();
747  if (pTrack && this == pList.get())
748  return pTrack;
749  }
750  return {};
751  }
752 
753  bool empty() const;
754  size_t size() const;
755 
756  double GetStartTime() const;
757  double GetEndTime() const;
758 
759  double GetMinOffset() const;
760  int GetHeight() const;
761 
762 #if LEGACY_PROJECT_FILE_SUPPORT
763  // File I/O
764  bool Load(wxTextFile * in, DirManager * dirManager) override;
765  bool Save(wxTextFile * out, bool overwrite) override;
766 #endif
767 
768 private:
769  bool isNull(TrackNodePointer p) const
770  { return (p.second == this && p.first == ListOfTracks::end())
771  || (p.second == &mPendingUpdates && p.first == mPendingUpdates.end()); }
773  { return { const_cast<TrackList*>(this)->ListOfTracks::end(),
774  const_cast<TrackList*>(this)}; }
776  { return { const_cast<TrackList*>(this)->ListOfTracks::begin(),
777  const_cast<TrackList*>(this)}; }
778 
779  // Move an iterator to the next node, if any; else stay at end
781  {
782  if ( isNull(p) )
783  return p;
784  auto q = p;
785  ++q.first;
786  return q;
787  }
788 
789  // Move an iterator to the previous node, if any; else wrap to end
791  {
792  if (p == getBegin())
793  return getEnd();
794  else {
795  auto q = p;
796  --q.first;
797  return q;
798  }
799  }
800 
802  void PermutationEvent();
803  void DeletionEvent();
804  void ResizingEvent(TrackNodePointer node);
805 
807 
808  std::weak_ptr<TrackList> mSelf;
809 
810  // Nondecreasing during the session.
811  // Nonpersistent.
812  // Used to assign ids to added tracks.
813  static long sCounter;
814 
815 public:
816  using Updater = std::function< void(Track &dest, const Track &src) >;
817  // Start a deferred update of the project.
818  // The return value is a duplicate of the given track.
819  // While ApplyPendingTracks or ClearPendingTracks is not yet called,
820  // there may be other direct changes to the project that push undo history.
821  // Meanwhile the returned object can accumulate other changes for a deferred
822  // push, and temporarily shadow the actual project track for display purposes.
823  // The Updater function, if not null, merges state (from the actual project
824  // into the pending track) which is not meant to be overridden by the
825  // accumulated pending changes.
826  // To keep the display consistent, the Y and Height values, minimized state,
827  // and Linked state must be copied, and this will be done even if the
828  // Updater does not do it.
829  // Pending track will have the same TrackId as the actual.
830  // Pending changed tracks will not occur in iterations.
831  std::shared_ptr<Track> RegisterPendingChangedTrack(
832  Updater updater,
833  Track *src
834  );
835 
836  // Like the previous, but for a NEW track, not a replacement track. Caller
837  // supplies the track, and there are no updates.
838  // Pending track will have an unassigned TrackId.
839  // Pending changed tracks WILL occur in iterations, always after actual
840  // tracks, and in the sequence that they were added. They can be
841  // distinguished from actual tracks by TrackId.
842  void RegisterPendingNewTrack( const std::shared_ptr<Track> &pTrack );
843 
844  // Invoke the updaters of pending tracks. Pass any exceptions from the
845  // updater functions.
846  void UpdatePendingTracks();
847 
848  // Forget pending track additions and changes;
849  // if requested, give back the pending added tracks.
850  void ClearPendingTracks( ListOfTracks *pAdded = nullptr );
851 
852  // Change the state of the project.
853  // Strong guarantee for project state in case of exceptions.
854  // Will always clear the pending updates.
855  // Return true if the state of the track list really did change.
856  bool ApplyPendingTracks();
857 
858  bool HasPendingTracks() const;
859 
860 private:
861  // Need to put pending tracks into a list so that GetLink() works
863  // This is in correspondence with mPendingUpdates
864  std::vector< Updater > mUpdaters;
865 };
866 
867 class AUDACITY_DLL_API TrackFactory
868 {
869  private:
870  TrackFactory(const std::shared_ptr<DirManager> &dirManager, const ZoomInfo *zoomInfo):
871  mDirManager(dirManager)
872  , mZoomInfo(zoomInfo)
873  {
874  }
875 
876  const std::shared_ptr<DirManager> mDirManager;
877  const ZoomInfo *const mZoomInfo;
878  friend class AudacityProject;
879  friend class BenchmarkDialog;
880 
881  public:
882  // These methods are defined in WaveTrack.cpp, NoteTrack.cpp,
883  // LabelTrack.cpp, and TimeTrack.cpp respectively
884  std::unique_ptr<WaveTrack> DuplicateWaveTrack(const WaveTrack &orig);
885  std::unique_ptr<WaveTrack> NewWaveTrack(sampleFormat format = (sampleFormat)0,
886  double rate = 0);
887  std::unique_ptr<LabelTrack> NewLabelTrack();
888  std::unique_ptr<TimeTrack> NewTimeTrack();
889 #if defined(USE_MIDI)
890  std::unique_ptr<NoteTrack> NewNoteTrack();
891 #endif
892 };
893 
894 // global functions
895 struct TransportTracks;
896 TransportTracks GetAllPlaybackTracks(TrackList &trackList, bool selectedOnly, bool useMidi = false);
897 
898 #endif
friend TrackList
Definition: Track.h:447
bool GetSolo() const
Definition: Track.h:392
void SetId(TrackId id)
Definition: Track.h:131
virtual void SetPan(float)
Definition: Track.h:301
A list of TrackListNode items.
Definition: Track.h:627
virtual ~TrackListOfKindIterator()
Definition: Track.h:533
Creates and manages BlockFile objects.
Definition: DirManager.h:52
int GetActualHeight() const
Definition: Track.h:201
TransportTracks GetAllPlaybackTracks(TrackList &trackList, bool selectedOnly, bool useMidi=false)
Definition: Track.cpp:1585
virtual Track * Prev(bool skiplinked=false)
Definition: Track.cpp:490
ViewInfo is used mainly to hold the zooming, selection and scroll information. It also has some statu...
Definition: ViewInfo.h:141
virtual ~VisibleTrackIterator()
Definition: Track.h:566
virtual ~SyncLockedTracksIterator()
Definition: Track.h:583
bool CanMoveDown(Track *t) const
Definition: Track.cpp:1121
void Select(Track *t, bool selected=true)
Definition: Track.cpp:1027
int GetHeight() const
Definition: Track.cpp:1372
PlayableTrack(const std::shared_ptr< DirManager > &projDirManager)
Definition: Track.h:387
bool isNull(TrackNodePointer p) const
Definition: Track.h:769
double GetStartTime() const
Definition: Track.cpp:1413
int mIndex
Definition: Track.h:116
std::weak_ptr< Track > mpTrack
Definition: Track.h:610
const_iterator cend() const
Definition: Track.h:665
bool GetSelected() const
Definition: Track.h:284
TrackNodePointer mNode
Definition: Track.h:115
virtual ~TrackListIterator()
Definition: Track.h:421
virtual ~TrackListCondIterator()
Definition: Track.h:510
const Track * First(const TrackList *val=NULL)
Definition: Track.h:473
virtual void SetOffset(double o)
Definition: Track.h:298
virtual bool Condition(Track *t) override
Definition: Track.cpp:610
TrackKindEnum
Definition: Track.h:251
virtual ~SelectedTrackListOfKindIterator()
Definition: Track.h:551
TrackId GetId() const
Definition: Track.h:129
Track * Add(std::unique_ptr< TrackKind > &&t)
Add a Track, giving it a fresh id.
Definition: Track.cpp:906
int mHeight
Definition: Track.h:118
void DeletionEvent()
Definition: Track.cpp:865
double GetEndTime() const
Definition: Track.cpp:1418
void Offset(double t)
Definition: Track.h:297
bool mSelected
Definition: Track.h:122
Vector operator*(const Vector &left, const Vector &right)
Definition: Matrix.cpp:153
void RegisterPendingNewTrack(const std::shared_ptr< Track > &pTrack)
Definition: Track.cpp:1442
iterator begin()
Definition: Track.h:659
void clear()=delete
void ClearPendingTracks(ListOfTracks *pAdded=nullptr)
Definition: Track.cpp:1469
virtual int GetChannel() const
Definition: Track.h:294
std::pair< ListOfTracks::iterator, ListOfTracks * > TrackNodePointer
Definition: Track.h:65
void SwapNodes(TrackNodePointer s1, TrackNodePointer s2)
Definition: Track.cpp:1131
bool GetLinked() const
Definition: Track.h:287
std::weak_ptr< SelectHandle > mSelectHandle
Definition: Track.h:365
const std::shared_ptr< DirManager > mDirManager
Definition: Track.h:876
TrackListCondIterator(TrackList *val=NULL)
Definition: Track.h:508
static long sCounter
Definition: Track.h:813
bool MoveUp(Track *t)
Definition: Track.cpp:1198
virtual bool Condition(Track *t)=0
TrackList(TrackList &&that)
Definition: Track.h:640
TrackId()
Definition: Track.h:84
TrackNodePointer getPrev(TrackNodePointer p) const
Definition: Track.h:790
bool ApplyPendingTracks()
Definition: Track.cpp:1496
void SetChannel(int c)
Definition: Track.h:300
virtual std::shared_ptr< Track > FindTrack()=0
const std::shared_ptr< DirManager > & GetDirManager() const
Definition: Track.h:308
AudacityProject * mProject
Definition: Track.h:572
wxString mDefaultName
Definition: Track.h:120
TrackId(long value)
Definition: Track.h:85
std::shared_ptr< TrackVRulerControls > mpVRulerContols
Definition: Track.h:362
TimeTrack * GetTimeTrack()
Definition: Track.cpp:1244
TrackList & operator=(const TrackList &)=delete
const Track * Last(bool skiplinked=false)
Definition: Track.h:481
void ResizingEvent(TrackNodePointer node)
Definition: Track.cpp:872
virtual int GetKind() const
Definition: Track.h:338
static std::shared_ptr< TrackList > Create()
Definition: Track.cpp:792
void SetMute(bool m)
Definition: Track.h:393
Used to create a WaveTrack, or a LabelTrack.. Implementation of the functions of this class are dispe...
Definition: Track.h:867
PlayableTrack(const Track &orig)
Definition: Track.h:389
virtual std::vector< UIHandlePtr > HitTest(const TrackPanelMouseState &state, const AudacityProject *pProject)=0
A LabelTrack is a Track that holds labels (LabelStruct).
Definition: LabelTrack.h:113
const Track * Next(bool skiplinked=false)
Definition: Track.h:477
std::shared_ptr< Track > RegisterPendingChangedTrack(Updater updater, Track *src)
Definition: Track.cpp:1424
wxString GetDefaultName() const
Definition: Track.h:281
TrackList()
Definition: Track.cpp:786
void Swap(TrackList &that)
Definition: Track.cpp:808
AudioTrack(const std::shared_ptr< DirManager > &projDirManager)
Definition: Track.h:372
TrackList is a flat linked list of tracks supporting Add, Remove, Clear, and Contains, plus serialization of the list of tracks.
Definition: Track.h:601
AudacityProject provides the main window, with tools and tracks contained within it.
Definition: Project.h:176
A kind of Track used to 'warp time'.
Definition: TimeTrack.h:29
bool operator!=(const TrackId &other) const
Definition: Track.h:90
size_t size() const
Definition: Track.cpp:1234
std::function< void(Track &dest, const Track &src) > Updater
Definition: Track.h:816
bool CanMoveUp(Track *t) const
Definition: Track.cpp:1116
TrackPanelCellIterator::CellType & operator++(TrackPanelCellIterator::CellType &type)
int format
Definition: ExportPCM.cpp:56
WaveTrackConstArray GetWaveTrackConstArray(bool selectionOnly, bool includeMuted=true) const
Definition: Track.cpp:1349
bool HandleXMLAttribute(const wxChar *, const wxChar *)
Definition: Track.h:380
const Track * Prev(bool skiplinked=false)
Definition: Track.h:479
AudioTrack(const Track &orig)
Definition: Track.h:374
ListOfTracks mPendingUpdates
Definition: Track.h:862
Track * GetNext(Track *t, bool linked=false) const
Return a track in the list that comes after Track t.
Definition: Track.cpp:1048
wxDECLARE_EXPORTED_EVENT(AUDACITY_DLL_API, EVT_TRACKLIST_PERMUTED, wxCommandEvent)
long mValue
Definition: Track.h:99
Track * AddToHead(std::unique_ptr< TrackKind > &&t)
Add a Track, giving it a fresh id.
Definition: Track.cpp:930
std::vector< std::shared_ptr< WaveTrack > > WaveTrackArray
Definition: AudioIO.h:67
bool operator<(const TrackId &other) const
Definition: Track.h:95
void RecalcPositions(TrackNodePointer node)
Definition: Track.cpp:831
std::shared_ptr< TrackPanelResizerCell > mpResizer
Definition: Track.h:363
std::vector< std::shared_ptr< const WaveTrack > > WaveTrackConstArray
Definition: AudioIO.h:68
bool mMinimized
Definition: Track.h:125
bool Contains(const Track *t) const
Mainly a test function. Uses a linear search, so could be slow.
Definition: Track.cpp:1224
virtual void SetPanFromChannelType()
Definition: Track.h:302
bool Move(Track *t, bool up)
Definition: Track.h:716
std::shared_ptr< TrackPanelCell > ContextMenuDelegate() override
Definition: Track.h:173
A Track that can load/save audio data to/from XML.
Definition: Track.h:369
sampleFormat
Definition: Types.h:188
Track * FindById(TrackId id)
Definition: Track.cpp:894
virtual ~TrackList()
Definition: Track.cpp:826
std::weak_ptr< TimeShiftHandle > mTimeShiftHandle
Definition: Track.h:366
ListOfTracks::value_type Replace(Track *t, ListOfTracks::value_type &&with)
Definition: Track.cpp:963
std::weak_ptr< TrackList > mList
Definition: Track.h:114
A Track that contains audio waveform data.
Definition: WaveTrack.h:60
WaveTrackArray GetWaveTrackArray(bool selectionOnly, bool includeMuted=true)
Definition: Track.cpp:1344
bool HasPendingTracks() const
Definition: Track.cpp:1573
Fundamental data object of Audacity, placed in the TrackPanel. Classes derived form it include the Wa...
Definition: Track.h:102
const_iterator begin() const
Definition: Track.h:662
This class is an interface which should be implemented by classes which wish to be able to load and s...
Definition: XMLTagHandler.h:72
unsigned GetNumExportChannels(bool selectionOnly) const
Find out how many channels this track list mixes to.
Definition: Track.cpp:1260
TrackListConstIterator(const TrackList *val)
Definition: Track.h:464
wxString GetName() const
Definition: Track.h:279
virtual Track * First(TrackList *val=nullptr)
Definition: Track.cpp:418
iterator end()
Definition: Track.h:661
const_iterator cbegin() const
Definition: Track.h:664
virtual Track * Last(bool skiplinked=false)
Definition: Track.cpp:437
void Clear(bool sendEvent=true)
Make the list empty.
Definition: Track.cpp:1006
TrackNodePointer getEnd() const
Definition: Track.h:772
std::shared_ptr< Subclass > Lock(const std::weak_ptr< Subclass > &wTrack)
Definition: Track.h:742
int GetGroupHeight(const Track *t) const
Definition: Track.cpp:1105
An AudioTrack that can be played and stopped.
Definition: Track.h:384
bool MoveDown(Track *t)
Definition: Track.cpp:1211
double mOffset
Definition: Track.h:238
bool operator==(const TrackId &other) const
Definition: Track.h:87
void SetDefaultName(const wxString &n)
Definition: Track.h:282
An iterator for a TrackList.
Definition: Track.h:410
bool operator==(const TrackNodePointer &a, const TrackNodePointer &b)
Definition: Track.h:67
std::vector< std::shared_ptr< const NoteTrack > > NoteTrackConstArray
Definition: Track.h:54
bool mLinked
Definition: Track.h:124
TrackNodePointer getBegin() const
Definition: Track.h:775
double GetMinOffset() const
Definition: Track.cpp:1408
wxRect mPanelRect
Definition: Track.h:573
TrackListConstIterator(const TrackList *val, TrackNodePointer p)
Definition: Track.h:460
TrackNodePointer Remove(Track *t)
Definition: Track.cpp:985
TrackList * l
Definition: Track.h:449
WX_DEFINE_USER_EXPORTED_ARRAY(Track *, TrackArray, class AUDACITY_DLL_API)
Track * GetPrev(Track *t, bool linked=false) const
Definition: Track.cpp:1067
void SetName(const wxString &n)
Definition: Track.h:280
SelectedTrackListOfKindIterator(int kind, TrackList *val=NULL)
Definition: Track.h:550
void Permute(const std::vector< TrackNodePointer > &permutation)
For use in sorting: assume each iterator points into this list, no duplications.
Definition: Track.cpp:880
virtual Track * Next(bool skiplinked=false)
Definition: Track.cpp:460
TrackListIterator mIter
Definition: Track.h:500
void Init(const Track &orig)
Definition: Track.cpp:83
const Track * StartWith(const Track *val)
Definition: Track.h:475
void WriteXMLAttributes(XMLWriter &WXUNUSED(xmlFile)) const
Definition: Track.h:377
TrackFactory(const std::shared_ptr< DirManager > &dirManager, const ZoomInfo *zoomInfo)
Definition: Track.h:870
const ZoomInfo *const mZoomInfo
Definition: Track.h:877
bool GetMute() const
Definition: Track.h:391
Definition: Track.h:81
std::vector< Updater > mUpdaters
Definition: Track.h:864
TrackNodePointer getNext(TrackNodePointer p) const
Definition: Track.h:780
virtual Track * StartWith(Track *val)
Definition: Track.cpp:401
static std::shared_ptr< Subclass > Pointer(const Track *t)
Definition: Track.h:148
const_iterator end() const
Definition: Track.h:663
std::unique_ptr< Track > Holder
Definition: Track.h:272
TrackListEvent(wxEventType commandType=wxEVT_NULL, int winid=0)
Definition: Track.h:603
Base class for XMLFileWriter and XMLStringWriter that provides the general functionality for creating...
Definition: XMLWriter.h:22
void PermutationEvent()
Definition: Track.cpp:858
static std::shared_ptr< Subclass > Pointer(Track *t)
Definition: Track.h:137
std::list< std::shared_ptr< Track > > ListOfTracks
Definition: Track.h:62
virtual void Merge(const Track &orig)
Definition: Track.cpp:104
virtual bool GetErrorOpening()
Definition: Track.h:345
wxSize vrulerSize
Definition: Track.h:184
bool operator!=(const TrackNodePointer &a, const TrackNodePointer &b)
Definition: Track.h:70
void SetSolo(bool s)
Definition: Track.h:394
int mY
Definition: Track.h:117
friend class TrackListIterator
Definition: Track.h:668
std::shared_ptr< DirManager > mDirManager
Definition: Track.h:240
std::shared_ptr< TrackControls > mpControls
Definition: Track.h:361
std::weak_ptr< TrackList > mSelf
Definition: Track.h:808
void UpdatePendingTracks()
Definition: Track.cpp:1449
wxEvent * Clone() const override
Definition: Track.h:608
bool empty() const
Definition: Track.cpp:1229
BenchmarkDialog is used for measuring performance and accuracy of the BlockFile system.
Definition: Benchmark.cpp:46
int mChannel
Definition: Track.h:237
A Track that is used for Midi notes. (Somewhat old code).
TrackId mId
Definition: Track.h:111
wxString mName
Definition: Track.h:119