Audacity 3.2.0
Classes | Public Types | Public Member Functions | Private Member Functions | Private Attributes | List of all members
Mixer Class Reference

Functions for doing the mixdown of the tracks. More...

#include <Mix.h>

Collaboration diagram for Mixer:
[legend]

Classes

struct  Input
 
struct  Source
 

Public Types

using WarpOptions = MixerOptions::Warp
 
using MixerSpec = MixerOptions::Downmix
 
using ResampleParameters = MixerOptions::ResampleParameters
 
using TimesAndSpeed = MixerOptions::TimesAndSpeed
 
using Stages = std::vector< MixerOptions::StageSpecification >
 
using Inputs = std::vector< Input >
 

Public Member Functions

 Mixer (Inputs inputs, bool mayThrow, const WarpOptions &warpOptions, double startTime, double stopTime, unsigned numOutChannels, size_t outBufferSize, bool outInterleaved, double outRate, sampleFormat outFormat, bool highQuality=true, MixerSpec *mixerSpec=nullptr, bool applytTrackGains=true)
 
 Mixer (const Mixer &)=delete
 
Mixeroperator= (const Mixer &)=delete
 
virtual ~Mixer ()
 
size_t BufferSize () const
 
size_t Process (size_t maxSamples)
 
size_t Process ()
 
void Reposition (double t, bool bSkipping=false)
 Reposition processing to absolute time next time Process() is called. More...
 
void SetTimesAndSpeed (double t0, double t1, double speed, bool bSkipping=false)
 Used in scrubbing and other nonuniform playback policies. More...
 
void SetSpeedForKeyboardScrubbing (double speed, double startTime)
 
double MixGetCurrentTime ()
 Current time in seconds (unwarped, i.e. always between startTime and stopTime) More...
 
constSamplePtr GetBuffer ()
 Retrieve the main buffer or the interleaved buffer. More...
 
constSamplePtr GetBuffer (int channel)
 Retrieve one of the non-interleaved buffers. More...
 
sampleFormat EffectiveFormat () const
 Deduce the effective width of the output, which may be narrower than the stored format. More...
 

Private Member Functions

void Clear ()
 
std::pair< bool, sampleFormatNeedsDither (bool needsDither, double rate) const
 

Private Attributes

const unsigned mNumChannels
 
Inputs mInputs
 
const size_t mBufferSize
 
const bool mApplyTrackGains
 
const bool mHighQuality
 
const sampleFormat mFormat
 
const bool mInterleaved
 
sampleFormat mEffectiveFormat
 
bool mNeedsDither
 
const std::shared_ptr< TimesAndSpeedmTimesAndSpeed
 
AudioGraph::Buffers mFloatBuffers
 
std::vector< std::vector< float > > mTemp
 
const std::vector< SampleBuffermBuffer
 
std::vector< MixerSourcemSources
 
std::vector< EffectSettingsmSettings
 
std::vector< AudioGraph::BuffersmStageBuffers
 
std::vector< std::unique_ptr< EffectStage > > mStages
 
std::vector< SourcemDecoratedSources
 

Detailed Description

Functions for doing the mixdown of the tracks.

Definition at line 27 of file Mix.h.

Member Typedef Documentation

◆ Inputs

using Mixer::Inputs = std::vector<Input>

Definition at line 45 of file Mix.h.

◆ MixerSpec

Definition at line 30 of file Mix.h.

◆ ResampleParameters

Definition at line 31 of file Mix.h.

◆ Stages

Definition at line 33 of file Mix.h.

◆ TimesAndSpeed

Definition at line 32 of file Mix.h.

◆ WarpOptions

Definition at line 29 of file Mix.h.

Constructor & Destructor Documentation

◆ Mixer() [1/2]

Mixer::Mixer ( Inputs  inputs,
bool  mayThrow,
const WarpOptions warpOptions,
double  startTime,
double  stopTime,
unsigned  numOutChannels,
size_t  outBufferSize,
bool  outInterleaved,
double  outRate,
sampleFormat  outFormat,
bool  highQuality = true,
MixerSpec mixerSpec = nullptr,
bool  applytTrackGains = true 
)
Precondition
all sequences in inputs are non-null
any left channels in inputs are immediately followed by their partners
Postcondition
BufferSize() <= outBufferSize (equality when no inputs have stages)
Parameters
mixerSpecNull or else must have a lifetime enclosing this object's

Definition at line 71 of file Mix.cpp.

80 : mNumChannels{ numOutChannels }
81 , mInputs{ move(inputs) }
82 , mBufferSize{ FindBufferSize(mInputs, outBufferSize) }
83 , mApplyTrackGains{ applyTrackGains }
84 , mHighQuality{ highQuality }
85 , mFormat{ outFormat }
86 , mInterleaved{ outInterleaved }
87
88 , mTimesAndSpeed{ std::make_shared<TimesAndSpeed>( TimesAndSpeed{
89 startTime, stopTime, warpOptions.initialSpeed, startTime
90 } ) }
91
92 // PRL: Bug2536: see other comments below for the last, padding argument
93 // TODO: more-than-two-channels
94 // Issue 3565 workaround: allocate one extra buffer when applying a
95 // GVerb effect stage. It is simply discarded
96 // See also issue 3854, when the number of out channels expected by the
97 // plug-in is yet larger
98 , mFloatBuffers{ 3, mBufferSize, 1, 1 }
99
100 // non-interleaved
101 , mTemp{ initVector<float>(mNumChannels, mBufferSize) }
102 , mBuffer{ initVector<SampleBuffer>(mInterleaved ? 1 : mNumChannels,
103 [format = mFormat,
105 ](auto &buffer){ buffer.Allocate(size, format); }
106 )}
108{
109 assert(BufferSize() <= outBufferSize);
110 const auto nChannelsIn =
111 std::accumulate(mInputs.begin(), mInputs.end(), size_t{},
112 [](auto sum, const auto &input){
113 return sum + input.pSequence->NChannels(); });
114
115 // Examine the temporary instances that were made in FindBufferSize
116 // This finds a sufficient, but not necessary, condition to do dithering
117 bool needsDither = std::any_of(mInputs.begin(), mInputs.end(),
118 [](const Input &input){
119 return std::any_of(input.stages.begin(), input.stages.end(),
120 [](const MixerOptions::StageSpecification &spec){
121 return spec.mpFirstInstance &&
122 spec.mpFirstInstance->NeedsDither(); } ); } );
123
124 auto pMixerSpec = ( mixerSpec &&
125 mixerSpec->GetNumChannels() == mNumChannels &&
126 mixerSpec->GetNumTracks() == nChannelsIn
127 ) ? mixerSpec : nullptr;
128
129 // Reserve vectors first so we can take safe references to pushed elements
130 mSources.reserve(nChannelsIn);
131 const auto nStages = std::accumulate(mInputs.begin(), mInputs.end(), 0,
132 [](auto sum, const auto &input){
133 return sum + input.stages.size() * input.pSequence->NChannels(); });
134 mSettings.reserve(nStages);
135 mStageBuffers.reserve(nStages);
136
137 size_t i = 0;
138 for (auto &input : mInputs) {
139 const auto &sequence = input.pSequence;
140 if (!sequence) {
141 assert(false);
142 break;
143 }
144 auto increment = finally([&]{ i += sequence->NChannels(); });
145
146 auto &source = mSources.emplace_back(sequence, BufferSize(), outRate,
147 warpOptions, highQuality, mayThrow, mTimesAndSpeed,
148 (pMixerSpec ? &pMixerSpec->mMap[i] : nullptr));
149 AudioGraph::Source *pDownstream = &source;
150 for (const auto &stage : input.stages) {
151 // Make a mutable copy of stage.settings
152 auto &settings = mSettings.emplace_back(stage.settings);
153 // TODO: more-than-two-channels
154 // Like mFloatBuffers but padding not needed for soxr
155 // Allocate one extra buffer to hold dummy zero inputs
156 // (Issue 3854)
157 auto &stageInput = mStageBuffers.emplace_back(3, mBufferSize, 1);
158 const auto &factory = [&stage]{
159 // Avoid unnecessary repeated calls to the factory
160 return stage.mpFirstInstance
161 ? move(stage.mpFirstInstance)
162 : stage.factory();
163 };
164 auto &pNewDownstream =
165 mStages.emplace_back(EffectStage::Create(-1,
166 *pDownstream, stageInput,
167 factory, settings, outRate, std::nullopt, *sequence
168 ));
169 if (pNewDownstream)
170 pDownstream = pNewDownstream.get();
171 else {
172 // Just omit the failed stage from rendering
173 // TODO propagate the error?
174 mStageBuffers.pop_back();
175 mSettings.pop_back();
176 }
177 }
178 mDecoratedSources.emplace_back(Source{ source, *pDownstream });
179 }
180
181 // Decide once at construction time
182 std::tie(mNeedsDither, mEffectiveFormat) = NeedsDither(needsDither, outRate);
183}
static Settings & settings()
Definition: TrackInfo.cpp:69
Upstream producer of sample streams, taking Buffers as external context.
static std::unique_ptr< EffectStage > Create(int channel, Source &upstream, Buffers &inBuffers, const Factory &factory, EffectSettings &settings, double sampleRate, std::optional< sampleCount > genLength, const WideSampleSequence &sequence)
Satisfies postcondition of constructor or returns null.
Definition: EffectStage.cpp:79
AudioGraph::Buffers mFloatBuffers
Definition: Mix.h:147
std::vector< EffectSettings > mSettings
Definition: Mix.h:158
const std::vector< SampleBuffer > mBuffer
Definition: Mix.h:155
std::vector< std::unique_ptr< EffectStage > > mStages
Definition: Mix.h:160
std::vector< Source > mDecoratedSources
Definition: Mix.h:163
const bool mApplyTrackGains
Definition: Mix.h:133
const sampleFormat mFormat
Definition: Mix.h:135
Inputs mInputs
Definition: Mix.h:122
MixerOptions::TimesAndSpeed TimesAndSpeed
Definition: Mix.h:32
std::vector< std::vector< float > > mTemp
Definition: Mix.h:152
std::pair< bool, sampleFormat > NeedsDither(bool needsDither, double rate) const
Definition: Mix.cpp:190
const unsigned mNumChannels
Definition: Mix.h:121
sampleFormat mEffectiveFormat
Definition: Mix.h:139
const bool mInterleaved
Definition: Mix.h:136
const size_t mBufferSize
Definition: Mix.h:125
bool mNeedsDither
Definition: Mix.h:140
std::vector< AudioGraph::Buffers > mStageBuffers
Definition: Mix.h:159
const bool mHighQuality
Definition: Mix.h:134
std::vector< MixerSource > mSources
Definition: Mix.h:157
size_t BufferSize() const
Definition: Mix.h:72
const std::shared_ptr< TimesAndSpeed > mTimesAndSpeed
Definition: Mix.h:142
unsigned GetNumTracks() const
Definition: MixerOptions.h:50
unsigned GetNumChannels() const
Definition: MixerOptions.h:47
size_t FindBufferSize(const Mixer::Inputs &inputs, size_t bufferSize)
Definition: Mix.cpp:48
static RegisteredToolbarFactory factory

