Audacity 3.2.0
WaveClip.h
Go to the documentation of this file.
1/**********************************************************************
2
3 Audacity: A Digital Audio Editor
4
5 WaveClip.h
6
7 ?? Dominic Mazzoni
8 ?? Markus Meyer
9
10*******************************************************************/
11
12#ifndef __AUDACITY_WAVECLIP__
13#define __AUDACITY_WAVECLIP__
14
15
16
17#include "ClientData.h"
18#include "SampleFormat.h"
19#include "ClipInterface.h"
20#include "XMLTagHandler.h"
21#include "SampleCount.h"
23
24#include <wx/longlong.h>
25
26#include <cassert>
27#include <functional>
28#include <optional>
29#include <vector>
30
31class BlockArray;
32class Envelope;
33class ProgressDialog;
34class sampleCount;
35class SampleBlock;
37using SampleBlockFactoryPtr = std::shared_ptr<SampleBlockFactory>;
38class Sequence;
40namespace BasicUI { class ProgressDialog; }
41
42class WaveClip;
43
44// Array of pointers that assume ownership
45using WaveClipHolder = std::shared_ptr< WaveClip >;
46using WaveClipHolders = std::vector < WaveClipHolder >;
47using WaveClipConstHolders = std::vector < std::shared_ptr< const WaveClip > >;
48using ProgressReporter = std::function<void(double)>;
49
50// A bundle of arrays needed for drawing waveforms. The object may or may not
51// own the storage for those arrays. If it does, it destroys them.
53{
54public:
55 int width;
57 float *min, *max, *rms;
58
59 std::vector<sampleCount> ownWhere;
60 std::vector<float> ownMin, ownMax, ownRms;
61
62public:
64 : width(w), where(0), min(0), max(0), rms(0)
65 {
66 }
67
68 // Create "own" arrays.
69 void Allocate()
70 {
71 ownWhere.resize(width + 1);
72 ownMin.resize(width);
73 ownMax.resize(width);
74 ownRms.resize(width);
75
76 where = &ownWhere[0];
77 if (width > 0) {
78 min = &ownMin[0];
79 max = &ownMax[0];
80 rms = &ownRms[0];
81 }
82 else {
83 min = max = rms = 0;
84 }
85 }
86
88 {
89 }
90};
91
92struct WAVE_TRACK_API WaveClipListener
93{
94 virtual ~WaveClipListener() = 0;
95 virtual void MarkChanged() = 0;
96 virtual void Invalidate() = 0;
97};
98
99class WAVE_TRACK_API WaveClip final :
100 public ClipInterface,
101 public XMLTagHandler,
102 public ClientData::Site<WaveClip, WaveClipListener>
103{
104private:
105 // It is an error to copy a WaveClip without specifying the
106 // sample block factory.
107
108 WaveClip(const WaveClip&) = delete;
109 WaveClip& operator= (const WaveClip&) = delete;
110
111public:
113
115
120 WaveClip(size_t width,
122 int rate, int colourIndex);
123
127
130 WaveClip(const WaveClip& orig,
132 bool copyCutlines);
133
135
139 WaveClip(const WaveClip& orig,
141 bool copyCutlines,
142 double t0, double t1);
143
144 virtual ~WaveClip();
145
147 bool CheckInvariants() const;
148
151 size_t GetWidth() const override;
152
153 void ConvertToSampleFormat(sampleFormat format,
154 const std::function<void(size_t)> & progressReport = {});
155
156 int GetRate() const override
157 {
158 return mRate;
159 }
160
161 // Set rate without resampling. This will change the length of the clip
162 void SetRate(int rate);
163
165 void StretchLeftTo(double to);
167 void StretchRightTo(double to);
168
169 double GetStretchRatio() const override;
170
173 bool HasEqualStretchRatio(const WaveClip& other) const;
174 bool StretchRatioEquals(double value) const;
176
177 // Resample clip. This also will set the rate, but without changing
178 // the length of the clip
179 void Resample(int rate, BasicUI::ProgressDialog *progress = nullptr);
180
181 void SetColourIndex(int index) { mColourIndex = index; }
182 int GetColourIndex() const { return mColourIndex; }
183
184 double GetSequenceStartTime() const noexcept;
185 void SetSequenceStartTime(double startTime);
186 double GetSequenceEndTime() const;
188 sampleCount GetSequenceStartSample() const;
191 sampleCount GetSequenceSamplesCount() const;
192
195 double GetPlayStartTime() const noexcept override;
196 void SetPlayStartTime(double time);
197
200 double GetPlayEndTime() const override;
201
204 double GetPlayDuration() const;
205
206 bool IsEmpty() const;
207
209 sampleCount GetPlayStartSample() const;
211 sampleCount GetPlayEndSample() const;
212
216 sampleCount GetVisibleSampleCount() const override;
217
219 void SetTrimLeft(double trim);
221 double GetTrimLeft() const noexcept;
222
224 void SetTrimRight(double trim);
226 double GetTrimRight() const noexcept;
227
229 void TrimLeft(double deltaTime);
231 void TrimRight(double deltaTime);
232
234 void TrimLeftTo(double to);
236 void TrimRightTo(double to);
237
239 void ShiftBy(double delta) noexcept;
240
243
248 bool SplitsPlayRegion(double t) const;
252 bool WithinPlayRegion(double t) const;
256 bool BeforePlayRegion(double t) const;
260 bool AtOrBeforePlayRegion(double t) const;
264 bool AfterPlayRegion(double t) const;
269 bool EntirelyWithinPlayRegion(double t0, double t1) const;
274 bool PartlyWithinPlayRegion(double t0, double t1) const;
279 bool IntersectsPlayRegion(double t0, double t1) const;
285 bool CoversEntirePlayRegion(double t0, double t1) const;
286
291 sampleCount CountSamples(double t0, double t1) const;
292
301 AudioSegmentSampleView GetSampleView(
302 size_t iChannel, sampleCount start, size_t length,
303 bool mayThrow = true) const override;
304
316 AudioSegmentSampleView GetSampleView(
317 size_t iChannel, double t0, double t1, bool mayThrow = true) const;
318
320
325 bool GetSamples(size_t ii, samplePtr buffer, sampleFormat format,
326 sampleCount start, size_t len, bool mayThrow = true) const;
327
329
333 bool GetSamples(samplePtr buffers[], sampleFormat format,
334 sampleCount start, size_t len, bool mayThrow = true) const;
335
337
341 void SetSamples(size_t ii, constSamplePtr buffer, sampleFormat format,
342 sampleCount start, size_t len,
343 sampleFormat effectiveFormat
349 );
350
354 bool
355 GetFloatAtTime(double t, size_t iChannel, float& value, bool mayThrow) const;
356
359 // clang-format off
369 // clang-format on
370 void SetFloatsFromTime(
371 double t, size_t iChannel, const float* buffer, size_t numSamples,
372 sampleFormat effectiveFormat);
373
380 void SetFloatsCenteredAroundTime(
381 double t, size_t iChannel, const float* buffer, size_t numSideSamples,
382 sampleFormat effectiveFormat);
383
384 void SetFloatAtTime(
385 double t, size_t iChannel, float value, sampleFormat effectiveFormat);
387
388 Envelope* GetEnvelope() { return mEnvelope.get(); }
389 const Envelope* GetEnvelope() const { return mEnvelope.get(); }
390 void SetEnvelope(std::unique_ptr<Envelope> p);
391
393
396 BlockArray* GetSequenceBlockArray(size_t ii);
400 const BlockArray* GetSequenceBlockArray(size_t ii) const;
401
405
408 Sequence* GetSequence(size_t ii) {
409 assert(ii < GetWidth());
410 return mSequences[ii].get();
411 }
415 const Sequence* GetSequence(size_t ii) const { return mSequences[ii].get(); }
416
421 void MarkChanged();
422
429 std::pair<float, float> GetMinMax(size_t ii,
430 double t0, double t1, bool mayThrow) const;
434 float GetRMS(size_t ii, double t0, double t1, bool mayThrow) const;
435
439 void UpdateEnvelopeTrackLen();
440
443 std::shared_ptr<SampleBlock>
444 AppendNewBlock(constSamplePtr buffer, sampleFormat format, size_t len);
445
448 void AppendSharedBlock(const std::shared_ptr<SampleBlock> &pBlock);
449
452
459 size_t len, unsigned int stride,
460 sampleFormat effectiveFormat
466 );
467
469
473 void Flush();
474
477 void Clear(double t0, double t1);
478
483 void ClearLeft(double t);
487 void ClearRight(double t);
488
491 void ClearAndAddCutLine(double t0, double t1);
492
498 bool Paste(double t0, const WaveClip& other);
499
502 void InsertSilence( double t, double len, double *pEnvelopeValue = nullptr );
503
506 void AppendSilence( double len, double envelopeValue );
507
509 WaveClipHolders &GetCutLines() { return mCutLines; }
511 { return reinterpret_cast< const WaveClipConstHolders& >( mCutLines ); }
512 size_t NumCutLines() const { return mCutLines.size(); }
513
517 bool FindCutLine(double cutLinePosition,
518 double* cutLineStart = NULL,
519 double *cutLineEnd = NULL) const;
520
524 void ExpandCutLine(double cutLinePosition);
525
527 bool RemoveCutLine(double cutLinePosition);
528
530 void OffsetCutLines(double t0, double len);
531
533
534 void CloseLock() noexcept;
535
536 //
537 // XMLTagHandler callback methods for loading and saving
538 //
539
540 bool HandleXMLTag(const std::string_view& tag, const AttributesList &attrs) override;
541 void HandleXMLEndTag(const std::string_view& tag) override;
542 XMLTagHandler *HandleXMLChild(const std::string_view& tag) override;
543 void WriteXML(XMLWriter &xmlFile) const /* not override */;
544
545 // AWD, Oct 2009: for pasting whitespace at the end of selection
546 bool GetIsPlaceholder() const { return mIsPlaceholder; }
547 void SetIsPlaceholder(bool val) { mIsPlaceholder = val; }
548
549 // used by commands which interact with clips using the keyboard
550 bool SharesBoundaryWithNextClip(const WaveClip* next) const;
551
552 void SetName(const wxString& name);
553 const wxString& GetName() const;
554
555 // TimeToSamples and SamplesToTime take clip stretch ratio into account.
556 // Use them to convert time / sample offsets.
557 sampleCount TimeToSamples(double time) const override;
558 double SamplesToTime(sampleCount s) const noexcept;
559
561 void SetSilence(sampleCount offset, sampleCount length);
562
564
568 constSamplePtr GetAppendBuffer(size_t ii) const;
569 size_t GetAppendBufferLen() const;
570
571 void
572 OnProjectTempoChange(const std::optional<double>& oldTempo, double newTempo);
573
574private:
575 // Always gives non-negative answer, not more than sample sequence length
576 // even if t0 really falls outside that range
577 sampleCount TimeToSequenceSamples(double t) const;
578
579 sampleCount GetNumSamples() const;
580 SampleFormats GetSampleFormats() const;
581 const SampleBlockFactoryPtr &GetFactory();
582 std::vector<std::unique_ptr<Sequence>> GetEmptySequenceCopies() const;
583 void StretchCutLines(double ratioChange);
584 double SnapToTrackSample(double time) const noexcept;
585
588 void ClearSequence(double t0, double t1);
589
591 struct Transaction {
592 explicit Transaction(WaveClip &clip);
593 ~Transaction();
594 void Commit() { committed = true; }
595
597 std::vector<std::unique_ptr<Sequence>> sequences;
598 const double mTrimLeft,
600 bool committed{ false };
601 };
602
605 double mSequenceOffset { 0 };
606 double mTrimLeft { 0 };
607 double mTrimRight { 0 };
609
610 // Used in GetStretchRatio which computes the factor, by which the sample
611 // interval is multiplied, to get a realtime duration.
612 double mClipStretchRatio = 1.;
613 std::optional<double> mRawAudioTempo;
614 std::optional<double> mProjectTempo;
615
617 int mRate;
619
627 std::vector<std::unique_ptr<Sequence>> mSequences;
629 std::unique_ptr<Envelope> mEnvelope;
630
633
636 WaveClipHolders mCutLines {};
637
638 // AWD, Oct. 2009: for whitespace-at-end-of-selection pasting
639 bool mIsPlaceholder { false };
640
641private:
642 wxString mName;
643};
644
645#endif
An audio segment is either a whole clip or the silence between clips. Views allow shared references t...
Utility ClientData::Site to register hooks into a host class that attach client data.
const TranslatableString name
Definition: Distortion.cpp:76
std::shared_ptr< SampleBlockFactory > SampleBlockFactoryPtr
Definition: SampleBlock.h:30
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
std::function< void(double)> ProgressReporter
Definition: Track.h:53
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
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;}))
std::vector< Attribute > AttributesList
Definition: XMLTagHandler.h:40
Abstraction of a progress dialog with well defined time-to-completion estimate.
Definition: BasicUI.h:157
Utility to register hooks into a host class that attach client data.
Definition: ClientData.h:228
Piecewise linear or piecewise exponential function from double to double.
Definition: Envelope.h:72
ProgressDialog Class.
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
Two sample formats, remembering format of original source and describing stored format.
Definition: SampleFormat.h:79
A WaveTrack contains WaveClip(s). A WaveClip contains a Sequence. A Sequence is primarily an interfac...
Definition: Sequence.h:53
This allows multiple clips to be a part of one WaveTrack.
Definition: WaveClip.h:103
std::optional< double > mRawAudioTempo
Definition: WaveClip.h:613
void SetIsPlaceholder(bool val)
Definition: WaveClip.h:547
std::unique_ptr< Envelope > mEnvelope
Envelope is unique, not per-sequence.
Definition: WaveClip.h:629
std::optional< double > mProjectTempo
Definition: WaveClip.h:614
wxString mName
Definition: WaveClip.h:642
int GetRate() const override
Definition: WaveClip.h:156
int mRate
Sample rate of the raw audio, i.e., before stretching.
Definition: WaveClip.h:617
int mColourIndex
Definition: WaveClip.h:618
WaveClipHolders & GetCutLines()
Get access to cut lines list.
Definition: WaveClip.h:509
void SetColourIndex(int index)
Definition: WaveClip.h:181
WaveClip(const WaveClip &)=delete
const Sequence * GetSequence(size_t ii) const
Definition: WaveClip.h:415
Sequence * GetSequence(size_t ii)
Definition: WaveClip.h:408
const WaveClipConstHolders & GetCutLines() const
Definition: WaveClip.h:510
size_t NumCutLines() const
Definition: WaveClip.h:512
int GetColourIndex() const
Definition: WaveClip.h:182
const Envelope * GetEnvelope() const
Definition: WaveClip.h:389
Site< WaveClip, WaveClipListener > Caches
Definition: WaveClip.h:112
std::vector< std::unique_ptr< Sequence > > mSequences
Definition: WaveClip.h:627
std::vector< float > ownMin
Definition: WaveClip.h:60
WaveDisplay(int w)
Definition: WaveClip.h:63
float * rms
Definition: WaveClip.h:57
sampleCount * where
Definition: WaveClip.h:56
~WaveDisplay()
Definition: WaveClip.h:87
std::vector< sampleCount > ownWhere
Definition: WaveClip.h:59
float * min
Definition: WaveClip.h:57
std::vector< float > ownMax
Definition: WaveClip.h:60
int width
Definition: WaveClip.h:55
float * max
Definition: WaveClip.h:57
void Allocate()
Definition: WaveClip.h:69
std::vector< float > ownRms
Definition: WaveClip.h:60
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
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
STL namespace.
Restores state when an update loop over mSequences fails midway.
Definition: WaveClip.h:591
const double mTrimLeft
Definition: WaveClip.h:598
std::vector< std::unique_ptr< Sequence > > sequences
Definition: WaveClip.h:597
const double mTrimRight
Definition: WaveClip.h:599
virtual void MarkChanged()=0
virtual void Invalidate()=0