24 #include <linux/time.h>
29 #define SIGN_BIT (0x80)
30 #define QUANT_MASK (0xf)
33 #define SEG_MASK (0x70)
35 static inline int val_seg(
int val)
83 static unsigned char linear2ulaw(
int pcm_val)
91 pcm_val =
BIAS - pcm_val;
101 seg = val_seg(pcm_val);
107 uval = (seg << 4) | ((pcm_val >> (seg + 3)) & 0xF);
120 static int ulaw2linear(
unsigned char u_val)
132 t <<= ((unsigned)u_val & SEG_MASK) >>
SEG_SHIFT;
142 const struct snd_pcm_plugin_channel *src_channels,
143 struct snd_pcm_plugin_channel *dst_channels,
159 sample ^= data->
flip;
168 static void mulaw_decode(
struct snd_pcm_plugin *plugin,
169 const struct snd_pcm_plugin_channel *src_channels,
170 struct snd_pcm_plugin_channel *dst_channels,
175 int nchannels = plugin->src_format.channels;
179 int src_step, dst_step;
184 dst_channels[
channel].enabled = 0;
187 dst_channels[
channel].enabled = 1;
188 src = src_channels[
channel].area.addr + src_channels[
channel].area.first / 8;
189 dst = dst_channels[
channel].area.addr + dst_channels[
channel].area.first / 8;
190 src_step = src_channels[
channel].area.step / 8;
191 dst_step = dst_channels[
channel].area.step / 8;
193 while (frames1-- > 0) {
194 signed short sample = ulaw2linear(*src);
195 cvt_s16_to_native(data, dst, sample);
202 static inline signed short cvt_native_to_s16(
struct mulaw_priv *data,
210 sample ^= data->
flip;
211 return (
signed short)sample;
214 static void mulaw_encode(
struct snd_pcm_plugin *plugin,
215 const struct snd_pcm_plugin_channel *src_channels,
216 struct snd_pcm_plugin_channel *dst_channels,
221 int nchannels = plugin->src_format.channels;
225 int src_step, dst_step;
227 if (!src_channels[
channel].enabled) {
230 dst_channels[
channel].enabled = 0;
233 dst_channels[
channel].enabled = 1;
234 src = src_channels[
channel].area.addr + src_channels[
channel].area.first / 8;
235 dst = dst_channels[
channel].area.addr + dst_channels[
channel].area.first / 8;
236 src_step = src_channels[
channel].area.step / 8;
237 dst_step = dst_channels[
channel].area.step / 8;
239 while (frames1-- > 0) {
240 signed short sample = cvt_native_to_s16(data, src);
241 *dst = linear2ulaw(sample);
249 const struct snd_pcm_plugin_channel *src_channels,
250 struct snd_pcm_plugin_channel *dst_channels,
255 if (
snd_BUG_ON(!plugin || !src_channels || !dst_channels))
259 #ifdef CONFIG_SND_DEBUG
262 for (channel = 0; channel < plugin->src_format.channels; channel++) {
263 if (
snd_BUG_ON(src_channels[channel].area.first % 8 ||
264 src_channels[channel].area.step % 8))
266 if (
snd_BUG_ON(dst_channels[channel].area.first % 8 ||
267 dst_channels[channel].area.step % 8))
272 data = (
struct mulaw_priv *)plugin->extra_data;
273 data->
func(plugin, src_channels, dst_channels, frames);
279 #ifdef SNDRV_LITTLE_ENDIAN
299 struct snd_pcm_plugin_format *src_format,
300 struct snd_pcm_plugin_format *dst_format,
301 struct snd_pcm_plugin **r_plugin)
305 struct snd_pcm_plugin *plugin;
306 struct snd_pcm_plugin_format *
format;
313 if (
snd_BUG_ON(src_format->rate != dst_format->rate))
315 if (
snd_BUG_ON(src_format->channels != dst_format->channels))
334 src_format, dst_format,
338 data = (
struct mulaw_priv *)plugin->extra_data;
340 init_data(data, format->format);
341 plugin->transfer = mulaw_transfer;