comparison libtwamr/bgnscd.c @ 308:8dfb7cbe6b59

libtwamr: integrated up to bgnscd.c
author Mychaela Falconia <falcon@freecalypso.org>
date Tue, 16 Apr 2024 17:57:21 +0000
parents
children
comparison
equal deleted inserted replaced
307:6b33f3ba4289 308:8dfb7cbe6b59
1 /*************************************************************************
2 *
3 * GSM AMR-NB speech codec R98 Version 7.6.0 December 12, 2001
4 * R99 Version 3.3.0
5 * REL-4 Version 4.1.0
6 *
7 ********************************************************************************
8 *
9 * File : bgnscd.c
10 * Purpose : Background noise source charateristic detector (SCD)
11 *
12 ********************************************************************************
13 */
14
15 /*
16 ********************************************************************************
17 * MODULE INCLUDE FILE AND VERSION ID
18 ********************************************************************************
19 */
20 #include "namespace.h"
21 #include "bgnscd.h"
22
23 #include "typedef.h"
24 #include "basic_op.h"
25 #include "no_count.h"
26 #include "cnst.h"
27 #include "memops.h"
28 #include "gmed_n.h"
29 #include "sqrt_l.h"
30
31 /*
32 ********************************************************************************
33 * LOCAL VARIABLES AND TABLES
34 ********************************************************************************
35 */
36 /*-----------------------------------------------------------------*
37 * Decoder constant parameters (defined in "cnst.h") *
38 *-----------------------------------------------------------------*
39 * L_FRAME : Frame size. *
40 * L_SUBFR : Sub-frame size. *
41 *-----------------------------------------------------------------*/
42
43 /*
44 ********************************************************************************
45 * PUBLIC PROGRAM CODE
46 ********************************************************************************
47 */
48 /*
49 **************************************************************************
50 *
51 * Function : Bgn_scd_reset
52 * Purpose : Resets state memory
53 *
54 **************************************************************************
55 */
56 void Bgn_scd_reset (Bgn_scdState *state)
57 {
58 /* Static vectors to zero */
59 Set_zero (state->frameEnergyHist, L_ENERGYHIST);
60
61 /* Initialize hangover handling */
62 state->bgHangover = 0;
63 }
64
65 /*
66 **************************************************************************
67 *
68 * Function : Bgn_scd
69 * Purpose : Charaterice synthesis speech and detect background noise
70 * Returns : background noise decision; 0 = no bgn, 1 = bgn
71 *
72 **************************************************************************
73 */
74 Word16 Bgn_scd (Bgn_scdState *st, /* i : State variables for bgn SCD */
75 Word16 ltpGainHist[], /* i : LTP gain history */
76 Word16 speech[], /* o : synthesis speech frame */
77 Word16 *voicedHangover /* o : # of frames after last
78 voiced frame */
79 )
80 {
81 Word16 i;
82 Word16 prevVoiced, inbgNoise;
83 Word16 temp;
84 Word16 ltpLimit, frameEnergyMin;
85 Word16 currEnergy, noiseFloor, maxEnergy, maxEnergyLastPart;
86 Word32 s;
87
88 /* Update the inBackgroundNoise flag (valid for use in next frame if BFI) */
89 /* it now works as a energy detector floating on top */
90 /* not as good as a VAD. */
91
92 currEnergy = 0; move16 ();
93 s = (Word32) 0; move32 ();
94
95 for (i = 0; i < L_FRAME; i++)
96 {
97 s = L_mac (s, speech[i], speech[i]);
98 }
99
100 s = L_shl(s, 2);
101
102 currEnergy = extract_h (s);
103
104 frameEnergyMin = 32767; move16 ();
105
106 for (i = 0; i < L_ENERGYHIST; i++)
107 {
108 test ();
109 if (sub(st->frameEnergyHist[i], frameEnergyMin) < 0)
110 frameEnergyMin = st->frameEnergyHist[i]; move16 ();
111 }
112
113 noiseFloor = shl (frameEnergyMin, 4); /* Frame Energy Margin of 16 */
114
115 maxEnergy = st->frameEnergyHist[0]; move16 ();
116 for (i = 1; i < L_ENERGYHIST-4; i++)
117 {
118 test ();
119 if ( sub (maxEnergy, st->frameEnergyHist[i]) < 0)
120 {
121 maxEnergy = st->frameEnergyHist[i]; move16 ();
122 }
123 }
124
125 maxEnergyLastPart = st->frameEnergyHist[2*L_ENERGYHIST/3]; move16 ();
126 for (i = 2*L_ENERGYHIST/3+1; i < L_ENERGYHIST; i++)
127 {
128 test ();
129 if ( sub (maxEnergyLastPart, st->frameEnergyHist[i] ) < 0)
130 {
131 maxEnergyLastPart = st->frameEnergyHist[i]; move16 ();
132 }
133 }
134
135 inbgNoise = 0; /* false */ move16 ();
136
137 /* Do not consider silence as noise */
138 /* Do not consider continuous high volume as noise */
139 /* Or if the current noise level is very low */
140 /* Mark as noise if under current noise limit */
141 /* OR if the maximum energy is below the upper limit */
142
143 test (); test (); test (); test (); test ();
144 if ( (sub(maxEnergy, LOWERNOISELIMIT) > 0) &&
145 (sub(currEnergy, FRAMEENERGYLIMIT) < 0) &&
146 (sub(currEnergy, LOWERNOISELIMIT) > 0) &&
147 ( (sub(currEnergy, noiseFloor) < 0) ||
148 (sub(maxEnergyLastPart, UPPERNOISELIMIT) < 0)))
149 {
150 test ();
151 if (sub(add(st->bgHangover, 1), 30) > 0)
152 {
153 st->bgHangover = 30; move16 ();
154 } else
155 {
156 st->bgHangover = add(st->bgHangover, 1);
157 }
158 }
159 else
160 {
161 st->bgHangover = 0; move16 ();
162 }
163
164 /* make final decision about frame state , act somewhat cautiosly */
165 test ();
166 if (sub(st->bgHangover,1) > 0)
167 inbgNoise = 1; /* true */ move16 ();
168
169 for (i = 0; i < L_ENERGYHIST-1; i++)
170 {
171 st->frameEnergyHist[i] = st->frameEnergyHist[i+1]; move16 ();
172 }
173 st->frameEnergyHist[L_ENERGYHIST-1] = currEnergy; move16 ();
174
175 /* prepare for voicing decision; tighten the threshold after some
176 time in noise */
177 ltpLimit = 13926; /* 0.85 Q14 */ move16 ();
178 test ();
179 if (sub(st->bgHangover, 8) > 0)
180 {
181 ltpLimit = 15565; /* 0.95 Q14 */ move16 ();
182 }
183 test ();
184 if (sub(st->bgHangover, 15) > 0)
185 {
186 ltpLimit = 16383; /* 1.00 Q14 */ move16 ();
187 }
188
189 /* weak sort of voicing indication. */
190 prevVoiced = 0; /* false */ move16 ();
191 test ();
192
193 if (sub(gmed_n(&ltpGainHist[4], 5), ltpLimit) > 0)
194 {
195 prevVoiced = 1; /* true */ move16 ();
196 }
197 test ();
198 if (sub(st->bgHangover, 20) > 0) {
199 if (sub(gmed_n(ltpGainHist, 9), ltpLimit) > 0)
200 {
201 prevVoiced = 1; /* true */ move16 ();
202 }
203 else
204 {
205 prevVoiced = 0; /* false */ move16 ();
206 }
207 }
208
209 test ();
210 if (prevVoiced)
211 {
212 *voicedHangover = 0; move16 ();
213 }
214 else
215 {
216 temp = add(*voicedHangover, 1);
217 test ();
218 if (sub(temp, 10) > 0)
219 {
220 *voicedHangover = 10; move16 ();
221 }
222 else
223 {
224 *voicedHangover = temp; move16 ();
225 }
226 }
227
228 return inbgNoise;
229 }