diff options
Diffstat (limited to 'audio/audio_int.h')
-rw-r--r-- | audio/audio_int.h | 196 |
1 files changed, 124 insertions, 72 deletions
diff --git a/audio/audio_int.h b/audio/audio_int.h index 244b454012..2d079d00a2 100644 --- a/audio/audio_int.h +++ b/audio/audio_int.h @@ -31,23 +31,11 @@ #endif #include "mixeng.h" -struct audio_pcm_ops; - -typedef enum { - AUD_OPT_INT, - AUD_OPT_FMT, - AUD_OPT_STR, - AUD_OPT_BOOL -} audio_option_tag_e; +#ifdef CONFIG_GIO +#include <gio/gio.h> +#endif -struct audio_option { - const char *name; - audio_option_tag_e tag; - void *valp; - const char *descr; - int *overriddenp; - int overridden; -}; +struct audio_pcm_ops; struct audio_callback { void *opaque; @@ -56,66 +44,73 @@ struct audio_callback { struct audio_pcm_info { int bits; - int sign; + bool is_signed; + bool is_float; int freq; int nchannels; - int align; - int shift; + int bytes_per_frame; int bytes_per_second; int swap_endianness; }; +typedef struct AudioState AudioState; typedef struct SWVoiceCap SWVoiceCap; +typedef struct STSampleBuffer { + size_t pos, size; + st_sample *buffer; +} STSampleBuffer; + typedef struct HWVoiceOut { + AudioState *s; int enabled; int poll_mode; int pending_disable; struct audio_pcm_info info; f_sample *clip; - - int rpos; uint64_t ts_helper; - struct st_sample *mix_buf; + STSampleBuffer mix_buf; + void *buf_emul; + size_t pos_emul, pending_emul, size_emul; - int samples; + size_t samples; QLIST_HEAD (sw_out_listhead, SWVoiceOut) sw_head; QLIST_HEAD (sw_cap_listhead, SWVoiceCap) cap_head; - int ctl_caps; struct audio_pcm_ops *pcm_ops; QLIST_ENTRY (HWVoiceOut) entries; } 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 total_samples_captured; uint64_t ts_helper; - struct st_sample *conv_buf; + STSampleBuffer conv_buf; + void *buf_emul; + size_t pos_emul, pending_emul, size_emul; - int samples; + size_t samples; QLIST_HEAD (sw_in_listhead, SWVoiceIn) sw_head; - int ctl_caps; struct audio_pcm_ops *pcm_ops; QLIST_ENTRY (HWVoiceIn) entries; } HWVoiceIn; struct SWVoiceOut { QEMUSoundCard *card; + AudioState *s; struct audio_pcm_info info; t_sample *conv; - int64_t ratio; - struct st_sample *buf; + STSampleBuffer resample_buf; void *rate; - int total_hw_samples_mixed; + size_t total_hw_samples_mixed; int active; int empty; HWVoiceOut *hw; @@ -127,12 +122,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; - struct st_sample *buf; + size_t total_hw_samples_acquired; + STSampleBuffer resample_buf; f_sample *clip; HWVoiceIn *hw; char *name; @@ -145,33 +140,63 @@ typedef struct audio_driver audio_driver; struct audio_driver { const char *name; const char *descr; - struct audio_option *options; - void *(*init) (void); + void *(*init) (Audiodev *, Error **); void (*fini) (void *); +#ifdef CONFIG_GIO + void (*set_dbus_server) (AudioState *s, GDBusObjectManagerServer *manager, bool p2p); +#endif struct audio_pcm_ops *pcm_ops; - int can_be_default; int max_voices_out; int max_voices_in; - int voice_size_out; - int voice_size_in; - int ctl_caps; + size_t voice_size_out; + size_t voice_size_in; QLIST_ENTRY(audio_driver) next; }; 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); - 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); - int (*ctl_in) (HWVoiceIn *hw, int cmd, ...); + int (*init_out)(HWVoiceOut *hw, audsettings *as, void *drv_opaque); + void (*fini_out)(HWVoiceOut *hw); + size_t (*write) (HWVoiceOut *hw, void *buf, size_t size); + void (*run_buffer_out)(HWVoiceOut *hw); + /* + * Get the free output buffer size. This is an upper limit. The size + * returned by function get_buffer_out may be smaller. + */ + size_t (*buffer_get_free)(HWVoiceOut *hw); + /* + * get a buffer that after later can be passed to put_buffer_out; optional + * returns the buffer, and writes it's size to size (in bytes) + */ + void *(*get_buffer_out)(HWVoiceOut *hw, size_t *size); + /* + * put back the buffer returned by get_buffer_out; optional + * buf must be equal the pointer returned by get_buffer_out, + * size may be smaller + */ + size_t (*put_buffer_out)(HWVoiceOut *hw, void *buf, size_t size); + void (*enable_out)(HWVoiceOut *hw, bool enable); + void (*volume_out)(HWVoiceOut *hw, Volume *vol); + + int (*init_in) (HWVoiceIn *hw, audsettings *as, void *drv_opaque); + void (*fini_in) (HWVoiceIn *hw); + size_t (*read) (HWVoiceIn *hw, void *buf, size_t size); + void (*run_buffer_in)(HWVoiceIn *hw); + void *(*get_buffer_in)(HWVoiceIn *hw, size_t *size); + void (*put_buffer_in)(HWVoiceIn *hw, void *buf, size_t size); + void (*enable_in)(HWVoiceIn *hw, bool enable); + void (*volume_in)(HWVoiceIn *hw, Volume *vol); }; +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); +void audio_generic_run_buffer_out(HWVoiceOut *hw); +size_t audio_generic_buffer_get_free(HWVoiceOut *hw); +void *audio_generic_get_buffer_out(HWVoiceOut *hw, size_t *size); +size_t audio_generic_put_buffer_out(HWVoiceOut *hw, void *buf, size_t size); +size_t audio_generic_write(HWVoiceOut *hw, void *buf, size_t size); +size_t audio_generic_read(HWVoiceIn *hw, void *buf, size_t size); + struct capture_callback { struct audio_capture_ops ops; void *opaque; @@ -191,8 +216,9 @@ struct SWVoiceCap { QLIST_ENTRY (SWVoiceCap) entries; }; -struct AudioState { +typedef struct AudioState { struct audio_driver *drv; + Audiodev *dev; void *drv_opaque; QEMUTimer *ts; @@ -203,40 +229,58 @@ struct AudioState { int nb_hw_voices_out; 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; +extern const char *audio_prio_list[]; + void audio_driver_register(audio_driver *drv); -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); - -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); - 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); + +const char *audio_application_name(void); -#define VOICE_ENABLE 1 -#define VOICE_DISABLE 2 -#define VOICE_VOLUME 3 +typedef struct RateCtl { + int64_t start_ticks; + int64_t bytes_sent; +} RateCtl; -#define VOICE_VOLUME_CAP (1 << VOICE_VOLUME) +void audio_rate_start(RateCtl *rate); +size_t audio_rate_peek_bytes(RateCtl *rate, struct audio_pcm_info *info); +void audio_rate_add_bytes(RateCtl *rate, size_t bytes_used); +size_t audio_rate_get_bytes(RateCtl *rate, struct audio_pcm_info *info, + size_t bytes_avail); -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); } +/** + * audio_ring_posb() - returns new position in ringbuffer in backward + * direction at given distance + * + * @pos: current position in ringbuffer + * @dist: distance in ringbuffer to walk in reverse direction + * @len: size of ringbuffer + */ +static inline size_t audio_ring_posb(size_t pos, size_t dist, size_t len) +{ + return pos >= dist ? pos - dist : len - dist + pos; +} + #define dolog(fmt, ...) AUD_log(AUDIO_CAP, fmt, ## __VA_ARGS__) #ifdef DEBUG @@ -245,7 +289,15 @@ static inline int audio_ring_dist (int dst, int src, int len) #define ldebug(fmt, ...) (void)0 #endif -#define AUDIO_STRINGIFY_(n) #n -#define AUDIO_STRINGIFY(n) AUDIO_STRINGIFY_(n) +typedef struct AudiodevListEntry { + Audiodev *dev; + QSIMPLEQ_ENTRY(AudiodevListEntry) next; +} AudiodevListEntry; + +typedef QSIMPLEQ_HEAD(, AudiodevListEntry) AudiodevListHead; + +void audio_create_pdos(Audiodev *dev); +AudiodevPerDirectionOptions *audio_get_pdo_in(Audiodev *dev); +AudiodevPerDirectionOptions *audio_get_pdo_out(Audiodev *dev); #endif /* QEMU_AUDIO_INT_H */ |