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