blob: 5bcb1c60e183c678eedfc4fc0cf88e53f1bfcbd4 [file] [log] [blame]
bellardfb065182004-11-09 23:09:44 +00001/*
2 * QEMU Audio subsystem header
bellard1d14ffa2005-10-30 18:58:22 +00003 *
4 * Copyright (c) 2003-2005 Vassili Karpov (malc)
5 *
bellardfb065182004-11-09 23:09:44 +00006 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
Markus Armbruster175de522016-06-29 15:29:06 +020024
bellardfb065182004-11-09 23:09:44 +000025#ifndef QEMU_AUDIO_INT_H
26#define QEMU_AUDIO_INT_H
27
bellard1d14ffa2005-10-30 18:58:22 +000028#ifdef CONFIG_COREAUDIO
29#define FLOAT_MIXENG
30/* #define RECIPROCAL */
31#endif
32#include "mixeng.h"
bellardfb065182004-11-09 23:09:44 +000033
bellard1d14ffa2005-10-30 18:58:22 +000034struct audio_pcm_ops;
35
36typedef enum {
37 AUD_OPT_INT,
38 AUD_OPT_FMT,
39 AUD_OPT_STR,
40 AUD_OPT_BOOL
41} audio_option_tag_e;
42
43struct audio_option {
44 const char *name;
45 audio_option_tag_e tag;
46 void *valp;
47 const char *descr;
thsfe8f0962007-07-12 10:59:21 +000048 int *overriddenp;
49 int overridden;
bellard1d14ffa2005-10-30 18:58:22 +000050};
51
52struct audio_callback {
53 void *opaque;
malccb4f03e2009-10-15 02:40:17 +040054 audio_callback_fn fn;
bellard1d14ffa2005-10-30 18:58:22 +000055};
56
57struct audio_pcm_info {
58 int bits;
59 int sign;
60 int freq;
61 int nchannels;
62 int align;
63 int shift;
64 int bytes_per_second;
bellardd929eba2006-07-04 21:47:22 +000065 int swap_endianness;
bellard1d14ffa2005-10-30 18:58:22 +000066};
67
bellardec36b692006-07-16 18:57:03 +000068typedef struct SWVoiceCap SWVoiceCap;
69
bellard1d14ffa2005-10-30 18:58:22 +000070typedef struct HWVoiceOut {
bellardfb065182004-11-09 23:09:44 +000071 int enabled;
malc713a98f2009-09-12 02:28:45 +040072 int poll_mode;
bellardfb065182004-11-09 23:09:44 +000073 int pending_disable;
bellard1d14ffa2005-10-30 18:58:22 +000074 struct audio_pcm_info info;
bellardfb065182004-11-09 23:09:44 +000075
76 f_sample *clip;
bellardfb065182004-11-09 23:09:44 +000077
78 int rpos;
bellard1d14ffa2005-10-30 18:58:22 +000079 uint64_t ts_helper;
bellardfb065182004-11-09 23:09:44 +000080
malc1ea879e2008-12-03 22:48:44 +000081 struct st_sample *mix_buf;
bellardfb065182004-11-09 23:09:44 +000082
83 int samples;
Blue Swirl72cf2d42009-09-12 07:36:22 +000084 QLIST_HEAD (sw_out_listhead, SWVoiceOut) sw_head;
85 QLIST_HEAD (sw_cap_listhead, SWVoiceCap) cap_head;
Marc-André Lureauc01b2452012-04-17 14:32:36 +020086 int ctl_caps;
blueswir135f4b582008-10-06 18:08:30 +000087 struct audio_pcm_ops *pcm_ops;
Blue Swirl72cf2d42009-09-12 07:36:22 +000088 QLIST_ENTRY (HWVoiceOut) entries;
bellard1d14ffa2005-10-30 18:58:22 +000089} HWVoiceOut;
bellardfb065182004-11-09 23:09:44 +000090
bellard1d14ffa2005-10-30 18:58:22 +000091typedef struct HWVoiceIn {
92 int enabled;
malc713a98f2009-09-12 02:28:45 +040093 int poll_mode;
bellard1d14ffa2005-10-30 18:58:22 +000094 struct audio_pcm_info info;
bellardfb065182004-11-09 23:09:44 +000095
96 t_sample *conv;
97
bellard1d14ffa2005-10-30 18:58:22 +000098 int wpos;
bellard1d14ffa2005-10-30 18:58:22 +000099 int total_samples_captured;
100 uint64_t ts_helper;
101
malc1ea879e2008-12-03 22:48:44 +0000102 struct st_sample *conv_buf;
bellard1d14ffa2005-10-30 18:58:22 +0000103
104 int samples;
Blue Swirl72cf2d42009-09-12 07:36:22 +0000105 QLIST_HEAD (sw_in_listhead, SWVoiceIn) sw_head;
Marc-André Lureauc01b2452012-04-17 14:32:36 +0200106 int ctl_caps;
blueswir135f4b582008-10-06 18:08:30 +0000107 struct audio_pcm_ops *pcm_ops;
Blue Swirl72cf2d42009-09-12 07:36:22 +0000108 QLIST_ENTRY (HWVoiceIn) entries;
bellard1d14ffa2005-10-30 18:58:22 +0000109} HWVoiceIn;
110
bellard1d14ffa2005-10-30 18:58:22 +0000111struct SWVoiceOut {
malc1a7dafc2009-05-14 03:11:35 +0400112 QEMUSoundCard *card;
bellard1d14ffa2005-10-30 18:58:22 +0000113 struct audio_pcm_info info;
114 t_sample *conv;
bellardfb065182004-11-09 23:09:44 +0000115 int64_t ratio;
malc1ea879e2008-12-03 22:48:44 +0000116 struct st_sample *buf;
bellardfb065182004-11-09 23:09:44 +0000117 void *rate;
bellard1d14ffa2005-10-30 18:58:22 +0000118 int total_hw_samples_mixed;
bellardfb065182004-11-09 23:09:44 +0000119 int active;
bellard1d14ffa2005-10-30 18:58:22 +0000120 int empty;
121 HWVoiceOut *hw;
bellardfb065182004-11-09 23:09:44 +0000122 char *name;
malc1ea879e2008-12-03 22:48:44 +0000123 struct mixeng_volume vol;
bellard1d14ffa2005-10-30 18:58:22 +0000124 struct audio_callback callback;
Blue Swirl72cf2d42009-09-12 07:36:22 +0000125 QLIST_ENTRY (SWVoiceOut) entries;
bellardfb065182004-11-09 23:09:44 +0000126};
127
bellard1d14ffa2005-10-30 18:58:22 +0000128struct SWVoiceIn {
malc1a7dafc2009-05-14 03:11:35 +0400129 QEMUSoundCard *card;
bellard1d14ffa2005-10-30 18:58:22 +0000130 int active;
131 struct audio_pcm_info info;
132 int64_t ratio;
133 void *rate;
134 int total_hw_samples_acquired;
malc1ea879e2008-12-03 22:48:44 +0000135 struct st_sample *buf;
bellard1d14ffa2005-10-30 18:58:22 +0000136 f_sample *clip;
137 HWVoiceIn *hw;
138 char *name;
malc1ea879e2008-12-03 22:48:44 +0000139 struct mixeng_volume vol;
bellard1d14ffa2005-10-30 18:58:22 +0000140 struct audio_callback callback;
Blue Swirl72cf2d42009-09-12 07:36:22 +0000141 QLIST_ENTRY (SWVoiceIn) entries;
bellardfb065182004-11-09 23:09:44 +0000142};
143
bellardc0fe3822005-11-05 18:55:28 +0000144struct audio_driver {
145 const char *name;
146 const char *descr;
147 struct audio_option *options;
148 void *(*init) (void);
149 void (*fini) (void *);
blueswir135f4b582008-10-06 18:08:30 +0000150 struct audio_pcm_ops *pcm_ops;
bellardc0fe3822005-11-05 18:55:28 +0000151 int can_be_default;
152 int max_voices_out;
153 int max_voices_in;
154 int voice_size_out;
155 int voice_size_in;
Marc-André Lureauc01b2452012-04-17 14:32:36 +0200156 int ctl_caps;
bellardc0fe3822005-11-05 18:55:28 +0000157};
158
bellard1d14ffa2005-10-30 18:58:22 +0000159struct audio_pcm_ops {
Kővágó, Zoltán5706db12015-06-03 23:03:47 +0200160 int (*init_out)(HWVoiceOut *hw, struct audsettings *as, void *drv_opaque);
bellard1d14ffa2005-10-30 18:58:22 +0000161 void (*fini_out)(HWVoiceOut *hw);
malcbdff2532009-09-18 11:37:39 +0400162 int (*run_out) (HWVoiceOut *hw, int live);
bellard1d14ffa2005-10-30 18:58:22 +0000163 int (*write) (SWVoiceOut *sw, void *buf, int size);
164 int (*ctl_out) (HWVoiceOut *hw, int cmd, ...);
bellardfb065182004-11-09 23:09:44 +0000165
Kővágó, Zoltán5706db12015-06-03 23:03:47 +0200166 int (*init_in) (HWVoiceIn *hw, struct audsettings *as, void *drv_opaque);
bellard1d14ffa2005-10-30 18:58:22 +0000167 void (*fini_in) (HWVoiceIn *hw);
168 int (*run_in) (HWVoiceIn *hw);
169 int (*read) (SWVoiceIn *sw, void *buf, int size);
170 int (*ctl_in) (HWVoiceIn *hw, int cmd, ...);
171};
bellardfb065182004-11-09 23:09:44 +0000172
bellard8ead62c2006-07-04 16:51:32 +0000173struct capture_callback {
174 struct audio_capture_ops ops;
175 void *opaque;
Blue Swirl72cf2d42009-09-12 07:36:22 +0000176 QLIST_ENTRY (capture_callback) entries;
bellard8ead62c2006-07-04 16:51:32 +0000177};
178
bellardec36b692006-07-16 18:57:03 +0000179struct CaptureVoiceOut {
bellard8ead62c2006-07-04 16:51:32 +0000180 HWVoiceOut hw;
181 void *buf;
Blue Swirl72cf2d42009-09-12 07:36:22 +0000182 QLIST_HEAD (cb_listhead, capture_callback) cb_head;
183 QLIST_ENTRY (CaptureVoiceOut) entries;
bellardec36b692006-07-16 18:57:03 +0000184};
185
186struct SWVoiceCap {
187 SWVoiceOut sw;
188 CaptureVoiceOut *cap;
Blue Swirl72cf2d42009-09-12 07:36:22 +0000189 QLIST_ENTRY (SWVoiceCap) entries;
bellardec36b692006-07-16 18:57:03 +0000190};
bellard8ead62c2006-07-04 16:51:32 +0000191
bellardc0fe3822005-11-05 18:55:28 +0000192struct AudioState {
193 struct audio_driver *drv;
194 void *drv_opaque;
195
196 QEMUTimer *ts;
Blue Swirl72cf2d42009-09-12 07:36:22 +0000197 QLIST_HEAD (card_listhead, QEMUSoundCard) card_head;
198 QLIST_HEAD (hw_in_listhead, HWVoiceIn) hw_head_in;
199 QLIST_HEAD (hw_out_listhead, HWVoiceOut) hw_head_out;
200 QLIST_HEAD (cap_listhead, CaptureVoiceOut) cap_head;
bellardc0fe3822005-11-05 18:55:28 +0000201 int nb_hw_voices_out;
202 int nb_hw_voices_in;
malc978dd632009-02-18 20:44:04 +0000203 int vm_running;
bellardc0fe3822005-11-05 18:55:28 +0000204};
205
206extern struct audio_driver no_audio_driver;
207extern struct audio_driver oss_audio_driver;
208extern struct audio_driver sdl_audio_driver;
209extern struct audio_driver wav_audio_driver;
bellardc0fe3822005-11-05 18:55:28 +0000210extern struct audio_driver alsa_audio_driver;
211extern struct audio_driver coreaudio_audio_driver;
212extern struct audio_driver dsound_audio_driver;
malcb8e59f12008-07-02 21:03:08 +0000213extern struct audio_driver pa_audio_driver;
Gerd Hoffmann3e313752010-11-09 17:29:46 +0100214extern struct audio_driver spice_audio_driver;
Michael Walle00e07672011-01-05 01:05:47 +0100215extern const struct mixeng_volume nominal_volume;
bellardc0fe3822005-11-05 18:55:28 +0000216
malc1ea879e2008-12-03 22:48:44 +0000217void audio_pcm_init_info (struct audio_pcm_info *info, struct audsettings *as);
bellard1d14ffa2005-10-30 18:58:22 +0000218void audio_pcm_info_clear_buf (struct audio_pcm_info *info, void *buf, int len);
bellardfb065182004-11-09 23:09:44 +0000219
bellard1d14ffa2005-10-30 18:58:22 +0000220int audio_pcm_sw_write (SWVoiceOut *sw, void *buf, int len);
221int audio_pcm_hw_get_live_in (HWVoiceIn *hw);
bellardfb065182004-11-09 23:09:44 +0000222
bellard1d14ffa2005-10-30 18:58:22 +0000223int audio_pcm_sw_read (SWVoiceIn *sw, void *buf, int len);
bellardfb065182004-11-09 23:09:44 +0000224
malcddabec72009-09-18 10:59:38 +0400225int audio_pcm_hw_clip_out (HWVoiceOut *hw, void *pcm_buf,
226 int live, int pending);
227
bellardc0fe3822005-11-05 18:55:28 +0000228int audio_bug (const char *funcname, int cond);
229void *audio_calloc (const char *funcname, int nmemb, size_t size);
230
malc713a98f2009-09-12 02:28:45 +0400231void audio_run (const char *msg);
232
bellardfb065182004-11-09 23:09:44 +0000233#define VOICE_ENABLE 1
234#define VOICE_DISABLE 2
Marc-André Lureau6c95ab92012-04-17 14:32:35 +0200235#define VOICE_VOLUME 3
bellardfb065182004-11-09 23:09:44 +0000236
Marc-André Lureauc01b2452012-04-17 14:32:36 +0200237#define VOICE_VOLUME_CAP (1 << VOICE_VOLUME)
238
bellard1d14ffa2005-10-30 18:58:22 +0000239static inline int audio_ring_dist (int dst, int src, int len)
240{
241 return (dst >= src) ? (dst - src) : (len - src + dst);
242}
243
Stefan Weil87e613e2013-06-16 11:19:31 +0200244#define dolog(fmt, ...) AUD_log(AUDIO_CAP, fmt, ## __VA_ARGS__)
bellard1d14ffa2005-10-30 18:58:22 +0000245
246#ifdef DEBUG
Stefan Weil87e613e2013-06-16 11:19:31 +0200247#define ldebug(fmt, ...) AUD_log(AUDIO_CAP, fmt, ## __VA_ARGS__)
bellard1d14ffa2005-10-30 18:58:22 +0000248#else
Stefan Weil87e613e2013-06-16 11:19:31 +0200249#define ldebug(fmt, ...) (void)0
bellard1d14ffa2005-10-30 18:58:22 +0000250#endif
bellard1d14ffa2005-10-30 18:58:22 +0000251
252#define AUDIO_STRINGIFY_(n) #n
253#define AUDIO_STRINGIFY(n) AUDIO_STRINGIFY_(n)
254
255#if defined _MSC_VER || defined __GNUC__
256#define AUDIO_FUNC __FUNCTION__
257#else
258#define AUDIO_FUNC __FILE__ ":" AUDIO_STRINGIFY (__LINE__)
259#endif
260
Markus Armbruster175de522016-06-29 15:29:06 +0200261#endif /* QEMU_AUDIO_INT_H */