diff --git a/Source/EnumFloatParameter.cpp b/Source/EnumFloatParameter.cpp index b8dab6a..4b23a3e 100644 --- a/Source/EnumFloatParameter.cpp +++ b/Source/EnumFloatParameter.cpp @@ -20,6 +20,15 @@ int EnumFloatParameter::getParameterIndex(void) return i; } +void EnumFloatParameter::setParameterIndex(int i) +{ + this->value = (float)i/(float)values.size(); + if (this->value < 0.0f) + this->value = 0.0f; + else if (this->value > 1.0f) + this->value = 1.0f; +} + String EnumFloatParameter::getParameterText(void) { return values[this->getParameterIndex()]; diff --git a/Source/EnumFloatParameter.h b/Source/EnumFloatParameter.h index bc880b8..0e89030 100644 --- a/Source/EnumFloatParameter.h +++ b/Source/EnumFloatParameter.h @@ -8,6 +8,7 @@ public: ~EnumFloatParameter(void); String getParameterText(void); int getParameterIndex(void); + void EnumFloatParameter::setParameterIndex(int); private: StringArray values; }; diff --git a/Source/IntFloatParameter.cpp b/Source/IntFloatParameter.cpp index b84c3f0..284ab77 100644 --- a/Source/IntFloatParameter.cpp +++ b/Source/IntFloatParameter.cpp @@ -15,12 +15,21 @@ IntFloatParameter::~IntFloatParameter(void) int IntFloatParameter::getParameterValue(void) { int range = max - min; - int i = (int)(this->value * range); + int i = (int)(this->value * range) + min; if (i > range) i = range; return i; } +void IntFloatParameter::setParameterValue(int i) +{ + this->value = (float)(i - min)/(float)(max - min); + if (this->value < 0.0f) + this->value = 0.0f; + else if (this->value > 1.0f) + this->value = 1.0f; +} + String IntFloatParameter::getParameterText(void) { return String(this->getParameterValue()); diff --git a/Source/IntFloatParameter.h b/Source/IntFloatParameter.h index 9d2c2f2..b9735ae 100644 --- a/Source/IntFloatParameter.h +++ b/Source/IntFloatParameter.h @@ -8,6 +8,7 @@ public: ~IntFloatParameter(void); String getParameterText(void); int getParameterValue(void); + void setParameterValue(int i); private: int min; int max; diff --git a/Source/PluginProcessor.cpp b/Source/PluginProcessor.cpp index 291699a..c41d0a4 100644 --- a/Source/PluginProcessor.cpp +++ b/Source/PluginProcessor.cpp @@ -9,8 +9,10 @@ JuceOplvstiAudioProcessor::JuceOplvstiAudioProcessor() Opl = new Hiopl(44100); // 1 second at 44100 Opl->SetSampleRate(44100); Opl->EnableWaveformControl(); - Opl->EnableSustain(1, 1); - Opl->EnableSustain(1, 2); + for (int i = 1; i <= Hiopl::CHANNELS; i++) { + Opl->EnableSustain(i, 1); + Opl->EnableSustain(i, 2); + } const String waveforms[] = {"Sine", "Half Sine", "Abs Sine", "Quarter Sine"}; params.push_back(new EnumFloatParameter("Carrier Wave", @@ -18,7 +20,7 @@ JuceOplvstiAudioProcessor::JuceOplvstiAudioProcessor() ); setParameter(params.size()-1, 0.0f); params.push_back(new EnumFloatParameter("Modulator Wave", StringArray(waveforms, sizeof(waveforms)/sizeof(String))) - ); setParameter(params.size()-1,0.0f); + ); setParameter(params.size()-1, 0.0f); /* const String levels[] = {"-0.75 dB", "-1.5 dB", "-3 dB", "-6 dB", "-12 dB", "-24 dB"}; params.push_back(new EnumFloatParameter("Carrier Attenuation", @@ -29,9 +31,9 @@ JuceOplvstiAudioProcessor::JuceOplvstiAudioProcessor() ); setParameter(params.size()-1,0.75f); */ params.push_back(new IntFloatParameter("Carrier Attenuation", 0, 63)); - setParameter(params.size()-1,0.0f); + setParameter(params.size()-1, 0.0f); params.push_back(new IntFloatParameter("Modulator Attenuation", 0, 63)); - setParameter(params.size()-1,0.75f); + setParameter(params.size()-1, 0.75f); const String frq_multipliers[] = { "x0.5", "x1", "x2", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10", "x10", "x12", "x12", "x15", "x15" @@ -44,24 +46,30 @@ JuceOplvstiAudioProcessor::JuceOplvstiAudioProcessor() ); setParameter(params.size()-1, 0.15f); params.push_back(new IntFloatParameter("Modulator Feedback", 0, 7)); - setParameter(params.size()-1,0.0f); + setParameter(params.size()-1, 0.0f); params.push_back(new IntFloatParameter("Carrier Attack", 0, 15)); - setParameter(params.size()-1,0.5f); + setParameter(params.size()-1, 0.5f); params.push_back(new IntFloatParameter("Carrier Decay", 0, 15)); - setParameter(params.size()-1,0.25f); + setParameter(params.size()-1, 0.25f); params.push_back(new IntFloatParameter("Carrier Sustain", 0, 15)); - setParameter(params.size()-1,0.125f); + setParameter(params.size()-1, 0.125f); params.push_back(new IntFloatParameter("Carrier Release", 0, 15)); - setParameter(params.size()-1,0.5f); + setParameter(params.size()-1, 0.5f); params.push_back(new IntFloatParameter("Modulator Attack", 0, 15)); - setParameter(params.size()-1,0.5f); + setParameter(params.size()-1, 0.5f); params.push_back(new IntFloatParameter("Modulator Decay", 0, 15)); - setParameter(params.size()-1,0.25f); + setParameter(params.size()-1, 0.25f); params.push_back(new IntFloatParameter("Modulator Sustain", 0, 15)); - setParameter(params.size()-1,0.25f); + setParameter(params.size()-1, 0.25f); params.push_back(new IntFloatParameter("Modulator Release", 0, 15)); - setParameter(params.size()-1,0.25f); + setParameter(params.size()-1, 0.25f); + + for(int i = 0; i < params.size(); i++) { + paramIdxByName[params[i]->getName()] = i; + } + + //programs[" } @@ -85,6 +93,22 @@ float JuceOplvstiAudioProcessor::getParameter (int index) return params[index]->getParameter(); } +void JuceOplvstiAudioProcessor::setIntParameter (String name, int value) +{ + int i = paramIdxByName[name]; + IntFloatParameter* p = (IntFloatParameter*)params[i]; + p->setParameterValue(value); + setParameter(i, p->getParameter()); +} + +void JuceOplvstiAudioProcessor::setEnumParameter (String name, int index) +{ + int i = paramIdxByName[name]; + EnumFloatParameter* p = (EnumFloatParameter*)params[i]; + p->setParameterIndex(index); + setParameter(i, p->getParameter()); +} + void JuceOplvstiAudioProcessor::setParameter (int index, float newValue) { FloatParameter* p = params[index]; @@ -95,22 +119,22 @@ void JuceOplvstiAudioProcessor::setParameter (int index, float newValue) osc = 1; } if (name.endsWith("Wave")) { - Opl->SetWaveform(1, osc, (Waveform)((EnumFloatParameter*)p)->getParameterIndex()); + for(int c=1;c<=Hiopl::CHANNELS;c++) Opl->SetWaveform(c, osc, (Waveform)((EnumFloatParameter*)p)->getParameterIndex()); } else if (name.endsWith("Attenuation")) { //Opl->SetAttenuation(1, osc, 0x1<<((EnumFloatParameter*)p)->getParameterIndex()); - Opl->SetAttenuation(1, osc, ((IntFloatParameter*)p)->getParameterValue()); + for(int c=1;c<=Hiopl::CHANNELS;c++) Opl->SetAttenuation(c, osc, ((IntFloatParameter*)p)->getParameterValue()); } else if (name.endsWith("Frequency Multiplier")) { - Opl->SetFrequencyMultiple(1, osc, (FreqMultiple)((EnumFloatParameter*)p)->getParameterIndex()); + for(int c=1;c<=Hiopl::CHANNELS;c++) Opl->SetFrequencyMultiple(c, osc, (FreqMultiple)((EnumFloatParameter*)p)->getParameterIndex()); } else if (name.endsWith("Attack")) { - Opl->SetEnvelopeAttack(1, osc, ((IntFloatParameter*)p)->getParameterValue()); + for(int c=1;c<=Hiopl::CHANNELS;c++) Opl->SetEnvelopeAttack(c, osc, ((IntFloatParameter*)p)->getParameterValue()); } else if (name.endsWith("Decay")) { - Opl->SetEnvelopeDecay(1, osc, ((IntFloatParameter*)p)->getParameterValue()); + for(int c=1;c<=Hiopl::CHANNELS;c++) Opl->SetEnvelopeDecay(c, osc, ((IntFloatParameter*)p)->getParameterValue()); } else if (name.endsWith("Sustain")) { - Opl->SetEnvelopeSustain(1, osc, ((IntFloatParameter*)p)->getParameterValue()); + for(int c=1;c<=Hiopl::CHANNELS;c++) Opl->SetEnvelopeSustain(c, osc, ((IntFloatParameter*)p)->getParameterValue()); } else if (name.endsWith("Release")) { - Opl->SetEnvelopeRelease(1, osc, ((IntFloatParameter*)p)->getParameterValue()); + for(int c=1;c<=Hiopl::CHANNELS;c++) Opl->SetEnvelopeRelease(c, osc, ((IntFloatParameter*)p)->getParameterValue()); } else if (name.endsWith("Feedback")) { - Opl->SetModulatorFeedback(1, ((IntFloatParameter*)p)->getParameterValue()); + for(int c=1;c<=Hiopl::CHANNELS;c++) Opl->SetModulatorFeedback(c, ((IntFloatParameter*)p)->getParameterValue()); } } @@ -218,14 +242,15 @@ void JuceOplvstiAudioProcessor::processBlock (AudioSampleBuffer& buffer, MidiBuf MidiMessage midi_message(0); int sample_number; while (midi_buffer_iterator.getNextEvent(midi_message,sample_number)) { + int ch = 1 + (midi_message.getNoteNumber() % Hiopl::CHANNELS); // kind of hackish, but.. if (midi_message.isNoteOn()) { //note on at sample_number samples after //the beginning of the current buffer float noteHz = (float)MidiMessage::getMidiNoteInHertz(midi_message.getNoteNumber()); - Opl->KeyOn(1, noteHz); + Opl->KeyOn(ch, noteHz); } else if (midi_message.isNoteOff()) { - Opl->KeyOff(1); + Opl->KeyOff(ch); } } Opl->Generate(buffer.getNumSamples(), buffer.getSampleData(0)); diff --git a/Source/PluginProcessor.h b/Source/PluginProcessor.h index 4319922..8437fd5 100644 --- a/Source/PluginProcessor.h +++ b/Source/PluginProcessor.h @@ -43,6 +43,8 @@ public: float getParameter (int index); void setParameter (int index, float newValue); + void setEnumParameter (String name, int newValue); + void setIntParameter (String name, int newValue); const String getParameterName (int index); const String getParameterText (int index); @@ -71,6 +73,8 @@ public: private: Hiopl *Opl; std::vector params; + std::map paramIdxByName; + static const std::map programs; //============================================================================== JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (JuceOplvstiAudioProcessor) diff --git a/Source/hiopl.h b/Source/hiopl.h index 0f85767..33a5936 100644 --- a/Source/hiopl.h +++ b/Source/hiopl.h @@ -14,11 +14,10 @@ enum FreqMultiple }; -const int CHANNELS = 9; -const int OSCILLATORS = 2; - class Hiopl { public: + static const int CHANNELS = 9; + static const int OSCILLATORS = 2; Hiopl(int buflen); void Generate(int length, short* buffer); void Generate(int length, float* buffer);