Annotation of qemu/audio/audio_template.h, revision 1.1.1.4

1.1       root        1: /*
                      2:  * QEMU Audio subsystem header
                      3:  *
                      4:  * Copyright (c) 2005 Vassili Karpov (malc)
                      5:  *
                      6:  * Permission is hereby granted, free of charge, to any person obtaining a copy
                      7:  * of this software and associated documentation files (the "Software"), to deal
                      8:  * in the Software without restriction, including without limitation the rights
                      9:  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
                     10:  * copies of the Software, and to permit persons to whom the Software is
                     11:  * furnished to do so, subject to the following conditions:
                     12:  *
                     13:  * The above copyright notice and this permission notice shall be included in
                     14:  * all copies or substantial portions of the Software.
                     15:  *
                     16:  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
                     17:  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
                     18:  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
                     19:  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
                     20:  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
                     21:  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
                     22:  * THE SOFTWARE.
                     23:  */
                     24: 
                     25: #ifdef DAC
                     26: #define NAME "playback"
                     27: #define HWBUF hw->mix_buf
                     28: #define TYPE out
                     29: #define HW HWVoiceOut
                     30: #define SW SWVoiceOut
                     31: #else
                     32: #define NAME "capture"
                     33: #define TYPE in
                     34: #define HW HWVoiceIn
                     35: #define SW SWVoiceIn
                     36: #define HWBUF hw->conv_buf
                     37: #endif
                     38: 
                     39: static void glue (audio_init_nb_voices_, TYPE) (
                     40:     AudioState *s,
                     41:     struct audio_driver *drv
                     42:     )
                     43: {
                     44:     int max_voices = glue (drv->max_voices_, TYPE);
                     45:     int voice_size = glue (drv->voice_size_, TYPE);
                     46: 
                     47:     if (glue (s->nb_hw_voices_, TYPE) > max_voices) {
                     48:         if (!max_voices) {
                     49: #ifdef DAC
                     50:             dolog ("Driver `%s' does not support " NAME "\n", drv->name);
                     51: #endif
                     52:         }
                     53:         else {
                     54:             dolog ("Driver `%s' does not support %d " NAME " voices, max %d\n",
                     55:                    drv->name,
                     56:                    glue (s->nb_hw_voices_, TYPE),
                     57:                    max_voices);
                     58:         }
                     59:         glue (s->nb_hw_voices_, TYPE) = max_voices;
                     60:     }
                     61: 
                     62:     if (audio_bug (AUDIO_FUNC, !voice_size && max_voices)) {
                     63:         dolog ("drv=`%s' voice_size=0 max_voices=%d\n",
                     64:                drv->name, max_voices);
                     65:         glue (s->nb_hw_voices_, TYPE) = 0;
                     66:     }
                     67: 
                     68:     if (audio_bug (AUDIO_FUNC, voice_size && !max_voices)) {
                     69:         dolog ("drv=`%s' voice_size=%d max_voices=0\n",
                     70:                drv->name, voice_size);
                     71:     }
                     72: }
                     73: 
                     74: static void glue (audio_pcm_hw_free_resources_, TYPE) (HW *hw)
                     75: {
                     76:     if (HWBUF) {
                     77:         qemu_free (HWBUF);
                     78:     }
                     79: 
                     80:     HWBUF = NULL;
                     81: }
                     82: 
                     83: static int glue (audio_pcm_hw_alloc_resources_, TYPE) (HW *hw)
                     84: {
1.1.1.4 ! root       85:     HWBUF = audio_calloc (AUDIO_FUNC, hw->samples, sizeof (struct st_sample));
1.1       root       86:     if (!HWBUF) {
                     87:         dolog ("Could not allocate " NAME " buffer (%d samples)\n",
                     88:                hw->samples);
                     89:         return -1;
                     90:     }
                     91: 
                     92:     return 0;
                     93: }
                     94: 
                     95: static void glue (audio_pcm_sw_free_resources_, TYPE) (SW *sw)
                     96: {
                     97:     if (sw->buf) {
                     98:         qemu_free (sw->buf);
                     99:     }
                    100: 
                    101:     if (sw->rate) {
                    102:         st_rate_stop (sw->rate);
                    103:     }
                    104: 
                    105:     sw->buf = NULL;
                    106:     sw->rate = NULL;
                    107: }
                    108: 
                    109: static int glue (audio_pcm_sw_alloc_resources_, TYPE) (SW *sw)
                    110: {
                    111:     int samples;
                    112: 
                    113: #ifdef DAC
                    114:     samples = sw->hw->samples;
                    115: #else
                    116:     samples = ((int64_t) sw->hw->samples << 32) / sw->ratio;
                    117: #endif
                    118: 
1.1.1.4 ! root      119:     sw->buf = audio_calloc (AUDIO_FUNC, samples, sizeof (struct st_sample));
1.1       root      120:     if (!sw->buf) {
                    121:         dolog ("Could not allocate buffer for `%s' (%d samples)\n",
                    122:                SW_NAME (sw), samples);
                    123:         return -1;
                    124:     }
                    125: 
                    126: #ifdef DAC
                    127:     sw->rate = st_rate_start (sw->info.freq, sw->hw->info.freq);
                    128: #else
                    129:     sw->rate = st_rate_start (sw->hw->info.freq, sw->info.freq);
                    130: #endif
                    131:     if (!sw->rate) {
                    132:         qemu_free (sw->buf);
                    133:         sw->buf = NULL;
                    134:         return -1;
                    135:     }
                    136:     return 0;
                    137: }
                    138: 
                    139: static int glue (audio_pcm_sw_init_, TYPE) (
                    140:     SW *sw,
                    141:     HW *hw,
                    142:     const char *name,
1.1.1.4 ! root      143:     struct audsettings *as
1.1       root      144:     )
                    145: {
                    146:     int err;
                    147: 
1.1.1.2   root      148:     audio_pcm_init_info (&sw->info, as);
1.1       root      149:     sw->hw = hw;
                    150:     sw->active = 0;
                    151: #ifdef DAC
                    152:     sw->ratio = ((int64_t) sw->hw->info.freq << 32) / sw->info.freq;
                    153:     sw->total_hw_samples_mixed = 0;
                    154:     sw->empty = 1;
                    155: #else
                    156:     sw->ratio = ((int64_t) sw->info.freq << 32) / sw->hw->info.freq;
                    157: #endif
                    158: 
                    159: #ifdef DAC
                    160:     sw->conv = mixeng_conv
                    161: #else
                    162:     sw->clip = mixeng_clip
                    163: #endif
                    164:         [sw->info.nchannels == 2]
                    165:         [sw->info.sign]
1.1.1.2   root      166:         [sw->info.swap_endianness]
1.1.1.3   root      167:         [audio_bits_to_index (sw->info.bits)];
1.1       root      168: 
                    169:     sw->name = qemu_strdup (name);
                    170:     err = glue (audio_pcm_sw_alloc_resources_, TYPE) (sw);
                    171:     if (err) {
                    172:         qemu_free (sw->name);
                    173:         sw->name = NULL;
                    174:     }
                    175:     return err;
                    176: }
                    177: 
                    178: static void glue (audio_pcm_sw_fini_, TYPE) (SW *sw)
                    179: {
                    180:     glue (audio_pcm_sw_free_resources_, TYPE) (sw);
                    181:     if (sw->name) {
                    182:         qemu_free (sw->name);
                    183:         sw->name = NULL;
                    184:     }
                    185: }
                    186: 
                    187: static void glue (audio_pcm_hw_add_sw_, TYPE) (HW *hw, SW *sw)
                    188: {
                    189:     LIST_INSERT_HEAD (&hw->sw_head, sw, entries);
                    190: }
                    191: 
                    192: static void glue (audio_pcm_hw_del_sw_, TYPE) (SW *sw)
                    193: {
                    194:     LIST_REMOVE (sw, entries);
                    195: }
                    196: 
                    197: static void glue (audio_pcm_hw_gc_, TYPE) (AudioState *s, HW **hwp)
                    198: {
                    199:     HW *hw = *hwp;
                    200: 
                    201:     if (!hw->sw_head.lh_first) {
1.1.1.2   root      202: #ifdef DAC
                    203:         audio_detach_capture (hw);
                    204: #endif
1.1       root      205:         LIST_REMOVE (hw, entries);
                    206:         glue (s->nb_hw_voices_, TYPE) += 1;
                    207:         glue (audio_pcm_hw_free_resources_ ,TYPE) (hw);
                    208:         glue (hw->pcm_ops->fini_, TYPE) (hw);
                    209:         qemu_free (hw);
                    210:         *hwp = NULL;
                    211:     }
                    212: }
                    213: 
                    214: static HW *glue (audio_pcm_hw_find_any_, TYPE) (AudioState *s, HW *hw)
                    215: {
                    216:     return hw ? hw->entries.le_next : s->glue (hw_head_, TYPE).lh_first;
                    217: }
                    218: 
                    219: static HW *glue (audio_pcm_hw_find_any_enabled_, TYPE) (AudioState *s, HW *hw)
                    220: {
                    221:     while ((hw = glue (audio_pcm_hw_find_any_, TYPE) (s, hw))) {
                    222:         if (hw->enabled) {
                    223:             return hw;
                    224:         }
                    225:     }
                    226:     return NULL;
                    227: }
                    228: 
                    229: static HW *glue (audio_pcm_hw_find_specific_, TYPE) (
                    230:     AudioState *s,
                    231:     HW *hw,
1.1.1.4 ! root      232:     struct audsettings *as
1.1       root      233:     )
                    234: {
                    235:     while ((hw = glue (audio_pcm_hw_find_any_, TYPE) (s, hw))) {
                    236:         if (audio_pcm_info_eq (&hw->info, as)) {
                    237:             return hw;
                    238:         }
                    239:     }
                    240:     return NULL;
                    241: }
                    242: 
