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