Audacity  3.0.3
Classes | 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

class  WarpOptions
 

Public Member Functions

 Mixer (const WaveTrackConstArray &inputTracks, 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)
 
virtual ~ Mixer ()
 
size_t Process (size_t maxSamples)
 
void Restart ()
 
void Reposition (double t, bool bSkipping=false)
 
void SetTimesAndSpeed (double t0, double t1, double speed)
 
void SetSpeedForPlayAtSpeed (double speed)
 
void SetSpeedForKeyboardScrubbing (double speed, double startTime)
 
double MixGetCurrentTime ()
 
samplePtr GetBuffer ()
 Retrieve the main buffer or the interleaved buffer. More...
 
samplePtr GetBuffer (int channel)
 Retrieve one of the non-interleaved buffers. More...
 

Private Member Functions

void Clear ()
 
size_t MixSameRate (int *channelFlags, WaveTrackCache &cache, sampleCount *pos)
 
size_t MixVariableRates (int *channelFlags, WaveTrackCache &cache, sampleCount *pos, float *queue, int *queueStart, int *queueLen, Resample *pResample)
 
void MakeResamplers ()
 

Private Attributes

const size_t mNumInputTracks
 
ArrayOf< WaveTrackCachemInputTrack
 
bool mbVariableRates
 
const BoundedEnvelopemEnvelope
 
ArrayOf< sampleCountmSamplePos
 
const bool mApplyTrackGains
 
Doubles mEnvValues
 
double mT0
 
double mT1
 
double mTime
 
ArrayOf< std::unique_ptr< Resample > > mResample
 
const size_t mQueueMaxLen
 
FloatBuffers mSampleQueue
 
ArrayOf< int > mQueueStart
 
ArrayOf< int > mQueueLen
 
size_t mProcessLen
 
MixerSpecmMixerSpec
 
size_t mMaxOut
 
const unsigned mNumChannels
 
Floats mGains
 
unsigned mNumBuffers
 
size_t mBufferSize
 
size_t mInterleavedBufferSize
 
const sampleFormat mFormat
 
bool mInterleaved
 
ArrayOf< SampleBuffermBuffer
 
ArrayOf< SampleBuffermTemp
 
Floats mFloatBuffer
 
const double mRate
 
double mSpeed
 
bool mHighQuality
 
std::vector< double > mMinFactor
 
std::vector< double > mMaxFactor
 
const bool mMayThrow
 

Detailed Description

Functions for doing the mixdown of the tracks.

Definition at line 78 of file Mix.h.

Constructor & Destructor Documentation

◆ Mixer()

Mixer::Mixer ( const WaveTrackConstArray inputTracks,
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 
)

Definition at line 238 of file Mix.cpp.

245  : mNumInputTracks { inputTracks.size() }
246 
247  , mApplyTrackGains{ applyTrackGains }
248 
249  // This is the number of samples grabbed in one go from a track
250  // and placed in a queue, when mixing with resampling.
251  // (Should we use WaveTrack::GetBestBlockSize instead?)
252  , mQueueMaxLen{ 65536 }
254 
255  , mNumChannels{ numOutChannels }
256  , mGains{ mNumChannels }
257 
258  , mFormat{ outFormat }
259  , mRate{ outRate }
260 
261  , mMayThrow{ mayThrow }
262 {
263  mHighQuality = highQuality;
265 
266  // mSamplePos holds for each track the next sample position not
267  // yet processed.
269  for(size_t i=0; i<mNumInputTracks; i++) {
270  mInputTrack[i].SetTrack(inputTracks[i]);
271  mSamplePos[i] = inputTracks[i]->TimeToLongSamples(startTime);
272  }
273  mEnvelope = warpOptions.envelope;
274  mT0 = startTime;
275  mT1 = stopTime;
276  mTime = startTime;
277  mBufferSize = outBufferSize;
278  mInterleaved = outInterleaved;
279  mSpeed = 1.0;
280  if( mixerSpec && mixerSpec->GetNumChannels() == mNumChannels &&
281  mixerSpec->GetNumTracks() == mNumInputTracks )
282  mMixerSpec = mixerSpec;
283  else
284  mMixerSpec = NULL;
285 
286  if (mInterleaved) {
287  mNumBuffers = 1;
289  }
290  else {
293  }
294 
297  for (unsigned int c = 0; c < mNumBuffers; c++) {
298  mBuffer[c].Allocate(mInterleavedBufferSize, mFormat);
300  }
301  // PRL: Bug2536: see other comments below
303 
304  // But cut the queue into blocks of this finer size
305  // for variable rate resampling. Each block is resampled at some
306  // constant rate.
307  mProcessLen = 1024;
308 
309  // Position in each queue of the start of the next block to resample.
311 
312  // For each queue, the number of available samples after the queue start.
315  mMinFactor.resize(mNumInputTracks);
316  mMaxFactor.resize(mNumInputTracks);
317  for (size_t i = 0; i<mNumInputTracks; i++) {
318  double factor = (mRate / mInputTrack[i].GetTrack()->GetRate());
319  if (mEnvelope) {
320  // variable rate resampling
321  mbVariableRates = true;
322  mMinFactor[i] = factor / mEnvelope->GetRangeUpper();
323  mMaxFactor[i] = factor / mEnvelope->GetRangeLower();
324  }
325  else if (warpOptions.minSpeed > 0.0 && warpOptions.maxSpeed > 0.0) {
326  // variable rate resampling
327  mbVariableRates = true;
328  mMinFactor[i] = factor / warpOptions.maxSpeed;
329  mMaxFactor[i] = factor / warpOptions.minSpeed;
330  }
331  else {
332  // constant rate resampling
333  mbVariableRates = false;
334  mMinFactor[i] = mMaxFactor[i] = factor;
335  }
336 
337  mQueueStart[i] = 0;
338  mQueueLen[i] = 0;
339  }
340 
341  MakeResamplers();
342 
343  const auto envLen = std::max(mQueueMaxLen, mInterleavedBufferSize);
344  mEnvValues.reinit(envLen);
345 }

◆ ~ Mixer()

virtual Mixer::~ Mixer ( )
virtual

Member Function Documentation

◆ Clear()

void Mixer::Clear ( )
private

Definition at line 357 of file Mix.cpp.

358 {
359  for (unsigned int c = 0; c < mNumBuffers; c++) {
360  memset(mTemp[c].ptr(), 0, mInterleavedBufferSize * SAMPLE_SIZE(floatSample));
361  }
362 }

References floatSample, mInterleavedBufferSize, mNumBuffers, mTemp, and SAMPLE_SIZE.

Referenced by Process().

Here is the caller graph for this function:

◆ GetBuffer() [1/2]

samplePtr Mixer::GetBuffer ( )

Retrieve the main buffer or the interleaved buffer.

Definition at line 716 of file Mix.cpp.

717 {
718  return mBuffer[0].ptr();
719 }

References mBuffer.

◆ GetBuffer() [2/2]

samplePtr Mixer::GetBuffer ( int  channel)

Retrieve one of the non-interleaved buffers.

Definition at line 721 of file Mix.cpp.

722 {
723  return mBuffer[channel].ptr();
724 }

References mBuffer.

◆ MakeResamplers()

void Mixer::MakeResamplers ( )
private

Definition at line 351 of file Mix.cpp.

352 {
353  for (size_t i = 0; i < mNumInputTracks; i++)
354  mResample[i] = std::make_unique<Resample>(mHighQuality, mMinFactor[i], mMaxFactor[i]);
355 }

References mHighQuality, mMaxFactor, mMinFactor, mNumInputTracks, and mResample.

Referenced by Reposition(), and Restart().

Here is the caller graph for this function:

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

727 {
728  return mTime;
729 }

References mTime.

◆ MixSameRate()

size_t Mixer::MixSameRate ( int *  channelFlags,
WaveTrackCache cache,
sampleCount pos 
)
private

Definition at line 568 of file Mix.cpp.

570 {
571  const WaveTrack *const track = cache.GetTrack().get();
572  const double t = ( *pos ).as_double() / track->GetRate();
573  const double trackEndTime = track->GetEndTime();
574  const double trackStartTime = track->GetStartTime();
575  const bool backwards = (mT1 < mT0);
576  const double tEnd = backwards
577  ? std::max(trackStartTime, mT1)
578  : std::min(trackEndTime, mT1);
579 
580  //don't process if we're at the end of the selection or track.
581  if ((backwards ? t <= tEnd : t >= tEnd))
582  return 0;
583  //if we're about to approach the end of the track or selection, figure out how much we need to grab
584  auto slen = limitSampleBufferSize(
585  mMaxOut,
586  // PRL: maybe t and tEnd should be given as sampleCount instead to
587  // avoid trouble subtracting one large value from another for a small
588  // difference
589  sampleCount{ (backwards ? t - tEnd : tEnd - t) * track->GetRate() + 0.5 }
590  );
591 
592  if (backwards) {
593  auto results = cache.GetFloats(*pos - (slen - 1), slen, mMayThrow);
594  if (results)
595  memcpy(mFloatBuffer.get(), results, sizeof(float) * slen);
596  else
597  memset(mFloatBuffer.get(), 0, sizeof(float) * slen);
598  track->GetEnvelopeValues(mEnvValues.get(), slen, t - (slen - 1) / mRate);
599  for(decltype(slen) i = 0; i < slen; i++)
600  mFloatBuffer[i] *= mEnvValues[i]; // Track gain control will go here?
602 
603  *pos -= slen;
604  }
605  else {
606  auto results = cache.GetFloats(*pos, slen, mMayThrow);
607  if (results)
608  memcpy(mFloatBuffer.get(), results, sizeof(float) * slen);
609  else
610  memset(mFloatBuffer.get(), 0, sizeof(float) * slen);
611  track->GetEnvelopeValues(mEnvValues.get(), slen, t);
612  for(decltype(slen) i = 0; i < slen; i++)
613  mFloatBuffer[i] *= mEnvValues[i]; // Track gain control will go here?
614 
615  *pos += slen;
616  }
617 
618  for(size_t c=0; c<mNumChannels; c++)
619  if (mApplyTrackGains)
620  mGains[c] = track->GetChannelGain(c);
621  else
622  mGains[c] = 1.0;
623 
624  MixBuffers(mNumChannels, channelFlags, mGains.get(),
625  (samplePtr)mFloatBuffer.get(), mTemp.get(), slen, mInterleaved);
626 
627  return slen;
628 }

References floatSample, WaveTrack::GetChannelGain(), WaveTrack::GetEndTime(), WaveTrack::GetEnvelopeValues(), WaveTrackCache::GetFloats(), WaveTrack::GetRate(), WaveTrack::GetStartTime(), WaveTrackCache::GetTrack(), limitSampleBufferSize(), mApplyTrackGains, mEnvValues, mFloatBuffer, mGains, min(), mInterleaved, MixBuffers(), mMaxOut, mMayThrow, mNumChannels, mRate, mT0, mT1, mTemp, and ReverseSamples().

Referenced by Process().

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

◆ MixVariableRates()

size_t Mixer::MixVariableRates ( int *  channelFlags,
WaveTrackCache cache,
sampleCount pos,
float *  queue,
int *  queueStart,
int *  queueLen,
Resample pResample 
)
private

Definition at line 413 of file Mix.cpp.

417 {
418  const WaveTrack *const track = cache.GetTrack().get();
419  const double trackRate = track->GetRate();
420  const double initialWarp = mRate / mSpeed / trackRate;
421  const double tstep = 1.0 / trackRate;
422  auto sampleSize = SAMPLE_SIZE(floatSample);
423 
424  decltype(mMaxOut) out = 0;
425 
426  /* time is floating point. Sample rate is integer. The number of samples
427  * has to be integer, but the multiplication gives a float result, which we
428  * round to get an integer result. TODO: is this always right or can it be
429  * off by one sometimes? Can we not get this information directly from the
430  * clip (which must know) rather than convert the time?
431  *
432  * LLL: Not at this time. While WaveClips provide methods to retrieve the
433  * start and end sample, they do the same float->sampleCount conversion
434  * to calculate the position.
435  */
436 
437  // Find the last sample
438  double endTime = track->GetEndTime();
439  double startTime = track->GetStartTime();
440  const bool backwards = (mT1 < mT0);
441  const double tEnd = backwards
442  ? std::max(startTime, mT1)
443  : std::min(endTime, mT1);
444  const auto endPos = track->TimeToLongSamples(tEnd);
445  // Find the time corresponding to the start of the queue, for use with time track
446  double t = ((*pos).as_long_long() +
447  (backwards ? *queueLen : - *queueLen)) / trackRate;
448 
449  while (out < mMaxOut) {
450  if (*queueLen < (int)mProcessLen) {
451  // Shift pending portion to start of the buffer
452  memmove(queue, &queue[*queueStart], (*queueLen) * sampleSize);
453  *queueStart = 0;
454 
455  auto getLen = limitSampleBufferSize(
456  mQueueMaxLen - *queueLen,
457  backwards ? *pos - endPos : endPos - *pos
458  );
459 
460  // Nothing to do if past end of play interval
461  if (getLen > 0) {
462  if (backwards) {
463  auto results =
464  cache.GetFloats(*pos - (getLen - 1), getLen, mMayThrow);
465  if (results)
466  memcpy(&queue[*queueLen], results, sizeof(float) * getLen);
467  else
468  memset(&queue[*queueLen], 0, sizeof(float) * getLen);
469 
470  track->GetEnvelopeValues(mEnvValues.get(),
471  getLen,
472  (*pos - (getLen- 1)).as_double() / trackRate);
473  *pos -= getLen;
474  }
475  else {
476  auto results = cache.GetFloats(*pos, getLen, mMayThrow);
477  if (results)
478  memcpy(&queue[*queueLen], results, sizeof(float) * getLen);
479  else
480  memset(&queue[*queueLen], 0, sizeof(float) * getLen);
481 
482  track->GetEnvelopeValues(mEnvValues.get(),
483  getLen,
484  (*pos).as_double() / trackRate);
485 
486  *pos += getLen;
487  }
488 
489  for (decltype(getLen) i = 0; i < getLen; i++) {
490  queue[(*queueLen) + i] *= mEnvValues[i];
491  }
492 
493  if (backwards)
495  *queueLen, getLen);
496 
497  *queueLen += getLen;
498  }
499  }
500 
501  auto thisProcessLen = mProcessLen;
502  bool last = (*queueLen < (int)mProcessLen);
503  if (last) {
504  thisProcessLen = *queueLen;
505  }
506 
507  double factor = initialWarp;
508  if (mEnvelope)
509  {
510  //TODO-MB: The end time is wrong when the resampler doesn't use all input samples,
511  // as a result of this the warp factor may be slightly wrong, so AudioIO will stop too soon
512  // or too late (resulting in missing sound or inserted silence). This can't be fixed
513  // without changing the way the resampler works, because the number of input samples that will be used
514  // is unpredictable. Maybe it can be compensated later though.
515  if (backwards)
516  factor *= ComputeWarpFactor( *mEnvelope,
517  t - (double)thisProcessLen / trackRate + tstep, t + tstep);
518  else
519  factor *= ComputeWarpFactor( *mEnvelope,
520  t, t + (double)thisProcessLen / trackRate);
521  }
522 
523  auto results = pResample->Process(factor,
524  &queue[*queueStart],
525  thisProcessLen,
526  last,
527  // PRL: Bug2536: crash in soxr happened on Mac, sometimes, when
528  // mMaxOut - out == 1 and &mFloatBuffer[out + 1] was an unmapped
529  // address, because soxr, strangely, fetched an 8-byte (misaligned!)
530  // value from &mFloatBuffer[out], but did nothing with it anyway,
531  // in soxr_output_no_callback.
532  // Now we make the bug go away by allocating a little more space in
533  // the buffer than we need.
534  &mFloatBuffer[out],
535  mMaxOut - out);
536 
537  const auto input_used = results.first;
538  *queueStart += input_used;
539  *queueLen -= input_used;
540  out += results.second;
541  t += (input_used / trackRate) * (backwards ? -1 : 1);
542 
543  if (last) {
544  break;
545  }
546  }
547 
548  for (size_t c = 0; c < mNumChannels; c++) {
549  if (mApplyTrackGains) {
550  mGains[c] = track->GetChannelGain(c);
551  }
552  else {
553  mGains[c] = 1.0;
554  }
555  }
556 
558  channelFlags,
559  mGains.get(),
560  (samplePtr)mFloatBuffer.get(),
561  mTemp.get(),
562  out,
563  mInterleaved);
564 
565  return out;
566 }

