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

A Track that contains audio waveform data. More...

#include <WaveTrack.h>

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

Classes

struct  CreateToken
 
struct  Region
 Structure to hold region of a wavetrack and a comparison function for sortability. More...
 

Public Types

using Interval = WaveClip
 
using IntervalHolder = std::shared_ptr< Interval >
 
using IntervalHolders = std::vector< IntervalHolder >
 
using IntervalConstHolder = std::shared_ptr< const Interval >
 
using IntervalConstHolders = std::vector< IntervalConstHolder >
 
using Regions = std::vector< Region >
 
using Holder = std::shared_ptr< WaveTrack >
 
- Public Types inherited from Track
using AttachedObjects = ::AttachedTrackObjects
 Alias for my base type. More...
 
using Holder = std::shared_ptr< Track >
 
- Public Types inherited from ClientData::Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy >
using DataType = ClientData
 
using DataPointer = Pointer< ClientData >
 
using DataFactory = std::function< DataPointer(Host &) >
 Type of function from which RegisteredFactory is constructed; it builds attachments. More...
 
- Public Types inherited from ChannelGroup
enum class  LinkType : int { None = 0 , Group = 2 , Aligned }
 For two tracks describes the type of the linkage. More...
 
using Attachments = ChannelGroupAttachments
 
using Interval = WideChannelGroupInterval
 
- Public Types inherited from Observer::Publisher< WaveTrackMessage >
using message_type = WaveTrackMessage
 
using CallbackReturn = std::conditional_t< true, void, bool >
 
using Callback = std::function< CallbackReturn(const WaveTrackMessage &) >
 Type of functions that can be connected to the Publisher. More...
 

Public Member Functions

 WaveTrack (CreateToken &&, const SampleBlockFactoryPtr &pFactory, sampleFormat format, double rate)
 Don't call directly, but use Create. More...
 
const SampleBlockFactoryPtrGetSampleBlockFactory () const
 
size_t NChannels () const override
 A constant property. More...
 
auto GetChannel (size_t iChannel)
 
auto GetChannel (size_t iChannel) const
 
auto Channels ()
 
auto Channels () const
 
AudioGraph::ChannelType GetChannelType () const override
 Classify this channel. More...
 
void Init (const WaveTrack &orig)
 
virtual ~WaveTrack ()
 
void MoveTo (double o) override
 
bool LinkConsistencyFix (bool doFix) override
 Check consistency of channel groups, and maybe fix it. More...
 
double GetStartTime () const override
 Implement WideSampleSequence. More...
 
double GetEndTime () const override
 Implement WideSampleSequence. More...
 
double GetRate () const override
 
void SetRate (double newRate)
 !brief Sets the new rate for the track without resampling it More...
 
float GetGain () const
 
void SetGain (float newGain)
 
float GetPan () const
 
void SetPan (float newPan)
 
float GetChannelGain (int channel) const override
 Takes gain and pan into account. More...
 
sampleCount GetVisibleSampleCount () const
 
sampleFormat GetSampleFormat () const override
 
void ConvertToSampleFormat (sampleFormat format, const std::function< void(size_t)> &progressReport={})
 
Track::Holder Cut (double t0, double t1) override
 Create tracks and modify this track. More...
 
Holder EmptyCopy (size_t nChannels, const SampleBlockFactoryPtr &pFactory={}) const
 
Holder EmptyCopy (const SampleBlockFactoryPtr &pFactory={}) const
 
void MakeMono ()
 Simply discard any right channel. More...
 
Holder MonoToStereo ()
 
std::vector< HolderSplitChannels ()
 
void SwapChannels ()
 
Track::Holder Copy (double t0, double t1, bool forClipboard=true) const override
 Create new tracks and don't modify this track. More...
 
void Clear (double t0, double t1) override
 
void Paste (double t0, const Track &src) override
 
void ClearAndPaste (double t0, double t1, const WaveTrack &src, bool preserve=true, bool merge=true, const TimeWarper *effectWarper=nullptr, bool clearByTrimming=false)
 
void Silence (double t0, double t1, ProgressReporter reportProgress) override
 
void InsertSilence (double t, double len) override
 
void Split (double t0, double t1)
 
std::pair< IntervalHolder, IntervalHolderSplitAt (double t)
 
void ClearAndAddCutLine (double t0, double t1)
 
Holder SplitCut (double t0, double t1)
 
void SplitDelete (double t0, double t1)
 
void Join (double t0, double t1, const ProgressReporter &reportProgress)
 
void Disjoin (double t0, double t1)
 
void Trim (double t0, double t1)
 
void ApplyPitchAndSpeed (std::optional< TimeInterval > interval, ProgressReporter reportProgress)
 
void SyncLockAdjust (double oldT1, double newT1) override
 
bool IsEmpty (double t0, double t1) const
 Returns true if there are no WaveClips in the specified region. More...
 
bool Append (size_t iChannel, constSamplePtr buffer, sampleFormat format, size_t len, unsigned int stride=1, sampleFormat effectiveFormat=widestSampleFormat) override
 
void Flush () override
 
void RepairChannels () override
 
bool DoGet (size_t iChannel, size_t nBuffers, const samplePtr buffers[], sampleFormat format, sampleCount start, size_t len, bool backwards, fillFormat fill=FillFormat::fillZero, bool mayThrow=true, sampleCount *pNumWithinClips=nullptr) const override
 This fails if any clip overlapping the range has non-unit stretch ratio! More...
 
ChannelGroupSampleView GetSampleView (double t0, double t1, bool mayThrow=true) const
 Request samples within [t0, t1), not knowing in advance how many this will be. More...
 
sampleFormat WidestEffectiveFormat () const override
 
bool HasTrivialEnvelope () const override
 
void GetEnvelopeValues (double *buffer, size_t bufferLen, double t0, bool backwards) const override
 
size_t GetBestBlockSize (sampleCount t) const
 
size_t GetMaxBlockSize () const
 
size_t GetIdealBlockSize ()
 
bool HandleXMLTag (const std::string_view &tag, const AttributesList &attrs) override
 
void HandleXMLEndTag (const std::string_view &tag) override
 
XMLTagHandlerHandleXMLChild (const std::string_view &tag) override
 
void WriteXML (XMLWriter &xmlFile) const override
 
std::optional< TranslatableStringGetErrorOpening () const override
 
IntervalHolder GetLeftmostClip ()
 
IntervalConstHolder GetLeftmostClip () const
 
IntervalHolder GetRightmostClip ()
 
IntervalConstHolder GetRightmostClip () const
 
ClipConstHolders GetClipInterfaces () const
 Get access to the (visible) clips in the tracks, in unspecified order. More...
 
IntervalHolder CreateClip (double offset=.0, const wxString &name=wxEmptyString, const Interval *pToCopy=nullptr, bool copyCutlines=true)
 
IntervalHolder CopyClip (const Interval &toCopy, bool copyCutlines)
 Create new clip and add it to this track. More...
 
IntervalHolder NewestOrNewClip ()
 Get access to the most recently added clip, or create a clip, if there is not already one. THIS IS NOT NECESSARILY RIGHTMOST. More...
 
IntervalHolder RightmostOrNewClip ()
 Get access to the last (rightmost) clip, or create a clip, if there is not already one. More...
 
int GetNumClips () const
 
IntervalHolders SortedIntervalArray ()
 Return all WaveClips sorted by clip play start time. More...
 
IntervalConstHolders SortedIntervalArray () const
 Return all WaveClips sorted by clip play start time. More...
 
bool CanOffsetClips (const std::vector< Interval * > &movingClips, double amount, double *allowedAmount=nullptr)
 Decide whether the clips could be offset (and inserted) together without overlapping other clips. More...
 
bool CanInsertClip (const Interval &clip, double &slideBy, double tolerance) const
 
bool MergeClips (int clipidx1, int clipidx2)
 
void Resample (int rate, BasicUI::ProgressDialog *progress=NULL)
 
bool SetFloats (const float *const *buffers, sampleCount start, size_t len, sampleFormat effectiveFormat=widestSampleFormat)
 Random-access assignment of a range of samples. More...
 
const TypeInfoGetTypeInfo () const override
 
IntervalConstHolder GetNextInterval (const Interval &interval, PlaybackDirection searchDirection) const
 
IntervalHolder GetNextInterval (const Interval &interval, PlaybackDirection searchDirection)
 
IntervalHolder GetIntervalAtTime (double t)
 
auto Intervals ()
 
auto Intervals () const
 
void InsertInterval (const IntervalHolder &interval, bool newClip, bool allowEmpty=false)
 
void RemoveInterval (const IntervalHolder &interval)
 
Track::Holder PasteInto (AudacityProject &project, TrackList &list) const override
 
bool HasClipNamed (const wxString &name) const
 
size_t NIntervals () const override
 Report the number of intervals. More...
 
IntervalHolder GetClip (size_t iInterval)
 
IntervalConstHolder GetClip (size_t iInterval) const
 used only during deserialization More...
 
void SetLegacyFormat (sampleFormat format)
 
int GetClipIndex (const Interval &clip) const
 Get the linear index of a given clip (== number of clips if not found) More...
 
void ZipClips (bool mustAlign=true)
 
virtual void Paste (double t, const Track &src)=0
 Weak precondition allows overrides to replicate one channel into many. More...
 
PlayableSequence implementation
const ChannelGroupFindChannelGroup () const override
 Find associated ChannelGroup if any. More...
 
bool GetMute () const override
 May vary asynchronously. More...
 
bool GetSolo () const override
 May vary asynchronously. More...
 
- Public Member Functions inherited from WritableSampleTrack
 WritableSampleTrack ()
 
 WritableSampleTrack (const WritableSampleTrack &other, ProtectedCreationArg &&)
 
 ~WritableSampleTrack () override
 
const TypeInfoGetTypeInfo () const override
 
virtual size_t NChannels () const=0
 Report the number of channels. More...
 
virtual double GetRate () const=0
 
- Public Member Functions inherited from SampleTrack
 SampleTrack ()
 
 SampleTrack (const SampleTrack &other, ProtectedCreationArg &&)
 
 ~SampleTrack () override
 
const TypeInfoGetTypeInfo () const override
 
virtual sampleFormat GetSampleFormat () const =0
 
double GetStartTime () const
 Get the minimum of Start() values of intervals, or 0 when none. More...
 
double GetEndTime () const
 Get the maximum of End() values of intervals, or 0 when none. More...
 
bool GetFloats (size_t iChannel, size_t nBuffers, float *const buffers[], sampleCount start, size_t len, bool backwards=false, fillFormat fill=FillFormat::fillZero, bool mayThrow=true, sampleCount *pNumWithinClips=nullptr) const
 
- Public Member Functions inherited from PlayableTrack
 PlayableTrack ()
 
 PlayableTrack (const PlayableTrack &orig, ProtectedCreationArg &&)
 
bool GetMute () const
 
bool GetSolo () const
 
bool GetNotMute () const
 
bool GetNotSolo () const
 
void SetMute (bool m)
 
void SetSolo (bool s)
 
void WriteXMLAttributes (XMLWriter &xmlFile) const
 
bool HandleXMLAttribute (const std::string_view &attr, const XMLAttributeValueView &value)
 
- Public Member Functions inherited from AudioTrack
 AudioTrack ()
 
 AudioTrack (const Track &orig, ProtectedCreationArg &&a)
 
void WriteXMLAttributes (XMLWriter &WXUNUSED(xmlFile)) const
 
bool HandleXMLAttribute (const std::string_view &, const XMLAttributeValueView &)
 
- Public Member Functions inherited from Track
TrackId GetId () const
 
template<typename Subclass = Track>
std::shared_ptr< Subclass > SharedPointer ()
 
template<typename Subclass = const Track>
auto SharedPointer () const -> std::enable_if_t< std::is_const_v< Subclass >, std::shared_ptr< Subclass > >
 
virtual const TypeInfoGetTypeInfo () const =0
 
virtual const TypeNamesGetTypeNames () const
 
virtual bool SupportsBasicEditing () const
 Whether this track type implements cut-copy-paste; by default, true. More...
 
virtual Holder PasteInto (AudacityProject &project, TrackList &list) const =0
 
virtual bool LinkConsistencyFix (bool doFix=true)
 Check consistency of channel groups, and maybe fix it. More...
 
bool LinkConsistencyCheck ()
 Do the non-mutating part of consistency fix only and return status. More...
 
bool HasOwner () const
 
std::shared_ptr< TrackListGetOwner () const
 
LinkType GetLinkType () const noexcept
 
 Track ()
 
 Track (const Track &orig, ProtectedCreationArg &&)
 
Trackoperator= (const Track &orig)=delete
 
virtual ~Track ()
 
void Init (const Track &orig)
 
virtual Holder Duplicate (DuplicateOptions={}) const
 public nonvirtual duplication function that invokes Clone() More...
 
void ReparentAllAttachments ()
 
const wxString & GetName () const
 Name is always the same for all channels of a group. More...
 
void SetName (const wxString &n)
 
bool GetSelected () const
 Selectedness is always the same for all channels of a group. More...
 
virtual void SetSelected (bool s)
 
virtual Holder Cut (double t0, double t1)=0
 Create tracks and modify this track. More...
 
virtual Holder Copy (double t0, double t1, bool forClipboard=true) const =0
 Create new tracks and don't modify this track. More...
 
virtual void Clear (double t0, double t1)=0
 
virtual void Paste (double t, const Track &src)=0
 Weak precondition allows overrides to replicate one channel into many. More...
 
virtual void SyncLockAdjust (double oldT1, double newT1)
 
virtual void Silence (double t0, double t1, ProgressReporter reportProgress={})=0
 
virtual void InsertSilence (double t, double len)=0
 
bool SameKindAs (const Track &track) const
 
template<typename R = void, typename ... Functions>
TypeSwitch (const Functions &...functions)
 
template<typename R = void, typename ... Functions>
TypeSwitch (const Functions &...functions) const
 
virtual void WriteXML (XMLWriter &xmlFile) const =0
 
virtual std::optional< TranslatableStringGetErrorOpening () const
 
void Notify (bool allChannels, int code=-1)
 
bool Any () const
 
bool IsSelected () const
 
bool IsLeader () const
 
void AdjustPositions ()
 
void WriteCommonXMLAttributes (XMLWriter &xmlFile, bool includeNameAndSelected=true) const
 
bool HandleCommonXMLAttribute (const std::string_view &attr, const XMLAttributeValueView &valueView)
 
- 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< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy >
 ~Site ()
 
 Site ()
 
 Site (const Site &other)
 
Siteoperator= (const Site &other)
 
 Site (Site &&other)
 
Siteoperator= (Site &&other)
 
size_t size () const
 How many attachment pointers are in the Site. More...
 
template<typename Subclass = ClientData>
Subclass & Get (const RegisteredFactory &key)
 Get reference to an attachment, creating on demand if not present, down-cast it to Subclass. More...
 
template<typename Subclass = const ClientData>
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...
 
template<typename Subclass = ClientData>
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...
 
template<typename Subclass = const ClientData>
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...
 
template<typename ReplacementPointer >
void Assign (const RegisteredFactory &key, ReplacementPointer &&replacement)
 Reassign Site's pointer to ClientData. More...
 
- Public Member Functions inherited from ChannelGroup
virtual ~ChannelGroup ()
 
double GetStartTime () const
 Get the minimum of Start() values of intervals, or 0 when none. More...
 
double GetEndTime () const
 Get the maximum of End() values of intervals, or 0 when none. More...
 
void ShiftBy (double t)
 Change start time by given duration. More...
 
virtual void MoveTo (double o)=0
 Change start time to given time point. More...
 
template<typename ChannelType = Channel>
std::shared_ptr< ChannelType > GetChannel (size_t iChannel)
 Retrieve a channel, cast to the given type. More...
 
template<typename ChannelType = const Channel>
auto GetChannel (size_t iChannel) const -> std::enable_if_t< std::is_const_v< ChannelType >, std::shared_ptr< ChannelType > >
 
template<typename ChannelType = Channel>
IteratorRange< ChannelIterator< ChannelType > > Channels ()
 Get range of channels with mutative access. More...
 
template<typename ChannelType = const Channel>
auto Channels () const -> std::enable_if_t< std::is_const_v< ChannelType >, IteratorRange< ChannelIterator< ChannelType > > >
 Get range of channels with read-only access. More...
 
std::shared_ptr< ChannelNthChannel (size_t nChannel)
 
std::shared_ptr< const ChannelNthChannel (size_t nChannel) const
 
template<typename IntervalType = Interval>
std::shared_ptr< IntervalType > GetInterval (size_t iInterval)
 Retrieve an interval, cast to the given type. More...
 
template<typename IntervalType = const Interval>
auto GetInterval (size_t iInterval) const -> std::enable_if_t< std::is_const_v< IntervalType >, std::shared_ptr< IntervalType > >
 
template<typename IntervalType = Interval>
IteratorRange< IntervalIterator< IntervalType > > Intervals ()
 Get range of intervals with mutative access. More...
 
template<typename IntervalType = const Interval>
auto Intervals () const -> std::enable_if_t< std::is_const_v< IntervalType >, IteratorRange< IntervalIterator< IntervalType > > >
 Get range of intervals with read-only access. More...
 
- Public Member Functions inherited from PlayableSequence
 ~PlayableSequence () override
 
virtual const ChannelGroupFindChannelGroup () const =0
 Find associated ChannelGroup if any. More...
 
virtual bool GetSolo () const =0
 May vary asynchronously. More...
 
virtual bool GetMute () const =0
 May vary asynchronously. More...
 
- Public Member Functions inherited from WideSampleSequence
virtual ~WideSampleSequence ()
 
virtual size_t NChannels () const =0
 A constant property. More...
 
virtual float GetChannelGain (int channel) const =0
 
bool GetFloats (size_t iChannel, size_t nBuffers, float *const buffers[], sampleCount start, size_t len, bool backwards=false, fillFormat fill=FillFormat::fillZero, bool mayThrow=true, sampleCount *pNumWithinClips=nullptr) const
 
virtual bool DoGet (size_t iChannel, size_t nBuffers, const samplePtr buffers[], sampleFormat format, sampleCount start, size_t len, bool backward, fillFormat fill=FillFormat::fillZero, bool mayThrow=true, sampleCount *pNumWithinClips=nullptr) const =0
 
virtual double GetStartTime () const =0
 
virtual double GetEndTime () const =0
 
virtual double GetRate () const =0
 
sampleCount TimeToLongSamples (double t0) const
 
double LongSamplesToTime (sampleCount pos) const
 
double SnapToSample (double t) const
 
virtual sampleFormat WidestEffectiveFormat () const =0
 
virtual bool HasTrivialEnvelope () const =0
 
virtual void GetEnvelopeValues (double *buffer, size_t bufferLen, double t0, bool backwards) const =0
 
- Public Member Functions inherited from AudioGraph::Channel
virtual ~Channel ()
 
virtual ChannelType GetChannelType () const =0
 Classify this channel. More...
 
- Public Member Functions inherited from RecordableSequence
virtual ~RecordableSequence ()
 
virtual sampleFormat GetSampleFormat () const =0
 
virtual double GetRate () const =0
 
virtual size_t NChannels () const =0
 A constant property. More...
 
virtual bool Append (size_t iChannel, constSamplePtr buffer, sampleFormat format, size_t len, unsigned int stride, sampleFormat effectiveFormat)=0
 Append the sample data to the track. You must call Flush() after the last Append. More...
 
virtual void Flush ()=0
 Flush must be called after last Append. More...
 
virtual void RepairChannels ()=0
 
virtual void InsertSilence (double t, double len)=0
 
- Public Member Functions inherited from Observer::Publisher< WaveTrackMessage >
 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 Member Functions

static wxString GetDefaultAudioTrackNamePreference ()
 
static double ProjectNyquistFrequency (const AudacityProject &project)
 
static WaveTrackNew (AudacityProject &project)
 
static Holder Create (const SampleBlockFactoryPtr &pFactory, sampleFormat format, double rate)
 Factory builds all AttachedTrackObjects. More...
 
static const TypeInfoClassTypeInfo ()
 
- Static Public Member Functions inherited from WritableSampleTrack
static const TypeInfoClassTypeInfo ()
 
- Static Public Member Functions inherited from SampleTrack
static const TypeInfoClassTypeInfo ()
 
- Static Public Member Functions inherited from PlayableTrack
static const TypeInfoClassTypeInfo ()
 
- Static Public Member Functions inherited from AudioTrack
static const TypeInfoClassTypeInfo ()
 
- Static Public Member Functions inherited from Track
template<typename Subclass = Track>
static std::shared_ptr< Subclass > SharedPointer (Track *pTrack)
 
template<typename Subclass = const Track>
static std::shared_ptr< Subclass > SharedPointer (const Track *pTrack)
 
static const TypeInfoClassTypeInfo ()
 
static void CopyAttachments (Track &dst, const Track &src, bool deep)
 Copy (deep) or just share (!deep) AttachedTrackObjects. More...
 
- Static Public Member Functions inherited from ClientData::Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy >
static size_t numFactories ()
 How many static factories have been registered with this specialization of Site. More...
 

Static Public Attributes

static const char * WaveTrack_tag = "wavetrack"
 
- Static Public Attributes inherited from Observer::Publisher< WaveTrackMessage >
static constexpr bool notifies_all
 

Private Member Functions

std::ptrdiff_t FindClip (const Interval &clip)
 
void RemoveClip (std::ptrdiff_t distance)
 
Track::Holder Clone (bool backup) const override
 
wxString MakeClipCopyName (const wxString &originalName) const
 
wxString MakeNewClipName () const
 
void CopyWholeClip (const Interval &clip, double t0, bool forClipboard)
 
void CopyPartOfClip (const Interval &clip, double t0, double t1, bool forClipboard)
 
void FinishCopy (double t0, double t1, double endTime, bool forClipboard)
 
IntervalConstHolders SortedClipArray () const
 Return all WaveClips sorted by clip play start time. More...
 
IntervalConstHolder GetClipAtTime (double time) const
 
void CreateRight ()
 
WaveClipHolder DoCreateClip (double offset=.0, const wxString &name=wxEmptyString) const
 Create a new clip that can be inserted later into the track. More...
 
bool InsertClip (WaveClipHolders &clips, WaveClipHolder clip, bool newClip, bool backup, bool allowEmpty)
 
void CopyClips (WaveClipHolders &clips, SampleBlockFactoryPtr pFactory, const WaveClipHolders &orig, bool backup)
 
void MergeChannelAttachments (WaveTrack &&other)
 
void EraseChannelAttachments (size_t index)
 Erase all attachments for a given index. More...
 
void HandleClear (double t0, double t1, bool addCutLines, bool split, bool clearByTrimming=false)
 
void ClearAndPasteAtSameTempo (double t0, double t1, const WaveTrack &src, bool preserve, bool merge, const TimeWarper *effectWarper, bool clearByTrimming)
 
void ExpandOneCutLine (double cutLinePosition, double *cutlineStart, double *cutlineEnd)
 
void ApplyPitchAndSpeedOnIntervals (const std::vector< IntervalHolder > &intervals, const ProgressReporter &reportProgress)
 
void ReplaceInterval (const IntervalHolder &oldOne, const IntervalHolder &newOne)
 
std::shared_ptr< WideChannelGroupIntervalDoGetInterval (size_t iInterval) override
 Retrieve an interval. More...
 
std::shared_ptr<::ChannelDoGetChannel (size_t iChannel) override
 
WaveClipHoldersNarrowClips ()
 
