1 /*
2 * Real Audio 1.0 (14.4K) encoder
3 * Copyright (c) 2010 Francesco Lavra <francescolavra@interfree.it>
4 *
5 * This file is part of FFmpeg.
6 *
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.
11 *
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.
16 *
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
20 */
21
22 /**
23 * @file
24 * Real Audio 1.0 (14.4K) encoder
25 * @author Francesco Lavra <francescolavra@interfree.it>
26 */
27
29
39
41 {
45 return 0;
46 }
47
48
50 {
53
57 return -1;
58 }
71
73
74 return 0;
75 }
76
77
78 /**
79 * Quantize a value by searching a sorted table for the element with the
80 * nearest value
81 *
82 * @param value value to quantize
83 * @param table array containing the quantization table
84 * @param size size of the quantization table
85 * @return index of the quantization table corresponding to the element with the
86 * nearest value
87 */
89 {
90 unsigned int low = 0, high =
size - 1;
91
92 while (1) {
93 int index = (low + high) >> 1;
95
100 } else {
102 }
103 }
104 }
105
106
107 /**
108 * Orthogonalize a vector to another vector
109 *
110 * @param v vector to orthogonalize
111 * @param u vector against which orthogonalization is performed
112 */
114 {
116 float num = 0, den = 0;
117
121 }
122 num /= den;
125 }
126
127
128 /**
129 * Calculate match score and gain of an LPC-filtered vector with respect to
130 * input data, possibly orthogonalizing it to up to two other vectors.
131 *
132 * @param work array used to calculate the filtered vector
133 * @param coefs coefficients of the LPC filter
134 * @param vect original vector
135 * @param ortho1 first vector against which orthogonalization is performed
136 * @param ortho2 second vector against which orthogonalization is performed
137 * @param data input data
138 * @param score pointer to variable where match score is returned
139 * @param gain pointer to variable where gain is returned
140 */
142 const float *ortho1, const float *ortho2,
143 const float *
data,
float *score,
float *gain)
144 {
147
149 if (ortho1)
151 if (ortho2)
157 }
159 *score = 0;
160 return;
161 }
164 }
165
166
167 /**
168 * Create a vector from the adaptive codebook at a given lag value
169 *
170 * @param vect array where vector is stored
171 * @param cb adaptive codebook
172 * @param lag lag value
173 */
175 {
177
183 vect[lag +
i] =
cb[
i];
184 }
185
186
187 /**
188 * Search the adaptive codebook for the best entry and gain and remove its
189 * contribution from input data
190 *
191 * @param adapt_cb array from which the adaptive codebook is extracted
192 * @param work array used to calculate LPC-filtered vectors
193 * @param coefs coefficients of the LPC filter
194 * @param data input data
195 * @return index of the best entry of the adaptive codebook
196 */
198 const float *coefs,
float *
data)
199 {
201 float score, gain, best_score,
av_uninit(best_gain);
203
204 gain = best_score = 0;
208 if (score > best_score) {
209 best_score = score;
211 best_gain = gain;
212 }
213 }
214 if (!best_score)
215 return 0;
216
217 /**
218 * Re-calculate the filtered vector from the vector with maximum match score
219 * and remove its contribution from input data.
220 */
226 }
227
228
229 /**
230 * Find the best vector of a fixed codebook by applying an LPC filter to
231 * codebook entries, possibly orthogonalizing them to up to two other vectors
232 * and matching the results with input data.
233 *
234 * @param work array used to calculate the filtered vectors
235 * @param coefs coefficients of the LPC filter
236 * @param cb fixed codebook
237 * @param ortho1 first vector against which orthogonalization is performed
238 * @param ortho2 second vector against which orthogonalization is performed
239 * @param data input data
240 * @param idx pointer to variable where the index of the best codebook entry is
241 * returned
242 * @param gain pointer to variable where the gain of the best codebook entry is
243 * returned
244 */
247 const float *ortho2,
float *
data,
int *idx,
248 float *gain)
249 {
251 float g, score, best_score;
253
254 *idx = *gain = best_score = 0;
259 if (score > best_score) {
260 best_score = score;
263 }
264 }
265 }
266
267
268 /**
269 * Search the two fixed codebooks for the best entry and gain
270 *
271 * @param work array used to calculate LPC-filtered vectors
272 * @param coefs coefficients of the LPC filter
273 * @param data input data
274 * @param cba_idx index of the best entry of the adaptive codebook
275 * @param cb1_idx pointer to variable where the index of the best entry of the
276 * first fixed codebook is returned
277 * @param cb2_idx pointer to variable where the index of the best entry of the
278 * second fixed codebook is returned
279 */
281 int cba_idx, int *cb1_idx, int *cb2_idx)
282 {
284 float gain;
287
288 /**
289 * The filtered vector from the adaptive codebook can be retrieved from
290 * work, because this function is called just after adaptive_cb_search().
291 */
292 if (cba_idx)
293 memcpy(cba_vect,
work,
sizeof(cba_vect));
294
296 data, cb1_idx, &gain);
297
298 /**
299 * Re-calculate the filtered vector from the vector with maximum match score
300 * and remove its contribution from input data.
301 */
302 if (gain) {
306 if (cba_idx)
310 memcpy(cb1_vect,
work,
sizeof(cb1_vect));
311 ortho_cb1 = 1;
312 } else
313 ortho_cb1 = 0;
314
316 ortho_cb1 ? cb1_vect :
NULL,
data, cb2_idx, &gain);
317 }
318
319
320 /**
321 * Encode a subblock of the current frame
322 *
323 * @param ractx encoder context
324 * @param sblock_data input data of the subblock
325 * @param lpc_coefs coefficients of the LPC filter
326 * @param rms RMS of the reflection coefficients
327 * @param pb pointer to PutBitContext of the current frame
328 */
330 const int16_t *sblock_data,
331 const int16_t *lpc_coefs, unsigned int rms,
333 {
337 int cba_idx, cb1_idx, cb2_idx, gain;
339 unsigned m[3];
341 float error, best_error;
342
345 coefs[
i] = lpc_coefs[
i] * (1/4096.0);
346 }
347
348 /**
349 * Calculate the zero-input response of the LPC filter and subtract it from
350 * input data.
351 */
357 }
358
359 /**
360 * Codebook search is performed without taking into account the contribution
361 * of the previous subblock, since it has been just subtracted from input
362 * data.
363 */
365
368 if (cba_idx) {
369 /**
370 * The filtered vector from the adaptive codebook can be retrieved from
371 * work, see implementation of adaptive_cb_search().
372 */
374
377 }
382 }
391 best_error = FLT_MAX;
392 gain = 0;
393 for (n = 0; n < 256; n++) {
395 (1/4096.0);
397 (1/4096.0);
399 if (cba_idx) {
401 (1/4096.0);
406 (
data[
i] - sblock_data[
i]);
407 }
408 } else {
412 (
data[
i] - sblock_data[
i]);
413 }
414 }
415 if (
error < best_error) {
417 gain = n;
418 }
419 }
425 gain);
426 }
427
428
431 {
432 static const uint8_t
sizes[
LPC_ORDER] = {64, 32, 32, 16, 16, 8, 8, 8, 8, 4};
433 static const uint8_t bit_sizes[
LPC_ORDER] = {6, 5, 5, 4, 4, 3, 3, 3, 3, 2};
440 int lpc_refl[
LPC_ORDER];
/**< reflection coefficients of the frame */
441 unsigned int refl_rms[
NBLOCKS];
/**< RMS of the reflection coefficients */
443 int energy = 0;
445
447 return 0;
448
451
452 /**
453 * Since the LPC coefficients are calculated on a frame centered over the
454 * fourth subframe, to encode a given frame, data from the next frame is
455 * needed. In each call to this function, the previous frame (whose data are
456 * saved in the encoder context) is encoded, and data from the current frame
457 * are saved in the encoder context to be used in the next function call.
458 */
461 energy += (lpc_data[
i] * lpc_data[
i]) >> 4;
462 }
464 int j;
467 energy += (lpc_data[
i] * lpc_data[
i]) >> 4;
468 }
469 }
473 32)];
474
481
482 /**
483 * TODO: apply perceptual weighting of the input speech through bandwidth
484 * expansion of the LPC filter.
485 */
486
488 /**
489 * The filter is unstable: use the coefficients of the previous frame.
490 */
493 /* the filter is still unstable. set reflection coeffs to zero. */
494 memset(lpc_refl, 0, sizeof(lpc_refl));
495 }
496 }
502 }
506 refl_rms[1] =
ff_interp(ractx, block_coefs[1], 2,
507 energy <= ractx->old_energy,
509 refl_rms[2] =
ff_interp(ractx, block_coefs[2], 3, 0, energy);
515 block_coefs[
i], refl_rms[
i], &pb);
520
521 /* copy input samples to current block for processing in next call */
524 for (;
i <
frame->nb_samples;
i++)
526
529 } else
533
534 /* Get the next frame pts/duration */
537
538 *got_packet_ptr = 1;
539 return 0;
540 }
541
542
556 .supported_samplerates = (const int[]){ 8000, 0 },
559 };