-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgainquan.c
110 lines (93 loc) · 3.91 KB
/
gainquan.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
/*****************************************************************************/
/* BroadVoice(R)16 (BV16) Floating-Point ANSI-C Source Code */
/* Revision Date: October 5, 2012 */
/* Version 1.2 */
/*****************************************************************************/
/*****************************************************************************/
/* Copyright 2000-2012 Broadcom Corporation */
/* */
/* This software is provided under the GNU Lesser General Public License, */
/* version 2.1, as published by the Free Software Foundation ("LGPL"). */
/* This program is distributed in the hope that it will be useful, but */
/* WITHOUT ANY SUPPORT OR WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the LGPL for */
/* more details. A copy of the LGPL is available at */
/* http://www.broadcom.com/licenses/LGPLv2.1.php, */
/* or by writing to the Free Software Foundation, Inc., */
/* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
/*****************************************************************************/
/*****************************************************************************
gainquan.c : gain quantization based on inter-subframe
moving-average prediction of logarithmic gain.
$Log$
******************************************************************************/
#include <math.h>
#include "typedef.h"
#include "bv16cnst.h"
#include "bvcommon.h"
#include "bv16externs.h"
int gainquan(
Float *gainq,
Float lg,
Float *lgpm,
Float *prevlg, /* previous log gains (last two frames) */
Float level
)
{
Float elg, lgpe, limit, dmin, d;
int i, n, gidx=0, *p_gidx;
/* calculate estimated log-gain */
elg = lgmean;
for (i = 0; i < LGPORDER; i++) {
elg += lgp[i] * lgpm[i];
}
/* subtract log-gain mean & estimated log-gain to get prediction error */
lgpe = lg - elg;
/* scalar quantization of log-gain prediction error */
dmin = 1e30;
p_gidx = idxord;
for (i = 0; i < LGPECBSZ; i++) {
d = lgpe - lgpecb[*p_gidx++];
if (d < 0.0F) {
d = -d;
}
if (d < dmin) {
dmin = d;
gidx= i;
}
}
/* calculate quantized log-gain */
*gainq = lgpecb[idxord[gidx]] + elg;
/* look up from lgclimit() table the maximum log gain change allowed */
i = (int) ((prevlg[0] - level - LGLB) * 0.5F); /* get column index */
if (i >= NGB) {
i = NGB - 1;
} else if (i < 0) {
i = 0;
}
n = (int) ((prevlg[0] - prevlg[1] - LGCLB) * 0.5F); /* get row index */
if (n >= NGCB) {
n = NGCB - 1;
} else if (n < 0) {
n = 0;
}
i = i * NGCB + n;
/* check whether quantized log-gain cause a gain change > lgclimit */
limit = prevlg[0] + lgclimit[i];/* limit that log-gain shouldn't exceed */
while ((*gainq > limit) && (gidx > 0) ) { /* if q log-gain exceeds limit */
gidx -= 1; /* decrement gain quantizer index by 1 */
*gainq = lgpecb[idxord[gidx]] + elg; /* use next quantizer output*/
}
/* get true codebook index */
gidx = idxord[gidx];
/* update log-gain predictor memory */
prevlg[1] = prevlg[0];
prevlg[0] = *gainq;
for (i = LGPORDER - 1; i > 0; i--) {
lgpm[i] = lgpm[i-1];
}
lgpm[0] = lgpecb[gidx];
/* convert quantized log-gain to linear domain */
*gainq = pow(2.0F, 0.5F * *gainq);
return gidx;
}