References anonymous_namespace{ExportPCM.cpp}::format, and size.

◆ Mixer() [2/2]

Mixer::Mixer ( const Mixer )
delete

◆ ~Mixer()

Mixer::~Mixer ( )
virtual

Definition at line 185 of file Mix.cpp.

186{
187}

Member Function Documentation

◆ BufferSize()

size_t Mixer::BufferSize ( ) const
inline

Definition at line 72 of file Mix.h.

72{ return mBufferSize; }

Referenced by Process().

Here is the caller graph for this function:

◆ Clear()

void Mixer::Clear ( )
private

Definition at line 248 of file Mix.cpp.

249{
250 for (auto &buffer: mTemp)
251 std::fill(buffer.begin(), buffer.end(), 0);
252}

References mTemp.

Referenced by Process().

Here is the caller graph for this function:

◆ EffectiveFormat()

sampleFormat Mixer::EffectiveFormat ( ) const

Deduce the effective width of the output, which may be narrower than the stored format.

Definition at line 385 of file Mix.cpp.

386{
387 return mEffectiveFormat;
388}

References mEffectiveFormat.

Referenced by MixAndRender().

Here is the caller graph for this function:

◆ GetBuffer() [1/2]

constSamplePtr Mixer::GetBuffer ( )

Retrieve the main buffer or the interleaved buffer.

