split away drive init from ide_init2()
[qemu.git] / audio / alsaaudio.c
blob3fb6cbd41a1b1f55a6bcf639b88f8c4269efe67b
1 /*
2 * QEMU ALSA audio driver
4 * Copyright (c) 2005 Vassili Karpov (malc)
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:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
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.
24 #include <alsa/asoundlib.h>
25 #include "qemu-common.h"
26 #include "qemu-char.h"
27 #include "audio.h"
29 #if QEMU_GNUC_PREREQ(4, 3)
30 #pragma GCC diagnostic ignored "-Waddress"
31 #endif
33 #define AUDIO_CAP "alsa"
34 #include "audio_int.h"
36 struct pollhlp {
37 snd_pcm_t *handle;
38 struct pollfd *pfds;
39 int count;
40 int mask;
43 typedef struct ALSAVoiceOut {
44 HWVoiceOut hw;
45 void *pcm_buf;
46 snd_pcm_t *handle;
47 struct pollhlp pollhlp;
48 } ALSAVoiceOut;
50 typedef struct ALSAVoiceIn {
51 HWVoiceIn hw;
52 snd_pcm_t *handle;
53 void *pcm_buf;
54 struct pollhlp pollhlp;
55 } ALSAVoiceIn;
57 static struct {
58 int size_in_usec_in;
59 int size_in_usec_out;
60 const char *pcm_name_in;
61 const char *pcm_name_out;
62 unsigned int buffer_size_in;
63 unsigned int period_size_in;
64 unsigned int buffer_size_out;
65 unsigned int period_size_out;
66 unsigned int threshold;
68 int buffer_size_in_overridden;
69 int period_size_in_overridden;
71 int buffer_size_out_overridden;
72 int period_size_out_overridden;
73 int verbose;
74 } conf = {
75 .buffer_size_out = 1024,
76 .pcm_name_out = "default",
77 .pcm_name_in = "default",
80 struct alsa_params_req {
81 int freq;
82 snd_pcm_format_t fmt;
83 int nchannels;
84 int size_in_usec;
85 int override_mask;
86 unsigned int buffer_size;
87 unsigned int period_size;
90 struct alsa_params_obt {
91 int freq;
92 audfmt_e fmt;
93 int endianness;
94 int nchannels;
95 snd_pcm_uframes_t samples;
98 static void GCC_FMT_ATTR (2, 3) alsa_logerr (int err, const char *fmt, ...)
100 va_list ap;
102 va_start (ap, fmt);
103 AUD_vlog (AUDIO_CAP, fmt, ap);
104 va_end (ap);
106 AUD_log (AUDIO_CAP, "Reason: %s\n", snd_strerror (err));
109 static void GCC_FMT_ATTR (3, 4) alsa_logerr2 (
110 int err,
111 const char *typ,
112 const char *fmt,
116 va_list ap;
118 AUD_log (AUDIO_CAP, "Could not initialize %s\n", typ);
120 va_start (ap, fmt);
121 AUD_vlog (AUDIO_CAP, fmt, ap);
122 va_end (ap);
124 AUD_log (AUDIO_CAP, "Reason: %s\n", snd_strerror (err));
127 static void alsa_fini_poll (struct pollhlp *hlp)
129 int i;
130 struct pollfd *pfds = hlp->pfds;
132 if (pfds) {
133 for (i = 0; i < hlp->count; ++i) {
134 qemu_set_fd_handler (pfds[i].fd, NULL, NULL, NULL);
136 qemu_free (pfds);
138 hlp->pfds = NULL;
139 hlp->count = 0;
140 hlp->handle = NULL;
143 static void alsa_anal_close1 (snd_pcm_t **handlep)
145 int err = snd_pcm_close (*handlep);
146 if (err) {
147 alsa_logerr (err, "Failed to close PCM handle %p\n", *handlep);
149 *handlep = NULL;
152 static void alsa_anal_close (snd_pcm_t **handlep, struct pollhlp *hlp)
154 alsa_fini_poll (hlp);
155 alsa_anal_close1 (handlep);
158 static int alsa_recover (snd_pcm_t *handle)
160 int err = snd_pcm_prepare (handle);
161 if (err < 0) {
162 alsa_logerr (err, "Failed to prepare handle %p\n", handle);
163 return -1;
165 return 0;
168 static int alsa_resume (snd_pcm_t *handle)
170 int err = snd_pcm_resume (handle);
171 if (err < 0) {
172 alsa_logerr (err, "Failed to resume handle %p\n", handle);
173 return -1;
175 return 0;
178 static void alsa_poll_handler (void *opaque)
180 int err, count;
181 snd_pcm_state_t state;
182 struct pollhlp *hlp = opaque;
183 unsigned short revents;
185 count = poll (hlp->pfds, hlp->count, 0);
186 if (count < 0) {
187 dolog ("alsa_poll_handler: poll %s\n", strerror (errno));
188 return;
191 if (!count) {
192 return;
195 /* XXX: ALSA example uses initial count, not the one returned by
196 poll, correct? */
197 err = snd_pcm_poll_descriptors_revents (hlp->handle, hlp->pfds,
198 hlp->count, &revents);
199 if (err < 0) {
200 alsa_logerr (err, "snd_pcm_poll_descriptors_revents");
201 return;
204 if (!(revents & hlp->mask)) {
205 if (conf.verbose) {
206 dolog ("revents = %d\n", revents);
208 return;
211 state = snd_pcm_state (hlp->handle);
212 switch (state) {
213 case SND_PCM_STATE_XRUN:
214 alsa_recover (hlp->handle);
215 break;
217 case SND_PCM_STATE_SUSPENDED:
218 alsa_resume (hlp->handle);
219 break;
221 case SND_PCM_STATE_PREPARED:
222 audio_run ("alsa run (prepared)");
223 break;
225 case SND_PCM_STATE_RUNNING:
226 audio_run ("alsa run (running)");
227 break;
229 default:
230 dolog ("Unexpected state %d\n", state);
234 static int alsa_poll_helper (snd_pcm_t *handle, struct pollhlp *hlp, int mask)
236 int i, count, err;
237 struct pollfd *pfds;
239 count = snd_pcm_poll_descriptors_count (handle);
240 if (count <= 0) {
241 dolog ("Could not initialize poll mode\n"
242 "Invalid number of poll descriptors %d\n", count);
243 return -1;
246 pfds = audio_calloc ("alsa_poll_helper", count, sizeof (*pfds));
247 if (!pfds) {
248 dolog ("Could not initialize poll mode\n");
249 return -1;
252 err = snd_pcm_poll_descriptors (handle, pfds, count);
253 if (err < 0) {
254 alsa_logerr (err, "Could not initialize poll mode\n"
255 "Could not obtain poll descriptors\n");
256 qemu_free (pfds);
257 return -1;
260 for (i = 0; i < count; ++i) {
261 if (pfds[i].events & POLLIN) {
262 err = qemu_set_fd_handler (pfds[i].fd, alsa_poll_handler,
263 NULL, hlp);
265 if (pfds[i].events & POLLOUT) {
266 if (conf.verbose) {
267 dolog ("POLLOUT %d %d\n", i, pfds[i].fd);
269 err = qemu_set_fd_handler (pfds[i].fd, NULL,
270 alsa_poll_handler, hlp);
272 if (conf.verbose) {
273 dolog ("Set handler events=%#x index=%d fd=%d err=%d\n",
274 pfds[i].events, i, pfds[i].fd, err);
277 if (err) {
278 dolog ("Failed to set handler events=%#x index=%d fd=%d err=%d\n",
279 pfds[i].events, i, pfds[i].fd, err);
281 while (i--) {
282 qemu_set_fd_handler (pfds[i].fd, NULL, NULL, NULL);
284 qemu_free (pfds);
285 return -1;
288 hlp->pfds = pfds;
289 hlp->count = count;
290 hlp->handle = handle;
291 hlp->mask = mask;
292 return 0;
295 static int alsa_poll_out (HWVoiceOut *hw)
297 ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw;
299 return alsa_poll_helper (alsa->handle, &alsa->pollhlp, POLLOUT);
302 static int alsa_poll_in (HWVoiceIn *hw)
304 ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw;
306 return alsa_poll_helper (alsa->handle, &alsa->pollhlp, POLLIN);
309 static int alsa_write (SWVoiceOut *sw, void *buf, int len)
311 return audio_pcm_sw_write (sw, buf, len);
314 static snd_pcm_format_t aud_to_alsafmt (audfmt_e fmt)
316 switch (fmt) {
317 case AUD_FMT_S8:
318 return SND_PCM_FORMAT_S8;
320 case AUD_FMT_U8:
321 return SND_PCM_FORMAT_U8;
323 case AUD_FMT_S16:
324 return SND_PCM_FORMAT_S16_LE;
326 case AUD_FMT_U16:
327 return SND_PCM_FORMAT_U16_LE;
329 case AUD_FMT_S32:
330 return SND_PCM_FORMAT_S32_LE;
332 case AUD_FMT_U32:
333 return SND_PCM_FORMAT_U32_LE;
335 default:
336 dolog ("Internal logic error: Bad audio format %d\n", fmt);
337 #ifdef DEBUG_AUDIO
338 abort ();
339 #endif
340 return SND_PCM_FORMAT_U8;
344 static int alsa_to_audfmt (snd_pcm_format_t alsafmt, audfmt_e *fmt,
345 int *endianness)
347 switch (alsafmt) {
348 case SND_PCM_FORMAT_S8:
349 *endianness = 0;
350 *fmt = AUD_FMT_S8;
351 break;
353 case SND_PCM_FORMAT_U8:
354 *endianness = 0;
355 *fmt = AUD_FMT_U8;
356 break;
358 case SND_PCM_FORMAT_S16_LE:
359 *endianness = 0;
360 *fmt = AUD_FMT_S16;
361 break;
363 case SND_PCM_FORMAT_U16_LE:
364 *endianness = 0;
365 *fmt = AUD_FMT_U16;
366 break;
368 case SND_PCM_FORMAT_S16_BE:
369 *endianness = 1;
370 *fmt = AUD_FMT_S16;
371 break;
373 case SND_PCM_FORMAT_U16_BE:
374 *endianness = 1;
375 *fmt = AUD_FMT_U16;
376 break;
378 case SND_PCM_FORMAT_S32_LE:
379 *endianness = 0;
380 *fmt = AUD_FMT_S32;
381 break;
383 case SND_PCM_FORMAT_U32_LE:
384 *endianness = 0;
385 *fmt = AUD_FMT_U32;
386 break;
388 case SND_PCM_FORMAT_S32_BE:
389 *endianness = 1;
390 *fmt = AUD_FMT_S32;
391 break;
393 case SND_PCM_FORMAT_U32_BE:
394 *endianness = 1;
395 *fmt = AUD_FMT_U32;
396 break;
398 default:
399 dolog ("Unrecognized audio format %d\n", alsafmt);
400 return -1;
403 return 0;
406 static void alsa_dump_info (struct alsa_params_req *req,
407 struct alsa_params_obt *obt)
409 dolog ("parameter | requested value | obtained value\n");
410 dolog ("format | %10d | %10d\n", req->fmt, obt->fmt);
411 dolog ("channels | %10d | %10d\n",
412 req->nchannels, obt->nchannels);
413 dolog ("frequency | %10d | %10d\n", req->freq, obt->freq);
414 dolog ("============================================\n");
415 dolog ("requested: buffer size %d period size %d\n",
416 req->buffer_size, req->period_size);
417 dolog ("obtained: samples %ld\n", obt->samples);
420 static void alsa_set_threshold (snd_pcm_t *handle, snd_pcm_uframes_t threshold)
422 int err;
423 snd_pcm_sw_params_t *sw_params;
425 snd_pcm_sw_params_alloca (&sw_params);
427 err = snd_pcm_sw_params_current (handle, sw_params);
428 if (err < 0) {
429 dolog ("Could not fully initialize DAC\n");
430 alsa_logerr (err, "Failed to get current software parameters\n");
431 return;
434 err = snd_pcm_sw_params_set_start_threshold (handle, sw_params, threshold);
435 if (err < 0) {
436 dolog ("Could not fully initialize DAC\n");
437 alsa_logerr (err, "Failed to set software threshold to %ld\n",
438 threshold);
439 return;
442 err = snd_pcm_sw_params (handle, sw_params);
443 if (err < 0) {
444 dolog ("Could not fully initialize DAC\n");
445 alsa_logerr (err, "Failed to set software parameters\n");
446 return;
450 static int alsa_open (int in, struct alsa_params_req *req,
451 struct alsa_params_obt *obt, snd_pcm_t **handlep)
453 snd_pcm_t *handle;
454 snd_pcm_hw_params_t *hw_params;
455 int err;
456 int size_in_usec;
457 unsigned int freq, nchannels;
458 const char *pcm_name = in ? conf.pcm_name_in : conf.pcm_name_out;
459 snd_pcm_uframes_t obt_buffer_size;
460 const char *typ = in ? "ADC" : "DAC";
461 snd_pcm_format_t obtfmt;
463 freq = req->freq;
464 nchannels = req->nchannels;
465 size_in_usec = req->size_in_usec;
467 snd_pcm_hw_params_alloca (&hw_params);
469 err = snd_pcm_open (
470 &handle,
471 pcm_name,
472 in ? SND_PCM_STREAM_CAPTURE : SND_PCM_STREAM_PLAYBACK,
473 SND_PCM_NONBLOCK
475 if (err < 0) {
476 alsa_logerr2 (err, typ, "Failed to open `%s':\n", pcm_name);
477 return -1;
480 err = snd_pcm_hw_params_any (handle, hw_params);
481 if (err < 0) {
482 alsa_logerr2 (err, typ, "Failed to initialize hardware parameters\n");
483 goto err;
486 err = snd_pcm_hw_params_set_access (
487 handle,
488 hw_params,
489 SND_PCM_ACCESS_RW_INTERLEAVED
491 if (err < 0) {
492 alsa_logerr2 (err, typ, "Failed to set access type\n");
493 goto err;
496 err = snd_pcm_hw_params_set_format (handle, hw_params, req->fmt);
497 if (err < 0 && conf.verbose) {
498 alsa_logerr2 (err, typ, "Failed to set format %d\n", req->fmt);
501 err = snd_pcm_hw_params_set_rate_near (handle, hw_params, &freq, 0);
502 if (err < 0) {
503 alsa_logerr2 (err, typ, "Failed to set frequency %d\n", req->freq);
504 goto err;
507 err = snd_pcm_hw_params_set_channels_near (
508 handle,
509 hw_params,
510 &nchannels
512 if (err < 0) {
513 alsa_logerr2 (err, typ, "Failed to set number of channels %d\n",
514 req->nchannels);
515 goto err;
518 if (nchannels != 1 && nchannels != 2) {
519 alsa_logerr2 (err, typ,
520 "Can not handle obtained number of channels %d\n",
521 nchannels);
522 goto err;
525 if (req->buffer_size) {
526 unsigned long obt;
528 if (size_in_usec) {
529 int dir = 0;
530 unsigned int btime = req->buffer_size;
532 err = snd_pcm_hw_params_set_buffer_time_near (
533 handle,
534 hw_params,
535 &btime,
536 &dir
538 obt = btime;
540 else {
541 snd_pcm_uframes_t bsize = req->buffer_size;
543 err = snd_pcm_hw_params_set_buffer_size_near (
544 handle,
545 hw_params,
546 &bsize
548 obt = bsize;
550 if (err < 0) {
551 alsa_logerr2 (err, typ, "Failed to set buffer %s to %d\n",
552 size_in_usec ? "time" : "size", req->buffer_size);
553 goto err;
556 if ((req->override_mask & 2) && (obt - req->buffer_size))
557 dolog ("Requested buffer %s %u was rejected, using %lu\n",
558 size_in_usec ? "time" : "size", req->buffer_size, obt);
561 if (req->period_size) {
562 unsigned long obt;
564 if (size_in_usec) {
565 int dir = 0;
566 unsigned int ptime = req->period_size;
568 err = snd_pcm_hw_params_set_period_time_near (
569 handle,
570 hw_params,
571 &ptime,
572 &dir
574 obt = ptime;
576 else {
577 int dir = 0;
578 snd_pcm_uframes_t psize = req->period_size;
580 err = snd_pcm_hw_params_set_period_size_near (
581 handle,
582 hw_params,
583 &psize,
584 &dir
586 obt = psize;
589 if (err < 0) {
590 alsa_logerr2 (err, typ, "Failed to set period %s to %d\n",
591 size_in_usec ? "time" : "size", req->period_size);
592 goto err;
595 if ((req->override_mask & 1) && (obt - req->period_size))
596 dolog ("Requested period %s %u was rejected, using %lu\n",
597 size_in_usec ? "time" : "size", req->period_size, obt);
600 err = snd_pcm_hw_params (handle, hw_params);
601 if (err < 0) {
602 alsa_logerr2 (err, typ, "Failed to apply audio parameters\n");
603 goto err;
606 err = snd_pcm_hw_params_get_buffer_size (hw_params, &obt_buffer_size);
607 if (err < 0) {
608 alsa_logerr2 (err, typ, "Failed to get buffer size\n");
609 goto err;
612 err = snd_pcm_hw_params_get_format (hw_params, &obtfmt);
613 if (err < 0) {
614 alsa_logerr2 (err, typ, "Failed to get format\n");
615 goto err;
618 if (alsa_to_audfmt (obtfmt, &obt->fmt, &obt->endianness)) {
619 dolog ("Invalid format was returned %d\n", obtfmt);
620 goto err;
623 err = snd_pcm_prepare (handle);
624 if (err < 0) {
625 alsa_logerr2 (err, typ, "Could not prepare handle %p\n", handle);
626 goto err;
629 if (!in && conf.threshold) {
630 snd_pcm_uframes_t threshold;
631 int bytes_per_sec;
633 bytes_per_sec = freq << (nchannels == 2);
635 switch (obt->fmt) {
636 case AUD_FMT_S8:
637 case AUD_FMT_U8:
638 break;
640 case AUD_FMT_S16:
641 case AUD_FMT_U16:
642 bytes_per_sec <<= 1;
643 break;
645 case AUD_FMT_S32:
646 case AUD_FMT_U32:
647 bytes_per_sec <<= 2;
648 break;
651 threshold = (conf.threshold * bytes_per_sec) / 1000;
652 alsa_set_threshold (handle, threshold);
655 obt->nchannels = nchannels;
656 obt->freq = freq;
657 obt->samples = obt_buffer_size;
659 *handlep = handle;
661 if (conf.verbose &&
662 (obt->fmt != req->fmt ||
663 obt->nchannels != req->nchannels ||
664 obt->freq != req->freq)) {
665 dolog ("Audio paramters for %s\n", typ);
666 alsa_dump_info (req, obt);
669 #ifdef DEBUG
670 alsa_dump_info (req, obt);
671 #endif
672 return 0;
674 err:
675 alsa_anal_close1 (&handle);
676 return -1;
679 static snd_pcm_sframes_t alsa_get_avail (snd_pcm_t *handle)
681 snd_pcm_sframes_t avail;
683 avail = snd_pcm_avail_update (handle);
684 if (avail < 0) {
685 if (avail == -EPIPE) {
686 if (!alsa_recover (handle)) {
687 avail = snd_pcm_avail_update (handle);
691 if (avail < 0) {
692 alsa_logerr (avail,
693 "Could not obtain number of available frames\n");
694 return -1;
698 return avail;
701 static int alsa_run_out (HWVoiceOut *hw)
703 ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw;
704 int rpos, live, decr;
705 int samples;
706 uint8_t *dst;
707 struct st_sample *src;
708 snd_pcm_sframes_t avail;
710 live = audio_pcm_hw_get_live_out (hw);
711 if (!live) {
712 return 0;
715 avail = alsa_get_avail (alsa->handle);
716 if (avail < 0) {
717 dolog ("Could not get number of available playback frames\n");
718 return 0;
721 decr = audio_MIN (live, avail);
722 samples = decr;
723 rpos = hw->rpos;
724 while (samples) {
725 int left_till_end_samples = hw->samples - rpos;
726 int len = audio_MIN (samples, left_till_end_samples);
727 snd_pcm_sframes_t written;
729 src = hw->mix_buf + rpos;
730 dst = advance (alsa->pcm_buf, rpos << hw->info.shift);
732 hw->clip (dst, src, len);
734 while (len) {
735 written = snd_pcm_writei (alsa->handle, dst, len);
737 if (written <= 0) {
738 switch (written) {
739 case 0:
740 if (conf.verbose) {
741 dolog ("Failed to write %d frames (wrote zero)\n", len);
743 goto exit;
745 case -EPIPE:
746 if (alsa_recover (alsa->handle)) {
747 alsa_logerr (written, "Failed to write %d frames\n",
748 len);
749 goto exit;
751 if (conf.verbose) {
752 dolog ("Recovering from playback xrun\n");
754 continue;
756 case -ESTRPIPE:
757 /* stream is suspended and waiting for an
758 application recovery */
759 if (alsa_resume (alsa->handle)) {
760 alsa_logerr (written, "Failed to write %d frames\n",
761 len);
762 goto exit;
764 if (conf.verbose) {
765 dolog ("Resuming suspended output stream\n");
767 continue;
769 case -EAGAIN:
770 goto exit;
772 default:
773 alsa_logerr (written, "Failed to write %d frames to %p\n",
774 len, dst);
775 goto exit;
779 rpos = (rpos + written) % hw->samples;
780 samples -= written;
781 len -= written;
782 dst = advance (dst, written << hw->info.shift);
783 src += written;
787 exit:
788 hw->rpos = rpos;
789 return decr;
792 static void alsa_fini_out (HWVoiceOut *hw)
794 ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw;
796 ldebug ("alsa_fini\n");
797 alsa_anal_close (&alsa->handle, &alsa->pollhlp);
799 if (alsa->pcm_buf) {
800 qemu_free (alsa->pcm_buf);
801 alsa->pcm_buf = NULL;
805 static int alsa_init_out (HWVoiceOut *hw, struct audsettings *as)
807 ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw;
808 struct alsa_params_req req;
809 struct alsa_params_obt obt;
810 snd_pcm_t *handle;
811 struct audsettings obt_as;
813 req.fmt = aud_to_alsafmt (as->fmt);
814 req.freq = as->freq;
815 req.nchannels = as->nchannels;
816 req.period_size = conf.period_size_out;
817 req.buffer_size = conf.buffer_size_out;
818 req.size_in_usec = conf.size_in_usec_out;
819 req.override_mask =
820 (conf.period_size_out_overridden ? 1 : 0) |
821 (conf.buffer_size_out_overridden ? 2 : 0);
823 if (alsa_open (0, &req, &obt, &handle)) {
824 return -1;
827 obt_as.freq = obt.freq;
828 obt_as.nchannels = obt.nchannels;
829 obt_as.fmt = obt.fmt;
830 obt_as.endianness = obt.endianness;
832 audio_pcm_init_info (&hw->info, &obt_as);
833 hw->samples = obt.samples;
835 alsa->pcm_buf = audio_calloc (AUDIO_FUNC, obt.samples, 1 << hw->info.shift);
836 if (!alsa->pcm_buf) {
837 dolog ("Could not allocate DAC buffer (%d samples, each %d bytes)\n",
838 hw->samples, 1 << hw->info.shift);
839 alsa_anal_close1 (&handle);
840 return -1;
843 alsa->handle = handle;
844 return 0;
847 static int alsa_voice_ctl (snd_pcm_t *handle, const char *typ, int pause)
849 int err;
851 if (pause) {
852 err = snd_pcm_drop (handle);
853 if (err < 0) {
854 alsa_logerr (err, "Could not stop %s\n", typ);
855 return -1;
858 else {
859 err = snd_pcm_prepare (handle);
860 if (err < 0) {
861 alsa_logerr (err, "Could not prepare handle for %s\n", typ);
862 return -1;
866 return 0;
869 static int alsa_ctl_out (HWVoiceOut *hw, int cmd, ...)
871 va_list ap;
872 int poll_mode;
873 ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw;
875 va_start (ap, cmd);
876 poll_mode = va_arg (ap, int);
877 va_end (ap);
879 switch (cmd) {
880 case VOICE_ENABLE:
881 ldebug ("enabling voice\n");
882 if (poll_mode && alsa_poll_out (hw)) {
883 poll_mode = 0;
885 hw->poll_mode = poll_mode;
886 return alsa_voice_ctl (alsa->handle, "playback", 0);
888 case VOICE_DISABLE:
889 ldebug ("disabling voice\n");
890 return alsa_voice_ctl (alsa->handle, "playback", 1);
893 return -1;
896 static int alsa_init_in (HWVoiceIn *hw, struct audsettings *as)
898 ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw;
899 struct alsa_params_req req;
900 struct alsa_params_obt obt;
901 snd_pcm_t *handle;
902 struct audsettings obt_as;
904 req.fmt = aud_to_alsafmt (as->fmt);
905 req.freq = as->freq;
906 req.nchannels = as->nchannels;
907 req.period_size = conf.period_size_in;
908 req.buffer_size = conf.buffer_size_in;
909 req.size_in_usec = conf.size_in_usec_in;
910 req.override_mask =
911 (conf.period_size_in_overridden ? 1 : 0) |
912 (conf.buffer_size_in_overridden ? 2 : 0);
914 if (alsa_open (1, &req, &obt, &handle)) {
915 return -1;
918 obt_as.freq = obt.freq;
919 obt_as.nchannels = obt.nchannels;
920 obt_as.fmt = obt.fmt;
921 obt_as.endianness = obt.endianness;
923 audio_pcm_init_info (&hw->info, &obt_as);
924 hw->samples = obt.samples;
926 alsa->pcm_buf = audio_calloc (AUDIO_FUNC, hw->samples, 1 << hw->info.shift);
927 if (!alsa->pcm_buf) {
928 dolog ("Could not allocate ADC buffer (%d samples, each %d bytes)\n",
929 hw->samples, 1 << hw->info.shift);
930 alsa_anal_close1 (&handle);
931 return -1;
934 alsa->handle = handle;
935 return 0;
938 static void alsa_fini_in (HWVoiceIn *hw)
940 ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw;
942 alsa_anal_close (&alsa->handle, &alsa->pollhlp);
944 if (alsa->pcm_buf) {
945 qemu_free (alsa->pcm_buf);
946 alsa->pcm_buf = NULL;
950 static int alsa_run_in (HWVoiceIn *hw)
952 ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw;
953 int hwshift = hw->info.shift;
954 int i;
955 int live = audio_pcm_hw_get_live_in (hw);
956 int dead = hw->samples - live;
957 int decr;
958 struct {
959 int add;
960 int len;
961 } bufs[2] = {
962 { .add = hw->wpos, .len = 0 },
963 { .add = 0, .len = 0 }
965 snd_pcm_sframes_t avail;
966 snd_pcm_uframes_t read_samples = 0;
968 if (!dead) {
969 return 0;
972 avail = alsa_get_avail (alsa->handle);
973 if (avail < 0) {
974 dolog ("Could not get number of captured frames\n");
975 return 0;
978 if (!avail) {
979 snd_pcm_state_t state;
981 state = snd_pcm_state (alsa->handle);
982 switch (state) {
983 case SND_PCM_STATE_PREPARED:
984 avail = hw->samples;
985 break;
986 case SND_PCM_STATE_SUSPENDED:
987 /* stream is suspended and waiting for an application recovery */
988 if (alsa_resume (alsa->handle)) {
989 dolog ("Failed to resume suspended input stream\n");
990 return 0;
992 if (conf.verbose) {
993 dolog ("Resuming suspended input stream\n");
995 break;
996 default:
997 if (conf.verbose) {
998 dolog ("No frames available and ALSA state is %d\n", state);
1000 return 0;
1004 decr = audio_MIN (dead, avail);
1005 if (!decr) {
1006 return 0;
1009 if (hw->wpos + decr > hw->samples) {
1010 bufs[0].len = (hw->samples - hw->wpos);
1011 bufs[1].len = (decr - (hw->samples - hw->wpos));
1013 else {
1014 bufs[0].len = decr;
1017 for (i = 0; i < 2; ++i) {
1018 void *src;
1019 struct st_sample *dst;
1020 snd_pcm_sframes_t nread;
1021 snd_pcm_uframes_t len;
1023 len = bufs[i].len;
1025 src = advance (alsa->pcm_buf, bufs[i].add << hwshift);
1026 dst = hw->conv_buf + bufs[i].add;
1028 while (len) {
1029 nread = snd_pcm_readi (alsa->handle, src, len);
1031 if (nread <= 0) {
1032 switch (nread) {
1033 case 0:
1034 if (conf.verbose) {
1035 dolog ("Failed to read %ld frames (read zero)\n", len);
1037 goto exit;
1039 case -EPIPE:
1040 if (alsa_recover (alsa->handle)) {
1041 alsa_logerr (nread, "Failed to read %ld frames\n", len);
1042 goto exit;
1044 if (conf.verbose) {
1045 dolog ("Recovering from capture xrun\n");
1047 continue;
1049 case -EAGAIN:
1050 goto exit;
1052 default:
1053 alsa_logerr (
1054 nread,
1055 "Failed to read %ld frames from %p\n",
1056 len,
1059 goto exit;
1063 hw->conv (dst, src, nread, &nominal_volume);
1065 src = advance (src, nread << hwshift);
1066 dst += nread;
1068 read_samples += nread;
1069 len -= nread;
1073 exit:
1074 hw->wpos = (hw->wpos + read_samples) % hw->samples;
1075 return read_samples;
1078 static int alsa_read (SWVoiceIn *sw, void *buf, int size)
1080 return audio_pcm_sw_read (sw, buf, size);
1083 static int alsa_ctl_in (HWVoiceIn *hw, int cmd, ...)
1085 va_list ap;
1086 int poll_mode;
1087 ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw;
1089 va_start (ap, cmd);
1090 poll_mode = va_arg (ap, int);
1091 va_end (ap);
1093 switch (cmd) {
1094 case VOICE_ENABLE:
1095 ldebug ("enabling voice\n");
1096 if (poll_mode && alsa_poll_in (hw)) {
1097 poll_mode = 0;
1099 hw->poll_mode = poll_mode;
1101 return alsa_voice_ctl (alsa->handle, "capture", 0);
1103 case VOICE_DISABLE:
1104 ldebug ("disabling voice\n");
1105 if (hw->poll_mode) {
1106 hw->poll_mode = 0;
1107 alsa_fini_poll (&alsa->pollhlp);
1109 return alsa_voice_ctl (alsa->handle, "capture", 1);
1112 return -1;
1115 static void *alsa_audio_init (void)
1117 return &conf;
1120 static void alsa_audio_fini (void *opaque)
1122 (void) opaque;
1125 static struct audio_option alsa_options[] = {
1127 .name = "DAC_SIZE_IN_USEC",
1128 .tag = AUD_OPT_BOOL,
1129 .valp = &conf.size_in_usec_out,
1130 .descr = "DAC period/buffer size in microseconds (otherwise in frames)"
1133 .name = "DAC_PERIOD_SIZE",
1134 .tag = AUD_OPT_INT,
1135 .valp = &conf.period_size_out,
1136 .descr = "DAC period size (0 to go with system default)",
1137 .overriddenp = &conf.period_size_out_overridden
1140 .name = "DAC_BUFFER_SIZE",
1141 .tag = AUD_OPT_INT,
1142 .valp = &conf.buffer_size_out,
1143 .descr = "DAC buffer size (0 to go with system default)",
1144 .overriddenp = &conf.buffer_size_out_overridden
1147 .name = "ADC_SIZE_IN_USEC",
1148 .tag = AUD_OPT_BOOL,
1149 .valp = &conf.size_in_usec_in,
1150 .descr =
1151 "ADC period/buffer size in microseconds (otherwise in frames)"
1154 .name = "ADC_PERIOD_SIZE",
1155 .tag = AUD_OPT_INT,
1156 .valp = &conf.period_size_in,
1157 .descr = "ADC period size (0 to go with system default)",
1158 .overriddenp = &conf.period_size_in_overridden
1161 .name = "ADC_BUFFER_SIZE",
1162 .tag = AUD_OPT_INT,
1163 .valp = &conf.buffer_size_in,
1164 .descr = "ADC buffer size (0 to go with system default)",
1165 .overriddenp = &conf.buffer_size_in_overridden
1168 .name = "THRESHOLD",
1169 .tag = AUD_OPT_INT,
1170 .valp = &conf.threshold,
1171 .descr = "(undocumented)"
1174 .name = "DAC_DEV",
1175 .tag = AUD_OPT_STR,
1176 .valp = &conf.pcm_name_out,
1177 .descr = "DAC device name (for instance dmix)"
1180 .name = "ADC_DEV",
1181 .tag = AUD_OPT_STR,
1182 .valp = &conf.pcm_name_in,
1183 .descr = "ADC device name"
1186 .name = "VERBOSE",
1187 .tag = AUD_OPT_BOOL,
1188 .valp = &conf.verbose,
1189 .descr = "Behave in a more verbose way"
1191 { /* End of list */ }
1194 static struct audio_pcm_ops alsa_pcm_ops = {
1195 .init_out = alsa_init_out,
1196 .fini_out = alsa_fini_out,
1197 .run_out = alsa_run_out,
1198 .write = alsa_write,
1199 .ctl_out = alsa_ctl_out,
1201 .init_in = alsa_init_in,
1202 .fini_in = alsa_fini_in,
1203 .run_in = alsa_run_in,
1204 .read = alsa_read,
1205 .ctl_in = alsa_ctl_in,
1208 struct audio_driver alsa_audio_driver = {
1209 .name = "alsa",
1210 .descr = "ALSA http://www.alsa-project.org",
1211 .options = alsa_options,
1212 .init = alsa_audio_init,
1213 .fini = alsa_audio_fini,
1214 .pcm_ops = &alsa_pcm_ops,
1215 .can_be_default = 1,
1216 .max_voices_out = INT_MAX,
1217 .max_voices_in = INT_MAX,
1218 .voice_size_out = sizeof (ALSAVoiceOut),
1219 .voice_size_in = sizeof (ALSAVoiceIn)