comparison src/Output/sun/convert.c @ 0:13389e613d67 trunk

[svn] - initial import of audacious-plugins tree (lots to do)
author nenolod
date Mon, 18 Sep 2006 01:11:49 -0700
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:13389e613d67
1 /*
2 * Copyright (C) 2001 Haavard Kvaalen
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 */
18
19 #include "sun.h"
20
21 void * sun_get_convert_buffer(size_t size)
22 {
23 static size_t length;
24 static void *buffer;
25
26 if (size > 0 && size <= length)
27 return buffer;
28
29 length = size;
30 buffer = g_realloc(buffer, size);
31 return buffer;
32 }
33
34 static int convert_swap_endian(void **data, int length)
35 {
36 int i;
37 guint16 *ptr = *data;
38
39 for (i = 0; i < length; i += 2, ptr++)
40 *ptr = GUINT16_SWAP_LE_BE(*ptr);
41
42 return i;
43 }
44
45 static int convert_swap_sign_and_endian_to_native(void **data, int length)
46 {
47 int i;
48 guint16 *ptr = *data;
49
50 for (i = 0; i < length; i += 2, ptr++)
51 *ptr = GUINT16_SWAP_LE_BE(*ptr) ^ 1 << 15;
52
53 return (i);
54 }
55
56 static int convert_swap_sign_and_endian_to_alien(void **data, int length)
57 {
58 int i;
59 guint16 *ptr = *data;
60
61 for (i = 0; i < length; i += 2, ptr++)
62 *ptr = GUINT16_SWAP_LE_BE(*ptr ^ 1 << 15);
63
64 return i;
65 }
66
67 static int convert_swap_sign16(void **data, int length)
68 {
69 int i;
70 gint16 *ptr = *data;
71
72 for (i = 0; i < length; i += 2, ptr++)
73 *ptr ^= 1 << 15;
74
75 return i;
76 }
77
78 static int convert_swap_sign8(void **data, int length)
79 {
80 int i;
81 gint8 *ptr = *data;
82
83 for (i = 0; i < length; i++)
84 *ptr++ ^= 1 << 7;
85
86 return i;
87 }
88
89 static int convert_to_8_native_endian(void **data, int length)
90 {
91 int i;
92 gint16 *input = *data;
93 gint8 *output = *data;
94
95 for (i = 0; i < length / 2; i++)
96 *output++ = *input++ >> 8;
97
98 return i;
99 }
100
101 static int convert_to_8_native_endian_swap_sign(void **data, int length)
102 {
103 int i;
104 gint16 *input = *data;
105 gint8 *output = *data;
106
107 for (i = 0; i < length / 2; i++)
108 *output++ = (*input++ >> 8) ^ (1 << 7);
109
110 return i;
111 }
112
113
114 static int convert_to_8_alien_endian(void **data, int length)
115 {
116 int i;
117 gint16 *input = *data;
118 gint8 *output = *data;
119
120 for (i = 0; i < length / 2; i++)
121 *output++ = *input++ & 0xff;
122
123 return i;
124 }
125
126 static int convert_to_8_alien_endian_swap_sign(void **data, int length)
127 {
128 int i;
129 gint16 *input = *data;
130 gint8 *output = *data;
131
132 for (i = 0; i < length / 2; i++)
133 *output++ = (*input++ & 0xff) ^ (1 << 7);
134
135 return i;
136 }
137
138 static int convert_to_16_native_endian(void **data, int length)
139 {
140 int i;
141 guint16 *output;
142 guint8 *input = *data;
143
144 *data = sun_get_convert_buffer(length * 2);
145 output = *data;
146
147 for (i = 0; i < length; i++)
148 *output++ = *input++ << 8;
149
150 return (i * 2);
151 }
152
153 static int convert_to_16_native_endian_swap_sign(void **data, int length)
154 {
155 int i;
156 guint16 *output;
157 guint8 *input = *data;
158
159 *data = sun_get_convert_buffer(length * 2);
160 output = *data;
161 for (i = 0; i < length; i++)
162 *output++ = (*input++ << 8) ^ (1 << 15);
163
164 return (i * 2);
165 }
166
167
168 static int convert_to_16_alien_endian(void **data, int length)
169 {
170 int i;
171 guint16 *output;
172 guint8 *input = *data;
173
174 *data = sun_get_convert_buffer(length * 2);
175 output = *data;
176 for (i = 0; i < length; i++)
177 *output++ = *input++;
178
179 return (i * 2);
180 }
181
182 static int convert_to_16_alien_endian_swap_sign(void **data, int length)
183 {
184 int i;
185 guint16 *output;
186 guint8 *input = *data;
187
188 *data = sun_get_convert_buffer(length * 2);
189 output = *data;
190 for (i = 0; i < length; i++)
191 *output++ = *input++ ^ (1 << 7);
192
193 return (i * 2);
194 }
195
196 int (*sun_get_convert_func(int output, int input))(void **, int)
197 {
198 if (output == input)
199 return NULL;
200
201 if ((output == AUDIO_ENCODING_ULINEAR_BE &&
202 input == AUDIO_ENCODING_ULINEAR_LE) ||
203 (output == AUDIO_ENCODING_ULINEAR_LE &&
204 input == AUDIO_ENCODING_ULINEAR_BE) ||
205 (output == AUDIO_ENCODING_SLINEAR_BE &&
206 input == AUDIO_ENCODING_SLINEAR_LE) ||
207 (output == AUDIO_ENCODING_SLINEAR_LE &&
208 input == AUDIO_ENCODING_SLINEAR_BE))
209 return convert_swap_endian;
210
211 if ((output == AUDIO_ENCODING_ULINEAR_BE &&
212 input == AUDIO_ENCODING_SLINEAR_BE) ||
213 (output == AUDIO_ENCODING_ULINEAR_LE &&
214 input == AUDIO_ENCODING_SLINEAR_LE) ||
215 (output == AUDIO_ENCODING_SLINEAR_BE &&
216 input == AUDIO_ENCODING_ULINEAR_BE) ||
217 (output == AUDIO_ENCODING_SLINEAR_LE &&
218 input == AUDIO_ENCODING_ULINEAR_LE))
219 return convert_swap_sign16;
220
221 if ((IS_BIG_ENDIAN &&
222 ((output == AUDIO_ENCODING_ULINEAR_BE &&
223 input == AUDIO_ENCODING_SLINEAR_LE) ||
224 (output == AUDIO_ENCODING_SLINEAR_BE &&
225 input == AUDIO_ENCODING_ULINEAR_LE))) ||
226 (!IS_BIG_ENDIAN &&
227 ((output == AUDIO_ENCODING_ULINEAR_LE &&
228 input == AUDIO_ENCODING_SLINEAR_BE) ||
229 (output == AUDIO_ENCODING_SLINEAR_LE &&
230 input == AUDIO_ENCODING_ULINEAR_BE))))
231 return convert_swap_sign_and_endian_to_native;
232
233 if ((!IS_BIG_ENDIAN &&
234 ((output == AUDIO_ENCODING_ULINEAR_BE &&
235 input == AUDIO_ENCODING_SLINEAR_LE) ||
236 (output == AUDIO_ENCODING_SLINEAR_BE &&
237 input == AUDIO_ENCODING_ULINEAR_LE))) ||
238 (IS_BIG_ENDIAN &&
239 ((output == AUDIO_ENCODING_ULINEAR_LE &&
240 input == AUDIO_ENCODING_SLINEAR_BE) ||
241 (output == AUDIO_ENCODING_SLINEAR_LE &&
242 input == AUDIO_ENCODING_ULINEAR_BE))))
243 return convert_swap_sign_and_endian_to_alien;
244
245 if ((IS_BIG_ENDIAN &&
246 ((output == AUDIO_ENCODING_PCM8 &&
247 input == AUDIO_ENCODING_ULINEAR_BE) ||
248 (output == AUDIO_ENCODING_SLINEAR &&
249 input == AUDIO_ENCODING_SLINEAR_BE))) ||
250 (!IS_BIG_ENDIAN &&
251 ((output == AUDIO_ENCODING_PCM8 &&
252 input == AUDIO_ENCODING_ULINEAR_LE) ||
253 (output == AUDIO_ENCODING_SLINEAR &&
254 input == AUDIO_ENCODING_SLINEAR_LE))))
255 return convert_to_8_native_endian;
256
257 if ((IS_BIG_ENDIAN &&
258 ((output == AUDIO_ENCODING_PCM8 &&
259 input == AUDIO_ENCODING_SLINEAR_BE) ||
260 (output == AUDIO_ENCODING_SLINEAR &&
261 input == AUDIO_ENCODING_ULINEAR_BE))) ||
262 (!IS_BIG_ENDIAN &&
263 ((output == AUDIO_ENCODING_PCM8 &&
264 input == AUDIO_ENCODING_SLINEAR_LE) ||
265 (output == AUDIO_ENCODING_SLINEAR &&
266 input == AUDIO_ENCODING_ULINEAR_LE))))
267 return convert_to_8_native_endian_swap_sign;
268
269 if ((!IS_BIG_ENDIAN &&
270 ((output == AUDIO_ENCODING_PCM8 &&
271 input == AUDIO_ENCODING_ULINEAR_BE) ||
272 (output == AUDIO_ENCODING_SLINEAR &&
273 input == AUDIO_ENCODING_SLINEAR_BE))) ||
274 (IS_BIG_ENDIAN &&
275 ((output == AUDIO_ENCODING_PCM8 &&
276 input == AUDIO_ENCODING_ULINEAR_LE) ||
277 (output == AUDIO_ENCODING_SLINEAR &&
278 input == AUDIO_ENCODING_SLINEAR_LE))))
279 return convert_to_8_alien_endian;
280
281 if ((!IS_BIG_ENDIAN &&
282 ((output == AUDIO_ENCODING_PCM8 &&
283 input == AUDIO_ENCODING_SLINEAR_BE) ||
284 (output == AUDIO_ENCODING_SLINEAR &&
285 input == AUDIO_ENCODING_ULINEAR_BE))) ||
286 (IS_BIG_ENDIAN &&
287 ((output == AUDIO_ENCODING_PCM8 &&
288 input == AUDIO_ENCODING_SLINEAR_LE) ||
289 (output == AUDIO_ENCODING_SLINEAR &&
290 input == AUDIO_ENCODING_ULINEAR_LE))))
291 return convert_to_8_alien_endian_swap_sign;
292
293 if ((output == AUDIO_ENCODING_PCM8 &&
294 input == AUDIO_ENCODING_SLINEAR) ||
295 (output == AUDIO_ENCODING_SLINEAR &&
296 input == AUDIO_ENCODING_PCM8))
297 return convert_swap_sign8;
298
299 if ((IS_BIG_ENDIAN &&
300 ((output == AUDIO_ENCODING_ULINEAR_BE &&
301 input == AUDIO_ENCODING_PCM8) ||
302 (output == AUDIO_ENCODING_SLINEAR_BE &&
303 input == AUDIO_ENCODING_SLINEAR))) ||
304 (!IS_BIG_ENDIAN &&
305 ((output == AUDIO_ENCODING_ULINEAR_LE &&
306 input == AUDIO_ENCODING_PCM8) ||
307 (output == AUDIO_ENCODING_SLINEAR_LE &&
308 input == AUDIO_ENCODING_SLINEAR))))
309 return convert_to_16_native_endian;
310
311 if ((IS_BIG_ENDIAN &&
312 ((output == AUDIO_ENCODING_ULINEAR_BE &&
313 input == AUDIO_ENCODING_SLINEAR) ||
314 (output == AUDIO_ENCODING_SLINEAR_BE &&
315 input == AUDIO_ENCODING_PCM8))) ||
316 (!IS_BIG_ENDIAN &&
317 ((output == AUDIO_ENCODING_ULINEAR_LE &&
318 input == AUDIO_ENCODING_SLINEAR) ||
319 (output == AUDIO_ENCODING_SLINEAR_LE &&
320 input == AUDIO_ENCODING_PCM8))))
321 return convert_to_16_native_endian_swap_sign;
322
323 if ((!IS_BIG_ENDIAN &&
324 ((output == AUDIO_ENCODING_ULINEAR_BE &&
325 input == AUDIO_ENCODING_PCM8) ||
326 (output == AUDIO_ENCODING_SLINEAR_BE &&
327 input == AUDIO_ENCODING_SLINEAR))) ||
328 (IS_BIG_ENDIAN &&
329 ((output == AUDIO_ENCODING_ULINEAR_LE &&
330 input == AUDIO_ENCODING_PCM8) ||
331 (output == AUDIO_ENCODING_SLINEAR_LE &&
332 input == AUDIO_ENCODING_SLINEAR))))
333 return convert_to_16_alien_endian;
334
335 if ((!IS_BIG_ENDIAN &&
336 ((output == AUDIO_ENCODING_ULINEAR_BE &&
337 input == AUDIO_ENCODING_SLINEAR) ||
338 (output == AUDIO_ENCODING_SLINEAR_BE &&
339 input == AUDIO_ENCODING_PCM8))) ||
340 (IS_BIG_ENDIAN &&
341 ((output == AUDIO_ENCODING_ULINEAR_LE &&
342 input == AUDIO_ENCODING_SLINEAR) ||
343 (output == AUDIO_ENCODING_SLINEAR_LE &&
344 input == AUDIO_ENCODING_PCM8))))
345 return convert_to_16_alien_endian_swap_sign;
346
347 return NULL;
348 }