Le 24/05/2023 à 23:10, Mark Cave-Ayland a écrit :
> 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.
>
> Since not all audio backends guarantee an all-zero output when no data is
> provided, explicitly generate an all-zero output when this condition occurs to
> avoid the audio backends re-using their internal buffers and looping audio once
> the FIFOs are empty.
>
> Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
> ---
> hw/audio/asc.c | 9 ++++++---
> 1 file changed, 6 insertions(+), 3 deletions(-)
>
> diff --git a/hw/audio/asc.c b/hw/audio/asc.c
> index 04194b1e43..c5173a8d35 100644
> --- a/hw/audio/asc.c
> +++ b/hw/audio/asc.c
> @@ -158,8 +158,10 @@ static int generate_fifo(ASCState *s, int maxsamples)
> limit = MIN(MAX(s->fifos[0].cnt, s->fifos[1].cnt), maxsamples);
>
> /*
> - * If starting a new run with no FIFO data present, update the IRQ and
> - * continue
> + * MacOS (un)helpfully leaves the FIFO engine running even when it has
> + * finished writing out samples. Since not all audio backends guarantee an
> + * all-zero output when no data is provided, zero out the sample buffer
> + * and then update the FIFO flags and IRQ as normal and continue
> */
> if (limit == 0 && s->fifos[0].int_status == 0 &&
> s->fifos[1].int_status == 0) {
> @@ -168,8 +170,9 @@ static int generate_fifo(ASCState *s, int maxsamples)
> s->fifos[1].int_status |= ASC_FIFO_STATUS_HALF_FULL |
> ASC_FIFO_STATUS_FULL_EMPTY;
>
> + memset(buf, 0x80, maxsamples << s->shift);
> asc_raise_irq(s);
> - return 0;
> + return maxsamples;
> }
>
> while (count < limit) {
Reviewed-by: Laurent Vivier <laurent@vivier.eu>