That was a nice birthday present! I was worried I was going to spent the entire day, plus the past few days, trying to figure this out. So close now to finishing my synth! Last thing this is to save and load presets!
Ok done adding all my synth parameters, along with some gui settings in the set/getStateInformation, using your above example.
Final thing is I need to store my 8 tone generatorās wavetables each of 4096 floats, as these tables in many cases would have been edited (changed) by the user. What would be the easiest way to do that, working off your above example, and yes I figure that I do not want to store these tables as XML.
You donāt have to use XML. You can always just stream the values out in order after your XML is written to the stream. Thatās not as flexible as using XML, but saves a lot of overhead you donāt need. Maybe stream the size of the arrays (count, 4096 in your case) first, just in case it changes?
I would rather use base64 encoding of the wavetable and embed it in the XML.
Only drawback is, that base64 is int8, and your wavetable is probably in floats. But that is also solvable.
It seems unnecessary to store all 4,000-some values of each wavetable. How were these wavetables originally generated? If itās based on some kind of deterministic equation, then you can just save the equation and the size of the table with your state info, and to restore just recalculate values based on the equation and table size.
If the user can edit the wavetables, then you can use a technique such as B-splines to reverse engineer an equation that fits whatever arbitrary curve the user has created. The other advantage of this approach is it would allow you to change the table size while preserving the original shape of the curve.
@Mrugalla knows a lot about B-splines if you want more info on that!
You obviously have not seem my YouTube video demo in earlier posts. My synth has ways to create literally millions of weird waveform via an advanced waveform creator, plus a manual fine tune editor, so no I have to save them.
Unless itās literally 4,000 random points generated by white noise, Iād be willing to bet that no matter how weird the shape is, there exists a mathematical equation that can model it accurately and reproducably.
Youāre on, how much? But keep in mind that via a manual editor, user can select whole or part of the table, and then move, flip, bit reduce, jagging, smooth, distort, or take that particular part and go to my waveform creator and for that selected edit part create one of millions of waveforms. Sure I could record the userās steps, but missa thinks it will be a lot easier to just save the waveforms.
i think you mixed up b-splines with cubic bezier curves. i didnāt finish the b-spline-thing. anyway. my ideas for this wavetable problem are:
a) save them as wav-files in some folder, just like it is done in serum. that also makes them exchangable with other synths, something users enjoy a lot.
b) actually find the polynom that describes the curve whenever it has to be saved and use the polynom to construct it when loaded. maybe that functionality would even open up new other feature possibilities
surge ships wavetables as standalone files for browsing and can browse both factory and user wavetables in this way. Even our wavetables which are formula specified are saved as binaries (right now).
but if you use them in a patch it streams the binary into the patch, so patches are transportable across machines with different wavetable libraries.
we actually save it as a binary blob (we donāt use the JUCE parameter mechanism to save) but storing the binary wavetable in our patch file, although it leads to bigger patches, results in well working sharable patch documents.
(We also allow export to wav of a wavetable and try to support the various RIFF tagging mechanisms that the various wt synths use and have a format for files which isnāt wav which matches the bigwig wt oscillator and stuff).
Here is the Youtube video link, as promised, demonstrating a bit of my synth, and in particular preset selection, creation, and importing wavetable waveforms, and then manipulate part or all of the waveform.
By the way, a free download of this synth, in a sandbox (no saving or loading) version will be available very soon!
Iām guessing even if you were able to define a polynomial that would express the waveforms perfectly, it would be a lot of work up front, and would trading some time to recompute them versus some added space in the data. For a really large amount of data, we sometimes write it to an external file so as not to bloat the data too much (but that requires the user to migrate that file if they migrate the session, and not all hosts provide a way to know where the session is so you can write the file there). Otherwise, we stream to a buffer/buffers, and use 64-bit-encoding to put that/them into the XML.
Even the simplest attempt to manually use MemoryOutputStream to write and MemoryInputStream to read fails, so I am missing something, doing something wrong.
End of my getStateInformation
void MutineerAudioProcessor::setStateInformation (const void* data, int sizeInBytes)
...
// Above all my audio parameters and xml converted gui settings.
copyXmlToBinary (*xml, destData);
MemoryOutputStream (destData, true).writeInt (wavetableSize);
I checked the Reaper stored the ārppā file, and I can see that something is added in the section that stores my synth state, however when I attempt to read it back in setStateInformation, it is garbage.
void MutineerAudioProcessor::setStateInformation (const void* data, int sizeInBytes)
{
// Retrieving audio parameters and xml converted gui settings up here
....
parameters.replaceState (ValueTree::fromXml (*xmlState));
// Reads invalid, garbage value
wavetableSize = MemoryInputStream (data, sizeof(int), false).readInt ();
}
I tried using āstd::to_stringā and then xml->setAttribute to write the data which works fine, but I am having difficulty using std:stof to read it back,
Hey, super nice synth, congratulations! Itās looking and sounding good and I can very much imagine using it!
As to what @benvining suggested: itās actually not so unrealistic at all. Itās amazing what some seemingly simple equations can achieve. Although itās easier to just save the wavetable as a binary (and itās probably what I would do) it might be interesting to look into what he suggested at some point, even if just as an intellectual exercise. Perhaps it can be useful for something else. Hereās a video which demonstrates the general idea quite well. Truly fascinating stuff!