source: roaraudio/libroardsp/convert.c @ 2386:0ff0440ba500

Last change on this file since 2386:0ff0440ba500 was 2386:0ff0440ba500, checked in by phi, 15 years ago

added SRC (libsamplerate) based resampler

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