source: roaraudio/libroardsp/convert.c @ 626:f7076b318cdf

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

Added roar_conv_chans_nto18()

File size: 6.1 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 {
172    return -1;
173   }
174  } else {
175   return -1;
176  }
177 }
178
179 return 0;
180}
181
182int roar_conv_codec_s2u8 (void * out, void * in, int samples) {
183 char * ip = in;
184 unsigned char * op = out;
185 int i;
186
187 for(i = 0; i < samples; i++)
188  op[i] = ip[i] + 128;
189
190 return 0;
191}
192
193
194int roar_conv       (void * out, void * in, int samples, struct roar_audio_info * from, struct roar_audio_info * to) {
195 void * ip = in;
196
197 // TODO: decide how to work around both in and out beeing to small to hold all
198 //       data between the steps.
199 //       for the moment: guess out >= in
200
201 if ( from->bits != to->bits ) {
202  if ( roar_conv_bits(out, ip, samples, from->bits, to->bits) == -1 )
203   return -1;
204  else
205   ip = out;
206 }
207
208 if ( from->rate != to->rate ) {
209  if ( roar_conv_rate(out, ip, samples, from->rate, to->rate, to->bits, from->channels) == -1 )
210   return -1;
211  else
212   ip = out;
213 }
214
215 if ( from->channels != to->channels ) {
216  if ( roar_conv_chans(out, ip, samples, from->channels, to->channels, to->bits) == -1 )
217   return -1;
218  else
219   ip = out;
220 }
221
222 if ( from->codec != to->codec )
223  return -1;
224
225 return 0;
226}
227
228
229
230int roar_conv_poly4_16 (int16_t * out, int16_t * in, size_t olen, size_t ilen) {
231 return roar_conv_poly4_16s(out, in, olen, ilen, (float)ilen/olen);
232}
233
234int roar_conv_poly4_16s (int16_t * out, int16_t * in, size_t olen, size_t ilen, float step) {
235 float poly[4];
236 float data[4];
237 float t    = 0;
238 int16_t * ci = in;
239 int io, ii = 0;
240 int i;
241
242 printf("step=%f\n", step);
243
244 // we can not make a poly4 with less than 4 points ;)
245 if ( ilen < 4 )
246  return -1;
247
248 for (i = 0; i < 4; i++)
249  data[i] = ci[i];
250 roar_math_mkpoly_4x4(poly, data);
251/*
252 printf("new poly: data[4] = {%f, %f, %f, %f}, poly[4] = {%f, %f, %f, %f}\n",
253         data[0], data[1], data[2], data[3],
254         poly[0], poly[1], poly[2], poly[3]
255       );
256*/
257
258 //0 1 2 3
259
260 for (io = 0; io < olen; io++) {
261//  printf("t=%f\n", t);
262  out[io] = roar_math_cvpoly_4x4(poly, t);
263  t += step;
264  if ( t > 2 ) { // we need a new ploynome
265 //  printf("t > 2, need new data\n");
266   if ( (ii + 4) < ilen ) { // else: end of block.
267    t -= 1;
268//    printf("new data: ii=%i\n", ii);
269    ii++;
270    ci++;
271    for (i = 0; i < 4; i++)
272     data[i] = ci[i];
273    roar_math_mkpoly_4x4(poly, data);
274/*
275   printf("new poly: data[4] = {%f, %f, %f, %f}, poly[4] = {%f, %f, %f, %f}\n",
276           data[0], data[1], data[2], data[3],
277           poly[0], poly[1], poly[2], poly[3]
278          );
279*/
280   }
281  }
282 }
283
284 printf("io=%i\n", io);
285
286 return 0;
287}
288
289//ll
Note: See TracBrowser for help on using the repository browser.