From: Stefan Reinauer Date: Sun, 31 May 2026 07:18:38 +0000 (-0700) Subject: sound: track QEMU output voices separately X-Git-Url: https://git.unchartedbackwaters.co.uk/w/?a=commitdiff_plain;h=1246eda13acffa3a536c89ca6539b24f589ad142;p=francis%2Fwinuae.git sound: track QEMU output voices separately Keep every QEMU output voice on a small linked list instead of replacing a single global pointer. Pass the voice through the audio callback so each active stream reads its own buffer. Update all active QEMU voice volumes, only run QEMU board audio when a voice is active, clamp writes to the sample buffer, and return no input data until the capture path has a real backend. --- diff --git a/qemuvga/qemuaudio.h b/qemuvga/qemuaudio.h index 0551096f..c39c5912 100644 --- a/qemuvga/qemuaudio.h +++ b/qemuvga/qemuaudio.h @@ -32,6 +32,7 @@ struct SWVoiceOut audfmt_e fmt; int left_volume, right_volume; int streamid; + struct SWVoiceOut *next; }; struct SWVoiceIn { diff --git a/sndboard.cpp b/sndboard.cpp index 3d17fa6e..68ba3706 100644 --- a/sndboard.cpp +++ b/sndboard.cpp @@ -2831,7 +2831,7 @@ static SWVoiceOut *qemu_voice_out; static bool audio_state_sndboard_qemu(int streamid, void *params) { - SWVoiceOut *out = qemu_voice_out; + SWVoiceOut *out = (SWVoiceOut*)params; if (!out || !out->active) return false; @@ -2876,39 +2876,60 @@ static bool audio_state_sndboard_qemu(int streamid, void *params) return true; } -static void calculate_volume_qemu(void) +static void calculate_volume_qemu(SWVoiceOut *out) { - SWVoiceOut *out = qemu_voice_out; if (!out) return; out->left_volume = (100 - currprefs.sound_volume_board) * 32768 / 100; out->right_volume = (100 - currprefs.sound_volume_board) * 32768 / 100; } +static void calculate_volume_qemu_all(void) +{ + for (SWVoiceOut *out = qemu_voice_out; out; out = out->next) { + calculate_volume_qemu(out); + } +} + +static bool qemu_voice_out_active(void) +{ + for (SWVoiceOut *out = qemu_voice_out; out; out = out->next) { + if (out->active) + return true; + } + return false; +} + void AUD_close_in(QEMUSoundCard *card, SWVoiceIn *sw) { } int AUD_read(SWVoiceIn *sw, void *pcm_buf, int size) { - return size; + return 0; } int AUD_write(SWVoiceOut *sw, void *pcm_buf, int size) { + if (!sw || !pcm_buf || size <= 0) + return 0; + if (size > (int)sizeof(sw->samplebuf)) + size = sizeof(sw->samplebuf); memcpy(sw->samplebuf, pcm_buf, size); sw->samplebuf_total = size; return sw->samplebuf_total; } void AUD_set_active_out(SWVoiceOut *sw, int on) { + if (!sw) + return; sw->active = on != 0; sw->event_time = (int)(base_event_clock * CYCLE_UNIT / sw->freq); sw->samplebuf_index = 0; sw->samplebuf_total = 0; - calculate_volume_qemu(); + calculate_volume_qemu(sw); audio_enable_stream(false, sw->streamid, 2, NULL, NULL); sw->streamid = 0; if (on) { - sw->streamid = audio_enable_stream(true, -1, 2, audio_state_sndboard_qemu, NULL); + sw->streamid = audio_enable_stream(true, -1, 2, audio_state_sndboard_qemu, sw); } } void AUD_set_active_in(SWVoiceIn *sw, int on) @@ -2920,8 +2941,15 @@ int AUD_is_active_in(SWVoiceIn *sw) } void AUD_close_out(QEMUSoundCard *card, SWVoiceOut *sw) { - qemu_voice_out = NULL; if (sw) { + SWVoiceOut **outp = &qemu_voice_out; + while (*outp) { + if (*outp == sw) { + *outp = sw->next; + break; + } + outp = &(*outp)->next; + } audio_enable_stream(false, sw->streamid, 0, NULL, NULL); sw->streamid = 0; xfree(sw); @@ -2946,8 +2974,11 @@ SWVoiceOut *AUD_open_out( struct audsettings *settings) { SWVoiceOut *out = sw; - if (!sw) + if (!sw) { out = xcalloc(SWVoiceOut, 1); + out->next = qemu_voice_out; + qemu_voice_out = out; + } int bits = 8; if (settings->fmt >= AUD_FMT_U16) @@ -2967,8 +2998,6 @@ SWVoiceOut *AUD_open_out( write_log(_T("QEMU AUDIO: freq=%d ch=%d bits=%d (fmt=%d) '%s'\n"), out->freq, out->ch, bits, settings->fmt, name2); xfree(name2); - qemu_voice_out = out; - return out; } @@ -2983,7 +3012,7 @@ static void sndboard_vsync(void) sndboard_vsync_toccata(&snddev[0]); if (fm801_active) sndboard_vsync_fm801(); - if (qemu_voice_out && qemu_voice_out->active) + if (qemu_voice_out_active()) sndboard_vsync_qemu(); } @@ -2993,8 +3022,7 @@ void sndboard_ext_volume(void) calculate_volume_toccata(&snddev[0]); if (fm801_active) calculate_volume_fm801(); - if (qemu_voice_out && qemu_voice_out->active) - calculate_volume_qemu(); + calculate_volume_qemu_all(); } static void snd_init(void)