|
|
1.1 root 1: /*
2: * QEMU Audio subsystem
1.1.1.2 root 3: *
4: * Copyright (c) 2003-2005 Vassili Karpov (malc)
5: *
1.1 root 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: */
1.1.1.5 root 24: #include "hw/hw.h"
25: #include "audio.h"
1.1.1.7 root 26: #include "monitor.h"
1.1.1.5 root 27: #include "qemu-timer.h"
28: #include "sysemu.h"
1.1 root 29:
1.1.1.2 root 30: #define AUDIO_CAP "audio"
31: #include "audio_int.h"
1.1 root 32:
1.1.1.2 root 33: /* #define DEBUG_PLIVE */
34: /* #define DEBUG_LIVE */
35: /* #define DEBUG_OUT */
1.1.1.3 root 36: /* #define DEBUG_CAPTURE */
1.1.1.8 root 37: /* #define DEBUG_POLL */
1.1 root 38:
1.1.1.2 root 39: #define SW_NAME(sw) (sw)->name ? (sw)->name : "unknown"
40:
1.1.1.8 root 41:
42: /* Order of CONFIG_AUDIO_DRIVERS is import.
43: The 1st one is the one used by default, that is the reason
44: that we generate the list.
45: */
1.1.1.2 root 46: static struct audio_driver *drvtab[] = {
1.1.1.8 root 47: CONFIG_AUDIO_DRIVERS
1.1.1.2 root 48: &no_audio_driver,
49: &wav_audio_driver
50: };
51:
52: struct fixed_settings {
53: int enabled;
54: int nb_voices;
55: int greedy;
1.1.1.6 root 56: struct audsettings settings;
1.1.1.2 root 57: };
58:
59: static struct {
60: struct fixed_settings fixed_out;
61: struct fixed_settings fixed_in;
62: union {
1.1.1.6 root 63: int hertz;
1.1.1.2 root 64: int64_t ticks;
65: } period;
66: int plive;
67: int log_to_monitor;
1.1.1.8 root 68: int try_poll_in;
69: int try_poll_out;
1.1.1.2 root 70: } conf = {
1.1.1.8 root 71: .fixed_out = { /* DAC fixed settings */
72: .enabled = 1,
73: .nb_voices = 1,
74: .greedy = 1,
75: .settings = {
76: .freq = 44100,
77: .nchannels = 2,
78: .fmt = AUD_FMT_S16,
79: .endianness = AUDIO_HOST_ENDIANNESS,
1.1.1.2 root 80: }
81: },
82:
1.1.1.8 root 83: .fixed_in = { /* ADC fixed settings */
84: .enabled = 1,
85: .nb_voices = 1,
86: .greedy = 1,
87: .settings = {
88: .freq = 44100,
89: .nchannels = 2,
90: .fmt = AUD_FMT_S16,
91: .endianness = AUDIO_HOST_ENDIANNESS,
1.1.1.2 root 92: }
93: },
94:
1.1.1.8 root 95: .period = { .hertz = 250 },
96: .plive = 0,
97: .log_to_monitor = 0,
98: .try_poll_in = 1,
99: .try_poll_out = 1,
1.1.1.2 root 100: };
1.1 root 101:
1.1.1.2 root 102: static AudioState glob_audio_state;
103:
1.1.1.6 root 104: struct mixeng_volume nominal_volume = {
1.1.1.8 root 105: .mute = 0,
1.1.1.2 root 106: #ifdef FLOAT_MIXENG
1.1.1.8 root 107: .r = 1.0,
108: .l = 1.0,
1.1.1.2 root 109: #else
1.1.1.8 root 110: .r = 1ULL << 32,
111: .l = 1ULL << 32,
1.1.1.2 root 112: #endif
1.1 root 113: };
114:
1.1.1.2 root 115: #ifdef AUDIO_IS_FLAWLESS_AND_NO_CHECKS_ARE_REQURIED
116: #error No its not
117: #else
1.1.1.9 ! root 118: static void audio_print_options (const char *prefix,
! 119: struct audio_option *opt);
! 120:
1.1.1.2 root 121: int audio_bug (const char *funcname, int cond)
122: {
123: if (cond) {
124: static int shown;
125:
1.1.1.3 root 126: AUD_log (NULL, "A bug was just triggered in %s\n", funcname);
1.1.1.2 root 127: if (!shown) {
1.1.1.9 ! root 128: struct audio_driver *d;
! 129:
1.1.1.2 root 130: shown = 1;
131: AUD_log (NULL, "Save all your work and restart without audio\n");
1.1.1.8 root 132: AUD_log (NULL, "Please send bug report to [email protected]\n");
1.1.1.2 root 133: AUD_log (NULL, "I am sorry\n");
1.1.1.9 ! root 134: d = glob_audio_state.drv;
! 135: if (d) {
! 136: audio_print_options (d->name, d->options);
! 137: }
1.1.1.2 root 138: }
139: AUD_log (NULL, "Context:\n");
140:
141: #if defined AUDIO_BREAKPOINT_ON_BUG
142: # if defined HOST_I386
143: # if defined __GNUC__
144: __asm__ ("int3");
145: # elif defined _MSC_VER
146: _asm _emit 0xcc;
147: # else
148: abort ();
149: # endif
150: # else
151: abort ();
152: # endif
153: #endif
154: }
155:
156: return cond;
157: }
158: #endif
159:
1.1.1.5 root 160: static inline int audio_bits_to_index (int bits)
161: {
162: switch (bits) {
163: case 8:
164: return 0;
165:
166: case 16:
167: return 1;
168:
169: case 32:
170: return 2;
171:
172: default:
173: audio_bug ("bits_to_index", 1);
174: AUD_log (NULL, "invalid bits %d\n", bits);
175: return 0;
176: }
177: }
178:
1.1.1.2 root 179: void *audio_calloc (const char *funcname, int nmemb, size_t size)
180: {
181: int cond;
182: size_t len;
183:
184: len = nmemb * size;
185: cond = !nmemb || !size;
186: cond |= nmemb < 0;
187: cond |= len < size;
188:
189: if (audio_bug ("audio_calloc", cond)) {
190: AUD_log (NULL, "%s passed invalid arguments to audio_calloc\n",
191: funcname);
192: AUD_log (NULL, "nmemb=%d size=%zu (len=%zu)\n", nmemb, size, len);
193: return NULL;
194: }
195:
196: return qemu_mallocz (len);
197: }
198:
199: static char *audio_alloc_prefix (const char *s)
1.1 root 200: {
1.1.1.2 root 201: const char qemu_prefix[] = "QEMU_";
1.1.1.6 root 202: size_t len, i;
203: char *r, *u;
1.1.1.2 root 204:
205: if (!s) {
206: return NULL;
207: }
208:
209: len = strlen (s);
210: r = qemu_malloc (len + sizeof (qemu_prefix));
211:
1.1.1.6 root 212: u = r + sizeof (qemu_prefix) - 1;
1.1.1.2 root 213:
1.1.1.6 root 214: pstrcpy (r, len + sizeof (qemu_prefix), qemu_prefix);
215: pstrcat (r, len + sizeof (qemu_prefix), s);
1.1.1.2 root 216:
1.1.1.6 root 217: for (i = 0; i < len; ++i) {
218: u[i] = qemu_toupper(u[i]);
1.1.1.2 root 219: }
1.1.1.6 root 220:
1.1.1.2 root 221: return r;
222: }
223:
1.1.1.5 root 224: static const char *audio_audfmt_to_string (audfmt_e fmt)
1.1.1.2 root 225: {
226: switch (fmt) {
227: case AUD_FMT_U8:
228: return "U8";
229:
230: case AUD_FMT_U16:
231: return "U16";
232:
233: case AUD_FMT_S8:
234: return "S8";
235:
236: case AUD_FMT_S16:
237: return "S16";
1.1.1.5 root 238:
239: case AUD_FMT_U32:
240: return "U32";
241:
242: case AUD_FMT_S32:
243: return "S32";
1.1.1.2 root 244: }
245:
246: dolog ("Bogus audfmt %d returning S16\n", fmt);
247: return "S16";
248: }
249:
1.1.1.5 root 250: static audfmt_e audio_string_to_audfmt (const char *s, audfmt_e defval,
251: int *defaultp)
1.1.1.2 root 252: {
253: if (!strcasecmp (s, "u8")) {
254: *defaultp = 0;
255: return AUD_FMT_U8;
256: }
257: else if (!strcasecmp (s, "u16")) {
258: *defaultp = 0;
259: return AUD_FMT_U16;
260: }
1.1.1.5 root 261: else if (!strcasecmp (s, "u32")) {
262: *defaultp = 0;
263: return AUD_FMT_U32;
264: }
1.1.1.2 root 265: else if (!strcasecmp (s, "s8")) {
266: *defaultp = 0;
267: return AUD_FMT_S8;
268: }
269: else if (!strcasecmp (s, "s16")) {
270: *defaultp = 0;
271: return AUD_FMT_S16;
272: }
1.1.1.5 root 273: else if (!strcasecmp (s, "s32")) {
274: *defaultp = 0;
275: return AUD_FMT_S32;
276: }
1.1.1.2 root 277: else {
278: dolog ("Bogus audio format `%s' using %s\n",
279: s, audio_audfmt_to_string (defval));
280: *defaultp = 1;
281: return defval;
282: }
283: }
284:
285: static audfmt_e audio_get_conf_fmt (const char *envname,
286: audfmt_e defval,
287: int *defaultp)
288: {
289: const char *var = getenv (envname);
290: if (!var) {
291: *defaultp = 1;
292: return defval;
293: }
294: return audio_string_to_audfmt (var, defval, defaultp);
295: }
296:
297: static int audio_get_conf_int (const char *key, int defval, int *defaultp)
298: {
299: int val;
1.1 root 300: char *strval;
301:
302: strval = getenv (key);
303: if (strval) {
1.1.1.2 root 304: *defaultp = 0;
1.1 root 305: val = atoi (strval);
1.1.1.2 root 306: return val;
307: }
308: else {
309: *defaultp = 1;
310: return defval;
1.1 root 311: }
312: }
313:
1.1.1.2 root 314: static const char *audio_get_conf_str (const char *key,
315: const char *defval,
316: int *defaultp)
1.1 root 317: {
318: const char *val = getenv (key);
1.1.1.2 root 319: if (!val) {
320: *defaultp = 1;
1.1 root 321: return defval;
1.1.1.2 root 322: }
323: else {
324: *defaultp = 0;
1.1 root 325: return val;
1.1.1.2 root 326: }
327: }
328:
329: void AUD_vlog (const char *cap, const char *fmt, va_list ap)
330: {
331: if (conf.log_to_monitor) {
332: if (cap) {
1.1.1.9 ! root 333: monitor_printf(default_mon, "%s: ", cap);
1.1.1.2 root 334: }
335:
1.1.1.9 ! root 336: monitor_vprintf(default_mon, fmt, ap);
1.1.1.2 root 337: }
338: else {
339: if (cap) {
340: fprintf (stderr, "%s: ", cap);
341: }
342:
343: vfprintf (stderr, fmt, ap);
344: }
1.1 root 345: }
346:
347: void AUD_log (const char *cap, const char *fmt, ...)
348: {
349: va_list ap;
1.1.1.2 root 350:
1.1 root 351: va_start (ap, fmt);
1.1.1.2 root 352: AUD_vlog (cap, fmt, ap);
1.1 root 353: va_end (ap);
354: }
355:
1.1.1.2 root 356: static void audio_print_options (const char *prefix,
357: struct audio_option *opt)
1.1 root 358: {
1.1.1.2 root 359: char *uprefix;
360:
361: if (!prefix) {
362: dolog ("No prefix specified\n");
363: return;
364: }
365:
366: if (!opt) {
367: dolog ("No options\n");
368: return;
369: }
370:
371: uprefix = audio_alloc_prefix (prefix);
372:
373: for (; opt->name; opt++) {
374: const char *state = "default";
375: printf (" %s_%s: ", uprefix, opt->name);
376:
1.1.1.5 root 377: if (opt->overriddenp && *opt->overriddenp) {
1.1.1.2 root 378: state = "current";
379: }
380:
381: switch (opt->tag) {
382: case AUD_OPT_BOOL:
383: {
384: int *intp = opt->valp;
385: printf ("boolean, %s = %d\n", state, *intp ? 1 : 0);
386: }
387: break;
388:
389: case AUD_OPT_INT:
390: {
391: int *intp = opt->valp;
392: printf ("integer, %s = %d\n", state, *intp);
393: }
394: break;
395:
396: case AUD_OPT_FMT:
397: {
398: audfmt_e *fmtp = opt->valp;
399: printf (
1.1.1.6 root 400: "format, %s = %s, (one of: U8 S8 U16 S16 U32 S32)\n",
1.1.1.2 root 401: state,
402: audio_audfmt_to_string (*fmtp)
403: );
404: }
405: break;
406:
407: case AUD_OPT_STR:
408: {
409: const char **strp = opt->valp;
410: printf ("string, %s = %s\n",
411: state,
412: *strp ? *strp : "(not set)");
413: }
414: break;
415:
416: default:
417: printf ("???\n");
418: dolog ("Bad value tag for option %s_%s %d\n",
419: uprefix, opt->name, opt->tag);
420: break;
421: }
422: printf (" %s\n", opt->descr);
423: }
424:
425: qemu_free (uprefix);
1.1 root 426: }
427:
1.1.1.2 root 428: static void audio_process_options (const char *prefix,
429: struct audio_option *opt)
1.1 root 430: {
1.1.1.2 root 431: char *optname;
432: const char qemu_prefix[] = "QEMU_";
1.1.1.6 root 433: size_t preflen, optlen;
1.1.1.2 root 434:
435: if (audio_bug (AUDIO_FUNC, !prefix)) {
436: dolog ("prefix = NULL\n");
437: return;
438: }
439:
440: if (audio_bug (AUDIO_FUNC, !opt)) {
441: dolog ("opt = NULL\n");
442: return;
443: }
444:
445: preflen = strlen (prefix);
446:
447: for (; opt->name; opt++) {
448: size_t len, i;
449: int def;
450:
451: if (!opt->valp) {
452: dolog ("Option value pointer for `%s' is not set\n",
453: opt->name);
454: continue;
455: }
456:
457: len = strlen (opt->name);
458: /* len of opt->name + len of prefix + size of qemu_prefix
459: * (includes trailing zero) + zero + underscore (on behalf of
460: * sizeof) */
1.1.1.6 root 461: optlen = len + preflen + sizeof (qemu_prefix) + 1;
462: optname = qemu_malloc (optlen);
1.1.1.2 root 463:
1.1.1.6 root 464: pstrcpy (optname, optlen, qemu_prefix);
1.1.1.2 root 465:
466: /* copy while upper-casing, including trailing zero */
467: for (i = 0; i <= preflen; ++i) {
1.1.1.6 root 468: optname[i + sizeof (qemu_prefix) - 1] = qemu_toupper(prefix[i]);
1.1.1.2 root 469: }
1.1.1.6 root 470: pstrcat (optname, optlen, "_");
471: pstrcat (optname, optlen, opt->name);
1.1.1.2 root 472:
473: def = 1;
474: switch (opt->tag) {
475: case AUD_OPT_BOOL:
476: case AUD_OPT_INT:
477: {
478: int *intp = opt->valp;
479: *intp = audio_get_conf_int (optname, *intp, &def);
480: }
481: break;
482:
483: case AUD_OPT_FMT:
484: {
485: audfmt_e *fmtp = opt->valp;
486: *fmtp = audio_get_conf_fmt (optname, *fmtp, &def);
487: }
488: break;
489:
490: case AUD_OPT_STR:
491: {
492: const char **strp = opt->valp;
493: *strp = audio_get_conf_str (optname, *strp, &def);
494: }
495: break;
1.1 root 496:
1.1.1.2 root 497: default:
498: dolog ("Bad value tag for option `%s' - %d\n",
499: optname, opt->tag);
500: break;
501: }
502:
1.1.1.5 root 503: if (!opt->overriddenp) {
504: opt->overriddenp = &opt->overridden;
1.1.1.2 root 505: }
1.1.1.5 root 506: *opt->overriddenp = !def;
1.1.1.2 root 507: qemu_free (optname);
508: }
509: }
510:
1.1.1.6 root 511: static void audio_print_settings (struct audsettings *as)
1.1.1.2 root 512: {
513: dolog ("frequency=%d nchannels=%d fmt=", as->freq, as->nchannels);
514:
515: switch (as->fmt) {
516: case AUD_FMT_S8:
517: AUD_log (NULL, "S8");
518: break;
519: case AUD_FMT_U8:
520: AUD_log (NULL, "U8");
521: break;
522: case AUD_FMT_S16:
523: AUD_log (NULL, "S16");
524: break;
525: case AUD_FMT_U16:
526: AUD_log (NULL, "U16");
527: break;
1.1.1.6 root 528: case AUD_FMT_S32:
529: AUD_log (NULL, "S32");
530: break;
531: case AUD_FMT_U32:
532: AUD_log (NULL, "U32");
533: break;
1.1.1.2 root 534: default:
535: AUD_log (NULL, "invalid(%d)", as->fmt);
536: break;
537: }
1.1.1.3 root 538:
539: AUD_log (NULL, " endianness=");
540: switch (as->endianness) {
541: case 0:
542: AUD_log (NULL, "little");
543: break;
544: case 1:
545: AUD_log (NULL, "big");
546: break;
547: default:
548: AUD_log (NULL, "invalid");
549: break;
550: }
1.1.1.2 root 551: AUD_log (NULL, "\n");
552: }
553:
1.1.1.6 root 554: static int audio_validate_settings (struct audsettings *as)
1.1.1.2 root 555: {
556: int invalid;
557:
558: invalid = as->nchannels != 1 && as->nchannels != 2;
1.1.1.3 root 559: invalid |= as->endianness != 0 && as->endianness != 1;
1.1.1.2 root 560:
561: switch (as->fmt) {
562: case AUD_FMT_S8:
563: case AUD_FMT_U8:
564: case AUD_FMT_S16:
565: case AUD_FMT_U16:
1.1.1.5 root 566: case AUD_FMT_S32:
567: case AUD_FMT_U32:
1.1.1.2 root 568: break;
569: default:
570: invalid = 1;
571: break;
572: }
573:
574: invalid |= as->freq <= 0;
1.1.1.3 root 575: return invalid ? -1 : 0;
1.1 root 576: }
577:
1.1.1.6 root 578: static int audio_pcm_info_eq (struct audio_pcm_info *info, struct audsettings *as)
1.1 root 579: {
1.1.1.2 root 580: int bits = 8, sign = 0;
581:
582: switch (as->fmt) {
583: case AUD_FMT_S8:
584: sign = 1;
585: case AUD_FMT_U8:
586: break;
587:
588: case AUD_FMT_S16:
589: sign = 1;
590: case AUD_FMT_U16:
591: bits = 16;
592: break;
1.1.1.5 root 593:
594: case AUD_FMT_S32:
595: sign = 1;
596: case AUD_FMT_U32:
597: bits = 32;
598: break;
1.1.1.2 root 599: }
600: return info->freq == as->freq
601: && info->nchannels == as->nchannels
602: && info->sign == sign
1.1.1.3 root 603: && info->bits == bits
604: && info->swap_endianness == (as->endianness != AUDIO_HOST_ENDIANNESS);
1.1 root 605: }
606:
1.1.1.6 root 607: void audio_pcm_init_info (struct audio_pcm_info *info, struct audsettings *as)
1.1 root 608: {
1.1.1.5 root 609: int bits = 8, sign = 0, shift = 0;
1.1 root 610:
1.1.1.2 root 611: switch (as->fmt) {
1.1 root 612: case AUD_FMT_S8:
613: sign = 1;
614: case AUD_FMT_U8:
615: break;
616:
617: case AUD_FMT_S16:
618: sign = 1;
619: case AUD_FMT_U16:
620: bits = 16;
1.1.1.5 root 621: shift = 1;
622: break;
623:
624: case AUD_FMT_S32:
625: sign = 1;
626: case AUD_FMT_U32:
627: bits = 32;
628: shift = 2;
1.1 root 629: break;
630: }
631:
1.1.1.2 root 632: info->freq = as->freq;
633: info->bits = bits;
634: info->sign = sign;
635: info->nchannels = as->nchannels;
1.1.1.5 root 636: info->shift = (as->nchannels == 2) + shift;
1.1.1.2 root 637: info->align = (1 << info->shift) - 1;
638: info->bytes_per_second = info->freq << info->shift;
1.1.1.3 root 639: info->swap_endianness = (as->endianness != AUDIO_HOST_ENDIANNESS);
1.1 root 640: }
641:
1.1.1.2 root 642: void audio_pcm_info_clear_buf (struct audio_pcm_info *info, void *buf, int len)
1.1 root 643: {
1.1.1.2 root 644: if (!len) {
645: return;
646: }
647:
648: if (info->sign) {
1.1.1.4 root 649: memset (buf, 0x00, len << info->shift);
1.1.1.2 root 650: }
651: else {
1.1.1.5 root 652: switch (info->bits) {
653: case 8:
1.1.1.4 root 654: memset (buf, 0x80, len << info->shift);
1.1.1.5 root 655: break;
1.1.1.2 root 656:
1.1.1.5 root 657: case 16:
658: {
659: int i;
660: uint16_t *p = buf;
661: int shift = info->nchannels - 1;
662: short s = INT16_MAX;
663:
664: if (info->swap_endianness) {
665: s = bswap16 (s);
666: }
667:
668: for (i = 0; i < len << shift; i++) {
669: p[i] = s;
670: }
1.1.1.2 root 671: }
1.1.1.5 root 672: break;
673:
674: case 32:
675: {
676: int i;
677: uint32_t *p = buf;
678: int shift = info->nchannels - 1;
679: int32_t s = INT32_MAX;
680:
681: if (info->swap_endianness) {
682: s = bswap32 (s);
683: }
1.1.1.2 root 684:
1.1.1.5 root 685: for (i = 0; i < len << shift; i++) {
686: p[i] = s;
687: }
1.1.1.2 root 688: }
1.1.1.5 root 689: break;
690:
691: default:
692: AUD_log (NULL, "audio_pcm_info_clear_buf: invalid bits %d\n",
693: info->bits);
694: break;
1.1.1.2 root 695: }
696: }
1.1 root 697: }
698:
1.1.1.2 root 699: /*
1.1.1.3 root 700: * Capture
701: */
1.1.1.6 root 702: static void noop_conv (struct st_sample *dst, const void *src,
703: int samples, struct mixeng_volume *vol)
1.1.1.3 root 704: {
705: (void) src;
706: (void) dst;
707: (void) samples;
708: (void) vol;
709: }
710:
711: static CaptureVoiceOut *audio_pcm_capture_find_specific (
1.1.1.6 root 712: struct audsettings *as
1.1.1.3 root 713: )
714: {
715: CaptureVoiceOut *cap;
1.1.1.7 root 716: AudioState *s = &glob_audio_state;
1.1.1.3 root 717:
718: for (cap = s->cap_head.lh_first; cap; cap = cap->entries.le_next) {
719: if (audio_pcm_info_eq (&cap->hw.info, as)) {
720: return cap;
721: }
722: }
723: return NULL;
724: }
725:
726: static void audio_notify_capture (CaptureVoiceOut *cap, audcnotification_e cmd)
727: {
728: struct capture_callback *cb;
729:
730: #ifdef DEBUG_CAPTURE
731: dolog ("notification %d sent\n", cmd);
732: #endif
733: for (cb = cap->cb_head.lh_first; cb; cb = cb->entries.le_next) {
734: cb->ops.notify (cb->opaque, cmd);
735: }
736: }
737:
738: static void audio_capture_maybe_changed (CaptureVoiceOut *cap, int enabled)
739: {
740: if (cap->hw.enabled != enabled) {
741: audcnotification_e cmd;
742: cap->hw.enabled = enabled;
743: cmd = enabled ? AUD_CNOTIFY_ENABLE : AUD_CNOTIFY_DISABLE;
744: audio_notify_capture (cap, cmd);
745: }
746: }
747:
748: static void audio_recalc_and_notify_capture (CaptureVoiceOut *cap)
749: {
750: HWVoiceOut *hw = &cap->hw;
751: SWVoiceOut *sw;
752: int enabled = 0;
753:
754: for (sw = hw->sw_head.lh_first; sw; sw = sw->entries.le_next) {
755: if (sw->active) {
756: enabled = 1;
757: break;
758: }
759: }
760: audio_capture_maybe_changed (cap, enabled);
761: }
762:
763: static void audio_detach_capture (HWVoiceOut *hw)
764: {
765: SWVoiceCap *sc = hw->cap_head.lh_first;
766:
767: while (sc) {
768: SWVoiceCap *sc1 = sc->entries.le_next;
769: SWVoiceOut *sw = &sc->sw;
770: CaptureVoiceOut *cap = sc->cap;
771: int was_active = sw->active;
772:
773: if (sw->rate) {
774: st_rate_stop (sw->rate);
775: sw->rate = NULL;
776: }
777:
1.1.1.8 root 778: QLIST_REMOVE (sw, entries);
779: QLIST_REMOVE (sc, entries);
1.1.1.3 root 780: qemu_free (sc);
781: if (was_active) {
782: /* We have removed soft voice from the capture:
783: this might have changed the overall status of the capture
784: since this might have been the only active voice */
785: audio_recalc_and_notify_capture (cap);
786: }
787: sc = sc1;
788: }
789: }
790:
1.1.1.7 root 791: static int audio_attach_capture (HWVoiceOut *hw)
1.1.1.3 root 792: {
1.1.1.7 root 793: AudioState *s = &glob_audio_state;
1.1.1.3 root 794: CaptureVoiceOut *cap;
795:
796: audio_detach_capture (hw);
797: for (cap = s->cap_head.lh_first; cap; cap = cap->entries.le_next) {
798: SWVoiceCap *sc;
799: SWVoiceOut *sw;
800: HWVoiceOut *hw_cap = &cap->hw;
801:
802: sc = audio_calloc (AUDIO_FUNC, 1, sizeof (*sc));
803: if (!sc) {
804: dolog ("Could not allocate soft capture voice (%zu bytes)\n",
805: sizeof (*sc));
806: return -1;
807: }
808:
809: sc->cap = cap;
810: sw = &sc->sw;
811: sw->hw = hw_cap;
812: sw->info = hw->info;
813: sw->empty = 1;
814: sw->active = hw->enabled;
815: sw->conv = noop_conv;
816: sw->ratio = ((int64_t) hw_cap->info.freq << 32) / sw->info.freq;
817: sw->rate = st_rate_start (sw->info.freq, hw_cap->info.freq);
818: if (!sw->rate) {
819: dolog ("Could not start rate conversion for `%s'\n", SW_NAME (sw));
820: qemu_free (sw);
821: return -1;
822: }
1.1.1.8 root 823: QLIST_INSERT_HEAD (&hw_cap->sw_head, sw, entries);
824: QLIST_INSERT_HEAD (&hw->cap_head, sc, entries);
1.1.1.3 root 825: #ifdef DEBUG_CAPTURE
826: asprintf (&sw->name, "for %p %d,%d,%d",
827: hw, sw->info.freq, sw->info.bits, sw->info.nchannels);
828: dolog ("Added %s active = %d\n", sw->name, sw->active);
829: #endif
830: if (sw->active) {
831: audio_capture_maybe_changed (cap, 1);
832: }
833: }
834: return 0;
835: }
836:
837: /*
1.1.1.2 root 838: * Hard voice (capture)
839: */
840: static int audio_pcm_hw_find_min_in (HWVoiceIn *hw)
1.1 root 841: {
1.1.1.2 root 842: SWVoiceIn *sw;
843: int m = hw->total_samples_captured;
844:
845: for (sw = hw->sw_head.lh_first; sw; sw = sw->entries.le_next) {
846: if (sw->active) {
847: m = audio_MIN (m, sw->total_hw_samples_acquired);
848: }
1.1 root 849: }
1.1.1.2 root 850: return m;
1.1 root 851: }
852:
1.1.1.2 root 853: int audio_pcm_hw_get_live_in (HWVoiceIn *hw)
1.1 root 854: {
1.1.1.2 root 855: int live = hw->total_samples_captured - audio_pcm_hw_find_min_in (hw);
856: if (audio_bug (AUDIO_FUNC, live < 0 || live > hw->samples)) {
857: dolog ("live=%d hw->samples=%d\n", live, hw->samples);
858: return 0;
859: }
860: return live;
1.1 root 861: }
862:
1.1.1.8 root 863: int audio_pcm_hw_clip_out (HWVoiceOut *hw, void *pcm_buf,
864: int live, int pending)
865: {
866: int left = hw->samples - pending;
867: int len = audio_MIN (left, live);
868: int clipped = 0;
869:
870: while (len) {
871: struct st_sample *src = hw->mix_buf + hw->rpos;
872: uint8_t *dst = advance (pcm_buf, hw->rpos << hw->info.shift);
873: int samples_till_end_of_buf = hw->samples - hw->rpos;
874: int samples_to_clip = audio_MIN (len, samples_till_end_of_buf);
875:
876: hw->clip (dst, src, samples_to_clip);
877:
878: hw->rpos = (hw->rpos + samples_to_clip) % hw->samples;
879: len -= samples_to_clip;
880: clipped += samples_to_clip;
881: }
882: return clipped;
883: }
884:
1.1.1.2 root 885: /*
886: * Soft voice (capture)
887: */
888: static int audio_pcm_sw_get_rpos_in (SWVoiceIn *sw)
1.1 root 889: {
1.1.1.2 root 890: HWVoiceIn *hw = sw->hw;
891: int live = hw->total_samples_captured - sw->total_hw_samples_acquired;
892: int rpos;
1.1 root 893:
1.1.1.2 root 894: if (audio_bug (AUDIO_FUNC, live < 0 || live > hw->samples)) {
895: dolog ("live=%d hw->samples=%d\n", live, hw->samples);
896: return 0;
1.1 root 897: }
898:
1.1.1.2 root 899: rpos = hw->wpos - live;
900: if (rpos >= 0) {
901: return rpos;
902: }
903: else {
904: return hw->samples + rpos;
905: }
1.1 root 906: }
907:
1.1.1.2 root 908: int audio_pcm_sw_read (SWVoiceIn *sw, void *buf, int size)
1.1 root 909: {
1.1.1.2 root 910: HWVoiceIn *hw = sw->hw;
911: int samples, live, ret = 0, swlim, isamp, osamp, rpos, total = 0;
1.1.1.6 root 912: struct st_sample *src, *dst = sw->buf;
1.1 root 913:
1.1.1.2 root 914: rpos = audio_pcm_sw_get_rpos_in (sw) % hw->samples;
915:
916: live = hw->total_samples_captured - sw->total_hw_samples_acquired;
917: if (audio_bug (AUDIO_FUNC, live < 0 || live > hw->samples)) {
918: dolog ("live_in=%d hw->samples=%d\n", live, hw->samples);
919: return 0;
920: }
921:
922: samples = size >> sw->info.shift;
923: if (!live) {
924: return 0;
925: }
926:
927: swlim = (live * sw->ratio) >> 32;
928: swlim = audio_MIN (swlim, samples);
929:
930: while (swlim) {
931: src = hw->conv_buf + rpos;
932: isamp = hw->wpos - rpos;
933: /* XXX: <= ? */
934: if (isamp <= 0) {
935: isamp = hw->samples - rpos;
1.1 root 936: }
1.1.1.2 root 937:
938: if (!isamp) {
939: break;
940: }
941: osamp = swlim;
942:
943: if (audio_bug (AUDIO_FUNC, osamp < 0)) {
944: dolog ("osamp=%d\n", osamp);
945: return 0;
946: }
947:
948: st_rate_flow (sw->rate, src, dst, &isamp, &osamp);
949: swlim -= osamp;
950: rpos = (rpos + isamp) % hw->samples;
951: dst += osamp;
952: ret += osamp;
953: total += isamp;
1.1 root 954: }
955:
1.1.1.2 root 956: sw->clip (buf, sw->buf, ret);
957: sw->total_hw_samples_acquired += total;
958: return ret << sw->info.shift;
1.1 root 959: }
960:
1.1.1.2 root 961: /*
962: * Hard voice (playback)
963: */
964: static int audio_pcm_hw_find_min_out (HWVoiceOut *hw, int *nb_livep)
1.1 root 965: {
1.1.1.2 root 966: SWVoiceOut *sw;
967: int m = INT_MAX;
968: int nb_live = 0;
1.1 root 969:
1.1.1.2 root 970: for (sw = hw->sw_head.lh_first; sw; sw = sw->entries.le_next) {
971: if (sw->active || !sw->empty) {
972: m = audio_MIN (m, sw->total_hw_samples_mixed);
973: nb_live += 1;
1.1 root 974: }
975: }
1.1.1.2 root 976:
977: *nb_livep = nb_live;
978: return m;
1.1 root 979: }
980:
1.1.1.8 root 981: static int audio_pcm_hw_get_live_out (HWVoiceOut *hw, int *nb_live)
1.1 root 982: {
1.1.1.2 root 983: int smin;
1.1.1.8 root 984: int nb_live1;
1.1 root 985:
1.1.1.8 root 986: smin = audio_pcm_hw_find_min_out (hw, &nb_live1);
987: if (nb_live) {
988: *nb_live = nb_live1;
1.1.1.2 root 989: }
1.1.1.8 root 990:
991: if (nb_live1) {
1.1.1.2 root 992: int live = smin;
1.1 root 993:
1.1.1.2 root 994: if (audio_bug (AUDIO_FUNC, live < 0 || live > hw->samples)) {
995: dolog ("live=%d hw->samples=%d\n", live, hw->samples);
996: return 0;
1.1 root 997: }
1.1.1.2 root 998: return live;
1.1 root 999: }
1.1.1.8 root 1000: return 0;
1.1.1.2 root 1001: }
1002:
1003: /*
1004: * Soft voice (playback)
1005: */
1006: int audio_pcm_sw_write (SWVoiceOut *sw, void *buf, int size)
1.1 root 1007: {
1008: int hwsamples, samples, isamp, osamp, wpos, live, dead, left, swlim, blck;
1.1.1.2 root 1009: int ret = 0, pos = 0, total = 0;
1010:
1011: if (!sw) {
1.1 root 1012: return size;
1.1.1.2 root 1013: }
1.1 root 1014:
1015: hwsamples = sw->hw->samples;
1016:
1.1.1.2 root 1017: live = sw->total_hw_samples_mixed;
1018: if (audio_bug (AUDIO_FUNC, live < 0 || live > hwsamples)){
1019: dolog ("live=%d hw->samples=%d\n", live, hwsamples);
1020: return 0;
1.1 root 1021: }
1.1.1.2 root 1022:
1023: if (live == hwsamples) {
1.1.1.3 root 1024: #ifdef DEBUG_OUT
1025: dolog ("%s is full %d\n", sw->name, live);
1026: #endif
1.1.1.2 root 1027: return 0;
1028: }
1029:
1030: wpos = (sw->hw->rpos + live) % hwsamples;
1031: samples = size >> sw->info.shift;
1032:
1.1 root 1033: dead = hwsamples - live;
1.1.1.2 root 1034: swlim = ((int64_t) dead << 32) / sw->ratio;
1.1 root 1035: swlim = audio_MIN (swlim, samples);
1.1.1.2 root 1036: if (swlim) {
1037: sw->conv (sw->buf, buf, swlim, &sw->vol);
1038: }
1.1 root 1039:
1040: while (swlim) {
1041: dead = hwsamples - live;
1042: left = hwsamples - wpos;
1043: blck = audio_MIN (dead, left);
1044: if (!blck) {
1045: break;
1046: }
1047: isamp = swlim;
1048: osamp = blck;
1.1.1.2 root 1049: st_rate_flow_mix (
1050: sw->rate,
1051: sw->buf + pos,
1052: sw->hw->mix_buf + wpos,
1053: &isamp,
1054: &osamp
1055: );
1.1 root 1056: ret += isamp;
1057: swlim -= isamp;
1058: pos += isamp;
1059: live += osamp;
1.1.1.2 root 1060: wpos = (wpos + osamp) % hwsamples;
1061: total += osamp;
1.1 root 1062: }
1063:
1.1.1.2 root 1064: sw->total_hw_samples_mixed += total;
1065: sw->empty = sw->total_hw_samples_mixed == 0;
1.1 root 1066:
1.1.1.2 root 1067: #ifdef DEBUG_OUT
1068: dolog (
1069: "%s: write size %d ret %d total sw %d\n",
1070: SW_NAME (sw),
1071: size >> sw->info.shift,
1072: ret,
1073: sw->total_hw_samples_mixed
1074: );
1075: #endif
1.1 root 1076:
1.1.1.2 root 1077: return ret << sw->info.shift;
1.1 root 1078: }
1079:
1.1.1.2 root 1080: #ifdef DEBUG_AUDIO
1081: static void audio_pcm_print_info (const char *cap, struct audio_pcm_info *info)
1.1 root 1082: {
1.1.1.2 root 1083: dolog ("%s: bits %d, sign %d, freq %d, nchan %d\n",
1084: cap, info->bits, info->sign, info->freq, info->nchannels);
1.1 root 1085: }
1.1.1.2 root 1086: #endif
1.1 root 1087:
1.1.1.2 root 1088: #define DAC
1089: #include "audio_template.h"
1090: #undef DAC
1091: #include "audio_template.h"
1.1 root 1092:
1.1.1.8 root 1093: /*
1094: * Timer
1095: */
1096: static void audio_timer (void *opaque)
1097: {
1098: AudioState *s = opaque;
1099:
1100: audio_run ("timer");
1101: qemu_mod_timer (s->ts, qemu_get_clock (vm_clock) + conf.period.ticks);
1102: }
1103:
1104:
1105: static int audio_is_timer_needed (void)
1106: {
1107: HWVoiceIn *hwi = NULL;
1108: HWVoiceOut *hwo = NULL;
1109:
1110: while ((hwo = audio_pcm_hw_find_any_enabled_out (hwo))) {
1111: if (!hwo->poll_mode) return 1;
1112: }
1113: while ((hwi = audio_pcm_hw_find_any_enabled_in (hwi))) {
1114: if (!hwi->poll_mode) return 1;
1115: }
1116: return 0;
1117: }
1118:
1119: static void audio_reset_timer (void)
1120: {
1121: AudioState *s = &glob_audio_state;
1122:
1123: if (audio_is_timer_needed ()) {
1124: qemu_mod_timer (s->ts, qemu_get_clock (vm_clock) + 1);
1125: }
1126: else {
1127: qemu_del_timer (s->ts);
1128: }
1129: }
1130:
1131: /*
1132: * Public API
1133: */
1.1.1.2 root 1134: int AUD_write (SWVoiceOut *sw, void *buf, int size)
1.1 root 1135: {
1.1.1.2 root 1136: int bytes;
1137:
1138: if (!sw) {
1139: /* XXX: Consider options */
1140: return size;
1.1 root 1141: }
1142:
1.1.1.2 root 1143: if (!sw->hw->enabled) {
1144: dolog ("Writing to disabled voice %s\n", SW_NAME (sw));
1145: return 0;
1.1 root 1146: }
1.1.1.2 root 1147:
1148: bytes = sw->hw->pcm_ops->write (sw, buf, size);
1149: return bytes;
1.1 root 1150: }
1151:
1.1.1.2 root 1152: int AUD_read (SWVoiceIn *sw, void *buf, int size)
1.1 root 1153: {
1.1.1.2 root 1154: int bytes;
1155:
1156: if (!sw) {
1157: /* XXX: Consider options */
1158: return size;
1.1 root 1159: }
1160:
1.1.1.2 root 1161: if (!sw->hw->enabled) {
1162: dolog ("Reading from disabled voice %s\n", SW_NAME (sw));
1163: return 0;
1.1 root 1164: }
1.1.1.2 root 1165:
1166: bytes = sw->hw->pcm_ops->read (sw, buf, size);
1167: return bytes;
1.1 root 1168: }
1169:
1.1.1.2 root 1170: int AUD_get_buffer_size_out (SWVoiceOut *sw)
1.1 root 1171: {
1.1.1.2 root 1172: return sw->hw->samples << sw->hw->info.shift;
1.1 root 1173: }
1174:
1.1.1.2 root 1175: void AUD_set_active_out (SWVoiceOut *sw, int on)
1.1 root 1176: {
1.1.1.2 root 1177: HWVoiceOut *hw;
1.1 root 1178:
1.1.1.2 root 1179: if (!sw) {
1180: return;
1.1 root 1181: }
1182:
1.1.1.2 root 1183: hw = sw->hw;
1184: if (sw->active != on) {
1.1.1.6 root 1185: AudioState *s = &glob_audio_state;
1.1.1.2 root 1186: SWVoiceOut *temp_sw;
1.1.1.3 root 1187: SWVoiceCap *sc;
1.1 root 1188:
1.1.1.2 root 1189: if (on) {
1190: hw->pending_disable = 0;
1191: if (!hw->enabled) {
1192: hw->enabled = 1;
1.1.1.6 root 1193: if (s->vm_running) {
1.1.1.8 root 1194: hw->pcm_ops->ctl_out (hw, VOICE_ENABLE, conf.try_poll_out);
1195: audio_reset_timer ();
1.1.1.6 root 1196: }
1.1.1.2 root 1197: }
1.1 root 1198: }
1.1.1.2 root 1199: else {
1200: if (hw->enabled) {
1201: int nb_active = 0;
1202:
1203: for (temp_sw = hw->sw_head.lh_first; temp_sw;
1204: temp_sw = temp_sw->entries.le_next) {
1205: nb_active += temp_sw->active != 0;
1206: }
1.1 root 1207:
1.1.1.2 root 1208: hw->pending_disable = nb_active == 1;
1209: }
1210: }
1.1.1.3 root 1211:
1212: for (sc = hw->cap_head.lh_first; sc; sc = sc->entries.le_next) {
1213: sc->sw.active = hw->enabled;
1214: if (hw->enabled) {
1215: audio_capture_maybe_changed (sc->cap, 1);
1216: }
1217: }
1.1.1.2 root 1218: sw->active = on;
1219: }
1.1 root 1220: }
1221:
1.1.1.2 root 1222: void AUD_set_active_in (SWVoiceIn *sw, int on)
1.1 root 1223: {
1.1.1.2 root 1224: HWVoiceIn *hw;
1.1 root 1225:
1.1.1.2 root 1226: if (!sw) {
1227: return;
1228: }
1.1 root 1229:
1.1.1.2 root 1230: hw = sw->hw;
1231: if (sw->active != on) {
1.1.1.6 root 1232: AudioState *s = &glob_audio_state;
1.1.1.2 root 1233: SWVoiceIn *temp_sw;
1.1 root 1234:
1.1.1.2 root 1235: if (on) {
1236: if (!hw->enabled) {
1237: hw->enabled = 1;
1.1.1.6 root 1238: if (s->vm_running) {
1.1.1.8 root 1239: hw->pcm_ops->ctl_in (hw, VOICE_ENABLE, conf.try_poll_in);
1.1.1.6 root 1240: }
1.1.1.2 root 1241: }
1242: sw->total_hw_samples_acquired = hw->total_samples_captured;
1.1 root 1243: }
1.1.1.2 root 1244: else {
1245: if (hw->enabled) {
1246: int nb_active = 0;
1247:
1248: for (temp_sw = hw->sw_head.lh_first; temp_sw;
1249: temp_sw = temp_sw->entries.le_next) {
1250: nb_active += temp_sw->active != 0;
1251: }
1.1 root 1252:
1.1.1.2 root 1253: if (nb_active == 1) {
1254: hw->enabled = 0;
1255: hw->pcm_ops->ctl_in (hw, VOICE_DISABLE);
1256: }
1.1 root 1257: }
1258: }
1.1.1.2 root 1259: sw->active = on;
1.1 root 1260: }
1.1.1.2 root 1261: }
1262:
1263: static int audio_get_avail (SWVoiceIn *sw)
1264: {
1265: int live;
1266:
1267: if (!sw) {
1268: return 0;
1.1 root 1269: }
1.1.1.2 root 1270:
1271: live = sw->hw->total_samples_captured - sw->total_hw_samples_acquired;
1272: if (audio_bug (AUDIO_FUNC, live < 0 || live > sw->hw->samples)) {
1273: dolog ("live=%d sw->hw->samples=%d\n", live, sw->hw->samples);
1274: return 0;
1275: }
1276:
1277: ldebug (
1.1.1.3 root 1278: "%s: get_avail live %d ret %" PRId64 "\n",
1.1.1.2 root 1279: SW_NAME (sw),
1280: live, (((int64_t) live << 32) / sw->ratio) << sw->info.shift
1281: );
1282:
1283: return (((int64_t) live << 32) / sw->ratio) << sw->info.shift;
1.1 root 1284: }
1285:
1.1.1.2 root 1286: static int audio_get_free (SWVoiceOut *sw)
1.1 root 1287: {
1.1.1.2 root 1288: int live, dead;
1.1 root 1289:
1.1.1.2 root 1290: if (!sw) {
1291: return 0;
1292: }
1.1 root 1293:
1.1.1.2 root 1294: live = sw->total_hw_samples_mixed;
1.1 root 1295:
1.1.1.2 root 1296: if (audio_bug (AUDIO_FUNC, live < 0 || live > sw->hw->samples)) {
1297: dolog ("live=%d sw->hw->samples=%d\n", live, sw->hw->samples);
1298: return 0;
1299: }
1.1 root 1300:
1.1.1.2 root 1301: dead = sw->hw->samples - live;
1.1 root 1302:
1.1.1.2 root 1303: #ifdef DEBUG_OUT
1.1.1.3 root 1304: dolog ("%s: get_free live %d dead %d ret %" PRId64 "\n",
1.1.1.2 root 1305: SW_NAME (sw),
1306: live, dead, (((int64_t) dead << 32) / sw->ratio) << sw->info.shift);
1307: #endif
1.1 root 1308:
1.1.1.2 root 1309: return (((int64_t) dead << 32) / sw->ratio) << sw->info.shift;
1.1 root 1310: }
1311:
1.1.1.3 root 1312: static void audio_capture_mix_and_clear (HWVoiceOut *hw, int rpos, int samples)
1313: {
1314: int n;
1315:
1316: if (hw->enabled) {
1317: SWVoiceCap *sc;
1318:
1319: for (sc = hw->cap_head.lh_first; sc; sc = sc->entries.le_next) {
1320: SWVoiceOut *sw = &sc->sw;
1321: int rpos2 = rpos;
1322:
1323: n = samples;
1324: while (n) {
1325: int till_end_of_hw = hw->samples - rpos2;
1326: int to_write = audio_MIN (till_end_of_hw, n);
1327: int bytes = to_write << hw->info.shift;
1328: int written;
1329:
1330: sw->buf = hw->mix_buf + rpos2;
1331: written = audio_pcm_sw_write (sw, NULL, bytes);
1332: if (written - bytes) {
1333: dolog ("Could not mix %d bytes into a capture "
1334: "buffer, mixed %d\n",
1335: bytes, written);
1336: break;
1337: }
1338: n -= to_write;
1339: rpos2 = (rpos2 + to_write) % hw->samples;
1340: }
1341: }
1342: }
1343:
1344: n = audio_MIN (samples, hw->samples - rpos);
1345: mixeng_clear (hw->mix_buf + rpos, n);
1346: mixeng_clear (hw->mix_buf, samples - n);
1347: }
1348:
1.1.1.2 root 1349: static void audio_run_out (AudioState *s)
1.1 root 1350: {
1.1.1.2 root 1351: HWVoiceOut *hw = NULL;
1352: SWVoiceOut *sw;
1.1 root 1353:
1.1.1.7 root 1354: while ((hw = audio_pcm_hw_find_any_enabled_out (hw))) {
1.1.1.2 root 1355: int played;
1.1.1.3 root 1356: int live, free, nb_live, cleanup_required, prev_rpos;
1.1 root 1357:
1.1.1.8 root 1358: live = audio_pcm_hw_get_live_out (hw, &nb_live);
1.1.1.2 root 1359: if (!nb_live) {
1360: live = 0;
1361: }
1.1 root 1362:
1.1.1.2 root 1363: if (audio_bug (AUDIO_FUNC, live < 0 || live > hw->samples)) {
1364: dolog ("live=%d hw->samples=%d\n", live, hw->samples);
1365: continue;
1366: }
1367:
1368: if (hw->pending_disable && !nb_live) {
1.1.1.3 root 1369: SWVoiceCap *sc;
1.1.1.2 root 1370: #ifdef DEBUG_OUT
1371: dolog ("Disabling voice\n");
1372: #endif
1373: hw->enabled = 0;
1374: hw->pending_disable = 0;
1375: hw->pcm_ops->ctl_out (hw, VOICE_DISABLE);
1.1.1.3 root 1376: for (sc = hw->cap_head.lh_first; sc; sc = sc->entries.le_next) {
1377: sc->sw.active = 0;
1378: audio_recalc_and_notify_capture (sc->cap);
1379: }
1.1.1.2 root 1380: continue;
1381: }
1.1 root 1382:
1.1.1.2 root 1383: if (!live) {
1384: for (sw = hw->sw_head.lh_first; sw; sw = sw->entries.le_next) {
1385: if (sw->active) {
1386: free = audio_get_free (sw);
1387: if (free > 0) {
1388: sw->callback.fn (sw->callback.opaque, free);
1389: }
1390: }
1.1 root 1391: }
1.1.1.2 root 1392: continue;
1.1 root 1393: }
1.1.1.2 root 1394:
1.1.1.3 root 1395: prev_rpos = hw->rpos;
1.1.1.8 root 1396: played = hw->pcm_ops->run_out (hw, live);
1.1.1.2 root 1397: if (audio_bug (AUDIO_FUNC, hw->rpos >= hw->samples)) {
1398: dolog ("hw->rpos=%d hw->samples=%d played=%d\n",
1399: hw->rpos, hw->samples, played);
1400: hw->rpos = 0;
1.1 root 1401: }
1402:
1.1.1.2 root 1403: #ifdef DEBUG_OUT
1404: dolog ("played=%d\n", played);
1405: #endif
1.1 root 1406:
1.1.1.2 root 1407: if (played) {
1408: hw->ts_helper += played;
1.1.1.3 root 1409: audio_capture_mix_and_clear (hw, prev_rpos, played);
1.1.1.2 root 1410: }
1.1 root 1411:
1.1.1.2 root 1412: cleanup_required = 0;
1413: for (sw = hw->sw_head.lh_first; sw; sw = sw->entries.le_next) {
1414: if (!sw->active && sw->empty) {
1415: continue;
1416: }
1.1 root 1417:
1.1.1.2 root 1418: if (audio_bug (AUDIO_FUNC, played > sw->total_hw_samples_mixed)) {
1419: dolog ("played=%d sw->total_hw_samples_mixed=%d\n",
1420: played, sw->total_hw_samples_mixed);
1421: played = sw->total_hw_samples_mixed;
1422: }
1.1 root 1423:
1.1.1.2 root 1424: sw->total_hw_samples_mixed -= played;
1.1 root 1425:
1.1.1.2 root 1426: if (!sw->total_hw_samples_mixed) {
1427: sw->empty = 1;
1428: cleanup_required |= !sw->active && !sw->callback.fn;
1429: }
1.1 root 1430:
1.1.1.2 root 1431: if (sw->active) {
1432: free = audio_get_free (sw);
1433: if (free > 0) {
1434: sw->callback.fn (sw->callback.opaque, free);
1435: }
1.1 root 1436: }
1437: }
1438:
1.1.1.2 root 1439: if (cleanup_required) {
1.1.1.3 root 1440: SWVoiceOut *sw1;
1441:
1442: sw = hw->sw_head.lh_first;
1443: while (sw) {
1444: sw1 = sw->entries.le_next;
1.1.1.2 root 1445: if (!sw->active && !sw->callback.fn) {
1446: #ifdef DEBUG_PLIVE
1447: dolog ("Finishing with old voice\n");
1448: #endif
1.1.1.7 root 1449: audio_close_out (sw);
1.1 root 1450: }
1.1.1.3 root 1451: sw = sw1;
1.1 root 1452: }
1453: }
1454: }
1455: }
1456:
1.1.1.2 root 1457: static void audio_run_in (AudioState *s)
1.1 root 1458: {
1.1.1.2 root 1459: HWVoiceIn *hw = NULL;
1.1 root 1460:
1.1.1.7 root 1461: while ((hw = audio_pcm_hw_find_any_enabled_in (hw))) {
1.1.1.2 root 1462: SWVoiceIn *sw;
1463: int captured, min;
1.1 root 1464:
1.1.1.2 root 1465: captured = hw->pcm_ops->run_in (hw);
1.1 root 1466:
1.1.1.2 root 1467: min = audio_pcm_hw_find_min_in (hw);
1468: hw->total_samples_captured += captured - min;
1469: hw->ts_helper += captured;
1.1 root 1470:
1.1.1.2 root 1471: for (sw = hw->sw_head.lh_first; sw; sw = sw->entries.le_next) {
1472: sw->total_hw_samples_acquired -= min;
1.1 root 1473:
1.1.1.2 root 1474: if (sw->active) {
1475: int avail;
1.1 root 1476:
1.1.1.2 root 1477: avail = audio_get_avail (sw);
1478: if (avail > 0) {
1479: sw->callback.fn (sw->callback.opaque, avail);
1480: }
1481: }
1482: }
1483: }
1.1 root 1484: }
1485:
1.1.1.3 root 1486: static void audio_run_capture (AudioState *s)
1487: {
1488: CaptureVoiceOut *cap;
1489:
1490: for (cap = s->cap_head.lh_first; cap; cap = cap->entries.le_next) {
1491: int live, rpos, captured;
1492: HWVoiceOut *hw = &cap->hw;
1493: SWVoiceOut *sw;
1494:
1.1.1.8 root 1495: captured = live = audio_pcm_hw_get_live_out (hw, NULL);
1.1.1.3 root 1496: rpos = hw->rpos;
1497: while (live) {
1498: int left = hw->samples - rpos;
1499: int to_capture = audio_MIN (live, left);
1.1.1.6 root 1500: struct st_sample *src;
1.1.1.3 root 1501: struct capture_callback *cb;
1502:
1503: src = hw->mix_buf + rpos;
1504: hw->clip (cap->buf, src, to_capture);
1505: mixeng_clear (src, to_capture);
1506:
1507: for (cb = cap->cb_head.lh_first; cb; cb = cb->entries.le_next) {
1508: cb->ops.capture (cb->opaque, cap->buf,
1509: to_capture << hw->info.shift);
1510: }
1511: rpos = (rpos + to_capture) % hw->samples;
1512: live -= to_capture;
1513: }
1514: hw->rpos = rpos;
1515:
1516: for (sw = hw->sw_head.lh_first; sw; sw = sw->entries.le_next) {
1517: if (!sw->active && sw->empty) {
1518: continue;
1519: }
1520:
1521: if (audio_bug (AUDIO_FUNC, captured > sw->total_hw_samples_mixed)) {
1522: dolog ("captured=%d sw->total_hw_samples_mixed=%d\n",
1523: captured, sw->total_hw_samples_mixed);
1524: captured = sw->total_hw_samples_mixed;
1525: }
1526:
1527: sw->total_hw_samples_mixed -= captured;
1528: sw->empty = sw->total_hw_samples_mixed == 0;
1529: }
1530: }
1531: }
1532:
1.1.1.8 root 1533: void audio_run (const char *msg)
1.1 root 1534: {
1.1.1.8 root 1535: AudioState *s = &glob_audio_state;
1.1.1.2 root 1536:
1537: audio_run_out (s);
1538: audio_run_in (s);
1.1.1.3 root 1539: audio_run_capture (s);
1.1.1.8 root 1540: #ifdef DEBUG_POLL
1541: {
1542: static double prevtime;
1543: double currtime;
1544: struct timeval tv;
1.1.1.2 root 1545:
1.1.1.8 root 1546: if (gettimeofday (&tv, NULL)) {
1547: perror ("audio_run: gettimeofday");
1548: return;
1549: }
1550:
1551: currtime = tv.tv_sec + tv.tv_usec * 1e-6;
1552: dolog ("Elapsed since last %s: %f\n", msg, currtime - prevtime);
1553: prevtime = currtime;
1554: }
1555: #endif
1.1 root 1556: }
1557:
1.1.1.2 root 1558: static struct audio_option audio_options[] = {
1559: /* DAC */
1.1.1.8 root 1560: {
1561: .name = "DAC_FIXED_SETTINGS",
1562: .tag = AUD_OPT_BOOL,
1563: .valp = &conf.fixed_out.enabled,
1564: .descr = "Use fixed settings for host DAC"
1565: },
1566: {
1567: .name = "DAC_FIXED_FREQ",
1568: .tag = AUD_OPT_INT,
1569: .valp = &conf.fixed_out.settings.freq,
1570: .descr = "Frequency for fixed host DAC"
1571: },
1572: {
1573: .name = "DAC_FIXED_FMT",
1574: .tag = AUD_OPT_FMT,
1575: .valp = &conf.fixed_out.settings.fmt,
1576: .descr = "Format for fixed host DAC"
1577: },
1578: {
1579: .name = "DAC_FIXED_CHANNELS",
1580: .tag = AUD_OPT_INT,
1581: .valp = &conf.fixed_out.settings.nchannels,
1582: .descr = "Number of channels for fixed DAC (1 - mono, 2 - stereo)"
1583: },
1584: {
1585: .name = "DAC_VOICES",
1586: .tag = AUD_OPT_INT,
1587: .valp = &conf.fixed_out.nb_voices,
1588: .descr = "Number of voices for DAC"
1589: },
1590: {
1591: .name = "DAC_TRY_POLL",
1592: .tag = AUD_OPT_BOOL,
1593: .valp = &conf.try_poll_out,
1594: .descr = "Attempt using poll mode for DAC"
1595: },
1.1.1.2 root 1596: /* ADC */
1.1.1.8 root 1597: {
1598: .name = "ADC_FIXED_SETTINGS",
1599: .tag = AUD_OPT_BOOL,
1600: .valp = &conf.fixed_in.enabled,
1601: .descr = "Use fixed settings for host ADC"
1602: },
1603: {
1604: .name = "ADC_FIXED_FREQ",
1605: .tag = AUD_OPT_INT,
1606: .valp = &conf.fixed_in.settings.freq,
1607: .descr = "Frequency for fixed host ADC"
1608: },
1609: {
1610: .name = "ADC_FIXED_FMT",
1611: .tag = AUD_OPT_FMT,
1612: .valp = &conf.fixed_in.settings.fmt,
1613: .descr = "Format for fixed host ADC"
1614: },
1615: {
1616: .name = "ADC_FIXED_CHANNELS",
1617: .tag = AUD_OPT_INT,
1618: .valp = &conf.fixed_in.settings.nchannels,
1619: .descr = "Number of channels for fixed ADC (1 - mono, 2 - stereo)"
1620: },
1621: {
1622: .name = "ADC_VOICES",
1623: .tag = AUD_OPT_INT,
1624: .valp = &conf.fixed_in.nb_voices,
1625: .descr = "Number of voices for ADC"
1626: },
1627: {
1628: .name = "ADC_TRY_POLL",
1629: .tag = AUD_OPT_BOOL,
1630: .valp = &conf.try_poll_in,
1631: .descr = "Attempt using poll mode for ADC"
1632: },
1.1.1.2 root 1633: /* Misc */
1.1.1.8 root 1634: {
1635: .name = "TIMER_PERIOD",
1636: .tag = AUD_OPT_INT,
1637: .valp = &conf.period.hertz,
1638: .descr = "Timer period in HZ (0 - use lowest possible)"
1639: },
1640: {
1641: .name = "PLIVE",
1642: .tag = AUD_OPT_BOOL,
1643: .valp = &conf.plive,
1644: .descr = "(undocumented)"
1645: },
1646: {
1647: .name = "LOG_TO_MONITOR",
1648: .tag = AUD_OPT_BOOL,
1649: .valp = &conf.log_to_monitor,
1650: .descr = "Print logging messages to monitor instead of stderr"
1651: },
1652: { /* End of list */ }
1.1.1.2 root 1653: };
1654:
1655: static void audio_pp_nb_voices (const char *typ, int nb)
1656: {
1657: switch (nb) {
1658: case 0:
1659: printf ("Does not support %s\n", typ);
1660: break;
1661: case 1:
1662: printf ("One %s voice\n", typ);
1663: break;
1664: case INT_MAX:
1665: printf ("Theoretically supports many %s voices\n", typ);
1666: break;
1667: default:
1668: printf ("Theoretically supports upto %d %s voices\n", nb, typ);
1669: break;
1.1 root 1670: }
1.1.1.2 root 1671:
1.1 root 1672: }
1673:
1.1.1.2 root 1674: void AUD_help (void)
1.1 root 1675: {
1.1.1.2 root 1676: size_t i;
1.1 root 1677:
1.1.1.2 root 1678: audio_process_options ("AUDIO", audio_options);
1.1.1.6 root 1679: for (i = 0; i < ARRAY_SIZE (drvtab); i++) {
1.1.1.2 root 1680: struct audio_driver *d = drvtab[i];
1681: if (d->options) {
1682: audio_process_options (d->name, d->options);
1.1 root 1683: }
1684: }
1685:
1.1.1.2 root 1686: printf ("Audio options:\n");
1687: audio_print_options ("AUDIO", audio_options);
1688: printf ("\n");
1689:
1690: printf ("Available drivers:\n");
1691:
1.1.1.6 root 1692: for (i = 0; i < ARRAY_SIZE (drvtab); i++) {
1.1.1.2 root 1693: struct audio_driver *d = drvtab[i];
1694:
1695: printf ("Name: %s\n", d->name);
1696: printf ("Description: %s\n", d->descr);
1697:
1698: audio_pp_nb_voices ("playback", d->max_voices_out);
1699: audio_pp_nb_voices ("capture", d->max_voices_in);
1700:
1701: if (d->options) {
1702: printf ("Options:\n");
1703: audio_print_options (d->name, d->options);
1.1 root 1704: }
1705: else {
1.1.1.2 root 1706: printf ("No options\n");
1.1 root 1707: }
1.1.1.2 root 1708: printf ("\n");
1.1 root 1709: }
1710:
1.1.1.2 root 1711: printf (
1712: "Options are settable through environment variables.\n"
1713: "Example:\n"
1714: #ifdef _WIN32
1715: " set QEMU_AUDIO_DRV=wav\n"
1716: " set QEMU_WAV_PATH=c:\\tune.wav\n"
1717: #else
1718: " export QEMU_AUDIO_DRV=wav\n"
1719: " export QEMU_WAV_PATH=$HOME/tune.wav\n"
1720: "(for csh replace export with setenv in the above)\n"
1.1 root 1721: #endif
1.1.1.2 root 1722: " qemu ...\n\n"
1723: );
1724: }
1.1 root 1725:
1.1.1.2 root 1726: static int audio_driver_init (AudioState *s, struct audio_driver *drv)
1.1 root 1727: {
1.1.1.2 root 1728: if (drv->options) {
1729: audio_process_options (drv->name, drv->options);
1.1 root 1730: }
1.1.1.2 root 1731: s->drv_opaque = drv->init ();
1732:
1733: if (s->drv_opaque) {
1.1.1.7 root 1734: audio_init_nb_voices_out (drv);
1735: audio_init_nb_voices_in (drv);
1.1.1.2 root 1736: s->drv = drv;
1.1 root 1737: return 0;
1738: }
1.1.1.2 root 1739: else {
1740: dolog ("Could not init `%s' audio driver\n", drv->name);
1741: return -1;
1742: }
1.1 root 1743: }
1744:
1.1.1.6 root 1745: static void audio_vm_change_state_handler (void *opaque, int running,
1746: int reason)
1.1 root 1747: {
1.1.1.2 root 1748: AudioState *s = opaque;
1749: HWVoiceOut *hwo = NULL;
1750: HWVoiceIn *hwi = NULL;
1751: int op = running ? VOICE_ENABLE : VOICE_DISABLE;
1.1 root 1752:
1.1.1.6 root 1753: s->vm_running = running;
1.1.1.7 root 1754: while ((hwo = audio_pcm_hw_find_any_enabled_out (hwo))) {
1.1.1.8 root 1755: hwo->pcm_ops->ctl_out (hwo, op, conf.try_poll_out);
1.1.1.2 root 1756: }
1.1 root 1757:
1.1.1.7 root 1758: while ((hwi = audio_pcm_hw_find_any_enabled_in (hwi))) {
1.1.1.8 root 1759: hwi->pcm_ops->ctl_in (hwi, op, conf.try_poll_in);
1.1 root 1760: }
1.1.1.8 root 1761: audio_reset_timer ();
1.1 root 1762: }
1763:
1764: static void audio_atexit (void)
1765: {
1.1.1.2 root 1766: AudioState *s = &glob_audio_state;
1767: HWVoiceOut *hwo = NULL;
1768: HWVoiceIn *hwi = NULL;
1.1 root 1769:
1.1.1.7 root 1770: while ((hwo = audio_pcm_hw_find_any_enabled_out (hwo))) {
1.1.1.3 root 1771: SWVoiceCap *sc;
1772:
1.1.1.2 root 1773: hwo->pcm_ops->ctl_out (hwo, VOICE_DISABLE);
1774: hwo->pcm_ops->fini_out (hwo);
1.1.1.3 root 1775:
1776: for (sc = hwo->cap_head.lh_first; sc; sc = sc->entries.le_next) {
1777: CaptureVoiceOut *cap = sc->cap;
1778: struct capture_callback *cb;
1779:
1780: for (cb = cap->cb_head.lh_first; cb; cb = cb->entries.le_next) {
1781: cb->ops.destroy (cb->opaque);
1782: }
1783: }
1.1.1.2 root 1784: }
1785:
1.1.1.7 root 1786: while ((hwi = audio_pcm_hw_find_any_enabled_in (hwi))) {
1.1.1.2 root 1787: hwi->pcm_ops->ctl_in (hwi, VOICE_DISABLE);
1788: hwi->pcm_ops->fini_in (hwi);
1789: }
1.1 root 1790:
1.1.1.2 root 1791: if (s->drv) {
1792: s->drv->fini (s->drv_opaque);
1.1 root 1793: }
1794: }
1795:
1.1.1.8 root 1796: static const VMStateDescription vmstate_audio = {
1797: .name = "audio",
1798: .version_id = 1,
1799: .minimum_version_id = 1,
1800: .minimum_version_id_old = 1,
1801: .fields = (VMStateField []) {
1802: VMSTATE_END_OF_LIST()
1.1.1.2 root 1803: }
1.1.1.8 root 1804: };
1.1 root 1805:
1.1.1.7 root 1806: static void audio_init (void)
1.1.1.2 root 1807: {
1808: size_t i;
1.1 root 1809: int done = 0;
1810: const char *drvname;
1.1.1.8 root 1811: VMChangeStateEntry *e;
1.1.1.2 root 1812: AudioState *s = &glob_audio_state;
1813:
1.1.1.7 root 1814: if (s->drv) {
1815: return;
1816: }
1817:
1.1.1.8 root 1818: QLIST_INIT (&s->hw_head_out);
1819: QLIST_INIT (&s->hw_head_in);
1820: QLIST_INIT (&s->cap_head);
1.1.1.2 root 1821: atexit (audio_atexit);
1822:
1823: s->ts = qemu_new_timer (vm_clock, audio_timer, s);
1824: if (!s->ts) {
1.1.1.7 root 1825: hw_error("Could not create audio timer\n");
1.1.1.2 root 1826: }
1827:
1828: audio_process_options ("AUDIO", audio_options);
1829:
1830: s->nb_hw_voices_out = conf.fixed_out.nb_voices;
1831: s->nb_hw_voices_in = conf.fixed_in.nb_voices;
1832:
1833: if (s->nb_hw_voices_out <= 0) {
1834: dolog ("Bogus number of playback voices %d, setting to 1\n",
1835: s->nb_hw_voices_out);
1836: s->nb_hw_voices_out = 1;
1837: }
1.1 root 1838:
1.1.1.2 root 1839: if (s->nb_hw_voices_in <= 0) {
1840: dolog ("Bogus number of capture voices %d, setting to 0\n",
1841: s->nb_hw_voices_in);
1842: s->nb_hw_voices_in = 0;
1843: }
1844:
1845: {
1846: int def;
1847: drvname = audio_get_conf_str ("QEMU_AUDIO_DRV", NULL, &def);
1.1 root 1848: }
1849:
1850: if (drvname) {
1851: int found = 0;
1.1.1.2 root 1852:
1.1.1.6 root 1853: for (i = 0; i < ARRAY_SIZE (drvtab); i++) {
1.1 root 1854: if (!strcmp (drvname, drvtab[i]->name)) {
1.1.1.2 root 1855: done = !audio_driver_init (s, drvtab[i]);
1.1 root 1856: found = 1;
1857: break;
1858: }
1859: }
1.1.1.2 root 1860:
1.1 root 1861: if (!found) {
1862: dolog ("Unknown audio driver `%s'\n", drvname);
1.1.1.2 root 1863: dolog ("Run with -audio-help to list available drivers\n");
1.1 root 1864: }
1865: }
1866:
1867: if (!done) {
1.1.1.6 root 1868: for (i = 0; !done && i < ARRAY_SIZE (drvtab); i++) {
1.1.1.2 root 1869: if (drvtab[i]->can_be_default) {
1870: done = !audio_driver_init (s, drvtab[i]);
1871: }
1.1 root 1872: }
1873: }
1874:
1875: if (!done) {
1.1.1.2 root 1876: done = !audio_driver_init (s, &no_audio_driver);
1877: if (!done) {
1.1.1.7 root 1878: hw_error("Could not initialize audio subsystem\n");
1.1.1.2 root 1879: }
1880: else {
1881: dolog ("warning: Using timer based audio emulation\n");
1882: }
1883: }
1884:
1.1.1.7 root 1885: if (conf.period.hertz <= 0) {
1886: if (conf.period.hertz < 0) {
1887: dolog ("warning: Timer period is negative - %d "
1888: "treating as zero\n",
1889: conf.period.hertz);
1890: }
1891: conf.period.ticks = 1;
1892: } else {
1.1.1.8 root 1893: conf.period.ticks =
1894: muldiv64 (1, get_ticks_per_sec (), conf.period.hertz);
1.1.1.7 root 1895: }
1896:
1897: e = qemu_add_vm_change_state_handler (audio_vm_change_state_handler, s);
1898: if (!e) {
1899: dolog ("warning: Could not register change state handler\n"
1900: "(Audio can continue looping even after stopping the VM)\n");
1.1.1.2 root 1901: }
1902:
1.1.1.8 root 1903: QLIST_INIT (&s->card_head);
1.1.1.9 ! root 1904: vmstate_register (NULL, 0, &vmstate_audio, s);
1.1 root 1905: }
1.1.1.3 root 1906:
1.1.1.7 root 1907: void AUD_register_card (const char *name, QEMUSoundCard *card)
1908: {
1909: audio_init ();
1910: card->name = qemu_strdup (name);
1911: memset (&card->entries, 0, sizeof (card->entries));
1.1.1.8 root 1912: QLIST_INSERT_HEAD (&glob_audio_state.card_head, card, entries);
1.1.1.7 root 1913: }
1914:
1915: void AUD_remove_card (QEMUSoundCard *card)
1916: {
1.1.1.8 root 1917: QLIST_REMOVE (card, entries);
1.1.1.7 root 1918: qemu_free (card->name);
1919: }
1920:
1921:
1.1.1.3 root 1922: CaptureVoiceOut *AUD_add_capture (
1.1.1.6 root 1923: struct audsettings *as,
1.1.1.3 root 1924: struct audio_capture_ops *ops,
1925: void *cb_opaque
1926: )
1927: {
1.1.1.7 root 1928: AudioState *s = &glob_audio_state;
1.1.1.3 root 1929: CaptureVoiceOut *cap;
1930: struct capture_callback *cb;
1931:
1932: if (audio_validate_settings (as)) {
1933: dolog ("Invalid settings were passed when trying to add capture\n");
1934: audio_print_settings (as);
1935: goto err0;
1936: }
1937:
1938: cb = audio_calloc (AUDIO_FUNC, 1, sizeof (*cb));
1939: if (!cb) {
1940: dolog ("Could not allocate capture callback information, size %zu\n",
1941: sizeof (*cb));
1942: goto err0;
1943: }
1944: cb->ops = *ops;
1945: cb->opaque = cb_opaque;
1946:
1.1.1.7 root 1947: cap = audio_pcm_capture_find_specific (as);
1.1.1.3 root 1948: if (cap) {
1.1.1.8 root 1949: QLIST_INSERT_HEAD (&cap->cb_head, cb, entries);
1.1.1.3 root 1950: return cap;
1951: }
1952: else {
1953: HWVoiceOut *hw;
1954: CaptureVoiceOut *cap;
1955:
1956: cap = audio_calloc (AUDIO_FUNC, 1, sizeof (*cap));
1957: if (!cap) {
1958: dolog ("Could not allocate capture voice, size %zu\n",
1959: sizeof (*cap));
1960: goto err1;
1961: }
1962:
1963: hw = &cap->hw;
1.1.1.8 root 1964: QLIST_INIT (&hw->sw_head);
1965: QLIST_INIT (&cap->cb_head);
1.1.1.3 root 1966:
1967: /* XXX find a more elegant way */
1968: hw->samples = 4096 * 4;
1969: hw->mix_buf = audio_calloc (AUDIO_FUNC, hw->samples,
1.1.1.6 root 1970: sizeof (struct st_sample));
1.1.1.3 root 1971: if (!hw->mix_buf) {
1972: dolog ("Could not allocate capture mix buffer (%d samples)\n",
1973: hw->samples);
1974: goto err2;
1975: }
1976:
1977: audio_pcm_init_info (&hw->info, as);
1978:
1979: cap->buf = audio_calloc (AUDIO_FUNC, hw->samples, 1 << hw->info.shift);
1980: if (!cap->buf) {
1981: dolog ("Could not allocate capture buffer "
1982: "(%d samples, each %d bytes)\n",
1983: hw->samples, 1 << hw->info.shift);
1984: goto err3;
1985: }
1986:
1987: hw->clip = mixeng_clip
1988: [hw->info.nchannels == 2]
1989: [hw->info.sign]
1990: [hw->info.swap_endianness]
1.1.1.5 root 1991: [audio_bits_to_index (hw->info.bits)];
1.1.1.3 root 1992:
1.1.1.8 root 1993: QLIST_INSERT_HEAD (&s->cap_head, cap, entries);
1994: QLIST_INSERT_HEAD (&cap->cb_head, cb, entries);
1.1.1.3 root 1995:
1996: hw = NULL;
1.1.1.7 root 1997: while ((hw = audio_pcm_hw_find_any_out (hw))) {
1998: audio_attach_capture (hw);
1.1.1.3 root 1999: }
2000: return cap;
2001:
2002: err3:
2003: qemu_free (cap->hw.mix_buf);
2004: err2:
2005: qemu_free (cap);
2006: err1:
2007: qemu_free (cb);
2008: err0:
2009: return NULL;
2010: }
2011: }
2012:
2013: void AUD_del_capture (CaptureVoiceOut *cap, void *cb_opaque)
2014: {
2015: struct capture_callback *cb;
2016:
2017: for (cb = cap->cb_head.lh_first; cb; cb = cb->entries.le_next) {
2018: if (cb->opaque == cb_opaque) {
2019: cb->ops.destroy (cb_opaque);
1.1.1.8 root 2020: QLIST_REMOVE (cb, entries);
1.1.1.3 root 2021: qemu_free (cb);
2022:
2023: if (!cap->cb_head.lh_first) {
2024: SWVoiceOut *sw = cap->hw.sw_head.lh_first, *sw1;
2025:
2026: while (sw) {
2027: SWVoiceCap *sc = (SWVoiceCap *) sw;
2028: #ifdef DEBUG_CAPTURE
2029: dolog ("freeing %s\n", sw->name);
2030: #endif
2031:
2032: sw1 = sw->entries.le_next;
2033: if (sw->rate) {
2034: st_rate_stop (sw->rate);
2035: sw->rate = NULL;
2036: }
1.1.1.8 root 2037: QLIST_REMOVE (sw, entries);
2038: QLIST_REMOVE (sc, entries);
1.1.1.3 root 2039: qemu_free (sc);
2040: sw = sw1;
2041: }
1.1.1.8 root 2042: QLIST_REMOVE (cap, entries);
1.1.1.3 root 2043: qemu_free (cap);
2044: }
2045: return;
2046: }
2047: }
2048: }
1.1.1.6 root 2049:
2050: void AUD_set_volume_out (SWVoiceOut *sw, int mute, uint8_t lvol, uint8_t rvol)
2051: {
2052: if (sw) {
2053: sw->vol.mute = mute;
2054: sw->vol.l = nominal_volume.l * lvol / 255;
2055: sw->vol.r = nominal_volume.r * rvol / 255;
2056: }
2057: }
2058:
2059: void AUD_set_volume_in (SWVoiceIn *sw, int mute, uint8_t lvol, uint8_t rvol)
2060: {
2061: if (sw) {
2062: sw->vol.mute = mute;
2063: sw->vol.l = nominal_volume.l * lvol / 255;
2064: sw->vol.r = nominal_volume.r * rvol / 255;
2065: }
2066: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.