source: roaraudio/libroardsp/convert.c @ 2099:858f02f3765e

Last change on this file since 2099:858f02f3765e was 2099:858f02f3765e, checked in by phi, 15 years ago

got it working :) (samples vs. frames)

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