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,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<Mixer>
(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);
}
}

View File

@ -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<size_t>(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

View File

@ -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

View File

@ -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) {

View File

@ -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;

View File

@ -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();

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.
return std::make_unique<Mixer>(inputTracks,
// Throw, to stop exporting, if read fails:
true,
Mixer::WarpOptions(timeTrack),
startTime, stopTime,
numOutChannels, outBufferSize, outInterleaved,