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