VirtualBox

source: vbox/trunk/src/VBox/Devices/Audio/audio.c@ 1248

Last change on this file since 1248 was 1071, checked in by vboxsync, 18 years ago

fix Vista crash if sound is enabled; made audio LogRel consistent; winmm was never used, show dsound instead

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

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette