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
;
407 int pa_alsa_set_sw_params(snd_pcm_t
*pcm
, snd_pcm_uframes_t avail_min
, pa_bool_t period_event
) {
408 snd_pcm_sw_params_t
*swparams
;
409 snd_pcm_uframes_t boundary
;
414 snd_pcm_sw_params_alloca(&swparams
);
416 if ((err
= snd_pcm_sw_params_current(pcm
, swparams
) < 0)) {
417 pa_log_warn("Unable to determine current swparams: %s\n", pa_alsa_strerror(err
));
421 if ((err
= snd_pcm_sw_params_set_period_event(pcm
, swparams
, period_event
)) < 0) {
422 pa_log_warn("Unable to disable period event: %s\n", pa_alsa_strerror(err
));
426 if ((err
= snd_pcm_sw_params_set_tstamp_mode(pcm
, swparams
, SND_PCM_TSTAMP_ENABLE
)) < 0) {
427 pa_log_warn("Unable to enable time stamping: %s\n", pa_alsa_strerror(err
));
431 if ((err
= snd_pcm_sw_params_get_boundary(swparams
, &boundary
)) < 0) {
432 pa_log_warn("Unable to get boundary: %s\n", pa_alsa_strerror(err
));
436 if ((err
= snd_pcm_sw_params_set_stop_threshold(pcm
, swparams
, boundary
)) < 0) {
437 pa_log_warn("Unable to set stop threshold: %s\n", pa_alsa_strerror(err
));
441 if ((err
= snd_pcm_sw_params_set_start_threshold(pcm
, swparams
, (snd_pcm_uframes_t
) -1)) < 0) {
442 pa_log_warn("Unable to set start threshold: %s\n", pa_alsa_strerror(err
));
446 if ((err
= snd_pcm_sw_params_set_avail_min(pcm
, swparams
, avail_min
)) < 0) {
447 pa_log_error("snd_pcm_sw_params_set_avail_min() failed: %s", pa_alsa_strerror(err
));
451 if ((err
= snd_pcm_sw_params(pcm
, swparams
)) < 0) {
452 pa_log_warn("Unable to set sw params: %s\n", pa_alsa_strerror(err
));
459 snd_pcm_t
*pa_alsa_open_by_device_id_auto(
465 snd_pcm_uframes_t
*period_size
,
466 snd_pcm_uframes_t
*buffer_size
,
467 snd_pcm_uframes_t tsched_size
,
469 pa_bool_t
*use_tsched
,
470 pa_alsa_profile_set
*ps
,
471 pa_alsa_mapping
**mapping
) {
474 snd_pcm_t
*pcm_handle
;
484 /* First we try to find a device string with a superset of the
485 * requested channel map. We iterate through our device table from
486 * top to bottom and take the first that matches. If we didn't
487 * find a working device that way, we iterate backwards, and check
488 * all devices that do not provide a superset of the requested
491 PA_HASHMAP_FOREACH(m
, ps
->mappings
, state
) {
492 if (!pa_channel_map_superset(&m
->channel_map
, map
))
495 pa_log_debug("Checking for superset %s (%s)", m
->name
, m
->device_strings
[0]);
497 pcm_handle
= pa_alsa_open_by_device_id_mapping(
518 PA_HASHMAP_FOREACH_BACKWARDS(m
, ps
->mappings
, state
) {
519 if (pa_channel_map_superset(&m
->channel_map
, map
))
522 pa_log_debug("Checking for subset %s (%s)", m
->name
, m
->device_strings
[0]);
524 pcm_handle
= pa_alsa_open_by_device_id_mapping(
545 /* OK, we didn't find any good device, so let's try the raw hw: stuff */
546 d
= pa_sprintf_malloc("hw:%s", dev_id
);
547 pa_log_debug("Trying %s as last resort...", d
);
548 pcm_handle
= pa_alsa_open_by_device_string(
562 if (pcm_handle
&& mapping
)
568 snd_pcm_t
*pa_alsa_open_by_device_id_mapping(
574 snd_pcm_uframes_t
*period_size
,
575 snd_pcm_uframes_t
*buffer_size
,
576 snd_pcm_uframes_t tsched_size
,
578 pa_bool_t
*use_tsched
,
579 pa_alsa_mapping
*m
) {
581 snd_pcm_t
*pcm_handle
;
582 pa_sample_spec try_ss
;
583 pa_channel_map try_map
;
591 try_ss
.channels
= m
->channel_map
.channels
;
592 try_ss
.rate
= ss
->rate
;
593 try_ss
.format
= ss
->format
;
594 try_map
= m
->channel_map
;
596 pcm_handle
= pa_alsa_open_by_template(
615 pa_assert(map
->channels
== ss
->channels
);
620 snd_pcm_t
*pa_alsa_open_by_device_string(
626 snd_pcm_uframes_t
*period_size
,
627 snd_pcm_uframes_t
*buffer_size
,
628 snd_pcm_uframes_t tsched_size
,
630 pa_bool_t
*use_tsched
,
631 pa_bool_t require_exact_channel_number
) {
635 snd_pcm_t
*pcm_handle
;
636 pa_bool_t reformat
= FALSE
;
642 d
= pa_xstrdup(device
);
645 pa_log_debug("Trying %s %s SND_PCM_NO_AUTO_FORMAT ...", d
, reformat
? "without" : "with");
647 if ((err
= snd_pcm_open(&pcm_handle
, d
, mode
,
649 SND_PCM_NO_AUTO_RESAMPLE
|
650 SND_PCM_NO_AUTO_CHANNELS
|
651 (reformat
? 0 : SND_PCM_NO_AUTO_FORMAT
))) < 0) {
652 pa_log_info("Error opening PCM device %s: %s", d
, pa_alsa_strerror(err
));
656 pa_log_debug("Managed to open %s", d
);
658 if ((err
= pa_alsa_set_hw_params(
666 require_exact_channel_number
)) < 0) {
671 snd_pcm_close(pcm_handle
);
675 /* Hmm, some hw is very exotic, so we retry with plug, if without it didn't work */
676 if (!pa_startswith(d
, "plug:") && !pa_startswith(d
, "plughw:")) {
679 t
= pa_sprintf_malloc("plug:%s", d
);
685 snd_pcm_close(pcm_handle
);
689 pa_log_info("Failed to set hardware parameters on %s: %s", d
, pa_alsa_strerror(err
));
690 snd_pcm_close(pcm_handle
);
700 if (ss
->channels
!= map
->channels
)
701 pa_channel_map_init_extend(map
, ss
->channels
, PA_CHANNEL_MAP_ALSA
);
712 snd_pcm_t
*pa_alsa_open_by_template(
719 snd_pcm_uframes_t
*period_size
,
720 snd_pcm_uframes_t
*buffer_size
,
721 snd_pcm_uframes_t tsched_size
,
723 pa_bool_t
*use_tsched
,
724 pa_bool_t require_exact_channel_number
) {
726 snd_pcm_t
*pcm_handle
;
729 for (i
= template; *i
; i
++) {
732 d
= pa_replace(*i
, "%f", dev_id
);
734 pcm_handle
= pa_alsa_open_by_device_string(
745 require_exact_channel_number
);
756 void pa_alsa_dump(pa_log_level_t level
, snd_pcm_t
*pcm
) {
762 pa_assert_se(snd_output_buffer_open(&out
) == 0);
764 if ((err
= snd_pcm_dump(pcm
, out
)) < 0)
765 pa_logl(level
, "snd_pcm_dump(): %s", pa_alsa_strerror(err
));
768 snd_output_buffer_string(out
, &s
);
769 pa_logl(level
, "snd_pcm_dump():\n%s", pa_strnull(s
));
772 pa_assert_se(snd_output_close(out
) == 0);
775 void pa_alsa_dump_status(snd_pcm_t
*pcm
) {
778 snd_pcm_status_t
*status
;
783 snd_pcm_status_alloca(&status
);
785 if ((err
= snd_output_buffer_open(&out
)) < 0) {
786 pa_log_debug("snd_output_buffer_open() failed: %s", pa_cstrerror(err
));
790 if ((err
= snd_pcm_status(pcm
, status
)) < 0) {
791 pa_log_debug("snd_pcm_status() failed: %s", pa_cstrerror(err
));
795 if ((err
= snd_pcm_status_dump(status
, out
)) < 0) {
796 pa_log_debug("snd_pcm_dump(): %s", pa_alsa_strerror(err
));
800 snd_output_buffer_string(out
, &s
);
801 pa_log_debug("snd_pcm_dump():\n%s", pa_strnull(s
));
805 snd_output_close(out
);
808 static void alsa_error_handler(const char *file
, int line
, const char *function
, int err
, const char *fmt
,...) {
812 alsa_file
= pa_sprintf_malloc("(alsa-lib)%s", file
);
816 pa_log_levelv_meta(PA_LOG_INFO
, alsa_file
, line
, function
, fmt
, ap
);
823 static pa_atomic_t n_error_handler_installed
= PA_ATOMIC_INIT(0);
825 void pa_alsa_refcnt_inc(void) {
826 /* This is not really thread safe, but we do our best */
828 if (pa_atomic_inc(&n_error_handler_installed
) == 0)
829 snd_lib_error_set_handler(alsa_error_handler
);
832 void pa_alsa_refcnt_dec(void) {
835 pa_assert_se((r
= pa_atomic_dec(&n_error_handler_installed
)) >= 1);
838 snd_lib_error_set_handler(NULL
);
839 snd_config_update_free_global();
843 pa_bool_t
pa_alsa_init_description(pa_proplist
*p
) {
847 if (pa_device_init_description(p
))
850 if (!(d
= pa_proplist_gets(p
, "alsa.card_name")))
851 d
= pa_proplist_gets(p
, "alsa.name");
856 k
= pa_proplist_gets(p
, PA_PROP_DEVICE_PROFILE_DESCRIPTION
);
859 pa_proplist_setf(p
, PA_PROP_DEVICE_DESCRIPTION
, _("%s %s"), d
, k
);
861 pa_proplist_sets(p
, PA_PROP_DEVICE_DESCRIPTION
, d
);
866 void pa_alsa_init_proplist_card(pa_core
*c
, pa_proplist
*p
, int card
) {
870 pa_assert(card
>= 0);
872 pa_proplist_setf(p
, "alsa.card", "%i", card
);
874 if (snd_card_get_name(card
, &cn
) >= 0) {
875 pa_proplist_sets(p
, "alsa.card_name", pa_strip(cn
));
879 if (snd_card_get_longname(card
, &lcn
) >= 0) {
880 pa_proplist_sets(p
, "alsa.long_card_name", pa_strip(lcn
));
884 if ((dn
= pa_alsa_get_driver_name(card
))) {
885 pa_proplist_sets(p
, "alsa.driver_name", dn
);
890 pa_udev_get_info(card
, p
);
894 pa_hal_get_info(c
, p
, card
);
898 void pa_alsa_init_proplist_pcm_info(pa_core
*c
, pa_proplist
*p
, snd_pcm_info_t
*pcm_info
) {
900 static const char * const alsa_class_table
[SND_PCM_CLASS_LAST
+1] = {
901 [SND_PCM_CLASS_GENERIC
] = "generic",
902 [SND_PCM_CLASS_MULTI
] = "multi",
903 [SND_PCM_CLASS_MODEM
] = "modem",
904 [SND_PCM_CLASS_DIGITIZER
] = "digitizer"
906 static const char * const class_table
[SND_PCM_CLASS_LAST
+1] = {
907 [SND_PCM_CLASS_GENERIC
] = "sound",
908 [SND_PCM_CLASS_MULTI
] = NULL
,
909 [SND_PCM_CLASS_MODEM
] = "modem",
910 [SND_PCM_CLASS_DIGITIZER
] = NULL
912 static const char * const alsa_subclass_table
[SND_PCM_SUBCLASS_LAST
+1] = {
913 [SND_PCM_SUBCLASS_GENERIC_MIX
] = "generic-mix",
914 [SND_PCM_SUBCLASS_MULTI_MIX
] = "multi-mix"
917 snd_pcm_class_t
class;
918 snd_pcm_subclass_t subclass
;
919 const char *n
, *id
, *sdn
;
925 pa_proplist_sets(p
, PA_PROP_DEVICE_API
, "alsa");
927 if ((class = snd_pcm_info_get_class(pcm_info
)) <= SND_PCM_CLASS_LAST
) {
928 if (class_table
[class])
929 pa_proplist_sets(p
, PA_PROP_DEVICE_CLASS
, class_table
[class]);
930 if (alsa_class_table
[class])
931 pa_proplist_sets(p
, "alsa.class", alsa_class_table
[class]);
934 if ((subclass
= snd_pcm_info_get_subclass(pcm_info
)) <= SND_PCM_SUBCLASS_LAST
)
935 if (alsa_subclass_table
[subclass
])
936 pa_proplist_sets(p
, "alsa.subclass", alsa_subclass_table
[subclass
]);
938 if ((n
= snd_pcm_info_get_name(pcm_info
))) {
939 char *t
= pa_xstrdup(n
);
940 pa_proplist_sets(p
, "alsa.name", pa_strip(t
));
944 if ((id
= snd_pcm_info_get_id(pcm_info
)))
945 pa_proplist_sets(p
, "alsa.id", id
);
947 pa_proplist_setf(p
, "alsa.subdevice", "%u", snd_pcm_info_get_subdevice(pcm_info
));
948 if ((sdn
= snd_pcm_info_get_subdevice_name(pcm_info
)))
949 pa_proplist_sets(p
, "alsa.subdevice_name", sdn
);
951 pa_proplist_setf(p
, "alsa.device", "%u", snd_pcm_info_get_device(pcm_info
));
953 if ((card
= snd_pcm_info_get_card(pcm_info
)) >= 0)
954 pa_alsa_init_proplist_card(c
, p
, card
);
957 void pa_alsa_init_proplist_pcm(pa_core
*c
, pa_proplist
*p
, snd_pcm_t
*pcm
) {
958 snd_pcm_hw_params_t
*hwparams
;
959 snd_pcm_info_t
*info
;
962 snd_pcm_hw_params_alloca(&hwparams
);
963 snd_pcm_info_alloca(&info
);
965 if ((err
= snd_pcm_hw_params_current(pcm
, hwparams
)) < 0)
966 pa_log_warn("Error fetching hardware parameter info: %s", pa_alsa_strerror(err
));
969 if ((bits
= snd_pcm_hw_params_get_sbits(hwparams
)) >= 0)
970 pa_proplist_setf(p
, "alsa.resolution_bits", "%i", bits
);
973 if ((err
= snd_pcm_info(pcm
, info
)) < 0)
974 pa_log_warn("Error fetching PCM info: %s", pa_alsa_strerror(err
));
976 pa_alsa_init_proplist_pcm_info(c
, p
, info
);
979 void pa_alsa_init_proplist_ctl(pa_proplist
*p
, const char *name
) {
982 snd_ctl_card_info_t
*info
;
987 snd_ctl_card_info_alloca(&info
);
989 if ((err
= snd_ctl_open(&ctl
, name
, 0)) < 0) {
990 pa_log_warn("Error opening low-level control device '%s': %s", name
, snd_strerror(err
));
994 if ((err
= snd_ctl_card_info(ctl
, info
)) < 0) {
995 pa_log_warn("Control device %s card info: %s", name
, snd_strerror(err
));
1000 if ((t
= snd_ctl_card_info_get_mixername(info
)) && *t
)
1001 pa_proplist_sets(p
, "alsa.mixer_name", t
);
1003 if ((t
= snd_ctl_card_info_get_components(info
)) && *t
)
1004 pa_proplist_sets(p
, "alsa.components", t
);
1009 int pa_alsa_recover_from_poll(snd_pcm_t
*pcm
, int revents
) {
1010 snd_pcm_state_t state
;
1015 if (revents
& POLLERR
)
1016 pa_log_debug("Got POLLERR from ALSA");
1017 if (revents
& POLLNVAL
)
1018 pa_log_warn("Got POLLNVAL from ALSA");
1019 if (revents
& POLLHUP
)
1020 pa_log_warn("Got POLLHUP from ALSA");
1021 if (revents
& POLLPRI
)
1022 pa_log_warn("Got POLLPRI from ALSA");
1023 if (revents
& POLLIN
)
1024 pa_log_debug("Got POLLIN from ALSA");
1025 if (revents
& POLLOUT
)
1026 pa_log_debug("Got POLLOUT from ALSA");
1028 state
= snd_pcm_state(pcm
);
1029 pa_log_debug("PCM state is %s", snd_pcm_state_name(state
));
1031 /* Try to recover from this error */
1035 case SND_PCM_STATE_XRUN
:
1036 if ((err
= snd_pcm_recover(pcm
, -EPIPE
, 1)) != 0) {
1037 pa_log_warn("Could not recover from POLLERR|POLLNVAL|POLLHUP and XRUN: %s", pa_alsa_strerror(err
));
1042 case SND_PCM_STATE_SUSPENDED
:
1043 if ((err
= snd_pcm_recover(pcm
, -ESTRPIPE
, 1)) != 0) {
1044 pa_log_warn("Could not recover from POLLERR|POLLNVAL|POLLHUP and SUSPENDED: %s", pa_alsa_strerror(err
));
1053 if ((err
= snd_pcm_prepare(pcm
)) < 0) {
1054 pa_log_warn("Could not recover from POLLERR|POLLNVAL|POLLHUP with snd_pcm_prepare(): %s", pa_alsa_strerror(err
));
1063 pa_rtpoll_item
* pa_alsa_build_pollfd(snd_pcm_t
*pcm
, pa_rtpoll
*rtpoll
) {
1065 struct pollfd
*pollfd
;
1066 pa_rtpoll_item
*item
;
1070 if ((n
= snd_pcm_poll_descriptors_count(pcm
)) < 0) {
1071 pa_log("snd_pcm_poll_descriptors_count() failed: %s", pa_alsa_strerror(n
));
1075 item
= pa_rtpoll_item_new(rtpoll
, PA_RTPOLL_NEVER
, (unsigned) n
);
1076 pollfd
= pa_rtpoll_item_get_pollfd(item
, NULL
);
1078 if ((err
= snd_pcm_poll_descriptors(pcm
, pollfd
, (unsigned) n
)) < 0) {
1079 pa_log("snd_pcm_poll_descriptors() failed: %s", pa_alsa_strerror(err
));
1080 pa_rtpoll_item_free(item
);
1087 snd_pcm_sframes_t
pa_alsa_safe_avail(snd_pcm_t
*pcm
, size_t hwbuf_size
, const pa_sample_spec
*ss
) {
1088 snd_pcm_sframes_t n
;
1092 pa_assert(hwbuf_size
> 0);
1095 /* Some ALSA driver expose weird bugs, let's inform the user about
1096 * what is going on */
1098 n
= snd_pcm_avail(pcm
);
1103 k
= (size_t) n
* pa_frame_size(ss
);
1105 if (k
>= hwbuf_size
* 5 ||
1106 k
>= pa_bytes_per_second(ss
)*10) {
1109 char *dn
= pa_alsa_get_driver_name_by_pcm(pcm
);
1110 pa_log(_("snd_pcm_avail() returned a value that is exceptionally large: %lu bytes (%lu ms).\n"
1111 "Most likely this is a bug in the ALSA driver '%s'. Please report this issue to the ALSA developers."),
1113 (unsigned long) (pa_bytes_to_usec(k
, ss
) / PA_USEC_PER_MSEC
),
1116 pa_alsa_dump(PA_LOG_ERROR
, pcm
);
1119 /* Mhmm, let's try not to fail completely */
1120 n
= (snd_pcm_sframes_t
) (hwbuf_size
/ pa_frame_size(ss
));
1126 int pa_alsa_safe_delay(snd_pcm_t
*pcm
, snd_pcm_sframes_t
*delay
, size_t hwbuf_size
, const pa_sample_spec
*ss
, pa_bool_t capture
) {
1130 snd_pcm_sframes_t avail
= 0;
1134 pa_assert(hwbuf_size
> 0);
1137 /* Some ALSA driver expose weird bugs, let's inform the user about
1138 * what is going on. We're going to get both the avail and delay values so
1139 * that we can compare and check them for capture */
1141 if ((r
= snd_pcm_avail_delay(pcm
, &avail
, delay
)) < 0)
1144 k
= (ssize_t
) *delay
* (ssize_t
) pa_frame_size(ss
);
1146 abs_k
= k
>= 0 ? (size_t) k
: (size_t) -k
;
1148 if (abs_k
>= hwbuf_size
* 5 ||
1149 abs_k
>= pa_bytes_per_second(ss
)*10) {
1152 char *dn
= pa_alsa_get_driver_name_by_pcm(pcm
);
1153 pa_log(_("snd_pcm_delay() returned a value that is exceptionally large: %li bytes (%s%lu ms).\n"
1154 "Most likely this is a bug in the ALSA driver '%s'. Please report this issue to the ALSA developers."),
1157 (unsigned long) (pa_bytes_to_usec(abs_k
, ss
) / PA_USEC_PER_MSEC
),
1160 pa_alsa_dump(PA_LOG_ERROR
, pcm
);
1163 /* Mhmm, let's try not to fail completely */
1165 *delay
= -(snd_pcm_sframes_t
) (hwbuf_size
/ pa_frame_size(ss
));
1167 *delay
= (snd_pcm_sframes_t
) (hwbuf_size
/ pa_frame_size(ss
));
1171 abs_k
= (size_t) avail
* pa_frame_size(ss
);
1173 if (abs_k
>= hwbuf_size
* 5 ||
1174 abs_k
>= pa_bytes_per_second(ss
)*10) {
1177 char *dn
= pa_alsa_get_driver_name_by_pcm(pcm
);
1178 pa_log(_("snd_pcm_avail() returned a value that is exceptionally large: %lu bytes (%lu ms).\n"
1179 "Most likely this is a bug in the ALSA driver '%s'. Please report this issue to the ALSA developers."),
1181 (unsigned long) (pa_bytes_to_usec(k
, ss
) / PA_USEC_PER_MSEC
),
1184 pa_alsa_dump(PA_LOG_ERROR
, pcm
);
1187 /* Mhmm, let's try not to fail completely */
1188 avail
= (snd_pcm_sframes_t
) (hwbuf_size
/ pa_frame_size(ss
));
1191 if (*delay
< avail
) {
1193 char *dn
= pa_alsa_get_driver_name_by_pcm(pcm
);
1194 pa_log(_("snd_pcm_avail_delay() returned strange values: delay %lu is less than avail %lu.\n"
1195 "Most likely this is a bug in the ALSA driver '%s'. Please report this issue to the ALSA developers."),
1196 (unsigned long) *delay
,
1197 (unsigned long) avail
,
1200 pa_alsa_dump(PA_LOG_ERROR
, pcm
);
1211 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
) {
1213 snd_pcm_uframes_t before
;
1220 pa_assert(hwbuf_size
> 0);
1225 r
= snd_pcm_mmap_begin(pcm
, areas
, offset
, frames
);
1230 k
= (size_t) *frames
* pa_frame_size(ss
);
1232 if (*frames
> before
||
1233 k
>= hwbuf_size
* 3 ||
1234 k
>= pa_bytes_per_second(ss
)*10)
1237 char *dn
= pa_alsa_get_driver_name_by_pcm(pcm
);
1238 pa_log(_("snd_pcm_mmap_begin() returned a value that is exceptionally large: %lu bytes (%lu ms).\n"
1239 "Most likely this is a bug in the ALSA driver '%s'. Please report this issue to the ALSA developers."),
1241 (unsigned long) (pa_bytes_to_usec(k
, ss
) / PA_USEC_PER_MSEC
),
1244 pa_alsa_dump(PA_LOG_ERROR
, pcm
);
1250 char *pa_alsa_get_driver_name(int card
) {
1253 pa_assert(card
>= 0);
1255 t
= pa_sprintf_malloc("/sys/class/sound/card%i/device/driver/module", card
);
1262 n
= pa_xstrdup(pa_path_get_filename(m
));
1268 char *pa_alsa_get_driver_name_by_pcm(snd_pcm_t
*pcm
) {
1270 snd_pcm_info_t
* info
;
1271 snd_pcm_info_alloca(&info
);
1275 if (snd_pcm_info(pcm
, info
) < 0)
1278 if ((card
= snd_pcm_info_get_card(info
)) < 0)
1281 return pa_alsa_get_driver_name(card
);
1284 char *pa_alsa_get_reserve_name(const char *device
) {
1290 if ((t
= strchr(device
, ':')))
1293 if ((i
= snd_card_get_index(device
)) < 0) {
1296 if (pa_atoi(device
, &k
) < 0)
1302 return pa_sprintf_malloc("Audio%i", i
);
1305 pa_bool_t
pa_alsa_pcm_is_hw(snd_pcm_t
*pcm
) {
1306 snd_pcm_info_t
* info
;
1307 snd_pcm_info_alloca(&info
);
1311 if (snd_pcm_info(pcm
, info
) < 0)
1314 return snd_pcm_info_get_card(info
) >= 0;
1317 pa_bool_t
pa_alsa_pcm_is_modem(snd_pcm_t
*pcm
) {
1318 snd_pcm_info_t
* info
;
1319 snd_pcm_info_alloca(&info
);
1323 if (snd_pcm_info(pcm
, info
) < 0)
1326 return snd_pcm_info_get_class(info
) == SND_PCM_CLASS_MODEM
;
1329 PA_STATIC_TLS_DECLARE(cstrerror
, pa_xfree
);
1331 const char* pa_alsa_strerror(int errnum
) {
1332 const char *original
= NULL
;
1333 char *translated
, *t
;
1336 if ((t
= PA_STATIC_TLS_GET(cstrerror
)))
1339 original
= snd_strerror(errnum
);
1342 pa_snprintf(errbuf
, sizeof(errbuf
), "Unknown error %i", errnum
);
1346 if (!(translated
= pa_locale_to_utf8(original
))) {
1347 pa_log_warn("Unable to convert error string to locale, filtering.");
1348 translated
= pa_utf8_filter(original
);
1351 PA_STATIC_TLS_SET(cstrerror
, translated
);
1356 pa_bool_t
pa_alsa_may_tsched(pa_bool_t want
) {
1361 if (!pa_rtclock_hrtimer()) {
1362 /* We cannot depend on being woken up in time when the timers
1363 are inaccurate, so let's fallback to classic IO based playback
1365 pa_log_notice("Disabling timer-based scheduling because high-resolution timers are not available from the kernel.");
1368 if (pa_running_in_vm()) {
1369 /* We cannot depend on being woken up when we ask for in a VM,
1370 * so let's fallback to classic IO based playback then. */
1371 pa_log_notice("Disabling timer-based scheduling because running inside a VM.");