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