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