Commit 7a24c80011d50c1716e84ab70de097caa201746f
1 parent
5b5ef0db
Rework period/buffer size setting
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4768 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
52 additions
and
138 deletions
audio/alsaaudio.c
| @@ -58,37 +58,15 @@ static struct { | @@ -58,37 +58,15 @@ static struct { | ||
| 58 | int period_size_out_overridden; | 58 | int period_size_out_overridden; |
| 59 | int verbose; | 59 | int verbose; |
| 60 | } conf = { | 60 | } conf = { |
| 61 | -#define DEFAULT_BUFFER_SIZE 1024 | ||
| 62 | -#define DEFAULT_PERIOD_SIZE 256 | ||
| 63 | -#ifdef HIGH_LATENCY | ||
| 64 | - .size_in_usec_in = 1, | ||
| 65 | - .size_in_usec_out = 1, | ||
| 66 | -#endif | ||
| 67 | .pcm_name_out = "default", | 61 | .pcm_name_out = "default", |
| 68 | .pcm_name_in = "default", | 62 | .pcm_name_in = "default", |
| 69 | -#ifdef HIGH_LATENCY | ||
| 70 | - .buffer_size_in = 400000, | ||
| 71 | - .period_size_in = 400000 / 4, | ||
| 72 | - .buffer_size_out = 400000, | ||
| 73 | - .period_size_out = 400000 / 4, | ||
| 74 | -#else | ||
| 75 | - .buffer_size_in = DEFAULT_BUFFER_SIZE * 4, | ||
| 76 | - .period_size_in = DEFAULT_PERIOD_SIZE * 4, | ||
| 77 | - .buffer_size_out = DEFAULT_BUFFER_SIZE, | ||
| 78 | - .period_size_out = DEFAULT_PERIOD_SIZE, | ||
| 79 | - .buffer_size_in_overridden = 0, | ||
| 80 | - .buffer_size_out_overridden = 0, | ||
| 81 | - .period_size_in_overridden = 0, | ||
| 82 | - .period_size_out_overridden = 0, | ||
| 83 | -#endif | ||
| 84 | - .threshold = 0, | ||
| 85 | - .verbose = 0 | ||
| 86 | }; | 63 | }; |
| 87 | 64 | ||
| 88 | struct alsa_params_req { | 65 | struct alsa_params_req { |
| 89 | int freq; | 66 | int freq; |
| 90 | snd_pcm_format_t fmt; | 67 | snd_pcm_format_t fmt; |
| 91 | int nchannels; | 68 | int nchannels; |
| 69 | + int size_in_usec; | ||
| 92 | unsigned int buffer_size; | 70 | unsigned int buffer_size; |
| 93 | unsigned int period_size; | 71 | unsigned int period_size; |
| 94 | }; | 72 | }; |
| @@ -286,17 +264,16 @@ static int alsa_open (int in, struct alsa_params_req *req, | @@ -286,17 +264,16 @@ static int alsa_open (int in, struct alsa_params_req *req, | ||
| 286 | snd_pcm_t *handle; | 264 | snd_pcm_t *handle; |
| 287 | snd_pcm_hw_params_t *hw_params; | 265 | snd_pcm_hw_params_t *hw_params; |
| 288 | int err; | 266 | int err; |
| 267 | + int size_in_usec; | ||
| 289 | unsigned int freq, nchannels; | 268 | unsigned int freq, nchannels; |
| 290 | const char *pcm_name = in ? conf.pcm_name_in : conf.pcm_name_out; | 269 | const char *pcm_name = in ? conf.pcm_name_in : conf.pcm_name_out; |
| 291 | - unsigned int period_size, buffer_size; | ||
| 292 | snd_pcm_uframes_t obt_buffer_size; | 270 | snd_pcm_uframes_t obt_buffer_size; |
| 293 | const char *typ = in ? "ADC" : "DAC"; | 271 | const char *typ = in ? "ADC" : "DAC"; |
| 294 | snd_pcm_format_t obtfmt; | 272 | snd_pcm_format_t obtfmt; |
| 295 | 273 | ||
| 296 | freq = req->freq; | 274 | freq = req->freq; |
| 297 | - period_size = req->period_size; | ||
| 298 | - buffer_size = req->buffer_size; | ||
| 299 | nchannels = req->nchannels; | 275 | nchannels = req->nchannels; |
| 276 | + size_in_usec = req->size_in_usec; | ||
| 300 | 277 | ||
| 301 | snd_pcm_hw_params_alloca (&hw_params); | 278 | snd_pcm_hw_params_alloca (&hw_params); |
| 302 | 279 | ||
| @@ -356,130 +333,61 @@ static int alsa_open (int in, struct alsa_params_req *req, | @@ -356,130 +333,61 @@ static int alsa_open (int in, struct alsa_params_req *req, | ||
| 356 | goto err; | 333 | goto err; |
| 357 | } | 334 | } |
| 358 | 335 | ||
| 359 | - if (!((in && conf.size_in_usec_in) || (!in && conf.size_in_usec_out))) { | ||
| 360 | - if (!buffer_size) { | ||
| 361 | - buffer_size = DEFAULT_BUFFER_SIZE; | ||
| 362 | - period_size= DEFAULT_PERIOD_SIZE; | ||
| 363 | - } | ||
| 364 | - } | ||
| 365 | - | ||
| 366 | - if (buffer_size) { | ||
| 367 | - if ((in && conf.size_in_usec_in) || (!in && conf.size_in_usec_out)) { | ||
| 368 | - if (period_size) { | ||
| 369 | - err = snd_pcm_hw_params_set_period_time_near ( | ||
| 370 | - handle, | ||
| 371 | - hw_params, | ||
| 372 | - &period_size, | ||
| 373 | - 0 | ||
| 374 | - ); | ||
| 375 | - if (err < 0) { | ||
| 376 | - alsa_logerr2 (err, typ, | ||
| 377 | - "Failed to set period time %d\n", | ||
| 378 | - req->period_size); | ||
| 379 | - goto err; | ||
| 380 | - } | ||
| 381 | - } | 336 | + if (req->buffer_size) { |
| 337 | + if (size_in_usec) { | ||
| 338 | + int dir = 0; | ||
| 339 | + unsigned int btime = req->buffer_size; | ||
| 382 | 340 | ||
| 383 | err = snd_pcm_hw_params_set_buffer_time_near ( | 341 | err = snd_pcm_hw_params_set_buffer_time_near ( |
| 384 | handle, | 342 | handle, |
| 385 | hw_params, | 343 | hw_params, |
| 386 | - &buffer_size, | ||
| 387 | - 0 | 344 | + &btime, |
| 345 | + &dir | ||
| 388 | ); | 346 | ); |
| 389 | - | ||
| 390 | - if (err < 0) { | ||
| 391 | - alsa_logerr2 (err, typ, | ||
| 392 | - "Failed to set buffer time %d\n", | ||
| 393 | - req->buffer_size); | ||
| 394 | - goto err; | ||
| 395 | - } | ||
| 396 | } | 347 | } |
| 397 | else { | 348 | else { |
| 398 | - int dir; | ||
| 399 | - snd_pcm_uframes_t minval; | ||
| 400 | - | ||
| 401 | - if (period_size) { | ||
| 402 | - minval = period_size; | ||
| 403 | - dir = 0; | ||
| 404 | - | ||
| 405 | - err = snd_pcm_hw_params_get_period_size_min ( | ||
| 406 | - hw_params, | ||
| 407 | - &minval, | ||
| 408 | - &dir | ||
| 409 | - ); | ||
| 410 | - if (err < 0) { | ||
| 411 | - alsa_logerr ( | ||
| 412 | - err, | ||
| 413 | - "Could not get minmal period size for %s\n", | ||
| 414 | - typ | ||
| 415 | - ); | ||
| 416 | - } | ||
| 417 | - else { | ||
| 418 | - if (period_size < minval) { | ||
| 419 | - if ((in && conf.period_size_in_overridden) | ||
| 420 | - || (!in && conf.period_size_out_overridden)) { | ||
| 421 | - dolog ("%s period size(%d) is less " | ||
| 422 | - "than minmal period size(%ld)\n", | ||
| 423 | - typ, | ||
| 424 | - period_size, | ||
| 425 | - minval); | ||
| 426 | - } | ||
| 427 | - period_size = minval; | ||
| 428 | - } | ||
| 429 | - } | 349 | + snd_pcm_uframes_t bsize = req->buffer_size; |
| 430 | 350 | ||
| 431 | - err = snd_pcm_hw_params_set_period_size ( | ||
| 432 | - handle, | ||
| 433 | - hw_params, | ||
| 434 | - period_size, | ||
| 435 | - 0 | ||
| 436 | - ); | ||
| 437 | - if (err < 0) { | ||
| 438 | - alsa_logerr2 (err, typ, "Failed to set period size %d\n", | ||
| 439 | - req->period_size); | ||
| 440 | - goto err; | ||
| 441 | - } | ||
| 442 | - } | 351 | + err = snd_pcm_hw_params_set_buffer_size_near ( |
| 352 | + handle, | ||
| 353 | + hw_params, | ||
| 354 | + &bsize | ||
| 355 | + ); | ||
| 356 | + } | ||
| 357 | + if (err < 0) { | ||
| 358 | + alsa_logerr2 (err, typ, "Failed to set buffer %s to %d\n", | ||
| 359 | + size_in_usec ? "time" : "size", req->buffer_size); | ||
| 360 | + goto err; | ||
| 361 | + } | ||
| 362 | + } | ||
| 363 | + | ||
| 364 | + if (req->period_size) { | ||
| 365 | + if (size_in_usec) { | ||
| 366 | + int dir = 0; | ||
| 367 | + unsigned int ptime = req->period_size; | ||
| 443 | 368 | ||
| 444 | - minval = buffer_size; | ||
| 445 | - err = snd_pcm_hw_params_get_buffer_size_min ( | 369 | + err = snd_pcm_hw_params_set_period_time_near ( |
| 370 | + handle, | ||
| 446 | hw_params, | 371 | hw_params, |
| 447 | - &minval | 372 | + &ptime, |
| 373 | + &dir | ||
| 448 | ); | 374 | ); |
| 449 | - if (err < 0) { | ||
| 450 | - alsa_logerr (err, "Could not get minmal buffer size for %s\n", | ||
| 451 | - typ); | ||
| 452 | - } | ||
| 453 | - else { | ||
| 454 | - if (buffer_size < minval) { | ||
| 455 | - if ((in && conf.buffer_size_in_overridden) | ||
| 456 | - || (!in && conf.buffer_size_out_overridden)) { | ||
| 457 | - dolog ( | ||
| 458 | - "%s buffer size(%d) is less " | ||
| 459 | - "than minimal buffer size(%ld)\n", | ||
| 460 | - typ, | ||
| 461 | - buffer_size, | ||
| 462 | - minval | ||
| 463 | - ); | ||
| 464 | - } | ||
| 465 | - buffer_size = minval; | ||
| 466 | - } | ||
| 467 | - } | 375 | + } |
| 376 | + else { | ||
| 377 | + snd_pcm_uframes_t psize = req->period_size; | ||
| 468 | 378 | ||
| 469 | - err = snd_pcm_hw_params_set_buffer_size ( | 379 | + err = snd_pcm_hw_params_set_buffer_size_near ( |
| 470 | handle, | 380 | handle, |
| 471 | hw_params, | 381 | hw_params, |
| 472 | - buffer_size | 382 | + &psize |
| 473 | ); | 383 | ); |
| 474 | - if (err < 0) { | ||
| 475 | - alsa_logerr2 (err, typ, "Failed to set buffer size %d\n", | ||
| 476 | - req->buffer_size); | ||
| 477 | - goto err; | ||
| 478 | - } | ||
| 479 | } | 384 | } |
| 480 | - } | ||
| 481 | - else { | ||
| 482 | - dolog ("warning: Buffer size is not set\n"); | 385 | + |
| 386 | + if (err < 0) { | ||
| 387 | + alsa_logerr2 (err, typ, "Failed to set period %s to %d\n", | ||
| 388 | + size_in_usec ? "time" : "size", req->period_size); | ||
| 389 | + goto err; | ||
| 390 | + } | ||
| 483 | } | 391 | } |
| 484 | 392 | ||
| 485 | err = snd_pcm_hw_params (handle, hw_params); | 393 | err = snd_pcm_hw_params (handle, hw_params); |
| @@ -697,6 +605,7 @@ static int alsa_init_out (HWVoiceOut *hw, audsettings_t *as) | @@ -697,6 +605,7 @@ static int alsa_init_out (HWVoiceOut *hw, audsettings_t *as) | ||
| 697 | req.nchannels = as->nchannels; | 605 | req.nchannels = as->nchannels; |
| 698 | req.period_size = conf.period_size_out; | 606 | req.period_size = conf.period_size_out; |
| 699 | req.buffer_size = conf.buffer_size_out; | 607 | req.buffer_size = conf.buffer_size_out; |
| 608 | + req.size_in_usec = conf.size_in_usec_in; | ||
| 700 | 609 | ||
| 701 | if (alsa_open (0, &req, &obt, &handle)) { | 610 | if (alsa_open (0, &req, &obt, &handle)) { |
| 702 | return -1; | 611 | return -1; |
| @@ -774,6 +683,7 @@ static int alsa_init_in (HWVoiceIn *hw, audsettings_t *as) | @@ -774,6 +683,7 @@ static int alsa_init_in (HWVoiceIn *hw, audsettings_t *as) | ||
| 774 | req.nchannels = as->nchannels; | 683 | req.nchannels = as->nchannels; |
| 775 | req.period_size = conf.period_size_in; | 684 | req.period_size = conf.period_size_in; |
| 776 | req.buffer_size = conf.buffer_size_in; | 685 | req.buffer_size = conf.buffer_size_in; |
| 686 | + req.size_in_usec = conf.size_in_usec_in; | ||
| 777 | 687 | ||
| 778 | if (alsa_open (1, &req, &obt, &handle)) { | 688 | if (alsa_open (1, &req, &obt, &handle)) { |
| 779 | return -1; | 689 | return -1; |
| @@ -953,16 +863,20 @@ static struct audio_option alsa_options[] = { | @@ -953,16 +863,20 @@ static struct audio_option alsa_options[] = { | ||
| 953 | {"DAC_SIZE_IN_USEC", AUD_OPT_BOOL, &conf.size_in_usec_out, | 863 | {"DAC_SIZE_IN_USEC", AUD_OPT_BOOL, &conf.size_in_usec_out, |
| 954 | "DAC period/buffer size in microseconds (otherwise in frames)", NULL, 0}, | 864 | "DAC period/buffer size in microseconds (otherwise in frames)", NULL, 0}, |
| 955 | {"DAC_PERIOD_SIZE", AUD_OPT_INT, &conf.period_size_out, | 865 | {"DAC_PERIOD_SIZE", AUD_OPT_INT, &conf.period_size_out, |
| 956 | - "DAC period size", &conf.period_size_out_overridden, 0}, | 866 | + "DAC period size (0 to go with system default)", |
| 867 | + &conf.period_size_out_overridden, 0}, | ||
| 957 | {"DAC_BUFFER_SIZE", AUD_OPT_INT, &conf.buffer_size_out, | 868 | {"DAC_BUFFER_SIZE", AUD_OPT_INT, &conf.buffer_size_out, |
| 958 | - "DAC buffer size", &conf.buffer_size_out_overridden, 0}, | 869 | + "DAC buffer size (0 to go with system default)", |
| 870 | + &conf.buffer_size_out_overridden, 0}, | ||
| 959 | 871 | ||
| 960 | {"ADC_SIZE_IN_USEC", AUD_OPT_BOOL, &conf.size_in_usec_in, | 872 | {"ADC_SIZE_IN_USEC", AUD_OPT_BOOL, &conf.size_in_usec_in, |
| 961 | "ADC period/buffer size in microseconds (otherwise in frames)", NULL, 0}, | 873 | "ADC period/buffer size in microseconds (otherwise in frames)", NULL, 0}, |
| 962 | {"ADC_PERIOD_SIZE", AUD_OPT_INT, &conf.period_size_in, | 874 | {"ADC_PERIOD_SIZE", AUD_OPT_INT, &conf.period_size_in, |
| 963 | - "ADC period size", &conf.period_size_in_overridden, 0}, | 875 | + "ADC period size (0 to go with system default)", |
| 876 | + &conf.period_size_in_overridden, 0}, | ||
| 964 | {"ADC_BUFFER_SIZE", AUD_OPT_INT, &conf.buffer_size_in, | 877 | {"ADC_BUFFER_SIZE", AUD_OPT_INT, &conf.buffer_size_in, |
| 965 | - "ADC buffer size", &conf.buffer_size_in_overridden, 0}, | 878 | + "ADC buffer size (0 to go with system default)", |
| 879 | + &conf.buffer_size_in_overridden, 0}, | ||
| 966 | 880 | ||
| 967 | {"THRESHOLD", AUD_OPT_INT, &conf.threshold, | 881 | {"THRESHOLD", AUD_OPT_INT, &conf.threshold, |
| 968 | "(undocumented)", NULL, 0}, | 882 | "(undocumented)", NULL, 0}, |