vserver 1.9.3
[linux-2.6.git] / sound / core / oss / pcm_plugin.c
index 6fd63ca..855071f 100644 (file)
@@ -172,7 +172,7 @@ int snd_pcm_plugin_build(snd_pcm_plug_t *plug,
        
        snd_assert(plug != NULL, return -ENXIO);
        snd_assert(src_format != NULL && dst_format != NULL, return -ENXIO);
-       plugin = (snd_pcm_plugin_t *)snd_kcalloc(sizeof(*plugin) + extra, GFP_KERNEL);
+       plugin = kcalloc(1, sizeof(*plugin) + extra, GFP_KERNEL);
        if (plugin == NULL)
                return -ENOMEM;
        plugin->name = name;
@@ -189,7 +189,7 @@ int snd_pcm_plugin_build(snd_pcm_plug_t *plug,
                channels = src_format->channels;
        else
                channels = dst_format->channels;
-       plugin->buf_channels = snd_kcalloc(channels * sizeof(*plugin->buf_channels), GFP_KERNEL);
+       plugin->buf_channels = kcalloc(channels, sizeof(*plugin->buf_channels), GFP_KERNEL);
        if (plugin->buf_channels == NULL) {
                snd_pcm_plugin_free(plugin);
                return -ENOMEM;
@@ -370,7 +370,7 @@ int snd_pcm_plug_slave_format(int format, snd_mask_t *format_mask)
                unsigned int i;
                switch (format) {
                case SNDRV_PCM_FORMAT_MU_LAW:
-                       for (i = 0; i < sizeof(preferred_formats) / sizeof(preferred_formats[0]); ++i) {
+                       for (i = 0; i < ARRAY_SIZE(preferred_formats); ++i) {
                                int format1 = preferred_formats[i];
                                if (snd_mask_test(format_mask, format1))
                                        return format1;
@@ -468,7 +468,7 @@ int snd_pcm_plug_format_plugins(snd_pcm_plug_t *plug,
        if (srcformat.channels > dstformat.channels) {
                int sv = srcformat.channels;
                int dv = dstformat.channels;
-               route_ttable_entry_t *ttable = snd_kcalloc(dv*sv*sizeof(*ttable), GFP_KERNEL);
+               route_ttable_entry_t *ttable = kcalloc(dv * sv, sizeof(*ttable), GFP_KERNEL);
                if (ttable == NULL)
                        return -ENOMEM;
 #if 1
@@ -531,7 +531,7 @@ int snd_pcm_plug_format_plugins(snd_pcm_plug_t *plug,
        if (srcformat.channels < dstformat.channels) {
                int sv = srcformat.channels;
                int dv = dstformat.channels;
-               route_ttable_entry_t *ttable = snd_kcalloc(dv * sv * sizeof(*ttable), GFP_KERNEL);
+               route_ttable_entry_t *ttable = kcalloc(dv * sv, sizeof(*ttable), GFP_KERNEL);
                if (ttable == NULL)
                        return -ENOMEM;
 #if 0
@@ -846,41 +846,31 @@ int snd_pcm_area_silence(const snd_pcm_channel_area_t *dst_area, size_t dst_offs
                         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 @@ int snd_pcm_area_silence(const snd_pcm_channel_area_t *dst_area, size_t dst_offs
                                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 @@ int snd_pcm_area_copy(const snd_pcm_channel_area_t *src_area, size_t src_offset,
        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 @@ int snd_pcm_area_copy(const snd_pcm_channel_area_t *src_area, size_t src_offset,
                        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 @@ int snd_pcm_area_copy(const snd_pcm_channel_area_t *src_area, size_t src_offset,
                                dstbit = 0;
                        }
                }
-               break;
-       }
-       case 8: {
-               while (samples-- > 0) {
-                       *dst = *src;
-                       src += src_step;
-                       dst += dst_step;
-               }
-               break;
-       }
-       case 16: {
-               while (samples-- > 0) {
-                       *(u_int16_t*)dst = *(u_int16_t*)src;
-                       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: {
+       } else {
+               width /= 8;
                while (samples-- > 0) {
-                       *(u_int64_t*)dst = *(u_int64_t*)src;
+                       memcpy(dst, src, width);
                        src += src_step;
                        dst += dst_step;
                }
-               break;
-       }
-       default:
-               snd_BUG();
        }
        return 0;
 }