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

#include <MixerSource.h>

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

Public Types

using TimesAndSpeed = MixerOptions::TimesAndSpeed
 
using ResampleParameters = MixerOptions::ResampleParameters
 
- Public Types inherited from AudioGraph::Source
using Buffers = AudioGraph::Buffers
 

Public Member Functions

 MixerSource (const std::shared_ptr< const WideSampleSequence > &seq, size_t bufferSize, double rate, const MixerOptions::Warp &options, bool highQuality, bool mayThrow, std::shared_ptr< TimesAndSpeed > pTimesAndSpeed, const ArrayOf< bool > *pMap)
 
 MixerSource (MixerSource &&)=default
 
MixerSourceoperator= (MixerSource &&)=delete
 
 ~MixerSource ()
 
unsigned Channels () const
 
const WideSampleSequenceGetSequence () const
 
const bool * MixerSpec (unsigned iChannel) const
 
bool AcceptsBuffers (const Buffers &buffers) const override
 
bool AcceptsBlockSize (size_t blockSize) const override
 
std::optional< size_t > Acquire (Buffers &data, size_t bound) override
 Occupy vacant space in Buffers with some data. More...
 
sampleCount Remaining () const override
 Result includes any amount Acquired and not yet Released. More...
 
bool Release () override
 Caller is done examining last Acquire()d positions. More...
 
bool Terminates () const override
 
void Reposition (double time, bool skipping)
 
bool VariableRates () const
 
- Public Member Functions inherited from AudioGraph::Source
virtual ~Source ()
 
virtual bool AcceptsBuffers (const Buffers &buffers) const =0
 
virtual bool AcceptsBlockSize (size_t blockSize) const =0
 
virtual std::optional< size_t > Acquire (Buffers &data, size_t bound)=0
 Occupy vacant space in Buffers with some data. More...
 
virtual sampleCount Remaining () const =0
 Result includes any amount Acquired and not yet Released. More...
 
virtual bool Release ()=0
 Caller is done examining last Acquire()d positions. More...
 
virtual bool Terminates () const
 Needed only to make some postconditions assertable; defaults true. More...
 

Private Member Functions

void MakeResamplers ()
 
size_t MixSameRate (unsigned nChannels, size_t maxOut, float *floatBuffers[])
 
size_t MixVariableRates (unsigned nChannels, size_t maxOut, float *floatBuffers[])
 
void ZeroFill (size_t produced, size_t max, float &floatBuffer)
 

Private Attributes

const std::shared_ptr< const WideSampleSequencempSeq
 
size_t i
 
const size_t mnChannels
 
const double mRate
 
const BoundedEnvelope *const mEnvelope
 Resampling, as needed, after gain envelope. More...
 
const bool mMayThrow
 
const std::shared_ptr< TimesAndSpeedmTimesAndSpeed
 
sampleCount mSamplePos
 Fetch position for source. More...
 
std::vector< std::vector< float > > mSampleQueue
 First intermediate buffer when resampling is needed. More...
 
int mQueueStart
 Position of the start of the next block to resample. More...
 
int mQueueLen
 The number of available samples after the queue start. More...
 
const ResampleParameters mResampleParameters
 
std::vector< std::unique_ptr< Resample > > mResample
 
std::vector< double > mEnvValues
 Gain envelopes are applied to input before other transformations. More...
 
const ArrayOf< bool > *const mpMap
 
unsigned mMaxChannels {}
 Remember how many channels were passed to Acquire() More...
 
size_t mLastProduced {}
 

Static Private Attributes

static constexpr size_t sProcessLen = 1024
 
static constexpr size_t sQueueMaxLen = 65536
 

Detailed Description

Fetches from tracks, applies envelopes; can resample, and warp time, even backwards, as for scrubbing.

This class inherits AudioGraph::Source but does not yet fulfill the contracts of all of the members. But it is not yet used through any pointer or reference to its base class.

Definition at line 33 of file MixerSource.h.

Member Typedef Documentation

◆ ResampleParameters

Definition at line 36 of file MixerSource.h.

◆ TimesAndSpeed

Definition at line 35 of file MixerSource.h.

Constructor & Destructor Documentation

◆ MixerSource() [1/2]

MixerSource::MixerSource ( const std::shared_ptr< const WideSampleSequence > &  seq,
size_t  bufferSize,
double  rate,
const MixerOptions::Warp options,
bool  highQuality,
bool  mayThrow,
std::shared_ptr< TimesAndSpeed pTimesAndSpeed,
const ArrayOf< bool > *  pMap 
)
Precondition
pTimesAndSpeed != nullptr
Parameters
pMapNull or else must have a lifetime enclosing this objects's

Definition at line 289 of file MixerSource.cpp.

294 : mpSeq{ seq }
295 , mnChannels{ mpSeq->NChannels() }
296 , mRate{ rate }
297 , mEnvelope{ options.envelope }
298 , mMayThrow{ mayThrow }
299 , mTimesAndSpeed{ move(pTimesAndSpeed) }
300 , mSampleQueue{ initVector<float>(mnChannels, sQueueMaxLen) }
301 , mQueueStart{ 0 }
302 , mQueueLen{ 0 }
303 , mResampleParameters{ highQuality, mpSeq->GetRate(), rate, options }
305 , mEnvValues( std::max(sQueueMaxLen, bufferSize) )
306 , mpMap{ pMap }
307{
308 assert(mTimesAndSpeed);
309 auto t0 = mTimesAndSpeed->mT0;
312}
std::vector< double > mEnvValues
Gain envelopes are applied to input before other transformations.
Definition: MixerSource.h:131
int mQueueStart
Position of the start of the next block to resample.
Definition: MixerSource.h:122
int mQueueLen
The number of available samples after the queue start.
Definition: MixerSource.h:125
const ResampleParameters mResampleParameters
Definition: MixerSource.h:127
const BoundedEnvelope *const mEnvelope
Resampling, as needed, after gain envelope.
Definition: MixerSource.h:107
const std::shared_ptr< TimesAndSpeed > mTimesAndSpeed
Definition: MixerSource.h:110
std::vector< std::vector< float > > mSampleQueue
First intermediate buffer when resampling is needed.
Definition: MixerSource.h:119
const std::shared_ptr< const WideSampleSequence > mpSeq
Definition: MixerSource.h:100
static constexpr size_t sQueueMaxLen
Definition: MixerSource.h:80
const ArrayOf< bool > *const mpMap
Definition: MixerSource.h:135
const bool mMayThrow
Definition: MixerSource.h:108
std::vector< std::unique_ptr< Resample > > mResample
Definition: MixerSource.h:128
const double mRate
Definition: MixerSource.h:104
const size_t mnChannels
Definition: MixerSource.h:103
void MakeResamplers()
Definition: MixerSource.cpp:40
sampleCount mSamplePos
Fetch position for source.
Definition: MixerSource.h:116
const WideSampleSequence & GetSequence() const
sampleCount TimeToLongSamples(double t0) const
const BoundedEnvelope *const envelope
Definition: MixerOptions.h:76

References GetSequence(), MakeResamplers(), mSamplePos, mTimesAndSpeed, and WideSampleSequence::TimeToLongSamples().

Here is the call graph for this function:

◆ MixerSource() [2/2]

MixerSource::MixerSource ( MixerSource &&  )
default

◆ ~MixerSource()

MixerSource::~MixerSource ( )
default

Member Function Documentation

◆ AcceptsBlockSize()

bool MixerSource::AcceptsBlockSize ( size_t  blockSize) const
overridevirtual

Implements AudioGraph::Source.

Definition at line 331 of file MixerSource.cpp.

332{
333 return blockSize <= mEnvValues.size();
334}

References mEnvValues.

Referenced by AcceptsBuffers(), and Acquire().

