From 2956a2cf88fb75527e341ca471170f0244f1ec8e Mon Sep 17 00:00:00 2001 From: NishiOwO Date: Tue, 27 Jan 2026 16:29:09 +0900 Subject: [PATCH] fix channel related things --- client/main.c | 2 +- engine/include/GearSrc/TypeDefs.h | 9 +++++++-- engine/src/sound/snd_flac.c | 1 + engine/src/sound/snd_mp3.c | 1 + engine/src/sound/snd_vorbis.c | 3 ++- engine/src/sound/snd_wav.c | 1 + engine/src/sound/sound.c | 7 ++++++- engine/src/sound/soundengine.c | 20 +++++++++++++++----- 8 files changed, 34 insertions(+), 10 deletions(-) diff --git a/client/main.c b/client/main.c index 14fa042..6b5e79c 100644 --- a/client/main.c +++ b/client/main.c @@ -78,7 +78,7 @@ int main(int argc, char** argv){ GSClientToggleSkybox(GSEngineGetClient(engine), GSTrue); - if((sound = GSSoundOpen(GSClientGetSoundEngine(GSEngineGetClient(engine)), "game:/shanghai.ogg")) != NULL){ + if((sound = GSSoundOpen(GSClientGetSoundEngine(GSEngineGetClient(engine)), "game:/shanghai.flac")) != NULL){ GSSoundToggleLoop(sound, 1); GSSoundStart(sound); } diff --git a/engine/include/GearSrc/TypeDefs.h b/engine/include/GearSrc/TypeDefs.h index 470ed80..2244eee 100644 --- a/engine/include/GearSrc/TypeDefs.h +++ b/engine/include/GearSrc/TypeDefs.h @@ -179,8 +179,13 @@ struct _GSSound { GSFile file; - void* opaque1; - void* opaque2; + void* opaque1; + void* opaque2; + + int from_channel; + ma_channel_converter_config converter_config; + ma_channel_converter converter; + int from_samplerate; ma_resampler_config resampler_config; ma_resampler resampler; diff --git a/engine/src/sound/snd_flac.c b/engine/src/sound/snd_flac.c index 614414a..b003f9c 100644 --- a/engine/src/sound/snd_flac.c +++ b/engine/src/sound/snd_flac.c @@ -45,6 +45,7 @@ GSSound GSSoundOpenFLAC(GSSoundEngine sengine, GSFile file) { } sound->from_samplerate = ((drflac*)sound->opaque1)->sampleRate; + sound->from_channel = ((drflac*)sound->opaque1)->channels; return sound; } diff --git a/engine/src/sound/snd_mp3.c b/engine/src/sound/snd_mp3.c index b1d3db8..5ff64cb 100644 --- a/engine/src/sound/snd_mp3.c +++ b/engine/src/sound/snd_mp3.c @@ -54,6 +54,7 @@ GSSound GSSoundOpenMP3(GSSoundEngine sengine, GSFile file) { } sound->from_samplerate = ((drmp3*)sound->opaque1)->sampleRate; + sound->from_channel = ((drmp3*)sound->opaque1)->channels; return sound; } diff --git a/engine/src/sound/snd_vorbis.c b/engine/src/sound/snd_vorbis.c index 95e1769..0544a2b 100644 --- a/engine/src/sound/snd_vorbis.c +++ b/engine/src/sound/snd_vorbis.c @@ -10,7 +10,7 @@ static void snd_reset(GSSound sound) { } static int snd_read(GSSound sound, GSI16* out, int frame) { - return stb_vorbis_get_samples_short_interleaved(sound->opaque1, 2, out, frame * 2); + return stb_vorbis_get_samples_short_interleaved(sound->opaque1, sound->from_channel, out, frame * sound->from_channel); } static void snd_close(GSSound sound) { @@ -43,6 +43,7 @@ GSSound GSSoundOpenVorbis(GSSoundEngine sengine, GSFile file) { info = stb_vorbis_get_info(sound->opaque1); sound->from_samplerate = info.sample_rate; + sound->from_channel = info.channels; return sound; } diff --git a/engine/src/sound/snd_wav.c b/engine/src/sound/snd_wav.c index f3b57bc..ba3715d 100644 --- a/engine/src/sound/snd_wav.c +++ b/engine/src/sound/snd_wav.c @@ -50,6 +50,7 @@ GSSound GSSoundOpenWAV(GSSoundEngine sengine, GSFile file) { } sound->from_samplerate = ((drwav*)sound->opaque1)->sampleRate; + sound->from_channel = ((drwav*)sound->opaque1)->channels; return sound; } diff --git a/engine/src/sound/sound.c b/engine/src/sound/sound.c index 97608af..3676e1a 100644 --- a/engine/src/sound/sound.c +++ b/engine/src/sound/sound.c @@ -20,6 +20,7 @@ GSSound GSSoundNew(GSSoundEngine sengine) { sound->loop = 0; sound->from_samplerate = 0; + sound->from_channel = 2; ma_mutex_init(&sound->mutex); @@ -33,9 +34,13 @@ GSSound GSSoundNew(GSSoundEngine sengine) { static void after(GSSound s) { GSSoundLock(s); if(s->from_samplerate > 0) { - s->resampler_config = ma_resampler_config_init(ma_format_s16, 2, s->from_samplerate, GSSoundDriverRate, ma_resample_algorithm_linear); + s->resampler_config = ma_resampler_config_init(ma_format_s16, s->from_channel, s->from_samplerate, GSSoundDriverRate, ma_resample_algorithm_linear); ma_resampler_init(&s->resampler_config, NULL, &s->resampler); } + if(s->from_channel != 2) { + s->converter_config = ma_channel_converter_config_init(ma_format_s16, s->from_channel, NULL, 2, NULL, ma_channel_mix_mode_default); + ma_channel_converter_init(&s->converter_config, NULL, &s->converter); + } GSSoundUnlock(s); } diff --git a/engine/src/sound/soundengine.c b/engine/src/sound/soundengine.c index 4f1bcbc..ec84722 100644 --- a/engine/src/sound/soundengine.c +++ b/engine/src/sound/soundengine.c @@ -19,6 +19,7 @@ static void read_callback(void* opaque, GSI16* out, int frame) { int s, f; GSI16* result; GSI16* result2; + GSI16* result3; GSSoundLock(sengine->sound[i]); if(sengine->sound[i]->paused || sengine->sound[i]->read == NULL) { @@ -32,8 +33,8 @@ static void read_callback(void* opaque, GSI16* out, int frame) { f = frame; } - result = malloc(sizeof(*result) * f * 2); - memset(result, 0, sizeof(*result) * f * 2); + result = malloc(sizeof(*result) * f * sengine->sound[i]->from_channel); + memset(result, 0, sizeof(*result) * f * sengine->sound[i]->from_channel); s = sengine->sound[i]->read(sengine->sound[i], result, f); if(s > 0) { int j; @@ -42,8 +43,8 @@ static void read_callback(void* opaque, GSI16* out, int frame) { ma_uint64 fin = f; ma_uint64 fout = frame; - result2 = malloc(sizeof(*result2) * frame * 2); - memset(result2, 0, sizeof(*result2) * frame * 2); + result2 = malloc(sizeof(*result2) * frame * sengine->sound[i]->from_channel); + memset(result2, 0, sizeof(*result2) * frame * sengine->sound[i]->from_channel); ma_resampler_process_pcm_frames(&sengine->sound[i]->resampler, result, &fin, result2, &fout); @@ -52,8 +53,17 @@ static void read_callback(void* opaque, GSI16* out, int frame) { result2 = result; } - for(j = 0; j < s * 2; j++) buffer[j] += (GSNumber)result2[j] / 32767; + if(sengine->sound[i]->from_channel == 2) { + result3 = result2; + } else { + result3 = malloc(sizeof(*result3) * frame * 2); + memset(result3, 0, sizeof(*result3) * frame * 2); + ma_channel_converter_process_pcm_frames(&sengine->sound[i]->converter, result3, result2, frame); + for(j = 0; j < s * 2; j++) buffer[j] += (GSNumber)result3[j] / 32767; + } + + if(result3 != result2) free(result3); if(result2 != result) free(result2); } else if(sengine->sound[i]->loop && sengine->sound[i]->reset != NULL) { sengine->sound[i]->reset(sengine->sound[i]);