VirtualBox

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

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

Pass the VM name to the audio driver. PulseAudio will name the name of the stream according to that name.

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

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