Skip to content

Commit

Permalink
IMusicDriver getDevice | IDevice::getName | devices::Opl::getEmulator…
Browse files Browse the repository at this point in the history
…Type (#263)

* IMusicDriver getDevice

* IMusicDriverTest

* update version

* getDeviceName

* IDeviceTypesFormatter

* Renderer OPL through device

* Renderer OPL through device test

* code rev
  • Loading branch information
Raffaello authored Oct 31, 2023
1 parent 6688ff5 commit 2fa3b7a
Show file tree
Hide file tree
Showing 31 changed files with 284 additions and 54 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ if(DEFINED ENV{VCPKG_ROOT} AND NOT DEFINED CMAKE_TOOLCHAIN_FILE)
endif()


project ("sdl2-hyper-sonic-drivers" VERSION 0.12.3 DESCRIPTION "SDL2 based Hyper-Sonic Drivers for emulating old soundcards")
project ("sdl2-hyper-sonic-drivers" VERSION 0.12.4 DESCRIPTION "SDL2 based Hyper-Sonic Drivers for emulating old soundcards")
include (TestBigEndian)
TEST_BIG_ENDIAN(IS_BIG_ENDIAN)
if(IS_BIG_ENDIAN)
Expand Down
1 change: 1 addition & 0 deletions sdl2-hyper-sonic-drivers/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ target_sources(${LIB_NAME} PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/src/HyperSonicDrivers/devices/MT32.cpp
# --- #
${CMAKE_CURRENT_SOURCE_DIR}/src/HyperSonicDrivers/drivers/PCMDriver.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/HyperSonicDrivers/drivers/IMusicDriver.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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <HyperSonicDrivers/audio/IMixer.hpp>
#include <HyperSonicDrivers/audio/IAudioStream.hpp>
#include <HyperSonicDrivers/hardware/opl/OPL.hpp>
#include <HyperSonicDrivers/devices/Opl.hpp>

namespace HyperSonicDrivers::audio
{
Expand All @@ -21,6 +22,7 @@ namespace HyperSonicDrivers::audio

virtual void renderBuffer(IAudioStream* stream) = 0;
inline void renderBuffer(const std::shared_ptr<hardware::opl::OPL>& opl) { renderBuffer(opl->getAudioStream().get()); };
inline void renderBuffer(const std::shared_ptr<devices::Opl>& opl) { renderBuffer(opl->getHardware()->getAudioStream().get()); };

protected:
std::shared_ptr<IMixer> m_mixer;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,9 @@ namespace HyperSonicDrivers::devices
Opl(mixer, emulator, OplType::OPL2, volume, pan)
{
}

eDeviceName Adlib::getName() const noexcept
{
return eDeviceName::Adlib;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,7 @@ namespace HyperSonicDrivers::devices
);

~Adlib() override = default;

eDeviceName getName() const noexcept override;
};
}
96 changes: 52 additions & 44 deletions sdl2-hyper-sonic-drivers/src/HyperSonicDrivers/devices/IDevice.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,56 +4,64 @@
#include <memory>
#include <optional>
#include <HyperSonicDrivers/audio/IMixer.hpp>
#include <HyperSonicDrivers/drivers/IMusicDriver.hpp>
#include <HyperSonicDrivers/drivers/midi/IMidiDriver.hpp>
#include <HyperSonicDrivers/hardware/IHardware.hpp>
#include <HyperSonicDrivers/devices/types.hpp>

namespace HyperSonicDrivers::devices
namespace HyperSonicDrivers
{
/**
* general interface for sound cards used by the drivers
* that is bound to a specific hardware
**/
class IDevice
namespace drivers
{
public:
IDevice(const std::shared_ptr<audio::IMixer>& mixer, const eDeviceType type);
virtual ~IDevice() = default;

virtual bool init() noexcept = 0;
virtual bool shutdown() noexcept = 0;
inline bool isInit() const noexcept { return m_init; };

std::optional<uint8_t> getChannelId() const noexcept { return m_hardware->getChannelId(); };

inline bool isAcquired() const noexcept { return m_acquired; }
inline bool isOwned(const drivers::IMusicDriver* owner) const noexcept { return m_owner == owner; }

bool acquire(drivers::IMusicDriver* owner);
bool release(const drivers::IMusicDriver* owner);

// helpers methods
void setVolume(const uint8_t volume);
void setPan(const uint8_t pan);
void setVolumePan(const uint8_t volume, const uint8_t pan);

inline std::shared_ptr<audio::IMixer> getMixer() const noexcept { return m_mixer; };
virtual hardware::IHardware* getHardware() const noexcept { return m_hardware; };
const eDeviceType type;
protected:
bool m_init = false;
std::shared_ptr<audio::IMixer> m_mixer;
hardware::IHardware* m_hardware = nullptr;
private:
// TODO: remove the atomic when removing the thread in MIDDrv
std::atomic<bool> m_acquired = false;
std::atomic<drivers::IMusicDriver*> m_owner = nullptr;
};

template<class T, class To = devices::IDevice, typename... Args>
std::shared_ptr<To> make_device(Args... args)
class IMusicDriver;
}

namespace devices
{
return std::dynamic_pointer_cast<To>(std::make_shared<T>(args...));
/**
* general interface for sound cards used by the drivers
* that is bound to a specific hardware
**/
class IDevice
{
public:
IDevice(const std::shared_ptr<audio::IMixer>& mixer, const eDeviceType type);
virtual ~IDevice() = default;

virtual bool init() noexcept = 0;
virtual bool shutdown() noexcept = 0;
inline bool isInit() const noexcept { return m_init; };

std::optional<uint8_t> getChannelId() const noexcept { return m_hardware->getChannelId(); };

inline bool isAcquired() const noexcept { return m_acquired; }
inline bool isOwned(const drivers::IMusicDriver* owner) const noexcept { return m_owner == owner; }

bool acquire(drivers::IMusicDriver* owner);
bool release(const drivers::IMusicDriver* owner);

// helpers methods
void setVolume(const uint8_t volume);
void setPan(const uint8_t pan);
void setVolumePan(const uint8_t volume, const uint8_t pan);

inline std::shared_ptr<audio::IMixer> getMixer() const noexcept { return m_mixer; };
virtual hardware::IHardware* getHardware() const noexcept { return m_hardware; };
virtual eDeviceName getName() const noexcept = 0;
const eDeviceType type;
protected:
bool m_init = false;
std::shared_ptr<audio::IMixer> m_mixer;
hardware::IHardware* m_hardware = nullptr;
private:
// TODO: remove the atomic when removing the thread in MIDDrv
std::atomic<bool> m_acquired = false;
std::atomic<drivers::IMusicDriver*> m_owner = nullptr;
};

template<class T, class To = devices::IDevice, typename... Args>
std::shared_ptr<To> make_device(Args... args)
{
return std::dynamic_pointer_cast<To>(std::make_shared<T>(args...));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ namespace HyperSonicDrivers::devices
return false;
}

eDeviceName MT32::getName() const noexcept
{
return eDeviceName::MT32;
}

void MT32::lcd_message(const std::string& msg) noexcept
{
m_mt32->sysEx(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ namespace HyperSonicDrivers::devices
bool init() noexcept override;
bool shutdown() noexcept override;

eDeviceName getName() const noexcept override;

inline std::shared_ptr<hardware::mt32::MT32> getMt32() const noexcept { return m_mt32; };

void lcd_message(const std::string& msg) noexcept;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ namespace HyperSonicDrivers::devices
const hardware::opl::OplEmulator emulator,
const hardware::opl::OplType type,
const uint8_t volume, const uint8_t pan) :
IDevice(mixer, eDeviceType::Opl)
IDevice(mixer, eDeviceType::Opl),
m_emulator(emulator)
{
using hardware::opl::OPLFactory;
using utils::logC;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,10 @@ namespace HyperSonicDrivers::devices
bool shutdown() noexcept override;

inline std::shared_ptr<hardware::opl::OPL> getOpl() const noexcept { return m_opl; };
hardware::opl::OPL* getHardware() const noexcept override { return dynamic_cast<hardware::opl::OPL*>(IDevice::getHardware()); };
inline hardware::opl::OPL* getHardware() const noexcept override { return dynamic_cast<hardware::opl::OPL*>(IDevice::getHardware()); };
inline hardware::opl::OplEmulator getEmulatorType() const noexcept { return m_emulator; };
private:
std::shared_ptr<hardware::opl::OPL> m_opl;
const hardware::opl::OplEmulator m_emulator;
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,9 @@ namespace HyperSonicDrivers::devices
Opl(mixer, emulator, OplType::DUAL_OPL2, volume, pan)
{
}

eDeviceName SbPro::getName() const noexcept
{
return eDeviceName::SbPro;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,7 @@ namespace HyperSonicDrivers::devices
);

~SbPro() override = default;

eDeviceName getName() const noexcept override;
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,9 @@ namespace HyperSonicDrivers::devices
Opl(mixer, emulator, OplType::OPL3, volume, pan)
{
}

eDeviceName SbPro2::getName() const noexcept
{
return eDeviceName::SbPro2;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,7 @@ namespace HyperSonicDrivers::devices
);

~SbPro2() override = default;

eDeviceName getName() const noexcept override;
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,12 @@ namespace HyperSonicDrivers::devices
Opl = 0,
Mt32,
};

enum class eDeviceName
{
Adlib,
SbPro,
SbPro2,
MT32
};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#include <HyperSonicDrivers/drivers/IMusicDriver.hpp>
#include <HyperSonicDrivers/utils/ILogger.hpp>

namespace HyperSonicDrivers::drivers
{
IMusicDriver::IMusicDriver(const std::shared_ptr<devices::IDevice>& device) :
m_device(device)
{
if (m_device == nullptr)
{
utils::throwLogC<std::runtime_error>("device is null");
}
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
#pragma once

#include <memory>
#include <HyperSonicDrivers/devices/IDevice.hpp>

namespace HyperSonicDrivers::drivers
{
/**
Expand All @@ -16,7 +19,7 @@ namespace HyperSonicDrivers::drivers
IMusicDriver(IMusicDriver&&) = delete;
IMusicDriver& operator=(IMusicDriver&) = delete;

IMusicDriver() = default;
explicit IMusicDriver(const std::shared_ptr<devices::IDevice>& device);
virtual ~IMusicDriver() = default;

virtual void play(const uint8_t track) noexcept = 0;
Expand All @@ -31,5 +34,10 @@ namespace HyperSonicDrivers::drivers

// TODO: it might not be required
//virtual bool isPaused() const noexcept = 0;

inline std::shared_ptr<devices::IDevice> getDevice() const noexcept { return m_device; };
protected:
// this is used to "lock" the device to a specific driver output and passed to IMidiDriver
std::shared_ptr<devices::IDevice> m_device;
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ namespace HyperSonicDrivers::drivers
const audio::mixer::eChannelGroup group,
const uint8_t volume,
const uint8_t pan
) : m_device(device), m_group(group), m_volume(volume), m_pan(pan)
) : IMusicDriver(device),
m_group(group), m_volume(volume), m_pan(pan)
{
// TODO: move the acquire logic where the callback is set
// NOTE/TODO: this brings up the acquire should set up the callback too?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,6 @@ namespace HyperSonicDrivers::drivers
inline void setTempo(const uint32_t tempo) noexcept { m_midiTempoChanged = true; m_tempo = tempo; }
bool open_() noexcept;
private:
// this is used to "lock" the device to a specific driver output and passed to IMidiDriver
std::shared_ptr<devices::IDevice> m_device;
// this is to abstract the specific midi driver implementation
std::unique_ptr<drivers::midi::IMidiDriver> m_midiDriver;
std::shared_ptr<audio::MIDI> m_midi;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ namespace HyperSonicDrivers::drivers::westwood
const audio::mixer::eChannelGroup group,
const uint8_t volume,
const uint8_t pan) :
m_device(opl), m_opl(opl->getOpl())
IMusicDriver(opl),
m_opl(opl->getOpl())
{
memset(m_channels.data(), 0, sizeof(m_channels));
hardware::TimerCallBack cb = std::bind(&ADLDriver::onCallback, this);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,6 @@ namespace HyperSonicDrivers::drivers::westwood
uint8_t m_opExtraLevel1BD = 0;
uint8_t m_opExtraLevel2BD = 0;

std::shared_ptr<devices::Opl> m_device;
std::shared_ptr<hardware::opl::OPL> m_opl;

struct QueueEntry
Expand Down
38 changes: 38 additions & 0 deletions sdl2-hyper-sonic-drivers/src/std/IDeviceTypesFormatter.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#pragma once

#include <string>
#include <format>
#include <HyperSonicDrivers/devices/types.hpp>

namespace std
{
template<>
struct formatter<HyperSonicDrivers::devices::eDeviceName> : formatter<string_view>
{
template<typename FormatContext>
auto format(HyperSonicDrivers::devices::eDeviceName device_name, FormatContext& fc) const
{
string str;

switch (device_name)
{
using enum HyperSonicDrivers::devices::eDeviceName;

case Adlib:
str = "Adlib";
break;
case SbPro:
str = "SbPro";
break;
case SbPro2:
str = "SbPro2";
break;
case MT32:
str = "MT32";
break;
}

return formatter<std::string_view>::format(str, fc);
}
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,13 @@ macro_test(
"../fixtures/midifile_sample.mid"
)

macro_test(
EXE TestIMusicDriver
FILES "drivers/TestIMusicDriver.cpp"
LINKS_PRIVATE hyper-sonic-drivers-static
FIXTURES
)

macro_test(
EXE TestMameOPL2
FILES "hardware/opl/scummvm/mame/TestMameOPL2.cpp"
Expand Down
Loading

0 comments on commit 2fa3b7a

Please sign in to comment.