Here is the caller graph for this function:

◆ AcceptsBuffers()

bool MixerSource::AcceptsBuffers ( const Buffers buffers) const
overridevirtual

Implements AudioGraph::Source.

Definition at line 326 of file MixerSource.cpp.

327{
328 return AcceptsBlockSize(buffers.BufferSize());
329}
bool AcceptsBlockSize(size_t blockSize) const override

References AcceptsBlockSize(), and AudioGraph::Buffers::BufferSize().

Referenced by Acquire().

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

◆ Acquire()

std::optional< size_t > MixerSource::Acquire ( Buffers data,
size_t  bound 
)
overridevirtual

Occupy vacant space in Buffers with some data.

May exceeed a single block of production Can assume same buffer is passed each time, while the caller advances it over the previous production, or discards it, or rotates the buffer. May rewind or rotate the buffer.

Returns
number of positions available to read from data or nullopt to fail
Precondition
AcceptsBuffers(data)
AcceptsBlockSize(data.BlockSize())
bound <= data.BlockSize()
data.BlockSize() <= data.Remaining()
Postcondition
result: !result || *result <= bound
result: !result || *result <= data.Remaining()
result: !result || *result <= Remaining()
data.Remaining() > 0
result: !result || bound == 0 || Remaining() == 0 || *result > 0 (progress guarantee)
!Terminates() or Remaining() was not previously defined, or is unchanged

Implements AudioGraph::Source.

Definition at line 338 of file MixerSource.cpp.

339{
340 assert(AcceptsBuffers(data));
341 assert(AcceptsBlockSize(data.BlockSize()));
342 assert(bound <= data.BlockSize());
343 assert(data.BlockSize() <= data.Remaining());
344
345 auto &[mT0, mT1, _, mTime] = *mTimesAndSpeed;
346 const bool backwards = (mT1 < mT0);
347 // TODO: more-than-two-channels
348 const auto maxChannels = mMaxChannels = data.Channels();
349 const auto limit = std::min<size_t>(mnChannels, maxChannels);
350 size_t maxTrack = 0;
351 const auto mixed = stackAllocate(size_t, maxChannels);
352 const auto pFloats = stackAllocate(float *, limit);
353 for (size_t j = 0; j < limit; ++j)
354 pFloats[j] = &data.GetWritePosition(j);
355 const auto rate = GetSequence().GetRate();
356 auto result = (mResampleParameters.mVariableRates || rate != mRate)
357 ? MixVariableRates(limit, bound, pFloats)
358 : MixSameRate(limit, bound, pFloats);
359 maxTrack = std::max(maxTrack, result);
360 auto newT = mSamplePos.as_double() / rate;
361 if (backwards)
362 mTime = std::min(mTime, newT);
363 else
364 mTime = std::max(mTime, newT);
365 for (size_t j = 0; j < limit; ++j) {
366 mixed[j] = result;
367 }
368 // Another pass in case channels of a track did not produce equal numbers
369 for (size_t j = 0; j < limit; ++j) {
370 const auto pFloat = &data.GetWritePosition(j);
371 const auto result = mixed[j];
372 ZeroFill(result, maxTrack, *pFloat);
373 }
374
375 mLastProduced = maxTrack;
376 assert(maxTrack <= bound);
377 assert(maxTrack <= data.Remaining());
378 assert(maxTrack <= Remaining());
379 assert(data.Remaining() > 0);
380 assert(bound == 0 || Remaining() == 0 || maxTrack > 0);
381 return { mLastProduced };
382}
int min(int a, int b)
#define _(s)
Definition: Internat.h:73
#define stackAllocate(T, count)
sampleCount Remaining() const override
Result includes any amount Acquired and not yet Released.
size_t MixSameRate(unsigned nChannels, size_t maxOut, float *floatBuffers[])
bool AcceptsBuffers(const Buffers &buffers) const override
size_t MixVariableRates(unsigned nChannels, size_t maxOut, float *floatBuffers[])
Definition: MixerSource.cpp:68
size_t mLastProduced
Definition: MixerSource.h:139
unsigned mMaxChannels
Remember how many channels were passed to Acquire()
Definition: MixerSource.h:138
void ZeroFill(size_t produced, size_t max, float &floatBuffer)
virtual double GetRate() const =0
double as_double() const
Definition: SampleCount.h:46

