VirtualBox

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

Last change on this file since 19002 was 19002, checked in by vboxsync, 16 years ago

Audio: Add support for FreeBSD

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