diff --git a/src/AudioIO.cpp b/src/AudioIO.cpp index 4320e964c..ccddc5cb0 100644 --- a/src/AudioIO.cpp +++ b/src/AudioIO.cpp @@ -1883,10 +1883,12 @@ int AudioIO::StartStream(const ConstWaveTrackArray &playbackTracks, // MB: use normal time for the end time, not warped time! mPlaybackMixers[i] = std::make_unique (WaveTrackConstArray{ mPlaybackTracks[i] }, - warpOptions, - mT0, mT1, 1, - playbackMixBufferSize, false, - mRate, floatSample, false); + // Don't throw for read errors, just play silence: + false, + warpOptions, + mT0, mT1, 1, + playbackMixBufferSize, false, + mRate, floatSample, false); mPlaybackMixers[i]->ApplyTrackGains(false); } } diff --git a/src/Mix.cpp b/src/Mix.cpp index 71ddc7eb7..a16ca05e2 100644 --- a/src/Mix.cpp +++ b/src/Mix.cpp @@ -160,6 +160,8 @@ void MixAndRender(TrackList *tracks, TrackFactory *trackFactory, } Mixer mixer(waveArray, + // Throw to abort mix-and-render if read fails: + true, Mixer::WarpOptions(tracks->GetTimeTrack()), startTime, endTime, mono ? 1 : 2, maxBlockLen, false, rate, format); @@ -239,6 +241,7 @@ Mixer::WarpOptions::WarpOptions(double min, double max) } Mixer::Mixer(const WaveTrackConstArray &inputTracks, + bool mayThrow, const WarpOptions &warpOptions, double startTime, double stopTime, unsigned numOutChannels, size_t outBufferSize, bool outInterleaved, @@ -254,6 +257,8 @@ Mixer::Mixer(const WaveTrackConstArray &inputTracks, , mNumChannels{ static_cast(numOutChannels) } , mGains{ mNumChannels } + + , mMayThrow{ mayThrow } { mHighQuality = highQuality; mInputTrack.reinit(mNumInputTracks); @@ -434,7 +439,7 @@ size_t Mixer::MixVariableRates(int *channelFlags, WaveTrackCache &cache, // Nothing to do if past end of play interval if (getLen > 0) { if (backwards) { - auto results = cache.Get(floatSample, *pos - (getLen - 1), getLen); + auto results = cache.Get(floatSample, *pos - (getLen - 1), getLen, mMayThrow); if (results) memcpy(&queue[*queueLen], results, sizeof(float) * getLen); else @@ -446,7 +451,7 @@ size_t Mixer::MixVariableRates(int *channelFlags, WaveTrackCache &cache, *pos -= getLen; } else { - auto results = cache.Get(floatSample, *pos, getLen); + auto results = cache.Get(floatSample, *pos, getLen, mMayThrow); if (results) memcpy(&queue[*queueLen], results, sizeof(float) * getLen); else @@ -554,7 +559,7 @@ size_t Mixer::MixSameRate(int *channelFlags, WaveTrackCache &cache, slen = std::min(slen, mMaxOut); if (backwards) { - auto results = cache.Get(floatSample, *pos - (slen - 1), slen); + auto results = cache.Get(floatSample, *pos - (slen - 1), slen, mMayThrow); if (results) memcpy(mFloatBuffer.get(), results, sizeof(float) * slen); else @@ -567,7 +572,7 @@ size_t Mixer::MixSameRate(int *channelFlags, WaveTrackCache &cache, *pos -= slen; } else { - auto results = cache.Get(floatSample, *pos, slen); + auto results = cache.Get(floatSample, *pos, slen, mMayThrow); if (results) memcpy(mFloatBuffer.get(), results, sizeof(float) * slen); else diff --git a/src/Mix.h b/src/Mix.h index 086b3d4ae..a2fefd82c 100644 --- a/src/Mix.h +++ b/src/Mix.h @@ -91,7 +91,7 @@ class AUDACITY_DLL_API Mixer { // Constructor / Destructor // - Mixer(const WaveTrackConstArray &inputTracks, + Mixer(const WaveTrackConstArray &inputTracks, bool mayThrow, const WarpOptions &warpOptions, double startTime, double stopTime, unsigned numOutChannels, size_t outBufferSize, bool outInterleaved, @@ -183,6 +183,8 @@ class AUDACITY_DLL_API Mixer { double mRate; double mSpeed; bool mHighQuality; + + bool mMayThrow; }; #endif diff --git a/src/WaveClip.cpp b/src/WaveClip.cpp index fa830ab89..cfc527576 100644 --- a/src/WaveClip.cpp +++ b/src/WaveClip.cpp @@ -901,7 +901,9 @@ bool SpecCache::CalculateOneSpectrum floatSample, sampleCount( floor(0.5 + from.as_double() + offset * rate) ), - myLen) + myLen, + // Don't throw in this drawing operation + false) ); if (copy) { diff --git a/src/WaveTrack.cpp b/src/WaveTrack.cpp index 4dcd66c0b..6e8f10c15 100644 --- a/src/WaveTrack.cpp +++ b/src/WaveTrack.cpp @@ -2621,7 +2621,7 @@ void WaveTrackCache::SetTrack(const WaveTrack *pTrack) } constSamplePtr WaveTrackCache::Get(sampleFormat format, - sampleCount start, size_t len) + sampleCount start, size_t len, bool mayThrow) { if (format == floatSample && len > 0) { const auto end = start + len; @@ -2671,7 +2671,9 @@ constSamplePtr WaveTrackCache::Get(sampleFormat format, if (start0 >= 0) { const auto len0 = mPTrack->GetBestBlockSize(start0); wxASSERT(len0 <= mBufferSize); - if (!mPTrack->Get(samplePtr(mBuffers[0].data.get()), floatSample, start0, len0)) + if (!mPTrack->Get( + samplePtr(mBuffers[0].data.get()), floatSample, start0, len0, + fillZero, mayThrow)) return 0; mBuffers[0].start = start0; mBuffers[0].len = len0; diff --git a/src/WaveTrack.h b/src/WaveTrack.h index 73252c010..712b8d925 100644 --- a/src/WaveTrack.h +++ b/src/WaveTrack.h @@ -648,7 +648,8 @@ public: // Returns null on failure // Returned pointer may be invalidated if Get is called again // Do not DELETE[] the pointer - constSamplePtr Get(sampleFormat format, sampleCount start, size_t len); + constSamplePtr Get( + sampleFormat format, sampleCount start, size_t len, bool mayThrow); private: void Free(); diff --git a/src/export/Export.cpp b/src/export/Export.cpp index 40812e807..e92a7cbda 100644 --- a/src/export/Export.cpp +++ b/src/export/Export.cpp @@ -246,6 +246,8 @@ std::unique_ptr ExportPlugin::CreateMixer(const WaveTrackConstArray &inpu { // MB: the stop time should not be warped, this was a bug. return std::make_unique(inputTracks, + // Throw, to stop exporting, if read fails: + true, Mixer::WarpOptions(timeTrack), startTime, stopTime, numOutChannels, outBufferSize, outInterleaved,