Audacity 3.2.0
Classes | Typedefs | Functions
WaveTrackUtilities Namespace Reference

Classes

class  AllClipsConstIterator
 
class  AllClipsIterator
 

Typedefs

using SampleBlockID = long long
 
using SampleBlockIDSet = std::unordered_set< SampleBlockID >
 
using BlockVisitor = std::function< void(const std::shared_ptr< SampleBlock > &)>
 
using BlockInspector = std::function< void(std::shared_ptr< const SampleBlock >)>
 
using IntervalHolder = std::shared_ptr< WaveTrack::Interval >
 
using IntervalHolders = std::vector< IntervalHolder >
 
using IntervalConstHolder = std::shared_ptr< const WaveTrack::Interval >
 
using ProgressReport = std::function< bool(double)>
 

Functions

IteratorRange< AllClipsIteratorGetAllClips (WaveTrack &track)
 
IteratorRange< AllClipsConstIteratorGetAllClips (const WaveTrack &track)
 
WAVE_TRACK_API bool Reverse (WaveTrack &track, sampleCount start, sampleCount len, const ProgressReport &report={})
 
WAVE_TRACK_API sampleCount GetSequenceSamplesCount (const WaveTrack &track)
 
WAVE_TRACK_API size_t CountBlocks (const WaveTrack &track)
 
WAVE_TRACK_API void CloseLock (WaveTrack &track) noexcept
 Should be called upon project close. Not balanced by unlocking calls. More...
 
WAVE_TRACK_API bool RemoveCutLine (WaveTrack &track, double cutLinePosition)
 Remove cut line, without expanding the audio in it. More...
 
WAVE_TRACK_API void ExpandCutLine (WaveTrack &track, double cutLinePosition, double *cutlineStart=nullptr, double *cutlineEnd=nullptr)
 
WAVE_TRACK_API bool HasHiddenData (const WaveTrack &track)
 Whether any clips have hidden audio. More...
 
WAVE_TRACK_API void DiscardTrimmed (WaveTrack &track)
 Remove hidden audio from all clips. More...
 
WAVE_TRACK_API void VisitBlocks (TrackList &tracks, BlockVisitor visitor, SampleBlockIDSet *pIDs=nullptr)
 
WAVE_TRACK_API void InspectBlocks (const TrackList &tracks, BlockInspector inspector, SampleBlockIDSet *pIDs=nullptr)
 
WAVE_TRACK_API WaveTrack::IntervalConstHolders GetClipsIntersecting (const WaveTrack &track, double t0, double t1)
 
WAVE_TRACK_API void ExpandClipTillNextOne (const WaveTrack &track, WaveTrack::Interval &interval)
 

Typedef Documentation

◆ BlockInspector

using WaveTrackUtilities::BlockInspector = typedef std::function<void(std::shared_ptr<const SampleBlock>)>

Definition at line 37 of file WaveTrackUtilities.h.

◆ BlockVisitor

using WaveTrackUtilities::BlockVisitor = typedef std::function<void(const std::shared_ptr<SampleBlock> &)>

Definition at line 35 of file WaveTrackUtilities.h.

◆ IntervalConstHolder

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

Definition at line 42 of file WaveTrackUtilities.h.

◆ IntervalHolder

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

Definition at line 40 of file WaveTrackUtilities.h.

◆ IntervalHolders

Definition at line 41 of file WaveTrackUtilities.h.

◆ ProgressReport

using WaveTrackUtilities::ProgressReport = typedef std::function<bool(double)>

Argument is in (0, 1)

Returns
true if processing should continue

Definition at line 128 of file WaveTrackUtilities.h.

◆ SampleBlockID

using WaveTrackUtilities::SampleBlockID = typedef long long

Definition at line 33 of file WaveTrackUtilities.h.

◆ SampleBlockIDSet

using WaveTrackUtilities::SampleBlockIDSet = typedef std::unordered_set<SampleBlockID>

Definition at line 34 of file WaveTrackUtilities.h.

Function Documentation

◆ CloseLock()

void WaveTrackUtilities::CloseLock ( WaveTrack track)
noexcept

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

Exception safety guarantee:
No-fail

Definition at line 286 of file WaveTrackUtilities.cpp.

287{
288 for (const auto &pClip : track.Intervals())
289 pClip->CloseLock();
290}
auto Intervals()
Definition: WaveTrack.h:670

