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

class  AllClipsConstIterator
 
class  AllClipsIterator
 
class  IntervalData
 
struct  Region
 Structure to hold region of a wavetrack and a comparison function for sortability. More...
 

Public Types

using Regions = std::vector< Region >
 
using Holder = std::shared_ptr< WaveTrack >
 
- Public Types inherited from SampleTrack
using Attachments = SampleTrackAttachments
 
- Public Types inherited from Track
enum class  LinkType : int { None = 0 , Group = 2 , Aligned }
 For two tracks describes the type of the linkage. More...
 
using ChannelGroupAttachments = ClientData::Site< ChannelGroupData, ClientData::Cloneable<>, ClientData::DeepCopying >
 Hosting of objects attached by higher level code. More...
 
using AttachedObjects = ::AttachedTrackObjects
 Alias for my base type. More...
 
using IntervalData = TrackIntervalData
 
using Interval = TrackInterval
 
using Intervals = std::vector< Interval >
 
using ConstInterval = ConstTrackInterval
 
using ConstIntervals = std::vector< ConstInterval >
 
using Holder = std::shared_ptr< Track >
 
template<typename R = void>
using Continuation = std::function< R() >
 Type of arguments passed as optional second parameter to TypeSwitch() cases. More...
 
using Fallthrough = Continuation<>
 Type of arguments passed as optional second parameter to TypeSwitch<void>() cases. More...
 
- 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 Member Functions

 WaveTrack (const SampleBlockFactoryPtr &pFactory, sampleFormat format, double rate)
 
 WaveTrack (const WaveTrack &orig, ProtectedCreationArg &&)
 Copied only in WaveTrack::Clone() ! More...
 
void Reinit (const WaveTrack &orig)
 
virtual ~WaveTrack ()
 
double GetOffset () const override
 
void SetOffset (double o) override
 
bool LinkConsistencyFix (bool doFix, bool completeList) override
 Check consistency of channel groups, and maybe fix it. More...
 
double GetStartTime () const override
 Get the time at which the first clip in the track starts. More...
 
double GetEndTime () const override
 Get the time at which the last clip in the track ends, plus recorded stuff. More...
 
double GetRate () const override
 
void SetRate (double newRate)
 
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...
 
int GetWaveColorIndex () const
 
void SetWaveColorIndex (int colorIndex)
 
sampleCount GetPlaySamplesCount () const
 
sampleCount GetSequenceSamplesCount () const
 
sampleFormat GetSampleFormat () const override
 
void ConvertToSampleFormat (sampleFormat format, const std::function< void(size_t)> &progressReport={})
 
Track::Holder Cut (double t0, double t1) override
 
Holder EmptyCopy (const SampleBlockFactoryPtr &pFactory={}, bool keepLink=true) const
 
Track::Holder Copy (double t0, double t1, bool forClipboard=true) const override
 
Track::Holder CopyNonconst (double t0, double t1)
 
void Clear (double t0, double t1) override
 
void Paste (double t0, const Track *src) override
 
void ClearAndPaste (double t0, double t1, const Track *src, bool preserve=true, bool merge=true, const TimeWarper *effectWarper=NULL)
 
void Silence (double t0, double t1) override
 
void InsertSilence (double t, double len) override
 
void SplitAt (double t)
 
void Split (double t0, double t1)
 
void ClearAndAddCutLine (double t0, double t1)
 
Track::Holder SplitCut (double t0, double t1)
 
void SplitDelete (double t0, double t1)
 
void Join (double t0, double t1)
 
void Disjoin (double t0, double t1)
 
void Trim (double t0, double t1)
 
void HandleClear (double t0, double t1, bool addCutLines, bool split)
 
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 (constSamplePtr buffer, sampleFormat format, size_t len, unsigned int stride=1, sampleFormat effectiveFormat=widestSampleFormat) override
 
void Flush () override
 
bool Get (samplePtr buffer, sampleFormat format, sampleCount start, size_t len, fillFormat fill=fillZero, bool mayThrow=true, sampleCount *pNumWithinClips=nullptr) const override
 
void Set (constSamplePtr buffer, sampleFormat format, sampleCount start, size_t len, sampleFormat effectiveFormat=widestSampleFormat)
 
sampleFormat WidestEffectiveFormat () const override
 
bool HasTrivialEnvelope () const override
 
void GetEnvelopeValues (double *buffer, size_t bufferLen, double t0) const override
 Fetch envelope values corresponding to uniformly separated sample times starting at the given time. More...
 
std::pair< float, float > GetMinMax (double t0, double t1, bool mayThrow=true) const
 
float GetRMS (double t0, double t1, bool mayThrow=true) const
 
SequenceGetSequenceAtTime (double time)
 
EnvelopeGetEnvelopeAtTime (double time)
 
WaveClipGetClipAtTime (double time)
 
sampleCount GetBlockStart (sampleCount t) const override
 This returns a possibly large or negative value. More...
 
size_t GetBestBlockSize (sampleCount t) const override
 This returns a nonnegative number of samples meant to size a memory buffer. More...
 
size_t GetMaxBlockSize () const override
 This returns a nonnegative number of samples meant to size a memory buffer. More...
 
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
 
bool GetErrorOpening () override
 
bool CloseLock ()
 
WaveClipHoldersGetClips ()
 
const WaveClipConstHoldersGetClips () const
 
IteratorRange< AllClipsIteratorGetAllClips ()
 
IteratorRange< AllClipsConstIteratorGetAllClips () const
 
WaveClipCreateClip (double offset=.0, const wxString &name=wxEmptyString)
 
WaveClipNewestOrNewClip ()
 Get access to the most recently added clip, or create a clip, if there is not already one. THIS IS NOT NECESSARILY RIGHTMOST. More...
 
WaveClipRightmostOrNewClip ()
 Get access to the last (rightmost) clip, or create a clip, if there is not already one. More...
 
int GetClipIndex (const WaveClip *clip) const
 
WaveClipGetClipByIndex (int index)
 
const WaveClipGetClipByIndex (int index) const
 
int GetNumClips () const
 
WaveClipPointers SortedClipArray ()
 
WaveClipConstPointers SortedClipArray () const
 
bool CanOffsetClips (const std::vector< WaveClip * > &clips, double amount, double *allowedAmount=nullptr)
 Decide whether the clips could be offset (and inserted) together without overlapping other clips. More...
 
bool CanInsertClip (WaveClip *clip, double &slideBy, double &tolerance) const
 
std::shared_ptr< WaveClipRemoveAndReturnClip (WaveClip *clip)
 
bool AddClip (const std::shared_ptr< WaveClip > &clip)
 Append a clip to the track; which must have the same block factory as this track; return success. More...
 
void MergeClips (int clipidx1, int clipidx2)
 
void ExpandCutLine (double cutLinePosition, double *cutlineStart=NULL, double *cutlineEnd=NULL)
 
bool RemoveCutLine (double cutLinePosition)
 
void Merge (const Track &orig)
 
void Resample (int rate, BasicUI::ProgressDialog *progress=NULL)
 
const TypeInfoGetTypeInfo () const override
 
Track::Holder PasteInto (AudacityProject &) const override
 Find or create the destination track for a paste, maybe in a different project. More...
 
ConstIntervals GetIntervals () const override
 Report times on the track where important intervals begin and end, for UI to snap to. More...
 
Intervals GetIntervals () override
 
const WaveClipFindClipByName (const wxString &name) const
 Returns nullptr if clip with such name was not found. More...
 
- Public Member Functions inherited from WritableSampleTrack
 WritableSampleTrack ()
 
 WritableSampleTrack (const WritableSampleTrack &other, ProtectedCreationArg &&)
 
 ~WritableSampleTrack () override
 
const TypeInfoGetTypeInfo () const override
 
virtual bool Append (constSamplePtr buffer, sampleFormat format, size_t len, unsigned int stride=1, sampleFormat effectiveFormat=widestSampleFormat)=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...
 
- Public Member Functions inherited from SampleTrack
 SampleTrack ()
 
 SampleTrack (const SampleTrack &other, ProtectedCreationArg &&)
 
 ~SampleTrack () override
 
AudioGraph::ChannelType GetChannelType () const final
 Classify this channel. More...
 
const TypeInfoGetTypeInfo () const override
 
virtual sampleFormat GetSampleFormat () const =0
 
virtual double GetRate () const =0
 
virtual sampleFormat WidestEffectiveFormat () const =0
 
virtual bool HasTrivialEnvelope () const =0
 
virtual void GetEnvelopeValues (double *buffer, size_t bufferLen, double t0) const =0
 Fetch envelope values corresponding to uniformly separated sample times starting at the given time. More...
 
virtual float GetChannelGain (int channel) const =0
 Takes gain and pan into account. More...
 
virtual size_t GetBestBlockSize (sampleCount t) const =0
 This returns a nonnegative number of samples meant to size a memory buffer. More...
 
virtual size_t GetMaxBlockSize () const =0
 This returns a nonnegative number of samples meant to size a memory buffer. More...
 
virtual sampleCount GetBlockStart (sampleCount t) const =0
 This returns a possibly large or negative value. More...
 
bool GetFloats (float *buffer, sampleCount start, size_t len, fillFormat fill=fillZero, bool mayThrow=true, sampleCount *pNumWithinClips=nullptr) const
 Retrieve samples from a track in floating-point format, regardless of the storage format. More...
 
virtual bool Get (samplePtr buffer, sampleFormat format, sampleCount start, size_t len, fillFormat fill=fillZero, bool mayThrow=true, sampleCount *pNumWithinClips=nullptr) const =0
 Retrieve samples from a track in a specified format. More...
 
sampleCount TimeToLongSamples (double t0) const
 Convert correctly between an (absolute) time in seconds and a number of samples. More...
 
double LongSamplesToTime (sampleCount pos) const
 Convert correctly between a number of samples and an (absolute) time in seconds. More...
 
- 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 > >
 
std::shared_ptr< TrackSubstitutePendingChangedTrack ()
 
std::shared_ptr< const TrackSubstitutePendingChangedTrack () const
 
std::shared_ptr< const TrackSubstituteOriginalTrack () const
 
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 &) const =0
 Find or create the destination track for a paste, maybe in a different project. More...
 
virtual ConstIntervals GetIntervals () const
 Report times on the track where important intervals begin and end, for UI to snap to. More...
 
virtual Intervals GetIntervals ()
 
virtual bool LinkConsistencyFix (bool doFix=true, bool completeList=true)
 Check consistency of channel groups, and maybe fix it. More...
 
bool LinkConsistencyCheck (bool completeList)
 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
 
bool IsAlignedWithLeader () const
 Returns true if the leader track has link type LinkType::Aligned. More...
 
ChannelGroupDataGetGroupData ()
 
const ChannelGroupDataGetGroupData () const
 
 Track ()
 
 Track (const Track &orig, ProtectedCreationArg &&)
 
Trackoperator= (const Track &orig)=delete
 
virtual ~Track ()
 
void Init (const Track &orig)
 
virtual Holder Duplicate () const
 
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)
 
void EnsureVisible (bool modifyState=false)
 
virtual double GetOffset () const =0
 
void Offset (double t)
 
virtual void SetOffset (double o)
 
virtual Holder Cut (double WXUNUSED(t0), double WXUNUSED(t1))=0
 
virtual Holder Copy (double WXUNUSED(t0), double WXUNUSED(t1), bool forClipboard=true) const =0
 
virtual void Clear (double WXUNUSED(t0), double WXUNUSED(t1))=0
 
virtual void Paste (double WXUNUSED(t), const Track *WXUNUSED(src))=0
 
virtual void SyncLockAdjust (double oldT1, double newT1)
 
virtual void Silence (double WXUNUSED(t0), double WXUNUSED(t1))=0
 
virtual void InsertSilence (double WXUNUSED(t), double WXUNUSED(len))=0
 
bool SameKindAs (const Track &track) const
 
template<typename R = void, typename ... Functions>
TypeSwitch (const Functions &...functions)
 Use this function rather than testing track type explicitly and making down-casts. More...
 
template<typename R = void, typename ... Functions>
TypeSwitch (const Functions &...functions) const
 Use this function rather than testing track type explicitly and making down-casts. More...
 
virtual void WriteXML (XMLWriter &xmlFile) const =0
 
virtual bool GetErrorOpening ()
 
virtual double GetStartTime () const =0
 
virtual double GetEndTime () const =0
 
void Notify (bool allChannels, int code=-1)
 
bool Any () const
 
bool IsSelected () const
 
bool IsLeader () const
 
bool IsSelectedLeader () 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 AudioGraph::Channel
virtual ~Channel ()
 
virtual ChannelType GetChannelType () const =0
 Classify this channel. More...
 

Static Public Member Functions

static wxString GetDefaultAudioTrackNamePreference ()
 
static WaveTrackNew (AudacityProject &project)
 
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 FinishCopy (const Track *n, Track *dest)
 
template<typename TrackType >
static void checkTrackType ()
 
template<typename R , typename TrackType , typename... Functions>
static R CallExecutor (R *, std::tuple<> *, TrackType &, const Functions &...)
 
template<typename R , typename TrackType , typename... Functions, typename Executor , typename... Executors>
static R CallExecutor (R *, std::tuple< Executor, Executors... > *, TrackType &track, const Functions &...functions)
 
template<typename ... Executors>
static constexpr unsigned UsedCases (std::tuple< Executors... > *)
 
template<typename Tag , bool IsConst, typename R , typename ... TrackTypes, typename ... Functions>
static R DoTypeSwitch (std::conditional_t< IsConst, const Track, Track > &track, TypeList::List< TrackTypes... >, const Functions &...functions)
 Deduce two packs from arguments. More...
 
- Static Public Member Functions inherited from ClientData::Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy >
static size_t slots ()
 How many static factories have been registered with this specialization of Site. More...
 

Protected Attributes

WaveClipHolders mClips
 
sampleFormat mFormat
 
int mRate
 
int mWaveColorIndex
 
- Protected Attributes inherited from Track
std::weak_ptr< TrackListmList
 
TrackNodePointer mNode {}
 Holds iterator to self, so that TrackList::Find can be constant-time. More...
 
int mIndex
 0-based position of this track in its TrackList More...
 
double mOffset
 

Private Member Functions

void Init (const WaveTrack &orig)
 
Track::Holder Clone () const override
 
wxString MakeClipCopyName (const wxString &originalName) const
 
wxString MakeNewClipName () const
 
void DoSetPan (float value)
 
void DoSetGain (float value)
 
void PasteWaveTrack (double t0, const WaveTrack *other)
 

Private Attributes

SampleBlockFactoryPtr mpFactory
 
wxCriticalSection mFlushCriticalSection
 
wxCriticalSection mAppendCriticalSection
 
double mLegacyProjectFileOffset
 

Friends

class WaveTrackFactory
 

Additional Inherited Members

- Public Attributes inherited from Track
std::pair< int, int > vrulerSize
 
- 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 >
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...
 
void BuildAll ()
 For each RegisteredFactory, if the corresponding attachment is absent in this, build and store it. More...
 

Detailed Description

A Track that contains audio waveform data.

Definition at line 50 of file WaveTrack.h.

Member Typedef Documentation

◆ Holder

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

Definition at line 99 of file WaveTrack.h.

◆ Regions

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

Definition at line 69 of file WaveTrack.h.

Constructor & Destructor Documentation

◆ WaveTrack() [1/2]

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

Definition at line 201 of file WaveTrack.cpp.

204 , mpFactory(pFactory)
205{
207
208 mFormat = format;
209 mRate = (int) rate;
210 mWaveColorIndex = 0;
211}
int format
Definition: ExportPCM.cpp:53
SampleBlockFactoryPtr mpFactory
Definition: WaveTrack.h:526
sampleFormat mFormat
Definition: WaveTrack.h:516
int mWaveColorIndex
Definition: WaveTrack.h:518
double mLegacyProjectFileOffset
Definition: WaveTrack.h:530
int mRate
Definition: WaveTrack.h:517

References format, mFormat, mLegacyProjectFileOffset, mRate, and mWaveColorIndex.

◆ WaveTrack() [2/2]

WaveTrack::WaveTrack ( const WaveTrack orig,
ProtectedCreationArg &&  a 
)

Copied only in WaveTrack::Clone() !

Definition at line 213 of file WaveTrack.cpp.

214 : WritableSampleTrack(orig, std::move(a))
215 , mpFactory( orig.mpFactory )
216{
218 for (const auto &clip : orig.mClips)
219 mClips.push_back
220 ( std::make_unique<WaveClip>( *clip, mpFactory, true ) );
221}
WaveClipHolders mClips
Definition: WaveTrack.h:514

References mClips, mLegacyProjectFileOffset, and mpFactory.

◆ ~WaveTrack()

WaveTrack::~WaveTrack ( )
virtual

Definition at line 253 of file WaveTrack.cpp.

254{
255}

Member Function Documentation

◆ AddClip()

bool WaveTrack::AddClip ( const std::shared_ptr< WaveClip > &  clip)

Append a clip to the track; which must have the same block factory as this track; return success.

Definition at line 1061 of file WaveTrack.cpp.

1062{
1063 if (clip->GetSequence()->GetFactory() != this->mpFactory)
1064 return false;
1065
1066 // Uncomment the following line after we correct the problem of zero-length clips
1067 //if (CanInsertClip(clip))
1068 mClips.push_back(clip); // transfer ownership
1069
1070 return true;
1071}

References mClips.

Referenced by ClearAndPaste(), and EffectReverse::ProcessOneWave().

Here is the caller graph for this function:

◆ Append()

bool WaveTrack::Append ( constSamplePtr  buffer,
sampleFormat  format,
size_t  len,
unsigned int  stride = 1,
sampleFormat  effectiveFormat = widestSampleFormat 
)
overridevirtual
Exception safety guarantee:
Partial – Some prefix (maybe none) of the buffer is appended, and no content already flushed to disk is lost.

Implements WritableSampleTrack.

Definition at line 1606 of file WaveTrack.cpp.

1608{
1609 return RightmostOrNewClip()
1610 ->Append(buffer, format, len, stride, effectiveFormat);
1611}
bool Append(constSamplePtr buffer, sampleFormat format, size_t len, unsigned int stride, sampleFormat effectiveFormat)
Definition: WaveClip.cpp:242
WaveClip * RightmostOrNewClip()
Get access to the last (rightmost) clip, or create a clip, if there is not already one.
Definition: WaveTrack.cpp:2212

References WaveClip::Append(), format, and RightmostOrNewClip().

Referenced by BlockGenerator::GenerateTrack(), EffectTwoPassSimpleMono::ProcessOne(), and NyquistEffect::PutCallback().

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

◆ CanInsertClip()

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

Definition at line 2316 of file WaveTrack.cpp.

2318{
2319 for (const auto &c : mClips)
2320 {
2321 //VS: Do we need to take into account sample rate difference?
2322 double d1 = c->GetPlayStartTime() - (clip->GetPlayEndTime()+slideBy);
2323 double d2 = (clip->GetPlayStartTime()+slideBy) - c->GetPlayEndTime();
2324 if ( (d1<0) && (d2<0) )
2325 {
2326 // clips overlap.
2327 // Try to rescue it.
2328 // The rescue logic is not perfect, and will typically
2329 // move the clip at most once.
2330 // We divide by 1000 rather than set to 0, to allow for
2331 // a second 'micro move' that is really about rounding error.
2332
2333 // VS: clip could be moved more than once, moving it in opposite
2334 // direction may reintroduce overlapping condition
2335 if( -d1 < tolerance ){
2336 // right edge of clip overlaps slightly.
2337 // slide clip left a small amount.
2338 slideBy +=d1;
2339 tolerance /=1000;
2340 } else if( -d2 < tolerance ){
2341 // left edge of clip overlaps slightly.
2342 // slide clip right a small amount.
2343 slideBy -= d2;
2344 tolerance /=1000;
2345 }
2346 else
2347 return false; // clips overlap No tolerance left.
2348 }
2349 }
2350
2351 return true;
2352}
double GetPlayStartTime() const noexcept
Definition: WaveClip.cpp:889
double GetPlayEndTime() const
Definition: WaveClip.cpp:899

References WaveClip::GetPlayEndTime(), WaveClip::GetPlayStartTime(), and mClips.

Here is the call graph for this function:

◆ CanOffsetClips()

bool WaveTrack::CanOffsetClips ( const std::vector< WaveClip * > &  clips,
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
clipsnot necessarily in this track
amountsigned
[out]allowedAmountif null, test exact amount only; else, largest (in magnitude) possible offset with same sign

Definition at line 2258 of file WaveTrack.cpp.

2262{
2263 if (allowedAmount)
2264 *allowedAmount = amount;
2265
2266 const auto &moving = [&](WaveClip *clip){
2267 // linear search might be improved, but expecting few moving clips
2268 // compared with the fixed clips
2269 return clips.end() != std::find( clips.begin(), clips.end(), clip );
2270 };
2271
2272 for (const auto &c: mClips) {
2273 if ( moving( c.get() ) )
2274 continue;
2275 for (const auto clip : clips) {
2276 if (c->GetPlayStartTime() < clip->GetPlayEndTime() + amount &&
2277 c->GetPlayEndTime() > clip->GetPlayStartTime() + amount)
2278 {
2279 if (!allowedAmount)
2280 return false; // clips overlap
2281
2282 if (amount > 0)
2283 {
2284 if (c->GetPlayStartTime() - clip->GetPlayEndTime() < *allowedAmount)
2285 *allowedAmount = c->GetPlayStartTime() - clip->GetPlayEndTime();
2286 if (*allowedAmount < 0)
2287 *allowedAmount = 0;
2288 } else
2289 {
2290 if (c->GetPlayEndTime() - clip->GetPlayStartTime() > *allowedAmount)
2291 *allowedAmount = c->GetPlayEndTime() - clip->GetPlayStartTime();
2292 if (*allowedAmount > 0)
2293 *allowedAmount = 0;
2294 }
2295 }
2296 }
2297 }
2298
2299 if (allowedAmount)
2300 {
2301 if (*allowedAmount == amount)
2302 return true;
2303
2304 // Check if the NEW calculated amount would not violate
2305 // any other constraint
2306 if (!CanOffsetClips(clips, *allowedAmount, nullptr)) {
2307 *allowedAmount = 0; // play safe and don't allow anything
2308 return false;
2309 }
2310 else
2311 return true;
2312 } else
2313 return true;
2314}
This allows multiple clips to be a part of one WaveTrack.
Definition: WaveClip.h:101
bool CanOffsetClips(const std::vector< WaveClip * > &clips, double amount, double *allowedAmount=nullptr)
Decide whether the clips could be offset (and inserted) together without overlapping other clips.
Definition: WaveTrack.cpp:2258

References CanOffsetClips(), and mClips.

Referenced by CanOffsetClips().

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

◆ ClassTypeInfo()

auto WaveTrack::ClassTypeInfo ( )
static

Definition at line 320 of file WaveTrack.cpp.

321{
322 return typeInfo();
323}
static const Track::TypeInfo & typeInfo()
Definition: WaveTrack.cpp:307

References typeInfo().

Here is the call graph for this function:

◆ Clear()

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

Definition at line 688 of file WaveTrack.cpp.

689{
690 HandleClear(t0, t1, false, false);
691}
void HandleClear(double t0, double t1, bool addCutLines, bool split)
Definition: WaveTrack.cpp:1074

References HandleClear().

Referenced by Cut(), EffectTruncSilence::DoRemoval(), anonymous_namespace{LabelMenus.cpp}::OnCutLabels(), PasteOverPreservingClips(), Generator::Process(), EffectStereoToMono::ProcessOne(), EffectPaulstretch::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 
)
Exception safety guarantee:
Strong

Definition at line 694 of file WaveTrack.cpp.

695{
696 HandleClear(t0, t1, true, false);
697}

References HandleClear().

Referenced by anonymous_namespace{EditMenus.cpp}::OnCut(), and 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 Track src,
bool  preserve = true,
bool  merge = true,
const TimeWarper effectWarper = NULL 
)
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 746 of file WaveTrack.cpp.

753{
754 double dur = std::min(t1 - t0, src->GetEndTime());
755
756 // If duration is 0, then it's just a plain paste
757 if (dur == 0.0) {
758 // use Weak-guarantee
759 Paste(t0, src);
760 return;
761 }
762
763 std::vector<SplitInfo> splits;
764 WaveClipHolders cuts;
765
766 //helper routine, that finds SplitInfo by time value,
767 //or creates a new one if no one exists yet
768 auto get_split = [&](double time) {
769 auto it = std::find_if(splits.begin(), splits.end(), [time](const SplitInfo& split) {
770 return split.time == time;
771 });
772 if(it == splits.end())
773 it = splits.insert(
774 splits.end(),
775 { time, nullptr, nullptr, std::nullopt, std::nullopt }
776 );
777 return it;
778 };
779
780 // If provided time warper was NULL, use a default one that does nothing
781 IdentityTimeWarper localWarper;
782 const TimeWarper *warper = (effectWarper ? effectWarper : &localWarper);
783
784 // Align to a sample
787
788 // Save the cut/split lines whether preserving or not since merging
789 // needs to know if a clip boundary is being crossed since Paste()
790 // will add split lines around the pasted clip if so.
791 for (const auto &clip : mClips) {
792 double st;
793
794 // Remember clip boundaries as locations to split
795 // we need to copy clips, trims and names, because the original ones
796 // could be changed later during Clear/Paste routines
797 st = LongSamplesToTime(TimeToLongSamples(clip->GetPlayStartTime()));
798 if (st >= t0 && st <= t1) {
799 auto it = get_split(st);
800 if (clip->GetTrimLeft() != 0)
801 {
802 //keep only hidden left part
803 it->right = std::make_shared<WaveClip>(*clip, mpFactory, false);
804 it->right->SetTrimLeft(.0);
805 it->right->ClearRight(clip->GetPlayStartTime());
806 }
807 it->rightClipName = clip->GetName();
808 }
809
810 st = LongSamplesToTime(TimeToLongSamples(clip->GetPlayEndTime()));
811 if (st >= t0 && st <= t1) {
812 auto it = get_split(st);
813 if (clip->GetTrimRight() != 0)
814 {
815 //keep only hidden right part
816 it->left = std::make_shared<WaveClip>(*clip, mpFactory, false);
817 it->left->SetTrimRight(.0);
818 it->left->ClearLeft(clip->GetPlayEndTime());
819 }
820 it->leftClipName = clip->GetName();
821 }
822
823 // Search for cut lines
824 auto &cutlines = clip->GetCutLines();
825 // May erase from cutlines, so don't use range-for
826 for (auto it = cutlines.begin(); it != cutlines.end(); ) {
827 WaveClip *cut = it->get();
828 double cs = LongSamplesToTime(TimeToLongSamples(clip->GetSequenceStartTime() +
829 cut->GetSequenceStartTime()));
830
831 // Remember cut point
832 if (cs >= t0 && cs <= t1) {
833
834 // Remember the absolute offset and add to our cuts array.
835 cut->SetSequenceStartTime(cs);
836 cuts.push_back(std::move(*it)); // transfer ownership!
837 it = cutlines.erase(it);
838 }
839 else
840 ++it;
841 }
842 }
843
844 const auto tolerance = 2.0 / GetRate();
845
846 // Now, clear the selection
847 HandleClear(t0, t1, false, false);
848 {
849
850 // And paste in the NEW data
851 Paste(t0, src);
852 {
853 // First, merge the NEW clip(s) in with the existing clips
854 if (merge && splits.size() > 0)
855 {
856 // Now t1 represents the absolute end of the pasted data.
857 t1 = t0 + src->GetEndTime();
858
859 // Get a sorted array of the clips
860 auto clips = SortedClipArray();
861
862 // Scan the sorted clips for the first clip whose start time
863 // exceeds the pasted regions end time.
864 {
865 WaveClip *prev = nullptr;
866 for (const auto clip : clips) {
867 // Merge this clip and the previous clip if the end time
868 // falls within it and this isn't the first clip in the track.
869 if (fabs(t1 - clip->GetPlayStartTime()) < tolerance) {
870 if (prev)
872 break;
873 }
874 prev = clip;
875 }
876 }
877 }
878
879 // Refill the array since clips have changed.
880 auto clips = SortedClipArray();
881
882 {
883 // Scan the sorted clips to look for the start of the pasted
884 // region.
885 WaveClip *prev = nullptr;
886 for (const auto clip : clips) {
887 if (prev) {
888 // It must be that clip is what was pasted and it begins where
889 // prev ends.
890 // use Weak-guarantee
892 break;
893 }
894 if (fabs(t0 - clip->GetPlayEndTime()) < tolerance)
895 // Merge this clip and the next clip if the start time
896 // falls within it and this isn't the last clip in the track.
897 prev = clip;
898 else
899 prev = nullptr;
900 }
901 }
902 }
903
904 // Restore cut/split lines
905 if (preserve) {
906
907 auto attachLeft = [](WaveClip* target, WaveClip* src)
908 {
909 wxASSERT(target->GetTrimLeft() == 0);
910 if (target->GetTrimLeft() != 0)
911 return;
912
913 auto trim = src->GetPlayEndTime() - src->GetPlayStartTime();
914 target->Paste(target->GetPlayStartTime(), src);
915 target->SetTrimLeft(trim);
916 //Play start time needs to be adjusted after
917 //prepending data to the sequence
918 target->Offset(-trim);
919 };
920
921 auto attachRight = [](WaveClip* target, WaveClip* src)
922 {
923 wxASSERT(target->GetTrimRight() == 0);
924 if (target->GetTrimRight() != 0)
925 return;
926
927 auto trim = src->GetPlayEndTime() - src->GetPlayStartTime();
928 target->Paste(target->GetPlayEndTime(), src);
929 target->SetTrimRight(trim);
930 };
931
932 // Restore the split lines and trims, transforming the position appropriately
933 for (const auto& split: splits) {
934 auto at = LongSamplesToTime(TimeToLongSamples(warper->Warp(split.time)));
935 for (const auto& clip : GetClips())
936 {
937 if (clip->WithinPlayRegion(at))//strictly inside
938 {
939 auto newClip = std::make_unique<WaveClip>(*clip, mpFactory, true);
940
941 clip->ClearRight(at);
942 newClip->ClearLeft(at);
943 if (split.left)
944 attachRight(clip.get(), split.left.get());
945 if (split.right)
946 attachLeft(newClip.get(), split.right.get());
947 AddClip(std::move(newClip));
948 break;
949 }
950 else if (clip->GetPlayStartSample() == TimeToLongSamples(at) && split.right)
951 {
952 attachLeft(clip.get(), split.right.get());
953 break;
954 }
955 else if (clip->GetPlayEndSample() == TimeToLongSamples(at) && split.left)
956 {
957 attachRight(clip.get(), split.left.get());
958 break;
959 }
960 }
961 }
962
963 //Restore clip names
964 for (const auto& split : splits)
965 {
966 auto s = TimeToLongSamples(warper->Warp(split.time));
967 for (auto& clip : GetClips())
968 {
969 if (split.rightClipName.has_value() && clip->GetPlayStartSample() == s)
970 clip->SetName(*split.rightClipName);
971 else if (split.leftClipName.has_value() && clip->GetPlayEndSample() == s)
972 clip->SetName(*split.leftClipName);
973 }
974 }
975
976 // Restore the saved cut lines, also transforming if time altered
977 for (const auto &clip : mClips) {
978 double st;
979 double et;
980
981 st = clip->GetPlayStartTime();
982 et = clip->GetPlayEndTime();
983
984 // Scan the cuts for any that live within this clip
985 for (auto it = cuts.begin(); it != cuts.end();) {
986 WaveClip *cut = it->get();
987 //cutlines in this array were orphaned previously
988 double cs = cut->GetSequenceStartTime();
989
990 // Offset the cut from the start of the clip and add it to
991 // this clips cutlines.
992 if (cs >= st && cs <= et) {
993 cut->SetSequenceStartTime(warper->Warp(cs) - st);
994 clip->GetCutLines().push_back( std::move(*it) ); // transfer ownership!
995 it = cuts.erase(it);
996 }
997 else
998 ++it;
999 }
1000 }
1001 }
1002 }
1003}
int min(int a, int b)
std::vector< WaveClipHolder > WaveClipHolders
Definition: WaveClip.h:42
No change to time at all.
Definition: TimeWarper.h:69
double LongSamplesToTime(sampleCount pos) const
Convert correctly between a number of samples and an (absolute) time in seconds.
Definition: SampleTrack.cpp:59
sampleCount TimeToLongSamples(double t0) const
Convert correctly between an (absolute) time in seconds and a number of samples.
Definition: SampleTrack.cpp:54
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
virtual double GetEndTime() const =0
double GetSequenceStartTime() const noexcept
Definition: WaveClip.cpp:967
void SetSequenceStartTime(double startTime)
Definition: WaveClip.cpp:973
double GetTrimRight() const noexcept
Returns the play end offset in seconds from the ending of the underlying sequence.
Definition: WaveClip.cpp:942
double GetTrimLeft() const noexcept
Returns the play start offset in seconds from the beginning of the underlying sequence.
Definition: WaveClip.cpp:932
void Paste(double t0, const WaveClip *other)
Paste data from other clip, resampling it if not equal rate.
Definition: WaveClip.cpp:374
void SetTrimRight(double trim)
Sets the play end offset in seconds from the ending of the underlying sequence.
Definition: WaveClip.cpp:937
void Offset(double delta) noexcept
Definition: WaveClip.cpp:1000
void SetTrimLeft(double trim)
Sets the play start offset in seconds from the beginning of the underlying sequence.
Definition: WaveClip.cpp:927
void Paste(double t0, const Track *src) override
Definition: WaveTrack.cpp:1403
bool AddClip(const std::shared_ptr< WaveClip > &clip)
Append a clip to the track; which must have the same block factory as this track; return success.
Definition: WaveTrack.cpp:1061
WaveClipPointers SortedClipArray()
Definition: WaveTrack.cpp:2489
int GetClipIndex(const WaveClip *clip) const
Definition: WaveTrack.cpp:2233
double GetRate() const override
Definition: WaveTrack.cpp:396
WaveClipHolders & GetClips()
Definition: WaveTrack.h:319
void MergeClips(int clipidx1, int clipidx2)
Definition: WaveTrack.cpp:2447

References AddClip(), GetClipIndex(), GetClips(), Track::GetEndTime(), WaveClip::GetPlayEndTime(), WaveClip::GetPlayStartTime(), GetRate(), WaveClip::GetSequenceStartTime(), WaveClip::GetTrimLeft(), WaveClip::GetTrimRight(), HandleClear(), SampleTrack::LongSamplesToTime(), mClips, MergeClips(), min(), mpFactory, WaveClip::Offset(), Paste(), WaveClip::Paste(), WaveClip::SetSequenceStartTime(), WaveClip::SetTrimLeft(), WaveClip::SetTrimRight(), SortedClipArray(), SampleTrack::TimeToLongSamples(), and TimeWarper::Warp().

Referenced by TrackSpectrumTransformer::DoFinish(), EffectSBSMS::Finalize(), WaveTrackSink::Flush(), anonymous_namespace{EditMenus.cpp}::OnPaste(), Generator::Process(), NyquistEffect::ProcessOne(), EffectNoiseRemoval::ProcessOne(), and EffectChangeSpeed::ProcessOne().

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

◆ Clone()

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

Implements Track.

Definition at line 365 of file WaveTrack.cpp.

366{
367 auto result = std::make_shared<WaveTrack>(*this, ProtectedCreationArg{});
368 result->Init(*this);
369 return result;
370}

◆ CloseLock()

bool WaveTrack::CloseLock ( )

Definition at line 1820 of file WaveTrack.cpp.

1821{
1822 for (const auto &clip : mClips)
1823 clip->CloseLock();
1824
1825 return true;
1826}

References mClips.

◆ 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 501 of file WaveTrack.cpp.

503{
504 for (const auto& clip : mClips)
505 clip->ConvertToSampleFormat(format, progressReport);
506 mFormat = format;
507}

References format, mClips, and mFormat.

Referenced by EffectEqualization::ProcessOne().

Here is the caller graph for this function:

◆ Copy()

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

Definition at line 621 of file WaveTrack.cpp.

622{
623 if (t1 < t0)
625
626 auto result = EmptyCopy();
627 WaveTrack *newTrack = result.get();
628
629 // PRL: Why shouldn't cutlines be copied and pasted too? I don't know, but
630 // that was the old behavior. But this function is also used by the
631 // Duplicate command and I changed its behavior in that case.
632
633 for (const auto &clip : mClips)
634 {
635 if (t0 <= clip->GetPlayStartTime() && t1 >= clip->GetPlayEndTime())
636 {
637 // Whole clip is in copy region
638 //wxPrintf("copy: clip %i is in copy region\n", (int)clip);
639
640 newTrack->mClips.push_back
641 (std::make_unique<WaveClip>(*clip, mpFactory, ! forClipboard));
642 WaveClip *const newClip = newTrack->mClips.back().get();
643 newClip->Offset(-t0);
644 }
645 else if (clip->CountSamples(t0, t1) >= 1)
646 {
647 // Clip is affected by command
648 //wxPrintf("copy: clip %i is affected by command\n", (int)clip);
649
650 auto newClip = std::make_unique<WaveClip>
651 (*clip, mpFactory, ! forClipboard, t0, t1);
652 newClip->SetName(clip->GetName());
653
654 newClip->Offset(-t0);
655 if (newClip->GetPlayStartTime() < 0)
656 newClip->SetPlayStartTime(0);
657
658 newTrack->mClips.push_back(std::move(newClip)); // transfer ownership
659 }
660 }
661
662 // AWD, Oct 2009: If the selection ends in whitespace, create a placeholder
663 // clip representing that whitespace
664 // PRL: Only if we want the track for pasting into other tracks. Not if it
665 // goes directly into a project as in the Duplicate command.
666 if (forClipboard &&
667 newTrack->GetEndTime() + 1.0 / newTrack->GetRate() < t1 - t0)
668 {
669 auto placeholder = std::make_unique<WaveClip>(mpFactory,
670 newTrack->GetSampleFormat(),
671 static_cast<int>(newTrack->GetRate()),
672 0 /*colourindex*/);
673 placeholder->SetIsPlaceholder(true);
674 placeholder->InsertSilence(0, (t1 - t0) - newTrack->GetEndTime());
675 placeholder->Offset(newTrack->GetEndTime());
676 newTrack->mClips.push_back(std::move(placeholder)); // transfer ownership
677 }
678
679 return result;
680}
#define THROW_INCONSISTENCY_EXCEPTION
Throw InconsistencyException, using C++ preprocessor to identify the source code location.
void SetPlayStartTime(double time)
Definition: WaveClip.cpp:894
void SetName(const wxString &name)
Definition: WaveClip.cpp:858
A Track that contains audio waveform data.
Definition: WaveTrack.h:51
sampleFormat GetSampleFormat() const override
Definition: WaveTrack.h:148
double GetEndTime() const override
Get the time at which the last clip in the track ends, plus recorded stuff.
Definition: WaveTrack.cpp:1848
Holder EmptyCopy(const SampleBlockFactoryPtr &pFactory={}, bool keepLink=true) const
Definition: WaveTrack.cpp:610

References EmptyCopy(), GetEndTime(), GetRate(), GetSampleFormat(), mClips, mpFactory, WaveClip::Offset(), and THROW_INCONSISTENCY_EXCEPTION.

Referenced by CopyNonconst(), Cut(), anonymous_namespace{EditMenus.cpp}::OnSplitCut(), anonymous_namespace{LabelMenus.cpp}::OnSplitCutLabels(), anonymous_namespace{EditMenus.cpp}::OnSplitNew(), PasteOverPreservingClips(), and SplitCut().

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

◆ CopyNonconst()

Track::Holder WaveTrack::CopyNonconst ( double  t0,
double  t1 
)

Definition at line 682 of file WaveTrack.cpp.

683{
684 return Copy(t0, t1);
685}
Track::Holder Copy(double t0, double t1, bool forClipboard=true) const override
Definition: WaveTrack.cpp:621

References Copy().

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

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

◆ CreateClip()

WaveClip * WaveTrack::CreateClip ( double  offset = .0,
const wxString &  name = wxEmptyString 
)

Definition at line 2192 of file WaveTrack.cpp.

2193{
2194 auto clip = std::make_unique<WaveClip>(mpFactory, mFormat, mRate, GetWaveColorIndex());
2195 clip->SetName(name);
2196 clip->SetSequenceStartTime(offset);
2197 mClips.push_back(std::move(clip));
2198
2199 return mClips.back().get();
2200}
const TranslatableString name
Definition: Distortion.cpp:76
int GetWaveColorIndex() const
Definition: WaveTrack.h:142

References GetWaveColorIndex(), mClips, mFormat, mpFactory, mRate, and name.

Referenced by AUPImportFileHandle::HandleWaveClip(), HandleXMLChild(), Join(), NewestOrNewClip(), and RightmostOrNewClip().

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

◆ Cut()

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

Definition at line 532 of file WaveTrack.cpp.

533{
534 if (t1 < t0)
536
537 auto tmp = Copy(t0, t1);
538
539 Clear(t0, t1);
540
541 return tmp;
542}
void Clear(double t0, double t1) override
Definition: WaveTrack.cpp:688

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 1477 of file WaveTrack.cpp.

1478{
1480 const size_t maxAtOnce = 1048576;
1481 Floats buffer{ maxAtOnce };
1482 Regions regions;
1483
1484 for (const auto &clip : mClips)
1485 {
1486 double startTime = clip->GetPlayStartTime();
1487 double endTime = clip->GetPlayEndTime();
1488
1489 if( endTime < t0 || startTime > t1 )
1490 continue;
1491
1492 //simply look for a sequence of zeroes and if the sequence
1493 //is greater than minimum number, split-DELETE the region
1494
1495 sampleCount seqStart = -1;
1496 auto start = clip->TimeToSamples(std::max(.0, t0 - startTime));
1497 auto end = clip->TimeToSamples(std::min(endTime, t1) - startTime);
1498
1499 auto len = ( end - start );
1500 for( decltype(len) done = 0; done < len; done += maxAtOnce )
1501 {
1502 auto numSamples = limitSampleBufferSize( maxAtOnce, len - done );
1503
1504 clip->GetSamples( ( samplePtr )buffer.get(), floatSample, start + done,
1505 numSamples );
1506 for( decltype(numSamples) i = 0; i < numSamples; i++ )
1507 {
1508 auto curSamplePos = start + done + i;
1509
1510 //start a NEW sequence
1511 if( buffer[ i ] == 0.0 && seqStart == -1 )
1512 seqStart = curSamplePos;
1513 else if( buffer[ i ] != 0.0 || curSamplePos == end - 1 )
1514 {
1515 if( seqStart != -1 )
1516 {
1517 decltype(end) seqEnd;
1518
1519 //consider the end case, where selection ends in zeroes
1520 if( curSamplePos == end - 1 && buffer[ i ] == 0.0 )
1521 seqEnd = end;
1522 else
1523 seqEnd = curSamplePos;
1524 if( seqEnd - seqStart + 1 > minSamples )
1525 {
1526 regions.push_back(
1527 Region(
1528 startTime + clip->SamplesToTime(seqStart),
1529 startTime + clip->SamplesToTime(seqEnd)
1530 )
1531 );
1532 }
1533 seqStart = -1;
1534 }
1535 }
1536 }
1537 }
1538 }
1539
1540 for( unsigned int i = 0; i < regions.size(); i++ )
1541 {
1542 const Region &region = regions.at(i);
1543 SplitDelete(region.start, region.end );
1544 }
1545}
WaveTrack::Regions Regions
Definition: LabelMenus.cpp:22
size_t limitSampleBufferSize(size_t bufferSize, sampleCount limit)
Definition: SampleCount.cpp:22
char * samplePtr
Definition: SampleFormat.h:55
WaveTrack::Region Region
#define WAVETRACK_MERGE_POINT_TOLERANCE
Definition: WaveTrack.h:46
void SplitDelete(double t0, double t1)
Definition: WaveTrack.cpp:1006
Positions or offsets within audio files need a wide type.
Definition: SampleCount.h:19
auto end(const Ptr< Type, BaseDeleter > &p)
Enables range-for.
Definition: PackedArray.h:159
Structure to hold region of a wavetrack and a comparison function for sortability.
Definition: WaveTrack.h:56

References PackedArray::end(), WaveTrack::Region::end, floatSample, limitSampleBufferSize(), mClips, min(), SplitDelete(), WaveTrack::Region::start, SampleTrack::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:

◆ DoSetGain()

void WaveTrack::DoSetGain ( float  value)
private

Definition at line 418 of file WaveTrack.cpp.

419{
420 GainAndPan::Get(*this).SetGain(value);
421}
Services * Get()
Fetch the global instance, or nullptr if none is yet installed.
Definition: BasicUI.cpp:196

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 436 of file WaveTrack.cpp.

437{
438 GainAndPan::Get(*this).SetPan(value);
439}

References BasicUI::Get().

Referenced by HandleXMLTag(), and SetPan().

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

◆ EmptyCopy()

WaveTrack::Holder WaveTrack::EmptyCopy ( const SampleBlockFactoryPtr pFactory = {},
bool  keepLink = true 
) const

Make another track copying format, rate, color, etc. but containing no clips

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.

Parameters
keepLinkif false, make the new track mono. But always preserve any other track group data.

Definition at line 610 of file WaveTrack.cpp.

612{
613 auto result = std::make_shared<WaveTrack>( pFactory, mFormat, mRate );
614 result->Init(*this);
615 result->mpFactory = pFactory ? pFactory : mpFactory;
616 if (!keepLink)
617 result->SetLinkType(LinkType::None);
618 return result;
619}

References mFormat, mpFactory, mRate, and Track::None.

Referenced by Copy(), TrackSpectrumTransformer::DoStart(), PasteInto(), Generator::Process(), EffectSBSMS::Process(), NyquistEffect::ProcessOne(), EffectNoiseRemoval::ProcessOne(), EffectStereoToMono::ProcessOne(), EffectChangeSpeed::ProcessOne(), and EffectPaulstretch::ProcessOne().

Here is the caller graph for this function:

◆ ExpandCutLine()

void WaveTrack::ExpandCutLine ( double  cutLinePosition,
double *  cutlineStart = NULL,
double *  cutlineEnd = NULL 
)
Exception safety guarantee:
Strong

Definition at line 2384 of file WaveTrack.cpp.

2386{
2387 bool editClipCanMove = GetEditClipsCanMove();
2388
2389 // Find clip which contains this cut line
2390 double start = 0, end = 0;
2391 auto pEnd = mClips.end();
2392 auto pClip = std::find_if( mClips.begin(), pEnd,
2393 [&](const WaveClipHolder &clip) {
2394 return clip->FindCutLine(cutLinePosition, &start, &end); } );
2395 if (pClip != pEnd)
2396 {
2397 auto &clip = *pClip;
2398 if (!editClipCanMove)
2399 {
2400 // We are not allowed to move the other clips, so see if there
2401 // is enough room to expand the cut line
2402 for (const auto &clip2: mClips)
2403 {
2404 if (clip2->GetPlayStartTime() > clip->GetPlayStartTime() &&
2405 clip->GetPlayEndTime() + end - start > clip2->GetPlayStartTime())
2406 // Strong-guarantee in case of this path
2409 XO("There is not enough room available to expand the cut line"),
2410 XO("Warning"),
2411 "Error:_Insufficient_space_in_track"
2412 };
2413 }
2414 }
2415
2416 clip->ExpandCutLine(cutLinePosition);
2417
2418 // Strong-guarantee provided that the following gives No-fail-guarantee
2419
2420 if (cutlineStart)
2421 *cutlineStart = start;
2422 if (cutlineEnd)
2423 *cutlineEnd = end;
2424
2425 // Move clips which are to the right of the cut line
2426 if (editClipCanMove)
2427 {
2428 for (const auto &clip2 : mClips)
2429 {
2430 if (clip2->GetPlayStartTime() > clip->GetPlayStartTime())
2431 clip2->Offset(end - start);
2432 }
2433 }
2434 }
2435}
@ BadUserAction
Indicates that the user performed an action that is not allowed.
XO("Cut/Copy/Paste")
std::shared_ptr< WaveClip > WaveClipHolder
Definition: WaveClip.h:41
bool GetEditClipsCanMove()
Definition: WaveTrack.cpp:2616
A MessageBoxException that shows a given, unvarying string.

References BadUserAction, PackedArray::end(), GetEditClipsCanMove(), mClips, and XO().

Here is the call graph for this function:

◆ FindClipByName()

const WaveClip * WaveTrack::FindClipByName ( const wxString &  name) const

Returns nullptr if clip with such name was not found.

Definition at line 355 of file WaveTrack.cpp.

356{
357 for (const auto& clip : mClips)
358 {
359 if (clip->GetName() == name)
360 return clip.get();
361 }
362 return nullptr;
363}

References mClips, and name.

Referenced by MakeClipCopyName(), and MakeNewClipName().

Here is the caller 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 WritableSampleTrack.

Definition at line 1679 of file WaveTrack.cpp.

1680{
1681 // After appending, presumably. Do this to the clip that gets appended.
1683}
void Flush()
Flush must be called after last Append.
Definition: WaveClip.cpp:260

References WaveClip::Flush(), and RightmostOrNewClip().

Referenced by EffectTwoPassSimpleMono::ProcessOne().

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

◆ Get()

bool WaveTrack::Get ( samplePtr  buffer,
sampleFormat  format,
sampleCount  start,
size_t  len,
fillFormat  fill = fillZero,
bool  mayThrow = true,
sampleCount pNumWithinClips = nullptr 
) const
overridevirtual

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 SampleTrack.

Definition at line 1945 of file WaveTrack.cpp.

1948{
1949 // Simple optimization: When this buffer is completely contained within one clip,
1950 // don't clear anything (because we won't have to). Otherwise, just clear
1951 // everything to be on the safe side.
1952 bool doClear = true;
1953 bool result = true;
1954 sampleCount samplesCopied = 0;
1955 for (const auto &clip: mClips)
1956 {
1957 if (start >= clip->GetPlayStartSample() && start+len <= clip->GetPlayEndSample())
1958 {
1959 doClear = false;
1960 break;
1961 }
1962 }
1963 if (doClear)
1964 {
1965 // Usually we fill in empty space with zero
1966 if( fill == fillZero )
1967 ClearSamples(buffer, format, 0, len);
1968 // but we don't have to.
1969 else if( fill==fillTwo )
1970 {
1971 wxASSERT( format==floatSample );
1972 float * pBuffer = (float*)buffer;
1973 for(size_t i=0;i<len;i++)
1974 pBuffer[i]=2.0f;
1975 }
1976 else
1977 {
1978 wxFAIL_MSG(wxT("Invalid fill format"));
1979 }
1980 }
1981
1982 // Iterate the clips. They are not necessarily sorted by time.
1983 for (const auto &clip: mClips)
1984 {
1985 auto clipStart = clip->GetPlayStartSample();
1986 auto clipEnd = clip->GetPlayEndSample();
1987
1988 if (clipEnd > start && clipStart < start+len)
1989 {
1990 // Clip sample region and Get/Put sample region overlap
1991 auto samplesToCopy =
1992 std::min( start+len - clipStart, clip->GetPlaySamplesCount() );
1993 auto startDelta = clipStart - start;
1994 decltype(startDelta) inclipDelta = 0;
1995 if (startDelta < 0)
1996 {
1997 inclipDelta = -startDelta; // make positive value
1998 samplesToCopy -= inclipDelta;
1999 // samplesToCopy is now either len or
2000 // (clipEnd - clipStart) - (start - clipStart)
2001 // == clipEnd - start > 0
2002 // samplesToCopy is not more than len
2003 //
2004 startDelta = 0;
2005 // startDelta is zero
2006 }
2007 else {
2008 // startDelta is nonnegative and less than len
2009 // samplesToCopy is positive and not more than len
2010 }
2011
2012 if (!clip->GetSamples(
2013 (samplePtr)(((char*)buffer) +
2014 startDelta.as_size_t() *
2016 format, inclipDelta, samplesToCopy.as_size_t(), mayThrow ))
2017 result = false;
2018 else
2019 samplesCopied += samplesToCopy;
2020 }
2021 }
2022 if( pNumWithinClips )
2023 *pNumWithinClips = samplesCopied;
2024 return result;
2025}
wxT("CloseDown"))
void ClearSamples(samplePtr dst, sampleFormat format, size_t start, size_t len)
#define SAMPLE_SIZE(SampleFormat)
Definition: SampleFormat.h:50
@ fillZero
Definition: SampleFormat.h:60
@ fillTwo
Definition: SampleFormat.h:61

References ClearSamples(), fillTwo, fillZero, floatSample, format, mClips, min(), SAMPLE_SIZE, and wxT().

Referenced by WaveTrackFactory::Get(), and EffectNoiseRemoval::ProcessOne().

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

◆ GetAllClips() [1/2]

IteratorRange< AllClipsIterator > WaveTrack::GetAllClips ( )
inline

Definition at line 401 of file WaveTrack.h.

402 {
403 return { AllClipsIterator{ *this }, AllClipsIterator{ } };
404 }

◆ GetAllClips() [2/2]

IteratorRange< AllClipsConstIterator > WaveTrack::GetAllClips ( ) const
inline

Definition at line 406 of file WaveTrack.h.

407 {
408 return { AllClipsConstIterator{ *this }, AllClipsConstIterator{ } };
409 }

◆ GetBestBlockSize()

size_t WaveTrack::GetBestBlockSize ( sampleCount  t) const
overridevirtual

This returns a nonnegative number of samples meant to size a memory buffer.

Implements SampleTrack.

Definition at line 1629 of file WaveTrack.cpp.

1630{
1631 auto bestBlockSize = GetMaxBlockSize();
1632
1633 for (const auto &clip : mClips)
1634 {
1635 auto startSample = clip->GetPlayStartSample();
1636 auto endSample = clip->GetPlayEndSample();
1637 if (s >= startSample && s < endSample)
1638 {
1639 bestBlockSize = clip->GetSequence()->GetBestBlockSize(s - clip->GetSequenceStartSample());
1640 break;
1641 }
1642 }
1643
1644 return bestBlockSize;
1645}
size_t GetMaxBlockSize() const override
This returns a nonnegative number of samples meant to size a memory buffer.
Definition: WaveTrack.cpp:1647

References GetMaxBlockSize(), and mClips.

Referenced by EffectNormalize::AnalyseTrackData(), CompareAudioCommand::Apply(), BlockGenerator::GenerateTrack(), NyquistEffect::GetCallback(), TrackSpectrumTransformer::Process(), EffectNoiseRemoval::ProcessOne(), EffectLoudness::ProcessOne(), EffectNormalize::ProcessOne(), EffectChangeSpeed::ProcessOne(), EffectSimpleMono::ProcessOne(), EffectTwoPassSimpleMono::ProcessOne(), EffectReverse::ProcessOneClip(), resampleCB(), VoiceKey::TestDirectionChanges(), VoiceKey::TestEnergy(), and VoiceKey::TestSignChanges().

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

◆ GetBlockStart()

sampleCount WaveTrack::GetBlockStart ( sampleCount  t) const
overridevirtual

This returns a possibly large or negative value.

Implements SampleTrack.

Definition at line 1613 of file WaveTrack.cpp.

1614{
1615 for (const auto &clip : mClips)
1616 {
1617 const auto startSample = clip->GetPlayStartSample();
1618 const auto endSample = clip->GetPlayEndSample();
1619 if (s >= startSample && s < endSample)
1620 {
1621 auto blockStartOffset = clip->GetSequence()->GetBlockStart(clip->ToSequenceSamples(s));
1622 return std::max(startSample, clip->GetSequenceStartSample() + blockStartOffset);
1623 }
1624 }
1625
1626 return -1;
1627}

References mClips.

◆ GetChannelGain()

float WaveTrack::GetChannelGain ( int  channel) const
overridevirtual

Takes gain and pan into account.

Implements SampleTrack.

Definition at line 454 of file WaveTrack.cpp.

455{
456 float left = 1.0;
457 float right = 1.0;
458
459 const auto pan = GetPan();
460 if (pan < 0)
461 right = (pan + 1.0);
462 else if (pan > 0)
463 left = 1.0 - pan;
464
465 const auto gain = GetGain();
466 if ((channel%2) == 0)
467 return left * gain;
468 else
469 return right * gain;
470}
float GetPan() const
Definition: WaveTrack.cpp:431
float GetGain() const
Definition: WaveTrack.cpp:413

References GetGain(), and GetPan().

Here is the call graph for this function:

◆ GetClipAtTime()

WaveClip * WaveTrack::GetClipAtTime ( double  time)

Definition at line 2153 of file WaveTrack.cpp.

2154{
2155
2156 const auto clips = SortedClipArray();
2157 auto p = std::find_if(clips.rbegin(), clips.rend(), [&] (WaveClip* const& clip) {
2158 return time >= clip->GetPlayStartTime() && time <= clip->GetPlayEndTime(); });
2159
2160 // When two clips are immediately next to each other, the GetPlayEndTime() of the first clip
2161 // and the GetPlayStartTime() of the second clip may not be exactly equal due to rounding errors.
2162 // If "time" is the end time of the first of two such clips, and the end time is slightly
2163 // less than the start time of the second clip, then the first rather than the
2164 // second clip is found by the above code. So correct this.
2165 if (p != clips.rend() && p != clips.rbegin() &&
2166 time == (*p)->GetPlayEndTime() &&
2167 (*p)->SharesBoundaryWithNextClip(*(p-1))) {
2168 p--;
2169 }
2170
2171 return p != clips.rend() ? *p : nullptr;
2172}

References SortedClipArray().

Referenced by SelectHandle::Click(), GetEnvelopeAtTime(), GetSequenceAtTime(), and PasteOverPreservingClips().

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

◆ GetClipByIndex() [1/2]

WaveClip * WaveTrack::GetClipByIndex ( int  index)

Definition at line 2240 of file WaveTrack.cpp.

2241{
2242 if(index < (int)mClips.size())
2243 return mClips[index].get();
2244 else
2245 return nullptr;
2246}

References mClips.

Referenced by GetClipByIndex(), MergeClips(), and PasteWaveTrack().

Here is the caller graph for this function:

◆ GetClipByIndex() [2/2]

const WaveClip * WaveTrack::GetClipByIndex ( int  index) const

Definition at line 2248 of file WaveTrack.cpp.

2249{
2250 return const_cast<WaveTrack&>(*this).GetClipByIndex(index);
2251}
WaveClip * GetClipByIndex(int index)
Definition: WaveTrack.cpp:2240

References GetClipByIndex().

Here is the call graph for this function:

◆ GetClipIndex()

int WaveTrack::GetClipIndex ( const WaveClip clip) const

Definition at line 2233 of file WaveTrack.cpp.

2234{
2235 int result;
2236 FindClip(mClips, clip, &result);
2237 return result;
2238}
WaveClipHolders::iterator FindClip(WaveClipHolders &list, const WaveClip *clip, int *distance=nullptr)
Definition: WaveTrack.cpp:1032

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

Referenced by ClearAndPaste(), and WaveTrackLocations::Update().

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

◆ GetClips() [1/2]

WaveClipHolders & WaveTrack::GetClips ( )
inline

◆ GetClips() [2/2]

const WaveClipConstHolders & WaveTrack::GetClips ( ) const
inline

Definition at line 320 of file WaveTrack.h.

321 { return reinterpret_cast< const WaveClipConstHolders& >( mClips ); }
std::vector< std::shared_ptr< const WaveClip > > WaveClipConstHolders
Definition: WaveClip.h:43

◆ GetDefaultAudioTrackNamePreference()

wxString WaveTrack::GetDefaultAudioTrackNamePreference ( )
static

Definition at line 164 of file WaveTrack.cpp.

165{
167
168 if (name.empty() || ( name == DefaultName.MSGID() ))
169 // When nothing was specified,
170 // the default-default is whatever translation of...
171 /* i18n-hint: The default name for an audio track. */
172 return DefaultName.Translation();
173 else
174 return name;
175}
static auto DefaultName
Definition: WaveTrack.cpp:162
StringSetting AudioTrackNameSetting
Definition: WaveTrack.cpp:2606
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:206

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

Get the time at which the last clip in the track ends, plus recorded stuff.

Returns
time in seconds, or zero if there are no clips in the track.

Implements Track.

Definition at line 1848 of file WaveTrack.cpp.

1849{
1850 bool found = false;
1851 double best = 0.0;
1852
1853 if (mClips.empty())
1854 return 0;
1855
1856 for (const auto &clip : mClips)
1857 if (!found)
1858 {
1859 found = true;
1860 best = clip->GetPlayEndTime();
1861 }
1862 else if (clip->GetPlayEndTime() > best)
1863 best = clip->GetPlayEndTime();
1864
1865 return best;
1866}

References mClips.

