Add some quick and dirty MIDI pitch wheel control.
This commit is contained in:
parent
de9f8732a7
commit
1ce43da7ac
4 changed files with 32 additions and 5 deletions
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in a new issue