FreeCalypso > hg > gsm-codec-lib
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(<pGainHist[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 } |