annotate ra144enc.c @ 12530:63edd10ad4bc libavcodec tip

Try to fix crashes introduced by r25218 r25218 made assumptions about the existence of past reference frames that weren't necessarily true.
author darkshikari
date Tue, 28 Sep 2010 09:06:22 +0000
parents 34beb0af8204
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
11870
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
1 /*
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
2 * Real Audio 1.0 (14.4K) encoder
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
3 * Copyright (c) 2010 Francesco Lavra <francescolavra@interfree.it>
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
4 *
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
5 * This file is part of FFmpeg.
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
6 *
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
7 * FFmpeg is free software; you can redistribute it and/or
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
8 * modify it under the terms of the GNU Lesser General Public
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
9 * License as published by the Free Software Foundation; either
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
10 * version 2.1 of the License, or (at your option) any later version.
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
11 *
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
12 * FFmpeg is distributed in the hope that it will be useful,
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
15 * Lesser General Public License for more details.
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
16 *
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
17 * You should have received a copy of the GNU Lesser General Public
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
18 * License along with FFmpeg; if not, write to the Free Software
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
20 */
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
21
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
22 /**
11874
a3152c2776c4 Remove filename from doxy comment
vitor
parents: 11873
diff changeset
23 * @file
11870
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
24 * Real Audio 1.0 (14.4K) encoder
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
25 * @author Francesco Lavra <francescolavra@interfree.it>
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
26 */
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
27
11871
1fccba2858dd Include float.h to provide FLT_MAX define. Should fix compilation on windows.
vitor
parents: 11870
diff changeset
28 #include <float.h>
11870
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
29
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
30 #include "avcodec.h"
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
31 #include "put_bits.h"
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
32 #include "lpc.h"
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
33 #include "celp_filters.h"
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
34 #include "ra144.h"
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
35
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
36
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
37 static av_cold int ra144_encode_init(AVCodecContext * avctx)
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
38 {
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
39 RA144Context *ractx;
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
40
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
41 if (avctx->sample_fmt != SAMPLE_FMT_S16) {
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
42 av_log(avctx, AV_LOG_ERROR, "invalid sample format\n");
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
43 return -1;
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
44 }
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
45 if (avctx->channels != 1) {
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
46 av_log(avctx, AV_LOG_ERROR, "invalid number of channels: %d\n",
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
47 avctx->channels);
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
48 return -1;
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
49 }
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
50 avctx->frame_size = NBLOCKS * BLOCKSIZE;
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
51 avctx->bit_rate = 8000;
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
52 ractx = avctx->priv_data;
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
53 ractx->lpc_coef[0] = ractx->lpc_tables[0];
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
54 ractx->lpc_coef[1] = ractx->lpc_tables[1];
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
55 ractx->avctx = avctx;
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
56 dsputil_init(&ractx->dsp, avctx);
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
57 return 0;
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
58 }
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
59
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
60
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
61 /**
12024
fdafbcef52f5 Fix grammar errors in documentation
mru
parents: 11874
diff changeset
62 * Quantize a value by searching a sorted table for the element with the
11870
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
63 * nearest value
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
64 *
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
65 * @param value value to quantize
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
66 * @param table array containing the quantization table
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
67 * @param size size of the quantization table
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
68 * @return index of the quantization table corresponding to the element with the
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
69 * nearest value
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
70 */
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
71 static int quantize(int value, const int16_t *table, unsigned int size)
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
72 {
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
73 unsigned int low = 0, high = size - 1;
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
74
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
75 while (1) {
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
76 int index = (low + high) >> 1;
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
77 int error = table[index] - value;
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
78
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
79 if (index == low)
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
80 return table[high] + error > value ? low : high;
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
81 if (error > 0) {
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
82 high = index;
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
83 } else {
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
84 low = index;
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
85 }
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
86 }
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
87 }
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
88
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
89
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
90 /**
12024
fdafbcef52f5 Fix grammar errors in documentation
mru
parents: 11874
diff changeset
91 * Orthogonalize a vector to another vector
11870
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
92 *
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
93 * @param v vector to orthogonalize
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
94 * @param u vector against which orthogonalization is performed
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
95 */
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
96 static void orthogonalize(float *v, const float *u)
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
97 {
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
98 int i;
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
99 float num = 0, den = 0;
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
100
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
101 for (i = 0; i < BLOCKSIZE; i++) {
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
102 num += v[i] * u[i];
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
103 den += u[i] * u[i];
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
104 }
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
105 num /= den;
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
106 for (i = 0; i < BLOCKSIZE; i++)
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
107 v[i] -= num * u[i];
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
108 }
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
109
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
110
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
111 /**
12024
fdafbcef52f5 Fix grammar errors in documentation
mru
parents: 11874
diff changeset
112 * Calculate match score and gain of an LPC-filtered vector with respect to
11870
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
113 * input data, possibly othogonalizing it to up to 2 other vectors
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
114 *
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
115 * @param work array used to calculate the filtered vector
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
116 * @param coefs coefficients of the LPC filter
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
117 * @param vect original vector
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
118 * @param ortho1 first vector against which orthogonalization is performed
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
119 * @param ortho2 second vector against which orthogonalization is performed
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
120 * @param data input data
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
121 * @param score pointer to variable where match score is returned
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
122 * @param gain pointer to variable where gain is returned
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
123 */
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
124 static void get_match_score(float *work, const float *coefs, float *vect,
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
125 const float *ortho1, const float *ortho2,
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
126 const float *data, float *score, float *gain)
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
127 {
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
128 float c, g;
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
129 int i;
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
130
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
131 ff_celp_lp_synthesis_filterf(work, coefs, vect, BLOCKSIZE, LPC_ORDER);
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
132 if (ortho1)
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
133 orthogonalize(work, ortho1);
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
134 if (ortho2)
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
135 orthogonalize(work, ortho2);
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
136 c = g = 0;
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
137 for (i = 0; i < BLOCKSIZE; i++) {
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
138 g += work[i] * work[i];
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
139 c += data[i] * work[i];
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
140 }
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
141 if (c <= 0) {
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
142 *score = 0;
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
143 return;
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
144 }
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
145 *gain = c / g;
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
146 *score = *gain * c;
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
147 }
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
148
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
149
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
150 /**
12024
fdafbcef52f5 Fix grammar errors in documentation
mru
parents: 11874
diff changeset
151 * Create a vector from the adaptive codebook at a given lag value
11870
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
152 *
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
153 * @param vect array where vector is stored
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
154 * @param cb adaptive codebook
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
155 * @param lag lag value
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
156 */
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
157 static void create_adapt_vect(float *vect, const int16_t *cb, int lag)
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
158 {
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
159 int i;
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
160
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
161 cb += BUFFERSIZE - lag;
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
162 for (i = 0; i < FFMIN(BLOCKSIZE, lag); i++)
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
163 vect[i] = cb[i];
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
164 if (lag < BLOCKSIZE)
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
165 for (i = 0; i < BLOCKSIZE - lag; i++)
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
166 vect[lag + i] = cb[i];
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
167 }
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
168
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
169
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
170 /**
12024
fdafbcef52f5 Fix grammar errors in documentation
mru
parents: 11874
diff changeset
171 * Search the adaptive codebook for the best entry and gain and remove its
11870
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
172 * contribution from input data
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
173 *
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
174 * @param adapt_cb array from which the adaptive codebook is extracted
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
175 * @param work array used to calculate LPC-filtered vectors
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
176 * @param coefs coefficients of the LPC filter
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
177 * @param data input data
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
178 * @return index of the best entry of the adaptive codebook
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
179 */
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
180 static int adaptive_cb_search(const int16_t *adapt_cb, float *work,
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
181 const float *coefs, float *data)
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
182 {
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
183 int i, best_vect;
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
184 float score, gain, best_score, best_gain;
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
185 float exc[BLOCKSIZE];
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
186
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
187 gain = best_score = 0;
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
188 for (i = BLOCKSIZE / 2; i <= BUFFERSIZE; i++) {
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
189 create_adapt_vect(exc, adapt_cb, i);
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
190 get_match_score(work, coefs, exc, NULL, NULL, data, &score, &gain);
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
191 if (score > best_score) {
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
192 best_score = score;
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
193 best_vect = i;
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
194 best_gain = gain;
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
195 }
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
196 }
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
197 if (!best_score)
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
198 return 0;
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
199
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
200 /**
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
201 * Re-calculate the filtered vector from the vector with maximum match score
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
202 * and remove its contribution from input data.
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
203 */
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
204 create_adapt_vect(exc, adapt_cb, best_vect);
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
205 ff_celp_lp_synthesis_filterf(work, coefs, exc, BLOCKSIZE, LPC_ORDER);
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
206 for (i = 0; i < BLOCKSIZE; i++)
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
207 data[i] -= best_gain * work[i];
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
208 return (best_vect - BLOCKSIZE / 2 + 1);
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
209 }
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
210
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
211
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
212 /**
12024
fdafbcef52f5 Fix grammar errors in documentation
mru
parents: 11874
diff changeset
213 * Find the best vector of a fixed codebook by applying an LPC filter to
11870
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
214 * codebook entries, possibly othogonalizing them to up to 2 other vectors and
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
215 * matching the results with input data
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
216 *
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
217 * @param work array used to calculate the filtered vectors
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
218 * @param coefs coefficients of the LPC filter
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
219 * @param cb fixed codebook
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
220 * @param ortho1 first vector against which orthogonalization is performed
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
221 * @param ortho2 second vector against which orthogonalization is performed
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
222 * @param data input data
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
223 * @param idx pointer to variable where the index of the best codebook entry is
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
224 * returned
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
225 * @param gain pointer to variable where the gain of the best codebook entry is
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
226 * returned
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
227 */
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
228 static void find_best_vect(float *work, const float *coefs,
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
229 const int8_t cb[][BLOCKSIZE], const float *ortho1,
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
230 const float *ortho2, float *data, int *idx,
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
231 float *gain)
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
232 {
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
233 int i, j;
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
234 float g, score, best_score;
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
235 float vect[BLOCKSIZE];
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
236
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
237 *idx = *gain = best_score = 0;
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
238 for (i = 0; i < FIXED_CB_SIZE; i++) {
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
239 for (j = 0; j < BLOCKSIZE; j++)
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
240 vect[j] = cb[i][j];
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
241 get_match_score(work, coefs, vect, ortho1, ortho2, data, &score, &g);
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
242 if (score > best_score) {
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
243 best_score = score;
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
244 *idx = i;
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
245 *gain = g;
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
246 }
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
247 }
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
248 }
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
249
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
250
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
251 /**
12024
fdafbcef52f5 Fix grammar errors in documentation
mru
parents: 11874
diff changeset
252 * Search the two fixed codebooks for the best entry and gain
11870
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
253 *
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
254 * @param work array used to calculate LPC-filtered vectors
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
255 * @param coefs coefficients of the LPC filter
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
256 * @param data input data
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
257 * @param cba_idx index of the best entry of the adaptive codebook
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
258 * @param cb1_idx pointer to variable where the index of the best entry of the
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
259 * first fixed codebook is returned
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
260 * @param cb2_idx pointer to variable where the index of the best entry of the
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
261 * second fixed codebook is returned
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
262 */
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
263 static void fixed_cb_search(float *work, const float *coefs, float *data,
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
264 int cba_idx, int *cb1_idx, int *cb2_idx)
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
265 {
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
266 int i, ortho_cb1;
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
267 float gain;
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
268 float cba_vect[BLOCKSIZE], cb1_vect[BLOCKSIZE];
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
269 float vect[BLOCKSIZE];
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
270
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
271 /**
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
272 * The filtered vector from the adaptive codebook can be retrieved from
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
273 * work, because this function is called just after adaptive_cb_search().
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
274 */
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
275 if (cba_idx)
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
276 memcpy(cba_vect, work, sizeof(cba_vect));
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
277
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
278 find_best_vect(work, coefs, ff_cb1_vects, cba_idx ? cba_vect : NULL, NULL,
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
279 data, cb1_idx, &gain);
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
280
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
281 /**
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
282 * Re-calculate the filtered vector from the vector with maximum match score
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
283 * and remove its contribution from input data.
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
284 */
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
285 if (gain) {
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
286 for (i = 0; i < BLOCKSIZE; i++)
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
287 vect[i] = ff_cb1_vects[*cb1_idx][i];
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
288 ff_celp_lp_synthesis_filterf(work, coefs, vect, BLOCKSIZE, LPC_ORDER);
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
289 if (cba_idx)
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
290 orthogonalize(work, cba_vect);
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
291 for (i = 0; i < BLOCKSIZE; i++)
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
292 data[i] -= gain * work[i];
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
293 memcpy(cb1_vect, work, sizeof(cb1_vect));
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
294 ortho_cb1 = 1;
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
295 } else
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
296 ortho_cb1 = 0;
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
297
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
298 find_best_vect(work, coefs, ff_cb2_vects, cba_idx ? cba_vect : NULL,
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
299 ortho_cb1 ? cb1_vect : NULL, data, cb2_idx, &gain);
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
300 }
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
301
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
302
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
303 /**
12024
fdafbcef52f5 Fix grammar errors in documentation
mru
parents: 11874
diff changeset
304 * Encode a subblock of the current frame
11870
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
305 *
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
306 * @param ractx encoder context
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
307 * @param sblock_data input data of the subblock
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
308 * @param lpc_coefs coefficients of the LPC filter
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
309 * @param rms RMS of the reflection coefficients
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
310 * @param pb pointer to PutBitContext of the current frame
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
311 */
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
312 static void ra144_encode_subblock(RA144Context *ractx,
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
313 const int16_t *sblock_data,
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
314 const int16_t *lpc_coefs, unsigned int rms,
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
315 PutBitContext *pb)
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
316 {
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
317 float data[BLOCKSIZE], work[LPC_ORDER + BLOCKSIZE];
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
318 float coefs[LPC_ORDER];
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
319 float zero[BLOCKSIZE], cba[BLOCKSIZE], cb1[BLOCKSIZE], cb2[BLOCKSIZE];
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
320 int16_t cba_vect[BLOCKSIZE];
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
321 int cba_idx, cb1_idx, cb2_idx, gain;
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
322 int i, n, m[3];
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
323 float g[3];
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
324 float error, best_error;
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
325
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
326 for (i = 0; i < LPC_ORDER; i++) {
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
327 work[i] = ractx->curr_sblock[BLOCKSIZE + i];
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
328 coefs[i] = lpc_coefs[i] * (1/4096.0);
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
329 }
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
330
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
331 /**
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
332 * Calculate the zero-input response of the LPC filter and subtract it from
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
333 * input data.
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
334 */
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
335 memset(data, 0, sizeof(data));
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
336 ff_celp_lp_synthesis_filterf(work + LPC_ORDER, coefs, data, BLOCKSIZE,
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
337 LPC_ORDER);
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
338 for (i = 0; i < BLOCKSIZE; i++) {
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
339 zero[i] = work[LPC_ORDER + i];
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
340 data[i] = sblock_data[i] - zero[i];
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
341 }
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
342
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
343 /**
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
344 * Codebook search is performed without taking into account the contribution
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
345 * of the previous subblock, since it has been just subtracted from input
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
346 * data.
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
347 */
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
348 memset(work, 0, LPC_ORDER * sizeof(*work));
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
349
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
350 cba_idx = adaptive_cb_search(ractx->adapt_cb, work + LPC_ORDER, coefs,
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
351 data);
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
352 if (cba_idx) {
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
353 /**
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
354 * The filtered vector from the adaptive codebook can be retrieved from
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
355 * work, see implementation of adaptive_cb_search().
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
356 */
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
357 memcpy(cba, work + LPC_ORDER, sizeof(cba));
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
358
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
359 ff_copy_and_dup(cba_vect, ractx->adapt_cb, cba_idx + BLOCKSIZE / 2 - 1);
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
360 m[0] = (ff_irms(cba_vect) * rms) >> 12;
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
361 }
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
362 fixed_cb_search(work + LPC_ORDER, coefs, data, cba_idx, &cb1_idx, &cb2_idx);
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
363 for (i = 0; i < BLOCKSIZE; i++) {
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
364 cb1[i] = ff_cb1_vects[cb1_idx][i];
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
365 cb2[i] = ff_cb2_vects[cb2_idx][i];
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
366 }
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
367 ff_celp_lp_synthesis_filterf(work + LPC_ORDER, coefs, cb1, BLOCKSIZE,
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
368 LPC_ORDER);
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
369 memcpy(cb1, work + LPC_ORDER, sizeof(cb1));
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
370 m[1] = (ff_cb1_base[cb1_idx] * rms) >> 8;
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
371 ff_celp_lp_synthesis_filterf(work + LPC_ORDER, coefs, cb2, BLOCKSIZE,
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
372 LPC_ORDER);
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
373 memcpy(cb2, work + LPC_ORDER, sizeof(cb2));
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
374 m[2] = (ff_cb2_base[cb2_idx] * rms) >> 8;
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
375 best_error = FLT_MAX;
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
376 gain = 0;
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
377 for (n = 0; n < 256; n++) {
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
378 g[1] = ((ff_gain_val_tab[n][1] * m[1]) >> ff_gain_exp_tab[n]) *
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
379 (1/4096.0);
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
380 g[2] = ((ff_gain_val_tab[n][2] * m[2]) >> ff_gain_exp_tab[n]) *
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
381 (1/4096.0);
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
382 error = 0;
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
383 if (cba_idx) {
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
384 g[0] = ((ff_gain_val_tab[n][0] * m[0]) >> ff_gain_exp_tab[n]) *
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
385 (1/4096.0);
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
386 for (i = 0; i < BLOCKSIZE; i++) {
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
387 data[i] = zero[i] + g[0] * cba[i] + g[1] * cb1[i] +
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
388 g[2] * cb2[i];
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
389 error += (data[i] - sblock_data[i]) *
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
390 (data[i] - sblock_data[i]);
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
391 }
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
392 } else {
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
393 for (i = 0; i < BLOCKSIZE; i++) {
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
394 data[i] = zero[i] + g[1] * cb1[i] + g[2] * cb2[i];
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
395 error += (data[i] - sblock_data[i]) *
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
396 (data[i] - sblock_data[i]);
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
397 }
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
398 }
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
399 if (error < best_error) {
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
400 best_error = error;
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
401 gain = n;
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
402 }
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
403 }
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
404 put_bits(pb, 7, cba_idx);
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
405 put_bits(pb, 8, gain);
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
406 put_bits(pb, 7, cb1_idx);
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
407 put_bits(pb, 7, cb2_idx);
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
408 ff_subblock_synthesis(ractx, lpc_coefs, cba_idx, cb1_idx, cb2_idx, rms,
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
409 gain);
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
410 }
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
411
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
412
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
413 static int ra144_encode_frame(AVCodecContext *avctx, uint8_t *frame,
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
414 int buf_size, void *data)
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
415 {
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
416 static const uint8_t sizes[LPC_ORDER] = {64, 32, 32, 16, 16, 8, 8, 8, 8, 4};
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
417 static const uint8_t bit_sizes[LPC_ORDER] = {6, 5, 5, 4, 4, 3, 3, 3, 3, 2};
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
418 RA144Context *ractx;
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
419 PutBitContext pb;
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
420 int32_t lpc_data[NBLOCKS * BLOCKSIZE];
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
421 int32_t lpc_coefs[LPC_ORDER][MAX_LPC_ORDER];
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
422 int shift[LPC_ORDER];
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
423 int16_t block_coefs[NBLOCKS][LPC_ORDER];
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
424 int lpc_refl[LPC_ORDER]; /**< reflection coefficients of the frame */
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
425 unsigned int refl_rms[NBLOCKS]; /**< RMS of the reflection coefficients */
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
426 int energy = 0;
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
427 int i, idx;
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
428
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
429 if (buf_size < FRAMESIZE) {
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
430 av_log(avctx, AV_LOG_ERROR, "output buffer too small\n");
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
431 return 0;
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
432 }
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
433 ractx = avctx->priv_data;
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
434
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
435 /**
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
436 * Since the LPC coefficients are calculated on a frame centered over the
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
437 * fourth subframe, to encode a given frame, data from the next frame is
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
438 * needed. In each call to this function, the previous frame (whose data are
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
439 * saved in the encoder context) is encoded, and data from the current frame
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
440 * are saved in the encoder context to be used in the next function call.
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
441 */
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
442 for (i = 0; i < (2 * BLOCKSIZE + BLOCKSIZE / 2); i++) {
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
443 lpc_data[i] = ractx->curr_block[BLOCKSIZE + BLOCKSIZE / 2 + i];
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
444 energy += (lpc_data[i] * lpc_data[i]) >> 4;
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
445 }
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
446 for (i = 2 * BLOCKSIZE + BLOCKSIZE / 2; i < NBLOCKS * BLOCKSIZE; i++) {
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
447 lpc_data[i] = *((int16_t *)data + i - 2 * BLOCKSIZE - BLOCKSIZE / 2) >>
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
448 2;
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
449 energy += (lpc_data[i] * lpc_data[i]) >> 4;
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
450 }
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
451 energy = ff_energy_tab[quantize(ff_t_sqrt(energy >> 5) >> 10, ff_energy_tab,
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
452 32)];
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
453
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
454 ff_lpc_calc_coefs(&ractx->dsp, lpc_data, NBLOCKS * BLOCKSIZE, LPC_ORDER,
12139
e59926e2c50c Add AVCodecContext.lpc_type and Add AVCodecContext.lpc_passes fields.
jbr
parents: 12024
diff changeset
455 LPC_ORDER, 16, lpc_coefs, shift, AV_LPC_TYPE_LEVINSON,
e59926e2c50c Add AVCodecContext.lpc_type and Add AVCodecContext.lpc_passes fields.
jbr
parents: 12024
diff changeset
456 0, ORDER_METHOD_EST, 12, 0);
11870
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
457 for (i = 0; i < LPC_ORDER; i++)
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
458 block_coefs[NBLOCKS - 1][i] = -(lpc_coefs[LPC_ORDER - 1][i] <<
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
459 (12 - shift[LPC_ORDER - 1]));
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
460
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
461 /**
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
462 * TODO: apply perceptual weighting of the input speech through bandwidth
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
463 * expansion of the LPC filter.
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
464 */
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
465
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
466 if (ff_eval_refl(lpc_refl, block_coefs[NBLOCKS - 1], avctx)) {
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
467 /**
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
468 * The filter is unstable: use the coefficients of the previous frame.
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
469 */
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
470 ff_int_to_int16(block_coefs[NBLOCKS - 1], ractx->lpc_coef[1]);
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
471 ff_eval_refl(lpc_refl, block_coefs[NBLOCKS - 1], avctx);
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
472 }
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
473 init_put_bits(&pb, frame, buf_size);
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
474 for (i = 0; i < LPC_ORDER; i++) {
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
475 idx = quantize(lpc_refl[i], ff_lpc_refl_cb[i], sizes[i]);
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
476 put_bits(&pb, bit_sizes[i], idx);
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
477 lpc_refl[i] = ff_lpc_refl_cb[i][idx];
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
478 }
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
479 ractx->lpc_refl_rms[0] = ff_rms(lpc_refl);
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
480 ff_eval_coefs(ractx->lpc_coef[0], lpc_refl);
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
481 refl_rms[0] = ff_interp(ractx, block_coefs[0], 1, 1, ractx->old_energy);
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
482 refl_rms[1] = ff_interp(ractx, block_coefs[1], 2,
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
483 energy <= ractx->old_energy,
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
484 ff_t_sqrt(energy * ractx->old_energy) >> 12);
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
485 refl_rms[2] = ff_interp(ractx, block_coefs[2], 3, 0, energy);
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
486 refl_rms[3] = ff_rescale_rms(ractx->lpc_refl_rms[0], energy);
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
487 ff_int_to_int16(block_coefs[NBLOCKS - 1], ractx->lpc_coef[0]);
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
488 put_bits(&pb, 5, quantize(energy, ff_energy_tab, 32));
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
489 for (i = 0; i < NBLOCKS; i++)
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
490 ra144_encode_subblock(ractx, ractx->curr_block + i * BLOCKSIZE,
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
491 block_coefs[i], refl_rms[i], &pb);
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
492 flush_put_bits(&pb);
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
493 ractx->old_energy = energy;
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
494 ractx->lpc_refl_rms[1] = ractx->lpc_refl_rms[0];
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
495 FFSWAP(unsigned int *, ractx->lpc_coef[0], ractx->lpc_coef[1]);
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
496 for (i = 0; i < NBLOCKS * BLOCKSIZE; i++)
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
497 ractx->curr_block[i] = *((int16_t *)data + i) >> 2;
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
498 return FRAMESIZE;
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
499 }
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
500
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
501
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
502 AVCodec ra_144_encoder =
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
503 {
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
504 "real_144",
12516
34beb0af8204 Replace deprecated CODEC_TYPE_AUDIO and CODEC_TYPE_VIDEO with the
stefano
parents: 12139
diff changeset
505 AVMEDIA_TYPE_AUDIO,
11870
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
506 CODEC_ID_RA_144,
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
507 sizeof(RA144Context),
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
508 ra144_encode_init,
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
509 ra144_encode_frame,
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
510 .long_name = NULL_IF_CONFIG_SMALL("RealAudio 1.0 (14.4K) encoder"),
6b1a63ea6e61 RealAudio 14.4k encoder.
vitor
parents:
diff changeset
511 };