VirtualBox

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

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

audio: on exit, shut down _every_ stream, not only the enabled onces

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

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