Referenced by AUPImportFileHandle::AddSilence(), EffectTruncSilence::Analyze(), Copy(), Effect::GetBounds(), PasteWaveTrack(), EffectChangeSpeed::Process(), EffectSBSMS::Process(), NyquistEffect::ProcessOne(), EffectStereoToMono::ProcessOne(), GetInfoCommand::SendTracks(), SyncLockAdjust(), and Trim().

Here is the caller graph for this function:

◆ GetEnvelopeAtTime()

Envelope * WaveTrack::GetEnvelopeAtTime ( double  time)

Definition at line 2174 of file WaveTrack.cpp.

2175{
2176 WaveClip* clip = GetClipAtTime(time);
2177 if (clip)
2178 return clip->GetEnvelope();
2179 else
2180 return NULL;
2181}
Envelope * GetEnvelope()
Definition: WaveClip.h:219
WaveClip * GetClipAtTime(double time)
Definition: WaveTrack.cpp:2153

References GetClipAtTime(), and WaveClip::GetEnvelope().

Here is the call graph for this function:

◆ GetEnvelopeValues()

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

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

Implements SampleTrack.

Definition at line 2085 of file WaveTrack.cpp.

2087{
2088 // The output buffer corresponds to an unbroken span of time which the callers expect
2089 // to be fully valid. As clips are processed below, the output buffer is updated with
2090 // envelope values from any portion of a clip, start, end, middle, or none at all.
2091 // Since this does not guarantee that the entire buffer is filled with values we need
2092 // to initialize the entire buffer to a default value.
2093 //
2094 // This does mean that, in the cases where a usable clip is located, the buffer value will
2095 // be set twice. Unfortunately, there is no easy way around this since the clips are not
2096 // stored in increasing time order. If they were, we could just track the time as the
2097 // buffer is filled.
2098 for (decltype(bufferLen) i = 0; i < bufferLen; i++)
2099 {
2100 buffer[i] = 1.0;
2101 }
2102
2103 double startTime = t0;
2104 auto tstep = 1.0 / mRate;
2105 double endTime = t0 + tstep * bufferLen;
2106 for (const auto &clip: mClips)
2107 {
2108 // IF clip intersects startTime..endTime THEN...
2109 auto dClipStartTime = clip->GetPlayStartTime();
2110 auto dClipEndTime = clip->GetPlayEndTime();
2111 if ((dClipStartTime < endTime) && (dClipEndTime > startTime))
2112 {
2113 auto rbuf = buffer;
2114 auto rlen = bufferLen;
2115 auto rt0 = t0;
2116
2117 if (rt0 < dClipStartTime)
2118 {
2119 // This is not more than the number of samples in
2120 // (endTime - startTime) which is bufferLen:
2121 auto nDiff = (sampleCount)floor((dClipStartTime - rt0) * mRate + 0.5);
2122 auto snDiff = nDiff.as_size_t();
2123 rbuf += snDiff;
2124 wxASSERT(snDiff <= rlen);
2125 rlen -= snDiff;
2126 rt0 = dClipStartTime;
2127 }
2128
2129 if (rt0 + rlen*tstep > dClipEndTime)
2130 {
2131 auto nClipLen = clip->GetPlayEndSample() - clip->GetPlayStartSample();
2132
2133 if (nClipLen <= 0) // Testing for bug 641, this problem is consistently '== 0', but doesn't hurt to check <.
2134 return;
2135
2136 // This check prevents problem cited in http://bugzilla.audacityteam.org/show_bug.cgi?id=528#c11,
2137 // Gale's cross_fade_out project, which was already corrupted by bug 528.
2138 // This conditional prevents the previous write past the buffer end, in clip->GetEnvelope() call.
2139 // Never increase rlen here.
2140 // PRL bug 827: rewrote it again
2141 rlen = limitSampleBufferSize( rlen, nClipLen );
2142 rlen = std::min(rlen, size_t(floor(0.5 + (dClipEndTime - rt0) / tstep)));
2143 }
2144 // Samples are obtained for the purpose of rendering a wave track,
2145 // so quantize time
2146 clip->GetEnvelope()->GetValues(rbuf, rlen, rt0, tstep);
2147 }
2148 }
2149}

References limitSampleBufferSize(), mClips, min(), and mRate.

Here is the call graph for this function:

◆ GetErrorOpening()

bool WaveTrack::GetErrorOpening ( )
overridevirtual

Reimplemented from Track.

Definition at line 1811 of file WaveTrack.cpp.

1812{
1813 for (const auto &clip : mClips)
1814 if (clip->GetSequence()->GetErrorOpening())
1815 return true;
1816
1817 return false;
1818}

References mClips.

◆ GetGain()

float WaveTrack::GetGain ( ) const

Definition at line 413 of file WaveTrack.cpp.

414{
415 return GainAndPan::Get(*this).GetGain();
416}

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 1669 of file WaveTrack.cpp.

1670{
1672}
size_t GetIdealBlockSize() const
Definition: Sequence.cpp:82
Sequence * GetSequence()
Definition: WaveClip.h:227
WaveClip * NewestOrNewClip()
Get access to the most recently added clip, or create a clip, if there is not already one....
Definition: WaveTrack.cpp:2202

References Sequence::GetIdealBlockSize(), WaveClip::GetSequence(), and NewestOrNewClip().

Referenced by NyquistEffect::GetCallback().

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

◆ GetIntervals() [1/2]

auto WaveTrack::GetIntervals ( ) const
overridevirtual

Report times on the track where important intervals begin and end, for UI to snap to.

Some intervals may be empty, and no ordering of the intervals is assumed.

Reimplemented from Track.

Definition at line 345 of file WaveTrack.cpp.

346{
347 return MakeIntervals<ConstIntervals>( mClips );
348}

References mClips.

◆ GetIntervals() [2/2]

auto WaveTrack::GetIntervals ( )
overridevirtual

This overload exposes the extra data of the intervals as non-const This overload exposes the extra data of the intervals as non-const

Reimplemented from Track.

Definition at line 350 of file WaveTrack.cpp.

351{
352 return MakeIntervals<Intervals>( mClips );
353}

◆ GetMaxBlockSize()

size_t WaveTrack::GetMaxBlockSize ( ) const
overridevirtual

This returns a nonnegative number of samples meant to size a memory buffer.

Implements SampleTrack.

Definition at line 1647 of file WaveTrack.cpp.

1648{
1649 decltype(GetMaxBlockSize()) maxblocksize = 0;
1650 for (const auto &clip : mClips)
1651 {
1652 maxblocksize = std::max(maxblocksize, clip->GetSequence()->GetMaxBlockSize());
1653 }
1654
1655 if (maxblocksize == 0)
1656 {
1657 // We really need the maximum block size, so create a
1658 // temporary sequence to get it.
1659 maxblocksize =
1661 .GetMaxBlockSize();
1662 }
1663
1664 wxASSERT(maxblocksize > 0);
1665
1666 return maxblocksize;
1667}
Two sample formats, remembering format of original source and describing stored format.
Definition: SampleFormat.h:77
A WaveTrack contains WaveClip(s). A WaveClip contains a Sequence. A Sequence is primarily an interfac...
Definition: Sequence.h:52

References GetMaxBlockSize(), mClips, mFormat, and mpFactory.

Referenced by EffectNormalize::AnalyseTrackData(), EffectTruncSilence::Analyze(), CompareAudioCommand::Apply(), BlockGenerator::GenerateTrack(), GetBestBlockSize(), GetMaxBlockSize(), EffectCompressor::InitPass1(), TrackSpectrumTransformer::Process(), EffectSBSMS::Process(), EffectEqualization::ProcessOne(), EffectClickRemoval::ProcessOne(), EffectNoiseRemoval::ProcessOne(), EffectStereoToMono::ProcessOne(), EffectNormalize::ProcessOne(), EffectChangeSpeed::ProcessOne(), EffectSimpleMono::ProcessOne(), EffectTwoPassSimpleMono::ProcessOne(), EffectReverse::ProcessOneClip(), VoiceKey::TestDirectionChanges(), VoiceKey::TestEnergy(), and VoiceKey::TestSignChanges().

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

◆ GetMinMax()

std::pair< float, float > WaveTrack::GetMinMax ( double  t0,
double  t1,
bool  mayThrow = true 
) const

Definition at line 1873 of file WaveTrack.cpp.

1875{
1876 std::pair<float, float> results {
1877 // we need these at extremes to make sure we find true min and max
1878 FLT_MAX, -FLT_MAX
1879 };
1880 bool clipFound = false;
1881
1882 if (t0 > t1) {
1883 if (mayThrow)
1885 return results;
1886 }
1887
1888 if (t0 == t1)
1889 return results;
1890
1891 for (const auto &clip: mClips)
1892 {
1893 if (t1 >= clip->GetPlayStartTime() && t0 <= clip->GetPlayEndTime())
1894 {
1895 clipFound = true;
1896 auto clipResults = clip->GetMinMax(t0, t1, mayThrow);
1897 if (clipResults.first < results.first)
1898 results.first = clipResults.first;
1899 if (clipResults.second > results.second)
1900 results.second = clipResults.second;
1901 }
1902 }
1903
1904 if(!clipFound)
1905 {
1906 results = { 0.f, 0.f }; // sensible defaults if no clips found
1907 }
1908
1909 return results;
1910}

References mClips, and THROW_INCONSISTENCY_EXCEPTION.

Referenced by EffectNormalize::AnalyseTrack(), and NyquistEffect::ProcessOne().

Here is the caller graph for this function:

◆ GetNumClips()

int WaveTrack::GetNumClips ( ) const

Definition at line 2253 of file WaveTrack.cpp.

2254{
2255 return mClips.size();
2256}

References mClips.

Referenced by PasteWaveTrack().

Here is the caller graph for this function:

◆ GetOffset()

double WaveTrack::GetOffset ( ) const
overridevirtual

Implements Track.

Definition at line 257 of file WaveTrack.cpp.

258{
259 return GetStartTime();
260}
double GetStartTime() const override
Get the time at which the first clip in the track starts.
Definition: WaveTrack.cpp:1828

References GetStartTime().

Referenced by TranscriptionToolBar::GetSamples(), and SetOffset().

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

◆ GetPan()

float WaveTrack::GetPan ( ) const

Definition at line 431 of file WaveTrack.cpp.

432{
433 return GainAndPan::Get(*this).GetPan();
434}

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:

◆ GetPlaySamplesCount()

sampleCount WaveTrack::GetPlaySamplesCount ( ) const

Definition at line 480 of file WaveTrack.cpp.

481{
482 sampleCount result{ 0 };
483
484 for (const auto& clip : mClips)
485 result += clip->GetPlaySamplesCount();
486
487 return result;
488}

References mClips.

◆ GetRate()

double WaveTrack::GetRate ( ) const
overridevirtual

◆ GetRMS()

float WaveTrack::GetRMS ( double  t0,
double  t1,
bool  mayThrow = true 
) const

Definition at line 1912 of file WaveTrack.cpp.

1913{
1914 if (t0 > t1) {
1915 if (mayThrow)
1917 return 0.f;
1918 }
1919
1920 if (t0 == t1)
1921 return 0.f;
1922
1923 double sumsq = 0.0;
1924 sampleCount length = 0;
1925
1926 for (const auto &clip: mClips)
1927 {
1928 // If t1 == clip->GetStartTime() or t0 == clip->GetEndTime(), then the clip
1929 // is not inside the selection, so we don't want it.
1930 // if (t1 >= clip->GetStartTime() && t0 <= clip->GetEndTime())
1931 if (t1 >= clip->GetPlayStartTime() && t0 <= clip->GetPlayEndTime())
1932 {
1933 auto clipStart = clip->TimeToSequenceSamples(std::max(t0, clip->GetPlayStartTime()));
1934 auto clipEnd = clip->TimeToSequenceSamples(std::min(t1, clip->GetPlayEndTime()));
1935
1936 float cliprms = clip->GetRMS(t0, t1, mayThrow);
1937
1938 sumsq += cliprms * cliprms * (clipEnd - clipStart).as_float();
1939 length += (clipEnd - clipStart);
1940 }
1941 }
1942 return length > 0 ? sqrt(sumsq / length.as_double()) : 0.0;
1943}
double as_double() const
Definition: SampleCount.h:46
__finl float_x4 __vecc sqrt(const float_x4 &a)

References sampleCount::as_double(), mClips, min(), staffpad::audio::simd::sqrt(), and THROW_INCONSISTENCY_EXCEPTION.

Referenced by EffectLoudness::GetTrackRMS(), and NyquistEffect::ProcessOne().

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

◆ GetSampleFormat()

sampleFormat WaveTrack::GetSampleFormat ( ) const
inlineoverridevirtual

Implements SampleTrack.

Definition at line 148 of file WaveTrack.h.

148{ return mFormat; }

Referenced by Copy(), anonymous_namespace{EditMenus.cpp}::EstimateCopyBytesCount(), and SyncLockAdjust().

Here is the caller graph for this function:

◆ GetSequenceAtTime()

Sequence * WaveTrack::GetSequenceAtTime ( double  time)

Definition at line 2183 of file WaveTrack.cpp.

2184{
2185 WaveClip* clip = GetClipAtTime(time);
2186 if (clip)
2187 return clip->GetSequence();
2188 else
2189 return NULL;
2190}

References GetClipAtTime(), and WaveClip::GetSequence().

Here is the call graph for this function:

◆ GetSequenceSamplesCount()

sampleCount WaveTrack::GetSequenceSamplesCount ( ) const

Definition at line 490 of file WaveTrack.cpp.

491{
492 sampleCount result{ 0 };
493
494 for (const auto& clip : mClips)
495 result += clip->GetSequenceSamplesCount();
496
497 return result;
498}

References mClips.

◆ GetStartTime()

double WaveTrack::GetStartTime ( ) const
overridevirtual

Get the time at which the first clip in the track starts.

Returns
time in seconds, or zero if there are no clips in the track

Implements Track.

Definition at line 1828 of file WaveTrack.cpp.

1829{
1830 bool found = false;
1831 double best = 0.0;
1832
1833 if (mClips.empty())
1834 return 0;
1835
1836 for (const auto &clip : mClips)
1837 if (!found)
1838 {
1839 found = true;
1840 best = clip->GetPlayStartTime();
1841 }
1842 else if (clip->GetPlayStartTime() < best)
1843 best = clip->GetPlayStartTime();
1844
1845 return best;
1846}

References mClips.

Referenced by Effect::GetBounds(), GetOffset(), PasteWaveTrack(), EffectChangeSpeed::Process(), EffectSBSMS::Process(), EffectStereoToMono::ProcessOne(), GetInfoCommand::SendTracks(), and Trim().

Here is the caller graph for this function:

◆ GetTypeInfo()

auto WaveTrack::GetTypeInfo ( ) const
overridevirtual

Reimplemented from WritableSampleTrack.

Definition at line 315 of file WaveTrack.cpp.

316{
317 return typeInfo();
318}

References typeInfo().

Here is the call graph for this function:

◆ GetWaveColorIndex()

int WaveTrack::GetWaveColorIndex ( ) const
inline

Definition at line 142 of file WaveTrack.h.

142{ return mWaveColorIndex; };

Referenced by CreateClip(), and InsertSilence().

Here is the caller graph for this function:

◆ HandleClear()

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

Definition at line 1074 of file WaveTrack.cpp.

1076{
1077 // For debugging, use an ASSERT so that we stop
1078 // closer to the problem.
1079 wxASSERT( t1 >= t0 );
1080 if (t1 < t0)
1082
1083 bool editClipCanMove = GetEditClipsCanMove();
1084
1085 WaveClipPointers clipsToDelete;
1086 WaveClipHolders clipsToAdd;
1087
1088 // We only add cut lines when deleting in the middle of a single clip
1089 // The cut line code is not really prepared to handle other situations
1090 if (addCutLines)
1091 {
1092 for (const auto &clip : mClips)
1093 {
1094 if (!clip->BeforePlayStartTime(t1) && !clip->AfterPlayEndTime(t0) &&
1095 (clip->BeforePlayStartTime(t0) || clip->AfterPlayEndTime(t1)))
1096 {
1097 addCutLines = false;
1098 break;
1099 }
1100 }
1101 }
1102
1103 for (const auto &clip : mClips)
1104 {
1105 if (clip->BeforePlayStartTime(t0) && clip->AfterPlayEndTime(t1))
1106 {
1107 // Whole clip must be deleted - remember this
1108 clipsToDelete.push_back(clip.get());
1109 }
1110 else if (!clip->BeforePlayStartTime(t1) && !clip->AfterPlayEndTime(t0))
1111 {
1112 // Clip data is affected by command
1113 if (addCutLines)
1114 {
1115 // Don't modify this clip in place, because we want a strong
1116 // guarantee, and might modify another clip
1117 clipsToDelete.push_back( clip.get() );
1118 auto newClip = std::make_unique<WaveClip>( *clip, mpFactory, true );
1119 newClip->ClearAndAddCutLine( t0, t1 );
1120 clipsToAdd.push_back( std::move( newClip ) );
1121 }
1122 else
1123 {
1124 if (split) {
1125 // Three cases:
1126
1127 if (clip->BeforePlayStartTime(t0)) {
1128 // Delete from the left edge
1129
1130 // Don't modify this clip in place, because we want a strong
1131 // guarantee, and might modify another clip
1132 clipsToDelete.push_back( clip.get() );
1133 auto newClip = std::make_unique<WaveClip>( *clip, mpFactory, true );
1134 newClip->TrimLeft(t1 - clip->GetPlayStartTime());
1135 clipsToAdd.push_back( std::move( newClip ) );
1136 }
1137 else if (clip->AfterPlayEndTime(t1)) {
1138 // Delete to right edge
1139
1140 // Don't modify this clip in place, because we want a strong
1141 // guarantee, and might modify another clip
1142 clipsToDelete.push_back( clip.get() );
1143 auto newClip = std::make_unique<WaveClip>( *clip, mpFactory, true );
1144 newClip->TrimRight(clip->GetPlayEndTime() - t0);
1145
1146 clipsToAdd.push_back( std::move( newClip ) );
1147 }
1148 else {
1149 // Delete in the middle of the clip...we actually create two
1150 // NEW clips out of the left and right halves...
1151
1152 auto leftClip = std::make_unique<WaveClip>(*clip, mpFactory, true);
1153 leftClip->TrimRight(clip->GetPlayEndTime() - t0);
1154 clipsToAdd.push_back(std::move(leftClip));
1155
1156 auto rightClip = std::make_unique<WaveClip>(*clip, mpFactory, true);
1157 rightClip->TrimLeft(t1 - rightClip->GetPlayStartTime());
1158 clipsToAdd.push_back(std::move(rightClip));
1159
1160 clipsToDelete.push_back(clip.get());
1161 }
1162 }
1163 else {
1164 // (We are not doing a split cut)
1165
1166 // Don't modify this clip in place, because we want a strong
1167 // guarantee, and might modify another clip
1168 clipsToDelete.push_back( clip.get() );
1169 auto newClip = std::make_unique<WaveClip>( *clip, mpFactory, true );
1170
1171 // clip->Clear keeps points < t0 and >= t1 via Envelope::CollapseRegion
1172 newClip->Clear(t0,t1);
1173
1174 clipsToAdd.push_back( std::move( newClip ) );
1175 }
1176 }
1177 }
1178 }
1179
1180 // Only now, change the contents of this track
1181 // use No-fail-guarantee for the rest
1182
1183 if (!split && editClipCanMove)
1184 {
1185 // Clip is "behind" the region -- offset it unless we're splitting
1186 // or we're using the "don't move other clips" mode
1187 for (const auto& clip : mClips)
1188 {
1189 if (clip->BeforePlayStartTime(t1))
1190 clip->Offset(-(t1 - t0));
1191 }
1192 }
1193
1194 for (const auto &clip: clipsToDelete)
1195 {
1196 auto myIt = FindClip(mClips, clip);
1197 if (myIt != mClips.end())
1198 mClips.erase(myIt); // deletes the clip!
1199 else
1200 wxASSERT(false);
1201 }
1202
1203 for (auto &clip: clipsToAdd)
1204 mClips.push_back(std::move(clip)); // transfer ownership
1205}
std::vector< WaveClip * > WaveClipPointers
Definition: WaveTrack.h:40

References anonymous_namespace{WaveTrack.cpp}::FindClip(), GetEditClipsCanMove(), mClips, mpFactory, and THROW_INCONSISTENCY_EXCEPTION.

Referenced by Clear(), ClearAndAddCutLine(), ClearAndPaste(), 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 1743 of file WaveTrack.cpp.

1744{
1745 if ( auto pChild = WaveTrackIORegistry::Get()
1746 .CallObjectAccessor(tag, *this) )
1747 return pChild;
1748
1749 //
1750 // This is legacy code (1.2 and previous) and is not called for NEW projects!
1751 //
1752 if (tag == "sequence" || tag == "envelope")
1753 {
1754 // This is a legacy project, so set the cached offset
1756
1757 // Legacy project file tracks are imported as one single wave clip
1758 if (tag == "sequence")
1759 return NewestOrNewClip()->GetSequence();
1760 else if (tag == "envelope")
1761 return NewestOrNewClip()->GetEnvelope();
1762 }
1763
1764 // JKC... for 1.1.0, one step better than what we had, but still badly broken.
1765 // If we see a waveblock at this level, we'd better generate a sequence.
1766 if (tag == "waveblock")
1767 {
1768 // This is a legacy project, so set the cached offset
1771 return pSeq;
1772 }
1773
1774 //
1775 // This is for the NEW file format (post-1.2)
1776 //
1777 if (tag == "waveclip")
1778 return CreateClip();
1779
1780 return nullptr;
1781}
WaveClip * CreateClip(double offset=.0, const wxString &name=wxEmptyString)
Definition: WaveTrack.cpp:2192
static XMLMethodRegistry & Get()
Get the unique instance.

References CreateClip(), XMLMethodRegistry< Host >::Get(), WaveClip::GetEnvelope(), WaveClip::GetSequence(), mLegacyProjectFileOffset, NewestOrNewClip(), and WaveClip::SetSequenceStartTime().

Here is the call graph for this function:

◆ HandleXMLEndTag()

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

Definition at line 1736 of file WaveTrack.cpp.

1737{
1738 // In case we opened a pre-multiclip project, we need to
1739 // simulate closing the waveclip tag.
1740 NewestOrNewClip()->HandleXMLEndTag("waveclip");
1741}
void HandleXMLEndTag(const std::string_view &tag) override
Definition: WaveClip.cpp:326

References WaveClip::HandleXMLEndTag(), and NewestOrNewClip().

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 1685 of file WaveTrack.cpp.

1686{
1687 if (tag == "wavetrack") {
1688 double dblValue;
1689 long nValue;
1690
1691 for (auto pair : attrs)
1692 {
1693 auto attr = pair.first;
1694 auto value = pair.second;
1695
1696 if (attr == "rate")
1697 {
1698 // mRate is an int, but "rate" in the project file is a float.
1699 if (!value.TryGet(dblValue) ||
1700 (dblValue < 1.0) || (dblValue > 1000000.0)) // allow a large range to be read
1701 return false;
1702
1703 mRate = lrint(dblValue);
1704 }
1705 else if (attr == "offset" && value.TryGet(dblValue))
1706 {
1707 // Offset is only relevant for legacy project files. The value
1708 // is cached until the actual WaveClip containing the legacy
1709 // track is created.
1710 mLegacyProjectFileOffset = dblValue;
1711 }
1712 else if (this->WritableSampleTrack::HandleXMLAttribute(attr, value))
1713 {}
1714 else if (this->Track::HandleCommonXMLAttribute(attr, value))
1715 ;
1716 else if (attr == "gain" && value.TryGet(dblValue))
1717 DoSetGain(dblValue);
1718 else if (attr == "pan" && value.TryGet(dblValue) &&
1719 (dblValue >= -1.0) && (dblValue <= 1.0))
1720 DoSetPan(dblValue);
1721 else if (attr == "linked" && value.TryGet(nValue))
1722 SetLinkType(ToLinkType(nValue), false);
1723 else if (attr == "colorindex" && value.TryGet(nValue))
1724 // Don't use SetWaveColorIndex as it sets the clips too.
1725 mWaveColorIndex = nValue;
1726 else if (attr == "sampleformat" && value.TryGet(nValue) &&
1728 mFormat = static_cast<sampleFormat>(nValue);
1729 } // while
1730 return true;
1731 }
1732
1733 return false;
1734}
sampleFormat
The ordering of these values with operator < agrees with the order of increasing bit width.
Definition: SampleFormat.h:30
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:1855
void SetLinkType(LinkType linkType, bool completeList=true)
Definition: Track.cpp:144
bool HandleCommonXMLAttribute(const std::string_view &attr, const XMLAttributeValueView &valueView)
Definition: Track.cpp:1165
void DoSetPan(float value)
Definition: WaveTrack.cpp:436
void DoSetGain(float value)
Definition: WaveTrack.cpp:418
#define lrint(dbl)
Definition: float_cast.h:169
Track::LinkType ToLinkType(int value)
Definition: WaveTrack.cpp:151

References DoSetGain(), DoSetPan(), Track::HandleCommonXMLAttribute(), PlayableTrack::HandleXMLAttribute(), Sequence::IsValidSampleFormat(), lrint, mFormat, mLegacyProjectFileOffset, mRate, mWaveColorIndex, Track::SetLinkType(), and anonymous_namespace{WaveTrack.cpp}::ToLinkType().

Here is the call graph for this function:

◆ HasTrivialEnvelope()

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

Implements SampleTrack.

Definition at line 2078 of file WaveTrack.cpp.

2079{
2080 auto &clips = GetClips();
2081 return std::all_of(clips.begin(), clips.end(),
2082 [](const auto &pClip){ return pClip->GetEnvelope()->IsTrivial(); });
2083}

References GetClips().

Here is the call graph for this function:

◆ Init()

void WaveTrack::Init ( const WaveTrack orig)
private

Definition at line 224 of file WaveTrack.cpp.

225{
227 mpFactory = orig.mpFactory;
228
229 mFormat = orig.mFormat;
231 mRate = orig.mRate;
232}
void Init(const Track &orig)
Definition: Track.cpp:55

References Track::Init(), mFormat, mpFactory, mRate, and mWaveColorIndex.

Referenced by Reinit().

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

◆ InsertSilence()

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

Definition at line 1437 of file WaveTrack.cpp.

1438{
1439 // Nothing to do, if length is zero.
1440 // Fixes Bug 1626
1441 if( len == 0 )
1442 return;
1443 if (len <= 0)
1445
1446 if (mClips.empty())
1447 {
1448 // Special case if there is no clip yet
1449 auto clip = std::make_unique<WaveClip>(mpFactory, mFormat, mRate, this->GetWaveColorIndex());
1450 clip->InsertSilence(0, len);
1451 // use No-fail-guarantee
1452 mClips.push_back( std::move( clip ) );
1453 return;
1454 }
1455 else {
1456 // Assume at most one clip contains t
1457 const auto end = mClips.end();
1458 const auto it = std::find_if( mClips.begin(), end,
1459 [&](const WaveClipHolder &clip) { return clip->WithinPlayRegion(t); } );
1460
1461 // use Strong-guarantee
1462 if (it != end)
1463 it->get()->InsertSilence(t, len);
1464
1465 // use No-fail-guarantee
1466 for (const auto &clip : mClips)
1467 {
1468 if (clip->BeforePlayStartTime(t))
1469 clip->Offset(len);
1470 }
1471 }
1472}

References PackedArray::end(), GetWaveColorIndex(), mClips, mFormat, mpFactory, mRate, and THROW_INCONSISTENCY_EXCEPTION.

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

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

◆ 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 510 of file WaveTrack.cpp.

511{
512 if (t0 > t1)
513 return true;
514
515 //wxPrintf("Searching for overlap in %.6f...%.6f\n", t0, t1);
516 for (const auto &clip : mClips)
517 {
518 if (!clip->BeforePlayStartTime(t1) && !clip->AfterPlayEndTime(t0)) {
519 //wxPrintf("Overlapping clip: %.6f...%.6f\n",
520 // clip->GetStartTime(),
521 // clip->GetEndTime());
522 // We found a clip that overlaps this region
523 return false;
524 }
525 }
526 //wxPrintf("No overlap found\n");
527
528 // Otherwise, no clips overlap this region
529 return true;
530}

References mClips.

Referenced by PasteWaveTrack(), Generator::Process(), and SyncLockAdjust().

Here is the caller graph for this function:

◆ Join()

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

Definition at line 1548 of file WaveTrack.cpp.

1549{
1550 // Merge all WaveClips overlapping selection into one
1551
1552 WaveClipPointers clipsToDelete;
1553 WaveClip* newClip{};
1554
1555 for (const auto &clip: mClips)
1556 {
1557 if (clip->GetPlayStartTime() < t1-(1.0/mRate) &&
1558 clip->GetPlayEndTime()-(1.0/mRate) > t0) {
1559
1560 // Put in sorted order
1561 auto it = clipsToDelete.begin(), end = clipsToDelete.end();
1562 for (; it != end; ++it)
1563 if ((*it)->GetPlayStartTime() > clip->GetPlayStartTime())
1564 break;
1565 //wxPrintf("Insert clip %.6f at position %d\n", clip->GetStartTime(), i);
1566 clipsToDelete.insert(it, clip.get());
1567 }
1568 }
1569
1570 //if there are no clips to DELETE, nothing to do
1571 if( clipsToDelete.size() == 0 )
1572 return;
1573
1574 auto t = clipsToDelete[0]->GetPlayStartTime();
1575 //preserve left trim data if any
1576 newClip = CreateClip(clipsToDelete[0]->GetSequenceStartTime(),
1577 clipsToDelete[0]->GetName());
1578
1579 for (const auto &clip : clipsToDelete)
1580 {
1581 //wxPrintf("t=%.6f adding clip (offset %.6f, %.6f ... %.6f)\n",
1582 // t, clip->GetOffset(), clip->GetStartTime(), clip->GetEndTime());
1583
1584 if (clip->GetPlayStartTime() - t > (1.0 / mRate)) {
1585 double addedSilence = (clip->GetPlayStartTime() - t);
1586 //wxPrintf("Adding %.6f seconds of silence\n");
1587 auto offset = clip->GetPlayStartTime();
1588 auto value = clip->GetEnvelope()->GetValue( offset );
1589 newClip->AppendSilence( addedSilence, value );
1590 t += addedSilence;
1591 }
1592
1593 //wxPrintf("Pasting at %.6f\n", t);
1594 newClip->Paste(t, clip);
1595
1596 t = newClip->GetPlayEndTime();
1597
1598 auto it = FindClip(mClips, clip);
1599 mClips.erase(it); // deletes the clip
1600 }
1601}
const wxString & GetName() const
Name is always the same for all channels of a group.
Definition: Track.cpp:64

References CreateClip(), PackedArray::end(), anonymous_namespace{WaveTrack.cpp}::FindClip(), Track::GetName(), mClips, and mRate.

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

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

◆ LinkConsistencyFix()

bool WaveTrack::LinkConsistencyFix ( bool  doFix,
bool  completeList 
)
overridevirtual

Check consistency of channel groups, and maybe fix it.

Parameters
doFixwhether to make any changes to correct inconsistencies
completeListwhether to assume that the TrackList containing this is completely loaded; if false, skip some of the checks
Returns
true if no inconsistencies were found

Reimplemented from Track.

Definition at line 274 of file WaveTrack.cpp.

275{
276 auto err = !WritableSampleTrack::LinkConsistencyFix(doFix, completeList);
277 if (completeList) {
278 auto linkType = GetLinkType();
279 if (static_cast<int>(linkType) == 1 || //Comes from old audacity version
280 linkType == LinkType::Aligned) {
281 auto next =
282 dynamic_cast<WaveTrack*>(*std::next(GetOwner()->Find(this)));
283 if (next == nullptr) {
284 //next track is absent or not a wave track, fix and report error
285 if (doFix) {
286 wxLogWarning(L"Right track %s is expected to be a WaveTrack."
287 "\n Removing link from left wave track %s.",
288 next->GetName(), GetName());
290 }
291 err = true;
292 }
293 else if (doFix) {
294 auto newLinkType =
295 AreAligned(SortedClipArray(), next->SortedClipArray())
297 //not an error
298 if (newLinkType != linkType)
299 SetLinkType(newLinkType);
300 }
301 }
302 }
303 return !err;
304}
Subclass * Find(const RegisteredFactory &key)
Get a (bare) pointer to an attachment, or null, down-cast it to Subclass *; will not create on demand...
Definition: ClientData.h:333
virtual bool LinkConsistencyFix(bool doFix=true, bool completeList=true)
Check consistency of channel groups, and maybe fix it.
Definition: Track.cpp:313
std::shared_ptr< TrackList > GetOwner() const
Definition: Track.h:333
LinkType GetLinkType() const noexcept
Definition: Track.cpp:1212
bool AreAligned(const WaveClipPointers &a, const WaveClipPointers &b)
Definition: WaveTrack.cpp:132

References Track::Aligned, anonymous_namespace{WaveTrack.cpp}::AreAligned(), ClientData::Site< Host, ClientData, ObjectCopyingPolicy, Pointer, ObjectLockingPolicy, RegistryLockingPolicy >::Find(), Track::GetLinkType(), Track::GetName(), Track::GetOwner(), Track::Group, Track::LinkConsistencyFix(), Track::None, Track::SetLinkType(), and SortedClipArray().

Here is the call graph for this function:

◆ MakeClipCopyName()

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

Definition at line 372 of file WaveTrack.cpp.

373{
374 auto name = originalName;
375 for (auto i = 1;; ++i)
376 {
377 if (FindClipByName(name) == nullptr)
378 return name;
379 //i18n-hint Template for clip name generation on copy-paste
380 name = XC("%s.%i", "clip name template").Format(originalName, i).Translation();
381 }
382}
#define XC(s, c)
Definition: Internat.h:37
const WaveClip * FindClipByName(const wxString &name) const
Returns nullptr if clip with such name was not found.
Definition: WaveTrack.cpp:355

References FindClipByName(), name, and XC.

Referenced by PasteWaveTrack().

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 384 of file WaveTrack.cpp.

385{
386 auto name = GetName();
387 for (auto i = 1;; ++i)
388 {
389 if (FindClipByName(name) == nullptr)
390 return name;
391 //i18n-hint Template for clip name generation on inserting new empty clip
392 name = XC("%s %i", "clip name template").Format(GetName(), i).Translation();
393 }
394}

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

Referenced by NewestOrNewClip(), PasteWaveTrack(), and RightmostOrNewClip().

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

◆ Merge()

void WaveTrack::Merge ( const Track orig)

Definition at line 243 of file WaveTrack.cpp.

244{
245 orig.TypeSwitch( [&](const WaveTrack *pwt) {
246 const WaveTrack &wt = *pwt;
247 // Copy attached data from orig. Nullify data in this where orig had null.
248 Attachments &attachments = *this;
249 attachments = *pwt;
250 });
251}
SampleTrackAttachments Attachments
Definition: SampleTrack.h:36
R TypeSwitch(const Functions &...functions)
Use this function rather than testing track type explicitly and making down-casts.
Definition: Track.h:755

References Track::TypeSwitch().

Referenced by WaveTrackMenuTable::OnMergeStereo().

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

◆ MergeClips()

void WaveTrack::MergeClips ( int  clipidx1,
int  clipidx2 
)
Exception safety guarantee:
Strong

Definition at line 2447 of file WaveTrack.cpp.

2448{
2449 WaveClip* clip1 = GetClipByIndex(clipidx1);
2450 WaveClip* clip2 = GetClipByIndex(clipidx2);
2451
2452 if (!clip1 || !clip2) // Could happen if one track of a linked pair had a split and the other didn't.
2453 return; // Don't throw, just do nothing.
2454
2455 // Append data from second clip to first clip
2456 // use Strong-guarantee
2457 clip1->Paste(clip1->GetPlayEndTime(), clip2);
2458
2459 // use No-fail-guarantee for the rest
2460 // Delete second clip
2461 auto it = FindClip(mClips, clip2);
2462 mClips.erase(it);
2463}

References anonymous_namespace{WaveTrack.cpp}::FindClip(), GetClipByIndex(), WaveClip::GetPlayEndTime(), mClips, and WaveClip::Paste().

Referenced by ClearAndPaste().

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

◆ New()

WaveTrack * WaveTrack::New ( AudacityProject project)
static

Definition at line 192 of file WaveTrack.cpp.

193{
194 auto &trackFactory = WaveTrackFactory::Get( project );
195 auto &tracks = TrackList::Get( project );
196 auto result = tracks.Add(trackFactory.Create());
197 result->AttachedTrackObjects::BuildAll();
198 return result;
199}
static TrackList & Get(AudacityProject &project)
Definition: Track.cpp:360
static WaveTrackFactory & Get(AudacityProject &project)
Definition: WaveTrack.cpp:2566

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

Here is the call graph for this function:

◆ NewestOrNewClip()

WaveClip * 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 2202 of file WaveTrack.cpp.

2203{
2204 if (mClips.empty()) {
2206 }
2207 else
2208 return mClips.back().get();
2209}
double mOffset
Definition: Track.h:372
wxString MakeNewClipName() const
Definition: WaveTrack.cpp:384

References CreateClip(), MakeNewClipName(), mClips, and Track::mOffset.

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

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

◆ Paste()

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

Definition at line 1403 of file WaveTrack.cpp.

1404{
1405 if (auto other = dynamic_cast<const WaveTrack*>(src))
1406 PasteWaveTrack(t0, other);
1407 else
1408 // THROW_INCONSISTENCY_EXCEPTION; // ?
1409 (void)0;// Empty if intentional.
1410}
void PasteWaveTrack(double t0, const WaveTrack *other)
Definition: WaveTrack.cpp:1248

References PasteWaveTrack().

Referenced by ClearAndPaste(), PasteOverPreservingClips(), EffectStereoToMono::ProcessOne(), EffectPaulstretch::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 ) const
overridevirtual

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

