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

enum class  ApplyGain { Discard , MapChannels , Mixdown }
 
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, ApplyGain applyGain=ApplyGain::MapChannels)
 
 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 ApplyGain mApplyGain
 
const bool mHighQuality
 
const sampleFormat mFormat
 
const bool mInterleaved
 
sampleFormat mEffectiveFormat
 
bool mNeedsDither
 
bool mHasMixerSpec {false}
 
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.

Member Enumeration Documentation

◆ ApplyGain

enum class Mixer::ApplyGain
strong
Enumerator
Discard 
MapChannels 
Mixdown 

Definition at line 47 of file Mix.h.

48 {
49 Discard,//< No source gain is applied
50 MapChannels, //< Apply gains per source's channel
51 Mixdown, //< Average gains from all channels in the source, numOutChannels should be 1
52 };

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,
ApplyGain  applyGain = ApplyGain::MapChannels 
)
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 , mApplyGain{ applyGain }
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 mHasMixerSpec = pMixerSpec != nullptr;
129
130 // Reserve vectors first so we can take safe references to pushed elements
131 mSources.reserve(nChannelsIn);
132 const auto nStages = std::accumulate(mInputs.begin(), mInputs.end(), 0,
133 [](auto sum, const auto &input){
134 return sum + input.stages.size() * input.pSequence->NChannels(); });
135 mSettings.reserve(nStages);
136 mStageBuffers.reserve(nStages);
137
138 size_t i = 0;
139 for (auto &input : mInputs) {
140 const auto &sequence = input.pSequence;
141 if (!sequence) {
142 assert(false);
143 break;
144 }
145 auto increment = finally([&]{ i += sequence->NChannels(); });
146
147 auto &source = mSources.emplace_back(sequence, BufferSize(), outRate,
148 warpOptions, highQuality, mayThrow, mTimesAndSpeed,
149 (pMixerSpec ? &pMixerSpec->mMap[i] : nullptr));
150 AudioGraph::Source *pDownstream = &source;
151 for (const auto &stage : input.stages) {
152 // Make a mutable copy of stage.settings
153 auto &settings = mSettings.emplace_back(stage.settings);
154 // TODO: more-than-two-channels
155 // Like mFloatBuffers but padding not needed for soxr
156 // Allocate one extra buffer to hold dummy zero inputs
157 // (Issue 3854)
158 auto &stageInput = mStageBuffers.emplace_back(3, mBufferSize, 1);
159 const auto &factory = [&stage]{
160 // Avoid unnecessary repeated calls to the factory
161 return stage.mpFirstInstance
162 ? move(stage.mpFirstInstance)
163 : stage.factory();
164 };
165 auto &pNewDownstream =
166 mStages.emplace_back(EffectStage::Create(-1,
167 *pDownstream, stageInput,
168 factory, settings, outRate, std::nullopt, *sequence
169 ));
170 if (pNewDownstream)
171 pDownstream = pNewDownstream.get();
172 else {
173 // Just omit the failed stage from rendering
174 // TODO propagate the error?
175 mStageBuffers.pop_back();
176 mSettings.pop_back();
177 }
178 }
179 mDecoratedSources.emplace_back(Source{ source, *pDownstream });
180 }
181
182 // Decide once at construction time
183 std::tie(mNeedsDither, mEffectiveFormat) = NeedsDither(needsDither, outRate);
184}
static RegisteredToolbarFactory factory
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:155
const ApplyGain mApplyGain
Definition: Mix.h:140
std::vector< EffectSettings > mSettings
Definition: Mix.h:166
const std::vector< SampleBuffer > mBuffer
Definition: Mix.h:163
std::vector< std::unique_ptr< EffectStage > > mStages
Definition: Mix.h:168
std::vector< Source > mDecoratedSources
Definition: Mix.h:171
const sampleFormat mFormat
Definition: Mix.h:142
Inputs mInputs
Definition: Mix.h:129
MixerOptions::TimesAndSpeed TimesAndSpeed
Definition: Mix.h:32
std::vector< std::vector< float > > mTemp
Definition: Mix.h:160
std::pair< bool, sampleFormat > NeedsDither(bool needsDither, double rate) const
Definition: Mix.cpp:189
const unsigned mNumChannels
Definition: Mix.h:128
sampleFormat mEffectiveFormat
Definition: Mix.h:146
const bool mInterleaved
Definition: Mix.h:143
const size_t mBufferSize
Definition: Mix.h:132
bool mNeedsDither
Definition: Mix.h:147
std::vector< AudioGraph::Buffers > mStageBuffers
Definition: Mix.h:167
const bool mHighQuality
Definition: Mix.h:141
std::vector< MixerSource > mSources
Definition: Mix.h:165
size_t BufferSize() const
Definition: Mix.h:79
const std::shared_ptr< TimesAndSpeed > mTimesAndSpeed
Definition: Mix.h:150
bool mHasMixerSpec
Definition: Mix.h:148
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

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

◆ Mixer() [2/2]

Mixer::Mixer ( const Mixer )
delete

◆ ~Mixer()

Mixer::~Mixer ( )
virtualdefault

