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:
parent
2bca60e52c
commit
7c22fae8c7
4 changed files with 65 additions and 49 deletions
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -66,6 +66,7 @@ private:
|
|||
|
||||
Range<int64> range;
|
||||
AudioBuffer<float> buffer;
|
||||
bool allSamplesRead = false;
|
||||
};
|
||||
|
||||
int useTimeSlice() override;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue