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