Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MidiDriver interface refactor #256

Merged
merged 45 commits into from
Oct 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
44f28f7
init
Raffaello Sep 29, 2023
98ea1fe
code rev
Raffaello Sep 29, 2023
5eabd09
midi interfaces WIP
Raffaello Sep 29, 2023
627b6ef
midi drivers refactor
Raffaello Sep 30, 2023
7497f36
fix build
Raffaello Sep 30, 2023
e0a3de9
[wip]
Raffaello Sep 30, 2023
cfbe38e
[WIP]
Raffaello Sep 30, 2023
bdfe55f
OplDriver refactor
Raffaello Sep 30, 2023
833aabc
clean-ups
Raffaello Sep 30, 2023
eeb7274
clean-ups
Raffaello Sep 30, 2023
f0fd8eb
clean-ups
Raffaello Sep 30, 2023
3cad67d
clean-ups
Raffaello Sep 30, 2023
193bb43
code rev
Raffaello Sep 30, 2023
10c2496
code refactor
Raffaello Sep 30, 2023
1907be9
code rev
Raffaello Sep 30, 2023
f78ae73
coder ev
Raffaello Oct 2, 2023
58ce13b
clean up scumm midi drv
Raffaello Oct 2, 2023
8df6f9a
clean up scumm midi drv
Raffaello Oct 2, 2023
293bb01
clean up scumm midi drv
Raffaello Oct 2, 2023
df11b76
clean up scumm midi drv
Raffaello Oct 2, 2023
6f83554
code rev
Raffaello Oct 2, 2023
e09e22b
scummvm MidiDriver pitchbend
Raffaello Oct 3, 2023
12d0a90
midi gm driver scummvm refactor
Raffaello Oct 3, 2023
783cb4e
midi gm driver scummvm refactor
Raffaello Oct 3, 2023
8d40587
midi gm driver scummvm refactor
Raffaello Oct 3, 2023
6bfcb14
midi gm driver scummvm refactor
Raffaello Oct 3, 2023
e9d8874
midi gm driver scummvm refactor
Raffaello Oct 3, 2023
bba5814
remove scummvm MidiDriver_BASE
Raffaello Oct 3, 2023
19d4657
midi driver scumm gm clean-ups
Raffaello Oct 3, 2023
65a1335
midi driver scumm gm clean-ups
Raffaello Oct 3, 2023
299100b
midi driver scumm gm clean-ups
Raffaello Oct 3, 2023
6b4abd7
midi driver scumm gm clean-ups
Raffaello Oct 3, 2023
f9da11c
midi driver scumm gm clean-ups
Raffaello Oct 3, 2023
3b3dfd2
fix midi scumm gm adlib
Raffaello Oct 3, 2023
fa0fc49
code rev
Raffaello Oct 3, 2023
fc67f98
code rev
Raffaello Oct 3, 2023
e89c55f
code rev
Raffaello Oct 3, 2023
a3ffcad
code rev
Raffaello Oct 3, 2023
033f52a
code rev
Raffaello Oct 3, 2023
59933f0
code rev
Raffaello Oct 3, 2023
5f930c5
sonarcloud code rev
Raffaello Oct 3, 2023
35a844e
code rev
Raffaello Oct 3, 2023
9519379
code rev
Raffaello Oct 3, 2023
921a4c8
code rev
Raffaello Oct 8, 2023
5ac1bc0
code rev
Raffaello Oct 10, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added doc/midi/MIDI Control Change Messages.pdf
Binary file not shown.
6 changes: 4 additions & 2 deletions sdl2-hyper-sonic-drivers/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -101,12 +101,14 @@ target_sources(${LIB_NAME} PRIVATE
# --- #
${CMAKE_CURRENT_SOURCE_DIR}/src/HyperSonicDrivers/drivers/PCMDriver.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/HyperSonicDrivers/drivers/MIDDriver.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/HyperSonicDrivers/drivers/midi/IMidiDriver.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/HyperSonicDrivers/drivers/midi/IMidiChannel.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/HyperSonicDrivers/drivers/midi/IMidiChannelVoice.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/HyperSonicDrivers/drivers/westwood/ADLDriver.cpp

${CMAKE_CURRENT_SOURCE_DIR}/src/HyperSonicDrivers/drivers/midi/scummvm/MidiDriver_BASE.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/HyperSonicDrivers/drivers/midi/scummvm/MidiDriver.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/HyperSonicDrivers/drivers/midi/scummvm/AdLibInstrument.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/HyperSonicDrivers/drivers/midi/scummvm/AdLibPart.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/HyperSonicDrivers/drivers/midi/scummvm/AdLibChannel.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/HyperSonicDrivers/drivers/midi/scummvm/AdLibPercussionChannel.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/HyperSonicDrivers/drivers/midi/scummvm/MidiDriver_ADLIB.cpp

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

namespace HyperSonicDrivers::audio::midi
{
// TODO: store it as uint32_t
class MIDIEvent
{
public:
Expand All @@ -25,6 +26,7 @@ namespace HyperSonicDrivers::audio::midi
b += (data[1] << 16);
return b;
}

// removed abs_time as it is not a MIDIEvent.
//uint32_t abs_time = 0; /// absolute ticks time derived from delta_time used for conversion.
};
Expand Down
70 changes: 60 additions & 10 deletions sdl2-hyper-sonic-drivers/src/HyperSonicDrivers/audio/midi/types.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ namespace HyperSonicDrivers::audio::midi
{
constexpr uint8_t MIDI_MAX_CHANNELS = 16;
constexpr uint8_t MIDI_PERCUSSION_CHANNEL = 9; // standard MIDI percussion channel
constexpr uint16_t MIDI_PITCH_BEND_DEFAULT = 0x2000; // pitch bend default value (zero)

typedef std::vector<uint8_t> midi_vector_t;

Expand All @@ -16,10 +17,8 @@ namespace HyperSonicDrivers::audio::midi
SINGLE_TRACK = 0,
SIMULTANEOUS_TRACK = 1,
MULTI_TRACK = 2
//TODO: add XMI_FORMAT?
};

// move to MIDIEvent class ?
typedef union MIDI_EVENT_type_u
{
uint8_t val;
Expand Down Expand Up @@ -79,18 +78,16 @@ namespace HyperSonicDrivers::audio::midi
SYS_EX7 = static_cast<uint8_t>((std::byte(MIDI_EVENT_TYPES_HIGH::META_SYSEX) << 4) | std::byte(MIDI_META_EVENT_TYPES_LOW::SYS_EX7)),
};

/*
// TODO: too many repetitions to be an enum
enum class MIDI_EVENT_CONTROLLER_TYPES : uint8_t
{
BANK_SELECT = 0,
BANK_SELECT_MSB = 0,
MODULATION_WHEEL = 1,
BREATH_CONTROL = 2,
FOOT_CONTROLLER = 4,
PORTAMENTO_TIME = 5,
DATA_ENTRY = 6,
CHANNEL_VOLUME = 7, // (MAIN VOLUME)
BALANCE = 8, // (PAN)
DATA_ENTRY_MSB = 6,
CHANNEL_VOLUME = 7,
BALANCE = 8,
PAN = 10,
EXPRESSION_CONTROLLER = 11,
EFFECT_CONTROL_1 = 12,
Expand All @@ -99,15 +96,68 @@ namespace HyperSonicDrivers::audio::midi
GENERAL_PURPOSE_CONTROLLER_2 = 17,
GENERAL_PURPOSE_CONTROLLER_3 = 18,
GENERAL_PURPOSE_CONTROLLER_4 = 19,
BANK_SELECT_2 = 32,
BANK_SELECT_LSB = 32,
MODULATION_WHEEL_2 = 33,
BREATH_CONTROL_2 = 34,
DATA_ENTRY_LSB = 38,
SUSTAIN = 64,
REVERB = 91,
TREMOLO = 92,
CHORUS = 93,
DETUNE = 94,
PHASER = 95,
RPN_LSB = 100,
RPN_MSB = 101,
ALL_SOUND_OFF = 120,
RESET_ALL_CONTROLLERS = 121,
ALL_NOTES_OFF = 123,

// eXtended MIDI
CHANNEL_LOCK = 110,
CHANNEL_LOCK_PROTECT = 111,
VOICE_PROTECT = 112,
TIMBRE_PROTECT = 113,
PATCH_BANK_SELECT = 114,
INDIRECT_CONTROLLER_PREFIX = 115,
FOR_LOOP_CONTROLLER = 116,
NEXT_BREAK_LOOP_CONTROLLER = 117,
CLEAR_BEAT_BAR_COUNT = 118,
CALLBACK_TRIGGER = 119,
SEQUENCE_BRANCH_INDEX = 120,
};
*/

enum class MIDI_RPN_TYPES : uint16_t
{
PITCH_BEND_SENSITIVITY = 0x0000,
FINE_TUNING = 0x0001,
COARSE_TUNING = 0x0002,
TUNING_PROGRAM_SELECT = 0x0003,
TUNING_BANK_SELECT = 0x0004,
RPN_NULL = 0x7F7F
};

enum class MIDI_RPN_TYPES_LSB : uint8_t
{
PITCH_BEND_SENSITIVITY = 0x00,
FINE_TUNING = 0x01,
COARSE_TUNING = 0x02,
TUNING_PROGRAM_SELECT = 0x03,
TUNING_BANK_SELECT = 0x04,
RPN_NULL = 0x7F
};

enum class MIDI_RPN_TYPES_MSB : uint8_t
{
PITCH_BEND_SENSITIVITY = 0x00,
FINE_TUNING = 0x00,
COARSE_TUNING = 0x00,
TUNING_PROGRAM_SELECT = 0x00,
TUNING_BANK_SELECT = 0x00,
RPN_NULL = 0x7F
};

constexpr MIDI_EVENT_TYPES_HIGH TO_HIGH(const uint8_t x) { return static_cast<MIDI_EVENT_TYPES_HIGH>(x); }
constexpr MIDI_META_EVENT_TYPES_LOW TO_META_LOW(const uint8_t x) { return static_cast<MIDI_META_EVENT_TYPES_LOW>(x); }
constexpr MIDI_META_EVENT TO_META(const uint8_t x) { return static_cast<MIDI_META_EVENT>(x); }
constexpr MIDI_EVENT_CONTROLLER_TYPES TO_CTRL(const uint8_t x) { return static_cast<MIDI_EVENT_CONTROLLER_TYPES>(x); }
}
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,6 @@ namespace HyperSonicDrivers::drivers
}

