Is it possible to save to a .WAV file the contents of my audioBuffer?

I have my own audioBuffer vector which contains a copy of the incoming buffer audio from the processBlock().

I’d like to write this out to a .WAV file (after the plugin has stopped running obviously), perhaps in the destructor, or another appropriate function… is this possible ?

Not necessarily looking for a Save Dialog to pop up, I know the path and name of the .WAV file I’d like outputted to.

Absolutely possible! If you want to write audio to a file, you should probably use the WavAudioFormat class. Then all you need to do is make a FileOutputStream and write the audio to it.

Let us know if you have any trouble getting this working. Best of luck!

thanks, I did find this in the Juce docs and I think this fits:

bool AudioFormatWriter::writeFromAudioSampleBuffer	(	const AudioBuffer< float > & 	source,
int 	startSample,
int 	numSamples 

I think that might be a good start. I am searching for some example code but not finding much so far.

I did find this on another thread:

auto fileStream = std::unique_ptr (file.createOutputStream());
WavAudioFormat wavFormat;
auto writer = wavFormat.createWriterFor (fileStream.get(), sampleRate, 1, 16, {}, 0);

that would get my filestream initialized I think.

I did some hunting on Github and found this. Seems like what I am looking for.
Where output is audioBuffer<float> I assume.

Save To File From Buffer

void saveOutput()
    File outputFile("/Users/nammick/Desktop/analysis1.wav");
    auto outStream = outputFile.createOutputStream();
    // in real code you must check whether the stream is null before continuing
    WavAudioFormat format;
    std::unique_ptr<AudioFormatWriter> writer (format->createWriterFor(outStream, 44100, output.getNumChannels(), 32,nullptr, 0));
    // again, you need add a check for a nullptr here
    writer->writeFromAudioSampleBuffer(output, 0, output.getNumSamples());

I’ll need to close the file. I assume I need to destroy outStream somewhere too(?)

This looks pretty good. Remember that these variables are declared within the function saveOutput(), so they will be destroyed when the function exits. outStream is a unique_ptr, so it will be destroyed too.

You only need to worry about destroying things manually in C++ if you made them with new (which you probably should avoid) or you used something particularly wonky.

note that the mentions of nullptr checks in those comments are referring to different objects. outStream needs to be checked like this:
if (! outStream) return;
which exits the method if the stream couldn’t be created. Instead of return you could put something more helpful like writing a debug message or something more specific.

Second, you need to check that the writer was made correctly, which looks like if (! writer) return; for the same reason.


thanks… he is using
File outputFile
Thats not working for me even if I include <stdio.h> and <fstream>.
Can I use std::ofstream outputFile instead? I assume so, just wanted to make 100% sure.

In this case File is juce::File so you’ll need to include JUCE to use it. You cannot substitute std::ofstream for juce::File.

Thanks, that worked.
My final error is this:

Its format. I tried juce::WavAudioFormat * format; as the * makes it pointer, and writer(juce::WavAudioFormat format->create...
but they didn’t work. Any ideas?

Try “format.” instead of “format->”. It’s not a pointer, and just making it a pointer for no other reason would mean you’d have to explicitly use new/delete on it.

thanks, I did try that earlier actually, but it gave me this message

outStream is a std::unique_ptr, isn’t it? If so, it needs to say outStream.get() there. Also, I think you need to pass {}, not nullptr, for that next-to-last parameter. It expects a reference, not a pointer.

Aha, I think we’re there. This is giving me no errors in compilation now.

juce::File outputFile("C:/myfile.wav");
std::unique_ptr<juce::FileOutputStream> outStream;
outStream = outputFile.createOutputStream();
juce::WavAudioFormat format;
std::unique_ptr<juce::AudioFormatWriter> writer;
writer.reset(format.createWriterFor(outStream.get(), 44100, 2, 32, {}, 0));

I hope that writer.reset is appropriate.