Skip to content

Commit

Permalink
clean up scumm midi drv
Browse files Browse the repository at this point in the history
  • Loading branch information
Raffaello committed Oct 2, 2023
1 parent 8df6f9a commit 293bb01
Show file tree
Hide file tree
Showing 6 changed files with 190 additions and 100 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@ namespace HyperSonicDrivers::drivers::midi::scummvm
void AdLibPart::init(MidiDriver_ADLIB* owner)
{
_owner = owner;
_priEff = 127;
programChange(0);
//programChange(0);
}

void AdLibPart::allocate()
Expand All @@ -27,13 +26,21 @@ namespace HyperSonicDrivers::drivers::midi::scummvm
memset(&_partInstrSecondary, 0, sizeof(_partInstrSecondary));
}

MidiDriver* AdLibPart::device() {
return _owner;
void AdLibPart::setInstr(const bool isOpl3) noexcept
{
if (isOpl3)
{
memcpy(&_partInstr, &g_gmInstrumentsOPL3[program][0], sizeof(AdLibInstrument));
memcpy(&_partInstrSecondary, &g_gmInstrumentsOPL3[program][1], sizeof(AdLibInstrument));
}
else
{
memcpy(&_partInstr, &g_gmInstruments[program], sizeof(AdLibInstrument));
}
}

uint8_t AdLibPart::getNumber()
{
return channel;
MidiDriver* AdLibPart::device() {
return _owner;
}

void AdLibPart::release()
Expand All @@ -45,37 +52,37 @@ namespace HyperSonicDrivers::drivers::midi::scummvm
_owner->send(channel, b);
}

void AdLibPart::noteOff(uint8_t note) {
/*void AdLibPart::noteOff(uint8_t note) {
#ifdef DEBUG_ADLIB
debug(6, "%10d: noteOff(%d)", g_tick, note);
#endif
_owner->partKeyOff(this, note);
}
}*/

void AdLibPart::noteOn(uint8_t note, uint8_t velocity) {
/*void AdLibPart::noteOn(uint8_t note, uint8_t velocity) {
#ifdef DEBUG_ADLIB
debug(6, "%10d: noteOn(%d,%d)", g_tick, note, velocity);
#endif
_owner->partKeyOn(this, &_partInstr, note, velocity,
&_partInstrSecondary,
pan);
}
}*/

void AdLibPart::programChange(uint8_t program) {
if (program > 127)
return;
//void AdLibPart::programChange(uint8_t program) {
// if (program > 127)
// return;

program = program;
if (!_owner->m_opl3Mode) {
memcpy(&_partInstr, &g_gmInstruments[program], sizeof(AdLibInstrument));
}
else {
memcpy(&_partInstr, &g_gmInstrumentsOPL3[program][0], sizeof(AdLibInstrument));
memcpy(&_partInstrSecondary, &g_gmInstrumentsOPL3[program][1], sizeof(AdLibInstrument));
}
// program = program;
// if (!_owner->m_opl3Mode) {
// memcpy(&_partInstr, &g_gmInstruments[program], sizeof(AdLibInstrument));
// }
// else {
// memcpy(&_partInstr, &g_gmInstrumentsOPL3[program][0], sizeof(AdLibInstrument));
// memcpy(&_partInstrSecondary, &g_gmInstrumentsOPL3[program][1], sizeof(AdLibInstrument));
// }

//spdlog::debug("Program {} {}", _channel, program);
}
// //spdlog::debug("Program {} {}", _channel, program);
//}

void AdLibPart::pitchBend(int16_t bend)
{
Expand All @@ -94,8 +101,10 @@ namespace HyperSonicDrivers::drivers::midi::scummvm
}
}

void AdLibPart::controlChange(uint8_t control, uint8_t value) {
switch (control) {
void AdLibPart::controlChange(uint8_t control, uint8_t value)
{
switch (control)
{
case 0:
case 32:
// Bank select. Not supported
Expand All @@ -121,7 +130,7 @@ namespace HyperSonicDrivers::drivers::midi::scummvm
priority(value);
break;
case 64:
sustain(value > 0);
setSustain(value);
break;
case 91:
// Effects level. Not supported.
Expand All @@ -139,7 +148,7 @@ namespace HyperSonicDrivers::drivers::midi::scummvm
modulationWheel(0);
pitchBendFactor(0);
detune(0);
sustain(false);
setSustain(false);
break;
case 123:
allNotesOff();
Expand Down Expand Up @@ -230,10 +239,10 @@ namespace HyperSonicDrivers::drivers::midi::scummvm
_priEff = value;
}

void AdLibPart::sustain(bool value)
void AdLibPart::setSustain(const uint8_t value)
{
_pedal = value;
if (!value) {
sustain = value;
if (value != 0) {
for (AdLibVoice* voice = _voice; voice; voice = voice->_next)
{
if (voice->_waitForPedal)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,7 @@ namespace HyperSonicDrivers::drivers::midi::scummvm
uint8_t _pitchBendFactor = 2;
//int8_t _transposeEff;
int8_t _detuneEff = 0;
bool _pedal = false;
uint8_t _priEff = 0;
uint8_t _priEff = 127;
//uint8_t pan = 64;
AdLibInstrument _partInstr;
AdLibInstrument _partInstrSecondary;
Expand All @@ -31,21 +30,25 @@ namespace HyperSonicDrivers::drivers::midi::scummvm
bool _allocated = false;

void init(MidiDriver_ADLIB* owner);
void allocate();
void allocate(); // TODO: this is more relative to AdLibVoice instead, Midi channel are 16, eventually are in use

public:
AdLibPart(const uint8_t channel);

inline const AdLibInstrument* getInstr() const noexcept { return &_partInstr; };
inline const AdLibInstrument* getInstrSecondary() const noexcept { return &_partInstrSecondary; };
void setInstr(const bool isOpl3) noexcept;


MidiDriver* device() override;
uint8_t getNumber() override;
void release() override;

void send(uint32_t b) override;

// Regular messages
void noteOff(uint8_t note) override;
void noteOn(uint8_t note, uint8_t velocity) override;
void programChange(uint8_t program) override;
//void noteOff(uint8_t note) override;
//void noteOn(uint8_t note, uint8_t velocity) override;
//void programChange(uint8_t program) override;
void pitchBend(int16_t bend) override;

// Control Change messages
Expand All @@ -56,7 +59,7 @@ namespace HyperSonicDrivers::drivers::midi::scummvm
void pitchBendFactor(uint8_t value) override;
void detune(uint8_t value) override;
void priority(uint8_t value) override;
void sustain(bool value) override;
void setSustain(const uint8_t value) override;
void effectLevel(uint8_t value) override { return; } // Not supported
void chorusLevel(uint8_t value) override { return; } // Not supported
void allNotesOff() override;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,59 +21,59 @@ namespace HyperSonicDrivers::drivers::midi::scummvm
std::ranges::fill(_customInstruments, nullptr);
}

void AdLibPercussionChannel::noteOff(uint8_t note)
{
if (_customInstruments[note])
{
note = _notes[note];
}
//void AdLibPercussionChannel::noteOff(uint8_t note)
//{
// if (_customInstruments[note])
// {
// note = _notes[note];
// }

// This used to ignore note off events, since the builtin percussion
// instrument data has a duration value, which causes the percussion notes
// to stop automatically. This is not the case for (Groovie's) custom
// percussion instruments though. Also the OPL3 driver of Sam&Max actually
// does not handle the duration value, so we need it there too.
_owner->partKeyOff(this, note);
}
// // This used to ignore note off events, since the builtin percussion
// // instrument data has a duration value, which causes the percussion notes
// // to stop automatically. This is not the case for (Groovie's) custom
// // percussion instruments though. Also the OPL3 driver of Sam&Max actually
// // does not handle the duration value, so we need it there too.
// _owner->partKeyOff(this, note);
//}

void AdLibPercussionChannel::noteOn(uint8_t note, uint8_t velocity) {
const AdLibInstrument* inst = nullptr;
const AdLibInstrument* sec = nullptr;
//void AdLibPercussionChannel::noteOn(uint8_t note, uint8_t velocity) {
// const AdLibInstrument* inst = nullptr;
// const AdLibInstrument* sec = nullptr;

// The custom instruments have priority over the default mapping
// We do not support custom instruments in OPL3 mode though.
if (!_owner->m_opl3Mode)
{
inst = _customInstruments[note].get();
if (inst)
note = _notes[note];
}
// // The custom instruments have priority over the default mapping
// // We do not support custom instruments in OPL3 mode though.
// if (!_owner->m_opl3Mode)
// {
// inst = _customInstruments[note].get();
// if (inst)
// note = _notes[note];
// }

if (!inst)
{
// Use the default GM to FM mapping as a fallback
uint8_t key = g_gmPercussionInstrumentMap[note];
if (key != 0xFF) {
if (!_owner->m_opl3Mode)
{
inst = &g_gmPercussionInstruments[key];
}
else
{
inst = &g_gmPercussionInstrumentsOPL3[key][0];
sec = &g_gmPercussionInstrumentsOPL3[key][1];
}
}
}
// if (!inst)
// {
// // Use the default GM to FM mapping as a fallback
// uint8_t key = g_gmPercussionInstrumentMap[note];
// if (key != 0xFF) {
// if (!_owner->m_opl3Mode)
// {
// inst = &g_gmPercussionInstruments[key];
// }
// else
// {
// inst = &g_gmPercussionInstrumentsOPL3[key][0];
// sec = &g_gmPercussionInstrumentsOPL3[key][1];
// }
// }
// }

if (!inst)
{
logD(std::format("No instrument FM definition for GM percussion key {:d}", note));
return;
}
// if (!inst)
// {
// logD(std::format("No instrument FM definition for GM percussion key {:d}", note));
// return;
// }

_owner->partKeyOn(this, inst, note, velocity, sec, pan);
}
// _owner->partKeyOn(this, inst, note, velocity, sec, pan);
//}

void AdLibPercussionChannel::sysEx_customInstrument(uint32_t type, const uint8_t* instr) {
// We do not allow custom instruments in OPL3 mode right now.
Expand Down Expand Up @@ -109,4 +109,16 @@ namespace HyperSonicDrivers::drivers::midi::scummvm
_customInstruments[note]->feedback = instr[12];
}
}

uint8_t AdLibPercussionChannel::getNote(const uint8_t note) const noexcept
{
if (_customInstruments[note])
return _notes[note];
return note;
}

AdLibInstrument* AdLibPercussionChannel::getInstrument(const uint8_t note) const noexcept
{
return _customInstruments[note].get();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,20 +25,22 @@ namespace HyperSonicDrivers::drivers::midi::scummvm
AdLibPercussionChannel() : AdLibPart(audio::midi::MIDI_PERCUSSION_CHANNEL) {};
~AdLibPercussionChannel() override = default;

void noteOff(uint8_t note) override;
void noteOn(uint8_t note, uint8_t velocity) override;
void programChange(uint8_t program) override { }
//void noteOff(uint8_t note) override;
//void noteOn(uint8_t note, uint8_t velocity) override;
//void programChange(uint8_t program) override { }

// Control Change messages
void modulationWheel(uint8_t value) override { }
void pitchBendFactor(uint8_t value) override { }
void detune(uint8_t value) override { }
void priority(uint8_t value) override { }
void sustain(bool value) override { }
void setSustain(const uint8_t value) override { }

// SysEx messages
void sysEx_customInstrument(uint32_t type, const uint8_t* instr) override;

uint8_t getNote(const uint8_t note) const noexcept;
AdLibInstrument* getInstrument(const uint8_t note) const noexcept;
private:
std::array<uint8_t, 256> _notes = { 0 };
std::array<std::unique_ptr<AdLibInstrument>, 256> _customInstruments;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,14 @@ namespace HyperSonicDrivers::drivers::midi::scummvm
virtual ~MidiChannel() = default;

virtual MidiDriver* device() = 0;
virtual uint8_t getNumber() = 0;
virtual void release() = 0;

virtual void send(uint32_t b) = 0; // 4-bit channel portion is ignored

// Regular messages
virtual void noteOff(uint8_t note) = 0;
virtual void noteOn(uint8_t note, uint8_t velocity) = 0;
virtual void programChange(uint8_t program) = 0;
//virtual void noteOff(uint8_t note) = 0;
//virtual void noteOn(uint8_t note, uint8_t velocity) = 0;
//virtual void programChange(uint8_t program) = 0;
virtual void pitchBend(int16_t bend) = 0; // -0x2000 to +0x1FFF

// Control Change messages
Expand All @@ -36,7 +35,7 @@ namespace HyperSonicDrivers::drivers::midi::scummvm
virtual void transpose(int8_t value) {}
virtual void detune(uint8_t value) { controlChange(static_cast<uint8_t>(audio::midi::MIDI_EVENT_CONTROLLER_TYPES::GENERAL_PURPOSE_CONTROLLER_2), value); }
virtual void priority(uint8_t value) { }
virtual void sustain(bool value) { controlChange(static_cast<uint8_t>(audio::midi::MIDI_EVENT_CONTROLLER_TYPES::SUSTAIN), value ? 1 : 0); }
virtual void setSustain(const uint8_t value) { controlChange(static_cast<uint8_t>(audio::midi::MIDI_EVENT_CONTROLLER_TYPES::SUSTAIN), value); }
virtual void effectLevel(uint8_t value) { controlChange(static_cast<uint8_t>(audio::midi::MIDI_EVENT_CONTROLLER_TYPES::REVERB), value); }
virtual void chorusLevel(uint8_t value) { controlChange(static_cast<uint8_t>(audio::midi::MIDI_EVENT_CONTROLLER_TYPES::CHORUS), value); }
virtual void allNotesOff() { controlChange(static_cast<uint8_t>(audio::midi::MIDI_EVENT_CONTROLLER_TYPES::ALL_NOTES_OFF), 0); }
Expand Down
Loading

0 comments on commit 293bb01

Please sign in to comment.