ffmpeg / libavcodec / ra144.c @ 5509bffa
History | View | Annotate | Download (12.9 KB)
1 |
/*
|
---|---|
2 |
* Real Audio 1.0 (14.4K)
|
3 |
* Copyright (c) 2003 the ffmpeg project
|
4 |
*
|
5 |
* This library is free software; you can redistribute it and/or
|
6 |
* modify it under the terms of the GNU Lesser General Public
|
7 |
* License as published by the Free Software Foundation; either
|
8 |
* version 2 of the License, or (at your option) any later version.
|
9 |
*
|
10 |
* This library is distributed in the hope that it will be useful,
|
11 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
13 |
* Lesser General Public License for more details.
|
14 |
*
|
15 |
* You should have received a copy of the GNU Lesser General Public
|
16 |
* License along with this library; if not, write to the Free Software
|
17 |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
18 |
*/
|
19 |
|
20 |
#include "avcodec.h" |
21 |
#include "ra144.h" |
22 |
|
23 |
#define DATABLOCK1 20 /* size of 14.4 input block in bytes */ |
24 |
#define DATACHUNK1 1440 /* size of 14.4 input chunk in bytes */ |
25 |
#define AUDIOBLOCK 160 /* size of output block in 16-bit words (320 bytes) */ |
26 |
#define AUDIOBUFFER 12288 /* size of output buffer in 16-bit words (24576 bytes) */ |
27 |
/* consts */
|
28 |
#define NBLOCKS 4 /* number of segments within a block */ |
29 |
#define BLOCKSIZE 40 /* (quarter) block size in 16-bit words (80 bytes) */ |
30 |
#define HALFBLOCK 20 /* BLOCKSIZE/2 */ |
31 |
#define BUFFERSIZE 146 /* for do_output */ |
32 |
|
33 |
|
34 |
/* internal globals */
|
35 |
typedef struct { |
36 |
unsigned int resetflag, val, oldval; |
37 |
unsigned int unpacked[28]; /* buffer for unpacked input */ |
38 |
unsigned int *iptr; /* pointer to current input (from unpacked) */ |
39 |
unsigned int gval; |
40 |
unsigned short *gsp; |
41 |
unsigned int gbuf1[8]; |
42 |
unsigned short gbuf2[120]; |
43 |
signed short output_buffer[40]; |
44 |
unsigned int *decptr; /* decoder ptr */ |
45 |
signed short *decsp; |
46 |
|
47 |
/* the swapped buffers */
|
48 |
unsigned int swapb1a[10]; |
49 |
unsigned int swapb2a[10]; |
50 |
unsigned int swapb1b[10]; |
51 |
unsigned int swapb2b[10]; |
52 |
unsigned int *swapbuf1; |
53 |
unsigned int *swapbuf2; |
54 |
unsigned int *swapbuf1alt; |
55 |
unsigned int *swapbuf2alt; |
56 |
|
57 |
unsigned int buffer[5]; |
58 |
unsigned short int buffer_2[148]; |
59 |
unsigned short int buffer_a[40]; |
60 |
unsigned short int buffer_b[40]; |
61 |
unsigned short int buffer_c[40]; |
62 |
unsigned short int buffer_d[40]; |
63 |
|
64 |
unsigned short int work[50]; |
65 |
unsigned short *sptr; |
66 |
|
67 |
int buffer1[10]; |
68 |
int buffer2[10]; |
69 |
|
70 |
signed short wavtable1[2304]; |
71 |
unsigned short wavtable2[2304]; |
72 |
} Real144_internal; |
73 |
|
74 |
static int ra144_decode_init(AVCodecContext * avctx) |
75 |
{ |
76 |
Real144_internal *glob=avctx->priv_data; |
77 |
|
78 |
memset(glob,0,sizeof(Real144_internal)); |
79 |
glob->resetflag=1;
|
80 |
glob->swapbuf1=glob->swapb1a; |
81 |
glob->swapbuf2=glob->swapb2a; |
82 |
glob->swapbuf1alt=glob->swapb1b; |
83 |
glob->swapbuf2alt=glob->swapb2b; |
84 |
|
85 |
memcpy(glob->wavtable1,wavtable1,sizeof(wavtable1));
|
86 |
memcpy(glob->wavtable2,wavtable2,sizeof(wavtable2));
|
87 |
|
88 |
return 0; |
89 |
} |
90 |
|
91 |
static void final(Real144_internal *glob, short *i1, short *i2, void *out, int *statbuf, int len); |
92 |
static void add_wav(Real144_internal *glob, int n, int f, int m1, int m2, int m3, short *s1, short *s2, short *s3, short *dest); |
93 |
static int irms(short *data, int factor); |
94 |
static void rotate_block(short *source, short *target, int offset); |
95 |
/* lookup square roots in table */
|
96 |
static int t_sqrt(unsigned int x) |
97 |
{ |
98 |
int s=0; |
99 |
while (x>0xfff) { s++; x=x>>2; } |
100 |
return (sqrt_table[x]<<s)<<2; |
101 |
} |
102 |
|
103 |
/* do 'voice' */
|
104 |
static void do_voice(int *a1, int *a2) |
105 |
{ |
106 |
int buffer[10]; |
107 |
int *b1,*b2;
|
108 |
int x,y;
|
109 |
int *ptr,*tmp;
|
110 |
|
111 |
b1=buffer; |
112 |
b2=a2; |
113 |
|
114 |
for (x=0;x<10;x++) { |
115 |
b1[x]=(*a1)<<4;
|
116 |
|
117 |
if(x>0) { |
118 |
ptr=b2+x; |
119 |
for (y=0;y<=x-1;y++) |
120 |
b1[y]=(((*a1)*(*(--ptr)))>>12)+b2[y];
|
121 |
} |
122 |
tmp=b1; |
123 |
b1=b2; |
124 |
b2=tmp; |
125 |
a1++; |
126 |
} |
127 |
ptr=a2+10;
|
128 |
while (ptr>a2) (*a2++)>>=4; |
129 |
} |
130 |
|
131 |
|
132 |
/* do quarter-block output */
|
133 |
static void do_output_subblock(Real144_internal *glob, unsigned int x) |
134 |
{ |
135 |
int a,b,c,d,e,f,g;
|
136 |
|
137 |
if (x==1) memset(glob->buffer,0,20); |
138 |
if ((*glob->iptr)==0) a=0; |
139 |
else a=(*glob->iptr)+HALFBLOCK-1; |
140 |
glob->iptr++; |
141 |
b=*(glob->iptr++); |
142 |
c=*(glob->iptr++); |
143 |
d=*(glob->iptr++); |
144 |
if (a) rotate_block(glob->buffer_2,glob->buffer_a,a);
|
145 |
memcpy(glob->buffer_b,etable1+b*BLOCKSIZE,BLOCKSIZE*2);
|
146 |
e=((ftable1[b]>>4)*glob->gval)>>8; |
147 |
memcpy(glob->buffer_c,etable2+c*BLOCKSIZE,BLOCKSIZE*2);
|
148 |
f=((ftable2[c]>>4)*glob->gval)>>8; |
149 |
if (a) g=irms(glob->buffer_a,glob->gval)>>12; |
150 |
else g=0; |
151 |
add_wav(glob,d,a,g,e,f,glob->buffer_a,glob->buffer_b,glob->buffer_c,glob->buffer_d); |
152 |
memmove(glob->buffer_2,glob->buffer_2+BLOCKSIZE,(BUFFERSIZE-BLOCKSIZE)*2);
|
153 |
memcpy(glob->buffer_2+BUFFERSIZE-BLOCKSIZE,glob->buffer_d,BLOCKSIZE*2);
|
154 |
final(glob,glob->gsp,glob->buffer_d,glob->output_buffer,glob->buffer,BLOCKSIZE); |
155 |
} |
156 |
|
157 |
/* rotate block */
|
158 |
static void rotate_block(short *source, short *target, int offset) |
159 |
{ |
160 |
short *end;
|
161 |
short *ptr1;
|
162 |
short *ptr2;
|
163 |
short *ptr3;
|
164 |
ptr2=source+BUFFERSIZE; |
165 |
ptr3=ptr1=ptr2-offset; |
166 |
end=target+BLOCKSIZE; |
167 |
while (target<end) {
|
168 |
*(target++)=*(ptr3++); |
169 |
if (ptr3==ptr2) ptr3=ptr1;
|
170 |
} |
171 |
} |
172 |
|
173 |
/* inverse root mean square */
|
174 |
static int irms(short *data, int factor) |
175 |
{ |
176 |
short *p1,*p2;
|
177 |
unsigned int sum; |
178 |
p2=(p1=data)+BLOCKSIZE; |
179 |
for (sum=0;p2>p1;p1++) sum+=(*p1)*(*p1); |
180 |
if (sum==0) return 0; /* OOPS - division by zero */ |
181 |
return (0x20000000/(t_sqrt(sum)>>8))*factor; |
182 |
} |
183 |
|
184 |
/* multiply/add wavetable */
|
185 |
static void add_wav(Real144_internal *glob, int n, int f, int m1, int m2, int m3, short *s1, short *s2, short *s3, short *dest) |
186 |
{ |
187 |
int a,b,c;
|
188 |
short *ptr,*ptr2;
|
189 |
|
190 |
ptr=glob->wavtable1+n*9;
|
191 |
ptr2=glob->wavtable2+n*9;
|
192 |
if (f!=0) { |
193 |
a=((*ptr)*m1)>>((*ptr2)+1);
|
194 |
} else {
|
195 |
a=0;
|
196 |
} |
197 |
ptr++;ptr2++; |
198 |
b=((*ptr)*m2)>>((*ptr2)+1);
|
199 |
ptr++;ptr2++; |
200 |
c=((*ptr)*m3)>>((*ptr2)+1);
|
201 |
ptr2=(ptr=dest)+BLOCKSIZE; |
202 |
if (f!=0) |
203 |
while (ptr<ptr2)
|
204 |
*(ptr++)=((*(s1++))*a+(*(s2++))*b+(*(s3++))*c)>>12;
|
205 |
else
|
206 |
while (ptr<ptr2)
|
207 |
*(ptr++)=((*(s2++))*b+(*(s3++))*c)>>12;
|
208 |
} |
209 |
|
210 |
|
211 |
static void final(Real144_internal *glob, short *i1, short *i2, void *out, int *statbuf, int len) |
212 |
{ |
213 |
int x,sum;
|
214 |
int buffer[10]; |
215 |
short *ptr;
|
216 |
short *ptr2;
|
217 |
|
218 |
memcpy(glob->work,statbuf,20);
|
219 |
memcpy(glob->work+10,i2,len*2); |
220 |
|
221 |
buffer[9]=i1[0]; |
222 |
buffer[8]=i1[1]; |
223 |
buffer[7]=i1[2]; |
224 |
buffer[6]=i1[3]; |
225 |
buffer[5]=i1[4]; |
226 |
buffer[4]=i1[5]; |
227 |
buffer[3]=i1[6]; |
228 |
buffer[2]=i1[7]; |
229 |
buffer[1]=i1[8]; |
230 |
buffer[0]=i1[9]; |
231 |
|
232 |
ptr2=(ptr=glob->work)+len; |
233 |
while (ptr<ptr2) {
|
234 |
for(sum=0,x=0;x<=9;x++) |
235 |
sum+=buffer[x]*(ptr[x]); |
236 |
sum=sum>>12;
|
237 |
x=ptr[10]-sum;
|
238 |
if (x<-32768 || x>32767) |
239 |
{ |
240 |
memset(out,0,len*2); |
241 |
memset(statbuf,0,20); |
242 |
return;
|
243 |
} |
244 |
ptr[10]=x;
|
245 |
ptr++; |
246 |
} |
247 |
memcpy(out,ptr+10-len,len*2); |
248 |
memcpy(statbuf,ptr,20);
|
249 |
} |
250 |
|
251 |
/* Decode 20-byte input */
|
252 |
static void unpack_input(unsigned char *input, unsigned int *output) |
253 |
{ |
254 |
unsigned int outbuffer[28]; |
255 |
unsigned short inbuffer[10]; |
256 |
unsigned int x; |
257 |
unsigned int *ptr; |
258 |
|
259 |
/* fix endianness */
|
260 |
for (x=0;x<20;x+=2) |
261 |
inbuffer[x/2]=(input[x]<<8)+input[x+1]; |
262 |
|
263 |
/* unpack */
|
264 |
ptr=outbuffer; |
265 |
*(ptr++)=27;
|
266 |
*(ptr++)=(inbuffer[0]>>10)&0x3f; |
267 |
*(ptr++)=(inbuffer[0]>>5)&0x1f; |
268 |
*(ptr++)=inbuffer[0]&0x1f; |
269 |
*(ptr++)=(inbuffer[1]>>12)&0xf; |
270 |
*(ptr++)=(inbuffer[1]>>8)&0xf; |
271 |
*(ptr++)=(inbuffer[1]>>5)&7; |
272 |
*(ptr++)=(inbuffer[1]>>2)&7; |
273 |
*(ptr++)=((inbuffer[1]<<1)&6)|((inbuffer[2]>>15)&1); |
274 |
*(ptr++)=(inbuffer[2]>>12)&7; |
275 |
*(ptr++)=(inbuffer[2]>>10)&3; |
276 |
*(ptr++)=(inbuffer[2]>>5)&0x1f; |
277 |
*(ptr++)=((inbuffer[2]<<2)&0x7c)|((inbuffer[3]>>14)&3); |
278 |
*(ptr++)=(inbuffer[3]>>6)&0xff; |
279 |
*(ptr++)=((inbuffer[3]<<1)&0x7e)|((inbuffer[4]>>15)&1); |
280 |
*(ptr++)=(inbuffer[4]>>8)&0x7f; |
281 |
*(ptr++)=(inbuffer[4]>>1)&0x7f; |
282 |
*(ptr++)=((inbuffer[4]<<7)&0x80)|((inbuffer[5]>>9)&0x7f); |
283 |
*(ptr++)=(inbuffer[5]>>2)&0x7f; |
284 |
*(ptr++)=((inbuffer[5]<<5)&0x60)|((inbuffer[6]>>11)&0x1f); |
285 |
*(ptr++)=(inbuffer[6]>>4)&0x7f; |
286 |
*(ptr++)=((inbuffer[6]<<4)&0xf0)|((inbuffer[7]>>12)&0xf); |
287 |
*(ptr++)=(inbuffer[7]>>5)&0x7f; |
288 |
*(ptr++)=((inbuffer[7]<<2)&0x7c)|((inbuffer[8]>>14)&3); |
289 |
*(ptr++)=(inbuffer[8]>>7)&0x7f; |
290 |
*(ptr++)=((inbuffer[8]<<1)&0xfe)|((inbuffer[9]>>15)&1); |
291 |
*(ptr++)=(inbuffer[9]>>8)&0x7f; |
292 |
*(ptr++)=(inbuffer[9]>>1)&0x7f; |
293 |
|
294 |
*(output++)=outbuffer[11];
|
295 |
for (x=1;x<11;*(output++)=outbuffer[x++]); |
296 |
ptr=outbuffer+12;
|
297 |
for (x=0;x<16;x+=4) |
298 |
{ |
299 |
*(output++)=ptr[x]; |
300 |
*(output++)=ptr[x+2];
|
301 |
*(output++)=ptr[x+3];
|
302 |
*(output++)=ptr[x+1];
|
303 |
} |
304 |
} |
305 |
|
306 |
static unsigned int rms(int *data, int f) |
307 |
{ |
308 |
int *c;
|
309 |
int x;
|
310 |
unsigned int res; |
311 |
int b;
|
312 |
|
313 |
c=data; |
314 |
b=0;
|
315 |
res=0x10000;
|
316 |
for (x=0;x<10;x++) |
317 |
{ |
318 |
res=(((0x1000000-(*c)*(*c))>>12)*res)>>12; |
319 |
if (res==0) return 0; |
320 |
if (res<=0x3fff) |
321 |
{ |
322 |
while (res<=0x3fff) |
323 |
{ |
324 |
b++; |
325 |
res<<=2;
|
326 |
} |
327 |
} else {
|
328 |
if (res>0x10000) |
329 |
return 0; /* We're screwed, might as well go out with a bang. :P */ |
330 |
} |
331 |
c++; |
332 |
} |
333 |
if (res>0) res=t_sqrt(res); |
334 |
|
335 |
res>>=(b+10);
|
336 |
res=(res*f)>>10;
|
337 |
return res;
|
338 |
} |
339 |
|
340 |
static void dec1(Real144_internal *glob, int *data, int *inp, int n, int f) |
341 |
{ |
342 |
short *ptr,*end;
|
343 |
|
344 |
*(glob->decptr++)=rms(data,f); |
345 |
glob->decptr++; |
346 |
end=(ptr=glob->decsp)+(n*10);
|
347 |
while (ptr<end) *(ptr++)=*(inp++);
|
348 |
} |
349 |
|
350 |
static int eq(Real144_internal *glob, short *in, int *target) |
351 |
{ |
352 |
int retval;
|
353 |
int a;
|
354 |
int b;
|
355 |
int c;
|
356 |
unsigned int u; |
357 |
short *sptr;
|
358 |
int *ptr1,*ptr2,*ptr3;
|
359 |
int *bp1,*bp2,*temp;
|
360 |
|
361 |
retval=0;
|
362 |
bp1=glob->buffer1; |
363 |
bp2=glob->buffer2; |
364 |
ptr2=(ptr3=glob->buffer2)+9;
|
365 |
sptr=in; |
366 |
while (ptr2>=ptr3)
|
367 |
*(ptr3++)=*(sptr++); |
368 |
|
369 |
target+=9;
|
370 |
a=bp2[9];
|
371 |
*target=a; |
372 |
if (a+0x1000>0x1fff) |
373 |
return 0; /* We're screwed, might as well go out with a bang. :P */ |
374 |
c=8;u=a;
|
375 |
while (c>=0) |
376 |
{ |
377 |
if (u==0x1000) u++; |
378 |
if (u==0xfffff000) u--; |
379 |
b=0x1000-((u*u)>>12); |
380 |
if (b==0) b++; |
381 |
ptr2=bp1; |
382 |
ptr1=(ptr3=bp2)+c; |
383 |
for (u=0;u<=c;u++) |
384 |
*(ptr2++)=((*(ptr3++)-(((*target)*(*(ptr1--)))>>12))*(0x1000000/b))>>12; |
385 |
*(--target)=u=bp1[(c--)]; |
386 |
if ((u+0x1000)>0x1fff) retval=1; |
387 |
temp=bp2; |
388 |
bp2=bp1; |
389 |
bp1=temp; |
390 |
} |
391 |
return retval;
|
392 |
} |
393 |
|
394 |
static void dec2(Real144_internal *glob, int *data, int *inp, int n, int f, int *inp2, int l) |
395 |
{ |
396 |
unsigned int *ptr1,*ptr2; |
397 |
int work[10]; |
398 |
int a,b;
|
399 |
int x;
|
400 |
int result;
|
401 |
|
402 |
if(l+1<NBLOCKS/2) a=NBLOCKS-(l+1); |
403 |
else a=l+1; |
404 |
b=NBLOCKS-a; |
405 |
if (l==0) |
406 |
{ |
407 |
glob->decsp=glob->sptr=glob->gbuf2; |
408 |
glob->decptr=glob->gbuf1; |
409 |
} |
410 |
ptr1=inp; |
411 |
ptr2=inp2; |
412 |
for (x=0;x<10*n;x++) |
413 |
*(glob->sptr++)=(a*(*ptr1++)+b*(*ptr2++))>>2;
|
414 |
result=eq(glob,glob->decsp,work); |
415 |
if (result==1) |
416 |
{ |
417 |
dec1(glob,data,inp,n,f); |
418 |
} else {
|
419 |
*(glob->decptr++)=rms(work,f); |
420 |
glob->decptr++; |
421 |
} |
422 |
glob->decsp+=n*10;
|
423 |
} |
424 |
|
425 |
/* Uncompress one block (20 bytes -> 160*2 bytes) */
|
426 |
static int ra144_decode_frame(AVCodecContext * avctx, |
427 |
void *vdata, int *data_size, |
428 |
uint8_t * buf, int buf_size)
|
429 |
{ |
430 |
unsigned int a,b,c; |
431 |
long s;
|
432 |
signed short *shptr; |
433 |
unsigned int *lptr,*temp; |
434 |
const short **dptr; |
435 |
int16_t *datao; |
436 |
int16_t *data = vdata; |
437 |
Real144_internal *glob=avctx->priv_data; |
438 |
|
439 |
if(buf_size==0) |
440 |
return 0; |
441 |
|
442 |
datao = data; |
443 |
unpack_input(buf,glob->unpacked); |
444 |
|
445 |
glob->iptr=glob->unpacked; |
446 |
glob->val=decodetable[0][(*(glob->iptr++))<<1]; |
447 |
|
448 |
dptr=decodetable+1;
|
449 |
lptr=glob->swapbuf1; |
450 |
while (lptr<glob->swapbuf1+10) |
451 |
*(lptr++)=(*(dptr++))[(*(glob->iptr++))<<1];
|
452 |
|
453 |
do_voice(glob->swapbuf1,glob->swapbuf2); |
454 |
|
455 |
a=t_sqrt(glob->val*glob->oldval)>>12;
|
456 |
|
457 |
for (c=0;c<NBLOCKS;c++) { |
458 |
if (c==(NBLOCKS-1)) { |
459 |
dec1(glob,glob->swapbuf1,glob->swapbuf2,3,glob->val);
|
460 |
} else {
|
461 |
if (c*2==(NBLOCKS-2)) { |
462 |
if (glob->oldval<glob->val) {
|
463 |
dec2(glob,glob->swapbuf1,glob->swapbuf2,3,a,glob->swapbuf2alt,c);
|
464 |
} else {
|
465 |
dec2(glob,glob->swapbuf1alt,glob->swapbuf2alt,3,a,glob->swapbuf2,c);
|
466 |
} |
467 |
} else {
|
468 |
if (c*2<(NBLOCKS-2)) { |
469 |
dec2(glob,glob->swapbuf1alt,glob->swapbuf2alt,3,glob->oldval,glob->swapbuf2,c);
|
470 |
} else {
|
471 |
dec2(glob,glob->swapbuf1,glob->swapbuf2,3,glob->val,glob->swapbuf2alt,c);
|
472 |
} |
473 |
} |
474 |
} |
475 |
} |
476 |
|
477 |
/* do output */
|
478 |
for (b=0,c=0;c<4;c++) { |
479 |
glob->gval=glob->gbuf1[c*2];
|
480 |
glob->gsp=glob->gbuf2+b; |
481 |
do_output_subblock(glob,glob->resetflag); |
482 |
glob->resetflag=0;
|
483 |
|
484 |
shptr=glob->output_buffer; |
485 |
while (shptr<glob->output_buffer+BLOCKSIZE) {
|
486 |
s=*(shptr++)<<2;
|
487 |
*data=s; |
488 |
if (s>32767) *data=32767; |
489 |
if (s<-32767) *data=-32768; |
490 |
data++; |
491 |
} |
492 |
b+=30;
|
493 |
} |
494 |
|
495 |
glob->oldval=glob->val; |
496 |
temp=glob->swapbuf1alt; |
497 |
glob->swapbuf1alt=glob->swapbuf1; |
498 |
glob->swapbuf1=temp; |
499 |
temp=glob->swapbuf2alt; |
500 |
glob->swapbuf2alt=glob->swapbuf2; |
501 |
glob->swapbuf2=temp; |
502 |
*data_size=(data-datao)*sizeof(*data);
|
503 |
return 20; |
504 |
} |
505 |
|
506 |
|
507 |
AVCodec ra_144_decoder = |
508 |
{ |
509 |
"real_144",
|
510 |
CODEC_TYPE_AUDIO, |
511 |
CODEC_ID_RA_144, |
512 |
sizeof(Real144_internal),
|
513 |
ra144_decode_init, |
514 |
NULL,
|
515 |
NULL,
|
516 |
ra144_decode_frame, |
517 |
}; |