From d97d49dbe714ee47f0a7cb6cd211edc2de70203e Mon Sep 17 00:00:00 2001 From: kichikuou Date: Tue, 4 Mar 2025 15:59:22 +0900 Subject: [PATCH] Fix Y103 command (play_pcm) * The parameter is the number of times to loop, e.g. Y103,2: will play the sound twice. This still does not work on Windows because PlaySound() does not support specifying the loop count. * Get AMSE data size from its header. This fixes audio glitch at the end of sounds. --- src/emscripten/mako.cpp | 9 +++++---- src/generic/mako.cpp | 11 ++++++----- src/sys/mako.h | 2 +- src/sys/nact_sys3.cpp | 2 +- src/win/mako.cpp | 9 +++++---- 5 files changed, 18 insertions(+), 15 deletions(-) diff --git a/src/emscripten/mako.cpp b/src/emscripten/mako.cpp index 8fe5713..a91a28c 100644 --- a/src/emscripten/mako.cpp +++ b/src/emscripten/mako.cpp @@ -100,7 +100,7 @@ void MAKO::get_mark(int* mark, int* loop) } } -void MAKO::play_pcm(int page, bool loop) +void MAKO::play_pcm(int page, int loops) { static const char header[44] = { 'R' , 'I' , 'F' , 'F' , 0x00, 0x00, 0x00, 0x00, @@ -117,7 +117,8 @@ void MAKO::play_pcm(int page, bool loop) std::vector buffer = amse.load(page); if (!buffer.empty()) { // AMSE形式 (乙女戦記) - int samples = (buffer.size() - 12) * 2; + uint32_t amse_size = SDL_SwapLE32(*reinterpret_cast(&buffer[8])); + int samples = (amse_size - 12) * 2; int total = samples + 0x24; wav_buffer.resize(total + 8); @@ -130,14 +131,14 @@ void MAKO::play_pcm(int page, bool loop) wav_buffer[41] = (samples >> 8) & 0xff; wav_buffer[42] = (samples >> 16) & 0xff; wav_buffer[43] = (samples >> 24) & 0xff; - for (size_t i = 12, p = 44; i < buffer.size(); i++) { + for (uint32_t i = 12, p = 44; i < amse_size; i++) { wav_buffer[p++] = buffer[i] & 0xf0; wav_buffer[p++] = (buffer[i] & 0x0f) << 4; } } } if (muspcm_load_data(wav_buffer.data(), wav_buffer.size())) - EM_ASM({ xsystem35.audio.pcm_start(0, $0); }, loop ? 0 : 1); + EM_ASM({ xsystem35.audio.pcm_start(0, $0); }, loops); } void MAKO::stop_pcm() { diff --git a/src/generic/mako.cpp b/src/generic/mako.cpp index 591368e..9f6504a 100644 --- a/src/generic/mako.cpp +++ b/src/generic/mako.cpp @@ -185,7 +185,7 @@ void MAKO::get_mark(int* mark, int* loop) midi->get_mark(mark, loop); } -void MAKO::play_pcm(int page, bool loop) +void MAKO::play_pcm(int page, int loops) { static char header[44] = { 'R' , 'I' , 'F' , 'F' , 0x00, 0x00, 0x00, 0x00, 'W' , 'A' , 'V' , 'E' , 'f' , 'm' , 't' , ' ' , @@ -199,13 +199,14 @@ void MAKO::play_pcm(int page, bool loop) if (!buffer.empty()) { // WAV形式 (Only You) mix_chunk = Mix_LoadWAV_RW(SDL_RWFromConstMem(buffer.data(), buffer.size()), 1 /* freesrc */); - Mix_PlayChannel(-1, mix_chunk, loop ? -1 : 0); + Mix_PlayChannel(-1, mix_chunk, loops ? loops : -1); return; } buffer = amse.load(page); if (!buffer.empty()) { // AMSE形式 (乙女戦記) - int samples = (buffer.size() - 12) * 2; + uint32_t amse_size = SDL_SwapLE32(*reinterpret_cast(&buffer[8])); + int samples = (amse_size - 12) * 2; int total = samples + 0x24; uint8* wav = (uint8*)malloc(total + 8); @@ -218,14 +219,14 @@ void MAKO::play_pcm(int page, bool loop) wav[41] = (samples >> 8) & 0xff; wav[42] = (samples >> 16) & 0xff; wav[43] = (samples >> 24) & 0xff; - for (size_t i = 12, p = 44; i < buffer.size(); i++) { + for (uint32_t i = 12, p = 44; i < amse_size; i++) { wav[p++] = buffer[i] & 0xf0; wav[p++] = (buffer[i] & 0x0f) << 4; } mix_chunk = Mix_LoadWAV_RW(SDL_RWFromConstMem(wav, total + 8), 1 /* freesrc */); free(wav); - Mix_PlayChannel(-1, mix_chunk, loop ? -1 : 0); + Mix_PlayChannel(-1, mix_chunk, loops ? loops : -1); } } diff --git a/src/sys/mako.h b/src/sys/mako.h index d889843..cb387fe 100644 --- a/src/sys/mako.h +++ b/src/sys/mako.h @@ -35,7 +35,7 @@ public: bool check_music(); void get_mark(int* mark, int* loop); - void play_pcm(int page, bool loop); + void play_pcm(int page, int loops); void stop_pcm(); bool check_pcm(); diff --git a/src/sys/nact_sys3.cpp b/src/sys/nact_sys3.cpp index 8ec35c9..03997e4 100644 --- a/src/sys/nact_sys3.cpp +++ b/src/sys/nact_sys3.cpp @@ -942,7 +942,7 @@ void NACT_Sys3::cmd_y() break; case 103: if(pcm_index < MAX_PCM) { - mako->play_pcm(pcm[pcm_index], param ? false : true); + mako->play_pcm(pcm[pcm_index], param); } break; case 104: diff --git a/src/win/mako.cpp b/src/win/mako.cpp index 4c5a1ab..1deb987 100644 --- a/src/win/mako.cpp +++ b/src/win/mako.cpp @@ -408,7 +408,7 @@ void MAKO::get_mark(int* mark, int* loop) midi->get_mark(mark, loop); } -void MAKO::play_pcm(int page, bool loop) +void MAKO::play_pcm(int page, int loops) { static char header[44] = { 'R' , 'I' , 'F' , 'F' , 0x00, 0x00, 0x00, 0x00, 'W' , 'A' , 'V' , 'E' , 'f' , 'm' , 't' , ' ' , @@ -424,7 +424,8 @@ void MAKO::play_pcm(int page, bool loop) std::vector buffer = amse.load(page); if (!buffer.empty()) { // AMSE形式 (乙女戦記) - int samples = (static_cast(buffer.size()) - 12) * 2; + uint32_t amse_size = SDL_SwapLE32(*reinterpret_cast(&buffer[8])); + int samples = (static_cast(amse_size) - 12) * 2; int total = samples + 0x24; wav_buffer.resize(total + 8); @@ -437,13 +438,13 @@ void MAKO::play_pcm(int page, bool loop) wav_buffer[41] = (samples >> 8) & 0xff; wav_buffer[42] = (samples >> 16) & 0xff; wav_buffer[43] = (samples >> 24) & 0xff; - for (size_t i = 12, p = 44; i < buffer.size(); i++) { + for (uint32_t i = 12, p = 44; i < amse_size; i++) { wav_buffer[p++] = buffer[i] & 0xf0; wav_buffer[p++] = (buffer[i] & 0x0f) << 4; } } } - PlaySound((LPCTSTR)wav_buffer.data(), NULL, SND_ASYNC | SND_MEMORY | (loop ? SND_LOOP : 0)); + PlaySound((LPCTSTR)wav_buffer.data(), NULL, SND_ASYNC | SND_MEMORY | (loops ? 0 : SND_LOOP)); } void MAKO::stop_pcm()