The Red Penguin

Audio file playback in JUCE


Thursday 30 July 2020

1. We will need to add three components to private: in the MainComponent class in our MainComponent header file.
juce::AudioFormatManager formatManager;

std::unique_ptr readerSource;

juce::AudioTransportSource transportSource;

2. Go to MainComponent.cpp and to prepareToPlay. We need to tell the formatManager to register the basic audio formats. So we add:
formatManager.registerBasicFormats();

3. We then need to add the URL of the file we are going to play. This can be a local file. MYK wrote:
juce::URL audioURL{"file:///home/matthew/aon_inspired.mp3"};

but I need to work out the correct way to write this path to find the file I want! e.g.
juce::URL audioURL{ "file:///b:/tracks/aon_inspired.mp3"};

4. He then added a big chunk of code in prepareToPlay ...
auto* reader = formatManager.createReaderFor(audioURL.createInputStream(false));
if (reader != nullprt) // good file!
{
std::unique_ptr newSource (new juce::AudioFormatReaderSource(reader, true));
transportSource.setSource (newSource.get(), 0, nullptr, reader->sampleRate);
readerSource.reset (newSource.release());
transportSource.start();
}

transportSource.prepareToPlay(samplesPerBlockExpected, sampleRate);

5. We now need to get the data out of the transport source and pass it to the audio system. We can do this in getNextAudioBlock.

We remove the old MainComponent::getNextAudioBlock code from the synthesis (for reference, it's here ...)
if (!playing)
{
bufferToFill.clearActiveBufferRegion();
return;
}

auto* leftChan = bufferToFill.buffer->getWritePointer(0, bufferToFill.startSample);
auto* rightChan = bufferToFill.buffer->getWritePointer(0, bufferToFill.startSample);

for (auto i = 0; i < bufferToFill.numSamples; ++i)
{
// double sample = rand.nextDouble() * 0.25;
double sample = fmod(phase, 0.2);

leftChan[i] = sample;
rightChan[i] = sample;

phase += dphase;

}

// bufferToFill.clearActiveBufferRegion();

and add this:
transportSource.getNextAudioBlock(bufferToFill);


6. To "complete the life cycle" we need to go to releaseResources() and add:
transportSource.releaseResources();

And that's it! We build and compile and it all works!