source: roaraudio/libroardsp/convert.c @ 2641:80c7f8cb3dbd

Last change on this file since 2641:80c7f8cb3dbd was 2501:b7965573ae61, checked in by phi, 15 years ago

start of roar_conv_bits_24to32()

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