Audacity 3.2.0
Classes | Public Types | Public Member Functions | Static Public Attributes | Private Member Functions | Static 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

class  ClearSequenceFinisher
 Fix consistency of cutlines and envelope after deleting from Sequences. More...
 
struct  CreateToken
 
struct  StrongInvariantScope
 
struct  Transaction
 Restores state when an update loop over mSequences fails midway. More...
 

Public Types

using Attachments = Site< WaveClip, WaveClipListener, ClientData::DeepCopying >
 
using Channel = WaveClipChannel
 
- Public Types inherited from ClientData::Site< WaveClip, WaveClipListener, ClientData::DeepCopying >
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 Types inherited from Observer::Publisher< CentShiftChange >
using message_type = CentShiftChange
 
using CallbackReturn = std::conditional_t< true, void, bool >
 
using Callback = std::function< CallbackReturn(const CentShiftChange &) >
 Type of functions that can be connected to the Publisher. More...
 
- Public Types inherited from Observer::Publisher< PitchAndSpeedPresetChange >
using message_type = PitchAndSpeedPresetChange
 
using CallbackReturn = std::conditional_t< true, void, bool >
 
using Callback = std::function< CallbackReturn(const PitchAndSpeedPresetChange &) >
 Type of functions that can be connected to the Publisher. More...
 
- Public Types inherited from Observer::Publisher< StretchRatioChange >
using message_type = StretchRatioChange
 
using CallbackReturn = std::conditional_t< true, void, bool >
 
using Callback = std::function< CallbackReturn(const StretchRatioChange &) >
 Type of functions that can be connected to the Publisher. More...
 
- Public Types inherited from Observer::Publisher< WaveClipDtorCalled >
using message_type = WaveClipDtorCalled
 
using CallbackReturn = std::conditional_t< true, void, bool >
 
using Callback = std::function< CallbackReturn(const WaveClipDtorCalled &) >
 Type of functions that can be connected to the Publisher. More...
 

Public Member Functions

 WaveClip (size_t width, const SampleBlockFactoryPtr &factory, sampleFormat format, int rate)
 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 ()
 
double Start () const override
 
double End () const override
 
std::shared_ptr< ChannelIntervalDoGetChannel (size_t iChannel) override
 Retrieve a channel. More...
 
auto Channels ()
 
auto Channels () const
 
bool CheckInvariants () const
 Check weak invariant conditions on mSequences and mCutlines. More...
 
bool StrongInvariant () const
 
void AssertOrRepairStrongInvariant ()
 
size_t NChannels () const override
 How many Sequences the clip contains. More...
 
void ConvertToSampleFormat (sampleFormat format, const std::function< void(size_t)> &progressReport={})
 
int GetRate () const override
 
void SetRate (int rate)
 
void SetRawAudioTempo (double tempo)
 
PitchAndSpeedPreset GetPitchAndSpeedPreset () const
 
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...
 
void StretchBy (double ratio)
 
double GetStretchRatio () const override
 
bool SetCentShift (int cents)
 
int GetCentShift () const override
 
Observer::Subscription SubscribeToCentShiftChange (std::function< void(int)> cb) const override
 
void SetPitchAndSpeedPreset (PitchAndSpeedPreset preset)
 
virtual Observer::Subscription SubscribeToPitchAndSpeedPresetChange (std::function< void(PitchAndSpeedPreset)> cb) const override
 
void Resample (int rate, BasicUI::ProgressDialog *progress=nullptr)
 
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
 
bool IsEmpty () 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 TrimQuarternotesFromRight (double quarters)
 Same as TrimRight, but expressed as quarter notes. 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)
 
EnvelopeGetEnvelope () noexcept
 
const EnvelopeGetEnvelope () const noexcept
 
void SetEnvelope (std::unique_ptr< Envelope > p)
 
const BlockArrayGetSequenceBlockArray (size_t ii) const
 
SequenceGetSequence (size_t ii)
 
const SequenceGetSequence (size_t ii) const
 
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< SampleBlockAppendToChannel (size_t iChannel, constSamplePtr buffer, sampleFormat format, size_t len)
 
std::shared_ptr< SampleBlockAppendLegacyNewBlock (constSamplePtr buffer, sampleFormat format, size_t len)
 
void AppendLegacySharedBlock (const std::shared_ptr< SampleBlock > &pBlock)
 
bool Append (size_t iChannel, size_t nChannels, constSamplePtr buffers[], sampleFormat format, size_t len, unsigned int stride, sampleFormat effectiveFormat)
 
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 RepairChannels ()
 Ensure that all sequences have the same sample count. More...
 
void Clear (double t0, double t1)
 
void ClearLeft (double t)
 
void ClearRight (double t)
 
void ClearAndAddCutLine (double t0, double t1)
 
void AddCutLine (WaveClipHolder pClip)
 
bool Paste (double t0, const WaveClip &other)
 
void InsertSilence (double t, double len, double *pEnvelopeValue=nullptr)
 
void AppendSilence (double len, double envelopeValue)
 
const WaveClipHoldersGetCutLines ()
 Get access to cut lines list. More...
 
const WaveClipConstHoldersGetCutLines () const
 
size_t NumCutLines () const
 
bool FindCutLine (double cutLinePosition, double *cutLineStart=nullptr, double *cutLineEnd=nullptr) 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 (size_t ii, XMLWriter &xmlFile) const
 
bool GetIsPlaceholder () const
 
void SetIsPlaceholder (bool val)
 
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 (size_t ii) const
 
void OnProjectTempoChange (const std::optional< double > &oldTempo, double newTempo)
 
SampleFormats GetSampleFormats () const
 
size_t CountBlocks () const
 
void DiscardRightChannel ()
 Reduce width. More...
 
void SwapChannels ()
 
std::shared_ptr< WaveClipSplitChannels ()
 
void MakeStereo (WaveClip &&other, bool mustAlign)
 
size_t GetBestBlockSize (sampleCount t) const
 A hint for sizing of well aligned fetches. More...
 
size_t GetMaxBlockSize () const
 
 WaveClip (const WaveClip &orig, const SampleBlockFactoryPtr &factory, bool copyCutlines, CreateToken token)
 
bool HasEqualPitchAndSpeed (const WaveClip &other) const
 
bool HasPitchOrSpeed () const
 
- 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 NChannels () const =0
 
virtual int GetCentShift () const =0
 
virtual Observer::Subscription SubscribeToCentShiftChange (std::function< void(int)> cb) const =0
 
virtual PitchAndSpeedPreset GetPitchAndSpeedPreset () const =0
 
virtual Observer::Subscription SubscribeToPitchAndSpeedPresetChange (std::function< void(PitchAndSpeedPreset)> cb) 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 WideChannelGroupInterval
 ~WideChannelGroupInterval () override
 
virtual size_t NChannels () const =0
 Report the number of channels. More...
 
template<typename IntervalType = ChannelInterval>
std::shared_ptr< IntervalType > GetChannel (size_t iChannel)
 Retrieve a channel, cast to the given type. More...
 
template<typename IntervalType = const ChannelInterval>
auto GetChannel (size_t iChannel) const -> std::enable_if_t< std::is_const_v< IntervalType >, std::shared_ptr< IntervalType > >
 
template<typename IntervalType = ChannelInterval>
IteratorRange< ChannelIterator< IntervalType > > Channels ()
 Get range of ChannelInterval objects with mutative access. More...
 
template<typename IntervalType = const ChannelInterval>
auto Channels () const -> std::enable_if_t< std::is_const_v< IntervalType >, IteratorRange< ChannelIterator< IntervalType > > >
 Get range of channels with read-only access. More...
 
- Public Member Functions inherited from ChannelGroupInterval
 ChannelGroupInterval ()=default
 
virtual ~ChannelGroupInterval ()
 
virtual double Start () const =0
 
virtual double End () 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, ClientData::DeepCopying >
 ~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...
 
- Public Member Functions inherited from Observer::Publisher< CentShiftChange >
 Publisher (ExceptionPolicy *pPolicy=nullptr, Alloc a={})
 Constructor supporting type-erased custom allocation/deletion. More...
 
 Publisher (Publisher &&)=default
 
Publisheroperator= (Publisher &&)=default
 
Subscription Subscribe (Callback callback)
 Connect a callback to the Publisher; later-connected are called earlier. More...
 
Subscription Subscribe (Object &obj, Return(Object::*callback)(Args...))
 Overload of Subscribe takes an object and pointer-to-member-function. More...
 
- Public Member Functions inherited from Observer::Publisher< PitchAndSpeedPresetChange >
 Publisher (ExceptionPolicy *pPolicy=nullptr, Alloc a={})
 Constructor supporting type-erased custom allocation/deletion. More...
 
 Publisher (Publisher &&)=default
 
Publisheroperator= (Publisher &&)=default
 
Subscription Subscribe (Callback callback)
 Connect a callback to the Publisher; later-connected are called earlier. More...
 
Subscription Subscribe (Object &obj, Return(Object::*callback)(Args...))
 Overload of Subscribe takes an object and pointer-to-member-function. More...
 
- Public Member Functions inherited from Observer::Publisher< StretchRatioChange >
 Publisher (ExceptionPolicy *pPolicy=nullptr, Alloc a={})
 Constructor supporting type-erased custom allocation/deletion. More...
 
 Publisher (Publisher &&)=default
 
Publisheroperator= (Publisher &&)=default
 
Subscription Subscribe (Callback callback)
 Connect a callback to the Publisher; later-connected are called earlier. More...
 
Subscription Subscribe (Object &obj, Return(Object::*callback)(Args...))
 Overload of Subscribe takes an object and pointer-to-member-function. More...
 
- Public Member Functions inherited from Observer::Publisher< WaveClipDtorCalled >
 Publisher (ExceptionPolicy *pPolicy=nullptr, Alloc a={})
 Constructor supporting type-erased custom allocation/deletion. More...
 
 Publisher (Publisher &&)=default
 
Publisheroperator= (Publisher &&)=default
 
Subscription Subscribe (Callback callback)
 Connect a callback to the Publisher; later-connected are called earlier. More...
 
Subscription Subscribe (Object &obj, Return(Object::*callback)(Args...))
 Overload of Subscribe takes an object and pointer-to-member-function. More...
 

Static Public Attributes

static const char * WaveClip_tag = "waveclip"
 
- Static Public Attributes inherited from Observer::Publisher< CentShiftChange >
static constexpr bool notifies_all
 
- Static Public Attributes inherited from Observer::Publisher< PitchAndSpeedPresetChange >
static constexpr bool notifies_all
 
- Static Public Attributes inherited from Observer::Publisher< StretchRatioChange >
static constexpr bool notifies_all
 
- Static Public Attributes inherited from Observer::Publisher< WaveClipDtorCalled >
static constexpr bool notifies_all
 

Private Member Functions

 WaveClip (const WaveClip &)=delete
 
WaveClipoperator= (const WaveClip &)=delete
 
size_t GreatestAppendBufferLen () const
 
void MarkChanged () noexcept
 Called by mutating operations; notifies listeners. More...
 
sampleCount TimeToSequenceSamples (double t) const
 
bool StretchRatioEquals (double value) const
 
sampleCount GetNumSamples () const
 
const SampleBlockFactoryPtrGetFactory () const
 
std::vector< std::unique_ptr< Sequence > > GetEmptySequenceCopies () const
 
void StretchCutLines (double ratioChange)
 
double SnapToTrackSample (double time) const noexcept
 
ClearSequenceFinisher ClearSequence (double t0, double t1)
 

Static Private Member Functions

static void TransferSequence (WaveClip &origClip, WaveClip &newClip)
 
static void FixSplitCutlines (WaveClipHolders &myCutlines, WaveClipHolders &newCutlines)
 

Private Attributes

PitchAndSpeedPreset mPitchAndSpeedPreset { PitchAndSpeedPreset::Default }
 
int mCentShift { 0 }
 
double mClipStretchRatio = 1.
 
std::optional< double > mRawAudioTempo
 
std::optional< double > mProjectTempo
 
int mRate
 Sample rate of the raw audio, i.e., before stretching. More...
 
std::vector< std::unique_ptr< Sequence > > mSequences
 
std::unique_ptr< EnvelopemEnvelope
 Envelope is unique, not per-sequence, and always non-null. 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, ClientData::DeepCopying >
static size_t numFactories ()
 How many static factories have been registered with this specialization of Site. More...
 
virtual std::shared_ptr< ChannelIntervalDoGetChannel (size_t iChannel)=0
 Retrieve a channel. More...
 
- Protected Member Functions inherited from ClientData::Site< WaveClip, WaveClipListener, ClientData::DeepCopying >
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...
 
void ForCorresponding (Site &other, const Function &function, bool create=true)
 
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 EraseIf (const Function &function)
 Erase attached objects satisfying a predicate. More...
 
void BuildAll ()
 For each RegisteredFactory, if the corresponding attachment is absent in this, build and store it. More...
 
- Protected Member Functions inherited from Observer::Publisher< CentShiftChange >
CallbackReturn Publish (const CentShiftChange &message)
 Send a message to connected callbacks. More...
 
- Protected Member Functions inherited from Observer::Publisher< PitchAndSpeedPresetChange >
CallbackReturn Publish (const PitchAndSpeedPresetChange &message)
 Send a message to connected callbacks. More...
 
- Protected Member Functions inherited from Observer::Publisher< StretchRatioChange >
CallbackReturn Publish (const StretchRatioChange &message)
 Send a message to connected callbacks. More...
 
- Protected Member Functions inherited from Observer::Publisher< WaveClipDtorCalled >
CallbackReturn Publish (const WaveClipDtorCalled &message)
 Send a message to connected callbacks. More...
 

Detailed Description

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

Definition at line 228 of file WaveClip.h.

Member Typedef Documentation

◆ Attachments

Definition at line 251 of file WaveClip.h.

◆ Channel

Definition at line 293 of file WaveClip.h.

Constructor & Destructor Documentation

◆ WaveClip() [1/5]

WaveClip::WaveClip ( const WaveClip )
privatedelete

◆ WaveClip() [2/5]

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

typical constructor

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

Definition at line 223 of file WaveClip.cpp.

226{
227 assert(width > 0);
228 mRate = rate;
229 mSequences.resize(width);
230 for (auto &pSequence : mSequences)
231 pSequence = std::make_unique<Sequence>(factory,
233
234 mEnvelope = std::make_unique<Envelope>(true, 1e-7, 2.0, 1.0);
235 assert(CheckInvariants());
236}
static RegisteredToolbarFactory factory
@ 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:79
bool CheckInvariants() const
Check weak invariant conditions on mSequences and mCutlines.
Definition: WaveClip.cpp:1970
std::unique_ptr< Envelope > mEnvelope
Envelope is unique, not per-sequence, and always non-null.
Definition: WaveClip.h:966
int mRate
Sample rate of the raw audio, i.e., before stretching.
Definition: WaveClip.h:959
std::vector< std::unique_ptr< Sequence > > mSequences
Definition: WaveClip.h:964

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

Here is the call graph for this function:

◆ WaveClip() [3/5]

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

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
NChannels() == orig.NChannels()
!copyCutlines || NumCutLines() == orig.NumCutLines()

Definition at line 270 of file WaveClip.h.

273 : WaveClip{ orig, factory, copyCutlines, {} }
274 {}
This allows multiple clips to be a part of one WaveTrack.
Definition: WaveClip.h:238

◆ WaveClip() [4/5]

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
NChannels() == orig.NChannels()

Definition at line 281 of file WaveClip.cpp.

284 : mCentShift { orig.mCentShift }
288{
289 assert(orig.CountSamples(t0, t1) > 0);
290
292
293 //Adjust trim values to sample-boundary
294 if(t0 > orig.GetPlayStartTime()) {
295 const auto s0 = orig.TimeToSamples(t0 - orig.GetSequenceStartTime());
296 mTrimLeft = orig.SamplesToTime(s0);
297
298 }
299 else
300 mTrimLeft = orig.mTrimLeft;
301
302 if(t1 < orig.GetPlayEndTime())
303 {
304 const auto s1 = orig.TimeToSamples(orig.GetSequenceEndTime() - t1);
305 mTrimRight = orig.SamplesToTime(s1);
306 }
307 else
308 mTrimRight = orig.mTrimRight;
309
310 mRate = orig.mRate;
311
312 // Deep copy of attachments
313 Attachments &attachments = *this;
314 attachments = orig;
315
317
318 mSequences.reserve(orig.NChannels());
319 for (auto &pSequence : orig.mSequences)
320 mSequences.push_back(
321 std::make_unique<Sequence>(*pSequence, factory));
322
323 mEnvelope = std::make_unique<Envelope>(*orig.mEnvelope);
324
325 if (copyCutlines)
326 for (const auto &cutline : orig.mCutLines)
327 mCutLines.push_back(
328 std::make_shared<WaveClip>(*cutline, factory, true));
329
330 assert(NChannels() == orig.NChannels());
331 assert(CheckInvariants());
332}
std::optional< double > mRawAudioTempo
Definition: WaveClip.h:955
double GetSequenceStartTime() const noexcept
Definition: WaveClip.cpp:1863
Site< WaveClip, WaveClipListener, ClientData::DeepCopying > Attachments
Definition: WaveClip.h:251
bool mIsPlaceholder
Definition: WaveClip.h:976
sampleCount TimeToSamples(double time) const override
Definition: WaveClip.cpp:1722
int mCentShift
Definition: WaveClip.h:950
double GetPlayStartTime() const noexcept override
Definition: WaveClip.cpp:1753
double mTrimRight
Definition: WaveClip.h:946
std::optional< double > mProjectTempo
Definition: WaveClip.h:956
sampleCount CountSamples(double t0, double t1) const
Definition: WaveClip.cpp:1948
double GetPlayEndTime() const override
Definition: WaveClip.cpp:1763
bool GetIsPlaceholder() const
Definition: WaveClip.h:772
double mSequenceOffset
Definition: WaveClip.h:944
double SamplesToTime(sampleCount s) const noexcept
Definition: WaveClip.cpp:1727
size_t NChannels() const override
How many Sequences the clip contains.
Definition: WaveClip.cpp:373
double mTrimLeft
Definition: WaveClip.h:945
WaveClipHolders mCutLines
Definition: WaveClip.h:973
double GetSequenceEndTime() const
Definition: WaveClip.cpp:1876
double mClipStretchRatio
Definition: WaveClip.h:954

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

Here is the call graph for this function:

◆ ~WaveClip()

WaveClip::~WaveClip ( )
virtual

Definition at line 335 of file WaveClip.cpp.

336{
338}
CallbackReturn Publish(const Message &message)
Send a message to connected callbacks.
Definition: Observer.h:207

References Observer::Publisher< Message, NotifyAll >::Publish().

Here is the call graph for this function:

◆ WaveClip() [5/5]

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

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

This is effectively private because CreateToken is private, but must be public to cooperate with make_shared.

The clip so constructed does NOT (yet) satisfy the class invariants!

Parameters
emptyCopyif true, don't make sequences
Postcondition
NChannels() == (token.emptyCopy ? 0 : orig.NChannels())
!copyCutlines || NumCutLines() == orig.NumCutLines()

Definition at line 238 of file WaveClip.cpp.

241 : mCentShift { orig.mCentShift }
246{
247 // essentially a copy constructor - but you must pass in the
248 // current sample block factory, because we might be copying
249 // from one project to another
250
252 mTrimLeft = orig.mTrimLeft;
253 mTrimRight = orig.mTrimRight;
254 mRate = orig.mRate;
255
256 // Deep copy of attachments
257 Attachments &attachments = *this;
258 attachments = orig;
259
260 mSequences.reserve(orig.NChannels());
261 if (!token.emptyCopy)
262 for (auto &pSequence : orig.mSequences)
263 mSequences.push_back(std::make_unique<Sequence>(*pSequence, factory));
264
265 mEnvelope = std::make_unique<Envelope>(*orig.mEnvelope);
266
267 mName = orig.mName;
268
269 if (copyCutlines)
270 for (const auto &clip: orig.mCutLines)
271 mCutLines.push_back(
272 std::make_shared<WaveClip>(*clip, factory, true, token));
273
275
276 assert(NChannels() == (token.emptyCopy ? 0 : orig.NChannels()));
277 assert(token.emptyCopy || CheckInvariants());
278 assert(!copyCutlines || NumCutLines() == orig.NumCutLines());
279}
PitchAndSpeedPreset mPitchAndSpeedPreset
Definition: WaveClip.h:949
wxString mName
Definition: WaveClip.h:978
size_t NumCutLines() const
Definition: WaveClip.h:731

References CheckInvariants(), WaveClip::CreateToken::emptyCopy, factory, GetIsPlaceholder(), mCutLines, mEnvelope, mIsPlaceholder, mName, mRate, mSequenceOffset, mSequences, mTrimLeft, mTrimRight, NChannels(), and NumCutLines().

Here is the call graph for this function:

Member Function Documentation

◆ AddCutLine()

void WaveClip::AddCutLine ( WaveClipHolder  pClip)
Precondition
NChannels() == pClip->NChannels()

Definition at line 1470 of file WaveClip.cpp.

1471{
1472 assert(NChannels() == pClip->NChannels());
1473 mCutLines.push_back(move(pClip));
1474 // New clip is assumed to have correct width
1475 assert(CheckInvariants());
1476}

References CheckInvariants(), mCutLines, and NChannels().

Referenced by ClearAndAddCutLine().

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

◆ AfterPlayRegion()

bool WaveClip::AfterPlayRegion ( double  t) const

) <= t

Definition at line 1943 of file WaveClip.cpp.

1944{
1945 return GetPlayEndTime() <= t;
1946}

References GetPlayEndTime().

Here is the call graph for this function:

◆ Append() [1/2]

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 NChannels() In case of failure or exceptions, the clip contents are unchanged but un-flushed data are lost
Precondition
StrongInvariant()
Postcondition
StrongInvariant()
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 869 of file WaveClip.cpp.

871{
872 StrongInvariantScope scope{ *this };
873
874 Transaction transaction{ *this };
875
876 //wxLogDebug(wxT("Append: len=%lli"), (long long) len);
877
878 size_t ii = 0;
879 bool appended = false;
880 for (auto &pSequence : mSequences)
881 appended =
882 pSequence->Append(buffers[ii++], format, len, stride, effectiveFormat)
883 || appended;
884
885 transaction.Commit();
886 // use No-fail-guarantee
888 MarkChanged();
889
890 return appended;
891}
void MarkChanged() noexcept
Called by mutating operations; notifies listeners.
Definition: WaveClip.cpp:735
void UpdateEnvelopeTrackLen()
Definition: WaveClip.cpp:807
static CommandContext::TargetFactory::SubstituteInUnique< InteractiveOutputTargets > scope

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

Here is the call graph for this function:

◆ Append() [2/2]

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

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

For stereo clips, typically this is invoked on left, then right channels, either alternating (as when recording) or in two batches (channel-major pattern of effect processing), which violates the strong invariant condition, then restores it (either repeatedly, or once).

Returns
true if at least one complete block was created In case of failure or exceptions, the clip contents are unchanged but un-flushed data are lost
Precondition
iChannel < NChannels()
iChannel + nChannels <= NChannels()
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 844 of file WaveClip.cpp.

847{
848 assert(iChannel < NChannels());
849 assert(iChannel + nChannels <= NChannels());
850
851 // No requirement or promise of the strong invariant, and therefore no
852 // need for Transaction
853
854 //wxLogDebug(wxT("Append: len=%lli"), (long long) len);
855
856 bool appended = false;
857 for (size_t ii = 0; ii < nChannels; ++ii)
858 appended = mSequences[iChannel + ii]->Append(
859 buffers[ii], format, len, stride, effectiveFormat)
860 || appended;
861
862 // use No-fail-guarantee
864 MarkChanged();
865
866 return appended;
867}
bool Append(size_t iChannel, size_t nChannels, constSamplePtr buffers[], sampleFormat format, size_t len, unsigned int stride, sampleFormat effectiveFormat)
Definition: WaveClip.cpp:844

References Append(), anonymous_namespace{ExportPCM.cpp}::format, anonymous_namespace{StretchingSequenceIntegrationTest.cpp}::iChannel, MarkChanged(), mSequences, NChannels(), and UpdateEnvelopeTrackLen().

Referenced by Append().

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

◆ AppendLegacyNewBlock()

std::shared_ptr< SampleBlock > WaveClip::AppendLegacyNewBlock ( constSamplePtr  buffer,
sampleFormat  format,
size_t  len 
)

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

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

Definition at line 826 of file WaveClip.cpp.

827{
828 // This is a special use function for legacy files only and this assertion
829 // does not need to be relaxed. The clip is in a still unzipped track.
830 assert(NChannels() == 1);
831 return AppendToChannel(0, buffer, format, len);
832}
std::shared_ptr< SampleBlock > AppendToChannel(size_t iChannel, constSamplePtr buffer, sampleFormat format, size_t len)
Definition: WaveClip.cpp:817

References AppendToChannel(), anonymous_namespace{ExportPCM.cpp}::format, and NChannels().

Here is the call graph for this function:

◆ AppendLegacySharedBlock()

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

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

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

Definition at line 835 of file WaveClip.cpp.

837{
838 // This is a special use function for legacy files only and this assertion
839 // does not need to be relaxed. The clip is in a still unzipped track.
840 assert(NChannels() == 1);
841 mSequences[0]->AppendSharedBlock( pBlock );
842}

References mSequences, and NChannels().

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 1276 of file WaveClip.cpp.

1277{
1278 auto t = GetPlayEndTime();
1279 InsertSilence( t, len, &envelopeValue );
1280}
void InsertSilence(double t, double len, double *pEnvelopeValue=nullptr)
Definition: WaveClip.cpp:1229

References GetPlayEndTime(), and InsertSilence().

Here is the call graph for this function:

◆ AppendToChannel()

std::shared_ptr< SampleBlock > WaveClip::AppendToChannel ( size_t  iChannel,
constSamplePtr  buffer,
sampleFormat  format,
size_t  len 
)
Precondition
iChannel < NChannels()
Exception safety guarantee:
Strong

Definition at line 817 of file WaveClip.cpp.

819{
820 assert(iChannel < NChannels());
821 return mSequences[iChannel]->AppendNewBlock(buffer, format, len);
822}

References anonymous_namespace{ExportPCM.cpp}::format, anonymous_namespace{StretchingSequenceIntegrationTest.cpp}::iChannel, mSequences, and NChannels().

Referenced by AppendLegacyNewBlock().

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

◆ AssertOrRepairStrongInvariant()

void WaveClip::AssertOrRepairStrongInvariant ( )

When StrongInvariant() is false, violate an assertion in debug, but in release, establish it (or fail, propagating an exception)

Exception safety guarantee:
Strong

Definition at line 2022 of file WaveClip.cpp.

2023{
2024 if (!StrongInvariant()) {
2025 assert(false);
2027 assert(StrongInvariant());
2028 }
2029}
void RepairChannels()
Ensure that all sequences have the same sample count.
Definition: WaveClip.cpp:918
bool StrongInvariant() const
Definition: WaveClip.cpp:2004

References RepairChannels(), and StrongInvariant().

Referenced by WaveClip::StrongInvariantScope::StrongInvariantScope().

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

◆ AtOrBeforePlayRegion()

bool WaveClip::AtOrBeforePlayRegion ( double  t) const

t <= [

Definition at line 1938 of file WaveClip.cpp.

1939{
1940 return t <= GetPlayStartTime();
1941}

References GetPlayStartTime().

Here is the call graph for this function:

◆ BeforePlayRegion()

bool WaveClip::BeforePlayRegion ( double  t) const

t < [

Definition at line 1933 of file WaveClip.cpp.

1934{
1935 return t < GetPlayStartTime();
1936}

References GetPlayStartTime().

Referenced by EntirelyWithinPlayRegion().

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

◆ Channels() [1/2]

auto WaveClip::Channels ( )
inline

Definition at line 295 of file WaveClip.h.

295 { return
296 WideChannelGroupInterval::Channels<Channel>(); }

◆ Channels() [2/2]

auto WaveClip::Channels ( ) const
inline

Definition at line 298 of file WaveClip.h.

298 { return
299 WideChannelGroupInterval::Channels<const Channel>(); }

◆ CheckInvariants()

bool WaveClip::CheckInvariants ( ) const

Check weak invariant conditions on mSequences and mCutlines.

Conditions are mSequences.size() > 0 all sequences are non-null all sequences have the same sample formats and sample block factory all cutlines satisfy the strong invariant

Definition at line 1970 of file WaveClip.cpp.

1971{
1972 const auto width = NChannels();
1973 auto iter = mSequences.begin(),
1974 end = mSequences.end();
1975 // There must be at least one pointer
1976 if (iter != end) {
1977 // All pointers mut be non-null
1978 auto &pFirst = *iter++;
1979 if (pFirst) {
1980 // All sequences must have the same sample formats, and sample block
1981 // factory
1982 return
1983 std::all_of(iter, end, [&](decltype(pFirst) pSequence) {
1984 return pSequence &&
1985 pSequence->GetSampleFormats() == pFirst->GetSampleFormats() &&
1986 pSequence->GetFactory() == pFirst->GetFactory();
1987 }) &&
1988 // All cut lines are non-null, satisfy the invariants, and match width
1989 std::all_of(mCutLines.begin(), mCutLines.end(),
1990 [width](const WaveClipHolder &pCutLine) {
1991 if (!(pCutLine && pCutLine->NChannels() == width))
1992 return false;
1993 if (!pCutLine->StrongInvariant()) {
1994 pCutLine->AssertOrRepairStrongInvariant();
1995 return false;
1996 }
1997 return true;
1998 });
1999 }
2000 }
2001 return false;
2002}
std::shared_ptr< WaveClip > WaveClipHolder
Definition: WaveClip.h:43
const char * end(const char *str) noexcept
Definition: StringUtils.h:106

References details::end(), mCutLines, mSequences, and NChannels().

Referenced by AddCutLine(), DiscardRightChannel(), HandleXMLEndTag(), MakeStereo(), StrongInvariant(), SwapChannels(), TransferSequence(), 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 1283 of file WaveClip.cpp.

1284{
1285 auto st0 = t0;
1286 auto st1 = t1;
1287 auto offset = .0;
1288 if (st0 <= GetPlayStartTime())
1289 {
1290 offset = (t0 - GetPlayStartTime()) + GetTrimLeft();
1291 st0 = GetSequenceStartTime();
1292
1293 SetTrimLeft(.0);
1294 }
1295 if (st1 >= GetPlayEndTime())
1296 {
1297 st1 = GetSequenceEndTime();
1298 SetTrimRight(.0);
1299 }
1300 Transaction transaction{ *this };
1301 ClearSequence(st0, st1)
1302 .Commit();
1303 transaction.Commit();
1304 MarkChanged();
1305
1306 if (offset != .0)
1307 ShiftBy(offset);
1308}
void ShiftBy(double delta) noexcept
Definition: WaveClip.cpp:1889
double GetTrimLeft() const noexcept
Returns the play start offset in seconds from the beginning of the underlying sequence.
Definition: WaveClip.cpp:1806
ClearSequenceFinisher ClearSequence(double t0, double t1)
Definition: WaveClip.cpp:1337
void SetTrimRight(double trim)
Sets the play end offset in seconds from the ending of the underlying sequence.
Definition: WaveClip.cpp:1811
void SetTrimLeft(double trim)
Sets the play start offset in seconds from the beginning of the underlying sequence.
Definition: WaveClip.cpp:1801

References ClearSequence(), WaveClip::ClearSequenceFinisher::Commit(), GetPlayEndTime(), GetPlayStartTime(), GetSequenceEndTime(), GetSequenceStartTime(), GetTrimLeft(), MarkChanged(), 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.

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

Definition at line 1406 of file WaveClip.cpp.

1407{
1408 StrongInvariantScope scope{ *this };
1409 if (t0 > GetPlayEndTime() || t1 < GetPlayStartTime() || CountSamples(t0, t1) == 0)
1410 return; // no samples to remove
1411
1412 Transaction transaction{ *this };
1413
1414 const double clip_t0 = std::max( t0, GetPlayStartTime() );
1415 const double clip_t1 = std::min( t1, GetPlayEndTime() );
1416
1417 auto newClip = std::make_shared<WaveClip>(
1418 *this, GetFactory(), true, clip_t0, clip_t1);
1419 if(t1 < GetPlayEndTime())
1420 {
1421 newClip->ClearSequence(t1, newClip->GetSequenceEndTime())
1422 .Commit();
1423 newClip->SetTrimRight(.0);
1424 }
1425 if(t0 > GetPlayStartTime())
1426 {
1427 newClip->ClearSequence(newClip->GetSequenceStartTime(), t0)
1428 .Commit();
1429 newClip->SetTrimLeft(.0);
1430 }
1431
1432 newClip->SetSequenceStartTime( clip_t0 - GetSequenceStartTime() );
1433
1434 // Remove cutlines from this clip that were in the selection, shift
1435 // left those that were after the selection
1436 // May DELETE as we iterate, so don't use range-for
1437 for (auto it = mCutLines.begin(); it != mCutLines.end();)
1438 {
1439 WaveClip* clip = it->get();
1440 double cutlinePosition = GetSequenceStartTime() + clip->GetSequenceStartTime();
1441 if (cutlinePosition >= t0 && cutlinePosition <= t1)
1442 it = mCutLines.erase(it);
1443 else
1444 {
1445 if (cutlinePosition >= t1)
1446 {
1447 clip->ShiftBy(clip_t0 - clip_t1);
1448 }
1449 ++it;
1450 }
1451 }
1452
1453 // Clear actual audio data
1454 auto s0 = TimeToSequenceSamples(t0);
1455 auto s1 = TimeToSequenceSamples(t1);
1456
1457 // use Weak-guarantee
1458 for (auto &pSequence : mSequences)
1459 pSequence->Delete(s0, s1-s0);
1460
1461 // Collapse envelope
1462 auto sampleTime = 1.0 / GetRate();
1463 GetEnvelope().CollapseRegion( t0, t1, sampleTime );
1464
1465 transaction.Commit();
1466 MarkChanged();
1467 AddCutLine(move(newClip));
1468}
int min(int a, int b)
void CollapseRegion(double t0, double t1, double sampleDur) noexcept
Definition: Envelope.cpp:378
sampleCount TimeToSequenceSamples(double t) const
Definition: WaveClip.cpp:1961
int GetRate() const override
Definition: WaveClip.h:337
Envelope & GetEnvelope() noexcept
Definition: WaveClip.h:553
const SampleBlockFactoryPtr & GetFactory() const
Definition: WaveClip.cpp:713
void AddCutLine(WaveClipHolder pClip)
Definition: WaveClip.cpp:1470

References AddCutLine(), Envelope::CollapseRegion(), CountSamples(), GetEnvelope(), GetFactory(), GetPlayEndTime(), GetPlayStartTime(), GetRate(), GetSequenceStartTime(), MarkChanged(), mCutLines, min(), mSequences, anonymous_namespace{wxCommandTargets.cpp}::scope, 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 1310 of file WaveClip.cpp.

1311{
1312 if (t > GetPlayStartTime() && t < GetPlayEndTime())
1313 {
1314 Transaction transaction{ *this };
1316 .Commit();
1317 transaction.Commit();
1318 SetTrimLeft(.0);
1320 MarkChanged();
1321 }
1322}
void SetSequenceStartTime(double startTime)
Definition: WaveClip.cpp:1870

References ClearSequence(), WaveClip::ClearSequenceFinisher::Commit(), GetPlayEndTime(), GetPlayStartTime(), GetSequenceStartTime(), MarkChanged(), 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 1324 of file WaveClip.cpp.

1325{
1326 if (t > GetPlayStartTime() && t < GetPlayEndTime())
1327 {
1328 Transaction transaction{ *this };
1330 .Commit();
1331 transaction.Commit();
1332 SetTrimRight(.0);
1333 MarkChanged();
1334 }
1335}

References ClearSequence(), WaveClip::ClearSequenceFinisher::Commit(), GetPlayEndTime(), GetPlayStartTime(), GetSequenceEndTime(), MarkChanged(), and SetTrimRight().

Here is the call graph for this function:

◆ ClearSequence()

auto 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)

Precondition
StrongInvariant()
Postcondition
StrongInvariant()

Definition at line 1337 of file WaveClip.cpp.

1338{
1339 StrongInvariantScope scope{ *this };
1340
1341 auto clip_t0 = std::max(t0, GetSequenceStartTime());
1342 auto clip_t1 = std::min(t1, GetSequenceEndTime());
1343
1344 auto s0 = TimeToSequenceSamples(clip_t0);
1345 auto s1 = TimeToSequenceSamples(clip_t1);
1346
1347 if (s0 == s1)
1348 return {};
1349
1350 // use Strong-guarantee
1351 for (auto &pSequence : mSequences)
1352 pSequence->Delete(s0, s1 - s0);
1353
1354 return { this, t0, t1, clip_t0, clip_t1 };
1355}

References min(), and anonymous_namespace{wxCommandTargets.cpp}::scope.

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 1559 of file WaveClip.cpp.

1560{
1561 // Don't need a Transaction for noexcept operations
1562 for (auto &pSequence : mSequences)
1563 pSequence->CloseLock();
1564 for (const auto &cutline: mCutLines)
1565 cutline->CloseLock();
1566}

References mCutLines, and mSequences.

◆ ConvertToSampleFormat()

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

Definition at line 782 of file WaveClip.cpp.

784{
785 // This mutator does not require the strong invariant. It leaves sample
786 // counts unchanged in each sequence.
787
788 // Note: it is not necessary to do this recursively to cutlines.
789 // They get converted as needed when they are expanded.
790
791 Transaction transaction{ *this };
792
793 auto bChanged = mSequences[0]->ConvertToSampleFormat(format, progressReport);
794 for (size_t ii = 1, width = NChannels(); ii < width; ++ii) {
795 bool alsoChanged =
796 mSequences[ii]->ConvertToSampleFormat(format, progressReport);
797 // Class invariant implies:
798 assert(bChanged == alsoChanged);
799 }
800 if (bChanged)
801 MarkChanged();
802
803 transaction.Commit();
804}

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

Here is the call graph for this function:

◆ CountBlocks()

size_t WaveClip::CountBlocks ( ) const

Definition at line 693 of file WaveClip.cpp.

694{
695 return std::accumulate(mSequences.begin(), mSequences.end(), size_t{},
696 [](size_t acc, auto &pSequence){
697 return acc + pSequence->GetBlockArray().size(); });
698}

References mSequences.

◆ CountSamples()

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

Counts number of sample times 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 1948 of file WaveClip.cpp.

1949{
1950 if(t0 < t1)
1951 {
1952 t0 = std::max(t0, GetPlayStartTime());
1953 t1 = std::min(t1, GetPlayEndTime());
1954 const auto s0 = TimeToSamples(t0 - GetPlayStartTime());
1955 const auto s1 = TimeToSamples(t1 - GetPlayStartTime());
1956 return s1 - s0;
1957 }
1958 return { 0 };
1959}

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 1927 of file WaveClip.cpp.

1928{
1929 assert(t0 <= t1);
1930 return t0 <= GetPlayStartTime() && GetPlayEndTime() <= t1;
1931}

References GetPlayEndTime(), and GetPlayStartTime().

Here is the call graph for this function:

◆ DiscardRightChannel()

void WaveClip::DiscardRightChannel ( )

Reduce width.

Postcondition
NChannels() == 1

Definition at line 429 of file WaveClip.cpp.

430{
431 mSequences.resize(1);
432 this->Attachments::ForEach([](WaveClipListener &attachment){
433 attachment.Erase(1);
434 });
435 for (auto &pCutline : mCutLines)
436 pCutline->DiscardRightChannel();
437 assert(NChannels() == 1);
438 assert(CheckInvariants());
439}
virtual void Erase(size_t index)
Definition: WaveClip.cpp:58

References CheckInvariants(), WaveClipListener::Erase(), mCutLines, mSequences, and NChannels().

Referenced by SplitChannels().

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

◆ DoGetChannel()

std::shared_ptr< ChannelInterval > WaveClip::DoGetChannel ( size_t  iChannel)
overridevirtual

Retrieve a channel.

Postcondition
result: !(iChannel < NChannels()) || result

Implements WideChannelGroupInterval.

Definition at line 350 of file WaveClip.cpp.

351{
352 return std::make_shared<Channel>(*this, iChannel);
353}

References anonymous_namespace{StretchingSequenceIntegrationTest.cpp}::iChannel.

◆ End()

double WaveClip::End ( ) const
overridevirtual
Postcondition
result: Start() < result

Implements ChannelGroupInterval.

Definition at line 345 of file WaveClip.cpp.

346{
347 return GetPlayEndTime();
348}

References GetPlayEndTime().

Referenced by anonymous_namespace{WaveClipAdjustBorderHandle.cpp}::GetRightAdjustLimit(), and TimeStretching::SetClipStretchRatio().

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

◆ EntirelyWithinPlayRegion()

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

t0 and t1 both ∈ [...)

Precondition
t0 <= t1

Definition at line 1905 of file WaveClip.cpp.

1906{
1907 assert(t0 <= t1);
1908 // t1 is the open end of the interval, hence it's ok if it's equal to the
1909 // open end of the play region.
1910 return !BeforePlayRegion(t0) && t1 <= GetPlayEndTime();
1911}
bool BeforePlayRegion(double t) const
t < [
Definition: WaveClip.cpp:1933

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 1499 of file WaveClip.cpp.

1500{
1501 auto end = mCutLines.end();
1502 auto it = std::find_if( mCutLines.begin(), end,
1503 [&](const WaveClipHolder &cutline) {
1504 return fabs(GetSequenceStartTime() + cutline->GetSequenceStartTime() - cutLinePosition) < 0.0001;
1505 } );
1506
1507 if ( it != end ) {
1508 auto *cutline = it->get();
1509 // assume Strong-guarantee from Paste
1510
1511 // Envelope::Paste takes offset into account, WaveClip::Paste doesn't!
1512 // Do this to get the right result:
1513 cutline->mEnvelope->SetOffset(0);
1514 bool success = Paste(
1515 GetSequenceStartTime() + cutline->GetSequenceStartTime(), *cutline);
1516 assert(success); // class invariant promises cutlines have correct width
1517
1518 // Now erase the cutline,
1519 // but be careful to find it again, because Paste above may
1520 // have modified the array of cutlines (if our cutline contained
1521 // another cutline!), invalidating the iterator we had.
1522 end = mCutLines.end();
1523 it = std::find_if(mCutLines.begin(), end,
1524 [=](const WaveClipHolder &p) { return p.get() == cutline; });
1525 if (it != end)
1526 mCutLines.erase(it); // deletes cutline!
1527 else {
1528 wxASSERT(false);
1529 }
1530 }
1531}
bool Paste(double t0, const WaveClip &other)
Definition: WaveClip.cpp:1100

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

Here is the call graph for this function:

◆ FindCutLine()

bool WaveClip::FindCutLine ( double  cutLinePosition,
double *  cutLineStart = nullptr,
double *  cutLineEnd = nullptr 
) 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 1478 of file WaveClip.cpp.

1481{
1482 for (const auto &cutline: mCutLines)
1483 {
1484 if (fabs(GetSequenceStartTime() + cutline->GetSequenceStartTime() - cutLinePosition) < 0.0001)
1485 {
1486 auto startTime = GetSequenceStartTime() + cutline->GetSequenceStartTime();
1487 if (cutlineStart)
1488 *cutlineStart = startTime;
1489 if (cutlineEnd)
1490 *cutlineEnd = startTime + cutline->SamplesToTime(cutline->GetVisibleSampleCount());
1491 return true;
1492 }
1493 }
1494
1495 return false;
1496}

References GetSequenceStartTime(), and mCutLines.

Here is the call graph for this function:

◆ FixSplitCutlines()

void WaveClip::FixSplitCutlines ( WaveClipHolders myCutlines,
WaveClipHolders newCutlines 
)
staticprivate

Definition at line 462 of file WaveClip.cpp.

464{
465 auto beginMe = myCutlines.begin(),
466 endMe = myCutlines.end();
467 auto iterNew = newCutlines.begin(),
468 endNew = newCutlines.end();
469 for_each(beginMe, endMe, [&](const auto &myCutline){
470 assert(iterNew != endNew);
471 const auto pNew = *iterNew;
472 TransferSequence(*myCutline, *pNew);
473 // Recursion!
474 FixSplitCutlines(myCutline->mCutLines, pNew->mCutLines);
475 ++iterNew;
476 });
477 assert(iterNew == endNew);
478}
static void FixSplitCutlines(WaveClipHolders &myCutlines, WaveClipHolders &newCutlines)
Definition: WaveClip.cpp:462
static void TransferSequence(WaveClip &origClip, WaveClip &newClip)
Definition: WaveClip.cpp:453

References FixSplitCutlines(), and TransferSequence().

Referenced by FixSplitCutlines(), and SplitChannels().

Here is the call graph for this function:
Here is the caller 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 893 of file WaveClip.cpp.

894{
895 // Does not require or guarantee the strong invariant
896
897 //wxLogDebug(wxT("WaveClip::Flush"));
898 //wxLogDebug(wxT(" mAppendBufferLen=%lli"), (long long) mAppendBufferLen);
899 //wxLogDebug(wxT(" previous sample count %lli"), (long long) mSequence->GetNumSamples());
900
901 if (GreatestAppendBufferLen() > 0) {
902
903 Transaction transaction{ *this };
904
905 for (auto &pSequence : mSequences)
906 pSequence->Flush();
907
908 transaction.Commit();
909
910 // No-fail operations
912 MarkChanged();
913 }
914
915 //wxLogDebug(wxT("now sample count %lli"), (long long) mSequence->GetNumSamples());
916}
size_t GreatestAppendBufferLen() const
Definition: WaveClip.cpp:537

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

Referenced by 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 < NChannels()

Definition at line 729 of file WaveClip.cpp.

730{
731 assert(ii < NChannels());
732 return mSequences[ii]->GetAppendBuffer();
733}

References mSequences, and NChannels().

Referenced by WaveClipChannel::GetAppendBuffer().

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

◆ GetAppendBufferLen()

size_t WaveClip::GetAppendBufferLen ( size_t  ii) const
Parameters
iiidentifies the channel
Precondition
ii < NChannels()

Definition at line 423 of file WaveClip.cpp.

424{
425 assert(iChannel < NChannels());
426 return mSequences[iChannel]->GetAppendBufferLen();
427}

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

Referenced by WaveClipChannel::GetAppendBufferLen(), and GreatestAppendBufferLen().

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

◆ GetBestBlockSize()

size_t WaveClip::GetBestBlockSize ( sampleCount  t) const

A hint for sizing of well aligned fetches.

Definition at line 701 of file WaveClip.cpp.

702{
703 return mSequences[0]->GetBestBlockSize(t);
704}

References mSequences.

◆ GetCentShift()

int WaveClip::GetCentShift ( ) const
overridevirtual

Implements ClipInterface.

Definition at line 634 of file WaveClip.cpp.

635{
636 return mCentShift;
637}

References mCentShift.

Referenced by anonymous_namespace{PitchAndSpeedDialog.cpp}::GetClipShift(), HasEqualPitchAndSpeed(), and HasPitchOrSpeed().

Here is the caller graph for this function:

◆ GetCutLines() [1/2]

const WaveClipHolders & WaveClip::GetCutLines ( )
inline

Get access to cut lines list.

Definition at line 728 of file WaveClip.h.

728{ return mCutLines; }

◆ GetCutLines() [2/2]

const WaveClipConstHolders & WaveClip::GetCutLines ( ) const
inline

Definition at line 729 of file WaveClip.h.

730 { return reinterpret_cast< const WaveClipConstHolders& >( mCutLines ); }
std::vector< WaveClipConstHolder > WaveClipConstHolders
Definition: WaveClip.h:46

◆ GetEmptySequenceCopies()

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

Definition at line 719 of file WaveClip.cpp.

720{
721 decltype(mSequences) newSequences;
722 newSequences.reserve(mSequences.size());
723 for (auto& pSequence : mSequences)
724 newSequences.push_back(std::make_unique<Sequence>(
725 pSequence->GetFactory(), pSequence->GetSampleFormats()));
726 return newSequences;
727}

References mSequences.

Referenced by Resample().

Here is the caller graph for this function:

◆ GetEnvelope() [1/2]

const Envelope & WaveClip::GetEnvelope ( ) const
inlinenoexcept

Definition at line 554 of file WaveClip.h.

554{ return *mEnvelope; }

◆ GetEnvelope() [2/2]

Envelope & WaveClip::GetEnvelope ( )
inlinenoexcept

Definition at line 553 of file WaveClip.h.

553{ return *mEnvelope; }

Referenced by ClearAndAddCutLine(), WaveClipChannel::GetEnvelope(), AUPImportFileHandle::HandleEnvelope(), InsertSilence(), and WaveClip::ClearSequenceFinisher::~ClearSequenceFinisher().

Here is the caller graph for this function:

◆ GetFactory()

const SampleBlockFactoryPtr & WaveClip::GetFactory ( ) const
private

Definition at line 713 of file WaveClip.cpp.

714{
715 // All sequences have the same factory by class invariant
716 return mSequences[0]->GetFactory();
717}

References mSequences.

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

Here is the caller graph for this function:

◆ GetIsPlaceholder()

bool WaveClip::GetIsPlaceholder ( ) const
inline

Definition at line 772 of file WaveClip.h.

772{ return mIsPlaceholder; }

Referenced by WaveClip().

Here is the caller graph for this function:

◆ GetMaxBlockSize()

size_t WaveClip::GetMaxBlockSize ( ) const

Definition at line 706 of file WaveClip.cpp.

707{
708 return std::accumulate(mSequences.begin(), mSequences.end(), size_t{},
709 [](size_t acc, auto &pSequence){
710 return std::max(acc, pSequence->GetMaxBlockSize()); });
711}

References mSequences.

◆ 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 < NChannels()

Definition at line 740 of file WaveClip.cpp.

742{
743 assert(ii < NChannels());
744 t0 = std::max(t0, GetPlayStartTime());
745 t1 = std::min(t1, GetPlayEndTime());
746 if (t0 > t1) {
747 if (mayThrow)
749 return {
750 0.f, // harmless, but unused since Sequence::GetMinMax does not use these values
751 0.f // harmless, but unused since Sequence::GetMinMax does not use these values
752 };
753 }
754
755 if (t0 == t1)
756 return{ 0.f, 0.f };
757
758 auto s0 = TimeToSequenceSamples(t0);
759 auto s1 = TimeToSequenceSamples(t1);
760
761 return mSequences[ii]->GetMinMax(s0, s1 - s0, mayThrow);
762}
#define THROW_INCONSISTENCY_EXCEPTION
Throw InconsistencyException, using C++ preprocessor to identify the source code location.

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

Referenced by WaveClipChannel::GetMinMax().

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

◆ GetName()

const wxString & WaveClip::GetName ( ) const

Definition at line 1717 of file WaveClip.cpp.

1718{
1719 return mName;
1720}

References mName.

◆ GetNumSamples()

sampleCount WaveClip::GetNumSamples ( ) const
private

Definition at line 678 of file WaveClip.cpp.

679{
680 // Assume only the weak invariant
681 sampleCount result = 0;
682 for (auto &pSequence: mSequences)
683 result = std::max(result, pSequence->GetNumSamples());
684 return result;
685}
Positions or offsets within audio files need a wide type.
Definition: SampleCount.h:19

References mSequences.

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

Here is the caller graph for this function:

◆ GetPitchAndSpeedPreset()

PitchAndSpeedPreset WaveClip::GetPitchAndSpeedPreset ( ) const
virtual

Implements ClipInterface.

Definition at line 1606 of file WaveClip.cpp.

1607{
1608 return mPitchAndSpeedPreset;
1609}

References mPitchAndSpeedPreset.

◆ GetPlayDuration()

double WaveClip::GetPlayDuration ( ) const

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

Definition at line 1775 of file WaveClip.cpp.

1776{
1777 return GetPlayEndTime() - GetPlayStartTime();
1778}

References GetPlayEndTime(), and GetPlayStartTime().

Referenced by IsEmpty().

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 1790 of file WaveClip.cpp.

1791{
1792 return sampleCount { GetPlayEndTime() * mRate + 0.5 };
1793}

References GetPlayEndTime(), and mRate.

Referenced by WaveClipChannel::GetPlayEndSample().

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 1763 of file WaveClip.cpp.

1764{
1765 const auto numSamples = GetNumSamples();
1766 double maxLen = mSequenceOffset +
1767 ((numSamples + GreatestAppendBufferLen()).as_double()) *
1769 mTrimRight;
1770 // JS: calculated value is not the length;
1771 // it is a maximum value and can be negative; no clipping to 0
1772 return SnapToTrackSample(maxLen);
1773}
double GetStretchRatio() const override
Definition: WaveClip.cpp:625
double SnapToTrackSample(double time) const noexcept
Definition: WaveClip.cpp:1732
sampleCount GetNumSamples() const
Definition: WaveClip.cpp:678

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

Referenced by AUPImportFileHandle::AddSilence(), AfterPlayRegion(), AppendSilence(), Clear(), ClearAndAddCutLine(), ClearLeft(), ClearRight(), CountSamples(), CoversEntirePlayRegion(), WaveClipChannel::End(), End(), EntirelyWithinPlayRegion(), GetMinMax(), GetPlayDuration(), GetPlayEndSample(), WaveClipChannel::GetPlayEndTime(), InsertSilence(), IntersectsPlayRegion(), Paste(), WaveClipUIUtilities::SelectClip(), anonymous_namespace{ClipOverflowButtonHandle.cpp}::SelectInterval(), 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 1785 of file WaveClip.cpp.

1786{
1787 return sampleCount { GetPlayStartTime() * mRate + 0.5 };
1788}

References GetPlayStartTime(), and mRate.

Referenced by WaveClipChannel::GetPlayStartSample().

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 1753 of file WaveClip.cpp.

1754{
1756}

References mSequenceOffset, mTrimLeft, and SnapToTrackSample().

Referenced by AtOrBeforePlayRegion(), BeforePlayRegion(), Clear(), ClearAndAddCutLine(), ClearLeft(), ClearRight(), CountSamples(), CoversEntirePlayRegion(), GetMinMax(), GetPlayDuration(), GetPlayStartSample(), WaveClipChannel::GetPlayStartTime(), InsertSilence(), IntersectsPlayRegion(), Paste(), WaveClipUIUtilities::SelectClip(), anonymous_namespace{ClipOverflowButtonHandle.cpp}::SelectInterval(), WaveClipUtilities::SharesBoundaryWithNextClip(), SplitsPlayRegion(), WaveClipChannel::Start(), Start(), StretchBy(), 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 337 of file WaveClip.h.

338 {
339 return mRate;
340 }

Referenced by ClearAndAddCutLine(), WaveClipChannel::GetRate(), InsertSilence(), Paste(), WaveClipUtilities::SharesBoundaryWithNextClip(), TrimQuarternotesFromRight(), UpdateEnvelopeTrackLen(), and WaveClip::ClearSequenceFinisher::~ClearSequenceFinisher().

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 < NChannels()

Definition at line 764 of file WaveClip.cpp.

765{
766 assert(ii < NChannels());
767 if (t0 > t1) {
768 if (mayThrow)
770 return 0.f;
771 }
772
773 if (t0 == t1)
774 return 0.f;
775
776 auto s0 = TimeToSequenceSamples(t0);
777 auto s1 = TimeToSequenceSamples(t1);
778
779 return mSequences[ii]->GetRMS(s0, s1-s0, mayThrow);
780}

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

Referenced by WaveClipChannel::GetRMS().

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

◆ GetSampleFormats()

SampleFormats WaveClip::GetSampleFormats ( ) const

Definition at line 687 of file WaveClip.cpp.

688{
689 // All sequences have the same formats by class invariant
690 return mSequences[0]->GetSampleFormats();
691}

References mSequences.

Referenced by MakeStereo(), and 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 NChannels()

Parameters
startrelative to clip play start sample

Definition at line 387 of file WaveClip.cpp.

389{
390 bool result = true;
391 for (size_t ii = 0, width = NChannels(); result && ii < width; ++ii)
392 result = GetSamples(ii, buffers[ii], format, start, len, mayThrow);
393 return result;
394}
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:378

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

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 < NChannels()

Definition at line 378 of file WaveClip.cpp.

381{
382 assert(ii < NChannels());
383 return mSequences[ii]
384 ->Get(buffer, format, start + TimeToSamples(mTrimLeft), len, mayThrow);
385}

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

Referenced by WaveClipUtilities::GetFloatAtTime(), WaveClipChannel::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 < NChannels()
stretched samples in [t0, t1) can be counted in a size_t

Definition at line 363 of file WaveClip.cpp.

365{
366 assert(iChannel < NChannels());
367 const auto start = TimeToSamples(std::max(0., t0));
368 const auto length =
369 (std::min(GetNumSamples(), TimeToSamples(t1)) - start).as_size_t();
370 return GetSampleView(iChannel, start, length, mayThrow);
371}
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:355

References GetNumSamples(), GetSampleView(), anonymous_namespace{StretchingSequenceIntegrationTest.cpp}::iChannel, min(), NChannels(), 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 < NChannels()

Implements ClipInterface.

Definition at line 355 of file WaveClip.cpp.

357{
358 assert(ii < NChannels());
359 return mSequences[ii]->GetFloatSampleView(
360 start + TimeToSamples(mTrimLeft), length, mayThrow);
361}

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

Referenced by WaveClipChannel::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 < NChannels()

Definition at line 571 of file WaveClip.h.

571 {
572 assert(ii < NChannels());
573 return mSequences[ii].get();
574 }

Referenced by WaveClipChannel::GetSequence().

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 < NChannels()

Definition at line 578 of file WaveClip.h.

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

◆ GetSequenceBlockArray()

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

Definition at line 417 of file WaveClip.cpp.

418{
419 assert(ii < NChannels());
420 return &mSequences[ii]->GetBlockArray();
421}

References mSequences, and NChannels().

Referenced by WaveClipChannel::GetSequenceBlockArray().

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

◆ GetSequenceEndTime()

double WaveClip::GetSequenceEndTime ( ) const

Definition at line 1876 of file WaveClip.cpp.

1877{
1878 const auto numSamples = GetNumSamples();
1879 double maxLen = GetSequenceStartTime() +
1880 numSamples.as_double() * GetStretchRatio() / mRate;
1881 return maxLen;
1882}

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

Referenced by Clear(), ClearRight(), anonymous_namespace{WaveClipAdjustBorderHandle.cpp}::GetLeftAdjustLimit(), anonymous_namespace{WaveClipAdjustBorderHandle.cpp}::GetRightAdjustLimit(), 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 1748 of file WaveClip.cpp.

1749{
1750 return GetNumSamples() * NChannels();
1751}

References GetNumSamples(), and NChannels().

Referenced by Paste().

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

◆ GetSequenceStartSample()

sampleCount WaveClip::GetSequenceStartSample ( ) const

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

Definition at line 1884 of file WaveClip.cpp.

1885{
1887}

References mSequenceOffset, and TimeToSamples().

Here is the call graph for this function:

◆ GetSequenceStartTime()

double WaveClip::GetSequenceStartTime ( ) const
noexcept

Definition at line 1863 of file WaveClip.cpp.

1864{
1865 // JS: mSequenceOffset is the minimum value and it is returned; no clipping to 0
1866 // Do we need to `SnapToTrackSample` before returning?
1867 return mSequenceOffset;
1868}

References mSequenceOffset.

Referenced by Clear(), ClearAndAddCutLine(), ClearLeft(), ExpandCutLine(), FindCutLine(), anonymous_namespace{WaveClipAdjustBorderHandle.cpp}::GetLeftAdjustLimit(), anonymous_namespace{WaveClipAdjustBorderHandle.cpp}::GetRightAdjustLimit(), GetSequenceEndTime(), InsertSilence(), OffsetCutLines(), Paste(), RemoveCutLine(), SetRate(), ShiftBy(), TimeToSequenceSamples(), WaveClip(), and WaveClip::ClearSequenceFinisher::~ClearSequenceFinisher().

Here is the caller graph for this function:

◆ GetStretchRatio()

double WaveClip::GetStretchRatio ( ) const
overridevirtual

Implements ClipTimes.

Definition at line 625 of file WaveClip.cpp.

626{
627 const auto dstSrcRatio =
628 mProjectTempo.has_value() && mRawAudioTempo.has_value() ?
630 1.0;
631 return mClipStretchRatio * dstSrcRatio;
632}

References mClipStretchRatio, mProjectTempo, and mRawAudioTempo.

Referenced by GetPlayEndTime(), GetSequenceEndTime(), WaveClipChannel::GetStretchRatio(), HasEqualPitchAndSpeed(), OnProjectTempoChange(), Paste(), SamplesToTime(), TimeStretching::SetClipStretchRatio(), SetRate(), WaveClipUtilities::SharesBoundaryWithNextClip(), StretchBy(), StretchLeftTo(), StretchRatioEquals(), TimeToSamples(), TrimQuarternotesFromRight(), and UpdateEnvelopeTrackLen().

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 1806 of file WaveClip.cpp.

1807{
1808 return mTrimLeft;
1809}

References mTrimLeft.

Referenced by Clear(), and WaveClipChannel::GetTrimLeft().

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 1816 of file WaveClip.cpp.

1817{
1818 return mTrimRight;
1819}

References mTrimRight.

Referenced by WaveClipChannel::GetTrimRight().

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 1795 of file WaveClip.cpp.

1796{
1797 return GetNumSamples()
1799}

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

Referenced by WaveClipChannel::GetVisibleSampleCount(), WaveClipUtilities::SetFloatsFromTime(), and WaveClipUtilities::SharesBoundaryWithNextClip().

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

◆ GreatestAppendBufferLen()

size_t WaveClip::GreatestAppendBufferLen ( ) const
private

Definition at line 537 of file WaveClip.cpp.

538{
539 size_t result = 0;
540 for (size_t iChannel = 0; iChannel < NChannels(); ++iChannel)
541 result = std::max(result, mSequences[iChannel]->GetAppendBufferLen());
542 return result;
543}
size_t GetAppendBufferLen(size_t ii) const
Definition: WaveClip.cpp:423

References GetAppendBufferLen(), anonymous_namespace{StretchingSequenceIntegrationTest.cpp}::iChannel, mSequences, and NChannels().

Referenced by Flush(), and GetPlayEndTime().

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

◆ HandleXMLChild()

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

Implements XMLTagHandler.

Definition at line 1034 of file WaveClip.cpp.

1035{
1036 auto &pFirst = mSequences[0];
1037 if (tag == Sequence::Sequence_tag) {
1038 // Push back a new sequence prototyped from the empty sequence made
1039 // by the constructor. See also HandleXMLEndTag above.
1040 // Assume sequences were serialized in channel iteration order.
1041 mSequences.push_back(std::make_unique<Sequence>(
1042 pFirst->GetFactory(), pFirst->GetSampleFormats()));
1043 return mSequences.back().get();
1044 }
1045 else if (tag == "envelope")
1046 return mEnvelope.get();
1047 else if (tag == WaveClip_tag)
1048 {
1049 // Nested wave clips are cut lines
1050 auto format = pFirst->GetSampleFormats().Stored();
1051 // The format is not stored in WaveClip itself but passed to
1052 // Sequence::Sequence; but then the Sequence will deserialize format
1053 // again
1054 mCutLines.push_back(
1055 std::make_shared<WaveClip>(
1056 // Make only one channel now, but recursive deserialization
1057 // increases the width later
1058 1, pFirst->GetFactory(),
1059 format, mRate));
1060 return mCutLines.back().get();
1061 }
1062 else
1063 return nullptr;
1064}
static const char * Sequence_tag
Definition: Sequence.h:56
static const char * WaveClip_tag
Definition: WaveClip.h:249

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

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 1020 of file WaveClip.cpp.

1021{
1022 // All blocks were deserialized into new sequences; remove the one made
1023 // by the constructor which remains empty.
1024 mSequences.erase(mSequences.begin());
1025 mSequences.shrink_to_fit();
1026 if (tag == WaveClip_tag)
1028 // A proof of this assertion assumes that nothing has happened since
1029 // construction of this, besides calls to the other deserialization
1030 // functions
1031 assert(CheckInvariants());
1032}

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

Here is the call graph for this function:

◆ HandleXMLTag()

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

Implements XMLTagHandler.

Definition at line 947 of file WaveClip.cpp.

948{
949 if (tag == WaveClip_tag)
950 {
951 double dblValue;
952 long longValue;
953 for (auto pair : attrs)
954 {
955 auto attr = pair.first;
956 auto value = pair.second;
957
958 if (attr == Offset_attr)
959 {
960 if (!value.TryGet(dblValue))
961 return false;
962 SetSequenceStartTime(dblValue);
963 }
964 else if (attr == TrimLeft_attr)
965 {
966 if (!value.TryGet(dblValue))
967 return false;
968 SetTrimLeft(dblValue);
969 }
970 else if (attr == TrimRight_attr)
971 {
972 if (!value.TryGet(dblValue))
973 return false;
974 SetTrimRight(dblValue);
975 }
976 else if (attr == CentShiftAttr)
977 {
978 if (!value.TryGet(dblValue))
979 return false;
980 mCentShift = dblValue;
981 }
982 else if (attr == PitchAndSpeedPreset_attr)
983 {
984 if (!value.TryGet(longValue))
985 return false;
986 mPitchAndSpeedPreset = static_cast<PitchAndSpeedPreset>(longValue);
987 }
988 else if (attr == RawAudioTempo_attr)
989 {
990 if (!value.TryGet(dblValue))
991 return false;
992 if (dblValue == 0)
993 mRawAudioTempo.reset();
994 else
995 mRawAudioTempo = dblValue;
996 }
997 else if (attr == ClipStretchRatio_attr)
998 {
999 if (!value.TryGet(dblValue))
1000 return false;
1001 mClipStretchRatio = dblValue;
1002 }
1003 else if (attr == Name_attr)
1004 {
1005 if(value.IsStringView())
1006 SetName(value.ToWString());
1007 }
1008 else if (Attachments::FindIf(
1009 [&](WaveClipListener &listener){
1010 return listener.HandleXMLAttribute(attr, value); }
1011 ))
1012 ;
1013 }
1014 return true;
1015 }
1016
1017 return false;
1018}
PitchAndSpeedPreset
Definition: ClipInterface.h:40
static constexpr auto TrimRight_attr
Definition: WaveClip.cpp:940
static constexpr auto RawAudioTempo_attr
Definition: WaveClip.cpp:943
static constexpr auto ClipStretchRatio_attr
Definition: WaveClip.cpp:944
static constexpr auto Name_attr
Definition: WaveClip.cpp:945
static constexpr auto CentShiftAttr
Definition: WaveClip.cpp:941
static constexpr auto Offset_attr
Definition: WaveClip.cpp:938
static constexpr auto TrimLeft_attr
Definition: WaveClip.cpp:939
static constexpr auto PitchAndSpeedPreset_attr
Definition: WaveClip.cpp:942
void SetName(const wxString &name)
Definition: WaveClip.cpp:1712
virtual bool HandleXMLAttribute(const std::string_view &attr, const XMLAttributeValueView &valueView)
Definition: WaveClip.cpp:44

References CentShiftAttr, ClipStretchRatio_attr, WaveClipListener::HandleXMLAttribute(), mCentShift, mClipStretchRatio, mPitchAndSpeedPreset, mRawAudioTempo, Name_attr, Offset_attr, PitchAndSpeedPreset_attr, RawAudioTempo_attr, SetName(), SetSequenceStartTime(), SetTrimLeft(), SetTrimRight(), TrimLeft_attr, TrimRight_attr, and WaveClip_tag.

Here is the call graph for this function:

◆ HasEqualPitchAndSpeed()

bool WaveClip::HasEqualPitchAndSpeed ( const WaveClip other) const

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

Definition at line 661 of file WaveClip.cpp.

662{
663 return StretchRatioEquals(other.GetStretchRatio()) &&
664 GetCentShift() == other.GetCentShift();
665}
int GetCentShift() const override
Definition: WaveClip.cpp:634
bool StretchRatioEquals(double value) const
Definition: WaveClip.cpp:672

References GetCentShift(), GetStretchRatio(), and StretchRatioEquals().

Here is the call graph for this function:

◆ HasPitchOrSpeed()

bool WaveClip::HasPitchOrSpeed ( ) const

Definition at line 667 of file WaveClip.cpp.

668{
669 return !StretchRatioEquals(1.0) || GetCentShift() != 0;
670}

References GetCentShift(), and StretchRatioEquals().

Referenced by WaveClipChannel::HasPitchOrSpeed().

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

Precondition
StrongInvariant()
Postcondition
StrongInvariant()
Exception safety guarantee:
Strong

Definition at line 1229 of file WaveClip.cpp.

1230{
1231 StrongInvariantScope scope{ *this };
1232 Transaction transaction{ *this };
1233 ClearSequenceFinisher finisher;
1234
1235 if (t == GetPlayStartTime() && t > GetSequenceStartTime())
1236 finisher = ClearSequence(GetSequenceStartTime(), t);
1237 else if (t == GetPlayEndTime() && t < GetSequenceEndTime()) {
1238 finisher = ClearSequence(t, GetSequenceEndTime());
1239 SetTrimRight(.0);
1240 }
1241
1242 const auto s0 = TimeToSequenceSamples(t);
1243 const auto slen = TimeToSamples(len);
1244
1245 // use Strong-guarantee
1246 for (auto &pSequence : mSequences)
1247 pSequence->InsertSilence(s0, slen);
1248
1249 // use No-fail-guarantee in the rest
1250 finisher.Commit();
1251 transaction.Commit();
1252
1253 OffsetCutLines(t, len);
1254
1255 const auto sampleTime = 1.0 / GetRate();
1256 auto &envelope = GetEnvelope();
1257 if ( pEnvelopeValue ) {
1258
1259 // Preserve limit value at the end
1260 auto oldLen = envelope.GetTrackLen();
1261 auto newLen = oldLen + len;
1262 envelope.Cap( sampleTime );
1263
1264 // Ramp across the silence to the given value
1265 envelope.SetTrackLen( newLen, sampleTime );
1266 envelope.InsertOrReplace
1267 ( envelope.GetOffset() + newLen, *pEnvelopeValue );
1268 }
1269 else
1270 envelope.InsertSpace( t, len );
1271
1272 MarkChanged();
1273}
void OffsetCutLines(double t0, double len)
Offset cutlines right to time 't0' by time amount 'len'.
Definition: WaveClip.cpp:1550

References ClearSequence(), WaveClip::ClearSequenceFinisher::Commit(), GetEnvelope(), GetPlayEndTime(), GetPlayStartTime(), GetRate(), GetSequenceEndTime(), GetSequenceStartTime(), MarkChanged(), mSequences, OffsetCutLines(), anonymous_namespace{wxCommandTargets.cpp}::scope, SetTrimRight(), TimeToSamples(), 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 1919 of file WaveClip.cpp.

1920{
1921 assert(t0 <= t1);
1922 // t1 is the open end of the interval, so it must be excluded from the closed
1923 // begin of the play region.
1924 return t0 < GetPlayEndTime() && GetPlayStartTime() < t1;
1925}

References GetPlayEndTime(), and GetPlayStartTime().

Referenced by WaveClipChannel::Intersects().

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

◆ IsEmpty()

bool WaveClip::IsEmpty ( ) const

Definition at line 1780 of file WaveClip.cpp.

1781{
1782 return std::floor(GetPlayDuration() * mRate + 0.5) < 2.0;
1783}
double GetPlayDuration() const
Definition: WaveClip.cpp:1775

References GetPlayDuration(), and mRate.

Here is the call graph for this function:

◆ MakeStereo()

void WaveClip::MakeStereo ( WaveClip &&  other,
bool  mustAlign 
)

Steal the right side data from other All cutlines are lost in this! Cutlines are not copied from other.

Stating sufficient preconditions for the postondition. Even stronger preconditions on matching offset, trims, and rates could be stated.

Precondition
NChannels() == 1
other.NChannels() == 1
GetSampleFormats() == other.GetSampleFormats()
GetSampleBlockFactory() == other.GetSampleBlockFactory()
!mustAlign || GetNumSamples() == other.GetNumSamples()
Postcondition
!mustAlign || StrongInvariant()

Definition at line 512 of file WaveClip.cpp.

513{
514 assert(NChannels() == 1);
515 assert(other.NChannels() == 1);
516 assert(GetSampleFormats() == other.GetSampleFormats());
517 assert(GetFactory() == other.GetFactory());
518 assert(!mustAlign || GetNumSamples() == other.GetNumSamples());
519
520 mCutLines.clear();
521 mSequences.resize(2);
522 mSequences[1] = move(other.mSequences[0]);
523
524 this->Attachments::ForCorresponding(other,
525 [mustAlign](WaveClipListener *pLeft, WaveClipListener *pRight){
526 // Precondition of callback from ClientData::Site
527 assert(pLeft && pRight);
528 pLeft->MakeStereo(std::move(*pRight), mustAlign);
529 });
530
531 if (mustAlign)
532 assert(StrongInvariant());
533 else
534 assert(CheckInvariants());
535}
SampleFormats GetSampleFormats() const
Definition: WaveClip.cpp:687
virtual void MakeStereo(WaveClipListener &&other, bool aligned)
Definition: WaveClip.cpp:50

References CheckInvariants(), GetFactory(), GetNumSamples(), GetSampleFormats(), WaveClipListener::MakeStereo(), mCutLines, mSequences, NChannels(), and StrongInvariant().

Here is the call graph for this function:

◆ MarkChanged()

void WaveClip::MarkChanged ( )
privatenoexcept

Called by mutating operations; notifies listeners.

Exception safety guarantee:
No-fail

Definition at line 735 of file WaveClip.cpp.

736{
737 Attachments::ForEach(std::mem_fn(&WaveClipListener::MarkChanged));
738}
virtual void MarkChanged() noexcept=0

References WaveClipListener::MarkChanged().

Referenced by Append(), Clear(), ClearAndAddCutLine(), ClearLeft(), ClearRight(), ConvertToSampleFormat(), Flush(), InsertSilence(), Paste(), Resample(), SetRate(), SetSamples(), SetSilence(), and ShiftBy().

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

◆ NChannels()

size_t WaveClip::NChannels ( ) const
overridevirtual

How many Sequences the clip contains.

Implements WideChannelGroupInterval.

Definition at line 373 of file WaveClip.cpp.

374{
375 return mSequences.size();
376}

References mSequences.

Referenced by AddCutLine(), Append(), AppendLegacyNewBlock(), AppendLegacySharedBlock(), AppendToChannel(), CheckInvariants(), ConvertToSampleFormat(), DiscardRightChannel(), GetAppendBuffer(), GetAppendBufferLen(), GetMinMax(), GetRMS(), GetSamples(), GetSampleView(), GetSequenceBlockArray(), GetSequenceSamplesCount(), GreatestAppendBufferLen(), MakeStereo(), Paste(), RepairChannels(), SetSamples(), SplitChannels(), StrongInvariant(), SwapChannels(), and WaveClip().

Here is the caller graph for this function:

◆ NumCutLines()

size_t WaveClip::NumCutLines ( ) const
inline

Definition at line 731 of file WaveClip.h.

731{ return mCutLines.size(); }

Referenced by WaveClip().

Here is the caller graph for this function:

◆ 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 1550 of file WaveClip.cpp.

1551{
1552 for (const auto &cutLine : mCutLines)
1553 {
1554 if (GetSequenceStartTime() + cutLine->GetSequenceStartTime() >= t0)
1555 cutLine->ShiftBy(len);
1556 }
1557}

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 545 of file WaveClip.cpp.

547{
548 if (!mRawAudioTempo.has_value())
549 // When we have tempo detection ready (either by header-file
550 // read-up or signal analysis) we can use something smarter than that. In
551 // the meantime, use the tempo of the project when the clip is created as
552 // source tempo.
553 mRawAudioTempo = oldTempo.value_or(newTempo);
554
555 if (oldTempo.has_value())
556 {
557 const auto ratioChange = *oldTempo / newTempo;
558 mSequenceOffset *= ratioChange;
559 mTrimLeft *= ratioChange;
560 mTrimRight *= ratioChange;
561 StretchCutLines(ratioChange);
562 mEnvelope->RescaleTimesBy(ratioChange);
563 }
564 mProjectTempo = newTempo;
567}
void StretchCutLines(double ratioChange)
Definition: WaveClip.cpp:613

References GetStretchRatio(), mEnvelope, mProjectTempo, mRawAudioTempo, mSequenceOffset, mTrimLeft, mTrimRight, Observer::Publisher< Message, NotifyAll >::Publish(), 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 1913 of file WaveClip.cpp.

1914{
1915 assert(t0 <= t1);
1916 return WithinPlayRegion(t0) != WithinPlayRegion(t1);
1917}
bool WithinPlayRegion(double t) const
t ∈ [...)
Definition: WaveClip.cpp:1900

References WithinPlayRegion().

Here is the call graph for this function:

◆ Paste()

bool WaveClip::Paste ( double  t0,
const WaveClip o 
)
Returns
true and succeed if and only if this->NChannels() == other.NChannels() and either this is empty or this->GetStretchRatio() == other.GetStretchRatio().
Precondition
StrongInvariant()
other.StrongInvariant()
Postcondition
StrongInvariant()

This says, same widths and ratios are sufficient for success

Postcondition
result: this->NChannels() != other.NChannels() || this->GetStretchRatio() != other.GetStretchRatio() || result
Exception safety guarantee:
Strong

Definition at line 1100 of file WaveClip.cpp.

1101{
1102 const WaveClip *pOther = &o;
1103 WaveClipHolder dup;
1104 if (!o.StrongInvariant()) {
1105 assert(false); // precondition not honored
1106 // But try to repair it and continue in release
1107 dup = std::make_shared<WaveClip>(o, o.GetFactory(), true);
1108 dup->RepairChannels();
1109 pOther = dup.get();
1110 }
1111 auto &other = *pOther;
1112
1113 if (NChannels() != other.NChannels())
1114 // post is satisfied
1115 return false;
1116
1117 if (GetSequenceSamplesCount() == 0)
1118 {
1119 // Empty clip: we're flexible and adopt the other's stretching.
1120 mRawAudioTempo = other.mRawAudioTempo;
1121 mClipStretchRatio = other.mClipStretchRatio;
1122 mProjectTempo = other.mProjectTempo;
1123 }
1124 else if (GetStretchRatio() != other.GetStretchRatio())
1125 // post is satisfied
1126 return false;
1127
1128 StrongInvariantScope scope{ *this };
1129
1130 Transaction transaction{ *this };
1131
1132 const bool clipNeedsResampling = other.mRate != mRate;
1133 const bool clipNeedsNewFormat =
1134 other.GetSampleFormats().Stored() != GetSampleFormats().Stored();
1135 std::shared_ptr<WaveClip> newClip;
1136
1137 t0 = std::clamp(t0, GetPlayStartTime(), GetPlayEndTime());
1138 // Delay the finish of the clearing of this clip
1139 ClearSequenceFinisher finisher;
1140
1141 //seems like edge cases cannot happen, see WaveTrack::PasteWaveTrack
1142 auto &factory = GetFactory();
1143 if (t0 == GetPlayStartTime())
1144 {
1145 finisher = ClearSequence(GetSequenceStartTime(), t0);
1146 SetTrimLeft(other.GetTrimLeft());
1147
1148 auto copy = std::make_shared<WaveClip>(other, factory, true);
1149 copy->ClearSequence(copy->GetPlayEndTime(), copy->GetSequenceEndTime())
1150 .Commit();
1151 newClip = std::move(copy);
1152 }
1153 else if (t0 == GetPlayEndTime())
1154 {
1156 SetTrimRight(other.GetTrimRight());
1157
1158 auto copy = std::make_shared<WaveClip>(other, factory, true);
1159 copy->ClearSequence(copy->GetSequenceStartTime(), copy->GetPlayStartTime())
1160 .Commit();
1161 newClip = std::move(copy);
1162 }
1163 else
1164 {
1165 newClip = std::make_shared<WaveClip>(other, factory, true);
1166 newClip->ClearSequence(newClip->GetPlayEndTime(), newClip->GetSequenceEndTime())
1167 .Commit();
1168 newClip->ClearSequence(newClip->GetSequenceStartTime(), newClip->GetPlayStartTime())
1169 .Commit();
1170 newClip->SetTrimLeft(0);
1171 newClip->SetTrimRight(0);
1172 }
1173
1174 if (clipNeedsResampling || clipNeedsNewFormat)
1175 {
1176 auto copy = std::make_shared<WaveClip>(*newClip.get(), factory, true);
1177
1178 if (clipNeedsResampling)
1179 // The other clip's rate is different from ours, so resample
1180 copy->Resample(mRate);
1181
1182 if (clipNeedsNewFormat)
1183 // Force sample formats to match.
1184 copy->ConvertToSampleFormat(GetSampleFormats().Stored());
1185 newClip = std::move(copy);
1186 }
1187
1188 // Paste cut lines contained in pasted clip
1189 WaveClipHolders newCutlines;
1190 for (const auto &cutline: newClip->mCutLines)
1191 {
1192 auto cutlineCopy = std::make_shared<WaveClip>(*cutline, factory,
1193 // Recursively copy cutlines of cutlines. They don't need
1194 // their offsets adjusted.
1195 true);
1196 cutlineCopy->ShiftBy(t0 - GetSequenceStartTime());
1197 newCutlines.push_back(std::move(cutlineCopy));
1198 }
1199
1201
1202 // Because newClip was made above as a copy of (a copy of) other
1203 assert(other.NChannels() == newClip->NChannels());
1204 // And other has the same width as this, so this loop is safe
1205 // Assume Strong-guarantee from Sequence::Paste
1206 for (size_t ii = 0, width = NChannels(); ii < width; ++ii)
1207 mSequences[ii]->Paste(s0, newClip->mSequences[ii].get());
1208
1209 // Assume No-fail-guarantee in the remaining
1210
1211 finisher.Commit();
1212 transaction.Commit();
1213 MarkChanged();
1214
1215 const auto sampleTime = 1.0 / GetRate();
1216 const auto timeOffsetInEnvelope =
1218 mEnvelope->PasteEnvelope(
1219 timeOffsetInEnvelope, newClip->mEnvelope.get(), sampleTime);
1220 OffsetCutLines(t0, newClip->GetPlayEndTime() - newClip->GetPlayStartTime());
1221
1222 for (auto &holder : newCutlines)
1223 mCutLines.push_back(std::move(holder));
1224
1225 return true;
1226}
std::vector< WaveClipHolder > WaveClipHolders
Definition: WaveClip.h:45
sampleFormat Stored() const
Definition: SampleFormat.h:91
sampleCount GetSequenceSamplesCount() const
Definition: WaveClip.cpp:1748
double as_double() const
Definition: SampleCount.h:46
void copy(const T *src, T *dst, int32_t n)
Definition: VectorOps.h:40

References sampleCount::as_double(), ClearSequence(), WaveClip::ClearSequenceFinisher::Commit(), staffpad::vo::copy(), factory, GetFactory(), GetPlayEndTime(), GetPlayStartTime(), GetRate(), GetSampleFormats(), GetSequenceEndTime(), GetSequenceSamplesCount(), GetSequenceStartTime(), GetStretchRatio(), MarkChanged(), mClipStretchRatio, mCutLines, mEnvelope, mProjectTempo, mRate, mRawAudioTempo, mSequences, NChannels(), OffsetCutLines(), Paste(), anonymous_namespace{wxCommandTargets.cpp}::scope, SetTrimLeft(), SetTrimRight(), SampleFormats::Stored(), StrongInvariant(), and TimeToSequenceSamples().

Referenced by ExpandCutLine(), and Paste().

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 1533 of file WaveClip.cpp.

1534{
1535 for (auto it = mCutLines.begin(); it != mCutLines.end(); ++it)
1536 {
1537 const auto &cutline = *it;
1538 //std::numeric_limits<double>::epsilon() or (1.0 / static_cast<double>(mRate))?
1539 if (fabs(GetSequenceStartTime() + cutline->GetSequenceStartTime() - cutLinePosition) < 0.0001)
1540 {
1541 mCutLines.erase(it); // deletes cutline!
1542 return true;
1543 }
1544 }
1545
1546 return false;
1547}

References GetSequenceStartTime(), and mCutLines.

Here is the call graph for this function:

◆ RepairChannels()

void WaveClip::RepairChannels ( )

Ensure that all sequences have the same sample count.

Definition at line 918 of file WaveClip.cpp.

919{
920 if (NChannels() < 2)
921 return;
922 // Be sure of consistency of sample counts
923 // We may be here because the drive can't hold another megabyte, but
924 // note that InsertSilence makes silent blocks that don't occupy
925 // space in the database table of blocks.
926 // (However autosave may want to rewrite the document blob, so this solution
927 // may yet not be perfect.)
928 Transaction transaction{ *this };
929 const auto maxSamples = GetNumSamples();
930 for (const auto &pSequence: mSequences) {
931 const auto numSamples = pSequence->GetNumSamples();
932 if (pSequence->GetNumSamples() != maxSamples)
933 pSequence->InsertSilence(numSamples, maxSamples - numSamples);
934 }
935 transaction.Commit();
936}

References GetNumSamples(), mSequences, and NChannels().

Referenced by AssertOrRepairStrongInvariant().

Here is the call graph for this function:
Here is the caller 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 1612 of file WaveClip.cpp.

1613{
1614 // This mutator does not require the strong invariant.
1615
1616 // Note: it is not necessary to do this recursively to cutlines.
1617 // They get resampled as needed when they are expanded.
1618
1619 if (rate == mRate)
1620 return; // Nothing to do
1621
1622 // This function does its own RAII without a Transaction
1623
1624 double factor = (double)rate / (double)mRate;
1625 ::Resample resample(true, factor, factor); // constant rate resampling
1626
1627 const size_t bufsize = 65536;
1628 Floats inBuffer{ bufsize };
1629 Floats outBuffer{ bufsize };
1630 sampleCount pos = 0;
1631 bool error = false;
1632 int outGenerated = 0;
1633 const auto numSamples = GetNumSamples();
1634
1635 // These sequences are appended to below
1636 auto newSequences = GetEmptySequenceCopies();
1637
1643 while (pos < numSamples || outGenerated > 0) {
1644 const auto inLen = limitSampleBufferSize( bufsize, numSamples - pos );
1645
1646 bool isLast = ((pos + inLen) == numSamples);
1647
1648 auto ppNewSequence = newSequences.begin();
1649 std::optional<std::pair<size_t, size_t>> results{};
1650 for (auto &pSequence : mSequences) {
1651 auto &pNewSequence = *ppNewSequence++;
1652 if (!pSequence->Get((samplePtr)inBuffer.get(), floatSample, pos, inLen, true))
1653 {
1654 error = true;
1655 break;
1656 }
1657
1658 // Expect the same results for all channels, or else fail
1659 auto newResults = resample.Process(factor, inBuffer.get(), inLen,
1660 isLast, outBuffer.get(), bufsize);
1661 if (!results)
1662 results.emplace(newResults);
1663 else if (*results != newResults) {
1664 error = true;
1665 break;
1666 }
1667
1668 outGenerated = results->second;
1669 if (outGenerated < 0) {
1670 error = true;
1671 break;
1672 }
1673
1674 pNewSequence->Append((samplePtr)outBuffer.get(), floatSample,
1675 outGenerated, 1,
1676 widestSampleFormat /* computed samples need dither */
1677 );
1678 }
1679 if (results)
1680 pos += results->first;
1681
1682 if (progress)
1683 {
1684 auto updateResult = progress->Poll(
1685 pos.as_long_long(),
1686 numSamples.as_long_long()
1687 );
1688 error = (updateResult != BasicUI::ProgressResult::Success);
1689 if (error)
1690 throw UserException{};
1691 }
1692 }
1693
1694 if (error)
1697 XO("Resampling failed."),
1698 XO("Warning"),
1699 "Error:_Resampling"
1700 };
1701 else
1702 {
1703 // Use No-fail-guarantee in these steps
1704 mSequences = move(newSequences);
1705 mRate = rate;
1706 Flush();
1707 Attachments::ForEach( std::mem_fn( &WaveClipListener::Invalidate ) );
1708 MarkChanged();
1709 }
1710}
@ Internal
Indicates internal failure from Audacity.
XO("Cut/Copy/Paste")
size_t limitSampleBufferSize(size_t bufferSize, sampleCount limit)
Definition: SampleCount.cpp:22
char * samplePtr
Definition: SampleFormat.h:57
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
std::vector< std::unique_ptr< Sequence > > GetEmptySequenceCopies() const
Definition: WaveClip.cpp:719
void Flush()
Flush must be called after last Append.
Definition: WaveClip.cpp:893
virtual void Invalidate()=0

References sampleCount::as_long_long(), floatSample, Flush(), GetEmptySequenceCopies(), GetNumSamples(), Internal, WaveClipListener::Invalidate(), limitSampleBufferSize(), MarkChanged(), 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 1727 of file WaveClip.cpp.

1728{
1729 return s.as_double() * GetStretchRatio() / mRate;
1730}

References GetStretchRatio(), and mRate.

Referenced by SetRate(), and WaveClip().

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

◆ SetCentShift()

bool WaveClip::SetCentShift ( int  cents)

Definition at line 1588 of file WaveClip.cpp.

1589{
1590 if (
1593 return false;
1594 mCentShift = cents;
1596 return true;
1597}
static constexpr auto MaxCents
static constexpr auto MinCents

References TimeAndPitchInterface::MaxCents, mCentShift, TimeAndPitchInterface::MinCents, and Observer::Publisher< Message, NotifyAll >::Publish().

Here is the call graph for this function:

◆ SetEnvelope()

void WaveClip::SetEnvelope ( std::unique_ptr< Envelope p)
Precondition
p

Definition at line 411 of file WaveClip.cpp.

412{
413 assert(p);
414 mEnvelope = move(p);
415}

References mEnvelope.

◆ SetIsPlaceholder()

void WaveClip::SetIsPlaceholder ( bool  val)
inline

Definition at line 773 of file WaveClip.h.

773{ mIsPlaceholder = val; }

◆ SetName()

void WaveClip::SetName ( const wxString &  name)

Definition at line 1712 of file WaveClip.cpp.

1713{
1714 mName = name;
1715}
const TranslatableString name
Definition: Distortion.cpp:76

References mName, and name.

Referenced by HandleXMLTag().

Here is the caller graph for this function:

◆ SetPitchAndSpeedPreset()

void WaveClip::SetPitchAndSpeedPreset ( PitchAndSpeedPreset  preset)

Definition at line 1599 of file WaveClip.cpp.

References mPitchAndSpeedPreset, preset, and Observer::Publisher< Message, NotifyAll >::Publish().

Here is the call graph for this function:

◆ SetPlayStartTime()

void WaveClip::SetPlayStartTime ( double  time)

Definition at line 1758 of file WaveClip.cpp.

1759{
1761}

References mTrimLeft, and SetSequenceStartTime().

Here is the call graph for this function:

◆ SetRate()

void WaveClip::SetRate ( int  rate)

Definition at line 1568 of file WaveClip.cpp.

1569{
1570 const auto trimLeftSampleNum = TimeToSamples(mTrimLeft);
1571 const auto trimRightSampleNum = TimeToSamples(mTrimRight);
1572 auto ratio = static_cast<double>(mRate) / rate;
1573 mRate = rate;
1574 mTrimLeft = SamplesToTime(trimLeftSampleNum);
1575 mTrimRight = SamplesToTime(trimRightSampleNum);
1576 const auto newLength =
1578 mEnvelope->RescaleTimes(newLength);
1579 MarkChanged();
1581}

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

Here is the call graph for this function:

◆ SetRawAudioTempo()

void WaveClip::SetRawAudioTempo ( double  tempo)

Definition at line 1583 of file WaveClip.cpp.

1584{
1585 mRawAudioTempo = tempo;
1586}

References mRawAudioTempo.

◆ SetSamples()

void WaveClip::SetSamples ( size_t  ii,
constSamplePtr  buffer,
sampleFormat  format,
sampleCount  start,
size_t  len,
sampleFormat  effectiveFormat 
)
Parameters
iiidentifies the channel
Precondition
ii < NChannels()
StrongInvariant()
Postcondition
StrongInvariant()
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 397 of file WaveClip.cpp.

400{
401 StrongInvariantScope scope{ *this };
402 assert(ii < NChannels());
403 // use Strong-guarantee
404 mSequences[ii]->SetSamples(buffer, format,
405 start + TimeToSamples(mTrimLeft), len, effectiveFormat);
406
407 // use No-fail-guarantee
408 MarkChanged();
409}

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

Referenced by WaveClipUtilities::SetFloatsFromTime(), and WaveClipChannel::SetSamples().

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 1870 of file WaveClip.cpp.

1871{
1872 mSequenceOffset = startTime;
1873 mEnvelope->SetOffset(startTime);
1874}

References mEnvelope, and mSequenceOffset.

Referenced by ClearLeft(), HandleXMLTag(), SetPlayStartTime(), SetRate(), and ShiftBy().

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)

Precondition
StrongInvariant()
Postcondition
StrongInvariant()

Definition at line 1737 of file WaveClip.cpp.

1738{
1739 StrongInvariantScope scope{ *this };
1740 const auto start = TimeToSamples(mTrimLeft) + offset;
1741 Transaction transaction{ *this };
1742 for (auto &pSequence : mSequences)
1743 pSequence->SetSilence(start, length);
1744 transaction.Commit();
1745 MarkChanged();
1746}

References WaveClip::Transaction::Commit(), MarkChanged(), mSequences, mTrimLeft, anonymous_namespace{wxCommandTargets.cpp}::scope, 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 1801 of file WaveClip.cpp.

1802{
1803 mTrimLeft = std::max(.0, trim);
1804}

References mTrimLeft.

Referenced by Clear(), 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 1811 of file WaveClip.cpp.

1812{
1813 mTrimRight = std::max(.0, trim);
1814}

References mTrimRight.

Referenced by Clear(), ClearRight(), HandleXMLTag(), InsertSilence(), Paste(), and TrimRight().

Here is the caller graph for this function:

◆ ShiftBy()

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

Definition at line 1889 of file WaveClip.cpp.

1890{
1892 MarkChanged();
1893}

References GetSequenceStartTime(), MarkChanged(), and SetSequenceStartTime().

Referenced by Clear(), ClearAndAddCutLine(), WaveTrackShifter::DoHorizontalOffset(), and WaveClip::ClearSequenceFinisher::~ClearSequenceFinisher().

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

◆ SnapToTrackSample()

double WaveClip::SnapToTrackSample ( double  time) const
privatenoexcept

Definition at line 1732 of file WaveClip.cpp.

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

References mRate, and fast_float::round().

Referenced by GetPlayEndTime(), GetPlayStartTime(), TrimLeftTo(), and TrimRightTo().

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

◆ SplitChannels()

std::shared_ptr< WaveClip > WaveClip::SplitChannels ( )

A stereo WaveClip becomes mono, keeping the left side and returning a new clip with the right side samples

Precondition
NChannels() == 2
Postcondition
NChannels() == 1
result: result->NChannels() == 1

Definition at line 480 of file WaveClip.cpp.

481{
482 assert(NChannels() == 2);
483
484 // Make empty copies of this and all cutlines
485 CreateToken token{ true };
486 auto result = std::make_shared<WaveClip>(*this, GetFactory(), true, token);
487
488 // Move one Sequence
489 TransferSequence(*this, *result);
490
491 // Must also do that for cutlines, which must be in correspondence, because
492 // of the post of the constructor.
493 // And possibly too for cutlines inside of cutlines!
494 FixSplitCutlines(mCutLines, result->mCutLines);
495
496 // Fix attachments in the new clip and assert consistency conditions between
497 // the clip and its cutlines
498 result->Attachments::ForEach([](WaveClipListener &attachment){
499 attachment.Erase(0);
500 });
501 assert(result->CheckInvariants());
502
503 // This call asserts invariants for this clip
505
506 // Assert postconditions
507 assert(NChannels() == 1);
508 assert(result->NChannels() == 1);
509 return result;
510}
void DiscardRightChannel()
Reduce width.
Definition: WaveClip.cpp:429

References DiscardRightChannel(), WaveClipListener::Erase(), FixSplitCutlines(), GetFactory(), mCutLines, NChannels(), and TransferSequence().

Here is the call 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 1895 of file WaveClip.cpp.

1896{
1897 return GetPlayStartTime() < t && t < GetPlayEndTime();
1898}

References GetPlayEndTime(), and GetPlayStartTime().

Here is the call graph for this function:

◆ Start()

double WaveClip::Start ( ) const
overridevirtual
Postcondition
result: result < End()

Implements ChannelGroupInterval.

Definition at line 340 of file WaveClip.cpp.

341{
342 return GetPlayStartTime();
343}

References GetPlayStartTime().

Referenced by anonymous_namespace{WaveClipAdjustBorderHandle.cpp}::GetLeftAdjustLimit(), and TimeStretching::SetClipStretchRatio().

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

◆ StretchBy()

void WaveClip::StretchBy ( double  ratio)

Definition at line 599 of file WaveClip.cpp.

600{
601 const auto pst = GetPlayStartTime();
602 mSequenceOffset = pst - mTrimLeft * ratio;
603 mTrimLeft *= ratio;
604 mTrimRight *= ratio;
605 mClipStretchRatio *= ratio;
606 mEnvelope->SetOffset(mSequenceOffset);
607 mEnvelope->RescaleTimesBy(ratio);
608 StretchCutLines(ratio);
611}

References GetPlayStartTime(), GetStretchRatio(), mClipStretchRatio, mEnvelope, mSequenceOffset, mTrimLeft, mTrimRight, Observer::Publisher< Message, NotifyAll >::Publish(), and StretchCutLines().

Referenced by StretchRightTo().

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 613 of file WaveClip.cpp.

614{
615 for (const auto& cutline : mCutLines)
616 {
617 cutline->mSequenceOffset *= ratioChange;
618 cutline->mTrimLeft *= ratioChange;
619 cutline->mTrimRight *= ratioChange;
620 cutline->mClipStretchRatio *= ratioChange;
621 cutline->mEnvelope->RescaleTimesBy(ratioChange);
622 }
623}

References mCutLines.

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

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 569 of file WaveClip.cpp.

570{
571 const auto pet = GetPlayEndTime();
572 if (to >= pet)
573 return;
574 const auto oldPlayDuration = pet - GetPlayStartTime();
575 const auto newPlayDuration = pet - to;
576 const auto ratioChange = newPlayDuration / oldPlayDuration;
577 mSequenceOffset = pet - (pet - mSequenceOffset) * ratioChange;
578 mTrimLeft *= ratioChange;
579 mTrimRight *= ratioChange;
580 mClipStretchRatio *= ratioChange;
581 mEnvelope->SetOffset(mSequenceOffset);
582 mEnvelope->RescaleTimesBy(ratioChange);
583 StretchCutLines(ratioChange);
586}

References GetPlayEndTime(), GetPlayStartTime(), GetStretchRatio(), mClipStretchRatio, mEnvelope, mSequenceOffset, mTrimLeft, mTrimRight, Observer::Publisher< Message, NotifyAll >::Publish(), and StretchCutLines().

Referenced by anonymous_namespace{WaveClipAdjustBorderHandle.cpp}::StretchLeftTo().

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

◆ StretchRatioEquals()

bool WaveClip::StretchRatioEquals ( double  value) const
private

Definition at line 672 of file WaveClip.cpp.

673{
675 1 + GetStretchRatio() - value);
676}
static bool IsPassThroughMode(double stretchRatio)

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

Referenced by HasEqualPitchAndSpeed(), and HasPitchOrSpeed().

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 588 of file WaveClip.cpp.

589{
590 const auto pst = GetPlayStartTime();
591 if (to <= pst)
592 return;
593 const auto oldPlayDuration = GetPlayEndTime() - pst;
594 const auto newPlayDuration = to - pst;
595 const auto ratioChange = newPlayDuration / oldPlayDuration;
596 StretchBy(ratioChange);
597}
void StretchBy(double ratio)
Definition: WaveClip.cpp:599

References GetPlayEndTime(), GetPlayStartTime(), and StretchBy().

Referenced by WaveTrackUtilities::ExpandClipTillNextOne(), TimeStretching::SetClipStretchRatio(), and anonymous_namespace{WaveClipAdjustBorderHandle.cpp}::StretchRightTo().

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

◆ StrongInvariant()

bool WaveClip::StrongInvariant ( ) const

A precondition for some mutating operations CheckInvariants() is true, and also all sequences have the same length

Definition at line 2004 of file WaveClip.cpp.

2005{
2006 if (!CheckInvariants())
2007 return false;
2008 const auto width = NChannels();
2009 auto iter = mSequences.begin(),
2010 end = mSequences.end();
2011 assert(iter != end); // because CheckInvariants is true
2012 auto &pFirst = *iter++;
2013 assert(pFirst); // likewise
2014 // All sequences must have the same lengths
2015 return all_of(iter, end, [&](decltype(pFirst) pSequence) {
2016 assert(pSequence); // likewise
2017 return pSequence->GetNumSamples() == pFirst->GetNumSamples();
2018 });
2019 return false;
2020}