1.1.1.4 ! root      243: static HW *glue (audio_pcm_hw_add_new_, TYPE) (AudioState *s,
        !           244:                                                struct audsettings *as)
1.1       root      245: {
                    246:     HW *hw;
                    247:     struct audio_driver *drv = s->drv;
                    248: 
                    249:     if (!glue (s->nb_hw_voices_, TYPE)) {
                    250:         return NULL;
                    251:     }
                    252: 
                    253:     if (audio_bug (AUDIO_FUNC, !drv)) {
                    254:         dolog ("No host audio driver\n");
                    255:         return NULL;
                    256:     }
                    257: 
                    258:     if (audio_bug (AUDIO_FUNC, !drv->pcm_ops)) {
                    259:         dolog ("Host audio driver without pcm_ops\n");
                    260:         return NULL;
                    261:     }
                    262: 
                    263:     hw = audio_calloc (AUDIO_FUNC, 1, glue (drv->voice_size_, TYPE));
                    264:     if (!hw) {
                    265:         dolog ("Can not allocate voice `%s' size %d\n",
                    266:                drv->name, glue (drv->voice_size_, TYPE));
                    267:         return NULL;
                    268:     }
                    269: 
                    270:     hw->pcm_ops = drv->pcm_ops;
                    271:     LIST_INIT (&hw->sw_head);
1.1.1.2   root      272: #ifdef DAC
                    273:     LIST_INIT (&hw->cap_head);
                    274: #endif
1.1       root      275:     if (glue (hw->pcm_ops->init_, TYPE) (hw, as)) {
                    276:         goto err0;
                    277:     }
                    278: 
                    279:     if (audio_bug (AUDIO_FUNC, hw->samples <= 0)) {
                    280:         dolog ("hw->samples=%d\n", hw->samples);
                    281:         goto err1;
                    282:     }
                    283: 
                    284: #ifdef DAC
                    285:     hw->clip = mixeng_clip
                    286: #else
                    287:     hw->conv = mixeng_conv
                    288: #endif
                    289:         [hw->info.nchannels == 2]
                    290:         [hw->info.sign]
1.1.1.2   root      291:         [hw->info.swap_endianness]
1.1.1.3   root      292:         [audio_bits_to_index (hw->info.bits)];
1.1       root      293: 
                    294:     if (glue (audio_pcm_hw_alloc_resources_, TYPE) (hw)) {
                    295:         goto err1;
                    296:     }
                    297: 
                    298:     LIST_INSERT_HEAD (&s->glue (hw_head_, TYPE), hw, entries);
                    299:     glue (s->nb_hw_voices_, TYPE) -= 1;
1.1.1.2   root      300: #ifdef DAC
                    301:     audio_attach_capture (s, hw);
                    302: #endif
1.1       root      303:     return hw;
                    304: 
                    305:  err1:
                    306:     glue (hw->pcm_ops->fini_, TYPE) (hw);
                    307:  err0:
                    308:     qemu_free (hw);
                    309:     return NULL;
                    310: }
                    311: 
