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