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

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: 
1.1.1.5 ! root       39: static void glue (audio_init_nb_voices_, TYPE) (struct audio_driver *drv)
1.1       root       40: {
1.1.1.5 ! root       41:     AudioState *s = &glob_audio_state;
1.1       root       42:     int max_voices = glue (drv->max_voices_, TYPE);
                     43:     int voice_size = glue (drv->voice_size_, TYPE);
                     44: 
                     45:     if (glue (s->nb_hw_voices_, TYPE) > max_voices) {
                     46:         if (!max_voices) {
                     47: #ifdef DAC
                     48:             dolog ("Driver `%s' does not support " NAME "\n", drv->name);
                     49: #endif
                     50:         }
                     51:         else {
                     52:             dolog ("Driver `%s' does not support %d " NAME " voices, max %d\n",
                     53:                    drv->name,
                     54:                    glue (s->nb_hw_voices_, TYPE),
                     55:                    max_voices);
                     56:         }
                     57:         glue (s->nb_hw_voices_, TYPE) = max_voices;
                     58:     }
                     59: 
                     60:     if (audio_bug (AUDIO_FUNC, !voice_size && max_voices)) {
                     61:         dolog ("drv=`%s' voice_size=0 max_voices=%d\n",
                     62:                drv->name, max_voices);
                     63:         glue (s->nb_hw_voices_, TYPE) = 0;
                     64:     }
                     65: 
                     66:     if (audio_bug (AUDIO_FUNC, voice_size && !max_voices)) {
                     67:         dolog ("drv=`%s' voice_size=%d max_voices=0\n",
                     68:                drv->name, voice_size);
                     69:     }
                     70: }
                     71: 
                     72: static void glue (audio_pcm_hw_free_resources_, TYPE) (HW *hw)
                     73: {
                     74:     if (HWBUF) {
                     75:         qemu_free (HWBUF);
                     76:     }
                     77: 
                     78:     HWBUF = NULL;
                     79: }
                     80: 
                     81: static int glue (audio_pcm_hw_alloc_resources_, TYPE) (HW *hw)
                     82: {
1.1.1.4   root       83:     HWBUF = audio_calloc (AUDIO_FUNC, hw->samples, sizeof (struct st_sample));
1.1       root       84:     if (!HWBUF) {
                     85:         dolog ("Could not allocate " NAME " buffer (%d samples)\n",
                     86:                hw->samples);
                     87:         return -1;
                     88:     }
                     89: 
                     90:     return 0;
                     91: }
                     92: 
                     93: static void glue (audio_pcm_sw_free_resources_, TYPE) (SW *sw)
                     94: {
                     95:     if (sw->buf) {
                     96:         qemu_free (sw->buf);
                     97:     }
                     98: 
                     99:     if (sw->rate) {
                    100:         st_rate_stop (sw->rate);
                    101:     }
                    102: 
                    103:     sw->buf = NULL;
                    104:     sw->rate = NULL;
                    105: }
                    106: 
                    107: static int glue (audio_pcm_sw_alloc_resources_, TYPE) (SW *sw)
                    108: {
                    109:     int samples;
                    110: 
                    111: #ifdef DAC
                    112:     samples = sw->hw->samples;
                    113: #else
                    114:     samples = ((int64_t) sw->hw->samples << 32) / sw->ratio;
                    115: #endif
                    116: 
1.1.1.4   root      117:     sw->buf = audio_calloc (AUDIO_FUNC, samples, sizeof (struct st_sample));
1.1       root      118:     if (!sw->buf) {
                    119:         dolog ("Could not allocate buffer for `%s' (%d samples)\n",
                    120:                SW_NAME (sw), samples);
                    121:         return -1;
                    122:     }
                    123: 
                    124: #ifdef DAC
                    125:     sw->rate = st_rate_start (sw->info.freq, sw->hw->info.freq);
                    126: #else
                    127:     sw->rate = st_rate_start (sw->hw->info.freq, sw->info.freq);
                    128: #endif
                    129:     if (!sw->rate) {
                    130:         qemu_free (sw->buf);
                    131:         sw->buf = NULL;
                    132:         return -1;
                    133:     }
                    134:     return 0;
                    135: }
                    136: 
                    137: static int glue (audio_pcm_sw_init_, TYPE) (
                    138:     SW *sw,
                    139:     HW *hw,
                    140:     const char *name,
1.1.1.4   root      141:     struct audsettings *as
1.1       root      142:     )
                    143: {
                    144:     int err;
                    145: 
1.1.1.2   root      146:     audio_pcm_init_info (&sw->info, as);
1.1       root      147:     sw->hw = hw;
                    148:     sw->active = 0;
                    149: #ifdef DAC
                    150:     sw->ratio = ((int64_t) sw->hw->info.freq << 32) / sw->info.freq;
                    151:     sw->total_hw_samples_mixed = 0;
                    152:     sw->empty = 1;
                    153: #else
                    154:     sw->ratio = ((int64_t) sw->info.freq << 32) / sw->hw->info.freq;
                    155: #endif
                    156: 
                    157: #ifdef DAC
                    158:     sw->conv = mixeng_conv
                    159: #else
                    160:     sw->clip = mixeng_clip
                    161: #endif
                    162:         [sw->info.nchannels == 2]
                    163:         [sw->info.sign]
1.1.1.2   root      164:         [sw->info.swap_endianness]
1.1.1.3   root      165:         [audio_bits_to_index (sw->info.bits)];
1.1       root      166: 
                    167:     sw->name = qemu_strdup (name);
                    168:     err = glue (audio_pcm_sw_alloc_resources_, TYPE) (sw);
                    169:     if (err) {
                    170:         qemu_free (sw->name);
                    171:         sw->name = NULL;
                    172:     }
                    173:     return err;
                    174: }
                    175: 
                    176: static void glue (audio_pcm_sw_fini_, TYPE) (SW *sw)
                    177: {
                    178:     glue (audio_pcm_sw_free_resources_, TYPE) (sw);
                    179:     if (sw->name) {
                    180:         qemu_free (sw->name);
                    181:         sw->name = NULL;
                    182:     }
                    183: }
                    184: 
                    185: static void glue (audio_pcm_hw_add_sw_, TYPE) (HW *hw, SW *sw)
                    186: {
                    187:     LIST_INSERT_HEAD (&hw->sw_head, sw, entries);
                    188: }
                    189: 
                    190: static void glue (audio_pcm_hw_del_sw_, TYPE) (SW *sw)
                    191: {
                    192:     LIST_REMOVE (sw, entries);
                    193: }
                    194: 
