/*
* Real Audio 1.0 (14.4K)
- * Copyright (c) 2003 the ffmpeg project
+ * Copyright (c) 2003 The FFmpeg project
*
- * This file is part of FFmpeg.
+ * This file is part of Libav.
*
- * FFmpeg is free software; you can redistribute it and/or
+ * Libav is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
- * FFmpeg is distributed in the hope that it will be useful,
+ * Libav is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with FFmpeg; if not, write to the Free Software
+ * License along with Libav; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <stdint.h>
#include "avcodec.h"
+#include "celp_filters.h"
+#include "mathops.h"
#include "ra144.h"
-const int16_t gain_val_tab[256][3] = {
+const int16_t ff_gain_val_tab[256][3] = {
{ 541, 956, 768}, { 877, 581, 568}, { 675,1574, 635}, {1248,1464, 668},
{1246, 839, 1394}, {2560,1386, 991}, { 925, 687, 608}, {2208, 797, 1144},
{ 535, 832, 799}, { 762, 605, 1154}, { 832,1122, 1003}, {1180, 687, 1176},
{9216,1020, 2028}, {9968, 924, 1188}, {5424, 909, 1206}, {6512, 744, 1086}
};
-const uint8_t gain_exp_tab[256] = {
+const uint8_t ff_gain_exp_tab[256] = {
15, 15, 15, 15, 15, 16, 14, 15, 14, 14, 14, 14, 14, 14, 14, 14,
14, 13, 14, 14, 13, 14, 13, 14, 13, 13, 13, 14, 13, 13, 14, 13,
13, 13, 13, 13, 14, 13, 12, 12, 13, 13, 13, 12, 13, 13, 13, 13,
12, 12, 11, 12, 12, 12, 12, 13, 11, 12, 12, 12, 13, 13, 12, 12
};
-const int8_t cb1_vects[128][40]={
+const int8_t ff_cb1_vects[128][40]={
{
38, -4, 15, -4, 14, -13, 12, -11, -2, -6,
-6, -11, -45, -16, -11, -13, -7, 6, -12, 4,
}
};
-const int8_t cb2_vects[128][40]={
+const int8_t ff_cb2_vects[128][40]={
{
73, -32, -60, -15, -26, 59, 2, -33, 30, -10,
-3, -17, 8, 30, -1, -26, -4, -22, 10, 16,
}
};
-const uint16_t cb1_base[128]={
+const uint16_t ff_cb1_base[128]={
19657, 18474, 18365, 17520, 21048, 18231, 18584, 16671,
20363, 19069, 19409, 18430, 21844, 18753, 19613, 17411,
20389, 21772, 20129, 21702, 20978, 20472, 19627, 19387,
16671, 18584, 18231, 21048, 17520, 18365, 18474, 19657,
};
-const uint16_t cb2_base[128]={
+const uint16_t ff_cb2_base[128]={
12174, 13380, 13879, 13832, 13170, 13227, 13204, 12053,
12410, 13988, 14348, 14631, 13100, 13415, 13224, 12268,
11982, 13825, 13499, 14210, 13877, 14788, 13811, 13109,
12053, 13204, 13227, 13170, 13832, 13879, 13380, 12174,
};
-const int16_t energy_tab[32]={
+const int16_t ff_energy_tab[32]={
0, 16, 20, 25, 32, 41, 51, 65,
81, 103, 129, 163, 205, 259, 326, 410,
516, 650, 819, 1031, 1298, 1634, 2057, 2590,
-617, 190, 802, 1483
};
-const int16_t * const lpc_refl_cb[10]={
+const int16_t * const ff_lpc_refl_cb[10]={
lpc_refl_cb1, lpc_refl_cb2, lpc_refl_cb3, lpc_refl_cb4, lpc_refl_cb5,
lpc_refl_cb6, lpc_refl_cb7, lpc_refl_cb8, lpc_refl_cb9, lpc_refl_cb10
};
-void add_wav(int16_t *dest, int n, int skip_first, int *m, const int16_t *s1,
- const int8_t *s2, const int8_t *s3)
+static void add_wav(int16_t *dest, int n, int skip_first, int *m,
+ const int16_t *s1, const int8_t *s2, const int8_t *s3)
{
int i;
int v[3];
v[0] = 0;
for (i=!skip_first; i<3; i++)
- v[i] = (gain_val_tab[n][i] * m[i]) >> gain_exp_tab[n];
+ v[i] = (ff_gain_val_tab[n][i] * m[i]) >> ff_gain_exp_tab[n];
if (v[0]) {
for (i=0; i < BLOCKSIZE; i++)
* Copy the last offset values of *source to *target. If those values are not
* enough to fill the target buffer, fill it with another copy of those values.
*/
-void copy_and_dup(int16_t *target, const int16_t *source, int offset)
+void ff_copy_and_dup(int16_t *target, const int16_t *source, int offset)
{
source += BUFFERSIZE - offset;
* @return 1 if one of the reflection coefficients is greater than
* 4095, 0 if not.
*/
-int eval_refl(int *refl, const int16_t *coefs, AVCodecContext *avctx)
+int ff_eval_refl(int *refl, const int16_t *coefs, AVCodecContext *avctx)
{
int b, i, j;
- int buffer1[10];
- int buffer2[10];
+ int buffer1[LPC_ORDER];
+ int buffer2[LPC_ORDER];
int *bp1 = buffer1;
int *bp2 = buffer2;
- for (i=0; i < 10; i++)
+ for (i=0; i < LPC_ORDER; i++)
buffer2[i] = coefs[i];
- refl[9] = bp2[9];
+ refl[LPC_ORDER-1] = bp2[LPC_ORDER-1];
- if ((unsigned) bp2[9] + 0x1000 > 0x1fff) {
+ if ((unsigned) bp2[LPC_ORDER-1] + 0x1000 > 0x1fff) {
av_log(avctx, AV_LOG_ERROR, "Overflow. Broken sample?\n");
return 1;
}
- for (i=8; i >= 0; i--) {
+ for (i = LPC_ORDER-2; i >= 0; i--) {
b = 0x1000-((bp2[i+1] * bp2[i+1]) >> 12);
if (!b)
/**
* Evaluate the LPC filter coefficients from the reflection coefficients.
- * Does the inverse of the eval_refl() function.
+ * Does the inverse of the ff_eval_refl() function.
*/
-void eval_coefs(int *coefs, const int *refl)
+void ff_eval_coefs(int *coefs, const int *refl)
{
- int buffer[10];
+ int buffer[LPC_ORDER];
int *b1 = buffer;
int *b2 = coefs;
int i, j;
- for (i=0; i < 10; i++) {
+ for (i=0; i < LPC_ORDER; i++) {
b1[i] = refl[i] << 4;
for (j=0; j < i; j++)
FFSWAP(int *, b1, b2);
}
- for (i=0; i < 10; i++)
+ for (i=0; i < LPC_ORDER; i++)
coefs[i] >>= 4;
}
-void int_to_int16(int16_t *out, const int *inp)
+void ff_int_to_int16(int16_t *out, const int *inp)
{
int i;
- for (i=0; i < 10; i++)
+ for (i = 0; i < LPC_ORDER; i++)
*out++ = *inp++;
}
* Evaluate sqrt(x << 24). x must fit in 20 bits. This value is evaluated in an
* odd way to make the output identical to the binary decoder.
*/
-int t_sqrt(unsigned int x)
+int ff_t_sqrt(unsigned int x)
{
int s = 2;
while (x > 0xfff) {
return ff_sqrt(x << 20) << s;
}
-unsigned int rms(const int *data)
+unsigned int ff_rms(const int *data)
{
int i;
unsigned int res = 0x10000;
- int b = 10;
+ int b = LPC_ORDER;
- for (i=0; i < 10; i++) {
+ for (i = 0; i < LPC_ORDER; i++) {
res = (((0x1000000 - data[i]*data[i]) >> 12) * res) >> 12;
if (res == 0)
}
}
- return t_sqrt(res) >> b;
+ return ff_t_sqrt(res) >> b;
}
-int interp(RA144Context *ractx, int16_t *out, int a, int copyold, int energy)
+int ff_interp(RA144Context *ractx, int16_t *out, int a, int copyold, int energy)
{
- int work[10];
+ int work[LPC_ORDER];
int b = NBLOCKS - a;
int i;
// Interpolate block coefficients from the this frame's forth block and
// last frame's forth block.
- for (i=0; i<10; i++)
+ for (i = 0; i < LPC_ORDER; i++)
out[i] = (a * ractx->lpc_coef[0][i] + b * ractx->lpc_coef[1][i])>> 2;
- if (eval_refl(work, out, ractx->avctx)) {
+ if (ff_eval_refl(work, out, ractx->avctx)) {
// The interpolated coefficients are unstable, copy either new or old
// coefficients.
- int_to_int16(out, ractx->lpc_coef[copyold]);
- return rescale_rms(ractx->lpc_refl_rms[copyold], energy);
+ ff_int_to_int16(out, ractx->lpc_coef[copyold]);
+ return ff_rescale_rms(ractx->lpc_refl_rms[copyold], energy);
} else {
- return rescale_rms(rms(work), energy);
+ return ff_rescale_rms(ff_rms(work), energy);
}
}
-unsigned int rescale_rms(unsigned int rms, unsigned int energy)
+unsigned int ff_rescale_rms(unsigned int rms, unsigned int energy)
{
return (rms * energy) >> 10;
}
/** inverse root mean square */
-int irms(const int16_t *data)
+int ff_irms(const int16_t *data)
{
unsigned int i, sum = 0;
if (sum == 0)
return 0; /* OOPS - division by zero */
- return 0x20000000 / (t_sqrt(sum) >> 8);
+ return 0x20000000 / (ff_t_sqrt(sum) >> 8);
+}
+
+void ff_subblock_synthesis(RA144Context *ractx, const uint16_t *lpc_coefs,
+ int cba_idx, int cb1_idx, int cb2_idx,
+ int gval, int gain)
+{
+ uint16_t buffer_a[BLOCKSIZE];
+ uint16_t *block;
+ int m[3];
+
+ if (cba_idx) {
+ cba_idx += BLOCKSIZE/2 - 1;
+ ff_copy_and_dup(buffer_a, ractx->adapt_cb, cba_idx);
+ m[0] = (ff_irms(buffer_a) * gval) >> 12;
+ } else {
+ m[0] = 0;
+ }
+ m[1] = (ff_cb1_base[cb1_idx] * gval) >> 8;
+ m[2] = (ff_cb2_base[cb2_idx] * gval) >> 8;
+ memmove(ractx->adapt_cb, ractx->adapt_cb + BLOCKSIZE,
+ (BUFFERSIZE - BLOCKSIZE) * sizeof(*ractx->adapt_cb));
+
+ block = ractx->adapt_cb + BUFFERSIZE - BLOCKSIZE;
+
+ add_wav(block, gain, cba_idx, m, cba_idx? buffer_a: NULL,
+ ff_cb1_vects[cb1_idx], ff_cb2_vects[cb2_idx]);
+
+ memcpy(ractx->curr_sblock, ractx->curr_sblock + BLOCKSIZE,
+ LPC_ORDER*sizeof(*ractx->curr_sblock));
+
+ if (ff_celp_lp_synthesis_filter(ractx->curr_sblock + LPC_ORDER, lpc_coefs,
+ block, BLOCKSIZE, LPC_ORDER, 1, 0, 0xfff))
+ memset(ractx->curr_sblock, 0, (LPC_ORDER+BLOCKSIZE)*sizeof(*ractx->curr_sblock));
}