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