1 /***
2 This file is part of PulseAudio.
3
4 Copyright 2006 Lennart Poettering
5 Copyright 2006-2007 Pierre Ossman <ossman@cendio.se> for Cendio AB
6 Copyright 2009 Finn Thain
7
8 PulseAudio is free software; you can redistribute it and/or modify
9 it under the terms of the GNU Lesser General Public License as published
10 by the Free Software Foundation; either version 2.1 of the License,
11 or (at your option) any later version.
12
13 PulseAudio is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public License
19 along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include <stdlib.h>
27 #include <stdio.h>
28 #include <errno.h>
29 #include <fcntl.h>
30 #include <unistd.h>
31 #include <sys/ioctl.h>
32 #include <sys/types.h>
33
34 #ifdef HAVE_POLL_H
35 #include <poll.h>
36 #endif
37
38 #include <signal.h>
39 #include <stropts.h>
40 #include <sys/audio.h>
41
42 #ifdef HAVE_SYS_CONF_H
43 #include <sys/conf.h>
44 #endif
45
46 #include <pulse/mainloop-signal.h>
47 #include <pulse/xmalloc.h>
48 #include <pulse/timeval.h>
49 #include <pulse/util.h>
50 #include <pulse/rtclock.h>
51
52 #include <pulsecore/sink.h>
53 #include <pulsecore/source.h>
54 #include <pulsecore/module.h>
55 #include <pulsecore/sample-util.h>
56 #include <pulsecore/core-util.h>
57 #include <pulsecore/modargs.h>
58 #include <pulsecore/log.h>
59 #include <pulsecore/core-error.h>
60 #include <pulsecore/thread-mq.h>
61 #include <pulsecore/rtpoll.h>
62 #include <pulsecore/thread.h>
63
64 #ifdef USE_SMOOTHER_2
65 #include <pulsecore/time-smoother_2.h>
66 #else
67 #include <pulsecore/time-smoother.h>
68 #endif
69
70 PA_MODULE_AUTHOR("Pierre Ossman");
71 PA_MODULE_DESCRIPTION("Solaris Sink/Source");
72 PA_MODULE_VERSION(PACKAGE_VERSION);
73 PA_MODULE_USAGE(
74 "sink_name=<name for the sink> "
75 "sink_properties=<properties for the sink> "
76 "source_name=<name for the source> "
77 "source_properties=<properties for the source> "
78 "device=<audio device file name> "
79 "record=<enable source?> "
80 "playback=<enable sink?> "
81 "format=<sample format> "
82 "channels=<number of channels> "
83 "rate=<sample rate> "
84 "buffer_length=<milliseconds> "
85 "channel_map=<channel map>");
86 PA_MODULE_LOAD_ONCE(false);
87
88 struct userdata {
89 pa_core *core;
90 pa_sink *sink;
91 pa_source *source;
92
93 pa_thread *thread;
94 pa_thread_mq thread_mq;
95 pa_rtpoll *rtpoll;
96
97 pa_signal_event *sig;
98
99 pa_memchunk memchunk;
100
101 uint32_t frame_size;
102 int32_t buffer_size;
103 uint64_t written_bytes, read_bytes;
104
105 char *device_name;
106 int mode;
107 int fd;
108 pa_rtpoll_item *rtpoll_item;
109 pa_module *module;
110
111 bool sink_suspended, source_suspended;
112
113 uint32_t play_samples_msw, record_samples_msw;
114 uint32_t prev_playback_samples, prev_record_samples;
115
116 int32_t minimum_request;
117
118 #ifdef USE_SMOOTHER_2
119 pa_smoother_2 *smoother;
120 #else
121 pa_smoother *smoother;
122 #endif
123 };
124
125 static const char* const valid_modargs[] = {
126 "sink_name",
127 "sink_properties",
128 "source_name",
129 "source_properties",
130 "device",
131 "record",
132 "playback",
133 "buffer_length",
134 "format",
135 "rate",
136 "channels",
137 "channel_map",
138 NULL
139 };
140
141 #define DEFAULT_DEVICE "/dev/audio"
142
143 #define MAX_RENDER_HZ (300)
144 /* This render rate limit imposes a minimum latency, but without it we waste too much CPU time. */
145
146 #define MAX_BUFFER_SIZE (128 * 1024)
147 /* An attempt to buffer more than 128 KB causes write() to fail with errno == EAGAIN. */
148
get_playback_buffered_bytes(struct userdata * u)149 static uint64_t get_playback_buffered_bytes(struct userdata *u) {
150 audio_info_t info;
151 uint64_t played_bytes;
152 int err;
153
154 pa_assert(u->sink);
155
156 err = ioctl(u->fd, AUDIO_GETINFO, &info);
157 pa_assert(err >= 0);
158
159 /* Handle wrap-around of the device's sample counter, which is a uint_32. */
160 if (u->prev_playback_samples > info.play.samples) {
161 /*
162 * Unfortunately info.play.samples can sometimes go backwards, even before it wraps!
163 * The bug seems to be absent on Solaris x86 nv117 with audio810 driver, at least on this (UP) machine.
164 * The bug is present on a different (SMP) machine running Solaris x86 nv103 with audioens driver.
165 * An earlier revision of this file mentions the same bug independently (unknown configuration).
166 */
167 if (u->prev_playback_samples + info.play.samples < 240000) {
168 ++u->play_samples_msw;
169 } else {
170 pa_log_debug("play.samples went backwards %d bytes", u->prev_playback_samples - info.play.samples);
171 }
172 }
173 u->prev_playback_samples = info.play.samples;
174 played_bytes = (((uint64_t)u->play_samples_msw << 32) + info.play.samples) * u->frame_size;
175
176 #ifdef USE_SMOOTHER_2
177 pa_smoother_2_put(u->smoother, pa_rtclock_now(), played_bytes);
178 #else
179 pa_smoother_put(u->smoother, pa_rtclock_now(), pa_bytes_to_usec(played_bytes, &u->sink->sample_spec));
180 #endif
181
182 if (u->written_bytes > played_bytes)
183 return u->written_bytes - played_bytes;
184 else
185 return 0;
186 }
187
sink_get_latency(struct userdata * u,pa_sample_spec * ss)188 static pa_usec_t sink_get_latency(struct userdata *u, pa_sample_spec *ss) {
189 pa_usec_t r = 0;
190
191 pa_assert(u);
192 pa_assert(ss);
193
194 if (u->fd >= 0) {
195 r = pa_bytes_to_usec(get_playback_buffered_bytes(u), ss);
196 if (u->memchunk.memblock)
197 r += pa_bytes_to_usec(u->memchunk.length, ss);
198 }
199 return r;
200 }
201
get_recorded_bytes(struct userdata * u)202 static uint64_t get_recorded_bytes(struct userdata *u) {
203 audio_info_t info;
204 uint64_t result;
205 int err;
206
207 pa_assert(u->source);
208
209 err = ioctl(u->fd, AUDIO_GETINFO, &info);
210 pa_assert(err >= 0);
211
212 if (u->prev_record_samples > info.record.samples)
213 ++u->record_samples_msw;
214 u->prev_record_samples = info.record.samples;
215 result = (((uint64_t)u->record_samples_msw << 32) + info.record.samples) * u->frame_size;
216
217 return result;
218 }
219
source_get_latency(struct userdata * u,pa_sample_spec * ss)220 static pa_usec_t source_get_latency(struct userdata *u, pa_sample_spec *ss) {
221 pa_usec_t r = 0;
222 audio_info_t info;
223
224 pa_assert(u);
225 pa_assert(ss);
226
227 if (u->fd) {
228 int err = ioctl(u->fd, AUDIO_GETINFO, &info);
229 pa_assert(err >= 0);
230
231 r = pa_bytes_to_usec(get_recorded_bytes(u), ss) - pa_bytes_to_usec(u->read_bytes, ss);
232 }
233 return r;
234 }
235
build_pollfd(struct userdata * u)236 static void build_pollfd(struct userdata *u) {
237 struct pollfd *pollfd;
238
239 pa_assert(u);
240 pa_assert(!u->rtpoll_item);
241 u->rtpoll_item = pa_rtpoll_item_new(u->rtpoll, PA_RTPOLL_NEVER, 1);
242
243 pollfd = pa_rtpoll_item_get_pollfd(u->rtpoll_item, NULL);
244 pollfd->fd = u->fd;
245 pollfd->events = 0;
246 pollfd->revents = 0;
247 }
248
set_buffer(int fd,int buffer_size)249 static int set_buffer(int fd, int buffer_size) {
250 audio_info_t info;
251
252 pa_assert(fd >= 0);
253
254 AUDIO_INITINFO(&info);
255 info.play.buffer_size = buffer_size;
256 info.record.buffer_size = buffer_size;
257
258 if (ioctl(fd, AUDIO_SETINFO, &info) < 0) {
259 if (errno == EINVAL)
260 pa_log("AUDIO_SETINFO: Unsupported buffer size.");
261 else
262 pa_log("AUDIO_SETINFO: %s", pa_cstrerror(errno));
263 return -1;
264 }
265
266 return 0;
267 }
268
auto_format(int fd,int mode,pa_sample_spec * ss)269 static int auto_format(int fd, int mode, pa_sample_spec *ss) {
270 audio_info_t info;
271
272 pa_assert(fd >= 0);
273 pa_assert(ss);
274
275 AUDIO_INITINFO(&info);
276
277 if (mode != O_RDONLY) {
278 info.play.sample_rate = ss->rate;
279 info.play.channels = ss->channels;
280 switch (ss->format) {
281 case PA_SAMPLE_U8:
282 info.play.precision = 8;
283 info.play.encoding = AUDIO_ENCODING_LINEAR;
284 break;
285 case PA_SAMPLE_ALAW:
286 info.play.precision = 8;
287 info.play.encoding = AUDIO_ENCODING_ALAW;
288 break;
289 case PA_SAMPLE_ULAW:
290 info.play.precision = 8;
291 info.play.encoding = AUDIO_ENCODING_ULAW;
292 break;
293 case PA_SAMPLE_S16NE:
294 info.play.precision = 16;
295 info.play.encoding = AUDIO_ENCODING_LINEAR;
296 break;
297 default:
298 pa_log("AUDIO_SETINFO: Unsupported sample format.");
299 return -1;
300 }
301 }
302
303 if (mode != O_WRONLY) {
304 info.record.sample_rate = ss->rate;
305 info.record.channels = ss->channels;
306 switch (ss->format) {
307 case PA_SAMPLE_U8:
308 info.record.precision = 8;
309 info.record.encoding = AUDIO_ENCODING_LINEAR;
310 break;
311 case PA_SAMPLE_ALAW:
312 info.record.precision = 8;
313 info.record.encoding = AUDIO_ENCODING_ALAW;
314 break;
315 case PA_SAMPLE_ULAW:
316 info.record.precision = 8;
317 info.record.encoding = AUDIO_ENCODING_ULAW;
318 break;
319 case PA_SAMPLE_S16NE:
320 info.record.precision = 16;
321 info.record.encoding = AUDIO_ENCODING_LINEAR;
322 break;
323 default:
324 pa_log("AUDIO_SETINFO: Unsupported sample format.");
325 return -1;
326 }
327 }
328
329 if (ioctl(fd, AUDIO_SETINFO, &info) < 0) {
330 if (errno == EINVAL)
331 pa_log("AUDIO_SETINFO: Failed to set sample format.");
332 else
333 pa_log("AUDIO_SETINFO: %s", pa_cstrerror(errno));
334 return -1;
335 }
336
337 return 0;
338 }
339
open_audio_device(struct userdata * u,pa_sample_spec * ss)340 static int open_audio_device(struct userdata *u, pa_sample_spec *ss) {
341 pa_assert(u);
342 pa_assert(ss);
343
344 if ((u->fd = pa_open_cloexec(u->device_name, u->mode | O_NONBLOCK, 0)) < 0) {
345 pa_log_warn("open %s failed (%s)", u->device_name, pa_cstrerror(errno));
346 return -1;
347 }
348
349 pa_log_info("device opened in %s mode.", u->mode == O_WRONLY ? "O_WRONLY" : (u->mode == O_RDONLY ? "O_RDONLY" : "O_RDWR"));
350
351 if (auto_format(u->fd, u->mode, ss) < 0)
352 return -1;
353
354 if (set_buffer(u->fd, u->buffer_size) < 0)
355 return -1;
356
357 u->written_bytes = u->read_bytes = 0;
358 u->play_samples_msw = u->record_samples_msw = 0;
359 u->prev_playback_samples = u->prev_record_samples = 0;
360
361 return u->fd;
362 }
363
suspend(struct userdata * u)364 static void suspend(struct userdata *u) {
365 pa_assert(u);
366 pa_assert(u->fd >= 0);
367
368 pa_log_info("Suspending...");
369
370 ioctl(u->fd, I_FLUSH, FLUSHRW);
371 pa_close(u->fd);
372 u->fd = -1;
373
374 if (u->rtpoll_item) {
375 pa_rtpoll_item_free(u->rtpoll_item);
376 u->rtpoll_item = NULL;
377 }
378
379 pa_log_info("Device suspended.");
380 }
381
unsuspend(struct userdata * u)382 static int unsuspend(struct userdata *u) {
383 pa_assert(u);
384 pa_assert(u->fd < 0);
385
386 pa_log_info("Resuming...");
387
388 if (open_audio_device(u, u->sink ? &u->sink->sample_spec : &u->source->sample_spec) < 0)
389 return -1;
390
391 build_pollfd(u);
392
393 pa_log_info("Device resumed.");
394
395 return 0;
396 }
397
sink_process_msg(pa_msgobject * o,int code,void * data,int64_t offset,pa_memchunk * chunk)398 static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offset, pa_memchunk *chunk) {
399 struct userdata *u = PA_SINK(o)->userdata;
400
401 switch (code) {
402
403 case PA_SINK_MESSAGE_GET_LATENCY:
404 *((int64_t*) data) = sink_get_latency(u, &PA_SINK(o)->sample_spec);
405 return 0;
406 }
407
408 return pa_sink_process_msg(o, code, data, offset, chunk);
409 }
410
411 /* Called from the IO thread. */
sink_set_state_in_io_thread_cb(pa_sink * s,pa_sink_state_t new_state,pa_suspend_cause_t new_suspend_cause)412 static int sink_set_state_in_io_thread_cb(pa_sink *s, pa_sink_state_t new_state, pa_suspend_cause_t new_suspend_cause) {
413 struct userdata *u;
414
415 pa_assert(s);
416 pa_assert_se(u = s->userdata);
417
418 /* It may be that only the suspend cause is changing, in which case there's
419 * nothing to do. */
420 if (new_state == s->thread_info.state)
421 return 0;
422
423 switch (new_state) {
424
425 case PA_SINK_SUSPENDED:
426
427 pa_assert(PA_SINK_IS_OPENED(s->thread_info.state));
428
429 #ifdef USE_SMOOTHER_2
430 pa_smoother_2_pause(u->smoother, pa_rtclock_now());
431 #else
432 pa_smoother_pause(u->smoother, pa_rtclock_now());
433 #endif
434
435 if (!u->source || u->source_suspended)
436 suspend(u);
437
438 u->sink_suspended = true;
439 break;
440
441 case PA_SINK_IDLE:
442 case PA_SINK_RUNNING:
443
444 if (s->thread_info.state == PA_SINK_SUSPENDED) {
445 #ifdef USE_SMOOTHER_2
446 pa_smoother_2_resume(u->smoother, pa_rtclock_now());
447 #else
448 pa_smoother_resume(u->smoother, pa_rtclock_now(), true);
449 #endif
450
451 if (!u->source || u->source_suspended) {
452 bool mute;
453 if (unsuspend(u) < 0)
454 return -1;
455 s->get_volume(s);
456 if (s->get_mute(s, &mute) >= 0)
457 pa_sink_set_mute(s, mute, false);
458 }
459 u->sink_suspended = false;
460 }
461 break;
462
463 case PA_SINK_INVALID_STATE:
464 case PA_SINK_UNLINKED:
465 case PA_SINK_INIT:
466 ;
467 }
468
469 return 0;
470 }
471
source_process_msg(pa_msgobject * o,int code,void * data,int64_t offset,pa_memchunk * chunk)472 static int source_process_msg(pa_msgobject *o, int code, void *data, int64_t offset, pa_memchunk *chunk) {
473 struct userdata *u = PA_SOURCE(o)->userdata;
474
475 switch (code) {
476
477 case PA_SOURCE_MESSAGE_GET_LATENCY:
478 *((pa_usec_t*) data) = source_get_latency(u, &PA_SOURCE(o)->sample_spec);
479 return 0;
480 }
481
482 return pa_source_process_msg(o, code, data, offset, chunk);
483 }
484
485 /* Called from the IO thread. */
source_set_state_in_io_thread_cb(pa_source * s,pa_source_state_t new_state,pa_suspend_cause_t new_suspend_cause)486 static int source_set_state_in_io_thread_cb(pa_source *s, pa_source_state_t new_state, pa_suspend_cause_t new_suspend_cause) {
487 struct userdata *u;
488
489 pa_assert(s);
490 pa_assert_se(u = s->userdata);
491
492 /* It may be that only the suspend cause is changing, in which case there's
493 * nothing to do. */
494 if (new_state == s->thread_info.state)
495 return 0;
496
497 switch (new_state) {
498
499 case PA_SOURCE_SUSPENDED:
500
501 pa_assert(PA_SOURCE_IS_OPENED(s->thread_info.state));
502
503 if (!u->sink || u->sink_suspended)
504 suspend(u);
505
506 u->source_suspended = true;
507 break;
508
509 case PA_SOURCE_IDLE:
510 case PA_SOURCE_RUNNING:
511
512 if (s->thread_info.state == PA_SOURCE_SUSPENDED) {
513 if (!u->sink || u->sink_suspended) {
514 if (unsuspend(u) < 0)
515 return -1;
516 s->get_volume(s);
517 }
518 u->source_suspended = false;
519 }
520 break;
521
522 case PA_SOURCE_UNLINKED:
523 case PA_SOURCE_INIT:
524 case PA_SOURCE_INVALID_STATE:
525 ;
526
527 }
528
529 return 0;
530 }
531
sink_set_volume(pa_sink * s)532 static void sink_set_volume(pa_sink *s) {
533 struct userdata *u;
534 audio_info_t info;
535
536 pa_assert_se(u = s->userdata);
537
538 if (u->fd >= 0) {
539 AUDIO_INITINFO(&info);
540
541 info.play.gain = pa_cvolume_max(&s->real_volume) * AUDIO_MAX_GAIN / PA_VOLUME_NORM;
542 pa_assert(info.play.gain <= AUDIO_MAX_GAIN);
543
544 if (ioctl(u->fd, AUDIO_SETINFO, &info) < 0) {
545 if (errno == EINVAL)
546 pa_log("AUDIO_SETINFO: Unsupported volume.");
547 else
548 pa_log("AUDIO_SETINFO: %s", pa_cstrerror(errno));
549 }
550 }
551 }
552
sink_get_volume(pa_sink * s)553 static void sink_get_volume(pa_sink *s) {
554 struct userdata *u;
555 audio_info_t info;
556
557 pa_assert_se(u = s->userdata);
558
559 if (u->fd >= 0) {
560 if (ioctl(u->fd, AUDIO_GETINFO, &info) < 0)
561 pa_log("AUDIO_SETINFO: %s", pa_cstrerror(errno));
562 else
563 pa_cvolume_set(&s->real_volume, s->sample_spec.channels, info.play.gain * PA_VOLUME_NORM / AUDIO_MAX_GAIN);
564 }
565 }
566
source_set_volume(pa_source * s)567 static void source_set_volume(pa_source *s) {
568 struct userdata *u;
569 audio_info_t info;
570
571 pa_assert_se(u = s->userdata);
572
573 if (u->fd >= 0) {
574 AUDIO_INITINFO(&info);
575
576 info.play.gain = pa_cvolume_max(&s->real_volume) * AUDIO_MAX_GAIN / PA_VOLUME_NORM;
577 pa_assert(info.play.gain <= AUDIO_MAX_GAIN);
578
579 if (ioctl(u->fd, AUDIO_SETINFO, &info) < 0) {
580 if (errno == EINVAL)
581 pa_log("AUDIO_SETINFO: Unsupported volume.");
582 else
583 pa_log("AUDIO_SETINFO: %s", pa_cstrerror(errno));
584 }
585 }
586 }
587
source_get_volume(pa_source * s)588 static void source_get_volume(pa_source *s) {
589 struct userdata *u;
590 audio_info_t info;
591
592 pa_assert_se(u = s->userdata);
593
594 if (u->fd >= 0) {
595 if (ioctl(u->fd, AUDIO_GETINFO, &info) < 0)
596 pa_log("AUDIO_SETINFO: %s", pa_cstrerror(errno));
597 else
598 pa_cvolume_set(&s->real_volume, s->sample_spec.channels, info.play.gain * PA_VOLUME_NORM / AUDIO_MAX_GAIN);
599 }
600 }
601
sink_set_mute(pa_sink * s)602 static void sink_set_mute(pa_sink *s) {
603 struct userdata *u = s->userdata;
604 audio_info_t info;
605
606 pa_assert(u);
607
608 if (u->fd >= 0) {
609 AUDIO_INITINFO(&info);
610
611 info.output_muted = s->muted;
612
613 if (ioctl(u->fd, AUDIO_SETINFO, &info) < 0)
614 pa_log("AUDIO_SETINFO: %s", pa_cstrerror(errno));
615 }
616 }
617
sink_get_mute(pa_sink * s,bool * mute)618 static int sink_get_mute(pa_sink *s, bool *mute) {
619 struct userdata *u = s->userdata;
620 audio_info_t info;
621
622 pa_assert(u);
623
624 if (u->fd < 0)
625 return -1;
626
627 if (ioctl(u->fd, AUDIO_GETINFO, &info) < 0) {
628 pa_log("AUDIO_GETINFO: %s", pa_cstrerror(errno));
629 return -1;
630 }
631
632 *mute = info.output_muted;
633
634 return 0;
635 }
636
process_rewind(struct userdata * u)637 static void process_rewind(struct userdata *u) {
638 size_t rewind_nbytes;
639
640 pa_assert(u);
641
642 if (!PA_SINK_IS_OPENED(u->sink->thread_info.state)) {
643 pa_sink_process_rewind(u->sink, 0);
644 return;
645 }
646
647 rewind_nbytes = u->sink->thread_info.rewind_nbytes;
648
649 if (rewind_nbytes > 0) {
650 pa_log_debug("Requested to rewind %lu bytes.", (unsigned long) rewind_nbytes);
651 rewind_nbytes = PA_MIN(u->memchunk.length, rewind_nbytes);
652 u->memchunk.length -= rewind_nbytes;
653 if (u->memchunk.length <= 0 && u->memchunk.memblock) {
654 pa_memblock_unref(u->memchunk.memblock);
655 pa_memchunk_reset(&u->memchunk);
656 }
657 pa_log_debug("Rewound %lu bytes.", (unsigned long) rewind_nbytes);
658 }
659
660 pa_sink_process_rewind(u->sink, rewind_nbytes);
661 }
662
thread_func(void * userdata)663 static void thread_func(void *userdata) {
664 struct userdata *u = userdata;
665 unsigned short revents = 0;
666 int ret, err;
667 audio_info_t info;
668
669 pa_assert(u);
670
671 pa_log_debug("Thread starting up");
672
673 if (u->core->realtime_scheduling)
674 pa_thread_make_realtime(u->core->realtime_priority);
675
676 pa_thread_mq_install(&u->thread_mq);
677
678 #ifdef USE_SMOOTHER_2
679 pa_smoother_2_reset(u->smoother, pa_rtclock_now());
680 #else
681 pa_smoother_set_time_offset(u->smoother, pa_rtclock_now());
682 #endif
683
684 for (;;) {
685 /* Render some data and write it to the dsp */
686
687 if (PA_UNLIKELY(u->sink->thread_info.rewind_requested))
688 process_rewind(u);
689
690 if (u->sink && PA_SINK_IS_OPENED(u->sink->thread_info.state)) {
691 pa_usec_t xtime0, ysleep_interval, xsleep_interval;
692 uint64_t buffered_bytes;
693
694 err = ioctl(u->fd, AUDIO_GETINFO, &info);
695 if (err < 0) {
696 pa_log("AUDIO_GETINFO ioctl failed: %s", pa_cstrerror(errno));
697 goto fail;
698 }
699
700 if (info.play.error) {
701 pa_log_debug("buffer under-run!");
702
703 AUDIO_INITINFO(&info);
704 info.play.error = 0;
705 if (ioctl(u->fd, AUDIO_SETINFO, &info) < 0)
706 pa_log("AUDIO_SETINFO: %s", pa_cstrerror(errno));
707
708 #ifdef USE_SMOOTHER_2
709 pa_smoother_2_reset(u->smoother, pa_rtclock_now());
710 #else
711 pa_smoother_reset(u->smoother, pa_rtclock_now(), true);
712 #endif
713 }
714
715 for (;;) {
716 void *p;
717 ssize_t w;
718 size_t len;
719 int write_type = 1;
720
721 /*
722 * Since we cannot modify the size of the output buffer we fake it
723 * by not filling it more than u->buffer_size.
724 */
725 xtime0 = pa_rtclock_now();
726 buffered_bytes = get_playback_buffered_bytes(u);
727 if (buffered_bytes >= (uint64_t)u->buffer_size)
728 break;
729
730 len = u->buffer_size - buffered_bytes;
731 len -= len % u->frame_size;
732
733 if (len < (size_t) u->minimum_request)
734 break;
735
736 if (!u->memchunk.length)
737 pa_sink_render(u->sink, u->sink->thread_info.max_request, &u->memchunk);
738
739 len = PA_MIN(u->memchunk.length, len);
740
741 p = pa_memblock_acquire(u->memchunk.memblock);
742 w = pa_write(u->fd, (uint8_t*) p + u->memchunk.index, len, &write_type);
743 pa_memblock_release(u->memchunk.memblock);
744
745 if (w <= 0) {
746 if (errno == EAGAIN) {
747 /* We may have realtime priority so yield the CPU to ensure that fd can become writable again. */
748 pa_log_debug("EAGAIN with %llu bytes buffered.", buffered_bytes);
749 break;
750 } else {
751 pa_log("Failed to write data to DSP: %s", pa_cstrerror(errno));
752 goto fail;
753 }
754 } else {
755 pa_assert(w % u->frame_size == 0);
756
757 u->written_bytes += w;
758 u->memchunk.index += w;
759 u->memchunk.length -= w;
760 if (u->memchunk.length <= 0) {
761 pa_memblock_unref(u->memchunk.memblock);
762 pa_memchunk_reset(&u->memchunk);
763 }
764 }
765 }
766
767 ysleep_interval = pa_bytes_to_usec(buffered_bytes / 2, &u->sink->sample_spec);
768 #ifdef USE_SMOOTHER_2
769 xsleep_interval = pa_smoother_2_translate(u->smoother, ysleep_interval);
770 #else
771 xsleep_interval = pa_smoother_translate(u->smoother, xtime0, ysleep_interval);
772 #endif
773 pa_rtpoll_set_timer_absolute(u->rtpoll, xtime0 + PA_MIN(xsleep_interval, ysleep_interval));
774 } else
775 pa_rtpoll_set_timer_disabled(u->rtpoll);
776
777 /* Try to read some data and pass it on to the source driver */
778
779 if (u->source && PA_SOURCE_IS_OPENED(u->source->thread_info.state) && (revents & POLLIN)) {
780 pa_memchunk memchunk;
781 void *p;
782 ssize_t r;
783 size_t len;
784
785 err = ioctl(u->fd, AUDIO_GETINFO, &info);
786 pa_assert(err >= 0);
787
788 if (info.record.error) {
789 pa_log_debug("buffer overflow!");
790
791 AUDIO_INITINFO(&info);
792 info.record.error = 0;
793 if (ioctl(u->fd, AUDIO_SETINFO, &info) < 0)
794 pa_log("AUDIO_SETINFO: %s", pa_cstrerror(errno));
795 }
796
797 err = ioctl(u->fd, I_NREAD, &len);
798 pa_assert(err >= 0);
799
800 if (len > 0) {
801 memchunk.memblock = pa_memblock_new(u->core->mempool, len);
802 pa_assert(memchunk.memblock);
803
804 p = pa_memblock_acquire(memchunk.memblock);
805 r = pa_read(u->fd, p, len, NULL);
806 pa_memblock_release(memchunk.memblock);
807
808 if (r < 0) {
809 pa_memblock_unref(memchunk.memblock);
810 if (errno == EAGAIN)
811 break;
812 else {
813 pa_log("Failed to read data from DSP: %s", pa_cstrerror(errno));
814 goto fail;
815 }
816 } else {
817 u->read_bytes += r;
818
819 memchunk.index = 0;
820 memchunk.length = r;
821
822 pa_source_post(u->source, &memchunk);
823 pa_memblock_unref(memchunk.memblock);
824
825 revents &= ~POLLIN;
826 }
827 }
828 }
829
830 if (u->rtpoll_item) {
831 struct pollfd *pollfd;
832
833 pa_assert(u->fd >= 0);
834
835 pollfd = pa_rtpoll_item_get_pollfd(u->rtpoll_item, NULL);
836 pollfd->events = (u->source && PA_SOURCE_IS_OPENED(u->source->thread_info.state)) ? POLLIN : 0;
837 }
838
839 /* Hmm, nothing to do. Let's sleep */
840 if ((ret = pa_rtpoll_run(u->rtpoll)) < 0)
841 goto fail;
842
843 if (ret == 0)
844 goto finish;
845
846 if (u->rtpoll_item) {
847 struct pollfd *pollfd;
848
849 pollfd = pa_rtpoll_item_get_pollfd(u->rtpoll_item, NULL);
850
851 if (pollfd->revents & ~(POLLOUT|POLLIN)) {
852 pa_log("DSP shutdown.");
853 goto fail;
854 }
855
856 revents = pollfd->revents;
857 } else
858 revents = 0;
859 }
860
861 fail:
862 /* We have to continue processing messages until we receive the
863 * SHUTDOWN message */
864 pa_asyncmsgq_post(u->thread_mq.outq, PA_MSGOBJECT(u->core), PA_CORE_MESSAGE_UNLOAD_MODULE, u->module, 0, NULL, NULL);
865 pa_asyncmsgq_wait_for(u->thread_mq.inq, PA_MESSAGE_SHUTDOWN);
866
867 finish:
868 pa_log_debug("Thread shutting down");
869 }
870
sig_callback(pa_mainloop_api * api,pa_signal_event * e,int sig,void * userdata)871 static void sig_callback(pa_mainloop_api *api, pa_signal_event*e, int sig, void *userdata) {
872 struct userdata *u = userdata;
873
874 pa_assert(u);
875
876 pa_log_debug("caught signal");
877
878 if (u->sink) {
879 pa_sink_get_volume(u->sink, true);
880 pa_sink_get_mute(u->sink, true);
881 }
882
883 if (u->source)
884 pa_source_get_volume(u->source, true);
885 }
886
pa__init(pa_module * m)887 int pa__init(pa_module *m) {
888 struct userdata *u = NULL;
889 bool record = true, playback = true;
890 pa_sample_spec ss;
891 pa_channel_map map;
892 pa_modargs *ma = NULL;
893 uint32_t buffer_length_msec;
894 int fd = -1;
895 pa_sink_new_data sink_new_data;
896 pa_source_new_data source_new_data;
897 char const *name;
898 char *name_buf;
899 bool namereg_fail;
900
901 pa_assert(m);
902
903 if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
904 pa_log("failed to parse module arguments.");
905 goto fail;
906 }
907
908 if (pa_modargs_get_value_boolean(ma, "record", &record) < 0 || pa_modargs_get_value_boolean(ma, "playback", &playback) < 0) {
909 pa_log("record= and playback= expect a boolean argument.");
910 goto fail;
911 }
912
913 if (!playback && !record) {
914 pa_log("neither playback nor record enabled for device.");
915 goto fail;
916 }
917
918 u = pa_xnew0(struct userdata, 1);
919
920 #ifndef USE_SMOOTHER_2
921 if (!(u->smoother = pa_smoother_new(PA_USEC_PER_SEC, PA_USEC_PER_SEC * 2, true, true, 10, pa_rtclock_now(), true)))
922 goto fail;
923 #endif
924
925 /*
926 * For a process (or several processes) to use the same audio device for both
927 * record and playback at the same time, the device's mixer must be enabled.
928 * See mixerctl(1). It may be turned off for playback only or record only.
929 */
930 u->mode = (playback && record) ? O_RDWR : (playback ? O_WRONLY : (record ? O_RDONLY : 0));
931
932 ss = m->core->default_sample_spec;
933 if (pa_modargs_get_sample_spec_and_channel_map(ma, &ss, &map, PA_CHANNEL_MAP_DEFAULT) < 0) {
934 pa_log("failed to parse sample specification");
935 goto fail;
936 }
937 u->frame_size = pa_frame_size(&ss);
938
939 #ifdef USE_SMOOTHER_2
940 u->smoother = pa_smoother_2_new(5*PA_USEC_PER_SEC, pa_rtclock_now(), u->frame_size, ss.rate);
941 #endif
942
943 u->minimum_request = pa_usec_to_bytes(PA_USEC_PER_SEC / MAX_RENDER_HZ, &ss);
944
945 buffer_length_msec = 100;
946 if (pa_modargs_get_value_u32(ma, "buffer_length", &buffer_length_msec) < 0) {
947 pa_log("failed to parse buffer_length argument");
948 goto fail;
949 }
950 u->buffer_size = pa_usec_to_bytes(1000 * buffer_length_msec, &ss);
951 if (u->buffer_size < 2 * u->minimum_request) {
952 pa_log("buffer_length argument cannot be smaller than %u",
953 (unsigned)(pa_bytes_to_usec(2 * u->minimum_request, &ss) / 1000));
954 goto fail;
955 }
956 if (u->buffer_size > MAX_BUFFER_SIZE) {
957 pa_log("buffer_length argument cannot be greater than %u",
958 (unsigned)(pa_bytes_to_usec(MAX_BUFFER_SIZE, &ss) / 1000));
959 goto fail;
960 }
961
962 u->device_name = pa_xstrdup(pa_modargs_get_value(ma, "device", DEFAULT_DEVICE));
963
964 if ((fd = open_audio_device(u, &ss)) < 0)
965 goto fail;
966
967 u->core = m->core;
968 u->module = m;
969 m->userdata = u;
970
971 pa_memchunk_reset(&u->memchunk);
972
973 u->rtpoll = pa_rtpoll_new();
974
975 if (pa_thread_mq_init(&u->thread_mq, m->core->mainloop, u->rtpoll) < 0) {
976 pa_log("pa_thread_mq_init() failed.");
977 goto fail;
978 }
979
980 u->rtpoll_item = NULL;
981 build_pollfd(u);
982
983 if (u->mode != O_WRONLY) {
984 name_buf = NULL;
985 namereg_fail = true;
986
987 if (!(name = pa_modargs_get_value(ma, "source_name", NULL))) {
988 name = name_buf = pa_sprintf_malloc("solaris_input.%s", pa_path_get_filename(u->device_name));
989 namereg_fail = false;
990 }
991
992 pa_source_new_data_init(&source_new_data);
993 source_new_data.driver = __FILE__;
994 source_new_data.module = m;
995 pa_source_new_data_set_name(&source_new_data, name);
996 source_new_data.namereg_fail = namereg_fail;
997 pa_source_new_data_set_sample_spec(&source_new_data, &ss);
998 pa_source_new_data_set_channel_map(&source_new_data, &map);
999 pa_proplist_sets(source_new_data.proplist, PA_PROP_DEVICE_STRING, u->device_name);
1000 pa_proplist_sets(source_new_data.proplist, PA_PROP_DEVICE_API, "solaris");
1001 pa_proplist_sets(source_new_data.proplist, PA_PROP_DEVICE_DESCRIPTION, "Solaris PCM source");
1002 pa_proplist_sets(source_new_data.proplist, PA_PROP_DEVICE_ACCESS_MODE, "serial");
1003 pa_proplist_setf(source_new_data.proplist, PA_PROP_DEVICE_BUFFERING_BUFFER_SIZE, "%lu", (unsigned long) u->buffer_size);
1004
1005 if (pa_modargs_get_proplist(ma, "source_properties", source_new_data.proplist, PA_UPDATE_REPLACE) < 0) {
1006 pa_log("Invalid properties");
1007 pa_source_new_data_done(&source_new_data);
1008 goto fail;
1009 }
1010
1011 u->source = pa_source_new(m->core, &source_new_data, PA_SOURCE_HARDWARE|PA_SOURCE_LATENCY);
1012 pa_source_new_data_done(&source_new_data);
1013 pa_xfree(name_buf);
1014
1015 if (!u->source) {
1016 pa_log("Failed to create source object");
1017 goto fail;
1018 }
1019
1020 u->source->userdata = u;
1021 u->source->parent.process_msg = source_process_msg;
1022 u->source->set_state_in_io_thread = source_set_state_in_io_thread_cb;
1023
1024 pa_source_set_asyncmsgq(u->source, u->thread_mq.inq);
1025 pa_source_set_rtpoll(u->source, u->rtpoll);
1026 pa_source_set_fixed_latency(u->source, pa_bytes_to_usec(u->buffer_size, &u->source->sample_spec));
1027
1028 pa_source_set_get_volume_callback(u->source, source_get_volume);
1029 pa_source_set_set_volume_callback(u->source, source_set_volume);
1030 u->source->refresh_volume = true;
1031 } else
1032 u->source = NULL;
1033
1034 if (u->mode != O_RDONLY) {
1035 name_buf = NULL;
1036 namereg_fail = true;
1037 if (!(name = pa_modargs_get_value(ma, "sink_name", NULL))) {
1038 name = name_buf = pa_sprintf_malloc("solaris_output.%s", pa_path_get_filename(u->device_name));
1039 namereg_fail = false;
1040 }
1041
1042 pa_sink_new_data_init(&sink_new_data);
1043 sink_new_data.driver = __FILE__;
1044 sink_new_data.module = m;
1045 pa_sink_new_data_set_name(&sink_new_data, name);
1046 sink_new_data.namereg_fail = namereg_fail;
1047 pa_sink_new_data_set_sample_spec(&sink_new_data, &ss);
1048 pa_sink_new_data_set_channel_map(&sink_new_data, &map);
1049 pa_proplist_sets(sink_new_data.proplist, PA_PROP_DEVICE_STRING, u->device_name);
1050 pa_proplist_sets(sink_new_data.proplist, PA_PROP_DEVICE_API, "solaris");
1051 pa_proplist_sets(sink_new_data.proplist, PA_PROP_DEVICE_DESCRIPTION, "Solaris PCM sink");
1052 pa_proplist_sets(sink_new_data.proplist, PA_PROP_DEVICE_ACCESS_MODE, "serial");
1053
1054 if (pa_modargs_get_proplist(ma, "sink_properties", sink_new_data.proplist, PA_UPDATE_REPLACE) < 0) {
1055 pa_log("Invalid properties");
1056 pa_sink_new_data_done(&sink_new_data);
1057 goto fail;
1058 }
1059
1060 u->sink = pa_sink_new(m->core, &sink_new_data, PA_SINK_HARDWARE|PA_SINK_LATENCY);
1061 pa_sink_new_data_done(&sink_new_data);
1062
1063 pa_assert(u->sink);
1064 u->sink->userdata = u;
1065 u->sink->parent.process_msg = sink_process_msg;
1066 u->sink->set_state_in_io_thread = sink_set_state_in_io_thread_cb;
1067
1068 pa_sink_set_asyncmsgq(u->sink, u->thread_mq.inq);
1069 pa_sink_set_rtpoll(u->sink, u->rtpoll);
1070 pa_sink_set_fixed_latency(u->sink, pa_bytes_to_usec(u->buffer_size, &u->sink->sample_spec));
1071 pa_sink_set_max_request(u->sink, u->buffer_size);
1072 pa_sink_set_max_rewind(u->sink, u->buffer_size);
1073
1074 pa_sink_set_get_volume_callback(u->sink, sink_get_volume);
1075 pa_sink_set_set_volume_callback(u->sink, sink_set_volume);
1076 pa_sink_set_get_mute_callback(u->sink, sink_get_mute);
1077 pa_sink_set_set_mute_callback(u->sink, sink_set_mute);
1078 u->sink->refresh_volume = u->sink->refresh_muted = true;
1079 } else
1080 u->sink = NULL;
1081
1082 pa_assert(u->source || u->sink);
1083
1084 u->sig = pa_signal_new(SIGPOLL, sig_callback, u);
1085 if (u->sig)
1086 ioctl(u->fd, I_SETSIG, S_MSG);
1087 else
1088 pa_log_warn("Could not register SIGPOLL handler");
1089
1090 if (!(u->thread = pa_thread_new("solaris", thread_func, u))) {
1091 pa_log("Failed to create thread.");
1092 goto fail;
1093 }
1094
1095 /* Read mixer settings */
1096 if (u->sink) {
1097 if (sink_new_data.volume_is_set)
1098 u->sink->set_volume(u->sink);
1099 else
1100 u->sink->get_volume(u->sink);
1101
1102 if (sink_new_data.muted_is_set)
1103 u->sink->set_mute(u->sink);
1104 else {
1105 bool mute;
1106
1107 if (u->sink->get_mute(u->sink, &mute) >= 0)
1108 pa_sink_set_mute(u->sink, mute, false);
1109 }
1110
1111 pa_sink_put(u->sink);
1112 }
1113
1114 if (u->source) {
1115 if (source_new_data.volume_is_set)
1116 u->source->set_volume(u->source);
1117 else
1118 u->source->get_volume(u->source);
1119
1120 pa_source_put(u->source);
1121 }
1122
1123 pa_modargs_free(ma);
1124
1125 return 0;
1126
1127 fail:
1128 if (u)
1129 pa__done(m);
1130 else if (fd >= 0)
1131 close(fd);
1132
1133 if (ma)
1134 pa_modargs_free(ma);
1135
1136 return -1;
1137 }
1138
pa__done(pa_module * m)1139 void pa__done(pa_module *m) {
1140 struct userdata *u;
1141
1142 pa_assert(m);
1143
1144 if (!(u = m->userdata))
1145 return;
1146
1147 if (u->sig) {
1148 ioctl(u->fd, I_SETSIG, 0);
1149 pa_signal_free(u->sig);
1150 }
1151
1152 if (u->sink)
1153 pa_sink_unlink(u->sink);
1154
1155 if (u->source)
1156 pa_source_unlink(u->source);
1157
1158 if (u->thread) {
1159 pa_asyncmsgq_send(u->thread_mq.inq, NULL, PA_MESSAGE_SHUTDOWN, NULL, 0, NULL);
1160 pa_thread_free(u->thread);
1161 }
1162
1163 pa_thread_mq_done(&u->thread_mq);
1164
1165 if (u->sink)
1166 pa_sink_unref(u->sink);
1167
1168 if (u->source)
1169 pa_source_unref(u->source);
1170
1171 if (u->memchunk.memblock)
1172 pa_memblock_unref(u->memchunk.memblock);
1173
1174 if (u->rtpoll_item)
1175 pa_rtpoll_item_free(u->rtpoll_item);
1176
1177 if (u->rtpoll)
1178 pa_rtpoll_free(u->rtpoll);
1179
1180 if (u->fd >= 0)
1181 close(u->fd);
1182
1183 if (u->smoother)
1184 #ifdef USE_SMOOTHER_2
1185 pa_smoother_2_free(u->smoother);
1186 #else
1187 pa_smoother_free(u->smoother);
1188 #endif
1189
1190 pa_xfree(u->device_name);
1191
1192 pa_xfree(u);
1193 }
1194