alsa: disable timer-based scheduling inside a VM
[platform/upstream/pulseaudio.git] / src / modules / alsa / alsa-util.c
1 /***
2   This file is part of PulseAudio.
3
4   Copyright 2004-2009 Lennart Poettering
5   Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
6
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.
11
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.
16
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
20   USA.
21 ***/
22
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26
27 #include <sys/types.h>
28 #include <limits.h>
29 #include <asoundlib.h>
30
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>
37
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>
47
48 #include "alsa-util.h"
49 #include "alsa-mixer.h"
50
51 #ifdef HAVE_HAL
52 #include "hal-util.h"
53 #endif
54
55 #ifdef HAVE_UDEV
56 #include "udev-util.h"
57 #endif
58
59 static int set_format(snd_pcm_t *pcm_handle, snd_pcm_hw_params_t *hwparams, pa_sample_format_t *f) {
60
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,
75     };
76
77     static const pa_sample_format_t try_order[] = {
78         PA_SAMPLE_FLOAT32NE,
79         PA_SAMPLE_FLOAT32RE,
80         PA_SAMPLE_S32NE,
81         PA_SAMPLE_S32RE,
82         PA_SAMPLE_S24_32NE,
83         PA_SAMPLE_S24_32RE,
84         PA_SAMPLE_S24NE,
85         PA_SAMPLE_S24RE,
86         PA_SAMPLE_S16NE,
87         PA_SAMPLE_S16RE,
88         PA_SAMPLE_ALAW,
89         PA_SAMPLE_ULAW,
90         PA_SAMPLE_U8
91     };
92
93     unsigned i;
94     int ret;
95
96     pa_assert(pcm_handle);
97     pa_assert(hwparams);
98     pa_assert(f);
99
100     if ((ret = snd_pcm_hw_params_set_format(pcm_handle, hwparams, format_trans[*f])) >= 0)
101         return ret;
102
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));
106
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;
127     else
128         goto try_auto;
129
130     if ((ret = snd_pcm_hw_params_set_format(pcm_handle, hwparams, format_trans[*f])) >= 0)
131         return ret;
132
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));
136
137 try_auto:
138
139     for (i = 0; i < PA_ELEMENTSOF(try_order); i++) {
140         *f = try_order[i];
141
142         if ((ret = snd_pcm_hw_params_set_format(pcm_handle, hwparams, format_trans[*f])) >= 0)
143             return ret;
144
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));
148     }
149
150     return -1;
151 }
152
153 static int set_period_size(snd_pcm_t *pcm_handle, snd_pcm_hw_params_t *hwparams, snd_pcm_uframes_t size) {
154     snd_pcm_uframes_t s;
155     int d, ret;
156
157     pa_assert(pcm_handle);
158     pa_assert(hwparams);
159
160     s = size;
161     d = 0;
162     if (snd_pcm_hw_params_set_period_size_near(pcm_handle, hwparams, &s, &d) < 0) {
163         s = size;
164         d = -1;
165         if (snd_pcm_hw_params_set_period_size_near(pcm_handle, hwparams, &s, &d) < 0) {
166             s = size;
167             d = 1;
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));
170                 return ret;
171             }
172         }
173     }
174
175     return 0;
176 }
177
178 static int set_buffer_size(snd_pcm_t *pcm_handle, snd_pcm_hw_params_t *hwparams, snd_pcm_uframes_t size) {
179     int ret;
180
181     pa_assert(pcm_handle);
182     pa_assert(hwparams);
183
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));
186         return ret;
187     }
188
189     return 0;
190 }
191
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,
196         pa_sample_spec *ss,
197         snd_pcm_uframes_t *period_size,
198         snd_pcm_uframes_t *buffer_size,
199         snd_pcm_uframes_t tsched_size,
200         pa_bool_t *use_mmap,
201         pa_bool_t *use_tsched,
202         pa_bool_t require_exact_channel_number) {
203
204     int ret = -1;
205     snd_pcm_hw_params_t *hwparams, *hwparams_copy;
206     int dir;
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;
212
213     pa_assert(pcm_handle);
214     pa_assert(ss);
215
216     snd_pcm_hw_params_alloca(&hwparams);
217     snd_pcm_hw_params_alloca(&hwparams_copy);
218
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));
221         goto finish;
222     }
223
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));
226         goto finish;
227     }
228
229     if (_use_mmap) {
230
231         if (snd_pcm_hw_params_set_access(pcm_handle, hwparams, SND_PCM_ACCESS_MMAP_INTERLEAVED) < 0) {
232
233             /* mmap() didn't work, fall back to interleaved */
234
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));
237                 goto finish;
238             }
239
240             _use_mmap = FALSE;
241         }
242
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));
245         goto finish;
246     }
247
248     if (!_use_mmap)
249         _use_tsched = FALSE;
250
251     if (!pa_alsa_pcm_is_hw(pcm_handle))
252         _use_tsched = FALSE;
253
254     if ((ret = set_format(pcm_handle, hwparams, &_ss.format)) < 0)
255         goto finish;
256
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));
259         goto finish;
260     }
261
262     if (require_exact_channel_number) {
263         if ((ret = snd_pcm_hw_params_set_channels(pcm_handle, hwparams, _ss.channels)) < 0) {
264             pa_log_debug("snd_pcm_hw_params_set_channels(%u) failed: %s", _ss.channels, pa_alsa_strerror(ret));
265             goto finish;
266         }
267     } else {
268         unsigned int c = _ss.channels;
269
270         if ((ret = snd_pcm_hw_params_set_channels_near(pcm_handle, hwparams, &c)) < 0) {
271             pa_log_debug("snd_pcm_hw_params_set_channels_near(%u) failed: %s", _ss.channels, pa_alsa_strerror(ret));
272             goto finish;
273         }
274
275         _ss.channels = c;
276     }
277
278     if (_use_tsched && tsched_size > 0) {
279         _buffer_size = (snd_pcm_uframes_t) (((uint64_t) tsched_size * _ss.rate) / ss->rate);
280         _period_size = _buffer_size;
281     } else {
282         _period_size = (snd_pcm_uframes_t) (((uint64_t) _period_size * _ss.rate) / ss->rate);
283         _buffer_size = (snd_pcm_uframes_t) (((uint64_t) _buffer_size * _ss.rate) / ss->rate);
284     }
285
286     if (_buffer_size > 0 || _period_size > 0) {
287         snd_pcm_uframes_t max_frames = 0;
288
289         if ((ret = snd_pcm_hw_params_get_buffer_size_max(hwparams, &max_frames)) < 0)
290             pa_log_warn("snd_pcm_hw_params_get_buffer_size_max() failed: %s", pa_alsa_strerror(ret));
291         else
292             pa_log_debug("Maximum hw buffer size is %lu ms", (long unsigned) (max_frames * PA_MSEC_PER_SEC / _ss.rate));
293
294         /* Some ALSA drivers really don't like if we set the buffer
295          * size first and the number of periods second. (which would
296          * make a lot more sense to me) So, try a few combinations
297          * before we give up. */
298
299         if (_buffer_size > 0 && _period_size > 0) {
300             snd_pcm_hw_params_copy(hwparams_copy, hwparams);
301
302             /* First try: set buffer size first, followed by period size */
303             if (set_buffer_size(pcm_handle, hwparams_copy, _buffer_size) >= 0 &&
304                 set_period_size(pcm_handle, hwparams_copy, _period_size) >= 0 &&
305                 snd_pcm_hw_params(pcm_handle, hwparams_copy) >= 0) {
306                 pa_log_debug("Set buffer size first, period size second.");
307                 goto success;
308             }
309
310             /* Second try: set period size first, followed by buffer size */
311             if (set_period_size(pcm_handle, hwparams_copy, _period_size) >= 0 &&
312                 set_buffer_size(pcm_handle, hwparams_copy, _buffer_size) >= 0 &&
313                 snd_pcm_hw_params(pcm_handle, hwparams_copy) >= 0) {
314                 pa_log_debug("Set period size first, buffer size second.");
315                 goto success;
316             }
317         }
318
319         if (_buffer_size > 0) {
320             snd_pcm_hw_params_copy(hwparams_copy, hwparams);
321
322             /* Third try: set only buffer size */
323             if (set_buffer_size(pcm_handle, hwparams_copy, _buffer_size) >= 0 &&
324                 snd_pcm_hw_params(pcm_handle, hwparams_copy) >= 0) {
325                 pa_log_debug("Set only buffer size second.");
326                 goto success;
327             }
328         }
329
330         if (_period_size > 0) {
331             snd_pcm_hw_params_copy(hwparams_copy, hwparams);
332
333             /* Fourth try: set only period size */
334             if (set_period_size(pcm_handle, hwparams_copy, _period_size) >= 0 &&
335                 snd_pcm_hw_params(pcm_handle, hwparams_copy) >= 0) {
336                 pa_log_debug("Set only period size second.");
337                 goto success;
338             }
339         }
340     }
341
342     pa_log_debug("Set neither period nor buffer size.");
343
344     /* Last chance, set nothing */
345     if  ((ret = snd_pcm_hw_params(pcm_handle, hwparams)) < 0) {
346         pa_log_info("snd_pcm_hw_params failed: %s", pa_alsa_strerror(ret));
347         goto finish;
348     }
349
350 success:
351
352     if (ss->rate != _ss.rate)
353         pa_log_info("Device %s doesn't support %u Hz, changed to %u Hz.", snd_pcm_name(pcm_handle), ss->rate, _ss.rate);
354
355     if (ss->channels != _ss.channels)
356         pa_log_info("Device %s doesn't support %u channels, changed to %u.", snd_pcm_name(pcm_handle), ss->channels, _ss.channels);
357
358     if (ss->format != _ss.format)
359         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));
360
361     if ((ret = snd_pcm_prepare(pcm_handle)) < 0) {
362         pa_log_info("snd_pcm_prepare() failed: %s", pa_alsa_strerror(ret));
363         goto finish;
364     }
365
366     if ((ret = snd_pcm_hw_params_current(pcm_handle, hwparams)) < 0) {
367         pa_log_info("snd_pcm_hw_params_current() failed: %s", pa_alsa_strerror(ret));
368         goto finish;
369     }
370
371     if ((ret = snd_pcm_hw_params_get_period_size(hwparams, &_period_size, &dir)) < 0 ||
372         (ret = snd_pcm_hw_params_get_buffer_size(hwparams, &_buffer_size)) < 0) {
373         pa_log_info("snd_pcm_hw_params_get_{period|buffer}_size() failed: %s", pa_alsa_strerror(ret));
374         goto finish;
375     }
376
377     /* If the sample rate deviates too much, we need to resample */
378     if (_ss.rate < ss->rate*.95 || _ss.rate > ss->rate*1.05)
379         ss->rate = _ss.rate;
380     ss->channels = _ss.channels;
381     ss->format = _ss.format;
382
383     pa_assert(_period_size > 0);
384     pa_assert(_buffer_size > 0);
385
386     if (buffer_size)
387         *buffer_size = _buffer_size;
388
389     if (period_size)
390         *period_size = _period_size;
391
392     if (use_mmap)
393         *use_mmap = _use_mmap;
394
395     if (use_tsched)
396         *use_tsched = _use_tsched;
397
398     ret = 0;
399
400     snd_pcm_nonblock(pcm_handle, 1);
401
402 finish:
403
404     return ret;
405 }
406
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;
410     int err;
411
412     pa_assert(pcm);
413
414     snd_pcm_sw_params_alloca(&swparams);
415
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));
418         return err;
419     }
420
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));
423         return err;
424     }
425
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));
428         return err;
429     }
430
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));
433         return err;
434     }
435
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));
438         return err;
439     }
440
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));
443         return err;
444     }
445
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));
448         return err;
449     }
450
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));
453         return err;
454     }
455
456     return 0;
457 }
458
459 snd_pcm_t *pa_alsa_open_by_device_id_auto(
460         const char *dev_id,
461         char **dev,
462         pa_sample_spec *ss,
463         pa_channel_map* map,
464         int mode,
465         snd_pcm_uframes_t *period_size,
466         snd_pcm_uframes_t *buffer_size,
467         snd_pcm_uframes_t tsched_size,
468         pa_bool_t *use_mmap,
469         pa_bool_t *use_tsched,
470         pa_alsa_profile_set *ps,
471         pa_alsa_mapping **mapping) {
472
473     char *d;
474     snd_pcm_t *pcm_handle;
475     void *state;
476     pa_alsa_mapping *m;
477
478     pa_assert(dev_id);
479     pa_assert(dev);
480     pa_assert(ss);
481     pa_assert(map);
482     pa_assert(ps);
483
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
489      * channel map.*/
490
491     PA_HASHMAP_FOREACH(m, ps->mappings, state) {
492         if (!pa_channel_map_superset(&m->channel_map, map))
493             continue;
494
495         pa_log_debug("Checking for superset %s (%s)", m->name, m->device_strings[0]);
496
497         pcm_handle = pa_alsa_open_by_device_id_mapping(
498                 dev_id,
499                 dev,
500                 ss,
501                 map,
502                 mode,
503                 period_size,
504                 buffer_size,
505                 tsched_size,
506                 use_mmap,
507                 use_tsched,
508                 m);
509
510         if (pcm_handle) {
511             if (mapping)
512                 *mapping = m;
513
514             return pcm_handle;
515         }
516     }
517
518     PA_HASHMAP_FOREACH_BACKWARDS(m, ps->mappings, state) {
519         if (pa_channel_map_superset(&m->channel_map, map))
520             continue;
521
522         pa_log_debug("Checking for subset %s (%s)", m->name, m->device_strings[0]);
523
524         pcm_handle = pa_alsa_open_by_device_id_mapping(
525                 dev_id,
526                 dev,
527                 ss,
528                 map,
529                 mode,
530                 period_size,
531                 buffer_size,
532                 tsched_size,
533                 use_mmap,
534                 use_tsched,
535                 m);
536
537         if (pcm_handle) {
538             if (mapping)
539                 *mapping = m;
540
541             return pcm_handle;
542         }
543     }
544
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(
549             d,
550             dev,
551             ss,
552             map,
553             mode,
554             period_size,
555             buffer_size,
556             tsched_size,
557             use_mmap,
558             use_tsched,
559             FALSE);
560     pa_xfree(d);
561
562     if (pcm_handle && mapping)
563         *mapping = NULL;
564
565     return pcm_handle;
566 }
567
568 snd_pcm_t *pa_alsa_open_by_device_id_mapping(
569         const char *dev_id,
570         char **dev,
571         pa_sample_spec *ss,
572         pa_channel_map* map,
573         int mode,
574         snd_pcm_uframes_t *period_size,
575         snd_pcm_uframes_t *buffer_size,
576         snd_pcm_uframes_t tsched_size,
577         pa_bool_t *use_mmap,
578         pa_bool_t *use_tsched,
579         pa_alsa_mapping *m) {
580
581     snd_pcm_t *pcm_handle;
582     pa_sample_spec try_ss;
583     pa_channel_map try_map;
584
585     pa_assert(dev_id);
586     pa_assert(dev);
587     pa_assert(ss);
588     pa_assert(map);
589     pa_assert(m);
590
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;
595
596     pcm_handle = pa_alsa_open_by_template(
597             m->device_strings,
598             dev_id,
599             dev,
600             &try_ss,
601             &try_map,
602             mode,
603             period_size,
604             buffer_size,
605             tsched_size,
606             use_mmap,
607             use_tsched,
608             TRUE);
609
610     if (!pcm_handle)
611         return NULL;
612
613     *ss = try_ss;
614     *map = try_map;
615     pa_assert(map->channels == ss->channels);
616
617     return pcm_handle;
618 }
619
620 snd_pcm_t *pa_alsa_open_by_device_string(
621         const char *device,
622         char **dev,
623         pa_sample_spec *ss,
624         pa_channel_map* map,
625         int mode,
626         snd_pcm_uframes_t *period_size,
627         snd_pcm_uframes_t *buffer_size,
628         snd_pcm_uframes_t tsched_size,
629         pa_bool_t *use_mmap,
630         pa_bool_t *use_tsched,
631         pa_bool_t require_exact_channel_number) {
632
633     int err;
634     char *d;
635     snd_pcm_t *pcm_handle;
636     pa_bool_t reformat = FALSE;
637
638     pa_assert(device);
639     pa_assert(ss);
640     pa_assert(map);
641
642     d = pa_xstrdup(device);
643
644     for (;;) {
645         pa_log_debug("Trying %s %s SND_PCM_NO_AUTO_FORMAT ...", d, reformat ? "without" : "with");
646
647         if ((err = snd_pcm_open(&pcm_handle, d, mode,
648                                 SND_PCM_NONBLOCK|
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));
653             goto fail;
654         }
655
656         pa_log_debug("Managed to open %s", d);
657
658         if ((err = pa_alsa_set_hw_params(
659                      pcm_handle,
660                      ss,
661                      period_size,
662                      buffer_size,
663                      tsched_size,
664                      use_mmap,
665                      use_tsched,
666                      require_exact_channel_number)) < 0) {
667
668             if (!reformat) {
669                 reformat = TRUE;
670
671                 snd_pcm_close(pcm_handle);
672                 continue;
673             }
674
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:")) {
677                 char *t;
678
679                 t = pa_sprintf_malloc("plug:%s", d);
680                 pa_xfree(d);
681                 d = t;
682
683                 reformat = FALSE;
684
685                 snd_pcm_close(pcm_handle);
686                 continue;
687             }
688
689             pa_log_info("Failed to set hardware parameters on %s: %s", d, pa_alsa_strerror(err));
690             snd_pcm_close(pcm_handle);
691
692             goto fail;
693         }
694
695         if (dev)
696             *dev = d;
697         else
698             pa_xfree(d);
699
700         if (ss->channels != map->channels)
701             pa_channel_map_init_extend(map, ss->channels, PA_CHANNEL_MAP_ALSA);
702
703         return pcm_handle;
704     }
705
706 fail:
707     pa_xfree(d);
708
709     return NULL;
710 }
711
712 snd_pcm_t *pa_alsa_open_by_template(
713         char **template,
714         const char *dev_id,
715         char **dev,
716         pa_sample_spec *ss,
717         pa_channel_map* map,
718         int mode,
719         snd_pcm_uframes_t *period_size,
720         snd_pcm_uframes_t *buffer_size,
721         snd_pcm_uframes_t tsched_size,
722         pa_bool_t *use_mmap,
723         pa_bool_t *use_tsched,
724         pa_bool_t require_exact_channel_number) {
725
726     snd_pcm_t *pcm_handle;
727     char **i;
728
729     for (i = template; *i; i++) {
730         char *d;
731
732         d = pa_replace(*i, "%f", dev_id);
733
734         pcm_handle = pa_alsa_open_by_device_string(
735                 d,
736                 dev,
737                 ss,
738                 map,
739                 mode,
740                 period_size,
741                 buffer_size,
742                 tsched_size,
743                 use_mmap,
744                 use_tsched,
745                 require_exact_channel_number);
746
747         pa_xfree(d);
748
749         if (pcm_handle)
750             return pcm_handle;
751     }
752
753     return NULL;
754 }
755
756 void pa_alsa_dump(pa_log_level_t level, snd_pcm_t *pcm) {
757     int err;
758     snd_output_t *out;
759
760     pa_assert(pcm);
761
762     pa_assert_se(snd_output_buffer_open(&out) == 0);
763
764     if ((err = snd_pcm_dump(pcm, out)) < 0)
765         pa_logl(level, "snd_pcm_dump(): %s", pa_alsa_strerror(err));
766     else {
767         char *s = NULL;
768         snd_output_buffer_string(out, &s);
769         pa_logl(level, "snd_pcm_dump():\n%s", pa_strnull(s));
770     }
771
772     pa_assert_se(snd_output_close(out) == 0);
773 }
774
775 void pa_alsa_dump_status(snd_pcm_t *pcm) {
776     int err;
777     snd_output_t *out;
778     snd_pcm_status_t *status;
779     char *s = NULL;
780
781     pa_assert(pcm);
782
783     snd_pcm_status_alloca(&status);
784
785     if ((err = snd_output_buffer_open(&out)) < 0) {
786         pa_log_debug("snd_output_buffer_open() failed: %s", pa_cstrerror(err));
787         return;
788     }
789
790     if ((err = snd_pcm_status(pcm, status)) < 0) {
791         pa_log_debug("snd_pcm_status() failed: %s", pa_cstrerror(err));
792         goto finish;
793     }
794
795     if ((err = snd_pcm_status_dump(status, out)) < 0) {
796         pa_log_debug("snd_pcm_dump(): %s", pa_alsa_strerror(err));
797         goto finish;
798     }
799
800     snd_output_buffer_string(out, &s);
801     pa_log_debug("snd_pcm_dump():\n%s", pa_strnull(s));
802
803 finish:
804
805     snd_output_close(out);
806 }
807
808 static void alsa_error_handler(const char *file, int line, const char *function, int err, const char *fmt,...) {
809     va_list ap;
810     char *alsa_file;
811
812     alsa_file = pa_sprintf_malloc("(alsa-lib)%s", file);
813
814     va_start(ap, fmt);
815
816     pa_log_levelv_meta(PA_LOG_INFO, alsa_file, line, function, fmt, ap);
817
818     va_end(ap);
819
820     pa_xfree(alsa_file);
821 }
822
823 static pa_atomic_t n_error_handler_installed = PA_ATOMIC_INIT(0);
824
825 void pa_alsa_refcnt_inc(void) {
826     /* This is not really thread safe, but we do our best */
827
828     if (pa_atomic_inc(&n_error_handler_installed) == 0)
829         snd_lib_error_set_handler(alsa_error_handler);
830 }
831
832 void pa_alsa_refcnt_dec(void) {
833     int r;
834
835     pa_assert_se((r = pa_atomic_dec(&n_error_handler_installed)) >= 1);
836
837     if (r == 1) {
838         snd_lib_error_set_handler(NULL);
839         snd_config_update_free_global();
840     }
841 }
842
843 pa_bool_t pa_alsa_init_description(pa_proplist *p) {
844     const char *d, *k;
845     pa_assert(p);
846
847     if (pa_device_init_description(p))
848         return TRUE;
849
850     if (!(d = pa_proplist_gets(p, "alsa.card_name")))
851         d = pa_proplist_gets(p, "alsa.name");
852
853     if (!d)
854         return FALSE;
855
856     k = pa_proplist_gets(p, PA_PROP_DEVICE_PROFILE_DESCRIPTION);
857
858     if (d && k)
859         pa_proplist_setf(p, PA_PROP_DEVICE_DESCRIPTION, _("%s %s"), d, k);
860     else if (d)
861         pa_proplist_sets(p, PA_PROP_DEVICE_DESCRIPTION, d);
862
863     return FALSE;
864 }
865
866 void pa_alsa_init_proplist_card(pa_core *c, pa_proplist *p, int card) {
867     char *cn, *lcn, *dn;
868
869     pa_assert(p);
870     pa_assert(card >= 0);
871
872     pa_proplist_setf(p, "alsa.card", "%i", card);
873
874     if (snd_card_get_name(card, &cn) >= 0) {
875         pa_proplist_sets(p, "alsa.card_name", cn);
876         free(cn);
877     }
878
879     if (snd_card_get_longname(card, &lcn) >= 0) {
880         pa_proplist_sets(p, "alsa.long_card_name", lcn);
881         free(lcn);
882     }
883
884     if ((dn = pa_alsa_get_driver_name(card))) {
885         pa_proplist_sets(p, "alsa.driver_name", dn);
886         pa_xfree(dn);
887     }
888
889 #ifdef HAVE_UDEV
890     pa_udev_get_info(card, p);
891 #endif
892
893 #ifdef HAVE_HAL
894     pa_hal_get_info(c, p, card);
895 #endif
896 }
897
898 void pa_alsa_init_proplist_pcm_info(pa_core *c, pa_proplist *p, snd_pcm_info_t *pcm_info) {
899
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"
905     };
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
911     };
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"
915     };
916
917     snd_pcm_class_t class;
918     snd_pcm_subclass_t subclass;
919     const char *n, *id, *sdn;
920     int card;
921
922     pa_assert(p);
923     pa_assert(pcm_info);
924
925     pa_proplist_sets(p, PA_PROP_DEVICE_API, "alsa");
926
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]);
932     }
933
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]);
937
938     if ((n = snd_pcm_info_get_name(pcm_info)))
939         pa_proplist_sets(p, "alsa.name", n);
940
941     if ((id = snd_pcm_info_get_id(pcm_info)))
942         pa_proplist_sets(p, "alsa.id", id);
943
944     pa_proplist_setf(p, "alsa.subdevice", "%u", snd_pcm_info_get_subdevice(pcm_info));
945     if ((sdn = snd_pcm_info_get_subdevice_name(pcm_info)))
946         pa_proplist_sets(p, "alsa.subdevice_name", sdn);
947
948     pa_proplist_setf(p, "alsa.device", "%u", snd_pcm_info_get_device(pcm_info));
949
950     if ((card = snd_pcm_info_get_card(pcm_info)) >= 0)
951         pa_alsa_init_proplist_card(c, p, card);
952 }
953
954 void pa_alsa_init_proplist_pcm(pa_core *c, pa_proplist *p, snd_pcm_t *pcm) {
955     snd_pcm_hw_params_t *hwparams;
956     snd_pcm_info_t *info;
957     int bits, err;
958
959     snd_pcm_hw_params_alloca(&hwparams);
960     snd_pcm_info_alloca(&info);
961
962     if ((err = snd_pcm_hw_params_current(pcm, hwparams)) < 0)
963         pa_log_warn("Error fetching hardware parameter info: %s", pa_alsa_strerror(err));
964     else {
965
966         if ((bits = snd_pcm_hw_params_get_sbits(hwparams)) >= 0)
967             pa_proplist_setf(p, "alsa.resolution_bits", "%i", bits);
968     }
969
970     if ((err = snd_pcm_info(pcm, info)) < 0)
971         pa_log_warn("Error fetching PCM info: %s", pa_alsa_strerror(err));
972     else
973         pa_alsa_init_proplist_pcm_info(c, p, info);
974 }
975
976 void pa_alsa_init_proplist_ctl(pa_proplist *p, const char *name) {
977     int err;
978     snd_ctl_t *ctl;
979     snd_ctl_card_info_t *info;
980     const char *t;
981
982     pa_assert(p);
983
984     snd_ctl_card_info_alloca(&info);
985
986     if ((err = snd_ctl_open(&ctl, name, 0)) < 0) {
987         pa_log_warn("Error opening low-level control device '%s': %s", name, snd_strerror(err));
988         return;
989     }
990
991     if ((err = snd_ctl_card_info(ctl, info)) < 0) {
992         pa_log_warn("Control device %s card info: %s", name, snd_strerror(err));
993         snd_ctl_close(ctl);
994         return;
995     }
996
997     if ((t = snd_ctl_card_info_get_mixername(info)) && *t)
998         pa_proplist_sets(p, "alsa.mixer_name", t);
999
1000     if ((t = snd_ctl_card_info_get_components(info)) && *t)
1001         pa_proplist_sets(p, "alsa.components", t);
1002
1003     snd_ctl_close(ctl);
1004 }
1005
1006 int pa_alsa_recover_from_poll(snd_pcm_t *pcm, int revents) {
1007     snd_pcm_state_t state;
1008     int err;
1009
1010     pa_assert(pcm);
1011
1012     if (revents & POLLERR)
1013         pa_log_debug("Got POLLERR from ALSA");
1014     if (revents & POLLNVAL)
1015         pa_log_warn("Got POLLNVAL from ALSA");
1016     if (revents & POLLHUP)
1017         pa_log_warn("Got POLLHUP from ALSA");
1018     if (revents & POLLPRI)
1019         pa_log_warn("Got POLLPRI from ALSA");
1020     if (revents & POLLIN)
1021         pa_log_debug("Got POLLIN from ALSA");
1022     if (revents & POLLOUT)
1023         pa_log_debug("Got POLLOUT from ALSA");
1024
1025     state = snd_pcm_state(pcm);
1026     pa_log_debug("PCM state is %s", snd_pcm_state_name(state));
1027
1028     /* Try to recover from this error */
1029
1030     switch (state) {
1031
1032         case SND_PCM_STATE_XRUN:
1033             if ((err = snd_pcm_recover(pcm, -EPIPE, 1)) != 0) {
1034                 pa_log_warn("Could not recover from POLLERR|POLLNVAL|POLLHUP and XRUN: %s", pa_alsa_strerror(err));
1035                 return -1;
1036             }
1037             break;
1038
1039         case SND_PCM_STATE_SUSPENDED:
1040             if ((err = snd_pcm_recover(pcm, -ESTRPIPE, 1)) != 0) {
1041                 pa_log_warn("Could not recover from POLLERR|POLLNVAL|POLLHUP and SUSPENDED: %s", pa_alsa_strerror(err));
1042                 return -1;
1043             }
1044             break;
1045
1046         default:
1047
1048             snd_pcm_drop(pcm);
1049
1050             if ((err = snd_pcm_prepare(pcm)) < 0) {
1051                 pa_log_warn("Could not recover from POLLERR|POLLNVAL|POLLHUP with snd_pcm_prepare(): %s", pa_alsa_strerror(err));
1052                 return -1;
1053             }
1054             break;
1055     }
1056
1057     return 0;
1058 }
1059
1060 pa_rtpoll_item* pa_alsa_build_pollfd(snd_pcm_t *pcm, pa_rtpoll *rtpoll) {
1061     int n, err;
1062     struct pollfd *pollfd;
1063     pa_rtpoll_item *item;
1064
1065     pa_assert(pcm);
1066
1067     if ((n = snd_pcm_poll_descriptors_count(pcm)) < 0) {
1068         pa_log("snd_pcm_poll_descriptors_count() failed: %s", pa_alsa_strerror(n));
1069         return NULL;
1070     }
1071
1072     item = pa_rtpoll_item_new(rtpoll, PA_RTPOLL_NEVER, (unsigned) n);
1073     pollfd = pa_rtpoll_item_get_pollfd(item, NULL);
1074
1075     if ((err = snd_pcm_poll_descriptors(pcm, pollfd, (unsigned) n)) < 0) {
1076         pa_log("snd_pcm_poll_descriptors() failed: %s", pa_alsa_strerror(err));
1077         pa_rtpoll_item_free(item);
1078         return NULL;
1079     }
1080
1081     return item;
1082 }
1083
1084 snd_pcm_sframes_t pa_alsa_safe_avail(snd_pcm_t *pcm, size_t hwbuf_size, const pa_sample_spec *ss) {
1085     snd_pcm_sframes_t n;
1086     size_t k;
1087
1088     pa_assert(pcm);
1089     pa_assert(hwbuf_size > 0);
1090     pa_assert(ss);
1091
1092     /* Some ALSA driver expose weird bugs, let's inform the user about
1093      * what is going on */
1094
1095     n = snd_pcm_avail(pcm);
1096
1097     if (n <= 0)
1098         return n;
1099
1100     k = (size_t) n * pa_frame_size(ss);
1101
1102     if (k >= hwbuf_size * 5 ||
1103         k >= pa_bytes_per_second(ss)*10) {
1104
1105         PA_ONCE_BEGIN {
1106             char *dn = pa_alsa_get_driver_name_by_pcm(pcm);
1107             pa_log(_("snd_pcm_avail() returned a value that is exceptionally large: %lu bytes (%lu ms).\n"
1108                      "Most likely this is a bug in the ALSA driver '%s'. Please report this issue to the ALSA developers."),
1109                    (unsigned long) k,
1110                    (unsigned long) (pa_bytes_to_usec(k, ss) / PA_USEC_PER_MSEC),
1111                    pa_strnull(dn));
1112             pa_xfree(dn);
1113             pa_alsa_dump(PA_LOG_ERROR, pcm);
1114         } PA_ONCE_END;
1115
1116         /* Mhmm, let's try not to fail completely */
1117         n = (snd_pcm_sframes_t) (hwbuf_size / pa_frame_size(ss));
1118     }
1119
1120     return n;
1121 }
1122
1123 int pa_alsa_safe_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delay, size_t hwbuf_size, const pa_sample_spec *ss) {
1124     ssize_t k;
1125     size_t abs_k;
1126     int r;
1127
1128     pa_assert(pcm);
1129     pa_assert(delay);
1130     pa_assert(hwbuf_size > 0);
1131     pa_assert(ss);
1132
1133     /* Some ALSA driver expose weird bugs, let's inform the user about
1134      * what is going on */
1135
1136     if ((r = snd_pcm_delay(pcm, delay)) < 0)
1137         return r;
1138
1139     k = (ssize_t) *delay * (ssize_t) pa_frame_size(ss);
1140
1141     abs_k = k >= 0 ? (size_t) k : (size_t) -k;
1142
1143     if (abs_k >= hwbuf_size * 5 ||
1144         abs_k >= pa_bytes_per_second(ss)*10) {
1145
1146         PA_ONCE_BEGIN {
1147             char *dn = pa_alsa_get_driver_name_by_pcm(pcm);
1148             pa_log(_("snd_pcm_delay() returned a value that is exceptionally large: %li bytes (%s%lu ms).\n"
1149                      "Most likely this is a bug in the ALSA driver '%s'. Please report this issue to the ALSA developers."),
1150                    (signed long) k,
1151                    k < 0 ? "-" : "",
1152                    (unsigned long) (pa_bytes_to_usec(abs_k, ss) / PA_USEC_PER_MSEC),
1153                    pa_strnull(dn));
1154             pa_xfree(dn);
1155             pa_alsa_dump(PA_LOG_ERROR, pcm);
1156         } PA_ONCE_END;
1157
1158         /* Mhmm, let's try not to fail completely */
1159         if (k < 0)
1160             *delay = -(snd_pcm_sframes_t) (hwbuf_size / pa_frame_size(ss));
1161         else
1162             *delay = (snd_pcm_sframes_t) (hwbuf_size / pa_frame_size(ss));
1163     }
1164
1165     return 0;
1166 }
1167
1168 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) {
1169     int r;
1170     snd_pcm_uframes_t before;
1171     size_t k;
1172
1173     pa_assert(pcm);
1174     pa_assert(areas);
1175     pa_assert(offset);
1176     pa_assert(frames);
1177     pa_assert(hwbuf_size > 0);
1178     pa_assert(ss);
1179
1180     before = *frames;
1181
1182     r = snd_pcm_mmap_begin(pcm, areas, offset, frames);
1183
1184     if (r < 0)
1185         return r;
1186
1187     k = (size_t) *frames * pa_frame_size(ss);
1188
1189     if (*frames > before ||
1190         k >= hwbuf_size * 3 ||
1191         k >= pa_bytes_per_second(ss)*10)
1192
1193         PA_ONCE_BEGIN {
1194             char *dn = pa_alsa_get_driver_name_by_pcm(pcm);
1195             pa_log(_("snd_pcm_mmap_begin() returned a value that is exceptionally large: %lu bytes (%lu ms).\n"
1196                      "Most likely this is a bug in the ALSA driver '%s'. Please report this issue to the ALSA developers."),
1197                    (unsigned long) k,
1198                    (unsigned long) (pa_bytes_to_usec(k, ss) / PA_USEC_PER_MSEC),
1199                    pa_strnull(dn));
1200             pa_xfree(dn);
1201             pa_alsa_dump(PA_LOG_ERROR, pcm);
1202         } PA_ONCE_END;
1203
1204     return r;
1205 }
1206
1207 char *pa_alsa_get_driver_name(int card) {
1208     char *t, *m, *n;
1209
1210     pa_assert(card >= 0);
1211
1212     t = pa_sprintf_malloc("/sys/class/sound/card%i/device/driver/module", card);
1213     m = pa_readlink(t);
1214     pa_xfree(t);
1215
1216     if (!m)
1217         return NULL;
1218
1219     n = pa_xstrdup(pa_path_get_filename(m));
1220     pa_xfree(m);
1221
1222     return n;
1223 }
1224
1225 char *pa_alsa_get_driver_name_by_pcm(snd_pcm_t *pcm) {
1226     int card;
1227     snd_pcm_info_t* info;
1228     snd_pcm_info_alloca(&info);
1229
1230     pa_assert(pcm);
1231
1232     if (snd_pcm_info(pcm, info) < 0)
1233         return NULL;
1234
1235     if ((card = snd_pcm_info_get_card(info)) < 0)
1236         return NULL;
1237
1238     return pa_alsa_get_driver_name(card);
1239 }
1240
1241 char *pa_alsa_get_reserve_name(const char *device) {
1242     const char *t;
1243     int i;
1244
1245     pa_assert(device);
1246
1247     if ((t = strchr(device, ':')))
1248         device = t+1;
1249
1250     if ((i = snd_card_get_index(device)) < 0) {
1251         int32_t k;
1252
1253         if (pa_atoi(device, &k) < 0)
1254             return NULL;
1255
1256         i = (int) k;
1257     }
1258
1259     return pa_sprintf_malloc("Audio%i", i);
1260 }
1261
1262 pa_bool_t pa_alsa_pcm_is_hw(snd_pcm_t *pcm) {
1263     snd_pcm_info_t* info;
1264     snd_pcm_info_alloca(&info);
1265
1266     pa_assert(pcm);
1267
1268     if (snd_pcm_info(pcm, info) < 0)
1269         return FALSE;
1270
1271     return snd_pcm_info_get_card(info) >= 0;
1272 }
1273
1274 pa_bool_t pa_alsa_pcm_is_modem(snd_pcm_t *pcm) {
1275     snd_pcm_info_t* info;
1276     snd_pcm_info_alloca(&info);
1277
1278     pa_assert(pcm);
1279
1280     if (snd_pcm_info(pcm, info) < 0)
1281         return FALSE;
1282
1283     return snd_pcm_info_get_class(info) == SND_PCM_CLASS_MODEM;
1284 }
1285
1286 PA_STATIC_TLS_DECLARE(cstrerror, pa_xfree);
1287
1288 const char* pa_alsa_strerror(int errnum) {
1289     const char *original = NULL;
1290     char *translated, *t;
1291     char errbuf[128];
1292
1293     if ((t = PA_STATIC_TLS_GET(cstrerror)))
1294         pa_xfree(t);
1295
1296     original = snd_strerror(errnum);
1297
1298     if (!original) {
1299         pa_snprintf(errbuf, sizeof(errbuf), "Unknown error %i", errnum);
1300         original = errbuf;
1301     }
1302
1303     if (!(translated = pa_locale_to_utf8(original))) {
1304         pa_log_warn("Unable to convert error string to locale, filtering.");
1305         translated = pa_utf8_filter(original);
1306     }
1307
1308     PA_STATIC_TLS_SET(cstrerror, translated);
1309
1310     return translated;
1311 }
1312
1313 pa_bool_t pa_alsa_may_tsched(pa_bool_t want) {
1314
1315     if (!want)
1316         return FALSE;
1317
1318     if (!pa_rtclock_hrtimer()) {
1319         /* We cannot depend on being woken up in time when the timers
1320         are inaccurate, so let's fallback to classic IO based playback
1321         then. */
1322         pa_log_notice("Disabling timer-based scheduling because high-resolution timers are not available from the kernel.");
1323         return FALSE; }
1324
1325     if (pa_running_in_vm()) {
1326         /* We cannot depend on being woken up when we ask for in a VM,
1327          * so let's fallback to classic IO based playback then. */
1328         pa_log_notice("Disabling timer-based scheduling because running inside a VM.");
1329         return FALSE;
1330     }
1331
1332
1333     return TRUE;
1334 }