source: roaraudio/libroardsp/convert.c @ 4125:365b99118145

Last change on this file since 4125:365b99118145 was 4125:365b99118145, checked in by phi, 14 years ago

fixed converter functions

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