From b3eb3832ad3ed55256fa2259a916784659f20a2d Mon Sep 17 00:00:00 2001 From: bruce Date: Thu, 12 Sep 2013 21:58:22 +0800 Subject: [PATCH] Finally get waveform control working, add modulator feedback, fix assorted bugs. --- Source/PluginProcessor.cpp | 23 ++++++++++++++++++----- Source/hiopl.cpp | 33 ++++++++++++++++++++++----------- Source/hiopl.h | 4 +++- 3 files changed, 43 insertions(+), 17 deletions(-) diff --git a/Source/PluginProcessor.cpp b/Source/PluginProcessor.cpp index 50439a2..291699a 100644 --- a/Source/PluginProcessor.cpp +++ b/Source/PluginProcessor.cpp @@ -8,6 +8,7 @@ JuceOplvstiAudioProcessor::JuceOplvstiAudioProcessor() { Opl = new Hiopl(44100); // 1 second at 44100 Opl->SetSampleRate(44100); + Opl->EnableWaveformControl(); Opl->EnableSustain(1, 1); Opl->EnableSustain(1, 2); @@ -18,7 +19,7 @@ JuceOplvstiAudioProcessor::JuceOplvstiAudioProcessor() params.push_back(new EnumFloatParameter("Modulator Wave", StringArray(waveforms, sizeof(waveforms)/sizeof(String))) ); 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", StringArray(levels, sizeof(levels)/sizeof(String))) @@ -26,7 +27,12 @@ JuceOplvstiAudioProcessor::JuceOplvstiAudioProcessor() params.push_back(new EnumFloatParameter("Modulator Attenuation", StringArray(levels, sizeof(levels)/sizeof(String))) ); setParameter(params.size()-1,0.75f); - + */ + params.push_back(new IntFloatParameter("Carrier Attenuation", 0, 63)); + setParameter(params.size()-1,0.0f); + params.push_back(new IntFloatParameter("Modulator Attenuation", 0, 63)); + 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" }; @@ -36,6 +42,9 @@ JuceOplvstiAudioProcessor::JuceOplvstiAudioProcessor() params.push_back(new EnumFloatParameter("Modulator Frequency Multiplier", StringArray(frq_multipliers, sizeof(frq_multipliers)/sizeof(String))) ); setParameter(params.size()-1, 0.15f); + + params.push_back(new IntFloatParameter("Modulator Feedback", 0, 7)); + setParameter(params.size()-1,0.0f); params.push_back(new IntFloatParameter("Carrier Attack", 0, 15)); setParameter(params.size()-1,0.5f); @@ -53,6 +62,7 @@ JuceOplvstiAudioProcessor::JuceOplvstiAudioProcessor() setParameter(params.size()-1,0.25f); params.push_back(new IntFloatParameter("Modulator Release", 0, 15)); setParameter(params.size()-1,0.25f); + } JuceOplvstiAudioProcessor::~JuceOplvstiAudioProcessor() @@ -87,7 +97,8 @@ void JuceOplvstiAudioProcessor::setParameter (int index, float newValue) if (name.endsWith("Wave")) { Opl->SetWaveform(1, osc, (Waveform)((EnumFloatParameter*)p)->getParameterIndex()); } else if (name.endsWith("Attenuation")) { - Opl->SetAttenuation(1, osc, 0x1<<((EnumFloatParameter*)p)->getParameterIndex()); + //Opl->SetAttenuation(1, osc, 0x1<<((EnumFloatParameter*)p)->getParameterIndex()); + Opl->SetAttenuation(1, osc, ((IntFloatParameter*)p)->getParameterValue()); } else if (name.endsWith("Frequency Multiplier")) { Opl->SetFrequencyMultiple(1, osc, (FreqMultiple)((EnumFloatParameter*)p)->getParameterIndex()); } else if (name.endsWith("Attack")) { @@ -98,6 +109,8 @@ void JuceOplvstiAudioProcessor::setParameter (int index, float newValue) Opl->SetEnvelopeSustain(1, osc, ((IntFloatParameter*)p)->getParameterValue()); } else if (name.endsWith("Release")) { Opl->SetEnvelopeRelease(1, osc, ((IntFloatParameter*)p)->getParameterValue()); + } else if (name.endsWith("Feedback")) { + Opl->SetModulatorFeedback(1, ((IntFloatParameter*)p)->getParameterValue()); } } @@ -209,10 +222,10 @@ void JuceOplvstiAudioProcessor::processBlock (AudioSampleBuffer& buffer, MidiBuf //note on at sample_number samples after //the beginning of the current buffer float noteHz = (float)MidiMessage::getMidiNoteInHertz(midi_message.getNoteNumber()); - Opl->KeyOn(0, noteHz); + Opl->KeyOn(1, noteHz); } else if (midi_message.isNoteOff()) { - Opl->KeyOff(0); + Opl->KeyOff(1); } } Opl->Generate(buffer.getNumSamples(), buffer.getSampleData(0)); diff --git a/Source/hiopl.cpp b/Source/hiopl.cpp index 79b5855..9be927a 100644 --- a/Source/hiopl.cpp +++ b/Source/hiopl.cpp @@ -78,14 +78,13 @@ void Hiopl::_ClearRegBits(Bit32u reg, Bit8u mask) { _WriteReg(reg, regCache[reg] & ~mask); } -void Hiopl::SetWaveform(int ch, int osc, Waveform wave) { - int offset = this->_GetOffset(ch, osc); - _WriteReg(0xe0+offset, (Bit8u)wave); +void Hiopl::EnableWaveformControl() { + _WriteReg(0x01, 0x20); } -Waveform Hiopl::GetWaveform(int ch, int osc) { - assert(_CheckParams(ch, osc)); - return static_cast(regCache[0xe0+2*ch+osc]); +void Hiopl::SetWaveform(int ch, int osc, Waveform wave) { + int offset = this->_GetOffset(ch, osc); + _WriteReg(0xe0+offset, (Bit8u)wave, 0x3); } void Hiopl::SetAttenuation(int ch, int osc, int level) { @@ -95,7 +94,7 @@ void Hiopl::SetAttenuation(int ch, int osc, int level) { void Hiopl::SetFrequencyMultiple(int ch, int osc, FreqMultiple mult) { int offset = this->_GetOffset(ch, osc); - _WriteReg(0x20+offset, (Bit8u)mult);//, 0xf); + _WriteReg(0x20+offset, (Bit8u)mult, 0xf); } void Hiopl::SetEnvelopeAttack(int ch, int osc, int t) { @@ -123,15 +122,22 @@ void Hiopl::EnableSustain(int ch, int osc) { _WriteReg(0x20+offset, (Bit8u)0x20, 0x20); } +void Hiopl::SetModulatorFeedback(int ch, int level) { + int offset = this->_GetOffset(ch); + _WriteReg(0xc0+offset, (Bit8u)level, 0x0e); +} + void Hiopl::KeyOn(int ch, float frqHz) { unsigned int fnum, block; + int offset = this->_GetOffset(ch); _milliHertzToFnum((unsigned int)(frqHz * 1000.0), &fnum, &block); - _WriteReg(0xa0, fnum % 0x100); - _WriteReg(0xb0, 0x20|((block&0x7)<<2)|(0x3&(fnum/0x100))); + _WriteReg(0xa0+offset, fnum % 0x100); + _WriteReg(0xb0+offset, 0x20|((block&0x7)<<2)|(0x3&(fnum/0x100))); } void Hiopl::KeyOff(int ch) { - _ClearRegBits(0xb0, 0x20); + int offset = this->_GetOffset(ch); + _ClearRegBits(0xb0+offset, 0x20); } // from libgamemusic, opl-util.cpp @@ -176,7 +182,7 @@ Hiopl::~Hiopl() { delete Buf32; }; -bool Hiopl::_CheckParams(int ch, int osc) { +bool Hiopl::_CheckParams(int ch, int osc=OSCILLATORS) { return ch > 0 && ch <= CHANNELS && osc > 0 && osc <= OSCILLATORS; } @@ -184,3 +190,8 @@ int Hiopl::_GetOffset(int ch, int osc) { assert(_CheckParams(ch, osc)); return (1 == osc) ? _op1offset[ch] : _op2offset[ch]; } + +int Hiopl::_GetOffset(int ch) { + assert(_CheckParams(ch)); + return ch - 1; +} diff --git a/Source/hiopl.h b/Source/hiopl.h index 95db478..0f85767 100644 --- a/Source/hiopl.h +++ b/Source/hiopl.h @@ -23,8 +23,8 @@ class Hiopl { void Generate(int length, short* buffer); void Generate(int length, float* buffer); void SetSampleRate(int hz); + void EnableWaveformControl(); void SetWaveform(int ch, int osc, Waveform wave); - Waveform GetWaveform(int ch, int osc); void SetAttenuation(int ch, int osc, int level); void SetFrequencyMultiple(int ch, int osc, FreqMultiple mult); void SetEnvelopeAttack(int ch, int osc, int t); @@ -32,6 +32,7 @@ class Hiopl { void SetEnvelopeSustain(int ch, int osc, int level); void SetEnvelopeRelease(int ch, int osc, int t); void EnableSustain(int ch, int osc); + void SetModulatorFeedback(int ch, int level); void KeyOn(int ch, float frqHz); void KeyOff(int ch); void _WriteReg(Bit32u reg, Bit8u value, Bit8u mask=0x0); @@ -43,6 +44,7 @@ class Hiopl { Bit32s *Buf32; bool _CheckParams(int ch, int osc); int _GetOffset(int ch, int osc); + int _GetOffset(int ch); void _milliHertzToFnum(unsigned int milliHertz, unsigned int *fnum, unsigned int *block, unsigned int conversionFactor=49716); std::map _op1offset; std::map _op2offset;