VirtualBox

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

Last change on this file since 25893 was 25893, checked in by vboxsync, 15 years ago

PDMDrv,*: multi context drivers, part 2.

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