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