const WaveClipHoldersNarrowClips () const
 
void DoSetRate (double newRate)
 
Holder DuplicateWithOtherTempo (double newTempo) const
 
bool GetOne (const WaveClipHolders &clips, size_t iChannel, samplePtr buffer, sampleFormat format, sampleCount start, size_t len, bool backwards, fillFormat fill, bool mayThrow, sampleCount *pNumWithinClips) const
 
void DoSetPan (float value)
 
void DoSetGain (float value)
 
void PasteWaveTrack (double t0, const WaveTrack &other, bool merge)
 
void PasteWaveTrackAtSameTempo (double t0, const WaveTrack &other, bool merge)
 
bool RateConsistencyCheck () const
 Whether all clips of an unzipped leader track have a common rate. More...
 
bool FormatConsistencyCheck () const
 
void ApplyPitchAndSpeedOne (double t0, double t1, const ProgressReporter &reportProgress)
 

Static Private Member Functions

static void JoinOne (WaveTrack &track, double t0, double t1)
 
static void WriteOneXML (const WaveChannel &channel, XMLWriter &xmlFile, size_t iChannel, size_t nChannels)
 

Private Attributes

WaveChannel mChannel
 
std::optional< WaveChannelmRightChannel
 may be null More...
 
WaveClipHolders mClips
 
int mLegacyRate { 0 }
 used only during deserialization More...
 
sampleFormat mLegacyFormat { undefinedSample }
 used only during deserialization More...
 
SampleBlockFactoryPtr mpFactory
 
wxCriticalSection mFlushCriticalSection
 
wxCriticalSection mAppendCriticalSection
 
double mLegacyProjectFileOffset { 0 }
 
friend WaveChannel
 

Friends

class WaveTrackFactory
 

Additional Inherited Members

- Protected Member Functions inherited from PlayableTrack
bool DoGetMute () const
 
void DoSetMute (bool value)
 
bool DoGetSolo () const
 
void DoSetSolo (bool value)
 
- Protected Member Functions inherited from Track
void SetLinkType (LinkType linkType, bool completeList=true)
 
- Protected Member Functions inherited from ClientData::Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy >
template<typename Function >
void ForEach (const Function &function)
 Invoke function on each ClientData object that has been created in this. More...
 
template<typename Function >
void ForEach (const Function &function) const
 Invoke function on each ClientData object that has been created in this. More...
 
template<typename Function >
void ForCorresponding (Site &other, const Function &function, bool create=true)
 
template<typename Function >
ClientData * FindIf (const Function &function)
 Return pointer to first attachment in this that is not null and satisfies a predicate, or nullptr. More...
 
template<typename Function >
const ClientData * FindIf (const Function &function) const
 Return pointer to first attachment in this that is not null and satisfies a predicate, or nullptr. More...
 
template<typename Function >
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...
 
virtual std::shared_ptr< ChannelDoGetChannel (size_t iChannel)=0
 
virtual std::shared_ptr< IntervalDoGetInterval (size_t iInterval)=0
 Retrieve an interval. More...
 
- Protected Member Functions inherited from Observer::Publisher< WaveTrackMessage >
CallbackReturn Publish (const WaveTrackMessage &message)
 Send a message to connected callbacks. More...
 
- Protected Attributes inherited from Track
std::weak_ptr< TrackListmList
 
TrackNodePointer mNode {}
 Holds iterator to self, so that TrackList::Find can be constant-time. More...
 

Detailed Description

A Track that contains audio waveform data.

Definition at line 200 of file WaveTrack.h.

Member Typedef Documentation

◆ Holder

using WaveTrack::Holder = std::shared_ptr<WaveTrack>

Definition at line 247 of file WaveTrack.h.

◆ Interval

Definition at line 208 of file WaveTrack.h.

◆ IntervalConstHolder

using WaveTrack::IntervalConstHolder = std::shared_ptr<const Interval>

Definition at line 211 of file WaveTrack.h.

◆ IntervalConstHolders

Definition at line 212 of file WaveTrack.h.

◆ IntervalHolder

using WaveTrack::IntervalHolder = std::shared_ptr<Interval>

Definition at line 209 of file WaveTrack.h.

◆ IntervalHolders

Definition at line 210 of file WaveTrack.h.

◆ Regions

using WaveTrack::Regions = std::vector < Region >

Definition at line 230 of file WaveTrack.h.

Constructor & Destructor Documentation

◆ WaveTrack()

WaveTrack::WaveTrack ( CreateToken &&  ,
const SampleBlockFactoryPtr pFactory,
sampleFormat  format,
double  rate 
)

Don't call directly, but use Create.

Definition at line 496 of file WaveTrack.cpp.

498 : mpFactory(pFactory)
499 , mChannel(*this)
500{
501 WaveTrackData::Get(*this).SetSampleFormat(format);
502 DoSetRate(static_cast<int>(rate));
503}
SampleBlockFactoryPtr mpFactory
Definition: WaveTrack.h:829
WaveChannel mChannel
Definition: WaveTrack.h:767
void DoSetRate(double newRate)
Definition: WaveTrack.cpp:813
Services * Get()
Fetch the global instance, or nullptr if none is yet installed.
Definition: BasicUI.cpp:202

References DoSetRate(), anonymous_namespace{ExportPCM.cpp}::format, and BasicUI::Get().

Here is the call graph for this function:

◆ ~WaveTrack()

WaveTrack::~WaveTrack ( )
virtual

Definition at line 561 of file WaveTrack.cpp.

562{
563}

Member Function Documentation

◆ Append()

bool WaveTrack::Append ( size_t  iChannel,
constSamplePtr  buffer,
sampleFormat  format,
size_t  len,
unsigned int  stride = 1,
sampleFormat  effectiveFormat = widestSampleFormat 
)
overridevirtual

If there is an existing WaveClip in the WaveTrack, then the data are appended to that clip. If there are no WaveClips in the track, then a new one is created.

Precondition
iChannel < NChannels()
Returns
true if at least one complete block was created
Exception safety guarantee:
Partial – Some prefix (maybe none) of the buffer is appended, and no content already flushed to disk is lost.

Implements RecordableSequence.

Definition at line 2227 of file WaveTrack.cpp.

2230{
2231 assert(iChannel < NChannels());
2232 auto pTrack = this;
2233 constSamplePtr buffers[]{ buffer };
2234 auto pClip = RightmostOrNewClip();
2235 return pClip->Append(iChannel, 1,
2236 buffers, format, len, stride, effectiveFormat);
2237}
const char * constSamplePtr
Definition: SampleFormat.h:58
IntervalHolder RightmostOrNewClip()
Get access to the last (rightmost) clip, or create a clip, if there is not already one.
Definition: WaveTrack.cpp:2990
size_t NChannels() const override
A constant property.
Definition: WaveTrack.cpp:532

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

Referenced by WaveChannel::Append(), and WaveChannel::AppendBuffer().

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

◆ ApplyPitchAndSpeed()

void WaveTrack::ApplyPitchAndSpeed ( std::optional< TimeInterval interval,
ProgressReporter  reportProgress 
)

Definition at line 1924 of file WaveTrack.cpp.

1926{
1927 // Assert that the interval is reasonable, but this function will be no-op
1928 // anyway if not
1929 assert(!interval.has_value() ||
1930 interval->first <= interval->second);
1931 if (GetNumClips() == 0)
1932 return;
1933 const auto startTime =
1934 interval ? std::max(SnapToSample(interval->first), GetStartTime()) :
1935 GetStartTime();
1936 const auto endTime =
1937 interval ? std::min(SnapToSample(interval->second), GetEndTime()) :
1938 GetEndTime();
1939 if (startTime >= endTime)
1940 return;
1941
1942 // Here we assume that left- and right clips are aligned.
1943 if (auto clipAtT0 = GetClipAtTime(startTime);
1944 clipAtT0 && clipAtT0->SplitsPlayRegion(startTime) &&
1945 clipAtT0->HasPitchOrSpeed())
1946 Split(startTime, startTime);
1947 if (auto clipAtT1 = GetClipAtTime(endTime);
1948 clipAtT1 && clipAtT1->SplitsPlayRegion(endTime) &&
1949 clipAtT1->HasPitchOrSpeed())
1950 Split(endTime, endTime);
1951
1952 IntervalHolders srcIntervals;
1953 auto clip = GetIntervalAtTime(startTime);
1954 while (clip && clip->GetPlayStartTime() < endTime)
1955 {
1956 if (clip->HasPitchOrSpeed())
1957 srcIntervals.push_back(clip);
1959 }
1960
1961 ApplyPitchAndSpeedOnIntervals(srcIntervals, reportProgress);
1962}
int min(int a, int b)
double GetStartTime() const override
Implement WideSampleSequence.
Definition: WaveTrack.cpp:2576
void ApplyPitchAndSpeedOnIntervals(const std::vector< IntervalHolder > &intervals, const ProgressReporter &reportProgress)
Definition: WaveTrack.cpp:3180
IntervalConstHolder GetNextInterval(const Interval &interval, PlaybackDirection searchDirection) const
Definition: WaveTrack.cpp:175
IntervalConstHolder GetClipAtTime(double time) const
Definition: WaveTrack.cpp:2924
void Split(double t0, double t1)
Definition: WaveTrack.cpp:3130
std::vector< IntervalHolder > IntervalHolders
Definition: WaveTrack.h:210
double GetEndTime() const override
Implement WideSampleSequence.
Definition: WaveTrack.cpp:2586
int GetNumClips() const
Definition: WaveTrack.cpp:3022
IntervalHolder GetIntervalAtTime(double t)
Definition: WaveTrack.cpp:203
double SnapToSample(double t) const

References ApplyPitchAndSpeedOnIntervals(), forward, GetClipAtTime(), GetEndTime(), GetIntervalAtTime(), GetNextInterval(), GetNumClips(), GetStartTime(), min(), WideSampleSequence::SnapToSample(), and Split().

Referenced by Silence().

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

◆ ApplyPitchAndSpeedOne()

void WaveTrack::ApplyPitchAndSpeedOne ( double  t0,
double  t1,
const ProgressReporter reportProgress 
)
private

◆ ApplyPitchAndSpeedOnIntervals()

void WaveTrack::ApplyPitchAndSpeedOnIntervals ( const std::vector< IntervalHolder > &  intervals,
const ProgressReporter reportProgress 
)
private

Definition at line 3180 of file WaveTrack.cpp.

3183{
3184 IntervalHolders dstIntervals;
3185 dstIntervals.reserve(srcIntervals.size());
3186 std::transform(
3187 srcIntervals.begin(), srcIntervals.end(),
3188 std::back_inserter(dstIntervals), [&](const IntervalHolder& interval) {
3189 return GetRenderedCopy(interval,
3190 reportProgress, mpFactory, GetSampleFormat());
3191 });
3192
3193 // If we reach this point it means that no error was thrown - we can replace
3194 // the source with the destination intervals.
3195 for (auto i = 0; i < srcIntervals.size(); ++i)
3196 ReplaceInterval(srcIntervals[i], dstIntervals[i]);
3197}
std::shared_ptr< Interval > IntervalHolder
Definition: WaveTrack.h:209
void ReplaceInterval(const IntervalHolder &oldOne, const IntervalHolder &newOne)
Definition: WaveTrack.cpp:3227

References ReplaceInterval().

Referenced by ApplyPitchAndSpeed(), and Join().

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

◆ CanInsertClip()

bool WaveTrack::CanInsertClip ( const Interval clip,
double &  slideBy,
double  tolerance 
) const

Definition at line 3086 of file WaveTrack.cpp.

3088{
3089 const auto &clips = Intervals();
3090 if (clips.empty())
3091 return true;
3092 // Find clip in this that overlaps most with `clip`:
3093 const auto candidateClipStartTime = candidateClip.GetPlayStartTime();
3094 const auto candidateClipEndTime = candidateClip.GetPlayEndTime();
3095 const auto t0 = SnapToSample(candidateClipStartTime + slideBy);
3096 const auto t1 = SnapToSample(candidateClipEndTime + slideBy);
3097 std::vector<double> overlaps;
3098 std::transform(
3099 clips.begin(), clips.end(), std::back_inserter(overlaps),
3100 [&](const auto& pClip) {
3101 return pClip->IntersectsPlayRegion(t0, t1) ?
3102 std::min(pClip->GetPlayEndTime(), t1) -
3103 std::max(pClip->GetPlayStartTime(), t0) :
3104 0.0;
3105 });
3106 const auto maxOverlap = std::max_element(overlaps.begin(), overlaps.end());
3107 if (*maxOverlap > tolerance)
3108 return false;
3109 auto iter = clips.begin();
3110 std::advance(iter, std::distance(overlaps.begin(), maxOverlap));
3111 const auto overlappedClip = *iter;
3112 const auto requiredOffset = slideBy +
3113 *maxOverlap * (overlappedClip->GetPlayStartTime() < t0 ? 1 : -1);
3114 // Brute-force check to see if there's another clip that'd be in the way.
3115 if (std::any_of(
3116 clips.begin(), clips.end(),
3117 [&](const auto& pClip)
3118 {
3119 const auto result = pClip->IntersectsPlayRegion(
3120 SnapToSample(candidateClipStartTime + requiredOffset),
3121 SnapToSample(candidateClipEndTime + requiredOffset));
3122 return result;
3123 }))
3124 return false;
3125 slideBy = requiredOffset;
3126 return true;
3127}
auto Intervals()
Definition: WaveTrack.h:670

References Intervals(), and WideSampleSequence::SnapToSample().

Here is the call graph for this function:

◆ CanOffsetClips()

bool WaveTrack::CanOffsetClips ( const std::vector< Interval * > &  movingClips,
double  amount,
double *  allowedAmount = nullptr 
)

Decide whether the clips could be offset (and inserted) together without overlapping other clips.

Returns
true if possible to offset by (allowedAmount ? *allowedAmount : amount)
Parameters
movingClipsnot necessarily in this track
amountsigned
[out]allowedAmountif null, test exact amount only; else, largest (in magnitude) possible offset with same sign

Definition at line 3027 of file WaveTrack.cpp.

3031{
3032 if (allowedAmount)
3033 *allowedAmount = amount;
3034
3035 const auto &moving = [&](Interval *clip){
3036 // linear search might be improved, but expecting few moving clips
3037 // compared with the fixed clips
3038 return movingClips.end() !=
3039 std::find(movingClips.begin(), movingClips.end(), clip);
3040 };
3041
3042 for (const auto &c: Intervals()) {
3043 if ( moving( c.get() ) )
3044 continue;
3045 for (const auto clip : movingClips) {
3046 if (c->GetPlayStartTime() < clip->GetPlayEndTime() + amount &&
3047 c->GetPlayEndTime() > clip->GetPlayStartTime() + amount)
3048 {
3049 if (!allowedAmount)
3050 return false; // clips overlap
3051
3052 if (amount > 0)
3053 {
3054 if (c->GetPlayStartTime() - clip->GetPlayEndTime() < *allowedAmount)
3055 *allowedAmount = c->GetPlayStartTime() - clip->GetPlayEndTime();
3056 if (*allowedAmount < 0)
3057 *allowedAmount = 0;
3058 } else
3059 {
3060 if (c->GetPlayEndTime() - clip->GetPlayStartTime() > *allowedAmount)
3061 *allowedAmount = c->GetPlayEndTime() - clip->GetPlayStartTime();
3062 if (*allowedAmount > 0)
3063 *allowedAmount = 0;
3064 }
3065 }
3066 }
3067 }
3068
3069 if (allowedAmount)
3070 {
3071 if (*allowedAmount == amount)
3072 return true;
3073
3074 // Check if the NEW calculated amount would not violate
3075 // any other constraint
3076 if (!CanOffsetClips(movingClips, *allowedAmount, nullptr)) {
3077 *allowedAmount = 0; // play safe and don't allow anything
3078 return false;
3079 }
3080 else
3081 return true;
3082 } else
3083 return true;
3084}
WaveClip Interval
Definition: WaveTrack.h:208
bool CanOffsetClips(const std::vector< Interval * > &movingClips, double amount, double *allowedAmount=nullptr)
Decide whether the clips could be offset (and inserted) together without overlapping other clips.
Definition: WaveTrack.cpp:3027

References CanOffsetClips(), and Intervals().

Referenced by CanOffsetClips().

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

◆ Channels() [1/2]

auto WaveTrack::Channels ( )
inline

◆ Channels() [2/2]

auto WaveTrack::Channels ( ) const
inline

Definition at line 265 of file WaveTrack.h.

265 {
266 return this->ChannelGroup::Channels<const WaveChannel>(); }

◆ ClassTypeInfo()

auto WaveTrack::ClassTypeInfo ( )
static

Definition at line 672 of file WaveTrack.cpp.

673{
674 return typeInfo();
675}
static const Track::TypeInfo & typeInfo()
Definition: WaveTrack.cpp:659

References typeInfo().

Here is the call graph for this function:

◆ Clear()

void WaveTrack::Clear ( double  t0,
double  t1 
)
overridevirtual
Exception safety guarantee:
Strong

Implements Track.

Definition at line 1138 of file WaveTrack.cpp.

1139{
1140 HandleClear(t0, t1, false, false);
1141}
void HandleClear(double t0, double t1, bool addCutLines, bool split, bool clearByTrimming=false)
Definition: WaveTrack.cpp:1527

References HandleClear().

Referenced by Cut(), EffectTruncSilence::DoRemoval(), anonymous_namespace{LabelMenus.cpp}::OnCutLabels(), TrackSpectrumTransformer::PostProcess(), EffectStereoToMono::ProcessOne(), SyncLockAdjust(), and Trim().

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

◆ ClearAndAddCutLine()

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

May assume precondition: t0 <= t1

Exception safety guarantee:
Strong

Definition at line 1144 of file WaveTrack.cpp.

1145{
1146 HandleClear(t0, t1, true, false);
1147}

References HandleClear().

Referenced by anonymous_namespace{LabelMenus.cpp}::OnCutLabels().

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

◆ ClearAndPaste()

void WaveTrack::ClearAndPaste ( double  t0,
double  t1,
const WaveTrack src,
bool  preserve = true,
bool  merge = true,
const TimeWarper effectWarper = nullptr,
bool  clearByTrimming = false 
)

May assume precondition: t0 <= t1 If the source has one channel and this has more, then replicate source

Precondition
src.NChannels() == 1 || src.NChannels() == NChannels()
Exception safety guarantee:
Weak – This WaveTrack remains destructible in case of AudacityException. But some of its cutline clips may have been destroyed.

Definition at line 1196 of file WaveTrack.cpp.

1204{
1205 // Get a modifiable copy of `src` because it may come from another project
1206 // with different tempo, making boundary queries incorrect.
1207 const auto& tempo = GetProjectTempo(*this);
1208 if (!tempo.has_value())
1210 const auto copyHolder = src.DuplicateWithOtherTempo(*tempo);
1212 t0, t1, *copyHolder, preserve, merge, effectWarper, clearByTrimming);
1213}
#define THROW_INCONSISTENCY_EXCEPTION
Throw InconsistencyException, using C++ preprocessor to identify the source code location.
const std::optional< double > & GetProjectTempo(const ChannelGroup &group)
Definition: TempoChange.cpp:48
Holder DuplicateWithOtherTempo(double newTempo) const
Definition: WaveTrack.cpp:575
void ClearAndPasteAtSameTempo(double t0, double t1, const WaveTrack &src, bool preserve, bool merge, const TimeWarper *effectWarper, bool clearByTrimming)
Definition: WaveTrack.cpp:1215

References ClearAndPasteAtSameTempo(), DuplicateWithOtherTempo(), GetProjectTempo(), and THROW_INCONSISTENCY_EXCEPTION.

Referenced by EffectSBSMS::Finalize(), anonymous_namespace{EditMenus.cpp}::OnPaste(), and PerTrackEffect::ProcessPass().

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

◆ ClearAndPasteAtSameTempo()

void WaveTrack::ClearAndPasteAtSameTempo ( double  t0,
double  t1,
const WaveTrack src,
bool  preserve,
bool  merge,
const TimeWarper effectWarper,
bool  clearByTrimming 
)
private

Definition at line 1215 of file WaveTrack.cpp.

