VirtualBox

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

Last change on this file since 566 was 366, checked in by vboxsync, 18 years ago

made mixing of pcm_in work

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