]> code.delx.au - pulseaudio/commitdiff
alsa: revert to first set number of periods, then set buffer size
authorLennart Poettering <lennart@poettering.net>
Fri, 31 Jul 2009 00:07:24 +0000 (02:07 +0200)
committerLennart Poettering <lennart@poettering.net>
Fri, 31 Jul 2009 00:07:24 +0000 (02:07 +0200)
Apparently some ALSA drivers aren't happy with getting the buffer size
configured first followed the period size. So swap the order again and
document this for future reference so that we don't turn that around
again.

src/modules/alsa/alsa-util.c

index 1f3e5dcd8b8e4a12473da21d0d0c660b7567e62a..a47a8958bfcc9407cd11ee8cb4d08b543cc1e2bc 100644 (file)
@@ -233,14 +233,16 @@ int pa_alsa_set_hw_params(
         goto finish;
     }
 
-    if (_period_size && tsched_size && _periods) {
+    if (_period_size > 0 && tsched_size > 0 && _periods > 0) {
+        snd_pcm_uframes_t buffer_size;
+        unsigned int p;
 
         /* Adjust the buffer sizes, if we didn't get the rate we were asking for */
         _period_size = (snd_pcm_uframes_t) (((uint64_t) _period_size * r) / ss->rate);
         tsched_size = (snd_pcm_uframes_t) (((uint64_t) tsched_size * r) / ss->rate);
 
         if (_use_tsched) {
-            snd_pcm_uframes_t buffer_size = 0;
+            buffer_size = 0;
 
             if ((ret = snd_pcm_hw_params_get_buffer_size_max(hwparams, &buffer_size)) < 0)
                 pa_log_warn("snd_pcm_hw_params_get_buffer_size_max() failed: %s", pa_alsa_strerror(ret));
@@ -251,32 +253,33 @@ int pa_alsa_set_hw_params(
             _periods = 1;
         }
 
-        if (_period_size > 0 && _periods > 0) {
-            snd_pcm_uframes_t buffer_size;
-
-            buffer_size = _periods * _period_size;
-
-            if ((ret = snd_pcm_hw_params_set_buffer_size_near(pcm_handle, hwparams, &buffer_size)) < 0)
-                pa_log_info("snd_pcm_hw_params_set_buffer_size_near() failed: %s", pa_alsa_strerror(ret));
-        }
-
-        if (_periods > 0) {
-
-            /* First we pass 0 as direction to get exactly what we
-             * asked for. That this is necessary is presumably a bug
-             * in ALSA. All in all this is mostly a hint to ALSA, so
-             * we don't care if this fails. */
-
-            dir = 0;
-            if (snd_pcm_hw_params_set_periods_near(pcm_handle, hwparams, &_periods, &dir) < 0) {
-                dir = 1;
-                if (snd_pcm_hw_params_set_periods_near(pcm_handle, hwparams, &_periods, &dir) < 0) {
-                    dir = -1;
-                    if ((ret = snd_pcm_hw_params_set_periods_near(pcm_handle, hwparams, &_periods, &dir)) < 0)
-                        pa_log_info("snd_pcm_hw_params_set_periods_near() failed: %s", pa_alsa_strerror(ret));
-                }
+        /* Some ALSA drivers really don't like if we set the buffer
+         * size first and the number of periods second. (which would
+         * make a lot more sense to me) So, follow this rule and
+         * adjust the periods first and the buffer size second */
+
+        /* First we pass 0 as direction to get exactly what we
+         * asked for. That this is necessary is presumably a bug
+         * in ALSA. All in all this is mostly a hint to ALSA, so
+         * we don't care if this fails. */
+
+        p = _periods;
+        dir = 0;
+        if (snd_pcm_hw_params_set_periods_near(pcm_handle, hwparams, &p, &dir) < 0) {
+            p = _periods;
+            dir = 1;
+            if (snd_pcm_hw_params_set_periods_near(pcm_handle, hwparams, &p, &dir) < 0) {
+                p = _periods;
+                dir = -1;
+                if ((ret = snd_pcm_hw_params_set_periods_near(pcm_handle, hwparams, &p, &dir)) < 0)
+                    pa_log_info("snd_pcm_hw_params_set_periods_near() failed: %s", pa_alsa_strerror(ret));
             }
         }
+
+        /* Now set the buffer size */
+        buffer_size = _periods * _period_size;
+        if ((ret = snd_pcm_hw_params_set_buffer_size_near(pcm_handle, hwparams, &buffer_size)) < 0)
+            pa_log_info("snd_pcm_hw_params_set_buffer_size_near() failed: %s", pa_alsa_strerror(ret));
     }
 
     if  ((ret = snd_pcm_hw_params(pcm_handle, hwparams)) < 0)