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