Returns
A smart pointer to the track; its use_count() can tell whether it is new

Implements Track.

Definition at line 336 of file WaveTrack.cpp.

337{
338 auto &trackFactory = WaveTrackFactory::Get( project );
339 auto &pSampleBlockFactory = trackFactory.GetSampleBlockFactory();
340 auto pNewTrack = EmptyCopy( pSampleBlockFactory );
341 pNewTrack->Paste(0.0, this);
342 return pNewTrack;
343}

References EmptyCopy(), and WaveTrackFactory::Get().

Here is the call graph for this function:

◆ PasteWaveTrack()

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

Definition at line 1248 of file WaveTrack.cpp.

1249{
1250 //
1251 // Pasting is a bit complicated, because with the existence of multiclip mode,
1252 // we must guess the behaviour the user wants.
1253 //
1254 // Currently, two modes are implemented:
1255 //
1256 // - If a single clip should be pasted, and it should be pasted inside another
1257 // clip, no NEW clips are generated. The audio is simply inserted.
1258 // This resembles the old (pre-multiclip support) behaviour. However, if
1259 // the clip is pasted outside of any clip, a NEW clip is generated. This is
1260 // the only behaviour which is different to what was done before, but it
1261 // shouldn't confuse users too much.
1262 //
1263 // - If multiple clips should be pasted, or a single clip that does not fill
1264 // the duration of the pasted track, these are always pasted as single
1265 // clips, and the current clip is split, when necessary. This may seem
1266 // strange at first, but it probably is better than trying to auto-merge
1267 // anything. The user can still merge the clips by hand (which should be a
1268 // simple command reachable by a hotkey or single mouse click).
1269 //
1270
1271 if (other->GetNumClips() == 0)
1272 return;
1273
1274 //wxPrintf("paste: we have at least one clip\n");
1275
1276 bool singleClipMode = other->GetNumClips() == 1 &&
1277 std::abs(other->GetStartTime()) < LongSamplesToTime(1) * 0.5;
1278
1279 const double insertDuration = other->GetEndTime();
1280 if (insertDuration != 0 && insertDuration < 1.0 / mRate)
1281 // PRL: I added this check to avoid violations of preconditions in other WaveClip and Sequence
1282 // methods, but allow the value 0 so I don't subvert the purpose of commit
1283 // 739422ba70ceb4be0bb1829b6feb0c5401de641e which causes append-recording always to make
1284 // a new clip.
1285 return;
1286
1287 //wxPrintf("Check if we need to make room for the pasted data\n");
1288
1289 auto pastingFromTempTrack = !other->GetOwner();
1290 bool editClipCanMove = GetEditClipsCanMove();
1291
1292 // Make room for the pasted data
1293 if (editClipCanMove) {
1294 if (!singleClipMode) {
1295 // We need to insert multiple clips, so split the current clip and ...
1296 SplitAt(t0);
1297 }
1298 //else if there is a clip at t0 insert new clip inside it and ...
1299
1300 // ... move everything to the right
1301 for (const auto& clip : mClips)
1302 {
1303 if (clip->GetPlayStartTime() > t0 - (1.0 / mRate))
1304 clip->Offset(insertDuration);
1305 }
1306 }
1307
1308 if (singleClipMode)
1309 {
1310 // Single clip mode
1311 // wxPrintf("paste: checking for single clip mode!\n");
1312
1313 WaveClip* insideClip = nullptr;
1314
1315 for (const auto& clip : mClips)
1316 {
1317 if (editClipCanMove)
1318 {
1319 if (clip->WithinPlayRegion(t0))
1320 {
1321 //wxPrintf("t0=%.6f: inside clip is %.6f ... %.6f\n",
1322 // t0, clip->GetStartTime(), clip->GetEndTime());
1323 insideClip = clip.get();
1324 break;
1325 }
1326 }
1327 else
1328 {
1329 // If clips are immovable we also allow prepending to clips
1330 if (clip->WithinPlayRegion(t0) ||
1331 TimeToLongSamples(t0) == clip->GetPlayStartSample())
1332 {
1333 insideClip = clip.get();
1334 break;
1335 }
1336 }
1337 }
1338
1339 if (insideClip)
1340 {
1341 // Exhibit traditional behaviour
1342 //wxPrintf("paste: traditional behaviour\n");
1343 if (!editClipCanMove)
1344 {
1345 // We did not move other clips out of the way already, so
1346 // check if we can paste without having to move other clips
1347 for (const auto& clip : mClips)
1348 {
1349 if (clip->GetPlayStartTime() > insideClip->GetPlayStartTime() &&
1350 insideClip->GetPlayEndTime() + insertDuration >
1351 clip->GetPlayStartTime())
1352 // Strong-guarantee in case of this path
1353 // not that it matters.
1356 XO("There is not enough room available to paste the selection"),
1357 XO("Warning"),
1358 "Error:_Insufficient_space_in_track"
1359 };
1360 }
1361 }
1362 insideClip->Paste(t0, other->GetClipByIndex(0));
1363 return;
1364 }
1365 // Just fall through and exhibit NEW behaviour
1366 }
1367
1368 // Insert NEW clips
1369 //wxPrintf("paste: multi clip mode!\n");
1370
1371 if (!editClipCanMove && !IsEmpty(t0, t0 + insertDuration - 1.0 / mRate))
1372 // Strong-guarantee in case of this path
1373 // not that it matters.
1376 XO("There is not enough room available to paste the selection"),
1377 XO("Warning"),
1378 "Error:_Insufficient_space_in_track"
1379 };
1380
1381 for (const auto& clip : other->mClips)
1382 {
1383 // AWD Oct. 2009: Don't actually paste in placeholder clips
1384 if (!clip->GetIsPlaceholder())
1385 {
1386 auto newClip =
1387 std::make_unique<WaveClip>(*clip, mpFactory, true);
1388 newClip->Resample(mRate);
1389 newClip->Offset(t0);
1390 newClip->MarkChanged();
1391 if (pastingFromTempTrack)
1392 //Clips from the tracks which aren't bound to any TrackList are
1393 //considered to be new entities, thus named using "new" name template
1394 newClip->SetName(MakeNewClipName());
1395 else
1396 newClip->SetName(MakeClipCopyName(clip->GetName()));
1397 mClips.push_back(std::move(newClip)); // transfer ownership
1398 }
1399 }
1400}
void SplitAt(double t)
Definition: WaveTrack.cpp:2363
bool IsEmpty(double t0, double t1) const
Returns true if there are no WaveClips in the specified region.
Definition: WaveTrack.cpp:510
int GetNumClips() const
Definition: WaveTrack.cpp:2253
wxString MakeClipCopyName(const wxString &originalName) const
Definition: WaveTrack.cpp:372

References BadUserAction, GetClipByIndex(), GetEditClipsCanMove(), GetEndTime(), GetNumClips(), Track::GetOwner(), WaveClip::GetPlayEndTime(), WaveClip::GetPlayStartTime(), GetStartTime(), IsEmpty(), SampleTrack::LongSamplesToTime(), MakeClipCopyName(), MakeNewClipName(), mClips, mpFactory, mRate, WaveClip::Paste(), SplitAt(), SampleTrack::TimeToLongSamples(), and XO().

Referenced by Paste().

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

◆ Reinit()

void WaveTrack::Reinit ( const WaveTrack orig)

Definition at line 234 of file WaveTrack.cpp.

235{
236 Init(orig);
237
238 // Copy attached data from orig. Nullify data in this where orig had null.
239 Attachments &attachments = *this;
240 attachments = orig;
241}
void Init(const WaveTrack &orig)
Definition: WaveTrack.cpp:224

References Init().

Referenced by ProjectAudioManager::DoRecord().

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

◆ RemoveAndReturnClip()

std::shared_ptr< WaveClip > WaveTrack::RemoveAndReturnClip ( WaveClip clip)

Definition at line 1048 of file WaveTrack.cpp.

1049{
1050 // Be clear about who owns the clip!!
1051 auto it = FindClip(mClips, clip);
1052 if (it != mClips.end()) {
1053 auto result = std::move(*it); // Array stops owning the clip, before we shrink it
1054 mClips.erase(it);
1055 return result;
1056 }
1057 else
1058 return {};
1059}

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

