From 1ce43da7ac284aca5e2def87952d1d9efc125e4a Mon Sep 17 00:00:00 2001 From: bruce Date: Mon, 23 Dec 2013 15:51:29 +0800 Subject: [PATCH] Add some quick and dirty MIDI pitch wheel control. --- Source/PluginProcessor.cpp | 19 +++++++++++++++++++ Source/PluginProcessor.h | 2 ++ Source/hiopl.cpp | 15 ++++++++++----- Source/hiopl.h | 1 + 4 files changed, 32 insertions(+), 5 deletions(-) diff --git a/Source/PluginProcessor.cpp b/Source/PluginProcessor.cpp index 0c1777f..ea71510 100644 --- a/Source/PluginProcessor.cpp +++ b/Source/PluginProcessor.cpp @@ -120,6 +120,7 @@ JuceOplvstiAudioProcessor::JuceOplvstiAudioProcessor() for (int i = 0; i < Hiopl::CHANNELS+1; i++) { active_notes[i] = NO_NOTE; } + currentScaledBend = 1.0f; } void JuceOplvstiAudioProcessor::initPrograms() @@ -366,6 +367,17 @@ void JuceOplvstiAudioProcessor::initPrograms() } +void JuceOplvstiAudioProcessor::applyPitchBend() +{ // apply the currently configured pitch bend to all active notes. + for (int i = 1; i <= Hiopl::CHANNELS; i++) { + if (NO_NOTE != active_notes[i]) { + float f = (float)MidiMessage::getMidiNoteInHertz(active_notes[i]); + f *= currentScaledBend; + Opl->SetFrequency(i, f); + } + } +} + JuceOplvstiAudioProcessor::~JuceOplvstiAudioProcessor() { } @@ -658,6 +670,7 @@ void JuceOplvstiAudioProcessor::processBlock (AudioSampleBuffer& buffer, MidiBuf } Opl->KeyOn(ch, noteHz); active_notes[ch] = n; + applyPitchBend(); } else if (midi_message.isNoteOff()) { int n = midi_message.getNoteNumber(); @@ -668,6 +681,12 @@ void JuceOplvstiAudioProcessor::processBlock (AudioSampleBuffer& buffer, MidiBuf Opl->KeyOff(ch); active_notes[ch] = NO_NOTE; } + else if (midi_message.isPitchWheel()) { + int bend = midi_message.getPitchWheelValue() - 0x2000; // range -8192 to 8191 + // 1.05946309436 == (2^(1/1200))^100 == 1 semitone == 100 cents + currentScaledBend = 1.0f + bend * .05775f / 8192; + applyPitchBend(); + } } Opl->Generate(buffer.getNumSamples(), buffer.getSampleData(0)); } diff --git a/Source/PluginProcessor.h b/Source/PluginProcessor.h index 1118cc4..e3cac2f 100644 --- a/Source/PluginProcessor.h +++ b/Source/PluginProcessor.h @@ -24,6 +24,7 @@ public: //============================================================================== JuceOplvstiAudioProcessor(); void initPrograms(); + void applyPitchBend(); ~JuceOplvstiAudioProcessor(); //============================================================================== @@ -88,6 +89,7 @@ private: bool velocity; static const int NO_NOTE=-1; int active_notes[Hiopl::CHANNELS+1]; // keyed by channel + float currentScaledBend; //============================================================================== JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (JuceOplvstiAudioProcessor) diff --git a/Source/hiopl.cpp b/Source/hiopl.cpp index 2d370ab..f6d520b 100644 --- a/Source/hiopl.cpp +++ b/Source/hiopl.cpp @@ -160,11 +160,7 @@ void Hiopl::SetModulatorFeedback(int ch, int level) { } 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+offset, fnum % 0x100); - _WriteReg(0xb0+offset, 0x20|((block&0x7)<<2)|(0x3&(fnum/0x100))); + Hiopl::SetFrequency(ch, frqHz, true); } void Hiopl::KeyOff(int ch) { @@ -172,6 +168,15 @@ void Hiopl::KeyOff(int ch) { _ClearRegBits(0xb0+offset, 0x20); } +void Hiopl::SetFrequency(int ch, float frqHz, bool keyOn) { + unsigned int fnum, block; + int offset = this->_GetOffset(ch); + _milliHertzToFnum((unsigned int)(frqHz * 1000.0), &fnum, &block); + _WriteReg(0xa0+offset, fnum % 0x100); + uint8 trig = (regCache[0xb0+offset] & 0x20) | (keyOn ? 0x20 : 0x00); + _WriteReg(0xb0+offset, trig|((block&0x7)<<2)|(0x3&(fnum/0x100))); +} + // from libgamemusic, opl-util.cpp void Hiopl::_milliHertzToFnum(unsigned int milliHertz, unsigned int *fnum, unsigned int *block, unsigned int conversionFactor) diff --git a/Source/hiopl.h b/Source/hiopl.h index 34f36e6..bd05bfe 100644 --- a/Source/hiopl.h +++ b/Source/hiopl.h @@ -46,6 +46,7 @@ class Hiopl { void SetModulatorFeedback(int ch, int level); void KeyOn(int ch, float frqHz); void KeyOff(int ch); + void SetFrequency(int ch, float frqHz, bool keyOn=false); void _WriteReg(Bit32u reg, Bit8u value, Bit8u mask=0x0); void _ClearRegBits(Bit32u reg, Bit8u mask); ~Hiopl();