source: roaraudio/libroardsp/convert.c @ 633:0326bde1f1cb

Last change on this file since 633:0326bde1f1cb was 633:0326bde1f1cb, checked in by phi, 16 years ago

added roar_conv_codec_s2u16()

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