Definition at line 375 of file Mix.cpp.

376{
377 return mBuffer[0].ptr();
378}

References mBuffer.

Referenced by MixAndRender().

Here is the caller graph for this function:

◆ GetBuffer() [2/2]

constSamplePtr Mixer::GetBuffer ( int  channel)

Retrieve one of the non-interleaved buffers.

Definition at line 380 of file Mix.cpp.

381{
382 return mBuffer[channel].ptr();
383}

References mBuffer.

◆ MixGetCurrentTime()

double Mixer::MixGetCurrentTime ( )

Current time in seconds (unwarped, i.e. always between startTime and stopTime)

This value is not accurate, it's useful for progress bars and indicators, but nothing else.

Definition at line 390 of file Mix.cpp.

391{
392 return mTimesAndSpeed->mTime;
393}

References mTimesAndSpeed.

Referenced by anonymous_namespace{ExportPluginHelpers.cpp}::EvalExportProgress(), and MixAndRender().

Here is the caller graph for this function:

◆ NeedsDither()

std::pair< bool, sampleFormat > Mixer::NeedsDither ( bool  needsDither,
double  rate 
) const
private

TODO: more-than-two-channels

Definition at line 190 of file Mix.cpp.

191{
192 // This will accumulate the widest effective format of any input
193 // clip
194 auto widestEffectiveFormat = narrowestSampleFormat;
195
196 // needsDither may already be given as true.
197 // There are many other possible disqualifiers for the avoidance of dither.
198 if (std::any_of(mSources.begin(), mSources.end(),
199 std::mem_fn(&MixerSource::VariableRates))
200 )
201 // We will call MixVariableRates(), so we need nontrivial resampling
202 needsDither = true;
203
204 for (const auto &input : mInputs) {
205 auto &pSequence = input.pSequence;
206 if (!pSequence)
207 continue;
208 auto &sequence = *pSequence;
209 if (sequence.GetRate() != rate)
210 // Also leads to MixVariableRates(), needs nontrivial resampling
211 needsDither = true;
212 if (mApplyTrackGains) {
214 for (auto c : {0, 1}) {
215 const auto gain = sequence.GetChannelGain(c);
216 if (!(gain == 0.0 || gain == 1.0))
217 // Fractional gain may be applied even in MixSameRate
218 needsDither = true;
219 }
220 }
221
222 // Examine all tracks. (This ignores the time bounds for the mixer.
223 // If it did not, we might avoid dither in more cases. But if we fix
224 // that, remember that some mixers change their time bounds after
225 // construction, as when scrubbing.)
226 if (!sequence.HasTrivialEnvelope())
227 // Varying or non-unit gain may be applied even in MixSameRate
228 needsDither = true;
229 auto effectiveFormat = sequence.WidestEffectiveFormat();
230 if (effectiveFormat > mFormat)
231 // Real, not just nominal, precision loss would happen in at
232 // least one clip
233 needsDither = true;
234 widestEffectiveFormat =
235 std::max(widestEffectiveFormat, effectiveFormat);
236 }
237
238 if (needsDither)
239 // Results will be dithered to width mFormat
240 return { true, mFormat };
241 else {
242 // Results will not be dithered
243 assert(widestEffectiveFormat <= mFormat);
244 return { false, widestEffectiveFormat };
245 }
246}
@ narrowestSampleFormat
Two synonyms for previous values that might change if more values were added.
bool VariableRates() const
Definition: MixerSource.h:65

References mApplyTrackGains, mFormat, mInputs, mSources, narrowestSampleFormat, and MixerSource::VariableRates().

Here is the call graph for this function:

◆ operator=()

