diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-16 13:13:38 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-16 13:13:38 -0400 |
commit | fc8a327db6c46de783b1a4276d846841b9abc24c (patch) | |
tree | bee512c142cccea93511debd98ef954581693727 /sound/core/oss/linear.c | |
parent | 92d15c2ccbb3e31a3fc71ad28fdb55e1319383c0 (diff) | |
parent | 24837e6f249a2c83667552e6871c1543b4a6b934 (diff) |
Merge branch 'linus' of master.kernel.org:/pub/scm/linux/kernel/git/perex/alsa
* 'linus' of master.kernel.org:/pub/scm/linux/kernel/git/perex/alsa: (264 commits)
[ALSA] version 1.0.15
[ALSA] Fix thinko in cs4231 mce down check
[ALSA] sun-cs4231: improved waiting after MCE down
[ALSA] sun-cs4231: use cs4231-regs.h
[ALSA] This simplifies and fixes waiting loops of the mce_down()
[ALSA] This patch adds support for a wavetable chip on
[ALSA] This patch removes open_mutex from the ad1848-lib as
[ALSA] fix bootup crash in snd_gus_interrupt()
[ALSA] hda-codec - Fix SKU ID function for realtek codecs
[ALSA] Support ASUS P701 eeepc [0x1043 0x82a1] support
[ALSA] hda-codec - Add array terminator for dmic in STAC codec
[ALSA] hdsp - Fix zero division
[ALSA] usb-audio - Fix double comment
[ALSA] hda-codec - Fix STAC922x volume knob control
[ALSA] Changed Jaroslav Kysela's e-mail from perex@suse.cz to perex@perex.cz
[ALSA] hda-codec - Fix for Fujitsu Lifebook C1410
[ALSA] mpu-401: remove MPU401_INFO_UART_ONLY flag
[ALSA] mpu-401: do not require an ACK byte for the ENTER_UART command
[ALSA] via82xx - Add DXS quirk for Shuttle AK31v2
[ALSA] hda-codec - Fix input_mux numbers for vaio stac92xx
...
Diffstat (limited to 'sound/core/oss/linear.c')
-rw-r--r-- | sound/core/oss/linear.c | 91 |
1 files changed, 52 insertions, 39 deletions
diff --git a/sound/core/oss/linear.c b/sound/core/oss/linear.c index 5b1bcdc64779..06f96a3e86f6 100644 --- a/sound/core/oss/linear.c +++ b/sound/core/oss/linear.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Linear conversion Plug-In | 2 | * Linear conversion Plug-In |
3 | * Copyright (c) 1999 by Jaroslav Kysela <perex@suse.cz>, | 3 | * Copyright (c) 1999 by Jaroslav Kysela <perex@perex.cz>, |
4 | * Abramo Bagnara <abramo@alsa-project.org> | 4 | * Abramo Bagnara <abramo@alsa-project.org> |
5 | * | 5 | * |
6 | * | 6 | * |
@@ -21,9 +21,6 @@ | |||
21 | */ | 21 | */ |
22 | 22 | ||
23 | #include <sound/driver.h> | 23 | #include <sound/driver.h> |
24 | |||
25 | #ifdef CONFIG_SND_PCM_OSS_PLUGINS | ||
26 | |||
27 | #include <linux/time.h> | 24 | #include <linux/time.h> |
28 | #include <sound/core.h> | 25 | #include <sound/core.h> |
29 | #include <sound/pcm.h> | 26 | #include <sound/pcm.h> |
@@ -34,19 +31,34 @@ | |||
34 | */ | 31 | */ |
35 | 32 | ||
36 | struct linear_priv { | 33 | struct linear_priv { |
37 | int conv; | 34 | int cvt_endian; /* need endian conversion? */ |
35 | unsigned int src_ofs; /* byte offset in source format */ | ||
36 | unsigned int dst_ofs; /* byte soffset in destination format */ | ||
37 | unsigned int copy_ofs; /* byte offset in temporary u32 data */ | ||
38 | unsigned int dst_bytes; /* byte size of destination format */ | ||
39 | unsigned int copy_bytes; /* bytes to copy per conversion */ | ||
40 | unsigned int flip; /* MSB flip for signeness, done after endian conv */ | ||
38 | }; | 41 | }; |
39 | 42 | ||
43 | static inline void do_convert(struct linear_priv *data, | ||
44 | unsigned char *dst, unsigned char *src) | ||
45 | { | ||
46 | unsigned int tmp = 0; | ||
47 | unsigned char *p = (unsigned char *)&tmp; | ||
48 | |||
49 | memcpy(p + data->copy_ofs, src + data->src_ofs, data->copy_bytes); | ||
50 | if (data->cvt_endian) | ||
51 | tmp = swab32(tmp); | ||
52 | tmp ^= data->flip; | ||
53 | memcpy(dst, p + data->dst_ofs, data->dst_bytes); | ||
54 | } | ||
55 | |||
40 | static void convert(struct snd_pcm_plugin *plugin, | 56 | static void convert(struct snd_pcm_plugin *plugin, |
41 | const struct snd_pcm_plugin_channel *src_channels, | 57 | const struct snd_pcm_plugin_channel *src_channels, |
42 | struct snd_pcm_plugin_channel *dst_channels, | 58 | struct snd_pcm_plugin_channel *dst_channels, |
43 | snd_pcm_uframes_t frames) | 59 | snd_pcm_uframes_t frames) |
44 | { | 60 | { |
45 | #define CONV_LABELS | ||
46 | #include "plugin_ops.h" | ||
47 | #undef CONV_LABELS | ||
48 | struct linear_priv *data = (struct linear_priv *)plugin->extra_data; | 61 | struct linear_priv *data = (struct linear_priv *)plugin->extra_data; |
49 | void *conv = conv_labels[data->conv]; | ||
50 | int channel; | 62 | int channel; |
51 | int nchannels = plugin->src_format.channels; | 63 | int nchannels = plugin->src_format.channels; |
52 | for (channel = 0; channel < nchannels; ++channel) { | 64 | for (channel = 0; channel < nchannels; ++channel) { |
@@ -67,11 +79,7 @@ static void convert(struct snd_pcm_plugin *plugin, | |||
67 | dst_step = dst_channels[channel].area.step / 8; | 79 | dst_step = dst_channels[channel].area.step / 8; |
68 | frames1 = frames; | 80 | frames1 = frames; |
69 | while (frames1-- > 0) { | 81 | while (frames1-- > 0) { |
70 | goto *conv; | 82 | do_convert(data, dst, src); |
71 | #define CONV_END after | ||
72 | #include "plugin_ops.h" | ||
73 | #undef CONV_END | ||
74 | after: | ||
75 | src += src_step; | 83 | src += src_step; |
76 | dst += dst_step; | 84 | dst += dst_step; |
77 | } | 85 | } |
@@ -106,29 +114,36 @@ static snd_pcm_sframes_t linear_transfer(struct snd_pcm_plugin *plugin, | |||
106 | return frames; | 114 | return frames; |
107 | } | 115 | } |
108 | 116 | ||
109 | static int conv_index(int src_format, int dst_format) | 117 | static void init_data(struct linear_priv *data, int src_format, int dst_format) |
110 | { | 118 | { |
111 | int src_endian, dst_endian, sign, src_width, dst_width; | 119 | int src_le, dst_le, src_bytes, dst_bytes; |
112 | 120 | ||
113 | sign = (snd_pcm_format_signed(src_format) != | 121 | src_bytes = snd_pcm_format_width(src_format) / 8; |
114 | snd_pcm_format_signed(dst_format)); | 122 | dst_bytes = snd_pcm_format_width(dst_format) / 8; |
115 | #ifdef SNDRV_LITTLE_ENDIAN | 123 | src_le = snd_pcm_format_little_endian(src_format) > 0; |
116 | src_endian = snd_pcm_format_big_endian(src_format); | 124 | dst_le = snd_pcm_format_little_endian(dst_format) > 0; |
117 | dst_endian = snd_pcm_format_big_endian(dst_format); | 125 | |
118 | #else | 126 | data->dst_bytes = dst_bytes; |
119 | src_endian = snd_pcm_format_little_endian(src_format); | 127 | data->cvt_endian = src_le != dst_le; |
120 | dst_endian = snd_pcm_format_little_endian(dst_format); | 128 | data->copy_bytes = src_bytes < dst_bytes ? src_bytes : dst_bytes; |
121 | #endif | 129 | if (src_le) { |
122 | 130 | data->copy_ofs = 4 - data->copy_bytes; | |
123 | if (src_endian < 0) | 131 | data->src_ofs = src_bytes - data->copy_bytes; |
124 | src_endian = 0; | 132 | } else |
125 | if (dst_endian < 0) | 133 | data->src_ofs = snd_pcm_format_physical_width(src_format) / 8 - |
126 | dst_endian = 0; | 134 | src_bytes; |
127 | 135 | if (dst_le) | |
128 | src_width = snd_pcm_format_width(src_format) / 8 - 1; | 136 | data->dst_ofs = 4 - data->dst_bytes; |
129 | dst_width = snd_pcm_format_width(dst_format) / 8 - 1; | 137 | else |
130 | 138 | data->dst_ofs = snd_pcm_format_physical_width(dst_format) / 8 - | |
131 | return src_width * 32 + src_endian * 16 + sign * 8 + dst_width * 2 + dst_endian; | 139 | dst_bytes; |
140 | if (snd_pcm_format_signed(src_format) != | ||
141 | snd_pcm_format_signed(dst_format)) { | ||
142 | if (dst_le) | ||
143 | data->flip = cpu_to_le32(0x80000000); | ||
144 | else | ||
145 | data->flip = cpu_to_be32(0x80000000); | ||
146 | } | ||
132 | } | 147 | } |
133 | 148 | ||
134 | int snd_pcm_plugin_build_linear(struct snd_pcm_substream *plug, | 149 | int snd_pcm_plugin_build_linear(struct snd_pcm_substream *plug, |
@@ -154,10 +169,8 @@ int snd_pcm_plugin_build_linear(struct snd_pcm_substream *plug, | |||
154 | if (err < 0) | 169 | if (err < 0) |
155 | return err; | 170 | return err; |
156 | data = (struct linear_priv *)plugin->extra_data; | 171 | data = (struct linear_priv *)plugin->extra_data; |
157 | data->conv = conv_index(src_format->format, dst_format->format); | 172 | init_data(data, src_format->format, dst_format->format); |
158 | plugin->transfer = linear_transfer; | 173 | plugin->transfer = linear_transfer; |
159 | *r_plugin = plugin; | 174 | *r_plugin = plugin; |
160 | return 0; | 175 | return 0; |
161 | } | 176 | } |
162 | |||
163 | #endif | ||