Mercurial > libavcodec.hg
comparison qcelpdec.c @ 8145:f27d01aff4af libavcodec
More OKed parts of the QCELP decoder
patch by Kenan Gillet, kenan.gillet gmail com
author | vitor |
---|---|
date | Fri, 14 Nov 2008 17:36:47 +0000 |
parents | 3b5256153553 |
children | 4da8fc62ae00 |
comparison
equal
deleted
inserted
replaced
8144:a0d64d63a131 | 8145:f27d01aff4af |
---|---|
47 int i; | 47 int i; |
48 | 48 |
49 for (i = 0; i < length; i++) | 49 for (i = 0; i < length; i++) |
50 out[i] = weight_coeff_a * in_a[i] | 50 out[i] = weight_coeff_a * in_a[i] |
51 + weight_coeff_b * in_b[i]; | 51 + weight_coeff_b * in_b[i]; |
52 } | |
53 | |
54 /** | |
55 * Initialize the speech codec according to the specification. | |
56 * | |
57 * TIA/EIA/IS-733 2.4.9 | |
58 */ | |
59 static av_cold int qcelp_decode_init(AVCodecContext *avctx) { | |
60 QCELPContext *q = avctx->priv_data; | |
61 int i; | |
62 | |
63 avctx->sample_fmt = SAMPLE_FMT_FLT; | |
64 | |
65 for (i = 0; i < 10; i++) | |
66 q->prev_lspf[i] = (i + 1) / 11.; | |
67 | |
68 return 0; | |
69 } | |
70 | |
71 /** | |
72 * Computes the scaled codebook vector Cdn From INDEX and GAIN | |
73 * for all rates. | |
74 * | |
75 * The specification lacks some information here. | |
76 * | |
77 * TIA/EIA/IS-733 has an omission on the codebook index determination | |
78 * formula for RATE_FULL and RATE_HALF frames at section 2.4.8.1.1. It says | |
79 * you have to subtract the decoded index parameter from the given scaled | |
80 * codebook vector index 'n' to get the desired circular codebook index, but | |
81 * it does not mention that you have to clamp 'n' to [0-9] in order to get | |
82 * RI-compliant results. | |
83 * | |
84 * The reason for this mistake seems to be the fact they forgot to mention you | |
85 * have to do these calculations per codebook subframe and adjust given | |
86 * equation values accordingly. | |
87 * | |
88 * @param q the context | |
89 * @param gain array holding the 4 pitch subframe gain values | |
90 * @param cdn_vector array for the generated scaled codebook vector | |
91 */ | |
92 static void compute_svector(const QCELPContext *q, | |
93 const float *gain, | |
94 float *cdn_vector) { | |
95 int i, j, k; | |
96 uint16_t cbseed, cindex; | |
97 float *rnd, tmp_gain, fir_filter_value; | |
98 | |
99 switch (q->framerate) { | |
100 case RATE_FULL: | |
101 for (i = 0; i < 16; i++) { | |
102 tmp_gain = gain[i] * QCELP_RATE_FULL_CODEBOOK_RATIO; | |
103 cindex = -q->cindex[i]; | |
104 for (j = 0; j < 10; j++) | |
105 *cdn_vector++ = tmp_gain * qcelp_rate_full_codebook[cindex++ & 127]; | |
106 } | |
107 break; | |
108 case RATE_HALF: | |
109 for (i = 0; i < 4; i++) { | |
110 tmp_gain = gain[i] * QCELP_RATE_HALF_CODEBOOK_RATIO; | |
111 cindex = -q->cindex[i]; | |
112 for (j = 0; j < 40; j++) | |
113 *cdn_vector++ = tmp_gain * qcelp_rate_half_codebook[cindex++ & 127]; | |
114 } | |
115 break; | |
116 case RATE_QUARTER: | |
117 cbseed = (0x0003 & q->lspv[4])<<14 | | |
118 (0x003F & q->lspv[3])<< 8 | | |
119 (0x0060 & q->lspv[2])<< 1 | | |
120 (0x0007 & q->lspv[1])<< 3 | | |
121 (0x0038 & q->lspv[0])>> 3 ; | |
122 rnd = q->rnd_fir_filter_mem + 20; | |
123 for (i = 0; i < 8; i++) { | |
124 tmp_gain = gain[i] * (QCELP_SQRT1887 / 32768.0); | |
125 for (k = 0; k < 20; k++) { | |
126 cbseed = 521 * cbseed + 259; | |
127 *rnd = (int16_t)cbseed; | |
128 | |
129 // FIR filter | |
130 fir_filter_value = 0.0; | |
131 for (j = 0; j < 10; j++) | |
132 fir_filter_value += qcelp_rnd_fir_coefs[j ] * (rnd[-j ] + rnd[-20+j]); | |
133 fir_filter_value += qcelp_rnd_fir_coefs[10] * rnd[-10]; | |
134 | |
135 *cdn_vector++ = tmp_gain * fir_filter_value; | |
136 rnd++; | |
137 } | |
138 } | |
139 memcpy(q->rnd_fir_filter_mem, q->rnd_fir_filter_mem + 160, 20 * sizeof(float)); | |
140 break; | |
141 case RATE_OCTAVE: | |
142 cbseed = q->first16bits; | |
143 for (i = 0; i < 8; i++) { | |
144 tmp_gain = gain[i] * (QCELP_SQRT1887 / 32768.0); | |
145 for (j = 0; j < 20; j++) { | |
146 cbseed = 521 * cbseed + 259; | |
147 *cdn_vector++ = tmp_gain * (int16_t)cbseed; | |
148 } | |
149 } | |
150 break; | |
151 case I_F_Q: | |
152 cbseed = -44; // random codebook index | |
153 for (i = 0; i < 4; i++) { | |
154 tmp_gain = gain[i] * QCELP_RATE_FULL_CODEBOOK_RATIO; | |
155 for (j = 0; j < 40; j++) | |
156 *cdn_vector++ = tmp_gain * qcelp_rate_full_codebook[cbseed++ & 127]; | |
157 } | |
158 break; | |
159 } | |
160 } | |
161 | |
162 /** | |
163 * Apply generic gain control. | |
164 * | |
165 * @param v_out output vector | |
166 * @param v_in gain-controlled vector | |
167 * @param v_ref vector to control gain of | |
168 * | |
169 * FIXME: If v_ref is a zero vector, it energy is zero | |
170 * and the behavior of the gain control is | |
171 * undefined in the specs. | |
172 * | |
173 * TIA/EIA/IS-733 2.4.8.3-2/3/4/5, 2.4.8.6 | |
174 */ | |
175 static void apply_gain_ctrl(float *v_out, | |
176 const float *v_ref, | |
177 const float *v_in) { | |
178 int i, j, len; | |
179 float scalefactor; | |
180 | |
181 for (i = 0, j = 0; i < 4; i++) { | |
182 scalefactor = ff_dot_productf(v_in + j, v_in + j, 40); | |
183 if (scalefactor) | |
184 scalefactor = sqrt(ff_dot_productf(v_ref + j, v_ref + j, 40) / scalefactor); | |
185 else | |
186 av_log_missing_feature(NULL, "Zero energy for gain control", 1); | |
187 for (len = j + 40; j < len; j++) | |
188 v_out[j] = scalefactor * v_in[j]; | |
189 } | |
52 } | 190 } |
53 | 191 |
54 /** | 192 /** |
55 * Apply filter in pitch-subframe steps. | 193 * Apply filter in pitch-subframe steps. |
56 * | 194 * |
129 weight = 1.0; | 267 weight = 1.0; |
130 } | 268 } |
131 | 269 |
132 if (weight != 1.0) { | 270 if (weight != 1.0) { |
133 weighted_vector_sumf(interpolated_lspf, curr_lspf, q->prev_lspf, weight, 1.0 - weight, 10); | 271 weighted_vector_sumf(interpolated_lspf, curr_lspf, q->prev_lspf, weight, 1.0 - weight, 10); |
134 lspf2lpc(q, interpolated_lspf, lpc); | 272 qcelp_lspf2lpc(interpolated_lspf, lpc); |
135 } else if (q->framerate >= RATE_QUARTER || (q->framerate == I_F_Q && !subframe_num)) | 273 } else if (q->framerate >= RATE_QUARTER || (q->framerate == I_F_Q && !subframe_num)) |
136 lspf2lpc(q, curr_lspf, lpc); | 274 qcelp_lspf2lpc(curr_lspf, lpc); |
137 } | 275 } |
138 | 276 |
139 static int buf_size2framerate(const int buf_size) { | 277 static int buf_size2framerate(const int buf_size) { |
140 switch (buf_size) { | 278 switch (buf_size) { |
141 case 35: | 279 case 35: |