source: roaraudio/libroardsp/convert.c @ 4123:e8ac20348706

Last change on this file since 4123:e8ac20348706 was 4123:e8ac20348706, checked in by phi, 14 years ago

make the conv2 nuericaly more stable

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