audio: reduce glob_audio_state usage

Remove glob_audio_state from functions, where possible without breaking
the API.  This means that most static functions in audio.c now take an
AudioState pointer instead of implicitly using glob_audio_state.  Also
included a pointer in SWVoice*, HWVoice* structs, so that functions
dealing them can know the audio state without having to pass it around
separately.

This is required in order to support multiple simultaneous audio
backends (added in a later commit).

Signed-off-by: Kővágó, Zoltán <DirtY.iCE.hu@gmail.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-id: b5e241f24e795267b145bcde7c6a72dd5e6037ea.1566168923.git.DirtY.iCE.hu@gmail.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
This commit is contained in:
Kővágó, Zoltán 2019-08-19 01:06:46 +02:00 committed by Gerd Hoffmann
parent e463494145
commit 526fb0581e
3 changed files with 57 additions and 56 deletions

View File

@ -401,12 +401,10 @@ static void noop_conv (struct st_sample *dst, const void *src, int samples)
(void) samples; (void) samples;
} }
static CaptureVoiceOut *audio_pcm_capture_find_specific ( static CaptureVoiceOut *audio_pcm_capture_find_specific(AudioState *s,
struct audsettings *as struct audsettings *as)
)
{ {
CaptureVoiceOut *cap; CaptureVoiceOut *cap;
AudioState *s = &glob_audio_state;
for (cap = s->cap_head.lh_first; cap; cap = cap->entries.le_next) { for (cap = s->cap_head.lh_first; cap; cap = cap->entries.le_next) {
if (audio_pcm_info_eq (&cap->hw.info, as)) { if (audio_pcm_info_eq (&cap->hw.info, as)) {
@ -483,7 +481,7 @@ static void audio_detach_capture (HWVoiceOut *hw)
static int audio_attach_capture (HWVoiceOut *hw) static int audio_attach_capture (HWVoiceOut *hw)
{ {
AudioState *s = &glob_audio_state; AudioState *s = hw->s;
CaptureVoiceOut *cap; CaptureVoiceOut *cap;
audio_detach_capture (hw); audio_detach_capture (hw);
@ -791,19 +789,15 @@ static void audio_pcm_print_info (const char *cap, struct audio_pcm_info *info)
/* /*
* Timer * Timer
*/ */
static int audio_is_timer_needed(AudioState *s)
static bool audio_timer_running;
static uint64_t audio_timer_last;
static int audio_is_timer_needed (void)
{ {
HWVoiceIn *hwi = NULL; HWVoiceIn *hwi = NULL;
HWVoiceOut *hwo = NULL; HWVoiceOut *hwo = NULL;
while ((hwo = audio_pcm_hw_find_any_enabled_out (hwo))) { while ((hwo = audio_pcm_hw_find_any_enabled_out(s, hwo))) {
if (!hwo->poll_mode) return 1; if (!hwo->poll_mode) return 1;
} }
while ((hwi = audio_pcm_hw_find_any_enabled_in (hwi))) { while ((hwi = audio_pcm_hw_find_any_enabled_in(s, hwi))) {
if (!hwi->poll_mode) return 1; if (!hwi->poll_mode) return 1;
} }
return 0; return 0;
@ -811,18 +805,18 @@ static int audio_is_timer_needed (void)
static void audio_reset_timer (AudioState *s) static void audio_reset_timer (AudioState *s)
{ {
if (audio_is_timer_needed ()) { if (audio_is_timer_needed(s)) {
timer_mod_anticipate_ns(s->ts, timer_mod_anticipate_ns(s->ts,
qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + s->period_ticks); qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + s->period_ticks);
if (!audio_timer_running) { if (!s->timer_running) {
audio_timer_running = true; s->timer_running = true;
audio_timer_last = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); s->timer_last = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
trace_audio_timer_start(s->period_ticks / SCALE_MS); trace_audio_timer_start(s->period_ticks / SCALE_MS);
} }
} else { } else {
timer_del(s->ts); timer_del(s->ts);
if (audio_timer_running) { if (s->timer_running) {
audio_timer_running = false; s->timer_running = false;
trace_audio_timer_stop(); trace_audio_timer_stop();
} }
} }
@ -834,11 +828,11 @@ static void audio_timer (void *opaque)
AudioState *s = opaque; AudioState *s = opaque;
now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
diff = now - audio_timer_last; diff = now - s->timer_last;
if (diff > s->period_ticks * 3 / 2) { if (diff > s->period_ticks * 3 / 2) {
trace_audio_timer_delayed(diff / SCALE_MS); trace_audio_timer_delayed(diff / SCALE_MS);
} }
audio_timer_last = now; s->timer_last = now;
audio_run("timer"); audio_run("timer");
audio_reset_timer(s); audio_reset_timer(s);
@ -892,7 +886,7 @@ void AUD_set_active_out (SWVoiceOut *sw, int on)
hw = sw->hw; hw = sw->hw;
if (sw->active != on) { if (sw->active != on) {
AudioState *s = &glob_audio_state; AudioState *s = sw->s;
SWVoiceOut *temp_sw; SWVoiceOut *temp_sw;
SWVoiceCap *sc; SWVoiceCap *sc;
@ -939,7 +933,7 @@ void AUD_set_active_in (SWVoiceIn *sw, int on)
hw = sw->hw; hw = sw->hw;
if (sw->active != on) { if (sw->active != on) {
AudioState *s = &glob_audio_state; AudioState *s = sw->s;
SWVoiceIn *temp_sw; SWVoiceIn *temp_sw;
if (on) { if (on) {
@ -1062,7 +1056,7 @@ static void audio_run_out (AudioState *s)
HWVoiceOut *hw = NULL; HWVoiceOut *hw = NULL;
SWVoiceOut *sw; SWVoiceOut *sw;
while ((hw = audio_pcm_hw_find_any_enabled_out (hw))) { while ((hw = audio_pcm_hw_find_any_enabled_out(s, hw))) {
int played; int played;
int live, free, nb_live, cleanup_required, prev_rpos; int live, free, nb_live, cleanup_required, prev_rpos;
@ -1167,7 +1161,7 @@ static void audio_run_in (AudioState *s)
{ {
HWVoiceIn *hw = NULL; HWVoiceIn *hw = NULL;
while ((hw = audio_pcm_hw_find_any_enabled_in (hw))) { while ((hw = audio_pcm_hw_find_any_enabled_in(s, hw))) {
SWVoiceIn *sw; SWVoiceIn *sw;
int captured = 0, min; int captured = 0, min;
@ -1273,8 +1267,8 @@ static int audio_driver_init(AudioState *s, struct audio_driver *drv,
s->drv_opaque = drv->init(dev); s->drv_opaque = drv->init(dev);
if (s->drv_opaque) { if (s->drv_opaque) {
audio_init_nb_voices_out (drv); audio_init_nb_voices_out(s, drv);
audio_init_nb_voices_in (drv); audio_init_nb_voices_in(s, drv);
s->drv = drv; s->drv = drv;
return 0; return 0;
} }
@ -1295,11 +1289,11 @@ static void audio_vm_change_state_handler (void *opaque, int running,
int op = running ? VOICE_ENABLE : VOICE_DISABLE; int op = running ? VOICE_ENABLE : VOICE_DISABLE;
s->vm_running = running; s->vm_running = running;
while ((hwo = audio_pcm_hw_find_any_enabled_out (hwo))) { while ((hwo = audio_pcm_hw_find_any_enabled_out(s, hwo))) {
hwo->pcm_ops->ctl_out(hwo, op); hwo->pcm_ops->ctl_out(hwo, op);
} }
while ((hwi = audio_pcm_hw_find_any_enabled_in (hwi))) { while ((hwi = audio_pcm_hw_find_any_enabled_in(s, hwi))) {
hwi->pcm_ops->ctl_in(hwi, op); hwi->pcm_ops->ctl_in(hwi, op);
} }
audio_reset_timer (s); audio_reset_timer (s);
@ -1319,7 +1313,7 @@ void audio_cleanup(void)
HWVoiceIn *hwi, *hwin; HWVoiceIn *hwi, *hwin;
is_cleaning_up = true; is_cleaning_up = true;
QLIST_FOREACH_SAFE(hwo, &glob_audio_state.hw_head_out, entries, hwon) { QLIST_FOREACH_SAFE(hwo, &s->hw_head_out, entries, hwon) {
SWVoiceCap *sc; SWVoiceCap *sc;
if (hwo->enabled) { if (hwo->enabled) {
@ -1338,7 +1332,7 @@ void audio_cleanup(void)
QLIST_REMOVE(hwo, entries); QLIST_REMOVE(hwo, entries);
} }
QLIST_FOREACH_SAFE(hwi, &glob_audio_state.hw_head_in, entries, hwin) { QLIST_FOREACH_SAFE(hwi, &s->hw_head_in, entries, hwin) {
if (hwi->enabled) { if (hwi->enabled) {
hwi->pcm_ops->ctl_in (hwi, VOICE_DISABLE); hwi->pcm_ops->ctl_in (hwi, VOICE_DISABLE);
} }
@ -1534,7 +1528,7 @@ CaptureVoiceOut *AUD_add_capture (
cb->ops = *ops; cb->ops = *ops;
cb->opaque = cb_opaque; cb->opaque = cb_opaque;
cap = audio_pcm_capture_find_specific (as); cap = audio_pcm_capture_find_specific(s, as);
if (cap) { if (cap) {
QLIST_INSERT_HEAD (&cap->cb_head, cb, entries); QLIST_INSERT_HEAD (&cap->cb_head, cb, entries);
return cap; return cap;
@ -1546,6 +1540,7 @@ CaptureVoiceOut *AUD_add_capture (
cap = g_malloc0(sizeof(*cap)); cap = g_malloc0(sizeof(*cap));
hw = &cap->hw; hw = &cap->hw;
hw->s = s;
QLIST_INIT (&hw->sw_head); QLIST_INIT (&hw->sw_head);
QLIST_INIT (&cap->cb_head); QLIST_INIT (&cap->cb_head);
@ -1566,7 +1561,7 @@ CaptureVoiceOut *AUD_add_capture (
QLIST_INSERT_HEAD (&s->cap_head, cap, entries); QLIST_INSERT_HEAD (&s->cap_head, cap, entries);
QLIST_INSERT_HEAD (&cap->cb_head, cb, entries); QLIST_INSERT_HEAD (&cap->cb_head, cb, entries);
QLIST_FOREACH(hw, &glob_audio_state.hw_head_out, entries) { QLIST_FOREACH(hw, &s->hw_head_out, entries) {
audio_attach_capture (hw); audio_attach_capture (hw);
} }
return cap; return cap;

View File

@ -49,9 +49,11 @@ struct audio_pcm_info {
int swap_endianness; int swap_endianness;
}; };
typedef struct AudioState AudioState;
typedef struct SWVoiceCap SWVoiceCap; typedef struct SWVoiceCap SWVoiceCap;
typedef struct HWVoiceOut { typedef struct HWVoiceOut {
AudioState *s;
int enabled; int enabled;
int poll_mode; int poll_mode;
int pending_disable; int pending_disable;
@ -73,6 +75,7 @@ typedef struct HWVoiceOut {
} HWVoiceOut; } HWVoiceOut;
typedef struct HWVoiceIn { typedef struct HWVoiceIn {
AudioState *s;
int enabled; int enabled;
int poll_mode; int poll_mode;
struct audio_pcm_info info; struct audio_pcm_info info;
@ -94,6 +97,7 @@ typedef struct HWVoiceIn {
struct SWVoiceOut { struct SWVoiceOut {
QEMUSoundCard *card; QEMUSoundCard *card;
AudioState *s;
struct audio_pcm_info info; struct audio_pcm_info info;
t_sample *conv; t_sample *conv;
int64_t ratio; int64_t ratio;
@ -111,6 +115,7 @@ struct SWVoiceOut {
struct SWVoiceIn { struct SWVoiceIn {
QEMUSoundCard *card; QEMUSoundCard *card;
AudioState *s;
int active; int active;
struct audio_pcm_info info; struct audio_pcm_info info;
int64_t ratio; int64_t ratio;
@ -188,6 +193,9 @@ typedef struct AudioState {
int nb_hw_voices_in; int nb_hw_voices_in;
int vm_running; int vm_running;
int64_t period_ticks; int64_t period_ticks;
bool timer_running;
uint64_t timer_last;
} AudioState; } AudioState;
extern const struct mixeng_volume nominal_volume; extern const struct mixeng_volume nominal_volume;

View File

@ -36,9 +36,9 @@
#define HWBUF hw->conv_buf #define HWBUF hw->conv_buf
#endif #endif
static void glue (audio_init_nb_voices_, TYPE) (struct audio_driver *drv) static void glue(audio_init_nb_voices_, TYPE)(AudioState *s,
struct audio_driver *drv)
{ {
AudioState *s = &glob_audio_state;
int max_voices = glue (drv->max_voices_, TYPE); int max_voices = glue (drv->max_voices_, TYPE);
int voice_size = glue (drv->voice_size_, TYPE); int voice_size = glue (drv->voice_size_, TYPE);
@ -183,8 +183,8 @@ static void glue (audio_pcm_hw_del_sw_, TYPE) (SW *sw)
static void glue (audio_pcm_hw_gc_, TYPE) (HW **hwp) static void glue (audio_pcm_hw_gc_, TYPE) (HW **hwp)
{ {
AudioState *s = &glob_audio_state;
HW *hw = *hwp; HW *hw = *hwp;
AudioState *s = hw->s;
if (!hw->sw_head.lh_first) { if (!hw->sw_head.lh_first) {
#ifdef DAC #ifdef DAC
@ -199,15 +199,14 @@ static void glue (audio_pcm_hw_gc_, TYPE) (HW **hwp)
} }
} }
static HW *glue (audio_pcm_hw_find_any_, TYPE) (HW *hw) static HW *glue(audio_pcm_hw_find_any_, TYPE)(AudioState *s, HW *hw)
{ {
AudioState *s = &glob_audio_state;
return hw ? hw->entries.le_next : glue (s->hw_head_, TYPE).lh_first; return hw ? hw->entries.le_next : glue (s->hw_head_, TYPE).lh_first;
} }
static HW *glue (audio_pcm_hw_find_any_enabled_, TYPE) (HW *hw) static HW *glue(audio_pcm_hw_find_any_enabled_, TYPE)(AudioState *s, HW *hw)
{ {
while ((hw = glue (audio_pcm_hw_find_any_, TYPE) (hw))) { while ((hw = glue(audio_pcm_hw_find_any_, TYPE)(s, hw))) {
if (hw->enabled) { if (hw->enabled) {
return hw; return hw;
} }
@ -215,12 +214,10 @@ static HW *glue (audio_pcm_hw_find_any_enabled_, TYPE) (HW *hw)
return NULL; return NULL;
} }
static HW *glue (audio_pcm_hw_find_specific_, TYPE) ( static HW *glue(audio_pcm_hw_find_specific_, TYPE)(AudioState *s, HW *hw,
HW *hw, struct audsettings *as)
struct audsettings *as
)
{ {
while ((hw = glue (audio_pcm_hw_find_any_, TYPE) (hw))) { while ((hw = glue(audio_pcm_hw_find_any_, TYPE)(s, hw))) {
if (audio_pcm_info_eq (&hw->info, as)) { if (audio_pcm_info_eq (&hw->info, as)) {
return hw; return hw;
} }
@ -228,10 +225,10 @@ static HW *glue (audio_pcm_hw_find_specific_, TYPE) (
return NULL; return NULL;
} }
static HW *glue (audio_pcm_hw_add_new_, TYPE) (struct audsettings *as) static HW *glue(audio_pcm_hw_add_new_, TYPE)(AudioState *s,
struct audsettings *as)
{ {
HW *hw; HW *hw;
AudioState *s = &glob_audio_state;
struct audio_driver *drv = s->drv; struct audio_driver *drv = s->drv;
if (!glue (s->nb_hw_voices_, TYPE)) { if (!glue (s->nb_hw_voices_, TYPE)) {
@ -255,6 +252,7 @@ static HW *glue (audio_pcm_hw_add_new_, TYPE) (struct audsettings *as)
return NULL; return NULL;
} }
hw->s = s;
hw->pcm_ops = drv->pcm_ops; hw->pcm_ops = drv->pcm_ops;
hw->ctl_caps = drv->ctl_caps; hw->ctl_caps = drv->ctl_caps;
@ -328,33 +326,33 @@ AudiodevPerDirectionOptions *glue(audio_get_pdo_, TYPE)(Audiodev *dev)
abort(); abort();
} }
static HW *glue (audio_pcm_hw_add_, TYPE) (struct audsettings *as) static HW *glue(audio_pcm_hw_add_, TYPE)(AudioState *s, struct audsettings *as)
{ {
HW *hw; HW *hw;
AudioState *s = &glob_audio_state;
AudiodevPerDirectionOptions *pdo = glue(audio_get_pdo_, TYPE)(s->dev); AudiodevPerDirectionOptions *pdo = glue(audio_get_pdo_, TYPE)(s->dev);
if (pdo->fixed_settings) { if (pdo->fixed_settings) {
hw = glue (audio_pcm_hw_add_new_, TYPE) (as); hw = glue(audio_pcm_hw_add_new_, TYPE)(s, as);
if (hw) { if (hw) {
return hw; return hw;
} }
} }
hw = glue (audio_pcm_hw_find_specific_, TYPE) (NULL, as); hw = glue(audio_pcm_hw_find_specific_, TYPE)(s, NULL, as);
if (hw) { if (hw) {
return hw; return hw;
} }
hw = glue (audio_pcm_hw_add_new_, TYPE) (as); hw = glue(audio_pcm_hw_add_new_, TYPE)(s, as);
if (hw) { if (hw) {
return hw; return hw;
} }
return glue (audio_pcm_hw_find_any_, TYPE) (NULL); return glue(audio_pcm_hw_find_any_, TYPE)(s, NULL);
} }
static SW *glue(audio_pcm_create_voice_pair_, TYPE)( static SW *glue(audio_pcm_create_voice_pair_, TYPE)(
AudioState *s,
const char *sw_name, const char *sw_name,
struct audsettings *as struct audsettings *as
) )
@ -362,7 +360,6 @@ static SW *glue (audio_pcm_create_voice_pair_, TYPE) (
SW *sw; SW *sw;
HW *hw; HW *hw;
struct audsettings hw_as; struct audsettings hw_as;
AudioState *s = &glob_audio_state;
AudiodevPerDirectionOptions *pdo = glue(audio_get_pdo_, TYPE)(s->dev); AudiodevPerDirectionOptions *pdo = glue(audio_get_pdo_, TYPE)(s->dev);
if (pdo->fixed_settings) { if (pdo->fixed_settings) {
@ -378,8 +375,9 @@ static SW *glue (audio_pcm_create_voice_pair_, TYPE) (
sw_name ? sw_name : "unknown", sizeof (*sw)); sw_name ? sw_name : "unknown", sizeof (*sw));
goto err1; goto err1;
} }
sw->s = s;
hw = glue (audio_pcm_hw_add_, TYPE) (&hw_as); hw = glue(audio_pcm_hw_add_, TYPE)(s, &hw_as);
if (!hw) { if (!hw) {
goto err2; goto err2;
} }
@ -476,7 +474,7 @@ SW *glue (AUD_open_, TYPE) (
} }
} }
else { else {
sw = glue (audio_pcm_create_voice_pair_, TYPE) (name, as); sw = glue(audio_pcm_create_voice_pair_, TYPE)(s, name, as);
if (!sw) { if (!sw) {
dolog ("Failed to create voice `%s'\n", name); dolog ("Failed to create voice `%s'\n", name);
return NULL; return NULL;