Issues using AudioFormatWriter

I am trying to use AudioFormatWriter to write an AudioBuffer to a WAV file. My program runs fine until I close out the window, at which point an exception is triggered. An output file is created, but it contains no audio.

Here’s what I declared in my MainComponent header file:

    juce::File outputFile{ "c:/tmp/out.wav"};
    juce::FileOutputStream outputStream{ outputFile };

    juce::WavAudioFormat wavFormat;
    juce::AudioFormatManager formatManager;
    juce::StringPairArray metaData;
    juce::AudioFormatWriter* writer;

In the MainComponent constructor:

    formatManager.registerBasicFormats();
    metaData = juce::WavAudioFormat::createBWAVMetadata("", "", "", juce::Time::getCurrentTime(), 0, "");
    writer = wavFormat.createWriterFor(&outputStream, sampleRate, 2, 16, metaData, 0);

In the getNextAudioBlock() member function:

    if (recordEnabled)
        writer->writeFromAudioSampleBuffer(*bufferToFill.buffer, 0, bufferToFill.numSamples);

Running this code, the exception I ran into was in “juce_LeakedObjectDetector.h”.

It seems like what I need to do is to delete the pointer to AudioFormatWriter. I tried calling “delete writer” in the releaseResources() function, but that just caused a delete operator exception to be thrown.

I also tried making the pointer to AudioFormatWriter a unique pointer, like so (after declaring it as a unique_ptr in the header of course):

    writer = std::make_unique<juce::AudioFormatWriter>(*wavFormat.createWriterFor(&outputStream, sampleRate, 2, 16, metaData, 0));

That just got me the following errors:

What am I missing? It can’t be that difficult to just write to a WAV file in JUCE. There should really be a tutorial on this.

Regarding the std::unique_ptr issue, you can’t use std::make_unique in this case.

You need to do something like :

writer.reset(wavFormat.createWriterFor(&outputStream, sampleRate, 2, 16, metaData, 0));

Note that also the unique_ptr needs to be nulled/resetted at some point, if you want the writer to finish its operations. (You could use a simple writer.reset() for that.)

However, I suspect that is not going to work for you, either, since you also got the somewhat odd error when trying to do manual memory management.

You also need to delete the output file before trying write into it. Otherwise you risk just appending new data into an already corrupted file.

And yes, trying to write a simple WAV file can be a bit involved with Juce, especially when you need to split the operations across several class methods and when there are multiple threads involved.

Xenakios, thank you for the tips. As you suspected, when I tried using .reset(), I got the same error as when I tried to manually manage the memory.

Maybe it’s because I need to close the file output stream before deleting the writer? If I were using standard I/O I’d use a function like fclose(). But in the documentation, I don’t see any method for closing a JUCE output stream.