source: roaraudio/libroardsp/convert.c @ 4117:dc93b9056733

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

moved comment to where it should be

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