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