]> code.delx.au - pulseaudio/blob - src/modules/module-alsa-source.c
Merge branch 'new-world-order'
[pulseaudio] / src / modules / module-alsa-source.c
1 /***
2 This file is part of PulseAudio.
3
4 Copyright 2004-2008 Lennart Poettering
5 Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
6
7 PulseAudio is free software; you can redistribute it and/or modify
8 it under the terms of the GNU Lesser General Public License as published
9 by the Free Software Foundation; either version 2 of the License,
10 or (at your option) any later version.
11
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.
16
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
20 USA.
21 ***/
22
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26
27 #include <stdio.h>
28
29 #include <asoundlib.h>
30
31 #ifdef HAVE_VALGRIND_MEMCHECK_H
32 #include <valgrind/memcheck.h>
33 #endif
34
35 #include <pulse/xmalloc.h>
36 #include <pulse/util.h>
37 #include <pulse/timeval.h>
38
39 #include <pulsecore/core-error.h>
40 #include <pulsecore/core.h>
41 #include <pulsecore/module.h>
42 #include <pulsecore/memchunk.h>
43 #include <pulsecore/sink.h>
44 #include <pulsecore/modargs.h>
45 #include <pulsecore/core-util.h>
46 #include <pulsecore/sample-util.h>
47 #include <pulsecore/log.h>
48 #include <pulsecore/macro.h>
49 #include <pulsecore/thread.h>
50 #include <pulsecore/core-error.h>
51 #include <pulsecore/thread-mq.h>
52 #include <pulsecore/rtpoll.h>
53 #include <pulsecore/time-smoother.h>
54 #include <pulsecore/rtclock.h>
55
56 #include "alsa-util.h"
57 #include "module-alsa-source-symdef.h"
58
59 PA_MODULE_AUTHOR("Lennart Poettering");
60 PA_MODULE_DESCRIPTION("ALSA Source");
61 PA_MODULE_VERSION(PACKAGE_VERSION);
62 PA_MODULE_LOAD_ONCE(FALSE);
63 PA_MODULE_USAGE(
64 "source_name=<name for the source> "
65 "device=<ALSA device> "
66 "device_id=<ALSA card index> "
67 "format=<sample format> "
68 "rate=<sample rate> "
69 "channels=<number of channels> "
70 "channel_map=<channel map> "
71 "fragments=<number of fragments> "
72 "fragment_size=<fragment size> "
73 "mmap=<enable memory mapping?> "
74 "tsched=<enable system timer based scheduling mode?> "
75 "tsched_buffer_size=<buffer size when using timer based scheduling> "
76 "tsched_buffer_watermark=<upper fill watermark>");
77
78 static const char* const valid_modargs[] = {
79 "source_name",
80 "device",
81 "device_id",
82 "format",
83 "rate",
84 "channels",
85 "channel_map",
86 "fragments",
87 "fragment_size",
88 "mmap",
89 "tsched",
90 "tsched_buffer_size",
91 "tsched_buffer_watermark",
92 NULL
93 };
94
95 #define DEFAULT_DEVICE "default"
96 #define DEFAULT_TSCHED_BUFFER_USEC (2*PA_USEC_PER_SEC) /* 2s */
97 #define DEFAULT_TSCHED_WATERMARK_USEC (20*PA_USEC_PER_MSEC) /* 20ms */
98 #define TSCHED_MIN_SLEEP_USEC (3*PA_USEC_PER_MSEC) /* 3ms */
99 #define TSCHED_MIN_WAKEUP_USEC (3*PA_USEC_PER_MSEC) /* 3ms */
100
101 struct userdata {
102 pa_core *core;
103 pa_module *module;
104 pa_source *source;
105
106 pa_thread *thread;
107 pa_thread_mq thread_mq;
108 pa_rtpoll *rtpoll;
109
110 snd_pcm_t *pcm_handle;
111
112 pa_alsa_fdlist *mixer_fdl;
113 snd_mixer_t *mixer_handle;
114 snd_mixer_elem_t *mixer_elem;
115 long hw_volume_max, hw_volume_min;
116 long hw_dB_max, hw_dB_min;
117 pa_bool_t hw_dB_supported;
118 pa_bool_t mixer_seperate_channels;
119
120 pa_cvolume hardware_volume;
121
122 size_t frame_size, fragment_size, hwbuf_size, tsched_watermark;
123 unsigned nfragments;
124
125 char *device_name;
126
127 pa_bool_t use_mmap, use_tsched;
128
129 pa_rtpoll_item *alsa_rtpoll_item;
130
131 snd_mixer_selem_channel_id_t mixer_map[SND_MIXER_SCHN_LAST];
132
133 pa_smoother *smoother;
134 int64_t frame_index;
135
136 snd_pcm_sframes_t hwbuf_unused_frames;
137 };
138
139 static void fix_tsched_watermark(struct userdata *u) {
140 size_t max_use;
141 size_t min_sleep, min_wakeup;
142 pa_assert(u);
143
144 max_use = u->hwbuf_size - (size_t) u->hwbuf_unused_frames * u->frame_size;
145
146 min_sleep = pa_usec_to_bytes(TSCHED_MIN_SLEEP_USEC, &u->source->sample_spec);
147 min_wakeup = pa_usec_to_bytes(TSCHED_MIN_WAKEUP_USEC, &u->source->sample_spec);
148
149 if (min_sleep > max_use/2)
150 min_sleep = pa_frame_align(max_use/2, &u->source->sample_spec);
151 if (min_sleep < u->frame_size)
152 min_sleep = u->frame_size;
153
154 if (min_wakeup > max_use/2)
155 min_wakeup = pa_frame_align(max_use/2, &u->source->sample_spec);
156 if (min_wakeup < u->frame_size)
157 min_wakeup = u->frame_size;
158
159 if (u->tsched_watermark > max_use-min_sleep)
160 u->tsched_watermark = max_use-min_sleep;
161
162 if (u->tsched_watermark < min_wakeup)
163 u->tsched_watermark = min_wakeup;
164 }
165
166 static pa_usec_t hw_sleep_time(struct userdata *u, pa_usec_t *sleep_usec, pa_usec_t*process_usec) {
167 pa_usec_t wm, usec;
168
169 pa_assert(u);
170
171 usec = pa_source_get_requested_latency_within_thread(u->source);
172
173 if (usec == (pa_usec_t) -1)
174 usec = pa_bytes_to_usec(u->hwbuf_size, &u->source->sample_spec);
175
176 /* pa_log_debug("hw buffer time: %u ms", (unsigned) (usec / PA_USEC_PER_MSEC)); */
177
178 wm = pa_bytes_to_usec(u->tsched_watermark, &u->source->sample_spec);
179
180 if (usec >= wm) {
181 *sleep_usec = usec - wm;
182 *process_usec = wm;
183 } else
184 *process_usec = *sleep_usec = usec /= 2;
185
186 /* pa_log_debug("after watermark: %u ms", (unsigned) (*sleep_usec / PA_USEC_PER_MSEC)); */
187
188 return usec;
189 }
190
191 static int try_recover(struct userdata *u, const char *call, int err) {
192 pa_assert(u);
193 pa_assert(call);
194 pa_assert(err < 0);
195
196 pa_log_debug("%s: %s", call, snd_strerror(err));
197
198 pa_assert(err != -EAGAIN);
199
200 if (err == -EPIPE)
201 pa_log_debug("%s: Buffer overrun!", call);
202
203 if ((err = snd_pcm_recover(u->pcm_handle, err, 1)) == 0) {
204 snd_pcm_start(u->pcm_handle);
205 return 0;
206 }
207
208 pa_log("%s: %s", call, snd_strerror(err));
209 return -1;
210 }
211
212 static size_t check_left_to_record(struct userdata *u, snd_pcm_sframes_t n) {
213 size_t left_to_record;
214 size_t rec_space = u->hwbuf_size - (size_t) u->hwbuf_unused_frames*u->frame_size;
215
216 if ((size_t) n*u->frame_size < rec_space)
217 left_to_record = rec_space - ((size_t) n*u->frame_size);
218 else
219 left_to_record = 0;
220
221 if (left_to_record > 0) {
222 /* 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); */
223 } else {
224 pa_log_info("Overrun!");
225
226 if (u->use_tsched) {
227 size_t old_watermark = u->tsched_watermark;
228
229 u->tsched_watermark *= 2;
230 fix_tsched_watermark(u);
231
232 if (old_watermark != u->tsched_watermark)
233 pa_log_notice("Increasing wakeup watermark to %0.2f ms",
234 (double) pa_bytes_to_usec(u->tsched_watermark, &u->source->sample_spec) / PA_USEC_PER_MSEC);
235 }
236 }
237
238 return left_to_record;
239 }
240
241 static int mmap_read(struct userdata *u, pa_usec_t *sleep_usec, pa_bool_t polled) {
242 int work_done = 0;
243 pa_usec_t max_sleep_usec = 0, process_usec = 0;
244 size_t left_to_record;
245
246 pa_assert(u);
247 pa_source_assert_ref(u->source);
248
249 if (u->use_tsched)
250 hw_sleep_time(u, &max_sleep_usec, &process_usec);
251
252 for (;;) {
253 snd_pcm_sframes_t n;
254 int r;
255
256 snd_pcm_hwsync(u->pcm_handle);
257
258 if (PA_UNLIKELY((n = pa_alsa_safe_avail_update(u->pcm_handle, u->hwbuf_size, &u->source->sample_spec)) < 0)) {
259
260 if ((r = try_recover(u, "snd_pcm_avail_update", (int) n)) == 0)
261 continue;
262
263 return r;
264 }
265
266 left_to_record = check_left_to_record(u, n);
267
268 if (u->use_tsched)
269 if (!polled &&
270 pa_bytes_to_usec(left_to_record, &u->source->sample_spec) > process_usec+max_sleep_usec/2)
271 break;
272
273 if (PA_UNLIKELY(n <= 0)) {
274
275 if (polled)
276 pa_log("ALSA woke us up to read new data from the device, but there was actually nothing to read! "
277 "Most likely this is an ALSA driver bug. Please report this issue to the PulseAudio device.");
278
279 break;
280 }
281
282 polled = FALSE;
283
284 for (;;) {
285 int err;
286 const snd_pcm_channel_area_t *areas;
287 snd_pcm_uframes_t offset, frames = (snd_pcm_uframes_t) n;
288 pa_memchunk chunk;
289 void *p;
290 snd_pcm_sframes_t sframes;
291
292 /* pa_log_debug("%lu frames to read", (unsigned long) frames); */
293
294 if (PA_UNLIKELY((err = pa_alsa_safe_mmap_begin(u->pcm_handle, &areas, &offset, &frames, u->hwbuf_size, &u->source->sample_spec)) < 0)) {
295
296 if ((r = try_recover(u, "snd_pcm_mmap_begin", err)) == 0)
297 continue;
298
299 return r;
300 }
301
302 /* Make sure that if these memblocks need to be copied they will fit into one slot */
303 if (frames > pa_mempool_block_size_max(u->source->core->mempool)/u->frame_size)
304 frames = pa_mempool_block_size_max(u->source->core->mempool)/u->frame_size;
305
306 /* Check these are multiples of 8 bit */
307 pa_assert((areas[0].first & 7) == 0);
308 pa_assert((areas[0].step & 7)== 0);
309
310 /* We assume a single interleaved memory buffer */
311 pa_assert((areas[0].first >> 3) == 0);
312 pa_assert((areas[0].step >> 3) == u->frame_size);
313
314 p = (uint8_t*) areas[0].addr + (offset * u->frame_size);
315
316 chunk.memblock = pa_memblock_new_fixed(u->core->mempool, p, frames * u->frame_size, TRUE);
317 chunk.length = pa_memblock_get_length(chunk.memblock);
318 chunk.index = 0;
319
320 pa_source_post(u->source, &chunk);
321 pa_memblock_unref_fixed(chunk.memblock);
322
323 if (PA_UNLIKELY((sframes = snd_pcm_mmap_commit(u->pcm_handle, offset, frames)) < 0)) {
324
325 if ((r = try_recover(u, "snd_pcm_mmap_commit", (int) sframes)) == 0)
326 continue;
327
328 return r;
329 }
330
331 work_done = 1;
332
333 u->frame_index += (int64_t) frames;
334
335 /* pa_log_debug("read %lu frames", (unsigned long) frames); */
336
337 if (frames >= (snd_pcm_uframes_t) n)
338 break;
339
340 n -= (snd_pcm_sframes_t) frames;
341 }
342 }
343
344 *sleep_usec = pa_bytes_to_usec(left_to_record, &u->source->sample_spec) - process_usec;
345 return work_done;
346 }
347
348 static int unix_read(struct userdata *u, pa_usec_t *sleep_usec, pa_bool_t polled) {
349 int work_done = 0;
350 pa_usec_t max_sleep_usec = 0, process_usec = 0;
351 size_t left_to_record;
352
353 pa_assert(u);
354 pa_source_assert_ref(u->source);
355
356 if (u->use_tsched)
357 hw_sleep_time(u, &max_sleep_usec, &process_usec);
358
359 for (;;) {
360 snd_pcm_sframes_t n;
361 int r;
362
363 snd_pcm_hwsync(u->pcm_handle);
364
365 if (PA_UNLIKELY((n = pa_alsa_safe_avail_update(u->pcm_handle, u->hwbuf_size, &u->source->sample_spec)) < 0)) {
366
367 if ((r = try_recover(u, "snd_pcm_avail_update", (int) n)) == 0)
368 continue;
369
370 return r;
371 }
372
373 left_to_record = check_left_to_record(u, n);
374
375 if (u->use_tsched)
376 if (!polled &&
377 pa_bytes_to_usec(left_to_record, &u->source->sample_spec) > process_usec+max_sleep_usec/2)
378 break;
379
380 if (PA_UNLIKELY(n <= 0)) {
381
382 if (polled)
383 pa_log("ALSA woke us up to read new data from the device, but there was actually nothing to read! "
384 "Most likely this is an ALSA driver bug. Please report this issue to the PulseAudio developers.");
385
386 return work_done;
387 }
388
389 polled = FALSE;
390
391 for (;;) {
392 void *p;
393 snd_pcm_sframes_t frames;
394 pa_memchunk chunk;
395
396 chunk.memblock = pa_memblock_new(u->core->mempool, (size_t) -1);
397
398 frames = (snd_pcm_sframes_t) (pa_memblock_get_length(chunk.memblock) / u->frame_size);
399
400 if (frames > n)
401 frames = n;
402
403 /* pa_log_debug("%lu frames to read", (unsigned long) n); */
404
405 p = pa_memblock_acquire(chunk.memblock);
406 frames = snd_pcm_readi(u->pcm_handle, (uint8_t*) p, (snd_pcm_uframes_t) frames);
407 pa_memblock_release(chunk.memblock);
408
409 pa_assert(frames != 0);
410
411 if (PA_UNLIKELY(frames < 0)) {
412 pa_memblock_unref(chunk.memblock);
413
414 if ((r = try_recover(u, "snd_pcm_readi", (int) (frames))) == 0)
415 continue;
416
417 return r;
418 }
419
420 chunk.index = 0;
421 chunk.length = (size_t) frames * u->frame_size;
422
423 pa_source_post(u->source, &chunk);
424 pa_memblock_unref(chunk.memblock);
425
426 work_done = 1;
427
428 u->frame_index += frames;
429
430 /* pa_log_debug("read %lu frames", (unsigned long) frames); */
431
432 if (frames >= n)
433 break;
434
435 n -= frames;
436 }
437 }
438
439 *sleep_usec = pa_bytes_to_usec(left_to_record, &u->source->sample_spec) - process_usec;
440 return work_done;
441 }
442
443 static void update_smoother(struct userdata *u) {
444 snd_pcm_sframes_t delay = 0;
445 int64_t frames;
446 int err;
447 pa_usec_t now1, now2;
448
449 pa_assert(u);
450 pa_assert(u->pcm_handle);
451
452 /* Let's update the time smoother */
453
454 snd_pcm_hwsync(u->pcm_handle);
455 snd_pcm_avail_update(u->pcm_handle);
456
457 if (PA_UNLIKELY((err = snd_pcm_delay(u->pcm_handle, &delay)) < 0)) {
458 pa_log_warn("Failed to get delay: %s", snd_strerror(err));
459 return;
460 }
461
462 frames = u->frame_index + delay;
463
464 now1 = pa_rtclock_usec();
465 now2 = pa_bytes_to_usec((uint64_t) frames * u->frame_size, &u->source->sample_spec);
466
467 pa_smoother_put(u->smoother, now1, now2);
468 }
469
470 static pa_usec_t source_get_latency(struct userdata *u) {
471 pa_usec_t r = 0;
472 int64_t delay;
473 pa_usec_t now1, now2;
474
475 pa_assert(u);
476
477 now1 = pa_rtclock_usec();
478 now2 = pa_smoother_get(u->smoother, now1);
479
480 delay = (int64_t) now2 - (int64_t) pa_bytes_to_usec((uint64_t) u->frame_index * u->frame_size, &u->source->sample_spec);
481
482 if (delay > 0)
483 r = (pa_usec_t) delay;
484
485 return r;
486 }
487
488 static int build_pollfd(struct userdata *u) {
489 pa_assert(u);
490 pa_assert(u->pcm_handle);
491
492 if (u->alsa_rtpoll_item)
493 pa_rtpoll_item_free(u->alsa_rtpoll_item);
494
495 if (!(u->alsa_rtpoll_item = pa_alsa_build_pollfd(u->pcm_handle, u->rtpoll)))
496 return -1;
497
498 return 0;
499 }
500
501 static int suspend(struct userdata *u) {
502 pa_assert(u);
503 pa_assert(u->pcm_handle);
504
505 pa_smoother_pause(u->smoother, pa_rtclock_usec());
506
507 /* Let's suspend */
508 snd_pcm_close(u->pcm_handle);
509 u->pcm_handle = NULL;
510
511 if (u->alsa_rtpoll_item) {
512 pa_rtpoll_item_free(u->alsa_rtpoll_item);
513 u->alsa_rtpoll_item = NULL;
514 }
515
516 pa_log_info("Device suspended...");
517
518 return 0;
519 }
520
521 static int update_sw_params(struct userdata *u) {
522 snd_pcm_uframes_t avail_min;
523 int err;
524
525 pa_assert(u);
526
527 /* Use the full buffer if noone asked us for anything specific */
528 u->hwbuf_unused_frames = 0;
529
530 if (u->use_tsched) {
531 pa_usec_t latency;
532
533 if ((latency = pa_source_get_requested_latency_within_thread(u->source)) != (pa_usec_t) -1) {
534 size_t b;
535
536 pa_log_debug("latency set to %0.2fms", (double) latency / PA_USEC_PER_MSEC);
537
538 b = pa_usec_to_bytes(latency, &u->source->sample_spec);
539
540 /* We need at least one sample in our buffer */
541
542 if (PA_UNLIKELY(b < u->frame_size))
543 b = u->frame_size;
544
545 u->hwbuf_unused_frames = (snd_pcm_sframes_t)
546 (PA_LIKELY(b < u->hwbuf_size) ?
547 ((u->hwbuf_size - b) / u->frame_size) : 0);
548
549 fix_tsched_watermark(u);
550 }
551 }
552
553 pa_log_debug("hwbuf_unused_frames=%lu", (unsigned long) u->hwbuf_unused_frames);
554
555 avail_min = 1;
556
557 if (u->use_tsched) {
558 pa_usec_t sleep_usec, process_usec;
559
560 hw_sleep_time(u, &sleep_usec, &process_usec);
561 avail_min += pa_usec_to_bytes(sleep_usec, &u->source->sample_spec);
562 }
563
564 pa_log_debug("setting avail_min=%lu", (unsigned long) avail_min);
565
566 if ((err = pa_alsa_set_sw_params(u->pcm_handle, avail_min)) < 0) {
567 pa_log("Failed to set software parameters: %s", snd_strerror(err));
568 return err;
569 }
570
571 return 0;
572 }
573
574 static int unsuspend(struct userdata *u) {
575 pa_sample_spec ss;
576 int err;
577 pa_bool_t b, d;
578 unsigned nfrags;
579 snd_pcm_uframes_t period_size;
580
581 pa_assert(u);
582 pa_assert(!u->pcm_handle);
583
584 pa_log_info("Trying resume...");
585
586 snd_config_update_free_global();
587
588 if ((err = snd_pcm_open(&u->pcm_handle, u->device_name, SND_PCM_STREAM_CAPTURE,
589 /*SND_PCM_NONBLOCK|*/
590 SND_PCM_NO_AUTO_RESAMPLE|
591 SND_PCM_NO_AUTO_CHANNELS|
592 SND_PCM_NO_AUTO_FORMAT)) < 0) {
593 pa_log("Error opening PCM device %s: %s", u->device_name, snd_strerror(err));
594 goto fail;
595 }
596
597 ss = u->source->sample_spec;
598 nfrags = u->nfragments;
599 period_size = u->fragment_size / u->frame_size;
600 b = u->use_mmap;
601 d = u->use_tsched;
602
603 if ((err = pa_alsa_set_hw_params(u->pcm_handle, &ss, &nfrags, &period_size, u->hwbuf_size / u->frame_size, &b, &d, TRUE)) < 0) {
604 pa_log("Failed to set hardware parameters: %s", snd_strerror(err));
605 goto fail;
606 }
607
608 if (b != u->use_mmap || d != u->use_tsched) {
609 pa_log_warn("Resume failed, couldn't get original access mode.");
610 goto fail;
611 }
612
613 if (!pa_sample_spec_equal(&ss, &u->source->sample_spec)) {
614 pa_log_warn("Resume failed, couldn't restore original sample settings.");
615 goto fail;
616 }
617
618 if (nfrags != u->nfragments || period_size*u->frame_size != u->fragment_size) {
619 pa_log_warn("Resume failed, couldn't restore original fragment settings. (Old: %lu*%lu, New %lu*%lu)",
620 (unsigned long) u->nfragments, (unsigned long) u->fragment_size,
621 (unsigned long) nfrags, period_size * u->frame_size);
622 goto fail;
623 }
624
625 if (update_sw_params(u) < 0)
626 goto fail;
627
628 if (build_pollfd(u) < 0)
629 goto fail;
630
631 /* FIXME: We need to reload the volume somehow */
632
633 snd_pcm_start(u->pcm_handle);
634 pa_smoother_resume(u->smoother, pa_rtclock_usec());
635
636 pa_log_info("Resumed successfully...");
637
638 return 0;
639
640 fail:
641 if (u->pcm_handle) {
642 snd_pcm_close(u->pcm_handle);
643 u->pcm_handle = NULL;
644 }
645
646 return -1;
647 }
648
649 static int source_process_msg(pa_msgobject *o, int code, void *data, int64_t offset, pa_memchunk *chunk) {
650 struct userdata *u = PA_SOURCE(o)->userdata;
651
652 switch (code) {
653
654 case PA_SOURCE_MESSAGE_GET_LATENCY: {
655 pa_usec_t r = 0;
656
657 if (u->pcm_handle)
658 r = source_get_latency(u);
659
660 *((pa_usec_t*) data) = r;
661
662 return 0;
663 }
664
665 case PA_SOURCE_MESSAGE_SET_STATE:
666
667 switch ((pa_source_state_t) PA_PTR_TO_UINT(data)) {
668
669 case PA_SOURCE_SUSPENDED:
670 pa_assert(PA_SOURCE_IS_OPENED(u->source->thread_info.state));
671
672 if (suspend(u) < 0)
673 return -1;
674
675 break;
676
677 case PA_SOURCE_IDLE:
678 case PA_SOURCE_RUNNING:
679
680 if (u->source->thread_info.state == PA_SOURCE_INIT) {
681 if (build_pollfd(u) < 0)
682 return -1;
683
684 snd_pcm_start(u->pcm_handle);
685 }
686
687 if (u->source->thread_info.state == PA_SOURCE_SUSPENDED) {
688 if (unsuspend(u) < 0)
689 return -1;
690 }
691
692 break;
693
694 case PA_SOURCE_UNLINKED:
695 case PA_SOURCE_INIT:
696 ;
697 }
698
699 break;
700 }
701
702 return pa_source_process_msg(o, code, data, offset, chunk);
703 }
704
705 static int mixer_callback(snd_mixer_elem_t *elem, unsigned int mask) {
706 struct userdata *u = snd_mixer_elem_get_callback_private(elem);
707
708 pa_assert(u);
709 pa_assert(u->mixer_handle);
710
711 if (mask == SND_CTL_EVENT_MASK_REMOVE)
712 return 0;
713
714 if (mask & SND_CTL_EVENT_MASK_VALUE) {
715 pa_source_get_volume(u->source, TRUE);
716 pa_source_get_mute(u->source, TRUE);
717 }
718
719 return 0;
720 }
721
722 static pa_volume_t from_alsa_volume(struct userdata *u, long alsa_vol) {
723
724 return (pa_volume_t) round(((double) (alsa_vol - u->hw_volume_min) * PA_VOLUME_NORM) /
725 (double) (u->hw_volume_max - u->hw_volume_min));
726 }
727
728 static long to_alsa_volume(struct userdata *u, pa_volume_t vol) {
729 long alsa_vol;
730
731 alsa_vol = (long) round(((double) vol * (double) (u->hw_volume_max - u->hw_volume_min))
732 / PA_VOLUME_NORM) + u->hw_volume_min;
733
734 return PA_CLAMP_UNLIKELY(alsa_vol, u->hw_volume_min, u->hw_volume_max);
735 }
736
737 static int source_get_volume_cb(pa_source *s) {
738 struct userdata *u = s->userdata;
739 int err;
740 unsigned i;
741 pa_cvolume r;
742 char t[PA_CVOLUME_SNPRINT_MAX];
743
744 pa_assert(u);
745 pa_assert(u->mixer_elem);
746
747 if (u->mixer_seperate_channels) {
748
749 r.channels = s->sample_spec.channels;
750
751 for (i = 0; i < s->sample_spec.channels; i++) {
752 long alsa_vol;
753
754 if (u->hw_dB_supported) {
755
756 if ((err = snd_mixer_selem_get_capture_dB(u->mixer_elem, u->mixer_map[i], &alsa_vol)) < 0)
757 goto fail;
758
759 #ifdef HAVE_VALGRIND_MEMCHECK_H
760 VALGRIND_MAKE_MEM_DEFINED(&alsa_vol, sizeof(alsa_vol));
761 #endif
762
763 r.values[i] = pa_sw_volume_from_dB((double) (alsa_vol - u->hw_dB_max) / 100.0);
764 } else {
765
766 if ((err = snd_mixer_selem_get_capture_volume(u->mixer_elem, u->mixer_map[i], &alsa_vol)) < 0)
767 goto fail;
768
769 r.values[i] = from_alsa_volume(u, alsa_vol);
770 }
771 }
772
773 } else {
774 long alsa_vol;
775
776 if (u->hw_dB_supported) {
777
778 if ((err = snd_mixer_selem_get_capture_dB(u->mixer_elem, SND_MIXER_SCHN_MONO, &alsa_vol)) < 0)
779 goto fail;
780
781 #ifdef HAVE_VALGRIND_MEMCHECK_H
782 VALGRIND_MAKE_MEM_DEFINED(&alsa_vol, sizeof(alsa_vol));
783 #endif
784
785 pa_cvolume_set(&r, s->sample_spec.channels, pa_sw_volume_from_dB((double) (alsa_vol - u->hw_dB_max) / 100.0));
786
787 } else {
788
789 if ((err = snd_mixer_selem_get_capture_volume(u->mixer_elem, SND_MIXER_SCHN_MONO, &alsa_vol)) < 0)
790 goto fail;
791
792 pa_cvolume_set(&r, s->sample_spec.channels, from_alsa_volume(u, alsa_vol));
793 }
794 }
795
796 pa_log_debug("Read hardware volume: %s", pa_cvolume_snprint(t, sizeof(t), &r));
797
798 if (!pa_cvolume_equal(&u->hardware_volume, &r)) {
799
800 u->hardware_volume = s->volume = r;
801
802 if (u->hw_dB_supported) {
803 pa_cvolume reset;
804
805 /* Hmm, so the hardware volume changed, let's reset our software volume */
806
807 pa_cvolume_reset(&reset, s->sample_spec.channels);
808 pa_source_set_soft_volume(s, &reset);
809 }
810 }
811
812 return 0;
813
814 fail:
815 pa_log_error("Unable to read volume: %s", snd_strerror(err));
816
817 return -1;
818 }
819
820 static int source_set_volume_cb(pa_source *s) {
821 struct userdata *u = s->userdata;
822 int err;
823 unsigned i;
824 pa_cvolume r;
825
826 pa_assert(u);
827 pa_assert(u->mixer_elem);
828
829 if (u->mixer_seperate_channels) {
830
831 r.channels = s->sample_spec.channels;
832
833 for (i = 0; i < s->sample_spec.channels; i++) {
834 long alsa_vol;
835 pa_volume_t vol;
836
837 vol = s->volume.values[i];
838
839 if (u->hw_dB_supported) {
840
841 alsa_vol = (long) (pa_sw_volume_to_dB(vol) * 100);
842 alsa_vol += u->hw_dB_max;
843 alsa_vol = PA_CLAMP_UNLIKELY(alsa_vol, u->hw_dB_min, u->hw_dB_max);
844
845 if ((err = snd_mixer_selem_set_capture_dB(u->mixer_elem, u->mixer_map[i], alsa_vol, 1)) < 0)
846 goto fail;
847
848 if ((err = snd_mixer_selem_get_capture_dB(u->mixer_elem, u->mixer_map[i], &alsa_vol)) < 0)
849 goto fail;
850
851 r.values[i] = pa_sw_volume_from_dB((double) (alsa_vol - u->hw_dB_max) / 100.0);
852
853 } else {
854 alsa_vol = to_alsa_volume(u, vol);
855
856 if ((err = snd_mixer_selem_set_capture_volume(u->mixer_elem, u->mixer_map[i], alsa_vol)) < 0)
857 goto fail;
858
859 if ((err = snd_mixer_selem_get_capture_volume(u->mixer_elem, u->mixer_map[i], &alsa_vol)) < 0)
860 goto fail;
861
862 r.values[i] = from_alsa_volume(u, alsa_vol);
863 }
864 }
865
866 } else {
867 pa_volume_t vol;
868 long alsa_vol;
869
870 vol = pa_cvolume_max(&s->volume);
871
872 if (u->hw_dB_supported) {
873 alsa_vol = (long) (pa_sw_volume_to_dB(vol) * 100);
874 alsa_vol += u->hw_dB_max;
875 alsa_vol = PA_CLAMP_UNLIKELY(alsa_vol, u->hw_dB_min, u->hw_dB_max);
876
877 if ((err = snd_mixer_selem_set_capture_dB_all(u->mixer_elem, alsa_vol, 1)) < 0)
878 goto fail;
879
880 if ((err = snd_mixer_selem_get_capture_dB(u->mixer_elem, SND_MIXER_SCHN_MONO, &alsa_vol)) < 0)
881 goto fail;
882
883 pa_cvolume_set(&r, s->volume.channels, pa_sw_volume_from_dB((double) (alsa_vol - u->hw_dB_max) / 100.0));
884
885 } else {
886 alsa_vol = to_alsa_volume(u, vol);
887
888 if ((err = snd_mixer_selem_set_capture_volume_all(u->mixer_elem, alsa_vol)) < 0)
889 goto fail;
890
891 if ((err = snd_mixer_selem_get_capture_volume(u->mixer_elem, SND_MIXER_SCHN_MONO, &alsa_vol)) < 0)
892 goto fail;
893
894 pa_cvolume_set(&r, s->sample_spec.channels, from_alsa_volume(u, alsa_vol));
895 }
896 }
897
898 u->hardware_volume = r;
899
900 if (u->hw_dB_supported) {
901 char t[PA_CVOLUME_SNPRINT_MAX];
902
903 /* Match exactly what the user requested by software */
904
905 pa_sw_cvolume_divide(&r, &s->volume, &r);
906 pa_source_set_soft_volume(s, &r);
907
908 pa_log_debug("Requested volume: %s", pa_cvolume_snprint(t, sizeof(t), &s->volume));
909 pa_log_debug("Got hardware volume: %s", pa_cvolume_snprint(t, sizeof(t), &u->hardware_volume));
910 pa_log_debug("Calculated software volume: %s", pa_cvolume_snprint(t, sizeof(t), &r));
911
912 } else
913
914 /* We can't match exactly what the user requested, hence let's
915 * at least tell the user about it */
916
917 s->volume = r;
918
919 return 0;
920
921 fail:
922 pa_log_error("Unable to set volume: %s", snd_strerror(err));
923
924 return -1;
925 }
926
927 static int source_get_mute_cb(pa_source *s) {
928 struct userdata *u = s->userdata;
929 int err, sw;
930
931 pa_assert(u);
932 pa_assert(u->mixer_elem);
933
934 if ((err = snd_mixer_selem_get_capture_switch(u->mixer_elem, 0, &sw)) < 0) {
935 pa_log_error("Unable to get switch: %s", snd_strerror(err));
936 return -1;
937 }
938
939 s->muted = !sw;
940
941 return 0;
942 }
943
944 static int source_set_mute_cb(pa_source *s) {
945 struct userdata *u = s->userdata;
946 int err;
947
948 pa_assert(u);
949 pa_assert(u->mixer_elem);
950
951 if ((err = snd_mixer_selem_set_capture_switch_all(u->mixer_elem, !s->muted)) < 0) {
952 pa_log_error("Unable to set switch: %s", snd_strerror(err));
953 return -1;
954 }
955
956 return 0;
957 }
958
959 static void source_update_requested_latency_cb(pa_source *s) {
960 struct userdata *u = s->userdata;
961 pa_assert(u);
962
963 if (!u->pcm_handle)
964 return;
965
966 update_sw_params(u);
967 }
968
969 static void thread_func(void *userdata) {
970 struct userdata *u = userdata;
971 unsigned short revents = 0;
972
973 pa_assert(u);
974
975 pa_log_debug("Thread starting up");
976
977 if (u->core->realtime_scheduling)
978 pa_make_realtime(u->core->realtime_priority);
979
980 pa_thread_mq_install(&u->thread_mq);
981 pa_rtpoll_install(u->rtpoll);
982
983 for (;;) {
984 int ret;
985
986 /* pa_log_debug("loop"); */
987
988 /* Read some data and pass it to the sources */
989 if (PA_SOURCE_IS_OPENED(u->source->thread_info.state)) {
990 int work_done = 0;
991 pa_usec_t sleep_usec = 0;
992
993 if (u->use_mmap)
994 work_done = mmap_read(u, &sleep_usec, revents & POLLIN);
995 else
996 work_done = unix_read(u, &sleep_usec, revents & POLLIN);
997
998 if (work_done < 0)
999 goto fail;
1000
1001 /* pa_log_debug("work_done = %i", work_done); */
1002
1003 if (work_done)
1004 update_smoother(u);
1005
1006 if (u->use_tsched) {
1007 pa_usec_t cusec;
1008
1009 /* OK, the capture buffer is now empty, let's
1010 * calculate when to wake up next */
1011
1012 /* pa_log_debug("Waking up in %0.2fms (sound card clock).", (double) sleep_usec / PA_USEC_PER_MSEC); */
1013
1014 /* Convert from the sound card time domain to the
1015 * system time domain */
1016 cusec = pa_smoother_translate(u->smoother, pa_rtclock_usec(), sleep_usec);
1017
1018 /* pa_log_debug("Waking up in %0.2fms (system clock).", (double) cusec / PA_USEC_PER_MSEC); */
1019
1020 /* We don't trust the conversion, so we wake up whatever comes first */
1021 pa_rtpoll_set_timer_relative(u->rtpoll, PA_MIN(sleep_usec, cusec));
1022 }
1023 } else if (u->use_tsched)
1024
1025 /* OK, we're in an invalid state, let's disable our timers */
1026 pa_rtpoll_set_timer_disabled(u->rtpoll);
1027
1028 /* Hmm, nothing to do. Let's sleep */
1029 if ((ret = pa_rtpoll_run(u->rtpoll, TRUE)) < 0)
1030 goto fail;
1031
1032 if (ret == 0)
1033 goto finish;
1034
1035 /* Tell ALSA about this and process its response */
1036 if (PA_SOURCE_IS_OPENED(u->source->thread_info.state)) {
1037 struct pollfd *pollfd;
1038 int err;
1039 unsigned n;
1040
1041 pollfd = pa_rtpoll_item_get_pollfd(u->alsa_rtpoll_item, &n);
1042
1043 if ((err = snd_pcm_poll_descriptors_revents(u->pcm_handle, pollfd, n, &revents)) < 0) {
1044 pa_log("snd_pcm_poll_descriptors_revents() failed: %s", snd_strerror(err));
1045 goto fail;
1046 }
1047
1048 if (revents & (POLLOUT|POLLERR|POLLNVAL|POLLHUP|POLLPRI)) {
1049 if (pa_alsa_recover_from_poll(u->pcm_handle, revents) < 0)
1050 goto fail;
1051
1052 snd_pcm_start(u->pcm_handle);
1053 }
1054
1055 if (revents && u->use_tsched)
1056 pa_log_debug("Wakeup from ALSA!%s%s", (revents & POLLIN) ? " INPUT" : "", (revents & POLLOUT) ? " OUTPUT" : "");
1057 } else
1058 revents = 0;
1059 }
1060
1061 fail:
1062 /* If this was no regular exit from the loop we have to continue
1063 * processing messages until we received PA_MESSAGE_SHUTDOWN */
1064 pa_asyncmsgq_post(u->thread_mq.outq, PA_MSGOBJECT(u->core), PA_CORE_MESSAGE_UNLOAD_MODULE, u->module, 0, NULL, NULL);
1065 pa_asyncmsgq_wait_for(u->thread_mq.inq, PA_MESSAGE_SHUTDOWN);
1066
1067 finish:
1068 pa_log_debug("Thread shutting down");
1069 }
1070
1071 int pa__init(pa_module*m) {
1072
1073 pa_modargs *ma = NULL;
1074 struct userdata *u = NULL;
1075 const char *dev_id;
1076 pa_sample_spec ss;
1077 pa_channel_map map;
1078 uint32_t nfrags, hwbuf_size, frag_size, tsched_size, tsched_watermark;
1079 snd_pcm_uframes_t period_frames, tsched_frames;
1080 size_t frame_size;
1081 snd_pcm_info_t *pcm_info = NULL;
1082 int err;
1083 const char *name;
1084 char *name_buf = NULL;
1085 pa_bool_t namereg_fail;
1086 pa_bool_t use_mmap = TRUE, b, use_tsched = TRUE, d;
1087 pa_source_new_data data;
1088
1089 snd_pcm_info_alloca(&pcm_info);
1090
1091 pa_assert(m);
1092
1093 pa_alsa_redirect_errors_inc();
1094
1095 if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
1096 pa_log("Failed to parse module arguments");
1097 goto fail;
1098 }
1099
1100 ss = m->core->default_sample_spec;
1101 if (pa_modargs_get_sample_spec_and_channel_map(ma, &ss, &map, PA_CHANNEL_MAP_ALSA) < 0) {
1102 pa_log("Failed to parse sample specification");
1103 goto fail;
1104 }
1105
1106 frame_size = pa_frame_size(&ss);
1107
1108 nfrags = m->core->default_n_fragments;
1109 frag_size = (uint32_t) pa_usec_to_bytes(m->core->default_fragment_size_msec*PA_USEC_PER_MSEC, &ss);
1110 if (frag_size <= 0)
1111 frag_size = (uint32_t) frame_size;
1112 tsched_size = (uint32_t) pa_usec_to_bytes(DEFAULT_TSCHED_BUFFER_USEC, &ss);
1113 tsched_watermark = (uint32_t) pa_usec_to_bytes(DEFAULT_TSCHED_WATERMARK_USEC, &ss);
1114
1115 if (pa_modargs_get_value_u32(ma, "fragments", &nfrags) < 0 ||
1116 pa_modargs_get_value_u32(ma, "fragment_size", &frag_size) < 0 ||
1117 pa_modargs_get_value_u32(ma, "tsched_buffer_size", &tsched_size) < 0 ||
1118 pa_modargs_get_value_u32(ma, "tsched_buffer_watermark", &tsched_watermark) < 0) {
1119 pa_log("Failed to parse buffer metrics");
1120 goto fail;
1121 }
1122
1123 hwbuf_size = frag_size * nfrags;
1124 period_frames = frag_size/frame_size;
1125 tsched_frames = tsched_size/frame_size;
1126
1127 if (pa_modargs_get_value_boolean(ma, "mmap", &use_mmap) < 0) {
1128 pa_log("Failed to parse mmap argument.");
1129 goto fail;
1130 }
1131
1132 if (pa_modargs_get_value_boolean(ma, "tsched", &use_tsched) < 0) {
1133 pa_log("Failed to parse timer_scheduling argument.");
1134 goto fail;
1135 }
1136
1137 if (use_tsched && !pa_rtclock_hrtimer()) {
1138 pa_log_notice("Disabling timer-based scheduling because high-resolution timers are not available from the kernel.");
1139 use_tsched = FALSE;
1140 }
1141
1142 u = pa_xnew0(struct userdata, 1);
1143 u->core = m->core;
1144 u->module = m;
1145 m->userdata = u;
1146 u->use_mmap = use_mmap;
1147 u->use_tsched = use_tsched;
1148 u->rtpoll = pa_rtpoll_new();
1149 pa_thread_mq_init(&u->thread_mq, m->core->mainloop, u->rtpoll);
1150 u->alsa_rtpoll_item = NULL;
1151
1152 u->smoother = pa_smoother_new(DEFAULT_TSCHED_WATERMARK_USEC, DEFAULT_TSCHED_WATERMARK_USEC, TRUE, 5);
1153 pa_smoother_set_time_offset(u->smoother, pa_rtclock_usec());
1154
1155 snd_config_update_free_global();
1156
1157 b = use_mmap;
1158 d = use_tsched;
1159
1160 if ((dev_id = pa_modargs_get_value(ma, "device_id", NULL))) {
1161
1162 if (!(u->pcm_handle = pa_alsa_open_by_device_id(
1163 dev_id,
1164 &u->device_name,
1165 &ss, &map,
1166 SND_PCM_STREAM_CAPTURE,
1167 &nfrags, &period_frames, tsched_frames,
1168 &b, &d)))
1169 goto fail;
1170
1171 } else {
1172
1173 if (!(u->pcm_handle = pa_alsa_open_by_device_string(
1174 pa_modargs_get_value(ma, "device", DEFAULT_DEVICE),
1175 &u->device_name,
1176 &ss, &map,
1177 SND_PCM_STREAM_CAPTURE,
1178 &nfrags, &period_frames, tsched_frames,
1179 &b, &d)))
1180 goto fail;
1181 }
1182
1183 pa_assert(u->device_name);
1184 pa_log_info("Successfully opened device %s.", u->device_name);
1185
1186 if (use_mmap && !b) {
1187 pa_log_info("Device doesn't support mmap(), falling back to UNIX read/write mode.");
1188 u->use_mmap = use_mmap = FALSE;
1189 }
1190
1191 if (use_tsched && (!b || !d)) {
1192 pa_log_info("Cannot enabled timer-based scheduling, falling back to sound IRQ scheduling.");
1193 u->use_tsched = use_tsched = FALSE;
1194 }
1195
1196 if (u->use_mmap)
1197 pa_log_info("Successfully enabled mmap() mode.");
1198
1199 if (u->use_tsched)
1200 pa_log_info("Successfully enabled timer-based scheduling mode.");
1201
1202 if ((err = snd_pcm_info(u->pcm_handle, pcm_info)) < 0) {
1203 pa_log("Error fetching PCM info: %s", snd_strerror(err));
1204 goto fail;
1205 }
1206
1207 /* ALSA might tweak the sample spec, so recalculate the frame size */
1208 frame_size = pa_frame_size(&ss);
1209
1210 if ((err = snd_mixer_open(&u->mixer_handle, 0)) < 0)
1211 pa_log("Error opening mixer: %s", snd_strerror(err));
1212 else {
1213 pa_bool_t found = FALSE;
1214
1215 if (pa_alsa_prepare_mixer(u->mixer_handle, u->device_name) >= 0)
1216 found = TRUE;
1217 else {
1218 snd_pcm_info_t* info;
1219
1220 snd_pcm_info_alloca(&info);
1221
1222 if (snd_pcm_info(u->pcm_handle, info) >= 0) {
1223 char *md;
1224 int card;
1225
1226 if ((card = snd_pcm_info_get_card(info)) >= 0) {
1227
1228 md = pa_sprintf_malloc("hw:%i", card);
1229
1230 if (strcmp(u->device_name, md))
1231 if (pa_alsa_prepare_mixer(u->mixer_handle, md) >= 0)
1232 found = TRUE;
1233 pa_xfree(md);
1234 }
1235 }
1236 }
1237
1238 if (found)
1239 if (!(u->mixer_elem = pa_alsa_find_elem(u->mixer_handle, "Capture", "Mic")))
1240 found = FALSE;
1241
1242 if (!found) {
1243 snd_mixer_close(u->mixer_handle);
1244 u->mixer_handle = NULL;
1245 }
1246 }
1247
1248 if ((name = pa_modargs_get_value(ma, "source_name", NULL)))
1249 namereg_fail = TRUE;
1250 else {
1251 name = name_buf = pa_sprintf_malloc("alsa_input.%s", u->device_name);
1252 namereg_fail = FALSE;
1253 }
1254
1255 pa_source_new_data_init(&data);
1256 data.driver = __FILE__;
1257 data.module = m;
1258 pa_source_new_data_set_name(&data, name);
1259 data.namereg_fail = namereg_fail;
1260 pa_source_new_data_set_sample_spec(&data, &ss);
1261 pa_source_new_data_set_channel_map(&data, &map);
1262
1263 pa_alsa_init_proplist(data.proplist, pcm_info);
1264 pa_proplist_sets(data.proplist, PA_PROP_DEVICE_STRING, u->device_name);
1265 pa_proplist_setf(data.proplist, PA_PROP_DEVICE_BUFFERING_BUFFER_SIZE, "%lu", (unsigned long) (period_frames * frame_size * nfrags));
1266 pa_proplist_setf(data.proplist, PA_PROP_DEVICE_BUFFERING_FRAGMENT_SIZE, "%lu", (unsigned long) (period_frames * frame_size));
1267 pa_proplist_sets(data.proplist, PA_PROP_DEVICE_ACCESS_MODE, u->use_tsched ? "mmap+timer" : (u->use_mmap ? "mmap" : "serial"));
1268
1269 u->source = pa_source_new(m->core, &data, PA_SOURCE_HARDWARE|PA_SOURCE_LATENCY);
1270 pa_source_new_data_done(&data);
1271 pa_xfree(name_buf);
1272
1273 if (!u->source) {
1274 pa_log("Failed to create source object");
1275 goto fail;
1276 }
1277
1278 u->source->parent.process_msg = source_process_msg;
1279 u->source->update_requested_latency = source_update_requested_latency_cb;
1280 u->source->userdata = u;
1281
1282 pa_source_set_asyncmsgq(u->source, u->thread_mq.inq);
1283 pa_source_set_rtpoll(u->source, u->rtpoll);
1284
1285 u->frame_size = frame_size;
1286 u->fragment_size = frag_size = (uint32_t) (period_frames * frame_size);
1287 u->nfragments = nfrags;
1288 u->hwbuf_size = u->fragment_size * nfrags;
1289 u->hwbuf_unused_frames = 0;
1290 u->tsched_watermark = tsched_watermark;
1291 u->frame_index = 0;
1292 u->hw_dB_supported = FALSE;
1293 u->hw_dB_min = u->hw_dB_max = 0;
1294 u->hw_volume_min = u->hw_volume_max = 0;
1295 u->mixer_seperate_channels = FALSE;
1296 pa_cvolume_mute(&u->hardware_volume, u->source->sample_spec.channels);
1297
1298 if (use_tsched)
1299 fix_tsched_watermark(u);
1300
1301 pa_source_set_latency_range(u->source,
1302 !use_tsched ? pa_bytes_to_usec(u->hwbuf_size, &ss) : (pa_usec_t) -1,
1303 pa_bytes_to_usec(u->hwbuf_size, &ss));
1304
1305 pa_log_info("Using %u fragments of size %lu bytes, buffer time is %0.2fms",
1306 nfrags, (long unsigned) u->fragment_size,
1307 (double) pa_bytes_to_usec(u->hwbuf_size, &ss) / PA_USEC_PER_MSEC);
1308
1309 if (use_tsched)
1310 pa_log_info("Time scheduling watermark is %0.2fms",
1311 (double) pa_bytes_to_usec(u->tsched_watermark, &ss) / PA_USEC_PER_MSEC);
1312
1313 if (update_sw_params(u) < 0)
1314 goto fail;
1315
1316 if (u->mixer_handle) {
1317 pa_assert(u->mixer_elem);
1318
1319 if (snd_mixer_selem_has_capture_volume(u->mixer_elem)) {
1320 pa_bool_t suitable = FALSE;
1321
1322 if (snd_mixer_selem_get_capture_volume_range(u->mixer_elem, &u->hw_volume_min, &u->hw_volume_max) < 0)
1323 pa_log_info("Failed to get volume range. Falling back to software volume control.");
1324 else if (u->hw_volume_min >= u->hw_volume_max)
1325 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);
1326 else {
1327 pa_log_info("Volume ranges from %li to %li.", u->hw_volume_min, u->hw_volume_max);
1328 suitable = TRUE;
1329 }
1330
1331 if (snd_mixer_selem_get_capture_dB_range(u->mixer_elem, &u->hw_dB_min, &u->hw_dB_max) < 0)
1332 pa_log_info("Mixer doesn't support dB information.");
1333 else {
1334 #ifdef HAVE_VALGRIND_MEMCHECK_H
1335 VALGRIND_MAKE_MEM_DEFINED(&u->hw_dB_min, sizeof(u->hw_dB_min));
1336 VALGRIND_MAKE_MEM_DEFINED(&u->hw_dB_max, sizeof(u->hw_dB_max));
1337 #endif
1338
1339 if (u->hw_dB_min >= u->hw_dB_max)
1340 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);
1341 else {
1342 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);
1343 u->hw_dB_supported = TRUE;
1344 }
1345 }
1346
1347 if (suitable &&
1348 !u->hw_dB_supported &&
1349 u->hw_volume_max - u->hw_volume_min < 3) {
1350
1351 pa_log_info("Device has less than 4 volume levels. Falling back to software volume control.");
1352 suitable = FALSE;
1353 }
1354
1355 if (suitable) {
1356 u->mixer_seperate_channels = pa_alsa_calc_mixer_map(u->mixer_elem, &map, u->mixer_map, FALSE) >= 0;
1357
1358 u->source->get_volume = source_get_volume_cb;
1359 u->source->set_volume = source_set_volume_cb;
1360 u->source->flags |= PA_SOURCE_HW_VOLUME_CTRL | (u->hw_dB_supported ? PA_SOURCE_DECIBEL_VOLUME : 0);
1361 pa_log_info("Using hardware volume control. Hardware dB scale %s.", u->hw_dB_supported ? "supported" : "not supported");
1362 } else
1363 pa_log_info("Using software volume control.");
1364 }
1365
1366 if (snd_mixer_selem_has_capture_switch(u->mixer_elem)) {
1367 u->source->get_mute = source_get_mute_cb;
1368 u->source->set_mute = source_set_mute_cb;
1369 u->source->flags |= PA_SOURCE_HW_MUTE_CTRL;
1370 } else
1371 pa_log_info("Using software mute control.");
1372
1373 u->mixer_fdl = pa_alsa_fdlist_new();
1374
1375 if (pa_alsa_fdlist_set_mixer(u->mixer_fdl, u->mixer_handle, m->core->mainloop) < 0) {
1376 pa_log("Failed to initialize file descriptor monitoring");
1377 goto fail;
1378 }
1379
1380 snd_mixer_elem_set_callback(u->mixer_elem, mixer_callback);
1381 snd_mixer_elem_set_callback_private(u->mixer_elem, u);
1382 } else
1383 u->mixer_fdl = NULL;
1384
1385 pa_alsa_dump(u->pcm_handle);
1386
1387 if (!(u->thread = pa_thread_new(thread_func, u))) {
1388 pa_log("Failed to create thread.");
1389 goto fail;
1390 }
1391 /* Get initial mixer settings */
1392 if (data.volume_is_set) {
1393 if (u->source->set_volume)
1394 u->source->set_volume(u->source);
1395 } else {
1396 if (u->source->get_volume)
1397 u->source->get_volume(u->source);
1398 }
1399
1400 if (data.muted_is_set) {
1401 if (u->source->set_mute)
1402 u->source->set_mute(u->source);
1403 } else {
1404 if (u->source->get_mute)
1405 u->source->get_mute(u->source);
1406 }
1407
1408 pa_source_put(u->source);
1409
1410 pa_modargs_free(ma);
1411
1412 return 0;
1413
1414 fail:
1415
1416 if (ma)
1417 pa_modargs_free(ma);
1418
1419 pa__done(m);
1420
1421 return -1;
1422 }
1423
1424 void pa__done(pa_module*m) {
1425 struct userdata *u;
1426
1427 pa_assert(m);
1428
1429 if (!(u = m->userdata)) {
1430 pa_alsa_redirect_errors_dec();
1431 return;
1432 }
1433
1434 if (u->source)
1435 pa_source_unlink(u->source);
1436
1437 if (u->thread) {
1438 pa_asyncmsgq_send(u->thread_mq.inq, NULL, PA_MESSAGE_SHUTDOWN, NULL, 0, NULL);
1439 pa_thread_free(u->thread);
1440 }
1441
1442 pa_thread_mq_done(&u->thread_mq);
1443
1444 if (u->source)
1445 pa_source_unref(u->source);
1446
1447 if (u->alsa_rtpoll_item)
1448 pa_rtpoll_item_free(u->alsa_rtpoll_item);
1449
1450 if (u->rtpoll)
1451 pa_rtpoll_free(u->rtpoll);
1452
1453 if (u->mixer_fdl)
1454 pa_alsa_fdlist_free(u->mixer_fdl);
1455
1456 if (u->mixer_handle)
1457 snd_mixer_close(u->mixer_handle);
1458
1459 if (u->pcm_handle) {
1460 snd_pcm_drop(u->pcm_handle);
1461 snd_pcm_close(u->pcm_handle);
1462 }
1463
1464 if (u->smoother)
1465 pa_smoother_free(u->smoother);
1466
1467 pa_xfree(u->device_name);
1468 pa_xfree(u);
1469
1470 snd_config_update_free_global();
1471 pa_alsa_redirect_errors_dec();
1472 }