mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
Merge remote-tracking branch 'remotes/kraxel/tags/audio-20190821-pull-request' into staging
audio: second batch of -audiodev support, adding support for multiple backends. # gpg: Signature made Wed 21 Aug 2019 09:40:37 BST # 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-20190821-pull-request: audio: fix memory leak reported by ASAN audio: use size_t where makes sense audio: remove read and write pcm_ops paaudio: fix playback glitches audio: do not run each backend in audio_run audio: remove audio_MIN, audio_MAX paaudio: properly disconnect streams in fini_* paaudio: do not move stream when sink/source name is specified audio: audiodev= parameters no longer optional when -audiodev present paaudio: prepare for multiple audiodev audio: add audiodev properties to frontends audio: add audiodev property to vnc and wav_capture audio: basic support for multi backend audio audio: reduce glob_audio_state usage audio: Add missing fall through comments Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
+20
-29
@@ -39,6 +39,7 @@ struct pollhlp {
|
||||
struct pollfd *pfds;
|
||||
int count;
|
||||
int mask;
|
||||
AudioState *s;
|
||||
};
|
||||
|
||||
typedef struct ALSAVoiceOut {
|
||||
@@ -199,11 +200,11 @@ static void alsa_poll_handler (void *opaque)
|
||||
break;
|
||||
|
||||
case SND_PCM_STATE_PREPARED:
|
||||
audio_run ("alsa run (prepared)");
|
||||
audio_run(hlp->s, "alsa run (prepared)");
|
||||
break;
|
||||
|
||||
case SND_PCM_STATE_RUNNING:
|
||||
audio_run ("alsa run (running)");
|
||||
audio_run(hlp->s, "alsa run (running)");
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -269,11 +270,6 @@ static int alsa_poll_in (HWVoiceIn *hw)
|
||||
return alsa_poll_helper (alsa->handle, &alsa->pollhlp, POLLIN);
|
||||
}
|
||||
|
||||
static int alsa_write (SWVoiceOut *sw, void *buf, int len)
|
||||
{
|
||||
return audio_pcm_sw_write (sw, buf, len);
|
||||
}
|
||||
|
||||
static snd_pcm_format_t aud_to_alsafmt (AudioFormat fmt, int endianness)
|
||||
{
|
||||
switch (fmt) {
|
||||
@@ -634,7 +630,7 @@ static void alsa_write_pending (ALSAVoiceOut *alsa)
|
||||
|
||||
while (alsa->pending) {
|
||||
int left_till_end_samples = hw->samples - alsa->wpos;
|
||||
int len = audio_MIN (alsa->pending, left_till_end_samples);
|
||||
int len = MIN (alsa->pending, left_till_end_samples);
|
||||
char *src = advance (alsa->pcm_buf, alsa->wpos << hw->info.shift);
|
||||
|
||||
while (len) {
|
||||
@@ -685,10 +681,10 @@ static void alsa_write_pending (ALSAVoiceOut *alsa)
|
||||
}
|
||||
}
|
||||
|
||||
static int alsa_run_out (HWVoiceOut *hw, int live)
|
||||
static size_t alsa_run_out(HWVoiceOut *hw, size_t live)
|
||||
{
|
||||
ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw;
|
||||
int decr;
|
||||
size_t decr;
|
||||
snd_pcm_sframes_t avail;
|
||||
|
||||
avail = alsa_get_avail (alsa->handle);
|
||||
@@ -697,7 +693,7 @@ static int alsa_run_out (HWVoiceOut *hw, int live)
|
||||
return 0;
|
||||
}
|
||||
|
||||
decr = audio_MIN (live, avail);
|
||||
decr = MIN (live, avail);
|
||||
decr = audio_pcm_hw_clip_out (hw, alsa->pcm_buf, decr, alsa->pending);
|
||||
alsa->pending += decr;
|
||||
alsa_write_pending (alsa);
|
||||
@@ -743,12 +739,13 @@ static int alsa_init_out(HWVoiceOut *hw, struct audsettings *as,
|
||||
|
||||
alsa->pcm_buf = audio_calloc(__func__, obt.samples, 1 << hw->info.shift);
|
||||
if (!alsa->pcm_buf) {
|
||||
dolog ("Could not allocate DAC buffer (%d samples, each %d bytes)\n",
|
||||
hw->samples, 1 << hw->info.shift);
|
||||
dolog("Could not allocate DAC buffer (%zu samples, each %d bytes)\n",
|
||||
hw->samples, 1 << hw->info.shift);
|
||||
alsa_anal_close1 (&handle);
|
||||
return -1;
|
||||
}
|
||||
|
||||
alsa->pollhlp.s = hw->s;
|
||||
alsa->handle = handle;
|
||||
alsa->dev = dev;
|
||||
return 0;
|
||||
@@ -844,12 +841,13 @@ static int alsa_init_in(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque)
|
||||
|
||||
alsa->pcm_buf = audio_calloc(__func__, hw->samples, 1 << hw->info.shift);
|
||||
if (!alsa->pcm_buf) {
|
||||
dolog ("Could not allocate ADC buffer (%d samples, each %d bytes)\n",
|
||||
hw->samples, 1 << hw->info.shift);
|
||||
dolog("Could not allocate ADC buffer (%zu samples, each %d bytes)\n",
|
||||
hw->samples, 1 << hw->info.shift);
|
||||
alsa_anal_close1 (&handle);
|
||||
return -1;
|
||||
}
|
||||
|
||||
alsa->pollhlp.s = hw->s;
|
||||
alsa->handle = handle;
|
||||
alsa->dev = dev;
|
||||
return 0;
|
||||
@@ -865,17 +863,17 @@ static void alsa_fini_in (HWVoiceIn *hw)
|
||||
alsa->pcm_buf = NULL;
|
||||
}
|
||||
|
||||
static int alsa_run_in (HWVoiceIn *hw)
|
||||
static size_t alsa_run_in(HWVoiceIn *hw)
|
||||
{
|
||||
ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw;
|
||||
int hwshift = hw->info.shift;
|
||||
int i;
|
||||
int live = audio_pcm_hw_get_live_in (hw);
|
||||
int dead = hw->samples - live;
|
||||
int decr;
|
||||
size_t live = audio_pcm_hw_get_live_in (hw);
|
||||
size_t dead = hw->samples - live;
|
||||
size_t decr;
|
||||
struct {
|
||||
int add;
|
||||
int len;
|
||||
size_t add;
|
||||
size_t len;
|
||||
} bufs[2] = {
|
||||
{ .add = hw->wpos, .len = 0 },
|
||||
{ .add = 0, .len = 0 }
|
||||
@@ -915,7 +913,7 @@ static int alsa_run_in (HWVoiceIn *hw)
|
||||
}
|
||||
}
|
||||
|
||||
decr = audio_MIN (dead, avail);
|
||||
decr = MIN(dead, avail);
|
||||
if (!decr) {
|
||||
return 0;
|
||||
}
|
||||
@@ -985,11 +983,6 @@ static int alsa_run_in (HWVoiceIn *hw)
|
||||
return read_samples;
|
||||
}
|
||||
|
||||
static int alsa_read (SWVoiceIn *sw, void *buf, int size)
|
||||
{
|
||||
return audio_pcm_sw_read (sw, buf, size);
|
||||
}
|
||||
|
||||
static int alsa_ctl_in (HWVoiceIn *hw, int cmd, ...)
|
||||
{
|
||||
ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw;
|
||||
@@ -1073,13 +1066,11 @@ static struct audio_pcm_ops alsa_pcm_ops = {
|
||||
.init_out = alsa_init_out,
|
||||
.fini_out = alsa_fini_out,
|
||||
.run_out = alsa_run_out,
|
||||
.write = alsa_write,
|
||||
.ctl_out = alsa_ctl_out,
|
||||
|
||||
.init_in = alsa_init_in,
|
||||
.fini_in = alsa_fini_in,
|
||||
.run_in = alsa_run_in,
|
||||
.read = alsa_read,
|
||||
.ctl_in = alsa_ctl_in,
|
||||
};
|
||||
|
||||
|
||||
+201
-146
File diff suppressed because it is too large
Load Diff
+15
-22
@@ -27,6 +27,7 @@
|
||||
|
||||
#include "qemu/queue.h"
|
||||
#include "qapi/qapi-types-audio.h"
|
||||
#include "hw/qdev-properties.h"
|
||||
|
||||
typedef void (*audio_callback_fn) (void *opaque, int avail);
|
||||
|
||||
@@ -78,8 +79,10 @@ 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;
|
||||
|
||||
@@ -92,7 +95,8 @@ void AUD_log (const char *cap, const char *fmt, ...) GCC_FMT_ATTR(2, 3);
|
||||
|
||||
void AUD_register_card (const char *name, QEMUSoundCard *card);
|
||||
void AUD_remove_card (QEMUSoundCard *card);
|
||||
CaptureVoiceOut *AUD_add_capture (
|
||||
CaptureVoiceOut *AUD_add_capture(
|
||||
AudioState *s,
|
||||
struct audsettings *as,
|
||||
struct audio_capture_ops *ops,
|
||||
void *opaque
|
||||
@@ -109,7 +113,7 @@ SWVoiceOut *AUD_open_out (
|
||||
);
|
||||
|
||||
void AUD_close_out (QEMUSoundCard *card, SWVoiceOut *sw);
|
||||
int AUD_write (SWVoiceOut *sw, void *pcm_buf, int size);
|
||||
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);
|
||||
@@ -130,7 +134,7 @@ SWVoiceIn *AUD_open_in (
|
||||
);
|
||||
|
||||
void AUD_close_in (QEMUSoundCard *card, SWVoiceIn *sw);
|
||||
int AUD_read (SWVoiceIn *sw, void *pcm_buf, int size);
|
||||
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);
|
||||
|
||||
@@ -143,25 +147,8 @@ static inline void *advance (void *p, int incr)
|
||||
return (d + incr);
|
||||
}
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define audio_MIN(a, b) ( __extension__ ({ \
|
||||
__typeof (a) ta = a; \
|
||||
__typeof (b) tb = b; \
|
||||
((ta)>(tb)?(tb):(ta)); \
|
||||
}))
|
||||
|
||||
#define audio_MAX(a, b) ( __extension__ ({ \
|
||||
__typeof (a) ta = a; \
|
||||
__typeof (b) tb = b; \
|
||||
((ta)<(tb)?(tb):(ta)); \
|
||||
}))
|
||||
#else
|
||||
#define audio_MIN(a, b) ((a)>(b)?(b):(a))
|
||||
#define audio_MAX(a, b) ((a)<(b)?(b):(a))
|
||||
#endif
|
||||
|
||||
int wav_start_capture (CaptureState *s, const char *path, int freq,
|
||||
int bits, int nchannels);
|
||||
int wav_start_capture(AudioState *state, CaptureState *s, const char *path,
|
||||
int freq, int bits, int nchannels);
|
||||
|
||||
bool audio_is_cleaning_up(void);
|
||||
void audio_cleanup(void);
|
||||
@@ -175,4 +162,10 @@ void audio_parse_option(const char *opt);
|
||||
void audio_init_audiodevs(void);
|
||||
void audio_legacy_help(void);
|
||||
|
||||
AudioState *audio_state_by_name(const char *name);
|
||||
const char *audio_get_id(QEMUSoundCard *card);
|
||||
|
||||
#define DEFINE_AUDIO_PROPERTIES(_s, _f) \
|
||||
DEFINE_PROP_AUDIODEV("audiodev", _s, _f)
|
||||
|
||||
#endif /* QEMU_AUDIO_H */
|
||||
|
||||
+24
-19
@@ -49,9 +49,11 @@ struct audio_pcm_info {
|
||||
int swap_endianness;
|
||||
};
|
||||
|
||||
typedef struct AudioState AudioState;
|
||||
typedef struct SWVoiceCap SWVoiceCap;
|
||||
|
||||
typedef struct HWVoiceOut {
|
||||
AudioState *s;
|
||||
int enabled;
|
||||
int poll_mode;
|
||||
int pending_disable;
|
||||
@@ -59,12 +61,12 @@ typedef struct HWVoiceOut {
|
||||
|
||||
f_sample *clip;
|
||||
|
||||
int rpos;
|
||||
size_t rpos;
|
||||
uint64_t ts_helper;
|
||||
|
||||
struct st_sample *mix_buf;
|
||||
|
||||
int samples;
|
||||
size_t samples;
|
||||
QLIST_HEAD (sw_out_listhead, SWVoiceOut) sw_head;
|
||||
QLIST_HEAD (sw_cap_listhead, SWVoiceCap) cap_head;
|
||||
int ctl_caps;
|
||||
@@ -73,19 +75,20 @@ typedef struct HWVoiceOut {
|
||||
} HWVoiceOut;
|
||||
|
||||
typedef struct HWVoiceIn {
|
||||
AudioState *s;
|
||||
int enabled;
|
||||
int poll_mode;
|
||||
struct audio_pcm_info info;
|
||||
|
||||
t_sample *conv;
|
||||
|
||||
int wpos;
|
||||
int total_samples_captured;
|
||||
size_t wpos;
|
||||
size_t total_samples_captured;
|
||||
uint64_t ts_helper;
|
||||
|
||||
struct st_sample *conv_buf;
|
||||
|
||||
int samples;
|
||||
size_t samples;
|
||||
QLIST_HEAD (sw_in_listhead, SWVoiceIn) sw_head;
|
||||
int ctl_caps;
|
||||
struct audio_pcm_ops *pcm_ops;
|
||||
@@ -94,12 +97,13 @@ typedef struct HWVoiceIn {
|
||||
|
||||
struct SWVoiceOut {
|
||||
QEMUSoundCard *card;
|
||||
AudioState *s;
|
||||
struct audio_pcm_info info;
|
||||
t_sample *conv;
|
||||
int64_t ratio;
|
||||
struct st_sample *buf;
|
||||
void *rate;
|
||||
int total_hw_samples_mixed;
|
||||
size_t total_hw_samples_mixed;
|
||||
int active;
|
||||
int empty;
|
||||
HWVoiceOut *hw;
|
||||
@@ -111,11 +115,12 @@ struct SWVoiceOut {
|
||||
|
||||
struct SWVoiceIn {
|
||||
QEMUSoundCard *card;
|
||||
AudioState *s;
|
||||
int active;
|
||||
struct audio_pcm_info info;
|
||||
int64_t ratio;
|
||||
void *rate;
|
||||
int total_hw_samples_acquired;
|
||||
size_t total_hw_samples_acquired;
|
||||
struct st_sample *buf;
|
||||
f_sample *clip;
|
||||
HWVoiceIn *hw;
|
||||
@@ -144,14 +149,12 @@ struct audio_driver {
|
||||
struct audio_pcm_ops {
|
||||
int (*init_out)(HWVoiceOut *hw, struct audsettings *as, void *drv_opaque);
|
||||
void (*fini_out)(HWVoiceOut *hw);
|
||||
int (*run_out) (HWVoiceOut *hw, int live);
|
||||
int (*write) (SWVoiceOut *sw, void *buf, int size);
|
||||
size_t (*run_out)(HWVoiceOut *hw, size_t live);
|
||||
int (*ctl_out) (HWVoiceOut *hw, int cmd, ...);
|
||||
|
||||
int (*init_in) (HWVoiceIn *hw, struct audsettings *as, void *drv_opaque);
|
||||
void (*fini_in) (HWVoiceIn *hw);
|
||||
int (*run_in) (HWVoiceIn *hw);
|
||||
int (*read) (SWVoiceIn *sw, void *buf, int size);
|
||||
size_t (*run_in)(HWVoiceIn *hw);
|
||||
int (*ctl_in) (HWVoiceIn *hw, int cmd, ...);
|
||||
};
|
||||
|
||||
@@ -188,6 +191,11 @@ typedef struct AudioState {
|
||||
int nb_hw_voices_in;
|
||||
int vm_running;
|
||||
int64_t period_ticks;
|
||||
|
||||
bool timer_running;
|
||||
uint64_t timer_last;
|
||||
|
||||
QTAILQ_ENTRY(AudioState) list;
|
||||
} AudioState;
|
||||
|
||||
extern const struct mixeng_volume nominal_volume;
|
||||
@@ -200,18 +208,15 @@ audio_driver *audio_driver_lookup(const char *name);
|
||||
void audio_pcm_init_info (struct audio_pcm_info *info, struct audsettings *as);
|
||||
void audio_pcm_info_clear_buf (struct audio_pcm_info *info, void *buf, int len);
|
||||
|
||||
int audio_pcm_sw_write (SWVoiceOut *sw, void *buf, int len);
|
||||
int audio_pcm_hw_get_live_in (HWVoiceIn *hw);
|
||||
size_t audio_pcm_hw_get_live_in(HWVoiceIn *hw);
|
||||
|
||||
int audio_pcm_sw_read (SWVoiceIn *sw, void *buf, int len);
|
||||
|
||||
int audio_pcm_hw_clip_out (HWVoiceOut *hw, void *pcm_buf,
|
||||
int live, int pending);
|
||||
size_t audio_pcm_hw_clip_out(HWVoiceOut *hw, void *pcm_buf,
|
||||
size_t live, size_t pending);
|
||||
|
||||
int audio_bug (const char *funcname, int cond);
|
||||
void *audio_calloc (const char *funcname, int nmemb, size_t size);
|
||||
|
||||
void audio_run (const char *msg);
|
||||
void audio_run(AudioState *s, const char *msg);
|
||||
|
||||
#define VOICE_ENABLE 1
|
||||
#define VOICE_DISABLE 2
|
||||
@@ -219,7 +224,7 @@ void audio_run (const char *msg);
|
||||
|
||||
#define VOICE_VOLUME_CAP (1 << VOICE_VOLUME)
|
||||
|
||||
static inline int audio_ring_dist (int dst, int src, int len)
|
||||
static inline size_t audio_ring_dist(size_t dst, size_t src, size_t len)
|
||||
{
|
||||
return (dst >= src) ? (dst - src) : (len - src + dst);
|
||||
}
|
||||
|
||||
+30
-32
@@ -36,9 +36,9 @@
|
||||
#define HWBUF hw->conv_buf
|
||||
#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 voice_size = glue (drv->voice_size_, TYPE);
|
||||
|
||||
@@ -75,16 +75,16 @@ static void glue (audio_pcm_hw_free_resources_, TYPE) (HW *hw)
|
||||
HWBUF = NULL;
|
||||
}
|
||||
|
||||
static int glue (audio_pcm_hw_alloc_resources_, TYPE) (HW *hw)
|
||||
static bool glue(audio_pcm_hw_alloc_resources_, TYPE)(HW *hw)
|
||||
{
|
||||
HWBUF = audio_calloc(__func__, hw->samples, sizeof(struct st_sample));
|
||||
if (!HWBUF) {
|
||||
dolog ("Could not allocate " NAME " buffer (%d samples)\n",
|
||||
hw->samples);
|
||||
return -1;
|
||||
dolog("Could not allocate " NAME " buffer (%zu samples)\n",
|
||||
hw->samples);
|
||||
return false;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void glue (audio_pcm_sw_free_resources_, TYPE) (SW *sw)
|
||||
@@ -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)
|
||||
{
|
||||
AudioState *s = &glob_audio_state;
|
||||
HW *hw = *hwp;
|
||||
AudioState *s = hw->s;
|
||||
|
||||
if (!hw->sw_head.lh_first) {
|
||||
#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;
|
||||
}
|
||||
|
||||
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) {
|
||||
return hw;
|
||||
}
|
||||
@@ -215,12 +214,10 @@ static HW *glue (audio_pcm_hw_find_any_enabled_, TYPE) (HW *hw)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static HW *glue (audio_pcm_hw_find_specific_, TYPE) (
|
||||
HW *hw,
|
||||
struct audsettings *as
|
||||
)
|
||||
static HW *glue(audio_pcm_hw_find_specific_, TYPE)(AudioState *s, HW *hw,
|
||||
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)) {
|
||||
return hw;
|
||||
}
|
||||
@@ -228,10 +225,10 @@ static HW *glue (audio_pcm_hw_find_specific_, TYPE) (
|
||||
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;
|
||||
AudioState *s = &glob_audio_state;
|
||||
struct audio_driver *drv = s->drv;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
hw->s = s;
|
||||
hw->pcm_ops = drv->pcm_ops;
|
||||
hw->ctl_caps = drv->ctl_caps;
|
||||
|
||||
@@ -267,7 +265,7 @@ static HW *glue (audio_pcm_hw_add_new_, TYPE) (struct audsettings *as)
|
||||
}
|
||||
|
||||
if (audio_bug(__func__, hw->samples <= 0)) {
|
||||
dolog ("hw->samples=%d\n", hw->samples);
|
||||
dolog("hw->samples=%zd\n", hw->samples);
|
||||
goto err1;
|
||||
}
|
||||
|
||||
@@ -281,7 +279,7 @@ static HW *glue (audio_pcm_hw_add_new_, TYPE) (struct audsettings *as)
|
||||
[hw->info.swap_endianness]
|
||||
[audio_bits_to_index (hw->info.bits)];
|
||||
|
||||
if (glue (audio_pcm_hw_alloc_resources_, TYPE) (hw)) {
|
||||
if (!glue(audio_pcm_hw_alloc_resources_, TYPE)(hw)) {
|
||||
goto err1;
|
||||
}
|
||||
|
||||
@@ -328,33 +326,33 @@ AudiodevPerDirectionOptions *glue(audio_get_pdo_, TYPE)(Audiodev *dev)
|
||||
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;
|
||||
AudioState *s = &glob_audio_state;
|
||||
AudiodevPerDirectionOptions *pdo = glue(audio_get_pdo_, TYPE)(s->dev);
|
||||
|
||||
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) {
|
||||
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) {
|
||||
return hw;
|
||||
}
|
||||
|
||||
hw = glue (audio_pcm_hw_add_new_, TYPE) (as);
|
||||
hw = glue(audio_pcm_hw_add_new_, TYPE)(s, as);
|
||||
if (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,
|
||||
struct audsettings *as
|
||||
)
|
||||
@@ -362,7 +360,6 @@ static SW *glue (audio_pcm_create_voice_pair_, TYPE) (
|
||||
SW *sw;
|
||||
HW *hw;
|
||||
struct audsettings hw_as;
|
||||
AudioState *s = &glob_audio_state;
|
||||
AudiodevPerDirectionOptions *pdo = glue(audio_get_pdo_, TYPE)(s->dev);
|
||||
|
||||
if (pdo->fixed_settings) {
|
||||
@@ -378,8 +375,9 @@ static SW *glue (audio_pcm_create_voice_pair_, TYPE) (
|
||||
sw_name ? sw_name : "unknown", sizeof (*sw));
|
||||
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) {
|
||||
goto err2;
|
||||
}
|
||||
@@ -430,7 +428,7 @@ SW *glue (AUD_open_, TYPE) (
|
||||
struct audsettings *as
|
||||
)
|
||||
{
|
||||
AudioState *s = &glob_audio_state;
|
||||
AudioState *s = card->state;
|
||||
AudiodevPerDirectionOptions *pdo = glue(audio_get_pdo_, TYPE)(s->dev);
|
||||
|
||||
if (audio_bug(__func__, !card || !name || !callback_fn || !as)) {
|
||||
@@ -476,7 +474,7 @@ SW *glue (AUD_open_, TYPE) (
|
||||
}
|
||||
}
|
||||
else {
|
||||
sw = glue (audio_pcm_create_voice_pair_, TYPE) (name, as);
|
||||
sw = glue(audio_pcm_create_voice_pair_, TYPE)(s, name, as);
|
||||
if (!sw) {
|
||||
dolog ("Failed to create voice `%s'\n", name);
|
||||
return NULL;
|
||||
|
||||
+6
-12
@@ -43,9 +43,9 @@ typedef struct coreaudioVoiceOut {
|
||||
UInt32 audioDevicePropertyBufferFrameSize;
|
||||
AudioStreamBasicDescription outputStreamBasicDescription;
|
||||
AudioDeviceIOProcID ioprocid;
|
||||
int live;
|
||||
int decr;
|
||||
int rpos;
|
||||
size_t live;
|
||||
size_t decr;
|
||||
size_t rpos;
|
||||
} coreaudioVoiceOut;
|
||||
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
|
||||
@@ -397,9 +397,9 @@ static int coreaudio_unlock (coreaudioVoiceOut *core, const char *fn_name)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int coreaudio_run_out (HWVoiceOut *hw, int live)
|
||||
static size_t coreaudio_run_out(HWVoiceOut *hw, size_t live)
|
||||
{
|
||||
int decr;
|
||||
size_t decr;
|
||||
coreaudioVoiceOut *core = (coreaudioVoiceOut *) hw;
|
||||
|
||||
if (coreaudio_lock (core, "coreaudio_run_out")) {
|
||||
@@ -413,7 +413,7 @@ static int coreaudio_run_out (HWVoiceOut *hw, int live)
|
||||
core->live);
|
||||
}
|
||||
|
||||
decr = audio_MIN (core->decr, live);
|
||||
decr = MIN (core->decr, live);
|
||||
core->decr -= decr;
|
||||
|
||||
core->live = live - decr;
|
||||
@@ -489,11 +489,6 @@ static OSStatus audioDeviceIOProc(
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int coreaudio_write (SWVoiceOut *sw, void *buf, int len)
|
||||
{
|
||||
return audio_pcm_sw_write (sw, buf, len);
|
||||
}
|
||||
|
||||
static int coreaudio_init_out(HWVoiceOut *hw, struct audsettings *as,
|
||||
void *drv_opaque)
|
||||
{
|
||||
@@ -692,7 +687,6 @@ static struct audio_pcm_ops coreaudio_pcm_ops = {
|
||||
.init_out = coreaudio_init_out,
|
||||
.fini_out = coreaudio_fini_out,
|
||||
.run_out = coreaudio_run_out,
|
||||
.write = coreaudio_write,
|
||||
.ctl_out = coreaudio_ctl_out
|
||||
};
|
||||
|
||||
|
||||
+10
-21
@@ -454,24 +454,20 @@ static int dsound_ctl_out (HWVoiceOut *hw, int cmd, ...)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dsound_write (SWVoiceOut *sw, void *buf, int len)
|
||||
{
|
||||
return audio_pcm_sw_write (sw, buf, len);
|
||||
}
|
||||
|
||||
static int dsound_run_out (HWVoiceOut *hw, int live)
|
||||
static size_t dsound_run_out(HWVoiceOut *hw, size_t live)
|
||||
{
|
||||
int err;
|
||||
HRESULT hr;
|
||||
DSoundVoiceOut *ds = (DSoundVoiceOut *) hw;
|
||||
LPDIRECTSOUNDBUFFER dsb = ds->dsound_buffer;
|
||||
int len, hwshift;
|
||||
size_t len;
|
||||
int hwshift;
|
||||
DWORD blen1, blen2;
|
||||
DWORD len1, len2;
|
||||
DWORD decr;
|
||||
DWORD wpos, ppos, old_pos;
|
||||
LPVOID p1, p2;
|
||||
int bufsize;
|
||||
size_t bufsize;
|
||||
dsound *s = ds->s;
|
||||
AudiodevDsoundOptions *dso = &s->dev->u.dsound;
|
||||
|
||||
@@ -538,9 +534,9 @@ static int dsound_run_out (HWVoiceOut *hw, int live)
|
||||
}
|
||||
}
|
||||
|
||||
if (audio_bug(__func__, len < 0 || len > bufsize)) {
|
||||
dolog ("len=%d bufsize=%d old_pos=%ld ppos=%ld\n",
|
||||
len, bufsize, old_pos, ppos);
|
||||
if (audio_bug(__func__, len > bufsize)) {
|
||||
dolog("len=%zu bufsize=%zu old_pos=%ld ppos=%ld\n",
|
||||
len, bufsize, old_pos, ppos);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -645,18 +641,13 @@ static int dsound_ctl_in (HWVoiceIn *hw, int cmd, ...)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dsound_read (SWVoiceIn *sw, void *buf, int len)
|
||||
{
|
||||
return audio_pcm_sw_read (sw, buf, len);
|
||||
}
|
||||
|
||||
static int dsound_run_in (HWVoiceIn *hw)
|
||||
static size_t dsound_run_in(HWVoiceIn *hw)
|
||||
{
|
||||
int err;
|
||||
HRESULT hr;
|
||||
DSoundVoiceIn *ds = (DSoundVoiceIn *) hw;
|
||||
LPDIRECTSOUNDCAPTUREBUFFER dscb = ds->dsound_capture_buffer;
|
||||
int live, len, dead;
|
||||
size_t live, len, dead;
|
||||
DWORD blen1, blen2;
|
||||
DWORD len1, len2;
|
||||
DWORD decr;
|
||||
@@ -707,7 +698,7 @@ static int dsound_run_in (HWVoiceIn *hw)
|
||||
if (!len) {
|
||||
return 0;
|
||||
}
|
||||
len = audio_MIN (len, dead);
|
||||
len = MIN (len, dead);
|
||||
|
||||
err = dsound_lock_in (
|
||||
dscb,
|
||||
@@ -856,13 +847,11 @@ static struct audio_pcm_ops dsound_pcm_ops = {
|
||||
.init_out = dsound_init_out,
|
||||
.fini_out = dsound_fini_out,
|
||||
.run_out = dsound_run_out,
|
||||
.write = dsound_write,
|
||||
.ctl_out = dsound_ctl_out,
|
||||
|
||||
.init_in = dsound_init_in,
|
||||
.fini_in = dsound_fini_in,
|
||||
.run_in = dsound_run_in,
|
||||
.read = dsound_read,
|
||||
.ctl_in = dsound_ctl_in
|
||||
};
|
||||
|
||||
|
||||
+5
-4
@@ -33,6 +33,7 @@ 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);
|
||||
@@ -41,10 +42,10 @@ extern t_sample *mixeng_conv[2][2][2][3];
|
||||
extern f_sample *mixeng_clip[2][2][2][3];
|
||||
|
||||
void *st_rate_start (int inrate, int outrate);
|
||||
void st_rate_flow (void *opaque, struct st_sample *ibuf, struct st_sample *obuf,
|
||||
int *isamp, int *osamp);
|
||||
void st_rate_flow_mix (void *opaque, struct st_sample *ibuf, struct st_sample *obuf,
|
||||
int *isamp, int *osamp);
|
||||
void st_rate_flow(void *opaque, st_sample *ibuf, st_sample *obuf,
|
||||
size_t *isamp, size_t *osamp);
|
||||
void st_rate_flow_mix(void *opaque, st_sample *ibuf, st_sample *obuf,
|
||||
size_t *isamp, size_t *osamp);
|
||||
void st_rate_stop (void *opaque);
|
||||
void mixeng_clear (struct st_sample *buf, int len);
|
||||
void mixeng_volume (struct st_sample *buf, int len, struct mixeng_volume *vol);
|
||||
|
||||
+10
-29
@@ -41,10 +41,10 @@ typedef struct NoVoiceIn {
|
||||
int64_t old_ticks;
|
||||
} NoVoiceIn;
|
||||
|
||||
static int no_run_out (HWVoiceOut *hw, int live)
|
||||
static size_t no_run_out(HWVoiceOut *hw, size_t live)
|
||||
{
|
||||
NoVoiceOut *no = (NoVoiceOut *) hw;
|
||||
int decr, samples;
|
||||
size_t decr, samples;
|
||||
int64_t now;
|
||||
int64_t ticks;
|
||||
int64_t bytes;
|
||||
@@ -52,20 +52,15 @@ static int no_run_out (HWVoiceOut *hw, int live)
|
||||
now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
|
||||
ticks = now - no->old_ticks;
|
||||
bytes = muldiv64(ticks, hw->info.bytes_per_second, NANOSECONDS_PER_SECOND);
|
||||
bytes = audio_MIN(bytes, INT_MAX);
|
||||
bytes = MIN(bytes, SIZE_MAX);
|
||||
samples = bytes >> hw->info.shift;
|
||||
|
||||
no->old_ticks = now;
|
||||
decr = audio_MIN (live, samples);
|
||||
decr = MIN (live, samples);
|
||||
hw->rpos = (hw->rpos + decr) % hw->samples;
|
||||
return decr;
|
||||
}
|
||||
|
||||
static int no_write (SWVoiceOut *sw, void *buf, int len)
|
||||
{
|
||||
return audio_pcm_sw_write(sw, buf, len);
|
||||
}
|
||||
|
||||
static int no_init_out(HWVoiceOut *hw, struct audsettings *as, void *drv_opaque)
|
||||
{
|
||||
audio_pcm_init_info (&hw->info, as);
|
||||
@@ -97,12 +92,12 @@ static void no_fini_in (HWVoiceIn *hw)
|
||||
(void) hw;
|
||||
}
|
||||
|
||||
static int no_run_in (HWVoiceIn *hw)
|
||||
static size_t no_run_in(HWVoiceIn *hw)
|
||||
{
|
||||
NoVoiceIn *no = (NoVoiceIn *) hw;
|
||||
int live = audio_pcm_hw_get_live_in (hw);
|
||||
int dead = hw->samples - live;
|
||||
int samples = 0;
|
||||
size_t live = audio_pcm_hw_get_live_in(hw);
|
||||
size_t dead = hw->samples - live;
|
||||
size_t samples = 0;
|
||||
|
||||
if (dead) {
|
||||
int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
|
||||
@@ -111,25 +106,13 @@ static int no_run_in (HWVoiceIn *hw)
|
||||
muldiv64(ticks, hw->info.bytes_per_second, NANOSECONDS_PER_SECOND);
|
||||
|
||||
no->old_ticks = now;
|
||||
bytes = audio_MIN (bytes, INT_MAX);
|
||||
bytes = MIN (bytes, SIZE_MAX);
|
||||
samples = bytes >> hw->info.shift;
|
||||
samples = audio_MIN (samples, dead);
|
||||
samples = MIN (samples, dead);
|
||||
}
|
||||
return samples;
|
||||
}
|
||||
|
||||
static int no_read (SWVoiceIn *sw, void *buf, int size)
|
||||
{
|
||||
/* use custom code here instead of audio_pcm_sw_read() to avoid
|
||||
* useless resampling/mixing */
|
||||
int samples = size >> sw->info.shift;
|
||||
int total = sw->hw->total_samples_captured - sw->total_hw_samples_acquired;
|
||||
int to_clear = audio_MIN (samples, total);
|
||||
sw->total_hw_samples_acquired += total;
|
||||
audio_pcm_info_clear_buf (&sw->info, buf, to_clear);
|
||||
return to_clear << sw->info.shift;
|
||||
}
|
||||
|
||||
static int no_ctl_in (HWVoiceIn *hw, int cmd, ...)
|
||||
{
|
||||
(void) hw;
|
||||
@@ -151,13 +134,11 @@ static struct audio_pcm_ops no_pcm_ops = {
|
||||
.init_out = no_init_out,
|
||||
.fini_out = no_fini_out,
|
||||
.run_out = no_run_out,
|
||||
.write = no_write,
|
||||
.ctl_out = no_ctl_out,
|
||||
|
||||
.init_in = no_init_in,
|
||||
.fini_in = no_fini_in,
|
||||
.run_in = no_run_in,
|
||||
.read = no_read,
|
||||
.ctl_in = no_ctl_in
|
||||
};
|
||||
|
||||
|
||||
+32
-43
@@ -110,33 +110,28 @@ static void oss_anal_close (int *fdp)
|
||||
|
||||
static void oss_helper_poll_out (void *opaque)
|
||||
{
|
||||
(void) opaque;
|
||||
audio_run ("oss_poll_out");
|
||||
AudioState *s = opaque;
|
||||
audio_run(s, "oss_poll_out");
|
||||
}
|
||||
|
||||
static void oss_helper_poll_in (void *opaque)
|
||||
{
|
||||
(void) opaque;
|
||||
audio_run ("oss_poll_in");
|
||||
AudioState *s = opaque;
|
||||
audio_run(s, "oss_poll_in");
|
||||
}
|
||||
|
||||
static void oss_poll_out (HWVoiceOut *hw)
|
||||
{
|
||||
OSSVoiceOut *oss = (OSSVoiceOut *) hw;
|
||||
|
||||
qemu_set_fd_handler (oss->fd, NULL, oss_helper_poll_out, NULL);
|
||||
qemu_set_fd_handler(oss->fd, NULL, oss_helper_poll_out, hw->s);
|
||||
}
|
||||
|
||||
static void oss_poll_in (HWVoiceIn *hw)
|
||||
{
|
||||
OSSVoiceIn *oss = (OSSVoiceIn *) hw;
|
||||
|
||||
qemu_set_fd_handler (oss->fd, oss_helper_poll_in, NULL, NULL);
|
||||
}
|
||||
|
||||
static int oss_write (SWVoiceOut *sw, void *buf, int len)
|
||||
{
|
||||
return audio_pcm_sw_write (sw, buf, len);
|
||||
qemu_set_fd_handler(oss->fd, oss_helper_poll_in, NULL, hw->s);
|
||||
}
|
||||
|
||||
static int aud_to_ossfmt (AudioFormat fmt, int endianness)
|
||||
@@ -388,7 +383,7 @@ static void oss_write_pending (OSSVoiceOut *oss)
|
||||
int samples_written;
|
||||
ssize_t bytes_written;
|
||||
int samples_till_end = hw->samples - oss->wpos;
|
||||
int samples_to_write = audio_MIN (oss->pending, samples_till_end);
|
||||
int samples_to_write = MIN (oss->pending, samples_till_end);
|
||||
int bytes_to_write = samples_to_write << hw->info.shift;
|
||||
void *pcm = advance (oss->pcm_buf, oss->wpos << hw->info.shift);
|
||||
|
||||
@@ -416,13 +411,14 @@ static void oss_write_pending (OSSVoiceOut *oss)
|
||||
}
|
||||
}
|
||||
|
||||
static int oss_run_out (HWVoiceOut *hw, int live)
|
||||
static size_t oss_run_out(HWVoiceOut *hw, size_t live)
|
||||
{
|
||||
OSSVoiceOut *oss = (OSSVoiceOut *) hw;
|
||||
int err, decr;
|
||||
int err;
|
||||
size_t decr;
|
||||
struct audio_buf_info abinfo;
|
||||
struct count_info cntinfo;
|
||||
int bufsize;
|
||||
size_t bufsize;
|
||||
|
||||
bufsize = hw->samples << hw->info.shift;
|
||||
|
||||
@@ -437,7 +433,7 @@ static int oss_run_out (HWVoiceOut *hw, int live)
|
||||
|
||||
pos = hw->rpos << hw->info.shift;
|
||||
bytes = audio_ring_dist (cntinfo.ptr, pos, bufsize);
|
||||
decr = audio_MIN (bytes >> hw->info.shift, live);
|
||||
decr = MIN (bytes >> hw->info.shift, live);
|
||||
}
|
||||
else {
|
||||
err = ioctl (oss->fd, SNDCTL_DSP_GETOSPACE, &abinfo);
|
||||
@@ -456,7 +452,7 @@ static int oss_run_out (HWVoiceOut *hw, int live)
|
||||
return 0;
|
||||
}
|
||||
|
||||
decr = audio_MIN (abinfo.bytes >> hw->info.shift, live);
|
||||
decr = MIN (abinfo.bytes >> hw->info.shift, live);
|
||||
if (!decr) {
|
||||
return 0;
|
||||
}
|
||||
@@ -481,8 +477,8 @@ static void oss_fini_out (HWVoiceOut *hw)
|
||||
if (oss->mmapped) {
|
||||
err = munmap (oss->pcm_buf, hw->samples << hw->info.shift);
|
||||
if (err) {
|
||||
oss_logerr (errno, "Failed to unmap buffer %p, size %d\n",
|
||||
oss->pcm_buf, hw->samples << hw->info.shift);
|
||||
oss_logerr(errno, "Failed to unmap buffer %p, size %zu\n",
|
||||
oss->pcm_buf, hw->samples << hw->info.shift);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -548,8 +544,8 @@ static int oss_init_out(HWVoiceOut *hw, struct audsettings *as,
|
||||
0
|
||||
);
|
||||
if (oss->pcm_buf == MAP_FAILED) {
|
||||
oss_logerr (errno, "Failed to map %d bytes of DAC\n",
|
||||
hw->samples << hw->info.shift);
|
||||
oss_logerr(errno, "Failed to map %zu bytes of DAC\n",
|
||||
hw->samples << hw->info.shift);
|
||||
}
|
||||
else {
|
||||
int err;
|
||||
@@ -573,8 +569,8 @@ static int oss_init_out(HWVoiceOut *hw, struct audsettings *as,
|
||||
if (!oss->mmapped) {
|
||||
err = munmap (oss->pcm_buf, hw->samples << hw->info.shift);
|
||||
if (err) {
|
||||
oss_logerr (errno, "Failed to unmap buffer %p size %d\n",
|
||||
oss->pcm_buf, hw->samples << hw->info.shift);
|
||||
oss_logerr(errno, "Failed to unmap buffer %p size %zu\n",
|
||||
oss->pcm_buf, hw->samples << hw->info.shift);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -586,7 +582,7 @@ static int oss_init_out(HWVoiceOut *hw, struct audsettings *as,
|
||||
1 << hw->info.shift);
|
||||
if (!oss->pcm_buf) {
|
||||
dolog (
|
||||
"Could not allocate DAC buffer (%d samples, each %d bytes)\n",
|
||||
"Could not allocate DAC buffer (%zu samples, each %d bytes)\n",
|
||||
hw->samples,
|
||||
1 << hw->info.shift
|
||||
);
|
||||
@@ -698,8 +694,8 @@ static int oss_init_in(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque)
|
||||
hw->samples = (obt.nfrags * obt.fragsize) >> hw->info.shift;
|
||||
oss->pcm_buf = audio_calloc(__func__, hw->samples, 1 << hw->info.shift);
|
||||
if (!oss->pcm_buf) {
|
||||
dolog ("Could not allocate ADC buffer (%d samples, each %d bytes)\n",
|
||||
hw->samples, 1 << hw->info.shift);
|
||||
dolog("Could not allocate ADC buffer (%zu samples, each %d bytes)\n",
|
||||
hw->samples, 1 << hw->info.shift);
|
||||
oss_anal_close (&fd);
|
||||
return -1;
|
||||
}
|
||||
@@ -719,17 +715,17 @@ static void oss_fini_in (HWVoiceIn *hw)
|
||||
oss->pcm_buf = NULL;
|
||||
}
|
||||
|
||||
static int oss_run_in (HWVoiceIn *hw)
|
||||
static size_t oss_run_in(HWVoiceIn *hw)
|
||||
{
|
||||
OSSVoiceIn *oss = (OSSVoiceIn *) hw;
|
||||
int hwshift = hw->info.shift;
|
||||
int i;
|
||||
int live = audio_pcm_hw_get_live_in (hw);
|
||||
int dead = hw->samples - live;
|
||||
size_t live = audio_pcm_hw_get_live_in (hw);
|
||||
size_t dead = hw->samples - live;
|
||||
size_t read_samples = 0;
|
||||
struct {
|
||||
int add;
|
||||
int len;
|
||||
size_t add;
|
||||
size_t len;
|
||||
} bufs[2] = {
|
||||
{ .add = hw->wpos, .len = 0 },
|
||||
{ .add = 0, .len = 0 }
|
||||
@@ -756,9 +752,9 @@ static int oss_run_in (HWVoiceIn *hw)
|
||||
|
||||
if (nread > 0) {
|
||||
if (nread & hw->info.align) {
|
||||
dolog ("warning: Misaligned read %zd (requested %d), "
|
||||
"alignment %d\n", nread, bufs[i].add << hwshift,
|
||||
hw->info.align + 1);
|
||||
dolog("warning: Misaligned read %zd (requested %zu), "
|
||||
"alignment %d\n", nread, bufs[i].add << hwshift,
|
||||
hw->info.align + 1);
|
||||
}
|
||||
read_samples += nread >> hwshift;
|
||||
hw->conv (hw->conv_buf + bufs[i].add, p, nread >> hwshift);
|
||||
@@ -771,9 +767,9 @@ static int oss_run_in (HWVoiceIn *hw)
|
||||
case EAGAIN:
|
||||
break;
|
||||
default:
|
||||
oss_logerr (
|
||||
oss_logerr(
|
||||
errno,
|
||||
"Failed to read %d bytes of audio (to %p)\n",
|
||||
"Failed to read %zu bytes of audio (to %p)\n",
|
||||
bufs[i].len, p
|
||||
);
|
||||
break;
|
||||
@@ -788,11 +784,6 @@ static int oss_run_in (HWVoiceIn *hw)
|
||||
return read_samples;
|
||||
}
|
||||
|
||||
static int oss_read (SWVoiceIn *sw, void *buf, int size)
|
||||
{
|
||||
return audio_pcm_sw_read (sw, buf, size);
|
||||
}
|
||||
|
||||
static int oss_ctl_in (HWVoiceIn *hw, int cmd, ...)
|
||||
{
|
||||
OSSVoiceIn *oss = (OSSVoiceIn *) hw;
|
||||
@@ -855,13 +846,11 @@ static struct audio_pcm_ops oss_pcm_ops = {
|
||||
.init_out = oss_init_out,
|
||||
.fini_out = oss_fini_out,
|
||||
.run_out = oss_run_out,
|
||||
.write = oss_write,
|
||||
.ctl_out = oss_ctl_out,
|
||||
|
||||
.init_in = oss_init_in,
|
||||
.fini_in = oss_fini_in,
|
||||
.run_in = oss_run_in,
|
||||
.read = oss_read,
|
||||
.ctl_in = oss_ctl_in
|
||||
};
|
||||
|
||||
|
||||
+240
-181
File diff suppressed because it is too large
Load Diff
@@ -28,7 +28,7 @@
|
||||
* Return number of samples processed.
|
||||
*/
|
||||
void NAME (void *opaque, struct st_sample *ibuf, struct st_sample *obuf,
|
||||
int *isamp, int *osamp)
|
||||
size_t *isamp, size_t *osamp)
|
||||
{
|
||||
struct rate *rate = opaque;
|
||||
struct st_sample *istart, *iend;
|
||||
|
||||
+12
-18
@@ -41,8 +41,8 @@
|
||||
|
||||
typedef struct SDLVoiceOut {
|
||||
HWVoiceOut hw;
|
||||
int live;
|
||||
int decr;
|
||||
size_t live;
|
||||
size_t decr;
|
||||
} SDLVoiceOut;
|
||||
|
||||
static struct SDLAudioState {
|
||||
@@ -184,22 +184,22 @@ static void sdl_callback (void *opaque, Uint8 *buf, int len)
|
||||
SDLVoiceOut *sdl = opaque;
|
||||
SDLAudioState *s = &glob_sdl;
|
||||
HWVoiceOut *hw = &sdl->hw;
|
||||
int samples = len >> hw->info.shift;
|
||||
int to_mix, decr;
|
||||
size_t samples = len >> hw->info.shift;
|
||||
size_t to_mix, decr;
|
||||
|
||||
if (s->exit || !sdl->live) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* dolog ("in callback samples=%d live=%d\n", samples, sdl->live); */
|
||||
/* dolog ("in callback samples=%zu live=%zu\n", samples, sdl->live); */
|
||||
|
||||
to_mix = audio_MIN(samples, sdl->live);
|
||||
to_mix = MIN(samples, sdl->live);
|
||||
decr = to_mix;
|
||||
while (to_mix) {
|
||||
int chunk = audio_MIN(to_mix, hw->samples - hw->rpos);
|
||||
size_t chunk = 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); */
|
||||
/* dolog ("in callback to_mix %zu, chunk %zu\n", to_mix, chunk); */
|
||||
hw->clip(buf, src, chunk);
|
||||
hw->rpos = (hw->rpos + chunk) % hw->samples;
|
||||
to_mix -= chunk;
|
||||
@@ -209,7 +209,7 @@ static void sdl_callback (void *opaque, Uint8 *buf, int len)
|
||||
sdl->live -= decr;
|
||||
sdl->decr += decr;
|
||||
|
||||
/* dolog ("done len=%d\n", len); */
|
||||
/* dolog ("done len=%zu\n", len); */
|
||||
|
||||
/* SDL2 does not clear the remaining buffer for us, so do it on our own */
|
||||
if (samples) {
|
||||
@@ -217,14 +217,9 @@ static void sdl_callback (void *opaque, Uint8 *buf, int len)
|
||||
}
|
||||
}
|
||||
|
||||
static int sdl_write_out (SWVoiceOut *sw, void *buf, int len)
|
||||
static size_t sdl_run_out(HWVoiceOut *hw, size_t live)
|
||||
{
|
||||
return audio_pcm_sw_write (sw, buf, len);
|
||||
}
|
||||
|
||||
static int sdl_run_out (HWVoiceOut *hw, int live)
|
||||
{
|
||||
int decr;
|
||||
size_t decr;
|
||||
SDLVoiceOut *sdl = (SDLVoiceOut *) hw;
|
||||
|
||||
SDL_LockAudio();
|
||||
@@ -236,7 +231,7 @@ static int sdl_run_out (HWVoiceOut *hw, int live)
|
||||
sdl->live);
|
||||
}
|
||||
|
||||
decr = audio_MIN (sdl->decr, live);
|
||||
decr = MIN (sdl->decr, live);
|
||||
sdl->decr -= decr;
|
||||
|
||||
sdl->live = live;
|
||||
@@ -342,7 +337,6 @@ static struct audio_pcm_ops sdl_pcm_ops = {
|
||||
.init_out = sdl_init_out,
|
||||
.fini_out = sdl_fini_out,
|
||||
.run_out = sdl_run_out,
|
||||
.write = sdl_write_out,
|
||||
.ctl_out = sdl_ctl_out,
|
||||
};
|
||||
|
||||
|
||||
+11
-23
@@ -152,31 +152,31 @@ static void line_out_fini (HWVoiceOut *hw)
|
||||
spice_server_remove_interface (&out->sin.base);
|
||||
}
|
||||
|
||||
static int line_out_run (HWVoiceOut *hw, int live)
|
||||
static size_t line_out_run (HWVoiceOut *hw, size_t live)
|
||||
{
|
||||
SpiceVoiceOut *out = container_of (hw, SpiceVoiceOut, hw);
|
||||
int rpos, decr;
|
||||
int samples;
|
||||
size_t rpos, decr;
|
||||
size_t samples;
|
||||
|
||||
if (!live) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
decr = rate_get_samples (&hw->info, &out->rate);
|
||||
decr = audio_MIN (live, decr);
|
||||
decr = MIN (live, decr);
|
||||
|
||||
samples = decr;
|
||||
rpos = hw->rpos;
|
||||
while (samples) {
|
||||
int left_till_end_samples = hw->samples - rpos;
|
||||
int len = audio_MIN (samples, left_till_end_samples);
|
||||
int len = MIN (samples, left_till_end_samples);
|
||||
|
||||
if (!out->frame) {
|
||||
spice_server_playback_get_buffer (&out->sin, &out->frame, &out->fsize);
|
||||
out->fpos = out->frame;
|
||||
}
|
||||
if (out->frame) {
|
||||
len = audio_MIN (len, out->fsize);
|
||||
len = MIN (len, out->fsize);
|
||||
hw->clip (out->fpos, hw->mix_buf + rpos, len);
|
||||
out->fsize -= len;
|
||||
out->fpos += len;
|
||||
@@ -192,11 +192,6 @@ static int line_out_run (HWVoiceOut *hw, int live)
|
||||
return decr;
|
||||
}
|
||||
|
||||
static int line_out_write (SWVoiceOut *sw, void *buf, int len)
|
||||
{
|
||||
return audio_pcm_sw_write (sw, buf, len);
|
||||
}
|
||||
|
||||
static int line_out_ctl (HWVoiceOut *hw, int cmd, ...)
|
||||
{
|
||||
SpiceVoiceOut *out = container_of (hw, SpiceVoiceOut, hw);
|
||||
@@ -280,12 +275,12 @@ static void line_in_fini (HWVoiceIn *hw)
|
||||
spice_server_remove_interface (&in->sin.base);
|
||||
}
|
||||
|
||||
static int line_in_run (HWVoiceIn *hw)
|
||||
static size_t line_in_run(HWVoiceIn *hw)
|
||||
{
|
||||
SpiceVoiceIn *in = container_of (hw, SpiceVoiceIn, hw);
|
||||
int num_samples;
|
||||
size_t num_samples;
|
||||
int ready;
|
||||
int len[2];
|
||||
size_t len[2];
|
||||
uint64_t delta_samp;
|
||||
const uint32_t *samples;
|
||||
|
||||
@@ -294,7 +289,7 @@ static int line_in_run (HWVoiceIn *hw)
|
||||
}
|
||||
|
||||
delta_samp = rate_get_samples (&hw->info, &in->rate);
|
||||
num_samples = audio_MIN (num_samples, delta_samp);
|
||||
num_samples = MIN (num_samples, delta_samp);
|
||||
|
||||
ready = spice_server_record_get_samples (&in->sin, in->samples, num_samples);
|
||||
samples = in->samples;
|
||||
@@ -304,7 +299,7 @@ static int line_in_run (HWVoiceIn *hw)
|
||||
ready = LINE_IN_SAMPLES;
|
||||
}
|
||||
|
||||
num_samples = audio_MIN (ready, num_samples);
|
||||
num_samples = MIN (ready, num_samples);
|
||||
|
||||
if (hw->wpos + num_samples > hw->samples) {
|
||||
len[0] = hw->samples - hw->wpos;
|
||||
@@ -325,11 +320,6 @@ static int line_in_run (HWVoiceIn *hw)
|
||||
return num_samples;
|
||||
}
|
||||
|
||||
static int line_in_read (SWVoiceIn *sw, void *buf, int size)
|
||||
{
|
||||
return audio_pcm_sw_read (sw, buf, size);
|
||||
}
|
||||
|
||||
static int line_in_ctl (HWVoiceIn *hw, int cmd, ...)
|
||||
{
|
||||
SpiceVoiceIn *in = container_of (hw, SpiceVoiceIn, hw);
|
||||
@@ -377,13 +367,11 @@ static struct audio_pcm_ops audio_callbacks = {
|
||||
.init_out = line_out_init,
|
||||
.fini_out = line_out_fini,
|
||||
.run_out = line_out_run,
|
||||
.write = line_out_write,
|
||||
.ctl_out = line_out_ctl,
|
||||
|
||||
.init_in = line_in_init,
|
||||
.fini_in = line_in_fini,
|
||||
.run_in = line_in_run,
|
||||
.read = line_in_read,
|
||||
.ctl_in = line_in_ctl,
|
||||
};
|
||||
|
||||
|
||||
+6
-12
@@ -40,10 +40,10 @@ typedef struct WAVVoiceOut {
|
||||
int total_samples;
|
||||
} WAVVoiceOut;
|
||||
|
||||
static int wav_run_out (HWVoiceOut *hw, int live)
|
||||
static size_t wav_run_out(HWVoiceOut *hw, size_t live)
|
||||
{
|
||||
WAVVoiceOut *wav = (WAVVoiceOut *) hw;
|
||||
int rpos, decr, samples;
|
||||
size_t rpos, decr, samples;
|
||||
uint8_t *dst;
|
||||
struct st_sample *src;
|
||||
int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
|
||||
@@ -59,12 +59,12 @@ static int wav_run_out (HWVoiceOut *hw, int live)
|
||||
}
|
||||
|
||||
wav->old_ticks = now;
|
||||
decr = audio_MIN (live, samples);
|
||||
decr = MIN (live, samples);
|
||||
samples = decr;
|
||||
rpos = hw->rpos;
|
||||
while (samples) {
|
||||
int left_till_end_samples = hw->samples - rpos;
|
||||
int convert_samples = audio_MIN (samples, left_till_end_samples);
|
||||
int convert_samples = MIN (samples, left_till_end_samples);
|
||||
|
||||
src = hw->mix_buf + rpos;
|
||||
dst = advance (wav->pcm_buf, rpos << hw->info.shift);
|
||||
@@ -84,11 +84,6 @@ static int wav_run_out (HWVoiceOut *hw, int live)
|
||||
return decr;
|
||||
}
|
||||
|
||||
static int wav_write_out (SWVoiceOut *sw, void *buf, int len)
|
||||
{
|
||||
return audio_pcm_sw_write (sw, buf, len);
|
||||
}
|
||||
|
||||
/* VICE code: Store number as little endian. */
|
||||
static void le_store (uint8_t *buf, uint32_t val, int len)
|
||||
{
|
||||
@@ -144,8 +139,8 @@ static int wav_init_out(HWVoiceOut *hw, struct audsettings *as,
|
||||
hw->samples = 1024;
|
||||
wav->pcm_buf = audio_calloc(__func__, hw->samples, 1 << hw->info.shift);
|
||||
if (!wav->pcm_buf) {
|
||||
dolog ("Could not allocate buffer (%d bytes)\n",
|
||||
hw->samples << hw->info.shift);
|
||||
dolog("Could not allocate buffer (%zu bytes)\n",
|
||||
hw->samples << hw->info.shift);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -240,7 +235,6 @@ static struct audio_pcm_ops wav_pcm_ops = {
|
||||
.init_out = wav_init_out,
|
||||
.fini_out = wav_fini_out,
|
||||
.run_out = wav_run_out,
|
||||
.write = wav_write_out,
|
||||
.ctl_out = wav_ctl_out,
|
||||
};
|
||||
|
||||
|
||||
+3
-3
@@ -104,8 +104,8 @@ static struct capture_ops wav_capture_ops = {
|
||||
.info = wav_capture_info
|
||||
};
|
||||
|
||||
int wav_start_capture (CaptureState *s, const char *path, int freq,
|
||||
int bits, int nchannels)
|
||||
int wav_start_capture(AudioState *state, CaptureState *s, const char *path,
|
||||
int freq, int bits, int nchannels)
|
||||
{
|
||||
WAVState *wav;
|
||||
uint8_t hdr[] = {
|
||||
@@ -170,7 +170,7 @@ int wav_start_capture (CaptureState *s, const char *path, int freq,
|
||||
goto error_free;
|
||||
}
|
||||
|
||||
cap = AUD_add_capture (&as, &ops, wav);
|
||||
cap = AUD_add_capture(state, &as, &ops, wav);
|
||||
if (!cap) {
|
||||
error_report("Failed to add audio capture");
|
||||
goto error_free;
|
||||
|
||||
+6
-5
@@ -819,16 +819,17 @@ ETEXI
|
||||
|
||||
{
|
||||
.name = "wavcapture",
|
||||
.args_type = "path:F,freq:i?,bits:i?,nchannels:i?",
|
||||
.params = "path [frequency [bits [channels]]]",
|
||||
.args_type = "path:F,audiodev:s,freq:i?,bits:i?,nchannels:i?",
|
||||
.params = "path audiodev [frequency [bits [channels]]]",
|
||||
.help = "capture audio to a wave file (default frequency=44100 bits=16 channels=2)",
|
||||
.cmd = hmp_wavcapture,
|
||||
},
|
||||
STEXI
|
||||
@item wavcapture @var{filename} [@var{frequency} [@var{bits} [@var{channels}]]]
|
||||
@item wavcapture @var{filename} @var{audiodev} [@var{frequency} [@var{bits} [@var{channels}]]]
|
||||
@findex wavcapture
|
||||
Capture audio into @var{filename}. Using sample rate @var{frequency}
|
||||
bits per sample @var{bits} and number of channels @var{channels}.
|
||||
Capture audio into @var{filename} from @var{audiodev}, using sample rate
|
||||
@var{frequency} bits per sample @var{bits} and number of channels
|
||||
@var{channels}.
|
||||
|
||||
Defaults:
|
||||
@itemize @minus
|
||||
|
||||
+6
-5
@@ -965,7 +965,7 @@ static int write_audio (AC97LinkState *s, AC97BusMasterRegs *r,
|
||||
uint32_t temp = r->picb << 1;
|
||||
uint32_t written = 0;
|
||||
int to_copy = 0;
|
||||
temp = audio_MIN (temp, max);
|
||||
temp = MIN (temp, max);
|
||||
|
||||
if (!temp) {
|
||||
*stop = 1;
|
||||
@@ -974,7 +974,7 @@ static int write_audio (AC97LinkState *s, AC97BusMasterRegs *r,
|
||||
|
||||
while (temp) {
|
||||
int copied;
|
||||
to_copy = audio_MIN (temp, sizeof (tmpbuf));
|
||||
to_copy = MIN (temp, sizeof (tmpbuf));
|
||||
pci_dma_read (&s->dev, addr, tmpbuf, to_copy);
|
||||
copied = AUD_write (s->voice_po, tmpbuf, to_copy);
|
||||
dolog ("write_audio max=%x to_copy=%x copied=%x\n",
|
||||
@@ -1020,7 +1020,7 @@ static void write_bup (AC97LinkState *s, int elapsed)
|
||||
}
|
||||
|
||||
while (elapsed) {
|
||||
int temp = audio_MIN (elapsed, sizeof (s->silence));
|
||||
int temp = MIN (elapsed, sizeof (s->silence));
|
||||
while (temp) {
|
||||
int copied = AUD_write (s->voice_po, s->silence, temp);
|
||||
if (!copied)
|
||||
@@ -1041,7 +1041,7 @@ static int read_audio (AC97LinkState *s, AC97BusMasterRegs *r,
|
||||
int to_copy = 0;
|
||||
SWVoiceIn *voice = (r - s->bm_regs) == MC_INDEX ? s->voice_mc : s->voice_pi;
|
||||
|
||||
temp = audio_MIN (temp, max);
|
||||
temp = MIN (temp, max);
|
||||
|
||||
if (!temp) {
|
||||
*stop = 1;
|
||||
@@ -1050,7 +1050,7 @@ static int read_audio (AC97LinkState *s, AC97BusMasterRegs *r,
|
||||
|
||||
while (temp) {
|
||||
int acquired;
|
||||
to_copy = audio_MIN (temp, sizeof (tmpbuf));
|
||||
to_copy = MIN (temp, sizeof (tmpbuf));
|
||||
acquired = AUD_read (voice, tmpbuf, to_copy);
|
||||
if (!acquired) {
|
||||
*stop = 1;
|
||||
@@ -1410,6 +1410,7 @@ static int ac97_init (PCIBus *bus)
|
||||
}
|
||||
|
||||
static Property ac97_properties[] = {
|
||||
DEFINE_AUDIO_PROPERTIES(AC97LinkState, card),
|
||||
DEFINE_PROP_UINT32 ("use_broken_id", AC97LinkState, use_broken_id, 0),
|
||||
DEFINE_PROP_END_OF_LIST (),
|
||||
};
|
||||
|
||||
+3
-2
@@ -195,7 +195,7 @@ static void adlib_callback (void *opaque, int free)
|
||||
return;
|
||||
}
|
||||
|
||||
to_play = audio_MIN (s->left, samples);
|
||||
to_play = MIN (s->left, samples);
|
||||
while (to_play) {
|
||||
written = write_audio (s, to_play);
|
||||
|
||||
@@ -210,7 +210,7 @@ static void adlib_callback (void *opaque, int free)
|
||||
}
|
||||
}
|
||||
|
||||
samples = audio_MIN (samples, s->samples - s->pos);
|
||||
samples = MIN (samples, s->samples - s->pos);
|
||||
if (!samples) {
|
||||
return;
|
||||
}
|
||||
@@ -299,6 +299,7 @@ static void adlib_realizefn (DeviceState *dev, Error **errp)
|
||||
}
|
||||
|
||||
static Property adlib_properties[] = {
|
||||
DEFINE_AUDIO_PROPERTIES(AdlibState, card),
|
||||
DEFINE_PROP_UINT32 ("iobase", AdlibState, port, 0x220),
|
||||
DEFINE_PROP_UINT32 ("freq", AdlibState, freq, 44100),
|
||||
DEFINE_PROP_END_OF_LIST (),
|
||||
|
||||
+3
-2
@@ -536,7 +536,7 @@ static int cs_write_audio (CSState *s, int nchan, int dma_pos,
|
||||
int copied;
|
||||
size_t to_copy;
|
||||
|
||||
to_copy = audio_MIN (temp, left);
|
||||
to_copy = MIN (temp, left);
|
||||
if (to_copy > sizeof (tmpbuf)) {
|
||||
to_copy = sizeof (tmpbuf);
|
||||
}
|
||||
@@ -579,7 +579,7 @@ static int cs_dma_read (void *opaque, int nchan, int dma_pos, int dma_len)
|
||||
till = (s->dregs[Playback_Lower_Base_Count]
|
||||
| (s->dregs[Playback_Upper_Base_Count] << 8)) << s->shift;
|
||||
till -= s->transferred;
|
||||
copy = audio_MIN (till, copy);
|
||||
copy = MIN (till, copy);
|
||||
}
|
||||
|
||||
if ((copy <= 0) || (dma_len <= 0)) {
|
||||
@@ -690,6 +690,7 @@ static int cs4231a_init (ISABus *bus)
|
||||
}
|
||||
|
||||
static Property cs4231a_properties[] = {
|
||||
DEFINE_AUDIO_PROPERTIES(CSState, card),
|
||||
DEFINE_PROP_UINT32 ("iobase", CSState, port, 0x534),
|
||||
DEFINE_PROP_UINT32 ("irq", CSState, irq, 9),
|
||||
DEFINE_PROP_UINT32 ("dma", CSState, dma, 3),
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user