VirtualBox

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

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

audio: call driver's fini function before forcing the NULL audio driver

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 49.1 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 while ((hwo = audio_pcm_hw_find_any_enabled_out (s, hwo))) {
1495 SWVoiceCap *sc;
1496
1497 hwo->pcm_ops->ctl_out (hwo, VOICE_DISABLE);
1498 hwo->pcm_ops->fini_out (hwo);
1499
1500 for (sc = hwo->cap_head.lh_first; sc; sc = sc->entries.le_next) {
1501 CaptureVoiceOut *cap = sc->cap;
1502 struct capture_callback *cb;
1503
1504 for (cb = cap->cb_head.lh_first; cb; cb = cb->entries.le_next) {
1505 cb->ops.destroy (cb->opaque);
1506 }
1507 }
1508 }
1509
1510 while ((hwi = audio_pcm_hw_find_any_enabled_in (s, hwi))) {
1511 hwi->pcm_ops->ctl_in (hwi, VOICE_DISABLE);
1512 hwi->pcm_ops->fini_in (hwi);
1513 }
1514
1515 if (s->drv) {
1516 s->drv->fini (s->drv_opaque);
1517 }
1518}
1519
1520void AUD_register_card (const char *name, QEMUSoundCard *card)
1521{
1522 AudioState *s = &glob_audio_state;
1523 card->audio = s;
1524 card->name = qemu_strdup (name);
1525 memset (&card->entries, 0, sizeof (card->entries));
1526 LIST_INSERT_HEAD (&s->card_head, card, entries);
1527}
1528
1529void AUD_remove_card (QEMUSoundCard *card)
1530{
1531 LIST_REMOVE (card, entries);
1532 card->audio = NULL;
1533 qemu_free (card->name);
1534}
1535
1536static void audio_timer_helper (PPDMDRVINS pDrvIns, PTMTIMER pTimer)
1537{
1538 AudioState *s = &glob_audio_state;
1539 audio_timer (s);
1540}
1541
1542static int AUD_init (PPDMDRVINS pDrvIns, const char *drvname)
1543{
1544 size_t i;
1545 int done = 0;
1546 AudioState *s = &glob_audio_state;
1547 int rc;
1548
1549 LIST_INIT (&s->hw_head_out);
1550 LIST_INIT (&s->hw_head_in);
1551 LIST_INIT (&s->cap_head);
1552
1553 rc = pDrvIns->pDrvHlp->pfnTMTimerCreate (pDrvIns, TMCLOCK_VIRTUAL,
1554 audio_timer_helper, "Audio timer", &s->ts);
1555 if (VBOX_FAILURE (rc))
1556 return rc;
1557
1558 audio_process_options ("AUDIO", audio_options);
1559
1560 s->nb_hw_voices_out = conf.fixed_out.nb_voices;
1561 s->nb_hw_voices_in = conf.fixed_in.nb_voices;
1562
1563 if (s->nb_hw_voices_out <= 0) {
1564 dolog ("Bogus number of playback voices %d, setting to 1\n",
1565 s->nb_hw_voices_out);
1566 s->nb_hw_voices_out = 1;
1567 }
1568
1569 if (s->nb_hw_voices_in <= 0) {
1570 dolog ("Bogus number of capture voices %d, setting to 0\n",
1571 s->nb_hw_voices_in);
1572 s->nb_hw_voices_in = 0;
1573 }
1574
1575 LogRel(("Audio: Trying driver '%s'.\n", drvname));
1576
1577 if (drvname) {
1578 int found = 0;
1579
1580 for (i = 0; i < sizeof (drvtab) / sizeof (drvtab[0]); i++) {
1581 if (!strcmp (drvname, drvtab[i]->name)) {
1582 done = !audio_driver_init (s, drvtab[i]);
1583 found = 1;
1584 break;
1585 }
1586 }
1587
1588 if (!found) {
1589 dolog ("Unknown audio driver `%s'\n", drvname);
1590 }
1591 }
1592
1593 if (!done) {
1594 for (i = 0; !done && i < sizeof (drvtab) / sizeof (drvtab[0]); i++) {
1595 if (drvtab[i]->can_be_default) {
1596 LogRel(("Audio: Initialization of driver '%s' failed, trying '%s'.\n",
1597 drvname, drvtab[i]->name));
1598 drvname = drvtab[i]->name;
1599 done = !audio_driver_init (s, drvtab[i]);
1600 }
1601 }
1602 }
1603
1604 if (!done) {
1605 done = !audio_driver_init (s, &no_audio_driver);
1606 if (!done) {
1607 dolog ("Could not initialize audio subsystem\n");
1608 }
1609 else {
1610 LogRel(("Audio: Initialization of driver '%s' failed, using NULL driver.\n", drvname));
1611 dolog ("warning: Using timer based audio emulation\n");
1612 }
1613 }
1614
1615 if (done) {
1616 if (conf.period.hz <= 0) {
1617 if (conf.period.hz < 0) {
1618 dolog ("warning: Timer period is negative - %d "
1619 "treating as zero\n",
1620 conf.period.hz);
1621 }
1622 conf.period.ticks = 1;
1623 }
1624 else {
1625 conf.period.ticks = pDrvIns->pDrvHlp->pfnTMGetVirtualFreq (pDrvIns)
1626 / conf.period.hz;
1627 }
1628 }
1629 else {
1630 /* XXX */
1631 rc = TMTimerDestroy (s->ts);
1632 return rc;
1633 }
1634
1635 LIST_INIT (&s->card_head);
1636 TMTimerSet (s->ts, TMTimerGet (s->ts) + conf.period.ticks);
1637 return VINF_SUCCESS;
1638}
1639
1640int AUD_init_null(void)
1641{
1642 AudioState *s = &glob_audio_state;
1643
1644#ifdef VBOX
1645 if (s->drv)
1646 s->drv->fini (s->drv_opaque);
1647#endif
1648
1649 LogRel(("Audio: Using NULL audio driver\n"));
1650 return audio_driver_init (s, &no_audio_driver);
1651}
1652
1653CaptureVoiceOut *AUD_add_capture (
1654 AudioState *s,
1655 audsettings_t *as,
1656 struct audio_capture_ops *ops,
1657 void *cb_opaque
1658 )
1659{
1660 CaptureVoiceOut *cap;
1661 struct capture_callback *cb;
1662
1663 if (!s) {
1664 /* XXX suppress */
1665 s = &glob_audio_state;
1666 }
1667
1668 if (audio_validate_settings (as)) {
1669 dolog ("Invalid settings were passed when trying to add capture\n");
1670 audio_print_settings (as);
1671 goto err0;
1672 }
1673
1674 cb = audio_calloc (AUDIO_FUNC, 1, sizeof (*cb));
1675 if (!cb) {
1676 dolog ("Could not allocate capture callback information, size %u\n",
1677 sizeof (*cb));
1678 goto err0;
1679 }
1680 cb->ops = *ops;
1681 cb->opaque = cb_opaque;
1682
1683 cap = audio_pcm_capture_find_specific (s, as);
1684 if (cap) {
1685 LIST_INSERT_HEAD (&cap->cb_head, cb, entries);
1686 return cap;
1687 }
1688 else {
1689 HWVoiceOut *hw;
1690 CaptureVoiceOut *cap;
1691
1692 cap = audio_calloc (AUDIO_FUNC, 1, sizeof (*cap));
1693 if (!cap) {
1694 dolog ("Could not allocate capture voice, size %u\n",
1695 sizeof (*cap));
1696 goto err1;
1697 }
1698
1699 hw = &cap->hw;
1700 LIST_INIT (&hw->sw_head);
1701 LIST_INIT (&cap->cb_head);
1702
1703 /* XXX find a more elegant way */
1704 hw->samples = 4096 * 4;
1705 hw->mix_buf = audio_calloc (AUDIO_FUNC, hw->samples,
1706 sizeof (st_sample_t));
1707 if (!hw->mix_buf) {
1708 dolog ("Could not allocate capture mix buffer (%d samples)\n",
1709 hw->samples);
1710 goto err2;
1711 }
1712
1713 audio_pcm_init_info (&hw->info, as);
1714
1715 cap->buf = audio_calloc (AUDIO_FUNC, hw->samples, 1 << hw->info.shift);
1716 if (!cap->buf) {
1717 dolog ("Could not allocate capture buffer "
1718 "(%d samples, each %d bytes)\n",
1719 hw->samples, 1 << hw->info.shift);
1720 goto err3;
1721 }
1722
1723 hw->clip = mixeng_clip
1724 [hw->info.nchannels == 2]
1725 [hw->info.sign]
1726 [hw->info.swap_endianness]
1727 [hw->info.bits == 16];
1728
1729 LIST_INSERT_HEAD (&s->cap_head, cap, entries);
1730 LIST_INSERT_HEAD (&cap->cb_head, cb, entries);
1731
1732 hw = NULL;
1733 while ((hw = audio_pcm_hw_find_any_out (s, hw))) {
1734 audio_attach_capture (s, hw);
1735 }
1736 return cap;
1737
1738 err3:
1739 qemu_free (cap->hw.mix_buf);
1740 err2:
1741 qemu_free (cap);
1742 err1:
1743 qemu_free (cb);
1744 err0:
1745 return NULL;
1746 }
1747}
1748
1749void AUD_del_capture (CaptureVoiceOut *cap, void *cb_opaque)
1750{
1751 struct capture_callback *cb;
1752
1753 for (cb = cap->cb_head.lh_first; cb; cb = cb->entries.le_next) {
1754 if (cb->opaque == cb_opaque) {
1755 cb->ops.destroy (cb_opaque);
1756 LIST_REMOVE (cb, entries);
1757 qemu_free (cb);
1758
1759 if (!cap->cb_head.lh_first) {
1760 SWVoiceOut *sw = cap->hw.sw_head.lh_first, *sw1;
1761
1762 while (sw) {
1763 SWVoiceCap *sc = (SWVoiceCap *) sw;
1764#ifdef DEBUG_CAPTURE
1765 dolog ("freeing %s\n", sw->name);
1766#endif
1767
1768 sw1 = sw->entries.le_next;
1769 if (sw->rate) {
1770 st_rate_stop (sw->rate);
1771 sw->rate = NULL;
1772 }
1773 LIST_REMOVE (sw, entries);
1774 LIST_REMOVE (sc, entries);
1775 qemu_free (sc);
1776 sw = sw1;
1777 }
1778 LIST_REMOVE (cap, entries);
1779 qemu_free (cap);
1780 }
1781 return;
1782 }
1783 }
1784}
1785
1786void AUD_set_volume_out (SWVoiceOut *sw, int mute, uint8_t lvol, uint8_t rvol)
1787{
1788 if (sw)
1789 {
1790 sw->vol.mute = mute;
1791 sw->vol.l = (uint32_t)lvol * 0x808080; /* maximum is INT_MAX = 0x7fffffff */
1792 sw->vol.r = (uint32_t)rvol * 0x808080; /* maximum is INT_MAX = 0x7fffffff */
1793 }
1794}
1795
1796void AUD_set_volume (audmixerctl_t mt, int *mute, uint8_t *lvol, uint8_t *rvol)
1797{
1798 volume_t *vol = NULL;
1799 const char *name;
1800
1801 switch (mt)
1802 {
1803 case AUD_MIXER_VOLUME:
1804 name = "MASTER";
1805 vol = &pcm_out_volume;
1806 break;
1807 case AUD_MIXER_PCM:
1808 name = "PCM_OUT";
1809 break;
1810 case AUD_MIXER_LINE_IN:
1811 name = "LINE_IN";
1812 vol = &pcm_in_volume;
1813 break;
1814 default:
1815 return;
1816
1817 }
1818
1819 if (vol)
1820 {
1821 vol->mute = *mute;
1822 vol->l = ((uint32_t)*lvol) * 0x808080; /* maximum is INT_MAX = 0x7fffffff */
1823 vol->r = ((uint32_t)*rvol) * 0x808080; /* maximum is INT_MAX = 0x7fffffff */
1824 }
1825#if 0
1826 LogRel(("AUDIO: Set '%s' volume to %d%%/%d%%\n", name, (*lvol*100)/255, (*rvol*100)/255l));
1827#endif
1828}
1829
1830void AUD_set_record_source (audrecsource_t *ars, audrecsource_t *als)
1831{
1832 LogRel(("Audio: set_record_source ars=%d als=%d (not implemented)\n", *ars, *als));
1833}
1834
1835/**
1836 * Queries an interface to the driver.
1837 *
1838 * @returns Pointer to interface.
1839 * @returns NULL if the interface was not supported by the driver.
1840 * @param pInterface Pointer to this interface structure.
1841 * @param enmInterface The requested interface identification.
1842 * @thread Any thread.
1843 */
1844static DECLCALLBACK(void *) drvAudioQueryInterface(PPDMIBASE pInterface,
1845 PDMINTERFACE enmInterface)
1846{
1847 PPDMDRVINS pDrvIns = PDMIBASE_2_PDMDRV(pInterface);
1848 PDRVAUDIO pData = PDMINS2DATA(pDrvIns, PDRVAUDIO);
1849 switch (enmInterface)
1850 {
1851 case PDMINTERFACE_BASE:
1852 return &pDrvIns->IBase;
1853 case PDMINTERFACE_AUDIO_CONNECTOR:
1854 return &pData->IAudioConnector;
1855 default:
1856 return NULL;
1857 }
1858}
1859
1860/**
1861 * Power Off notification.
1862 *
1863 * @param pDrvIns The driver instance data.
1864 */
1865static DECLCALLBACK(void) drvAudioPowerOff(PPDMDRVINS pDrvIns)
1866{
1867 AudioState *s = &glob_audio_state;
1868 audio_vm_change_state_handler (s, 0);
1869}
1870
1871/**
1872 * Destruct a driver instance.
1873 *
1874 * Most VM resources are freed by the VM. This callback is provided so that any non-VM
1875 * resources can be freed correctly.
1876 *
1877 * @param pDrvIns The driver instance data.
1878 */
1879static DECLCALLBACK(void) drvAudioDestruct(PPDMDRVINS pDrvIns)
1880{
1881 LogFlow(("drvAUDIODestruct:\n"));
1882
1883 audio_atexit ();
1884}
1885
1886/**
1887 * Construct an AUDIO driver instance.
1888 *
1889 * @returns VBox status.
1890 * @param pDrvIns The driver instance data.
1891 * If the registration structure is needed, pDrvIns->pDrvReg points to it.
1892 * @param pCfgHandle Configuration node handle for the driver. Use this to obtain the configuration
1893 * of the driver instance. It's also found in pDrvIns->pCfgHandle, but like
1894 * iInstance it's expected to be used a bit in this function.
1895 */
1896static DECLCALLBACK(int) drvAudioConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfgHandle)
1897{
1898 int rc;
1899 PDRVAUDIO pData = PDMINS2DATA(pDrvIns, PDRVAUDIO);
1900 char *drvname;
1901
1902 LogFlow(("drvAUDIOConstruct:\n"));
1903 /*
1904 * Validate the config.
1905 */
1906 if (!CFGMR3AreValuesValid(pCfgHandle, "AudioDriver\0"))
1907 return VERR_PDM_DRVINS_UNKNOWN_CFG_VALUES;
1908
1909 /*
1910 * Init the static parts.
1911 */
1912 pData->pDrvIns = pDrvIns;
1913 /* IBase */
1914 pDrvIns->IBase.pfnQueryInterface = drvAudioQueryInterface;
1915 /* IAudio */
1916 /* pData->IAudioConnector.pfn; */
1917
1918 glob_audio_state.pDrvIns = pDrvIns;
1919
1920 rc = CFGMR3QueryStringAlloc (pCfgHandle, "AudioDriver", &drvname);
1921 if (VBOX_FAILURE (rc))
1922 return rc;
1923
1924 rc = AUD_init (pDrvIns, drvname);
1925 if (VBOX_FAILURE (rc))
1926 return rc;
1927
1928 MMR3HeapFree (drvname);
1929
1930 return VINF_SUCCESS;
1931}
1932
1933/**
1934 * Suspend notification.
1935 *
1936 * @returns VBox status.
1937 * @param pDrvIns The driver instance data.
1938 */
1939static DECLCALLBACK(void) drvAudioSuspend(PPDMDRVINS pDrvIns)
1940{
1941 AudioState *s = &glob_audio_state;
1942 audio_vm_change_state_handler (s, 0);
1943}
1944
1945/**
1946 * Resume notification.
1947 *
1948 * @returns VBox status.
1949 * @param pDrvIns The driver instance data.
1950 */
1951static DECLCALLBACK(void) audioResume(PPDMDRVINS pDrvIns)
1952{
1953 AudioState *s = &glob_audio_state;
1954 audio_vm_change_state_handler (s, 1);
1955}
1956
1957/**
1958 * Audio driver registration record.
1959 */
1960const PDMDRVREG g_DrvAUDIO =
1961{
1962 /* u32Version */
1963 PDM_DRVREG_VERSION,
1964 /* szDriverName */
1965 "AUDIO",
1966 /* pszDescription */
1967 "AUDIO Driver",
1968 /* fFlags */
1969 PDM_DRVREG_FLAGS_HOST_BITS_DEFAULT,
1970 /* fClass. */
1971 PDM_DRVREG_CLASS_AUDIO,
1972 /* cMaxInstances */
1973 1,
1974 /* cbInstance */
1975 sizeof(DRVAUDIO),
1976 /* pfnConstruct */
1977 drvAudioConstruct,
1978 /* pfnDestruct */
1979 drvAudioDestruct,
1980 /* pfnIOCtl */
1981 NULL,
1982 /* pfnPowerOn */
1983 NULL,
1984 /* pfnReset */
1985 NULL,
1986 /* pfnSuspend */
1987 drvAudioSuspend,
1988 /* pfnResume */
1989 audioResume,
1990 /* pfnDetach */
1991 NULL,
1992 /* pfnPowerOff */
1993 drvAudioPowerOff
1994};
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