• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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