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 SampleTrack &leader, 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 SampleTrackGetChannel (unsigned iChannel) 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 iChannel, size_t maxOut, float &floatBuffer)
 
size_t MixVariableRates (unsigned iChannel, size_t maxOut, float &floatBuffer)
 
void ZeroFill (size_t produced, size_t max, float &floatBuffer)
 

Private Attributes

const std::shared_ptr< const SampleTrackmpLeader
 
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
 
std::vector< SampleTrackCachemInputTrack
 SampleTrackCaches are the source of data. More...
 
std::vector< sampleCountmSamplePos
 Fetch position for source. More...
 
std::vector< std::vector< float > > mSampleQueue
 First intermediate buffer when resampling is needed. More...
 
std::vector< int > mQueueStart
 Position in each queue of the start of the next block to resample. More...
 
std::vector< int > mQueueLen
 For each queue, 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 30 of file MixerSource.h.

Member Typedef Documentation

◆ ResampleParameters

Definition at line 33 of file MixerSource.h.

◆ TimesAndSpeed

Definition at line 32 of file MixerSource.h.

Constructor & Destructor Documentation

◆ MixerSource() [1/2]

MixerSource::MixerSource ( const SampleTrack leader,
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 283 of file MixerSource.cpp.

287 : mpLeader{ leader.SharedPointer<const SampleTrack>() }
289 , mRate{ rate }
290 , mEnvelope{ options.envelope }
291 , mMayThrow{ mayThrow }
292 , mTimesAndSpeed{ move(pTimesAndSpeed) }
295 , mSampleQueue{ initVector<float>(mnChannels, sQueueMaxLen) }
296 , mQueueStart( mnChannels, 0 )
297 , mQueueLen( mnChannels, 0 )
298 , mResampleParameters{ highQuality, leader, rate, options }
300 , mEnvValues( std::max(sQueueMaxLen, bufferSize) )
301 , mpMap{ pMap }
302{
303 size_t j = 0;
304 for (auto channel : TrackList::Channels(&leader))
305 mInputTrack[j++].SetTrack(channel->SharedPointer<const SampleTrack>());
306
307 assert(mTimesAndSpeed);
308 auto t0 = mTimesAndSpeed->mT0;
309 for (j = 0; j < mnChannels; ++j) {
311 }
313}
std::vector< double > mEnvValues
Gain envelopes are applied to input before other transformations.
Definition: MixerSource.h:128
const ResampleParameters mResampleParameters
Definition: MixerSource.h:124
const BoundedEnvelope *const mEnvelope
Resampling, as needed, after gain envelope.
Definition: MixerSource.h:101
const std::shared_ptr< TimesAndSpeed > mTimesAndSpeed
Definition: MixerSource.h:104
std::vector< std::vector< float > > mSampleQueue
First intermediate buffer when resampling is needed.
Definition: MixerSource.h:116
const SampleTrack * GetChannel(unsigned iChannel) const
static constexpr size_t sQueueMaxLen
Definition: MixerSource.h:76
std::vector< sampleCount > mSamplePos
Fetch position for source.
Definition: MixerSource.h:113
std::vector< SampleTrackCache > mInputTrack
SampleTrackCaches are the source of data.
Definition: MixerSource.h:107
const ArrayOf< bool > *const mpMap
Definition: MixerSource.h:132
const bool mMayThrow
Definition: MixerSource.h:102
std::vector< std::unique_ptr< Resample > > mResample
Definition: MixerSource.h:125
std::vector< int > mQueueLen
For each queue, the number of available samples after the queue start.
Definition: MixerSource.h:122
std::vector< int > mQueueStart
Position in each queue of the start of the next block to resample.
Definition: MixerSource.h:119
const double mRate
Definition: MixerSource.h:98
const size_t mnChannels
Definition: MixerSource.h:97
void MakeResamplers()
Definition: MixerSource.cpp:41
const std::shared_ptr< const SampleTrack > mpLeader
Definition: MixerSource.h:94
sampleCount TimeToLongSamples(double t0) const
Convert correctly between an (absolute) time in seconds and a number of samples.
Definition: SampleTrack.cpp:43
std::shared_ptr< Subclass > SharedPointer()
Definition: Track.h:232
static size_t NChannels(const Track &track)
Count channels of a track.
Definition: Track.h:1424
static auto Channels(TrackType *pTrack) -> TrackIterRange< TrackType >
Definition: Track.h:1417
const BoundedEnvelope *const envelope
Definition: MixerOptions.h:74

References TrackList::Channels(), GetChannel(), MakeResamplers(), mInputTrack, mnChannels, mSamplePos, mTimesAndSpeed, and SampleTrack::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 335 of file MixerSource.cpp.

336{
337 return blockSize <= mEnvValues.size();
338}

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 330 of file MixerSource.cpp.

331{
332 return AcceptsBlockSize(buffers.BufferSize());
333}
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 342 of file MixerSource.cpp.

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

References _, AcceptsBlockSize(), AcceptsBuffers(), AudioGraph::Buffers::BlockSize(), AudioGraph::Buffers::Channels(), GetChannel(), 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 48 of file MixerSource.h.

48{ return mnChannels; }

References mnChannels.

◆ GetChannel()

const SampleTrack * MixerSource::GetChannel ( unsigned  iChannel) const

Definition at line 317 of file MixerSource.cpp.

318{
319 auto range = TrackList::Channels(mpLeader.get());
320 auto iter = range.begin();
321 std::advance(iter, iChannel);
322 return *iter;
323}

References TrackList::Channels(), and mpLeader.

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

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

◆ MakeResamplers()

void MixerSource::MakeResamplers ( )
private

Definition at line 41 of file MixerSource.cpp.

42{
43 for (size_t j = 0; j < mnChannels; ++j)
44 mResample[j] = std::make_unique<Resample>(
47}
std::vector< double > mMaxFactor
Definition: MixerOptions.h:85
std::vector< double > mMinFactor
Definition: MixerOptions.h:85

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

Definition at line 325 of file MixerSource.cpp.

326{
327 return mpMap ? mpMap[iChannel].get() : nullptr;
328}

References mpMap.

◆ MixSameRate()

size_t MixerSource::MixSameRate ( unsigned  iChannel,
size_t  maxOut,
float &  floatBuffer 
)
private
Postcondition
result: result <= maxOut

Definition at line 213 of file MixerSource.cpp.

215{
216 // This function fetches samples from the input tracks, whatever their
217 // formats, as floats; it may also apply envelope values.
218
219 auto &cache = mInputTrack[iChannel];
220 const auto pos = &mSamplePos[iChannel];
221
222 const auto pFloat = &floatBuffer;
223 const auto track = cache.GetTrack().get();
224 const double t = ( *pos ).as_double() / track->GetRate();
225 const double trackEndTime = track->GetEndTime();
226 const double trackStartTime = track->GetStartTime();
227 const auto &[mT0, mT1, _, __] = *mTimesAndSpeed;
228 const bool backwards = (mT1 < mT0);
229 const double tEnd = backwards
230 ? std::max(trackStartTime, mT1)
231 : std::min(trackEndTime, mT1);
232
233 //don't process if we're at the end of the selection or track.
234 if ((backwards ? t <= tEnd : t >= tEnd))
235 return 0;
236 //if we're about to approach the end of the track or selection, figure out how much we need to grab
237 const auto slen = limitSampleBufferSize(
238 maxOut,
239 // PRL: maybe t and tEnd should be given as sampleCount instead to
240 // avoid trouble subtracting one large value from another for a small
241 // difference
242 sampleCount{ (backwards ? t - tEnd : tEnd - t) * track->GetRate() + 0.5 }
243 );
244
245 if (backwards) {
246 auto results = cache.GetFloats(*pos - (slen - 1), slen, mMayThrow);
247 if (results)
248 memcpy(pFloat, results, sizeof(float) * slen);
249 else
250 memset(pFloat, 0, sizeof(float) * slen);
251 track->GetEnvelopeValues(mEnvValues.data(), slen, t - (slen - 1) / mRate);
252 for (size_t i = 0; i < slen; i++)
253 pFloat[i] *= mEnvValues[i]; // Track gain control will go here?
254 ReverseSamples((samplePtr)pFloat, floatSample, 0, slen);
255
256 *pos -= slen;
257 }
258 else {
259 auto results = cache.GetFloats(*pos, slen, mMayThrow);
260 if (results)
261 memcpy(pFloat, results, sizeof(float) * slen);
262 else
263 memset(pFloat, 0, sizeof(float) * slen);
264 track->GetEnvelopeValues(mEnvValues.data(), slen, t);
265 for (size_t i = 0; i < slen; i++)
266 pFloat[i] *= mEnvValues[i]; // Track gain control will go here?
267
268 *pos += slen;
269 }
270
271 assert(slen <= maxOut);
272 return slen;
273}
size_t limitSampleBufferSize(size_t bufferSize, sampleCount limit)
Definition: SampleCount.cpp:22
void ReverseSamples(samplePtr dst, sampleFormat format, int start, int len)
char * samplePtr
Definition: SampleFormat.h:55
size_t i
Definition: MixerSource.h:95
Positions or offsets within audio files need a wide type.
Definition: SampleCount.h:19
STL namespace.

References _, floatSample, i, limitSampleBufferSize(), mEnvValues, min(), mInputTrack, mMayThrow, mRate, mSamplePos, mTimesAndSpeed, and ReverseSamples().

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  iChannel,
size_t  maxOut,
float &  floatBuffer 
)
private
Postcondition
result: result <= maxOut

Definition at line 69 of file MixerSource.cpp.

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

References _, anonymous_namespace{MixerSource.cpp}::ComputeWarpFactor(), floatSample, i, limitSampleBufferSize(), mEnvelope, mEnvValues, min(), mInputTrack, mMayThrow, mQueueLen, mQueueStart, mRate, mResample, mSamplePos, mSampleQueue, mTimesAndSpeed, ReverseSamples(), 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 395 of file MixerSource.cpp.

396{
397 mLastProduced = 0;
398 return true;
399}

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 389 of file MixerSource.cpp.

390{
391 // TODO: make a more exact calculation of total remaining; see Terminates()
392 return mLastProduced;
393}

References mLastProduced.

Referenced by Acquire().

Here is the caller graph for this function:

◆ Reposition()

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

Definition at line 411 of file MixerSource.cpp.

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

References GetChannel(), MakeResamplers(), mnChannels, mQueueLen, mQueueStart, mSamplePos, and SampleTrack::TimeToLongSamples().

Here is the call graph for this function:

◆ Terminates()

bool MixerSource::Terminates ( ) const
overridevirtual
Returns
false

Reimplemented from AudioGraph::Source.

Definition at line 401 of file MixerSource.cpp.

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

◆ VariableRates()

bool MixerSource::VariableRates ( ) const
inline

Definition at line 61 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 275 of file MixerSource.cpp.

277{
278 assert(produced <= max);
279 const auto pFloat = &floatBuffer;
280 std::fill(pFloat + produced, pFloat + max, 0);
281}

Referenced by Acquire().

Here is the caller graph for this function:

Member Data Documentation

◆ i

size_t MixerSource::i
private

Definition at line 95 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 101 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 128 of file MixerSource.h.

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

◆ mInputTrack

std::vector<SampleTrackCache> MixerSource::mInputTrack
private

SampleTrackCaches are the source of data.

Definition at line 107 of file MixerSource.h.

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

◆ mLastProduced

size_t MixerSource::mLastProduced {}
private

Definition at line 136 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 135 of file MixerSource.h.

Referenced by Acquire().

◆ mMayThrow

const bool MixerSource::mMayThrow
private

Definition at line 102 of file MixerSource.h.

Referenced by MixSameRate(), and MixVariableRates().

◆ mnChannels

const size_t MixerSource::mnChannels
private

Definition at line 97 of file MixerSource.h.

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

◆ mpLeader

const std::shared_ptr<const SampleTrack> MixerSource::mpLeader
private

Definition at line 94 of file MixerSource.h.

Referenced by GetChannel().

◆ mpMap

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

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

Definition at line 132 of file MixerSource.h.

Referenced by MixerSpec().

◆ mQueueLen

std::vector<int> MixerSource::mQueueLen
private

For each queue, the number of available samples after the queue start.

Definition at line 122 of file MixerSource.h.

Referenced by MixVariableRates(), and Reposition().

◆ mQueueStart

std::vector<int> MixerSource::mQueueStart
private

Position in each queue of the start of the next block to resample.

Definition at line 119 of file MixerSource.h.

Referenced by MixVariableRates(), and Reposition().

◆ mRate

const double MixerSource::mRate
private

Definition at line 98 of file MixerSource.h.

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

◆ mResample

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

Definition at line 125 of file MixerSource.h.

Referenced by MakeResamplers(), and MixVariableRates().

◆ mResampleParameters

const ResampleParameters MixerSource::mResampleParameters
private

Definition at line 124 of file MixerSource.h.

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

◆ mSamplePos

std::vector<sampleCount> MixerSource::mSamplePos
private

Fetch position for source.

mSamplePos holds for each track the next sample position not yet processed.

Definition at line 113 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 116 of file MixerSource.h.

Referenced by MixVariableRates().

◆ mTimesAndSpeed

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

Definition at line 104 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 69 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 76 of file MixerSource.h.

Referenced by MixVariableRates().


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