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 <modules/reserve-wrap.h>
58 #include "alsa-util.h"
59 #include "alsa-sink.h"
61 /* #define DEBUG_TIMING */
63 #define DEFAULT_DEVICE "default"
64 #define DEFAULT_TSCHED_BUFFER_USEC (2*PA_USEC_PER_SEC) /* 2s -- Overall buffer size */
65 #define DEFAULT_TSCHED_WATERMARK_USEC (20*PA_USEC_PER_MSEC) /* 20ms -- Fill up when only this much is left in the buffer */
66 #define TSCHED_WATERMARK_STEP_USEC (10*PA_USEC_PER_MSEC) /* 10ms -- On underrun, increase watermark by this */
67 #define TSCHED_MIN_SLEEP_USEC (10*PA_USEC_PER_MSEC) /* 10ms -- Sleep at least 10ms on each iteration */
68 #define TSCHED_MIN_WAKEUP_USEC (4*PA_USEC_PER_MSEC) /* 4ms -- Wakeup at least this long before the buffer runs empty*/
76 pa_thread_mq thread_mq
;
79 snd_pcm_t
*pcm_handle
;
81 pa_alsa_fdlist
*mixer_fdl
;
82 snd_mixer_t
*mixer_handle
;
83 snd_mixer_elem_t
*mixer_elem
;
84 long hw_volume_max
, hw_volume_min
;
85 long hw_dB_max
, hw_dB_min
;
86 pa_bool_t hw_dB_supported
:1;
87 pa_bool_t mixer_seperate_channels
:1;
88 pa_cvolume hardware_volume
;
101 pa_memchunk memchunk
;
105 pa_bool_t use_mmap
:1, use_tsched
:1;
107 pa_bool_t first
, after_rewind
;
109 pa_rtpoll_item
*alsa_rtpoll_item
;
111 snd_mixer_selem_channel_id_t mixer_map
[SND_MIXER_SCHN_LAST
];
113 pa_smoother
*smoother
;
114 uint64_t write_count
;
115 uint64_t since_start
;
117 pa_reserve_wrapper
*reserve
;
118 pa_hook_slot
*reserve_slot
;
121 static void userdata_free(struct userdata
*u
);
123 static pa_hook_result_t
reserve_cb(pa_reserve_wrapper
*r
, void *forced
, struct userdata
*u
) {
127 if (pa_sink_suspend(u
->sink
, TRUE
) < 0)
128 return PA_HOOK_CANCEL
;
133 static void reserve_done(struct userdata
*u
) {
136 if (u
->reserve_slot
) {
137 pa_hook_slot_free(u
->reserve_slot
);
138 u
->reserve_slot
= NULL
;
142 pa_reserve_wrapper_unref(u
->reserve
);
147 static void reserve_update(struct userdata
*u
) {
148 const char *description
;
154 if ((description
= pa_proplist_gets(u
->sink
->proplist
, PA_PROP_DEVICE_DESCRIPTION
)))
155 pa_reserve_wrapper_set_application_device_name(u
->reserve
, description
);
158 static int reserve_init(struct userdata
*u
, const char *dname
) {
167 /* We are resuming, try to lock the device */
168 if (!(rname
= pa_alsa_get_reserve_name(dname
)))
171 u
->reserve
= pa_reserve_wrapper_get(u
->core
, rname
);
179 pa_assert(!u
->reserve_slot
);
180 u
->reserve_slot
= pa_hook_connect(pa_reserve_wrapper_hook(u
->reserve
), PA_HOOK_NORMAL
, (pa_hook_cb_t
) reserve_cb
, u
);
185 static void fix_min_sleep_wakeup(struct userdata
*u
) {
186 size_t max_use
, max_use_2
;
190 max_use
= u
->hwbuf_size
- u
->hwbuf_unused
;
191 max_use_2
= pa_frame_align(max_use
/2, &u
->sink
->sample_spec
);
193 u
->min_sleep
= pa_usec_to_bytes(TSCHED_MIN_SLEEP_USEC
, &u
->sink
->sample_spec
);
194 u
->min_sleep
= PA_CLAMP(u
->min_sleep
, u
->frame_size
, max_use_2
);
196 u
->min_wakeup
= pa_usec_to_bytes(TSCHED_MIN_WAKEUP_USEC
, &u
->sink
->sample_spec
);
197 u
->min_wakeup
= PA_CLAMP(u
->min_wakeup
, u
->frame_size
, max_use_2
);
200 static void fix_tsched_watermark(struct userdata
*u
) {
204 max_use
= u
->hwbuf_size
- u
->hwbuf_unused
;
206 if (u
->tsched_watermark
> max_use
- u
->min_sleep
)
207 u
->tsched_watermark
= max_use
- u
->min_sleep
;
209 if (u
->tsched_watermark
< u
->min_wakeup
)
210 u
->tsched_watermark
= u
->min_wakeup
;
213 static void adjust_after_underrun(struct userdata
*u
) {
214 size_t old_watermark
;
215 pa_usec_t old_min_latency
, new_min_latency
;
218 pa_assert(u
->use_tsched
);
220 /* First, just try to increase the watermark */
221 old_watermark
= u
->tsched_watermark
;
222 u
->tsched_watermark
= PA_MIN(u
->tsched_watermark
* 2, u
->tsched_watermark
+ u
->watermark_step
);
223 fix_tsched_watermark(u
);
225 if (old_watermark
!= u
->tsched_watermark
) {
226 pa_log_notice("Increasing wakeup watermark to %0.2f ms",
227 (double) pa_bytes_to_usec(u
->tsched_watermark
, &u
->sink
->sample_spec
) / PA_USEC_PER_MSEC
);
231 /* Hmm, we cannot increase the watermark any further, hence let's raise the latency */
232 old_min_latency
= u
->sink
->thread_info
.min_latency
;
233 new_min_latency
= PA_MIN(old_min_latency
* 2, old_min_latency
+ TSCHED_WATERMARK_STEP_USEC
);
234 new_min_latency
= PA_MIN(new_min_latency
, u
->sink
->thread_info
.max_latency
);
236 if (old_min_latency
!= new_min_latency
) {
237 pa_log_notice("Increasing minimal latency to %0.2f ms",
238 (double) new_min_latency
/ PA_USEC_PER_MSEC
);
240 pa_sink_update_latency_range(u
->sink
, new_min_latency
, u
->sink
->thread_info
.max_latency
);
244 /* When we reach this we're officialy fucked! */
247 static void hw_sleep_time(struct userdata
*u
, pa_usec_t
*sleep_usec
, pa_usec_t
*process_usec
) {
250 pa_assert(sleep_usec
);
251 pa_assert(process_usec
);
255 usec
= pa_sink_get_requested_latency_within_thread(u
->sink
);
257 if (usec
== (pa_usec_t
) -1)
258 usec
= pa_bytes_to_usec(u
->hwbuf_size
, &u
->sink
->sample_spec
);
260 wm
= pa_bytes_to_usec(u
->tsched_watermark
, &u
->sink
->sample_spec
);
265 *sleep_usec
= usec
- wm
;
269 pa_log_debug("Buffer time: %lu ms; Sleep time: %lu ms; Process time: %lu ms",
270 (unsigned long) (usec
/ PA_USEC_PER_MSEC
),
271 (unsigned long) (*sleep_usec
/ PA_USEC_PER_MSEC
),
272 (unsigned long) (*process_usec
/ PA_USEC_PER_MSEC
));
276 static int try_recover(struct userdata
*u
, const char *call
, int err
) {
281 pa_log_debug("%s: %s", call
, snd_strerror(err
));
283 pa_assert(err
!= -EAGAIN
);
286 pa_log_debug("%s: Buffer underrun!", call
);
288 if ((err
= snd_pcm_recover(u
->pcm_handle
, err
, 1)) < 0) {
289 pa_log("%s: %s", call
, snd_strerror(err
));
298 static size_t check_left_to_play(struct userdata
*u
, size_t n_bytes
) {
301 /* We use <= instead of < for this check here because an underrun
302 * only happens after the last sample was processed, not already when
303 * it is removed from the buffer. This is particularly important
304 * when block transfer is used. */
306 if (n_bytes
<= u
->hwbuf_size
) {
307 left_to_play
= u
->hwbuf_size
- n_bytes
;
310 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
);
320 if (!u
->first
&& !u
->after_rewind
) {
322 if (pa_log_ratelimit())
323 pa_log_info("Underrun!");
326 adjust_after_underrun(u
);
333 static int mmap_write(struct userdata
*u
, pa_usec_t
*sleep_usec
, pa_bool_t polled
) {
334 pa_bool_t work_done
= TRUE
;
335 pa_usec_t max_sleep_usec
= 0, process_usec
= 0;
340 pa_sink_assert_ref(u
->sink
);
343 hw_sleep_time(u
, &max_sleep_usec
, &process_usec
);
350 /* First we determine how many samples are missing to fill the
351 * buffer up to 100% */
353 if (PA_UNLIKELY((n
= pa_alsa_safe_avail(u
->pcm_handle
, u
->hwbuf_size
, &u
->sink
->sample_spec
)) < 0)) {
355 if ((r
= try_recover(u
, "snd_pcm_avail", (int) n
)) == 0)
361 n_bytes
= (size_t) n
* u
->frame_size
;
364 pa_log_debug("avail: %lu", (unsigned long) n_bytes
);
367 left_to_play
= check_left_to_play(u
, n_bytes
);
371 /* We won't fill up the playback buffer before at least
372 * half the sleep time is over because otherwise we might
373 * ask for more data from the clients then they expect. We
374 * need to guarantee that clients only have to keep around
375 * a single hw buffer length. */
378 pa_bytes_to_usec(left_to_play
, &u
->sink
->sample_spec
) > process_usec
+max_sleep_usec
/2) {
380 pa_log_debug("Not filling up, because too early.");
385 if (PA_UNLIKELY(n_bytes
<= u
->hwbuf_unused
)) {
389 char *dn
= pa_alsa_get_driver_name_by_pcm(u
->pcm_handle
);
390 pa_log(_("ALSA woke us up to write new data to the device, but there was actually nothing to write!\n"
391 "Most likely this is a bug in the ALSA driver '%s'. Please report this issue to the ALSA developers.\n"
392 "We were woken up with POLLOUT set -- however a subsequent snd_pcm_avail() returned 0 or another value < min_avail."),
398 pa_log_debug("Not filling up, because not necessary.");
406 pa_log_debug("Not filling up, because already too many iterations.");
412 n_bytes
-= u
->hwbuf_unused
;
416 pa_log_debug("Filling up");
423 const snd_pcm_channel_area_t
*areas
;
424 snd_pcm_uframes_t offset
, frames
;
425 snd_pcm_sframes_t sframes
;
427 frames
= (snd_pcm_uframes_t
) (n_bytes
/ u
->frame_size
);
428 /* pa_log_debug("%lu frames to write", (unsigned long) frames); */
430 if (PA_UNLIKELY((err
= pa_alsa_safe_mmap_begin(u
->pcm_handle
, &areas
, &offset
, &frames
, u
->hwbuf_size
, &u
->sink
->sample_spec
)) < 0)) {
432 if ((r
= try_recover(u
, "snd_pcm_mmap_begin", err
)) == 0)
438 /* Make sure that if these memblocks need to be copied they will fit into one slot */
439 if (frames
> pa_mempool_block_size_max(u
->sink
->core
->mempool
)/u
->frame_size
)
440 frames
= pa_mempool_block_size_max(u
->sink
->core
->mempool
)/u
->frame_size
;
442 /* Check these are multiples of 8 bit */
443 pa_assert((areas
[0].first
& 7) == 0);
444 pa_assert((areas
[0].step
& 7)== 0);
446 /* We assume a single interleaved memory buffer */
447 pa_assert((areas
[0].first
>> 3) == 0);
448 pa_assert((areas
[0].step
>> 3) == u
->frame_size
);
450 p
= (uint8_t*) areas
[0].addr
+ (offset
* u
->frame_size
);
452 chunk
.memblock
= pa_memblock_new_fixed(u
->core
->mempool
, p
, frames
* u
->frame_size
, TRUE
);
453 chunk
.length
= pa_memblock_get_length(chunk
.memblock
);
456 pa_sink_render_into_full(u
->sink
, &chunk
);
457 pa_memblock_unref_fixed(chunk
.memblock
);
459 if (PA_UNLIKELY((sframes
= snd_pcm_mmap_commit(u
->pcm_handle
, offset
, frames
)) < 0)) {
461 if ((r
= try_recover(u
, "snd_pcm_mmap_commit", (int) sframes
)) == 0)
469 u
->write_count
+= frames
* u
->frame_size
;
470 u
->since_start
+= frames
* u
->frame_size
;
473 pa_log_debug("Wrote %lu bytes", (unsigned long) (frames
* u
->frame_size
));
476 if ((size_t) frames
* u
->frame_size
>= n_bytes
)
479 n_bytes
-= (size_t) frames
* u
->frame_size
;
483 *sleep_usec
= pa_bytes_to_usec(left_to_play
, &u
->sink
->sample_spec
) - process_usec
;
484 return work_done
? 1 : 0;
487 static int unix_write(struct userdata
*u
, pa_usec_t
*sleep_usec
, pa_bool_t polled
) {
488 pa_bool_t work_done
= FALSE
;
489 pa_usec_t max_sleep_usec
= 0, process_usec
= 0;
494 pa_sink_assert_ref(u
->sink
);
497 hw_sleep_time(u
, &max_sleep_usec
, &process_usec
);
504 if (PA_UNLIKELY((n
= pa_alsa_safe_avail(u
->pcm_handle
, u
->hwbuf_size
, &u
->sink
->sample_spec
)) < 0)) {
506 if ((r
= try_recover(u
, "snd_pcm_avail", (int) n
)) == 0)
512 n_bytes
= (size_t) n
* u
->frame_size
;
513 left_to_play
= check_left_to_play(u
, n_bytes
);
517 /* We won't fill up the playback buffer before at least
518 * half the sleep time is over because otherwise we might
519 * ask for more data from the clients then they expect. We
520 * need to guarantee that clients only have to keep around
521 * a single hw buffer length. */
524 pa_bytes_to_usec(left_to_play
, &u
->sink
->sample_spec
) > process_usec
+max_sleep_usec
/2)
527 if (PA_UNLIKELY(n_bytes
<= u
->hwbuf_unused
)) {
531 char *dn
= pa_alsa_get_driver_name_by_pcm(u
->pcm_handle
);
532 pa_log(_("ALSA woke us up to write new data to the device, but there was actually nothing to write!\n"
533 "Most likely this is a bug in the ALSA driver '%s'. Please report this issue to the ALSA developers.\n"
534 "We were woken up with POLLOUT set -- however a subsequent snd_pcm_avail() returned 0 or another value < min_avail."),
544 pa_log_debug("Not filling up, because already too many iterations.");
550 n_bytes
-= u
->hwbuf_unused
;
554 snd_pcm_sframes_t frames
;
557 /* pa_log_debug("%lu frames to write", (unsigned long) frames); */
559 if (u
->memchunk
.length
<= 0)
560 pa_sink_render(u
->sink
, n_bytes
, &u
->memchunk
);
562 pa_assert(u
->memchunk
.length
> 0);
564 frames
= (snd_pcm_sframes_t
) (u
->memchunk
.length
/ u
->frame_size
);
566 if (frames
> (snd_pcm_sframes_t
) (n_bytes
/u
->frame_size
))
567 frames
= (snd_pcm_sframes_t
) (n_bytes
/u
->frame_size
);
569 p
= pa_memblock_acquire(u
->memchunk
.memblock
);
570 frames
= snd_pcm_writei(u
->pcm_handle
, (const uint8_t*) p
+ u
->memchunk
.index
, (snd_pcm_uframes_t
) frames
);
571 pa_memblock_release(u
->memchunk
.memblock
);
573 pa_assert(frames
!= 0);
575 if (PA_UNLIKELY(frames
< 0)) {
577 if ((r
= try_recover(u
, "snd_pcm_writei", (int) frames
)) == 0)
583 u
->memchunk
.index
+= (size_t) frames
* u
->frame_size
;
584 u
->memchunk
.length
-= (size_t) frames
* u
->frame_size
;
586 if (u
->memchunk
.length
<= 0) {
587 pa_memblock_unref(u
->memchunk
.memblock
);
588 pa_memchunk_reset(&u
->memchunk
);
593 u
->write_count
+= frames
* u
->frame_size
;
594 u
->since_start
+= frames
* u
->frame_size
;
596 /* pa_log_debug("wrote %lu frames", (unsigned long) frames); */
598 if ((size_t) frames
* u
->frame_size
>= n_bytes
)
601 n_bytes
-= (size_t) frames
* u
->frame_size
;
605 *sleep_usec
= pa_bytes_to_usec(left_to_play
, &u
->sink
->sample_spec
) - process_usec
;
606 return work_done
? 1 : 0;
609 static void update_smoother(struct userdata
*u
) {
610 snd_pcm_sframes_t delay
= 0;
613 pa_usec_t now1
= 0, now2
;
614 snd_pcm_status_t
*status
;
616 snd_pcm_status_alloca(&status
);
619 pa_assert(u
->pcm_handle
);
621 /* Let's update the time smoother */
623 if (PA_UNLIKELY((err
= pa_alsa_safe_delay(u
->pcm_handle
, &delay
, u
->hwbuf_size
, &u
->sink
->sample_spec
)) < 0)) {
624 pa_log_warn("Failed to query DSP status data: %s", snd_strerror(err
));
628 if (PA_UNLIKELY((err
= snd_pcm_status(u
->pcm_handle
, status
)) < 0))
629 pa_log_warn("Failed to get timestamp: %s", snd_strerror(err
));
631 snd_htimestamp_t htstamp
= { 0, 0 };
632 snd_pcm_status_get_htstamp(status
, &htstamp
);
633 now1
= pa_timespec_load(&htstamp
);
636 position
= (int64_t) u
->write_count
- ((int64_t) delay
* (int64_t) u
->frame_size
);
638 if (PA_UNLIKELY(position
< 0))
641 /* Hmm, if the timestamp is 0, then it wasn't set and we take the current time */
643 now1
= pa_rtclock_usec();
645 now2
= pa_bytes_to_usec((uint64_t) position
, &u
->sink
->sample_spec
);
647 pa_smoother_put(u
->smoother
, now1
, now2
);
650 static pa_usec_t
sink_get_latency(struct userdata
*u
) {
653 pa_usec_t now1
, now2
;
657 now1
= pa_rtclock_usec();
658 now2
= pa_smoother_get(u
->smoother
, now1
);
660 delay
= (int64_t) pa_bytes_to_usec(u
->write_count
, &u
->sink
->sample_spec
) - (int64_t) now2
;
662 r
= delay
>= 0 ? (pa_usec_t
) delay
: 0;
664 if (u
->memchunk
.memblock
)
665 r
+= pa_bytes_to_usec(u
->memchunk
.length
, &u
->sink
->sample_spec
);
670 static int build_pollfd(struct userdata
*u
) {
672 pa_assert(u
->pcm_handle
);
674 if (u
->alsa_rtpoll_item
)
675 pa_rtpoll_item_free(u
->alsa_rtpoll_item
);
677 if (!(u
->alsa_rtpoll_item
= pa_alsa_build_pollfd(u
->pcm_handle
, u
->rtpoll
)))
683 /* Called from IO context */
684 static int suspend(struct userdata
*u
) {
686 pa_assert(u
->pcm_handle
);
688 pa_smoother_pause(u
->smoother
, pa_rtclock_usec());
690 /* Let's suspend -- we don't call snd_pcm_drain() here since that might
691 * take awfully long with our long buffer sizes today. */
692 snd_pcm_close(u
->pcm_handle
);
693 u
->pcm_handle
= NULL
;
695 if (u
->alsa_rtpoll_item
) {
696 pa_rtpoll_item_free(u
->alsa_rtpoll_item
);
697 u
->alsa_rtpoll_item
= NULL
;
700 pa_log_info("Device suspended...");
705 /* Called from IO context */
706 static int update_sw_params(struct userdata
*u
) {
707 snd_pcm_uframes_t avail_min
;
712 /* Use the full buffer if noone asked us for anything specific */
718 if ((latency
= pa_sink_get_requested_latency_within_thread(u
->sink
)) != (pa_usec_t
) -1) {
721 pa_log_debug("Latency set to %0.2fms", (double) latency
/ PA_USEC_PER_MSEC
);
723 b
= pa_usec_to_bytes(latency
, &u
->sink
->sample_spec
);
725 /* We need at least one sample in our buffer */
727 if (PA_UNLIKELY(b
< u
->frame_size
))
730 u
->hwbuf_unused
= PA_LIKELY(b
< u
->hwbuf_size
) ? (u
->hwbuf_size
- b
) : 0;
733 fix_min_sleep_wakeup(u
);
734 fix_tsched_watermark(u
);
737 pa_log_debug("hwbuf_unused=%lu", (unsigned long) u
->hwbuf_unused
);
739 /* We need at last one frame in the used part of the buffer */
740 avail_min
= (snd_pcm_uframes_t
) u
->hwbuf_unused
/ u
->frame_size
+ 1;
743 pa_usec_t sleep_usec
, process_usec
;
745 hw_sleep_time(u
, &sleep_usec
, &process_usec
);
746 avail_min
+= pa_usec_to_bytes(sleep_usec
, &u
->sink
->sample_spec
) / u
->frame_size
;
749 pa_log_debug("setting avail_min=%lu", (unsigned long) avail_min
);
751 if ((err
= pa_alsa_set_sw_params(u
->pcm_handle
, avail_min
)) < 0) {
752 pa_log("Failed to set software parameters: %s", snd_strerror(err
));
756 pa_sink_set_max_request(u
->sink
, u
->hwbuf_size
- u
->hwbuf_unused
);
761 /* Called from IO context */
762 static int unsuspend(struct userdata
*u
) {
767 snd_pcm_uframes_t period_size
;
770 pa_assert(!u
->pcm_handle
);
772 pa_log_info("Trying resume...");
774 snd_config_update_free_global();
775 if ((err
= snd_pcm_open(&u
->pcm_handle
, u
->device_name
, SND_PCM_STREAM_PLAYBACK
,
776 /*SND_PCM_NONBLOCK|*/
777 SND_PCM_NO_AUTO_RESAMPLE
|
778 SND_PCM_NO_AUTO_CHANNELS
|
779 SND_PCM_NO_AUTO_FORMAT
)) < 0) {
780 pa_log("Error opening PCM device %s: %s", u
->device_name
, snd_strerror(err
));
784 ss
= u
->sink
->sample_spec
;
785 nfrags
= u
->nfragments
;
786 period_size
= u
->fragment_size
/ u
->frame_size
;
790 if ((err
= pa_alsa_set_hw_params(u
->pcm_handle
, &ss
, &nfrags
, &period_size
, u
->hwbuf_size
/ u
->frame_size
, &b
, &d
, TRUE
)) < 0) {
791 pa_log("Failed to set hardware parameters: %s", snd_strerror(err
));
795 if (b
!= u
->use_mmap
|| d
!= u
->use_tsched
) {
796 pa_log_warn("Resume failed, couldn't get original access mode.");
800 if (!pa_sample_spec_equal(&ss
, &u
->sink
->sample_spec
)) {
801 pa_log_warn("Resume failed, couldn't restore original sample settings.");
805 if (nfrags
!= u
->nfragments
|| period_size
*u
->frame_size
!= u
->fragment_size
) {
806 pa_log_warn("Resume failed, couldn't restore original fragment settings. (Old: %lu*%lu, New %lu*%lu)",
807 (unsigned long) u
->nfragments
, (unsigned long) u
->fragment_size
,
808 (unsigned long) nfrags
, period_size
* u
->frame_size
);
812 if (update_sw_params(u
) < 0)
815 if (build_pollfd(u
) < 0)
821 pa_log_info("Resumed successfully...");
827 snd_pcm_close(u
->pcm_handle
);
828 u
->pcm_handle
= NULL
;
834 /* Called from IO context */
835 static int sink_process_msg(pa_msgobject
*o
, int code
, void *data
, int64_t offset
, pa_memchunk
*chunk
) {
836 struct userdata
*u
= PA_SINK(o
)->userdata
;
840 case PA_SINK_MESSAGE_GET_LATENCY
: {
844 r
= sink_get_latency(u
);
846 *((pa_usec_t
*) data
) = r
;
851 case PA_SINK_MESSAGE_SET_STATE
:
853 switch ((pa_sink_state_t
) PA_PTR_TO_UINT(data
)) {
855 case PA_SINK_SUSPENDED
:
856 pa_assert(PA_SINK_IS_OPENED(u
->sink
->thread_info
.state
));
864 case PA_SINK_RUNNING
:
866 if (u
->sink
->thread_info
.state
== PA_SINK_INIT
) {
867 if (build_pollfd(u
) < 0)
871 if (u
->sink
->thread_info
.state
== PA_SINK_SUSPENDED
) {
872 if (unsuspend(u
) < 0)
878 case PA_SINK_UNLINKED
:
880 case PA_SINK_INVALID_STATE
:
887 return pa_sink_process_msg(o
, code
, data
, offset
, chunk
);
890 /* Called from main context */
891 static int sink_set_state_cb(pa_sink
*s
, pa_sink_state_t new_state
) {
892 pa_sink_state_t old_state
;
895 pa_sink_assert_ref(s
);
896 pa_assert_se(u
= s
->userdata
);
898 old_state
= pa_sink_get_state(u
->sink
);
900 if (PA_SINK_IS_OPENED(old_state
) && new_state
== PA_SINK_SUSPENDED
)
902 else if (old_state
== PA_SINK_SUSPENDED
&& PA_SINK_IS_OPENED(new_state
))
903 if (reserve_init(u
, u
->device_name
) < 0)
909 static int mixer_callback(snd_mixer_elem_t
*elem
, unsigned int mask
) {
910 struct userdata
*u
= snd_mixer_elem_get_callback_private(elem
);
913 pa_assert(u
->mixer_handle
);
915 if (mask
== SND_CTL_EVENT_MASK_REMOVE
)
918 if (mask
& SND_CTL_EVENT_MASK_VALUE
) {
919 pa_sink_get_volume(u
->sink
, TRUE
);
920 pa_sink_get_mute(u
->sink
, TRUE
);
926 static pa_volume_t
from_alsa_volume(struct userdata
*u
, long alsa_vol
) {
928 return (pa_volume_t
) round(((double) (alsa_vol
- u
->hw_volume_min
) * PA_VOLUME_NORM
) /
929 (double) (u
->hw_volume_max
- u
->hw_volume_min
));
932 static long to_alsa_volume(struct userdata
*u
, pa_volume_t vol
) {
935 alsa_vol
= (long) round(((double) vol
* (double) (u
->hw_volume_max
- u
->hw_volume_min
))
936 / PA_VOLUME_NORM
) + u
->hw_volume_min
;
938 return PA_CLAMP_UNLIKELY(alsa_vol
, u
->hw_volume_min
, u
->hw_volume_max
);
941 static void sink_get_volume_cb(pa_sink
*s
) {
942 struct userdata
*u
= s
->userdata
;
946 char t
[PA_CVOLUME_SNPRINT_MAX
];
949 pa_assert(u
->mixer_elem
);
951 if (u
->mixer_seperate_channels
) {
953 r
.channels
= s
->sample_spec
.channels
;
955 for (i
= 0; i
< s
->sample_spec
.channels
; i
++) {
958 if (u
->hw_dB_supported
) {
960 if ((err
= snd_mixer_selem_get_playback_dB(u
->mixer_elem
, u
->mixer_map
[i
], &alsa_vol
)) < 0)
963 #ifdef HAVE_VALGRIND_MEMCHECK_H
964 VALGRIND_MAKE_MEM_DEFINED(&alsa_vol
, sizeof(alsa_vol
));
967 r
.values
[i
] = pa_sw_volume_from_dB((double) (alsa_vol
- u
->hw_dB_max
) / 100.0);
970 if ((err
= snd_mixer_selem_get_playback_volume(u
->mixer_elem
, u
->mixer_map
[i
], &alsa_vol
)) < 0)
973 r
.values
[i
] = from_alsa_volume(u
, alsa_vol
);
980 if (u
->hw_dB_supported
) {
982 if ((err
= snd_mixer_selem_get_playback_dB(u
->mixer_elem
, SND_MIXER_SCHN_MONO
, &alsa_vol
)) < 0)
985 #ifdef HAVE_VALGRIND_MEMCHECK_H
986 VALGRIND_MAKE_MEM_DEFINED(&alsa_vol
, sizeof(alsa_vol
));
989 pa_cvolume_set(&r
, s
->sample_spec
.channels
, pa_sw_volume_from_dB((double) (alsa_vol
- u
->hw_dB_max
) / 100.0));
993 if ((err
= snd_mixer_selem_get_playback_volume(u
->mixer_elem
, SND_MIXER_SCHN_MONO
, &alsa_vol
)) < 0)
996 pa_cvolume_set(&r
, s
->sample_spec
.channels
, from_alsa_volume(u
, alsa_vol
));
1000 pa_log_debug("Read hardware volume: %s", pa_cvolume_snprint(t
, sizeof(t
), &r
));
1002 if (!pa_cvolume_equal(&u
->hardware_volume
, &r
)) {
1004 s
->virtual_volume
= u
->hardware_volume
= r
;
1006 if (u
->hw_dB_supported
) {
1009 /* Hmm, so the hardware volume changed, let's reset our software volume */
1010 pa_cvolume_reset(&reset
, s
->sample_spec
.channels
);
1011 pa_sink_set_soft_volume(s
, &reset
);
1018 pa_log_error("Unable to read volume: %s", snd_strerror(err
));
1021 static void sink_set_volume_cb(pa_sink
*s
) {
1022 struct userdata
*u
= s
->userdata
;
1028 pa_assert(u
->mixer_elem
);
1030 if (u
->mixer_seperate_channels
) {
1032 r
.channels
= s
->sample_spec
.channels
;
1034 for (i
= 0; i
< s
->sample_spec
.channels
; i
++) {
1038 vol
= s
->virtual_volume
.values
[i
];
1040 if (u
->hw_dB_supported
) {
1042 alsa_vol
= (long) (pa_sw_volume_to_dB(vol
) * 100);
1043 alsa_vol
+= u
->hw_dB_max
;
1044 alsa_vol
= PA_CLAMP_UNLIKELY(alsa_vol
, u
->hw_dB_min
, u
->hw_dB_max
);
1046 if ((err
= snd_mixer_selem_set_playback_dB(u
->mixer_elem
, u
->mixer_map
[i
], alsa_vol
, 1)) < 0)
1049 if ((err
= snd_mixer_selem_get_playback_dB(u
->mixer_elem
, u
->mixer_map
[i
], &alsa_vol
)) < 0)
1052 #ifdef HAVE_VALGRIND_MEMCHECK_H
1053 VALGRIND_MAKE_MEM_DEFINED(&alsa_vol
, sizeof(alsa_vol
));
1056 r
.values
[i
] = pa_sw_volume_from_dB((double) (alsa_vol
- u
->hw_dB_max
) / 100.0);
1059 alsa_vol
= to_alsa_volume(u
, vol
);
1061 if ((err
= snd_mixer_selem_set_playback_volume(u
->mixer_elem
, u
->mixer_map
[i
], alsa_vol
)) < 0)
1064 if ((err
= snd_mixer_selem_get_playback_volume(u
->mixer_elem
, u
->mixer_map
[i
], &alsa_vol
)) < 0)
1067 r
.values
[i
] = from_alsa_volume(u
, alsa_vol
);
1075 vol
= pa_cvolume_max(&s
->virtual_volume
);
1077 if (u
->hw_dB_supported
) {
1078 alsa_vol
= (long) (pa_sw_volume_to_dB(vol
) * 100);
1079 alsa_vol
+= u
->hw_dB_max
;
1080 alsa_vol
= PA_CLAMP_UNLIKELY(alsa_vol
, u
->hw_dB_min
, u
->hw_dB_max
);
1082 if ((err
= snd_mixer_selem_set_playback_dB_all(u
->mixer_elem
, alsa_vol
, 1)) < 0)
1085 if ((err
= snd_mixer_selem_get_playback_dB(u
->mixer_elem
, SND_MIXER_SCHN_MONO
, &alsa_vol
)) < 0)
1088 #ifdef HAVE_VALGRIND_MEMCHECK_H
1089 VALGRIND_MAKE_MEM_DEFINED(&alsa_vol
, sizeof(alsa_vol
));
1092 pa_cvolume_set(&r
, s
->sample_spec
.channels
, pa_sw_volume_from_dB((double) (alsa_vol
- u
->hw_dB_max
) / 100.0));
1095 alsa_vol
= to_alsa_volume(u
, vol
);
1097 if ((err
= snd_mixer_selem_set_playback_volume_all(u
->mixer_elem
, alsa_vol
)) < 0)
1100 if ((err
= snd_mixer_selem_get_playback_volume(u
->mixer_elem
, SND_MIXER_SCHN_MONO
, &alsa_vol
)) < 0)
1103 pa_cvolume_set(&r
, s
->sample_spec
.channels
, from_alsa_volume(u
, alsa_vol
));
1107 u
->hardware_volume
= r
;
1109 if (u
->hw_dB_supported
) {
1110 char t
[PA_CVOLUME_SNPRINT_MAX
];
1112 /* Match exactly what the user requested by software */
1113 pa_sw_cvolume_divide(&s
->soft_volume
, &s
->virtual_volume
, &u
->hardware_volume
);
1115 pa_log_debug("Requested volume: %s", pa_cvolume_snprint(t
, sizeof(t
), &s
->virtual_volume
));
1116 pa_log_debug("Got hardware volume: %s", pa_cvolume_snprint(t
, sizeof(t
), &u
->hardware_volume
));
1117 pa_log_debug("Calculated software volume: %s", pa_cvolume_snprint(t
, sizeof(t
), &s
->soft_volume
));
1121 /* We can't match exactly what the user requested, hence let's
1122 * at least tell the user about it */
1124 s
->virtual_volume
= r
;
1129 pa_log_error("Unable to set volume: %s", snd_strerror(err
));
1132 static void sink_get_mute_cb(pa_sink
*s
) {
1133 struct userdata
*u
= s
->userdata
;
1137 pa_assert(u
->mixer_elem
);
1139 if ((err
= snd_mixer_selem_get_playback_switch(u
->mixer_elem
, 0, &sw
)) < 0) {
1140 pa_log_error("Unable to get switch: %s", snd_strerror(err
));
1147 static void sink_set_mute_cb(pa_sink
*s
) {
1148 struct userdata
*u
= s
->userdata
;
1152 pa_assert(u
->mixer_elem
);
1154 if ((err
= snd_mixer_selem_set_playback_switch_all(u
->mixer_elem
, !s
->muted
)) < 0) {
1155 pa_log_error("Unable to set switch: %s", snd_strerror(err
));
1160 static void sink_update_requested_latency_cb(pa_sink
*s
) {
1161 struct userdata
*u
= s
->userdata
;
1168 before
= u
->hwbuf_unused
;
1169 update_sw_params(u
);
1171 /* Let's check whether we now use only a smaller part of the
1172 buffer then before. If so, we need to make sure that subsequent
1173 rewinds are relative to the new maxium fill level and not to the
1174 current fill level. Thus, let's do a full rewind once, to clear
1177 if (u
->hwbuf_unused
> before
) {
1178 pa_log_debug("Requesting rewind due to latency change.");
1179 pa_sink_request_rewind(s
, (size_t) -1);
1183 static int process_rewind(struct userdata
*u
) {
1184 snd_pcm_sframes_t unused
;
1185 size_t rewind_nbytes
, unused_nbytes
, limit_nbytes
;
1188 /* Figure out how much we shall rewind and reset the counter */
1189 rewind_nbytes
= u
->sink
->thread_info
.rewind_nbytes
;
1190 u
->sink
->thread_info
.rewind_nbytes
= 0;
1192 if (rewind_nbytes
<= 0)
1195 pa_assert(rewind_nbytes
> 0);
1196 pa_log_debug("Requested to rewind %lu bytes.", (unsigned long) rewind_nbytes
);
1198 snd_pcm_hwsync(u
->pcm_handle
);
1199 if ((unused
= snd_pcm_avail_update(u
->pcm_handle
)) < 0) {
1200 pa_log("snd_pcm_avail_update() failed: %s", snd_strerror((int) unused
));
1204 unused_nbytes
= u
->tsched_watermark
+ (size_t) unused
* u
->frame_size
;
1206 if (u
->hwbuf_size
> unused_nbytes
)
1207 limit_nbytes
= u
->hwbuf_size
- unused_nbytes
;
1211 if (rewind_nbytes
> limit_nbytes
)
1212 rewind_nbytes
= limit_nbytes
;
1214 if (rewind_nbytes
> 0) {
1215 snd_pcm_sframes_t in_frames
, out_frames
;
1217 pa_log_debug("Limited to %lu bytes.", (unsigned long) rewind_nbytes
);
1219 in_frames
= (snd_pcm_sframes_t
) (rewind_nbytes
/ u
->frame_size
);
1220 pa_log_debug("before: %lu", (unsigned long) in_frames
);
1221 if ((out_frames
= snd_pcm_rewind(u
->pcm_handle
, (snd_pcm_uframes_t
) in_frames
)) < 0) {
1222 pa_log("snd_pcm_rewind() failed: %s", snd_strerror((int) out_frames
));
1225 pa_log_debug("after: %lu", (unsigned long) out_frames
);
1227 rewind_nbytes
= (size_t) out_frames
* u
->frame_size
;
1229 if (rewind_nbytes
<= 0)
1230 pa_log_info("Tried rewind, but was apparently not possible.");
1232 u
->write_count
-= out_frames
* u
->frame_size
;
1233 pa_log_debug("Rewound %lu bytes.", (unsigned long) rewind_nbytes
);
1234 pa_sink_process_rewind(u
->sink
, rewind_nbytes
);
1236 u
->after_rewind
= TRUE
;
1240 pa_log_debug("Mhmm, actually there is nothing to rewind.");
1244 pa_sink_process_rewind(u
->sink
, 0);
1250 static void thread_func(void *userdata
) {
1251 struct userdata
*u
= userdata
;
1252 unsigned short revents
= 0;
1256 pa_log_debug("Thread starting up");
1258 if (u
->core
->realtime_scheduling
)
1259 pa_make_realtime(u
->core
->realtime_priority
);
1261 pa_thread_mq_install(&u
->thread_mq
);
1262 pa_rtpoll_install(u
->rtpoll
);
1268 pa_log_debug("Loop");
1271 /* Render some data and write it to the dsp */
1272 if (PA_SINK_IS_OPENED(u
->sink
->thread_info
.state
)) {
1274 pa_usec_t sleep_usec
= 0;
1276 if (u
->sink
->thread_info
.rewind_requested
)
1277 if (process_rewind(u
) < 0)
1281 work_done
= mmap_write(u
, &sleep_usec
, revents
& POLLOUT
);
1283 work_done
= unix_write(u
, &sleep_usec
, revents
& POLLOUT
);
1288 /* pa_log_debug("work_done = %i", work_done); */
1293 pa_log_info("Starting playback.");
1294 snd_pcm_start(u
->pcm_handle
);
1296 pa_smoother_resume(u
->smoother
, pa_rtclock_usec());
1302 if (u
->use_tsched
) {
1305 if (u
->since_start
<= u
->hwbuf_size
) {
1307 /* USB devices on ALSA seem to hit a buffer
1308 * underrun during the first iterations much
1309 * quicker then we calculate here, probably due to
1310 * the transport latency. To accomodate for that
1311 * we artificially decrease the sleep time until
1312 * we have filled the buffer at least once
1315 pa_log_debug("Cutting sleep time for the initial iterations by half.");
1319 /* OK, the playback buffer is now full, let's
1320 * calculate when to wake up next */
1321 /* pa_log_debug("Waking up in %0.2fms (sound card clock).", (double) sleep_usec / PA_USEC_PER_MSEC); */
1323 /* Convert from the sound card time domain to the
1324 * system time domain */
1325 cusec
= pa_smoother_translate(u
->smoother
, pa_rtclock_usec(), sleep_usec
);
1327 /* pa_log_debug("Waking up in %0.2fms (system clock).", (double) cusec / PA_USEC_PER_MSEC); */
1329 /* We don't trust the conversion, so we wake up whatever comes first */
1330 pa_rtpoll_set_timer_relative(u
->rtpoll
, PA_MIN(sleep_usec
, cusec
));
1334 u
->after_rewind
= FALSE
;
1336 } else if (u
->use_tsched
)
1338 /* OK, we're in an invalid state, let's disable our timers */
1339 pa_rtpoll_set_timer_disabled(u
->rtpoll
);
1341 /* Hmm, nothing to do. Let's sleep */
1342 if ((ret
= pa_rtpoll_run(u
->rtpoll
, TRUE
)) < 0)
1348 /* Tell ALSA about this and process its response */
1349 if (PA_SINK_IS_OPENED(u
->sink
->thread_info
.state
)) {
1350 struct pollfd
*pollfd
;
1354 pollfd
= pa_rtpoll_item_get_pollfd(u
->alsa_rtpoll_item
, &n
);
1356 if ((err
= snd_pcm_poll_descriptors_revents(u
->pcm_handle
, pollfd
, n
, &revents
)) < 0) {
1357 pa_log("snd_pcm_poll_descriptors_revents() failed: %s", snd_strerror(err
));
1361 if (revents
& ~POLLOUT
) {
1362 if (pa_alsa_recover_from_poll(u
->pcm_handle
, revents
) < 0)
1367 } else if (revents
&& u
->use_tsched
&& pa_log_ratelimit())
1368 pa_log_debug("Wakeup from ALSA!");
1375 /* If this was no regular exit from the loop we have to continue
1376 * processing messages until we received PA_MESSAGE_SHUTDOWN */
1377 pa_asyncmsgq_post(u
->thread_mq
.outq
, PA_MSGOBJECT(u
->core
), PA_CORE_MESSAGE_UNLOAD_MODULE
, u
->module
, 0, NULL
, NULL
);
1378 pa_asyncmsgq_wait_for(u
->thread_mq
.inq
, PA_MESSAGE_SHUTDOWN
);
1381 pa_log_debug("Thread shutting down");
1384 static void set_sink_name(pa_sink_new_data
*data
, pa_modargs
*ma
, const char *device_id
, const char *device_name
) {
1390 pa_assert(device_name
);
1392 if ((n
= pa_modargs_get_value(ma
, "sink_name", NULL
))) {
1393 pa_sink_new_data_set_name(data
, n
);
1394 data
->namereg_fail
= TRUE
;
1398 if ((n
= pa_modargs_get_value(ma
, "name", NULL
)))
1399 data
->namereg_fail
= TRUE
;
1401 n
= device_id
? device_id
: device_name
;
1402 data
->namereg_fail
= FALSE
;
1405 t
= pa_sprintf_malloc("alsa_output.%s", n
);
1406 pa_sink_new_data_set_name(data
, t
);
1410 static int setup_mixer(struct userdata
*u
, pa_bool_t ignore_dB
) {
1413 if (!u
->mixer_handle
)
1416 pa_assert(u
->mixer_elem
);
1418 if (snd_mixer_selem_has_playback_volume(u
->mixer_elem
)) {
1419 pa_bool_t suitable
= FALSE
;
1421 if (snd_mixer_selem_get_playback_volume_range(u
->mixer_elem
, &u
->hw_volume_min
, &u
->hw_volume_max
) < 0)
1422 pa_log_info("Failed to get volume range. Falling back to software volume control.");
1423 else if (u
->hw_volume_min
>= u
->hw_volume_max
)
1424 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
);
1426 pa_log_info("Volume ranges from %li to %li.", u
->hw_volume_min
, u
->hw_volume_max
);
1431 if (ignore_dB
|| snd_mixer_selem_get_playback_dB_range(u
->mixer_elem
, &u
->hw_dB_min
, &u
->hw_dB_max
) < 0)
1432 pa_log_info("Mixer doesn't support dB information or data is ignored.");
1434 #ifdef HAVE_VALGRIND_MEMCHECK_H
1435 VALGRIND_MAKE_MEM_DEFINED(&u
->hw_dB_min
, sizeof(u
->hw_dB_min
));
1436 VALGRIND_MAKE_MEM_DEFINED(&u
->hw_dB_max
, sizeof(u
->hw_dB_max
));
1439 if (u
->hw_dB_min
>= u
->hw_dB_max
)
1440 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);
1442 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);
1443 u
->hw_dB_supported
= TRUE
;
1445 if (u
->hw_dB_max
> 0) {
1446 u
->sink
->base_volume
= pa_sw_volume_from_dB(- (double) u
->hw_dB_max
/100.0);
1447 pa_log_info("Fixing base volume to %0.2f dB", pa_sw_volume_to_dB(u
->sink
->base_volume
));
1449 pa_log_info("No particular base volume set, fixing to 0 dB");
1453 if (!u
->hw_dB_supported
&&
1454 u
->hw_volume_max
- u
->hw_volume_min
< 3) {
1456 pa_log_info("Device doesn't do dB volume and has less than 4 volume levels. Falling back to software volume control.");
1462 u
->mixer_seperate_channels
= pa_alsa_calc_mixer_map(u
->mixer_elem
, &u
->sink
->channel_map
, u
->mixer_map
, TRUE
) >= 0;
1464 u
->sink
->get_volume
= sink_get_volume_cb
;
1465 u
->sink
->set_volume
= sink_set_volume_cb
;
1466 u
->sink
->flags
|= PA_SINK_HW_VOLUME_CTRL
| (u
->hw_dB_supported
? PA_SINK_DECIBEL_VOLUME
: 0);
1467 pa_log_info("Using hardware volume control. Hardware dB scale %s.", u
->hw_dB_supported
? "supported" : "not supported");
1469 if (!u
->hw_dB_supported
)
1470 u
->sink
->n_volume_steps
= u
->hw_volume_max
- u
->hw_volume_min
+ 1;
1472 pa_log_info("Using software volume control.");
1475 if (snd_mixer_selem_has_playback_switch(u
->mixer_elem
)) {
1476 u
->sink
->get_mute
= sink_get_mute_cb
;
1477 u
->sink
->set_mute
= sink_set_mute_cb
;
1478 u
->sink
->flags
|= PA_SINK_HW_MUTE_CTRL
;
1480 pa_log_info("Using software mute control.");
1482 u
->mixer_fdl
= pa_alsa_fdlist_new();
1484 if (pa_alsa_fdlist_set_mixer(u
->mixer_fdl
, u
->mixer_handle
, u
->core
->mainloop
) < 0) {
1485 pa_log("Failed to initialize file descriptor monitoring");
1489 snd_mixer_elem_set_callback(u
->mixer_elem
, mixer_callback
);
1490 snd_mixer_elem_set_callback_private(u
->mixer_elem
, u
);
1495 pa_sink
*pa_alsa_sink_new(pa_module
*m
, pa_modargs
*ma
, const char*driver
, pa_card
*card
, const pa_alsa_profile_info
*profile
) {
1497 struct userdata
*u
= NULL
;
1498 const char *dev_id
= NULL
;
1501 uint32_t nfrags
, hwbuf_size
, frag_size
, tsched_size
, tsched_watermark
;
1502 snd_pcm_uframes_t period_frames
, tsched_frames
;
1504 pa_bool_t use_mmap
= TRUE
, b
, use_tsched
= TRUE
, d
, ignore_dB
= FALSE
;
1506 pa_sink_new_data data
;
1511 ss
= m
->core
->default_sample_spec
;
1512 map
= m
->core
->default_channel_map
;
1513 if (pa_modargs_get_sample_spec_and_channel_map(ma
, &ss
, &map
, PA_CHANNEL_MAP_ALSA
) < 0) {
1514 pa_log("Failed to parse sample specification and channel map");
1518 frame_size
= pa_frame_size(&ss
);
1520 nfrags
= m
->core
->default_n_fragments
;
1521 frag_size
= (uint32_t) pa_usec_to_bytes(m
->core
->default_fragment_size_msec
*PA_USEC_PER_MSEC
, &ss
);
1523 frag_size
= (uint32_t) frame_size
;
1524 tsched_size
= (uint32_t) pa_usec_to_bytes(DEFAULT_TSCHED_BUFFER_USEC
, &ss
);
1525 tsched_watermark
= (uint32_t) pa_usec_to_bytes(DEFAULT_TSCHED_WATERMARK_USEC
, &ss
);
1527 if (pa_modargs_get_value_u32(ma
, "fragments", &nfrags
) < 0 ||
1528 pa_modargs_get_value_u32(ma
, "fragment_size", &frag_size
) < 0 ||
1529 pa_modargs_get_value_u32(ma
, "tsched_buffer_size", &tsched_size
) < 0 ||
1530 pa_modargs_get_value_u32(ma
, "tsched_buffer_watermark", &tsched_watermark
) < 0) {
1531 pa_log("Failed to parse buffer metrics");
1535 hwbuf_size
= frag_size
* nfrags
;
1536 period_frames
= frag_size
/frame_size
;
1537 tsched_frames
= tsched_size
/frame_size
;
1539 if (pa_modargs_get_value_boolean(ma
, "mmap", &use_mmap
) < 0) {
1540 pa_log("Failed to parse mmap argument.");
1544 if (pa_modargs_get_value_boolean(ma
, "tsched", &use_tsched
) < 0) {
1545 pa_log("Failed to parse tsched argument.");
1549 if (pa_modargs_get_value_boolean(ma
, "ignore_dB", &ignore_dB
) < 0) {
1550 pa_log("Failed to parse ignore_dB argument.");
1554 if (use_tsched
&& !pa_rtclock_hrtimer()) {
1555 pa_log_notice("Disabling timer-based scheduling because high-resolution timers are not available from the kernel.");
1559 u
= pa_xnew0(struct userdata
, 1);
1562 u
->use_mmap
= use_mmap
;
1563 u
->use_tsched
= use_tsched
;
1565 u
->rtpoll
= pa_rtpoll_new();
1566 pa_thread_mq_init(&u
->thread_mq
, m
->core
->mainloop
, u
->rtpoll
);
1568 u
->smoother
= pa_smoother_new(DEFAULT_TSCHED_BUFFER_USEC
*2, DEFAULT_TSCHED_BUFFER_USEC
*2, TRUE
, 5);
1569 usec
= pa_rtclock_usec();
1570 pa_smoother_set_time_offset(u
->smoother
, usec
);
1571 pa_smoother_pause(u
->smoother
, usec
);
1573 if (reserve_init(u
, pa_modargs_get_value(
1575 pa_modargs_get_value(ma
, "device", DEFAULT_DEVICE
))) < 0)
1583 if (!(dev_id
= pa_modargs_get_value(ma
, "device_id", NULL
))) {
1584 pa_log("device_id= not set");
1588 if (!(u
->pcm_handle
= pa_alsa_open_by_device_id_profile(
1592 SND_PCM_STREAM_PLAYBACK
,
1593 &nfrags
, &period_frames
, tsched_frames
,
1598 } else if ((dev_id
= pa_modargs_get_value(ma
, "device_id", NULL
))) {
1600 if (!(u
->pcm_handle
= pa_alsa_open_by_device_id_auto(
1604 SND_PCM_STREAM_PLAYBACK
,
1605 &nfrags
, &period_frames
, tsched_frames
,
1612 if (!(u
->pcm_handle
= pa_alsa_open_by_device_string(
1613 pa_modargs_get_value(ma
, "device", DEFAULT_DEVICE
),
1616 SND_PCM_STREAM_PLAYBACK
,
1617 &nfrags
, &period_frames
, tsched_frames
,
1623 pa_assert(u
->device_name
);
1624 pa_log_info("Successfully opened device %s.", u
->device_name
);
1627 pa_log_info("Selected configuration '%s' (%s).", profile
->description
, profile
->name
);
1629 if (use_mmap
&& !b
) {
1630 pa_log_info("Device doesn't support mmap(), falling back to UNIX read/write mode.");
1631 u
->use_mmap
= use_mmap
= FALSE
;
1634 if (use_tsched
&& (!b
|| !d
)) {
1635 pa_log_info("Cannot enable timer-based scheduling, falling back to sound IRQ scheduling.");
1636 u
->use_tsched
= use_tsched
= FALSE
;
1640 pa_log_info("Successfully enabled mmap() mode.");
1643 pa_log_info("Successfully enabled timer-based scheduling mode.");
1645 /* ALSA might tweak the sample spec, so recalculate the frame size */
1646 frame_size
= pa_frame_size(&ss
);
1648 pa_alsa_find_mixer_and_elem(u
->pcm_handle
, &u
->mixer_handle
, &u
->mixer_elem
);
1650 pa_sink_new_data_init(&data
);
1651 data
.driver
= driver
;
1654 set_sink_name(&data
, ma
, dev_id
, u
->device_name
);
1655 pa_sink_new_data_set_sample_spec(&data
, &ss
);
1656 pa_sink_new_data_set_channel_map(&data
, &map
);
1658 pa_alsa_init_proplist_pcm(m
->core
, data
.proplist
, u
->pcm_handle
);
1659 pa_proplist_sets(data
.proplist
, PA_PROP_DEVICE_STRING
, u
->device_name
);
1660 pa_proplist_setf(data
.proplist
, PA_PROP_DEVICE_BUFFERING_BUFFER_SIZE
, "%lu", (unsigned long) (period_frames
* frame_size
* nfrags
));
1661 pa_proplist_setf(data
.proplist
, PA_PROP_DEVICE_BUFFERING_FRAGMENT_SIZE
, "%lu", (unsigned long) (period_frames
* frame_size
));
1662 pa_proplist_sets(data
.proplist
, PA_PROP_DEVICE_ACCESS_MODE
, u
->use_tsched
? "mmap+timer" : (u
->use_mmap
? "mmap" : "serial"));
1665 pa_proplist_sets(data
.proplist
, PA_PROP_DEVICE_PROFILE_NAME
, profile
->name
);
1666 pa_proplist_sets(data
.proplist
, PA_PROP_DEVICE_PROFILE_DESCRIPTION
, profile
->description
);
1669 u
->sink
= pa_sink_new(m
->core
, &data
, PA_SINK_HARDWARE
|PA_SINK_LATENCY
);
1670 pa_sink_new_data_done(&data
);
1673 pa_log("Failed to create sink object");
1677 u
->sink
->parent
.process_msg
= sink_process_msg
;
1678 u
->sink
->update_requested_latency
= sink_update_requested_latency_cb
;
1679 u
->sink
->set_state
= sink_set_state_cb
;
1680 u
->sink
->userdata
= u
;
1682 pa_sink_set_asyncmsgq(u
->sink
, u
->thread_mq
.inq
);
1683 pa_sink_set_rtpoll(u
->sink
, u
->rtpoll
);
1685 u
->frame_size
= frame_size
;
1686 u
->fragment_size
= frag_size
= (uint32_t) (period_frames
* frame_size
);
1687 u
->nfragments
= nfrags
;
1688 u
->hwbuf_size
= u
->fragment_size
* nfrags
;
1689 u
->tsched_watermark
= tsched_watermark
;
1690 pa_cvolume_mute(&u
->hardware_volume
, u
->sink
->sample_spec
.channels
);
1693 fix_min_sleep_wakeup(u
);
1694 fix_tsched_watermark(u
);
1696 u
->watermark_step
= pa_usec_to_bytes(TSCHED_WATERMARK_STEP_USEC
, &u
->sink
->sample_spec
);
1699 u
->sink
->thread_info
.max_rewind
= use_tsched
? u
->hwbuf_size
: 0;
1700 u
->sink
->thread_info
.max_request
= u
->hwbuf_size
;
1702 pa_sink_set_latency_range(u
->sink
,
1703 !use_tsched
? pa_bytes_to_usec(u
->hwbuf_size
, &ss
) : (pa_usec_t
) -1,
1704 pa_bytes_to_usec(u
->hwbuf_size
, &ss
));
1706 pa_log_info("Using %u fragments of size %lu bytes, buffer time is %0.2fms",
1707 nfrags
, (long unsigned) u
->fragment_size
,
1708 (double) pa_bytes_to_usec(u
->hwbuf_size
, &ss
) / PA_USEC_PER_MSEC
);
1711 pa_log_info("Time scheduling watermark is %0.2fms",
1712 (double) pa_bytes_to_usec(u
->tsched_watermark
, &ss
) / PA_USEC_PER_MSEC
);
1716 if (update_sw_params(u
) < 0)
1719 if (setup_mixer(u
, ignore_dB
) < 0)
1722 pa_alsa_dump(u
->pcm_handle
);
1724 if (!(u
->thread
= pa_thread_new(thread_func
, u
))) {
1725 pa_log("Failed to create thread.");
1729 /* Get initial mixer settings */
1730 if (data
.volume_is_set
) {
1731 if (u
->sink
->set_volume
)
1732 u
->sink
->set_volume(u
->sink
);
1734 if (u
->sink
->get_volume
)
1735 u
->sink
->get_volume(u
->sink
);
1738 if (data
.muted_is_set
) {
1739 if (u
->sink
->set_mute
)
1740 u
->sink
->set_mute(u
->sink
);
1742 if (u
->sink
->get_mute
)
1743 u
->sink
->get_mute(u
->sink
);
1746 pa_sink_put(u
->sink
);
1757 static void userdata_free(struct userdata
*u
) {
1761 pa_sink_unlink(u
->sink
);
1764 pa_asyncmsgq_send(u
->thread_mq
.inq
, NULL
, PA_MESSAGE_SHUTDOWN
, NULL
, 0, NULL
);
1765 pa_thread_free(u
->thread
);
1768 pa_thread_mq_done(&u
->thread_mq
);
1771 pa_sink_unref(u
->sink
);
1773 if (u
->memchunk
.memblock
)
1774 pa_memblock_unref(u
->memchunk
.memblock
);
1776 if (u
->alsa_rtpoll_item
)
1777 pa_rtpoll_item_free(u
->alsa_rtpoll_item
);
1780 pa_rtpoll_free(u
->rtpoll
);
1783 pa_alsa_fdlist_free(u
->mixer_fdl
);
1785 if (u
->mixer_handle
)
1786 snd_mixer_close(u
->mixer_handle
);
1788 if (u
->pcm_handle
) {
1789 snd_pcm_drop(u
->pcm_handle
);
1790 snd_pcm_close(u
->pcm_handle
);
1794 pa_smoother_free(u
->smoother
);
1798 pa_xfree(u
->device_name
);
1802 void pa_alsa_sink_free(pa_sink
*s
) {
1805 pa_sink_assert_ref(s
);
1806 pa_assert_se(u
= s
->userdata
);