Basic note on/off triggering from MIDI working.
This commit is contained in:
parent
f160931d6f
commit
c428892c56
5 changed files with 111 additions and 32 deletions
|
@ -11,6 +11,14 @@
|
||||||
#include "PluginProcessor.h"
|
#include "PluginProcessor.h"
|
||||||
#include "PluginEditor.h"
|
#include "PluginEditor.h"
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
// Parameters Tags
|
||||||
|
pOsc1Wave = 0,
|
||||||
|
pOsc2Wave,
|
||||||
|
|
||||||
|
pNumParams
|
||||||
|
};
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
JuceOplvstiAudioProcessor::JuceOplvstiAudioProcessor()
|
JuceOplvstiAudioProcessor::JuceOplvstiAudioProcessor()
|
||||||
|
@ -30,7 +38,7 @@ const String JuceOplvstiAudioProcessor::getName() const
|
||||||
|
|
||||||
int JuceOplvstiAudioProcessor::getNumParameters()
|
int JuceOplvstiAudioProcessor::getNumParameters()
|
||||||
{
|
{
|
||||||
return 0;
|
return pNumParams;
|
||||||
}
|
}
|
||||||
|
|
||||||
float JuceOplvstiAudioProcessor::getParameter (int index)
|
float JuceOplvstiAudioProcessor::getParameter (int index)
|
||||||
|
@ -40,10 +48,22 @@ float JuceOplvstiAudioProcessor::getParameter (int index)
|
||||||
|
|
||||||
void JuceOplvstiAudioProcessor::setParameter (int index, float newValue)
|
void JuceOplvstiAudioProcessor::setParameter (int index, float newValue)
|
||||||
{
|
{
|
||||||
|
switch (index) {
|
||||||
|
case pOsc1Wave:
|
||||||
|
break;
|
||||||
|
case pOsc2Wave:
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const String JuceOplvstiAudioProcessor::getParameterName (int index)
|
const String JuceOplvstiAudioProcessor::getParameterName (int index)
|
||||||
{
|
{
|
||||||
|
switch (index) {
|
||||||
|
case pOsc1Wave:
|
||||||
|
return "Carrier waveform";
|
||||||
|
case pOsc2Wave:
|
||||||
|
return "Modulator waveform";
|
||||||
|
}
|
||||||
return String::empty;
|
return String::empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,36 +146,9 @@ void JuceOplvstiAudioProcessor::changeProgramName (int index, const String& newN
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
void JuceOplvstiAudioProcessor::prepareToPlay (double sampleRate, int samplesPerBlock)
|
void JuceOplvstiAudioProcessor::prepareToPlay (double sampleRate, int samplesPerBlock)
|
||||||
{
|
{
|
||||||
Opl->SetSampleRate(sampleRate);
|
Opl->SetSampleRate((int)sampleRate);
|
||||||
// Use this method as the place to do any pre-playback
|
// Use this method as the place to do any pre-playback
|
||||||
// initialisation that you need..
|
// initialisation that you need..
|
||||||
|
|
||||||
Opl->_WriteReg(0x20,0x32);
|
|
||||||
Opl->_WriteReg(0x23,0x21);
|
|
||||||
Opl->_WriteReg(0x40,0x1a);
|
|
||||||
Opl->_WriteReg(0x43,0x09);
|
|
||||||
Opl->_WriteReg(0x60,0x84);
|
|
||||||
Opl->_WriteReg(0x63,0x84);
|
|
||||||
Opl->_WriteReg(0x80,0x29);
|
|
||||||
Opl->_WriteReg(0x83,0x44);
|
|
||||||
Opl->_WriteReg(0xe3,0x00);
|
|
||||||
Opl->_WriteReg(0xe0,0x02);
|
|
||||||
Opl->_WriteReg(0xc0,0x06);
|
|
||||||
Opl->_WriteReg(0xa0,0x8b);
|
|
||||||
Opl->_WriteReg(0xb0,0x26);
|
|
||||||
Opl->_WriteReg(0x21,0x32);
|
|
||||||
Opl->_WriteReg(0x24,0x21);
|
|
||||||
Opl->_WriteReg(0x41,0x1a);
|
|
||||||
Opl->_WriteReg(0x44,0x09);
|
|
||||||
Opl->_WriteReg(0x61,0x84);
|
|
||||||
Opl->_WriteReg(0x64,0x84);
|
|
||||||
Opl->_WriteReg(0x81,0x29);
|
|
||||||
Opl->_WriteReg(0x84,0x44);
|
|
||||||
Opl->_WriteReg(0xe4,0x00);
|
|
||||||
Opl->_WriteReg(0xe1,0x02);
|
|
||||||
Opl->_WriteReg(0xc1,0x06);
|
|
||||||
Opl->_WriteReg(0xa1,0x8b);
|
|
||||||
Opl->_WriteReg(0xb1,0x2a);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void JuceOplvstiAudioProcessor::releaseResources()
|
void JuceOplvstiAudioProcessor::releaseResources()
|
||||||
|
@ -167,6 +160,21 @@ void JuceOplvstiAudioProcessor::releaseResources()
|
||||||
void JuceOplvstiAudioProcessor::processBlock (AudioSampleBuffer& buffer, MidiBuffer& midiMessages)
|
void JuceOplvstiAudioProcessor::processBlock (AudioSampleBuffer& buffer, MidiBuffer& midiMessages)
|
||||||
{
|
{
|
||||||
buffer.clear(0, 0, buffer.getNumSamples());
|
buffer.clear(0, 0, buffer.getNumSamples());
|
||||||
|
MidiBuffer::Iterator midi_buffer_iterator(midiMessages);
|
||||||
|
|
||||||
|
MidiMessage midi_message(0);
|
||||||
|
int sample_number;
|
||||||
|
while (midi_buffer_iterator.getNextEvent(midi_message,sample_number)) {
|
||||||
|
if (midi_message.isNoteOn()) {
|
||||||
|
//note on at sample_number samples after
|
||||||
|
//the begining of the current buffer
|
||||||
|
float noteHz = MidiMessage::getMidiNoteInHertz(midi_message.getNoteNumber());
|
||||||
|
Opl->KeyOn(0, noteHz);
|
||||||
|
}
|
||||||
|
else if (midi_message.isNoteOff()) {
|
||||||
|
Opl->KeyOff(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
Opl->Generate(buffer.getNumSamples(), buffer.getSampleData(0));
|
Opl->Generate(buffer.getNumSamples(), buffer.getSampleData(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,6 +41,9 @@
|
||||||
#include "dosbox.h"
|
#include "dosbox.h"
|
||||||
#include "dbopl.h"
|
#include "dbopl.h"
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning ( disable: 4244 4127 )
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef PI
|
#ifndef PI
|
||||||
#define PI 3.14159265358979323846
|
#define PI 3.14159265358979323846
|
||||||
|
|
|
@ -27,6 +27,17 @@ void Hiopl::Generate(int length, float* buffer) {
|
||||||
|
|
||||||
void Hiopl::SetSampleRate(int hz) {
|
void Hiopl::SetSampleRate(int hz) {
|
||||||
adlib->Init(hz);
|
adlib->Init(hz);
|
||||||
|
_WriteReg(0x20,0x32); // modulator multiplier 2
|
||||||
|
_WriteReg(0x23,0x21); // carrier multiplier 1
|
||||||
|
_WriteReg(0x40,0x1a); // modulator level
|
||||||
|
_WriteReg(0x43,0x09); // carrier level
|
||||||
|
_WriteReg(0x60,0x84); // AD
|
||||||
|
_WriteReg(0x63,0x84); // AD
|
||||||
|
_WriteReg(0x80,0x29); // SR
|
||||||
|
_WriteReg(0x83,0x44); // SR
|
||||||
|
_WriteReg(0xe3,0x00); // wave select
|
||||||
|
_WriteReg(0xe0,0x02); // wave select
|
||||||
|
_WriteReg(0xc0,0x06); // carrier self-feedback level
|
||||||
}
|
}
|
||||||
|
|
||||||
void Hiopl::_WriteReg(Bit32u reg, Bit8u value) {
|
void Hiopl::_WriteReg(Bit32u reg, Bit8u value) {
|
||||||
|
@ -34,9 +45,13 @@ void Hiopl::_WriteReg(Bit32u reg, Bit8u value) {
|
||||||
regCache[reg] = value;
|
regCache[reg] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Hiopl::_ClearRegBits(Bit32u reg, Bit8u mask) {
|
||||||
|
_WriteReg(reg, regCache[reg] & ~mask);
|
||||||
|
}
|
||||||
|
|
||||||
void Hiopl::SetWaveform(int ch, int osc, Waveform wave) {
|
void Hiopl::SetWaveform(int ch, int osc, Waveform wave) {
|
||||||
assert(_CheckParams(ch, osc));
|
assert(_CheckParams(ch, osc));
|
||||||
_WriteReg(0xe0+2*ch+osc, wave);
|
_WriteReg(0xe0+2*ch+osc, (Bit8u)wave);
|
||||||
}
|
}
|
||||||
|
|
||||||
Waveform Hiopl::GetWaveform(int ch, int osc) {
|
Waveform Hiopl::GetWaveform(int ch, int osc) {
|
||||||
|
@ -44,8 +59,55 @@ Waveform Hiopl::GetWaveform(int ch, int osc) {
|
||||||
return static_cast<Waveform>(regCache[0xe0+2*ch+osc]);
|
return static_cast<Waveform>(regCache[0xe0+2*ch+osc]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Hiopl::KeyOn(int ch, int frq) {
|
void Hiopl::KeyOn(int ch, float frqHz) {
|
||||||
|
unsigned int fnum, block;
|
||||||
|
_milliHertzToFnum((unsigned int)(frqHz * 1000.0), &fnum, &block);
|
||||||
|
_WriteReg(0xa0, fnum % 0x100);
|
||||||
|
_WriteReg(0xb0, 0x20|((block&0x7)<<2)|(0x3&(fnum/0x100)));
|
||||||
|
//_WriteReg(0xa0, 0x8b);
|
||||||
|
//_WriteReg(0xb0, 0x26);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Hiopl::KeyOff(int ch) {
|
||||||
|
_ClearRegBits(0xb0, 0x20);
|
||||||
|
}
|
||||||
|
|
||||||
|
// from libgamemusic, opl-util.cpp
|
||||||
|
void Hiopl::_milliHertzToFnum(unsigned int milliHertz,
|
||||||
|
unsigned int *fnum, unsigned int *block, unsigned int conversionFactor)
|
||||||
|
{
|
||||||
|
// Special case to avoid divide by zero
|
||||||
|
if (milliHertz == 0) {
|
||||||
|
*block = 0; // actually any block will work
|
||||||
|
*fnum = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Special case for frequencies too high to produce
|
||||||
|
if (milliHertz > 6208431) {
|
||||||
|
*block = 7;
|
||||||
|
*fnum = 1023;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is a bit more efficient and doesn't need log2() from math.h
|
||||||
|
if (milliHertz > 3104215) *block = 7;
|
||||||
|
else if (milliHertz > 1552107) *block = 6;
|
||||||
|
else if (milliHertz > 776053) *block = 5;
|
||||||
|
else if (milliHertz > 388026) *block = 4;
|
||||||
|
else if (milliHertz > 194013) *block = 3;
|
||||||
|
else if (milliHertz > 97006) *block = 2;
|
||||||
|
else if (milliHertz > 48503) *block = 1;
|
||||||
|
else *block = 0;
|
||||||
|
|
||||||
|
// Slightly more efficient version
|
||||||
|
*fnum = ((unsigned long long)milliHertz << (20 - *block)) / (conversionFactor * 1000.0) + 0.5;
|
||||||
|
if ((*block == 7) && (*fnum > 1023)) {
|
||||||
|
// frequency out of range, clipping to maximum value.
|
||||||
|
*fnum = 1023;
|
||||||
|
}
|
||||||
|
assert(*block <= 7);
|
||||||
|
assert(*fnum < 1024);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Hiopl::~Hiopl() {
|
Hiopl::~Hiopl() {
|
||||||
|
|
|
@ -22,12 +22,15 @@ class Hiopl {
|
||||||
void SetSampleRate(int hz);
|
void SetSampleRate(int hz);
|
||||||
void SetWaveform(int ch, int osc, Waveform wave);
|
void SetWaveform(int ch, int osc, Waveform wave);
|
||||||
Waveform GetWaveform(int ch, int osc);
|
Waveform GetWaveform(int ch, int osc);
|
||||||
void Hiopl::KeyOn(int ch, int frq);
|
void KeyOn(int ch, float frqHz);
|
||||||
|
void KeyOff(int ch);
|
||||||
void _WriteReg(Bit32u reg, Bit8u value);
|
void _WriteReg(Bit32u reg, Bit8u value);
|
||||||
|
void _ClearRegBits(Bit32u reg, Bit8u mask);
|
||||||
~Hiopl();
|
~Hiopl();
|
||||||
private:
|
private:
|
||||||
Adlib::Handler *adlib;
|
Adlib::Handler *adlib;
|
||||||
Bit8u regCache[256];
|
Bit8u regCache[256];
|
||||||
Bit32s *Buf32;
|
Bit32s *Buf32;
|
||||||
bool _CheckParams(int ch, int osc);
|
bool _CheckParams(int ch, int osc);
|
||||||
|
void _milliHertzToFnum(unsigned int milliHertz, unsigned int *fnum, unsigned int *block, unsigned int conversionFactor=49716);
|
||||||
};
|
};
|
||||||
|
|
|
@ -24,6 +24,9 @@
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#pragma warning ( disable : 4786 )
|
#pragma warning ( disable : 4786 )
|
||||||
#pragma warning ( disable : 4290 )
|
#pragma warning ( disable : 4290 )
|
||||||
|
#pragma warning ( disable : 4512 ) // assignment operator could not be generated
|
||||||
|
#pragma warning ( disable : 4100 ) // unreferenced parameter
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue