source: roaraudio/libroardsp/convert.c @ 2749:bbb02514597a

Last change on this file since 2749:bbb02514597a was 2749:bbb02514597a, checked in by phi, 15 years ago

new prototypes

File size: 27.6 KB
Line 
1//convert.c:
2
3/*
4 *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008
5 *
6 *  This file is part of libroar a part of RoarAudio,
7 *  a cross-platform sound system for both, home and professional use.
8 *  See README for details.
9 *
10 *  This file is free software; you can redistribute it and/or modify
11 *  it under the terms of the GNU General Public License version 3
12 *  as published by the Free Software Foundation.
13 *
14 *  libroar is distributed in the hope that it will be useful,
15 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 *  GNU General Public License for more details.
18 *
19 *  You should have received a copy of the GNU General Public License
20 *  along with this software; see the file COPYING.  If not, write to
21 *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
22 *
23 *  NOTE for everyone want's to change something and send patches:
24 *  read README and HACKING! There a addition information on
25 *  the license of this document you need to read before you send
26 *  any patches.
27 *
28 *  NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc
29 *  or libpulse*:
30 *  The libs libroaresd, libroararts and libroarpulse link this lib
31 *  and are therefore GPL. Because of this it may be illigal to use
32 *  them with any software that uses libesd, libartsc or libpulse*.
33 */
34
35#include "libroardsp.h"
36//#define free(p) {ROAR_WARN("free(%p) = ?", (p)); free((p)); ROAR_WARN("free(%p): OK", (p));}
37
38int roar_conv_bits (void * out, void * in, int samples, int from, int to) {
39 int format;
40
41 if ( from == to ) {
42  if ( in == out )
43   return 0;
44
45  memcpy(out, in, samples * from / 8);
46  return 0;
47 }
48
49 format = ((from / 8) << 4) + (to / 8);
50
51 switch (format) {
52  case 0x12: return roar_conv_bits_8to16( out, in, samples);
53  case 0x14: return roar_conv_bits_8to32( out, in, samples);
54  case 0x21: return roar_conv_bits_16to8( out, in, samples);
55  case 0x24: return roar_conv_bits_16to32(out, in, samples);
56  case 0x34: return roar_conv_bits_24to32(out, in, samples);
57  case 0x41: return roar_conv_bits_32to8( out, in, samples);
58  case 0x42: return roar_conv_bits_32to16(out, in, samples);
59  default:
60   errno = ENOSYS;
61   return -1;
62 }
63
64 return -1;
65}
66
67int roar_conv_bits_8to16 (void * out, void * in, int samples) {
68 char    * ip = (char   *)in;
69 int16_t * op = (int16_t*)out;
70 int i;
71
72 for (i = samples - 1; i >= 0; i--)
73  op[i] = ip[i] << 8;
74
75 return 0;
76}
77
78int roar_conv_bits_8to32  (void * out, void * in, int samples) {
79 char    * ip = (char   *)in;
80 int32_t * op = (int32_t*)out;
81 int i;
82
83 for (i = samples - 1; i >= 0; i--)
84  op[i] = (int32_t) ip[i] << 24;
85
86 return 0;
87}
88
89int roar_conv_bits_16to8 (void * out, void * in, int samples) {
90 int16_t * ip = (int16_t*)in;
91 char    * op = (char   *)out;
92 int i;
93
94 ROAR_DBG("roar_conv_bits_16to8(out=%p, in=%p, samples=%i) = ?", out, in, samples);
95
96 for (i = 0; i < samples; i++)
97  op[i] = ip[i] >> 8;
98
99 return 0;
100}
101
102int roar_conv_bits_16to32 (void * out, void * in, int samples) {
103 int16_t * ip = (int16_t*)in;
104 int32_t * op = (int32_t*)out;
105 int i;
106
107 for (i = samples - 1; i >= 0; i--)
108  op[i] = (int32_t) ip[i] << 16;
109
110 return 0;
111}
112
113int roar_conv_bits_24to32 (void * out, void * in, int samples) {
114 uint8_t * ip = (uint8_t*)in;
115 int32_t * op = (int32_t*)out;
116 int i;
117 union {
118  int32_t i;
119  uint8_t c[4];
120 } t;
121
122 ROAR_DBG("roar_conv_bits_24to32(out=%p, in=%p, samples=%i) = ?", out, in, samples);
123
124#if (BYTE_ORDER == BIG_ENDIAN) || (BYTE_ORDER == LITTLE_ENDIAN)
125 t.i = 0;
126#else
127  ROAR_DBG("roar_conv_bits_24to32(out=%p, in=%p, samples=%i) = -1", out, in, samples);
128  return -1;
129#endif
130
131 samples--;
132 ip += 3 * samples;
133
134 for (i = samples; i >= 0; i--) {
135#if BYTE_ORDER == BIG_ENDIAN
136  t.c[0] = *(ip--);
137  t.c[1] = *(ip--);
138  t.c[2] = *(ip--);
139#elif BYTE_ORDER == LITTLE_ENDIAN
140  t.c[2] = *(ip--);
141  t.c[3] = *(ip--);
142  t.c[1] = *(ip--);
143#endif
144  ROAR_DBG("roar_conv_bits_24to32(*): i=%i, t.i=0x%.8X", i, t.i);
145  op[i] = t.i;
146 }
147
148 ROAR_DBG("roar_conv_bits_24to32(out=%p, in=%p, samples=%i) = 0", out, in, samples);
149 return 0;
150}
151
152int roar_conv_bits_32to8 (void * out, void * in, int samples) {
153 int32_t * ip = (int32_t*)in;
154 char    * op = (char   *)out;
155 int i;
156
157 for (i = 0; i < samples; i++)
158  op[i] = ip[i] >> 24;
159
160 return 0;
161}
162
163int roar_conv_bits_32to16 (void * out, void * in, int samples) {
164 int32_t * ip = (int32_t*)in;
165 int16_t * op = (int16_t*)out;
166 int i;
167
168 for (i = 0; i < samples; i++)
169  op[i] = ip[i] >> 16;
170
171 return 0;
172}
173
174int roar_conv_chans (void * out, void * in, int samples, int from, int to, int bits) {
175 if ( from == to ) {
176  if ( in == out )
177   return 0;
178
179  memcpy(out, in, samples * from * bits / 8);
180  return 0;
181 }
182
183 switch (bits) {
184  case 8:
185   switch (from) {
186    case 1:
187     switch (to) {
188      case  2: return roar_conv_chans_1to28(out, in, samples);
189      default: return roar_conv_chans_1ton8(out, in, samples, to);
190     }
191     break;
192    case 2:
193     switch (to) {
194      case  1: return roar_conv_chans_2to18(out, in, samples);
195      default: return -1;
196     }
197     break;
198    default:
199     switch (to) {
200      case  1: return roar_conv_chans_nto18(out, in, samples, from);
201      default: return -1;
202     }
203   }
204  break;
205  case 16:
206   switch (from) {
207    case 1:
208     switch (to) {
209      case  2: return roar_conv_chans_1to216(out, in, samples);
210      default: return roar_conv_chans_1ton16(out, in, samples, to);
211     }
212     break;
213    case 2:
214     switch (to) {
215      case  1: return roar_conv_chans_2to116(out, in, samples);
216      case  3: return roar_conv_chans_2to316(out, in, samples);
217      case  4: return roar_conv_chans_2to416(out, in, samples);
218      case  5: return roar_conv_chans_2to516(out, in, samples);
219      case  6: return roar_conv_chans_2to616(out, in, samples);
220      default: return -1;
221     }
222     break;
223    default:
224     switch (to) {
225      case  1: return roar_conv_chans_nto116(out, in, samples, from);
226      default: return -1;
227     }
228   }
229  break;
230  default: return -1;
231 }
232
233 return -1;
234}
235
236int roar_conv_chans_1ton8  (void * out, void * in, int samples, int to) {
237 char * ip = (char*) in, * op = (char*) out;
238 int i;
239 int c;
240
241 for (i = samples - 1; i >= 0; i--)
242  for (c = to - 1; c >= 0; c--)
243   op[i*to + c] = ip[i];
244
245 return 0;
246}
247
248int roar_conv_chans_1to28  (void * out, void * in, int samples) {
249 char * ip = (char*) in, * op = (char*) out;
250 int i, h;
251
252 samples--;
253
254 for (i = (h = samples) * 2; i >= 0; i -= 2, h--) {
255  op[i + 0] = ip[h];
256  op[i + 1] = ip[h];
257 }
258
259 return 0;
260}
261
262int roar_conv_chans_1ton16 (void * out, void * in, int samples, int to) {
263 int16_t * ip = (int16_t*) in, * op = (int16_t*) out;
264 int i;
265 int c;
266
267 for (i = samples - 1; i >= 0; i--)
268  for (c = to - 1; c >= 0; c--)
269   op[i*to + c] = ip[i];
270
271 return 0;
272}
273
274int roar_conv_chans_1to216 (void * out, void * in, int samples) {
275 int16_t * ip = (int16_t*) in, * op = (int16_t*) out;
276 int i, h;
277
278 samples--;
279
280 for (i = (h = samples) * 2; i >= 0; i -= 2, h--) {
281  op[i + 0] = ip[h];
282  op[i + 1] = ip[h];
283 }
284
285 return 0;
286}
287
288int roar_conv_chans_nto18  (void * out, void * in, int samples, int from) {
289 int8_t * ip = (int8_t*) in, * op = (int8_t*) out;
290 int i;
291 int c;
292 register int s;
293
294 samples /= from;
295
296 for (i = samples - 1; i >= 0; i--) {
297  s  = 0;
298
299  for (c = 0; c < from; c++)
300   s += ip[i*from + c];
301
302  s /= from;
303  op[i] = s;
304 }
305
306 return 0;
307}
308
309int roar_conv_chans_2to18  (void * out, void * in, int samples) {
310 int8_t * ip = (int8_t*) in, * op = (int8_t*) out;
311 int i, h;
312
313 samples -= 2;
314
315 for (h = (i = samples) / 2; i >= 0; i -= 2, h--)
316  op[h] = ((int)ip[i + 0] + (int)ip[i + 1]) / 2;
317
318 return 0;
319}
320
321int roar_conv_chans_nto116 (void * out, void * in, int samples, int from) {
322 int16_t * ip = (int16_t*) in, * op = (int16_t*) out;
323 int i;
324 int c;
325 register int s;
326
327 samples /= from;
328
329 for (i = samples - 1; i >= 0; i--) {
330  s  = 0;
331
332  for (c = 0; c < from; c++)
333   s += ip[i*from + c];
334
335  s /= from;
336  op[i] = s;
337 }
338
339 return 0;
340}
341
342int roar_conv_chans_2to116  (void * out, void * in, int samples) {
343 int16_t * ip = (int16_t*) in, * op = (int16_t*) out;
344 int i, h;
345
346 ROAR_DBG("roar_conv_chans_2to116(out=%p, in=%p, samples=%i) = ?", out, in, samples);
347
348 samples -= 2;
349
350 for (h = (i = samples) / 2; i >= 0; i -= 2, h--) {
351  ROAR_DBG("roar_conv_chans_2to116(out=%p, in=%p, samples=%i): op[%i] = (ip[%i] + ip[%i])/2", out, in, samples, h, i, i+1);
352  op[h] = ((int)ip[i + 0] + (int)ip[i + 1]) / 2;
353 }
354
355 return 0;
356}
357
358int roar_conv_chans_2to38  (void * out, void * in, int samples);
359int roar_conv_chans_2to316 (void * out, void * in, int samples) {
360 int16_t * ip = (int16_t*) in, * op = (int16_t*) out;
361 int i, h;
362
363 samples -= 2;
364
365 i  = samples;
366 h  = (samples / 2) * 3;
367
368 for (; i >= 0; i -= 2, h -= 3) {
369  op[h+0] = ip[i+0];
370  op[h+1] = ip[i+1];
371  op[h+2] = ((int)ip[i + 0] + (int)ip[i + 1]) / 2;
372 }
373
374 return 0;
375}
376
377int roar_conv_chans_2to48  (void * out, void * in, int samples);
378int roar_conv_chans_2to416 (void * out, void * in, int samples) {
379 int16_t * ip = (int16_t*) in, * op = (int16_t*) out;
380 int i, h;
381
382 samples -= 2;
383
384 i  = samples;
385 h  = (samples / 2) * 4;
386
387 for (; i >= 0; i -= 2, h -= 4) {
388  op[h+0] = ip[i+0];
389  op[h+1] = ip[i+1];
390  op[h+2] = ip[i+0];
391  op[h+3] = ip[i+1];
392 }
393
394 return 0;
395}
396
397int roar_conv_chans_2to58  (void * out, void * in, int samples);
398int roar_conv_chans_2to516 (void * out, void * in, int samples) {
399 int16_t * ip = (int16_t*) in, * op = (int16_t*) out;
400 int i, h;
401
402 samples -= 2;
403
404 i  = samples;
405 h  = (samples / 2) * 5;
406
407 for (; i >= 0; i -= 2, h -= 5) {
408  op[h+0] = ip[i+0];
409  op[h+1] = ip[i+1];
410  op[h+2] = ((int)ip[i + 0] + (int)ip[i + 1]) / 2;
411  op[h+3] = ip[i+0];
412  op[h+4] = ip[i+1];
413 }
414
415 return 0;
416}
417int roar_conv_chans_2to68  (void * out, void * in, int samples);
418int roar_conv_chans_2to616 (void * out, void * in, int samples) {
419 int16_t * ip = (int16_t*) in, * op = (int16_t*) out;
420 int i, h;
421
422 samples -= 2;
423
424 i  = samples;
425 h  = (samples / 2) * 6;
426
427 for (; i >= 0; i -= 2, h -= 6) {
428  op[h+0] = ip[i+0];
429  op[h+1] = ip[i+1];
430  op[h+2] = ((int)ip[i + 0] + (int)ip[i + 1]) / 2;
431  op[h+3] = op[h+2];
432  op[h+4] = ip[i+0];
433  op[h+5] = ip[i+1];
434 }
435
436 return 0;
437}
438
439int roar_conv_chans_3to28  (void * out, void * in, int samples);
440int roar_conv_chans_3to216 (void * out, void * in, int samples);
441int roar_conv_chans_4to28  (void * out, void * in, int samples);
442int roar_conv_chans_4to216 (void * out, void * in, int samples);
443int roar_conv_chans_5to28  (void * out, void * in, int samples);
444int roar_conv_chans_5to216 (void * out, void * in, int samples);
445int roar_conv_chans_6to28  (void * out, void * in, int samples);
446int roar_conv_chans_6to216 (void * out, void * in, int samples);
447
448
449
450int roar_conv_rate (void * out, void * in, int samples, int from, int to, int bits, int channels) {
451#ifdef ROAR_HAVE_LIBSAMPLERATE
452 return roar_conv_rate_SRC(out, in, samples, from, to, bits, channels);
453#else
454 if ( bits == 8  )
455  return roar_conv_rate_8(out, in, samples, from, to, channels);
456
457 if ( bits == 16 )
458  return roar_conv_rate_16(out, in, samples, from, to, channels);
459
460 return -1;
461#endif
462}
463
464int roar_conv_rate_8  (void * out, void * in, int samples, int from, int to, int channels) {
465 return -1;
466}
467
468int roar_conv_rate_16 (void * out, void * in, int samples, int from, int to, int channels) {
469 if ( from > to ) {
470  switch (channels) {
471   case 1:
472     return roar_conv_rate_161zoh(out, in, samples, from, to);
473   case 2:
474     return roar_conv_rate_162zoh(out, in, samples, from, to);
475   default:
476     return -1;
477  }
478 } else {
479  if ( channels == 1 ) {
480   printf("roar_conv_rate_16(): samples=%i -> %i, rate=%i -> %i\n", samples*from/to, samples, from, to);
481   return roar_conv_poly4_16s((int16_t*) out, (int16_t*) in, samples, samples*from/to, (float)from/to);
482 //  return roar_conv_poly4_16((int16_t*) out, (int16_t*) in, samples*to/from, samples);
483  }
484 }
485
486 return -1;
487}
488
489int roar_conv_rate_161zoh(void * out, void * in, int samples, int from, int to) {
490 int16_t * ip = in;
491 int16_t * op = out;
492 float t = 0;
493 float step = (float)to/from;
494 int i;
495
496 for (i= 0; i < samples; i++) {
497  op[(int)t] = ip[i];
498  t += step;
499 }
500
501 return 0;
502}
503
504int roar_conv_rate_162zoh(void * out, void * in, int samples, int from, int to) {
505 int16_t * ip = in;
506 int16_t * op = out;
507 float t = 0;
508 float step = (float)to/from;
509 int i;
510
511 ROAR_DBG("roar_conv_rate_162zoh(*): samples=%i", samples);
512 samples /= 2;
513// samples -= 1;
514 ROAR_DBG("roar_conv_rate_162zoh(*): samples=%i", samples);
515
516 for (i= 0; i < samples; i++) {
517  ROAR_DBG("roar_conv_rate_162zoh(*): t=%f, i=%i // op[%i] = ip[%i]", t, i, 2*(int)t, 2*i);
518  op[2*(int)t    ] = ip[2*i    ];
519  op[2*(int)t + 1] = ip[2*i + 1];
520  t += step;
521 }
522
523 return 0;
524}
525
526int roar_conv_rate_SRC   (void * out, void * in, int samples, int from, int to, int bits, int channels) {
527#ifdef ROAR_HAVE_LIBSAMPLERATE
528 double radio = (double) to / (double) from;
529 int outsamples = radio * samples;
530 float * inf  = malloc(samples*sizeof(float));
531 float * outf = malloc(outsamples*sizeof(float));
532 int i;
533 SRC_DATA srcdata;
534
535 ROAR_DBG("roar_conv_rate_SRC(*): radio=%lf, samples=%i, outsamples=%i", radio, samples, outsamples);
536
537 if ( inf == NULL ) {
538  if ( outf != NULL )
539   free(outf);
540
541  return -1;
542 }
543
544 if ( outf == NULL ) {
545  if ( inf != NULL )
546   free(inf);
547
548  return -1;
549 }
550
551 switch (bits) {
552  case  8:
553    for (i = 0; i < samples; i++)
554     inf[i] = *(((int8_t *)in)+i) / 128.0;
555   break;
556  case 16:
557    for (i = 0; i < samples; i++)
558     inf[i] = *(((int16_t*)in)+i) / 32768.0;
559   break;
560  case 32:
561    for (i = 0; i < samples; i++)
562     inf[i] = *(((int32_t*)in)+i) / 2147483648.0;
563   break;
564  default:
565    free(outf);
566    free(inf);
567    return -1;
568 }
569
570 srcdata.data_in       = inf;
571 srcdata.data_out      = outf;
572 srcdata.input_frames  = samples/channels;
573 srcdata.output_frames = outsamples/channels;
574 srcdata.src_ratio     = radio;
575
576 if ( src_simple(&srcdata, SRC_ZERO_ORDER_HOLD, channels) != 0 ) {
577  free(outf);
578  free(inf);
579  return -1;
580 }
581
582 switch (bits) {
583  case  8:
584    for (i = 0; i < outsamples; i++)
585     *(((int8_t *)out)+i) = outf[i] * 128.0;
586   break;
587  case 16:
588    for (i = 0; i < outsamples; i++)
589     *(((int16_t*)out)+i) = outf[i] * 32768.0;
590   break;
591  case 32:
592    for (i = 0; i < outsamples; i++)
593     *(((int32_t*)out)+i) = outf[i] * 2147483648.0;
594   break;
595   // no errors here, they are handled above
596 }
597
598 free(outf);
599 free(inf);
600
601 return 0;
602#else
603 return -1;
604#endif
605}
606
607int roar_conv_signedness  (void * out, void * in, int samples, int from, int to, int bits) {
608
609 if ( from != to ) {
610  if ( from && !to ) {
611   switch (bits) {
612    case  8: roar_conv_codec_s2u8( out, in, samples); break;
613    case 16: roar_conv_codec_s2u16(out, in, samples); break;
614    case 32: roar_conv_codec_s2u32(out, in, samples); break;
615    default:
616     errno = ENOSYS;
617     return -1;
618   }
619  } else if ( !from && to ) {
620   switch (bits) {
621    case  8: roar_conv_codec_u2s8( out, in, samples); break;
622    case 16: roar_conv_codec_u2s16(out, in, samples); break;
623    case 32: roar_conv_codec_u2s32(out, in, samples); break;
624    default:
625     errno = ENOSYS;
626     return -1;
627   }
628  } else {
629   return -1;
630  }
631 } else {
632  if ( out == in )
633   return 0;
634
635  memcpy(out, in, samples * bits / 8);
636  return 0;
637 }
638
639 return 0;
640}
641
642int roar_conv_codec (void * out, void * in, int samples, int from, int to, int bits) {
643 int inbo = ROAR_CODEC_BYTE_ORDER(from), outbo = ROAR_CODEC_BYTE_ORDER(to);
644 int ins  = ROAR_CODEC_IS_SIGNED(from),  outs  = ROAR_CODEC_IS_SIGNED(to);
645 void * nin = in;
646
647
648 ROAR_DBG("roar_conv_codec(out=%p, in=%p, samples=%i, from=%i(%s), to=%i(%s), bits=%i) = ?",
649              out, in, samples, from, roar_codec2str(from), to, roar_codec2str(to), bits);
650
651 roar_conv_endian(out, in, samples, inbo, outbo, bits);
652 nin = out;
653
654 return roar_conv_signedness(out, in, samples, ins, outs, bits);
655}
656
657int roar_conv_codec_s2u8 (void * out, void * in, int samples) {
658 char * ip = in;
659 unsigned char * op = out;
660 int i;
661
662 for(i = 0; i < samples; i++)
663  op[i] = ip[i] + 128;
664
665 return 0;
666}
667
668int roar_conv_codec_s2u16 (void * out, void * in, int samples) {
669 int16_t  * ip = in;
670 uint16_t * op = out;
671 int i;
672
673 for(i = 0; i < samples; i++)
674  op[i] = ip[i] + 32768;
675
676 return 0;
677}
678
679int roar_conv_codec_s2u32 (void * out, void * in, int samples) {
680 int32_t  * ip = in;
681 uint32_t * op = out;
682 int i;
683
684 for(i = 0; i < samples; i++)
685  op[i] = ip[i] + 2147483648U;
686
687 return 0;
688}
689
690int roar_conv_codec_u2s8 (void * out, void * in, int samples) {
691 unsigned char * ip = in;
692          char * op = out;
693 int i;
694
695 for(i = 0; i < samples; i++)
696  op[i] = ip[i] - 128;
697
698 return 0;
699}
700
701int roar_conv_codec_u2s16 (void * out, void * in, int samples) {
702 uint16_t  * ip = in;
703 int16_t   * op = out;
704 int i;
705
706 for(i = 0; i < samples; i++)
707  op[i] = ip[i] - 32768;
708
709 return 0;
710}
711
712int roar_conv_codec_u2s32 (void * out, void * in, int samples) {
713 uint32_t  * ip = in;
714 int32_t   * op = out;
715 int i;
716
717 for(i = 0; i < samples; i++)
718  op[i] = ip[i] - 2147483648U;
719
720 return 0;
721}
722
723
724int roar_conv_endian      (void * out, void * in, int samples, int from, int to, int bits) {
725
726 if ( bits == 8 ) {
727  from = to = ROAR_CODEC_NATIVE_ENDIAN;
728
729 } else if ( bits == 16 ) {
730  if ( from  == ROAR_CODEC_PDP )
731   from = ROAR_CODEC_LE;
732  if ( to    == ROAR_CODEC_PDP )
733   to   = ROAR_CODEC_LE;
734 }
735
736 ROAR_DBG("roar_conv_endian(out=%p, in=%p, samples=%i, from=%i, to=%i, bits=%i) = ?", out, in, samples, from, to, bits);
737
738 if ( from == to ) {
739  if ( in != out ) {
740   memcpy(out, in, samples * bits / 8);
741  }
742  return 0;
743 } else {
744  if ( bits == 16 ) {
745   // in this case we can only have LE vs. BE, so, only need to swap:
746   ROAR_DBG("roar_conv_endian(*): Doing 16 bit byteswap");
747   return roar_conv_endian_16(out, in, samples);
748  } else if ( bits == 24 ) {
749   if ( (from == ROAR_CODEC_LE || from == ROAR_CODEC_BE) && (to == ROAR_CODEC_LE || to == ROAR_CODEC_BE) ) {
750    return roar_conv_endian_24(out, in, samples);
751   } else { // what the hell is PDP eddines in 24 bit mode?
752    return -1;
753   }
754  } else if ( bits == 32 ) {
755   if ( (from == ROAR_CODEC_LE || from == ROAR_CODEC_BE) && (to == ROAR_CODEC_LE || to == ROAR_CODEC_BE) ) {
756    return roar_conv_endian_32(out, in, samples);
757   } else { // need to handle 32 PDP eddines here?
758    return -1;
759   }
760  } else {
761   return -1;
762  }
763 }
764
765 return -1;
766}
767
768
769int roar_conv_endian_16   (void * out, void * in, int samples) {
770 char          * ip = in;
771 char          * op = out;
772 register char   c;
773 int             i;
774
775 samples *= 2;
776
777 if ( out != in ) {
778//  printf("out != in\n");
779  for(i = 0; i < samples; i += 2) {
780//   printf("op[%i] = ip[%i]\nop[%i] = ip[%i]\n", i, i+1, i+1, i);
781   op[i  ] = ip[i+1];
782   op[i+1] = ip[i  ];
783  }
784 } else {
785//  printf("out == in\n");
786  for(i = 0; i < samples; i += 2) {
787   c       = ip[i+1];
788   op[i+1] = ip[i  ];
789   op[i  ] = c;
790  }
791 }
792
793 return 0;
794}
795
796int roar_conv_endian_24   (void * out, void * in, int samples) {
797 char          * ip = in;
798 char          * op = out;
799 register char   c;
800 int             i;
801
802 samples *= 3;
803
804 if ( out != in ) {
805//  printf("out != in\n");
806  for(i = 0; i < samples; i += 3) {
807//   printf("op[%i] = ip[%i]\nop[%i] = ip[%i]\n", i, i+1, i+1, i);
808   op[i  ] = ip[i+2];
809   op[i+2] = ip[i  ];
810  }
811 } else {
812//  printf("out == in\n");
813  for(i = 0; i < samples; i += 3) {
814   c       = ip[i+2];
815   op[i+2] = ip[i  ];
816   op[i  ] = c;
817  }
818 }
819
820 return 0;
821}
822
823int roar_conv_endian_32   (void * out, void * in, int samples) {
824 int32_t       * ip = in;
825 int32_t       * op = out;
826 union {
827  int32_t val;
828  char    data[4];
829 }               c, h;
830 int             i;
831
832 // may the holly optimizer save our souls!
833
834 ROAR_DBG("roar_conv_endian_32(out=%p, in=%p, samples=%i) = ?", out, in, samples);
835
836 for (i = 0; i < samples; i++) {
837  c.val     = ip[i];
838  h.data[0] = c.data[3];
839  h.data[1] = c.data[2];
840  h.data[2] = c.data[1];
841  h.data[3] = c.data[0];
842  op[i]     = h.val;
843 }
844
845 return 0;
846}
847
848int roar_conv       (void * out, void * in, int samples, struct roar_audio_info * from, struct roar_audio_info * to) {
849 void * ip = in;
850 void * real_out = NULL;
851 size_t from_size, to_size;
852
853 // TODO: decide how to work around both in and out beeing to small to hold all
854 //       data between the steps.
855 //       for the moment: guess out >= in
856
857 from_size = (from->bits * samples) / 8;
858 to_size   = (  to->bits * samples * to->rate * to->channels) / (8 * from->rate * from->channels);
859
860 ROAR_DBG("roar_conv(*): size: %i->%i", from_size, to_size);
861
862 if ( to_size < from_size ) {
863  real_out = out;
864
865  if ( (out = malloc(from_size)) == NULL )
866   return -1;
867
868  ROAR_DBG("roar_conv(*): malloc(%i)=%p", (int)from_size, out);
869 }
870
871 ROAR_DBG("roar_conv(*): bo conv: %i->%i(native)", ROAR_CODEC_BYTE_ORDER(from->codec), ROAR_CODEC_NATIVE_ENDIAN);
872
873 if ( ROAR_CODEC_BYTE_ORDER(from->codec) != ROAR_CODEC_NATIVE_ENDIAN ) {
874  ROAR_DBG("roar_conv(*): doing bo input conv");
875  if ( roar_conv_endian(out, ip, samples, ROAR_CODEC_BYTE_ORDER(from->codec), ROAR_CODEC_NATIVE_ENDIAN, from->bits) == -1 ) {
876   if ( to_size < from_size )
877    free(out);
878   return -1;
879  } else {
880   ip = out;
881  }
882 }
883
884 if ( from->bits != to->bits ) {
885  if ( roar_conv_bits(out, ip, samples, from->bits, to->bits) == -1 ) {
886   if ( to_size < from_size )
887    free(out);
888   return -1;
889  } else {
890   ip = out;
891  }
892 }
893
894 if ( ROAR_CODEC_IS_SIGNED(from->codec) != ROAR_CODEC_IS_SIGNED(to->codec) ) {
895  if ( roar_conv_signedness(out, ip, samples, ROAR_CODEC_IS_SIGNED(from->codec), ROAR_CODEC_IS_SIGNED(to->codec), to->bits) == -1 ) {
896   if ( to_size < from_size )
897    free(out);
898   return -1;
899  } else {
900   ip = out;
901  }
902 }
903
904/*
905 if ( from->codec != to->codec ) {
906  if ( roar_conv_codec (out, ip, samples, from->codec, to->codec, to->bits) == -1 )
907   return -1;
908  else
909   ip = out;
910 }
911*/
912
913 if ( from->rate != to->rate ) {
914  if ( roar_conv_rate(out, ip, samples, from->rate, to->rate, to->bits, from->channels) == -1 ) {
915   ROAR_DBG("roar_conv(*): failed to convert rate %i->%i (%ich%ibits)", from->rate, to->rate, to->bits, from->channels);
916   if ( to_size < from_size )
917    free(out);
918   return -1;
919  } else {
920   ip = out;
921   samples = (samples * to->rate) / from->rate;
922  }
923 }
924
925 if ( from->channels != to->channels ) {
926  if ( roar_conv_chans(out, ip, samples, from->channels, to->channels, to->bits) == -1 ) {
927   if ( to_size < from_size )
928    free(out);
929   return -1;
930  } else {
931   ip = out;
932  }
933 }
934
935 if ( ROAR_CODEC_BYTE_ORDER(to->codec) != ROAR_CODEC_NATIVE_ENDIAN ) {
936  if ( roar_conv_endian(out, ip, samples, ROAR_CODEC_NATIVE_ENDIAN, ROAR_CODEC_BYTE_ORDER(to->codec), to->bits) == -1 ) {
937   if ( to_size < from_size )
938    free(out);
939   return -1;
940  } else {
941   ip = out;
942  }
943 }
944
945 if ( to_size < from_size ) {
946  ROAR_DBG("roar_conv(*): memcpy(%p, %p, %i) = ?", real_out, out, (int)to_size);
947  memcpy(real_out, out, to_size);
948  free(out);
949  ROAR_DBG("roar_conv(*): free(%p): OK!", out);
950 }
951
952 return 0;
953}
954
955int roar_conv2(void * out, void * in,
956               size_t inlen,
957               struct roar_audio_info * from, struct roar_audio_info * to,
958               size_t bufsize) {
959 size_t samples;
960 size_t needed_buffer;
961 void   * cin = in;
962 struct roar_audio_info cinfo;
963 int    need_signed = 0;
964
965 memcpy(&cinfo, from, sizeof(cinfo));
966
967 ROAR_DBG("roar_conv2(out=%p, in=%p, inlen=%lu, from=%p{...}, to=%p{...}, bufsize=%lu", out, in, inlen, from, to, bufsize);
968
969/*
970 if ( in != out ) {
971  memset(out, 0xA0, bufsize);
972 } else {
973  ROAR_WARN("roar_conv2(*): in==out!");
974  memset(out+inlen, 0xA0, bufsize-inlen);
975 }
976*/
977
978 // calcumate number of input samples:
979 samples = (inlen * 8) / (from->bits);
980
981 ROAR_DBG("roar_conv2(*): input samples: %i", samples);
982
983 // calculate size per frame
984 needed_buffer  = ROAR_MAX(from->channels, to->channels) * ROAR_MAX(from->bits, to->bits) / 8;
985
986 needed_buffer *= samples;
987 needed_buffer /= from->channels;
988
989 if ( from->rate < to->rate )
990  needed_buffer *= (float)to->rate/(float)from->rate;
991
992 ROAR_DBG("roar_conv2(*): needed_buffer=%u, bufsize=%u", needed_buffer, bufsize);
993
994 // chjeck if we have enogth RAM to convert
995 if ( needed_buffer > bufsize )
996  return -1;
997
998 if ( from->rate != to->rate || from->channels != to->channels )
999  need_signed = 1;
1000
1001  ROAR_DBG("roar_conv2(*): need_signed=%i", need_signed);
1002
1003 if ( ROAR_CODEC_BYTE_ORDER(from->codec) != ROAR_CODEC_NATIVE_ENDIAN ) {
1004  ROAR_DBG("roar_conv2(*): doing bo input conv");
1005  if ( roar_conv_endian(out, cin, samples,
1006       ROAR_CODEC_BYTE_ORDER(from->codec), ROAR_CODEC_NATIVE_ENDIAN, from->bits) == -1 ) {
1007   return -1;
1008  }
1009  cin = out;
1010 }
1011
1012 if ( to->bits > from->bits ) {
1013  ROAR_DBG("roar_conv2(*): bits: %i->%i", from->bits, to->bits);
1014  if ( roar_conv_bits(out, cin, samples, from->bits, to->bits) == -1 )
1015   return -1;
1016
1017  cin        = out;
1018  cinfo.bits = to->bits;
1019 }
1020
1021 if ( need_signed && ! ROAR_CODEC_IS_SIGNED(from->codec) ) {
1022  ROAR_DBG("roar_conv2(*): sign: unsigned->signed");
1023  if ( roar_conv_signedness(out, cin, samples,
1024                            ROAR_CODEC_IS_SIGNED(from->codec), ROAR_CODEC_IS_SIGNED(to->codec),
1025                            cinfo.bits) == -1 )
1026   return -1;
1027
1028  cin            = out;
1029  cinfo.codec    = ROAR_CODEC_PCM_S_LE; // just a signed PCM, which is of no intrest
1030 }
1031
1032 if ( to->channels > from->channels ) {
1033  ROAR_DBG("roar_conv2(*): channels: %i->%i", from->channels, to->channels);
1034  if ( roar_conv_chans(out, cin, samples, from->channels, to->channels, cinfo.bits) == -1 )
1035   return -1;
1036
1037  cin            = out;
1038  cinfo.channels = to->channels;
1039 }
1040
1041//--//
1042 if ( from->rate != to->rate ) {
1043  if ( roar_conv_rate(out, cin, samples, from->rate, to->rate, cinfo.bits, cinfo.channels) == -1 )
1044   return -1;
1045
1046  cin            = out;
1047  samples        = (float)samples * (float)to->rate / (float)from->rate;
1048  cinfo.rate     = to->rate;
1049 }
1050
1051 if ( cinfo.channels != to->channels ) {
1052  ROAR_DBG("roar_conv2(*): channels: %i->%i", cinfo.channels, to->channels);
1053  if ( roar_conv_chans(out, cin, samples, cinfo.channels, to->channels, cinfo.bits) == -1 )
1054   return -1;
1055
1056  cin            = out;
1057  cinfo.channels = to->channels;
1058 }
1059
1060 if ( ROAR_CODEC_IS_SIGNED(cinfo.codec) != ROAR_CODEC_IS_SIGNED(to->codec) ) {
1061  ROAR_DBG("roar_conv2(*): sign: ?(%i)->?(%i)", ROAR_CODEC_IS_SIGNED(cinfo.codec), ROAR_CODEC_IS_SIGNED(to->codec));
1062  if ( roar_conv_signedness(out, cin, samples,
1063                            ROAR_CODEC_IS_SIGNED(cinfo.codec), ROAR_CODEC_IS_SIGNED(to->codec),
1064                            cinfo.bits) == -1 )
1065   return -1;
1066
1067  cin            = out;
1068  cinfo.codec    = to->codec;
1069 }
1070
1071 if ( cinfo.bits != to->bits ) {
1072  ROAR_DBG("roar_conv2(*): bits: %i->%i", cinfo.bits, to->bits);
1073  if ( roar_conv_bits(out, cin, samples, cinfo.bits, to->bits) == -1 )
1074   return -1;
1075
1076  cin        = out;
1077  cinfo.bits = to->bits;
1078 }
1079
1080 if ( ROAR_CODEC_BYTE_ORDER(to->codec) != ROAR_CODEC_NATIVE_ENDIAN ) {
1081  ROAR_DBG("roar_conv2(*): doing bo output conv");
1082  if ( roar_conv_endian(out, cin, samples,
1083       ROAR_CODEC_NATIVE_ENDIAN, ROAR_CODEC_BYTE_ORDER(to->codec), to->bits) == -1 ) {
1084   return -1;
1085  }
1086  cin = out;
1087 }
1088
1089 ROAR_DBG("roar_conv2(*) = 0");
1090 return 0;
1091}
1092
1093int roar_conv_poly4_16 (int16_t * out, int16_t * in, size_t olen, size_t ilen) {
1094 return roar_conv_poly4_16s(out, in, olen, ilen, (float)ilen/olen);
1095}
1096
1097int roar_conv_poly4_16s (int16_t * out, int16_t * in, size_t olen, size_t ilen, float step) {
1098 float poly[4];
1099 float data[4];
1100 float t    = 0;
1101 int16_t * ci = in;
1102 int io, ii = 0;
1103 int i;
1104
1105 printf("step=%f\n", step);
1106
1107 // we can not make a poly4 with less than 4 points ;)
1108 if ( ilen < 4 )
1109  return -1;
1110
1111 for (i = 0; i < 4; i++)
1112  data[i] = ci[i];
1113 roar_math_mkpoly_4x4(poly, data);
1114/*
1115 printf("new poly: data[4] = {%f, %f, %f, %f}, poly[4] = {%f, %f, %f, %f}\n",
1116         data[0], data[1], data[2], data[3],
1117         poly[0], poly[1], poly[2], poly[3]
1118       );
1119*/
1120
1121 //0 1 2 3
1122
1123 for (io = 0; io < olen; io++) {
1124//  printf("t=%f\n", t);
1125  out[io] = roar_math_cvpoly_4x4(poly, t);
1126  t += step;
1127  if ( t > 2 ) { // we need a new ploynome
1128 //  printf("t > 2, need new data\n");
1129   if ( (ii + 4) < ilen ) { // else: end of block.
1130    t -= 1;
1131//    printf("new data: ii=%i\n", ii);
1132    ii++;
1133    ci++;
1134    for (i = 0; i < 4; i++)
1135     data[i] = ci[i];
1136    roar_math_mkpoly_4x4(poly, data);
1137/*
1138   printf("new poly: data[4] = {%f, %f, %f, %f}, poly[4] = {%f, %f, %f, %f}\n",
1139           data[0], data[1], data[2], data[3],
1140           poly[0], poly[1], poly[2], poly[3]
1141          );
1142*/
1143   }
1144  }
1145 }
1146
1147 printf("io=%i\n", io);
1148
1149 return 0;
1150}
1151
1152//ll
Note: See TracBrowser for help on using the repository browser.