Reading sections of a FLAC sometimes comes back empty

Hey all,

I’m working on a sampler that saves the audio data for each preset in one FLAC file. Each sound instance then reads its portion of the file into memory when the plugin loads.

However, I’m finding that lots of the sound instances end up with empty buffers.

Here’s the code that does the reading:

	auto reader = audioFormatManager.createReaderFor(monolithFile);
	data.reset(new juce::AudioBuffer<float>(reader->numChannels, length));
	reader->read(data->getArrayOfWritePointers(), reader->numChannels, monolithStartSample, length);

	this->maxSample = data->getMagnitude(0, length);
	if (maxSample == 0)
		DBG("empty buffer");

the FLAC file in question absolutely contains audio data between monoStart and monoStart + length.

Also, it seems like it’s always the same sections of the file which end up with empty buffers. This file, for example,

fails 720000 - 1440000
fails 1440000 - 2160000
fails 2160000 - 2501808
succeeds 2501808 - 2669328
fails 2669328 - 3389328

There are no problems if I read the entire file into memory first and then copy the various sections into each instance’s buffer. Do I need to reset the FLAC reader’s state or something?

Never worked with flac files in JUCE, but here is an example code I used for reading and writing wav files. At least the readAudioFile() function should also work with flacs.

void readAudioFile(AudioSampleBuffer& buffer, juce::File file)
{
    buffer.clear();
    std::unique_ptr<juce::AudioFormatReader> reader (formatManager.createReaderFor (file));
    if (reader.get() != nullptr)
    {
        buffer.setSize(reader->numChannels, reader->lengthInSamples);
        reader->read(&buffer, 0, reader->lengthInSamples, 0, true, true);
    }
}
void writeAudioFile(AudioSampleBuffer& buffer, juce::File newFile)
{
    WavAudioFormat format;
    std::unique_ptr<AudioFormatWriter> writer;
    writer.reset (format.createWriterFor (new FileOutputStream (newFile),
                                          44100.0,
                                          buffer.getNumChannels(),
                                          32,
                                          {},
                                          0));
    if (writer != nullptr)
        writer->writeFromAudioSampleBuffer (buffer, 0, buffer.getNumSamples());
}

it seems like you have some mistakes in the read function:

void read (AudioBuffer< float > *buffer, int startSampleInDestBuffer, int numSamples, int64 readerStartSample, bool useReaderLeftChan, bool useReaderRightChan)

so if you want to read a portion of a file, the code should look like (coded out of my head, not tested):

void readAudioFile(AudioSampleBuffer& buffer, juce::File file, int startSample, int lastSample)
{
    buffer.clear();
    std::unique_ptr<juce::AudioFormatReader> reader (formatManager.createReaderFor (file));
    if (reader.get() != nullptr)
    {
        int bufferSize = lastSample - startSample;
        buffer.setSize(reader->numChannels, bufferSize);
        reader->read(&buffer, 0, bufferSize , startSample, true, true);
    }
}

Hey @imagiro,

It looks like this issue may be related to a bug I’ve just filed on GitHub related to random access (seeking) of FLAC files. You might be able to try patching the code as listed in the above-linked GitHub issue, which might fix the issue if you’re using JUCE 7.0.3 or higher.