Audacity 3.2.0
Classes | Public Types | Public Member Functions | Private Member Functions | Private Attributes | List of all members
WaveClip Class Referencefinal

This allows multiple clips to be a part of one WaveTrack. More...

#include <WaveClip.h>

Inheritance diagram for WaveClip:
[legend]
Collaboration diagram for WaveClip:
[legend]

Classes

struct  Transaction
 Restores state when an update loop over mSequences fails midway. More...
 

Public Types

using Caches = Site< WaveClip, WaveClipListener >
 
- Public Types inherited from ClientData::Site< WaveClip, WaveClipListener >
using DataType = WaveClipListener
 
using DataPointer = UniquePtr< WaveClipListener >
 
using DataFactory = std::function< DataPointer(WaveClip &) >
 Type of function from which RegisteredFactory is constructed; it builds attachments. More...
 

Public Member Functions

 WaveClip (size_t width, const SampleBlockFactoryPtr &factory, sampleFormat format, int rate, int colourIndex)
 typical constructor More...
 
 WaveClip (const WaveClip &orig, const SampleBlockFactoryPtr &factory, bool copyCutlines)
 
 WaveClip (const WaveClip &orig, const SampleBlockFactoryPtr &factory, bool copyCutlines, double t0, double t1)
 Copy only a range from the given WaveClip. More...
 
virtual ~WaveClip ()
 
bool CheckInvariants () const
 Check invariant conditions on mSequences and mCutlines. More...
 
size_t GetWidth () const override
 
void ConvertToSampleFormat (sampleFormat format, const std::function< void(size_t)> &progressReport={})
 
int GetRate () const override
 
void SetRate (int rate)
 
void StretchLeftTo (double to)
 Stretches from left to the absolute time (if in expected range) More...
 
void StretchRightTo (double to)
 Sets from the right to the absolute time (if in expected range) More...
 
double GetStretchRatio () const override
 
void Resample (int rate, BasicUI::ProgressDialog *progress=nullptr)
 
void ApplyStretchRatio (const std::function< void(double)> &reportProgress)
 Renders the stretching of the clip (preserving duration). More...
 
void SetColourIndex (int index)
 
int GetColourIndex () const
 
double GetSequenceStartTime () const noexcept
 
void SetSequenceStartTime (double startTime)
 
double GetSequenceEndTime () const
 
sampleCount GetSequenceStartSample () const
 Returns the index of the first sample of the underlying sequence. More...
 
sampleCount GetSequenceSamplesCount () const
 
double GetPlayStartTime () const noexcept override
 
void SetPlayStartTime (double time)
 
double GetPlayEndTime () const override
 
double GetPlayDuration () const
 
sampleCount GetPlayStartSample () const
 Real start time of the clip, quantized to raw sample rate (track's rate) More...
 
sampleCount GetPlayEndSample () const
 Real end time of the clip, quantized to raw sample rate (track's rate) More...
 
sampleCount GetVisibleSampleCount () const override
 
void SetTrimLeft (double trim)
 Sets the play start offset in seconds from the beginning of the underlying sequence. More...
 
double GetTrimLeft () const noexcept
 Returns the play start offset in seconds from the beginning of the underlying sequence. More...
 
void SetTrimRight (double trim)
 Sets the play end offset in seconds from the ending of the underlying sequence. More...
 
double GetTrimRight () const noexcept
 Returns the play end offset in seconds from the ending of the underlying sequence. More...
 
void TrimLeft (double deltaTime)
 Moves play start position by deltaTime. More...
 
void TrimRight (double deltaTime)
 Moves play end position by deltaTime. More...
 
void TrimLeftTo (double to)
 Sets the the left trimming to the absolute time (if that is in bounds) More...
 
void TrimRightTo (double to)
 Sets the the right trimming to the absolute time (if that is in bounds) More...
 
void ShiftBy (double delta) noexcept
 
bool SplitsPlayRegion (double t) const
 [ < t and t < ), such that if the track were split at t, it would split this clip in two of lengths > 0. More...
 
bool WithinPlayRegion (double t) const
 t ∈ [...) More...
 
bool BeforePlayRegion (double t) const
 t < [ More...
 
bool AtOrBeforePlayRegion (double t) const
 t <= [ More...
 
bool AfterPlayRegion (double t) const
 ) <= t More...
 
bool EntirelyWithinPlayRegion (double t0, double t1) const
 t0 and t1 both ∈ [...) More...
 
bool PartlyWithinPlayRegion (double t0, double t1) const
 t0 xor t1 ∈ [...) More...
 
bool IntersectsPlayRegion (double t0, double t1) const
 [t0, t1) ∩ [...) != ∅ More...
 
bool CoversEntirePlayRegion (double t0, double t1) const
 t0 <= [ and ) <= t1, such that removing [t0, t1) from the track deletes this clip. More...
 
sampleCount CountSamples (double t0, double t1) const
 
AudioSegmentSampleView GetSampleView (size_t iChannel, sampleCount start, size_t length, bool mayThrow=true) const override
 Request up to length samples. The actual number of samples available from the returned view is queried through AudioSegmentSampleView::GetSampleCount(). More...
 
AudioSegmentSampleView GetSampleView (size_t iChannel, double t0, double t1, bool mayThrow=true) const
 Request interval samples within [t0, t1). t0 and t1 are truncated to the clip's play start and end. Stretching influences the number of samples fitting into [t0, t1), i.e., half as many for twice as large a stretch ratio, due to a larger spacing of the raw samples. The actual number of samples available from the returned view is queried through AudioSegmentSampleView::GetSampleCount(). More...
 
bool GetSamples (size_t ii, samplePtr buffer, sampleFormat format, sampleCount start, size_t len, bool mayThrow=true) const
 Get samples from one channel. More...
 
bool GetSamples (samplePtr buffers[], sampleFormat format, sampleCount start, size_t len, bool mayThrow=true) const
 Get (non-interleaved) samples from all channels. More...
 
void SetSamples (size_t ii, constSamplePtr buffer, sampleFormat format, sampleCount start, size_t len, sampleFormat effectiveFormat)
 
bool GetFloatAtTime (double t, size_t iChannel, float &value, bool mayThrow) const
 
EnvelopeGetEnvelope ()
 
const EnvelopeGetEnvelope () const
 
BlockArrayGetSequenceBlockArray (size_t ii)
 
const BlockArrayGetSequenceBlockArray (size_t ii) const
 
SequenceGetSequence (size_t ii)
 
const SequenceGetSequence (size_t ii) const
 
void MarkChanged ()
 
std::pair< float, float > GetMinMax (size_t ii, double t0, double t1, bool mayThrow) const
 
float GetRMS (size_t ii, double t0, double t1, bool mayThrow) const
 
void UpdateEnvelopeTrackLen ()
 
std::shared_ptr< SampleBlockAppendNewBlock (samplePtr buffer, sampleFormat format, size_t len)
 
void AppendSharedBlock (const std::shared_ptr< SampleBlock > &pBlock)
 
bool Append (constSamplePtr buffers[], sampleFormat format, size_t len, unsigned int stride, sampleFormat effectiveFormat)
 
void Flush ()
 Flush must be called after last Append. More...
 
void Clear (double t0, double t1)
 
void ClearLeft (double t)
 
void ClearRight (double t)
 
void ClearAndAddCutLine (double t0, double t1)
 
bool Paste (double t0, const WaveClip &other)
 Paste data from other clip, resampling it if not equal rate. More...
 
void InsertSilence (double t, double len, double *pEnvelopeValue=nullptr)
 
void AppendSilence (double len, double envelopeValue)
 
WaveClipHoldersGetCutLines ()
 Get access to cut lines list. More...
 
const WaveClipConstHoldersGetCutLines () const
 
size_t NumCutLines () const
 
bool FindCutLine (double cutLinePosition, double *cutLineStart=NULL, double *cutLineEnd=NULL) const
 
void ExpandCutLine (double cutLinePosition)
 
bool RemoveCutLine (double cutLinePosition)
 Remove cut line, without expanding the audio in it. More...
 
void OffsetCutLines (double t0, double len)
 Offset cutlines right to time 't0' by time amount 'len'. More...
 
void CloseLock () noexcept
 Should be called upon project close. Not balanced by unlocking calls. More...
 
bool HandleXMLTag (const std::string_view &tag, const AttributesList &attrs) override
 
void HandleXMLEndTag (const std::string_view &tag) override
 
XMLTagHandlerHandleXMLChild (const std::string_view &tag) override
 
void WriteXML (XMLWriter &xmlFile) const
 
bool GetIsPlaceholder () const
 
void SetIsPlaceholder (bool val)
 
bool SharesBoundaryWithNextClip (const WaveClip *next) const
 
void SetName (const wxString &name)
 
const wxString & GetName () const
 
sampleCount TimeToSamples (double time) const override
 
double SamplesToTime (sampleCount s) const noexcept
 
void SetSilence (sampleCount offset, sampleCount length)
 Silences the 'length' amount of samples starting from 'offset'(relative to the play start) More...
 
constSamplePtr GetAppendBuffer (size_t ii) const
 Get one channel of the append buffer. More...
 
size_t GetAppendBufferLen () const
 
void OnProjectTempoChange (const std::optional< double > &oldTempo, double newTempo)
 
bool HasEqualStretchRatio (const WaveClip &other) const
 
bool StretchRatioEquals (double value) const
 
void SetFloatsFromTime (double t, size_t iChannel, const float *buffer, size_t numSamples, sampleFormat effectiveFormat)
 Considers buffer as audio starting at TimeToSamples(t) (relative to clip play start time) and with equal stretch ratio. Samples at intersecting indices are then copied, leaving non-intersecting clip samples untouched. E.g., buffer: [a b c d e] clip : [x y z] result: [d e z]. More...
 
void SetFloatsCenteredAroundTime (double t, size_t iChannel, const float *buffer, size_t numSideSamples, sampleFormat effectiveFormat)
 Same as SetFloatsFromTime, but with buffer starting at TimeToSamples(t0 - SamplesToTime(numSideSamples)). [buffer, buffer + 2 * numSizeSamples + 1) is assumed to be a valid span of addresses. More...
 
void SetFloatAtTime (double t, size_t iChannel, float value, sampleFormat effectiveFormat)
 
- Public Member Functions inherited from ClipInterface
 ~ClipInterface () override
 
virtual AudioSegmentSampleView GetSampleView (size_t iChannel, sampleCount start, size_t length, bool mayThrow=true) const =0
 
virtual size_t GetWidth () const =0
 
- Public Member Functions inherited from ClipTimes
virtual ~ClipTimes ()
 
virtual sampleCount GetVisibleSampleCount () const =0
 
virtual int GetRate () const =0
 
virtual double GetPlayStartTime () const =0
 
virtual double GetPlayEndTime () const =0
 
virtual sampleCount TimeToSamples (double time) const =0
 
virtual double GetStretchRatio () const =0
 
- Public Member Functions inherited from XMLTagHandler
 XMLTagHandler ()
 
virtual ~XMLTagHandler ()
 
virtual bool HandleXMLTag (const std::string_view &tag, const AttributesList &attrs)=0
 
virtual void HandleXMLEndTag (const std::string_view &WXUNUSED(tag))
 
virtual void HandleXMLContent (const std::string_view &WXUNUSED(content))
 
virtual XMLTagHandlerHandleXMLChild (const std::string_view &tag)=0
 
void ReadXMLEndTag (const char *tag)
 
void ReadXMLContent (const char *s, int len)
 
XMLTagHandlerReadXMLChild (const char *tag)
 
- Public Member Functions inherited from ClientData::Site< WaveClip, WaveClipListener >
 ~Site ()
 
 Site ()
 
 Site (const Site &other)
 
 Site (Site &&other)
 
Siteoperator= (const Site &other)
 
Siteoperator= (Site &&other)
 
size_t size () const
 How many attachment pointers are in the Site. More...
 
Subclass & Get (const RegisteredFactory &key)
 Get reference to an attachment, creating on demand if not present, down-cast it to Subclass. More...
 
auto Get (const RegisteredFactory &key) const -> std::enable_if_t< std::is_const< Subclass >::value, Subclass & >
 Get reference to an attachment, creating on demand if not present, down-cast it to Subclass. More...
 
Subclass * Find (const RegisteredFactory &key)
 Get a (bare) pointer to an attachment, or null, down-cast it to Subclass *; will not create on demand. More...
 
auto Find (const RegisteredFactory &key) const -> std::enable_if_t< std::is_const< Subclass >::value, Subclass * >
 Get a (bare) pointer to an attachment, or null, down-cast it to Subclass *; will not create on demand. More...
 
void Assign (const RegisteredFactory &key, ReplacementPointer &&replacement)
 Reassign Site's pointer to ClientData. More...
 

Private Member Functions

 WaveClip (const WaveClip &)=delete
 
WaveClipoperator= (const WaveClip &)=delete
 
sampleCount TimeToSequenceSamples (double t) const
 
sampleCount GetNumSamples () const
 
SampleFormats GetSampleFormats () const
 
const SampleBlockFactoryPtrGetFactory ()
 
std::vector< std::unique_ptr< Sequence > > GetEmptySequenceCopies () const
 
void StretchCutLines (double ratioChange)
 
double SnapToTrackSample (double time) const noexcept
 
void ClearSequence (double t0, double t1)
 

Private Attributes

double mClipStretchRatio = 1.
 
std::optional< double > mRawAudioTempo
 
std::optional< double > mProjectTempo
 
int mRate
 Sample rate of the raw audio, i.e., before stretching. More...
 
int mColourIndex
 
std::vector< std::unique_ptr< Sequence > > mSequences
 
std::unique_ptr< EnvelopemEnvelope
 Envelope is unique, not per-sequence. More...
 
WaveClipHolders mCutLines {}
 
bool mIsPlaceholder { false }
 
wxString mName
 
double mSequenceOffset { 0 }
 
double mTrimLeft { 0 }
 
double mTrimRight { 0 }
 

Additional Inherited Members

- Static Public Member Functions inherited from ClientData::Site< WaveClip, WaveClipListener >
static size_t numFactories ()
 How many static factories have been registered with this specialization of Site. More...
 
- Protected Member Functions inherited from ClientData::Site< WaveClip, WaveClipListener >
void ForEach (const Function &function)
 Invoke function on each ClientData object that has been created in this. More...
 
void ForEach (const Function &function) const
 Invoke function on each ClientData object that has been created in this. More...
 
WaveClipListenerFindIf (const Function &function)
 Return pointer to first attachment in this that is not null and satisfies a predicate, or nullptr. More...
 
const WaveClipListenerFindIf (const Function &function) const
 Return pointer to first attachment in this that is not null and satisfies a predicate, or nullptr. More...
 
void BuildAll ()
 For each RegisteredFactory, if the corresponding attachment is absent in this, build and store it. More...
 

Detailed Description

This allows multiple clips to be a part of one WaveTrack.

Definition at line 99 of file WaveClip.h.

Member Typedef Documentation

◆ Caches

Definition at line 112 of file WaveClip.h.

Constructor & Destructor Documentation

◆ WaveClip() [1/4]

WaveClip::WaveClip ( const WaveClip )
privatedelete

◆ WaveClip() [2/4]

WaveClip::WaveClip ( size_t  width,
const SampleBlockFactoryPtr factory,
sampleFormat  format,
int  rate,
int  colourIndex 
)

typical constructor

Parameters
widthhow many sequences
Precondition
width > 0
Postcondition
GetWidth() == width

Definition at line 44 of file WaveClip.cpp.

47{
48 assert(width > 0);
49 mRate = rate;
50 mColourIndex = colourIndex;
51 mSequences.resize(width);
52 for (auto &pSequence : mSequences)
53 pSequence = std::make_unique<Sequence>(factory,
55
56 mEnvelope = std::make_unique<Envelope>(true, 1e-7, 2.0, 1.0);
57 assert(CheckInvariants());
58}
@ narrowestSampleFormat
Two synonyms for previous values that might change if more values were added.
Two sample formats, remembering format of original source and describing stored format.
Definition: SampleFormat.h:77
bool CheckInvariants() const
Check invariant conditions on mSequences and mCutlines.
Definition: WaveClip.cpp:1529
std::unique_ptr< Envelope > mEnvelope
Envelope is unique, not per-sequence.
Definition: WaveClip.h:632
int mRate
Sample rate of the raw audio, i.e., before stretching.
Definition: WaveClip.h:620
int mColourIndex
Definition: WaveClip.h:621
std::vector< std::unique_ptr< Sequence > > mSequences
Definition: WaveClip.h:630
static RegisteredToolbarFactory factory

References CheckInvariants(), cloud::factory, anonymous_namespace{ExportPCM.cpp}::format, mColourIndex, mEnvelope, mRate, mSequences, and narrowestSampleFormat.

Here is the call graph for this function:

◆ WaveClip() [3/4]

WaveClip::WaveClip ( const WaveClip orig,
const SampleBlockFactoryPtr factory,
bool  copyCutlines 
)

essentially a copy constructor - but you must pass in the current sample block factory, because we might be copying from one project to another

Postcondition
GetWidth() == orig.GetWidth()

Definition at line 60 of file WaveClip.cpp.

66{
67 // essentially a copy constructor - but you must pass in the
68 // current sample block factory, because we might be copying
69 // from one project to another
70
72 mTrimLeft = orig.mTrimLeft;
74 mRate = orig.mRate;
76 mSequences.reserve(orig.GetWidth());
77 for (auto &pSequence : orig.mSequences)
78 mSequences.push_back(
79 std::make_unique<Sequence>(*pSequence, factory));
80
81 mEnvelope = std::make_unique<Envelope>(*orig.mEnvelope);
82
83 mName = orig.mName;
84
85 if (copyCutlines)
86 for (const auto &clip: orig.mCutLines)
87 mCutLines.push_back(std::make_shared<WaveClip>(*clip, factory, true));
88
90
91 assert(GetWidth() == orig.GetWidth());
92 assert(CheckInvariants());
93}
std::optional< double > mRawAudioTempo
Definition: WaveClip.h:616
bool mIsPlaceholder
Definition: WaveClip.h:642
double mTrimRight
Definition: WaveClip.h:610
std::optional< double > mProjectTempo
Definition: WaveClip.h:617
wxString mName
Definition: WaveClip.h:645
bool GetIsPlaceholder() const
Definition: WaveClip.h:549
double mSequenceOffset
Definition: WaveClip.h:608
double mTrimLeft
Definition: WaveClip.h:609
WaveClipHolders mCutLines
Definition: WaveClip.h:639
size_t GetWidth() const override
Definition: WaveClip.cpp:167
double mClipStretchRatio
Definition: WaveClip.h:615

References CheckInvariants(), cloud::factory, GetIsPlaceholder(), GetWidth(), mColourIndex, mCutLines, mEnvelope, mIsPlaceholder, mName, mRate, mSequenceOffset, mSequences, mTrimLeft, and mTrimRight.

Here is the call graph for this function:

◆ WaveClip() [4/4]

WaveClip::WaveClip ( const WaveClip orig,
const SampleBlockFactoryPtr factory,
bool  copyCutlines,
double  t0,
double  t1 
)

Copy only a range from the given WaveClip.

Precondition
CountSamples(t1, t0) > 0
Postcondition
GetWidth() == orig.GetWidth()

Definition at line 95 of file WaveClip.cpp.

101{
102 assert(orig.CountSamples(t0, t1) > 0);
103
105
106 //Adjust trim values to sample-boundary
107 if(t0 > orig.GetPlayStartTime()) {
108 const auto s0 = orig.TimeToSamples(t0 - orig.GetSequenceStartTime());
109 mTrimLeft = orig.SamplesToTime(s0);
110
111 }
112 else
113 mTrimLeft = orig.mTrimLeft;
114
115 if(t1 < orig.GetPlayEndTime())
116 {
117 const auto s1 = orig.TimeToSamples(orig.GetSequenceEndTime() - t1);
118 mTrimRight = orig.SamplesToTime(s1);
119 }
120 else
121 mTrimRight = orig.mTrimRight;
122
123 mRate = orig.mRate;
125
127
128 mSequences.reserve(orig.GetWidth());
129 for (auto &pSequence : orig.mSequences)
130 mSequences.push_back(
131 std::make_unique<Sequence>(*pSequence, factory));
132
133 mEnvelope = std::make_unique<Envelope>(*orig.mEnvelope);
134
135 if (copyCutlines)
136 for (const auto &cutline : orig.mCutLines)
137 mCutLines.push_back(
138 std::make_shared<WaveClip>(*cutline, factory, true));
139
140 assert(GetWidth() == orig.GetWidth());
141 assert(CheckInvariants());
142}
double GetSequenceStartTime() const noexcept
Definition: WaveClip.cpp:1424
sampleCount TimeToSamples(double time) const override
Definition: WaveClip.cpp:1310
double GetPlayStartTime() const noexcept override
Definition: WaveClip.cpp:1340
sampleCount CountSamples(double t0, double t1) const
Definition: WaveClip.cpp:1507
double GetPlayEndTime() const override
Definition: WaveClip.cpp:1350
double SamplesToTime(sampleCount s) const noexcept
Definition: WaveClip.cpp:1315
double GetSequenceEndTime() const
Definition: WaveClip.cpp:1436

References CheckInvariants(), CountSamples(), cloud::factory, GetIsPlaceholder(), GetPlayEndTime(), GetPlayStartTime(), GetSequenceEndTime(), GetSequenceStartTime(), GetWidth(), mColourIndex, mCutLines, mEnvelope, mIsPlaceholder, mRate, mSequenceOffset, mSequences, mTrimLeft, mTrimRight, SamplesToTime(), and TimeToSamples().

Here is the call graph for this function:

◆ ~WaveClip()

WaveClip::~WaveClip ( )
virtual

Definition at line 145 of file WaveClip.cpp.

146{
147}

Member Function Documentation

◆ AfterPlayRegion()

bool WaveClip::AfterPlayRegion ( double  t) const

) <= t

Definition at line 1502 of file WaveClip.cpp.

1503{
1504 return GetPlayEndTime() <= t;
1505}

References GetPlayEndTime().

Here is the call graph for this function:

◆ Append()

bool WaveClip::Append ( constSamplePtr  buffers[],
sampleFormat  format,
size_t  len,
unsigned int  stride,
sampleFormat  effectiveFormat 
)

Append (non-interleaved) samples to all channels You must call Flush after the last Append

Returns
true if at least one complete block was created assume as many buffers available as GetWidth() In case of failure or exceptions, the clip contents are unchanged but un-flushed data are lost
Parameters
effectiveFormatMake the effective format of the data at least the minumum of this value and `format`. (Maybe wider, if merging with preexistent data.) If the data are later narrowed from stored format, but not narrower than the effective, then no dithering will occur.

Definition at line 488 of file WaveClip.cpp.

490{
491 Finally Do{ [this]{ assert(CheckInvariants()); } };
492
493 Transaction transaction{ *this };
494
495 //wxLogDebug(wxT("Append: len=%lli"), (long long) len);
496
497 size_t ii = 0;
498 bool appended = false;
499 for (auto &pSequence : mSequences)
500 appended =
501 pSequence->Append(buffers[ii++], format, len, stride, effectiveFormat)
502 || appended;
503
504 transaction.Commit();
505 // use No-fail-guarantee
507 MarkChanged();
508
509 return appended;
510}
void MarkChanged()
Definition: WaveClip.cpp:393
void UpdateEnvelopeTrackLen()
Definition: WaveClip.cpp:462
"finally" as in The C++ Programming Language, 4th ed., p. 358 Useful for defining ad-hoc RAII actions...
Definition: MemoryX.h:173

References CheckInvariants(), WaveClip::Transaction::Commit(), anonymous_namespace{ExportPCM.cpp}::format, MarkChanged(), mSequences, and UpdateEnvelopeTrackLen().

Here is the call graph for this function:

◆ AppendNewBlock()

std::shared_ptr< SampleBlock > WaveClip::AppendNewBlock ( samplePtr  buffer,
sampleFormat  format,
size_t  len 
)

For use in importing pre-version-3 projects to preserve sharing of blocks; no dithering applied

Precondition
GetWidth() == 1
Exception safety guarantee:
Strong

Definition at line 470 of file WaveClip.cpp.

472{
473 // This is a special use function for legacy files only and this assertion
474 // does not need to be relaxed
475 assert(GetWidth() == 1);
476 return mSequences[0]->AppendNewBlock( buffer, format, len );
477}

References anonymous_namespace{ExportPCM.cpp}::format, GetWidth(), and mSequences.

Here is the call graph for this function:

◆ AppendSharedBlock()

void WaveClip::AppendSharedBlock ( const std::shared_ptr< SampleBlock > &  pBlock)

For use in importing pre-version-3 projects to preserve sharing of blocks

Precondition
GetWidth() == 1
Exception safety guarantee:
Strong

Definition at line 480 of file WaveClip.cpp.

481{
482 // This is a special use function for legacy files only and this assertion
483 // does not need to be relaxed
484 assert(GetWidth() == 1);
485 mSequences[0]->AppendSharedBlock( pBlock );
486}

References GetWidth(), and mSequences.

Here is the call graph for this function:

◆ AppendSilence()

void WaveClip::AppendSilence ( double  len,
double  envelopeValue 
)

Insert silence at the end, and causes the envelope to ramp linearly to the given value

Exception safety guarantee:
Strong

Definition at line 801 of file WaveClip.cpp.

802{
803 auto t = GetPlayEndTime();
804 InsertSilence( t, len, &envelopeValue );
805}
void InsertSilence(double t, double len, double *pEnvelopeValue=nullptr)
Definition: WaveClip.cpp:757

References GetPlayEndTime(), and InsertSilence().

Here is the call graph for this function:

◆ ApplyStretchRatio()

void WaveClip::ApplyStretchRatio ( const std::function< void(double)> &  reportProgress)

Renders the stretching of the clip (preserving duration).

Postcondition
GetStretchRatio() == 1

Definition at line 1182 of file WaveClip.cpp.

1183{
1184 const auto stretchRatio = GetStretchRatio();
1185 if (stretchRatio == 1.0)
1186 return;
1187
1188 auto success = false;
1189 auto newSequences = GetEmptySequenceCopies();
1190 bool swappedOnce = false;
1191
1192 Finally Do { [&, trimLeftBeforeStretch = GetTrimLeft(),
1193 trimRightBeforeStretch = GetTrimRight(),
1194 offsetBeforeStretch = GetSequenceStartTime()] {
1195 if (success)
1196 {
1197 this->mClipStretchRatio = 1.0;
1198 this->mRawAudioTempo = this->mProjectTempo;
1199 assert(this->GetStretchRatio() == 1.0);
1200 }
1201 else
1202 {
1203 this->SetTrimLeft(trimLeftBeforeStretch);
1204 this->SetTrimRight(trimRightBeforeStretch);
1205 this->SetSequenceStartTime(offsetBeforeStretch);
1206 if (swappedOnce)
1207 std::swap(mSequences, newSequences);
1208 }
1209 } };
1210
1211 const auto originalPlayStartTime = GetPlayStartTime();
1212 const auto originalPlayEndTime = GetPlayEndTime();
1213
1214 // Leave 1 second of raw, unstretched audio before and after visible region
1215 // to ensure the algorithm is in a steady state when reaching the play
1216 // boundaries.
1217 TrimLeftTo(originalPlayStartTime - stretchRatio);
1218 TrimRightTo(originalPlayEndTime + stretchRatio);
1219
1220 // Let's not use the `durationToDiscard` functionality of the
1221 // `TimeAndPitchSource`: this determines the source readout offset. We want
1222 // to do better here: feed earlier samples, but discard the early output.
1223 constexpr auto sourceDurationToDiscard = 0.;
1224 constexpr auto blockSize = 1024;
1225 const auto numChannels = GetWidth();
1226
1227 ClipTimeAndPitchSource stretcherSource { *this, sourceDurationToDiscard,
1230 params.timeRatio = stretchRatio;
1231 StaffPadTimeAndPitch stretcher { GetRate(), numChannels, stretcherSource,
1232 std::move(params) };
1233
1234 // Post-rendering sample counts, i.e., stretched units
1235 int beginSamplesToDiscard =
1236 (originalPlayStartTime - GetPlayStartTime()) * GetRate() + .5;
1237 const int endSamplesToDiscard =
1238 (GetPlayEndTime() - originalPlayEndTime) * GetRate() + .5;
1239 const auto totalNumOutSamples =
1240 sampleCount { GetVisibleSampleCount().as_double() * stretchRatio -
1241 beginSamplesToDiscard - endSamplesToDiscard + .5 };
1242
1243 sampleCount numOutSamples { 0 };
1244 AudioContainer container(blockSize, numChannels);
1245 while (numOutSamples < totalNumOutSamples)
1246 {
1247 const auto numSamplesToGet =
1248 limitSampleBufferSize(blockSize, totalNumOutSamples - numOutSamples);
1249 stretcher.GetSamples(container.Get(), numSamplesToGet);
1250 const auto numSamplesToConsume =
1251 std::max(0, static_cast<int>(numSamplesToGet) - beginSamplesToDiscard);
1252 beginSamplesToDiscard -= numSamplesToGet - numSamplesToConsume;
1253 if (numSamplesToConsume == 0)
1254 continue;
1255 auto channel = 0u;
1256 for (auto& newSequence : newSequences)
1257 newSequence->Append(
1258 reinterpret_cast<samplePtr>(
1259 container.Get()[channel++] + numSamplesToGet -
1260 numSamplesToConsume),
1261 floatSample, numSamplesToConsume, 1,
1262 widestSampleFormat /* computed samples need dither */
1263 );
1264 numOutSamples += numSamplesToConsume;
1265 if (reportProgress)
1266 reportProgress(
1267 numOutSamples.as_double() / totalNumOutSamples.as_double());
1268 }
1269
1270 std::swap(mSequences, newSequences);
1271 swappedOnce = true;
1272
1273 // Now that sequences are swapped we don't have hidden data anymore. The
1274 // position of the visible part must be preserved, though.
1275 SetTrimLeft(0.);
1276 SetTrimRight(0.);
1277 SetSequenceStartTime(originalPlayStartTime);
1278
1279 Flush();
1280 Caches::ForEach(std::mem_fn(&WaveClipListener::Invalidate));
1281
1282 success = true;
1283}
EffectDistortionSettings params
Definition: Distortion.cpp:77
size_t limitSampleBufferSize(size_t bufferSize, sampleCount limit)
Definition: SampleCount.cpp:22
char * samplePtr
Definition: SampleFormat.h:55
std::vector< std::unique_ptr< Sequence > > GetEmptySequenceCopies() const
Definition: WaveClip.cpp:377
double GetStretchRatio() const override
Definition: WaveClip.cpp:339
void SetSequenceStartTime(double startTime)
Definition: WaveClip.cpp:1430
sampleCount GetVisibleSampleCount() const override
Definition: WaveClip.cpp:1377
double GetTrimRight() const noexcept
Returns the play end offset in seconds from the ending of the underlying sequence.
Definition: WaveClip.cpp:1398
int GetRate() const override
Definition: WaveClip.h:156
double GetTrimLeft() const noexcept
Returns the play start offset in seconds from the beginning of the underlying sequence.
Definition: WaveClip.cpp:1388
void TrimLeftTo(double to)
Sets the the left trimming to the absolute time (if that is in bounds)
Definition: WaveClip.cpp:1413
void TrimRightTo(double to)
Sets the the right trimming to the absolute time (if that is in bounds)
Definition: WaveClip.cpp:1419
void SetTrimRight(double trim)
Sets the play end offset in seconds from the ending of the underlying sequence.
Definition: WaveClip.cpp:1393
void SetTrimLeft(double trim)
Sets the play start offset in seconds from the beginning of the underlying sequence.
Definition: WaveClip.cpp:1383
void Flush()
Flush must be called after last Append.
Definition: WaveClip.cpp:512
Positions or offsets within audio files need a wide type.
Definition: SampleCount.h:19
double as_double() const
Definition: SampleCount.h:46
void swap(std::unique_ptr< Alg_seq > &a, std::unique_ptr< Alg_seq > &b)
Definition: NoteTrack.cpp:770
virtual void Invalidate()=0

References sampleCount::as_double(), floatSample, Flush(), forward, AudioContainer::Get(), GetEmptySequenceCopies(), GetPlayEndTime(), GetPlayStartTime(), GetRate(), GetSequenceStartTime(), GetStretchRatio(), GetTrimLeft(), GetTrimRight(), GetVisibleSampleCount(), GetWidth(), WaveClipListener::Invalidate(), limitSampleBufferSize(), mClipStretchRatio, mProjectTempo, mRawAudioTempo, mSequences, params, SetSequenceStartTime(), SetTrimLeft(), SetTrimRight(), anonymous_namespace{NoteTrack.cpp}::swap(), TrimLeftTo(), TrimRightTo(), and widestSampleFormat.

Here is the call graph for this function:

◆ AtOrBeforePlayRegion()

bool WaveClip::AtOrBeforePlayRegion ( double  t) const

t <= [

Definition at line 1497 of file WaveClip.cpp.

1498{
1499 return t <= GetPlayStartTime();
1500}

References GetPlayStartTime().

Here is the call graph for this function:

◆ BeforePlayRegion()

bool WaveClip::BeforePlayRegion ( double  t) const

t < [

Definition at line 1492 of file WaveClip.cpp.

1493{
1494 return t < GetPlayStartTime();
1495}

References GetPlayStartTime().

Referenced by EntirelyWithinPlayRegion().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ CheckInvariants()

bool WaveClip::CheckInvariants ( ) const

Check invariant conditions on mSequences and mCutlines.

Definition at line 1529 of file WaveClip.cpp.

1530{
1531 const auto width = GetWidth();
1532 auto iter = mSequences.begin(),
1533 end = mSequences.end();
1534 // There must be at least one pointer
1535 if (iter != end) {
1536 // All pointers mut be non-null
1537 auto &pFirst = *iter++;
1538 if (pFirst) {
1539 // All sequences must have the same lengths, append buffer lengths,
1540 // sample formats, and sample block factory
1541 return
1542 std::all_of(iter, end, [&](decltype(pFirst) pSequence) {
1543 return pSequence &&
1544 pSequence->GetNumSamples() == pFirst->GetNumSamples() &&
1545 pSequence->GetAppendBufferLen() == pFirst->GetAppendBufferLen()
1546 &&
1547 pSequence->GetSampleFormats() == pFirst->GetSampleFormats() &&
1548 pSequence->GetFactory() == pFirst->GetFactory();
1549 }) &&
1550 // All cut lines are non-null, satisfy the invariants, and match width
1551 std::all_of(mCutLines.begin(), mCutLines.end(),
1552 [width](const WaveClipHolder &pCutLine) {
1553 return pCutLine && pCutLine->GetWidth() == width &&
1554 pCutLine->CheckInvariants();
1555 });
1556 }
1557 }
1558 return false;
1559}
std::shared_ptr< WaveClip > WaveClipHolder
Definition: WaveClip.h:45
auto end(const Ptr< Type, BaseDeleter > &p)
Enables range-for.
Definition: PackedArray.h:159

References PackedArray::end(), GetWidth(), mCutLines, and mSequences.

Referenced by Append(), ClearAndAddCutLine(), HandleXMLEndTag(), Paste(), and WaveClip().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Clear()

void WaveClip::Clear ( double  t0,
double  t1 
)

This name is consistent with WaveTrack::Clear. It performs a "Cut" operation (but without putting the cut audio to the clipboard)

Exception safety guarantee:
Strong

Definition at line 808 of file WaveClip.cpp.

809{
810 auto st0 = t0;
811 auto st1 = t1;
812 auto offset = .0;
813 if (st0 <= GetPlayStartTime())
814 {
815 offset = (t0 - GetPlayStartTime()) + GetTrimLeft();
816 st0 = GetSequenceStartTime();
817
818 SetTrimLeft(.0);
819 }
820 if (st1 >= GetPlayEndTime())
821 {
822 st1 = GetSequenceEndTime();
823 SetTrimRight(.0);
824 }
825 ClearSequence(st0, st1);
826
827 if (offset != .0)
828 ShiftBy(offset);
829}
void ShiftBy(double delta) noexcept
Definition: WaveClip.cpp:1449
void ClearSequence(double t0, double t1)
Definition: WaveClip.cpp:850

References ClearSequence(), GetPlayEndTime(), GetPlayStartTime(), GetSequenceEndTime(), GetSequenceStartTime(), GetTrimLeft(), SetTrimLeft(), SetTrimRight(), and ShiftBy().

Here is the call graph for this function:

◆ ClearAndAddCutLine()

void WaveClip::ClearAndAddCutLine ( double  t0,
double  t1 
)

Clear, and add cut line that starts at t0 and contains everything until t1 if there is at least one clip sample between t0 and t1, noop otherwise.

Exception safety guarantee:
Weak – This WaveClip remains destructible in case of AudacityException. But some cutlines may be deleted

Definition at line 913 of file WaveClip.cpp.

914{
915 if (t0 > GetPlayEndTime() || t1 < GetPlayStartTime() || CountSamples(t0, t1) == 0)
916 return; // no samples to remove
917
918 Transaction transaction{ *this };
919
920 const double clip_t0 = std::max( t0, GetPlayStartTime() );
921 const double clip_t1 = std::min( t1, GetPlayEndTime() );
922
923 auto newClip = std::make_shared<WaveClip>(
924 *this, GetFactory(), true, clip_t0, clip_t1);
925 if(t1 < GetPlayEndTime())
926 {
927 newClip->ClearSequence(t1, newClip->GetSequenceEndTime());
928 newClip->SetTrimRight(.0);
929 }
930 if(t0 > GetPlayStartTime())
931 {
932 newClip->ClearSequence(newClip->GetSequenceStartTime(), t0);
933 newClip->SetTrimLeft(.0);
934 }
935
936 newClip->SetSequenceStartTime( clip_t0 - GetSequenceStartTime() );
937
938 // Remove cutlines from this clip that were in the selection, shift
939 // left those that were after the selection
940 // May DELETE as we iterate, so don't use range-for
941 for (auto it = mCutLines.begin(); it != mCutLines.end();)
942 {
943 WaveClip* clip = it->get();
944 double cutlinePosition = GetSequenceStartTime() + clip->GetSequenceStartTime();
945 if (cutlinePosition >= t0 && cutlinePosition <= t1)
946 it = mCutLines.erase(it);
947 else
948 {
949 if (cutlinePosition >= t1)
950 {
951 clip->ShiftBy(clip_t0 - clip_t1);
952 }
953 ++it;
954 }
955 }
956
957 // Clear actual audio data
958 auto s0 = TimeToSequenceSamples(t0);
959 auto s1 = TimeToSequenceSamples(t1);
960
961 // use Weak-guarantee
962 for (auto &pSequence : mSequences)
963 pSequence->Delete(s0, s1-s0);
964
965 // Collapse envelope
966 auto sampleTime = 1.0 / GetRate();
967 GetEnvelope()->CollapseRegion( t0, t1, sampleTime );
968
969 transaction.Commit();
970 MarkChanged();
971
972 mCutLines.push_back(std::move(newClip));
973
974 // New cutline was copied from this so will have correct width
975 assert(CheckInvariants());
976}
int min(int a, int b)
void CollapseRegion(double t0, double t1, double sampleDur)
Definition: Envelope.cpp:378
This allows multiple clips to be a part of one WaveTrack.
Definition: WaveClip.h:103
sampleCount TimeToSequenceSamples(double t) const
Definition: WaveClip.cpp:1520
Envelope * GetEnvelope()
Definition: WaveClip.h:393
const SampleBlockFactoryPtr & GetFactory()
Definition: WaveClip.cpp:371

References CheckInvariants(), Envelope::CollapseRegion(), CountSamples(), GetEnvelope(), GetFactory(), GetPlayEndTime(), GetPlayStartTime(), GetRate(), GetSequenceStartTime(), MarkChanged(), mCutLines, min(), mSequences, ShiftBy(), and TimeToSequenceSamples().

Here is the call graph for this function:

◆ ClearLeft()

void WaveClip::ClearLeft ( double  t)

Removes samples starting from the left boundary of the clip till t, if it's inside the play region. Also removes trimmed (hidden) data, if present. Changes offset to make remaining samples stay at their old place. Destructive operation.

Definition at line 831 of file WaveClip.cpp.

832{
833 if (t > GetPlayStartTime() && t < GetPlayEndTime())
834 {
836 SetTrimLeft(.0);
838 }
839}

References ClearSequence(), GetPlayEndTime(), GetPlayStartTime(), GetSequenceStartTime(), SetSequenceStartTime(), and SetTrimLeft().

Here is the call graph for this function:

◆ ClearRight()

void WaveClip::ClearRight ( double  t)

Removes samples starting from t (if it's inside the clip), till the right boundary. Also removes trimmed (hidden) data, if present. Destructive operation.

Definition at line 841 of file WaveClip.cpp.

842{
843 if (t > GetPlayStartTime() && t < GetPlayEndTime())
844 {
846 SetTrimRight(.0);
847 }
848}

References ClearSequence(), GetPlayEndTime(), GetPlayStartTime(), GetSequenceEndTime(), and SetTrimRight().

Here is the call graph for this function:

◆ ClearSequence()

void WaveClip::ClearSequence ( double  t0,
double  t1 
)
private

This name is consistent with WaveTrack::Clear. It performs a "Cut" operation (but without putting the cut audio to the clipboard)

Definition at line 850 of file WaveClip.cpp.

851{
852 Transaction transaction{ *this };
853
854 auto clip_t0 = std::max(t0, GetSequenceStartTime());
855 auto clip_t1 = std::min(t1, GetSequenceEndTime());
856
857 auto s0 = TimeToSequenceSamples(clip_t0);
858 auto s1 = TimeToSequenceSamples(clip_t1);
859
860 if (s0 != s1)
861 {
862 // use Strong-guarantee
863 for (auto &pSequence : mSequences)
864 pSequence->Delete(s0, s1 - s0);
865
866 // use No-fail-guarantee in the remaining
867
868 // msmeyer
869 //
870 // Delete all cutlines that are within the given area, if any.
871 //
872 // Note that when cutlines are active, two functions are used:
873 // Clear() and ClearAndAddCutLine(). ClearAndAddCutLine() is called
874 // whenever the user directly calls a command that removes some audio, e.g.
875 // "Cut" or "Clear" from the menu. This command takes care about recursive
876 // preserving of cutlines within clips. Clear() is called when internal
877 // operations want to remove audio. In the latter case, it is the right
878 // thing to just remove all cutlines within the area.
879 //
880
881 // May DELETE as we iterate, so don't use range-for
882 for (auto it = mCutLines.begin(); it != mCutLines.end();)
883 {
884 WaveClip* clip = it->get();
885 double cutlinePosition = GetSequenceStartTime() + clip->GetSequenceStartTime();
886 if (cutlinePosition >= t0 && cutlinePosition <= t1)
887 {
888 // This cutline is within the area, DELETE it
889 it = mCutLines.erase(it);
890 }
891 else
892 {
893 if (cutlinePosition >= t1)
894 {
895 clip->ShiftBy(clip_t0 - clip_t1);
896 }
897 ++it;
898 }
899 }
900
901 // Collapse envelope
902 auto sampleTime = 1.0 / GetRate();
903 GetEnvelope()->CollapseRegion(t0, t1, sampleTime);
904 }
905
906 transaction.Commit();
907 MarkChanged();
908}

References Envelope::CollapseRegion(), GetEnvelope(), GetRate(), GetSequenceEndTime(), GetSequenceStartTime(), MarkChanged(), mCutLines, min(), mSequences, ShiftBy(), and TimeToSequenceSamples().

Referenced by Clear(), ClearLeft(), ClearRight(), InsertSilence(), and Paste().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ CloseLock()

void WaveClip::CloseLock ( )
noexcept

Should be called upon project close. Not balanced by unlocking calls.

Exception safety guarantee:
No-fail

Definition at line 1061 of file WaveClip.cpp.

1062{
1063 // Don't need a Transaction for noexcept operations
1064 for (auto &pSequence : mSequences)
1065 pSequence->CloseLock();
1066 for (const auto &cutline: mCutLines)
1067 cutline->CloseLock();
1068}

References mCutLines, and mSequences.

◆ ConvertToSampleFormat()

void WaveClip::ConvertToSampleFormat ( sampleFormat  format,
const std::function< void(size_t)> &  progressReport = {} 
)

Definition at line 440 of file WaveClip.cpp.

442{
443 // Note: it is not necessary to do this recursively to cutlines.
444 // They get converted as needed when they are expanded.
445
446 Transaction transaction{ *this };
447
448 auto bChanged = mSequences[0]->ConvertToSampleFormat(format, progressReport);
449 for (size_t ii = 1, width = GetWidth(); ii < width; ++ii) {
450 bool alsoChanged =
451 mSequences[ii]->ConvertToSampleFormat(format, progressReport);
452 // Class invariant implies:
453 assert(bChanged == alsoChanged);
454 }
455 if (bChanged)
456 MarkChanged();
457
458 transaction.Commit();
459}

References anonymous_namespace{ExportPCM.cpp}::format, GetWidth(), MarkChanged(), and mSequences.

Here is the call graph for this function:

◆ CountSamples()

sampleCount WaveClip::CountSamples ( double  t0,
double  t1 
) const

Counts number of samples within t0 and t1 region. t0 and t1 are rounded to the nearest clip sample boundary, i.e. relative to clips start time offset.

Returns
Number of samples within t0 and t1 if t1 > t0, 0 otherwise

Definition at line 1507 of file WaveClip.cpp.

1508{
1509 if(t0 < t1)
1510 {
1511 t0 = std::max(t0, GetPlayStartTime());
1512 t1 = std::min(t1, GetPlayEndTime());
1513 const auto s0 = TimeToSamples(t0 - GetPlayStartTime());
1514 const auto s1 = TimeToSamples(t1 - GetPlayStartTime());
1515 return s1 - s0;
1516 }
1517 return { 0 };
1518}

References GetPlayEndTime(), GetPlayStartTime(), min(), and TimeToSamples().

Referenced by ClearAndAddCutLine(), and WaveClip().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ CoversEntirePlayRegion()

bool WaveClip::CoversEntirePlayRegion ( double  t0,
double  t1 
) const

t0 <= [ and ) <= t1, such that removing [t0, t1) from the track deletes this clip.

Precondition
t0 <= t1

Definition at line 1486 of file WaveClip.cpp.

1487{
1488 assert(t0 <= t1);
1489 return t0 <= GetPlayStartTime() && GetPlayEndTime() <= t1;
1490}

References GetPlayEndTime(), and GetPlayStartTime().

Here is the call graph for this function:

◆ EntirelyWithinPlayRegion()

bool WaveClip::EntirelyWithinPlayRegion ( double  t0,
double  t1 
) const

t0 and t1 both ∈ [...)

Precondition
t0 <= t1

Definition at line 1464 of file WaveClip.cpp.

1465{
1466 assert(t0 <= t1);
1467 // t1 is the open end of the interval, hence it's ok if it's equal to the
1468 // open end of the play region.
1469 return !BeforePlayRegion(t0) && t1 <= GetPlayEndTime();
1470}
bool BeforePlayRegion(double t) const
t < [
Definition: WaveClip.cpp:1492

References BeforePlayRegion(), and GetPlayEndTime().

Here is the call graph for this function:

◆ ExpandCutLine()

void WaveClip::ExpandCutLine ( double  cutLinePosition)

Expand cut line (that is, re-insert audio, then DELETE audio saved in cut line). Returns true if a cut line could be found and successfully expanded, false otherwise

Exception safety guarantee:
Strong

Definition at line 999 of file WaveClip.cpp.

1000{
1001 auto end = mCutLines.end();
1002 auto it = std::find_if( mCutLines.begin(), end,
1003 [&](const WaveClipHolder &cutline) {
1004 return fabs(GetSequenceStartTime() + cutline->GetSequenceStartTime() - cutLinePosition) < 0.0001;
1005 } );
1006
1007 if ( it != end ) {
1008 auto *cutline = it->get();
1009 // assume Strong-guarantee from Paste
1010
1011 // Envelope::Paste takes offset into account, WaveClip::Paste doesn't!
1012 // Do this to get the right result:
1013 cutline->mEnvelope->SetOffset(0);
1014
1015 bool success =
1016 Paste(GetSequenceStartTime() + cutline->GetSequenceStartTime(),
1017 *cutline);
1018 assert(success); // class invariant promises cutlines have correct width
1019
1020 // Now erase the cutline,
1021 // but be careful to find it again, because Paste above may
1022 // have modified the array of cutlines (if our cutline contained
1023 // another cutline!), invalidating the iterator we had.
1024 end = mCutLines.end();
1025 it = std::find_if(mCutLines.begin(), end,
1026 [=](const WaveClipHolder &p) { return p.get() == cutline; });
1027 if (it != end)
1028 mCutLines.erase(it); // deletes cutline!
1029 else {
1030 wxASSERT(false);
1031 }
1032 }
1033}
bool Paste(double t0, const WaveClip &other)
Paste data from other clip, resampling it if not equal rate.
Definition: WaveClip.cpp:663

References PackedArray::end(), GetSequenceStartTime(), mCutLines, and Paste().

Here is the call graph for this function:

◆ FindCutLine()

bool WaveClip::FindCutLine ( double  cutLinePosition,
double *  cutLineStart = NULL,
double *  cutLineEnd = NULL 
) const

Find cut line at (approximately) this position. Returns true and fills in cutLineStart and cutLineEnd (if specified) if a cut line at this position could be found. Return false otherwise.

Definition at line 978 of file WaveClip.cpp.

981{
982 for (const auto &cutline: mCutLines)
983 {
984 if (fabs(GetSequenceStartTime() + cutline->GetSequenceStartTime() - cutLinePosition) < 0.0001)
985 {
986 auto startTime = GetSequenceStartTime() + cutline->GetSequenceStartTime();
987 if (cutlineStart)
988 *cutlineStart = startTime;
989 if (cutlineEnd)
990 *cutlineEnd = startTime + cutline->SamplesToTime(cutline->GetVisibleSampleCount());
991 return true;
992 }
993 }
994
995 return false;
996}

References GetSequenceStartTime(), and mCutLines.

Here is the call graph for this function:

◆ Flush()

void WaveClip::Flush ( )

Flush must be called after last Append.

In case of exceptions, the clip contents are unchanged but un-flushed data are lost

Definition at line 512 of file WaveClip.cpp.

513{
514 //wxLogDebug(wxT("WaveClip::Flush"));
515 //wxLogDebug(wxT(" mAppendBufferLen=%lli"), (long long) mAppendBufferLen);
516 //wxLogDebug(wxT(" previous sample count %lli"), (long long) mSequence->GetNumSamples());
517
518 if (GetAppendBufferLen() > 0) {
519
520 Transaction transaction{ *this };
521
522 for (auto &pSequence : mSequences)
523 pSequence->Flush();
524
525 transaction.Commit();
526
527 // No-fail operations
529 MarkChanged();
530 }
531
532 //wxLogDebug(wxT("now sample count %lli"), (long long) mSequence->GetNumSamples());
533}
size_t GetAppendBufferLen() const
Definition: WaveClip.cpp:265

References WaveClip::Transaction::Commit(), GetAppendBufferLen(), MarkChanged(), mSequences, and UpdateEnvelopeTrackLen().

Referenced by ApplyStretchRatio(), WaveTrack::FlushOne(), and Resample().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetAppendBuffer()

constSamplePtr WaveClip::GetAppendBuffer ( size_t  ii) const

Get one channel of the append buffer.

Parameters
iiidentifies the channel
Precondition
ii < GetWidth()

Definition at line 387 of file WaveClip.cpp.

388{
389 assert(ii < GetWidth());
390 return mSequences[ii]->GetAppendBuffer();
391}

References GetWidth(), and mSequences.

Referenced by WaveChannelInterval::GetAppendBuffer().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetAppendBufferLen()

size_t WaveClip::GetAppendBufferLen ( ) const

Definition at line 265 of file WaveClip.cpp.

266{
267 // All append buffers have equal lengths by class invariant
268 return mSequences[0]->GetAppendBufferLen();
269}

References mSequences.

Referenced by Flush(), WaveChannelInterval::GetAppendBufferLen(), and GetPlayEndTime().

Here is the caller graph for this function:

◆ GetColourIndex()

int WaveClip::GetColourIndex ( ) const
inline

Definition at line 189 of file WaveClip.h.

189{ return mColourIndex; }

Referenced by WaveChannelInterval::GetColourIndex().

Here is the caller graph for this function:

◆ GetCutLines() [1/2]

WaveClipHolders & WaveClip::GetCutLines ( )
inline

Get access to cut lines list.

Definition at line 512 of file WaveClip.h.

512{ return mCutLines; }

◆ GetCutLines() [2/2]

const WaveClipConstHolders & WaveClip::GetCutLines ( ) const
inline

Definition at line 513 of file WaveClip.h.

514 { return reinterpret_cast< const WaveClipConstHolders& >( mCutLines ); }
std::vector< std::shared_ptr< const WaveClip > > WaveClipConstHolders
Definition: WaveClip.h:47

◆ GetEmptySequenceCopies()

std::vector< std::unique_ptr< Sequence > > WaveClip::GetEmptySequenceCopies ( ) const
private

Definition at line 377 of file WaveClip.cpp.

378{
379 decltype(mSequences) newSequences;
380 newSequences.reserve(mSequences.size());
381 for (auto& pSequence : mSequences)
382 newSequences.push_back(std::make_unique<Sequence>(
383 pSequence->GetFactory(), pSequence->GetSampleFormats()));
384 return newSequences;
385}

References mSequences.

Referenced by ApplyStretchRatio(), and Resample().

Here is the caller graph for this function:

◆ GetEnvelope() [1/2]

Envelope * WaveClip::GetEnvelope ( )
inline

Definition at line 393 of file WaveClip.h.

393{ return mEnvelope.get(); }

Referenced by ClearAndAddCutLine(), ClearSequence(), WaveChannelInterval::GetEnvelope(), WaveTrack::GetEnvelopeAtTime(), AUPImportFileHandle::HandleEnvelope(), WaveTrack::HandleXMLChild(), and InsertSilence().

Here is the caller graph for this function:

◆ GetEnvelope() [2/2]

const Envelope * WaveClip::GetEnvelope ( ) const
inline

Definition at line 394 of file WaveClip.h.

394{ return mEnvelope.get(); }

◆ GetFactory()

const SampleBlockFactoryPtr & WaveClip::GetFactory ( )
private

Definition at line 371 of file WaveClip.cpp.

372{
373 // All sequences have the same factory by class invariant
374 return mSequences[0]->GetFactory();
375}

References mSequences.

Referenced by ClearAndAddCutLine(), Paste(), and WaveClip::Transaction::Transaction().

Here is the caller graph for this function:

◆ GetFloatAtTime()

bool WaveClip::GetFloatAtTime ( double  t,
size_t  iChannel,
float &  value,
bool  mayThrow 
) const
Parameters
trelative to clip start sample

Definition at line 204 of file WaveClip.cpp.

206{
207 if (!WithinPlayRegion(t))
208 return false;
209 const auto start = TimeToSamples(t);
210 return GetSamples(
211 iChannel, reinterpret_cast<samplePtr>(&value), floatSample, start, 1u,
212 mayThrow);
213}
bool WithinPlayRegion(double t) const
t ∈ [...)
Definition: WaveClip.cpp:1459
bool GetSamples(size_t ii, samplePtr buffer, sampleFormat format, sampleCount start, size_t len, bool mayThrow=true) const
Get samples from one channel.
Definition: WaveClip.cpp:172

References floatSample, GetSamples(), anonymous_namespace{StretchingSequenceIntegrationTest.cpp}::iChannel, TimeToSamples(), and WithinPlayRegion().

Here is the call graph for this function:

◆ GetIsPlaceholder()

bool WaveClip::GetIsPlaceholder ( ) const
inline

Definition at line 549 of file WaveClip.h.

549{ return mIsPlaceholder; }

Referenced by WaveClip().

Here is the caller graph for this function:

◆ GetMinMax()

std::pair< float, float > WaveClip::GetMinMax ( size_t  ii,
double  t0,
double  t1,
bool  mayThrow 
) const

Getting high-level data for one channel for screen display and clipping calculations and Contrast

Parameters
iiidentifies the channel
Precondition
ii < GetWidth()

Definition at line 398 of file WaveClip.cpp.

400{
401 assert(ii < GetWidth());
402 t0 = std::max(t0, GetPlayStartTime());
403 t1 = std::min(t1, GetPlayEndTime());
404 if (t0 > t1) {
405 if (mayThrow)
407 return {
408 0.f, // harmless, but unused since Sequence::GetMinMax does not use these values
409 0.f // harmless, but unused since Sequence::GetMinMax does not use these values
410 };
411 }
412
413 if (t0 == t1)
414 return{ 0.f, 0.f };
415
416 auto s0 = TimeToSequenceSamples(t0);
417 auto s1 = TimeToSequenceSamples(t1);
418
419 return mSequences[ii]->GetMinMax(s0, s1 - s0, mayThrow);
420}
#define THROW_INCONSISTENCY_EXCEPTION
Throw InconsistencyException, using C++ preprocessor to identify the source code location.

References GetPlayEndTime(), GetPlayStartTime(), GetWidth(), min(), mSequences, THROW_INCONSISTENCY_EXCEPTION, and TimeToSequenceSamples().

Here is the call graph for this function:

◆ GetName()

const wxString & WaveClip::GetName ( ) const

Definition at line 1305 of file WaveClip.cpp.

1306{
1307 return mName;
1308}

References mName.

◆ GetNumSamples()

sampleCount WaveClip::GetNumSamples ( ) const
private

Definition at line 359 of file WaveClip.cpp.

360{
361 // All sequences have equal lengths by class invariant
362 return mSequences[0]->GetNumSamples();
363}

References mSequences.

Referenced by GetPlayEndTime(), GetSampleView(), GetSequenceEndTime(), GetSequenceSamplesCount(), GetVisibleSampleCount(), Resample(), SetRate(), TimeToSequenceSamples(), and UpdateEnvelopeTrackLen().

Here is the caller graph for this function:

◆ GetPlayDuration()

double WaveClip::GetPlayDuration ( ) const

Always a multiple of the track's sample period, whether the clip is stretched or not.

Definition at line 1362 of file WaveClip.cpp.

1363{
1364 return GetPlayEndTime() - GetPlayStartTime();
1365}

References GetPlayEndTime(), and GetPlayStartTime().

Referenced by anonymous_namespace{WaveTrack.cpp}::GetSampleAccessArgs().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetPlayEndSample()

sampleCount WaveClip::GetPlayEndSample ( ) const

Real end time of the clip, quantized to raw sample rate (track's rate)

Definition at line 1372 of file WaveClip.cpp.

1373{
1374 return sampleCount { GetPlayEndTime() * mRate + 0.5 };
1375}

References GetPlayEndTime(), and mRate.

Referenced by WaveTrack::ReverseOne().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetPlayEndTime()

double WaveClip::GetPlayEndTime ( ) const
overridevirtual

Open-end of play region. Always a multiple of the track's sample period, whether the clip is stretched or not.

Implements ClipTimes.

Definition at line 1350 of file WaveClip.cpp.

1351{
1352 const auto numSamples = GetNumSamples();
1353 double maxLen = mSequenceOffset +
1354 ((numSamples + GetAppendBufferLen()).as_double()) *
1356 mTrimRight;
1357 // JS: calculated value is not the length;
1358 // it is a maximum value and can be negative; no clipping to 0
1359 return SnapToTrackSample(maxLen);
1360}
double SnapToTrackSample(double time) const noexcept
Definition: WaveClip.cpp:1320
sampleCount GetNumSamples() const
Definition: WaveClip.cpp:359

References GetAppendBufferLen(), GetNumSamples(), GetStretchRatio(), mRate, mSequenceOffset, mTrimRight, and SnapToTrackSample().

Referenced by AUPImportFileHandle::AddSilence(), AfterPlayRegion(), AppendSilence(), ApplyStretchRatio(), WaveTrack::CanInsertClip(), Clear(), ClearAndAddCutLine(), WaveTrack::ClearAndPasteOne(), ClearLeft(), ClearRight(), CountSamples(), CoversEntirePlayRegion(), WaveChannelInterval::End(), EntirelyWithinPlayRegion(), WaveTrack::GetAdjacentClip(), GetMinMax(), GetPlayDuration(), GetPlayEndSample(), WaveChannelInterval::GetPlayEndTime(), InsertSilence(), IntersectsPlayRegion(), WaveTrackUtils::IsClipSelected(), WaveTrack::MergeOneClipPair(), Paste(), WaveTrack::PasteOne(), SplitsPlayRegion(), StretchLeftTo(), StretchRightTo(), TrimLeftTo(), WaveClip(), and WithinPlayRegion().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetPlayStartSample()

sampleCount WaveClip::GetPlayStartSample ( ) const

Real start time of the clip, quantized to raw sample rate (track's rate)

Definition at line 1367 of file WaveClip.cpp.

1368{
1369 return sampleCount { GetPlayStartTime() * mRate + 0.5 };
1370}

References GetPlayStartTime(), and mRate.

Referenced by WaveTrack::ReverseOne().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetPlayStartTime()

double WaveClip::GetPlayStartTime ( ) const
overridevirtualnoexcept

Closed-begin of play region. Always a multiple of the track's sample period, whether the clip is stretched or not.

Implements ClipTimes.

Definition at line 1340 of file WaveClip.cpp.

1341{
1343}

References mSequenceOffset, mTrimLeft, and SnapToTrackSample().

Referenced by ApplyStretchRatio(), AtOrBeforePlayRegion(), BeforePlayRegion(), WaveTrack::CanInsertClip(), Clear(), ClearAndAddCutLine(), WaveTrack::ClearAndPasteOne(), ClearLeft(), ClearRight(), CountSamples(), CoversEntirePlayRegion(), WaveTrack::GetAdjacentClip(), GetMinMax(), GetPlayDuration(), GetPlayStartSample(), WaveChannelInterval::GetPlayStartTime(), anonymous_namespace{WaveTrack.cpp}::GetSampleAccessArgs(), InsertSilence(), IntersectsPlayRegion(), WaveTrackUtils::IsClipSelected(), WaveTrack::JoinOne(), Paste(), WaveTrack::PasteOne(), WaveTrack::RightmostOrNewClip(), SharesBoundaryWithNextClip(), SplitsPlayRegion(), WaveChannelInterval::Start(), StretchLeftTo(), StretchRightTo(), TrimRightTo(), WaveClip(), and WithinPlayRegion().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetRate()

int WaveClip::GetRate ( ) const
inlineoverridevirtual

Implements ClipTimes.

Definition at line 156 of file WaveClip.h.

157 {
158 return mRate;
159 }

Referenced by ApplyStretchRatio(), ClearAndAddCutLine(), ClearSequence(), WaveChannelInterval::GetRate(), anonymous_namespace{WaveTrack.cpp}::GetSampleAccessArgs(), InsertSilence(), Paste(), anonymous_namespace{SampleHandle.cpp}::SampleResolutionTest(), SharesBoundaryWithNextClip(), and UpdateEnvelopeTrackLen().

Here is the caller graph for this function:

◆ GetRMS()

float WaveClip::GetRMS ( size_t  ii,
double  t0,
double  t1,
bool  mayThrow 
) const

Getting high-level data for one channel for screen display and clipping calculations and Contrast

Parameters
iiidentifies the channel
Precondition
ii < GetWidth()

Definition at line 422 of file WaveClip.cpp.

423{
424 assert(ii < GetWidth());
425 if (t0 > t1) {
426 if (mayThrow)
428 return 0.f;
429 }
430
431 if (t0 == t1)
432 return 0.f;
433
434 auto s0 = TimeToSequenceSamples(t0);
435 auto s1 = TimeToSequenceSamples(t1);
436
437 return mSequences[ii]->GetRMS(s0, s1-s0, mayThrow);
438}

References GetWidth(), mSequences, THROW_INCONSISTENCY_EXCEPTION, and TimeToSequenceSamples().

Here is the call graph for this function:

◆ GetSampleFormats()

SampleFormats WaveClip::GetSampleFormats ( ) const
private

Definition at line 365 of file WaveClip.cpp.

366{
367 // All sequences have the same formats by class invariant
368 return mSequences[0]->GetSampleFormats();
369}

References mSequences.

Referenced by Paste().

Here is the caller graph for this function:

◆ GetSamples() [1/2]

bool WaveClip::GetSamples ( samplePtr  buffers[],
sampleFormat  format,
sampleCount  start,
size_t  len,
bool  mayThrow = true 
) const

Get (non-interleaved) samples from all channels.

assume as many buffers available as GetWidth()

Parameters
startrelative to clip play start sample

Definition at line 181 of file WaveClip.cpp.

183{
184 bool result = true;
185 for (size_t ii = 0, width = GetWidth(); result && ii < width; ++ii)
186 result = GetSamples(ii, buffers[ii], format, start, len, mayThrow);
187 return result;
188}

References anonymous_namespace{ExportPCM.cpp}::format, GetSamples(), and GetWidth().

Here is the call graph for this function:

◆ GetSamples() [2/2]

bool WaveClip::GetSamples ( size_t  ii,
samplePtr  buffer,
sampleFormat  format,
sampleCount  start,
size_t  len,
bool  mayThrow = true 
) const

Get samples from one channel.

Parameters
iiidentifies the channel
startrelative to clip play start sample
Precondition
ii < GetWidth()

Definition at line 172 of file WaveClip.cpp.

175{
176 assert(ii < GetWidth());
177 return mSequences[ii]
178 ->Get(buffer, format, start + TimeToSamples(mTrimLeft), len, mayThrow);
179}

References anonymous_namespace{ExportPCM.cpp}::format, GetWidth(), mSequences, mTrimLeft, and TimeToSamples().

Referenced by GetFloatAtTime(), WaveChannelInterval::GetSamples(), and GetSamples().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetSampleView() [1/2]

AudioSegmentSampleView WaveClip::GetSampleView ( size_t  iChannel,
double  t0,
double  t1,
bool  mayThrow = true 
) const

Request interval samples within [t0, t1). t0 and t1 are truncated to the clip's play start and end. Stretching influences the number of samples fitting into [t0, t1), i.e., half as many for twice as large a stretch ratio, due to a larger spacing of the raw samples. The actual number of samples available from the returned view is queried through AudioSegmentSampleView::GetSampleCount().

Precondition
iChannel < GetWidth()
stretched samples in [t0, t1) can be counted in a size_t

Definition at line 157 of file WaveClip.cpp.

159{
160 assert(iChannel < GetWidth());
161 const auto start = TimeToSamples(std::max(0., t0));
162 const auto length =
163 (std::min(GetNumSamples(), TimeToSamples(t1)) - start).as_size_t();
164 return GetSampleView(iChannel, start, length, mayThrow);
165}
AudioSegmentSampleView GetSampleView(size_t iChannel, sampleCount start, size_t length, bool mayThrow=true) const override
Request up to length samples. The actual number of samples available from the returned view is querie...
Definition: WaveClip.cpp:149

References GetNumSamples(), GetSampleView(), GetWidth(), anonymous_namespace{StretchingSequenceIntegrationTest.cpp}::iChannel, min(), and TimeToSamples().

Here is the call graph for this function:

◆ GetSampleView() [2/2]

AudioSegmentSampleView WaveClip::GetSampleView ( size_t  iChannel,
sampleCount  start,
size_t  length,
bool  mayThrow = true 
) const
overridevirtual

Request up to length samples. The actual number of samples available from the returned view is queried through AudioSegmentSampleView::GetSampleCount().

Parameters
startindex of first clip sample from play start
Precondition
iChannel < GetWidth()

Implements ClipInterface.

Definition at line 149 of file WaveClip.cpp.

151{
152 assert(ii < GetWidth());
153 return mSequences[ii]->GetFloatSampleView(
154 start + TimeToSamples(mTrimLeft), length, mayThrow);
155}

References GetWidth(), mSequences, mTrimLeft, and TimeToSamples().

Referenced by WaveChannelInterval::GetSampleView(), and GetSampleView().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetSequence() [1/2]

Sequence * WaveClip::GetSequence ( size_t  ii)
inline

Get low-level access to a sequence. Whenever possible, don't use this, but use more high-level functions inside WaveClip (or add them if you think they are useful for general use)

Precondition
ii < GetWidth()

Definition at line 412 of file WaveClip.h.

412 {
413 assert(ii < GetWidth());
414 return mSequences[ii].get();
415 }

Referenced by WaveTrack::GetIdealBlockSize(), WaveChannelInterval::GetSequence(), and WaveTrack::HandleXMLChild().

Here is the caller graph for this function:

◆ GetSequence() [2/2]

const Sequence * WaveClip::GetSequence ( size_t  ii) const
inline

Get low-level access to a sequence. Whenever possible, don't use this, but use more high-level functions inside WaveClip (or add them if you think they are useful for general use)

Precondition
ii < GetWidth()

Definition at line 419 of file WaveClip.h.

419{ return mSequences[ii].get(); }

◆ GetSequenceBlockArray() [1/2]

BlockArray * WaveClip::GetSequenceBlockArray ( size_t  ii)
Parameters
iiidentifies the channel
Precondition
ii < GetWidth()

Definition at line 253 of file WaveClip.cpp.

254{
255 assert(ii < GetWidth());
256 return &mSequences[ii]->GetBlockArray();
257}

References GetWidth(), and mSequences.

Here is the call graph for this function:

◆ GetSequenceBlockArray() [2/2]

const BlockArray * WaveClip::GetSequenceBlockArray ( size_t  ii) const

Parameters
iiidentifies the channel
Precondition
ii < GetWidth()

Definition at line 259 of file WaveClip.cpp.

260{
261 assert(ii < GetWidth());
262 return &mSequences[ii]->GetBlockArray();
263}

References GetWidth(), and mSequences.

Here is the call graph for this function:

◆ GetSequenceEndTime()

double WaveClip::GetSequenceEndTime ( ) const

Definition at line 1436 of file WaveClip.cpp.

1437{
1438 const auto numSamples = GetNumSamples();
1439 double maxLen = GetSequenceStartTime() +
1440 numSamples.as_double() * GetStretchRatio() / mRate;
1441 return maxLen;
1442}

References GetNumSamples(), GetSequenceStartTime(), GetStretchRatio(), and mRate.

Referenced by Clear(), ClearRight(), ClearSequence(), InsertSilence(), Paste(), TimeToSequenceSamples(), TrimRightTo(), and WaveClip().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetSequenceSamplesCount()

sampleCount WaveClip::GetSequenceSamplesCount ( ) const

Returns the total number of samples in all underlying sequences (but not counting the cutlines)

Definition at line 1335 of file WaveClip.cpp.

1336{
1337 return GetNumSamples() * GetWidth();
1338}

References GetNumSamples(), and GetWidth().

Here is the call graph for this function:

◆ GetSequenceStartSample()

sampleCount WaveClip::GetSequenceStartSample ( ) const

Returns the index of the first sample of the underlying sequence.

Definition at line 1444 of file WaveClip.cpp.

1445{
1447}

References mSequenceOffset, and TimeToSamples().

Here is the call graph for this function:

◆ GetSequenceStartTime()

double WaveClip::GetSequenceStartTime ( ) const
noexcept

Definition at line 1424 of file WaveClip.cpp.

1425{
1426 // JS: mSequenceOffset is the minimum value and it is returned; no clipping to 0
1427 return mSequenceOffset;
1428}

References mSequenceOffset.

Referenced by ApplyStretchRatio(), Clear(), ClearAndAddCutLine(), WaveTrack::ClearAndPasteOne(), ClearLeft(), ClearSequence(), ExpandCutLine(), FindCutLine(), GetSequenceEndTime(), InsertSilence(), OffsetCutLines(), Paste(), RemoveCutLine(), SetRate(), TimeToSequenceSamples(), and WaveClip().

Here is the caller graph for this function:

◆ GetStretchRatio()

double WaveClip::GetStretchRatio ( ) const
overridevirtual

Implements ClipTimes.

Definition at line 339 of file WaveClip.cpp.

340{
341 const auto dstSrcRatio =
342 mProjectTempo.has_value() && mRawAudioTempo.has_value() ?
344 1.0;
345 return mClipStretchRatio * dstSrcRatio;
346}

References mClipStretchRatio, mProjectTempo, and mRawAudioTempo.

Referenced by ApplyStretchRatio(), GetPlayEndTime(), anonymous_namespace{WaveTrack.cpp}::GetSampleAccessArgs(), GetSequenceEndTime(), WaveChannelInterval::GetStretchRatio(), HasEqualStretchRatio(), SharesBoundaryWithNextClip(), StretchRatioEquals(), and TimeToSamples().

Here is the caller graph for this function:

◆ GetTrimLeft()

double WaveClip::GetTrimLeft ( ) const
noexcept

Returns the play start offset in seconds from the beginning of the underlying sequence.

Definition at line 1388 of file WaveClip.cpp.

1389{
1390 return mTrimLeft;
1391}

References mTrimLeft.

Referenced by ApplyStretchRatio(), Clear(), WaveTrack::ClearAndPasteOne(), WaveChannelInterval::GetTrimLeft(), and Paste().

Here is the caller graph for this function:

◆ GetTrimRight()

double WaveClip::GetTrimRight ( ) const
noexcept

Returns the play end offset in seconds from the ending of the underlying sequence.

Definition at line 1398 of file WaveClip.cpp.

1399{
1400 return mTrimRight;
1401}

References mTrimRight.

Referenced by ApplyStretchRatio(), WaveTrack::ClearAndPasteOne(), WaveChannelInterval::GetTrimRight(), and Paste().

Here is the caller graph for this function:

◆ GetVisibleSampleCount()

sampleCount WaveClip::GetVisibleSampleCount ( ) const
overridevirtual

Returns a number of raw samples, not accounting for stretching.

Implements ClipTimes.

Definition at line 1377 of file WaveClip.cpp.

1378{
1379 return GetNumSamples()
1381}

References GetNumSamples(), mTrimLeft, mTrimRight, and TimeToSamples().

Referenced by ApplyStretchRatio(), anonymous_namespace{WaveTrack.cpp}::GetSampleAccessArgs(), WaveChannelInterval::GetVisibleSampleCount(), SetFloatsFromTime(), and SharesBoundaryWithNextClip().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetWidth()

size_t WaveClip::GetWidth ( ) const
overridevirtual

How many Sequences the clip contains. Set at construction time; changes only if increased by deserialization

Implements ClipInterface.

Definition at line 167 of file WaveClip.cpp.

168{
169 return mSequences.size();
170}

References mSequences.

Referenced by AppendNewBlock(), AppendSharedBlock(), ApplyStretchRatio(), CheckInvariants(), WaveTrack::ClearAndPasteOne(), ConvertToSampleFormat(), GetAppendBuffer(), GetMinMax(), GetRMS(), GetSamples(), GetSampleView(), GetSequenceBlockArray(), GetSequenceSamplesCount(), Paste(), SetSamples(), and WaveClip().

Here is the caller graph for this function:

◆ HandleXMLChild()

XMLTagHandler * WaveClip::HandleXMLChild ( const std::string_view &  tag)
overridevirtual

Implements XMLTagHandler.

Definition at line 611 of file WaveClip.cpp.

612{
613 auto &pFirst = mSequences[0];
614 if (tag == "sequence") {
615 mSequences.push_back(std::make_unique<Sequence>(
616 pFirst->GetFactory(), pFirst->GetSampleFormats()));
617 return mSequences.back().get();
618 }
619 else if (tag == "envelope")
620 return mEnvelope.get();
621 else if (tag == "waveclip")
622 {
623 // Nested wave clips are cut lines
624 auto format = pFirst->GetSampleFormats().Stored();
625 // The format is not stored in WaveClip itself but passed to
626 // Sequence::Sequence; but then the Sequence will deserialize format
627 // again
628 mCutLines.push_back(
629 std::make_shared<WaveClip>(
630 // Make only one channel now, but recursive deserialization
631 // increases the width later
632 1, pFirst->GetFactory(),
633 format, mRate, 0 /*colourindex*/));
634 return mCutLines.back().get();
635 }
636 else
637 return NULL;
638}

References anonymous_namespace{ExportPCM.cpp}::format, mCutLines, mEnvelope, mRate, and mSequences.

Referenced by AUPImportFileHandle::HandleSequence(), and AUPImportFileHandle::HandleWaveClip().

Here is the caller graph for this function:

◆ HandleXMLEndTag()

void WaveClip::HandleXMLEndTag ( const std::string_view &  tag)
override

Definition at line 597 of file WaveClip.cpp.

598{
599 // All blocks were deserialized into new sequences; remove the one made
600 // by the constructor which remains empty.
601 mSequences.erase(mSequences.begin());
602 mSequences.shrink_to_fit();
603 if (tag == "waveclip")
605 // A proof of this assertion assumes that nothing has happened since
606 // construction of this, besides calls to the other deserialization
607 // functions
608 assert(CheckInvariants());
609}

References CheckInvariants(), mSequences, and UpdateEnvelopeTrackLen().

Referenced by WaveTrack::HandleXMLEndTag().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ HandleXMLTag()

bool WaveClip::HandleXMLTag ( const std::string_view &  tag,
const AttributesList attrs 
)
overridevirtual

Implements XMLTagHandler.

Definition at line 535 of file WaveClip.cpp.

536{
537 if (tag == "waveclip")
538 {
539 double dblValue;
540 long longValue;
541 for (auto pair : attrs)
542 {
543 auto attr = pair.first;
544 auto value = pair.second;
545
546 if (attr == "offset")
547 {
548 if (!value.TryGet(dblValue))
549 return false;
550 SetSequenceStartTime(dblValue);
551 }
552 else if (attr == "trimLeft")
553 {
554 if (!value.TryGet(dblValue))
555 return false;
556 SetTrimLeft(dblValue);
557 }
558 else if (attr == "trimRight")
559 {
560 if (!value.TryGet(dblValue))
561 return false;
562 SetTrimRight(dblValue);
563 }
564 else if (attr == "rawAudioTempo")
565 {
566 if (!value.TryGet(dblValue))
567 return false;
568 if (dblValue == 0)
569 mRawAudioTempo.reset();
570 else
571 mRawAudioTempo = dblValue;
572 }
573 else if (attr == "clipStretchRatio")
574 {
575 if (!value.TryGet(dblValue))
576 return false;
577 mClipStretchRatio = dblValue;
578 }
579 else if (attr == "name")
580 {
581 if(value.IsStringView())
582 SetName(value.ToWString());
583 }
584 else if (attr == "colorindex")
585 {
586 if (!value.TryGet(longValue))
587 return false;
588 SetColourIndex(longValue);
589 }
590 }
591 return true;
592 }
593
594 return false;
595}
void SetName(const wxString &name)
Definition: WaveClip.cpp:1300
void SetColourIndex(int index)
Definition: WaveClip.h:188

References mClipStretchRatio, mRawAudioTempo, SetColourIndex(), SetName(), SetSequenceStartTime(), SetTrimLeft(), and SetTrimRight().

Here is the call graph for this function:

◆ HasEqualStretchRatio()

bool WaveClip::HasEqualStretchRatio ( const WaveClip other) const

Checks for stretch-ratio equality, accounting for rounding errors.

Definition at line 348 of file WaveClip.cpp.

349{
350 return StretchRatioEquals(other.GetStretchRatio());
351}
bool StretchRatioEquals(double value) const
Definition: WaveClip.cpp:353

References GetStretchRatio(), and StretchRatioEquals().

Referenced by WaveTrack::ClearAndPasteOne(), and WaveTrack::MergeOneClipPair().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ InsertSilence()

void WaveClip::InsertSilence ( double  t,
double  len,
double *  pEnvelopeValue = nullptr 
)

Insert silence - note that this is an efficient operation for large amounts of silence

Exception safety guarantee:
Strong

Definition at line 757 of file WaveClip.cpp.

758{
759 Transaction transaction{ *this };
760
761 if (t == GetPlayStartTime() && t > GetSequenceStartTime())
763 else if (t == GetPlayEndTime() && t < GetSequenceEndTime()) {
765 SetTrimRight(.0);
766 }
767
768 auto s0 = TimeToSequenceSamples(t);
769 auto slen = (sampleCount)floor(len * mRate + 0.5);
770
771 // use Strong-guarantee
772 for (auto &pSequence : mSequences)
773 pSequence->InsertSilence(s0, slen);
774
775 transaction.Commit();
776
777 // use No-fail-guarantee
778 OffsetCutLines(t, len);
779
780 const auto sampleTime = 1.0 / GetRate();
781 auto pEnvelope = GetEnvelope();
782 if ( pEnvelopeValue ) {
783
784 // Preserve limit value at the end
785 auto oldLen = pEnvelope->GetTrackLen();
786 auto newLen = oldLen + len;
787 pEnvelope->Cap( sampleTime );
788
789 // Ramp across the silence to the given value
790 pEnvelope->SetTrackLen( newLen, sampleTime );
791 pEnvelope->InsertOrReplace
792 ( pEnvelope->GetOffset() + newLen, *pEnvelopeValue );
793 }
794 else
795 pEnvelope->InsertSpace( t, len );
796
797 MarkChanged();
798}
void OffsetCutLines(double t0, double len)
Offset cutlines right to time 't0' by time amount 'len'.
Definition: WaveClip.cpp:1052

References ClearSequence(), GetEnvelope(), GetPlayEndTime(), GetPlayStartTime(), GetRate(), GetSequenceEndTime(), GetSequenceStartTime(), MarkChanged(), mRate, mSequences, OffsetCutLines(), SetTrimRight(), and TimeToSequenceSamples().

Referenced by AUPImportFileHandle::AddSilence(), and AppendSilence().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ IntersectsPlayRegion()

bool WaveClip::IntersectsPlayRegion ( double  t0,
double  t1 
) const

[t0, t1) ∩ [...) != ∅

Precondition
t0 <= t1

Definition at line 1478 of file WaveClip.cpp.

1479{
1480 assert(t0 <= t1);
1481 // t1 is the open end of the interval, so it must be excluded from the closed
1482 // begin of the play region.
1483 return t0 < GetPlayEndTime() && GetPlayStartTime() < t1;
1484}

References GetPlayEndTime(), and GetPlayStartTime().

Referenced by WaveChannelInterval::Intersects().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ MarkChanged()

void WaveClip::MarkChanged ( )

WaveTrack calls this whenever data in the wave clip changes. It is called automatically when WaveClip has a chance to know that something has changed, like when member functions SetSamples() etc. are called.

Exception safety guarantee:
No-fail

Definition at line 393 of file WaveClip.cpp.

394{
395 Caches::ForEach( std::mem_fn( &WaveClipListener::MarkChanged ) );
396}
virtual void MarkChanged()=0

References WaveClipListener::MarkChanged().

Referenced by Append(), ClearAndAddCutLine(), ClearSequence(), ConvertToSampleFormat(), Flush(), InsertSilence(), Paste(), SetRate(), SetSamples(), and SetSilence().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ NumCutLines()

size_t WaveClip::NumCutLines ( ) const
inline

Definition at line 515 of file WaveClip.h.

515{ return mCutLines.size(); }

◆ OffsetCutLines()

void WaveClip::OffsetCutLines ( double  t0,
double  len 
)

Offset cutlines right to time 't0' by time amount 'len'.

Exception safety guarantee:
No-fail

Definition at line 1052 of file WaveClip.cpp.

1053{
1054 for (const auto &cutLine : mCutLines)
1055 {
1056 if (GetSequenceStartTime() + cutLine->GetSequenceStartTime() >= t0)
1057 cutLine->ShiftBy(len);
1058 }
1059}

References GetSequenceStartTime(), and mCutLines.

Referenced by InsertSilence(), and Paste().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ OnProjectTempoChange()

void WaveClip::OnProjectTempoChange ( const std::optional< double > &  oldTempo,
double  newTempo 
)

Definition at line 271 of file WaveClip.cpp.

273{
274 if (!mRawAudioTempo.has_value())
275 // When we have tempo detection ready (either by header-file
276 // read-up or signal analysis) we can use something smarter than that. In
277 // the meantime, use the tempo of the project when the clip is created as
278 // source tempo.
279 mRawAudioTempo = oldTempo;
280
281 if (oldTempo.has_value())
282 {
283 const auto ratioChange = *mProjectTempo / newTempo;
284 mSequenceOffset *= ratioChange;
285 mTrimLeft *= ratioChange;
286 mTrimRight *= ratioChange;
287 StretchCutLines(ratioChange);
288 mEnvelope->RescaleTimesBy(ratioChange);
289 }
290 mProjectTempo = newTempo;
291}
void StretchCutLines(double ratioChange)
Definition: WaveClip.cpp:327

References mEnvelope, mProjectTempo, mRawAudioTempo, mSequenceOffset, mTrimLeft, mTrimRight, and StretchCutLines().

Here is the call graph for this function:

◆ operator=()

WaveClip & WaveClip::operator= ( const WaveClip )
privatedelete

◆ PartlyWithinPlayRegion()

bool WaveClip::PartlyWithinPlayRegion ( double  t0,
double  t1 
) const

t0 xor t1 ∈ [...)

Precondition
t0 <= t1

Definition at line 1472 of file WaveClip.cpp.

1473{
1474 assert(t0 <= t1);
1475 return WithinPlayRegion(t0) != WithinPlayRegion(t1);
1476}

References WithinPlayRegion().

Here is the call graph for this function:

◆ Paste()

bool WaveClip::Paste ( double  t0,
const WaveClip other 
)

Paste data from other clip, resampling it if not equal rate.

Returns
true and succeed if and only if this->GetWidth() == other.GetWidth()
Exception safety guarantee:
Strong

Definition at line 663 of file WaveClip.cpp.

664{
665 if (GetWidth() != other.GetWidth())
666 return false;
667
668 Finally Do{ [this]{ assert(CheckInvariants()); } };
669
670 Transaction transaction{ *this };
671
672 const bool clipNeedsResampling = other.mRate != mRate;
673 const bool clipNeedsNewFormat =
675 std::shared_ptr<WaveClip> newClip;
676
677 t0 = std::clamp(t0, GetPlayStartTime(), GetPlayEndTime());
678
679 //seems like edge cases cannot happen, see WaveTrack::PasteWaveTrack
680 auto &factory = GetFactory();
681 if (t0 == GetPlayStartTime())
682 {
684 SetTrimLeft(other.GetTrimLeft());
685
686 auto copy = std::make_shared<WaveClip>(other, factory, true);
687 copy->ClearSequence(copy->GetPlayEndTime(), copy->GetSequenceEndTime());
688 newClip = std::move(copy);
689 }
690 else if (t0 == GetPlayEndTime())
691 {
693 SetTrimRight(other.GetTrimRight());
694
695 auto copy = std::make_shared<WaveClip>(other, factory, true);
696 copy->ClearSequence(copy->GetSequenceStartTime(), copy->GetPlayStartTime());
697 newClip = std::move(copy);
698 }
699 else
700 {
701 newClip = std::make_shared<WaveClip>(other, factory, true);
702 newClip->ClearSequence(newClip->GetPlayEndTime(), newClip->GetSequenceEndTime());
703 newClip->ClearSequence(newClip->GetSequenceStartTime(), newClip->GetPlayStartTime());
704 newClip->SetTrimLeft(0);
705 newClip->SetTrimRight(0);
706 }
707
708 if (clipNeedsResampling || clipNeedsNewFormat)
709 {
710 auto copy = std::make_shared<WaveClip>(*newClip.get(), factory, true);
711 if (clipNeedsResampling)
712 // The other clip's rate is different from ours, so resample
713 copy->Resample(mRate);
714 if (clipNeedsNewFormat)
715 // Force sample formats to match.
716 copy->ConvertToSampleFormat(GetSampleFormats().Stored());
717 newClip = std::move(copy);
718 }
719
720 // Paste cut lines contained in pasted clip
721 WaveClipHolders newCutlines;
722 for (const auto &cutline: newClip->mCutLines)
723 {
724 auto cutlineCopy = std::make_shared<WaveClip>(*cutline, factory,
725 // Recursively copy cutlines of cutlines. They don't need
726 // their offsets adjusted.
727 true);
728 cutlineCopy->ShiftBy(t0 - GetSequenceStartTime());
729 newCutlines.push_back(std::move(cutlineCopy));
730 }
731
733
734 // Because newClip was made above as a copy of (a copy of) other
735 assert(other.GetWidth() == newClip->GetWidth());
736 // And other has the same width as this, so this loop is safe
737 // Assume Strong-guarantee from Sequence::Paste
738 for (size_t ii = 0, width = GetWidth(); ii < width; ++ii)
739 mSequences[ii]->Paste(s0, newClip->mSequences[ii].get());
740
741 transaction.Commit();
742
743 // Assume No-fail-guarantee in the remaining
744 MarkChanged();
745 auto sampleTime = 1.0 / GetRate();
746 mEnvelope->PasteEnvelope
747 (s0.as_double()/mRate + GetSequenceStartTime(), newClip->mEnvelope.get(), sampleTime);
748 OffsetCutLines(t0, newClip->GetPlayEndTime() - newClip->GetPlayStartTime());
749
750 for (auto &holder : newCutlines)
751 mCutLines.push_back(std::move(holder));
752
753 return true;
754}
std::vector< WaveClipHolder > WaveClipHolders
Definition: WaveClip.h:46
sampleFormat Stored() const
Definition: SampleFormat.h:89
SampleFormats GetSampleFormats() const
Definition: WaveClip.cpp:365
void copy(const T *src, T *dst, int32_t n)
Definition: VectorOps.h:31

References sampleCount::as_double(), CheckInvariants(), ClearSequence(), staffpad::vo::copy(), cloud::factory, GetFactory(), GetPlayEndTime(), GetPlayStartTime(), GetRate(), GetSampleFormats(), GetSequenceEndTime(), GetSequenceStartTime(), GetTrimLeft(), GetTrimRight(), GetWidth(), MarkChanged(), mCutLines, mEnvelope, mRate, mSequences, OffsetCutLines(), Paste(), SetTrimLeft(), SetTrimRight(), SampleFormats::Stored(), and TimeToSequenceSamples().

Referenced by WaveTrack::ClearAndPasteOne(), ExpandCutLine(), WaveTrack::MergeOneClipPair(), Paste(), and WaveTrack::PasteOne().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ RemoveCutLine()

bool WaveClip::RemoveCutLine ( double  cutLinePosition)

Remove cut line, without expanding the audio in it.

Definition at line 1035 of file WaveClip.cpp.

1036{
1037 for (auto it = mCutLines.begin(); it != mCutLines.end(); ++it)
1038 {
1039 const auto &cutline = *it;
1040 //std::numeric_limits<double>::epsilon() or (1.0 / static_cast<double>(mRate))?
1041 if (fabs(GetSequenceStartTime() + cutline->GetSequenceStartTime() - cutLinePosition) < 0.0001)
1042 {
1043 mCutLines.erase(it); // deletes cutline!
1044 return true;
1045 }
1046 }
1047
1048 return false;
1049}

References GetSequenceStartTime(), and mCutLines.

Here is the call graph for this function:

◆ Resample()

void WaveClip::Resample ( int  rate,
BasicUI::ProgressDialog progress = nullptr 
)
Exception safety guarantee:
Strong

We want to keep going as long as we have something to feed the resampler with OR as long as the resampler spews out samples (which could continue for a few iterations after we stop feeding it)

Definition at line 1085 of file WaveClip.cpp.

1086{
1087 // Note: it is not necessary to do this recursively to cutlines.
1088 // They get resampled as needed when they are expanded.
1089
1090 if (rate == mRate)
1091 return; // Nothing to do
1092
1093 // This function does its own RAII without a Transaction
1094
1095 double factor = (double)rate / (double)mRate;
1096 ::Resample resample(true, factor, factor); // constant rate resampling
1097
1098 const size_t bufsize = 65536;
1099 Floats inBuffer{ bufsize };
1100 Floats outBuffer{ bufsize };
1101 sampleCount pos = 0;
1102 bool error = false;
1103 int outGenerated = 0;
1104 const auto numSamples = GetNumSamples();
1105
1106 // These sequences are appended to below
1107 auto newSequences = GetEmptySequenceCopies();
1108
1114 while (pos < numSamples || outGenerated > 0) {
1115 const auto inLen = limitSampleBufferSize( bufsize, numSamples - pos );
1116
1117 bool isLast = ((pos + inLen) == numSamples);
1118
1119 auto ppNewSequence = newSequences.begin();
1120 std::optional<std::pair<size_t, size_t>> results{};
1121 for (auto &pSequence : mSequences) {
1122 auto &pNewSequence = *ppNewSequence++;
1123 if (!pSequence->Get((samplePtr)inBuffer.get(), floatSample, pos, inLen, true))
1124 {
1125 error = true;
1126 break;
1127 }
1128
1129 // Expect the same results for all channels, or else fail
1130 auto newResults = resample.Process(factor, inBuffer.get(), inLen,
1131 isLast, outBuffer.get(), bufsize);
1132 if (!results)
1133 results.emplace(newResults);
1134 else if (*results != newResults) {
1135 error = true;
1136 break;
1137 }
1138
1139 outGenerated = results->second;
1140 if (outGenerated < 0) {
1141 error = true;
1142 break;
1143 }
1144
1145 pNewSequence->Append((samplePtr)outBuffer.get(), floatSample,
1146 outGenerated, 1,
1147 widestSampleFormat /* computed samples need dither */
1148 );
1149 }
1150 if (results)
1151 pos += results->first;
1152
1153 if (progress)
1154 {
1155 auto updateResult = progress->Poll(
1156 pos.as_long_long(),
1157 numSamples.as_long_long()
1158 );
1159 error = (updateResult != BasicUI::ProgressResult::Success);
1160 if (error)
1161 throw UserException{};
1162 }
1163 }
1164
1165 if (error)
1168 XO("Resampling failed."),
1169 XO("Warning"),
1170 "Error:_Resampling"
1171 };
1172 else
1173 {
1174 // Use No-fail-guarantee in these steps
1175 mSequences = move(newSequences);
1176 mRate = rate;
1177 Flush();
1178 Caches::ForEach( std::mem_fn( &WaveClipListener::Invalidate ) );
1179 }
1180}
@ Internal
Indicates internal failure from Audacity.
XO("Cut/Copy/Paste")
virtual ProgressResult Poll(unsigned long long numerator, unsigned long long denominator, const TranslatableString &message={})=0
Update the bar and poll for clicks. Call only on the main thread.
Interface to libsoxr.
Definition: Resample.h:27
A MessageBoxException that shows a given, unvarying string.
Can be thrown when user cancels operations, as with a progress dialog. Delayed handler does nothing.
Definition: UserException.h:17

References sampleCount::as_long_long(), floatSample, Flush(), GetEmptySequenceCopies(), GetNumSamples(), Internal, WaveClipListener::Invalidate(), limitSampleBufferSize(), mRate, mSequences, BasicUI::ProgressDialog::Poll(), Resample::Process(), BasicUI::Success, widestSampleFormat, and XO().

Here is the call graph for this function:

◆ SamplesToTime()

double WaveClip::SamplesToTime ( sampleCount  s) const
noexcept

Definition at line 1315 of file WaveClip.cpp.

1316{
1317 return s.as_double() * GetStretchRatio() / mRate;
1318}

Referenced by anonymous_namespace{WaveTrack.cpp}::RoundToNearestClipSample(), SetFloatsCenteredAroundTime(), SetRate(), and WaveClip().

Here is the caller graph for this function:

◆ SetColourIndex()

void WaveClip::SetColourIndex ( int  index)
inline

Definition at line 188 of file WaveClip.h.

188{ mColourIndex = index; }

Referenced by HandleXMLTag().

Here is the caller graph for this function:

◆ SetFloatAtTime()

void WaveClip::SetFloatAtTime ( double  t,
size_t  iChannel,
float  value,
sampleFormat  effectiveFormat 
)

Definition at line 247 of file WaveClip.cpp.

249{
250 SetFloatsCenteredAroundTime(t, iChannel, &value, 0u, effectiveFormat);
251}
void SetFloatsCenteredAroundTime(double t, size_t iChannel, const float *buffer, size_t numSideSamples, sampleFormat effectiveFormat)
Same as SetFloatsFromTime, but with buffer starting at TimeToSamples(t0 - SamplesToTime(numSideSample...
Definition: WaveClip.cpp:238

References anonymous_namespace{StretchingSequenceIntegrationTest.cpp}::iChannel, and SetFloatsCenteredAroundTime().

Here is the call graph for this function:

◆ SetFloatsCenteredAroundTime()

void WaveClip::SetFloatsCenteredAroundTime ( double  t,
size_t  iChannel,
const float *  buffer,
size_t  numSideSamples,
sampleFormat  effectiveFormat 
)

Same as SetFloatsFromTime, but with buffer starting at TimeToSamples(t0 - SamplesToTime(numSideSamples)). [buffer, buffer + 2 * numSizeSamples + 1) is assumed to be a valid span of addresses.

Definition at line 238 of file WaveClip.cpp.

241{
243 t - SamplesToTime(numSideSamples), iChannel, buffer,
244 2 * numSideSamples + 1, effectiveFormat);
245}
void SetFloatsFromTime(double t, size_t iChannel, const float *buffer, size_t numSamples, sampleFormat effectiveFormat)
Considers buffer as audio starting at TimeToSamples(t) (relative to clip play start time) and with eq...
Definition: WaveClip.cpp:215

References anonymous_namespace{StretchingSequenceIntegrationTest.cpp}::iChannel, SamplesToTime(), and SetFloatsFromTime().

Referenced by SetFloatAtTime().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ SetFloatsFromTime()

void WaveClip::SetFloatsFromTime ( double  t,
size_t  iChannel,
const float *  buffer,
size_t  numSamples,
sampleFormat  effectiveFormat 
)

Considers buffer as audio starting at TimeToSamples(t) (relative to clip play start time) and with equal stretch ratio. Samples at intersecting indices are then copied, leaving non-intersecting clip samples untouched. E.g., buffer: [a b c d e] clip : [x y z] result: [d e z].

Succeed with out-of-bounds requests, only changing what is in bounds.

Definition at line 215 of file WaveClip.cpp.

218{
219 const auto maybeNegativeStart = TimeToSamples(t);
220 const auto maybeOutOfBoundEnd = maybeNegativeStart + numFloats;
221 const auto effectiveStart = std::max(sampleCount { 0 }, maybeNegativeStart);
222 const auto effectiveEnd =
223 std::min(GetVisibleSampleCount(), maybeOutOfBoundEnd);
224 if (effectiveStart >= effectiveEnd)
225 return;
226 // Cannot be greater than `numFloats` -> safe cast
227 const auto effectiveLen = (effectiveEnd - effectiveStart).as_size_t();
228 // Cannot be greater than `numFloats` -> safe cast
229 const auto numLeadingZeros =
230 (effectiveStart - maybeNegativeStart).as_size_t();
231 const auto offsetBuffer =
232 reinterpret_cast<const char*>(buffer + numLeadingZeros);
234 iChannel, offsetBuffer, floatSample, effectiveStart, effectiveLen,
235 effectiveFormat);
236}
void SetSamples(size_t ii, constSamplePtr buffer, sampleFormat format, sampleCount start, size_t len, sampleFormat effectiveFormat)
Definition: WaveClip.cpp:191

References floatSample, GetVisibleSampleCount(), anonymous_namespace{StretchingSequenceIntegrationTest.cpp}::iChannel, min(), SetSamples(), and TimeToSamples().

Referenced by SetFloatsCenteredAroundTime().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ SetIsPlaceholder()

void WaveClip::SetIsPlaceholder ( bool  val)
inline

Definition at line 550 of file WaveClip.h.

550{ mIsPlaceholder = val; }

◆ SetName()

void WaveClip::SetName ( const wxString &  name)

Definition at line 1300 of file WaveClip.cpp.

1301{
1302 mName = name;
1303}
const TranslatableString name
Definition: Distortion.cpp:76

References mName, and name.

Referenced by HandleXMLTag(), and PasteOverPreservingClips().

Here is the caller graph for this function:

◆ SetPlayStartTime()

void WaveClip::SetPlayStartTime ( double  time)

Definition at line 1345 of file WaveClip.cpp.

1346{
1348}

References mTrimLeft, and SetSequenceStartTime().

Here is the call graph for this function:

◆ SetRate()

void WaveClip::SetRate ( int  rate)

Definition at line 1070 of file WaveClip.cpp.

1071{
1072 const auto trimLeftSampleNum = TimeToSamples(mTrimLeft);
1073 const auto trimRightSampleNum = TimeToSamples(mTrimRight);
1074 auto ratio = static_cast<double>(mRate) / rate;
1075 mRate = rate;
1076 mTrimLeft = SamplesToTime(trimLeftSampleNum);
1077 mTrimRight = SamplesToTime(trimRightSampleNum);
1078 auto newLength = GetNumSamples().as_double() / mRate;
1079 mEnvelope->RescaleTimes( newLength );
1080 MarkChanged();
1082}

References sampleCount::as_double(), GetNumSamples(), GetSequenceStartTime(), MarkChanged(), mEnvelope, mRate, mTrimLeft, mTrimRight, SamplesToTime(), SetSequenceStartTime(), and TimeToSamples().

Here is the call graph for this function:

◆ SetSamples()

void WaveClip::SetSamples ( size_t  ii,
constSamplePtr  buffer,
sampleFormat  format,
sampleCount  start,
size_t  len,
sampleFormat  effectiveFormat 
)
Parameters
iiidentifies the channel
Precondition
ii < GetWidth()
Parameters
startrelative to clip play start sample
Exception safety guarantee:
Strong
Parameters
effectiveFormatMake the effective format of the data at least the minumum of this value and `format`. (Maybe wider, if merging with preexistent data.) If the data are later narrowed from stored format, but not narrower than the effective, then no dithering will occur.

Definition at line 191 of file WaveClip.cpp.

194{
195 assert(ii < GetWidth());
196 // use Strong-guarantee
197 mSequences[ii]->SetSamples(buffer, format,
198 start + TimeToSamples(mTrimLeft), len, effectiveFormat);
199
200 // use No-fail-guarantee
201 MarkChanged();
202}

References anonymous_namespace{ExportPCM.cpp}::format, GetWidth(), MarkChanged(), mSequences, mTrimLeft, and TimeToSamples().

Referenced by SetFloatsFromTime().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ SetSequenceStartTime()

void WaveClip::SetSequenceStartTime ( double  startTime)

Definition at line 1430 of file WaveClip.cpp.

1431{
1432 mSequenceOffset = startTime;
1433 mEnvelope->SetOffset(startTime);
1434}

References mEnvelope, and mSequenceOffset.

Referenced by ApplyStretchRatio(), WaveTrack::ClearAndPasteOne(), ClearLeft(), WaveTrack::HandleXMLChild(), HandleXMLTag(), SetPlayStartTime(), and SetRate().

Here is the caller graph for this function:

◆ SetSilence()

void WaveClip::SetSilence ( sampleCount  offset,
sampleCount  length 
)

Silences the 'length' amount of samples starting from 'offset'(relative to the play start)

Definition at line 1325 of file WaveClip.cpp.

1326{
1327 const auto start = TimeToSamples(mTrimLeft) + offset;
1328 Transaction transaction{ *this };
1329 for (auto &pSequence : mSequences)
1330 pSequence->SetSilence(start, length);
1331 transaction.Commit();
1332 MarkChanged();
1333}

References WaveClip::Transaction::Commit(), MarkChanged(), mSequences, mTrimLeft, and TimeToSamples().

Here is the call graph for this function:

◆ SetTrimLeft()

void WaveClip::SetTrimLeft ( double  trim)

Sets the play start offset in seconds from the beginning of the underlying sequence.

Definition at line 1383 of file WaveClip.cpp.

1384{
1385 mTrimLeft = std::max(.0, trim);
1386}

References mTrimLeft.

Referenced by ApplyStretchRatio(), Clear(), WaveTrack::ClearAndPasteOne(), ClearLeft(), HandleXMLTag(), Paste(), and TrimLeft().

Here is the caller graph for this function:

◆ SetTrimRight()

void WaveClip::SetTrimRight ( double  trim)

Sets the play end offset in seconds from the ending of the underlying sequence.

Definition at line 1393 of file WaveClip.cpp.

1394{
1395 mTrimRight = std::max(.0, trim);
1396}

References mTrimRight.

Referenced by ApplyStretchRatio(), Clear(), WaveTrack::ClearAndPasteOne(), ClearRight(), HandleXMLTag(), InsertSilence(), Paste(), and TrimRight().

Here is the caller graph for this function:

◆ SharesBoundaryWithNextClip()

bool WaveClip::SharesBoundaryWithNextClip ( const WaveClip next) const

Definition at line 1289 of file WaveClip.cpp.

1290{
1291 double endThis = GetRate() * GetPlayStartTime() +
1293 double startNext = next->GetRate() * next->GetPlayStartTime();
1294
1295 // given that a double has about 15 significant digits, using a criterion
1296 // of half a sample should be safe in all normal usage.
1297 return fabs(startNext - endThis) < 0.5;
1298}

References sampleCount::as_double(), GetPlayStartTime(), GetRate(), GetStretchRatio(), and GetVisibleSampleCount().

Here is the call graph for this function:

◆ ShiftBy()

void WaveClip::ShiftBy ( double  delta)
noexcept
Exception safety guarantee:
No-fail

Definition at line 1449 of file WaveClip.cpp.

1450{
1452}

Referenced by Clear(), ClearAndAddCutLine(), WaveTrack::ClearAndPasteOne(), ClearSequence(), and WaveTrack::CopyOne().

Here is the caller graph for this function:

◆ SnapToTrackSample()

double WaveClip::SnapToTrackSample ( double  time) const
privatenoexcept

Definition at line 1320 of file WaveClip.cpp.

1321{
1322 return std::round(t * mRate) / mRate;
1323}
fastfloat_really_inline void round(adjusted_mantissa &am, callback cb) noexcept
Definition: fast_float.h:2512

References fast_float::round().

Referenced by GetPlayEndTime(), and GetPlayStartTime().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ SplitsPlayRegion()

bool WaveClip::SplitsPlayRegion ( double  t) const

[ < t and t < ), such that if the track were split at t, it would split this clip in two of lengths > 0.

The play region is an open-closed interval, [...), where "[ = GetPlayStartTime()", and ") = GetPlayEndTime()."

Definition at line 1454 of file WaveClip.cpp.

1455{
1456 return GetPlayStartTime() < t && t < GetPlayEndTime();
1457}

References GetPlayEndTime(), and GetPlayStartTime().

Referenced by WaveTrack::ApplyStretchRatioOne().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ StretchCutLines()

void WaveClip::StretchCutLines ( double  ratioChange)
private

Definition at line 327 of file WaveClip.cpp.

328{
329 for (const auto& cutline : mCutLines)
330 {
331 cutline->mSequenceOffset *= ratioChange;
332 cutline->mTrimLeft *= ratioChange;
333 cutline->mTrimRight *= ratioChange;
334 cutline->mClipStretchRatio *= ratioChange;
335 cutline->mEnvelope->RescaleTimesBy(ratioChange);
336 }
337}

References mCutLines.

Referenced by OnProjectTempoChange(), StretchLeftTo(), and StretchRightTo().

Here is the caller graph for this function:

◆ StretchLeftTo()

void WaveClip::StretchLeftTo ( double  to)

Stretches from left to the absolute time (if in expected range)

Definition at line 293 of file WaveClip.cpp.

294{
295 const auto pet = GetPlayEndTime();
296 if (to >= pet)
297 return;
298 const auto oldPlayDuration = pet - GetPlayStartTime();
299 const auto newPlayDuration = pet - to;
300 const auto ratioChange = newPlayDuration / oldPlayDuration;
301 mSequenceOffset = pet - (pet - mSequenceOffset) * ratioChange;
302 mTrimLeft *= ratioChange;
303 mTrimRight *= ratioChange;
304 mClipStretchRatio *= ratioChange;
305 mEnvelope->SetOffset(mSequenceOffset);
306 mEnvelope->RescaleTimesBy(ratioChange);
307 StretchCutLines(ratioChange);
308}

References GetPlayEndTime(), GetPlayStartTime(), mClipStretchRatio, mEnvelope, mSequenceOffset, mTrimLeft, mTrimRight, and StretchCutLines().

Here is the call graph for this function:

◆ StretchRatioEquals()

bool WaveClip::StretchRatioEquals ( double  value) const

Definition at line 353 of file WaveClip.cpp.

354{
356 1 + GetStretchRatio() - value);
357}
static bool IsPassThroughMode(double stretchRatio)

References GetStretchRatio(), and TimeAndPitchInterface::IsPassThroughMode().

Referenced by HasEqualStretchRatio().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ StretchRightTo()

void WaveClip::StretchRightTo ( double  to)

Sets from the right to the absolute time (if in expected range)

Definition at line 310 of file WaveClip.cpp.

311{
312 const auto pst = GetPlayStartTime();
313 if (to <= pst)
314 return;
315 const auto oldPlayDuration = GetPlayEndTime() - pst;
316 const auto newPlayDuration = to - pst;
317 const auto ratioChange = newPlayDuration / oldPlayDuration;
318 mSequenceOffset = pst - mTrimLeft * ratioChange;
319 mTrimLeft *= ratioChange;
320 mTrimRight *= ratioChange;
321 mClipStretchRatio *= ratioChange;
322 mEnvelope->SetOffset(mSequenceOffset);
323 mEnvelope->RescaleTimesBy(ratioChange);
324 StretchCutLines(ratioChange);
325}

References GetPlayEndTime(), GetPlayStartTime(), mClipStretchRatio, mEnvelope, mSequenceOffset, mTrimLeft, mTrimRight, and StretchCutLines().

Here is the call graph for this function:

◆ TimeToSamples()

sampleCount WaveClip::TimeToSamples ( double  time) const
overridevirtual

Implements ClipTimes.

Definition at line 1310 of file WaveClip.cpp.

1311{
1312 return sampleCount(floor(time * mRate / GetStretchRatio() + 0.5));
1313}

References GetStretchRatio(), and mRate.

Referenced by CountSamples(), GetFloatAtTime(), GetSamples(), GetSampleView(), GetSequenceStartSample(), GetVisibleSampleCount(), SetFloatsFromTime(), SetRate(), SetSamples(), SetSilence(), WaveChannelInterval::TimeToSamples(), TimeToSequenceSamples(), and WaveClip().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ TimeToSequenceSamples()

sampleCount WaveClip::TimeToSequenceSamples ( double  t) const
private

Definition at line 1520 of file WaveClip.cpp.

1521{
1522 if (t < GetSequenceStartTime())
1523 return 0;
1524 else if (t > GetSequenceEndTime())
1525 return GetNumSamples();
1526 return TimeToSamples(t - GetSequenceStartTime());
1527}

References GetNumSamples(), GetSequenceEndTime(), GetSequenceStartTime(), and TimeToSamples().

Referenced by ClearAndAddCutLine(), ClearSequence(), GetMinMax(), GetRMS(), InsertSilence(), and Paste().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ TrimLeft()

void WaveClip::TrimLeft ( double  deltaTime)

Moves play start position by deltaTime.

Definition at line 1403 of file WaveClip.cpp.

1404{
1405 SetTrimLeft(mTrimLeft + deltaTime);
1406}

References mTrimLeft, and SetTrimLeft().

Here is the call graph for this function:

◆ TrimLeftTo()

void WaveClip::TrimLeftTo ( double  to)

Sets the the left trimming to the absolute time (if that is in bounds)

Definition at line 1413 of file WaveClip.cpp.

1414{
1415 mTrimLeft =
1416 std::clamp(to, mSequenceOffset, GetPlayEndTime()) - mSequenceOffset;
1417}

References GetPlayEndTime(), mSequenceOffset, and mTrimLeft.

Referenced by ApplyStretchRatio().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ TrimRight()

void WaveClip::TrimRight ( double  deltaTime)

Moves play end position by deltaTime.

Definition at line 1408 of file WaveClip.cpp.

1409{
1410 SetTrimRight(mTrimRight + deltaTime);
1411}

References mTrimRight, and SetTrimRight().

Here is the call graph for this function:

◆ TrimRightTo()

void WaveClip::TrimRightTo ( double  to)

Sets the the right trimming to the absolute time (if that is in bounds)

Definition at line 1419 of file WaveClip.cpp.

1420{
1422}

References GetPlayStartTime(), GetSequenceEndTime(), and mTrimRight.

Referenced by ApplyStretchRatio().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ UpdateEnvelopeTrackLen()

void WaveClip::UpdateEnvelopeTrackLen ( )

Whenever you do an operation to the sequence that will change the number of samples (that is, the length of the clip), you will want to call this function to tell the envelope about it.

Exception safety guarantee:
No-fail

Definition at line 462 of file WaveClip.cpp.

463{
464 auto len = (GetNumSamples().as_double()) / mRate;
465 if (len != mEnvelope->GetTrackLen())
466 mEnvelope->SetTrackLen(len, 1.0 / GetRate());
467}

References sampleCount::as_double(), GetNumSamples(), GetRate(), mEnvelope, and mRate.

Referenced by Append(), Flush(), and HandleXMLEndTag().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ WithinPlayRegion()

bool WaveClip::WithinPlayRegion ( double  t) const

t ∈ [...)

Definition at line 1459 of file WaveClip.cpp.

1460{
1461 return GetPlayStartTime() <= t && t < GetPlayEndTime();
1462}

References GetPlayEndTime(), and GetPlayStartTime().

Referenced by GetFloatAtTime(), and PartlyWithinPlayRegion().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ WriteXML()

void WaveClip::WriteXML ( XMLWriter xmlFile) const

Definition at line 640 of file WaveClip.cpp.

642{
643 xmlFile.StartTag(wxT("waveclip"));
644 xmlFile.WriteAttr(wxT("offset"), mSequenceOffset, 8);
645 xmlFile.WriteAttr(wxT("trimLeft"), mTrimLeft, 8);
646 xmlFile.WriteAttr(wxT("trimRight"), mTrimRight, 8);
647 xmlFile.WriteAttr(wxT("rawAudioTempo"), mRawAudioTempo.value_or(0.), 8);
648 xmlFile.WriteAttr(wxT("clipStretchRatio"), mClipStretchRatio, 8);
649 xmlFile.WriteAttr(wxT("name"), mName);
650 xmlFile.WriteAttr(wxT("colorindex"), mColourIndex );
651
652 for (auto &pSequence : mSequences)
653 pSequence->WriteXML(xmlFile);
654 mEnvelope->WriteXML(xmlFile);
655
656 for (const auto &clip: mCutLines)
657 clip->WriteXML(xmlFile);
658
659 xmlFile.EndTag(wxT("waveclip"));
660}
wxT("CloseDown"))
virtual void StartTag(const wxString &name)
Definition: XMLWriter.cpp:79
void WriteAttr(const wxString &name, const Identifier &value)
Definition: XMLWriter.h:36
virtual void EndTag(const wxString &name)
Definition: XMLWriter.cpp:102

References wxT().

Here is the call graph for this function:

Member Data Documentation

◆ mClipStretchRatio

double WaveClip::mClipStretchRatio = 1.
private

◆ mColourIndex

int WaveClip::mColourIndex
private

Definition at line 621 of file WaveClip.h.

Referenced by WaveClip().

◆ mCutLines

WaveClipHolders WaveClip::mCutLines {}
private

Cut Lines are nothing more than ordinary wave clips, with the offset relative to the start of the clip.

Invariant
all are non-null

Definition at line 639 of file WaveClip.h.

Referenced by CheckInvariants(), ClearAndAddCutLine(), ClearSequence(), CloseLock(), ExpandCutLine(), FindCutLine(), HandleXMLChild(), OffsetCutLines(), Paste(), RemoveCutLine(), StretchCutLines(), and WaveClip().

◆ mEnvelope

std::unique_ptr<Envelope> WaveClip::mEnvelope
private

◆ mIsPlaceholder

bool WaveClip::mIsPlaceholder { false }
private

Definition at line 642 of file WaveClip.h.

Referenced by WaveClip().

◆ mName

wxString WaveClip::mName
private

Definition at line 645 of file WaveClip.h.

Referenced by GetName(), SetName(), and WaveClip().

◆ mProjectTempo

std::optional<double> WaveClip::mProjectTempo
private

Definition at line 617 of file WaveClip.h.

Referenced by ApplyStretchRatio(), GetStretchRatio(), and OnProjectTempoChange().

◆ mRate

int WaveClip::mRate
private

◆ mRawAudioTempo

std::optional<double> WaveClip::mRawAudioTempo
private

Definition at line 616 of file WaveClip.h.

Referenced by ApplyStretchRatio(), GetStretchRatio(), HandleXMLTag(), and OnProjectTempoChange().

◆ mSequenceOffset

double WaveClip::mSequenceOffset { 0 }
private

Real-time durations, i.e., stretching the clip modifies these.

Definition at line 608 of file WaveClip.h.

Referenced by GetPlayEndTime(), GetPlayStartTime(), GetSequenceStartSample(), GetSequenceStartTime(), OnProjectTempoChange(), SetSequenceStartTime(), StretchLeftTo(), StretchRightTo(), TrimLeftTo(), and WaveClip().

◆ mSequences

std::vector<std::unique_ptr<Sequence> > WaveClip::mSequences
private

◆ mTrimLeft

double WaveClip::mTrimLeft { 0 }
private

◆ mTrimRight

double WaveClip::mTrimRight { 0 }
private

The documentation for this class was generated from the following files: