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  // Cause certain overriding tool modes (Zoom; future ones?) to behave
162  // uniformly in all tracks, disregarding track contents.
163  // Do not further override this...
164  std::vector<UIHandlePtr> HitTest
165  (const TrackPanelMouseState &, const AudacityProject *pProject)
166  final override;
167 
168  public:
169 
170  // Rather override this for subclasses:
171  virtual std::vector<UIHandlePtr> DetailedHitTest
172  (const TrackPanelMouseState &,
173  const AudacityProject *pProject, int currentTool, bool bMultiTool)
174  = 0;
175 
176  mutable wxSize vrulerSize;
177 
178  // Return another, associated TrackPanelCell object that implements the
179  // drop-down, close and minimize buttons, etc.
180  std::shared_ptr<TrackPanelCell> GetTrackControl();
181 
182  // Return another, associated TrackPanelCell object that implements the
183  // mouse actions for the vertical ruler
184  std::shared_ptr<TrackPanelCell> GetVRulerControl();
185 
186  // Return another, associated TrackPanelCell object that implements the
187  // click and drag to resize
188  std::shared_ptr<TrackPanelCell> GetResizer();
189 
190  // This just returns a constant and can be overriden by subclasses
191  // to specify a different height for the case that the track is minimized.
192  virtual int GetMinimizedHeight() const;
193  int GetActualHeight() const { return mHeight; }
194 
195  int GetIndex() const;
196  void SetIndex(int index);
197 
198  int GetY() const;
199 private:
200  // Always maintain a strictly contiguous layout of tracks.
201  // So client code is not permitted to modify this attribute directly.
202  void SetY(int y);
203  // No need yet to make this virtual
204  void DoSetY(int y);
205 public:
206 
207  int GetHeight() const;
208  void SetHeight(int h);
209 protected:
210  virtual void DoSetHeight(int h);
211 public:
212 
213  bool GetMinimized() const;
214  void SetMinimized(bool isMinimized);
215 protected:
216  virtual void DoSetMinimized(bool isMinimized);
217 public:
218 
219  Track *GetLink() const;
220 
221  private:
222  TrackNodePointer GetNode() const;
223  void SetOwner
224  (const std::weak_ptr<TrackList> &list, TrackNodePointer node);
225 
226  // Keep in Track
227 
228  protected:
229  int mChannel;
230  double mOffset;
231 
232  mutable std::shared_ptr<DirManager> mDirManager;
233 
234  public:
235 
236  enum
237  {
238  LeftChannel = 0,
239  RightChannel = 1,
240  MonoChannel = 2
241  };
242 
244  {
247 #if defined(USE_MIDI)
248  Note,
249 #endif
252  All
253  };
254 
255  enum : unsigned { DefaultHeight = 150 };
256 
257  Track(const std::shared_ptr<DirManager> &projDirManager);
258  Track(const Track &orig);
259 
260  virtual ~ Track();
261 
262  void Init(const Track &orig);
263 
264  using Holder = std::unique_ptr<Track>;
265  virtual Holder Duplicate() const = 0;
266 
267  // Called when this track is merged to stereo with another, and should
268  // take on some paramaters of its partner.
269  virtual void Merge(const Track &orig);
270 
271  wxString GetName() const { return mName; }
272  void SetName( const wxString &n ) { mName = n; }
273  wxString GetDefaultName() const { return mDefaultName; }
274  void SetDefaultName( const wxString &n ) { mDefaultName = n; }
275 
276  bool GetSelected() const { return mSelected; }
277  virtual void SetSelected(bool s);
278 
279  bool GetLinked () const { return mLinked; }
280  void SetLinked (bool l);
281 private:
282  // No need yet to make this virtual
283  void DoSetLinked(bool l);
284 public:
285 
286  virtual int GetChannel() const { return mChannel;};
287  virtual double GetOffset() const = 0;
288 
289  void Offset(double t) { SetOffset(GetOffset() + t); }
290  virtual void SetOffset (double o) { mOffset = o; }
291 
292  void SetChannel(int c) { mChannel = c; }
293  virtual void SetPan( float ){ ;}
294  virtual void SetPanFromChannelType(){ ;};
295 
296  // AS: Note that the dirManager is mutable. This is
297  // mostly to support "Duplicate" of const objects,
298  // but in general, mucking with the dir manager is
299  // separate from the Track.
300  const std::shared_ptr<DirManager> &GetDirManager() const { return mDirManager; }
301 
302  // Create a NEW track and modify this track
303  // Return non-NULL or else throw
304  // May assume precondition: t0 <= t1
305  virtual Holder Cut(double WXUNUSED(t0), double WXUNUSED(t1)) = 0;
306 
307  // Create a NEW track and don't modify this track
308  // Return non-NULL or else throw
309  // Note that subclasses may want to distinguish tracks stored in a clipboard
310  // from those stored in a project
311  // May assume precondition: t0 <= t1
312  virtual Holder Copy
313  (double WXUNUSED(t0), double WXUNUSED(t1), bool forClipboard = true) const = 0;
314 
315  // May assume precondition: t0 <= t1
316  virtual void Clear(double WXUNUSED(t0), double WXUNUSED(t1)) = 0;
317 
318  virtual void Paste(double WXUNUSED(t), const Track * WXUNUSED(src)) = 0;
319 
320  // This can be used to adjust a sync-lock selected track when the selection
321  // is replaced by one of a different length.
322  virtual void SyncLockAdjust(double oldT1, double newT1);
323 
324  // May assume precondition: t0 <= t1
325  virtual void Silence(double WXUNUSED(t0), double WXUNUSED(t1)) = 0;
326 
327  // May assume precondition: t0 <= t1
328  virtual void InsertSilence(double WXUNUSED(t), double WXUNUSED(len)) = 0;
329 
330  virtual int GetKind() const { return None; }
331 
332  // XMLTagHandler callback methods -- NEW virtual for writing
333  virtual void WriteXML(XMLWriter &xmlFile) const = 0;
334 
335  // Returns true if an error was encountered while trying to
336  // open the track from XML
337  virtual bool GetErrorOpening() { return false; }
338 
339  virtual double GetStartTime() const = 0;
340  virtual double GetEndTime() const = 0;
341 
342  // Checks if sync-lock is on and any track in its sync-lock group is selected.
343  bool IsSyncLockSelected() const;
344 
345 protected:
346  std::shared_ptr<Track> FindTrack() override;
347 
348  // These are called to create controls on demand:
349  virtual std::shared_ptr<TrackControls> GetControls() = 0;
350  virtual std::shared_ptr<TrackVRulerControls> GetVRulerControls() = 0;
351 
352  // These hold the controls:
353  std::shared_ptr<TrackControls> mpControls;
354  std::shared_ptr<TrackVRulerControls> mpVRulerContols;
355  std::shared_ptr<TrackPanelResizerCell> mpResizer;
356 
357  std::weak_ptr<SelectHandle> mSelectHandle;
358  std::weak_ptr<TimeShiftHandle> mTimeShiftHandle;
359 };
360 
361 class AUDACITY_DLL_API AudioTrack /* not final */ : public Track
362 {
363 public:
364  AudioTrack(const std::shared_ptr<DirManager> &projDirManager)
365  : Track{ projDirManager } {}
366  AudioTrack(const Track &orig) : Track{ orig } {}
367 
368  // Serialize, not with tags of its own, but as attributes within a tag.
369  void WriteXMLAttributes(XMLWriter &WXUNUSED(xmlFile)) const {}
370 
371  // Return true iff the attribute is recognized.
372  bool HandleXMLAttribute(const wxChar * /*attr*/, const wxChar * /*value*/)
373  { return false; }
374 };
375 
376 class AUDACITY_DLL_API PlayableTrack /* not final */ : public AudioTrack
377 {
378 public:
379  PlayableTrack(const std::shared_ptr<DirManager> &projDirManager)
380  : AudioTrack{ projDirManager } {}
381  PlayableTrack(const Track &orig) : AudioTrack{ orig } {}
382 
383  bool GetMute () const { return mMute; }
384  bool GetSolo () const { return mSolo; }
385  void SetMute (bool m) { mMute = m; }
386  void SetSolo (bool s) { mSolo = s; }
387 
388  void Init( const PlayableTrack &init );
389  void Merge( const Track &init ) override;
390 
391  // Serialize, not with tags of its own, but as attributes within a tag.
392  void WriteXMLAttributes(XMLWriter &xmlFile) const;
393 
394  // Return true iff the attribute is recognized.
395  bool HandleXMLAttribute(const wxChar *attr, const wxChar *value);
396 
397 protected:
398  bool mMute { false };
399  bool mSolo { false };
400 };
401 
402 class AUDACITY_DLL_API TrackListIterator /* not final */
403 : public std::iterator< std::forward_iterator_tag, Track *const >
404 {
405  public:
406  // The default-constructed value can serve as the end iterator for
407  // traversal over any track list.
409  explicit TrackListIterator(TrackList * val);
410  explicit TrackListIterator(TrackList * val, TrackNodePointer p);
411  TrackListIterator(const TrackListIterator&) = default;
412  TrackListIterator& operator=(const TrackListIterator&) = default;
413  virtual ~TrackListIterator() {}
414 
415  // Iterate functions
416  virtual Track *First(TrackList * val = nullptr);
417  virtual Track *StartWith(Track * val);
418  virtual Track *Next(bool skiplinked = false);
419  virtual Track *Prev(bool skiplinked = false);
420  virtual Track *Last(bool skiplinked = false);
421 
422  Track *RemoveCurrent(); // deletes track, returns next
423 
424  // Provide minimal STL forward-iterator idiom:
425 
426  // unlike Next, this is non-mutating.
427  // An end iterator may be safely dereferenced, returning nullptr.
428  Track *operator * () const;
429 
430  TrackListIterator &operator++ () { (void) Next(); return *this; }
432  { auto copy = *this; operator++(); return copy; }
433 
434  bool operator == (const TrackListIterator &other) const;
435  bool operator != (const TrackListIterator &other) const
436  { return !(*this == other); }
437 
438  protected:
439  friend TrackList;
440 
441  TrackList *l {};
443 };
444 
445 class AUDACITY_DLL_API TrackListConstIterator
446 : public std::iterator< std::forward_iterator_tag, const Track *const >
447 {
448 public:
449  // The default-constructed value can serve as the end iterator for
450  // traversal over any track list.
453  const TrackList * val, TrackNodePointer p)
454  : mIter(const_cast<TrackList*>(val), p)
455  {}
457  const TrackList * val)
458  : mIter(const_cast<TrackList*>(val))
459  {}
461  TrackListConstIterator& operator=(const TrackListConstIterator&) = default;
463 
464  // Iterate functions
465  const Track *First(const TrackList * val = NULL)
466  { return mIter.First(const_cast<TrackList*>(val)); }
467  const Track *StartWith(const Track * val)
468  { return mIter.StartWith(const_cast<Track*>(val)); }
469  const Track *Next(bool skiplinked = false)
470  { return mIter.Next(skiplinked); }
471  const Track *Prev(bool skiplinked = false)
472  { return mIter.Prev(skiplinked); }
473  const Track *Last(bool skiplinked = false)
474  { return mIter.Last(skiplinked); }
475 
476  // Provide minimal STL forward-iterator idiom:
477 
478  // unlike Next, this is non-mutating.
479  // An end iterator may be safely dereferenced, returning nullptr.
480  const Track *operator * () const { return *mIter; }
481 
482  TrackListConstIterator &operator++ () { (void) Next(); return *this; }
484  { auto copy = *this; operator++(); return copy; }
485 
486  bool operator == (const TrackListConstIterator &other) const
487  { return mIter == other.mIter; }
488  bool operator != (const TrackListConstIterator &other) const
489  { return !(*this == other); }
490 
491 private:
493 };
494 
495 // TrackListCondIterator (base class for iterators that iterate over all tracks)
496 // that meet a condition)
497 class AUDACITY_DLL_API TrackListCondIterator /* not final */ : public TrackListIterator
498 {
499  public:
501  : TrackListIterator(val) {}
503 
504  // Iteration functions
505  Track *First(TrackList *val = NULL) override;
506  Track *StartWith(Track *val) override;
507  Track *Next(bool skiplinked = false) override;
508  Track *Prev(bool skiplinked = false) override;
509  Track *Last(bool skiplinked = false) override;
510 
511  protected:
512  // NEW virtual
513  virtual bool Condition(Track *t) = 0;
514 };
515 
516 //
517 // TrackListOfKindIterator
518 //
519 // Based on TrackListIterator and returns only tracks of the specified type.
520 //
521 class AUDACITY_DLL_API TrackListOfKindIterator /* not final */ : public TrackListCondIterator
522 {
523  public:
524  TrackListOfKindIterator(int kind, TrackList * val = NULL);
526 
527  protected:
528  virtual bool Condition(Track *t) override;
529 
530  private:
531  int kind;
532 };
533 
534 //
535 // SelectedTrackListOfKindIterator
536 //
537 // Based on TrackListOfKindIterator and returns only tracks selected.
538 //
539 class AUDACITY_DLL_API SelectedTrackListOfKindIterator final : public TrackListOfKindIterator
540 {
541  public:
542  SelectedTrackListOfKindIterator(int kind, TrackList * val = NULL) : TrackListOfKindIterator(kind, val) {}
544 
545  protected:
546  bool Condition(Track *t) override;
547 };
548 
549 //
550 // VisibleTrackIterator
551 //
552 // Based on TrackListIterator returns only the currently visible tracks.
553 //
554 class AUDACITY_DLL_API VisibleTrackIterator final : public TrackListCondIterator
555 {
556  public:
559 
560  protected:
561  bool Condition(Track *t) override;
562 
563  private:
565  wxRect mPanelRect;
566 };
567 
568 
569 // SyncLockedTracksIterator returns only tracks belonging to the sync-locked tracks
570 // in which the starting track is a member.
571 class AUDACITY_DLL_API SyncLockedTracksIterator final : public TrackListIterator
572 {
573  public:
576 
577  // Iterate functions
578  Track *StartWith(Track *member) override;
579  Track *Next(bool skiplinked = false) override;
580  Track *Prev(bool skiplinked = false) override;
581  Track *Last(bool skiplinked = false) override;
582 
583  private:
584  bool IsGoodNextTrack(const Track *t) const;
586 };
587 
588 
593 struct TrackListEvent : public wxCommandEvent
594 {
595  TrackListEvent(wxEventType commandType = wxEVT_NULL, int winid = 0)
596  : wxCommandEvent{ commandType, winid } {}
597 
598  TrackListEvent( const TrackListEvent& ) = default;
599 
600  wxEvent *Clone() const override { return new TrackListEvent(*this); }
601 
602  std::weak_ptr<Track> mpTrack;
603 };
604 
605 // Posted when tracks are reordered but otherwise unchanged.
606 wxDECLARE_EXPORTED_EVENT(AUDACITY_DLL_API,
607  EVT_TRACKLIST_PERMUTED, wxCommandEvent);
608 
609 // Posted when some track was added or changed its height.
610 // Cast to TrackListEvent and examine mpTrack to retrieve it.
611 wxDECLARE_EXPORTED_EVENT(AUDACITY_DLL_API,
612  EVT_TRACKLIST_RESIZING, wxCommandEvent);
613 
614 // Posted when a track has been deleted from a tracklist.
615 // Also posted when one track replaces another
616 wxDECLARE_EXPORTED_EVENT(AUDACITY_DLL_API,
617  EVT_TRACKLIST_DELETION, wxCommandEvent);
618 
619 class TrackList final : public wxEvtHandler, public ListOfTracks
620 {
621  // privatize this, make you use Swap instead:
622  using ListOfTracks::swap;
623 
624  // Create an empty TrackList
625  TrackList();
626 
627  // Disallow copy
628  TrackList(const TrackList &that) = delete;
629  TrackList &operator= (const TrackList&) = delete;
630 
631  // Allow move
632  TrackList(TrackList &&that) : TrackList() { Swap(that); }
634 
635  void clear() = delete;
636 
637  public:
638  // Create an empty TrackList
639  static std::shared_ptr<TrackList> Create();
640 
641  // Move is defined in terms of Swap
642  void Swap(TrackList &that);
643 
644  // Destructor
645  virtual ~TrackList();
646 
647  // Hide the inherited begin() and end()
650  using value_type = Track *;
651  iterator begin() { return iterator{
652  this, { ListOfTracks::begin(), this } }; }
653  iterator end() { return {}; }
654  const_iterator begin() const { return const_iterator{ this }; }
655  const_iterator end() const { return {}; }
656  const_iterator cbegin() const { return begin(); }
657  const_iterator cend() const { return end(); }
658 
659  friend class Track;
660  friend class TrackListIterator;
662 
664  void Permute(const std::vector<TrackNodePointer> &permutation);
665 
666  Track *FindById( TrackId id );
667 
669  template<typename TrackKind>
670  Track *Add(std::unique_ptr<TrackKind> &&t);
671 
673  template<typename TrackKind>
674  Track *AddToHead(std::unique_ptr<TrackKind> &&t);
675 
677  template<typename TrackKind>
678  Track *Add(std::shared_ptr<TrackKind> &&t);
679 
682  ListOfTracks::value_type Replace(Track * t, ListOfTracks::value_type &&with);
683 
687 
689  void Clear(bool sendEvent = true);
690 
692  void Select(Track * t, bool selected = true);
693 
694  Track *GetPrev(Track * t, bool linked = false) const;
695 
700  Track *GetNext(Track * t, bool linked = false) const;
701  int GetGroupHeight(Track * t) const;
702 
703  bool CanMoveUp(Track * t) const;
704  bool CanMoveDown(Track * t) const;
705 
706  bool MoveUp(Track * t);
707  bool MoveDown(Track * t);
708  bool Move(Track * t, bool up) { return up ? MoveUp(t) : MoveDown(t); }
709 
711  const TimeTrack *GetTimeTrack() const;
712 
719  unsigned GetNumExportChannels(bool selectionOnly) const;
720 
721  WaveTrackArray GetWaveTrackArray(bool selectionOnly, bool includeMuted = true);
722  WaveTrackConstArray GetWaveTrackConstArray(bool selectionOnly, bool includeMuted = true) const;
723 
724 #if defined(USE_MIDI)
725  NoteTrackConstArray GetNoteTrackConstArray(bool selectionOnly) const;
726 #endif
727 
729  bool Contains(const Track * t) const;
730 
731  // Return non-null only if the weak pointer is not, and the track is
732  // owned by this list; constant time.
733  template <typename Subclass>
734  std::shared_ptr<Subclass> Lock(const std::weak_ptr<Subclass> &wTrack)
735  {
736  auto pTrack = wTrack.lock();
737  if (pTrack) {
738  auto pList = pTrack->mList.lock();
739  if (pTrack && this == pList.get())
740  return pTrack;
741  }
742  return {};
743  }
744 
745  bool empty() const;
746  size_t size() const;
747 
748  double GetStartTime() const;
749  double GetEndTime() const;
750 
751  double GetMinOffset() const;
752  int GetHeight() const;
753 
754 #if LEGACY_PROJECT_FILE_SUPPORT
755  // File I/O
756  bool Load(wxTextFile * in, DirManager * dirManager) override;
757  bool Save(wxTextFile * out, bool overwrite) override;
758 #endif
759 
760 private:
761  bool isNull(TrackNodePointer p) const
762  { return (p.second == this && p.first == ListOfTracks::end())
763  || (p.second == &mPendingUpdates && p.first == mPendingUpdates.end()); }
765  { return { const_cast<TrackList*>(this)->ListOfTracks::end(),
766  const_cast<TrackList*>(this)}; }
768  { return { const_cast<TrackList*>(this)->ListOfTracks::begin(),
769  const_cast<TrackList*>(this)}; }
770 
771  // Move an iterator to the next node, if any; else stay at end
773  {
774  if ( isNull(p) )
775  return p;
776  auto q = p;
777  ++q.first;
778  return q;
779  }
780 
781  // Move an iterator to the previous node, if any; else wrap to end
783  {
784  if (p == getBegin())
785  return getEnd();
786  else {
787  auto q = p;
788  --q.first;
789  return q;
790  }
791  }
792 
794  void PermutationEvent();
795  void DeletionEvent();
796  void ResizingEvent(TrackNodePointer node);
797 
799 
800  std::weak_ptr<TrackList> mSelf;
801 
802  // Nondecreasing during the session.
803  // Nonpersistent.
804  // Used to assign ids to added tracks.
805  static long sCounter;
806 
807 public:
808  using Updater = std::function< void(Track &dest, const Track &src) >;
809  // Start a deferred update of the project.
810  // The return value is a duplicate of the given track.
811  // While ApplyPendingTracks or ClearPendingTracks is not yet called,
812  // there may be other direct changes to the project that push undo history.
813  // Meanwhile the returned object can accumulate other changes for a deferred
814  // push, and temporarily shadow the actual project track for display purposes.
815  // The Updater function, if not null, merges state (from the actual project
816  // into the pending track) which is not meant to be overridden by the
817  // accumulated pending changes.
818  // To keep the display consistent, the Y and Height values, minimized state,
819  // and Linked state must be copied, and this will be done even if the
820  // Updater does not do it.
821  // Pending track will have the same TrackId as the actual.
822  // Pending changed tracks will not occur in iterations.
823  std::shared_ptr<Track> RegisterPendingChangedTrack(
824  Updater updater,
825  Track *src
826  );
827 
828  // Like the previous, but for a NEW track, not a replacement track. Caller
829  // supplies the track, and there are no updates.
830  // Pending track will have an unassigned TrackId.
831  // Pending changed tracks WILL occur in iterations, always after actual
832  // tracks, and in the sequence that they were added. They can be
833  // distinguished from actual tracks by TrackId.
834  void RegisterPendingNewTrack( const std::shared_ptr<Track> &pTrack );
835 
836  // Invoke the updaters of pending tracks. Pass any exceptions from the
837  // updater functions.
838  void UpdatePendingTracks();
839 
840  // Forget pending track additions and changes;
841  // if requested, give back the pending added tracks.
842  void ClearPendingTracks( ListOfTracks *pAdded = nullptr );
843 
844  // Change the state of the project.
845  // Strong guarantee for project state in case of exceptions.
846  // Will always clear the pending updates.
847  // Return true if the state of the track list really did change.
848  bool ApplyPendingTracks();
849 
850  // Find anything registered with RegisterPendingChangedTrack and not yet
851  // cleared or applied
852  std::shared_ptr<Track> FindPendingChangedTrack(TrackId id) const;
853 
854  bool HasPendingTracks() const;
855 
856 private:
857  // Need to put pending tracks into a list so that GetLink() works
859  // This is in correspondence with mPendingUpdates
860  std::vector< Updater > mUpdaters;
861 };
862 
863 class AUDACITY_DLL_API TrackFactory
864 {
865  private:
866  TrackFactory(const std::shared_ptr<DirManager> &dirManager, const ZoomInfo *zoomInfo):
867  mDirManager(dirManager)
868  , mZoomInfo(zoomInfo)
869  {
870  }
871 
872  const std::shared_ptr<DirManager> mDirManager;
873  const ZoomInfo *const mZoomInfo;
874  friend class AudacityProject;
875  friend class BenchmarkDialog;
876 
877  public:
878  // These methods are defined in WaveTrack.cpp, NoteTrack.cpp,
879  // LabelTrack.cpp, and TimeTrack.cpp respectively
880  std::unique_ptr<WaveTrack> DuplicateWaveTrack(const WaveTrack &orig);
881  std::unique_ptr<WaveTrack> NewWaveTrack(sampleFormat format = (sampleFormat)0,
882  double rate = 0);
883  std::unique_ptr<LabelTrack> NewLabelTrack();
884  std::unique_ptr<TimeTrack> NewTimeTrack();
885 #if defined(USE_MIDI)
886  std::unique_ptr<NoteTrack> NewNoteTrack();
887 #endif
888 };
889 
890 // global functions
891 struct TransportTracks;
892 TransportTracks GetAllPlaybackTracks(const TrackList &trackList, bool selectedOnly, bool useMidi = false);
893 
894 #endif
friend TrackList
Definition: Track.h:439
bool GetSolo() const
Definition: Track.h:384
void SetId(TrackId id)
Definition: Track.h:131
virtual void SetPan(float)
Definition: Track.h:293
A list of TrackListNode items.
Definition: Track.h:619
virtual ~TrackListOfKindIterator()
Definition: Track.h:525
Creates and manages BlockFile objects.
Definition: DirManager.h:52
int GetActualHeight() const
Definition: Track.h:193
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:558
virtual ~SyncLockedTracksIterator()
Definition: Track.h:575
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:379
bool isNull(TrackNodePointer p) const
Definition: Track.h:761
double GetStartTime() const
Definition: Track.cpp:1413
int mIndex
Definition: Track.h:116
std::weak_ptr< Track > mpTrack
Definition: Track.h:602
const_iterator cend() const
Definition: Track.h:657
bool GetSelected() const
Definition: Track.h:276
TrackNodePointer mNode
Definition: Track.h:115
virtual ~TrackListIterator()
Definition: Track.h:413
virtual ~TrackListCondIterator()
Definition: Track.h:502
const Track * First(const TrackList *val=NULL)
Definition: Track.h:465
virtual void SetOffset(double o)
Definition: Track.h:290
virtual bool Condition(Track *t) override
Definition: Track.cpp:610
TrackKindEnum
Definition: Track.h:243
virtual ~SelectedTrackListOfKindIterator()
Definition: Track.h:543
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:289
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:651
void clear()=delete
void ClearPendingTracks(ListOfTracks *pAdded=nullptr)
Definition: Track.cpp:1469
virtual int GetChannel() const
Definition: Track.h:286
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:279
std::weak_ptr< SelectHandle > mSelectHandle
Definition: Track.h:357
const std::shared_ptr< DirManager > mDirManager
Definition: Track.h:872
TrackListCondIterator(TrackList *val=NULL)
Definition: Track.h:500
static long sCounter
Definition: Track.h:805
bool MoveUp(Track *t)
Definition: Track.cpp:1198
virtual bool Condition(Track *t)=0
TrackList(TrackList &&that)
Definition: Track.h:632
TrackId()
Definition: Track.h:84
TrackNodePointer getPrev(TrackNodePointer p) const
Definition: Track.h:782
bool ApplyPendingTracks()
Definition: Track.cpp:1496
void SetChannel(int c)
Definition: Track.h:292
virtual std::shared_ptr< Track > FindTrack()=0
const std::shared_ptr< DirManager > & GetDirManager() const
Definition: Track.h:300
AudacityProject * mProject
Definition: Track.h:564
wxString mDefaultName
Definition: Track.h:120
TrackId(long value)
Definition: Track.h:85
std::shared_ptr< TrackVRulerControls > mpVRulerContols
Definition: Track.h:354
TimeTrack * GetTimeTrack()
Definition: Track.cpp:1244
TrackList & operator=(const TrackList &)=delete
const Track * Last(bool skiplinked=false)
Definition: Track.h:473
void ResizingEvent(TrackNodePointer node)
Definition: Track.cpp:872
virtual int GetKind() const
Definition: Track.h:330
static std::shared_ptr< TrackList > Create()
Definition: Track.cpp:792
void SetMute(bool m)
Definition: Track.h:385
Used to create a WaveTrack, or a LabelTrack.. Implementation of the functions of this class are dispe...
Definition: Track.h:863
PlayableTrack(const Track &orig)
Definition: Track.h:381
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:469
std::shared_ptr< Track > RegisterPendingChangedTrack(Updater updater, Track *src)
Definition: Track.cpp:1424
wxString GetDefaultName() const
Definition: Track.h:273
TrackList()
Definition: Track.cpp:786
void Swap(TrackList &that)
Definition: Track.cpp:808
AudioTrack(const std::shared_ptr< DirManager > &projDirManager)
Definition: Track.h:364
TrackList is a flat linked list of tracks supporting Add, Remove, Clear, and Contains, plus serialization of the list of tracks.
Definition: Track.h:593
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:808
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:372
const Track * Prev(bool skiplinked=false)
Definition: Track.h:471
AudioTrack(const Track &orig)
Definition: Track.h:366
ListOfTracks mPendingUpdates
Definition: Track.h:858
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:66
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:355
std::vector< std::shared_ptr< const WaveTrack > > WaveTrackConstArray
Definition: AudioIO.h:67
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:294
bool Move(Track *t, bool up)
Definition: Track.h:708
A Track that can load/save audio data to/from XML.
Definition: Track.h:361
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:358
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:1567
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:654
std::shared_ptr< Track > FindPendingChangedTrack(TrackId id) const
Definition: Track.cpp:1557
This class is an interface which should be implemented by classes which wish to be able to load and s...
Definition: XMLTagHandler.h:70
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:456
wxString GetName() const
Definition: Track.h:271
virtual Track * First(TrackList *val=nullptr)
Definition: Track.cpp:418
iterator end()
Definition: Track.h:653
const_iterator cbegin() const
Definition: Track.h:656
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:764
std::shared_ptr< Subclass > Lock(const std::weak_ptr< Subclass > &wTrack)
Definition: Track.h:734
An AudioTrack that can be played and stopped.
Definition: Track.h:376
bool MoveDown(Track *t)
Definition: Track.cpp:1211
double mOffset
Definition: Track.h:230
bool operator==(const TrackId &other) const
Definition: Track.h:87
void SetDefaultName(const wxString &n)
Definition: Track.h:274
An iterator for a TrackList.
Definition: Track.h:402
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:767
double GetMinOffset() const
Definition: Track.cpp:1408
wxRect mPanelRect
Definition: Track.h:565
int GetGroupHeight(Track *t) const
Definition: Track.cpp:1105
TrackListConstIterator(const TrackList *val, TrackNodePointer p)
Definition: Track.h:452
TrackNodePointer Remove(Track *t)
Definition: Track.cpp:985
TrackList * l
Definition: Track.h:441
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:272
SelectedTrackListOfKindIterator(int kind, TrackList *val=NULL)
Definition: Track.h:542
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:492
TransportTracks GetAllPlaybackTracks(const TrackList &trackList, bool selectedOnly, bool useMidi=false)
Definition: Track.cpp:1579
void Init(const Track &orig)
Definition: Track.cpp:83
const Track * StartWith(const Track *val)
Definition: Track.h:467
void WriteXMLAttributes(XMLWriter &WXUNUSED(xmlFile)) const
Definition: Track.h:369
TrackFactory(const std::shared_ptr< DirManager > &dirManager, const ZoomInfo *zoomInfo)
Definition: Track.h:866
const ZoomInfo *const mZoomInfo
Definition: Track.h:873
bool GetMute() const
Definition: Track.h:383
Definition: Track.h:81
std::vector< Updater > mUpdaters
Definition: Track.h:860
TrackNodePointer getNext(TrackNodePointer p) const
Definition: Track.h:772
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:655
std::unique_ptr< Track > Holder
Definition: Track.h:264
TrackListEvent(wxEventType commandType=wxEVT_NULL, int winid=0)
Definition: Track.h:595
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:337
wxSize vrulerSize
Definition: Track.h:176
bool operator!=(const TrackNodePointer &a, const TrackNodePointer &b)
Definition: Track.h:70
void SetSolo(bool s)
Definition: Track.h:386
int mY
Definition: Track.h:117
friend class TrackListIterator
Definition: Track.h:660
std::shared_ptr< DirManager > mDirManager
Definition: Track.h:232
std::shared_ptr< TrackControls > mpControls
Definition: Track.h:353
std::weak_ptr< TrackList > mSelf
Definition: Track.h:800
void UpdatePendingTracks()
Definition: Track.cpp:1449
wxEvent * Clone() const override
Definition: Track.h:600
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:229
A Track that is used for Midi notes. (Somewhat old code).
TrackId mId
Definition: Track.h:111
wxString mName
Definition: Track.h:119