Now supports setting frequency multipliers and attenuation levels.
This commit is contained in:
parent
7fe1775859
commit
ad1167f562
3 changed files with 108 additions and 24 deletions
|
@ -1,13 +1,3 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file was auto-generated!
|
||||
|
||||
It contains the basic startup code for a Juce application.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#include "PluginProcessor.h"
|
||||
#include "PluginEditor.h"
|
||||
#include "EnumFloatParameter.h"
|
||||
|
@ -23,6 +13,22 @@ JuceOplvstiAudioProcessor::JuceOplvstiAudioProcessor()
|
|||
params.push_back(new EnumFloatParameter("Modulator Wave",
|
||||
StringArray(waveforms, sizeof(waveforms)/sizeof(String)))
|
||||
);
|
||||
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)))
|
||||
);
|
||||
params.push_back(new EnumFloatParameter("Modulator Attenuation",
|
||||
StringArray(levels, sizeof(levels)/sizeof(String)))
|
||||
);
|
||||
const String frq_multipliers[] = {
|
||||
"x0.5", "x1", "x2", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10", "x10", "x12", "x12", "x15", "x15"
|
||||
};
|
||||
params.push_back(new EnumFloatParameter("Carrier Frequency Multiplier",
|
||||
StringArray(frq_multipliers, sizeof(frq_multipliers)/sizeof(String)))
|
||||
);
|
||||
params.push_back(new EnumFloatParameter("Modulator Frequency Multiplier",
|
||||
StringArray(frq_multipliers, sizeof(frq_multipliers)/sizeof(String)))
|
||||
);
|
||||
}
|
||||
|
||||
JuceOplvstiAudioProcessor::~JuceOplvstiAudioProcessor()
|
||||
|
@ -47,7 +53,22 @@ float JuceOplvstiAudioProcessor::getParameter (int index)
|
|||
|
||||
void JuceOplvstiAudioProcessor::setParameter (int index, float newValue)
|
||||
{
|
||||
params[index]->setParameter(newValue);
|
||||
FloatParameter* p = params[index];
|
||||
p->setParameter(newValue);
|
||||
String name = p->getName();
|
||||
if (name == "Carrier Wave") {
|
||||
Opl->SetWaveform(1, 1, (Waveform)((EnumFloatParameter*)p)->getParameterIndex());
|
||||
} else if (name == "Modulator Wave") {
|
||||
Opl->SetWaveform(1, 2, (Waveform)((EnumFloatParameter*)p)->getParameterIndex());
|
||||
} else if (name == "Modulator Attenuation") {
|
||||
Opl->SetAttenuation(1, 1, 0x1<<((EnumFloatParameter*)p)->getParameterIndex());
|
||||
} else if (name == "Carrier Attenuation") {
|
||||
Opl->SetAttenuation(1, 2, 0x1<<((EnumFloatParameter*)p)->getParameterIndex());
|
||||
} else if (name == "Carrier Frequency Multiplier") {
|
||||
Opl->SetFrequencyMultiple(1, 1, (FreqMultiple)((EnumFloatParameter*)p)->getParameterIndex());
|
||||
} else if (name == "Modulator Frequency Multiplier") {
|
||||
Opl->SetFrequencyMultiple(1, 2, (FreqMultiple)((EnumFloatParameter*)p)->getParameterIndex());
|
||||
}
|
||||
}
|
||||
|
||||
const String JuceOplvstiAudioProcessor::getParameterName (int index)
|
||||
|
|
|
@ -1,12 +1,36 @@
|
|||
#include "Hiopl.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include "../JuceLibraryCode/JuceHeader.h"
|
||||
|
||||
// A higher level wrapper around the DOSBox OPL emulator.
|
||||
|
||||
Hiopl::Hiopl(int buflen) {
|
||||
adlib = new DBOPL::Handler();
|
||||
Buf32 = new Bit32s[buflen];
|
||||
_op1offset[1] = 0x0;
|
||||
_op1offset[2] = 0x1;
|
||||
_op1offset[3] = 0x2;
|
||||
_op1offset[4] = 0x8;
|
||||
_op1offset[5] = 0x9;
|
||||
_op1offset[6] = 0xa;
|
||||
_op1offset[7] = 0x10;
|
||||
_op1offset[8] = 0x11;
|
||||
_op1offset[9] = 0x12;
|
||||
|
||||
_op2offset[1] = 0x3;
|
||||
_op2offset[2] = 0x4;
|
||||
_op2offset[3] = 0x5;
|
||||
_op2offset[4] = 0xb;
|
||||
_op2offset[5] = 0xc;
|
||||
_op2offset[6] = 0xd;
|
||||
_op2offset[7] = 0x13;
|
||||
_op2offset[8] = 0x14;
|
||||
_op2offset[9] = 0x15;
|
||||
|
||||
for (int i = 0; i < 256; i++) {
|
||||
_WriteReg(i, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void Hiopl::Generate(int length, short* buffer) {
|
||||
|
@ -23,24 +47,40 @@ void Hiopl::Generate(int length, float* buffer) {
|
|||
for (int i = 0; i < length; i++) {
|
||||
buffer[i] = (float)(Buf32[i])/32768.0f;
|
||||
}
|
||||
/*
|
||||
AudioData::ConverterInstance<
|
||||
AudioData::Pointer <AudioData::Int16,
|
||||
AudioData::NativeEndian,
|
||||
AudioData::Interleaved,
|
||||
AudioData::Const>,
|
||||
AudioData::Pointer <AudioData::Float32,
|
||||
AudioData::NativeEndian,
|
||||
AudioData::NonInterleaved,
|
||||
AudioData::NonConst>
|
||||
>converter;
|
||||
converter.convertSamples(buffer, 0, Buf32, 0, length);
|
||||
*/
|
||||
}
|
||||
|
||||
void Hiopl::SetSampleRate(int 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(0x40,0x1a); // modulator attenuation
|
||||
_WriteReg(0x43,0x09); // carrier attenuation
|
||||
_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
|
||||
//_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, Bit8u mask) {
|
||||
if (mask > 0) {
|
||||
value = (regCache[reg] & (~mask)) | (value & mask);
|
||||
}
|
||||
adlib->WriteReg(reg, value);
|
||||
regCache[reg] = value;
|
||||
}
|
||||
|
@ -50,8 +90,8 @@ void Hiopl::_ClearRegBits(Bit32u reg, Bit8u mask) {
|
|||
}
|
||||
|
||||
void Hiopl::SetWaveform(int ch, int osc, Waveform wave) {
|
||||
assert(_CheckParams(ch, osc));
|
||||
_WriteReg(0xe0+2*ch+osc, (Bit8u)wave);
|
||||
int offset = this->_GetOffset(ch, osc);
|
||||
_WriteReg(0xe0+offset, (Bit8u)wave);
|
||||
}
|
||||
|
||||
Waveform Hiopl::GetWaveform(int ch, int osc) {
|
||||
|
@ -59,6 +99,16 @@ Waveform Hiopl::GetWaveform(int ch, int osc) {
|
|||
return static_cast<Waveform>(regCache[0xe0+2*ch+osc]);
|
||||
}
|
||||
|
||||
void Hiopl::SetAttenuation(int ch, int osc, int level) {
|
||||
int offset = this->_GetOffset(ch, osc);
|
||||
_WriteReg(0x40+offset, (Bit8u)level, 0x3f);
|
||||
}
|
||||
|
||||
void Hiopl::SetFrequencyMultiple(int ch, int osc, FreqMultiple mult) {
|
||||
int offset = this->_GetOffset(ch, osc);
|
||||
_WriteReg(0x20+offset, (Bit8u)mult);//, 0xf);
|
||||
}
|
||||
|
||||
void Hiopl::KeyOn(int ch, float frqHz) {
|
||||
unsigned int fnum, block;
|
||||
_milliHertzToFnum((unsigned int)(frqHz * 1000.0), &fnum, &block);
|
||||
|
@ -115,5 +165,10 @@ Hiopl::~Hiopl() {
|
|||
};
|
||||
|
||||
bool Hiopl::_CheckParams(int ch, int osc) {
|
||||
return ch >= 0 && ch < CHANNELS && osc >= 0 && osc < OSCILLATORS;
|
||||
}
|
||||
return ch > 0 && ch <= CHANNELS && osc > 0 && osc <= OSCILLATORS;
|
||||
}
|
||||
|
||||
int Hiopl::_GetOffset(int ch, int osc) {
|
||||
assert(_CheckParams(ch, osc));
|
||||
return (1 == osc) ? _op1offset[ch] : _op2offset[ch];
|
||||
}
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
#include <map>
|
||||
|
||||
#include "adlib.h"
|
||||
#include "dbopl.h"
|
||||
|
||||
|
@ -6,11 +8,12 @@ enum Waveform
|
|||
SIN = 0, HALF_SIN = 1, ABS_SIN = 2, QUART_SIN = 3
|
||||
};
|
||||
|
||||
enum Oscillator
|
||||
enum FreqMultiple
|
||||
{
|
||||
CAR = 0, MOD = 1
|
||||
xHALF=0, x1=1, x2=2, x3=3, x4=4, x5=5, x6=6, x7=7, x8=8, x9=9, x10=10, x12=12, x15=15
|
||||
};
|
||||
|
||||
|
||||
const int CHANNELS = 9;
|
||||
const int OSCILLATORS = 2;
|
||||
|
||||
|
@ -22,9 +25,11 @@ class Hiopl {
|
|||
void SetSampleRate(int hz);
|
||||
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 KeyOn(int ch, float frqHz);
|
||||
void KeyOff(int ch);
|
||||
void _WriteReg(Bit32u reg, Bit8u value);
|
||||
void _WriteReg(Bit32u reg, Bit8u value, Bit8u mask=0x0);
|
||||
void _ClearRegBits(Bit32u reg, Bit8u mask);
|
||||
~Hiopl();
|
||||
private:
|
||||
|
@ -32,5 +37,8 @@ class Hiopl {
|
|||
Bit8u regCache[256];
|
||||
Bit32s *Buf32;
|
||||
bool _CheckParams(int ch, int osc);
|
||||
int _GetOffset(int ch, int osc);
|
||||
void _milliHertzToFnum(unsigned int milliHertz, unsigned int *fnum, unsigned int *block, unsigned int conversionFactor=49716);
|
||||
std::map<int, int> _op1offset;
|
||||
std::map<int, int> _op2offset;
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue