Update of /cvsroot/alsa/alsa-oss
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv4508

Modified Files:
        alsa-oss.c 
Log Message:
A try to fixed the problem when period_size and buffer_size is not power of two.
Added suspend/resume support to read/write functions.


Index: alsa-oss.c
===================================================================
RCS file: /cvsroot/alsa/alsa-oss/alsa-oss.c,v
retrieving revision 1.41
retrieving revision 1.42
diff -u -r1.41 -r1.42
--- alsa-oss.c  1 Dec 2003 14:06:23 -0000       1.41
+++ alsa-oss.c  7 Feb 2004 15:02:41 -0000       1.42
@@ -42,6 +42,7 @@
 snd_pcm_uframes_t _snd_pcm_mmap_hw_ptr(snd_pcm_t *pcm);
 
 static int debug = 0;
+static snd_output_t *debug_out = NULL;
 
 #if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95)
 #define NEW_MACRO_VARARGS
@@ -213,14 +214,15 @@
                err = snd_pcm_hw_params_set_channels(pcm, hw, dsp->channels);
                if (err < 0)
                        return err;
-
-               err = snd_pcm_hw_params_set_periods_integer(pcm, hw);
-               if (err < 0)
-                       return err;
                rate = dsp->rate;
                err = snd_pcm_hw_params_set_rate_near(pcm, hw, &rate, 0);
                if (err < 0)
                        return err;
+#if 0
+               err = snd_pcm_hw_params_set_periods_integer(pcm, hw);
+               if (err < 0)
+                       return err;
+#endif
 
                if (str->mmap_buffer) {
                        snd_pcm_access_mask_t *mask;
@@ -258,12 +260,31 @@
                        }
                        if (dsp->fragshift > 0) {
                                snd_pcm_uframes_t s = (1 << dsp->fragshift) / 
str->frame_bytes;
-                               err = snd_pcm_hw_params_set_period_size_near(pcm, hw, 
&s, 0);
+                               s *= 16;
+                               while (s >= 1024 && (err = 
snd_pcm_hw_params_set_buffer_size(pcm, hw, s)) < 0)
+                                       s /= 2;
+                               s = (1 << dsp->fragshift) / str->frame_bytes;
+                               while (s >= 256 && (err = 
snd_pcm_hw_params_set_period_size(pcm, hw, s, 0)) < 0)
+                                       s /= 2;
+                               if (err < 0) {
+                                       s = (1 << dsp->fragshift) / str->frame_bytes;
+                                       err = 
snd_pcm_hw_params_set_period_size_near(pcm, hw, &s, 0);
+                               }
+                               fprintf(stderr, "set period size = %li, err = %i\n", 
s, err);
                        } else {
-                               snd_pcm_uframes_t s = 16;
-                               while (s * 2 < dsp->rate / 4) 
+                               snd_pcm_uframes_t s = 16, old_s;
+                               while (s * 2 < dsp->rate / 2) 
                                        s *= 2;
-                               err = snd_pcm_hw_params_set_period_size_near(pcm, hw, 
&s, 0);
+                               old_s = s = s / 2;
+                               while (s >= 1024 && (err = 
snd_pcm_hw_params_set_buffer_size(pcm, hw, s)) < 0)
+                                       s /= 2;
+                               s = old_s;
+                               while (s >= 256 && (err = 
snd_pcm_hw_params_set_period_size(pcm, hw, s, 0)) < 0)
+                                       s /= 2;
+                               if (err < 0) {
+                                       s = old_s;
+                                       err = 
snd_pcm_hw_params_set_period_size_near(pcm, hw, &s, 0);
+                               }
                        }
                        if (err < 0)
                                return err;
@@ -351,6 +372,16 @@
        err = oss_dsp_sw_params(dsp);
        if (err < 0) 
                return err;
+#if 0
+       if (debug && debug_out) {
+               int k;
+               for (k = 1; k >= 0; --k) {
+                       oss_dsp_stream_t *str = &dsp->streams[k];
+                       if (str->pcm)
+                               snd_pcm_dump(str->pcm, debug_out);
+               }
+       }
+#endif
        return 0;
 }
 
@@ -395,6 +426,10 @@
        int result;
        char name[64];
 
+       if (debug_out == NULL) {
+               if (snd_output_stdio_attach(&debug_out, stderr, 0) < 0)
+                       debug_out = NULL;
+       }
        switch (device) {
        case OSS_DEVICE_DSP:
                format = AFMT_U8;
@@ -714,6 +749,13 @@
            snd_pcm_state(pcm) == SND_PCM_STATE_XRUN &&
            (result = snd_pcm_prepare(pcm)) == 0)
                goto _again;
+       if (result == -EPIPE && 
+           snd_pcm_state(pcm) == SND_PCM_STATE_SUSPENDED) {
+               while ((result = snd_pcm_resume(pcm)) == -EAGAIN)
+                       sleep(1);
+               if (result < 0 && (result = snd_pcm_prepare(pcm)) == 0)
+                       goto _again;
+       }
        if (result < 0) {
                errno = -result;
                result = -1;
@@ -749,6 +791,13 @@
            snd_pcm_state(pcm) == SND_PCM_STATE_XRUN &&
            (result = snd_pcm_prepare(pcm)) == 0)
                goto _again;
+       if (result == -EPIPE && 
+           snd_pcm_state(pcm) == SND_PCM_STATE_SUSPENDED) {
+               while ((result = snd_pcm_resume(pcm)) == -EAGAIN)
+                       sleep(1);
+               if (result < 0 && (result = snd_pcm_prepare(pcm)) == 0)
+                       goto _again;
+       }
        if (result < 0) {
                errno = -result;
                result = -1;



-------------------------------------------------------
The SF.Net email is sponsored by EclipseCon 2004
Premiere Conference on Open Tools Development and Integration
See the breadth of Eclipse activity. February 3-5 in Anaheim, CA.
http://www.eclipsecon.org/osdn
_______________________________________________
Alsa-cvslog mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/alsa-cvslog

Reply via email to