1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-10-25 15:53:52 +02:00

Bug1887: crash or hang loop-playing with WASAPI; libsoxr 0.1.3 to blame...

... probably?  This is a workaround to prevent crashes in libsoxr that did
not happen with the previous version.
This commit is contained in:
Paul Licameli
2018-06-11 14:05:00 -04:00
parent 800ddf32e1
commit 14051f04cf
2 changed files with 24 additions and 8 deletions

View File

@@ -313,32 +313,34 @@ Mixer::Mixer(const WaveTrackConstArray &inputTracks,
// For each queue, the number of available samples after the queue start. // For each queue, the number of available samples after the queue start.
mQueueLen.reinit(mNumInputTracks); mQueueLen.reinit(mNumInputTracks);
mResample.reinit(mNumInputTracks); mResample.reinit(mNumInputTracks);
for(size_t i=0; i<mNumInputTracks; i++) { mMinFactor.resize(mNumInputTracks);
mMaxFactor.resize(mNumInputTracks);
for (size_t i = 0; i<mNumInputTracks; i++) {
double factor = (mRate / mInputTrack[i].GetTrack()->GetRate()); double factor = (mRate / mInputTrack[i].GetTrack()->GetRate());
double minFactor, maxFactor;
if (mTimeTrack) { if (mTimeTrack) {
// variable rate resampling // variable rate resampling
mbVariableRates = true; mbVariableRates = true;
minFactor = factor / mTimeTrack->GetRangeUpper(); mMinFactor[i] = factor / mTimeTrack->GetRangeUpper();
maxFactor = factor / mTimeTrack->GetRangeLower(); mMaxFactor[i] = factor / mTimeTrack->GetRangeLower();
} }
else if (warpOptions.minSpeed > 0.0 && warpOptions.maxSpeed > 0.0) { else if (warpOptions.minSpeed > 0.0 && warpOptions.maxSpeed > 0.0) {
// variable rate resampling // variable rate resampling
mbVariableRates = true; mbVariableRates = true;
minFactor = factor / warpOptions.maxSpeed; mMinFactor[i] = factor / warpOptions.maxSpeed;
maxFactor = factor / warpOptions.minSpeed; mMaxFactor[i] = factor / warpOptions.minSpeed;
} }
else { else {
// constant rate resampling // constant rate resampling
mbVariableRates = false; mbVariableRates = false;
minFactor = maxFactor = factor; mMinFactor[i] = mMaxFactor[i] = factor;
} }
mResample[i] = std::make_unique<Resample>(mHighQuality, minFactor, maxFactor);
mQueueStart[i] = 0; mQueueStart[i] = 0;
mQueueLen[i] = 0; mQueueLen[i] = 0;
} }
MakeResamplers();
const auto envLen = std::max(mQueueMaxLen, mInterleavedBufferSize); const auto envLen = std::max(mQueueMaxLen, mInterleavedBufferSize);
mEnvValues.reinit(envLen); mEnvValues.reinit(envLen);
} }
@@ -347,6 +349,12 @@ Mixer::~Mixer()
{ {
} }
void Mixer::MakeResamplers()
{
for (size_t i = 0; i < mNumInputTracks; i++)
mResample[i] = std::make_unique<Resample>(mHighQuality, mMinFactor[i], mMaxFactor[i]);
}
void Mixer::ApplyTrackGains(bool apply) void Mixer::ApplyTrackGains(bool apply)
{ {
mApplyTrackGains = apply; mApplyTrackGains = apply;
@@ -709,6 +717,11 @@ void Mixer::Restart()
mQueueStart[i] = 0; mQueueStart[i] = 0;
mQueueLen[i] = 0; mQueueLen[i] = 0;
} }
// Bug 1887: libsoxr 0.1.3, first used in Audacity 2.3.0, crashes with
// constant rate resampling if you try to reuse the resampler after it has
// flushed. Should that be considered a bug in sox? This works around it:
MakeResamplers();
} }
void Mixer::Reposition(double t) void Mixer::Reposition(double t)

View File

@@ -157,6 +157,8 @@ class AUDACITY_DLL_API Mixer {
int *queueStart, int *queueLen, int *queueStart, int *queueLen,
Resample * pResample); Resample * pResample);
void MakeResamplers();
private: private:
// Input // Input
@@ -192,6 +194,7 @@ class AUDACITY_DLL_API Mixer {
double mRate; double mRate;
double mSpeed; double mSpeed;
bool mHighQuality; bool mHighQuality;
std::vector<double> mMinFactor, mMaxFactor;
bool mMayThrow; bool mMayThrow;
}; };