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

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

unix.superglobalmegacorp.com

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