1 /* 2 * QEMU ALSA audio driver 3 * 4 * Copyright (c) 2005 Vassili Karpov (malc) 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a copy 7 * of this software and associated documentation files (the "Software"), to deal 8 * in the Software without restriction, including without limitation the rights 9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 * copies of the Software, and to permit persons to whom the Software is 11 * furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included in 14 * all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 * THE SOFTWARE. 23 */ 24 #include <alsa/asoundlib.h> 25 #include "qemu-common.h" 26 #include "qemu/main-loop.h" 27 #include "audio.h" 28 29 #if QEMU_GNUC_PREREQ(4, 3) 30 #pragma GCC diagnostic ignored "-Waddress" 31 #endif 32 33 #define AUDIO_CAP "alsa" 34 #include "audio_int.h" 35 36 struct pollhlp { 37 snd_pcm_t *handle; 38 struct pollfd *pfds; 39 int count; 40 int mask; 41 }; 42 43 typedef struct ALSAVoiceOut { 44 HWVoiceOut hw; 45 int wpos; 46 int pending; 47 void *pcm_buf; 48 snd_pcm_t *handle; 49 struct pollhlp pollhlp; 50 } ALSAVoiceOut; 51 52 typedef struct ALSAVoiceIn { 53 HWVoiceIn hw; 54 snd_pcm_t *handle; 55 void *pcm_buf; 56 struct pollhlp pollhlp; 57 } ALSAVoiceIn; 58 59 static struct { 60 int size_in_usec_in; 61 int size_in_usec_out; 62 const char *pcm_name_in; 63 const char *pcm_name_out; 64 unsigned int buffer_size_in; 65 unsigned int period_size_in; 66 unsigned int buffer_size_out; 67 unsigned int period_size_out; 68 unsigned int threshold; 69 70 int buffer_size_in_overridden; 71 int period_size_in_overridden; 72 73 int buffer_size_out_overridden; 74 int period_size_out_overridden; 75 int verbose; 76 } conf = { 77 .buffer_size_out = 4096, 78 .period_size_out = 1024, 79 .pcm_name_out = "default", 80 .pcm_name_in = "default", 81 }; 82 83 struct alsa_params_req { 84 int freq; 85 snd_pcm_format_t fmt; 86 int nchannels; 87 int size_in_usec; 88 int override_mask; 89 unsigned int buffer_size; 90 unsigned int period_size; 91 }; 92 93 struct alsa_params_obt { 94 int freq; 95 audfmt_e fmt; 96 int endianness; 97 int nchannels; 98 snd_pcm_uframes_t samples; 99 }; 100 101 static void GCC_FMT_ATTR (2, 3) alsa_logerr (int err, const char *fmt, ...) 102 { 103 va_list ap; 104 105 va_start (ap, fmt); 106 AUD_vlog (AUDIO_CAP, fmt, ap); 107 va_end (ap); 108 109 AUD_log (AUDIO_CAP, "Reason: %s\n", snd_strerror (err)); 110 } 111 112 static void GCC_FMT_ATTR (3, 4) alsa_logerr2 ( 113 int err, 114 const char *typ, 115 const char *fmt, 116 ... 117 ) 118 { 119 va_list ap; 120 121 AUD_log (AUDIO_CAP, "Could not initialize %s\n", typ); 122 123 va_start (ap, fmt); 124 AUD_vlog (AUDIO_CAP, fmt, ap); 125 va_end (ap); 126 127 AUD_log (AUDIO_CAP, "Reason: %s\n", snd_strerror (err)); 128 } 129 130 static void alsa_fini_poll (struct pollhlp *hlp) 131 { 132 int i; 133 struct pollfd *pfds = hlp->pfds; 134 135 if (pfds) { 136 for (i = 0; i < hlp->count; ++i) { 137 qemu_set_fd_handler (pfds[i].fd, NULL, NULL, NULL); 138 } 139 g_free (pfds); 140 } 141 hlp->pfds = NULL; 142 hlp->count = 0; 143 hlp->handle = NULL; 144 } 145 146 static void alsa_anal_close1 (snd_pcm_t **handlep) 147 { 148 int err = snd_pcm_close (*handlep); 149 if (err) { 150 alsa_logerr (err, "Failed to close PCM handle %p\n", *handlep); 151 } 152 *handlep = NULL; 153 } 154 155 static void alsa_anal_close (snd_pcm_t **handlep, struct pollhlp *hlp) 156 { 157 alsa_fini_poll (hlp); 158 alsa_anal_close1 (handlep); 159 } 160 161 static int alsa_recover (snd_pcm_t *handle) 162 { 163 int err = snd_pcm_prepare (handle); 164 if (err < 0) { 165 alsa_logerr (err, "Failed to prepare handle %p\n", handle); 166 return -1; 167 } 168 return 0; 169 } 170 171 static int alsa_resume (snd_pcm_t *handle) 172 { 173 int err = snd_pcm_resume (handle); 174 if (err < 0) { 175 alsa_logerr (err, "Failed to resume handle %p\n", handle); 176 return -1; 177 } 178 return 0; 179 } 180 181 static void alsa_poll_handler (void *opaque) 182 { 183 int err, count; 184 snd_pcm_state_t state; 185 struct pollhlp *hlp = opaque; 186 unsigned short revents; 187 188 count = poll (hlp->pfds, hlp->count, 0); 189 if (count < 0) { 190 dolog ("alsa_poll_handler: poll %s\n", strerror (errno)); 191 return; 192 } 193 194 if (!count) { 195 return; 196 } 197 198 /* XXX: ALSA example uses initial count, not the one returned by 199 poll, correct? */ 200 err = snd_pcm_poll_descriptors_revents (hlp->handle, hlp->pfds, 201 hlp->count, &revents); 202 if (err < 0) { 203 alsa_logerr (err, "snd_pcm_poll_descriptors_revents"); 204 return; 205 } 206 207 if (!(revents & hlp->mask)) { 208 if (conf.verbose) { 209 dolog ("revents = %d\n", revents); 210 } 211 return; 212 } 213 214 state = snd_pcm_state (hlp->handle); 215 switch (state) { 216 case SND_PCM_STATE_SETUP: 217 alsa_recover (hlp->handle); 218 break; 219 220 case SND_PCM_STATE_XRUN: 221 alsa_recover (hlp->handle); 222 break; 223 224 case SND_PCM_STATE_SUSPENDED: 225 alsa_resume (hlp->handle); 226 break; 227 228 case SND_PCM_STATE_PREPARED: 229 audio_run ("alsa run (prepared)"); 230 break; 231 232 case SND_PCM_STATE_RUNNING: 233 audio_run ("alsa run (running)"); 234 break; 235 236 default: 237 dolog ("Unexpected state %d\n", state); 238 } 239 } 240 241 static int alsa_poll_helper (snd_pcm_t *handle, struct pollhlp *hlp, int mask) 242 { 243 int i, count, err; 244 struct pollfd *pfds; 245 246 count = snd_pcm_poll_descriptors_count (handle); 247 if (count <= 0) { 248 dolog ("Could not initialize poll mode\n" 249 "Invalid number of poll descriptors %d\n", count); 250 return -1; 251 } 252 253 pfds = audio_calloc ("alsa_poll_helper", count, sizeof (*pfds)); 254 if (!pfds) { 255 dolog ("Could not initialize poll mode\n"); 256 return -1; 257 } 258 259 err = snd_pcm_poll_descriptors (handle, pfds, count); 260 if (err < 0) { 261 alsa_logerr (err, "Could not initialize poll mode\n" 262 "Could not obtain poll descriptors\n"); 263 g_free (pfds); 264 return -1; 265 } 266 267 for (i = 0; i < count; ++i) { 268 if (pfds[i].events & POLLIN) { 269 err = qemu_set_fd_handler (pfds[i].fd, alsa_poll_handler, 270 NULL, hlp); 271 } 272 if (pfds[i].events & POLLOUT) { 273 if (conf.verbose) { 274 dolog ("POLLOUT %d %d\n", i, pfds[i].fd); 275 } 276 err = qemu_set_fd_handler (pfds[i].fd, NULL, 277 alsa_poll_handler, hlp); 278 } 279 if (conf.verbose) { 280 dolog ("Set handler events=%#x index=%d fd=%d err=%d\n", 281 pfds[i].events, i, pfds[i].fd, err); 282 } 283 284 if (err) { 285 dolog ("Failed to set handler events=%#x index=%d fd=%d err=%d\n", 286 pfds[i].events, i, pfds[i].fd, err); 287 288 while (i--) { 289 qemu_set_fd_handler (pfds[i].fd, NULL, NULL, NULL); 290 } 291 g_free (pfds); 292 return -1; 293 } 294 } 295 hlp->pfds = pfds; 296 hlp->count = count; 297 hlp->handle = handle; 298 hlp->mask = mask; 299 return 0; 300 } 301 302 static int alsa_poll_out (HWVoiceOut *hw) 303 { 304 ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw; 305 306 return alsa_poll_helper (alsa->handle, &alsa->pollhlp, POLLOUT); 307 } 308 309 static int alsa_poll_in (HWVoiceIn *hw) 310 { 311 ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw; 312 313 return alsa_poll_helper (alsa->handle, &alsa->pollhlp, POLLIN); 314 } 315 316 static int alsa_write (SWVoiceOut *sw, void *buf, int len) 317 { 318 return audio_pcm_sw_write (sw, buf, len); 319 } 320 321 static snd_pcm_format_t aud_to_alsafmt (audfmt_e fmt, int endianness) 322 { 323 switch (fmt) { 324 case AUD_FMT_S8: 325 return SND_PCM_FORMAT_S8; 326 327 case AUD_FMT_U8: 328 return SND_PCM_FORMAT_U8; 329 330 case AUD_FMT_S16: 331 if (endianness) { 332 return SND_PCM_FORMAT_S16_BE; 333 } 334 else { 335 return SND_PCM_FORMAT_S16_LE; 336 } 337 338 case AUD_FMT_U16: 339 if (endianness) { 340 return SND_PCM_FORMAT_U16_BE; 341 } 342 else { 343 return SND_PCM_FORMAT_U16_LE; 344 } 345 346 case AUD_FMT_S32: 347 if (endianness) { 348 return SND_PCM_FORMAT_S32_BE; 349 } 350 else { 351 return SND_PCM_FORMAT_S32_LE; 352 } 353 354 case AUD_FMT_U32: 355 if (endianness) { 356 return SND_PCM_FORMAT_U32_BE; 357 } 358 else { 359 return SND_PCM_FORMAT_U32_LE; 360 } 361 362 default: 363 dolog ("Internal logic error: Bad audio format %d\n", fmt); 364 #ifdef DEBUG_AUDIO 365 abort (); 366 #endif 367 return SND_PCM_FORMAT_U8; 368 } 369 } 370 371 static int alsa_to_audfmt (snd_pcm_format_t alsafmt, audfmt_e *fmt, 372 int *endianness) 373 { 374 switch (alsafmt) { 375 case SND_PCM_FORMAT_S8: 376 *endianness = 0; 377 *fmt = AUD_FMT_S8; 378 break; 379 380 case SND_PCM_FORMAT_U8: 381 *endianness = 0; 382 *fmt = AUD_FMT_U8; 383 break; 384 385 case SND_PCM_FORMAT_S16_LE: 386 *endianness = 0; 387 *fmt = AUD_FMT_S16; 388 break; 389 390 case SND_PCM_FORMAT_U16_LE: 391 *endianness = 0; 392 *fmt = AUD_FMT_U16; 393 break; 394 395 case SND_PCM_FORMAT_S16_BE: 396 *endianness = 1; 397 *fmt = AUD_FMT_S16; 398 break; 399 400 case SND_PCM_FORMAT_U16_BE: 401 *endianness = 1; 402 *fmt = AUD_FMT_U16; 403 break; 404 405 case SND_PCM_FORMAT_S32_LE: 406 *endianness = 0; 407 *fmt = AUD_FMT_S32; 408 break; 409 410 case SND_PCM_FORMAT_U32_LE: 411 *endianness = 0; 412 *fmt = AUD_FMT_U32; 413 break; 414 415 case SND_PCM_FORMAT_S32_BE: 416 *endianness = 1; 417 *fmt = AUD_FMT_S32; 418 break; 419 420 case SND_PCM_FORMAT_U32_BE: 421 *endianness = 1; 422 *fmt = AUD_FMT_U32; 423 break; 424 425 default: 426 dolog ("Unrecognized audio format %d\n", alsafmt); 427 return -1; 428 } 429 430 return 0; 431 } 432 433 static void alsa_dump_info (struct alsa_params_req *req, 434 struct alsa_params_obt *obt, 435 snd_pcm_format_t obtfmt) 436 { 437 dolog ("parameter | requested value | obtained value\n"); 438 dolog ("format | %10d | %10d\n", req->fmt, obtfmt); 439 dolog ("channels | %10d | %10d\n", 440 req->nchannels, obt->nchannels); 441 dolog ("frequency | %10d | %10d\n", req->freq, obt->freq); 442 dolog ("============================================\n"); 443 dolog ("requested: buffer size %d period size %d\n", 444 req->buffer_size, req->period_size); 445 dolog ("obtained: samples %ld\n", obt->samples); 446 } 447 448 static void alsa_set_threshold (snd_pcm_t *handle, snd_pcm_uframes_t threshold) 449 { 450 int err; 451 snd_pcm_sw_params_t *sw_params; 452 453 snd_pcm_sw_params_alloca (&sw_params); 454 455 err = snd_pcm_sw_params_current (handle, sw_params); 456 if (err < 0) { 457 dolog ("Could not fully initialize DAC\n"); 458 alsa_logerr (err, "Failed to get current software parameters\n"); 459 return; 460 } 461 462 err = snd_pcm_sw_params_set_start_threshold (handle, sw_params, threshold); 463 if (err < 0) { 464 dolog ("Could not fully initialize DAC\n"); 465 alsa_logerr (err, "Failed to set software threshold to %ld\n", 466 threshold); 467 return; 468 } 469 470 err = snd_pcm_sw_params (handle, sw_params); 471 if (err < 0) { 472 dolog ("Could not fully initialize DAC\n"); 473 alsa_logerr (err, "Failed to set software parameters\n"); 474 return; 475 } 476 } 477 478 static int alsa_open (int in, struct alsa_params_req *req, 479 struct alsa_params_obt *obt, snd_pcm_t **handlep) 480 { 481 snd_pcm_t *handle; 482 snd_pcm_hw_params_t *hw_params; 483 int err; 484 int size_in_usec; 485 unsigned int freq, nchannels; 486 const char *pcm_name = in ? conf.pcm_name_in : conf.pcm_name_out; 487 snd_pcm_uframes_t obt_buffer_size; 488 const char *typ = in ? "ADC" : "DAC"; 489 snd_pcm_format_t obtfmt; 490 491 freq = req->freq; 492 nchannels = req->nchannels; 493 size_in_usec = req->size_in_usec; 494 495 snd_pcm_hw_params_alloca (&hw_params); 496 497 err = snd_pcm_open ( 498 &handle, 499 pcm_name, 500 in ? SND_PCM_STREAM_CAPTURE : SND_PCM_STREAM_PLAYBACK, 501 SND_PCM_NONBLOCK 502 ); 503 if (err < 0) { 504 alsa_logerr2 (err, typ, "Failed to open `%s':\n", pcm_name); 505 return -1; 506 } 507 508 err = snd_pcm_hw_params_any (handle, hw_params); 509 if (err < 0) { 510 alsa_logerr2 (err, typ, "Failed to initialize hardware parameters\n"); 511 goto err; 512 } 513 514 err = snd_pcm_hw_params_set_access ( 515 handle, 516 hw_params, 517 SND_PCM_ACCESS_RW_INTERLEAVED 518 ); 519 if (err < 0) { 520 alsa_logerr2 (err, typ, "Failed to set access type\n"); 521 goto err; 522 } 523 524 err = snd_pcm_hw_params_set_format (handle, hw_params, req->fmt); 525 if (err < 0 && conf.verbose) { 526 alsa_logerr2 (err, typ, "Failed to set format %d\n", req->fmt); 527 } 528 529 err = snd_pcm_hw_params_set_rate_near (handle, hw_params, &freq, 0); 530 if (err < 0) { 531 alsa_logerr2 (err, typ, "Failed to set frequency %d\n", req->freq); 532 goto err; 533 } 534 535 err = snd_pcm_hw_params_set_channels_near ( 536 handle, 537 hw_params, 538 &nchannels 539 ); 540 if (err < 0) { 541 alsa_logerr2 (err, typ, "Failed to set number of channels %d\n", 542 req->nchannels); 543 goto err; 544 } 545 546 if (nchannels != 1 && nchannels != 2) { 547 alsa_logerr2 (err, typ, 548 "Can not handle obtained number of channels %d\n", 549 nchannels); 550 goto err; 551 } 552 553 if (req->buffer_size) { 554 unsigned long obt; 555 556 if (size_in_usec) { 557 int dir = 0; 558 unsigned int btime = req->buffer_size; 559 560 err = snd_pcm_hw_params_set_buffer_time_near ( 561 handle, 562 hw_params, 563 &btime, 564 &dir 565 ); 566 obt = btime; 567 } 568 else { 569 snd_pcm_uframes_t bsize = req->buffer_size; 570 571 err = snd_pcm_hw_params_set_buffer_size_near ( 572 handle, 573 hw_params, 574 &bsize 575 ); 576 obt = bsize; 577 } 578 if (err < 0) { 579 alsa_logerr2 (err, typ, "Failed to set buffer %s to %d\n", 580 size_in_usec ? "time" : "size", req->buffer_size); 581 goto err; 582 } 583 584 if ((req->override_mask & 2) && (obt - req->buffer_size)) 585 dolog ("Requested buffer %s %u was rejected, using %lu\n", 586 size_in_usec ? "time" : "size", req->buffer_size, obt); 587 } 588 589 if (req->period_size) { 590 unsigned long obt; 591 592 if (size_in_usec) { 593 int dir = 0; 594 unsigned int ptime = req->period_size; 595 596 err = snd_pcm_hw_params_set_period_time_near ( 597 handle, 598 hw_params, 599 &ptime, 600 &dir 601 ); 602 obt = ptime; 603 } 604 else { 605 int dir = 0; 606 snd_pcm_uframes_t psize = req->period_size; 607 608 err = snd_pcm_hw_params_set_period_size_near ( 609 handle, 610 hw_params, 611 &psize, 612 &dir 613 ); 614 obt = psize; 615 } 616 617 if (err < 0) { 618 alsa_logerr2 (err, typ, "Failed to set period %s to %d\n", 619 size_in_usec ? "time" : "size", req->period_size); 620 goto err; 621 } 622 623 if (((req->override_mask & 1) && (obt - req->period_size))) 624 dolog ("Requested period %s %u was rejected, using %lu\n", 625 size_in_usec ? "time" : "size", req->period_size, obt); 626 } 627 628 err = snd_pcm_hw_params (handle, hw_params); 629 if (err < 0) { 630 alsa_logerr2 (err, typ, "Failed to apply audio parameters\n"); 631 goto err; 632 } 633 634 err = snd_pcm_hw_params_get_buffer_size (hw_params, &obt_buffer_size); 635 if (err < 0) { 636 alsa_logerr2 (err, typ, "Failed to get buffer size\n"); 637 goto err; 638 } 639 640 err = snd_pcm_hw_params_get_format (hw_params, &obtfmt); 641 if (err < 0) { 642 alsa_logerr2 (err, typ, "Failed to get format\n"); 643 goto err; 644 } 645 646 if (alsa_to_audfmt (obtfmt, &obt->fmt, &obt->endianness)) { 647 dolog ("Invalid format was returned %d\n", obtfmt); 648 goto err; 649 } 650 651 err = snd_pcm_prepare (handle); 652 if (err < 0) { 653 alsa_logerr2 (err, typ, "Could not prepare handle %p\n", handle); 654 goto err; 655 } 656 657 if (!in && conf.threshold) { 658 snd_pcm_uframes_t threshold; 659 int bytes_per_sec; 660 661 bytes_per_sec = freq << (nchannels == 2); 662 663 switch (obt->fmt) { 664 case AUD_FMT_S8: 665 case AUD_FMT_U8: 666 break; 667 668 case AUD_FMT_S16: 669 case AUD_FMT_U16: 670 bytes_per_sec <<= 1; 671 break; 672 673 case AUD_FMT_S32: 674 case AUD_FMT_U32: 675 bytes_per_sec <<= 2; 676 break; 677 } 678 679 threshold = (conf.threshold * bytes_per_sec) / 1000; 680 alsa_set_threshold (handle, threshold); 681 } 682 683 obt->nchannels = nchannels; 684 obt->freq = freq; 685 obt->samples = obt_buffer_size; 686 687 *handlep = handle; 688 689 if (conf.verbose && 690 (obtfmt != req->fmt || 691 obt->nchannels != req->nchannels || 692 obt->freq != req->freq)) { 693 dolog ("Audio parameters for %s\n", typ); 694 alsa_dump_info (req, obt, obtfmt); 695 } 696 697 #ifdef DEBUG 698 alsa_dump_info (req, obt, obtfmt); 699 #endif 700 return 0; 701 702 err: 703 alsa_anal_close1 (&handle); 704 return -1; 705 } 706 707 static snd_pcm_sframes_t alsa_get_avail (snd_pcm_t *handle) 708 { 709 snd_pcm_sframes_t avail; 710 711 avail = snd_pcm_avail_update (handle); 712 if (avail < 0) { 713 if (avail == -EPIPE) { 714 if (!alsa_recover (handle)) { 715 avail = snd_pcm_avail_update (handle); 716 } 717 } 718 719 if (avail < 0) { 720 alsa_logerr (avail, 721 "Could not obtain number of available frames\n"); 722 return -1; 723 } 724 } 725 726 return avail; 727 } 728 729 static void alsa_write_pending (ALSAVoiceOut *alsa) 730 { 731 HWVoiceOut *hw = &alsa->hw; 732 733 while (alsa->pending) { 734 int left_till_end_samples = hw->samples - alsa->wpos; 735 int len = audio_MIN (alsa->pending, left_till_end_samples); 736 char *src = advance (alsa->pcm_buf, alsa->wpos << hw->info.shift); 737 738 while (len) { 739 snd_pcm_sframes_t written; 740 741 written = snd_pcm_writei (alsa->handle, src, len); 742 743 if (written <= 0) { 744 switch (written) { 745 case 0: 746 if (conf.verbose) { 747 dolog ("Failed to write %d frames (wrote zero)\n", len); 748 } 749 return; 750 751 case -EPIPE: 752 if (alsa_recover (alsa->handle)) { 753 alsa_logerr (written, "Failed to write %d frames\n", 754 len); 755 return; 756 } 757 if (conf.verbose) { 758 dolog ("Recovering from playback xrun\n"); 759 } 760 continue; 761 762 case -ESTRPIPE: 763 /* stream is suspended and waiting for an 764 application recovery */ 765 if (alsa_resume (alsa->handle)) { 766 alsa_logerr (written, "Failed to write %d frames\n", 767 len); 768 return; 769 } 770 if (conf.verbose) { 771 dolog ("Resuming suspended output stream\n"); 772 } 773 continue; 774 775 case -EAGAIN: 776 return; 777 778 default: 779 alsa_logerr (written, "Failed to write %d frames from %p\n", 780 len, src); 781 return; 782 } 783 } 784 785 alsa->wpos = (alsa->wpos + written) % hw->samples; 786 alsa->pending -= written; 787 len -= written; 788 } 789 } 790 } 791 792 static int alsa_run_out (HWVoiceOut *hw, int live) 793 { 794 ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw; 795 int decr; 796 snd_pcm_sframes_t avail; 797 798 avail = alsa_get_avail (alsa->handle); 799 if (avail < 0) { 800 dolog ("Could not get number of available playback frames\n"); 801 return 0; 802 } 803 804 decr = audio_MIN (live, avail); 805 decr = audio_pcm_hw_clip_out (hw, alsa->pcm_buf, decr, alsa->pending); 806 alsa->pending += decr; 807 alsa_write_pending (alsa); 808 return decr; 809 } 810 811 static void alsa_fini_out (HWVoiceOut *hw) 812 { 813 ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw; 814 815 ldebug ("alsa_fini\n"); 816 alsa_anal_close (&alsa->handle, &alsa->pollhlp); 817 818 g_free(alsa->pcm_buf); 819 alsa->pcm_buf = NULL; 820 } 821 822 static int alsa_init_out (HWVoiceOut *hw, struct audsettings *as) 823 { 824 ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw; 825 struct alsa_params_req req; 826 struct alsa_params_obt obt; 827 snd_pcm_t *handle; 828 struct audsettings obt_as; 829 830 req.fmt = aud_to_alsafmt (as->fmt, as->endianness); 831 req.freq = as->freq; 832 req.nchannels = as->nchannels; 833 req.period_size = conf.period_size_out; 834 req.buffer_size = conf.buffer_size_out; 835 req.size_in_usec = conf.size_in_usec_out; 836 req.override_mask = 837 (conf.period_size_out_overridden ? 1 : 0) | 838 (conf.buffer_size_out_overridden ? 2 : 0); 839 840 if (alsa_open (0, &req, &obt, &handle)) { 841 return -1; 842 } 843 844 obt_as.freq = obt.freq; 845 obt_as.nchannels = obt.nchannels; 846 obt_as.fmt = obt.fmt; 847 obt_as.endianness = obt.endianness; 848 849 audio_pcm_init_info (&hw->info, &obt_as); 850 hw->samples = obt.samples; 851 852 alsa->pcm_buf = audio_calloc (AUDIO_FUNC, obt.samples, 1 << hw->info.shift); 853 if (!alsa->pcm_buf) { 854 dolog ("Could not allocate DAC buffer (%d samples, each %d bytes)\n", 855 hw->samples, 1 << hw->info.shift); 856 alsa_anal_close1 (&handle); 857 return -1; 858 } 859 860 alsa->handle = handle; 861 return 0; 862 } 863 864 #define VOICE_CTL_PAUSE 0 865 #define VOICE_CTL_PREPARE 1 866 #define VOICE_CTL_START 2 867 868 static int alsa_voice_ctl (snd_pcm_t *handle, const char *typ, int ctl) 869 { 870 int err; 871 872 if (ctl == VOICE_CTL_PAUSE) { 873 err = snd_pcm_drop (handle); 874 if (err < 0) { 875 alsa_logerr (err, "Could not stop %s\n", typ); 876 return -1; 877 } 878 } 879 else { 880 err = snd_pcm_prepare (handle); 881 if (err < 0) { 882 alsa_logerr (err, "Could not prepare handle for %s\n", typ); 883 return -1; 884 } 885 if (ctl == VOICE_CTL_START) { 886 err = snd_pcm_start(handle); 887 if (err < 0) { 888 alsa_logerr (err, "Could not start handle for %s\n", typ); 889 return -1; 890 } 891 } 892 } 893 894 return 0; 895 } 896 897 static int alsa_ctl_out (HWVoiceOut *hw, int cmd, ...) 898 { 899 ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw; 900 901 switch (cmd) { 902 case VOICE_ENABLE: 903 { 904 va_list ap; 905 int poll_mode; 906 907 va_start (ap, cmd); 908 poll_mode = va_arg (ap, int); 909 va_end (ap); 910 911 ldebug ("enabling voice\n"); 912 if (poll_mode && alsa_poll_out (hw)) { 913 poll_mode = 0; 914 } 915 hw->poll_mode = poll_mode; 916 return alsa_voice_ctl (alsa->handle, "playback", VOICE_CTL_PREPARE); 917 } 918 919 case VOICE_DISABLE: 920 ldebug ("disabling voice\n"); 921 if (hw->poll_mode) { 922 hw->poll_mode = 0; 923 alsa_fini_poll (&alsa->pollhlp); 924 } 925 return alsa_voice_ctl (alsa->handle, "playback", VOICE_CTL_PAUSE); 926 } 927 928 return -1; 929 } 930 931 static int alsa_init_in (HWVoiceIn *hw, struct audsettings *as) 932 { 933 ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw; 934 struct alsa_params_req req; 935 struct alsa_params_obt obt; 936 snd_pcm_t *handle; 937 struct audsettings obt_as; 938 939 req.fmt = aud_to_alsafmt (as->fmt, as->endianness); 940 req.freq = as->freq; 941 req.nchannels = as->nchannels; 942 req.period_size = conf.period_size_in; 943 req.buffer_size = conf.buffer_size_in; 944 req.size_in_usec = conf.size_in_usec_in; 945 req.override_mask = 946 (conf.period_size_in_overridden ? 1 : 0) | 947 (conf.buffer_size_in_overridden ? 2 : 0); 948 949 if (alsa_open (1, &req, &obt, &handle)) { 950 return -1; 951 } 952 953 obt_as.freq = obt.freq; 954 obt_as.nchannels = obt.nchannels; 955 obt_as.fmt = obt.fmt; 956 obt_as.endianness = obt.endianness; 957 958 audio_pcm_init_info (&hw->info, &obt_as); 959 hw->samples = obt.samples; 960 961 alsa->pcm_buf = audio_calloc (AUDIO_FUNC, hw->samples, 1 << hw->info.shift); 962 if (!alsa->pcm_buf) { 963 dolog ("Could not allocate ADC buffer (%d samples, each %d bytes)\n", 964 hw->samples, 1 << hw->info.shift); 965 alsa_anal_close1 (&handle); 966 return -1; 967 } 968 969 alsa->handle = handle; 970 return 0; 971 } 972 973 static void alsa_fini_in (HWVoiceIn *hw) 974 { 975 ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw; 976 977 alsa_anal_close (&alsa->handle, &alsa->pollhlp); 978 979 g_free(alsa->pcm_buf); 980 alsa->pcm_buf = NULL; 981 } 982 983 static int alsa_run_in (HWVoiceIn *hw) 984 { 985 ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw; 986 int hwshift = hw->info.shift; 987 int i; 988 int live = audio_pcm_hw_get_live_in (hw); 989 int dead = hw->samples - live; 990 int decr; 991 struct { 992 int add; 993 int len; 994 } bufs[2] = { 995 { .add = hw->wpos, .len = 0 }, 996 { .add = 0, .len = 0 } 997 }; 998 snd_pcm_sframes_t avail; 999 snd_pcm_uframes_t read_samples = 0; 1000 1001 if (!dead) { 1002 return 0; 1003 } 1004 1005 avail = alsa_get_avail (alsa->handle); 1006 if (avail < 0) { 1007 dolog ("Could not get number of captured frames\n"); 1008 return 0; 1009 } 1010 1011 if (!avail) { 1012 snd_pcm_state_t state; 1013 1014 state = snd_pcm_state (alsa->handle); 1015 switch (state) { 1016 case SND_PCM_STATE_PREPARED: 1017 avail = hw->samples; 1018 break; 1019 case SND_PCM_STATE_SUSPENDED: 1020 /* stream is suspended and waiting for an application recovery */ 1021 if (alsa_resume (alsa->handle)) { 1022 dolog ("Failed to resume suspended input stream\n"); 1023 return 0; 1024 } 1025 if (conf.verbose) { 1026 dolog ("Resuming suspended input stream\n"); 1027 } 1028 break; 1029 default: 1030 if (conf.verbose) { 1031 dolog ("No frames available and ALSA state is %d\n", state); 1032 } 1033 return 0; 1034 } 1035 } 1036 1037 decr = audio_MIN (dead, avail); 1038 if (!decr) { 1039 return 0; 1040 } 1041 1042 if (hw->wpos + decr > hw->samples) { 1043 bufs[0].len = (hw->samples - hw->wpos); 1044 bufs[1].len = (decr - (hw->samples - hw->wpos)); 1045 } 1046 else { 1047 bufs[0].len = decr; 1048 } 1049 1050 for (i = 0; i < 2; ++i) { 1051 void *src; 1052 struct st_sample *dst; 1053 snd_pcm_sframes_t nread; 1054 snd_pcm_uframes_t len; 1055 1056 len = bufs[i].len; 1057 1058 src = advance (alsa->pcm_buf, bufs[i].add << hwshift); 1059 dst = hw->conv_buf + bufs[i].add; 1060 1061 while (len) { 1062 nread = snd_pcm_readi (alsa->handle, src, len); 1063 1064 if (nread <= 0) { 1065 switch (nread) { 1066 case 0: 1067 if (conf.verbose) { 1068 dolog ("Failed to read %ld frames (read zero)\n", len); 1069 } 1070 goto exit; 1071 1072 case -EPIPE: 1073 if (alsa_recover (alsa->handle)) { 1074 alsa_logerr (nread, "Failed to read %ld frames\n", len); 1075 goto exit; 1076 } 1077 if (conf.verbose) { 1078 dolog ("Recovering from capture xrun\n"); 1079 } 1080 continue; 1081 1082 case -EAGAIN: 1083 goto exit; 1084 1085 default: 1086 alsa_logerr ( 1087 nread, 1088 "Failed to read %ld frames from %p\n", 1089 len, 1090 src 1091 ); 1092 goto exit; 1093 } 1094 } 1095 1096 hw->conv (dst, src, nread); 1097 1098 src = advance (src, nread << hwshift); 1099 dst += nread; 1100 1101 read_samples += nread; 1102 len -= nread; 1103 } 1104 } 1105 1106 exit: 1107 hw->wpos = (hw->wpos + read_samples) % hw->samples; 1108 return read_samples; 1109 } 1110 1111 static int alsa_read (SWVoiceIn *sw, void *buf, int size) 1112 { 1113 return audio_pcm_sw_read (sw, buf, size); 1114 } 1115 1116 static int alsa_ctl_in (HWVoiceIn *hw, int cmd, ...) 1117 { 1118 ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw; 1119 1120 switch (cmd) { 1121 case VOICE_ENABLE: 1122 { 1123 va_list ap; 1124 int poll_mode; 1125 1126 va_start (ap, cmd); 1127 poll_mode = va_arg (ap, int); 1128 va_end (ap); 1129 1130 ldebug ("enabling voice\n"); 1131 if (poll_mode && alsa_poll_in (hw)) { 1132 poll_mode = 0; 1133 } 1134 hw->poll_mode = poll_mode; 1135 1136 return alsa_voice_ctl (alsa->handle, "capture", VOICE_CTL_START); 1137 } 1138 1139 case VOICE_DISABLE: 1140 ldebug ("disabling voice\n"); 1141 if (hw->poll_mode) { 1142 hw->poll_mode = 0; 1143 alsa_fini_poll (&alsa->pollhlp); 1144 } 1145 return alsa_voice_ctl (alsa->handle, "capture", VOICE_CTL_PAUSE); 1146 } 1147 1148 return -1; 1149 } 1150 1151 static void *alsa_audio_init (void) 1152 { 1153 return &conf; 1154 } 1155 1156 static void alsa_audio_fini (void *opaque) 1157 { 1158 (void) opaque; 1159 } 1160 1161 static struct audio_option alsa_options[] = { 1162 { 1163 .name = "DAC_SIZE_IN_USEC", 1164 .tag = AUD_OPT_BOOL, 1165 .valp = &conf.size_in_usec_out, 1166 .descr = "DAC period/buffer size in microseconds (otherwise in frames)" 1167 }, 1168 { 1169 .name = "DAC_PERIOD_SIZE", 1170 .tag = AUD_OPT_INT, 1171 .valp = &conf.period_size_out, 1172 .descr = "DAC period size (0 to go with system default)", 1173 .overriddenp = &conf.period_size_out_overridden 1174 }, 1175 { 1176 .name = "DAC_BUFFER_SIZE", 1177 .tag = AUD_OPT_INT, 1178 .valp = &conf.buffer_size_out, 1179 .descr = "DAC buffer size (0 to go with system default)", 1180 .overriddenp = &conf.buffer_size_out_overridden 1181 }, 1182 { 1183 .name = "ADC_SIZE_IN_USEC", 1184 .tag = AUD_OPT_BOOL, 1185 .valp = &conf.size_in_usec_in, 1186 .descr = 1187 "ADC period/buffer size in microseconds (otherwise in frames)" 1188 }, 1189 { 1190 .name = "ADC_PERIOD_SIZE", 1191 .tag = AUD_OPT_INT, 1192 .valp = &conf.period_size_in, 1193 .descr = "ADC period size (0 to go with system default)", 1194 .overriddenp = &conf.period_size_in_overridden 1195 }, 1196 { 1197 .name = "ADC_BUFFER_SIZE", 1198 .tag = AUD_OPT_INT, 1199 .valp = &conf.buffer_size_in, 1200 .descr = "ADC buffer size (0 to go with system default)", 1201 .overriddenp = &conf.buffer_size_in_overridden 1202 }, 1203 { 1204 .name = "THRESHOLD", 1205 .tag = AUD_OPT_INT, 1206 .valp = &conf.threshold, 1207 .descr = "(undocumented)" 1208 }, 1209 { 1210 .name = "DAC_DEV", 1211 .tag = AUD_OPT_STR, 1212 .valp = &conf.pcm_name_out, 1213 .descr = "DAC device name (for instance dmix)" 1214 }, 1215 { 1216 .name = "ADC_DEV", 1217 .tag = AUD_OPT_STR, 1218 .valp = &conf.pcm_name_in, 1219 .descr = "ADC device name" 1220 }, 1221 { 1222 .name = "VERBOSE", 1223 .tag = AUD_OPT_BOOL, 1224 .valp = &conf.verbose, 1225 .descr = "Behave in a more verbose way" 1226 }, 1227 { /* End of list */ } 1228 }; 1229 1230 static struct audio_pcm_ops alsa_pcm_ops = { 1231 .init_out = alsa_init_out, 1232 .fini_out = alsa_fini_out, 1233 .run_out = alsa_run_out, 1234 .write = alsa_write, 1235 .ctl_out = alsa_ctl_out, 1236 1237 .init_in = alsa_init_in, 1238 .fini_in = alsa_fini_in, 1239 .run_in = alsa_run_in, 1240 .read = alsa_read, 1241 .ctl_in = alsa_ctl_in, 1242 }; 1243 1244 struct audio_driver alsa_audio_driver = { 1245 .name = "alsa", 1246 .descr = "ALSA http://www.alsa-project.org", 1247 .options = alsa_options, 1248 .init = alsa_audio_init, 1249 .fini = alsa_audio_fini, 1250 .pcm_ops = &alsa_pcm_ops, 1251 .can_be_default = 1, 1252 .max_voices_out = INT_MAX, 1253 .max_voices_in = INT_MAX, 1254 .voice_size_out = sizeof (ALSAVoiceOut), 1255 .voice_size_in = sizeof (ALSAVoiceIn) 1256 }; 1257