- constify

- refactored MidiCC
- JaySynthSound is not MidiCC, but has MidiCC
- refactored xml import export for patches and banks
This commit is contained in:
2023-04-28 12:32:26 +02:00
parent 5850ab5d46
commit b4add9e530
7 changed files with 153 additions and 119 deletions
+2 -2
View File
@@ -4953,7 +4953,7 @@ void JaySynthAudioProcessorEditor::buttonClicked (Button* buttonThatWasClicked)
if (fc.browseForFileToOpen()) if (fc.browseForFileToOpen())
{ {
File const &file = fc.getResult(); File const &file = fc.getResult();
getProcessor()->loadPatch(0, file); getProcessor()->loadPatch(file, 0);
} }
} }
else if (buttonThatWasClicked == m_button_patch_save) else if (buttonThatWasClicked == m_button_patch_save)
@@ -4962,7 +4962,7 @@ void JaySynthAudioProcessorEditor::buttonClicked (Button* buttonThatWasClicked)
if (fc.browseForFileToSave(true)) if (fc.browseForFileToSave(true))
{ {
File const &file = fc.getResult(); File const &file = fc.getResult();
getProcessor()->savePatch(0, file); getProcessor()->savePatch(file, 0);
} }
} }
else if (buttonThatWasClicked == m_button_patch_incr) else if (buttonThatWasClicked == m_button_patch_incr)
+12 -15
View File
@@ -115,10 +115,11 @@ JaySynthMidiCC& JaySynthMidiCC::operator= (JaySynthMidiCC& other)
return *this; return *this;
} }
void JaySynthMidiCC::copyMidiCC(JaySynthMidiCC *pSrc) void JaySynthMidiCC::copyMidiCC(JaySynthMidiCC const *pSrc)
{ {
int i; int i;
midiCC_container_t *pMidiContainerSrc, *pMidiContainerDst; midiCC_container_t const *pMidiContainerSrc;
midiCC_container_t *pMidiContainerDst;
for (i=0; i < NUM_MIDI_CONTROLLERS; i++) for (i=0; i < NUM_MIDI_CONTROLLERS; i++)
removeDestinations(i); removeDestinations(i);
@@ -153,22 +154,18 @@ void JaySynthMidiCC::copyMidiCC(JaySynthMidiCC *pSrc)
isModified = false; isModified = false;
} }
bool JaySynthMidiCC::isMidiCCmodified(void) bool JaySynthMidiCC::isMidiCCmodified(void) const
{ {
return isModified; 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) return result;
{
name = name.removeCharacters (String("."));
name = name.replaceCharacter (' ','_');
return name;
} }
int JaySynthMidiCC::findParamID_byName(String name) 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*/); 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; int paramID;
midiCC_container_t *pMidiContainer; midiCC_container_t const *pMidiContainer;
XmlElement *pXML, *pXML_root, *pXML_PARAM, *pXML_PARAM_INFO; XmlElement *pXML, *pXML_root, *pXML_PARAM, *pXML_PARAM_INFO;
// Store controller and slider infos // Store controller and slider infos
@@ -279,7 +276,7 @@ int JaySynthMidiCC::importXML(String name)
return importXML(pXML_root); return importXML(pXML_root);
} }
int JaySynthMidiCC::importXML(XmlElement *pXML_doc) int JaySynthMidiCC::importXML(XmlElement const *pXML_doc)
{ {
int i, paramID; int i, paramID;
midiCC_container_t *pMidiContainer; midiCC_container_t *pMidiContainer;
+5 -6
View File
@@ -42,15 +42,14 @@ public:
~JaySynthMidiCC(); ~JaySynthMidiCC();
JaySynthMidiCC& operator= (JaySynthMidiCC& other); JaySynthMidiCC& operator= (JaySynthMidiCC& other);
void copyMidiCC(JaySynthMidiCC *pSrc); void copyMidiCC(JaySynthMidiCC const *pSrc);
JaySynthMidiCC* getMidiCC(void); bool isMidiCCmodified(void) const;
bool isMidiCCmodified(void); String toParameterNameXML (String const &name) const;
const String toParameterNameXML (String name);
int findParamID_byName(String name); int findParamID_byName(String name);
void exportXML(String name); void exportXML(String name);
void exportXML(XmlElement *pXML_doc); void exportXML(XmlElement *pXML_doc) const;
int importXML(String name); int importXML(String name);
int importXML(XmlElement *pXML_doc); int importXML(XmlElement const *pXML_doc);
void add(midiCC_container_t *pObj, int controllerID); void add(midiCC_container_t *pObj, int controllerID);
void remove(midiCC_container_t *pObj, int controllerID); void remove(midiCC_container_t *pObj, int controllerID);
struct midiCC_container_t* getAtParamID(int paramID); struct midiCC_container_t* getAtParamID(int paramID);
+7 -2
View File
@@ -155,12 +155,17 @@ JaySynthSound::~JaySynthSound()
{ {
} }
const JaySynthMidiCC* JaySynthSound::getMidiCC() const
{
return &m_midiCC;
}
void JaySynthSound::setName(String ProgramName) void JaySynthSound::setName(String ProgramName)
{ {
name = ProgramName; name = ProgramName;
} }
String JaySynthSound::getName(void) String JaySynthSound::getName(void) const
{ {
return name; return name;
} }
@@ -170,7 +175,7 @@ void JaySynthSound::setParameter(int index, synth_float_t param)
parameter[index] = param; parameter[index] = param;
} }
synth_float_t JaySynthSound::getParameter(int index) synth_float_t JaySynthSound::getParameter(int index) const
{ {
return parameter[index]; return parameter[index];
} }
+5 -3
View File
@@ -15,7 +15,7 @@
//============================================================================== //==============================================================================
/** A synth sound that's just a bunch of parameters that makes an incredible sound.. */ /** 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: public:
synth_float_t parameter[SYNTH_NUM_PARAMS]; synth_float_t parameter[SYNTH_NUM_PARAMS];
@@ -24,10 +24,12 @@ public:
JaySynthSound(); JaySynthSound();
~JaySynthSound(); ~JaySynthSound();
JaySynthMidiCC m_midiCC;
const JaySynthMidiCC* getMidiCC() const;
void setName(String ProgramName); void setName(String ProgramName);
String getName(void); String getName(void) const;
void setParameter(int index, synth_float_t param); 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); void initParameter(int index, synth_float_t param);
bool appliesToNote (const int /*midiNoteNumber*/) { return true; } bool appliesToNote (const int /*midiNoteNumber*/) { return true; }
bool appliesToChannel (const int /*midiChannel*/) { return true; } bool appliesToChannel (const int /*midiChannel*/) { return true; }
+111 -89
View File
@@ -13,6 +13,8 @@
#include "JaySynthAudioProcessorEditor.h" #include "JaySynthAudioProcessorEditor.h"
#include "synth/vector_utils.h" #include "synth/vector_utils.h"
using namespace juce;
JaySynthAudioProcessorEditor* getEditor(JaySynthAudioProcessor *pThis) JaySynthAudioProcessorEditor* getEditor(JaySynthAudioProcessor *pThis)
{ {
return dynamic_cast<JaySynthAudioProcessorEditor*>(pThis->getActiveEditor()); return dynamic_cast<JaySynthAudioProcessorEditor*>(pThis->getActiveEditor());
@@ -473,7 +475,7 @@ void JaySynthAudioProcessor::setCurrentProgram (int index)
// Set SYNTH_PARAM_TOTAL_NUM_VOICES first // Set SYNTH_PARAM_TOTAL_NUM_VOICES first
setParam(SYNTH_PARAM_TOTAL_NUM_VOICES, currpatch->getParameter(SYNTH_PARAM_TOTAL_NUM_VOICES), false, false); 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->setMidiCC_editBuffer(&midCC_editBuffer);
pSynth->ClearControls(); pSynth->ClearControls();
@@ -689,52 +691,113 @@ const String JaySynthAudioProcessor::getParameterNameXML (int index)
return name; 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) void JaySynthAudioProcessor::getStateInformation (MemoryBlock& destData)
{ {
int i, progID; commitEditBuffer();
synth_float_t value;
JaySynthSound *pPatch;
XmlElement *pXML;
// Create an outer XML element.. // Create an outer XML element..
ScopedPointer<XmlElement>xml = new XmlElement("JSYNTH_BANK"); ScopedPointer<XmlElement>xml = new XmlElement("JSYNTH_BANK");
bank2xml(*xml);
setCurrentProgram(getCurrentProgram());
MemoryOutputStream outputStream(destData, false); MemoryOutputStream outputStream(destData, false);
MemoryBlock tmpBlock(destData.getSize(), /*initialiseToZero*/true); MemoryBlock tmpBlock(destData.getSize(), /*initialiseToZero*/true);
GZIPCompressorOutputStream GZIPEnc(&outputStream, /*compressionLevel*/0, /*deleteDestStreamWhenDestroyed*/false, /*windowBits*/0); 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.. // then use this helper function to stuff it into the binary blob and return it..
copyXmlToBinary (*xml, tmpBlock); copyXmlToBinary (*xml, tmpBlock);
GZIPEnc.write(tmpBlock.getData(), tmpBlock.getSize()); GZIPEnc.write(tmpBlock.getData(), tmpBlock.getSize());
outputStream.flush(); outputStream.flush();
#if 1 #if 0
{ {
File pluginfile = File::getSpecialLocation (File::currentExecutableFile).getParentDirectory(); File pluginfile = File::getSpecialLocation (File::currentExecutableFile).getParentDirectory();
File file(pluginfile.getFullPathName() + String("/bank.xml")); File file(pluginfile.getFullPathName() + String("/bank.xml"));
@@ -746,10 +809,7 @@ void JaySynthAudioProcessor::getStateInformation (MemoryBlock& destData)
void JaySynthAudioProcessor::setStateInformation (const void* data, int sizeInBytes) void JaySynthAudioProcessor::setStateInformation (const void* data, int sizeInBytes)
{ {
int i, progID, uncompressedSize; int uncompressedSize;
synth_float_t value;
JaySynthSound *pPatch;
XmlElement *pXML;
String lastError; String lastError;
ScopedPointer<XmlElement> xmlState = NULL; ScopedPointer<XmlElement> xmlState = NULL;
void* pData; void* pData;
@@ -773,38 +833,11 @@ void JaySynthAudioProcessor::setStateInformation (const void* data, int sizeInBy
if (xmlState != 0) if (xmlState != 0)
{ {
// make sure that it's actually our type of XML object.. // make sure that it's actually our type of XML object..
if (xmlState->hasTagName ("JSYNTH_BANK")) if (xmlState->hasTagName ("JSYNTH_BANK"))
{ {
pXML = xmlState->getFirstChildElement(); XmlElement *pXML = xmlState->getFirstChildElement();
xml2bank(*pXML);
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();
}
} }
setCurrentProgram(getCurrentProgram()); setCurrentProgram(getCurrentProgram());
} }
@@ -818,8 +851,8 @@ void JaySynthAudioProcessor::getCurrentProgramStateInformation (MemoryBlock& des
// You should use this method to store your parameters in the memory block. // 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: // Here's an example of how you can use XML to make it easy and more robust:
int i; commitEditBuffer();
synth_float_t value;
MemoryOutputStream outputStream (destData, false); MemoryOutputStream outputStream (destData, false);
MemoryBlock tmpBlock(2*65536, /*initialiseToZero*/true); MemoryBlock tmpBlock(2*65536, /*initialiseToZero*/true);
GZIPCompressorOutputStream GZIPEnc(&outputStream, /*compressionLevel*/0, /*deleteDestStreamWhenDestroyed*/false, /*windowBits*/0); GZIPCompressorOutputStream GZIPEnc(&outputStream, /*compressionLevel*/0, /*deleteDestStreamWhenDestroyed*/false, /*windowBits*/0);
@@ -827,23 +860,7 @@ void JaySynthAudioProcessor::getCurrentProgramStateInformation (MemoryBlock& des
// Create an outer XML element.. // Create an outer XML element..
ScopedPointer<XmlElement>xml = new XmlElement("JSYNTH_PATCH"); ScopedPointer<XmlElement>xml = new XmlElement("JSYNTH_PATCH");
if (isPatchModified() || midCC_editBuffer.isMidiCCmodified()) patch2xml(*xml, currpatch);
{
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);
setCurrentProgram(getCurrentProgram()); setCurrentProgram(getCurrentProgram());
// then use this helper function to stuff it into the binary blob and return it.. // 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.. // make sure that it's actually our type of XML object..
if (xmlState->hasTagName ("JSYNTH_PATCH")) if (xmlState->hasTagName ("JSYNTH_PATCH"))
{ {
xml2patch(*xmlState, currpatch);
#if 0
// ok, now pull out our parameters.. // ok, now pull out our parameters..
currpatch->setName(xmlState->getStringAttribute("NAME")); currpatch->setName(xmlState->getStringAttribute("NAME"));
for (i=0; i < SYNTH_NUM_PARAMS; i++) for (i=0; i < SYNTH_NUM_PARAMS; i++)
@@ -905,18 +925,20 @@ void JaySynthAudioProcessor::setCurrentProgramStateInformation (const void* data
} }
currpatch->setParameter(i, value); currpatch->setParameter(i, value);
} }
} ((JaySynthMidiCC*)currpatch->getMidiCC())->importXML(xmlState);
currpatch->getMidiCC()->importXML(xmlState); #endif
setCurrentProgram(getCurrentProgram()); setCurrentProgram(getCurrentProgram());
}
} }
} }
void JaySynthAudioProcessor::loadPatch (int index, const File &file) void JaySynthAudioProcessor::loadPatch (const File &file, int index)
{ {
String filename(file.getFullPathName()); String filename(file.getFullPathName());
} }
void JaySynthAudioProcessor::savePatch (int index, const File &file) void JaySynthAudioProcessor::savePatch (const File &file, int index)
{ {
String filename(file.getFullPathName()); String filename(file.getFullPathName());
} }
+11 -2
View File
@@ -205,16 +205,25 @@ public:
void copyXmlToBinary (const XmlElement& xml, juce::MemoryBlock& destData); void copyXmlToBinary (const XmlElement& xml, juce::MemoryBlock& destData);
XmlElement* getXmlFromBinary (const void* data, const int sizeInBytes); XmlElement* getXmlFromBinary (const void* data, const int sizeInBytes);
const String getParameterNameXML (int index); 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 getCurrentProgramStateInformation (MemoryBlock& destData);
void setCurrentProgramStateInformation (const void* data, int sizeInBytes); void setCurrentProgramStateInformation (const void* data, int sizeInBytes);
void getStateInformation (MemoryBlock& destData); void getStateInformation (MemoryBlock& destData);
void setStateInformation (const void* data, int sizeInBytes); void setStateInformation (const void* data, int sizeInBytes);
void loadPatch (int index, const File &file); void loadPatch (const File &file, int index);
void savePatch (int index, const File &file); void savePatch (const File &file, int index);
void loadBank (const File &file); void loadBank (const File &file);
void saveBank (const File &file); void saveBank (const File &file);
void commitEditBuffer();
//============================================================================== //==============================================================================
// These properties are public so that our editor component can access them // 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 // A bit of a hacky way to do it, but it's only a demo! Obviously in your own