Presets
No presets implemented yet, but I'm thinking about it.
Memory limitations - I'm working with a 128KB EEPROM, half of which I am reserving for software loads. The main memory is only 16KB so 4 loads, or a single load 4x larger, could conceivably fit in that half. This leaves 64KB for presets and the like. What makes up a preset? A preset is basically a group of parameters that get written from EEPROM to various RAM locations when loading a preset, and vice versa when storing a preset.
Parameter sizing - What is a parameter? A bunch of things actually. At the lowest level it's the current "position" of the associated encoder. There may be manipulation of it in order to use it in the code (filter frequency, audio mix, etc.). Finally, it may require yet more manipulation in order to display it in a convenient human readable form (decimal Hz for example) which includes a text label prefix. (It's really too bad we somehow picked base 10 for our numbering system. Base 4 makes much more sense, and would have relieved us all from the drudgery of memorizing times tables, long division, etc.)
For efficiency of storage, what's the smallest practical number the lowest level parameter can be? I'm thinking unsigned byte here. Even though the encoders employ code that senses velocity, spinning a knob from 0 to 255 is perhaps about as much as I'd want to do for any single setting adjustment. Thinking about specific applications, and given an upper frequency limit of ~8kHz and a lower of maybe 8Hz gives a span of 10 octaves, dividing this by 255 means we can specify 1/25th of an octave, or ~1/2 note, which seems fine enough resolution for most things. I'm thinking unsigned because it's easy to check over/underflow, and most parameters values are used unsigned by their code.
Parameter forms - What converts the lowest level parameters to a useful form by the code? Currently I'm doing this in the code itself, though that's kind of clunky and slow for code in the DSP critical path. I have a separate thread which deals with the encoders and updates the associated parameters, but it could also be handling this conversion. Finally, what converts the parameters to display values and strings? I'm also doing this on a separate thread.
I'm currently grouping the lowest level parameter, its upper and lower limits (all 16 bit values), and its string label in a single blob. These blobs are grouped together for a single screen, but otherwise are located all over the code. This requires a striding function to return a pointer to the base of the indexed blob, but once the pointers get one or two deep I can barely keep straight what's going on.
Normalization - I'm thinking of defining specific types of parameters (yes/no flag, unsigned limited to 1 thru 15 forms, unsigned limited to (2^n)-1, etc.) and then having a byte "type" dictating how they are to be interpreted to both real values in the code (stored as a 32 bit) and for display (stored as a 32 bit pointer to a string). The type byte, real value, and string pointer are fixed in the code, with only the low level parameter byte needing to be stored in preset memory.
There are only 8 screens so far, with max 7 parameters, so 56 bytes tops per preset. We could have a thousand presets, which is way more than I anticipate implementing.
System parameters - There are parameters that shouldn't be updated with the preset system, and these are things like volume and pitch linearization, sensitivity, and offset; mains frequency (for the hum CIC filter); etc. I'm still thinking about how to handle these, perhaps only storing them when performing an auto-calibration of the axes or similar, and only recalling them at power-up.
Auto parameters - Should the instrument track all user activity and store this in EEPROM in real time, so that any playing around is remembered through power cycles? I'm not sure. It seems like a handy thing, but users often rely on power cycles to clear situations that are causing them trouble.
Default preset - I'm thinking preset 0 should always load at power-up.
Factory vs. user presets - Often there are factory preset regions and user preset regions. Sometimes you can write over the factory presets. And there is almost always a way to reset things back to 100% factory settings.
External editors and preset storage - Lots of instruments have PC or tablet software you can run that accesses the parameter system, which can provide easier editing and preset storage / updating / trading with others, etc. I don't really like external editors. Sure they're convenient, but they invite laziness with the development of the native instrument UI , and they (and their electrical interfaces) tend to go out of style pretty quickly (try to run and connect even a 10 year old editor on anything to anything).