References CheckInvariants(), details::end(), mSequences, and NChannels().

Referenced by AssertOrRepairStrongInvariant(), MakeStereo(), and Paste().

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

◆ SubscribeToCentShiftChange()

Observer::Subscription WaveClip::SubscribeToCentShiftChange ( std::function< void(int)>  cb) const
overridevirtual

Implements ClipInterface.

Definition at line 640 of file WaveClip.cpp.

641{
642 // Consider the list of subcribers as a mutable member that doesn't change
643 // real state
644 return const_cast<WaveClip*>(this)->
646 [cb](const CentShiftChange& cents) { cb(cents.newValue); });
647}
An object that sends messages to an open-ended list of subscribed callbacks.
Definition: Observer.h:108
const int newValue
Definition: WaveClip.h:203

References CentShiftChange::newValue.

◆ SubscribeToPitchAndSpeedPresetChange()

Observer::Subscription WaveClip::SubscribeToPitchAndSpeedPresetChange ( std::function< void(PitchAndSpeedPreset)>  cb) const
overridevirtual

Implements ClipInterface.

Definition at line 649 of file WaveClip.cpp.

651{
652 // Consider the list of subcribers as a mutable member that doesn't change
653 // real state
654 return const_cast<WaveClip*>(this)->
656 [cb](const PitchAndSpeedPresetChange& formant) {
657 cb(formant.newValue);
658 });
659}
const PitchAndSpeedPreset newValue
Definition: WaveClip.h:212