1218{
1219 const auto srcNChannels = src.NChannels();
1220 assert(srcNChannels == NChannels());
1221 assert(
1222 GetProjectTempo(*this).has_value() &&
1223 GetProjectTempo(*this) == GetProjectTempo(src));
1224
1225 t0 = SnapToSample(t0);
1226 t1 = SnapToSample(t1);
1227
1228 const auto endTime = src.GetEndTime();
1229 double dur = std::min(t1 - t0, endTime);
1230
1231 // If duration is 0, then it's just a plain paste
1232 if (dur == 0.0) {
1233 // use Weak-guarantee
1234 PasteWaveTrack(t0, src, merge);
1235 return;
1236 }
1237
1238 auto &track = *this;
1239
1240 std::vector<SplitInfo> splits;
1241 IntervalHolders cuts;
1242
1243 //helper routine, that finds SplitInfo by time value,
1244 //or creates a new one if no one exists yet
1245 auto get_split = [&](double time) {
1246 auto it = std::find_if(splits.begin(), splits.end(),
1247 [time](const SplitInfo& split) { return split.time == time; });
1248 if(it == splits.end())
1249 it = splits.insert(
1250 splits.end(),
1251 { time, nullptr, nullptr, std::nullopt, std::nullopt }
1252 );
1253 return it;
1254 };
1255
1256 // If provided time warper was NULL, use a default one that does nothing
1257 IdentityTimeWarper localWarper;
1258 const TimeWarper *warper = (effectWarper ? effectWarper : &localWarper);
1259
1260 const auto roundTime = [&track](double t){
1261 return track.SnapToSample(t);
1262 };
1263
1264 // Align to a sample
1265 t0 = roundTime(t0);
1266 t1 = roundTime(t1);
1267
1268 // Save the cut/split lines whether preserving or not since merging
1269 // needs to know if a clip boundary is being crossed since Paste()
1270 // will add split lines around the pasted clip if so.
1271 for (const auto &&clip : track.Intervals()) {
1272 double st;
1273
1274 // Remember clip boundaries as locations to split
1275 // we need to copy clips, trims and names, because the original ones
1276 // could be changed later during Clear/Paste routines
1277 st = roundTime(clip->GetPlayStartTime());
1278 if (st >= t0 && st <= t1) {
1279 auto it = get_split(st);
1280 if (clip->GetTrimLeft() != 0) {
1281 //keep only hidden left part
1282 it->right = track.CopyClip(*clip, false);
1283 it->right->SetTrimLeft(.0);
1284 it->right->ClearRight(clip->GetPlayStartTime());
1285 }
1286 it->rightClipName = clip->GetName();
1287 }
1288
1289 st = roundTime(clip->GetPlayEndTime());
1290 if (st >= t0 && st <= t1) {
1291 auto it = get_split(st);
1292 if (clip->GetTrimRight() != 0) {
1293 //keep only hidden right part
1294 it->left = track.CopyClip(*clip, false);
1295 it->left->SetTrimRight(.0);
1296 it->left->ClearLeft(clip->GetPlayEndTime());
1297 }
1298 it->leftClipName = clip->GetName();
1299 }
1300
1301 // Search for cut lines
1302 auto cutlines = clip->GetCutLines();
1303 for (auto &cut : cutlines) {
1304 const auto unrounded =
1305 clip->GetSequenceStartTime() + cut->GetSequenceStartTime();
1306 const double cs = roundTime(unrounded);
1307
1308 // Remember cut point
1309 if (cs >= t0 && cs <= t1) {
1310 // Remember the absolute offset and add to our cuts array.
1311 cut->SetSequenceStartTime(cs);
1312 bool removed = clip->RemoveCutLine(unrounded);
1313 assert(removed);
1314 cuts.push_back(move(cut));
1315 }
1316 }
1317 }
1318
1319 const auto tolerance = 2.0 / track.GetRate();
1320
1321 // This is not a split-cut operation.
1322 constexpr auto split = false;
1323
1324 // Now, clear the selection
1325 track.HandleClear(t0, t1, false, split, clearByTrimming);
1326
1327 // And paste in the new data
1328 track.PasteWaveTrackAtSameTempo(t0, src, merge);
1329
1330 // First, merge the new clip(s) in with the existing clips
1331 if (merge && splits.size() > 0) {
1332 {
1333 // Now t1 represents the absolute end of the pasted data.
1334 t1 = t0 + endTime;
1335
1336 // Get a sorted array of the clips
1337 auto clips = track.SortedIntervalArray();
1338
1339 // Scan the sorted clips for the first clip whose start time
1340 // exceeds the pasted regions end time.
1341 IntervalHolder prev;
1342 for (const auto clip : clips) {
1343 // Merge this clip and the previous clip if the end time
1344 // falls within it and this isn't the first clip in the track.
1345 if (fabs(t1 - clip->GetPlayStartTime()) < tolerance) {
1346 if (prev && clip->HasEqualPitchAndSpeed(*prev))
1347 track.MergeClips(
1348 track.GetClipIndex(*prev), track.GetClipIndex(*clip));
1349 break;
1350 }
1351 prev = clip;
1352 }
1353 }
1354
1355 {
1356 // Refill the array since clips have changed.
1357 auto clips = track.SortedIntervalArray();
1358
1359 // Scan the sorted clips to look for the start of the pasted
1360 // region.
1361 IntervalHolder prev;
1362 for (const auto clip : clips) {
1363 if (prev) {
1364 // It must be that clip is what was pasted and it begins where
1365 // prev ends.
1366 // use Weak-guarantee
1367 if (clip->HasEqualPitchAndSpeed(*prev))
1368 track.MergeClips(
1369 track.GetClipIndex(*prev), track.GetClipIndex(*clip));
1370 break;
1371 }
1372 if (fabs(t0 - clip->GetPlayEndTime()) < tolerance)
1373 // Merge this clip and the next clip if the start time
1374 // falls within it and this isn't the last clip in the track.
1375 prev = clip;
1376 else
1377 prev = nullptr;
1378 }
1379 }
1380 }
1381
1382 // Restore cut/split lines
1383 if (preserve) {
1384 auto attachLeft = [](Interval& target, Interval& src) {
1385 // What this lambda does is restoring the left hidden data of `target`
1386 // that was cleared by `HandleClear`. Hence, `target` has no left
1387 // hidden data at this stage.
1388 assert(target.GetTrimLeft() == 0);
1389 if (target.GetTrimLeft() != 0)
1390 return;
1391
1392 // `src` was created by copy from `target`, so they have equal width,
1393 // pitch and speed.
1394 assert(target.NChannels() == src.NChannels());
1395 assert(target.HasEqualPitchAndSpeed(src));
1396
1397 auto trim = src.GetPlayEndTime() - src.GetPlayStartTime();
1398 auto success = target.Paste(target.GetPlayStartTime(), src);
1399 assert(success); // because of precondition above
1400 target.SetTrimLeft(trim);
1401 //Play start time needs to be adjusted after
1402 //prepending data to the sequence
1403 target.ShiftBy(-trim);
1404 };
1405
1406 auto attachRight = [](Interval &target, Interval &src)
1407 {
1408 // See `attachLeft` for rationale behind these asserts.
1409 assert(target.GetTrimRight() == 0);
1410 if (target.GetTrimRight() != 0)
1411 return;
1412 assert(target.NChannels() == src.NChannels());
1413 assert(target.HasEqualPitchAndSpeed(src));
1414
1415 auto trim = src.GetPlayEndTime() - src.GetPlayStartTime();
1416 auto success = target.Paste(target.GetPlayEndTime(), src);
1417 assert(success); // because of precondition above
1418 target.SetTrimRight(trim);
1419 };
1420
1421 // Restore the split lines and trims, transforming the position appropriately
1422 for (const auto& split: splits) {
1423 auto at = roundTime(warper->Warp(split.time));
1424 for (const auto &&clip : track.Intervals()) {
1425 // Clips in split began as copies of a clip in the track,
1426 // therefore have the same width, satisfying preconditions to
1427 // attach
1428 if (clip->SplitsPlayRegion(at))//strictly inside
1429 {
1430 auto newClip = CopyClip(*clip, true);
1431 clip->ClearRight(at);
1432 newClip->ClearLeft(at);
1433 if (split.left)
1434 // clip was cleared right
1435 attachRight(*clip, *split.left);
1436 if (split.right)
1437 // new clip was cleared left
1438 attachLeft(*newClip, *split.right);
1439 track.InsertInterval(move(newClip), false);
1440 break;
1441 }
1442 else if (clip->GetPlayStartSample() ==
1443 track.TimeToLongSamples(at) && split.right) {
1444 // Satisfy the precondition of attachLeft first!
1445 const auto trim = clip->GetTrimLeft();
1446 const auto seqStartTime = clip->GetSequenceStartTime();
1447 clip->Clear(seqStartTime, seqStartTime + trim);
1448 // This clearing, although only removing the hidden part, moved
1449 // the clip leftwards. We don't want this in this case.
1450 clip->ShiftBy(trim);
1451 attachLeft(*clip, *split.right);
1452 break;
1453 }
1454 else if (clip->GetPlayEndSample() ==
1455 track.TimeToLongSamples(at) && split.left) {
1456 // Satisfy the precondition of attachRight first!
1457 clip->Clear(
1458 clip->GetPlayEndTime(), clip->GetSequenceEndTime());
1459 attachRight(*clip, *split.left);
1460 break;
1461 }
1462 }
1463 }
1464
1465 //Restore clip names
1466 for (const auto& split : splits)
1467 {
1468 auto s = track.TimeToLongSamples(warper->Warp(split.time));
1469 for (auto &&clip : track.Intervals()) {
1470 if (split.rightClipName.has_value() && clip->GetPlayStartSample() == s)
1471 clip->SetName(*split.rightClipName);
1472 else if (split.leftClipName.has_value() && clip->GetPlayEndSample() == s)
1473 clip->SetName(*split.leftClipName);
1474 }
1475 }
1476
1477 // Restore the saved cut lines, also transforming if time altered
1478 for (const auto &&clip : track.Intervals()) {
1479 const double st = clip->GetPlayStartTime();
1480 const double et = clip->GetPlayEndTime();
1481
1482 // Scan the cuts for any that live within this clip
1483 for (auto &cut : cuts) {
1484 if (!cut)
1485 continue;
1486
1487 //cutlines in this array were orphaned previously
1488 double cs = cut->GetSequenceStartTime();
1489
1490 // Offset the cut from the start of the clip and add it to
1491 // this clips cutlines.
1492 if (cs >= st && cs <= et) {
1493 cut->SetSequenceStartTime(warper->Warp(cs) - st);
1494 clip->AddCutLine(cut);
1495 cut = {};
1496 }
1497 }
1498 }
1499 }
1500}
No change to time at all.
Definition: TimeWarper.h:69
Transforms one point in time to another point. For example, a time stretching effect might use one to...
Definition: TimeWarper.h:62
virtual double Warp(double originalTime) const =0
void Paste(double t0, const Track &src) override
Definition: WaveTrack.cpp:1965
IntervalHolder CopyClip(const Interval &toCopy, bool copyCutlines)
Create new clip and add it to this track.
Definition: WaveTrack.cpp:2948
void PasteWaveTrack(double t0, const WaveTrack &other, bool merge)
Definition: WaveTrack.cpp:1686

References CopyClip(), GetEndTime(), GetProjectTempo(), min(), WideChannelGroupInterval::NChannels(), NChannels(), PasteWaveTrack(), WideSampleSequence::SnapToSample(), and TimeWarper::Warp().

Referenced by ClearAndPaste().

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

◆ Clone()

Track::Holder WaveTrack::Clone ( bool  backup) const
overrideprivatevirtual

Subclass responsibility implements only a part of Duplicate(), copying the track data proper (not associated data such as for groups and views) including TrackId

Parameters
backupwhether the duplication is for backup purposes while opening a project, instead of other editing operations
Postcondition
result tracks have same TrackIds as the channels of this

Implements Track.

Definition at line 761 of file WaveTrack.cpp.

762{
763 auto newTrack = EmptyCopy(NChannels());
764 newTrack->CopyClips(newTrack->mClips,
765 newTrack->mpFactory, this->mClips, backup);
766 return newTrack;
767}
Holder EmptyCopy(size_t nChannels, const SampleBlockFactoryPtr &pFactory={}) const
Definition: WaveTrack.cpp:989

References EmptyCopy(), and NChannels().

Here is the call graph for this function:

◆ ConvertToSampleFormat()

void WaveTrack::ConvertToSampleFormat ( sampleFormat  format,
const std::function< void(size_t)> &  progressReport = {} 
)
Exception safety guarantee:
Weak – Might complete on only some clips

Definition at line 901 of file WaveTrack.cpp.

903{
904 for (const auto &pClip : Intervals())
905 pClip->ConvertToSampleFormat(format, progressReport);
906 WaveTrackData::Get(*this).SetSampleFormat(format);
907}

References anonymous_namespace{ExportPCM.cpp}::format, BasicUI::Get(), and Intervals().

Here is the call graph for this function:

◆ Copy()

Track::Holder WaveTrack::Copy ( double  t0,
double  t1,
bool  forClipboard = true 
) const
overridevirtual

Create new tracks and don't modify this track.

Returns
non-NULL or else throw Note that subclasses may want to distinguish tracks stored in a clipboard from those stored in a project May assume precondition: t0 <= t1 Should invoke Track::Init

Implements Track.

Definition at line 1073 of file WaveTrack.cpp.

1074{
1075 if (t1 < t0)
1077
1078 auto newTrack = EmptyCopy(NChannels());
1079 const auto endTime = std::max(GetEndTime(), t1);
1080 for (const auto pClip : Intervals()) {
1081 // PRL: Why shouldn't cutlines be copied and pasted too? I don't know,
1082 // but that was the old behavior. But this function is also used by the
1083 // Duplicate command and I changed its behavior in that case.
1084 if (pClip->IsEmpty())
1085 continue;
1086 else if (t0 <= pClip->GetPlayStartTime() && t1 >= pClip->GetPlayEndTime())
1087 {
1088 newTrack->CopyWholeClip(*pClip, t0, forClipboard);
1089 }
1090 else if (pClip->CountSamples(t0, t1) >= 1) {
1091 newTrack->CopyPartOfClip(*pClip, t0, t1, forClipboard);
1092 }
1093 }
1094 newTrack->FinishCopy(t0, t1, endTime, forClipboard);
1095 return newTrack;
1096}

References EmptyCopy(), GetEndTime(), Intervals(), NChannels(), and THROW_INCONSISTENCY_EXCEPTION.

Referenced by Cut(), anonymous_namespace{LabelMenus.cpp}::OnCopyLabels(), anonymous_namespace{LabelMenus.cpp}::OnCutLabels(), anonymous_namespace{EditMenus.cpp}::OnSplitCut(), and anonymous_namespace{EditMenus.cpp}::OnSplitNew().

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

◆ CopyClip()

auto WaveTrack::CopyClip ( const Interval toCopy,
bool  copyCutlines 
)

Create new clip and add it to this track.

Returns a pointer to the newly created clip, using this track's block factory but copying all else from the given clip, except possibly the cutlines.

Definition at line 2948 of file WaveTrack.cpp.

2950{
2951 return CreateClip(toCopy.GetSequenceStartTime(),
2952 toCopy.GetName(), &toCopy, copyCutlines);
2953}
IntervalHolder CreateClip(double offset=.0, const wxString &name=wxEmptyString, const Interval *pToCopy=nullptr, bool copyCutlines=true)
Definition: WaveTrack.cpp:2934

Referenced by ClearAndPasteAtSameTempo(), and HandleClear().

Here is the caller graph for this function:

◆ CopyClips()

void WaveTrack::CopyClips ( WaveClipHolders clips,
SampleBlockFactoryPtr  pFactory,
const WaveClipHolders orig,
bool  backup 
)
private

Definition at line 518 of file WaveTrack.cpp.

520{
521 for (const auto &clip : orig)
522 InsertClip(clips,
523 std::make_shared<WaveClip>(*clip, pFactory, true),
524 false, backup, false);
525}
bool InsertClip(WaveClipHolders &clips, WaveClipHolder clip, bool newClip, bool backup, bool allowEmpty)
Definition: WaveTrack.cpp:1908

References InsertClip().

Here is the call graph for this function:

◆ CopyPartOfClip()

void WaveTrack::CopyPartOfClip ( const Interval clip,
double  t0,
double  t1,
bool  forClipboard 
)
private

Definition at line 1108 of file WaveTrack.cpp.

1110{
1111 const auto &pFactory = GetSampleBlockFactory();
1112 auto newClip = std::make_shared<Interval>(
1113 clip, pFactory, !forClipboard, t0, t1);
1114 newClip->SetName(clip.GetName());
1115 newClip->ShiftBy(-t0);
1116 if (newClip->GetPlayStartTime() < 0)
1117 newClip->SetPlayStartTime(0);
1118 InsertInterval(std::move(newClip), false, false);
1119}
void InsertInterval(const IntervalHolder &interval, bool newClip, bool allowEmpty=false)
Definition: WaveTrack.cpp:3208
const SampleBlockFactoryPtr & GetSampleBlockFactory() const
Definition: WaveTrack.h:253

References GetSampleBlockFactory(), and InsertInterval().

Here is the call graph for this function:

◆ CopyWholeClip()

void WaveTrack::CopyWholeClip ( const Interval clip,
double  t0,
bool  forClipboard 
)
private

Definition at line 1098 of file WaveTrack.cpp.

1100{
1101 const auto &pFactory = GetSampleBlockFactory();
1102 const auto newClip =
1103 std::make_shared<Interval>(clip, pFactory, !forClipboard);
1104 InsertInterval(newClip, false, false);
1105 newClip->ShiftBy(-t0);
1106}

References GetSampleBlockFactory(), and InsertInterval().

Here is the call graph for this function:

◆ Create()

auto WaveTrack::Create ( const SampleBlockFactoryPtr pFactory,
sampleFormat  format,
double  rate 
)
static

Factory builds all AttachedTrackObjects.

Definition at line 505 of file WaveTrack.cpp.

508{
509 auto result =
510 std::make_shared<WaveTrack>(CreateToken{}, pFactory, format, rate);
511 // Only after make_shared returns, can weak_from_this be used, which
512 // attached object factories may need
513 // (but this is anyway just the factory for unit test purposes)
514 result->AttachedTrackObjects::BuildAll();
515 return result;
516}

References anonymous_namespace{ExportPCM.cpp}::format.

Referenced by TestWaveTrackMaker::Track().

Here is the caller graph for this function:

◆ CreateClip()

auto WaveTrack::CreateClip ( double  offset = .0,
const wxString &  name = wxEmptyString,
const Interval pToCopy = nullptr,
bool  copyCutlines = true 
)

Create new clip that uses this track's factory but do not add it to the track

Returns a pointer to the newly created clip. Optionally initial offset and clip name may be provided, and a clip from which to copy all sample data. The clip is not owned by the track. Use InsertInterval to make it so.

Parameters
offsetdesired sequence (not play) start time

Definition at line 2934 of file WaveTrack.cpp.

2936{
2937 if (pToCopy) {
2938 auto pNewClip =
2939 std::make_shared<WaveClip>(*pToCopy, mpFactory, copyCutlines);
2940 pNewClip->SetName(name);
2941 pNewClip->SetSequenceStartTime(offset);
2942 return pNewClip;
2943 }
2944 else
2945 return DoCreateClip(offset, name);
2946}
const TranslatableString name
Definition: Distortion.cpp:76
WaveClipHolder DoCreateClip(double offset=.0, const wxString &name=wxEmptyString) const
Create a new clip that can be inserted later into the track.
Definition: WaveTrack.cpp:2960

References name.

Referenced by ProjectAudioManager::DoRecord(), FinishCopy(), AUPImportFileHandle::HandleWaveClip(), InsertSilence(), Join(), and PasteWaveTrackAtSameTempo().

Here is the caller graph for this function:

◆ CreateRight()

void WaveTrack::CreateRight ( )
private

Definition at line 2955 of file WaveTrack.cpp.

2956{
2957 mRightChannel.emplace(*this);
2958}
std::optional< WaveChannel > mRightChannel
may be null
Definition: WaveTrack.h:769

References mRightChannel.

Referenced by ZipClips().

Here is the caller graph for this function:

◆ Cut()

Track::Holder WaveTrack::Cut ( double  t0,
double  t1 
)
overridevirtual

Create tracks and modify this track.

Returns
non-NULL or else throw May assume precondition: t0 <= t1

Implements Track.

Definition at line 932 of file WaveTrack.cpp.

933{
934 if (t1 < t0)
936
937 auto result = Copy(t0, t1);
938 Clear(t0, t1);
939 return result;
940}
void Clear(double t0, double t1) override
Definition: WaveTrack.cpp:1138
Track::Holder Copy(double t0, double t1, bool forClipboard=true) const override
Create new tracks and don't modify this track.
Definition: WaveTrack.cpp:1073

References Clear(), Copy(), and THROW_INCONSISTENCY_EXCEPTION.

Here is the call graph for this function:

◆ Disjoin()

void WaveTrack::Disjoin ( double  t0,
double  t1 
)
Exception safety guarantee:
Weak

Definition at line 2040 of file WaveTrack.cpp.

2041{
2043 const size_t maxAtOnce = 1048576;
2044 std::vector<float> buffer;
2045 std::vector<samplePtr> buffers;
2046 Regions regions;
2047
2048 const size_t width = NChannels();
2049
2050 for (const auto &interval : Intervals()) {
2051 double startTime = interval->Start();
2052 double endTime = interval->End();
2053
2054 if (endTime < t0 || startTime > t1)
2055 continue;
2056
2057 // Assume all clips will have the same width
2058 if (buffer.empty()) {
2059 buffer.resize(maxAtOnce * width);
2060 buffers.resize(width);
2061 auto pBuffer = buffer.data();
2062 for (size_t ii = 0; ii < width; ++ii, pBuffer += maxAtOnce)
2063 buffers[ii] = reinterpret_cast<samplePtr>(pBuffer);
2064 }
2065
2066 const auto allZeroesAt = [&](size_t i) {
2067 auto pData = buffer.data() + i;
2068 for (size_t ii = 0; ii < width; ++ii, pData += maxAtOnce) {
2069 if (*pData != 0.0)
2070 return false;
2071 }
2072 return true;
2073 };
2074
2075 // simply look for a sequence of zeroes (across all channels) and if the
2076 // sequence is longer than the minimum number, split-delete the region
2077
2078 sampleCount seqStart = -1;
2079 auto start = interval->TimeToSamples(std::max(.0, t0 - startTime));
2080 auto end = interval->TimeToSamples(std::min(endTime, t1) - startTime);
2081
2082 auto len = (end - start);
2083 for (decltype(len) done = 0; done < len; done += maxAtOnce) {
2084 auto numSamples = limitSampleBufferSize(maxAtOnce, len - done);
2085
2086 auto bufferIt = buffers.begin();
2087
2088 for (auto channel : interval->Channels())
2089 channel->GetSamples(
2090 *bufferIt++, floatSample, start + done, numSamples);
2091
2092 for (decltype(numSamples) i = 0; i < numSamples; ++i) {
2093 auto curSamplePos = start + done + i;
2094
2095 //start a NEW sequence
2096 if (seqStart == -1 && allZeroesAt(i))
2097 seqStart = curSamplePos;
2098 else if (curSamplePos == end - 1 || !allZeroesAt(i)) {
2099 if (seqStart != -1) {
2100 decltype(end) seqEnd;
2101
2102 //consider the end case, where selection ends in zeroes
2103 if (curSamplePos == end - 1 && allZeroesAt(i))
2104 seqEnd = end;
2105 else
2106 seqEnd = curSamplePos;
2107 if (seqEnd - seqStart + 1 > minSamples) {
2108 regions.push_back(
2109 Region(
2110 startTime + interval->SamplesToTime(seqStart),
2111 startTime + interval->SamplesToTime(seqEnd)
2112 )
2113 );
2114 }
2115 seqStart = -1;
2116 }
2117 }
2118 } // samples
2119 } // blocks
2120 } // finding regions
2121
2122 for (const auto &region : regions)
2123 SplitDelete(region.start, region.end);
2124}
WaveTrack::Regions Regions
Definition: LabelMenus.cpp:26
size_t limitSampleBufferSize(size_t bufferSize, sampleCount limit)
Definition: SampleCount.cpp:22
char * samplePtr
Definition: SampleFormat.h:57
WaveTrack::Region Region
#define WAVETRACK_MERGE_POINT_TOLERANCE
Definition: WaveTrack.h:67
void SplitDelete(double t0, double t1)
Definition: WaveTrack.cpp:1503
sampleCount TimeToLongSamples(double t0) const
Positions or offsets within audio files need a wide type.
Definition: SampleCount.h:19
const char * end(const char *str) noexcept
Definition: StringUtils.h:106

References details::end(), floatSample, Intervals(), limitSampleBufferSize(), min(), NChannels(), SplitDelete(), WideSampleSequence::TimeToLongSamples(), and WAVETRACK_MERGE_POINT_TOLERANCE.

Referenced by anonymous_namespace{LabelMenus.cpp}::OnDisjoinLabels().

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

◆ DoCreateClip()

auto WaveTrack::DoCreateClip ( double  offset = .0,
const wxString &  name = wxEmptyString 
) const
private

Create a new clip that can be inserted later into the track.

Returns a pointer to the newly created clip. Optionally initial offset and clip name may be provided

Postcondition
result: result->NChannels() == track.NChannels()

Definition at line 2960 of file WaveTrack.cpp.

