]> git.alsa-project.org Git - alsa-lib.git/commitdiff
pcm: add defaults.pcm.minperiodtime parsing
authorJaroslav Kysela <perex@perex.cz>
Wed, 11 Aug 2010 17:45:40 +0000 (19:45 +0200)
committerJaroslav Kysela <perex@perex.cz>
Wed, 11 Aug 2010 17:55:15 +0000 (19:55 +0200)
Some broken applications like Audacious don't set any timing parameters.
While the alsa-lib behaviour is to select the smallest period size and
biggest buffer size, the result is the generation of thousands
interrupts per second.

The default value in alsa.conf is 5000usec.

Signed-off-by: Jaroslav Kysela <perex@perex.cz>
src/conf/alsa.conf
src/pcm/pcm.c
src/pcm/pcm_local.h
src/pcm/pcm_params.c

index db6425976e79fdae354acdfe89441904d6deaff9..516052908eb742ca48f0ffd86c6b2614815d759e 100644 (file)
@@ -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
index f910189a45e168cc4e94bfdbe3cf7374c1235125..f3c2f743363862617eb937b8718749eed4d8e816 100644 (file)
@@ -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);
index 9aa81e1422bcc61e3fe5cf4fecfe6d6bfa1eea1a..dda970c15746e185cf25da0150952603354c06b8 100644 (file)
@@ -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;
index 0e1c3fc506943046fd259f7562bd2d024bfb1956..6120677a6030a2ec591875f2d3305afbb4f31384 100644 (file)
@@ -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);