1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-10 23:44:24 +00:00

BufferingAudioFormatReader: Return failure from read() in more cases

read() now returns failure in the case of a read timeout, or if
reading any block failed.
This commit is contained in:
attila 2020-09-02 22:13:41 -03:00
parent 2bca60e52c
commit 7c22fae8c7
4 changed files with 65 additions and 49 deletions

View file

@ -115,7 +115,7 @@ bool AudioFormatReader::read (int* const* destChannels,
return true;
}
static void readChannels (AudioFormatReader& reader, int** chans, AudioBuffer<float>* buffer,
static bool readChannels (AudioFormatReader& reader, int** chans, AudioBuffer<float>* buffer,
int startSample, int numSamples, int64 readerStartSample, int numTargetChannels,
bool convertToFloat)
{
@ -123,13 +123,16 @@ static void readChannels (AudioFormatReader& reader, int** chans, AudioBuffer<fl
chans[j] = reinterpret_cast<int*> (buffer->getWritePointer (j, startSample));
chans[numTargetChannels] = nullptr;
reader.read (chans, numTargetChannels, readerStartSample, numSamples, true);
const bool success = reader.read (chans, numTargetChannels, readerStartSample, numSamples, true);
if (convertToFloat)
convertFixedToFloat (chans, numTargetChannels, numSamples);
return success;
}
void AudioFormatReader::read (AudioBuffer<float>* buffer,
bool AudioFormatReader::read (AudioBuffer<float>* buffer,
int startSample,
int numSamples,
int64 readerStartSample,
@ -139,58 +142,61 @@ void AudioFormatReader::read (AudioBuffer<float>* buffer,
jassert (buffer != nullptr);
jassert (startSample >= 0 && startSample + numSamples <= buffer->getNumSamples());
if (numSamples > 0)
if (numSamples <= 0)
return true;
auto numTargetChannels = buffer->getNumChannels();
if (numTargetChannels <= 2)
{
auto numTargetChannels = buffer->getNumChannels();
int* dests[2] = { reinterpret_cast<int*> (buffer->getWritePointer (0, startSample)),
reinterpret_cast<int*> (numTargetChannels > 1 ? buffer->getWritePointer (1, startSample) : nullptr) };
int* chans[3] = {};
if (numTargetChannels <= 2)
if (useReaderLeftChan == useReaderRightChan)
{
int* dests[2] = { reinterpret_cast<int*> (buffer->getWritePointer (0, startSample)),
reinterpret_cast<int*> (numTargetChannels > 1 ? buffer->getWritePointer (1, startSample) : nullptr) };
int* chans[3] = {};
chans[0] = dests[0];
if (useReaderLeftChan == useReaderRightChan)
{
chans[0] = dests[0];
if (numChannels > 1)
chans[1] = dests[1];
}
else if (useReaderLeftChan || (numChannels == 1))
{
chans[0] = dests[0];
}
else if (useReaderRightChan)
{
chans[1] = dests[0];
}
read (chans, 2, readerStartSample, numSamples, true);
// if the target's stereo and the source is mono, dupe the first channel..
if (numTargetChannels > 1
&& (chans[0] == nullptr || chans[1] == nullptr)
&& (dests[0] != nullptr && dests[1] != nullptr))
{
memcpy (dests[1], dests[0], (size_t) numSamples * sizeof (float));
}
if (! usesFloatingPointData)
convertFixedToFloat (dests, 2, numSamples);
if (numChannels > 1)
chans[1] = dests[1];
}
else if (numTargetChannels <= 64)
else if (useReaderLeftChan || (numChannels == 1))
{
int* chans[65];
readChannels (*this, chans, buffer, startSample, numSamples,
readerStartSample, numTargetChannels, ! usesFloatingPointData);
chans[0] = dests[0];
}
else
else if (useReaderRightChan)
{
HeapBlock<int*> chans (numTargetChannels + 1);
readChannels (*this, chans, buffer, startSample, numSamples,
readerStartSample, numTargetChannels, ! usesFloatingPointData);
chans[1] = dests[0];
}
if (! read (chans, 2, readerStartSample, numSamples, true))
return false;
// if the target's stereo and the source is mono, dupe the first channel..
if (numTargetChannels > 1
&& (chans[0] == nullptr || chans[1] == nullptr)
&& (dests[0] != nullptr && dests[1] != nullptr))
{
memcpy (dests[1], dests[0], (size_t) numSamples * sizeof (float));
}
if (! usesFloatingPointData)
convertFixedToFloat (dests, 2, numSamples);
return true;
}
if (numTargetChannels <= 64)
{
int* chans[65];
return readChannels (*this, chans, buffer, startSample, numSamples,
readerStartSample, numTargetChannels, ! usesFloatingPointData);
}
HeapBlock<int*> chans (numTargetChannels + 1);
return readChannels (*this, chans, buffer, startSample, numSamples,
readerStartSample, numTargetChannels, ! usesFloatingPointData);
}
void AudioFormatReader::readMaxLevels (int64 startSampleInFile, int64 numSamples,

View file

@ -132,8 +132,12 @@ public:
the buffer's floating-point format, and will try to intelligently
cope with mismatches between the number of channels in the reader
and the buffer.
@returns true if the operation succeeded, false if there was an error. Note
that reading sections of data beyond the extent of the stream isn't an
error - the reader should just return zeros for these regions
*/
void read (AudioBuffer<float>* buffer,
bool read (AudioBuffer<float>* buffer,
int startSampleInDestBuffer,
int numSamples,
int64 readerStartSample,

View file

@ -56,6 +56,8 @@ bool BufferingAudioReader::readSamples (int** destSamples, int numDestChannels,
const ScopedLock sl (lock);
nextReadPosition = startSampleInFile;
bool allSamplesRead = true;
while (numSamples > 0)
{
if (auto block = getBlockContaining (startSampleInFile))
@ -79,6 +81,8 @@ bool BufferingAudioReader::readSamples (int** destSamples, int numDestChannels,
startOffsetInDestBuffer += numToDo;
startSampleInFile += numToDo;
numSamples -= numToDo;
allSamplesRead = allSamplesRead && block->allSamplesRead;
}
else
{
@ -88,6 +92,7 @@ bool BufferingAudioReader::readSamples (int** destSamples, int numDestChannels,
if (auto* dest = (float*) destSamples[j])
FloatVectorOperations::clear (dest + startOffsetInDestBuffer, numSamples);
allSamplesRead = false;
break;
}
else
@ -98,14 +103,14 @@ bool BufferingAudioReader::readSamples (int** destSamples, int numDestChannels,
}
}
return true;
return allSamplesRead;
}
BufferingAudioReader::BufferedBlock::BufferedBlock (AudioFormatReader& reader, int64 pos, int numSamples)
: range (pos, pos + numSamples),
buffer ((int) reader.numChannels, numSamples)
buffer ((int) reader.numChannels, numSamples),
allSamplesRead (reader.read (&buffer, 0, numSamples, pos, true, true))
{
reader.read (&buffer, 0, numSamples, pos, true, true);
}
BufferingAudioReader::BufferedBlock* BufferingAudioReader::getBlockContaining (int64 pos) const noexcept

View file

@ -66,6 +66,7 @@ private:
Range<int64> range;
AudioBuffer<float> buffer;
bool allSamplesRead = false;
};
int useTimeSlice() override;