refactored pacth import/export

This commit is contained in:
2026-05-10 16:10:51 +02:00
parent f72a89ed61
commit e9a5784ed1
3 changed files with 166 additions and 126 deletions
+122 -89
View File
@@ -184,25 +184,13 @@ int JaySynthMidiCC::findParamID_byName(String name)
return (int)paramNamedValueSet.getWithDefault (toParameterNameXML(name), var(-1));
}
void JaySynthMidiCC::exportXML(String name)
{
File file(name);
XmlElement xml ("JSYNTH_MIDICC_TABLE_FILE");
exportXML(&xml);
file.create();
xml.writeToFile (/*const File &destinationFile*/file, /*const String &dtdToUse*/"JSYNTH_MIDICC_TABLE_FILE" /*, const String &encodingType="UTF-8", int lineWrapLength=60*/);
}
void JaySynthMidiCC::exportXML(XmlElement *pXML_root) const
void JaySynthMidiCC::export_midi_cc(XmlElement *pXML) const
{
int paramID;
midiCC_container_t const *pMidiContainer;
XmlElement *pXML, *pXML_PARAM, *pXML_PARAM_INFO;
XmlElement *pXML_PARAM, *pXML_PARAM_INFO;
// Store controller and slider infos
pXML = pXML_root->createNewChildElement (String("TARGETS"));
for (paramID=0; paramID < SYNTH_NUM_PARAMS; paramID++)
{
pMidiContainer = &midiCC_containers[paramID];
@@ -212,29 +200,34 @@ void JaySynthMidiCC::exportXML(XmlElement *pXML_root) const
pXML_PARAM->setAttribute ("IS_ABSOLUTE", pMidiContainer->doChangeParameter);
pXML_PARAM->setAttribute ("DO_APPLY_ON_PATCH_INIT", pMidiContainer->doApplyOnPatchInit);
pXML_PARAM->setAttribute ("CONTROLLER_ID", pMidiContainer->controllerID);
}
}
void JaySynthMidiCC::export_midi_velkey(XmlElement *pXML) const
{
int paramID;
midiCC_container_t const *pMidiContainer;
XmlElement *pXML_PARAM, *pXML_PARAM_INFO;
// Store controller and slider infos
for (paramID=0; paramID < SYNTH_NUM_PARAMS; paramID++)
{
pMidiContainer = &midiCC_containers[paramID];
pXML_PARAM = pXML->createNewChildElement (String("PARAM_") + String(paramID));
pXML_PARAM->setAttribute ("NAME", toParameterNameXML(pMidiContainer->constraints.pName));
pXML_PARAM->setAttribute ("IS_VELOCITY_ASSIGNED", pMidiContainer->isVelAssigned);
pXML_PARAM->setAttribute ("IS_KEYFOLLOW_ASSIGNED", pMidiContainer->isKeyAssigned);
pXML_PARAM->setAttribute ("VELKEY_COMBINE_OP", pMidiContainer->velKeyCombineOP);
pXML_PARAM_INFO = pXML_PARAM->createNewChildElement (String("RELATIVE"));
// pXML_PARAM_INFO->setAttribute ("BASE", String(pMidiContainer->control.base, 10));
// pXML_PARAM_INFO->setAttribute ("KEXP", String(pMidiContainer->control.kexp, 10));
// pXML_PARAM_INFO->setAttribute ("SCENTER", String(pMidiContainer->control.scenter, 10));
pXML_PARAM_INFO->setAttribute ("PMIN", String(pMidiContainer->control.pmin, 10));
pXML_PARAM_INFO->setAttribute ("PMAX", String(pMidiContainer->control.pmax, 10));
// pXML_PARAM_INFO->setAttribute ("PINTERVAL", String(pMidiContainer->control.pinterval, 10));
pXML_PARAM_INFO = pXML_PARAM->createNewChildElement (String("ABSOLUTE"));
// pXML_PARAM_INFO->setAttribute ("BASE", String(pMidiContainer->param.base, 10));
// pXML_PARAM_INFO->setAttribute ("KEXP", String(pMidiContainer->param.kexp, 10));
// pXML_PARAM_INFO->setAttribute ("SCENTER", String(pMidiContainer->param.scenter, 10));
pXML_PARAM_INFO->setAttribute ("PMIN", String(pMidiContainer->param.pmin, 10));
pXML_PARAM_INFO->setAttribute ("PMAX", String(pMidiContainer->param.pmax, 10));
// pXML_PARAM_INFO->setAttribute ("PINTERVAL", String(pMidiContainer->param.pinterval, 10));
pXML_PARAM_INFO = pXML_PARAM->createNewChildElement (String("VELOCITY_CURVE"));
// pXML_PARAM_INFO->setAttribute ("BASE", String(pMidiContainer->curve_vel.base, 10));
pXML_PARAM_INFO->setAttribute ("KEXP", String(pMidiContainer->curve_vel.kexp, 10));
pXML_PARAM_INFO->setAttribute ("SCENTER", String(pMidiContainer->curve_vel.scenter, 10));
pXML_PARAM_INFO->setAttribute ("PMIN", String(pMidiContainer->curve_vel.pmin, 10));
@@ -242,41 +235,124 @@ void JaySynthMidiCC::exportXML(XmlElement *pXML_root) const
pXML_PARAM_INFO->setAttribute ("PINTERVAL", String(pMidiContainer->curve_vel.pinterval, 10));
pXML_PARAM_INFO = pXML_PARAM->createNewChildElement (String("KEYFOLLOW_CURVE"));
// pXML_PARAM_INFO->setAttribute ("BASE", String(pMidiContainer->curve_key.base, 10));
pXML_PARAM_INFO->setAttribute ("KEXP", String(pMidiContainer->curve_key.kexp, 10));
pXML_PARAM_INFO->setAttribute ("SCENTER", String(pMidiContainer->curve_key.scenter, 10));
pXML_PARAM_INFO->setAttribute ("PMIN", String(pMidiContainer->curve_key.pmin, 10));
pXML_PARAM_INFO->setAttribute ("PMAX", String(pMidiContainer->curve_key.pmax, 10));
pXML_PARAM_INFO->setAttribute ("PINTERVAL", String(pMidiContainer->curve_key.pinterval, 10));
}
}
/*
int JaySynthMidiCC::import_midi_velkey(XmlElement const *pXML)
{
int i, controllerID, numDst;
XmlElement *pXML_dst, *pXML_MIDICC;
int i, paramID;
midiCC_container_t *pMidiContainer;
XmlElement *pXML_PARAM, *pXML_PARAM_INFO;
// todo: romove that in future versions
pXML = pXML_root->createNewChildElement (String("CONTROLLERS"));
// Store MIDI controller assignments
for (controllerID=0; controllerID < NUM_MIDI_CONTROLLERS; controllerID++)
for (i=0; i < NUM_MIDI_CONTROLLERS; i++)
removeDestinations(i);
// make sure that it's actually our type of XML object..
if (pXML)
{
pXML_MIDICC = pXML->createNewChildElement (String("MIDICC_") + String(controllerID));
pXML_MIDICC->setAttribute ("ID", controllerID);
pXML_dst = pXML_MIDICC->createNewChildElement (String("TARGETS"));
numDst = getNumDestinations(controllerID);
for (i=0; i < numDst; i++)
pXML_PARAM = pXML->getFirstChildElement();
while(pXML_PARAM)
{
pMidiContainer = getDestination(controllerID, i);
pXML_dst->setAttribute (String("PARAM") + String(pMidiContainer->constraints.id), pMidiContainer->constraints.pName);
}
}
}
// todo: romove that in future versions
*/
paramID = findParamID_byName(pXML_PARAM->getStringAttribute("NAME"));
if (paramID < 0)
{
pXML_PARAM = pXML_PARAM->getNextElement();
continue;
}
int JaySynthMidiCC::importXML(XmlElement const *pXML_MidiCc)
pMidiContainer = &midiCC_containers[paramID];
pMidiContainer->isVelAssigned = pXML_PARAM->getIntAttribute("IS_VELOCITY_ASSIGNED", 0) != 0;
pMidiContainer->isKeyAssigned = pXML_PARAM->getIntAttribute("IS_KEYFOLLOW_ASSIGNED", 0) != 0;
pMidiContainer->velKeyCombineOP = pXML_PARAM->getIntAttribute("VELKEY_COMBINE_OP", VELKEY_OP_ADD);
pXML_PARAM_INFO = pXML_PARAM->getChildByName(String("RELATIVE"));
if (pXML_PARAM_INFO)
{
pMidiContainer->control.pmin = pXML_PARAM_INFO->getDoubleAttribute("PMIN", pMidiContainer->constraints.pmin);
pMidiContainer->control.pmax = pXML_PARAM_INFO->getDoubleAttribute("PMAX", pMidiContainer->constraints.pmax);
}
pXML_PARAM_INFO = pXML_PARAM->getChildByName(String("ABSOLUTE"));
if (pXML_PARAM_INFO)
{
pMidiContainer->param.pmin = pXML_PARAM_INFO->getDoubleAttribute("PMIN", pMidiContainer->constraints.pmin);
pMidiContainer->param.pmax = pXML_PARAM_INFO->getDoubleAttribute("PMAX", pMidiContainer->constraints.pmax);
}
pXML_PARAM_INFO = pXML_PARAM->getChildByName(String("VELOCITY_CURVE"));
if (pXML_PARAM_INFO)
{
pMidiContainer->curve_vel.kexp = pXML_PARAM_INFO->getDoubleAttribute("KEXP", 0);
pMidiContainer->curve_vel.scenter = pXML_PARAM_INFO->getDoubleAttribute("SCENTER", 0.5);
pMidiContainer->curve_vel.pmin = pXML_PARAM_INFO->getDoubleAttribute("PMIN", 0);
pMidiContainer->curve_vel.pmax = pXML_PARAM_INFO->getDoubleAttribute("PMAX", 1);
}
pXML_PARAM_INFO = pXML_PARAM->getChildByName(String("KEYFOLLOW_CURVE"));
if (pXML_PARAM_INFO)
{
pMidiContainer->curve_key.kexp = pXML_PARAM_INFO->getDoubleAttribute("KEXP", 0);
pMidiContainer->curve_key.scenter = pXML_PARAM_INFO->getDoubleAttribute("SCENTER", 0.5);
pMidiContainer->curve_key.pmin = pXML_PARAM_INFO->getDoubleAttribute("PMIN", 0);
pMidiContainer->curve_key.pmax = pXML_PARAM_INFO->getDoubleAttribute("PMAX", 1);
}
if (pXML_PARAM->getIntAttribute("IS_ASSIGNED", 0))
add(pMidiContainer, pXML_PARAM->getIntAttribute("CONTROLLER_ID", 0));
else
remove(pMidiContainer, pXML_PARAM->getIntAttribute("CONTROLLER_ID", 0));
pXML_PARAM = pXML_PARAM->getNextElement();
}
}
isModified = false;
return 0;
}
int JaySynthMidiCC::import_midi_cc(XmlElement const *pXML)
{
int i, paramID;
midiCC_container_t *pMidiContainer;
XmlElement *pXML_PARAM, *pXML_PARAM_INFO;
for (i=0; i < NUM_MIDI_CONTROLLERS; i++)
removeDestinations(i);
// make sure that it's actually our type of XML object..
if (pXML)
{
pXML_PARAM = pXML->getFirstChildElement();
while(pXML_PARAM)
{
paramID = findParamID_byName(pXML_PARAM->getStringAttribute("NAME"));
if (paramID < 0)
{
pXML_PARAM = pXML_PARAM->getNextElement();
continue;
}
pMidiContainer = &midiCC_containers[paramID];
pMidiContainer->doChangeParameter = pXML_PARAM->getIntAttribute("IS_ABSOLUTE", pXML_PARAM->getIntAttribute("DO_CHANGE_PARAMETER", 0)) != 0;
pMidiContainer->doApplyOnPatchInit = pXML_PARAM->getIntAttribute("DO_APPLY_ON_PATCH_INIT", 0) != 0;
if (pXML_PARAM->getIntAttribute("IS_ASSIGNED", 0))
add(pMidiContainer, pXML_PARAM->getIntAttribute("CONTROLLER_ID", 0));
else
remove(pMidiContainer, pXML_PARAM->getIntAttribute("CONTROLLER_ID", 0));
pXML_PARAM = pXML_PARAM->getNextElement();
}
}
isModified = false;
return 0;
}
int JaySynthMidiCC::import_midi_cc_legacy(XmlElement const *pXML_MidiCc)
{
int i, paramID;
midiCC_container_t *pMidiContainer;
@@ -289,7 +365,7 @@ int JaySynthMidiCC::importXML(XmlElement const *pXML_MidiCc)
if (pXML_MidiCc)
{
pXML = pXML_MidiCc->getFirstChildElement();
while(pXML)
if(pXML)
{
pXML_PARAM = pXML->getFirstChildElement();
while(pXML_PARAM)
@@ -312,45 +388,33 @@ int JaySynthMidiCC::importXML(XmlElement const *pXML_MidiCc)
pXML_PARAM_INFO = pXML_PARAM->getChildByName(String("RELATIVE"));
if (pXML_PARAM_INFO)
{
// pMidiContainer->control.base = pXML_PARAM_INFO->getDoubleAttribute("BASE", pMidiContainer->constraints.base);
// pMidiContainer->control.kexp = pXML_PARAM_INFO->getDoubleAttribute("KEXP", pMidiContainer->constraints.kexp);
// pMidiContainer->control.scenter = pXML_PARAM_INFO->getDoubleAttribute("SCENTER", pMidiContainer->constraints.scenter);
pMidiContainer->control.pmin = pXML_PARAM_INFO->getDoubleAttribute("PMIN", pMidiContainer->constraints.pmin);
pMidiContainer->control.pmax = pXML_PARAM_INFO->getDoubleAttribute("PMAX", pMidiContainer->constraints.pmax);
// pMidiContainer->control.pinterval = pXML_PARAM_INFO->getDoubleAttribute("PINTERVAL", pMidiContainer->constraints.pinterval);
}
pXML_PARAM_INFO = pXML_PARAM->getChildByName(String("ABSOLUTE"));
if (pXML_PARAM_INFO)
{
// pMidiContainer->param.base = pXML_PARAM_INFO->getDoubleAttribute("BASE", pMidiContainer->constraints.base);
// pMidiContainer->param.kexp = pXML_PARAM_INFO->getDoubleAttribute("KEXP", pMidiContainer->constraints.kexp);
// pMidiContainer->param.scenter = pXML_PARAM_INFO->getDoubleAttribute("SCENTER", pMidiContainer->constraints.scenter);
pMidiContainer->param.pmin = pXML_PARAM_INFO->getDoubleAttribute("PMIN", pMidiContainer->constraints.pmin);
pMidiContainer->param.pmax = pXML_PARAM_INFO->getDoubleAttribute("PMAX", pMidiContainer->constraints.pmax);
// pMidiContainer->param.pinterval = pXML_PARAM_INFO->getDoubleAttribute("PINTERVAL", pMidiContainer->constraints.pinterval);
}
pXML_PARAM_INFO = pXML_PARAM->getChildByName(String("VELOCITY_CURVE"));
if (pXML_PARAM_INFO)
{
// pMidiContainer->curve_vel.base = pXML_PARAM_INFO->getDoubleAttribute("BASE", exp(1.0));
pMidiContainer->curve_vel.kexp = pXML_PARAM_INFO->getDoubleAttribute("KEXP", 0);
pMidiContainer->curve_vel.scenter = pXML_PARAM_INFO->getDoubleAttribute("SCENTER", 0.5);
pMidiContainer->curve_vel.pmin = pXML_PARAM_INFO->getDoubleAttribute("PMIN", 0);
pMidiContainer->curve_vel.pmax = pXML_PARAM_INFO->getDoubleAttribute("PMAX", 1);
// pMidiContainer->curve_vel.pinterval = pXML_PARAM_INFO->getDoubleAttribute("PINTERVAL", 0);
}
pXML_PARAM_INFO = pXML_PARAM->getChildByName(String("KEYFOLLOW_CURVE"));
if (pXML_PARAM_INFO)
{
// pMidiContainer->curve_key.base = pXML_PARAM_INFO->getDoubleAttribute("BASE", exp(1.0));
pMidiContainer->curve_key.kexp = pXML_PARAM_INFO->getDoubleAttribute("KEXP", 0);
pMidiContainer->curve_key.scenter = pXML_PARAM_INFO->getDoubleAttribute("SCENTER", 0.5);
pMidiContainer->curve_key.pmin = pXML_PARAM_INFO->getDoubleAttribute("PMIN", 0);
pMidiContainer->curve_key.pmax = pXML_PARAM_INFO->getDoubleAttribute("PMAX", 1);
// pMidiContainer->curve_key.pinterval = pXML_PARAM_INFO->getDoubleAttribute("PINTERVAL", 0);
}
if (pXML_PARAM->getIntAttribute("IS_ASSIGNED", 0))
@@ -360,37 +424,6 @@ int JaySynthMidiCC::importXML(XmlElement const *pXML_MidiCc)
pXML_PARAM = pXML_PARAM->getNextElement();
}
// todo: romove that in future versions
{
int controllerID;
XmlElement *pXML_MIDICC, *pXML_DST;
pXML = pXML->getNextElement();
while(pXML)
{
pXML_MIDICC = pXML->getFirstChildElement();
while(pXML_MIDICC)
{
controllerID = pXML_MIDICC->getIntAttribute("ID");
pXML_DST = pXML_MIDICC->getFirstChildElement();
if (pXML_DST)
{
for (i=0; i < pXML_DST->getNumAttributes(); i++)
{
paramID = findParamID_byName(pXML_DST->getAttributeValue(i));
if (paramID < 0)
break;
pMidiContainer = &midiCC_containers[paramID];
add(pMidiContainer, controllerID);
}
}
pXML_MIDICC = pXML_MIDICC->getNextElement();
}
pXML = pXML->getNextElement();
}
}
// todo: romove that in future versions
}
}
isModified = false;
+5 -3
View File
@@ -55,9 +55,11 @@ public:
bool isMidiCCmodified(void) const;
String toParameterNameXML (String const &name) const;
int findParamID_byName(String name);
void exportXML(String name);
void exportXML(XmlElement *pXML_doc) const;
int importXML(XmlElement const *pXML_doc);
void export_midi_cc(XmlElement *pXML_doc) const;
int import_midi_cc(XmlElement const *pXML_doc);
void export_midi_velkey(XmlElement *pXML_doc) const;
int import_midi_velkey(XmlElement const *pXML_doc);
int import_midi_cc_legacy(XmlElement const *pXML_doc);
void add(midiCC_container_t *pObj, int controllerID);
void remove(midiCC_container_t *pObj, int controllerID);
struct midiCC_container_t* getAtParamID(int paramID);
+33 -28
View File
@@ -741,8 +741,9 @@ void JaySynthAudioProcessor::patchEncodeXml(XmlElement *xml, JaySynthSound const
synth_float_t value = patch->getParameter(i);
xml_patch->setAttribute (getParameterNameXML(i), String(value, 10));
}
XmlElement *xml_midiCC = xml->createNewChildElement("MidiCC");
patch->getMidiCC()->exportXML(xml_midiCC);
patch->getMidiCC()->export_midi_velkey(xml->createNewChildElement("VelKey"));
patch->getMidiCC()->export_midi_cc(xml->createNewChildElement("MidiCC"));
}
void JaySynthAudioProcessor::patchDecodeXml(const XmlElement *xml, JaySynthSound *patch)
@@ -761,12 +762,24 @@ void JaySynthAudioProcessor::patchDecodeXml(const XmlElement *xml, JaySynthSound
}
patch->setParameter(i, value);
}
XmlElement *pXML_MidiCc = xml->getChildByName ("JSYNTH_MIDICONTROLLER_TABLE");
if (pXML_MidiCc)
{
((JaySynthMidiCC*)patch->getMidiCC())->importXML(pXML_MidiCc);
}
void JaySynthAudioProcessor::patchDecodeXml_legacy(const XmlElement& xml, JaySynthSound *patch)
{
// ok, now pull out our parameters..
patch->setName(xml.getStringAttribute("NAME"));
for (int i=0; i < SYNTH_NUM_PARAMS; i++)
{
synth_float_t value = (synth_float_t) xml.getDoubleAttribute (getParameterNameXML(i), patch->getParameter(i));
if (i==SYNTH_PARAM_TUNE)
{
if (value > 400.0)
{
value = 1200*log(value/440)/log(2.0);
}
}
patch->setParameter(i, value);
}
}
void JaySynthAudioProcessor::bankEncodeXml(XmlElement *xml)
@@ -951,15 +964,26 @@ void JaySynthAudioProcessor::patchImportXml (const XmlElement *xml, JaySynthSoun
if (xml2->hasTagName ("Patch"))
{
patchDecodeXml(xml2, patch);
XmlElement *pXML_MidiCc = xml2->getChildByName ("JSYNTH_MIDICONTROLLER_TABLE");
if (pXML_MidiCc)
{
((JaySynthMidiCC*)patch->getMidiCC())->import_midi_cc_legacy(pXML_MidiCc);
}
}
else if (xml->hasTagName ("JSYNTH_PATCH"))
{
patchDecodeXml_legacy(*xml, patch);
XmlElement *pXML_MidiCc = xml->getChildByName ("JSYNTH_MIDICONTROLLER_TABLE");
((JaySynthMidiCC*)patch->getMidiCC())->import_midi_cc_legacy(pXML_MidiCc);
}
else if (xml2->hasTagName ("VelKey"))
{
((JaySynthMidiCC*)patch->getMidiCC())->import_midi_velkey(xml->getChildByName ("VelKey"));
}
else if (xml2->hasTagName ("MidiCC"))
{
XmlElement *pXML_MidiCc = xml->getChildByName ("MidiCC");
((JaySynthMidiCC*)patch->getMidiCC())->importXML(pXML_MidiCc);
((JaySynthMidiCC*)patch->getMidiCC())->import_midi_cc(xml->getChildByName ("MidiCC"));
}
xml2 = xml2->getNextElement();
};
@@ -1041,25 +1065,6 @@ void JaySynthAudioProcessor::saveBankToFile (const File &file)
xml->writeToFile (/*const File &destinationFile*/file, /*dtdToUse*/"");
}
}
void JaySynthAudioProcessor::patchDecodeXml_legacy(const XmlElement& xml, JaySynthSound *patch)
{
// ok, now pull out our parameters..
patch->setName(xml.getStringAttribute("NAME"));
for (int i=0; i < SYNTH_NUM_PARAMS; i++)
{
synth_float_t value = (synth_float_t) xml.getDoubleAttribute (getParameterNameXML(i), patch->getParameter(i));
if (i==SYNTH_PARAM_TUNE)
{
if (value > 400.0)
{
value = 1200*log(value/440)/log(2.0);
}
}
patch->setParameter(i, value);
}
XmlElement *pXML_MidiCc = xml.getChildByName ("JSYNTH_MIDICONTROLLER_TABLE");
((JaySynthMidiCC*)patch->getMidiCC())->importXML(pXML_MidiCc);
}
void JaySynthAudioProcessor::bankDecodeXml_legacy(const XmlElement& xml)
{
@@ -1075,7 +1080,7 @@ void JaySynthAudioProcessor::bankDecodeXml_legacy(const XmlElement& xml)
JaySynthSound *pPatch = &patches[progID];
patchDecodeXml_legacy(*pXML, pPatch);
XmlElement *pXML_MidiCc = pXML->getChildByName ("JSYNTH_MIDICONTROLLER_TABLE");
((JaySynthMidiCC*)pPatch->getMidiCC())->importXML(pXML_MidiCc);
((JaySynthMidiCC*)pPatch->getMidiCC())->import_midi_cc(pXML_MidiCc);
pXML = pXML->getNextElement();
}
}