]> code.delx.au - pulseaudio/blob - src/modules/alsa/alsa-source.c
core: make sure soft mute status stays in sync with hw mute status
[pulseaudio] / src / modules / alsa / 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.1 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 #include <pulse/i18n.h>
39
40 #include <pulsecore/core-error.h>
41 #include <pulsecore/core.h>
42 #include <pulsecore/module.h>
43 #include <pulsecore/memchunk.h>
44 #include <pulsecore/sink.h>
45 #include <pulsecore/modargs.h>
46 #include <pulsecore/core-util.h>
47 #include <pulsecore/sample-util.h>
48 #include <pulsecore/log.h>
49 #include <pulsecore/macro.h>
50 #include <pulsecore/thread.h>
51 #include <pulsecore/core-error.h>
52 #include <pulsecore/thread-mq.h>
53 #include <pulsecore/rtpoll.h>
54 #include <pulsecore/time-smoother.h>
55 #include <pulsecore/rtclock.h>
56
57 #include <modules/reserve-wrap.h>
58
59 #include "alsa-util.h"
60 #include "alsa-source.h"
61
62 /* #define DEBUG_TIMING */
63
64 #define DEFAULT_DEVICE "default"
65 #define DEFAULT_TSCHED_BUFFER_USEC (2*PA_USEC_PER_SEC) /* 2s */
66 #define DEFAULT_TSCHED_WATERMARK_USEC (20*PA_USEC_PER_MSEC) /* 20ms */
67 #define TSCHED_WATERMARK_STEP_USEC (10*PA_USEC_PER_MSEC) /* 10ms */
68 #define TSCHED_MIN_SLEEP_USEC (10*PA_USEC_PER_MSEC) /* 10ms */
69 #define TSCHED_MIN_WAKEUP_USEC (4*PA_USEC_PER_MSEC) /* 4ms */
70
71 struct userdata {
72 pa_core *core;
73 pa_module *module;
74 pa_source *source;
75
76 pa_thread *thread;
77 pa_thread_mq thread_mq;
78 pa_rtpoll *rtpoll;
79
80 snd_pcm_t *pcm_handle;
81
82 pa_alsa_fdlist *mixer_fdl;
83 snd_mixer_t *mixer_handle;
84 snd_mixer_elem_t *mixer_elem;
85 long hw_volume_max, hw_volume_min;
86 long hw_dB_max, hw_dB_min;
87 pa_bool_t hw_dB_supported:1;
88 pa_bool_t mixer_seperate_channels:1;
89
90 pa_cvolume hardware_volume;
91
92 size_t
93 frame_size,
94 fragment_size,
95 hwbuf_size,
96 tsched_watermark,
97 hwbuf_unused,
98 min_sleep,
99 min_wakeup,
100 watermark_step;
101
102 unsigned nfragments;
103
104 char *device_name;
105
106 pa_bool_t use_mmap:1, use_tsched:1;
107
108 pa_rtpoll_item *alsa_rtpoll_item;
109
110 snd_mixer_selem_channel_id_t mixer_map[SND_MIXER_SCHN_LAST];
111
112 pa_smoother *smoother;
113 uint64_t read_count;
114
115 pa_reserve_wrapper *reserve;
116 pa_hook_slot *reserve_slot;
117 pa_reserve_monitor_wrapper *monitor;
118 pa_hook_slot *monitor_slot;
119 };
120
121 static void userdata_free(struct userdata *u);
122
123 static pa_hook_result_t reserve_cb(pa_reserve_wrapper *r, void *forced, struct userdata *u) {
124 pa_assert(r);
125 pa_assert(u);
126
127 if (pa_source_suspend(u->source, TRUE, PA_SUSPEND_APPLICATION) < 0)
128 return PA_HOOK_CANCEL;
129
130 return PA_HOOK_OK;
131 }
132
133 static void reserve_done(struct userdata *u) {
134 pa_assert(u);
135
136 if (u->reserve_slot) {
137 pa_hook_slot_free(u->reserve_slot);
138 u->reserve_slot = NULL;
139 }
140
141 if (u->reserve) {
142 pa_reserve_wrapper_unref(u->reserve);
143 u->reserve = NULL;
144 }
145 }
146
147 static void reserve_update(struct userdata *u) {
148 const char *description;
149 pa_assert(u);
150
151 if (!u->source || !u->reserve)
152 return;
153
154 if ((description = pa_proplist_gets(u->source->proplist, PA_PROP_DEVICE_DESCRIPTION)))
155 pa_reserve_wrapper_set_application_device_name(u->reserve, description);
156 }
157
158 static int reserve_init(struct userdata *u, const char *dname) {
159 char *rname;
160
161 pa_assert(u);
162 pa_assert(dname);
163
164 if (u->reserve)
165 return 0;
166
167 if (pa_in_system_mode())
168 return 0;
169
170 /* We are resuming, try to lock the device */
171 if (!(rname = pa_alsa_get_reserve_name(dname)))
172 return 0;
173
174 u->reserve = pa_reserve_wrapper_get(u->core, rname);
175 pa_xfree(rname);
176
177 if (!(u->reserve))
178 return -1;
179
180 reserve_update(u);
181
182 pa_assert(!u->reserve_slot);
183 u->reserve_slot = pa_hook_connect(pa_reserve_wrapper_hook(u->reserve), PA_HOOK_NORMAL, (pa_hook_cb_t) reserve_cb, u);
184
185 return 0;
186 }
187
188 static pa_hook_result_t monitor_cb(pa_reserve_monitor_wrapper *w, void* busy, struct userdata *u) {
189 pa_bool_t b;
190
191 pa_assert(w);
192 pa_assert(u);
193
194 b = PA_PTR_TO_UINT(busy) && !u->reserve;
195
196 pa_source_suspend(u->source, b, PA_SUSPEND_APPLICATION);
197 return PA_HOOK_OK;
198 }
199
200 static void monitor_done(struct userdata *u) {
201 pa_assert(u);
202
203 if (u->monitor_slot) {
204 pa_hook_slot_free(u->monitor_slot);
205 u->monitor_slot = NULL;
206 }
207
208 if (u->monitor) {
209 pa_reserve_monitor_wrapper_unref(u->monitor);
210 u->monitor = NULL;
211 }
212 }
213
214 static int reserve_monitor_init(struct userdata *u, const char *dname) {
215 char *rname;
216
217 pa_assert(u);
218 pa_assert(dname);
219
220 if (pa_in_system_mode())
221 return 0;
222
223 /* We are resuming, try to lock the device */
224 if (!(rname = pa_alsa_get_reserve_name(dname)))
225 return 0;
226
227 u->monitor = pa_reserve_monitor_wrapper_get(u->core, rname);
228 pa_xfree(rname);
229
230 if (!(u->monitor))
231 return -1;
232
233 pa_assert(!u->monitor_slot);
234 u->monitor_slot = pa_hook_connect(pa_reserve_monitor_wrapper_hook(u->monitor), PA_HOOK_NORMAL, (pa_hook_cb_t) monitor_cb, u);
235
236 return 0;
237 }
238
239 static void fix_min_sleep_wakeup(struct userdata *u) {
240 size_t max_use, max_use_2;
241 pa_assert(u);
242
243 max_use = u->hwbuf_size - u->hwbuf_unused;
244 max_use_2 = pa_frame_align(max_use/2, &u->source->sample_spec);
245
246 u->min_sleep = pa_usec_to_bytes(TSCHED_MIN_SLEEP_USEC, &u->source->sample_spec);
247 u->min_sleep = PA_CLAMP(u->min_sleep, u->frame_size, max_use_2);
248
249 u->min_wakeup = pa_usec_to_bytes(TSCHED_MIN_WAKEUP_USEC, &u->source->sample_spec);
250 u->min_wakeup = PA_CLAMP(u->min_wakeup, u->frame_size, max_use_2);
251 }
252
253 static void fix_tsched_watermark(struct userdata *u) {
254 size_t max_use;
255 pa_assert(u);
256
257 max_use = u->hwbuf_size - u->hwbuf_unused;
258
259 if (u->tsched_watermark > max_use - u->min_sleep)
260 u->tsched_watermark = max_use - u->min_sleep;
261
262 if (u->tsched_watermark < u->min_wakeup)
263 u->tsched_watermark = u->min_wakeup;
264 }
265
266 static void adjust_after_overrun(struct userdata *u) {
267 size_t old_watermark;
268 pa_usec_t old_min_latency, new_min_latency;
269
270 pa_assert(u);
271 pa_assert(u->use_tsched);
272
273 /* First, just try to increase the watermark */
274 old_watermark = u->tsched_watermark;
275 u->tsched_watermark = PA_MIN(u->tsched_watermark * 2, u->tsched_watermark + u->watermark_step);
276
277 fix_tsched_watermark(u);
278
279 if (old_watermark != u->tsched_watermark) {
280 pa_log_notice("Increasing wakeup watermark to %0.2f ms",
281 (double) pa_bytes_to_usec(u->tsched_watermark, &u->source->sample_spec) / PA_USEC_PER_MSEC);
282 return;
283 }
284
285 /* Hmm, we cannot increase the watermark any further, hence let's raise the latency */
286 old_min_latency = u->source->thread_info.min_latency;
287 new_min_latency = PA_MIN(old_min_latency * 2, old_min_latency + TSCHED_WATERMARK_STEP_USEC);
288 new_min_latency = PA_MIN(new_min_latency, u->source->thread_info.max_latency);
289
290 if (old_min_latency != new_min_latency) {
291 pa_log_notice("Increasing minimal latency to %0.2f ms",
292 (double) new_min_latency / PA_USEC_PER_MSEC);
293
294 pa_source_set_latency_range_within_thread(u->source, new_min_latency, u->source->thread_info.max_latency);
295 return;
296 }
297
298 /* When we reach this we're officialy fucked! */
299 }
300
301 static pa_usec_t hw_sleep_time(struct userdata *u, pa_usec_t *sleep_usec, pa_usec_t*process_usec) {
302 pa_usec_t wm, usec;
303
304 pa_assert(u);
305
306 usec = pa_source_get_requested_latency_within_thread(u->source);
307
308 if (usec == (pa_usec_t) -1)
309 usec = pa_bytes_to_usec(u->hwbuf_size, &u->source->sample_spec);
310
311 wm = pa_bytes_to_usec(u->tsched_watermark, &u->source->sample_spec);
312
313 if (wm > usec)
314 wm = usec/2;
315
316 *sleep_usec = usec - wm;
317 *process_usec = wm;
318
319 #ifdef DEBUG_TIMING
320 pa_log_debug("Buffer time: %lu ms; Sleep time: %lu ms; Process time: %lu ms",
321 (unsigned long) (usec / PA_USEC_PER_MSEC),
322 (unsigned long) (*sleep_usec / PA_USEC_PER_MSEC),
323 (unsigned long) (*process_usec / PA_USEC_PER_MSEC));
324 #endif
325
326 return usec;
327 }
328
329 static int try_recover(struct userdata *u, const char *call, int err) {
330 pa_assert(u);
331 pa_assert(call);
332 pa_assert(err < 0);
333
334 pa_log_debug("%s: %s", call, pa_alsa_strerror(err));
335
336 pa_assert(err != -EAGAIN);
337
338 if (err == -EPIPE)
339 pa_log_debug("%s: Buffer overrun!", call);
340
341 if ((err = snd_pcm_recover(u->pcm_handle, err, 1)) < 0) {
342 pa_log("%s: %s", call, pa_alsa_strerror(err));
343 return -1;
344 }
345
346 snd_pcm_start(u->pcm_handle);
347 return 0;
348 }
349
350 static size_t check_left_to_record(struct userdata *u, size_t n_bytes) {
351 size_t left_to_record;
352 size_t rec_space = u->hwbuf_size - u->hwbuf_unused;
353
354 /* We use <= instead of < for this check here because an overrun
355 * only happens after the last sample was processed, not already when
356 * it is removed from the buffer. This is particularly important
357 * when block transfer is used. */
358
359 if (n_bytes <= rec_space) {
360 left_to_record = rec_space - n_bytes;
361
362 #ifdef DEBUG_TIMING
363 pa_log_debug("%0.2f ms left to record", (double) pa_bytes_to_usec(left_to_record, &u->source->sample_spec) / PA_USEC_PER_MSEC);
364 #endif
365
366 } else {
367 left_to_record = 0;
368
369 #ifdef DEBUG_TIMING
370 PA_DEBUG_TRAP;
371 #endif
372
373 if (pa_log_ratelimit())
374 pa_log_info("Overrun!");
375
376 if (u->use_tsched)
377 adjust_after_overrun(u);
378 }
379
380 return left_to_record;
381 }
382
383 static int mmap_read(struct userdata *u, pa_usec_t *sleep_usec, pa_bool_t polled) {
384 pa_bool_t work_done = FALSE;
385 pa_usec_t max_sleep_usec = 0, process_usec = 0;
386 size_t left_to_record;
387 unsigned j = 0;
388
389 pa_assert(u);
390 pa_source_assert_ref(u->source);
391
392 if (u->use_tsched)
393 hw_sleep_time(u, &max_sleep_usec, &process_usec);
394
395 for (;;) {
396 snd_pcm_sframes_t n;
397 size_t n_bytes;
398 int r;
399
400 if (PA_UNLIKELY((n = pa_alsa_safe_avail(u->pcm_handle, u->hwbuf_size, &u->source->sample_spec)) < 0)) {
401
402 if ((r = try_recover(u, "snd_pcm_avail", (int) n)) == 0)
403 continue;
404
405 return r;
406 }
407
408 n_bytes = (size_t) n * u->frame_size;
409
410 #ifdef DEBUG_TIMING
411 pa_log_debug("avail: %lu", (unsigned long) n_bytes);
412 #endif
413
414 left_to_record = check_left_to_record(u, n_bytes);
415
416 if (u->use_tsched)
417 if (!polled &&
418 pa_bytes_to_usec(left_to_record, &u->source->sample_spec) > process_usec+max_sleep_usec/2) {
419 #ifdef DEBUG_TIMING
420 pa_log_debug("Not reading, because too early.");
421 #endif
422 break;
423 }
424
425 if (PA_UNLIKELY(n_bytes <= 0)) {
426
427 if (polled)
428 PA_ONCE_BEGIN {
429 char *dn = pa_alsa_get_driver_name_by_pcm(u->pcm_handle);
430 pa_log(_("ALSA woke us up to read new data from the device, but there was actually nothing to read!\n"
431 "Most likely this is a bug in the ALSA driver '%s'. Please report this issue to the ALSA developers.\n"
432 "We were woken up with POLLIN set -- however a subsequent snd_pcm_avail() returned 0 or another value < min_avail."),
433 pa_strnull(dn));
434 pa_xfree(dn);
435 } PA_ONCE_END;
436
437 #ifdef DEBUG_TIMING
438 pa_log_debug("Not reading, because not necessary.");
439 #endif
440 break;
441 }
442
443 if (++j > 10) {
444 #ifdef DEBUG_TIMING
445 pa_log_debug("Not filling up, because already too many iterations.");
446 #endif
447
448 break;
449 }
450
451 polled = FALSE;
452
453 #ifdef DEBUG_TIMING
454 pa_log_debug("Reading");
455 #endif
456
457 for (;;) {
458 int err;
459 const snd_pcm_channel_area_t *areas;
460 snd_pcm_uframes_t offset, frames;
461 pa_memchunk chunk;
462 void *p;
463 snd_pcm_sframes_t sframes;
464
465 frames = (snd_pcm_uframes_t) (n_bytes / u->frame_size);
466
467 /* pa_log_debug("%lu frames to read", (unsigned long) frames); */
468
469 if (PA_UNLIKELY((err = pa_alsa_safe_mmap_begin(u->pcm_handle, &areas, &offset, &frames, u->hwbuf_size, &u->source->sample_spec)) < 0)) {
470
471 if ((r = try_recover(u, "snd_pcm_mmap_begin", err)) == 0)
472 continue;
473
474 return r;
475 }
476
477 /* Make sure that if these memblocks need to be copied they will fit into one slot */
478 if (frames > pa_mempool_block_size_max(u->source->core->mempool)/u->frame_size)
479 frames = pa_mempool_block_size_max(u->source->core->mempool)/u->frame_size;
480
481 /* Check these are multiples of 8 bit */
482 pa_assert((areas[0].first & 7) == 0);
483 pa_assert((areas[0].step & 7)== 0);
484
485 /* We assume a single interleaved memory buffer */
486 pa_assert((areas[0].first >> 3) == 0);
487 pa_assert((areas[0].step >> 3) == u->frame_size);
488
489 p = (uint8_t*) areas[0].addr + (offset * u->frame_size);
490
491 chunk.memblock = pa_memblock_new_fixed(u->core->mempool, p, frames * u->frame_size, TRUE);
492 chunk.length = pa_memblock_get_length(chunk.memblock);
493 chunk.index = 0;
494
495 pa_source_post(u->source, &chunk);
496 pa_memblock_unref_fixed(chunk.memblock);
497
498 if (PA_UNLIKELY((sframes = snd_pcm_mmap_commit(u->pcm_handle, offset, frames)) < 0)) {
499
500 if ((r = try_recover(u, "snd_pcm_mmap_commit", (int) sframes)) == 0)
501 continue;
502
503 return r;
504 }
505
506 work_done = TRUE;
507
508 u->read_count += frames * u->frame_size;
509
510 #ifdef DEBUG_TIMING
511 pa_log_debug("Read %lu bytes (of possible %lu bytes)", (unsigned long) (frames * u->frame_size), (unsigned long) n_bytes);
512 #endif
513
514 if ((size_t) frames * u->frame_size >= n_bytes)
515 break;
516
517 n_bytes -= (size_t) frames * u->frame_size;
518 }
519 }
520
521 *sleep_usec = pa_bytes_to_usec(left_to_record, &u->source->sample_spec);
522
523 if (*sleep_usec > process_usec)
524 *sleep_usec -= process_usec;
525 else
526 *sleep_usec = 0;
527
528 return work_done ? 1 : 0;
529 }
530
531 static int unix_read(struct userdata *u, pa_usec_t *sleep_usec, pa_bool_t polled) {
532 int work_done = FALSE;
533 pa_usec_t max_sleep_usec = 0, process_usec = 0;
534 size_t left_to_record;
535 unsigned j = 0;
536
537 pa_assert(u);
538 pa_source_assert_ref(u->source);
539
540 if (u->use_tsched)
541 hw_sleep_time(u, &max_sleep_usec, &process_usec);
542
543 for (;;) {
544 snd_pcm_sframes_t n;
545 size_t n_bytes;
546 int r;
547
548 if (PA_UNLIKELY((n = pa_alsa_safe_avail(u->pcm_handle, u->hwbuf_size, &u->source->sample_spec)) < 0)) {
549
550 if ((r = try_recover(u, "snd_pcm_avail", (int) n)) == 0)
551 continue;
552
553 return r;
554 }
555
556 n_bytes = (size_t) n * u->frame_size;
557 left_to_record = check_left_to_record(u, n_bytes);
558
559 if (u->use_tsched)
560 if (!polled &&
561 pa_bytes_to_usec(left_to_record, &u->source->sample_spec) > process_usec+max_sleep_usec/2)
562 break;
563
564 if (PA_UNLIKELY(n_bytes <= 0)) {
565
566 if (polled)
567 PA_ONCE_BEGIN {
568 char *dn = pa_alsa_get_driver_name_by_pcm(u->pcm_handle);
569 pa_log(_("ALSA woke us up to read new data from the device, but there was actually nothing to read!\n"
570 "Most likely this is a bug in the ALSA driver '%s'. Please report this issue to the ALSA developers.\n"
571 "We were woken up with POLLIN set -- however a subsequent snd_pcm_avail() returned 0 or another value < min_avail."),
572 pa_strnull(dn));
573 pa_xfree(dn);
574 } PA_ONCE_END;
575
576 break;
577 }
578
579 if (++j > 10) {
580 #ifdef DEBUG_TIMING
581 pa_log_debug("Not filling up, because already too many iterations.");
582 #endif
583
584 break;
585 }
586
587 polled = FALSE;
588
589 for (;;) {
590 void *p;
591 snd_pcm_sframes_t frames;
592 pa_memchunk chunk;
593
594 chunk.memblock = pa_memblock_new(u->core->mempool, (size_t) -1);
595
596 frames = (snd_pcm_sframes_t) (pa_memblock_get_length(chunk.memblock) / u->frame_size);
597
598 if (frames > (snd_pcm_sframes_t) (n_bytes/u->frame_size))
599 frames = (snd_pcm_sframes_t) (n_bytes/u->frame_size);
600
601 /* pa_log_debug("%lu frames to read", (unsigned long) n); */
602
603 p = pa_memblock_acquire(chunk.memblock);
604 frames = snd_pcm_readi(u->pcm_handle, (uint8_t*) p, (snd_pcm_uframes_t) frames);
605 pa_memblock_release(chunk.memblock);
606
607 pa_assert(frames != 0);
608
609 if (PA_UNLIKELY(frames < 0)) {
610 pa_memblock_unref(chunk.memblock);
611
612 if ((r = try_recover(u, "snd_pcm_readi", (int) (frames))) == 0)
613 continue;
614
615 return r;
616 }
617
618 chunk.index = 0;
619 chunk.length = (size_t) frames * u->frame_size;
620
621 pa_source_post(u->source, &chunk);
622 pa_memblock_unref(chunk.memblock);
623
624 work_done = TRUE;
625
626 u->read_count += frames * u->frame_size;
627
628 /* pa_log_debug("read %lu frames", (unsigned long) frames); */
629
630 if ((size_t) frames * u->frame_size >= n_bytes)
631 break;
632
633 n_bytes -= (size_t) frames * u->frame_size;
634 }
635 }
636
637 *sleep_usec = pa_bytes_to_usec(left_to_record, &u->source->sample_spec);
638
639 if (*sleep_usec > process_usec)
640 *sleep_usec -= process_usec;
641 else
642 *sleep_usec = 0;
643
644 return work_done ? 1 : 0;
645 }
646
647 static void update_smoother(struct userdata *u) {
648 snd_pcm_sframes_t delay = 0;
649 uint64_t position;
650 int err;
651 pa_usec_t now1 = 0, now2;
652 snd_pcm_status_t *status;
653
654 snd_pcm_status_alloca(&status);
655
656 pa_assert(u);
657 pa_assert(u->pcm_handle);
658
659 /* Let's update the time smoother */
660
661 if (PA_UNLIKELY((err = pa_alsa_safe_delay(u->pcm_handle, &delay, u->hwbuf_size, &u->source->sample_spec)) < 0)) {
662 pa_log_warn("Failed to get delay: %s", pa_alsa_strerror(err));
663 return;
664 }
665
666 if (PA_UNLIKELY((err = snd_pcm_status(u->pcm_handle, status)) < 0))
667 pa_log_warn("Failed to get timestamp: %s", pa_alsa_strerror(err));
668 else {
669 snd_htimestamp_t htstamp = { 0, 0 };
670 snd_pcm_status_get_htstamp(status, &htstamp);
671 now1 = pa_timespec_load(&htstamp);
672 }
673
674 position = u->read_count + ((uint64_t) delay * (uint64_t) u->frame_size);
675
676 /* Hmm, if the timestamp is 0, then it wasn't set and we take the current time */
677 if (now1 <= 0)
678 now1 = pa_rtclock_usec();
679
680 now2 = pa_bytes_to_usec(position, &u->source->sample_spec);
681
682 pa_smoother_put(u->smoother, now1, now2);
683 }
684
685 static pa_usec_t source_get_latency(struct userdata *u) {
686 int64_t delay;
687 pa_usec_t now1, now2;
688
689 pa_assert(u);
690
691 now1 = pa_rtclock_usec();
692 now2 = pa_smoother_get(u->smoother, now1);
693
694 delay = (int64_t) now2 - (int64_t) pa_bytes_to_usec(u->read_count, &u->source->sample_spec);
695
696 return delay >= 0 ? (pa_usec_t) delay : 0;
697 }
698
699 static int build_pollfd(struct userdata *u) {
700 pa_assert(u);
701 pa_assert(u->pcm_handle);
702
703 if (u->alsa_rtpoll_item)
704 pa_rtpoll_item_free(u->alsa_rtpoll_item);
705
706 if (!(u->alsa_rtpoll_item = pa_alsa_build_pollfd(u->pcm_handle, u->rtpoll)))
707 return -1;
708
709 return 0;
710 }
711
712 static int suspend(struct userdata *u) {
713 pa_assert(u);
714 pa_assert(u->pcm_handle);
715
716 pa_smoother_pause(u->smoother, pa_rtclock_usec());
717
718 /* Let's suspend */
719 snd_pcm_close(u->pcm_handle);
720 u->pcm_handle = NULL;
721
722 if (u->alsa_rtpoll_item) {
723 pa_rtpoll_item_free(u->alsa_rtpoll_item);
724 u->alsa_rtpoll_item = NULL;
725 }
726
727 pa_log_info("Device suspended...");
728
729 return 0;
730 }
731
732 static int update_sw_params(struct userdata *u) {
733 snd_pcm_uframes_t avail_min;
734 int err;
735
736 pa_assert(u);
737
738 /* Use the full buffer if noone asked us for anything specific */
739 u->hwbuf_unused = 0;
740
741 if (u->use_tsched) {
742 pa_usec_t latency;
743
744 if ((latency = pa_source_get_requested_latency_within_thread(u->source)) != (pa_usec_t) -1) {
745 size_t b;
746
747 pa_log_debug("latency set to %0.2fms", (double) latency / PA_USEC_PER_MSEC);
748
749 b = pa_usec_to_bytes(latency, &u->source->sample_spec);
750
751 /* We need at least one sample in our buffer */
752
753 if (PA_UNLIKELY(b < u->frame_size))
754 b = u->frame_size;
755
756 u->hwbuf_unused = PA_LIKELY(b < u->hwbuf_size) ? (u->hwbuf_size - b) : 0;
757 }
758
759 fix_min_sleep_wakeup(u);
760 fix_tsched_watermark(u);
761 }
762
763 pa_log_debug("hwbuf_unused=%lu", (unsigned long) u->hwbuf_unused);
764
765 avail_min = 1;
766
767 if (u->use_tsched) {
768 pa_usec_t sleep_usec, process_usec;
769
770 hw_sleep_time(u, &sleep_usec, &process_usec);
771 avail_min += pa_usec_to_bytes(sleep_usec, &u->source->sample_spec) / u->frame_size;
772 }
773
774 pa_log_debug("setting avail_min=%lu", (unsigned long) avail_min);
775
776 if ((err = pa_alsa_set_sw_params(u->pcm_handle, avail_min)) < 0) {
777 pa_log("Failed to set software parameters: %s", pa_alsa_strerror(err));
778 return err;
779 }
780
781 return 0;
782 }
783
784 static int unsuspend(struct userdata *u) {
785 pa_sample_spec ss;
786 int err;
787 pa_bool_t b, d;
788 unsigned nfrags;
789 snd_pcm_uframes_t period_size;
790
791 pa_assert(u);
792 pa_assert(!u->pcm_handle);
793
794 pa_log_info("Trying resume...");
795
796 snd_config_update_free_global();
797
798 if ((err = snd_pcm_open(&u->pcm_handle, u->device_name, SND_PCM_STREAM_CAPTURE,
799 /*SND_PCM_NONBLOCK|*/
800 SND_PCM_NO_AUTO_RESAMPLE|
801 SND_PCM_NO_AUTO_CHANNELS|
802 SND_PCM_NO_AUTO_FORMAT)) < 0) {
803 pa_log("Error opening PCM device %s: %s", u->device_name, pa_alsa_strerror(err));
804 goto fail;
805 }
806
807 ss = u->source->sample_spec;
808 nfrags = u->nfragments;
809 period_size = u->fragment_size / u->frame_size;
810 b = u->use_mmap;
811 d = u->use_tsched;
812
813 if ((err = pa_alsa_set_hw_params(u->pcm_handle, &ss, &nfrags, &period_size, u->hwbuf_size / u->frame_size, &b, &d, TRUE)) < 0) {
814 pa_log("Failed to set hardware parameters: %s", pa_alsa_strerror(err));
815 goto fail;
816 }
817
818 if (b != u->use_mmap || d != u->use_tsched) {
819 pa_log_warn("Resume failed, couldn't get original access mode.");
820 goto fail;
821 }
822
823 if (!pa_sample_spec_equal(&ss, &u->source->sample_spec)) {
824 pa_log_warn("Resume failed, couldn't restore original sample settings.");
825 goto fail;
826 }
827
828 if (nfrags != u->nfragments || period_size*u->frame_size != u->fragment_size) {
829 pa_log_warn("Resume failed, couldn't restore original fragment settings. (Old: %lu*%lu, New %lu*%lu)",
830 (unsigned long) u->nfragments, (unsigned long) u->fragment_size,
831 (unsigned long) nfrags, period_size * u->frame_size);
832 goto fail;
833 }
834
835 if (update_sw_params(u) < 0)
836 goto fail;
837
838 if (build_pollfd(u) < 0)
839 goto fail;
840
841 /* FIXME: We need to reload the volume somehow */
842
843 snd_pcm_start(u->pcm_handle);
844 pa_smoother_resume(u->smoother, pa_rtclock_usec(), TRUE);
845
846 pa_log_info("Resumed successfully...");
847
848 return 0;
849
850 fail:
851 if (u->pcm_handle) {
852 snd_pcm_close(u->pcm_handle);
853 u->pcm_handle = NULL;
854 }
855
856 return -1;
857 }
858
859 static int source_process_msg(pa_msgobject *o, int code, void *data, int64_t offset, pa_memchunk *chunk) {
860 struct userdata *u = PA_SOURCE(o)->userdata;
861
862 switch (code) {
863
864 case PA_SOURCE_MESSAGE_GET_LATENCY: {
865 pa_usec_t r = 0;
866
867 if (u->pcm_handle)
868 r = source_get_latency(u);
869
870 *((pa_usec_t*) data) = r;
871
872 return 0;
873 }
874
875 case PA_SOURCE_MESSAGE_SET_STATE:
876
877 switch ((pa_source_state_t) PA_PTR_TO_UINT(data)) {
878
879 case PA_SOURCE_SUSPENDED:
880 pa_assert(PA_SOURCE_IS_OPENED(u->source->thread_info.state));
881
882 if (suspend(u) < 0)
883 return -1;
884
885 break;
886
887 case PA_SOURCE_IDLE:
888 case PA_SOURCE_RUNNING:
889
890 if (u->source->thread_info.state == PA_SOURCE_INIT) {
891 if (build_pollfd(u) < 0)
892 return -1;
893
894 snd_pcm_start(u->pcm_handle);
895 }
896
897 if (u->source->thread_info.state == PA_SOURCE_SUSPENDED) {
898 if (unsuspend(u) < 0)
899 return -1;
900 }
901
902 break;
903
904 case PA_SOURCE_UNLINKED:
905 case PA_SOURCE_INIT:
906 case PA_SOURCE_INVALID_STATE:
907 ;
908 }
909
910 break;
911 }
912
913 return pa_source_process_msg(o, code, data, offset, chunk);
914 }
915
916 /* Called from main context */
917 static int source_set_state_cb(pa_source *s, pa_source_state_t new_state) {
918 pa_source_state_t old_state;
919 struct userdata *u;
920
921 pa_source_assert_ref(s);
922 pa_assert_se(u = s->userdata);
923
924 old_state = pa_source_get_state(u->source);
925
926 if (PA_SINK_IS_OPENED(old_state) && new_state == PA_SINK_SUSPENDED)
927 reserve_done(u);
928 else if (old_state == PA_SINK_SUSPENDED && PA_SINK_IS_OPENED(new_state))
929 if (reserve_init(u, u->device_name) < 0)
930 return -1;
931
932 return 0;
933 }
934
935 static int mixer_callback(snd_mixer_elem_t *elem, unsigned int mask) {
936 struct userdata *u = snd_mixer_elem_get_callback_private(elem);
937
938 pa_assert(u);
939 pa_assert(u->mixer_handle);
940
941 if (mask == SND_CTL_EVENT_MASK_REMOVE)
942 return 0;
943
944 if (mask & SND_CTL_EVENT_MASK_VALUE) {
945 pa_source_get_volume(u->source, TRUE);
946 pa_source_get_mute(u->source, TRUE);
947 }
948
949 return 0;
950 }
951
952 static pa_volume_t from_alsa_volume(struct userdata *u, long alsa_vol) {
953
954 return (pa_volume_t) round(((double) (alsa_vol - u->hw_volume_min) * PA_VOLUME_NORM) /
955 (double) (u->hw_volume_max - u->hw_volume_min));
956 }
957
958 static long to_alsa_volume(struct userdata *u, pa_volume_t vol) {
959 long alsa_vol;
960
961 alsa_vol = (long) round(((double) vol * (double) (u->hw_volume_max - u->hw_volume_min))
962 / PA_VOLUME_NORM) + u->hw_volume_min;
963
964 return PA_CLAMP_UNLIKELY(alsa_vol, u->hw_volume_min, u->hw_volume_max);
965 }
966
967 static void source_get_volume_cb(pa_source *s) {
968 struct userdata *u = s->userdata;
969 int err;
970 unsigned i;
971 pa_cvolume r;
972 char t[PA_CVOLUME_SNPRINT_MAX];
973
974 pa_assert(u);
975 pa_assert(u->mixer_elem);
976
977 if (u->mixer_seperate_channels) {
978
979 r.channels = s->sample_spec.channels;
980
981 for (i = 0; i < s->sample_spec.channels; i++) {
982 long alsa_vol;
983
984 if (u->hw_dB_supported) {
985
986 if ((err = snd_mixer_selem_get_capture_dB(u->mixer_elem, u->mixer_map[i], &alsa_vol)) < 0)
987 goto fail;
988
989 #ifdef HAVE_VALGRIND_MEMCHECK_H
990 VALGRIND_MAKE_MEM_DEFINED(&alsa_vol, sizeof(alsa_vol));
991 #endif
992
993 r.values[i] = pa_sw_volume_from_dB((double) (alsa_vol - u->hw_dB_max) / 100.0);
994 } else {
995
996 if ((err = snd_mixer_selem_get_capture_volume(u->mixer_elem, u->mixer_map[i], &alsa_vol)) < 0)
997 goto fail;
998
999 r.values[i] = from_alsa_volume(u, alsa_vol);
1000 }
1001 }
1002
1003 } else {
1004 long alsa_vol;
1005
1006 if (u->hw_dB_supported) {
1007
1008 if ((err = snd_mixer_selem_get_capture_dB(u->mixer_elem, SND_MIXER_SCHN_MONO, &alsa_vol)) < 0)
1009 goto fail;
1010
1011 #ifdef HAVE_VALGRIND_MEMCHECK_H
1012 VALGRIND_MAKE_MEM_DEFINED(&alsa_vol, sizeof(alsa_vol));
1013 #endif
1014
1015 pa_cvolume_set(&r, s->sample_spec.channels, pa_sw_volume_from_dB((double) (alsa_vol - u->hw_dB_max) / 100.0));
1016
1017 } else {
1018
1019 if ((err = snd_mixer_selem_get_capture_volume(u->mixer_elem, SND_MIXER_SCHN_MONO, &alsa_vol)) < 0)
1020 goto fail;
1021
1022 pa_cvolume_set(&r, s->sample_spec.channels, from_alsa_volume(u, alsa_vol));
1023 }
1024 }
1025
1026 pa_log_debug("Read hardware volume: %s", pa_cvolume_snprint(t, sizeof(t), &r));
1027
1028 if (!pa_cvolume_equal(&u->hardware_volume, &r)) {
1029
1030 s->virtual_volume = u->hardware_volume = r;
1031
1032 if (u->hw_dB_supported) {
1033 pa_cvolume reset;
1034
1035 /* Hmm, so the hardware volume changed, let's reset our software volume */
1036 pa_cvolume_reset(&reset, s->sample_spec.channels);
1037 pa_source_set_soft_volume(s, &reset);
1038 }
1039 }
1040
1041 return;
1042
1043 fail:
1044 pa_log_error("Unable to read volume: %s", pa_alsa_strerror(err));
1045 }
1046
1047 static void source_set_volume_cb(pa_source *s) {
1048 struct userdata *u = s->userdata;
1049 int err;
1050 unsigned i;
1051 pa_cvolume r;
1052
1053 pa_assert(u);
1054 pa_assert(u->mixer_elem);
1055
1056 if (u->mixer_seperate_channels) {
1057
1058 r.channels = s->sample_spec.channels;
1059
1060 for (i = 0; i < s->sample_spec.channels; i++) {
1061 long alsa_vol;
1062 pa_volume_t vol;
1063
1064 vol = s->virtual_volume.values[i];
1065
1066 if (u->hw_dB_supported) {
1067
1068 alsa_vol = (long) (pa_sw_volume_to_dB(vol) * 100);
1069 alsa_vol += u->hw_dB_max;
1070 alsa_vol = PA_CLAMP_UNLIKELY(alsa_vol, u->hw_dB_min, u->hw_dB_max);
1071
1072 if ((err = snd_mixer_selem_set_capture_dB(u->mixer_elem, u->mixer_map[i], alsa_vol, 1)) < 0)
1073 goto fail;
1074
1075 if ((err = snd_mixer_selem_get_capture_dB(u->mixer_elem, u->mixer_map[i], &alsa_vol)) < 0)
1076 goto fail;
1077
1078 #ifdef HAVE_VALGRIND_MEMCHECK_H
1079 VALGRIND_MAKE_MEM_DEFINED(&alsa_vol, sizeof(alsa_vol));
1080 #endif
1081
1082 r.values[i] = pa_sw_volume_from_dB((double) (alsa_vol - u->hw_dB_max) / 100.0);
1083
1084 } else {
1085 alsa_vol = to_alsa_volume(u, vol);
1086
1087 if ((err = snd_mixer_selem_set_capture_volume(u->mixer_elem, u->mixer_map[i], alsa_vol)) < 0)
1088 goto fail;
1089
1090 if ((err = snd_mixer_selem_get_capture_volume(u->mixer_elem, u->mixer_map[i], &alsa_vol)) < 0)
1091 goto fail;
1092
1093 r.values[i] = from_alsa_volume(u, alsa_vol);
1094 }
1095 }
1096
1097 } else {
1098 pa_volume_t vol;
1099 long alsa_vol;
1100
1101 vol = pa_cvolume_max(&s->virtual_volume);
1102
1103 if (u->hw_dB_supported) {
1104 alsa_vol = (long) (pa_sw_volume_to_dB(vol) * 100);
1105 alsa_vol += u->hw_dB_max;
1106 alsa_vol = PA_CLAMP_UNLIKELY(alsa_vol, u->hw_dB_min, u->hw_dB_max);
1107
1108 if ((err = snd_mixer_selem_set_capture_dB_all(u->mixer_elem, alsa_vol, 1)) < 0)
1109 goto fail;
1110
1111 if ((err = snd_mixer_selem_get_capture_dB(u->mixer_elem, SND_MIXER_SCHN_MONO, &alsa_vol)) < 0)
1112 goto fail;
1113
1114 #ifdef HAVE_VALGRIND_MEMCHECK_H
1115 VALGRIND_MAKE_MEM_DEFINED(&alsa_vol, sizeof(alsa_vol));
1116 #endif
1117
1118 pa_cvolume_set(&r, s->sample_spec.channels, pa_sw_volume_from_dB((double) (alsa_vol - u->hw_dB_max) / 100.0));
1119
1120 } else {
1121 alsa_vol = to_alsa_volume(u, vol);
1122
1123 if ((err = snd_mixer_selem_set_capture_volume_all(u->mixer_elem, alsa_vol)) < 0)
1124 goto fail;
1125
1126 if ((err = snd_mixer_selem_get_capture_volume(u->mixer_elem, SND_MIXER_SCHN_MONO, &alsa_vol)) < 0)
1127 goto fail;
1128
1129 pa_cvolume_set(&r, s->sample_spec.channels, from_alsa_volume(u, alsa_vol));
1130 }
1131 }
1132
1133 u->hardware_volume = r;
1134
1135 if (u->hw_dB_supported) {
1136 char t[PA_CVOLUME_SNPRINT_MAX];
1137
1138 /* Match exactly what the user requested by software */
1139
1140 pa_sw_cvolume_divide(&s->soft_volume, &s->virtual_volume, &u->hardware_volume);
1141
1142 pa_log_debug("Requested volume: %s", pa_cvolume_snprint(t, sizeof(t), &s->virtual_volume));
1143 pa_log_debug("Got hardware volume: %s", pa_cvolume_snprint(t, sizeof(t), &u->hardware_volume));
1144 pa_log_debug("Calculated software volume: %s", pa_cvolume_snprint(t, sizeof(t), &s->soft_volume));
1145
1146 } else
1147
1148 /* We can't match exactly what the user requested, hence let's
1149 * at least tell the user about it */
1150
1151 s->virtual_volume = r;
1152
1153 return;
1154
1155 fail:
1156 pa_log_error("Unable to set volume: %s", pa_alsa_strerror(err));
1157 }
1158
1159 static void source_get_mute_cb(pa_source *s) {
1160 struct userdata *u = s->userdata;
1161 int err, sw = 0;
1162
1163 pa_assert(u);
1164 pa_assert(u->mixer_elem);
1165
1166 if ((err = snd_mixer_selem_get_capture_switch(u->mixer_elem, 0, &sw)) < 0) {
1167 pa_log_error("Unable to get switch: %s", pa_alsa_strerror(err));
1168 return;
1169 }
1170
1171 s->muted = !sw;
1172 }
1173
1174 static void source_set_mute_cb(pa_source *s) {
1175 struct userdata *u = s->userdata;
1176 int err;
1177
1178 pa_assert(u);
1179 pa_assert(u->mixer_elem);
1180
1181 if ((err = snd_mixer_selem_set_capture_switch_all(u->mixer_elem, !s->muted)) < 0) {
1182 pa_log_error("Unable to set switch: %s", pa_alsa_strerror(err));
1183 return;
1184 }
1185 }
1186
1187 static void source_update_requested_latency_cb(pa_source *s) {
1188 struct userdata *u = s->userdata;
1189 pa_assert(u);
1190
1191 if (!u->pcm_handle)
1192 return;
1193
1194 update_sw_params(u);
1195 }
1196
1197 static void thread_func(void *userdata) {
1198 struct userdata *u = userdata;
1199 unsigned short revents = 0;
1200
1201 pa_assert(u);
1202
1203 pa_log_debug("Thread starting up");
1204
1205 if (u->core->realtime_scheduling)
1206 pa_make_realtime(u->core->realtime_priority);
1207
1208 pa_thread_mq_install(&u->thread_mq);
1209 pa_rtpoll_install(u->rtpoll);
1210
1211 for (;;) {
1212 int ret;
1213
1214 #ifdef DEBUG_TIMING
1215 pa_log_debug("Loop");
1216 #endif
1217
1218 /* Read some data and pass it to the sources */
1219 if (PA_SOURCE_IS_OPENED(u->source->thread_info.state)) {
1220 int work_done;
1221 pa_usec_t sleep_usec = 0;
1222
1223 if (u->use_mmap)
1224 work_done = mmap_read(u, &sleep_usec, revents & POLLIN);
1225 else
1226 work_done = unix_read(u, &sleep_usec, revents & POLLIN);
1227
1228 if (work_done < 0)
1229 goto fail;
1230
1231 /* pa_log_debug("work_done = %i", work_done); */
1232
1233 if (work_done)
1234 update_smoother(u);
1235
1236 if (u->use_tsched) {
1237 pa_usec_t cusec;
1238
1239 /* OK, the capture buffer is now empty, let's
1240 * calculate when to wake up next */
1241
1242 /* pa_log_debug("Waking up in %0.2fms (sound card clock).", (double) sleep_usec / PA_USEC_PER_MSEC); */
1243
1244 /* Convert from the sound card time domain to the
1245 * system time domain */
1246 cusec = pa_smoother_translate(u->smoother, pa_rtclock_usec(), sleep_usec);
1247
1248 /* pa_log_debug("Waking up in %0.2fms (system clock).", (double) cusec / PA_USEC_PER_MSEC); */
1249
1250 /* We don't trust the conversion, so we wake up whatever comes first */
1251 pa_rtpoll_set_timer_relative(u->rtpoll, PA_MIN(sleep_usec, cusec));
1252 }
1253 } else if (u->use_tsched)
1254
1255 /* OK, we're in an invalid state, let's disable our timers */
1256 pa_rtpoll_set_timer_disabled(u->rtpoll);
1257
1258 /* Hmm, nothing to do. Let's sleep */
1259 if ((ret = pa_rtpoll_run(u->rtpoll, TRUE)) < 0)
1260 goto fail;
1261
1262 if (ret == 0)
1263 goto finish;
1264
1265 /* Tell ALSA about this and process its response */
1266 if (PA_SOURCE_IS_OPENED(u->source->thread_info.state)) {
1267 struct pollfd *pollfd;
1268 int err;
1269 unsigned n;
1270
1271 pollfd = pa_rtpoll_item_get_pollfd(u->alsa_rtpoll_item, &n);
1272
1273 if ((err = snd_pcm_poll_descriptors_revents(u->pcm_handle, pollfd, n, &revents)) < 0) {
1274 pa_log("snd_pcm_poll_descriptors_revents() failed: %s", pa_alsa_strerror(err));
1275 goto fail;
1276 }
1277
1278 if (revents & ~POLLIN) {
1279 if (pa_alsa_recover_from_poll(u->pcm_handle, revents) < 0)
1280 goto fail;
1281
1282 snd_pcm_start(u->pcm_handle);
1283 } else if (revents && u->use_tsched && pa_log_ratelimit())
1284 pa_log_debug("Wakeup from ALSA!");
1285
1286 } else
1287 revents = 0;
1288 }
1289
1290 fail:
1291 /* If this was no regular exit from the loop we have to continue
1292 * processing messages until we received PA_MESSAGE_SHUTDOWN */
1293 pa_asyncmsgq_post(u->thread_mq.outq, PA_MSGOBJECT(u->core), PA_CORE_MESSAGE_UNLOAD_MODULE, u->module, 0, NULL, NULL);
1294 pa_asyncmsgq_wait_for(u->thread_mq.inq, PA_MESSAGE_SHUTDOWN);
1295
1296 finish:
1297 pa_log_debug("Thread shutting down");
1298 }
1299
1300 static void set_source_name(pa_source_new_data *data, pa_modargs *ma, const char *device_id, const char *device_name) {
1301 const char *n;
1302 char *t;
1303
1304 pa_assert(data);
1305 pa_assert(ma);
1306 pa_assert(device_name);
1307
1308 if ((n = pa_modargs_get_value(ma, "source_name", NULL))) {
1309 pa_source_new_data_set_name(data, n);
1310 data->namereg_fail = TRUE;
1311 return;
1312 }
1313
1314 if ((n = pa_modargs_get_value(ma, "name", NULL)))
1315 data->namereg_fail = TRUE;
1316 else {
1317 n = device_id ? device_id : device_name;
1318 data->namereg_fail = FALSE;
1319 }
1320
1321 t = pa_sprintf_malloc("alsa_input.%s", n);
1322 pa_source_new_data_set_name(data, t);
1323 pa_xfree(t);
1324 }
1325
1326 static int setup_mixer(struct userdata *u, pa_bool_t ignore_dB) {
1327 pa_assert(u);
1328
1329 if (!u->mixer_handle)
1330 return 0;
1331
1332 pa_assert(u->mixer_elem);
1333
1334 if (snd_mixer_selem_has_capture_volume(u->mixer_elem)) {
1335 pa_bool_t suitable = FALSE;
1336
1337 if (snd_mixer_selem_get_capture_volume_range(u->mixer_elem, &u->hw_volume_min, &u->hw_volume_max) < 0)
1338 pa_log_info("Failed to get volume range. Falling back to software volume control.");
1339 else if (u->hw_volume_min >= u->hw_volume_max)
1340 pa_log_warn("Your kernel driver is broken: it reports a volume range from %li to %li which makes no sense.", u->hw_volume_min, u->hw_volume_max);
1341 else {
1342 pa_log_info("Volume ranges from %li to %li.", u->hw_volume_min, u->hw_volume_max);
1343 suitable = TRUE;
1344 }
1345
1346 if (suitable) {
1347 if (ignore_dB || snd_mixer_selem_get_capture_dB_range(u->mixer_elem, &u->hw_dB_min, &u->hw_dB_max) < 0)
1348 pa_log_info("Mixer doesn't support dB information or data is ignored.");
1349 else {
1350 #ifdef HAVE_VALGRIND_MEMCHECK_H
1351 VALGRIND_MAKE_MEM_DEFINED(&u->hw_dB_min, sizeof(u->hw_dB_min));
1352 VALGRIND_MAKE_MEM_DEFINED(&u->hw_dB_max, sizeof(u->hw_dB_max));
1353 #endif
1354
1355 if (u->hw_dB_min >= u->hw_dB_max)
1356 pa_log_warn("Your kernel driver is broken: it reports a volume range from %0.2f dB to %0.2f dB which makes no sense.", (double) u->hw_dB_min/100.0, (double) u->hw_dB_max/100.0);
1357 else {
1358 pa_log_info("Volume ranges from %0.2f dB to %0.2f dB.", (double) u->hw_dB_min/100.0, (double) u->hw_dB_max/100.0);
1359 u->hw_dB_supported = TRUE;
1360
1361 if (u->hw_dB_max > 0) {
1362 u->source->base_volume = pa_sw_volume_from_dB(- (double) u->hw_dB_max/100.0);
1363 pa_log_info("Fixing base volume to %0.2f dB", pa_sw_volume_to_dB(u->source->base_volume));
1364 } else
1365 pa_log_info("No particular base volume set, fixing to 0 dB");
1366 }
1367 }
1368
1369 if (!u->hw_dB_supported &&
1370 u->hw_volume_max - u->hw_volume_min < 3) {
1371
1372 pa_log_info("Device has less than 4 volume levels. Falling back to software volume control.");
1373 suitable = FALSE;
1374 }
1375 }
1376
1377 if (suitable) {
1378 u->mixer_seperate_channels = pa_alsa_calc_mixer_map(u->mixer_elem, &u->source->channel_map, u->mixer_map, FALSE) >= 0;
1379
1380 u->source->get_volume = source_get_volume_cb;
1381 u->source->set_volume = source_set_volume_cb;
1382 u->source->flags |= PA_SOURCE_HW_VOLUME_CTRL | (u->hw_dB_supported ? PA_SOURCE_DECIBEL_VOLUME : 0);
1383 pa_log_info("Using hardware volume control. Hardware dB scale %s.", u->hw_dB_supported ? "supported" : "not supported");
1384
1385 if (!u->hw_dB_supported)
1386 u->source->n_volume_steps = u->hw_volume_max - u->hw_volume_min + 1;
1387 } else
1388 pa_log_info("Using software volume control.");
1389 }
1390
1391 if (snd_mixer_selem_has_capture_switch(u->mixer_elem)) {
1392 u->source->get_mute = source_get_mute_cb;
1393 u->source->set_mute = source_set_mute_cb;
1394 u->source->flags |= PA_SOURCE_HW_MUTE_CTRL;
1395 } else
1396 pa_log_info("Using software mute control.");
1397
1398 u->mixer_fdl = pa_alsa_fdlist_new();
1399
1400 if (pa_alsa_fdlist_set_mixer(u->mixer_fdl, u->mixer_handle, u->core->mainloop) < 0) {
1401 pa_log("Failed to initialize file descriptor monitoring");
1402 return -1;
1403 }
1404
1405 snd_mixer_elem_set_callback(u->mixer_elem, mixer_callback);
1406 snd_mixer_elem_set_callback_private(u->mixer_elem, u);
1407
1408 return 0;
1409 }
1410
1411 pa_source *pa_alsa_source_new(pa_module *m, pa_modargs *ma, const char*driver, pa_card *card, const pa_alsa_profile_info *profile) {
1412
1413 struct userdata *u = NULL;
1414 const char *dev_id = NULL;
1415 pa_sample_spec ss, requested_ss;
1416 pa_channel_map map;
1417 uint32_t nfrags, hwbuf_size, frag_size, tsched_size, tsched_watermark;
1418 snd_pcm_uframes_t period_frames, tsched_frames;
1419 size_t frame_size;
1420 pa_bool_t use_mmap = TRUE, b, use_tsched = TRUE, d, ignore_dB = FALSE;
1421 pa_source_new_data data;
1422 char *control_device = NULL;
1423
1424 pa_assert(m);
1425 pa_assert(ma);
1426
1427 ss = m->core->default_sample_spec;
1428 map = m->core->default_channel_map;
1429 if (pa_modargs_get_sample_spec_and_channel_map(ma, &ss, &map, PA_CHANNEL_MAP_ALSA) < 0) {
1430 pa_log("Failed to parse sample specification");
1431 goto fail;
1432 }
1433
1434 requested_ss = ss;
1435 frame_size = pa_frame_size(&ss);
1436
1437 nfrags = m->core->default_n_fragments;
1438 frag_size = (uint32_t) pa_usec_to_bytes(m->core->default_fragment_size_msec*PA_USEC_PER_MSEC, &ss);
1439 if (frag_size <= 0)
1440 frag_size = (uint32_t) frame_size;
1441 tsched_size = (uint32_t) pa_usec_to_bytes(DEFAULT_TSCHED_BUFFER_USEC, &ss);
1442 tsched_watermark = (uint32_t) pa_usec_to_bytes(DEFAULT_TSCHED_WATERMARK_USEC, &ss);
1443
1444 if (pa_modargs_get_value_u32(ma, "fragments", &nfrags) < 0 ||
1445 pa_modargs_get_value_u32(ma, "fragment_size", &frag_size) < 0 ||
1446 pa_modargs_get_value_u32(ma, "tsched_buffer_size", &tsched_size) < 0 ||
1447 pa_modargs_get_value_u32(ma, "tsched_buffer_watermark", &tsched_watermark) < 0) {
1448 pa_log("Failed to parse buffer metrics");
1449 goto fail;
1450 }
1451
1452 hwbuf_size = frag_size * nfrags;
1453 period_frames = frag_size/frame_size;
1454 tsched_frames = tsched_size/frame_size;
1455
1456 if (pa_modargs_get_value_boolean(ma, "mmap", &use_mmap) < 0) {
1457 pa_log("Failed to parse mmap argument.");
1458 goto fail;
1459 }
1460
1461 if (pa_modargs_get_value_boolean(ma, "tsched", &use_tsched) < 0) {
1462 pa_log("Failed to parse timer_scheduling argument.");
1463 goto fail;
1464 }
1465
1466 if (pa_modargs_get_value_boolean(ma, "ignore_dB", &ignore_dB) < 0) {
1467 pa_log("Failed to parse ignore_dB argument.");
1468 goto fail;
1469 }
1470
1471 if (use_tsched && !pa_rtclock_hrtimer()) {
1472 pa_log_notice("Disabling timer-based scheduling because high-resolution timers are not available from the kernel.");
1473 use_tsched = FALSE;
1474 }
1475
1476 u = pa_xnew0(struct userdata, 1);
1477 u->core = m->core;
1478 u->module = m;
1479 u->use_mmap = use_mmap;
1480 u->use_tsched = use_tsched;
1481 u->rtpoll = pa_rtpoll_new();
1482 pa_thread_mq_init(&u->thread_mq, m->core->mainloop, u->rtpoll);
1483 u->alsa_rtpoll_item = NULL;
1484
1485 u->smoother = pa_smoother_new(
1486 DEFAULT_TSCHED_WATERMARK_USEC*2,
1487 DEFAULT_TSCHED_WATERMARK_USEC*2,
1488 TRUE,
1489 TRUE,
1490 5,
1491 pa_rtclock_usec(),
1492 FALSE);
1493
1494 dev_id = pa_modargs_get_value(
1495 ma, "device_id",
1496 pa_modargs_get_value(ma, "device", DEFAULT_DEVICE));
1497
1498 if (reserve_init(u, dev_id) < 0)
1499 goto fail;
1500
1501 if (reserve_monitor_init(u, dev_id) < 0)
1502 goto fail;
1503
1504 b = use_mmap;
1505 d = use_tsched;
1506
1507 if (profile) {
1508
1509 if (!(dev_id = pa_modargs_get_value(ma, "device_id", NULL))) {
1510 pa_log("device_id= not set");
1511 goto fail;
1512 }
1513
1514 if (!(u->pcm_handle = pa_alsa_open_by_device_id_profile(
1515 dev_id,
1516 &u->device_name,
1517 &ss, &map,
1518 SND_PCM_STREAM_CAPTURE,
1519 &nfrags, &period_frames, tsched_frames,
1520 &b, &d, profile)))
1521 goto fail;
1522
1523 } else if ((dev_id = pa_modargs_get_value(ma, "device_id", NULL))) {
1524
1525 if (!(u->pcm_handle = pa_alsa_open_by_device_id_auto(
1526 dev_id,
1527 &u->device_name,
1528 &ss, &map,
1529 SND_PCM_STREAM_CAPTURE,
1530 &nfrags, &period_frames, tsched_frames,
1531 &b, &d, &profile)))
1532 goto fail;
1533
1534 } else {
1535
1536 if (!(u->pcm_handle = pa_alsa_open_by_device_string(
1537 pa_modargs_get_value(ma, "device", DEFAULT_DEVICE),
1538 &u->device_name,
1539 &ss, &map,
1540 SND_PCM_STREAM_CAPTURE,
1541 &nfrags, &period_frames, tsched_frames,
1542 &b, &d, FALSE)))
1543 goto fail;
1544 }
1545
1546 pa_assert(u->device_name);
1547 pa_log_info("Successfully opened device %s.", u->device_name);
1548
1549 if (pa_alsa_pcm_is_modem(u->pcm_handle)) {
1550 pa_log_notice("Device %s is modem, refusing further initialization.", u->device_name);
1551 goto fail;
1552 }
1553
1554 if (profile)
1555 pa_log_info("Selected configuration '%s' (%s).", profile->description, profile->name);
1556
1557 if (use_mmap && !b) {
1558 pa_log_info("Device doesn't support mmap(), falling back to UNIX read/write mode.");
1559 u->use_mmap = use_mmap = FALSE;
1560 }
1561
1562 if (use_tsched && (!b || !d)) {
1563 pa_log_info("Cannot enable timer-based scheduling, falling back to sound IRQ scheduling.");
1564 u->use_tsched = use_tsched = FALSE;
1565 }
1566
1567 if (use_tsched && !pa_alsa_pcm_is_hw(u->pcm_handle)) {
1568 pa_log_info("Device is not a hardware device, disabling timer-based scheduling.");
1569 u->use_tsched = use_tsched = FALSE;
1570 }
1571
1572 if (u->use_mmap)
1573 pa_log_info("Successfully enabled mmap() mode.");
1574
1575 if (u->use_tsched)
1576 pa_log_info("Successfully enabled timer-based scheduling mode.");
1577
1578 /* ALSA might tweak the sample spec, so recalculate the frame size */
1579 frame_size = pa_frame_size(&ss);
1580
1581 pa_alsa_find_mixer_and_elem(u->pcm_handle, &control_device, &u->mixer_handle, &u->mixer_elem, pa_modargs_get_value(ma, "control", NULL), profile);
1582
1583 pa_source_new_data_init(&data);
1584 data.driver = driver;
1585 data.module = m;
1586 data.card = card;
1587 set_source_name(&data, ma, dev_id, u->device_name);
1588 pa_source_new_data_set_sample_spec(&data, &ss);
1589 pa_source_new_data_set_channel_map(&data, &map);
1590
1591 pa_alsa_init_proplist_pcm(m->core, data.proplist, u->pcm_handle, u->mixer_elem);
1592 pa_proplist_sets(data.proplist, PA_PROP_DEVICE_STRING, u->device_name);
1593 pa_proplist_setf(data.proplist, PA_PROP_DEVICE_BUFFERING_BUFFER_SIZE, "%lu", (unsigned long) (period_frames * frame_size * nfrags));
1594 pa_proplist_setf(data.proplist, PA_PROP_DEVICE_BUFFERING_FRAGMENT_SIZE, "%lu", (unsigned long) (period_frames * frame_size));
1595 pa_proplist_sets(data.proplist, PA_PROP_DEVICE_ACCESS_MODE, u->use_tsched ? "mmap+timer" : (u->use_mmap ? "mmap" : "serial"));
1596
1597 if (profile) {
1598 pa_proplist_sets(data.proplist, PA_PROP_DEVICE_PROFILE_NAME, profile->name);
1599 pa_proplist_sets(data.proplist, PA_PROP_DEVICE_PROFILE_DESCRIPTION, profile->description);
1600 }
1601
1602 pa_alsa_init_description(data.proplist);
1603
1604 if (control_device) {
1605 pa_alsa_init_proplist_ctl(data.proplist, control_device);
1606 pa_xfree(control_device);
1607 }
1608
1609 if (pa_modargs_get_proplist(ma, "source_properties", data.proplist, PA_UPDATE_REPLACE) < 0) {
1610 pa_log("Invalid properties");
1611 pa_source_new_data_done(&data);
1612 goto fail;
1613 }
1614
1615 u->source = pa_source_new(m->core, &data, PA_SOURCE_HARDWARE|PA_SOURCE_LATENCY|(u->use_tsched ? PA_SOURCE_DYNAMIC_LATENCY : 0));
1616 pa_source_new_data_done(&data);
1617
1618 if (!u->source) {
1619 pa_log("Failed to create source object");
1620 goto fail;
1621 }
1622
1623 u->source->parent.process_msg = source_process_msg;
1624 u->source->update_requested_latency = source_update_requested_latency_cb;
1625 u->source->set_state = source_set_state_cb;
1626 u->source->userdata = u;
1627
1628 pa_source_set_asyncmsgq(u->source, u->thread_mq.inq);
1629 pa_source_set_rtpoll(u->source, u->rtpoll);
1630
1631 u->frame_size = frame_size;
1632 u->fragment_size = frag_size = (uint32_t) (period_frames * frame_size);
1633 u->nfragments = nfrags;
1634 u->hwbuf_size = u->fragment_size * nfrags;
1635 u->tsched_watermark = pa_usec_to_bytes_round_up(pa_bytes_to_usec_round_up(tsched_watermark, &requested_ss), &u->source->sample_spec);
1636 pa_cvolume_mute(&u->hardware_volume, u->source->sample_spec.channels);
1637
1638 pa_log_info("Using %u fragments of size %lu bytes, buffer time is %0.2fms",
1639 nfrags, (long unsigned) u->fragment_size,
1640 (double) pa_bytes_to_usec(u->hwbuf_size, &ss) / PA_USEC_PER_MSEC);
1641
1642 if (u->use_tsched) {
1643 u->watermark_step = pa_usec_to_bytes(TSCHED_WATERMARK_STEP_USEC, &u->source->sample_spec);
1644
1645 fix_min_sleep_wakeup(u);
1646 fix_tsched_watermark(u);
1647
1648 pa_source_set_latency_range(u->source,
1649 0,
1650 pa_bytes_to_usec(u->hwbuf_size, &ss));
1651
1652 pa_log_info("Time scheduling watermark is %0.2fms",
1653 (double) pa_bytes_to_usec(u->tsched_watermark, &ss) / PA_USEC_PER_MSEC);
1654 } else
1655 pa_source_set_fixed_latency(u->source, pa_bytes_to_usec(u->hwbuf_size, &ss));
1656
1657 reserve_update(u);
1658
1659 if (update_sw_params(u) < 0)
1660 goto fail;
1661
1662 if (setup_mixer(u, ignore_dB) < 0)
1663 goto fail;
1664
1665 pa_alsa_dump(PA_LOG_DEBUG, u->pcm_handle);
1666
1667 if (!(u->thread = pa_thread_new(thread_func, u))) {
1668 pa_log("Failed to create thread.");
1669 goto fail;
1670 }
1671 /* Get initial mixer settings */
1672 if (data.volume_is_set) {
1673 if (u->source->set_volume)
1674 u->source->set_volume(u->source);
1675 } else {
1676 if (u->source->get_volume)
1677 u->source->get_volume(u->source);
1678 }
1679
1680 if (data.muted_is_set) {
1681 if (u->source->set_mute)
1682 u->source->set_mute(u->source);
1683 } else {
1684 if (u->source->get_mute)
1685 u->source->get_mute(u->source);
1686 }
1687
1688 pa_source_put(u->source);
1689
1690 return u->source;
1691
1692 fail:
1693
1694 if (u)
1695 userdata_free(u);
1696
1697 return NULL;
1698 }
1699
1700 static void userdata_free(struct userdata *u) {
1701 pa_assert(u);
1702
1703 if (u->source)
1704 pa_source_unlink(u->source);
1705
1706 if (u->thread) {
1707 pa_asyncmsgq_send(u->thread_mq.inq, NULL, PA_MESSAGE_SHUTDOWN, NULL, 0, NULL);
1708 pa_thread_free(u->thread);
1709 }
1710
1711 pa_thread_mq_done(&u->thread_mq);
1712
1713 if (u->source)
1714 pa_source_unref(u->source);
1715
1716 if (u->alsa_rtpoll_item)
1717 pa_rtpoll_item_free(u->alsa_rtpoll_item);
1718
1719 if (u->rtpoll)
1720 pa_rtpoll_free(u->rtpoll);
1721
1722 if (u->mixer_fdl)
1723 pa_alsa_fdlist_free(u->mixer_fdl);
1724
1725 if (u->mixer_handle)
1726 snd_mixer_close(u->mixer_handle);
1727
1728 if (u->pcm_handle) {
1729 snd_pcm_drop(u->pcm_handle);
1730 snd_pcm_close(u->pcm_handle);
1731 }
1732
1733 if (u->smoother)
1734 pa_smoother_free(u->smoother);
1735
1736 reserve_done(u);
1737 monitor_done(u);
1738
1739 pa_xfree(u->device_name);
1740 pa_xfree(u);
1741 }
1742
1743 void pa_alsa_source_free(pa_source *s) {
1744 struct userdata *u;
1745
1746 pa_source_assert_ref(s);
1747 pa_assert_se(u = s->userdata);
1748
1749 userdata_free(u);
1750 }