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