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