From 6eaff838f26adadba8ea914a4a1f8deb3cde9521 Mon Sep 17 00:00:00 2001 From: Paul-Licameli Date: Sun, 15 May 2016 10:06:51 -0500 Subject: [PATCH] Less scrub lag: avoid redundant disk traffic in Mixer... Also improves performance in bug 860, but not as much as the special case patch for that bug in Bugzilla --- src/Mix.cpp | 45 ++++++++++++++++++++++----------------------- src/Mix.h | 11 ++++++----- 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/src/Mix.cpp b/src/Mix.cpp index ec22bb2aa..329afc81d 100644 --- a/src/Mix.cpp +++ b/src/Mix.cpp @@ -22,7 +22,6 @@ #include "Audacity.h" - #include "Mix.h" #include @@ -251,13 +250,13 @@ Mixer::Mixer(const WaveTrackConstArray &inputTracks, const auto numInputTracks = inputTracks.size(); mHighQuality = highQuality; mNumInputTracks = numInputTracks; - mInputTrack = new const WaveTrack*[mNumInputTracks]; + mInputTrack = new WaveTrackCache[mNumInputTracks]; // mSamplePos holds for each track the next sample position not // yet processed. mSamplePos = new sampleCount[mNumInputTracks]; for(i=0; iTimeToLongSamples(startTime); } mTimeTrack = warpOptions.timeTrack; @@ -313,7 +312,7 @@ Mixer::Mixer(const WaveTrackConstArray &inputTracks, mSampleQueue = new float *[mNumInputTracks]; mResample = new Resample*[mNumInputTracks]; for(i=0; iGetRate()); + double factor = (mRate / mInputTrack[i].GetTrack()->GetRate()); double minFactor, maxFactor; if (mTimeTrack) { // variable rate resampling @@ -408,11 +407,12 @@ void MixBuffers(int numChannels, int *channelFlags, float *gains, } } -sampleCount Mixer::MixVariableRates(int *channelFlags, const WaveTrack *track, +sampleCount Mixer::MixVariableRates(int *channelFlags, WaveTrackCache &cache, sampleCount *pos, float *queue, int *queueStart, int *queueLen, Resample * pResample) { + const WaveTrack *const track = cache.GetTrack(); const double trackRate = track->GetRate(); const double initialWarp = mRate / mSpeed / trackRate; const double tstep = 1.0 / trackRate; @@ -455,10 +455,8 @@ sampleCount Mixer::MixVariableRates(int *channelFlags, const WaveTrack *track, // Nothing to do if past end of play interval if (getLen > 0) { if (backwards) { - track->Get((samplePtr)&queue[*queueLen], - floatSample, - *pos - (getLen - 1), - getLen); + auto results = cache.Get(floatSample, *pos - (getLen - 1), getLen); + memcpy(&queue[*queueLen], results, sizeof(float) * getLen); track->GetEnvelopeValues(mEnvValues, getLen, @@ -468,10 +466,8 @@ sampleCount Mixer::MixVariableRates(int *channelFlags, const WaveTrack *track, *pos -= getLen; } else { - track->Get((samplePtr)&queue[*queueLen], - floatSample, - *pos, - getLen); + auto results = cache.Get(floatSample, *pos, getLen); + memcpy(&queue[*queueLen], results, sizeof(float) * getLen); track->GetEnvelopeValues(mEnvValues, getLen, @@ -558,9 +554,10 @@ sampleCount Mixer::MixVariableRates(int *channelFlags, const WaveTrack *track, return out; } -sampleCount Mixer::MixSameRate(int *channelFlags, const WaveTrack *track, +sampleCount Mixer::MixSameRate(int *channelFlags, WaveTrackCache &cache, sampleCount *pos) { + const WaveTrack *const track = cache.GetTrack(); int slen = mMaxOut; int c; const double t = *pos / track->GetRate(); @@ -588,7 +585,8 @@ sampleCount Mixer::MixSameRate(int *channelFlags, const WaveTrack *track, slen = mMaxOut; if (backwards) { - track->Get((samplePtr)mFloatBuffer, floatSample, *pos - (slen - 1), slen); + auto results = cache.Get(floatSample, *pos - (slen - 1), slen); + memcpy(mFloatBuffer, results, sizeof(float) * slen); track->GetEnvelopeValues(mEnvValues, slen, t - (slen - 1) / mRate, 1.0 / mRate); for(int i=0; iGet((samplePtr)mFloatBuffer, floatSample, *pos, slen); + auto results = cache.Get(floatSample, *pos, slen); + memcpy(mFloatBuffer, results, sizeof(float) * slen); track->GetEnvelopeValues(mEnvValues, slen, t, 1.0 / mRate); for(int i=0; iGetRate() != mRate) maxOut = std::max(maxOut, - MixVariableRates(channelFlags, track, - &mSamplePos[i], mSampleQueue[i], - &mQueueStart[i], &mQueueLen[i], mResample[i])); + MixVariableRates(channelFlags, mInputTrack[i], + &mSamplePos[i], mSampleQueue[i], + &mQueueStart[i], &mQueueLen[i], mResample[i])); else maxOut = std::max(maxOut, - MixSameRate(channelFlags, track, &mSamplePos[i])); + MixSameRate(channelFlags, mInputTrack[i], &mSamplePos[i])); double t = (double)mSamplePos[i] / (double)track->GetRate(); if (mT0 > mT1) @@ -728,7 +727,7 @@ void Mixer::Restart() mTime = mT0; for(i=0; iTimeToLongSamples(mT0); + mSamplePos[i] = mInputTrack[i].GetTrack()->TimeToLongSamples(mT0); for(i=0; iTimeToLongSamples(mTime); + mSamplePos[i] = mInputTrack[i].GetTrack()->TimeToLongSamples(mTime); mQueueStart[i] = 0; mQueueLen[i] = 0; } diff --git a/src/Mix.h b/src/Mix.h index e50481def..d70f053bb 100644 --- a/src/Mix.h +++ b/src/Mix.h @@ -14,16 +14,16 @@ #include "MemoryX.h" #include - #include "SampleFormat.h" -#include "Resample.h" +class Resample; class DirManager; class TimeTrack; class TrackFactory; class TrackList; class WaveTrack; class WaveTrackConstArray; +class WaveTrackCache; /** @brief Mixes together all input tracks, applying any envelopes, amplitude * gain, panning, and real-time effects in the process. @@ -141,10 +141,10 @@ class AUDACITY_DLL_API Mixer { private: void Clear(); - sampleCount MixSameRate(int *channelFlags, const WaveTrack *src, + sampleCount MixSameRate(int *channelFlags, WaveTrackCache &cache, sampleCount *pos); - sampleCount MixVariableRates(int *channelFlags, const WaveTrack *track, + sampleCount MixVariableRates(int *channelFlags, WaveTrackCache &cache, sampleCount *pos, float *queue, int *queueStart, int *queueLen, Resample * pResample); @@ -152,7 +152,8 @@ class AUDACITY_DLL_API Mixer { private: // Input int mNumInputTracks; - const WaveTrack **mInputTrack; + WaveTrackCache *mInputTrack; + bool mbVariableRates; const TimeTrack *mTimeTrack; sampleCount *mSamplePos;