VirtualBox

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

Last change on this file since 34906 was 34906, checked in by vboxsync, 14 years ago

Initial audio filter implementation, which is used for audio input via remote desktop server.

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