summaryrefslogtreecommitdiff
path: root/audio/alsaaudio.c
diff options
context:
space:
mode:
authormalc <malc@c046a42c-6fe2-441c-8c8c-71466251a162>2008-06-21 17:14:57 +0000
committermalc <malc@c046a42c-6fe2-441c-8c8c-71466251a162>2008-06-21 17:14:57 +0000
commit7a24c80011d50c1716e84ab70de097caa201746f (patch)
treeac781b46f66b15cc5b5f73f92c01fdf7cbe5571a /audio/alsaaudio.c
parent5b5ef0db745c70d9ba967ea133542be3fc927180 (diff)
downloadqemu-7a24c80011d50c1716e84ab70de097caa201746f.tar.gz
Rework period/buffer size setting
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4768 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'audio/alsaaudio.c')
-rw-r--r--audio/alsaaudio.c190
1 files changed, 52 insertions, 138 deletions
diff --git a/audio/alsaaudio.c b/audio/alsaaudio.c
index 43cfa258d7..7d488859d1 100644
--- a/audio/alsaaudio.c
+++ b/audio/alsaaudio.c
@@ -58,37 +58,15 @@ static struct {
int period_size_out_overridden;
int verbose;
} conf = {
-#define DEFAULT_BUFFER_SIZE 1024
-#define DEFAULT_PERIOD_SIZE 256
-#ifdef HIGH_LATENCY
- .size_in_usec_in = 1,
- .size_in_usec_out = 1,
-#endif
.pcm_name_out = "default",
.pcm_name_in = "default",
-#ifdef HIGH_LATENCY
- .buffer_size_in = 400000,
- .period_size_in = 400000 / 4,
- .buffer_size_out = 400000,
- .period_size_out = 400000 / 4,
-#else
- .buffer_size_in = DEFAULT_BUFFER_SIZE * 4,
- .period_size_in = DEFAULT_PERIOD_SIZE * 4,
- .buffer_size_out = DEFAULT_BUFFER_SIZE,
- .period_size_out = DEFAULT_PERIOD_SIZE,
- .buffer_size_in_overridden = 0,
- .buffer_size_out_overridden = 0,
- .period_size_in_overridden = 0,
- .period_size_out_overridden = 0,
-#endif
- .threshold = 0,
- .verbose = 0
};
struct alsa_params_req {
int freq;
snd_pcm_format_t fmt;
int nchannels;
+ int size_in_usec;
unsigned int buffer_size;
unsigned int period_size;
};
@@ -286,17 +264,16 @@ static int alsa_open (int in, struct alsa_params_req *req,
snd_pcm_t *handle;
snd_pcm_hw_params_t *hw_params;
int err;
+ int size_in_usec;
unsigned int freq, nchannels;
const char *pcm_name = in ? conf.pcm_name_in : conf.pcm_name_out;
- unsigned int period_size, buffer_size;
snd_pcm_uframes_t obt_buffer_size;
const char *typ = in ? "ADC" : "DAC";
snd_pcm_format_t obtfmt;
freq = req->freq;
- period_size = req->period_size;
- buffer_size = req->buffer_size;
nchannels = req->nchannels;
+ size_in_usec = req->size_in_usec;
snd_pcm_hw_params_alloca (&hw_params);
@@ -356,130 +333,61 @@ static int alsa_open (int in, struct alsa_params_req *req,
goto err;
}
- if (!((in && conf.size_in_usec_in) || (!in && conf.size_in_usec_out))) {
- if (!buffer_size) {
- buffer_size = DEFAULT_BUFFER_SIZE;
- period_size= DEFAULT_PERIOD_SIZE;
- }
- }
-
- if (buffer_size) {
- if ((in && conf.size_in_usec_in) || (!in && conf.size_in_usec_out)) {
- if (period_size) {
- err = snd_pcm_hw_params_set_period_time_near (
- handle,
- hw_params,
- &period_size,
- 0
- );
- if (err < 0) {
- alsa_logerr2 (err, typ,
- "Failed to set period time %d\n",
- req->period_size);
- goto err;
- }
- }
+ if (req->buffer_size) {
+ if (size_in_usec) {
+ int dir = 0;
+ unsigned int btime = req->buffer_size;
err = snd_pcm_hw_params_set_buffer_time_near (
handle,
hw_params,
- &buffer_size,
- 0
+ &btime,
+ &dir
);
-
- if (err < 0) {
- alsa_logerr2 (err, typ,
- "Failed to set buffer time %d\n",
- req->buffer_size);
- goto err;
- }
}
else {
- int dir;
- snd_pcm_uframes_t minval;
-
- if (period_size) {
- minval = period_size;
- dir = 0;
-
- err = snd_pcm_hw_params_get_period_size_min (
- hw_params,
- &minval,
- &dir
- );
- if (err < 0) {
- alsa_logerr (
- err,
- "Could not get minmal period size for %s\n",
- typ
- );
- }
- else {
- if (period_size < minval) {
- if ((in && conf.period_size_in_overridden)
- || (!in && conf.period_size_out_overridden)) {
- dolog ("%s period size(%d) is less "
- "than minmal period size(%ld)\n",
- typ,
- period_size,
- minval);
- }
- period_size = minval;
- }
- }
+ snd_pcm_uframes_t bsize = req->buffer_size;
- err = snd_pcm_hw_params_set_period_size (
- handle,
- hw_params,
- period_size,
- 0
- );
- if (err < 0) {
- alsa_logerr2 (err, typ, "Failed to set period size %d\n",
- req->period_size);
- goto err;
- }
- }
+ err = snd_pcm_hw_params_set_buffer_size_near (
+ handle,
+ hw_params,
+ &bsize
+ );
+ }
+ if (err < 0) {
+ alsa_logerr2 (err, typ, "Failed to set buffer %s to %d\n",
+ size_in_usec ? "time" : "size", req->buffer_size);
+ goto err;
+ }
+ }
+
+ if (req->period_size) {
+ if (size_in_usec) {
+ int dir = 0;
+ unsigned int ptime = req->period_size;
- minval = buffer_size;
- err = snd_pcm_hw_params_get_buffer_size_min (
+ err = snd_pcm_hw_params_set_period_time_near (
+ handle,
hw_params,
- &minval
+ &ptime,
+ &dir
);
- if (err < 0) {
- alsa_logerr (err, "Could not get minmal buffer size for %s\n",
- typ);
- }
- else {
- if (buffer_size < minval) {
- if ((in && conf.buffer_size_in_overridden)
- || (!in && conf.buffer_size_out_overridden)) {
- dolog (
- "%s buffer size(%d) is less "
- "than minimal buffer size(%ld)\n",
- typ,
- buffer_size,
- minval
- );
- }
- buffer_size = minval;
- }
- }
+ }
+ else {
+ snd_pcm_uframes_t psize = req->period_size;
- err = snd_pcm_hw_params_set_buffer_size (
+ err = snd_pcm_hw_params_set_buffer_size_near (
handle,
hw_params,
- buffer_size
+ &psize
);
- if (err < 0) {
- alsa_logerr2 (err, typ, "Failed to set buffer size %d\n",
- req->buffer_size);
- goto err;
- }
}
- }
- else {
- dolog ("warning: Buffer size is not set\n");
+
+ if (err < 0) {
+ alsa_logerr2 (err, typ, "Failed to set period %s to %d\n",
+ size_in_usec ? "time" : "size", req->period_size);
+ goto err;
+ }
}
err = snd_pcm_hw_params (handle, hw_params);
@@ -697,6 +605,7 @@ static int alsa_init_out (HWVoiceOut *hw, audsettings_t *as)
req.nchannels = as->nchannels;
req.period_size = conf.period_size_out;
req.buffer_size = conf.buffer_size_out;
+ req.size_in_usec = conf.size_in_usec_in;
if (alsa_open (0, &req, &obt, &handle)) {
return -1;
@@ -774,6 +683,7 @@ static int alsa_init_in (HWVoiceIn *hw, audsettings_t *as)
req.nchannels = as->nchannels;
req.period_size = conf.period_size_in;
req.buffer_size = conf.buffer_size_in;
+ req.size_in_usec = conf.size_in_usec_in;
if (alsa_open (1, &req, &obt, &handle)) {
return -1;
@@ -953,16 +863,20 @@ static struct audio_option alsa_options[] = {
{"DAC_SIZE_IN_USEC", AUD_OPT_BOOL, &conf.size_in_usec_out,
"DAC period/buffer size in microseconds (otherwise in frames)", NULL, 0},
{"DAC_PERIOD_SIZE", AUD_OPT_INT, &conf.period_size_out,
- "DAC period size", &conf.period_size_out_overridden, 0},
+ "DAC period size (0 to go with system default)",
+ &conf.period_size_out_overridden, 0},
{"DAC_BUFFER_SIZE", AUD_OPT_INT, &conf.buffer_size_out,
- "DAC buffer size", &conf.buffer_size_out_overridden, 0},
+ "DAC buffer size (0 to go with system default)",
+ &conf.buffer_size_out_overridden, 0},
{"ADC_SIZE_IN_USEC", AUD_OPT_BOOL, &conf.size_in_usec_in,
"ADC period/buffer size in microseconds (otherwise in frames)", NULL, 0},
{"ADC_PERIOD_SIZE", AUD_OPT_INT, &conf.period_size_in,
- "ADC period size", &conf.period_size_in_overridden, 0},
+ "ADC period size (0 to go with system default)",
+ &conf.period_size_in_overridden, 0},
{"ADC_BUFFER_SIZE", AUD_OPT_INT, &conf.buffer_size_in,
- "ADC buffer size", &conf.buffer_size_in_overridden, 0},
+ "ADC buffer size (0 to go with system default)",
+ &conf.buffer_size_in_overridden, 0},
{"THRESHOLD", AUD_OPT_INT, &conf.threshold,
"(undocumented)", NULL, 0},