source: roaraudio/libroardsp/convert.c @ 2741:09f063a4a56e

Last change on this file since 2741:09f063a4a56e was 2741:09f063a4a56e, checked in by phi, 15 years ago

added roar_conv_chans_2to316()

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