]> git.proxmox.com Git - mirror_qemu.git/blob - audio/audio_template.h
audio/audio_template: use g_new0() to replace audio_calloc()
[mirror_qemu.git] / audio / audio_template.h
1 /*
2 * QEMU Audio subsystem header
3 *
4 * Copyright (c) 2005 Vassili Karpov (malc)
5 *
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:
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 */
24
25 #ifdef DAC
26 #define NAME "playback"
27 #define HWBUF hw->mix_buf
28 #define TYPE out
29 #define HW HWVoiceOut
30 #define SW SWVoiceOut
31 #else
32 #define NAME "capture"
33 #define TYPE in
34 #define HW HWVoiceIn
35 #define SW SWVoiceIn
36 #define HWBUF hw->conv_buf
37 #endif
38
39 static void glue(audio_init_nb_voices_, TYPE)(AudioState *s,
40 struct audio_driver *drv)
41 {
42 int max_voices = glue (drv->max_voices_, TYPE);
43 size_t voice_size = glue(drv->voice_size_, TYPE);
44
45 if (glue (s->nb_hw_voices_, TYPE) > max_voices) {
46 if (!max_voices) {
47 #ifdef DAC
48 dolog ("Driver `%s' does not support " NAME "\n", drv->name);
49 #endif
50 } else {
51 dolog ("Driver `%s' does not support %d " NAME " voices, max %d\n",
52 drv->name,
53 glue (s->nb_hw_voices_, TYPE),
54 max_voices);
55 }
56 glue (s->nb_hw_voices_, TYPE) = max_voices;
57 }
58
59 if (audio_bug(__func__, !voice_size && max_voices)) {
60 dolog ("drv=`%s' voice_size=0 max_voices=%d\n",
61 drv->name, max_voices);
62 glue (s->nb_hw_voices_, TYPE) = 0;
63 }
64
65 if (audio_bug(__func__, voice_size && !max_voices)) {
66 dolog("drv=`%s' voice_size=%zu max_voices=0\n",
67 drv->name, voice_size);
68 }
69 }
70
71 static void glue (audio_pcm_hw_free_resources_, TYPE) (HW *hw)
72 {
73 g_free(hw->buf_emul);
74 g_free (HWBUF);
75 HWBUF = NULL;
76 }
77
78 static void glue(audio_pcm_hw_alloc_resources_, TYPE)(HW *hw)
79 {
80 if (glue(audio_get_pdo_, TYPE)(hw->s->dev)->mixing_engine) {
81 size_t samples = hw->samples;
82 if (audio_bug(__func__, samples == 0)) {
83 dolog("Attempted to allocate empty buffer\n");
84 }
85
86 HWBUF = g_malloc0(sizeof(STSampleBuffer) + sizeof(st_sample) * samples);
87 HWBUF->size = samples;
88 } else {
89 HWBUF = NULL;
90 }
91 }
92
93 static void glue (audio_pcm_sw_free_resources_, TYPE) (SW *sw)
94 {
95 g_free (sw->buf);
96
97 if (sw->rate) {
98 st_rate_stop (sw->rate);
99 }
100
101 sw->buf = NULL;
102 sw->rate = NULL;
103 }
104
105 static int glue (audio_pcm_sw_alloc_resources_, TYPE) (SW *sw)
106 {
107 int samples;
108
109 if (!glue(audio_get_pdo_, TYPE)(sw->s->dev)->mixing_engine) {
110 return 0;
111 }
112
113 #ifdef DAC
114 samples = ((int64_t) sw->HWBUF->size << 32) / sw->ratio;
115 #else
116 samples = (int64_t)sw->HWBUF->size * sw->ratio >> 32;
117 #endif
118 if (audio_bug(__func__, samples < 0)) {
119 dolog("Can not allocate buffer for `%s' (%d samples)\n",
120 SW_NAME(sw), samples);
121 return -1;
122 }
123
124 if (samples == 0) {
125 HW *hw = sw->hw;
126 size_t f_fe_min;
127
128 /* f_fe_min = ceil(1 [frames] * f_be [Hz] / size_be [frames]) */
129 f_fe_min = (hw->info.freq + HWBUF->size - 1) / HWBUF->size;
130 qemu_log_mask(LOG_UNIMP,
131 AUDIO_CAP ": The guest selected a " NAME " sample rate"
132 " of %d Hz for %s. Only sample rates >= %zu Hz are"
133 " supported.\n",
134 sw->info.freq, sw->name, f_fe_min);
135 return -1;
136 }
137
138 sw->buf = g_new0(st_sample, samples);
139
140 #ifdef DAC
141 sw->rate = st_rate_start (sw->info.freq, sw->hw->info.freq);
142 #else
143 sw->rate = st_rate_start (sw->hw->info.freq, sw->info.freq);
144 #endif
145
146 return 0;
147 }
148
149 static int glue (audio_pcm_sw_init_, TYPE) (
150 SW *sw,
151 HW *hw,
152 const char *name,
153 struct audsettings *as
154 )
155 {
156 int err;
157
158 audio_pcm_init_info (&sw->info, as);
159 sw->hw = hw;
160 sw->active = 0;
161 #ifdef DAC
162 sw->ratio = ((int64_t) sw->hw->info.freq << 32) / sw->info.freq;
163 sw->total_hw_samples_mixed = 0;
164 sw->empty = 1;
165 #else
166 sw->ratio = ((int64_t) sw->info.freq << 32) / sw->hw->info.freq;
167 #endif
168
169 if (sw->info.is_float) {
170 #ifdef DAC
171 sw->conv = mixeng_conv_float[sw->info.nchannels == 2];
172 #else
173 sw->clip = mixeng_clip_float[sw->info.nchannels == 2];
174 #endif
175 } else {
176 #ifdef DAC
177 sw->conv = mixeng_conv
178 #else
179 sw->clip = mixeng_clip
180 #endif
181 [sw->info.nchannels == 2]
182 [sw->info.is_signed]
183 [sw->info.swap_endianness]
184 [audio_bits_to_index(sw->info.bits)];
185 }
186
187 sw->name = g_strdup (name);
188 err = glue (audio_pcm_sw_alloc_resources_, TYPE) (sw);
189 if (err) {
190 g_free (sw->name);
191 sw->name = NULL;
192 }
193 return err;
194 }
195
196 static void glue (audio_pcm_sw_fini_, TYPE) (SW *sw)
197 {
198 glue (audio_pcm_sw_free_resources_, TYPE) (sw);
199 g_free (sw->name);
200 sw->name = NULL;
201 }
202
203 static void glue (audio_pcm_hw_add_sw_, TYPE) (HW *hw, SW *sw)
204 {
205 QLIST_INSERT_HEAD (&hw->sw_head, sw, entries);
206 }
207
208 static void glue (audio_pcm_hw_del_sw_, TYPE) (SW *sw)
209 {
210 QLIST_REMOVE (sw, entries);
211 }
212
213 static void glue (audio_pcm_hw_gc_, TYPE) (HW **hwp)
214 {
215 HW *hw = *hwp;
216 AudioState *s = hw->s;
217
218 if (!hw->sw_head.lh_first) {
219 #ifdef DAC
220 audio_detach_capture(hw);
221 #endif
222 QLIST_REMOVE(hw, entries);
223 glue(hw->pcm_ops->fini_, TYPE) (hw);
224 glue(s->nb_hw_voices_, TYPE) += 1;
225 glue(audio_pcm_hw_free_resources_ , TYPE) (hw);
226 g_free(hw);
227 *hwp = NULL;
228 }
229 }
230
231 static HW *glue(audio_pcm_hw_find_any_, TYPE)(AudioState *s, HW *hw)
232 {
233 return hw ? hw->entries.le_next : glue (s->hw_head_, TYPE).lh_first;
234 }
235
236 static HW *glue(audio_pcm_hw_find_any_enabled_, TYPE)(AudioState *s, HW *hw)
237 {
238 while ((hw = glue(audio_pcm_hw_find_any_, TYPE)(s, hw))) {
239 if (hw->enabled) {
240 return hw;
241 }
242 }
243 return NULL;
244 }
245
246 static HW *glue(audio_pcm_hw_find_specific_, TYPE)(AudioState *s, HW *hw,
247 struct audsettings *as)
248 {
249 while ((hw = glue(audio_pcm_hw_find_any_, TYPE)(s, hw))) {
250 if (audio_pcm_info_eq (&hw->info, as)) {
251 return hw;
252 }
253 }
254 return NULL;
255 }
256
257 static HW *glue(audio_pcm_hw_add_new_, TYPE)(AudioState *s,
258 struct audsettings *as)
259 {
260 HW *hw;
261 struct audio_driver *drv = s->drv;
262
263 if (!glue (s->nb_hw_voices_, TYPE)) {
264 return NULL;
265 }
266
267 if (audio_bug(__func__, !drv)) {
268 dolog ("No host audio driver\n");
269 return NULL;
270 }
271
272 if (audio_bug(__func__, !drv->pcm_ops)) {
273 dolog ("Host audio driver without pcm_ops\n");
274 return NULL;
275 }
276
277 /*
278 * Since glue(s->nb_hw_voices_, TYPE) is != 0, glue(drv->voice_size_, TYPE)
279 * is guaranteed to be != 0. See the audio_init_nb_voices_* functions.
280 */
281 hw = g_malloc0(glue(drv->voice_size_, TYPE));
282 hw->s = s;
283 hw->pcm_ops = drv->pcm_ops;
284
285 QLIST_INIT (&hw->sw_head);
286 #ifdef DAC
287 QLIST_INIT (&hw->cap_head);
288 #endif
289 if (glue (hw->pcm_ops->init_, TYPE) (hw, as, s->drv_opaque)) {
290 goto err0;
291 }
292
293 if (audio_bug(__func__, hw->samples <= 0)) {
294 dolog("hw->samples=%zd\n", hw->samples);
295 goto err1;
296 }
297
298 if (hw->info.is_float) {
299 #ifdef DAC
300 hw->clip = mixeng_clip_float[hw->info.nchannels == 2];
301 #else
302 hw->conv = mixeng_conv_float[hw->info.nchannels == 2];
303 #endif
304 } else {
305 #ifdef DAC
306 hw->clip = mixeng_clip
307 #else
308 hw->conv = mixeng_conv
309 #endif
310 [hw->info.nchannels == 2]
311 [hw->info.is_signed]
312 [hw->info.swap_endianness]
313 [audio_bits_to_index(hw->info.bits)];
314 }
315
316 glue(audio_pcm_hw_alloc_resources_, TYPE)(hw);
317
318 QLIST_INSERT_HEAD (&s->glue (hw_head_, TYPE), hw, entries);
319 glue (s->nb_hw_voices_, TYPE) -= 1;
320 #ifdef DAC
321 audio_attach_capture (hw);
322 #endif
323 return hw;
324
325 err1:
326 glue (hw->pcm_ops->fini_, TYPE) (hw);
327 err0:
328 g_free (hw);
329 return NULL;
330 }
331
332 AudiodevPerDirectionOptions *glue(audio_get_pdo_, TYPE)(Audiodev *dev)
333 {
334 switch (dev->driver) {
335 case AUDIODEV_DRIVER_NONE:
336 return dev->u.none.TYPE;
337 #ifdef CONFIG_AUDIO_ALSA
338 case AUDIODEV_DRIVER_ALSA:
339 return qapi_AudiodevAlsaPerDirectionOptions_base(dev->u.alsa.TYPE);
340 #endif
341 #ifdef CONFIG_AUDIO_COREAUDIO
342 case AUDIODEV_DRIVER_COREAUDIO:
343 return qapi_AudiodevCoreaudioPerDirectionOptions_base(
344 dev->u.coreaudio.TYPE);
345 #endif
346 #ifdef CONFIG_DBUS_DISPLAY
347 case AUDIODEV_DRIVER_DBUS:
348 return dev->u.dbus.TYPE;
349 #endif
350 #ifdef CONFIG_AUDIO_DSOUND
351 case AUDIODEV_DRIVER_DSOUND:
352 return dev->u.dsound.TYPE;
353 #endif
354 #ifdef CONFIG_AUDIO_JACK
355 case AUDIODEV_DRIVER_JACK:
356 return qapi_AudiodevJackPerDirectionOptions_base(dev->u.jack.TYPE);
357 #endif
358 #ifdef CONFIG_AUDIO_OSS
359 case AUDIODEV_DRIVER_OSS:
360 return qapi_AudiodevOssPerDirectionOptions_base(dev->u.oss.TYPE);
361 #endif
362 #ifdef CONFIG_AUDIO_PA
363 case AUDIODEV_DRIVER_PA:
364 return qapi_AudiodevPaPerDirectionOptions_base(dev->u.pa.TYPE);
365 #endif
366 #ifdef CONFIG_AUDIO_SDL
367 case AUDIODEV_DRIVER_SDL:
368 return qapi_AudiodevSdlPerDirectionOptions_base(dev->u.sdl.TYPE);
369 #endif
370 #ifdef CONFIG_AUDIO_SNDIO
371 case AUDIODEV_DRIVER_SNDIO:
372 return dev->u.sndio.TYPE;
373 #endif
374 #ifdef CONFIG_SPICE
375 case AUDIODEV_DRIVER_SPICE:
376 return dev->u.spice.TYPE;
377 #endif
378 case AUDIODEV_DRIVER_WAV:
379 return dev->u.wav.TYPE;
380
381 case AUDIODEV_DRIVER__MAX:
382 break;
383 }
384 abort();
385 }
386
387 static HW *glue(audio_pcm_hw_add_, TYPE)(AudioState *s, struct audsettings *as)
388 {
389 HW *hw;
390 AudiodevPerDirectionOptions *pdo = glue(audio_get_pdo_, TYPE)(s->dev);
391
392 if (!pdo->mixing_engine || pdo->fixed_settings) {
393 hw = glue(audio_pcm_hw_add_new_, TYPE)(s, as);
394 if (!pdo->mixing_engine || hw) {
395 return hw;
396 }
397 }
398
399 hw = glue(audio_pcm_hw_find_specific_, TYPE)(s, NULL, as);
400 if (hw) {
401 return hw;
402 }
403
404 hw = glue(audio_pcm_hw_add_new_, TYPE)(s, as);
405 if (hw) {
406 return hw;
407 }
408
409 return glue(audio_pcm_hw_find_any_, TYPE)(s, NULL);
410 }
411
412 static SW *glue(audio_pcm_create_voice_pair_, TYPE)(
413 AudioState *s,
414 const char *sw_name,
415 struct audsettings *as
416 )
417 {
418 SW *sw;
419 HW *hw;
420 struct audsettings hw_as;
421 AudiodevPerDirectionOptions *pdo = glue(audio_get_pdo_, TYPE)(s->dev);
422
423 if (pdo->fixed_settings) {
424 hw_as = audiodev_to_audsettings(pdo);
425 } else {
426 hw_as = *as;
427 }
428
429 sw = g_new0(SW, 1);
430 sw->s = s;
431
432 hw = glue(audio_pcm_hw_add_, TYPE)(s, &hw_as);
433 if (!hw) {
434 dolog("Could not create a backend for voice `%s'\n", sw_name);
435 goto err1;
436 }
437
438 glue (audio_pcm_hw_add_sw_, TYPE) (hw, sw);
439
440 if (glue (audio_pcm_sw_init_, TYPE) (sw, hw, sw_name, as)) {
441 goto err2;
442 }
443
444 return sw;
445
446 err2:
447 glue (audio_pcm_hw_del_sw_, TYPE) (sw);
448 glue (audio_pcm_hw_gc_, TYPE) (&hw);
449 err1:
450 g_free(sw);
451 return NULL;
452 }
453
454 static void glue (audio_close_, TYPE) (SW *sw)
455 {
456 glue (audio_pcm_sw_fini_, TYPE) (sw);
457 glue (audio_pcm_hw_del_sw_, TYPE) (sw);
458 glue (audio_pcm_hw_gc_, TYPE) (&sw->hw);
459 g_free (sw);
460 }
461
462 void glue (AUD_close_, TYPE) (QEMUSoundCard *card, SW *sw)
463 {
464 if (sw) {
465 if (audio_bug(__func__, !card)) {
466 dolog ("card=%p\n", card);
467 return;
468 }
469
470 glue (audio_close_, TYPE) (sw);
471 }
472 }
473
474 SW *glue (AUD_open_, TYPE) (
475 QEMUSoundCard *card,
476 SW *sw,
477 const char *name,
478 void *callback_opaque ,
479 audio_callback_fn callback_fn,
480 struct audsettings *as
481 )
482 {
483 AudioState *s;
484 AudiodevPerDirectionOptions *pdo;
485
486 if (audio_bug(__func__, !card || !name || !callback_fn || !as)) {
487 dolog ("card=%p name=%p callback_fn=%p as=%p\n",
488 card, name, callback_fn, as);
489 goto fail;
490 }
491
492 s = card->state;
493 pdo = glue(audio_get_pdo_, TYPE)(s->dev);
494
495 ldebug ("open %s, freq %d, nchannels %d, fmt %d\n",
496 name, as->freq, as->nchannels, as->fmt);
497
498 if (audio_bug(__func__, audio_validate_settings(as))) {
499 audio_print_settings (as);
500 goto fail;
501 }
502
503 if (audio_bug(__func__, !s->drv)) {
504 dolog ("Can not open `%s' (no host audio driver)\n", name);
505 goto fail;
506 }
507
508 if (sw && audio_pcm_info_eq (&sw->info, as)) {
509 return sw;
510 }
511
512 if (!pdo->fixed_settings && sw) {
513 glue (AUD_close_, TYPE) (card, sw);
514 sw = NULL;
515 }
516
517 if (sw) {
518 HW *hw = sw->hw;
519
520 if (!hw) {
521 dolog("Internal logic error: voice `%s' has no backend\n",
522 SW_NAME(sw));
523 goto fail;
524 }
525
526 glue (audio_pcm_sw_fini_, TYPE) (sw);
527 if (glue (audio_pcm_sw_init_, TYPE) (sw, hw, name, as)) {
528 goto fail;
529 }
530 } else {
531 sw = glue(audio_pcm_create_voice_pair_, TYPE)(s, name, as);
532 if (!sw) {
533 return NULL;
534 }
535 }
536
537 sw->card = card;
538 sw->vol = nominal_volume;
539 sw->callback.fn = callback_fn;
540 sw->callback.opaque = callback_opaque;
541
542 #ifdef DEBUG_AUDIO
543 dolog ("%s\n", name);
544 audio_pcm_print_info ("hw", &sw->hw->info);
545 audio_pcm_print_info ("sw", &sw->info);
546 #endif
547
548 return sw;
549
550 fail:
551 glue (AUD_close_, TYPE) (card, sw);
552 return NULL;
553 }
554
555 int glue (AUD_is_active_, TYPE) (SW *sw)
556 {
557 return sw ? sw->active : 0;
558 }
559
560 void glue (AUD_init_time_stamp_, TYPE) (SW *sw, QEMUAudioTimeStamp *ts)
561 {
562 if (!sw) {
563 return;
564 }
565
566 ts->old_ts = sw->hw->ts_helper;
567 }
568
569 uint64_t glue (AUD_get_elapsed_usec_, TYPE) (SW *sw, QEMUAudioTimeStamp *ts)
570 {
571 uint64_t delta, cur_ts, old_ts;
572
573 if (!sw) {
574 return 0;
575 }
576
577 cur_ts = sw->hw->ts_helper;
578 old_ts = ts->old_ts;
579 /* dolog ("cur %" PRId64 " old %" PRId64 "\n", cur_ts, old_ts); */
580
581 if (cur_ts >= old_ts) {
582 delta = cur_ts - old_ts;
583 } else {
584 delta = UINT64_MAX - old_ts + cur_ts;
585 }
586
587 if (!delta) {
588 return 0;
589 }
590
591 return muldiv64 (delta, sw->hw->info.freq, 1000000);
592 }
593
594 #undef TYPE
595 #undef HW
596 #undef SW
597 #undef HWBUF
598 #undef NAME