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)
{