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