Saving MIDI CC assignments in user presets?
-
@dannytaurus said in Saving MIDI CC assignments in user presets?:
Launch the plugin - load the CC mappings from separate file
Handled here, no?
-
@David-Healey Maybe, yes.
-
@dannytaurus @David-Healey Can't the CC mapping simply be removed from the preset using the handler? Isn't the custom preset intended for this purpose in the first place? Never tried myself that being said...
-
@David-Healey Apparently not.
There are 3 HISE restore points that run after
onInit, so it still needs handling.From Claude:
Fresh instance in a DAW:
FrontendProcessor::restorePluginrunscompileAllScripts()(your onInit applies the file) and then restores the
MidiAutomation node from the embedded project state (FrontEndProcessor.cpp:458). The export always writes that node ā even when empty,exportAsValueTreeadds it unconditionally ā so a fresh instance immediately clears the mappings you just loaded. Your file-load is defeated before the user ever touches the plugin.Reopening a session: the host calls
setStateInformationat some point after instantiation (host-dependent timing), andFrontEndProcessor.cpp:576restores the session's stale mapping copy over whatever onInit applied.In the editor: every project load stashes the project XML's
<MidiAutomation/>and applies it after script compilation (MainController.cpp:562/577)
ā same wipe while you're developing. -
@ustk Not sure. To be honest, I just want all the 'CC data in presets' code out of my fork.
Might just drop the preprocessor and remove it all directly.
I can't see a situation where I would ever want CC data in the presets. So a preprocessor is only useful for backwards compatibility, which I don't have any of

-
I think this is what the custom user preset model is for: https://docs.hise.dev/scripting/scripting-api/userpresethandler/index.html#setusecustomuserpresetmodel
Haven't tried it myself.
-
@David-Healey Lol
@ustk said in Saving MIDI CC assignments in user presets?:
@dannytaurus @David-Healey Can't the CC mapping simply be removed from the preset using the handler? Isn't the custom preset intended for this purpose in the first place? Never tried myself that being said...
Just checked and the answer is no, you can't manage what is written... But Claude came with a neat solution:
// (processBeforeLoading, unpackComplexData) uph.setEnableUserPresetPreprocessing(true, false); uph.setPreCallback(function(presetData) { // presetData is a JS object; MidiAutomation is a top-level property. // Emptying it means applyJSON rebuilds an empty <MidiAutomation> node, // so the incoming preset never overwrites the current CC assignments. presetData.MidiAutomation = {}; // or just rewrite what you already saved }); -
@David-Healey @David-Healey So the working solution is
const var currentAutomationState = {"ChildId": "Controller", "Children": []}; const var mah = Engine.createMidiAutomationHandler(); mah.setUpdateCallback(function() { currentAutomationState.Children = this.getAutomationDataObject(); }); const var uph = Engine.createUserPresetHandler(); uph.setEnableUserPresetPreprocessing(true, false); uph.setPreCallback(function(presetData) { presetData.MidiAutomation = currentAutomationState; });The automation state is saved in the instance but you can just save it in a file if you wish so.
I'd prefer not in my case, because if you load multiple instances of the plugin, they'll all react to the same CC... -
@ustk said in Saving MIDI CC assignments in user presets?:
const var currentAutomationState = {"ChildId": "Controller", "Children": []};
Does this store MPE and Macro assignments too?
-
@David-Healey Apparently macro yes, but MPE

Here's the automation data object:[ { "Controller": 6, "Channel": -1, "Processor": "Interface", "MacroIndex": -1, "Start": 0.0, "End": 1.0, "FullStart": 0.0, "FullEnd": 1.0, "Skew": 3.106283926937945, "Interval": 0.0, "Converter": "37.nT6K8CBGgC..VEFa0U1Pu4lckIGckIG.ADPXiQWZ1UF.ADf...", "Attribute": "HiBoostBWKnb", "Inverted": false } ] -
@David-Healey Just tested with my seaboard and yes, it works for MPE that have been MIDI learnt (Since it's just MIDI in the end...)
-
@ustk said in Saving MIDI CC assignments in user presets?:
I'd prefer not in my case, because if you load multiple instances of the plugin, they'll all react to the same CC...
That's a very interesting point!
EDIT: actually, maybe it's fine. The DAW will only send MIDI CC to the active plugin, right?
-
@dannytaurus If by inactive you mean hidden UI, then Midi is still reaching them
-
@ustk A DAW will only route incoming live controller messages to the active or record-armed track(s), surely?
So if I have 3 different synths all set to respond to mod wheel > filter, then only the active one will respond when I turn the mod wheel, right?
Regardless of whether the synth UI is visible or hidden. It's based on active tracks, right?
The other 2 'unselected', 'inactive', 'not record-armed' synths won't respond to live controller data
Otherwise there would be chaos! Unless that's what you wanted, and armed ALL tracks for record!

-
@dannytaurus Oh yes absolutely, active in the sense of "armed track", then 100% yes

-
@ustk Yes, 'active' is too ambiguous a word to have used in the first place. My bad.
-
@dannytaurus The honour of badness is mine

-
@ustk said in Saving MIDI CC assignments in user presets?:
So the working solution is
I think there's more to it, at least if you're saving/loading it from a file.
setUpdateCallback is triggered before
on initandsetPreCallbackis only triggered when loading a preset.So we need it to be that when we make a change to automation we save the the object to a file.
Then at init we load that object from the file usingsetAutomationDataFromObject
And during preload we pass the object into preset data.