diff --git a/OB-Xd.jucer b/OB-Xd.jucer index 6d4ba21..1165bb0 100644 --- a/OB-Xd.jucer +++ b/OB-Xd.jucer @@ -65,8 +65,7 @@ - + @@ -75,19 +74,19 @@ osxArchitecture="64BitIntel"/> - - - - - - - - - - - - - + + + + + + + + + + + + + @@ -96,19 +95,19 @@ targetName="Obxd64"/> - - - - - - - - - - - - - + + + + + + + + + + + + + @@ -139,22 +138,22 @@ - - + + - - - - - - - - - - - - + + + + + + + + + + + + @@ -165,36 +164,37 @@ - - - - - - - - - - - - + + + + + + + + + + + + - - - - - - - - - - - - - + + + + + + + + + + + + + diff --git a/Source/Engine/Motherboard.h b/Source/Engine/Motherboard.h index 12477f0..21d9201 100755 --- a/Source/Engine/Motherboard.h +++ b/Source/Engine/Motherboard.h @@ -48,8 +48,9 @@ public: bool vibratoEnabled; float Volume; - const static int MAX_VOICES=8; - float pannings[MAX_VOICES]; + const static int MAX_VOICES = 32; + const static int MAX_PANNINGS = 8; + float pannings[MAX_PANNINGS]; ObxdVoice voices[MAX_VOICES]; bool uni; bool Oversample; @@ -79,7 +80,7 @@ public: // pannings = new float[MAX_VOICES]; totalvc = MAX_VOICES; vq = VoiceQueue(MAX_VOICES,voices); - for(int i = 0 ; i < MAX_VOICES;++i) + for(int i = 0 ; i < MAX_PANNINGS;++i) { pannings[i]= 0.5; } @@ -362,11 +363,12 @@ public: float x1 = processSynthVoice(voices[i],lfovalue,viblfo); if(Oversample) { - float x2 = processSynthVoice(voices[i],lfovalue2,viblfo2); vlo+=x2*(1-pannings[i]); - vro+=x2*(pannings[i]); + float x2 = processSynthVoice(voices[i],lfovalue2,viblfo2); + vlo+=x2*(1-pannings[i % MAX_PANNINGS]); + vro+=x2*(pannings[i % MAX_PANNINGS]); } - vl+=x1*(1-pannings[i]); - vr+=x1*(pannings[i]); + vl+=x1*(1-pannings[i % MAX_PANNINGS]); + vr+=x1*(pannings[i % MAX_PANNINGS]); } if(Oversample) { diff --git a/Source/Engine/SynthEngine.h b/Source/Engine/SynthEngine.h index 7e74550..c916590 100755 --- a/Source/Engine/SynthEngine.h +++ b/Source/Engine/SynthEngine.h @@ -166,7 +166,7 @@ public: } void setVoiceCount(float param) { - synth.setVoiceCount(roundToInt((param*7) +1)); + synth.setVoiceCount(roundToInt((param*(synth.MAX_VOICES-1)) +1)); } void procPitchWheelAmount(float param) { @@ -184,7 +184,7 @@ public: } void processPan(float param,int idx) { - synth.pannings[idx-1] = param; + synth.pannings[(idx-1) % synth.MAX_PANNINGS] = param; } void processTune(float param) { diff --git a/Source/Images/voices.png b/Source/Images/voices.png index c8af407..fdaa2a3 100755 Binary files a/Source/Images/voices.png and b/Source/Images/voices.png differ diff --git a/Source/PluginEditor.cpp b/Source/PluginEditor.cpp index c50300f..989a9d5 100755 --- a/Source/PluginEditor.cpp +++ b/Source/PluginEditor.cpp @@ -287,14 +287,8 @@ void ObxdAudioProcessorEditor::rebuildComponents() envelopeDetuneKnob = addTinyKnob(1353,300,ownerFilter,ENVDER,"Env",0.2); voiceSwitch = addNormalButtonList(124,338,17,ownerFilter,VOICE_COUNT,"VoiceCount",ImageCache::getFromMemory(BinaryData::voices_png,BinaryData::voices_pngSize)); - voiceSwitch ->addChoise("1"); - voiceSwitch ->addChoise("2"); - voiceSwitch ->addChoise("3"); - voiceSwitch ->addChoise("4"); - voiceSwitch ->addChoise("5"); - voiceSwitch ->addChoise("6"); - voiceSwitch ->addChoise("7"); - voiceSwitch ->addChoise("8"); + for (int i=1; i <= 32; i++) + voiceSwitch ->addChoise(String(i)); voiceSwitch ->setValue(ownerFilter->getParameter(VOICE_COUNT),dontSendNotification); legatoSwitch = addNormalButtonList(25,338,65,ownerFilter,LEGATOMODE,"Legato",ImageCache::getFromMemory(BinaryData::legato_png,BinaryData::legato_pngSize)); @@ -400,14 +394,8 @@ void ObxdAudioProcessorEditor::rebuildComponents() bendLfoRateKnob = addNormalKnobClassic(364,345,ownerFilter,BENDLFORATE,"ModRate",0.4); voiceSwitch = addNormalButtonListClassic(172,321,38,ownerFilter,VOICE_COUNT,"VoiceCount",ImageCache::getFromFile(skinFolder.getChildFile("voices.png"))); - voiceSwitch ->addChoise("1"); - voiceSwitch ->addChoise("2"); - voiceSwitch ->addChoise("3"); - voiceSwitch ->addChoise("4"); - voiceSwitch ->addChoise("5"); - voiceSwitch ->addChoise("6"); - voiceSwitch ->addChoise("7"); - voiceSwitch ->addChoise("8"); + for (int i=1; i <= 32; i++) + voiceSwitch->addChoise(String(i)); voiceSwitch ->setValue(ownerFilter->getParameter(VOICE_COUNT),dontSendNotification); legatoSwitch = addNormalButtonListClassic(65,321,95,ownerFilter,LEGATOMODE,"Legato",ImageCache::getFromFile(skinFolder.getChildFile("legato.png"))); @@ -511,7 +499,7 @@ void ObxdAudioProcessorEditor::sliderValueChanged (Slider* c) handleSParam(lfoAmt1Knob,LFO1AMT) handleSParam(lfoAmt2Knob,LFO2AMT) - handleSParam(pan1Knob,PAN1) + handleSParam(pan1Knob,PAN1) handleSParam(pan2Knob,PAN2) handleSParam(pan3Knob,PAN3) handleSParam(pan4Knob,PAN4) @@ -671,12 +659,12 @@ void ObxdAudioProcessorEditor::mouseUp(const MouseEvent& e) int bankStart = 1000; { - const String currentBank = getFilter()->getCurrentBankFile().getFileName(); - + const String currentBank = getFilter()->getCurrentBankFile().getFileName(); + for (int i = 0; i < banks.size(); ++i) { const File bank = banks.getUnchecked(i); - bankMenu.addItem(i + bankStart + 1, bank.getFileNameWithoutExtension(), true, bank.getFileName() == currentBank); + bankMenu.addItem(i + bankStart + 1, bank.getFileName(), true, bank.getFileName() == currentBank); } menu.addSubMenu("Banks", bankMenu); diff --git a/Source/PluginProcessor.cpp b/Source/PluginProcessor.cpp index cba424f..166cf82 100755 --- a/Source/PluginProcessor.cpp +++ b/Source/PluginProcessor.cpp @@ -11,6 +11,9 @@ It contains the basic startup code for a Juce application. #include "PluginEditor.h" #include "Engine/Params.h" +// Compare JUCE_VERSION against this to check for JUCE 5.4.3 and earlier +#define JUCE_543 328707 + //only sse2 version on windows #ifdef _WINDOWS #define __SSE2__ @@ -724,7 +727,7 @@ AudioProcessorEditor* ObxdAudioProcessor::createEditor() } //============================================================================== -void ObxdAudioProcessor::getStateInformation (MemoryBlock& destData) +void ObxdAudioProcessor::getStateInformation(MemoryBlock& destData) { XmlElement xmlState = XmlElement("Datsounds"); xmlState.setAttribute(S("currentProgram"), programs.currentProgram); @@ -734,6 +737,7 @@ void ObxdAudioProcessor::getStateInformation (MemoryBlock& destData) { XmlElement* xpr = new XmlElement("program"); xpr->setAttribute(S("programName"), programs.programs[i].name); + xpr->setAttribute(S("voiceCount"), Motherboard::MAX_VOICES); for (int k = 0; k < PARAM_COUNT; ++k) { @@ -750,60 +754,7 @@ void ObxdAudioProcessor::getStateInformation (MemoryBlock& destData) xmlState.setAttribute(String(i), bindings.controllers[i]); } - copyXmlToBinary(xmlState,destData); -} - -void ObxdAudioProcessor::setStateInformation (const void* data, int sizeInBytes) -{ - if (XmlElement* const xmlState = getXmlFromBinary(data,sizeInBytes)) - { - XmlElement* xprogs = xmlState->getFirstChildElement(); - if (xprogs->hasTagName(S("programs"))) - { - int i = 0; - forEachXmlChildElement(*xprogs, e) - { - programs.programs[i].setDefaultValues(); - - for (int k = 0; k < PARAM_COUNT; ++k) - { - programs.programs[i].values[k] = e->getDoubleAttribute(String(k), programs.programs[i].values[k]); - } - - programs.programs[i].name = e->getStringAttribute(S("programName"), S("Default")); - - ++i; - } - } - - for (int i = 0; i < 255; ++i) - { - bindings.controllers[i] = xmlState->getIntAttribute(String(i), 0); - } - - setCurrentProgram(xmlState->getIntAttribute(S("currentProgram"), 0)); - - delete xmlState; - } -} - -void ObxdAudioProcessor::setCurrentProgramStateInformation(const void* data,int sizeInBytes) -{ - if (XmlElement* const e = getXmlFromBinary(data, sizeInBytes)) - { - programs.currentProgramPtr->setDefaultValues(); - - for (int k = 0; k < PARAM_COUNT; ++k) - { - programs.currentProgramPtr->values[k] = e->getDoubleAttribute(String(k), programs.currentProgramPtr->values[k]); - } - - programs.currentProgramPtr->name = e->getStringAttribute(S("programName"), S("Default")); - - setCurrentProgram(programs.currentProgram); - - delete e; - } + copyXmlToBinary(xmlState, destData); } void ObxdAudioProcessor::getCurrentProgramStateInformation(MemoryBlock& destData) @@ -815,11 +766,85 @@ void ObxdAudioProcessor::getCurrentProgramStateInformation(MemoryBlock& destData xmlState.setAttribute(String(k), programs.currentProgramPtr->values[k]); } + xmlState.setAttribute(S("voiceCount"), Motherboard::MAX_VOICES); xmlState.setAttribute(S("programName"), programs.currentProgramPtr->name); copyXmlToBinary(xmlState, destData); } +void ObxdAudioProcessor::setStateInformation(const void* data, int sizeInBytes) +{ +#if JUCE_VERSION <= JUCE_543 + XmlElement * const xmlState = getXmlFromBinary(data, sizeInBytes); +#else + std::unique_ptr xmlState = getXmlFromBinary(data, sizeInBytes); +#endif + if (xmlState) + { + XmlElement* xprogs = xmlState->getFirstChildElement(); + if (xprogs->hasTagName(S("programs"))) + { + int i = 0; + forEachXmlChildElement(*xprogs, e) + { + bool newFormat = e->hasAttribute("voiceCount"); + programs.programs[i].setDefaultValues(); + + for (int k = 0; k < PARAM_COUNT; ++k) + { + float value = float(e->getDoubleAttribute(String(k), programs.programs[i].values[k])); + if (!newFormat && k == VOICE_COUNT) value *= 0.25f; + programs.programs[i].values[k] = value; + } + + programs.programs[i].name = e->getStringAttribute(S("programName"), S("Default")); + + ++i; + } + } + + for (int i = 0; i < 255; ++i) + { + bindings.controllers[i] = xmlState->getIntAttribute(String(i), 0); + } + + setCurrentProgram(xmlState->getIntAttribute(S("currentProgram"), 0)); + +#if JUCE_VERSION <= JUCE_543 + delete xmlState; +#endif + } + } + +void ObxdAudioProcessor::setCurrentProgramStateInformation(const void* data, int sizeInBytes) +{ +#if JUCE_VERSION <= JUCE_543 + XmlElement * const e = getXmlFromBinary(data, sizeInBytes); +#else + std::unique_ptr e = getXmlFromBinary(data, sizeInBytes); +#endif + if (e) + { + programs.currentProgramPtr->setDefaultValues(); + + bool newFormat = e->hasAttribute("voiceCount"); + for (int k = 0; k < PARAM_COUNT; ++k) + { + float value = float(e->getDoubleAttribute(String(k), programs.currentProgramPtr->values[k])); + if (!newFormat && k == VOICE_COUNT) value *= 0.25f; + programs.currentProgramPtr->values[k] = value; + } + + programs.currentProgramPtr->name = e->getStringAttribute(S("programName"), S("Default")); + + setCurrentProgram(programs.currentProgram); + +#if JUCE_VERSION <= JUCE_543 + delete e; +#endif + } +} + //============================================================================== bool ObxdAudioProcessor::loadFromFXBFile(const File& fxbFile) {