Audacity 3.2.0
WaveTrackSink.cpp
Go to the documentation of this file.
1/**********************************************************************
2
3 Audacity: A Digital Audio Editor
4
5 @file WaveTrackSink.cpp
6
7 Dominic Mazzoni
8 Vaughan Johnson
9 Martyn Shaw
10
11 Paul Licameli split from PerTrackEffect.cpp
12
13**********************************************************************/
14#include "WaveTrackSink.h"
15
16#include "AudioGraphBuffers.h"
17#include "TimeWarper.h"
18#include "WaveTrack.h"
19#include <cassert>
20
22 sampleCount start, bool isGenerator, bool isProcessor,
23 sampleFormat effectiveFormat
24) : mLeft{ left }, mpRight{ pRight }
25 , mGenLeft{ isGenerator ? left.EmptyCopy() : nullptr }
26 , mGenRight{ pRight && isGenerator ? pRight->EmptyCopy() : nullptr }
27 , mIsProcessor{ isProcessor }
28 , mEffectiveFormat{ effectiveFormat }
29 , mOutPos{ start }
30{
31}
32
34
35bool WaveTrackSink::AcceptsBuffers(const Buffers &buffers) const
36{
37 return buffers.Channels() > 0;
38}
39
41{
42 if (data.BlockSize() <= data.Remaining()) {
43 // post is satisfied
44 }
45 else
46 // Output buffers have (mostly) filled
47 // (less than one block remains; maybe nonzero because of samples
48 // discarded for initial latency correction)
49 DoConsume(data);
50 return true;
51}
52
53bool WaveTrackSink::Release(const Buffers &, size_t)
54{
55 // May become non-trivial later
56 return true;
57}
58
60{
61 // Satisfy pre of GetReadPosition()
62 assert(data.Channels() > 0);
63 const auto inputBufferCnt = data.Position();
64 if (inputBufferCnt > 0) {
65 // Some data still unwritten
66 if (mIsProcessor) {
68 floatSample, mOutPos, inputBufferCnt, mEffectiveFormat);
69 if (mpRight)
71 floatSample, mOutPos, inputBufferCnt, mEffectiveFormat);
72 }
73 else if (mGenLeft) {
74 mGenLeft->Append(data.GetReadPosition(0),
75 floatSample, inputBufferCnt);
76 if (mGenRight)
77 mGenRight->Append(data.GetReadPosition(1),
78 floatSample, inputBufferCnt);
79 }
80 // Satisfy post
81 data.Rewind();
82 // Bump to the next track position
83 mOutPos += inputBufferCnt;
84 }
85 else {
86 // Position is zero, therefore Remaining() is a positive multiple of
87 // block size
88 }
89 // assert the post
90 assert(data.BlockSize() <= data.Remaining());
91}
92
93void WaveTrackSink::Flush(Buffers &data, const double t0, const double t1)
94{
95 DoConsume(data);
96 if (mGenLeft) {
97 // Transfer the data from the temporary tracks to the actual ones
98 mGenLeft->Flush();
99 // mT1 gives us the NEW selection. We want to replace up to GetSel1().
100 PasteTimeWarper warper{ t1, t0 + mGenLeft->GetEndTime() };
101 mLeft.ClearAndPaste(t0, t1, mGenLeft.get(), true, true, &warper);
102 if (mGenRight) {
103 mGenRight->Flush();
104 mpRight->ClearAndPaste(t0, t1, mGenRight.get(), true, true, &warper);
105 }
106 }
107}
sampleFormat
The ordering of these values with operator < agrees with the order of increasing bit width.
Definition: SampleFormat.h:30
Contains declarations for TimeWarper, IdentityTimeWarper, ShiftTimeWarper, LinearTimeWarper,...
Accumulates (non-interleaved) data during effect processing.
size_t BlockSize() const
size_t Position() const
size_t Remaining() const
void Rewind()
Reset positions to starts of buffers.
unsigned Channels() const
constSamplePtr GetReadPosition(unsigned iChannel) const
Get accumulated data for one channel.
Unit slope but with either a jump (pasting more) or a flat interval (pasting less)
Definition: TimeWarper.h:181
A Track that contains audio waveform data.
Definition: WaveTrack.h:57
void Set(constSamplePtr buffer, sampleFormat format, sampleCount start, size_t len, sampleFormat effectiveFormat=widestSampleFormat)
Definition: WaveTrack.cpp:2191
void ClearAndPaste(double t0, double t1, const Track *src, bool preserve=true, bool merge=true, const TimeWarper *effectWarper=NULL)
Definition: WaveTrack.cpp:899
const sampleFormat mEffectiveFormat
Definition: WaveTrackSink.h:55
~WaveTrackSink() override
WaveTrackSink(WaveTrack &left, WaveTrack *pRight, sampleCount start, bool isGenerator, bool isProcessor, sampleFormat effectiveFormat)
void DoConsume(Buffers &data)
bool Acquire(Buffers &data) override
Guarantee empty space in Buffers before they are written.
bool Release(const Buffers &data, size_t curBlockSize) override
Acknowledge receipt of data in Buffers, which caller may then Advance()
void Flush(Buffers &data, double t0, double t1)
WaveTrack & mLeft
Definition: WaveTrackSink.h:51
const bool mIsProcessor
Definition: WaveTrackSink.h:54
sampleCount mOutPos
Definition: WaveTrackSink.h:57
const std::shared_ptr< WaveTrack > mGenLeft
Definition: WaveTrackSink.h:53
bool AcceptsBuffers(const Buffers &buffers) const override
Accepts buffers only if there is at least one channel.
WaveTrack *const mpRight
Definition: WaveTrackSink.h:52
const std::shared_ptr< WaveTrack > mGenRight
Definition: WaveTrackSink.h:53
Positions or offsets within audio files need a wide type.
Definition: SampleCount.h:19