1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-06-25 16:48:44 +02:00

Specify whether to throw on bad read in Mixer and WaveTrackCache...

... Do throw when exporting or mixing-and-rendering; don't if playing back or
drawing a spectrogram, but then just use zeroes.
This commit is contained in:
Paul Licameli 2016-12-22 17:08:29 -05:00
parent 987b038fd8
commit 38b8e57e4e
7 changed files with 29 additions and 13 deletions

View File

@ -1883,6 +1883,8 @@ int AudioIO::StartStream(const ConstWaveTrackArray &playbackTracks,
// MB: use normal time for the end time, not warped time! // MB: use normal time for the end time, not warped time!
mPlaybackMixers[i] = std::make_unique<Mixer> mPlaybackMixers[i] = std::make_unique<Mixer>
(WaveTrackConstArray{ mPlaybackTracks[i] }, (WaveTrackConstArray{ mPlaybackTracks[i] },
// Don't throw for read errors, just play silence:
false,
warpOptions, warpOptions,
mT0, mT1, 1, mT0, mT1, 1,
playbackMixBufferSize, false, playbackMixBufferSize, false,

View File

@ -160,6 +160,8 @@ void MixAndRender(TrackList *tracks, TrackFactory *trackFactory,
} }
Mixer mixer(waveArray, Mixer mixer(waveArray,
// Throw to abort mix-and-render if read fails:
true,
Mixer::WarpOptions(tracks->GetTimeTrack()), Mixer::WarpOptions(tracks->GetTimeTrack()),
startTime, endTime, mono ? 1 : 2, maxBlockLen, false, startTime, endTime, mono ? 1 : 2, maxBlockLen, false,
rate, format); rate, format);
@ -239,6 +241,7 @@ Mixer::WarpOptions::WarpOptions(double min, double max)
} }
Mixer::Mixer(const WaveTrackConstArray &inputTracks, Mixer::Mixer(const WaveTrackConstArray &inputTracks,
bool mayThrow,
const WarpOptions &warpOptions, const WarpOptions &warpOptions,
double startTime, double stopTime, double startTime, double stopTime,
unsigned numOutChannels, size_t outBufferSize, bool outInterleaved, unsigned numOutChannels, size_t outBufferSize, bool outInterleaved,
@ -254,6 +257,8 @@ Mixer::Mixer(const WaveTrackConstArray &inputTracks,
, mNumChannels{ static_cast<size_t>(numOutChannels) } , mNumChannels{ static_cast<size_t>(numOutChannels) }
, mGains{ mNumChannels } , mGains{ mNumChannels }
, mMayThrow{ mayThrow }
{ {
mHighQuality = highQuality; mHighQuality = highQuality;
mInputTrack.reinit(mNumInputTracks); mInputTrack.reinit(mNumInputTracks);
@ -434,7 +439,7 @@ size_t Mixer::MixVariableRates(int *channelFlags, WaveTrackCache &cache,
// Nothing to do if past end of play interval // Nothing to do if past end of play interval
if (getLen > 0) { if (getLen > 0) {
if (backwards) { if (backwards) {
auto results = cache.Get(floatSample, *pos - (getLen - 1), getLen); auto results = cache.Get(floatSample, *pos - (getLen - 1), getLen, mMayThrow);
if (results) if (results)
memcpy(&queue[*queueLen], results, sizeof(float) * getLen); memcpy(&queue[*queueLen], results, sizeof(float) * getLen);
else else
@ -446,7 +451,7 @@ size_t Mixer::MixVariableRates(int *channelFlags, WaveTrackCache &cache,
*pos -= getLen; *pos -= getLen;
} }
else { else {
auto results = cache.Get(floatSample, *pos, getLen); auto results = cache.Get(floatSample, *pos, getLen, mMayThrow);
if (results) if (results)
memcpy(&queue[*queueLen], results, sizeof(float) * getLen); memcpy(&queue[*queueLen], results, sizeof(float) * getLen);
else else
@ -554,7 +559,7 @@ size_t Mixer::MixSameRate(int *channelFlags, WaveTrackCache &cache,
slen = std::min(slen, mMaxOut); slen = std::min(slen, mMaxOut);
if (backwards) { if (backwards) {
auto results = cache.Get(floatSample, *pos - (slen - 1), slen); auto results = cache.Get(floatSample, *pos - (slen - 1), slen, mMayThrow);
if (results) if (results)
memcpy(mFloatBuffer.get(), results, sizeof(float) * slen); memcpy(mFloatBuffer.get(), results, sizeof(float) * slen);
else else
@ -567,7 +572,7 @@ size_t Mixer::MixSameRate(int *channelFlags, WaveTrackCache &cache,
*pos -= slen; *pos -= slen;
} }
else { else {
auto results = cache.Get(floatSample, *pos, slen); auto results = cache.Get(floatSample, *pos, slen, mMayThrow);
if (results) if (results)
memcpy(mFloatBuffer.get(), results, sizeof(float) * slen); memcpy(mFloatBuffer.get(), results, sizeof(float) * slen);
else else

View File

@ -91,7 +91,7 @@ class AUDACITY_DLL_API Mixer {
// Constructor / Destructor // Constructor / Destructor
// //
Mixer(const WaveTrackConstArray &inputTracks, Mixer(const WaveTrackConstArray &inputTracks, bool mayThrow,
const WarpOptions &warpOptions, const WarpOptions &warpOptions,
double startTime, double stopTime, double startTime, double stopTime,
unsigned numOutChannels, size_t outBufferSize, bool outInterleaved, unsigned numOutChannels, size_t outBufferSize, bool outInterleaved,
@ -183,6 +183,8 @@ class AUDACITY_DLL_API Mixer {
double mRate; double mRate;
double mSpeed; double mSpeed;
bool mHighQuality; bool mHighQuality;
bool mMayThrow;
}; };
#endif #endif

View File

@ -901,7 +901,9 @@ bool SpecCache::CalculateOneSpectrum
floatSample, sampleCount( floatSample, sampleCount(
floor(0.5 + from.as_double() + offset * rate) floor(0.5 + from.as_double() + offset * rate)
), ),
myLen) myLen,
// Don't throw in this drawing operation
false)
); );
if (copy) { if (copy) {

View File

@ -2621,7 +2621,7 @@ void WaveTrackCache::SetTrack(const WaveTrack *pTrack)
} }
constSamplePtr WaveTrackCache::Get(sampleFormat format, constSamplePtr WaveTrackCache::Get(sampleFormat format,
sampleCount start, size_t len) sampleCount start, size_t len, bool mayThrow)
{ {
if (format == floatSample && len > 0) { if (format == floatSample && len > 0) {
const auto end = start + len; const auto end = start + len;
@ -2671,7 +2671,9 @@ constSamplePtr WaveTrackCache::Get(sampleFormat format,
if (start0 >= 0) { if (start0 >= 0) {
const auto len0 = mPTrack->GetBestBlockSize(start0); const auto len0 = mPTrack->GetBestBlockSize(start0);
wxASSERT(len0 <= mBufferSize); 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; return 0;
mBuffers[0].start = start0; mBuffers[0].start = start0;
mBuffers[0].len = len0; mBuffers[0].len = len0;

View File

@ -648,7 +648,8 @@ public:
// Returns null on failure // Returns null on failure
// Returned pointer may be invalidated if Get is called again // Returned pointer may be invalidated if Get is called again
// Do not DELETE[] the pointer // 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: private:
void Free(); void Free();

View File

@ -246,6 +246,8 @@ std::unique_ptr<Mixer> ExportPlugin::CreateMixer(const WaveTrackConstArray &inpu
{ {
// MB: the stop time should not be warped, this was a bug. // MB: the stop time should not be warped, this was a bug.
return std::make_unique<Mixer>(inputTracks, return std::make_unique<Mixer>(inputTracks,
// Throw, to stop exporting, if read fails:
true,
Mixer::WarpOptions(timeTrack), Mixer::WarpOptions(timeTrack),
startTime, stopTime, startTime, stopTime,
numOutChannels, outBufferSize, outInterleaved, numOutChannels, outBufferSize, outInterleaved,