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