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