VirtualBox

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

最後變更 在這個檔案從7272是 6598,由 vboxsync 提交於 17 年 前

fixed Windows build

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

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