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:
parent
987b038fd8
commit
38b8e57e4e
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
13
src/Mix.cpp
13
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<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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue