niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 1 | /* |
bjornv@webrtc.org | 152c34c | 2012-01-23 12:36:46 +0000 | [diff] [blame] | 2 | * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 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 some DSP initialization functions and |
| 13 | * constant table definitions. |
| 14 | */ |
| 15 | |
| 16 | #include "dsp.h" |
| 17 | |
| 18 | #include "signal_processing_library.h" |
| 19 | |
| 20 | #include "neteq_error_codes.h" |
| 21 | |
| 22 | /* Filter coefficients used when downsampling from the indicated |
| 23 | sample rates (8, 16, 32, 48 kHz) to 4 kHz. |
| 24 | Coefficients are in Q12. */ |
| 25 | |
| 26 | /* {0.3, 0.4, 0.3} */ |
pbos@webrtc.org | 0946a56 | 2013-04-09 00:28:06 +0000 | [diff] [blame] | 27 | const int16_t WebRtcNetEQ_kDownsample8kHzTbl[] = { 1229, 1638, 1229 }; |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 28 | |
| 29 | #ifdef NETEQ_WIDEBAND |
| 30 | /* {0.15, 0.2, 0.3, 0.2, 0.15} */ |
pbos@webrtc.org | 0946a56 | 2013-04-09 00:28:06 +0000 | [diff] [blame] | 31 | const int16_t WebRtcNetEQ_kDownsample16kHzTbl[] = |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 32 | { 614, 819, 1229, 819, 614}; |
| 33 | #endif |
| 34 | |
| 35 | #ifdef NETEQ_32KHZ_WIDEBAND |
| 36 | /* {0.1425, 0.1251, 0.1525, 0.1628, 0.1525, 0.1251, 0.1425} */ |
pbos@webrtc.org | 0946a56 | 2013-04-09 00:28:06 +0000 | [diff] [blame] | 37 | const int16_t WebRtcNetEQ_kDownsample32kHzTbl[] = |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 38 | { 584, 512, 625, 667, 625, 512, 584}; |
| 39 | #endif |
| 40 | |
| 41 | #ifdef NETEQ_48KHZ_WIDEBAND |
| 42 | /* {0.2487, 0.0952, 0.1042, 0.1074, 0.1042, 0.0952, 0.2487} */ |
pbos@webrtc.org | 0946a56 | 2013-04-09 00:28:06 +0000 | [diff] [blame] | 43 | const int16_t WebRtcNetEQ_kDownsample48kHzTbl[] = |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 44 | { 1019, 390, 427, 440, 427, 390, 1019}; |
| 45 | #endif |
| 46 | |
| 47 | /* Constants used in expand function WebRtcNetEQ_Expand */ |
| 48 | |
| 49 | /* Q12: -1.264421 + 4.8659148*x - 4.0092827*x^2 + 1.4100529*x^3 */ |
pbos@webrtc.org | 0946a56 | 2013-04-09 00:28:06 +0000 | [diff] [blame] | 50 | const int16_t WebRtcNetEQ_kMixFractionFuncTbl[4] = { -5179, 19931, -16422, 5776 }; |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 51 | |
| 52 | /* Tabulated divisions to save complexity */ |
| 53 | /* 1049/{0, .., 6} */ |
pbos@webrtc.org | 0946a56 | 2013-04-09 00:28:06 +0000 | [diff] [blame] | 54 | const int16_t WebRtcNetEQ_k1049div[7] = { 0, 1049, 524, 349, 262, 209, 174 }; |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 55 | |
| 56 | /* 2097/{0, .., 6} */ |
pbos@webrtc.org | 0946a56 | 2013-04-09 00:28:06 +0000 | [diff] [blame] | 57 | const int16_t WebRtcNetEQ_k2097div[7] = { 0, 2097, 1048, 699, 524, 419, 349 }; |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 58 | |
| 59 | /* 5243/{0, .., 6} */ |
pbos@webrtc.org | 0946a56 | 2013-04-09 00:28:06 +0000 | [diff] [blame] | 60 | const int16_t WebRtcNetEQ_k5243div[7] = { 0, 5243, 2621, 1747, 1310, 1048, 873 }; |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 61 | |
| 62 | #ifdef WEBRTC_NETEQ_40BITACC_TEST |
| 63 | /* |
| 64 | * Run NetEQ with simulated 40-bit accumulator to run bit-exact to a DSP |
| 65 | * implementation where the main (spl and NetEQ) functions have been |
| 66 | * 40-bit optimized. For testing purposes. |
| 67 | */ |
| 68 | |
| 69 | /**************************************************************************** |
| 70 | * WebRtcNetEQ_40BitAccCrossCorr(...) |
| 71 | * |
| 72 | * Calculates the Cross correlation between two sequences seq1 and seq2. Seq1 |
| 73 | * is fixed and seq2 slides as the pointer is increased with step |
| 74 | * |
| 75 | * Input: |
| 76 | * - seq1 : First sequence (fixed throughout the correlation) |
| 77 | * - seq2 : Second sequence (slided step_seq2 for each |
| 78 | * new correlation) |
| 79 | * - dimSeq : Number of samples to use in the cross correlation. |
| 80 | * Should be no larger than 1024 to avoid overflow. |
| 81 | * - dimCrossCorr : Number of CrossCorrelations to calculate (start |
| 82 | * position for seq2 is updated for each new one) |
| 83 | * - rShift : Number of right shifts to use |
| 84 | * - step_seq2 : How many (positive or negative) steps the seq2 |
| 85 | * pointer should be updated for each new cross |
| 86 | * correlation value |
| 87 | * |
| 88 | * Output: |
| 89 | * - crossCorr : The cross correlation in Q-rShift |
| 90 | */ |
| 91 | |
pbos@webrtc.org | 0946a56 | 2013-04-09 00:28:06 +0000 | [diff] [blame] | 92 | void WebRtcNetEQ_40BitAccCrossCorr(int32_t *crossCorr, |
| 93 | int16_t *seq1, |
| 94 | int16_t *seq2, |
| 95 | int16_t dimSeq, |
| 96 | int16_t dimCrossCorr, |
| 97 | int16_t rShift, |
| 98 | int16_t step_seq2) |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 99 | { |
| 100 | int i, j; |
pbos@webrtc.org | 0946a56 | 2013-04-09 00:28:06 +0000 | [diff] [blame] | 101 | int16_t *seq1Ptr, *seq2Ptr; |
| 102 | int64_t acc; |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 103 | |
| 104 | for (i = 0; i < dimCrossCorr; i++) |
| 105 | { |
| 106 | /* Set the pointer to the static vector, set the pointer to |
| 107 | the sliding vector and initialize crossCorr */ |
| 108 | seq1Ptr = seq1; |
| 109 | seq2Ptr = seq2 + (step_seq2 * i); |
| 110 | acc = 0; |
| 111 | |
| 112 | /* Perform the cross correlation */ |
| 113 | for (j = 0; j < dimSeq; j++) |
| 114 | { |
| 115 | acc += WEBRTC_SPL_MUL_16_16((*seq1Ptr), (*seq2Ptr)); |
| 116 | seq1Ptr++; |
| 117 | seq2Ptr++; |
| 118 | } |
| 119 | |
pbos@webrtc.org | 0946a56 | 2013-04-09 00:28:06 +0000 | [diff] [blame] | 120 | (*crossCorr) = (int32_t) (acc >> rShift); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 121 | crossCorr++; |
| 122 | } |
| 123 | } |
| 124 | |
| 125 | /**************************************************************************** |
| 126 | * WebRtcNetEQ_40BitAccDotW16W16(...) |
| 127 | * |
pbos@webrtc.org | 0946a56 | 2013-04-09 00:28:06 +0000 | [diff] [blame] | 128 | * Calculates the dot product between two vectors (int16_t) |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 129 | * |
| 130 | * Input: |
| 131 | * - vector1 : Vector 1 |
| 132 | * - vector2 : Vector 2 |
| 133 | * - len : Number of samples in vector |
| 134 | * Should be no larger than 1024 to avoid overflow. |
| 135 | * - scaling : The number of left shifts required to avoid overflow |
| 136 | * in the dot product |
| 137 | * Return value : The dot product |
| 138 | */ |
| 139 | |
pbos@webrtc.org | 0946a56 | 2013-04-09 00:28:06 +0000 | [diff] [blame] | 140 | int32_t WebRtcNetEQ_40BitAccDotW16W16(int16_t *vector1, |
| 141 | int16_t *vector2, |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 142 | int len, |
| 143 | int scaling) |
| 144 | { |
pbos@webrtc.org | 0946a56 | 2013-04-09 00:28:06 +0000 | [diff] [blame] | 145 | int32_t sum; |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 146 | int i; |
pbos@webrtc.org | 0946a56 | 2013-04-09 00:28:06 +0000 | [diff] [blame] | 147 | int64_t acc; |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 148 | |
| 149 | acc = 0; |
| 150 | for (i = 0; i < len; i++) |
| 151 | { |
| 152 | acc += WEBRTC_SPL_MUL_16_16(*vector1++, *vector2++); |
| 153 | } |
| 154 | |
pbos@webrtc.org | 0946a56 | 2013-04-09 00:28:06 +0000 | [diff] [blame] | 155 | sum = (int32_t) (acc >> scaling); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 156 | |
| 157 | return(sum); |
| 158 | } |
| 159 | |
| 160 | #endif /* WEBRTC_NETEQ_40BITACC_TEST */ |
| 161 | |
| 162 | /**************************************************************************** |
| 163 | * WebRtcNetEQ_DSPInit(...) |
| 164 | * |
| 165 | * Initializes DSP side of NetEQ. |
| 166 | * |
| 167 | * Input: |
| 168 | * - inst : NetEq DSP instance |
| 169 | * - fs : Initial sample rate (may change when decoding data) |
| 170 | * |
| 171 | * Output: |
| 172 | * - inst : Updated instance |
| 173 | * |
| 174 | * Return value : 0 - ok |
| 175 | * : non-zero - error |
| 176 | */ |
| 177 | |
pbos@webrtc.org | 0946a56 | 2013-04-09 00:28:06 +0000 | [diff] [blame] | 178 | int WebRtcNetEQ_DSPInit(DSPInst_t *inst, uint16_t fs) |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 179 | { |
| 180 | |
| 181 | int res = 0; |
pbos@webrtc.org | 0946a56 | 2013-04-09 00:28:06 +0000 | [diff] [blame] | 182 | int16_t fs_mult; |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 183 | |
| 184 | /* Pointers and values to save before clearing the instance */ |
| 185 | #ifdef NETEQ_CNG_CODEC |
| 186 | void *savedPtr1 = inst->CNG_Codec_inst; |
| 187 | #endif |
| 188 | void *savedPtr2 = inst->pw16_readAddress; |
| 189 | void *savedPtr3 = inst->pw16_writeAddress; |
| 190 | void *savedPtr4 = inst->main_inst; |
| 191 | #ifdef NETEQ_VAD |
| 192 | void *savedVADptr = inst->VADInst.VADState; |
| 193 | VADInitFunction savedVADinit = inst->VADInst.initFunction; |
| 194 | VADSetmodeFunction savedVADsetmode = inst->VADInst.setmodeFunction; |
| 195 | VADFunction savedVADfunc = inst->VADInst.VADFunction; |
pbos@webrtc.org | 0946a56 | 2013-04-09 00:28:06 +0000 | [diff] [blame] | 196 | int16_t savedVADEnabled = inst->VADInst.VADEnabled; |
bjornv@webrtc.org | b38fca1 | 2012-06-19 11:03:32 +0000 | [diff] [blame] | 197 | int savedVADMode = inst->VADInst.VADMode; |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 198 | #endif /* NETEQ_VAD */ |
| 199 | DSPStats_t saveStats; |
pbos@webrtc.org | 0946a56 | 2013-04-09 00:28:06 +0000 | [diff] [blame] | 200 | int16_t saveMsPerCall = inst->millisecondsPerCall; |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 201 | enum BGNMode saveBgnMode = inst->BGNInst.bgnMode; |
| 202 | #ifdef NETEQ_STEREO |
| 203 | MasterSlaveInfo saveMSinfo; |
| 204 | #endif |
| 205 | |
| 206 | /* copy contents of statInst to avoid clearing */WEBRTC_SPL_MEMCPY_W16(&saveStats, &(inst->statInst), |
pbos@webrtc.org | 0946a56 | 2013-04-09 00:28:06 +0000 | [diff] [blame] | 207 | sizeof(DSPStats_t)/sizeof(int16_t)); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 208 | |
| 209 | #ifdef NETEQ_STEREO |
| 210 | /* copy contents of msInfo to avoid clearing */WEBRTC_SPL_MEMCPY_W16(&saveMSinfo, &(inst->msInfo), |
pbos@webrtc.org | 0946a56 | 2013-04-09 00:28:06 +0000 | [diff] [blame] | 211 | sizeof(MasterSlaveInfo)/sizeof(int16_t)); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 212 | #endif |
| 213 | |
| 214 | /* check that the sample rate is valid */ |
| 215 | if ((fs != 8000) |
| 216 | #ifdef NETEQ_WIDEBAND |
| 217 | &&(fs!=16000) |
| 218 | #endif |
| 219 | #ifdef NETEQ_32KHZ_WIDEBAND |
| 220 | &&(fs!=32000) |
| 221 | #endif |
| 222 | #ifdef NETEQ_48KHZ_WIDEBAND |
| 223 | &&(fs!=48000) |
| 224 | #endif |
| 225 | ) |
| 226 | { |
| 227 | /* invalid rate */ |
| 228 | return (CODEC_DB_UNSUPPORTED_FS); |
| 229 | } |
| 230 | |
| 231 | /* calcualte fs/8000 */ |
| 232 | fs_mult = WebRtcSpl_DivW32W16ResW16(fs, 8000); |
| 233 | |
| 234 | /* Set everything to zero since most variables should be zero at start */ |
pbos@webrtc.org | 0946a56 | 2013-04-09 00:28:06 +0000 | [diff] [blame] | 235 | WebRtcSpl_MemSetW16((int16_t *) inst, 0, sizeof(DSPInst_t) / sizeof(int16_t)); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 236 | |
| 237 | /* Restore saved pointers */ |
| 238 | #ifdef NETEQ_CNG_CODEC |
| 239 | inst->CNG_Codec_inst = (CNG_dec_inst *)savedPtr1; |
| 240 | #endif |
pbos@webrtc.org | 0946a56 | 2013-04-09 00:28:06 +0000 | [diff] [blame] | 241 | inst->pw16_readAddress = (int16_t *) savedPtr2; |
| 242 | inst->pw16_writeAddress = (int16_t *) savedPtr3; |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 243 | inst->main_inst = savedPtr4; |
| 244 | #ifdef NETEQ_VAD |
| 245 | inst->VADInst.VADState = savedVADptr; |
| 246 | inst->VADInst.initFunction = savedVADinit; |
| 247 | inst->VADInst.setmodeFunction = savedVADsetmode; |
| 248 | inst->VADInst.VADFunction = savedVADfunc; |
| 249 | inst->VADInst.VADEnabled = savedVADEnabled; |
| 250 | inst->VADInst.VADMode = savedVADMode; |
| 251 | #endif /* NETEQ_VAD */ |
| 252 | |
| 253 | /* Initialize main part */ |
| 254 | inst->fs = fs; |
| 255 | inst->millisecondsPerCall = saveMsPerCall; |
| 256 | inst->timestampsPerCall = inst->millisecondsPerCall * 8 * fs_mult; |
| 257 | inst->ExpandInst.w16_overlap = 5 * fs_mult; |
| 258 | inst->endPosition = 565 * fs_mult; |
| 259 | inst->curPosition = inst->endPosition - inst->ExpandInst.w16_overlap; |
| 260 | inst->w16_seedInc = 1; |
| 261 | inst->uw16_seed = 777; |
| 262 | inst->w16_muteFactor = 16384; /* 1.0 in Q14 */ |
| 263 | inst->w16_frameLen = 3 * inst->timestampsPerCall; /* Dummy initialize to 30ms */ |
| 264 | |
| 265 | inst->w16_speechHistoryLen = 256 * fs_mult; |
| 266 | inst->pw16_speechHistory = &inst->speechBuffer[inst->endPosition |
| 267 | - inst->w16_speechHistoryLen]; |
| 268 | inst->ExpandInst.pw16_overlapVec = &(inst->pw16_speechHistory[inst->w16_speechHistoryLen |
| 269 | - inst->ExpandInst.w16_overlap]); |
| 270 | |
| 271 | /* Reusage of memory in speechBuffer inside Expand */ |
| 272 | inst->ExpandInst.pw16_expVecs[0] = &inst->speechBuffer[0]; |
| 273 | inst->ExpandInst.pw16_expVecs[1] = &inst->speechBuffer[126 * fs_mult]; |
| 274 | inst->ExpandInst.pw16_arState = &inst->speechBuffer[2 * 126 * fs_mult]; |
| 275 | inst->ExpandInst.pw16_arFilter = &inst->speechBuffer[2 * 126 * fs_mult |
| 276 | + UNVOICED_LPC_ORDER]; |
| 277 | /* Ends at 2*126*fs_mult+UNVOICED_LPC_ORDER+(UNVOICED_LPC_ORDER+1) */ |
| 278 | |
| 279 | inst->ExpandInst.w16_expandMuteFactor = 16384; /* 1.0 in Q14 */ |
| 280 | |
| 281 | /* Initialize BGN part */ |
| 282 | inst->BGNInst.pw16_filter[0] = 4096; |
| 283 | inst->BGNInst.w16_scale = 20000; |
| 284 | inst->BGNInst.w16_scaleShift = 24; |
| 285 | inst->BGNInst.w32_energyUpdate = 500000; |
| 286 | inst->BGNInst.w32_energyUpdateLow = 0; |
| 287 | inst->BGNInst.w32_energy = 2500; |
| 288 | inst->BGNInst.w16_initialized = 0; |
| 289 | inst->BGNInst.bgnMode = saveBgnMode; |
| 290 | |
| 291 | /* Recreate statistics counters */WEBRTC_SPL_MEMCPY_W16(&(inst->statInst), &saveStats, |
pbos@webrtc.org | 0946a56 | 2013-04-09 00:28:06 +0000 | [diff] [blame] | 292 | sizeof(DSPStats_t)/sizeof(int16_t)); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 293 | |
| 294 | #ifdef NETEQ_STEREO |
| 295 | /* Recreate MSinfo */WEBRTC_SPL_MEMCPY_W16(&(inst->msInfo), &saveMSinfo, |
pbos@webrtc.org | 0946a56 | 2013-04-09 00:28:06 +0000 | [diff] [blame] | 296 | sizeof(MasterSlaveInfo)/sizeof(int16_t)); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 297 | #endif |
| 298 | |
| 299 | #ifdef NETEQ_CNG_CODEC |
| 300 | if (inst->CNG_Codec_inst!=NULL) |
| 301 | { |
| 302 | /* initialize comfort noise generator */ |
| 303 | res |= WebRtcCng_InitDec(inst->CNG_Codec_inst); |
| 304 | } |
| 305 | #endif |
| 306 | |
| 307 | #ifdef NETEQ_VAD |
| 308 | /* initialize PostDecode VAD instance |
| 309 | (don't bother checking for NULL instance, this is done inside init function) */ |
| 310 | res |= WebRtcNetEQ_InitVAD(&inst->VADInst, fs); |
| 311 | #endif /* NETEQ_VAD */ |
| 312 | |
| 313 | return (res); |
| 314 | } |
| 315 | |
| 316 | /**************************************************************************** |
| 317 | * WebRtcNetEQ_AddressInit(...) |
| 318 | * |
| 319 | * Initializes the shared-memory communication on the DSP side. |
| 320 | * |
| 321 | * Input: |
| 322 | * - inst : NetEQ DSP instance |
| 323 | * - data2McuAddress : Pointer to memory where DSP writes / MCU reads |
| 324 | * - data2DspAddress : Pointer to memory where MCU writes / DSP reads |
| 325 | * - mainInst : NetEQ main instance |
| 326 | * |
| 327 | * Output: |
| 328 | * - inst : Updated instance |
| 329 | * |
| 330 | * Return value : 0 - ok |
| 331 | */ |
| 332 | |
| 333 | int WebRtcNetEQ_AddressInit(DSPInst_t *inst, const void *data2McuAddress, |
| 334 | const void *data2DspAddress, const void *mainInst) |
| 335 | { |
| 336 | |
| 337 | /* set shared-memory addresses in the DSP instance */ |
pbos@webrtc.org | 0946a56 | 2013-04-09 00:28:06 +0000 | [diff] [blame] | 338 | inst->pw16_readAddress = (int16_t *) data2DspAddress; |
| 339 | inst->pw16_writeAddress = (int16_t *) data2McuAddress; |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 340 | |
| 341 | /* set pointer to main NetEQ instance */ |
| 342 | inst->main_inst = (void *) mainInst; |
| 343 | |
| 344 | /* set output frame size to 10 ms = 80 samples in narrowband */ |
| 345 | inst->millisecondsPerCall = 10; |
| 346 | inst->timestampsPerCall = 80; |
| 347 | |
| 348 | return (0); |
| 349 | |
| 350 | } |
| 351 | |
| 352 | /**************************************************************************** |
| 353 | * NETEQDSP_clearInCallStats(...) |
| 354 | * |
| 355 | * Reset in-call statistics variables on DSP side. |
| 356 | * |
| 357 | * Input: |
| 358 | * - inst : NetEQ DSP instance |
| 359 | * |
| 360 | * Output: |
| 361 | * - inst : Updated instance |
| 362 | * |
| 363 | * Return value : 0 - ok |
| 364 | */ |
| 365 | |
| 366 | int WebRtcNetEQ_ClearInCallStats(DSPInst_t *inst) |
| 367 | { |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 368 | /* Reset statistics counters */ |
| 369 | inst->statInst.accelerateLength = 0; |
| 370 | inst->statInst.expandLength = 0; |
| 371 | inst->statInst.preemptiveLength = 0; |
roosa@google.com | b8ba4d8 | 2012-12-14 00:06:18 +0000 | [diff] [blame] | 372 | inst->statInst.addedSamples = 0; |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 373 | return (0); |
| 374 | } |
| 375 | |
| 376 | /**************************************************************************** |
| 377 | * WebRtcNetEQ_ClearPostCallStats(...) |
| 378 | * |
| 379 | * Reset post-call statistics variables on DSP side. |
| 380 | * |
| 381 | * Input: |
| 382 | * - inst : NetEQ DSP instance |
| 383 | * |
| 384 | * Output: |
| 385 | * - inst : Updated instance |
| 386 | * |
| 387 | * Return value : 0 - ok |
| 388 | */ |
| 389 | |
| 390 | int WebRtcNetEQ_ClearPostCallStats(DSPInst_t *inst) |
| 391 | { |
| 392 | |
| 393 | /* Reset statistics counters */ |
| 394 | inst->statInst.expandedVoiceSamples = 0; |
| 395 | inst->statInst.expandedNoiseSamples = 0; |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 396 | return (0); |
| 397 | } |
| 398 | |
turaj@webrtc.org | 92d1f07 | 2013-04-15 16:52:04 +0000 | [diff] [blame^] | 399 | /**************************************************************************** |
| 400 | * WebRtcNetEQ_ClearActivityStats(...) |
| 401 | * |
| 402 | * Reset processing activity statistics. |
| 403 | * |
| 404 | * Input: |
| 405 | * - inst : NetEQ DSP instance |
| 406 | * |
| 407 | * Output: |
| 408 | * - inst : Updated instance |
| 409 | * |
| 410 | */ |
| 411 | |
| 412 | void WebRtcNetEQ_ClearActivityStats(DSPInst_t *inst) { |
| 413 | memset(&inst->activity_stats, 0, sizeof(ActivityStats)); |
| 414 | } |
| 415 | |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 416 | #ifdef NETEQ_VAD |
| 417 | |
| 418 | /**************************************************************************** |
| 419 | * WebRtcNetEQ_InitVAD(...) |
| 420 | * |
| 421 | * Initializes post-decode VAD instance. |
| 422 | * |
| 423 | * Input: |
| 424 | * - VADinst : PostDecodeVAD instance |
| 425 | * - fs : Initial sample rate |
| 426 | * |
| 427 | * Output: |
| 428 | * - VADinst : Updated instance |
| 429 | * |
| 430 | * Return value : 0 - Ok |
| 431 | * -1 - Error |
| 432 | */ |
| 433 | |
pbos@webrtc.org | 0946a56 | 2013-04-09 00:28:06 +0000 | [diff] [blame] | 434 | int WebRtcNetEQ_InitVAD(PostDecodeVAD_t *VADInst, uint16_t fs) |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 435 | { |
| 436 | |
| 437 | int res = 0; |
| 438 | |
| 439 | /* initially, disable the post-decode VAD */ |
| 440 | VADInst->VADEnabled = 0; |
| 441 | |
| 442 | if (VADInst->VADState != NULL /* if VAD state is provided */ |
| 443 | && VADInst->initFunction != NULL /* and all function ... */ |
| 444 | && VADInst->setmodeFunction != NULL /* ... pointers ... */ |
| 445 | && VADInst->VADFunction != NULL) /* ... are defined */ |
| 446 | { |
bjornv@webrtc.org | ab2bb82 | 2012-01-18 14:51:02 +0000 | [diff] [blame] | 447 | res = VADInst->initFunction( VADInst->VADState ); /* call VAD init function */ |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 448 | res |= WebRtcNetEQ_SetVADModeInternal( VADInst, VADInst->VADMode ); |
| 449 | |
| 450 | if (res!=0) |
| 451 | { |
| 452 | /* something is wrong; play it safe and set the VADstate to NULL */ |
| 453 | VADInst->VADState = NULL; |
| 454 | } |
| 455 | else if (fs<=16000) |
| 456 | { |
| 457 | /* enable VAD if NB or WB (VAD cannot handle SWB) */ |
| 458 | VADInst->VADEnabled = 1; |
| 459 | } |
| 460 | } |
| 461 | |
| 462 | /* reset SID/CNG interval counter */ |
| 463 | VADInst->SIDintervalCounter = 0; |
| 464 | |
| 465 | /* initialize with active-speaker decision */ |
| 466 | VADInst->VADDecision = 1; |
| 467 | |
| 468 | return(res); |
| 469 | |
| 470 | } |
| 471 | |
| 472 | /**************************************************************************** |
| 473 | * WebRtcNetEQ_SetVADModeInternal(...) |
| 474 | * |
| 475 | * Set the VAD mode in the VAD struct, and communicate it to the VAD instance |
| 476 | * if it exists. |
| 477 | * |
| 478 | * Input: |
| 479 | * - VADinst : PostDecodeVAD instance |
| 480 | * - mode : Mode number passed on to the VAD function |
| 481 | * |
| 482 | * Output: |
| 483 | * - VADinst : Updated instance |
| 484 | * |
| 485 | * Return value : 0 - Ok |
| 486 | * -1 - Error |
| 487 | */ |
| 488 | |
bjornv@webrtc.org | f4b77fd | 2012-01-25 12:40:00 +0000 | [diff] [blame] | 489 | int WebRtcNetEQ_SetVADModeInternal(PostDecodeVAD_t *VADInst, int mode) |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 490 | { |
| 491 | |
| 492 | int res = 0; |
| 493 | |
| 494 | VADInst->VADMode = mode; |
| 495 | |
| 496 | if (VADInst->VADState != NULL) |
| 497 | { |
| 498 | /* call setmode function */ |
bjornv@webrtc.org | 152c34c | 2012-01-23 12:36:46 +0000 | [diff] [blame] | 499 | res = VADInst->setmodeFunction(VADInst->VADState, mode); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 500 | } |
| 501 | |
| 502 | return(res); |
| 503 | |
| 504 | } |
| 505 | |
| 506 | #endif /* NETEQ_VAD */ |
| 507 | |
| 508 | /**************************************************************************** |
| 509 | * WebRtcNetEQ_FlushSpeechBuffer(...) |
| 510 | * |
| 511 | * Flush the speech buffer. |
| 512 | * |
| 513 | * Input: |
| 514 | * - inst : NetEq DSP instance |
| 515 | * |
| 516 | * Output: |
| 517 | * - inst : Updated instance |
| 518 | * |
| 519 | * Return value : 0 - ok |
| 520 | * : non-zero - error |
| 521 | */ |
| 522 | |
| 523 | int WebRtcNetEQ_FlushSpeechBuffer(DSPInst_t *inst) |
| 524 | { |
pbos@webrtc.org | 0946a56 | 2013-04-09 00:28:06 +0000 | [diff] [blame] | 525 | int16_t fs_mult; |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 526 | |
| 527 | /* calcualte fs/8000 */ |
| 528 | fs_mult = WebRtcSpl_DivW32W16ResW16(inst->fs, 8000); |
| 529 | |
| 530 | /* clear buffer */ |
| 531 | WebRtcSpl_MemSetW16(inst->speechBuffer, 0, SPEECH_BUF_SIZE); |
| 532 | inst->endPosition = 565 * fs_mult; |
| 533 | inst->curPosition = inst->endPosition - inst->ExpandInst.w16_overlap; |
| 534 | |
| 535 | return 0; |
| 536 | } |
| 537 | |