Merge tag 'audio-test-pull-request' of https://gitlab.com/marcandre.lureau/qemu into staging

Audio clean-ups

# -----BEGIN PGP SIGNATURE-----
#
# iQJQBAABCgA6FiEEh6m9kz+HxgbSdvYt2ujhCXWWnOUFAmkEWqwcHG1hcmNhbmRy
# ZS5sdXJlYXVAcmVkaGF0LmNvbQAKCRDa6OEJdZac5a4RD/49KcP8h/5+QT3nu703
# OL/c/+M0DEZCVikzbj1T+nZNlUZtto/wE1vY0/xxzoyMh/4XbUFI0b/YK8WcQyUx
# ozrWOCi6TquS1QpR62FBmDJ6QDA2KteTF8Zq/owdFj+l7VJ5F5mzcuuFCxLx1EVH
# 7qOIf37Vk4r8jz42CLRTusPGQZLSvS8LbTBP62guauXlVAKVWI8k9macRSqoTBRo
# VrQO3QC/JFSqkB2jGfes8AMU+RWLYPG3ICCf0UYHH/kMik/JEL+1arx7au7oukTb
# 3kp8cxGnuJzBKCvY8SLwQF3YiCotYQIjSkvAQrMYBXalPBjQIIh+vzegcF1D+xZb
# 6KR4kh3oXPHtVCG2AXcxA4IuAi50jYFPn6TgDkRrUAEhsOqOxLo5bmZsqWK7L3/u
# 61jLKSjLRSc+NjhwHN0YVy1ocdsLf2z1LQNHjC1TuxrgI//9fQnOE2gASb8tmJGg
# BlPYp5h6G50IEaACzlZEtudWpKRb/XyflWpHbWte0VUO9dpz/cUvO1P38CpPD1dr
# ohENb8eLn0L23M12tUABV0IoA729phBYh3Eua9uIzEVfuRVfoPCuocx6VxQked91
# SZr7X9G80Nyh5YYiMlrwpN8eDgPtKfW5JwI2wYME6clGLnf/catkqCl/qp4nQeG5
# LPZiFy5Krz+QuSq41DjcSWRD+g==
# =qTgA
# -----END PGP SIGNATURE-----
# gpg: Signature made Fri 31 Oct 2025 07:43:56 AM CET
# gpg:                using RSA key 87A9BD933F87C606D276F62DDAE8E10975969CE5
# gpg:                issuer "marcandre.lureau@redhat.com"
# gpg: Good signature from "Marc-André Lureau <marcandre.lureau@redhat.com>" [unknown]
# gpg:                 aka "Marc-André Lureau <marcandre.lureau@gmail.com>" [unknown]
# gpg: WARNING: The key's User ID is not certified with a trusted signature!
# gpg:          There is no indication that the signature belongs to the owner.
# Primary key fingerprint: 87A9 BD93 3F87 C606 D276  F62D DAE8 E109 7596 9CE5