Mixer & Mixer::operator= ( const Mixer )
delete

◆ Process() [1/2]

size_t Mixer::Process ( )
inline
Postcondition
result: result <= BufferSize()

Definition at line 91 of file Mix.h.

91{ return Process(BufferSize()); }
size_t Process()
Definition: Mix.h:91

References BufferSize, and Process().

Referenced by Process().

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

◆ Process() [2/2]

size_t Mixer::Process ( size_t  maxSamples)

Process a maximum of 'maxSamples' samples and put them into the buffer, at GetBuffer().

Precondition
maxSamples <= BufferSize()
Postcondition
result: result <= maxSamples
Returns
number of output samples, or 0, if there are no more samples that must be processed.

Definition at line 271 of file Mix.cpp.

272{
273 assert(maxToProcess <= BufferSize());
274
275 // MB: this is wrong! mT represented warped time, and mTime is too inaccurate to use
276 // it here. It's also unnecessary I think.
277 //if (mT >= mT1)
278 // return 0;
279
280 size_t maxOut = 0;
281 const auto channelFlags = stackAllocate(unsigned char, mNumChannels);
282 const auto gains = stackAllocate(float, mNumChannels);
283 if (!mApplyTrackGains)
284 std::fill(gains, gains + mNumChannels, 1.0f);
285
286 // Decides which output buffers an input channel accumulates into
287 auto findChannelFlags = [&channelFlags, numChannels = mNumChannels]
288 (const bool *map, const WideSampleSequence &sequence, size_t iChannel){
289 const auto end = channelFlags + numChannels;
290 std::fill(channelFlags, end, 0);
291 if (map)
292 // ignore left and right when downmixing is customized
293 std::copy(map, map + numChannels, channelFlags);
294 else if (IsMono(sequence))
295 std::fill(channelFlags, end, 1);
296 else if (iChannel == 0)
297 channelFlags[0] = 1;
298 else if (iChannel == 1) {
299 if (numChannels >= 2)
300 channelFlags[1] = 1;
301 else
302 channelFlags[0] = 1;
303 }
304 return channelFlags;
305 };
306
307 auto &[mT0, mT1, _, mTime] = *mTimesAndSpeed;
308 auto oldTime = mTime;
309 // backwards (as possibly in scrubbing)
310 const auto backwards = (mT0 > mT1);
311
312 Clear();
313 // TODO: more-than-two-channels
314 auto maxChannels = std::max(2u, mFloatBuffers.Channels());
315
316 for (auto &[ upstream, downstream ] : mDecoratedSources) {
317 auto oResult = downstream.Acquire(mFloatBuffers, maxToProcess);
318 // One of MixVariableRates or MixSameRate assigns into mTemp[*][*] which
319 // are the sources for the CopySamples calls, and they copy into
320 // mBuffer[*][*]
321 if (!oResult)
322 return 0;
323 auto result = *oResult;
324 maxOut = std::max(maxOut, result);
325
326 // Insert effect stages here! Passing them all channels of the track
327
328 const auto limit = std::min<size_t>(upstream.Channels(), maxChannels);
329 for (size_t j = 0; j < limit; ++j) {
330 const auto pFloat = (const float *)mFloatBuffers.GetReadPosition(j);
331 auto &sequence = upstream.GetSequence();
332 if (mApplyTrackGains) {
333 for (size_t c = 0; c < mNumChannels; ++c) {
334 if (mNumChannels > 1)
335 gains[c] = sequence.GetChannelGain(c);
336 else
337 gains[c] = sequence.GetChannelGain(j);
338 }
339 }
340 const auto flags =
341 findChannelFlags(upstream.MixerSpec(j), sequence, j);
342 MixBuffers(mNumChannels, flags, gains, *pFloat, mTemp, result);
343 }
344
345 downstream.Release();
346 mFloatBuffers.Advance(result);
348 }
349
350 if (backwards)
351 mTime = std::clamp(mTime, mT1, oldTime);
352 else
353 mTime = std::clamp(mTime, oldTime, mT1);
354
355 const auto dstStride = (mInterleaved ? mNumChannels : 1);
356 auto ditherType = mNeedsDither
359 for (size_t c = 0; c < mNumChannels; ++c)
362 ? mBuffer[0].ptr() + (c * SAMPLE_SIZE(mFormat))
363 : mBuffer[c].ptr()
364 ),
365 mFormat, maxOut, ditherType,
366 1, dstStride);
367
368 // MB: this doesn't take warping into account, replaced with code based on mSamplePos
369 //mT += (maxOut / mRate);
370
371 assert(maxOut <= maxToProcess);
372 return maxOut;
373}
@ none
Definition: Dither.h:20
#define _(s)
Definition: Internat.h:73
static void MixBuffers(unsigned numChannels, const unsigned char *channelFlags, const float *gains, const float &src, std::vector< std::vector< float > > &dests, int len)
Definition: Mix.cpp:254
#define stackAllocate(T, count)
Definition: Mix.cpp:269
DitherType gLowQualityDither
These global variables are assigned at application startup or after change of preferences.
DitherType gHighQualityDither
void CopySamples(constSamplePtr src, sampleFormat srcFormat, samplePtr dst, sampleFormat dstFormat, size_t len, DitherType ditherType, unsigned int srcStride, unsigned int dstStride)
Copy samples from any format to any other format; apply dithering only if narrowing the format.
#define SAMPLE_SIZE(SampleFormat)
Definition: SampleFormat.h:52
const char * constSamplePtr
Definition: SampleFormat.h:58
void Advance(size_t count)
Move the positions.
size_t Rotate()
Shift all data at and after the old position to position 0.
unsigned Channels() const
constSamplePtr GetReadPosition(unsigned iChannel) const
Get accumulated data for one channel.
void Clear()
Definition: Mix.cpp:248
bool IsMono(const Channel &channel)
Whether the channel is mono.
auto end(const Ptr< Type, BaseDeleter > &p)
Enables range-for.
Definition: PackedArray.h:159
void copy(const T *src, T *dst, int32_t n)
Definition: VectorOps.h:40

