summaryrefslogtreecommitdiff
path: root/interp.c
diff options
context:
space:
mode:
authorerdgeist@erdgeist.org <erdgeist@bauklotz.fritz.box>2019-07-04 23:26:09 +0200
committererdgeist@erdgeist.org <erdgeist@bauklotz.fritz.box>2019-07-04 23:26:09 +0200
commitf02dfce6e6c34b3d8a7b8a0e784b506178e331fa (patch)
tree45556e6104242d4702689760433d7321ae74ec17 /interp.c
stripdown of version 0.9
Diffstat (limited to 'interp.c')
-rw-r--r--interp.c331
1 files changed, 331 insertions, 0 deletions
diff --git a/interp.c b/interp.c
new file mode 100644
index 0000000..2109acb
--- /dev/null
+++ b/interp.c
@@ -0,0 +1,331 @@
1/*---------------------------------------------------------------------------*\
2
3 FILE........: interp.c
4 AUTHOR......: David Rowe
5 DATE CREATED: 9/10/09
6
7 Interpolation of 20ms frames to 10ms frames.
8
9\*---------------------------------------------------------------------------*/
10
11/*
12 Copyright (C) 2009 David Rowe
13
14 All rights reserved.
15
16 This program is free software; you can redistribute it and/or modify
17 it under the terms of the GNU Lesser General Public License version 2.1, as
18 published by the Free Software Foundation. This program is
19 distributed in the hope that it will be useful, but WITHOUT ANY
20 WARRANTY; without even the implied warranty of MERCHANTABILITY or
21 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
22 License for more details.
23
24 You should have received a copy of the GNU Lesser General Public License
25 along with this program; if not, see <http://www.gnu.org/licenses/>.
26*/
27
28#include <assert.h>
29#include <math.h>
30#include <string.h>
31#include <stdio.h>
32
33#include "defines.h"
34#include "interp.h"
35#include "lsp.h"
36#include "quantise.h"
37
38float sample_log_amp(MODEL *model, float w);
39
40#if 0
41/*---------------------------------------------------------------------------*\
42
43 FUNCTION....: interp()
44 AUTHOR......: David Rowe
45 DATE CREATED: 22/8/10
46
47 Given two frames decribed by model parameters 20ms apart, determines
48 the model parameters of the 10ms frame between them. Assumes
49 voicing is available for middle (interpolated) frame. Outputs are
50 amplitudes and Wo for the interpolated frame.
51
52 This version can interpolate the amplitudes between two frames of
53 different Wo and L.
54
55 This version works by log linear interpolation, but listening tests
56 showed it creates problems in background noise, e.g. hts2a and mmt1.
57 When this function is used (--dec mode) bg noise appears to be
58 amplitude modulated, and gets louder. The interp_lsp() function
59 below seems to do a better job.
60
61\*---------------------------------------------------------------------------*/
62
63void interpolate(
64 MODEL *interp, /* interpolated model params */
65 MODEL *prev, /* previous frames model params */
66 MODEL *next, /* next frames model params */
67 float Wo_min
68)
69{
70 int l;
71 float w,log_amp;
72
73 /* Wo depends on voicing of this and adjacent frames */
74
75 if (interp->voiced) {
76 if (prev->voiced && next->voiced)
77 interp->Wo = (prev->Wo + next->Wo)/2.0;
78 if (!prev->voiced && next->voiced)
79 interp->Wo = next->Wo;
80 if (prev->voiced && !next->voiced)
81 interp->Wo = prev->Wo;
82 }
83 else {
84 interp->Wo = Wo_min;
85 }
86 interp->L = PI/interp->Wo;
87
88 /* Interpolate amplitudes using linear interpolation in log domain */
89
90 for(l=1; l<=interp->L; l++) {
91 w = l*interp->Wo;
92 log_amp = (sample_log_amp(prev, w) + sample_log_amp(next, w))/2.0;
93 interp->A[l] = powf(10.0, log_amp);
94 }
95}
96#endif
97
98/*---------------------------------------------------------------------------*\
99
100 FUNCTION....: sample_log_amp()
101 AUTHOR......: David Rowe
102 DATE CREATED: 22/8/10
103
104 Samples the amplitude envelope at an arbitrary frequency w. Uses
105 linear interpolation in the log domain to sample between harmonic
106 amplitudes.
107
108\*---------------------------------------------------------------------------*/
109
110float sample_log_amp(MODEL *model, float w)
111{
112 int m;
113 float f, log_amp;
114
115 assert(w > 0.0); assert (w <= PI);
116
117 m = floorf(w/model->Wo + 0.5);
118 f = (w - m*model->Wo)/w;
119 assert(f <= 1.0);
120
121 if (m < 1) {
122 log_amp = f*log10f(model->A[1] + 1E-6);
123 }
124 else if ((m+1) > model->L) {
125 log_amp = (1.0-f)*log10f(model->A[model->L] + 1E-6);
126 }
127 else {
128 log_amp = (1.0-f)*log10f(model->A[m] + 1E-6) +
129 f*log10f(model->A[m+1] + 1E-6);
130 }
131
132 return log_amp;
133}
134
135#ifdef NOT_NEEDED
136
137/*---------------------------------------------------------------------------*\
138
139 FUNCTION....: interp_lsp()
140 AUTHOR......: David Rowe
141 DATE CREATED: 10 Nov 2010
142
143 Given two frames decribed by model parameters 20ms apart, determines
144 the model parameters of the 10ms frame between them. Assumes
145 voicing is available for middle (interpolated) frame. Outputs are
146 amplitudes and Wo for the interpolated frame.
147
148 This version uses interpolation of LSPs, seems to do a better job
149 with bg noise.
150
151\*---------------------------------------------------------------------------*/
152
153void interpolate_lsp(
154 codec2_fft_cfg fft_fwd_cfg,
155 MODEL *interp, /* interpolated model params */
156 MODEL *prev, /* previous frames model params */
157 MODEL *next, /* next frames model params */
158 float *prev_lsps, /* previous frames LSPs */
159 float prev_e, /* previous frames LPC energy */
160 float *next_lsps, /* next frames LSPs */
161 float next_e, /* next frames LPC energy */
162 float *ak_interp, /* interpolated aks for this frame */
163 float *lsps_interp, /* interpolated lsps for this frame */
164 float Wo_min
165)
166{
167 int i;
168 float e;
169 float snr;
170
171 /* trap corner case where V est is probably wrong */
172
173 if (interp->voiced && !prev->voiced && !next->voiced) {
174 interp->voiced = 0;
175 }
176
177 /* Wo depends on voicing of this and adjacent frames */
178
179 if (interp->voiced) {
180 if (prev->voiced && next->voiced)
181 interp->Wo = (prev->Wo + next->Wo)/2.0;
182 if (!prev->voiced && next->voiced)
183 interp->Wo = next->Wo;
184 if (prev->voiced && !next->voiced)
185 interp->Wo = prev->Wo;
186 }
187 else {
188 interp->Wo = Wo_min;
189 }
190 interp->L = PI/interp->Wo;
191
192 //printf(" interp: prev_v: %d next_v: %d prev_Wo: %f next_Wo: %f\n",
193 // prev->voiced, next->voiced, prev->Wo, next->Wo);
194 //printf(" interp: Wo: %1.5f L: %d\n", interp->Wo, interp->L);
195
196 /* interpolate LSPs */
197
198 for(i=0; i<LPC_ORD; i++) {
199 lsps_interp[i] = (prev_lsps[i] + next_lsps[i])/2.0;
200 }
201
202 /* Interpolate LPC energy in log domain */
203
204 e = powf(10.0, (log10f(prev_e) + log10f(next_e))/2.0);
205 //printf(" interp: e: %f\n", e);
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}
213#endif
214
215/*---------------------------------------------------------------------------*\
216
217 FUNCTION....: interp_Wo()
218 AUTHOR......: David Rowe
219 DATE CREATED: 22 May 2012
220
221 Interpolates centre 10ms sample of Wo and L samples given two
222 samples 20ms apart. Assumes voicing is available for centre
223 (interpolated) frame.
224
225\*---------------------------------------------------------------------------*/
226
227void interp_Wo(
228 MODEL *interp, /* interpolated model params */
229 MODEL *prev, /* previous frames model params */
230 MODEL *next, /* next frames model params */
231 float Wo_min
232 )
233{
234 interp_Wo2(interp, prev, next, 0.5, Wo_min);
235}
236
237/*---------------------------------------------------------------------------*\
238
239 FUNCTION....: interp_Wo2()
240 AUTHOR......: David Rowe
241 DATE CREATED: 22 May 2012
242
243 Weighted interpolation of two Wo samples.
244
245\*---------------------------------------------------------------------------*/
246
247void interp_Wo2(
248 MODEL *interp, /* interpolated model params */
249 MODEL *prev, /* previous frames model params */
250 MODEL *next, /* next frames model params */
251 float weight,
252 float Wo_min
253)
254{
255 /* trap corner case where voicing est is probably wrong */
256
257 if (interp->voiced && !prev->voiced && !next->voiced) {
258 interp->voiced = 0;
259 }
260
261 /* Wo depends on voicing of this and adjacent frames */
262
263 if (interp->voiced) {
264 if (prev->voiced && next->voiced)
265 interp->Wo = (1.0 - weight)*prev->Wo + weight*next->Wo;
266 if (!prev->voiced && next->voiced)
267 interp->Wo = next->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}
276
277
278/*---------------------------------------------------------------------------*\
279
280 FUNCTION....: interp_energy()
281 AUTHOR......: David Rowe
282 DATE CREATED: 22 May 2012
283
284 Interpolates centre 10ms sample of energy given two samples 20ms
285 apart.
286
287\*---------------------------------------------------------------------------*/
288
289float interp_energy(float prev_e, float next_e)
290{
291 //return powf(10.0, (log10f(prev_e) + log10f(next_e))/2.0);
292 return sqrtf(prev_e * next_e); //looks better is math. identical and faster math
293}
294
295
296/*---------------------------------------------------------------------------*\
297
298 FUNCTION....: interp_energy2()
299 AUTHOR......: David Rowe
300 DATE CREATED: 22 May 2012
301
302 Interpolates centre 10ms sample of energy given two samples 20ms
303 apart.
304
305\*---------------------------------------------------------------------------*/
306
307float interp_energy2(float prev_e, float next_e, float weight)
308{
309 return POW10F((1.0 - weight)*log10f(prev_e) + weight*log10f(next_e));
310
311}
312
313
314/*---------------------------------------------------------------------------*\
315
316 FUNCTION....: interpolate_lsp_ver2()
317 AUTHOR......: David Rowe
318 DATE CREATED: 22 May 2012
319
320 Weighted interpolation of LSPs.
321
322\*---------------------------------------------------------------------------*/
323
324void interpolate_lsp_ver2(float interp[], float prev[], float next[], float weight, int order)
325{
326 int i;
327
328 for(i=0; i<order; i++)
329 interp[i] = (1.0 - weight)*prev[i] + weight*next[i];
330}
331