source: roaraudio/libroardsp/convert.c @ 5282:efca34f07bfc

Last change on this file since 5282:efca34f07bfc was 5282:efca34f07bfc, checked in by phi, 12 years ago

some ports to AVR and 8 and 16 bit archs

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