References _, AudioGraph::Buffers::Advance(), BufferSize(), AudioGraph::Buffers::Channels(), Clear(), staffpad::vo::copy(), CopySamples(), PackedArray::end(), floatSample, AudioGraph::Buffers::GetReadPosition(), gHighQualityDither, gLowQualityDither, anonymous_namespace{StretchingSequenceIntegrationTest.cpp}::iChannel, AudioGraph::IsMono(), mApplyTrackGains, mBuffer, mDecoratedSources, mFloatBuffers, mFormat, mHighQuality, mInterleaved, MixBuffers(), mNeedsDither, mNumChannels, mTemp, mTimesAndSpeed, none, AudioGraph::Buffers::Rotate(), SAMPLE_SIZE, and stackAllocate.

Referenced by MixAndRender().

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

◆ Reposition()

void Mixer::Reposition ( double  t,
bool  bSkipping = false 
)

Reposition processing to absolute time next time Process() is called.

Definition at line 395 of file Mix.cpp.

396{
397 const auto &[mT0, mT1, _, __] = *mTimesAndSpeed;
398 auto &mTime = mTimesAndSpeed->mTime;
399 mTime = t;
400 const bool backwards = (mT1 < mT0);
401 if (backwards)
402 mTime = std::clamp(mTime, mT1, mT0);
403 else
404 mTime = std::clamp(mTime, mT0, mT1);
405
406 for (auto &source : mSources)
407 source.Reposition(mTime, bSkipping);
408}

References _, mSources, and mTimesAndSpeed.

Referenced by SetSpeedForKeyboardScrubbing(), and SetTimesAndSpeed().

Here is the caller graph for this function:

◆ SetSpeedForKeyboardScrubbing()

void Mixer::SetSpeedForKeyboardScrubbing ( double  speed,
double  startTime 
)

Definition at line 420 of file Mix.cpp.

421{
422 wxASSERT(std::isfinite(speed));
423 auto &[mT0, mT1, mSpeed, _] = *mTimesAndSpeed;
424
425 // Check if the direction has changed
426 if ((speed > 0.0 && mT1 < mT0) || (speed < 0.0 && mT1 > mT0)) {
427 // It's safe to use 0 and std::numeric_limits<double>::max(),
428 // because Mixer::MixVariableRates() doesn't sample past the start
429 // or end of the audio in a track.
430 if (speed > 0.0 && mT1 < mT0) {
431 mT0 = 0;
432 mT1 = std::numeric_limits<double>::max();
433 }
434 else {
435 mT0 = std::numeric_limits<double>::max();
436 mT1 = 0;
437 }
438
439 Reposition(startTime, true);
440 }
441
442 mSpeed = fabs(speed);
443}
void Reposition(double t, bool bSkipping=false)
Reposition processing to absolute time next time Process() is called.
Definition: Mix.cpp:395

References _, mTimesAndSpeed, and Reposition().

Here is the call graph for this function:

◆ SetTimesAndSpeed()

void Mixer::SetTimesAndSpeed ( double  t0,
double  t1,
double  speed,
bool  bSkipping = false 
)

Used in scrubbing and other nonuniform playback policies.

Definition at line 410 of file Mix.cpp.

411{
412 wxASSERT(std::isfinite(speed));
413 auto &[mT0, mT1, mSpeed, _] = *mTimesAndSpeed;
414 mT0 = t0;
415 mT1 = t1;
416 mSpeed = fabs(speed);
417 Reposition(t0, bSkipping);
418}

References _, mTimesAndSpeed, and Reposition().

Here is the call graph for this function:

Member Data Documentation

◆ mApplyTrackGains

const bool Mixer::mApplyTrackGains
private

Definition at line 133 of file Mix.h.

Referenced by NeedsDither(), and Process().

◆ mBuffer

const std::vector<SampleBuffer> Mixer::mBuffer
private

Definition at line 155 of file Mix.h.

Referenced by GetBuffer(), and Process().

◆ mBufferSize

const size_t Mixer::mBufferSize
private

Definition at line 125 of file Mix.h.

◆ mDecoratedSources

std::vector<Source> Mixer::mDecoratedSources
private

Definition at line 163 of file Mix.h.

Referenced by Process().

◆ mEffectiveFormat

sampleFormat Mixer::mEffectiveFormat
private

Definition at line 139 of file Mix.h.

Referenced by EffectiveFormat().

◆ mFloatBuffers

AudioGraph::Buffers Mixer::mFloatBuffers
private

Definition at line 147 of file Mix.h.

Referenced by Process().

◆ mFormat

const sampleFormat Mixer::mFormat
private

Definition at line 135 of file Mix.h.

Referenced by NeedsDither(), and Process().

◆ mHighQuality

const bool Mixer::mHighQuality
private

Definition at line 134 of file Mix.h.

Referenced by Process().

◆ mInputs

Inputs Mixer::mInputs
private

Definition at line 122 of file Mix.h.

Referenced by NeedsDither().

◆ mInterleaved

const bool Mixer::mInterleaved
private

Definition at line 136 of file Mix.h.

Referenced by Process().

◆ mNeedsDither

bool Mixer::mNeedsDither
private

Definition at line 140 of file Mix.h.

Referenced by Process().

◆ mNumChannels

const unsigned Mixer::mNumChannels
private

Definition at line 121 of file Mix.h.

Referenced by Process().

◆ mSettings

std::vector<EffectSettings> Mixer::mSettings
private

Definition at line 158 of file Mix.h.

◆ mSources

std::vector<MixerSource> Mixer::mSources
private

Definition at line 157 of file Mix.h.

Referenced by NeedsDither(), and Reposition().

◆ mStageBuffers

std::vector<AudioGraph::Buffers> Mixer::mStageBuffers
private

Definition at line 159 of file Mix.h.

◆ mStages

std::vector<std::unique_ptr<EffectStage> > Mixer::mStages
private

Definition at line 160 of file Mix.h.

◆ mTemp

std::vector<std::vector<float> > Mixer::mTemp
private

Definition at line 152 of file Mix.h.

Referenced by Clear(), and Process().

◆ mTimesAndSpeed

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

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