annotate amrnbdec.c @ 11560:8a4984c5cacc libavcodec

Define AVMediaType enum, and use it instead of enum CodecType, which is deprecated and will be dropped at the next major bump.
author stefano
date Tue, 30 Mar 2010 23:30:55 +0000
parents c2e19a511e26
children 7dd2a45249a9
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
11235
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
1 /*
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
2 * AMR narrowband decoder
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
3 * Copyright (c) 2006-2007 Robert Swain
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
4 * Copyright (c) 2009 Colin McQuillan
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
5 *
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
6 * This file is part of FFmpeg.
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
7 *
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
8 * FFmpeg is free software; you can redistribute it and/or
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
9 * modify it under the terms of the GNU Lesser General Public
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
10 * License as published by the Free Software Foundation; either
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
11 * version 2.1 of the License, or (at your option) any later version.
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
12 *
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
13 * FFmpeg is distributed in the hope that it will be useful,
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
16 * Lesser General Public License for more details.
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
17 *
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
18 * You should have received a copy of the GNU Lesser General Public
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
19 * License along with FFmpeg; if not, write to the Free Software
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
21 */
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
22
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
23
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
24 /**
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
25 * @file libavcodec/amrnbdec.c
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
26 * AMR narrowband decoder
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
27 *
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
28 * This decoder uses floats for simplicity and so is not bit-exact. One
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
29 * difference is that differences in phase can accumulate. The test sequences
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
30 * in 3GPP TS 26.074 can still be useful.
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
31 *
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
32 * - Comparing this file's output to the output of the ref decoder gives a
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
33 * PSNR of 30 to 80. Plotting the output samples shows a difference in
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
34 * phase in some areas.
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
35 *
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
36 * - Comparing both decoders against their input, this decoder gives a similar
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
37 * PSNR. If the test sequence homing frames are removed (this decoder does
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
38 * not detect them), the PSNR is at least as good as the reference on 140
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
39 * out of 169 tests.
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
40 */
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
41
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
42
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
43 #include <string.h>
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
44 #include <math.h>
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
45
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
46 #include "avcodec.h"
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
47 #include "get_bits.h"
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
48 #include "libavutil/common.h"
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
49 #include "celp_math.h"
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
50 #include "celp_filters.h"
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
51 #include "acelp_filters.h"
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
52 #include "acelp_vectors.h"
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
53 #include "acelp_pitch_delay.h"
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
54 #include "lsp.h"
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
55
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
56 #include "amrnbdata.h"
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
57
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
58 #define AMR_BLOCK_SIZE 160 ///< samples per frame
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
59 #define AMR_SAMPLE_BOUND 32768.0 ///< threshold for synthesis overflow
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
60
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
61 /**
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
62 * Scale from constructed speech to [-1,1]
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
63 *
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
64 * AMR is designed to produce 16-bit PCM samples (3GPP TS 26.090 4.2) but
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
65 * upscales by two (section 6.2.2).
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
66 *
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
67 * Fundamentally, this scale is determined by energy_mean through
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
68 * the fixed vector contribution to the excitation vector.
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
69 */
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
70 #define AMR_SAMPLE_SCALE (2.0 / 32768.0)
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
71
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
72 /** Prediction factor for 12.2kbit/s mode */
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
73 #define PRED_FAC_MODE_12k2 0.65
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
74
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
75 #define LSF_R_FAC (8000.0 / 32768.0) ///< LSF residual tables to Hertz
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
76 #define MIN_LSF_SPACING (50.0488 / 8000.0) ///< Ensures stability of LPC filter
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
77 #define PITCH_LAG_MIN_MODE_12k2 18 ///< Lower bound on decoded lag search in 12.2kbit/s mode
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
78
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
79 /** Initial energy in dB. Also used for bad frames (unimplemented). */
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
80 #define MIN_ENERGY -14.0
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
81
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
82 /** Maximum sharpening factor
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
83 *
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
84 * The specification says 0.8, which should be 13107, but the reference C code
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
85 * uses 13017 instead. (Amusingly the same applies to SHARP_MAX in g729dec.c.)
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
86 */
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
87 #define SHARP_MAX 0.79449462890625
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
88
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
89 /** Number of impulse response coefficients used for tilt factor */
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
90 #define AMR_TILT_RESPONSE 22
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
91 /** Tilt factor = 1st reflection coefficient * gamma_t */
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
92 #define AMR_TILT_GAMMA_T 0.8
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
93 /** Adaptive gain control factor used in post-filter */
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
94 #define AMR_AGC_ALPHA 0.9
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
95
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
96 typedef struct AMRContext {
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
97 AMRNBFrame frame; ///< decoded AMR parameters (lsf coefficients, codebook indexes, etc)
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
98 uint8_t bad_frame_indicator; ///< bad frame ? 1 : 0
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
99 enum Mode cur_frame_mode;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
100
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
101 int16_t prev_lsf_r[LP_FILTER_ORDER]; ///< residual LSF vector from previous subframe
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
102 double lsp[4][LP_FILTER_ORDER]; ///< lsp vectors from current frame
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
103 double prev_lsp_sub4[LP_FILTER_ORDER]; ///< lsp vector for the 4th subframe of the previous frame
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
104
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
105 float lsf_q[4][LP_FILTER_ORDER]; ///< Interpolated LSF vector for fixed gain smoothing
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
106 float lsf_avg[LP_FILTER_ORDER]; ///< vector of averaged lsf vector
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
107
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
108 float lpc[4][LP_FILTER_ORDER]; ///< lpc coefficient vectors for 4 subframes
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
109
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
110 uint8_t pitch_lag_int; ///< integer part of pitch lag from current subframe
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
111
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
112 float excitation_buf[PITCH_DELAY_MAX + LP_FILTER_ORDER + 1 + AMR_SUBFRAME_SIZE]; ///< current excitation and all necessary excitation history
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
113 float *excitation; ///< pointer to the current excitation vector in excitation_buf
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
114
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
115 float pitch_vector[AMR_SUBFRAME_SIZE]; ///< adaptive code book (pitch) vector
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
116 float fixed_vector[AMR_SUBFRAME_SIZE]; ///< algebraic codebook (fixed) vector (must be kept zero between frames)
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
117
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
118 float prediction_error[4]; ///< quantified prediction errors {20log10(^gamma_gc)} for previous four subframes
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
119 float pitch_gain[5]; ///< quantified pitch gains for the current and previous four subframes
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
120 float fixed_gain[5]; ///< quantified fixed gains for the current and previous four subframes
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
121
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
122 float beta; ///< previous pitch_gain, bounded by [0.0,SHARP_MAX]
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
123 uint8_t diff_count; ///< the number of subframes for which diff has been above 0.65
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
124 uint8_t hang_count; ///< the number of subframes since a hangover period started
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
125
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
126 float prev_sparse_fixed_gain; ///< previous fixed gain; used by anti-sparseness processing to determine "onset"
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
127 uint8_t prev_ir_filter_nr; ///< previous impulse response filter "impNr": 0 - strong, 1 - medium, 2 - none
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
128 uint8_t ir_filter_onset; ///< flag for impulse response filter strength
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
129
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
130 float postfilter_mem[10]; ///< previous intermediate values in the formant filter
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
131 float tilt_mem; ///< previous input to tilt compensation filter
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
132 float postfilter_agc; ///< previous factor used for adaptive gain control
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
133 float high_pass_mem[2]; ///< previous intermediate values in the high-pass filter
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
134
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
135 float samples_in[LP_FILTER_ORDER + AMR_SUBFRAME_SIZE]; ///< floating point samples
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
136
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
137 } AMRContext;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
138
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
139 /** Double version of ff_weighted_vector_sumf() */
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
140 static void weighted_vector_sumd(double *out, const double *in_a,
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
141 const double *in_b, double weight_coeff_a,
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
142 double weight_coeff_b, int length)
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
143 {
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
144 int i;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
145
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
146 for (i = 0; i < length; i++)
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
147 out[i] = weight_coeff_a * in_a[i]
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
148 + weight_coeff_b * in_b[i];
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
149 }
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
150
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
151 static av_cold int amrnb_decode_init(AVCodecContext *avctx)
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
152 {
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
153 AMRContext *p = avctx->priv_data;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
154 int i;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
155
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
156 avctx->sample_fmt = SAMPLE_FMT_FLT;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
157
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
158 // p->excitation always points to the same position in p->excitation_buf
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
159 p->excitation = &p->excitation_buf[PITCH_DELAY_MAX + LP_FILTER_ORDER + 1];
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
160
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
161 for (i = 0; i < LP_FILTER_ORDER; i++) {
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
162 p->prev_lsp_sub4[i] = lsp_sub4_init[i] * 1000 / (float)(1 << 15);
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
163 p->lsf_avg[i] = p->lsf_q[3][i] = lsp_avg_init[i] / (float)(1 << 15);
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
164 }
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
165
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
166 for (i = 0; i < 4; i++)
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
167 p->prediction_error[i] = MIN_ENERGY;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
168
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
169 return 0;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
170 }
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
171
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
172
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
173 /**
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
174 * Unpack an RFC4867 speech frame into the AMR frame mode and parameters.
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
175 *
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
176 * The order of speech bits is specified by 3GPP TS 26.101.
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
177 *
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
178 * @param p the context
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
179 * @param buf pointer to the input buffer
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
180 * @param buf_size size of the input buffer
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
181 *
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
182 * @return the frame mode
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
183 */
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
184 static enum Mode unpack_bitstream(AMRContext *p, const uint8_t *buf,
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
185 int buf_size)
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
186 {
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
187 GetBitContext gb;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
188 enum Mode mode;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
189
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
190 init_get_bits(&gb, buf, buf_size * 8);
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
191
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
192 // Decode the first octet.
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
193 skip_bits(&gb, 1); // padding bit
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
194 mode = get_bits(&gb, 4); // frame type
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
195 p->bad_frame_indicator = !get_bits1(&gb); // quality bit
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
196 skip_bits(&gb, 2); // two padding bits
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
197
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
198 if (mode <= MODE_DTX) {
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
199 uint16_t *data = (uint16_t *)&p->frame;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
200 const uint8_t *order = amr_unpacking_bitmaps_per_mode[mode];
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
201 int field_size;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
202
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
203 memset(&p->frame, 0, sizeof(AMRNBFrame));
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
204 buf++;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
205 while ((field_size = *order++)) {
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
206 int field = 0;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
207 int field_offset = *order++;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
208 while (field_size--) {
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
209 int bit = *order++;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
210 field <<= 1;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
211 field |= buf[bit >> 3] >> (bit & 7) & 1;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
212 }
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
213 data[field_offset] = field;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
214 }
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
215 }
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
216
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
217 return mode;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
218 }
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
219
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
220
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
221 /// @defgroup amr_lpc_decoding AMR pitch LPC coefficient decoding functions
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
222 /// @{
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
223
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
224 /**
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
225 * Convert an lsf vector into an lsp vector.
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
226 *
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
227 * @param lsf input lsf vector
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
228 * @param lsp output lsp vector
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
229 */
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
230 static void lsf2lsp(const float *lsf, double *lsp)
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
231 {
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
232 int i;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
233
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
234 for (i = 0; i < LP_FILTER_ORDER; i++)
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
235 lsp[i] = cos(2.0 * M_PI * lsf[i]);
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
236 }
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
237
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
238 /**
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
239 * Interpolate the LSF vector (used for fixed gain smoothing).
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
240 * The interpolation is done over all four subframes even in MODE_12k2.
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
241 *
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
242 * @param[in,out] lsf_q LSFs in [0,1] for each subframe
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
243 * @param[in] lsf_new New LSFs in [0,1] for subframe 4
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
244 */
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
245 static void interpolate_lsf(float lsf_q[4][LP_FILTER_ORDER], float *lsf_new)
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
246 {
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
247 int i;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
248
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
249 for (i = 0; i < 4; i++)
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
250 ff_weighted_vector_sumf(lsf_q[i], lsf_q[3], lsf_new,
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
251 0.25 * (3 - i), 0.25 * (i + 1),
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
252 LP_FILTER_ORDER);
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
253 }
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
254
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
255 /**
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
256 * Decode a set of 5 split-matrix quantized lsf indexes into an lsp vector.
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
257 *
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
258 * @param p the context
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
259 * @param lsp output LSP vector
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
260 * @param lsf_no_r LSF vector without the residual vector added
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
261 * @param lsf_quantizer pointers to LSF dictionary tables
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
262 * @param quantizer_offset offset in tables
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
263 * @param sign for the 3 dictionary table
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
264 * @param update store data for computing the next frame's LSFs
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
265 */
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
266 static void lsf2lsp_for_mode12k2(AMRContext *p, double lsp[LP_FILTER_ORDER],
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
267 const float lsf_no_r[LP_FILTER_ORDER],
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
268 const int16_t *lsf_quantizer[5],
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
269 const int quantizer_offset,
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
270 const int sign, const int update)
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
271 {
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
272 int16_t lsf_r[LP_FILTER_ORDER]; // residual LSF vector
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
273 float lsf_q[LP_FILTER_ORDER]; // quantified LSF vector
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
274 int i;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
275
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
276 for (i = 0; i < LP_FILTER_ORDER >> 1; i++)
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
277 memcpy(&lsf_r[i << 1], &lsf_quantizer[i][quantizer_offset],
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
278 2 * sizeof(*lsf_r));
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
279
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
280 if (sign) {
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
281 lsf_r[4] *= -1;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
282 lsf_r[5] *= -1;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
283 }
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
284
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
285 if (update)
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
286 memcpy(p->prev_lsf_r, lsf_r, LP_FILTER_ORDER * sizeof(float));
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
287
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
288 for (i = 0; i < LP_FILTER_ORDER; i++)
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
289 lsf_q[i] = lsf_r[i] * (LSF_R_FAC / 8000.0) + lsf_no_r[i] * (1.0 / 8000.0);
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
290
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
291 ff_set_min_dist_lsf(lsf_q, MIN_LSF_SPACING, LP_FILTER_ORDER);
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
292
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
293 if (update)
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
294 interpolate_lsf(p->lsf_q, lsf_q);
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
295
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
296 lsf2lsp(lsf_q, lsp);
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
297 }
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
298
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
299 /**
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
300 * Decode a set of 5 split-matrix quantized lsf indexes into 2 lsp vectors.
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
301 *
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
302 * @param p pointer to the AMRContext
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
303 */
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
304 static void lsf2lsp_5(AMRContext *p)
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
305 {
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
306 const uint16_t *lsf_param = p->frame.lsf;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
307 float lsf_no_r[LP_FILTER_ORDER]; // LSFs without the residual vector
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
308 const int16_t *lsf_quantizer[5];
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
309 int i;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
310
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
311 lsf_quantizer[0] = lsf_5_1[lsf_param[0]];
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
312 lsf_quantizer[1] = lsf_5_2[lsf_param[1]];
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
313 lsf_quantizer[2] = lsf_5_3[lsf_param[2] >> 1];
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
314 lsf_quantizer[3] = lsf_5_4[lsf_param[3]];
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
315 lsf_quantizer[4] = lsf_5_5[lsf_param[4]];
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
316
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
317 for (i = 0; i < LP_FILTER_ORDER; i++)
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
318 lsf_no_r[i] = p->prev_lsf_r[i] * LSF_R_FAC * PRED_FAC_MODE_12k2 + lsf_5_mean[i];
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
319
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
320 lsf2lsp_for_mode12k2(p, p->lsp[1], lsf_no_r, lsf_quantizer, 0, lsf_param[2] & 1, 0);
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
321 lsf2lsp_for_mode12k2(p, p->lsp[3], lsf_no_r, lsf_quantizer, 2, lsf_param[2] & 1, 1);
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
322
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
323 // interpolate LSP vectors at subframes 1 and 3
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
324 weighted_vector_sumd(p->lsp[0], p->prev_lsp_sub4, p->lsp[1], 0.5, 0.5, LP_FILTER_ORDER);
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
325 weighted_vector_sumd(p->lsp[2], p->lsp[1] , p->lsp[3], 0.5, 0.5, LP_FILTER_ORDER);
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
326 }
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
327
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
328 /**
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
329 * Decode a set of 3 split-matrix quantized lsf indexes into an lsp vector.
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
330 *
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
331 * @param p pointer to the AMRContext
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
332 */
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
333 static void lsf2lsp_3(AMRContext *p)
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
334 {
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
335 const uint16_t *lsf_param = p->frame.lsf;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
336 int16_t lsf_r[LP_FILTER_ORDER]; // residual LSF vector
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
337 float lsf_q[LP_FILTER_ORDER]; // quantified LSF vector
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
338 const int16_t *lsf_quantizer;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
339 int i, j;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
340
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
341 lsf_quantizer = (p->cur_frame_mode == MODE_7k95 ? lsf_3_1_MODE_7k95 : lsf_3_1)[lsf_param[0]];
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
342 memcpy(lsf_r, lsf_quantizer, 3 * sizeof(*lsf_r));
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
343
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
344 lsf_quantizer = lsf_3_2[lsf_param[1] << (p->cur_frame_mode <= MODE_5k15)];
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
345 memcpy(lsf_r + 3, lsf_quantizer, 3 * sizeof(*lsf_r));
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
346
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
347 lsf_quantizer = (p->cur_frame_mode <= MODE_5k15 ? lsf_3_3_MODE_5k15 : lsf_3_3)[lsf_param[2]];
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
348 memcpy(lsf_r + 6, lsf_quantizer, 4 * sizeof(*lsf_r));
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
349
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
350 // calculate mean-removed LSF vector and add mean
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
351 for (i = 0; i < LP_FILTER_ORDER; i++)
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
352 lsf_q[i] = (lsf_r[i] + p->prev_lsf_r[i] * pred_fac[i]) * (LSF_R_FAC / 8000.0) + lsf_3_mean[i] * (1.0 / 8000.0);
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
353
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
354 ff_set_min_dist_lsf(lsf_q, MIN_LSF_SPACING, LP_FILTER_ORDER);
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
355
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
356 // store data for computing the next frame's LSFs
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
357 interpolate_lsf(p->lsf_q, lsf_q);
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
358 memcpy(p->prev_lsf_r, lsf_r, LP_FILTER_ORDER * sizeof(*lsf_r));
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
359
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
360 lsf2lsp(lsf_q, p->lsp[3]);
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
361
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
362 // interpolate LSP vectors at subframes 1, 2 and 3
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
363 for (i = 1; i <= 3; i++)
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
364 for(j = 0; j < LP_FILTER_ORDER; j++)
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
365 p->lsp[i-1][j] = p->prev_lsp_sub4[j] +
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
366 (p->lsp[3][j] - p->prev_lsp_sub4[j]) * 0.25 * i;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
367 }
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
368
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
369 /// @}
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
370
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
371
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
372 /// @defgroup amr_pitch_vector_decoding AMR pitch vector decoding functions
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
373 /// @{
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
374
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
375 /**
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
376 * Like ff_decode_pitch_lag(), but with 1/6 resolution
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
377 */
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
378 static void decode_pitch_lag_1_6(int *lag_int, int *lag_frac, int pitch_index,
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
379 const int prev_lag_int, const int subframe)
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
380 {
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
381 if (subframe == 0 || subframe == 2) {
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
382 if (pitch_index < 463) {
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
383 *lag_int = (pitch_index + 107) * 10923 >> 16;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
384 *lag_frac = pitch_index - *lag_int * 6 + 105;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
385 } else {
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
386 *lag_int = pitch_index - 368;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
387 *lag_frac = 0;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
388 }
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
389 } else {
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
390 *lag_int = ((pitch_index + 5) * 10923 >> 16) - 1;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
391 *lag_frac = pitch_index - *lag_int * 6 - 3;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
392 *lag_int += av_clip(prev_lag_int - 5, PITCH_LAG_MIN_MODE_12k2,
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
393 PITCH_DELAY_MAX - 9);
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
394 }
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
395 }
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
396
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
397 static void decode_pitch_vector(AMRContext *p,
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
398 const AMRNBSubframe *amr_subframe,
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
399 const int subframe)
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
400 {
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
401 int pitch_lag_int, pitch_lag_frac;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
402 enum Mode mode = p->cur_frame_mode;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
403
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
404 if (p->cur_frame_mode == MODE_12k2) {
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
405 decode_pitch_lag_1_6(&pitch_lag_int, &pitch_lag_frac,
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
406 amr_subframe->p_lag, p->pitch_lag_int,
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
407 subframe);
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
408 } else
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
409 ff_decode_pitch_lag(&pitch_lag_int, &pitch_lag_frac,
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
410 amr_subframe->p_lag,
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
411 p->pitch_lag_int, subframe,
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
412 mode != MODE_4k75 && mode != MODE_5k15,
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
413 mode <= MODE_6k7 ? 4 : (mode == MODE_7k95 ? 5 : 6));
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
414
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
415 p->pitch_lag_int = pitch_lag_int; // store previous lag in a uint8_t
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
416
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
417 pitch_lag_frac <<= (p->cur_frame_mode != MODE_12k2);
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
418
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
419 pitch_lag_int += pitch_lag_frac > 0;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
420
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
421 /* Calculate the pitch vector by interpolating the past excitation at the
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
422 pitch lag using a b60 hamming windowed sinc function. */
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
423 ff_acelp_interpolatef(p->excitation, p->excitation + 1 - pitch_lag_int,
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
424 ff_b60_sinc, 6,
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
425 pitch_lag_frac + 6 - 6*(pitch_lag_frac > 0),
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
426 10, AMR_SUBFRAME_SIZE);
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
427
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
428 memcpy(p->pitch_vector, p->excitation, AMR_SUBFRAME_SIZE * sizeof(float));
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
429 }
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
430
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
431 /// @}
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
432
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
433
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
434 /// @defgroup amr_algebraic_code_book AMR algebraic code book (fixed) vector decoding functions
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
435 /// @{
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
436
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
437 /**
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
438 * Decode a 10-bit algebraic codebook index from a 10.2 kbit/s frame.
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
439 */
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
440 static void decode_10bit_pulse(int code, int pulse_position[8],
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
441 int i1, int i2, int i3)
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
442 {
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
443 // coded using 7+3 bits with the 3 LSBs being, individually, the LSB of 1 of
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
444 // the 3 pulses and the upper 7 bits being coded in base 5
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
445 const uint8_t *positions = base_five_table[code >> 3];
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
446 pulse_position[i1] = (positions[2] << 1) + ( code & 1);
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
447 pulse_position[i2] = (positions[1] << 1) + ((code >> 1) & 1);
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
448 pulse_position[i3] = (positions[0] << 1) + ((code >> 2) & 1);
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
449 }
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
450
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
451 /**
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
452 * Decode the algebraic codebook index to pulse positions and signs and
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
453 * construct the algebraic codebook vector for MODE_10k2.
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
454 *
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
455 * @param fixed_index positions of the eight pulses
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
456 * @param fixed_sparse pointer to the algebraic codebook vector
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
457 */
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
458 static void decode_8_pulses_31bits(const int16_t *fixed_index,
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
459 AMRFixed *fixed_sparse)
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
460 {
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
461 int pulse_position[8];
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
462 int i, temp;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
463
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
464 decode_10bit_pulse(fixed_index[4], pulse_position, 0, 4, 1);
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
465 decode_10bit_pulse(fixed_index[5], pulse_position, 2, 6, 5);
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
466
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
467 // coded using 5+2 bits with the 2 LSBs being, individually, the LSB of 1 of
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
468 // the 2 pulses and the upper 5 bits being coded in base 5
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
469 temp = ((fixed_index[6] >> 2) * 25 + 12) >> 5;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
470 pulse_position[3] = temp % 5;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
471 pulse_position[7] = temp / 5;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
472 if (pulse_position[7] & 1)
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
473 pulse_position[3] = 4 - pulse_position[3];
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
474 pulse_position[3] = (pulse_position[3] << 1) + ( fixed_index[6] & 1);
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
475 pulse_position[7] = (pulse_position[7] << 1) + ((fixed_index[6] >> 1) & 1);
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
476
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
477 fixed_sparse->n = 8;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
478 for (i = 0; i < 4; i++) {
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
479 const int pos1 = (pulse_position[i] << 2) + i;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
480 const int pos2 = (pulse_position[i + 4] << 2) + i;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
481 const float sign = fixed_index[i] ? -1.0 : 1.0;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
482 fixed_sparse->x[i ] = pos1;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
483 fixed_sparse->x[i + 4] = pos2;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
484 fixed_sparse->y[i ] = sign;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
485 fixed_sparse->y[i + 4] = pos2 < pos1 ? -sign : sign;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
486 }
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
487 }
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
488
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
489 /**
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
490 * Decode the algebraic codebook index to pulse positions and signs,
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
491 * then construct the algebraic codebook vector.
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
492 *
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
493 * nb of pulses | bits encoding pulses
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
494 * For MODE_4k75 or MODE_5k15, 2 | 1-3, 4-6, 7
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
495 * MODE_5k9, 2 | 1, 2-4, 5-6, 7-9
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
496 * MODE_6k7, 3 | 1-3, 4, 5-7, 8, 9-11
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
497 * MODE_7k4 or MODE_7k95, 4 | 1-3, 4-6, 7-9, 10, 11-13
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
498 *
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
499 * @param fixed_sparse pointer to the algebraic codebook vector
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
500 * @param pulses algebraic codebook indexes
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
501 * @param mode mode of the current frame
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
502 * @param subframe current subframe number
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
503 */
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
504 static void decode_fixed_sparse(AMRFixed *fixed_sparse, const uint16_t *pulses,
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
505 const enum Mode mode, const int subframe)
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
506 {
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
507 assert(MODE_4k75 <= mode && mode <= MODE_12k2);
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
508
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
509 if (mode == MODE_12k2) {
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
510 ff_decode_10_pulses_35bits(pulses, fixed_sparse, gray_decode, 5, 3);
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
511 } else if (mode == MODE_10k2) {
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
512 decode_8_pulses_31bits(pulses, fixed_sparse);
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
513 } else {
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
514 int *pulse_position = fixed_sparse->x;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
515 int i, pulse_subset;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
516 const int fixed_index = pulses[0];
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
517
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
518 if (mode <= MODE_5k15) {
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
519 pulse_subset = ((fixed_index >> 3) & 8) + (subframe << 1);
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
520 pulse_position[0] = ( fixed_index & 7) * 5 + track_position[pulse_subset];
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
521 pulse_position[1] = ((fixed_index >> 3) & 7) * 5 + track_position[pulse_subset + 1];
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
522 fixed_sparse->n = 2;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
523 } else if (mode == MODE_5k9) {
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
524 pulse_subset = ((fixed_index & 1) << 1) + 1;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
525 pulse_position[0] = ((fixed_index >> 1) & 7) * 5 + pulse_subset;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
526 pulse_subset = (fixed_index >> 4) & 3;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
527 pulse_position[1] = ((fixed_index >> 6) & 7) * 5 + pulse_subset + (pulse_subset == 3 ? 1 : 0);
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
528 fixed_sparse->n = pulse_position[0] == pulse_position[1] ? 1 : 2;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
529 } else if (mode == MODE_6k7) {
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
530 pulse_position[0] = (fixed_index & 7) * 5;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
531 pulse_subset = (fixed_index >> 2) & 2;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
532 pulse_position[1] = ((fixed_index >> 4) & 7) * 5 + pulse_subset + 1;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
533 pulse_subset = (fixed_index >> 6) & 2;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
534 pulse_position[2] = ((fixed_index >> 8) & 7) * 5 + pulse_subset + 2;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
535 fixed_sparse->n = 3;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
536 } else { // mode <= MODE_7k95
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
537 pulse_position[0] = gray_decode[ fixed_index & 7];
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
538 pulse_position[1] = gray_decode[(fixed_index >> 3) & 7] + 1;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
539 pulse_position[2] = gray_decode[(fixed_index >> 6) & 7] + 2;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
540 pulse_subset = (fixed_index >> 9) & 1;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
541 pulse_position[3] = gray_decode[(fixed_index >> 10) & 7] + pulse_subset + 3;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
542 fixed_sparse->n = 4;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
543 }
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
544 for (i = 0; i < fixed_sparse->n; i++)
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
545 fixed_sparse->y[i] = (pulses[1] >> i) & 1 ? 1.0 : -1.0;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
546 }
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
547 }
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
548
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
549 /**
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
550 * Apply pitch lag to obtain the sharpened fixed vector (section 6.1.2)
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
551 *
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
552 * @param p the context
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
553 * @param subframe unpacked amr subframe
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
554 * @param mode mode of the current frame
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
555 * @param fixed_sparse sparse respresentation of the fixed vector
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
556 */
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
557 static void pitch_sharpening(AMRContext *p, int subframe, enum Mode mode,
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
558 AMRFixed *fixed_sparse)
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
559 {
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
560 // The spec suggests the current pitch gain is always used, but in other
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
561 // modes the pitch and codebook gains are joinly quantized (sec 5.8.2)
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
562 // so the codebook gain cannot depend on the quantized pitch gain.
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
563 if (mode == MODE_12k2)
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
564 p->beta = FFMIN(p->pitch_gain[4], 1.0);
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
565
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
566 fixed_sparse->pitch_lag = p->pitch_lag_int;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
567 fixed_sparse->pitch_fac = p->beta;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
568
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
569 // Save pitch sharpening factor for the next subframe
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
570 // MODE_4k75 only updates on the 2nd and 4th subframes - this follows from
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
571 // the fact that the gains for two subframes are jointly quantized.
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
572 if (mode != MODE_4k75 || subframe & 1)
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
573 p->beta = av_clipf(p->pitch_gain[4], 0.0, SHARP_MAX);
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
574 }
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
575 /// @}
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
576
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
577
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
578 /// @defgroup amr_gain_decoding AMR gain decoding functions
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
579 /// @{
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
580
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
581 /**
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
582 * fixed gain smoothing
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
583 * Note that where the spec specifies the "spectrum in the q domain"
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
584 * in section 6.1.4, in fact frequencies should be used.
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
585 *
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
586 * @param p the context
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
587 * @param lsf LSFs for the current subframe, in the range [0,1]
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
588 * @param lsf_avg averaged LSFs
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
589 * @param mode mode of the current frame
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
590 *
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
591 * @return fixed gain smoothed
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
592 */
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
593 static float fixed_gain_smooth(AMRContext *p , const float *lsf,
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
594 const float *lsf_avg, const enum Mode mode)
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
595 {
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
596 float diff = 0.0;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
597 int i;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
598
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
599 for (i = 0; i < LP_FILTER_ORDER; i++)
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
600 diff += fabs(lsf_avg[i] - lsf[i]) / lsf_avg[i];
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
601
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
602 // If diff is large for ten subframes, disable smoothing for a 40-subframe
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
603 // hangover period.
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
604 p->diff_count++;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
605 if (diff <= 0.65)
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
606 p->diff_count = 0;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
607
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
608 if (p->diff_count > 10) {
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
609 p->hang_count = 0;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
610 p->diff_count--; // don't let diff_count overflow
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
611 }
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
612
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
613 if (p->hang_count < 40) {
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
614 p->hang_count++;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
615 } else if (mode < MODE_7k4 || mode == MODE_10k2) {
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
616 const float smoothing_factor = av_clipf(4.0 * diff - 1.6, 0.0, 1.0);
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
617 const float fixed_gain_mean = (p->fixed_gain[0] + p->fixed_gain[1] +
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
618 p->fixed_gain[2] + p->fixed_gain[3] +
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
619 p->fixed_gain[4]) * 0.2;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
620 return smoothing_factor * p->fixed_gain[4] +
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
621 (1.0 - smoothing_factor) * fixed_gain_mean;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
622 }
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
623 return p->fixed_gain[4];
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
624 }
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
625
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
626 /**
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
627 * Decode pitch gain and fixed gain factor (part of section 6.1.3).
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
628 *
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
629 * @param p the context
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
630 * @param amr_subframe unpacked amr subframe
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
631 * @param mode mode of the current frame
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
632 * @param subframe current subframe number
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
633 * @param fixed_gain_factor decoded gain correction factor
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
634 */
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
635 static void decode_gains(AMRContext *p, const AMRNBSubframe *amr_subframe,
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
636 const enum Mode mode, const int subframe,
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
637 float *fixed_gain_factor)
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
638 {
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
639 if (mode == MODE_12k2 || mode == MODE_7k95) {
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
640 p->pitch_gain[4] = qua_gain_pit [amr_subframe->p_gain ]
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
641 * (1.0 / 16384.0);
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
642 *fixed_gain_factor = qua_gain_code[amr_subframe->fixed_gain]
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
643 * (1.0 / 2048.0);
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
644 } else {
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
645 const uint16_t *gains;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
646
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
647 if (mode >= MODE_6k7) {
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
648 gains = gains_high[amr_subframe->p_gain];
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
649 } else if (mode >= MODE_5k15) {
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
650 gains = gains_low [amr_subframe->p_gain];
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
651 } else {
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
652 // gain index is only coded in subframes 0,2 for MODE_4k75
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
653 gains = gains_MODE_4k75[(p->frame.subframe[subframe & 2].p_gain << 1) + (subframe & 1)];
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
654 }
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
655
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
656 p->pitch_gain[4] = gains[0] * (1.0 / 16384.0);
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
657 *fixed_gain_factor = gains[1] * (1.0 / 4096.0);
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
658 }
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
659 }
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
660
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
661 /// @}
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
662
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
663
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
664 /// @defgroup amr_pre_processing AMR pre-processing functions
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
665 /// @{
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
666
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
667 /**
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
668 * Circularly convolve a sparse fixed vector with a phase dispersion impulse
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
669 * response filter (D.6.2 of G.729 and 6.1.5 of AMR).
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
670 *
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
671 * @param out vector with filter applied
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
672 * @param in source vector
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
673 * @param filter phase filter coefficients
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
674 *
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
675 * out[n] = sum(i,0,len-1){ in[i] * filter[(len + n - i)%len] }
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
676 */
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
677 static void apply_ir_filter(float *out, const AMRFixed *in,
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
678 const float *filter)
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
679 {
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
680 float filter1[AMR_SUBFRAME_SIZE], //!< filters at pitch lag*1 and *2
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
681 filter2[AMR_SUBFRAME_SIZE];
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
682 int lag = in->pitch_lag;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
683 float fac = in->pitch_fac;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
684 int i;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
685
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
686 if (lag < AMR_SUBFRAME_SIZE) {
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
687 ff_celp_circ_addf(filter1, filter, filter, lag, fac,
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
688 AMR_SUBFRAME_SIZE);
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
689
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
690 if (lag < AMR_SUBFRAME_SIZE >> 1)
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
691 ff_celp_circ_addf(filter2, filter, filter1, lag, fac,
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
692 AMR_SUBFRAME_SIZE);
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
693 }
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
694
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
695 memset(out, 0, sizeof(float) * AMR_SUBFRAME_SIZE);
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
696 for (i = 0; i < in->n; i++) {
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
697 int x = in->x[i];
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
698 float y = in->y[i];
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
699 const float *filterp;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
700
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
701 if (x >= AMR_SUBFRAME_SIZE - lag) {
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
702 filterp = filter;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
703 } else if (x >= AMR_SUBFRAME_SIZE - (lag << 1)) {
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
704 filterp = filter1;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
705 } else
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
706 filterp = filter2;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
707
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
708 ff_celp_circ_addf(out, out, filterp, x, y, AMR_SUBFRAME_SIZE);
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
709 }
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
710 }
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
711
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
712 /**
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
713 * Reduce fixed vector sparseness by smoothing with one of three IR filters.
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
714 * Also know as "adaptive phase dispersion".
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
715 *
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
716 * This implements 3GPP TS 26.090 section 6.1(5).
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
717 *
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
718 * @param p the context
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
719 * @param fixed_sparse algebraic codebook vector
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
720 * @param fixed_vector unfiltered fixed vector
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
721 * @param fixed_gain smoothed gain
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
722 * @param out space for modified vector if necessary
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
723 */
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
724 static const float *anti_sparseness(AMRContext *p, AMRFixed *fixed_sparse,
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
725 const float *fixed_vector,
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
726 float fixed_gain, float *out)
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
727 {
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
728 int ir_filter_nr;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
729
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
730 if (p->pitch_gain[4] < 0.6) {
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
731 ir_filter_nr = 0; // strong filtering
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
732 } else if (p->pitch_gain[4] < 0.9) {
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
733 ir_filter_nr = 1; // medium filtering
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
734 } else
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
735 ir_filter_nr = 2; // no filtering
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
736
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
737 // detect 'onset'
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
738 if (fixed_gain > 2.0 * p->prev_sparse_fixed_gain) {
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
739 p->ir_filter_onset = 2;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
740 } else if (p->ir_filter_onset)
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
741 p->ir_filter_onset--;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
742
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
743 if (!p->ir_filter_onset) {
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
744 int i, count = 0;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
745
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
746 for (i = 0; i < 5; i++)
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
747 if (p->pitch_gain[i] < 0.6)
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
748 count++;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
749 if (count > 2)
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
750 ir_filter_nr = 0;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
751
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
752 if (ir_filter_nr > p->prev_ir_filter_nr + 1)
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
753 ir_filter_nr--;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
754 } else if (ir_filter_nr < 2)
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
755 ir_filter_nr++;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
756
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
757 // Disable filtering for very low level of fixed_gain.
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
758 // Note this step is not specified in the technical description but is in
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
759 // the reference source in the function Ph_disp.
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
760 if (fixed_gain < 5.0)
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
761 ir_filter_nr = 2;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
762
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
763 if (p->cur_frame_mode != MODE_7k4 && p->cur_frame_mode < MODE_10k2
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
764 && ir_filter_nr < 2) {
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
765 apply_ir_filter(out, fixed_sparse,
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
766 (p->cur_frame_mode == MODE_7k95 ?
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
767 ir_filters_lookup_MODE_7k95 :
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
768 ir_filters_lookup)[ir_filter_nr]);
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
769 fixed_vector = out;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
770 }
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
771
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
772 // update ir filter strength history
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
773 p->prev_ir_filter_nr = ir_filter_nr;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
774 p->prev_sparse_fixed_gain = fixed_gain;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
775
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
776 return fixed_vector;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
777 }
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
778
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
779 /// @}
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
780
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
781
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
782 /// @defgroup amr_synthesis AMR synthesis functions
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
783 /// @{
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
784
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
785 /**
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
786 * Conduct 10th order linear predictive coding synthesis.
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
787 *
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
788 * @param p pointer to the AMRContext
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
789 * @param lpc pointer to the LPC coefficients
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
790 * @param fixed_gain fixed codebook gain for synthesis
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
791 * @param fixed_vector algebraic codebook vector
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
792 * @param samples pointer to the output speech samples
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
793 * @param overflow 16-bit overflow flag
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
794 */
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
795 static int synthesis(AMRContext *p, float *lpc,
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
796 float fixed_gain, const float *fixed_vector,
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
797 float *samples, uint8_t overflow)
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
798 {
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
799 int i, overflow_temp = 0;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
800 float excitation[AMR_SUBFRAME_SIZE];
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
801
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
802 // if an overflow has been detected, the pitch vector is scaled down by a
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
803 // factor of 4
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
804 if (overflow)
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
805 for (i = 0; i < AMR_SUBFRAME_SIZE; i++)
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
806 p->pitch_vector[i] *= 0.25;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
807
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
808 ff_weighted_vector_sumf(excitation, p->pitch_vector, fixed_vector,
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
809 p->pitch_gain[4], fixed_gain, AMR_SUBFRAME_SIZE);
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
810
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
811 // emphasize pitch vector contribution
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
812 if (p->pitch_gain[4] > 0.5 && !overflow) {
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
813 float energy = ff_dot_productf(excitation, excitation,
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
814 AMR_SUBFRAME_SIZE);
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
815 float pitch_factor =
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
816 p->pitch_gain[4] *
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
817 (p->cur_frame_mode == MODE_12k2 ?
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
818 0.25 * FFMIN(p->pitch_gain[4], 1.0) :
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
819 0.5 * FFMIN(p->pitch_gain[4], SHARP_MAX));
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
820
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
821 for (i = 0; i < AMR_SUBFRAME_SIZE; i++)
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
822 excitation[i] += pitch_factor * p->pitch_vector[i];
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
823
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
824 ff_scale_vector_to_given_sum_of_squares(excitation, excitation, energy,
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
825 AMR_SUBFRAME_SIZE);
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
826 }
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
827
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
828 ff_celp_lp_synthesis_filterf(samples, lpc, excitation, AMR_SUBFRAME_SIZE,
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
829 LP_FILTER_ORDER);
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
830
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
831 // detect overflow
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
832 for (i = 0; i < AMR_SUBFRAME_SIZE; i++)
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
833 if (fabsf(samples[i]) > AMR_SAMPLE_BOUND) {
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
834 overflow_temp = 1;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
835 samples[i] = av_clipf(samples[i], -AMR_SAMPLE_BOUND,
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
836 AMR_SAMPLE_BOUND);
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
837 }
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
838
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
839 return overflow_temp;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
840 }
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
841
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
842 /// @}
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
843
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
844
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
845 /// @defgroup amr_update AMR update functions
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
846 /// @{
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
847
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
848 /**
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
849 * Update buffers and history at the end of decoding a subframe.
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
850 *
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
851 * @param p pointer to the AMRContext
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
852 */
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
853 static void update_state(AMRContext *p)
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
854 {
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
855 memcpy(p->prev_lsp_sub4, p->lsp[3], LP_FILTER_ORDER * sizeof(p->lsp[3][0]));
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
856
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
857 memmove(&p->excitation_buf[0], &p->excitation_buf[AMR_SUBFRAME_SIZE],
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
858 (PITCH_DELAY_MAX + LP_FILTER_ORDER + 1) * sizeof(float));
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
859
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
860 memmove(&p->pitch_gain[0], &p->pitch_gain[1], 4 * sizeof(float));
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
861 memmove(&p->fixed_gain[0], &p->fixed_gain[1], 4 * sizeof(float));
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
862
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
863 memmove(&p->samples_in[0], &p->samples_in[AMR_SUBFRAME_SIZE],
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
864 LP_FILTER_ORDER * sizeof(float));
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
865 }
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
866
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
867 /// @}
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
868
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
869
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
870 /// @defgroup amr_postproc AMR Post processing functions
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
871 /// @{
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
872
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
873 /**
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
874 * Get the tilt factor of a formant filter from its transfer function
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
875 *
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
876 * @param lpc_n LP_FILTER_ORDER coefficients of the numerator
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
877 * @param lpc_d LP_FILTER_ORDER coefficients of the denominator
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
878 */
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
879 static float tilt_factor(float *lpc_n, float *lpc_d)
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
880 {
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
881 float rh0, rh1; // autocorrelation at lag 0 and 1
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
882
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
883 // LP_FILTER_ORDER prior zeros are needed for ff_celp_lp_synthesis_filterf
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
884 float impulse_buffer[LP_FILTER_ORDER + AMR_TILT_RESPONSE] = { 0 };
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
885 float *hf = impulse_buffer + LP_FILTER_ORDER; // start of impulse response
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
886
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
887 hf[0] = 1.0;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
888 memcpy(hf + 1, lpc_n, sizeof(float) * LP_FILTER_ORDER);
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
889 ff_celp_lp_synthesis_filterf(hf, lpc_d, hf, AMR_TILT_RESPONSE,
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
890 LP_FILTER_ORDER);
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
891
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
892 rh0 = ff_dot_productf(hf, hf, AMR_TILT_RESPONSE);
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
893 rh1 = ff_dot_productf(hf, hf + 1, AMR_TILT_RESPONSE - 1);
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
894
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
895 // The spec only specifies this check for 12.2 and 10.2 kbit/s
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
896 // modes. But in the ref source the tilt is always non-negative.
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
897 return rh1 >= 0.0 ? rh1 / rh0 * AMR_TILT_GAMMA_T : 0.0;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
898 }
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
899
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
900 /**
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
901 * Perform adaptive post-filtering to enhance the quality of the speech.
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
902 * See section 6.2.1.
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
903 *
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
904 * @param p pointer to the AMRContext
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
905 * @param lpc interpolated LP coefficients for this subframe
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
906 * @param buf_out output of the filter
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
907 */
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
908 static void postfilter(AMRContext *p, float *lpc, float *buf_out)
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
909 {
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
910 int i;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
911 float *samples = p->samples_in + LP_FILTER_ORDER; // Start of input
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
912
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
913 float speech_gain = ff_dot_productf(samples, samples,
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
914 AMR_SUBFRAME_SIZE);
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
915
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
916 float pole_out[AMR_SUBFRAME_SIZE + LP_FILTER_ORDER]; // Output of pole filter
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
917 const float *gamma_n, *gamma_d; // Formant filter factor table
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
918 float lpc_n[LP_FILTER_ORDER], lpc_d[LP_FILTER_ORDER]; // Transfer function coefficients
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
919
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
920 if (p->cur_frame_mode == MODE_12k2 || p->cur_frame_mode == MODE_10k2) {
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
921 gamma_n = ff_pow_0_7;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
922 gamma_d = ff_pow_0_75;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
923 } else {
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
924 gamma_n = ff_pow_0_55;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
925 gamma_d = ff_pow_0_7;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
926 }
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
927
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
928 for (i = 0; i < LP_FILTER_ORDER; i++) {
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
929 lpc_n[i] = lpc[i] * gamma_n[i];
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
930 lpc_d[i] = lpc[i] * gamma_d[i];
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
931 }
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
932
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
933 memcpy(pole_out, p->postfilter_mem, sizeof(float) * LP_FILTER_ORDER);
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
934 ff_celp_lp_synthesis_filterf(pole_out + LP_FILTER_ORDER, lpc_d, samples,
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
935 AMR_SUBFRAME_SIZE, LP_FILTER_ORDER);
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
936 memcpy(p->postfilter_mem, pole_out + AMR_SUBFRAME_SIZE,
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
937 sizeof(float) * LP_FILTER_ORDER);
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
938
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
939 ff_celp_lp_zero_synthesis_filterf(buf_out, lpc_n,
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
940 pole_out + LP_FILTER_ORDER,
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
941 AMR_SUBFRAME_SIZE, LP_FILTER_ORDER);
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
942
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
943 ff_tilt_compensation(&p->tilt_mem, tilt_factor(lpc_n, lpc_d), buf_out,
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
944 AMR_SUBFRAME_SIZE);
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
945
11462
c2e19a511e26 Fix spelling.
rbultje
parents: 11235
diff changeset
946 ff_adaptive_gain_control(buf_out, speech_gain, AMR_SUBFRAME_SIZE,
c2e19a511e26 Fix spelling.
rbultje
parents: 11235
diff changeset
947 AMR_AGC_ALPHA, &p->postfilter_agc);
11235
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
948 }
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
949
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
950 /// @}
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
951
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
952 static int amrnb_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
953 AVPacket *avpkt)
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
954 {
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
955
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
956 AMRContext *p = avctx->priv_data; // pointer to private data
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
957 const uint8_t *buf = avpkt->data;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
958 int buf_size = avpkt->size;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
959 float *buf_out = data; // pointer to the output data buffer
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
960 int i, subframe;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
961 float fixed_gain_factor;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
962 AMRFixed fixed_sparse = {0}; // fixed vector up to anti-sparseness processing
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
963 float spare_vector[AMR_SUBFRAME_SIZE]; // extra stack space to hold result from anti-sparseness processing
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
964 float synth_fixed_gain; // the fixed gain that synthesis should use
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
965 const float *synth_fixed_vector; // pointer to the fixed vector that synthesis should use
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
966
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
967 p->cur_frame_mode = unpack_bitstream(p, buf, buf_size);
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
968 if (p->cur_frame_mode == MODE_DTX) {
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
969 av_log_missing_feature(avctx, "dtx mode", 1);
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
970 return -1;
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
971 }
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
972
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
973 if (p->cur_frame_mode == MODE_12k2) {
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
974 lsf2lsp_5(p);
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
975 } else
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
976 lsf2lsp_3(p);
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
977
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
978 for (i = 0; i < 4; i++)
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
979 ff_acelp_lspd2lpc(p->lsp[i], p->lpc[i], 5);
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
980
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
981 for (subframe = 0; subframe < 4; subframe++) {
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
982 const AMRNBSubframe *amr_subframe = &p->frame.subframe[subframe];
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
983
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
984 decode_pitch_vector(p, amr_subframe, subframe);
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
985
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
986 decode_fixed_sparse(&fixed_sparse, amr_subframe->pulses,
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
987 p->cur_frame_mode, subframe);
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
988
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
989 // The fixed gain (section 6.1.3) depends on the fixed vector
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
990 // (section 6.1.2), but the fixed vector calculation uses
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
991 // pitch sharpening based on the on the pitch gain (section 6.1.3).
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
992 // So the correct order is: pitch gain, pitch sharpening, fixed gain.
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
993 decode_gains(p, amr_subframe, p->cur_frame_mode, subframe,
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
994 &fixed_gain_factor);
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
995
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
996 pitch_sharpening(p, subframe, p->cur_frame_mode, &fixed_sparse);
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
997
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
998 ff_set_fixed_vector(p->fixed_vector, &fixed_sparse, 1.0,
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
999 AMR_SUBFRAME_SIZE);
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
1000
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
1001 p->fixed_gain[4] =
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
1002 ff_amr_set_fixed_gain(fixed_gain_factor,
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
1003 ff_dot_productf(p->fixed_vector, p->fixed_vector,
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
1004 AMR_SUBFRAME_SIZE)/AMR_SUBFRAME_SIZE,
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
1005 p->prediction_error,
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
1006 energy_mean[p->cur_frame_mode], energy_pred_fac);
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
1007
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
1008 // The excitation feedback is calculated without any processing such
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
1009 // as fixed gain smoothing. This isn't mentioned in the specification.
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
1010 for (i = 0; i < AMR_SUBFRAME_SIZE; i++)
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
1011 p->excitation[i] *= p->pitch_gain[4];
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
1012 ff_set_fixed_vector(p->excitation, &fixed_sparse, p->fixed_gain[4],
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
1013 AMR_SUBFRAME_SIZE);
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
1014
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
1015 // In the ref decoder, excitation is stored with no fractional bits.
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
1016 // This step prevents buzz in silent periods. The ref encoder can
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
1017 // emit long sequences with pitch factor greater than one. This
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
1018 // creates unwanted feedback if the excitation vector is nonzero.
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
1019 // (e.g. test sequence T19_795.COD in 3GPP TS 26.074)
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
1020 for (i = 0; i < AMR_SUBFRAME_SIZE; i++)
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
1021 p->excitation[i] = truncf(p->excitation[i]);
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
1022
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
1023 // Smooth fixed gain.
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
1024 // The specification is ambiguous, but in the reference source, the
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
1025 // smoothed value is NOT fed back into later fixed gain smoothing.
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
1026 synth_fixed_gain = fixed_gain_smooth(p, p->lsf_q[subframe],
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
1027 p->lsf_avg, p->cur_frame_mode);
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
1028
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
1029 synth_fixed_vector = anti_sparseness(p, &fixed_sparse, p->fixed_vector,
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
1030 synth_fixed_gain, spare_vector);
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
1031
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
1032 if (synthesis(p, p->lpc[subframe], synth_fixed_gain,
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
1033 synth_fixed_vector, &p->samples_in[LP_FILTER_ORDER], 0))
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
1034 // overflow detected -> rerun synthesis scaling pitch vector down
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
1035 // by a factor of 4, skipping pitch vector contribution emphasis
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
1036 // and adaptive gain control
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
1037 synthesis(p, p->lpc[subframe], synth_fixed_gain,
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
1038 synth_fixed_vector, &p->samples_in[LP_FILTER_ORDER], 1);
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
1039
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
1040 postfilter(p, p->lpc[subframe], buf_out + subframe * AMR_SUBFRAME_SIZE);
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
1041
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
1042 // update buffers and history
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
1043 ff_clear_fixed_vector(p->fixed_vector, &fixed_sparse, AMR_SUBFRAME_SIZE);
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
1044 update_state(p);
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
1045 }
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
1046
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
1047 ff_acelp_apply_order_2_transfer_function(buf_out, highpass_zeros,
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
1048 highpass_poles, highpass_gain,
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
1049 p->high_pass_mem, AMR_BLOCK_SIZE);
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
1050
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
1051 for (i = 0; i < AMR_BLOCK_SIZE; i++)
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
1052 buf_out[i] = av_clipf(buf_out[i] * AMR_SAMPLE_SCALE,
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
1053 -1.0, 32767.0 / 32768.0);
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
1054
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
1055 /* Update averaged lsf vector (used for fixed gain smoothing).
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
1056 *
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
1057 * Note that lsf_avg should not incorporate the current frame's LSFs
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
1058 * for fixed_gain_smooth.
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
1059 * The specification has an incorrect formula: the reference decoder uses
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
1060 * qbar(n-1) rather than qbar(n) in section 6.1(4) equation 71. */
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
1061 ff_weighted_vector_sumf(p->lsf_avg, p->lsf_avg, p->lsf_q[3],
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
1062 0.84, 0.16, LP_FILTER_ORDER);
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
1063
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
1064 /* report how many samples we got */
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
1065 *data_size = AMR_BLOCK_SIZE * sizeof(float);
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
1066
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
1067 /* return the amount of bytes consumed if everything was OK */
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
1068 return frame_sizes_nb[p->cur_frame_mode] + 1; // +7 for rounding and +8 for TOC
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
1069 }
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
1070
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
1071
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
1072 AVCodec amrnb_decoder = {
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
1073 .name = "amrnb",
11560
8a4984c5cacc Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents: 11462
diff changeset
1074 .type = AVMEDIA_TYPE_AUDIO,
11235
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
1075 .id = CODEC_ID_AMR_NB,
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
1076 .priv_data_size = sizeof(AMRContext),
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
1077 .init = amrnb_decode_init,
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
1078 .decode = amrnb_decode_frame,
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
1079 .long_name = NULL_IF_CONFIG_SMALL("Adaptive Multi-Rate NarrowBand"),
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
1080 .sample_fmts = (enum SampleFormat[]){SAMPLE_FMT_FLT,SAMPLE_FMT_NONE},
5c339e441ace AMR-NB floating-point based decoder.
vitor
parents:
diff changeset
1081 };