Member Function Documentation

◆ BufferSize()

size_t Mixer::BufferSize ( ) const
inline

Definition at line 79 of file Mix.h.

79{ return mBufferSize; }

Referenced by Process().

Here is the caller graph for this function:

◆ Clear()

void Mixer::Clear ( )
private

Definition at line 250 of file Mix.cpp.

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

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 388 of file Mix.cpp.

389{
390 return mEffectiveFormat;
391}

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 378 of file Mix.cpp.

379{
380 return mBuffer[0].ptr();
381}

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 383 of file Mix.cpp.

384{
385 return mBuffer[channel].ptr();
386}

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 393 of file Mix.cpp.

394{
395 return mTimesAndSpeed->mTime;
396}

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 189 of file Mix.cpp.

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

References Discard, mApplyGain, mFormat, mHasMixerSpec, Mixdown, mNumChannels, 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 98 of file Mix.h.

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

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);
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();
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 }
340 gains[0] /= static_cast<float>(limit);
341 }
342
343 const auto flags =
344 findChannelFlags(upstream.MixerSpec(j), sequence, j);
345 MixBuffers(mNumChannels, flags, gains, *pFloat, mTemp, result);
346 }
347
348 downstream.Release();
349 mFloatBuffers.Advance(result);
351 }
352
353 if (backwards)
354 mTime = std::clamp(mTime, mT1, oldTime);
355 else
356 mTime = std::clamp(mTime, oldTime, mT1);
357
358 const auto dstStride = (mInterleaved ? mNumChannels : 1);
359 auto ditherType = mNeedsDither
362 for (size_t c = 0; c < mNumChannels; ++c)
365 ? mBuffer[0].ptr() + (c * SAMPLE_SIZE(mFormat))
366 : mBuffer[c].ptr()
367 ),
368 mFormat, maxOut, ditherType,
369 1, dstStride);
370
371 // MB: this doesn't take warping into account, replaced with code based on mSamplePos
372 //mT += (maxOut / mRate);
373
374 assert(maxOut <= maxToProcess);
375 return maxOut;
376}
@ 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:256
#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:250
bool IsMono(const Channel &channel)
Whether the channel is mono.
const char * end(const char *str) noexcept
Definition: StringUtils.h:106
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(), Discard, details::end(), floatSample, AudioGraph::Buffers::GetReadPosition(), gHighQualityDither, gLowQualityDither, anonymous_namespace{StretchingSequenceIntegrationTest.cpp}::iChannel, AudioGraph::IsMono(), mApplyGain, mBuffer, mDecoratedSources, mFloatBuffers, mFormat, mHasMixerSpec, mHighQuality, mInterleaved, MixBuffers(), Mixdown, 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 398 of file Mix.cpp.

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

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 423 of file Mix.cpp.

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

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 413 of file Mix.cpp.

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

References _, mTimesAndSpeed, and Reposition().

Here is the call graph for this function:

Member Data Documentation

◆ mApplyGain

const ApplyGain Mixer::mApplyGain
private

Definition at line 140 of file Mix.h.

Referenced by NeedsDither(), and Process().

◆ mBuffer

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

Definition at line 163 of file Mix.h.

Referenced by GetBuffer(), and Process().

◆ mBufferSize

const size_t Mixer::mBufferSize
private

Definition at line 132 of file Mix.h.

◆ mDecoratedSources

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

Definition at line 171 of file Mix.h.

Referenced by Process().

◆ mEffectiveFormat

sampleFormat Mixer::mEffectiveFormat
private

Definition at line 146 of file Mix.h.

Referenced by EffectiveFormat().

◆ mFloatBuffers

AudioGraph::Buffers Mixer::mFloatBuffers
private

Definition at line 155 of file Mix.h.

Referenced by Process().

◆ mFormat

const sampleFormat Mixer::mFormat
private

Definition at line 142 of file Mix.h.

Referenced by NeedsDither(), and Process().

◆ mHasMixerSpec

bool Mixer::mHasMixerSpec {false}
private

Definition at line 148 of file Mix.h.

Referenced by NeedsDither(), and Process().

◆ mHighQuality

const bool Mixer::mHighQuality
private

Definition at line 141 of file Mix.h.

Referenced by Process().

◆ mInputs

Inputs Mixer::mInputs
private

Definition at line 129 of file Mix.h.

◆ mInterleaved

const bool Mixer::mInterleaved
private

Definition at line 143 of file Mix.h.

Referenced by Process().

◆ mNeedsDither

bool Mixer::mNeedsDither
private

Definition at line 147 of file Mix.h.

Referenced by Process().

◆ mNumChannels

const unsigned Mixer::mNumChannels
private

Definition at line 128 of file Mix.h.

Referenced by NeedsDither(), and Process().

◆ mSettings

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

Definition at line 166 of file Mix.h.

◆ mSources

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

Definition at line 165 of file Mix.h.

Referenced by NeedsDither(), and Reposition().

◆ mStageBuffers

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

Definition at line 167 of file Mix.h.

◆ mStages

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

Definition at line 168 of file Mix.h.

◆ mTemp

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

Definition at line 160 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: