# Embedding audio in get/setStateInformation

**URL:** <https://forum.juce.com/t/embedding-audio-in-get-setstateinformation/26326>\
**Category:** Audio Plugins\
**Created:** [February 8, 2018, 9:52pm UTC](https://forum.juce.com/t/embedding-audio-in-get-setstateinformation/26326 "2018-02-08T21:52:47Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![slegs](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/slegs/32/3037_2.png) [@slegs](https://forum.juce.com/u/slegs)\
**Post date:** [February 8, 2018, 9:52pm UTC](https://forum.juce.com/t/embedding-audio-in-get-setstateinformation/26326/1 "2018-02-08T21:52:47Z")

</div>

Hey y’all. I am trying to embed a very small audio file in the plugin data that is stored and reloaded in get/savestateinformation. I’m converting the audio to a base 64 encoding, writing it to an attribute within the XML that contains my AudioProcessorValueTreeState, and then reloading it and converting it back from base 64. However, whenever I load the audio in setStateInformation, the AudioFormatReader reads that the audio is of 0 length, even though the size of the encoded strings, MemoryBlocks and the original AudioSampleBuffer are all consistent. I have also tried the Base64 standard encoding as well and I get the same results.  
I am doing so the following way:

originalData is an AudioSampleBuffer containing the audio I would like to save

```auto
getStateInformation(MemoryBlock& destData) {
   XmlElement xml ("MYPLUGINSETTINGS");
   ...
   add other attributes
   ...
   MemoryOutputStream audioMemory (originalData->getNumSamples());
   if (AudioFormatWriter* writer = getCorrectAudioFormatWriter(&audioMemory)) {
       writer->writeFromAudioSampleBuffer(*originalData, 0, originalData->getNumSamples());
       MemoryBlock audioMemoryBlock = audioMemory.getMemoryBlock();
       String base64AudioData = audioMemoryBlock.toBase64Encoding();
       xml.setAttribute(settingAudioData, base64AudioData);
   }
   ...
   copyXmlToBinary (xml, destData);
}

setStateInformation (const void* data, int sizeInBytes) {
   ScopedPointer<XmlElement> xmlState (getXmlFromBinary (data, sizeInBytes));
   ...
   extract other attributes
   ...
   String retrievedAudioData = xmlState->getStringAttribute(settingAudioData);
   MemoryBlock retrievedAudioMemoryBlock;
   retrievedAudioMemoryBlock.fromBase64Encoding(retrievedAudioData);
   MemoryInputStream* stream = new  
   MemoryInputStream(retrievedAudioMemoryBlock.getData(), 
   retrievedAudioMemoryBlock.getSize(),true);
   reloadSynth(false, stream);
}

```

Do y’all have any ideas? Thank you!

---

<div class="post-metadata">

**Author:** ![daniel](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/daniel/32/790_2.png) [@daniel](https://forum.juce.com/u/daniel)\
**Post date:** [February 8, 2018, 9:59pm UTC](https://forum.juce.com/t/embedding-audio-in-get-setstateinformation/26326/2 "2018-02-08T21:59:06Z")

</div>

Would you mind adding three backticks ````` before and after your code?  
Then the code appears formatted and easier readable…

Thanks

And to your problem: I don’t know anything about your `getCorrectAudioFormatWriter ()` function, but I assume it creates an AudioFormatWriter on the heap. This will write it’s length when calling flush or when the AudioFormatWriter is destroyed. Since you are leaking the writer, the length is never updated…

Just a guess…

---

<div class="post-metadata">

**Author:** ![slegs](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/slegs/32/3037_2.png) [@slegs](https://forum.juce.com/u/slegs)\
**Post date:** [February 8, 2018, 10:03pm UTC](https://forum.juce.com/t/embedding-audio-in-get-setstateinformation/26326/3 "2018-02-08T22:03:32Z")

</div>

edited, thank you I’m still pretty new!

---

<div class="post-metadata">

**Author:** ![daniel](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/daniel/32/790_2.png) [@daniel](https://forum.juce.com/u/daniel)\
**Post date:** [February 8, 2018, 10:06pm UTC](https://forum.juce.com/t/embedding-audio-in-get-setstateinformation/26326/4 "2018-02-08T22:06:26Z")

</div>

Thanks, that looks better 🙂

Ideally you put the `AudioFormatWriter` into a ScopedPointer and let it go out of scope before you call `audioMemoryBlock.toBase64Encoding()`…

---

<div class="post-metadata">

**Author:** ![slegs](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/slegs/32/3037_2.png) [@slegs](https://forum.juce.com/u/slegs)\
**Post date:** [February 8, 2018, 10:25pm UTC](https://forum.juce.com/t/embedding-audio-in-get-setstateinformation/26326/5 "2018-02-08T22:25:39Z")

</div>

I tried to make your suggested changes and now **audioMemory** is being deleted prematurely and I am getting ‘pointer being freed was not allocated’ in the console. I’ll include getCorrectAudioFormatWriter below:

`audioFile` is the File that corresponds with originalData

```auto
AudioFormatWriter* SMPLRAudioProcessor::getCorrectAudioFormatWriter(OutputStream* out)
{
    if (audioFile.hasFileExtension(".wav")) {
            WavAudioFormat wav;
            if (AudioFormatWriter* writer = wav.createWriterFor(out, getFileSampleRate(),
                (originalData->getNumChannels() == 2 ? AudioChannelSet::stereo() : AudioChannelSet::mono()), 16, nullptr, 0))
            {
                return writer;
            }
        }
    ...
    handle other extensions
    ...
}

```

Is this an incorrect way to generate an AudioFormatWriter? I think the error that is happening now is because **writer** is using **audioMemory** and when I delete **writer** and try to run `audioMemoryBlock.toBase64Encoding()`, it’s already deleted

---

<div class="post-metadata">

**Author:** ![daniel](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/daniel/32/790_2.png) [@daniel](https://forum.juce.com/u/daniel)\
**Post date:** [February 8, 2018, 10:43pm UTC](https://forum.juce.com/t/embedding-audio-in-get-setstateinformation/26326/6 "2018-02-08T22:43:04Z")

</div>

Indeed, the AudioFormatWriter docs say:

> Parameters  
> destStream: the stream to write to - this will be deleted by this object when it is no longer needed

So you cannot use the MemoryOutputStream like that. In this case it has to be on the heap.

This should work (not tested):

```auto
MemoryBlock audioMemory;
{
    auto* output = new MemoryOutputStream (audioMemory);
    ScopedPointer<AudioFormatWriter> writer = getCorrectAudioFormatWriter (output);
    if (writer)
        writer->writeFromAudioSampleBuffer (*originalData, 0, originalData->getNumSamples());
    // closing the scope causes the writer to flush which will delete the MemoryOutputStream
}
xml.setAttribute (settingAudioData, audioMemory.toBase64Encoding());

```

Good luck

Edit: on a separate note: I think it is not necessary to put your plugin data in XML, it is handy if you want to inspect the data though. You could write directly into the block, since the host allows binary data here. It is up to you how you serialise your data… but XML is probably the safest way, it might just add some overhead…

---

<div class="post-metadata">

**Author:** ![slegs](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/slegs/32/3037_2.png) [@slegs](https://forum.juce.com/u/slegs)\
**Post date:** [February 8, 2018, 11:25pm UTC](https://forum.juce.com/t/embedding-audio-in-get-setstateinformation/26326/7 "2018-02-08T23:25:52Z")

</div>

Heck yeah that worked!! Thank you so much @daniel I really appreciate your help. I owe you a beer 🙏
