From 212a7bf138cfe31cf46ecbd8553fbd5b00584183 Mon Sep 17 00:00:00 2001 From: kichikuou Date: Tue, 22 Sep 2026 20:34:26 +0900 Subject: [PATCH] SDL: Test mixer time and volume conversions Share SDL3_mixer gain and 10-millisecond time conversions across the PCM, BGM, CD, and MIDI backends. Add SDL3 unit coverage for volume clamping, combined gain, time units, and tick counter wraparound. --- src/CMakeLists.txt | 6 ++++++ src/bgm.sdl3mixer.c | 20 ++++++------------- src/cdrom.sdl3mixer.c | 12 ++---------- src/midi.sdl3mixer.c | 13 ++----------- src/pcm.sdl3mixer.c | 15 +++------------ src/sdl3_mixer_utils.c | 25 ++++++++++++++++++++++++ src/sdl3_mixer_utils.h | 10 ++++++++++ src/sdl3_mixer_utils_test.c | 38 +++++++++++++++++++++++++++++++++++++ src/src_tests.c | 6 ++++++ 9 files changed, 98 insertions(+), 47 deletions(-) create mode 100644 src/sdl3_mixer_utils.c create mode 100644 src/sdl3_mixer_utils.h create mode 100644 src/sdl3_mixer_utils_test.c diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 022613b..cd5042c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -109,6 +109,7 @@ elseif (XSYSTEM35_SDL_VERSION STREQUAL "3") target_sources(xsystem35 PRIVATE pcm.sdl3mixer.c sdl3_mixer_backend.c + sdl3_mixer_utils.c bgm.sdl3mixer.c) target_compile_definitions(xsystem35 PRIVATE HAVE_SDL3_MIXER_BACKEND) else() @@ -226,6 +227,11 @@ else() # non-emscripten, non-android target_compile_definitions(src_tests PRIVATE TEST_FONT_DIR="${PROJECT_SOURCE_DIR}/fonts") target_link_libraries(src_tests PRIVATE src_lib xsystem35_sdl) + if (XSYSTEM35_SDL_VERSION STREQUAL "3") + target_sources(src_tests PRIVATE + sdl3_mixer_utils.c + sdl3_mixer_utils_test.c) + endif() add_test(NAME src_tests COMMAND src_tests) file(COPY testdata DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) endif() diff --git a/src/bgm.sdl3mixer.c b/src/bgm.sdl3mixer.c index 98e4702..49f1a58 100644 --- a/src/bgm.sdl3mixer.c +++ b/src/bgm.sdl3mixer.c @@ -18,6 +18,7 @@ #include "music_private.h" #include "nact.h" #include "sdl3_mixer_backend.h" +#include "sdl3_mixer_utils.h" #include "system.h" static DRIFILETYPE dri_type; @@ -26,19 +27,9 @@ static int current_no; static int current_vol = 100; static uint32_t start_time; -static int clamp_volume(int volume) -{ - if (volume < 0) - return 0; - if (volume > 100) - return 100; - return volume; -} - static float music_gain(int volume) { - float gain = clamp_volume(volume) / 100.0f; - return gain * clamp_volume(prv.volval[BGM_VOLVAL_CH]) / 100.0f; + return sdl3_mixer_gain(volume, prv.volval[BGM_VOLVAL_CH]); } static void apply_music_volume(int volume) @@ -105,7 +96,7 @@ bool musbgm_play(int no, int time, int volume, int loop_count) int loops = loop_count == 0 ? -1 : loop_count - 1; current_vol = volume; if (!sdl3_mixer_play_music(SDL3_MIXER_MUSIC_BGM, audio, - loops, time * 10, music_gain(current_vol))) + loops, sdl3_mixer_10ms_to_ms(time), music_gain(current_vol))) return false; current_no = no; start_time = sys_get_ticks(); @@ -115,7 +106,8 @@ bool musbgm_play(int no, int time, int volume, int loop_count) void musbgm_stop(int no, int time) { if (no == current_no) - sdl3_mixer_stop_music(SDL3_MIXER_MUSIC_BGM, time * 10); + sdl3_mixer_stop_music(SDL3_MIXER_MUSIC_BGM, + sdl3_mixer_10ms_to_ms(time)); } void musbgm_fade(int no, int time, int volume) @@ -129,7 +121,7 @@ int musbgm_getpos(int no) { if (!musbgm_isplaying(no)) return 0; - return (sys_get_ticks() - start_time) / 10; + return sdl3_mixer_elapsed_10ms(start_time, sys_get_ticks()); } int musbgm_getlen(int no) diff --git a/src/cdrom.sdl3mixer.c b/src/cdrom.sdl3mixer.c index c6ffcda..89abb4e 100644 --- a/src/cdrom.sdl3mixer.c +++ b/src/cdrom.sdl3mixer.c @@ -21,6 +21,7 @@ #include "cdrom.h" #include "music_private.h" #include "sdl3_mixer_backend.h" +#include "sdl3_mixer_utils.h" #include "system.h" #define PLAYLIST_MAX 256 @@ -32,18 +33,9 @@ static uint32_t start_time; static void cdrom_stop(void); -static int clamp_volume(int volume) -{ - if (volume < 0) - return 0; - if (volume > 100) - return 100; - return volume; -} - static float music_gain(void) { - return clamp_volume(prv.volval[BGM_VOLVAL_CH]) / 100.0f; + return sdl3_mixer_gain(100, prv.volval[BGM_VOLVAL_CH]); } static void apply_volume(void) diff --git a/src/midi.sdl3mixer.c b/src/midi.sdl3mixer.c index f14e88d..5a570b7 100644 --- a/src/midi.sdl3mixer.c +++ b/src/midi.sdl3mixer.c @@ -15,6 +15,7 @@ #include "midi.h" #include "music_private.h" #include "sdl3_mixer_backend.h" +#include "sdl3_mixer_utils.h" #include "system.h" #define FLUIDSYNTH_SOUNDFONT_PATH \ @@ -33,19 +34,9 @@ static bool has_decoder(const char *name) return false; } -static int clamp_volume(int volume) -{ - if (volume < 0) - return 0; - if (volume > 100) - return 100; - return volume; -} - static float music_gain(void) { - float gain = clamp_volume(current_vol) / 100.0f; - return gain * clamp_volume(prv.volval[BGM_VOLVAL_CH]) / 100.0f; + return sdl3_mixer_gain(current_vol, prv.volval[BGM_VOLVAL_CH]); } static void apply_volume(void) diff --git a/src/pcm.sdl3mixer.c b/src/pcm.sdl3mixer.c index 544f361..ec47bab 100644 --- a/src/pcm.sdl3mixer.c +++ b/src/pcm.sdl3mixer.c @@ -21,6 +21,7 @@ #include "music_private.h" #include "nact.h" #include "sdl3_mixer_backend.h" +#include "sdl3_mixer_utils.h" #include "system.h" #define SAMPLE_RATE 44100 @@ -40,15 +41,6 @@ struct decoded_audio { size_t length; }; -static int clamp_volume(int volume) -{ - if (volume < 0) - return 0; - if (volume > 100) - return 100; - return volume; -} - static void apply_volume(int slot) { if (!slots[slot].track) @@ -56,9 +48,8 @@ static void apply_volume(int slot) int channel = prv.vol_pcm_sub[slot]; if ((unsigned)channel >= 16) channel = 0; - float gain = clamp_volume(slots[slot].volume) / 100.0f; - gain *= clamp_volume(prv.volval[channel]) / 100.0f; - MIX_SetTrackGain(slots[slot].track, gain); + MIX_SetTrackGain(slots[slot].track, + sdl3_mixer_gain(slots[slot].volume, prv.volval[channel])); } static MIX_Audio *load_audio(const void *data, size_t size) diff --git a/src/sdl3_mixer_utils.c b/src/sdl3_mixer_utils.c new file mode 100644 index 0000000..05ee6a9 --- /dev/null +++ b/src/sdl3_mixer_utils.c @@ -0,0 +1,25 @@ +#include "sdl3_mixer_utils.h" + +static int clamp_volume(int volume) +{ + if (volume < 0) + return 0; + if (volume > 100) + return 100; + return volume; +} + +float sdl3_mixer_gain(int volume, int balance) +{ + return (float)(clamp_volume(volume) * clamp_volume(balance)) / 10000.0f; +} + +int sdl3_mixer_10ms_to_ms(int time) +{ + return time * 10; +} + +int sdl3_mixer_elapsed_10ms(uint32_t start, uint32_t now) +{ + return (now - start) / 10; +} diff --git a/src/sdl3_mixer_utils.h b/src/sdl3_mixer_utils.h new file mode 100644 index 0000000..0bb4212 --- /dev/null +++ b/src/sdl3_mixer_utils.h @@ -0,0 +1,10 @@ +#ifndef XSYSTEM35_SDL3_MIXER_UTILS_H +#define XSYSTEM35_SDL3_MIXER_UTILS_H + +#include + +float sdl3_mixer_gain(int volume, int balance); +int sdl3_mixer_10ms_to_ms(int time); +int sdl3_mixer_elapsed_10ms(uint32_t start, uint32_t now); + +#endif /* XSYSTEM35_SDL3_MIXER_UTILS_H */ diff --git a/src/sdl3_mixer_utils_test.c b/src/sdl3_mixer_utils_test.c new file mode 100644 index 0000000..c9116fa --- /dev/null +++ b/src/sdl3_mixer_utils_test.c @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2026 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include + +#include "sdl3_mixer_utils.h" +#include "unittest.h" + +static int gain_basis_points(int volume, int balance) +{ + return sdl3_mixer_gain(volume, balance) * 10000.0f + 0.5f; +} + +void sdl3_mixer_utils_test(void) +{ + ASSERT_EQUAL(gain_basis_points(100, 100), 10000); + ASSERT_EQUAL(gain_basis_points(50, 50), 2500); + ASSERT_EQUAL(gain_basis_points(33, 77), 2541); + ASSERT_EQUAL(gain_basis_points(-1, 100), 0); + ASSERT_EQUAL(gain_basis_points(100, -1), 0); + ASSERT_EQUAL(gain_basis_points(101, 200), 10000); + + ASSERT_EQUAL(sdl3_mixer_10ms_to_ms(0), 0); + ASSERT_EQUAL(sdl3_mixer_10ms_to_ms(1), 10); + ASSERT_EQUAL(sdl3_mixer_10ms_to_ms(123), 1230); + + ASSERT_EQUAL(sdl3_mixer_elapsed_10ms(1000, 1000), 0); + ASSERT_EQUAL(sdl3_mixer_elapsed_10ms(1000, 1009), 0); + ASSERT_EQUAL(sdl3_mixer_elapsed_10ms(1000, 1010), 1); + ASSERT_EQUAL(sdl3_mixer_elapsed_10ms(1000, 1123), 12); + ASSERT_EQUAL(sdl3_mixer_elapsed_10ms(UINT32_MAX - 4, 5), 1); +} diff --git a/src/src_tests.c b/src/src_tests.c index 042fbf2..d043e55 100644 --- a/src/src_tests.c +++ b/src/src_tests.c @@ -26,6 +26,9 @@ void gameresource_test(void); void hankaku_test(void); void qnt_test(void); void sdl_compat_test(void); +#if XSYSTEM35_SDL_VERSION == 3 +void sdl3_mixer_utils_test(void); +#endif void variable_test(void); void sys_error(char *format, ...) { @@ -51,5 +54,8 @@ int main() { hankaku_test(); qnt_test(); sdl_compat_test(); +#if XSYSTEM35_SDL_VERSION == 3 + sdl3_mixer_utils_test(); +#endif return 0; }