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