diff --git a/sdl2-hyper-sonic-drivers/src/HyperSonicDrivers/drivers/midi/IMidiDriver.hpp b/sdl2-hyper-sonic-drivers/src/HyperSonicDrivers/drivers/midi/IMidiDriver.hpp index fbe4652c..500fd8c9 100644 --- a/sdl2-hyper-sonic-drivers/src/HyperSonicDrivers/drivers/midi/IMidiDriver.hpp +++ b/sdl2-hyper-sonic-drivers/src/HyperSonicDrivers/drivers/midi/IMidiDriver.hpp @@ -36,5 +36,19 @@ namespace HyperSonicDrivers::drivers::midi virtual void onCallback() noexcept = 0; + // MIDI events + //virtual void noteOff(const uint8_t chan, const uint8_t note) noexcept = 0; + //virtual void noteOn(const uint8_t chan, const uint8_t note, const uint8_t vol) noexcept = 0; + //virtual void controller(const uint8_t chan, const uint8_t ctrl, uint8_t value) noexcept = 0; + //virtual void programChange(const uint8_t chan, const uint8_t program) noexcept = 0; + //virtual void pitchBend(const uint8_t chan, const uint16_t bend) noexcept = 0; + + // MIDI Controller Events + //virtual void ctrl_modulationWheel(const uint8_t chan, const uint8_t value) const noexcept = 0; + //virtual void ctrl_volume(const uint8_t chan, const uint8_t value) const noexcept = 0; + //virtual void ctrl_panPosition(const uint8_t chan, uint8_t value) const noexcept = 0; + //virtual void ctrl_sustain(const uint8_t chan, uint8_t value) const noexcept = 0; + + }; } diff --git a/sdl2-hyper-sonic-drivers/src/HyperSonicDrivers/drivers/midi/opl/OplDriver.cpp b/sdl2-hyper-sonic-drivers/src/HyperSonicDrivers/drivers/midi/opl/OplDriver.cpp index 15b29d95..673318a3 100644 --- a/sdl2-hyper-sonic-drivers/src/HyperSonicDrivers/drivers/midi/opl/OplDriver.cpp +++ b/sdl2-hyper-sonic-drivers/src/HyperSonicDrivers/drivers/midi/opl/OplDriver.cpp @@ -194,7 +194,7 @@ namespace HyperSonicDrivers::drivers::midi::opl } } - void OplDriver::controller(const uint8_t chan, const uint8_t control, uint8_t value) const noexcept + void OplDriver::controller(const uint8_t chan, const uint8_t control, uint8_t value) noexcept { // MIDI_EVENT_CONTROLLER_TYPES switch (control) @@ -262,12 +262,12 @@ namespace HyperSonicDrivers::drivers::midi::opl } } - void OplDriver::programChange(const uint8_t chan, const uint8_t program) const noexcept + void OplDriver::programChange(const uint8_t chan, const uint8_t program) noexcept { m_channels[chan]->programChange(program); } - void OplDriver::pitchBend(const uint8_t chan, const uint16_t bend) const noexcept + void OplDriver::pitchBend(const uint8_t chan, const uint16_t bend) noexcept { //spdlog::debug("PITCH_BEND {}", bend); // OPLPitchWheel diff --git a/sdl2-hyper-sonic-drivers/src/HyperSonicDrivers/drivers/midi/opl/OplDriver.hpp b/sdl2-hyper-sonic-drivers/src/HyperSonicDrivers/drivers/midi/opl/OplDriver.hpp index 0b82046b..9c159b7a 100644 --- a/sdl2-hyper-sonic-drivers/src/HyperSonicDrivers/drivers/midi/opl/OplDriver.hpp +++ b/sdl2-hyper-sonic-drivers/src/HyperSonicDrivers/drivers/midi/opl/OplDriver.hpp @@ -50,6 +50,21 @@ namespace HyperSonicDrivers::drivers::midi::opl protected: void onCallback() noexcept override; + // TODO: every MIDI function that has channel put into IMidiChannel interface + // ------ + // MIDI Events + void noteOff(const uint8_t chan, const uint8_t note) noexcept; + void noteOn(const uint8_t chan, const uint8_t note, const uint8_t vol) noexcept; + void controller(const uint8_t chan, const uint8_t ctrl, uint8_t value) noexcept; + void programChange(const uint8_t chan, const uint8_t program) noexcept; + void pitchBend(const uint8_t chan, const uint16_t bend) noexcept; + + // MIDI Controller Events + void ctrl_modulationWheel(const uint8_t chan, const uint8_t value) const noexcept; + void ctrl_volume(const uint8_t chan, const uint8_t value) const noexcept; + void ctrl_panPosition(const uint8_t chan, uint8_t value) const noexcept; + void ctrl_sustain(const uint8_t chan, uint8_t value) const noexcept; + private: std::shared_ptr m_opl; std::shared_ptr m_op2Bank; @@ -65,21 +80,6 @@ namespace HyperSonicDrivers::drivers::midi::opl std::list m_voicesInUseIndex; std::list m_voicesFreeIndex; - // MIDI Events - void noteOff(const uint8_t chan, const uint8_t note) noexcept; - void noteOn(const uint8_t chan, const uint8_t note, const uint8_t vol) noexcept; - void controller(const uint8_t chan, const uint8_t ctrl, uint8_t value) const noexcept; - void programChange(const uint8_t chan, const uint8_t program) const noexcept; - void pitchBend(const uint8_t chan, const uint16_t bend) const noexcept; - - // MIDI Controller Events - void ctrl_modulationWheel(const uint8_t chan, const uint8_t value) const noexcept; - void ctrl_volume(const uint8_t chan, const uint8_t value) const noexcept; - void ctrl_panPosition(const uint8_t chan, uint8_t value) const noexcept; - void ctrl_sustain(const uint8_t chan, uint8_t value) const noexcept; - - //void onTimer(); - void releaseSustain(const uint8_t channel) const noexcept; uint8_t releaseVoice(const uint8_t slot, const bool forced); int allocateVoice(const uint8_t slot, const uint8_t channel, diff --git a/sdl2-hyper-sonic-drivers/src/HyperSonicDrivers/drivers/midi/scummvm/MidiDriver_ADLIB.cpp b/sdl2-hyper-sonic-drivers/src/HyperSonicDrivers/drivers/midi/scummvm/MidiDriver_ADLIB.cpp index 8147ca32..fb0f2639 100644 --- a/sdl2-hyper-sonic-drivers/src/HyperSonicDrivers/drivers/midi/scummvm/MidiDriver_ADLIB.cpp +++ b/sdl2-hyper-sonic-drivers/src/HyperSonicDrivers/drivers/midi/scummvm/MidiDriver_ADLIB.cpp @@ -173,7 +173,7 @@ namespace HyperSonicDrivers::drivers::midi::scummvm free(_regCacheSecondary); } - void MidiDriver_ADLIB::send(const audio::midi::MIDIEvent& e) /*const*/ noexcept + void MidiDriver_ADLIB::send(const audio::midi::MIDIEvent& e) noexcept { using audio::midi::TO_HIGH; using audio::midi::MIDI_EVENT_TYPES_HIGH; @@ -188,11 +188,13 @@ namespace HyperSonicDrivers::drivers::midi::scummvm } } - void MidiDriver_ADLIB::send(uint32_t b) { + void MidiDriver_ADLIB::send(uint32_t b) + { send(b & 0xF, b & 0xFFFFFFF0); } - void MidiDriver_ADLIB::send(int8_t chan, uint32_t b) { + void MidiDriver_ADLIB::send(int8_t chan, uint32_t b) + { using audio::midi::MIDI_EVENT_type_u; using audio::midi::MIDI_EVENT_TYPES_HIGH; @@ -202,33 +204,25 @@ namespace HyperSonicDrivers::drivers::midi::scummvm MIDI_EVENT_type_u cmd; cmd.val = static_cast(b & 0xFF); - AdLibPart* part; - if (chan == 9) - part = &_percussion; - else - part = &_parts[chan]; - switch (static_cast(cmd.high)) { case MIDI_EVENT_TYPES_HIGH::NOTE_OFF:// Note Off - part->noteOff(param1); - logD(std::format("noteOff {} {}", chan, param1)); + noteOff(chan, param1); break; case MIDI_EVENT_TYPES_HIGH::NOTE_ON: // Note On - part->noteOn(param1, param2); - logD(std::format("noteOn {} {}", param1, param2)); + noteOn(chan, param1, param2); break; case MIDI_EVENT_TYPES_HIGH::AFTERTOUCH: // Aftertouch break; // Not supported. case MIDI_EVENT_TYPES_HIGH::CONTROLLER: // Control Change - part->controlChange(param1, param2); + controller(chan, param1, param2); break; case MIDI_EVENT_TYPES_HIGH::PROGRAM_CHANGE: // Program Change - part->programChange(param1); + programChange(chan, param1); break; case MIDI_EVENT_TYPES_HIGH::CHANNEL_AFTERTOUCH: // Channel Pressure break; // Not supported. case MIDI_EVENT_TYPES_HIGH::PITCH_BEND: // Pitch Bend - part->pitchBend(static_cast((param1 | (param2 << 7)) - 0x2000)); + pitchBend(chan, static_cast((param1 | (param2 << 7)) - 0x2000)); break; case MIDI_EVENT_TYPES_HIGH::META_SYSEX: // SysEx // We should never get here! SysEx information has to be @@ -365,6 +359,38 @@ namespace HyperSonicDrivers::drivers::midi::scummvm } } + void MidiDriver_ADLIB::noteOff(const uint8_t chan, const uint8_t note) noexcept + { + auto part = getChannel(chan); + part->noteOff(note); + logD(std::format("noteOff {} {}", chan, note)); + } + + void MidiDriver_ADLIB::noteOn(const uint8_t chan, const uint8_t note, const uint8_t vol) noexcept + { + auto part = getChannel(chan); + part->noteOn(note, vol); + logD(std::format("noteOn {} {}", note, vol)); + } + + void MidiDriver_ADLIB::controller(const uint8_t chan, const uint8_t ctrl, uint8_t value) noexcept + { + auto part = getChannel(chan); + part->controlChange(ctrl, value); + } + + void MidiDriver_ADLIB::programChange(const uint8_t chan, const uint8_t program) noexcept + { + auto part = getChannel(chan); + part->programChange(program); + } + + void MidiDriver_ADLIB::pitchBend(const uint8_t chan, const uint16_t bend) noexcept + { + auto part = getChannel(chan); + part->pitchBend(static_cast(bend)); + } + //void MidiDriver_ADLIB::setTimerCallback(void* timerParam, /*Common::TimerManager::TimerProc*/ void* timerProc) { // _adlibTimerProc = timerProc; // _adlibTimerParam = timerParam; @@ -661,6 +687,14 @@ namespace HyperSonicDrivers::drivers::midi::scummvm } } + AdLibPart* MidiDriver_ADLIB::getChannel(const uint8_t channel) noexcept + { + if (channel == 9) + return &_percussion; + else + return &_parts[channel]; + } + void MidiDriver_ADLIB::partKeyOn(AdLibPart* part, const AdLibInstrument* instr, uint8_t note, uint8_t velocity, const AdLibInstrument* second, uint8_t pan) { AdLibVoice* voice; diff --git a/sdl2-hyper-sonic-drivers/src/HyperSonicDrivers/drivers/midi/scummvm/MidiDriver_ADLIB.hpp b/sdl2-hyper-sonic-drivers/src/HyperSonicDrivers/drivers/midi/scummvm/MidiDriver_ADLIB.hpp index 93da9071..2831313b 100644 --- a/sdl2-hyper-sonic-drivers/src/HyperSonicDrivers/drivers/midi/scummvm/MidiDriver_ADLIB.hpp +++ b/sdl2-hyper-sonic-drivers/src/HyperSonicDrivers/drivers/midi/scummvm/MidiDriver_ADLIB.hpp @@ -54,6 +54,22 @@ namespace HyperSonicDrivers::drivers::midi::scummvm //virtual void setTimerCallback(void* timerParam, /*Common::TimerManager::TimerProc*/ void* timerProc); + protected: + void onCallback() noexcept override; + + // MIDI Events + void noteOff(const uint8_t chan, const uint8_t note) noexcept; + void noteOn(const uint8_t chan, const uint8_t note, const uint8_t vol) noexcept; + void controller(const uint8_t chan, const uint8_t ctrl, uint8_t value) noexcept; + void programChange(const uint8_t chan, const uint8_t program) noexcept; + void pitchBend(const uint8_t chan, const uint16_t bend) noexcept; + + // MIDI Controller Events + //void ctrl_modulationWheel(const uint8_t chan, const uint8_t value) const noexcept {/*in MIDIChannel*/ }; + //void ctrl_volume(const uint8_t chan, const uint8_t value) const noexcept {/*in MIDIChannel*/ }; + //void ctrl_panPosition(const uint8_t chan, uint8_t value) const noexcept {/*in MIDIChannel*/ }; + //void ctrl_sustain(const uint8_t chan, uint8_t value) const noexcept {/*in MIDIChannel*/ }; + private: std::shared_ptr m_opl; bool _scummSmallHeader = false; // FIXME: This flag controls a special mode for SCUMM V3 games @@ -76,10 +92,8 @@ namespace HyperSonicDrivers::drivers::midi::scummvm int _timerIncrease = 0xD69; int _timerThreshold = 0x411B; - //bool _isOpen = false; + AdLibPart* getChannel(const uint8_t channel) noexcept; - //void onTimer(); - void onCallback() noexcept override; void partKeyOn(AdLibPart* part, const AdLibInstrument* instr, uint8_t note, uint8_t velocity, const AdLibInstrument* second, uint8_t pan); void partKeyOff(AdLibPart* part, uint8_t note); diff --git a/sdl2-hyper-sonic-drivers/src/HyperSonicDrivers/drivers/midi/scummvm/MidiDriver_BASE.hpp b/sdl2-hyper-sonic-drivers/src/HyperSonicDrivers/drivers/midi/scummvm/MidiDriver_BASE.hpp index b0a2ab70..5566d25a 100644 --- a/sdl2-hyper-sonic-drivers/src/HyperSonicDrivers/drivers/midi/scummvm/MidiDriver_BASE.hpp +++ b/sdl2-hyper-sonic-drivers/src/HyperSonicDrivers/drivers/midi/scummvm/MidiDriver_BASE.hpp @@ -68,21 +68,6 @@ namespace HyperSonicDrivers::drivers::midi::scummvm using IMidiDriver::send; - /** - * Output a packed midi command to the midi stream. - * The 'lowest' uint8_t (i.e. b & 0xFF) is the status - * code, then come (if used) the first and second - * opcode. - */ - //virtual void send(uint32_t b) = 0; - - /** - * Send a MIDI command from a specific source. If the MIDI driver - * does not support multiple sources, the source parameter is - * ignored. - */ - //virtual void send(int8_t channel, uint32_t b) { send(b); } - /** * Output a midi command to the midi stream. Convenience wrapper * around the usual 'packed' send method.