source: roaraudio/libroardsp/convert.c @ 849:52b8d86b3e60

Last change on this file since 849:52b8d86b3e60 was 849:52b8d86b3e60, checked in by phi, 16 years ago

changed spaces and use 32 bit funcs in 32 bit mode

File size: 10.1 KB
Line 
1//convert.c:
2
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
35#include "libroar.h"
36
37int roar_conv_bits (void * out, void * in, int samples, int from, int to) {
38 int format;
39
40 if ( from == to ) {
41  if ( in == out )
42   return 0;
43
44  memcpy(out, in, samples * from / 8);
45  return 0;
46 }
47
48 format = ((from / 8) << 4) + (to / 8);
49
50 switch (format) {
51  case 0x12: return roar_conv_bits_8to16( out, in, samples);
52  case 0x14: return roar_conv_bits_8to32( out, in, samples);
53  case 0x21: return roar_conv_bits_16to8( out, in, samples);
54  case 0x24: return roar_conv_bits_16to32(out, in, samples);
55  case 0x41: return roar_conv_bits_32to8( out, in, samples);
56  case 0x42: return roar_conv_bits_32to16(out, in, samples);
57  default:
58   errno = ENOSYS;
59   return -1;
60 }
61
62 return -1;
63}
64
65int roar_conv_bits_8to16 (void * out, void * in, int samples) {
66 char    * ip = (char   *)in;
67 int16_t * op = (int16_t*)out;
68 int i;
69
70 for (i = samples - 1; i >= 0; i--)
71  op[i] = ip[i] << 8;
72
73 return 0;
74}
75
76int roar_conv_bits_8to32  (void * out, void * in, int samples) {
77 char    * ip = (char   *)in;
78 int32_t * op = (int32_t*)out;
79 int i;
80
81 for (i = samples - 1; i >= 0; i--)
82  op[i] = ip[i] << 24;
83
84 return 0;
85}
86
87int roar_conv_bits_16to8 (void * out, void * in, int samples) {
88 int16_t * ip = (int16_t*)in;
89 char    * op = (char   *)out;
90 int i;
91
92 ROAR_DBG("roar_conv_bits_16to8(out=%p, in=%p, samples=%i) = ?", out, in, samples);
93
94 for (i = 0; i < samples; i++)
95  op[i] = ip[i] >> 8;
96
97 return 0;
98}
99
100int roar_conv_bits_16to32 (void * out, void * in, int samples) {
101 int16_t * ip = (int16_t*)in;
102 int32_t * op = (int32_t*)out;
103 int i;
104
105 for (i = samples - 1; i >= 0; i--)
106  op[i] = ip[i] << 16;
107
108 return 0;
109}
110
111int roar_conv_bits_32to8 (void * out, void * in, int samples) {
112 int32_t * ip = (int32_t*)in;
113 char    * op = (char   *)out;
114 int i;
115
116 for (i = 0; i < samples; i++)
117  op[i] = ip[i] >> 24;
118
119 return 0;
120}
121
122int roar_conv_bits_32to16 (void * out, void * in, int samples) {
123 int32_t * ip = (int32_t*)in;
124 int16_t * op = (int16_t*)out;
125 int i;
126
127 for (i = 0; i < samples; i++)
128  op[i] = ip[i] >> 16;
129
130 return 0;
131}
132
133int roar_conv_chans (void * out, void * in, int samples, int from, int to, int bits) {
134 if ( from == 1 ) {
135  if ( bits == 8 ) {
136   return roar_conv_chans_1ton8(out, in, samples, to);
137  } else if ( bits == 16 ) {
138   return roar_conv_chans_1ton16(out, in, samples, to);
139  } else {
140   return -1;
141  }
142 } else if ( to == 1 ) {
143  if ( bits == 8 ) {
144   return roar_conv_chans_nto18(out, in, samples, from);
145  } else if ( bits == 16 ) {
146   return roar_conv_chans_nto116(out, in, samples, from);
147  } else {
148   return -1;
149  }
150 }
151
152 return -1;
153}
154
155int roar_conv_chans_1ton8  (void * out, void * in, int samples, int to) {
156 char * ip = (char*) in, * op = (char*) out;
157 int i;
158 int c;
159
160 for (i = samples - 1; i >= 0; i--)
161  for (c = to - 1; c >= 0; c--)
162   op[i*to + c] = ip[i];
163
164 return 0;
165}
166
167int roar_conv_chans_1ton16 (void * out, void * in, int samples, int to) {
168 int16_t * ip = (int16_t*) in, * op = (int16_t*) out;
169 int i;
170 int c;
171
172 for (i = samples - 1; i >= 0; i--)
173  for (c = to - 1; c >= 0; c--)
174   op[i*to + c] = ip[i];
175
176 return 0;
177}
178
179int roar_conv_chans_nto18  (void * out, void * in, int samples, int from) {
180 int8_t * ip = (int8_t*) in, * op = (int8_t*) out;
181 int i;
182 int c;
183 register int s;
184
185 samples /= from;
186
187 for (i = samples - 1; i >= 0; i--) {
188  s  = 0;
189
190  for (c = 0; c < from; c++)
191   s += ip[i*from + c];
192
193  s /= from;
194  op[i] = s;
195 }
196
197 return 0;
198}
199
200int roar_conv_chans_nto116 (void * out, void * in, int samples, int from) {
201 int16_t * ip = (int16_t*) in, * op = (int16_t*) out;
202 int i;
203 int c;
204 register int s;
205
206 samples /= from;
207
208 for (i = samples - 1; i >= 0; i--) {
209  s  = 0;
210
211  for (c = 0; c < from; c++)
212   s += ip[i*from + c];
213
214  s /= from;
215  op[i] = s;
216 }
217
218 return 0;
219}
220
221int roar_conv_rate (void * out, void * in, int samples, int from, int to, int bits, int channels) {
222 if ( bits == 8  )
223  return roar_conv_rate_8(out, in, samples, from, to, channels);
224
225 if ( bits == 16 )
226  return roar_conv_rate_16(out, in, samples, from, to, channels);
227
228 return -1;
229}
230
231int roar_conv_rate_8  (void * out, void * in, int samples, int from, int to, int channels) {
232 return -1;
233}
234
235int roar_conv_rate_16 (void * out, void * in, int samples, int from, int to, int channels) {
236 if ( channels == 1 ) {
237  printf("roar_conv_rate_16(): samples=%i -> %i, rate=%i -> %i\n", samples*from/to, samples, from, to);
238  return roar_conv_poly4_16s((int16_t*) out, (int16_t*) in, samples, samples*from/to, (float)from/to);
239//  return roar_conv_poly4_16((int16_t*) out, (int16_t*) in, samples*to/from, samples);
240 }
241
242 return -1;
243}
244
245int raor_conv_codec (void * out, void * in, int samples, int from, int to, int bits) {
246 int inbo = ROAR_CODEC_BYTE_ORDER(from), outbo = ROAR_CODEC_BYTE_ORDER(to);
247 int ins  = ROAR_CODEC_IS_SIGNED(from),  outs  = ROAR_CODEC_IS_SIGNED(to);
248
249 if ( inbo != outbo )
250  return -1;
251
252 if ( ins != outs ) {
253  if ( ins && !outs ) {
254   switch (bits) {
255    case  8: roar_conv_codec_s2u8( out, in, samples);  break;
256    case 16: roar_conv_codec_s2u16(out, in, samples); break;
257    case 32: roar_conv_codec_s2u32(out, in, samples); break;
258    default:
259     errno = ENOSYS;
260     return -1;
261   }
262  } else if ( !ins && outs ) {
263   switch (bits) {
264    case  8: roar_conv_codec_u2s8( out, in, samples);  break;
265    case 16: roar_conv_codec_u2s16(out, in, samples); break;
266    case 32: roar_conv_codec_u2s32(out, in, samples); break;
267    default:
268     errno = ENOSYS;
269     return -1;
270   }
271  } else {
272   return -1;
273  }
274 }
275
276 return 0;
277}
278
279int roar_conv_codec_s2u8 (void * out, void * in, int samples) {
280 char * ip = in;
281 unsigned char * op = out;
282 int i;
283
284 for(i = 0; i < samples; i++)
285  op[i] = ip[i] + 128;
286
287 return 0;
288}
289
290int roar_conv_codec_s2u16 (void * out, void * in, int samples) {
291 int16_t  * ip = in;
292 uint16_t * op = out;
293 int i;
294
295 for(i = 0; i < samples; i++)
296  op[i] = ip[i] + 32768;
297
298 return 0;
299}
300
301int roar_conv_codec_s2u32 (void * out, void * in, int samples) {
302 int32_t  * ip = in;
303 uint32_t * op = out;
304 int i;
305
306 for(i = 0; i < samples; i++)
307  op[i] = ip[i] + 2147483648U;
308
309 return 0;
310}
311
312int roar_conv_codec_u2s8 (void * out, void * in, int samples) {
313 unsigned char * ip = in;
314          char * op = out;
315 int i;
316
317 for(i = 0; i < samples; i++)
318  op[i] = ip[i] - 128;
319
320 return 0;
321}
322
323int roar_conv_codec_u2s16 (void * out, void * in, int samples) {
324 uint16_t  * ip = in;
325 int16_t   * op = out;
326 int i;
327
328 for(i = 0; i < samples; i++)
329  op[i] = ip[i] - 32768;
330
331 return 0;
332}
333
334int roar_conv_codec_u2s32 (void * out, void * in, int samples) {
335 uint32_t  * ip = in;
336 int32_t   * op = out;
337 int i;
338
339 for(i = 0; i < samples; i++)
340  op[i] = ip[i] - 2147483648U;
341
342 return 0;
343}
344
345int roar_conv       (void * out, void * in, int samples, struct roar_audio_info * from, struct roar_audio_info * to) {
346 void * ip = in;
347
348 // TODO: decide how to work around both in and out beeing to small to hold all
349 //       data between the steps.
350 //       for the moment: guess out >= in
351
352 if ( from->bits != to->bits ) {
353  if ( roar_conv_bits(out, ip, samples, from->bits, to->bits) == -1 )
354   return -1;
355  else
356   ip = out;
357 }
358
359 if ( from->rate != to->rate ) {
360  if ( roar_conv_rate(out, ip, samples, from->rate, to->rate, to->bits, from->channels) == -1 )
361   return -1;
362  else
363   ip = out;
364 }
365
366 if ( from->channels != to->channels ) {
367  if ( roar_conv_chans(out, ip, samples, from->channels, to->channels, to->bits) == -1 )
368   return -1;
369  else
370   ip = out;
371 }
372
373 if ( from->codec != to->codec ) {
374  if ( raor_conv_codec (out, ip, samples, from->codec, to->codec, to->bits) == -1 )
375   return -1;
376  else
377   ip = out;
378 }
379
380 return 0;
381}
382
383
384
385int roar_conv_poly4_16 (int16_t * out, int16_t * in, size_t olen, size_t ilen) {
386 return roar_conv_poly4_16s(out, in, olen, ilen, (float)ilen/olen);
387}
388
389int roar_conv_poly4_16s (int16_t * out, int16_t * in, size_t olen, size_t ilen, float step) {
390 float poly[4];
391 float data[4];
392 float t    = 0;
393 int16_t * ci = in;
394 int io, ii = 0;
395 int i;
396
397 printf("step=%f\n", step);
398
399 // we can not make a poly4 with less than 4 points ;)
400 if ( ilen < 4 )
401  return -1;
402
403 for (i = 0; i < 4; i++)
404  data[i] = ci[i];
405 roar_math_mkpoly_4x4(poly, data);
406/*
407 printf("new poly: data[4] = {%f, %f, %f, %f}, poly[4] = {%f, %f, %f, %f}\n",
408         data[0], data[1], data[2], data[3],
409         poly[0], poly[1], poly[2], poly[3]
410       );
411*/
412
413 //0 1 2 3
414
415 for (io = 0; io < olen; io++) {
416//  printf("t=%f\n", t);
417  out[io] = roar_math_cvpoly_4x4(poly, t);
418  t += step;
419  if ( t > 2 ) { // we need a new ploynome
420 //  printf("t > 2, need new data\n");
421   if ( (ii + 4) < ilen ) { // else: end of block.
422    t -= 1;
423//    printf("new data: ii=%i\n", ii);
424    ii++;
425    ci++;
426    for (i = 0; i < 4; i++)
427     data[i] = ci[i];
428    roar_math_mkpoly_4x4(poly, data);
429/*
430   printf("new poly: data[4] = {%f, %f, %f, %f}, poly[4] = {%f, %f, %f, %f}\n",
431           data[0], data[1], data[2], data[3],
432           poly[0], poly[1], poly[2], poly[3]
433          );
434*/
435   }
436  }
437 }
438
439 printf("io=%i\n", io);
440
441 return 0;
442}
443
444//ll
Note: See TracBrowser for help on using the repository browser.