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

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

unix.superglobalmegacorp.com

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