Fedora kernel-2.6.17-1.2142_FC4 patched with stable patch-2.6.17.4-vs2.0.2-rc26.diff
[linux-2.6.git] / sound / core / oss / rate.c
index 1096ec1..18d8a0f 100644 (file)
@@ -20,6 +20,9 @@
  */
   
 #include <sound/driver.h>
+
+#ifdef CONFIG_SND_PCM_OSS_PLUGINS
+
 #include <linux/time.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
  *  Basic rate conversion plugin
  */
 
-typedef struct {
+struct rate_channel {
        signed short last_S1;
        signed short last_S2;
-} rate_channel_t;
+};
  
-typedef void (*rate_f)(snd_pcm_plugin_t *plugin,
-                      const snd_pcm_plugin_channel_t *src_channels,
-                      snd_pcm_plugin_channel_t *dst_channels,
+typedef void (*rate_f)(struct snd_pcm_plugin *plugin,
+                      const struct snd_pcm_plugin_channel *src_channels,
+                      struct snd_pcm_plugin_channel *dst_channels,
                       int src_frames, int dst_frames);
 
-typedef struct rate_private_data {
+struct rate_priv {
        unsigned int pitch;
        unsigned int pos;
        rate_f func;
-       int get, put;
        snd_pcm_sframes_t old_src_frames, old_dst_frames;
-       rate_channel_t channels[0];
-} rate_t;
+       struct rate_channel channels[0];
+};
 
-static void rate_init(snd_pcm_plugin_t *plugin)
+static void rate_init(struct snd_pcm_plugin *plugin)
 {
        unsigned int channel;
-       rate_t *data = (rate_t *)plugin->extra_data;
+       struct rate_priv *data = (struct rate_priv *)plugin->extra_data;
        data->pos = 0;
        for (channel = 0; channel < plugin->src_format.channels; channel++) {
                data->channels[channel].last_S1 = 0;
@@ -63,29 +65,20 @@ static void rate_init(snd_pcm_plugin_t *plugin)
        }
 }
 
-static void resample_expand(snd_pcm_plugin_t *plugin,
-                           const snd_pcm_plugin_channel_t *src_channels,
-                           snd_pcm_plugin_channel_t *dst_channels,
+static void resample_expand(struct snd_pcm_plugin *plugin,
+                           const struct snd_pcm_plugin_channel *src_channels,
+                           struct snd_pcm_plugin_channel *dst_channels,
                            int src_frames, int dst_frames)
 {
        unsigned int pos = 0;
        signed int val;
        signed short S1, S2;
-       char *src, *dst;
+       signed short *src, *dst;
        unsigned int channel;
        int src_step, dst_step;
        int src_frames1, dst_frames1;
-       rate_t *data = (rate_t *)plugin->extra_data;
-       rate_channel_t *rchannels = data->channels;
-
-#define GET_S16_LABELS
-#define PUT_S16_LABELS
-#include "plugin_ops.h"
-#undef GET_S16_LABELS
-#undef PUT_S16_LABELS
-       void *get = get_s16_labels[data->get];
-       void *put = put_s16_labels[data->put];
-       signed short sample = 0;
+       struct rate_priv *data = (struct rate_priv *)plugin->extra_data;
+       struct rate_channel *rchannels = data->channels;
        
        for (channel = 0; channel < plugin->src_format.channels; channel++) {
                pos = data->pos;
@@ -98,10 +91,12 @@ static void resample_expand(snd_pcm_plugin_t *plugin,
                        continue;
                }
                dst_channels[channel].enabled = 1;
-               src = (char *)src_channels[channel].area.addr + src_channels[channel].area.first / 8;
-               dst = (char *)dst_channels[channel].area.addr + dst_channels[channel].area.first / 8;
-               src_step = src_channels[channel].area.step / 8;
-               dst_step = dst_channels[channel].area.step / 8;
+               src = (signed short *)src_channels[channel].area.addr +
+                       src_channels[channel].area.first / 8 / 2;
+               dst = (signed short *)dst_channels[channel].area.addr +
+                       dst_channels[channel].area.first / 8 / 2;
+               src_step = src_channels[channel].area.step / 8 / 2;
+               dst_step = dst_channels[channel].area.step / 8 / 2;
                src_frames1 = src_frames;
                dst_frames1 = dst_frames;
                while (dst_frames1-- > 0) {
@@ -109,12 +104,7 @@ static void resample_expand(snd_pcm_plugin_t *plugin,
                                pos &= R_MASK;
                                S1 = S2;
                                if (src_frames1-- > 0) {
-                                       goto *get;
-#define GET_S16_END after_get
-#include "plugin_ops.h"
-#undef GET_S16_END
-                               after_get:
-                                       S2 = sample;
+                                       S2 = *src;
                                        src += src_step;
                                }
                        }
@@ -123,12 +113,7 @@ static void resample_expand(snd_pcm_plugin_t *plugin,
                                val = -32768;
                        else if (val > 32767)
                                val = 32767;
-                       sample = val;
-                       goto *put;
-#define PUT_S16_END after_put
-#include "plugin_ops.h"
-#undef PUT_S16_END
-               after_put:
+                       *dst = val;
                        dst += dst_step;
                        pos += data->pitch;
                }
@@ -139,29 +124,20 @@ static void resample_expand(snd_pcm_plugin_t *plugin,
        data->pos = pos;
 }
 
-static void resample_shrink(snd_pcm_plugin_t *plugin,
-                           const snd_pcm_plugin_channel_t *src_channels,
-                           snd_pcm_plugin_channel_t *dst_channels,
+static void resample_shrink(struct snd_pcm_plugin *plugin,
+                           const struct snd_pcm_plugin_channel *src_channels,
+                           struct snd_pcm_plugin_channel *dst_channels,
                            int src_frames, int dst_frames)
 {
        unsigned int pos = 0;
        signed int val;
        signed short S1, S2;
-       char *src, *dst;
+       signed short *src, *dst;
        unsigned int channel;
        int src_step, dst_step;
        int src_frames1, dst_frames1;
-       rate_t *data = (rate_t *)plugin->extra_data;
-       rate_channel_t *rchannels = data->channels;
-       
-#define GET_S16_LABELS
-#define PUT_S16_LABELS
-#include "plugin_ops.h"
-#undef GET_S16_LABELS
-#undef PUT_S16_LABELS
-       void *get = get_s16_labels[data->get];
-       void *put = put_s16_labels[data->put];
-       signed short sample = 0;
+       struct rate_priv *data = (struct rate_priv *)plugin->extra_data;
+       struct rate_channel *rchannels = data->channels;
 
        for (channel = 0; channel < plugin->src_format.channels; ++channel) {
                pos = data->pos;
@@ -174,21 +150,18 @@ static void resample_shrink(snd_pcm_plugin_t *plugin,
                        continue;
                }
                dst_channels[channel].enabled = 1;
-               src = (char *)src_channels[channel].area.addr + src_channels[channel].area.first / 8;
-               dst = (char *)dst_channels[channel].area.addr + dst_channels[channel].area.first / 8;
-               src_step = src_channels[channel].area.step / 8;
-               dst_step = dst_channels[channel].area.step / 8;
+               src = (signed short *)src_channels[channel].area.addr +
+                       src_channels[channel].area.first / 8 / 2;
+               dst = (signed short *)dst_channels[channel].area.addr +
+                       dst_channels[channel].area.first / 8 / 2;
+               src_step = src_channels[channel].area.step / 8 / 2;
+               dst_step = dst_channels[channel].area.step / 8 / 2;
                src_frames1 = src_frames;
                dst_frames1 = dst_frames;
                while (dst_frames1 > 0) {
                        S1 = S2;
                        if (src_frames1-- > 0) {
-                               goto *get;
-#define GET_S16_END after_get
-#include "plugin_ops.h"
-#undef GET_S16_END
-                       after_get:
-                               S2 = sample;
+                               S1 = *src;
                                src += src_step;
                        }
                        if (pos & ~R_MASK) {
@@ -198,12 +171,7 @@ static void resample_shrink(snd_pcm_plugin_t *plugin,
                                        val = -32768;
                                else if (val > 32767)
                                        val = 32767;
-                               sample = val;
-                               goto *put;
-#define PUT_S16_END after_put
-#include "plugin_ops.h"
-#undef PUT_S16_END
-                       after_put:
+                               *dst = val;
                                dst += dst_step;
                                dst_frames1--;
                        }
@@ -216,15 +184,15 @@ static void resample_shrink(snd_pcm_plugin_t *plugin,
        data->pos = pos;
 }
 
-static snd_pcm_sframes_t rate_src_frames(snd_pcm_plugin_t *plugin, snd_pcm_uframes_t frames)
+static snd_pcm_sframes_t rate_src_frames(struct snd_pcm_plugin *plugin, snd_pcm_uframes_t frames)
 {
-       rate_t *data;
+       struct rate_priv *data;
        snd_pcm_sframes_t res;
 
        snd_assert(plugin != NULL, return -ENXIO);
        if (frames == 0)
                return 0;
-       data = (rate_t *)plugin->extra_data;
+       data = (struct rate_priv *)plugin->extra_data;
        if (plugin->src_format.rate < plugin->dst_format.rate) {
                res = (((frames * data->pitch) + (BITS/2)) >> SHIFT);
        } else {
@@ -248,15 +216,15 @@ static snd_pcm_sframes_t rate_src_frames(snd_pcm_plugin_t *plugin, snd_pcm_ufram
        return res;
 }
 
-static snd_pcm_sframes_t rate_dst_frames(snd_pcm_plugin_t *plugin, snd_pcm_uframes_t frames)
+static snd_pcm_sframes_t rate_dst_frames(struct snd_pcm_plugin *plugin, snd_pcm_uframes_t frames)
 {
-       rate_t *data;
+       struct rate_priv *data;
        snd_pcm_sframes_t res;
 
        snd_assert(plugin != NULL, return -ENXIO);
        if (frames == 0)
                return 0;
-       data = (rate_t *)plugin->extra_data;
+       data = (struct rate_priv *)plugin->extra_data;
        if (plugin->src_format.rate < plugin->dst_format.rate) {
                res = (((frames << SHIFT) + (data->pitch / 2)) / data->pitch);
        } else {
@@ -280,13 +248,13 @@ static snd_pcm_sframes_t rate_dst_frames(snd_pcm_plugin_t *plugin, snd_pcm_ufram
        return res;
 }
 
-static snd_pcm_sframes_t rate_transfer(snd_pcm_plugin_t *plugin,
-                            const snd_pcm_plugin_channel_t *src_channels,
-                            snd_pcm_plugin_channel_t *dst_channels,
+static snd_pcm_sframes_t rate_transfer(struct snd_pcm_plugin *plugin,
+                            const struct snd_pcm_plugin_channel *src_channels,
+                            struct snd_pcm_plugin_channel *dst_channels,
                             snd_pcm_uframes_t frames)
 {
        snd_pcm_uframes_t dst_frames;
-       rate_t *data;
+       struct rate_priv *data;
 
        snd_assert(plugin != NULL && src_channels != NULL && dst_channels != NULL, return -ENXIO);
        if (frames == 0)
@@ -308,14 +276,14 @@ static snd_pcm_sframes_t rate_transfer(snd_pcm_plugin_t *plugin,
        dst_frames = rate_dst_frames(plugin, frames);
        if (dst_frames > dst_channels[0].frames)
                dst_frames = dst_channels[0].frames;
-       data = (rate_t *)plugin->extra_data;
+       data = (struct rate_priv *)plugin->extra_data;
        data->func(plugin, src_channels, dst_channels, frames, dst_frames);
        return dst_frames;
 }
 
-static int rate_action(snd_pcm_plugin_t *plugin,
-                      snd_pcm_plugin_action_t action,
-                      unsigned long udata ATTRIBUTE_UNUSED)
+static int rate_action(struct snd_pcm_plugin *plugin,
+                      enum snd_pcm_plugin_action action,
+                      unsigned long udata)
 {
        snd_assert(plugin != NULL, return -ENXIO);
        switch (action) {
@@ -329,36 +297,32 @@ static int rate_action(snd_pcm_plugin_t *plugin,
        return 0;       /* silenty ignore other actions */
 }
 
-int snd_pcm_plugin_build_rate(snd_pcm_plug_t *plug,
-                             snd_pcm_plugin_format_t *src_format,
-                             snd_pcm_plugin_format_t *dst_format,
-                             snd_pcm_plugin_t **r_plugin)
+int snd_pcm_plugin_build_rate(struct snd_pcm_substream *plug,
+                             struct snd_pcm_plugin_format *src_format,
+                             struct snd_pcm_plugin_format *dst_format,
+                             struct snd_pcm_plugin **r_plugin)
 {
        int err;
-       rate_t *data;
-       snd_pcm_plugin_t *plugin;
+       struct rate_priv *data;
+       struct snd_pcm_plugin *plugin;
 
        snd_assert(r_plugin != NULL, return -ENXIO);
        *r_plugin = NULL;
 
        snd_assert(src_format->channels == dst_format->channels, return -ENXIO);
        snd_assert(src_format->channels > 0, return -ENXIO);
-       snd_assert(snd_pcm_format_linear(src_format->format) != 0, return -ENXIO);
-       snd_assert(snd_pcm_format_linear(dst_format->format) != 0, return -ENXIO);
+       snd_assert(src_format->format == SNDRV_PCM_FORMAT_S16, return -ENXIO);
+       snd_assert(dst_format->format == SNDRV_PCM_FORMAT_S16, return -ENXIO);
        snd_assert(src_format->rate != dst_format->rate, return -ENXIO);
 
        err = snd_pcm_plugin_build(plug, "rate conversion",
                                   src_format, dst_format,
-                                  sizeof(rate_t) + src_format->channels * sizeof(rate_channel_t),
+                                  sizeof(struct rate_priv) +
+                                  src_format->channels * sizeof(struct rate_channel),
                                   &plugin);
        if (err < 0)
                return err;
-       data = (rate_t *)plugin->extra_data;
-       data->get = getput_index(src_format->format);
-       snd_assert(data->get >= 0 && data->get < 4*2*2, return -EINVAL);
-       data->put = getput_index(dst_format->format);
-       snd_assert(data->put >= 0 && data->put < 4*2*2, return -EINVAL);
-
+       data = (struct rate_priv *)plugin->extra_data;
        if (src_format->rate < dst_format->rate) {
                data->pitch = ((src_format->rate << SHIFT) + (dst_format->rate >> 1)) / dst_format->rate;
                data->func = resample_expand;
@@ -376,3 +340,5 @@ int snd_pcm_plugin_build_rate(snd_pcm_plug_t *plug,
        *r_plugin = plugin;
        return 0;
 }
+
+#endif