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>
38 #include <pulse/i18n.h>
40 #include <pulsecore/core.h>
41 #include <pulsecore/module.h>
42 #include <pulsecore/memchunk.h>
43 #include <pulsecore/sink.h>
44 #include <pulsecore/modargs.h>
45 #include <pulsecore/core-util.h>
46 #include <pulsecore/sample-util.h>
47 #include <pulsecore/log.h>
48 #include <pulsecore/macro.h>
49 #include <pulsecore/thread.h>
50 #include <pulsecore/core-error.h>
51 #include <pulsecore/thread-mq.h>
52 #include <pulsecore/rtpoll.h>
53 #include <pulsecore/rtclock.h>
54 #include <pulsecore/time-smoother.h>
56 #include "alsa-util.h"
57 #include "alsa-sink.h"
59 /* #define DEBUG_TIMING */
61 #define DEFAULT_DEVICE "default"
62 #define DEFAULT_TSCHED_BUFFER_USEC (2*PA_USEC_PER_SEC) /* 2s */
63 #define DEFAULT_TSCHED_WATERMARK_USEC (20*PA_USEC_PER_MSEC) /* 20ms */
64 #define TSCHED_MIN_SLEEP_USEC (10*PA_USEC_PER_MSEC) /* 10ms */
65 #define TSCHED_MIN_WAKEUP_USEC (4*PA_USEC_PER_MSEC) /* 4ms */
73 pa_thread_mq thread_mq
;
76 snd_pcm_t
*pcm_handle
;
78 pa_alsa_fdlist
*mixer_fdl
;
79 snd_mixer_t
*mixer_handle
;
80 snd_mixer_elem_t
*mixer_elem
;
81 long hw_volume_max
, hw_volume_min
;
82 long hw_dB_max
, hw_dB_min
;
83 pa_bool_t hw_dB_supported
:1;
84 pa_bool_t mixer_seperate_channels
:1;
85 pa_cvolume hardware_volume
;
87 size_t frame_size
, fragment_size
, hwbuf_size
, tsched_watermark
, hwbuf_unused
, min_sleep
, min_wakeup
;
93 pa_bool_t use_mmap
:1, use_tsched
:1;
95 pa_bool_t first
, after_rewind
;
97 pa_rtpoll_item
*alsa_rtpoll_item
;
99 snd_mixer_selem_channel_id_t mixer_map
[SND_MIXER_SCHN_LAST
];
101 pa_smoother
*smoother
;
102 uint64_t write_count
;
103 uint64_t since_start
;
106 static void userdata_free(struct userdata
*u
);
108 static void fix_min_sleep_wakeup(struct userdata
*u
) {
109 size_t max_use
, max_use_2
;
113 max_use
= u
->hwbuf_size
- u
->hwbuf_unused
;
114 max_use_2
= pa_frame_align(max_use
/2, &u
->sink
->sample_spec
);
116 u
->min_sleep
= pa_usec_to_bytes(TSCHED_MIN_SLEEP_USEC
, &u
->sink
->sample_spec
);
117 u
->min_sleep
= PA_CLAMP(u
->min_sleep
, u
->frame_size
, max_use_2
);
119 u
->min_wakeup
= pa_usec_to_bytes(TSCHED_MIN_WAKEUP_USEC
, &u
->sink
->sample_spec
);
120 u
->min_wakeup
= PA_CLAMP(u
->min_wakeup
, u
->frame_size
, max_use_2
);
123 static void fix_tsched_watermark(struct userdata
*u
) {
127 max_use
= u
->hwbuf_size
- u
->hwbuf_unused
;
129 if (u
->tsched_watermark
> max_use
- u
->min_sleep
)
130 u
->tsched_watermark
= max_use
- u
->min_sleep
;
132 if (u
->tsched_watermark
< u
->min_wakeup
)
133 u
->tsched_watermark
= u
->min_wakeup
;
136 static void adjust_after_underrun(struct userdata
*u
) {
137 size_t old_watermark
;
138 pa_usec_t old_min_latency
, new_min_latency
;
142 /* First, just try to increase the watermark */
143 old_watermark
= u
->tsched_watermark
;
144 u
->tsched_watermark
*= 2;
145 fix_tsched_watermark(u
);
147 if (old_watermark
!= u
->tsched_watermark
) {
148 pa_log_notice("Increasing wakeup watermark to %0.2f ms",
149 (double) pa_bytes_to_usec(u
->tsched_watermark
, &u
->sink
->sample_spec
) / PA_USEC_PER_MSEC
);
153 /* Hmm, we cannot increase the watermark any further, hence let's raise the latency */
154 old_min_latency
= u
->sink
->thread_info
.min_latency
;
155 new_min_latency
= PA_MIN(old_min_latency
* 2, u
->sink
->thread_info
.max_latency
);
157 if (old_min_latency
!= new_min_latency
) {
158 pa_log_notice("Increasing minimal latency to %0.2f ms",
159 (double) new_min_latency
/ PA_USEC_PER_MSEC
);
161 pa_sink_update_latency_range(u
->sink
, new_min_latency
, u
->sink
->thread_info
.max_latency
);
165 /* When we reach this we're officialy fucked! */
168 static void hw_sleep_time(struct userdata
*u
, pa_usec_t
*sleep_usec
, pa_usec_t
*process_usec
) {
171 pa_assert(sleep_usec
);
172 pa_assert(process_usec
);
176 usec
= pa_sink_get_requested_latency_within_thread(u
->sink
);
178 if (usec
== (pa_usec_t
) -1)
179 usec
= pa_bytes_to_usec(u
->hwbuf_size
, &u
->sink
->sample_spec
);
181 wm
= pa_bytes_to_usec(u
->tsched_watermark
, &u
->sink
->sample_spec
);
186 *sleep_usec
= usec
- wm
;
190 pa_log_debug("Buffer time: %lu ms; Sleep time: %lu ms; Process time: %lu ms",
191 (unsigned long) (usec
/ PA_USEC_PER_MSEC
),
192 (unsigned long) (*sleep_usec
/ PA_USEC_PER_MSEC
),
193 (unsigned long) (*process_usec
/ PA_USEC_PER_MSEC
));
197 static int try_recover(struct userdata
*u
, const char *call
, int err
) {
202 pa_log_debug("%s: %s", call
, snd_strerror(err
));
204 pa_assert(err
!= -EAGAIN
);
207 pa_log_debug("%s: Buffer underrun!", call
);
209 if ((err
= snd_pcm_recover(u
->pcm_handle
, err
, 1)) < 0) {
210 pa_log("%s: %s", call
, snd_strerror(err
));
219 static size_t check_left_to_play(struct userdata
*u
, size_t n_bytes
) {
222 /* We use <= instead of < for this check here because an underrun
223 * only happens after the last sample was processed, not already when
224 * it is removed from the buffer. This is particularly important
225 * when block transfer is used. */
227 if (n_bytes
<= u
->hwbuf_size
) {
228 left_to_play
= u
->hwbuf_size
- n_bytes
;
231 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
);
241 if (!u
->first
&& !u
->after_rewind
) {
243 if (pa_log_ratelimit())
244 pa_log_info("Underrun!");
247 adjust_after_underrun(u
);
254 static int mmap_write(struct userdata
*u
, pa_usec_t
*sleep_usec
, pa_bool_t polled
) {
255 pa_bool_t work_done
= TRUE
;
256 pa_usec_t max_sleep_usec
= 0, process_usec
= 0;
260 pa_sink_assert_ref(u
->sink
);
263 hw_sleep_time(u
, &max_sleep_usec
, &process_usec
);
270 /* First we determine how many samples are missing to fill the
271 * buffer up to 100% */
273 if (PA_UNLIKELY((n
= pa_alsa_safe_avail(u
->pcm_handle
, u
->hwbuf_size
, &u
->sink
->sample_spec
)) < 0)) {
275 if ((r
= try_recover(u
, "snd_pcm_avail", (int) n
)) == 0)
281 n_bytes
= (size_t) n
* u
->frame_size
;
284 pa_log_debug("avail: %lu", (unsigned long) n_bytes
);
287 left_to_play
= check_left_to_play(u
, n_bytes
);
291 /* We won't fill up the playback buffer before at least
292 * half the sleep time is over because otherwise we might
293 * ask for more data from the clients then they expect. We
294 * need to guarantee that clients only have to keep around
295 * a single hw buffer length. */
298 pa_bytes_to_usec(left_to_play
, &u
->sink
->sample_spec
) > process_usec
+max_sleep_usec
/2) {
300 pa_log_debug("Not filling up, because too early.");
305 if (PA_UNLIKELY(n_bytes
<= u
->hwbuf_unused
)) {
307 if (polled
&& pa_log_ratelimit())
308 pa_log(_("ALSA woke us up to write new data to the device, but there was actually nothing to write! "
309 "Most likely this is an ALSA driver bug. Please report this issue to the ALSA developers. "
310 "We were woken up with POLLOUT set -- however a subsequent snd_pcm_avail_update() returned 0."));
313 pa_log_debug("Not filling up, because not necessary.");
318 n_bytes
-= u
->hwbuf_unused
;
322 pa_log_debug("Filling up");
329 const snd_pcm_channel_area_t
*areas
;
330 snd_pcm_uframes_t offset
, frames
;
331 snd_pcm_sframes_t sframes
;
333 frames
= (snd_pcm_uframes_t
) (n_bytes
/ u
->frame_size
);
334 /* pa_log_debug("%lu frames to write", (unsigned long) frames); */
336 if (PA_UNLIKELY((err
= pa_alsa_safe_mmap_begin(u
->pcm_handle
, &areas
, &offset
, &frames
, u
->hwbuf_size
, &u
->sink
->sample_spec
)) < 0)) {
338 if ((r
= try_recover(u
, "snd_pcm_mmap_begin", err
)) == 0)
344 /* Make sure that if these memblocks need to be copied they will fit into one slot */
345 if (frames
> pa_mempool_block_size_max(u
->sink
->core
->mempool
)/u
->frame_size
)
346 frames
= pa_mempool_block_size_max(u
->sink
->core
->mempool
)/u
->frame_size
;
348 /* Check these are multiples of 8 bit */
349 pa_assert((areas
[0].first
& 7) == 0);
350 pa_assert((areas
[0].step
& 7)== 0);
352 /* We assume a single interleaved memory buffer */
353 pa_assert((areas
[0].first
>> 3) == 0);
354 pa_assert((areas
[0].step
>> 3) == u
->frame_size
);
356 p
= (uint8_t*) areas
[0].addr
+ (offset
* u
->frame_size
);
358 chunk
.memblock
= pa_memblock_new_fixed(u
->core
->mempool
, p
, frames
* u
->frame_size
, TRUE
);
359 chunk
.length
= pa_memblock_get_length(chunk
.memblock
);
362 pa_sink_render_into_full(u
->sink
, &chunk
);
363 pa_memblock_unref_fixed(chunk
.memblock
);
365 if (PA_UNLIKELY((sframes
= snd_pcm_mmap_commit(u
->pcm_handle
, offset
, frames
)) < 0)) {
367 if ((r
= try_recover(u
, "snd_pcm_mmap_commit", (int) sframes
)) == 0)
375 u
->write_count
+= frames
* u
->frame_size
;
376 u
->since_start
+= frames
* u
->frame_size
;
379 pa_log_debug("Wrote %lu bytes", (unsigned long) (frames
* u
->frame_size
));
382 if ((size_t) frames
* u
->frame_size
>= n_bytes
)
385 n_bytes
-= (size_t) frames
* u
->frame_size
;
389 *sleep_usec
= pa_bytes_to_usec(left_to_play
, &u
->sink
->sample_spec
) - process_usec
;
390 return work_done
? 1 : 0;
393 static int unix_write(struct userdata
*u
, pa_usec_t
*sleep_usec
, pa_bool_t polled
) {
394 pa_bool_t work_done
= FALSE
;
395 pa_usec_t max_sleep_usec
= 0, process_usec
= 0;
399 pa_sink_assert_ref(u
->sink
);
402 hw_sleep_time(u
, &max_sleep_usec
, &process_usec
);
409 if (PA_UNLIKELY((n
= pa_alsa_safe_avail(u
->pcm_handle
, u
->hwbuf_size
, &u
->sink
->sample_spec
)) < 0)) {
411 if ((r
= try_recover(u
, "snd_pcm_avail", (int) n
)) == 0)
417 n_bytes
= (size_t) n
* u
->frame_size
;
418 left_to_play
= check_left_to_play(u
, n_bytes
);
422 /* We won't fill up the playback buffer before at least
423 * half the sleep time is over because otherwise we might
424 * ask for more data from the clients then they expect. We
425 * need to guarantee that clients only have to keep around
426 * a single hw buffer length. */
429 pa_bytes_to_usec(left_to_play
, &u
->sink
->sample_spec
) > process_usec
+max_sleep_usec
/2)
432 if (PA_UNLIKELY(n_bytes
<= u
->hwbuf_unused
)) {
434 if (polled
&& pa_log_ratelimit())
435 pa_log(_("ALSA woke us up to write new data to the device, but there was actually nothing to write! "
436 "Most likely this is an ALSA driver bug. Please report this issue to the ALSA developers. "
437 "We were woken up with POLLOUT set -- however a subsequent snd_pcm_avail_update() returned 0."));
442 n_bytes
-= u
->hwbuf_unused
;
446 snd_pcm_sframes_t frames
;
449 /* pa_log_debug("%lu frames to write", (unsigned long) frames); */
451 if (u
->memchunk
.length
<= 0)
452 pa_sink_render(u
->sink
, n_bytes
, &u
->memchunk
);
454 pa_assert(u
->memchunk
.length
> 0);
456 frames
= (snd_pcm_sframes_t
) (u
->memchunk
.length
/ u
->frame_size
);
458 if (frames
> (snd_pcm_sframes_t
) (n_bytes
/u
->frame_size
))
459 frames
= (snd_pcm_sframes_t
) (n_bytes
/u
->frame_size
);
461 p
= pa_memblock_acquire(u
->memchunk
.memblock
);
462 frames
= snd_pcm_writei(u
->pcm_handle
, (const uint8_t*) p
+ u
->memchunk
.index
, (snd_pcm_uframes_t
) frames
);
463 pa_memblock_release(u
->memchunk
.memblock
);
465 pa_assert(frames
!= 0);
467 if (PA_UNLIKELY(frames
< 0)) {
469 if ((r
= try_recover(u
, "snd_pcm_writei", (int) frames
)) == 0)
475 u
->memchunk
.index
+= (size_t) frames
* u
->frame_size
;
476 u
->memchunk
.length
-= (size_t) frames
* u
->frame_size
;
478 if (u
->memchunk
.length
<= 0) {
479 pa_memblock_unref(u
->memchunk
.memblock
);
480 pa_memchunk_reset(&u
->memchunk
);
485 u
->write_count
+= frames
* u
->frame_size
;
486 u
->since_start
+= frames
* u
->frame_size
;
488 /* pa_log_debug("wrote %lu frames", (unsigned long) frames); */
490 if ((size_t) frames
* u
->frame_size
>= n_bytes
)
493 n_bytes
-= (size_t) frames
* u
->frame_size
;
497 *sleep_usec
= pa_bytes_to_usec(left_to_play
, &u
->sink
->sample_spec
) - process_usec
;
498 return work_done
? 1 : 0;
501 static void update_smoother(struct userdata
*u
) {
502 snd_pcm_sframes_t delay
= 0;
505 pa_usec_t now1
= 0, now2
;
506 snd_pcm_status_t
*status
;
508 snd_pcm_status_alloca(&status
);
511 pa_assert(u
->pcm_handle
);
513 /* Let's update the time smoother */
515 if (PA_UNLIKELY((err
= snd_pcm_delay(u
->pcm_handle
, &delay
)) < 0)) {
516 pa_log_warn("Failed to query DSP status data: %s", snd_strerror(err
));
520 if (PA_UNLIKELY((err
= snd_pcm_status(u
->pcm_handle
, status
)) < 0))
521 pa_log_warn("Failed to get timestamp: %s", snd_strerror(err
));
523 snd_htimestamp_t htstamp
= { 0, 0 };
524 snd_pcm_status_get_htstamp(status
, &htstamp
);
525 now1
= pa_timespec_load(&htstamp
);
528 position
= (int64_t) u
->write_count
- ((int64_t) delay
* (int64_t) u
->frame_size
);
530 if (PA_UNLIKELY(position
< 0))
533 /* Hmm, if the timestamp is 0, then it wasn't set and we take the current time */
535 now1
= pa_rtclock_usec();
537 now2
= pa_bytes_to_usec((uint64_t) position
, &u
->sink
->sample_spec
);
539 pa_smoother_put(u
->smoother
, now1
, now2
);
542 static pa_usec_t
sink_get_latency(struct userdata
*u
) {
545 pa_usec_t now1
, now2
;
549 now1
= pa_rtclock_usec();
550 now2
= pa_smoother_get(u
->smoother
, now1
);
552 delay
= (int64_t) pa_bytes_to_usec(u
->write_count
, &u
->sink
->sample_spec
) - (int64_t) now2
;
554 r
= delay
>= 0 ? (pa_usec_t
) delay
: 0;
556 if (u
->memchunk
.memblock
)
557 r
+= pa_bytes_to_usec(u
->memchunk
.length
, &u
->sink
->sample_spec
);
562 static int build_pollfd(struct userdata
*u
) {
564 pa_assert(u
->pcm_handle
);
566 if (u
->alsa_rtpoll_item
)
567 pa_rtpoll_item_free(u
->alsa_rtpoll_item
);
569 if (!(u
->alsa_rtpoll_item
= pa_alsa_build_pollfd(u
->pcm_handle
, u
->rtpoll
)))
575 static int suspend(struct userdata
*u
) {
577 pa_assert(u
->pcm_handle
);
579 pa_smoother_pause(u
->smoother
, pa_rtclock_usec());
581 /* Let's suspend -- we don't call snd_pcm_drain() here since that might
582 * take awfully long with our long buffer sizes today. */
583 snd_pcm_close(u
->pcm_handle
);
584 u
->pcm_handle
= NULL
;
586 if (u
->alsa_rtpoll_item
) {
587 pa_rtpoll_item_free(u
->alsa_rtpoll_item
);
588 u
->alsa_rtpoll_item
= NULL
;
591 pa_log_info("Device suspended...");
596 static int update_sw_params(struct userdata
*u
) {
597 snd_pcm_uframes_t avail_min
;
602 /* Use the full buffer if noone asked us for anything specific */
608 if ((latency
= pa_sink_get_requested_latency_within_thread(u
->sink
)) != (pa_usec_t
) -1) {
611 pa_log_debug("Latency set to %0.2fms", (double) latency
/ PA_USEC_PER_MSEC
);
613 b
= pa_usec_to_bytes(latency
, &u
->sink
->sample_spec
);
615 /* We need at least one sample in our buffer */
617 if (PA_UNLIKELY(b
< u
->frame_size
))
620 u
->hwbuf_unused
= PA_LIKELY(b
< u
->hwbuf_size
) ? (u
->hwbuf_size
- b
) : 0;
623 fix_min_sleep_wakeup(u
);
624 fix_tsched_watermark(u
);
627 pa_log_debug("hwbuf_unused=%lu", (unsigned long) u
->hwbuf_unused
);
629 /* We need at last one frame in the used part of the buffer */
630 avail_min
= (snd_pcm_uframes_t
) u
->hwbuf_unused
/ u
->frame_size
+ 1;
633 pa_usec_t sleep_usec
, process_usec
;
635 hw_sleep_time(u
, &sleep_usec
, &process_usec
);
636 avail_min
+= pa_usec_to_bytes(sleep_usec
, &u
->sink
->sample_spec
) / u
->frame_size
;
639 pa_log_debug("setting avail_min=%lu", (unsigned long) avail_min
);
641 if ((err
= pa_alsa_set_sw_params(u
->pcm_handle
, avail_min
)) < 0) {
642 pa_log("Failed to set software parameters: %s", snd_strerror(err
));
646 pa_sink_set_max_request(u
->sink
, u
->hwbuf_size
- u
->hwbuf_unused
);
651 static int unsuspend(struct userdata
*u
) {
656 snd_pcm_uframes_t period_size
;
659 pa_assert(!u
->pcm_handle
);
661 pa_log_info("Trying resume...");
663 snd_config_update_free_global();
664 if ((err
= snd_pcm_open(&u
->pcm_handle
, u
->device_name
, SND_PCM_STREAM_PLAYBACK
,
665 /*SND_PCM_NONBLOCK|*/
666 SND_PCM_NO_AUTO_RESAMPLE
|
667 SND_PCM_NO_AUTO_CHANNELS
|
668 SND_PCM_NO_AUTO_FORMAT
)) < 0) {
669 pa_log("Error opening PCM device %s: %s", u
->device_name
, snd_strerror(err
));
673 ss
= u
->sink
->sample_spec
;
674 nfrags
= u
->nfragments
;
675 period_size
= u
->fragment_size
/ u
->frame_size
;
679 if ((err
= pa_alsa_set_hw_params(u
->pcm_handle
, &ss
, &nfrags
, &period_size
, u
->hwbuf_size
/ u
->frame_size
, &b
, &d
, TRUE
)) < 0) {
680 pa_log("Failed to set hardware parameters: %s", snd_strerror(err
));
684 if (b
!= u
->use_mmap
|| d
!= u
->use_tsched
) {
685 pa_log_warn("Resume failed, couldn't get original access mode.");
689 if (!pa_sample_spec_equal(&ss
, &u
->sink
->sample_spec
)) {
690 pa_log_warn("Resume failed, couldn't restore original sample settings.");
694 if (nfrags
!= u
->nfragments
|| period_size
*u
->frame_size
!= u
->fragment_size
) {
695 pa_log_warn("Resume failed, couldn't restore original fragment settings. (Old: %lu*%lu, New %lu*%lu)",
696 (unsigned long) u
->nfragments
, (unsigned long) u
->fragment_size
,
697 (unsigned long) nfrags
, period_size
* u
->frame_size
);
701 if (update_sw_params(u
) < 0)
704 if (build_pollfd(u
) < 0)
710 pa_log_info("Resumed successfully...");
716 snd_pcm_close(u
->pcm_handle
);
717 u
->pcm_handle
= NULL
;
723 static int sink_process_msg(pa_msgobject
*o
, int code
, void *data
, int64_t offset
, pa_memchunk
*chunk
) {
724 struct userdata
*u
= PA_SINK(o
)->userdata
;
728 case PA_SINK_MESSAGE_GET_LATENCY
: {
732 r
= sink_get_latency(u
);
734 *((pa_usec_t
*) data
) = r
;
739 case PA_SINK_MESSAGE_SET_STATE
:
741 switch ((pa_sink_state_t
) PA_PTR_TO_UINT(data
)) {
743 case PA_SINK_SUSPENDED
:
744 pa_assert(PA_SINK_IS_OPENED(u
->sink
->thread_info
.state
));
752 case PA_SINK_RUNNING
:
754 if (u
->sink
->thread_info
.state
== PA_SINK_INIT
) {
755 if (build_pollfd(u
) < 0)
759 if (u
->sink
->thread_info
.state
== PA_SINK_SUSPENDED
) {
760 if (unsuspend(u
) < 0)
766 case PA_SINK_UNLINKED
:
768 case PA_SINK_INVALID_STATE
:
775 return pa_sink_process_msg(o
, code
, data
, offset
, chunk
);
778 static int mixer_callback(snd_mixer_elem_t
*elem
, unsigned int mask
) {
779 struct userdata
*u
= snd_mixer_elem_get_callback_private(elem
);
782 pa_assert(u
->mixer_handle
);
784 if (mask
== SND_CTL_EVENT_MASK_REMOVE
)
787 if (mask
& SND_CTL_EVENT_MASK_VALUE
) {
788 pa_sink_get_volume(u
->sink
, TRUE
);
789 pa_sink_get_mute(u
->sink
, TRUE
);
795 static pa_volume_t
from_alsa_volume(struct userdata
*u
, long alsa_vol
) {
797 return (pa_volume_t
) round(((double) (alsa_vol
- u
->hw_volume_min
) * PA_VOLUME_NORM
) /
798 (double) (u
->hw_volume_max
- u
->hw_volume_min
));
801 static long to_alsa_volume(struct userdata
*u
, pa_volume_t vol
) {
804 alsa_vol
= (long) round(((double) vol
* (double) (u
->hw_volume_max
- u
->hw_volume_min
))
805 / PA_VOLUME_NORM
) + u
->hw_volume_min
;
807 return PA_CLAMP_UNLIKELY(alsa_vol
, u
->hw_volume_min
, u
->hw_volume_max
);
810 static void sink_get_volume_cb(pa_sink
*s
) {
811 struct userdata
*u
= s
->userdata
;
815 char t
[PA_CVOLUME_SNPRINT_MAX
];
818 pa_assert(u
->mixer_elem
);
820 if (u
->mixer_seperate_channels
) {
822 r
.channels
= s
->sample_spec
.channels
;
824 for (i
= 0; i
< s
->sample_spec
.channels
; i
++) {
827 if (u
->hw_dB_supported
) {
829 if ((err
= snd_mixer_selem_get_playback_dB(u
->mixer_elem
, u
->mixer_map
[i
], &alsa_vol
)) < 0)
832 #ifdef HAVE_VALGRIND_MEMCHECK_H
833 VALGRIND_MAKE_MEM_DEFINED(&alsa_vol
, sizeof(alsa_vol
));
836 r
.values
[i
] = pa_sw_volume_from_dB((double) (alsa_vol
- u
->hw_dB_max
) / 100.0);
839 if ((err
= snd_mixer_selem_get_playback_volume(u
->mixer_elem
, u
->mixer_map
[i
], &alsa_vol
)) < 0)
842 r
.values
[i
] = from_alsa_volume(u
, alsa_vol
);
849 if (u
->hw_dB_supported
) {
851 if ((err
= snd_mixer_selem_get_playback_dB(u
->mixer_elem
, SND_MIXER_SCHN_MONO
, &alsa_vol
)) < 0)
854 #ifdef HAVE_VALGRIND_MEMCHECK_H
855 VALGRIND_MAKE_MEM_DEFINED(&alsa_vol
, sizeof(alsa_vol
));
858 pa_cvolume_set(&r
, s
->sample_spec
.channels
, pa_sw_volume_from_dB((double) (alsa_vol
- u
->hw_dB_max
) / 100.0));
862 if ((err
= snd_mixer_selem_get_playback_volume(u
->mixer_elem
, SND_MIXER_SCHN_MONO
, &alsa_vol
)) < 0)
865 pa_cvolume_set(&r
, s
->sample_spec
.channels
, from_alsa_volume(u
, alsa_vol
));
869 pa_log_debug("Read hardware volume: %s", pa_cvolume_snprint(t
, sizeof(t
), &r
));
871 if (!pa_cvolume_equal(&u
->hardware_volume
, &r
)) {
873 s
->virtual_volume
= u
->hardware_volume
= r
;
875 if (u
->hw_dB_supported
) {
878 /* Hmm, so the hardware volume changed, let's reset our software volume */
879 pa_cvolume_reset(&reset
, s
->sample_spec
.channels
);
880 pa_sink_set_soft_volume(s
, &reset
);
887 pa_log_error("Unable to read volume: %s", snd_strerror(err
));
890 static void sink_set_volume_cb(pa_sink
*s
) {
891 struct userdata
*u
= s
->userdata
;
897 pa_assert(u
->mixer_elem
);
899 if (u
->mixer_seperate_channels
) {
901 r
.channels
= s
->sample_spec
.channels
;
903 for (i
= 0; i
< s
->sample_spec
.channels
; i
++) {
907 vol
= s
->virtual_volume
.values
[i
];
909 if (u
->hw_dB_supported
) {
911 alsa_vol
= (long) (pa_sw_volume_to_dB(vol
) * 100);
912 alsa_vol
+= u
->hw_dB_max
;
913 alsa_vol
= PA_CLAMP_UNLIKELY(alsa_vol
, u
->hw_dB_min
, u
->hw_dB_max
);
915 if ((err
= snd_mixer_selem_set_playback_dB(u
->mixer_elem
, u
->mixer_map
[i
], alsa_vol
, 1)) < 0)
918 if ((err
= snd_mixer_selem_get_playback_dB(u
->mixer_elem
, u
->mixer_map
[i
], &alsa_vol
)) < 0)
921 #ifdef HAVE_VALGRIND_MEMCHECK_H
922 VALGRIND_MAKE_MEM_DEFINED(&alsa_vol
, sizeof(alsa_vol
));
925 r
.values
[i
] = pa_sw_volume_from_dB((double) (alsa_vol
- u
->hw_dB_max
) / 100.0);
928 alsa_vol
= to_alsa_volume(u
, vol
);
930 if ((err
= snd_mixer_selem_set_playback_volume(u
->mixer_elem
, u
->mixer_map
[i
], alsa_vol
)) < 0)
933 if ((err
= snd_mixer_selem_get_playback_volume(u
->mixer_elem
, u
->mixer_map
[i
], &alsa_vol
)) < 0)
936 r
.values
[i
] = from_alsa_volume(u
, alsa_vol
);
944 vol
= pa_cvolume_max(&s
->virtual_volume
);
946 if (u
->hw_dB_supported
) {
947 alsa_vol
= (long) (pa_sw_volume_to_dB(vol
) * 100);
948 alsa_vol
+= u
->hw_dB_max
;
949 alsa_vol
= PA_CLAMP_UNLIKELY(alsa_vol
, u
->hw_dB_min
, u
->hw_dB_max
);
951 if ((err
= snd_mixer_selem_set_playback_dB_all(u
->mixer_elem
, alsa_vol
, 1)) < 0)
954 if ((err
= snd_mixer_selem_get_playback_dB(u
->mixer_elem
, SND_MIXER_SCHN_MONO
, &alsa_vol
)) < 0)
957 #ifdef HAVE_VALGRIND_MEMCHECK_H
958 VALGRIND_MAKE_MEM_DEFINED(&alsa_vol
, sizeof(alsa_vol
));
961 pa_cvolume_set(&r
, s
->sample_spec
.channels
, pa_sw_volume_from_dB((double) (alsa_vol
- u
->hw_dB_max
) / 100.0));
964 alsa_vol
= to_alsa_volume(u
, vol
);
966 if ((err
= snd_mixer_selem_set_playback_volume_all(u
->mixer_elem
, alsa_vol
)) < 0)
969 if ((err
= snd_mixer_selem_get_playback_volume(u
->mixer_elem
, SND_MIXER_SCHN_MONO
, &alsa_vol
)) < 0)
972 pa_cvolume_set(&r
, s
->sample_spec
.channels
, from_alsa_volume(u
, alsa_vol
));
976 u
->hardware_volume
= r
;
978 if (u
->hw_dB_supported
) {
979 char t
[PA_CVOLUME_SNPRINT_MAX
];
981 /* Match exactly what the user requested by software */
982 pa_sw_cvolume_divide(&s
->soft_volume
, &s
->virtual_volume
, &u
->hardware_volume
);
984 pa_log_debug("Requested volume: %s", pa_cvolume_snprint(t
, sizeof(t
), &s
->virtual_volume
));
985 pa_log_debug("Got hardware volume: %s", pa_cvolume_snprint(t
, sizeof(t
), &u
->hardware_volume
));
986 pa_log_debug("Calculated software volume: %s", pa_cvolume_snprint(t
, sizeof(t
), &s
->soft_volume
));
990 /* We can't match exactly what the user requested, hence let's
991 * at least tell the user about it */
993 s
->virtual_volume
= r
;
998 pa_log_error("Unable to set volume: %s", snd_strerror(err
));
1001 static void sink_get_mute_cb(pa_sink
*s
) {
1002 struct userdata
*u
= s
->userdata
;
1006 pa_assert(u
->mixer_elem
);
1008 if ((err
= snd_mixer_selem_get_playback_switch(u
->mixer_elem
, 0, &sw
)) < 0) {
1009 pa_log_error("Unable to get switch: %s", snd_strerror(err
));
1016 static void sink_set_mute_cb(pa_sink
*s
) {
1017 struct userdata
*u
= s
->userdata
;
1021 pa_assert(u
->mixer_elem
);
1023 if ((err
= snd_mixer_selem_set_playback_switch_all(u
->mixer_elem
, !s
->muted
)) < 0) {
1024 pa_log_error("Unable to set switch: %s", snd_strerror(err
));
1029 static void sink_update_requested_latency_cb(pa_sink
*s
) {
1030 struct userdata
*u
= s
->userdata
;
1037 before
= u
->hwbuf_unused
;
1038 update_sw_params(u
);
1040 /* Let's check whether we now use only a smaller part of the
1041 buffer then before. If so, we need to make sure that subsequent
1042 rewinds are relative to the new maxium fill level and not to the
1043 current fill level. Thus, let's do a full rewind once, to clear
1046 if (u
->hwbuf_unused
> before
) {
1047 pa_log_debug("Requesting rewind due to latency change.");
1048 pa_sink_request_rewind(s
, (size_t) -1);
1052 static int process_rewind(struct userdata
*u
) {
1053 snd_pcm_sframes_t unused
;
1054 size_t rewind_nbytes
, unused_nbytes
, limit_nbytes
;
1057 /* Figure out how much we shall rewind and reset the counter */
1058 rewind_nbytes
= u
->sink
->thread_info
.rewind_nbytes
;
1059 u
->sink
->thread_info
.rewind_nbytes
= 0;
1061 if (rewind_nbytes
<= 0)
1064 pa_assert(rewind_nbytes
> 0);
1065 pa_log_debug("Requested to rewind %lu bytes.", (unsigned long) rewind_nbytes
);
1067 snd_pcm_hwsync(u
->pcm_handle
);
1068 if ((unused
= snd_pcm_avail_update(u
->pcm_handle
)) < 0) {
1069 pa_log("snd_pcm_avail_update() failed: %s", snd_strerror((int) unused
));
1073 unused_nbytes
= u
->tsched_watermark
+ (size_t) unused
* u
->frame_size
;
1075 if (u
->hwbuf_size
> unused_nbytes
)
1076 limit_nbytes
= u
->hwbuf_size
- unused_nbytes
;
1080 if (rewind_nbytes
> limit_nbytes
)
1081 rewind_nbytes
= limit_nbytes
;
1083 if (rewind_nbytes
> 0) {
1084 snd_pcm_sframes_t in_frames
, out_frames
;
1086 pa_log_debug("Limited to %lu bytes.", (unsigned long) rewind_nbytes
);
1088 in_frames
= (snd_pcm_sframes_t
) (rewind_nbytes
/ u
->frame_size
);
1089 pa_log_debug("before: %lu", (unsigned long) in_frames
);
1090 if ((out_frames
= snd_pcm_rewind(u
->pcm_handle
, (snd_pcm_uframes_t
) in_frames
)) < 0) {
1091 pa_log("snd_pcm_rewind() failed: %s", snd_strerror((int) out_frames
));
1094 pa_log_debug("after: %lu", (unsigned long) out_frames
);
1096 rewind_nbytes
= (size_t) out_frames
* u
->frame_size
;
1098 if (rewind_nbytes
<= 0)
1099 pa_log_info("Tried rewind, but was apparently not possible.");
1101 u
->write_count
-= out_frames
* u
->frame_size
;
1102 pa_log_debug("Rewound %lu bytes.", (unsigned long) rewind_nbytes
);
1103 pa_sink_process_rewind(u
->sink
, rewind_nbytes
);
1105 u
->after_rewind
= TRUE
;
1109 pa_log_debug("Mhmm, actually there is nothing to rewind.");
1113 pa_sink_process_rewind(u
->sink
, 0);
1119 static void thread_func(void *userdata
) {
1120 struct userdata
*u
= userdata
;
1121 unsigned short revents
= 0;
1125 pa_log_debug("Thread starting up");
1127 if (u
->core
->realtime_scheduling
)
1128 pa_make_realtime(u
->core
->realtime_priority
);
1130 pa_thread_mq_install(&u
->thread_mq
);
1131 pa_rtpoll_install(u
->rtpoll
);
1137 pa_log_debug("Loop");
1140 /* Render some data and write it to the dsp */
1141 if (PA_SINK_IS_OPENED(u
->sink
->thread_info
.state
)) {
1143 pa_usec_t sleep_usec
= 0;
1145 if (u
->sink
->thread_info
.rewind_requested
)
1146 if (process_rewind(u
) < 0)
1150 work_done
= mmap_write(u
, &sleep_usec
, revents
& POLLOUT
);
1152 work_done
= unix_write(u
, &sleep_usec
, revents
& POLLOUT
);
1157 /* pa_log_debug("work_done = %i", work_done); */
1162 pa_log_info("Starting playback.");
1163 snd_pcm_start(u
->pcm_handle
);
1165 pa_smoother_resume(u
->smoother
, pa_rtclock_usec());
1171 if (u
->use_tsched
) {
1174 if (u
->since_start
<= u
->hwbuf_size
) {
1176 /* USB devices on ALSA seem to hit a buffer
1177 * underrun during the first iterations much
1178 * quicker then we calculate here, probably due to
1179 * the transport latency. To accomodate for that
1180 * we artificially decrease the sleep time until
1181 * we have filled the buffer at least once
1184 pa_log_debug("Cutting sleep time for the initial iterations by half.");
1188 /* OK, the playback buffer is now full, let's
1189 * calculate when to wake up next */
1190 /* pa_log_debug("Waking up in %0.2fms (sound card clock).", (double) sleep_usec / PA_USEC_PER_MSEC); */
1192 /* Convert from the sound card time domain to the
1193 * system time domain */
1194 cusec
= pa_smoother_translate(u
->smoother
, pa_rtclock_usec(), sleep_usec
);
1196 /* pa_log_debug("Waking up in %0.2fms (system clock).", (double) cusec / PA_USEC_PER_MSEC); */
1198 /* We don't trust the conversion, so we wake up whatever comes first */
1199 pa_rtpoll_set_timer_relative(u
->rtpoll
, PA_MIN(sleep_usec
, cusec
));
1203 u
->after_rewind
= FALSE
;
1205 } else if (u
->use_tsched
)
1207 /* OK, we're in an invalid state, let's disable our timers */
1208 pa_rtpoll_set_timer_disabled(u
->rtpoll
);
1210 /* Hmm, nothing to do. Let's sleep */
1211 if ((ret
= pa_rtpoll_run(u
->rtpoll
, TRUE
)) < 0)
1217 /* Tell ALSA about this and process its response */
1218 if (PA_SINK_IS_OPENED(u
->sink
->thread_info
.state
)) {
1219 struct pollfd
*pollfd
;
1223 pollfd
= pa_rtpoll_item_get_pollfd(u
->alsa_rtpoll_item
, &n
);
1225 if ((err
= snd_pcm_poll_descriptors_revents(u
->pcm_handle
, pollfd
, n
, &revents
)) < 0) {
1226 pa_log("snd_pcm_poll_descriptors_revents() failed: %s", snd_strerror(err
));
1230 if (revents
& ~POLLOUT
) {
1231 if (pa_alsa_recover_from_poll(u
->pcm_handle
, revents
) < 0)
1236 } else if (revents
&& u
->use_tsched
&& pa_log_ratelimit())
1237 pa_log_debug("Wakeup from ALSA!");
1244 /* If this was no regular exit from the loop we have to continue
1245 * processing messages until we received PA_MESSAGE_SHUTDOWN */
1246 pa_asyncmsgq_post(u
->thread_mq
.outq
, PA_MSGOBJECT(u
->core
), PA_CORE_MESSAGE_UNLOAD_MODULE
, u
->module
, 0, NULL
, NULL
);
1247 pa_asyncmsgq_wait_for(u
->thread_mq
.inq
, PA_MESSAGE_SHUTDOWN
);
1250 pa_log_debug("Thread shutting down");
1253 static void set_sink_name(pa_sink_new_data
*data
, pa_modargs
*ma
, const char *device_id
, const char *device_name
) {
1259 pa_assert(device_name
);
1261 if ((n
= pa_modargs_get_value(ma
, "sink_name", NULL
))) {
1262 pa_sink_new_data_set_name(data
, n
);
1263 data
->namereg_fail
= TRUE
;
1267 if ((n
= pa_modargs_get_value(ma
, "name", NULL
)))
1268 data
->namereg_fail
= TRUE
;
1270 n
= device_id
? device_id
: device_name
;
1271 data
->namereg_fail
= FALSE
;
1274 t
= pa_sprintf_malloc("alsa_output.%s", n
);
1275 pa_sink_new_data_set_name(data
, t
);
1279 static int setup_mixer(struct userdata
*u
, pa_bool_t ignore_dB
) {
1282 if (!u
->mixer_handle
)
1285 pa_assert(u
->mixer_elem
);
1287 if (snd_mixer_selem_has_playback_volume(u
->mixer_elem
)) {
1288 pa_bool_t suitable
= FALSE
;
1290 if (snd_mixer_selem_get_playback_volume_range(u
->mixer_elem
, &u
->hw_volume_min
, &u
->hw_volume_max
) < 0)
1291 pa_log_info("Failed to get volume range. Falling back to software volume control.");
1292 else if (u
->hw_volume_min
>= u
->hw_volume_max
)
1293 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
);
1295 pa_log_info("Volume ranges from %li to %li.", u
->hw_volume_min
, u
->hw_volume_max
);
1300 if (ignore_dB
|| snd_mixer_selem_get_playback_dB_range(u
->mixer_elem
, &u
->hw_dB_min
, &u
->hw_dB_max
) < 0)
1301 pa_log_info("Mixer doesn't support dB information or data is ignored.");
1303 #ifdef HAVE_VALGRIND_MEMCHECK_H
1304 VALGRIND_MAKE_MEM_DEFINED(&u
->hw_dB_min
, sizeof(u
->hw_dB_min
));
1305 VALGRIND_MAKE_MEM_DEFINED(&u
->hw_dB_max
, sizeof(u
->hw_dB_max
));
1308 if (u
->hw_dB_min
>= u
->hw_dB_max
)
1309 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);
1311 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);
1312 u
->hw_dB_supported
= TRUE
;
1314 if (u
->hw_dB_max
> 0) {
1315 u
->sink
->base_volume
= pa_sw_volume_from_dB(- (double) u
->hw_dB_max
/100.0);
1316 pa_log_info("Fixing base volume to %0.2f dB", pa_sw_volume_to_dB(u
->sink
->base_volume
));
1318 pa_log_info("No particular base volume set, fixing to 0 dB");
1322 if (!u
->hw_dB_supported
&&
1323 u
->hw_volume_max
- u
->hw_volume_min
< 3) {
1325 pa_log_info("Device doesn't do dB volume and has less than 4 volume levels. Falling back to software volume control.");
1331 u
->mixer_seperate_channels
= pa_alsa_calc_mixer_map(u
->mixer_elem
, &u
->sink
->channel_map
, u
->mixer_map
, TRUE
) >= 0;
1333 u
->sink
->get_volume
= sink_get_volume_cb
;
1334 u
->sink
->set_volume
= sink_set_volume_cb
;
1335 u
->sink
->flags
|= PA_SINK_HW_VOLUME_CTRL
| (u
->hw_dB_supported
? PA_SINK_DECIBEL_VOLUME
: 0);
1336 pa_log_info("Using hardware volume control. Hardware dB scale %s.", u
->hw_dB_supported
? "supported" : "not supported");
1338 if (!u
->hw_dB_supported
)
1339 u
->sink
->n_volume_steps
= u
->hw_volume_max
- u
->hw_volume_min
+ 1;
1341 pa_log_info("Using software volume control.");
1344 if (snd_mixer_selem_has_playback_switch(u
->mixer_elem
)) {
1345 u
->sink
->get_mute
= sink_get_mute_cb
;
1346 u
->sink
->set_mute
= sink_set_mute_cb
;
1347 u
->sink
->flags
|= PA_SINK_HW_MUTE_CTRL
;
1349 pa_log_info("Using software mute control.");
1351 u
->mixer_fdl
= pa_alsa_fdlist_new();
1353 if (pa_alsa_fdlist_set_mixer(u
->mixer_fdl
, u
->mixer_handle
, u
->core
->mainloop
) < 0) {
1354 pa_log("Failed to initialize file descriptor monitoring");
1358 snd_mixer_elem_set_callback(u
->mixer_elem
, mixer_callback
);
1359 snd_mixer_elem_set_callback_private(u
->mixer_elem
, u
);
1364 pa_sink
*pa_alsa_sink_new(pa_module
*m
, pa_modargs
*ma
, const char*driver
, pa_card
*card
, const pa_alsa_profile_info
*profile
) {
1366 struct userdata
*u
= NULL
;
1367 const char *dev_id
= NULL
;
1370 uint32_t nfrags
, hwbuf_size
, frag_size
, tsched_size
, tsched_watermark
;
1371 snd_pcm_uframes_t period_frames
, tsched_frames
;
1373 pa_bool_t use_mmap
= TRUE
, b
, use_tsched
= TRUE
, d
, ignore_dB
= FALSE
;
1375 pa_sink_new_data data
;
1380 ss
= m
->core
->default_sample_spec
;
1381 if (pa_modargs_get_sample_spec_and_channel_map(ma
, &ss
, &map
, PA_CHANNEL_MAP_ALSA
) < 0) {
1382 pa_log("Failed to parse sample specification and channel map");
1386 frame_size
= pa_frame_size(&ss
);
1388 nfrags
= m
->core
->default_n_fragments
;
1389 frag_size
= (uint32_t) pa_usec_to_bytes(m
->core
->default_fragment_size_msec
*PA_USEC_PER_MSEC
, &ss
);
1391 frag_size
= (uint32_t) frame_size
;
1392 tsched_size
= (uint32_t) pa_usec_to_bytes(DEFAULT_TSCHED_BUFFER_USEC
, &ss
);
1393 tsched_watermark
= (uint32_t) pa_usec_to_bytes(DEFAULT_TSCHED_WATERMARK_USEC
, &ss
);
1395 if (pa_modargs_get_value_u32(ma
, "fragments", &nfrags
) < 0 ||
1396 pa_modargs_get_value_u32(ma
, "fragment_size", &frag_size
) < 0 ||
1397 pa_modargs_get_value_u32(ma
, "tsched_buffer_size", &tsched_size
) < 0 ||
1398 pa_modargs_get_value_u32(ma
, "tsched_buffer_watermark", &tsched_watermark
) < 0) {
1399 pa_log("Failed to parse buffer metrics");
1403 hwbuf_size
= frag_size
* nfrags
;
1404 period_frames
= frag_size
/frame_size
;
1405 tsched_frames
= tsched_size
/frame_size
;
1407 if (pa_modargs_get_value_boolean(ma
, "mmap", &use_mmap
) < 0) {
1408 pa_log("Failed to parse mmap argument.");
1412 if (pa_modargs_get_value_boolean(ma
, "tsched", &use_tsched
) < 0) {
1413 pa_log("Failed to parse tsched argument.");
1417 if (pa_modargs_get_value_boolean(ma
, "ignore_dB", &ignore_dB
) < 0) {
1418 pa_log("Failed to parse ignore_dB argument.");
1422 if (use_tsched
&& !pa_rtclock_hrtimer()) {
1423 pa_log_notice("Disabling timer-based scheduling because high-resolution timers are not available from the kernel.");
1427 u
= pa_xnew0(struct userdata
, 1);
1430 u
->use_mmap
= use_mmap
;
1431 u
->use_tsched
= use_tsched
;
1433 u
->rtpoll
= pa_rtpoll_new();
1434 pa_thread_mq_init(&u
->thread_mq
, m
->core
->mainloop
, u
->rtpoll
);
1436 u
->smoother
= pa_smoother_new(DEFAULT_TSCHED_BUFFER_USEC
*2, DEFAULT_TSCHED_BUFFER_USEC
*2, TRUE
, 5);
1437 usec
= pa_rtclock_usec();
1438 pa_smoother_set_time_offset(u
->smoother
, usec
);
1439 pa_smoother_pause(u
->smoother
, usec
);
1446 if (!(dev_id
= pa_modargs_get_value(ma
, "device_id", NULL
))) {
1447 pa_log("device_id= not set");
1451 if (!(u
->pcm_handle
= pa_alsa_open_by_device_id_profile(
1455 SND_PCM_STREAM_PLAYBACK
,
1456 &nfrags
, &period_frames
, tsched_frames
,
1461 } else if ((dev_id
= pa_modargs_get_value(ma
, "device_id", NULL
))) {
1463 if (!(u
->pcm_handle
= pa_alsa_open_by_device_id_auto(
1467 SND_PCM_STREAM_PLAYBACK
,
1468 &nfrags
, &period_frames
, tsched_frames
,
1475 if (!(u
->pcm_handle
= pa_alsa_open_by_device_string(
1476 pa_modargs_get_value(ma
, "device", DEFAULT_DEVICE
),
1479 SND_PCM_STREAM_PLAYBACK
,
1480 &nfrags
, &period_frames
, tsched_frames
,
1486 pa_assert(u
->device_name
);
1487 pa_log_info("Successfully opened device %s.", u
->device_name
);
1490 pa_log_info("Selected configuration '%s' (%s).", profile
->description
, profile
->name
);
1492 if (use_mmap
&& !b
) {
1493 pa_log_info("Device doesn't support mmap(), falling back to UNIX read/write mode.");
1494 u
->use_mmap
= use_mmap
= FALSE
;
1497 if (use_tsched
&& (!b
|| !d
)) {
1498 pa_log_info("Cannot enable timer-based scheduling, falling back to sound IRQ scheduling.");
1499 u
->use_tsched
= use_tsched
= FALSE
;
1503 pa_log_info("Successfully enabled mmap() mode.");
1506 pa_log_info("Successfully enabled timer-based scheduling mode.");
1508 /* ALSA might tweak the sample spec, so recalculate the frame size */
1509 frame_size
= pa_frame_size(&ss
);
1511 pa_alsa_find_mixer_and_elem(u
->pcm_handle
, &u
->mixer_handle
, &u
->mixer_elem
);
1513 pa_sink_new_data_init(&data
);
1514 data
.driver
= driver
;
1517 set_sink_name(&data
, ma
, dev_id
, u
->device_name
);
1518 pa_sink_new_data_set_sample_spec(&data
, &ss
);
1519 pa_sink_new_data_set_channel_map(&data
, &map
);
1521 pa_alsa_init_proplist_pcm(m
->core
, data
.proplist
, u
->pcm_handle
);
1522 pa_proplist_sets(data
.proplist
, PA_PROP_DEVICE_STRING
, u
->device_name
);
1523 pa_proplist_setf(data
.proplist
, PA_PROP_DEVICE_BUFFERING_BUFFER_SIZE
, "%lu", (unsigned long) (period_frames
* frame_size
* nfrags
));
1524 pa_proplist_setf(data
.proplist
, PA_PROP_DEVICE_BUFFERING_FRAGMENT_SIZE
, "%lu", (unsigned long) (period_frames
* frame_size
));
1525 pa_proplist_sets(data
.proplist
, PA_PROP_DEVICE_ACCESS_MODE
, u
->use_tsched
? "mmap+timer" : (u
->use_mmap
? "mmap" : "serial"));
1528 pa_proplist_sets(data
.proplist
, PA_PROP_DEVICE_PROFILE_NAME
, profile
->name
);
1529 pa_proplist_sets(data
.proplist
, PA_PROP_DEVICE_PROFILE_DESCRIPTION
, profile
->description
);
1532 u
->sink
= pa_sink_new(m
->core
, &data
, PA_SINK_HARDWARE
|PA_SINK_LATENCY
);
1533 pa_sink_new_data_done(&data
);
1536 pa_log("Failed to create sink object");
1540 u
->sink
->parent
.process_msg
= sink_process_msg
;
1541 u
->sink
->update_requested_latency
= sink_update_requested_latency_cb
;
1542 u
->sink
->userdata
= u
;
1544 pa_sink_set_asyncmsgq(u
->sink
, u
->thread_mq
.inq
);
1545 pa_sink_set_rtpoll(u
->sink
, u
->rtpoll
);
1547 u
->frame_size
= frame_size
;
1548 u
->fragment_size
= frag_size
= (uint32_t) (period_frames
* frame_size
);
1549 u
->nfragments
= nfrags
;
1550 u
->hwbuf_size
= u
->fragment_size
* nfrags
;
1551 u
->tsched_watermark
= tsched_watermark
;
1552 pa_cvolume_mute(&u
->hardware_volume
, u
->sink
->sample_spec
.channels
);
1555 fix_min_sleep_wakeup(u
);
1556 fix_tsched_watermark(u
);
1559 u
->sink
->thread_info
.max_rewind
= use_tsched
? u
->hwbuf_size
: 0;
1560 u
->sink
->thread_info
.max_request
= u
->hwbuf_size
;
1562 pa_sink_set_latency_range(u
->sink
,
1563 !use_tsched
? pa_bytes_to_usec(u
->hwbuf_size
, &ss
) : (pa_usec_t
) -1,
1564 pa_bytes_to_usec(u
->hwbuf_size
, &ss
));
1566 pa_log_info("Using %u fragments of size %lu bytes, buffer time is %0.2fms",
1567 nfrags
, (long unsigned) u
->fragment_size
,
1568 (double) pa_bytes_to_usec(u
->hwbuf_size
, &ss
) / PA_USEC_PER_MSEC
);
1571 pa_log_info("Time scheduling watermark is %0.2fms",
1572 (double) pa_bytes_to_usec(u
->tsched_watermark
, &ss
) / PA_USEC_PER_MSEC
);
1574 if (update_sw_params(u
) < 0)
1577 if (setup_mixer(u
, ignore_dB
) < 0)
1580 pa_alsa_dump(u
->pcm_handle
);
1582 if (!(u
->thread
= pa_thread_new(thread_func
, u
))) {
1583 pa_log("Failed to create thread.");
1587 /* Get initial mixer settings */
1588 if (data
.volume_is_set
) {
1589 if (u
->sink
->set_volume
)
1590 u
->sink
->set_volume(u
->sink
);
1592 if (u
->sink
->get_volume
)
1593 u
->sink
->get_volume(u
->sink
);
1596 if (data
.muted_is_set
) {
1597 if (u
->sink
->set_mute
)
1598 u
->sink
->set_mute(u
->sink
);
1600 if (u
->sink
->get_mute
)
1601 u
->sink
->get_mute(u
->sink
);
1604 pa_sink_put(u
->sink
);
1615 static void userdata_free(struct userdata
*u
) {
1619 pa_sink_unlink(u
->sink
);
1622 pa_asyncmsgq_send(u
->thread_mq
.inq
, NULL
, PA_MESSAGE_SHUTDOWN
, NULL
, 0, NULL
);
1623 pa_thread_free(u
->thread
);
1626 pa_thread_mq_done(&u
->thread_mq
);
1629 pa_sink_unref(u
->sink
);
1631 if (u
->memchunk
.memblock
)
1632 pa_memblock_unref(u
->memchunk
.memblock
);
1634 if (u
->alsa_rtpoll_item
)
1635 pa_rtpoll_item_free(u
->alsa_rtpoll_item
);
1638 pa_rtpoll_free(u
->rtpoll
);
1641 pa_alsa_fdlist_free(u
->mixer_fdl
);
1643 if (u
->mixer_handle
)
1644 snd_mixer_close(u
->mixer_handle
);
1646 if (u
->pcm_handle
) {
1647 snd_pcm_drop(u
->pcm_handle
);
1648 snd_pcm_close(u
->pcm_handle
);
1652 pa_smoother_free(u
->smoother
);
1654 pa_xfree(u
->device_name
);
1658 void pa_alsa_sink_free(pa_sink
*s
) {
1661 pa_sink_assert_ref(s
);
1662 pa_assert_se(u
= s
->userdata
);