VirtualBox

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

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

pdmifs.h: the penultimate batch of refactored interface ID code.

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