fix channel related things

This commit is contained in:
Nishi 2026-01-27 16:29:09 +09:00
commit 2956a2cf88
Signed by: nishi
GPG key ID: 27EF69B208EB9343
8 changed files with 34 additions and 10 deletions

View file

@ -78,7 +78,7 @@ int main(int argc, char** argv){
GSClientToggleSkybox(GSEngineGetClient(engine), GSTrue); 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); GSSoundToggleLoop(sound, 1);
GSSoundStart(sound); GSSoundStart(sound);
} }

View file

@ -179,8 +179,13 @@ struct _GSSound {
GSFile file; GSFile file;
void* opaque1; void* opaque1;
void* opaque2; void* opaque2;
int from_channel;
ma_channel_converter_config converter_config;
ma_channel_converter converter;
int from_samplerate; int from_samplerate;
ma_resampler_config resampler_config; ma_resampler_config resampler_config;
ma_resampler resampler; ma_resampler resampler;

View file

@ -45,6 +45,7 @@ GSSound GSSoundOpenFLAC(GSSoundEngine sengine, GSFile file) {
} }
sound->from_samplerate = ((drflac*)sound->opaque1)->sampleRate; sound->from_samplerate = ((drflac*)sound->opaque1)->sampleRate;
sound->from_channel = ((drflac*)sound->opaque1)->channels;
return sound; return sound;
} }

View file

@ -54,6 +54,7 @@ GSSound GSSoundOpenMP3(GSSoundEngine sengine, GSFile file) {
} }
sound->from_samplerate = ((drmp3*)sound->opaque1)->sampleRate; sound->from_samplerate = ((drmp3*)sound->opaque1)->sampleRate;
sound->from_channel = ((drmp3*)sound->opaque1)->channels;
return sound; return sound;
} }

View file

@ -10,7 +10,7 @@ static void snd_reset(GSSound sound) {
} }
static int snd_read(GSSound sound, GSI16* out, int frame) { 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) { static void snd_close(GSSound sound) {
@ -43,6 +43,7 @@ GSSound GSSoundOpenVorbis(GSSoundEngine sengine, GSFile file) {
info = stb_vorbis_get_info(sound->opaque1); info = stb_vorbis_get_info(sound->opaque1);
sound->from_samplerate = info.sample_rate; sound->from_samplerate = info.sample_rate;
sound->from_channel = info.channels;
return sound; return sound;
} }

View file

@ -50,6 +50,7 @@ GSSound GSSoundOpenWAV(GSSoundEngine sengine, GSFile file) {
} }
sound->from_samplerate = ((drwav*)sound->opaque1)->sampleRate; sound->from_samplerate = ((drwav*)sound->opaque1)->sampleRate;
sound->from_channel = ((drwav*)sound->opaque1)->channels;
return sound; return sound;
} }

View file

@ -20,6 +20,7 @@ GSSound GSSoundNew(GSSoundEngine sengine) {
sound->loop = 0; sound->loop = 0;
sound->from_samplerate = 0; sound->from_samplerate = 0;
sound->from_channel = 2;
ma_mutex_init(&sound->mutex); ma_mutex_init(&sound->mutex);
@ -33,9 +34,13 @@ GSSound GSSoundNew(GSSoundEngine sengine) {
static void after(GSSound s) { static void after(GSSound s) {
GSSoundLock(s); GSSoundLock(s);
if(s->from_samplerate > 0) { 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); 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); GSSoundUnlock(s);
} }

View file

@ -19,6 +19,7 @@ static void read_callback(void* opaque, GSI16* out, int frame) {
int s, f; int s, f;
GSI16* result; GSI16* result;
GSI16* result2; GSI16* result2;
GSI16* result3;
GSSoundLock(sengine->sound[i]); GSSoundLock(sengine->sound[i]);
if(sengine->sound[i]->paused || sengine->sound[i]->read == NULL) { 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; f = frame;
} }
result = malloc(sizeof(*result) * f * 2); result = malloc(sizeof(*result) * f * sengine->sound[i]->from_channel);
memset(result, 0, sizeof(*result) * f * 2); memset(result, 0, sizeof(*result) * f * sengine->sound[i]->from_channel);
s = sengine->sound[i]->read(sengine->sound[i], result, f); s = sengine->sound[i]->read(sengine->sound[i], result, f);
if(s > 0) { if(s > 0) {
int j; int j;
@ -42,8 +43,8 @@ static void read_callback(void* opaque, GSI16* out, int frame) {
ma_uint64 fin = f; ma_uint64 fin = f;
ma_uint64 fout = frame; ma_uint64 fout = frame;
result2 = malloc(sizeof(*result2) * frame * 2); result2 = malloc(sizeof(*result2) * frame * sengine->sound[i]->from_channel);
memset(result2, 0, sizeof(*result2) * frame * 2); memset(result2, 0, sizeof(*result2) * frame * sengine->sound[i]->from_channel);
ma_resampler_process_pcm_frames(&sengine->sound[i]->resampler, result, &fin, result2, &fout); 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; 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); if(result2 != result) free(result2);
} else if(sengine->sound[i]->loop && sengine->sound[i]->reset != NULL) { } else if(sengine->sound[i]->loop && sengine->sound[i]->reset != NULL) {
sengine->sound[i]->reset(sengine->sound[i]); sengine->sound[i]->reset(sengine->sound[i]);