References PitchAndSpeedPresetChange::newValue.

◆ SwapChannels()

void WaveClip::SwapChannels ( )
Precondition
NChannels() == 2

Definition at line 441 of file WaveClip.cpp.

442{
443 assert(NChannels() == 2);
444 this->Attachments::ForEach([](WaveClipListener &attachment){
445 attachment.SwapChannels();
446 });
448 for (auto &pCutline : mCutLines)
449 pCutline->SwapChannels();
450 assert(CheckInvariants());
451}
void swap(std::unique_ptr< Alg_seq > &a, std::unique_ptr< Alg_seq > &b)
Definition: NoteTrack.cpp:628
virtual void SwapChannels()
Default implementation does nothing.
Definition: WaveClip.cpp:54

References CheckInvariants(), mCutLines, mSequences, NChannels(), anonymous_namespace{NoteTrack.cpp}::swap(), and WaveClipListener::SwapChannels().

Here is the call graph for this function:

◆ TimeToSamples()

sampleCount WaveClip::TimeToSamples ( double  time) const
overridevirtual

Implements ClipTimes.

Definition at line 1722 of file WaveClip.cpp.

1723{
1724 return sampleCount(floor(time * mRate / GetStretchRatio() + 0.5));
1725}

References GetStretchRatio(), and mRate.