1.1.1.5 ! root      195: static void glue (audio_pcm_hw_gc_, TYPE) (HW **hwp)
1.1       root      196: {
1.1.1.5 ! root      197:     AudioState *s = &glob_audio_state;
1.1       root      198:     HW *hw = *hwp;
                    199: 
                    200:     if (!hw->sw_head.lh_first) {
1.1.1.2   root      201: #ifdef DAC
                    202:         audio_detach_capture (hw);
                    203: #endif
1.1       root      204:         LIST_REMOVE (hw, entries);
                    205:         glue (s->nb_hw_voices_, TYPE) += 1;
                    206:         glue (audio_pcm_hw_free_resources_ ,TYPE) (hw);
                    207:         glue (hw->pcm_ops->fini_, TYPE) (hw);
                    208:         qemu_free (hw);
                    209:         *hwp = NULL;
                    210:     }
                    211: }
                    212: 
1.1.1.5 ! root      213: static HW *glue (audio_pcm_hw_find_any_, TYPE) (HW *hw)
1.1       root      214: {
1.1.1.5 ! root      215:     AudioState *s = &glob_audio_state;
        !           216:     return hw ? hw->entries.le_next : glue (s->hw_head_, TYPE).lh_first;
1.1       root      217: }
                    218: 
1.1.1.5 ! root      219: static HW *glue (audio_pcm_hw_find_any_enabled_, TYPE) (HW *hw)
1.1       root      220: {
1.1.1.5 ! root      221:     while ((hw = glue (audio_pcm_hw_find_any_, TYPE) (hw))) {
1.1       root      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:     HW *hw,
1.1.1.4   root      231:     struct audsettings *as
1.1       root      232:     )
                    233: {
1.1.1.5 ! root      234:     while ((hw = glue (audio_pcm_hw_find_any_, TYPE) (hw))) {
1.1       root      235:         if (audio_pcm_info_eq (&hw->info, as)) {
                    236:             return hw;
                    237:         }
                    238:     }
                    239:     return NULL;
                    240: }
                    241: 
1.1.1.5 ! root      242: static HW *glue (audio_pcm_hw_add_new_, TYPE) (struct audsettings *as)
1.1       root      243: {
                    244:     HW *hw;
1.1.1.5 ! root      245:     AudioState *s = &glob_audio_state;
1.1       root      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
1.1.1.5 ! root      300:     audio_attach_capture (hw);
1.1.1.2   root      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: 
1.1.1.5 ! root      311: static HW *glue (audio_pcm_hw_add_, TYPE) (struct audsettings *as)
1.1       root      312: {
                    313:     HW *hw;
                    314: 
                    315:     if (glue (conf.fixed_, TYPE).enabled && glue (conf.fixed_, TYPE).greedy) {
1.1.1.5 ! root      316:         hw = glue (audio_pcm_hw_add_new_, TYPE) (as);
1.1       root      317:         if (hw) {
                    318:             return hw;
                    319:         }
                    320:     }
                    321: 
1.1.1.5 ! root      322:     hw = glue (audio_pcm_hw_find_specific_, TYPE) (NULL, as);
1.1       root      323:     if (hw) {
                    324:         return hw;
                    325:     }
                    326: 
1.1.1.5 ! root      327:     hw = glue (audio_pcm_hw_add_new_, TYPE) (as);
1.1       root      328:     if (hw) {
                    329:         return hw;
                    330:     }
                    331: 
1.1.1.5 ! root      332:     return glue (audio_pcm_hw_find_any_, TYPE) (NULL);
1.1       root      333: }
                    334: 
                    335: static SW *glue (audio_pcm_create_voice_pair_, TYPE) (
                    336:     const char *sw_name,
1.1.1.4   root      337:     struct audsettings *as
1.1       root      338:     )
                    339: {
                    340:     SW *sw;
                    341:     HW *hw;
1.1.1.4   root      342:     struct audsettings hw_as;
1.1       root      343: 
                    344:     if (glue (conf.fixed_, TYPE).enabled) {
                    345:         hw_as = glue (conf.fixed_, TYPE).settings;
                    346:     }
                    347:     else {
                    348:         hw_as = *as;
                    349:     }
                    350: 
                    351:     sw = audio_calloc (AUDIO_FUNC, 1, sizeof (*sw));
                    352:     if (!sw) {
                    353:         dolog ("Could not allocate soft voice `%s' (%zu bytes)\n",
                    354:                sw_name ? sw_name : "unknown", sizeof (*sw));
                    355:         goto err1;
                    356:     }
                    357: 
1.1.1.5 ! root      358:     hw = glue (audio_pcm_hw_add_, TYPE) (&hw_as);
1.1       root      359:     if (!hw) {
                    360:         goto err2;
                    361:     }
                    362: 
                    363:     glue (audio_pcm_hw_add_sw_, TYPE) (hw, sw);
                    364: 
1.1.1.2   root      365:     if (glue (audio_pcm_sw_init_, TYPE) (sw, hw, sw_name, as)) {
1.1       root      366:         goto err3;
                    367:     }
                    368: 
                    369:     return sw;
                    370: 
                    371: err3:
                    372:     glue (audio_pcm_hw_del_sw_, TYPE) (sw);
1.1.1.5 ! root      373:     glue (audio_pcm_hw_gc_, TYPE) (&hw);
1.1       root      374: err2:
                    375:     qemu_free (sw);
                    376: err1:
                    377:     return NULL;
                    378: }
                    379: 
1.1.1.5 ! root      380: static void glue (audio_close_, TYPE) (SW *sw)
1.1       root      381: {
                    382:     glue (audio_pcm_sw_fini_, TYPE) (sw);
                    383:     glue (audio_pcm_hw_del_sw_, TYPE) (sw);
1.1.1.5 ! root      384:     glue (audio_pcm_hw_gc_, TYPE) (&sw->hw);
1.1       root      385:     qemu_free (sw);
                    386: }
                    387: 
                    388: void glue (AUD_close_, TYPE) (QEMUSoundCard *card, SW *sw)
                    389: {
                    390:     if (sw) {
1.1.1.5 ! root      391:         if (audio_bug (AUDIO_FUNC, !card)) {
        !           392:             dolog ("card=%p\n", card);
1.1       root      393:             return;
                    394:         }
                    395: 
1.1.1.5 ! root      396:         glue (audio_close_, TYPE) (sw);
1.1       root      397:     }
                    398: }
                    399: 
                    400: SW *glue (AUD_open_, TYPE) (
                    401:     QEMUSoundCard *card,
                    402:     SW *sw,
                    403:     const char *name,
                    404:     void *callback_opaque ,
                    405:     audio_callback_fn_t callback_fn,
1.1.1.4   root      406:     struct audsettings *as
1.1       root      407:     )
                    408: {
1.1.1.5 ! root      409:     AudioState *s = &glob_audio_state;
1.1       root      410: #ifdef DAC
                    411:     int live = 0;
                    412:     SW *old_sw = NULL;
                    413: #endif
                    414: 
                    415:     ldebug ("open %s, freq %d, nchannels %d, fmt %d\n",
                    416:             name, as->freq, as->nchannels, as->fmt);
                    417: 
1.1.1.5 ! root      418:     if (audio_bug (AUDIO_FUNC, !card || !name || !callback_fn || !as)) {
        !           419:         dolog ("card=%p name=%p callback_fn=%p as=%p\n",
        !           420:                card, name, callback_fn, as);
1.1       root      421:         goto fail;
                    422:     }
                    423: 
1.1.1.2   root      424:     if (audio_bug (AUDIO_FUNC, audio_validate_settings (as))) {
1.1       root      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);
1.1.1.2   root      476:         if (glue (audio_pcm_sw_init_, TYPE) (sw, hw, name, as)) {
1.1       root      477:             goto fail;
                    478:         }
                    479:     }
                    480:     else {
1.1.1.5 ! root      481:         sw = glue (audio_pcm_create_voice_pair_, TYPE) (name, as);
1.1       root      482:         if (!sw) {
                    483:             dolog ("Failed to create voice `%s'\n", name);
                    484:             return NULL;
                    485:         }
                    486:     }
                    487: 
                    488:     if (sw) {
1.1.1.5 ! root      489:         sw->card = card;
1.1       root      490:         sw->vol = nominal_volume;
                    491:         sw->callback.fn = callback_fn;
                    492:         sw->callback.opaque = callback_opaque;
                    493: 
                    494: #ifdef DAC
                    495:         if (live) {
                    496:             int mixed =
                    497:                 (live << old_sw->info.shift)
                    498:                 * old_sw->info.bytes_per_second
                    499:                 / sw->info.bytes_per_second;
                    500: 
                    501: #ifdef DEBUG_PLIVE
                    502:             dolog ("Silence will be mixed %d\n", mixed);
                    503: #endif
                    504:             sw->total_hw_samples_mixed += mixed;
                    505:         }
                    506: #endif
                    507: 
                    508: #ifdef DEBUG_AUDIO
                    509:         dolog ("%s\n", name);
                    510:         audio_pcm_print_info ("hw", &sw->hw->info);
                    511:         audio_pcm_print_info ("sw", &sw->info);
                    512: #endif
                    513:     }
                    514: 
                    515:     return sw;
                    516: 
                    517:  fail:
                    518:     glue (AUD_close_, TYPE) (card, sw);
                    519:     return NULL;
                    520: }
                    521: 
                    522: int glue (AUD_is_active_, TYPE) (SW *sw)
                    523: {
                    524:     return sw ? sw->active : 0;
                    525: }
                    526: 
                    527: void glue (AUD_init_time_stamp_, TYPE) (SW *sw, QEMUAudioTimeStamp *ts)
                    528: {
                    529:     if (!sw) {
                    530:         return;
                    531:     }
                    532: 
                    533:     ts->old_ts = sw->hw->ts_helper;
                    534: }
                    535: 
                    536: uint64_t glue (AUD_get_elapsed_usec_, TYPE) (SW *sw, QEMUAudioTimeStamp *ts)
                    537: {
                    538:     uint64_t delta, cur_ts, old_ts;
                    539: 
                    540:     if (!sw) {
                    541:         return 0;
                    542:     }
                    543: 
                    544:     cur_ts = sw->hw->ts_helper;
                    545:     old_ts = ts->old_ts;
                    546:     /* dolog ("cur %lld old %lld\n", cur_ts, old_ts); */
                    547: 
                    548:     if (cur_ts >= old_ts) {
                    549:         delta = cur_ts - old_ts;
                    550:     }
                    551:     else {
                    552:         delta = UINT64_MAX - old_ts + cur_ts;
                    553:     }
                    554: 
                    555:     if (!delta) {
                    556:         return 0;
                    557:     }
                    558: 
                    559:     return (delta * sw->hw->info.freq) / 1000000;
                    560: }
                    561: 
                    562: #undef TYPE
                    563: #undef HW
                    564: #undef SW
                    565: #undef HWBUF
                    566: #undef NAME

unix.superglobalmegacorp.com

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