Referenced by ProjectFileManager::CompactProjectOnClose(), ProjectFileManager::DiscardAutosave(), and ProjectFileManager::OpenProjectFile().

Here is the caller graph for this function:

◆ CountBlocks()

size_t WaveTrackUtilities::CountBlocks ( const WaveTrack track)
Returns
the total number of blocks in all underlying sequences of all clips, across all channels (including hidden audio but not counting the cutlines)

Definition at line 278 of file WaveTrackUtilities.cpp.

279{
280 size_t result{};
281 for (const auto &pInterval : track.Intervals())
282 result += pInterval->CountBlocks();
283 return result;
284}

References WaveTrack::Intervals().

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

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

◆ DiscardTrimmed()

void WaveTrackUtilities::DiscardTrimmed ( WaveTrack track)

Remove hidden audio from all clips.

Definition at line 360 of file WaveTrackUtilities.cpp.

361{
362 for (const auto &pClip : track.Intervals()) {
363 if (pClip->GetTrimLeft() != 0) {
364 auto t0 = pClip->GetPlayStartTime();
365 pClip->SetTrimLeft(0);
366 pClip->ClearLeft(t0);
367 }
368 if (pClip->GetTrimRight() != 0) {
369 auto t1 = pClip->GetPlayEndTime();
370 pClip->SetTrimRight(0);
371 pClip->ClearRight(t1);
372 }
373 }
374}

References WaveTrack::Intervals().

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

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

◆ ExpandClipTillNextOne()

void WaveTrackUtilities::ExpandClipTillNextOne ( const WaveTrack track,
WaveTrack::Interval interval 
)

Definition at line 447 of file WaveTrackUtilities.cpp.

449{
450 if (
451 const auto nextClip =
453 {
454 interval.StretchRightTo(nextClip->GetPlayStartTime());
455 }
456}
void StretchRightTo(double to)
Sets from the right to the absolute time (if in expected range)
Definition: WaveClip.cpp:588
IntervalConstHolder GetNextInterval(const Interval &interval, PlaybackDirection searchDirection) const
Definition: WaveTrack.cpp:175

References forward, WaveTrack::GetNextInterval(), and WaveClip::StretchRightTo().

Referenced by PitchAndSpeedDialog::PopulateOrExchange().

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

◆ ExpandCutLine()

void WaveTrackUtilities::ExpandCutLine ( WaveTrack track,
double  cutLinePosition,
double *  cutlineStart = nullptr,
double *  cutlineEnd = nullptr 
)

Expand cut line (that is, re-insert audio, then delete audio saved in cut line)

Definition at line 305 of file WaveTrackUtilities.cpp.

308{
309 const bool editClipCanMove = GetEditClipsCanMove();
310
311 // Find clip which contains this cut line
312 double start = 0, end = 0;
313 const auto &clips = track.Intervals();
314 const auto pEnd = clips.end();
315 const auto pClip = std::find_if(clips.begin(), pEnd,
316 [&](const auto &clip) {
317 return clip->FindCutLine(cutLinePosition, &start, &end); });
318 if (pClip != pEnd) {
319 auto &&clip = *pClip;
320 if (!editClipCanMove) {
321 // We are not allowed to move the other clips, so see if there
322 // is enough room to expand the cut line
323 for (const auto &clip2: clips)
324 if (clip2->GetPlayStartTime() > clip->GetPlayStartTime() &&
325 clip->GetPlayEndTime() + end - start > clip2->GetPlayStartTime())
326 // Strong-guarantee in case of this path
329 XO("There is not enough room available to expand the cut line"),
330 XO("Warning"),
331 "Error:_Insufficient_space_in_track"
332 };
333 }
334
335 clip->ExpandCutLine(cutLinePosition);
336
337 // Strong-guarantee provided that the following gives No-fail-guarantee
338
339 if (cutlineStart)
340 *cutlineStart = start;
341 if (cutlineEnd)
342 *cutlineEnd = end;
343
344 // Move clips which are to the right of the cut line
345 if (editClipCanMove)
346 for (const auto &clip2 : clips)
347 if (clip2->GetPlayStartTime() > clip->GetPlayStartTime())
348 clip2->ShiftBy(end - start);
349 }
350}
@ BadUserAction
Indicates that the user performed an action that is not allowed.
XO("Cut/Copy/Paste")
bool GetEditClipsCanMove()
Definition: WaveTrack.cpp:3381
A MessageBoxException that shows a given, unvarying string.
const char * end(const char *str) noexcept
Definition: StringUtils.h:106

