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);
395 if (PA_UNLIKELY((n = pa_alsa_safe_avail(u->pcm_handle, u->hwbuf_size, &u->source->sample_spec)) < 0)) {
397 if ((r = try_recover(u, "snd_pcm_avail", (int) n)) == 0)
403 n_bytes = (size_t) n * u->frame_size;
406 pa_log_debug("avail: %lu", (unsigned long) n_bytes);
409 left_to_record = check_left_to_record(u, n_bytes);
413 pa_bytes_to_usec(left_to_record, &u->source->sample_spec) > process_usec+max_sleep_usec/2) {
415 pa_log_debug("Not reading, because too early.");
420 if (PA_UNLIKELY(n_bytes <= 0)) {
424 char *dn = pa_alsa_get_driver_name_by_pcm(u->pcm_handle);
425 pa_log(_("ALSA woke us up to read new data from the device, but there was actually nothing to read!\n"
426 "Most likely this is a bug in the ALSA driver '%s'. Please report this issue to the ALSA developers.\n"
427 "We were woken up with POLLIN set -- however a subsequent snd_pcm_avail() returned 0 or another value < min_avail."),
433 pa_log_debug("Not reading, because not necessary.");
440 pa_log_debug("Not filling up, because already too many iterations.");
449 pa_log_debug("Reading");
454 const snd_pcm_channel_area_t *areas;
455 snd_pcm_uframes_t offset, frames;
458 snd_pcm_sframes_t sframes;
460 frames = (snd_pcm_uframes_t) (n_bytes / u->frame_size);
462 /* pa_log_debug("%lu frames to read", (unsigned long) frames); */
464 if (PA_UNLIKELY((err = pa_alsa_safe_mmap_begin(u->pcm_handle, &areas, &offset, &frames, u->hwbuf_size, &u->source->sample_spec)) < 0)) {
466 if ((r = try_recover(u, "snd_pcm_mmap_begin", err)) == 0)
472 /* Make sure that if these memblocks need to be copied they will fit into one slot */
473 if (frames > pa_mempool_block_size_max(u->source->core->mempool)/u->frame_size)
474 frames = pa_mempool_block_size_max(u->source->core->mempool)/u->frame_size;
479 /* Check these are multiples of 8 bit */
480 pa_assert((areas[0].first & 7) == 0);
481 pa_assert((areas[0].step & 7)== 0);
483 /* We assume a single interleaved memory buffer */
484 pa_assert((areas[0].first >> 3) == 0);
485 pa_assert((areas[0].step >> 3) == u->frame_size);
487 p = (uint8_t*) areas[0].addr + (offset * u->frame_size);
489 chunk.memblock = pa_memblock_new_fixed(u->core->mempool, p, frames * u->frame_size, TRUE);
490 chunk.length = pa_memblock_get_length(chunk.memblock);
493 pa_source_post(u->source, &chunk);
494 pa_memblock_unref_fixed(chunk.memblock);
496 if (PA_UNLIKELY((sframes = snd_pcm_mmap_commit(u->pcm_handle, offset, frames)) < 0)) {
498 if ((r = try_recover(u, "snd_pcm_mmap_commit", (int) sframes)) == 0)
506 u->read_count += frames * u->frame_size;
509 pa_log_debug("Read %lu bytes (of possible %lu bytes)", (unsigned long) (frames * u->frame_size), (unsigned long) n_bytes);
512 if ((size_t) frames * u->frame_size >= n_bytes)
515 n_bytes -= (size_t) frames * u->frame_size;
519 *sleep_usec = pa_bytes_to_usec(left_to_record, &u->source->sample_spec);
521 if (*sleep_usec > process_usec)
522 *sleep_usec -= process_usec;
526 return work_done ? 1 : 0;
529 static int unix_read(struct userdata *u, pa_usec_t *sleep_usec, pa_bool_t polled) {
530 int work_done = FALSE;
531 pa_usec_t max_sleep_usec = 0, process_usec = 0;
532 size_t left_to_record;
536 pa_source_assert_ref(u->source);
539 hw_sleep_time(u, &max_sleep_usec, &process_usec);
546 if (PA_UNLIKELY((n = pa_alsa_safe_avail(u->pcm_handle, u->hwbuf_size, &u->source->sample_spec)) < 0)) {
548 if ((r = try_recover(u, "snd_pcm_avail", (int) n)) == 0)
554 n_bytes = (size_t) n * u->frame_size;
555 left_to_record = check_left_to_record(u, n_bytes);
559 pa_bytes_to_usec(left_to_record, &u->source->sample_spec) > process_usec+max_sleep_usec/2)
562 if (PA_UNLIKELY(n_bytes <= 0)) {
566 char *dn = pa_alsa_get_driver_name_by_pcm(u->pcm_handle);
567 pa_log(_("ALSA woke us up to read new data from the device, but there was actually nothing to read!\n"
568 "Most likely this is a bug in the ALSA driver '%s'. Please report this issue to the ALSA developers.\n"
569 "We were woken up with POLLIN set -- however a subsequent snd_pcm_avail() returned 0 or another value < min_avail."),
579 pa_log_debug("Not filling up, because already too many iterations.");
589 snd_pcm_sframes_t frames;
592 chunk.memblock = pa_memblock_new(u->core->mempool, (size_t) -1);
594 frames = (snd_pcm_sframes_t) (pa_memblock_get_length(chunk.memblock) / u->frame_size);
596 if (frames > (snd_pcm_sframes_t) (n_bytes/u->frame_size))
597 frames = (snd_pcm_sframes_t) (n_bytes/u->frame_size);
599 /* pa_log_debug("%lu frames to read", (unsigned long) n); */
601 p = pa_memblock_acquire(chunk.memblock);
602 frames = snd_pcm_readi(u->pcm_handle, (uint8_t*) p, (snd_pcm_uframes_t) frames);
603 pa_memblock_release(chunk.memblock);
606 pa_memblock_unref(chunk.memblock);
610 if (PA_UNLIKELY(frames < 0)) {
611 pa_memblock_unref(chunk.memblock);
613 if ((r = try_recover(u, "snd_pcm_readi", (int) (frames))) == 0)
620 chunk.length = (size_t) frames * u->frame_size;
622 pa_source_post(u->source, &chunk);
623 pa_memblock_unref(chunk.memblock);
627 u->read_count += frames * u->frame_size;
629 /* pa_log_debug("read %lu frames", (unsigned long) frames); */
631 if ((size_t) frames * u->frame_size >= n_bytes)
634 n_bytes -= (size_t) frames * u->frame_size;
638 *sleep_usec = pa_bytes_to_usec(left_to_record, &u->source->sample_spec);
640 if (*sleep_usec > process_usec)
641 *sleep_usec -= process_usec;
645 return work_done ? 1 : 0;
648 static void update_smoother(struct userdata *u) {
649 snd_pcm_sframes_t delay = 0;
652 pa_usec_t now1 = 0, now2;
653 snd_pcm_status_t *status;
655 snd_pcm_status_alloca(&status);
658 pa_assert(u->pcm_handle);
660 /* Let's update the time smoother */
662 if (PA_UNLIKELY((err = pa_alsa_safe_delay(u->pcm_handle, &delay, u->hwbuf_size, &u->source->sample_spec)) < 0)) {
663 pa_log_warn("Failed to get delay: %s", pa_alsa_strerror(err));
667 if (PA_UNLIKELY((err = snd_pcm_status(u->pcm_handle, status)) < 0))
668 pa_log_warn("Failed to get timestamp: %s", pa_alsa_strerror(err));
670 snd_htimestamp_t htstamp = { 0, 0 };
671 snd_pcm_status_get_htstamp(status, &htstamp);
672 now1 = pa_timespec_load(&htstamp);
675 position = u->read_count + ((uint64_t) delay * (uint64_t) u->frame_size);
677 /* Hmm, if the timestamp is 0, then it wasn't set and we take the current time */
679 now1 = pa_rtclock_now();
681 now2 = pa_bytes_to_usec(position, &u->source->sample_spec);
683 pa_smoother_put(u->smoother, now1, now2);
686 static pa_usec_t source_get_latency(struct userdata *u) {
688 pa_usec_t now1, now2;
692 now1 = pa_rtclock_now();
693 now2 = pa_smoother_get(u->smoother, now1);
695 delay = (int64_t) now2 - (int64_t) pa_bytes_to_usec(u->read_count, &u->source->sample_spec);
697 return delay >= 0 ? (pa_usec_t) delay : 0;
700 static int build_pollfd(struct userdata *u) {
702 pa_assert(u->pcm_handle);
704 if (u->alsa_rtpoll_item)
705 pa_rtpoll_item_free(u->alsa_rtpoll_item);
707 if (!(u->alsa_rtpoll_item = pa_alsa_build_pollfd(u->pcm_handle, u->rtpoll)))
713 static int suspend(struct userdata *u) {
715 pa_assert(u->pcm_handle);
717 pa_smoother_pause(u->smoother, pa_rtclock_now());
720 snd_pcm_close(u->pcm_handle);
721 u->pcm_handle = NULL;
723 if (u->alsa_rtpoll_item) {
724 pa_rtpoll_item_free(u->alsa_rtpoll_item);
725 u->alsa_rtpoll_item = NULL;
728 pa_log_info("Device suspended...");
733 static int update_sw_params(struct userdata *u) {
734 snd_pcm_uframes_t avail_min;
739 /* Use the full buffer if noone asked us for anything specific */
745 if ((latency = pa_source_get_requested_latency_within_thread(u->source)) != (pa_usec_t) -1) {
748 pa_log_debug("latency set to %0.2fms", (double) latency / PA_USEC_PER_MSEC);
750 b = pa_usec_to_bytes(latency, &u->source->sample_spec);
752 /* We need at least one sample in our buffer */
754 if (PA_UNLIKELY(b < u->frame_size))
757 u->hwbuf_unused = PA_LIKELY(b < u->hwbuf_size) ? (u->hwbuf_size - b) : 0;
760 fix_min_sleep_wakeup(u);
761 fix_tsched_watermark(u);
764 pa_log_debug("hwbuf_unused=%lu", (unsigned long) u->hwbuf_unused);
769 pa_usec_t sleep_usec, process_usec;
771 hw_sleep_time(u, &sleep_usec, &process_usec);
772 avail_min += pa_usec_to_bytes(sleep_usec, &u->source->sample_spec) / u->frame_size;
775 pa_log_debug("setting avail_min=%lu", (unsigned long) avail_min);
777 if ((err = pa_alsa_set_sw_params(u->pcm_handle, avail_min)) < 0) {
778 pa_log("Failed to set software parameters: %s", pa_alsa_strerror(err));
785 static int unsuspend(struct userdata *u) {
790 snd_pcm_uframes_t period_size;
793 pa_assert(!u->pcm_handle);
795 pa_log_info("Trying resume...");
797 if ((err = snd_pcm_open(&u->pcm_handle, u->device_name, SND_PCM_STREAM_CAPTURE,
798 /*SND_PCM_NONBLOCK|*/
799 SND_PCM_NO_AUTO_RESAMPLE|
800 SND_PCM_NO_AUTO_CHANNELS|
801 SND_PCM_NO_AUTO_FORMAT)) < 0) {
802 pa_log("Error opening PCM device %s: %s", u->device_name, pa_alsa_strerror(err));
806 ss = u->source->sample_spec;
807 nfrags = u->nfragments;
808 period_size = u->fragment_size / u->frame_size;
812 if ((err = pa_alsa_set_hw_params(u->pcm_handle, &ss, &nfrags, &period_size, u->hwbuf_size / u->frame_size, &b, &d, TRUE)) < 0) {
813 pa_log("Failed to set hardware parameters: %s", pa_alsa_strerror(err));
817 if (b != u->use_mmap || d != u->use_tsched) {
818 pa_log_warn("Resume failed, couldn't get original access mode.");
822 if (!pa_sample_spec_equal(&ss, &u->source->sample_spec)) {
823 pa_log_warn("Resume failed, couldn't restore original sample settings.");
827 if (nfrags != u->nfragments || period_size*u->frame_size != u->fragment_size) {
828 pa_log_warn("Resume failed, couldn't restore original fragment settings. (Old: %lu*%lu, New %lu*%lu)",
829 (unsigned long) u->nfragments, (unsigned long) u->fragment_size,
830 (unsigned long) nfrags, period_size * u->frame_size);
834 if (update_sw_params(u) < 0)
837 if (build_pollfd(u) < 0)
840 /* FIXME: We need to reload the volume somehow */
842 snd_pcm_start(u->pcm_handle);
843 pa_smoother_resume(u->smoother, pa_rtclock_now(), TRUE);
845 pa_log_info("Resumed successfully...");
851 snd_pcm_close(u->pcm_handle);
852 u->pcm_handle = NULL;
858 static int source_process_msg(pa_msgobject *o, int code, void *data, int64_t offset, pa_memchunk *chunk) {
859 struct userdata *u = PA_SOURCE(o)->userdata;
863 case PA_SOURCE_MESSAGE_GET_LATENCY: {
867 r = source_get_latency(u);
869 *((pa_usec_t*) data) = r;
874 case PA_SOURCE_MESSAGE_SET_STATE:
876 switch ((pa_source_state_t) PA_PTR_TO_UINT(data)) {
878 case PA_SOURCE_SUSPENDED:
879 pa_assert(PA_SOURCE_IS_OPENED(u->source->thread_info.state));
887 case PA_SOURCE_RUNNING:
889 if (u->source->thread_info.state == PA_SOURCE_INIT) {
890 if (build_pollfd(u) < 0)
893 snd_pcm_start(u->pcm_handle);
896 if (u->source->thread_info.state == PA_SOURCE_SUSPENDED) {
897 if (unsuspend(u) < 0)
903 case PA_SOURCE_UNLINKED:
905 case PA_SOURCE_INVALID_STATE:
912 return pa_source_process_msg(o, code, data, offset, chunk);
915 /* Called from main context */
916 static int source_set_state_cb(pa_source *s, pa_source_state_t new_state) {
917 pa_source_state_t old_state;
920 pa_source_assert_ref(s);
921 pa_assert_se(u = s->userdata);
923 old_state = pa_source_get_state(u->source);
925 if (PA_SINK_IS_OPENED(old_state) && new_state == PA_SINK_SUSPENDED)
927 else if (old_state == PA_SINK_SUSPENDED && PA_SINK_IS_OPENED(new_state))
928 if (reserve_init(u, u->device_name) < 0)
934 static int mixer_callback(snd_mixer_elem_t *elem, unsigned int mask) {
935 struct userdata *u = snd_mixer_elem_get_callback_private(elem);
938 pa_assert(u->mixer_handle);
940 if (mask == SND_CTL_EVENT_MASK_REMOVE)
943 if (mask & SND_CTL_EVENT_MASK_VALUE) {
944 pa_source_get_volume(u->source, TRUE);
945 pa_source_get_mute(u->source, TRUE);
951 static void source_get_volume_cb(pa_source *s) {
952 struct userdata *u = s->userdata;
954 char t[PA_CVOLUME_SNPRINT_MAX];
957 pa_assert(u->mixer_path);
958 pa_assert(u->mixer_handle);
960 if (pa_alsa_path_get_volume(u->mixer_path, u->mixer_handle, &s->channel_map, &r) < 0)
963 /* Shift down by the base volume, so that 0dB becomes maximum volume */
964 pa_sw_cvolume_multiply_scalar(&r, &r, s->base_volume);
966 pa_log_debug("Read hardware volume: %s", pa_cvolume_snprint(t, sizeof(t), &r));
968 if (pa_cvolume_equal(&u->hardware_volume, &r))
971 s->virtual_volume = u->hardware_volume = r;
973 if (u->mixer_path->has_dB) {
976 /* Hmm, so the hardware volume changed, let's reset our software volume */
977 pa_cvolume_reset(&reset, s->sample_spec.channels);
978 pa_source_set_soft_volume(s, &reset);
982 static void source_set_volume_cb(pa_source *s) {
983 struct userdata *u = s->userdata;
985 char t[PA_CVOLUME_SNPRINT_MAX];
988 pa_assert(u->mixer_path);
989 pa_assert(u->mixer_handle);
991 /* Shift up by the base volume */
992 pa_sw_cvolume_divide_scalar(&r, &s->virtual_volume, s->base_volume);
994 if (pa_alsa_path_set_volume(u->mixer_path, u->mixer_handle, &s->channel_map, &r) < 0)
997 /* Shift down by the base volume, so that 0dB becomes maximum volume */
998 pa_sw_cvolume_multiply_scalar(&r, &r, s->base_volume);
1000 u->hardware_volume = r;
1002 if (u->mixer_path->has_dB) {
1004 /* Match exactly what the user requested by software */
1005 pa_sw_cvolume_divide(&s->soft_volume, &s->virtual_volume, &u->hardware_volume);
1007 pa_log_debug("Requested volume: %s", pa_cvolume_snprint(t, sizeof(t), &s->virtual_volume));
1008 pa_log_debug("Got hardware volume: %s", pa_cvolume_snprint(t, sizeof(t), &u->hardware_volume));
1009 pa_log_debug("Calculated software volume: %s", pa_cvolume_snprint(t, sizeof(t), &s->soft_volume));
1012 pa_log_debug("Wrote hardware volume: %s", pa_cvolume_snprint(t, sizeof(t), &r));
1014 /* We can't match exactly what the user requested, hence let's
1015 * at least tell the user about it */
1017 s->virtual_volume = r;
1021 static void source_get_mute_cb(pa_source *s) {
1022 struct userdata *u = s->userdata;
1026 pa_assert(u->mixer_path);
1027 pa_assert(u->mixer_handle);
1029 if (pa_alsa_path_get_mute(u->mixer_path, u->mixer_handle, &b) < 0)
1035 static void source_set_mute_cb(pa_source *s) {
1036 struct userdata *u = s->userdata;
1039 pa_assert(u->mixer_path);
1040 pa_assert(u->mixer_handle);
1042 pa_alsa_path_set_mute(u->mixer_path, u->mixer_handle, s->muted);
1045 static int source_set_port_cb(pa_source *s, pa_device_port *p) {
1046 struct userdata *u = s->userdata;
1047 pa_alsa_port_data *data;
1051 pa_assert(u->mixer_handle);
1053 data = PA_DEVICE_PORT_DATA(p);
1055 pa_assert_se(u->mixer_path = data->path);
1056 pa_alsa_path_select(u->mixer_path, u->mixer_handle);
1058 if (u->mixer_path->has_volume && u->mixer_path->has_dB) {
1059 s->base_volume = pa_sw_volume_from_dB(-u->mixer_path->max_dB);
1060 s->n_volume_steps = PA_VOLUME_NORM+1;
1062 if (u->mixer_path->max_dB > 0.0)
1063 pa_log_info("Fixing base volume to %0.2f dB", pa_sw_volume_to_dB(s->base_volume));
1065 pa_log_info("No particular base volume set, fixing to 0 dB");
1067 s->base_volume = PA_VOLUME_NORM;
1068 s->n_volume_steps = u->mixer_path->max_volume - u->mixer_path->min_volume + 1;
1072 pa_alsa_setting_select(data->setting, u->mixer_handle);
1082 static void source_update_requested_latency_cb(pa_source *s) {
1083 struct userdata *u = s->userdata;
1089 update_sw_params(u);
1092 static void thread_func(void *userdata) {
1093 struct userdata *u = userdata;
1094 unsigned short revents = 0;
1098 pa_log_debug("Thread starting up");
1100 if (u->core->realtime_scheduling)
1101 pa_make_realtime(u->core->realtime_priority);
1103 pa_thread_mq_install(&u->thread_mq);
1109 pa_log_debug("Loop");
1112 /* Read some data and pass it to the sources */
1113 if (PA_SOURCE_IS_OPENED(u->source->thread_info.state)) {
1115 pa_usec_t sleep_usec = 0;
1118 work_done = mmap_read(u, &sleep_usec, revents & POLLIN);
1120 work_done = unix_read(u, &sleep_usec, revents & POLLIN);
1125 /* pa_log_debug("work_done = %i", work_done); */
1130 if (u->use_tsched) {
1133 /* OK, the capture buffer is now empty, let's
1134 * calculate when to wake up next */
1136 /* pa_log_debug("Waking up in %0.2fms (sound card clock).", (double) sleep_usec / PA_USEC_PER_MSEC); */
1138 /* Convert from the sound card time domain to the
1139 * system time domain */
1140 cusec = pa_smoother_translate(u->smoother, pa_rtclock_now(), sleep_usec);
1142 /* pa_log_debug("Waking up in %0.2fms (system clock).", (double) cusec / PA_USEC_PER_MSEC); */
1144 /* We don't trust the conversion, so we wake up whatever comes first */
1145 pa_rtpoll_set_timer_relative(u->rtpoll, PA_MIN(sleep_usec, cusec));
1147 } else if (u->use_tsched)
1149 /* OK, we're in an invalid state, let's disable our timers */
1150 pa_rtpoll_set_timer_disabled(u->rtpoll);
1152 /* Hmm, nothing to do. Let's sleep */
1153 if ((ret = pa_rtpoll_run(u->rtpoll, TRUE)) < 0)
1159 /* Tell ALSA about this and process its response */
1160 if (PA_SOURCE_IS_OPENED(u->source->thread_info.state)) {
1161 struct pollfd *pollfd;
1165 pollfd = pa_rtpoll_item_get_pollfd(u->alsa_rtpoll_item, &n);
1167 if ((err = snd_pcm_poll_descriptors_revents(u->pcm_handle, pollfd, n, &revents)) < 0) {
1168 pa_log("snd_pcm_poll_descriptors_revents() failed: %s", pa_alsa_strerror(err));
1172 if (revents & ~POLLIN) {
1173 if (pa_alsa_recover_from_poll(u->pcm_handle, revents) < 0)
1176 snd_pcm_start(u->pcm_handle);
1177 } else if (revents && u->use_tsched && pa_log_ratelimit())
1178 pa_log_debug("Wakeup from ALSA!");
1185 /* If this was no regular exit from the loop we have to continue
1186 * processing messages until we received PA_MESSAGE_SHUTDOWN */
1187 pa_asyncmsgq_post(u->thread_mq.outq, PA_MSGOBJECT(u->core), PA_CORE_MESSAGE_UNLOAD_MODULE, u->module, 0, NULL, NULL);
1188 pa_asyncmsgq_wait_for(u->thread_mq.inq, PA_MESSAGE_SHUTDOWN);
1191 pa_log_debug("Thread shutting down");
1194 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) {
1200 pa_assert(device_name);
1202 if ((n = pa_modargs_get_value(ma, "source_name", NULL))) {
1203 pa_source_new_data_set_name(data, n);
1204 data->namereg_fail = TRUE;
1208 if ((n = pa_modargs_get_value(ma, "name", NULL)))
1209 data->namereg_fail = TRUE;
1211 n = device_id ? device_id : device_name;
1212 data->namereg_fail = FALSE;
1216 t = pa_sprintf_malloc("alsa_input.%s.%s", n, mapping->name);
1218 t = pa_sprintf_malloc("alsa_input.%s", n);
1220 pa_source_new_data_set_name(data, t);
1224 static void find_mixer(struct userdata *u, pa_alsa_mapping *mapping, const char *element, pa_bool_t ignore_dB) {
1226 if (!mapping && !element)
1229 if (!(u->mixer_handle = pa_alsa_open_mixer_for_pcm(u->pcm_handle, &u->control_device))) {
1230 pa_log_info("Failed to find a working mixer device.");
1236 if (!(u->mixer_path = pa_alsa_path_synthesize(element, PA_ALSA_DIRECTION_INPUT)))
1239 if (pa_alsa_path_probe(u->mixer_path, u->mixer_handle, ignore_dB) < 0)
1242 pa_log_debug("Probed mixer path %s:", u->mixer_path->name);
1243 pa_alsa_path_dump(u->mixer_path);
1246 if (!(u->mixer_path_set = pa_alsa_path_set_new(mapping, PA_ALSA_DIRECTION_INPUT)))
1249 pa_alsa_path_set_probe(u->mixer_path_set, u->mixer_handle, ignore_dB);
1251 pa_log_debug("Probed mixer paths:");
1252 pa_alsa_path_set_dump(u->mixer_path_set);
1259 if (u->mixer_path_set) {
1260 pa_alsa_path_set_free(u->mixer_path_set);
1261 u->mixer_path_set = NULL;
1262 } else if (u->mixer_path) {
1263 pa_alsa_path_free(u->mixer_path);
1264 u->mixer_path = NULL;
1267 if (u->mixer_handle) {
1268 snd_mixer_close(u->mixer_handle);
1269 u->mixer_handle = NULL;
1273 static int setup_mixer(struct userdata *u, pa_bool_t ignore_dB) {
1276 if (!u->mixer_handle)
1279 if (u->source->active_port) {
1280 pa_alsa_port_data *data;
1282 /* We have a list of supported paths, so let's activate the
1283 * one that has been chosen as active */
1285 data = PA_DEVICE_PORT_DATA(u->source->active_port);
1286 u->mixer_path = data->path;
1288 pa_alsa_path_select(data->path, u->mixer_handle);
1291 pa_alsa_setting_select(data->setting, u->mixer_handle);
1295 if (!u->mixer_path && u->mixer_path_set)
1296 u->mixer_path = u->mixer_path_set->paths;
1298 if (u->mixer_path) {
1299 /* Hmm, we have only a single path, then let's activate it */
1301 pa_alsa_path_select(u->mixer_path, u->mixer_handle);
1303 if (u->mixer_path->settings)
1304 pa_alsa_setting_select(u->mixer_path->settings, u->mixer_handle);
1309 if (!u->mixer_path->has_volume)
1310 pa_log_info("Driver does not support hardware volume control, falling back to software volume control.");
1313 if (u->mixer_path->has_dB) {
1314 pa_log_info("Hardware volume ranges from %0.2f dB to %0.2f dB.", u->mixer_path->min_dB, u->mixer_path->max_dB);
1316 u->source->base_volume = pa_sw_volume_from_dB(-u->mixer_path->max_dB);
1317 u->source->n_volume_steps = PA_VOLUME_NORM+1;
1319 if (u->mixer_path->max_dB > 0.0)
1320 pa_log_info("Fixing base volume to %0.2f dB", pa_sw_volume_to_dB(u->source->base_volume));
1322 pa_log_info("No particular base volume set, fixing to 0 dB");
1325 pa_log_info("Hardware volume ranges from %li to %li.", u->mixer_path->min_volume, u->mixer_path->max_volume);
1326 u->source->base_volume = PA_VOLUME_NORM;
1327 u->source->n_volume_steps = u->mixer_path->max_volume - u->mixer_path->min_volume + 1;
1330 u->source->get_volume = source_get_volume_cb;
1331 u->source->set_volume = source_set_volume_cb;
1333 u->source->flags |= PA_SOURCE_HW_VOLUME_CTRL | (u->mixer_path->has_dB ? PA_SOURCE_DECIBEL_VOLUME : 0);
1334 pa_log_info("Using hardware volume control. Hardware dB scale %s.", u->mixer_path->has_dB ? "supported" : "not supported");
1337 if (!u->mixer_path->has_mute) {
1338 pa_log_info("Driver does not support hardware mute control, falling back to software mute control.");
1340 u->source->get_mute = source_get_mute_cb;
1341 u->source->set_mute = source_set_mute_cb;
1342 u->source->flags |= PA_SOURCE_HW_MUTE_CTRL;
1343 pa_log_info("Using hardware mute control.");
1346 u->mixer_fdl = pa_alsa_fdlist_new();
1348 if (pa_alsa_fdlist_set_mixer(u->mixer_fdl, u->mixer_handle, u->core->mainloop) < 0) {
1349 pa_log("Failed to initialize file descriptor monitoring");
1353 if (u->mixer_path_set)
1354 pa_alsa_path_set_set_callback(u->mixer_path_set, u->mixer_handle, mixer_callback, u);
1356 pa_alsa_path_set_callback(u->mixer_path, u->mixer_handle, mixer_callback, u);
1361 pa_source *pa_alsa_source_new(pa_module *m, pa_modargs *ma, const char*driver, pa_card *card, pa_alsa_mapping *mapping) {
1363 struct userdata *u = NULL;
1364 const char *dev_id = NULL;
1365 pa_sample_spec ss, requested_ss;
1367 uint32_t nfrags, hwbuf_size, frag_size, tsched_size, tsched_watermark;
1368 snd_pcm_uframes_t period_frames, tsched_frames;
1370 pa_bool_t use_mmap = TRUE, b, use_tsched = TRUE, d, ignore_dB = FALSE;
1371 pa_source_new_data data;
1372 pa_alsa_profile_set *profile_set = NULL;
1377 ss = m->core->default_sample_spec;
1378 map = m->core->default_channel_map;
1379 if (pa_modargs_get_sample_spec_and_channel_map(ma, &ss, &map, PA_CHANNEL_MAP_ALSA) < 0) {
1380 pa_log("Failed to parse sample specification");
1385 frame_size = pa_frame_size(&ss);
1387 nfrags = m->core->default_n_fragments;
1388 frag_size = (uint32_t) pa_usec_to_bytes(m->core->default_fragment_size_msec*PA_USEC_PER_MSEC, &ss);
1390 frag_size = (uint32_t) frame_size;
1391 tsched_size = (uint32_t) pa_usec_to_bytes(DEFAULT_TSCHED_BUFFER_USEC, &ss);
1392 tsched_watermark = (uint32_t) pa_usec_to_bytes(DEFAULT_TSCHED_WATERMARK_USEC, &ss);
1394 if (pa_modargs_get_value_u32(ma, "fragments", &nfrags) < 0 ||
1395 pa_modargs_get_value_u32(ma, "fragment_size", &frag_size) < 0 ||
1396 pa_modargs_get_value_u32(ma, "tsched_buffer_size", &tsched_size) < 0 ||
1397 pa_modargs_get_value_u32(ma, "tsched_buffer_watermark", &tsched_watermark) < 0) {
1398 pa_log("Failed to parse buffer metrics");
1402 hwbuf_size = frag_size * nfrags;
1403 period_frames = frag_size/frame_size;
1404 tsched_frames = tsched_size/frame_size;
1406 if (pa_modargs_get_value_boolean(ma, "mmap", &use_mmap) < 0) {
1407 pa_log("Failed to parse mmap argument.");
1411 if (pa_modargs_get_value_boolean(ma, "tsched", &use_tsched) < 0) {
1412 pa_log("Failed to parse timer_scheduling argument.");
1416 if (pa_modargs_get_value_boolean(ma, "ignore_dB", &ignore_dB) < 0) {
1417 pa_log("Failed to parse ignore_dB argument.");
1421 if (use_tsched && !pa_rtclock_hrtimer()) {
1422 pa_log_notice("Disabling timer-based scheduling because high-resolution timers are not available from the kernel.");
1426 u = pa_xnew0(struct userdata, 1);
1429 u->use_mmap = use_mmap;
1430 u->use_tsched = use_tsched;
1431 u->rtpoll = pa_rtpoll_new();
1432 pa_thread_mq_init(&u->thread_mq, m->core->mainloop, u->rtpoll);
1434 u->smoother = pa_smoother_new(
1435 DEFAULT_TSCHED_WATERMARK_USEC*2,
1436 DEFAULT_TSCHED_WATERMARK_USEC*2,
1443 dev_id = pa_modargs_get_value(
1445 pa_modargs_get_value(ma, "device", DEFAULT_DEVICE));
1447 if (reserve_init(u, dev_id) < 0)
1450 if (reserve_monitor_init(u, dev_id) < 0)
1458 if (!(dev_id = pa_modargs_get_value(ma, "device_id", NULL))) {
1459 pa_log("device_id= not set");
1463 if (!(u->pcm_handle = pa_alsa_open_by_device_id_mapping(
1467 SND_PCM_STREAM_CAPTURE,
1468 &nfrags, &period_frames, tsched_frames,
1472 } else if ((dev_id = pa_modargs_get_value(ma, "device_id", NULL))) {
1474 if (!(profile_set = pa_alsa_profile_set_new(NULL, &map)))
1477 if (!(u->pcm_handle = pa_alsa_open_by_device_id_auto(
1481 SND_PCM_STREAM_CAPTURE,
1482 &nfrags, &period_frames, tsched_frames,
1483 &b, &d, profile_set, &mapping)))
1488 if (!(u->pcm_handle = pa_alsa_open_by_device_string(
1489 pa_modargs_get_value(ma, "device", DEFAULT_DEVICE),
1492 SND_PCM_STREAM_CAPTURE,
1493 &nfrags, &period_frames, tsched_frames,
1498 pa_assert(u->device_name);
1499 pa_log_info("Successfully opened device %s.", u->device_name);
1501 if (pa_alsa_pcm_is_modem(u->pcm_handle)) {
1502 pa_log_notice("Device %s is modem, refusing further initialization.", u->device_name);
1507 pa_log_info("Selected mapping '%s' (%s).", mapping->description, mapping->name);
1509 if (use_mmap && !b) {
1510 pa_log_info("Device doesn't support mmap(), falling back to UNIX read/write mode.");
1511 u->use_mmap = use_mmap = FALSE;
1514 if (use_tsched && (!b || !d)) {
1515 pa_log_info("Cannot enable timer-based scheduling, falling back to sound IRQ scheduling.");
1516 u->use_tsched = use_tsched = FALSE;
1519 if (use_tsched && !pa_alsa_pcm_is_hw(u->pcm_handle)) {
1520 pa_log_info("Device is not a hardware device, disabling timer-based scheduling.");
1521 u->use_tsched = use_tsched = FALSE;
1525 pa_log_info("Successfully enabled mmap() mode.");
1528 pa_log_info("Successfully enabled timer-based scheduling mode.");
1530 /* ALSA might tweak the sample spec, so recalculate the frame size */
1531 frame_size = pa_frame_size(&ss);
1533 find_mixer(u, mapping, pa_modargs_get_value(ma, "control", NULL), ignore_dB);
1535 pa_source_new_data_init(&data);
1536 data.driver = driver;
1539 set_source_name(&data, ma, dev_id, u->device_name, mapping);
1540 pa_source_new_data_set_sample_spec(&data, &ss);
1541 pa_source_new_data_set_channel_map(&data, &map);
1543 pa_alsa_init_proplist_pcm(m->core, data.proplist, u->pcm_handle);
1544 pa_proplist_sets(data.proplist, PA_PROP_DEVICE_STRING, u->device_name);
1545 pa_proplist_setf(data.proplist, PA_PROP_DEVICE_BUFFERING_BUFFER_SIZE, "%lu", (unsigned long) (period_frames * frame_size * nfrags));
1546 pa_proplist_setf(data.proplist, PA_PROP_DEVICE_BUFFERING_FRAGMENT_SIZE, "%lu", (unsigned long) (period_frames * frame_size));
1547 pa_proplist_sets(data.proplist, PA_PROP_DEVICE_ACCESS_MODE, u->use_tsched ? "mmap+timer" : (u->use_mmap ? "mmap" : "serial"));
1550 pa_proplist_sets(data.proplist, PA_PROP_DEVICE_PROFILE_NAME, mapping->name);
1551 pa_proplist_sets(data.proplist, PA_PROP_DEVICE_PROFILE_DESCRIPTION, mapping->description);
1554 pa_alsa_init_description(data.proplist);
1556 if (u->control_device)
1557 pa_alsa_init_proplist_ctl(data.proplist, u->control_device);
1559 if (pa_modargs_get_proplist(ma, "source_properties", data.proplist, PA_UPDATE_REPLACE) < 0) {
1560 pa_log("Invalid properties");
1561 pa_source_new_data_done(&data);
1565 if (u->mixer_path_set)
1566 pa_alsa_add_ports(&data.ports, u->mixer_path_set);
1568 u->source = pa_source_new(m->core, &data, PA_SOURCE_HARDWARE|PA_SOURCE_LATENCY|(u->use_tsched ? PA_SOURCE_DYNAMIC_LATENCY : 0));
1569 pa_source_new_data_done(&data);
1572 pa_log("Failed to create source object");
1576 u->source->parent.process_msg = source_process_msg;
1577 u->source->update_requested_latency = source_update_requested_latency_cb;
1578 u->source->set_state = source_set_state_cb;
1579 u->source->set_port = source_set_port_cb;
1580 u->source->userdata = u;
1582 pa_source_set_asyncmsgq(u->source, u->thread_mq.inq);
1583 pa_source_set_rtpoll(u->source, u->rtpoll);
1585 u->frame_size = frame_size;
1586 u->fragment_size = frag_size = (uint32_t) (period_frames * frame_size);
1587 u->nfragments = nfrags;
1588 u->hwbuf_size = u->fragment_size * nfrags;
1589 u->tsched_watermark = pa_usec_to_bytes_round_up(pa_bytes_to_usec_round_up(tsched_watermark, &requested_ss), &u->source->sample_spec);
1590 pa_cvolume_mute(&u->hardware_volume, u->source->sample_spec.channels);
1592 pa_log_info("Using %u fragments of size %lu bytes, buffer time is %0.2fms",
1593 nfrags, (long unsigned) u->fragment_size,
1594 (double) pa_bytes_to_usec(u->hwbuf_size, &ss) / PA_USEC_PER_MSEC);
1596 if (u->use_tsched) {
1597 u->watermark_step = pa_usec_to_bytes(TSCHED_WATERMARK_STEP_USEC, &u->source->sample_spec);
1599 fix_min_sleep_wakeup(u);
1600 fix_tsched_watermark(u);
1602 pa_source_set_latency_range(u->source,
1604 pa_bytes_to_usec(u->hwbuf_size, &ss));
1606 pa_log_info("Time scheduling watermark is %0.2fms",
1607 (double) pa_bytes_to_usec(u->tsched_watermark, &ss) / PA_USEC_PER_MSEC);
1609 pa_source_set_fixed_latency(u->source, pa_bytes_to_usec(u->hwbuf_size, &ss));
1613 if (update_sw_params(u) < 0)
1616 if (setup_mixer(u, ignore_dB) < 0)
1619 pa_alsa_dump(PA_LOG_DEBUG, u->pcm_handle);
1621 if (!(u->thread = pa_thread_new(thread_func, u))) {
1622 pa_log("Failed to create thread.");
1625 /* Get initial mixer settings */
1626 if (data.volume_is_set) {
1627 if (u->source->set_volume)
1628 u->source->set_volume(u->source);
1630 if (u->source->get_volume)
1631 u->source->get_volume(u->source);
1634 if (data.muted_is_set) {
1635 if (u->source->set_mute)
1636 u->source->set_mute(u->source);
1638 if (u->source->get_mute)
1639 u->source->get_mute(u->source);
1642 pa_source_put(u->source);
1645 pa_alsa_profile_set_free(profile_set);
1655 pa_alsa_profile_set_free(profile_set);
1660 static void userdata_free(struct userdata *u) {
1664 pa_source_unlink(u->source);
1667 pa_asyncmsgq_send(u->thread_mq.inq, NULL, PA_MESSAGE_SHUTDOWN, NULL, 0, NULL);
1668 pa_thread_free(u->thread);
1671 pa_thread_mq_done(&u->thread_mq);
1674 pa_source_unref(u->source);
1676 if (u->alsa_rtpoll_item)
1677 pa_rtpoll_item_free(u->alsa_rtpoll_item);
1680 pa_rtpoll_free(u->rtpoll);
1682 if (u->pcm_handle) {
1683 snd_pcm_drop(u->pcm_handle);
1684 snd_pcm_close(u->pcm_handle);
1688 pa_alsa_fdlist_free(u->mixer_fdl);
1690 if (u->mixer_path_set)
1691 pa_alsa_path_set_free(u->mixer_path_set);
1692 else if (u->mixer_path)
1693 pa_alsa_path_free(u->mixer_path);
1695 if (u->mixer_handle)
1696 snd_mixer_close(u->mixer_handle);
1699 pa_smoother_free(u->smoother);
1704 pa_xfree(u->device_name);
1705 pa_xfree(u->control_device);
1709 void pa_alsa_source_free(pa_source *s) {
1712 pa_source_assert_ref(s);
1713 pa_assert_se(u = s->userdata);