source: roaraudio/libroardsp/convert.c @ 845:21845f9f414c

Last change on this file since 845:21845f9f414c was 845:21845f9f414c, checked in by phi, 16 years ago

added roar_conv_bits_AtoB() with A,B element 8,16,32 :)

File size: 9.0 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   if ( bits == 8 ) {
255    roar_conv_codec_s2u8(out, in, samples);
256   } else if ( bits == 16 ) {
257    roar_conv_codec_s2u16(out, in, samples);
258   } else {
259    return -1;
260   }
261  } else {
262   return -1;
263  }
264 }
265
266 return 0;
267}
268
269int roar_conv_codec_s2u8 (void * out, void * in, int samples) {
270 char * ip = in;
271 unsigned char * op = out;
272 int i;
273
274 for(i = 0; i < samples; i++)
275  op[i] = ip[i] + 128;
276
277 return 0;
278}
279
280int roar_conv_codec_s2u16 (void * out, void * in, int samples) {
281 int16_t  * ip = in;
282 uint16_t * op = out;
283 int i;
284
285 for(i = 0; i < samples; i++)
286  op[i] = ip[i] + 32768;
287
288 return 0;
289}
290
291int roar_conv       (void * out, void * in, int samples, struct roar_audio_info * from, struct roar_audio_info * to) {
292 void * ip = in;
293
294 // TODO: decide how to work around both in and out beeing to small to hold all
295 //       data between the steps.
296 //       for the moment: guess out >= in
297
298 if ( from->bits != to->bits ) {
299  if ( roar_conv_bits(out, ip, samples, from->bits, to->bits) == -1 )
300   return -1;
301  else
302   ip = out;
303 }
304
305 if ( from->rate != to->rate ) {
306  if ( roar_conv_rate(out, ip, samples, from->rate, to->rate, to->bits, from->channels) == -1 )
307   return -1;
308  else
309   ip = out;
310 }
311
312 if ( from->channels != to->channels ) {
313  if ( roar_conv_chans(out, ip, samples, from->channels, to->channels, to->bits) == -1 )
314   return -1;
315  else
316   ip = out;
317 }
318
319 if ( from->codec != to->codec ) {
320  if ( raor_conv_codec (out, ip, samples, from->codec, to->codec, to->bits) == -1 )
321   return -1;
322  else
323   ip = out;
324 }
325
326 return 0;
327}
328
329
330
331int roar_conv_poly4_16 (int16_t * out, int16_t * in, size_t olen, size_t ilen) {
332 return roar_conv_poly4_16s(out, in, olen, ilen, (float)ilen/olen);
333}
334
335int roar_conv_poly4_16s (int16_t * out, int16_t * in, size_t olen, size_t ilen, float step) {
336 float poly[4];
337 float data[4];
338 float t    = 0;
339 int16_t * ci = in;
340 int io, ii = 0;
341 int i;
342
343 printf("step=%f\n", step);
344
345 // we can not make a poly4 with less than 4 points ;)
346 if ( ilen < 4 )
347  return -1;
348
349 for (i = 0; i < 4; i++)
350  data[i] = ci[i];
351 roar_math_mkpoly_4x4(poly, data);
352/*
353 printf("new poly: data[4] = {%f, %f, %f, %f}, poly[4] = {%f, %f, %f, %f}\n",
354         data[0], data[1], data[2], data[3],
355         poly[0], poly[1], poly[2], poly[3]
356       );
357*/
358
359 //0 1 2 3
360
361 for (io = 0; io < olen; io++) {
362//  printf("t=%f\n", t);
363  out[io] = roar_math_cvpoly_4x4(poly, t);
364  t += step;
365  if ( t > 2 ) { // we need a new ploynome
366 //  printf("t > 2, need new data\n");
367   if ( (ii + 4) < ilen ) { // else: end of block.
368    t -= 1;
369//    printf("new data: ii=%i\n", ii);
370    ii++;
371    ci++;
372    for (i = 0; i < 4; i++)
373     data[i] = ci[i];
374    roar_math_mkpoly_4x4(poly, data);
375/*
376   printf("new poly: data[4] = {%f, %f, %f, %f}, poly[4] = {%f, %f, %f, %f}\n",
377           data[0], data[1], data[2], data[3],
378           poly[0], poly[1], poly[2], poly[3]
379          );
380*/
381   }
382  }
383 }
384
385 printf("io=%i\n", io);
386
387 return 0;
388}
389
390//ll
Note: See TracBrowser for help on using the repository browser.