sdlaudio: add -audiodev sdl,out.buffer-count option

Currently there is a crackling noise with SDL2 audio playback.
Commit bcf19777df: "audio/sdlaudio: Allow audio playback with
SDL2" already mentioned the crackling noise.

Add an out.buffer-count option to give users a chance to select
sane settings for glitch free audio playback. The idea was taken
from the coreaudio backend.

The in.buffer-count option will be used with one of the next
patches.

Signed-off-by: Volker Rümelin <vr_qemu@t-online.de>
Acked-by: Markus Armbruster <armbru@redhat.com>
Message-id: 9315afe5-5958-c0b4-ea1e-14769511a9d5@t-online.de
Message-Id: <20210110100239.27588-3-vr_qemu@t-online.de>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
This commit is contained in:
Volker Rümelin 2021-01-10 11:02:19 +01:00 committed by Gerd Hoffmann
parent ff69c481a2
commit 5a0926c23f
6 changed files with 52 additions and 7 deletions

View File

@ -2003,7 +2003,7 @@ void audio_create_pdos(Audiodev *dev)
CASE(JACK, jack, Jack);
CASE(OSS, oss, Oss);
CASE(PA, pa, Pa);
CASE(SDL, sdl, );
CASE(SDL, sdl, Sdl);
CASE(SPICE, spice, );
CASE(WAV, wav, );

View File

@ -286,7 +286,8 @@ static void handle_sdl(Audiodev *dev)
{
/* SDL is output only */
get_samples_to_usecs("QEMU_SDL_SAMPLES", &dev->u.sdl.out->buffer_length,
&dev->u.sdl.out->has_buffer_length, dev->u.sdl.out);
&dev->u.sdl.out->has_buffer_length,
qapi_AudiodevSdlPerDirectionOptions_base(dev->u.sdl.out));
}
/* wav */

View File

@ -337,7 +337,7 @@ AudiodevPerDirectionOptions *glue(audio_get_pdo_, TYPE)(Audiodev *dev)
case AUDIODEV_DRIVER_PA:
return qapi_AudiodevPaPerDirectionOptions_base(dev->u.pa.TYPE);
case AUDIODEV_DRIVER_SDL:
return dev->u.sdl.TYPE;
return qapi_AudiodevSdlPerDirectionOptions_base(dev->u.sdl.TYPE);
case AUDIODEV_DRIVER_SPICE:
return dev->u.spice.TYPE;
case AUDIODEV_DRIVER_WAV:

View File

@ -276,12 +276,18 @@ static int sdl_init_out(HWVoiceOut *hw, struct audsettings *as,
int endianness;
int err;
AudioFormat effective_fmt;
AudiodevSdlPerDirectionOptions *spdo = s->dev->u.sdl.out;
struct audsettings obt_as;
req.freq = as->freq;
req.format = aud_to_sdlfmt (as->fmt);
req.channels = as->nchannels;
req.samples = audio_buffer_samples(s->dev->u.sdl.out, as, 11610);
/*
* This is wrong. SDL samples are QEMU frames. The buffer size will be
* the requested buffer size multiplied by the number of channels.
*/
req.samples = audio_buffer_samples(
qapi_AudiodevSdlPerDirectionOptions_base(spdo), as, 11610);
req.callback = sdl_callback;
req.userdata = sdl;
@ -301,7 +307,8 @@ static int sdl_init_out(HWVoiceOut *hw, struct audsettings *as,
obt_as.endianness = endianness;
audio_pcm_init_info (&hw->info, &obt_as);
hw->samples = obt.samples;
hw->samples = (spdo->has_buffer_count ? spdo->buffer_count : 4) *
obt.samples;
s->initialized = 1;
s->exit = 0;

View File

@ -301,6 +301,37 @@
'*out': 'AudiodevPaPerDirectionOptions',
'*server': 'str' } }
##
# @AudiodevSdlPerDirectionOptions:
#
# Options of the SDL audio backend that are used for both playback and
# recording.
#
# @buffer-count: number of buffers (default 4)
#
# Since: 6.0
##
{ 'struct': 'AudiodevSdlPerDirectionOptions',
'base': 'AudiodevPerDirectionOptions',
'data': {
'*buffer-count': 'uint32' } }
##
# @AudiodevSdlOptions:
#
# Options of the SDL audio backend.
#
# @in: options of the recording stream
#
# @out: options of the playback stream
#
# Since: 6.0
##
{ 'struct': 'AudiodevSdlOptions',
'data': {
'*in': 'AudiodevSdlPerDirectionOptions',
'*out': 'AudiodevSdlPerDirectionOptions' } }
##
# @AudiodevWavOptions:
#
@ -385,6 +416,6 @@
'jack': 'AudiodevJackOptions',
'oss': 'AudiodevOssOptions',
'pa': 'AudiodevPaOptions',
'sdl': 'AudiodevGenericOptions',
'sdl': 'AudiodevSdlOptions',
'spice': 'AudiodevGenericOptions',
'wav': 'AudiodevWavOptions' } }

View File

@ -588,6 +588,7 @@ DEF("audiodev", HAS_ARG, QEMU_OPTION_audiodev,
#endif
#ifdef CONFIG_AUDIO_SDL
"-audiodev sdl,id=id[,prop[=value][,...]]\n"
" in|out.buffer-count= number of buffers\n"
#endif
#ifdef CONFIG_SPICE
"-audiodev spice,id=id[,prop[=value][,...]]\n"
@ -745,7 +746,12 @@ SRST
``-audiodev sdl,id=id[,prop[=value][,...]]``
Creates a backend using SDL. This backend is available on most
systems, but you should use your platform's native backend if
possible. This backend has no backend specific properties.
possible.
SDL specific options are:
``in|out.buffer-count=count``
Sets the count of the buffers.
``-audiodev spice,id=id[,prop[=value][,...]]``
Creates a backend that sends audio through SPICE. This backend