Save an AudioBuffer to Xml


I need to save an AudioBuffer to a XmlElement, so I was wondering if there is some way to that similar to this one related to saving an Image:

MemoryOutputStream out;
PNGImageFormat format;

format.writeImageToStream(map, out);
juce::MemoryBlock pngData(out.getData(), out.getDataSize());

mapXml->setAttribute("MapImage", pngData.toBase64Encoding());

Is there any way to do this? Thanks in advance for any kind of help!
Best Regards,

Okay so I have tried this solution:

For Saving:

        MemoryOutputStream out;
	WavAudioFormat format;
	AudioFormatWriter* writer = format.createWriterFor(&out, 48000, 1, 16, StringPairArray(), 0);
	writer->writeFromAudioSampleBuffer(impulseResponse, 0, impulseResponse.getNumSamples());

	juce::MemoryBlock wavData(out.getData(), out.getDataSize());
	parentXml->getChildByName("ImpulseResponse")->setAttribute("AudioFile", wavData.toBase64Encoding());

And loading back:

               if (wavData->fromBase64Encoding(parentXml->getChildByName("ImpulseResponse")->getStringAttribute("AudioFile")))

		MemoryInputStream in(wavData->getData(), wavData->getSize(), false);
		WavAudioFormat format;
		AudioFormatReader* reader = format.createReaderFor(&in, false);

		impulseResponse.setSize(1, reader->lengthInSamples);
		reader->read(&impulseResponse, 0, reader->lengthInSamples, 0, true, true);

But apparently reader->lengthInSamples is always 0 so I dont get my buffer as it should. Is this the right way to do it or I am skipping something?

Nobody had some experience with this? :frowning:

Your problem is, that the writer does not finish, because it is leaking.
The length of a wav file will be written into the header, when the writer object is destroyed.

Best practice is to put the writer into a unique_ptr:

MemoryBlock wavData;
    // MemoryOutputStream is owned, if the writer was created successfully
    std::unique_ptr<AudioFormatWriter> writer (format.createWriterFor (new MemoryOutputStream (wavData, false), 48000, 1, 16, StringPairArray(), 0));
    writer->writeFromAudioSampleBuffer(impulseResponse, 0, impulseResponse.getNumSamples());
    // end of scope flushes the writer
auto response = parentXml->getChildByName ("ImpulseResponse");
if (response)
    response->setAttribute ("AudioFile", wavData.toBase64Encoding());

Hope that helps

Sorry for the late answer! That works like a charm, thank you very much! Cheers :slight_smile: