Browse Source

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.
pull/22/head
attila 5 years ago
parent
commit
7c22fae8c7
4 changed files with 65 additions and 49 deletions
  1. +51
    -45
      modules/juce_audio_formats/format/juce_AudioFormatReader.cpp
  2. +5
    -1
      modules/juce_audio_formats/format/juce_AudioFormatReader.h
  3. +8
    -3
      modules/juce_audio_formats/format/juce_BufferingAudioFormatReader.cpp
  4. +1
    -0
      modules/juce_audio_formats/format/juce_BufferingAudioFormatReader.h

+ 51
- 45
modules/juce_audio_formats/format/juce_AudioFormatReader.cpp 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)
{
auto numTargetChannels = buffer->getNumChannels();
if (numTargetChannels <= 2)
{
int* dests[2] = { reinterpret_cast<int*> (buffer->getWritePointer (0, startSample)),
reinterpret_cast<int*> (numTargetChannels > 1 ? buffer->getWritePointer (1, startSample) : nullptr) };
int* chans[3] = {};
if (useReaderLeftChan == useReaderRightChan)
{
chans[0] = dests[0];
if (numSamples <= 0)
return true;
if (numChannels > 1)
chans[1] = dests[1];
}
else if (useReaderLeftChan || (numChannels == 1))
{
chans[0] = dests[0];
}
else if (useReaderRightChan)
{
chans[1] = dests[0];
}
auto numTargetChannels = buffer->getNumChannels();
read (chans, 2, readerStartSample, numSamples, true);
if (numTargetChannels <= 2)
{
int* dests[2] = { reinterpret_cast<int*> (buffer->getWritePointer (0, startSample)),
reinterpret_cast<int*> (numTargetChannels > 1 ? buffer->getWritePointer (1, startSample) : nullptr) };
int* chans[3] = {};
// 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 (useReaderLeftChan == useReaderRightChan)
{
chans[0] = dests[0];
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)
{
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))
{
HeapBlock<int*> chans (numTargetChannels + 1);
readChannels (*this, chans, buffer, startSample, numSamples,
readerStartSample, numTargetChannels, ! usesFloatingPointData);
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,


+ 5
- 1
modules/juce_audio_formats/format/juce_AudioFormatReader.h 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,


+ 8
- 3
modules/juce_audio_formats/format/juce_BufferingAudioFormatReader.cpp 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


+ 1
- 0
modules/juce_audio_formats/format/juce_BufferingAudioFormatReader.h View File

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


Loading…
Cancel
Save