References BadUserAction, details::end(), GetEditClipsCanMove(), WaveTrack::Intervals(), and XO().

Referenced by CutlineHandle::Click().

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

◆ GetAllClips() [1/2]

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

Definition at line 121 of file WaveTrackUtilities.h.

122{
123 return { AllClipsConstIterator{ track }, AllClipsConstIterator{} };
124}

◆ GetAllClips() [2/2]

IteratorRange< AllClipsIterator > WaveTrackUtilities::GetAllClips ( WaveTrack track)
inline

Definition at line 116 of file WaveTrackUtilities.h.

117{
118 return { AllClipsIterator{ track }, AllClipsIterator{} };
119}

Referenced by VisitBlocks().

Here is the caller graph for this function:

◆ GetClipsIntersecting()

WaveTrack::IntervalConstHolders WaveTrackUtilities::GetClipsIntersecting ( const WaveTrack track,
double  t0,
double  t1 
)
Precondition
t0 <= t1

Definition at line 404 of file WaveTrackUtilities.cpp.

406{
407 assert(t0 <= t1);
409 const auto &intervals = track.Intervals();
410 copy_if(intervals.begin(), intervals.end(), back_inserter(result),
411 [&](const auto &pClip){
412 return pClip->IntersectsPlayRegion(t0, t1); });
413 return result;
414}
std::vector< IntervalConstHolder > IntervalConstHolders
Definition: WaveTrack.h:212

References WaveTrack::Intervals().

Referenced by WaveChannelSubView::GetMenuItems(), anonymous_namespace{EditMenus.cpp}::JoinClipsAvailableFlag(), and SelectActions::Handler::OnZeroCrossing().

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

◆ GetSequenceSamplesCount()

sampleCount WaveTrackUtilities::GetSequenceSamplesCount ( const WaveTrack track)
Returns
the total number of samples in all underlying sequences of all clips, across all channels (including hidden audio but not counting the cutlines)

Definition at line 270 of file WaveTrackUtilities.cpp.

271{
272 sampleCount result{ 0 };
273 for (const auto &pInterval : track.Intervals())
274 result += pInterval->GetSequenceSamplesCount();
275 return result;
276}
Positions or offsets within audio files need a wide type.
Definition: SampleCount.h:19

References WaveTrack::Intervals().

Referenced by anonymous_namespace{EditMenus.cpp}::EstimateCopyBytesCount(), FormatMenuTable::OnFormatChange(), and WaveClip::WriteXML().

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

◆ HasHiddenData()

bool WaveTrackUtilities::HasHiddenData ( const WaveTrack track)

Whether any clips have hidden audio.

Definition at line 352 of file WaveTrackUtilities.cpp.

353{
354 const auto &clips = track.Intervals();
355 return std::any_of(clips.begin(), clips.end(), [](const auto &pClip){
356 return pClip->GetTrimLeft() != 0 || pClip->GetTrimRight() != 0;
357 });
358}

References WaveTrack::Intervals().

Here is the call graph for this function:

◆ InspectBlocks()

void WaveTrackUtilities::InspectBlocks ( const TrackList tracks,
BlockInspector  inspector,
SampleBlockIDSet pIDs = nullptr 
)

Definition at line 397 of file WaveTrackUtilities.cpp.

399{
400 VisitBlocks(const_cast<TrackList &>(tracks), move(inspector), pIDs);
401}
const auto tracks
A flat linked list of tracks supporting Add, Remove, Clear, and Contains, serialization of the list o...
Definition: Track.h:850
WAVE_TRACK_API void VisitBlocks(TrackList &tracks, BlockVisitor visitor, SampleBlockIDSet *pIDs=nullptr)

References tracks, and VisitBlocks().

Referenced by anonymous_namespace{HistoryWindow.cpp}::SpaceUsageCalculator::CalculateUsage(), ProjectFileIO::CopyTo(), EstimateRemovedBlocks(), ProjectFileIO::GetCurrentUsage(), ProjectFileIO::SaveProject(), and ProjectFileIO::ShouldCompact().

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

◆ RemoveCutLine()

bool WaveTrackUtilities::RemoveCutLine ( WaveTrack track,
double  cutLinePosition 
)

Remove cut line, without expanding the audio in it.

Definition at line 292 of file WaveTrackUtilities.cpp.

293{
294 bool removed = false;
295 for (const auto &pClip : track.Intervals())
296 if (pClip->RemoveCutLine(cutLinePosition)) {
297 removed = true;
298 break;
299 }
300 return removed;
301}

References WaveTrack::Intervals().

Referenced by CutlineHandle::Click().

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

◆ Reverse()

bool WaveTrackUtilities::Reverse ( WaveTrack track,
sampleCount  start,
sampleCount  len,
const ProgressReport report = {} 
)

Definition at line 126 of file WaveTrackUtilities.cpp.

128{
129 bool rValue = true; // return value
130
131 // start, end, len refer to the selected reverse region
132 auto end = start + len;
133
134 auto clipArray = track.SortedIntervalArray();
135 const auto invariant = [&]{
136 return std::is_sorted(clipArray.begin(), clipArray.end(),
137 [](const auto &pA, const auto &pB){
138 return pA->GetPlayStartTime() < pB->GetPlayEndTime();
139 });
140 };
141 assert(invariant());
142
143 // STEP 1:
144 // If a reverse selection begins and/or ends at the inside of a clip
145 // perform a split at the start and/or end of the reverse selection
146 // Beware, the array grows as we loop over it, so don't use range-for
147 for (size_t ii = 0; ii < clipArray.size(); ++ii) {
148 const auto &clip = *clipArray[ii];
149 auto clipStart = clip.GetPlayStartSample();
150 auto clipEnd = clip.GetPlayEndSample();
151 const auto splitAt = [&](double splitTime){
152 auto [_, second] = track.SplitAt(splitTime);
153 if (second)
154 clipArray.insert(clipArray.begin() + ii + 1, second);
155 };
156 if (clipStart < start && clipEnd > start && clipEnd <= end) {
157 // the reverse selection begins at the inside of a clip
158 double splitTime = track.LongSamplesToTime(start);
159 splitAt(splitTime);
160 }
161 else if (clipStart >= start && clipStart < end && clipEnd > end) {
162 // the reverse selection ends at the inside of a clip
163 double splitTime = track.LongSamplesToTime(end);
164 splitAt(splitTime);
165 }
166 else if (clipStart < start && clipEnd > end) {
167 // the selection begins AND ends at the inside of a clip
168 double splitTime = track.LongSamplesToTime(end);
169 splitAt(splitTime);
170 splitTime = track.LongSamplesToTime(start);
171 splitAt(splitTime);
172 }
173 assert(invariant());
174 }
175
176 //STEP 2:
177 // Individually reverse each clip inside the selected region
178 // and apply the appropriate offset after detaching them from the track
179
180 bool checkedFirstClip = false;
181
182 // used in calculating the offset of clips to rearrange
183 // holds the new end position of the current clip
184 auto currentEnd = end;
185
186 // holds the reversed clips
188 IntervalHolders revClips;
189 // holds the clips that appear after the reverse selection region
190 IntervalHolders otherClips;
191 // Unlike in the previous iteration, clipArray is not inserted or
192 // erased
193 size_t i = 0;
194 for (const auto &clip : clipArray) {
195 Finally Do([&]{ ++i; });
196 auto clipStart = clip->GetPlayStartSample();
197 auto clipEnd = clip->GetPlayEndSample();
198
199 if (clipStart >= start && clipEnd <= end) {
200 // if the clip is inside the selected region
201 // this is used to check if the selected region begins with a
202 // whitespace. If yes then clipStart (of the first clip) and start are
203 // not the same. Adjust currentEnd accordingly and set endMerge to
204 // false
205 if (!checkedFirstClip && clipStart > start) {
206 checkedFirstClip = true;
207 if (i > 0) {
208 if (clipArray[i - 1]->GetPlayEndSample() <= start)
209 currentEnd -= (clipStart - start);
210 }
211 else
212 currentEnd -= (clipStart - start);
213 }
214
215 auto revStart = std::max(clipStart, start);
216 auto revEnd = std::min(end, clipEnd);
217 auto revLen = revEnd - revStart;
218 if (revEnd >= revStart) {
219 // reverse the clip
220 if (!ReverseOneClip(track, revStart, revLen, start, end, progress))
221 {
222 rValue = false;
223 break;
224 }
225
226 // calculate the offset required
227 auto clipOffsetStart = currentEnd - (clipEnd - clipStart);
228 double offsetStartTime = track.LongSamplesToTime(clipOffsetStart);
229 if (i + 1 < clipArray.size()) {
230 // update currentEnd if there is a clip to process next
231 auto nextClipStart = clipArray[i + 1]->GetPlayStartSample();
232 currentEnd = currentEnd -
233 (clipEnd - clipStart) - (nextClipStart - clipEnd);
234 }
235
236 // detach the clip from track
237 revClips.push_back(clip);
238 track.RemoveInterval(clip);
239 // align time to a sample and set offset
240 revClips.back()->SetPlayStartTime(
241 track.SnapToSample(offsetStartTime));
242 }
243 }
244 else if (clipStart >= end) {
245 // clip is after the selection region
246 // simply remove and append to otherClips
247 otherClips.push_back(clip);
248 track.RemoveInterval(clip);
249 }
250 }
251
252 // STEP 3: Append the clips from
253 // revClips and otherClips back to the track
254 // the last clip of revClips is appended to the track first
255 // PRL: I don't think that matters, the sequence of storage of clips in the
256 // track is not elsewhere assumed to be by time
257 for (auto it = revClips.rbegin(), revEnd = revClips.rend();
258 it != revEnd; ++it)
259 track.InsertInterval(*it, false);
260
261 if (!rValue)
262 return false;
263
264 for (auto &clip : otherClips)
265 track.InsertInterval(clip, false);
266
267 return rValue;
268}
int min(int a, int b)
#define _(s)
Definition: Internat.h:73
void InsertInterval(const IntervalHolder &interval, bool newClip, bool allowEmpty=false)
Definition: WaveTrack.cpp:3208
std::pair< IntervalHolder, IntervalHolder > SplitAt(double t)
Definition: WaveTrack.cpp:3138
IntervalHolders SortedIntervalArray()
Return all WaveClips sorted by clip play start time.
Definition: WaveTrack.cpp:3270
std::vector< IntervalHolder > IntervalHolders
Definition: WaveTrack.h:210
void RemoveInterval(const IntervalHolder &interval)
Definition: WaveTrack.cpp:3219
double LongSamplesToTime(sampleCount pos) const
double SnapToSample(double t) const
std::vector< IntervalHolder > IntervalHolders
bool ReverseOneClip(WaveTrack &track, sampleCount start, sampleCount len, sampleCount originalStart, sampleCount originalEnd, const WaveTrackUtilities::ProgressReport &report)
"finally" as in The C++ Programming Language, 4th ed., p. 358 Useful for defining ad-hoc RAII actions...
Definition: MemoryX.h:175

