Mercurial > libavcodec.hg
annotate sipr16k.c @ 12266:48d6738904a9 libavcodec
Fix SPLATB_REG mess. Used to be a if/elseif/elseif/elseif spaghetti, so this
splits it into small optimization-specific macros which are selected for each
DSP function. The advantage of this approach is that the sse4 functions now
use the ssse3 codepath also without needing an explicit sse4 codepath.
author | rbultje |
---|---|
date | Sat, 24 Jul 2010 19:33:05 +0000 |
parents | 8b6f3d3b55cb |
children |
rev | line source |
---|---|
10891 | 1 /* |
2 * SIPR decoder for the 16k mode | |
3 * | |
4 * Copyright (c) 2008 Vladimir Voroshilov | |
5 * Copyright (c) 2009 Vitor Sessak | |
6 * | |
7 * This file is part of FFmpeg. | |
8 * | |
9 * FFmpeg is free software; you can redistribute it and/or | |
10 * modify it under the terms of the GNU Lesser General Public | |
11 * License as published by the Free Software Foundation; either | |
12 * version 2.1 of the License, or (at your option) any later version. | |
13 * | |
14 * FFmpeg is distributed in the hope that it will be useful, | |
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
17 * Lesser General Public License for more details. | |
18 * | |
19 * You should have received a copy of the GNU Lesser General Public | |
20 * License along with FFmpeg; if not, write to the Free Software | |
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
22 */ | |
23 | |
24 #include <math.h> | |
25 | |
26 #include "sipr.h" | |
27 #include "libavutil/mathematics.h" | |
28 #include "lsp.h" | |
29 #include "celp_math.h" | |
30 #include "acelp_vectors.h" | |
31 #include "acelp_pitch_delay.h" | |
32 #include "acelp_filters.h" | |
33 #include "celp_filters.h" | |
34 | |
35 #include "sipr16kdata.h" | |
36 | |
37 /** | |
38 * Convert an lsf vector into an lsp vector. | |
39 * | |
40 * @param lsf input lsf vector | |
41 * @param lsp output lsp vector | |
42 */ | |
43 static void lsf2lsp(const float *lsf, double *lsp) | |
44 { | |
45 int i; | |
46 | |
47 for (i = 0; i < LP_FILTER_ORDER_16k; i++) | |
48 lsp[i] = cosf(lsf[i]); | |
49 } | |
50 | |
51 static void dequant(float *out, const int *idx, const float *cbs[]) | |
52 { | |
53 int i; | |
54 | |
55 for (i = 0; i < 4; i++) | |
56 memcpy(out + 3*i, cbs[i] + 3*idx[i], 3*sizeof(float)); | |
57 | |
58 memcpy(out + 12, cbs[4] + 4*idx[4], 4*sizeof(float)); | |
59 } | |
60 | |
61 static void lsf_decode_fp_16k(float* lsf_history, float* isp_new, | |
62 const int* parm, int ma_pred) | |
63 { | |
64 int i; | |
65 float isp_q[LP_FILTER_ORDER_16k]; | |
66 | |
67 dequant(isp_q, parm, lsf_codebooks_16k); | |
68 | |
69 for (i = 0; i < LP_FILTER_ORDER_16k; i++) { | |
70 isp_new[i] = (1 - qu[ma_pred]) * isp_q[i] | |
71 + qu[ma_pred] * lsf_history[i] | |
72 + mean_lsf_16k[i]; | |
73 } | |
74 | |
75 memcpy(lsf_history, isp_q, LP_FILTER_ORDER_16k * sizeof(float)); | |
76 } | |
77 | |
78 static int dec_delay3_1st(int index) | |
79 { | |
80 if (index < 390) { | |
81 return index + 88; | |
82 } else | |
83 return 3 * index - 690; | |
84 } | |
85 | |
86 static int dec_delay3_2nd(int index, int pit_min, int pit_max, | |
87 int pitch_lag_prev) | |
88 { | |
89 if (index < 62) { | |
90 int pitch_delay_min = av_clip(pitch_lag_prev - 10, | |
91 pit_min, pit_max - 19); | |
92 return 3 * pitch_delay_min + index - 2; | |
93 } else | |
94 return 3 * pitch_lag_prev; | |
95 } | |
96 | |
11649
e4e4fce64e5d
Make the Sipr16k postfilter function write data into the target/output buffer.
rbultje
parents:
10891
diff
changeset
|
97 static void postfilter(float *out_data, float* synth, float* iir_mem, |
e4e4fce64e5d
Make the Sipr16k postfilter function write data into the target/output buffer.
rbultje
parents:
10891
diff
changeset
|
98 float* filt_mem[2], float* mem_preemph) |
10891 | 99 { |
100 float buf[30 + LP_FILTER_ORDER_16k]; | |
101 float *tmpbuf = buf + LP_FILTER_ORDER_16k; | |
102 float s; | |
103 int i; | |
104 | |
105 for (i = 0; i < LP_FILTER_ORDER_16k; i++) | |
106 filt_mem[0][i] = iir_mem[i] * ff_pow_0_5[i]; | |
107 | |
108 memcpy(tmpbuf - LP_FILTER_ORDER_16k, mem_preemph, | |
109 LP_FILTER_ORDER_16k*sizeof(*buf)); | |
110 | |
111 ff_celp_lp_synthesis_filterf(tmpbuf, filt_mem[1], synth, 30, | |
112 LP_FILTER_ORDER_16k); | |
113 | |
114 memcpy(synth - LP_FILTER_ORDER_16k, mem_preemph, | |
115 LP_FILTER_ORDER_16k * sizeof(*synth)); | |
116 | |
11649
e4e4fce64e5d
Make the Sipr16k postfilter function write data into the target/output buffer.
rbultje
parents:
10891
diff
changeset
|
117 ff_celp_lp_synthesis_filterf(synth, filt_mem[0], synth, 30, |
10891 | 118 LP_FILTER_ORDER_16k); |
119 | |
11649
e4e4fce64e5d
Make the Sipr16k postfilter function write data into the target/output buffer.
rbultje
parents:
10891
diff
changeset
|
120 memcpy(out_data + 30 - LP_FILTER_ORDER_16k, |
e4e4fce64e5d
Make the Sipr16k postfilter function write data into the target/output buffer.
rbultje
parents:
10891
diff
changeset
|
121 synth + 30 - LP_FILTER_ORDER_16k, |
e4e4fce64e5d
Make the Sipr16k postfilter function write data into the target/output buffer.
rbultje
parents:
10891
diff
changeset
|
122 LP_FILTER_ORDER_16k * sizeof(*synth)); |
e4e4fce64e5d
Make the Sipr16k postfilter function write data into the target/output buffer.
rbultje
parents:
10891
diff
changeset
|
123 |
e4e4fce64e5d
Make the Sipr16k postfilter function write data into the target/output buffer.
rbultje
parents:
10891
diff
changeset
|
124 ff_celp_lp_synthesis_filterf(out_data + 30, filt_mem[0], |
e4e4fce64e5d
Make the Sipr16k postfilter function write data into the target/output buffer.
rbultje
parents:
10891
diff
changeset
|
125 synth + 30, 2 * L_SUBFR_16k - 30, |
e4e4fce64e5d
Make the Sipr16k postfilter function write data into the target/output buffer.
rbultje
parents:
10891
diff
changeset
|
126 LP_FILTER_ORDER_16k); |
e4e4fce64e5d
Make the Sipr16k postfilter function write data into the target/output buffer.
rbultje
parents:
10891
diff
changeset
|
127 |
e4e4fce64e5d
Make the Sipr16k postfilter function write data into the target/output buffer.
rbultje
parents:
10891
diff
changeset
|
128 |
e4e4fce64e5d
Make the Sipr16k postfilter function write data into the target/output buffer.
rbultje
parents:
10891
diff
changeset
|
129 memcpy(mem_preemph, out_data + 2*L_SUBFR_16k - LP_FILTER_ORDER_16k, |
10891 | 130 LP_FILTER_ORDER_16k * sizeof(*synth)); |
131 | |
132 FFSWAP(float *, filt_mem[0], filt_mem[1]); | |
133 for (i = 0, s = 0; i < 30; i++, s += 1.0/30) | |
11649
e4e4fce64e5d
Make the Sipr16k postfilter function write data into the target/output buffer.
rbultje
parents:
10891
diff
changeset
|
134 out_data[i] = tmpbuf[i] + s * (synth[i] - tmpbuf[i]); |
10891 | 135 } |
136 | |
137 /** | |
138 * Floating point version of ff_acelp_lp_decode(). | |
139 */ | |
140 static void acelp_lp_decodef(float *lp_1st, float *lp_2nd, | |
141 const double *lsp_2nd, const double *lsp_prev) | |
142 { | |
143 double lsp_1st[LP_FILTER_ORDER_16k]; | |
144 int i; | |
145 | |
146 /* LSP values for first subframe (3.2.5 of G.729, Equation 24) */ | |
147 for (i = 0; i < LP_FILTER_ORDER_16k; i++) | |
148 lsp_1st[i] = (lsp_2nd[i] + lsp_prev[i]) * 0.5; | |
149 | |
150 ff_acelp_lspd2lpc(lsp_1st, lp_1st, LP_FILTER_ORDER_16k >> 1); | |
151 | |
152 /* LSP values for second subframe (3.2.5 of G.729) */ | |
153 ff_acelp_lspd2lpc(lsp_2nd, lp_2nd, LP_FILTER_ORDER_16k >> 1); | |
154 } | |
155 | |
156 /** | |
157 * Floating point version of ff_acelp_decode_gain_code(). | |
158 */ | |
159 static float acelp_decode_gain_codef(float gain_corr_factor, const float *fc_v, | |
160 float mr_energy, const float *quant_energy, | |
161 const float *ma_prediction_coeff, | |
162 int subframe_size, int ma_pred_order) | |
163 { | |
164 mr_energy += | |
165 ff_dot_productf(quant_energy, ma_prediction_coeff, ma_pred_order); | |
166 | |
167 mr_energy = gain_corr_factor * exp(M_LN10 / 20. * mr_energy) / | |
168 sqrt((0.01 + ff_dot_productf(fc_v, fc_v, subframe_size))); | |
169 return mr_energy; | |
170 } | |
171 | |
172 #define DIVIDE_BY_3(x) ((x) * 10923 >> 15) | |
173 | |
174 void ff_sipr_decode_frame_16k(SiprContext *ctx, SiprParameters *params, | |
175 float *out_data) | |
176 { | |
177 int frame_size = SUBFRAME_COUNT_16k * L_SUBFR_16k; | |
178 float *synth = ctx->synth_buf + LP_FILTER_ORDER_16k; | |
179 float lsf_new[LP_FILTER_ORDER_16k]; | |
180 double lsp_new[LP_FILTER_ORDER_16k]; | |
181 float Az[2][LP_FILTER_ORDER_16k]; | |
182 float fixed_vector[L_SUBFR_16k]; | |
183 float pitch_fac, gain_code; | |
184 | |
185 int i; | |
186 int pitch_delay_3x; | |
187 | |
188 float *excitation = ctx->excitation + 292; | |
189 | |
190 lsf_decode_fp_16k(ctx->lsf_history, lsf_new, params->vq_indexes, | |
191 params->ma_pred_switch); | |
192 | |
193 ff_set_min_dist_lsf(lsf_new, LSFQ_DIFF_MIN / 2, LP_FILTER_ORDER_16k); | |
194 | |
195 lsf2lsp(lsf_new, lsp_new); | |
196 | |
197 acelp_lp_decodef(Az[0], Az[1], lsp_new, ctx->lsp_history_16k); | |
198 | |
199 memcpy(ctx->lsp_history_16k, lsp_new, LP_FILTER_ORDER_16k * sizeof(double)); | |
200 | |
201 memcpy(synth - LP_FILTER_ORDER_16k, ctx->synth, | |
202 LP_FILTER_ORDER_16k * sizeof(*synth)); | |
203 | |
204 for (i = 0; i < SUBFRAME_COUNT_16k; i++) { | |
205 int i_subfr = i * L_SUBFR_16k; | |
206 AMRFixed f; | |
207 float gain_corr_factor; | |
208 int pitch_delay_int; | |
209 int pitch_delay_frac; | |
210 | |
211 if (!i) { | |
212 pitch_delay_3x = dec_delay3_1st(params->pitch_delay[i]); | |
213 } else | |
214 pitch_delay_3x = dec_delay3_2nd(params->pitch_delay[i], | |
215 PITCH_MIN, PITCH_MAX, | |
216 ctx->pitch_lag_prev); | |
217 | |
218 pitch_fac = gain_pitch_cb_16k[params->gp_index[i]]; | |
219 f.pitch_fac = FFMIN(pitch_fac, 1.0); | |
220 f.pitch_lag = DIVIDE_BY_3(pitch_delay_3x+1); | |
221 ctx->pitch_lag_prev = f.pitch_lag; | |
222 | |
223 pitch_delay_int = DIVIDE_BY_3(pitch_delay_3x + 2); | |
224 pitch_delay_frac = pitch_delay_3x + 2 - 3*pitch_delay_int; | |
225 | |
226 ff_acelp_interpolatef(&excitation[i_subfr], | |
227 &excitation[i_subfr] - pitch_delay_int + 1, | |
228 sinc_win, 3, pitch_delay_frac + 1, | |
229 LP_FILTER_ORDER, L_SUBFR_16k); | |
230 | |
231 | |
232 memset(fixed_vector, 0, sizeof(fixed_vector)); | |
233 | |
234 ff_decode_10_pulses_35bits(params->fc_indexes[i], &f, | |
235 ff_fc_4pulses_8bits_tracks_13, 5, 4); | |
236 | |
237 ff_set_fixed_vector(fixed_vector, &f, 1.0, L_SUBFR_16k); | |
238 | |
239 gain_corr_factor = gain_cb_16k[params->gc_index[i]]; | |
240 gain_code = gain_corr_factor * | |
241 acelp_decode_gain_codef(sqrt(L_SUBFR_16k), fixed_vector, | |
242 19.0 - 15.0/(0.05*M_LN10/M_LN2), | |
243 pred_16k, ctx->energy_history, | |
244 L_SUBFR_16k, 2); | |
245 | |
246 ctx->energy_history[1] = ctx->energy_history[0]; | |
247 ctx->energy_history[0] = 20.0 * log10f(gain_corr_factor); | |
248 | |
249 ff_weighted_vector_sumf(&excitation[i_subfr], &excitation[i_subfr], | |
250 fixed_vector, pitch_fac, | |
251 gain_code, L_SUBFR_16k); | |
252 | |
253 ff_celp_lp_synthesis_filterf(synth + i_subfr, Az[i], | |
254 &excitation[i_subfr], L_SUBFR_16k, | |
255 LP_FILTER_ORDER_16k); | |
256 | |
257 } | |
258 memcpy(ctx->synth, synth + frame_size - LP_FILTER_ORDER_16k, | |
259 LP_FILTER_ORDER_16k * sizeof(*synth)); | |
260 | |
261 memmove(ctx->excitation, ctx->excitation + 2 * L_SUBFR_16k, | |
262 (L_INTERPOL+PITCH_MAX) * sizeof(float)); | |
263 | |
11649
e4e4fce64e5d
Make the Sipr16k postfilter function write data into the target/output buffer.
rbultje
parents:
10891
diff
changeset
|
264 postfilter(out_data, synth, ctx->iir_mem, ctx->filt_mem, ctx->mem_preemph); |
10891 | 265 |
266 memcpy(ctx->iir_mem, Az[1], LP_FILTER_ORDER_16k * sizeof(float)); | |
267 } | |
268 | |
269 void ff_sipr_init_16k(SiprContext *ctx) | |
270 { | |
271 int i; | |
272 | |
273 for (i = 0; i < LP_FILTER_ORDER_16k; i++) | |
274 ctx->lsp_history_16k[i] = cos((i + 1) * M_PI/(LP_FILTER_ORDER_16k + 1)); | |
275 | |
276 ctx->filt_mem[0] = ctx->filt_buf[0]; | |
277 ctx->filt_mem[1] = ctx->filt_buf[1]; | |
278 | |
279 ctx->pitch_lag_prev = 180; | |
280 } |