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