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