2 This file is part of PulseAudio.
4 Copyright 2004-2009 Lennart Poettering
5 Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
7 PulseAudio is free software; you can redistribute it and/or modify
8 it under the terms of the GNU Lesser General Public License as published
9 by the Free Software Foundation; either version 2.1 of the License,
10 or (at your option) any later version.
12 PulseAudio is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
17 You should have received a copy of the GNU Lesser General Public License
18 along with PulseAudio; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
27 #include <sys/types.h>
29 #include <asoundlib.h>
31 #include <pulse/sample.h>
32 #include <pulse/xmalloc.h>
33 #include <pulse/timeval.h>
34 #include <pulse/util.h>
35 #include <pulse/i18n.h>
36 #include <pulse/utf8.h>
38 #include <pulsecore/log.h>
39 #include <pulsecore/macro.h>
40 #include <pulsecore/core-util.h>
41 #include <pulsecore/atomic.h>
42 #include <pulsecore/core-error.h>
43 #include <pulsecore/once.h>
44 #include <pulsecore/thread.h>
45 #include <pulsecore/conf-parser.h>
46 #include <pulsecore/core-rtclock.h>
48 #include "alsa-util.h"
49 #include "alsa-mixer.h"
56 #include "udev-util.h"
59 static int set_format(snd_pcm_t
*pcm_handle
, snd_pcm_hw_params_t
*hwparams
, pa_sample_format_t
*f
) {
61 static const snd_pcm_format_t format_trans
[] = {
62 [PA_SAMPLE_U8
] = SND_PCM_FORMAT_U8
,
63 [PA_SAMPLE_ALAW
] = SND_PCM_FORMAT_A_LAW
,
64 [PA_SAMPLE_ULAW
] = SND_PCM_FORMAT_MU_LAW
,
65 [PA_SAMPLE_S16LE
] = SND_PCM_FORMAT_S16_LE
,
66 [PA_SAMPLE_S16BE
] = SND_PCM_FORMAT_S16_BE
,
67 [PA_SAMPLE_FLOAT32LE
] = SND_PCM_FORMAT_FLOAT_LE
,
68 [PA_SAMPLE_FLOAT32BE
] = SND_PCM_FORMAT_FLOAT_BE
,
69 [PA_SAMPLE_S32LE
] = SND_PCM_FORMAT_S32_LE
,
70 [PA_SAMPLE_S32BE
] = SND_PCM_FORMAT_S32_BE
,
71 [PA_SAMPLE_S24LE
] = SND_PCM_FORMAT_S24_3LE
,
72 [PA_SAMPLE_S24BE
] = SND_PCM_FORMAT_S24_3BE
,
73 [PA_SAMPLE_S24_32LE
] = SND_PCM_FORMAT_S24_LE
,
74 [PA_SAMPLE_S24_32BE
] = SND_PCM_FORMAT_S24_BE
,
77 static const pa_sample_format_t try_order
[] = {
96 pa_assert(pcm_handle
);
100 if ((ret
= snd_pcm_hw_params_set_format(pcm_handle
, hwparams
, format_trans
[*f
])) >= 0)
103 pa_log_debug("snd_pcm_hw_params_set_format(%s) failed: %s",
104 snd_pcm_format_description(format_trans
[*f
]),
105 pa_alsa_strerror(ret
));
107 if (*f
== PA_SAMPLE_FLOAT32BE
)
108 *f
= PA_SAMPLE_FLOAT32LE
;
109 else if (*f
== PA_SAMPLE_FLOAT32LE
)
110 *f
= PA_SAMPLE_FLOAT32BE
;
111 else if (*f
== PA_SAMPLE_S24BE
)
112 *f
= PA_SAMPLE_S24LE
;
113 else if (*f
== PA_SAMPLE_S24LE
)
114 *f
= PA_SAMPLE_S24BE
;
115 else if (*f
== PA_SAMPLE_S24_32BE
)
116 *f
= PA_SAMPLE_S24_32LE
;
117 else if (*f
== PA_SAMPLE_S24_32LE
)
118 *f
= PA_SAMPLE_S24_32BE
;
119 else if (*f
== PA_SAMPLE_S16BE
)
120 *f
= PA_SAMPLE_S16LE
;
121 else if (*f
== PA_SAMPLE_S16LE
)
122 *f
= PA_SAMPLE_S16BE
;
123 else if (*f
== PA_SAMPLE_S32BE
)
124 *f
= PA_SAMPLE_S32LE
;
125 else if (*f
== PA_SAMPLE_S32LE
)
126 *f
= PA_SAMPLE_S32BE
;
130 if ((ret
= snd_pcm_hw_params_set_format(pcm_handle
, hwparams
, format_trans
[*f
])) >= 0)
133 pa_log_debug("snd_pcm_hw_params_set_format(%s) failed: %s",
134 snd_pcm_format_description(format_trans
[*f
]),
135 pa_alsa_strerror(ret
));
139 for (i
= 0; i
< PA_ELEMENTSOF(try_order
); i
++) {
142 if ((ret
= snd_pcm_hw_params_set_format(pcm_handle
, hwparams
, format_trans
[*f
])) >= 0)
145 pa_log_debug("snd_pcm_hw_params_set_format(%s) failed: %s",
146 snd_pcm_format_description(format_trans
[*f
]),
147 pa_alsa_strerror(ret
));
153 static int set_period_size(snd_pcm_t
*pcm_handle
, snd_pcm_hw_params_t
*hwparams
, snd_pcm_uframes_t size
) {
157 pa_assert(pcm_handle
);
162 if (snd_pcm_hw_params_set_period_size_near(pcm_handle
, hwparams
, &s
, &d
) < 0) {
165 if (snd_pcm_hw_params_set_period_size_near(pcm_handle
, hwparams
, &s
, &d
) < 0) {
168 if ((ret
= snd_pcm_hw_params_set_period_size_near(pcm_handle
, hwparams
, &s
, &d
)) < 0) {
169 pa_log_info("snd_pcm_hw_params_set_period_size_near() failed: %s", pa_alsa_strerror(ret
));
178 static int set_buffer_size(snd_pcm_t
*pcm_handle
, snd_pcm_hw_params_t
*hwparams
, snd_pcm_uframes_t size
) {
181 pa_assert(pcm_handle
);
184 if ((ret
= snd_pcm_hw_params_set_buffer_size_near(pcm_handle
, hwparams
, &size
)) < 0) {
185 pa_log_info("snd_pcm_hw_params_set_buffer_size_near() failed: %s", pa_alsa_strerror(ret
));
192 /* Set the hardware parameters of the given ALSA device. Returns the
193 * selected fragment settings in *buffer_size and *period_size. If tsched mode can be enabled */
194 int pa_alsa_set_hw_params(
195 snd_pcm_t
*pcm_handle
,
197 snd_pcm_uframes_t
*period_size
,
198 snd_pcm_uframes_t
*buffer_size
,
199 snd_pcm_uframes_t tsched_size
,
201 pa_bool_t
*use_tsched
,
202 pa_bool_t require_exact_channel_number
) {
205 snd_pcm_hw_params_t
*hwparams
, *hwparams_copy
;
207 snd_pcm_uframes_t _period_size
= period_size
? *period_size
: 0;
208 snd_pcm_uframes_t _buffer_size
= buffer_size
? *buffer_size
: 0;
209 pa_bool_t _use_mmap
= use_mmap
&& *use_mmap
;
210 pa_bool_t _use_tsched
= use_tsched
&& *use_tsched
;
211 pa_sample_spec _ss
= *ss
;
213 pa_assert(pcm_handle
);
216 snd_pcm_hw_params_alloca(&hwparams
);
217 snd_pcm_hw_params_alloca(&hwparams_copy
);
219 if ((ret
= snd_pcm_hw_params_any(pcm_handle
, hwparams
)) < 0) {
220 pa_log_debug("snd_pcm_hw_params_any() failed: %s", pa_alsa_strerror(ret
));
224 if ((ret
= snd_pcm_hw_params_set_rate_resample(pcm_handle
, hwparams
, 0)) < 0) {
225 pa_log_debug("snd_pcm_hw_params_set_rate_resample() failed: %s", pa_alsa_strerror(ret
));
231 if (snd_pcm_hw_params_set_access(pcm_handle
, hwparams
, SND_PCM_ACCESS_MMAP_INTERLEAVED
) < 0) {
233 /* mmap() didn't work, fall back to interleaved */
235 if ((ret
= snd_pcm_hw_params_set_access(pcm_handle
, hwparams
, SND_PCM_ACCESS_RW_INTERLEAVED
)) < 0) {
236 pa_log_debug("snd_pcm_hw_params_set_access() failed: %s", pa_alsa_strerror(ret
));
243 } else if ((ret
= snd_pcm_hw_params_set_access(pcm_handle
, hwparams
, SND_PCM_ACCESS_RW_INTERLEAVED
)) < 0) {
244 pa_log_debug("snd_pcm_hw_params_set_access() failed: %s", pa_alsa_strerror(ret
));
251 if (!pa_alsa_pcm_is_hw(pcm_handle
))
254 if ((ret
= set_format(pcm_handle
, hwparams
, &_ss
.format
)) < 0)
257 if ((ret
= snd_pcm_hw_params_set_rate_near(pcm_handle
, hwparams
, &_ss
.rate
, NULL
)) < 0) {
258 pa_log_debug("snd_pcm_hw_params_set_rate_near() failed: %s", pa_alsa_strerror(ret
));
262 /* We ignore very small sampling rate deviations */
263 if (_ss
.rate
>= ss
->rate
*.95 && _ss
.rate
<= ss
->rate
*1.05)
266 if (require_exact_channel_number
) {
267 if ((ret
= snd_pcm_hw_params_set_channels(pcm_handle
, hwparams
, _ss
.channels
)) < 0) {
268 pa_log_debug("snd_pcm_hw_params_set_channels(%u) failed: %s", _ss
.channels
, pa_alsa_strerror(ret
));
272 unsigned int c
= _ss
.channels
;
274 if ((ret
= snd_pcm_hw_params_set_channels_near(pcm_handle
, hwparams
, &c
)) < 0) {
275 pa_log_debug("snd_pcm_hw_params_set_channels_near(%u) failed: %s", _ss
.channels
, pa_alsa_strerror(ret
));
282 if (_use_tsched
&& tsched_size
> 0) {
283 _buffer_size
= (snd_pcm_uframes_t
) (((uint64_t) tsched_size
* _ss
.rate
) / ss
->rate
);
284 _period_size
= _buffer_size
;
286 _period_size
= (snd_pcm_uframes_t
) (((uint64_t) _period_size
* _ss
.rate
) / ss
->rate
);
287 _buffer_size
= (snd_pcm_uframes_t
) (((uint64_t) _buffer_size
* _ss
.rate
) / ss
->rate
);
290 if (_buffer_size
> 0 || _period_size
> 0) {
291 snd_pcm_uframes_t max_frames
= 0;
293 if ((ret
= snd_pcm_hw_params_get_buffer_size_max(hwparams
, &max_frames
)) < 0)
294 pa_log_warn("snd_pcm_hw_params_get_buffer_size_max() failed: %s", pa_alsa_strerror(ret
));
296 pa_log_debug("Maximum hw buffer size is %lu ms", (long unsigned) (max_frames
* PA_MSEC_PER_SEC
/ _ss
.rate
));
298 /* Some ALSA drivers really don't like if we set the buffer
299 * size first and the number of periods second. (which would
300 * make a lot more sense to me) So, try a few combinations
301 * before we give up. */
303 if (_buffer_size
> 0 && _period_size
> 0) {
304 snd_pcm_hw_params_copy(hwparams_copy
, hwparams
);
306 /* First try: set buffer size first, followed by period size */
307 if (set_buffer_size(pcm_handle
, hwparams_copy
, _buffer_size
) >= 0 &&
308 set_period_size(pcm_handle
, hwparams_copy
, _period_size
) >= 0 &&
309 snd_pcm_hw_params(pcm_handle
, hwparams_copy
) >= 0) {
310 pa_log_debug("Set buffer size first (to %lu samples), period size second (to %lu samples).", (unsigned long) _buffer_size
, (unsigned long) _period_size
);
314 /* Second try: set period size first, followed by buffer size */
315 if (set_period_size(pcm_handle
, hwparams_copy
, _period_size
) >= 0 &&
316 set_buffer_size(pcm_handle
, hwparams_copy
, _buffer_size
) >= 0 &&
317 snd_pcm_hw_params(pcm_handle
, hwparams_copy
) >= 0) {
318 pa_log_debug("Set period size first (to %lu samples), buffer size second (to %lu samples).", (unsigned long) _period_size
, (unsigned long) _buffer_size
);
323 if (_buffer_size
> 0) {
324 snd_pcm_hw_params_copy(hwparams_copy
, hwparams
);
326 /* Third try: set only buffer size */
327 if (set_buffer_size(pcm_handle
, hwparams_copy
, _buffer_size
) >= 0 &&
328 snd_pcm_hw_params(pcm_handle
, hwparams_copy
) >= 0) {
329 pa_log_debug("Set only buffer size (to %lu samples).", (unsigned long) _buffer_size
);
334 if (_period_size
> 0) {
335 snd_pcm_hw_params_copy(hwparams_copy
, hwparams
);
337 /* Fourth try: set only period size */
338 if (set_period_size(pcm_handle
, hwparams_copy
, _period_size
) >= 0 &&
339 snd_pcm_hw_params(pcm_handle
, hwparams_copy
) >= 0) {
340 pa_log_debug("Set only period size (to %lu samples).", (unsigned long) _period_size
);
346 pa_log_debug("Set neither period nor buffer size.");
348 /* Last chance, set nothing */
349 if ((ret
= snd_pcm_hw_params(pcm_handle
, hwparams
)) < 0) {
350 pa_log_info("snd_pcm_hw_params failed: %s", pa_alsa_strerror(ret
));
356 if (ss
->rate
!= _ss
.rate
)
357 pa_log_info("Device %s doesn't support %u Hz, changed to %u Hz.", snd_pcm_name(pcm_handle
), ss
->rate
, _ss
.rate
);
359 if (ss
->channels
!= _ss
.channels
)
360 pa_log_info("Device %s doesn't support %u channels, changed to %u.", snd_pcm_name(pcm_handle
), ss
->channels
, _ss
.channels
);
362 if (ss
->format
!= _ss
.format
)
363 pa_log_info("Device %s doesn't support sample format %s, changed to %s.", snd_pcm_name(pcm_handle
), pa_sample_format_to_string(ss
->format
), pa_sample_format_to_string(_ss
.format
));
365 if ((ret
= snd_pcm_prepare(pcm_handle
)) < 0) {
366 pa_log_info("snd_pcm_prepare() failed: %s", pa_alsa_strerror(ret
));
370 if ((ret
= snd_pcm_hw_params_current(pcm_handle
, hwparams
)) < 0) {
371 pa_log_info("snd_pcm_hw_params_current() failed: %s", pa_alsa_strerror(ret
));
375 if ((ret
= snd_pcm_hw_params_get_period_size(hwparams
, &_period_size
, &dir
)) < 0 ||
376 (ret
= snd_pcm_hw_params_get_buffer_size(hwparams
, &_buffer_size
)) < 0) {
377 pa_log_info("snd_pcm_hw_params_get_{period|buffer}_size() failed: %s", pa_alsa_strerror(ret
));
382 ss
->channels
= _ss
.channels
;
383 ss
->format
= _ss
.format
;
385 pa_assert(_period_size
> 0);
386 pa_assert(_buffer_size
> 0);
389 *buffer_size
= _buffer_size
;
392 *period_size
= _period_size
;
395 *use_mmap
= _use_mmap
;
398 *use_tsched
= _use_tsched
;
402 snd_pcm_nonblock(pcm_handle
, 1);
409 int pa_alsa_set_sw_params(snd_pcm_t
*pcm
, snd_pcm_uframes_t avail_min
, pa_bool_t period_event
) {
410 snd_pcm_sw_params_t
*swparams
;
411 snd_pcm_uframes_t boundary
;
416 snd_pcm_sw_params_alloca(&swparams
);
418 if ((err
= snd_pcm_sw_params_current(pcm
, swparams
) < 0)) {
419 pa_log_warn("Unable to determine current swparams: %s\n", pa_alsa_strerror(err
));
423 if ((err
= snd_pcm_sw_params_set_period_event(pcm
, swparams
, period_event
)) < 0) {
424 pa_log_warn("Unable to disable period event: %s\n", pa_alsa_strerror(err
));
428 if ((err
= snd_pcm_sw_params_set_tstamp_mode(pcm
, swparams
, SND_PCM_TSTAMP_ENABLE
)) < 0) {
429 pa_log_warn("Unable to enable time stamping: %s\n", pa_alsa_strerror(err
));
433 if ((err
= snd_pcm_sw_params_get_boundary(swparams
, &boundary
)) < 0) {
434 pa_log_warn("Unable to get boundary: %s\n", pa_alsa_strerror(err
));
438 if ((err
= snd_pcm_sw_params_set_stop_threshold(pcm
, swparams
, boundary
)) < 0) {
439 pa_log_warn("Unable to set stop threshold: %s\n", pa_alsa_strerror(err
));
443 if ((err
= snd_pcm_sw_params_set_start_threshold(pcm
, swparams
, (snd_pcm_uframes_t
) -1)) < 0) {
444 pa_log_warn("Unable to set start threshold: %s\n", pa_alsa_strerror(err
));
448 if ((err
= snd_pcm_sw_params_set_avail_min(pcm
, swparams
, avail_min
)) < 0) {
449 pa_log_error("snd_pcm_sw_params_set_avail_min() failed: %s", pa_alsa_strerror(err
));
453 if ((err
= snd_pcm_sw_params(pcm
, swparams
)) < 0) {
454 pa_log_warn("Unable to set sw params: %s\n", pa_alsa_strerror(err
));
461 snd_pcm_t
*pa_alsa_open_by_device_id_auto(
467 snd_pcm_uframes_t
*period_size
,
468 snd_pcm_uframes_t
*buffer_size
,
469 snd_pcm_uframes_t tsched_size
,
471 pa_bool_t
*use_tsched
,
472 pa_alsa_profile_set
*ps
,
473 pa_alsa_mapping
**mapping
) {
476 snd_pcm_t
*pcm_handle
;
486 /* First we try to find a device string with a superset of the
487 * requested channel map. We iterate through our device table from
488 * top to bottom and take the first that matches. If we didn't
489 * find a working device that way, we iterate backwards, and check
490 * all devices that do not provide a superset of the requested
493 PA_HASHMAP_FOREACH(m
, ps
->mappings
, state
) {
494 if (!pa_channel_map_superset(&m
->channel_map
, map
))
497 pa_log_debug("Checking for superset %s (%s)", m
->name
, m
->device_strings
[0]);
499 pcm_handle
= pa_alsa_open_by_device_id_mapping(
520 PA_HASHMAP_FOREACH_BACKWARDS(m
, ps
->mappings
, state
) {
521 if (pa_channel_map_superset(&m
->channel_map
, map
))
524 pa_log_debug("Checking for subset %s (%s)", m
->name
, m
->device_strings
[0]);
526 pcm_handle
= pa_alsa_open_by_device_id_mapping(
547 /* OK, we didn't find any good device, so let's try the raw hw: stuff */
548 d
= pa_sprintf_malloc("hw:%s", dev_id
);
549 pa_log_debug("Trying %s as last resort...", d
);
550 pcm_handle
= pa_alsa_open_by_device_string(
564 if (pcm_handle
&& mapping
)
570 snd_pcm_t
*pa_alsa_open_by_device_id_mapping(
576 snd_pcm_uframes_t
*period_size
,
577 snd_pcm_uframes_t
*buffer_size
,
578 snd_pcm_uframes_t tsched_size
,
580 pa_bool_t
*use_tsched
,
581 pa_alsa_mapping
*m
) {
583 snd_pcm_t
*pcm_handle
;
584 pa_sample_spec try_ss
;
585 pa_channel_map try_map
;
593 try_ss
.channels
= m
->channel_map
.channels
;
594 try_ss
.rate
= ss
->rate
;
595 try_ss
.format
= ss
->format
;
596 try_map
= m
->channel_map
;
598 pcm_handle
= pa_alsa_open_by_template(
617 pa_assert(map
->channels
== ss
->channels
);
622 snd_pcm_t
*pa_alsa_open_by_device_string(
628 snd_pcm_uframes_t
*period_size
,
629 snd_pcm_uframes_t
*buffer_size
,
630 snd_pcm_uframes_t tsched_size
,
632 pa_bool_t
*use_tsched
,
633 pa_bool_t require_exact_channel_number
) {
637 snd_pcm_t
*pcm_handle
;
638 pa_bool_t reformat
= FALSE
;
644 d
= pa_xstrdup(device
);
647 pa_log_debug("Trying %s %s SND_PCM_NO_AUTO_FORMAT ...", d
, reformat
? "without" : "with");
649 if ((err
= snd_pcm_open(&pcm_handle
, d
, mode
,
651 SND_PCM_NO_AUTO_RESAMPLE
|
652 SND_PCM_NO_AUTO_CHANNELS
|
653 (reformat
? 0 : SND_PCM_NO_AUTO_FORMAT
))) < 0) {
654 pa_log_info("Error opening PCM device %s: %s", d
, pa_alsa_strerror(err
));
658 pa_log_debug("Managed to open %s", d
);
660 if ((err
= pa_alsa_set_hw_params(
668 require_exact_channel_number
)) < 0) {
673 snd_pcm_close(pcm_handle
);
677 /* Hmm, some hw is very exotic, so we retry with plug, if without it didn't work */
678 if (!pa_startswith(d
, "plug:") && !pa_startswith(d
, "plughw:")) {
681 t
= pa_sprintf_malloc("plug:%s", d
);
687 snd_pcm_close(pcm_handle
);
691 pa_log_info("Failed to set hardware parameters on %s: %s", d
, pa_alsa_strerror(err
));
692 snd_pcm_close(pcm_handle
);
702 if (ss
->channels
!= map
->channels
)
703 pa_channel_map_init_extend(map
, ss
->channels
, PA_CHANNEL_MAP_ALSA
);
714 snd_pcm_t
*pa_alsa_open_by_template(
721 snd_pcm_uframes_t
*period_size
,
722 snd_pcm_uframes_t
*buffer_size
,
723 snd_pcm_uframes_t tsched_size
,
725 pa_bool_t
*use_tsched
,
726 pa_bool_t require_exact_channel_number
) {
728 snd_pcm_t
*pcm_handle
;
731 for (i
= template; *i
; i
++) {
734 d
= pa_replace(*i
, "%f", dev_id
);
736 pcm_handle
= pa_alsa_open_by_device_string(
747 require_exact_channel_number
);
758 void pa_alsa_dump(pa_log_level_t level
, snd_pcm_t
*pcm
) {
764 pa_assert_se(snd_output_buffer_open(&out
) == 0);
766 if ((err
= snd_pcm_dump(pcm
, out
)) < 0)
767 pa_logl(level
, "snd_pcm_dump(): %s", pa_alsa_strerror(err
));
770 snd_output_buffer_string(out
, &s
);
771 pa_logl(level
, "snd_pcm_dump():\n%s", pa_strnull(s
));
774 pa_assert_se(snd_output_close(out
) == 0);
777 void pa_alsa_dump_status(snd_pcm_t
*pcm
) {
780 snd_pcm_status_t
*status
;
785 snd_pcm_status_alloca(&status
);
787 if ((err
= snd_output_buffer_open(&out
)) < 0) {
788 pa_log_debug("snd_output_buffer_open() failed: %s", pa_cstrerror(err
));
792 if ((err
= snd_pcm_status(pcm
, status
)) < 0) {
793 pa_log_debug("snd_pcm_status() failed: %s", pa_cstrerror(err
));
797 if ((err
= snd_pcm_status_dump(status
, out
)) < 0) {
798 pa_log_debug("snd_pcm_dump(): %s", pa_alsa_strerror(err
));
802 snd_output_buffer_string(out
, &s
);
803 pa_log_debug("snd_pcm_dump():\n%s", pa_strnull(s
));
807 snd_output_close(out
);
810 static void alsa_error_handler(const char *file
, int line
, const char *function
, int err
, const char *fmt
,...) {
814 alsa_file
= pa_sprintf_malloc("(alsa-lib)%s", file
);
818 pa_log_levelv_meta(PA_LOG_INFO
, alsa_file
, line
, function
, fmt
, ap
);
825 static pa_atomic_t n_error_handler_installed
= PA_ATOMIC_INIT(0);
827 void pa_alsa_refcnt_inc(void) {
828 /* This is not really thread safe, but we do our best */
830 if (pa_atomic_inc(&n_error_handler_installed
) == 0)
831 snd_lib_error_set_handler(alsa_error_handler
);
834 void pa_alsa_refcnt_dec(void) {
837 pa_assert_se((r
= pa_atomic_dec(&n_error_handler_installed
)) >= 1);
840 snd_lib_error_set_handler(NULL
);
841 snd_config_update_free_global();
845 pa_bool_t
pa_alsa_init_description(pa_proplist
*p
) {
849 if (pa_device_init_description(p
))
852 if (!(d
= pa_proplist_gets(p
, "alsa.card_name")))
853 d
= pa_proplist_gets(p
, "alsa.name");
858 k
= pa_proplist_gets(p
, PA_PROP_DEVICE_PROFILE_DESCRIPTION
);
861 pa_proplist_setf(p
, PA_PROP_DEVICE_DESCRIPTION
, _("%s %s"), d
, k
);
863 pa_proplist_sets(p
, PA_PROP_DEVICE_DESCRIPTION
, d
);
868 void pa_alsa_init_proplist_card(pa_core
*c
, pa_proplist
*p
, int card
) {
872 pa_assert(card
>= 0);
874 pa_proplist_setf(p
, "alsa.card", "%i", card
);
876 if (snd_card_get_name(card
, &cn
) >= 0) {
877 pa_proplist_sets(p
, "alsa.card_name", cn
);
881 if (snd_card_get_longname(card
, &lcn
) >= 0) {
882 pa_proplist_sets(p
, "alsa.long_card_name", lcn
);
886 if ((dn
= pa_alsa_get_driver_name(card
))) {
887 pa_proplist_sets(p
, "alsa.driver_name", dn
);
892 pa_udev_get_info(card
, p
);
896 pa_hal_get_info(c
, p
, card
);
900 void pa_alsa_init_proplist_pcm_info(pa_core
*c
, pa_proplist
*p
, snd_pcm_info_t
*pcm_info
) {
902 static const char * const alsa_class_table
[SND_PCM_CLASS_LAST
+1] = {
903 [SND_PCM_CLASS_GENERIC
] = "generic",
904 [SND_PCM_CLASS_MULTI
] = "multi",
905 [SND_PCM_CLASS_MODEM
] = "modem",
906 [SND_PCM_CLASS_DIGITIZER
] = "digitizer"
908 static const char * const class_table
[SND_PCM_CLASS_LAST
+1] = {
909 [SND_PCM_CLASS_GENERIC
] = "sound",
910 [SND_PCM_CLASS_MULTI
] = NULL
,
911 [SND_PCM_CLASS_MODEM
] = "modem",
912 [SND_PCM_CLASS_DIGITIZER
] = NULL
914 static const char * const alsa_subclass_table
[SND_PCM_SUBCLASS_LAST
+1] = {
915 [SND_PCM_SUBCLASS_GENERIC_MIX
] = "generic-mix",
916 [SND_PCM_SUBCLASS_MULTI_MIX
] = "multi-mix"
919 snd_pcm_class_t
class;
920 snd_pcm_subclass_t subclass
;
921 const char *n
, *id
, *sdn
;
927 pa_proplist_sets(p
, PA_PROP_DEVICE_API
, "alsa");
929 if ((class = snd_pcm_info_get_class(pcm_info
)) <= SND_PCM_CLASS_LAST
) {
930 if (class_table
[class])
931 pa_proplist_sets(p
, PA_PROP_DEVICE_CLASS
, class_table
[class]);
932 if (alsa_class_table
[class])
933 pa_proplist_sets(p
, "alsa.class", alsa_class_table
[class]);
936 if ((subclass
= snd_pcm_info_get_subclass(pcm_info
)) <= SND_PCM_SUBCLASS_LAST
)
937 if (alsa_subclass_table
[subclass
])
938 pa_proplist_sets(p
, "alsa.subclass", alsa_subclass_table
[subclass
]);
940 if ((n
= snd_pcm_info_get_name(pcm_info
)))
941 pa_proplist_sets(p
, "alsa.name", n
);
943 if ((id
= snd_pcm_info_get_id(pcm_info
)))
944 pa_proplist_sets(p
, "alsa.id", id
);
946 pa_proplist_setf(p
, "alsa.subdevice", "%u", snd_pcm_info_get_subdevice(pcm_info
));
947 if ((sdn
= snd_pcm_info_get_subdevice_name(pcm_info
)))
948 pa_proplist_sets(p
, "alsa.subdevice_name", sdn
);
950 pa_proplist_setf(p
, "alsa.device", "%u", snd_pcm_info_get_device(pcm_info
));
952 if ((card
= snd_pcm_info_get_card(pcm_info
)) >= 0)
953 pa_alsa_init_proplist_card(c
, p
, card
);
956 void pa_alsa_init_proplist_pcm(pa_core
*c
, pa_proplist
*p
, snd_pcm_t
*pcm
) {
957 snd_pcm_hw_params_t
*hwparams
;
958 snd_pcm_info_t
*info
;
961 snd_pcm_hw_params_alloca(&hwparams
);
962 snd_pcm_info_alloca(&info
);
964 if ((err
= snd_pcm_hw_params_current(pcm
, hwparams
)) < 0)
965 pa_log_warn("Error fetching hardware parameter info: %s", pa_alsa_strerror(err
));
968 if ((bits
= snd_pcm_hw_params_get_sbits(hwparams
)) >= 0)
969 pa_proplist_setf(p
, "alsa.resolution_bits", "%i", bits
);
972 if ((err
= snd_pcm_info(pcm
, info
)) < 0)
973 pa_log_warn("Error fetching PCM info: %s", pa_alsa_strerror(err
));
975 pa_alsa_init_proplist_pcm_info(c
, p
, info
);
978 void pa_alsa_init_proplist_ctl(pa_proplist
*p
, const char *name
) {
981 snd_ctl_card_info_t
*info
;
986 snd_ctl_card_info_alloca(&info
);
988 if ((err
= snd_ctl_open(&ctl
, name
, 0)) < 0) {
989 pa_log_warn("Error opening low-level control device '%s': %s", name
, snd_strerror(err
));
993 if ((err
= snd_ctl_card_info(ctl
, info
)) < 0) {
994 pa_log_warn("Control device %s card info: %s", name
, snd_strerror(err
));
999 if ((t
= snd_ctl_card_info_get_mixername(info
)) && *t
)
1000 pa_proplist_sets(p
, "alsa.mixer_name", t
);
1002 if ((t
= snd_ctl_card_info_get_components(info
)) && *t
)
1003 pa_proplist_sets(p
, "alsa.components", t
);
1008 int pa_alsa_recover_from_poll(snd_pcm_t
*pcm
, int revents
) {
1009 snd_pcm_state_t state
;
1014 if (revents
& POLLERR
)
1015 pa_log_debug("Got POLLERR from ALSA");
1016 if (revents
& POLLNVAL
)
1017 pa_log_warn("Got POLLNVAL from ALSA");
1018 if (revents
& POLLHUP
)
1019 pa_log_warn("Got POLLHUP from ALSA");
1020 if (revents
& POLLPRI
)
1021 pa_log_warn("Got POLLPRI from ALSA");
1022 if (revents
& POLLIN
)
1023 pa_log_debug("Got POLLIN from ALSA");
1024 if (revents
& POLLOUT
)
1025 pa_log_debug("Got POLLOUT from ALSA");
1027 state
= snd_pcm_state(pcm
);
1028 pa_log_debug("PCM state is %s", snd_pcm_state_name(state
));
1030 /* Try to recover from this error */
1034 case SND_PCM_STATE_XRUN
:
1035 if ((err
= snd_pcm_recover(pcm
, -EPIPE
, 1)) != 0) {
1036 pa_log_warn("Could not recover from POLLERR|POLLNVAL|POLLHUP and XRUN: %s", pa_alsa_strerror(err
));
1041 case SND_PCM_STATE_SUSPENDED
:
1042 if ((err
= snd_pcm_recover(pcm
, -ESTRPIPE
, 1)) != 0) {
1043 pa_log_warn("Could not recover from POLLERR|POLLNVAL|POLLHUP and SUSPENDED: %s", pa_alsa_strerror(err
));
1052 if ((err
= snd_pcm_prepare(pcm
)) < 0) {
1053 pa_log_warn("Could not recover from POLLERR|POLLNVAL|POLLHUP with snd_pcm_prepare(): %s", pa_alsa_strerror(err
));
1062 pa_rtpoll_item
* pa_alsa_build_pollfd(snd_pcm_t
*pcm
, pa_rtpoll
*rtpoll
) {
1064 struct pollfd
*pollfd
;
1065 pa_rtpoll_item
*item
;
1069 if ((n
= snd_pcm_poll_descriptors_count(pcm
)) < 0) {
1070 pa_log("snd_pcm_poll_descriptors_count() failed: %s", pa_alsa_strerror(n
));
1074 item
= pa_rtpoll_item_new(rtpoll
, PA_RTPOLL_NEVER
, (unsigned) n
);
1075 pollfd
= pa_rtpoll_item_get_pollfd(item
, NULL
);
1077 if ((err
= snd_pcm_poll_descriptors(pcm
, pollfd
, (unsigned) n
)) < 0) {
1078 pa_log("snd_pcm_poll_descriptors() failed: %s", pa_alsa_strerror(err
));
1079 pa_rtpoll_item_free(item
);
1086 snd_pcm_sframes_t
pa_alsa_safe_avail(snd_pcm_t
*pcm
, size_t hwbuf_size
, const pa_sample_spec
*ss
) {
1087 snd_pcm_sframes_t n
;
1091 pa_assert(hwbuf_size
> 0);
1094 /* Some ALSA driver expose weird bugs, let's inform the user about
1095 * what is going on */
1097 n
= snd_pcm_avail(pcm
);
1102 k
= (size_t) n
* pa_frame_size(ss
);
1104 if (k
>= hwbuf_size
* 5 ||
1105 k
>= pa_bytes_per_second(ss
)*10) {
1108 char *dn
= pa_alsa_get_driver_name_by_pcm(pcm
);
1109 pa_log(_("snd_pcm_avail() returned a value that is exceptionally large: %lu bytes (%lu ms).\n"
1110 "Most likely this is a bug in the ALSA driver '%s'. Please report this issue to the ALSA developers."),
1112 (unsigned long) (pa_bytes_to_usec(k
, ss
) / PA_USEC_PER_MSEC
),
1115 pa_alsa_dump(PA_LOG_ERROR
, pcm
);
1118 /* Mhmm, let's try not to fail completely */
1119 n
= (snd_pcm_sframes_t
) (hwbuf_size
/ pa_frame_size(ss
));
1125 int pa_alsa_safe_delay(snd_pcm_t
*pcm
, snd_pcm_sframes_t
*delay
, size_t hwbuf_size
, const pa_sample_spec
*ss
) {
1132 pa_assert(hwbuf_size
> 0);
1135 /* Some ALSA driver expose weird bugs, let's inform the user about
1136 * what is going on */
1138 if ((r
= snd_pcm_delay(pcm
, delay
)) < 0)
1141 k
= (ssize_t
) *delay
* (ssize_t
) pa_frame_size(ss
);
1143 abs_k
= k
>= 0 ? (size_t) k
: (size_t) -k
;
1145 if (abs_k
>= hwbuf_size
* 5 ||
1146 abs_k
>= pa_bytes_per_second(ss
)*10) {
1149 char *dn
= pa_alsa_get_driver_name_by_pcm(pcm
);
1150 pa_log(_("snd_pcm_delay() returned a value that is exceptionally large: %li bytes (%s%lu ms).\n"
1151 "Most likely this is a bug in the ALSA driver '%s'. Please report this issue to the ALSA developers."),
1154 (unsigned long) (pa_bytes_to_usec(abs_k
, ss
) / PA_USEC_PER_MSEC
),
1157 pa_alsa_dump(PA_LOG_ERROR
, pcm
);
1160 /* Mhmm, let's try not to fail completely */
1162 *delay
= -(snd_pcm_sframes_t
) (hwbuf_size
/ pa_frame_size(ss
));
1164 *delay
= (snd_pcm_sframes_t
) (hwbuf_size
/ pa_frame_size(ss
));
1170 int pa_alsa_safe_mmap_begin(snd_pcm_t
*pcm
, const snd_pcm_channel_area_t
**areas
, snd_pcm_uframes_t
*offset
, snd_pcm_uframes_t
*frames
, size_t hwbuf_size
, const pa_sample_spec
*ss
) {
1172 snd_pcm_uframes_t before
;
1179 pa_assert(hwbuf_size
> 0);
1184 r
= snd_pcm_mmap_begin(pcm
, areas
, offset
, frames
);
1189 k
= (size_t) *frames
* pa_frame_size(ss
);
1191 if (*frames
> before
||
1192 k
>= hwbuf_size
* 3 ||
1193 k
>= pa_bytes_per_second(ss
)*10)
1196 char *dn
= pa_alsa_get_driver_name_by_pcm(pcm
);
1197 pa_log(_("snd_pcm_mmap_begin() returned a value that is exceptionally large: %lu bytes (%lu ms).\n"
1198 "Most likely this is a bug in the ALSA driver '%s'. Please report this issue to the ALSA developers."),
1200 (unsigned long) (pa_bytes_to_usec(k
, ss
) / PA_USEC_PER_MSEC
),
1203 pa_alsa_dump(PA_LOG_ERROR
, pcm
);
1209 char *pa_alsa_get_driver_name(int card
) {
1212 pa_assert(card
>= 0);
1214 t
= pa_sprintf_malloc("/sys/class/sound/card%i/device/driver/module", card
);
1221 n
= pa_xstrdup(pa_path_get_filename(m
));
1227 char *pa_alsa_get_driver_name_by_pcm(snd_pcm_t
*pcm
) {
1229 snd_pcm_info_t
* info
;
1230 snd_pcm_info_alloca(&info
);
1234 if (snd_pcm_info(pcm
, info
) < 0)
1237 if ((card
= snd_pcm_info_get_card(info
)) < 0)
1240 return pa_alsa_get_driver_name(card
);
1243 char *pa_alsa_get_reserve_name(const char *device
) {
1249 if ((t
= strchr(device
, ':')))
1252 if ((i
= snd_card_get_index(device
)) < 0) {
1255 if (pa_atoi(device
, &k
) < 0)
1261 return pa_sprintf_malloc("Audio%i", i
);
1264 pa_bool_t
pa_alsa_pcm_is_hw(snd_pcm_t
*pcm
) {
1265 snd_pcm_info_t
* info
;
1266 snd_pcm_info_alloca(&info
);
1270 if (snd_pcm_info(pcm
, info
) < 0)
1273 return snd_pcm_info_get_card(info
) >= 0;
1276 pa_bool_t
pa_alsa_pcm_is_modem(snd_pcm_t
*pcm
) {
1277 snd_pcm_info_t
* info
;
1278 snd_pcm_info_alloca(&info
);
1282 if (snd_pcm_info(pcm
, info
) < 0)
1285 return snd_pcm_info_get_class(info
) == SND_PCM_CLASS_MODEM
;
1288 PA_STATIC_TLS_DECLARE(cstrerror
, pa_xfree
);
1290 const char* pa_alsa_strerror(int errnum
) {
1291 const char *original
= NULL
;
1292 char *translated
, *t
;
1295 if ((t
= PA_STATIC_TLS_GET(cstrerror
)))
1298 original
= snd_strerror(errnum
);
1301 pa_snprintf(errbuf
, sizeof(errbuf
), "Unknown error %i", errnum
);
1305 if (!(translated
= pa_locale_to_utf8(original
))) {
1306 pa_log_warn("Unable to convert error string to locale, filtering.");
1307 translated
= pa_utf8_filter(original
);
1310 PA_STATIC_TLS_SET(cstrerror
, translated
);
1315 pa_bool_t
pa_alsa_may_tsched(pa_bool_t want
) {
1320 if (!pa_rtclock_hrtimer()) {
1321 /* We cannot depend on being woken up in time when the timers
1322 are inaccurate, so let's fallback to classic IO based playback
1324 pa_log_notice("Disabling timer-based scheduling because high-resolution timers are not available from the kernel.");
1327 if (pa_running_in_vm()) {
1328 /* We cannot depend on being woken up when we ask for in a VM,
1329 * so let's fallback to classic IO based playback then. */
1330 pa_log_notice("Disabling timer-based scheduling because running inside a VM.");