References _, details::end(), WaveTrack::InsertInterval(), WideSampleSequence::LongSamplesToTime(), min(), WaveTrack::RemoveInterval(), anonymous_namespace{WaveTrackUtilities.cpp}::ReverseOneClip(), WideSampleSequence::SnapToSample(), WaveTrack::SortedIntervalArray(), and WaveTrack::SplitAt().

Referenced by EffectReverse::Process().

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

◆ VisitBlocks()

void WaveTrackUtilities::VisitBlocks ( TrackList tracks,
BlockVisitor  visitor,
SampleBlockIDSet pIDs = nullptr 
)

Definition at line 376 of file WaveTrackUtilities.cpp.

378{
379 for (auto wt : tracks.Any<WaveTrack>())
380 // Scan all clips within current track
381 for (const auto &pClip : GetAllClips(*wt))
382 // Scan all sample blocks within current clip
383 for (const auto &pChannel : pClip->Channels()) {
384 auto blocks = pChannel->GetSequenceBlockArray();
385 for (const auto &block : *blocks) {
386 auto &pBlock = block.sb;
387 if (pBlock) {
388 if (pIDs && !pIDs->insert(pBlock->GetBlockID()).second)
389 continue;
390 if (visitor)
391 visitor(pBlock);
392 }
393 }
394 }
395}
A Track that contains audio waveform data.
Definition: WaveTrack.h:203
IteratorRange< AllClipsIterator > GetAllClips(WaveTrack &track)

References GetAllClips(), and tracks.

Referenced by InspectBlocks(), and audacity::cloud::audiocom::sync::LocalProjectSnapshot::ProjectBlocksLock::VisitBlocks().

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