2962{
2963 auto clip = std::make_shared<WaveClip>(NChannels(),
2965 clip->SetName(name);
2966 clip->SetSequenceStartTime(offset);
2967
2968 const auto& tempo = GetProjectTempo(*this);
2969 if (tempo.has_value())
2970 clip->OnProjectTempoChange(std::nullopt, *tempo);
2971 assert(clip->NChannels() == NChannels());
2972 return clip;
2973}
sampleFormat GetSampleFormat() const override
Definition: WaveTrack.cpp:895
double GetRate() const override
Definition: WaveTrack.cpp:798

References GetProjectTempo(), anonymous_namespace{TimeTrack.cpp}::GetRate(), and name.

Here is the call graph for this function:

◆ DoGet()

bool WaveTrack::DoGet ( size_t  iChannel,
size_t  nBuffers,
const samplePtr  buffers[],
sampleFormat  format,
sampleCount  start,
size_t  len,
bool  backwards,
fillFormat  fill = FillFormat::fillZero,
bool  mayThrow = true,
sampleCount pNumWithinClips = nullptr 
) const
overridevirtual

This fails if any clip overlapping the range has non-unit stretch ratio!

MM: Now that each wave track can contain multiple clips, we don't have a continuous space of samples anymore, but we simulate it, because there are a lot of places (e.g. effects) using this interface. This interface makes much sense for modifying samples, but note that it is not time-accurate, because the "offset" is a double value and therefore can lie inbetween samples. But as long as you use the same value for "start" in both calls to "Set" and "Get" it is guaranteed that the same samples are affected.

Implements WideSampleSequence.

Definition at line 2609 of file WaveTrack.cpp.

2613{
2614 const auto nChannels = NChannels();
2615 assert(iChannel + nBuffers <= nChannels); // precondition
2616 return std::all_of(buffers, buffers + nBuffers, [&](samplePtr buffer) {
2617 const auto result = GetOne(mClips, iChannel++,
2618 buffer, format, start, len, backwards, fill, mayThrow,
2619 pNumWithinClips);
2620 return result;
2621 });
2622}
bool GetOne(const WaveClipHolders &clips, size_t iChannel, samplePtr buffer, sampleFormat format, sampleCount start, size_t len, bool backwards, fillFormat fill, bool mayThrow, sampleCount *pNumWithinClips) const
Definition: WaveTrack.cpp:2624
WaveClipHolders mClips
Definition: WaveTrack.h:775

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

Referenced by WaveChannel::DoGet().

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

◆ DoGetChannel()

std::shared_ptr<::Channel > WaveTrack::DoGetChannel ( size_t  iChannel)
overrideprivatevirtual

Retrieve a channel For fixed iChannel, resulting address must be unchanging, if there has been no other mutation of this ChannelGroup

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

Implements ChannelGroup.

Definition at line 718 of file WaveTrack.cpp.

719{
720 auto nChannels = NChannels();
721 if (iChannel >= nChannels)
722 return {};
723 // TODO: more-than-two-channels
724 ::Channel &aliased = (iChannel == 0)
725 ? mChannel
726 : *mRightChannel;
727 // Use aliasing constructor of std::shared_ptr
728 return { shared_from_this(), &aliased };
729}

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

Here is the call graph for this function:

◆ DoGetInterval()

std::shared_ptr< WideChannelGroupInterval > WaveTrack::DoGetInterval ( size_t  iInterval)
overrideprivatevirtual

Retrieve an interval.

Postcondition
result: !(iInterval < NIntervals()) || result

Implements ChannelGroup.

Definition at line 704 of file WaveTrack.cpp.

705{
706 if (iInterval < NIntervals())
707 return mClips[iInterval];
708 return {};
709}
size_t NIntervals() const override
Report the number of intervals.
Definition: WaveTrack.cpp:688

References mClips, and NIntervals().

Here is the call graph for this function:

◆ DoSetGain()

void WaveTrack::DoSetGain ( float  value)
private

Definition at line 824 of file WaveTrack.cpp.

825{
826 WaveTrackData::Get(*this).SetGain(value);
827}

References BasicUI::Get().

Referenced by HandleXMLTag(), and SetGain().

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

◆ DoSetPan()

void WaveTrack::DoSetPan ( float  value)
private

Definition at line 842 of file WaveTrack.cpp.

843{
844 WaveTrackData::Get(*this).SetPan(value);
845}

References BasicUI::Get().

Referenced by HandleXMLTag(), and SetPan().

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

◆ DoSetRate()

void WaveTrack::DoSetRate ( double  newRate)
private

Definition at line 813 of file WaveTrack.cpp.

814{
815 auto &data = WaveTrackData::Get(*this);
816 data.SetRate(static_cast<int>(newRate));
817}

References BasicUI::Get().

Referenced by Resample(), SetRate(), and WaveTrack().

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

◆ DuplicateWithOtherTempo()

auto WaveTrack::DuplicateWithOtherTempo ( double  newTempo) const
private

Definition at line 575 of file WaveTrack.cpp.

576{
577 const auto srcCopy = Duplicate();
578 ::DoProjectTempoChange(*srcCopy, newTempo);
579 return std::static_pointer_cast<WaveTrack>(srcCopy);
580}
void DoProjectTempoChange(ChannelGroup &group, double newTempo)
Definition: TempoChange.cpp:41
virtual Holder Duplicate(DuplicateOptions={}) const
public nonvirtual duplication function that invokes Clone()
Definition: Track.cpp:109

References DoProjectTempoChange(), and anonymous_namespace{FloatVectorClip.cpp}::Duplicate().

Referenced by ClearAndPaste(), and PasteWaveTrack().

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

◆ EmptyCopy() [1/2]

auto WaveTrack::EmptyCopy ( const SampleBlockFactoryPtr pFactory = {}) const

Make another channel group copying format, rate, etc. but containing no clips; with as many channels as in this

It is important to pass the correct factory (that for the project which will own the copy) in the unusual case that a track is copied from another project or the clipboard. For copies within one project, the default will do.

Definition at line 1010 of file WaveTrack.cpp.

1012{
1013 return EmptyCopy(NChannels(), pFactory);
1014}

◆ EmptyCopy() [2/2]

WaveTrack::Holder WaveTrack::EmptyCopy ( size_t  nChannels,
const SampleBlockFactoryPtr pFactory = {} 
) const

Make another track copying format, rate, etc. but containing no clips; with the specified number of channels.

It is important to pass the correct factory (that for the project which will own the copy) in the unusual case that a track is copied from another project or the clipboard. For copies within one project, the default will do.

Definition at line 989 of file WaveTrack.cpp.

991{
992 const auto rate = GetRate();
993 auto result = std::make_shared<WaveTrack>(CreateToken{},
994 pFactory, GetSampleFormat(), rate);
995 if (nChannels > 1)
996 result->CreateRight();
997 result->Init(*this);
998 // Copy state rather than BuildAll()
999 Track::CopyAttachments(*result, *this, true /* deep copy */);
1000 // The previous line might have destroyed the rate information stored in
1001 // channel group data. The copy is not yet in a TrackList. Reassign rate
1002 // in case the track needs to make WaveClips before it is properly joined
1003 // with the opposite channel in a TrackList.
1004 result->DoSetRate(rate);
1005 result->mpFactory = pFactory ? pFactory : mpFactory;
1006 WaveTrackData::Get(*result).SetOrigin(0);
1007 return result;
1008}
static void CopyAttachments(Track &dst, const Track &src, bool deep)
Copy (deep) or just share (!deep) AttachedTrackObjects.
Definition: Track.cpp:94

References Track::CopyAttachments(), BasicUI::Get(), GetRate(), GetSampleFormat(), and mpFactory.

Referenced by Clone(), Copy(), WaveTrackFactory::Create(), PasteInto(), EffectStereoToMono::ProcessOne(), and SyncLockAdjust().

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

◆ EraseChannelAttachments()

void WaveTrack::EraseChannelAttachments ( size_t  index)
private

Erase all attachments for a given index.

Definition at line 454 of file WaveTrack.cpp.

455{
457 [this, ii](TrackAttachment &attachment){
458 if (const auto pAttachments =
459 dynamic_cast<ChannelAttachmentsBase *>(&attachment))
460 pAttachments->Erase(shared_from_this(), ii);
461 });
462}
Holds multiple objects as a single attachment to Track.
void ForEach(const Function &function)
Invoke function on each ClientData object that has been created in this.
Definition: ClientData.h:389

References ClientData::Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy >::ForEach().

Referenced by MakeMono().

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

◆ ExpandOneCutLine()

void WaveTrack::ExpandOneCutLine ( double  cutLinePosition,
double *  cutlineStart,
double *  cutlineEnd 
)
private

◆ FindChannelGroup()

const ChannelGroup * WaveTrack::FindChannelGroup ( ) const
overridevirtual

Find associated ChannelGroup if any.

Implements PlayableSequence.

Definition at line 2313 of file WaveTrack.cpp.

2314{
2315 return this;
2316}

◆ FindClip()

std::ptrdiff_t WaveTrack::FindClip ( const Interval clip)
private

Definition at line 1510 of file WaveTrack.cpp.

1511{
1512 auto clips = Intervals();
1513 const auto begin = clips.begin();
1514 const auto pred = [&](auto pClip){ return pClip.get() == &clip; };
1515 auto iter = std::find_if(begin, clips.end(), pred);
1516 return std::distance(begin, iter);
1517}
const char * begin(const char *str) noexcept
Definition: StringUtils.h:101

References details::begin(), and Intervals().

Referenced by Join(), and ReplaceInterval().

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

◆ FinishCopy()

void WaveTrack::FinishCopy ( double  t0,
double  t1,
double  endTime,
bool  forClipboard 
)
private

Definition at line 1121 of file WaveTrack.cpp.

1123{
1124 // AWD, Oct 2009: If the selection ends in whitespace, create a
1125 // placeholder clip representing that whitespace
1126 // PRL: Only if we want the track for pasting into other tracks. Not if
1127 // it goes directly into a project as in the Duplicate command.
1128 if (forClipboard && endTime + 1.0 / GetRate() < t1 - t0) {
1129 auto placeholder = CreateClip();
1130 placeholder->SetIsPlaceholder(true);
1131 placeholder->InsertSilence(0, (t1 - t0) - GetEndTime());
1132 placeholder->ShiftBy(GetEndTime());
1133 InsertInterval(move(placeholder), true, false);
1134 }
1135}

References CreateClip(), GetEndTime(), GetRate(), and InsertInterval().

Here is the call graph for this function:

◆ Flush()

void WaveTrack::Flush ( )
overridevirtual
Exception safety guarantee:
Mixed
Exception safety guarantee:
No-fail – The rightmost clip will be in a flushed state.
Exception safety guarantee:
Partial – Some initial portion (maybe none) of the append buffer of the rightmost clip gets appended; no previously saved contents are lost.

Implements RecordableSequence.

Definition at line 2294 of file WaveTrack.cpp.

2295{
2296 if (NIntervals() == 0)
2297 return;
2298 // After appending, presumably. Do this to the clip that gets appended.
2299 GetRightmostClip()->Flush();
2300}
IntervalHolder GetRightmostClip()
Definition: WaveTrack.cpp:2549

References GetRightmostClip(), and NIntervals().

Referenced by ImportUtils::FinalizeImport(), WaveTrackSink::Flush(), TrackSpectrumTransformer::PostProcess(), and EffectSBSMS::Process().

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

◆ FormatConsistencyCheck()

bool WaveTrack::FormatConsistencyCheck ( ) const
private

Whether all tracks in unzipped group and all clips have a common sample format

Definition at line 1899 of file WaveTrack.cpp.

1900{
1901 const auto channels = TrackList::Channels(this);
1902 return std::all_of(channels.begin(), channels.end(),
1903 [&](const WaveTrack *pTrack){
1904 return pTrack && pTrack->mLegacyFormat == mLegacyFormat;
1905 });
1906}
static auto Channels(TrackType *pTrack) -> TrackIterRange< TrackType >
Definition: Track.h:1016
A Track that contains audio waveform data.
Definition: WaveTrack.h:203

References TrackList::Channels().

Referenced by LinkConsistencyFix().

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

◆ GetBestBlockSize()

size_t WaveTrack::GetBestBlockSize ( sampleCount  t) const

Definition at line 2239 of file WaveTrack.cpp.

2240{
2241 auto bestBlockSize = GetMaxBlockSize();
2242
2243 for (const auto &clip : Intervals()) {
2244 auto startSample = clip->GetPlayStartSample();
2245 auto endSample = clip->GetPlayEndSample();
2246 if (s >= startSample && s < endSample)
2247 {
2248 // ignore extra channels (this function will soon be removed)
2249 bestBlockSize =
2250 clip->GetBestBlockSize(s - clip->GetSequenceStartSample());
2251 break;
2252 }
2253 }
2254
2255 return bestBlockSize;
2256}
size_t GetMaxBlockSize() const
Definition: WaveTrack.cpp:2258

References GetMaxBlockSize(), and Intervals().

Referenced by WaveChannel::GetBestBlockSize(), and anonymous_namespace{WaveTrackUtilities.cpp}::ReverseOneClip().

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

◆ GetChannel() [1/2]

auto WaveTrack::GetChannel ( size_t  iChannel)
inline

Definition at line 258 of file WaveTrack.h.

258 {
259 return this->ChannelGroup::GetChannel<WaveChannel>(iChannel); }

References anonymous_namespace{StretchingSequenceIntegrationTest.cpp}::iChannel.

Referenced by WaveTrackMenuTable::OnMergeStereo(), and WaveTrackMenuTable::SplitStereo().

Here is the caller graph for this function:

◆ GetChannel() [2/2]

auto WaveTrack::GetChannel ( size_t  iChannel) const
inline

Definition at line 260 of file WaveTrack.h.

260 {
261 return this->ChannelGroup::GetChannel<const WaveChannel>(iChannel); }

References anonymous_namespace{StretchingSequenceIntegrationTest.cpp}::iChannel.

◆ GetChannelGain()

float WaveTrack::GetChannelGain ( int  channel) const
overridevirtual

Takes gain and pan into account.

Implements WideSampleSequence.

Definition at line 865 of file WaveTrack.cpp.

866{
867 // channel is not necessarily less than the channel group width but
868 // a mono track might pan differently according to that
869 float left = 1.0;
870 float right = 1.0;
871
872 const auto pan = GetPan();
873 if (pan < 0)
874 right = (pan + 1.0);
875 else if (pan > 0)
876 left = 1.0 - pan;
877
878 const auto gain = GetGain();
879 if ((channel % 2) == 0)
880 return left * gain;
881 else
882 return right * gain;
883}
float GetPan() const
Definition: WaveTrack.cpp:837
float GetGain() const
Definition: WaveTrack.cpp:819

References GetGain(), and GetPan().

Referenced by WaveChannel::GetChannelGain(), and EffectStereoToMono::ProcessOne().

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

◆ GetChannelType()

AudioGraph::ChannelType WaveTrack::GetChannelType ( ) const
overridevirtual

Classify this channel.

Implements AudioGraph::Channel.

Definition at line 548 of file WaveTrack.cpp.

549{
550 // Not quite meaningful but preserving old behavior
551 return (*Channels().begin())->WaveChannel::GetChannelType();
552}
auto Channels()
Definition: WaveTrack.h:263

References details::begin(), and Channels().

Here is the call graph for this function:

◆ GetClip() [1/2]

auto WaveTrack::GetClip ( size_t  iInterval)

Definition at line 693 of file WaveTrack.cpp.

694{
695 return std::static_pointer_cast<Interval>(DoGetInterval(iInterval));
696}
std::shared_ptr< WideChannelGroupInterval > DoGetInterval(size_t iInterval) override
Retrieve an interval.
Definition: WaveTrack.cpp:704

Referenced by GetClip(), HandleXMLChild(), MergeClips(), and PasteWaveTrackAtSameTempo().

Here is the caller graph for this function:

◆ GetClip() [2/2]

auto WaveTrack::GetClip ( size_t  iInterval) const

used only during deserialization

Definition at line 698 of file WaveTrack.cpp.

699{
700 return const_cast<WaveTrack&>(*this).GetClip(iInterval);
701}
IntervalHolder GetClip(size_t iInterval)
Definition: WaveTrack.cpp:693

References GetClip().

Here is the call graph for this function:

◆ GetClipAtTime()

auto WaveTrack::GetClipAtTime ( double  time) const
private

Definition at line 2924 of file WaveTrack.cpp.

2925{
2926 const auto clips = SortedClipArray();
2927 auto p = std::find_if(
2928 clips.rbegin(), clips.rend(), [&](const auto &pClip) {
2929 return pClip->WithinPlayRegion(time);
2930 });
2931 return p != clips.rend() ? *p : nullptr;
2932}
IntervalConstHolders SortedClipArray() const
Return all WaveClips sorted by clip play start time.
Definition: WaveTrack.cpp:3260

References WaveChannelUtilities::SortedClipArray().

Referenced by ApplyPitchAndSpeed().

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

◆ GetClipIndex()

int WaveTrack::GetClipIndex ( const Interval clip) const

Get the linear index of a given clip (== number of clips if not found)

Definition at line 3010 of file WaveTrack.cpp.

3011{
3012 int result = 0;
3013 const auto &clips = Intervals();
3014 const auto test =
3015 [&](const auto &pOtherClip){ return &clip == pOtherClip.get(); };
3016 auto begin = clips.begin(),
3017 end = clips.end(),
3018 iter = std::find_if(begin, end, test);
3019 return std::distance(begin, iter);
3020}

References details::begin(), details::end(), and Intervals().

Here is the call graph for this function:

◆ GetClipInterfaces()

ClipConstHolders WaveTrack::GetClipInterfaces ( ) const

Get access to the (visible) clips in the tracks, in unspecified order.

Definition at line 2565 of file WaveTrack.cpp.

2566{
2567 auto clips = Intervals();
2568 return { clips.begin(), clips.end() };
2569}

References Intervals().

Here is the call graph for this function:

◆ GetDefaultAudioTrackNamePreference()

wxString WaveTrack::GetDefaultAudioTrackNamePreference ( )
static

Definition at line 375 of file WaveTrack.cpp.

376{
378
379 if (name.empty() || ( name == DefaultName.MSGID() ))
380 // When nothing was specified,
381 // the default-default is whatever translation of...
382 /* i18n-hint: The default name for an audio track. */
383 return DefaultName.Translation();
384 else
385 return name;
386}
static auto DefaultName
Definition: WaveTrack.cpp:366
StringSetting AudioTrackNameSetting
Definition: WaveTrack.cpp:3371
bool ReadWithDefault(T *pVar, const T &defaultValue) const
overload of ReadWithDefault returning a boolean that is true if the value was previously defined *‍/
Definition: Prefs.h:213

References AudioTrackNameSetting, DefaultName, TranslatableString::empty(), name, and Setting< T >::ReadWithDefault().

Referenced by TracksPrefs::Commit(), EffectBase::DoEffect(), ProjectAudioManager::DoRecord(), anonymous_namespace{WaveTrackMenuItems.cpp}::OnNewStereoTrack(), and anonymous_namespace{WaveTrackMenuItems.cpp}::OnNewWaveTrack().

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

◆ GetEndTime()

double WaveTrack::GetEndTime ( ) const
overridevirtual

Implement WideSampleSequence.

Implements WideSampleSequence.

Definition at line 2586 of file WaveTrack.cpp.

2587{
2588 return ChannelGroup::GetEndTime();
2589}
double GetEndTime() const
Get the maximum of End() values of intervals, or 0 when none.
Definition: Channel.cpp:61

References ChannelGroup::GetEndTime().

Referenced by AUPImportFileHandle::AddSilence(), EffectTruncSilence::Analyze(), ApplyPitchAndSpeed(), ClearAndPasteAtSameTempo(), Copy(), FinishCopy(), Effect::GetBounds(), WaveChannel::GetEndTime(), PasteWaveTrackAtSameTempo(), TrackSpectrumTransformer::PostProcess(), EffectStereoToMono::ProcessOne(), GetInfoCommand::SendTracks(), RateMenuTable::SetRate(), SyncLockAdjust(), and Trim().

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

◆ GetEnvelopeValues()

void WaveTrack::GetEnvelopeValues ( double *  buffer,
size_t  bufferLen,
double  t0,
bool  backwards 
) const
overridevirtual

Fetch envelope values corresponding to uniformly separated sample times starting at the given time

Parameters
backwardsif true, fetch values in reverse order, from t0 to t0 - bufferLen / rate

Implements WideSampleSequence.

Definition at line 2847 of file WaveTrack.cpp.

2849{
2850 auto pTrack = this;
2851 if (!pTrack)
2852 return;
2853
2854 if (backwards)
2855 t0 -= bufferLen / pTrack->GetRate();
2856 // The output buffer corresponds to an unbroken span of time which the callers expect
2857 // to be fully valid. As clips are processed below, the output buffer is updated with
2858 // envelope values from any portion of a clip, start, end, middle, or none at all.
2859 // Since this does not guarantee that the entire buffer is filled with values we need
2860 // to initialize the entire buffer to a default value.
2861 //
2862 // This does mean that, in the cases where a usable clip is located, the buffer value will
2863 // be set twice. Unfortunately, there is no easy way around this since the clips are not
2864 // stored in increasing time order. If they were, we could just track the time as the
2865 // buffer is filled.
2866 for (decltype(bufferLen) i = 0; i < bufferLen; i++)
2867 {
2868 buffer[i] = 1.0;
2869 }
2870
2871 double startTime = t0;
2872 const auto rate = pTrack->GetRate();
2873 auto tstep = 1.0 / rate;
2874 double endTime = t0 + tstep * bufferLen;
2875 for (const auto &clip: pTrack->Intervals())
2876 {
2877 // IF clip intersects startTime..endTime THEN...
2878 auto dClipStartTime = clip->GetPlayStartTime();
2879 auto dClipEndTime = clip->GetPlayEndTime();
2880 if ((dClipStartTime < endTime) && (dClipEndTime > startTime))
2881 {
2882 auto rbuf = buffer;
2883 auto rlen = bufferLen;
2884 auto rt0 = t0;
2885
2886 if (rt0 < dClipStartTime)
2887 {
2888 // This is not more than the number of samples in
2889 // (endTime - startTime) which is bufferLen:
2890 auto nDiff = (sampleCount)floor((dClipStartTime - rt0) * rate + 0.5);
2891 auto snDiff = nDiff.as_size_t();
2892 rbuf += snDiff;
2893 wxASSERT(snDiff <= rlen);
2894 rlen -= snDiff;
2895 rt0 = dClipStartTime;
2896 }
2897
2898 if (rt0 + rlen*tstep > dClipEndTime)
2899 {
2900 auto nClipLen = clip->GetPlayEndSample() - clip->GetPlayStartSample();
2901
2902 if (nClipLen <= 0) // Testing for bug 641, this problem is consistently '== 0', but doesn't hurt to check <.
2903 return;
2904
2905 // This check prevents problem cited in http://bugzilla.audacityteam.org/show_bug.cgi?id=528#c11,
2906 // Gale's cross_fade_out project, which was already corrupted by bug 528.
2907 // This conditional prevents the previous write past the buffer end, in clip->GetEnvelope() call.
2908 // Never increase rlen here.
2909 // PRL bug 827: rewrote it again
2910 rlen = limitSampleBufferSize( rlen, nClipLen );
2911 rlen = std::min(rlen, size_t(floor(0.5 + (dClipEndTime - rt0) / tstep)));
2912 }
2913 // Samples are obtained for the purpose of rendering a wave track,
2914 // so quantize time
2915 clip->GetEnvelope().GetValues(rbuf, rlen, rt0, tstep);
2916 }
2917 }
2918 if (backwards)
2919 std::reverse(buffer, buffer + bufferLen);
2920}

References limitSampleBufferSize(), and min().

Referenced by WaveChannel::GetEnvelopeValues().

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

◆ GetErrorOpening()

std::optional< TranslatableString > WaveTrack::GetErrorOpening ( ) const
overridevirtual

Returns nonempty if an error was encountered while trying to open the track from XML

May assume consistency of stereo channel grouping and examine other channels

Reimplemented from Track.

Definition at line 2521 of file WaveTrack.cpp.

2522{
2523 for (const auto &pClip : Intervals()) {
2524 const auto width = pClip->NChannels();
2525 for (size_t ii = 0; ii < width; ++ii)
2526 if (pClip->GetSequence(ii)->GetErrorOpening())
2527 return XO("A track has a corrupted sample sequence.");
2528 }
2529
2530 return {};
2531}
XO("Cut/Copy/Paste")

References Intervals(), and XO().

Here is the call graph for this function:

◆ GetGain()

float WaveTrack::GetGain ( ) const

Definition at line 819 of file WaveTrack.cpp.

