|
|
1.1 root 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:
1.1.1.5 ! root 39: static void glue (audio_init_nb_voices_, TYPE) (struct audio_driver *drv)
1.1 root 40: {
1.1.1.5 ! root 41: AudioState *s = &glob_audio_state;
1.1 root 42: int max_voices = glue (drv->max_voices_, TYPE);
43: int 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: }
51: else {
52: dolog ("Driver `%s' does not support %d " NAME " voices, max %d\n",
53: drv->name,
54: glue (s->nb_hw_voices_, TYPE),
55: max_voices);
56: }
57: glue (s->nb_hw_voices_, TYPE) = max_voices;
58: }
59:
60: if (audio_bug (AUDIO_FUNC, !voice_size && max_voices)) {
61: dolog ("drv=`%s' voice_size=0 max_voices=%d\n",
62: drv->name, max_voices);
63: glue (s->nb_hw_voices_, TYPE) = 0;
64: }
65:
66: if (audio_bug (AUDIO_FUNC, voice_size && !max_voices)) {
67: dolog ("drv=`%s' voice_size=%d max_voices=0\n",
68: drv->name, voice_size);
69: }
70: }
71:
72: static void glue (audio_pcm_hw_free_resources_, TYPE) (HW *hw)
73: {
74: if (HWBUF) {
75: qemu_free (HWBUF);
76: }
77:
78: HWBUF = NULL;
79: }
80:
81: static int glue (audio_pcm_hw_alloc_resources_, TYPE) (HW *hw)
82: {
1.1.1.4 root 83: HWBUF = audio_calloc (AUDIO_FUNC, hw->samples, sizeof (struct st_sample));
1.1 root 84: if (!HWBUF) {
85: dolog ("Could not allocate " NAME " buffer (%d samples)\n",
86: hw->samples);
87: return -1;
88: }
89:
90: return 0;
91: }
92:
93: static void glue (audio_pcm_sw_free_resources_, TYPE) (SW *sw)
94: {
95: if (sw->buf) {
96: qemu_free (sw->buf);
97: }
98:
99: if (sw->rate) {
100: st_rate_stop (sw->rate);
101: }
102:
103: sw->buf = NULL;
104: sw->rate = NULL;
105: }
106:
107: static int glue (audio_pcm_sw_alloc_resources_, TYPE) (SW *sw)
108: {
109: int samples;
110:
111: #ifdef DAC
112: samples = sw->hw->samples;
113: #else
114: samples = ((int64_t) sw->hw->samples << 32) / sw->ratio;
115: #endif
116:
1.1.1.4 root 117: sw->buf = audio_calloc (AUDIO_FUNC, samples, sizeof (struct st_sample));
1.1 root 118: if (!sw->buf) {
119: dolog ("Could not allocate buffer for `%s' (%d samples)\n",
120: SW_NAME (sw), samples);
121: return -1;
122: }
123:
124: #ifdef DAC
125: sw->rate = st_rate_start (sw->info.freq, sw->hw->info.freq);
126: #else
127: sw->rate = st_rate_start (sw->hw->info.freq, sw->info.freq);
128: #endif
129: if (!sw->rate) {
130: qemu_free (sw->buf);
131: sw->buf = NULL;
132: return -1;
133: }
134: return 0;
135: }
136:
137: static int glue (audio_pcm_sw_init_, TYPE) (
138: SW *sw,
139: HW *hw,
140: const char *name,
1.1.1.4 root 141: struct audsettings *as
1.1 root 142: )
143: {
144: int err;
145:
1.1.1.2 root 146: audio_pcm_init_info (&sw->info, as);
1.1 root 147: sw->hw = hw;
148: sw->active = 0;
149: #ifdef DAC
150: sw->ratio = ((int64_t) sw->hw->info.freq << 32) / sw->info.freq;
151: sw->total_hw_samples_mixed = 0;
152: sw->empty = 1;
153: #else
154: sw->ratio = ((int64_t) sw->info.freq << 32) / sw->hw->info.freq;
155: #endif
156:
157: #ifdef DAC
158: sw->conv = mixeng_conv
159: #else
160: sw->clip = mixeng_clip
161: #endif
162: [sw->info.nchannels == 2]
163: [sw->info.sign]
1.1.1.2 root 164: [sw->info.swap_endianness]
1.1.1.3 root 165: [audio_bits_to_index (sw->info.bits)];
1.1 root 166:
167: sw->name = qemu_strdup (name);
168: err = glue (audio_pcm_sw_alloc_resources_, TYPE) (sw);
169: if (err) {
170: qemu_free (sw->name);
171: sw->name = NULL;
172: }
173: return err;
174: }
175:
176: static void glue (audio_pcm_sw_fini_, TYPE) (SW *sw)
177: {
178: glue (audio_pcm_sw_free_resources_, TYPE) (sw);
179: if (sw->name) {
180: qemu_free (sw->name);
181: sw->name = NULL;
182: }
183: }
184:
185: static void glue (audio_pcm_hw_add_sw_, TYPE) (HW *hw, SW *sw)
186: {
187: LIST_INSERT_HEAD (&hw->sw_head, sw, entries);
188: }
189:
190: static void glue (audio_pcm_hw_del_sw_, TYPE) (SW *sw)
191: {
192: LIST_REMOVE (sw, entries);
193: }
194:
1.1.1.5 ! root 195: static void glue (audio_pcm_hw_gc_, TYPE) (HW **hwp)
1.1 root 196: {
1.1.1.5 ! root 197: AudioState *s = &glob_audio_state;
1.1 root 198: HW *hw = *hwp;
199:
200: if (!hw->sw_head.lh_first) {
1.1.1.2 root 201: #ifdef DAC
202: audio_detach_capture (hw);
203: #endif
1.1 root 204: LIST_REMOVE (hw, entries);
205: glue (s->nb_hw_voices_, TYPE) += 1;
206: glue (audio_pcm_hw_free_resources_ ,TYPE) (hw);
207: glue (hw->pcm_ops->fini_, TYPE) (hw);
208: qemu_free (hw);
209: *hwp = NULL;
210: }
211: }
212:
1.1.1.5 ! root 213: static HW *glue (audio_pcm_hw_find_any_, TYPE) (HW *hw)
1.1 root 214: {
1.1.1.5 ! root 215: AudioState *s = &glob_audio_state;
! 216: return hw ? hw->entries.le_next : glue (s->hw_head_, TYPE).lh_first;
1.1 root 217: }
218:
1.1.1.5 ! root 219: static HW *glue (audio_pcm_hw_find_any_enabled_, TYPE) (HW *hw)
1.1 root 220: {
1.1.1.5 ! root 221: while ((hw = glue (audio_pcm_hw_find_any_, TYPE) (hw))) {
1.1 root 222: if (hw->enabled) {
223: return hw;
224: }
225: }
226: return NULL;
227: }
228:
229: static HW *glue (audio_pcm_hw_find_specific_, TYPE) (
230: HW *hw,
1.1.1.4 root 231: struct audsettings *as
1.1 root 232: )
233: {
1.1.1.5 ! root 234: while ((hw = glue (audio_pcm_hw_find_any_, TYPE) (hw))) {
1.1 root 235: if (audio_pcm_info_eq (&hw->info, as)) {
236: return hw;
237: }
238: }
239: return NULL;
240: }
241:
1.1.1.5 ! root 242: static HW *glue (audio_pcm_hw_add_new_, TYPE) (struct audsettings *as)
1.1 root 243: {
244: HW *hw;
1.1.1.5 ! root 245: AudioState *s = &glob_audio_state;
1.1 root 246: struct audio_driver *drv = s->drv;
247:
248: if (!glue (s->nb_hw_voices_, TYPE)) {
249: return NULL;
250: }
251:
252: if (audio_bug (AUDIO_FUNC, !drv)) {
253: dolog ("No host audio driver\n");
254: return NULL;
255: }
256:
257: if (audio_bug (AUDIO_FUNC, !drv->pcm_ops)) {
258: dolog ("Host audio driver without pcm_ops\n");
259: return NULL;
260: }
261:
262: hw = audio_calloc (AUDIO_FUNC, 1, glue (drv->voice_size_, TYPE));
263: if (!hw) {
264: dolog ("Can not allocate voice `%s' size %d\n",
265: drv->name, glue (drv->voice_size_, TYPE));
266: return NULL;
267: }
268:
269: hw->pcm_ops = drv->pcm_ops;
270: LIST_INIT (&hw->sw_head);
1.1.1.2 root 271: #ifdef DAC
272: LIST_INIT (&hw->cap_head);
273: #endif
1.1 root 274: if (glue (hw->pcm_ops->init_, TYPE) (hw, as)) {
275: goto err0;
276: }
277:
278: if (audio_bug (AUDIO_FUNC, hw->samples <= 0)) {
279: dolog ("hw->samples=%d\n", hw->samples);
280: goto err1;
281: }
282:
283: #ifdef DAC
284: hw->clip = mixeng_clip
285: #else
286: hw->conv = mixeng_conv
287: #endif
288: [hw->info.nchannels == 2]
289: [hw->info.sign]
1.1.1.2 root 290: [hw->info.swap_endianness]
1.1.1.3 root 291: [audio_bits_to_index (hw->info.bits)];
1.1 root 292:
293: if (glue (audio_pcm_hw_alloc_resources_, TYPE) (hw)) {
294: goto err1;
295: }
296:
297: LIST_INSERT_HEAD (&s->glue (hw_head_, TYPE), hw, entries);
298: glue (s->nb_hw_voices_, TYPE) -= 1;
1.1.1.2 root 299: #ifdef DAC
1.1.1.5 ! root 300: audio_attach_capture (hw);
1.1.1.2 root 301: #endif
1.1 root 302: return hw;
303:
304: err1:
305: glue (hw->pcm_ops->fini_, TYPE) (hw);
306: err0:
307: qemu_free (hw);
308: return NULL;
309: }
310:
1.1.1.5 ! root 311: static HW *glue (audio_pcm_hw_add_, TYPE) (struct audsettings *as)
1.1 root 312: {
313: HW *hw;
314:
315: if (glue (conf.fixed_, TYPE).enabled && glue (conf.fixed_, TYPE).greedy) {
1.1.1.5 ! root 316: hw = glue (audio_pcm_hw_add_new_, TYPE) (as);
1.1 root 317: if (hw) {
318: return hw;
319: }
320: }
321:
1.1.1.5 ! root 322: hw = glue (audio_pcm_hw_find_specific_, TYPE) (NULL, as);
1.1 root 323: if (hw) {
324: return hw;
325: }
326:
1.1.1.5 ! root 327: hw = glue (audio_pcm_hw_add_new_, TYPE) (as);
1.1 root 328: if (hw) {
329: return hw;
330: }
331:
1.1.1.5 ! root 332: return glue (audio_pcm_hw_find_any_, TYPE) (NULL);
1.1 root 333: }
334:
335: static SW *glue (audio_pcm_create_voice_pair_, TYPE) (
336: const char *sw_name,
1.1.1.4 root 337: struct audsettings *as
1.1 root 338: )
339: {
340: SW *sw;
341: HW *hw;
1.1.1.4 root 342: struct audsettings hw_as;
1.1 root 343:
344: if (glue (conf.fixed_, TYPE).enabled) {
345: hw_as = glue (conf.fixed_, TYPE).settings;
346: }
347: else {
348: hw_as = *as;
349: }
350:
351: sw = audio_calloc (AUDIO_FUNC, 1, sizeof (*sw));
352: if (!sw) {
353: dolog ("Could not allocate soft voice `%s' (%zu bytes)\n",
354: sw_name ? sw_name : "unknown", sizeof (*sw));
355: goto err1;
356: }
357:
1.1.1.5 ! root 358: hw = glue (audio_pcm_hw_add_, TYPE) (&hw_as);
1.1 root 359: if (!hw) {
360: goto err2;
361: }
362:
363: glue (audio_pcm_hw_add_sw_, TYPE) (hw, sw);
364:
1.1.1.2 root 365: if (glue (audio_pcm_sw_init_, TYPE) (sw, hw, sw_name, as)) {
1.1 root 366: goto err3;
367: }
368:
369: return sw;
370:
371: err3:
372: glue (audio_pcm_hw_del_sw_, TYPE) (sw);
1.1.1.5 ! root 373: glue (audio_pcm_hw_gc_, TYPE) (&hw);
1.1 root 374: err2:
375: qemu_free (sw);
376: err1:
377: return NULL;
378: }
379:
1.1.1.5 ! root 380: static void glue (audio_close_, TYPE) (SW *sw)
1.1 root 381: {
382: glue (audio_pcm_sw_fini_, TYPE) (sw);
383: glue (audio_pcm_hw_del_sw_, TYPE) (sw);
1.1.1.5 ! root 384: glue (audio_pcm_hw_gc_, TYPE) (&sw->hw);
1.1 root 385: qemu_free (sw);
386: }
387:
388: void glue (AUD_close_, TYPE) (QEMUSoundCard *card, SW *sw)
389: {
390: if (sw) {
1.1.1.5 ! root 391: if (audio_bug (AUDIO_FUNC, !card)) {
! 392: dolog ("card=%p\n", card);
1.1 root 393: return;
394: }
395:
1.1.1.5 ! root 396: glue (audio_close_, TYPE) (sw);
1.1 root 397: }
398: }
399:
400: SW *glue (AUD_open_, TYPE) (
401: QEMUSoundCard *card,
402: SW *sw,
403: const char *name,
404: void *callback_opaque ,
405: audio_callback_fn_t callback_fn,
1.1.1.4 root 406: struct audsettings *as
1.1 root 407: )
408: {
1.1.1.5 ! root 409: AudioState *s = &glob_audio_state;
1.1 root 410: #ifdef DAC
411: int live = 0;
412: SW *old_sw = NULL;
413: #endif
414:
415: ldebug ("open %s, freq %d, nchannels %d, fmt %d\n",
416: name, as->freq, as->nchannels, as->fmt);
417:
1.1.1.5 ! root 418: if (audio_bug (AUDIO_FUNC, !card || !name || !callback_fn || !as)) {
! 419: dolog ("card=%p name=%p callback_fn=%p as=%p\n",
! 420: card, name, callback_fn, as);
1.1 root 421: goto fail;
422: }
423:
1.1.1.2 root 424: if (audio_bug (AUDIO_FUNC, audio_validate_settings (as))) {
1.1 root 425: audio_print_settings (as);
426: goto fail;
427: }
428:
429: if (audio_bug (AUDIO_FUNC, !s->drv)) {
430: dolog ("Can not open `%s' (no host audio driver)\n", name);
431: goto fail;
432: }
433:
434: if (sw && audio_pcm_info_eq (&sw->info, as)) {
435: return sw;
436: }
437:
438: #ifdef DAC
439: if (conf.plive && sw && (!sw->active && !sw->empty)) {
440: live = sw->total_hw_samples_mixed;
441:
442: #ifdef DEBUG_PLIVE
443: dolog ("Replacing voice %s with %d live samples\n", SW_NAME (sw), live);
444: dolog ("Old %s freq %d, bits %d, channels %d\n",
445: SW_NAME (sw), sw->info.freq, sw->info.bits, sw->info.nchannels);
446: dolog ("New %s freq %d, bits %d, channels %d\n",
447: name,
448: freq,
449: (fmt == AUD_FMT_S16 || fmt == AUD_FMT_U16) ? 16 : 8,
450: nchannels);
451: #endif
452:
453: if (live) {
454: old_sw = sw;
455: old_sw->callback.fn = NULL;
456: sw = NULL;
457: }
458: }
459: #endif
460:
461: if (!glue (conf.fixed_, TYPE).enabled && sw) {
462: glue (AUD_close_, TYPE) (card, sw);
463: sw = NULL;
464: }
465:
466: if (sw) {
467: HW *hw = sw->hw;
468:
469: if (!hw) {
470: dolog ("Internal logic error voice `%s' has no hardware store\n",
471: SW_NAME (sw));
472: goto fail;
473: }
474:
475: glue (audio_pcm_sw_fini_, TYPE) (sw);
1.1.1.2 root 476: if (glue (audio_pcm_sw_init_, TYPE) (sw, hw, name, as)) {
1.1 root 477: goto fail;
478: }
479: }
480: else {
1.1.1.5 ! root 481: sw = glue (audio_pcm_create_voice_pair_, TYPE) (name, as);
1.1 root 482: if (!sw) {
483: dolog ("Failed to create voice `%s'\n", name);
484: return NULL;
485: }
486: }
487:
488: if (sw) {
1.1.1.5 ! root 489: sw->card = card;
1.1 root 490: sw->vol = nominal_volume;
491: sw->callback.fn = callback_fn;
492: sw->callback.opaque = callback_opaque;
493:
494: #ifdef DAC
495: if (live) {
496: int mixed =
497: (live << old_sw->info.shift)
498: * old_sw->info.bytes_per_second
499: / sw->info.bytes_per_second;
500:
501: #ifdef DEBUG_PLIVE
502: dolog ("Silence will be mixed %d\n", mixed);
503: #endif
504: sw->total_hw_samples_mixed += mixed;
505: }
506: #endif
507:
508: #ifdef DEBUG_AUDIO
509: dolog ("%s\n", name);
510: audio_pcm_print_info ("hw", &sw->hw->info);
511: audio_pcm_print_info ("sw", &sw->info);
512: #endif
513: }
514:
515: return sw;
516:
517: fail:
518: glue (AUD_close_, TYPE) (card, sw);
519: return NULL;
520: }
521:
522: int glue (AUD_is_active_, TYPE) (SW *sw)
523: {
524: return sw ? sw->active : 0;
525: }
526:
527: void glue (AUD_init_time_stamp_, TYPE) (SW *sw, QEMUAudioTimeStamp *ts)
528: {
529: if (!sw) {
530: return;
531: }
532:
533: ts->old_ts = sw->hw->ts_helper;
534: }
535:
536: uint64_t glue (AUD_get_elapsed_usec_, TYPE) (SW *sw, QEMUAudioTimeStamp *ts)
537: {
538: uint64_t delta, cur_ts, old_ts;
539:
540: if (!sw) {
541: return 0;
542: }
543:
544: cur_ts = sw->hw->ts_helper;
545: old_ts = ts->old_ts;
546: /* dolog ("cur %lld old %lld\n", cur_ts, old_ts); */
547:
548: if (cur_ts >= old_ts) {
549: delta = cur_ts - old_ts;
550: }
551: else {
552: delta = UINT64_MAX - old_ts + cur_ts;
553: }
554:
555: if (!delta) {
556: return 0;
557: }
558:
559: return (delta * sw->hw->info.freq) / 1000000;
560: }
561:
562: #undef TYPE
563: #undef HW
564: #undef SW
565: #undef HWBUF
566: #undef NAME
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.