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

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: {
1.1.1.6 ! root      187:     QLIST_INSERT_HEAD (&hw->sw_head, sw, entries);
1.1       root      188: }
                    189: 
                    190: static void glue (audio_pcm_hw_del_sw_, TYPE) (SW *sw)
                    191: {
1.1.1.6 ! root      192:     QLIST_REMOVE (sw, entries);
1.1       root      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.1.6 ! root      204:         QLIST_REMOVE (hw, entries);
1.1       root      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;
1.1.1.6 ! root      270:     QLIST_INIT (&hw->sw_head);
1.1.1.2   root      271: #ifdef DAC
1.1.1.6 ! root      272:     QLIST_INIT (&hw->cap_head);
1.1.1.2   root      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: 
1.1.1.6 ! root      297:     QLIST_INSERT_HEAD (&s->glue (hw_head_, TYPE), hw, entries);
1.1       root      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 ,
1.1.1.6 ! root      405:     audio_callback_fn 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,
1.1.1.6 ! root      448:                as->freq,
        !           449:                (as->fmt == AUD_FMT_S16 || as->fmt == AUD_FMT_U16) ? 16 : 8,
        !           450:                as->nchannels);
1.1       root      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: 
1.1.1.6 ! root      488:     sw->card = card;
        !           489:     sw->vol = nominal_volume;
        !           490:     sw->callback.fn = callback_fn;
        !           491:     sw->callback.opaque = callback_opaque;
1.1       root      492: 
                    493: #ifdef DAC
1.1.1.6 ! root      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;
1.1       root      499: 
                    500: #ifdef DEBUG_PLIVE
1.1.1.6 ! root      501:         dolog ("Silence will be mixed %d\n", mixed);
1.1       root      502: #endif
1.1.1.6 ! root      503:         sw->total_hw_samples_mixed += mixed;
        !           504:     }
1.1       root      505: #endif
                    506: 
                    507: #ifdef DEBUG_AUDIO
1.1.1.6 ! root      508:     dolog ("%s\n", name);
        !           509:     audio_pcm_print_info ("hw", &sw->hw->info);
        !           510:     audio_pcm_print_info ("sw", &sw->info);
1.1       root      511: #endif
                    512: 
                    513:     return sw;
                    514: 
                    515:  fail:
                    516:     glue (AUD_close_, TYPE) (card, sw);
                    517:     return NULL;
                    518: }
                    519: 
                    520: int glue (AUD_is_active_, TYPE) (SW *sw)
                    521: {
                    522:     return sw ? sw->active : 0;
                    523: }
                    524: 
                    525: void glue (AUD_init_time_stamp_, TYPE) (SW *sw, QEMUAudioTimeStamp *ts)
                    526: {
                    527:     if (!sw) {
                    528:         return;
                    529:     }
                    530: 
                    531:     ts->old_ts = sw->hw->ts_helper;
                    532: }
                    533: 
                    534: uint64_t glue (AUD_get_elapsed_usec_, TYPE) (SW *sw, QEMUAudioTimeStamp *ts)
                    535: {
                    536:     uint64_t delta, cur_ts, old_ts;
                    537: 
                    538:     if (!sw) {
                    539:         return 0;
                    540:     }
                    541: 
                    542:     cur_ts = sw->hw->ts_helper;
                    543:     old_ts = ts->old_ts;
                    544:     /* dolog ("cur %lld old %lld\n", cur_ts, old_ts); */
                    545: 
                    546:     if (cur_ts >= old_ts) {
                    547:         delta = cur_ts - old_ts;
                    548:     }
                    549:     else {
                    550:         delta = UINT64_MAX - old_ts + cur_ts;
                    551:     }
                    552: 
                    553:     if (!delta) {
                    554:         return 0;
                    555:     }
                    556: 
1.1.1.6 ! root      557:     return muldiv64 (delta, sw->hw->info.freq, 1000000);
1.1       root      558: }
                    559: 
                    560: #undef TYPE
                    561: #undef HW
                    562: #undef SW
                    563: #undef HWBUF
                    564: #undef NAME

unix.superglobalmegacorp.com

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