Commit 7a24c80011d50c1716e84ab70de097caa201746f

Authored by malc
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},