Bug in AudioFormatReader::read


#1

Hi!

I think there is a bug in the AudioFormatReader::read() function. I have checked this with the latest version of the file juce_AudioFormatReader.cpp.

When using AudioFormatReader::read() with a negative value of startSampleInSource and fillLeftoverChannelsWithCopies=true, not all samples are copied to the leftover channels.

Because startSampleInSource is negative, the value of numSamplesToRead is reduced by the amount of silence in the beginning as less samples have to be read from the source. But when the leftover channels are copied or cleared, that reduced number of samples is also used. So that amount of samples is missing in the end of the leftover channels.

My suggestion is:

Add

int originalNumSamplesToRead = numSamplesToRead;

in the beginning of the fuction and change

if (numDestChannels > (int) numChannels)
{
    if (fillLeftoverChannelsWithCopies)
    {
(...)
        if (lastFullChannel != nullptr)
            for (int i = (int) numChannels; i < numDestChannels; ++i)
                if (destSamples[i] != nullptr)
                    memcpy (destSamples[i], lastFullChannel, sizeof (int) * (size_t) numSamplesToRead);
    }
    else
    {
        for (int i = (int) numChannels; i < numDestChannels; ++i)
            if (destSamples[i] != nullptr)
                zeromem (destSamples[i], sizeof (int) * (size_t) numSamplesToRead);
    }
}

to

if (numDestChannels > (int) numChannels)
{
    if (fillLeftoverChannelsWithCopies)
    {
(...)
        if (lastFullChannel != nullptr)
            for (int i = (int) numChannels; i < numDestChannels; ++i)
                if (destSamples[i] != nullptr)
                    memcpy (destSamples[i], lastFullChannel, sizeof (int) * (size_t) originalNumSamplesToRead);
    }
    else
    {
        for (int i = (int) numChannels; i < numDestChannels; ++i)
            if (destSamples[i] != nullptr)
                zeromem (destSamples[i], sizeof (int) * (size_t) originalNumSamplesToRead);
    }
}

 

Best Regards,

Gregor


#2

Ah, good catch, thanks! Will get that sorted out right away!