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; 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, int startSample, int numSamples, int64 readerStartSample, int numTargetChannels,
bool convertToFloat) 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[j] = reinterpret_cast<int*> (buffer->getWritePointer (j, startSample));
chans[numTargetChannels] = nullptr; chans[numTargetChannels] = nullptr;
reader.read (chans, numTargetChannels, readerStartSample, numSamples, true);
const bool success = reader.read (chans, numTargetChannels, readerStartSample, numSamples, true);
if (convertToFloat) if (convertToFloat)
convertFixedToFloat (chans, numTargetChannels, numSamples); convertFixedToFloat (chans, numTargetChannels, numSamples);
return success;
} }
void AudioFormatReader::read (AudioBuffer<float>* buffer,
bool AudioFormatReader::read (AudioBuffer<float>* buffer,
int startSample, int startSample,
int numSamples, int numSamples,
int64 readerStartSample, int64 readerStartSample,
@@ -139,58 +142,61 @@ void AudioFormatReader::read (AudioBuffer<float>* buffer,
jassert (buffer != nullptr); jassert (buffer != nullptr);
jassert (startSample >= 0 && startSample + numSamples <= buffer->getNumSamples()); 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, 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 the buffer's floating-point format, and will try to intelligently
cope with mismatches between the number of channels in the reader cope with mismatches between the number of channels in the reader
and the buffer. 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 startSampleInDestBuffer,
int numSamples, int numSamples,
int64 readerStartSample, 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); const ScopedLock sl (lock);
nextReadPosition = startSampleInFile; nextReadPosition = startSampleInFile;
bool allSamplesRead = true;
while (numSamples > 0) while (numSamples > 0)
{ {
if (auto block = getBlockContaining (startSampleInFile)) if (auto block = getBlockContaining (startSampleInFile))
@@ -79,6 +81,8 @@ bool BufferingAudioReader::readSamples (int** destSamples, int numDestChannels,
startOffsetInDestBuffer += numToDo; startOffsetInDestBuffer += numToDo;
startSampleInFile += numToDo; startSampleInFile += numToDo;
numSamples -= numToDo; numSamples -= numToDo;
allSamplesRead = allSamplesRead && block->allSamplesRead;
} }
else else
{ {
@@ -88,6 +92,7 @@ bool BufferingAudioReader::readSamples (int** destSamples, int numDestChannels,
if (auto* dest = (float*) destSamples[j]) if (auto* dest = (float*) destSamples[j])
FloatVectorOperations::clear (dest + startOffsetInDestBuffer, numSamples); FloatVectorOperations::clear (dest + startOffsetInDestBuffer, numSamples);
allSamplesRead = false;
break; break;
} }
else 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) BufferingAudioReader::BufferedBlock::BufferedBlock (AudioFormatReader& reader, int64 pos, int numSamples)
: range (pos, pos + 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 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; Range<int64> range;
AudioBuffer<float> buffer; AudioBuffer<float> buffer;
bool allSamplesRead = false;
}; };
int useTimeSlice() override; int useTimeSlice() override;


Loading…
Cancel
Save