X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=sound%2Fcore%2Foss%2Frate.c;h=18d8a0f4e8168a0b145b2179673f24a1b1c29f48;hb=43bc926fffd92024b46cafaf7350d669ba9ca884;hp=1096ec186714065bf78d1e662d14e5489874b07a;hpb=cee37fe97739d85991964371c1f3a745c00dd236;p=linux-2.6.git diff --git a/sound/core/oss/rate.c b/sound/core/oss/rate.c index 1096ec186..18d8a0f4e 100644 --- a/sound/core/oss/rate.c +++ b/sound/core/oss/rate.c @@ -20,6 +20,9 @@ */ #include + +#ifdef CONFIG_SND_PCM_OSS_PLUGINS + #include #include #include @@ -33,29 +36,28 @@ * 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