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 #include <pulse/i18n.h>
32 #include <pulse/rtclock.h>
33 #include <pulse/timeval.h>
34 #include <pulse/util.h>
35 #include <pulse/xmalloc.h>
37 #include <pulsecore/core-error.h>
38 #include <pulsecore/core.h>
39 #include <pulsecore/module.h>
40 #include <pulsecore/memchunk.h>
41 #include <pulsecore/sink.h>
42 #include <pulsecore/modargs.h>
43 #include <pulsecore/core-rtclock.h>
44 #include <pulsecore/core-util.h>
45 #include <pulsecore/sample-util.h>
46 #include <pulsecore/log.h>
47 #include <pulsecore/macro.h>
48 #include <pulsecore/thread.h>
49 #include <pulsecore/core-error.h>
50 #include <pulsecore/thread-mq.h>
51 #include <pulsecore/rtpoll.h>
52 #include <pulsecore/time-smoother.h>
54 #include <modules/reserve-wrap.h>
56 #include "alsa-util.h"
57 #include "alsa-source.h"
59 /* #define DEBUG_TIMING */
61 #define DEFAULT_DEVICE "default"
62 #define DEFAULT_TSCHED_BUFFER_USEC (2*PA_USEC_PER_SEC) /* 2s */
63 #define DEFAULT_TSCHED_WATERMARK_USEC (20*PA_USEC_PER_MSEC) /* 20ms */
64 #define TSCHED_WATERMARK_STEP_USEC (10*PA_USEC_PER_MSEC) /* 10ms */
65 #define TSCHED_MIN_SLEEP_USEC (10*PA_USEC_PER_MSEC) /* 10ms */
66 #define TSCHED_MIN_WAKEUP_USEC (4*PA_USEC_PER_MSEC) /* 4ms */
74 pa_thread_mq thread_mq
;
77 snd_pcm_t
*pcm_handle
;
79 pa_alsa_fdlist
*mixer_fdl
;
80 snd_mixer_t
*mixer_handle
;
81 pa_alsa_path_set
*mixer_path_set
;
82 pa_alsa_path
*mixer_path
;
84 pa_cvolume hardware_volume
;
101 pa_bool_t use_mmap
:1, use_tsched
:1;
103 pa_rtpoll_item
*alsa_rtpoll_item
;
105 snd_mixer_selem_channel_id_t mixer_map
[SND_MIXER_SCHN_LAST
];
107 pa_smoother
*smoother
;
110 pa_reserve_wrapper
*reserve
;
111 pa_hook_slot
*reserve_slot
;
112 pa_reserve_monitor_wrapper
*monitor
;
113 pa_hook_slot
*monitor_slot
;
116 static void userdata_free(struct userdata
*u
);
118 static pa_hook_result_t
reserve_cb(pa_reserve_wrapper
*r
, void *forced
, struct userdata
*u
) {
122 if (pa_source_suspend(u
->source
, TRUE
, PA_SUSPEND_APPLICATION
) < 0)
123 return PA_HOOK_CANCEL
;
128 static void reserve_done(struct userdata
*u
) {
131 if (u
->reserve_slot
) {
132 pa_hook_slot_free(u
->reserve_slot
);
133 u
->reserve_slot
= NULL
;
137 pa_reserve_wrapper_unref(u
->reserve
);
142 static void reserve_update(struct userdata
*u
) {
143 const char *description
;
146 if (!u
->source
|| !u
->reserve
)
149 if ((description
= pa_proplist_gets(u
->source
->proplist
, PA_PROP_DEVICE_DESCRIPTION
)))
150 pa_reserve_wrapper_set_application_device_name(u
->reserve
, description
);
153 static int reserve_init(struct userdata
*u
, const char *dname
) {
162 if (pa_in_system_mode())
165 /* We are resuming, try to lock the device */
166 if (!(rname
= pa_alsa_get_reserve_name(dname
)))
169 u
->reserve
= pa_reserve_wrapper_get(u
->core
, rname
);
177 pa_assert(!u
->reserve_slot
);
178 u
->reserve_slot
= pa_hook_connect(pa_reserve_wrapper_hook(u
->reserve
), PA_HOOK_NORMAL
, (pa_hook_cb_t
) reserve_cb
, u
);
183 static pa_hook_result_t
monitor_cb(pa_reserve_monitor_wrapper
*w
, void* busy
, struct userdata
*u
) {
189 b
= PA_PTR_TO_UINT(busy
) && !u
->reserve
;
191 pa_source_suspend(u
->source
, b
, PA_SUSPEND_APPLICATION
);
195 static void monitor_done(struct userdata
*u
) {
198 if (u
->monitor_slot
) {
199 pa_hook_slot_free(u
->monitor_slot
);
200 u
->monitor_slot
= NULL
;
204 pa_reserve_monitor_wrapper_unref(u
->monitor
);
209 static int reserve_monitor_init(struct userdata
*u
, const char *dname
) {
215 if (pa_in_system_mode())
218 /* We are resuming, try to lock the device */
219 if (!(rname
= pa_alsa_get_reserve_name(dname
)))
222 u
->monitor
= pa_reserve_monitor_wrapper_get(u
->core
, rname
);
228 pa_assert(!u
->monitor_slot
);
229 u
->monitor_slot
= pa_hook_connect(pa_reserve_monitor_wrapper_hook(u
->monitor
), PA_HOOK_NORMAL
, (pa_hook_cb_t
) monitor_cb
, u
);
234 static void fix_min_sleep_wakeup(struct userdata
*u
) {
235 size_t max_use
, max_use_2
;
238 max_use
= u
->hwbuf_size
- u
->hwbuf_unused
;
239 max_use_2
= pa_frame_align(max_use
/2, &u
->source
->sample_spec
);
241 u
->min_sleep
= pa_usec_to_bytes(TSCHED_MIN_SLEEP_USEC
, &u
->source
->sample_spec
);
242 u
->min_sleep
= PA_CLAMP(u
->min_sleep
, u
->frame_size
, max_use_2
);
244 u
->min_wakeup
= pa_usec_to_bytes(TSCHED_MIN_WAKEUP_USEC
, &u
->source
->sample_spec
);
245 u
->min_wakeup
= PA_CLAMP(u
->min_wakeup
, u
->frame_size
, max_use_2
);
248 static void fix_tsched_watermark(struct userdata
*u
) {
252 max_use
= u
->hwbuf_size
- u
->hwbuf_unused
;
254 if (u
->tsched_watermark
> max_use
- u
->min_sleep
)
255 u
->tsched_watermark
= max_use
- u
->min_sleep
;
257 if (u
->tsched_watermark
< u
->min_wakeup
)
258 u
->tsched_watermark
= u
->min_wakeup
;
261 static void adjust_after_overrun(struct userdata
*u
) {
262 size_t old_watermark
;
263 pa_usec_t old_min_latency
, new_min_latency
;
266 pa_assert(u
->use_tsched
);
268 /* First, just try to increase the watermark */
269 old_watermark
= u
->tsched_watermark
;
270 u
->tsched_watermark
= PA_MIN(u
->tsched_watermark
* 2, u
->tsched_watermark
+ u
->watermark_step
);
272 fix_tsched_watermark(u
);
274 if (old_watermark
!= u
->tsched_watermark
) {
275 pa_log_notice("Increasing wakeup watermark to %0.2f ms",
276 (double) pa_bytes_to_usec(u
->tsched_watermark
, &u
->source
->sample_spec
) / PA_USEC_PER_MSEC
);
280 /* Hmm, we cannot increase the watermark any further, hence let's raise the latency */
281 old_min_latency
= u
->source
->thread_info
.min_latency
;
282 new_min_latency
= PA_MIN(old_min_latency
* 2, old_min_latency
+ TSCHED_WATERMARK_STEP_USEC
);
283 new_min_latency
= PA_MIN(new_min_latency
, u
->source
->thread_info
.max_latency
);
285 if (old_min_latency
!= new_min_latency
) {
286 pa_log_notice("Increasing minimal latency to %0.2f ms",
287 (double) new_min_latency
/ PA_USEC_PER_MSEC
);
289 pa_source_set_latency_range_within_thread(u
->source
, new_min_latency
, u
->source
->thread_info
.max_latency
);
293 /* When we reach this we're officialy fucked! */
296 static pa_usec_t
hw_sleep_time(struct userdata
*u
, pa_usec_t
*sleep_usec
, pa_usec_t
*process_usec
) {
301 usec
= pa_source_get_requested_latency_within_thread(u
->source
);
303 if (usec
== (pa_usec_t
) -1)
304 usec
= pa_bytes_to_usec(u
->hwbuf_size
, &u
->source
->sample_spec
);
306 wm
= pa_bytes_to_usec(u
->tsched_watermark
, &u
->source
->sample_spec
);
311 *sleep_usec
= usec
- wm
;
315 pa_log_debug("Buffer time: %lu ms; Sleep time: %lu ms; Process time: %lu ms",
316 (unsigned long) (usec
/ PA_USEC_PER_MSEC
),
317 (unsigned long) (*sleep_usec
/ PA_USEC_PER_MSEC
),
318 (unsigned long) (*process_usec
/ PA_USEC_PER_MSEC
));
324 static int try_recover(struct userdata
*u
, const char *call
, int err
) {
329 pa_log_debug("%s: %s", call
, pa_alsa_strerror(err
));
331 pa_assert(err
!= -EAGAIN
);
334 pa_log_debug("%s: Buffer overrun!", call
);
336 if ((err
= snd_pcm_recover(u
->pcm_handle
, err
, 1)) < 0) {
337 pa_log("%s: %s", call
, pa_alsa_strerror(err
));
341 snd_pcm_start(u
->pcm_handle
);
345 static size_t check_left_to_record(struct userdata
*u
, size_t n_bytes
) {
346 size_t left_to_record
;
347 size_t rec_space
= u
->hwbuf_size
- u
->hwbuf_unused
;
349 /* We use <= instead of < for this check here because an overrun
350 * only happens after the last sample was processed, not already when
351 * it is removed from the buffer. This is particularly important
352 * when block transfer is used. */
354 if (n_bytes
<= rec_space
) {
355 left_to_record
= rec_space
- n_bytes
;
358 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
);
368 if (pa_log_ratelimit())
369 pa_log_info("Overrun!");
372 adjust_after_overrun(u
);
375 return left_to_record
;
378 static int mmap_read(struct userdata
*u
, pa_usec_t
*sleep_usec
, pa_bool_t polled
) {
379 pa_bool_t work_done
= FALSE
;
380 pa_usec_t max_sleep_usec
= 0, process_usec
= 0;
381 size_t left_to_record
;
385 pa_source_assert_ref(u
->source
);
388 hw_sleep_time(u
, &max_sleep_usec
, &process_usec
);
394 pa_bool_t after_avail
= TRUE
;
396 if (PA_UNLIKELY((n
= pa_alsa_safe_avail(u
->pcm_handle
, u
->hwbuf_size
, &u
->source
->sample_spec
)) < 0)) {
398 if ((r
= try_recover(u
, "snd_pcm_avail", (int) n
)) == 0)
404 n_bytes
= (size_t) n
* u
->frame_size
;
407 pa_log_debug("avail: %lu", (unsigned long) n_bytes
);
410 left_to_record
= check_left_to_record(u
, n_bytes
);
414 pa_bytes_to_usec(left_to_record
, &u
->source
->sample_spec
) > process_usec
+max_sleep_usec
/2) {
416 pa_log_debug("Not reading, because too early.");
421 if (PA_UNLIKELY(n_bytes
<= 0)) {
425 char *dn
= pa_alsa_get_driver_name_by_pcm(u
->pcm_handle
);
426 pa_log(_("ALSA woke us up to read new data from the device, but there was actually nothing to read!\n"
427 "Most likely this is a bug in the ALSA driver '%s'. Please report this issue to the ALSA developers.\n"
428 "We were woken up with POLLIN set -- however a subsequent snd_pcm_avail() returned 0 or another value < min_avail."),
434 pa_log_debug("Not reading, because not necessary.");
441 pa_log_debug("Not filling up, because already too many iterations.");
450 pa_log_debug("Reading");
455 const snd_pcm_channel_area_t
*areas
;
456 snd_pcm_uframes_t offset
, frames
;
459 snd_pcm_sframes_t sframes
;
461 frames
= (snd_pcm_uframes_t
) (n_bytes
/ u
->frame_size
);
463 /* pa_log_debug("%lu frames to read", (unsigned long) frames); */
465 if (PA_UNLIKELY((err
= pa_alsa_safe_mmap_begin(u
->pcm_handle
, &areas
, &offset
, &frames
, u
->hwbuf_size
, &u
->source
->sample_spec
)) < 0)) {
467 if (!after_avail
&& err
== -EAGAIN
)
470 if ((r
= try_recover(u
, "snd_pcm_mmap_begin", err
)) == 0)
476 /* Make sure that if these memblocks need to be copied they will fit into one slot */
477 if (frames
> pa_mempool_block_size_max(u
->source
->core
->mempool
)/u
->frame_size
)
478 frames
= pa_mempool_block_size_max(u
->source
->core
->mempool
)/u
->frame_size
;
480 if (!after_avail
&& frames
== 0)
483 pa_assert(frames
> 0);
486 /* Check these are multiples of 8 bit */
487 pa_assert((areas
[0].first
& 7) == 0);
488 pa_assert((areas
[0].step
& 7)== 0);
490 /* We assume a single interleaved memory buffer */
491 pa_assert((areas
[0].first
>> 3) == 0);
492 pa_assert((areas
[0].step
>> 3) == u
->frame_size
);
494 p
= (uint8_t*) areas
[0].addr
+ (offset
* u
->frame_size
);
496 chunk
.memblock
= pa_memblock_new_fixed(u
->core
->mempool
, p
, frames
* u
->frame_size
, TRUE
);
497 chunk
.length
= pa_memblock_get_length(chunk
.memblock
);
500 pa_source_post(u
->source
, &chunk
);
501 pa_memblock_unref_fixed(chunk
.memblock
);
503 if (PA_UNLIKELY((sframes
= snd_pcm_mmap_commit(u
->pcm_handle
, offset
, frames
)) < 0)) {
505 if ((r
= try_recover(u
, "snd_pcm_mmap_commit", (int) sframes
)) == 0)
513 u
->read_count
+= frames
* u
->frame_size
;
516 pa_log_debug("Read %lu bytes (of possible %lu bytes)", (unsigned long) (frames
* u
->frame_size
), (unsigned long) n_bytes
);
519 if ((size_t) frames
* u
->frame_size
>= n_bytes
)
522 n_bytes
-= (size_t) frames
* u
->frame_size
;
526 *sleep_usec
= pa_bytes_to_usec(left_to_record
, &u
->source
->sample_spec
);
528 if (*sleep_usec
> process_usec
)
529 *sleep_usec
-= process_usec
;
533 return work_done
? 1 : 0;
536 static int unix_read(struct userdata
*u
, pa_usec_t
*sleep_usec
, pa_bool_t polled
) {
537 int work_done
= FALSE
;
538 pa_usec_t max_sleep_usec
= 0, process_usec
= 0;
539 size_t left_to_record
;
543 pa_source_assert_ref(u
->source
);
546 hw_sleep_time(u
, &max_sleep_usec
, &process_usec
);
552 pa_bool_t after_avail
= TRUE
;
554 if (PA_UNLIKELY((n
= pa_alsa_safe_avail(u
->pcm_handle
, u
->hwbuf_size
, &u
->source
->sample_spec
)) < 0)) {
556 if ((r
= try_recover(u
, "snd_pcm_avail", (int) n
)) == 0)
562 n_bytes
= (size_t) n
* u
->frame_size
;
563 left_to_record
= check_left_to_record(u
, n_bytes
);
567 pa_bytes_to_usec(left_to_record
, &u
->source
->sample_spec
) > process_usec
+max_sleep_usec
/2)
570 if (PA_UNLIKELY(n_bytes
<= 0)) {
574 char *dn
= pa_alsa_get_driver_name_by_pcm(u
->pcm_handle
);
575 pa_log(_("ALSA woke us up to read new data from the device, but there was actually nothing to read!\n"
576 "Most likely this is a bug in the ALSA driver '%s'. Please report this issue to the ALSA developers.\n"
577 "We were woken up with POLLIN set -- however a subsequent snd_pcm_avail() returned 0 or another value < min_avail."),
587 pa_log_debug("Not filling up, because already too many iterations.");
597 snd_pcm_sframes_t frames
;
600 chunk
.memblock
= pa_memblock_new(u
->core
->mempool
, (size_t) -1);
602 frames
= (snd_pcm_sframes_t
) (pa_memblock_get_length(chunk
.memblock
) / u
->frame_size
);
604 if (frames
> (snd_pcm_sframes_t
) (n_bytes
/u
->frame_size
))
605 frames
= (snd_pcm_sframes_t
) (n_bytes
/u
->frame_size
);
607 /* pa_log_debug("%lu frames to read", (unsigned long) n); */
609 p
= pa_memblock_acquire(chunk
.memblock
);
610 frames
= snd_pcm_readi(u
->pcm_handle
, (uint8_t*) p
, (snd_pcm_uframes_t
) frames
);
611 pa_memblock_release(chunk
.memblock
);
613 if (PA_UNLIKELY(frames
< 0)) {
614 pa_memblock_unref(chunk
.memblock
);
616 if (!after_avail
&& (int) frames
== -EAGAIN
)
619 if ((r
= try_recover(u
, "snd_pcm_readi", (int) frames
)) == 0)
625 if (!after_avail
&& frames
== 0) {
626 pa_memblock_unref(chunk
.memblock
);
630 pa_assert(frames
> 0);
634 chunk
.length
= (size_t) frames
* u
->frame_size
;
636 pa_source_post(u
->source
, &chunk
);
637 pa_memblock_unref(chunk
.memblock
);
641 u
->read_count
+= frames
* u
->frame_size
;
643 /* pa_log_debug("read %lu frames", (unsigned long) frames); */
645 if ((size_t) frames
* u
->frame_size
>= n_bytes
)
648 n_bytes
-= (size_t) frames
* u
->frame_size
;
652 *sleep_usec
= pa_bytes_to_usec(left_to_record
, &u
->source
->sample_spec
);
654 if (*sleep_usec
> process_usec
)
655 *sleep_usec
-= process_usec
;
659 return work_done
? 1 : 0;
662 static void update_smoother(struct userdata
*u
) {
663 snd_pcm_sframes_t delay
= 0;
666 pa_usec_t now1
= 0, now2
;
667 snd_pcm_status_t
*status
;
669 snd_pcm_status_alloca(&status
);
672 pa_assert(u
->pcm_handle
);
674 /* Let's update the time smoother */
676 if (PA_UNLIKELY((err
= pa_alsa_safe_delay(u
->pcm_handle
, &delay
, u
->hwbuf_size
, &u
->source
->sample_spec
)) < 0)) {
677 pa_log_warn("Failed to get delay: %s", pa_alsa_strerror(err
));
681 if (PA_UNLIKELY((err
= snd_pcm_status(u
->pcm_handle
, status
)) < 0))
682 pa_log_warn("Failed to get timestamp: %s", pa_alsa_strerror(err
));
684 snd_htimestamp_t htstamp
= { 0, 0 };
685 snd_pcm_status_get_htstamp(status
, &htstamp
);
686 now1
= pa_timespec_load(&htstamp
);
689 position
= u
->read_count
+ ((uint64_t) delay
* (uint64_t) u
->frame_size
);
691 /* Hmm, if the timestamp is 0, then it wasn't set and we take the current time */
693 now1
= pa_rtclock_now();
695 now2
= pa_bytes_to_usec(position
, &u
->source
->sample_spec
);
697 pa_smoother_put(u
->smoother
, now1
, now2
);
700 static pa_usec_t
source_get_latency(struct userdata
*u
) {
702 pa_usec_t now1
, now2
;
706 now1
= pa_rtclock_now();
707 now2
= pa_smoother_get(u
->smoother
, now1
);
709 delay
= (int64_t) now2
- (int64_t) pa_bytes_to_usec(u
->read_count
, &u
->source
->sample_spec
);
711 return delay
>= 0 ? (pa_usec_t
) delay
: 0;
714 static int build_pollfd(struct userdata
*u
) {
716 pa_assert(u
->pcm_handle
);
718 if (u
->alsa_rtpoll_item
)
719 pa_rtpoll_item_free(u
->alsa_rtpoll_item
);
721 if (!(u
->alsa_rtpoll_item
= pa_alsa_build_pollfd(u
->pcm_handle
, u
->rtpoll
)))
727 static int suspend(struct userdata
*u
) {
729 pa_assert(u
->pcm_handle
);
731 pa_smoother_pause(u
->smoother
, pa_rtclock_now());
734 snd_pcm_close(u
->pcm_handle
);
735 u
->pcm_handle
= NULL
;
737 if (u
->alsa_rtpoll_item
) {
738 pa_rtpoll_item_free(u
->alsa_rtpoll_item
);
739 u
->alsa_rtpoll_item
= NULL
;
742 pa_log_info("Device suspended...");
747 static int update_sw_params(struct userdata
*u
) {
748 snd_pcm_uframes_t avail_min
;
753 /* Use the full buffer if noone asked us for anything specific */
759 if ((latency
= pa_source_get_requested_latency_within_thread(u
->source
)) != (pa_usec_t
) -1) {
762 pa_log_debug("latency set to %0.2fms", (double) latency
/ PA_USEC_PER_MSEC
);
764 b
= pa_usec_to_bytes(latency
, &u
->source
->sample_spec
);
766 /* We need at least one sample in our buffer */
768 if (PA_UNLIKELY(b
< u
->frame_size
))
771 u
->hwbuf_unused
= PA_LIKELY(b
< u
->hwbuf_size
) ? (u
->hwbuf_size
- b
) : 0;
774 fix_min_sleep_wakeup(u
);
775 fix_tsched_watermark(u
);
778 pa_log_debug("hwbuf_unused=%lu", (unsigned long) u
->hwbuf_unused
);
783 pa_usec_t sleep_usec
, process_usec
;
785 hw_sleep_time(u
, &sleep_usec
, &process_usec
);
786 avail_min
+= pa_usec_to_bytes(sleep_usec
, &u
->source
->sample_spec
) / u
->frame_size
;
789 pa_log_debug("setting avail_min=%lu", (unsigned long) avail_min
);
791 if ((err
= pa_alsa_set_sw_params(u
->pcm_handle
, avail_min
)) < 0) {
792 pa_log("Failed to set software parameters: %s", pa_alsa_strerror(err
));
799 static int unsuspend(struct userdata
*u
) {
804 snd_pcm_uframes_t period_size
;
807 pa_assert(!u
->pcm_handle
);
809 pa_log_info("Trying resume...");
811 if ((err
= snd_pcm_open(&u
->pcm_handle
, u
->device_name
, SND_PCM_STREAM_CAPTURE
,
812 /*SND_PCM_NONBLOCK|*/
813 SND_PCM_NO_AUTO_RESAMPLE
|
814 SND_PCM_NO_AUTO_CHANNELS
|
815 SND_PCM_NO_AUTO_FORMAT
)) < 0) {
816 pa_log("Error opening PCM device %s: %s", u
->device_name
, pa_alsa_strerror(err
));
820 ss
= u
->source
->sample_spec
;
821 nfrags
= u
->nfragments
;
822 period_size
= u
->fragment_size
/ u
->frame_size
;
826 if ((err
= pa_alsa_set_hw_params(u
->pcm_handle
, &ss
, &nfrags
, &period_size
, u
->hwbuf_size
/ u
->frame_size
, &b
, &d
, TRUE
)) < 0) {
827 pa_log("Failed to set hardware parameters: %s", pa_alsa_strerror(err
));
831 if (b
!= u
->use_mmap
|| d
!= u
->use_tsched
) {
832 pa_log_warn("Resume failed, couldn't get original access mode.");
836 if (!pa_sample_spec_equal(&ss
, &u
->source
->sample_spec
)) {
837 pa_log_warn("Resume failed, couldn't restore original sample settings.");
841 if (nfrags
!= u
->nfragments
|| period_size
*u
->frame_size
!= u
->fragment_size
) {
842 pa_log_warn("Resume failed, couldn't restore original fragment settings. (Old: %lu*%lu, New %lu*%lu)",
843 (unsigned long) u
->nfragments
, (unsigned long) u
->fragment_size
,
844 (unsigned long) nfrags
, period_size
* u
->frame_size
);
848 if (update_sw_params(u
) < 0)
851 if (build_pollfd(u
) < 0)
854 /* FIXME: We need to reload the volume somehow */
856 snd_pcm_start(u
->pcm_handle
);
857 pa_smoother_resume(u
->smoother
, pa_rtclock_now(), TRUE
);
859 pa_log_info("Resumed successfully...");
865 snd_pcm_close(u
->pcm_handle
);
866 u
->pcm_handle
= NULL
;
872 static int source_process_msg(pa_msgobject
*o
, int code
, void *data
, int64_t offset
, pa_memchunk
*chunk
) {
873 struct userdata
*u
= PA_SOURCE(o
)->userdata
;
877 case PA_SOURCE_MESSAGE_GET_LATENCY
: {
881 r
= source_get_latency(u
);
883 *((pa_usec_t
*) data
) = r
;
888 case PA_SOURCE_MESSAGE_SET_STATE
:
890 switch ((pa_source_state_t
) PA_PTR_TO_UINT(data
)) {
892 case PA_SOURCE_SUSPENDED
:
893 pa_assert(PA_SOURCE_IS_OPENED(u
->source
->thread_info
.state
));
901 case PA_SOURCE_RUNNING
:
903 if (u
->source
->thread_info
.state
== PA_SOURCE_INIT
) {
904 if (build_pollfd(u
) < 0)
907 snd_pcm_start(u
->pcm_handle
);
910 if (u
->source
->thread_info
.state
== PA_SOURCE_SUSPENDED
) {
911 if (unsuspend(u
) < 0)
917 case PA_SOURCE_UNLINKED
:
919 case PA_SOURCE_INVALID_STATE
:
926 return pa_source_process_msg(o
, code
, data
, offset
, chunk
);
929 /* Called from main context */
930 static int source_set_state_cb(pa_source
*s
, pa_source_state_t new_state
) {
931 pa_source_state_t old_state
;
934 pa_source_assert_ref(s
);
935 pa_assert_se(u
= s
->userdata
);
937 old_state
= pa_source_get_state(u
->source
);
939 if (PA_SINK_IS_OPENED(old_state
) && new_state
== PA_SINK_SUSPENDED
)
941 else if (old_state
== PA_SINK_SUSPENDED
&& PA_SINK_IS_OPENED(new_state
))
942 if (reserve_init(u
, u
->device_name
) < 0)
948 static int mixer_callback(snd_mixer_elem_t
*elem
, unsigned int mask
) {
949 struct userdata
*u
= snd_mixer_elem_get_callback_private(elem
);
952 pa_assert(u
->mixer_handle
);
954 if (mask
== SND_CTL_EVENT_MASK_REMOVE
)
957 if (mask
& SND_CTL_EVENT_MASK_VALUE
) {
958 pa_source_get_volume(u
->source
, TRUE
);
959 pa_source_get_mute(u
->source
, TRUE
);
965 static void source_get_volume_cb(pa_source
*s
) {
966 struct userdata
*u
= s
->userdata
;
968 char t
[PA_CVOLUME_SNPRINT_MAX
];
971 pa_assert(u
->mixer_path
);
972 pa_assert(u
->mixer_handle
);
974 if (pa_alsa_path_get_volume(u
->mixer_path
, u
->mixer_handle
, &s
->channel_map
, &r
) < 0)
977 /* Shift down by the base volume, so that 0dB becomes maximum volume */
978 pa_sw_cvolume_multiply_scalar(&r
, &r
, s
->base_volume
);
980 pa_log_debug("Read hardware volume: %s", pa_cvolume_snprint(t
, sizeof(t
), &r
));
982 if (pa_cvolume_equal(&u
->hardware_volume
, &r
))
985 s
->virtual_volume
= u
->hardware_volume
= r
;
987 if (u
->mixer_path
->has_dB
) {
990 /* Hmm, so the hardware volume changed, let's reset our software volume */
991 pa_cvolume_reset(&reset
, s
->sample_spec
.channels
);
992 pa_source_set_soft_volume(s
, &reset
);
996 static void source_set_volume_cb(pa_source
*s
) {
997 struct userdata
*u
= s
->userdata
;
999 char t
[PA_CVOLUME_SNPRINT_MAX
];
1002 pa_assert(u
->mixer_path
);
1003 pa_assert(u
->mixer_handle
);
1005 /* Shift up by the base volume */
1006 pa_sw_cvolume_divide_scalar(&r
, &s
->virtual_volume
, s
->base_volume
);
1008 if (pa_alsa_path_set_volume(u
->mixer_path
, u
->mixer_handle
, &s
->channel_map
, &r
) < 0)
1011 /* Shift down by the base volume, so that 0dB becomes maximum volume */
1012 pa_sw_cvolume_multiply_scalar(&r
, &r
, s
->base_volume
);
1014 u
->hardware_volume
= r
;
1016 if (u
->mixer_path
->has_dB
) {
1018 /* Match exactly what the user requested by software */
1019 pa_sw_cvolume_divide(&s
->soft_volume
, &s
->virtual_volume
, &u
->hardware_volume
);
1021 pa_log_debug("Requested volume: %s", pa_cvolume_snprint(t
, sizeof(t
), &s
->virtual_volume
));
1022 pa_log_debug("Got hardware volume: %s", pa_cvolume_snprint(t
, sizeof(t
), &u
->hardware_volume
));
1023 pa_log_debug("Calculated software volume: %s", pa_cvolume_snprint(t
, sizeof(t
), &s
->soft_volume
));
1026 pa_log_debug("Wrote hardware volume: %s", pa_cvolume_snprint(t
, sizeof(t
), &r
));
1028 /* We can't match exactly what the user requested, hence let's
1029 * at least tell the user about it */
1031 s
->virtual_volume
= r
;
1035 static void source_get_mute_cb(pa_source
*s
) {
1036 struct userdata
*u
= s
->userdata
;
1040 pa_assert(u
->mixer_path
);
1041 pa_assert(u
->mixer_handle
);
1043 if (pa_alsa_path_get_mute(u
->mixer_path
, u
->mixer_handle
, &b
) < 0)
1049 static void source_set_mute_cb(pa_source
*s
) {
1050 struct userdata
*u
= s
->userdata
;
1053 pa_assert(u
->mixer_path
);
1054 pa_assert(u
->mixer_handle
);
1056 pa_alsa_path_set_mute(u
->mixer_path
, u
->mixer_handle
, s
->muted
);
1059 static int source_set_port_cb(pa_source
*s
, pa_device_port
*p
) {
1060 struct userdata
*u
= s
->userdata
;
1061 pa_alsa_port_data
*data
;
1065 pa_assert(u
->mixer_handle
);
1067 data
= PA_DEVICE_PORT_DATA(p
);
1069 pa_assert_se(u
->mixer_path
= data
->path
);
1070 pa_alsa_path_select(u
->mixer_path
, u
->mixer_handle
);
1072 if (u
->mixer_path
->has_volume
&& u
->mixer_path
->has_dB
) {
1073 s
->base_volume
= pa_sw_volume_from_dB(-u
->mixer_path
->max_dB
);
1074 s
->n_volume_steps
= PA_VOLUME_NORM
+1;
1076 if (u
->mixer_path
->max_dB
> 0.0)
1077 pa_log_info("Fixing base volume to %0.2f dB", pa_sw_volume_to_dB(s
->base_volume
));
1079 pa_log_info("No particular base volume set, fixing to 0 dB");
1081 s
->base_volume
= PA_VOLUME_NORM
;
1082 s
->n_volume_steps
= u
->mixer_path
->max_volume
- u
->mixer_path
->min_volume
+ 1;
1086 pa_alsa_setting_select(data
->setting
, u
->mixer_handle
);
1096 static void source_update_requested_latency_cb(pa_source
*s
) {
1097 struct userdata
*u
= s
->userdata
;
1103 update_sw_params(u
);
1106 static void thread_func(void *userdata
) {
1107 struct userdata
*u
= userdata
;
1108 unsigned short revents
= 0;
1112 pa_log_debug("Thread starting up");
1114 if (u
->core
->realtime_scheduling
)
1115 pa_make_realtime(u
->core
->realtime_priority
);
1117 pa_thread_mq_install(&u
->thread_mq
);
1123 pa_log_debug("Loop");
1126 /* Read some data and pass it to the sources */
1127 if (PA_SOURCE_IS_OPENED(u
->source
->thread_info
.state
)) {
1129 pa_usec_t sleep_usec
= 0;
1132 work_done
= mmap_read(u
, &sleep_usec
, revents
& POLLIN
);
1134 work_done
= unix_read(u
, &sleep_usec
, revents
& POLLIN
);
1139 /* pa_log_debug("work_done = %i", work_done); */
1144 if (u
->use_tsched
) {
1147 /* OK, the capture buffer is now empty, let's
1148 * calculate when to wake up next */
1150 /* pa_log_debug("Waking up in %0.2fms (sound card clock).", (double) sleep_usec / PA_USEC_PER_MSEC); */
1152 /* Convert from the sound card time domain to the
1153 * system time domain */
1154 cusec
= pa_smoother_translate(u
->smoother
, pa_rtclock_now(), sleep_usec
);
1156 /* pa_log_debug("Waking up in %0.2fms (system clock).", (double) cusec / PA_USEC_PER_MSEC); */
1158 /* We don't trust the conversion, so we wake up whatever comes first */
1159 pa_rtpoll_set_timer_relative(u
->rtpoll
, PA_MIN(sleep_usec
, cusec
));
1161 } else if (u
->use_tsched
)
1163 /* OK, we're in an invalid state, let's disable our timers */
1164 pa_rtpoll_set_timer_disabled(u
->rtpoll
);
1166 /* Hmm, nothing to do. Let's sleep */
1167 if ((ret
= pa_rtpoll_run(u
->rtpoll
, TRUE
)) < 0)
1173 /* Tell ALSA about this and process its response */
1174 if (PA_SOURCE_IS_OPENED(u
->source
->thread_info
.state
)) {
1175 struct pollfd
*pollfd
;
1179 pollfd
= pa_rtpoll_item_get_pollfd(u
->alsa_rtpoll_item
, &n
);
1181 if ((err
= snd_pcm_poll_descriptors_revents(u
->pcm_handle
, pollfd
, n
, &revents
)) < 0) {
1182 pa_log("snd_pcm_poll_descriptors_revents() failed: %s", pa_alsa_strerror(err
));
1186 if (revents
& ~POLLIN
) {
1187 if (pa_alsa_recover_from_poll(u
->pcm_handle
, revents
) < 0)
1190 snd_pcm_start(u
->pcm_handle
);
1191 } else if (revents
&& u
->use_tsched
&& pa_log_ratelimit())
1192 pa_log_debug("Wakeup from ALSA!");
1199 /* If this was no regular exit from the loop we have to continue
1200 * processing messages until we received PA_MESSAGE_SHUTDOWN */
1201 pa_asyncmsgq_post(u
->thread_mq
.outq
, PA_MSGOBJECT(u
->core
), PA_CORE_MESSAGE_UNLOAD_MODULE
, u
->module
, 0, NULL
, NULL
);
1202 pa_asyncmsgq_wait_for(u
->thread_mq
.inq
, PA_MESSAGE_SHUTDOWN
);
1205 pa_log_debug("Thread shutting down");
1208 static void set_source_name(pa_source_new_data
*data
, pa_modargs
*ma
, const char *device_id
, const char *device_name
, pa_alsa_mapping
*mapping
) {
1214 pa_assert(device_name
);
1216 if ((n
= pa_modargs_get_value(ma
, "source_name", NULL
))) {
1217 pa_source_new_data_set_name(data
, n
);
1218 data
->namereg_fail
= TRUE
;
1222 if ((n
= pa_modargs_get_value(ma
, "name", NULL
)))
1223 data
->namereg_fail
= TRUE
;
1225 n
= device_id
? device_id
: device_name
;
1226 data
->namereg_fail
= FALSE
;
1230 t
= pa_sprintf_malloc("alsa_input.%s.%s", n
, mapping
->name
);
1232 t
= pa_sprintf_malloc("alsa_input.%s", n
);
1234 pa_source_new_data_set_name(data
, t
);
1238 static void find_mixer(struct userdata
*u
, pa_alsa_mapping
*mapping
, const char *element
, pa_bool_t ignore_dB
) {
1240 if (!mapping
&& !element
)
1243 if (!(u
->mixer_handle
= pa_alsa_open_mixer_for_pcm(u
->pcm_handle
, &u
->control_device
))) {
1244 pa_log_info("Failed to find a working mixer device.");
1250 if (!(u
->mixer_path
= pa_alsa_path_synthesize(element
, PA_ALSA_DIRECTION_INPUT
)))
1253 if (pa_alsa_path_probe(u
->mixer_path
, u
->mixer_handle
, ignore_dB
) < 0)
1256 pa_log_debug("Probed mixer path %s:", u
->mixer_path
->name
);
1257 pa_alsa_path_dump(u
->mixer_path
);
1260 if (!(u
->mixer_path_set
= pa_alsa_path_set_new(mapping
, PA_ALSA_DIRECTION_INPUT
)))
1263 pa_alsa_path_set_probe(u
->mixer_path_set
, u
->mixer_handle
, ignore_dB
);
1265 pa_log_debug("Probed mixer paths:");
1266 pa_alsa_path_set_dump(u
->mixer_path_set
);
1273 if (u
->mixer_path_set
) {
1274 pa_alsa_path_set_free(u
->mixer_path_set
);
1275 u
->mixer_path_set
= NULL
;
1276 } else if (u
->mixer_path
) {
1277 pa_alsa_path_free(u
->mixer_path
);
1278 u
->mixer_path
= NULL
;
1281 if (u
->mixer_handle
) {
1282 snd_mixer_close(u
->mixer_handle
);
1283 u
->mixer_handle
= NULL
;
1287 static int setup_mixer(struct userdata
*u
, pa_bool_t ignore_dB
) {
1290 if (!u
->mixer_handle
)
1293 if (u
->source
->active_port
) {
1294 pa_alsa_port_data
*data
;
1296 /* We have a list of supported paths, so let's activate the
1297 * one that has been chosen as active */
1299 data
= PA_DEVICE_PORT_DATA(u
->source
->active_port
);
1300 u
->mixer_path
= data
->path
;
1302 pa_alsa_path_select(data
->path
, u
->mixer_handle
);
1305 pa_alsa_setting_select(data
->setting
, u
->mixer_handle
);
1309 if (!u
->mixer_path
&& u
->mixer_path_set
)
1310 u
->mixer_path
= u
->mixer_path_set
->paths
;
1312 if (u
->mixer_path
) {
1313 /* Hmm, we have only a single path, then let's activate it */
1315 pa_alsa_path_select(u
->mixer_path
, u
->mixer_handle
);
1317 if (u
->mixer_path
->settings
)
1318 pa_alsa_setting_select(u
->mixer_path
->settings
, u
->mixer_handle
);
1323 if (!u
->mixer_path
->has_volume
)
1324 pa_log_info("Driver does not support hardware volume control, falling back to software volume control.");
1327 if (u
->mixer_path
->has_dB
) {
1328 pa_log_info("Hardware volume ranges from %0.2f dB to %0.2f dB.", u
->mixer_path
->min_dB
, u
->mixer_path
->max_dB
);
1330 u
->source
->base_volume
= pa_sw_volume_from_dB(-u
->mixer_path
->max_dB
);
1331 u
->source
->n_volume_steps
= PA_VOLUME_NORM
+1;
1333 if (u
->mixer_path
->max_dB
> 0.0)
1334 pa_log_info("Fixing base volume to %0.2f dB", pa_sw_volume_to_dB(u
->source
->base_volume
));
1336 pa_log_info("No particular base volume set, fixing to 0 dB");
1339 pa_log_info("Hardware volume ranges from %li to %li.", u
->mixer_path
->min_volume
, u
->mixer_path
->max_volume
);
1340 u
->source
->base_volume
= PA_VOLUME_NORM
;
1341 u
->source
->n_volume_steps
= u
->mixer_path
->max_volume
- u
->mixer_path
->min_volume
+ 1;
1344 u
->source
->get_volume
= source_get_volume_cb
;
1345 u
->source
->set_volume
= source_set_volume_cb
;
1347 u
->source
->flags
|= PA_SOURCE_HW_VOLUME_CTRL
| (u
->mixer_path
->has_dB
? PA_SOURCE_DECIBEL_VOLUME
: 0);
1348 pa_log_info("Using hardware volume control. Hardware dB scale %s.", u
->mixer_path
->has_dB
? "supported" : "not supported");
1351 if (!u
->mixer_path
->has_mute
) {
1352 pa_log_info("Driver does not support hardware mute control, falling back to software mute control.");
1354 u
->source
->get_mute
= source_get_mute_cb
;
1355 u
->source
->set_mute
= source_set_mute_cb
;
1356 u
->source
->flags
|= PA_SOURCE_HW_MUTE_CTRL
;
1357 pa_log_info("Using hardware mute control.");
1360 u
->mixer_fdl
= pa_alsa_fdlist_new();
1362 if (pa_alsa_fdlist_set_mixer(u
->mixer_fdl
, u
->mixer_handle
, u
->core
->mainloop
) < 0) {
1363 pa_log("Failed to initialize file descriptor monitoring");
1367 if (u
->mixer_path_set
)
1368 pa_alsa_path_set_set_callback(u
->mixer_path_set
, u
->mixer_handle
, mixer_callback
, u
);
1370 pa_alsa_path_set_callback(u
->mixer_path
, u
->mixer_handle
, mixer_callback
, u
);
1375 pa_source
*pa_alsa_source_new(pa_module
*m
, pa_modargs
*ma
, const char*driver
, pa_card
*card
, pa_alsa_mapping
*mapping
) {
1377 struct userdata
*u
= NULL
;
1378 const char *dev_id
= NULL
;
1379 pa_sample_spec ss
, requested_ss
;
1381 uint32_t nfrags
, hwbuf_size
, frag_size
, tsched_size
, tsched_watermark
;
1382 snd_pcm_uframes_t period_frames
, tsched_frames
;
1384 pa_bool_t use_mmap
= TRUE
, b
, use_tsched
= TRUE
, d
, ignore_dB
= FALSE
;
1385 pa_source_new_data data
;
1386 pa_alsa_profile_set
*profile_set
= NULL
;
1391 ss
= m
->core
->default_sample_spec
;
1392 map
= m
->core
->default_channel_map
;
1393 if (pa_modargs_get_sample_spec_and_channel_map(ma
, &ss
, &map
, PA_CHANNEL_MAP_ALSA
) < 0) {
1394 pa_log("Failed to parse sample specification");
1399 frame_size
= pa_frame_size(&ss
);
1401 nfrags
= m
->core
->default_n_fragments
;
1402 frag_size
= (uint32_t) pa_usec_to_bytes(m
->core
->default_fragment_size_msec
*PA_USEC_PER_MSEC
, &ss
);
1404 frag_size
= (uint32_t) frame_size
;
1405 tsched_size
= (uint32_t) pa_usec_to_bytes(DEFAULT_TSCHED_BUFFER_USEC
, &ss
);
1406 tsched_watermark
= (uint32_t) pa_usec_to_bytes(DEFAULT_TSCHED_WATERMARK_USEC
, &ss
);
1408 if (pa_modargs_get_value_u32(ma
, "fragments", &nfrags
) < 0 ||
1409 pa_modargs_get_value_u32(ma
, "fragment_size", &frag_size
) < 0 ||
1410 pa_modargs_get_value_u32(ma
, "tsched_buffer_size", &tsched_size
) < 0 ||
1411 pa_modargs_get_value_u32(ma
, "tsched_buffer_watermark", &tsched_watermark
) < 0) {
1412 pa_log("Failed to parse buffer metrics");
1416 hwbuf_size
= frag_size
* nfrags
;
1417 period_frames
= frag_size
/frame_size
;
1418 tsched_frames
= tsched_size
/frame_size
;
1420 if (pa_modargs_get_value_boolean(ma
, "mmap", &use_mmap
) < 0) {
1421 pa_log("Failed to parse mmap argument.");
1425 if (pa_modargs_get_value_boolean(ma
, "tsched", &use_tsched
) < 0) {
1426 pa_log("Failed to parse timer_scheduling argument.");
1430 if (pa_modargs_get_value_boolean(ma
, "ignore_dB", &ignore_dB
) < 0) {
1431 pa_log("Failed to parse ignore_dB argument.");
1435 if (use_tsched
&& !pa_rtclock_hrtimer()) {
1436 pa_log_notice("Disabling timer-based scheduling because high-resolution timers are not available from the kernel.");
1440 u
= pa_xnew0(struct userdata
, 1);
1443 u
->use_mmap
= use_mmap
;
1444 u
->use_tsched
= use_tsched
;
1445 u
->rtpoll
= pa_rtpoll_new();
1446 pa_thread_mq_init(&u
->thread_mq
, m
->core
->mainloop
, u
->rtpoll
);
1448 u
->smoother
= pa_smoother_new(
1449 DEFAULT_TSCHED_WATERMARK_USEC
*2,
1450 DEFAULT_TSCHED_WATERMARK_USEC
*2,
1457 dev_id
= pa_modargs_get_value(
1459 pa_modargs_get_value(ma
, "device", DEFAULT_DEVICE
));
1461 if (reserve_init(u
, dev_id
) < 0)
1464 if (reserve_monitor_init(u
, dev_id
) < 0)
1472 if (!(dev_id
= pa_modargs_get_value(ma
, "device_id", NULL
))) {
1473 pa_log("device_id= not set");
1477 if (!(u
->pcm_handle
= pa_alsa_open_by_device_id_mapping(
1481 SND_PCM_STREAM_CAPTURE
,
1482 &nfrags
, &period_frames
, tsched_frames
,
1486 } else if ((dev_id
= pa_modargs_get_value(ma
, "device_id", NULL
))) {
1488 if (!(profile_set
= pa_alsa_profile_set_new(NULL
, &map
)))
1491 if (!(u
->pcm_handle
= pa_alsa_open_by_device_id_auto(
1495 SND_PCM_STREAM_CAPTURE
,
1496 &nfrags
, &period_frames
, tsched_frames
,
1497 &b
, &d
, profile_set
, &mapping
)))
1502 if (!(u
->pcm_handle
= pa_alsa_open_by_device_string(
1503 pa_modargs_get_value(ma
, "device", DEFAULT_DEVICE
),
1506 SND_PCM_STREAM_CAPTURE
,
1507 &nfrags
, &period_frames
, tsched_frames
,
1512 pa_assert(u
->device_name
);
1513 pa_log_info("Successfully opened device %s.", u
->device_name
);
1515 if (pa_alsa_pcm_is_modem(u
->pcm_handle
)) {
1516 pa_log_notice("Device %s is modem, refusing further initialization.", u
->device_name
);
1521 pa_log_info("Selected mapping '%s' (%s).", mapping
->description
, mapping
->name
);
1523 if (use_mmap
&& !b
) {
1524 pa_log_info("Device doesn't support mmap(), falling back to UNIX read/write mode.");
1525 u
->use_mmap
= use_mmap
= FALSE
;
1528 if (use_tsched
&& (!b
|| !d
)) {
1529 pa_log_info("Cannot enable timer-based scheduling, falling back to sound IRQ scheduling.");
1530 u
->use_tsched
= use_tsched
= FALSE
;
1533 if (use_tsched
&& !pa_alsa_pcm_is_hw(u
->pcm_handle
)) {
1534 pa_log_info("Device is not a hardware device, disabling timer-based scheduling.");
1535 u
->use_tsched
= use_tsched
= FALSE
;
1539 pa_log_info("Successfully enabled mmap() mode.");
1542 pa_log_info("Successfully enabled timer-based scheduling mode.");
1544 /* ALSA might tweak the sample spec, so recalculate the frame size */
1545 frame_size
= pa_frame_size(&ss
);
1547 find_mixer(u
, mapping
, pa_modargs_get_value(ma
, "control", NULL
), ignore_dB
);
1549 pa_source_new_data_init(&data
);
1550 data
.driver
= driver
;
1553 set_source_name(&data
, ma
, dev_id
, u
->device_name
, mapping
);
1554 pa_source_new_data_set_sample_spec(&data
, &ss
);
1555 pa_source_new_data_set_channel_map(&data
, &map
);
1557 pa_alsa_init_proplist_pcm(m
->core
, data
.proplist
, u
->pcm_handle
);
1558 pa_proplist_sets(data
.proplist
, PA_PROP_DEVICE_STRING
, u
->device_name
);
1559 pa_proplist_setf(data
.proplist
, PA_PROP_DEVICE_BUFFERING_BUFFER_SIZE
, "%lu", (unsigned long) (period_frames
* frame_size
* nfrags
));
1560 pa_proplist_setf(data
.proplist
, PA_PROP_DEVICE_BUFFERING_FRAGMENT_SIZE
, "%lu", (unsigned long) (period_frames
* frame_size
));
1561 pa_proplist_sets(data
.proplist
, PA_PROP_DEVICE_ACCESS_MODE
, u
->use_tsched
? "mmap+timer" : (u
->use_mmap
? "mmap" : "serial"));
1564 pa_proplist_sets(data
.proplist
, PA_PROP_DEVICE_PROFILE_NAME
, mapping
->name
);
1565 pa_proplist_sets(data
.proplist
, PA_PROP_DEVICE_PROFILE_DESCRIPTION
, mapping
->description
);
1568 pa_alsa_init_description(data
.proplist
);
1570 if (u
->control_device
)
1571 pa_alsa_init_proplist_ctl(data
.proplist
, u
->control_device
);
1573 if (pa_modargs_get_proplist(ma
, "source_properties", data
.proplist
, PA_UPDATE_REPLACE
) < 0) {
1574 pa_log("Invalid properties");
1575 pa_source_new_data_done(&data
);
1579 if (u
->mixer_path_set
)
1580 pa_alsa_add_ports(&data
.ports
, u
->mixer_path_set
);
1582 u
->source
= pa_source_new(m
->core
, &data
, PA_SOURCE_HARDWARE
|PA_SOURCE_LATENCY
|(u
->use_tsched
? PA_SOURCE_DYNAMIC_LATENCY
: 0));
1583 pa_source_new_data_done(&data
);
1586 pa_log("Failed to create source object");
1590 u
->source
->parent
.process_msg
= source_process_msg
;
1591 u
->source
->update_requested_latency
= source_update_requested_latency_cb
;
1592 u
->source
->set_state
= source_set_state_cb
;
1593 u
->source
->set_port
= source_set_port_cb
;
1594 u
->source
->userdata
= u
;
1596 pa_source_set_asyncmsgq(u
->source
, u
->thread_mq
.inq
);
1597 pa_source_set_rtpoll(u
->source
, u
->rtpoll
);
1599 u
->frame_size
= frame_size
;
1600 u
->fragment_size
= frag_size
= (uint32_t) (period_frames
* frame_size
);
1601 u
->nfragments
= nfrags
;
1602 u
->hwbuf_size
= u
->fragment_size
* nfrags
;
1603 u
->tsched_watermark
= pa_usec_to_bytes_round_up(pa_bytes_to_usec_round_up(tsched_watermark
, &requested_ss
), &u
->source
->sample_spec
);
1604 pa_cvolume_mute(&u
->hardware_volume
, u
->source
->sample_spec
.channels
);
1606 pa_log_info("Using %u fragments of size %lu bytes, buffer time is %0.2fms",
1607 nfrags
, (long unsigned) u
->fragment_size
,
1608 (double) pa_bytes_to_usec(u
->hwbuf_size
, &ss
) / PA_USEC_PER_MSEC
);
1610 if (u
->use_tsched
) {
1611 u
->watermark_step
= pa_usec_to_bytes(TSCHED_WATERMARK_STEP_USEC
, &u
->source
->sample_spec
);
1613 fix_min_sleep_wakeup(u
);
1614 fix_tsched_watermark(u
);
1616 pa_source_set_latency_range(u
->source
,
1618 pa_bytes_to_usec(u
->hwbuf_size
, &ss
));
1620 pa_log_info("Time scheduling watermark is %0.2fms",
1621 (double) pa_bytes_to_usec(u
->tsched_watermark
, &ss
) / PA_USEC_PER_MSEC
);
1623 pa_source_set_fixed_latency(u
->source
, pa_bytes_to_usec(u
->hwbuf_size
, &ss
));
1627 if (update_sw_params(u
) < 0)
1630 if (setup_mixer(u
, ignore_dB
) < 0)
1633 pa_alsa_dump(PA_LOG_DEBUG
, u
->pcm_handle
);
1635 if (!(u
->thread
= pa_thread_new(thread_func
, u
))) {
1636 pa_log("Failed to create thread.");
1639 /* Get initial mixer settings */
1640 if (data
.volume_is_set
) {
1641 if (u
->source
->set_volume
)
1642 u
->source
->set_volume(u
->source
);
1644 if (u
->source
->get_volume
)
1645 u
->source
->get_volume(u
->source
);
1648 if (data
.muted_is_set
) {
1649 if (u
->source
->set_mute
)
1650 u
->source
->set_mute(u
->source
);
1652 if (u
->source
->get_mute
)
1653 u
->source
->get_mute(u
->source
);
1656 pa_source_put(u
->source
);
1659 pa_alsa_profile_set_free(profile_set
);
1669 pa_alsa_profile_set_free(profile_set
);
1674 static void userdata_free(struct userdata
*u
) {
1678 pa_source_unlink(u
->source
);
1681 pa_asyncmsgq_send(u
->thread_mq
.inq
, NULL
, PA_MESSAGE_SHUTDOWN
, NULL
, 0, NULL
);
1682 pa_thread_free(u
->thread
);
1685 pa_thread_mq_done(&u
->thread_mq
);
1688 pa_source_unref(u
->source
);
1690 if (u
->alsa_rtpoll_item
)
1691 pa_rtpoll_item_free(u
->alsa_rtpoll_item
);
1694 pa_rtpoll_free(u
->rtpoll
);
1696 if (u
->pcm_handle
) {
1697 snd_pcm_drop(u
->pcm_handle
);
1698 snd_pcm_close(u
->pcm_handle
);
1702 pa_alsa_fdlist_free(u
->mixer_fdl
);
1704 if (u
->mixer_path_set
)
1705 pa_alsa_path_set_free(u
->mixer_path_set
);
1706 else if (u
->mixer_path
)
1707 pa_alsa_path_free(u
->mixer_path
);
1709 if (u
->mixer_handle
)
1710 snd_mixer_close(u
->mixer_handle
);
1713 pa_smoother_free(u
->smoother
);
1718 pa_xfree(u
->device_name
);
1719 pa_xfree(u
->control_device
);
1723 void pa_alsa_source_free(pa_source
*s
) {
1726 pa_source_assert_ref(s
);
1727 pa_assert_se(u
= s
->userdata
);