From b4add9e530de0050c8e6a9d53122fde65fa36452 Mon Sep 17 00:00:00 2001 From: jens Date: Fri, 28 Apr 2023 12:32:26 +0200 Subject: [PATCH] - constify - refactored MidiCC - JaySynthSound is not MidiCC, but has MidiCC - refactored xml import export for patches and banks --- Source/JaySynthAudioProcessorEditor.cpp | 4 +- Source/JaySynthMidiCC.cpp | 27 ++-- Source/JaySynthMidiCC.h | 11 +- Source/JaySynthSound.cpp | 9 +- Source/JaySynthSound.h | 8 +- Source/PluginProcessor.cpp | 200 +++++++++++++----------- Source/PluginProcessor.h | 13 +- 7 files changed, 153 insertions(+), 119 deletions(-) diff --git a/Source/JaySynthAudioProcessorEditor.cpp b/Source/JaySynthAudioProcessorEditor.cpp index 7500b51..b1d0016 100644 --- a/Source/JaySynthAudioProcessorEditor.cpp +++ b/Source/JaySynthAudioProcessorEditor.cpp @@ -4953,7 +4953,7 @@ void JaySynthAudioProcessorEditor::buttonClicked (Button* buttonThatWasClicked) if (fc.browseForFileToOpen()) { File const &file = fc.getResult(); - getProcessor()->loadPatch(0, file); + getProcessor()->loadPatch(file, 0); } } else if (buttonThatWasClicked == m_button_patch_save) @@ -4962,7 +4962,7 @@ void JaySynthAudioProcessorEditor::buttonClicked (Button* buttonThatWasClicked) if (fc.browseForFileToSave(true)) { File const &file = fc.getResult(); - getProcessor()->savePatch(0, file); + getProcessor()->savePatch(file, 0); } } else if (buttonThatWasClicked == m_button_patch_incr) diff --git a/Source/JaySynthMidiCC.cpp b/Source/JaySynthMidiCC.cpp index 2ff46a0..1ebff62 100644 --- a/Source/JaySynthMidiCC.cpp +++ b/Source/JaySynthMidiCC.cpp @@ -115,10 +115,11 @@ JaySynthMidiCC& JaySynthMidiCC::operator= (JaySynthMidiCC& other) return *this; } -void JaySynthMidiCC::copyMidiCC(JaySynthMidiCC *pSrc) +void JaySynthMidiCC::copyMidiCC(JaySynthMidiCC const *pSrc) { int i; - midiCC_container_t *pMidiContainerSrc, *pMidiContainerDst; + midiCC_container_t const *pMidiContainerSrc; + midiCC_container_t *pMidiContainerDst; for (i=0; i < NUM_MIDI_CONTROLLERS; i++) removeDestinations(i); @@ -153,22 +154,18 @@ void JaySynthMidiCC::copyMidiCC(JaySynthMidiCC *pSrc) isModified = false; } -bool JaySynthMidiCC::isMidiCCmodified(void) +bool JaySynthMidiCC::isMidiCCmodified(void) const { return isModified; } -JaySynthMidiCC* JaySynthMidiCC::getMidiCC(void) +String JaySynthMidiCC::toParameterNameXML (String const &name) const { - return this; -} + String result; + result = name.removeCharacters (String(".")); + result = result.replaceCharacter (' ','_'); -const String JaySynthMidiCC::toParameterNameXML (String name) -{ - name = name.removeCharacters (String(".")); - name = name.replaceCharacter (' ','_'); - - return name; + return result; } int JaySynthMidiCC::findParamID_byName(String name) @@ -187,10 +184,10 @@ void JaySynthMidiCC::exportXML(String name) 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) +void JaySynthMidiCC::exportXML(XmlElement *pXML_doc) const { int paramID; - midiCC_container_t *pMidiContainer; + midiCC_container_t const *pMidiContainer; XmlElement *pXML, *pXML_root, *pXML_PARAM, *pXML_PARAM_INFO; // Store controller and slider infos @@ -279,7 +276,7 @@ int JaySynthMidiCC::importXML(String name) return importXML(pXML_root); } -int JaySynthMidiCC::importXML(XmlElement *pXML_doc) +int JaySynthMidiCC::importXML(XmlElement const *pXML_doc) { int i, paramID; midiCC_container_t *pMidiContainer; diff --git a/Source/JaySynthMidiCC.h b/Source/JaySynthMidiCC.h index b8794de..157dea1 100644 --- a/Source/JaySynthMidiCC.h +++ b/Source/JaySynthMidiCC.h @@ -42,15 +42,14 @@ public: ~JaySynthMidiCC(); JaySynthMidiCC& operator= (JaySynthMidiCC& other); - void copyMidiCC(JaySynthMidiCC *pSrc); - JaySynthMidiCC* getMidiCC(void); - bool isMidiCCmodified(void); - const String toParameterNameXML (String name); + void copyMidiCC(JaySynthMidiCC const *pSrc); + bool isMidiCCmodified(void) const; + String toParameterNameXML (String const &name) const; int findParamID_byName(String name); void exportXML(String name); - void exportXML(XmlElement *pXML_doc); + void exportXML(XmlElement *pXML_doc) const; int importXML(String name); - int importXML(XmlElement *pXML_doc); + int importXML(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); diff --git a/Source/JaySynthSound.cpp b/Source/JaySynthSound.cpp index 7a50a53..a0a97e5 100644 --- a/Source/JaySynthSound.cpp +++ b/Source/JaySynthSound.cpp @@ -155,12 +155,17 @@ JaySynthSound::~JaySynthSound() { } +const JaySynthMidiCC* JaySynthSound::getMidiCC() const +{ + return &m_midiCC; +} + void JaySynthSound::setName(String ProgramName) { name = ProgramName; } -String JaySynthSound::getName(void) +String JaySynthSound::getName(void) const { return name; } @@ -170,7 +175,7 @@ void JaySynthSound::setParameter(int index, synth_float_t param) parameter[index] = param; } -synth_float_t JaySynthSound::getParameter(int index) +synth_float_t JaySynthSound::getParameter(int index) const { return parameter[index]; } diff --git a/Source/JaySynthSound.h b/Source/JaySynthSound.h index f1e7fa2..e5add6a 100644 --- a/Source/JaySynthSound.h +++ b/Source/JaySynthSound.h @@ -15,7 +15,7 @@ //============================================================================== /** A synth sound that's just a bunch of parameters that makes an incredible sound.. */ -class JaySynthSound : public SynthesiserSound, public JaySynthMidiCC +class JaySynthSound : public SynthesiserSound { public: synth_float_t parameter[SYNTH_NUM_PARAMS]; @@ -24,10 +24,12 @@ public: JaySynthSound(); ~JaySynthSound(); + JaySynthMidiCC m_midiCC; + const JaySynthMidiCC* getMidiCC() const; void setName(String ProgramName); - String getName(void); + String getName(void) const; void setParameter(int index, synth_float_t param); - synth_float_t getParameter(int index); + synth_float_t getParameter(int index) const; void initParameter(int index, synth_float_t param); bool appliesToNote (const int /*midiNoteNumber*/) { return true; } bool appliesToChannel (const int /*midiChannel*/) { return true; } diff --git a/Source/PluginProcessor.cpp b/Source/PluginProcessor.cpp index bf877ca..0801b12 100644 --- a/Source/PluginProcessor.cpp +++ b/Source/PluginProcessor.cpp @@ -13,6 +13,8 @@ #include "JaySynthAudioProcessorEditor.h" #include "synth/vector_utils.h" +using namespace juce; + JaySynthAudioProcessorEditor* getEditor(JaySynthAudioProcessor *pThis) { return dynamic_cast(pThis->getActiveEditor()); @@ -473,7 +475,7 @@ void JaySynthAudioProcessor::setCurrentProgram (int index) // Set SYNTH_PARAM_TOTAL_NUM_VOICES first setParam(SYNTH_PARAM_TOTAL_NUM_VOICES, currpatch->getParameter(SYNTH_PARAM_TOTAL_NUM_VOICES), false, false); - midCC_editBuffer = *currpatch->getMidiCC(); + midCC_editBuffer = *((JaySynthMidiCC*)currpatch->getMidiCC()); pSynth->setMidiCC_editBuffer(&midCC_editBuffer); pSynth->ClearControls(); @@ -689,52 +691,113 @@ const String JaySynthAudioProcessor::getParameterNameXML (int index) return name; } +void JaySynthAudioProcessor::commitEditBuffer() +{ + if (isPatchModified() || midCC_editBuffer.isMidiCCmodified()) + { + for (int i=0; i < SYNTH_NUM_PARAMS; i++) + { + synth_float_t value = getParam(i); + currpatch->setParameter(i, value); // Copy synth param to current program + } + JaySynthMidiCC *midiCC = (JaySynthMidiCC*)currpatch->getMidiCC(); + midiCC->copyMidiCC(&midCC_editBuffer); // Copy MidiCC edit buffer to patch + } +} + +void JaySynthAudioProcessor::patch2xml(XmlElement& xml, JaySynthSound const *patch) +{ + xml.setAttribute ("NAME", patch->getName()); + for (int i=0; i < SYNTH_NUM_PARAMS; i++) + { + synth_float_t value = patch->getParameter(i); + xml.setAttribute (getParameterNameXML(i), String(value, 10)); + } + patch->getMidiCC()->exportXML(&xml); +} + +void JaySynthAudioProcessor::xml2patch(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); + } + ((JaySynthMidiCC*)patch->getMidiCC())->importXML(&xml); +} + +void JaySynthAudioProcessor::bank2xml(XmlElement& xml) +{ + for (int i=0; i < NUM_PROGRAMS; i++) + { + XmlElement *pXml = xml.createNewChildElement (String("PATCH_") + String(i)); + JaySynthSound *pPatch = &patches[i]; + pXml->setAttribute ("ID", i); + patch2xml(*pXml, pPatch); + } +} + +void JaySynthAudioProcessor::xml2bank(const XmlElement& xml) +{ + // make sure that it's actually our type of XML object.. + XmlElement *pXML = (XmlElement*)&xml; + + while(pXML) + { + int progID = pXML->getIntAttribute("ID"); + if (progID >= NUM_PROGRAMS) + break; + + JaySynthSound *pPatch = &patches[progID]; + + // ok, now pull out our parameters.. + pPatch->setName(pXML->getStringAttribute("NAME")); + for (int i=0; i < SYNTH_NUM_PARAMS; i++) + { + synth_float_t value = (synth_float_t) pXML->getDoubleAttribute (getParameterNameXML(i), pPatch->getParameter(i)); + if (i==SYNTH_PARAM_TUNE) + { + if (value > 400.0) + { + value = 1200*log(value/440)/log(2.0); + } + } + pPatch->setParameter(i, value); + } + ((JaySynthMidiCC*)pPatch->getMidiCC())->importXML(pXML); + pXML = pXML->getNextElement(); + } +} + void JaySynthAudioProcessor::getStateInformation (MemoryBlock& destData) { - int i, progID; - synth_float_t value; - JaySynthSound *pPatch; - XmlElement *pXML; - + commitEditBuffer(); + // Create an outer XML element.. ScopedPointerxml = new XmlElement("JSYNTH_BANK"); + bank2xml(*xml); + setCurrentProgram(getCurrentProgram()); + MemoryOutputStream outputStream(destData, false); MemoryBlock tmpBlock(destData.getSize(), /*initialiseToZero*/true); GZIPCompressorOutputStream GZIPEnc(&outputStream, /*compressionLevel*/0, /*deleteDestStreamWhenDestroyed*/false, /*windowBits*/0); - if (isPatchModified() || midCC_editBuffer.isMidiCCmodified()) - { - for (i=0; i < SYNTH_NUM_PARAMS; i++) - { - value = getParam(i); - currpatch->setParameter(i, value); // Copy synth param to current program - } - currpatch->getMidiCC()->copyMidiCC(&midCC_editBuffer); // Copy MidiCC edit buffer to patch - } - - for (progID=0; progID < NUM_PROGRAMS; progID++) - { - pXML = xml->createNewChildElement (String("PATCH_") + String(progID)); - pPatch = &patches[progID]; - pXML->setAttribute ("ID", progID); - pXML->setAttribute ("NAME", pPatch->getName()); - for (i=0; i < SYNTH_NUM_PARAMS; i++) - { - value = pPatch->getParameter(i); - pXML->setAttribute (getParameterNameXML(i), String(value, 10)); - } - pPatch->getMidiCC()->exportXML(pXML); - - } - setCurrentProgram(getCurrentProgram()); - // then use this helper function to stuff it into the binary blob and return it.. copyXmlToBinary (*xml, tmpBlock); GZIPEnc.write(tmpBlock.getData(), tmpBlock.getSize()); outputStream.flush(); -#if 1 +#if 0 { File pluginfile = File::getSpecialLocation (File::currentExecutableFile).getParentDirectory(); File file(pluginfile.getFullPathName() + String("/bank.xml")); @@ -746,10 +809,7 @@ void JaySynthAudioProcessor::getStateInformation (MemoryBlock& destData) void JaySynthAudioProcessor::setStateInformation (const void* data, int sizeInBytes) { - int i, progID, uncompressedSize; - synth_float_t value; - JaySynthSound *pPatch; - XmlElement *pXML; + int uncompressedSize; String lastError; ScopedPointer xmlState = NULL; void* pData; @@ -773,38 +833,11 @@ void JaySynthAudioProcessor::setStateInformation (const void* data, int sizeInBy if (xmlState != 0) { - // make sure that it's actually our type of XML object.. if (xmlState->hasTagName ("JSYNTH_BANK")) { - pXML = xmlState->getFirstChildElement(); - - while(pXML) - { - progID = pXML->getIntAttribute("ID"); - if (progID >= NUM_PROGRAMS) - break; - - pPatch = &patches[progID]; - - // ok, now pull out our parameters.. - pPatch->setName(pXML->getStringAttribute("NAME")); - for (i=0; i < SYNTH_NUM_PARAMS; i++) - { - value = (synth_float_t) pXML->getDoubleAttribute (getParameterNameXML(i), pPatch->getParameter(i)); - if (i==SYNTH_PARAM_TUNE) - { - if (value > 400.0) - { - value = 1200*log(value/440)/log(2.0); - } - } - pPatch->setParameter(i, value); - } - pPatch->getMidiCC()->importXML(pXML); - pXML = pXML->getNextElement(); - - } + XmlElement *pXML = xmlState->getFirstChildElement(); + xml2bank(*pXML); } setCurrentProgram(getCurrentProgram()); } @@ -818,8 +851,8 @@ void JaySynthAudioProcessor::getCurrentProgramStateInformation (MemoryBlock& des // You should use this method to store your parameters in the memory block. // Here's an example of how you can use XML to make it easy and more robust: - int i; - synth_float_t value; + commitEditBuffer(); + MemoryOutputStream outputStream (destData, false); MemoryBlock tmpBlock(2*65536, /*initialiseToZero*/true); GZIPCompressorOutputStream GZIPEnc(&outputStream, /*compressionLevel*/0, /*deleteDestStreamWhenDestroyed*/false, /*windowBits*/0); @@ -827,23 +860,7 @@ void JaySynthAudioProcessor::getCurrentProgramStateInformation (MemoryBlock& des // Create an outer XML element.. ScopedPointerxml = new XmlElement("JSYNTH_PATCH"); - if (isPatchModified() || midCC_editBuffer.isMidiCCmodified()) - { - for (i=0; i < SYNTH_NUM_PARAMS; i++) - { - value = getParam(i); - currpatch->setParameter(i, value); // Copy synth param to current program - } - currpatch->getMidiCC()->copyMidiCC(&midCC_editBuffer); // Copy MidiCC edit buffer to patch - } - - xml->setAttribute ("NAME", currpatch->getName()); - for (i=0; i < SYNTH_NUM_PARAMS; i++) - { - value = currpatch->getParameter(i); - xml->setAttribute (getParameterNameXML(i), String(value, 10)); - } - currpatch->getMidiCC()->exportXML(xml); + patch2xml(*xml, currpatch); setCurrentProgram(getCurrentProgram()); // then use this helper function to stuff it into the binary blob and return it.. @@ -891,6 +908,9 @@ void JaySynthAudioProcessor::setCurrentProgramStateInformation (const void* data // make sure that it's actually our type of XML object.. if (xmlState->hasTagName ("JSYNTH_PATCH")) { + xml2patch(*xmlState, currpatch); + +#if 0 // ok, now pull out our parameters.. currpatch->setName(xmlState->getStringAttribute("NAME")); for (i=0; i < SYNTH_NUM_PARAMS; i++) @@ -905,18 +925,20 @@ void JaySynthAudioProcessor::setCurrentProgramStateInformation (const void* data } currpatch->setParameter(i, value); } - } - currpatch->getMidiCC()->importXML(xmlState); + ((JaySynthMidiCC*)currpatch->getMidiCC())->importXML(xmlState); +#endif setCurrentProgram(getCurrentProgram()); + } + } } -void JaySynthAudioProcessor::loadPatch (int index, const File &file) +void JaySynthAudioProcessor::loadPatch (const File &file, int index) { String filename(file.getFullPathName()); } -void JaySynthAudioProcessor::savePatch (int index, const File &file) +void JaySynthAudioProcessor::savePatch (const File &file, int index) { String filename(file.getFullPathName()); } diff --git a/Source/PluginProcessor.h b/Source/PluginProcessor.h index 6745b48..66211fb 100644 --- a/Source/PluginProcessor.h +++ b/Source/PluginProcessor.h @@ -205,16 +205,25 @@ public: void copyXmlToBinary (const XmlElement& xml, juce::MemoryBlock& destData); XmlElement* getXmlFromBinary (const void* data, const int sizeInBytes); const String getParameterNameXML (int index); + + void patch2xml(XmlElement& xml, JaySynthSound const *patch); + void xml2patch(const XmlElement& xml, JaySynthSound *patch); + + void bank2xml(XmlElement& xml); + void xml2bank(const XmlElement& xml); + void getCurrentProgramStateInformation (MemoryBlock& destData); void setCurrentProgramStateInformation (const void* data, int sizeInBytes); void getStateInformation (MemoryBlock& destData); void setStateInformation (const void* data, int sizeInBytes); - void loadPatch (int index, const File &file); - void savePatch (int index, const File &file); + void loadPatch (const File &file, int index); + void savePatch (const File &file, int index); void loadBank (const File &file); void saveBank (const File &file); + + void commitEditBuffer(); //============================================================================== // These properties are public so that our editor component can access them // A bit of a hacky way to do it, but it's only a demo! Obviously in your own