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