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