References _, AcceptsBlockSize(), AcceptsBuffers(), sampleCount::as_double(), AudioGraph::Buffers::BlockSize(), AudioGraph::Buffers::Channels(), WideSampleSequence::GetRate(), GetSequence(), AudioGraph::Buffers::GetWritePosition(), min(), MixSameRate(), MixVariableRates(), mLastProduced, mMaxChannels, mnChannels, mRate, mResampleParameters, mSamplePos, mTimesAndSpeed, MixerOptions::ResampleParameters::mVariableRates, AudioGraph::Buffers::Remaining(), Remaining(), stackAllocate, and ZeroFill().

Here is the call graph for this function:

◆ Channels()

unsigned MixerSource::Channels ( ) const
inline

Definition at line 52 of file MixerSource.h.

52{ return mnChannels; }

References mnChannels.

◆ GetSequence()

const WideSampleSequence & MixerSource::GetSequence ( ) const

Definition at line 316 of file MixerSource.cpp.

317{
318 return *mpSeq;
319}

References mpSeq.

Referenced by Acquire(), MixerSource(), and Reposition().

Here is the caller graph for this function:

◆ MakeResamplers()

void MixerSource::MakeResamplers ( )
private

Definition at line 40 of file MixerSource.cpp.

References MixerOptions::ResampleParameters::mHighQuality, MixerOptions::ResampleParameters::mMaxFactor, MixerOptions::ResampleParameters::mMinFactor, mnChannels, mResample, and mResampleParameters.

Referenced by MixerSource(), and Reposition().

Here is the caller graph for this function:

◆ MixerSpec()

const bool * MixerSource::MixerSpec ( unsigned  iChannel) const

◆ MixSameRate()

size_t MixerSource::MixSameRate ( unsigned  nChannels,
size_t  maxOut,
float *  floatBuffers[] 
)
private

Assume floatBuffers has extent nChannels

Postcondition
result: result <= maxOut

Definition at line 219 of file MixerSource.cpp.