m_midiDriver.reset();

//auto opl = std::dynamic_pointer_cast<devices::Opl>(m_device)->getOpl();
auto opl_drv = std::make_unique<drivers::midi::opl::OplDriver>(std::dynamic_pointer_cast<devices::Opl>(m_device));
opl_drv->setOP2Bank(op2Bank);
m_midiDriver = std::move(opl_drv);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#include <HyperSonicDrivers/drivers/midi/IMidiChannel.hpp>
#include <HyperSonicDrivers/audio/midi/types.hpp>

namespace HyperSonicDrivers::drivers::midi
{
IMidiChannel::IMidiChannel(const uint8_t channel) :
channel(channel),
isPercussion(channel == audio::midi::MIDI_PERCUSSION_CHANNEL)
{}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#pragma once

#include <cstdint>
#include <HyperSonicDrivers/drivers/midi/IMidiChannelVoice.hpp>

namespace HyperSonicDrivers::drivers::midi
{
/**
* Interface for MIDI operation to a specific MIDI Channel
**/
class IMidiChannel
{
public:
explicit IMidiChannel(const uint8_t channel);
virtual ~IMidiChannel() = default;

const uint8_t channel; // MIDI channel number
uint8_t volume = 0; // channel volume
uint8_t pan = 64; // pan, 64=center
uint16_t pitch = 0; // pitch wheel, 0=normal
uint8_t sustain = 0; // sustain pedal value
uint8_t modulation = 0; // modulation pot value
uint8_t program = 0; // instrument number
const bool isPercussion;
};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#include <HyperSonicDrivers/drivers/midi/IMidiChannelVoice.hpp>
#include <HyperSonicDrivers/drivers/midi/IMidiChannel.hpp>
#include <cmath>

namespace HyperSonicDrivers::drivers::midi
{
uint8_t IMidiChannelVoice::getChannelNum() const noexcept
{
return m_channel->channel;
}

void IMidiChannelVoice::setVolumes(const uint8_t volume) noexcept
{
m_volume = volume;
m_real_volume = calcVolume_();
}

uint8_t IMidiChannelVoice::calcVolume_() const noexcept
{
return std::min<uint8_t>(static_cast<uint8_t>(m_volume * m_channel->volume / 127), 127);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#pragma once

#include <cstdint>

namespace HyperSonicDrivers::drivers::midi
{
class IMidiChannel;

/**
* Interface for Midi Channel Voice message to have a polyphonic MidiChannel.
* this is mono-phonic channel, multiple combination of this gives a polyphonic MidiChannel
**/
class IMidiChannelVoice
{
public:
IMidiChannelVoice() = default;
virtual ~IMidiChannelVoice() = default;

inline IMidiChannel* getChannel() const noexcept { return m_channel; }
uint8_t getChannelNum() const noexcept;
inline uint8_t getNote() const noexcept { return m_note; }
//inline uint8_t getVolume() const noexcept { return m_volume; };
void setVolumes(const uint8_t volume) noexcept;
inline bool isFree() const noexcept { return m_free; }
inline bool isSustain() const noexcept { return m_sustain; };
inline bool isVibrato() const noexcept { return m_vibrato; }

protected:
IMidiChannel* m_channel = nullptr; // MIDI channel
uint8_t m_note = 0; /* note number */
uint8_t m_volume = 0; /* note volume */
uint8_t m_real_volume = 0; /* adjusted note volume */
int16_t m_pitch_factor = 0; /* pitch-wheel value */
bool m_free = true;
bool m_sustain = false; // this are Opl exclusive or are midi?
bool m_vibrato = false; // ""

private:
/// <summary>
/// The volume is between 0-127 as a per MIDI specification.
/// OPLWriter expect a MIDI volume value and converts to OPL value.
/// OPL chips has a volume attenuation (inverted values)
/// range from 0-64 inverted (0 is max, 64 is muted).
/// </summary>
uint8_t calcVolume_() const noexcept;
};

}
Loading
Loading