blob: a345a8fdcd2f8b99e59e8337cc806452133e6d9e [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 Accelerate algorithm that is used to reduce
13 * the delay by removing a part of the audio stream.
14 */
15
16#include "dsp.h"
17
18#include "signal_processing_library.h"
19
20#include "dsp_helpfunctions.h"
21#include "neteq_error_codes.h"
22
23#define ACCELERATE_CORR_LEN 50
24#define ACCELERATE_MIN_LAG 10
25#define ACCELERATE_MAX_LAG 60
26#define ACCELERATE_DOWNSAMPLED_LEN (ACCELERATE_CORR_LEN + ACCELERATE_MAX_LAG)
27
28/* Scratch usage:
29
30 Type Name size startpos endpos
pbos@webrtc.org0946a562013-04-09 00:28:06 +000031 int16_t pw16_downSampSpeech 110 0 109
32 int32_t pw32_corr 2*50 110 209
33 int16_t pw16_corr 50 0 49
niklase@google.com470e71d2011-07-07 08:21:25 +000034
35 Total: 110+2*50
36 */
37
38#define SCRATCH_PW16_DS_SPEECH 0
39#define SCRATCH_PW32_CORR ACCELERATE_DOWNSAMPLED_LEN
40#define SCRATCH_PW16_CORR 0
41
42/****************************************************************************
43 * WebRtcNetEQ_Accelerate(...)
44 *
45 * This function tries to shorten the audio data by removing one or several
46 * pitch periods. The operation is only carried out if the correlation is
47 * strong or if the signal energy is very low.
48 *
49 * Input:
50 * - inst : NetEQ DSP instance
51 * - scratchPtr : Pointer to scratch vector.
52 * - decoded : Pointer to newly decoded speech.
53 * - len : Length of decoded speech.
54 * - BGNonly : If non-zero, Accelerate will only remove the last
55 * DEFAULT_TIME_ADJUST seconds of the input.
56 * No signal matching is done.
57 *
58 * Output:
59 * - inst : Updated instance
60 * - outData : Pointer to a memory space where the output data
61 * should be stored
62 * - pw16_len : Number of samples written to outData.
63 *
64 * Return value : 0 - Ok
65 * <0 - Error
66 */
67
68int WebRtcNetEQ_Accelerate(DSPInst_t *inst,
69#ifdef SCRATCH
pbos@webrtc.org0946a562013-04-09 00:28:06 +000070 int16_t *pw16_scratchPtr,
niklase@google.com470e71d2011-07-07 08:21:25 +000071#endif
pbos@webrtc.org0946a562013-04-09 00:28:06 +000072 const int16_t *pw16_decoded, int len,
73 int16_t *pw16_outData, int16_t *pw16_len,
74 int16_t BGNonly)
niklase@google.com470e71d2011-07-07 08:21:25 +000075{
76
77#ifdef SCRATCH
78 /* Use scratch memory for internal temporary vectors */
pbos@webrtc.org0946a562013-04-09 00:28:06 +000079 int16_t *pw16_downSampSpeech = pw16_scratchPtr + SCRATCH_PW16_DS_SPEECH;
80 int32_t *pw32_corr = (int32_t*) (pw16_scratchPtr + SCRATCH_PW32_CORR);
81 int16_t *pw16_corr = pw16_scratchPtr + SCRATCH_PW16_CORR;
niklase@google.com470e71d2011-07-07 08:21:25 +000082#else
83 /* Allocate memory for temporary vectors */
pbos@webrtc.org0946a562013-04-09 00:28:06 +000084 int16_t pw16_downSampSpeech[ACCELERATE_DOWNSAMPLED_LEN];
85 int32_t pw32_corr[ACCELERATE_CORR_LEN];
86 int16_t pw16_corr[ACCELERATE_CORR_LEN];
niklase@google.com470e71d2011-07-07 08:21:25 +000087#endif
pbos@webrtc.org0946a562013-04-09 00:28:06 +000088 int16_t w16_decodedMax = 0;
89 int16_t w16_tmp;
90 int16_t w16_tmp2;
91 int32_t w32_tmp;
92 int32_t w32_tmp2;
niklase@google.com470e71d2011-07-07 08:21:25 +000093
pbos@webrtc.org0946a562013-04-09 00:28:06 +000094 const int16_t w16_startLag = ACCELERATE_MIN_LAG;
95 const int16_t w16_endLag = ACCELERATE_MAX_LAG;
96 const int16_t w16_corrLen = ACCELERATE_CORR_LEN;
97 const int16_t *pw16_vec1, *pw16_vec2;
98 int16_t *pw16_vectmp;
99 int16_t w16_inc, w16_startfact;
100 int16_t w16_bestIndex, w16_bestVal;
101 int16_t w16_VAD = 1;
102 int16_t fsMult;
103 int16_t fsMult120;
104 int32_t w32_en1, w32_en2, w32_cc;
105 int16_t w16_en1, w16_en2;
106 int16_t w16_en1Scale, w16_en2Scale;
107 int16_t w16_sqrtEn1En2;
108 int16_t w16_bestCorr = 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000109 int ok;
110
111#ifdef NETEQ_STEREO
112 MasterSlaveInfo *msInfo = inst->msInfo;
113#endif
114
115 fsMult = WebRtcNetEQ_CalcFsMult(inst->fs); /* Calculate fs/8000 */
116
117 /* Pre-calculate common multiplication with fsMult */
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000118 fsMult120 = (int16_t) WEBRTC_SPL_MUL_16_16(fsMult, 120); /* 15 ms */
niklase@google.com470e71d2011-07-07 08:21:25 +0000119
120 inst->ExpandInst.w16_consecExp = 0; /* Last was not expand any more */
121
122 /* Sanity check for len variable; must be (almost) 30 ms
123 (120*fsMult + max(bestIndex)) */
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000124 if (len < (int16_t) WEBRTC_SPL_MUL_16_16((120 + 119), fsMult))
niklase@google.com470e71d2011-07-07 08:21:25 +0000125 {
126 /* Length of decoded data too short */
127 inst->w16_mode = MODE_UNSUCCESS_ACCELERATE;
128 *pw16_len = len;
129
130 /* simply move all data from decoded to outData */
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000131 WEBRTC_SPL_MEMMOVE_W16(pw16_outData, pw16_decoded, (int16_t) len);
niklase@google.com470e71d2011-07-07 08:21:25 +0000132
133 return NETEQ_OTHER_ERROR;
134 }
135
136 /***********************************/
137 /* Special operations for BGN only */
138 /***********************************/
139
140 /* Check if "background noise only" flag is set */
141 if (BGNonly)
142 {
143 /* special operation for BGN only; simply remove a chunk of data */
144 w16_bestIndex = DEFAULT_TIME_ADJUST * WEBRTC_SPL_LSHIFT_W16(fsMult, 3); /* X*fs/1000 */
145
146 /* Sanity check for bestIndex */
147 if (w16_bestIndex > len)
148 { /* not good, do nothing instead */
149 inst->w16_mode = MODE_UNSUCCESS_ACCELERATE;
150 *pw16_len = len;
151
152 /* simply move all data from decoded to outData */
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000153 WEBRTC_SPL_MEMMOVE_W16(pw16_outData, pw16_decoded, (int16_t) len);
niklase@google.com470e71d2011-07-07 08:21:25 +0000154
155 return NETEQ_OTHER_ERROR;
156 }
157
158 /* set length parameter */
159 *pw16_len = len - w16_bestIndex; /* we remove bestIndex samples */
160
161 /* copy to output */
162 WEBRTC_SPL_MEMMOVE_W16(pw16_outData, pw16_decoded, *pw16_len);
163
164 /* set mode */
165 inst->w16_mode = MODE_LOWEN_ACCELERATE;
166
167 /* update statistics */
168 inst->statInst.accelerateLength += w16_bestIndex;
turaj@webrtc.org92d1f072013-04-15 16:52:04 +0000169 /* Short-term activity statistics. */
170 inst->activity_stats.accelerate_bgn_samples += w16_bestIndex;
niklase@google.com470e71d2011-07-07 08:21:25 +0000171
172 return 0;
173 } /* end of special code for BGN mode */
174
175#ifdef NETEQ_STEREO
176
177 /* Sanity for msInfo */
178 if (msInfo == NULL)
179 {
180 /* this should not happen here */
181 return MASTER_SLAVE_ERROR;
182 }
183
184 if (msInfo->msMode != NETEQ_SLAVE)
185 {
186 /* Find correlation lag only for non-slave instances */
187
188#endif
189
190 /****************************************************************/
191 /* Find the strongest correlation lag by downsampling to 4 kHz, */
192 /* calculating correlation for downsampled signal and finding */
193 /* the strongest correlation peak. */
194 /****************************************************************/
195
196 /* find maximum absolute value */
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000197 w16_decodedMax = WebRtcSpl_MaxAbsValueW16(pw16_decoded, (int16_t) len);
niklase@google.com470e71d2011-07-07 08:21:25 +0000198
199 /* downsample the decoded speech to 4 kHz */
200 ok = WebRtcNetEQ_DownSampleTo4kHz(pw16_decoded, len, inst->fs, pw16_downSampSpeech,
201 ACCELERATE_DOWNSAMPLED_LEN, 1 /* compensate delay*/);
202 if (ok != 0)
203 {
204 /* error */
205 inst->w16_mode = MODE_UNSUCCESS_ACCELERATE;
206 *pw16_len = len;
207 /* simply move all data from decoded to outData */
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000208 WEBRTC_SPL_MEMMOVE_W16(pw16_outData, pw16_decoded, (int16_t) len);
niklase@google.com470e71d2011-07-07 08:21:25 +0000209 return NETEQ_OTHER_ERROR;
210 }
211
212 /*
213 * Set scaling factor for cross correlation to protect against overflow
214 * (log2(50) => 6)
215 */
216 w16_tmp = 6 - WebRtcSpl_NormW32(WEBRTC_SPL_MUL_16_16(w16_decodedMax, w16_decodedMax));
217 w16_tmp = WEBRTC_SPL_MAX(0, w16_tmp);
218
219 /* Perform correlation from lag 10 to lag 60 in 4 kHz domain */
220 WebRtcNetEQ_CrossCorr(
221 pw32_corr, &pw16_downSampSpeech[w16_endLag],
222 &pw16_downSampSpeech[w16_endLag - w16_startLag], w16_corrLen,
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000223 (int16_t) (w16_endLag - w16_startLag), w16_tmp, -1);
niklase@google.com470e71d2011-07-07 08:21:25 +0000224
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000225 /* Normalize correlation to 14 bits and put in a int16_t vector */
niklase@google.com470e71d2011-07-07 08:21:25 +0000226 w32_tmp = WebRtcSpl_MaxAbsValueW32(pw32_corr, w16_corrLen);
227 w16_tmp = 17 - WebRtcSpl_NormW32(w32_tmp);
228 w16_tmp = WEBRTC_SPL_MAX(0, w16_tmp);
229
230 WebRtcSpl_VectorBitShiftW32ToW16(pw16_corr, w16_corrLen, pw32_corr, w16_tmp);
231
232#ifdef NETEQ_STEREO
233 } /* end if (msInfo->msMode != NETEQ_SLAVE) */
234
235 if ((msInfo->msMode == NETEQ_MASTER) || (msInfo->msMode == NETEQ_MONO))
236 {
237 /* Find the strongest correlation peak by using the parabolic fit method */
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000238 WebRtcNetEQ_PeakDetection(pw16_corr, (int16_t) w16_corrLen, 1, fsMult,
niklase@google.com470e71d2011-07-07 08:21:25 +0000239 &w16_bestIndex, &w16_bestVal);
240 /* 0 <= bestIndex <= (2*corrLen - 1)*fsMult = 99*fsMult */
241
242 /* Compensate bestIndex for displaced starting position */
243 w16_bestIndex = w16_bestIndex + w16_startLag * WEBRTC_SPL_LSHIFT_W16(fsMult, 1);
244 /* 20*fsMult <= bestIndex <= 119*fsMult */
245
246 msInfo->bestIndex = w16_bestIndex;
247 }
248 else if (msInfo->msMode == NETEQ_SLAVE)
249 {
250 if (msInfo->extraInfo == ACC_FAIL)
251 {
252 /* Master has signaled an unsuccessful accelerate */
253 w16_bestIndex = 0;
254 }
255 else
256 {
257 /* Get best index from master */
258 w16_bestIndex = msInfo->bestIndex;
259 }
260 }
261 else
262 {
263 /* Invalid mode */
264 return MASTER_SLAVE_ERROR;
265 }
266
267#else /* NETEQ_STEREO */
268
269 /* Find the strongest correlation peak by using the parabolic fit method */
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000270 WebRtcNetEQ_PeakDetection(pw16_corr, (int16_t) w16_corrLen, 1, fsMult,
niklase@google.com470e71d2011-07-07 08:21:25 +0000271 &w16_bestIndex, &w16_bestVal);
272 /* 0 <= bestIndex <= (2*corrLen - 1)*fsMult = 99*fsMult */
273
274 /* Compensate bestIndex for displaced starting position */
275 w16_bestIndex = w16_bestIndex + w16_startLag * WEBRTC_SPL_LSHIFT_W16(fsMult, 1);
276 /* 20*fsMult <= bestIndex <= 119*fsMult */
277
278#endif /* NETEQ_STEREO */
279
280#ifdef NETEQ_STEREO
281
282 if (msInfo->msMode != NETEQ_SLAVE)
283 {
284 /* Calculate correlation only for non-slave instances */
285
286#endif /* NETEQ_STEREO */
287
288 /*****************************************************/
289 /* Calculate correlation bestCorr for the found lag. */
290 /* Also do a simple VAD decision. */
291 /*****************************************************/
292
293 /*
294 * Calculate scaling to ensure that bestIndex samples can be square-summed
295 * without overflowing
296 */
297 w16_tmp = (31
298 - WebRtcSpl_NormW32(WEBRTC_SPL_MUL_16_16(w16_decodedMax, w16_decodedMax)));
299 w16_tmp += (31 - WebRtcSpl_NormW32(w16_bestIndex));
300 w16_tmp -= 31;
301 w16_tmp = WEBRTC_SPL_MAX(0, w16_tmp);
302
303 /* vec1 starts at 15 ms minus one pitch period */
304 pw16_vec1 = &pw16_decoded[fsMult120 - w16_bestIndex];
305 /* vec2 start at 15 ms */
306 pw16_vec2 = &pw16_decoded[fsMult120];
307
308 /* Calculate energies for vec1 and vec2 */
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000309 w32_en1 = WebRtcNetEQ_DotW16W16((int16_t*) pw16_vec1,
310 (int16_t*) pw16_vec1, w16_bestIndex, w16_tmp);
311 w32_en2 = WebRtcNetEQ_DotW16W16((int16_t*) pw16_vec2,
312 (int16_t*) pw16_vec2, w16_bestIndex, w16_tmp);
niklase@google.com470e71d2011-07-07 08:21:25 +0000313
314 /* Calculate cross-correlation at the found lag */
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000315 w32_cc = WebRtcNetEQ_DotW16W16((int16_t*) pw16_vec1, (int16_t*) pw16_vec2,
niklase@google.com470e71d2011-07-07 08:21:25 +0000316 w16_bestIndex, w16_tmp);
317
318 /* Check VAD constraint
319 ((en1+en2)/(2*bestIndex)) <= 8*inst->BGNInst.energy */
320 w32_tmp = WEBRTC_SPL_RSHIFT_W32(w32_en1 + w32_en2, 4); /* (en1+en2)/(2*8) */
321 if (inst->BGNInst.w16_initialized == 1)
322 {
323 w32_tmp2 = inst->BGNInst.w32_energy;
324 }
325 else
326 {
327 /* if BGN parameters have not been estimated, use a fixed threshold */
328 w32_tmp2 = 75000;
329 }
330 w16_tmp2 = 16 - WebRtcSpl_NormW32(w32_tmp2);
331 w16_tmp2 = WEBRTC_SPL_MAX(0, w16_tmp2);
332 w32_tmp = WEBRTC_SPL_RSHIFT_W32(w32_tmp, w16_tmp2);
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000333 w16_tmp2 = (int16_t) WEBRTC_SPL_RSHIFT_W32(w32_tmp2, w16_tmp2);
niklase@google.com470e71d2011-07-07 08:21:25 +0000334 w32_tmp2 = WEBRTC_SPL_MUL_16_16(w16_bestIndex, w16_tmp2);
335
336 /* Scale w32_tmp properly before comparing with w32_tmp2 */
337 /* (w16_tmp is scaling before energy calculation, thus 2*w16_tmp) */
338 if (WebRtcSpl_NormW32(w32_tmp) < WEBRTC_SPL_LSHIFT_W32(w16_tmp,1))
339 {
340 /* Cannot scale only w32_tmp, must scale w32_temp2 too */
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000341 int16_t tempshift = WebRtcSpl_NormW32(w32_tmp);
niklase@google.com470e71d2011-07-07 08:21:25 +0000342 w32_tmp = WEBRTC_SPL_LSHIFT_W32(w32_tmp, tempshift);
343 w32_tmp2 = WEBRTC_SPL_RSHIFT_W32(w32_tmp2,
344 WEBRTC_SPL_LSHIFT_W32(w16_tmp,1) - tempshift);
345 }
346 else
347 {
348 w32_tmp = WEBRTC_SPL_LSHIFT_W32(w32_tmp,
349 WEBRTC_SPL_LSHIFT_W32(w16_tmp,1));
350 }
351
352 if (w32_tmp <= w32_tmp2) /*((en1+en2)/(2*bestIndex)) <= 8*inst->BGNInst.energy */
353 {
354 /* The signal seems to be passive speech */
355 w16_VAD = 0;
356 w16_bestCorr = 0; /* Correlation does not matter */
357 }
358 else
359 {
360 /* The signal is active speech */
361 w16_VAD = 1;
362
363 /* Calculate correlation (cc/sqrt(en1*en2)) */
364
365 /* Start with calculating scale values */
366 w16_en1Scale = 16 - WebRtcSpl_NormW32(w32_en1);
367 w16_en1Scale = WEBRTC_SPL_MAX(0, w16_en1Scale);
368 w16_en2Scale = 16 - WebRtcSpl_NormW32(w32_en2);
369 w16_en2Scale = WEBRTC_SPL_MAX(0, w16_en2Scale);
370
371 /* Make sure total scaling is even (to simplify scale factor after sqrt) */
372 if ((w16_en1Scale + w16_en2Scale) & 1)
373 {
374 w16_en1Scale += 1;
375 }
376
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000377 /* Convert energies to int16_t */
378 w16_en1 = (int16_t) WEBRTC_SPL_RSHIFT_W32(w32_en1, w16_en1Scale);
379 w16_en2 = (int16_t) WEBRTC_SPL_RSHIFT_W32(w32_en2, w16_en2Scale);
niklase@google.com470e71d2011-07-07 08:21:25 +0000380
381 /* Calculate energy product */
382 w32_tmp = WEBRTC_SPL_MUL_16_16(w16_en1, w16_en2);
383
384 /* Calculate square-root of energy product */
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000385 w16_sqrtEn1En2 = (int16_t) WebRtcSpl_SqrtFloor(w32_tmp);
niklase@google.com470e71d2011-07-07 08:21:25 +0000386
387 /* Calculate cc/sqrt(en1*en2) in Q14 */
388 w16_tmp = 14 - WEBRTC_SPL_RSHIFT_W16(w16_en1Scale+w16_en2Scale, 1);
389 w32_cc = WEBRTC_SPL_SHIFT_W32(w32_cc, w16_tmp);
390 w32_cc = WEBRTC_SPL_MAX(0, w32_cc); /* Don't divide with negative number */
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000391 w16_bestCorr = (int16_t) WebRtcSpl_DivW32W16(w32_cc, w16_sqrtEn1En2);
niklase@google.com470e71d2011-07-07 08:21:25 +0000392 w16_bestCorr = WEBRTC_SPL_MIN(16384, w16_bestCorr); /* set maximum to 1.0 */
393 }
394
395#ifdef NETEQ_STEREO
396
397 } /* end if (msInfo->msMode != NETEQ_SLAVE) */
398
399#endif /* NETEQ_STEREO */
400
401 /************************************************/
402 /* Check accelerate criteria and remove samples */
403 /************************************************/
404
405 /* Check for strong correlation (>0.9) or passive speech */
406#ifdef NETEQ_STEREO
407 if ((((w16_bestCorr > 14746) || (w16_VAD == 0)) && (msInfo->msMode != NETEQ_SLAVE))
408 || ((msInfo->msMode == NETEQ_SLAVE) && (msInfo->extraInfo != ACC_FAIL)))
409#else
410 if ((w16_bestCorr > 14746) || (w16_VAD == 0))
411#endif
412 {
413 /* Do accelerate operation by overlap add */
414
415 /*
416 * Calculate cross-fading slope so that the fading factor goes from
417 * 1 (16384 in Q14) to 0 in one pitch period (bestIndex).
418 */
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000419 w16_inc = (int16_t) WebRtcSpl_DivW32W16((int32_t) 16384,
420 (int16_t) (w16_bestIndex + 1)); /* in Q14 */
niklase@google.com470e71d2011-07-07 08:21:25 +0000421
422 /* Initiate fading factor */
423 w16_startfact = 16384 - w16_inc;
424
425 /* vec1 starts at 15 ms minus one pitch period */
426 pw16_vec1 = &pw16_decoded[fsMult120 - w16_bestIndex];
427 /* vec2 start at 15 ms */
428 pw16_vec2 = &pw16_decoded[fsMult120];
429
430 /* Copy unmodified part [0 to 15 ms minus 1 pitch period] */
431 w16_tmp = (fsMult120 - w16_bestIndex);
432 WEBRTC_SPL_MEMMOVE_W16(pw16_outData, pw16_decoded, w16_tmp);
433
434 /* Generate interpolated part of length bestIndex (1 pitch period) */
435 pw16_vectmp = pw16_outData + w16_tmp; /* start of interpolation output */
436 /* Reuse mixing function from Expand */
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000437 WebRtcNetEQ_MixVoiceUnvoice(pw16_vectmp, (int16_t*) pw16_vec1,
438 (int16_t*) pw16_vec2, &w16_startfact, w16_inc, w16_bestIndex);
niklase@google.com470e71d2011-07-07 08:21:25 +0000439
440 /* Move the last part (also unmodified) */
441 /* Take from decoded at 15 ms + 1 pitch period */
442 pw16_vec2 = &pw16_decoded[fsMult120 + w16_bestIndex];
443 WEBRTC_SPL_MEMMOVE_W16(&pw16_outData[fsMult120], pw16_vec2,
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000444 (int16_t) (len - fsMult120 - w16_bestIndex));
niklase@google.com470e71d2011-07-07 08:21:25 +0000445
446 /* Set the mode flag */
447 if (w16_VAD)
448 {
449 inst->w16_mode = MODE_SUCCESS_ACCELERATE;
450 }
451 else
452 {
453 inst->w16_mode = MODE_LOWEN_ACCELERATE;
454 }
455
456 /* Calculate resulting length = original length - pitch period */
457 *pw16_len = len - w16_bestIndex;
458
459 /* Update in-call statistics */
460 inst->statInst.accelerateLength += w16_bestIndex;
turaj@webrtc.org92d1f072013-04-15 16:52:04 +0000461 /* Short-term activity statistics. */
462 inst->activity_stats.accelarate_normal_samples += w16_bestIndex;
niklase@google.com470e71d2011-07-07 08:21:25 +0000463
464 return 0;
465 }
466 else
467 {
468 /* Accelerate not allowed */
469
470#ifdef NETEQ_STEREO
471 /* Signal to slave(s) that this was unsuccessful */
472 if (msInfo->msMode == NETEQ_MASTER)
473 {
474 msInfo->extraInfo = ACC_FAIL;
475 }
476#endif
477
478 /* Set mode flag to unsuccessful accelerate */
479 inst->w16_mode = MODE_UNSUCCESS_ACCELERATE;
480
481 /* Length is unmodified */
482 *pw16_len = len;
483
484 /* Simply move all data from decoded to outData */
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000485 WEBRTC_SPL_MEMMOVE_W16(pw16_outData, pw16_decoded, (int16_t) len);
niklase@google.com470e71d2011-07-07 08:21:25 +0000486
487 return 0;
488 }
489}
490
491#undef SCRATCH_PW16_DS_SPEECH
492#undef SCRATCH_PW32_CORR
493#undef SCRATCH_PW16_CORR