221{
222 const auto &[mT0, mT1, _, __] = *mTimesAndSpeed;
223 const bool backwards = (mT1 < mT0);
224 const auto sequenceRate = mpSeq->GetRate();
225 const double tEnd = [mpSeq = mpSeq, mT1 = mT1, backwards]{
226 const double sequenceEndTime = mpSeq->GetEndTime();
227 const double sequenceStartTime = mpSeq->GetStartTime();
228 return backwards
229 ? std::max(sequenceStartTime, mT1)
230 : std::min(sequenceEndTime, mT1);
231 }();
232
233 // This function fetches samples from the input sequences, whatever their
234 // formats, as floats; it may also apply envelope values.
235
236 auto pos = mSamplePos;
237
238 const double t = (pos).as_double() / sequenceRate;
239
240 //don't process if we're at the end of the selection or sequence.
241 if ((backwards ? t <= tEnd : t >= tEnd))
242 return 0;
243 //if we're about to approach the end of the sequence or selection, figure out how much we need to grab
244 const auto slen = limitSampleBufferSize(
245 maxOut,
246 // PRL: maybe t and tEnd should be given as sampleCount instead to
247 // avoid trouble subtracting one large value from another for a small
248 // difference
249 sampleCount{ (backwards ? t - tEnd : tEnd - t) * sequenceRate + 0.5 }
250 );
251
252 constexpr auto iChannel = 0u;
253 if (!mpSeq->GetFloats(
254 iChannel, nChannels, floatBuffers, pos, slen, backwards,
256 ) {
257 // Now redundant in case of failure
258 // for (size_t iChannel = 0; iChannel < nChannels; ++iChannel)
259 // memset(floatBuffers[iChannel], 0, sizeof(float) * slen);
260
261 }
262
263 mpSeq->GetEnvelopeValues(mEnvValues.data(), slen, t, backwards);
264
265 for (size_t iChannel = 0; iChannel < nChannels; ++iChannel) {
266 const auto pFloat = floatBuffers[iChannel];
267 for (size_t i = 0; i < slen; i++)
268 pFloat[i] *= mEnvValues[i]; // Track gain control will go here?
269 }
270
271 if (backwards)
272 pos -= slen;
273 else
274 pos += slen;
275
276 assert(slen <= maxOut);
277 mSamplePos = pos;
278 return slen;
279}
size_t limitSampleBufferSize(size_t bufferSize, sampleCount limit)
Definition: SampleCount.cpp:22
Positions or offsets within audio files need a wide type.
Definition: SampleCount.h:19
STL namespace.

References _, fillZero, i, anonymous_namespace{StretchingSequenceIntegrationTest.cpp}::iChannel, limitSampleBufferSize(), mEnvValues, min(), mMayThrow, mpSeq, mSamplePos, and mTimesAndSpeed.

Referenced by Acquire().

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

◆ MixVariableRates()

size_t MixerSource::MixVariableRates ( unsigned  nChannels,
size_t  maxOut,
float *  floatBuffers[] 
)
private

Assume floatBuffers has extent nChannels

Postcondition
result: result <= maxOut

Definition at line 68 of file MixerSource.cpp.

70{
71 const auto &[mT0, mT1, mSpeed, _] = *mTimesAndSpeed;
72 const bool backwards = (mT1 < mT0);
73
74 const double sequenceRate = mpSeq->GetRate();
75 const double initialWarp = mRate / mSpeed / sequenceRate;
76 const double tstep = 1.0 / sequenceRate;
77 const auto sampleSize = SAMPLE_SIZE(floatSample);
78 // Find the last sample
79 const auto endPos = [mpSeq = mpSeq, mT1 = mT1, backwards]{
80 double endTime = mpSeq->GetEndTime();
81 double startTime = mpSeq->GetStartTime();
82 const double tEnd = backwards
83 ? std::max(startTime, mT1)
84 : std::min(endTime, mT1);
85 return mpSeq->TimeToLongSamples(tEnd);
86 }();
87
88 auto pos = mSamplePos;
89 auto queueStart = mQueueStart;
90 auto queueLen = mQueueLen;
91
92 size_t out = 0;
93
94 /* time is floating point. Sample rate is integer. The number of samples
95 * has to be integer, but the multiplication gives a float result, which we
96 * round to get an integer result. TODO: is this always right or can it be
97 * off by one sometimes? Can we not get this information directly from the
98 * clip (which must know) rather than convert the time?
99 *
100 * LLL: Not at this time. While WaveClips provide methods to retrieve the
101 * start and end sample, they do the same float->sampleCount conversion
102 * to calculate the position.
103 */
104
105 // Find the time corresponding to the start of the queue, for use with time track
106 double t = ((pos).as_long_long() +
107 (backwards ? queueLen : - queueLen)) / sequenceRate;
108
109 while (out < maxOut) {
110 if (queueLen < (int)sProcessLen) {
111 // Shift pending portion to start of the buffer
112 for (size_t iChannel = 0; iChannel < nChannels; ++iChannel) {
113 const auto queue = mSampleQueue[iChannel].data();
114 memmove(queue, &queue[queueStart], (queueLen) * sampleSize);
115 }
116 queueStart = 0;
117
118 // How far to advance depends on endPos,
119 // which is independent of channel
120 auto getLen = limitSampleBufferSize(
121 sQueueMaxLen - queueLen,
122 backwards ? pos - endPos : endPos - pos
123 );
124
125 // Nothing to do if past end of play interval
126 if (getLen > 0) {
127 std::vector<float*> dst;
128 for (auto& queue : mSampleQueue)
129 dst.push_back(queue.data() + queueLen);
130 constexpr auto iChannel = 0u;
131 if (!mpSeq->GetFloats(
132 iChannel, nChannels, dst.data(), pos, getLen, backwards,
134 // Now redundant in case of failure
135 // for (size_t iChannel = 0; iChannel < nChannels; ++iChannel)
136 // memset(dst[i], 0, sizeof(float) * getLen);
137 }
138 mpSeq->GetEnvelopeValues(
139 mEnvValues.data(), getLen, (pos).as_double() / sequenceRate,
140 backwards);
141 for (size_t iChannel = 0; iChannel < nChannels; ++iChannel) {
142 const auto queue = mSampleQueue[iChannel].data();
143 for (decltype(getLen) i = 0; i < getLen; i++)
144 queue[(queueLen) + i] *= mEnvValues[i];
145 }
146
147 if (backwards)
148 pos -= getLen;
149 else
150 pos += getLen;
151 queueLen += getLen;
152 }
153 }
154
155 auto thisProcessLen = sProcessLen;
156 bool last = (queueLen < (int)sProcessLen);
157 if (last) {
158 thisProcessLen = queueLen;
159 }
160
161 double factor = initialWarp;
162 if (mEnvelope)
163 {
164 //TODO-MB: The end time is wrong when the resampler doesn't use all input samples,
165 // as a result of this the warp factor may be slightly wrong, so AudioIO will stop too soon
166 // or too late (resulting in missing sound or inserted silence). This can't be fixed
167 // without changing the way the resampler works, because the number of input samples that will be used
168 // is unpredictable. Maybe it can be compensated later though.
169 if (backwards)
170 factor *= ComputeWarpFactor( *mEnvelope,
171 t - (double)thisProcessLen / sequenceRate + tstep, t + tstep);
172 else
173 factor *= ComputeWarpFactor( *mEnvelope,
174 t, t + (double)thisProcessLen / sequenceRate);
175 }
176
177 std::pair<size_t, size_t> results;
178 for (size_t iChannel = 0; iChannel < nChannels; ++iChannel) {
179 const auto queue = mSampleQueue[iChannel].data();
180 const auto pResample = mResample[iChannel].get();
181 const auto pFloat = floatBuffers[iChannel];
182 // Assuming that progress of the Resampler depends only
183 // on the size of its inputs, this assignment has the same effect on
184 // each pass.
185 results = pResample->Process(factor,
186 &queue[queueStart],
187 thisProcessLen,
188 last,
189 // PRL: Bug2536: crash in soxr happened on Mac, sometimes, when
190 // maxOut - out == 1 and &pFloat[out + 1] was an unmapped
191 // address, because soxr, strangely, fetched an 8-byte (misaligned!)
192 // value from &pFloat[out], but did nothing with it anyway,
193 // in soxr_output_no_callback.
194 // Now we make the bug go away by allocating a little more space in
195 // the buffer than we need.
196 &pFloat[out],
197 maxOut - out);
198 }
199
200 const auto input_used = results.first;
201 queueStart += input_used;
202 queueLen -= input_used;
203 out += results.second;
204 t += (input_used / sequenceRate) * (backwards ? -1 : 1);
205
206 if (last) {
207 break;
208 }
209 }
210
211 assert(out <= maxOut);
212
213 mSamplePos = pos;
214 mQueueStart = queueStart;
215 mQueueLen = queueLen;
216 return out;
217}
#define SAMPLE_SIZE(SampleFormat)
Definition: SampleFormat.h:52
static constexpr size_t sProcessLen
Definition: MixerSource.h:73
double ComputeWarpFactor(const Envelope &env, double t0, double t1)
Compute the integral warp factor between two non-warped time points.
Definition: MixerSource.cpp:61

References _, anonymous_namespace{MixerSource.cpp}::ComputeWarpFactor(), fillZero, floatSample, i, anonymous_namespace{StretchingSequenceIntegrationTest.cpp}::iChannel, limitSampleBufferSize(), mEnvelope, mEnvValues, min(), mMayThrow, mpSeq, mQueueLen, mQueueStart, mRate, mResample, mSamplePos, mSampleQueue, mTimesAndSpeed, SAMPLE_SIZE, sProcessLen, and sQueueMaxLen.

Referenced by Acquire().

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

◆ operator=()

MixerSource & MixerSource::operator= ( MixerSource &&  )
delete

◆ Release()

bool MixerSource::Release ( )
overridevirtual

Caller is done examining last Acquire()d positions.

May be called only after at least one successful call to Acquire()

Returns
success
Postcondition
!Terminates() or Remaining() reduced by what was last returned by Acquire()

Implements AudioGraph::Source.

Definition at line 392 of file MixerSource.cpp.

393{
394 mLastProduced = 0;
395 return true;
396}

References mLastProduced.

◆ Remaining()

sampleCount MixerSource::Remaining ( ) const
overridevirtual

Result includes any amount Acquired and not yet Released.

May be undefined before the first successful call to Acquire()

Postcondition
result: result >= 0

Implements AudioGraph::Source.

Definition at line 386 of file MixerSource.cpp.

387{
388 // TODO: make a more exact calculation of total remaining; see Terminates()
389 return mLastProduced;
390}

References mLastProduced.

Referenced by Acquire().

Here is the caller graph for this function:

◆ Reposition()

void MixerSource::Reposition ( double  time,
bool  skipping 
)

Definition at line 408 of file MixerSource.cpp.

409{
411 mQueueStart = 0;
412 mQueueLen = 0;
413
414 // Bug 2025: libsoxr 0.1.3, first used in Audacity 2.3.0, crashes with
415 // constant rate resampling if you try to reuse the resampler after it has
416 // flushed. Should that be considered a bug in sox? This works around it.
417 // (See also bug 1887, and the same work around in Mixer::Restart().)
418 if (skipping)
420}

References GetSequence(), MakeResamplers(), mQueueLen, mQueueStart, mSamplePos, and WideSampleSequence::TimeToLongSamples().

Here is the call graph for this function:

◆ Terminates()

bool MixerSource::Terminates ( ) const
overridevirtual
Returns
false

Reimplemented from AudioGraph::Source.

Definition at line 398 of file MixerSource.cpp.

399{
400 // Not always terminating
401 // TODO: return true sometimes, for mixers that never reposition
402 // because they are not used in playback. But then an exact calculation of
403 // Remaining() is needed to satisfy the contract, and that is complicated
404 // when there is resampling or a time warp.
405 return false;
406}

◆ VariableRates()

bool MixerSource::VariableRates ( ) const
inline

Definition at line 65 of file MixerSource.h.

References mResampleParameters, and MixerOptions::ResampleParameters::mVariableRates.

Referenced by Mixer::NeedsDither().

Here is the caller graph for this function:

◆ ZeroFill()

void MixerSource::ZeroFill ( size_t  produced,
size_t  max,
float &  floatBuffer 
)
private
Precondition
produced <= max

Definition at line 281 of file MixerSource.cpp.

283{
284 assert(produced <= max);
285 const auto pFloat = &floatBuffer;
286 std::fill(pFloat + produced, pFloat + max, 0);
287}

Referenced by Acquire().

Here is the caller graph for this function:

Member Data Documentation

◆ i

size_t MixerSource::i
private

Definition at line 101 of file MixerSource.h.

Referenced by MixSameRate(), and MixVariableRates().

◆ mEnvelope

const BoundedEnvelope* const MixerSource::mEnvelope
private

Resampling, as needed, after gain envelope.

Definition at line 107 of file MixerSource.h.

Referenced by MixVariableRates().

◆ mEnvValues

std::vector<double> MixerSource::mEnvValues
private

Gain envelopes are applied to input before other transformations.

Definition at line 131 of file MixerSource.h.

Referenced by AcceptsBlockSize(), MixSameRate(), and MixVariableRates().

◆ mLastProduced

size_t MixerSource::mLastProduced {}
private

Definition at line 139 of file MixerSource.h.

Referenced by Acquire(), Release(), and Remaining().

◆ mMaxChannels

unsigned MixerSource::mMaxChannels {}
private

Remember how many channels were passed to Acquire()

Definition at line 138 of file MixerSource.h.

Referenced by Acquire().

◆ mMayThrow

const bool MixerSource::mMayThrow
private

Definition at line 108 of file MixerSource.h.

Referenced by MixSameRate(), and MixVariableRates().

◆ mnChannels

const size_t MixerSource::mnChannels
private

Definition at line 103 of file MixerSource.h.

Referenced by Acquire(), Channels(), and MakeResamplers().

◆ mpMap

const ArrayOf<bool>* const MixerSource::mpMap
private

many-to-one mixing of channels Pointer into array of arrays

Definition at line 135 of file MixerSource.h.

Referenced by MixerSpec().

◆ mpSeq

const std::shared_ptr<const WideSampleSequence> MixerSource::mpSeq
private

Definition at line 100 of file MixerSource.h.

Referenced by GetSequence(), MixSameRate(), and MixVariableRates().

◆ mQueueLen

int MixerSource::mQueueLen
private

The number of available samples after the queue start.

Definition at line 125 of file MixerSource.h.

Referenced by MixVariableRates(), and Reposition().

◆ mQueueStart

int MixerSource::mQueueStart
private

Position of the start of the next block to resample.

Definition at line 122 of file MixerSource.h.

Referenced by MixVariableRates(), and Reposition().

◆ mRate

const double MixerSource::mRate
private

Definition at line 104 of file MixerSource.h.

Referenced by Acquire(), and MixVariableRates().

◆ mResample

std::vector<std::unique_ptr<Resample> > MixerSource::mResample
private

Definition at line 128 of file MixerSource.h.

Referenced by MakeResamplers(), and MixVariableRates().

◆ mResampleParameters

const ResampleParameters MixerSource::mResampleParameters
private

Definition at line 127 of file MixerSource.h.

Referenced by Acquire(), MakeResamplers(), and VariableRates().

◆ mSamplePos

sampleCount MixerSource::mSamplePos
private

Fetch position for source.

mSamplePos holds the next sample position not yet processed

Definition at line 116 of file MixerSource.h.

Referenced by Acquire(), MixerSource(), MixSameRate(), MixVariableRates(), and Reposition().

◆ mSampleQueue

std::vector<std::vector<float> > MixerSource::mSampleQueue
private

First intermediate buffer when resampling is needed.

Definition at line 119 of file MixerSource.h.

Referenced by MixVariableRates().

◆ mTimesAndSpeed

const std::shared_ptr<TimesAndSpeed> MixerSource::mTimesAndSpeed
private

Definition at line 110 of file MixerSource.h.

Referenced by Acquire(), MixerSource(), MixSameRate(), and MixVariableRates().

◆ sProcessLen

constexpr size_t MixerSource::sProcessLen = 1024
staticconstexprprivate

Cut the queue into blocks of this finer size for variable rate resampling. Each block is resampled at some constant rate.

Definition at line 73 of file MixerSource.h.

Referenced by MixVariableRates().

◆ sQueueMaxLen

constexpr size_t MixerSource::sQueueMaxLen = 65536
staticconstexprprivate

This is the number of samples grabbed in one go from a track and placed in a queue, when mixing with resampling.

(Should we use SampleTrack::GetBestBlockSize instead?)

Definition at line 80 of file MixerSource.h.

Referenced by MixVariableRates().


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