Audacity 3.2.0
WaveTrack.h
Go to the documentation of this file.
1/**********************************************************************
2
3 Audacity: A Digital Audio Editor
4
5 WaveTrack.h
6
7 Dominic Mazzoni
8
9**********************************************************************/
10
11#ifndef __AUDACITY_WAVETRACK__
12#define __AUDACITY_WAVETRACK__
13
14#include "ClipInterface.h"
15#include "PlaybackDirection.h"
16#include "Prefs.h"
17#include "SampleCount.h"
18#include "SampleFormat.h"
19#include "SampleTrack.h"
20#include "WideSampleSequence.h"
21
22#include <vector>
23#include <functional>
24#include <wx/thread.h>
25#include <wx/longlong.h>
26
27class AudacityProject;
28
29namespace BasicUI{ class ProgressDialog; }
30
32using SampleBlockFactoryPtr = std::shared_ptr<SampleBlockFactory>;
33
34class TimeWarper;
35
36class ClipInterface;
37class Sequence;
38class WaveClip;
40
42using WaveClipHolder = std::shared_ptr<WaveClip>;
43using WaveClipHolders = std::vector<WaveClipHolder>;
44using WaveClipConstHolders = std::vector < std::shared_ptr< const WaveClip > >;
45
46using ClipConstHolders = std::vector<std::shared_ptr<const ClipInterface>>;
47
48// Temporary arrays of mere pointers
49using WaveClipPointers = std::vector < WaveClip* >;
50using WaveClipConstPointers = std::vector < const WaveClip* >;
51
52using ChannelSampleView = std::vector<AudioSegmentSampleView>;
53using ChannelGroupSampleView = std::vector<ChannelSampleView>;
54
55using TimeInterval = std::pair<double, double>;
56using ProgressReporter = std::function<void(double)>;
57
58//
59// Tolerance for merging wave tracks (in seconds)
60//
61#define WAVETRACK_MERGE_POINT_TOLERANCE 0.01
62
63class Envelope;
64class WaveTrack;
65
66class WAVE_TRACK_API WaveChannelInterval final
67 : public ChannelInterval
68 , public ClipTimes
69{
70public:
72 WaveChannelInterval(WaveClip &wideClip, WaveClip &narrowClip, size_t iChannel
73 ) : mWideClip{ wideClip }
74 , mNarrowClip{ narrowClip }
75 , miChannel{ iChannel }
76 {}
78
79 const WaveClip &GetClip() const { return mWideClip; }
80 const Envelope &GetEnvelope() const;
81 size_t GetChannelIndex() const { return miChannel; }
82
83 bool Intersects(double t0, double t1) const;
84 double Start() const;
85 double End() const;
86
98 GetSampleView(double t0, double t1, bool mayThrow) const;
99
100 sampleCount GetVisibleSampleCount() const override;
101 int GetRate() const override;
102 double GetPlayStartTime() const override;
103 double GetPlayEndTime() const override;
104 sampleCount TimeToSamples(double time) const override;
105 double GetStretchRatio() const override;
106
107 double GetTrimLeft() const;
108 double GetTrimRight() const;
109
110 bool GetSamples(samplePtr buffer, sampleFormat format,
111 sampleCount start, size_t len, bool mayThrow = true) const;
112
113 AudioSegmentSampleView GetSampleView(
114 sampleCount start, size_t length, bool mayThrow) const;
115
116 const Sequence &GetSequence() const;
117
118 constSamplePtr GetAppendBuffer() const;
119 size_t GetAppendBufferLen() const;
120
121 int GetColourIndex() const;
122
123private:
124 const WaveClip &GetNarrowClip() const { return mNarrowClip; }
125
128 const size_t miChannel;
129};
130
131class WAVE_TRACK_API WaveChannel
132 : public Channel
133 // TODO wide wave tracks -- remove "virtual"
134 , public virtual WideSampleSequence
135{
136public:
137 ~WaveChannel() override;
138
139 inline WaveTrack &GetTrack();
140 inline const WaveTrack &GetTrack() const;
141
142 auto GetInterval(size_t iInterval) { return
143 ::Channel::GetInterval<WaveChannelInterval>(iInterval); }
144 auto GetInterval(size_t iInterval) const { return
145 ::Channel::GetInterval<const WaveChannelInterval>(iInterval); }
146
147 auto Intervals() { return ::Channel::Intervals<WaveChannelInterval>(); }
148 auto Intervals() const {
149 return ::Channel::Intervals<const WaveChannelInterval>(); }
150
152
154 bool GetFloats(float *buffer, sampleCount start, size_t len,
155 fillFormat fill = FillFormat::fillZero, bool mayThrow = true,
156 sampleCount * pNumWithinClips = nullptr) const
157 {
158 constexpr auto backwards = false;
159 return GetFloats(
160 0, 1, &buffer, start, len, backwards, fill, mayThrow, pNumWithinClips);
161 }
162
173 ChannelSampleView GetSampleView(double t0, double t1, bool mayThrow) const;
174
176 [[nodiscard]] bool Set(constSamplePtr buffer, sampleFormat format,
177 sampleCount start, size_t len,
178 sampleFormat effectiveFormat = widestSampleFormat
184 );
185
186 bool AppendBuffer(constSamplePtr buffer, sampleFormat format, size_t len, unsigned stride, sampleFormat effectiveFormat);
187
194 bool Append(constSamplePtr buffer, sampleFormat format, size_t len);
195
196 // Get signed min and max sample values
200 std::pair<float, float> GetMinMax(
201 double t0, double t1, bool mayThrow = true) const;
202
204
207 float GetRMS(double t0, double t1, bool mayThrow = true) const;
208
210 inline size_t GetBestBlockSize(sampleCount t) const;
212 inline size_t GetIdealBlockSize();
215 inline size_t GetMaxBlockSize() const;
216};
217
218class WAVE_TRACK_API WaveTrack final
219 : public WritableSampleTrack
220 // TODO wide wave tracks -- remove this base class
221 , public WaveChannel
222{
223public:
224 // Resolve ambiguous lookup
226
229 struct Region
230 {
231 Region() : start(0), end(0) {}
232 Region(double start_, double end_) : start(start_), end(end_) {}
233
234 double start, end;
235
236 //used for sorting
237 bool operator < (const Region &b) const
238 {
239 return this->start < b.start;
240 }
241 };
242
243 using Regions = std::vector < Region >;
244
245 static wxString GetDefaultAudioTrackNamePreference();
246
247 static double ProjectNyquistFrequency(const AudacityProject &project);
248
249 //
250 // Constructor / Destructor / Duplicator
251 //
252
253 // Construct and also build all attachments
254 static WaveTrack *New( AudacityProject &project );
255
256 WaveTrack(
257 const SampleBlockFactoryPtr &pFactory, sampleFormat format, double rate);
260
262 size_t GetWidth() const;
263
265 size_t NChannels() const override;
266
267 auto GetChannel(size_t iChannel) {
268 return this->ChannelGroup::GetChannel<WaveChannel>(iChannel); }
269 auto GetChannel(size_t iChannel) const {
270 return this->ChannelGroup::GetChannel<const WaveChannel>(iChannel); }
271
272 auto Channels() {
273 return this->ChannelGroup::Channels<WaveChannel>(); }
274 auto Channels() const {
275 return this->ChannelGroup::Channels<const WaveChannel>(); }
276
277 AudioGraph::ChannelType GetChannelType() const override;
278
281
286 void Reinit(const WaveTrack &orig);
287 private:
288 void Init(const WaveTrack &orig);
289
290 TrackListHolder Clone() const override;
291
292 friend class WaveTrackFactory;
293
294 wxString MakeClipCopyName(const wxString& originalName) const;
295 wxString MakeNewClipName() const;
296 public:
297
298 using Holder = std::shared_ptr<WaveTrack>;
299
300 virtual ~WaveTrack();
301
302 void MoveTo(double o) override;
303
304 bool LinkConsistencyFix(bool doFix) override;
305
307 double GetStartTime() const override;
309 double GetEndTime() const override;
310
311 //
312 // Identifying the type of track
313 //
314
315 //
316 // WaveTrack parameters
317 //
318
319 double GetRate() const override;
322 void SetRate(double newRate);
323
324 // Multiplicative factor. Only converted to dB for display.
325 float GetGain() const;
326 void SetGain(float newGain);
327
328 // -1.0 (left) -> 1.0 (right)
329 float GetPan() const;
330 void SetPan(float newPan);
331
333 float GetChannelGain(int channel) const override;
334
335 int GetWaveColorIndex() const;
339 void SetWaveColorIndex(int colorIndex);
340
342
350 sampleCount GetSequenceSamplesCount() const;
351
358 size_t CountBlocks() const;
359
360 sampleFormat GetSampleFormat() const override;
361
365 void ConvertToSampleFormat(sampleFormat format,
366 const std::function<void(size_t)> & progressReport = {});
367
368 //
369 // High-level editing
370 //
371
372 TrackListHolder Cut(double t0, double t1) override;
373
376
385 Holder EmptyCopy(const SampleBlockFactoryPtr &pFactory = {},
386 bool keepLink = true) const;
387
390
401 TrackListHolder WideEmptyCopy(const SampleBlockFactoryPtr &pFactory = {},
402 bool keepLink = true) const;
403
405 TrackListHolder MonoToStereo();
406
407 // If forClipboard is true,
408 // and there is no clip at the end time of the selection, then the result
409 // will contain a "placeholder" clip whose only purpose is to make
410 // GetEndTime() correct. This clip is not re-copied when pasting.
411 TrackListHolder Copy(double t0, double t1, bool forClipboard = true)
412 const override;
413
414 void Clear(double t0, double t1) override;
415 void Paste(double t0, const Track &src) override;
416 using Track::Paste; // Get the non-virtual overload too
417
425 void ClearAndPaste(
426 double t0, double t1, const WaveTrack& src, bool preserve = true,
427 bool merge = true, const TimeWarper* effectWarper = nullptr,
428 bool clearByTrimming = false) /* not override */;
434 void ClearAndPaste(double t0, double t1,
435 const TrackList &src,
436 bool preserve = true,
437 bool merge = true,
438 const TimeWarper *effectWarper = nullptr)
439 {
440 ClearAndPaste(t0, t1, **src.Any<const WaveTrack>().begin(),
441 preserve, merge, effectWarper);
442 }
443
444 void Silence(double t0, double t1, ProgressReporter reportProgress) override;
445 void InsertSilence(double t, double len) override;
446
450 void Split(double t0, double t1) /* not override */;
455 void ClearAndAddCutLine(double t0, double t1) /* not override */;
456
461 TrackListHolder SplitCut(double t0, double t1) /* not override */;
462
463 // May assume precondition: t0 <= t1
467 void SplitDelete(double t0, double t1) /* not override */;
471 void Join(
472 double t0, double t1,
473 const ProgressReporter& reportProgress) /* not override */;
474 // May assume precondition: t0 <= t1
478 void Disjoin(double t0, double t1) /* not override */;
479
480 // May assume precondition: t0 <= t1
484 void Trim(double t0, double t1) /* not override */;
485
486 /*
487 * @param interval Entire track is rendered if nullopt, else only samples
488 * within [interval->first, interval->second), in which case clips are split
489 * at these boundaries before rendering - if rendering is needed.
490 *
491 * @pre `!interval.has_value() || interval->first <= interval->second`
492 */
493 void ApplyStretchRatio(
494 std::optional<TimeInterval> interval, ProgressReporter reportProgress);
495
496 void SyncLockAdjust(double oldT1, double newT1) override;
497
503 bool IsEmpty(double t0, double t1) const;
504
512 size_t len, unsigned int stride = 1,
513 sampleFormat effectiveFormat = widestSampleFormat, size_t iChannel = 0)
514 override;
515
516 void Flush() override;
517
518 bool IsLeader() const override;
519
522 const ChannelGroup *FindChannelGroup() const override;
523 bool GetMute() const override;
524 bool GetSolo() const override;
526
537
539 bool DoGet(
540 size_t iChannel, size_t nBuffers, const samplePtr buffers[],
541 sampleFormat format, sampleCount start, size_t len, bool backwards,
542 fillFormat fill = FillFormat::fillZero, bool mayThrow = true,
543 // Report how many samples were copied from within clips, rather than
544 // filled according to fillFormat; but these were not necessarily one
545 // contiguous range.
546 sampleCount* pNumWithinClips = nullptr) const override;
547
558 std::pair<size_t, size_t> GetFloatsCenteredAroundTime(
559 double t, size_t iChannel, float* buffer, size_t numSideSamples,
560 bool mayThrow) const;
561
565 bool
566 GetFloatAtTime(double t, size_t iChannel, float& value, bool mayThrow) const;
567
574 void SetFloatsCenteredAroundTime(
575 double t, size_t iChannel, const float* buffer, size_t numSideSamples,
576 sampleFormat effectiveFormat);
577
582 void SetFloatAtTime(
583 double t, size_t iChannel, float value, sampleFormat effectiveFormat);
584
592 void SetFloatsWithinTimeRange(
593 double t0, double t1, size_t iChannel,
594 const std::function<float(double sampleTime)>& producer,
595 sampleFormat effectiveFormat);
596
610 GetSampleView(double t0, double t1, bool mayThrow = true) const;
611
612 sampleFormat WidestEffectiveFormat() const override;
613
614 bool HasTrivialEnvelope() const override;
615
616 void GetEnvelopeValues(
617 double* buffer, size_t bufferLen, double t0,
618 bool backwards) const override;
619
620 //
621 // MM: We now have more than one sequence and envelope per track, so
622 // instead of GetEnvelope() we have the following function which gives the
623 // envelope that contains the given time.
624 //
625 Envelope* GetEnvelopeAtTime(double time);
626
627 const WaveClip* GetClipAtTime(double time) const;
628 WaveClip* GetClipAtTime(double time);
629 WaveClipConstHolders GetClipsIntersecting(double t0, double t1) const;
630
635 const WaveClip* GetNextClip(
636 const WaveClip& clip, PlaybackDirection searchDirection) const;
640 WaveClip*
641 GetNextClip(const WaveClip& clip, PlaybackDirection searchDirection);
642
647 const WaveClip* GetAdjacentClip(
648 const WaveClip& clip, PlaybackDirection searchDirection) const;
652 WaveClip*
653 GetAdjacentClip(const WaveClip& clip, PlaybackDirection searchDirection);
654
655 //
656 // Getting information about the track's internal block sizes
657 // and alignment for efficiency
658 //
659
660 // These return a nonnegative number of samples meant to size a memory buffer
661 size_t GetBestBlockSize(sampleCount t) const;
662 size_t GetMaxBlockSize() const;
663 size_t GetIdealBlockSize();
664
665 //
666 // XMLTagHandler callback methods for loading and saving
667 //
668
669 bool HandleXMLTag(const std::string_view& tag, const AttributesList& attrs) override;
670 void HandleXMLEndTag(const std::string_view& tag) override;
671 XMLTagHandler *HandleXMLChild(const std::string_view& tag) override;
672 void WriteXML(XMLWriter &xmlFile) const override;
673
674 // Returns true if an error occurred while reading from XML
675 std::optional<TranslatableString> GetErrorOpening() const override;
676
677 //
678 // Lock and unlock the track: you must lock the track before
679 // doing a copy and paste between projects.
680 //
681
683
687 bool CloseLock() noexcept;
688
691
694 WaveClipHolders &GetClips() { return mClips; }
699 { return reinterpret_cast< const WaveClipConstHolders& >( mClips ); }
700
701 const WaveClip* GetLeftmostClip() const;
702 const WaveClip* GetRightmostClip() const;
703
709 ClipConstHolders GetClipInterfaces() const;
710
711 // Get mutative access to all clips (in some unspecified sequence),
712 // including those hidden in cutlines.
714 : public ValueIterator< WaveClip * >
715 {
716 public:
717 // Constructs an "end" iterator
719
720 // Construct a "begin" iterator
721 explicit AllClipsIterator( WaveTrack &track )
722 {
723 push( track.mClips );
724 }
725
727 {
728 if (mStack.empty())
729 return nullptr;
730 else
731 return mStack.back().first->get();
732 }
733
734 AllClipsIterator &operator ++ ();
735
736 // Define == well enough to serve for loop termination test
737 friend bool operator == (
738 const AllClipsIterator &a, const AllClipsIterator &b)
739 { return a.mStack.empty() == b.mStack.empty(); }
740
741 friend bool operator != (
742 const AllClipsIterator &a, const AllClipsIterator &b)
743 { return !( a == b ); }
744
745 private:
746
747 void push( WaveClipHolders &clips );
748
749 using Iterator = WaveClipHolders::iterator;
750 using Pair = std::pair< Iterator, Iterator >;
751 using Stack = std::vector< Pair >;
752
754 };
755
756 // Get const access to all clips (in some unspecified sequence),
757 // including those hidden in cutlines.
759 : public ValueIterator< const WaveClip * >
760 {
761 public:
762 // Constructs an "end" iterator
764
765 // Construct a "begin" iterator
766 explicit AllClipsConstIterator( const WaveTrack &track )
767 : mIter{ const_cast< WaveTrack& >( track ) }
768 {}
769
770 const WaveClip *operator * () const
771 { return *mIter; }
772
773 AllClipsConstIterator &operator ++ ()
774 { ++mIter; return *this; }
775
776 // Define == well enough to serve for loop termination test
777 friend bool operator == (
779 { return a.mIter == b.mIter; }
780
781 friend bool operator != (
783 { return !( a == b ); }
784
785 private:
787 };
788
790 {
791 return { AllClipsIterator{ *this }, AllClipsIterator{ } };
792 }
793
795 {
796 return { AllClipsConstIterator{ *this }, AllClipsConstIterator{ } };
797 }
798
800 void CreateWideClip(double offset = .0, const wxString& name = wxEmptyString);
801
803
809 WaveClip* CreateClip(double offset = .0, const wxString& name = wxEmptyString);
810
816 WaveClip* NewestOrNewClip();
817
823 WaveClip* RightmostOrNewClip();
824
825 // Get the linear index of a given clip (-1 if the clip is not found)
826 int GetClipIndex(const WaveClip* clip) const;
827
829
833 WaveClip *GetClipByIndex(int index);
837 const WaveClip* GetClipByIndex(int index) const;
838
839 // Get number of clips in this WaveTrack
840 int GetNumClips() const;
841 int GetNumClips(double t0, double t1) const;
842
843 // Add all wave clips to the given array 'clips' and sort the array by
844 // clip start time. The array is emptied prior to adding the clips.
845 WaveClipPointers SortedClipArray();
846 WaveClipConstPointers SortedClipArray() const;
847
849
852 bool HasHiddenData() const;
853
855
858 void DiscardTrimmed();
859
861
864 bool CanOffsetClips(
865 const std::vector<WaveClip*> &clips,
866 double amount,
867 double *allowedAmount = nullptr
869 );
870
871 // Before moving a clip into a track (or inserting a clip), use this
872 // function to see if the times are valid (i.e. don't overlap with
873 // existing clips).
874 bool
875 CanInsertClip(const WaveClip& clip, double& slideBy, double tolerance) const;
876
877 // Remove the clip from the track and return a SMART pointer to it.
878 // You assume responsibility for its memory!
879 std::shared_ptr<WaveClip> RemoveAndReturnClip(WaveClip* clip);
880
883
887 bool AddClip(const std::shared_ptr<WaveClip> &clip);
888
889 // Merge two clips, that is append data from clip2 to clip1,
890 // then remove clip2 from track.
891 // clipidx1 and clipidx2 are indices into the clip list.
892 bool MergeClips(int clipidx1, int clipidx2);
893
896 /*
897 @pre `IsLeader()`
898 @param[out] cutlineStart start time of the insertion
899 @param[out] cutlineEnd end time of the insertion
900 */
901 void ExpandCutLine(double cutLinePosition,
902 double* cutlineStart = nullptr, double* cutlineEnd = nullptr);
903
905 /*
906 @pre `IsLeader()`
907 */
908 bool RemoveCutLine(double cutLinePosition);
909
910 // Resample track (i.e. all clips in the track)
911 void Resample(int rate, BasicUI::ProgressDialog *progress = NULL);
912
915 using ProgressReport = std::function<bool(double)>;
916 bool Reverse(sampleCount start, sampleCount len,
917 const ProgressReport &report = {});
918
919 const TypeInfo &GetTypeInfo() const override;
920 static const TypeInfo &ClassTypeInfo();
921
922 class WAVE_TRACK_API Interval final : public WideChannelGroupInterval {
923 public:
927 Interval(const ChannelGroup &group,
928 const std::shared_ptr<WaveClip> &pClip,
929 const std::shared_ptr<WaveClip> &pClip1);
930
931 Interval(
932 const ChannelGroup& group, size_t width,
933 const SampleBlockFactoryPtr& factory, int rate,
934 sampleFormat storedSampleFormat);
935
936 ~Interval() override;
937
938 void Append(constSamplePtr buffer[], sampleFormat format, size_t len);
939 void Flush();
940
941 void SetName(const wxString& name);
942 const wxString& GetName() const;
943
944 void SetColorIndex(int index);
945 int GetColorIndex() const;
946
947 void SetPlayStartTime(double time);
948 double GetPlayStartTime() const;
949 double GetPlayEndTime() const;
950 bool IntersectsPlayRegion(double t0, double t1) const;
951 bool WithinPlayRegion(double t) const;
952
953 double GetStretchRatio() const;
954
955 sampleCount TimeToSamples(double time) const;
956 double SamplesToTime(sampleCount s) const;
957 double GetSequenceStartTime() const;
958 double GetSequenceEndTime() const;
959 double GetTrimLeft() const;
960 double GetTrimRight() const;
961
962 auto GetChannel(size_t iChannel) { return
963 WideChannelGroupInterval::GetChannel<WaveChannelInterval>(iChannel); }
964 auto GetChannel(size_t iChannel) const { return
965 WideChannelGroupInterval::GetChannel<const WaveChannelInterval>(iChannel); }
966
967 auto Channels() { return
968 WideChannelGroupInterval::Channels<WaveChannelInterval>(); }
969
970 auto Channels() const { return
971 WideChannelGroupInterval::Channels<const WaveChannelInterval>(); }
972
973 bool IsPlaceholder() const;
974
975 void SetSequenceStartTime(double t);
976 void TrimLeftTo(double t);
977 void TrimRightTo(double t);
978 void StretchLeftTo(double t);
979 void StretchRightTo(double t);
980 void SetTrimLeft(double t);
981 void SetTrimRight(double t);
982 void ClearLeft(double t);
983 void ClearRight(double t);
984
988 std::shared_ptr<Interval> GetStretchRenderedCopy(
989 const std::function<void(double)>& reportProgress,
990 const ChannelGroup& group, const SampleBlockFactoryPtr& factory,
992 bool StretchRatioEquals(double value) const;
993
994 std::shared_ptr<const WaveClip> GetClip(size_t iChannel) const
995 { return iChannel == 0 ? mpClip : mpClip1; }
996 const std::shared_ptr<WaveClip> &GetClip(size_t iChannel)
997 { return iChannel == 0 ? mpClip : mpClip1; }
998 private:
999 const Envelope& GetEnvelope() const;
1000 void SetEnvelope(const Envelope& envelope);
1001
1002 // Helper function in time of migration to wide clips
1003 void ForEachClip(const std::function<void(WaveClip&)>& op);
1004
1005 std::shared_ptr<ChannelInterval> DoGetChannel(size_t iChannel) override;
1006 const std::shared_ptr<WaveClip> mpClip;
1008 const std::shared_ptr<WaveClip> mpClip1;
1009 };
1010
1011 using IntervalHolder = std::shared_ptr<Interval>;
1012 using IntervalConstHolder = std::shared_ptr<const Interval>;
1013
1015 IntervalConstHolder GetNextInterval(
1016 const Interval& interval, PlaybackDirection searchDirection) const;
1017
1022 GetNextInterval(const Interval& interval, PlaybackDirection searchDirection);
1023
1024 IntervalHolder GetIntervalAtTime(double t);
1025
1026 auto Intervals() { return ChannelGroup::Intervals<Interval>(); }
1027 auto Intervals() const { return ChannelGroup::Intervals<const Interval>(); }
1028
1030 const override;
1031
1033 const WaveClip* FindClipByName(const wxString& name) const;
1034
1035 size_t NIntervals() const override;
1036
1038 void SetLegacyFormat(sampleFormat format);
1039
1040 // TODO wide-wave-track: some other API
1041 void CopyClipEnvelopes();
1042
1043private:
1044 void FlushOne();
1045 // May assume precondition: t0 <= t1
1046 void HandleClear(
1047 double t0, double t1, bool addCutLines, bool split,
1048 bool clearByTrimming = false);
1049 /*
1050 * @brief Copy/Paste operations must preserve beat durations, but time
1051 * boundaries are expressed in seconds. For pasting to work, source and
1052 * destination tracks must therefore have equal tempo.
1053 * @pre Preconditions of `ClearAndPaste`
1054 * @pre `GetProjectTempo().has_value() && GetProjectTempo() ==
1055 * src.GetProjectTempo()`
1056 */
1057 void ClearAndPasteAtSameTempo(
1058 double t0, double t1, const WaveTrack& src, bool preserve, bool merge,
1059 const TimeWarper* effectWarper, bool clearByTrimming);
1060 static void ClearAndPasteOne(
1061 WaveTrack& track, double t0, double t1, double startTime, double endTime,
1062 const WaveTrack& src, bool preserve, bool merge,
1063 const TimeWarper* effectWarper, bool clearByTrimming);
1064
1066 static void JoinOne(WaveTrack& track, double t0, double t1);
1067 static Holder CopyOne(const WaveTrack &track,
1068 double t0, double t1, bool forClipboard);
1069 static void WriteOneXML(const WaveTrack &track, XMLWriter &xmlFile,
1070 size_t iChannel, size_t nChannels);
1071 static bool ReverseOne(WaveTrack &track,
1072 sampleCount start, sampleCount len, const ProgressReport &report = {});
1073 static bool ReverseOneClip(WaveTrack &track,
1074 sampleCount start, sampleCount len, sampleCount originalStart,
1075 sampleCount originalEnd, const ProgressReport &report = {});
1076 void SplitAt(double t) /* not override */;
1077 void ExpandOneCutLine(double cutLinePosition,
1078 double* cutlineStart, double* cutlineEnd);
1079 bool MergeOneClipPair(int clipidx1, int clipidx2);
1080 void ApplyStretchRatioOnIntervals(
1081 const std::vector<IntervalHolder>& intervals,
1082 const ProgressReporter& reportProgress);
1084 void InsertInterval(const IntervalHolder& interval);
1086 void RemoveInterval(const IntervalHolder& interval);
1089 void
1090 ReplaceInterval(const IntervalHolder& oldOne, const IntervalHolder& newOne);
1091
1092 std::shared_ptr<WideChannelGroupInterval> DoGetInterval(size_t iInterval)
1093 override;
1094 std::shared_ptr<::Channel> DoGetChannel(size_t iChannel) override;
1095
1096 ChannelGroup &DoGetChannelGroup() const override;
1097 ChannelGroup &ReallyDoGetChannelGroup() const override;
1098
1099 //
1100 // Protected variables
1101 //
1102
1108
1109 mutable int mLegacyRate{ 0 };
1111
1112private:
1113 //Updates rate parameter only in WaveTrackData
1114 void DoSetRate(double newRate);
1115 void SetClipRates(double newRate);
1116 void DoOnProjectTempoChange(
1117 const std::optional<double>& oldTempo, double newTempo) override;
1123 [[nodiscard]] TrackListHolder
1124 DuplicateWithOtherTempo(double newTempo, WaveTrack*& leader) const;
1125
1126 bool GetOne(
1127 samplePtr buffer, sampleFormat format, sampleCount start, size_t len,
1128 bool backwards, fillFormat fill, bool mayThrow,
1129 sampleCount* pNumWithinClips) const;
1130
1138 size_t GetFloatsFromTime(
1139 double t, size_t iChannel, float* buffer, size_t numSamples,
1140 bool mayThrow, PlaybackDirection direction) const;
1141
1147 void SetFloatsFromTime(
1148 double t, size_t iChannel, const float* buffer, size_t numSamples,
1149 sampleFormat effectiveFormat, PlaybackDirection direction);
1150
1151 void DoSetPan(float value);
1152 void DoSetGain(float value);
1153
1154 /*
1155 @pre `other.NChannels() == 1 || other.NChannels() == NChannels()`
1156 @pre `IsLeader()`
1157 */
1158 void PasteWaveTrack(double t0, const WaveTrack &other, bool merge);
1159 /*
1160 * @copybrief ClearAndPasteAtSameTempo
1161 * @pre Preconditions of `PasteWaveTrack`
1162 * @pre `GetProjectTempo().has_value() && GetProjectTempo() ==
1163 * other.GetProjectTempo()`
1164 */
1165 void
1166 PasteWaveTrackAtSameTempo(double t0, const WaveTrack& other, bool merge);
1167 static void PasteOne(
1168 WaveTrack& track, double t0, const WaveTrack& other, double startTime,
1169 double insertDuration, bool merge = true);
1170
1172
1175 bool RateConsistencyCheck() const;
1177
1180 bool FormatConsistencyCheck() const;
1181
1186 bool InsertClip(WaveClipHolder clip);
1187
1189 double t0, double t1, const ProgressReporter& reportProgress);
1190
1192
1193 wxCriticalSection mFlushCriticalSection;
1194 wxCriticalSection mAppendCriticalSection;
1196
1198};
1199
1201
1203 auto &result = static_cast<WaveTrack&>(DoGetChannelGroup());
1204 // TODO wide wave tracks -- remove assertion
1205 assert(&result == this);
1206 return result;
1207}
1208
1210 auto &result = static_cast<const WaveTrack&>(DoGetChannelGroup());
1211 // TODO wide wave tracks -- remove assertion
1212 assert(&result == this);
1213 return result;
1214}
1215
1217 return GetTrack().GetBestBlockSize(t);
1218}
1219
1221 return GetTrack().GetIdealBlockSize();
1222}
1223
1225 return GetTrack().GetMaxBlockSize();
1226}
1227
1228#include <unordered_set>
1229class SampleBlock;
1230using SampleBlockID = long long;
1231using SampleBlockIDSet = std::unordered_set<SampleBlockID>;
1232class TrackList;
1233using BlockVisitor = std::function< void(SampleBlock&) >;
1234using BlockInspector = std::function< void(const SampleBlock&) >;
1235
1236// Function to visit all sample blocks from a list of tracks.
1237// If a set is supplied, then only visit once each unique block ID not already
1238// in that set, and accumulate those into the set as a side-effect.
1239// The visitor function may be null.
1241 SampleBlockIDSet *pIDs = nullptr);
1242
1243// Non-mutating version of the above
1244WAVE_TRACK_API void InspectBlocks(const TrackList &tracks,
1245 BlockInspector inspector, SampleBlockIDSet *pIDs = nullptr);
1246
1247class ProjectRate;
1248
1249class WAVE_TRACK_API WaveTrackFactory final
1250 : public ClientData::Base
1251{
1252 public:
1254 static const WaveTrackFactory &Get( const AudacityProject &project );
1255 static WaveTrackFactory &Reset( AudacityProject &project );
1256 static void Destroy( AudacityProject &project );
1257
1259 const ProjectRate& rate,
1260 const SampleBlockFactoryPtr &pFactory)
1261 : mRate{ rate }
1262 , mpFactory(pFactory)
1263 {
1264 }
1267
1269 { return mpFactory; }
1270
1275 std::shared_ptr<WaveTrack> Create();
1276
1283 std::shared_ptr<WaveTrack> Create(sampleFormat format, double rate);
1284
1290 TrackListHolder Create(size_t nChannels);
1291
1298 TrackListHolder Create(size_t nChannels, sampleFormat format, double rate);
1299
1305 TrackListHolder Create(size_t nChannels, const WaveTrack& proto);
1306
1307 private:
1310};
1311
1312extern WAVE_TRACK_API BoolSetting
1314;
1315
1316extern WAVE_TRACK_API StringSetting AudioTrackNameSetting;
1317
1318WAVE_TRACK_API bool GetEditClipsCanMove();
1319
1320// Generate a registry for serialized data
1321#include "XMLMethodRegistry.h"
1324
1325#endif // __AUDACITY_WAVETRACK__
std::vector< std::shared_ptr< const ClipInterface > > ClipConstHolders
std::vector< AudioSegmentSampleView > ChannelSampleView
const TranslatableString name
Definition: Distortion.cpp:76
Vector operator*(const Vector &left, const Vector &right)
Definition: Matrix.cpp:153
std::vector< std::vector< AudioSegmentSampleView > > ChannelGroupSampleView
Definition: MixerBoard.h:35
PlaybackDirection
long long SampleBlockID
Definition: ProjectFileIO.h:43
bool operator==(const EffectReverbSettings &a, const EffectReverbSettings &b)
Definition: Reverb.cpp:632
std::shared_ptr< SampleBlockFactory > SampleBlockFactoryPtr
Definition: SampleBlock.h:30
bool operator<(sampleCount a, sampleCount b)
Definition: SampleCount.h:85
sampleFormat
The ordering of these values with operator < agrees with the order of increasing bit width.
Definition: SampleFormat.h:30
char * samplePtr
Definition: SampleFormat.h:57
const char * constSamplePtr
Definition: SampleFormat.h:58
enum FillFormat fillFormat
const auto tracks
const auto project
std::function< void(double)> ProgressReporter
Definition: Track.h:53
std::shared_ptr< TrackList > TrackListHolder
Definition: Track.h:42
std::shared_ptr< WaveClip > WaveClipHolder
Definition: WaveClip.h:45
std::vector< WaveClipHolder > WaveClipHolders
Definition: WaveClip.h:46
std::vector< std::shared_ptr< const WaveClip > > WaveClipConstHolders
Definition: WaveClip.h:47
std::function< void(SampleBlock &) > BlockVisitor
Definition: WaveTrack.h:1233
void VisitBlocks(TrackList &tracks, BlockVisitor visitor, SampleBlockIDSet *pIDs=nullptr)
Definition: WaveTrack.cpp:4437
DECLARE_XML_METHOD_REGISTRY(WAVE_TRACK_API, WaveTrackIORegistry)
WAVE_TRACK_API bool GetEditClipsCanMove()
Definition: WaveTrack.cpp:4538
std::unordered_set< SampleBlockID > SampleBlockIDSet
Definition: WaveTrack.h:1231
ENUMERATE_TRACK_TYPE(WaveTrack)
std::pair< double, double > TimeInterval
Definition: WaveTrack.h:55
std::function< void(const SampleBlock &) > BlockInspector
Definition: WaveTrack.h:1234
std::vector< WaveClip * > WaveClipPointers
Definition: WaveTrack.h:49
WAVE_TRACK_API StringSetting AudioTrackNameSetting
Definition: WaveTrack.cpp:4528
std::vector< const WaveClip * > WaveClipConstPointers
Definition: WaveTrack.h:50
WAVE_TRACK_API void InspectBlocks(const TrackList &tracks, BlockInspector inspector, SampleBlockIDSet *pIDs=nullptr)
Definition: WaveTrack.cpp:4459
WAVE_TRACK_API BoolSetting EditClipsCanMove
Definition: WaveTrack.cpp:4547
Append(Adapt< My >([](My &table) { return(WaveChannelSubViews::numFactories() > 1) ? std::make_unique< Entry >("MultiView", Entry::CheckItem, OnMultiViewID, XXO("&Multi-view"), POPUP_MENU_FN(OnMultiView), table, [](PopupMenuHandler &handler, wxMenu &menu, int id){ auto &table=static_cast< WaveTrackMenuTable & >(handler);auto &track=table.FindWaveTrack();const auto &view=WaveChannelView::Get(track);menu.Check(id, view.GetMultiView());}) :nullptr;}))
bool operator!=(const WaveTrackLocation &a, const WaveTrackLocation &b)
std::vector< Attribute > AttributesList
Definition: XMLTagHandler.h:40
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
Definition: Project.h:90
Abstraction of a progress dialog with well defined time-to-completion estimate.
Definition: BasicUI.h:157
This specialization of Setting for bool adds a Toggle method to negate the saved value.
Definition: Prefs.h:344
virtual ChannelGroup & DoGetChannelGroup() const =0
Subclass must override.
The intersection of a Channel and a WideChannelGroupInterval.
Definition: Channel.h:49
virtual double GetPlayEndTime() const =0
virtual double GetStretchRatio() const =0
virtual double GetPlayStartTime() const =0
virtual sampleCount TimeToSamples(double time) const =0
virtual sampleCount GetVisibleSampleCount() const =0
Piecewise linear or piecewise exponential function from double to double.
Definition: Envelope.h:72
ProgressDialog Class.
Holds project sample rate.
Definition: ProjectRate.h:24
Interface to libsoxr.
Definition: Resample.h:27
abstract base class with methods to produce SampleBlock objects
Definition: SampleBlock.h:117
Abstract class allows access to contents of a block of sound samples, serialization as XML,...
Definition: SampleBlock.h:46
bool GetFloats(float *buffer, sampleCount start, size_t len, fillFormat fill=FillFormat::fillZero, bool mayThrow=true, sampleCount *pNumWithinClips=nullptr) const
"narrow" overload fetches first channel only
Definition: SampleTrack.h:46
A WaveTrack contains WaveClip(s). A WaveClip contains a Sequence. A Sequence is primarily an interfac...
Definition: Sequence.h:53
Specialization of Setting for strings.
Definition: Prefs.h:368
Transforms one point in time to another point. For example, a time stretching effect might use one to...
Definition: TimeWarper.h:62
Abstract base class for an object holding data associated with points on a time axis.
Definition: Track.h:122
virtual void Paste(double t, const Track &src)=0
Weak precondition allows overrides to replicate one channel into many.
std::shared_ptr< Track > Holder
Definition: Track.h:225
A flat linked list of tracks supporting Add, Remove, Clear, and Contains, serialization of the list o...
Definition: Track.h:975
auto Any() -> TrackIterRange< TrackType >
Definition: Track.h:1079
auto GetInterval(size_t iInterval) const
Definition: WaveTrack.h:144
WaveTrack & GetTrack()
Definition: WaveTrack.h:1202
~WaveChannel() override
auto Intervals() const
Definition: WaveTrack.h:148
auto Intervals()
Definition: WaveTrack.h:147
auto GetInterval(size_t iInterval)
Definition: WaveTrack.h:142
bool GetFloats(float *buffer, sampleCount start, size_t len, fillFormat fill=FillFormat::fillZero, bool mayThrow=true, sampleCount *pNumWithinClips=nullptr) const
"narrow" overload fetches from the unique channel
Definition: WaveTrack.h:154
size_t GetIdealBlockSize()
A hint for sizing of well aligned fetches.
Definition: WaveTrack.h:1220
size_t GetBestBlockSize(sampleCount t) const
A hint for sizing of well aligned fetches.
Definition: WaveTrack.h:1216
size_t GetMaxBlockSize() const
Definition: WaveTrack.h:1224
WaveClip & mWideClip
Definition: WaveTrack.h:126
WaveChannelInterval(WaveClip &wideClip, WaveClip &narrowClip, size_t iChannel)
Assume lifetime of this object nests in those of arguments.
Definition: WaveTrack.h:72
WaveClip & mNarrowClip
Definition: WaveTrack.h:127
const WaveClip & GetNarrowClip() const
Definition: WaveTrack.h:124
const WaveClip & GetClip() const
Definition: WaveTrack.h:79
~WaveChannelInterval() override
size_t GetChannelIndex() const
Definition: WaveTrack.h:81
const size_t miChannel
Definition: WaveTrack.h:128
This allows multiple clips to be a part of one WaveTrack.
Definition: WaveClip.h:103
AllClipsConstIterator(const WaveTrack &track)
Definition: WaveTrack.h:766
std::pair< Iterator, Iterator > Pair
Definition: WaveTrack.h:750
std::vector< Pair > Stack
Definition: WaveTrack.h:751
WaveClipHolders::iterator Iterator
Definition: WaveTrack.h:749
AllClipsIterator(WaveTrack &track)
Definition: WaveTrack.h:721
std::shared_ptr< const WaveClip > GetClip(size_t iChannel) const
Definition: WaveTrack.h:994
const std::shared_ptr< WaveClip > mpClip1
TODO wide wave tracks: eliminate this.
Definition: WaveTrack.h:1008
auto GetChannel(size_t iChannel) const
Definition: WaveTrack.h:964
const std::shared_ptr< WaveClip > mpClip
Definition: WaveTrack.h:1006
auto Channels() const
Definition: WaveTrack.h:970
auto GetChannel(size_t iChannel)
Definition: WaveTrack.h:962
~Interval() override
const std::shared_ptr< WaveClip > & GetClip(size_t iChannel)
Definition: WaveTrack.h:996
Used to create or clone a WaveTrack, with appropriate context from the project that will own the trac...
Definition: WaveTrack.h:1251
WaveTrackFactory(const WaveTrackFactory &)=delete
const SampleBlockFactoryPtr & GetSampleBlockFactory() const
Definition: WaveTrack.h:1268
SampleBlockFactoryPtr mpFactory
Definition: WaveTrack.h:1309
WaveTrackFactory & operator=(const WaveTrackFactory &)=delete
WaveTrackFactory(const ProjectRate &rate, const SampleBlockFactoryPtr &pFactory)
Definition: WaveTrack.h:1258
const ProjectRate & mRate
Definition: WaveTrack.h:1308
A Track that contains audio waveform data.
Definition: WaveTrack.h:222
SampleBlockFactoryPtr mpFactory
Definition: WaveTrack.h:1191
friend WaveChannel
Definition: WaveTrack.h:1197
std::vector< Region > Regions
Definition: WaveTrack.h:243
auto GetChannel(size_t iChannel) const
Definition: WaveTrack.h:269
void ClearAndPaste(double t0, double t1, const TrackList &src, bool preserve=true, bool merge=true, const TimeWarper *effectWarper=nullptr)
Definition: WaveTrack.h:434
auto Channels()
Definition: WaveTrack.h:272
wxCriticalSection mFlushCriticalSection
Definition: WaveTrack.h:1193
IteratorRange< AllClipsConstIterator > GetAllClips() const
Definition: WaveTrack.h:794
std::function< bool(double)> ProgressReport
Definition: WaveTrack.h:915
size_t GetIdealBlockSize()
Definition: WaveTrack.cpp:2721
std::shared_ptr< Interval > IntervalHolder
Definition: WaveTrack.h:1011
IteratorRange< AllClipsIterator > GetAllClips()
Definition: WaveTrack.h:789
void ApplyStretchRatioOne(double t0, double t1, const ProgressReporter &reportProgress)
auto Intervals() const
Definition: WaveTrack.h:1027
const WaveClipConstHolders & GetClips() const
Definition: WaveTrack.h:698
auto Intervals()
Definition: WaveTrack.h:1026
auto Channels() const
Definition: WaveTrack.h:274
size_t GetMaxBlockSize() const
Definition: WaveTrack.cpp:2699
double mLegacyProjectFileOffset
Definition: WaveTrack.h:1195
auto GetChannel(size_t iChannel)
Definition: WaveTrack.h:267
size_t GetBestBlockSize(sampleCount t) const
Definition: WaveTrack.cpp:2679
wxCriticalSection mAppendCriticalSection
Definition: WaveTrack.h:1194
WaveClipHolders mClips
Definition: WaveTrack.h:1107
std::shared_ptr< const Interval > IntervalConstHolder
Definition: WaveTrack.h:1012
bool GetFloats(size_t iChannel, size_t nBuffers, float *const buffers[], sampleCount start, size_t len, bool backwards=false, fillFormat fill=FillFormat::fillZero, bool mayThrow=true, sampleCount *pNumWithinClips=nullptr) const
This class is an interface which should be implemented by classes which wish to be able to load and s...
Definition: XMLTagHandler.h:42
Base class for XMLFileWriter and XMLStringWriter that provides the general functionality for creating...
Definition: XMLWriter.h:25
Positions or offsets within audio files need a wide type.
Definition: SampleCount.h:19
ChannelType
Mutually exclusive channel classifications.
Services * Get()
Fetch the global instance, or nullptr if none is yet installed.
Definition: BasicUI.cpp:196
auto end(const Ptr< Type, BaseDeleter > &p)
Enables range-for.
Definition: PackedArray.h:159
bool HasHiddenData(const TrackList &trackList)
Definition: EditMenus.cpp:168
std::vector< long > Split(const PluginRegistryVersion &regver)
double GetRate(const Track &track)
Definition: TimeTrack.cpp:196
Track & GetTrack(Channel &channel)
void StretchRightTo(WaveTrack::Interval &interval, double t)
void StretchLeftTo(WaveTrack::Interval &interval, double t)
void TrimLeftTo(WaveTrack::Interval &interval, double t)
void TrimRightTo(WaveTrack::Interval &interval, double t)
static RegisteredToolbarFactory factory
A convenient default parameter for class template Site.
Definition: ClientData.h:28
A convenience for use with range-for.
Definition: MemoryX.h:277
Empty argument passed to some public constructors.
Definition: Track.h:129
A convenience for defining iterators that return rvalue types, so that they cooperate correctly with ...
Definition: MemoryX.h:263
Structure to hold region of a wavetrack and a comparison function for sortability.
Definition: WaveTrack.h:230
Region(double start_, double end_)
Definition: WaveTrack.h:232