audio: fixes and cleanups.

-----BEGIN PGP SIGNATURE-----
 Version: GnuPG v2.0.22 (GNU/Linux)
 
 iQIcBAABAgAGBQJcd7MsAAoJEEy22O7T6HE4vsQQAIWS7+gx/zaxoMwoZ0BcPA7T
 TaoROz911srx9XUgQkbZHrYL7k5MSbcU2muwB/S8fGP3KodEZKzDWp7sjewi0yB+
 v8emLhfKVy7aWVIiyyLuSvd0nA0Z38ovNuwOFdAOw4Yd496bhDpKp7qIV9oS7qUB
 xBH46U0mtMVMeCeTH+1CrT+/5ETPNvO0D51VN3Fs+8HL+rYenb8OzTAcxyTANFbb
 CrYf7O/ilEflf0S67yotuPkKILvmOhK9VIC+8keThsPBneUr/KbqvpBKivgGDJy+
 YBa5xhzraysLTNwLL+sLnRPprSsltUYf4GcI+WKiRr92KdCgDomFW/abPQDJtAZ9
 TgsZFBzZ+/FkUz0FtNpfI4anFAQDyfA1qVtpkk1uUMfZCcxaBaPcu8NzHIl62HfE
 l7Mr2AQAm5NqGXEdy4Xu4ZMqkIj3T0JOx5sULyfVgMZIwLSrjjRNB/GwGV23ZTPv
 NfXIPIwxANG2T9SRhPgmCZtQXY7qNlLR97I87ZgKQ7dzod1J4O0Tk+qt0wpHt6o3
 kpOgehtWZRFNGuT1zA6fVUJX942Rcps2lKvY+7hv47HhUgoTl7c0uRnBtcZgerD2
 wOldGeRuS67iy7Pjj2/Ih8lV8Brprb54t7CFrZ259uUlYKJQV4zd9tDdpNLN+bTT
 7UXq+vM3er0Rfw7LvAzz
 =RC1S
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/kraxel/tags/audio-20190228-pull-request' into staging

audio: fixes and cleanups.

# gpg: Signature made Thu 28 Feb 2019 10:08:44 GMT
# gpg:                using RSA key 4CB6D8EED3E87138
# gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>" [full]
# gpg:                 aka "Gerd Hoffmann <gerd@kraxel.org>" [full]
# gpg:                 aka "Gerd Hoffmann (private) <kraxel@gmail.com>" [full]
# Primary key fingerprint: A032 8CFF B93A 17A7 9901  FE7D 4CB6 D8EE D3E8 7138

* remotes/kraxel/tags/audio-20190228-pull-request:
  audio/sdlaudio: Simplify the sdl_callback function
  audio/sdlaudio: Remove the semaphore code
  audio: don't build alsa and sdl by default on linux
  audio: Do not check for audio_calloc failure
  audio: Use g_strdup_printf instead of manual building a string

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
master
Peter Maydell 2019-02-28 16:11:18 +00:00
commit 21ee7686d7
3 changed files with 34 additions and 227 deletions

View File