820{
821 return WaveTrackData::Get(*this).GetGain();
822}

References BasicUI::Get().

Referenced by WaveTrackControls::GainSlider(), GetChannelGain(), GetInfoCommand::SendTracks(), and SetGain().

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

◆ GetIdealBlockSize()

size_t WaveTrack::GetIdealBlockSize ( )

Definition at line 2279 of file WaveTrack.cpp.

2280{
2281 // ignore extra channels (this function will soon be removed)
2282 return (*NewestOrNewClip()->Channels().begin())->GetClip()
2283 .GetSequence(0)->GetIdealBlockSize();
2284}
IntervalHolder NewestOrNewClip()
Get access to the most recently added clip, or create a clip, if there is not already one....
Definition: WaveTrack.cpp:2975

References details::begin(), Channels(), and NewestOrNewClip().

Referenced by WaveChannel::GetIdealBlockSize().

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

◆ GetIntervalAtTime()

WaveTrack::IntervalHolder WaveTrack::GetIntervalAtTime ( double  t)

Definition at line 203 of file WaveTrack.cpp.

204{
205 IntervalHolder result;
206 for (const auto &interval : Intervals())
207 if (interval->WithinPlayRegion(t))
208 return interval;
209 return nullptr;
210}

References Intervals().

Referenced by ApplyPitchAndSpeed().

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

◆ GetLeftmostClip() [1/2]

auto WaveTrack::GetLeftmostClip ( )

Definition at line 2533 of file WaveTrack.cpp.

2533 {
2534 auto clips = Intervals();
2535 if (clips.empty())
2536 return nullptr;
2537 const auto begin = clips.begin(),
2538 iter = std::min_element(begin, clips.end(),
2539 [](const auto& a, const auto b) {
2540 return a->GetPlayStartTime() < b->GetPlayStartTime();
2541 });
2542 return GetClip(std::distance(begin, iter));
2543}

References details::begin().

Referenced by GetLeftmostClip(), and PasteWaveTrackAtSameTempo().

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

◆ GetLeftmostClip() [2/2]

auto WaveTrack::GetLeftmostClip ( ) const

Definition at line 2545 of file WaveTrack.cpp.

2545 {
2546 return const_cast<WaveTrack&>(*this).GetLeftmostClip();
2547}
IntervalHolder GetLeftmostClip()
Definition: WaveTrack.cpp:2533

References GetLeftmostClip().

Here is the call graph for this function:

◆ GetMaxBlockSize()

size_t WaveTrack::GetMaxBlockSize ( ) const

Definition at line 2258 of file WaveTrack.cpp.

2259{
2260 const auto clips = Intervals();
2261 auto maxblocksize = std::accumulate(clips.begin(), clips.end(), size_t{},
2262 [](size_t acc, auto pClip){
2263 return std::max(acc, pClip->GetMaxBlockSize()); });
2264
2265 if (maxblocksize == 0)
2266 {
2267 // We really need the maximum block size, so create a
2268 // temporary sequence to get it.
2269 maxblocksize =
2271 .GetMaxBlockSize();
2272 }
2273
2274 wxASSERT(maxblocksize > 0);
2275
2276 return maxblocksize;
2277}
Two sample formats, remembering format of original source and describing stored format.
Definition: SampleFormat.h:79
A WaveTrack contains WaveClip(s). A WaveClip contains a Sequence. A Sequence is primarily an interfac...
Definition: Sequence.h:53

References GetSampleFormat(), Intervals(), and mpFactory.

Referenced by EffectTruncSilence::Analyze(), CompareAudioCommand::Apply(), GetBestBlockSize(), WaveChannel::GetMaxBlockSize(), EffectStereoToMono::ProcessOne(), PerTrackEffect::ProcessPass(), and anonymous_namespace{WaveTrackUtilities.cpp}::ReverseOneClip().

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

◆ GetMute()

bool WaveTrack::GetMute ( ) const
overridevirtual

May vary asynchronously.

Implements PlayableSequence.

Definition at line 2318 of file WaveTrack.cpp.

2319{
2320 return PlayableTrack::GetMute();
2321}
bool GetMute() const
Definition: PlayableTrack.h:47

References PlayableTrack::GetMute().

Referenced by ExportAudioDialog::DoExportSplitByTracks(), ExportUtils::FindExportWaveTracks(), GetInfoCommand::SendTracks(), and ExportAudioDialog::UpdateTrackExportSettings().

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

◆ GetNextInterval() [1/2]

WaveTrack::IntervalHolder WaveTrack::GetNextInterval ( const Interval interval,
PlaybackDirection  searchDirection 
)

Returns
Interval that starts after(before) the beginning of the passed interval

Definition at line 196 of file WaveTrack.cpp.

198{
199 return std::const_pointer_cast<Interval>(
200 std::as_const(*this).GetNextInterval(interval, searchDirection));
201}

◆ GetNextInterval() [2/2]

std::shared_ptr< const WaveTrack::Interval > WaveTrack::GetNextInterval ( const Interval interval,
PlaybackDirection  searchDirection 
) const
Returns
Interval that starts after(before) the beginning of the passed interval

Definition at line 175 of file WaveTrack.cpp.

176{
177 std::shared_ptr<const Interval> result;
178 auto bestMatchTime = searchDirection == PlaybackDirection::forward
179 ? std::numeric_limits<double>::max()
180 : std::numeric_limits<double>::lowest();
181
182 for (const auto &other : Intervals()) {
183 if((searchDirection == PlaybackDirection::forward &&
184 (other->Start() > interval.Start() && other->Start() < bestMatchTime))
185 ||
186 (searchDirection == PlaybackDirection::backward &&
187 (other->Start() < interval.Start() && other->Start() > bestMatchTime)))
188 {
189 result = other;
190 bestMatchTime = other->Start();
191 }
192 }
193 return result;
194}
STL namespace.

References backward, forward, Intervals(), and ChannelGroupInterval::Start().

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

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

◆ GetNumClips()

int WaveTrack::GetNumClips ( ) const

Definition at line 3022 of file WaveTrack.cpp.

3023{
3024 return NarrowClips().size();
3025}
WaveClipHolders & NarrowClips()
Definition: WaveTrack.cpp:751

References NarrowClips().

Referenced by ApplyPitchAndSpeed(), and PasteWaveTrackAtSameTempo().

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

◆ GetOne()

bool WaveTrack::GetOne ( const WaveClipHolders clips,
size_t  iChannel,
samplePtr  buffer,
sampleFormat  format,
sampleCount  start,
size_t  len,
bool  backwards,
fillFormat  fill,
bool  mayThrow,
sampleCount pNumWithinClips 
) const
private

Definition at line 2624 of file WaveTrack.cpp.

2628{
2629 if (backwards)
2630 start -= len;
2631 // Simple optimization: When this buffer is completely contained within one clip,
2632 // don't clear anything (because we won't have to). Otherwise, just clear
2633 // everything to be on the safe side.
2634 bool doClear = true;
2635 bool result = true;
2636 sampleCount samplesCopied = 0;
2637 for (const auto &clip: clips)
2638 {
2639 if (start >= clip->GetPlayStartSample() && start+len <= clip->GetPlayEndSample())
2640 {
2641 doClear = false;
2642 break;
2643 }
2644 }
2645 if (doClear)
2646 {
2647 // Usually we fill in empty space with zero
2648 if (fill == FillFormat::fillZero)
2649 ClearSamples(buffer, format, 0, len);
2650 // but we don't have to.
2651 else if (fill == FillFormat::fillTwo)
2652 {
2653 wxASSERT( format==floatSample );
2654 float * pBuffer = (float*)buffer;
2655 for(size_t i=0;i<len;i++)
2656 pBuffer[i]=2.0f;
2657 }
2658 else
2659 {
2660 wxFAIL_MSG(wxT("Invalid fill format"));
2661 }
2662 }
2663
2664 // Iterate the clips. They are not necessarily sorted by time.
2665 for (const auto &clip: clips)
2666 {
2667 auto clipStart = clip->GetPlayStartSample();
2668 auto clipEnd = clip->GetPlayEndSample();
2669
2670 if (clipEnd > start && clipStart < start+len)
2671 {
2672 if (clip->HasPitchOrSpeed())
2673 return false;
2674
2675 // Clip sample region and Get/Put sample region overlap
2676 auto samplesToCopy =
2677 std::min( start+len - clipStart, clip->GetVisibleSampleCount() );
2678 auto startDelta = clipStart - start;
2679 decltype(startDelta) inclipDelta = 0;
2680 if (startDelta < 0)
2681 {
2682 inclipDelta = -startDelta; // make positive value
2683 samplesToCopy -= inclipDelta;
2684 // samplesToCopy is now either len or
2685 // (clipEnd - clipStart) - (start - clipStart)
2686 // == clipEnd - start > 0
2687 // samplesToCopy is not more than len
2688 //
2689 startDelta = 0;
2690 // startDelta is zero
2691 }
2692 else {
2693 // startDelta is nonnegative and less than len
2694 // samplesToCopy is positive and not more than len
2695 }
2696
2697 if (!clip->GetSamples(iChannel,
2698 (samplePtr)(((char*)buffer) +
2699 startDelta.as_size_t() *
2701 format, inclipDelta, samplesToCopy.as_size_t(), mayThrow ))
2702 result = false;
2703 else
2704 samplesCopied += samplesToCopy;
2705 }
2706 }
2707 if( pNumWithinClips )
2708 *pNumWithinClips = samplesCopied;
2709 if (result == true && backwards)
2710 ReverseSamples(buffer, format, 0, len);
2711 return result;
2712}
wxT("CloseDown"))
void ReverseSamples(samplePtr dst, sampleFormat format, int start, int len)
void ClearSamples(samplePtr dst, sampleFormat format, size_t start, size_t len)
#define SAMPLE_SIZE(SampleFormat)
Definition: SampleFormat.h:52

References ClearSamples(), fillTwo, fillZero, floatSample, anonymous_namespace{ExportPCM.cpp}::format, anonymous_namespace{StretchingSequenceIntegrationTest.cpp}::iChannel, min(), ReverseSamples(), SAMPLE_SIZE, and wxT().

Referenced by DoGet().

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

◆ GetPan()

float WaveTrack::GetPan ( ) const

Definition at line 837 of file WaveTrack.cpp.

838{
839 return WaveTrackData::Get(*this).GetPan();
840}

References BasicUI::Get().

Referenced by GetChannelGain(), WaveTrackControls::PanSlider(), GetInfoCommand::SendTracks(), and SetPan().

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

◆ GetRate()

double WaveTrack::GetRate ( ) const
overridevirtual

◆ GetRightmostClip() [1/2]

auto WaveTrack::GetRightmostClip ( )

Definition at line 2549 of file WaveTrack.cpp.

2549 {
2550 auto clips = Intervals();
2551 if (clips.empty())
2552 return nullptr;
2553 const auto begin = clips.begin(),
2554 iter = std::max_element(begin, clips.end(),
2555 [](const auto& a, const auto b) {
2556 return a->GetPlayEndTime() < b->GetPlayEndTime();
2557 });
2558 return GetClip(std::distance(begin, iter));
2559}

References details::begin().

Referenced by Flush(), GetRightmostClip(), and PasteWaveTrackAtSameTempo().

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

◆ GetRightmostClip() [2/2]

auto WaveTrack::GetRightmostClip ( ) const

Definition at line 2561 of file WaveTrack.cpp.

2561 {
2562 return const_cast<WaveTrack&>(*this).GetRightmostClip();
2563}

References GetRightmostClip().

Here is the call graph for this function:

◆ GetSampleBlockFactory()

const SampleBlockFactoryPtr & WaveTrack::GetSampleBlockFactory ( ) const
inline

Definition at line 253 of file WaveTrack.h.

254 { return mpFactory; }

Referenced by CopyPartOfClip(), and CopyWholeClip().

Here is the caller graph for this function:

◆ GetSampleFormat()

sampleFormat WaveTrack::GetSampleFormat ( ) const
overridevirtual

Implements RecordableSequence.

Definition at line 895 of file WaveTrack.cpp.

896{
897 return WaveTrackData::Get(*this).GetSampleFormat();
898}

References BasicUI::Get().

Referenced by EmptyCopy(), GetMaxBlockSize(), WaveChannel::GetSampleFormat(), and WaveTrackMenuTable::OnMergeStereo().

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

◆ GetSampleView()

ChannelGroupSampleView WaveTrack::GetSampleView ( double  t0,
double  t1,
bool  mayThrow = true 
) const

Request samples within [t0, t1), not knowing in advance how many this will be.

The stretching of intersecting intervals 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.

Postcondition
result: result.size() == NChannels()
Precondition
samples in [t0, t1) can be counted with size_t

Definition at line 2715 of file WaveTrack.cpp.

2716{
2718 for (const auto& channel : Channels()) {
2719 result.push_back(channel->GetSampleView(t0, t1, mayThrow));
2720 }
2721 return result;
2722}
std::vector< std::vector< AudioSegmentSampleView > > ChannelGroupSampleView
Definition: MixerBoard.h:35

References Channels().

Here is the call graph for this function:

◆ GetSolo()

bool WaveTrack::GetSolo ( ) const
overridevirtual

May vary asynchronously.

Implements PlayableSequence.

Definition at line 2323 of file WaveTrack.cpp.

2324{
2325 return PlayableTrack::GetSolo();
2326}
bool GetSolo() const
Definition: PlayableTrack.h:48

References PlayableTrack::GetSolo().

Referenced by ExportAudioDialog::DoExportSplitByTracks(), WaveformView::Draw(), ExportUtils::FindExportWaveTracks(), GetInfoCommand::SendTracks(), and ExportAudioDialog::UpdateTrackExportSettings().

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

◆ GetStartTime()

double WaveTrack::GetStartTime ( ) const
overridevirtual

Implement WideSampleSequence.

Implements WideSampleSequence.

Definition at line 2576 of file WaveTrack.cpp.

2577{
2579}
double GetStartTime() const
Get the minimum of Start() values of intervals, or 0 when none.
Definition: Channel.cpp:50

References ChannelGroup::GetStartTime().

Referenced by ApplyPitchAndSpeed(), Effect::GetBounds(), TranscriptionToolBar::GetSamples(), WaveChannel::GetStartTime(), MoveTo(), PasteWaveTrackAtSameTempo(), EffectStereoToMono::ProcessOne(), GetInfoCommand::SendTracks(), and Trim().

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

◆ GetTypeInfo()

auto WaveTrack::GetTypeInfo ( ) const
overridevirtual

Reimplemented from WritableSampleTrack.

Definition at line 667 of file WaveTrack.cpp.

668{
669 return typeInfo();
670}

References typeInfo().

Here is the call graph for this function:

◆ GetVisibleSampleCount()

sampleCount WaveTrack::GetVisibleSampleCount ( ) const

Definition at line 885 of file WaveTrack.cpp.

886{
887 sampleCount result{ 0 };
888
889 for (const auto& clip : Intervals())
890 result += clip->GetVisibleSampleCount();
891
892 return result;
893}

References Intervals().

Here is the call graph for this function:

◆ HandleClear()

void WaveTrack::HandleClear ( double  t0,
double  t1,
bool  addCutLines,
bool  split,
bool  clearByTrimming = false 
)
private
Exception safety guarantee:
Strong

Definition at line 1527 of file WaveTrack.cpp.

1529{
1530 // For debugging, use an ASSERT so that we stop
1531 // closer to the problem.
1532 wxASSERT( t1 >= t0 );
1533 if (t1 < t0)
1535
1536 t0 = SnapToSample(t0);
1537 t1 = SnapToSample(t1);
1538
1539 IntervalHolders clipsToDelete;
1540 IntervalHolders clipsToAdd;
1541
1542 // We only add cut lines when deleting in the middle of a single clip
1543 // The cut line code is not really prepared to handle other situations
1544 if (addCutLines)
1545 for (const auto &clip : Intervals())
1546 if (clip->PartlyWithinPlayRegion(t0, t1)) {
1547 addCutLines = false;
1548 break;
1549 }
1550
1551 for (const auto &clip : Intervals()) {
1552 if (clip->CoversEntirePlayRegion(t0, t1))
1553 // Whole clip must be deleted - remember this
1554 clipsToDelete.push_back(clip);
1555 else if (clip->IntersectsPlayRegion(t0, t1)) {
1556 // Clip data is affected by command
1557 if (addCutLines) {
1558 // Don't modify this clip in place, because we want a strong
1559 // guarantee, and might modify another clip
1560 clipsToDelete.push_back(clip);
1561 auto newClip = CopyClip(*clip, true);
1562 newClip->ClearAndAddCutLine(t0, t1);
1563 clipsToAdd.push_back(move(newClip));
1564 }
1565 else {
1566 if (split || clearByTrimming) {
1567 // Three cases:
1568
1569 if (clip->BeforePlayRegion(t0)) {
1570 // Delete from the left edge
1571
1572 // Don't modify this clip in place, because we want a strong
1573 // guarantee, and might modify another clip
1574 clipsToDelete.push_back(clip);
1575 auto newClip = CopyClip(*clip, true);
1576 newClip->TrimLeft(t1 - clip->GetPlayStartTime());
1577 if (!split)
1578 // If this is not a split-cut, where things are left in
1579 // place, we need to reposition the clip.
1580 newClip->ShiftBy(t0 - t1);
1581 clipsToAdd.push_back(move(newClip));
1582 }
1583 else if (clip->AfterPlayRegion(t1)) {
1584 // Delete to right edge
1585
1586 // Don't modify this clip in place, because we want a strong
1587 // guarantee, and might modify another clip
1588 clipsToDelete.push_back(clip);
1589 auto newClip = CopyClip(*clip, true);
1590 newClip->TrimRight(clip->GetPlayEndTime() - t0);
1591
1592 clipsToAdd.push_back(move(newClip));
1593 }
1594 else {
1595 // Delete in the middle of the clip...we actually create two
1596 // NEW clips out of the left and right halves...
1597
1598 auto leftClip = CopyClip(*clip, true);
1599 leftClip->TrimRight(clip->GetPlayEndTime() - t0);
1600 clipsToAdd.push_back(move(leftClip));
1601
1602 auto rightClip = CopyClip(*clip, true);
1603 rightClip->TrimLeft(t1 - clip->GetPlayStartTime());
1604 if (!split)
1605 // If this is not a split-cut, where things are left in
1606 // place, we need to reposition the clip.
1607 rightClip->ShiftBy(t0 - t1);
1608 clipsToAdd.push_back(move(rightClip));
1609
1610 clipsToDelete.push_back(clip);
1611 }
1612 }
1613 else {
1614 // (We are not doing a split cut)
1615
1616 // Don't modify this clip in place, because we want a strong
1617 // guarantee, and might modify another clip
1618 clipsToDelete.push_back(clip);
1619 auto newClip = CopyClip(*clip, true);
1620
1621 // clip->Clear keeps points < t0 and >= t1 via Envelope::CollapseRegion
1622 newClip->Clear(t0,t1);
1623
1624 clipsToAdd.push_back(move(newClip));
1625 }
1626 }
1627 }
1628 }
1629
1630 // Only now, change the contents of this track
1631 // use No-fail-guarantee for the rest
1632
1633 for (const auto &clip: clipsToDelete)
1634 RemoveInterval(clip);
1635
1636 const auto moveClipsLeft = !split && GetEditClipsCanMove();
1637 if (moveClipsLeft)
1638 // Clip is "behind" the region -- offset it unless we're splitting
1639 // or we're using the "don't move other clips" mode
1640 for (const auto &clip : Intervals())
1641 if (clip->AtOrBeforePlayRegion(t1))
1642 clip->ShiftBy(-(t1 - t0));
1643
1644 for (auto &clip: clipsToAdd)
1645 InsertInterval(move(clip), false);
1646}
bool GetEditClipsCanMove()
Definition: WaveTrack.cpp:3381
void RemoveInterval(const IntervalHolder &interval)
Definition: WaveTrack.cpp:3219

References CopyClip(), GetEditClipsCanMove(), InsertInterval(), Intervals(), RemoveInterval(), WideSampleSequence::SnapToSample(), and THROW_INCONSISTENCY_EXCEPTION.

Referenced by Clear(), ClearAndAddCutLine(), and SplitDelete().

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

◆ HandleXMLChild()

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

Implements XMLTagHandler.

Definition at line 2402 of file WaveTrack.cpp.