Referenced by CountSamples(), WaveClipUtilities::GetFloatAtTime(), GetSamples(), GetSampleView(), GetSequenceStartSample(), GetVisibleSampleCount(), InsertSilence(), WaveClipUtilities::SetFloatsFromTime(), SetRate(), SetSamples(), SetSilence(), WaveClipChannel::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 1961 of file WaveClip.cpp.

1962{
1963 if (t < GetSequenceStartTime())
1964 return 0;
1965 else if (t > GetSequenceEndTime())
1966 return GetNumSamples();
1967 return TimeToSamples(t - GetSequenceStartTime());
1968}

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

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

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

◆ TransferSequence()

void WaveClip::TransferSequence ( WaveClip origClip,
WaveClip newClip 
)
staticprivate

Definition at line 453 of file WaveClip.cpp.

454{
455 // Move right channel into result
456 newClip.mSequences.resize(1);
457 newClip.mSequences[0] = move(origClip.mSequences[1]);
458 // Delayed satisfaction of the class invariants after the empty construction
459 newClip.CheckInvariants();
460}

References CheckInvariants(), and mSequences.

Referenced by FixSplitCutlines(), and SplitChannels().

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 1821 of file WaveClip.cpp.

1822{
1823 SetTrimLeft(mTrimLeft + deltaTime);
1824}

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 1850 of file WaveClip.cpp.

