2
0
Fork 0

Finally get waveform control working, add modulator feedback, fix assorted bugs.

This commit is contained in:
bruce 2013-09-12 21:58:22 +08:00
parent 2dc2879064
commit b3eb3832ad
3 changed files with 43 additions and 17 deletions

View file

@ -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));

View file

@ -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<Waveform>(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;
}

View file

@ -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<int, int> _op1offset;
std::map<int, int> _op2offset;