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
70PA_MODULE_AUTHOR("Pierre Ossman");
71PA_MODULE_DESCRIPTION("Solaris Sink/Source");
72PA_MODULE_VERSION(PACKAGE_VERSION);
73PA_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>");
86PA_MODULE_LOAD_ONCE(false);
87
88struct 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
125static 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
149static 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
188static 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
202static 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
220static 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
236static 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
249static 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
269static 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
340static 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
364static 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
382static 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
398static 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. */
412static 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
472static 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. */
486static 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
532static 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
553static 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
567static 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
588static 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
602static 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
618static 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
637static 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
663static 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
861fail:
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
867finish:
868    pa_log_debug("Thread shutting down");
869}
870
871static 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
887int 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
1127fail:
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
1139void 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