* tag 'audio-test-pull-request' of https://gitlab.com/marcandre.lureau/qemu: (36 commits)
  audio: deprecate HMP audio commands
  audio: Rename @endianness argument as @big_endian for clarity
  audio: Remove pointless local variables
  audio: drop needless audio_driver "descr" field
  audio: move capture API to own header
  audio: cleanup, use bool for booleans
  audio: remove dependency on spice header
  audio: move audio.h under include/qemu/
  audio/dbus: use a helper function to set the backend dbus server
  audio: remove QEMUSoundCard
  audio: rename AudioState -> AudioBackend
  audio: move internal APIs to audio_int.h
  audio/replay: fix type punning
  audio: introduce AUD_set_volume_{in,out}_lr()
  audio: remove AUDIO_HOST_ENDIANNESS
  audio: remove some needless headers
  audio: initialize card_head during object init
  audio: register and unregister vmstate with AudioState
  audio: keep vmstate handle with AudioState
  audio: drop needless error message
  ...

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
Richard Henderson
2025-11-01 10:51:32 +01:00
79 changed files with 903 additions and 958 deletions
+1
View File
@@ -2978,6 +2978,7 @@ X: audio/paaudio.c
X: audio/sdlaudio.c
X: audio/sndioaudio.c
X: audio/spiceaudio.c
F: include/qemu/audio*.h
F: qapi/audio.json
ALSA Audio backend
+8 -29
View File
@@ -26,7 +26,7 @@
#include <alsa/asoundlib.h>
#include "qemu/main-loop.h"
#include "qemu/module.h"
#include "audio.h"
#include "qemu/audio.h"
#include "trace.h"
#pragma GCC diagnostic ignored "-Waddress"
@@ -41,7 +41,7 @@ struct pollhlp {
struct pollfd *pfds;
int count;
int mask;
AudioState *s;
AudioBackend *s;
};
typedef struct ALSAVoiceOut {
@@ -264,7 +264,7 @@ static int alsa_poll_in (HWVoiceIn *hw)
return alsa_poll_helper (alsa->handle, &alsa->pollhlp, POLLIN);
}
static snd_pcm_format_t aud_to_alsafmt (AudioFormat fmt, int endianness)
static snd_pcm_format_t aud_to_alsafmt(AudioFormat fmt, bool big_endian)
{
switch (fmt) {
case AUDIO_FORMAT_S8:
@@ -274,39 +274,19 @@ static snd_pcm_format_t aud_to_alsafmt (AudioFormat fmt, int endianness)
return SND_PCM_FORMAT_U8;
case AUDIO_FORMAT_S16:
if (endianness) {
return SND_PCM_FORMAT_S16_BE;
} else {
return SND_PCM_FORMAT_S16_LE;
}
return big_endian ? SND_PCM_FORMAT_S16_BE : SND_PCM_FORMAT_S16_LE;
case AUDIO_FORMAT_U16:
if (endianness) {
return SND_PCM_FORMAT_U16_BE;
} else {
return SND_PCM_FORMAT_U16_LE;
}
return big_endian ? SND_PCM_FORMAT_U16_BE : SND_PCM_FORMAT_U16_LE;
case AUDIO_FORMAT_S32:
if (endianness) {
return SND_PCM_FORMAT_S32_BE;
} else {
return SND_PCM_FORMAT_S32_LE;
}
return big_endian ? SND_PCM_FORMAT_S32_BE : SND_PCM_FORMAT_S32_LE;
case AUDIO_FORMAT_U32:
if (endianness) {
return SND_PCM_FORMAT_U32_BE;
} else {
return SND_PCM_FORMAT_U32_LE;
}
return big_endian ? SND_PCM_FORMAT_U32_BE : SND_PCM_FORMAT_U32_LE;
case AUDIO_FORMAT_F32:
if (endianness) {
return SND_PCM_FORMAT_FLOAT_BE;
} else {
return SND_PCM_FORMAT_FLOAT_LE;
}
return big_endian ? SND_PCM_FORMAT_FLOAT_BE : SND_PCM_FORMAT_FLOAT_LE;
default:
dolog ("Internal logic error: Bad audio format %d\n", fmt);
@@ -956,7 +936,6 @@ static struct audio_pcm_ops alsa_pcm_ops = {
static struct audio_driver alsa_audio_driver = {
.name = "alsa",
.descr = "ALSA http://www.alsa-project.org",
.init = alsa_audio_init,
.fini = alsa_audio_fini,
.pcm_ops = &alsa_pcm_ops,
+9 -2
View File
@@ -23,11 +23,12 @@
*/
#include "qemu/osdep.h"
#include "audio/audio.h"
#include "audio_int.h"
#include "monitor/hmp.h"
#include "monitor/monitor.h"
#include "qapi/error.h"
#include "qobject/qdict.h"
#include "qemu/error-report.h"
static QLIST_HEAD (capture_list_head, CaptureState) capture_head;
@@ -36,6 +37,8 @@ void hmp_info_capture(Monitor *mon, const QDict *qdict)
int i;
CaptureState *s;
warn_report_once("'info capture' is deprecated since v10.2, to be removed");
for (s = capture_head.lh_first, i = 0; s; s = s->entries.le_next, ++i) {
monitor_printf(mon, "[%d]: ", i);
s->ops.info (s->opaque);
@@ -48,6 +51,8 @@ void hmp_stopcapture(Monitor *mon, const QDict *qdict)
int n = qdict_get_int(qdict, "n");
CaptureState *s;
warn_report_once("'stopcapture' is deprecated since v10.2, to be removed");
for (s = capture_head.lh_first, i = 0; s; s = s->entries.le_next, ++i) {
if (i == n) {
s->ops.destroy (s->opaque);
@@ -67,7 +72,9 @@ void hmp_wavcapture(Monitor *mon, const QDict *qdict)
const char *audiodev = qdict_get_str(qdict, "audiodev");
CaptureState *s;
Error *local_err = NULL;
AudioState *as = audio_state_by_name(audiodev, &local_err);
AudioBackend *as = audio_be_by_name(audiodev, &local_err);
warn_report_once("'wavcapture' is deprecated since v10.2, to be removed");
if (!as) {
error_report_err(local_err);
+165 -156
View File
File diff suppressed because it is too large Load Diff
-185
View File
@@ -1,185 +0,0 @@
/*
* QEMU Audio subsystem header
*
* Copyright (c) 2003-2005 Vassili Karpov (malc)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef QEMU_AUDIO_H
#define QEMU_AUDIO_H
#include "qemu/queue.h"
#include "qapi/qapi-types-audio.h"
#include "hw/qdev-properties.h"
#include "hw/qdev-properties-system.h"
typedef void (*audio_callback_fn) (void *opaque, int avail);
#if HOST_BIG_ENDIAN
#define AUDIO_HOST_ENDIANNESS 1
#else
#define AUDIO_HOST_ENDIANNESS 0
#endif
typedef struct audsettings {
int freq;
int nchannels;
AudioFormat fmt;
int endianness;
} audsettings;
audsettings audiodev_to_audsettings(AudiodevPerDirectionOptions *pdo);
int audioformat_bytes_per_sample(AudioFormat fmt);
int audio_buffer_frames(AudiodevPerDirectionOptions *pdo,
audsettings *as, int def_usecs);
int audio_buffer_samples(AudiodevPerDirectionOptions *pdo,
audsettings *as, int def_usecs);
int audio_buffer_bytes(AudiodevPerDirectionOptions *pdo,
audsettings *as, int def_usecs);
typedef enum {
AUD_CNOTIFY_ENABLE,
AUD_CNOTIFY_DISABLE
} audcnotification_e;
struct audio_capture_ops {
void (*notify) (void *opaque, audcnotification_e cmd);
void (*capture) (void *opaque, const void *buf, int size);
void (*destroy) (void *opaque);
};
struct capture_ops {
void (*info) (void *opaque);
void (*destroy) (void *opaque);
};
typedef struct CaptureState {
void *opaque;
struct capture_ops ops;
QLIST_ENTRY (CaptureState) entries;
} CaptureState;
typedef struct SWVoiceOut SWVoiceOut;
typedef struct CaptureVoiceOut CaptureVoiceOut;
typedef struct SWVoiceIn SWVoiceIn;
typedef struct AudioState AudioState;
typedef struct QEMUSoundCard {
char *name;
AudioState *state;
QLIST_ENTRY (QEMUSoundCard) entries;
} QEMUSoundCard;
typedef struct QEMUAudioTimeStamp {
uint64_t old_ts;
} QEMUAudioTimeStamp;
void AUD_vlog (const char *cap, const char *fmt, va_list ap) G_GNUC_PRINTF(2, 0);
void AUD_log (const char *cap, const char *fmt, ...) G_GNUC_PRINTF(2, 3);
bool AUD_register_card (const char *name, QEMUSoundCard *card, Error **errp);
void AUD_remove_card (QEMUSoundCard *card);
CaptureVoiceOut *AUD_add_capture(
AudioState *s,
struct audsettings *as,
struct audio_capture_ops *ops,
void *opaque
);
void AUD_del_capture (CaptureVoiceOut *cap, void *cb_opaque);
SWVoiceOut *AUD_open_out (
QEMUSoundCard *card,
SWVoiceOut *sw,
const char *name,
void *callback_opaque,
audio_callback_fn callback_fn,
struct audsettings *settings
);
void AUD_close_out (QEMUSoundCard *card, SWVoiceOut *sw);
size_t AUD_write (SWVoiceOut *sw, void *pcm_buf, size_t size);
int AUD_get_buffer_size_out (SWVoiceOut *sw);
void AUD_set_active_out (SWVoiceOut *sw, int on);
int AUD_is_active_out (SWVoiceOut *sw);
void AUD_init_time_stamp_out (SWVoiceOut *sw, QEMUAudioTimeStamp *ts);
uint64_t AUD_get_elapsed_usec_out (SWVoiceOut *sw, QEMUAudioTimeStamp *ts);
void AUD_set_volume_out (SWVoiceOut *sw, int mute, uint8_t lvol, uint8_t rvol);
void AUD_set_volume_in (SWVoiceIn *sw, int mute, uint8_t lvol, uint8_t rvol);
#define AUDIO_MAX_CHANNELS 16
typedef struct Volume {
bool mute;
int channels;
uint8_t vol[AUDIO_MAX_CHANNELS];
} Volume;
void audio_set_volume_out(SWVoiceOut *sw, Volume *vol);
void audio_set_volume_in(SWVoiceIn *sw, Volume *vol);
SWVoiceIn *AUD_open_in (
QEMUSoundCard *card,
SWVoiceIn *sw,
const char *name,
void *callback_opaque,
audio_callback_fn callback_fn,
struct audsettings *settings
);
void AUD_close_in (QEMUSoundCard *card, SWVoiceIn *sw);
size_t AUD_read (SWVoiceIn *sw, void *pcm_buf, size_t size);
void AUD_set_active_in (SWVoiceIn *sw, int on);
int AUD_is_active_in (SWVoiceIn *sw);
void AUD_init_time_stamp_in (SWVoiceIn *sw, QEMUAudioTimeStamp *ts);
uint64_t AUD_get_elapsed_usec_in (SWVoiceIn *sw, QEMUAudioTimeStamp *ts);
static inline void *advance (void *p, int incr)
{
uint8_t *d = p;
return (d + incr);
}
int wav_start_capture(AudioState *state, CaptureState *s, const char *path,
int freq, int bits, int nchannels);
void audio_cleanup(void);
void audio_sample_to_uint64(const void *samples, int pos,
uint64_t *left, uint64_t *right);
void audio_sample_from_uint64(void *samples, int pos,
uint64_t left, uint64_t right);
void audio_define(Audiodev *audio);
void audio_define_default(Audiodev *dev, Error **errp);
void audio_parse_option(const char *opt);
void audio_create_default_audiodevs(void);
void audio_init_audiodevs(void);
void audio_help(void);
AudioState *audio_state_by_name(const char *name, Error **errp);
AudioState *audio_get_default_audio_state(Error **errp);
const char *audio_get_id(QEMUSoundCard *card);
#define DEFINE_AUDIO_PROPERTIES(_s, _f) \
DEFINE_PROP_AUDIODEV("audiodev", _s, _f)
#endif /* QEMU_AUDIO_H */
+46 -21
View File
@@ -29,12 +29,20 @@
#define FLOAT_MIXENG
/* #define RECIPROCAL */
#endif
#include "qemu/audio.h"
#include "qemu/audio-capture.h"
#include "mixeng.h"
#ifdef CONFIG_GIO
#include <gio/gio.h>
#endif
void G_GNUC_PRINTF(2, 0)
AUD_vlog(const char *cap, const char *fmt, va_list ap);
void G_GNUC_PRINTF(2, 3)
AUD_log(const char *cap, const char *fmt, ...);
struct audio_pcm_ops;
struct audio_callback {
@@ -53,7 +61,7 @@ struct audio_pcm_info {
int swap_endianness;
};
typedef struct AudioState AudioState;
typedef struct AudioBackend AudioBackend;
typedef struct SWVoiceCap SWVoiceCap;
typedef struct STSampleBuffer {
@@ -62,10 +70,10 @@ typedef struct STSampleBuffer {
} STSampleBuffer;
typedef struct HWVoiceOut {
AudioState *s;
int enabled;
AudioBackend *s;
bool enabled;
int poll_mode;
int pending_disable;
bool pending_disable;
struct audio_pcm_info info;
f_sample *clip;
@@ -83,8 +91,8 @@ typedef struct HWVoiceOut {
} HWVoiceOut;
typedef struct HWVoiceIn {
AudioState *s;
int enabled;
AudioBackend *s;
bool enabled;
int poll_mode;
struct audio_pcm_info info;
@@ -104,15 +112,14 @@ typedef struct HWVoiceIn {
} HWVoiceIn;
struct SWVoiceOut {
QEMUSoundCard *card;
AudioState *s;
AudioBackend *s;
struct audio_pcm_info info;
t_sample *conv;
STSampleBuffer resample_buf;
void *rate;
size_t total_hw_samples_mixed;
int active;
int empty;
bool active;
bool empty;
HWVoiceOut *hw;
char *name;
struct mixeng_volume vol;
@@ -121,9 +128,8 @@ struct SWVoiceOut {
};
struct SWVoiceIn {
QEMUSoundCard *card;
AudioState *s;
int active;
AudioBackend *s;
bool active;
struct audio_pcm_info info;
void *rate;
size_t total_hw_samples_acquired;
@@ -139,11 +145,13 @@ struct SWVoiceIn {
typedef struct audio_driver audio_driver;
struct audio_driver {
const char *name;
const char *descr;
void *(*init) (Audiodev *, Error **);
void (*fini) (void *);
#ifdef CONFIG_GIO
void (*set_dbus_server) (AudioState *s, GDBusObjectManagerServer *manager, bool p2p);
bool (*set_dbus_server)(AudioBackend *be,
GDBusObjectManagerServer *manager,
bool p2p,
Error **errp);
#endif
struct audio_pcm_ops *pcm_ops;
int max_voices_out;
@@ -187,6 +195,23 @@ struct audio_pcm_ops {
void (*volume_in)(HWVoiceIn *hw, Volume *vol);
};
audsettings audiodev_to_audsettings(AudiodevPerDirectionOptions *pdo);
int audioformat_bytes_per_sample(AudioFormat fmt);
int audio_buffer_frames(AudiodevPerDirectionOptions *pdo,
audsettings *as, int def_usecs);
int audio_buffer_samples(AudiodevPerDirectionOptions *pdo,
audsettings *as, int def_usecs);
int audio_buffer_bytes(AudiodevPerDirectionOptions *pdo,
audsettings *as, int def_usecs);
static inline void *advance(void *p, size_t incr)
{
return (uint8_t *)p + incr;
}
int wav_start_capture(AudioBackend *state, CaptureState *s, const char *path,
int freq, int bits, int nchannels);
void audio_generic_run_buffer_in(HWVoiceIn *hw);
void *audio_generic_get_buffer_in(HWVoiceIn *hw, size_t *size);
void audio_generic_put_buffer_in(HWVoiceIn *hw, void *buf, size_t size);
@@ -216,13 +241,14 @@ struct SWVoiceCap {
QLIST_ENTRY (SWVoiceCap) entries;
};
typedef struct AudioState {
typedef struct AudioBackend {
Object parent;
struct audio_driver *drv;
Audiodev *dev;
void *drv_opaque;
QEMUTimer *ts;
QLIST_HEAD (card_listhead, QEMUSoundCard) card_head;
QLIST_HEAD (hw_in_listhead, HWVoiceIn) hw_head_in;
QLIST_HEAD (hw_out_listhead, HWVoiceOut) hw_head_out;
QLIST_HEAD (cap_listhead, CaptureVoiceOut) cap_head;
@@ -233,9 +259,8 @@ typedef struct AudioState {
bool timer_running;
uint64_t timer_last;
QTAILQ_ENTRY(AudioState) list;
} AudioState;
VMChangeStateEntry *vmse;
} AudioBackend;
extern const struct mixeng_volume nominal_volume;
@@ -248,7 +273,7 @@ void audio_pcm_info_clear_buf (struct audio_pcm_info *info, void *buf, int len);
int audio_bug (const char *funcname, int cond);
void audio_run(AudioState *s, const char *msg);
void audio_run(AudioBackend *s, const char *msg);
const char *audio_application_name(void);
+21 -23
View File
@@ -36,7 +36,7 @@
#define HWBUF hw->conv_buf
#endif
static void glue(audio_init_nb_voices_, TYPE)(AudioState *s,
static void glue(audio_init_nb_voices_, TYPE)(AudioBackend *s,
struct audio_driver *drv, int min_voices)
{
int max_voices = glue (drv->max_voices_, TYPE);
@@ -166,10 +166,10 @@ static int glue (audio_pcm_sw_init_, TYPE) (
audio_pcm_init_info (&sw->info, as);
sw->hw = hw;
sw->active = 0;
sw->active = false;
#ifdef DAC
sw->total_hw_samples_mixed = 0;
sw->empty = 1;
sw->empty = true;
#endif
if (sw->info.is_float) {
@@ -221,7 +221,7 @@ static void glue (audio_pcm_hw_del_sw_, TYPE) (SW *sw)
static void glue (audio_pcm_hw_gc_, TYPE) (HW **hwp)
{
HW *hw = *hwp;
AudioState *s = hw->s;
AudioBackend *s = hw->s;
if (!hw->sw_head.lh_first) {
#ifdef DAC
@@ -236,12 +236,12 @@ static void glue (audio_pcm_hw_gc_, TYPE) (HW **hwp)
}
}
static HW *glue(audio_pcm_hw_find_any_, TYPE)(AudioState *s, HW *hw)
static HW *glue(audio_pcm_hw_find_any_, TYPE)(AudioBackend *s, HW *hw)
{
return hw ? hw->entries.le_next : glue (s->hw_head_, TYPE).lh_first;
}
static HW *glue(audio_pcm_hw_find_any_enabled_, TYPE)(AudioState *s, HW *hw)
static HW *glue(audio_pcm_hw_find_any_enabled_, TYPE)(AudioBackend *s, HW *hw)
{
while ((hw = glue(audio_pcm_hw_find_any_, TYPE)(s, hw))) {
if (hw->enabled) {
@@ -251,7 +251,7 @@ static HW *glue(audio_pcm_hw_find_any_enabled_, TYPE)(AudioState *s, HW *hw)
return NULL;
}
static HW *glue(audio_pcm_hw_find_specific_, TYPE)(AudioState *s, HW *hw,
static HW *glue(audio_pcm_hw_find_specific_, TYPE)(AudioBackend *s, HW *hw,
struct audsettings *as)
{
while ((hw = glue(audio_pcm_hw_find_any_, TYPE)(s, hw))) {
@@ -262,7 +262,7 @@ static HW *glue(audio_pcm_hw_find_specific_, TYPE)(AudioState *s, HW *hw,
return NULL;
}
static HW *glue(audio_pcm_hw_add_new_, TYPE)(AudioState *s,
static HW *glue(audio_pcm_hw_add_new_, TYPE)(AudioBackend *s,
struct audsettings *as)
{
HW *hw;
@@ -398,7 +398,7 @@ AudiodevPerDirectionOptions *glue(audio_get_pdo_, TYPE)(Audiodev *dev)
abort();
}
static HW *glue(audio_pcm_hw_add_, TYPE)(AudioState *s, struct audsettings *as)
static HW *glue(audio_pcm_hw_add_, TYPE)(AudioBackend *s, struct audsettings *as)
{
HW *hw;
AudiodevPerDirectionOptions *pdo = glue(audio_get_pdo_, TYPE)(s->dev);
@@ -424,7 +424,7 @@ static HW *glue(audio_pcm_hw_add_, TYPE)(AudioState *s, struct audsettings *as)
}
static SW *glue(audio_pcm_create_voice_pair_, TYPE)(
AudioState *s,
AudioBackend *s,
const char *sw_name,
struct audsettings *as
)
@@ -473,11 +473,11 @@ static void glue (audio_close_, TYPE) (SW *sw)
g_free (sw);
}
void glue (AUD_close_, TYPE) (QEMUSoundCard *card, SW *sw)
void glue(AUD_close_, TYPE)(AudioBackend *be, SW *sw)
{
if (sw) {
if (audio_bug(__func__, !card)) {
dolog ("card=%p\n", card);
if (audio_bug(__func__, !be)) {
dolog("backend=%p\n", be);
return;
}
@@ -486,7 +486,7 @@ void glue (AUD_close_, TYPE) (QEMUSoundCard *card, SW *sw)
}
SW *glue (AUD_open_, TYPE) (
QEMUSoundCard *card,
AudioBackend *be,
SW *sw,
const char *name,
void *callback_opaque ,
@@ -494,16 +494,15 @@ SW *glue (AUD_open_, TYPE) (
struct audsettings *as
)
{
AudioState *s;
AudioBackend *s = be;
AudiodevPerDirectionOptions *pdo;
if (audio_bug(__func__, !card || !name || !callback_fn || !as)) {
dolog ("card=%p name=%p callback_fn=%p as=%p\n",
card, name, callback_fn, as);
if (audio_bug(__func__, !be || !name || !callback_fn || !as)) {
dolog("backend=%p name=%p callback_fn=%p as=%p\n",
be, name, callback_fn, as);
goto fail;
}
s = card->state;
pdo = glue(audio_get_pdo_, TYPE)(s->dev);
ldebug ("open %s, freq %d, nchannels %d, fmt %d\n",
@@ -524,7 +523,7 @@ SW *glue (AUD_open_, TYPE) (
}
if (!pdo->fixed_settings && sw) {
glue (AUD_close_, TYPE) (card, sw);
glue(AUD_close_, TYPE)(be, sw);
sw = NULL;
}
@@ -548,7 +547,6 @@ SW *glue (AUD_open_, TYPE) (
}
}
sw->card = card;
sw->vol = nominal_volume;
sw->callback.fn = callback_fn;
sw->callback.opaque = callback_opaque;
@@ -562,11 +560,11 @@ SW *glue (AUD_open_, TYPE) (
return sw;
fail:
glue (AUD_close_, TYPE) (card, sw);
glue(AUD_close_, TYPE)(be, sw);
return NULL;
}
int glue (AUD_is_active_, TYPE) (SW *sw)
bool glue(AUD_is_active_, TYPE)(SW *sw)
{
return sw ? sw->active : 0;
}
+1 -1
View File
@@ -7,7 +7,7 @@
#include <mmreg.h>
#include <mmsystem.h>
#include "audio.h"
#include "qemu/audio.h"
#include "audio_int.h"
#include "audio_win_int.h"
+1 -2
View File
@@ -28,7 +28,7 @@
#include "qemu/main-loop.h"
#include "qemu/module.h"
#include "audio.h"
#include "qemu/audio.h"
#define AUDIO_CAP "coreaudio"
#include "audio_int.h"
@@ -664,7 +664,6 @@ static struct audio_pcm_ops coreaudio_pcm_ops = {
static struct audio_driver coreaudio_audio_driver = {
.name = "coreaudio",
.descr = "CoreAudio http://developer.apple.com/audio/coreaudio.html",
.init = coreaudio_audio_init,
.fini = coreaudio_audio_fini,
.pcm_ops = &coreaudio_pcm_ops,
+11 -9
View File
@@ -24,9 +24,7 @@
#include "qemu/osdep.h"
#include "qemu/error-report.h"
#include "qemu/host-utils.h"
#include "qemu/module.h"
#include "qemu/timer.h"
#include "qemu/dbus.h"
#ifdef G_OS_UNIX
@@ -37,7 +35,7 @@
#include "ui/dbus-display1.h"
#define AUDIO_CAP "dbus"
#include "audio.h"
#include "qemu/audio.h"
#include "audio_int.h"
#include "trace.h"
@@ -460,7 +458,7 @@ listener_in_vanished_cb(GDBusConnection *connection,
}
static gboolean
dbus_audio_register_listener(AudioState *s,
dbus_audio_register_listener(AudioBackend *s,
GDBusMethodInvocation *invocation,
#ifdef G_OS_UNIX
GUnixFDList *fd_list,
@@ -617,7 +615,7 @@ dbus_audio_register_listener(AudioState *s,
}
static gboolean
dbus_audio_register_out_listener(AudioState *s,
dbus_audio_register_out_listener(AudioBackend *s,
GDBusMethodInvocation *invocation,
#ifdef G_OS_UNIX
GUnixFDList *fd_list,
@@ -633,7 +631,7 @@ dbus_audio_register_out_listener(AudioState *s,
}
static gboolean
dbus_audio_register_in_listener(AudioState *s,
dbus_audio_register_in_listener(AudioBackend *s,
GDBusMethodInvocation *invocation,
#ifdef G_OS_UNIX
GUnixFDList *fd_list,
@@ -647,8 +645,11 @@ dbus_audio_register_in_listener(AudioState *s,
arg_listener, false);
}
static void
dbus_audio_set_server(AudioState *s, GDBusObjectManagerServer *server, bool p2p)
static bool
dbus_audio_set_server(AudioBackend *s,
GDBusObjectManagerServer *server,
bool p2p,
Error **errp)
{
DBusAudio *da = s->drv_opaque;
@@ -671,6 +672,8 @@ dbus_audio_set_server(AudioState *s, GDBusObjectManagerServer *server, bool p2p)
g_dbus_object_skeleton_add_interface(G_DBUS_OBJECT_SKELETON(da->audio),
G_DBUS_INTERFACE_SKELETON(da->iface));
g_dbus_object_manager_server_export(da->server, da->audio);
return true;
}
static struct audio_pcm_ops dbus_pcm_ops = {
@@ -692,7 +695,6 @@ static struct audio_pcm_ops dbus_pcm_ops = {
static struct audio_driver dbus_audio_driver = {
.name = "dbus",
.descr = "Timer based audio exposed with DBus interface",
.init = dbus_audio_init,
.fini = dbus_audio_fini,
.set_dbus_server = dbus_audio_set_server,
+91 -124
View File
@@ -27,12 +27,12 @@
*/
#include "qemu/osdep.h"
#include "audio.h"
#include "qemu/audio.h"
#define AUDIO_CAP "dsound"
#include "audio_int.h"
#include "qemu/host-utils.h"
#include "qemu/module.h"
#include "qapi/error.h"
#include <windows.h>
#include <mmsystem.h>
@@ -64,162 +64,154 @@ typedef struct {
dsound *s;
} DSoundVoiceIn;
static void dsound_log_hresult (HRESULT hr)
static const char *dserror(HRESULT hr)
{
const char *str = "BUG";
switch (hr) {
case DS_OK:
str = "The method succeeded";
break;
return "The method succeeded";
#ifdef DS_NO_VIRTUALIZATION
case DS_NO_VIRTUALIZATION:
str = "The buffer was created, but another 3D algorithm was substituted";
break;
return "The buffer was created, but another 3D algorithm was substituted";
#endif
#ifdef DS_INCOMPLETE
case DS_INCOMPLETE:
str = "The method succeeded, but not all the optional effects were obtained";
break;
return "The method succeeded, but not all the optional effects were obtained";
#endif
#ifdef DSERR_ACCESSDENIED
case DSERR_ACCESSDENIED:
str = "The request failed because access was denied";
break;
return "The request failed because access was denied";
#endif
#ifdef DSERR_ALLOCATED
case DSERR_ALLOCATED:
str = "The request failed because resources, "
"such as a priority level, were already in use "
"by another caller";
break;
return "The request failed because resources, "
"such as a priority level, were already in use "
"by another caller";
#endif
#ifdef DSERR_ALREADYINITIALIZED
case DSERR_ALREADYINITIALIZED:
str = "The object is already initialized";
break;
return "The object is already initialized";
#endif
#ifdef DSERR_BADFORMAT
case DSERR_BADFORMAT:
str = "The specified wave format is not supported";
break;
return "The specified wave format is not supported";
#endif
#ifdef DSERR_BADSENDBUFFERGUID
case DSERR_BADSENDBUFFERGUID:
str = "The GUID specified in an audiopath file "
"does not match a valid mix-in buffer";
break;
return "The GUID specified in an audiopath file "
"does not match a valid mix-in buffer";
#endif
#ifdef DSERR_BUFFERLOST
case DSERR_BUFFERLOST:
str = "The buffer memory has been lost and must be restored";
break;
return "The buffer memory has been lost and must be restored";
#endif
#ifdef DSERR_BUFFERTOOSMALL
case DSERR_BUFFERTOOSMALL:
str = "The buffer size is not great enough to "
"enable effects processing";
break;
return "The buffer size is not great enough to "
"enable effects processing";
#endif
#ifdef DSERR_CONTROLUNAVAIL
case DSERR_CONTROLUNAVAIL:
str = "The buffer control (volume, pan, and so on) "
"requested by the caller is not available. "
"Controls must be specified when the buffer is created, "
"using the dwFlags member of DSBUFFERDESC";
break;
return "The buffer control (volume, pan, and so on) "
"requested by the caller is not available. "
"Controls must be specified when the buffer is created, "
"using the dwFlags member of DSBUFFERDESC";
#endif
#ifdef DSERR_DS8_REQUIRED
case DSERR_DS8_REQUIRED:
str = "A DirectSound object of class CLSID_DirectSound8 or later "
"is required for the requested functionality. "
"For more information, see IDirectSound8 Interface";
break;
return "A DirectSound object of class CLSID_DirectSound8 or later "
"is required for the requested functionality. "
"For more information, see IDirectSound8 Interface";
#endif
#ifdef DSERR_FXUNAVAILABLE
case DSERR_FXUNAVAILABLE:
str = "The effects requested could not be found on the system, "
"or they are in the wrong order or in the wrong location; "
"for example, an effect expected in hardware "
"was found in software";
break;
return "The effects requested could not be found on the system, "
"or they are in the wrong order or in the wrong location; "
"for example, an effect expected in hardware "
"was found in software";
#endif
#ifdef DSERR_GENERIC
case DSERR_GENERIC:
str = "An undetermined error occurred inside the DirectSound subsystem";
break;
return "An undetermined error occurred inside the DirectSound subsystem";
#endif
#ifdef DSERR_INVALIDCALL
case DSERR_INVALIDCALL:
str = "This function is not valid for the current state of this object";
break;
return "This function is not valid for the current state of this object";
#endif
#ifdef DSERR_INVALIDPARAM
case DSERR_INVALIDPARAM:
str = "An invalid parameter was passed to the returning function";
break;
return "An invalid parameter was passed to the returning function";
#endif
#ifdef DSERR_NOAGGREGATION
case DSERR_NOAGGREGATION:
str = "The object does not support aggregation";
break;
return "The object does not support aggregation";
#endif
#ifdef DSERR_NODRIVER
case DSERR_NODRIVER:
str = "No sound driver is available for use, "
"or the given GUID is not a valid DirectSound device ID";
break;
return "No sound driver is available for use, "
"or the given GUID is not a valid DirectSound device ID";
#endif
#ifdef DSERR_NOINTERFACE
case DSERR_NOINTERFACE:
str = "The requested COM interface is not available";
break;
return "The requested COM interface is not available";
#endif
#ifdef DSERR_OBJECTNOTFOUND
case DSERR_OBJECTNOTFOUND:
str = "The requested object was not found";
break;
return "The requested object was not found";
#endif
#ifdef DSERR_OTHERAPPHASPRIO
case DSERR_OTHERAPPHASPRIO:
str = "Another application has a higher priority level, "
return "Another application has a higher priority level, "
"preventing this call from succeeding";
break;
#endif
#ifdef DSERR_OUTOFMEMORY
case DSERR_OUTOFMEMORY:
str = "The DirectSound subsystem could not allocate "
return "The DirectSound subsystem could not allocate "
"sufficient memory to complete the caller's request";
break;
#endif
#ifdef DSERR_PRIOLEVELNEEDED
case DSERR_PRIOLEVELNEEDED:
str = "A cooperative level of DSSCL_PRIORITY or higher is required";
break;
return "A cooperative level of DSSCL_PRIORITY or higher is required";
#endif
#ifdef DSERR_SENDLOOP
case DSERR_SENDLOOP:
str = "A circular loop of send effects was detected";
break;
return "A circular loop of send effects was detected";
#endif
#ifdef DSERR_UNINITIALIZED
case DSERR_UNINITIALIZED:
str = "The Initialize method has not been called "
"or has not been called successfully "
"before other methods were called";
break;
return "The Initialize method has not been called "
"or has not been called successfully "
"before other methods were called";
#endif
#ifdef DSERR_UNSUPPORTED
case DSERR_UNSUPPORTED:
str = "The function called is not supported at this time";
break;
return "The function called is not supported at this time";
#endif
default:
AUD_log (AUDIO_CAP, "Reason: Unknown (HRESULT 0x%lx)\n", hr);
return;
return NULL;
}
AUD_log (AUDIO_CAP, "Reason: %s\n", str);
}
static void dserror_set(Error **errp, HRESULT hr, const char *msg)
{
const char *str = dserror(hr);
if (str) {
error_setg(errp, "%s: %s", msg, str);
} else {
error_setg(errp, "%s: Unknown (HRESULT: 0x%lx)", msg, hr);
}
}
static void dsound_log_hresult(HRESULT hr)
{
const char *str = dserror(hr);
if (str) {
AUD_log (AUDIO_CAP, "Reason: %s\n", str);
} else {
AUD_log (AUDIO_CAP, "Reason: Unknown (HRESULT: 0x%lx)\n", hr);
}
}
static void G_GNUC_PRINTF (2, 3) dsound_logerr (
@@ -359,27 +351,6 @@ static void dsound_clear_sample (HWVoiceOut *hw, LPDIRECTSOUNDBUFFER dsb,
dsound_unlock_out (dsb, p1, p2, blen1, blen2);
}
static int dsound_set_cooperative_level(dsound *s)
{
HRESULT hr;
HWND hwnd;
hwnd = GetDesktopWindow();
hr = IDirectSound_SetCooperativeLevel (
s->dsound,
hwnd,
DSSCL_PRIORITY
);
if (FAILED (hr)) {
dsound_logerr (hr, "Could not set cooperative level for window %p\n",
hwnd);
return -1;
}
return 0;
}
static void dsound_enable_out(HWVoiceOut *hw, bool enable)
{
HRESULT hr;
@@ -621,7 +592,6 @@ static void dsound_audio_fini (void *opaque)
static void *dsound_audio_init(Audiodev *dev, Error **errp)
{
int err;
HRESULT hr;
dsound *s = g_new0(dsound, 1);
AudiodevDsoundOptions *dso;
@@ -637,8 +607,8 @@ static void *dsound_audio_init(Audiodev *dev, Error **errp)
hr = CoInitialize (NULL);
if (FAILED (hr)) {
dsound_logerr (hr, "Could not initialize COM\n");
g_free(s);
dserror_set(errp, hr, "Could not initialize COM");
dsound_audio_fini(s);
return NULL;
}
@@ -650,20 +620,15 @@ static void *dsound_audio_init(Audiodev *dev, Error **errp)
(void **) &s->dsound
);
if (FAILED (hr)) {
dsound_logerr (hr, "Could not create DirectSound instance\n");
g_free(s);
dserror_set(errp, hr, "Could not create DirectSound instance");
dsound_audio_fini(s);
return NULL;
}
hr = IDirectSound_Initialize (s->dsound, NULL);
if (FAILED (hr)) {
dsound_logerr (hr, "Could not initialize DirectSound\n");
hr = IDirectSound_Release (s->dsound);
if (FAILED (hr)) {
dsound_logerr (hr, "Could not release DirectSound\n");
}
g_free(s);
dserror_set(errp, hr, "Could not initialize DirectSound");
dsound_audio_fini(s);
return NULL;
}
@@ -675,23 +640,26 @@ static void *dsound_audio_init(Audiodev *dev, Error **errp)
(void **) &s->dsound_capture
);
if (FAILED (hr)) {
dsound_logerr (hr, "Could not create DirectSoundCapture instance\n");
} else {
hr = IDirectSoundCapture_Initialize (s->dsound_capture, NULL);
if (FAILED (hr)) {
dsound_logerr (hr, "Could not initialize DirectSoundCapture\n");
hr = IDirectSoundCapture_Release (s->dsound_capture);
if (FAILED (hr)) {
dsound_logerr (hr, "Could not release DirectSoundCapture\n");
}
s->dsound_capture = NULL;
}
dserror_set(errp, hr, "Could not create DirectSoundCapture instance");
dsound_audio_fini(s);
return NULL;
}
err = dsound_set_cooperative_level(s);
if (err) {
dsound_audio_fini (s);
hr = IDirectSoundCapture_Initialize (s->dsound_capture, NULL);
if (FAILED(hr)) {
dserror_set(errp, hr, "Could not initialize DirectSoundCapture");
dsound_audio_fini(s);
return NULL;
}
hr = IDirectSound_SetCooperativeLevel (
s->dsound,
GetDesktopWindow(),
DSSCL_PRIORITY
);
if (FAILED(hr)) {
dserror_set(errp, hr, "Could not set cooperative level");
dsound_audio_fini(s);
return NULL;
}
@@ -717,7 +685,6 @@ static struct audio_pcm_ops dsound_pcm_ops = {
static struct audio_driver dsound_audio_driver = {
.name = "dsound",
.descr = "DirectSound http://wikipedia.org/wiki/DirectSound",
.init = dsound_audio_init,
.fini = dsound_audio_fini,
.pcm_ops = &dsound_pcm_ops,
+1 -2
View File
@@ -26,7 +26,7 @@
#include "qemu/module.h"
#include "qemu/atomic.h"
#include "qemu/main-loop.h"
#include "audio.h"
#include "qemu/audio.h"
#define AUDIO_CAP "jack"
#include "audio_int.h"
@@ -672,7 +672,6 @@ static struct audio_pcm_ops jack_pcm_ops = {
static struct audio_driver jack_driver = {
.name = "jack",
.descr = "JACK Audio Connection Kit Client",
.init = qjack_init,
.fini = qjack_fini,
.pcm_ops = &jack_pcm_ops,
+4 -3
View File
@@ -1,12 +1,13 @@
system_ss.add([spice_headers, files('audio.c')])
system_ss.add(files(
'audio-hmp-cmds.c',
'audio.c',
'mixeng.c',
'noaudio.c',
'wavaudio.c',
'wavcapture.c',
))
# deprecated since v10.2, to be removed
system_ss.add(files('audio-hmp-cmds.c', 'wavcapture.c'))
system_ss.add(when: coreaudio, if_true: files('coreaudio.m'))
system_ss.add(when: dsound, if_true: files('dsoundaudio.c', 'audio_win_int.c'))
+6 -6
View File
@@ -24,11 +24,13 @@
*/
#include "qemu/osdep.h"
#include "qemu/bswap.h"
#include "qemu/error-report.h"
#include "audio.h"
#include "qemu/audio.h"
#define AUDIO_CAP "mixeng"
#include "audio_int.h"
#ifdef FLOAT_MIXENG
#include "qemu/error-report.h"
#endif
/* 8 bit */
#define ENDIAN_CONVERSION natural
@@ -402,7 +404,7 @@ f_sample *mixeng_clip_float[2][2] = {
}
};
void audio_sample_to_uint64(const void *samples, int pos,
void audio_sample_to_uint64(const st_sample *sample, int pos,
uint64_t *left, uint64_t *right)
{
#ifdef FLOAT_MIXENG
@@ -410,14 +412,13 @@ void audio_sample_to_uint64(const void *samples, int pos,
"Coreaudio and floating point samples are not supported by replay yet");
abort();
#else
const struct st_sample *sample = samples;
sample += pos;
*left = sample->l;
*right = sample->r;
#endif
}
void audio_sample_from_uint64(void *samples, int pos,
void audio_sample_from_uint64(st_sample *sample, int pos,
uint64_t left, uint64_t right)
{
#ifdef FLOAT_MIXENG
@@ -425,7 +426,6 @@ void audio_sample_from_uint64(void *samples, int pos,
"Coreaudio and floating point samples are not supported by replay yet");
abort();
#else
struct st_sample *sample = samples;
sample += pos;
sample->l = left;
sample->r = right;
-1
View File
@@ -33,7 +33,6 @@ struct st_sample { mixeng_real l; mixeng_real r; };
struct mixeng_volume { int mute; int64_t r; int64_t l; };
struct st_sample { int64_t l; int64_t r; };
#endif
typedef struct st_sample st_sample;
typedef void (t_sample) (struct st_sample *dst, const void *src, int samples);
typedef void (f_sample) (void *dst, const struct st_sample *src, int samples);
+1 -4
View File
@@ -23,10 +23,8 @@
*/
#include "qemu/osdep.h"
#include "qemu/host-utils.h"
#include "qemu/module.h"
#include "audio.h"
#include "qemu/timer.h"
#include "qemu/audio.h"
#define AUDIO_CAP "noaudio"
#include "audio_int.h"
@@ -131,7 +129,6 @@ static struct audio_pcm_ops no_pcm_ops = {
static struct audio_driver no_audio_driver = {
.name = "none",
.descr = "Timer based audio emulation",
.init = no_audio_init,
.fini = no_audio_fini,
.pcm_ops = &no_pcm_ops,
+8 -25
View File
@@ -29,7 +29,7 @@
#include "qemu/module.h"
#include "qemu/host-utils.h"
#include "qapi/error.h"
#include "audio.h"
#include "qemu/audio.h"
#include "trace.h"
#define AUDIO_CAP "oss"
@@ -107,13 +107,13 @@ static void oss_anal_close (int *fdp)
static void oss_helper_poll_out (void *opaque)
{
AudioState *s = opaque;
AudioBackend *s = opaque;
audio_run(s, "oss_poll_out");
}
static void oss_helper_poll_in (void *opaque)
{
AudioState *s = opaque;
AudioBackend *s = opaque;
audio_run(s, "oss_poll_in");
}
@@ -131,7 +131,7 @@ static void oss_poll_in (HWVoiceIn *hw)
qemu_set_fd_handler(oss->fd, oss_helper_poll_in, NULL, hw->s);
}
static int aud_to_ossfmt (AudioFormat fmt, int endianness)
static int aud_to_ossfmt(AudioFormat fmt, bool big_endian)
{
switch (fmt) {
case AUDIO_FORMAT_S8:
@@ -141,18 +141,10 @@ static int aud_to_ossfmt (AudioFormat fmt, int endianness)
return AFMT_U8;
case AUDIO_FORMAT_S16:
if (endianness) {
return AFMT_S16_BE;
} else {
return AFMT_S16_LE;
}
return big_endian ? AFMT_S16_BE : AFMT_S16_LE;
case AUDIO_FORMAT_U16:
if (endianness) {
return AFMT_U16_BE;
} else {
return AFMT_U16_LE;
}
return big_endian ? AFMT_U16_BE : AFMT_U16_LE;
default:
dolog ("Internal logic error: Bad audio format %d\n", fmt);
@@ -493,10 +485,8 @@ static int oss_init_out(HWVoiceOut *hw, struct audsettings *as,
{
OSSVoiceOut *oss = (OSSVoiceOut *) hw;
struct oss_params req, obt;
int endianness;
int err;
int fd;
AudioFormat effective_fmt;
struct audsettings obt_as;
Audiodev *dev = drv_opaque;
AudiodevOssOptions *oopts = &dev->u.oss;
@@ -511,7 +501,7 @@ static int oss_init_out(HWVoiceOut *hw, struct audsettings *as,
return -1;
}
err = oss_to_audfmt (obt.fmt, &effective_fmt, &endianness);
err = oss_to_audfmt(obt.fmt, &obt_as.fmt, &obt_as.endianness);
if (err) {
oss_anal_close (&fd);
return -1;
@@ -519,8 +509,6 @@ static int oss_init_out(HWVoiceOut *hw, struct audsettings *as,
obt_as.freq = obt.freq;
obt_as.nchannels = obt.nchannels;
obt_as.fmt = effective_fmt;
obt_as.endianness = endianness;
audio_pcm_init_info (&hw->info, &obt_as);
oss->nfrags = obt.nfrags;
@@ -628,10 +616,8 @@ static int oss_init_in(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque)
{
OSSVoiceIn *oss = (OSSVoiceIn *) hw;
struct oss_params req, obt;
int endianness;
int err;
int fd;
AudioFormat effective_fmt;
struct audsettings obt_as;
Audiodev *dev = drv_opaque;
@@ -644,7 +630,7 @@ static int oss_init_in(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque)
return -1;
}
err = oss_to_audfmt (obt.fmt, &effective_fmt, &endianness);
err = oss_to_audfmt(obt.fmt, &obt_as.fmt, &obt_as.endianness);
if (err) {
oss_anal_close (&fd);
return -1;
@@ -652,8 +638,6 @@ static int oss_init_in(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque)
obt_as.freq = obt.freq;
obt_as.nchannels = obt.nchannels;
obt_as.fmt = effective_fmt;
obt_as.endianness = endianness;
audio_pcm_init_info (&hw->info, &obt_as);
oss->nfrags = obt.nfrags;
@@ -779,7 +763,6 @@ static struct audio_pcm_ops oss_pcm_ops = {
static struct audio_driver oss_audio_driver = {
.name = "oss",
.descr = "OSS http://www.opensound.com",
.init = oss_audio_init,
.fini = oss_audio_fini,
.pcm_ops = &oss_pcm_ops,
+9 -15
View File
@@ -2,7 +2,7 @@
#include "qemu/osdep.h"
#include "qemu/module.h"
#include "audio.h"
#include "qemu/audio.h"
#include "qapi/error.h"
#include <pulse/pulseaudio.h>
@@ -316,7 +316,7 @@ unlock_and_fail:
return 0;
}
static pa_sample_format_t audfmt_to_pa (AudioFormat afmt, int endianness)
static pa_sample_format_t audfmt_to_pa(AudioFormat afmt, bool big_endian)
{
int format;
@@ -327,14 +327,14 @@ static pa_sample_format_t audfmt_to_pa (AudioFormat afmt, int endianness)
break;
case AUDIO_FORMAT_S16:
case AUDIO_FORMAT_U16:
format = endianness ? PA_SAMPLE_S16BE : PA_SAMPLE_S16LE;
format = big_endian ? PA_SAMPLE_S16BE : PA_SAMPLE_S16LE;
break;
case AUDIO_FORMAT_S32:
case AUDIO_FORMAT_U32:
format = endianness ? PA_SAMPLE_S32BE : PA_SAMPLE_S32LE;
format = big_endian ? PA_SAMPLE_S32BE : PA_SAMPLE_S32LE;
break;
case AUDIO_FORMAT_F32:
format = endianness ? PA_SAMPLE_FLOAT32BE : PA_SAMPLE_FLOAT32LE;
format = big_endian ? PA_SAMPLE_FLOAT32BE : PA_SAMPLE_FLOAT32LE;
break;
default:
dolog ("Internal logic error: Bad audio format %d\n", afmt);
@@ -747,14 +747,13 @@ static void qpa_volume_in(HWVoiceIn *hw, Volume *vol)
pa_threaded_mainloop_unlock(c->mainloop);
}
static int qpa_validate_per_direction_opts(Audiodev *dev,
AudiodevPaPerDirectionOptions *pdo)
static void qpa_validate_per_direction_opts(Audiodev *dev,
AudiodevPaPerDirectionOptions *pdo)
{
if (!pdo->has_latency) {
pdo->has_latency = true;
pdo->latency = 46440;
}
return 1;
}
/* common */
@@ -844,12 +843,8 @@ static void *qpa_audio_init(Audiodev *dev, Error **errp)
}
}
if (!qpa_validate_per_direction_opts(dev, popts->in)) {
return NULL;
}
if (!qpa_validate_per_direction_opts(dev, popts->out)) {
return NULL;
}
qpa_validate_per_direction_opts(dev, popts->in);
qpa_validate_per_direction_opts(dev, popts->out);
g = g_new0(paaudio, 1);
server = popts->server;
@@ -927,7 +922,6 @@ static struct audio_pcm_ops qpa_pcm_ops = {
static struct audio_driver pa_audio_driver = {
.name = "pa",
.descr = "http://www.pulseaudio.org/",
.init = qpa_audio_init,
.fini = qpa_audio_fini,
.pcm_ops = &qpa_pcm_ops,
+7 -8
View File
@@ -10,7 +10,7 @@
#include "qemu/osdep.h"
#include "qemu/module.h"
#include "audio.h"
#include "qemu/audio.h"
#include "qemu/error-report.h"
#include "qapi/error.h"
#include <spa/param/audio/format-utils.h>
@@ -324,7 +324,7 @@ done_unlock:
}
static int
audfmt_to_pw(AudioFormat fmt, int endianness)
audfmt_to_pw(AudioFormat fmt, bool big_endian)
{
int format;
@@ -336,19 +336,19 @@ audfmt_to_pw(AudioFormat fmt, int endianness)
format = SPA_AUDIO_FORMAT_U8;
break;
case AUDIO_FORMAT_S16:
format = endianness ? SPA_AUDIO_FORMAT_S16_BE : SPA_AUDIO_FORMAT_S16_LE;
format = big_endian ? SPA_AUDIO_FORMAT_S16_BE : SPA_AUDIO_FORMAT_S16_LE;
break;
case AUDIO_FORMAT_U16:
format = endianness ? SPA_AUDIO_FORMAT_U16_BE : SPA_AUDIO_FORMAT_U16_LE;
format = big_endian ? SPA_AUDIO_FORMAT_U16_BE : SPA_AUDIO_FORMAT_U16_LE;
break;
case AUDIO_FORMAT_S32:
format = endianness ? SPA_AUDIO_FORMAT_S32_BE : SPA_AUDIO_FORMAT_S32_LE;
format = big_endian ? SPA_AUDIO_FORMAT_S32_BE : SPA_AUDIO_FORMAT_S32_LE;
break;
case AUDIO_FORMAT_U32:
format = endianness ? SPA_AUDIO_FORMAT_U32_BE : SPA_AUDIO_FORMAT_U32_LE;
format = big_endian ? SPA_AUDIO_FORMAT_U32_BE : SPA_AUDIO_FORMAT_U32_LE;
break;
case AUDIO_FORMAT_F32:
format = endianness ? SPA_AUDIO_FORMAT_F32_BE : SPA_AUDIO_FORMAT_F32_LE;
format = big_endian ? SPA_AUDIO_FORMAT_F32_BE : SPA_AUDIO_FORMAT_F32_LE;
break;
default:
dolog("Internal logic error: Bad audio format %d\n", fmt);
@@ -838,7 +838,6 @@ static struct audio_pcm_ops qpw_pcm_ops = {
static struct audio_driver pw_audio_driver = {
.name = "pipewire",
.descr = "http://www.pipewire.org/",
.init = qpw_audio_init,
.fini = qpw_audio_fini,
.pcm_ops = &qpw_pcm_ops,
+3 -12
View File
@@ -27,7 +27,7 @@
#include <SDL_thread.h>
#include "qemu/module.h"
#include "qapi/error.h"
#include "audio.h"
#include "qemu/audio.h"
#ifndef _WIN32
#ifdef __sun__
@@ -338,9 +338,7 @@ static int sdl_init_out(HWVoiceOut *hw, struct audsettings *as,
{
SDLVoiceOut *sdl = (SDLVoiceOut *)hw;
SDL_AudioSpec req, obt;
int endianness;
int err;
AudioFormat effective_fmt;
Audiodev *dev = drv_opaque;
AudiodevSdlPerDirectionOptions *spdo = dev->u.sdl.out;
struct audsettings obt_as;
@@ -360,7 +358,7 @@ static int sdl_init_out(HWVoiceOut *hw, struct audsettings *as,
return -1;
}
err = sdl_to_audfmt(obt.format, &effective_fmt, &endianness);
err = sdl_to_audfmt(obt.format, &obt_as.fmt, &obt_as.endianness);
if (err) {
sdl_close_out(sdl);
return -1;
@@ -368,8 +366,6 @@ static int sdl_init_out(HWVoiceOut *hw, struct audsettings *as,
obt_as.freq = obt.freq;
obt_as.nchannels = obt.channels;
obt_as.fmt = effective_fmt;
obt_as.endianness = endianness;
audio_pcm_init_info (&hw->info, &obt_as);
hw->samples = (spdo->has_buffer_count ? spdo->buffer_count : 4) *
@@ -398,9 +394,7 @@ static int sdl_init_in(HWVoiceIn *hw, audsettings *as, void *drv_opaque)
{
SDLVoiceIn *sdl = (SDLVoiceIn *)hw;
SDL_AudioSpec req, obt;
int endianness;
int err;
AudioFormat effective_fmt;
Audiodev *dev = drv_opaque;
AudiodevSdlPerDirectionOptions *spdo = dev->u.sdl.in;
struct audsettings obt_as;
@@ -420,7 +414,7 @@ static int sdl_init_in(HWVoiceIn *hw, audsettings *as, void *drv_opaque)
return -1;
}
err = sdl_to_audfmt(obt.format, &effective_fmt, &endianness);
err = sdl_to_audfmt(obt.format, &obt_as.fmt, &obt_as.endianness);
if (err) {
sdl_close_in(sdl);
return -1;
@@ -428,8 +422,6 @@ static int sdl_init_in(HWVoiceIn *hw, audsettings *as, void *drv_opaque)
obt_as.freq = obt.freq;
obt_as.nchannels = obt.channels;
obt_as.fmt = effective_fmt;
obt_as.endianness = endianness;
audio_pcm_init_info(&hw->info, &obt_as);
hw->samples = (spdo->has_buffer_count ? spdo->buffer_count : 4) *
@@ -490,7 +482,6 @@ static struct audio_pcm_ops sdl_pcm_ops = {
static struct audio_driver sdl_audio_driver = {
.name = "sdl",
.descr = "SDL http://www.libsdl.org",
.init = sdl_audio_init,
.fini = sdl_audio_fini,
.pcm_ops = &sdl_pcm_ops,

Some files were not shown because too many files have changed in this diff Show More