Referenced by EffectReverse::ProcessOneWave().

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

◆ RemoveCutLine()

bool WaveTrack::RemoveCutLine ( double  cutLinePosition)

Definition at line 2437 of file WaveTrack.cpp.

2438{
2439 for (const auto &clip : mClips)
2440 if (clip->RemoveCutLine(cutLinePosition))
2441 return true;
2442
2443 return false;
2444}

References mClips.

◆ 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 2467 of file WaveTrack.cpp.

2468{
2469 for (const auto &clip : mClips)
2470 clip->Resample(rate, progress);
2471
2472 mRate = rate;
2473}

References mClips, and mRate.

◆ RightmostOrNewClip()

WaveClip * 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 2212 of file WaveTrack.cpp.

2213{
2214 if (mClips.empty()) {
2216 }
2217 else
2218 {
2219 auto it = mClips.begin();
2220 WaveClip *rightmost = (*it++).get();
2221 double maxOffset = rightmost->GetPlayStartTime();
2222 for (auto end = mClips.end(); it != end; ++it)
2223 {
2224 WaveClip *clip = it->get();
2225 double offset = clip->GetPlayStartTime();
2226 if (maxOffset < offset)
2227 maxOffset = offset, rightmost = clip;
2228 }
2229 return rightmost;
2230 }
2231}

References CreateClip(), PackedArray::end(), WaveClip::GetPlayStartTime(), MakeNewClipName(), mClips, and Track::mOffset.

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

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

◆ Set()

void WaveTrack::Set ( constSamplePtr  buffer,
sampleFormat  format,
sampleCount  start,
size_t  len,
sampleFormat  effectiveFormat = widestSampleFormat 
)
Exception safety guarantee:
Weak
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 2028 of file WaveTrack.cpp.

2030{
2031 for (const auto &clip: mClips)
2032 {
2033 auto clipStart = clip->GetPlayStartSample();
2034 auto clipEnd = clip->GetPlayEndSample();
2035
2036 if (clipEnd > start && clipStart < start+len)
2037 {
2038 // Clip sample region and Get/Put sample region overlap
2039 auto samplesToCopy =
2040 std::min( start+len - clipStart, clip->GetPlaySamplesCount() );
2041 auto startDelta = clipStart - start;
2042 decltype(startDelta) inclipDelta = 0;
2043 if (startDelta < 0)
2044 {
2045 inclipDelta = -startDelta; // make positive value
2046 samplesToCopy -= inclipDelta;
2047 // samplesToCopy is now either len or
2048 // (clipEnd - clipStart) - (start - clipStart)
2049 // == clipEnd - start > 0
2050 // samplesToCopy is not more than len
2051 //
2052 startDelta = 0;
2053 // startDelta is zero
2054 }
2055 else {
2056 // startDelta is nonnegative and less than len
2057 // samplesToCopy is positive and not more than len
2058 }
2059
2060 clip->SetSamples(
2061 buffer + startDelta.as_size_t() * SAMPLE_SIZE(format),
2062 format, inclipDelta, samplesToCopy.as_size_t(), effectiveFormat );
2063 clip->MarkChanged();
2064 }
2065 }
2066}

References format, mClips, min(), and SAMPLE_SIZE.

Referenced by EffectAutoDuck::ApplyDuckFade(), WaveTrackSink::DoConsume(), EffectTruncSilence::DoRemoval(), EffectClickRemoval::ProcessOne(), EffectRepair::ProcessOne(), EffectNormalize::ProcessOne(), EffectSimpleMono::ProcessOne(), EffectTwoPassSimpleMono::ProcessOne(), and EffectReverse::ProcessOneClip().

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 423 of file WaveTrack.cpp.

424{
425 if (GetGain() != newGain) {
426 DoSetGain(newGain);
427 Notify(true);
428 }
429}
void Notify(bool allChannels, int code=-1)
Definition: Track.cpp:265

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:

◆ SetOffset()

void WaveTrack::SetOffset ( double  o)
overridevirtual
Exception safety guarantee:
No-fail

Reimplemented from Track.

Definition at line 263 of file WaveTrack.cpp.

264{
265 double delta = o - GetOffset();
266
267 for (const auto &clip : mClips)
268 // assume No-fail-guarantee
269 clip->Offset(delta);
270
271 mOffset = o;
272}
double GetOffset() const override
Definition: WaveTrack.cpp:257

References GetOffset(), mClips, and Track::mOffset.

Here is the call graph for this function:

◆ SetPan()

void WaveTrack::SetPan ( float  newPan)

Definition at line 441 of file WaveTrack.cpp.

442{
443 if (newPan > 1.0)
444 newPan = 1.0;
445 else if (newPan < -1.0)
446 newPan = -1.0;
447
448 if ( GetPan() != newPan ) {
449 DoSetPan(newPan);
450 Notify(true);
451 }
452}

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

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

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

◆ SetRate()

void WaveTrack::SetRate ( double  newRate)

Definition at line 401 of file WaveTrack.cpp.

402{
403 wxASSERT( newRate > 0 );
404 newRate = std::max( 1.0, newRate );
405 auto ratio = mRate / newRate;
406 mRate = (int) newRate;
407 for (const auto &clip : mClips) {
408 clip->SetRate((int)newRate);
409 clip->SetSequenceStartTime( clip->GetSequenceStartTime() * ratio );
410 }
411}

References mClips, and mRate.

◆ SetWaveColorIndex()

void WaveTrack::SetWaveColorIndex ( int  colorIndex)
Exception safety guarantee:
Strong

Definition at line 473 of file WaveTrack.cpp.

474{
475 for (const auto &clip : mClips)
476 clip->SetColourIndex( colorIndex );
477 mWaveColorIndex = colorIndex;
478}

References mClips, and mWaveColorIndex.

Referenced by SetTrackVisualsCommand::ApplyInner().

Here is the caller graph for this function:

◆ Silence()

void WaveTrack::Silence ( double  t0,
double  t1 
)
override

Definition at line 1412 of file WaveTrack.cpp.

1413{
1414 if (t1 < t0)
1416
1417 auto start = TimeToLongSamples(t0);
1418 auto end = TimeToLongSamples(t1);
1419
1420 for (const auto &clip : mClips)
1421 {
1422 auto clipStart = clip->GetPlayStartSample();
1423 auto clipEnd = clip->GetPlayEndSample();
1424
1425 if (clipEnd > start && clipStart < end)
1426 {
1427 auto offset = std::max(start - clipStart, sampleCount(0));
1428 // Clip sample region and Get/Put sample region overlap
1429 auto length = std::min(end, clipEnd) - (clipStart + offset);
1430
1431 clip->SetSilence(offset, length);
1432 }
1433 }
1434}

References PackedArray::end(), mClips, min(), THROW_INCONSISTENCY_EXCEPTION, and SampleTrack::TimeToLongSamples().

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

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

◆ SortedClipArray() [1/2]

WaveClipPointers WaveTrack::SortedClipArray ( )

◆ SortedClipArray() [2/2]

WaveClipConstPointers WaveTrack::SortedClipArray ( ) const

Definition at line 2494 of file WaveTrack.cpp.

2495{
2496 return FillSortedClipArray<WaveClipConstPointers>(mClips);
2497}

References mClips.

◆ Split()

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

Definition at line 2355 of file WaveTrack.cpp.

2356{
2357 SplitAt( t0 );
2358 if( t0 != t1 )
2359 SplitAt( t1 );
2360}

References SplitAt().

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

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

◆ SplitAt()

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

Definition at line 2363 of file WaveTrack.cpp.

2364{
2365 for (const auto &c : mClips)
2366 {
2367 if (c->WithinPlayRegion(t))
2368 {
2370 auto newClip = std::make_unique<WaveClip>( *c, mpFactory, true );
2371 c->TrimRightTo(t);// put t on a sample
2372 newClip->TrimLeftTo(t);
2373
2374 // This could invalidate the iterators for the loop! But we return
2375 // at once so it's okay
2376 mClips.push_back(std::move(newClip)); // transfer ownership
2377 return;
2378 }
2379 }
2380}

References SampleTrack::LongSamplesToTime(), mClips, mpFactory, and SampleTrack::TimeToLongSamples().

Referenced by PasteWaveTrack(), EffectReverse::ProcessOneWave(), and Split().

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

◆ SplitCut()

Track::Holder WaveTrack::SplitCut ( double  t0,
double  t1 
)
Exception safety guarantee:
Strong

Definition at line 545 of file WaveTrack.cpp.

546{
547 if (t1 < t0)
549
550 // SplitCut is the same as 'Copy', then 'SplitDelete'
551 auto tmp = Copy(t0, t1);
552
553 SplitDelete(t0, t1);
554
555 return tmp;
556}

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

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

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

◆ SplitDelete()

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

Definition at line 1006 of file WaveTrack.cpp.

1007{
1008 bool addCutLines = false;
1009 bool split = true;
1010 HandleClear(t0, t1, addCutLines, split);
1011}

References HandleClear().

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

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

Reimplemented from Track.

Definition at line 1207 of file WaveTrack.cpp.

1208{
1209 if (newT1 > oldT1) {
1210 // Insert space within the track
1211
1212 // JKC: This is a rare case where using >= rather than > on a float matters.
1213 // GetEndTime() looks through the clips and may give us EXACTLY the same
1214 // value as T1, when T1 was set to be at the end of one of those clips.
1215 if (oldT1 >= GetEndTime())
1216 return;
1217
1218 // If track is empty at oldT1 insert whitespace; otherwise, silence
1219 if (IsEmpty(oldT1, oldT1))
1220 {
1221 // Check if clips can move
1222 if (EditClipsCanMove.Read()) {
1223 const auto offset = newT1 - oldT1;
1224 for(const auto& clip : mClips)
1225 {
1226 if (clip->GetPlayStartTime() > oldT1 - (1.0 / mRate))
1227 clip->Offset(offset);
1228 }
1229 }
1230 return;
1231 }
1232 else {
1233 // AWD: Could just use InsertSilence() on its own here, but it doesn't
1234 // follow EditClipCanMove rules (Paste() does it right)
1235 auto tmp = std::make_shared<WaveTrack>(
1237
1238 tmp->InsertSilence(0.0, newT1 - oldT1);
1239 tmp->Flush();
1240 Paste(oldT1, tmp.get());
1241 }
1242 }
1243 else if (newT1 < oldT1) {
1244 Clear(newT1, oldT1);
1245 }
1246}
BoolSetting EditClipsCanMove
Definition: WaveTrack.cpp:2625
bool Read(T *pVar) const
overload of Read returning a boolean that is true if the value was previously defined *‍/
Definition: Prefs.h:200

References Clear(), EditClipsCanMove, GetEndTime(), GetRate(), GetSampleFormat(), IsEmpty(), mClips, mpFactory, mRate, Paste(), and Setting< T >::Read().

Referenced by EffectPaulstretch::Process().

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

◆ Trim()

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

Definition at line 578 of file WaveTrack.cpp.

579{
580 bool inside0 = false;
581 bool inside1 = false;
582
583 for (const auto &clip : mClips)
584 {
585 if(t1 > clip->GetPlayStartTime() && t1 < clip->GetPlayEndTime())
586 {
587 clip->SetTrimRight(clip->GetTrimRight() + clip->GetPlayEndTime() - t1);
588 inside1 = true;
589 }
590
591 if(t0 > clip->GetPlayStartTime() && t0 < clip->GetPlayEndTime())
592 {
593 clip->SetTrimLeft(clip->GetTrimLeft() + t0 - clip->GetPlayStartTime());
594 inside0 = true;
595 }
596 }
597
598 //if inside0 is false, then the left selector was between
599 //clips, so DELETE everything to its left.
600 if(!inside1 && t1 < GetEndTime())
601 Clear(t1,GetEndTime());
602
603 if(!inside0 && t0 > GetStartTime())
605}

References Clear(), GetEndTime(), GetStartTime(), mClips, 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 SampleTrack.

Definition at line 2068 of file WaveTrack.cpp.

2069{
2070 auto &clips = GetClips();
2071 return std::accumulate(clips.begin(), clips.end(), narrowestSampleFormat,
2072 [](sampleFormat format, const auto &pClip){
2073 return std::max(format,
2074 pClip->GetSequence()->GetSampleFormats().Effective());
2075 });
2076}
@ narrowestSampleFormat
Two synonyms for previous values that might change if more values were added.

References format, GetClips(), and narrowestSampleFormat.

Here is the call graph for this function:

◆ WriteXML()

void WaveTrack::WriteXML ( XMLWriter xmlFile) const
overridevirtual

Implements Track.

Definition at line 1783 of file WaveTrack.cpp.

1785{
1786 xmlFile.StartTag(wxT("wavetrack"));
1787 this->Track::WriteCommonXMLAttributes( xmlFile );
1788 xmlFile.WriteAttr(wxT("linked"), static_cast<int>(GetLinkType()));
1790 xmlFile.WriteAttr(wxT("rate"), mRate);
1791
1792 // Some values don't vary independently in channels but have been written
1793 // redundantly for each channel. Keep doing this in 3.4 and later in case
1794 // a project is opened in an earlier version.
1795 xmlFile.WriteAttr(wxT("gain"), static_cast<double>(GetGain()));
1796 xmlFile.WriteAttr(wxT("pan"), static_cast<double>(GetPan()));
1797 xmlFile.WriteAttr(wxT("colorindex"), mWaveColorIndex );
1798
1799 xmlFile.WriteAttr(wxT("sampleformat"), static_cast<long>(mFormat) );
1800
1801 WaveTrackIORegistry::Get().CallWriters(*this, xmlFile);
1802
1803 for (const auto &clip : mClips)
1804 {
1805 clip->WriteXML(xmlFile);
1806 }
1807
1808 xmlFile.EndTag(wxT("wavetrack"));
1809}
void WriteXMLAttributes(XMLWriter &xmlFile) const
void WriteCommonXMLAttributes(XMLWriter &xmlFile, bool includeNameAndSelected=true) const
Definition: Track.cpp:1149
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

References XMLMethodRegistry< Host >::CallWriters(), XMLMethodRegistry< Host >::Get(), Track::WriteCommonXMLAttributes(), PlayableTrack::WriteXMLAttributes(), and wxT().

Here is the call graph for this function:

Friends And Related Function Documentation

◆ WaveTrackFactory

friend class WaveTrackFactory
friend

Definition at line 93 of file WaveTrack.h.

Member Data Documentation

◆ mAppendCriticalSection

wxCriticalSection WaveTrack::mAppendCriticalSection
private

Definition at line 529 of file WaveTrack.h.

◆ mClips

WaveClipHolders WaveTrack::mClips
protected

◆ mFlushCriticalSection

wxCriticalSection WaveTrack::mFlushCriticalSection
private

Definition at line 528 of file WaveTrack.h.

◆ mFormat

sampleFormat WaveTrack::mFormat
protected

◆ mLegacyProjectFileOffset

double WaveTrack::mLegacyProjectFileOffset
private

Definition at line 530 of file WaveTrack.h.

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

◆ mpFactory

SampleBlockFactoryPtr WaveTrack::mpFactory
private

◆ mRate

int WaveTrack::mRate
protected

◆ mWaveColorIndex

int WaveTrack::mWaveColorIndex
protected

Definition at line 518 of file WaveTrack.h.

Referenced by HandleXMLTag(), Init(), SetWaveColorIndex(), and WaveTrack().


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