blob: 8cbda521542edde4061ef3eab2e63601e044a30a [file] [log] [blame]
niklase@google.com470e71d2011-07-07 08:21:25 +00001/*
2 * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11/*
12 * This file contains the function for handling "normal" speech operation.
13 */
14#include "dsp.h"
15
16#include "signal_processing_library.h"
17
18#include "dsp_helpfunctions.h"
19
20/* Scratch usage:
21
22 Type Name size startpos endpos
pbos@webrtc.org0946a562013-04-09 00:28:06 +000023 int16_t pw16_expanded 125*fs/8000 0 125*fs/8000-1
niklase@google.com470e71d2011-07-07 08:21:25 +000024
25 func WebRtcNetEQ_Expand 40+370*fs/8000 125*fs/8000 39+495*fs/8000
26
27 Total: 40+495*fs/8000
28 */
29
30#define SCRATCH_PW16_EXPANDED 0
31#if (defined(NETEQ_48KHZ_WIDEBAND))
32#define SCRATCH_NETEQ_EXPAND 756
33#elif (defined(NETEQ_32KHZ_WIDEBAND))
34#define SCRATCH_NETEQ_EXPAND 504
35#elif (defined(NETEQ_WIDEBAND))
36#define SCRATCH_NETEQ_EXPAND 252
37#else /* NB */
38#define SCRATCH_NETEQ_EXPAND 126
39#endif
40
41/****************************************************************************
42 * WebRtcNetEQ_Normal(...)
43 *
44 * This function has the possibility to modify data that is played out in Normal
45 * mode, for example adjust the gain of the signal. The length of the signal
46 * can not be changed.
47 *
48 * Input:
49 * - inst : NetEq instance, i.e. the user that requests more
50 * speech/audio data
51 * - scratchPtr : Pointer to scratch vector
52 * - decoded : Pointer to vector of new data from decoder
53 * (Vector contents may be altered by the function)
54 * - len : Number of input samples
55 *
56 * Output:
57 * - inst : Updated user information
58 * - outData : Pointer to a memory space where the output data
59 * should be stored
60 * - pw16_len : Pointer to variable where the number of samples
61 * produced will be written
62 *
63 * Return value : >=0 - Number of samples written to outData
64 * -1 - Error
65 */
66
67int WebRtcNetEQ_Normal(DSPInst_t *inst,
68#ifdef SCRATCH
pbos@webrtc.org0946a562013-04-09 00:28:06 +000069 int16_t *pw16_scratchPtr,
niklase@google.com470e71d2011-07-07 08:21:25 +000070#endif
pbos@webrtc.org0946a562013-04-09 00:28:06 +000071 int16_t *pw16_decoded, int16_t len,
72 int16_t *pw16_outData, int16_t *pw16_len)
niklase@google.com470e71d2011-07-07 08:21:25 +000073{
74
75 int i;
pbos@webrtc.org0946a562013-04-09 00:28:06 +000076 int16_t fs_mult;
77 int16_t fs_shift;
78 int32_t w32_En_speech;
79 int16_t enLen;
80 int16_t w16_muted;
81 int16_t w16_inc, w16_frac;
82 int16_t w16_tmp;
83 int32_t w32_tmp;
niklase@google.com470e71d2011-07-07 08:21:25 +000084
85 /* Sanity check */
86 if (len < 0)
87 {
88 /* Cannot have negative length of input vector */
89 return (-1);
90 }
91
92 if (len == 0)
93 {
94 /* Still got some data to play => continue with the same mode */
95 *pw16_len = len;
96 return (len);
97 }
98
99 fs_mult = WebRtcSpl_DivW32W16ResW16(inst->fs, 8000);
100 fs_shift = 30 - WebRtcSpl_NormW32(fs_mult); /* Note that this is not "exact" for 48kHz */
101
102 /*
103 * Check if last RecOut call resulted in an Expand or a FadeToBGN. If so, we have to take
104 * care of some cross-fading and unmuting.
105 */
106 if (inst->w16_mode == MODE_EXPAND || inst->w16_mode == MODE_FADE_TO_BGN)
107 {
108
109 /* Define memory where temporary result from Expand algorithm can be stored. */
110#ifdef SCRATCH
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000111 int16_t *pw16_expanded = pw16_scratchPtr + SCRATCH_PW16_EXPANDED;
niklase@google.com470e71d2011-07-07 08:21:25 +0000112#else
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000113 int16_t pw16_expanded[FSMULT * 125];
niklase@google.com470e71d2011-07-07 08:21:25 +0000114#endif
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000115 int16_t expandedLen = 0;
116 int16_t w16_decodedMax;
niklase@google.com470e71d2011-07-07 08:21:25 +0000117
118 /* Find largest value in new data */
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000119 w16_decodedMax = WebRtcSpl_MaxAbsValueW16(pw16_decoded, (int16_t) len);
niklase@google.com470e71d2011-07-07 08:21:25 +0000120
121 /* Generate interpolation data using Expand */
122 /* First, set Expand parameters to appropriate values. */
123 inst->ExpandInst.w16_lagsPosition = 0;
124 inst->ExpandInst.w16_lagsDirection = 0;
125 inst->ExpandInst.w16_stopMuting = 1; /* Do not mute signal any more */
126
127 /* Call Expand */
128 WebRtcNetEQ_Expand(inst,
129#ifdef SCRATCH
130 pw16_scratchPtr + SCRATCH_NETEQ_EXPAND,
131#endif
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000132 pw16_expanded, &expandedLen, (int16_t) (inst->w16_mode == MODE_FADE_TO_BGN));
niklase@google.com470e71d2011-07-07 08:21:25 +0000133
134 inst->ExpandInst.w16_stopMuting = 0; /* Restore value */
135 inst->ExpandInst.w16_consecExp = 0; /* Last was not Expand any more */
136
137 /* Adjust muting factor (main muting factor times expand muting factor) */
138 if (inst->w16_mode == MODE_FADE_TO_BGN)
139 {
140 /* If last mode was FadeToBGN, the mute factor should be zero. */
141 inst->w16_muteFactor = 0;
142 }
143 else
144 {
145 /* w16_muteFactor * w16_expandMuteFactor */
146 inst->w16_muteFactor
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000147 = (int16_t) WEBRTC_SPL_MUL_16_16_RSFT(inst->w16_muteFactor,
niklase@google.com470e71d2011-07-07 08:21:25 +0000148 inst->ExpandInst.w16_expandMuteFactor, 14);
149 }
150
151 /* Adjust muting factor if needed (to BGN level) */
152 enLen = WEBRTC_SPL_MIN(fs_mult<<6, len); /* min( fs_mult * 64, len ) */
153 w16_tmp = 6 + fs_shift - WebRtcSpl_NormW32(
154 WEBRTC_SPL_MUL_16_16(w16_decodedMax, w16_decodedMax));
155 w16_tmp = WEBRTC_SPL_MAX(w16_tmp, 0);
156 w32_En_speech = WebRtcNetEQ_DotW16W16(pw16_decoded, pw16_decoded, enLen, w16_tmp);
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000157 w32_En_speech = WebRtcSpl_DivW32W16(w32_En_speech, (int16_t) (enLen >> w16_tmp));
niklase@google.com470e71d2011-07-07 08:21:25 +0000158
159 if ((w32_En_speech != 0) && (w32_En_speech > inst->BGNInst.w32_energy))
160 {
161 /* Normalize new frame energy to 15 bits */
162 w16_tmp = WebRtcSpl_NormW32(w32_En_speech) - 16;
163 /* we want inst->BGNInst.energy/En_speech in Q14 */
164 w32_tmp = WEBRTC_SPL_SHIFT_W32(inst->BGNInst.w32_energy, (w16_tmp+14));
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000165 w16_tmp = (int16_t) WEBRTC_SPL_SHIFT_W32(w32_En_speech, w16_tmp);
166 w16_tmp = (int16_t) WebRtcSpl_DivW32W16(w32_tmp, w16_tmp);
167 w16_muted = (int16_t) WebRtcSpl_SqrtFloor(
168 WEBRTC_SPL_LSHIFT_W32((int32_t) w16_tmp,
niklase@google.com470e71d2011-07-07 08:21:25 +0000169 14)); /* w16_muted in Q14 (sqrt(Q28)) */
170 }
171 else
172 {
173 w16_muted = 16384; /* 1.0 in Q14 */
174 }
175 if (w16_muted > inst->w16_muteFactor)
176 {
177 inst->w16_muteFactor = WEBRTC_SPL_MIN(w16_muted, 16384);
178 }
179
180 /* If muted increase by 0.64 for every 20 ms (NB/WB 0.0040/0.0020 in Q14) */
181 w16_inc = WebRtcSpl_DivW32W16ResW16(64, fs_mult);
182 for (i = 0; i < len; i++)
183 {
184 /* scale with mute factor */
185 w32_tmp = WEBRTC_SPL_MUL_16_16(pw16_decoded[i], inst->w16_muteFactor);
186 /* shift 14 with proper rounding */
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000187 pw16_decoded[i] = (int16_t) WEBRTC_SPL_RSHIFT_W32((w32_tmp + 8192), 14);
niklase@google.com470e71d2011-07-07 08:21:25 +0000188 /* increase mute_factor towards 16384 */
189 inst->w16_muteFactor = WEBRTC_SPL_MIN(16384, (inst->w16_muteFactor+w16_inc));
190 }
191
192 /*
193 * Interpolate the expanded data into the new vector
194 * (NB/WB/SWB32/SWB40 8/16/32/32 samples)
195 */
196 fs_shift = WEBRTC_SPL_MIN(3, fs_shift); /* Set to 3 for >32kHz */
197 w16_inc = 4 >> fs_shift;
198 w16_frac = w16_inc;
199 for (i = 0; i < 8 * fs_mult; i++)
200 {
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000201 pw16_decoded[i] = (int16_t) WEBRTC_SPL_RSHIFT_W32(
niklase@google.com470e71d2011-07-07 08:21:25 +0000202 (WEBRTC_SPL_MUL_16_16(w16_frac, pw16_decoded[i]) +
203 WEBRTC_SPL_MUL_16_16((32 - w16_frac), pw16_expanded[i]) + 8),
204 5);
205 w16_frac += w16_inc;
206 }
207
208#ifdef NETEQ_CNG_CODEC
209 }
210 else if (inst->w16_mode==MODE_RFC3389CNG)
211 { /* previous was RFC 3389 CNG...*/
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000212 int16_t pw16_CngInterp[32];
niklase@google.com470e71d2011-07-07 08:21:25 +0000213 /* Reset mute factor and start up fresh */
214 inst->w16_muteFactor = 16384;
215 if (inst->CNG_Codec_inst != NULL)
216 {
217 /* Generate long enough for 32kHz */
218 if(WebRtcCng_Generate(inst->CNG_Codec_inst,pw16_CngInterp, 32, 0)<0)
219 {
220 /* error returned; set return vector to all zeros */
221 WebRtcSpl_MemSetW16(pw16_CngInterp, 0, 32);
222 }
223 }
224 else
225 {
226 /*
227 * If no CNG instance is defined, just copy from the decoded data.
228 * (This will result in interpolating the decoded with itself.)
229 */
230 WEBRTC_SPL_MEMCPY_W16(pw16_CngInterp, pw16_decoded, fs_mult * 8);
231 }
232 /*
233 * Interpolate the CNG into the new vector
234 * (NB/WB/SWB32kHz/SWB48kHz 8/16/32/32 samples)
235 */
236 fs_shift = WEBRTC_SPL_MIN(3, fs_shift); /* Set to 3 for >32kHz */
237 w16_inc = 4>>fs_shift;
238 w16_frac = w16_inc;
239 for (i = 0; i < 8 * fs_mult; i++)
240 {
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000241 pw16_decoded[i] = (int16_t) WEBRTC_SPL_RSHIFT_W32(
niklase@google.com470e71d2011-07-07 08:21:25 +0000242 (WEBRTC_SPL_MUL_16_16(w16_frac, pw16_decoded[i]) +
243 WEBRTC_SPL_MUL_16_16((32-w16_frac), pw16_CngInterp[i]) + 8),
244 5);
245 w16_frac += w16_inc;
246 }
247#endif
248
249 }
250 else if (inst->w16_muteFactor < 16384)
251 {
252 /*
253 * Previous was neither of Expand, FadeToBGN or RFC3389_CNG, but we are still
254 * ramping up from previous muting.
255 * If muted increase by 0.64 for every 20 ms (NB/WB 0.0040/0.0020 in Q14)
256 */
257 w16_inc = WebRtcSpl_DivW32W16ResW16(64, fs_mult);
258 for (i = 0; i < len; i++)
259 {
260 /* scale with mute factor */
261 w32_tmp = WEBRTC_SPL_MUL_16_16(pw16_decoded[i], inst->w16_muteFactor);
262 /* shift 14 with proper rounding */
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000263 pw16_decoded[i] = (int16_t) WEBRTC_SPL_RSHIFT_W32((w32_tmp + 8192), 14);
niklase@google.com470e71d2011-07-07 08:21:25 +0000264 /* increase mute_factor towards 16384 */
265 inst->w16_muteFactor = WEBRTC_SPL_MIN(16384, (inst->w16_muteFactor+w16_inc));
266 }
267 }
268
269 /* Copy data to other buffer */WEBRTC_SPL_MEMMOVE_W16(pw16_outData, pw16_decoded, len);
270
271 inst->w16_mode = MODE_NORMAL;
272 *pw16_len = len;
273 return (len);
274
275}
276
277#undef SCRATCH_PW16_EXPANDED
278#undef SCRATCH_NETEQ_EXPAND
279