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

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: {
                     85:     HWBUF = audio_calloc (AUDIO_FUNC, hw->samples, sizeof (st_sample_t));
                     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: 
                    119:     sw->buf = audio_calloc (AUDIO_FUNC, samples, sizeof (st_sample_t));
                    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.2   root      143:     audsettings_t *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,
                    232:     audsettings_t *as
                    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: 
                    243: static HW *glue (audio_pcm_hw_add_new_, TYPE) (AudioState *s, audsettings_t *as)
                    244: {
                    245:     HW *hw;
                    246:     struct audio_driver *drv = s->drv;
                    247: 
                    248:     if (!glue (s->nb_hw_voices_, TYPE)) {
                    249:         return NULL;
                    250:     }
                    251: 
                    252:     if (audio_bug (AUDIO_FUNC, !drv)) {
                    253:         dolog ("No host audio driver\n");
                    254:         return NULL;
                    255:     }
                    256: 
                    257:     if (audio_bug (AUDIO_FUNC, !drv->pcm_ops)) {
                    258:         dolog ("Host audio driver without pcm_ops\n");
                    259:         return NULL;
                    260:     }
                    261: 
                    262:     hw = audio_calloc (AUDIO_FUNC, 1, glue (drv->voice_size_, TYPE));
                    263:     if (!hw) {
                    264:         dolog ("Can not allocate voice `%s' size %d\n",
                    265:                drv->name, glue (drv->voice_size_, TYPE));
                    266:         return NULL;
                    267:     }
                    268: 
                    269:     hw->pcm_ops = drv->pcm_ops;
                    270:     LIST_INIT (&hw->sw_head);
1.1.1.2   root      271: #ifdef DAC
                    272:     LIST_INIT (&hw->cap_head);
                    273: #endif
1.1       root      274:     if (glue (hw->pcm_ops->init_, TYPE) (hw, as)) {
                    275:         goto err0;
                    276:     }
                    277: 
                    278:     if (audio_bug (AUDIO_FUNC, hw->samples <= 0)) {
                    279:         dolog ("hw->samples=%d\n", hw->samples);
                    280:         goto err1;
                    281:     }
                    282: 
                    283: #ifdef DAC
                    284:     hw->clip = mixeng_clip
                    285: #else
                    286:     hw->conv = mixeng_conv
                    287: #endif
                    288:         [hw->info.nchannels == 2]
                    289:         [hw->info.sign]
1.1.1.2   root      290:         [hw->info.swap_endianness]
1.1.1.3 ! root      291:         [audio_bits_to_index (hw->info.bits)];
1.1       root      292: 
                    293:     if (glue (audio_pcm_hw_alloc_resources_, TYPE) (hw)) {
                    294:         goto err1;
                    295:     }
                    296: 
                    297:     LIST_INSERT_HEAD (&s->glue (hw_head_, TYPE), hw, entries);
                    298:     glue (s->nb_hw_voices_, TYPE) -= 1;
1.1.1.2   root      299: #ifdef DAC
                    300:     audio_attach_capture (s, hw);
                    301: #endif
1.1       root      302:     return hw;
                    303: 
                    304:  err1:
                    305:     glue (hw->pcm_ops->fini_, TYPE) (hw);
                    306:  err0:
                    307:     qemu_free (hw);
                    308:     return NULL;
                    309: }
                    310: 
                    311: static HW *glue (audio_pcm_hw_add_, TYPE) (AudioState *s, audsettings_t *as)
                    312: {
                    313:     HW *hw;
                    314: 
                    315:     if (glue (conf.fixed_, TYPE).enabled && glue (conf.fixed_, TYPE).greedy) {
                    316:         hw = glue (audio_pcm_hw_add_new_, TYPE) (s, as);
                    317:         if (hw) {
                    318:             return hw;
                    319:         }
                    320:     }
                    321: 
                    322:     hw = glue (audio_pcm_hw_find_specific_, TYPE) (s, NULL, as);
                    323:     if (hw) {
                    324:         return hw;
                    325:     }
                    326: 
                    327:     hw = glue (audio_pcm_hw_add_new_, TYPE) (s, as);
                    328:     if (hw) {
                    329:         return hw;
                    330:     }
                    331: 
                    332:     return glue (audio_pcm_hw_find_any_, TYPE) (s, NULL);
                    333: }
                    334: 
                    335: static SW *glue (audio_pcm_create_voice_pair_, TYPE) (
                    336:     AudioState *s,
                    337:     const char *sw_name,
1.1.1.2   root      338:     audsettings_t *as
1.1       root      339:     )
                    340: {
                    341:     SW *sw;
                    342:     HW *hw;
                    343:     audsettings_t hw_as;
                    344: 
                    345:     if (glue (conf.fixed_, TYPE).enabled) {
                    346:         hw_as = glue (conf.fixed_, TYPE).settings;
                    347:     }
                    348:     else {
                    349:         hw_as = *as;
                    350:     }
                    351: 
                    352:     sw = audio_calloc (AUDIO_FUNC, 1, sizeof (*sw));
                    353:     if (!sw) {
                    354:         dolog ("Could not allocate soft voice `%s' (%zu bytes)\n",
                    355:                sw_name ? sw_name : "unknown", sizeof (*sw));
                    356:         goto err1;
                    357:     }
                    358: 
                    359:     hw = glue (audio_pcm_hw_add_, TYPE) (s, &hw_as);
                    360:     if (!hw) {
                    361:         goto err2;
                    362:     }
                    363: 
                    364:     glue (audio_pcm_hw_add_sw_, TYPE) (hw, sw);
                    365: 
1.1.1.2   root      366:     if (glue (audio_pcm_sw_init_, TYPE) (sw, hw, sw_name, as)) {
1.1       root      367:         goto err3;
                    368:     }
                    369: 
                    370:     return sw;
                    371: 
                    372: err3:
                    373:     glue (audio_pcm_hw_del_sw_, TYPE) (sw);
                    374:     glue (audio_pcm_hw_gc_, TYPE) (s, &hw);
                    375: err2:
                    376:     qemu_free (sw);
                    377: err1:
                    378:     return NULL;
                    379: }
                    380: 
                    381: static void glue (audio_close_, TYPE) (AudioState *s, SW *sw)
                    382: {
                    383:     glue (audio_pcm_sw_fini_, TYPE) (sw);
                    384:     glue (audio_pcm_hw_del_sw_, TYPE) (sw);
                    385:     glue (audio_pcm_hw_gc_, TYPE) (s, &sw->hw);
                    386:     qemu_free (sw);
                    387: }
                    388: 
                    389: void glue (AUD_close_, TYPE) (QEMUSoundCard *card, SW *sw)
                    390: {
                    391:     if (sw) {
                    392:         if (audio_bug (AUDIO_FUNC, !card || !card->audio)) {
                    393:             dolog ("card=%p card->audio=%p\n",
                    394:                    card, card ? card->audio : NULL);
                    395:             return;
                    396:         }
                    397: 
                    398:         glue (audio_close_, TYPE) (card->audio, sw);
                    399:     }
                    400: }
                    401: 
                    402: SW *glue (AUD_open_, TYPE) (
                    403:     QEMUSoundCard *card,
                    404:     SW *sw,
                    405:     const char *name,
                    406:     void *callback_opaque ,
                    407:     audio_callback_fn_t callback_fn,
1.1.1.2   root      408:     audsettings_t *as
1.1       root      409:     )
                    410: {
                    411:     AudioState *s;
                    412: #ifdef DAC
                    413:     int live = 0;
                    414:     SW *old_sw = NULL;
                    415: #endif
                    416: 
                    417:     ldebug ("open %s, freq %d, nchannels %d, fmt %d\n",
                    418:             name, as->freq, as->nchannels, as->fmt);
                    419: 
                    420:     if (audio_bug (AUDIO_FUNC,
                    421:                    !card || !card->audio || !name || !callback_fn || !as)) {
                    422:         dolog ("card=%p card->audio=%p name=%p callback_fn=%p as=%p\n",
                    423:                card, card ? card->audio : NULL, name, callback_fn, as);
                    424:         goto fail;
                    425:     }
                    426: 
                    427:     s = card->audio;
                    428: 
1.1.1.2   root      429:     if (audio_bug (AUDIO_FUNC, audio_validate_settings (as))) {
1.1       root      430:         audio_print_settings (as);
                    431:         goto fail;
                    432:     }
                    433: 
                    434:     if (audio_bug (AUDIO_FUNC, !s->drv)) {
                    435:         dolog ("Can not open `%s' (no host audio driver)\n", name);
                    436:         goto fail;
                    437:     }
                    438: 
                    439:     if (sw && audio_pcm_info_eq (&sw->info, as)) {
                    440:         return sw;
                    441:     }
                    442: 
                    443: #ifdef DAC
                    444:     if (conf.plive && sw && (!sw->active && !sw->empty)) {
                    445:         live = sw->total_hw_samples_mixed;
                    446: 
                    447: #ifdef DEBUG_PLIVE
                    448:         dolog ("Replacing voice %s with %d live samples\n", SW_NAME (sw), live);
                    449:         dolog ("Old %s freq %d, bits %d, channels %d\n",
                    450:                SW_NAME (sw), sw->info.freq, sw->info.bits, sw->info.nchannels);
                    451:         dolog ("New %s freq %d, bits %d, channels %d\n",
                    452:                name,
                    453:                freq,
                    454:                (fmt == AUD_FMT_S16 || fmt == AUD_FMT_U16) ? 16 : 8,
                    455:                nchannels);
                    456: #endif
                    457: 
                    458:         if (live) {
                    459:             old_sw = sw;
                    460:             old_sw->callback.fn = NULL;
                    461:             sw = NULL;
                    462:         }
                    463:     }
                    464: #endif
                    465: 
                    466:     if (!glue (conf.fixed_, TYPE).enabled && sw) {
                    467:         glue (AUD_close_, TYPE) (card, sw);
                    468:         sw = NULL;
                    469:     }
                    470: 
                    471:     if (sw) {
                    472:         HW *hw = sw->hw;
                    473: 
                    474:         if (!hw) {
                    475:             dolog ("Internal logic error voice `%s' has no hardware store\n",
                    476:                    SW_NAME (sw));
                    477:             goto fail;
                    478:         }
                    479: 
                    480:         glue (audio_pcm_sw_fini_, TYPE) (sw);
1.1.1.2   root      481:         if (glue (audio_pcm_sw_init_, TYPE) (sw, hw, name, as)) {
1.1       root      482:             goto fail;
                    483:         }
                    484:     }
                    485:     else {
1.1.1.2   root      486:         sw = glue (audio_pcm_create_voice_pair_, TYPE) (s, name, as);
1.1       root      487:         if (!sw) {
                    488:             dolog ("Failed to create voice `%s'\n", name);
                    489:             return NULL;
                    490:         }
                    491:     }
                    492: 
                    493:     if (sw) {
                    494:         sw->vol = nominal_volume;
                    495:         sw->callback.fn = callback_fn;
                    496:         sw->callback.opaque = callback_opaque;
                    497: 
                    498: #ifdef DAC
                    499:         if (live) {
                    500:             int mixed =
                    501:                 (live << old_sw->info.shift)
                    502:                 * old_sw->info.bytes_per_second
                    503:                 / sw->info.bytes_per_second;
                    504: 
                    505: #ifdef DEBUG_PLIVE
                    506:             dolog ("Silence will be mixed %d\n", mixed);
                    507: #endif
                    508:             sw->total_hw_samples_mixed += mixed;
                    509:         }
                    510: #endif
                    511: 
                    512: #ifdef DEBUG_AUDIO
                    513:         dolog ("%s\n", name);
                    514:         audio_pcm_print_info ("hw", &sw->hw->info);
                    515:         audio_pcm_print_info ("sw", &sw->info);
                    516: #endif
                    517:     }
                    518: 
                    519:     return sw;
                    520: 
                    521:  fail:
                    522:     glue (AUD_close_, TYPE) (card, sw);
                    523:     return NULL;
                    524: }
                    525: 
                    526: int glue (AUD_is_active_, TYPE) (SW *sw)
                    527: {
                    528:     return sw ? sw->active : 0;
                    529: }
                    530: 
                    531: void glue (AUD_init_time_stamp_, TYPE) (SW *sw, QEMUAudioTimeStamp *ts)
                    532: {
                    533:     if (!sw) {
                    534:         return;
                    535:     }
                    536: 
                    537:     ts->old_ts = sw->hw->ts_helper;
                    538: }
                    539: 
                    540: uint64_t glue (AUD_get_elapsed_usec_, TYPE) (SW *sw, QEMUAudioTimeStamp *ts)
                    541: {
                    542:     uint64_t delta, cur_ts, old_ts;
                    543: 
                    544:     if (!sw) {
                    545:         return 0;
                    546:     }
                    547: 
                    548:     cur_ts = sw->hw->ts_helper;
                    549:     old_ts = ts->old_ts;
                    550:     /* dolog ("cur %lld old %lld\n", cur_ts, old_ts); */
                    551: 
                    552:     if (cur_ts >= old_ts) {
                    553:         delta = cur_ts - old_ts;
                    554:     }
                    555:     else {
                    556:         delta = UINT64_MAX - old_ts + cur_ts;
                    557:     }
                    558: 
                    559:     if (!delta) {
                    560:         return 0;
                    561:     }
                    562: 
                    563:     return (delta * sw->hw->info.freq) / 1000000;
                    564: }
                    565: 
                    566: #undef TYPE
                    567: #undef HW
                    568: #undef SW
                    569: #undef HWBUF
                    570: #undef NAME

unix.superglobalmegacorp.com

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