2 * QEMU Audio subsystem header
4 * Copyright (c) 2005 Vassili Karpov (malc)
6 * 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:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
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
27 #define HW glue (HWVoice, Out)
28 #define SW glue (SWVoice, Out)
31 #define HW glue (HWVoice, In)
32 #define SW glue (SWVoice, In)
35 static int glue (audio_pcm_hw_init_
, TYPE
) (
40 glue (audio_pcm_hw_free_resources_
, TYPE
) (hw
);
42 if (glue (hw
->pcm_ops
->init_
, TYPE
) (hw
, as
)) {
46 if (audio_bug (AUDIO_FUNC
, hw
->samples
<= 0)) {
47 dolog ("hw->samples=%d\n", hw
->samples
);
51 LIST_INIT (&hw
->sw_head
);
59 [hw
->info
.nchannels
== 2]
61 [hw
->info
.swap_endian
]
62 [hw
->info
.bits
== 16];
64 if (glue (audio_pcm_hw_alloc_resources_
, TYPE
) (hw
)) {
65 glue (hw
->pcm_ops
->fini_
, TYPE
) (hw
);
72 static void glue (audio_pcm_sw_fini_
, TYPE
) (SW
*sw
)
74 glue (audio_pcm_sw_free_resources_
, TYPE
) (sw
);
81 static void glue (audio_pcm_hw_add_sw_
, TYPE
) (HW
*hw
, SW
*sw
)
83 LIST_INSERT_HEAD (&hw
->sw_head
, sw
, entries
);
86 static void glue (audio_pcm_hw_del_sw_
, TYPE
) (SW
*sw
)
88 LIST_REMOVE (sw
, entries
);
91 static void glue (audio_pcm_hw_gc_
, TYPE
) (AudioState
*s
, HW
**hwp
)
95 if (!hw
->sw_head
.lh_first
) {
96 LIST_REMOVE (hw
, entries
);
97 glue (s
->nb_hw_voices_
, TYPE
) += 1;
98 glue (audio_pcm_hw_free_resources_
,TYPE
) (hw
);
99 glue (hw
->pcm_ops
->fini_
, TYPE
) (hw
);
105 static HW
*glue (audio_pcm_hw_find_any_
, TYPE
) (AudioState
*s
, HW
*hw
)
107 return hw
? hw
->entries
.le_next
: s
->glue (hw_head_
, TYPE
).lh_first
;
110 static HW
*glue (audio_pcm_hw_find_any_enabled_
, TYPE
) (AudioState
*s
, HW
*hw
)
112 while ((hw
= glue (audio_pcm_hw_find_any_
, TYPE
) (s
, hw
))) {
120 static HW
*glue (audio_pcm_hw_find_any_passive_
, TYPE
) (AudioState
*s
)
122 if (glue (s
->nb_hw_voices_
, TYPE
)) {
123 struct audio_driver
*drv
= s
->drv
;
125 if (audio_bug (AUDIO_FUNC
, !drv
)) {
126 dolog ("No host audio driver\n");
130 HW
*hw
= audio_calloc (AUDIO_FUNC
, 1, glue (drv
->voice_size_
, TYPE
));
132 dolog ("Can not allocate voice `%s' size %d\n",
133 drv
->name
, glue (drv
->voice_size_
, TYPE
));
136 LIST_INSERT_HEAD (&s
->glue (hw_head_
, TYPE
), hw
, entries
);
137 glue (s
->nb_hw_voices_
, TYPE
) -= 1;
144 static HW
*glue (audio_pcm_hw_find_specific_
, TYPE
) (
150 while ((hw
= glue (audio_pcm_hw_find_any_
, TYPE
) (s
, hw
))) {
151 if (audio_pcm_info_eq (&hw
->info
, as
)) {
158 static HW
*glue (audio_pcm_hw_add_new_
, TYPE
) (AudioState
*s
, audsettings_t
*as
)
162 hw
= glue (audio_pcm_hw_find_any_passive_
, TYPE
) (s
);
164 hw
->pcm_ops
= s
->drv
->pcm_ops
;
169 if (glue (audio_pcm_hw_init_
, TYPE
) (hw
, as
)) {
170 glue (audio_pcm_hw_gc_
, TYPE
) (s
, &hw
);
181 static HW
*glue (audio_pcm_hw_add_
, TYPE
) (AudioState
*s
, audsettings_t
*as
)
185 if (glue (conf
.fixed_
, TYPE
).enabled
&& glue (conf
.fixed_
, TYPE
).greedy
) {
186 hw
= glue (audio_pcm_hw_add_new_
, TYPE
) (s
, as
);
192 hw
= glue (audio_pcm_hw_find_specific_
, TYPE
) (s
, NULL
, as
);
197 hw
= glue (audio_pcm_hw_add_new_
, TYPE
) (s
, as
);
202 return glue (audio_pcm_hw_find_any_
, TYPE
) (s
, NULL
);
205 static SW
*glue (audio_pcm_create_voice_pair_
, TYPE
) (
215 if (glue (conf
.fixed_
, TYPE
).enabled
) {
216 hw_as
= glue (conf
.fixed_
, TYPE
).settings
;
222 sw
= audio_calloc (AUDIO_FUNC
, 1, sizeof (*sw
));
224 dolog ("Could not allocate soft voice `%s' (%d bytes)\n",
225 sw_name
? sw_name
: "unknown", sizeof (*sw
));
229 hw
= glue (audio_pcm_hw_add_
, TYPE
) (s
, &hw_as
);
234 glue (audio_pcm_hw_add_sw_
, TYPE
) (hw
, sw
);
236 if (glue (audio_pcm_sw_init_
, TYPE
) (sw
, hw
, sw_name
, as
)) {
243 glue (audio_pcm_hw_del_sw_
, TYPE
) (sw
);
244 glue (audio_pcm_hw_gc_
, TYPE
) (s
, &hw
);
251 static void glue (audio_close_
, TYPE
) (AudioState
*s
, SW
*sw
)
253 glue (audio_pcm_sw_fini_
, TYPE
) (sw
);
254 glue (audio_pcm_hw_del_sw_
, TYPE
) (sw
);
255 glue (audio_pcm_hw_gc_
, TYPE
) (s
, &sw
->hw
);
258 void glue (AUD_close_
, TYPE
) (QEMUSoundCard
*card
, SW
*sw
)
261 if (audio_bug (AUDIO_FUNC
, !card
|| !card
->audio
)) {
262 dolog ("card=%p card->audio=%p\n",
263 card
, card
? card
->audio
: NULL
);
267 glue (audio_close_
, TYPE
) (card
->audio
, sw
);
271 SW
*glue (AUD_open_
, TYPE
) (
275 void *callback_opaque
,
276 audio_callback_fn_t callback_fn
,
286 ldebug ("open %s, freq %d, nchannels %d, fmt %d\n",
287 name
, as
->freq
, as
->nchannels
, as
->fmt
);
289 if (audio_bug (AUDIO_FUNC
,
290 !card
|| !card
->audio
|| !name
|| !callback_fn
|| !as
)) {
291 dolog ("card=%p card->audio=%p name=%p callback_fn=%p as=%p\n",
292 card
, card
? card
->audio
: NULL
, name
, callback_fn
, as
);
298 if (audio_bug (AUDIO_FUNC
, audio_validate_settigs (as
))) {
299 audio_print_settings (as
);
303 if (audio_bug (AUDIO_FUNC
, !s
->drv
)) {
304 dolog ("Can not open `%s' (no host audio driver)\n", name
);
308 if (sw
&& audio_pcm_info_eq (&sw
->info
, as
)) {
313 if (conf
.plive
&& sw
&& (!sw
->active
&& !sw
->empty
)) {
314 live
= sw
->total_hw_samples_mixed
;
317 dolog ("Replacing voice %s with %d live samples\n", SW_NAME (sw
), live
);
318 dolog ("Old %s freq %d, bits %d, channels %d\n",
319 SW_NAME (sw
), sw
->info
.freq
, sw
->info
.bits
, sw
->info
.nchannels
);
320 dolog ("New %s freq %d, bits %d, channels %d\n",
323 (fmt
== AUD_FMT_S16
|| fmt
== AUD_FMT_U16
) ? 16 : 8,
329 old_sw
->callback
.fn
= NULL
;
335 if (!glue (conf
.fixed_
, TYPE
).enabled
&& sw
) {
336 glue (AUD_close_
, TYPE
) (card
, sw
);
344 dolog ("Internal logic error voice `%s' has no hardware store\n",
349 if (glue (audio_pcm_sw_init_
, TYPE
) (sw
, hw
, name
, as
)) {
354 sw
= glue (audio_pcm_create_voice_pair_
, TYPE
) (s
, name
, as
);
356 dolog ("Failed to create voice `%s'\n", name
);
362 sw
->vol
= nominal_volume
;
363 sw
->callback
.fn
= callback_fn
;
364 sw
->callback
.opaque
= callback_opaque
;
369 (live
<< old_sw
->info
.shift
)
370 * old_sw
->info
.bytes_per_second
371 / sw
->info
.bytes_per_second
;
374 dolog ("Silence will be mixed %d\n", mixed
);
376 sw
->total_hw_samples_mixed
+= mixed
;
381 dolog ("%s\n", name
);
382 audio_pcm_print_info ("hw", &sw
->hw
->info
);
383 audio_pcm_print_info ("sw", &sw
->info
);
390 glue (AUD_close_
, TYPE
) (card
, sw
);
394 int glue (AUD_is_active_
, TYPE
) (SW
*sw
)
396 return sw
? sw
->active
: 0;
399 void glue (AUD_init_time_stamp_
, TYPE
) (SW
*sw
, QEMUAudioTimeStamp
*ts
)
405 ts
->old_ts
= sw
->hw
->ts_helper
;
408 uint64_t glue (AUD_get_elapsed_usec_
, TYPE
) (SW
*sw
, QEMUAudioTimeStamp
*ts
)
410 uint64_t delta
, cur_ts
, old_ts
;
416 cur_ts
= sw
->hw
->ts_helper
;
418 /* dolog ("cur %lld old %lld\n", cur_ts, old_ts); */
420 if (cur_ts
>= old_ts
) {
421 delta
= cur_ts
- old_ts
;
424 delta
= UINT64_MAX
- old_ts
+ cur_ts
;
431 return (delta
* sw
->hw
->info
.freq
) / 1000000;