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>
This commit is contained in:
commit
21ee7686d7
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
186
audio/sdlaudio.c
186
audio/sdlaudio.c
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user