Annotation of qemu/audio/audio.c, revision 1.1.1.13

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.