1.1.1.4 ! root      312: static HW *glue (audio_pcm_hw_add_, TYPE) (AudioState *s,
        !           313:                                            struct audsettings *as)
1.1       root      314: {
                    315:     HW *hw;
                    316: 
                    317:     if (glue (conf.fixed_, TYPE).enabled && glue (conf.fixed_, TYPE).greedy) {
                    318:         hw = glue (audio_pcm_hw_add_new_, TYPE) (s, as);
                    319:         if (hw) {
                    320:             return hw;
                    321:         }
                    322:     }
                    323: 
                    324:     hw = glue (audio_pcm_hw_find_specific_, TYPE) (s, NULL, as);
                    325:     if (hw) {
                    326:         return hw;
                    327:     }
                    328: 
                    329:     hw = glue (audio_pcm_hw_add_new_, TYPE) (s, as);
                    330:     if (hw) {
                    331:         return hw;
                    332:     }
                    333: 
                    334:     return glue (audio_pcm_hw_find_any_, TYPE) (s, NULL);
                    335: }
                    336: 
                    337: static SW *glue (audio_pcm_create_voice_pair_, TYPE) (
                    338:     AudioState *s,
                    339:     const char *sw_name,
1.1.1.4 ! root      340:     struct audsettings *as
1.1       root      341:     )
                    342: {
                    343:     SW *sw;
                    344:     HW *hw;
1.1.1.4 ! root      345:     struct audsettings hw_as;
1.1       root      346: 
                    347:     if (glue (conf.fixed_, TYPE).enabled) {
                    348:         hw_as = glue (conf.fixed_, TYPE).settings;
                    349:     }
                    350:     else {
                    351:         hw_as = *as;
                    352:     }
                    353: 
                    354:     sw = audio_calloc (AUDIO_FUNC, 1, sizeof (*sw));
                    355:     if (!sw) {
                    356:         dolog ("Could not allocate soft voice `%s' (%zu bytes)\n",
                    357:                sw_name ? sw_name : "unknown", sizeof (*sw));
                    358:         goto err1;
                    359:     }
                    360: 
                    361:     hw = glue (audio_pcm_hw_add_, TYPE) (s, &hw_as);
                    362:     if (!hw) {
                    363:         goto err2;
                    364:     }
                    365: 
                    366:     glue (audio_pcm_hw_add_sw_, TYPE) (hw, sw);
                    367: 
1.1.1.2   root      368:     if (glue (audio_pcm_sw_init_, TYPE) (sw, hw, sw_name, as)) {
1.1       root      369:         goto err3;
                    370:     }
                    371: 
                    372:     return sw;
                    373: 
                    374: err3:
                    375:     glue (audio_pcm_hw_del_sw_, TYPE) (sw);
                    376:     glue (audio_pcm_hw_gc_, TYPE) (s, &hw);
                    377: err2:
                    378:     qemu_free (sw);
                    379: err1:
                    380:     return NULL;
                    381: }
                    382: 
                    383: static void glue (audio_close_, TYPE) (AudioState *s, SW *sw)
                    384: {
                    385:     glue (audio_pcm_sw_fini_, TYPE) (sw);
                    386:     glue (audio_pcm_hw_del_sw_, TYPE) (sw);
                    387:     glue (audio_pcm_hw_gc_, TYPE) (s, &sw->hw);
                    388:     qemu_free (sw);
                    389: }
                    390: 
                    391: void glue (AUD_close_, TYPE) (QEMUSoundCard *card, SW *sw)
                    392: {
                    393:     if (sw) {
                    394:         if (audio_bug (AUDIO_FUNC, !card || !card->audio)) {
                    395:             dolog ("card=%p card->audio=%p\n",
                    396:                    card, card ? card->audio : NULL);
                    397:             return;
                    398:         }
                    399: 
                    400:         glue (audio_close_, TYPE) (card->audio, sw);
                    401:     }
                    402: }
                    403: 
                    404: SW *glue (AUD_open_, TYPE) (
                    405:     QEMUSoundCard *card,
                    406:     SW *sw,
                    407:     const char *name,
                    408:     void *callback_opaque ,
                    409:     audio_callback_fn_t callback_fn,
1.1.1.4 ! root      410:     struct audsettings *as
1.1       root      411:     )
                    412: {
                    413:     AudioState *s;
                    414: #ifdef DAC
                    415:     int live = 0;
                    416:     SW *old_sw = NULL;
                    417: #endif
                    418: 
                    419:     ldebug ("open %s, freq %d, nchannels %d, fmt %d\n",
                    420:             name, as->freq, as->nchannels, as->fmt);
                    421: 
                    422:     if (audio_bug (AUDIO_FUNC,
                    423:                    !card || !card->audio || !name || !callback_fn || !as)) {
                    424:         dolog ("card=%p card->audio=%p name=%p callback_fn=%p as=%p\n",
                    425:                card, card ? card->audio : NULL, name, callback_fn, as);
                    426:         goto fail;
                    427:     }
                    428: 
                    429:     s = card->audio;
                    430: 
1.1.1.2   root      431:     if (audio_bug (AUDIO_FUNC, audio_validate_settings (as))) {
1.1       root      432:         audio_print_settings (as);
                    433:         goto fail;
                    434:     }
                    435: 
                    436:     if (audio_bug (AUDIO_FUNC, !s->drv)) {
                    437:         dolog ("Can not open `%s' (no host audio driver)\n", name);
                    438:         goto fail;
                    439:     }
                    440: 
                    441:     if (sw && audio_pcm_info_eq (&sw->info, as)) {
                    442:         return sw;
                    443:     }
                    444: 
                    445: #ifdef DAC
                    446:     if (conf.plive && sw && (!sw->active && !sw->empty)) {
                    447:         live = sw->total_hw_samples_mixed;
                    448: 
                    449: #ifdef DEBUG_PLIVE
                    450:         dolog ("Replacing voice %s with %d live samples\n", SW_NAME (sw), live);
                    451:         dolog ("Old %s freq %d, bits %d, channels %d\n",
                    452:                SW_NAME (sw), sw->info.freq, sw->info.bits, sw->info.nchannels);
                    453:         dolog ("New %s freq %d, bits %d, channels %d\n",
                    454:                name,
                    455:                freq,
                    456:                (fmt == AUD_FMT_S16 || fmt == AUD_FMT_U16) ? 16 : 8,
                    457:                nchannels);
                    458: #endif
                    459: 
                    460:         if (live) {
                    461:             old_sw = sw;
                    462:             old_sw->callback.fn = NULL;
                    463:             sw = NULL;
                    464:         }
                    465:     }
                    466: #endif
                    467: 
                    468:     if (!glue (conf.fixed_, TYPE).enabled && sw) {
                    469:         glue (AUD_close_, TYPE) (card, sw);
                    470:         sw = NULL;
                    471:     }
                    472: 
                    473:     if (sw) {
                    474:         HW *hw = sw->hw;
                    475: 
                    476:         if (!hw) {
                    477:             dolog ("Internal logic error voice `%s' has no hardware store\n",
                    478:                    SW_NAME (sw));
                    479:             goto fail;
                    480:         }
                    481: 
                    482:         glue (audio_pcm_sw_fini_, TYPE) (sw);
1.1.1.2   root      483:         if (glue (audio_pcm_sw_init_, TYPE) (sw, hw, name, as)) {
1.1       root      484:             goto fail;
                    485:         }
                    486:     }
                    487:     else {
1.1.1.2   root      488:         sw = glue (audio_pcm_create_voice_pair_, TYPE) (s, name, as);
1.1       root      489:         if (!sw) {
                    490:             dolog ("Failed to create voice `%s'\n", name);
                    491:             return NULL;
                    492:         }
                    493:     }
                    494: 
                    495:     if (sw) {
                    496:         sw->vol = nominal_volume;
                    497:         sw->callback.fn = callback_fn;
                    498:         sw->callback.opaque = callback_opaque;
                    499: 
                    500: #ifdef DAC
                    501:         if (live) {
                    502:             int mixed =
                    503:                 (live << old_sw->info.shift)
                    504:                 * old_sw->info.bytes_per_second
                    505:                 / sw->info.bytes_per_second;
                    506: 
                    507: #ifdef DEBUG_PLIVE
                    508:             dolog ("Silence will be mixed %d\n", mixed);
                    509: #endif
                    510:             sw->total_hw_samples_mixed += mixed;
                    511:         }
                    512: #endif
                    513: 
                    514: #ifdef DEBUG_AUDIO
                    515:         dolog ("%s\n", name);
                    516:         audio_pcm_print_info ("hw", &sw->hw->info);
                    517:         audio_pcm_print_info ("sw", &sw->info);
                    518: #endif
                    519:     }
                    520: 
                    521:     return sw;
                    522: 
                    523:  fail:
                    524:     glue (AUD_close_, TYPE) (card, sw);
                    525:     return NULL;
                    526: }
                    527: 
                    528: int glue (AUD_is_active_, TYPE) (SW *sw)
                    529: {
                    530:     return sw ? sw->active : 0;
                    531: }
                    532: 
                    533: void glue (AUD_init_time_stamp_, TYPE) (SW *sw, QEMUAudioTimeStamp *ts)
                    534: {
                    535:     if (!sw) {
                    536:         return;
                    537:     }
                    538: 
                    539:     ts->old_ts = sw->hw->ts_helper;
                    540: }
                    541: 
                    542: uint64_t glue (AUD_get_elapsed_usec_, TYPE) (SW *sw, QEMUAudioTimeStamp *ts)
                    543: {
                    544:     uint64_t delta, cur_ts, old_ts;
                    545: 
                    546:     if (!sw) {
                    547:         return 0;
                    548:     }
                    549: 
                    550:     cur_ts = sw->hw->ts_helper;
                    551:     old_ts = ts->old_ts;
                    552:     /* dolog ("cur %lld old %lld\n", cur_ts, old_ts); */
                    553: 
                    554:     if (cur_ts >= old_ts) {
                    555:         delta = cur_ts - old_ts;
                    556:     }
                    557:     else {
                    558:         delta = UINT64_MAX - old_ts + cur_ts;
                    559:     }
                    560: 
                    561:     if (!delta) {
                    562:         return 0;
                    563:     }
                    564: 
                    565:     return (delta * sw->hw->info.freq) / 1000000;
                    566: }
                    567: 
                    568: #undef TYPE
                    569: #undef HW
                    570: #undef SW
                    571: #undef HWBUF
                    572: #undef NAME

unix.superglobalmegacorp.com

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