|  | /* | 
|  | *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. | 
|  | * | 
|  | *  Use of this source code is governed by a BSD-style license | 
|  | *  that can be found in the LICENSE file in the root of the source | 
|  | *  tree. An additional intellectual property rights grant can be found | 
|  | *  in the file PATENTS.  All contributing project authors may | 
|  | *  be found in the AUTHORS file in the root of the source tree. | 
|  | */ | 
|  |  | 
|  | /* | 
|  | * This file contains the function for handling "normal" speech operation. | 
|  | */ | 
|  | #include "dsp.h" | 
|  |  | 
|  | #include "signal_processing_library.h" | 
|  |  | 
|  | #include "dsp_helpfunctions.h" | 
|  |  | 
|  | /* Scratch usage: | 
|  |  | 
|  | Type           Name                    size            startpos        endpos | 
|  | int16_t  pw16_expanded           125*fs/8000     0               125*fs/8000-1 | 
|  |  | 
|  | func           WebRtcNetEQ_Expand      40+370*fs/8000  125*fs/8000     39+495*fs/8000 | 
|  |  | 
|  | Total:  40+495*fs/8000 | 
|  | */ | 
|  |  | 
|  | #define     SCRATCH_PW16_EXPANDED           0 | 
|  | #if (defined(NETEQ_48KHZ_WIDEBAND)) | 
|  | #define     SCRATCH_NETEQ_EXPAND    756 | 
|  | #elif (defined(NETEQ_32KHZ_WIDEBAND)) | 
|  | #define     SCRATCH_NETEQ_EXPAND    504 | 
|  | #elif (defined(NETEQ_WIDEBAND)) | 
|  | #define     SCRATCH_NETEQ_EXPAND    252 | 
|  | #else    /* NB */ | 
|  | #define     SCRATCH_NETEQ_EXPAND    126 | 
|  | #endif | 
|  |  | 
|  | /**************************************************************************** | 
|  | * WebRtcNetEQ_Normal(...) | 
|  | * | 
|  | * This function has the possibility to modify data that is played out in Normal | 
|  | * mode, for example adjust the gain of the signal. The length of the signal | 
|  | * can not be changed. | 
|  | * | 
|  | * Input: | 
|  | *      - inst          : NetEq instance, i.e. the user that requests more | 
|  | *                        speech/audio data | 
|  | *      - scratchPtr    : Pointer to scratch vector | 
|  | *      - decoded       : Pointer to vector of new data from decoder | 
|  | *                        (Vector contents may be altered by the function) | 
|  | *      - len           : Number of input samples | 
|  | * | 
|  | * Output: | 
|  | *      - inst          : Updated user information | 
|  | *      - outData       : Pointer to a memory space where the output data | 
|  | *                        should be stored | 
|  | *      - pw16_len      : Pointer to variable where the number of samples | 
|  | *                        produced will be written | 
|  | * | 
|  | * Return value         : >=0 - Number of samples written to outData | 
|  | *                         -1 - Error | 
|  | */ | 
|  |  | 
|  | int WebRtcNetEQ_Normal(DSPInst_t *inst, | 
|  | #ifdef SCRATCH | 
|  | int16_t *pw16_scratchPtr, | 
|  | #endif | 
|  | int16_t *pw16_decoded, int16_t len, | 
|  | int16_t *pw16_outData, int16_t *pw16_len) | 
|  | { | 
|  |  | 
|  | int i; | 
|  | int16_t fs_mult; | 
|  | int16_t fs_shift; | 
|  | int32_t w32_En_speech; | 
|  | int16_t enLen; | 
|  | int16_t w16_muted; | 
|  | int16_t w16_inc, w16_frac; | 
|  | int16_t w16_tmp; | 
|  | int32_t w32_tmp; | 
|  |  | 
|  | /* Sanity check */ | 
|  | if (len < 0) | 
|  | { | 
|  | /* Cannot have negative length of input vector */ | 
|  | return (-1); | 
|  | } | 
|  |  | 
|  | if (len == 0) | 
|  | { | 
|  | /* Still got some data to play => continue with the same mode */ | 
|  | *pw16_len = len; | 
|  | return (len); | 
|  | } | 
|  |  | 
|  | fs_mult = WebRtcSpl_DivW32W16ResW16(inst->fs, 8000); | 
|  | fs_shift = 30 - WebRtcSpl_NormW32(fs_mult); /* Note that this is not "exact" for 48kHz */ | 
|  |  | 
|  | /* | 
|  | * Check if last RecOut call resulted in an Expand or a FadeToBGN. If so, we have to take | 
|  | * care of some cross-fading and unmuting. | 
|  | */ | 
|  | if (inst->w16_mode == MODE_EXPAND || inst->w16_mode == MODE_FADE_TO_BGN) | 
|  | { | 
|  |  | 
|  | /* Define memory where temporary result from Expand algorithm can be stored. */ | 
|  | #ifdef SCRATCH | 
|  | int16_t *pw16_expanded = pw16_scratchPtr + SCRATCH_PW16_EXPANDED; | 
|  | #else | 
|  | int16_t pw16_expanded[FSMULT * 125]; | 
|  | #endif | 
|  | int16_t expandedLen = 0; | 
|  | int16_t w16_decodedMax; | 
|  |  | 
|  | /* Find largest value in new data */ | 
|  | w16_decodedMax = WebRtcSpl_MaxAbsValueW16(pw16_decoded, (int16_t) len); | 
|  |  | 
|  | /* Generate interpolation data using Expand */ | 
|  | /* First, set Expand parameters to appropriate values. */ | 
|  | inst->ExpandInst.w16_lagsPosition = 0; | 
|  | inst->ExpandInst.w16_lagsDirection = 0; | 
|  | inst->ExpandInst.w16_stopMuting = 1; /* Do not mute signal any more */ | 
|  |  | 
|  | /* Call Expand */ | 
|  | WebRtcNetEQ_Expand(inst, | 
|  | #ifdef SCRATCH | 
|  | pw16_scratchPtr + SCRATCH_NETEQ_EXPAND, | 
|  | #endif | 
|  | pw16_expanded, &expandedLen, (int16_t) (inst->w16_mode == MODE_FADE_TO_BGN)); | 
|  |  | 
|  | inst->ExpandInst.w16_stopMuting = 0; /* Restore value */ | 
|  | inst->ExpandInst.w16_consecExp = 0; /* Last was not Expand any more */ | 
|  |  | 
|  | /* Adjust muting factor (main muting factor times expand muting factor) */ | 
|  | if (inst->w16_mode == MODE_FADE_TO_BGN) | 
|  | { | 
|  | /* If last mode was FadeToBGN, the mute factor should be zero. */ | 
|  | inst->w16_muteFactor = 0; | 
|  | } | 
|  | else | 
|  | { | 
|  | /* w16_muteFactor * w16_expandMuteFactor */ | 
|  | inst->w16_muteFactor | 
|  | = (int16_t) WEBRTC_SPL_MUL_16_16_RSFT(inst->w16_muteFactor, | 
|  | inst->ExpandInst.w16_expandMuteFactor, 14); | 
|  | } | 
|  |  | 
|  | /* Adjust muting factor if needed (to BGN level) */ | 
|  | enLen = WEBRTC_SPL_MIN(fs_mult<<6, len); /* min( fs_mult * 64, len ) */ | 
|  | w16_tmp = 6 + fs_shift - WebRtcSpl_NormW32( | 
|  | WEBRTC_SPL_MUL_16_16(w16_decodedMax, w16_decodedMax)); | 
|  | w16_tmp = WEBRTC_SPL_MAX(w16_tmp, 0); | 
|  | w32_En_speech = WebRtcNetEQ_DotW16W16(pw16_decoded, pw16_decoded, enLen, w16_tmp); | 
|  | w32_En_speech = WebRtcSpl_DivW32W16(w32_En_speech, (int16_t) (enLen >> w16_tmp)); | 
|  |  | 
|  | if ((w32_En_speech != 0) && (w32_En_speech > inst->BGNInst.w32_energy)) | 
|  | { | 
|  | /* Normalize new frame energy to 15 bits */ | 
|  | w16_tmp = WebRtcSpl_NormW32(w32_En_speech) - 16; | 
|  | /* we want inst->BGNInst.energy/En_speech in Q14 */ | 
|  | w32_tmp = WEBRTC_SPL_SHIFT_W32(inst->BGNInst.w32_energy, (w16_tmp+14)); | 
|  | w16_tmp = (int16_t) WEBRTC_SPL_SHIFT_W32(w32_En_speech, w16_tmp); | 
|  | w16_tmp = (int16_t) WebRtcSpl_DivW32W16(w32_tmp, w16_tmp); | 
|  | w16_muted = (int16_t) WebRtcSpl_SqrtFloor( | 
|  | WEBRTC_SPL_LSHIFT_W32((int32_t) w16_tmp, | 
|  | 14)); /* w16_muted in Q14 (sqrt(Q28)) */ | 
|  | } | 
|  | else | 
|  | { | 
|  | w16_muted = 16384; /* 1.0 in Q14 */ | 
|  | } | 
|  | if (w16_muted > inst->w16_muteFactor) | 
|  | { | 
|  | inst->w16_muteFactor = WEBRTC_SPL_MIN(w16_muted, 16384); | 
|  | } | 
|  |  | 
|  | /* If muted increase by 0.64 for every 20 ms (NB/WB 0.0040/0.0020 in Q14) */ | 
|  | w16_inc = WebRtcSpl_DivW32W16ResW16(64, fs_mult); | 
|  | for (i = 0; i < len; i++) | 
|  | { | 
|  | /* scale with mute factor */ | 
|  | w32_tmp = WEBRTC_SPL_MUL_16_16(pw16_decoded[i], inst->w16_muteFactor); | 
|  | /* shift 14 with proper rounding */ | 
|  | pw16_decoded[i] = (int16_t) WEBRTC_SPL_RSHIFT_W32((w32_tmp + 8192), 14); | 
|  | /* increase mute_factor towards 16384 */ | 
|  | inst->w16_muteFactor = WEBRTC_SPL_MIN(16384, (inst->w16_muteFactor+w16_inc)); | 
|  | } | 
|  |  | 
|  | /* | 
|  | * Interpolate the expanded data into the new vector | 
|  | * (NB/WB/SWB32/SWB40 8/16/32/32 samples) | 
|  | */ | 
|  | fs_shift = WEBRTC_SPL_MIN(3, fs_shift); /* Set to 3 for >32kHz */ | 
|  | w16_inc = 4 >> fs_shift; | 
|  | w16_frac = w16_inc; | 
|  | for (i = 0; i < 8 * fs_mult; i++) | 
|  | { | 
|  | pw16_decoded[i] = (int16_t) WEBRTC_SPL_RSHIFT_W32( | 
|  | (WEBRTC_SPL_MUL_16_16(w16_frac, pw16_decoded[i]) + | 
|  | WEBRTC_SPL_MUL_16_16((32 - w16_frac), pw16_expanded[i]) + 8), | 
|  | 5); | 
|  | w16_frac += w16_inc; | 
|  | } | 
|  |  | 
|  | #ifdef NETEQ_CNG_CODEC | 
|  | } | 
|  | else if (inst->w16_mode==MODE_RFC3389CNG) | 
|  | { /* previous was RFC 3389 CNG...*/ | 
|  | int16_t pw16_CngInterp[32]; | 
|  | /* Reset mute factor and start up fresh */ | 
|  | inst->w16_muteFactor = 16384; | 
|  | if (inst->CNG_Codec_inst != NULL) | 
|  | { | 
|  | /* Generate long enough for 32kHz */ | 
|  | if(WebRtcCng_Generate(inst->CNG_Codec_inst,pw16_CngInterp, 32, 0)<0) | 
|  | { | 
|  | /* error returned; set return vector to all zeros */ | 
|  | WebRtcSpl_MemSetW16(pw16_CngInterp, 0, 32); | 
|  | } | 
|  | } | 
|  | else | 
|  | { | 
|  | /* | 
|  | * If no CNG instance is defined, just copy from the decoded data. | 
|  | * (This will result in interpolating the decoded with itself.) | 
|  | */ | 
|  | WEBRTC_SPL_MEMCPY_W16(pw16_CngInterp, pw16_decoded, fs_mult * 8); | 
|  | } | 
|  | /* | 
|  | * Interpolate the CNG into the new vector | 
|  | * (NB/WB/SWB32kHz/SWB48kHz 8/16/32/32 samples) | 
|  | */ | 
|  | fs_shift = WEBRTC_SPL_MIN(3, fs_shift); /* Set to 3 for >32kHz */ | 
|  | w16_inc = 4>>fs_shift; | 
|  | w16_frac = w16_inc; | 
|  | for (i = 0; i < 8 * fs_mult; i++) | 
|  | { | 
|  | pw16_decoded[i] = (int16_t) WEBRTC_SPL_RSHIFT_W32( | 
|  | (WEBRTC_SPL_MUL_16_16(w16_frac, pw16_decoded[i]) + | 
|  | WEBRTC_SPL_MUL_16_16((32-w16_frac), pw16_CngInterp[i]) + 8), | 
|  | 5); | 
|  | w16_frac += w16_inc; | 
|  | } | 
|  | #endif | 
|  |  | 
|  | } | 
|  | else if (inst->w16_muteFactor < 16384) | 
|  | { | 
|  | /* | 
|  | * Previous was neither of Expand, FadeToBGN or RFC3389_CNG, but we are still | 
|  | * ramping up from previous muting. | 
|  | * If muted increase by 0.64 for every 20 ms (NB/WB 0.0040/0.0020 in Q14) | 
|  | */ | 
|  | w16_inc = WebRtcSpl_DivW32W16ResW16(64, fs_mult); | 
|  | for (i = 0; i < len; i++) | 
|  | { | 
|  | /* scale with mute factor */ | 
|  | w32_tmp = WEBRTC_SPL_MUL_16_16(pw16_decoded[i], inst->w16_muteFactor); | 
|  | /* shift 14 with proper rounding */ | 
|  | pw16_decoded[i] = (int16_t) WEBRTC_SPL_RSHIFT_W32((w32_tmp + 8192), 14); | 
|  | /* increase mute_factor towards 16384 */ | 
|  | inst->w16_muteFactor = WEBRTC_SPL_MIN(16384, (inst->w16_muteFactor+w16_inc)); | 
|  | } | 
|  | } | 
|  |  | 
|  | /* Copy data to other buffer */WEBRTC_SPL_MEMMOVE_W16(pw16_outData, pw16_decoded, len); | 
|  |  | 
|  | inst->w16_mode = MODE_NORMAL; | 
|  | *pw16_len = len; | 
|  | return (len); | 
|  |  | 
|  | } | 
|  |  | 
|  | #undef SCRATCH_PW16_EXPANDED | 
|  | #undef SCRATCH_NETEQ_EXPAND | 
|  |  |