References anonymous_namespace{Mix.cpp}::ComputeWarpFactor(), floatSample, WaveTrack::GetChannelGain(), WaveTrack::GetEndTime(), WaveTrack::GetEnvelopeValues(), WaveTrackCache::GetFloats(), WaveTrack::GetRate(), WaveTrack::GetStartTime(), WaveTrackCache::GetTrack(), limitSampleBufferSize(), mApplyTrackGains, mEnvelope, mEnvValues, mFloatBuffer, mGains, min(), mInterleaved, MixBuffers(), mMaxOut, mMayThrow, mNumChannels, mProcessLen, mQueueMaxLen, mRate, mSpeed, mT0, mT1, mTemp, Resample::Process(), ReverseSamples(), SAMPLE_SIZE, and WaveTrack::TimeToLongSamples().

Referenced by Process().

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

◆ Process()

size_t Mixer::Process ( size_t  maxSamples)

Process a maximum of 'maxSamples' samples and put them into a buffer which can be retrieved by calling GetBuffer(). Returns number of output samples, or 0, if there are no more samples that must be processed.

Definition at line 630 of file Mix.cpp.

631 {
632  // MB: this is wrong! mT represented warped time, and mTime is too inaccurate to use
633  // it here. It's also unnecessary I think.
634  //if (mT >= mT1)
635  // return 0;
636 
637  decltype(Process(0)) maxOut = 0;
638  ArrayOf<int> channelFlags{ mNumChannels };
639 
640  mMaxOut = maxToProcess;
641 
642  Clear();
643  for(size_t i=0; i<mNumInputTracks; i++) {
644  const WaveTrack *const track = mInputTrack[i].GetTrack().get();
645  for(size_t j=0; j<mNumChannels; j++)
646  channelFlags[j] = 0;
647 
648  if( mMixerSpec ) {
649  //ignore left and right when downmixing is not required
650  for(size_t j = 0; j < mNumChannels; j++ )
651  channelFlags[ j ] = mMixerSpec->mMap[ i ][ j ] ? 1 : 0;
652  }
653  else {
654  switch(track->GetChannel()) {
655  case Track::MonoChannel:
656  default:
657  for(size_t j=0; j<mNumChannels; j++)
658  channelFlags[j] = 1;
659  break;
660  case Track::LeftChannel:
661  channelFlags[0] = 1;
662  break;
663  case Track::RightChannel:
664  if (mNumChannels >= 2)
665  channelFlags[1] = 1;
666  else
667  channelFlags[0] = 1;
668  break;
669  }
670  }
671  if (mbVariableRates || track->GetRate() != mRate)
672  maxOut = std::max(maxOut,
673  MixVariableRates(channelFlags.get(), mInputTrack[i],
674  &mSamplePos[i], mSampleQueue[i].get(),
675  &mQueueStart[i], &mQueueLen[i], mResample[i].get()));
676  else
677  maxOut = std::max(maxOut,
678  MixSameRate(channelFlags.get(), mInputTrack[i], &mSamplePos[i]));
679 
680  double t = mSamplePos[i].as_double() / (double)track->GetRate();
681  if (mT0 > mT1)
682  // backwards (as possibly in scrubbing)
683  mTime = std::max(std::min(t, mTime), mT1);
684  else
685  // forwards (the usual)
686  mTime = std::min(std::max(t, mTime), mT1);
687  }
688  if(mInterleaved) {
689  for(size_t c=0; c<mNumChannels; c++) {
690  CopySamples(mTemp[0].ptr() + (c * SAMPLE_SIZE(floatSample)),
691  floatSample,
692  mBuffer[0].ptr() + (c * SAMPLE_SIZE(mFormat)),
693  mFormat,
694  maxOut,
696  mNumChannels,
697  mNumChannels);
698  }
699  }
700  else {
701  for(size_t c=0; c<mNumBuffers; c++) {
702  CopySamples(mTemp[c].ptr(),
703  floatSample,
704  mBuffer[c].ptr(),
705  mFormat,
706  maxOut,
708  }
709  }
710  // MB: this doesn't take warping into account, replaced with code based on mSamplePos
711  //mT += (maxOut / mRate);
712 
713  return maxOut;
714 }

References Clear(), CopySamples(), floatSample, WaveTrack::GetChannel(), WaveTrack::GetRate(), gHighQualityDither, gLowQualityDither, Track::LeftChannel, mBuffer, mbVariableRates, mFormat, mHighQuality, min(), mInputTrack, mInterleaved, MixSameRate(), MixVariableRates(), MixerSpec::mMap, mMaxOut, mMixerSpec, mNumBuffers, mNumChannels, mNumInputTracks, Track::MonoChannel, mQueueLen, mQueueStart, mRate, mResample, mSamplePos, mSampleQueue, mT0, mT1, mTemp, mTime, Track::RightChannel, and SAMPLE_SIZE.

Here is the call 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 749 of file Mix.cpp.

750 {
751  mTime = t;
752  const bool backwards = (mT1 < mT0);
753  if (backwards)
754  mTime = std::max(mT1, (std::min(mT0, mTime)));
755  else
756  mTime = std::max(mT0, (std::min(mT1, mTime)));
757 
758  for(size_t i=0; i<mNumInputTracks; i++) {
759  mSamplePos[i] = mInputTrack[i].GetTrack()->TimeToLongSamples(mTime);
760  mQueueStart[i] = 0;
761  mQueueLen[i] = 0;
762  }
763 
764  // Bug 2025: libsoxr 0.1.3, first used in Audacity 2.3.0, crashes with
765  // constant rate resampling if you try to reuse the resampler after it has
766  // flushed. Should that be considered a bug in sox? This works around it.
767  // (See also bug 1887, and the same work around in Mixer::Restart().)
768  if( bSkipping )
769  MakeResamplers();
770 }

References MakeResamplers(), min(), mInputTrack, mNumInputTracks, mQueueLen, mQueueStart, mSamplePos, mT0, mT1, and mTime.

Referenced by SetSpeedForKeyboardScrubbing(), and SetTimesAndSpeed().

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

◆ Restart()

void Mixer::Restart ( )

Restart processing at beginning of buffer next time Process() is called.

Definition at line 731 of file Mix.cpp.

732 {
733  mTime = mT0;
734 
735  for(size_t i=0; i<mNumInputTracks; i++)
736  mSamplePos[i] = mInputTrack[i].GetTrack()->TimeToLongSamples(mT0);
737 
738  for(size_t i=0; i<mNumInputTracks; i++) {
739  mQueueStart[i] = 0;
740  mQueueLen[i] = 0;
741  }
742 
743  // Bug 1887: libsoxr 0.1.3, first used in Audacity 2.3.0, crashes with
744  // constant rate resampling if you try to reuse the resampler after it has
745  // flushed. Should that be considered a bug in sox? This works around it:
746  MakeResamplers();
747 }

References MakeResamplers(), mInputTrack, mNumInputTracks, mQueueLen, mQueueStart, mSamplePos, mT0, and mTime.

Here is the call graph for this function:

◆ SetSpeedForKeyboardScrubbing()

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

Definition at line 787 of file Mix.cpp.

788 {
789  wxASSERT(std::isfinite(speed));
790 
791  // Check if the direction has changed
792  if ((speed > 0.0 && mT1 < mT0) || (speed < 0.0 && mT1 > mT0)) {
793  // It's safe to use 0 and std::numeric_limits<double>::max(),
794  // because Mixer::MixVariableRates() doesn't sample past the start
795  // or end of the audio in a track.
796  if (speed > 0.0 && mT1 < mT0) {
797  mT0 = 0;
798  mT1 = std::numeric_limits<double>::max();
799  }
800  else {
801  mT0 = std::numeric_limits<double>::max();
802  mT1 = 0;
803  }
804 
805  Reposition(startTime, true);
806  }
807 
808  mSpeed = fabs(speed);
809 }

References mSpeed, mT0, mT1, and Reposition().

Here is the call graph for this function:

◆ SetSpeedForPlayAtSpeed()

void Mixer::SetSpeedForPlayAtSpeed ( double  speed)

Definition at line 781 of file Mix.cpp.

782 {
783  wxASSERT(std::isfinite(speed));
784  mSpeed = fabs(speed);
785 }

References mSpeed.

◆ SetTimesAndSpeed()

void Mixer::SetTimesAndSpeed ( double  t0,
double  t1,
double  speed 
)

Definition at line 772 of file Mix.cpp.

773 {
774  wxASSERT(std::isfinite(speed));
775  mT0 = t0;
776  mT1 = t1;
777  mSpeed = fabs(speed);
778  Reposition(t0);
779 }

References mSpeed, mT0, mT1, and Reposition().

Here is the call graph for this function:

Member Data Documentation

◆ mApplyTrackGains

const bool Mixer::mApplyTrackGains
private

Definition at line 168 of file Mix.h.

Referenced by MixSameRate(), and MixVariableRates().

◆ mBuffer

ArrayOf<SampleBuffer> Mixer::mBuffer
private

Definition at line 190 of file Mix.h.

Referenced by GetBuffer(), and Process().

◆ mBufferSize

size_t Mixer::mBufferSize
private

Definition at line 186 of file Mix.h.

◆ mbVariableRates

bool Mixer::mbVariableRates
private

Definition at line 165 of file Mix.h.

Referenced by Process().

◆ mEnvelope

const BoundedEnvelope* Mixer::mEnvelope
private

Definition at line 166 of file Mix.h.

Referenced by MixVariableRates().

◆ mEnvValues

Doubles Mixer::mEnvValues
private

Definition at line 169 of file Mix.h.

Referenced by MixSameRate(), and MixVariableRates().

◆ mFloatBuffer

Floats Mixer::mFloatBuffer
private

Definition at line 191 of file Mix.h.

Referenced by MixSameRate(), and MixVariableRates().

◆ mFormat

const sampleFormat Mixer::mFormat
private

Definition at line 188 of file Mix.h.

Referenced by Process().

◆ mGains

Floats Mixer::mGains
private

Definition at line 184 of file Mix.h.

Referenced by MixSameRate(), and MixVariableRates().

◆ mHighQuality

bool Mixer::mHighQuality
private

Definition at line 194 of file Mix.h.

Referenced by MakeResamplers(), and Process().

◆ mInputTrack

ArrayOf<WaveTrackCache> Mixer::mInputTrack
private

Definition at line 164 of file Mix.h.

Referenced by Process(), Reposition(), and Restart().

◆ mInterleaved

bool Mixer::mInterleaved
private

Definition at line 189 of file Mix.h.

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

◆ mInterleavedBufferSize

size_t Mixer::mInterleavedBufferSize
private

Definition at line 187 of file Mix.h.

Referenced by Clear().

◆ mMaxFactor

std::vector<double> Mixer::mMaxFactor
private

Definition at line 195 of file Mix.h.

Referenced by MakeResamplers().

◆ mMaxOut

size_t Mixer::mMaxOut
private

Definition at line 182 of file Mix.h.

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

◆ mMayThrow

const bool Mixer::mMayThrow
private

Definition at line 197 of file Mix.h.

Referenced by MixSameRate(), and MixVariableRates().

◆ mMinFactor

std::vector<double> Mixer::mMinFactor
private

Definition at line 195 of file Mix.h.

Referenced by MakeResamplers().

◆ mMixerSpec

MixerSpec* Mixer::mMixerSpec
private

Definition at line 179 of file Mix.h.

Referenced by Process().

◆ mNumBuffers

unsigned Mixer::mNumBuffers
private

Definition at line 185 of file Mix.h.

Referenced by Clear(), and Process().

◆ mNumChannels

const unsigned Mixer::mNumChannels
private

Definition at line 183 of file Mix.h.

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

◆ mNumInputTracks

const size_t Mixer::mNumInputTracks
private

Definition at line 163 of file Mix.h.

Referenced by MakeResamplers(), Process(), Reposition(), and Restart().

◆ mProcessLen

size_t Mixer::mProcessLen
private

Definition at line 178 of file Mix.h.

Referenced by MixVariableRates().

◆ mQueueLen

ArrayOf<int> Mixer::mQueueLen
private

Definition at line 177 of file Mix.h.

Referenced by Process(), Reposition(), and Restart().

◆ mQueueMaxLen

const size_t Mixer::mQueueMaxLen
private

Definition at line 174 of file Mix.h.

Referenced by MixVariableRates().

◆ mQueueStart

ArrayOf<int> Mixer::mQueueStart
private

Definition at line 176 of file Mix.h.

Referenced by Process(), Reposition(), and Restart().

◆ mRate

const double Mixer::mRate
private

Definition at line 192 of file Mix.h.

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

◆ mResample

ArrayOf<std::unique_ptr<Resample> > Mixer::mResample
private

Definition at line 173 of file Mix.h.

Referenced by MakeResamplers(), and Process().

◆ mSamplePos

ArrayOf<sampleCount> Mixer::mSamplePos
private

Definition at line 167 of file Mix.h.

Referenced by Process(), Reposition(), and Restart().

◆ mSampleQueue

FloatBuffers Mixer::mSampleQueue
private

Definition at line 175 of file Mix.h.

Referenced by Process().

◆ mSpeed

double Mixer::mSpeed
private

◆ mT0

double Mixer::mT0
private

◆ mT1

double Mixer::mT1
private

◆ mTemp

ArrayOf<SampleBuffer> Mixer::mTemp
private

Definition at line 190 of file Mix.h.

Referenced by Clear(), MixSameRate(), MixVariableRates(), and Process().

◆ mTime

double Mixer::mTime
private

Definition at line 172 of file Mix.h.

Referenced by MixGetCurrentTime(), Process(), Reposition(), and Restart().


The documentation for this class was generated from the following files:
Mixer::MixSameRate
size_t MixSameRate(int *channelFlags, WaveTrackCache &cache, sampleCount *pos)
Definition: Mix.cpp:568
Mixer::mSampleQueue
FloatBuffers mSampleQueue
Definition: Mix.h:175
MixBuffers
void MixBuffers(unsigned numChannels, int *channelFlags, float *gains, samplePtr src, SampleBuffer *dests, int len, bool interleaved)
Definition: Mix.cpp:364
WaveTrack
A Track that contains audio waveform data.
Definition: WaveTrack.h:68
Mixer::mInterleaved
bool mInterleaved
Definition: Mix.h:189
Track::RightChannel
static const auto RightChannel
Definition: Track.h:266
Mixer::mInputTrack
ArrayOf< WaveTrackCache > mInputTrack
Definition: Mix.h:164
Mixer::mMixerSpec
MixerSpec * mMixerSpec
Definition: Mix.h:179
Mixer::mFormat
const sampleFormat mFormat
Definition: Mix.h:188
Mixer::mBuffer
ArrayOf< SampleBuffer > mBuffer
Definition: Mix.h:190
Mixer::mTemp
ArrayOf< SampleBuffer > mTemp
Definition: Mix.h:190
Mixer::mMaxOut
size_t mMaxOut
Definition: Mix.h:182
WaveTrack::GetEnvelopeValues
void GetEnvelopeValues(double *buffer, size_t bufferLen, double t0) const
Definition: WaveTrack.cpp:2025
WaveTrack::GetEndTime
double GetEndTime() const override
Get the time at which the last clip in the track ends, plus recorded stuff.
Definition: WaveTrack.cpp:1802
Mixer::mEnvelope
const BoundedEnvelope * mEnvelope
Definition: Mix.h:166
Mixer::mRate
const double mRate
Definition: Mix.h:192
Mixer::mGains
Floats mGains
Definition: Mix.h:184
Mixer::Reposition
void Reposition(double t, bool bSkipping=false)
Definition: Mix.cpp:749
Mixer::mBufferSize
size_t mBufferSize
Definition: Mix.h:186
ArrayOf::reinit
void reinit(Integral count, bool initialize=false)
Definition: MemoryX.h:56
Mixer::MakeResamplers
void MakeResamplers()
Definition: Mix.cpp:351
Mixer::mEnvValues
Doubles mEnvValues
Definition: Mix.h:169
ReverseSamples
void ReverseSamples(samplePtr dst, sampleFormat format, int start, int len)
Definition: SampleFormat.cpp:83
floatSample
@ floatSample
Definition: Types.h:199
WaveTrackCache::GetFloats
const float * GetFloats(sampleCount start, size_t len, bool mayThrow)
Retrieve samples as floats from the track or from the memory cache.
Definition: WaveTrack.cpp:2548
limitSampleBufferSize
size_t limitSampleBufferSize(size_t bufferSize, sampleCount limit)
Definition: Types.h:183
samplePtr
char * samplePtr
Definition: Types.h:214
MixerSpec::mMap
ArraysOf< bool > mMap
Definition: Mix.h:63
CopySamples
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.
Definition: SampleFormat.cpp:110
Mixer::mFloatBuffer
Floats mFloatBuffer
Definition: Mix.h:191
Track::MonoChannel
static const auto MonoChannel
Definition: Track.h:267
Mixer::MixVariableRates
size_t MixVariableRates(int *channelFlags, WaveTrackCache &cache, sampleCount *pos, float *queue, int *queueStart, int *queueLen, Resample *pResample)
Definition: Mix.cpp:413
Mixer::mTime
double mTime
Definition: Mix.h:172
MixerSpec::GetNumTracks
unsigned GetNumTracks()
Definition: Mix.h:73
Mixer::mNumInputTracks
const size_t mNumInputTracks
Definition: Mix.h:163
Track::LeftChannel
static const auto LeftChannel
Definition: Track.h:265
Mixer::mSamplePos
ArrayOf< sampleCount > mSamplePos
Definition: Mix.h:167
Mixer::mT0
double mT0
Definition: Mix.h:170
WaveTrack::GetStartTime
double GetStartTime() const override
Get the time at which the first clip in the track starts.
Definition: WaveTrack.cpp:1782
Mixer::mMaxFactor
std::vector< double > mMaxFactor
Definition: Mix.h:195
Mixer::mT1
double mT1
Definition: Mix.h:171
BoundedEnvelope::GetRangeLower
double GetRangeLower() const
Definition: Envelope.h:288
Mixer::Clear
void Clear()
Definition: Mix.cpp:357
min
int min(int a, int b)
Definition: CompareAudioCommand.cpp:106
Mixer::mQueueLen
ArrayOf< int > mQueueLen
Definition: Mix.h:177
WaveTrackCache::GetTrack
const std::shared_ptr< const WaveTrack > & GetTrack() const
Definition: WaveTrack.h:642
Mixer::mHighQuality
bool mHighQuality
Definition: Mix.h:194
WaveTrack::TimeToLongSamples
sampleCount TimeToLongSamples(double t0) const
Convert correctly between an (absolute) time in seconds and a number of samples.
Definition: WaveTrack.cpp:1772
sampleCount
Definition: Types.h:66
Mixer::mQueueMaxLen
const size_t mQueueMaxLen
Definition: Mix.h:174
Mixer::mResample
ArrayOf< std::unique_ptr< Resample > > mResample
Definition: Mix.h:173
Mixer::mSpeed
double mSpeed
Definition: Mix.h:193
gLowQualityDither
DitherType gLowQualityDither
These global variables are assigned at application startup or after change of preferences.
Definition: SampleFormat.cpp:48
Mixer::mNumBuffers
unsigned mNumBuffers
Definition: Mix.h:185
Mixer::mNumChannels
const unsigned mNumChannels
Definition: Mix.h:183
Resample::Process
std::pair< size_t, size_t > Process(double factor, float *inBuffer, size_t inBufferLen, bool lastFlag, float *outBuffer, size_t outBufferLen)
Main processing function. Resamples from the input buffer to the output buffer.
Definition: Resample.cpp:88
gHighQualityDither
DitherType gHighQualityDither
Definition: SampleFormat.cpp:49
Mixer::mMinFactor
std::vector< double > mMinFactor
Definition: Mix.h:195
Mixer::mMayThrow
const bool mMayThrow
Definition: Mix.h:197
anonymous_namespace{Mix.cpp}::ComputeWarpFactor
double ComputeWarpFactor(const Envelope &env, double t0, double t1)
Compute the integral warp factor between two non-warped time points.
Definition: Mix.cpp:406
WaveTrack::GetChannelGain
float GetChannelGain(int channel) const
Definition: WaveTrack.cpp:408
Mixer::mApplyTrackGains
const bool mApplyTrackGains
Definition: Mix.h:168
MixerSpec::GetNumChannels
unsigned GetNumChannels()
Definition: Mix.h:70
BoundedEnvelope::GetRangeUpper
double GetRangeUpper() const
Definition: Envelope.h:289
Mixer::mInterleavedBufferSize
size_t mInterleavedBufferSize
Definition: Mix.h:187
WaveTrack::GetChannel
ChannelType GetChannel() const override
Definition: WaveTrack.cpp:227
Mixer::mQueueStart
ArrayOf< int > mQueueStart
Definition: Mix.h:176
ArrayOf< float >
Mixer::mProcessLen
size_t mProcessLen
Definition: Mix.h:178
SAMPLE_SIZE
#define SAMPLE_SIZE(SampleFormat)
Definition: Types.h:209
Mixer::Process
size_t Process(size_t maxSamples)
Definition: Mix.cpp:630
Mixer::mbVariableRates
bool mbVariableRates
Definition: Mix.h:165
WaveTrack::GetRate
double GetRate() const
Definition: WaveTrack.cpp:360