diff options
Diffstat (limited to 'sound/core/oss/rate.c')
-rw-r--r-- | sound/core/oss/rate.c | 85 |
1 files changed, 25 insertions, 60 deletions
diff --git a/sound/core/oss/rate.c b/sound/core/oss/rate.c index 4854cef6fb4f..18d8a0f4e816 100644 --- a/sound/core/oss/rate.c +++ b/sound/core/oss/rate.c | |||
@@ -20,6 +20,9 @@ | |||
20 | */ | 20 | */ |
21 | 21 | ||
22 | #include <sound/driver.h> | 22 | #include <sound/driver.h> |
23 | |||
24 | #ifdef CONFIG_SND_PCM_OSS_PLUGINS | ||
25 | |||
23 | #include <linux/time.h> | 26 | #include <linux/time.h> |
24 | #include <sound/core.h> | 27 | #include <sound/core.h> |
25 | #include <sound/pcm.h> | 28 | #include <sound/pcm.h> |
@@ -47,7 +50,6 @@ struct rate_priv { | |||
47 | unsigned int pitch; | 50 | unsigned int pitch; |
48 | unsigned int pos; | 51 | unsigned int pos; |
49 | rate_f func; | 52 | rate_f func; |
50 | int get, put; | ||
51 | snd_pcm_sframes_t old_src_frames, old_dst_frames; | 53 | snd_pcm_sframes_t old_src_frames, old_dst_frames; |
52 | struct rate_channel channels[0]; | 54 | struct rate_channel channels[0]; |
53 | }; | 55 | }; |
@@ -71,21 +73,12 @@ static void resample_expand(struct snd_pcm_plugin *plugin, | |||
71 | unsigned int pos = 0; | 73 | unsigned int pos = 0; |
72 | signed int val; | 74 | signed int val; |
73 | signed short S1, S2; | 75 | signed short S1, S2; |
74 | char *src, *dst; | 76 | signed short *src, *dst; |
75 | unsigned int channel; | 77 | unsigned int channel; |
76 | int src_step, dst_step; | 78 | int src_step, dst_step; |
77 | int src_frames1, dst_frames1; | 79 | int src_frames1, dst_frames1; |
78 | struct rate_priv *data = (struct rate_priv *)plugin->extra_data; | 80 | struct rate_priv *data = (struct rate_priv *)plugin->extra_data; |
79 | struct rate_channel *rchannels = data->channels; | 81 | struct rate_channel *rchannels = data->channels; |
80 | |||
81 | #define GET_S16_LABELS | ||
82 | #define PUT_S16_LABELS | ||
83 | #include "plugin_ops.h" | ||
84 | #undef GET_S16_LABELS | ||
85 | #undef PUT_S16_LABELS | ||
86 | void *get = get_s16_labels[data->get]; | ||
87 | void *put = put_s16_labels[data->put]; | ||
88 | signed short sample = 0; | ||
89 | 82 | ||
90 | for (channel = 0; channel < plugin->src_format.channels; channel++) { | 83 | for (channel = 0; channel < plugin->src_format.channels; channel++) { |
91 | pos = data->pos; | 84 | pos = data->pos; |
@@ -98,10 +91,12 @@ static void resample_expand(struct snd_pcm_plugin *plugin, | |||
98 | continue; | 91 | continue; |
99 | } | 92 | } |
100 | dst_channels[channel].enabled = 1; | 93 | dst_channels[channel].enabled = 1; |
101 | src = (char *)src_channels[channel].area.addr + src_channels[channel].area.first / 8; | 94 | src = (signed short *)src_channels[channel].area.addr + |
102 | dst = (char *)dst_channels[channel].area.addr + dst_channels[channel].area.first / 8; | 95 | src_channels[channel].area.first / 8 / 2; |
103 | src_step = src_channels[channel].area.step / 8; | 96 | dst = (signed short *)dst_channels[channel].area.addr + |
104 | dst_step = dst_channels[channel].area.step / 8; | 97 | dst_channels[channel].area.first / 8 / 2; |
98 | src_step = src_channels[channel].area.step / 8 / 2; | ||
99 | dst_step = dst_channels[channel].area.step / 8 / 2; | ||
105 | src_frames1 = src_frames; | 100 | src_frames1 = src_frames; |
106 | dst_frames1 = dst_frames; | 101 | dst_frames1 = dst_frames; |
107 | while (dst_frames1-- > 0) { | 102 | while (dst_frames1-- > 0) { |
@@ -109,12 +104,7 @@ static void resample_expand(struct snd_pcm_plugin *plugin, | |||
109 | pos &= R_MASK; | 104 | pos &= R_MASK; |
110 | S1 = S2; | 105 | S1 = S2; |
111 | if (src_frames1-- > 0) { | 106 | if (src_frames1-- > 0) { |
112 | goto *get; | 107 | S2 = *src; |
113 | #define GET_S16_END after_get | ||
114 | #include "plugin_ops.h" | ||
115 | #undef GET_S16_END | ||
116 | after_get: | ||
117 | S2 = sample; | ||
118 | src += src_step; | 108 | src += src_step; |
119 | } | 109 | } |
120 | } | 110 | } |
@@ -123,12 +113,7 @@ static void resample_expand(struct snd_pcm_plugin *plugin, | |||
123 | val = -32768; | 113 | val = -32768; |
124 | else if (val > 32767) | 114 | else if (val > 32767) |
125 | val = 32767; | 115 | val = 32767; |
126 | sample = val; | 116 | *dst = val; |
127 | goto *put; | ||
128 | #define PUT_S16_END after_put | ||
129 | #include "plugin_ops.h" | ||
130 | #undef PUT_S16_END | ||
131 | after_put: | ||
132 | dst += dst_step; | 117 | dst += dst_step; |
133 | pos += data->pitch; | 118 | pos += data->pitch; |
134 | } | 119 | } |
@@ -147,21 +132,12 @@ static void resample_shrink(struct snd_pcm_plugin *plugin, | |||
147 | unsigned int pos = 0; | 132 | unsigned int pos = 0; |
148 | signed int val; | 133 | signed int val; |
149 | signed short S1, S2; | 134 | signed short S1, S2; |
150 | char *src, *dst; | 135 | signed short *src, *dst; |
151 | unsigned int channel; | 136 | unsigned int channel; |
152 | int src_step, dst_step; | 137 | int src_step, dst_step; |
153 | int src_frames1, dst_frames1; | 138 | int src_frames1, dst_frames1; |
154 | struct rate_priv *data = (struct rate_priv *)plugin->extra_data; | 139 | struct rate_priv *data = (struct rate_priv *)plugin->extra_data; |
155 | struct rate_channel *rchannels = data->channels; | 140 | struct rate_channel *rchannels = data->channels; |
156 | |||
157 | #define GET_S16_LABELS | ||
158 | #define PUT_S16_LABELS | ||
159 | #include "plugin_ops.h" | ||
160 | #undef GET_S16_LABELS | ||
161 | #undef PUT_S16_LABELS | ||
162 | void *get = get_s16_labels[data->get]; | ||
163 | void *put = put_s16_labels[data->put]; | ||
164 | signed short sample = 0; | ||
165 | 141 | ||
166 | for (channel = 0; channel < plugin->src_format.channels; ++channel) { | 142 | for (channel = 0; channel < plugin->src_format.channels; ++channel) { |
167 | pos = data->pos; | 143 | pos = data->pos; |
@@ -174,21 +150,18 @@ static void resample_shrink(struct snd_pcm_plugin *plugin, | |||
174 | continue; | 150 | continue; |
175 | } | 151 | } |
176 | dst_channels[channel].enabled = 1; | 152 | dst_channels[channel].enabled = 1; |
177 | src = (char *)src_channels[channel].area.addr + src_channels[channel].area.first / 8; | 153 | src = (signed short *)src_channels[channel].area.addr + |
178 | dst = (char *)dst_channels[channel].area.addr + dst_channels[channel].area.first / 8; | 154 | src_channels[channel].area.first / 8 / 2; |
179 | src_step = src_channels[channel].area.step / 8; | 155 | dst = (signed short *)dst_channels[channel].area.addr + |
180 | dst_step = dst_channels[channel].area.step / 8; | 156 | dst_channels[channel].area.first / 8 / 2; |
157 | src_step = src_channels[channel].area.step / 8 / 2; | ||
158 | dst_step = dst_channels[channel].area.step / 8 / 2; | ||
181 | src_frames1 = src_frames; | 159 | src_frames1 = src_frames; |
182 | dst_frames1 = dst_frames; | 160 | dst_frames1 = dst_frames; |
183 | while (dst_frames1 > 0) { | 161 | while (dst_frames1 > 0) { |
184 | S1 = S2; | 162 | S1 = S2; |
185 | if (src_frames1-- > 0) { | 163 | if (src_frames1-- > 0) { |
186 | goto *get; | 164 | S1 = *src; |
187 | #define GET_S16_END after_get | ||
188 | #include "plugin_ops.h" | ||
189 | #undef GET_S16_END | ||
190 | after_get: | ||
191 | S2 = sample; | ||
192 | src += src_step; | 165 | src += src_step; |
193 | } | 166 | } |
194 | if (pos & ~R_MASK) { | 167 | if (pos & ~R_MASK) { |
@@ -198,12 +171,7 @@ static void resample_shrink(struct snd_pcm_plugin *plugin, | |||
198 | val = -32768; | 171 | val = -32768; |
199 | else if (val > 32767) | 172 | else if (val > 32767) |
200 | val = 32767; | 173 | val = 32767; |
201 | sample = val; | 174 | *dst = val; |
202 | goto *put; | ||
203 | #define PUT_S16_END after_put | ||
204 | #include "plugin_ops.h" | ||
205 | #undef PUT_S16_END | ||
206 | after_put: | ||
207 | dst += dst_step; | 175 | dst += dst_step; |
208 | dst_frames1--; | 176 | dst_frames1--; |
209 | } | 177 | } |
@@ -343,8 +311,8 @@ int snd_pcm_plugin_build_rate(struct snd_pcm_substream *plug, | |||
343 | 311 | ||
344 | snd_assert(src_format->channels == dst_format->channels, return -ENXIO); | 312 | snd_assert(src_format->channels == dst_format->channels, return -ENXIO); |
345 | snd_assert(src_format->channels > 0, return -ENXIO); | 313 | snd_assert(src_format->channels > 0, return -ENXIO); |
346 | snd_assert(snd_pcm_format_linear(src_format->format) != 0, return -ENXIO); | 314 | snd_assert(src_format->format == SNDRV_PCM_FORMAT_S16, return -ENXIO); |
347 | snd_assert(snd_pcm_format_linear(dst_format->format) != 0, return -ENXIO); | 315 | snd_assert(dst_format->format == SNDRV_PCM_FORMAT_S16, return -ENXIO); |
348 | snd_assert(src_format->rate != dst_format->rate, return -ENXIO); | 316 | snd_assert(src_format->rate != dst_format->rate, return -ENXIO); |
349 | 317 | ||
350 | err = snd_pcm_plugin_build(plug, "rate conversion", | 318 | err = snd_pcm_plugin_build(plug, "rate conversion", |
@@ -355,11 +323,6 @@ int snd_pcm_plugin_build_rate(struct snd_pcm_substream *plug, | |||
355 | if (err < 0) | 323 | if (err < 0) |
356 | return err; | 324 | return err; |
357 | data = (struct rate_priv *)plugin->extra_data; | 325 | data = (struct rate_priv *)plugin->extra_data; |
358 | data->get = getput_index(src_format->format); | ||
359 | snd_assert(data->get >= 0 && data->get < 4*2*2, return -EINVAL); | ||
360 | data->put = getput_index(dst_format->format); | ||
361 | snd_assert(data->put >= 0 && data->put < 4*2*2, return -EINVAL); | ||
362 | |||
363 | if (src_format->rate < dst_format->rate) { | 326 | if (src_format->rate < dst_format->rate) { |
364 | data->pitch = ((src_format->rate << SHIFT) + (dst_format->rate >> 1)) / dst_format->rate; | 327 | data->pitch = ((src_format->rate << SHIFT) + (dst_format->rate >> 1)) / dst_format->rate; |
365 | data->func = resample_expand; | 328 | data->func = resample_expand; |
@@ -377,3 +340,5 @@ int snd_pcm_plugin_build_rate(struct snd_pcm_substream *plug, | |||
377 | *r_plugin = plugin; | 340 | *r_plugin = plugin; |
378 | return 0; | 341 | return 0; |
379 | } | 342 | } |
343 | |||
344 | #endif | ||