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 | 58 | int period_size_out_overridden; |
59 | 59 | int verbose; |
60 | 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 | 61 | .pcm_name_out = "default", |
68 | 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 | 65 | struct alsa_params_req { |
89 | 66 | int freq; |
90 | 67 | snd_pcm_format_t fmt; |
91 | 68 | int nchannels; |
69 | + int size_in_usec; | |
92 | 70 | unsigned int buffer_size; |
93 | 71 | unsigned int period_size; |
94 | 72 | }; |
... | ... | @@ -286,17 +264,16 @@ static int alsa_open (int in, struct alsa_params_req *req, |
286 | 264 | snd_pcm_t *handle; |
287 | 265 | snd_pcm_hw_params_t *hw_params; |
288 | 266 | int err; |
267 | + int size_in_usec; | |
289 | 268 | unsigned int freq, nchannels; |
290 | 269 | const char *pcm_name = in ? conf.pcm_name_in : conf.pcm_name_out; |
291 | - unsigned int period_size, buffer_size; | |
292 | 270 | snd_pcm_uframes_t obt_buffer_size; |
293 | 271 | const char *typ = in ? "ADC" : "DAC"; |
294 | 272 | snd_pcm_format_t obtfmt; |
295 | 273 | |
296 | 274 | freq = req->freq; |
297 | - period_size = req->period_size; | |
298 | - buffer_size = req->buffer_size; | |
299 | 275 | nchannels = req->nchannels; |
276 | + size_in_usec = req->size_in_usec; | |
300 | 277 | |
301 | 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 | 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 | 341 | err = snd_pcm_hw_params_set_buffer_time_near ( |
384 | 342 | handle, |
385 | 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 | 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 | 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 | 380 | handle, |
471 | 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 | 393 | err = snd_pcm_hw_params (handle, hw_params); |
... | ... | @@ -697,6 +605,7 @@ static int alsa_init_out (HWVoiceOut *hw, audsettings_t *as) |
697 | 605 | req.nchannels = as->nchannels; |
698 | 606 | req.period_size = conf.period_size_out; |
699 | 607 | req.buffer_size = conf.buffer_size_out; |
608 | + req.size_in_usec = conf.size_in_usec_in; | |
700 | 609 | |
701 | 610 | if (alsa_open (0, &req, &obt, &handle)) { |
702 | 611 | return -1; |
... | ... | @@ -774,6 +683,7 @@ static int alsa_init_in (HWVoiceIn *hw, audsettings_t *as) |
774 | 683 | req.nchannels = as->nchannels; |
775 | 684 | req.period_size = conf.period_size_in; |
776 | 685 | req.buffer_size = conf.buffer_size_in; |
686 | + req.size_in_usec = conf.size_in_usec_in; | |
777 | 687 | |
778 | 688 | if (alsa_open (1, &req, &obt, &handle)) { |
779 | 689 | return -1; |
... | ... | @@ -953,16 +863,20 @@ static struct audio_option alsa_options[] = { |
953 | 863 | {"DAC_SIZE_IN_USEC", AUD_OPT_BOOL, &conf.size_in_usec_out, |
954 | 864 | "DAC period/buffer size in microseconds (otherwise in frames)", NULL, 0}, |
955 | 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 | 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 | 872 | {"ADC_SIZE_IN_USEC", AUD_OPT_BOOL, &conf.size_in_usec_in, |
961 | 873 | "ADC period/buffer size in microseconds (otherwise in frames)", NULL, 0}, |
962 | 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 | 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 | 881 | {"THRESHOLD", AUD_OPT_INT, &conf.threshold, |
968 | 882 | "(undocumented)", NULL, 0}, | ... | ... |