mirror of https://github.com/xqemu/xqemu.git
Rework period/buffer size setting
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4768 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
5b5ef0db74
commit
7a24c80011
|
@ -58,37 +58,15 @@ static struct {
|
||||||
int period_size_out_overridden;
|
int period_size_out_overridden;
|
||||||
int verbose;
|
int verbose;
|
||||||
} conf = {
|
} 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_out = "default",
|
||||||
.pcm_name_in = "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 {
|
struct alsa_params_req {
|
||||||
int freq;
|
int freq;
|
||||||
snd_pcm_format_t fmt;
|
snd_pcm_format_t fmt;
|
||||||
int nchannels;
|
int nchannels;
|
||||||
|
int size_in_usec;
|
||||||
unsigned int buffer_size;
|
unsigned int buffer_size;
|
||||||
unsigned int period_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_t *handle;
|
||||||
snd_pcm_hw_params_t *hw_params;
|
snd_pcm_hw_params_t *hw_params;
|
||||||
int err;
|
int err;
|
||||||
|
int size_in_usec;
|
||||||
unsigned int freq, nchannels;
|
unsigned int freq, nchannels;
|
||||||
const char *pcm_name = in ? conf.pcm_name_in : conf.pcm_name_out;
|
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;
|
snd_pcm_uframes_t obt_buffer_size;
|
||||||
const char *typ = in ? "ADC" : "DAC";
|
const char *typ = in ? "ADC" : "DAC";
|
||||||
snd_pcm_format_t obtfmt;
|
snd_pcm_format_t obtfmt;
|
||||||
|
|
||||||
freq = req->freq;
|
freq = req->freq;
|
||||||
period_size = req->period_size;
|
|
||||||
buffer_size = req->buffer_size;
|
|
||||||
nchannels = req->nchannels;
|
nchannels = req->nchannels;
|
||||||
|
size_in_usec = req->size_in_usec;
|
||||||
|
|
||||||
snd_pcm_hw_params_alloca (&hw_params);
|
snd_pcm_hw_params_alloca (&hw_params);
|
||||||
|
|
||||||
|
@ -356,130 +333,61 @@ static int alsa_open (int in, struct alsa_params_req *req,
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!((in && conf.size_in_usec_in) || (!in && conf.size_in_usec_out))) {
|
if (req->buffer_size) {
|
||||||
if (!buffer_size) {
|
if (size_in_usec) {
|
||||||
buffer_size = DEFAULT_BUFFER_SIZE;
|
int dir = 0;
|
||||||
period_size= DEFAULT_PERIOD_SIZE;
|
unsigned int btime = req->buffer_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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
err = snd_pcm_hw_params_set_buffer_time_near (
|
err = snd_pcm_hw_params_set_buffer_time_near (
|
||||||
handle,
|
handle,
|
||||||
hw_params,
|
hw_params,
|
||||||
&buffer_size,
|
&btime,
|
||||||
0
|
&dir
|
||||||
);
|
);
|
||||||
|
|
||||||
if (err < 0) {
|
|
||||||
alsa_logerr2 (err, typ,
|
|
||||||
"Failed to set buffer time %d\n",
|
|
||||||
req->buffer_size);
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
int dir;
|
snd_pcm_uframes_t bsize = req->buffer_size;
|
||||||
snd_pcm_uframes_t minval;
|
|
||||||
|
|
||||||
if (period_size) {
|
err = snd_pcm_hw_params_set_buffer_size_near (
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
minval = buffer_size;
|
|
||||||
err = snd_pcm_hw_params_get_buffer_size_min (
|
|
||||||
hw_params,
|
|
||||||
&minval
|
|
||||||
);
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
err = snd_pcm_hw_params_set_buffer_size (
|
|
||||||
handle,
|
handle,
|
||||||
hw_params,
|
hw_params,
|
||||||
buffer_size
|
&bsize
|
||||||
);
|
);
|
||||||
if (err < 0) {
|
}
|
||||||
alsa_logerr2 (err, typ, "Failed to set buffer size %d\n",
|
if (err < 0) {
|
||||||
req->buffer_size);
|
alsa_logerr2 (err, typ, "Failed to set buffer %s to %d\n",
|
||||||
goto err;
|
size_in_usec ? "time" : "size", req->buffer_size);
|
||||||
}
|
goto err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
dolog ("warning: Buffer size is not set\n");
|
if (req->period_size) {
|
||||||
|
if (size_in_usec) {
|
||||||
|
int dir = 0;
|
||||||
|
unsigned int ptime = req->period_size;
|
||||||
|
|
||||||
|
err = snd_pcm_hw_params_set_period_time_near (
|
||||||
|
handle,
|
||||||
|
hw_params,
|
||||||
|
&ptime,
|
||||||
|
&dir
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
snd_pcm_uframes_t psize = req->period_size;
|
||||||
|
|
||||||
|
err = snd_pcm_hw_params_set_buffer_size_near (
|
||||||
|
handle,
|
||||||
|
hw_params,
|
||||||
|
&psize
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
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.nchannels = as->nchannels;
|
||||||
req.period_size = conf.period_size_out;
|
req.period_size = conf.period_size_out;
|
||||||
req.buffer_size = conf.buffer_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)) {
|
if (alsa_open (0, &req, &obt, &handle)) {
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -774,6 +683,7 @@ static int alsa_init_in (HWVoiceIn *hw, audsettings_t *as)
|
||||||
req.nchannels = as->nchannels;
|
req.nchannels = as->nchannels;
|
||||||
req.period_size = conf.period_size_in;
|
req.period_size = conf.period_size_in;
|
||||||
req.buffer_size = conf.buffer_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)) {
|
if (alsa_open (1, &req, &obt, &handle)) {
|
||||||
return -1;
|
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_SIZE_IN_USEC", AUD_OPT_BOOL, &conf.size_in_usec_out,
|
||||||
"DAC period/buffer size in microseconds (otherwise in frames)", NULL, 0},
|
"DAC period/buffer size in microseconds (otherwise in frames)", NULL, 0},
|
||||||
{"DAC_PERIOD_SIZE", AUD_OPT_INT, &conf.period_size_out,
|
{"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", 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_SIZE_IN_USEC", AUD_OPT_BOOL, &conf.size_in_usec_in,
|
||||||
"ADC period/buffer size in microseconds (otherwise in frames)", NULL, 0},
|
"ADC period/buffer size in microseconds (otherwise in frames)", NULL, 0},
|
||||||
{"ADC_PERIOD_SIZE", AUD_OPT_INT, &conf.period_size_in,
|
{"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", 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,
|
{"THRESHOLD", AUD_OPT_INT, &conf.threshold,
|
||||||
"(undocumented)", NULL, 0},
|
"(undocumented)", NULL, 0},
|
||||||
|
|
Loading…
Reference in New Issue