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