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    g_free(alsa->pcm_buf);
 819    alsa->pcm_buf = NULL;
 820}
 821
 822static int alsa_init_out (HWVoiceOut *hw, struct audsettings *as)
 823{
 824    ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw;
 825    struct alsa_params_req req;
 826    struct alsa_params_obt obt;
 827    snd_pcm_t *handle;
 828    struct audsettings obt_as;
 829
 830    req.fmt = aud_to_alsafmt (as->fmt, as->endianness);
 831    req.freq = as->freq;
 832    req.nchannels = as->nchannels;
 833    req.period_size = conf.period_size_out;
 834    req.buffer_size = conf.buffer_size_out;
 835    req.size_in_usec = conf.size_in_usec_out;
 836    req.override_mask =
 837        (conf.period_size_out_overridden ? 1 : 0) |
 838        (conf.buffer_size_out_overridden ? 2 : 0);
 839
 840    if (alsa_open (0, &req, &obt, &handle)) {
 841        return -1;
 842    }
 843
 844    obt_as.freq = obt.freq;
 845    obt_as.nchannels = obt.nchannels;
 846    obt_as.fmt = obt.fmt;
 847    obt_as.endianness = obt.endianness;
 848
 849    audio_pcm_init_info (&hw->info, &obt_as);
 850    hw->samples = obt.samples;
 851
 852    alsa->pcm_buf = audio_calloc (AUDIO_FUNC, obt.samples, 1 << hw->info.shift);
 853    if (!alsa->pcm_buf) {
 854        dolog ("Could not allocate DAC buffer (%d samples, each %d bytes)\n",
 855               hw->samples, 1 << hw->info.shift);
 856        alsa_anal_close1 (&handle);
 857        return -1;
 858    }
 859
 860    alsa->handle = handle;
 861    return 0;
 862}
 863
 864#define VOICE_CTL_PAUSE 0
 865#define VOICE_CTL_PREPARE 1
 866#define VOICE_CTL_START 2
 867
 868static int alsa_voice_ctl (snd_pcm_t *handle, const char *typ, int ctl)
 869{
 870    int err;
 871
 872    if (ctl == VOICE_CTL_PAUSE) {
 873        err = snd_pcm_drop (handle);
 874        if (err < 0) {
 875            alsa_logerr (err, "Could not stop %s\n", typ);
 876            return -1;
 877        }
 878    }
 879    else {
 880        err = snd_pcm_prepare (handle);
 881        if (err < 0) {
 882            alsa_logerr (err, "Could not prepare handle for %s\n", typ);
 883            return -1;
 884        }
 885        if (ctl == VOICE_CTL_START) {
 886            err = snd_pcm_start(handle);
 887            if (err < 0) {
 888                alsa_logerr (err, "Could not start handle for %s\n", typ);
 889                return -1;
 890            }
 891        }
 892    }
 893
 894    return 0;
 895}
 896
 897static int alsa_ctl_out (HWVoiceOut *hw, int cmd, ...)
 898{
 899    ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw;
 900
 901    switch (cmd) {
 902    case VOICE_ENABLE:
 903        {
 904            va_list ap;
 905            int poll_mode;
 906
 907            va_start (ap, cmd);
 908            poll_mode = va_arg (ap, int);
 909            va_end (ap);
 910
 911            ldebug ("enabling voice\n");
 912            if (poll_mode && alsa_poll_out (hw)) {
 913                poll_mode = 0;
 914            }
 915            hw->poll_mode = poll_mode;
 916            return alsa_voice_ctl (alsa->handle, "playback", VOICE_CTL_PREPARE);
 917        }
 918
 919    case VOICE_DISABLE:
 920        ldebug ("disabling voice\n");
 921        if (hw->poll_mode) {
 922            hw->poll_mode = 0;
 923            alsa_fini_poll (&alsa->pollhlp);
 924        }
 925        return alsa_voice_ctl (alsa->handle, "playback", VOICE_CTL_PAUSE);
 926    }
 927
 928    return -1;
 929}
 930
 931static int alsa_init_in (HWVoiceIn *hw, struct audsettings *as)
 932{
 933    ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw;
 934    struct alsa_params_req req;
 935    struct alsa_params_obt obt;
 936    snd_pcm_t *handle;
 937    struct audsettings obt_as;
 938
 939    req.fmt = aud_to_alsafmt (as->fmt, as->endianness);
 940    req.freq = as->freq;
 941    req.nchannels = as->nchannels;
 942    req.period_size = conf.period_size_in;
 943    req.buffer_size = conf.buffer_size_in;
 944    req.size_in_usec = conf.size_in_usec_in;
 945    req.override_mask =
 946        (conf.period_size_in_overridden ? 1 : 0) |
 947        (conf.buffer_size_in_overridden ? 2 : 0);
 948
 949    if (alsa_open (1, &req, &obt, &handle)) {
 950        return -1;
 951    }
 952
 953    obt_as.freq = obt.freq;
 954    obt_as.nchannels = obt.nchannels;
 955    obt_as.fmt = obt.fmt;
 956    obt_as.endianness = obt.endianness;
 957
 958    audio_pcm_init_info (&hw->info, &obt_as);
 959    hw->samples = obt.samples;
 960
 961    alsa->pcm_buf = audio_calloc (AUDIO_FUNC, hw->samples, 1 << hw->info.shift);
 962    if (!alsa->pcm_buf) {
 963        dolog ("Could not allocate ADC buffer (%d samples, each %d bytes)\n",
 964               hw->samples, 1 << hw->info.shift);
 965        alsa_anal_close1 (&handle);
 966        return -1;
 967    }
 968
 969    alsa->handle = handle;
 970    return 0;
 971}
 972
 973static void alsa_fini_in (HWVoiceIn *hw)
 974{
 975    ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw;
 976
 977    alsa_anal_close (&alsa->handle, &alsa->pollhlp);
 978
 979    g_free(alsa->pcm_buf);
 980    alsa->pcm_buf = NULL;
 981}
 982
 983static int alsa_run_in (HWVoiceIn *hw)
 984{
 985    ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw;
 986    int hwshift = hw->info.shift;
 987    int i;
 988    int live = audio_pcm_hw_get_live_in (hw);
 989    int dead = hw->samples - live;
 990    int decr;
 991    struct {
 992        int add;
 993        int len;
 994    } bufs[2] = {
 995        { .add = hw->wpos, .len = 0 },
 996        { .add = 0,        .len = 0 }
 997    };
 998    snd_pcm_sframes_t avail;
 999    snd_pcm_uframes_t read_samples = 0;
1000
1001    if (!dead) {
1002        return 0;
1003    }
1004
1005    avail = alsa_get_avail (alsa->handle);
1006    if (avail < 0) {
1007        dolog ("Could not get number of captured frames\n");
1008        return 0;
1009    }
1010
1011    if (!avail) {
1012        snd_pcm_state_t state;
1013
1014        state = snd_pcm_state (alsa->handle);
1015        switch (state) {
1016        case SND_PCM_STATE_PREPARED:
1017            avail = hw->samples;
1018            break;
1019        case SND_PCM_STATE_SUSPENDED:
1020            /* stream is suspended and waiting for an application recovery */
1021            if (alsa_resume (alsa->handle)) {
1022                dolog ("Failed to resume suspended input stream\n");
1023                return 0;
1024            }
1025            if (conf.verbose) {
1026                dolog ("Resuming suspended input stream\n");
1027            }
1028            break;
1029        default:
1030            if (conf.verbose) {
1031                dolog ("No frames available and ALSA state is %d\n", state);
1032            }
1033            return 0;
1034        }
1035    }
1036
1037    decr = audio_MIN (dead, avail);
1038    if (!decr) {
1039        return 0;
1040    }
1041
1042    if (hw->wpos + decr > hw->samples) {
1043        bufs[0].len = (hw->samples - hw->wpos);
1044        bufs[1].len = (decr - (hw->samples - hw->wpos));
1045    }
1046    else {
1047        bufs[0].len = decr;
1048    }
1049
1050    for (i = 0; i < 2; ++i) {
1051        void *src;
1052        struct st_sample *dst;
1053        snd_pcm_sframes_t nread;
1054        snd_pcm_uframes_t len;
1055
1056        len = bufs[i].len;
1057
1058        src = advance (alsa->pcm_buf, bufs[i].add << hwshift);
1059        dst = hw->conv_buf + bufs[i].add;
1060
1061        while (len) {
1062            nread = snd_pcm_readi (alsa->handle, src, len);
1063
1064            if (nread <= 0) {
1065                switch (nread) {
1066                case 0:
1067                    if (conf.verbose) {
1068                        dolog ("Failed to read %ld frames (read zero)\n", len);
1069                    }
1070                    goto exit;
1071
1072                case -EPIPE:
1073                    if (alsa_recover (alsa->handle)) {
1074                        alsa_logerr (nread, "Failed to read %ld frames\n", len);
1075                        goto exit;
1076                    }
1077                    if (conf.verbose) {
1078                        dolog ("Recovering from capture xrun\n");
1079                    }
1080                    continue;
1081
1082                case -EAGAIN:
1083                    goto exit;
1084
1085                default:
1086                    alsa_logerr (
1087                        nread,
1088                        "Failed to read %ld frames from %p\n",
1089                        len,
1090                        src
1091                        );
1092                    goto exit;
1093                }
1094            }
1095
1096            hw->conv (dst, src, nread);
1097
1098            src = advance (src, nread << hwshift);
1099            dst += nread;
1100
1101            read_samples += nread;
1102            len -= nread;
1103        }
1104    }
1105
1106 exit:
1107    hw->wpos = (hw->wpos + read_samples) % hw->samples;
1108    return read_samples;
1109}
1110
1111static int alsa_read (SWVoiceIn *sw, void *buf, int size)
1112{
1113    return audio_pcm_sw_read (sw, buf, size);
1114}
1115
1116static int alsa_ctl_in (HWVoiceIn *hw, int cmd, ...)
1117{
1118    ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw;
1119
1120    switch (cmd) {
1121    case VOICE_ENABLE:
1122        {
1123            va_list ap;
1124            int poll_mode;
1125
1126            va_start (ap, cmd);
1127            poll_mode = va_arg (ap, int);
1128            va_end (ap);
1129
1130            ldebug ("enabling voice\n");
1131            if (poll_mode && alsa_poll_in (hw)) {
1132                poll_mode = 0;
1133            }
1134            hw->poll_mode = poll_mode;
1135
1136            return alsa_voice_ctl (alsa->handle, "capture", VOICE_CTL_START);
1137        }
1138
1139    case VOICE_DISABLE:
1140        ldebug ("disabling voice\n");
1141        if (hw->poll_mode) {
1142            hw->poll_mode = 0;
1143            alsa_fini_poll (&alsa->pollhlp);
1144        }
1145        return alsa_voice_ctl (alsa->handle, "capture", VOICE_CTL_PAUSE);
1146    }
1147
1148    return -1;
1149}
1150
1151static void *alsa_audio_init (void)
1152{
1153    return &conf;
1154}
1155
1156static void alsa_audio_fini (void *opaque)
1157{
1158    (void) opaque;
1159}
1160
1161static struct audio_option alsa_options[] = {
1162    {
1163        .name        = "DAC_SIZE_IN_USEC",
1164        .tag         = AUD_OPT_BOOL,
1165        .valp        = &conf.size_in_usec_out,
1166        .descr       = "DAC period/buffer size in microseconds (otherwise in frames)"
1167    },
1168    {
1169        .name        = "DAC_PERIOD_SIZE",
1170        .tag         = AUD_OPT_INT,
1171        .valp        = &conf.period_size_out,
1172        .descr       = "DAC period size (0 to go with system default)",
1173        .overriddenp = &conf.period_size_out_overridden
1174    },
1175    {
1176        .name        = "DAC_BUFFER_SIZE",
1177        .tag         = AUD_OPT_INT,
1178        .valp        = &conf.buffer_size_out,
1179        .descr       = "DAC buffer size (0 to go with system default)",
1180        .overriddenp = &conf.buffer_size_out_overridden
1181    },
1182    {
1183        .name        = "ADC_SIZE_IN_USEC",
1184        .tag         = AUD_OPT_BOOL,
1185        .valp        = &conf.size_in_usec_in,
1186        .descr       =
1187        "ADC period/buffer size in microseconds (otherwise in frames)"
1188    },
1189    {
1190        .name        = "ADC_PERIOD_SIZE",
1191        .tag         = AUD_OPT_INT,
1192        .valp        = &conf.period_size_in,
1193        .descr       = "ADC period size (0 to go with system default)",
1194        .overriddenp = &conf.period_size_in_overridden
1195    },
1196    {
1197        .name        = "ADC_BUFFER_SIZE",
1198        .tag         = AUD_OPT_INT,
1199        .valp        = &conf.buffer_size_in,
1200        .descr       = "ADC buffer size (0 to go with system default)",
1201        .overriddenp = &conf.buffer_size_in_overridden
1202    },
1203    {
1204        .name        = "THRESHOLD",
1205        .tag         = AUD_OPT_INT,
1206        .valp        = &conf.threshold,
1207        .descr       = "(undocumented)"
1208    },
1209    {
1210        .name        = "DAC_DEV",
1211        .tag         = AUD_OPT_STR,
1212        .valp        = &conf.pcm_name_out,
1213        .descr       = "DAC device name (for instance dmix)"
1214    },
1215    {
1216        .name        = "ADC_DEV",
1217        .tag         = AUD_OPT_STR,
1218        .valp        = &conf.pcm_name_in,
1219        .descr       = "ADC device name"
1220    },
1221    {
1222        .name        = "VERBOSE",
1223        .tag         = AUD_OPT_BOOL,
1224        .valp        = &conf.verbose,
1225        .descr       = "Behave in a more verbose way"
1226    },
1227    { /* End of list */ }
1228};
1229
1230static struct audio_pcm_ops alsa_pcm_ops = {
1231    .init_out = alsa_init_out,
1232    .fini_out = alsa_fini_out,
1233    .run_out  = alsa_run_out,
1234    .write    = alsa_write,
1235    .ctl_out  = alsa_ctl_out,
1236
1237    .init_in  = alsa_init_in,
1238    .fini_in  = alsa_fini_in,
1239    .run_in   = alsa_run_in,
1240    .read     = alsa_read,
1241    .ctl_in   = alsa_ctl_in,
1242};
1243
1244struct audio_driver alsa_audio_driver = {
1245    .name           = "alsa",
1246    .descr          = "ALSA http://www.alsa-project.org",
1247    .options        = alsa_options,
1248    .init           = alsa_audio_init,
1249    .fini           = alsa_audio_fini,
1250    .pcm_ops        = &alsa_pcm_ops,
1251    .can_be_default = 1,
1252    .max_voices_out = INT_MAX,
1253    .max_voices_in  = INT_MAX,
1254    .voice_size_out = sizeof (ALSAVoiceOut),
1255    .voice_size_in  = sizeof (ALSAVoiceIn)
1256};
1257