summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/conf/alsa.conf1
-rw-r--r--src/pcm/pcm.c8
-rw-r--r--src/pcm/pcm_local.h1
-rw-r--r--src/pcm/pcm_params.c13
4 files changed, 21 insertions, 2 deletions
diff --git a/src/conf/alsa.conf b/src/conf/alsa.conf
index db642597..51605290 100644
--- a/src/conf/alsa.conf
+++ b/src/conf/alsa.conf
@@ -63,6 +63,7 @@ defaults.pcm.card 0
defaults.pcm.device 0
defaults.pcm.subdevice -1
defaults.pcm.nonblock 1
+defaults.pcm.minperiodtime 5000 # in us
defaults.pcm.ipc_key 5678293
defaults.pcm.ipc_gid audio
defaults.pcm.ipc_perm 0660
diff --git a/src/pcm/pcm.c b/src/pcm/pcm.c
index f910189a..f3c2f743 100644
--- a/src/pcm/pcm.c
+++ b/src/pcm/pcm.c
@@ -2058,7 +2058,7 @@ static int snd_pcm_open_conf(snd_pcm_t **pcmp, const char *name,
const char *str;
char *buf = NULL, *buf1 = NULL;
int err;
- snd_config_t *conf, *type_conf = NULL;
+ snd_config_t *conf, *type_conf = NULL, *tmp;
snd_config_iterator_t i, next;
const char *id;
const char *lib = NULL, *open_name = NULL;
@@ -2191,6 +2191,12 @@ static int snd_pcm_open_conf(snd_pcm_t **pcmp, const char *name,
snd_dlclose(h);
}
}
+ if (err >= 0) {
+ err = snd_config_search(pcm_root, "defaults.pcm.minperiodtime", &tmp);
+ if (err >= 0)
+ snd_config_get_integer(tmp, &(*pcmp)->minperiodtime);
+ err = 0;
+ }
if (type_conf)
snd_config_delete(type_conf);
free(buf);
diff --git a/src/pcm/pcm_local.h b/src/pcm/pcm_local.h
index 9aa81e14..dda970c1 100644
--- a/src/pcm/pcm_local.h
+++ b/src/pcm/pcm_local.h
@@ -179,6 +179,7 @@ struct _snd_pcm {
snd_pcm_type_t type;
snd_pcm_stream_t stream;
int mode;
+ long minperiodtime; /* in us */
int poll_fd_count;
int poll_fd;
unsigned short poll_events;
diff --git a/src/pcm/pcm_params.c b/src/pcm/pcm_params.c
index 0e1c3fc5..6120677a 100644
--- a/src/pcm/pcm_params.c
+++ b/src/pcm/pcm_params.c
@@ -1102,8 +1102,19 @@ static int snd_pcm_hw_params_choose(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
if (err < 0)
return err;
err = snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_RATE, NULL, 0);
- if (err < 0)
return err;
+ if (pcm->minperiodtime > 0) {
+ unsigned int min, max;
+ int dir = 1;
+ err = snd_pcm_hw_param_get_min(params, SND_PCM_HW_PARAM_PERIOD_TIME, &min, &dir);
+ if (err >= 0)
+ err = snd_pcm_hw_param_get_max(params, SND_PCM_HW_PARAM_PERIOD_TIME, &max, &dir);
+ if (err >= 0 && (long)min < pcm->minperiodtime &&
+ (long)max > pcm->minperiodtime) {
+ min = pcm->minperiodtime; dir = 1;
+ snd_pcm_hw_param_set_min(pcm, params, SND_CHANGE, SND_PCM_HW_PARAM_PERIOD_TIME, &min, &dir);
+ }
+ }
if (compat && *compat) {
/* old mode */
err = snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_PERIOD_TIME, NULL, 0);