1851{
1852 mTrimLeft =
1855}

References GetPlayEndTime(), mSequenceOffset, mTrimLeft, and SnapToTrackSample().

Referenced by anonymous_namespace{WaveClipAdjustBorderHandle.cpp}::TrimLeftTo().

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

◆ TrimQuarternotesFromRight()

void WaveClip::TrimQuarternotesFromRight ( double  quarters)

Same as TrimRight, but expressed as quarter notes.

Definition at line 1831 of file WaveClip.cpp.

1832{
1833 assert(mRawAudioTempo.has_value());
1834 if (!mRawAudioTempo.has_value())
1835 return;
1836 const auto secondsPerQuarter = 60 * GetStretchRatio() / *mRawAudioTempo;
1837 // MH https://github.com/audacity/audacity/issues/5878: Clip boundaries are
1838 // quantized to the sample period. Music durations aren't, though.
1839 // `quarters` was probably chosen such that the clip ends exactly at some
1840 // musical grid snapping point. However, if we right-trim by `quarters`,
1841 // the clip's play end time might be rounded up to the next sample period,
1842 // overlapping the next snapping point on the musical grid. We don't want
1843 // this, or it would disturb music producers who want to horizontally
1844 // duplicate loops.
1845 const auto quantizedTrim =
1846 std::ceil(quarters * secondsPerQuarter * GetRate()) / GetRate();
1847 TrimRight(quantizedTrim);
1848}
void TrimRight(double deltaTime)
Moves play end position by deltaTime.
Definition: WaveClip.cpp:1826

References GetRate(), GetStretchRatio(), mRawAudioTempo, and TrimRight().

Here is the call graph for this function:

◆ TrimRight()

void WaveClip::TrimRight ( double  deltaTime)

Moves play end position by deltaTime.

Definition at line 1826 of file WaveClip.cpp.

1827{
1828 SetTrimRight(mTrimRight + deltaTime);
1829}

References mTrimRight, and SetTrimRight().

Referenced by TrimQuarternotesFromRight().

Here is the call graph for this function:
Here is the caller 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 1857 of file WaveClip.cpp.

1858{
1859 const auto endTime = SnapToTrackSample(GetSequenceEndTime());
1860 mTrimRight = endTime - std::clamp(to, GetPlayStartTime(), endTime);
1861}

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

Referenced by anonymous_namespace{WaveClipAdjustBorderHandle.cpp}::TrimRightTo().

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 807 of file WaveClip.cpp.

808{
809 // The envelope time points account for stretching.
810 const auto len = GetNumSamples().as_double() * GetStretchRatio() / mRate;
811 if (len != mEnvelope->GetTrackLen())
812 mEnvelope->SetTrackLen(len, 1.0 / GetRate());
813}

References sampleCount::as_double(), GetNumSamples(), GetRate(), GetStretchRatio(), 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 1900 of file WaveClip.cpp.

1901{
1902 return GetPlayStartTime() <= t && t < GetPlayEndTime();
1903}

References GetPlayEndTime(), and GetPlayStartTime().

Referenced by WaveClipUtilities::GetFloatAtTime(), PartlyWithinPlayRegion(), and WaveClipChannel::WithinPlayRegion().

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

◆ WriteXML()

void WaveClip::WriteXML ( size_t  ii,
XMLWriter xmlFile 
) const

Wave clip data has always been written by channel-major iteration and is still done so for compatibility. Therefore, the first argument.

Parameters
iiidentifies the channel
Precondition
ii < NChannels()

Definition at line 1066 of file WaveClip.cpp.

1068{
1069 assert(ii < NChannels());
1070
1071 if (GetSequenceSamplesCount() <= 0)
1072 // Oops, I'm empty? How did that happen? Anyway, I do nothing but causing
1073 // problems, don't save me.
1074 return;
1075
1076 xmlFile.StartTag(WaveClip_tag);
1078 xmlFile.WriteAttr(TrimLeft_attr, mTrimLeft, 8);
1079 xmlFile.WriteAttr(TrimRight_attr, mTrimRight, 8);
1082 static_cast<long>(mPitchAndSpeedPreset));
1083 xmlFile.WriteAttr(RawAudioTempo_attr, mRawAudioTempo.value_or(0.), 8);
1085 xmlFile.WriteAttr(Name_attr, mName);
1086 Attachments::ForEach([&](const WaveClipListener &listener){
1087 listener.WriteXMLAttributes(xmlFile);
1088 });
1089
1090 mSequences[ii]->WriteXML(xmlFile);
1091 mEnvelope->WriteXML(xmlFile);
1092
1093 for (const auto &clip: mCutLines)
1094 clip->WriteXML(ii, xmlFile);
1095
1096 xmlFile.EndTag(WaveClip_tag);
1097}
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
virtual void WriteXMLAttributes(XMLWriter &writer) const
Definition: WaveClip.cpp:40

References CentShiftAttr, ClipStretchRatio_attr, WaveTrackUtilities::GetSequenceSamplesCount(), Name_attr, Offset_attr, PitchAndSpeedPreset_attr, RawAudioTempo_attr, TrimLeft_attr, TrimRight_attr, and WaveClipListener::WriteXMLAttributes().

Referenced by WaveClipChannel::WriteXML().

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

Member Data Documentation

◆ mCentShift

int WaveClip::mCentShift { 0 }
private

Definition at line 950 of file WaveClip.h.

Referenced by GetCentShift(), HandleXMLTag(), and SetCentShift().

◆ mClipStretchRatio

double WaveClip::mClipStretchRatio = 1.
private

Definition at line 954 of file WaveClip.h.

Referenced by GetStretchRatio(), HandleXMLTag(), Paste(), StretchBy(), and StretchLeftTo().

◆ 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 973 of file WaveClip.h.

Referenced by AddCutLine(), CheckInvariants(), ClearAndAddCutLine(), CloseLock(), DiscardRightChannel(), ExpandCutLine(), FindCutLine(), HandleXMLChild(), MakeStereo(), OffsetCutLines(), Paste(), RemoveCutLine(), SplitChannels(), StretchCutLines(), SwapChannels(), WaveClip(), and WaveClip::ClearSequenceFinisher::~ClearSequenceFinisher().

◆ mEnvelope

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

Envelope is unique, not per-sequence, and always non-null.

Definition at line 966 of file WaveClip.h.

Referenced by HandleXMLChild(), OnProjectTempoChange(), Paste(), SetEnvelope(), SetRate(), SetSequenceStartTime(), StretchBy(), StretchLeftTo(), UpdateEnvelopeTrackLen(), and WaveClip().

◆ mIsPlaceholder

bool WaveClip::mIsPlaceholder { false }
private

Definition at line 976 of file WaveClip.h.

Referenced by WaveClip().

◆ mName

wxString WaveClip::mName
private

Definition at line 978 of file WaveClip.h.

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

◆ mPitchAndSpeedPreset

PitchAndSpeedPreset WaveClip::mPitchAndSpeedPreset { PitchAndSpeedPreset::Default }
private

Definition at line 949 of file WaveClip.h.

Referenced by GetPitchAndSpeedPreset(), HandleXMLTag(), and SetPitchAndSpeedPreset().

◆ mProjectTempo

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

Definition at line 956 of file WaveClip.h.

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

◆ mRate

int WaveClip::mRate
private

◆ mRawAudioTempo

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

◆ mSequenceOffset

double WaveClip::mSequenceOffset { 0 }
private

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

Definition at line 944 of file WaveClip.h.

Referenced by GetPlayEndTime(), GetPlayStartTime(), GetSequenceStartSample(), GetSequenceStartTime(), OnProjectTempoChange(), SetSequenceStartTime(), StretchBy(), StretchLeftTo(), 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

◆ WaveClip_tag

const char * WaveClip::WaveClip_tag = "waveclip"
static

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