From: Laurent Vivier <laurent@vivier.eu>
To: qemu-devel@nongnu.org
Cc: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>,
Laurent Vivier <laurent@vivier.eu>
Subject: [PULL 08/20] asc: generate silence if FIFO empty but engine still running
Date: Sun, 8 Oct 2023 08:23:37 +0200 [thread overview]
Message-ID: <20231008062349.2733552-9-laurent@vivier.eu> (raw)
In-Reply-To: <20231008062349.2733552-1-laurent@vivier.eu>
From: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
MacOS (un)helpfully leaves the FIFO engine running even when all the samples have
been written to the hardware, and expects the FIFO status flags and IRQ to be
updated continuously.
There is an additional problem in that not all audio backends guarantee an
all-zero output when there is no FIFO data available, in particular the Windows
dsound backend which re-uses its internal circular buffer causing the last played
sound to loop indefinitely.
Whilst this is effectively a bug in the Windows dsound backend, work around it
for now using a simple heuristic: if the FIFO remains empty for half a cycle
(~23ms) then continuously fill the generated buffer with empty silence.
Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Reviewed-by: Laurent Vivier <laurent@vivier.eu>
Message-ID: <20231004083806.757242-9-mark.cave-ayland@ilande.co.uk>
Signed-off-by: Laurent Vivier <laurent@vivier.eu>
---
include/hw/audio/asc.h | 2 ++
hw/audio/asc.c | 19 +++++++++++++++++++
2 files changed, 21 insertions(+)
diff --git a/include/hw/audio/asc.h b/include/hw/audio/asc.h
index d9412815c324..4741f92c4613 100644
--- a/include/hw/audio/asc.h
+++ b/include/hw/audio/asc.h
@@ -68,6 +68,8 @@ struct ASCState {
int samples;
int shift;
+ uint8_t *silentbuf;
+
/* Time when we were last able to generate samples */
int64_t fifo_empty_ns;
diff --git a/hw/audio/asc.c b/hw/audio/asc.c
index 9084708eafab..0f36b4ce9b6f 100644
--- a/hw/audio/asc.c
+++ b/hw/audio/asc.c
@@ -341,6 +341,21 @@ static void asc_out_cb(void *opaque, int free_b)
}
if (!generated) {
+ /* Workaround for audio underflow bug on Windows dsound backend */
+ int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+ int silent_samples = muldiv64(now - s->fifo_empty_ns,
+ NANOSECONDS_PER_SECOND, ASC_FREQ);
+
+ if (silent_samples > ASC_FIFO_CYCLE_TIME / 2) {
+ /*
+ * No new FIFO data within half a cycle time (~23ms) so fill the
+ * entire available buffer with silence. This prevents an issue
+ * with the Windows dsound backend whereby the sound appears to
+ * loop because the FIFO has run out of data, and the driver
+ * reuses the stale content in its circular audio buffer.
+ */
+ AUD_write(s->voice, s->silentbuf, samples << s->shift);
+ }
return;
}
@@ -618,6 +633,7 @@ static void asc_unrealize(DeviceState *dev)
ASCState *s = ASC(dev);
g_free(s->mixbuf);
+ g_free(s->silentbuf);
AUD_remove_card(&s->card);
}
@@ -642,6 +658,9 @@ static void asc_realize(DeviceState *dev, Error **errp)
s->samples = AUD_get_buffer_size_out(s->voice) >> s->shift;
s->mixbuf = g_malloc0(s->samples << s->shift);
+ s->silentbuf = g_malloc0(s->samples << s->shift);
+ memset(s->silentbuf, 0x80, s->samples << s->shift);
+
/* Add easc registers if required */
if (s->type == ASC_TYPE_EASC) {
memory_region_add_subregion(&s->asc, ASC_EXTREG_OFFSET,
--
2.41.0
next prev parent reply other threads:[~2023-10-08 6:26 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-10-08 6:23 [PULL 00/20] Q800 for 8.2 patches Laurent Vivier
2023-10-08 6:23 ` [PULL 01/20] q800-glue.c: convert to Resettable interface Laurent Vivier
2023-10-08 6:23 ` [PULL 02/20] q800: add djMEMC memory controller Laurent Vivier
2023-10-08 6:23 ` [PULL 03/20] q800: add machine id register Laurent Vivier
2023-10-08 6:23 ` [PULL 04/20] q800: implement additional machine id bits on VIA1 port A Laurent Vivier
2023-10-08 6:23 ` [PULL 05/20] q800: add IOSB subsystem Laurent Vivier
2023-10-08 6:23 ` [PULL 06/20] q800: allow accesses to RAM area even if less memory is available Laurent Vivier
2023-10-08 6:23 ` [PULL 07/20] audio: add Apple Sound Chip (ASC) emulation Laurent Vivier
2023-10-08 6:23 ` Laurent Vivier [this message]
2023-10-08 6:23 ` [PULL 09/20] q800: add Apple Sound Chip (ASC) audio to machine Laurent Vivier
2023-10-08 6:23 ` [PULL 10/20] q800: add easc bool machine class property to switch between ASC and EASC Laurent Vivier
2023-10-08 6:23 ` [PULL 11/20] swim: add trace events for IWM and ISM registers Laurent Vivier
2023-10-08 6:23 ` [PULL 12/20] swim: split into separate IWM and ISM register blocks Laurent Vivier
2023-10-08 6:23 ` [PULL 13/20] swim: update IWM/ISM register block decoding Laurent Vivier
2023-10-08 6:23 ` [PULL 14/20] mac_via: work around underflow in TimeDBRA timing loop in SETUPTIMEK Laurent Vivier
2023-10-08 6:23 ` [PULL 15/20] mac_via: workaround NetBSD ADB bus enumeration issue Laurent Vivier
2023-10-08 6:23 ` [PULL 16/20] mac_via: implement ADB_STATE_IDLE state if shift register in input mode Laurent Vivier
2023-10-08 6:23 ` [PULL 17/20] mac_via: always clear ADB interrupt when switching to A/UX mode Laurent Vivier
2023-10-08 6:23 ` [PULL 18/20] q800: add ESCC alias at 0xc000 Laurent Vivier
2023-10-08 6:23 ` [PULL 19/20] q800: add alias for MacOS toolbox ROM at 0x40000000 Laurent Vivier
2023-10-08 6:23 ` [PULL 20/20] mac_via: extend timer calibration hack to work with A/UX Laurent Vivier
2023-10-10 1:29 ` [PULL 00/20] Q800 for 8.2 patches Stefan Hajnoczi
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20231008062349.2733552-9-laurent@vivier.eu \
--to=laurent@vivier.eu \
--cc=mark.cave-ayland@ilande.co.uk \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).