qemu/audio/alsaaudio.c
<<
>>
Prefs
   1/*
   2 * QEMU ALSA audio driver
   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#include <alsa/asoundlib.h>
  25#include "qemu-common.h"
  26#include "qemu/main-loop.h"
  27#include "audio.h"
  28
  29#if QEMU_GNUC_PREREQ(4, 3)
  30#pragma GCC diagnostic ignored "-Waddress"
  31#endif
  32
  33#define AUDIO_CAP "alsa"
  34#include "audio_int.h"
  35
  36struct pollhlp {
  37    snd_pcm_t *handle;
  38    struct pollfd *pfds;
  39    int count;
  40    int mask;
  41};
  42
  43typedef struct ALSAVoiceOut {
  44    HWVoiceOut hw;
  45    int wpos;
  46    int pending;
  47    void *pcm_buf;
  48    snd_pcm_t *handle;
  49    struct pollhlp pollhlp;
  50} ALSAVoiceOut;
  51
  52typedef struct ALSAVoiceIn {
  53    HWVoiceIn hw;
  54    snd_pcm_t *handle;
  55    void *pcm_buf;
  56    struct pollhlp pollhlp;
  57} ALSAVoiceIn;
  58
  59static struct {
  60    int size_in_usec_in;
  61    int size_in_usec_out;
  62    const char *pcm_name_in;
  63    const char *pcm_name_out;
  64    unsigned int buffer_size_in;
  65    unsigned int period_size_in;
  66    unsigned int buffer_size_out;
  67    unsigned int period_size_out;
  68    unsigned int threshold;
  69
  70    int buffer_size_in_overridden;
  71    int period_size_in_overridden;
  72
  73    int buffer_size_out_overridden;
  74    int period_size_out_overridden;
  75    int verbose;
  76} conf = {
  77    .buffer_size_out = 4096,
  78    .period_size_out = 1024,
  79    .pcm_name_out = "default",
  80    .pcm_name_in = "default",
  81};
  82
  83struct alsa_params_req {
  84    int freq;
  85    snd_pcm_format_t fmt;
  86    int nchannels;
  87    int size_in_usec;
  88    int override_mask;
  89    unsigned int buffer_size;
  90    unsigned int period_size;
  91};
  92
  93struct alsa_params_obt {
  94    int freq;
  95    audfmt_e fmt;
  96    int endianness;
  97    int nchannels;
  98    snd_pcm_uframes_t samples;
  99};
 100
 101static void GCC_FMT_ATTR (2, 3) alsa_logerr (int err, const char *fmt, ...)
 102{
 103    va_list ap;
 104
 105    va_start (ap, fmt);
 106    AUD_vlog (AUDIO_CAP, fmt, ap);
 107    va_end (ap);
 108
 109    AUD_log (AUDIO_CAP, "Reason: %s\n", snd_strerror (err));
 110}
 111
 112static void GCC_FMT_ATTR (3, 4) alsa_logerr2 (
 113    int err,
 114    const char *typ,
 115    const char *fmt,
 116    ...
 117    )
 118{
 119    va_list ap;
 120
 121    AUD_log (AUDIO_CAP, "Could not initialize %s\n", typ);
 122
 123    va_start (ap, fmt);
 124    AUD_vlog (AUDIO_CAP, fmt, ap);
 125    va_end (ap);
 126
 127    AUD_log (AUDIO_CAP, "Reason: %s\n", snd_strerror (err));
 128}
 129
 130static void alsa_fini_poll (struct pollhlp *hlp)
 131{
 132    int i;
 133    struct pollfd *pfds = hlp->pfds;
 134
 135    if (pfds) {
 136        for (i = 0; i < hlp->count; ++i) {
 137            qemu_set_fd_handler (pfds[i].fd, NULL, NULL, NULL);
 138        }
 139        g_free (pfds);
 140    }
 141    hlp->pfds = NULL;
 142    hlp->count = 0;
 143    hlp->handle = NULL;
 144}
 145
 146static void alsa_anal_close1 (snd_pcm_t **handlep)
 147{
 148    int err = snd_pcm_close (*handlep);
 149    if (err) {
 150        alsa_logerr (err, "Failed to close PCM handle %p\n", *handlep);
 151    }
 152    *handlep = NULL;
 153}
 154
 155static void alsa_anal_close (snd_pcm_t **handlep, struct pollhlp *hlp)
 156{
 157    alsa_fini_poll (hlp);
 158    alsa_anal_close1 (handlep);
 159}
 160
 161static int alsa_recover (snd_pcm_t *handle)
 162{
 163    int err = snd_pcm_prepare (handle);
 164    if (err < 0) {
 165        alsa_logerr (err, "Failed to prepare handle %p\n", handle);
 166        return -1;
 167    }
 168    return 0;
 169}
 170
 171static int alsa_resume (snd_pcm_t *handle)
 172{
 173    int err = snd_pcm_resume (handle);
 174    if (err < 0) {
 175        alsa_logerr (err, "Failed to resume handle %p\n", handle);
 176        return -1;
 177    }
 178    return 0;
 179}
 180
 181static void alsa_poll_handler (void *opaque)
 182{
 183    int err, count;
 184    snd_pcm_state_t state;
 185    struct pollhlp *hlp = opaque;
 186    unsigned short revents;
 187
 188    count = poll (hlp->pfds, hlp->count, 0);
 189    if (count < 0) {
 190        dolog ("alsa_poll_handler: poll %s\n", strerror (errno));
 191        return;
 192    }
 193
 194    if (!count) {
 195        return;
 196    }
 197
 198    /* XXX: ALSA example uses initial count, not the one returned by
 199       poll, correct? */
 200    err = snd_pcm_poll_descriptors_revents (hlp->handle, hlp->pfds,
 201                                            hlp->count, &revents);
 202    if (err < 0) {
 203        alsa_logerr (err, "snd_pcm_poll_descriptors_revents");
 204        return;
 205    }
 206
 207    if (!(revents & hlp->mask)) {
 208        if (conf.verbose) {
 209            dolog ("revents = %d\n", revents);
 210        }
 211        return;
 212    }
 213
 214    state = snd_pcm_state (hlp->handle);
 215    switch (state) {
 216    case SND_PCM_STATE_SETUP:
 217        alsa_recover (hlp->handle);
 218        break;
 219
 220    case SND_PCM_STATE_XRUN:
 221        alsa_recover (hlp->handle);
 222        break;
 223
 224    case SND_PCM_STATE_SUSPENDED:
 225        alsa_resume (hlp->handle);
 226        break;
 227
 228    case SND_PCM_STATE_PREPARED:
 229        audio_run ("alsa run (prepared)");
 230        break;
 231
 232    case SND_PCM_STATE_RUNNING:
 233        audio_run ("alsa run (running)");
 234        break;
 235
 236    default:
 237        dolog ("Unexpected state %d\n", state);
 238    }
 239}
 240
 241static int alsa_poll_helper (snd_pcm_t *handle, struct pollhlp *hlp, int mask)
 242{
 243    int i, count, err;
 244    struct pollfd *pfds;
 245
 246    count = snd_pcm_poll_descriptors_count (handle);
 247    if (count <= 0) {
 248        dolog ("Could not initialize poll mode\n"
 249               "Invalid number of poll descriptors %d\n", count);
 250        return -1;
 251    }
 252
 253    pfds = audio_calloc ("alsa_poll_helper", count, sizeof (*pfds));
 254    if (!pfds) {
 255        dolog ("Could not initialize poll mode\n");
 256        return -1;
 257    }
 258
 259    err = snd_pcm_poll_descriptors (handle, pfds, count);
 260    if (err < 0) {
 261        alsa_logerr (err, "Could not initialize poll mode\n"
 262                     "Could not obtain poll descriptors\n");
 263        g_free (pfds);
 264        return -1;
 265    }
 266
 267    for (i = 0; i < count; ++i) {
 268        if (pfds[i].events & POLLIN) {
 269            err = qemu_set_fd_handler (pfds[i].fd, alsa_poll_handler,
 270                                       NULL, hlp);
 271        }
 272        if (pfds[i].events & POLLOUT) {
 273            if (conf.verbose) {
 274                dolog ("POLLOUT %d %d\n", i, pfds[i].fd);
 275            }
 276            err = qemu_set_fd_handler (pfds[i].fd, NULL,
 277                                       alsa_poll_handler, hlp);
 278        }
 279        if (conf.verbose) {
 280            dolog ("Set handler events=%#x index=%d fd=%d err=%d\n",
 281                   pfds[i].events, i, pfds[i].fd, err);
 282        }
 283
 284        if (err) {
 285            dolog ("Failed to set handler events=%#x index=%d fd=%d err=%d\n",
 286                   pfds[i].events, i, pfds[i].fd, err);
 287
 288            while (i--) {
 289                qemu_set_fd_handler (pfds[i].fd, NULL, NULL, NULL);
 290            }
 291            g_free (pfds);
 292            return -1;
 293        }
 294    }
 295    hlp->pfds = pfds;
 296    hlp->count = count;
 297    hlp->handle = handle;
 298    hlp->mask = mask;
 299    return 0;
 300}
 301
 302static int alsa_poll_out (HWVoiceOut *hw)
 303{
 304    ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw;
 305
 306    return alsa_poll_helper (alsa->handle, &alsa->pollhlp, POLLOUT);
 307}
 308
 309static int alsa_poll_in (HWVoiceIn *hw)
 310{
 311    ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw;
 312
 313    return alsa_poll_helper (alsa->handle, &alsa->pollhlp, POLLIN);
 314}
 315
 316static int alsa_write (SWVoiceOut *sw, void *buf, int len)
 317{
 318    return audio_pcm_sw_write (sw, buf, len);
 319}
 320
 321static snd_pcm_format_t aud_to_alsafmt (audfmt_e fmt, int endianness)
 322{
 323    switch (fmt) {
 324    case AUD_FMT_S8:
 325        return SND_PCM_FORMAT_S8;
 326
 327    case AUD_FMT_U8:
 328        return SND_PCM_FORMAT_U8;
 329
 330    case AUD_FMT_S16:
 331        if (endianness) {
 332            return SND_PCM_FORMAT_S16_BE;
 333        }
 334        else {
 335            return SND_PCM_FORMAT_S16_LE;
 336        }
 337
 338    case AUD_FMT_U16:
 339        if (endianness) {
 340            return SND_PCM_FORMAT_U16_BE;
 341        }
 342        else {
 343            return SND_PCM_FORMAT_U16_LE;
 344        }
 345
 346    case AUD_FMT_S32:
 347        if (endianness) {
 348            return SND_PCM_FORMAT_S32_BE;
 349        }
 350        else {
 351            return SND_PCM_FORMAT_S32_LE;
 352        }
 353
 354    case AUD_FMT_U32:
 355        if (endianness) {
 356            return SND_PCM_FORMAT_U32_BE;
 357        }
 358        else {
 359            return SND_PCM_FORMAT_U32_LE;
 360        }
 361
 362    default:
 363        dolog ("Internal logic error: Bad audio format %d\n", fmt);
 364#ifdef DEBUG_AUDIO
 365        abort ();
 366#endif
 367        return SND_PCM_FORMAT_U8;
 368    }
 369}
 370
 371static int alsa_to_audfmt (snd_pcm_format_t alsafmt, audfmt_e *fmt,
 372                           int *endianness)
 373{
 374    switch (alsafmt) {
 375    case SND_PCM_FORMAT_S8:
 376        *endianness = 0;
 377        *fmt = AUD_FMT_S8;
 378        break;
 379
 380    case SND_PCM_FORMAT_U8:
 381        *endianness = 0;
 382        *fmt = AUD_FMT_U8;
 383        break;
 384
 385    case SND_PCM_FORMAT_S16_LE:
 386        *endianness = 0;
 387        *fmt = AUD_FMT_S16;
 388        break;
 389
 390    case SND_PCM_FORMAT_U16_LE:
 391        *endianness = 0;
 392        *fmt = AUD_FMT_U16;
 393        break;
 394
 395    case SND_PCM_FORMAT_S16_BE:
 396        *endianness = 1;
 397        *fmt = AUD_FMT_S16;
 398        break;
 399
 400    case SND_PCM_FORMAT_U16_BE:
 401        *endianness = 1;
 402        *fmt = AUD_FMT_U16;
 403        break;
 404
 405    case SND_PCM_FORMAT_S32_LE:
 406        *endianness = 0;
 407        *fmt = AUD_FMT_S32;
 408        break;
 409
 410    case SND_PCM_FORMAT_U32_LE:
 411        *endianness = 0;
 412        *fmt = AUD_FMT_U32;
 413        break;
 414
 415    case SND_PCM_FORMAT_S32_BE:
 416        *endianness = 1;
 417        *fmt = AUD_FMT_S32;
 418        break;
 419
 420    case SND_PCM_FORMAT_U32_BE:
 421        *endianness = 1;
 422        *fmt = AUD_FMT_U32;
 423        break;
 424
 425    default:
 426        dolog ("Unrecognized audio format %d\n", alsafmt);
 427        return -1;
 428    }
 429
 430    return 0;
 431}
 432
 433static void alsa_dump_info (struct alsa_params_req *req,
 434                            struct alsa_params_obt *obt,
 435                            snd_pcm_format_t obtfmt)
 436{
 437    dolog ("parameter | requested value | obtained value\n");
 438    dolog ("format    |      %10d |     %10d\n", req->fmt, obtfmt);
 439    dolog ("channels  |      %10d |     %10d\n",
 440           req->nchannels, obt->nchannels);
 441    dolog ("frequency |      %10d |     %10d\n", req->freq, obt->freq);
 442    dolog ("============================================\n");
 443    dolog ("requested: buffer size %d period size %d\n",
 444           req->buffer_size, req->period_size);
 445    dolog ("obtained: samples %ld\n", obt->samples);
 446}
 447
 448static void alsa_set_threshold (snd_pcm_t *handle, snd_pcm_uframes_t threshold)
 449{
 450    int err;
 451    snd_pcm_sw_params_t *sw_params;
 452
 453    snd_pcm_sw_params_alloca (&sw_params);
 454
 455    err = snd_pcm_sw_params_current (handle, sw_params);
 456    if (err < 0) {
 457        dolog ("Could not fully initialize DAC\n");
 458        alsa_logerr (err, "Failed to get current software parameters\n");
 459        return;
 460    }
 461
 462    err = snd_pcm_sw_params_set_start_threshold (handle, sw_params, threshold);
 463    if (err < 0) {
 464        dolog ("Could not fully initialize DAC\n");
 465        alsa_logerr (err, "Failed to set software threshold to %ld\n",
 466                     threshold);
 467        return;
 468    }
 469
 470    err = snd_pcm_sw_params (handle, sw_params);
 471    if (err < 0) {
 472        dolog ("Could not fully initialize DAC\n");
 473        alsa_logerr (err, "Failed to set software parameters\n");
 474        return;
 475    }
 476}
 477
 478static int alsa_open (int in, struct alsa_params_req *req,
 479                      struct alsa_params_obt *obt, snd_pcm_t **handlep)
 480{
 481    snd_pcm_t *handle;
 482    snd_pcm_hw_params_t *hw_params;
 483    int err;
 484    int size_in_usec;
 485    unsigned int freq, nchannels;
 486    const char *pcm_name = in ? conf.pcm_name_in : conf.pcm_name_out;
 487    snd_pcm_uframes_t obt_buffer_size;
 488    const char *typ = in ? "ADC" : "DAC";
 489    snd_pcm_format_t obtfmt;
 490
 491    freq = req->freq;
 492    nchannels = req->nchannels;
 493    size_in_usec = req->size_in_usec;
 494
 495    snd_pcm_hw_params_alloca (&hw_params);
 496
 497    err = snd_pcm_open (
 498        &handle,
 499        pcm_name,
 500        in ? SND_PCM_STREAM_CAPTURE : SND_PCM_STREAM_PLAYBACK,
 501        SND_PCM_NONBLOCK
 502        );
 503    if (err < 0) {
 504        alsa_logerr2 (err, typ, "Failed to open `%s':\n", pcm_name);
 505        return -1;
 506    }
 507
 508    err = snd_pcm_hw_params_any (handle, hw_params);
 509    if (err < 0) {
 510        alsa_logerr2 (err, typ, "Failed to initialize hardware parameters\n");
 511        goto err;
 512    }
 513
 514    err = snd_pcm_hw_params_set_access (
 515        handle,
 516        hw_params,
 517        SND_PCM_ACCESS_RW_INTERLEAVED
 518        );
 519    if (err < 0) {
 520        alsa_logerr2 (err, typ, "Failed to set access type\n");
 521        goto err;
 522    }
 523
 524    err = snd_pcm_hw_params_set_format (handle, hw_params, req->fmt);
 525    if (err < 0 && conf.verbose) {
 526        alsa_logerr2 (err, typ, "Failed to set format %d\n", req->fmt);
 527    }
 528
 529    err = snd_pcm_hw_params_set_rate_near (handle, hw_params, &freq, 0);
 530    if (err < 0) {
 531        alsa_logerr2 (err, typ, "Failed to set frequency %d\n", req->freq);
 532        goto err;
 533    }
 534
 535    err = snd_pcm_hw_params_set_channels_near (
 536        handle,
 537        hw_params,
 538        &nchannels
 539        );
 540    if (err < 0) {
 541        alsa_logerr2 (err, typ, "Failed to set number of channels %d\n",
 542                      req->nchannels);
 543        goto err;
 544    }
 545
 546    if (nchannels != 1 && nchannels != 2) {
 547        alsa_logerr2 (err, typ,
 548                      "Can not handle obtained number of channels %d\n",
 549                      nchannels);
 550        goto err;
 551    }
 552
 553    if (req->buffer_size) {
 554        unsigned long obt;
 555
 556        if (size_in_usec) {
 557            int dir = 0;
 558            unsigned int btime = req->buffer_size;
 559
 560            err = snd_pcm_hw_params_set_buffer_time_near (
 561                handle,
 562                hw_params,
 563                &btime,
 564                &dir
 565                );
 566            obt = btime;
 567        }
 568        else {
 569            snd_pcm_uframes_t bsize = req->buffer_size;
 570
 571            err = snd_pcm_hw_params_set_buffer_size_near (
 572                handle,
 573                hw_params,
 574                &bsize
 575                );
 576            obt = bsize;
 577        }
 578        if (err < 0) {
 579            alsa_logerr2 (err, typ, "Failed to set buffer %s to %d\n",
 580                          size_in_usec ? "time" : "size", req->buffer_size);
 581            goto err;
 582        }
 583
 584        if ((req->override_mask & 2) && (obt - req->buffer_size))
 585            dolog ("Requested buffer %s %u was rejected, using %lu\n",
 586                   size_in_usec ? "time" : "size", req->buffer_size, obt);
 587    }
 588
 589    if (req->period_size) {
 590        unsigned long obt;
 591
 592        if (size_in_usec) {
 593            int dir = 0;
 594            unsigned int ptime = req->period_size;
 595
 596            err = snd_pcm_hw_params_set_period_time_near (
 597                handle,
 598                hw_params,
 599                &ptime,
 600                &dir
 601                );
 602            obt = ptime;
 603        }
 604        else {
 605            int dir = 0;
 606            snd_pcm_uframes_t psize = req->period_size;
 607
 608            err = snd_pcm_hw_params_set_period_size_near (
 609                handle,
 610                hw_params,
 611                &psize,
 612                &dir
 613                );
 614            obt = psize;
 615        }
 616
 617        if (err < 0) {
 618            alsa_logerr2 (err, typ, "Failed to set period %s to %d\n",
 619                          size_in_usec ? "time" : "size", req->period_size);
 620            goto err;
 621        }
 622
 623        if (((req->override_mask & 1) && (obt - req->period_size)))
 624            dolog ("Requested period %s %u was rejected, using %lu\n",
 625                   size_in_usec ? "time" : "size", req->period_size, obt);
 626    }
 627
 628    err = snd_pcm_hw_params (handle, hw_params);
 629    if (err < 0) {
 630        alsa_logerr2 (err, typ, "Failed to apply audio parameters\n");
 631        goto err;
 632    }
 633
 634    err = snd_pcm_hw_params_get_buffer_size (hw_params, &obt_buffer_size);
 635    if (err < 0) {
 636        alsa_logerr2 (err, typ, "Failed to get buffer size\n");
 637        goto err;
 638    }
 639
 640    err = snd_pcm_hw_params_get_format (hw_params, &obtfmt);
 641    if (err < 0) {
 642        alsa_logerr2 (err, typ, "Failed to get format\n");
 643        goto err;
 644    }
 645
 646    if (alsa_to_audfmt (obtfmt, &obt->fmt, &obt->endianness)) {
 647        dolog ("Invalid format was returned %d\n", obtfmt);
 648        goto err;
 649    }
 650
 651    err = snd_pcm_prepare (handle);
 652    if (err < 0) {
 653        alsa_logerr2 (err, typ, "Could not prepare handle %p\n", handle);
 654        goto err;
 655    }
 656
 657    if (!in && conf.threshold) {
 658        snd_pcm_uframes_t threshold;
 659        int bytes_per_sec;
 660
 661        bytes_per_sec = freq << (nchannels == 2);
 662
 663        switch (obt->fmt) {
 664        case AUD_FMT_S8:
 665        case AUD_FMT_U8:
 666            break;
 667
 668        case AUD_FMT_S16:
 669        case AUD_FMT_U16:
 670            bytes_per_sec <<= 1;
 671            break;
 672
 673        case AUD_FMT_S32:
 674        case AUD_FMT_U32:
 675            bytes_per_sec <<= 2;
 676            break;
 677        }
 678
 679        threshold = (conf.threshold * bytes_per_sec) / 1000;
 680        alsa_set_threshold (handle, threshold);
 681    }
 682
 683    obt->nchannels = nchannels;
 684    obt->freq = freq;
 685    obt->samples = obt_buffer_size;
 686
 687    *handlep = handle;
 688
 689    if (conf.verbose &&
 690        (obtfmt != req->fmt ||
 691         obt->nchannels != req->nchannels ||
 692         obt->freq != req->freq)) {
 693        dolog ("Audio parameters for %s\n", typ);
 694        alsa_dump_info (req, obt, obtfmt);
 695    }
 696
 697#ifdef DEBUG
 698    alsa_dump_info (req, obt, obtfmt);
 699#endif
 700    return 0;
 701
 702 err:
 703    alsa_anal_close1 (&handle);
 704    return -1;
 705}
 706
 707static snd_pcm_sframes_t alsa_get_avail (snd_pcm_t *handle)
 708{
 709    snd_pcm_sframes_t avail;
 710
 711    avail = snd_pcm_avail_update (handle);
 712    if (avail < 0) {
 713        if (avail == -EPIPE) {
 714            if (!alsa_recover (handle)) {
 715                avail = snd_pcm_avail_update (handle);
 716            }
 717        }
 718
 719        if (avail < 0) {
 720            alsa_logerr (avail,
 721                         "Could not obtain number of available frames\n");
 722            return -1;
 723        }
 724    }
 725
 726    return avail;
 727}
 728
 729static void alsa_write_pending (ALSAVoiceOut *alsa)
 730{
 731    HWVoiceOut *hw = &alsa->hw;
 732
 733    while (alsa->pending) {
 734        int left_till_end_samples = hw->samples - alsa->wpos;
 735        int len = audio_MIN (alsa->pending, left_till_end_samples);
 736        char *src = advance (alsa->pcm_buf, alsa->wpos << hw->info.shift);
 737
 738        while (len) {
 739            snd_pcm_sframes_t written;
 740
 741            written = snd_pcm_writei (alsa->handle, src, len);
 742
 743            if (written <= 0) {
 744                switch (written) {
 745                case 0:
 746                    if (conf.verbose) {
 747                        dolog ("Failed to write %d frames (wrote zero)\n", len);
 748                    }
 749                    return;
 750
 751                case -EPIPE:
 752                    if (alsa_recover (alsa->handle)) {
 753                        alsa_logerr (written, "Failed to write %d frames\n",
 754                                     len);
 755                        return;
 756                    }
 757                    if (conf.verbose) {
 758                        dolog ("Recovering from playback xrun\n");
 759                    }
 760                    continue;
 761
 762                case -ESTRPIPE:
 763                    /* stream is suspended and waiting for an
 764                       application recovery */
 765                    if (alsa_resume (alsa->handle)) {
 766                        alsa_logerr (written, "Failed to write %d frames\n",
 767                                     len);
 768                        return;
 769                    }
 770                    if (conf.verbose) {
 771                        dolog ("Resuming suspended output stream\n");
 772                    }
 773                    continue;
 774
 775                case -EAGAIN:
 776                    return;
 777
 778                default:
 779                    alsa_logerr (written, "Failed to write %d frames from %p\n",
 780                                 len, src);
 781                    return;
 782                }
 783            }
 784
 785            alsa->wpos = (alsa->wpos + written) % hw->samples;
 786            alsa->pending -= written;
 787            len -= written;
 788        }
 789    }
 790}
 791
 792static int alsa_run_out (HWVoiceOut *hw, int live)
 793{
 794    ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw;
 795    int decr;
 796    snd_pcm_sframes_t avail;
 797
 798    avail = alsa_get_avail (alsa->handle);
 799    if (avail < 0) {
 800        dolog ("Could not get number of available playback frames\n");
 801        return 0;
 802    }
 803
 804    decr = audio_MIN (live, avail);
 805    decr = audio_pcm_hw_clip_out (hw, alsa->pcm_buf, decr, alsa->pending);
 806    alsa->pending += decr;
 807    alsa_write_pending (alsa);
 808    return decr;
 809}
 810
 811static void alsa_fini_out (HWVoiceOut *hw)
 812{
 813    ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw;
 814
 815    ldebug ("alsa_fini\n");
 816    alsa_anal_close (&alsa->handle, &alsa->pollhlp);
 817
 818    if (alsa->pcm_buf) {
 819        g_free (alsa->pcm_buf);
 820        alsa->pcm_buf = NULL;
 821    }
 822}
 823
 824static int alsa_init_out (HWVoiceOut *hw, struct audsettings *as)
 825{
 826    ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw;
 827    struct alsa_params_req req;
 828    struct alsa_params_obt obt;
 829    snd_pcm_t *handle;
 830    struct audsettings obt_as;
 831
 832    req.fmt = aud_to_alsafmt (as->fmt, as->endianness);
 833    req.freq = as->freq;
 834    req.nchannels = as->nchannels;
 835    req.period_size = conf.period_size_out;
 836    req.buffer_size = conf.buffer_size_out;
 837    req.size_in_usec = conf.size_in_usec_out;
 838    req.override_mask =
 839        (conf.period_size_out_overridden ? 1 : 0) |
 840        (conf.buffer_size_out_overridden ? 2 : 0);
 841
 842    if (alsa_open (0, &req, &obt, &handle)) {
 843        return -1;
 844    }
 845
 846    obt_as.freq = obt.freq;
 847    obt_as.nchannels = obt.nchannels;
 848    obt_as.fmt = obt.fmt;
 849    obt_as.endianness = obt.endianness;
 850
 851    audio_pcm_init_info (&hw->info, &obt_as);
 852    hw->samples = obt.samples;
 853
 854    alsa->pcm_buf = audio_calloc (AUDIO_FUNC, obt.samples, 1 << hw->info.shift);
 855    if (!alsa->pcm_buf) {
 856        dolog ("Could not allocate DAC buffer (%d samples, each %d bytes)\n",
 857               hw->samples, 1 << hw->info.shift);
 858        alsa_anal_close1 (&handle);
 859        return -1;
 860    }
 861
 862    alsa->handle = handle;
 863    return 0;
 864}
 865
 866#define VOICE_CTL_PAUSE 0
 867#define VOICE_CTL_PREPARE 1
 868#define VOICE_CTL_START 2
 869
 870static int alsa_voice_ctl (snd_pcm_t *handle, const char *typ, int ctl)
 871{
 872    int err;
 873
 874    if (ctl == VOICE_CTL_PAUSE) {
 875        err = snd_pcm_drop (handle);
 876        if (err < 0) {
 877            alsa_logerr (err, "Could not stop %s\n", typ);
 878            return -1;
 879        }
 880    }
 881    else {
 882        err = snd_pcm_prepare (handle);
 883        if (err < 0) {
 884            alsa_logerr (err, "Could not prepare handle for %s\n", typ);
 885            return -1;
 886        }
 887        if (ctl == VOICE_CTL_START) {
 888            err = snd_pcm_start(handle);
 889            if (err < 0) {
 890                alsa_logerr (err, "Could not start handle for %s\n", typ);
 891                return -1;
 892            }
 893        }
 894    }
 895
 896    return 0;
 897}
 898
 899static int alsa_ctl_out (HWVoiceOut *hw, int cmd, ...)
 900{
 901    ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw;
 902
 903    switch (cmd) {
 904    case VOICE_ENABLE:
 905        {
 906            va_list ap;
 907            int poll_mode;
 908
 909            va_start (ap, cmd);
 910            poll_mode = va_arg (ap, int);
 911            va_end (ap);
 912
 913            ldebug ("enabling voice\n");
 914            if (poll_mode && alsa_poll_out (hw)) {
 915                poll_mode = 0;
 916            }
 917            hw->poll_mode = poll_mode;
 918            return alsa_voice_ctl (alsa->handle, "playback", VOICE_CTL_PREPARE);
 919        }
 920
 921    case VOICE_DISABLE:
 922        ldebug ("disabling voice\n");
 923        if (hw->poll_mode) {
 924            hw->poll_mode = 0;
 925            alsa_fini_poll (&alsa->pollhlp);
 926        }
 927        return alsa_voice_ctl (alsa->handle, "playback", VOICE_CTL_PAUSE);
 928    }
 929
 930    return -1;
 931}
 932
 933static int alsa_init_in (HWVoiceIn *hw, struct audsettings *as)
 934{
 935    ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw;
 936    struct alsa_params_req req;
 937    struct alsa_params_obt obt;
 938    snd_pcm_t *handle;
 939    struct audsettings obt_as;
 940
 941    req.fmt = aud_to_alsafmt (as->fmt, as->endianness);
 942    req.freq = as->freq;
 943    req.nchannels = as->nchannels;
 944    req.period_size = conf.period_size_in;
 945    req.buffer_size = conf.buffer_size_in;
 946    req.size_in_usec = conf.size_in_usec_in;
 947    req.override_mask =
 948        (conf.period_size_in_overridden ? 1 : 0) |
 949        (conf.buffer_size_in_overridden ? 2 : 0);
 950
 951    if (alsa_open (1, &req, &obt, &handle)) {
 952        return -1;
 953    }
 954
 955    obt_as.freq = obt.freq;
 956    obt_as.nchannels = obt.nchannels;
 957    obt_as.fmt = obt.fmt;
 958    obt_as.endianness = obt.endianness;
 959
 960    audio_pcm_init_info (&hw->info, &obt_as);
 961    hw->samples = obt.samples;
 962
 963    alsa->pcm_buf = audio_calloc (AUDIO_FUNC, hw->samples, 1 << hw->info.shift);
 964    if (!alsa->pcm_buf) {
 965        dolog ("Could not allocate ADC buffer (%d samples, each %d bytes)\n",
 966               hw->samples, 1 << hw->info.shift);
 967        alsa_anal_close1 (&handle);
 968        return -1;
 969    }
 970
 971    alsa->handle = handle;
 972    return 0;
 973}
 974
 975static void alsa_fini_in (HWVoiceIn *hw)
 976{
 977    ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw;
 978
 979    alsa_anal_close (&alsa->handle, &alsa->pollhlp);
 980
 981    if (alsa->pcm_buf) {
 982        g_free (alsa->pcm_buf);
 983        alsa->pcm_buf = NULL;
 984    }
 985}
 986
 987static int alsa_run_in (HWVoiceIn *hw)
 988{
 989    ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw;
 990    int hwshift = hw->info.shift;
 991    int i;
 992    int live = audio_pcm_hw_get_live_in (hw);
 993    int dead = hw->samples - live;
 994    int decr;
 995    struct {
 996        int add;
 997        int len;
 998    } bufs[2] = {
 999        { .add = hw->wpos, .len = 0 },
1000        { .add = 0,        .len = 0 }
1001    };
1002    snd_pcm_sframes_t avail;
1003    snd_pcm_uframes_t read_samples = 0;
1004
1005    if (!dead) {
1006        return 0;
1007    }
1008
1009    avail = alsa_get_avail (alsa->handle);
1010    if (avail < 0) {
1011        dolog ("Could not get number of captured frames\n");
1012        return 0;
1013    }
1014
1015    if (!avail) {
1016        snd_pcm_state_t state;
1017
1018        state = snd_pcm_state (alsa->handle);
1019        switch (state) {
1020        case SND_PCM_STATE_PREPARED:
1021            avail = hw->samples;
1022            break;
1023        case SND_PCM_STATE_SUSPENDED:
1024            /* stream is suspended and waiting for an application recovery */
1025            if (alsa_resume (alsa->handle)) {
1026                dolog ("Failed to resume suspended input stream\n");
1027                return 0;
1028            }
1029            if (conf.verbose) {
1030                dolog ("Resuming suspended input stream\n");
1031            }
1032            break;
1033        default:
1034            if (conf.verbose) {
1035                dolog ("No frames available and ALSA state is %d\n", state);
1036            }
1037            return 0;
1038        }
1039    }
1040
1041    decr = audio_MIN (dead, avail);
1042    if (!decr) {
1043        return 0;
1044    }
1045
1046    if (hw->wpos + decr > hw->samples) {
1047        bufs[0].len = (hw->samples - hw->wpos);
1048        bufs[1].len = (decr - (hw->samples - hw->wpos));
1049    }
1050    else {
1051        bufs[0].len = decr;
1052    }
1053
1054    for (i = 0; i < 2; ++i) {
1055        void *src;
1056        struct st_sample *dst;
1057        snd_pcm_sframes_t nread;
1058        snd_pcm_uframes_t len;
1059
1060        len = bufs[i].len;
1061
1062        src = advance (alsa->pcm_buf, bufs[i].add << hwshift);
1063        dst = hw->conv_buf + bufs[i].add;
1064
1065        while (len) {
1066            nread = snd_pcm_readi (alsa->handle, src, len);
1067
1068            if (nread <= 0) {
1069                switch (nread) {
1070                case 0:
1071                    if (conf.verbose) {
1072                        dolog ("Failed to read %ld frames (read zero)\n", len);
1073                    }
1074                    goto exit;
1075
1076                case -EPIPE:
1077                    if (alsa_recover (alsa->handle)) {
1078                        alsa_logerr (nread, "Failed to read %ld frames\n", len);
1079                        goto exit;
1080                    }
1081                    if (conf.verbose) {
1082                        dolog ("Recovering from capture xrun\n");
1083                    }
1084                    continue;
1085
1086                case -EAGAIN:
1087                    goto exit;
1088
1089                default:
1090                    alsa_logerr (
1091                        nread,
1092                        "Failed to read %ld frames from %p\n",
1093                        len,
1094                        src
1095                        );
1096                    goto exit;
1097                }
1098            }
1099
1100            hw->conv (dst, src, nread);
1101
1102            src = advance (src, nread << hwshift);
1103            dst += nread;
1104
1105            read_samples += nread;
1106            len -= nread;
1107        }
1108    }
1109
1110 exit:
1111    hw->wpos = (hw->wpos + read_samples) % hw->samples;
1112    return read_samples;
1113}
1114
1115static int alsa_read (SWVoiceIn *sw, void *buf, int size)
1116{
1117    return audio_pcm_sw_read (sw, buf, size);
1118}
1119
1120static int alsa_ctl_in (HWVoiceIn *hw, int cmd, ...)
1121{
1122    ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw;
1123
1124    switch (cmd) {
1125    case VOICE_ENABLE:
1126        {
1127            va_list ap;
1128            int poll_mode;
1129
1130            va_start (ap, cmd);
1131            poll_mode = va_arg (ap, int);
1132            va_end (ap);
1133
1134            ldebug ("enabling voice\n");
1135            if (poll_mode && alsa_poll_in (hw)) {
1136                poll_mode = 0;
1137            }
1138            hw->poll_mode = poll_mode;
1139
1140            return alsa_voice_ctl (alsa->handle, "capture", VOICE_CTL_START);
1141        }
1142
1143    case VOICE_DISABLE:
1144        ldebug ("disabling voice\n");
1145        if (hw->poll_mode) {
1146            hw->poll_mode = 0;
1147            alsa_fini_poll (&alsa->pollhlp);
1148        }
1149        return alsa_voice_ctl (alsa->handle, "capture", VOICE_CTL_PAUSE);
1150    }
1151
1152    return -1;
1153}
1154
1155static void *alsa_audio_init (void)
1156{
1157    return &conf;
1158}
1159
1160static void alsa_audio_fini (void *opaque)
1161{
1162    (void) opaque;
1163}
1164
1165static struct audio_option alsa_options[] = {
1166    {
1167        .name        = "DAC_SIZE_IN_USEC",
1168        .tag         = AUD_OPT_BOOL,
1169        .valp        = &conf.size_in_usec_out,
1170        .descr       = "DAC period/buffer size in microseconds (otherwise in frames)"
1171    },
1172    {
1173        .name        = "DAC_PERIOD_SIZE",
1174        .tag         = AUD_OPT_INT,
1175        .valp        = &conf.period_size_out,
1176        .descr       = "DAC period size (0 to go with system default)",
1177        .overriddenp = &conf.period_size_out_overridden
1178    },
1179    {
1180        .name        = "DAC_BUFFER_SIZE",
1181        .tag         = AUD_OPT_INT,
1182        .valp        = &conf.buffer_size_out,
1183        .descr       = "DAC buffer size (0 to go with system default)",
1184        .overriddenp = &conf.buffer_size_out_overridden
1185    },
1186    {
1187        .name        = "ADC_SIZE_IN_USEC",
1188        .tag         = AUD_OPT_BOOL,
1189        .valp        = &conf.size_in_usec_in,
1190        .descr       =
1191        "ADC period/buffer size in microseconds (otherwise in frames)"
1192    },
1193    {
1194        .name        = "ADC_PERIOD_SIZE",
1195        .tag         = AUD_OPT_INT,
1196        .valp        = &conf.period_size_in,
1197        .descr       = "ADC period size (0 to go with system default)",
1198        .overriddenp = &conf.period_size_in_overridden
1199    },
1200    {
1201        .name        = "ADC_BUFFER_SIZE",
1202        .tag         = AUD_OPT_INT,
1203        .valp        = &conf.buffer_size_in,
1204        .descr       = "ADC buffer size (0 to go with system default)",
1205        .overriddenp = &conf.buffer_size_in_overridden
1206    },
1207    {
1208        .name        = "THRESHOLD",
1209        .tag         = AUD_OPT_INT,
1210        .valp        = &conf.threshold,
1211        .descr       = "(undocumented)"
1212    },
1213    {
1214        .name        = "DAC_DEV",
1215        .tag         = AUD_OPT_STR,
1216        .valp        = &conf.pcm_name_out,
1217        .descr       = "DAC device name (for instance dmix)"
1218    },
1219    {
1220        .name        = "ADC_DEV",
1221        .tag         = AUD_OPT_STR,
1222        .valp        = &conf.pcm_name_in,
1223        .descr       = "ADC device name"
1224    },
1225    {
1226        .name        = "VERBOSE",
1227        .tag         = AUD_OPT_BOOL,
1228        .valp        = &conf.verbose,
1229        .descr       = "Behave in a more verbose way"
1230    },
1231    { /* End of list */ }
1232};
1233
1234static struct audio_pcm_ops alsa_pcm_ops = {
1235    .init_out = alsa_init_out,
1236    .fini_out = alsa_fini_out,
1237    .run_out  = alsa_run_out,
1238    .write    = alsa_write,
1239    .ctl_out  = alsa_ctl_out,
1240
1241    .init_in  = alsa_init_in,
1242    .fini_in  = alsa_fini_in,
1243    .run_in   = alsa_run_in,
1244    .read     = alsa_read,
1245    .ctl_in   = alsa_ctl_in,
1246};
1247
1248struct audio_driver alsa_audio_driver = {
1249    .name           = "alsa",
1250    .descr          = "ALSA http://www.alsa-project.org",
1251    .options        = alsa_options,
1252    .init           = alsa_audio_init,
1253    .fini           = alsa_audio_fini,
1254    .pcm_ops        = &alsa_pcm_ops,
1255    .can_be_default = 1,
1256    .max_voices_out = INT_MAX,
1257    .max_voices_in  = INT_MAX,
1258    .voice_size_out = sizeof (ALSAVoiceOut),
1259    .voice_size_in  = sizeof (ALSAVoiceIn)
1260};
1261