Skip to content

Commit d59d5b6

Browse files
review ADLFile (#285)
* review ADLFile * code rev * adl-play example * fix adlFile num tracks * Fix CI * 📝 Add docstrings to `refactor` (#286) Docstrings generation was requested by @Raffaello. * #285 (comment) The following files were modified: * `sdl2-hyper-sonic-drivers/examples/adl-play.cpp` * `sdl2-hyper-sonic-drivers/sdl2-hyper-sonic-drivers.cpp` * `sdl2-hyper-sonic-drivers/src/HyperSonicDrivers/files/westwood/ADLFile.cpp` * `sdl2-hyper-sonic-drivers/test/HyperSonicDrivers/files/westwood/TestADLFile.cpp` Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * code rev * Fix Build * Fix SonarCloud * Fix ADL v3 header type word instead of byte * update Version patch * codeRabbit rev * Fix Audio Driver Play track type to uint16_t * code rev * minor improve of cross-OS code compatibility --------- Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
1 parent a58600b commit d59d5b6

File tree

20 files changed

+446
-100
lines changed

20 files changed

+446
-100
lines changed

.github/workflows/ci-windows.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ jobs:
6767
- uses: actions/checkout@v4
6868
- name: create build dir
6969
run: mkdir build
70-
- uses: actions/cache@v2
70+
- uses: actions/cache@v4
7171
id: dep-cache
7272
with:
7373
path: C:/vcpkg/packages

.github/workflows/sonarcloud.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,13 +53,13 @@ jobs:
5353
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
5454
- name: create build dir
5555
run: mkdir build
56-
- uses: actions/cache@v2
56+
- uses: actions/cache@v4
5757
id: dep-cache
5858
with:
5959
path: C:/vcpkg/packages
6060
key: ${{ runner.os }}-x64-windows-dep-cache-${{ hashFiles('**/*') }}
6161
restore-keys: ${{ runner.os }}-x64-windows-dep-cache
62-
- uses: actions/cache@v2
62+
- uses: actions/cache@v4
6363
id: sonar-cache
6464
with:
6565
path: |

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
**/out
22
/CMakeSettings.json
33
/.vs
4+
/.vscode
45
/build
56
*.bak
67
sdl2-hyper-sonic-drivers/src/HyperSonicDrivers/version.h

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ if(DEFINED ENV{VCPKG_ROOT} AND NOT DEFINED CMAKE_TOOLCHAIN_FILE)
55
endif()
66

77

8-
project ("sdl2-hyper-sonic-drivers" VERSION 0.18.0 DESCRIPTION "SDL2 based Hyper-Sonic Drivers for emulating old soundcards")
8+
project ("sdl2-hyper-sonic-drivers" VERSION 0.18.1 DESCRIPTION "SDL2 based Hyper-Sonic Drivers for emulating old soundcards")
99
include (TestBigEndian)
1010
TEST_BIG_ENDIAN(IS_BIG_ENDIAN)
1111
if(IS_BIG_ENDIAN)

sdl2-hyper-sonic-drivers/examples/CMakeLists.txt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,18 @@ macro_example(
8787
NONE
8888
)
8989

90+
macro_example(
91+
EXE ADLPlay
92+
FILE "adl-play.cpp"
93+
DEPS hyper-sonic-drivers-static
94+
LINKS ${LIB_SDL2main} hyper-sonic-drivers-static spdlog::spdlog SDL2::SDL2
95+
FIXTURES
96+
"../test/fixtures/DUNE0.ADL"
97+
#"../test/fixtures/EOBSOUND.ADL"
98+
#"../test/fixtures/LOREINTR.ADL"
99+
NONE
100+
)
101+
90102
macro_example(
91103
EXE PCMExample
92104
FILE "pcm-example.cpp"
Lines changed: 224 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,224 @@
1+
#include <HyperSonicDrivers/audio/sdl2/Mixer.hpp>
2+
#include <HyperSonicDrivers/hardware/opl/OPL.hpp>
3+
#include <HyperSonicDrivers/hardware/opl/OPLFactory.hpp>
4+
#include <HyperSonicDrivers/utils/algorithms.hpp>
5+
#include <HyperSonicDrivers/files/westwood/ADLFile.hpp>
6+
#include <HyperSonicDrivers/drivers/westwood/ADLDriver.hpp>
7+
#include <HyperSonicDrivers/utils/ILogger.hpp>
8+
#include <HyperSonicDrivers/devices/Adlib.hpp>
9+
#include <HyperSonicDrivers/devices/SbPro.hpp>
10+
#include <HyperSonicDrivers/devices/SbPro2.hpp>
11+
12+
#include <spdlog/spdlog.h>
13+
#include <fmt/color.h>
14+
15+
16+
#include <SDL2/SDL.h>
17+
18+
#include <memory>
19+
#include <cstdint>
20+
#include <map>
21+
#include <string>
22+
23+
using namespace HyperSonicDrivers;
24+
25+
using hardware::opl::OPLFactory;
26+
using hardware::opl::OplEmulator;
27+
using hardware::opl::OplType;
28+
using utils::delayMillis;
29+
using files::westwood::ADLFile;
30+
using drivers::westwood::ADLDriver;
31+
32+
33+
/**
34+
* @brief Play an ADL file using a chosen OPL emulator/type until the user exits.
35+
*
36+
* Plays the given ADL file through an OPL device constructed from the specified
37+
* emulator and OPL type. The function creates an ADLDriver bound to the
38+
* Music channel group and enters an SDL event-driven loop that starts playback
39+
* (initial track index is 5) and responds to key presses to control playback.
40+
*
41+
* Behavior:
42+
* - Selects an OPL device based on `type`:
43+
* - OPL2 -> Adlib + Opl
44+
* - DUAL_OPL2-> SbPro + Opl
45+
* - OPL3 -> SbPro2 + Opl
46+
* - If the provided mixer is not ready, logs an error and returns immediately.
47+
* - Starts playing the current track when not already playing.
48+
* - Key controls (during playback):
49+
* - ESC: stop all channels and return (exit function)
50+
* - RIGHT: stop channels and advance to the next track (wraps to 0)
51+
* - LEFT: stop channels and go to the previous track (wraps to last)
52+
*
53+
* This function blocks until ESC is pressed.
54+
*
55+
* @param emu OPL emulator selection used when constructing the device.
56+
* @param type OPL hardware type used to choose the concrete device implementation.
57+
* @param filename Path to the ADL file to load and play.
58+
*/
59+
void adl_play(const OplEmulator emu, const OplType type, std::shared_ptr<audio::IMixer> mixer, const std::string& filename)
60+
{
61+
using devices::make_device;
62+
using utils::ILogger;
63+
64+
auto adlFile = std::make_shared<ADLFile>(filename);
65+
std::shared_ptr<devices::Opl> device;
66+
switch (type)
67+
{
68+
using enum OplType;
69+
70+
case OPL2:
71+
device = make_device<devices::Adlib, devices::Opl>(mixer, emu);
72+
break;
73+
case DUAL_OPL2:
74+
device = make_device<devices::SbPro, devices::Opl>(mixer, emu);
75+
break;
76+
case OPL3:
77+
device = make_device<devices::SbPro2, devices::Opl>(mixer, emu);
78+
break;
79+
80+
}
81+
82+
uint8_t track = 0;
83+
84+
ADLDriver adlDrv(device, audio::mixer::eChannelGroup::Music);
85+
adlDrv.setADLFile(adlFile);
86+
87+
if(!mixer->isReady()) {
88+
spdlog::error("mixer not ready yet..");
89+
return;
90+
}
91+
92+
do
93+
{
94+
if (!adlDrv.isPlaying())
95+
{
96+
adlDrv.play(track);
97+
ILogger::instance->info(fmt::format("Playing track: {}/{}", static_cast<int>(track), adlFile->getNumTracks()), ILogger::eCategory::Application);
98+
}
99+
//delayMillis(1000);
100+
SDL_Event e;
101+
while (SDL_WaitEventTimeout(&e, 100))
102+
{
103+
if (e.type == SDL_QUIT)
104+
{
105+
adlDrv.stopAllChannels();
106+
return;
107+
}
108+
else if (e.type == SDL_KEYDOWN)
109+
{
110+
switch (e.key.keysym.sym)
111+
{
112+
case SDLK_ESCAPE:
113+
{
114+
adlDrv.stopAllChannels();
115+
return;
116+
}
117+
case SDLK_RIGHT:
118+
{
119+
adlDrv.stopAllChannels();
120+
track++;
121+
if (track >= adlFile->getNumTracks())
122+
track = 0;
123+
124+
break;
125+
}
126+
case SDLK_LEFT:
127+
{
128+
adlDrv.stopAllChannels();
129+
if (track > 0)
130+
track--;
131+
else
132+
track = adlFile->getNumTracks() - 1;
133+
134+
break;
135+
}
136+
}
137+
}
138+
}
139+
140+
} while (true);
141+
}
142+
143+
/**
144+
* @brief Program entry point for the ADL playback demo using SDL2 and OPL emulation.
145+
*
146+
* Initializes SDL video, creates a minimal SDL window, and starts an SDL-based audio mixer.
147+
* Iterates over configured OPL emulator and OPL type combinations, prints a colored header
148+
* for each pair, and invokes adl_play to run the ADL playback demo for "DUNE0.ADL".
149+
* Cleans up SDL resources before exiting.
150+
*
151+
* Return codes:
152+
* - 0 : Normal exit after running demos and cleanup.
153+
* - 1 : Mixer initialization failed.
154+
* - -1 : SDL video initialization failed.
155+
* - -2 : SDL window creation failed.
156+
*/
157+
int main(int argc, char* argv[])
158+
{
159+
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS) != 0)
160+
return -1;
161+
162+
auto pWin = SDL_CreateWindow("for Keyboard Input...", 0, 0, 320, 200, 0);
163+
if (!pWin)
164+
{
165+
SDL_Quit();
166+
return -2;
167+
}
168+
169+
170+
auto mixer = audio::make_mixer<audio::sdl2::Mixer>(8, 44100, 1024);
171+
if (!mixer->init())
172+
{
173+
spdlog::error("can't init mixer");
174+
SDL_DestroyWindow(pWin);
175+
SDL_Quit();
176+
return 1;
177+
}
178+
179+
180+
const std::map<OplEmulator, std::string> emus = {
181+
{ OplEmulator::DOS_BOX, "DOS_BOX" },
182+
//{ OplEmulator::MAME, "MAME" },
183+
//{ OplEmulator::NUKED, "NUKED" },
184+
//{ OplEmulator::WOODY, "WOODY" },
185+
};
186+
187+
const std::map<OplType, std::string> types = {
188+
{OplType::OPL2, "OPL2"},
189+
//{OplType::DUAL_OPL2, "DUAL_OPL2"},
190+
//{OplType::OPL3, "OPL3"},
191+
};
192+
193+
const std::string m = "##### {} {} #####";
194+
195+
spdlog::set_level(spdlog::level::info);
196+
HyperSonicDrivers::utils::ILogger::instance->setLevelAll(HyperSonicDrivers::utils::ILogger::eLevel::Info);
197+
for (const auto& emu : emus)
198+
{
199+
for (const auto& type : types)
200+
{
201+
using enum fmt::color;
202+
203+
for (const auto& c : { white_smoke, yellow, aqua,
204+
lime_green, blue_violet, indian_red }) {
205+
spdlog::info(fmt::format(fg(c), m, emu.second, type.second));
206+
}
207+
208+
try
209+
{
210+
adl_play(emu.first, type.first, mixer, "DUNE0.ADL");
211+
//adl_test(emu.first, type.first, mixer, "EOBSOUND.ADL", 1);
212+
//adl_test(emu.first, type.first, mixer, "LOREINTR.ADL", 3);
213+
}
214+
catch (const std::exception& e)
215+
{
216+
spdlog::default_logger()->error(e.what());
217+
}
218+
}
219+
}
220+
221+
SDL_DestroyWindow(pWin);
222+
SDL_Quit();
223+
return 0;
224+
}

0 commit comments

Comments
 (0)