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 if (alsa->pcm_buf) { 819 g_free (alsa->pcm_buf); 820 alsa->pcm_buf = NULL; 821 } 822 } 823 824 static int alsa_init_out (HWVoiceOut *hw, struct audsettings *as) 825 { 826 ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw; 827 struct alsa_params_req req; 828 struct alsa_params_obt obt; 829 snd_pcm_t *handle; 830 struct audsettings obt_as; 831 832 req.fmt = aud_to_alsafmt (as->fmt, as->endianness); 833 req.freq = as->freq; 834 req.nchannels = as->nchannels; 835 req.period_size = conf.period_size_out; 836 req.buffer_size = conf.buffer_size_out; 837 req.size_in_usec = conf.size_in_usec_out; 838 req.override_mask = 839 (conf.period_size_out_overridden ? 1 : 0) | 840 (conf.buffer_size_out_overridden ? 2 : 0); 841 842 if (alsa_open (0, &req, &obt, &handle)) { 843 return -1; 844 } 845 846 obt_as.freq = obt.freq; 847 obt_as.nchannels = obt.nchannels; 848 obt_as.fmt = obt.fmt; 849 obt_as.endianness = obt.endianness; 850 851 audio_pcm_init_info (&hw->info, &obt_as); 852 hw->samples = obt.samples; 853 854 alsa->pcm_buf = audio_calloc (AUDIO_FUNC, obt.samples, 1 << hw->info.shift); 855 if (!alsa->pcm_buf) { 856 dolog ("Could not allocate DAC buffer (%d samples, each %d bytes)\n", 857 hw->samples, 1 << hw->info.shift); 858 alsa_anal_close1 (&handle); 859 return -1; 860 } 861 862 alsa->handle = handle; 863 return 0; 864 } 865 866 #define VOICE_CTL_PAUSE 0 867 #define VOICE_CTL_PREPARE 1 868 #define VOICE_CTL_START 2 869 870 static int alsa_voice_ctl (snd_pcm_t *handle, const char *typ, int ctl) 871 { 872 int err; 873 874 if (ctl == VOICE_CTL_PAUSE) { 875 err = snd_pcm_drop (handle); 876 if (err < 0) { 877 alsa_logerr (err, "Could not stop %s\n", typ); 878 return -1; 879 } 880 } 881 else { 882 err = snd_pcm_prepare (handle); 883 if (err < 0) { 884 alsa_logerr (err, "Could not prepare handle for %s\n", typ); 885 return -1; 886 } 887 if (ctl == VOICE_CTL_START) { 888 err = snd_pcm_start(handle); 889 if (err < 0) { 890 alsa_logerr (err, "Could not start handle for %s\n", typ); 891 return -1; 892 } 893 } 894 } 895 896 return 0; 897 } 898 899 static int alsa_ctl_out (HWVoiceOut *hw, int cmd, ...) 900 { 901 ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw; 902 903 switch (cmd) { 904 case VOICE_ENABLE: 905 { 906 va_list ap; 907 int poll_mode; 908 909 va_start (ap, cmd); 910 poll_mode = va_arg (ap, int); 911 va_end (ap); 912 913 ldebug ("enabling voice\n"); 914 if (poll_mode && alsa_poll_out (hw)) { 915 poll_mode = 0; 916 } 917 hw->poll_mode = poll_mode; 918 return alsa_voice_ctl (alsa->handle, "playback", VOICE_CTL_PREPARE); 919 } 920 921 case VOICE_DISABLE: 922 ldebug ("disabling voice\n"); 923 if (hw->poll_mode) { 924 hw->poll_mode = 0; 925 alsa_fini_poll (&alsa->pollhlp); 926 } 927 return alsa_voice_ctl (alsa->handle, "playback", VOICE_CTL_PAUSE); 928 } 929 930 return -1; 931 } 932 933 static int alsa_init_in (HWVoiceIn *hw, struct audsettings *as) 934 { 935 ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw; 936 struct alsa_params_req req; 937 struct alsa_params_obt obt; 938 snd_pcm_t *handle; 939 struct audsettings obt_as; 940 941 req.fmt = aud_to_alsafmt (as->fmt, as->endianness); 942 req.freq = as->freq; 943 req.nchannels = as->nchannels; 944 req.period_size = conf.period_size_in; 945 req.buffer_size = conf.buffer_size_in; 946 req.size_in_usec = conf.size_in_usec_in; 947 req.override_mask = 948 (conf.period_size_in_overridden ? 1 : 0) | 949 (conf.buffer_size_in_overridden ? 2 : 0); 950 951 if (alsa_open (1, &req, &obt, &handle)) { 952 return -1; 953 } 954 955 obt_as.freq = obt.freq; 956 obt_as.nchannels = obt.nchannels; 957 obt_as.fmt = obt.fmt; 958 obt_as.endianness = obt.endianness; 959 960 audio_pcm_init_info (&hw->info, &obt_as); 961 hw->samples = obt.samples; 962 963 alsa->pcm_buf = audio_calloc (AUDIO_FUNC, hw->samples, 1 << hw->info.shift); 964 if (!alsa->pcm_buf) { 965 dolog ("Could not allocate ADC buffer (%d samples, each %d bytes)\n", 966 hw->samples, 1 << hw->info.shift); 967 alsa_anal_close1 (&handle); 968 return -1; 969 } 970 971 alsa->handle = handle; 972 return 0; 973 } 974 975 static void alsa_fini_in (HWVoiceIn *hw) 976 { 977 ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw; 978 979 alsa_anal_close (&alsa->handle, &alsa->pollhlp); 980 981 if (alsa->pcm_buf) { 982 g_free (alsa->pcm_buf); 983 alsa->pcm_buf = NULL; 984 } 985 } 986 987 static int alsa_run_in (HWVoiceIn *hw) 988 { 989 ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw; 990 int hwshift = hw->info.shift; 991 int i; 992 int live = audio_pcm_hw_get_live_in (hw); 993 int dead = hw->samples - live; 994 int decr; 995 struct { 996 int add; 997 int len; 998 } bufs[2] = { 999 { .add = hw->wpos, .len = 0 }, 1000 { .add = 0, .len = 0 } 1001 }; 1002 snd_pcm_sframes_t avail; 1003 snd_pcm_uframes_t read_samples = 0; 1004 1005 if (!dead) { 1006 return 0; 1007 } 1008 1009 avail = alsa_get_avail (alsa->handle); 1010 if (avail < 0) { 1011 dolog ("Could not get number of captured frames\n"); 1012 return 0; 1013 } 1014 1015 if (!avail) { 1016 snd_pcm_state_t state; 1017 1018 state = snd_pcm_state (alsa->handle); 1019 switch (state) { 1020 case SND_PCM_STATE_PREPARED: 1021 avail = hw->samples; 1022 break; 1023 case SND_PCM_STATE_SUSPENDED: 1024 /* stream is suspended and waiting for an application recovery */ 1025 if (alsa_resume (alsa->handle)) { 1026 dolog ("Failed to resume suspended input stream\n"); 1027 return 0; 1028 } 1029 if (conf.verbose) { 1030 dolog ("Resuming suspended input stream\n"); 1031 } 1032 break; 1033 default: 1034 if (conf.verbose) { 1035 dolog ("No frames available and ALSA state is %d\n", state); 1036 } 1037 return 0; 1038 } 1039 } 1040 1041 decr = audio_MIN (dead, avail); 1042 if (!decr) { 1043 return 0; 1044 } 1045 1046 if (hw->wpos + decr > hw->samples) { 1047 bufs[0].len = (hw->samples - hw->wpos); 1048 bufs[1].len = (decr - (hw->samples - hw->wpos)); 1049 } 1050 else { 1051 bufs[0].len = decr; 1052 } 1053 1054 for (i = 0; i < 2; ++i) { 1055 void *src; 1056 struct st_sample *dst; 1057 snd_pcm_sframes_t nread; 1058 snd_pcm_uframes_t len; 1059 1060 len = bufs[i].len; 1061 1062 src = advance (alsa->pcm_buf, bufs[i].add << hwshift); 1063 dst = hw->conv_buf + bufs[i].add; 1064 1065 while (len) { 1066 nread = snd_pcm_readi (alsa->handle, src, len); 1067 1068 if (nread <= 0) { 1069 switch (nread) { 1070 case 0: 1071 if (conf.verbose) { 1072 dolog ("Failed to read %ld frames (read zero)\n", len); 1073 } 1074 goto exit; 1075 1076 case -EPIPE: 1077 if (alsa_recover (alsa->handle)) { 1078 alsa_logerr (nread, "Failed to read %ld frames\n", len); 1079 goto exit; 1080 } 1081 if (conf.verbose) { 1082 dolog ("Recovering from capture xrun\n"); 1083 } 1084 continue; 1085 1086 case -EAGAIN: 1087 goto exit; 1088 1089 default: 1090 alsa_logerr ( 1091 nread, 1092 "Failed to read %ld frames from %p\n", 1093 len, 1094 src 1095 ); 1096 goto exit; 1097 } 1098 } 1099 1100 hw->conv (dst, src, nread); 1101 1102 src = advance (src, nread << hwshift); 1103 dst += nread; 1104 1105 read_samples += nread; 1106 len -= nread; 1107 } 1108 } 1109 1110 exit: 1111 hw->wpos = (hw->wpos + read_samples) % hw->samples; 1112 return read_samples; 1113 } 1114 1115 static int alsa_read (SWVoiceIn *sw, void *buf, int size) 1116 { 1117 return audio_pcm_sw_read (sw, buf, size); 1118 } 1119 1120 static int alsa_ctl_in (HWVoiceIn *hw, int cmd, ...) 1121 { 1122 ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw; 1123 1124 switch (cmd) { 1125 case VOICE_ENABLE: 1126 { 1127 va_list ap; 1128 int poll_mode; 1129 1130 va_start (ap, cmd); 1131 poll_mode = va_arg (ap, int); 1132 va_end (ap); 1133 1134 ldebug ("enabling voice\n"); 1135 if (poll_mode && alsa_poll_in (hw)) { 1136 poll_mode = 0; 1137 } 1138 hw->poll_mode = poll_mode; 1139 1140 return alsa_voice_ctl (alsa->handle, "capture", VOICE_CTL_START); 1141 } 1142 1143 case VOICE_DISABLE: 1144 ldebug ("disabling voice\n"); 1145 if (hw->poll_mode) { 1146 hw->poll_mode = 0; 1147 alsa_fini_poll (&alsa->pollhlp); 1148 } 1149 return alsa_voice_ctl (alsa->handle, "capture", VOICE_CTL_PAUSE); 1150 } 1151 1152 return -1; 1153 } 1154 1155 static void *alsa_audio_init (void) 1156 { 1157 return &conf; 1158 } 1159 1160 static void alsa_audio_fini (void *opaque) 1161 { 1162 (void) opaque; 1163 } 1164 1165 static struct audio_option alsa_options[] = { 1166 { 1167 .name = "DAC_SIZE_IN_USEC", 1168 .tag = AUD_OPT_BOOL, 1169 .valp = &conf.size_in_usec_out, 1170 .descr = "DAC period/buffer size in microseconds (otherwise in frames)" 1171 }, 1172 { 1173 .name = "DAC_PERIOD_SIZE", 1174 .tag = AUD_OPT_INT, 1175 .valp = &conf.period_size_out, 1176 .descr = "DAC period size (0 to go with system default)", 1177 .overriddenp = &conf.period_size_out_overridden 1178 }, 1179 { 1180 .name = "DAC_BUFFER_SIZE", 1181 .tag = AUD_OPT_INT, 1182 .valp = &conf.buffer_size_out, 1183 .descr = "DAC buffer size (0 to go with system default)", 1184 .overriddenp = &conf.buffer_size_out_overridden 1185 }, 1186 { 1187 .name = "ADC_SIZE_IN_USEC", 1188 .tag = AUD_OPT_BOOL, 1189 .valp = &conf.size_in_usec_in, 1190 .descr = 1191 "ADC period/buffer size in microseconds (otherwise in frames)" 1192 }, 1193 { 1194 .name = "ADC_PERIOD_SIZE", 1195 .tag = AUD_OPT_INT, 1196 .valp = &conf.period_size_in, 1197 .descr = "ADC period size (0 to go with system default)", 1198 .overriddenp = &conf.period_size_in_overridden 1199 }, 1200 { 1201 .name = "ADC_BUFFER_SIZE", 1202 .tag = AUD_OPT_INT, 1203 .valp = &conf.buffer_size_in, 1204 .descr = "ADC buffer size (0 to go with system default)", 1205 .overriddenp = &conf.buffer_size_in_overridden 1206 }, 1207 { 1208 .name = "THRESHOLD", 1209 .tag = AUD_OPT_INT, 1210 .valp = &conf.threshold, 1211 .descr = "(undocumented)" 1212 }, 1213 { 1214 .name = "DAC_DEV", 1215 .tag = AUD_OPT_STR, 1216 .valp = &conf.pcm_name_out, 1217 .descr = "DAC device name (for instance dmix)" 1218 }, 1219 { 1220 .name = "ADC_DEV", 1221 .tag = AUD_OPT_STR, 1222 .valp = &conf.pcm_name_in, 1223 .descr = "ADC device name" 1224 }, 1225 { 1226 .name = "VERBOSE", 1227 .tag = AUD_OPT_BOOL, 1228 .valp = &conf.verbose, 1229 .descr = "Behave in a more verbose way" 1230 }, 1231 { /* End of list */ } 1232 }; 1233 1234 static struct audio_pcm_ops alsa_pcm_ops = { 1235 .init_out = alsa_init_out, 1236 .fini_out = alsa_fini_out, 1237 .run_out = alsa_run_out, 1238 .write = alsa_write, 1239 .ctl_out = alsa_ctl_out, 1240 1241 .init_in = alsa_init_in, 1242 .fini_in = alsa_fini_in, 1243 .run_in = alsa_run_in, 1244 .read = alsa_read, 1245 .ctl_in = alsa_ctl_in, 1246 }; 1247 1248 struct audio_driver alsa_audio_driver = { 1249 .name = "alsa", 1250 .descr = "ALSA http://www.alsa-project.org", 1251 .options = alsa_options, 1252 .init = alsa_audio_init, 1253 .fini = alsa_audio_fini, 1254 .pcm_ops = &alsa_pcm_ops, 1255 .can_be_default = 1, 1256 .max_voices_out = INT_MAX, 1257 .max_voices_in = INT_MAX, 1258 .voice_size_out = sizeof (ALSAVoiceOut), 1259 .voice_size_in = sizeof (ALSAVoiceIn) 1260 }; 1261