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 "sysemu/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 "android/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 "android/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
106static void*  alsa_lib;
107
108struct pollhlp {
109    snd_pcm_t *handle;
110    struct pollfd *pfds;
111    int count;
112    int mask;
113};
114
115typedef 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
124typedef struct ALSAVoiceIn {
125    HWVoiceIn hw;
126    snd_pcm_t *handle;
127    void *pcm_buf;
128    struct pollhlp pollhlp;
129} ALSAVoiceIn;
130
131static 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
155struct 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
165struct alsa_params_obt {
166    int freq;
167    audfmt_e fmt;
168    int endianness;
169    int nchannels;
170    snd_pcm_uframes_t samples;
171};
172
173static 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
184static 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
202static 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        g_free (pfds);
212    }
213    hlp->pfds = NULL;
214    hlp->count = 0;
215    hlp->handle = NULL;
216}
217
218static 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
227static void alsa_anal_close (snd_pcm_t **handlep, struct pollhlp *hlp)
228{
229    alsa_fini_poll (hlp);
230    alsa_anal_close1 (handlep);
231}
232
233static 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
243static 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
253static 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
313static 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        g_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            g_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
374static 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
381static 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
388static int alsa_write (SWVoiceOut *sw, void *buf, int len)
389{
390    return audio_pcm_sw_write (sw, buf, len);
391}
392
393static 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
423static 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
485static 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
500static 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
530static 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
760static 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
782static 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
845static 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
864static 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        g_free (alsa->pcm_buf);
873        alsa->pcm_buf = NULL;
874    }
875}
876
877static 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
923Exit:
924    if (!D_ACTIVE)
925        stdio_enable();
926
927    return result;
928}
929
930static 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
952static 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
982static 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
1028Exit:
1029    if (!D_ACTIVE)
1030        stdio_enable();
1031
1032    return result;
1033}
1034
1035static 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        g_free (alsa->pcm_buf);
1043        alsa->pcm_buf = NULL;
1044    }
1045}
1046
1047static 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
1175static int alsa_read (SWVoiceIn *sw, void *buf, int size)
1176{
1177    return audio_pcm_sw_read (sw, buf, size);
1178}
1179
1180static 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
1215static 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
1234Fail:
1235    ldebug("%s: failed to open library\n", __FUNCTION__);
1236    dlclose(alsa_lib);
1237
1238Exit:
1239    return result;
1240}
1241
1242static 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
1251static 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
1320static 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
1334struct 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