summaryrefslogtreecommitdiff
path: root/newamp2.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 /newamp2.c
stripdown of version 0.9
Diffstat (limited to 'newamp2.c')
-rw-r--r--newamp2.c570
1 files changed, 570 insertions, 0 deletions
diff --git a/newamp2.c b/newamp2.c
new file mode 100644
index 0000000..6550557
--- /dev/null
+++ b/newamp2.c
@@ -0,0 +1,570 @@
1/*---------------------------------------------------------------------------*\
2
3 FILE........: newamp2.c
4 AUTHOR......: Thomas Kurin and Stefan Erhardt
5 INSTITUTE...: Institute for Electronics Engineering, University of Erlangen-Nuremberg
6 DATE CREATED: July 2018
7 BASED ON....: "newamp1" by David Rowe
8
9 Quantisation functions for the sinusoidal coder, using "newamp1"
10 algorithm that resamples variable rate L [Am} to a fixed rate K then
11 VQs.
12
13\*---------------------------------------------------------------------------*/
14
15/*
16 Copyright David Rowe 2017
17
18 All rights reserved.
19
20 This program is free software; you can redistribute it and/or modify
21 it under the terms of the GNU Lesser General Public License version 2.1, as
22 published by the Free Software Foundation. This program is
23 distributed in the hope that it will be useful, but WITHOUT ANY
24 WARRANTY; without even the implied warranty of MERCHANTABILITY or
25 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
26 License for more details.
27
28 You should have received a copy of the GNU Lesser General Public License
29 along with this program; if not, see <http://www.gnu.org/licenses/>.
30
31*/
32
33#include <assert.h>
34#include <stdio.h>
35#include <stdlib.h>
36#include <string.h>
37#include <math.h>
38
39#include "defines.h"
40#include "phase.h"
41#include "quantise.h"
42#include "mbest.h"
43#include "newamp1.h"
44#include "newamp2.h"
45
46/*---------------------------------------------------------------------------*\
47
48 FUNCTION....: n2_mel_sample_freqs_kHz()
49 AUTHOR......: Thomas Kurin and Stefan Erhardt
50 INSTITUTE...: Institute for Electronics Engineering, University of Erlangen-Nuremberg
51 DATE CREATED: July 2018
52
53 Outputs fixed frequencies for the K-Vectors to be able to work with both 8k and 16k mode.
54
55\*---------------------------------------------------------------------------*/
56
57void n2_mel_sample_freqs_kHz(float rate_K_sample_freqs_kHz[], int K)
58{
59 float freq[] = {0.199816, 0.252849, 0.309008, 0.368476, 0.431449, 0.498134, 0.568749, 0.643526, 0.722710, 0.806561, 0.895354, 0.989380,
60 1.088948, 1.194384, 1.306034, 1.424264, 1.549463, 1.682041, 1.822432, 1.971098, 2.128525, 2.295232, 2.471763, 2.658699,
61 2.856652, 3.066272, 3.288246, 3.523303, 3.772214, 4.035795, 4.314912, 4.610478, 4.923465, 5.254899, 5.605865, 5.977518,
62 6.371075, 6.787827, 7.229141, 7.696465};
63 int k;
64 //printf("\n\n");
65 for (k=0; k<K; k++) {
66 rate_K_sample_freqs_kHz[k] = freq[k];
67 // printf("%f ",mel);
68 // printf("%f \n",rate_K_sample_freqs_kHz[k]);
69 }
70
71}
72
73
74/*---------------------------------------------------------------------------*\
75
76 FUNCTION....: n2_resample_const_rate_f() still equal to resample_const_rate_f()
77 AUTHOR......: David Rowe
78 DATE CREATED: Jan 2017
79
80 Resample Am from time-varying rate L=floor(pi/Wo) to fixed rate K.
81
82\*---------------------------------------------------------------------------*/
83
84void n2_resample_const_rate_f(C2CONST *c2const, MODEL *model, float rate_K_vec[], float rate_K_sample_freqs_kHz[], int K)
85{
86 int m;
87 float AmdB[MAX_AMP+1], rate_L_sample_freqs_kHz[MAX_AMP+1], AmdB_peak;
88
89 /* convert rate L=pi/Wo amplitude samples to fixed rate K */
90
91 AmdB_peak = -100.0;
92 for(m=1; m<=model->L; m++) {
93 AmdB[m] = 20.0*log10(model->A[m]+1E-16);
94 if (AmdB[m] > AmdB_peak) {
95 AmdB_peak = AmdB[m];
96 }
97 rate_L_sample_freqs_kHz[m] = m*model->Wo*(c2const->Fs/2000.0)/M_PI;
98 //printf("m: %d AmdB: %f AmdB_peak: %f sf: %f\n", m, AmdB[m], AmdB_peak, rate_L_sample_freqs_kHz[m]);
99 }
100
101 /* clip between peak and peak -50dB, to reduce dynamic range */
102
103 for(m=1; m<=model->L; m++) {
104 if (AmdB[m] < (AmdB_peak-50.0)) {
105 AmdB[m] = AmdB_peak-50.0;
106 }
107 }
108
109 interp_para(rate_K_vec, &rate_L_sample_freqs_kHz[1], &AmdB[1], model->L, rate_K_sample_freqs_kHz, K);
110}
111
112
113/*---------------------------------------------------------------------------*\
114
115 FUNCTION....: n2_rate_K_mbest_encode
116 AUTHOR......: Thomas Kurin and Stefan Erhardt
117 INSTITUTE...: Institute for Electronics Engineering, University of Erlangen-Nuremberg
118 DATE CREATED: July 2018
119
120 One stage rate K newamp2 VQ quantiser using mbest search.
121
122\*---------------------------------------------------------------------------*/
123
124void n2_rate_K_mbest_encode(int *indexes, float *x, float *xq, int ndim)
125{
126 int i, n1;
127 const float *codebook1 = newamp2vq_cb[0].cb;
128 struct MBEST *mbest_stage1;
129 float w[ndim];
130 int index[1];
131
132 /* codebook is compiled for a fixed K */
133
134 //assert(ndim == newamp2vq_cb[0].k);
135
136 /* equal weights, could be argued mel freq axis gives freq dep weighting */
137
138 for(i=0; i<ndim; i++)
139 w[i] = 1.0;
140
141 mbest_stage1 = mbest_create(1);
142
143 index[0] = 0;
144
145 /* Stage 1 */
146
147 mbest_search450(codebook1, x, w, ndim,NEWAMP2_K, newamp2vq_cb[0].m, mbest_stage1, index);
148 MBEST_PRINT("Stage 1:", mbest_stage1);
149 n1 = mbest_stage1->list[0].index[0];
150
151 mbest_destroy(mbest_stage1);
152
153 //indexes[1]: legacy from newamp1
154 indexes[0] = n1; indexes[1] = n1;
155
156}
157
158
159/*---------------------------------------------------------------------------*\
160
161 FUNCTION....: n2_resample_rate_L
162 AUTHOR......: Thomas Kurin and Stefan Erhardt
163 INSTITUTE...: Institute for Electronics Engineering, University of Erlangen-Nuremberg
164 DATE CREATED: July 2018
165
166 Decoder side conversion of rate K vector back to rate L.
167 Plosives are set to zero for the first 2 of 4 frames.
168
169\*---------------------------------------------------------------------------*/
170
171void n2_resample_rate_L(C2CONST *c2const, MODEL *model, float rate_K_vec[], float rate_K_sample_freqs_kHz[], int K,int plosive_flag)
172{
173 float rate_K_vec_term[K+2], rate_K_sample_freqs_kHz_term[K+2];
174 float AmdB[MAX_AMP+1], rate_L_sample_freqs_kHz[MAX_AMP+1];
175 int m,k;
176
177 /* terminate either end of the rate K vecs with 0dB points */
178
179 rate_K_vec_term[0] = rate_K_vec_term[K+1] = 0.0;
180 rate_K_sample_freqs_kHz_term[0] = 0.0;
181 rate_K_sample_freqs_kHz_term[K+1] = 4.0;
182
183 for(k=0; k<K; k++) {
184 rate_K_vec_term[k+1] = rate_K_vec[k];
185 rate_K_sample_freqs_kHz_term[k+1] = rate_K_sample_freqs_kHz[k];
186
187 //printf("k: %d f: %f rate_K: %f\n", k, rate_K_sample_freqs_kHz[k], rate_K_vec[k]);
188 }
189
190 for(m=1; m<=model->L; m++) {
191 rate_L_sample_freqs_kHz[m] = m*model->Wo*(c2const->Fs/2000.0)/M_PI;
192 }
193
194 interp_para(&AmdB[1], rate_K_sample_freqs_kHz_term, rate_K_vec_term, K+2, &rate_L_sample_freqs_kHz[1], model->L);
195 for(m=1; m<=model->L; m++) {
196 if(plosive_flag==0){
197 model->A[m] = pow(10.0, AmdB[m]/20.0);
198 }else{
199 model->A[m] = 0.1;
200 }
201 // printf("m: %d f: %f AdB: %f A: %f\n", m, rate_L_sample_freqs_kHz[m], AmdB[m], model->A[m]);
202 }
203}
204
205/*---------------------------------------------------------------------------*\
206
207 FUNCTION....: n2_post_filter_newamp2
208 AUTHOR......: Thomas Kurin and Stefan Erhardt
209 INSTITUTE...: Institute for Electronics Engineering, University of Erlangen-Nuremberg
210 DATE CREATED: July 2018
211
212 Postfilter for the pseudo wideband mode. Still has to be adapted!
213
214\*---------------------------------------------------------------------------*/
215
216void n2_post_filter_newamp2(float vec[], float sample_freq_kHz[], int K, float pf_gain)
217{
218 int k;
219
220 /*
221 vec is rate K vector describing spectrum of current frame lets
222 pre-emp before applying PF. 20dB/dec over 300Hz. Postfilter
223 affects energy of frame so we measure energy before and after
224 and normalise. Plenty of room for experiment here as well.
225 */
226
227 float pre[K];
228 float e_before = 0.0;
229 float e_after = 0.0;
230 for(k=0; k<K; k++) {
231 pre[k] = 20.0*log10f(sample_freq_kHz[k]/0.3);
232 vec[k] += pre[k];
233 e_before += POW10F(vec[k]/10.0);
234 vec[k] *= pf_gain;
235 e_after += POW10F(vec[k]/10.0);
236 }
237
238 float gain = e_after/e_before;
239 float gaindB = 10*log10f(gain);
240
241 for(k=0; k<K; k++) {
242 vec[k] -= gaindB;
243 vec[k] -= pre[k];
244 }
245}
246
247
248/*---------------------------------------------------------------------------*\
249
250 FUNCTION....: newamp2_model_to_indexes
251 AUTHOR......: Thomas Kurin and Stefan Erhardt
252 INSTITUTE...: Institute for Electronics Engineering, University of Erlangen-Nuremberg
253 DATE CREATED: July 2018
254
255 newamp2 encoder: Encodes the 8k sampled samples using mbest search (one stage)
256
257\*---------------------------------------------------------------------------*/
258
259void newamp2_model_to_indexes(C2CONST *c2const,
260 int indexes[],
261 MODEL *model,
262 float rate_K_vec[],
263 float rate_K_sample_freqs_kHz[],
264 int K,
265 float *mean,
266 float rate_K_vec_no_mean[],
267 float rate_K_vec_no_mean_[],
268 int plosive
269 )
270{
271 int k;
272
273 /* convert variable rate L to fixed rate K */
274
275 resample_const_rate_f(c2const, model, rate_K_vec, rate_K_sample_freqs_kHz, K);
276
277 /* remove mean and two stage VQ */
278
279 float sum = 0.0;
280 for(k=0; k<K; k++)
281 sum += rate_K_vec[k];
282 *mean = sum/K;
283 for(k=0; k<K; k++)
284 {
285 rate_K_vec_no_mean[k] = rate_K_vec[k] - *mean;
286 }
287 //NEWAMP2_16K_K+1 because the last vector is not a vector for VQ (and not included in the constant)
288 //but a calculated medium mean value
289 n2_rate_K_mbest_encode(indexes, rate_K_vec_no_mean, rate_K_vec_no_mean_, NEWAMP2_16K_K+1);
290
291 /* scalar quantise mean (effectively the frame energy) */
292
293 float w[1] = {1.0};
294 float se;
295 indexes[2] = quantise(newamp2_energy_cb[0].cb,
296 mean,
297 w,
298 newamp2_energy_cb[0].k,
299 newamp2_energy_cb[0].m,
300 &se);
301
302 /* scalar quantise Wo. We steal the smallest Wo index to signal
303 an unvoiced frame */
304
305 if (model->voiced) {
306 int index = encode_log_Wo(c2const, model->Wo, 6);
307 if (index == 0) {
308 index = 1;
309 }
310 if (index == 63) {
311 index = 62;
312 }
313 indexes[3] = index;
314 }
315 else {
316 indexes[3] = 0;
317 }
318 if(plosive != 0){
319 indexes[3] = 63;
320 }
321 }
322
323
324/*---------------------------------------------------------------------------*\
325
326 FUNCTION....: newamp2_indexes_to_rate_K_vec
327 AUTHOR......: Thomas Kurin and Stefan Erhardt
328 INSTITUTE...: Institute for Electronics Engineering, University of Erlangen-Nuremberg
329 DATE CREATED: July 2018
330
331 newamp2 decoder for amplitudes {Am}. Given the rate K VQ and energy
332 indexes, outputs rate K vector. Equal to newamp1 but using only one stage VQ.
333
334\*---------------------------------------------------------------------------*/
335
336void newamp2_indexes_to_rate_K_vec(float rate_K_vec_[],
337 float rate_K_vec_no_mean_[],
338 float rate_K_sample_freqs_kHz[],
339 int K,
340 float *mean_,
341 int indexes[],
342 float pf_gain)
343{
344 int k;
345 const float *codebook1 = newamp2vq_cb[0].cb;
346 int n1 = indexes[0];
347
348 for(k=0; k<K; k++) {
349 rate_K_vec_no_mean_[k] = codebook1[(NEWAMP2_16K_K+1)*n1+k];
350 }
351
352 post_filter_newamp1(rate_K_vec_no_mean_, rate_K_sample_freqs_kHz, K, pf_gain);
353
354 *mean_ = newamp2_energy_cb[0].cb[indexes[2]];
355
356 for(k=0; k<K; k++) {
357 rate_K_vec_[k] = rate_K_vec_no_mean_[k] + *mean_;
358 }
359}
360
361/*---------------------------------------------------------------------------*\
362
363 FUNCTION....: newamp2_16k_indexes_to_rate_K_vec
364 AUTHOR......: Thomas Kurin and Stefan Erhardt
365 INSTITUTE...: Institute for Electronics Engineering, University of Erlangen-Nuremberg
366 DATE CREATED: July 2018
367
368 newamp2 decoder for amplitudes {Am}. Given the rate K VQ and energy
369 indexes, outputs rate K vector. Extends the sample rate by looking up the corresponding
370 higher frequency values with their energy difference to the base energy (=>mean2)
371
372\*---------------------------------------------------------------------------*/
373
374void newamp2_16k_indexes_to_rate_K_vec(float rate_K_vec_[],
375 float rate_K_vec_no_mean_[],
376 float rate_K_sample_freqs_kHz[],
377 int K,
378 float *mean_,
379 int indexes[],
380 float pf_gain)
381{
382 int k;
383 const float *codebook1 = newamp2vq_cb[0].cb;
384 float mean2 = 0;
385 int n1 = indexes[0];
386
387 for(k=0; k<K; k++) {
388 rate_K_vec_no_mean_[k] = codebook1[(K+1)*n1+k];
389 }
390
391 n2_post_filter_newamp2(rate_K_vec_no_mean_, rate_K_sample_freqs_kHz, K, pf_gain);
392
393 *mean_ = newamp2_energy_cb[0].cb[indexes[2]];
394 mean2 = *mean_ + codebook1[(K+1)*n1+K] -10;
395
396 //HF ear Protection
397 if(mean2>50){
398 mean2 = 50;
399 }
400
401 for(k=0; k<K; k++) {
402 if(k<NEWAMP2_K){
403 rate_K_vec_[k] = rate_K_vec_no_mean_[k] + *mean_;
404 }
405 else{
406 //Amplify or Reduce ??
407 rate_K_vec_[k] = rate_K_vec_no_mean_[k] + mean2;
408 }
409 }
410}
411/*---------------------------------------------------------------------------*\
412
413 FUNCTION....: newamp2_interpolate
414 AUTHOR......: Thomas Kurin and Stefan Erhardt
415 INSTITUTE...: Institute for Electronics Engineering, University of Erlangen-Nuremberg
416 DATE CREATED: July 2018
417
418 Interpolates to the 4 10ms Frames and leaves the forst 2 empty for plosives
419
420\*---------------------------------------------------------------------------*/
421
422void newamp2_interpolate(float interpolated_surface_[], float left_vec[], float right_vec[], int K, int plosive_flag)
423{
424 int i, k;
425 int M = 4;
426 float c;
427
428 /* (linearly) interpolate 25Hz amplitude vectors back to 100Hz */
429
430 if(plosive_flag == 0){
431 for(i=0,c=1.0; i<M; i++,c-=1.0/M) {
432 for(k=0; k<K; k++) {
433 interpolated_surface_[i*K+k] = left_vec[k]*c + right_vec[k]*(1.0-c);
434 }
435 }
436 }
437 else{
438 for(i=0,c=1.0; i<M; i++,c-=1.0/M) {
439 for(k=0; k<K; k++) {
440 if(i<2){
441 interpolated_surface_[i*K+k] = 0;
442 }
443 else{
444 //perhaps add some dB ?
445 interpolated_surface_[i*K+k] = right_vec[k];
446 }
447 }
448 }
449
450 }
451}
452
453
454/*---------------------------------------------------------------------------*\
455
456 FUNCTION....: newamp2_indexes_to_model
457 AUTHOR......: Thomas Kurin and Stefan Erhardt
458 INSTITUTE...: Institute for Electronics Engineering, University of Erlangen-Nuremberg
459 DATE CREATED: July 2018
460
461 newamp2 decoder. Chooses whether to decode to 16k mode or to 8k mode
462
463\*---------------------------------------------------------------------------*/
464
465void newamp2_indexes_to_model(C2CONST *c2const,
466 MODEL model_[],
467 COMP H[],
468 float *interpolated_surface_,
469 float prev_rate_K_vec_[],
470 float *Wo_left,
471 int *voicing_left,
472 float rate_K_sample_freqs_kHz[],
473 int K,
474 codec2_fft_cfg fwd_cfg,
475 codec2_fft_cfg inv_cfg,
476 int indexes[],
477 float pf_gain,
478 int flag16k)
479{
480 float rate_K_vec_[K], rate_K_vec_no_mean_[K], mean_, Wo_right;
481 int voicing_right, k;
482 int M = 4;
483
484 /* extract latest rate K vector */
485
486 if(flag16k == 0){
487 newamp2_indexes_to_rate_K_vec(rate_K_vec_,
488 rate_K_vec_no_mean_,
489 rate_K_sample_freqs_kHz,
490 K,
491 &mean_,
492 indexes,
493 pf_gain);
494 }else{
495 newamp2_16k_indexes_to_rate_K_vec(rate_K_vec_,
496 rate_K_vec_no_mean_,
497 rate_K_sample_freqs_kHz,
498 K,
499 &mean_,
500 indexes,
501 pf_gain);
502 }
503
504
505 /* decode latest Wo and voicing and plosive */
506 int plosive_flag = 0;
507
508 //Voiced with Wo
509 if (indexes[3]>0 && indexes[3]<63) {
510 Wo_right = decode_log_Wo(c2const, indexes[3], 6);
511 voicing_right = 1;
512 }
513 //Unvoiced
514 else if(indexes[3] == 0){
515 Wo_right = 2.0*M_PI/100.0;
516 voicing_right = 0;
517 }
518 //indexes[3]=63 (= Plosive) and unvoiced
519 else {
520 Wo_right = 2.0*M_PI/100.0;
521 voicing_right = 0;
522 plosive_flag = 1;
523 }
524
525 /* interpolate 25Hz rate K vec back to 100Hz */
526
527 float *left_vec = prev_rate_K_vec_;
528 float *right_vec = rate_K_vec_;
529 newamp2_interpolate(interpolated_surface_, left_vec, right_vec, K,plosive_flag);
530
531 /* interpolate 25Hz v and Wo back to 100Hz */
532
533 float aWo_[M];
534 int avoicing_[M], aL_[M], i;
535
536 interp_Wo_v(aWo_, aL_, avoicing_, *Wo_left, Wo_right, *voicing_left, voicing_right);
537
538 /* back to rate L amplitudes, synthesis phase for each frame */
539
540 for(i=0; i<M; i++) {
541 model_[i].Wo = aWo_[i];
542 model_[i].L = aL_[i];
543 model_[i].voiced = avoicing_[i];
544 //Plosive Detected
545 if(plosive_flag>0){
546 //First two frames are set to zero
547 if (i<2){
548 n2_resample_rate_L(c2const, &model_[i], &interpolated_surface_[K*i], rate_K_sample_freqs_kHz, K,1);
549 }
550 else{
551 n2_resample_rate_L(c2const, &model_[i], &interpolated_surface_[K*i], rate_K_sample_freqs_kHz, K,0);
552 }
553 }
554 //No Plosive, standard resample
555 else{
556 n2_resample_rate_L(c2const, &model_[i], &interpolated_surface_[K*i], rate_K_sample_freqs_kHz, K,0);
557 }
558 determine_phase(c2const, &H[(MAX_AMP+1)*i], &model_[i], NEWAMP2_PHASE_NFFT, fwd_cfg, inv_cfg);
559 }
560
561 /* update memories for next time */
562
563 for(k=0; k<K; k++) {
564 prev_rate_K_vec_[k] = rate_K_vec_[k];
565 }
566 *Wo_left = Wo_right;
567 *voicing_left = voicing_right;
568
569}
570