source: roaraudio/libroardsp/convert.c @ 624:b07ec9408d64

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

added support fro 16 bit downmixing

File size: 5.8 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 -1;
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_nto116 (void * out, void * in, int samples, int from) {
95 int16_t * ip = (int16_t*) in, * op = (int16_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_rate (void * out, void * in, int samples, int from, int to, int bits, int channels) {
116 if ( bits == 8  )
117  return roar_conv_rate_8(out, in, samples, from, to, channels);
118
119 if ( bits == 16 )
120  return roar_conv_rate_16(out, in, samples, from, to, channels);
121
122 return -1;
123}
124
125int roar_conv_rate_8  (void * out, void * in, int samples, int from, int to, int channels) {
126 return -1;
127}
128
129int roar_conv_rate_16 (void * out, void * in, int samples, int from, int to, int channels) {
130 if ( channels == 1 ) {
131  printf("roar_conv_rate_16(): samples=%i -> %i, rate=%i -> %i\n", samples*from/to, samples, from, to);
132  return roar_conv_poly4_16s((int16_t*) out, (int16_t*) in, samples, samples*from/to, (float)from/to);
133//  return roar_conv_poly4_16((int16_t*) out, (int16_t*) in, samples*to/from, samples);
134 }
135
136 return -1;
137}
138
139int raor_conv_codec (void * out, void * in, int samples, int from, int to, int bits) {
140 int inbo = ROAR_CODEC_BYTE_ORDER(from), outbo = ROAR_CODEC_BYTE_ORDER(to);
141 int ins  = ROAR_CODEC_IS_SIGNED(from),  outs  = ROAR_CODEC_IS_SIGNED(to);
142
143 if ( inbo != outbo )
144  return -1;
145
146 if ( ins != outs ) {
147  if ( ins && !outs ) {
148   if ( bits == 8 ) {
149    roar_conv_codec_s2u8(out, in, samples);
150   } else {
151    return -1;
152   }
153  } else {
154   return -1;
155  }
156 }
157
158 return 0;
159}
160
161int roar_conv_codec_s2u8 (void * out, void * in, int samples) {
162 char * ip = in;
163 unsigned char * op = out;
164 int i;
165
166 for(i = 0; i < samples; i++)
167  op[i] = ip[i] + 128;
168
169 return 0;
170}
171
172
173int roar_conv       (void * out, void * in, int samples, struct roar_audio_info * from, struct roar_audio_info * to) {
174 void * ip = in;
175
176 // TODO: decide how to work around both in and out beeing to small to hold all
177 //       data between the steps.
178 //       for the moment: guess out >= in
179
180 if ( from->bits != to->bits ) {
181  if ( roar_conv_bits(out, ip, samples, from->bits, to->bits) == -1 )
182   return -1;
183  else
184   ip = out;
185 }
186
187 if ( from->rate != to->rate ) {
188  if ( roar_conv_rate(out, ip, samples, from->rate, to->rate, to->bits, from->channels) == -1 )
189   return -1;
190  else
191   ip = out;
192 }
193
194 if ( from->channels != to->channels ) {
195  if ( roar_conv_chans(out, ip, samples, from->channels, to->channels, to->bits) == -1 )
196   return -1;
197  else
198   ip = out;
199 }
200
201 if ( from->codec != to->codec )
202  return -1;
203
204 return 0;
205}
206
207
208
209int roar_conv_poly4_16 (int16_t * out, int16_t * in, size_t olen, size_t ilen) {
210 return roar_conv_poly4_16s(out, in, olen, ilen, (float)ilen/olen);
211}
212
213int roar_conv_poly4_16s (int16_t * out, int16_t * in, size_t olen, size_t ilen, float step) {
214 float poly[4];
215 float data[4];
216 float t    = 0;
217 int16_t * ci = in;
218 int io, ii = 0;
219 int i;
220
221 printf("step=%f\n", step);
222
223 // we can not make a poly4 with less than 4 points ;)
224 if ( ilen < 4 )
225  return -1;
226
227 for (i = 0; i < 4; i++)
228  data[i] = ci[i];
229 roar_math_mkpoly_4x4(poly, data);
230/*
231 printf("new poly: data[4] = {%f, %f, %f, %f}, poly[4] = {%f, %f, %f, %f}\n",
232         data[0], data[1], data[2], data[3],
233         poly[0], poly[1], poly[2], poly[3]
234       );
235*/
236
237 //0 1 2 3
238
239 for (io = 0; io < olen; io++) {
240//  printf("t=%f\n", t);
241  out[io] = roar_math_cvpoly_4x4(poly, t);
242  t += step;
243  if ( t > 2 ) { // we need a new ploynome
244 //  printf("t > 2, need new data\n");
245   if ( (ii + 4) < ilen ) { // else: end of block.
246    t -= 1;
247//    printf("new data: ii=%i\n", ii);
248    ii++;
249    ci++;
250    for (i = 0; i < 4; i++)
251     data[i] = ci[i];
252    roar_math_mkpoly_4x4(poly, data);
253/*
254   printf("new poly: data[4] = {%f, %f, %f, %f}, poly[4] = {%f, %f, %f, %f}\n",
255           data[0], data[1], data[2], data[3],
256           poly[0], poly[1], poly[2], poly[3]
257          );
258*/
259   }
260  }
261 }
262
263 printf("io=%i\n", io);
264
265 return 0;
266}
267
268//ll
Note: See TracBrowser for help on using the repository browser.