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