2 This file is part of PulseAudio.
4 Copyright 2004-2008 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 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
29 #include <asoundlib.h>
31 #ifdef HAVE_VALGRIND_MEMCHECK_H
32 #include <valgrind/memcheck.h>
35 #include <pulse/xmalloc.h>
36 #include <pulse/util.h>
37 #include <pulse/timeval.h>
39 #include <pulsecore/core.h>
40 #include <pulsecore/module.h>
41 #include <pulsecore/memchunk.h>
42 #include <pulsecore/sink.h>
43 #include <pulsecore/modargs.h>
44 #include <pulsecore/core-util.h>
45 #include <pulsecore/sample-util.h>
46 #include <pulsecore/log.h>
47 #include <pulsecore/macro.h>
48 #include <pulsecore/thread.h>
49 #include <pulsecore/core-error.h>
50 #include <pulsecore/thread-mq.h>
51 #include <pulsecore/rtpoll.h>
52 #include <pulsecore/rtclock.h>
53 #include <pulsecore/time-smoother.h>
55 #include "alsa-util.h"
56 #include "alsa-sink.h"
58 #define DEFAULT_DEVICE "default"
59 #define DEFAULT_TSCHED_BUFFER_USEC (2*PA_USEC_PER_SEC) /* 2s */
60 #define DEFAULT_TSCHED_WATERMARK_USEC (20*PA_USEC_PER_MSEC) /* 20ms */
61 #define TSCHED_MIN_SLEEP_USEC (3*PA_USEC_PER_MSEC) /* 3ms */
62 #define TSCHED_MIN_WAKEUP_USEC (3*PA_USEC_PER_MSEC) /* 3ms */
70 pa_thread_mq thread_mq
;
73 snd_pcm_t
*pcm_handle
;
75 pa_alsa_fdlist
*mixer_fdl
;
76 snd_mixer_t
*mixer_handle
;
77 snd_mixer_elem_t
*mixer_elem
;
78 long hw_volume_max
, hw_volume_min
;
79 long hw_dB_max
, hw_dB_min
;
80 pa_bool_t hw_dB_supported
;
81 pa_bool_t mixer_seperate_channels
;
82 pa_cvolume hardware_volume
;
84 size_t frame_size
, fragment_size
, hwbuf_size
, tsched_watermark
;
90 pa_bool_t use_mmap
, use_tsched
;
92 pa_bool_t first
, after_rewind
;
94 pa_rtpoll_item
*alsa_rtpoll_item
;
96 snd_mixer_selem_channel_id_t mixer_map
[SND_MIXER_SCHN_LAST
];
98 pa_smoother
*smoother
;
100 uint64_t since_start
;
102 snd_pcm_sframes_t hwbuf_unused_frames
;
105 static void userdata_free(struct userdata
*u
);
107 static void fix_tsched_watermark(struct userdata
*u
) {
109 size_t min_sleep
, min_wakeup
;
112 max_use
= u
->hwbuf_size
- (size_t) u
->hwbuf_unused_frames
* u
->frame_size
;
114 min_sleep
= pa_usec_to_bytes(TSCHED_MIN_SLEEP_USEC
, &u
->sink
->sample_spec
);
115 min_wakeup
= pa_usec_to_bytes(TSCHED_MIN_WAKEUP_USEC
, &u
->sink
->sample_spec
);
117 if (min_sleep
> max_use
/2)
118 min_sleep
= pa_frame_align(max_use
/2, &u
->sink
->sample_spec
);
119 if (min_sleep
< u
->frame_size
)
120 min_sleep
= u
->frame_size
;
122 if (min_wakeup
> max_use
/2)
123 min_wakeup
= pa_frame_align(max_use
/2, &u
->sink
->sample_spec
);
124 if (min_wakeup
< u
->frame_size
)
125 min_wakeup
= u
->frame_size
;
127 if (u
->tsched_watermark
> max_use
-min_sleep
)
128 u
->tsched_watermark
= max_use
-min_sleep
;
130 if (u
->tsched_watermark
< min_wakeup
)
131 u
->tsched_watermark
= min_wakeup
;
134 static void hw_sleep_time(struct userdata
*u
, pa_usec_t
*sleep_usec
, pa_usec_t
*process_usec
) {
137 pa_assert(sleep_usec
);
138 pa_assert(process_usec
);
142 usec
= pa_sink_get_requested_latency_within_thread(u
->sink
);
144 if (usec
== (pa_usec_t
) -1)
145 usec
= pa_bytes_to_usec(u
->hwbuf_size
, &u
->sink
->sample_spec
);
147 /* pa_log_debug("hw buffer time: %u ms", (unsigned) (usec / PA_USEC_PER_MSEC)); */
149 wm
= pa_bytes_to_usec(u
->tsched_watermark
, &u
->sink
->sample_spec
);
152 *sleep_usec
= usec
- wm
;
155 *process_usec
= *sleep_usec
= usec
/ 2;
157 /* pa_log_debug("after watermark: %u ms", (unsigned) (*sleep_usec / PA_USEC_PER_MSEC)); */
160 static int try_recover(struct userdata
*u
, const char *call
, int err
) {
165 pa_log_debug("%s: %s", call
, snd_strerror(err
));
167 pa_assert(err
!= -EAGAIN
);
170 pa_log_debug("%s: Buffer underrun!", call
);
172 if ((err
= snd_pcm_recover(u
->pcm_handle
, err
, 1)) == 0) {
178 pa_log("%s: %s", call
, snd_strerror(err
));
182 static size_t check_left_to_play(struct userdata
*u
, snd_pcm_sframes_t n
) {
185 if ((size_t) n
*u
->frame_size
< u
->hwbuf_size
)
186 left_to_play
= u
->hwbuf_size
- ((size_t) n
*u
->frame_size
);
190 if (left_to_play
> 0) {
191 /* pa_log_debug("%0.2f ms left to play", (double) pa_bytes_to_usec(left_to_play, &u->sink->sample_spec) / PA_USEC_PER_MSEC); */
192 } else if (!u
->first
&& !u
->after_rewind
) {
194 if (pa_log_ratelimit())
195 pa_log_info("Underrun!");
198 size_t old_watermark
= u
->tsched_watermark
;
200 u
->tsched_watermark
*= 2;
201 fix_tsched_watermark(u
);
203 if (old_watermark
!= u
->tsched_watermark
)
204 pa_log_notice("Increasing wakeup watermark to %0.2f ms",
205 (double) pa_bytes_to_usec(u
->tsched_watermark
, &u
->sink
->sample_spec
) / PA_USEC_PER_MSEC
);
212 static int mmap_write(struct userdata
*u
, pa_usec_t
*sleep_usec
, pa_bool_t polled
) {
214 pa_usec_t max_sleep_usec
= 0, process_usec
= 0;
218 pa_sink_assert_ref(u
->sink
);
221 hw_sleep_time(u
, &max_sleep_usec
, &process_usec
);
227 snd_pcm_hwsync(u
->pcm_handle
);
229 /* First we determine how many samples are missing to fill the
230 * buffer up to 100% */
232 if (PA_UNLIKELY((n
= pa_alsa_safe_avail_update(u
->pcm_handle
, u
->hwbuf_size
, &u
->sink
->sample_spec
)) < 0)) {
234 if ((r
= try_recover(u
, "snd_pcm_avail_update", (int) n
)) == 0)
240 left_to_play
= check_left_to_play(u
, n
);
244 /* We won't fill up the playback buffer before at least
245 * half the sleep time is over because otherwise we might
246 * ask for more data from the clients then they expect. We
247 * need to guarantee that clients only have to keep around
248 * a single hw buffer length. */
251 pa_bytes_to_usec(left_to_play
, &u
->sink
->sample_spec
) > process_usec
+max_sleep_usec
/2)
254 if (PA_UNLIKELY(n
<= u
->hwbuf_unused_frames
)) {
256 if (polled
&& pa_log_ratelimit())
257 pa_log("ALSA woke us up to write new data to the device, but there was actually nothing to write! "
258 "Most likely this is an ALSA driver bug. Please report this issue to the ALSA developers. "
259 "We were woken up with POLLOUT set -- however a subsequent snd_pcm_avail_update() returned 0.");
264 n
-= u
->hwbuf_unused_frames
;
268 /* pa_log_debug("Filling up"); */
274 const snd_pcm_channel_area_t
*areas
;
275 snd_pcm_uframes_t offset
, frames
= (snd_pcm_uframes_t
) n
;
276 snd_pcm_sframes_t sframes
;
278 /* pa_log_debug("%lu frames to write", (unsigned long) frames); */
280 if (PA_UNLIKELY((err
= pa_alsa_safe_mmap_begin(u
->pcm_handle
, &areas
, &offset
, &frames
, u
->hwbuf_size
, &u
->sink
->sample_spec
)) < 0)) {
282 if ((r
= try_recover(u
, "snd_pcm_mmap_begin", err
)) == 0)
288 /* Make sure that if these memblocks need to be copied they will fit into one slot */
289 if (frames
> pa_mempool_block_size_max(u
->sink
->core
->mempool
)/u
->frame_size
)
290 frames
= pa_mempool_block_size_max(u
->sink
->core
->mempool
)/u
->frame_size
;
292 /* Check these are multiples of 8 bit */
293 pa_assert((areas
[0].first
& 7) == 0);
294 pa_assert((areas
[0].step
& 7)== 0);
296 /* We assume a single interleaved memory buffer */
297 pa_assert((areas
[0].first
>> 3) == 0);
298 pa_assert((areas
[0].step
>> 3) == u
->frame_size
);
300 p
= (uint8_t*) areas
[0].addr
+ (offset
* u
->frame_size
);
302 chunk
.memblock
= pa_memblock_new_fixed(u
->core
->mempool
, p
, frames
* u
->frame_size
, TRUE
);
303 chunk
.length
= pa_memblock_get_length(chunk
.memblock
);
306 pa_sink_render_into_full(u
->sink
, &chunk
);
308 /* FIXME: Maybe we can do something to keep this memory block
309 * a little bit longer around? */
310 pa_memblock_unref_fixed(chunk
.memblock
);
312 if (PA_UNLIKELY((sframes
= snd_pcm_mmap_commit(u
->pcm_handle
, offset
, frames
)) < 0)) {
314 if ((r
= try_recover(u
, "snd_pcm_mmap_commit", (int) sframes
)) == 0)
322 u
->frame_index
+= (int64_t) frames
;
323 u
->since_start
+= frames
* u
->frame_size
;
325 /* pa_log_debug("wrote %lu frames", (unsigned long) frames); */
327 if (frames
>= (snd_pcm_uframes_t
) n
)
330 n
-= (snd_pcm_sframes_t
) frames
;
334 *sleep_usec
= pa_bytes_to_usec(left_to_play
, &u
->sink
->sample_spec
) - process_usec
;
338 static int unix_write(struct userdata
*u
, pa_usec_t
*sleep_usec
, pa_bool_t polled
) {
340 pa_usec_t max_sleep_usec
= 0, process_usec
= 0;
344 pa_sink_assert_ref(u
->sink
);
347 hw_sleep_time(u
, &max_sleep_usec
, &process_usec
);
353 snd_pcm_hwsync(u
->pcm_handle
);
355 if (PA_UNLIKELY((n
= pa_alsa_safe_avail_update(u
->pcm_handle
, u
->hwbuf_size
, &u
->sink
->sample_spec
)) < 0)) {
357 if ((r
= try_recover(u
, "snd_pcm_avail_update", (int) n
)) == 0)
363 left_to_play
= check_left_to_play(u
, n
);
367 /* We won't fill up the playback buffer before at least
368 * half the sleep time is over because otherwise we might
369 * ask for more data from the clients then they expect. We
370 * need to guarantee that clients only have to keep around
371 * a single hw buffer length. */
374 pa_bytes_to_usec(left_to_play
, &u
->sink
->sample_spec
) > process_usec
+max_sleep_usec
/2)
377 if (PA_UNLIKELY(n
<= u
->hwbuf_unused_frames
)) {
379 if (polled
&& pa_log_ratelimit())
380 pa_log("ALSA woke us up to write new data to the device, but there was actually nothing to write! "
381 "Most likely this is an ALSA driver bug. Please report this issue to the ALSA developers. "
382 "We were woken up with POLLOUT set -- however a subsequent snd_pcm_avail_update() returned 0.");
387 n
-= u
->hwbuf_unused_frames
;
392 snd_pcm_sframes_t frames
;
395 /* pa_log_debug("%lu frames to write", (unsigned long) frames); */
397 if (u
->memchunk
.length
<= 0)
398 pa_sink_render(u
->sink
, (size_t) n
* u
->frame_size
, &u
->memchunk
);
400 pa_assert(u
->memchunk
.length
> 0);
402 frames
= (snd_pcm_sframes_t
) (u
->memchunk
.length
/ u
->frame_size
);
407 p
= pa_memblock_acquire(u
->memchunk
.memblock
);
408 frames
= snd_pcm_writei(u
->pcm_handle
, (const uint8_t*) p
+ u
->memchunk
.index
, (snd_pcm_uframes_t
) frames
);
409 pa_memblock_release(u
->memchunk
.memblock
);
411 pa_assert(frames
!= 0);
413 if (PA_UNLIKELY(frames
< 0)) {
415 if ((r
= try_recover(u
, "snd_pcm_writei", (int) frames
)) == 0)
421 u
->memchunk
.index
+= (size_t) frames
* u
->frame_size
;
422 u
->memchunk
.length
-= (size_t) frames
* u
->frame_size
;
424 if (u
->memchunk
.length
<= 0) {
425 pa_memblock_unref(u
->memchunk
.memblock
);
426 pa_memchunk_reset(&u
->memchunk
);
431 u
->frame_index
+= frames
;
432 u
->since_start
+= (size_t) frames
* u
->frame_size
;
434 /* pa_log_debug("wrote %lu frames", (unsigned long) frames); */
443 *sleep_usec
= pa_bytes_to_usec(left_to_play
, &u
->sink
->sample_spec
) - process_usec
;
447 static void update_smoother(struct userdata
*u
) {
448 snd_pcm_sframes_t delay
= 0;
451 pa_usec_t now1
, now2
;
452 /* struct timeval timestamp; */
453 snd_pcm_status_t
*status
;
455 snd_pcm_status_alloca(&status
);
458 pa_assert(u
->pcm_handle
);
460 /* Let's update the time smoother */
462 snd_pcm_hwsync(u
->pcm_handle
);
463 snd_pcm_avail_update(u
->pcm_handle
);
465 /* if (PA_UNLIKELY((err = snd_pcm_status(u->pcm_handle, status)) < 0)) { */
466 /* pa_log("Failed to query DSP status data: %s", snd_strerror(err)); */
470 /* delay = snd_pcm_status_get_delay(status); */
472 if (PA_UNLIKELY((err
= snd_pcm_delay(u
->pcm_handle
, &delay
)) < 0)) {
473 pa_log("Failed to query DSP status data: %s", snd_strerror(err
));
477 frames
= u
->frame_index
- delay
;
479 /* pa_log_debug("frame_index = %llu, delay = %llu, p = %llu", (unsigned long long) u->frame_index, (unsigned long long) delay, (unsigned long long) frames); */
481 /* snd_pcm_status_get_tstamp(status, ×tamp); */
482 /* pa_rtclock_from_wallclock(×tamp); */
483 /* now1 = pa_timeval_load(×tamp); */
485 now1
= pa_rtclock_usec();
486 now2
= pa_bytes_to_usec((uint64_t) frames
* u
->frame_size
, &u
->sink
->sample_spec
);
487 pa_smoother_put(u
->smoother
, now1
, now2
);
490 static pa_usec_t
sink_get_latency(struct userdata
*u
) {
493 pa_usec_t now1
, now2
;
497 now1
= pa_rtclock_usec();
498 now2
= pa_smoother_get(u
->smoother
, now1
);
500 delay
= (int64_t) pa_bytes_to_usec((uint64_t) u
->frame_index
* u
->frame_size
, &u
->sink
->sample_spec
) - (int64_t) now2
;
503 r
= (pa_usec_t
) delay
;
505 if (u
->memchunk
.memblock
)
506 r
+= pa_bytes_to_usec(u
->memchunk
.length
, &u
->sink
->sample_spec
);
511 static int build_pollfd(struct userdata
*u
) {
513 pa_assert(u
->pcm_handle
);
515 if (u
->alsa_rtpoll_item
)
516 pa_rtpoll_item_free(u
->alsa_rtpoll_item
);
518 if (!(u
->alsa_rtpoll_item
= pa_alsa_build_pollfd(u
->pcm_handle
, u
->rtpoll
)))
524 static int suspend(struct userdata
*u
) {
526 pa_assert(u
->pcm_handle
);
528 pa_smoother_pause(u
->smoother
, pa_rtclock_usec());
530 /* Let's suspend -- we don't call snd_pcm_drain() here since that might
531 * take awfully long with our long buffer sizes today. */
532 snd_pcm_close(u
->pcm_handle
);
533 u
->pcm_handle
= NULL
;
535 if (u
->alsa_rtpoll_item
) {
536 pa_rtpoll_item_free(u
->alsa_rtpoll_item
);
537 u
->alsa_rtpoll_item
= NULL
;
540 pa_log_info("Device suspended...");
545 static int update_sw_params(struct userdata
*u
) {
546 snd_pcm_uframes_t avail_min
;
551 /* Use the full buffer if noone asked us for anything specific */
552 u
->hwbuf_unused_frames
= 0;
557 if ((latency
= pa_sink_get_requested_latency_within_thread(u
->sink
)) != (pa_usec_t
) -1) {
560 pa_log_debug("latency set to %0.2fms", (double) latency
/ PA_USEC_PER_MSEC
);
562 b
= pa_usec_to_bytes(latency
, &u
->sink
->sample_spec
);
564 /* We need at least one sample in our buffer */
566 if (PA_UNLIKELY(b
< u
->frame_size
))
569 u
->hwbuf_unused_frames
= (snd_pcm_sframes_t
)
570 (PA_LIKELY(b
< u
->hwbuf_size
) ?
571 ((u
->hwbuf_size
- b
) / u
->frame_size
) : 0);
574 fix_tsched_watermark(u
);
577 pa_log_debug("hwbuf_unused_frames=%lu", (unsigned long) u
->hwbuf_unused_frames
);
579 /* We need at last one frame in the used part of the buffer */
580 avail_min
= (snd_pcm_uframes_t
) u
->hwbuf_unused_frames
+ 1;
583 pa_usec_t sleep_usec
, process_usec
;
585 hw_sleep_time(u
, &sleep_usec
, &process_usec
);
586 avail_min
+= pa_usec_to_bytes(sleep_usec
, &u
->sink
->sample_spec
) / u
->frame_size
;
589 pa_log_debug("setting avail_min=%lu", (unsigned long) avail_min
);
591 if ((err
= pa_alsa_set_sw_params(u
->pcm_handle
, avail_min
)) < 0) {
592 pa_log("Failed to set software parameters: %s", snd_strerror(err
));
596 pa_sink_set_max_request(u
->sink
, u
->hwbuf_size
- (size_t) u
->hwbuf_unused_frames
* u
->frame_size
);
601 static int unsuspend(struct userdata
*u
) {
606 snd_pcm_uframes_t period_size
;
609 pa_assert(!u
->pcm_handle
);
611 pa_log_info("Trying resume...");
613 snd_config_update_free_global();
614 if ((err
= snd_pcm_open(&u
->pcm_handle
, u
->device_name
, SND_PCM_STREAM_PLAYBACK
,
615 /*SND_PCM_NONBLOCK|*/
616 SND_PCM_NO_AUTO_RESAMPLE
|
617 SND_PCM_NO_AUTO_CHANNELS
|
618 SND_PCM_NO_AUTO_FORMAT
)) < 0) {
619 pa_log("Error opening PCM device %s: %s", u
->device_name
, snd_strerror(err
));
623 ss
= u
->sink
->sample_spec
;
624 nfrags
= u
->nfragments
;
625 period_size
= u
->fragment_size
/ u
->frame_size
;
629 if ((err
= pa_alsa_set_hw_params(u
->pcm_handle
, &ss
, &nfrags
, &period_size
, u
->hwbuf_size
/ u
->frame_size
, &b
, &d
, TRUE
)) < 0) {
630 pa_log("Failed to set hardware parameters: %s", snd_strerror(err
));
634 if (b
!= u
->use_mmap
|| d
!= u
->use_tsched
) {
635 pa_log_warn("Resume failed, couldn't get original access mode.");
639 if (!pa_sample_spec_equal(&ss
, &u
->sink
->sample_spec
)) {
640 pa_log_warn("Resume failed, couldn't restore original sample settings.");
644 if (nfrags
!= u
->nfragments
|| period_size
*u
->frame_size
!= u
->fragment_size
) {
645 pa_log_warn("Resume failed, couldn't restore original fragment settings. (Old: %lu*%lu, New %lu*%lu)",
646 (unsigned long) u
->nfragments
, (unsigned long) u
->fragment_size
,
647 (unsigned long) nfrags
, period_size
* u
->frame_size
);
651 if (update_sw_params(u
) < 0)
654 if (build_pollfd(u
) < 0)
657 /* FIXME: We need to reload the volume somehow */
662 pa_log_info("Resumed successfully...");
668 snd_pcm_close(u
->pcm_handle
);
669 u
->pcm_handle
= NULL
;
675 static int sink_process_msg(pa_msgobject
*o
, int code
, void *data
, int64_t offset
, pa_memchunk
*chunk
) {
676 struct userdata
*u
= PA_SINK(o
)->userdata
;
680 case PA_SINK_MESSAGE_GET_LATENCY
: {
684 r
= sink_get_latency(u
);
686 *((pa_usec_t
*) data
) = r
;
691 case PA_SINK_MESSAGE_SET_STATE
:
693 switch ((pa_sink_state_t
) PA_PTR_TO_UINT(data
)) {
695 case PA_SINK_SUSPENDED
:
696 pa_assert(PA_SINK_IS_OPENED(u
->sink
->thread_info
.state
));
704 case PA_SINK_RUNNING
:
706 if (u
->sink
->thread_info
.state
== PA_SINK_INIT
) {
707 if (build_pollfd(u
) < 0)
711 if (u
->sink
->thread_info
.state
== PA_SINK_SUSPENDED
) {
712 if (unsuspend(u
) < 0)
718 case PA_SINK_UNLINKED
:
720 case PA_SINK_INVALID_STATE
:
727 return pa_sink_process_msg(o
, code
, data
, offset
, chunk
);
730 static int mixer_callback(snd_mixer_elem_t
*elem
, unsigned int mask
) {
731 struct userdata
*u
= snd_mixer_elem_get_callback_private(elem
);
734 pa_assert(u
->mixer_handle
);
736 if (mask
== SND_CTL_EVENT_MASK_REMOVE
)
739 if (mask
& SND_CTL_EVENT_MASK_VALUE
) {
740 pa_sink_get_volume(u
->sink
, TRUE
);
741 pa_sink_get_mute(u
->sink
, TRUE
);
747 static pa_volume_t
from_alsa_volume(struct userdata
*u
, long alsa_vol
) {
749 return (pa_volume_t
) round(((double) (alsa_vol
- u
->hw_volume_min
) * PA_VOLUME_NORM
) /
750 (double) (u
->hw_volume_max
- u
->hw_volume_min
));
753 static long to_alsa_volume(struct userdata
*u
, pa_volume_t vol
) {
756 alsa_vol
= (long) round(((double) vol
* (double) (u
->hw_volume_max
- u
->hw_volume_min
))
757 / PA_VOLUME_NORM
) + u
->hw_volume_min
;
759 return PA_CLAMP_UNLIKELY(alsa_vol
, u
->hw_volume_min
, u
->hw_volume_max
);
762 static void sink_get_volume_cb(pa_sink
*s
) {
763 struct userdata
*u
= s
->userdata
;
767 char t
[PA_CVOLUME_SNPRINT_MAX
];
770 pa_assert(u
->mixer_elem
);
772 if (u
->mixer_seperate_channels
) {
774 r
.channels
= s
->sample_spec
.channels
;
776 for (i
= 0; i
< s
->sample_spec
.channels
; i
++) {
779 if (u
->hw_dB_supported
) {
781 if ((err
= snd_mixer_selem_get_playback_dB(u
->mixer_elem
, u
->mixer_map
[i
], &alsa_vol
)) < 0)
784 #ifdef HAVE_VALGRIND_MEMCHECK_H
785 VALGRIND_MAKE_MEM_DEFINED(&alsa_vol
, sizeof(alsa_vol
));
788 r
.values
[i
] = pa_sw_volume_from_dB((double) (alsa_vol
- u
->hw_dB_max
) / 100.0);
791 if ((err
= snd_mixer_selem_get_playback_volume(u
->mixer_elem
, u
->mixer_map
[i
], &alsa_vol
)) < 0)
794 r
.values
[i
] = from_alsa_volume(u
, alsa_vol
);
801 if (u
->hw_dB_supported
) {
803 if ((err
= snd_mixer_selem_get_playback_dB(u
->mixer_elem
, SND_MIXER_SCHN_MONO
, &alsa_vol
)) < 0)
806 #ifdef HAVE_VALGRIND_MEMCHECK_H
807 VALGRIND_MAKE_MEM_DEFINED(&alsa_vol
, sizeof(alsa_vol
));
810 pa_cvolume_set(&r
, s
->sample_spec
.channels
, pa_sw_volume_from_dB((double) (alsa_vol
- u
->hw_dB_max
) / 100.0));
814 if ((err
= snd_mixer_selem_get_playback_volume(u
->mixer_elem
, SND_MIXER_SCHN_MONO
, &alsa_vol
)) < 0)
817 pa_cvolume_set(&r
, s
->sample_spec
.channels
, from_alsa_volume(u
, alsa_vol
));
821 pa_log_debug("Read hardware volume: %s", pa_cvolume_snprint(t
, sizeof(t
), &r
));
823 if (!pa_cvolume_equal(&u
->hardware_volume
, &r
)) {
825 s
->virtual_volume
= u
->hardware_volume
= r
;
827 if (u
->hw_dB_supported
) {
830 /* Hmm, so the hardware volume changed, let's reset our software volume */
831 pa_cvolume_reset(&reset
, s
->sample_spec
.channels
);
832 pa_sink_set_soft_volume(s
, &reset
);
839 pa_log_error("Unable to read volume: %s", snd_strerror(err
));
842 static void sink_set_volume_cb(pa_sink
*s
) {
843 struct userdata
*u
= s
->userdata
;
849 pa_assert(u
->mixer_elem
);
851 if (u
->mixer_seperate_channels
) {
853 r
.channels
= s
->sample_spec
.channels
;
855 for (i
= 0; i
< s
->sample_spec
.channels
; i
++) {
859 vol
= s
->virtual_volume
.values
[i
];
861 if (u
->hw_dB_supported
) {
863 alsa_vol
= (long) (pa_sw_volume_to_dB(vol
) * 100);
864 alsa_vol
+= u
->hw_dB_max
;
865 alsa_vol
= PA_CLAMP_UNLIKELY(alsa_vol
, u
->hw_dB_min
, u
->hw_dB_max
);
867 if ((err
= snd_mixer_selem_set_playback_dB(u
->mixer_elem
, u
->mixer_map
[i
], alsa_vol
, 1)) < 0)
870 if ((err
= snd_mixer_selem_get_playback_dB(u
->mixer_elem
, u
->mixer_map
[i
], &alsa_vol
)) < 0)
873 #ifdef HAVE_VALGRIND_MEMCHECK_H
874 VALGRIND_MAKE_MEM_DEFINED(&alsa_vol
, sizeof(alsa_vol
));
877 r
.values
[i
] = pa_sw_volume_from_dB((double) (alsa_vol
- u
->hw_dB_max
) / 100.0);
880 alsa_vol
= to_alsa_volume(u
, vol
);
882 if ((err
= snd_mixer_selem_set_playback_volume(u
->mixer_elem
, u
->mixer_map
[i
], alsa_vol
)) < 0)
885 if ((err
= snd_mixer_selem_get_playback_volume(u
->mixer_elem
, u
->mixer_map
[i
], &alsa_vol
)) < 0)
888 r
.values
[i
] = from_alsa_volume(u
, alsa_vol
);
896 vol
= pa_cvolume_max(&s
->virtual_volume
);
898 if (u
->hw_dB_supported
) {
899 alsa_vol
= (long) (pa_sw_volume_to_dB(vol
) * 100);
900 alsa_vol
+= u
->hw_dB_max
;
901 alsa_vol
= PA_CLAMP_UNLIKELY(alsa_vol
, u
->hw_dB_min
, u
->hw_dB_max
);
903 if ((err
= snd_mixer_selem_set_playback_dB_all(u
->mixer_elem
, alsa_vol
, 1)) < 0)
906 if ((err
= snd_mixer_selem_get_playback_dB(u
->mixer_elem
, SND_MIXER_SCHN_MONO
, &alsa_vol
)) < 0)
909 #ifdef HAVE_VALGRIND_MEMCHECK_H
910 VALGRIND_MAKE_MEM_DEFINED(&alsa_vol
, sizeof(alsa_vol
));
913 pa_cvolume_set(&r
, s
->sample_spec
.channels
, pa_sw_volume_from_dB((double) (alsa_vol
- u
->hw_dB_max
) / 100.0));
916 alsa_vol
= to_alsa_volume(u
, vol
);
918 if ((err
= snd_mixer_selem_set_playback_volume_all(u
->mixer_elem
, alsa_vol
)) < 0)
921 if ((err
= snd_mixer_selem_get_playback_volume(u
->mixer_elem
, SND_MIXER_SCHN_MONO
, &alsa_vol
)) < 0)
924 pa_cvolume_set(&r
, s
->sample_spec
.channels
, from_alsa_volume(u
, alsa_vol
));
928 u
->hardware_volume
= r
;
930 if (u
->hw_dB_supported
) {
931 char t
[PA_CVOLUME_SNPRINT_MAX
];
933 /* Match exactly what the user requested by software */
934 pa_sw_cvolume_divide(&s
->soft_volume
, &s
->virtual_volume
, &u
->hardware_volume
);
936 pa_log_debug("Requested volume: %s", pa_cvolume_snprint(t
, sizeof(t
), &s
->virtual_volume
));
937 pa_log_debug("Got hardware volume: %s", pa_cvolume_snprint(t
, sizeof(t
), &u
->hardware_volume
));
938 pa_log_debug("Calculated software volume: %s", pa_cvolume_snprint(t
, sizeof(t
), &s
->soft_volume
));
942 /* We can't match exactly what the user requested, hence let's
943 * at least tell the user about it */
945 s
->virtual_volume
= r
;
950 pa_log_error("Unable to set volume: %s", snd_strerror(err
));
953 static void sink_get_mute_cb(pa_sink
*s
) {
954 struct userdata
*u
= s
->userdata
;
958 pa_assert(u
->mixer_elem
);
960 if ((err
= snd_mixer_selem_get_playback_switch(u
->mixer_elem
, 0, &sw
)) < 0) {
961 pa_log_error("Unable to get switch: %s", snd_strerror(err
));
968 static void sink_set_mute_cb(pa_sink
*s
) {
969 struct userdata
*u
= s
->userdata
;
973 pa_assert(u
->mixer_elem
);
975 if ((err
= snd_mixer_selem_set_playback_switch_all(u
->mixer_elem
, !s
->muted
)) < 0) {
976 pa_log_error("Unable to set switch: %s", snd_strerror(err
));
981 static void sink_update_requested_latency_cb(pa_sink
*s
) {
982 struct userdata
*u
= s
->userdata
;
983 snd_pcm_sframes_t before
;
989 before
= u
->hwbuf_unused_frames
;
992 /* Let's check whether we now use only a smaller part of the
993 buffer then before. If so, we need to make sure that subsequent
994 rewinds are relative to the new maxium fill level and not to the
995 current fill level. Thus, let's do a full rewind once, to clear
998 if (u
->hwbuf_unused_frames
> before
) {
999 pa_log_debug("Requesting rewind due to latency change.");
1000 pa_sink_request_rewind(s
, (size_t) -1);
1004 static int process_rewind(struct userdata
*u
) {
1005 snd_pcm_sframes_t unused
;
1006 size_t rewind_nbytes
, unused_nbytes
, limit_nbytes
;
1009 /* Figure out how much we shall rewind and reset the counter */
1010 rewind_nbytes
= u
->sink
->thread_info
.rewind_nbytes
;
1011 u
->sink
->thread_info
.rewind_nbytes
= 0;
1013 if (rewind_nbytes
<= 0)
1016 pa_assert(rewind_nbytes
> 0);
1017 pa_log_debug("Requested to rewind %lu bytes.", (unsigned long) rewind_nbytes
);
1019 snd_pcm_hwsync(u
->pcm_handle
);
1020 if ((unused
= snd_pcm_avail_update(u
->pcm_handle
)) < 0) {
1021 pa_log("snd_pcm_avail_update() failed: %s", snd_strerror((int) unused
));
1025 unused_nbytes
= u
->tsched_watermark
+ (size_t) unused
* u
->frame_size
;
1027 if (u
->hwbuf_size
> unused_nbytes
)
1028 limit_nbytes
= u
->hwbuf_size
- unused_nbytes
;
1032 if (rewind_nbytes
> limit_nbytes
)
1033 rewind_nbytes
= limit_nbytes
;
1035 if (rewind_nbytes
> 0) {
1036 snd_pcm_sframes_t in_frames
, out_frames
;
1038 pa_log_debug("Limited to %lu bytes.", (unsigned long) rewind_nbytes
);
1040 in_frames
= (snd_pcm_sframes_t
) (rewind_nbytes
/ u
->frame_size
);
1041 pa_log_debug("before: %lu", (unsigned long) in_frames
);
1042 if ((out_frames
= snd_pcm_rewind(u
->pcm_handle
, (snd_pcm_uframes_t
) in_frames
)) < 0) {
1043 pa_log("snd_pcm_rewind() failed: %s", snd_strerror((int) out_frames
));
1046 pa_log_debug("after: %lu", (unsigned long) out_frames
);
1048 rewind_nbytes
= (size_t) out_frames
* u
->frame_size
;
1050 if (rewind_nbytes
<= 0)
1051 pa_log_info("Tried rewind, but was apparently not possible.");
1053 u
->frame_index
-= out_frames
;
1054 pa_log_debug("Rewound %lu bytes.", (unsigned long) rewind_nbytes
);
1055 pa_sink_process_rewind(u
->sink
, rewind_nbytes
);
1057 u
->after_rewind
= TRUE
;
1061 pa_log_debug("Mhmm, actually there is nothing to rewind.");
1065 pa_sink_process_rewind(u
->sink
, 0);
1071 static void thread_func(void *userdata
) {
1072 struct userdata
*u
= userdata
;
1073 unsigned short revents
= 0;
1077 pa_log_debug("Thread starting up");
1079 if (u
->core
->realtime_scheduling
)
1080 pa_make_realtime(u
->core
->realtime_priority
);
1082 pa_thread_mq_install(&u
->thread_mq
);
1083 pa_rtpoll_install(u
->rtpoll
);
1088 /* pa_log_debug("loop"); */
1090 /* Render some data and write it to the dsp */
1091 if (PA_SINK_IS_OPENED(u
->sink
->thread_info
.state
)) {
1093 pa_usec_t sleep_usec
= 0;
1095 if (u
->sink
->thread_info
.rewind_requested
)
1096 if (process_rewind(u
) < 0)
1100 work_done
= mmap_write(u
, &sleep_usec
, revents
& POLLOUT
);
1102 work_done
= unix_write(u
, &sleep_usec
, revents
& POLLOUT
);
1107 /* pa_log_debug("work_done = %i", work_done); */
1112 pa_log_info("Starting playback.");
1113 snd_pcm_start(u
->pcm_handle
);
1115 pa_smoother_resume(u
->smoother
, pa_rtclock_usec());
1121 if (u
->use_tsched
) {
1124 if (u
->since_start
<= u
->hwbuf_size
) {
1126 /* USB devices on ALSA seem to hit a buffer
1127 * underrun during the first iterations much
1128 * quicker then we calculate here, probably due to
1129 * the transport latency. To accomodate for that
1130 * we artificially decrease the sleep time until
1131 * we have filled the buffer at least once
1134 /*pa_log_debug("Cutting sleep time for the initial iterations by half.");*/
1138 /* OK, the playback buffer is now full, let's
1139 * calculate when to wake up next */
1140 /* pa_log_debug("Waking up in %0.2fms (sound card clock).", (double) sleep_usec / PA_USEC_PER_MSEC); */
1142 /* Convert from the sound card time domain to the
1143 * system time domain */
1144 cusec
= pa_smoother_translate(u
->smoother
, pa_rtclock_usec(), sleep_usec
);
1146 /* pa_log_debug("Waking up in %0.2fms (system clock).", (double) cusec / PA_USEC_PER_MSEC); */
1148 /* We don't trust the conversion, so we wake up whatever comes first */
1149 pa_rtpoll_set_timer_relative(u
->rtpoll
, PA_MIN(sleep_usec
, cusec
));
1153 u
->after_rewind
= FALSE
;
1155 } else if (u
->use_tsched
)
1157 /* OK, we're in an invalid state, let's disable our timers */
1158 pa_rtpoll_set_timer_disabled(u
->rtpoll
);
1160 /* Hmm, nothing to do. Let's sleep */
1161 if ((ret
= pa_rtpoll_run(u
->rtpoll
, TRUE
)) < 0)
1167 /* Tell ALSA about this and process its response */
1168 if (PA_SINK_IS_OPENED(u
->sink
->thread_info
.state
)) {
1169 struct pollfd
*pollfd
;
1173 pollfd
= pa_rtpoll_item_get_pollfd(u
->alsa_rtpoll_item
, &n
);
1175 if ((err
= snd_pcm_poll_descriptors_revents(u
->pcm_handle
, pollfd
, n
, &revents
)) < 0) {
1176 pa_log("snd_pcm_poll_descriptors_revents() failed: %s", snd_strerror(err
));
1180 if (revents
& (POLLIN
|POLLERR
|POLLNVAL
|POLLHUP
|POLLPRI
)) {
1181 if (pa_alsa_recover_from_poll(u
->pcm_handle
, revents
) < 0)
1188 if (revents
&& u
->use_tsched
&& pa_log_ratelimit())
1189 pa_log_debug("Wakeup from ALSA!%s%s", (revents
& POLLIN
) ? " INPUT" : "", (revents
& POLLOUT
) ? " OUTPUT" : "");
1195 /* If this was no regular exit from the loop we have to continue
1196 * processing messages until we received PA_MESSAGE_SHUTDOWN */
1197 pa_asyncmsgq_post(u
->thread_mq
.outq
, PA_MSGOBJECT(u
->core
), PA_CORE_MESSAGE_UNLOAD_MODULE
, u
->module
, 0, NULL
, NULL
);
1198 pa_asyncmsgq_wait_for(u
->thread_mq
.inq
, PA_MESSAGE_SHUTDOWN
);
1201 pa_log_debug("Thread shutting down");
1204 static void set_sink_name(pa_sink_new_data
*data
, pa_modargs
*ma
, const char *device_id
, const char *device_name
) {
1210 pa_assert(device_name
);
1212 if ((n
= pa_modargs_get_value(ma
, "sink_name", NULL
))) {
1213 pa_sink_new_data_set_name(data
, n
);
1214 data
->namereg_fail
= TRUE
;
1218 if ((n
= pa_modargs_get_value(ma
, "name", NULL
)))
1219 data
->namereg_fail
= TRUE
;
1221 n
= device_id
? device_id
: device_name
;
1222 data
->namereg_fail
= FALSE
;
1225 t
= pa_sprintf_malloc("alsa_output.%s", n
);
1226 pa_sink_new_data_set_name(data
, t
);
1230 pa_sink
*pa_alsa_sink_new(pa_module
*m
, pa_modargs
*ma
, const char*driver
, pa_card
*card
, const pa_alsa_profile_info
*profile
) {
1232 struct userdata
*u
= NULL
;
1233 const char *dev_id
= NULL
;
1236 uint32_t nfrags
, hwbuf_size
, frag_size
, tsched_size
, tsched_watermark
;
1237 snd_pcm_uframes_t period_frames
, tsched_frames
;
1240 pa_bool_t use_mmap
= TRUE
, b
, use_tsched
= TRUE
, d
, ignore_dB
= FALSE
;
1242 pa_sink_new_data data
;
1247 ss
= m
->core
->default_sample_spec
;
1248 if (pa_modargs_get_sample_spec_and_channel_map(ma
, &ss
, &map
, PA_CHANNEL_MAP_ALSA
) < 0) {
1249 pa_log("Failed to parse sample specification and channel map");
1253 frame_size
= pa_frame_size(&ss
);
1255 nfrags
= m
->core
->default_n_fragments
;
1256 frag_size
= (uint32_t) pa_usec_to_bytes(m
->core
->default_fragment_size_msec
*PA_USEC_PER_MSEC
, &ss
);
1258 frag_size
= (uint32_t) frame_size
;
1259 tsched_size
= (uint32_t) pa_usec_to_bytes(DEFAULT_TSCHED_BUFFER_USEC
, &ss
);
1260 tsched_watermark
= (uint32_t) pa_usec_to_bytes(DEFAULT_TSCHED_WATERMARK_USEC
, &ss
);
1262 if (pa_modargs_get_value_u32(ma
, "fragments", &nfrags
) < 0 ||
1263 pa_modargs_get_value_u32(ma
, "fragment_size", &frag_size
) < 0 ||
1264 pa_modargs_get_value_u32(ma
, "tsched_buffer_size", &tsched_size
) < 0 ||
1265 pa_modargs_get_value_u32(ma
, "tsched_buffer_watermark", &tsched_watermark
) < 0) {
1266 pa_log("Failed to parse buffer metrics");
1270 hwbuf_size
= frag_size
* nfrags
;
1271 period_frames
= frag_size
/frame_size
;
1272 tsched_frames
= tsched_size
/frame_size
;
1274 if (pa_modargs_get_value_boolean(ma
, "mmap", &use_mmap
) < 0) {
1275 pa_log("Failed to parse mmap argument.");
1279 if (pa_modargs_get_value_boolean(ma
, "tsched", &use_tsched
) < 0) {
1280 pa_log("Failed to parse tsched argument.");
1284 if (pa_modargs_get_value_boolean(ma
, "ignore_dB", &ignore_dB
) < 0) {
1285 pa_log("Failed to parse ignore_dB argument.");
1289 if (use_tsched
&& !pa_rtclock_hrtimer()) {
1290 pa_log_notice("Disabling timer-based scheduling because high-resolution timers are not available from the kernel.");
1294 u
= pa_xnew0(struct userdata
, 1);
1297 u
->use_mmap
= use_mmap
;
1298 u
->use_tsched
= use_tsched
;
1301 u
->after_rewind
= FALSE
;
1302 u
->rtpoll
= pa_rtpoll_new();
1303 pa_thread_mq_init(&u
->thread_mq
, m
->core
->mainloop
, u
->rtpoll
);
1304 u
->alsa_rtpoll_item
= NULL
;
1306 u
->smoother
= pa_smoother_new(DEFAULT_TSCHED_BUFFER_USEC
*2, DEFAULT_TSCHED_BUFFER_USEC
*2, TRUE
, 5);
1307 usec
= pa_rtclock_usec();
1308 pa_smoother_set_time_offset(u
->smoother
, usec
);
1309 pa_smoother_pause(u
->smoother
, usec
);
1316 if (!(dev_id
= pa_modargs_get_value(ma
, "device_id", NULL
))) {
1317 pa_log("device_id= not set");
1321 if (!(u
->pcm_handle
= pa_alsa_open_by_device_id_profile(
1325 SND_PCM_STREAM_PLAYBACK
,
1326 &nfrags
, &period_frames
, tsched_frames
,
1331 } else if ((dev_id
= pa_modargs_get_value(ma
, "device_id", NULL
))) {
1333 if (!(u
->pcm_handle
= pa_alsa_open_by_device_id_auto(
1337 SND_PCM_STREAM_PLAYBACK
,
1338 &nfrags
, &period_frames
, tsched_frames
,
1345 if (!(u
->pcm_handle
= pa_alsa_open_by_device_string(
1346 pa_modargs_get_value(ma
, "device", DEFAULT_DEVICE
),
1349 SND_PCM_STREAM_PLAYBACK
,
1350 &nfrags
, &period_frames
, tsched_frames
,
1356 pa_assert(u
->device_name
);
1357 pa_log_info("Successfully opened device %s.", u
->device_name
);
1360 pa_log_info("Selected configuration '%s' (%s).", profile
->description
, profile
->name
);
1362 if (use_mmap
&& !b
) {
1363 pa_log_info("Device doesn't support mmap(), falling back to UNIX read/write mode.");
1364 u
->use_mmap
= use_mmap
= FALSE
;
1367 if (use_tsched
&& (!b
|| !d
)) {
1368 pa_log_info("Cannot enabled timer-based scheduling, falling back to sound IRQ scheduling.");
1369 u
->use_tsched
= use_tsched
= FALSE
;
1373 pa_log_info("Successfully enabled mmap() mode.");
1376 pa_log_info("Successfully enabled timer-based scheduling mode.");
1378 /* ALSA might tweak the sample spec, so recalculate the frame size */
1379 frame_size
= pa_frame_size(&ss
);
1381 pa_alsa_find_mixer_and_elem(u
->pcm_handle
, &u
->mixer_handle
, &u
->mixer_elem
);
1383 pa_sink_new_data_init(&data
);
1384 data
.driver
= driver
;
1387 set_sink_name(&data
, ma
, dev_id
, u
->device_name
);
1388 pa_sink_new_data_set_sample_spec(&data
, &ss
);
1389 pa_sink_new_data_set_channel_map(&data
, &map
);
1391 pa_alsa_init_proplist_pcm(m
->core
, data
.proplist
, u
->pcm_handle
);
1392 pa_proplist_sets(data
.proplist
, PA_PROP_DEVICE_STRING
, u
->device_name
);
1393 pa_proplist_setf(data
.proplist
, PA_PROP_DEVICE_BUFFERING_BUFFER_SIZE
, "%lu", (unsigned long) (period_frames
* frame_size
* nfrags
));
1394 pa_proplist_setf(data
.proplist
, PA_PROP_DEVICE_BUFFERING_FRAGMENT_SIZE
, "%lu", (unsigned long) (period_frames
* frame_size
));
1395 pa_proplist_sets(data
.proplist
, PA_PROP_DEVICE_ACCESS_MODE
, u
->use_tsched
? "mmap+timer" : (u
->use_mmap
? "mmap" : "serial"));
1398 pa_proplist_sets(data
.proplist
, PA_PROP_DEVICE_PROFILE_NAME
, profile
->name
);
1399 pa_proplist_sets(data
.proplist
, PA_PROP_DEVICE_PROFILE_DESCRIPTION
, profile
->description
);
1402 u
->sink
= pa_sink_new(m
->core
, &data
, PA_SINK_HARDWARE
|PA_SINK_LATENCY
);
1403 pa_sink_new_data_done(&data
);
1406 pa_log("Failed to create sink object");
1410 u
->sink
->parent
.process_msg
= sink_process_msg
;
1411 u
->sink
->update_requested_latency
= sink_update_requested_latency_cb
;
1412 u
->sink
->userdata
= u
;
1414 pa_sink_set_asyncmsgq(u
->sink
, u
->thread_mq
.inq
);
1415 pa_sink_set_rtpoll(u
->sink
, u
->rtpoll
);
1417 u
->frame_size
= frame_size
;
1418 u
->fragment_size
= frag_size
= (uint32_t) (period_frames
* frame_size
);
1419 u
->nfragments
= nfrags
;
1420 u
->hwbuf_size
= u
->fragment_size
* nfrags
;
1421 u
->hwbuf_unused_frames
= 0;
1422 u
->tsched_watermark
= tsched_watermark
;
1424 u
->hw_dB_supported
= FALSE
;
1425 u
->hw_dB_min
= u
->hw_dB_max
= 0;
1426 u
->hw_volume_min
= u
->hw_volume_max
= 0;
1427 u
->mixer_seperate_channels
= FALSE
;
1428 pa_cvolume_mute(&u
->hardware_volume
, u
->sink
->sample_spec
.channels
);
1431 fix_tsched_watermark(u
);
1433 u
->sink
->thread_info
.max_rewind
= use_tsched
? u
->hwbuf_size
: 0;
1434 u
->sink
->thread_info
.max_request
= u
->hwbuf_size
;
1436 pa_sink_set_latency_range(u
->sink
,
1437 !use_tsched
? pa_bytes_to_usec(u
->hwbuf_size
, &ss
) : (pa_usec_t
) -1,
1438 pa_bytes_to_usec(u
->hwbuf_size
, &ss
));
1440 pa_log_info("Using %u fragments of size %lu bytes, buffer time is %0.2fms",
1441 nfrags
, (long unsigned) u
->fragment_size
,
1442 (double) pa_bytes_to_usec(u
->hwbuf_size
, &ss
) / PA_USEC_PER_MSEC
);
1445 pa_log_info("Time scheduling watermark is %0.2fms",
1446 (double) pa_bytes_to_usec(u
->tsched_watermark
, &ss
) / PA_USEC_PER_MSEC
);
1448 if (update_sw_params(u
) < 0)
1451 pa_memchunk_reset(&u
->memchunk
);
1453 if (u
->mixer_handle
) {
1454 pa_assert(u
->mixer_elem
);
1456 if (snd_mixer_selem_has_playback_volume(u
->mixer_elem
)) {
1457 pa_bool_t suitable
= FALSE
;
1459 if (snd_mixer_selem_get_playback_volume_range(u
->mixer_elem
, &u
->hw_volume_min
, &u
->hw_volume_max
) < 0)
1460 pa_log_info("Failed to get volume range. Falling back to software volume control.");
1461 else if (u
->hw_volume_min
>= u
->hw_volume_max
)
1462 pa_log_warn("Your kernel driver is broken: it reports a volume range from %li to %li which makes no sense.", u
->hw_volume_min
, u
->hw_volume_max
);
1464 pa_log_info("Volume ranges from %li to %li.", u
->hw_volume_min
, u
->hw_volume_max
);
1469 if (ignore_dB
|| snd_mixer_selem_get_playback_dB_range(u
->mixer_elem
, &u
->hw_dB_min
, &u
->hw_dB_max
) < 0)
1470 pa_log_info("Mixer doesn't support dB information or data is ignored.");
1472 #ifdef HAVE_VALGRIND_MEMCHECK_H
1473 VALGRIND_MAKE_MEM_DEFINED(&u
->hw_dB_min
, sizeof(u
->hw_dB_min
));
1474 VALGRIND_MAKE_MEM_DEFINED(&u
->hw_dB_max
, sizeof(u
->hw_dB_max
));
1477 if (u
->hw_dB_min
>= u
->hw_dB_max
)
1478 pa_log_warn("Your kernel driver is broken: it reports a volume range from %0.2f dB to %0.2f dB which makes no sense.", (double) u
->hw_dB_min
/100.0, (double) u
->hw_dB_max
/100.0);
1480 pa_log_info("Volume ranges from %0.2f dB to %0.2f dB.", (double) u
->hw_dB_min
/100.0, (double) u
->hw_dB_max
/100.0);
1481 u
->hw_dB_supported
= TRUE
;
1483 if (u
->hw_dB_max
> 0) {
1484 u
->sink
->base_volume
= pa_sw_volume_from_dB(- (double) u
->hw_dB_max
/100.0);
1485 pa_log_info("Fixing base volume to %0.2f dB", pa_sw_volume_to_dB(u
->sink
->base_volume
));
1487 pa_log_info("No particular base volume set, fixing to 0 dB");
1491 if (!u
->hw_dB_supported
&&
1492 u
->hw_volume_max
- u
->hw_volume_min
< 3) {
1494 pa_log_info("Device doesn't do dB volume and has less than 4 volume levels. Falling back to software volume control.");
1500 u
->mixer_seperate_channels
= pa_alsa_calc_mixer_map(u
->mixer_elem
, &map
, u
->mixer_map
, TRUE
) >= 0;
1502 u
->sink
->get_volume
= sink_get_volume_cb
;
1503 u
->sink
->set_volume
= sink_set_volume_cb
;
1504 u
->sink
->flags
|= PA_SINK_HW_VOLUME_CTRL
| (u
->hw_dB_supported
? PA_SINK_DECIBEL_VOLUME
: 0);
1505 pa_log_info("Using hardware volume control. Hardware dB scale %s.", u
->hw_dB_supported
? "supported" : "not supported");
1507 if (!u
->hw_dB_supported
)
1508 u
->sink
->n_volume_steps
= u
->hw_volume_max
- u
->hw_volume_min
+ 1;
1510 pa_log_info("Using software volume control.");
1513 if (snd_mixer_selem_has_playback_switch(u
->mixer_elem
)) {
1514 u
->sink
->get_mute
= sink_get_mute_cb
;
1515 u
->sink
->set_mute
= sink_set_mute_cb
;
1516 u
->sink
->flags
|= PA_SINK_HW_MUTE_CTRL
;
1518 pa_log_info("Using software mute control.");
1520 u
->mixer_fdl
= pa_alsa_fdlist_new();
1522 if (pa_alsa_fdlist_set_mixer(u
->mixer_fdl
, u
->mixer_handle
, m
->core
->mainloop
) < 0) {
1523 pa_log("Failed to initialize file descriptor monitoring");
1527 snd_mixer_elem_set_callback(u
->mixer_elem
, mixer_callback
);
1528 snd_mixer_elem_set_callback_private(u
->mixer_elem
, u
);
1530 u
->mixer_fdl
= NULL
;
1532 pa_alsa_dump(u
->pcm_handle
);
1534 if (!(u
->thread
= pa_thread_new(thread_func
, u
))) {
1535 pa_log("Failed to create thread.");
1539 /* Get initial mixer settings */
1540 if (data
.volume_is_set
) {
1541 if (u
->sink
->set_volume
)
1542 u
->sink
->set_volume(u
->sink
);
1544 if (u
->sink
->get_volume
)
1545 u
->sink
->get_volume(u
->sink
);
1548 if (data
.muted_is_set
) {
1549 if (u
->sink
->set_mute
)
1550 u
->sink
->set_mute(u
->sink
);
1552 if (u
->sink
->get_mute
)
1553 u
->sink
->get_mute(u
->sink
);
1556 pa_sink_put(u
->sink
);
1567 static void userdata_free(struct userdata
*u
) {
1571 pa_sink_unlink(u
->sink
);
1574 pa_asyncmsgq_send(u
->thread_mq
.inq
, NULL
, PA_MESSAGE_SHUTDOWN
, NULL
, 0, NULL
);
1575 pa_thread_free(u
->thread
);
1578 pa_thread_mq_done(&u
->thread_mq
);
1581 pa_sink_unref(u
->sink
);
1583 if (u
->memchunk
.memblock
)
1584 pa_memblock_unref(u
->memchunk
.memblock
);
1586 if (u
->alsa_rtpoll_item
)
1587 pa_rtpoll_item_free(u
->alsa_rtpoll_item
);
1590 pa_rtpoll_free(u
->rtpoll
);
1593 pa_alsa_fdlist_free(u
->mixer_fdl
);
1595 if (u
->mixer_handle
)
1596 snd_mixer_close(u
->mixer_handle
);
1598 if (u
->pcm_handle
) {
1599 snd_pcm_drop(u
->pcm_handle
);
1600 snd_pcm_close(u
->pcm_handle
);
1604 pa_smoother_free(u
->smoother
);
1606 pa_xfree(u
->device_name
);
1610 void pa_alsa_sink_free(pa_sink
*s
) {
1613 pa_sink_assert_ref(s
);
1614 pa_assert_se(u
= s
->userdata
);