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