alsaaudio.c revision 55f4e4a5ec657a017e3bf75299ad71fd1c968dd3
1/* 2 * QEMU ALSA audio driver 3 * 4 * Copyright (c) 2008 The Android Open Source Project 5 * Copyright (c) 2005 Vassili Karpov (malc) 6 * 7 * Permission is hereby granted, free of charge, to any person obtaining a copy 8 * of this software and associated documentation files (the "Software"), to deal 9 * in the Software without restriction, including without limitation the rights 10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 * copies of the Software, and to permit persons to whom the Software is 12 * furnished to do so, subject to the following conditions: 13 * 14 * The above copyright notice and this permission notice shall be included in 15 * all copies or substantial portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 * THE SOFTWARE. 24 */ 25#include <alsa/asoundlib.h> 26#include "vl.h" 27 28#define AUDIO_CAP "alsa" 29#include "audio_int.h" 30#include <dlfcn.h> 31#include <pthread.h> 32#include "android_debug.h" 33 34#define DEBUG 1 35 36#if DEBUG 37# include <stdio.h> 38# define D(...) VERBOSE_PRINT(audio,__VA_ARGS__) 39# define D_ACTIVE VERBOSE_CHECK(audio) 40# define O(...) VERBOSE_PRINT(audioout,__VA_ARGS__) 41# define I(...) VERBOSE_PRINT(audioin,__VA_ARGS__) 42#else 43# define D(...) ((void)0) 44# define D_ACTIVE 0 45# define O(...) ((void)0) 46# define I(...) ((void)0) 47#endif 48 49 50#define STRINGIFY_(x) #x 51#define STRINGIFY(x) STRINGIFY_(x) 52 53#define DYN_SYMBOLS \ 54 DYN_FUNCTION(size_t,snd_pcm_sw_params_sizeof,(void)) \ 55 DYN_FUNCTION(int,snd_pcm_hw_params_current,(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)) \ 56 DYN_FUNCTION(int,snd_pcm_sw_params_set_start_threshold,(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val)) \ 57 DYN_FUNCTION(int,snd_pcm_sw_params,(snd_pcm_t *pcm, snd_pcm_sw_params_t *params)) \ 58 DYN_FUNCTION(int,snd_pcm_sw_params_current,(snd_pcm_t *pcm, snd_pcm_sw_params_t *params)) \ 59 DYN_FUNCTION(size_t,snd_pcm_hw_params_sizeof,(void)) \ 60 DYN_FUNCTION(int,snd_pcm_hw_params_any,(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)) \ 61 DYN_FUNCTION(int,snd_pcm_hw_params_set_access,(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_access_t _access)) \ 62 DYN_FUNCTION(int,snd_pcm_hw_params_set_format,(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_format_t val)) \ 63 DYN_FUNCTION(int,snd_pcm_hw_params_set_rate_near,(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)) \ 64 DYN_FUNCTION(int,snd_pcm_hw_params_set_channels_near,(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val)) \ 65 DYN_FUNCTION(int,snd_pcm_hw_params_set_buffer_time_near,(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)) \ 66 DYN_FUNCTION(int,snd_pcm_hw_params,(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)) \ 67 DYN_FUNCTION(int,snd_pcm_hw_params_get_buffer_size,(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val)) \ 68 DYN_FUNCTION(int,snd_pcm_prepare,(snd_pcm_t *pcm)) \ 69 DYN_FUNCTION(int,snd_pcm_hw_params_get_period_size,(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *frames, int *dir)) \ 70 DYN_FUNCTION(int,snd_pcm_hw_params_get_period_size_min,(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *frames, int *dir)) \ 71 DYN_FUNCTION(int,snd_pcm_hw_params_set_period_size,(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t val, int dir)) \ 72 DYN_FUNCTION(int,snd_pcm_hw_params_get_buffer_size_min,(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val)) \ 73 DYN_FUNCTION(int,snd_pcm_hw_params_set_buffer_size,(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t val)) \ 74 DYN_FUNCTION(int,snd_pcm_hw_params_set_period_time_near,(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)) \ 75 DYN_FUNCTION(snd_pcm_sframes_t,snd_pcm_avail_update,(snd_pcm_t *pcm)) \ 76 DYN_FUNCTION(int,snd_pcm_drop,(snd_pcm_t *pcm)) \ 77 DYN_FUNCTION(snd_pcm_sframes_t,snd_pcm_writei,(snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size)) \ 78 DYN_FUNCTION(snd_pcm_sframes_t,snd_pcm_readi,(snd_pcm_t *pcm, void *buffer, snd_pcm_uframes_t size)) \ 79 DYN_FUNCTION(snd_pcm_state_t,snd_pcm_state,(snd_pcm_t *pcm)) \ 80 DYN_FUNCTION(const char*,snd_strerror,(int errnum)) \ 81 DYN_FUNCTION(int,snd_pcm_open,(snd_pcm_t **pcm, const char *name,snd_pcm_stream_t stream, int mode)) \ 82 DYN_FUNCTION(int,snd_pcm_close,(snd_pcm_t *pcm)) \ 83 84 85 86/* define pointers to library functions we're going to use */ 87#define DYN_FUNCTION(ret,name,sig) \ 88 static ret (*func_ ## name)sig; 89 90DYN_SYMBOLS 91 92#undef DYN_FUNCTION 93 94#define func_snd_pcm_hw_params_alloca(ptr) \ 95 do { assert(ptr); *ptr = (snd_pcm_hw_params_t *) alloca(func_snd_pcm_hw_params_sizeof()); memset(*ptr, 0, func_snd_pcm_hw_params_sizeof()); } while (0) 96 97#define func_snd_pcm_sw_params_alloca(ptr) \ 98 do { assert(ptr); *ptr = (snd_pcm_sw_params_t *) alloca(func_snd_pcm_sw_params_sizeof()); memset(*ptr, 0, func_snd_pcm_sw_params_sizeof()); } while (0) 99 100static void* alsa_lib; 101 102typedef struct ALSAVoiceOut { 103 HWVoiceOut hw; 104 void *pcm_buf; 105 snd_pcm_t *handle; 106} ALSAVoiceOut; 107 108typedef struct ALSAVoiceIn { 109 HWVoiceIn hw; 110 snd_pcm_t *handle; 111 void *pcm_buf; 112} ALSAVoiceIn; 113 114static struct { 115 int size_in_usec_in; 116 int size_in_usec_out; 117 const char *pcm_name_in; 118 const char *pcm_name_out; 119 unsigned int buffer_size_in; 120 unsigned int period_size_in; 121 unsigned int buffer_size_out; 122 unsigned int period_size_out; 123 unsigned int threshold; 124 125 int buffer_size_in_overriden; 126 int period_size_in_overriden; 127 128 int buffer_size_out_overriden; 129 int period_size_out_overriden; 130 int verbose; 131} conf = { 132#ifdef HIGH_LATENCY 133 .size_in_usec_in = 1, 134 .size_in_usec_out = 1, 135#endif 136 .pcm_name_out = "default", 137 .pcm_name_in = "default", 138#ifdef HIGH_LATENCY 139 .buffer_size_in = 400000, 140 .period_size_in = 400000 / 4, 141 .buffer_size_out = 400000, 142 .period_size_out = 400000 / 4, 143#else 144#define DEFAULT_BUFFER_SIZE 1024 145#define DEFAULT_PERIOD_SIZE 256 146 .buffer_size_in = DEFAULT_BUFFER_SIZE * 4, 147 .period_size_in = DEFAULT_PERIOD_SIZE * 4, 148 .buffer_size_out = DEFAULT_BUFFER_SIZE, 149 .period_size_out = DEFAULT_PERIOD_SIZE, 150 .buffer_size_in_overriden = 0, 151 .buffer_size_out_overriden = 0, 152 .period_size_in_overriden = 0, 153 .period_size_out_overriden = 0, 154#endif 155 .threshold = 0, 156 .verbose = 0 157}; 158 159struct alsa_params_req { 160 int freq; 161 audfmt_e fmt; 162 int nchannels; 163 unsigned int buffer_size; 164 unsigned int period_size; 165}; 166 167struct alsa_params_obt { 168 int freq; 169 audfmt_e fmt; 170 int nchannels; 171 snd_pcm_uframes_t samples; 172}; 173 174static void GCC_FMT_ATTR (2, 3) alsa_logerr (int err, const char *fmt, ...) 175{ 176 va_list ap; 177 178 va_start (ap, fmt); 179 AUD_vlog (AUDIO_CAP, fmt, ap); 180 va_end (ap); 181 182 AUD_log (AUDIO_CAP, "Reason: %s\n", func_snd_strerror (err)); 183} 184 185static void GCC_FMT_ATTR (3, 4) alsa_logerr2 ( 186 int err, 187 const char *typ, 188 const char *fmt, 189 ... 190 ) 191{ 192 va_list ap; 193 194 AUD_log (AUDIO_CAP, "Could not initialize %s\n", typ); 195 196 va_start (ap, fmt); 197 AUD_vlog (AUDIO_CAP, fmt, ap); 198 va_end (ap); 199 200 AUD_log (AUDIO_CAP, "Reason: %s\n", func_snd_strerror (err)); 201} 202 203static void alsa_anal_close (snd_pcm_t **handlep) 204{ 205 int err = func_snd_pcm_close (*handlep); 206 if (err) { 207 alsa_logerr (err, "Failed to close PCM handle %p\n", *handlep); 208 } 209 *handlep = NULL; 210} 211 212static int alsa_write (SWVoiceOut *sw, void *buf, int len) 213{ 214 return audio_pcm_sw_write (sw, buf, len); 215} 216 217static int aud_to_alsafmt (audfmt_e fmt) 218{ 219 switch (fmt) { 220 case AUD_FMT_S8: 221 return SND_PCM_FORMAT_S8; 222 223 case AUD_FMT_U8: 224 return SND_PCM_FORMAT_U8; 225 226 case AUD_FMT_S16: 227 return SND_PCM_FORMAT_S16_LE; 228 229 case AUD_FMT_U16: 230 return SND_PCM_FORMAT_U16_LE; 231 232 default: 233 dolog ("Internal logic error: Bad audio format %d\n", fmt); 234#ifdef DEBUG_AUDIO 235 abort (); 236#endif 237 return SND_PCM_FORMAT_U8; 238 } 239} 240 241static int alsa_to_audfmt (int alsafmt, audfmt_e *fmt, int *endianness) 242{ 243 switch (alsafmt) { 244 case SND_PCM_FORMAT_S8: 245 *endianness = 0; 246 *fmt = AUD_FMT_S8; 247 break; 248 249 case SND_PCM_FORMAT_U8: 250 *endianness = 0; 251 *fmt = AUD_FMT_U8; 252 break; 253 254 case SND_PCM_FORMAT_S16_LE: 255 *endianness = 0; 256 *fmt = AUD_FMT_S16; 257 break; 258 259 case SND_PCM_FORMAT_U16_LE: 260 *endianness = 0; 261 *fmt = AUD_FMT_U16; 262 break; 263 264 case SND_PCM_FORMAT_S16_BE: 265 *endianness = 1; 266 *fmt = AUD_FMT_S16; 267 break; 268 269 case SND_PCM_FORMAT_U16_BE: 270 *endianness = 1; 271 *fmt = AUD_FMT_U16; 272 break; 273 274 default: 275 dolog ("Unrecognized audio format %d\n", alsafmt); 276 return -1; 277 } 278 279 return 0; 280} 281 282#if defined DEBUG_MISMATCHES || defined DEBUG 283static void alsa_dump_info (struct alsa_params_req *req, 284 struct alsa_params_obt *obt) 285{ 286 dolog ("parameter | requested value | obtained value\n"); 287 dolog ("format | %10d | %10d\n", req->fmt, obt->fmt); 288 dolog ("channels | %10d | %10d\n", 289 req->nchannels, obt->nchannels); 290 dolog ("frequency | %10d | %10d\n", req->freq, obt->freq); 291 dolog ("============================================\n"); 292 dolog ("requested: buffer size %d period size %d\n", 293 req->buffer_size, req->period_size); 294 dolog ("obtained: samples %ld\n", obt->samples); 295} 296#endif 297 298static void alsa_set_threshold (snd_pcm_t *handle, snd_pcm_uframes_t threshold) 299{ 300 int err; 301 snd_pcm_sw_params_t *sw_params; 302 303 func_snd_pcm_sw_params_alloca (&sw_params); 304 305 err = func_snd_pcm_sw_params_current (handle, sw_params); 306 if (err < 0) { 307 dolog ("Could not fully initialize DAC\n"); 308 alsa_logerr (err, "Failed to get current software parameters\n"); 309 return; 310 } 311 312 err = func_snd_pcm_sw_params_set_start_threshold (handle, sw_params, threshold); 313 if (err < 0) { 314 dolog ("Could not fully initialize DAC\n"); 315 alsa_logerr (err, "Failed to set software threshold to %ld\n", 316 threshold); 317 return; 318 } 319 320 err = func_snd_pcm_sw_params (handle, sw_params); 321 if (err < 0) { 322 dolog ("Could not fully initialize DAC\n"); 323 alsa_logerr (err, "Failed to set software parameters\n"); 324 return; 325 } 326} 327 328static int alsa_open (int in, struct alsa_params_req *req, 329 struct alsa_params_obt *obt, snd_pcm_t **handlep) 330{ 331 snd_pcm_t *handle; 332 snd_pcm_hw_params_t *hw_params; 333 int err, freq, nchannels; 334 const char *pcm_name = in ? conf.pcm_name_in : conf.pcm_name_out; 335 unsigned int period_size, buffer_size; 336 snd_pcm_uframes_t obt_buffer_size; 337 const char *typ = in ? "ADC" : "DAC"; 338 339 freq = req->freq; 340 period_size = req->period_size; 341 buffer_size = req->buffer_size; 342 nchannels = req->nchannels; 343 344 func_snd_pcm_hw_params_alloca (&hw_params); 345 346 err = func_snd_pcm_open ( 347 &handle, 348 pcm_name, 349 in ? SND_PCM_STREAM_CAPTURE : SND_PCM_STREAM_PLAYBACK, 350 SND_PCM_NONBLOCK 351 ); 352 if (err < 0) { 353 alsa_logerr2 (err, typ, "Failed to open `%s':\n", pcm_name); 354 return -1; 355 } 356 357 err = func_snd_pcm_hw_params_any (handle, hw_params); 358 if (err < 0) { 359 alsa_logerr2 (err, typ, "Failed to initialize hardware parameters\n"); 360 goto err; 361 } 362 363 err = func_snd_pcm_hw_params_set_access ( 364 handle, 365 hw_params, 366 SND_PCM_ACCESS_RW_INTERLEAVED 367 ); 368 if (err < 0) { 369 alsa_logerr2 (err, typ, "Failed to set access type\n"); 370 goto err; 371 } 372 373 err = func_snd_pcm_hw_params_set_format (handle, hw_params, req->fmt); 374 if (err < 0) { 375 alsa_logerr2 (err, typ, "Failed to set format %d\n", req->fmt); 376 goto err; 377 } 378 379 err = func_snd_pcm_hw_params_set_rate_near (handle, hw_params, (unsigned*)&freq, 0); 380 if (err < 0) { 381 alsa_logerr2 (err, typ, "Failed to set frequency %d\n", req->freq); 382 goto err; 383 } 384 385 err = func_snd_pcm_hw_params_set_channels_near ( 386 handle, 387 hw_params, 388 (unsigned*)&nchannels 389 ); 390 if (err < 0) { 391 alsa_logerr2 (err, typ, "Failed to set number of channels %d\n", 392 req->nchannels); 393 goto err; 394 } 395 396 if (nchannels != 1 && nchannels != 2) { 397 alsa_logerr2 (err, typ, 398 "Can not handle obtained number of channels %d\n", 399 nchannels); 400 goto err; 401 } 402 403 if (!((in && conf.size_in_usec_in) || (!in && conf.size_in_usec_out))) { 404 if (!buffer_size) { 405 buffer_size = DEFAULT_BUFFER_SIZE; 406 period_size= DEFAULT_PERIOD_SIZE; 407 } 408 } 409 410 if (buffer_size) { 411 if ((in && conf.size_in_usec_in) || (!in && conf.size_in_usec_out)) { 412 if (period_size) { 413 err = func_snd_pcm_hw_params_set_period_time_near ( 414 handle, 415 hw_params, 416 &period_size, 417 0 418 ); 419 if (err < 0) { 420 alsa_logerr2 (err, typ, 421 "Failed to set period time %d\n", 422 req->period_size); 423 goto err; 424 } 425 } 426 427 err = func_snd_pcm_hw_params_set_buffer_time_near ( 428 handle, 429 hw_params, 430 &buffer_size, 431 0 432 ); 433 434 if (err < 0) { 435 alsa_logerr2 (err, typ, 436 "Failed to set buffer time %d\n", 437 req->buffer_size); 438 goto err; 439 } 440 } 441 else { 442 int dir; 443 snd_pcm_uframes_t minval; 444 445 if (period_size) { 446 minval = period_size; 447 dir = 0; 448 449 err = func_snd_pcm_hw_params_get_period_size_min ( 450 hw_params, 451 &minval, 452 &dir 453 ); 454 if (err < 0) { 455 alsa_logerr ( 456 err, 457 "Could not get minmal period size for %s\n", 458 typ 459 ); 460 } 461 else { 462 if (period_size < minval) { 463 if ((in && conf.period_size_in_overriden) 464 || (!in && conf.period_size_out_overriden)) { 465 dolog ("%s period size(%d) is less " 466 "than minmal period size(%ld)\n", 467 typ, 468 period_size, 469 minval); 470 } 471 period_size = minval; 472 } 473 } 474 475 err = func_snd_pcm_hw_params_set_period_size ( 476 handle, 477 hw_params, 478 period_size, 479 0 480 ); 481 if (err < 0) { 482 alsa_logerr2 (err, typ, "Failed to set period size %d\n", 483 req->period_size); 484 goto err; 485 } 486 } 487 488 minval = buffer_size; 489 err = func_snd_pcm_hw_params_get_buffer_size_min ( 490 hw_params, 491 &minval 492 ); 493 if (err < 0) { 494 alsa_logerr (err, "Could not get minmal buffer size for %s\n", 495 typ); 496 } 497 else { 498 if (buffer_size < minval) { 499 if ((in && conf.buffer_size_in_overriden) 500 || (!in && conf.buffer_size_out_overriden)) { 501 dolog ( 502 "%s buffer size(%d) is less " 503 "than minimal buffer size(%ld)\n", 504 typ, 505 buffer_size, 506 minval 507 ); 508 } 509 buffer_size = minval; 510 } 511 } 512 513 err = func_snd_pcm_hw_params_set_buffer_size ( 514 handle, 515 hw_params, 516 buffer_size 517 ); 518 if (err < 0) { 519 alsa_logerr2 (err, typ, "Failed to set buffer size %d\n", 520 req->buffer_size); 521 goto err; 522 } 523 } 524 } 525 else { 526 dolog ("warning: Buffer size is not set\n"); 527 } 528 529 err = func_snd_pcm_hw_params (handle, hw_params); 530 if (err < 0) { 531 alsa_logerr2 (err, typ, "Failed to apply audio parameters\n"); 532 goto err; 533 } 534 535 err = func_snd_pcm_hw_params_get_buffer_size (hw_params, &obt_buffer_size); 536 if (err < 0) { 537 alsa_logerr2 (err, typ, "Failed to get buffer size\n"); 538 goto err; 539 } 540 541 err = func_snd_pcm_prepare (handle); 542 if (err < 0) { 543 alsa_logerr2 (err, typ, "Could not prepare handle %p\n", handle); 544 goto err; 545 } 546 547 if (!in && conf.threshold) { 548 snd_pcm_uframes_t threshold; 549 int bytes_per_sec; 550 551 bytes_per_sec = freq 552 << (nchannels == 2) 553 << (req->fmt == AUD_FMT_S16 || req->fmt == AUD_FMT_U16); 554 555 threshold = (conf.threshold * bytes_per_sec) / 1000; 556 alsa_set_threshold (handle, threshold); 557 } 558 559 obt->fmt = req->fmt; 560 obt->nchannels = nchannels; 561 obt->freq = freq; 562 obt->samples = obt_buffer_size; 563 *handlep = handle; 564 565#if defined DEBUG_MISMATCHES || defined DEBUG 566 if (obt->fmt != req->fmt || 567 obt->nchannels != req->nchannels || 568 obt->freq != req->freq) { 569 dolog ("Audio paramters mismatch for %s\n", typ); 570 alsa_dump_info (req, obt); 571 } 572#endif 573 574#ifdef DEBUG 575 alsa_dump_info (req, obt); 576#endif 577 return 0; 578 579 err: 580 alsa_anal_close (&handle); 581 return -1; 582} 583 584static int alsa_recover (snd_pcm_t *handle) 585{ 586 int err = func_snd_pcm_prepare (handle); 587 if (err < 0) { 588 alsa_logerr (err, "Failed to prepare handle %p\n", handle); 589 return -1; 590 } 591 return 0; 592} 593 594static snd_pcm_sframes_t alsa_get_avail (snd_pcm_t *handle) 595{ 596 snd_pcm_sframes_t avail; 597 598 avail = func_snd_pcm_avail_update (handle); 599 if (avail < 0) { 600 if (avail == -EPIPE) { 601 if (!alsa_recover (handle)) { 602 avail = func_snd_pcm_avail_update (handle); 603 } 604 } 605 606 if (avail < 0) { 607 alsa_logerr (avail, 608 "Could not obtain number of available frames\n"); 609 return -1; 610 } 611 } 612 613 return avail; 614} 615 616static int alsa_run_out (HWVoiceOut *hw) 617{ 618 ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw; 619 int rpos, live, decr; 620 int samples; 621 uint8_t *dst; 622 st_sample_t *src; 623 snd_pcm_sframes_t avail; 624 625 live = audio_pcm_hw_get_live_out (hw); 626 if (!live) { 627 return 0; 628 } 629 630 avail = alsa_get_avail (alsa->handle); 631 if (avail < 0) { 632 dolog ("Could not get number of available playback frames\n"); 633 return 0; 634 } 635 636 decr = audio_MIN (live, avail); 637 samples = decr; 638 rpos = hw->rpos; 639 while (samples) { 640 int left_till_end_samples = hw->samples - rpos; 641 int len = audio_MIN (samples, left_till_end_samples); 642 snd_pcm_sframes_t written; 643 644 src = hw->mix_buf + rpos; 645 dst = advance (alsa->pcm_buf, rpos << hw->info.shift); 646 647 hw->clip (dst, src, len); 648 649 while (len) { 650 written = func_snd_pcm_writei (alsa->handle, dst, len); 651 652 if (written <= 0) { 653 switch (written) { 654 case 0: 655 if (conf.verbose) { 656 dolog ("Failed to write %d frames (wrote zero)\n", len); 657 } 658 goto exit; 659 660 case -EPIPE: 661 if (alsa_recover (alsa->handle)) { 662 alsa_logerr (written, "Failed to write %d frames\n", 663 len); 664 goto exit; 665 } 666 if (conf.verbose) { 667 dolog ("Recovering from playback xrun\n"); 668 } 669 continue; 670 671 case -EAGAIN: 672 goto exit; 673 674 default: 675 alsa_logerr (written, "Failed to write %d frames to %p\n", 676 len, dst); 677 goto exit; 678 } 679 } 680 681 rpos = (rpos + written) % hw->samples; 682 samples -= written; 683 len -= written; 684 dst = advance (dst, written << hw->info.shift); 685 src += written; 686 } 687 } 688 689 exit: 690 hw->rpos = rpos; 691 return decr; 692} 693 694static void alsa_fini_out (HWVoiceOut *hw) 695{ 696 ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw; 697 698 ldebug ("alsa_fini\n"); 699 alsa_anal_close (&alsa->handle); 700 701 if (alsa->pcm_buf) { 702 qemu_free (alsa->pcm_buf); 703 alsa->pcm_buf = NULL; 704 } 705} 706 707static int alsa_init_out (HWVoiceOut *hw, audsettings_t *as) 708{ 709 ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw; 710 struct alsa_params_req req; 711 struct alsa_params_obt obt; 712 audfmt_e effective_fmt; 713 int endianness; 714 int err, result = -1; 715 snd_pcm_t *handle; 716 audsettings_t obt_as; 717 718 /* shut alsa debug spew */ 719 if (!D_ACTIVE) 720 stdio_disable(); 721 722 req.fmt = aud_to_alsafmt (as->fmt); 723 req.freq = as->freq; 724 req.nchannels = as->nchannels; 725 req.period_size = conf.period_size_out; 726 req.buffer_size = conf.buffer_size_out; 727 728 if (alsa_open (0, &req, &obt, &handle)) { 729 goto Exit; 730 } 731 732 err = alsa_to_audfmt (obt.fmt, &effective_fmt, &endianness); 733 if (err) { 734 alsa_anal_close (&handle); 735 goto Exit; 736 } 737 738 obt_as.freq = obt.freq; 739 obt_as.nchannels = obt.nchannels; 740 obt_as.fmt = effective_fmt; 741 obt_as.endianness = endianness; 742 743 audio_pcm_init_info (&hw->info, &obt_as); 744 hw->samples = obt.samples; 745 746 alsa->pcm_buf = audio_calloc (AUDIO_FUNC, obt.samples, 1 << hw->info.shift); 747 if (!alsa->pcm_buf) { 748 dolog ("Could not allocate DAC buffer (%d samples, each %d bytes)\n", 749 hw->samples, 1 << hw->info.shift); 750 alsa_anal_close (&handle); 751 goto Exit; 752 } 753 754 alsa->handle = handle; 755 result = 0; /* success */ 756 757Exit: 758 if (!D_ACTIVE) 759 stdio_enable(); 760 761 return result; 762} 763 764static int alsa_voice_ctl (snd_pcm_t *handle, const char *typ, int pause) 765{ 766 int err; 767 768 if (pause) { 769 err = func_snd_pcm_drop (handle); 770 if (err < 0) { 771 alsa_logerr (err, "Could not stop %s\n", typ); 772 return -1; 773 } 774 } 775 else { 776 err = func_snd_pcm_prepare (handle); 777 if (err < 0) { 778 alsa_logerr (err, "Could not prepare handle for %s\n", typ); 779 return -1; 780 } 781 } 782 783 return 0; 784} 785 786static int alsa_ctl_out (HWVoiceOut *hw, int cmd, ...) 787{ 788 ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw; 789 790 switch (cmd) { 791 case VOICE_ENABLE: 792 ldebug ("enabling voice\n"); 793 return alsa_voice_ctl (alsa->handle, "playback", 0); 794 795 case VOICE_DISABLE: 796 ldebug ("disabling voice\n"); 797 return alsa_voice_ctl (alsa->handle, "playback", 1); 798 } 799 800 return -1; 801} 802 803static int alsa_init_in (HWVoiceIn *hw, audsettings_t *as) 804{ 805 ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw; 806 struct alsa_params_req req; 807 struct alsa_params_obt obt; 808 int endianness; 809 int err, result = -1; 810 audfmt_e effective_fmt; 811 snd_pcm_t *handle; 812 audsettings_t obt_as; 813 814 /* shut alsa debug spew */ 815 if (!D_ACTIVE) 816 stdio_disable(); 817 818 req.fmt = aud_to_alsafmt (as->fmt); 819 req.freq = as->freq; 820 req.nchannels = as->nchannels; 821 req.period_size = conf.period_size_in; 822 req.buffer_size = conf.buffer_size_in; 823 824 if (alsa_open (1, &req, &obt, &handle)) { 825 goto Exit; 826 } 827 828 err = alsa_to_audfmt (obt.fmt, &effective_fmt, &endianness); 829 if (err) { 830 alsa_anal_close (&handle); 831 goto Exit; 832 } 833 834 obt_as.freq = obt.freq; 835 obt_as.nchannels = obt.nchannels; 836 obt_as.fmt = effective_fmt; 837 obt_as.endianness = endianness; 838 839 audio_pcm_init_info (&hw->info, &obt_as); 840 hw->samples = obt.samples; 841 842 alsa->pcm_buf = audio_calloc (AUDIO_FUNC, hw->samples, 1 << hw->info.shift); 843 if (!alsa->pcm_buf) { 844 dolog ("Could not allocate ADC buffer (%d samples, each %d bytes)\n", 845 hw->samples, 1 << hw->info.shift); 846 alsa_anal_close (&handle); 847 goto Exit; 848 } 849 850 alsa->handle = handle; 851 result = 0; /* success */ 852 853Exit: 854 if (!D_ACTIVE) 855 stdio_enable(); 856 857 return result; 858} 859 860static void alsa_fini_in (HWVoiceIn *hw) 861{ 862 ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw; 863 864 alsa_anal_close (&alsa->handle); 865 866 if (alsa->pcm_buf) { 867 qemu_free (alsa->pcm_buf); 868 alsa->pcm_buf = NULL; 869 } 870} 871 872static int alsa_run_in (HWVoiceIn *hw) 873{ 874 ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw; 875 int hwshift = hw->info.shift; 876 int i; 877 int live = audio_pcm_hw_get_live_in (hw); 878 int dead = hw->samples - live; 879 int decr; 880 struct { 881 int add; 882 int len; 883 } bufs[2] = { 884 { hw->wpos, 0 }, 885 { 0, 0 } 886 }; 887 snd_pcm_sframes_t avail; 888 snd_pcm_uframes_t read_samples = 0; 889 890 if (!dead) { 891 return 0; 892 } 893 894 avail = alsa_get_avail (alsa->handle); 895 if (avail < 0) { 896 dolog ("Could not get number of captured frames\n"); 897 return 0; 898 } 899 900 if (!avail && (func_snd_pcm_state (alsa->handle) == SND_PCM_STATE_PREPARED)) { 901 avail = hw->samples; 902 } 903 904 decr = audio_MIN (dead, avail); 905 if (!decr) { 906 return 0; 907 } 908 909 if (hw->wpos + decr > hw->samples) { 910 bufs[0].len = (hw->samples - hw->wpos); 911 bufs[1].len = (decr - (hw->samples - hw->wpos)); 912 } 913 else { 914 bufs[0].len = decr; 915 } 916 917 for (i = 0; i < 2; ++i) { 918 void *src; 919 st_sample_t *dst; 920 snd_pcm_sframes_t nread; 921 snd_pcm_uframes_t len; 922 923 len = bufs[i].len; 924 925 src = advance (alsa->pcm_buf, bufs[i].add << hwshift); 926 dst = hw->conv_buf + bufs[i].add; 927 928 while (len) { 929 nread = func_snd_pcm_readi (alsa->handle, src, len); 930 931 if (nread <= 0) { 932 switch (nread) { 933 case 0: 934 if (conf.verbose) { 935 dolog ("Failed to read %ld frames (read zero)\n", len); 936 } 937 goto exit; 938 939 case -EPIPE: 940 if (alsa_recover (alsa->handle)) { 941 alsa_logerr (nread, "Failed to read %ld frames\n", len); 942 goto exit; 943 } 944 if (conf.verbose) { 945 dolog ("Recovering from capture xrun\n"); 946 } 947 continue; 948 949 case -EAGAIN: 950 goto exit; 951 952 default: 953 alsa_logerr ( 954 nread, 955 "Failed to read %ld frames from %p\n", 956 len, 957 src 958 ); 959 goto exit; 960 } 961 } 962 963 hw->conv (dst, src, nread, &nominal_volume); 964 965 src = advance (src, nread << hwshift); 966 dst += nread; 967 968 read_samples += nread; 969 len -= nread; 970 } 971 } 972 973 exit: 974 hw->wpos = (hw->wpos + read_samples) % hw->samples; 975 return read_samples; 976} 977 978static int alsa_read (SWVoiceIn *sw, void *buf, int size) 979{ 980 return audio_pcm_sw_read (sw, buf, size); 981} 982 983static int alsa_ctl_in (HWVoiceIn *hw, int cmd, ...) 984{ 985 ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw; 986 987 switch (cmd) { 988 case VOICE_ENABLE: 989 ldebug ("enabling voice\n"); 990 return alsa_voice_ctl (alsa->handle, "capture", 0); 991 992 case VOICE_DISABLE: 993 ldebug ("disabling voice\n"); 994 return alsa_voice_ctl (alsa->handle, "capture", 1); 995 } 996 997 return -1; 998} 999 1000static void *alsa_audio_init (void) 1001{ 1002 void* result = NULL; 1003 1004 alsa_lib = dlopen( "libasound.so", RTLD_NOW ); 1005 if (alsa_lib == NULL) 1006 alsa_lib = dlopen( "libasound.so.2", RTLD_NOW ); 1007 1008 if (alsa_lib == NULL) { 1009 ldebug("could not find libasound on this system\n"); 1010 goto Exit; 1011 } 1012 1013#undef DYN_FUNCTION 1014#define DYN_FUNCTION(ret,name,sig) \ 1015 do { \ 1016 (func_ ##name) = dlsym( alsa_lib, STRINGIFY(name) ); \ 1017 if ((func_##name) == NULL) { \ 1018 ldebug("could not find %s in libasound\n", STRINGIFY(name)); \ 1019 goto Fail; \ 1020 } \ 1021 } while (0); 1022 1023 DYN_SYMBOLS 1024 1025 result = &conf; 1026 goto Exit; 1027 1028Fail: 1029 ldebug("%s: failed to open library\n", __FUNCTION__); 1030 dlclose(alsa_lib); 1031 1032Exit: 1033 return result; 1034} 1035 1036static void alsa_audio_fini (void *opaque) 1037{ 1038 if (alsa_lib != NULL) { 1039 dlclose(alsa_lib); 1040 alsa_lib = NULL; 1041 } 1042 (void) opaque; 1043} 1044 1045static struct audio_option alsa_options[] = { 1046 {"DAC_SIZE_IN_USEC", AUD_OPT_BOOL, &conf.size_in_usec_out, 1047 "DAC period/buffer size in microseconds (otherwise in frames)", NULL, 0}, 1048 {"DAC_PERIOD_SIZE", AUD_OPT_INT, &conf.period_size_out, 1049 "DAC period size", &conf.period_size_out_overriden, 0}, 1050 {"DAC_BUFFER_SIZE", AUD_OPT_INT, &conf.buffer_size_out, 1051 "DAC buffer size", &conf.buffer_size_out_overriden, 0}, 1052 1053 {"ADC_SIZE_IN_USEC", AUD_OPT_BOOL, &conf.size_in_usec_in, 1054 "ADC period/buffer size in microseconds (otherwise in frames)", NULL, 0}, 1055 {"ADC_PERIOD_SIZE", AUD_OPT_INT, &conf.period_size_in, 1056 "ADC period size", &conf.period_size_in_overriden, 0}, 1057 {"ADC_BUFFER_SIZE", AUD_OPT_INT, &conf.buffer_size_in, 1058 "ADC buffer size", &conf.buffer_size_in_overriden, 0}, 1059 1060 {"THRESHOLD", AUD_OPT_INT, &conf.threshold, 1061 "(undocumented)", NULL, 0}, 1062 1063 {"DAC_DEV", AUD_OPT_STR, &conf.pcm_name_out, 1064 "DAC device name (for instance dmix)", NULL, 0}, 1065 1066 {"ADC_DEV", AUD_OPT_STR, &conf.pcm_name_in, 1067 "ADC device name", NULL, 0}, 1068 1069 {"VERBOSE", AUD_OPT_BOOL, &conf.verbose, 1070 "Behave in a more verbose way", NULL, 0}, 1071 1072 {NULL, 0, NULL, NULL, NULL, 0} 1073}; 1074 1075static struct audio_pcm_ops alsa_pcm_ops = { 1076 alsa_init_out, 1077 alsa_fini_out, 1078 alsa_run_out, 1079 alsa_write, 1080 alsa_ctl_out, 1081 1082 alsa_init_in, 1083 alsa_fini_in, 1084 alsa_run_in, 1085 alsa_read, 1086 alsa_ctl_in 1087}; 1088 1089struct audio_driver alsa_audio_driver = { 1090 INIT_FIELD (name = ) "alsa", 1091 INIT_FIELD (descr = ) "ALSA audio (www.alsa-project.org)", 1092 INIT_FIELD (options = ) alsa_options, 1093 INIT_FIELD (init = ) alsa_audio_init, 1094 INIT_FIELD (fini = ) alsa_audio_fini, 1095 INIT_FIELD (pcm_ops = ) &alsa_pcm_ops, 1096 INIT_FIELD (can_be_default = ) 1, 1097 INIT_FIELD (max_voices_out = ) INT_MAX, 1098 INIT_FIELD (max_voices_in = ) INT_MAX, 1099 INIT_FIELD (voice_size_out = ) sizeof (ALSAVoiceOut), 1100 INIT_FIELD (voice_size_in = ) sizeof (ALSAVoiceIn) 1101}; 1102