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