source: roaraudio/libroardsp/convert.c @ 2796:ed4b8a2ee05a

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

try a XOR based solution

File size: 28.2 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    case 4:
224     switch (to) {
225      case  1: return roar_conv_chans_nto116(out, in, samples, 4);
226      case  2: return roar_conv_chans_4to216(out, in, samples);
227      default: return -1;
228     }
229     break;
230    default:
231     switch (to) {
232      case  1: return roar_conv_chans_nto116(out, in, samples, from);
233      default: return -1;
234     }
235   }
236  break;
237  default: return -1;
238 }
239
240 return -1;
241}
242
243int roar_conv_chans_1ton8  (void * out, void * in, int samples, int to) {
244 char * ip = (char*) in, * op = (char*) out;
245 int i;
246 int c;
247
248 for (i = samples - 1; i >= 0; i--)
249  for (c = to - 1; c >= 0; c--)
250   op[i*to + c] = ip[i];
251
252 return 0;
253}
254
255int roar_conv_chans_1to28  (void * out, void * in, int samples) {
256 char * ip = (char*) in, * op = (char*) out;
257 int i, h;
258
259 samples--;
260
261 for (i = (h = samples) * 2; i >= 0; i -= 2, h--) {
262  op[i + 0] = ip[h];
263  op[i + 1] = ip[h];
264 }
265
266 return 0;
267}
268
269int roar_conv_chans_1ton16 (void * out, void * in, int samples, int to) {
270 int16_t * ip = (int16_t*) in, * op = (int16_t*) out;
271 int i;
272 int c;
273
274 for (i = samples - 1; i >= 0; i--)
275  for (c = to - 1; c >= 0; c--)
276   op[i*to + c] = ip[i];
277
278 return 0;
279}
280
281int roar_conv_chans_1to216 (void * out, void * in, int samples) {
282 int16_t * ip = (int16_t*) in, * op = (int16_t*) out;
283 int i, h;
284
285 samples--;
286
287 for (i = (h = samples) * 2; i >= 0; i -= 2, h--) {
288  op[i + 0] = ip[h];
289  op[i + 1] = ip[h];
290 }
291
292 return 0;
293}
294
295int roar_conv_chans_nto18  (void * out, void * in, int samples, int from) {
296 int8_t * ip = (int8_t*) in, * op = (int8_t*) out;
297 int i;
298 int c;
299 register int s;
300
301 samples /= from;
302
303 for (i = samples - 1; i >= 0; i--) {
304  s  = 0;
305
306  for (c = 0; c < from; c++)
307   s += ip[i*from + c];
308
309  s /= from;
310  op[i] = s;
311 }
312
313 return 0;
314}
315
316int roar_conv_chans_2to18  (void * out, void * in, int samples) {
317 int8_t * ip = (int8_t*) in, * op = (int8_t*) out;
318 int i, h;
319
320 samples -= 2;
321
322 for (h = (i = samples) / 2; i >= 0; i -= 2, h--)
323  op[h] = ((int)ip[i + 0] + (int)ip[i + 1]) / 2;
324
325 return 0;
326}
327
328int roar_conv_chans_nto116 (void * out, void * in, int samples, int from) {
329 int16_t * ip = (int16_t*) in, * op = (int16_t*) out;
330 int i;
331 int c;
332 register int s;
333
334 samples /= from;
335
336 for (i = samples - 1; i >= 0; i--) {
337  s  = 0;
338
339  for (c = 0; c < from; c++)
340   s += ip[i*from + c];
341
342  s /= from;
343  op[i] = s;
344 }
345
346 return 0;
347}
348
349int roar_conv_chans_2to116  (void * out, void * in, int samples) {
350 int16_t * ip = (int16_t*) in, * op = (int16_t*) out;
351 int i, h;
352
353 ROAR_DBG("roar_conv_chans_2to116(out=%p, in=%p, samples=%i) = ?", out, in, samples);
354
355 samples -= 2;
356
357 for (h = (i = samples) / 2; i >= 0; i -= 2, h--) {
358  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);
359  op[h] = ((int)ip[i + 0] + (int)ip[i + 1]) / 2;
360 }
361
362 return 0;
363}
364
365int roar_conv_chans_2to38  (void * out, void * in, int samples);
366int roar_conv_chans_2to316 (void * out, void * in, int samples) {
367 int16_t * ip = (int16_t*) in, * op = (int16_t*) out;
368 int i, h;
369
370 samples -= 2;
371
372 i  = samples;
373 h  = (samples / 2) * 3;
374
375 for (; i >= 0; i -= 2, h -= 3) {
376  op[h+0] = ip[i+0];
377  op[h+1] = ip[i+1];
378  op[h+2] = ((int)ip[i + 0] + (int)ip[i + 1]) / 2;
379 }
380
381 return 0;
382}
383
384int roar_conv_chans_2to48  (void * out, void * in, int samples);
385int roar_conv_chans_2to416 (void * out, void * in, int samples) {
386 int16_t * ip = (int16_t*) in, * op = (int16_t*) out;
387 int i, h;
388
389 samples -= 2;
390
391 i  = samples;
392 h  = (samples / 2) * 4;
393
394 for (; i >= 0; i -= 2, h -= 4) {
395  op[h+0] = ip[i+0];
396  op[h+1] = ip[i+1];
397  op[h+2] = ip[i+0];
398  op[h+3] = ip[i+1];
399 }
400
401 return 0;
402}
403
404int roar_conv_chans_2to58  (void * out, void * in, int samples);
405int roar_conv_chans_2to516 (void * out, void * in, int samples) {
406 int16_t * ip = (int16_t*) in, * op = (int16_t*) out;
407 int i, h;
408
409 samples -= 2;
410
411 i  = samples;
412 h  = (samples / 2) * 5;
413
414 for (; i >= 0; i -= 2, h -= 5) {
415  op[h+0] = ip[i+0];
416  op[h+1] = ip[i+1];
417  op[h+2] = ((int)ip[i + 0] + (int)ip[i + 1]) / 2;
418  op[h+3] = ip[i+0];
419  op[h+4] = ip[i+1];
420 }
421
422 return 0;
423}
424int roar_conv_chans_2to68  (void * out, void * in, int samples);
425int roar_conv_chans_2to616 (void * out, void * in, int samples) {
426 int16_t * ip = (int16_t*) in, * op = (int16_t*) out;
427 int i, h;
428
429 samples -= 2;
430
431 i  = samples;
432 h  = (samples / 2) * 6;
433
434 for (; i >= 0; i -= 2, h -= 6) {
435  op[h+0] = ip[i+0];
436  op[h+1] = ip[i+1];
437  op[h+2] = ((int)ip[i + 0] + (int)ip[i + 1]) / 2;
438  op[h+3] = op[h+2];
439  op[h+4] = ip[i+0];
440  op[h+5] = ip[i+1];
441 }
442
443 return 0;
444}
445
446int roar_conv_chans_3to28  (void * out, void * in, int samples);
447int roar_conv_chans_3to216 (void * out, void * in, int samples);
448int roar_conv_chans_4to28  (void * out, void * in, int samples);
449int roar_conv_chans_4to216 (void * out, void * in, int samples) {
450 int16_t * ip = (int16_t*) in, * op = (int16_t*) out;
451 int i, h;
452
453 samples -= 4;
454
455 for (i = h = 0; i < samples; i += 4, h += 2) {
456  op[h+0] = ((int)ip[i + 0] + (int)ip[i + 2]) / 2;
457  op[h+1] = ((int)ip[i + 1] + (int)ip[i + 3]) / 2;
458 }
459
460 return 0;
461}
462
463int roar_conv_chans_5to28  (void * out, void * in, int samples);
464int roar_conv_chans_5to216 (void * out, void * in, int samples);
465int roar_conv_chans_6to28  (void * out, void * in, int samples);
466int roar_conv_chans_6to216 (void * out, void * in, int samples);
467
468
469
470int roar_conv_rate (void * out, void * in, int samples, int from, int to, int bits, int channels) {
471#ifdef ROAR_HAVE_LIBSAMPLERATE
472 return roar_conv_rate_SRC(out, in, samples, from, to, bits, channels);
473#else
474 if ( bits == 8  )
475  return roar_conv_rate_8(out, in, samples, from, to, channels);
476
477 if ( bits == 16 )
478  return roar_conv_rate_16(out, in, samples, from, to, channels);
479
480 return -1;
481#endif
482}
483
484int roar_conv_rate_8  (void * out, void * in, int samples, int from, int to, int channels) {
485 return -1;
486}
487
488int roar_conv_rate_16 (void * out, void * in, int samples, int from, int to, int channels) {
489 if ( from > to ) {
490  switch (channels) {
491   case 1:
492     return roar_conv_rate_161zoh(out, in, samples, from, to);
493   case 2:
494     return roar_conv_rate_162zoh(out, in, samples, from, to);
495   default:
496     return -1;
497  }
498 } else {
499  if ( channels == 1 ) {
500   printf("roar_conv_rate_16(): samples=%i -> %i, rate=%i -> %i\n", samples*from/to, samples, from, to);
501   return roar_conv_poly4_16s((int16_t*) out, (int16_t*) in, samples, samples*from/to, (float)from/to);
502 //  return roar_conv_poly4_16((int16_t*) out, (int16_t*) in, samples*to/from, samples);
503  }
504 }
505
506 return -1;
507}
508
509int roar_conv_rate_161zoh(void * out, void * in, int samples, int from, int to) {
510 int16_t * ip = in;
511 int16_t * op = out;
512 float t = 0;
513 float step = (float)to/from;
514 int i;
515
516 for (i= 0; i < samples; i++) {
517  op[(int)t] = ip[i];
518  t += step;
519 }
520
521 return 0;
522}
523
524int roar_conv_rate_162zoh(void * out, void * in, int samples, int from, int to) {
525 int16_t * ip = in;
526 int16_t * op = out;
527 float t = 0;
528 float step = (float)to/from;
529 int i;
530
531 ROAR_DBG("roar_conv_rate_162zoh(*): samples=%i", samples);
532 samples /= 2;
533// samples -= 1;
534 ROAR_DBG("roar_conv_rate_162zoh(*): samples=%i", samples);
535
536 for (i= 0; i < samples; i++) {
537  ROAR_DBG("roar_conv_rate_162zoh(*): t=%f, i=%i // op[%i] = ip[%i]", t, i, 2*(int)t, 2*i);
538  op[2*(int)t    ] = ip[2*i    ];
539  op[2*(int)t + 1] = ip[2*i + 1];
540  t += step;
541 }
542
543 return 0;
544}
545
546int roar_conv_rate_SRC   (void * out, void * in, int samples, int from, int to, int bits, int channels) {
547#ifdef ROAR_HAVE_LIBSAMPLERATE
548 double radio = (double) to / (double) from;
549 int outsamples = radio * samples;
550 float * inf  = malloc(samples*sizeof(float));
551 float * outf = malloc(outsamples*sizeof(float));
552 int i;
553 SRC_DATA srcdata;
554
555 ROAR_DBG("roar_conv_rate_SRC(*): radio=%lf, samples=%i, outsamples=%i", radio, samples, outsamples);
556
557 if ( inf == NULL ) {
558  if ( outf != NULL )
559   free(outf);
560
561  return -1;
562 }
563
564 if ( outf == NULL ) {
565  if ( inf != NULL )
566   free(inf);
567
568  return -1;
569 }
570
571 switch (bits) {
572  case  8:
573    for (i = 0; i < samples; i++)
574     inf[i] = *(((int8_t *)in)+i) / 128.0;
575   break;
576  case 16:
577    for (i = 0; i < samples; i++)
578     inf[i] = *(((int16_t*)in)+i) / 32768.0;
579   break;
580  case 32:
581    for (i = 0; i < samples; i++)
582     inf[i] = *(((int32_t*)in)+i) / 2147483648.0;
583   break;
584  default:
585    free(outf);
586    free(inf);
587    return -1;
588 }
589
590 srcdata.data_in       = inf;
591 srcdata.data_out      = outf;
592 srcdata.input_frames  = samples/channels;
593 srcdata.output_frames = outsamples/channels;
594 srcdata.src_ratio     = radio;
595
596 if ( src_simple(&srcdata, SRC_ZERO_ORDER_HOLD, channels) != 0 ) {
597  free(outf);
598  free(inf);
599  return -1;
600 }
601
602 switch (bits) {
603  case  8:
604    for (i = 0; i < outsamples; i++)
605     *(((int8_t *)out)+i) = outf[i] * 128.0;
606   break;
607  case 16:
608    for (i = 0; i < outsamples; i++)
609     *(((int16_t*)out)+i) = outf[i] * 32768.0;
610   break;
611  case 32:
612    for (i = 0; i < outsamples; i++)
613     *(((int32_t*)out)+i) = outf[i] * 2147483648.0;
614   break;
615   // no errors here, they are handled above
616 }
617
618 free(outf);
619 free(inf);
620
621 return 0;
622#else
623 return -1;
624#endif
625}
626
627int roar_conv_signedness  (void * out, void * in, int samples, int from, int to, int bits) {
628
629 if ( from != to ) {
630  if ( from && !to ) {
631   switch (bits) {
632    case  8: roar_conv_codec_s2u8( out, in, samples); break;
633    case 16: roar_conv_codec_s2u16(out, in, samples); break;
634    case 32: roar_conv_codec_s2u32(out, in, samples); break;
635    default:
636     errno = ENOSYS;
637     return -1;
638   }
639  } else if ( !from && to ) {
640   switch (bits) {
641    case  8: roar_conv_codec_u2s8( out, in, samples); break;
642    case 16: roar_conv_codec_u2s16(out, in, samples); break;
643    case 32: roar_conv_codec_u2s32(out, in, samples); break;
644    default:
645     errno = ENOSYS;
646     return -1;
647   }
648  } else {
649   return -1;
650  }
651 } else {
652  if ( out == in )
653   return 0;
654
655  memcpy(out, in, samples * bits / 8);
656  return 0;
657 }
658
659 return 0;
660}
661
662int roar_conv_codec (void * out, void * in, int samples, int from, int to, int bits) {
663 int inbo = ROAR_CODEC_BYTE_ORDER(from), outbo = ROAR_CODEC_BYTE_ORDER(to);
664 int ins  = ROAR_CODEC_IS_SIGNED(from),  outs  = ROAR_CODEC_IS_SIGNED(to);
665 void * nin = in;
666
667
668 ROAR_DBG("roar_conv_codec(out=%p, in=%p, samples=%i, from=%i(%s), to=%i(%s), bits=%i) = ?",
669              out, in, samples, from, roar_codec2str(from), to, roar_codec2str(to), bits);
670
671 roar_conv_endian(out, in, samples, inbo, outbo, bits);
672 nin = out;
673
674 return roar_conv_signedness(out, in, samples, ins, outs, bits);
675}
676
677int roar_conv_codec_s2u8 (void * out, void * in, int samples) {
678 char * ip = in;
679 unsigned char * op = out;
680 int i;
681
682 for(i = 0; i < samples; i++)
683  op[i] = ip[i] + 128;
684
685 return 0;
686}
687
688int roar_conv_codec_s2u16 (void * out, void * in, int samples) {
689 int16_t  * ip = in;
690 uint16_t * op = out;
691 int i;
692
693 for(i = 0; i < samples; i++) {
694  op[i] = ip[i];
695
696  if ( ip[i] & 0x8000 ) {
697   op[i] = ip[i] ^ 0xFFFF;
698  } else {
699   op[i] = ip[i] ^ 0x8000;
700  }
701 }
702
703 return 0;
704}
705
706int roar_conv_codec_s2u32 (void * out, void * in, int samples) {
707 int32_t  * ip = in;
708 uint32_t * op = out;
709 int i;
710
711 for(i = 0; i < samples; i++)
712  op[i] = ip[i] + 2147483648U;
713
714 return 0;
715}
716
717int roar_conv_codec_u2s8 (void * out, void * in, int samples) {
718 unsigned char * ip = in;
719          char * op = out;
720 int i;
721
722 for(i = 0; i < samples; i++)
723  op[i] = ip[i] - 128;
724
725 return 0;
726}
727
728int roar_conv_codec_u2s16 (void * out, void * in, int samples) {
729 uint16_t  * ip = in;
730 int16_t   * op = out;
731 int i;
732
733 for(i = 0; i < samples; i++)
734  op[i] = ip[i] - 32768;
735
736 return 0;
737}
738
739int roar_conv_codec_u2s32 (void * out, void * in, int samples) {
740 uint32_t  * ip = in;
741 int32_t   * op = out;
742 int i;
743
744 for(i = 0; i < samples; i++)
745  op[i] = ip[i] - 2147483648U;
746
747 return 0;
748}
749
750
751int roar_conv_endian      (void * out, void * in, int samples, int from, int to, int bits) {
752
753 if ( bits == 8 ) {
754  from = to = ROAR_CODEC_NATIVE_ENDIAN;
755
756 } else if ( bits == 16 ) {
757  if ( from  == ROAR_CODEC_PDP )
758   from = ROAR_CODEC_LE;
759  if ( to    == ROAR_CODEC_PDP )
760   to   = ROAR_CODEC_LE;
761 }
762
763 ROAR_DBG("roar_conv_endian(out=%p, in=%p, samples=%i, from=%i, to=%i, bits=%i) = ?", out, in, samples, from, to, bits);
764
765 if ( from == to ) {
766  if ( in != out ) {
767   memcpy(out, in, samples * bits / 8);
768  }
769  return 0;
770 } else {
771  if ( bits == 16 ) {
772   // in this case we can only have LE vs. BE, so, only need to swap:
773   ROAR_DBG("roar_conv_endian(*): Doing 16 bit byteswap");
774   return roar_conv_endian_16(out, in, samples);
775  } else if ( bits == 24 ) {
776   if ( (from == ROAR_CODEC_LE || from == ROAR_CODEC_BE) && (to == ROAR_CODEC_LE || to == ROAR_CODEC_BE) ) {
777    return roar_conv_endian_24(out, in, samples);
778   } else { // what the hell is PDP eddines in 24 bit mode?
779    return -1;
780   }
781  } else if ( bits == 32 ) {
782   if ( (from == ROAR_CODEC_LE || from == ROAR_CODEC_BE) && (to == ROAR_CODEC_LE || to == ROAR_CODEC_BE) ) {
783    return roar_conv_endian_32(out, in, samples);
784   } else { // need to handle 32 PDP eddines here?
785    return -1;
786   }
787  } else {
788   return -1;
789  }
790 }
791
792 return -1;
793}
794
795
796int roar_conv_endian_16   (void * out, void * in, int samples) {
797 char          * ip = in;
798 char          * op = out;
799 register char   c;
800 int             i;
801
802 samples *= 2;
803
804 if ( out != in ) {
805//  printf("out != in\n");
806  for(i = 0; i < samples; i += 2) {
807//   printf("op[%i] = ip[%i]\nop[%i] = ip[%i]\n", i, i+1, i+1, i);
808   op[i  ] = ip[i+1];
809   op[i+1] = ip[i  ];
810  }
811 } else {
812//  printf("out == in\n");
813  for(i = 0; i < samples; i += 2) {
814   c       = ip[i+1];
815   op[i+1] = ip[i  ];
816   op[i  ] = c;
817  }
818 }
819
820 return 0;
821}
822
823int roar_conv_endian_24   (void * out, void * in, int samples) {
824 char          * ip = in;
825 char          * op = out;
826 register char   c;
827 int             i;
828
829 samples *= 3;
830
831 if ( out != in ) {
832//  printf("out != in\n");
833  for(i = 0; i < samples; i += 3) {
834//   printf("op[%i] = ip[%i]\nop[%i] = ip[%i]\n", i, i+1, i+1, i);
835   op[i  ] = ip[i+2];
836   op[i+2] = ip[i  ];
837  }
838 } else {
839//  printf("out == in\n");
840  for(i = 0; i < samples; i += 3) {
841   c       = ip[i+2];
842   op[i+2] = ip[i  ];
843   op[i  ] = c;
844  }
845 }
846
847 return 0;
848}
849
850int roar_conv_endian_32   (void * out, void * in, int samples) {
851 int32_t       * ip = in;
852 int32_t       * op = out;
853 union {
854  int32_t val;
855  char    data[4];
856 }               c, h;
857 int             i;
858
859 // may the holly optimizer save our souls!
860
861 ROAR_DBG("roar_conv_endian_32(out=%p, in=%p, samples=%i) = ?", out, in, samples);
862
863 for (i = 0; i < samples; i++) {
864  c.val     = ip[i];
865  h.data[0] = c.data[3];
866  h.data[1] = c.data[2];
867  h.data[2] = c.data[1];
868  h.data[3] = c.data[0];
869  op[i]     = h.val;
870 }
871
872 return 0;
873}
874
875int roar_conv       (void * out, void * in, int samples, struct roar_audio_info * from, struct roar_audio_info * to) {
876 void * ip = in;
877 void * real_out = NULL;
878 size_t from_size, to_size;
879
880 // TODO: decide how to work around both in and out beeing to small to hold all
881 //       data between the steps.
882 //       for the moment: guess out >= in
883
884 from_size = (from->bits * samples) / 8;
885 to_size   = (  to->bits * samples * to->rate * to->channels) / (8 * from->rate * from->channels);
886
887 ROAR_DBG("roar_conv(*): size: %i->%i", from_size, to_size);
888
889 if ( to_size < from_size ) {
890  real_out = out;
891
892  if ( (out = malloc(from_size)) == NULL )
893   return -1;
894
895  ROAR_DBG("roar_conv(*): malloc(%i)=%p", (int)from_size, out);
896 }
897
898 ROAR_DBG("roar_conv(*): bo conv: %i->%i(native)", ROAR_CODEC_BYTE_ORDER(from->codec), ROAR_CODEC_NATIVE_ENDIAN);
899
900 if ( ROAR_CODEC_BYTE_ORDER(from->codec) != ROAR_CODEC_NATIVE_ENDIAN ) {
901  ROAR_DBG("roar_conv(*): doing bo input conv");
902  if ( roar_conv_endian(out, ip, samples, ROAR_CODEC_BYTE_ORDER(from->codec), ROAR_CODEC_NATIVE_ENDIAN, from->bits) == -1 ) {
903   if ( to_size < from_size )
904    free(out);
905   return -1;
906  } else {
907   ip = out;
908  }
909 }
910
911 if ( from->bits != to->bits ) {
912  if ( roar_conv_bits(out, ip, samples, from->bits, to->bits) == -1 ) {
913   if ( to_size < from_size )
914    free(out);
915   return -1;
916  } else {
917   ip = out;
918  }
919 }
920
921 if ( ROAR_CODEC_IS_SIGNED(from->codec) != ROAR_CODEC_IS_SIGNED(to->codec) ) {
922  if ( roar_conv_signedness(out, ip, samples, ROAR_CODEC_IS_SIGNED(from->codec), ROAR_CODEC_IS_SIGNED(to->codec), to->bits) == -1 ) {
923   if ( to_size < from_size )
924    free(out);
925   return -1;
926  } else {
927   ip = out;
928  }
929 }
930
931/*
932 if ( from->codec != to->codec ) {
933  if ( roar_conv_codec (out, ip, samples, from->codec, to->codec, to->bits) == -1 )
934   return -1;
935  else
936   ip = out;
937 }
938*/
939
940 if ( from->rate != to->rate ) {
941  if ( roar_conv_rate(out, ip, samples, from->rate, to->rate, to->bits, from->channels) == -1 ) {
942   ROAR_DBG("roar_conv(*): failed to convert rate %i->%i (%ich%ibits)", from->rate, to->rate, to->bits, from->channels);
943   if ( to_size < from_size )
944    free(out);
945   return -1;
946  } else {
947   ip = out;
948   samples = (samples * to->rate) / from->rate;
949  }
950 }
951
952 if ( from->channels != to->channels ) {
953  if ( roar_conv_chans(out, ip, samples, from->channels, to->channels, to->bits) == -1 ) {
954   if ( to_size < from_size )
955    free(out);
956   return -1;
957  } else {
958   ip = out;
959  }
960 }
961
962 if ( ROAR_CODEC_BYTE_ORDER(to->codec) != ROAR_CODEC_NATIVE_ENDIAN ) {
963  if ( roar_conv_endian(out, ip, samples, ROAR_CODEC_NATIVE_ENDIAN, ROAR_CODEC_BYTE_ORDER(to->codec), to->bits) == -1 ) {
964   if ( to_size < from_size )
965    free(out);
966   return -1;
967  } else {
968   ip = out;
969  }
970 }
971
972 if ( to_size < from_size ) {
973  ROAR_DBG("roar_conv(*): memcpy(%p, %p, %i) = ?", real_out, out, (int)to_size);
974  memcpy(real_out, out, to_size);
975  free(out);
976  ROAR_DBG("roar_conv(*): free(%p): OK!", out);
977 }
978
979 return 0;
980}
981
982int roar_conv2(void * out, void * in,
983               size_t inlen,
984               struct roar_audio_info * from, struct roar_audio_info * to,
985               size_t bufsize) {
986 size_t samples;
987 size_t needed_buffer;
988 void   * cin = in;
989 struct roar_audio_info cinfo;
990 int    need_signed = 0;
991
992 memcpy(&cinfo, from, sizeof(cinfo));
993
994 ROAR_DBG("roar_conv2(out=%p, in=%p, inlen=%lu, from=%p{...}, to=%p{...}, bufsize=%lu", out, in, inlen, from, to, bufsize);
995
996/*
997 if ( in != out ) {
998  memset(out, 0xA0, bufsize);
999 } else {
1000  ROAR_WARN("roar_conv2(*): in==out!");
1001  memset(out+inlen, 0xA0, bufsize-inlen);
1002 }
1003*/
1004
1005 // calcumate number of input samples:
1006 samples = (inlen * 8) / (from->bits);
1007
1008 ROAR_DBG("roar_conv2(*): input samples: %i", samples);
1009
1010 // calculate size per frame
1011 needed_buffer  = ROAR_MAX(from->channels, to->channels) * ROAR_MAX(from->bits, to->bits) / 8;
1012
1013 needed_buffer *= samples;
1014 needed_buffer /= from->channels;
1015
1016 if ( from->rate < to->rate )
1017  needed_buffer *= (float)to->rate/(float)from->rate;
1018
1019 ROAR_DBG("roar_conv2(*): needed_buffer=%u, bufsize=%u", needed_buffer, bufsize);
1020
1021 // chjeck if we have enogth RAM to convert
1022 if ( needed_buffer > bufsize )
1023  return -1;
1024
1025 if ( from->rate != to->rate || from->channels != to->channels )
1026  need_signed = 1;
1027
1028  ROAR_DBG("roar_conv2(*): need_signed=%i", need_signed);
1029
1030 if ( ROAR_CODEC_BYTE_ORDER(from->codec) != ROAR_CODEC_NATIVE_ENDIAN ) {
1031  ROAR_DBG("roar_conv2(*): doing bo input conv");
1032  if ( roar_conv_endian(out, cin, samples,
1033       ROAR_CODEC_BYTE_ORDER(from->codec), ROAR_CODEC_NATIVE_ENDIAN, from->bits) == -1 ) {
1034   return -1;
1035  }
1036  cin = out;
1037 }
1038
1039 if ( to->bits > from->bits ) {
1040  ROAR_DBG("roar_conv2(*): bits: %i->%i", from->bits, to->bits);
1041  if ( roar_conv_bits(out, cin, samples, from->bits, to->bits) == -1 )
1042   return -1;
1043
1044  cin        = out;
1045  cinfo.bits = to->bits;
1046 }
1047
1048 if ( need_signed && ! ROAR_CODEC_IS_SIGNED(from->codec) ) {
1049  ROAR_DBG("roar_conv2(*): sign: unsigned->signed");
1050  if ( roar_conv_signedness(out, cin, samples,
1051                            ROAR_CODEC_IS_SIGNED(from->codec), ROAR_CODEC_IS_SIGNED(to->codec),
1052                            cinfo.bits) == -1 )
1053   return -1;
1054
1055  cin            = out;
1056  cinfo.codec    = ROAR_CODEC_PCM_S_LE; // just a signed PCM, which is of no intrest
1057 }
1058
1059 if ( to->channels > from->channels ) {
1060  ROAR_DBG("roar_conv2(*): channels: %i->%i", from->channels, to->channels);
1061  if ( roar_conv_chans(out, cin, samples, from->channels, to->channels, cinfo.bits) == -1 )
1062   return -1;
1063
1064  cin            = out;
1065  cinfo.channels = to->channels;
1066 }
1067
1068//--//
1069 if ( from->rate != to->rate ) {
1070  if ( roar_conv_rate(out, cin, samples, from->rate, to->rate, cinfo.bits, cinfo.channels) == -1 )
1071   return -1;
1072
1073  cin            = out;
1074  samples        = (float)samples * (float)to->rate / (float)from->rate;
1075  cinfo.rate     = to->rate;
1076 }
1077
1078 if ( cinfo.channels != to->channels ) {
1079  ROAR_DBG("roar_conv2(*): channels: %i->%i", cinfo.channels, to->channels);
1080  if ( roar_conv_chans(out, cin, samples, cinfo.channels, to->channels, cinfo.bits) == -1 )
1081   return -1;
1082
1083  cin            = out;
1084  cinfo.channels = to->channels;
1085 }
1086
1087 if ( ROAR_CODEC_IS_SIGNED(cinfo.codec) != ROAR_CODEC_IS_SIGNED(to->codec) ) {
1088  ROAR_DBG("roar_conv2(*): sign: ?(%i)->?(%i)", ROAR_CODEC_IS_SIGNED(cinfo.codec), ROAR_CODEC_IS_SIGNED(to->codec));
1089  if ( roar_conv_signedness(out, cin, samples,
1090                            ROAR_CODEC_IS_SIGNED(cinfo.codec), ROAR_CODEC_IS_SIGNED(to->codec),
1091                            cinfo.bits) == -1 )
1092   return -1;
1093
1094  cin            = out;
1095  cinfo.codec    = to->codec;
1096 }
1097
1098 if ( cinfo.bits != to->bits ) {
1099  ROAR_DBG("roar_conv2(*): bits: %i->%i", cinfo.bits, to->bits);
1100  if ( roar_conv_bits(out, cin, samples, cinfo.bits, to->bits) == -1 )
1101   return -1;
1102
1103  cin        = out;
1104  cinfo.bits = to->bits;
1105 }
1106
1107 if ( ROAR_CODEC_BYTE_ORDER(to->codec) != ROAR_CODEC_NATIVE_ENDIAN ) {
1108  ROAR_DBG("roar_conv2(*): doing bo output conv");
1109  if ( roar_conv_endian(out, cin, samples,
1110       ROAR_CODEC_NATIVE_ENDIAN, ROAR_CODEC_BYTE_ORDER(to->codec), to->bits) == -1 ) {
1111   return -1;
1112  }
1113  cin = out;
1114 }
1115
1116 ROAR_DBG("roar_conv2(*) = 0");
1117 return 0;
1118}
1119
1120int roar_conv_poly4_16 (int16_t * out, int16_t * in, size_t olen, size_t ilen) {
1121 return roar_conv_poly4_16s(out, in, olen, ilen, (float)ilen/olen);
1122}
1123
1124int roar_conv_poly4_16s (int16_t * out, int16_t * in, size_t olen, size_t ilen, float step) {
1125 float poly[4];
1126 float data[4];
1127 float t    = 0;
1128 int16_t * ci = in;
1129 int io, ii = 0;
1130 int i;
1131
1132 printf("step=%f\n", step);
1133
1134 // we can not make a poly4 with less than 4 points ;)
1135 if ( ilen < 4 )
1136  return -1;
1137
1138 for (i = 0; i < 4; i++)
1139  data[i] = ci[i];
1140 roar_math_mkpoly_4x4(poly, data);
1141/*
1142 printf("new poly: data[4] = {%f, %f, %f, %f}, poly[4] = {%f, %f, %f, %f}\n",
1143         data[0], data[1], data[2], data[3],
1144         poly[0], poly[1], poly[2], poly[3]
1145       );
1146*/
1147
1148 //0 1 2 3
1149
1150 for (io = 0; io < olen; io++) {
1151//  printf("t=%f\n", t);
1152  out[io] = roar_math_cvpoly_4x4(poly, t);
1153  t += step;
1154  if ( t > 2 ) { // we need a new ploynome
1155 //  printf("t > 2, need new data\n");
1156   if ( (ii + 4) < ilen ) { // else: end of block.
1157    t -= 1;
1158//    printf("new data: ii=%i\n", ii);
1159    ii++;
1160    ci++;
1161    for (i = 0; i < 4; i++)
1162     data[i] = ci[i];
1163    roar_math_mkpoly_4x4(poly, data);
1164/*
1165   printf("new poly: data[4] = {%f, %f, %f, %f}, poly[4] = {%f, %f, %f, %f}\n",
1166           data[0], data[1], data[2], data[3],
1167           poly[0], poly[1], poly[2], poly[3]
1168          );
1169*/
1170   }
1171  }
1172 }
1173
1174 printf("io=%i\n", io);
1175
1176 return 0;
1177}
1178
1179//ll
Note: See TracBrowser for help on using the repository browser.