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}, |