2 * Real Audio 1.0 (14.4K)
4 * Copyright (c) 2008 Vitor Sessak
5 * Copyright (c) 2003 Nick Kurshev
6 * Based on public domain decoder at http://www.honeypot.net/audio
8 * This file is part of FFmpeg.
10 * FFmpeg is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2.1 of the License, or (at your option) any later version.
15 * FFmpeg is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with FFmpeg; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
26 #include "bitstream.h"
28 #include "acelp_filters.h"
30 #define NBLOCKS 4 ///< number of subblocks within a block
31 #define BLOCKSIZE 40 ///< subblock size in 16-bit words
32 #define BUFFERSIZE 146 ///< the size of the adaptive codebook
36 unsigned int old_energy
; ///< previous frame energy
38 unsigned int lpc_tables
[2][10];
40 /** LPC coefficients: lpc_coef[0] is the coefficients of the current frame
41 * and lpc_coef[1] of the previous one */
42 unsigned int *lpc_coef
[2];
44 unsigned int lpc_refl_rms
[2];
46 /** the current subblock padded by the last 10 values of the previous one*/
47 int16_t curr_sblock
[50];
49 /** adaptive codebook. Its size is two units bigger to avoid a
51 uint16_t adapt_cb
[148];
54 static int ra144_decode_init(AVCodecContext
* avctx
)
56 RA144Context
*ractx
= avctx
->priv_data
;
58 ractx
->lpc_coef
[0] = ractx
->lpc_tables
[0];
59 ractx
->lpc_coef
[1] = ractx
->lpc_tables
[1];
65 * Evaluate sqrt(x << 24). x must fit in 20 bits. This value is evaluated in an
66 * odd way to make the output identical to the binary decoder.
68 static int t_sqrt(unsigned int x
)
76 return ff_sqrt(x
<< 20) << s
;
80 * Evaluate the LPC filter coefficients from the reflection coefficients.
81 * Does the inverse of the eval_refl() function.
83 static void eval_coefs(int *coefs
, const int *refl
)
90 for (x
=0; x
< 10; x
++) {
94 b1
[y
] = ((refl
[x
] * b2
[x
-y
-1]) >> 12) + b2
[y
];
96 FFSWAP(int *, b1
, b2
);
99 for (x
=0; x
< 10; x
++)
104 * Copy the last offset values of *source to *target. If those values are not
105 * enough to fill the target buffer, fill it with another copy of those values.
107 static void copy_and_dup(int16_t *target
, const int16_t *source
, int offset
)
109 source
+= BUFFERSIZE
- offset
;
111 if (offset
> BLOCKSIZE
) {
112 memcpy(target
, source
, BLOCKSIZE
*sizeof(*target
));
114 memcpy(target
, source
, offset
*sizeof(*target
));
115 memcpy(target
+ offset
, source
, (BLOCKSIZE
- offset
)*sizeof(*target
));
119 /** inverse root mean square */
120 static int irms(const int16_t *data
)
122 unsigned int i
, sum
= 0;
124 for (i
=0; i
< BLOCKSIZE
; i
++)
125 sum
+= data
[i
] * data
[i
];
128 return 0; /* OOPS - division by zero */
130 return 0x20000000 / (t_sqrt(sum
) >> 8);
133 static void add_wav(int16_t *dest
, int n
, int skip_first
, int *m
,
134 const int16_t *s1
, const int8_t *s2
, const int8_t *s3
)
140 for (i
=!skip_first
; i
<3; i
++)
141 v
[i
] = (gain_val_tab
[n
][i
] * m
[i
]) >> (gain_exp_tab
[n
][i
] + 1);
143 for (i
=0; i
< BLOCKSIZE
; i
++)
144 dest
[i
] = (s1
[i
]*v
[0] + s2
[i
]*v
[1] + s3
[i
]*v
[2]) >> 12;
147 static unsigned int rescale_rms(unsigned int rms
, unsigned int energy
)
149 return (rms
* energy
) >> 10;
152 static unsigned int rms(const int *data
)
155 unsigned int res
= 0x10000;
158 for (x
=0; x
<10; x
++) {
159 res
= (((0x1000000 - data
[x
]*data
[x
]) >> 12) * res
) >> 12;
164 while (res
<= 0x3fff) {
176 static void do_output_subblock(RA144Context
*ractx
, const uint16_t *lpc_coefs
,
177 int gval
, GetBitContext
*gb
)
179 uint16_t buffer_a
[40];
181 int cba_idx
= get_bits(gb
, 7); // index of the adaptive CB, 0 if none
182 int gain
= get_bits(gb
, 8);
183 int cb1_idx
= get_bits(gb
, 7);
184 int cb2_idx
= get_bits(gb
, 7);
188 cba_idx
+= BLOCKSIZE
/2 - 1;
189 copy_and_dup(buffer_a
, ractx
->adapt_cb
, cba_idx
);
190 m
[0] = (irms(buffer_a
) * gval
) >> 12;
195 m
[1] = (cb1_base
[cb1_idx
] * gval
) >> 8;
196 m
[2] = (cb2_base
[cb2_idx
] * gval
) >> 8;
198 memmove(ractx
->adapt_cb
, ractx
->adapt_cb
+ BLOCKSIZE
,
199 (BUFFERSIZE
- BLOCKSIZE
) * sizeof(*ractx
->adapt_cb
));
201 block
= ractx
->adapt_cb
+ BUFFERSIZE
- BLOCKSIZE
;
203 add_wav(block
, gain
, cba_idx
, m
, buffer_a
,
204 cb1_vects
[cb1_idx
], cb2_vects
[cb2_idx
]);
206 memcpy(ractx
->curr_sblock
, ractx
->curr_sblock
+ 40,
207 10*sizeof(*ractx
->curr_sblock
));
208 memcpy(ractx
->curr_sblock
+ 10, block
,
209 BLOCKSIZE
*sizeof(*ractx
->curr_sblock
));
211 if (ff_acelp_lp_synthesis_filter(
212 ractx
->curr_sblock
+ 10, lpc_coefs
,
213 ractx
->curr_sblock
+ 10, BLOCKSIZE
,
216 memset(ractx
->curr_sblock
, 0, 50*sizeof(*ractx
->curr_sblock
));
219 static void int_to_int16(int16_t *out
, const int *inp
)
228 * Evaluate the reflection coefficients from the filter coefficients.
229 * Does the inverse of the eval_coefs() function.
231 * @return 1 if one of the reflection coefficients is of magnitude greater than
234 static int eval_refl(int *refl
, const int16_t *coefs
, RA144Context
*ractx
)
244 for (i
=0; i
< 10; i
++)
245 buffer2
[i
] = coefs
[i
];
247 u
= refl
[9] = bp2
[9];
249 if (u
+ 0x1000 > 0x1fff) {
250 av_log(ractx
, AV_LOG_ERROR
, "Overflow. Broken sample?\n");
254 for (c
=8; c
>= 0; c
--) {
261 b
= 0x1000-((u
* u
) >> 12);
267 bp1
[u
] = ((bp2
[u
] - ((refl
[c
+1] * bp2
[c
-u
]) >> 12)) * (0x1000000 / b
)) >> 12;
269 refl
[c
] = u
= bp1
[c
];
271 if ((u
+ 0x1000) > 0x1fff)
274 FFSWAP(int *, bp1
, bp2
);
279 static int interp(RA144Context
*ractx
, int16_t *out
, int block_num
,
280 int copyold
, int energy
)
283 int a
= block_num
+ 1;
287 // Interpolate block coefficients from the this frame forth block and
288 // last frame forth block
290 out
[x
] = (a
* ractx
->lpc_coef
[0][x
] + b
* ractx
->lpc_coef
[1][x
])>> 2;
292 if (eval_refl(work
, out
, ractx
)) {
293 // The interpolated coefficients are unstable, copy either new or old
295 int_to_int16(out
, ractx
->lpc_coef
[copyold
]);
296 return rescale_rms(ractx
->lpc_refl_rms
[copyold
], energy
);
298 return rescale_rms(rms(work
), energy
);
302 /** Uncompress one block (20 bytes -> 160*2 bytes) */
303 static int ra144_decode_frame(AVCodecContext
* avctx
, void *vdata
,
304 int *data_size
, const uint8_t *buf
, int buf_size
)
306 static const uint8_t sizes
[10] = {6, 5, 5, 4, 4, 3, 3, 3, 3, 2};
307 unsigned int refl_rms
[4]; // RMS of the reflection coefficients
308 uint16_t block_coefs
[4][30]; // LPC coefficients of each sub-block
309 unsigned int lpc_refl
[10]; // LPC reflection coefficients of the frame
311 int16_t *data
= vdata
;
314 RA144Context
*ractx
= avctx
->priv_data
;
318 av_log(avctx
, AV_LOG_ERROR
,
319 "Frame too small (%d bytes). Truncated file?\n", buf_size
);
323 init_get_bits(&gb
, buf
, 20 * 8);
326 lpc_refl
[i
] = lpc_refl_cb
[i
][get_bits(&gb
, sizes
[i
])];
328 eval_coefs(ractx
->lpc_coef
[0], lpc_refl
);
329 ractx
->lpc_refl_rms
[0] = rms(lpc_refl
);
331 energy
= energy_tab
[get_bits(&gb
, 5)];
333 refl_rms
[0] = interp(ractx
, block_coefs
[0], 0, 1, ractx
->old_energy
);
334 refl_rms
[1] = interp(ractx
, block_coefs
[1], 1, energy
<= ractx
->old_energy
,
335 t_sqrt(energy
*ractx
->old_energy
) >> 12);
336 refl_rms
[2] = interp(ractx
, block_coefs
[2], 2, 0, energy
);
337 refl_rms
[3] = rescale_rms(ractx
->lpc_refl_rms
[0], energy
);
339 int_to_int16(block_coefs
[3], ractx
->lpc_coef
[0]);
341 for (c
=0; c
<4; c
++) {
342 do_output_subblock(ractx
, block_coefs
[c
], refl_rms
[c
], &gb
);
344 for (i
=0; i
<BLOCKSIZE
; i
++)
345 *data
++ = av_clip_int16(ractx
->curr_sblock
[i
+ 10] << 2);
348 ractx
->old_energy
= energy
;
349 ractx
->lpc_refl_rms
[1] = ractx
->lpc_refl_rms
[0];
351 FFSWAP(unsigned int *, ractx
->lpc_coef
[0], ractx
->lpc_coef
[1]);
357 AVCodec ra_144_decoder
=
362 sizeof(RA144Context
),
367 .long_name
= NULL_IF_CONFIG_SMALL("RealAudio 1.0 (14.4K)"),