• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * QEMU Audio subsystem
3  *
4  * Copyright (c) 2007-2008 The Android Open Source Project
5  * Copyright (c) 2003-2005 Vassili Karpov (malc)
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining a copy
8  * of this software and associated documentation files (the "Software"), to deal
9  * in the Software without restriction, including without limitation the rights
10  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11  * copies of the Software, and to permit persons to whom the Software is
12  * furnished to do so, subject to the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be included in
15  * all copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23  * THE SOFTWARE.
24  */
25 #include "hw/hw.h"
26 #include "audio.h"
27 #include "monitor.h"
28 #include "qemu-timer.h"
29 #include "sysemu.h"
30 
31 #define AUDIO_CAP "audio"
32 #include "audio_int.h"
33 #include "android/utils/system.h"
34 #include "qemu_debug.h"
35 #include "android/android.h"
36 
37 /* #define DEBUG_PLIVE */
38 /* #define DEBUG_LIVE */
39 /* #define DEBUG_OUT */
40 /* #define DEBUG_CAPTURE */
41 
42 #define SW_NAME(sw) (sw)->name ? (sw)->name : "unknown"
43 
44 static struct audio_driver *drvtab[] = {
45 #ifdef CONFIG_PULSEAUDIO
46     &pa_audio_driver,
47 #endif
48 #ifdef CONFIG_ESD
49     &esd_audio_driver,
50 #endif
51 #ifdef CONFIG_ALSA
52     &alsa_audio_driver,
53 #endif
54 #ifdef CONFIG_COREAUDIO
55     &coreaudio_audio_driver,
56 #endif
57 #ifdef CONFIG_DSOUND
58     &dsound_audio_driver,
59 #endif
60 #ifdef CONFIG_FMOD
61     &fmod_audio_driver,
62 #endif
63 #ifdef CONFIG_WINAUDIO
64     &win_audio_driver,
65 #endif
66 #ifdef CONFIG_OSS
67     &oss_audio_driver,
68 #endif
69     &no_audio_driver,
70 #if 0  /* disabled WAV audio for now - until we find a user-friendly way to use it */
71     &wav_audio_driver
72 #endif
73 };
74 
75 
76 int
audio_get_backend_count(int is_input)77 audio_get_backend_count( int  is_input )
78 {
79     int  nn, count = 0;
80 
81     for (nn = 0; nn < sizeof(drvtab)/sizeof(drvtab[0]); nn++)
82     {
83         if (is_input) {
84             if ( drvtab[nn]->max_voices_in > 0 )
85                 count += 1;
86         } else {
87             if ( drvtab[nn]->max_voices_out > 0 )
88                 count += 1;
89         }
90     }
91     return  count;
92 }
93 
94 const char*
audio_get_backend_name(int is_input,int index,const char ** pinfo)95 audio_get_backend_name( int   is_input, int  index, const char*  *pinfo )
96 {
97     int  nn;
98 
99     index += 1;
100     for (nn = 0; nn < sizeof(drvtab)/sizeof(drvtab[0]); nn++)
101     {
102         if (is_input) {
103             if ( drvtab[nn]->max_voices_in > 0 ) {
104                 if ( --index == 0 ) {
105                     *pinfo = drvtab[nn]->descr;
106                     return drvtab[nn]->name;
107                 }
108             }
109         } else {
110             if ( drvtab[nn]->max_voices_out > 0 ) {
111                 if ( --index == 0 ) {
112                     *pinfo = drvtab[nn]->descr;
113                     return drvtab[nn]->name;
114                 }
115             }
116         }
117     }
118     *pinfo = NULL;
119     return  NULL;
120 }
121 
122 
123 int
audio_check_backend_name(int is_input,const char * name)124 audio_check_backend_name( int  is_input, const char*  name )
125 {
126     int  nn;
127 
128     for (nn = 0; nn < sizeof(drvtab)/sizeof(drvtab[0]); nn++)
129     {
130         if ( !strcmp(drvtab[nn]->name, name) ) {
131             if (is_input) {
132                 if (drvtab[nn]->max_voices_in > 0)
133                     return 1;
134             } else {
135                 if (drvtab[nn]->max_voices_out > 0)
136                     return 1;
137             }
138             break;
139         }
140     }
141     return 0;
142 }
143 
144 
145 struct fixed_settings {
146     int enabled;
147     int nb_voices;
148     int greedy;
149     struct audsettings settings;
150 };
151 
152 static struct {
153     struct fixed_settings fixed_out;
154     struct fixed_settings fixed_in;
155     union {
156         int hertz;
157         int64_t ticks;
158     } period;
159     int plive;
160     int log_to_monitor;
161     int try_poll_in;
162     int try_poll_out;
163 } conf = {
164     .fixed_out = { /* DAC fixed settings */
165         .enabled = 1,
166         .nb_voices = 1,
167         .greedy = 1,
168         .settings = {
169             .freq = 44100,
170             .nchannels = 2,
171             .fmt = AUD_FMT_S16,
172             .endianness =  AUDIO_HOST_ENDIANNESS,
173         }
174     },
175 
176     .fixed_in = { /* ADC fixed settings */
177         .enabled = 1,
178         .nb_voices = 1,
179         .greedy = 1,
180         .settings = {
181             .freq = 44100,
182             .nchannels = 2,
183             .fmt = AUD_FMT_S16,
184             .endianness = AUDIO_HOST_ENDIANNESS,
185         }
186     },
187 
188     .period = { .hertz = 250 },
189     .plive = 0,
190     .log_to_monitor = 0,
191     .try_poll_in = 1,
192     .try_poll_out = 1,
193 };
194 
195 static AudioState glob_audio_state;
196 
197 struct mixeng_volume nominal_volume = {
198     .mute = 0,
199 #ifdef FLOAT_MIXENG
200     .r = 1.0,
201     .l = 1.0,
202 #else
203     .r = 1ULL << 32,
204     .l = 1ULL << 32,
205 #endif
206 };
207 
208 #ifdef AUDIO_IS_FLAWLESS_AND_NO_CHECKS_ARE_REQURIED
209 #error No its not
210 #else
211 static void audio_print_options (const char *prefix,
212                                  struct audio_option *opt);
213 
audio_bug(const char * funcname,int cond)214 int audio_bug (const char *funcname, int cond)
215 {
216     if (cond) {
217         static int shown;
218 
219         AUD_log (NULL, "A bug was just triggered in %s\n", funcname);
220         if (!shown) {
221             struct audio_driver *d;
222 
223             shown = 1;
224             AUD_log (NULL, "Save all your work and restart without audio\n");
225             AUD_log (NULL, "Please send bug report to av1474@comtv.ru\n");
226             AUD_log (NULL, "I am sorry\n");
227             d = glob_audio_state.drv;
228             if (d) {
229                 audio_print_options (d->name, d->options);
230             }
231         }
232         AUD_log (NULL, "Context:\n");
233 
234 #if defined AUDIO_BREAKPOINT_ON_BUG
235 #  if defined HOST_I386
236 #    if defined __GNUC__
237         __asm__ ("int3");
238 #    elif defined _MSC_VER
239         _asm _emit 0xcc;
240 #    else
241         abort ();
242 #    endif
243 #  else
244         abort ();
245 #  endif
246 #endif
247     }
248 
249     return cond;
250 }
251 #endif
252 
audio_bits_to_index(int bits)253 static inline int audio_bits_to_index (int bits)
254 {
255     switch (bits) {
256     case 8:
257         return 0;
258 
259     case 16:
260         return 1;
261 
262     case 32:
263         return 2;
264 
265     default:
266         audio_bug ("bits_to_index", 1);
267         AUD_log (NULL, "invalid bits %d\n", bits);
268         return 0;
269     }
270 }
271 
audio_calloc(const char * funcname,int nmemb,size_t size)272 void *audio_calloc (const char *funcname, int nmemb, size_t size)
273 {
274     int cond;
275     size_t len;
276 
277     len = nmemb * size;
278     cond = !nmemb || !size;
279     cond |= nmemb < 0;
280     cond |= len < size;
281 
282     if (audio_bug ("audio_calloc", cond)) {
283         AUD_log (NULL, "%s passed invalid arguments to audio_calloc\n",
284                  funcname);
285         AUD_log (NULL, "nmemb=%d size=%zu (len=%zu)\n", nmemb, size, len);
286         return NULL;
287     }
288 
289     return qemu_mallocz (len);
290 }
291 
audio_alloc_prefix(const char * s)292 static char *audio_alloc_prefix (const char *s)
293 {
294     const char qemu_prefix[] = "QEMU_";
295     size_t len, i;
296     char *r, *u;
297 
298     if (!s) {
299         return NULL;
300     }
301 
302     len = strlen (s);
303     r = qemu_malloc (len + sizeof (qemu_prefix));
304 
305     u = r + sizeof (qemu_prefix) - 1;
306 
307     pstrcpy (r, len + sizeof (qemu_prefix), qemu_prefix);
308     pstrcat (r, len + sizeof (qemu_prefix), s);
309 
310     for (i = 0; i < len; ++i) {
311         u[i] = qemu_toupper(u[i]);
312     }
313 
314     return r;
315 }
316 
audio_audfmt_to_string(audfmt_e fmt)317 static const char *audio_audfmt_to_string (audfmt_e fmt)
318 {
319     switch (fmt) {
320     case AUD_FMT_U8:
321         return "U8";
322 
323     case AUD_FMT_U16:
324         return "U16";
325 
326     case AUD_FMT_S8:
327         return "S8";
328 
329     case AUD_FMT_S16:
330         return "S16";
331 
332     case AUD_FMT_U32:
333         return "U32";
334 
335     case AUD_FMT_S32:
336         return "S32";
337     }
338 
339     dolog ("Bogus audfmt %d returning S16\n", fmt);
340     return "S16";
341 }
342 
audio_string_to_audfmt(const char * s,audfmt_e defval,int * defaultp)343 static audfmt_e audio_string_to_audfmt (const char *s, audfmt_e defval,
344                                         int *defaultp)
345 {
346     if (!strcasecmp (s, "u8")) {
347         *defaultp = 0;
348         return AUD_FMT_U8;
349     }
350     else if (!strcasecmp (s, "u16")) {
351         *defaultp = 0;
352         return AUD_FMT_U16;
353     }
354     else if (!strcasecmp (s, "u32")) {
355         *defaultp = 0;
356         return AUD_FMT_U32;
357     }
358     else if (!strcasecmp (s, "s8")) {
359         *defaultp = 0;
360         return AUD_FMT_S8;
361     }
362     else if (!strcasecmp (s, "s16")) {
363         *defaultp = 0;
364         return AUD_FMT_S16;
365     }
366     else if (!strcasecmp (s, "s32")) {
367         *defaultp = 0;
368         return AUD_FMT_S32;
369     }
370     else {
371         dolog ("Bogus audio format `%s' using %s\n",
372                s, audio_audfmt_to_string (defval));
373         *defaultp = 1;
374         return defval;
375     }
376 }
377 
audio_get_conf_fmt(const char * envname,audfmt_e defval,int * defaultp)378 static audfmt_e audio_get_conf_fmt (const char *envname,
379                                     audfmt_e defval,
380                                     int *defaultp)
381 {
382     const char *var = getenv (envname);
383     if (!var) {
384         *defaultp = 1;
385         return defval;
386     }
387     return audio_string_to_audfmt (var, defval, defaultp);
388 }
389 
audio_get_conf_int(const char * key,int defval,int * defaultp)390 static int audio_get_conf_int (const char *key, int defval, int *defaultp)
391 {
392     int val;
393     char *strval;
394 
395     strval = getenv (key);
396     if (strval) {
397         *defaultp = 0;
398         val = atoi (strval);
399         return val;
400     }
401     else {
402         *defaultp = 1;
403         return defval;
404     }
405 }
406 
audio_get_conf_str(const char * key,const char * defval,int * defaultp)407 static const char *audio_get_conf_str (const char *key,
408                                        const char *defval,
409                                        int *defaultp)
410 {
411     const char *val = getenv (key);
412     if (!val) {
413         *defaultp = 1;
414         return defval;
415     }
416     else {
417         *defaultp = 0;
418         return val;
419     }
420 }
421 
422 /* defined in android_sdl.c */
423 extern void  dprintn(const char*  fmt, ...);
424 extern void  dprintnv(const char*  fmt, va_list  args);
425 
AUD_vlog(const char * cap,const char * fmt,va_list ap)426 void AUD_vlog (const char *cap, const char *fmt, va_list ap)
427 {
428     if (conf.log_to_monitor) {
429         if (cap) {
430             monitor_printf(cur_mon, "%s: ", cap);
431         }
432 
433         monitor_vprintf(cur_mon, fmt, ap);
434     }
435     else {
436         if (!VERBOSE_CHECK(audio))
437             return;
438 
439         if (cap) {
440             dprintn("%s: ", cap);
441         }
442 
443         dprintnv(fmt, ap);
444     }
445 }
446 
AUD_log(const char * cap,const char * fmt,...)447 void AUD_log (const char *cap, const char *fmt, ...)
448 {
449     va_list ap;
450 
451     va_start (ap, fmt);
452     AUD_vlog (cap, fmt, ap);
453     va_end (ap);
454 }
455 
audio_print_options(const char * prefix,struct audio_option * opt)456 static void audio_print_options (const char *prefix,
457                                  struct audio_option *opt)
458 {
459     char *uprefix;
460 
461     if (!prefix) {
462         dolog ("No prefix specified\n");
463         return;
464     }
465 
466     if (!opt) {
467         dolog ("No options\n");
468         return;
469     }
470 
471     uprefix = audio_alloc_prefix (prefix);
472 
473     for (; opt->name; opt++) {
474         const char *state = "default";
475         printf ("  %s_%s: ", uprefix, opt->name);
476 
477         if (opt->overriddenp && *opt->overriddenp) {
478             state = "current";
479         }
480 
481         switch (opt->tag) {
482         case AUD_OPT_BOOL:
483             {
484                 int *intp = opt->valp;
485                 printf ("boolean, %s = %d\n", state, *intp ? 1 : 0);
486             }
487             break;
488 
489         case AUD_OPT_INT:
490             {
491                 int *intp = opt->valp;
492                 printf ("integer, %s = %d\n", state, *intp);
493             }
494             break;
495 
496         case AUD_OPT_FMT:
497             {
498                 audfmt_e *fmtp = opt->valp;
499                 printf (
500                     "format, %s = %s, (one of: U8 S8 U16 S16 U32 S32)\n",
501                     state,
502                     audio_audfmt_to_string (*fmtp)
503                     );
504             }
505             break;
506 
507         case AUD_OPT_STR:
508             {
509                 const char **strp = opt->valp;
510                 printf ("string, %s = %s\n",
511                         state,
512                         *strp ? *strp : "(not set)");
513             }
514             break;
515 
516         default:
517             printf ("???\n");
518             dolog ("Bad value tag for option %s_%s %d\n",
519                    uprefix, opt->name, opt->tag);
520             break;
521         }
522         printf ("    %s\n", opt->descr);
523     }
524 
525     qemu_free (uprefix);
526 }
527 
audio_process_options(const char * prefix,struct audio_option * opt)528 static void audio_process_options (const char *prefix,
529                                    struct audio_option *opt)
530 {
531     char *optname;
532     const char qemu_prefix[] = "QEMU_";
533     size_t preflen, optlen;
534 
535     if (audio_bug (AUDIO_FUNC, !prefix)) {
536         dolog ("prefix = NULL\n");
537         return;
538     }
539 
540     if (audio_bug (AUDIO_FUNC, !opt)) {
541         dolog ("opt = NULL\n");
542         return;
543     }
544 
545     preflen = strlen (prefix);
546 
547     for (; opt->name; opt++) {
548         size_t len, i;
549         int def;
550 
551         if (!opt->valp) {
552             dolog ("Option value pointer for `%s' is not set\n",
553                    opt->name);
554             continue;
555         }
556 
557         len = strlen (opt->name);
558         /* len of opt->name + len of prefix + size of qemu_prefix
559          * (includes trailing zero) + zero + underscore (on behalf of
560          * sizeof) */
561         optlen = len + preflen + sizeof (qemu_prefix) + 1;
562         optname = qemu_malloc (optlen);
563 
564         pstrcpy (optname, optlen, qemu_prefix);
565 
566         /* copy while upper-casing, including trailing zero */
567         for (i = 0; i <= preflen; ++i) {
568             optname[i + sizeof (qemu_prefix) - 1] = qemu_toupper(prefix[i]);
569         }
570         pstrcat (optname, optlen, "_");
571         pstrcat (optname, optlen, opt->name);
572 
573         def = 1;
574         switch (opt->tag) {
575         case AUD_OPT_BOOL:
576         case AUD_OPT_INT:
577             {
578                 int *intp = opt->valp;
579                 *intp = audio_get_conf_int (optname, *intp, &def);
580             }
581             break;
582 
583         case AUD_OPT_FMT:
584             {
585                 audfmt_e *fmtp = opt->valp;
586                 *fmtp = audio_get_conf_fmt (optname, *fmtp, &def);
587             }
588             break;
589 
590         case AUD_OPT_STR:
591             {
592                 const char **strp = opt->valp;
593                 *strp = audio_get_conf_str (optname, *strp, &def);
594             }
595             break;
596 
597         default:
598             dolog ("Bad value tag for option `%s' - %d\n",
599                    optname, opt->tag);
600             break;
601         }
602 
603         if (!opt->overriddenp) {
604             opt->overriddenp = &opt->overridden;
605         }
606         *opt->overriddenp = !def;
607         qemu_free (optname);
608     }
609 }
610 
audio_print_settings(struct audsettings * as)611 static void audio_print_settings (struct audsettings *as)
612 {
613     dolog ("frequency=%d nchannels=%d fmt=", as->freq, as->nchannels);
614 
615     switch (as->fmt) {
616     case AUD_FMT_S8:
617         AUD_log (NULL, "S8");
618         break;
619     case AUD_FMT_U8:
620         AUD_log (NULL, "U8");
621         break;
622     case AUD_FMT_S16:
623         AUD_log (NULL, "S16");
624         break;
625     case AUD_FMT_U16:
626         AUD_log (NULL, "U16");
627         break;
628     case AUD_FMT_S32:
629         AUD_log (NULL, "S32");
630         break;
631     case AUD_FMT_U32:
632         AUD_log (NULL, "U32");
633         break;
634     default:
635         AUD_log (NULL, "invalid(%d)", as->fmt);
636         break;
637     }
638 
639     AUD_log (NULL, " endianness=");
640     switch (as->endianness) {
641     case 0:
642         AUD_log (NULL, "little");
643         break;
644     case 1:
645         AUD_log (NULL, "big");
646         break;
647     default:
648         AUD_log (NULL, "invalid");
649         break;
650     }
651     AUD_log (NULL, "\n");
652 }
653 
audio_validate_settings(struct audsettings * as)654 static int audio_validate_settings (struct audsettings *as)
655 {
656     int invalid;
657 
658     invalid = as->nchannels != 1 && as->nchannels != 2;
659     invalid |= as->endianness != 0 && as->endianness != 1;
660 
661     switch (as->fmt) {
662     case AUD_FMT_S8:
663     case AUD_FMT_U8:
664     case AUD_FMT_S16:
665     case AUD_FMT_U16:
666     case AUD_FMT_S32:
667     case AUD_FMT_U32:
668         break;
669     default:
670         invalid = 1;
671         break;
672     }
673 
674     invalid |= as->freq <= 0;
675     return invalid ? -1 : 0;
676 }
677 
audio_pcm_info_eq(struct audio_pcm_info * info,struct audsettings * as)678 static int audio_pcm_info_eq (struct audio_pcm_info *info, struct audsettings *as)
679 {
680     int bits = 8, sign = 0;
681 
682     switch (as->fmt) {
683     case AUD_FMT_S8:
684         sign = 1;
685     case AUD_FMT_U8:
686         break;
687 
688     case AUD_FMT_S16:
689         sign = 1;
690     case AUD_FMT_U16:
691         bits = 16;
692         break;
693 
694     case AUD_FMT_S32:
695         sign = 1;
696     case AUD_FMT_U32:
697         bits = 32;
698         break;
699     }
700     return info->freq == as->freq
701         && info->nchannels == as->nchannels
702         && info->sign == sign
703         && info->bits == bits
704         && info->swap_endianness == (as->endianness != AUDIO_HOST_ENDIANNESS);
705 }
706 
audio_pcm_init_info(struct audio_pcm_info * info,struct audsettings * as)707 void audio_pcm_init_info (struct audio_pcm_info *info, struct audsettings *as)
708 {
709     int bits = 8, sign = 0, shift = 0;
710 
711     switch (as->fmt) {
712     case AUD_FMT_S8:
713         sign = 1;
714     case AUD_FMT_U8:
715         break;
716 
717     case AUD_FMT_S16:
718         sign = 1;
719     case AUD_FMT_U16:
720         bits = 16;
721         shift = 1;
722         break;
723 
724     case AUD_FMT_S32:
725         sign = 1;
726     case AUD_FMT_U32:
727         bits = 32;
728         shift = 2;
729         break;
730     }
731 
732     info->freq = as->freq;
733     info->bits = bits;
734     info->sign = sign;
735     info->nchannels = as->nchannels;
736     info->shift = (as->nchannels == 2) + shift;
737     info->align = (1 << info->shift) - 1;
738     info->bytes_per_second = info->freq << info->shift;
739     info->swap_endianness = (as->endianness != AUDIO_HOST_ENDIANNESS);
740 }
741 
audio_pcm_info_clear_buf(struct audio_pcm_info * info,void * buf,int len)742 void audio_pcm_info_clear_buf (struct audio_pcm_info *info, void *buf, int len)
743 {
744     if (!len) {
745         return;
746     }
747 
748     if (info->sign) {
749         memset (buf, 0x00, len << info->shift);
750     }
751     else {
752         switch (info->bits) {
753         case 8:
754             memset (buf, 0x80, len << info->shift);
755             break;
756 
757         case 16:
758             {
759                 int i;
760                 uint16_t *p = buf;
761                 int shift = info->nchannels - 1;
762                 short s = INT16_MAX;
763 
764                 if (info->swap_endianness) {
765                     s = bswap16 (s);
766                 }
767 
768                 for (i = 0; i < len << shift; i++) {
769                     p[i] = s;
770                 }
771             }
772             break;
773 
774         case 32:
775             {
776                 int i;
777                 uint32_t *p = buf;
778                 int shift = info->nchannels - 1;
779                 int32_t s = INT32_MAX;
780 
781                 if (info->swap_endianness) {
782                     s = bswap32 (s);
783                 }
784 
785                 for (i = 0; i < len << shift; i++) {
786                     p[i] = s;
787                 }
788             }
789             break;
790 
791         default:
792             AUD_log (NULL, "audio_pcm_info_clear_buf: invalid bits %d\n",
793                      info->bits);
794             break;
795         }
796     }
797 }
798 
799 /*
800  * Capture
801  */
noop_conv(struct st_sample * dst,const void * src,int samples,struct mixeng_volume * vol)802 static void noop_conv (struct st_sample *dst, const void *src,
803                        int samples, struct mixeng_volume *vol)
804 {
805     (void) src;
806     (void) dst;
807     (void) samples;
808     (void) vol;
809 }
810 
audio_pcm_capture_find_specific(struct audsettings * as)811 static CaptureVoiceOut *audio_pcm_capture_find_specific (
812     struct audsettings *as
813     )
814 {
815     CaptureVoiceOut *cap;
816     AudioState *s = &glob_audio_state;
817 
818     for (cap = s->cap_head.lh_first; cap; cap = cap->entries.le_next) {
819         if (audio_pcm_info_eq (&cap->hw.info, as)) {
820             return cap;
821         }
822     }
823     return NULL;
824 }
825 
audio_notify_capture(CaptureVoiceOut * cap,audcnotification_e cmd)826 static void audio_notify_capture (CaptureVoiceOut *cap, audcnotification_e cmd)
827 {
828     struct capture_callback *cb;
829 
830 #ifdef DEBUG_CAPTURE
831     dolog ("notification %d sent\n", cmd);
832 #endif
833     for (cb = cap->cb_head.lh_first; cb; cb = cb->entries.le_next) {
834         cb->ops.notify (cb->opaque, cmd);
835     }
836 }
837 
audio_capture_maybe_changed(CaptureVoiceOut * cap,int enabled)838 static void audio_capture_maybe_changed (CaptureVoiceOut *cap, int enabled)
839 {
840     if (cap->hw.enabled != enabled) {
841         audcnotification_e cmd;
842         cap->hw.enabled = enabled;
843         cmd = enabled ? AUD_CNOTIFY_ENABLE : AUD_CNOTIFY_DISABLE;
844         audio_notify_capture (cap, cmd);
845     }
846 }
847 
audio_recalc_and_notify_capture(CaptureVoiceOut * cap)848 static void audio_recalc_and_notify_capture (CaptureVoiceOut *cap)
849 {
850     HWVoiceOut *hw = &cap->hw;
851     SWVoiceOut *sw;
852     int enabled = 0;
853 
854     for (sw = hw->sw_head.lh_first; sw; sw = sw->entries.le_next) {
855         if (sw->active) {
856             enabled = 1;
857             break;
858         }
859     }
860     audio_capture_maybe_changed (cap, enabled);
861 }
862 
audio_detach_capture(HWVoiceOut * hw)863 static void audio_detach_capture (HWVoiceOut *hw)
864 {
865     SWVoiceCap *sc = hw->cap_head.lh_first;
866 
867     while (sc) {
868         SWVoiceCap *sc1 = sc->entries.le_next;
869         SWVoiceOut *sw = &sc->sw;
870         CaptureVoiceOut *cap = sc->cap;
871         int was_active = sw->active;
872 
873         if (sw->rate) {
874             st_rate_stop (sw->rate);
875             sw->rate = NULL;
876         }
877 
878         QLIST_REMOVE (sw, entries);
879         QLIST_REMOVE (sc, entries);
880         qemu_free (sc);
881         if (was_active) {
882             /* We have removed soft voice from the capture:
883                this might have changed the overall status of the capture
884                since this might have been the only active voice */
885             audio_recalc_and_notify_capture (cap);
886         }
887         sc = sc1;
888     }
889 }
890 
audio_attach_capture(HWVoiceOut * hw)891 static int audio_attach_capture (HWVoiceOut *hw)
892 {
893     AudioState *s = &glob_audio_state;
894     CaptureVoiceOut *cap;
895 
896     audio_detach_capture (hw);
897     for (cap = s->cap_head.lh_first; cap; cap = cap->entries.le_next) {
898         SWVoiceCap *sc;
899         SWVoiceOut *sw;
900         HWVoiceOut *hw_cap = &cap->hw;
901 
902         sc = audio_calloc (AUDIO_FUNC, 1, sizeof (*sc));
903         if (!sc) {
904             dolog ("Could not allocate soft capture voice (%zu bytes)\n",
905                    sizeof (*sc));
906             return -1;
907         }
908 
909         sc->cap = cap;
910         sw = &sc->sw;
911         sw->hw = hw_cap;
912         sw->info = hw->info;
913         sw->empty = 1;
914         sw->active = hw->enabled;
915         sw->conv = noop_conv;
916         sw->ratio = ((int64_t) hw_cap->info.freq << 32) / sw->info.freq;
917         sw->rate = st_rate_start (sw->info.freq, hw_cap->info.freq);
918         if (!sw->rate) {
919             dolog ("Could not start rate conversion for `%s'\n", SW_NAME (sw));
920             qemu_free (sw);
921             return -1;
922         }
923         QLIST_INSERT_HEAD (&hw_cap->sw_head, sw, entries);
924         QLIST_INSERT_HEAD (&hw->cap_head, sc, entries);
925 #ifdef DEBUG_CAPTURE
926         asprintf (&sw->name, "for %p %d,%d,%d",
927                   hw, sw->info.freq, sw->info.bits, sw->info.nchannels);
928         dolog ("Added %s active = %d\n", sw->name, sw->active);
929 #endif
930         if (sw->active) {
931             audio_capture_maybe_changed (cap, 1);
932         }
933     }
934     return 0;
935 }
936 
937 /*
938  * Hard voice (capture)
939  */
audio_pcm_hw_find_min_in(HWVoiceIn * hw)940 static int audio_pcm_hw_find_min_in (HWVoiceIn *hw)
941 {
942     SWVoiceIn *sw;
943     int m = hw->total_samples_captured;
944 
945     for (sw = hw->sw_head.lh_first; sw; sw = sw->entries.le_next) {
946         if (sw->active) {
947             m = audio_MIN (m, sw->total_hw_samples_acquired);
948         }
949     }
950     return m;
951 }
952 
audio_pcm_hw_get_live_in(HWVoiceIn * hw)953 int audio_pcm_hw_get_live_in (HWVoiceIn *hw)
954 {
955     int live = hw->total_samples_captured - audio_pcm_hw_find_min_in (hw);
956     if (audio_bug (AUDIO_FUNC, live < 0 || live > hw->samples)) {
957         dolog ("live=%d hw->samples=%d\n", live, hw->samples);
958         return 0;
959     }
960     return live;
961 }
962 
audio_pcm_hw_clip_out(HWVoiceOut * hw,void * pcm_buf,int live,int pending)963 int audio_pcm_hw_clip_out (HWVoiceOut *hw, void *pcm_buf,
964                            int live, int pending)
965 {
966     int left = hw->samples - pending;
967     int len = audio_MIN (left, live);
968     int clipped = 0;
969 
970     while (len) {
971         struct st_sample *src = hw->mix_buf + hw->rpos;
972         uint8_t *dst = advance (pcm_buf, hw->rpos << hw->info.shift);
973         int samples_till_end_of_buf = hw->samples - hw->rpos;
974         int samples_to_clip = audio_MIN (len, samples_till_end_of_buf);
975 
976         hw->clip (dst, src, samples_to_clip);
977 
978         hw->rpos = (hw->rpos + samples_to_clip) % hw->samples;
979         len -= samples_to_clip;
980         clipped += samples_to_clip;
981     }
982     return clipped;
983 }
984 
985 /*
986  * Soft voice (capture)
987  */
audio_pcm_sw_get_rpos_in(SWVoiceIn * sw)988 static int audio_pcm_sw_get_rpos_in (SWVoiceIn *sw)
989 {
990     HWVoiceIn *hw = sw->hw;
991     int live = hw->total_samples_captured - sw->total_hw_samples_acquired;
992     int rpos;
993 
994     if (audio_bug (AUDIO_FUNC, live < 0 || live > hw->samples)) {
995         dolog ("live=%d hw->samples=%d\n", live, hw->samples);
996         return 0;
997     }
998 
999     rpos = hw->wpos - live;
1000     if (rpos >= 0) {
1001         return rpos;
1002     }
1003     else {
1004         return hw->samples + rpos;
1005     }
1006 }
1007 
audio_pcm_sw_read(SWVoiceIn * sw,void * buf,int size)1008 int audio_pcm_sw_read (SWVoiceIn *sw, void *buf, int size)
1009 {
1010     HWVoiceIn *hw = sw->hw;
1011     int samples, live, ret = 0, swlim, isamp, osamp, rpos, total = 0;
1012     struct st_sample *src, *dst = sw->buf;
1013 
1014     rpos = audio_pcm_sw_get_rpos_in (sw) % hw->samples;
1015 
1016     live = hw->total_samples_captured - sw->total_hw_samples_acquired;
1017     if (audio_bug (AUDIO_FUNC, live < 0 || live > hw->samples)) {
1018         dolog ("live_in=%d hw->samples=%d\n", live, hw->samples);
1019         return 0;
1020     }
1021 
1022     samples = size >> sw->info.shift;
1023     if (!live) {
1024         return 0;
1025     }
1026 
1027     swlim = (live * sw->ratio) >> 32;
1028     swlim = audio_MIN (swlim, samples);
1029 
1030     while (swlim) {
1031         src = hw->conv_buf + rpos;
1032         isamp = hw->wpos - rpos;
1033         /* XXX: <= ? */
1034         if (isamp <= 0) {
1035             isamp = hw->samples - rpos;
1036         }
1037 
1038         if (!isamp) {
1039             break;
1040         }
1041         osamp = swlim;
1042 
1043         if (audio_bug (AUDIO_FUNC, osamp < 0)) {
1044             dolog ("osamp=%d\n", osamp);
1045             return 0;
1046         }
1047 
1048         st_rate_flow (sw->rate, src, dst, &isamp, &osamp);
1049         swlim -= osamp;
1050         rpos = (rpos + isamp) % hw->samples;
1051         dst += osamp;
1052         ret += osamp;
1053         total += isamp;
1054     }
1055 
1056     sw->clip (buf, sw->buf, ret);
1057     sw->total_hw_samples_acquired += total;
1058     return ret << sw->info.shift;
1059 }
1060 
1061 /*
1062  * Hard voice (playback)
1063  */
audio_pcm_hw_find_min_out(HWVoiceOut * hw,int * nb_livep)1064 static int audio_pcm_hw_find_min_out (HWVoiceOut *hw, int *nb_livep)
1065 {
1066     SWVoiceOut *sw;
1067     int m = INT_MAX;
1068     int nb_live = 0;
1069 
1070     for (sw = hw->sw_head.lh_first; sw; sw = sw->entries.le_next) {
1071         if (sw->active && !sw->empty) {
1072             m = audio_MIN (m, sw->total_hw_samples_mixed);
1073             nb_live += 1;
1074         }
1075     }
1076 
1077     *nb_livep = nb_live;
1078     return m;
1079 }
1080 
audio_pcm_hw_get_live_out(HWVoiceOut * hw,int * nb_live)1081 static int audio_pcm_hw_get_live_out (HWVoiceOut *hw, int *nb_live)
1082 {
1083     int smin;
1084     int nb_live1;
1085 
1086     smin = audio_pcm_hw_find_min_out (hw, &nb_live1);
1087     if (nb_live) {
1088         *nb_live = nb_live1;
1089     }
1090 
1091     if (nb_live1) {
1092         int live = smin;
1093 
1094         if (audio_bug (AUDIO_FUNC, live < 0 || live > hw->samples)) {
1095             dolog ("live=%d hw->samples=%d\n", live, hw->samples);
1096             return 0;
1097         }
1098         return live;
1099     }
1100     return 0;
1101 }
1102 
1103 /*
1104  * Soft voice (playback)
1105  */
audio_pcm_sw_write(SWVoiceOut * sw,void * buf,int size)1106 int audio_pcm_sw_write (SWVoiceOut *sw, void *buf, int size)
1107 {
1108     int hwsamples, samples, isamp, osamp, wpos, live, dead, left, swlim, blck;
1109     int ret = 0, pos = 0, total = 0;
1110 
1111     if (!sw) {
1112         return size;
1113     }
1114 
1115     hwsamples = sw->hw->samples;
1116 
1117     live = sw->total_hw_samples_mixed;
1118     if (audio_bug (AUDIO_FUNC, live < 0 || live > hwsamples)){
1119         dolog ("live=%d hw->samples=%d\n", live, hwsamples);
1120         return 0;
1121     }
1122 
1123     if (live == hwsamples) {
1124 #ifdef DEBUG_OUT
1125         dolog ("%s is full %d\n", sw->name, live);
1126 #endif
1127         return 0;
1128     }
1129 
1130     wpos = (sw->hw->rpos + live) % hwsamples;
1131     samples = size >> sw->info.shift;
1132 
1133     dead = hwsamples - live;
1134     swlim = ((int64_t) dead << 32) / sw->ratio;
1135     swlim = audio_MIN (swlim, samples);
1136     if (swlim) {
1137         sw->conv (sw->buf, buf, swlim, &sw->vol);
1138     }
1139 
1140     while (swlim) {
1141         dead = hwsamples - live;
1142         left = hwsamples - wpos;
1143         blck = audio_MIN (dead, left);
1144         if (!blck) {
1145             break;
1146         }
1147         isamp = swlim;
1148         osamp = blck;
1149         st_rate_flow_mix (
1150             sw->rate,
1151             sw->buf + pos,
1152             sw->hw->mix_buf + wpos,
1153             &isamp,
1154             &osamp
1155             );
1156         ret += isamp;
1157         swlim -= isamp;
1158         pos += isamp;
1159         live += osamp;
1160         wpos = (wpos + osamp) % hwsamples;
1161         total += osamp;
1162     }
1163 
1164     sw->total_hw_samples_mixed += total;
1165     sw->empty = sw->total_hw_samples_mixed == 0;
1166 
1167 #ifdef DEBUG_OUT
1168     dolog (
1169         "%s: write size %d ret %d total sw %d\n",
1170         SW_NAME (sw),
1171         size >> sw->info.shift,
1172         ret,
1173         sw->total_hw_samples_mixed
1174         );
1175 #endif
1176 
1177     return ret << sw->info.shift;
1178 }
1179 
1180 #ifdef DEBUG_AUDIO
audio_pcm_print_info(const char * cap,struct audio_pcm_info * info)1181 static void audio_pcm_print_info (const char *cap, struct audio_pcm_info *info)
1182 {
1183     dolog ("%s: bits %d, sign %d, freq %d, nchan %d\n",
1184            cap, info->bits, info->sign, info->freq, info->nchannels);
1185 }
1186 #endif
1187 
1188 #define DAC
1189 #include "audio_template.h"
1190 #undef DAC
1191 #include "audio_template.h"
1192 
1193 /*
1194  * Timer
1195  */
audio_timer(void * opaque)1196 static void audio_timer (void *opaque)
1197 {
1198     AudioState *s = opaque;
1199 #if 0
1200 #define  MAX_DIFFS  100
1201     int64_t         now  = qemu_get_clock_ms(vm_clock);
1202     static int64_t  last = 0;
1203     static float    diffs[MAX_DIFFS];
1204     static int      num_diffs;
1205 
1206     if (last == 0)
1207         last = now;
1208     else {
1209         diffs[num_diffs] = (float)((now-last)/1e6);  /* last diff in ms */
1210         if (++num_diffs == MAX_DIFFS) {
1211             double  min_diff = 1e6, max_diff = -1e6;
1212             double  all_diff = 0.;
1213             int     nn;
1214 
1215             for (nn = 0; nn < num_diffs; nn++) {
1216                 if (diffs[nn] < min_diff) min_diff = diffs[nn];
1217                 if (diffs[nn] > max_diff) max_diff = diffs[nn];
1218                 all_diff += diffs[nn];
1219             }
1220             all_diff *= 1.0/num_diffs;
1221             printf("audio timer: min_diff=%6.2g max_diff=%6.2g avg_diff=%6.2g samples=%d\n",
1222                             min_diff, max_diff, all_diff, num_diffs);
1223             num_diffs = 0;
1224         }
1225     }
1226     last = now;
1227 #endif
1228 
1229     audio_run ("timer");
1230     qemu_mod_timer (s->ts, qemu_get_clock_ns (vm_clock) + conf.period.ticks);
1231 }
1232 
1233 
audio_is_timer_needed(void)1234 static int audio_is_timer_needed (void)
1235 {
1236     HWVoiceIn *hwi = NULL;
1237     HWVoiceOut *hwo = NULL;
1238 
1239     while ((hwo = audio_pcm_hw_find_any_enabled_out (hwo))) {
1240         if (!hwo->poll_mode) return 1;
1241     }
1242     while ((hwi = audio_pcm_hw_find_any_enabled_in (hwi))) {
1243         if (!hwi->poll_mode) return 1;
1244     }
1245     return 0;
1246 }
1247 
audio_reset_timer(void)1248 static void audio_reset_timer (void)
1249 {
1250     AudioState *s = &glob_audio_state;
1251 
1252     if (audio_is_timer_needed ()) {
1253         qemu_mod_timer (s->ts, qemu_get_clock_ns (vm_clock) + 1);
1254     }
1255     else {
1256         qemu_del_timer (s->ts);
1257     }
1258 }
1259 
1260 /*
1261  * Public API
1262  */
AUD_write(SWVoiceOut * sw,void * buf,int size)1263 int AUD_write (SWVoiceOut *sw, void *buf, int size)
1264 {
1265     int bytes;
1266 
1267     if (!sw) {
1268         /* XXX: Consider options */
1269         return size;
1270     }
1271 
1272     if (!sw->hw->enabled) {
1273         dolog ("Writing to disabled voice %s\n", SW_NAME (sw));
1274         return 0;
1275     }
1276 
1277     bytes = sw->hw->pcm_ops->write (sw, buf, size);
1278     return bytes;
1279 }
1280 
AUD_read(SWVoiceIn * sw,void * buf,int size)1281 int AUD_read (SWVoiceIn *sw, void *buf, int size)
1282 {
1283     int bytes;
1284 
1285     if (!sw) {
1286         /* XXX: Consider options */
1287         return size;
1288     }
1289 
1290     if (!sw->hw->enabled) {
1291         dolog ("Reading from disabled voice %s\n", SW_NAME (sw));
1292         return 0;
1293     }
1294 
1295     bytes = sw->hw->pcm_ops->read (sw, buf, size);
1296     return bytes;
1297 }
1298 
AUD_get_buffer_size_out(SWVoiceOut * sw)1299 int AUD_get_buffer_size_out (SWVoiceOut *sw)
1300 {
1301     return sw->hw->samples << sw->hw->info.shift;
1302 }
1303 
AUD_set_active_out(SWVoiceOut * sw,int on)1304 void AUD_set_active_out (SWVoiceOut *sw, int on)
1305 {
1306     HWVoiceOut *hw;
1307 
1308     if (!sw) {
1309         return;
1310     }
1311 
1312     hw = sw->hw;
1313     if (sw->active != on) {
1314         AudioState *s = &glob_audio_state;
1315         SWVoiceOut *temp_sw;
1316         SWVoiceCap *sc;
1317 
1318         if (on) {
1319             hw->pending_disable = 0;
1320             if (!hw->enabled) {
1321                 hw->enabled = 1;
1322                 if (s->vm_running) {
1323                     hw->pcm_ops->ctl_out (hw, VOICE_ENABLE, conf.try_poll_out);
1324                     audio_reset_timer ();
1325                 }
1326             }
1327         }
1328         else {
1329             if (hw->enabled) {
1330                 int nb_active = 0;
1331 
1332                 for (temp_sw = hw->sw_head.lh_first; temp_sw;
1333                      temp_sw = temp_sw->entries.le_next) {
1334                     nb_active += temp_sw->active != 0;
1335                 }
1336 
1337                 hw->pending_disable = nb_active == 1;
1338             }
1339         }
1340 
1341         for (sc = hw->cap_head.lh_first; sc; sc = sc->entries.le_next) {
1342             sc->sw.active = hw->enabled;
1343             if (hw->enabled) {
1344                 audio_capture_maybe_changed (sc->cap, 1);
1345             }
1346         }
1347         sw->active = on;
1348     }
1349 }
1350 
AUD_set_active_in(SWVoiceIn * sw,int on)1351 void AUD_set_active_in (SWVoiceIn *sw, int on)
1352 {
1353     HWVoiceIn *hw;
1354 
1355     if (!sw) {
1356         return;
1357     }
1358 
1359     hw = sw->hw;
1360     if (sw->active != on) {
1361         AudioState *s = &glob_audio_state;
1362         SWVoiceIn *temp_sw;
1363 
1364         if (on) {
1365             if (!hw->enabled) {
1366                 hw->enabled = 1;
1367                 if (s->vm_running) {
1368                     hw->pcm_ops->ctl_in (hw, VOICE_ENABLE, conf.try_poll_in);
1369                 }
1370             }
1371             sw->total_hw_samples_acquired = hw->total_samples_captured;
1372         }
1373         else {
1374             if (hw->enabled) {
1375                 int nb_active = 0;
1376 
1377                 for (temp_sw = hw->sw_head.lh_first; temp_sw;
1378                      temp_sw = temp_sw->entries.le_next) {
1379                     nb_active += temp_sw->active != 0;
1380                 }
1381 
1382                 if (nb_active == 1) {
1383                     hw->enabled = 0;
1384                     hw->pcm_ops->ctl_in (hw, VOICE_DISABLE);
1385                 }
1386             }
1387         }
1388         sw->active = on;
1389     }
1390 }
1391 
audio_get_avail(SWVoiceIn * sw)1392 static int audio_get_avail (SWVoiceIn *sw)
1393 {
1394     int live;
1395 
1396     if (!sw) {
1397         return 0;
1398     }
1399 
1400     live = sw->hw->total_samples_captured - sw->total_hw_samples_acquired;
1401     if (audio_bug (AUDIO_FUNC, live < 0 || live > sw->hw->samples)) {
1402         dolog ("live=%d sw->hw->samples=%d\n", live, sw->hw->samples);
1403         return 0;
1404     }
1405 
1406     ldebug (
1407         "%s: get_avail live %d ret %" PRId64 "\n",
1408         SW_NAME (sw),
1409         live, (((int64_t) live << 32) / sw->ratio) << sw->info.shift
1410         );
1411 
1412     return (((int64_t) live << 32) / sw->ratio) << sw->info.shift;
1413 }
1414 
audio_get_free(SWVoiceOut * sw)1415 static int audio_get_free (SWVoiceOut *sw)
1416 {
1417     int live, dead;
1418 
1419     if (!sw) {
1420         return 0;
1421     }
1422 
1423     live = sw->total_hw_samples_mixed;
1424 
1425     if (audio_bug (AUDIO_FUNC, live < 0 || live > sw->hw->samples)) {
1426         dolog ("live=%d sw->hw->samples=%d\n", live, sw->hw->samples);
1427         return 0;
1428     }
1429 
1430     dead = sw->hw->samples - live;
1431 
1432 #ifdef DEBUG_OUT
1433     dolog ("%s: get_free live %d dead %d ret %" PRId64 "\n",
1434            SW_NAME (sw),
1435            live, dead, (((int64_t) dead << 32) / sw->ratio) << sw->info.shift);
1436 #endif
1437 
1438     return (((int64_t) dead << 32) / sw->ratio) << sw->info.shift;
1439 }
1440 
audio_capture_mix_and_clear(HWVoiceOut * hw,int rpos,int samples)1441 static void audio_capture_mix_and_clear (HWVoiceOut *hw, int rpos, int samples)
1442 {
1443     int n;
1444 
1445     if (hw->enabled) {
1446         SWVoiceCap *sc;
1447 
1448         for (sc = hw->cap_head.lh_first; sc; sc = sc->entries.le_next) {
1449             SWVoiceOut *sw = &sc->sw;
1450             int rpos2 = rpos;
1451 
1452             n = samples;
1453             while (n) {
1454                 int till_end_of_hw = hw->samples - rpos2;
1455                 int to_write = audio_MIN (till_end_of_hw, n);
1456                 int bytes = to_write << hw->info.shift;
1457                 int written;
1458 
1459                 sw->buf = hw->mix_buf + rpos2;
1460                 written = audio_pcm_sw_write (sw, NULL, bytes);
1461                 if (written - bytes) {
1462                     dolog ("Could not mix %d bytes into a capture "
1463                            "buffer, mixed %d\n",
1464                            bytes, written);
1465                     break;
1466                 }
1467                 n -= to_write;
1468                 rpos2 = (rpos2 + to_write) % hw->samples;
1469             }
1470         }
1471     }
1472 
1473     n = audio_MIN (samples, hw->samples - rpos);
1474     mixeng_clear (hw->mix_buf + rpos, n);
1475     mixeng_clear (hw->mix_buf, samples - n);
1476 }
1477 
audio_run_out(AudioState * s)1478 static void audio_run_out (AudioState *s)
1479 {
1480     HWVoiceOut *hw = NULL;
1481     SWVoiceOut *sw;
1482 
1483     while ((hw = audio_pcm_hw_find_any_enabled_out (hw))) {
1484         int played;
1485         int live, free, nb_live, cleanup_required, prev_rpos;
1486 
1487         live = audio_pcm_hw_get_live_out (hw, &nb_live);
1488         if (!nb_live) {
1489             live = 0;
1490         }
1491 
1492         if (audio_bug (AUDIO_FUNC, live < 0 || live > hw->samples)) {
1493             dolog ("live=%d hw->samples=%d\n", live, hw->samples);
1494             continue;
1495         }
1496 
1497         if (hw->pending_disable && !nb_live) {
1498             SWVoiceCap *sc;
1499 #ifdef DEBUG_OUT
1500             dolog ("Disabling voice\n");
1501 #endif
1502             hw->enabled = 0;
1503             hw->pending_disable = 0;
1504             hw->pcm_ops->ctl_out (hw, VOICE_DISABLE);
1505             for (sc = hw->cap_head.lh_first; sc; sc = sc->entries.le_next) {
1506                 sc->sw.active = 0;
1507                 audio_recalc_and_notify_capture (sc->cap);
1508             }
1509             continue;
1510         }
1511 
1512         if (!live) {
1513             for (sw = hw->sw_head.lh_first; sw; sw = sw->entries.le_next) {
1514                 if (sw->active) {
1515                     free = audio_get_free (sw);
1516                     if (free > 0) {
1517                         sw->callback.fn (sw->callback.opaque, free);
1518                     }
1519                 }
1520             }
1521             continue;
1522         }
1523 
1524         prev_rpos = hw->rpos;
1525         played = hw->pcm_ops->run_out (hw, live);
1526         if (audio_bug (AUDIO_FUNC, hw->rpos >= hw->samples)) {
1527             dolog ("hw->rpos=%d hw->samples=%d played=%d\n",
1528                    hw->rpos, hw->samples, played);
1529             hw->rpos = 0;
1530         }
1531 
1532 #ifdef DEBUG_OUT
1533         dolog ("played=%d\n", played);
1534 #endif
1535 
1536         if (played) {
1537             hw->ts_helper += played;
1538             audio_capture_mix_and_clear (hw, prev_rpos, played);
1539         }
1540 
1541         cleanup_required = 0;
1542         for (sw = hw->sw_head.lh_first; sw; sw = sw->entries.le_next) {
1543             if (!sw->active || sw->empty) {
1544                 continue;
1545             }
1546 
1547             if (audio_bug (AUDIO_FUNC, played > sw->total_hw_samples_mixed)) {
1548                 dolog ("played=%d sw->total_hw_samples_mixed=%d\n",
1549                        played, sw->total_hw_samples_mixed);
1550                 played = sw->total_hw_samples_mixed;
1551             }
1552 
1553             sw->total_hw_samples_mixed -= played;
1554 
1555             if (!sw->total_hw_samples_mixed) {
1556                 sw->empty = 1;
1557                 cleanup_required |= !sw->active && !sw->callback.fn;
1558             }
1559 
1560             if (sw->active) {
1561                 free = audio_get_free (sw);
1562                 if (free > 0) {
1563                     sw->callback.fn (sw->callback.opaque, free);
1564                 }
1565             }
1566         }
1567 
1568         if (cleanup_required) {
1569             SWVoiceOut *sw1;
1570 
1571             sw = hw->sw_head.lh_first;
1572             while (sw) {
1573                 sw1 = sw->entries.le_next;
1574                 if (!sw->active && !sw->callback.fn) {
1575 #ifdef DEBUG_PLIVE
1576                     dolog ("Finishing with old voice\n");
1577 #endif
1578                     audio_close_out (sw);
1579                 }
1580                 sw = sw1;
1581             }
1582         }
1583     }
1584 }
1585 
audio_run_in(AudioState * s)1586 static void audio_run_in (AudioState *s)
1587 {
1588     HWVoiceIn *hw = NULL;
1589 
1590     while ((hw = audio_pcm_hw_find_any_enabled_in (hw))) {
1591         SWVoiceIn *sw;
1592         int captured, min;
1593 
1594         captured = hw->pcm_ops->run_in (hw);
1595 
1596         min = audio_pcm_hw_find_min_in (hw);
1597         hw->total_samples_captured += captured - min;
1598         hw->ts_helper += captured;
1599 
1600         for (sw = hw->sw_head.lh_first; sw; sw = sw->entries.le_next) {
1601             sw->total_hw_samples_acquired -= min;
1602 
1603             if (sw->active) {
1604                 int avail;
1605 
1606                 avail = audio_get_avail (sw);
1607                 if (avail > 0) {
1608                     sw->callback.fn (sw->callback.opaque, avail);
1609                 }
1610             }
1611         }
1612     }
1613 }
1614 
audio_run_capture(AudioState * s)1615 static void audio_run_capture (AudioState *s)
1616 {
1617     CaptureVoiceOut *cap;
1618 
1619     for (cap = s->cap_head.lh_first; cap; cap = cap->entries.le_next) {
1620         int live, rpos, captured;
1621         HWVoiceOut *hw = &cap->hw;
1622         SWVoiceOut *sw;
1623 
1624         captured = live = audio_pcm_hw_get_live_out (hw, NULL);
1625         rpos = hw->rpos;
1626         while (live) {
1627             int left = hw->samples - rpos;
1628             int to_capture = audio_MIN (live, left);
1629             struct st_sample *src;
1630             struct capture_callback *cb;
1631 
1632             src = hw->mix_buf + rpos;
1633             hw->clip (cap->buf, src, to_capture);
1634             mixeng_clear (src, to_capture);
1635 
1636             for (cb = cap->cb_head.lh_first; cb; cb = cb->entries.le_next) {
1637                 cb->ops.capture (cb->opaque, cap->buf,
1638                                  to_capture << hw->info.shift);
1639             }
1640             rpos = (rpos + to_capture) % hw->samples;
1641             live -= to_capture;
1642         }
1643         hw->rpos = rpos;
1644 
1645         for (sw = hw->sw_head.lh_first; sw; sw = sw->entries.le_next) {
1646             if (!sw->active && sw->empty) {
1647                 continue;
1648             }
1649 
1650             if (audio_bug (AUDIO_FUNC, captured > sw->total_hw_samples_mixed)) {
1651                 dolog ("captured=%d sw->total_hw_samples_mixed=%d\n",
1652                        captured, sw->total_hw_samples_mixed);
1653                 captured = sw->total_hw_samples_mixed;
1654             }
1655 
1656             sw->total_hw_samples_mixed -= captured;
1657             sw->empty = sw->total_hw_samples_mixed == 0;
1658         }
1659     }
1660 }
1661 
audio_run(const char * msg)1662 void audio_run (const char *msg)
1663 {
1664     AudioState *s = &glob_audio_state;
1665 
1666     audio_run_out (s);
1667     audio_run_in (s);
1668     audio_run_capture (s);
1669 #ifdef DEBUG_POLL
1670     {
1671         static double prevtime;
1672         double currtime;
1673         struct timeval tv;
1674 
1675         if (gettimeofday (&tv, NULL)) {
1676             perror ("audio_run: gettimeofday");
1677             return;
1678         }
1679 
1680         currtime = tv.tv_sec + tv.tv_usec * 1e-6;
1681         dolog ("Elapsed since last %s: %f\n", msg, currtime - prevtime);
1682         prevtime = currtime;
1683     }
1684 #endif
1685 }
1686 
1687 static struct audio_option audio_options[] = {
1688     /* DAC */
1689     {
1690         .name  = "DAC_FIXED_SETTINGS",
1691         .tag   = AUD_OPT_BOOL,
1692         .valp  = &conf.fixed_out.enabled,
1693         .descr = "Use fixed settings for host DAC"
1694     },
1695     {
1696         .name  = "DAC_FIXED_FREQ",
1697         .tag   = AUD_OPT_INT,
1698         .valp  = &conf.fixed_out.settings.freq,
1699         .descr = "Frequency for fixed host DAC"
1700     },
1701     {
1702         .name  = "DAC_FIXED_FMT",
1703         .tag   = AUD_OPT_FMT,
1704         .valp  = &conf.fixed_out.settings.fmt,
1705         .descr = "Format for fixed host DAC"
1706     },
1707     {
1708         .name  = "DAC_FIXED_CHANNELS",
1709         .tag   = AUD_OPT_INT,
1710         .valp  = &conf.fixed_out.settings.nchannels,
1711         .descr = "Number of channels for fixed DAC (1 - mono, 2 - stereo)"
1712     },
1713     {
1714         .name  = "DAC_VOICES",
1715         .tag   = AUD_OPT_INT,
1716         .valp  = &conf.fixed_out.nb_voices,
1717         .descr = "Number of voices for DAC"
1718     },
1719     {
1720         .name  = "DAC_TRY_POLL",
1721         .tag   = AUD_OPT_BOOL,
1722         .valp  = &conf.try_poll_out,
1723         .descr = "Attempt using poll mode for DAC"
1724     },
1725     /* ADC */
1726     {
1727         .name  = "ADC_FIXED_SETTINGS",
1728         .tag   = AUD_OPT_BOOL,
1729         .valp  = &conf.fixed_in.enabled,
1730         .descr = "Use fixed settings for host ADC"
1731     },
1732     {
1733         .name  = "ADC_FIXED_FREQ",
1734         .tag   = AUD_OPT_INT,
1735         .valp  = &conf.fixed_in.settings.freq,
1736         .descr = "Frequency for fixed host ADC"
1737     },
1738     {
1739         .name  = "ADC_FIXED_FMT",
1740         .tag   = AUD_OPT_FMT,
1741         .valp  = &conf.fixed_in.settings.fmt,
1742         .descr = "Format for fixed host ADC"
1743     },
1744     {
1745         .name  = "ADC_FIXED_CHANNELS",
1746         .tag   = AUD_OPT_INT,
1747         .valp  = &conf.fixed_in.settings.nchannels,
1748         .descr = "Number of channels for fixed ADC (1 - mono, 2 - stereo)"
1749     },
1750     {
1751         .name  = "ADC_VOICES",
1752         .tag   = AUD_OPT_INT,
1753         .valp  = &conf.fixed_in.nb_voices,
1754         .descr = "Number of voices for ADC"
1755     },
1756     {
1757         .name  = "ADC_TRY_POLL",
1758         .tag   = AUD_OPT_BOOL,
1759         .valp  = &conf.try_poll_in,
1760         .descr = "Attempt using poll mode for ADC"
1761     },
1762     /* Misc */
1763     {
1764         .name  = "TIMER_PERIOD",
1765         .tag   = AUD_OPT_INT,
1766         .valp  = &conf.period.hertz,
1767         .descr = "Timer period in HZ (0 - use lowest possible)"
1768     },
1769     {
1770         .name  = "PLIVE",
1771         .tag   = AUD_OPT_BOOL,
1772         .valp  = &conf.plive,
1773         .descr = "(undocumented)"
1774     },
1775     {
1776         .name  = "LOG_TO_MONITOR",
1777         .tag   = AUD_OPT_BOOL,
1778         .valp  = &conf.log_to_monitor,
1779         .descr = "Print logging messages to monitor instead of stderr"
1780     },
1781     { /* End of list */ }
1782 };
1783 
audio_pp_nb_voices(const char * typ,int nb)1784 static void audio_pp_nb_voices (const char *typ, int nb)
1785 {
1786     switch (nb) {
1787     case 0:
1788         printf ("Does not support %s\n", typ);
1789         break;
1790     case 1:
1791         printf ("One %s voice\n", typ);
1792         break;
1793     case INT_MAX:
1794         printf ("Theoretically supports many %s voices\n", typ);
1795         break;
1796     default:
1797         printf ("Theoretically supports upto %d %s voices\n", nb, typ);
1798         break;
1799     }
1800 
1801 }
1802 
AUD_help(void)1803 void AUD_help (void)
1804 {
1805     size_t i;
1806 
1807     audio_process_options ("AUDIO", audio_options);
1808     for (i = 0; i < ARRAY_SIZE (drvtab); i++) {
1809         struct audio_driver *d = drvtab[i];
1810         if (d->options) {
1811             audio_process_options (d->name, d->options);
1812         }
1813     }
1814 
1815     printf ("Audio options:\n");
1816     audio_print_options ("AUDIO", audio_options);
1817     printf ("\n");
1818 
1819     printf ("Available drivers:\n");
1820 
1821     for (i = 0; i < ARRAY_SIZE (drvtab); i++) {
1822         struct audio_driver *d = drvtab[i];
1823 
1824         printf ("Name: %s\n", d->name);
1825         printf ("Description: %s\n", d->descr);
1826 
1827         audio_pp_nb_voices ("playback", d->max_voices_out);
1828         audio_pp_nb_voices ("capture", d->max_voices_in);
1829 
1830         if (d->options) {
1831             printf ("Options:\n");
1832             audio_print_options (d->name, d->options);
1833         }
1834         else {
1835             printf ("No options\n");
1836         }
1837         printf ("\n");
1838     }
1839 
1840     printf (
1841         "Options are settable through environment variables.\n"
1842         "Example:\n"
1843 #ifdef _WIN32
1844         "  set QEMU_AUDIO_DRV=wav\n"
1845         "  set QEMU_WAV_PATH=c:\\tune.wav\n"
1846 #else
1847         "  export QEMU_AUDIO_DRV=wav\n"
1848         "  export QEMU_WAV_PATH=$HOME/tune.wav\n"
1849         "(for csh replace export with setenv in the above)\n"
1850 #endif
1851         "  qemu ...\n\n"
1852         );
1853 }
1854 
audio_driver_init(AudioState * s,struct audio_driver * drv)1855 static int audio_driver_init (AudioState *s, struct audio_driver *drv)
1856 {
1857     if (drv->options) {
1858         audio_process_options (drv->name, drv->options);
1859     }
1860     s->drv_opaque = drv->init ();
1861 
1862     if (s->drv_opaque) {
1863         audio_init_nb_voices_out (drv);
1864         audio_init_nb_voices_in (drv);
1865         s->drv = drv;
1866         return 0;
1867     }
1868     else {
1869         dolog ("Could not init `%s' audio driver\n", drv->name);
1870         return -1;
1871     }
1872 }
1873 
audio_vm_change_state_handler(void * opaque,int running,int reason)1874 static void audio_vm_change_state_handler (void *opaque, int running,
1875                                            int reason)
1876 {
1877     AudioState *s = opaque;
1878     HWVoiceOut *hwo = NULL;
1879     HWVoiceIn *hwi = NULL;
1880     int op = running ? VOICE_ENABLE : VOICE_DISABLE;
1881 
1882     s->vm_running = running;
1883     while ((hwo = audio_pcm_hw_find_any_enabled_out (hwo))) {
1884         hwo->pcm_ops->ctl_out (hwo, op, conf.try_poll_out);
1885     }
1886 
1887     while ((hwi = audio_pcm_hw_find_any_enabled_in (hwi))) {
1888         hwi->pcm_ops->ctl_in (hwi, op, conf.try_poll_in);
1889     }
1890     audio_reset_timer ();
1891 }
1892 
1893 static int initialized;
1894 
audio_atexit(void)1895 static void audio_atexit (void)
1896 {
1897     AudioState *s = &glob_audio_state;
1898     HWVoiceOut *hwo = NULL;
1899     HWVoiceIn *hwi = NULL;
1900 
1901     if (!initialized) return;
1902     initialized = 0;
1903 
1904     while ((hwo = audio_pcm_hw_find_any_enabled_out (hwo))) {
1905         SWVoiceCap *sc;
1906 
1907         hwo->pcm_ops->ctl_out (hwo, VOICE_DISABLE);
1908         hwo->pcm_ops->fini_out (hwo);
1909 
1910         for (sc = hwo->cap_head.lh_first; sc; sc = sc->entries.le_next) {
1911             CaptureVoiceOut *cap = sc->cap;
1912             struct capture_callback *cb;
1913 
1914             for (cb = cap->cb_head.lh_first; cb; cb = cb->entries.le_next) {
1915                 cb->ops.destroy (cb->opaque);
1916             }
1917         }
1918     }
1919 
1920     while ((hwi = audio_pcm_hw_find_any_enabled_in (hwi))) {
1921         hwi->pcm_ops->ctl_in (hwi, VOICE_DISABLE);
1922         hwi->pcm_ops->fini_in (hwi);
1923     }
1924 
1925     if (s->drv) {
1926         s->drv->fini (s->drv_opaque);
1927     }
1928 }
1929 
audio_save(QEMUFile * f,void * opaque)1930 static void audio_save (QEMUFile *f, void *opaque)
1931 {
1932     (void) f;
1933     (void) opaque;
1934 }
1935 
audio_load(QEMUFile * f,void * opaque,int version_id)1936 static int audio_load (QEMUFile *f, void *opaque, int version_id)
1937 {
1938     (void) f;
1939     (void) opaque;
1940 
1941     if (version_id != 1) {
1942         return -EINVAL;
1943     }
1944 
1945     return 0;
1946 }
1947 
1948 
1949 
audio_init(void)1950 static void audio_init (void)
1951 {
1952     size_t i;
1953     int done = 0;
1954     const char *drvname;
1955     VMChangeStateEntry *e;
1956     AudioState *s = &glob_audio_state;
1957 
1958     if (s->drv) {
1959         return;
1960     }
1961 
1962     QLIST_INIT (&s->hw_head_out);
1963     QLIST_INIT (&s->hw_head_in);
1964     QLIST_INIT (&s->cap_head);
1965     atexit (audio_atexit);
1966 
1967     s->ts = qemu_new_timer_ns (vm_clock, audio_timer, s);
1968     if (!s->ts) {
1969         dolog ("Could not create audio timer\n");
1970         return;
1971     }
1972 
1973     audio_process_options ("AUDIO", audio_options);
1974 
1975     s->nb_hw_voices_out = conf.fixed_out.nb_voices;
1976     s->nb_hw_voices_in = conf.fixed_in.nb_voices;
1977 
1978     if (s->nb_hw_voices_out <= 0) {
1979         dolog ("Bogus number of playback voices %d, setting to 1\n",
1980                s->nb_hw_voices_out);
1981         s->nb_hw_voices_out = 1;
1982     }
1983 
1984     if (s->nb_hw_voices_in <= 0) {
1985         dolog ("Bogus number of capture voices %d, setting to 0\n",
1986                s->nb_hw_voices_in);
1987         s->nb_hw_voices_in = 0;
1988     }
1989 
1990     {
1991         int def;
1992         drvname = audio_get_conf_str ("QEMU_AUDIO_DRV", NULL, &def);
1993     }
1994 
1995     if (drvname) {
1996         int found = 0;
1997 
1998         for (i = 0; i < ARRAY_SIZE (drvtab); i++) {
1999             if (!strcmp (drvname, drvtab[i]->name)) {
2000                 done = !audio_driver_init (s, drvtab[i]);
2001                 found = 1;
2002                 break;
2003             }
2004         }
2005 
2006         if (!found) {
2007             dolog ("Unknown audio driver `%s'\n", drvname);
2008             dolog ("Run with -audio-help to list available drivers\n");
2009         }
2010     }
2011 
2012     if (!done) {
2013         for (i = 0; !done && i < ARRAY_SIZE (drvtab); i++) {
2014             if (drvtab[i]->can_be_default) {
2015                 done = !audio_driver_init (s, drvtab[i]);
2016             }
2017         }
2018     }
2019 
2020     if (!done) {
2021         done = !audio_driver_init (s, &no_audio_driver);
2022         if (!done) {
2023             hw_error("Could not initialize audio subsystem\n");
2024         }
2025         else {
2026             dolog ("warning: Using timer based audio emulation\n");
2027         }
2028     }
2029 
2030     if (conf.period.hertz <= 0) {
2031         if (conf.period.hertz < 0) {
2032             dolog ("warning: Timer period is negative - %d "
2033                    "treating as zero\n",
2034                    conf.period.hertz);
2035         }
2036         conf.period.ticks = 1;
2037     } else {
2038         conf.period.ticks =
2039             muldiv64 (1, get_ticks_per_sec (), conf.period.hertz);
2040     }
2041 
2042     e = qemu_add_vm_change_state_handler (audio_vm_change_state_handler, s);
2043     if (!e) {
2044         dolog ("warning: Could not register change state handler\n"
2045                "(Audio can continue looping even after stopping the VM)\n");
2046     }
2047     initialized = 1;
2048 
2049     QLIST_INIT (&s->card_head);
2050     register_savevm ("audio", 0, 1, audio_save, audio_load, s);
2051     audio_reset_timer();
2052 }
2053 
AUD_register_card(const char * name,QEMUSoundCard * card)2054 void AUD_register_card (const char *name, QEMUSoundCard *card)
2055 {
2056     audio_init ();
2057     card->name = qemu_strdup (name);
2058     memset (&card->entries, 0, sizeof (card->entries));
2059     QLIST_INSERT_HEAD (&glob_audio_state.card_head, card, entries);
2060 }
2061 
AUD_remove_card(QEMUSoundCard * card)2062 void AUD_remove_card (QEMUSoundCard *card)
2063 {
2064     QLIST_REMOVE (card, entries);
2065     qemu_free (card->name);
2066 }
2067 
2068 
AUD_add_capture(struct audsettings * as,struct audio_capture_ops * ops,void * cb_opaque)2069 CaptureVoiceOut *AUD_add_capture (
2070     struct audsettings *as,
2071     struct audio_capture_ops *ops,
2072     void *cb_opaque
2073     )
2074 {
2075     AudioState *s = &glob_audio_state;
2076     CaptureVoiceOut *cap;
2077     struct capture_callback *cb;
2078 
2079     if (audio_validate_settings (as)) {
2080         dolog ("Invalid settings were passed when trying to add capture\n");
2081         audio_print_settings (as);
2082         goto err0;
2083     }
2084 
2085     cb = audio_calloc (AUDIO_FUNC, 1, sizeof (*cb));
2086     if (!cb) {
2087         dolog ("Could not allocate capture callback information, size %zu\n",
2088                sizeof (*cb));
2089         goto err0;
2090     }
2091     cb->ops = *ops;
2092     cb->opaque = cb_opaque;
2093 
2094     cap = audio_pcm_capture_find_specific (as);
2095     if (cap) {
2096         QLIST_INSERT_HEAD (&cap->cb_head, cb, entries);
2097         return cap;
2098     }
2099     else {
2100         HWVoiceOut *hw;
2101         CaptureVoiceOut *cap;
2102 
2103         cap = audio_calloc (AUDIO_FUNC, 1, sizeof (*cap));
2104         if (!cap) {
2105             dolog ("Could not allocate capture voice, size %zu\n",
2106                    sizeof (*cap));
2107             goto err1;
2108         }
2109 
2110         hw = &cap->hw;
2111         QLIST_INIT (&hw->sw_head);
2112         QLIST_INIT (&cap->cb_head);
2113 
2114         /* XXX find a more elegant way */
2115         hw->samples = 4096 * 4;
2116         hw->mix_buf = audio_calloc (AUDIO_FUNC, hw->samples,
2117                                     sizeof (struct st_sample));
2118         if (!hw->mix_buf) {
2119             dolog ("Could not allocate capture mix buffer (%d samples)\n",
2120                    hw->samples);
2121             goto err2;
2122         }
2123 
2124         audio_pcm_init_info (&hw->info, as);
2125 
2126         cap->buf = audio_calloc (AUDIO_FUNC, hw->samples, 1 << hw->info.shift);
2127         if (!cap->buf) {
2128             dolog ("Could not allocate capture buffer "
2129                    "(%d samples, each %d bytes)\n",
2130                    hw->samples, 1 << hw->info.shift);
2131             goto err3;
2132         }
2133 
2134         hw->clip = mixeng_clip
2135             [hw->info.nchannels == 2]
2136             [hw->info.sign]
2137             [hw->info.swap_endianness]
2138             [audio_bits_to_index (hw->info.bits)];
2139 
2140         QLIST_INSERT_HEAD (&s->cap_head, cap, entries);
2141         QLIST_INSERT_HEAD (&cap->cb_head, cb, entries);
2142 
2143         hw = NULL;
2144         while ((hw = audio_pcm_hw_find_any_out (hw))) {
2145             audio_attach_capture (hw);
2146         }
2147         return cap;
2148 
2149     err3:
2150         qemu_free (cap->hw.mix_buf);
2151     err2:
2152         qemu_free (cap);
2153     err1:
2154         qemu_free (cb);
2155     err0:
2156         return NULL;
2157     }
2158 }
2159 
AUD_del_capture(CaptureVoiceOut * cap,void * cb_opaque)2160 void AUD_del_capture (CaptureVoiceOut *cap, void *cb_opaque)
2161 {
2162     struct capture_callback *cb;
2163 
2164     for (cb = cap->cb_head.lh_first; cb; cb = cb->entries.le_next) {
2165         if (cb->opaque == cb_opaque) {
2166             cb->ops.destroy (cb_opaque);
2167             QLIST_REMOVE (cb, entries);
2168             qemu_free (cb);
2169 
2170             if (!cap->cb_head.lh_first) {
2171                 SWVoiceOut *sw = cap->hw.sw_head.lh_first, *sw1;
2172 
2173                 while (sw) {
2174                     SWVoiceCap *sc = (SWVoiceCap *) sw;
2175 #ifdef DEBUG_CAPTURE
2176                     dolog ("freeing %s\n", sw->name);
2177 #endif
2178 
2179                     sw1 = sw->entries.le_next;
2180                     if (sw->rate) {
2181                         st_rate_stop (sw->rate);
2182                         sw->rate = NULL;
2183                     }
2184                     QLIST_REMOVE (sw, entries);
2185                     QLIST_REMOVE (sc, entries);
2186                     qemu_free (sc);
2187                     sw = sw1;
2188                 }
2189                 QLIST_REMOVE (cap, entries);
2190                 qemu_free (cap);
2191             }
2192             return;
2193         }
2194     }
2195 }
2196 
AUD_set_volume_out(SWVoiceOut * sw,int mute,uint8_t lvol,uint8_t rvol)2197 void AUD_set_volume_out (SWVoiceOut *sw, int mute, uint8_t lvol, uint8_t rvol)
2198 {
2199     if (sw) {
2200         sw->vol.mute = mute;
2201         sw->vol.l = nominal_volume.l * lvol / 255;
2202         sw->vol.r = nominal_volume.r * rvol / 255;
2203     }
2204 }
2205 
AUD_set_volume_in(SWVoiceIn * sw,int mute,uint8_t lvol,uint8_t rvol)2206 void AUD_set_volume_in (SWVoiceIn *sw, int mute, uint8_t lvol, uint8_t rvol)
2207 {
2208     if (sw) {
2209         sw->vol.mute = mute;
2210         sw->vol.l = nominal_volume.l * lvol / 255;
2211         sw->vol.r = nominal_volume.r * rvol / 255;
2212     }
2213 }
2214