2403{
2404 if (auto pChild = WaveTrackIORegistry::Get().CallObjectAccessor(tag, *this))
2405 // Deserialize any extra attached structures
2406 return pChild;
2407
2408 const auto getClip = [this]() -> WaveClip & {
2409 return (*NewestOrNewClip()->Channels().begin())->GetClip();
2410 };
2411
2412 //
2413 // This is legacy code (1.2 and previous) and is not called for new projects!
2414 if (tag == Sequence::Sequence_tag || tag == "envelope") {
2415 // This is a legacy project, so set the cached offset
2416 NewestOrNewClip()->SetSequenceStartTime(mLegacyProjectFileOffset);
2417
2418 // Legacy project file tracks are imported as one single wave clip
2419 if (tag == Sequence::Sequence_tag)
2420 return getClip().GetSequence(0);
2421 else if (tag == "envelope")
2422 return &getClip().GetEnvelope();
2423 }
2424
2425 // JKC... for 1.1.0, one step better than what we had, but still badly broken.
2426 // If we see a waveblock at this level, we'd better generate a sequence.
2427 if (tag == Sequence::WaveBlock_tag) {
2428 // This is a legacy project, so set the cached offset
2429 NewestOrNewClip()->SetSequenceStartTime(mLegacyProjectFileOffset);
2430 auto pSeq = getClip().GetSequence(0);
2431 return pSeq;
2432 }
2433
2434 // This is for the new file format (post-1.2)
2435 if (tag == WaveClip::WaveClip_tag) {
2436 // Make clips (which don't serialize the rate) consistent with channel rate,
2437 // though the consistency check of channels with each other remains to do.
2438 // Not all `WaveTrackData` fields are properly initialized by now,
2439 // use deserialization helpers.
2440 auto clip = std::make_shared<WaveClip>(1,
2442 const auto xmlHandler = clip.get();
2443 auto &clips = NarrowClips();
2444 clips.push_back(std::move(clip));
2445 Publish({ clips.back(), WaveTrackMessage::Deserialized });
2446 return xmlHandler;
2447 }
2448
2449 return nullptr;
2450}
CallbackReturn Publish(const WaveTrackMessage &message)
Send a message to connected callbacks.
Definition: Observer.h:207
static const char * Sequence_tag
Definition: Sequence.h:56
static const char * WaveBlock_tag
Definition: Sequence.h:57
This allows multiple clips to be a part of one WaveTrack.
Definition: WaveClip.h:238
static const char * WaveClip_tag
Definition: WaveClip.h:249
int mLegacyRate
used only during deserialization
Definition: WaveTrack.h:777
double mLegacyProjectFileOffset
Definition: WaveTrack.h:833
sampleFormat mLegacyFormat
used only during deserialization
Definition: WaveTrack.h:778
static XMLMethodRegistry & Get()
Get the unique instance.
@ Deserialized
being read from project file
Definition: WaveTrack.h:76

References WaveTrackMessage::Deserialized, XMLMethodRegistry< Host >::Get(), GetClip(), mLegacyFormat, mLegacyProjectFileOffset, mLegacyRate, mpFactory, NarrowClips(), NewestOrNewClip(), Observer::Publisher< WaveTrackMessage >::Publish(), Sequence::Sequence_tag, Sequence::WaveBlock_tag, and WaveClip::WaveClip_tag.

Here is the call graph for this function:

◆ HandleXMLEndTag()

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

Definition at line 2390 of file WaveTrack.cpp.

2391{
2392#if 0
2393 // In case we opened a pre-multiclip project, we need to
2394 // simulate closing the waveclip tag.
2395 NewestOrNewClip()->HandleXMLEndTag(WaveClip::WaveClip_tag);
2396#else
2397 // File compatibility breaks have intervened long since, and the line above
2398 // would now have undesirable side effects
2399#endif
2400}

References NewestOrNewClip(), and WaveClip::WaveClip_tag.

Here is the call graph for this function:

◆ HandleXMLTag()

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

Implements XMLTagHandler.

Definition at line 2338 of file WaveTrack.cpp.

2339{
2340 if (tag == WaveTrack_tag) {
2341 double dblValue;
2342 long nValue;
2343
2344 for (const auto& pair : attrs)
2345 {
2346 const auto& attr = pair.first;
2347 const auto& value = pair.second;
2348
2349 if (attr == Rate_attr)
2350 {
2351 // mRate is an int, but "rate" in the project file is a float.
2352 if (!value.TryGet(dblValue) ||
2353 (dblValue < 1.0) || (dblValue > 1000000.0)) // allow a large range to be read
2354 return false;
2355
2356 // Defer the setting of rate until LinkConsistencyFix
2357 mLegacyRate = lrint(dblValue);
2358 }
2359 else if (attr == Offset_attr && value.TryGet(dblValue))
2360 {
2361 // Offset is only relevant for legacy project files. The value
2362 // is cached until the actual WaveClip containing the legacy
2363 // track is created.
2364 mLegacyProjectFileOffset = dblValue;
2365 }
2366 else if (this->WritableSampleTrack::HandleXMLAttribute(attr, value))
2367 {}
2368 else if (this->Track::HandleCommonXMLAttribute(attr, value))
2369 ;
2370 else if (attr == Gain_attr && value.TryGet(dblValue))
2371 DoSetGain(dblValue);
2372 else if (attr == Pan_attr && value.TryGet(dblValue) &&
2373 (dblValue >= -1.0) && (dblValue <= 1.0))
2374 DoSetPan(dblValue);
2375 else if (attr == Linked_attr && value.TryGet(nValue))
2376 SetLinkType(ToLinkType(nValue), false);
2377 else if (attr == SampleFormat_attr && value.TryGet(nValue) &&
2379 {
2380 //Remember sample format until consistency check is performed.
2381 SetLegacyFormat(static_cast<sampleFormat>(nValue));
2382 }
2383 } // while
2384 return true;
2385 }
2386
2387 return false;
2388}
sampleFormat
The ordering of these values with operator < agrees with the order of increasing bit width.
Definition: SampleFormat.h:30
static constexpr auto Pan_attr
Definition: WaveTrack.cpp:2333
static constexpr auto Rate_attr
Definition: WaveTrack.cpp:2331
static constexpr auto SampleFormat_attr
Definition: WaveTrack.cpp:2335
static constexpr auto Offset_attr
Definition: WaveTrack.cpp:2330
static constexpr auto Linked_attr
Definition: WaveTrack.cpp:2334
static constexpr auto Gain_attr
Definition: WaveTrack.cpp:2332
bool HandleXMLAttribute(const std::string_view &attr, const XMLAttributeValueView &value)
static bool IsValidSampleFormat(const int nValue)
true if nValue is one of the sampleFormat enum values
Definition: Sequence.cpp:1905
void SetLinkType(LinkType linkType, bool completeList=true)
Definition: Track.cpp:136
bool HandleCommonXMLAttribute(const std::string_view &attr, const XMLAttributeValueView &valueView)
Definition: Track.cpp:819
void DoSetPan(float value)
Definition: WaveTrack.cpp:842
static const char * WaveTrack_tag
Definition: WaveTrack.h:206
void SetLegacyFormat(sampleFormat format)
Definition: WaveTrack.cpp:2308
void DoSetGain(float value)
Definition: WaveTrack.cpp:824
#define lrint(dbl)
Definition: float_cast.h:169
Track::LinkType ToLinkType(int value)
Definition: WaveTrack.cpp:347

References DoSetGain(), DoSetPan(), Gain_attr, Track::HandleCommonXMLAttribute(), PlayableTrack::HandleXMLAttribute(), Sequence::IsValidSampleFormat(), Linked_attr, lrint, mLegacyProjectFileOffset, mLegacyRate, Offset_attr, Pan_attr, Rate_attr, SampleFormat_attr, SetLegacyFormat(), Track::SetLinkType(), anonymous_namespace{WaveTrack.cpp}::ToLinkType(), and WaveTrack_tag.

Here is the call graph for this function:

◆ HasClipNamed()

bool WaveTrack::HasClipNamed ( const wxString &  name) const

Definition at line 711 of file WaveTrack.cpp.

712{
713 auto clips = Intervals();
714 return std::any_of(clips.begin(), clips.end(),
715 [&](const auto &pClip){ return pClip->GetName() == name; });
716}

References Intervals().

Referenced by ProjectAudioManager::DoRecord(), MakeClipCopyName(), and MakeNewClipName().

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

◆ HasTrivialEnvelope()

bool WaveTrack::HasTrivialEnvelope ( ) const
overridevirtual
Returns
whether envelope values are all unit

Implements WideSampleSequence.

Definition at line 2831 of file WaveTrack.cpp.

2832{
2833 auto pTrack = this;
2834 if (!pTrack)
2835 return false;
2836 auto clips = pTrack->Intervals();
2837 return std::all_of(clips.begin(), clips.end(),
2838 [](const auto &pClip){ return pClip->GetEnvelope().IsTrivial(); });
2839}

Referenced by WaveChannel::HasTrivialEnvelope().

Here is the caller graph for this function:

◆ Init()

void WaveTrack::Init ( const WaveTrack orig)

Overwrite data excluding the sample sequence but including display settings

Definition at line 555 of file WaveTrack.cpp.

556{
558 mpFactory = orig.mpFactory;
559}
void Init(const Track &orig)
Definition: Track.cpp:47

References Track::Init(), and mpFactory.

Referenced by ProjectAudioManager::DoRecord().

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

◆ InsertClip()

bool WaveTrack::InsertClip ( WaveClipHolders clips,
WaveClipHolder  clip,
bool  newClip,
bool  backup,
bool  allowEmpty 
)
private

Sets project tempo on clip upon push. Use this instead of NarrowClips().push_back

Returns
true on success
Parameters
backupwhether the duplication is for backup purposes while opening a project, instead of other editing operations

Definition at line 1908 of file WaveTrack.cpp.

1910{
1911 if (!backup && !clip->GetIsPlaceholder() && !allowEmpty && clip->IsEmpty())
1912 return false;
1913
1914 const auto& tempo = GetProjectTempo(*this);
1915 if (tempo.has_value())
1916 clip->OnProjectTempoChange(std::nullopt, *tempo);
1917 clips.push_back(std::move(clip));
1918 Publish({ clips.back(),
1920
1921 return true;
1922}
@ New
newly created and empty
Definition: WaveTrack.h:75
@ Inserted
(partly) copied from another clip, or moved from a track
Definition: WaveTrack.h:77

References GetProjectTempo(), WaveTrackMessage::Inserted, WaveTrackMessage::New, and Observer::Publisher< WaveTrackMessage >::Publish().

Referenced by CopyClips(), and InsertInterval().

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

◆ InsertInterval()

void WaveTrack::InsertInterval ( const IntervalHolder interval,
bool  newClip,
bool  allowEmpty = false 
)

Definition at line 3208 of file WaveTrack.cpp.

3210{
3211 if (clip) {
3212 constexpr bool backup = false;
3213 InsertClip(mClips, clip, newClip, backup, allowEmpty);
3214 // Detect errors resulting in duplicate shared pointers to clips
3215 assert(ClipsAreUnique(mClips));
3216 }
3217}
bool ClipsAreUnique(const WaveClipHolders &clips)
Definition: WaveTrack.cpp:3200

References anonymous_namespace{WaveTrack.cpp}::ClipsAreUnique(), InsertClip(), and mClips.

Referenced by CopyPartOfClip(), CopyWholeClip(), ProjectAudioManager::DoRecord(), FinishCopy(), HandleClear(), AUPImportFileHandle::HandleWaveClip(), InsertSilence(), Join(), ReplaceInterval(), and WaveTrackUtilities::Reverse().

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

◆ InsertSilence()

void WaveTrack::InsertSilence ( double  t,
double  len 
)
overridevirtual
Exception safety guarantee:
Strong

Implements RecordableSequence.

Definition at line 2002 of file WaveTrack.cpp.

2003{
2004 // Nothing to do, if length is zero.
2005 // Fixes Bug 1626
2006 if (len == 0)
2007 return;
2008 if (len <= 0)
2010
2011 auto &&clips = Intervals();
2012 if (clips.empty()) {
2013 // Special case if there is no clip yet
2014 auto clip = CreateClip(0);
2015 clip->InsertSilence(0, len);
2016 // use No-fail-guarantee
2017 InsertInterval(move(clip), true);
2018 }
2019 else
2020 {
2021 // Assume at most one clip contains t
2022 const auto end = clips.end();
2023 const auto it = std::find_if(clips.begin(), end,
2024 [&](const IntervalHolder &clip) { return clip->SplitsPlayRegion(t); } );
2025
2026 // use Strong-guarantee
2027 if (it != end)
2028 (*it)->InsertSilence(t, len);
2029
2030 // use No-fail-guarantee
2031 for (const auto &&clip : clips)
2032 if (clip->BeforePlayRegion(t))
2033 clip->ShiftBy(len);
2034 }
2035}

References CreateClip(), details::end(), InsertInterval(), Intervals(), and THROW_INCONSISTENCY_EXCEPTION.

Referenced by AUPImportFileHandle::AddSilence(), and EffectSilence::GenerateTrack().

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

◆ Intervals() [1/2]

auto WaveTrack::Intervals ( )
inline

◆ Intervals() [2/2]

auto WaveTrack::Intervals ( ) const
inline

Definition at line 671 of file WaveTrack.h.

671{ return ChannelGroup::Intervals<const Interval>(); }

◆ IsEmpty()

bool WaveTrack::IsEmpty ( double  t0,
double  t1 
) const

Returns true if there are no WaveClips in the specified region.

Returns
true if no clips in the track overlap the specified time range, false otherwise.

Definition at line 910 of file WaveTrack.cpp.

911{
912 if (t0 > t1)
913 return true;
914
915 //wxPrintf("Searching for overlap in %.6f...%.6f\n", t0, t1);
916 for (const auto &clip : Intervals())
917 {
918 if (clip->IntersectsPlayRegion(t0, t1)) {
919 //wxPrintf("Overlapping clip: %.6f...%.6f\n",
920 // clip->GetStartTime(),
921 // clip->GetEndTime());
922 // We found a clip that overlaps this region
923 return false;
924 }
925 }
926 //wxPrintf("No overlap found\n");
927
928 // Otherwise, no clips overlap this region
929 return true;
930}

References Intervals().

Referenced by SyncLockAdjust().

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

◆ Join()

void WaveTrack::Join ( double  t0,
double  t1,
const ProgressReporter reportProgress 
)
Exception safety guarantee:
Weak

Definition at line 2127 of file WaveTrack.cpp.

2129{
2130 // Merge all WaveClips overlapping selection into one
2131 const auto &intervals = Intervals();
2132
2133 {
2134 IntervalHolders intervalsToJoin;
2135 for (const auto &interval : intervals)
2136 if (interval->IntersectsPlayRegion(t0, t1))
2137 intervalsToJoin.push_back(interval);
2138 if (intervalsToJoin.size() < 2u)
2139 return;
2140 if (std::any_of(
2141 intervalsToJoin.begin() + 1, intervalsToJoin.end(),
2142 [first = intervalsToJoin[0]](const auto& interval) {
2143 return !first->HasEqualPitchAndSpeed(*interval);
2144 }))
2145 ApplyPitchAndSpeedOnIntervals(intervalsToJoin, reportProgress);
2146 }
2147
2148 IntervalHolders clipsToDelete;
2149 IntervalHolder newClip{};
2150
2151 const auto rate = GetRate();
2152 for (const auto &clip: intervals) {
2153 if (clip->IntersectsPlayRegion(t0, t1)) {
2154 // Put in sorted order
2155 auto it = clipsToDelete.begin(), end = clipsToDelete.end();
2156 for (; it != end; ++it)
2157 if ((*it)->GetPlayStartTime() > clip->GetPlayStartTime())
2158 break;
2159 //wxPrintf("Insert clip %.6f at position %d\n", clip->GetStartTime(), i);
2160 clipsToDelete.insert(it, clip);
2161 }
2162 }
2163
2164 //if there are no clips to delete, nothing to do
2165 if (clipsToDelete.empty())
2166 return;
2167
2168 const auto firstToDelete = clipsToDelete[0].get();
2169 auto t = firstToDelete->GetPlayStartTime();
2170 //preserve left trim data if any
2171 newClip = CreateClip(
2172 firstToDelete->GetSequenceStartTime(),
2173 firstToDelete->GetName());
2174
2175 for (const auto &clip : clipsToDelete) {
2176 // wxPrintf("t=%.6f adding clip (offset %.6f, %.6f ... %.6f)\n",
2177 // t, clip->GetOffset(), clip->GetStartTime(),
2178 // clip->GetEndTime());
2179
2180 if (clip->GetPlayStartTime() - t > (1.0 / rate))
2181 {
2182 double addedSilence = (clip->GetPlayStartTime() - t);
2183 // wxPrintf("Adding %.6f seconds of silence\n");
2184 auto offset = clip->GetPlayStartTime();
2185 auto value = clip->GetEnvelope().GetValue(offset);
2186 newClip->AppendSilence(addedSilence, value);
2187 t += addedSilence;
2188 }
2189
2190 // wxPrintf("Pasting at %.6f\n", t);
2191 bool success = newClip->Paste(t, *clip);
2192 assert(success); // promise of DoCreateClip
2193
2194 t = newClip->GetPlayEndTime();
2195
2196 RemoveClip(FindClip(*clip));
2197 }
2198
2199 InsertInterval(move(newClip), false);
2200}
void RemoveClip(std::ptrdiff_t distance)
Definition: WaveTrack.cpp:1519
std::ptrdiff_t FindClip(const Interval &clip)
Definition: WaveTrack.cpp:1510

References ApplyPitchAndSpeedOnIntervals(), CreateClip(), details::end(), FindClip(), GetRate(), InsertInterval(), Intervals(), and RemoveClip().

Referenced by anonymous_namespace{LabelMenus.cpp}::OnJoinLabels().

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

◆ JoinOne()

static void WaveTrack::JoinOne ( WaveTrack track,
double  t0,
double  t1 
)
staticprivate
Precondition
All clips intersecting [t0, t1) have unit stretch ratio

◆ LinkConsistencyFix()

bool WaveTrack::LinkConsistencyFix ( bool  doFix)
overridevirtual

Check consistency of channel groups, and maybe fix it.

Parameters
doFixwhether to make any changes to correct inconsistencies
Precondition
!doFix || IsLeader()
Returns
true if no inconsistencies were found

Reimplemented from Track.

Definition at line 582 of file WaveTrack.cpp.

583{
584 // This implies satisfaction of the precondition of SetRate()
585 assert(!doFix || IsLeader());
586
587 const auto removeZeroClips = [](WaveClipHolders& clips) {
588 // Check for zero-length clips and remove them
589 for (auto it = clips.begin(); it != clips.end();)
590 {
591 if ((*it)->IsEmpty())
592 it = clips.erase(it);
593 else
594 ++it;
595 }
596 };
597
599
600 auto linkType = GetLinkType();
601 if (linkType != LinkType::None) {
602 auto next = *TrackList::Channels(this).first.advance(1);
603 if (next == nullptr) {
604 //next track is absent or not a wave track, fix and report error
605 if (doFix) {
606 wxLogWarning(L"Right track %s is expected to be a WaveTrack."
607 "\n Removing link from left wave track %s.",
608 next->GetName(), GetName());
610 }
611 err = true;
612 }
613 else if (doFix) {
614 // non-error upgrades happen here
615 if (!AreAligned(SortedClipArray(), next->SortedClipArray()) ||
617 {
618 SetLinkType(linkType = LinkType::None);
619 }
620 else
621 {
622 SetLinkType(linkType = LinkType::Aligned);
623 //clean up zero clips only after alignment check has completed
624 //this can't break alignment as there should be a "twin"
625 //in the right channel which will also be removed, otherwise
626 //track will be unlinked because AreAligned returned false
627 removeZeroClips(NarrowClips());
628 removeZeroClips(next->NarrowClips());
629 }
630 }
631 }
632 if (doFix) {
633 // More non-error upgrading
634 // Set the common channel group rate from the unzipped leader's rate
635 if (mLegacyRate > 0)
636 {
637 WaveTrack *next{};
638 if (linkType != LinkType::None)
639 next = *TrackList::Channels(this).first.advance(1);
641 mLegacyRate = 0;
642 if (next)
643 next->mLegacyRate = 0;
645 WaveTrackData::Get(*this).SetSampleFormat(mLegacyFormat);
646 if (next && next->mLegacyFormat != undefinedSample)
647 WaveTrackData::Get(*next).SetSampleFormat(mLegacyFormat);
648 }
649 if (linkType == LinkType::None)
650 // Did not visit the other call to removeZeroClips, do it now
651 removeZeroClips(NarrowClips());
652 else
653 // Make a real wide wave track from two deserialized narrow tracks
654 ZipClips();
655 }
656 return !err;
657}
std::vector< WaveClipHolder > WaveClipHolders
Definition: WaveClip.h:45
@ Aligned
Tracks are grouped and changes should be synchronized.
virtual bool LinkConsistencyFix(bool doFix=true)
Check consistency of channel groups, and maybe fix it.
Definition: Track.cpp:266
const wxString & GetName() const
Name is always the same for all channels of a group.
Definition: Track.cpp:64
bool IsLeader() const
Definition: Track.cpp:261
LinkType GetLinkType() const noexcept
Definition: Track.cpp:853
void SetRate(double newRate)
!brief Sets the new rate for the track without resampling it
Definition: WaveTrack.cpp:803
void ZipClips(bool mustAlign=true)
Definition: WaveTrack.cpp:3290
bool FormatConsistencyCheck() const
Definition: WaveTrack.cpp:1899
bool RateConsistencyCheck() const
Whether all clips of an unzipped leader track have a common rate.
Definition: WaveTrack.cpp:1880
bool AreAligned(const WaveTrack::IntervalConstHolders &a, const WaveTrack::IntervalConstHolders &b)
Definition: WaveTrack.cpp:326

References ChannelGroup::Aligned, anonymous_namespace{WaveTrack.cpp}::anonymous_namespace{WaveTrack.cpp}::AreAligned(), TrackList::Channels(), FormatConsistencyCheck(), BasicUI::Get(), Track::GetLinkType(), Track::GetName(), Track::IsLeader(), Track::LinkConsistencyFix(), mLegacyFormat, mLegacyRate, NarrowClips(), ChannelGroup::None, RateConsistencyCheck(), Track::SetLinkType(), SetRate(), SortedClipArray(), undefinedSample, and ZipClips().

Here is the call graph for this function:

◆ MakeClipCopyName()

wxString WaveTrack::MakeClipCopyName ( const wxString &  originalName) const
private

Definition at line 769 of file WaveTrack.cpp.

770{
771 auto name = originalName;
772 for (auto i = 1;; ++i)
773 {
774 if (!HasClipNamed(name))
775 return name;
776 //i18n-hint Template for clip name generation on copy-paste
777 name = XC("%s.%i", "clip name template").Format(originalName, i).Translation();
778 }
779}
#define XC(s, c)
Definition: Internat.h:37
bool HasClipNamed(const wxString &name) const
Definition: WaveTrack.cpp:711

References HasClipNamed(), name, and XC.

Here is the call graph for this function:

◆ MakeMono()

void WaveTrack::MakeMono ( )

Simply discard any right channel.

Definition at line 1016 of file WaveTrack.cpp.

1017{
1018 mRightChannel.reset();
1019 for (auto &pClip : mClips)
1020 pClip->DiscardRightChannel();
1022}
void EraseChannelAttachments(size_t index)
Erase all attachments for a given index.
Definition: WaveTrack.cpp:454

References EraseChannelAttachments(), mClips, and mRightChannel.

Referenced by EffectStereoToMono::ProcessOne().

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

◆ MakeNewClipName()

wxString WaveTrack::MakeNewClipName ( ) const
private

Definition at line 781 of file WaveTrack.cpp.

782{
783 auto name = GetName();
784 for (auto i = 1;; ++i)
785 {
786 if (!HasClipNamed(name))
787 return name;
788 //i18n-hint Template for clip name generation on inserting new empty clip
789 name = XC("%s %i", "clip name template").Format(GetName(), i).Translation();
790 }
791}

References Track::GetName(), HasClipNamed(), name, and XC.

Here is the call graph for this function:

◆ MergeChannelAttachments()

void WaveTrack::MergeChannelAttachments ( WaveTrack &&  other)
private

Steal channel attachments from other, then destroy the track attachment slot

Definition at line 431 of file WaveTrack.cpp.

432{
434 [this](TrackAttachment *pLeft, TrackAttachment *pRight){
435 // Precondition of callback from ClientData::Site
436 assert(pLeft && pRight);
437 const auto pLeftAttachments =
438 dynamic_cast<ChannelAttachmentsBase *>(pLeft);
439 const auto pRightAttachments =
440 dynamic_cast<ChannelAttachmentsBase *>(pRight);
441 // They should have come from the same factory of channel attachments
442 assert((pLeftAttachments == nullptr) == (pRightAttachments == nullptr));
443 if (pLeftAttachments) {
444 // First fixup the back-pointers from channel views to their track
445 pRightAttachments->Reparent(shared_from_this());
446 // Then "steal" them
447 pLeftAttachments->MakeStereo(shared_from_this(),
448 std::move(*pRightAttachments));
449 }
450 });
451}
void ForCorresponding(Site &other, const Function &function, bool create=true)
Definition: ClientData.h:428

References ClientData::Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy >::ForCorresponding().

Referenced by ZipClips().

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

◆ MergeClips()

bool WaveTrack::MergeClips ( int  clipidx1,
int  clipidx2 
)

Definition at line 3158 of file WaveTrack.cpp.

3159{
3160 const auto clip1 = GetClip(clipidx1);
3161 const auto clip2 = GetClip(clipidx2);
3162
3163 if (!clip1 || !clip2)
3164 return false; // Don't throw, just do nothing.
3165
3166 if (!clip1->HasEqualPitchAndSpeed(*clip2))
3167 return false;
3168
3169 // Append data from second clip to first clip
3170 // use Strong-guarantee
3171 bool success = clip1->Paste(clip1->GetPlayEndTime(), *clip2);
3172 assert(success); // assuming clips of the same track must have same width
3173
3174 // use No-fail-guarantee for the rest
3175 // Delete second clip
3176 RemoveInterval(clip2);
3177 return true;
3178}

References GetClip(), and RemoveInterval().

Here is the call graph for this function:

◆ MonoToStereo()

auto WaveTrack::MonoToStereo ( )
Precondition
!GetOwner()

Definition at line 1024 of file WaveTrack.cpp.

1025{
1026 assert(!GetOwner());
1027 MakeMono();
1028
1029 // Make temporary new mono track
1030 auto newTrack = Duplicate();
1031
1032 // Make a list
1033 auto result = TrackList::Temporary(nullptr, shared_from_this());
1034 result->Add(newTrack);
1035 // Destroy the temporary track, widening this track to stereo
1036 ZipClips();
1037
1038 return std::static_pointer_cast<WaveTrack>(result->DetachFirst());
1039}
std::shared_ptr< TrackList > GetOwner() const
Definition: Track.h:230
static TrackListHolder Temporary(AudacityProject *pProject, const Track::Holder &pTrack={})
Definition: Track.cpp:858
void MakeMono()
Simply discard any right channel.
Definition: WaveTrack.cpp:1016

References anonymous_namespace{FloatVectorClip.cpp}::Duplicate(), and TrackList::Temporary().

Here is the call graph for this function:

◆ MoveTo()

void WaveTrack::MoveTo ( double  origin)
overridevirtual
Exception safety guarantee:
No-fail

Implements ChannelGroup.

Definition at line 566 of file WaveTrack.cpp.

567{
568 double delta = origin - GetStartTime();
569 for (const auto &pInterval : Intervals())
570 // assume No-fail-guarantee
571 pInterval->ShiftBy(delta);
572 WaveTrackData::Get(*this).SetOrigin(origin);
573}

References BasicUI::Get(), GetStartTime(), and Intervals().

Here is the call graph for this function:

◆ NarrowClips() [1/2]

WaveClipHolders & WaveTrack::NarrowClips ( )
private

Definition at line 751 of file WaveTrack.cpp.

752{
753 return mClips;
754}

References mClips.

Referenced by GetNumClips(), HandleXMLChild(), LinkConsistencyFix(), NIntervals(), and RemoveClip().

Here is the caller graph for this function:

◆ NarrowClips() [2/2]

const WaveClipHolders & WaveTrack::NarrowClips ( ) const
private

Definition at line 756 of file WaveTrack.cpp.

757{
758 return mClips;
759}

References mClips.

◆ NChannels()

size_t WaveTrack::NChannels ( ) const
overridevirtual

A constant property.

Postcondition
result: result > 0

Implements RecordableSequence.

Definition at line 532 of file WaveTrack.cpp.

533{
534 return mRightChannel.has_value() ? 2 : 1;
535}

References mRightChannel.

Referenced by Append(), AppendItem(), ProjectAudioManager::ChooseExistingRecordingTracks(), ClearAndPasteAtSameTempo(), Clone(), Copy(), EffectBase::CountWaveTracks(), Disjoin(), DoGet(), DoGetChannel(), anonymous_namespace{TrackMenus.cpp}::DoMixAndRender(), EffectSBSMS::Finalize(), CompareAudioCommand::GetSelection(), PasteWaveTrackAtSameTempo(), NyquistEffect::Process(), EffectReverse::Process(), anonymous_namespace{WaveTrackUtilities.cpp}::ReverseOneClip(), GetInfoCommand::SendTracks(), SwapChannels(), and ZipClips().

Here is the caller graph for this function:

◆ New()

WaveTrack * WaveTrack::New ( AudacityProject project)
static

Definition at line 488 of file WaveTrack.cpp.

489{
490 auto &trackFactory = WaveTrackFactory::Get( project );
491 auto &tracks = TrackList::Get( project );
492 auto result = tracks.Add(trackFactory.Create());
493 return result;
494}
const auto tracks
const auto project
static TrackList & Get(AudacityProject &project)
Definition: Track.cpp:314
static WaveTrackFactory & Get(AudacityProject &project)
Definition: WaveTrack.cpp:3349

References TrackList::Get(), WaveTrackFactory::Get(), project, and tracks.

Here is the call graph for this function:

◆ NewestOrNewClip()

auto WaveTrack::NewestOrNewClip ( )

Get access to the most recently added clip, or create a clip, if there is not already one. THIS IS NOT NECESSARILY RIGHTMOST.

Returns
a pointer to the most recently added WaveClip

Definition at line 2975 of file WaveTrack.cpp.

2976{
2977 const auto &intervals = Intervals();
2978 if (intervals.empty()) {
2979 const auto origin = WaveTrackData::Get(*this).GetOrigin();
2980 const auto name = MakeNewClipName();
2981 auto pInterval = CreateClip(origin, name);
2982 InsertInterval(pInterval, true, true);
2983 return pInterval;
2984 }
2985 else
2986 return mClips.back();
2987}
wxString MakeNewClipName() const
Definition: WaveTrack.cpp:781

References BasicUI::Get(), and name.

Referenced by GetIdealBlockSize(), HandleXMLChild(), and HandleXMLEndTag().

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

◆ NIntervals()

size_t WaveTrack::NIntervals ( ) const
overridevirtual

Report the number of intervals.

Implements ChannelGroup.

Definition at line 688 of file WaveTrack.cpp.

689{
690 return NarrowClips().size();
691}

References NarrowClips().

Referenced by DoGetInterval(), and Flush().

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

◆ Paste() [1/2]

virtual void Track::Paste ( double  t,
const Track src 
)
virtual

Weak precondition allows overrides to replicate one channel into many.

Precondition
SameKindAs(src)
src.NChannels() == 1 || src.NChannels() == NChannels()

Implements Track.

◆ Paste() [2/2]

void WaveTrack::Paste ( double  t0,
const Track src 
)
overridevirtual
Exception safety guarantee:
Weak

Implements Track.

Definition at line 1965 of file WaveTrack.cpp.

1966{
1967 if (const auto other = dynamic_cast<const WaveTrack*>(&src))
1968 {
1969 // Currently `Paste` isn't used by code that wants the newer "don't merge
1970 // when copy/pasting" behaviour ...
1971 constexpr auto merge = true;
1972 PasteWaveTrack(t0, *other, merge);
1973 }
1974 else
1975 // THROW_INCONSISTENCY_EXCEPTION; // ?
1976 (void)0;// Empty if intentional.
1977}

References PasteWaveTrack().

Referenced by EffectStereoToMono::ProcessOne(), and SyncLockAdjust().

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

◆ PasteInto()

Track::Holder WaveTrack::PasteInto ( AudacityProject project,
TrackList list 
) const
overridevirtual

Find or create the destination track for a paste, maybe in a different project

Parameters
listto which any newly created tracks are added; but left unchanged if an existing track is found in the project instead
Returns
A smart pointer to a track

Implements Track.

Definition at line 677 of file WaveTrack.cpp.

679{
680 auto &trackFactory = WaveTrackFactory::Get(project);
681 auto &pSampleBlockFactory = trackFactory.GetSampleBlockFactory();
682 auto pFirstTrack = EmptyCopy(pSampleBlockFactory);
683 list.Add(pFirstTrack->SharedPointer());
684 pFirstTrack->Paste(0.0, *this);
685 return pFirstTrack->SharedPointer();
686}
TrackKind * Add(const std::shared_ptr< TrackKind > &t, bool assignIds=true)
Definition: Track.h:1048

References TrackList::Add(), EmptyCopy(), WaveTrackFactory::Get(), and project.

Here is the call graph for this function:

◆ PasteWaveTrack()

void WaveTrack::PasteWaveTrack ( double  t0,
const WaveTrack other,
bool  merge 
)
private

Definition at line 1686 of file WaveTrack.cpp.

1687{
1688 // Get a modifiable copy of `src` because it may come from another project
1689 // with different tempo, making boundary queries incorrect.
1690 const auto& tempo = GetProjectTempo(*this);
1691 if (!tempo.has_value())
1693 const auto copyHolder = other.DuplicateWithOtherTempo(*tempo);
1694 PasteWaveTrackAtSameTempo(t0, *copyHolder, merge);
1695}
void PasteWaveTrackAtSameTempo(double t0, const WaveTrack &other, bool merge)
Definition: WaveTrack.cpp:1697

References DuplicateWithOtherTempo(), GetProjectTempo(), PasteWaveTrackAtSameTempo(), and THROW_INCONSISTENCY_EXCEPTION.

Referenced by ClearAndPasteAtSameTempo(), and Paste().

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

◆ PasteWaveTrackAtSameTempo()

void WaveTrack::PasteWaveTrackAtSameTempo ( double  t0,
const WaveTrack other,
bool  merge 
)
private

Definition at line 1697 of file WaveTrack.cpp.

1699{
1700 const auto otherNChannels = other.NChannels();
1701 assert(otherNChannels == NChannels());
1702 assert(
1703 GetProjectTempo(*this).has_value() &&
1704 GetProjectTempo(*this) == GetProjectTempo(other));
1705 const auto startTime = other.GetStartTime();
1706 const auto endTime = other.GetEndTime();
1707
1708 const auto insertDuration = endTime;
1709 auto &track = *this;
1710 //
1711 // Pasting is a bit complicated, because with the existence of multiclip mode,
1712 // we must guess the behaviour the user wants.
1713 //
1714 // Currently, two modes are implemented:
1715 //
1716 // - If a single clip should be pasted, and it should be pasted inside another
1717 // clip, no NEW clips are generated. The audio is simply inserted.
1718 // This resembles the old (pre-multiclip support) behaviour. However, if
1719 // the clip is pasted outside of any clip, a NEW clip is generated. This is
1720 // the only behaviour which is different to what was done before, but it
1721 // shouldn't confuse users too much.
1722 //
1723 // - If multiple clips should be pasted, or a single clip that does not fill
1724 // the duration of the pasted track, these are always pasted as single
1725 // clips, and the current clip is split, when necessary. This may seem
1726 // strange at first, but it probably is better than trying to auto-merge
1727 // anything. The user can still merge the clips by hand (which should be a
1728 // simple command reachable by a hotkey or single mouse click).
1729 //
1730
1731 if (other.GetNumClips() == 0)
1732 return;
1733
1734 t0 = track.SnapToSample(t0);
1735
1736 //wxPrintf("paste: we have at least one clip\n");
1737
1738 const auto clipAtT0 = track.GetIntervalAtTime(t0);
1739 const auto otherFirstClip = other.GetLeftmostClip();
1740 const auto otherLastClip = other.GetRightmostClip();
1741 const auto pitchAndSpeedMatch =
1742 !clipAtT0 || (clipAtT0->HasEqualPitchAndSpeed(*otherFirstClip) &&
1743 clipAtT0->HasEqualPitchAndSpeed(*otherLastClip));
1744
1745 // `singleClipMode` will try to merge. Only allow this if clips on both ends
1746 // of the selection have equal stretch ratio.
1747 const bool singleClipMode =
1748 other.GetNumClips() == 1 &&
1749 std::abs(startTime) < track.LongSamplesToTime(1) * 0.5 &&
1750 pitchAndSpeedMatch && merge;
1751
1752 const auto rate = track.GetRate();
1753 if (insertDuration != 0 && insertDuration < 1.0 / rate)
1754 // PRL: I added this check to avoid violations of preconditions in other WaveClip and Sequence
1755 // methods, but allow the value 0 so I don't subvert the purpose of commit
1756 // 739422ba70ceb4be0bb1829b6feb0c5401de641e which causes append-recording always to make
1757 // a new clip.
1758 return;
1759
1760 //wxPrintf("Check if we need to make room for the pasted data\n");
1761
1762 auto pastingFromTempTrack = !other.GetOwner();
1763 bool editClipCanMove = GetEditClipsCanMove();
1764
1765 const SimpleMessageBoxException notEnoughSpaceException {
1767 XO("There is not enough room available to paste the selection"),
1768 XO("Warning"), "Error:_Insufficient_space_in_track"
1769 };
1770
1771 // Make room for the pasted data
1772 if (editClipCanMove) {
1773 if (!singleClipMode)
1774 // We need to insert multiple clips, so split the current clip and ...
1775 track.SplitAt(t0);
1776
1777 //else if there is a clip at t0 insert new clip inside it and ...
1778
1779 // ... move everything to the right
1780 for (const auto& clip : track.Intervals())
1781 if (clip->GetPlayStartTime() > t0 - (1.0 / rate))
1782 clip->ShiftBy(insertDuration);
1783 }
1784 else
1785 {
1786 if (!merge)
1787 track.SplitAt(t0);
1788 const auto clipAtT0 = track.GetClipAtTime(t0);
1789 const auto t = clipAtT0 ? clipAtT0->GetPlayEndTime() : t0;
1790 if (!track.IsEmpty(t, t + insertDuration))
1791 throw notEnoughSpaceException;
1792 }
1793
1794 // See if the clipboard data is one clip only and if it should be merged. If
1795 // edit-clip-can-move mode is checked, merging happens only if the pasting
1796 // point splits a clip. If it isn't, merging also happens when the pasting
1797 // point is at the exact beginning of a clip.
1798 if (singleClipMode && merge) {
1799 // Single clip mode
1800 // wxPrintf("paste: checking for single clip mode!\n");
1801
1802 IntervalHolder insideClip{};
1803 for (const auto& clip : track.Intervals()) {
1804 if (editClipCanMove) {
1805 if (clip->SplitsPlayRegion(t0)) {
1806 //wxPrintf("t0=%.6f: inside clip is %.6f ... %.6f\n",
1807 // t0, clip->GetStartTime(), clip->GetEndTime());
1808 insideClip = clip;
1809 break;
1810 }
1811 }
1812 else {
1813 // If clips are immovable we also allow prepending to clips
1814 if (clip->WithinPlayRegion(t0))
1815 {
1816 insideClip = clip;
1817 break;
1818 }
1819 }
1820 }
1821
1822 if (insideClip) {
1823 // Exhibit traditional behaviour
1824 //wxPrintf("paste: traditional behaviour\n");
1825 if (!editClipCanMove) {
1826 // We did not move other clips out of the way already, so
1827 // check if we can paste without having to move other clips
1828 for (const auto& clip : track.Intervals()) {
1829 if (clip->GetPlayStartTime() > insideClip->GetPlayStartTime() &&
1830 insideClip->GetPlayEndTime() + insertDuration >
1831 clip->GetPlayStartTime())
1832 // Strong-guarantee in case of this path
1833 // not that it matters.
1834 throw notEnoughSpaceException;
1835 }
1836 }
1837 if (auto pClip = other.GetClip(0)) {
1838 // This branch only gets executed in `singleClipMode` - we've
1839 // already made sure that stretch ratios are equal, satisfying
1840 // `WaveClip::Paste`'s precondition.
1841 assert(insideClip->GetStretchRatio() == pClip->GetStretchRatio());
1842 // This too should follow from the assertion of the same number
1843 // of channels in the tracks, near the top
1844 assert(insideClip->NChannels() == pClip->NChannels());
1845 bool success = insideClip->Paste(t0, *pClip);
1846 assert(success);
1847 }
1848 return;
1849 }
1850 // Just fall through and exhibit NEW behaviour
1851 }
1852
1853 // Insert NEW clips
1854 //wxPrintf("paste: multi clip mode!\n");
1855
1856 if (!editClipCanMove &&
1857 !track.IsEmpty(t0, t0 + insertDuration - 1.0 / rate))
1858 // Strong-guarantee in case of this path
1859 // not that it matters.
1860 throw notEnoughSpaceException;
1861
1862 for (const auto& clip : other.Intervals()) {
1863 // AWD Oct. 2009: Don't actually paste in placeholder clips
1864 if (!clip->GetIsPlaceholder()) {
1865 const auto name = (pastingFromTempTrack)
1866 //Clips from the tracks which aren't bound to any TrackList are
1867 //considered to be new entities, thus named using "new" name template
1868 ? track.MakeNewClipName()
1869 : track.MakeClipCopyName(clip->GetName());
1870 const auto oldPlayStart = clip->GetPlayStartTime();
1871 const auto newSequenceStart =
1872 (oldPlayStart + t0) - clip->GetTrimLeft();
1873 const auto newClip = CreateClip(newSequenceStart, name, clip.get());
1874 newClip->Resample(rate);
1875 track.InsertInterval(move(newClip), false);
1876 }
1877 }
1878}
@ BadUserAction
Indicates that the user performed an action that is not allowed.
A MessageBoxException that shows a given, unvarying string.

References BadUserAction, CreateClip(), GetClip(), GetEditClipsCanMove(), GetEndTime(), GetLeftmostClip(), GetNumClips(), Track::GetOwner(), GetProjectTempo(), GetRightmostClip(), GetStartTime(), Intervals(), name, NChannels(), and XO().

Referenced by PasteWaveTrack().

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

◆ ProjectNyquistFrequency()

double WaveTrack::ProjectNyquistFrequency ( const AudacityProject project)
static

Definition at line 358 of file WaveTrack.cpp.

359{
361 return std::max(ProjectRate::Get(project).GetRate(),
362 tracks.Any<const WaveTrack>().max(&WaveTrack::GetRate))
363 / 2.0;
364}
static ProjectRate & Get(AudacityProject &project)
Definition: ProjectRate.cpp:28

References ProjectRate::Get(), TrackList::Get(), GetRate(), project, and tracks.

Referenced by SelectFrequenciesCommand::Apply(), and SpectralSelectionBar::ModifySpectralSelection().

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

◆ RateConsistencyCheck()

bool WaveTrack::RateConsistencyCheck ( ) const
private

Whether all clips of an unzipped leader track have a common rate.

Definition at line 1880 of file WaveTrack.cpp.

1881{
1882 // The channels and all clips in them should have the same sample rate.
1883 std::optional<double> oRate;
1884 auto channels = TrackList::Channels(this);
1885 return std::all_of(channels.begin(), channels.end(),
1886 [&](const WaveTrack *pTrack){
1887 if (!pTrack)
1888 return false;
1889
1890 const auto rate = pTrack->mLegacyRate;
1891 if (!oRate)
1892 oRate = rate;
1893 else if (*oRate != rate)
1894 return false;
1895 return true;
1896 });
1897}

References TrackList::Channels().

Referenced by LinkConsistencyFix().

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

◆ RemoveClip()

void WaveTrack::RemoveClip ( std::ptrdiff_t  distance)
private

Definition at line 1519 of file WaveTrack.cpp.

1520{
1521 auto &clips = NarrowClips();
1522 if (distance < clips.size())
1523 clips.erase(clips.begin() + distance);
1524}

References NarrowClips().

Referenced by Join().

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

◆ RemoveInterval()

void WaveTrack::RemoveInterval ( const IntervalHolder interval)

Definition at line 3219 of file WaveTrack.cpp.

3220{
3221 const auto end = mClips.end(),
3222 iter = find(mClips.begin(), end, interval);
3223 if (iter != end)
3224 mClips.erase(iter);
3225}

References details::end(), and mClips.

Referenced by HandleClear(), MergeClips(), ReplaceInterval(), and WaveTrackUtilities::Reverse().

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

◆ RepairChannels()

void WaveTrack::RepairChannels ( )
overridevirtual

Called in exception handling after possibly unbalanced calls to Append in different channels. Allows the sequence to repair consistency.

Implements RecordableSequence.

Definition at line 2302 of file WaveTrack.cpp.

2303{
2304 for (auto pInterval : Intervals())
2305 pInterval->RepairChannels();
2306}

References Intervals().

Here is the call graph for this function:

◆ ReplaceInterval()

void WaveTrack::ReplaceInterval ( const IntervalHolder oldOne,
const IntervalHolder newOne 
)
private
Precondition
oldOne->NChannels() == newOne->NChannels()
newOne and oldOne are the same, or else newOne is not already owned by this or any other track

Definition at line 3227 of file WaveTrack.cpp.

3229{
3230 assert(newOne == oldOne || FindClip(*newOne) == Intervals().size());
3231 assert(oldOne->NChannels() == newOne->NChannels());
3232 RemoveInterval(oldOne);
3233 InsertInterval(newOne, false);
3234 newOne->SetName(oldOne->GetName());
3235}
size_t size() const
How many attachment pointers are in the Site.
Definition: ClientData.h:260

References FindClip(), InsertInterval(), Intervals(), RemoveInterval(), and ClientData::Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy >::size().

Referenced by ApplyPitchAndSpeedOnIntervals().

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

◆ Resample()

void WaveTrack::Resample ( int  rate,
BasicUI::ProgressDialog progress = NULL 
)
Exception safety guarantee:
Weak – Partial completion may leave clips at differing sample rates!

Definition at line 3239 of file WaveTrack.cpp.

3240{
3241 for (const auto &pClip : Intervals())
3242 pClip->Resample(rate, progress);
3243 DoSetRate(rate);
3244}

References DoSetRate(), and Intervals().

Here is the call graph for this function:

◆ RightmostOrNewClip()

auto WaveTrack::RightmostOrNewClip ( )

Get access to the last (rightmost) clip, or create a clip, if there is not already one.

Returns
a pointer to a WaveClip at the end of the track
Exception safety guarantee:
No-fail

Definition at line 2990 of file WaveTrack.cpp.

2991{
2992 if (mClips.empty()) {
2993 auto pInterval = CreateClip(
2994 WaveTrackData::Get(*this).GetOrigin(), MakeNewClipName());
2995 InsertInterval(pInterval, true, true);
2996 return pInterval;
2997 }
2998 else {
2999 auto end = mClips.end(),
3000 it = max_element(mClips.begin(), end,
3001 [](const auto &pClip1, const auto &pClip2){
3002 return pClip1->GetPlayStartTime() < pClip2->GetPlayStartTime();
3003 });
3004 assert(it != end);
3005 return *it;
3006 }
3007}

References details::end(), and BasicUI::Get().

Referenced by AUPImportFileHandle::AddSamples(), Append(), and AUPImportFileHandle::HandleEnvelope().

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

◆ SetFloats()

bool WaveTrack::SetFloats ( const float *const *  buffers,
sampleCount  start,
size_t  len,
sampleFormat  effectiveFormat = widestSampleFormat 
)

Random-access assignment of a range of samples.

Parameters
buffersa span of pointers of size NChannels()
Precondition
each of buffers is non-null
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 3246 of file WaveTrack.cpp.

3248{
3249 bool result = true;
3250 size_t ii = 0;
3251 for (const auto &pChannel : Channels()) {
3252 const auto buffer = buffers[ii++];
3253 assert(buffer); // precondition
3254 result = pChannel->SetFloats(buffer, start, len, effectiveFormat)
3255 && result;
3256 }
3257 return result;
3258}

References Channels().

Referenced by anonymous_namespace{WaveTrackUtilities.cpp}::ReverseOneClip().

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

◆ SetGain()

void WaveTrack::SetGain ( float  newGain)

Definition at line 829 of file WaveTrack.cpp.

830{
831 if (GetGain() != newGain) {
832 DoSetGain(newGain);
833 Notify(true);
834 }
835}
void Notify(bool allChannels, int code=-1)
Definition: Track.cpp:234

References DoSetGain(), GetGain(), and Track::Notify().

Referenced by MixerTrackCluster::HandleSliderGain(), and anonymous_namespace{TrackMenus.cpp}::SetTrackGain().

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

◆ SetLegacyFormat()

void WaveTrack::SetLegacyFormat ( sampleFormat  format)

Definition at line 2308 of file WaveTrack.cpp.

2309{
2311}

References anonymous_namespace{ExportPCM.cpp}::format, and mLegacyFormat.

Referenced by AUPImportFileHandle::HandleXMLEndTag(), and HandleXMLTag().

Here is the caller graph for this function:

◆ SetPan()

void WaveTrack::SetPan ( float  newPan)

Definition at line 847 of file WaveTrack.cpp.

848{
849 if (newPan > 1.0)
850 newPan = 1.0;
851 else if (newPan < -1.0)
852 newPan = -1.0;
853
854 if ( GetPan() != newPan ) {
855 DoSetPan(newPan);
856 Notify(true);
857 }
858}

References DoSetPan(), GetPan(), and Track::Notify().

Referenced by MixerTrackCluster::HandleSliderPan(), WaveTrackMenuTable::OnMergeStereo(), and anonymous_namespace{TrackMenus.cpp}::SetTrackPan().

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

◆ SetRate()

void WaveTrack::SetRate ( double  newRate)

!brief Sets the new rate for the track without resampling it

Precondition
newRate > 0

Definition at line 803 of file WaveTrack.cpp.

804{
805 assert(newRate > 0);
806 newRate = std::max( 1.0, newRate );
807 DoSetRate(newRate);
808
809 for (const auto &clip : Intervals())
810 clip->SetRate(newRate);
811}

References DoSetRate(), and Intervals().

Referenced by LinkConsistencyFix(), and RateMenuTable::SetRate().

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

◆ Silence()

void WaveTrack::Silence ( double  t0,
double  t1,
ProgressReporter  reportProgress 
)
overridevirtual

Implements Track.

Definition at line 1979 of file WaveTrack.cpp.

1980{
1981 if (t1 < t0)
1983
1984 ApplyPitchAndSpeed({ { t0, t1 } }, std::move(reportProgress));
1985
1986 auto start = TimeToLongSamples(t0);
1987 auto end = TimeToLongSamples(t1);
1988
1989 for (const auto &pClip : Intervals()) {
1990 auto clipStart = pClip->GetPlayStartSample();
1991 auto clipEnd = pClip->GetPlayEndSample();
1992 if (clipEnd > start && clipStart < end) {
1993 auto offset = std::max(start - clipStart, sampleCount(0));
1994 // Clip sample region and Get/Put sample region overlap
1995 auto length = std::min(end, clipEnd) - (clipStart + offset);
1996 pClip->SetSilence(offset, length);
1997 }
1998 }
1999}
void ApplyPitchAndSpeed(std::optional< TimeInterval > interval, ProgressReporter reportProgress)
Definition: WaveTrack.cpp:1924

References ApplyPitchAndSpeed(), details::end(), Intervals(), min(), THROW_INCONSISTENCY_EXCEPTION, and WideSampleSequence::TimeToLongSamples().

Referenced by anonymous_namespace{LabelMenus.cpp}::OnSilenceLabels(), anonymous_namespace{EditMenus.cpp}::OnSplitCut(), and anonymous_namespace{LabelMenus.cpp}::OnSplitDeleteLabels().

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

◆ SortedClipArray()

auto WaveTrack::SortedClipArray ( ) const
private

Return all WaveClips sorted by clip play start time.

Definition at line 3260 of file WaveTrack.cpp.

3261{
3262 const auto &intervals = Intervals();
3263 IntervalConstHolders clips{ intervals.begin(), intervals.end() };
3264 const auto comp = [](const auto &a, const auto &b) {
3265 return a->GetPlayStartTime() < b->GetPlayStartTime(); };
3266 std::sort(clips.begin(), clips.end(), comp);
3267 return clips;
3268}
std::vector< IntervalConstHolder > IntervalConstHolders
Definition: WaveTrack.h:212

References Intervals().

Referenced by LinkConsistencyFix(), and ZipClips().

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

◆ SortedIntervalArray() [1/2]

auto WaveTrack::SortedIntervalArray ( )

Return all WaveClips sorted by clip play start time.

Definition at line 3270 of file WaveTrack.cpp.

3271{
3272 const auto &intervals = Intervals();
3273 IntervalHolders result;
3274 copy(intervals.begin(), intervals.end(), back_inserter(result));
3275 sort(result.begin(), result.end(), [](const auto &pA, const auto &pB){
3276 return pA->GetPlayStartTime() < pB->GetPlayStartTime(); });
3277 return result;
3278}
void copy(const T *src, T *dst, int32_t n)
Definition: VectorOps.h:40

References staffpad::vo::copy().

Referenced by SetEnvelopeCommand::ApplyInner(), EffectSBSMS::Finalize(), anonymous_namespace{ClipMenus.cpp}::FindNextClip(), anonymous_namespace{ClipMenus.cpp}::FindNextClipBoundary(), anonymous_namespace{ClipMenus.cpp}::FindPrevClip(), anonymous_namespace{ClipMenus.cpp}::FindPrevClipBoundary(), FindWaveTrackLocations(), anonymous_namespace{Nyquist.cpp}::GetClipBoundaries(), WaveTrackUtilities::Reverse(), and GetInfoCommand::SendEnvelopes().

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

◆ SortedIntervalArray() [2/2]

auto WaveTrack::SortedIntervalArray ( ) const

Return all WaveClips sorted by clip play start time.

Definition at line 3280 of file WaveTrack.cpp.

3281{
3282 const auto &intervals = Intervals();
3283 IntervalConstHolders result;
3284 copy(intervals.begin(), intervals.end(), back_inserter(result));
3285 sort(result.begin(), result.end(), [](const auto &pA, const auto &pB){
3286 return pA->GetPlayStartTime() < pB->GetPlayStartTime(); });
3287 return result;
3288}

References staffpad::vo::copy(), and Intervals().

Here is the call graph for this function:

◆ Split()

void WaveTrack::Split ( double  t0,
double  t1 
)
Exception safety guarantee:
Weak

Definition at line 3130 of file WaveTrack.cpp.

3131{
3132 SplitAt(t0);
3133 if (t0 != t1)
3134 SplitAt(t1);
3135}
std::pair< IntervalHolder, IntervalHolder > SplitAt(double t)
Definition: WaveTrack.cpp:3138

References SplitAt().

Referenced by ApplyPitchAndSpeed(), and anonymous_namespace{LabelMenus.cpp}::OnSplitLabels().

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

◆ SplitAt()

auto WaveTrack::SplitAt ( double  t)
Exception safety guarantee:
Weak

Definition at line 3138 of file WaveTrack.cpp.

3139{
3140 for (const auto &&c : Intervals()) {
3141 if (c->SplitsPlayRegion(t)) {
3142 t = SnapToSample(t);
3143 auto newClip = CopyClip(*c, true);
3144 c->TrimRightTo(t);// put t on a sample
3145 newClip->TrimLeftTo(t);
3146 auto result = std::pair{ c, newClip };
3147
3148 // This could invalidate the iterators for the loop! But we return
3149 // at once so it's okay
3150 InsertInterval(move(newClip), false); // transfer ownership
3151 return result;
3152 }
3153 }
3154 return {};
3155}

Referenced by WaveTrackUtilities::Reverse(), and Split().

Here is the caller graph for this function:

◆ SplitChannels()

auto WaveTrack::SplitChannels ( )

Definition at line 1041 of file WaveTrack.cpp.

1042{
1043 std::vector<Holder> result{ SharedPointer<WaveTrack>() };
1044 if (NChannels() == 2) {
1045 auto pOwner = GetOwner();
1046 assert(pOwner); // pre
1047 auto pNewTrack = result.emplace_back(EmptyCopy(1));
1048 for (auto &pClip : mClips)
1049 pNewTrack->mClips.emplace_back(pClip->SplitChannels());
1050 this->mRightChannel.reset();
1051 auto iter = pOwner->Find(this);
1052 pOwner->Insert(*++iter, pNewTrack);
1053 // Fix up the channel attachments to avoid waste of space
1054 result[0]->EraseChannelAttachments(1);
1055 result[1]->EraseChannelAttachments(0);
1056 }
1057 return result;
1058}

Referenced by WaveTrackMenuTable::SplitStereo().

Here is the caller graph for this function:

◆ SplitCut()

auto WaveTrack::SplitCut ( double  t0,
double  t1 
)
Postcondition
result: result->NChannels() == NChannels()
Exception safety guarantee:
Strong

Definition at line 943 of file WaveTrack.cpp.

944{
945 if (t1 < t0)
947
948 // SplitCut is the same as 'Copy', then 'SplitDelete'
949 auto result = Copy(t0, t1);
950 SplitDelete(t0, t1);
951 return std::static_pointer_cast<WaveTrack>(result);
952}

References THROW_INCONSISTENCY_EXCEPTION.

Referenced by anonymous_namespace{EditMenus.cpp}::OnSplitCut(), and anonymous_namespace{LabelMenus.cpp}::OnSplitCutLabels().

Here is the caller graph for this function:

◆ SplitDelete()

void WaveTrack::SplitDelete ( double  t0,
double  t1 
)
Exception safety guarantee:
Strong

Definition at line 1503 of file WaveTrack.cpp.

1504{
1505 constexpr bool addCutLines = false;
1506 constexpr bool split = true;
1507 HandleClear(t0, t1, addCutLines, split);
1508}

References HandleClear().

Referenced by Disjoin(), EffectSBSMS::Finalize(), anonymous_namespace{EditMenus.cpp}::OnSplitDelete(), anonymous_namespace{LabelMenus.cpp}::OnSplitDeleteLabels(), anonymous_namespace{EditMenus.cpp}::OnSplitNew(), and Trim().

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

◆ SwapChannels()

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

Definition at line 1060 of file WaveTrack.cpp.

1061{
1062 assert(NChannels() == 2);
1063 for (const auto &pClip: mClips)
1064 pClip->SwapChannels();
1065 this->AttachedTrackObjects::ForEach([this](TrackAttachment &attachment){
1066 if (const auto pAttachments =
1067 dynamic_cast<ChannelAttachmentsBase *>(&attachment)) {
1068 pAttachments->SwapChannels(shared_from_this());
1069 }
1070 });
1071}

References ClientData::Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy >::ForEach(), mClips, and NChannels().

Referenced by WaveTrackMenuTable::OnSwapChannels().

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

◆ SyncLockAdjust()

void WaveTrack::SyncLockAdjust ( double  oldT1,
double  newT1 
)
overridevirtual

This can be used to adjust a sync-lock selected track when the selection is replaced by one of a different length.

Reimplemented from Track.

Definition at line 1648 of file WaveTrack.cpp.

1649{
1650 const auto endTime = GetEndTime();
1651 if (newT1 > oldT1 &&
1652 // JKC: This is a rare case where using >= rather than > on a float matters.
1653 // GetEndTime() looks through the clips and may give us EXACTLY the same
1654 // value as T1, when T1 was set to be at the end of one of those clips.
1655 oldT1 >= endTime)
1656 return;
1657 if (newT1 > oldT1) {
1658 // Insert space within the track
1659
1660 // If track is empty at oldT1 insert whitespace; otherwise, silence
1661 if (IsEmpty(oldT1, oldT1)) {
1662 // Check if clips can move
1663 if (EditClipsCanMove.Read()) {
1664 const auto offset = newT1 - oldT1;
1665 const auto rate = GetRate();
1666 for (const auto &clip : Intervals())
1667 if (clip->GetPlayStartTime() > oldT1 - (1.0 / rate))
1668 clip->ShiftBy(offset);
1669 }
1670 return;
1671 }
1672 else {
1673 // AWD: Could just use InsertSilence() on its own here, but it doesn't
1674 // follow EditClipCanMove rules (Paste() does it right)
1675 const auto duration = newT1 - oldT1;
1676 auto tmp = EmptyCopy(mpFactory);
1677 tmp->InsertSilence(0.0, duration);
1678 tmp->Flush();
1679 Paste(oldT1, *tmp);
1680 }
1681 }
1682 else if (newT1 < oldT1)
1683 Clear(newT1, oldT1);
1684}
BoolSetting EditClipsCanMove
Definition: WaveTrack.cpp:3390
bool Read(T *pVar) const
overload of Read returning a boolean that is true if the value was previously defined *‍/
Definition: Prefs.h:207
bool IsEmpty(double t0, double t1) const
Returns true if there are no WaveClips in the specified region.
Definition: WaveTrack.cpp:910

References Clear(), EditClipsCanMove, EmptyCopy(), GetEndTime(), GetRate(), Intervals(), IsEmpty(), mpFactory, Paste(), and Setting< T >::Read().

Here is the call graph for this function:

◆ Trim()

void WaveTrack::Trim ( double  t0,
double  t1 
)
Exception safety guarantee:
Weak

Definition at line 957 of file WaveTrack.cpp.

958{
959 bool inside0 = false;
960 bool inside1 = false;
961
962 for (const auto &clip : Intervals()) {
963 if (t1 > clip->GetPlayStartTime() && t1 < clip->GetPlayEndTime()) {
964 clip->SetTrimRight(
965 clip->GetTrimRight() + clip->GetPlayEndTime() - t1);
966 inside1 = true;
967 }
968
969 if (t0 > clip->GetPlayStartTime() && t0 < clip->GetPlayEndTime()) {
970 clip->SetTrimLeft(
971 clip->GetTrimLeft() + t0 - clip->GetPlayStartTime());
972 inside0 = true;
973 }
974 }
975
976 //if inside0 is false, then the left selector was between
977 //clips, so DELETE everything to its left.
978 if (const auto endTime = GetEndTime()
979 ; !inside1 && t1 < endTime
980 )
981 Clear(t1, endTime);
982
983 if (const auto startTime = GetStartTime()
984 ; !inside0 && t0 > startTime
985 )
986 SplitDelete(startTime, t0);
987}

References Clear(), GetEndTime(), GetStartTime(), Intervals(), and SplitDelete().

Referenced by anonymous_namespace{EditMenus.cpp}::OnTrim().

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

◆ WidestEffectiveFormat()

sampleFormat WaveTrack::WidestEffectiveFormat ( ) const
overridevirtual
Returns
widest effective SampleFormat in any part of the track

Implements WideSampleSequence.

Definition at line 2818 of file WaveTrack.cpp.

2819{
2820 auto result = narrowestSampleFormat;
2821 for (const auto &pClip : Intervals())
2822 result = std::max(result, pClip->GetSampleFormats().Effective());
2823 return result;
2824}
@ narrowestSampleFormat
Two synonyms for previous values that might change if more values were added.

References Intervals(), and narrowestSampleFormat.

Referenced by WaveChannel::WidestEffectiveFormat().

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

◆ WriteOneXML()

void WaveTrack::WriteOneXML ( const WaveChannel channel,
XMLWriter xmlFile,
size_t  iChannel,
size_t  nChannels 
)
staticprivate

Definition at line 2462 of file WaveTrack.cpp.

2465{
2466 // Track data has always been written using channel-major iteration.
2467 // Do it still this way for compatibility.
2468
2469 // Some values don't vary independently in channels but have been written
2470 // redundantly for each channel. Keep doing this in 3.4 and later in case
2471 // a project is opened in an earlier version.
2472
2473 xmlFile.StartTag(WaveTrack_tag);
2474 auto &track = channel.GetTrack();
2475
2476 // Name, selectedness, etc. are channel group properties
2477 track.Track::WriteCommonXMLAttributes(xmlFile);
2478
2479 // Write the "channel" attribute so earlier versions can interpret stereo
2480 // tracks, but this version doesn't read it
2481 {
2482 enum ChannelType {
2483 LeftChannel = 0,
2484 RightChannel = 1,
2485 MonoChannel = 2
2486 };
2487 const auto channelType = (nChannels == 0)
2488 ? MonoChannel
2489 : (iChannel == 0)
2490 ? LeftChannel
2491 : RightChannel;
2492 xmlFile.WriteAttr(Channel_attr, channelType);
2493 }
2494
2495 // The "linked" flag is used to define the beginning of a channel group
2496 // that isn't mono
2497 const auto linkType = static_cast<int>(
2498 (iChannel == 0) && (nChannels == 2)
2500 : LinkType::None);
2501 xmlFile.WriteAttr(Linked_attr, linkType);
2502
2503 // More channel group properties written redundantly
2504 track.WritableSampleTrack::WriteXMLAttributes(xmlFile);
2505 xmlFile.WriteAttr(Rate_attr, track.GetRate());
2506 xmlFile.WriteAttr(Gain_attr, static_cast<double>(track.GetGain()));
2507 xmlFile.WriteAttr(Pan_attr, static_cast<double>(track.GetPan()));
2508 xmlFile.WriteAttr(SampleFormat_attr, static_cast<long>(track.GetSampleFormat()));
2509
2510 // Other persistent data specified elsewhere;
2511 // NOT written redundantly any more
2512 if (iChannel == 0)
2513 WaveTrackIORegistry::Get().CallWriters(track, xmlFile);
2514
2515 for (const auto &clip : channel.Intervals())
2516 clip->WriteXML(xmlFile);
2517
2518 xmlFile.EndTag(WaveTrack_tag);
2519}
static constexpr auto Channel_attr
Definition: WaveTrack.cpp:2336
WaveTrack & GetTrack()
Definition: WaveTrack.h:840
IteratorRange< IntervalIterator< WaveClipChannel > > Intervals()
Definition: WaveTrack.cpp:745
void CallWriters(const Host &host, XMLWriter &writer)
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
ChannelType
Mutually exclusive channel classifications.

References ChannelGroup::Aligned, XMLMethodRegistry< Host >::CallWriters(), Channel_attr, XMLWriter::EndTag(), Gain_attr, XMLMethodRegistry< Host >::Get(), WaveChannel::GetTrack(), anonymous_namespace{StretchingSequenceIntegrationTest.cpp}::iChannel, WaveChannel::Intervals(), AudioGraph::LeftChannel, Linked_attr, AudioGraph::MonoChannel, ChannelGroup::None, Pan_attr, Rate_attr, AudioGraph::RightChannel, SampleFormat_attr, XMLWriter::StartTag(), WaveTrack_tag, and XMLWriter::WriteAttr().

Here is the call graph for this function:

◆ WriteXML()

void WaveTrack::WriteXML ( XMLWriter xmlFile) const
overridevirtual

Implements Track.

Definition at line 2452 of file WaveTrack.cpp.

2454{
2455 const auto channels = Channels();
2456 size_t iChannel = 0,
2457 nChannels = channels.size();
2458 for (const auto pChannel : channels)
2459 WriteOneXML(*pChannel, xmlFile, iChannel++, nChannels);
2460}
static void WriteOneXML(const WaveChannel &channel, XMLWriter &xmlFile, size_t iChannel, size_t nChannels)
Definition: WaveTrack.cpp:2462

References anonymous_namespace{StretchingSequenceIntegrationTest.cpp}::iChannel.

◆ ZipClips()

void WaveTrack::ZipClips ( bool  mustAlign = true)

Convert channel-major storage to interval-major, replacing two tracks with one in the owning TrackList

Precondition
GetOwner()
next track in the list exists, is a WaveTrack, has one channel only
NChannels() == 1
if mustAlign, then clips are aligned across the tracks
Parameters
mustAlignif false, clips may be of different number or not aligned. Do not use the resulting track normally!

Refuse if clips are not well aligned.

Definition at line 3290 of file WaveTrack.cpp.

3291{
3292 const auto pOwner = GetOwner();
3293 assert(GetOwner()); // pre
3294 assert(NChannels() == 1); // pre
3295
3296 // If deserializing, first un-link the track, so iterator finds the partner.
3298
3299 auto iter = pOwner->Find(this);
3300 assert(this == *iter);
3301 ++iter;
3302 assert(iter != pOwner->end()); // pre
3303 auto pRight = dynamic_cast<WaveTrack*>(*iter);
3304 assert(pRight && pRight->NChannels() == 1); // pre
3305
3307 if (mustAlign &&
3308 !AreAligned(this->SortedClipArray(), pRight->SortedClipArray()))
3309 return;
3310
3311 CreateRight();
3312
3313 // Now steal right side sample data info. When not requiring alignment,
3314 // because this is a track that just keeps the sample counts of blocks
3315 // above 0 for later purposes -- then there is laxity about consistent
3316 // width of the clips.
3317 auto iterMe = mClips.begin(),
3318 endMe = mClips.end();
3319 auto iterRight = pRight->mClips.begin(),
3320 endRight = pRight->mClips.end();
3321 while (iterMe != endMe && iterRight != endRight) {
3322 (*iterMe)->MakeStereo(std::move(**iterRight), mustAlign);
3323 ++iterMe;
3324 ++iterRight;
3325 }
3326 assert(!mustAlign || (iterMe == endMe && iterRight == endRight));
3327
3328 while (iterRight != endRight) {
3329 // Leftover misaligned mono clips
3330 mClips.emplace_back(move(*iterRight));
3331 ++iterRight;
3332 }
3333
3334 this->MergeChannelAttachments(std::move(*pRight));
3335
3336 pOwner->Remove(*pRight);
3337}
void CreateRight()
Definition: WaveTrack.cpp:2955
void MergeChannelAttachments(WaveTrack &&other)
Definition: WaveTrack.cpp:431

References anonymous_namespace{WaveTrack.cpp}::anonymous_namespace{WaveTrack.cpp}::AreAligned(), CreateRight(), Track::GetOwner(), mClips, MergeChannelAttachments(), NChannels(), ChannelGroup::None, Track::SetLinkType(), and SortedClipArray().

Referenced by LinkConsistencyFix(), PerTrackEffect::ProcessPass(), and ProjectFileManager::ReadProjectFile().

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

Friends And Related Function Documentation

◆ WaveTrackFactory

friend class WaveTrackFactory
friend

Definition at line 280 of file WaveTrack.h.

Member Data Documentation

◆ mAppendCriticalSection

wxCriticalSection WaveTrack::mAppendCriticalSection
private

Definition at line 832 of file WaveTrack.h.

◆ mChannel

WaveChannel WaveTrack::mChannel
private
Invariant
non-null

Definition at line 767 of file WaveTrack.h.

Referenced by DoGetChannel().

◆ mClips

WaveClipHolders WaveTrack::mClips
private

Do not call mClips.push_back directly. Use InsertClip instead.

Invariant
all are non-null

Definition at line 775 of file WaveTrack.h.

Referenced by DoGet(), DoGetInterval(), InsertInterval(), MakeMono(), NarrowClips(), RemoveInterval(), SwapChannels(), and ZipClips().

◆ mFlushCriticalSection

wxCriticalSection WaveTrack::mFlushCriticalSection
private

Definition at line 831 of file WaveTrack.h.

◆ mLegacyFormat

sampleFormat WaveTrack::mLegacyFormat { undefinedSample }
private

used only during deserialization

Definition at line 778 of file WaveTrack.h.

Referenced by HandleXMLChild(), LinkConsistencyFix(), and SetLegacyFormat().

◆ mLegacyProjectFileOffset

double WaveTrack::mLegacyProjectFileOffset { 0 }
private

Definition at line 833 of file WaveTrack.h.

Referenced by HandleXMLChild(), and HandleXMLTag().

◆ mLegacyRate

int WaveTrack::mLegacyRate { 0 }
mutableprivate

used only during deserialization

Definition at line 777 of file WaveTrack.h.

Referenced by HandleXMLChild(), HandleXMLTag(), and LinkConsistencyFix().

◆ mpFactory

SampleBlockFactoryPtr WaveTrack::mpFactory
private

Definition at line 829 of file WaveTrack.h.

Referenced by EmptyCopy(), GetMaxBlockSize(), HandleXMLChild(), Init(), and SyncLockAdjust().

◆ mRightChannel

std::optional<WaveChannel> WaveTrack::mRightChannel
private

may be null

Definition at line 769 of file WaveTrack.h.

Referenced by CreateRight(), DoGetChannel(), MakeMono(), and NChannels().

◆ WaveChannel

friend WaveTrack::WaveChannel
private

Definition at line 835 of file WaveTrack.h.

◆ WaveTrack_tag

const char * WaveTrack::WaveTrack_tag = "wavetrack"
static

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