Mercurial > audlegacy
annotate libaudacious/xconvert.c @ 1355:2a69c94320e6 trunk
[svn] - add tuple->formatter to tuplespace
author | nenolod |
---|---|
date | Wed, 28 Jun 2006 19:06:06 -0700 |
parents | 0a73d1faeb4e |
children | 6f1346ce2764 |
rev | line source |
---|---|
0 | 1 /* |
2 * Copyright (C) 2001-2003 Haavard Kvaalen <havardk@xmms.org> | |
3 * | |
4 * Licensed under GNU LGPL version 2. | |
5 */ | |
6 | |
7 #include "config.h" | |
8 #include <stdlib.h> | |
9 #include <audacious/plugin.h> | |
10 #include "xconvert.h" | |
11 | |
12 #define IS_BIG_ENDIAN (G_BYTE_ORDER==G_BIG_ENDIAN) | |
13 | |
14 struct buffer { | |
15 void *buffer; | |
16 int size; | |
17 }; | |
18 | |
19 struct xmms_convert_buffers { | |
20 struct buffer format_buffer, stereo_buffer, freq_buffer; | |
21 }; | |
22 | |
23 struct xmms_convert_buffers * | |
24 xmms_convert_buffers_new(void) | |
25 { | |
26 return g_malloc0(sizeof(struct xmms_convert_buffers)); | |
27 } | |
28 | |
29 static void * | |
30 convert_get_buffer(struct buffer *buffer, size_t size) | |
31 { | |
625
0a73d1faeb4e
[svn] GCC 4.1 warning fixes by Diego 'Flameeyes' Petteno from Gentoo.
chainsaw
parents:
0
diff
changeset
|
32 if (size > 0 && size <= (size_t)buffer->size) |
0 | 33 return buffer->buffer; |
34 | |
35 buffer->size = size; | |
36 buffer->buffer = g_realloc(buffer->buffer, size); | |
37 return buffer->buffer; | |
38 } | |
39 | |
40 void | |
41 xmms_convert_buffers_free(struct xmms_convert_buffers *buf) | |
42 { | |
43 convert_get_buffer(&buf->format_buffer, 0); | |
44 convert_get_buffer(&buf->stereo_buffer, 0); | |
45 convert_get_buffer(&buf->freq_buffer, 0); | |
46 } | |
47 | |
48 void | |
49 xmms_convert_buffers_destroy(struct xmms_convert_buffers *buf) | |
50 { | |
51 if (!buf) | |
52 return; | |
53 xmms_convert_buffers_free(buf); | |
54 g_free(buf); | |
55 } | |
56 | |
57 static int | |
58 convert_swap_endian(struct xmms_convert_buffers *buf, void **data, int length) | |
59 { | |
60 guint16 *ptr = *data; | |
61 int i; | |
62 for (i = 0; i < length; i += 2, ptr++) | |
63 *ptr = GUINT16_SWAP_LE_BE(*ptr); | |
64 | |
65 return i; | |
66 } | |
67 | |
68 static int | |
69 convert_swap_sign_and_endian_to_native(struct | |
70 xmms_convert_buffers | |
71 *buf, void **data, int length) | |
72 { | |
73 guint16 *ptr = *data; | |
74 int i; | |
75 for (i = 0; i < length; i += 2, ptr++) | |
76 *ptr = GUINT16_SWAP_LE_BE(*ptr) ^ 1 << 15; | |
77 | |
78 return i; | |
79 } | |
80 | |
81 static int | |
82 convert_swap_sign_and_endian_to_alien(struct | |
83 xmms_convert_buffers *buf, | |
84 void **data, int length) | |
85 { | |
86 guint16 *ptr = *data; | |
87 int i; | |
88 for (i = 0; i < length; i += 2, ptr++) | |
89 *ptr = GUINT16_SWAP_LE_BE(*ptr ^ 1 << 15); | |
90 | |
91 return i; | |
92 } | |
93 | |
94 static int | |
95 convert_swap_sign16(struct xmms_convert_buffers *buf, void **data, int length) | |
96 { | |
97 gint16 *ptr = *data; | |
98 int i; | |
99 for (i = 0; i < length; i += 2, ptr++) | |
100 *ptr ^= 1 << 15; | |
101 | |
102 return i; | |
103 } | |
104 | |
105 static int | |
106 convert_swap_sign8(struct xmms_convert_buffers *buf, void **data, int length) | |
107 { | |
108 gint8 *ptr = *data; | |
109 int i; | |
110 for (i = 0; i < length; i++) | |
111 *ptr++ ^= 1 << 7; | |
112 | |
113 return i; | |
114 } | |
115 | |
116 static int | |
117 convert_to_8_native_endian(struct xmms_convert_buffers *buf, | |
118 void **data, int length) | |
119 { | |
120 gint8 *output = *data; | |
121 gint16 *input = *data; | |
122 int i; | |
123 for (i = 0; i < length / 2; i++) | |
124 *output++ = *input++ >> 8; | |
125 | |
126 return i; | |
127 } | |
128 | |
129 static int | |
130 convert_to_8_native_endian_swap_sign(struct xmms_convert_buffers | |
131 *buf, void **data, int length) | |
132 { | |
133 gint8 *output = *data; | |
134 gint16 *input = *data; | |
135 int i; | |
136 for (i = 0; i < length / 2; i++) | |
137 *output++ = (*input++ >> 8) ^ (1 << 7); | |
138 | |
139 return i; | |
140 } | |
141 | |
142 | |
143 static int | |
144 convert_to_8_alien_endian(struct xmms_convert_buffers *buf, | |
145 void **data, int length) | |
146 { | |
147 gint8 *output = *data; | |
148 gint16 *input = *data; | |
149 int i; | |
150 for (i = 0; i < length / 2; i++) | |
151 *output++ = *input++ & 0xff; | |
152 | |
153 return i; | |
154 } | |
155 | |
156 static int | |
157 convert_to_8_alien_endian_swap_sign(struct xmms_convert_buffers | |
158 *buf, void **data, int length) | |
159 { | |
160 gint8 *output = *data; | |
161 gint16 *input = *data; | |
162 int i; | |
163 for (i = 0; i < length / 2; i++) | |
164 *output++ = (*input++ & 0xff) ^ (1 << 7); | |
165 | |
166 return i; | |
167 } | |
168 | |
169 static int | |
170 convert_to_16_native_endian(struct xmms_convert_buffers *buf, | |
171 void **data, int length) | |
172 { | |
173 guint8 *input = *data; | |
174 guint16 *output; | |
175 int i; | |
176 *data = convert_get_buffer(&buf->format_buffer, length * 2); | |
177 output = *data; | |
178 for (i = 0; i < length; i++) | |
179 *output++ = *input++ << 8; | |
180 | |
181 return i * 2; | |
182 } | |
183 | |
184 static int | |
185 convert_to_16_native_endian_swap_sign(struct | |
186 xmms_convert_buffers *buf, | |
187 void **data, int length) | |
188 { | |
189 guint8 *input = *data; | |
190 guint16 *output; | |
191 int i; | |
192 *data = convert_get_buffer(&buf->format_buffer, length * 2); | |
193 output = *data; | |
194 for (i = 0; i < length; i++) | |
195 *output++ = (*input++ << 8) ^ (1 << 15); | |
196 | |
197 return i * 2; | |
198 } | |
199 | |
200 | |
201 static int | |
202 convert_to_16_alien_endian(struct xmms_convert_buffers *buf, | |
203 void **data, int length) | |
204 { | |
205 guint8 *input = *data; | |
206 guint16 *output; | |
207 int i; | |
208 *data = convert_get_buffer(&buf->format_buffer, length * 2); | |
209 output = *data; | |
210 for (i = 0; i < length; i++) | |
211 *output++ = *input++; | |
212 | |
213 return i * 2; | |
214 } | |
215 | |
216 static int | |
217 convert_to_16_alien_endian_swap_sign(struct xmms_convert_buffers | |
218 *buf, void **data, int length) | |
219 { | |
220 guint8 *input = *data; | |
221 guint16 *output; | |
222 int i; | |
223 *data = convert_get_buffer(&buf->format_buffer, length * 2); | |
224 output = *data; | |
225 for (i = 0; i < length; i++) | |
226 *output++ = *input++ ^ (1 << 7); | |
227 | |
228 return i * 2; | |
229 } | |
230 | |
231 static AFormat | |
232 unnativize(AFormat fmt) | |
233 { | |
234 if (fmt == FMT_S16_NE) { | |
235 if (IS_BIG_ENDIAN) | |
236 return FMT_S16_BE; | |
237 else | |
238 return FMT_S16_LE; | |
239 } | |
240 if (fmt == FMT_U16_NE) { | |
241 if (IS_BIG_ENDIAN) | |
242 return FMT_U16_BE; | |
243 else | |
244 return FMT_U16_LE; | |
245 } | |
246 return fmt; | |
247 } | |
248 | |
249 convert_func_t | |
250 xmms_convert_get_func(AFormat output, AFormat input) | |
251 { | |
252 output = unnativize(output); | |
253 input = unnativize(input); | |
254 | |
255 if (output == input) | |
256 return NULL; | |
257 | |
258 if ((output == FMT_U16_BE && input == FMT_U16_LE) || | |
259 (output == FMT_U16_LE && input == FMT_U16_BE) || | |
260 (output == FMT_S16_BE && input == FMT_S16_LE) || | |
261 (output == FMT_S16_LE && input == FMT_S16_BE)) | |
262 return convert_swap_endian; | |
263 | |
264 if ((output == FMT_U16_BE && input == FMT_S16_BE) || | |
265 (output == FMT_U16_LE && input == FMT_S16_LE) || | |
266 (output == FMT_S16_BE && input == FMT_U16_BE) || | |
267 (output == FMT_S16_LE && input == FMT_U16_LE)) | |
268 return convert_swap_sign16; | |
269 | |
270 if ((IS_BIG_ENDIAN && | |
271 ((output == FMT_U16_BE && input == FMT_S16_LE) || | |
272 (output == FMT_S16_BE && input == FMT_U16_LE))) || | |
273 (!IS_BIG_ENDIAN && | |
274 ((output == FMT_U16_LE && input == FMT_S16_BE) || | |
275 (output == FMT_S16_LE && input == FMT_U16_BE)))) | |
276 return convert_swap_sign_and_endian_to_native; | |
277 | |
278 if ((!IS_BIG_ENDIAN && | |
279 ((output == FMT_U16_BE && input == FMT_S16_LE) || | |
280 (output == FMT_S16_BE && input == FMT_U16_LE))) || | |
281 (IS_BIG_ENDIAN && | |
282 ((output == FMT_U16_LE && input == FMT_S16_BE) || | |
283 (output == FMT_S16_LE && input == FMT_U16_BE)))) | |
284 return convert_swap_sign_and_endian_to_alien; | |
285 | |
286 if ((IS_BIG_ENDIAN && | |
287 ((output == FMT_U8 && input == FMT_U16_BE) || | |
288 (output == FMT_S8 && input == FMT_S16_BE))) || | |
289 (!IS_BIG_ENDIAN && | |
290 ((output == FMT_U8 && input == FMT_U16_LE) || | |
291 (output == FMT_S8 && input == FMT_S16_LE)))) | |
292 return convert_to_8_native_endian; | |
293 | |
294 if ((IS_BIG_ENDIAN && | |
295 ((output == FMT_U8 && input == FMT_S16_BE) || | |
296 (output == FMT_S8 && input == FMT_U16_BE))) || | |
297 (!IS_BIG_ENDIAN && | |
298 ((output == FMT_U8 && input == FMT_S16_LE) || | |
299 (output == FMT_S8 && input == FMT_U16_LE)))) | |
300 return convert_to_8_native_endian_swap_sign; | |
301 | |
302 if ((!IS_BIG_ENDIAN && | |
303 ((output == FMT_U8 && input == FMT_U16_BE) || | |
304 (output == FMT_S8 && input == FMT_S16_BE))) || | |
305 (IS_BIG_ENDIAN && | |
306 ((output == FMT_U8 && input == FMT_U16_LE) || | |
307 (output == FMT_S8 && input == FMT_S16_LE)))) | |
308 return convert_to_8_alien_endian; | |
309 | |
310 if ((!IS_BIG_ENDIAN && | |
311 ((output == FMT_U8 && input == FMT_S16_BE) || | |
312 (output == FMT_S8 && input == FMT_U16_BE))) || | |
313 (IS_BIG_ENDIAN && | |
314 ((output == FMT_U8 && input == FMT_S16_LE) || | |
315 (output == FMT_S8 && input == FMT_U16_LE)))) | |
316 return convert_to_8_alien_endian_swap_sign; | |
317 | |
318 if ((output == FMT_U8 && input == FMT_S8) || | |
319 (output == FMT_S8 && input == FMT_U8)) | |
320 return convert_swap_sign8; | |
321 | |
322 if ((IS_BIG_ENDIAN && | |
323 ((output == FMT_U16_BE && input == FMT_U8) || | |
324 (output == FMT_S16_BE && input == FMT_S8))) || | |
325 (!IS_BIG_ENDIAN && | |
326 ((output == FMT_U16_LE && input == FMT_U8) || | |
327 (output == FMT_S16_LE && input == FMT_S8)))) | |
328 return convert_to_16_native_endian; | |
329 | |
330 if ((IS_BIG_ENDIAN && | |
331 ((output == FMT_U16_BE && input == FMT_S8) || | |
332 (output == FMT_S16_BE && input == FMT_U8))) || | |
333 (!IS_BIG_ENDIAN && | |
334 ((output == FMT_U16_LE && input == FMT_S8) || | |
335 (output == FMT_S16_LE && input == FMT_U8)))) | |
336 return convert_to_16_native_endian_swap_sign; | |
337 | |
338 if ((!IS_BIG_ENDIAN && | |
339 ((output == FMT_U16_BE && input == FMT_U8) || | |
340 (output == FMT_S16_BE && input == FMT_S8))) || | |
341 (IS_BIG_ENDIAN && | |
342 ((output == FMT_U16_LE && input == FMT_U8) || | |
343 (output == FMT_S16_LE && input == FMT_S8)))) | |
344 return convert_to_16_alien_endian; | |
345 | |
346 if ((!IS_BIG_ENDIAN && | |
347 ((output == FMT_U16_BE && input == FMT_S8) || | |
348 (output == FMT_S16_BE && input == FMT_U8))) || | |
349 (IS_BIG_ENDIAN && | |
350 ((output == FMT_U16_LE && input == FMT_S8) || | |
351 (output == FMT_S16_LE && input == FMT_U8)))) | |
352 return convert_to_16_alien_endian_swap_sign; | |
353 | |
354 g_warning("Translation needed, but not available.\n" | |
355 "Input: %d; Output %d.", input, output); | |
356 return NULL; | |
357 } | |
358 | |
359 static int | |
360 convert_mono_to_stereo(struct xmms_convert_buffers *buf, | |
361 void **data, int length, int b16) | |
362 { | |
363 int i; | |
364 void *outbuf = convert_get_buffer(&buf->stereo_buffer, length * 2); | |
365 | |
366 if (b16) { | |
367 guint16 *output = outbuf, *input = *data; | |
368 for (i = 0; i < length / 2; i++) { | |
369 *output++ = *input; | |
370 *output++ = *input; | |
371 input++; | |
372 } | |
373 } | |
374 else { | |
375 guint8 *output = outbuf, *input = *data; | |
376 for (i = 0; i < length; i++) { | |
377 *output++ = *input; | |
378 *output++ = *input; | |
379 input++; | |
380 } | |
381 } | |
382 *data = outbuf; | |
383 | |
384 return length * 2; | |
385 } | |
386 | |
387 static int | |
388 convert_mono_to_stereo_8(struct xmms_convert_buffers *buf, | |
389 void **data, int length) | |
390 { | |
391 return convert_mono_to_stereo(buf, data, length, FALSE); | |
392 } | |
393 | |
394 static int | |
395 convert_mono_to_stereo_16(struct xmms_convert_buffers *buf, | |
396 void **data, int length) | |
397 { | |
398 return convert_mono_to_stereo(buf, data, length, TRUE); | |
399 } | |
400 | |
401 static int | |
402 convert_stereo_to_mono_u8(struct xmms_convert_buffers *buf, | |
403 void **data, int length) | |
404 { | |
405 guint8 *output = *data, *input = *data; | |
406 int i; | |
407 for (i = 0; i < length / 2; i++) { | |
408 guint16 tmp; | |
409 tmp = *input++; | |
410 tmp += *input++; | |
411 *output++ = tmp / 2; | |
412 } | |
413 return length / 2; | |
414 } | |
415 static int | |
416 convert_stereo_to_mono_s8(struct xmms_convert_buffers *buf, | |
417 void **data, int length) | |
418 { | |
419 gint8 *output = *data, *input = *data; | |
420 int i; | |
421 for (i = 0; i < length / 2; i++) { | |
422 gint16 tmp; | |
423 tmp = *input++; | |
424 tmp += *input++; | |
425 *output++ = tmp / 2; | |
426 } | |
427 return length / 2; | |
428 } | |
429 static int | |
430 convert_stereo_to_mono_u16le(struct xmms_convert_buffers *buf, | |
431 void **data, int length) | |
432 { | |
433 guint16 *output = *data, *input = *data; | |
434 int i; | |
435 for (i = 0; i < length / 4; i++) { | |
436 guint32 tmp; | |
437 guint16 stmp; | |
438 tmp = GUINT16_FROM_LE(*input); | |
439 input++; | |
440 tmp += GUINT16_FROM_LE(*input); | |
441 input++; | |
442 stmp = tmp / 2; | |
443 *output++ = GUINT16_TO_LE(stmp); | |
444 } | |
445 return length / 2; | |
446 } | |
447 | |
448 static int | |
449 convert_stereo_to_mono_u16be(struct xmms_convert_buffers *buf, | |
450 void **data, int length) | |
451 { | |
452 guint16 *output = *data, *input = *data; | |
453 int i; | |
454 for (i = 0; i < length / 4; i++) { | |
455 guint32 tmp; | |
456 guint16 stmp; | |
457 tmp = GUINT16_FROM_BE(*input); | |
458 input++; | |
459 tmp += GUINT16_FROM_BE(*input); | |
460 input++; | |
461 stmp = tmp / 2; | |
462 *output++ = GUINT16_TO_BE(stmp); | |
463 } | |
464 return length / 2; | |
465 } | |
466 | |
467 static int | |
468 convert_stereo_to_mono_s16le(struct xmms_convert_buffers *buf, | |
469 void **data, int length) | |
470 { | |
471 gint16 *output = *data, *input = *data; | |
472 int i; | |
473 for (i = 0; i < length / 4; i++) { | |
474 gint32 tmp; | |
475 gint16 stmp; | |
476 tmp = GINT16_FROM_LE(*input); | |
477 input++; | |
478 tmp += GINT16_FROM_LE(*input); | |
479 input++; | |
480 stmp = tmp / 2; | |
481 *output++ = GINT16_TO_LE(stmp); | |
482 } | |
483 return length / 2; | |
484 } | |
485 | |
486 static int | |
487 convert_stereo_to_mono_s16be(struct xmms_convert_buffers *buf, | |
488 void **data, int length) | |
489 { | |
490 gint16 *output = *data, *input = *data; | |
491 int i; | |
492 for (i = 0; i < length / 4; i++) { | |
493 gint32 tmp; | |
494 gint16 stmp; | |
495 tmp = GINT16_FROM_BE(*input); | |
496 input++; | |
497 tmp += GINT16_FROM_BE(*input); | |
498 input++; | |
499 stmp = tmp / 2; | |
500 *output++ = GINT16_TO_BE(stmp); | |
501 } | |
502 return length / 2; | |
503 } | |
504 | |
505 convert_channel_func_t | |
506 xmms_convert_get_channel_func(AFormat fmt, int output, int input) | |
507 { | |
508 fmt = unnativize(fmt); | |
509 | |
510 if (output == input) | |
511 return NULL; | |
512 | |
513 if (input == 1 && output == 2) | |
514 switch (fmt) { | |
515 case FMT_U8: | |
516 case FMT_S8: | |
517 return convert_mono_to_stereo_8; | |
518 case FMT_U16_LE: | |
519 case FMT_U16_BE: | |
520 case FMT_S16_LE: | |
521 case FMT_S16_BE: | |
522 return convert_mono_to_stereo_16; | |
523 default: | |
524 g_warning("Unknown format: %d" "No conversion available.", fmt); | |
525 return NULL; | |
526 } | |
527 if (input == 2 && output == 1) | |
528 switch (fmt) { | |
529 case FMT_U8: | |
530 return convert_stereo_to_mono_u8; | |
531 case FMT_S8: | |
532 return convert_stereo_to_mono_s8; | |
533 case FMT_U16_LE: | |
534 return convert_stereo_to_mono_u16le; | |
535 case FMT_U16_BE: | |
536 return convert_stereo_to_mono_u16be; | |
537 case FMT_S16_LE: | |
538 return convert_stereo_to_mono_s16le; | |
539 case FMT_S16_BE: | |
540 return convert_stereo_to_mono_s16be; | |
541 default: | |
542 g_warning("Unknown format: %d. " | |
543 "No conversion available.", fmt); | |
544 return NULL; | |
545 | |
546 } | |
547 | |
548 g_warning("Input has %d channels, soundcard uses %d channels\n" | |
549 "No conversion is available", input, output); | |
550 return NULL; | |
551 } | |
552 | |
553 | |
554 #define RESAMPLE_STEREO(sample_type, bswap) \ | |
555 const int shift = sizeof (sample_type); \ | |
556 int i, in_samples, out_samples, x, delta; \ | |
557 sample_type *inptr = *data, *outptr; \ | |
558 guint nlen = (((length >> shift) * ofreq) / ifreq); \ | |
559 void *nbuf; \ | |
560 if (nlen == 0) \ | |
561 return 0; \ | |
562 nlen <<= shift; \ | |
563 if (bswap) \ | |
564 convert_swap_endian(NULL, data, length); \ | |
565 nbuf = convert_get_buffer(&buf->freq_buffer, nlen); \ | |
566 outptr = nbuf; \ | |
567 in_samples = length >> shift; \ | |
568 out_samples = nlen >> shift; \ | |
569 delta = (in_samples << 12) / out_samples; \ | |
570 for (x = 0, i = 0; i < out_samples; i++) \ | |
571 { \ | |
572 int x1, frac; \ | |
573 x1 = (x >> 12) << 12; \ | |
574 frac = x - x1; \ | |
575 *outptr++ = \ | |
576 ((inptr[(x1 >> 12) << 1] * \ | |
577 ((1<<12) - frac) + \ | |
578 inptr[((x1 >> 12) + 1) << 1] * \ | |
579 frac) >> 12); \ | |
580 *outptr++ = \ | |
581 ((inptr[((x1 >> 12) << 1) + 1] * \ | |
582 ((1<<12) - frac) + \ | |
583 inptr[(((x1 >> 12) + 1) << 1) + 1] * \ | |
584 frac) >> 12); \ | |
585 x += delta; \ | |
586 } \ | |
587 if (bswap) \ | |
588 convert_swap_endian(NULL, &nbuf, nlen); \ | |
589 *data = nbuf; \ | |
590 return nlen; \ | |
591 | |
592 | |
593 #define RESAMPLE_MONO(sample_type, bswap) \ | |
594 const int shift = sizeof (sample_type) - 1; \ | |
595 int i, x, delta, in_samples, out_samples; \ | |
596 sample_type *inptr = *data, *outptr; \ | |
597 guint nlen = (((length >> shift) * ofreq) / ifreq); \ | |
598 void *nbuf; \ | |
599 if (nlen == 0) \ | |
600 return 0; \ | |
601 nlen <<= shift; \ | |
602 if (bswap) \ | |
603 convert_swap_endian(NULL, data, length); \ | |
604 nbuf = convert_get_buffer(&buf->freq_buffer, nlen); \ | |
605 outptr = nbuf; \ | |
606 in_samples = length >> shift; \ | |
607 out_samples = nlen >> shift; \ | |
608 delta = ((length >> shift) << 12) / out_samples; \ | |
609 for (x = 0, i = 0; i < out_samples; i++) \ | |
610 { \ | |
611 int x1, frac; \ | |
612 x1 = (x >> 12) << 12; \ | |
613 frac = x - x1; \ | |
614 *outptr++ = \ | |
615 ((inptr[x1 >> 12] * ((1<<12) - frac) + \ | |
616 inptr[(x1 >> 12) + 1] * frac) >> 12); \ | |
617 x += delta; \ | |
618 } \ | |
619 if (bswap) \ | |
620 convert_swap_endian(NULL, &nbuf, nlen); \ | |
621 *data = nbuf; \ | |
622 return nlen; \ | |
623 | |
624 static int | |
625 convert_resample_stereo_s16ne(struct xmms_convert_buffers *buf, | |
626 void **data, int length, int ifreq, int ofreq) | |
627 { | |
628 RESAMPLE_STEREO(gint16, FALSE); | |
629 } | |
630 | |
631 static int | |
632 convert_resample_stereo_s16ae(struct xmms_convert_buffers *buf, | |
633 void **data, int length, int ifreq, int ofreq) | |
634 { | |
635 RESAMPLE_STEREO(gint16, TRUE); | |
636 } | |
637 | |
638 static int | |
639 convert_resample_stereo_u16ne(struct xmms_convert_buffers *buf, | |
640 void **data, int length, int ifreq, int ofreq) | |
641 { | |
642 RESAMPLE_STEREO(guint16, FALSE); | |
643 } | |
644 | |
645 static int | |
646 convert_resample_stereo_u16ae(struct xmms_convert_buffers *buf, | |
647 void **data, int length, int ifreq, int ofreq) | |
648 { | |
649 RESAMPLE_STEREO(guint16, TRUE); | |
650 } | |
651 | |
652 static int | |
653 convert_resample_mono_s16ne(struct xmms_convert_buffers *buf, | |
654 void **data, int length, int ifreq, int ofreq) | |
655 { | |
656 RESAMPLE_MONO(gint16, FALSE); | |
657 } | |
658 | |
659 static int | |
660 convert_resample_mono_s16ae(struct xmms_convert_buffers *buf, | |
661 void **data, int length, int ifreq, int ofreq) | |
662 { | |
663 RESAMPLE_MONO(gint16, TRUE); | |
664 } | |
665 | |
666 static int | |
667 convert_resample_mono_u16ne(struct xmms_convert_buffers *buf, | |
668 void **data, int length, int ifreq, int ofreq) | |
669 { | |
670 RESAMPLE_MONO(guint16, FALSE); | |
671 } | |
672 | |
673 static int | |
674 convert_resample_mono_u16ae(struct xmms_convert_buffers *buf, | |
675 void **data, int length, int ifreq, int ofreq) | |
676 { | |
677 RESAMPLE_MONO(guint16, TRUE); | |
678 } | |
679 | |
680 static int | |
681 convert_resample_stereo_u8(struct xmms_convert_buffers *buf, | |
682 void **data, int length, int ifreq, int ofreq) | |
683 { | |
684 RESAMPLE_STEREO(guint8, FALSE); | |
685 } | |
686 | |
687 static int | |
688 convert_resample_mono_u8(struct xmms_convert_buffers *buf, | |
689 void **data, int length, int ifreq, int ofreq) | |
690 { | |
691 RESAMPLE_MONO(guint8, FALSE); | |
692 } | |
693 | |
694 static int | |
695 convert_resample_stereo_s8(struct xmms_convert_buffers *buf, | |
696 void **data, int length, int ifreq, int ofreq) | |
697 { | |
698 RESAMPLE_STEREO(gint8, FALSE); | |
699 } | |
700 | |
701 static int | |
702 convert_resample_mono_s8(struct xmms_convert_buffers *buf, | |
703 void **data, int length, int ifreq, int ofreq) | |
704 { | |
705 RESAMPLE_MONO(gint8, FALSE); | |
706 } | |
707 | |
708 | |
709 convert_freq_func_t | |
710 xmms_convert_get_frequency_func(AFormat fmt, int channels) | |
711 { | |
712 fmt = unnativize(fmt); | |
713 g_message("fmt %d, channels: %d", fmt, channels); | |
714 | |
715 if (channels < 1 || channels > 2) { | |
716 g_warning("Unsupported number of channels: %d. " | |
717 "Resample function not available", channels); | |
718 return NULL; | |
719 } | |
720 if ((IS_BIG_ENDIAN && fmt == FMT_U16_BE) || | |
721 (!IS_BIG_ENDIAN && fmt == FMT_U16_LE)) { | |
722 if (channels == 1) | |
723 return convert_resample_mono_u16ne; | |
724 else | |
725 return convert_resample_stereo_u16ne; | |
726 } | |
727 if ((IS_BIG_ENDIAN && fmt == FMT_S16_BE) || | |
728 (!IS_BIG_ENDIAN && fmt == FMT_S16_LE)) { | |
729 if (channels == 1) | |
730 return convert_resample_mono_s16ne; | |
731 else | |
732 return convert_resample_stereo_s16ne; | |
733 } | |
734 if ((!IS_BIG_ENDIAN && fmt == FMT_U16_BE) || | |
735 (IS_BIG_ENDIAN && fmt == FMT_U16_LE)) { | |
736 if (channels == 1) | |
737 return convert_resample_mono_u16ae; | |
738 else | |
739 return convert_resample_stereo_u16ae; | |
740 } | |
741 if ((!IS_BIG_ENDIAN && fmt == FMT_S16_BE) || | |
742 (IS_BIG_ENDIAN && fmt == FMT_S16_LE)) { | |
743 if (channels == 1) | |
744 return convert_resample_mono_s16ae; | |
745 else | |
746 return convert_resample_stereo_s16ae; | |
747 } | |
748 if (fmt == FMT_U8) { | |
749 if (channels == 1) | |
750 return convert_resample_mono_u8; | |
751 else | |
752 return convert_resample_stereo_u8; | |
753 } | |
754 if (fmt == FMT_S8) { | |
755 if (channels == 1) | |
756 return convert_resample_mono_s8; | |
757 else | |
758 return convert_resample_stereo_s8; | |
759 } | |
760 g_warning("Resample function not available" "Format %d.", fmt); | |
761 return NULL; | |
762 } |