]> git.proxmox.com Git - mirror_qemu.git/blob - audio/alsaaudio.c
paaudio: fix playback glitches
[mirror_qemu.git] / 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
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 int alsa_write (SWVoiceOut *sw, void *buf, int len)
274 {
275 return audio_pcm_sw_write (sw, buf, len);
276 }
277
278 static snd_pcm_format_t aud_to_alsafmt (AudioFormat fmt, int endianness)
279 {
280 switch (fmt) {
281 case AUDIO_FORMAT_S8:
282 return SND_PCM_FORMAT_S8;
283
284 case AUDIO_FORMAT_U8:
285 return SND_PCM_FORMAT_U8;
286
287 case AUDIO_FORMAT_S16:
288 if (endianness) {
289 return SND_PCM_FORMAT_S16_BE;
290 }
291 else {
292 return SND_PCM_FORMAT_S16_LE;
293 }
294
295 case AUDIO_FORMAT_U16:
296 if (endianness) {
297 return SND_PCM_FORMAT_U16_BE;
298 }
299 else {
300 return SND_PCM_FORMAT_U16_LE;
301 }
302
303 case AUDIO_FORMAT_S32:
304 if (endianness) {
305 return SND_PCM_FORMAT_S32_BE;
306 }
307 else {
308 return SND_PCM_FORMAT_S32_LE;
309 }
310
311 case AUDIO_FORMAT_U32:
312 if (endianness) {
313 return SND_PCM_FORMAT_U32_BE;
314 }
315 else {
316 return SND_PCM_FORMAT_U32_LE;
317 }
318
319 default:
320 dolog ("Internal logic error: Bad audio format %d\n", fmt);
321 #ifdef DEBUG_AUDIO
322 abort ();
323 #endif
324 return SND_PCM_FORMAT_U8;
325 }
326 }
327
328 static int alsa_to_audfmt (snd_pcm_format_t alsafmt, AudioFormat *fmt,
329 int *endianness)
330 {
331 switch (alsafmt) {
332 case SND_PCM_FORMAT_S8:
333 *endianness = 0;
334 *fmt = AUDIO_FORMAT_S8;
335 break;
336
337 case SND_PCM_FORMAT_U8:
338 *endianness = 0;
339 *fmt = AUDIO_FORMAT_U8;
340 break;
341
342 case SND_PCM_FORMAT_S16_LE:
343 *endianness = 0;
344 *fmt = AUDIO_FORMAT_S16;
345 break;
346
347 case SND_PCM_FORMAT_U16_LE:
348 *endianness = 0;
349 *fmt = AUDIO_FORMAT_U16;
350 break;
351
352 case SND_PCM_FORMAT_S16_BE:
353 *endianness = 1;
354 *fmt = AUDIO_FORMAT_S16;
355 break;
356
357 case SND_PCM_FORMAT_U16_BE:
358 *endianness = 1;
359 *fmt = AUDIO_FORMAT_U16;
360 break;
361
362 case SND_PCM_FORMAT_S32_LE:
363 *endianness = 0;
364 *fmt = AUDIO_FORMAT_S32;
365 break;
366
367 case SND_PCM_FORMAT_U32_LE:
368 *endianness = 0;
369 *fmt = AUDIO_FORMAT_U32;
370 break;
371
372 case SND_PCM_FORMAT_S32_BE:
373 *endianness = 1;
374 *fmt = AUDIO_FORMAT_S32;
375 break;
376
377 case SND_PCM_FORMAT_U32_BE:
378 *endianness = 1;
379 *fmt = AUDIO_FORMAT_U32;
380 break;
381
382 default:
383 dolog ("Unrecognized audio format %d\n", alsafmt);
384 return -1;
385 }
386
387 return 0;
388 }
389
390 static void alsa_dump_info (struct alsa_params_req *req,
391 struct alsa_params_obt *obt,
392 snd_pcm_format_t obtfmt,
393 AudiodevAlsaPerDirectionOptions *apdo)
394 {
395 dolog("parameter | requested value | obtained value\n");
396 dolog("format | %10d | %10d\n", req->fmt, obtfmt);
397 dolog("channels | %10d | %10d\n",
398 req->nchannels, obt->nchannels);
399 dolog("frequency | %10d | %10d\n", req->freq, obt->freq);
400 dolog("============================================\n");
401 dolog("requested: buffer len %" PRId32 " period len %" PRId32 "\n",
402 apdo->buffer_length, apdo->period_length);
403 dolog("obtained: samples %ld\n", obt->samples);
404 }
405
406 static void alsa_set_threshold (snd_pcm_t *handle, snd_pcm_uframes_t threshold)
407 {
408 int err;
409 snd_pcm_sw_params_t *sw_params;
410
411 snd_pcm_sw_params_alloca (&sw_params);
412
413 err = snd_pcm_sw_params_current (handle, sw_params);
414 if (err < 0) {
415 dolog ("Could not fully initialize DAC\n");
416 alsa_logerr (err, "Failed to get current software parameters\n");
417 return;
418 }
419
420 err = snd_pcm_sw_params_set_start_threshold (handle, sw_params, threshold);
421 if (err < 0) {
422 dolog ("Could not fully initialize DAC\n");
423 alsa_logerr (err, "Failed to set software threshold to %ld\n",
424 threshold);
425 return;
426 }
427
428 err = snd_pcm_sw_params (handle, sw_params);
429 if (err < 0) {
430 dolog ("Could not fully initialize DAC\n");
431 alsa_logerr (err, "Failed to set software parameters\n");
432 return;
433 }
434 }
435
436 static int alsa_open(bool in, struct alsa_params_req *req,
437 struct alsa_params_obt *obt, snd_pcm_t **handlep,
438 Audiodev *dev)
439 {
440 AudiodevAlsaOptions *aopts = &dev->u.alsa;
441 AudiodevAlsaPerDirectionOptions *apdo = in ? aopts->in : aopts->out;
442 snd_pcm_t *handle;
443 snd_pcm_hw_params_t *hw_params;
444 int err;
445 unsigned int freq, nchannels;
446 const char *pcm_name = apdo->has_dev ? apdo->dev : "default";
447 snd_pcm_uframes_t obt_buffer_size;
448 const char *typ = in ? "ADC" : "DAC";
449 snd_pcm_format_t obtfmt;
450
451 freq = req->freq;
452 nchannels = req->nchannels;
453
454 snd_pcm_hw_params_alloca (&hw_params);
455
456 err = snd_pcm_open (
457 &handle,
458 pcm_name,
459 in ? SND_PCM_STREAM_CAPTURE : SND_PCM_STREAM_PLAYBACK,
460 SND_PCM_NONBLOCK
461 );
462 if (err < 0) {
463 alsa_logerr2 (err, typ, "Failed to open `%s':\n", pcm_name);
464 return -1;
465 }
466
467 err = snd_pcm_hw_params_any (handle, hw_params);
468 if (err < 0) {
469 alsa_logerr2 (err, typ, "Failed to initialize hardware parameters\n");
470 goto err;
471 }
472
473 err = snd_pcm_hw_params_set_access (
474 handle,
475 hw_params,
476 SND_PCM_ACCESS_RW_INTERLEAVED
477 );
478 if (err < 0) {
479 alsa_logerr2 (err, typ, "Failed to set access type\n");
480 goto err;
481 }
482
483 err = snd_pcm_hw_params_set_format (handle, hw_params, req->fmt);
484 if (err < 0) {
485 alsa_logerr2 (err, typ, "Failed to set format %d\n", req->fmt);
486 }
487
488 err = snd_pcm_hw_params_set_rate_near (handle, hw_params, &freq, 0);
489 if (err < 0) {
490 alsa_logerr2 (err, typ, "Failed to set frequency %d\n", req->freq);
491 goto err;
492 }
493
494 err = snd_pcm_hw_params_set_channels_near (
495 handle,
496 hw_params,
497 &nchannels
498 );
499 if (err < 0) {
500 alsa_logerr2 (err, typ, "Failed to set number of channels %d\n",
501 req->nchannels);
502 goto err;
503 }
504
505 if (nchannels != 1 && nchannels != 2) {
506 alsa_logerr2 (err, typ,
507 "Can not handle obtained number of channels %d\n",
508 nchannels);
509 goto err;
510 }
511
512 if (apdo->buffer_length) {
513 int dir = 0;
514 unsigned int btime = apdo->buffer_length;
515
516 err = snd_pcm_hw_params_set_buffer_time_near(
517 handle, hw_params, &btime, &dir);
518
519 if (err < 0) {
520 alsa_logerr2(err, typ, "Failed to set buffer time to %" PRId32 "\n",
521 apdo->buffer_length);
522 goto err;
523 }
524
525 if (apdo->has_buffer_length && btime != apdo->buffer_length) {
526 dolog("Requested buffer time %" PRId32
527 " was rejected, using %u\n", apdo->buffer_length, btime);
528 }
529 }
530
531 if (apdo->period_length) {
532 int dir = 0;
533 unsigned int ptime = apdo->period_length;
534
535 err = snd_pcm_hw_params_set_period_time_near(handle, hw_params, &ptime,
536 &dir);
537
538 if (err < 0) {
539 alsa_logerr2(err, typ, "Failed to set period time to %" PRId32 "\n",
540 apdo->period_length);
541 goto err;
542 }
543
544 if (apdo->has_period_length && ptime != apdo->period_length) {
545 dolog("Requested period time %" PRId32 " was rejected, using %d\n",
546 apdo->period_length, ptime);
547 }
548 }
549
550 err = snd_pcm_hw_params (handle, hw_params);
551 if (err < 0) {
552 alsa_logerr2 (err, typ, "Failed to apply audio parameters\n");
553 goto err;
554 }
555
556 err = snd_pcm_hw_params_get_buffer_size (hw_params, &obt_buffer_size);
557 if (err < 0) {
558 alsa_logerr2 (err, typ, "Failed to get buffer size\n");
559 goto err;
560 }
561
562 err = snd_pcm_hw_params_get_format (hw_params, &obtfmt);
563 if (err < 0) {
564 alsa_logerr2 (err, typ, "Failed to get format\n");
565 goto err;
566 }
567
568 if (alsa_to_audfmt (obtfmt, &obt->fmt, &obt->endianness)) {
569 dolog ("Invalid format was returned %d\n", obtfmt);
570 goto err;
571 }
572
573 err = snd_pcm_prepare (handle);
574 if (err < 0) {
575 alsa_logerr2 (err, typ, "Could not prepare handle %p\n", handle);
576 goto err;
577 }
578
579 if (!in && aopts->has_threshold && aopts->threshold) {
580 struct audsettings as = { .freq = freq };
581 alsa_set_threshold(
582 handle,
583 audio_buffer_frames(qapi_AudiodevAlsaPerDirectionOptions_base(apdo),
584 &as, aopts->threshold));
585 }
586
587 obt->nchannels = nchannels;
588 obt->freq = freq;
589 obt->samples = obt_buffer_size;
590
591 *handlep = handle;
592
593 if (obtfmt != req->fmt ||
594 obt->nchannels != req->nchannels ||
595 obt->freq != req->freq) {
596 dolog ("Audio parameters for %s\n", typ);
597 alsa_dump_info(req, obt, obtfmt, apdo);
598 }
599
600 #ifdef DEBUG
601 alsa_dump_info(req, obt, obtfmt, pdo);
602 #endif
603 return 0;
604
605 err:
606 alsa_anal_close1 (&handle);
607 return -1;
608 }
609
610 static snd_pcm_sframes_t alsa_get_avail (snd_pcm_t *handle)
611 {
612 snd_pcm_sframes_t avail;
613
614 avail = snd_pcm_avail_update (handle);
615 if (avail < 0) {
616 if (avail == -EPIPE) {
617 if (!alsa_recover (handle)) {
618 avail = snd_pcm_avail_update (handle);
619 }
620 }
621
622 if (avail < 0) {
623 alsa_logerr (avail,
624 "Could not obtain number of available frames\n");
625 return -1;
626 }
627 }
628
629 return avail;
630 }
631
632 static void alsa_write_pending (ALSAVoiceOut *alsa)
633 {
634 HWVoiceOut *hw = &alsa->hw;
635
636 while (alsa->pending) {
637 int left_till_end_samples = hw->samples - alsa->wpos;
638 int len = MIN (alsa->pending, left_till_end_samples);
639 char *src = advance (alsa->pcm_buf, alsa->wpos << hw->info.shift);
640
641 while (len) {
642 snd_pcm_sframes_t written;
643
644 written = snd_pcm_writei (alsa->handle, src, len);
645
646 if (written <= 0) {
647 switch (written) {
648 case 0:
649 trace_alsa_wrote_zero(len);
650 return;
651
652 case -EPIPE:
653 if (alsa_recover (alsa->handle)) {
654 alsa_logerr (written, "Failed to write %d frames\n",
655 len);
656 return;
657 }
658 trace_alsa_xrun_out();
659 continue;
660
661 case -ESTRPIPE:
662 /* stream is suspended and waiting for an
663 application recovery */
664 if (alsa_resume (alsa->handle)) {
665 alsa_logerr (written, "Failed to write %d frames\n",
666 len);
667 return;
668 }
669 trace_alsa_resume_out();
670 continue;
671
672 case -EAGAIN:
673 return;
674
675 default:
676 alsa_logerr (written, "Failed to write %d frames from %p\n",
677 len, src);
678 return;
679 }
680 }
681
682 alsa->wpos = (alsa->wpos + written) % hw->samples;
683 alsa->pending -= written;
684 len -= written;
685 }
686 }
687 }
688
689 static int alsa_run_out (HWVoiceOut *hw, int live)
690 {
691 ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw;
692 int decr;
693 snd_pcm_sframes_t avail;
694
695 avail = alsa_get_avail (alsa->handle);
696 if (avail < 0) {
697 dolog ("Could not get number of available playback frames\n");
698 return 0;
699 }
700
701 decr = MIN (live, avail);
702 decr = audio_pcm_hw_clip_out (hw, alsa->pcm_buf, decr, alsa->pending);
703 alsa->pending += decr;
704 alsa_write_pending (alsa);
705 return decr;
706 }
707
708 static void alsa_fini_out (HWVoiceOut *hw)
709 {
710 ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw;
711
712 ldebug ("alsa_fini\n");
713 alsa_anal_close (&alsa->handle, &alsa->pollhlp);
714
715 g_free(alsa->pcm_buf);
716 alsa->pcm_buf = NULL;
717 }
718
719 static int alsa_init_out(HWVoiceOut *hw, struct audsettings *as,
720 void *drv_opaque)
721 {
722 ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw;
723 struct alsa_params_req req;
724 struct alsa_params_obt obt;
725 snd_pcm_t *handle;
726 struct audsettings obt_as;
727 Audiodev *dev = drv_opaque;
728
729 req.fmt = aud_to_alsafmt (as->fmt, as->endianness);
730 req.freq = as->freq;
731 req.nchannels = as->nchannels;
732
733 if (alsa_open(0, &req, &obt, &handle, dev)) {
734 return -1;
735 }
736
737 obt_as.freq = obt.freq;
738 obt_as.nchannels = obt.nchannels;
739 obt_as.fmt = obt.fmt;
740 obt_as.endianness = obt.endianness;
741
742 audio_pcm_init_info (&hw->info, &obt_as);
743 hw->samples = obt.samples;
744
745 alsa->pcm_buf = audio_calloc(__func__, obt.samples, 1 << hw->info.shift);
746 if (!alsa->pcm_buf) {
747 dolog ("Could not allocate DAC buffer (%d samples, each %d bytes)\n",
748 hw->samples, 1 << hw->info.shift);
749 alsa_anal_close1 (&handle);
750 return -1;
751 }
752
753 alsa->pollhlp.s = hw->s;
754 alsa->handle = handle;
755 alsa->dev = dev;
756 return 0;
757 }
758
759 #define VOICE_CTL_PAUSE 0
760 #define VOICE_CTL_PREPARE 1
761 #define VOICE_CTL_START 2
762
763 static int alsa_voice_ctl (snd_pcm_t *handle, const char *typ, int ctl)
764 {
765 int err;
766
767 if (ctl == VOICE_CTL_PAUSE) {
768 err = snd_pcm_drop (handle);
769 if (err < 0) {
770 alsa_logerr (err, "Could not stop %s\n", typ);
771 return -1;
772 }
773 }
774 else {
775 err = snd_pcm_prepare (handle);
776 if (err < 0) {
777 alsa_logerr (err, "Could not prepare handle for %s\n", typ);
778 return -1;
779 }
780 if (ctl == VOICE_CTL_START) {
781 err = snd_pcm_start(handle);
782 if (err < 0) {
783 alsa_logerr (err, "Could not start handle for %s\n", typ);
784 return -1;
785 }
786 }
787 }
788
789 return 0;
790 }
791
792 static int alsa_ctl_out (HWVoiceOut *hw, int cmd, ...)
793 {
794 ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw;
795 AudiodevAlsaPerDirectionOptions *apdo = alsa->dev->u.alsa.out;
796
797 switch (cmd) {
798 case VOICE_ENABLE:
799 {
800 bool poll_mode = apdo->try_poll;
801
802 ldebug ("enabling voice\n");
803 if (poll_mode && alsa_poll_out (hw)) {
804 poll_mode = 0;
805 }
806 hw->poll_mode = poll_mode;
807 return alsa_voice_ctl (alsa->handle, "playback", VOICE_CTL_PREPARE);
808 }
809
810 case VOICE_DISABLE:
811 ldebug ("disabling voice\n");
812 if (hw->poll_mode) {
813 hw->poll_mode = 0;
814 alsa_fini_poll (&alsa->pollhlp);
815 }
816 return alsa_voice_ctl (alsa->handle, "playback", VOICE_CTL_PAUSE);
817 }
818
819 return -1;
820 }
821
822 static int alsa_init_in(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque)
823 {
824 ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw;
825 struct alsa_params_req req;
826 struct alsa_params_obt obt;
827 snd_pcm_t *handle;
828 struct audsettings obt_as;
829 Audiodev *dev = drv_opaque;
830
831 req.fmt = aud_to_alsafmt (as->fmt, as->endianness);
832 req.freq = as->freq;
833 req.nchannels = as->nchannels;
834
835 if (alsa_open(1, &req, &obt, &handle, dev)) {
836 return -1;
837 }
838
839 obt_as.freq = obt.freq;
840 obt_as.nchannels = obt.nchannels;
841 obt_as.fmt = obt.fmt;
842 obt_as.endianness = obt.endianness;
843
844 audio_pcm_init_info (&hw->info, &obt_as);
845 hw->samples = obt.samples;
846
847 alsa->pcm_buf = audio_calloc(__func__, hw->samples, 1 << hw->info.shift);
848 if (!alsa->pcm_buf) {
849 dolog ("Could not allocate ADC buffer (%d samples, each %d bytes)\n",
850 hw->samples, 1 << hw->info.shift);
851 alsa_anal_close1 (&handle);
852 return -1;
853 }
854
855 alsa->pollhlp.s = hw->s;
856 alsa->handle = handle;
857 alsa->dev = dev;
858 return 0;
859 }
860
861 static void alsa_fini_in (HWVoiceIn *hw)
862 {
863 ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw;
864
865 alsa_anal_close (&alsa->handle, &alsa->pollhlp);
866
867 g_free(alsa->pcm_buf);
868 alsa->pcm_buf = NULL;
869 }
870
871 static int alsa_run_in (HWVoiceIn *hw)
872 {
873 ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw;
874 int hwshift = hw->info.shift;
875 int i;
876 int live = audio_pcm_hw_get_live_in (hw);
877 int dead = hw->samples - live;
878 int decr;
879 struct {
880 int add;
881 int len;
882 } bufs[2] = {
883 { .add = hw->wpos, .len = 0 },
884 { .add = 0, .len = 0 }
885 };
886 snd_pcm_sframes_t avail;
887 snd_pcm_uframes_t read_samples = 0;
888
889 if (!dead) {
890 return 0;
891 }
892
893 avail = alsa_get_avail (alsa->handle);
894 if (avail < 0) {
895 dolog ("Could not get number of captured frames\n");
896 return 0;
897 }
898
899 if (!avail) {
900 snd_pcm_state_t state;
901
902 state = snd_pcm_state (alsa->handle);
903 switch (state) {
904 case SND_PCM_STATE_PREPARED:
905 avail = hw->samples;
906 break;
907 case SND_PCM_STATE_SUSPENDED:
908 /* stream is suspended and waiting for an application recovery */
909 if (alsa_resume (alsa->handle)) {
910 dolog ("Failed to resume suspended input stream\n");
911 return 0;
912 }
913 trace_alsa_resume_in();
914 break;
915 default:
916 trace_alsa_no_frames(state);
917 return 0;
918 }
919 }
920
921 decr = MIN (dead, avail);
922 if (!decr) {
923 return 0;
924 }
925
926 if (hw->wpos + decr > hw->samples) {
927 bufs[0].len = (hw->samples - hw->wpos);
928 bufs[1].len = (decr - (hw->samples - hw->wpos));
929 }
930 else {
931 bufs[0].len = decr;
932 }
933
934 for (i = 0; i < 2; ++i) {
935 void *src;
936 struct st_sample *dst;
937 snd_pcm_sframes_t nread;
938 snd_pcm_uframes_t len;
939
940 len = bufs[i].len;
941
942 src = advance (alsa->pcm_buf, bufs[i].add << hwshift);
943 dst = hw->conv_buf + bufs[i].add;
944
945 while (len) {
946 nread = snd_pcm_readi (alsa->handle, src, len);
947
948 if (nread <= 0) {
949 switch (nread) {
950 case 0:
951 trace_alsa_read_zero(len);
952 goto exit;
953
954 case -EPIPE:
955 if (alsa_recover (alsa->handle)) {
956 alsa_logerr (nread, "Failed to read %ld frames\n", len);
957 goto exit;
958 }
959 trace_alsa_xrun_in();
960 continue;
961
962 case -EAGAIN:
963 goto exit;
964
965 default:
966 alsa_logerr (
967 nread,
968 "Failed to read %ld frames from %p\n",
969 len,
970 src
971 );
972 goto exit;
973 }
974 }
975
976 hw->conv (dst, src, nread);
977
978 src = advance (src, nread << hwshift);
979 dst += nread;
980
981 read_samples += nread;
982 len -= nread;
983 }
984 }
985
986 exit:
987 hw->wpos = (hw->wpos + read_samples) % hw->samples;
988 return read_samples;
989 }
990
991 static int alsa_read (SWVoiceIn *sw, void *buf, int size)
992 {
993 return audio_pcm_sw_read (sw, buf, size);
994 }
995
996 static int alsa_ctl_in (HWVoiceIn *hw, int cmd, ...)
997 {
998 ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw;
999 AudiodevAlsaPerDirectionOptions *apdo = alsa->dev->u.alsa.in;
1000
1001 switch (cmd) {
1002 case VOICE_ENABLE:
1003 {
1004 bool poll_mode = apdo->try_poll;
1005
1006 ldebug ("enabling voice\n");
1007 if (poll_mode && alsa_poll_in (hw)) {
1008 poll_mode = 0;
1009 }
1010 hw->poll_mode = poll_mode;
1011
1012 return alsa_voice_ctl (alsa->handle, "capture", VOICE_CTL_START);
1013 }
1014
1015 case VOICE_DISABLE:
1016 ldebug ("disabling voice\n");
1017 if (hw->poll_mode) {
1018 hw->poll_mode = 0;
1019 alsa_fini_poll (&alsa->pollhlp);
1020 }
1021 return alsa_voice_ctl (alsa->handle, "capture", VOICE_CTL_PAUSE);
1022 }
1023
1024 return -1;
1025 }
1026
1027 static void alsa_init_per_direction(AudiodevAlsaPerDirectionOptions *apdo)
1028 {
1029 if (!apdo->has_try_poll) {
1030 apdo->try_poll = true;
1031 apdo->has_try_poll = true;
1032 }
1033 }
1034
1035 static void *alsa_audio_init(Audiodev *dev)
1036 {
1037 AudiodevAlsaOptions *aopts;
1038 assert(dev->driver == AUDIODEV_DRIVER_ALSA);
1039
1040 aopts = &dev->u.alsa;
1041 alsa_init_per_direction(aopts->in);
1042 alsa_init_per_direction(aopts->out);
1043
1044 /*
1045 * need to define them, as otherwise alsa produces no sound
1046 * doesn't set has_* so alsa_open can identify it wasn't set by the user
1047 */
1048 if (!dev->u.alsa.out->has_period_length) {
1049 /* 1024 frames assuming 44100Hz */
1050 dev->u.alsa.out->period_length = 1024 * 1000000 / 44100;
1051 }
1052 if (!dev->u.alsa.out->has_buffer_length) {
1053 /* 4096 frames assuming 44100Hz */
1054 dev->u.alsa.out->buffer_length = 4096ll * 1000000 / 44100;
1055 }
1056
1057 /*
1058 * OptsVisitor sets unspecified optional fields to zero, but do not depend
1059 * on it...
1060 */
1061 if (!dev->u.alsa.in->has_period_length) {
1062 dev->u.alsa.in->period_length = 0;
1063 }
1064 if (!dev->u.alsa.in->has_buffer_length) {
1065 dev->u.alsa.in->buffer_length = 0;
1066 }
1067
1068 return dev;
1069 }
1070
1071 static void alsa_audio_fini (void *opaque)
1072 {
1073 }
1074
1075 static struct audio_pcm_ops alsa_pcm_ops = {
1076 .init_out = alsa_init_out,
1077 .fini_out = alsa_fini_out,
1078 .run_out = alsa_run_out,
1079 .write = alsa_write,
1080 .ctl_out = alsa_ctl_out,
1081
1082 .init_in = alsa_init_in,
1083 .fini_in = alsa_fini_in,
1084 .run_in = alsa_run_in,
1085 .read = alsa_read,
1086 .ctl_in = alsa_ctl_in,
1087 };
1088
1089 static struct audio_driver alsa_audio_driver = {
1090 .name = "alsa",
1091 .descr = "ALSA http://www.alsa-project.org",
1092 .init = alsa_audio_init,
1093 .fini = alsa_audio_fini,
1094 .pcm_ops = &alsa_pcm_ops,
1095 .can_be_default = 1,
1096 .max_voices_out = INT_MAX,
1097 .max_voices_in = INT_MAX,
1098 .voice_size_out = sizeof (ALSAVoiceOut),
1099 .voice_size_in = sizeof (ALSAVoiceIn)
1100 };
1101
1102 static void register_audio_alsa(void)
1103 {
1104 audio_driver_register(&alsa_audio_driver);
1105 }
1106 type_init(register_audio_alsa);