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