2 * Real Audio 1.0 (14.4K)
3 * Copyright (c) 2003 the ffmpeg project
5 * This file is part of FFmpeg.
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 #include "bitstream.h"
26 #define NBLOCKS 4 /* number of segments within a block */
27 #define BLOCKSIZE 40 /* (quarter) block size in 16-bit words (80 bytes) */
28 #define HALFBLOCK 20 /* BLOCKSIZE/2 */
29 #define BUFFERSIZE 146 /* for do_output */
32 /* internal globals */
34 unsigned int old_energy
; ///< previous frame energy
36 /* the swapped buffers */
37 unsigned int lpc_tables
[2][10];
38 unsigned int *lpc_coef
; ///< LPC coefficients
39 unsigned int *lpc_coef_old
; ///< previous frame LPC coefficients
40 unsigned int lpc_refl_rms
;
41 unsigned int lpc_refl_rms_old
;
43 unsigned int buffer
[5];
44 uint16_t adapt_cb
[148]; ///< adaptive codebook
47 static int ra144_decode_init(AVCodecContext
* avctx
)
49 RA144Context
*ractx
= avctx
->priv_data
;
51 ractx
->lpc_coef
= ractx
->lpc_tables
[0];
52 ractx
->lpc_coef_old
= ractx
->lpc_tables
[1];
58 * Evaluate sqrt(x << 24). x must fit in 20 bits. This value is evaluated in an
59 * odd way to make the output identical to the binary decoder.
61 static int t_sqrt(unsigned int x
)
69 return (ff_sqrt(x
<< 20) << s
) << 2;
73 * Evaluate the LPC filter coefficients from the reflection coefficients.
74 * Does the inverse of the eval_refl() function.
76 static void eval_coefs(const int *refl
, int *coefs
)
83 for (x
=0; x
< 10; x
++) {
87 b1
[y
] = ((refl
[x
] * b2
[x
-y
-1]) >> 12) + b2
[y
];
89 FFSWAP(int *, b1
, b2
);
92 for (x
=0; x
< 10; x
++)
97 static void rotate_block(const int16_t *source
, int16_t *target
, int offset
)
100 source
+= BUFFERSIZE
- offset
;
102 while (i
<BLOCKSIZE
) {
103 target
[i
++] = source
[k
++];
110 /* inverse root mean square */
111 static int irms(const int16_t *data
, int factor
)
113 unsigned int i
, sum
= 0;
115 for (i
=0; i
< BLOCKSIZE
; i
++)
116 sum
+= data
[i
] * data
[i
];
119 return 0; /* OOPS - division by zero */
121 return (0x20000000 / (t_sqrt(sum
) >> 8)) * factor
;
124 /* multiply/add wavetable */
125 static void add_wav(int n
, int skip_first
, int *m
, const int16_t *s1
,
126 const int8_t *s2
, const int8_t *s3
, int16_t *dest
)
132 for (i
=!skip_first
; i
<3; i
++)
133 v
[i
] = (gain_val_tab
[n
][i
] * m
[i
]) >> (gain_exp_tab
[n
][i
] + 1);
135 for (i
=0; i
< BLOCKSIZE
; i
++)
136 dest
[i
] = ((*(s1
++))*v
[0] + (*(s2
++))*v
[1] + (*(s3
++))*v
[2]) >> 12;
140 static void lpc_filter(const int16_t *lpc_coefs
, const int16_t *adapt_coef
,
141 void *out
, int *statbuf
, int len
)
147 memcpy(work
, statbuf
,20);
148 memcpy(work
+ 10, adapt_coef
, len
* 2);
150 for (i
=0; i
<len
; i
++) {
155 sum
+= lpc_coefs
[9-x
] * ptr
[x
];
159 new_val
= ptr
[10] - sum
;
161 if (new_val
< -32768 || new_val
> 32767) {
162 memset(out
, 0, len
* 2);
163 memset(statbuf
, 0, 20);
171 memcpy(out
, work
+10, len
* 2);
172 memcpy(statbuf
, work
+ 40, 20);
175 static unsigned int rescale_rms(int rms
, int energy
)
177 return (rms
* energy
) >> 10;
180 static unsigned int rms(const int *data
)
183 unsigned int res
= 0x10000;
186 for (x
=0; x
<10; x
++) {
187 res
= (((0x1000000 - (*data
) * (*data
)) >> 12) * res
) >> 12;
192 while (res
<= 0x3fff) {
206 /* do quarter-block output */
207 static void do_output_subblock(RA144Context
*ractx
,
208 const uint16_t *lpc_coefs
, unsigned int gval
,
209 int16_t *output_buffer
, GetBitContext
*gb
)
211 uint16_t buffer_a
[40];
213 int cba_idx
= get_bits(gb
, 7); // index of the adaptive CB, 0 if none
214 int gain
= get_bits(gb
, 8);
215 int cb1_idx
= get_bits(gb
, 7);
216 int cb2_idx
= get_bits(gb
, 7);
220 cba_idx
+= HALFBLOCK
- 1;
221 rotate_block(ractx
->adapt_cb
, buffer_a
, cba_idx
);
222 m
[0] = irms(buffer_a
, gval
) >> 12;
227 m
[1] = ((cb1_base
[cb1_idx
] >> 4) * gval
) >> 8;
228 m
[2] = ((cb2_base
[cb2_idx
] >> 4) * gval
) >> 8;
230 memmove(ractx
->adapt_cb
, ractx
->adapt_cb
+ BLOCKSIZE
,
231 (BUFFERSIZE
- BLOCKSIZE
) * 2);
233 block
= ractx
->adapt_cb
+ BUFFERSIZE
- BLOCKSIZE
;
235 add_wav(gain
, cba_idx
, m
, buffer_a
, cb1_vects
[cb1_idx
], cb2_vects
[cb2_idx
],
238 lpc_filter(lpc_coefs
, block
, output_buffer
, ractx
->buffer
, BLOCKSIZE
);
241 static void int_to_int16(int16_t *out
, const int *inp
)
250 * Evaluate the reflection coefficients from the filter coefficients.
251 * Does the inverse of the eval_coefs() function.
253 * @return 1 if one of the reflection coefficients is of magnitude greater than
256 static int eval_refl(const int16_t *coefs
, int *refl
, RA144Context
*ractx
)
266 for (i
=0; i
< 10; i
++)
267 buffer2
[i
] = coefs
[i
];
269 u
= refl
[9] = bp2
[9];
271 if (u
+ 0x1000 > 0x1fff) {
272 av_log(ractx
, AV_LOG_ERROR
, "Overflow. Broken sample?\n");
276 for (c
=8; c
>= 0; c
--) {
283 b
= 0x1000-((u
* u
) >> 12);
289 bp1
[u
] = ((bp2
[u
] - ((refl
[c
+1] * bp2
[c
-u
]) >> 12)) * (0x1000000 / b
)) >> 12;
291 refl
[c
] = u
= bp1
[c
];
293 if ((u
+ 0x1000) > 0x1fff)
296 FFSWAP(int *, bp1
, bp2
);
301 static int interp(RA144Context
*ractx
, int16_t *out
, int block_num
,
302 int copynew
, int energy
)
305 int a
= block_num
+ 1;
309 // Interpolate block coefficients from the this frame forth block and
310 // last frame forth block
312 out
[x
] = (a
* ractx
->lpc_coef
[x
] + b
* ractx
->lpc_coef_old
[x
])>> 2;
314 if (eval_refl(out
, work
, ractx
)) {
315 // The interpolated coefficients are unstable, copy either new or old
318 int_to_int16(out
, ractx
->lpc_coef
);
319 return rescale_rms(ractx
->lpc_refl_rms
, energy
);
321 int_to_int16(out
, ractx
->lpc_coef_old
);
322 return rescale_rms(ractx
->lpc_refl_rms_old
, energy
);
325 return rescale_rms(rms(work
), energy
);
329 /* Uncompress one block (20 bytes -> 160*2 bytes) */
330 static int ra144_decode_frame(AVCodecContext
* avctx
,
331 void *vdata
, int *data_size
,
332 const uint8_t * buf
, int buf_size
)
334 static const uint8_t sizes
[10] = {6, 5, 5, 4, 4, 3, 3, 3, 3, 2};
335 unsigned int refl_rms
[4]; // RMS of the reflection coefficients
336 uint16_t block_coefs
[4][30]; // LPC coefficients of each sub-block
337 unsigned int lpc_refl
[10]; // LPC reflection coefficients of the frame
339 int16_t *data
= vdata
;
342 RA144Context
*ractx
= avctx
->priv_data
;
346 av_log(avctx
, AV_LOG_ERROR
,
347 "Frame too small (%d bytes). Truncated file?\n", buf_size
);
350 init_get_bits(&gb
, buf
, 20 * 8);
353 // "<< 1"? Doesn't this make one value out of two of the table useless?
354 lpc_refl
[i
] = lpc_refl_cb
[i
][get_bits(&gb
, sizes
[i
]) << 1];
356 eval_coefs(lpc_refl
, ractx
->lpc_coef
);
357 ractx
->lpc_refl_rms
= rms(lpc_refl
);
359 energy
= energy_tab
[get_bits(&gb
, 5) << 1]; // Useless table entries?
361 refl_rms
[0] = interp(ractx
, block_coefs
[0], 0, 0, ractx
->old_energy
);
362 refl_rms
[1] = interp(ractx
, block_coefs
[1], 1, energy
> ractx
->old_energy
,
363 t_sqrt(energy
*ractx
->old_energy
) >> 12);
364 refl_rms
[2] = interp(ractx
, block_coefs
[2], 2, 1, energy
);
365 refl_rms
[3] = rescale_rms(ractx
->lpc_refl_rms
, energy
);
367 int_to_int16(block_coefs
[3], ractx
->lpc_coef
);
370 for (c
=0; c
<4; c
++) {
371 do_output_subblock(ractx
, block_coefs
[c
], refl_rms
[c
], data
, &gb
);
373 for (i
=0; i
<BLOCKSIZE
; i
++) {
374 *data
= av_clip_int16(*data
<< 2);
379 ractx
->old_energy
= energy
;
380 ractx
->lpc_refl_rms_old
= ractx
->lpc_refl_rms
;
382 FFSWAP(unsigned int *, ractx
->lpc_coef_old
, ractx
->lpc_coef
);
389 AVCodec ra_144_decoder
=
394 sizeof(RA144Context
),
399 .long_name
= NULL_IF_CONFIG_SMALL("RealAudio 1.0 (14.4K)"),