/* ============================================================================== This file was auto-generated! It contains the basic startup code for a Juce application. ============================================================================== */ #include "../JuceLibraryCode/JuceHeader.h" #include "synth/synth_defs.h" #include "JaySynthMidiCC.h" //============================================================================== JaySynthMidiCC::JaySynthMidiCC() { int i; param_info_t *pConstraints; for (i=0; i < SYNTH_NUM_PARAMS; i++) { pConstraints = getParamInfo(i); // Constraints paramInfoInit(&midiCC_containers[i].constraints, i, pConstraints->pName); paramInfoSet(&midiCC_containers[i].constraints, /*base*/pConstraints->base, /*kexp*/pConstraints->kexp, /*scenter*/pConstraints->scenter, /*pmin*/pConstraints->pmin, /*pcenter*/pConstraints->pcenter, /*pmax*/pConstraints->pmax, /*pinterval*/pConstraints->pinterval); // Control paramInfoInit(&midiCC_containers[i].control, i, pConstraints->pName); paramInfoSet(&midiCC_containers[i].control, /*base*/1, /*kexp*/1, /*scenter*/0.5, /*pmin*/0, /*pcenter*/-1E18, /*pmax*/pConstraints->pmax, /*pinterval*/pConstraints->pinterval); // Parameters paramInfoInit(&midiCC_containers[i].param, i, pConstraints->pName); paramInfoSet(&midiCC_containers[i].param, /*base*/pConstraints->base, /*kexp*/pConstraints->kexp, /*scenter*/pConstraints->scenter, /*pmin*/pConstraints->pmin, /*pcenter*/-1E18, /*pmax*/pConstraints->pmax, /*pinterval*/pConstraints->pinterval); midiCC_containers[i].doChangeParameter = false; midiCC_containers[i].controllerID = 0; midiCC_containers[i].isAssigned = false; midiCC_containers[i].doApplyOnPatchInit = false; // Velocity paramInfoInit(&midiCC_containers[i].curve_vel, i, pConstraints->pName); paramInfoSet(&midiCC_containers[i].curve_vel, /*base*/exp(1.0), /*kexp*/0, /*scenter*/0.0, /*pmin*/0, /*pcenter*/-1E18, /*pmax*/1, /*pinterval*/0); // Key follow paramInfoInit(&midiCC_containers[i].curve_key, i, pConstraints->pName); paramInfoSet(&midiCC_containers[i].curve_key, /*base*/exp(1.0), /*kexp*/0, /*scenter*/0.0, /*pmin*/0, /*pcenter*/-1E18, /*pmax*/1, /*pinterval*/0); midiCC_containers[i].isVelAssigned = false; midiCC_containers[i].isKeyAssigned = false; midiCC_containers[i].velKeyCombineOP = VELKEY_OP_ADD; isModified = false; paramNamedValueSet.set(toParameterNameXML(String(pConstraints->pName)), var(i)); } } JaySynthMidiCC::~JaySynthMidiCC() { int i; for (i=0; i < SYNTH_NUM_PARAMS; i++) { paramInfoFree(&midiCC_containers[i].constraints); paramInfoFree(&midiCC_containers[i].control); paramInfoFree(&midiCC_containers[i].param); paramInfoFree(&midiCC_containers[i].curve_vel); paramInfoFree(&midiCC_containers[i].curve_key); } for (i=0; i < NUM_MIDI_CONTROLLERS; i++) removeDestinations(i); } JaySynthMidiCC& JaySynthMidiCC::operator= (JaySynthMidiCC& other) { if (this != &other) { this->copyMidiCC(&other); } return *this; } void JaySynthMidiCC::copyMidiCC(JaySynthMidiCC *pSrc) { int i; midiCC_container_t *pMidiContainerSrc, *pMidiContainerDst; for (i=0; i < NUM_MIDI_CONTROLLERS; i++) removeDestinations(i); pMidiContainerSrc = pSrc->midiCC_containers; pMidiContainerDst = this->midiCC_containers; for (i=0; i < SYNTH_NUM_PARAMS; i++) { paramInfoCopy(&pMidiContainerDst[i].constraints, &pMidiContainerSrc[i].constraints); paramInfoCopy(&pMidiContainerDst[i].control, &pMidiContainerSrc[i].control); paramInfoCopy(&pMidiContainerDst[i].param, &pMidiContainerSrc[i].param); pMidiContainerDst[i].doChangeParameter = pMidiContainerSrc[i].doChangeParameter; pMidiContainerDst[i].doApplyOnPatchInit = pMidiContainerSrc[i].doApplyOnPatchInit; pMidiContainerDst[i].controllerID = pMidiContainerSrc[i].controllerID; pMidiContainerDst[i].isAssigned = 0; if (pMidiContainerSrc[i].isAssigned) { add(&pMidiContainerDst[i], pMidiContainerSrc[i].controllerID); } } for (i=0; i < SYNTH_NUM_PARAMS; i++) { paramInfoCopy(&pMidiContainerDst[i].curve_vel, &pMidiContainerSrc[i].curve_vel); paramInfoCopy(&pMidiContainerDst[i].curve_key, &pMidiContainerSrc[i].curve_key); pMidiContainerDst[i].isVelAssigned = pMidiContainerSrc[i].isVelAssigned; pMidiContainerDst[i].isKeyAssigned = pMidiContainerSrc[i].isKeyAssigned; pMidiContainerDst[i].velKeyCombineOP = pMidiContainerSrc[i].velKeyCombineOP; } isModified = false; } bool JaySynthMidiCC::isMidiCCmodified(void) { return isModified; } JaySynthMidiCC* JaySynthMidiCC::getMidiCC(void) { return this; } const String JaySynthMidiCC::toParameterNameXML (String name) { name = name.removeCharacters (String(".")); name = name.replaceCharacter (' ','_'); return name; } 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_doc) { int paramID; midiCC_container_t *pMidiContainer; XmlElement *pXML, *pXML_root, *pXML_PARAM, *pXML_PARAM_INFO; // Store controller and slider infos pXML_root = pXML_doc->createNewChildElement (String("JSYNTH_MIDICONTROLLER_TABLE")); pXML = pXML_root->createNewChildElement (String("TARGETS")); 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_ASSIGNED", pMidiContainer->isAssigned); pXML_PARAM->setAttribute ("IS_ABSOLUTE", pMidiContainer->doChangeParameter); pXML_PARAM->setAttribute ("DO_APPLY_ON_PATCH_INIT", pMidiContainer->doApplyOnPatchInit); pXML_PARAM->setAttribute ("CONTROLLER_ID", pMidiContainer->controllerID); 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)); pXML_PARAM_INFO->setAttribute ("PMAX", String(pMidiContainer->curve_vel.pmax, 10)); 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 i, controllerID, numDst; XmlElement *pXML_dst, *pXML_MIDICC; // todo: romove that in future versions pXML = pXML_root->createNewChildElement (String("CONTROLLERS")); // Store MIDI controller assignments for (controllerID=0; controllerID < NUM_MIDI_CONTROLLERS; controllerID++) { 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++) { pMidiContainer = getDestination(controllerID, i); pXML_dst->setAttribute (String("PARAM") + String(pMidiContainer->constraints.id), pMidiContainer->constraints.pName); } } } // todo: romove that in future versions */ } int JaySynthMidiCC::importXML(String name) { File file(name); XmlDocument xml(file); ScopedPointer pXML_root (xml.getDocumentElement()); return importXML(pXML_root); } int JaySynthMidiCC::importXML(XmlElement *pXML_doc) { int i, paramID; midiCC_container_t *pMidiContainer; XmlElement *pXML, *pXML_root, *pXML_PARAM, *pXML_PARAM_INFO; for (i=0; i < NUM_MIDI_CONTROLLERS; i++) removeDestinations(i); pXML_root = pXML_doc->getChildByName ("JSYNTH_MIDICONTROLLER_TABLE"); // make sure that it's actually our type of XML object.. if (pXML_root) { pXML = pXML_root->getFirstChildElement(); while(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; 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.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)) add(pMidiContainer, pXML_PARAM->getIntAttribute("CONTROLLER_ID", 0)); 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; return 0; } void JaySynthMidiCC::add(midiCC_container_t *pObj, int controllerID) { if (controllerID >= NUM_MIDI_CONTROLLERS) return; remove(pObj, pObj->controllerID); if (midiCC_dest[controllerID].contains(pObj)) return; pObj->isAssigned = 1; pObj->controllerID = controllerID; midiCC_dest[controllerID].append(pObj); isModified = true; } void JaySynthMidiCC::remove(midiCC_container_t *pObj, int controllerID) { if (controllerID >= NUM_MIDI_CONTROLLERS) return; pObj->isAssigned = 0; if (midiCC_dest[controllerID].contains(pObj)) { midiCC_dest[controllerID].remove(pObj); } isModified = true; } struct midiCC_container_t* JaySynthMidiCC::getAtParamID(int paramID) { if (paramID >= SYNTH_NUM_PARAMS) return NULL; return &midiCC_containers[paramID]; } int JaySynthMidiCC::getNumDestinations(int controllerID) { if (controllerID >= NUM_MIDI_CONTROLLERS) return 0; return midiCC_dest[controllerID].size(); } void JaySynthMidiCC::removeDestinations(int controllerID) { int i; if (controllerID >= NUM_MIDI_CONTROLLERS) return; int numDst = getNumDestinations(controllerID); midiCC_container_t *pDst; for (i=0; i < numDst; i++) { pDst = getDestination(controllerID, 0); remove(pDst, controllerID); } midiCC_dest[controllerID].deleteAll(); isModified = true; } midiCC_container_t* JaySynthMidiCC::getDestination(int controllerID, int index) { if (controllerID >= NUM_MIDI_CONTROLLERS) return NULL; midiCC_container_t *pDst; if (index >= getNumDestinations(controllerID)) return NULL; pDst = midiCC_dest[controllerID][index].get(); return pDst; } int JaySynthMidiCC::getParamID(midiCC_container_t *pObj) { return pObj->constraints.id; } int JaySynthMidiCC::getControllerID(midiCC_container_t *pObj) { return pObj->controllerID; } void JaySynthMidiCC::setControllerID(midiCC_container_t *pObj, int controllerID) { if (controllerID >= NUM_MIDI_CONTROLLERS) return; if(isAssigned(pObj)) { remove(pObj, pObj->controllerID); add(pObj, controllerID); } pObj->controllerID = controllerID; isModified = true; } bool JaySynthMidiCC::isAssigned(midiCC_container_t *pObj) { return pObj->isAssigned; } void JaySynthMidiCC::setDoChangeParameter(midiCC_container_t *pObj, bool doChangeParameter) { pObj->doChangeParameter = doChangeParameter; isModified = true; } bool JaySynthMidiCC::doChangeParameter(midiCC_container_t *pObj) { return pObj->doChangeParameter; } void JaySynthMidiCC::setDoApplyOnPatchInit(midiCC_container_t *pObj, bool doApplyOnPatchInit) { pObj->doApplyOnPatchInit = doApplyOnPatchInit; isModified = true; } bool JaySynthMidiCC::doApplyOnPatchInit(midiCC_container_t *pObj) { return pObj->doApplyOnPatchInit; } synth_float_t JaySynthMidiCC::getConstraintsMin(midiCC_container_t *pObj) { return pObj->constraints.pmin; } synth_float_t JaySynthMidiCC::getConstraintsMax(midiCC_container_t *pObj) { return pObj->constraints.pmax; } param_info_t* JaySynthMidiCC::getConstraints(midiCC_container_t *pObj) { return &pObj->constraints; } synth_float_t JaySynthMidiCC::getControlMin(midiCC_container_t *pObj) { return pObj->control.pmin; } void JaySynthMidiCC::setControlMin(midiCC_container_t *pObj, synth_float_t value) { pObj->control.pmin = value; isModified = true; } synth_float_t JaySynthMidiCC::getControlMax(midiCC_container_t *pObj) { return pObj->control.pmax; } void JaySynthMidiCC::setControlMax(midiCC_container_t *pObj, synth_float_t value) { pObj->control.pmax = value; isModified = true; } param_info_t* JaySynthMidiCC::getControl(midiCC_container_t *pObj) { return &pObj->control; } synth_float_t JaySynthMidiCC::getParamMin(midiCC_container_t *pObj) { return pObj->param.pmin; } void JaySynthMidiCC::setParamMin(midiCC_container_t *pObj, synth_float_t value) { pObj->param.pmin = value; isModified = true; } synth_float_t JaySynthMidiCC::getParamMax(midiCC_container_t *pObj) { return pObj->param.pmax; } void JaySynthMidiCC::setParamMax(midiCC_container_t *pObj, synth_float_t value) { pObj->param.pmax = value; isModified = true; } param_info_t* JaySynthMidiCC::getParam(midiCC_container_t *pObj) { return &pObj->param; } param_info_t* JaySynthMidiCC::getVelCurve(midiCC_container_t *pObj) { return &pObj->curve_vel; } void JaySynthMidiCC::setVelCurveMin(midiCC_container_t *pObj, synth_float_t value) { pObj->curve_vel.pmin = value; isModified = true; } void JaySynthMidiCC::setVelCurveMax(midiCC_container_t *pObj, synth_float_t value) { pObj->curve_vel.pmax = value; isModified = true; } void JaySynthMidiCC::setVelCurveSkew(midiCC_container_t *pObj, synth_float_t value) { pObj->curve_vel.scenter = value; isModified = true; } void JaySynthMidiCC::setVelCurveShape(midiCC_container_t *pObj, synth_float_t value) { pObj->curve_vel.kexp = value; isModified = true; } param_info_t* JaySynthMidiCC::getKeyCurve(midiCC_container_t *pObj) { return &pObj->curve_key; } void JaySynthMidiCC::setKeyCurveMin(midiCC_container_t *pObj, synth_float_t value) { pObj->curve_key.pmin = value; isModified = true; } void JaySynthMidiCC::setKeyCurveMax(midiCC_container_t *pObj, synth_float_t value) { pObj->curve_key.pmax = value; isModified = true; } void JaySynthMidiCC::setKeyCurveSkew(midiCC_container_t *pObj, synth_float_t value) { pObj->curve_key.scenter = value; isModified = true; } void JaySynthMidiCC::setKeyCurveShape(midiCC_container_t *pObj, synth_float_t value) { pObj->curve_key.kexp = value; isModified = true; } bool JaySynthMidiCC::isAssignedVel(midiCC_container_t *pObj) { return pObj->isVelAssigned; } bool JaySynthMidiCC::isAssignedKey(midiCC_container_t *pObj) { return pObj->isKeyAssigned; } void JaySynthMidiCC::setAssignedVel(midiCC_container_t *pObj, bool active) { pObj->isVelAssigned = active; isModified = true; } void JaySynthMidiCC::setAssignedKey(midiCC_container_t *pObj, bool active) { pObj->isKeyAssigned = active; isModified = true; } int JaySynthMidiCC::getVelKeyCombineOP(midiCC_container_t *pObj) { return pObj->velKeyCombineOP; } void JaySynthMidiCC::setVelKeyCombineOP(midiCC_container_t *pObj, int combineOP) { if (combineOP >= VELKEY_NUM_OPS) return; pObj->velKeyCombineOP = combineOP; isModified = true; } bool JaySynthMidiCC::isAssignedVelKeyControl(int paramID) { return isAssignedVel(&midiCC_containers[paramID]) || isAssignedKey(&midiCC_containers[paramID]); } synth_float_t JaySynthMidiCC::getVelKeyControl(int paramID, synth_float_t vel, synth_float_t key) { synth_float_t result, result_vel, result_key; result_vel = 0; result_key = 0; result = 0; if (isAssignedVel(&midiCC_containers[paramID])) result_vel = toParam(&midiCC_containers[paramID].curve_vel, vel); if (isAssignedKey(&midiCC_containers[paramID])) result_key = toParam(&midiCC_containers[paramID].curve_key, key/127); switch (midiCC_containers[paramID].velKeyCombineOP) { case VELKEY_OP_ADD: result = jsy_min(1, jsy_max(-1, result_vel + result_key)); break; case VELKEY_OP_SUB: result = jsy_min(1, jsy_max(-1, result_vel - result_key)); break; case VELKEY_OP_MUL: if (!isAssignedVel(&midiCC_containers[paramID])) { result = result_key; break; } if (!isAssignedKey(&midiCC_containers[paramID])) { result = result_vel; break; } result = result_vel * result_key; break; default: break; } return midiCC_containers[paramID].constraints.pmax*result; }