• 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 #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