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

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,
                    143:     audsettings_t *as,
                    144:     int endian
                    145:     )
                    146: {
                    147:     int err;
                    148: 
                    149:     audio_pcm_init_info (&sw->info, as, audio_need_to_swap_endian (endian));
                    150:     sw->hw = hw;
                    151:     sw->active = 0;
                    152: #ifdef DAC
                    153:     sw->ratio = ((int64_t) sw->hw->info.freq << 32) / sw->info.freq;
                    154:     sw->total_hw_samples_mixed = 0;
                    155:     sw->empty = 1;
                    156: #else
                    157:     sw->ratio = ((int64_t) sw->info.freq << 32) / sw->hw->info.freq;
                    158: #endif
                    159: 
                    160: #ifdef DAC
                    161:     sw->conv = mixeng_conv
                    162: #else
                    163:     sw->clip = mixeng_clip
                    164: #endif
                    165:         [sw->info.nchannels == 2]
                    166:         [sw->info.sign]
                    167:         [sw->info.swap_endian]
                    168:         [sw->info.bits == 16];
                    169: 
                    170:     sw->name = qemu_strdup (name);
                    171:     err = glue (audio_pcm_sw_alloc_resources_, TYPE) (sw);
                    172:     if (err) {
                    173:         qemu_free (sw->name);
                    174:         sw->name = NULL;
                    175:     }
                    176:     return err;
                    177: }
                    178: 
                    179: static void glue (audio_pcm_sw_fini_, TYPE) (SW *sw)
                    180: {
                    181:     glue (audio_pcm_sw_free_resources_, TYPE) (sw);
                    182:     if (sw->name) {
                    183:         qemu_free (sw->name);
                    184:         sw->name = NULL;
                    185:     }
                    186: }
                    187: 
                    188: static void glue (audio_pcm_hw_add_sw_, TYPE) (HW *hw, SW *sw)
                    189: {
                    190:     LIST_INSERT_HEAD (&hw->sw_head, sw, entries);
                    191: }
                    192: 
                    193: static void glue (audio_pcm_hw_del_sw_, TYPE) (SW *sw)
                    194: {
                    195:     LIST_REMOVE (sw, entries);
                    196: }
                    197: 
                    198: static void glue (audio_pcm_hw_gc_, TYPE) (AudioState *s, HW **hwp)
                    199: {
                    200:     HW *hw = *hwp;
                    201: 
                    202:     if (!hw->sw_head.lh_first) {
                    203:         LIST_REMOVE (hw, entries);
                    204:         glue (s->nb_hw_voices_, TYPE) += 1;
                    205:         glue (audio_pcm_hw_free_resources_ ,TYPE) (hw);
                    206:         glue (hw->pcm_ops->fini_, TYPE) (hw);
                    207:         qemu_free (hw);
                    208:         *hwp = NULL;
                    209:     }
                    210: }
                    211: 
                    212: static HW *glue (audio_pcm_hw_find_any_, TYPE) (AudioState *s, HW *hw)
                    213: {
                    214:     return hw ? hw->entries.le_next : s->glue (hw_head_, TYPE).lh_first;
                    215: }
                    216: 
                    217: static HW *glue (audio_pcm_hw_find_any_enabled_, TYPE) (AudioState *s, HW *hw)
                    218: {
                    219:     while ((hw = glue (audio_pcm_hw_find_any_, TYPE) (s, hw))) {
                    220:         if (hw->enabled) {
                    221:             return hw;
                    222:         }
                    223:     }
                    224:     return NULL;
                    225: }
                    226: 
                    227: static HW *glue (audio_pcm_hw_find_specific_, TYPE) (
                    228:     AudioState *s,
                    229:     HW *hw,
                    230:     audsettings_t *as
                    231:     )
                    232: {
                    233:     while ((hw = glue (audio_pcm_hw_find_any_, TYPE) (s, hw))) {
                    234:         if (audio_pcm_info_eq (&hw->info, as)) {
                    235:             return hw;
                    236:         }
                    237:     }
                    238:     return NULL;
                    239: }
                    240: 
                    241: static HW *glue (audio_pcm_hw_add_new_, TYPE) (AudioState *s, audsettings_t *as)
                    242: {
                    243:     HW *hw;
                    244:     struct audio_driver *drv = s->drv;
                    245: 
                    246:     if (!glue (s->nb_hw_voices_, TYPE)) {
                    247:         return NULL;
                    248:     }
                    249: 
                    250:     if (audio_bug (AUDIO_FUNC, !drv)) {
                    251:         dolog ("No host audio driver\n");
                    252:         return NULL;
                    253:     }
                    254: 
                    255:     if (audio_bug (AUDIO_FUNC, !drv->pcm_ops)) {
                    256:         dolog ("Host audio driver without pcm_ops\n");
                    257:         return NULL;
                    258:     }
                    259: 
                    260:     hw = audio_calloc (AUDIO_FUNC, 1, glue (drv->voice_size_, TYPE));
                    261:     if (!hw) {
                    262:         dolog ("Can not allocate voice `%s' size %d\n",
                    263:                drv->name, glue (drv->voice_size_, TYPE));
                    264:         return NULL;
                    265:     }
                    266: 
                    267:     hw->pcm_ops = drv->pcm_ops;
                    268:     LIST_INIT (&hw->sw_head);
                    269: 
                    270:     if (glue (hw->pcm_ops->init_, TYPE) (hw, as)) {
                    271:         goto err0;
                    272:     }
                    273: 
                    274:     if (audio_bug (AUDIO_FUNC, hw->samples <= 0)) {
                    275:         dolog ("hw->samples=%d\n", hw->samples);
                    276:         goto err1;
                    277:     }
                    278: 
                    279: #ifdef DAC
                    280:     hw->clip = mixeng_clip
                    281: #else
                    282:     hw->conv = mixeng_conv
                    283: #endif
                    284:         [hw->info.nchannels == 2]
                    285:         [hw->info.sign]
                    286:         [hw->info.swap_endian]
                    287:         [hw->info.bits == 16];
                    288: 
                    289:     if (glue (audio_pcm_hw_alloc_resources_, TYPE) (hw)) {
                    290:         goto err1;
                    291:     }
                    292: 
                    293:     LIST_INSERT_HEAD (&s->glue (hw_head_, TYPE), hw, entries);
                    294:     glue (s->nb_hw_voices_, TYPE) -= 1;
                    295:     return hw;
                    296: 
                    297:  err1:
                    298:     glue (hw->pcm_ops->fini_, TYPE) (hw);
                    299:  err0:
                    300:     qemu_free (hw);
                    301:     return NULL;
                    302: }
                    303: 
                    304: static HW *glue (audio_pcm_hw_add_, TYPE) (AudioState *s, audsettings_t *as)
                    305: {
                    306:     HW *hw;
                    307: 
                    308:     if (glue (conf.fixed_, TYPE).enabled && glue (conf.fixed_, TYPE).greedy) {
                    309:         hw = glue (audio_pcm_hw_add_new_, TYPE) (s, as);
                    310:         if (hw) {
                    311:             return hw;
                    312:         }
                    313:     }
                    314: 
                    315:     hw = glue (audio_pcm_hw_find_specific_, TYPE) (s, NULL, as);
                    316:     if (hw) {
                    317:         return hw;
                    318:     }
                    319: 
                    320:     hw = glue (audio_pcm_hw_add_new_, TYPE) (s, as);
                    321:     if (hw) {
                    322:         return hw;
                    323:     }
                    324: 
                    325:     return glue (audio_pcm_hw_find_any_, TYPE) (s, NULL);
                    326: }
                    327: 
                    328: static SW *glue (audio_pcm_create_voice_pair_, TYPE) (
                    329:     AudioState *s,
                    330:     const char *sw_name,
                    331:     audsettings_t *as,
                    332:     int sw_endian
                    333:     )
                    334: {
                    335:     SW *sw;
                    336:     HW *hw;
                    337:     audsettings_t hw_as;
                    338: 
                    339:     if (glue (conf.fixed_, TYPE).enabled) {
                    340:         hw_as = glue (conf.fixed_, TYPE).settings;
                    341:     }
                    342:     else {
                    343:         hw_as = *as;
                    344:     }
                    345: 
                    346:     sw = audio_calloc (AUDIO_FUNC, 1, sizeof (*sw));
                    347:     if (!sw) {
                    348:         dolog ("Could not allocate soft voice `%s' (%zu bytes)\n",
                    349:                sw_name ? sw_name : "unknown", sizeof (*sw));
                    350:         goto err1;
                    351:     }
                    352: 
                    353:     hw = glue (audio_pcm_hw_add_, TYPE) (s, &hw_as);
                    354:     if (!hw) {
                    355:         goto err2;
                    356:     }
                    357: 
                    358:     glue (audio_pcm_hw_add_sw_, TYPE) (hw, sw);
                    359: 
                    360:     if (glue (audio_pcm_sw_init_, TYPE) (sw, hw, sw_name, as, sw_endian)) {
                    361:         goto err3;
                    362:     }
                    363: 
                    364:     return sw;
                    365: 
                    366: err3:
                    367:     glue (audio_pcm_hw_del_sw_, TYPE) (sw);
                    368:     glue (audio_pcm_hw_gc_, TYPE) (s, &hw);
                    369: err2:
                    370:     qemu_free (sw);
                    371: err1:
                    372:     return NULL;
                    373: }
                    374: 
                    375: static void glue (audio_close_, TYPE) (AudioState *s, SW *sw)
                    376: {
                    377:     glue (audio_pcm_sw_fini_, TYPE) (sw);
                    378:     glue (audio_pcm_hw_del_sw_, TYPE) (sw);
                    379:     glue (audio_pcm_hw_gc_, TYPE) (s, &sw->hw);
                    380:     qemu_free (sw);
                    381: }
                    382: 
                    383: void glue (AUD_close_, TYPE) (QEMUSoundCard *card, SW *sw)
                    384: {
                    385:     if (sw) {
                    386:         if (audio_bug (AUDIO_FUNC, !card || !card->audio)) {
                    387:             dolog ("card=%p card->audio=%p\n",
                    388:                    card, card ? card->audio : NULL);
                    389:             return;
                    390:         }
                    391: 
                    392:         glue (audio_close_, TYPE) (card->audio, sw);
                    393:     }
                    394: }
                    395: 
                    396: SW *glue (AUD_open_, TYPE) (
                    397:     QEMUSoundCard *card,
                    398:     SW *sw,
                    399:     const char *name,
                    400:     void *callback_opaque ,
                    401:     audio_callback_fn_t callback_fn,
                    402:     audsettings_t *as,
                    403:     int sw_endian
                    404:     )
                    405: {
                    406:     AudioState *s;
                    407: #ifdef DAC
                    408:     int live = 0;
                    409:     SW *old_sw = NULL;
                    410: #endif
                    411: 
                    412:     ldebug ("open %s, freq %d, nchannels %d, fmt %d\n",
                    413:             name, as->freq, as->nchannels, as->fmt);
                    414: 
                    415:     if (audio_bug (AUDIO_FUNC,
                    416:                    !card || !card->audio || !name || !callback_fn || !as)) {
                    417:         dolog ("card=%p card->audio=%p name=%p callback_fn=%p as=%p\n",
                    418:                card, card ? card->audio : NULL, name, callback_fn, as);
                    419:         goto fail;
                    420:     }
                    421: 
                    422:     s = card->audio;
                    423: 
                    424:     if (audio_bug (AUDIO_FUNC, audio_validate_settigs (as))) {
                    425:         audio_print_settings (as);
                    426:         goto fail;
                    427:     }
                    428: 
                    429:     if (audio_bug (AUDIO_FUNC, !s->drv)) {
                    430:         dolog ("Can not open `%s' (no host audio driver)\n", name);
                    431:         goto fail;
                    432:     }
                    433: 
                    434:     if (sw && audio_pcm_info_eq (&sw->info, as)) {
                    435:         return sw;
                    436:     }
                    437: 
                    438: #ifdef DAC
                    439:     if (conf.plive && sw && (!sw->active && !sw->empty)) {
                    440:         live = sw->total_hw_samples_mixed;
                    441: 
                    442: #ifdef DEBUG_PLIVE
                    443:         dolog ("Replacing voice %s with %d live samples\n", SW_NAME (sw), live);
                    444:         dolog ("Old %s freq %d, bits %d, channels %d\n",
                    445:                SW_NAME (sw), sw->info.freq, sw->info.bits, sw->info.nchannels);
                    446:         dolog ("New %s freq %d, bits %d, channels %d\n",
                    447:                name,
                    448:                freq,
                    449:                (fmt == AUD_FMT_S16 || fmt == AUD_FMT_U16) ? 16 : 8,
                    450:                nchannels);
                    451: #endif
                    452: 
                    453:         if (live) {
                    454:             old_sw = sw;
                    455:             old_sw->callback.fn = NULL;
                    456:             sw = NULL;
                    457:         }
                    458:     }
                    459: #endif
                    460: 
                    461:     if (!glue (conf.fixed_, TYPE).enabled && sw) {
                    462:         glue (AUD_close_, TYPE) (card, sw);
                    463:         sw = NULL;
                    464:     }
                    465: 
                    466:     if (sw) {
                    467:         HW *hw = sw->hw;
                    468: 
                    469:         if (!hw) {
                    470:             dolog ("Internal logic error voice `%s' has no hardware store\n",
                    471:                    SW_NAME (sw));
                    472:             goto fail;
                    473:         }
                    474: 
                    475:         glue (audio_pcm_sw_fini_, TYPE) (sw);
                    476:         if (glue (audio_pcm_sw_init_, TYPE) (sw, hw, name, as, sw_endian)) {
                    477:             goto fail;
                    478:         }
                    479:     }
                    480:     else {
                    481:         sw = glue (audio_pcm_create_voice_pair_, TYPE) (s, name, as, sw_endian);
                    482:         if (!sw) {
                    483:             dolog ("Failed to create voice `%s'\n", name);
                    484:             return NULL;
                    485:         }
                    486:     }
                    487: 
                    488:     if (sw) {
                    489:         sw->vol = nominal_volume;
                    490:         sw->callback.fn = callback_fn;
                    491:         sw->callback.opaque = callback_opaque;
                    492: 
                    493: #ifdef DAC
                    494:         if (live) {
                    495:             int mixed =
                    496:                 (live << old_sw->info.shift)
                    497:                 * old_sw->info.bytes_per_second
                    498:                 / sw->info.bytes_per_second;
                    499: 
                    500: #ifdef DEBUG_PLIVE
                    501:             dolog ("Silence will be mixed %d\n", mixed);
                    502: #endif
                    503:             sw->total_hw_samples_mixed += mixed;
                    504:         }
                    505: #endif
                    506: 
                    507: #ifdef DEBUG_AUDIO
                    508:         dolog ("%s\n", name);
                    509:         audio_pcm_print_info ("hw", &sw->hw->info);
                    510:         audio_pcm_print_info ("sw", &sw->info);
                    511: #endif
                    512:     }
                    513: 
                    514:     return sw;
                    515: 
                    516:  fail:
                    517:     glue (AUD_close_, TYPE) (card, sw);
                    518:     return NULL;
                    519: }
                    520: 
                    521: int glue (AUD_is_active_, TYPE) (SW *sw)
                    522: {
                    523:     return sw ? sw->active : 0;
                    524: }
                    525: 
                    526: void glue (AUD_init_time_stamp_, TYPE) (SW *sw, QEMUAudioTimeStamp *ts)
                    527: {
                    528:     if (!sw) {
                    529:         return;
                    530:     }
                    531: 
                    532:     ts->old_ts = sw->hw->ts_helper;
                    533: }
                    534: 
                    535: uint64_t glue (AUD_get_elapsed_usec_, TYPE) (SW *sw, QEMUAudioTimeStamp *ts)
                    536: {
                    537:     uint64_t delta, cur_ts, old_ts;
                    538: 
                    539:     if (!sw) {
                    540:         return 0;
                    541:     }
                    542: 
                    543:     cur_ts = sw->hw->ts_helper;
                    544:     old_ts = ts->old_ts;
                    545:     /* dolog ("cur %lld old %lld\n", cur_ts, old_ts); */
                    546: 
                    547:     if (cur_ts >= old_ts) {
                    548:         delta = cur_ts - old_ts;
                    549:     }
                    550:     else {
                    551:         delta = UINT64_MAX - old_ts + cur_ts;
                    552:     }
                    553: 
                    554:     if (!delta) {
                    555:         return 0;
                    556:     }
                    557: 
                    558:     return (delta * sw->hw->info.freq) / 1000000;
                    559: }
                    560: 
                    561: #undef TYPE
                    562: #undef HW
                    563: #undef SW
                    564: #undef HWBUF
                    565: #undef NAME

unix.superglobalmegacorp.com

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