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.1 of the License,
10 or (at your option) any later version.
12 PulseAudio is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
17 You should have received a copy of the GNU Lesser General Public License
18 along with PulseAudio; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
29 #include <asoundlib.h>
31 #ifdef HAVE_VALGRIND_MEMCHECK_H
32 #include <valgrind/memcheck.h>
35 #include <pulse/i18n.h>
36 #include <pulse/rtclock.h>
37 #include <pulse/timeval.h>
38 #include <pulse/util.h>
39 #include <pulse/xmalloc.h>
41 #include <pulsecore/core.h>
42 #include <pulsecore/module.h>
43 #include <pulsecore/memchunk.h>
44 #include <pulsecore/sink.h>
45 #include <pulsecore/modargs.h>
46 #include <pulsecore/core-rtclock.h>
47 #include <pulsecore/core-util.h>
48 #include <pulsecore/sample-util.h>
49 #include <pulsecore/log.h>
50 #include <pulsecore/macro.h>
51 #include <pulsecore/thread.h>
52 #include <pulsecore/core-error.h>
53 #include <pulsecore/thread-mq.h>
54 #include <pulsecore/rtpoll.h>
55 #include <pulsecore/time-smoother.h>
57 #include <modules/reserve-wrap.h>
59 #include "alsa-util.h"
60 #include "alsa-sink.h"
62 /* #define DEBUG_TIMING */
64 #define DEFAULT_DEVICE "default"
65 #define DEFAULT_TSCHED_BUFFER_USEC (2*PA_USEC_PER_SEC) /* 2s -- Overall buffer size */
66 #define DEFAULT_TSCHED_WATERMARK_USEC (20*PA_USEC_PER_MSEC) /* 20ms -- Fill up when only this much is left in the buffer */
67 #define TSCHED_WATERMARK_STEP_USEC (10*PA_USEC_PER_MSEC) /* 10ms -- On underrun, increase watermark by this */
68 #define TSCHED_MIN_SLEEP_USEC (10*PA_USEC_PER_MSEC) /* 10ms -- Sleep at least 10ms on each iteration */
69 #define TSCHED_MIN_WAKEUP_USEC (4*PA_USEC_PER_MSEC) /* 4ms -- Wakeup at least this long before the buffer runs empty*/
71 #define VOLUME_ACCURACY (PA_VOLUME_NORM/100) /* don't require volume adjustments to be perfectly correct. don't necessarily extend granularity in software unless the differences get greater than this level */
79 pa_thread_mq thread_mq
;
82 snd_pcm_t
*pcm_handle
;
84 pa_alsa_fdlist
*mixer_fdl
;
85 snd_mixer_t
*mixer_handle
;
86 pa_alsa_path_set
*mixer_path_set
;
87 pa_alsa_path
*mixer_path
;
89 pa_cvolume hardware_volume
;
102 pa_memchunk memchunk
;
104 char *device_name
; /* name of the PCM device */
105 char *control_device
; /* name of the control device */
107 pa_bool_t use_mmap
:1, use_tsched
:1;
109 pa_bool_t first
, after_rewind
;
111 pa_rtpoll_item
*alsa_rtpoll_item
;
113 snd_mixer_selem_channel_id_t mixer_map
[SND_MIXER_SCHN_LAST
];
115 pa_smoother
*smoother
;
116 uint64_t write_count
;
117 uint64_t since_start
;
119 pa_reserve_wrapper
*reserve
;
120 pa_hook_slot
*reserve_slot
;
121 pa_reserve_monitor_wrapper
*monitor
;
122 pa_hook_slot
*monitor_slot
;
125 static void userdata_free(struct userdata
*u
);
127 static pa_hook_result_t
reserve_cb(pa_reserve_wrapper
*r
, void *forced
, struct userdata
*u
) {
131 if (pa_sink_suspend(u
->sink
, TRUE
, PA_SUSPEND_APPLICATION
) < 0)
132 return PA_HOOK_CANCEL
;
137 static void reserve_done(struct userdata
*u
) {
140 if (u
->reserve_slot
) {
141 pa_hook_slot_free(u
->reserve_slot
);
142 u
->reserve_slot
= NULL
;
146 pa_reserve_wrapper_unref(u
->reserve
);
151 static void reserve_update(struct userdata
*u
) {
152 const char *description
;
155 if (!u
->sink
|| !u
->reserve
)
158 if ((description
= pa_proplist_gets(u
->sink
->proplist
, PA_PROP_DEVICE_DESCRIPTION
)))
159 pa_reserve_wrapper_set_application_device_name(u
->reserve
, description
);
162 static int reserve_init(struct userdata
*u
, const char *dname
) {
171 if (pa_in_system_mode())
174 if (!(rname
= pa_alsa_get_reserve_name(dname
)))
177 /* We are resuming, try to lock the device */
178 u
->reserve
= pa_reserve_wrapper_get(u
->core
, rname
);
186 pa_assert(!u
->reserve_slot
);
187 u
->reserve_slot
= pa_hook_connect(pa_reserve_wrapper_hook(u
->reserve
), PA_HOOK_NORMAL
, (pa_hook_cb_t
) reserve_cb
, u
);
192 static pa_hook_result_t
monitor_cb(pa_reserve_monitor_wrapper
*w
, void* busy
, struct userdata
*u
) {
198 b
= PA_PTR_TO_UINT(busy
) && !u
->reserve
;
200 pa_sink_suspend(u
->sink
, b
, PA_SUSPEND_APPLICATION
);
204 static void monitor_done(struct userdata
*u
) {
207 if (u
->monitor_slot
) {
208 pa_hook_slot_free(u
->monitor_slot
);
209 u
->monitor_slot
= NULL
;
213 pa_reserve_monitor_wrapper_unref(u
->monitor
);
218 static int reserve_monitor_init(struct userdata
*u
, const char *dname
) {
224 if (pa_in_system_mode())
227 if (!(rname
= pa_alsa_get_reserve_name(dname
)))
230 u
->monitor
= pa_reserve_monitor_wrapper_get(u
->core
, rname
);
236 pa_assert(!u
->monitor_slot
);
237 u
->monitor_slot
= pa_hook_connect(pa_reserve_monitor_wrapper_hook(u
->monitor
), PA_HOOK_NORMAL
, (pa_hook_cb_t
) monitor_cb
, u
);
242 static void fix_min_sleep_wakeup(struct userdata
*u
) {
243 size_t max_use
, max_use_2
;
247 max_use
= u
->hwbuf_size
- u
->hwbuf_unused
;
248 max_use_2
= pa_frame_align(max_use
/2, &u
->sink
->sample_spec
);
250 u
->min_sleep
= pa_usec_to_bytes(TSCHED_MIN_SLEEP_USEC
, &u
->sink
->sample_spec
);
251 u
->min_sleep
= PA_CLAMP(u
->min_sleep
, u
->frame_size
, max_use_2
);
253 u
->min_wakeup
= pa_usec_to_bytes(TSCHED_MIN_WAKEUP_USEC
, &u
->sink
->sample_spec
);
254 u
->min_wakeup
= PA_CLAMP(u
->min_wakeup
, u
->frame_size
, max_use_2
);
257 static void fix_tsched_watermark(struct userdata
*u
) {
261 max_use
= u
->hwbuf_size
- u
->hwbuf_unused
;
263 if (u
->tsched_watermark
> max_use
- u
->min_sleep
)
264 u
->tsched_watermark
= max_use
- u
->min_sleep
;
266 if (u
->tsched_watermark
< u
->min_wakeup
)
267 u
->tsched_watermark
= u
->min_wakeup
;
270 static void adjust_after_underrun(struct userdata
*u
) {
271 size_t old_watermark
;
272 pa_usec_t old_min_latency
, new_min_latency
;
275 pa_assert(u
->use_tsched
);
277 /* First, just try to increase the watermark */
278 old_watermark
= u
->tsched_watermark
;
279 u
->tsched_watermark
= PA_MIN(u
->tsched_watermark
* 2, u
->tsched_watermark
+ u
->watermark_step
);
280 fix_tsched_watermark(u
);
282 if (old_watermark
!= u
->tsched_watermark
) {
283 pa_log_notice("Increasing wakeup watermark to %0.2f ms",
284 (double) pa_bytes_to_usec(u
->tsched_watermark
, &u
->sink
->sample_spec
) / PA_USEC_PER_MSEC
);
288 /* Hmm, we cannot increase the watermark any further, hence let's raise the latency */
289 old_min_latency
= u
->sink
->thread_info
.min_latency
;
290 new_min_latency
= PA_MIN(old_min_latency
* 2, old_min_latency
+ TSCHED_WATERMARK_STEP_USEC
);
291 new_min_latency
= PA_MIN(new_min_latency
, u
->sink
->thread_info
.max_latency
);
293 if (old_min_latency
!= new_min_latency
) {
294 pa_log_notice("Increasing minimal latency to %0.2f ms",
295 (double) new_min_latency
/ PA_USEC_PER_MSEC
);
297 pa_sink_set_latency_range_within_thread(u
->sink
, new_min_latency
, u
->sink
->thread_info
.max_latency
);
301 /* When we reach this we're officialy fucked! */
304 static void hw_sleep_time(struct userdata
*u
, pa_usec_t
*sleep_usec
, pa_usec_t
*process_usec
) {
307 pa_assert(sleep_usec
);
308 pa_assert(process_usec
);
312 usec
= pa_sink_get_requested_latency_within_thread(u
->sink
);
314 if (usec
== (pa_usec_t
) -1)
315 usec
= pa_bytes_to_usec(u
->hwbuf_size
, &u
->sink
->sample_spec
);
317 wm
= pa_bytes_to_usec(u
->tsched_watermark
, &u
->sink
->sample_spec
);
322 *sleep_usec
= usec
- wm
;
326 pa_log_debug("Buffer time: %lu ms; Sleep time: %lu ms; Process time: %lu ms",
327 (unsigned long) (usec
/ PA_USEC_PER_MSEC
),
328 (unsigned long) (*sleep_usec
/ PA_USEC_PER_MSEC
),
329 (unsigned long) (*process_usec
/ PA_USEC_PER_MSEC
));
333 static int try_recover(struct userdata
*u
, const char *call
, int err
) {
338 pa_log_debug("%s: %s", call
, pa_alsa_strerror(err
));
340 pa_assert(err
!= -EAGAIN
);
343 pa_log_debug("%s: Buffer underrun!", call
);
345 if (err
== -ESTRPIPE
)
346 pa_log_debug("%s: System suspended!", call
);
348 if ((err
= snd_pcm_recover(u
->pcm_handle
, err
, 1)) < 0) {
349 pa_log("%s: %s", call
, pa_alsa_strerror(err
));
358 static size_t check_left_to_play(struct userdata
*u
, size_t n_bytes
) {
361 /* We use <= instead of < for this check here because an underrun
362 * only happens after the last sample was processed, not already when
363 * it is removed from the buffer. This is particularly important
364 * when block transfer is used. */
366 if (n_bytes
<= u
->hwbuf_size
) {
367 left_to_play
= u
->hwbuf_size
- n_bytes
;
370 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
);
380 if (!u
->first
&& !u
->after_rewind
) {
382 if (pa_log_ratelimit())
383 pa_log_info("Underrun!");
386 adjust_after_underrun(u
);
393 static int mmap_write(struct userdata
*u
, pa_usec_t
*sleep_usec
, pa_bool_t polled
) {
394 pa_bool_t work_done
= TRUE
;
395 pa_usec_t max_sleep_usec
= 0, process_usec
= 0;
400 pa_sink_assert_ref(u
->sink
);
403 hw_sleep_time(u
, &max_sleep_usec
, &process_usec
);
409 pa_bool_t after_avail
= TRUE
;
411 /* First we determine how many samples are missing to fill the
412 * buffer up to 100% */
414 if (PA_UNLIKELY((n
= pa_alsa_safe_avail(u
->pcm_handle
, u
->hwbuf_size
, &u
->sink
->sample_spec
)) < 0)) {
416 if ((r
= try_recover(u
, "snd_pcm_avail", (int) n
)) == 0)
422 n_bytes
= (size_t) n
* u
->frame_size
;
425 pa_log_debug("avail: %lu", (unsigned long) n_bytes
);
428 left_to_play
= check_left_to_play(u
, n_bytes
);
432 /* We won't fill up the playback buffer before at least
433 * half the sleep time is over because otherwise we might
434 * ask for more data from the clients then they expect. We
435 * need to guarantee that clients only have to keep around
436 * a single hw buffer length. */
439 pa_bytes_to_usec(left_to_play
, &u
->sink
->sample_spec
) > process_usec
+max_sleep_usec
/2) {
441 pa_log_debug("Not filling up, because too early.");
446 if (PA_UNLIKELY(n_bytes
<= u
->hwbuf_unused
)) {
450 char *dn
= pa_alsa_get_driver_name_by_pcm(u
->pcm_handle
);
451 pa_log(_("ALSA woke us up to write new data to the device, but there was actually nothing to write!\n"
452 "Most likely this is a bug in the ALSA driver '%s'. Please report this issue to the ALSA developers.\n"
453 "We were woken up with POLLOUT set -- however a subsequent snd_pcm_avail() returned 0 or another value < min_avail."),
459 pa_log_debug("Not filling up, because not necessary.");
467 pa_log_debug("Not filling up, because already too many iterations.");
473 n_bytes
-= u
->hwbuf_unused
;
477 pa_log_debug("Filling up");
484 const snd_pcm_channel_area_t
*areas
;
485 snd_pcm_uframes_t offset
, frames
;
486 snd_pcm_sframes_t sframes
;
488 frames
= (snd_pcm_uframes_t
) (n_bytes
/ u
->frame_size
);
489 /* pa_log_debug("%lu frames to write", (unsigned long) frames); */
491 if (PA_UNLIKELY((err
= pa_alsa_safe_mmap_begin(u
->pcm_handle
, &areas
, &offset
, &frames
, u
->hwbuf_size
, &u
->sink
->sample_spec
)) < 0)) {
493 if (!after_avail
&& err
== -EAGAIN
)
496 if ((r
= try_recover(u
, "snd_pcm_mmap_begin", err
)) == 0)
502 /* Make sure that if these memblocks need to be copied they will fit into one slot */
503 if (frames
> pa_mempool_block_size_max(u
->sink
->core
->mempool
)/u
->frame_size
)
504 frames
= pa_mempool_block_size_max(u
->sink
->core
->mempool
)/u
->frame_size
;
506 if (!after_avail
&& frames
== 0)
509 pa_assert(frames
> 0);
512 /* Check these are multiples of 8 bit */
513 pa_assert((areas
[0].first
& 7) == 0);
514 pa_assert((areas
[0].step
& 7)== 0);
516 /* We assume a single interleaved memory buffer */
517 pa_assert((areas
[0].first
>> 3) == 0);
518 pa_assert((areas
[0].step
>> 3) == u
->frame_size
);
520 p
= (uint8_t*) areas
[0].addr
+ (offset
* u
->frame_size
);
522 chunk
.memblock
= pa_memblock_new_fixed(u
->core
->mempool
, p
, frames
* u
->frame_size
, TRUE
);
523 chunk
.length
= pa_memblock_get_length(chunk
.memblock
);
526 pa_sink_render_into_full(u
->sink
, &chunk
);
527 pa_memblock_unref_fixed(chunk
.memblock
);
529 if (PA_UNLIKELY((sframes
= snd_pcm_mmap_commit(u
->pcm_handle
, offset
, frames
)) < 0)) {
531 if ((r
= try_recover(u
, "snd_pcm_mmap_commit", (int) sframes
)) == 0)
539 u
->write_count
+= frames
* u
->frame_size
;
540 u
->since_start
+= frames
* u
->frame_size
;
543 pa_log_debug("Wrote %lu bytes (of possible %lu bytes)", (unsigned long) (frames
* u
->frame_size
), (unsigned long) n_bytes
);
546 if ((size_t) frames
* u
->frame_size
>= n_bytes
)
549 n_bytes
-= (size_t) frames
* u
->frame_size
;
553 *sleep_usec
= pa_bytes_to_usec(left_to_play
, &u
->sink
->sample_spec
);
555 if (*sleep_usec
> process_usec
)
556 *sleep_usec
-= process_usec
;
560 return work_done
? 1 : 0;
563 static int unix_write(struct userdata
*u
, pa_usec_t
*sleep_usec
, pa_bool_t polled
) {
564 pa_bool_t work_done
= FALSE
;
565 pa_usec_t max_sleep_usec
= 0, process_usec
= 0;
570 pa_sink_assert_ref(u
->sink
);
573 hw_sleep_time(u
, &max_sleep_usec
, &process_usec
);
580 if (PA_UNLIKELY((n
= pa_alsa_safe_avail(u
->pcm_handle
, u
->hwbuf_size
, &u
->sink
->sample_spec
)) < 0)) {
582 if ((r
= try_recover(u
, "snd_pcm_avail", (int) n
)) == 0)
588 n_bytes
= (size_t) n
* u
->frame_size
;
589 left_to_play
= check_left_to_play(u
, n_bytes
);
593 /* We won't fill up the playback buffer before at least
594 * half the sleep time is over because otherwise we might
595 * ask for more data from the clients then they expect. We
596 * need to guarantee that clients only have to keep around
597 * a single hw buffer length. */
600 pa_bytes_to_usec(left_to_play
, &u
->sink
->sample_spec
) > process_usec
+max_sleep_usec
/2)
603 if (PA_UNLIKELY(n_bytes
<= u
->hwbuf_unused
)) {
607 char *dn
= pa_alsa_get_driver_name_by_pcm(u
->pcm_handle
);
608 pa_log(_("ALSA woke us up to write new data to the device, but there was actually nothing to write!\n"
609 "Most likely this is a bug in the ALSA driver '%s'. Please report this issue to the ALSA developers.\n"
610 "We were woken up with POLLOUT set -- however a subsequent snd_pcm_avail() returned 0 or another value < min_avail."),
620 pa_log_debug("Not filling up, because already too many iterations.");
626 n_bytes
-= u
->hwbuf_unused
;
630 snd_pcm_sframes_t frames
;
632 pa_bool_t after_avail
= TRUE
;
634 /* pa_log_debug("%lu frames to write", (unsigned long) frames); */
636 if (u
->memchunk
.length
<= 0)
637 pa_sink_render(u
->sink
, n_bytes
, &u
->memchunk
);
639 pa_assert(u
->memchunk
.length
> 0);
641 frames
= (snd_pcm_sframes_t
) (u
->memchunk
.length
/ u
->frame_size
);
643 if (frames
> (snd_pcm_sframes_t
) (n_bytes
/u
->frame_size
))
644 frames
= (snd_pcm_sframes_t
) (n_bytes
/u
->frame_size
);
646 p
= pa_memblock_acquire(u
->memchunk
.memblock
);
647 frames
= snd_pcm_writei(u
->pcm_handle
, (const uint8_t*) p
+ u
->memchunk
.index
, (snd_pcm_uframes_t
) frames
);
648 pa_memblock_release(u
->memchunk
.memblock
);
650 if (PA_UNLIKELY(frames
< 0)) {
652 if (!after_avail
&& (int) frames
== -EAGAIN
)
655 if ((r
= try_recover(u
, "snd_pcm_writei", (int) frames
)) == 0)
661 if (!after_avail
&& frames
== 0)
664 pa_assert(frames
> 0);
667 u
->memchunk
.index
+= (size_t) frames
* u
->frame_size
;
668 u
->memchunk
.length
-= (size_t) frames
* u
->frame_size
;
670 if (u
->memchunk
.length
<= 0) {
671 pa_memblock_unref(u
->memchunk
.memblock
);
672 pa_memchunk_reset(&u
->memchunk
);
677 u
->write_count
+= frames
* u
->frame_size
;
678 u
->since_start
+= frames
* u
->frame_size
;
680 /* pa_log_debug("wrote %lu frames", (unsigned long) frames); */
682 if ((size_t) frames
* u
->frame_size
>= n_bytes
)
685 n_bytes
-= (size_t) frames
* u
->frame_size
;
689 *sleep_usec
= pa_bytes_to_usec(left_to_play
, &u
->sink
->sample_spec
);
691 if (*sleep_usec
> process_usec
)
692 *sleep_usec
-= process_usec
;
696 return work_done
? 1 : 0;
699 static void update_smoother(struct userdata
*u
) {
700 snd_pcm_sframes_t delay
= 0;
703 pa_usec_t now1
= 0, now2
;
704 snd_pcm_status_t
*status
;
706 snd_pcm_status_alloca(&status
);
709 pa_assert(u
->pcm_handle
);
711 /* Let's update the time smoother */
713 if (PA_UNLIKELY((err
= pa_alsa_safe_delay(u
->pcm_handle
, &delay
, u
->hwbuf_size
, &u
->sink
->sample_spec
)) < 0)) {
714 pa_log_warn("Failed to query DSP status data: %s", pa_alsa_strerror(err
));
718 if (PA_UNLIKELY((err
= snd_pcm_status(u
->pcm_handle
, status
)) < 0))
719 pa_log_warn("Failed to get timestamp: %s", pa_alsa_strerror(err
));
721 snd_htimestamp_t htstamp
= { 0, 0 };
722 snd_pcm_status_get_htstamp(status
, &htstamp
);
723 now1
= pa_timespec_load(&htstamp
);
726 position
= (int64_t) u
->write_count
- ((int64_t) delay
* (int64_t) u
->frame_size
);
728 if (PA_UNLIKELY(position
< 0))
731 /* Hmm, if the timestamp is 0, then it wasn't set and we take the current time */
733 now1
= pa_rtclock_now();
735 now2
= pa_bytes_to_usec((uint64_t) position
, &u
->sink
->sample_spec
);
737 pa_smoother_put(u
->smoother
, now1
, now2
);
740 static pa_usec_t
sink_get_latency(struct userdata
*u
) {
743 pa_usec_t now1
, now2
;
747 now1
= pa_rtclock_now();
748 now2
= pa_smoother_get(u
->smoother
, now1
);
750 delay
= (int64_t) pa_bytes_to_usec(u
->write_count
, &u
->sink
->sample_spec
) - (int64_t) now2
;
752 r
= delay
>= 0 ? (pa_usec_t
) delay
: 0;
754 if (u
->memchunk
.memblock
)
755 r
+= pa_bytes_to_usec(u
->memchunk
.length
, &u
->sink
->sample_spec
);
760 static int build_pollfd(struct userdata
*u
) {
762 pa_assert(u
->pcm_handle
);
764 if (u
->alsa_rtpoll_item
)
765 pa_rtpoll_item_free(u
->alsa_rtpoll_item
);
767 if (!(u
->alsa_rtpoll_item
= pa_alsa_build_pollfd(u
->pcm_handle
, u
->rtpoll
)))
773 /* Called from IO context */
774 static int suspend(struct userdata
*u
) {
776 pa_assert(u
->pcm_handle
);
778 pa_smoother_pause(u
->smoother
, pa_rtclock_now());
780 /* Let's suspend -- we don't call snd_pcm_drain() here since that might
781 * take awfully long with our long buffer sizes today. */
782 snd_pcm_close(u
->pcm_handle
);
783 u
->pcm_handle
= NULL
;
785 if (u
->alsa_rtpoll_item
) {
786 pa_rtpoll_item_free(u
->alsa_rtpoll_item
);
787 u
->alsa_rtpoll_item
= NULL
;
790 pa_log_info("Device suspended...");
795 /* Called from IO context */
796 static int update_sw_params(struct userdata
*u
) {
797 snd_pcm_uframes_t avail_min
;
802 /* Use the full buffer if noone asked us for anything specific */
808 if ((latency
= pa_sink_get_requested_latency_within_thread(u
->sink
)) != (pa_usec_t
) -1) {
811 pa_log_debug("Latency set to %0.2fms", (double) latency
/ PA_USEC_PER_MSEC
);
813 b
= pa_usec_to_bytes(latency
, &u
->sink
->sample_spec
);
815 /* We need at least one sample in our buffer */
817 if (PA_UNLIKELY(b
< u
->frame_size
))
820 u
->hwbuf_unused
= PA_LIKELY(b
< u
->hwbuf_size
) ? (u
->hwbuf_size
- b
) : 0;
823 fix_min_sleep_wakeup(u
);
824 fix_tsched_watermark(u
);
827 pa_log_debug("hwbuf_unused=%lu", (unsigned long) u
->hwbuf_unused
);
829 /* We need at last one frame in the used part of the buffer */
830 avail_min
= (snd_pcm_uframes_t
) u
->hwbuf_unused
/ u
->frame_size
+ 1;
833 pa_usec_t sleep_usec
, process_usec
;
835 hw_sleep_time(u
, &sleep_usec
, &process_usec
);
836 avail_min
+= pa_usec_to_bytes(sleep_usec
, &u
->sink
->sample_spec
) / u
->frame_size
;
839 pa_log_debug("setting avail_min=%lu", (unsigned long) avail_min
);
841 if ((err
= pa_alsa_set_sw_params(u
->pcm_handle
, avail_min
)) < 0) {
842 pa_log("Failed to set software parameters: %s", pa_alsa_strerror(err
));
846 pa_sink_set_max_request_within_thread(u
->sink
, u
->hwbuf_size
- u
->hwbuf_unused
);
851 /* Called from IO context */
852 static int unsuspend(struct userdata
*u
) {
857 snd_pcm_uframes_t period_size
;
860 pa_assert(!u
->pcm_handle
);
862 pa_log_info("Trying resume...");
864 if ((err
= snd_pcm_open(&u
->pcm_handle
, u
->device_name
, SND_PCM_STREAM_PLAYBACK
,
865 /*SND_PCM_NONBLOCK|*/
866 SND_PCM_NO_AUTO_RESAMPLE
|
867 SND_PCM_NO_AUTO_CHANNELS
|
868 SND_PCM_NO_AUTO_FORMAT
)) < 0) {
869 pa_log("Error opening PCM device %s: %s", u
->device_name
, pa_alsa_strerror(err
));
873 ss
= u
->sink
->sample_spec
;
874 nfrags
= u
->nfragments
;
875 period_size
= u
->fragment_size
/ u
->frame_size
;
879 if ((err
= pa_alsa_set_hw_params(u
->pcm_handle
, &ss
, &nfrags
, &period_size
, u
->hwbuf_size
/ u
->frame_size
, &b
, &d
, TRUE
)) < 0) {
880 pa_log("Failed to set hardware parameters: %s", pa_alsa_strerror(err
));
884 if (b
!= u
->use_mmap
|| d
!= u
->use_tsched
) {
885 pa_log_warn("Resume failed, couldn't get original access mode.");
889 if (!pa_sample_spec_equal(&ss
, &u
->sink
->sample_spec
)) {
890 pa_log_warn("Resume failed, couldn't restore original sample settings.");
894 if (nfrags
!= u
->nfragments
|| period_size
*u
->frame_size
!= u
->fragment_size
) {
895 pa_log_warn("Resume failed, couldn't restore original fragment settings. (Old: %lu*%lu, New %lu*%lu)",
896 (unsigned long) u
->nfragments
, (unsigned long) u
->fragment_size
,
897 (unsigned long) nfrags
, period_size
* u
->frame_size
);
901 if (update_sw_params(u
) < 0)
904 if (build_pollfd(u
) < 0)
908 pa_smoother_reset(u
->smoother
, pa_rtclock_now(), TRUE
);
914 pa_log_info("Resumed successfully...");
920 snd_pcm_close(u
->pcm_handle
);
921 u
->pcm_handle
= NULL
;
927 /* Called from IO context */
928 static int sink_process_msg(pa_msgobject
*o
, int code
, void *data
, int64_t offset
, pa_memchunk
*chunk
) {
929 struct userdata
*u
= PA_SINK(o
)->userdata
;
933 case PA_SINK_MESSAGE_GET_LATENCY
: {
937 r
= sink_get_latency(u
);
939 *((pa_usec_t
*) data
) = r
;
944 case PA_SINK_MESSAGE_SET_STATE
:
946 switch ((pa_sink_state_t
) PA_PTR_TO_UINT(data
)) {
948 case PA_SINK_SUSPENDED
:
949 pa_assert(PA_SINK_IS_OPENED(u
->sink
->thread_info
.state
));
957 case PA_SINK_RUNNING
:
959 if (u
->sink
->thread_info
.state
== PA_SINK_INIT
) {
960 if (build_pollfd(u
) < 0)
964 if (u
->sink
->thread_info
.state
== PA_SINK_SUSPENDED
) {
965 if (unsuspend(u
) < 0)
971 case PA_SINK_UNLINKED
:
973 case PA_SINK_INVALID_STATE
:
980 return pa_sink_process_msg(o
, code
, data
, offset
, chunk
);
983 /* Called from main context */
984 static int sink_set_state_cb(pa_sink
*s
, pa_sink_state_t new_state
) {
985 pa_sink_state_t old_state
;
988 pa_sink_assert_ref(s
);
989 pa_assert_se(u
= s
->userdata
);
991 old_state
= pa_sink_get_state(u
->sink
);
993 if (PA_SINK_IS_OPENED(old_state
) && new_state
== PA_SINK_SUSPENDED
)
995 else if (old_state
== PA_SINK_SUSPENDED
&& PA_SINK_IS_OPENED(new_state
))
996 if (reserve_init(u
, u
->device_name
) < 0)
1002 static int mixer_callback(snd_mixer_elem_t
*elem
, unsigned int mask
) {
1003 struct userdata
*u
= snd_mixer_elem_get_callback_private(elem
);
1006 pa_assert(u
->mixer_handle
);
1008 if (mask
== SND_CTL_EVENT_MASK_REMOVE
)
1011 if (mask
& SND_CTL_EVENT_MASK_VALUE
) {
1012 pa_sink_get_volume(u
->sink
, TRUE
);
1013 pa_sink_get_mute(u
->sink
, TRUE
);
1019 static void sink_get_volume_cb(pa_sink
*s
) {
1020 struct userdata
*u
= s
->userdata
;
1022 char t
[PA_CVOLUME_SNPRINT_MAX
];
1025 pa_assert(u
->mixer_path
);
1026 pa_assert(u
->mixer_handle
);
1028 if (pa_alsa_path_get_volume(u
->mixer_path
, u
->mixer_handle
, &s
->channel_map
, &r
) < 0)
1031 /* Shift down by the base volume, so that 0dB becomes maximum volume */
1032 pa_sw_cvolume_multiply_scalar(&r
, &r
, s
->base_volume
);
1034 pa_log_debug("Read hardware volume: %s", pa_cvolume_snprint(t
, sizeof(t
), &r
));
1036 if (pa_cvolume_equal(&u
->hardware_volume
, &r
))
1039 s
->real_volume
= u
->hardware_volume
= r
;
1041 /* Hmm, so the hardware volume changed, let's reset our software volume */
1042 if (u
->mixer_path
->has_dB
)
1043 pa_sink_set_soft_volume(s
, NULL
);
1046 static void sink_set_volume_cb(pa_sink
*s
) {
1047 struct userdata
*u
= s
->userdata
;
1049 char t
[PA_CVOLUME_SNPRINT_MAX
];
1052 pa_assert(u
->mixer_path
);
1053 pa_assert(u
->mixer_handle
);
1055 /* Shift up by the base volume */
1056 pa_sw_cvolume_divide_scalar(&r
, &s
->real_volume
, s
->base_volume
);
1058 if (pa_alsa_path_set_volume(u
->mixer_path
, u
->mixer_handle
, &s
->channel_map
, &r
) < 0)
1061 /* Shift down by the base volume, so that 0dB becomes maximum volume */
1062 pa_sw_cvolume_multiply_scalar(&r
, &r
, s
->base_volume
);
1064 u
->hardware_volume
= r
;
1066 if (u
->mixer_path
->has_dB
) {
1067 pa_cvolume new_soft_volume
;
1068 pa_bool_t accurate_enough
;
1070 /* Match exactly what the user requested by software */
1071 pa_sw_cvolume_divide(&new_soft_volume
, &s
->real_volume
, &u
->hardware_volume
);
1073 /* If the adjustment to do in software is only minimal we
1074 * can skip it. That saves us CPU at the expense of a bit of
1077 (pa_cvolume_min(&new_soft_volume
) >= (PA_VOLUME_NORM
- VOLUME_ACCURACY
)) &&
1078 (pa_cvolume_max(&new_soft_volume
) <= (PA_VOLUME_NORM
+ VOLUME_ACCURACY
));
1080 pa_log_debug("Requested volume: %s", pa_cvolume_snprint(t
, sizeof(t
), &s
->real_volume
));
1081 pa_log_debug("Got hardware volume: %s", pa_cvolume_snprint(t
, sizeof(t
), &u
->hardware_volume
));
1082 pa_log_debug("Calculated software volume: %s (accurate-enough=%s)", pa_cvolume_snprint(t
, sizeof(t
), &new_soft_volume
),
1083 pa_yes_no(accurate_enough
));
1085 if (!accurate_enough
)
1086 s
->soft_volume
= new_soft_volume
;
1089 pa_log_debug("Wrote hardware volume: %s", pa_cvolume_snprint(t
, sizeof(t
), &r
));
1091 /* We can't match exactly what the user requested, hence let's
1092 * at least tell the user about it */
1098 static void sink_get_mute_cb(pa_sink
*s
) {
1099 struct userdata
*u
= s
->userdata
;
1103 pa_assert(u
->mixer_path
);
1104 pa_assert(u
->mixer_handle
);
1106 if (pa_alsa_path_get_mute(u
->mixer_path
, u
->mixer_handle
, &b
) < 0)
1112 static void sink_set_mute_cb(pa_sink
*s
) {
1113 struct userdata
*u
= s
->userdata
;
1116 pa_assert(u
->mixer_path
);
1117 pa_assert(u
->mixer_handle
);
1119 pa_alsa_path_set_mute(u
->mixer_path
, u
->mixer_handle
, s
->muted
);
1122 static int sink_set_port_cb(pa_sink
*s
, pa_device_port
*p
) {
1123 struct userdata
*u
= s
->userdata
;
1124 pa_alsa_port_data
*data
;
1128 pa_assert(u
->mixer_handle
);
1130 data
= PA_DEVICE_PORT_DATA(p
);
1132 pa_assert_se(u
->mixer_path
= data
->path
);
1133 pa_alsa_path_select(u
->mixer_path
, u
->mixer_handle
);
1135 if (u
->mixer_path
->has_volume
&& u
->mixer_path
->has_dB
) {
1136 s
->base_volume
= pa_sw_volume_from_dB(-u
->mixer_path
->max_dB
);
1137 s
->n_volume_steps
= PA_VOLUME_NORM
+1;
1139 if (u
->mixer_path
->max_dB
> 0.0)
1140 pa_log_info("Fixing base volume to %0.2f dB", pa_sw_volume_to_dB(s
->base_volume
));
1142 pa_log_info("No particular base volume set, fixing to 0 dB");
1144 s
->base_volume
= PA_VOLUME_NORM
;
1145 s
->n_volume_steps
= u
->mixer_path
->max_volume
- u
->mixer_path
->min_volume
+ 1;
1149 pa_alsa_setting_select(data
->setting
, u
->mixer_handle
);
1159 static void sink_update_requested_latency_cb(pa_sink
*s
) {
1160 struct userdata
*u
= s
->userdata
;
1167 before
= u
->hwbuf_unused
;
1168 update_sw_params(u
);
1170 /* Let's check whether we now use only a smaller part of the
1171 buffer then before. If so, we need to make sure that subsequent
1172 rewinds are relative to the new maximum fill level and not to the
1173 current fill level. Thus, let's do a full rewind once, to clear
1176 if (u
->hwbuf_unused
> before
) {
1177 pa_log_debug("Requesting rewind due to latency change.");
1178 pa_sink_request_rewind(s
, (size_t) -1);
1182 static int process_rewind(struct userdata
*u
) {
1183 snd_pcm_sframes_t unused
;
1184 size_t rewind_nbytes
, unused_nbytes
, limit_nbytes
;
1187 /* Figure out how much we shall rewind and reset the counter */
1188 rewind_nbytes
= u
->sink
->thread_info
.rewind_nbytes
;
1190 pa_log_debug("Requested to rewind %lu bytes.", (unsigned long) rewind_nbytes
);
1192 if (PA_UNLIKELY((unused
= pa_alsa_safe_avail(u
->pcm_handle
, u
->hwbuf_size
, &u
->sink
->sample_spec
)) < 0)) {
1193 pa_log("snd_pcm_avail() failed: %s", pa_alsa_strerror((int) unused
));
1197 unused_nbytes
= u
->tsched_watermark
+ (size_t) unused
* u
->frame_size
;
1199 if (u
->hwbuf_size
> unused_nbytes
)
1200 limit_nbytes
= u
->hwbuf_size
- unused_nbytes
;
1204 if (rewind_nbytes
> limit_nbytes
)
1205 rewind_nbytes
= limit_nbytes
;
1207 if (rewind_nbytes
> 0) {
1208 snd_pcm_sframes_t in_frames
, out_frames
;
1210 pa_log_debug("Limited to %lu bytes.", (unsigned long) rewind_nbytes
);
1212 in_frames
= (snd_pcm_sframes_t
) (rewind_nbytes
/ u
->frame_size
);
1213 pa_log_debug("before: %lu", (unsigned long) in_frames
);
1214 if ((out_frames
= snd_pcm_rewind(u
->pcm_handle
, (snd_pcm_uframes_t
) in_frames
)) < 0) {
1215 pa_log("snd_pcm_rewind() failed: %s", pa_alsa_strerror((int) out_frames
));
1216 if (try_recover(u
, "process_rewind", out_frames
) < 0)
1221 pa_log_debug("after: %lu", (unsigned long) out_frames
);
1223 rewind_nbytes
= (size_t) out_frames
* u
->frame_size
;
1225 if (rewind_nbytes
<= 0)
1226 pa_log_info("Tried rewind, but was apparently not possible.");
1228 u
->write_count
-= rewind_nbytes
;
1229 pa_log_debug("Rewound %lu bytes.", (unsigned long) rewind_nbytes
);
1230 pa_sink_process_rewind(u
->sink
, rewind_nbytes
);
1232 u
->after_rewind
= TRUE
;
1236 pa_log_debug("Mhmm, actually there is nothing to rewind.");
1238 pa_sink_process_rewind(u
->sink
, 0);
1242 static void thread_func(void *userdata
) {
1243 struct userdata
*u
= userdata
;
1244 unsigned short revents
= 0;
1248 pa_log_debug("Thread starting up");
1250 if (u
->core
->realtime_scheduling
)
1251 pa_make_realtime(u
->core
->realtime_priority
);
1253 pa_thread_mq_install(&u
->thread_mq
);
1259 pa_log_debug("Loop");
1262 /* Render some data and write it to the dsp */
1263 if (PA_SINK_IS_OPENED(u
->sink
->thread_info
.state
)) {
1265 pa_usec_t sleep_usec
= 0;
1267 if (PA_UNLIKELY(u
->sink
->thread_info
.rewind_requested
))
1268 if (process_rewind(u
) < 0)
1272 work_done
= mmap_write(u
, &sleep_usec
, revents
& POLLOUT
);
1274 work_done
= unix_write(u
, &sleep_usec
, revents
& POLLOUT
);
1279 /* pa_log_debug("work_done = %i", work_done); */
1284 pa_log_info("Starting playback.");
1285 snd_pcm_start(u
->pcm_handle
);
1287 pa_smoother_resume(u
->smoother
, pa_rtclock_now(), TRUE
);
1293 if (u
->use_tsched
) {
1296 if (u
->since_start
<= u
->hwbuf_size
) {
1298 /* USB devices on ALSA seem to hit a buffer
1299 * underrun during the first iterations much
1300 * quicker then we calculate here, probably due to
1301 * the transport latency. To accommodate for that
1302 * we artificially decrease the sleep time until
1303 * we have filled the buffer at least once
1306 if (pa_log_ratelimit())
1307 pa_log_debug("Cutting sleep time for the initial iterations by half.");
1311 /* OK, the playback buffer is now full, let's
1312 * calculate when to wake up next */
1313 /* pa_log_debug("Waking up in %0.2fms (sound card clock).", (double) sleep_usec / PA_USEC_PER_MSEC); */
1315 /* Convert from the sound card time domain to the
1316 * system time domain */
1317 cusec
= pa_smoother_translate(u
->smoother
, pa_rtclock_now(), sleep_usec
);
1319 /* pa_log_debug("Waking up in %0.2fms (system clock).", (double) cusec / PA_USEC_PER_MSEC); */
1321 /* We don't trust the conversion, so we wake up whatever comes first */
1322 pa_rtpoll_set_timer_relative(u
->rtpoll
, PA_MIN(sleep_usec
, cusec
));
1326 u
->after_rewind
= FALSE
;
1328 } else if (u
->use_tsched
)
1330 /* OK, we're in an invalid state, let's disable our timers */
1331 pa_rtpoll_set_timer_disabled(u
->rtpoll
);
1333 /* Hmm, nothing to do. Let's sleep */
1334 if ((ret
= pa_rtpoll_run(u
->rtpoll
, TRUE
)) < 0)
1340 /* Tell ALSA about this and process its response */
1341 if (PA_SINK_IS_OPENED(u
->sink
->thread_info
.state
)) {
1342 struct pollfd
*pollfd
;
1346 pollfd
= pa_rtpoll_item_get_pollfd(u
->alsa_rtpoll_item
, &n
);
1348 if ((err
= snd_pcm_poll_descriptors_revents(u
->pcm_handle
, pollfd
, n
, &revents
)) < 0) {
1349 pa_log("snd_pcm_poll_descriptors_revents() failed: %s", pa_alsa_strerror(err
));
1353 if (revents
& ~POLLOUT
) {
1354 if (pa_alsa_recover_from_poll(u
->pcm_handle
, revents
) < 0)
1359 } else if (revents
&& u
->use_tsched
&& pa_log_ratelimit())
1360 pa_log_debug("Wakeup from ALSA!");
1367 /* If this was no regular exit from the loop we have to continue
1368 * processing messages until we received PA_MESSAGE_SHUTDOWN */
1369 pa_asyncmsgq_post(u
->thread_mq
.outq
, PA_MSGOBJECT(u
->core
), PA_CORE_MESSAGE_UNLOAD_MODULE
, u
->module
, 0, NULL
, NULL
);
1370 pa_asyncmsgq_wait_for(u
->thread_mq
.inq
, PA_MESSAGE_SHUTDOWN
);
1373 pa_log_debug("Thread shutting down");
1376 static void set_sink_name(pa_sink_new_data
*data
, pa_modargs
*ma
, const char *device_id
, const char *device_name
, pa_alsa_mapping
*mapping
) {
1382 pa_assert(device_name
);
1384 if ((n
= pa_modargs_get_value(ma
, "sink_name", NULL
))) {
1385 pa_sink_new_data_set_name(data
, n
);
1386 data
->namereg_fail
= TRUE
;
1390 if ((n
= pa_modargs_get_value(ma
, "name", NULL
)))
1391 data
->namereg_fail
= TRUE
;
1393 n
= device_id
? device_id
: device_name
;
1394 data
->namereg_fail
= FALSE
;
1398 t
= pa_sprintf_malloc("alsa_output.%s.%s", n
, mapping
->name
);
1400 t
= pa_sprintf_malloc("alsa_output.%s", n
);
1402 pa_sink_new_data_set_name(data
, t
);
1406 static void find_mixer(struct userdata
*u
, pa_alsa_mapping
*mapping
, const char *element
, pa_bool_t ignore_dB
) {
1408 if (!mapping
&& !element
)
1411 if (!(u
->mixer_handle
= pa_alsa_open_mixer_for_pcm(u
->pcm_handle
, &u
->control_device
))) {
1412 pa_log_info("Failed to find a working mixer device.");
1418 if (!(u
->mixer_path
= pa_alsa_path_synthesize(element
, PA_ALSA_DIRECTION_OUTPUT
)))
1421 if (pa_alsa_path_probe(u
->mixer_path
, u
->mixer_handle
, ignore_dB
) < 0)
1424 pa_log_debug("Probed mixer path %s:", u
->mixer_path
->name
);
1425 pa_alsa_path_dump(u
->mixer_path
);
1428 if (!(u
->mixer_path_set
= pa_alsa_path_set_new(mapping
, PA_ALSA_DIRECTION_OUTPUT
)))
1431 pa_alsa_path_set_probe(u
->mixer_path_set
, u
->mixer_handle
, ignore_dB
);
1433 pa_log_debug("Probed mixer paths:");
1434 pa_alsa_path_set_dump(u
->mixer_path_set
);
1441 if (u
->mixer_path_set
) {
1442 pa_alsa_path_set_free(u
->mixer_path_set
);
1443 u
->mixer_path_set
= NULL
;
1444 } else if (u
->mixer_path
) {
1445 pa_alsa_path_free(u
->mixer_path
);
1446 u
->mixer_path
= NULL
;
1449 if (u
->mixer_handle
) {
1450 snd_mixer_close(u
->mixer_handle
);
1451 u
->mixer_handle
= NULL
;
1455 static int setup_mixer(struct userdata
*u
, pa_bool_t ignore_dB
) {
1458 if (!u
->mixer_handle
)
1461 if (u
->sink
->active_port
) {
1462 pa_alsa_port_data
*data
;
1464 /* We have a list of supported paths, so let's activate the
1465 * one that has been chosen as active */
1467 data
= PA_DEVICE_PORT_DATA(u
->sink
->active_port
);
1468 u
->mixer_path
= data
->path
;
1470 pa_alsa_path_select(data
->path
, u
->mixer_handle
);
1473 pa_alsa_setting_select(data
->setting
, u
->mixer_handle
);
1477 if (!u
->mixer_path
&& u
->mixer_path_set
)
1478 u
->mixer_path
= u
->mixer_path_set
->paths
;
1480 if (u
->mixer_path
) {
1481 /* Hmm, we have only a single path, then let's activate it */
1483 pa_alsa_path_select(u
->mixer_path
, u
->mixer_handle
);
1485 if (u
->mixer_path
->settings
)
1486 pa_alsa_setting_select(u
->mixer_path
->settings
, u
->mixer_handle
);
1491 if (!u
->mixer_path
->has_volume
)
1492 pa_log_info("Driver does not support hardware volume control, falling back to software volume control.");
1495 if (u
->mixer_path
->has_dB
) {
1496 pa_log_info("Hardware volume ranges from %0.2f dB to %0.2f dB.", u
->mixer_path
->min_dB
, u
->mixer_path
->max_dB
);
1498 u
->sink
->base_volume
= pa_sw_volume_from_dB(-u
->mixer_path
->max_dB
);
1499 u
->sink
->n_volume_steps
= PA_VOLUME_NORM
+1;
1501 if (u
->mixer_path
->max_dB
> 0.0)
1502 pa_log_info("Fixing base volume to %0.2f dB", pa_sw_volume_to_dB(u
->sink
->base_volume
));
1504 pa_log_info("No particular base volume set, fixing to 0 dB");
1507 pa_log_info("Hardware volume ranges from %li to %li.", u
->mixer_path
->min_volume
, u
->mixer_path
->max_volume
);
1508 u
->sink
->base_volume
= PA_VOLUME_NORM
;
1509 u
->sink
->n_volume_steps
= u
->mixer_path
->max_volume
- u
->mixer_path
->min_volume
+ 1;
1512 u
->sink
->get_volume
= sink_get_volume_cb
;
1513 u
->sink
->set_volume
= sink_set_volume_cb
;
1515 u
->sink
->flags
|= PA_SINK_HW_VOLUME_CTRL
| (u
->mixer_path
->has_dB
? PA_SINK_DECIBEL_VOLUME
: 0);
1516 pa_log_info("Using hardware volume control. Hardware dB scale %s.", u
->mixer_path
->has_dB
? "supported" : "not supported");
1519 if (!u
->mixer_path
->has_mute
) {
1520 pa_log_info("Driver does not support hardware mute control, falling back to software mute control.");
1522 u
->sink
->get_mute
= sink_get_mute_cb
;
1523 u
->sink
->set_mute
= sink_set_mute_cb
;
1524 u
->sink
->flags
|= PA_SINK_HW_MUTE_CTRL
;
1525 pa_log_info("Using hardware mute control.");
1528 u
->mixer_fdl
= pa_alsa_fdlist_new();
1530 if (pa_alsa_fdlist_set_mixer(u
->mixer_fdl
, u
->mixer_handle
, u
->core
->mainloop
) < 0) {
1531 pa_log("Failed to initialize file descriptor monitoring");
1535 if (u
->mixer_path_set
)
1536 pa_alsa_path_set_set_callback(u
->mixer_path_set
, u
->mixer_handle
, mixer_callback
, u
);
1538 pa_alsa_path_set_callback(u
->mixer_path
, u
->mixer_handle
, mixer_callback
, u
);
1543 pa_sink
*pa_alsa_sink_new(pa_module
*m
, pa_modargs
*ma
, const char*driver
, pa_card
*card
, pa_alsa_mapping
*mapping
) {
1545 struct userdata
*u
= NULL
;
1546 const char *dev_id
= NULL
;
1547 pa_sample_spec ss
, requested_ss
;
1549 uint32_t nfrags
, hwbuf_size
, frag_size
, tsched_size
, tsched_watermark
;
1550 snd_pcm_uframes_t period_frames
, tsched_frames
;
1552 pa_bool_t use_mmap
= TRUE
, b
, use_tsched
= TRUE
, d
, ignore_dB
= FALSE
;
1553 pa_sink_new_data data
;
1554 pa_alsa_profile_set
*profile_set
= NULL
;
1559 ss
= m
->core
->default_sample_spec
;
1560 map
= m
->core
->default_channel_map
;
1561 if (pa_modargs_get_sample_spec_and_channel_map(ma
, &ss
, &map
, PA_CHANNEL_MAP_ALSA
) < 0) {
1562 pa_log("Failed to parse sample specification and channel map");
1567 frame_size
= pa_frame_size(&ss
);
1569 nfrags
= m
->core
->default_n_fragments
;
1570 frag_size
= (uint32_t) pa_usec_to_bytes(m
->core
->default_fragment_size_msec
*PA_USEC_PER_MSEC
, &ss
);
1572 frag_size
= (uint32_t) frame_size
;
1573 tsched_size
= (uint32_t) pa_usec_to_bytes(DEFAULT_TSCHED_BUFFER_USEC
, &ss
);
1574 tsched_watermark
= (uint32_t) pa_usec_to_bytes(DEFAULT_TSCHED_WATERMARK_USEC
, &ss
);
1576 if (pa_modargs_get_value_u32(ma
, "fragments", &nfrags
) < 0 ||
1577 pa_modargs_get_value_u32(ma
, "fragment_size", &frag_size
) < 0 ||
1578 pa_modargs_get_value_u32(ma
, "tsched_buffer_size", &tsched_size
) < 0 ||
1579 pa_modargs_get_value_u32(ma
, "tsched_buffer_watermark", &tsched_watermark
) < 0) {
1580 pa_log("Failed to parse buffer metrics");
1584 hwbuf_size
= frag_size
* nfrags
;
1585 period_frames
= frag_size
/frame_size
;
1586 tsched_frames
= tsched_size
/frame_size
;
1588 if (pa_modargs_get_value_boolean(ma
, "mmap", &use_mmap
) < 0) {
1589 pa_log("Failed to parse mmap argument.");
1593 if (pa_modargs_get_value_boolean(ma
, "tsched", &use_tsched
) < 0) {
1594 pa_log("Failed to parse tsched argument.");
1598 if (pa_modargs_get_value_boolean(ma
, "ignore_dB", &ignore_dB
) < 0) {
1599 pa_log("Failed to parse ignore_dB argument.");
1603 if (use_tsched
&& !pa_rtclock_hrtimer()) {
1604 pa_log_notice("Disabling timer-based scheduling because high-resolution timers are not available from the kernel.");
1608 u
= pa_xnew0(struct userdata
, 1);
1611 u
->use_mmap
= use_mmap
;
1612 u
->use_tsched
= use_tsched
;
1614 u
->rtpoll
= pa_rtpoll_new();
1615 pa_thread_mq_init(&u
->thread_mq
, m
->core
->mainloop
, u
->rtpoll
);
1617 u
->smoother
= pa_smoother_new(
1618 DEFAULT_TSCHED_BUFFER_USEC
*2,
1619 DEFAULT_TSCHED_BUFFER_USEC
*2,
1626 dev_id
= pa_modargs_get_value(
1628 pa_modargs_get_value(ma
, "device", DEFAULT_DEVICE
));
1630 if (reserve_init(u
, dev_id
) < 0)
1633 if (reserve_monitor_init(u
, dev_id
) < 0)
1641 if (!(dev_id
= pa_modargs_get_value(ma
, "device_id", NULL
))) {
1642 pa_log("device_id= not set");
1646 if (!(u
->pcm_handle
= pa_alsa_open_by_device_id_mapping(
1650 SND_PCM_STREAM_PLAYBACK
,
1651 &nfrags
, &period_frames
, tsched_frames
,
1656 } else if ((dev_id
= pa_modargs_get_value(ma
, "device_id", NULL
))) {
1658 if (!(profile_set
= pa_alsa_profile_set_new(NULL
, &map
)))
1661 if (!(u
->pcm_handle
= pa_alsa_open_by_device_id_auto(
1665 SND_PCM_STREAM_PLAYBACK
,
1666 &nfrags
, &period_frames
, tsched_frames
,
1667 &b
, &d
, profile_set
, &mapping
)))
1673 if (!(u
->pcm_handle
= pa_alsa_open_by_device_string(
1674 pa_modargs_get_value(ma
, "device", DEFAULT_DEVICE
),
1677 SND_PCM_STREAM_PLAYBACK
,
1678 &nfrags
, &period_frames
, tsched_frames
,
1683 pa_assert(u
->device_name
);
1684 pa_log_info("Successfully opened device %s.", u
->device_name
);
1686 if (pa_alsa_pcm_is_modem(u
->pcm_handle
)) {
1687 pa_log_notice("Device %s is modem, refusing further initialization.", u
->device_name
);
1692 pa_log_info("Selected mapping '%s' (%s).", mapping
->description
, mapping
->name
);
1694 if (use_mmap
&& !b
) {
1695 pa_log_info("Device doesn't support mmap(), falling back to UNIX read/write mode.");
1696 u
->use_mmap
= use_mmap
= FALSE
;
1699 if (use_tsched
&& (!b
|| !d
)) {
1700 pa_log_info("Cannot enable timer-based scheduling, falling back to sound IRQ scheduling.");
1701 u
->use_tsched
= use_tsched
= FALSE
;
1704 if (use_tsched
&& !pa_alsa_pcm_is_hw(u
->pcm_handle
)) {
1705 pa_log_info("Device is not a hardware device, disabling timer-based scheduling.");
1706 u
->use_tsched
= use_tsched
= FALSE
;
1710 pa_log_info("Successfully enabled mmap() mode.");
1713 pa_log_info("Successfully enabled timer-based scheduling mode.");
1715 /* ALSA might tweak the sample spec, so recalculate the frame size */
1716 frame_size
= pa_frame_size(&ss
);
1718 find_mixer(u
, mapping
, pa_modargs_get_value(ma
, "control", NULL
), ignore_dB
);
1720 pa_sink_new_data_init(&data
);
1721 data
.driver
= driver
;
1724 set_sink_name(&data
, ma
, dev_id
, u
->device_name
, mapping
);
1725 pa_sink_new_data_set_sample_spec(&data
, &ss
);
1726 pa_sink_new_data_set_channel_map(&data
, &map
);
1728 pa_alsa_init_proplist_pcm(m
->core
, data
.proplist
, u
->pcm_handle
);
1729 pa_proplist_sets(data
.proplist
, PA_PROP_DEVICE_STRING
, u
->device_name
);
1730 pa_proplist_setf(data
.proplist
, PA_PROP_DEVICE_BUFFERING_BUFFER_SIZE
, "%lu", (unsigned long) (period_frames
* frame_size
* nfrags
));
1731 pa_proplist_setf(data
.proplist
, PA_PROP_DEVICE_BUFFERING_FRAGMENT_SIZE
, "%lu", (unsigned long) (period_frames
* frame_size
));
1732 pa_proplist_sets(data
.proplist
, PA_PROP_DEVICE_ACCESS_MODE
, u
->use_tsched
? "mmap+timer" : (u
->use_mmap
? "mmap" : "serial"));
1735 pa_proplist_sets(data
.proplist
, PA_PROP_DEVICE_PROFILE_NAME
, mapping
->name
);
1736 pa_proplist_sets(data
.proplist
, PA_PROP_DEVICE_PROFILE_DESCRIPTION
, mapping
->description
);
1739 pa_alsa_init_description(data
.proplist
);
1741 if (u
->control_device
)
1742 pa_alsa_init_proplist_ctl(data
.proplist
, u
->control_device
);
1744 if (pa_modargs_get_proplist(ma
, "sink_properties", data
.proplist
, PA_UPDATE_REPLACE
) < 0) {
1745 pa_log("Invalid properties");
1746 pa_sink_new_data_done(&data
);
1750 if (u
->mixer_path_set
)
1751 pa_alsa_add_ports(&data
.ports
, u
->mixer_path_set
);
1753 u
->sink
= pa_sink_new(m
->core
, &data
, PA_SINK_HARDWARE
|PA_SINK_LATENCY
|(u
->use_tsched
? PA_SINK_DYNAMIC_LATENCY
: 0));
1754 pa_sink_new_data_done(&data
);
1757 pa_log("Failed to create sink object");
1761 u
->sink
->parent
.process_msg
= sink_process_msg
;
1762 u
->sink
->update_requested_latency
= sink_update_requested_latency_cb
;
1763 u
->sink
->set_state
= sink_set_state_cb
;
1764 u
->sink
->set_port
= sink_set_port_cb
;
1765 u
->sink
->userdata
= u
;
1767 pa_sink_set_asyncmsgq(u
->sink
, u
->thread_mq
.inq
);
1768 pa_sink_set_rtpoll(u
->sink
, u
->rtpoll
);
1770 u
->frame_size
= frame_size
;
1771 u
->fragment_size
= frag_size
= (uint32_t) (period_frames
* frame_size
);
1772 u
->nfragments
= nfrags
;
1773 u
->hwbuf_size
= u
->fragment_size
* nfrags
;
1774 u
->tsched_watermark
= pa_usec_to_bytes_round_up(pa_bytes_to_usec_round_up(tsched_watermark
, &requested_ss
), &u
->sink
->sample_spec
);
1775 pa_cvolume_mute(&u
->hardware_volume
, u
->sink
->sample_spec
.channels
);
1777 pa_log_info("Using %u fragments of size %lu bytes, buffer time is %0.2fms",
1778 nfrags
, (long unsigned) u
->fragment_size
,
1779 (double) pa_bytes_to_usec(u
->hwbuf_size
, &ss
) / PA_USEC_PER_MSEC
);
1781 pa_sink_set_max_request(u
->sink
, u
->hwbuf_size
);
1782 pa_sink_set_max_rewind(u
->sink
, u
->hwbuf_size
);
1784 if (u
->use_tsched
) {
1785 u
->watermark_step
= pa_usec_to_bytes(TSCHED_WATERMARK_STEP_USEC
, &u
->sink
->sample_spec
);
1787 fix_min_sleep_wakeup(u
);
1788 fix_tsched_watermark(u
);
1790 pa_sink_set_latency_range(u
->sink
,
1792 pa_bytes_to_usec(u
->hwbuf_size
, &ss
));
1794 pa_log_info("Time scheduling watermark is %0.2fms",
1795 (double) pa_bytes_to_usec(u
->tsched_watermark
, &ss
) / PA_USEC_PER_MSEC
);
1797 pa_sink_set_fixed_latency(u
->sink
, pa_bytes_to_usec(u
->hwbuf_size
, &ss
));
1801 if (update_sw_params(u
) < 0)
1804 if (setup_mixer(u
, ignore_dB
) < 0)
1807 pa_alsa_dump(PA_LOG_DEBUG
, u
->pcm_handle
);
1809 if (!(u
->thread
= pa_thread_new(thread_func
, u
))) {
1810 pa_log("Failed to create thread.");
1814 /* Get initial mixer settings */
1815 if (data
.volume_is_set
) {
1816 if (u
->sink
->set_volume
)
1817 u
->sink
->set_volume(u
->sink
);
1819 if (u
->sink
->get_volume
)
1820 u
->sink
->get_volume(u
->sink
);
1823 if (data
.muted_is_set
) {
1824 if (u
->sink
->set_mute
)
1825 u
->sink
->set_mute(u
->sink
);
1827 if (u
->sink
->get_mute
)
1828 u
->sink
->get_mute(u
->sink
);
1831 pa_sink_put(u
->sink
);
1834 pa_alsa_profile_set_free(profile_set
);
1844 pa_alsa_profile_set_free(profile_set
);
1849 static void userdata_free(struct userdata
*u
) {
1853 pa_sink_unlink(u
->sink
);
1856 pa_asyncmsgq_send(u
->thread_mq
.inq
, NULL
, PA_MESSAGE_SHUTDOWN
, NULL
, 0, NULL
);
1857 pa_thread_free(u
->thread
);
1860 pa_thread_mq_done(&u
->thread_mq
);
1863 pa_sink_unref(u
->sink
);
1865 if (u
->memchunk
.memblock
)
1866 pa_memblock_unref(u
->memchunk
.memblock
);
1868 if (u
->alsa_rtpoll_item
)
1869 pa_rtpoll_item_free(u
->alsa_rtpoll_item
);
1872 pa_rtpoll_free(u
->rtpoll
);
1874 if (u
->pcm_handle
) {
1875 snd_pcm_drop(u
->pcm_handle
);
1876 snd_pcm_close(u
->pcm_handle
);
1880 pa_alsa_fdlist_free(u
->mixer_fdl
);
1882 if (u
->mixer_path_set
)
1883 pa_alsa_path_set_free(u
->mixer_path_set
);
1884 else if (u
->mixer_path
)
1885 pa_alsa_path_free(u
->mixer_path
);
1887 if (u
->mixer_handle
)
1888 snd_mixer_close(u
->mixer_handle
);
1891 pa_smoother_free(u
->smoother
);
1896 pa_xfree(u
->device_name
);
1897 pa_xfree(u
->control_device
);
1901 void pa_alsa_sink_free(pa_sink
*s
) {
1904 pa_sink_assert_ref(s
);
1905 pa_assert_se(u
= s
->userdata
);