VirtualBox

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

Last change on this file since 6117 was 6117, checked in by vboxsync, 17 years ago

audio: forgot this

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