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