@ -454,9 +454,7 @@ static void audio_print_options (const char *prefix,
static void audio_process_options (const char *prefix,
struct audio_option *opt)
{
char *optname;
const char qemu_prefix[] = "QEMU_";
size_t preflen, optlen;
gchar *prefix_upper;
if (audio_bug(__func__, !prefix)) {
dolog ("prefix = NULL\n");
@ -468,10 +466,10 @@ static void audio_process_options (const char *prefix,
return;
}
preflen = strlen (prefix);
prefix_upper = g_utf8_strup(prefix, -1);
for (; opt->name; opt++) {
size_t len, i;
char *optname;
int def;
if (!opt->valp) {
@ -480,21 +478,7 @@ static void audio_process_options (const char *prefix,
continue;
}
len = strlen (opt->name);
/* len of opt->name + len of prefix + size of qemu_prefix
* (includes trailing zero) + zero + underscore (on behalf of
* sizeof) */
optlen = len + preflen + sizeof (qemu_prefix) + 1;
optname = g_malloc (optlen);
pstrcpy (optname, optlen, qemu_prefix);
/* copy while upper-casing, including trailing zero */
for (i = 0; i <= preflen; ++i) {
optname[i + sizeof (qemu_prefix) - 1] = qemu_toupper(prefix[i]);
}
pstrcat (optname, optlen, "_");
pstrcat (optname, optlen, opt->name);
optname = g_strdup_printf("QEMU_%s_%s", prefix_upper, opt->name);
def = 1;
switch (opt->tag) {
@ -532,6 +516,7 @@ static void audio_process_options (const char *prefix,
*opt->overriddenp = !def;
g_free (optname);
}
g_free(prefix_upper);
}
static void audio_print_settings (struct audsettings *as)
@ -826,12 +811,7 @@ static int audio_attach_capture (HWVoiceOut *hw)
SWVoiceOut *sw;
HWVoiceOut *hw_cap = &cap->hw;
sc = audio_calloc(__func__, 1, sizeof(*sc));
if (!sc) {
dolog ("Could not allocate soft capture voice (%zu bytes)\n",
sizeof (*sc));
return -1;
}
sc = g_malloc0(sizeof(*sc));
sc->cap = cap;
sw = &sc->sw;
@ -1975,15 +1955,10 @@ CaptureVoiceOut *AUD_add_capture (
if (audio_validate_settings (as)) {
dolog ("Invalid settings were passed when trying to add capture\n");
audio_print_settings (as);
goto err0;
return NULL;
}
cb = audio_calloc(__func__, 1, sizeof(*cb));
if (!cb) {
dolog ("Could not allocate capture callback information, size %zu\n",
sizeof (*cb));
goto err0;
}
cb = g_malloc0(sizeof(*cb));
cb->ops = *ops;
cb->opaque = cb_opaque;
@ -1996,12 +1971,7 @@ CaptureVoiceOut *AUD_add_capture (
HWVoiceOut *hw;
CaptureVoiceOut *cap;
cap = audio_calloc(__func__, 1, sizeof(*cap));
if (!cap) {
dolog ("Could not allocate capture voice, size %zu\n",
sizeof (*cap));
goto err1;
}
cap = g_malloc0(sizeof(*cap));
hw = &cap->hw;
QLIST_INIT (&hw->sw_head);
@ -2009,23 +1979,11 @@ CaptureVoiceOut *AUD_add_capture (
/* XXX find a more elegant way */
hw->samples = 4096 * 4;
hw->mix_buf = audio_calloc(__func__, hw->samples,
sizeof(struct st_sample));
if (!hw->mix_buf) {
dolog ("Could not allocate capture mix buffer (%d samples)\n",
hw->samples);
goto err2;
}
hw->mix_buf = g_new0(struct st_sample, hw->samples);
audio_pcm_init_info (&hw->info, as);
cap->buf = audio_calloc(__func__, hw->samples, 1 << hw->info.shift);
if (!cap->buf) {
dolog ("Could not allocate capture buffer "
"(%d samples, each %d bytes)\n",
hw->samples, 1 << hw->info.shift);
goto err3;
}
cap->buf = g_malloc0_n(hw->samples, 1 << hw->info.shift);
hw->clip = mixeng_clip
[hw->info.nchannels == 2]
@ -2040,15 +1998,6 @@ CaptureVoiceOut *AUD_add_capture (
audio_attach_capture (hw);
}
return cap;
err3:
g_free (cap->hw.mix_buf);
err2:
g_free (cap);
err1:
g_free (cb);
err0:
return NULL;
}
}

View File

@ -38,14 +38,9 @@
#define AUDIO_CAP "sdl"
#include "audio_int.h"
#define USE_SEMAPHORE (SDL_MAJOR_VERSION < 2)
typedef struct SDLVoiceOut {
HWVoiceOut hw;
int live;
#if USE_SEMAPHORE
int rpos;
#endif
int decr;
} SDLVoiceOut;
@ -57,10 +52,6 @@ static struct {
static struct SDLAudioState {
int exit;
#if USE_SEMAPHORE
SDL_mutex *mutex;
SDL_sem *sem;
#endif
int initialized;
bool driver_created;
} glob_sdl;
@ -77,66 +68,6 @@ static void GCC_FMT_ATTR (1, 2) sdl_logerr (const char *fmt, ...)
AUD_log (AUDIO_CAP, "Reason: %s\n", SDL_GetError ());
}
static int sdl_lock (SDLAudioState *s, const char *forfn)
{
#if USE_SEMAPHORE
if (SDL_LockMutex (s->mutex)) {
sdl_logerr ("SDL_LockMutex for %s failed\n", forfn);
return -1;
}
#else
SDL_LockAudio();
#endif
return 0;
}
static int sdl_unlock (SDLAudioState *s, const char *forfn)
{
#if USE_SEMAPHORE
if (SDL_UnlockMutex (s->mutex)) {
sdl_logerr ("SDL_UnlockMutex for %s failed\n", forfn);
return -1;
}
#else
SDL_UnlockAudio();
#endif
return 0;
}
static int sdl_post (SDLAudioState *s, const char *forfn)
{
#if USE_SEMAPHORE
if (SDL_SemPost (s->sem)) {
sdl_logerr ("SDL_SemPost for %s failed\n", forfn);
return -1;
}
#endif
return 0;
}
#if USE_SEMAPHORE
static int sdl_wait (SDLAudioState *s, const char *forfn)
{
if (SDL_SemWait (s->sem)) {
sdl_logerr ("SDL_SemWait for %s failed\n", forfn);
return -1;
}
return 0;
}
#endif
static int sdl_unlock_and_post (SDLAudioState *s, const char *forfn)
{
if (sdl_unlock (s, forfn)) {
return -1;
}
return sdl_post (s, forfn);
}
static int aud_to_sdlfmt (audfmt_e fmt)
{
switch (fmt) {
@ -243,9 +174,9 @@ static int sdl_open (SDL_AudioSpec *req, SDL_AudioSpec *obt)
static void sdl_close (SDLAudioState *s)
{
if (s->initialized) {
sdl_lock (s, "sdl_close");
SDL_LockAudio();
s->exit = 1;
sdl_unlock_and_post (s, "sdl_close");
SDL_UnlockAudio();
SDL_PauseAudio (1);
SDL_CloseAudio ();
s->initialized = 0;
@ -258,76 +189,36 @@ static void sdl_callback (void *opaque, Uint8 *buf, int len)
SDLAudioState *s = &glob_sdl;
HWVoiceOut *hw = &sdl->hw;
int samples = len >> hw->info.shift;
int to_mix, decr;
if (s->exit) {
if (s->exit || !sdl->live) {
return;
}
while (samples) {
int to_mix, decr;
/* dolog ("in callback samples=%d live=%d\n", samples, sdl->live); */
/* dolog ("in callback samples=%d\n", samples); */
#if USE_SEMAPHORE
sdl_wait (s, "sdl_callback");
if (s->exit) {
return;
}
to_mix = audio_MIN(samples, sdl->live);
decr = to_mix;
while (to_mix) {
int chunk = audio_MIN(to_mix, hw->samples - hw->rpos);
struct st_sample *src = hw->mix_buf + hw->rpos;
if (sdl_lock (s, "sdl_callback")) {
return;
}
if (audio_bug(__func__, sdl->live < 0 || sdl->live > hw->samples)) {
dolog ("sdl->live=%d hw->samples=%d\n",
sdl->live, hw->samples);
return;
}
if (!sdl->live) {
goto again;
}
#else
if (s->exit || !sdl->live) {
break;
}
#endif
/* dolog ("in callback live=%d\n", live); */
to_mix = audio_MIN (samples, sdl->live);
decr = to_mix;
while (to_mix) {
int chunk = audio_MIN (to_mix, hw->samples - hw->rpos);
struct st_sample *src = hw->mix_buf + hw->rpos;
/* dolog ("in callback to_mix %d, chunk %d\n", to_mix, chunk); */
hw->clip (buf, src, chunk);
#if USE_SEMAPHORE
sdl->rpos = (sdl->rpos + chunk) % hw->samples;
#else
hw->rpos = (hw->rpos + chunk) % hw->samples;
#endif
to_mix -= chunk;
buf += chunk << hw->info.shift;
}
samples -= decr;
sdl->live -= decr;
sdl->decr += decr;
#if USE_SEMAPHORE
again:
if (sdl_unlock (s, "sdl_callback")) {
return;
}
#endif
/* dolog ("in callback to_mix %d, chunk %d\n", to_mix, chunk); */
hw->clip(buf, src, chunk);
hw->rpos = (hw->rpos + chunk) % hw->samples;
to_mix -= chunk;
buf += chunk << hw->info.shift;
}
samples -= decr;
sdl->live -= decr;
sdl->decr += decr;
/* dolog ("done len=%d\n", len); */
#if (SDL_MAJOR_VERSION >= 2)
/* SDL2 does not clear the remaining buffer for us, so do it on our own */
if (samples) {
memset(buf, 0, samples << hw->info.shift);
}
#endif
}
static int sdl_write_out (SWVoiceOut *sw, void *buf, int len)
@ -339,11 +230,8 @@ static int sdl_run_out (HWVoiceOut *hw, int live)
{
int decr;
SDLVoiceOut *sdl = (SDLVoiceOut *) hw;
SDLAudioState *s = &glob_sdl;
if (sdl_lock (s, "sdl_run_out")) {
return 0;
}
SDL_LockAudio();
if (sdl->decr > live) {
ldebug ("sdl->decr %d live %d sdl->live %d\n",
@ -355,19 +243,10 @@ static int sdl_run_out (HWVoiceOut *hw, int live)
decr = audio_MIN (sdl->decr, live);
sdl->decr -= decr;
#if USE_SEMAPHORE
sdl->live = live - decr;
hw->rpos = sdl->rpos;
#else
sdl->live = live;
#endif
if (sdl->live > 0) {
sdl_unlock_and_post (s, "sdl_run_out");
}
else {
sdl_unlock (s, "sdl_run_out");
}
SDL_UnlockAudio();
return decr;
}
@ -449,23 +328,6 @@ static void *sdl_audio_init (void)
return NULL;
}
#if USE_SEMAPHORE
s->mutex = SDL_CreateMutex ();
if (!s->mutex) {
sdl_logerr ("Failed to create SDL mutex\n");
SDL_QuitSubSystem (SDL_INIT_AUDIO);
return NULL;
}
s->sem = SDL_CreateSemaphore (0);
if (!s->sem) {
sdl_logerr ("Failed to create SDL semaphore\n");
SDL_DestroyMutex (s->mutex);
SDL_QuitSubSystem (SDL_INIT_AUDIO);
return NULL;
}
#endif
s->driver_created = true;
return s;
}
@ -474,10 +336,6 @@ static void sdl_audio_fini (void *opaque)
{
SDLAudioState *s = opaque;
sdl_close (s);
#if USE_SEMAPHORE
SDL_DestroySemaphore (s->sem);
SDL_DestroyMutex (s->mutex);
#endif
SDL_QuitSubSystem (SDL_INIT_AUDIO);
s->driver_created = false;
}

2
configure vendored
View File

@ -879,7 +879,7 @@ Haiku)
LIBS="-lposix_error_mapper -lnetwork $LIBS"
;;
Linux)
audio_drv_list="try-pa try-alsa try-sdl oss"
audio_drv_list="try-pa oss"
audio_possible_drivers="oss alsa sdl pa"
linux="yes"
linux_user="yes"