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

Modified Files:
        pcm_plugin.c 
Log Message:
Clean up and optimization of PCM format-specific functions.

- Use array indexing instead of huge swith/case.
- Removed superfluous handling of floats.
- Use memcpy for silencing to simplify the codes.



Index: pcm_plugin.c
===================================================================
RCS file: /cvsroot/alsa/alsa-kernel/core/oss/pcm_plugin.c,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -r1.18 -r1.19
--- pcm_plugin.c        5 Feb 2004 15:38:42 -0000       1.18
+++ pcm_plugin.c        9 Jun 2004 17:36:14 -0000       1.19
@@ -846,41 +846,31 @@
                         size_t samples, int format)
 {
        /* FIXME: sub byte resolution and odd dst_offset */
-       char *dst;
+       unsigned char *dst;
        unsigned int dst_step;
        int width;
-       u_int64_t silence;
+       const unsigned char *silence;
        if (!dst_area->addr)
                return 0;
        dst = dst_area->addr + (dst_area->first + dst_area->step * dst_offset) / 8;
        width = snd_pcm_format_physical_width(format);
+       if (width <= 0)
+               return -EINVAL;
+       if (dst_area->step == (unsigned int) width && width >= 8)
+               return snd_pcm_format_set_silence(format, dst, samples);
        silence = snd_pcm_format_silence_64(format);
-       if (dst_area->step == (unsigned int) width) {
-               size_t dwords = samples * width / 64;
-               u_int64_t *dst64 = (u_int64_t *)dst;
-
-               samples -= dwords * 64 / width;
-               while (dwords-- > 0)
-                       *dst64++ = silence;
-               if (samples == 0)
-                       return 0;
-               dst = (char *)dst64;
-       }
+       if (! silence)
+               return -EINVAL;
        dst_step = dst_area->step / 8;
-       switch (width) {
-       case 4: {
-               u_int8_t s0 = silence & 0xf0;
-               u_int8_t s1 = silence & 0x0f;
+       if (width == 4) {
+               /* Ima ADPCM */
                int dstbit = dst_area->first % 8;
                int dstbit_step = dst_area->step % 8;
                while (samples-- > 0) {
-                       if (dstbit) {
+                       if (dstbit)
                                *dst &= 0xf0;
-                               *dst |= s1;
-                       } else {
+                       else
                                *dst &= 0x0f;
-                               *dst |= s0;
-                       }
                        dst += dst_step;
                        dstbit += dstbit_step;
                        if (dstbit == 8) {
@@ -888,41 +878,12 @@
                                dstbit = 0;
                        }
                }
-               break;
-       }
-       case 8: {
-               u_int8_t sil = silence;
-               while (samples-- > 0) {
-                       *dst = sil;
-                       dst += dst_step;
-               }
-               break;
-       }
-       case 16: {
-               u_int16_t sil = silence;
-               while (samples-- > 0) {
-                       *(u_int16_t*)dst = sil;
-                       dst += dst_step;
-               }
-               break;
-       }
-       case 32: {
-               u_int32_t sil = silence;
-               while (samples-- > 0) {
-                       *(u_int32_t*)dst = sil;
-                       dst += dst_step;
-               }
-               break;
-       }
-       case 64: {
+       } else {
+               width /= 8;
                while (samples-- > 0) {
-                       *(u_int64_t*)dst = silence;
+                       memcpy(dst, silence, width);
                        dst += dst_step;
                }
-               break;
-       }
-       default:
-               snd_BUG();
        }
        return 0;
 }
@@ -942,18 +903,18 @@
        if (!dst_area->addr)
                return 0;
        width = snd_pcm_format_physical_width(format);
+       if (width <= 0)
+               return -EINVAL;
        if (src_area->step == (unsigned int) width &&
-           dst_area->step == (unsigned int) width) {
+           dst_area->step == (unsigned int) width && width >= 8) {
                size_t bytes = samples * width / 8;
-               samples -= bytes * 8 / width;
                memcpy(dst, src, bytes);
-               if (samples == 0)
-                       return 0;
+               return 0;
        }
        src_step = src_area->step / 8;
        dst_step = dst_area->step / 8;
-       switch (width) {
-       case 4: {
+       if (width == 4) {
+               /* Ima ADPCM */
                int srcbit = src_area->first % 8;
                int srcbit_step = src_area->step % 8;
                int dstbit = dst_area->first % 8;
@@ -963,12 +924,11 @@
                        if (srcbit)
                                srcval = *src & 0x0f;
                        else
-                               srcval = *src & 0xf0;
+                               srcval = (*src & 0xf0) >> 4;
                        if (dstbit)
-                               *dst &= 0xf0;
+                               *dst = (*dst & 0xf0) | srcval;
                        else
-                               *dst &= 0x0f;
-                       *dst |= srcval;
+                               *dst = (*dst & 0x0f) | (srcval << 4);
                        src += src_step;
                        srcbit += srcbit_step;
                        if (srcbit == 8) {
@@ -982,42 +942,13 @@
                                dstbit = 0;
                        }
                }
-               break;
-       }
-       case 8: {
-               while (samples-- > 0) {
-                       *dst = *src;
-                       src += src_step;
-                       dst += dst_step;
-               }
-               break;
-       }
-       case 16: {
+       } else {
+               width /= 8;
                while (samples-- > 0) {
-                       *(u_int16_t*)dst = *(u_int16_t*)src;
+                       memcpy(dst, src, width);
                        src += src_step;
                        dst += dst_step;
                }
-               break;
-       }
-       case 32: {
-               while (samples-- > 0) {
-                       *(u_int32_t*)dst = *(u_int32_t*)src;
-                       src += src_step;
-                       dst += dst_step;
-               }
-               break;
-       }
-       case 64: {
-               while (samples-- > 0) {
-                       *(u_int64_t*)dst = *(u_int64_t*)src;
-                       src += src_step;
-                       dst += dst_step;
-               }
-               break;
-       }
-       default:
-               snd_BUG();
        }
        return 0;
 }



-------------------------------------------------------
This SF.Net email is sponsored by: GNOME Foundation
Hackers Unite!  GUADEC: The world's #1 Open Source Desktop Event.
GNOME Users and Developers European Conference, 28-30th June in Norway
http://2004/guadec.org
_______________________________________________
Alsa-cvslog mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/alsa-cvslog

Reply via email to