source: roaraudio/libroardsp/convert.c @ 690:cee9bf5fa456

Last change on this file since 690:cee9bf5fa456 was 690:cee9bf5fa456, checked in by phi, 16 years ago

added copyright statements

File size: 7.9 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 if ( from == to ) {
39  if ( in == out )
40   return 0;
41
42  memcpy(out, in, samples * from / 8);
43  return 0;
44 }
45
46 if ( from ==  8 && to == 16 )
47  return roar_conv_bits_8to16(out, in, samples);
48
49 if ( from == 16 && to ==  8 )
50  return roar_conv_bits_16to8(out, in, samples);
51
52 return -1;
53}
54
55int roar_conv_bits_8to16 (void * out, void * in, int samples) {
56 char    * ip = (char   *)in;
57 int16_t * op = (int16_t*)out;
58 int i;
59
60 for (i = samples - 1; i >= 0; i--)
61  op[i] = ip[i] << 8;
62
63 return 0;
64}
65
66int roar_conv_bits_16to8 (void * out, void * in, int samples) {
67 int16_t * ip = (int16_t*)in;
68 char    * op = (char   *)out;
69 int i;
70
71 ROAR_DBG("roar_conv_bits_16to8(out=%p, in=%p, samples=%i) = ?", out, in, samples);
72
73 for (i = 0; i < samples; i++)
74  op[i] = ip[i] >> 8;
75
76 return 0;
77}
78
79
80int roar_conv_chans (void * out, void * in, int samples, int from, int to, int bits) {
81 if ( from == 1 ) {
82  if ( bits == 8 ) {
83   return roar_conv_chans_1ton8(out, in, samples, to);
84  } else if ( bits == 16 ) {
85   return roar_conv_chans_1ton16(out, in, samples, to);
86  } else {
87   return -1;
88  }
89 } else if ( to == 1 ) {
90  if ( bits == 8 ) {
91   return roar_conv_chans_nto18(out, in, samples, from);
92  } else if ( bits == 16 ) {
93   return roar_conv_chans_nto116(out, in, samples, from);
94  } else {
95   return -1;
96  }
97 }
98
99 return -1;
100}
101
102int roar_conv_chans_1ton8  (void * out, void * in, int samples, int to) {
103 char * ip = (char*) in, * op = (char*) out;
104 int i;
105 int c;
106
107 for (i = samples - 1; i >= 0; i--)
108  for (c = to - 1; c >= 0; c--)
109   op[i*to + c] = ip[i];
110
111 return 0;
112}
113
114int roar_conv_chans_1ton16 (void * out, void * in, int samples, int to) {
115 int16_t * ip = (int16_t*) in, * op = (int16_t*) out;
116 int i;
117 int c;
118
119 for (i = samples - 1; i >= 0; i--)
120  for (c = to - 1; c >= 0; c--)
121   op[i*to + c] = ip[i];
122
123 return 0;
124}
125
126int roar_conv_chans_nto18  (void * out, void * in, int samples, int from) {
127 int8_t * ip = (int8_t*) in, * op = (int8_t*) out;
128 int i;
129 int c;
130 register int s;
131
132 samples /= from;
133
134 for (i = samples - 1; i >= 0; i--) {
135  s  = 0;
136
137  for (c = 0; c < from; c++)
138   s += ip[i*from + c];
139
140  s /= from;
141  op[i] = s;
142 }
143
144 return 0;
145}
146
147int roar_conv_chans_nto116 (void * out, void * in, int samples, int from) {
148 int16_t * ip = (int16_t*) in, * op = (int16_t*) out;
149 int i;
150 int c;
151 register int s;
152
153 samples /= from;
154
155 for (i = samples - 1; i >= 0; i--) {
156  s  = 0;
157
158  for (c = 0; c < from; c++)
159   s += ip[i*from + c];
160
161  s /= from;
162  op[i] = s;
163 }
164
165 return 0;
166}
167
168int roar_conv_rate (void * out, void * in, int samples, int from, int to, int bits, int channels) {
169 if ( bits == 8  )
170  return roar_conv_rate_8(out, in, samples, from, to, channels);
171
172 if ( bits == 16 )
173  return roar_conv_rate_16(out, in, samples, from, to, channels);
174
175 return -1;
176}
177
178int roar_conv_rate_8  (void * out, void * in, int samples, int from, int to, int channels) {
179 return -1;
180}
181
182int roar_conv_rate_16 (void * out, void * in, int samples, int from, int to, int channels) {
183 if ( channels == 1 ) {
184  printf("roar_conv_rate_16(): samples=%i -> %i, rate=%i -> %i\n", samples*from/to, samples, from, to);
185  return roar_conv_poly4_16s((int16_t*) out, (int16_t*) in, samples, samples*from/to, (float)from/to);
186//  return roar_conv_poly4_16((int16_t*) out, (int16_t*) in, samples*to/from, samples);
187 }
188
189 return -1;
190}
191
192int raor_conv_codec (void * out, void * in, int samples, int from, int to, int bits) {
193 int inbo = ROAR_CODEC_BYTE_ORDER(from), outbo = ROAR_CODEC_BYTE_ORDER(to);
194 int ins  = ROAR_CODEC_IS_SIGNED(from),  outs  = ROAR_CODEC_IS_SIGNED(to);
195
196 if ( inbo != outbo )
197  return -1;
198
199 if ( ins != outs ) {
200  if ( ins && !outs ) {
201   if ( bits == 8 ) {
202    roar_conv_codec_s2u8(out, in, samples);
203   } else if ( bits == 16 ) {
204    roar_conv_codec_s2u16(out, in, samples);
205   } else {
206    return -1;
207   }
208  } else {
209   return -1;
210  }
211 }
212
213 return 0;
214}
215
216int roar_conv_codec_s2u8 (void * out, void * in, int samples) {
217 char * ip = in;
218 unsigned char * op = out;
219 int i;
220
221 for(i = 0; i < samples; i++)
222  op[i] = ip[i] + 128;
223
224 return 0;
225}
226
227int roar_conv_codec_s2u16 (void * out, void * in, int samples) {
228 int16_t  * ip = in;
229 uint16_t * op = out;
230 int i;
231
232 for(i = 0; i < samples; i++)
233  op[i] = ip[i] + 32768;
234
235 return 0;
236}
237
238int roar_conv       (void * out, void * in, int samples, struct roar_audio_info * from, struct roar_audio_info * to) {
239 void * ip = in;
240
241 // TODO: decide how to work around both in and out beeing to small to hold all
242 //       data between the steps.
243 //       for the moment: guess out >= in
244
245 if ( from->bits != to->bits ) {
246  if ( roar_conv_bits(out, ip, samples, from->bits, to->bits) == -1 )
247   return -1;
248  else
249   ip = out;
250 }
251
252 if ( from->rate != to->rate ) {
253  if ( roar_conv_rate(out, ip, samples, from->rate, to->rate, to->bits, from->channels) == -1 )
254   return -1;
255  else
256   ip = out;
257 }
258
259 if ( from->channels != to->channels ) {
260  if ( roar_conv_chans(out, ip, samples, from->channels, to->channels, to->bits) == -1 )
261   return -1;
262  else
263   ip = out;
264 }
265
266 if ( from->codec != to->codec ) {
267  if ( raor_conv_codec (out, ip, samples, from->codec, to->codec, to->bits) == -1 )
268   return -1;
269  else
270   ip = out;
271 }
272
273 return 0;
274}
275
276
277
278int roar_conv_poly4_16 (int16_t * out, int16_t * in, size_t olen, size_t ilen) {
279 return roar_conv_poly4_16s(out, in, olen, ilen, (float)ilen/olen);
280}
281
282int roar_conv_poly4_16s (int16_t * out, int16_t * in, size_t olen, size_t ilen, float step) {
283 float poly[4];
284 float data[4];
285 float t    = 0;
286 int16_t * ci = in;
287 int io, ii = 0;
288 int i;
289
290 printf("step=%f\n", step);
291
292 // we can not make a poly4 with less than 4 points ;)
293 if ( ilen < 4 )
294  return -1;
295
296 for (i = 0; i < 4; i++)
297  data[i] = ci[i];
298 roar_math_mkpoly_4x4(poly, data);
299/*
300 printf("new poly: data[4] = {%f, %f, %f, %f}, poly[4] = {%f, %f, %f, %f}\n",
301         data[0], data[1], data[2], data[3],
302         poly[0], poly[1], poly[2], poly[3]
303       );
304*/
305
306 //0 1 2 3
307
308 for (io = 0; io < olen; io++) {
309//  printf("t=%f\n", t);
310  out[io] = roar_math_cvpoly_4x4(poly, t);
311  t += step;
312  if ( t > 2 ) { // we need a new ploynome
313 //  printf("t > 2, need new data\n");
314   if ( (ii + 4) < ilen ) { // else: end of block.
315    t -= 1;
316//    printf("new data: ii=%i\n", ii);
317    ii++;
318    ci++;
319    for (i = 0; i < 4; i++)
320     data[i] = ci[i];
321    roar_math_mkpoly_4x4(poly, data);
322/*
323   printf("new poly: data[4] = {%f, %f, %f, %f}, poly[4] = {%f, %f, %f, %f}\n",
324           data[0], data[1], data[2], data[3],
325           poly[0], poly[1], poly[2], poly[3]
326          );
327*/
328   }
329  }
330 }
331
332 printf("io=%i\n", io);
333
334 return 0;
335}
336
337//ll
Note: See TracBrowser for help on using the repository browser.