diff options
Diffstat (limited to 'interp.c')
-rw-r--r-- | interp.c | 247 |
1 files changed, 112 insertions, 135 deletions
@@ -25,13 +25,14 @@ | |||
25 | along with this program; if not, see <http://www.gnu.org/licenses/>. | 25 | along with this program; if not, see <http://www.gnu.org/licenses/>. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | #include "interp.h" | ||
29 | |||
28 | #include <assert.h> | 30 | #include <assert.h> |
29 | #include <math.h> | 31 | #include <math.h> |
30 | #include <string.h> | ||
31 | #include <stdio.h> | 32 | #include <stdio.h> |
33 | #include <string.h> | ||
32 | 34 | ||
33 | #include "defines.h" | 35 | #include "defines.h" |
34 | #include "interp.h" | ||
35 | #include "lsp.h" | 36 | #include "lsp.h" |
36 | #include "quantise.h" | 37 | #include "quantise.h" |
37 | 38 | ||
@@ -44,7 +45,7 @@ float sample_log_amp(MODEL *model, float w); | |||
44 | AUTHOR......: David Rowe | 45 | AUTHOR......: David Rowe |
45 | DATE CREATED: 22/8/10 | 46 | DATE CREATED: 22/8/10 |
46 | 47 | ||
47 | Given two frames decribed by model parameters 20ms apart, determines | 48 | Given two frames described by model parameters 20ms apart, determines |
48 | the model parameters of the 10ms frame between them. Assumes | 49 | the model parameters of the 10ms frame between them. Assumes |
49 | voicing is available for middle (interpolated) frame. Outputs are | 50 | voicing is available for middle (interpolated) frame. Outputs are |
50 | amplitudes and Wo for the interpolated frame. | 51 | amplitudes and Wo for the interpolated frame. |
@@ -107,29 +108,27 @@ void interpolate( | |||
107 | 108 | ||
108 | \*---------------------------------------------------------------------------*/ | 109 | \*---------------------------------------------------------------------------*/ |
109 | 110 | ||
110 | float sample_log_amp(MODEL *model, float w) | 111 | float sample_log_amp(MODEL *model, float w) { |
111 | { | 112 | int m; |
112 | int m; | 113 | float f, log_amp; |
113 | float f, log_amp; | ||
114 | 114 | ||
115 | assert(w > 0.0); assert (w <= PI); | 115 | assert(w > 0.0); |
116 | assert(w <= PI); | ||
116 | 117 | ||
117 | m = floorf(w/model->Wo + 0.5); | 118 | m = floorf(w / model->Wo + 0.5); |
118 | f = (w - m*model->Wo)/w; | 119 | f = (w - m * model->Wo) / w; |
119 | assert(f <= 1.0); | 120 | assert(f <= 1.0); |
120 | 121 | ||
121 | if (m < 1) { | 122 | if (m < 1) { |
122 | log_amp = f*log10f(model->A[1] + 1E-6); | 123 | log_amp = f * log10f(model->A[1] + 1E-6); |
123 | } | 124 | } else if ((m + 1) > model->L) { |
124 | else if ((m+1) > model->L) { | 125 | log_amp = (1.0 - f) * log10f(model->A[model->L] + 1E-6); |
125 | log_amp = (1.0-f)*log10f(model->A[model->L] + 1E-6); | 126 | } else { |
126 | } | 127 | log_amp = (1.0 - f) * log10f(model->A[m] + 1E-6) + |
127 | else { | 128 | f * log10f(model->A[m + 1] + 1E-6); |
128 | log_amp = (1.0-f)*log10f(model->A[m] + 1E-6) + | 129 | } |
129 | f*log10f(model->A[m+1] + 1E-6); | ||
130 | } | ||
131 | 130 | ||
132 | return log_amp; | 131 | return log_amp; |
133 | } | 132 | } |
134 | 133 | ||
135 | #ifdef NOT_NEEDED | 134 | #ifdef NOT_NEEDED |
@@ -140,7 +139,7 @@ float sample_log_amp(MODEL *model, float w) | |||
140 | AUTHOR......: David Rowe | 139 | AUTHOR......: David Rowe |
141 | DATE CREATED: 10 Nov 2010 | 140 | DATE CREATED: 10 Nov 2010 |
142 | 141 | ||
143 | Given two frames decribed by model parameters 20ms apart, determines | 142 | Given two frames described by model parameters 20ms apart, determines |
144 | the model parameters of the 10ms frame between them. Assumes | 143 | the model parameters of the 10ms frame between them. Assumes |
145 | voicing is available for middle (interpolated) frame. Outputs are | 144 | voicing is available for middle (interpolated) frame. Outputs are |
146 | amplitudes and Wo for the interpolated frame. | 145 | amplitudes and Wo for the interpolated frame. |
@@ -150,65 +149,59 @@ float sample_log_amp(MODEL *model, float w) | |||
150 | 149 | ||
151 | \*---------------------------------------------------------------------------*/ | 150 | \*---------------------------------------------------------------------------*/ |
152 | 151 | ||
153 | void interpolate_lsp( | 152 | void interpolate_lsp(codec2_fft_cfg fft_fwd_cfg, |
154 | codec2_fft_cfg fft_fwd_cfg, | 153 | MODEL *interp, /* interpolated model params */ |
155 | MODEL *interp, /* interpolated model params */ | 154 | MODEL *prev, /* previous frames model params */ |
156 | MODEL *prev, /* previous frames model params */ | 155 | MODEL *next, /* next frames model params */ |
157 | MODEL *next, /* next frames model params */ | 156 | float *prev_lsps, /* previous frames LSPs */ |
158 | float *prev_lsps, /* previous frames LSPs */ | 157 | float prev_e, /* previous frames LPC energy */ |
159 | float prev_e, /* previous frames LPC energy */ | 158 | float *next_lsps, /* next frames LSPs */ |
160 | float *next_lsps, /* next frames LSPs */ | 159 | float next_e, /* next frames LPC energy */ |
161 | float next_e, /* next frames LPC energy */ | 160 | float *ak_interp, /* interpolated aks for this frame */ |
162 | float *ak_interp, /* interpolated aks for this frame */ | 161 | float *lsps_interp, /* interpolated lsps for this frame */ |
163 | float *lsps_interp, /* interpolated lsps for this frame */ | 162 | float Wo_min) { |
164 | float Wo_min | 163 | int i; |
165 | ) | 164 | float e; |
166 | { | 165 | float snr; |
167 | int i; | 166 | |
168 | float e; | 167 | /* trap corner case where V est is probably wrong */ |
169 | float snr; | 168 | |
170 | 169 | if (interp->voiced && !prev->voiced && !next->voiced) { | |
171 | /* trap corner case where V est is probably wrong */ | 170 | interp->voiced = 0; |
172 | 171 | } | |
173 | if (interp->voiced && !prev->voiced && !next->voiced) { | 172 | |
174 | interp->voiced = 0; | 173 | /* Wo depends on voicing of this and adjacent frames */ |
175 | } | 174 | |
176 | 175 | if (interp->voiced) { | |
177 | /* Wo depends on voicing of this and adjacent frames */ | 176 | if (prev->voiced && next->voiced) interp->Wo = (prev->Wo + next->Wo) / 2.0; |
178 | 177 | if (!prev->voiced && next->voiced) interp->Wo = next->Wo; | |
179 | if (interp->voiced) { | 178 | if (prev->voiced && !next->voiced) interp->Wo = prev->Wo; |
180 | if (prev->voiced && next->voiced) | 179 | } else { |
181 | interp->Wo = (prev->Wo + next->Wo)/2.0; | 180 | interp->Wo = Wo_min; |
182 | if (!prev->voiced && next->voiced) | 181 | } |
183 | interp->Wo = next->Wo; | 182 | interp->L = PI / interp->Wo; |
184 | if (prev->voiced && !next->voiced) | 183 | |
185 | interp->Wo = prev->Wo; | 184 | // printf(" interp: prev_v: %d next_v: %d prev_Wo: %f next_Wo: %f\n", |
186 | } | 185 | // prev->voiced, next->voiced, prev->Wo, next->Wo); |
187 | else { | 186 | // printf(" interp: Wo: %1.5f L: %d\n", interp->Wo, interp->L); |
188 | interp->Wo = Wo_min; | 187 | |
189 | } | 188 | /* interpolate LSPs */ |
190 | interp->L = PI/interp->Wo; | 189 | |
191 | 190 | for (i = 0; i < LPC_ORD; i++) { | |
192 | //printf(" interp: prev_v: %d next_v: %d prev_Wo: %f next_Wo: %f\n", | 191 | lsps_interp[i] = (prev_lsps[i] + next_lsps[i]) / 2.0; |
193 | // prev->voiced, next->voiced, prev->Wo, next->Wo); | 192 | } |
194 | //printf(" interp: Wo: %1.5f L: %d\n", interp->Wo, interp->L); | 193 | |
195 | 194 | /* Interpolate LPC energy in log domain */ | |
196 | /* interpolate LSPs */ | 195 | |
197 | 196 | e = powf(10.0, (log10f(prev_e) + log10f(next_e)) / 2.0); | |
198 | for(i=0; i<LPC_ORD; i++) { | 197 | // printf(" interp: e: %f\n", e); |
199 | lsps_interp[i] = (prev_lsps[i] + next_lsps[i])/2.0; | 198 | |
200 | } | 199 | /* convert back to amplitudes */ |
201 | 200 | ||
202 | /* Interpolate LPC energy in log domain */ | 201 | lsp_to_lpc(lsps_interp, ak_interp, LPC_ORD); |
203 | 202 | aks_to_M2(fft_fwd_cfg, ak_interp, LPC_ORD, interp, e, &snr, 0, 0, 1, 1, | |
204 | e = powf(10.0, (log10f(prev_e) + log10f(next_e))/2.0); | 203 | LPCPF_BETA, LPCPF_GAMMA); |
205 | //printf(" interp: e: %f\n", e); | 204 | // printf(" interp: ak[1]: %f A[1] %f\n", ak_interp[1], interp->A[1]); |
206 | |||
207 | /* convert back to amplitudes */ | ||
208 | |||
209 | lsp_to_lpc(lsps_interp, ak_interp, LPC_ORD); | ||
210 | aks_to_M2(fft_fwd_cfg, ak_interp, LPC_ORD, interp, e, &snr, 0, 0, 1, 1, LPCPF_BETA, LPCPF_GAMMA); | ||
211 | //printf(" interp: ak[1]: %f A[1] %f\n", ak_interp[1], interp->A[1]); | ||
212 | } | 205 | } |
213 | #endif | 206 | #endif |
214 | 207 | ||
@@ -224,14 +217,11 @@ void interpolate_lsp( | |||
224 | 217 | ||
225 | \*---------------------------------------------------------------------------*/ | 218 | \*---------------------------------------------------------------------------*/ |
226 | 219 | ||
227 | void interp_Wo( | 220 | void interp_Wo(MODEL *interp, /* interpolated model params */ |
228 | MODEL *interp, /* interpolated model params */ | 221 | MODEL *prev, /* previous frames model params */ |
229 | MODEL *prev, /* previous frames model params */ | 222 | MODEL *next, /* next frames model params */ |
230 | MODEL *next, /* next frames model params */ | 223 | float Wo_min) { |
231 | float Wo_min | 224 | interp_Wo2(interp, prev, next, 0.5, Wo_min); |
232 | ) | ||
233 | { | ||
234 | interp_Wo2(interp, prev, next, 0.5, Wo_min); | ||
235 | } | 225 | } |
236 | 226 | ||
237 | /*---------------------------------------------------------------------------*\ | 227 | /*---------------------------------------------------------------------------*\ |
@@ -244,37 +234,29 @@ void interp_Wo( | |||
244 | 234 | ||
245 | \*---------------------------------------------------------------------------*/ | 235 | \*---------------------------------------------------------------------------*/ |
246 | 236 | ||
247 | void interp_Wo2( | 237 | void interp_Wo2(MODEL *interp, /* interpolated model params */ |
248 | MODEL *interp, /* interpolated model params */ | 238 | MODEL *prev, /* previous frames model params */ |
249 | MODEL *prev, /* previous frames model params */ | 239 | MODEL *next, /* next frames model params */ |
250 | MODEL *next, /* next frames model params */ | 240 | float weight, float Wo_min) { |
251 | float weight, | 241 | /* trap corner case where voicing est is probably wrong */ |
252 | float Wo_min | 242 | |
253 | ) | 243 | if (interp->voiced && !prev->voiced && !next->voiced) { |
254 | { | 244 | interp->voiced = 0; |
255 | /* trap corner case where voicing est is probably wrong */ | 245 | } |
256 | 246 | ||
257 | if (interp->voiced && !prev->voiced && !next->voiced) { | 247 | /* Wo depends on voicing of this and adjacent frames */ |
258 | interp->voiced = 0; | 248 | |
259 | } | 249 | if (interp->voiced) { |
260 | 250 | if (prev->voiced && next->voiced) | |
261 | /* Wo depends on voicing of this and adjacent frames */ | 251 | interp->Wo = (1.0 - weight) * prev->Wo + weight * next->Wo; |
262 | 252 | if (!prev->voiced && next->voiced) interp->Wo = next->Wo; | |
263 | if (interp->voiced) { | 253 | if (prev->voiced && !next->voiced) interp->Wo = prev->Wo; |
264 | if (prev->voiced && next->voiced) | 254 | } else { |
265 | interp->Wo = (1.0 - weight)*prev->Wo + weight*next->Wo; | 255 | interp->Wo = Wo_min; |
266 | if (!prev->voiced && next->voiced) | 256 | } |
267 | interp->Wo = next->Wo; | 257 | interp->L = PI / interp->Wo; |
268 | if (prev->voiced && !next->voiced) | ||
269 | interp->Wo = prev->Wo; | ||
270 | } | ||
271 | else { | ||
272 | interp->Wo = Wo_min; | ||
273 | } | ||
274 | interp->L = PI/interp->Wo; | ||
275 | } | 258 | } |
276 | 259 | ||
277 | |||
278 | /*---------------------------------------------------------------------------*\ | 260 | /*---------------------------------------------------------------------------*\ |
279 | 261 | ||
280 | FUNCTION....: interp_energy() | 262 | FUNCTION....: interp_energy() |
@@ -286,13 +268,12 @@ void interp_Wo2( | |||
286 | 268 | ||
287 | \*---------------------------------------------------------------------------*/ | 269 | \*---------------------------------------------------------------------------*/ |
288 | 270 | ||
289 | float interp_energy(float prev_e, float next_e) | 271 | float interp_energy(float prev_e, float next_e) { |
290 | { | 272 | // return powf(10.0, (log10f(prev_e) + log10f(next_e))/2.0); |
291 | //return powf(10.0, (log10f(prev_e) + log10f(next_e))/2.0); | 273 | return sqrtf(prev_e * |
292 | return sqrtf(prev_e * next_e); //looks better is math. identical and faster math | 274 | next_e); // looks better is math. identical and faster math |
293 | } | 275 | } |
294 | 276 | ||
295 | |||
296 | /*---------------------------------------------------------------------------*\ | 277 | /*---------------------------------------------------------------------------*\ |
297 | 278 | ||
298 | FUNCTION....: interp_energy2() | 279 | FUNCTION....: interp_energy2() |
@@ -304,13 +285,10 @@ float interp_energy(float prev_e, float next_e) | |||
304 | 285 | ||
305 | \*---------------------------------------------------------------------------*/ | 286 | \*---------------------------------------------------------------------------*/ |
306 | 287 | ||
307 | float interp_energy2(float prev_e, float next_e, float weight) | 288 | float interp_energy2(float prev_e, float next_e, float weight) { |
308 | { | 289 | return POW10F((1.0 - weight) * log10f(prev_e) + weight * log10f(next_e)); |
309 | return POW10F((1.0 - weight)*log10f(prev_e) + weight*log10f(next_e)); | ||
310 | |||
311 | } | 290 | } |
312 | 291 | ||
313 | |||
314 | /*---------------------------------------------------------------------------*\ | 292 | /*---------------------------------------------------------------------------*\ |
315 | 293 | ||
316 | FUNCTION....: interpolate_lsp_ver2() | 294 | FUNCTION....: interpolate_lsp_ver2() |
@@ -321,11 +299,10 @@ float interp_energy2(float prev_e, float next_e, float weight) | |||
321 | 299 | ||
322 | \*---------------------------------------------------------------------------*/ | 300 | \*---------------------------------------------------------------------------*/ |
323 | 301 | ||
324 | void interpolate_lsp_ver2(float interp[], float prev[], float next[], float weight, int order) | 302 | void interpolate_lsp_ver2(float interp[], float prev[], float next[], |
325 | { | 303 | float weight, int order) { |
326 | int i; | 304 | int i; |
327 | 305 | ||
328 | for(i=0; i<order; i++) | 306 | for (i = 0; i < order; i++) |
329 | interp[i] = (1.0 - weight)*prev[i] + weight*next[i]; | 307 | interp[i] = (1.0 - weight) * prev[i] + weight * next[i]; |
330 | } | 308 | } |
331 | |||