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/xmalloc.h>
36 #include <pulse/util.h>
37 #include <pulse/timeval.h>
38 #include <pulse/i18n.h>
40 #include <pulsecore/core-error.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-util.h>
47 #include <pulsecore/sample-util.h>
48 #include <pulsecore/log.h>
49 #include <pulsecore/macro.h>
50 #include <pulsecore/thread.h>
51 #include <pulsecore/core-error.h>
52 #include <pulsecore/thread-mq.h>
53 #include <pulsecore/rtpoll.h>
54 #include <pulsecore/time-smoother.h>
55 #include <pulsecore/rtclock.h>
57 #include <modules/reserve-wrap.h>
59 #include "alsa-util.h"
60 #include "alsa-source.h"
62 /* #define DEBUG_TIMING */
64 #define DEFAULT_DEVICE "default"
65 #define DEFAULT_TSCHED_BUFFER_USEC (2*PA_USEC_PER_SEC) /* 2s */
66 #define DEFAULT_TSCHED_WATERMARK_USEC (20*PA_USEC_PER_MSEC) /* 20ms */
67 #define TSCHED_WATERMARK_STEP_USEC (10*PA_USEC_PER_MSEC) /* 10ms */
68 #define TSCHED_MIN_SLEEP_USEC (10*PA_USEC_PER_MSEC) /* 10ms */
69 #define TSCHED_MIN_WAKEUP_USEC (4*PA_USEC_PER_MSEC) /* 4ms */
77 pa_thread_mq thread_mq
;
80 snd_pcm_t
*pcm_handle
;
82 pa_alsa_fdlist
*mixer_fdl
;
83 snd_mixer_t
*mixer_handle
;
84 snd_mixer_elem_t
*mixer_elem
;
85 long hw_volume_max
, hw_volume_min
;
86 long hw_dB_max
, hw_dB_min
;
87 pa_bool_t hw_dB_supported
:1;
88 pa_bool_t mixer_seperate_channels
:1;
90 pa_cvolume hardware_volume
;
106 pa_bool_t use_mmap
:1, use_tsched
:1;
108 pa_rtpoll_item
*alsa_rtpoll_item
;
110 snd_mixer_selem_channel_id_t mixer_map
[SND_MIXER_SCHN_LAST
];
112 pa_smoother
*smoother
;
115 pa_reserve_wrapper
*reserve
;
116 pa_hook_slot
*reserve_slot
;
117 pa_reserve_monitor_wrapper
*monitor
;
118 pa_hook_slot
*monitor_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_source_suspend(u
->source
, TRUE
, PA_SUSPEND_APPLICATION
) < 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
;
151 if (!u
->source
|| !u
->reserve
)
154 if ((description
= pa_proplist_gets(u
->source
->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 if (pa_in_system_mode())
170 /* We are resuming, try to lock the device */
171 if (!(rname
= pa_alsa_get_reserve_name(dname
)))
174 u
->reserve
= pa_reserve_wrapper_get(u
->core
, rname
);
182 pa_assert(!u
->reserve_slot
);
183 u
->reserve_slot
= pa_hook_connect(pa_reserve_wrapper_hook(u
->reserve
), PA_HOOK_NORMAL
, (pa_hook_cb_t
) reserve_cb
, u
);
188 static pa_hook_result_t
monitor_cb(pa_reserve_monitor_wrapper
*w
, void* busy
, struct userdata
*u
) {
194 b
= PA_PTR_TO_UINT(busy
) && !u
->reserve
;
196 pa_source_suspend(u
->source
, b
, PA_SUSPEND_APPLICATION
);
200 static void monitor_done(struct userdata
*u
) {
203 if (u
->monitor_slot
) {
204 pa_hook_slot_free(u
->monitor_slot
);
205 u
->monitor_slot
= NULL
;
209 pa_reserve_monitor_wrapper_unref(u
->monitor
);
214 static int reserve_monitor_init(struct userdata
*u
, const char *dname
) {
220 if (pa_in_system_mode())
223 /* We are resuming, try to lock the device */
224 if (!(rname
= pa_alsa_get_reserve_name(dname
)))
227 u
->monitor
= pa_reserve_monitor_wrapper_get(u
->core
, rname
);
233 pa_assert(!u
->monitor_slot
);
234 u
->monitor_slot
= pa_hook_connect(pa_reserve_monitor_wrapper_hook(u
->monitor
), PA_HOOK_NORMAL
, (pa_hook_cb_t
) monitor_cb
, u
);
239 static void fix_min_sleep_wakeup(struct userdata
*u
) {
240 size_t max_use
, max_use_2
;
243 max_use
= u
->hwbuf_size
- u
->hwbuf_unused
;
244 max_use_2
= pa_frame_align(max_use
/2, &u
->source
->sample_spec
);
246 u
->min_sleep
= pa_usec_to_bytes(TSCHED_MIN_SLEEP_USEC
, &u
->source
->sample_spec
);
247 u
->min_sleep
= PA_CLAMP(u
->min_sleep
, u
->frame_size
, max_use_2
);
249 u
->min_wakeup
= pa_usec_to_bytes(TSCHED_MIN_WAKEUP_USEC
, &u
->source
->sample_spec
);
250 u
->min_wakeup
= PA_CLAMP(u
->min_wakeup
, u
->frame_size
, max_use_2
);
253 static void fix_tsched_watermark(struct userdata
*u
) {
257 max_use
= u
->hwbuf_size
- u
->hwbuf_unused
;
259 if (u
->tsched_watermark
> max_use
- u
->min_sleep
)
260 u
->tsched_watermark
= max_use
- u
->min_sleep
;
262 if (u
->tsched_watermark
< u
->min_wakeup
)
263 u
->tsched_watermark
= u
->min_wakeup
;
266 static void adjust_after_overrun(struct userdata
*u
) {
267 size_t old_watermark
;
268 pa_usec_t old_min_latency
, new_min_latency
;
271 pa_assert(u
->use_tsched
);
273 /* First, just try to increase the watermark */
274 old_watermark
= u
->tsched_watermark
;
275 u
->tsched_watermark
= PA_MIN(u
->tsched_watermark
* 2, u
->tsched_watermark
+ u
->watermark_step
);
277 fix_tsched_watermark(u
);
279 if (old_watermark
!= u
->tsched_watermark
) {
280 pa_log_notice("Increasing wakeup watermark to %0.2f ms",
281 (double) pa_bytes_to_usec(u
->tsched_watermark
, &u
->source
->sample_spec
) / PA_USEC_PER_MSEC
);
285 /* Hmm, we cannot increase the watermark any further, hence let's raise the latency */
286 old_min_latency
= u
->source
->thread_info
.min_latency
;
287 new_min_latency
= PA_MIN(old_min_latency
* 2, old_min_latency
+ TSCHED_WATERMARK_STEP_USEC
);
288 new_min_latency
= PA_MIN(new_min_latency
, u
->source
->thread_info
.max_latency
);
290 if (old_min_latency
!= new_min_latency
) {
291 pa_log_notice("Increasing minimal latency to %0.2f ms",
292 (double) new_min_latency
/ PA_USEC_PER_MSEC
);
294 pa_source_set_latency_range_within_thread(u
->source
, new_min_latency
, u
->source
->thread_info
.max_latency
);
298 /* When we reach this we're officialy fucked! */
301 static pa_usec_t
hw_sleep_time(struct userdata
*u
, pa_usec_t
*sleep_usec
, pa_usec_t
*process_usec
) {
306 usec
= pa_source_get_requested_latency_within_thread(u
->source
);
308 if (usec
== (pa_usec_t
) -1)
309 usec
= pa_bytes_to_usec(u
->hwbuf_size
, &u
->source
->sample_spec
);
311 wm
= pa_bytes_to_usec(u
->tsched_watermark
, &u
->source
->sample_spec
);
316 *sleep_usec
= usec
- wm
;
320 pa_log_debug("Buffer time: %lu ms; Sleep time: %lu ms; Process time: %lu ms",
321 (unsigned long) (usec
/ PA_USEC_PER_MSEC
),
322 (unsigned long) (*sleep_usec
/ PA_USEC_PER_MSEC
),
323 (unsigned long) (*process_usec
/ PA_USEC_PER_MSEC
));
329 static int try_recover(struct userdata
*u
, const char *call
, int err
) {
334 pa_log_debug("%s: %s", call
, pa_alsa_strerror(err
));
336 pa_assert(err
!= -EAGAIN
);
339 pa_log_debug("%s: Buffer overrun!", call
);
341 if ((err
= snd_pcm_recover(u
->pcm_handle
, err
, 1)) < 0) {
342 pa_log("%s: %s", call
, pa_alsa_strerror(err
));
346 snd_pcm_start(u
->pcm_handle
);
350 static size_t check_left_to_record(struct userdata
*u
, size_t n_bytes
) {
351 size_t left_to_record
;
352 size_t rec_space
= u
->hwbuf_size
- u
->hwbuf_unused
;
354 /* We use <= instead of < for this check here because an overrun
355 * only happens after the last sample was processed, not already when
356 * it is removed from the buffer. This is particularly important
357 * when block transfer is used. */
359 if (n_bytes
<= rec_space
) {
360 left_to_record
= rec_space
- n_bytes
;
363 pa_log_debug("%0.2f ms left to record", (double) pa_bytes_to_usec(left_to_record
, &u
->source
->sample_spec
) / PA_USEC_PER_MSEC
);
373 if (pa_log_ratelimit())
374 pa_log_info("Overrun!");
377 adjust_after_overrun(u
);
380 return left_to_record
;
383 static int mmap_read(struct userdata
*u
, pa_usec_t
*sleep_usec
, pa_bool_t polled
) {
384 pa_bool_t work_done
= FALSE
;
385 pa_usec_t max_sleep_usec
= 0, process_usec
= 0;
386 size_t left_to_record
;
390 pa_source_assert_ref(u
->source
);
393 hw_sleep_time(u
, &max_sleep_usec
, &process_usec
);
400 if (PA_UNLIKELY((n
= pa_alsa_safe_avail(u
->pcm_handle
, u
->hwbuf_size
, &u
->source
->sample_spec
)) < 0)) {
402 if ((r
= try_recover(u
, "snd_pcm_avail", (int) n
)) == 0)
408 n_bytes
= (size_t) n
* u
->frame_size
;
411 pa_log_debug("avail: %lu", (unsigned long) n_bytes
);
414 left_to_record
= check_left_to_record(u
, n_bytes
);
418 pa_bytes_to_usec(left_to_record
, &u
->source
->sample_spec
) > process_usec
+max_sleep_usec
/2) {
420 pa_log_debug("Not reading, because too early.");
425 if (PA_UNLIKELY(n_bytes
<= 0)) {
429 char *dn
= pa_alsa_get_driver_name_by_pcm(u
->pcm_handle
);
430 pa_log(_("ALSA woke us up to read new data from the device, but there was actually nothing to read!\n"
431 "Most likely this is a bug in the ALSA driver '%s'. Please report this issue to the ALSA developers.\n"
432 "We were woken up with POLLIN set -- however a subsequent snd_pcm_avail() returned 0 or another value < min_avail."),
438 pa_log_debug("Not reading, because not necessary.");
445 pa_log_debug("Not filling up, because already too many iterations.");
454 pa_log_debug("Reading");
459 const snd_pcm_channel_area_t
*areas
;
460 snd_pcm_uframes_t offset
, frames
;
463 snd_pcm_sframes_t sframes
;
465 frames
= (snd_pcm_uframes_t
) (n_bytes
/ u
->frame_size
);
467 /* pa_log_debug("%lu frames to read", (unsigned long) frames); */
469 if (PA_UNLIKELY((err
= pa_alsa_safe_mmap_begin(u
->pcm_handle
, &areas
, &offset
, &frames
, u
->hwbuf_size
, &u
->source
->sample_spec
)) < 0)) {
471 if ((r
= try_recover(u
, "snd_pcm_mmap_begin", err
)) == 0)
477 /* Make sure that if these memblocks need to be copied they will fit into one slot */
478 if (frames
> pa_mempool_block_size_max(u
->source
->core
->mempool
)/u
->frame_size
)
479 frames
= pa_mempool_block_size_max(u
->source
->core
->mempool
)/u
->frame_size
;
481 /* Check these are multiples of 8 bit */
482 pa_assert((areas
[0].first
& 7) == 0);
483 pa_assert((areas
[0].step
& 7)== 0);
485 /* We assume a single interleaved memory buffer */
486 pa_assert((areas
[0].first
>> 3) == 0);
487 pa_assert((areas
[0].step
>> 3) == u
->frame_size
);
489 p
= (uint8_t*) areas
[0].addr
+ (offset
* u
->frame_size
);
491 chunk
.memblock
= pa_memblock_new_fixed(u
->core
->mempool
, p
, frames
* u
->frame_size
, TRUE
);
492 chunk
.length
= pa_memblock_get_length(chunk
.memblock
);
495 pa_source_post(u
->source
, &chunk
);
496 pa_memblock_unref_fixed(chunk
.memblock
);
498 if (PA_UNLIKELY((sframes
= snd_pcm_mmap_commit(u
->pcm_handle
, offset
, frames
)) < 0)) {
500 if ((r
= try_recover(u
, "snd_pcm_mmap_commit", (int) sframes
)) == 0)
508 u
->read_count
+= frames
* u
->frame_size
;
511 pa_log_debug("Read %lu bytes (of possible %lu bytes)", (unsigned long) (frames
* u
->frame_size
), (unsigned long) n_bytes
);
514 if ((size_t) frames
* u
->frame_size
>= n_bytes
)
517 n_bytes
-= (size_t) frames
* u
->frame_size
;
521 *sleep_usec
= pa_bytes_to_usec(left_to_record
, &u
->source
->sample_spec
);
523 if (*sleep_usec
> process_usec
)
524 *sleep_usec
-= process_usec
;
528 return work_done
? 1 : 0;
531 static int unix_read(struct userdata
*u
, pa_usec_t
*sleep_usec
, pa_bool_t polled
) {
532 int work_done
= FALSE
;
533 pa_usec_t max_sleep_usec
= 0, process_usec
= 0;
534 size_t left_to_record
;
538 pa_source_assert_ref(u
->source
);
541 hw_sleep_time(u
, &max_sleep_usec
, &process_usec
);
548 if (PA_UNLIKELY((n
= pa_alsa_safe_avail(u
->pcm_handle
, u
->hwbuf_size
, &u
->source
->sample_spec
)) < 0)) {
550 if ((r
= try_recover(u
, "snd_pcm_avail", (int) n
)) == 0)
556 n_bytes
= (size_t) n
* u
->frame_size
;
557 left_to_record
= check_left_to_record(u
, n_bytes
);
561 pa_bytes_to_usec(left_to_record
, &u
->source
->sample_spec
) > process_usec
+max_sleep_usec
/2)
564 if (PA_UNLIKELY(n_bytes
<= 0)) {
568 char *dn
= pa_alsa_get_driver_name_by_pcm(u
->pcm_handle
);
569 pa_log(_("ALSA woke us up to read new data from the device, but there was actually nothing to read!\n"
570 "Most likely this is a bug in the ALSA driver '%s'. Please report this issue to the ALSA developers.\n"
571 "We were woken up with POLLIN set -- however a subsequent snd_pcm_avail() returned 0 or another value < min_avail."),
581 pa_log_debug("Not filling up, because already too many iterations.");
591 snd_pcm_sframes_t frames
;
594 chunk
.memblock
= pa_memblock_new(u
->core
->mempool
, (size_t) -1);
596 frames
= (snd_pcm_sframes_t
) (pa_memblock_get_length(chunk
.memblock
) / u
->frame_size
);
598 if (frames
> (snd_pcm_sframes_t
) (n_bytes
/u
->frame_size
))
599 frames
= (snd_pcm_sframes_t
) (n_bytes
/u
->frame_size
);
601 /* pa_log_debug("%lu frames to read", (unsigned long) n); */
603 p
= pa_memblock_acquire(chunk
.memblock
);
604 frames
= snd_pcm_readi(u
->pcm_handle
, (uint8_t*) p
, (snd_pcm_uframes_t
) frames
);
605 pa_memblock_release(chunk
.memblock
);
607 pa_assert(frames
!= 0);
609 if (PA_UNLIKELY(frames
< 0)) {
610 pa_memblock_unref(chunk
.memblock
);
612 if ((r
= try_recover(u
, "snd_pcm_readi", (int) (frames
))) == 0)
619 chunk
.length
= (size_t) frames
* u
->frame_size
;
621 pa_source_post(u
->source
, &chunk
);
622 pa_memblock_unref(chunk
.memblock
);
626 u
->read_count
+= frames
* u
->frame_size
;
628 /* pa_log_debug("read %lu frames", (unsigned long) frames); */
630 if ((size_t) frames
* u
->frame_size
>= n_bytes
)
633 n_bytes
-= (size_t) frames
* u
->frame_size
;
637 *sleep_usec
= pa_bytes_to_usec(left_to_record
, &u
->source
->sample_spec
);
639 if (*sleep_usec
> process_usec
)
640 *sleep_usec
-= process_usec
;
644 return work_done
? 1 : 0;
647 static void update_smoother(struct userdata
*u
) {
648 snd_pcm_sframes_t delay
= 0;
651 pa_usec_t now1
= 0, now2
;
652 snd_pcm_status_t
*status
;
654 snd_pcm_status_alloca(&status
);
657 pa_assert(u
->pcm_handle
);
659 /* Let's update the time smoother */
661 if (PA_UNLIKELY((err
= pa_alsa_safe_delay(u
->pcm_handle
, &delay
, u
->hwbuf_size
, &u
->source
->sample_spec
)) < 0)) {
662 pa_log_warn("Failed to get delay: %s", pa_alsa_strerror(err
));
666 if (PA_UNLIKELY((err
= snd_pcm_status(u
->pcm_handle
, status
)) < 0))
667 pa_log_warn("Failed to get timestamp: %s", pa_alsa_strerror(err
));
669 snd_htimestamp_t htstamp
= { 0, 0 };
670 snd_pcm_status_get_htstamp(status
, &htstamp
);
671 now1
= pa_timespec_load(&htstamp
);
674 position
= u
->read_count
+ ((uint64_t) delay
* (uint64_t) u
->frame_size
);
676 /* Hmm, if the timestamp is 0, then it wasn't set and we take the current time */
678 now1
= pa_rtclock_usec();
680 now2
= pa_bytes_to_usec(position
, &u
->source
->sample_spec
);
682 pa_smoother_put(u
->smoother
, now1
, now2
);
685 static pa_usec_t
source_get_latency(struct userdata
*u
) {
687 pa_usec_t now1
, now2
;
691 now1
= pa_rtclock_usec();
692 now2
= pa_smoother_get(u
->smoother
, now1
);
694 delay
= (int64_t) now2
- (int64_t) pa_bytes_to_usec(u
->read_count
, &u
->source
->sample_spec
);
696 return delay
>= 0 ? (pa_usec_t
) delay
: 0;
699 static int build_pollfd(struct userdata
*u
) {
701 pa_assert(u
->pcm_handle
);
703 if (u
->alsa_rtpoll_item
)
704 pa_rtpoll_item_free(u
->alsa_rtpoll_item
);
706 if (!(u
->alsa_rtpoll_item
= pa_alsa_build_pollfd(u
->pcm_handle
, u
->rtpoll
)))
712 static int suspend(struct userdata
*u
) {
714 pa_assert(u
->pcm_handle
);
716 pa_smoother_pause(u
->smoother
, pa_rtclock_usec());
719 snd_pcm_close(u
->pcm_handle
);
720 u
->pcm_handle
= NULL
;
722 if (u
->alsa_rtpoll_item
) {
723 pa_rtpoll_item_free(u
->alsa_rtpoll_item
);
724 u
->alsa_rtpoll_item
= NULL
;
727 pa_log_info("Device suspended...");
732 static int update_sw_params(struct userdata
*u
) {
733 snd_pcm_uframes_t avail_min
;
738 /* Use the full buffer if noone asked us for anything specific */
744 if ((latency
= pa_source_get_requested_latency_within_thread(u
->source
)) != (pa_usec_t
) -1) {
747 pa_log_debug("latency set to %0.2fms", (double) latency
/ PA_USEC_PER_MSEC
);
749 b
= pa_usec_to_bytes(latency
, &u
->source
->sample_spec
);
751 /* We need at least one sample in our buffer */
753 if (PA_UNLIKELY(b
< u
->frame_size
))
756 u
->hwbuf_unused
= PA_LIKELY(b
< u
->hwbuf_size
) ? (u
->hwbuf_size
- b
) : 0;
759 fix_min_sleep_wakeup(u
);
760 fix_tsched_watermark(u
);
763 pa_log_debug("hwbuf_unused=%lu", (unsigned long) u
->hwbuf_unused
);
768 pa_usec_t sleep_usec
, process_usec
;
770 hw_sleep_time(u
, &sleep_usec
, &process_usec
);
771 avail_min
+= pa_usec_to_bytes(sleep_usec
, &u
->source
->sample_spec
) / u
->frame_size
;
774 pa_log_debug("setting avail_min=%lu", (unsigned long) avail_min
);
776 if ((err
= pa_alsa_set_sw_params(u
->pcm_handle
, avail_min
)) < 0) {
777 pa_log("Failed to set software parameters: %s", pa_alsa_strerror(err
));
784 static int unsuspend(struct userdata
*u
) {
789 snd_pcm_uframes_t period_size
;
792 pa_assert(!u
->pcm_handle
);
794 pa_log_info("Trying resume...");
796 snd_config_update_free_global();
798 if ((err
= snd_pcm_open(&u
->pcm_handle
, u
->device_name
, SND_PCM_STREAM_CAPTURE
,
799 /*SND_PCM_NONBLOCK|*/
800 SND_PCM_NO_AUTO_RESAMPLE
|
801 SND_PCM_NO_AUTO_CHANNELS
|
802 SND_PCM_NO_AUTO_FORMAT
)) < 0) {
803 pa_log("Error opening PCM device %s: %s", u
->device_name
, pa_alsa_strerror(err
));
807 ss
= u
->source
->sample_spec
;
808 nfrags
= u
->nfragments
;
809 period_size
= u
->fragment_size
/ u
->frame_size
;
813 if ((err
= pa_alsa_set_hw_params(u
->pcm_handle
, &ss
, &nfrags
, &period_size
, u
->hwbuf_size
/ u
->frame_size
, &b
, &d
, TRUE
)) < 0) {
814 pa_log("Failed to set hardware parameters: %s", pa_alsa_strerror(err
));
818 if (b
!= u
->use_mmap
|| d
!= u
->use_tsched
) {
819 pa_log_warn("Resume failed, couldn't get original access mode.");
823 if (!pa_sample_spec_equal(&ss
, &u
->source
->sample_spec
)) {
824 pa_log_warn("Resume failed, couldn't restore original sample settings.");
828 if (nfrags
!= u
->nfragments
|| period_size
*u
->frame_size
!= u
->fragment_size
) {
829 pa_log_warn("Resume failed, couldn't restore original fragment settings. (Old: %lu*%lu, New %lu*%lu)",
830 (unsigned long) u
->nfragments
, (unsigned long) u
->fragment_size
,
831 (unsigned long) nfrags
, period_size
* u
->frame_size
);
835 if (update_sw_params(u
) < 0)
838 if (build_pollfd(u
) < 0)
841 /* FIXME: We need to reload the volume somehow */
843 snd_pcm_start(u
->pcm_handle
);
844 pa_smoother_resume(u
->smoother
, pa_rtclock_usec(), TRUE
);
846 pa_log_info("Resumed successfully...");
852 snd_pcm_close(u
->pcm_handle
);
853 u
->pcm_handle
= NULL
;
859 static int source_process_msg(pa_msgobject
*o
, int code
, void *data
, int64_t offset
, pa_memchunk
*chunk
) {
860 struct userdata
*u
= PA_SOURCE(o
)->userdata
;
864 case PA_SOURCE_MESSAGE_GET_LATENCY
: {
868 r
= source_get_latency(u
);
870 *((pa_usec_t
*) data
) = r
;
875 case PA_SOURCE_MESSAGE_SET_STATE
:
877 switch ((pa_source_state_t
) PA_PTR_TO_UINT(data
)) {
879 case PA_SOURCE_SUSPENDED
:
880 pa_assert(PA_SOURCE_IS_OPENED(u
->source
->thread_info
.state
));
888 case PA_SOURCE_RUNNING
:
890 if (u
->source
->thread_info
.state
== PA_SOURCE_INIT
) {
891 if (build_pollfd(u
) < 0)
894 snd_pcm_start(u
->pcm_handle
);
897 if (u
->source
->thread_info
.state
== PA_SOURCE_SUSPENDED
) {
898 if (unsuspend(u
) < 0)
904 case PA_SOURCE_UNLINKED
:
906 case PA_SOURCE_INVALID_STATE
:
913 return pa_source_process_msg(o
, code
, data
, offset
, chunk
);
916 /* Called from main context */
917 static int source_set_state_cb(pa_source
*s
, pa_source_state_t new_state
) {
918 pa_source_state_t old_state
;
921 pa_source_assert_ref(s
);
922 pa_assert_se(u
= s
->userdata
);
924 old_state
= pa_source_get_state(u
->source
);
926 if (PA_SINK_IS_OPENED(old_state
) && new_state
== PA_SINK_SUSPENDED
)
928 else if (old_state
== PA_SINK_SUSPENDED
&& PA_SINK_IS_OPENED(new_state
))
929 if (reserve_init(u
, u
->device_name
) < 0)
935 static int mixer_callback(snd_mixer_elem_t
*elem
, unsigned int mask
) {
936 struct userdata
*u
= snd_mixer_elem_get_callback_private(elem
);
939 pa_assert(u
->mixer_handle
);
941 if (mask
== SND_CTL_EVENT_MASK_REMOVE
)
944 if (mask
& SND_CTL_EVENT_MASK_VALUE
) {
945 pa_source_get_volume(u
->source
, TRUE
);
946 pa_source_get_mute(u
->source
, TRUE
);
952 static pa_volume_t
from_alsa_volume(struct userdata
*u
, long alsa_vol
) {
954 return (pa_volume_t
) round(((double) (alsa_vol
- u
->hw_volume_min
) * PA_VOLUME_NORM
) /
955 (double) (u
->hw_volume_max
- u
->hw_volume_min
));
958 static long to_alsa_volume(struct userdata
*u
, pa_volume_t vol
) {
961 alsa_vol
= (long) round(((double) vol
* (double) (u
->hw_volume_max
- u
->hw_volume_min
))
962 / PA_VOLUME_NORM
) + u
->hw_volume_min
;
964 return PA_CLAMP_UNLIKELY(alsa_vol
, u
->hw_volume_min
, u
->hw_volume_max
);
967 static void source_get_volume_cb(pa_source
*s
) {
968 struct userdata
*u
= s
->userdata
;
972 char t
[PA_CVOLUME_SNPRINT_MAX
];
975 pa_assert(u
->mixer_elem
);
977 if (u
->mixer_seperate_channels
) {
979 r
.channels
= s
->sample_spec
.channels
;
981 for (i
= 0; i
< s
->sample_spec
.channels
; i
++) {
984 if (u
->hw_dB_supported
) {
986 if ((err
= snd_mixer_selem_get_capture_dB(u
->mixer_elem
, u
->mixer_map
[i
], &alsa_vol
)) < 0)
989 #ifdef HAVE_VALGRIND_MEMCHECK_H
990 VALGRIND_MAKE_MEM_DEFINED(&alsa_vol
, sizeof(alsa_vol
));
993 r
.values
[i
] = pa_sw_volume_from_dB((double) (alsa_vol
- u
->hw_dB_max
) / 100.0);
996 if ((err
= snd_mixer_selem_get_capture_volume(u
->mixer_elem
, u
->mixer_map
[i
], &alsa_vol
)) < 0)
999 r
.values
[i
] = from_alsa_volume(u
, alsa_vol
);
1006 if (u
->hw_dB_supported
) {
1008 if ((err
= snd_mixer_selem_get_capture_dB(u
->mixer_elem
, SND_MIXER_SCHN_MONO
, &alsa_vol
)) < 0)
1011 #ifdef HAVE_VALGRIND_MEMCHECK_H
1012 VALGRIND_MAKE_MEM_DEFINED(&alsa_vol
, sizeof(alsa_vol
));
1015 pa_cvolume_set(&r
, s
->sample_spec
.channels
, pa_sw_volume_from_dB((double) (alsa_vol
- u
->hw_dB_max
) / 100.0));
1019 if ((err
= snd_mixer_selem_get_capture_volume(u
->mixer_elem
, SND_MIXER_SCHN_MONO
, &alsa_vol
)) < 0)
1022 pa_cvolume_set(&r
, s
->sample_spec
.channels
, from_alsa_volume(u
, alsa_vol
));
1026 pa_log_debug("Read hardware volume: %s", pa_cvolume_snprint(t
, sizeof(t
), &r
));
1028 if (!pa_cvolume_equal(&u
->hardware_volume
, &r
)) {
1030 s
->virtual_volume
= u
->hardware_volume
= r
;
1032 if (u
->hw_dB_supported
) {
1035 /* Hmm, so the hardware volume changed, let's reset our software volume */
1036 pa_cvolume_reset(&reset
, s
->sample_spec
.channels
);
1037 pa_source_set_soft_volume(s
, &reset
);
1044 pa_log_error("Unable to read volume: %s", pa_alsa_strerror(err
));
1047 static void source_set_volume_cb(pa_source
*s
) {
1048 struct userdata
*u
= s
->userdata
;
1054 pa_assert(u
->mixer_elem
);
1056 if (u
->mixer_seperate_channels
) {
1058 r
.channels
= s
->sample_spec
.channels
;
1060 for (i
= 0; i
< s
->sample_spec
.channels
; i
++) {
1064 vol
= s
->virtual_volume
.values
[i
];
1066 if (u
->hw_dB_supported
) {
1068 alsa_vol
= (long) (pa_sw_volume_to_dB(vol
) * 100);
1069 alsa_vol
+= u
->hw_dB_max
;
1070 alsa_vol
= PA_CLAMP_UNLIKELY(alsa_vol
, u
->hw_dB_min
, u
->hw_dB_max
);
1072 if ((err
= snd_mixer_selem_set_capture_dB(u
->mixer_elem
, u
->mixer_map
[i
], alsa_vol
, 1)) < 0)
1075 if ((err
= snd_mixer_selem_get_capture_dB(u
->mixer_elem
, u
->mixer_map
[i
], &alsa_vol
)) < 0)
1078 #ifdef HAVE_VALGRIND_MEMCHECK_H
1079 VALGRIND_MAKE_MEM_DEFINED(&alsa_vol
, sizeof(alsa_vol
));
1082 r
.values
[i
] = pa_sw_volume_from_dB((double) (alsa_vol
- u
->hw_dB_max
) / 100.0);
1085 alsa_vol
= to_alsa_volume(u
, vol
);
1087 if ((err
= snd_mixer_selem_set_capture_volume(u
->mixer_elem
, u
->mixer_map
[i
], alsa_vol
)) < 0)
1090 if ((err
= snd_mixer_selem_get_capture_volume(u
->mixer_elem
, u
->mixer_map
[i
], &alsa_vol
)) < 0)
1093 r
.values
[i
] = from_alsa_volume(u
, alsa_vol
);
1101 vol
= pa_cvolume_max(&s
->virtual_volume
);
1103 if (u
->hw_dB_supported
) {
1104 alsa_vol
= (long) (pa_sw_volume_to_dB(vol
) * 100);
1105 alsa_vol
+= u
->hw_dB_max
;
1106 alsa_vol
= PA_CLAMP_UNLIKELY(alsa_vol
, u
->hw_dB_min
, u
->hw_dB_max
);
1108 if ((err
= snd_mixer_selem_set_capture_dB_all(u
->mixer_elem
, alsa_vol
, 1)) < 0)
1111 if ((err
= snd_mixer_selem_get_capture_dB(u
->mixer_elem
, SND_MIXER_SCHN_MONO
, &alsa_vol
)) < 0)
1114 #ifdef HAVE_VALGRIND_MEMCHECK_H
1115 VALGRIND_MAKE_MEM_DEFINED(&alsa_vol
, sizeof(alsa_vol
));
1118 pa_cvolume_set(&r
, s
->sample_spec
.channels
, pa_sw_volume_from_dB((double) (alsa_vol
- u
->hw_dB_max
) / 100.0));
1121 alsa_vol
= to_alsa_volume(u
, vol
);
1123 if ((err
= snd_mixer_selem_set_capture_volume_all(u
->mixer_elem
, alsa_vol
)) < 0)
1126 if ((err
= snd_mixer_selem_get_capture_volume(u
->mixer_elem
, SND_MIXER_SCHN_MONO
, &alsa_vol
)) < 0)
1129 pa_cvolume_set(&r
, s
->sample_spec
.channels
, from_alsa_volume(u
, alsa_vol
));
1133 u
->hardware_volume
= r
;
1135 if (u
->hw_dB_supported
) {
1136 char t
[PA_CVOLUME_SNPRINT_MAX
];
1138 /* Match exactly what the user requested by software */
1140 pa_sw_cvolume_divide(&s
->soft_volume
, &s
->virtual_volume
, &u
->hardware_volume
);
1142 pa_log_debug("Requested volume: %s", pa_cvolume_snprint(t
, sizeof(t
), &s
->virtual_volume
));
1143 pa_log_debug("Got hardware volume: %s", pa_cvolume_snprint(t
, sizeof(t
), &u
->hardware_volume
));
1144 pa_log_debug("Calculated software volume: %s", pa_cvolume_snprint(t
, sizeof(t
), &s
->soft_volume
));
1148 /* We can't match exactly what the user requested, hence let's
1149 * at least tell the user about it */
1151 s
->virtual_volume
= r
;
1156 pa_log_error("Unable to set volume: %s", pa_alsa_strerror(err
));
1159 static void source_get_mute_cb(pa_source
*s
) {
1160 struct userdata
*u
= s
->userdata
;
1164 pa_assert(u
->mixer_elem
);
1166 if ((err
= snd_mixer_selem_get_capture_switch(u
->mixer_elem
, 0, &sw
)) < 0) {
1167 pa_log_error("Unable to get switch: %s", pa_alsa_strerror(err
));
1174 static void source_set_mute_cb(pa_source
*s
) {
1175 struct userdata
*u
= s
->userdata
;
1179 pa_assert(u
->mixer_elem
);
1181 if ((err
= snd_mixer_selem_set_capture_switch_all(u
->mixer_elem
, !s
->muted
)) < 0) {
1182 pa_log_error("Unable to set switch: %s", pa_alsa_strerror(err
));
1187 static void source_update_requested_latency_cb(pa_source
*s
) {
1188 struct userdata
*u
= s
->userdata
;
1194 update_sw_params(u
);
1197 static void thread_func(void *userdata
) {
1198 struct userdata
*u
= userdata
;
1199 unsigned short revents
= 0;
1203 pa_log_debug("Thread starting up");
1205 if (u
->core
->realtime_scheduling
)
1206 pa_make_realtime(u
->core
->realtime_priority
);
1208 pa_thread_mq_install(&u
->thread_mq
);
1209 pa_rtpoll_install(u
->rtpoll
);
1215 pa_log_debug("Loop");
1218 /* Read some data and pass it to the sources */
1219 if (PA_SOURCE_IS_OPENED(u
->source
->thread_info
.state
)) {
1221 pa_usec_t sleep_usec
= 0;
1224 work_done
= mmap_read(u
, &sleep_usec
, revents
& POLLIN
);
1226 work_done
= unix_read(u
, &sleep_usec
, revents
& POLLIN
);
1231 /* pa_log_debug("work_done = %i", work_done); */
1236 if (u
->use_tsched
) {
1239 /* OK, the capture buffer is now empty, let's
1240 * calculate when to wake up next */
1242 /* pa_log_debug("Waking up in %0.2fms (sound card clock).", (double) sleep_usec / PA_USEC_PER_MSEC); */
1244 /* Convert from the sound card time domain to the
1245 * system time domain */
1246 cusec
= pa_smoother_translate(u
->smoother
, pa_rtclock_usec(), sleep_usec
);
1248 /* pa_log_debug("Waking up in %0.2fms (system clock).", (double) cusec / PA_USEC_PER_MSEC); */
1250 /* We don't trust the conversion, so we wake up whatever comes first */
1251 pa_rtpoll_set_timer_relative(u
->rtpoll
, PA_MIN(sleep_usec
, cusec
));
1253 } else if (u
->use_tsched
)
1255 /* OK, we're in an invalid state, let's disable our timers */
1256 pa_rtpoll_set_timer_disabled(u
->rtpoll
);
1258 /* Hmm, nothing to do. Let's sleep */
1259 if ((ret
= pa_rtpoll_run(u
->rtpoll
, TRUE
)) < 0)
1265 /* Tell ALSA about this and process its response */
1266 if (PA_SOURCE_IS_OPENED(u
->source
->thread_info
.state
)) {
1267 struct pollfd
*pollfd
;
1271 pollfd
= pa_rtpoll_item_get_pollfd(u
->alsa_rtpoll_item
, &n
);
1273 if ((err
= snd_pcm_poll_descriptors_revents(u
->pcm_handle
, pollfd
, n
, &revents
)) < 0) {
1274 pa_log("snd_pcm_poll_descriptors_revents() failed: %s", pa_alsa_strerror(err
));
1278 if (revents
& ~POLLIN
) {
1279 if (pa_alsa_recover_from_poll(u
->pcm_handle
, revents
) < 0)
1282 snd_pcm_start(u
->pcm_handle
);
1283 } else if (revents
&& u
->use_tsched
&& pa_log_ratelimit())
1284 pa_log_debug("Wakeup from ALSA!");
1291 /* If this was no regular exit from the loop we have to continue
1292 * processing messages until we received PA_MESSAGE_SHUTDOWN */
1293 pa_asyncmsgq_post(u
->thread_mq
.outq
, PA_MSGOBJECT(u
->core
), PA_CORE_MESSAGE_UNLOAD_MODULE
, u
->module
, 0, NULL
, NULL
);
1294 pa_asyncmsgq_wait_for(u
->thread_mq
.inq
, PA_MESSAGE_SHUTDOWN
);
1297 pa_log_debug("Thread shutting down");
1300 static void set_source_name(pa_source_new_data
*data
, pa_modargs
*ma
, const char *device_id
, const char *device_name
) {
1306 pa_assert(device_name
);
1308 if ((n
= pa_modargs_get_value(ma
, "source_name", NULL
))) {
1309 pa_source_new_data_set_name(data
, n
);
1310 data
->namereg_fail
= TRUE
;
1314 if ((n
= pa_modargs_get_value(ma
, "name", NULL
)))
1315 data
->namereg_fail
= TRUE
;
1317 n
= device_id
? device_id
: device_name
;
1318 data
->namereg_fail
= FALSE
;
1321 t
= pa_sprintf_malloc("alsa_input.%s", n
);
1322 pa_source_new_data_set_name(data
, t
);
1326 static int setup_mixer(struct userdata
*u
, pa_bool_t ignore_dB
) {
1329 if (!u
->mixer_handle
)
1332 pa_assert(u
->mixer_elem
);
1334 if (snd_mixer_selem_has_capture_volume(u
->mixer_elem
)) {
1335 pa_bool_t suitable
= FALSE
;
1337 if (snd_mixer_selem_get_capture_volume_range(u
->mixer_elem
, &u
->hw_volume_min
, &u
->hw_volume_max
) < 0)
1338 pa_log_info("Failed to get volume range. Falling back to software volume control.");
1339 else if (u
->hw_volume_min
>= u
->hw_volume_max
)
1340 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
);
1342 pa_log_info("Volume ranges from %li to %li.", u
->hw_volume_min
, u
->hw_volume_max
);
1347 if (ignore_dB
|| snd_mixer_selem_get_capture_dB_range(u
->mixer_elem
, &u
->hw_dB_min
, &u
->hw_dB_max
) < 0)
1348 pa_log_info("Mixer doesn't support dB information or data is ignored.");
1350 #ifdef HAVE_VALGRIND_MEMCHECK_H
1351 VALGRIND_MAKE_MEM_DEFINED(&u
->hw_dB_min
, sizeof(u
->hw_dB_min
));
1352 VALGRIND_MAKE_MEM_DEFINED(&u
->hw_dB_max
, sizeof(u
->hw_dB_max
));
1355 if (u
->hw_dB_min
>= u
->hw_dB_max
)
1356 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);
1358 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);
1359 u
->hw_dB_supported
= TRUE
;
1361 if (u
->hw_dB_max
> 0) {
1362 u
->source
->base_volume
= pa_sw_volume_from_dB(- (double) u
->hw_dB_max
/100.0);
1363 pa_log_info("Fixing base volume to %0.2f dB", pa_sw_volume_to_dB(u
->source
->base_volume
));
1365 pa_log_info("No particular base volume set, fixing to 0 dB");
1369 if (!u
->hw_dB_supported
&&
1370 u
->hw_volume_max
- u
->hw_volume_min
< 3) {
1372 pa_log_info("Device has less than 4 volume levels. Falling back to software volume control.");
1378 u
->mixer_seperate_channels
= pa_alsa_calc_mixer_map(u
->mixer_elem
, &u
->source
->channel_map
, u
->mixer_map
, FALSE
) >= 0;
1380 u
->source
->get_volume
= source_get_volume_cb
;
1381 u
->source
->set_volume
= source_set_volume_cb
;
1382 u
->source
->flags
|= PA_SOURCE_HW_VOLUME_CTRL
| (u
->hw_dB_supported
? PA_SOURCE_DECIBEL_VOLUME
: 0);
1383 pa_log_info("Using hardware volume control. Hardware dB scale %s.", u
->hw_dB_supported
? "supported" : "not supported");
1385 if (!u
->hw_dB_supported
)
1386 u
->source
->n_volume_steps
= u
->hw_volume_max
- u
->hw_volume_min
+ 1;
1388 pa_log_info("Using software volume control.");
1391 if (snd_mixer_selem_has_capture_switch(u
->mixer_elem
)) {
1392 u
->source
->get_mute
= source_get_mute_cb
;
1393 u
->source
->set_mute
= source_set_mute_cb
;
1394 u
->source
->flags
|= PA_SOURCE_HW_MUTE_CTRL
;
1396 pa_log_info("Using software mute control.");
1398 u
->mixer_fdl
= pa_alsa_fdlist_new();
1400 if (pa_alsa_fdlist_set_mixer(u
->mixer_fdl
, u
->mixer_handle
, u
->core
->mainloop
) < 0) {
1401 pa_log("Failed to initialize file descriptor monitoring");
1405 snd_mixer_elem_set_callback(u
->mixer_elem
, mixer_callback
);
1406 snd_mixer_elem_set_callback_private(u
->mixer_elem
, u
);
1411 pa_source
*pa_alsa_source_new(pa_module
*m
, pa_modargs
*ma
, const char*driver
, pa_card
*card
, const pa_alsa_profile_info
*profile
) {
1413 struct userdata
*u
= NULL
;
1414 const char *dev_id
= NULL
;
1415 pa_sample_spec ss
, requested_ss
;
1417 uint32_t nfrags
, hwbuf_size
, frag_size
, tsched_size
, tsched_watermark
;
1418 snd_pcm_uframes_t period_frames
, tsched_frames
;
1420 pa_bool_t use_mmap
= TRUE
, b
, use_tsched
= TRUE
, d
, ignore_dB
= FALSE
;
1421 pa_source_new_data data
;
1422 char *control_device
= NULL
;
1427 ss
= m
->core
->default_sample_spec
;
1428 map
= m
->core
->default_channel_map
;
1429 if (pa_modargs_get_sample_spec_and_channel_map(ma
, &ss
, &map
, PA_CHANNEL_MAP_ALSA
) < 0) {
1430 pa_log("Failed to parse sample specification");
1435 frame_size
= pa_frame_size(&ss
);
1437 nfrags
= m
->core
->default_n_fragments
;
1438 frag_size
= (uint32_t) pa_usec_to_bytes(m
->core
->default_fragment_size_msec
*PA_USEC_PER_MSEC
, &ss
);
1440 frag_size
= (uint32_t) frame_size
;
1441 tsched_size
= (uint32_t) pa_usec_to_bytes(DEFAULT_TSCHED_BUFFER_USEC
, &ss
);
1442 tsched_watermark
= (uint32_t) pa_usec_to_bytes(DEFAULT_TSCHED_WATERMARK_USEC
, &ss
);
1444 if (pa_modargs_get_value_u32(ma
, "fragments", &nfrags
) < 0 ||
1445 pa_modargs_get_value_u32(ma
, "fragment_size", &frag_size
) < 0 ||
1446 pa_modargs_get_value_u32(ma
, "tsched_buffer_size", &tsched_size
) < 0 ||
1447 pa_modargs_get_value_u32(ma
, "tsched_buffer_watermark", &tsched_watermark
) < 0) {
1448 pa_log("Failed to parse buffer metrics");
1452 hwbuf_size
= frag_size
* nfrags
;
1453 period_frames
= frag_size
/frame_size
;
1454 tsched_frames
= tsched_size
/frame_size
;
1456 if (pa_modargs_get_value_boolean(ma
, "mmap", &use_mmap
) < 0) {
1457 pa_log("Failed to parse mmap argument.");
1461 if (pa_modargs_get_value_boolean(ma
, "tsched", &use_tsched
) < 0) {
1462 pa_log("Failed to parse timer_scheduling argument.");
1466 if (pa_modargs_get_value_boolean(ma
, "ignore_dB", &ignore_dB
) < 0) {
1467 pa_log("Failed to parse ignore_dB argument.");
1471 if (use_tsched
&& !pa_rtclock_hrtimer()) {
1472 pa_log_notice("Disabling timer-based scheduling because high-resolution timers are not available from the kernel.");
1476 u
= pa_xnew0(struct userdata
, 1);
1479 u
->use_mmap
= use_mmap
;
1480 u
->use_tsched
= use_tsched
;
1481 u
->rtpoll
= pa_rtpoll_new();
1482 pa_thread_mq_init(&u
->thread_mq
, m
->core
->mainloop
, u
->rtpoll
);
1483 u
->alsa_rtpoll_item
= NULL
;
1485 u
->smoother
= pa_smoother_new(
1486 DEFAULT_TSCHED_WATERMARK_USEC
*2,
1487 DEFAULT_TSCHED_WATERMARK_USEC
*2,
1494 dev_id
= pa_modargs_get_value(
1496 pa_modargs_get_value(ma
, "device", DEFAULT_DEVICE
));
1498 if (reserve_init(u
, dev_id
) < 0)
1501 if (reserve_monitor_init(u
, dev_id
) < 0)
1509 if (!(dev_id
= pa_modargs_get_value(ma
, "device_id", NULL
))) {
1510 pa_log("device_id= not set");
1514 if (!(u
->pcm_handle
= pa_alsa_open_by_device_id_profile(
1518 SND_PCM_STREAM_CAPTURE
,
1519 &nfrags
, &period_frames
, tsched_frames
,
1523 } else if ((dev_id
= pa_modargs_get_value(ma
, "device_id", NULL
))) {
1525 if (!(u
->pcm_handle
= pa_alsa_open_by_device_id_auto(
1529 SND_PCM_STREAM_CAPTURE
,
1530 &nfrags
, &period_frames
, tsched_frames
,
1536 if (!(u
->pcm_handle
= pa_alsa_open_by_device_string(
1537 pa_modargs_get_value(ma
, "device", DEFAULT_DEVICE
),
1540 SND_PCM_STREAM_CAPTURE
,
1541 &nfrags
, &period_frames
, tsched_frames
,
1546 pa_assert(u
->device_name
);
1547 pa_log_info("Successfully opened device %s.", u
->device_name
);
1549 if (pa_alsa_pcm_is_modem(u
->pcm_handle
)) {
1550 pa_log_notice("Device %s is modem, refusing further initialization.", u
->device_name
);
1555 pa_log_info("Selected configuration '%s' (%s).", profile
->description
, profile
->name
);
1557 if (use_mmap
&& !b
) {
1558 pa_log_info("Device doesn't support mmap(), falling back to UNIX read/write mode.");
1559 u
->use_mmap
= use_mmap
= FALSE
;
1562 if (use_tsched
&& (!b
|| !d
)) {
1563 pa_log_info("Cannot enable timer-based scheduling, falling back to sound IRQ scheduling.");
1564 u
->use_tsched
= use_tsched
= FALSE
;
1567 if (use_tsched
&& !pa_alsa_pcm_is_hw(u
->pcm_handle
)) {
1568 pa_log_info("Device is not a hardware device, disabling timer-based scheduling.");
1569 u
->use_tsched
= use_tsched
= FALSE
;
1573 pa_log_info("Successfully enabled mmap() mode.");
1576 pa_log_info("Successfully enabled timer-based scheduling mode.");
1578 /* ALSA might tweak the sample spec, so recalculate the frame size */
1579 frame_size
= pa_frame_size(&ss
);
1581 pa_alsa_find_mixer_and_elem(u
->pcm_handle
, &control_device
, &u
->mixer_handle
, &u
->mixer_elem
, pa_modargs_get_value(ma
, "control", NULL
), profile
);
1583 pa_source_new_data_init(&data
);
1584 data
.driver
= driver
;
1587 set_source_name(&data
, ma
, dev_id
, u
->device_name
);
1588 pa_source_new_data_set_sample_spec(&data
, &ss
);
1589 pa_source_new_data_set_channel_map(&data
, &map
);
1591 pa_alsa_init_proplist_pcm(m
->core
, data
.proplist
, u
->pcm_handle
, u
->mixer_elem
);
1592 pa_proplist_sets(data
.proplist
, PA_PROP_DEVICE_STRING
, u
->device_name
);
1593 pa_proplist_setf(data
.proplist
, PA_PROP_DEVICE_BUFFERING_BUFFER_SIZE
, "%lu", (unsigned long) (period_frames
* frame_size
* nfrags
));
1594 pa_proplist_setf(data
.proplist
, PA_PROP_DEVICE_BUFFERING_FRAGMENT_SIZE
, "%lu", (unsigned long) (period_frames
* frame_size
));
1595 pa_proplist_sets(data
.proplist
, PA_PROP_DEVICE_ACCESS_MODE
, u
->use_tsched
? "mmap+timer" : (u
->use_mmap
? "mmap" : "serial"));
1598 pa_proplist_sets(data
.proplist
, PA_PROP_DEVICE_PROFILE_NAME
, profile
->name
);
1599 pa_proplist_sets(data
.proplist
, PA_PROP_DEVICE_PROFILE_DESCRIPTION
, profile
->description
);
1602 pa_alsa_init_description(data
.proplist
);
1604 if (control_device
) {
1605 pa_alsa_init_proplist_ctl(data
.proplist
, control_device
);
1606 pa_xfree(control_device
);
1609 if (pa_modargs_get_proplist(ma
, "source_properties", data
.proplist
, PA_UPDATE_REPLACE
) < 0) {
1610 pa_log("Invalid properties");
1611 pa_source_new_data_done(&data
);
1615 u
->source
= pa_source_new(m
->core
, &data
, PA_SOURCE_HARDWARE
|PA_SOURCE_LATENCY
|(u
->use_tsched
? PA_SOURCE_DYNAMIC_LATENCY
: 0));
1616 pa_source_new_data_done(&data
);
1619 pa_log("Failed to create source object");
1623 u
->source
->parent
.process_msg
= source_process_msg
;
1624 u
->source
->update_requested_latency
= source_update_requested_latency_cb
;
1625 u
->source
->set_state
= source_set_state_cb
;
1626 u
->source
->userdata
= u
;
1628 pa_source_set_asyncmsgq(u
->source
, u
->thread_mq
.inq
);
1629 pa_source_set_rtpoll(u
->source
, u
->rtpoll
);
1631 u
->frame_size
= frame_size
;
1632 u
->fragment_size
= frag_size
= (uint32_t) (period_frames
* frame_size
);
1633 u
->nfragments
= nfrags
;
1634 u
->hwbuf_size
= u
->fragment_size
* nfrags
;
1635 u
->tsched_watermark
= pa_usec_to_bytes_round_up(pa_bytes_to_usec_round_up(tsched_watermark
, &requested_ss
), &u
->source
->sample_spec
);
1636 pa_cvolume_mute(&u
->hardware_volume
, u
->source
->sample_spec
.channels
);
1638 pa_log_info("Using %u fragments of size %lu bytes, buffer time is %0.2fms",
1639 nfrags
, (long unsigned) u
->fragment_size
,
1640 (double) pa_bytes_to_usec(u
->hwbuf_size
, &ss
) / PA_USEC_PER_MSEC
);
1642 if (u
->use_tsched
) {
1643 u
->watermark_step
= pa_usec_to_bytes(TSCHED_WATERMARK_STEP_USEC
, &u
->source
->sample_spec
);
1645 fix_min_sleep_wakeup(u
);
1646 fix_tsched_watermark(u
);
1648 pa_source_set_latency_range(u
->source
,
1650 pa_bytes_to_usec(u
->hwbuf_size
, &ss
));
1652 pa_log_info("Time scheduling watermark is %0.2fms",
1653 (double) pa_bytes_to_usec(u
->tsched_watermark
, &ss
) / PA_USEC_PER_MSEC
);
1655 pa_source_set_fixed_latency(u
->source
, pa_bytes_to_usec(u
->hwbuf_size
, &ss
));
1659 if (update_sw_params(u
) < 0)
1662 if (setup_mixer(u
, ignore_dB
) < 0)
1665 pa_alsa_dump(PA_LOG_DEBUG
, u
->pcm_handle
);
1667 if (!(u
->thread
= pa_thread_new(thread_func
, u
))) {
1668 pa_log("Failed to create thread.");
1671 /* Get initial mixer settings */
1672 if (data
.volume_is_set
) {
1673 if (u
->source
->set_volume
)
1674 u
->source
->set_volume(u
->source
);
1676 if (u
->source
->get_volume
)
1677 u
->source
->get_volume(u
->source
);
1680 if (data
.muted_is_set
) {
1681 if (u
->source
->set_mute
)
1682 u
->source
->set_mute(u
->source
);
1684 if (u
->source
->get_mute
)
1685 u
->source
->get_mute(u
->source
);
1688 pa_source_put(u
->source
);
1700 static void userdata_free(struct userdata
*u
) {
1704 pa_source_unlink(u
->source
);
1707 pa_asyncmsgq_send(u
->thread_mq
.inq
, NULL
, PA_MESSAGE_SHUTDOWN
, NULL
, 0, NULL
);
1708 pa_thread_free(u
->thread
);
1711 pa_thread_mq_done(&u
->thread_mq
);
1714 pa_source_unref(u
->source
);
1716 if (u
->alsa_rtpoll_item
)
1717 pa_rtpoll_item_free(u
->alsa_rtpoll_item
);
1720 pa_rtpoll_free(u
->rtpoll
);
1723 pa_alsa_fdlist_free(u
->mixer_fdl
);
1725 if (u
->mixer_handle
)
1726 snd_mixer_close(u
->mixer_handle
);
1728 if (u
->pcm_handle
) {
1729 snd_pcm_drop(u
->pcm_handle
);
1730 snd_pcm_close(u
->pcm_handle
);
1734 pa_smoother_free(u
->smoother
);
1739 pa_xfree(u
->device_name
);
1743 void pa_alsa_source_free(pa_source
*s
) {
1746 pa_source_assert_ref(s
);
1747 pa_assert_se(u
= s
->userdata
);