diff options
Diffstat (limited to 'chromium/third_party/webrtc/modules/audio_coding/neteq/recout.c')
-rw-r--r-- | chromium/third_party/webrtc/modules/audio_coding/neteq/recout.c | 1502 |
1 files changed, 0 insertions, 1502 deletions
diff --git a/chromium/third_party/webrtc/modules/audio_coding/neteq/recout.c b/chromium/third_party/webrtc/modules/audio_coding/neteq/recout.c deleted file mode 100644 index 8f62007310c..00000000000 --- a/chromium/third_party/webrtc/modules/audio_coding/neteq/recout.c +++ /dev/null @@ -1,1502 +0,0 @@ -/* - * Copyright (c) 2012 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. - */ - -/* - * Implementation of RecOut function, which is the main function for the audio output - * process. This function must be called (through the NetEQ API) once every 10 ms. - */ - -#include "dsp.h" - -#include <assert.h> -#include <string.h> /* to define NULL */ - -#include "signal_processing_library.h" - -#include "dsp_helpfunctions.h" -#include "neteq_error_codes.h" -#include "neteq_defines.h" -#include "mcu_dsp_common.h" - -/* Audio types */ -#define TYPE_SPEECH 1 -#define TYPE_CNG 2 - -#ifdef NETEQ_DELAY_LOGGING -#include "delay_logging.h" -#include <stdio.h> -#pragma message("*******************************************************************") -#pragma message("You have specified to use NETEQ_DELAY_LOGGING in the NetEQ library.") -#pragma message("Make sure that your test application supports this.") -#pragma message("*******************************************************************") -#endif - -/* Scratch usage: - - Type Name size startpos endpos - int16_t pw16_NetEqAlgorithm_buffer 1080*fs/8000 0 1080*fs/8000-1 - struct dspInfo 6 1080*fs/8000 1085*fs/8000 - - func WebRtcNetEQ_Normal 40+495*fs/8000 0 39+495*fs/8000 - func WebRtcNetEQ_Merge 40+496*fs/8000 0 39+496*fs/8000 - func WebRtcNetEQ_Expand 40+370*fs/8000 126*fs/800 39+496*fs/8000 - func WebRtcNetEQ_Accelerate 210 240*fs/8000 209+240*fs/8000 - func WebRtcNetEQ_BGNUpdate 69 480*fs/8000 68+480*fs/8000 - - Total: 1086*fs/8000 - */ - -#define SCRATCH_ALGORITHM_BUFFER 0 -#define SCRATCH_NETEQ_NORMAL 0 -#define SCRATCH_NETEQ_MERGE 0 - -#if (defined(NETEQ_48KHZ_WIDEBAND)) -#define SCRATCH_DSP_INFO 6480 -#define SCRATCH_NETEQ_ACCELERATE 1440 -#define SCRATCH_NETEQ_BGN_UPDATE 2880 -#define SCRATCH_NETEQ_EXPAND 756 -#elif (defined(NETEQ_32KHZ_WIDEBAND)) -#define SCRATCH_DSP_INFO 4320 -#define SCRATCH_NETEQ_ACCELERATE 960 -#define SCRATCH_NETEQ_BGN_UPDATE 1920 -#define SCRATCH_NETEQ_EXPAND 504 -#elif (defined(NETEQ_WIDEBAND)) -#define SCRATCH_DSP_INFO 2160 -#define SCRATCH_NETEQ_ACCELERATE 480 -#define SCRATCH_NETEQ_BGN_UPDATE 960 -#define SCRATCH_NETEQ_EXPAND 252 -#else /* NB */ -#define SCRATCH_DSP_INFO 1080 -#define SCRATCH_NETEQ_ACCELERATE 240 -#define SCRATCH_NETEQ_BGN_UPDATE 480 -#define SCRATCH_NETEQ_EXPAND 126 -#endif - -#if (defined(NETEQ_48KHZ_WIDEBAND)) -#define SIZE_SCRATCH_BUFFER 6516 -#elif (defined(NETEQ_32KHZ_WIDEBAND)) -#define SIZE_SCRATCH_BUFFER 4344 -#elif (defined(NETEQ_WIDEBAND)) -#define SIZE_SCRATCH_BUFFER 2172 -#else /* NB */ -#define SIZE_SCRATCH_BUFFER 1086 -#endif - -#ifdef NETEQ_DELAY_LOGGING -extern FILE *delay_fid2; /* file pointer to delay log file */ -extern uint32_t tot_received_packets; -#endif - - -int WebRtcNetEQ_RecOutInternal(DSPInst_t *inst, int16_t *pw16_outData, - int16_t *pw16_len, int16_t BGNonly, - int av_sync) -{ - - int16_t blockLen, payloadLen, len = 0, pos; - int16_t w16_tmp1, w16_tmp2, w16_tmp3, DataEnough; - int16_t *blockPtr; - int16_t MD = 0; - - int16_t speechType = TYPE_SPEECH; - uint16_t instr; - uint16_t uw16_tmp; -#ifdef SCRATCH - char pw8_ScratchBuffer[((SIZE_SCRATCH_BUFFER + 1) * 2)]; - int16_t *pw16_scratchPtr = (int16_t*) pw8_ScratchBuffer; - /* pad with 240*fs_mult to match the overflow guard below */ - int16_t pw16_decoded_buffer[NETEQ_MAX_FRAME_SIZE+240*6]; - int16_t *pw16_NetEqAlgorithm_buffer = pw16_scratchPtr - + SCRATCH_ALGORITHM_BUFFER; - DSP2MCU_info_t *dspInfo = (DSP2MCU_info_t*) (pw16_scratchPtr + SCRATCH_DSP_INFO); -#else - /* pad with 240*fs_mult to match the overflow guard below */ - int16_t pw16_decoded_buffer[NETEQ_MAX_FRAME_SIZE+240*6]; - int16_t pw16_NetEqAlgorithm_buffer[NETEQ_MAX_OUTPUT_SIZE+240*6]; - DSP2MCU_info_t dspInfoStruct; - DSP2MCU_info_t *dspInfo = &dspInfoStruct; -#endif - int16_t fs_mult; - int borrowedSamples; - int oldBorrowedSamples; - int return_value = 0; - int16_t lastModeBGNonly = (inst->w16_mode & MODE_BGN_ONLY) != 0; /* check BGN flag */ - void *mainInstBackup = inst->main_inst; - -#ifdef NETEQ_DELAY_LOGGING - int temp_var; -#endif - int16_t dtmfValue = -1; - int16_t dtmfVolume = -1; - int playDtmf = 0; -#ifdef NETEQ_ATEVENT_DECODE - int dtmfSwitch = 0; -#endif -#ifdef NETEQ_STEREO - MasterSlaveInfo *msInfo = inst->msInfo; -#endif - int16_t *sharedMem = pw16_NetEqAlgorithm_buffer; /* Reuse memory SHARED_MEM_SIZE size */ - inst->pw16_readAddress = sharedMem; - inst->pw16_writeAddress = sharedMem; - - /* Get information about if there is one descriptor left */ - if (inst->codec_ptr_inst.funcGetMDinfo != NULL) - { - MD = inst->codec_ptr_inst.funcGetMDinfo(inst->codec_ptr_inst.codec_state); - if (MD > 0) - MD = 1; - else - MD = 0; - } - -#ifdef NETEQ_STEREO - if ((msInfo->msMode == NETEQ_SLAVE) && (inst->codec_ptr_inst.funcDecode != NULL)) - { - /* - * Valid function pointers indicate that we have decoded something, - * and that the timestamp information is correct. - */ - - /* Get the information from master to correct synchronization */ - uint32_t currentMasterTimestamp; - uint32_t currentSlaveTimestamp; - - currentMasterTimestamp = msInfo->endTimestamp - msInfo->samplesLeftWithOverlap; - currentSlaveTimestamp = inst->endTimestamp - (inst->endPosition - inst->curPosition); - - /* Partition the uint32_t space in three: [0 0.25) [0.25 0.75] (0.75 1] - * We consider a wrap to have occurred if the timestamps are in - * different edge partitions. - */ - if (currentSlaveTimestamp < 0x40000000 && - currentMasterTimestamp > 0xc0000000) { - // Slave has wrapped. - currentSlaveTimestamp += (0xffffffff - currentMasterTimestamp) + 1; - currentMasterTimestamp = 0; - } else if (currentMasterTimestamp < 0x40000000 && - currentSlaveTimestamp > 0xc0000000) { - // Master has wrapped. - currentMasterTimestamp += (0xffffffff - currentSlaveTimestamp) + 1; - currentSlaveTimestamp = 0; - } - - if (currentSlaveTimestamp < currentMasterTimestamp) - { - /* brute-force discard a number of samples to catch up */ - inst->curPosition += currentMasterTimestamp - currentSlaveTimestamp; - - } - else if (currentSlaveTimestamp > currentMasterTimestamp) - { - /* back off current position to slow down */ - inst->curPosition -= currentSlaveTimestamp - currentMasterTimestamp; - } - - /* make sure we have at least "overlap" samples left */ - inst->curPosition = WEBRTC_SPL_MIN(inst->curPosition, - inst->endPosition - inst->ExpandInst.w16_overlap); - - /* make sure we do not end up outside the speech history */ - inst->curPosition = WEBRTC_SPL_MAX(inst->curPosition, 0); - } -#endif - - /* Write status data to shared memory */ - dspInfo->playedOutTS = inst->endTimestamp; - dspInfo->samplesLeft = inst->endPosition - inst->curPosition - - inst->ExpandInst.w16_overlap; - dspInfo->MD = MD; - dspInfo->lastMode = inst->w16_mode; - dspInfo->frameLen = inst->w16_frameLen; - - /* Force update of codec if codec function is NULL */ - if (inst->codec_ptr_inst.funcDecode == NULL) - { - dspInfo->lastMode |= MODE_AWAITING_CODEC_PTR; - } - -#ifdef NETEQ_STEREO - if (msInfo->msMode == NETEQ_SLAVE && (msInfo->extraInfo == DTMF_OVERDUB - || msInfo->extraInfo == DTMF_ONLY)) - { - /* Signal that the master instance generated DTMF tones */ - dspInfo->lastMode |= MODE_MASTER_DTMF_SIGNAL; - } - - if (msInfo->msMode != NETEQ_MONO) - { - /* We are using stereo mode; signal this to MCU side */ - dspInfo->lastMode |= MODE_USING_STEREO; - } -#endif - - WEBRTC_SPL_MEMCPY_W8(inst->pw16_writeAddress,dspInfo,sizeof(DSP2MCU_info_t)); - - /* Signal MCU with "interrupt" call to main inst*/ -#ifdef NETEQ_STEREO - assert(msInfo != NULL); - if (msInfo->msMode == NETEQ_MASTER) - { - /* clear info to slave */ - WebRtcSpl_MemSetW16((int16_t *) msInfo, 0, - sizeof(MasterSlaveInfo) / sizeof(int16_t)); - /* re-set mode */ - msInfo->msMode = NETEQ_MASTER; - - /* Store some information to slave */ - msInfo->endTimestamp = inst->endTimestamp; - msInfo->samplesLeftWithOverlap = inst->endPosition - inst->curPosition; - } -#endif - - /* - * This call will trigger the MCU side to make a decision based on buffer contents and - * decision history. Instructions, encoded data and function pointers will be written - * to the shared memory. - */ - return_value = WebRtcNetEQ_DSP2MCUinterrupt((MainInst_t *) inst->main_inst, sharedMem); - - /* Read MCU data and instructions */ - instr = (uint16_t) (inst->pw16_readAddress[0] & 0xf000); - -#ifdef NETEQ_STEREO - if (msInfo->msMode == NETEQ_MASTER) - { - msInfo->instruction = instr; - } - else if (msInfo->msMode == NETEQ_SLAVE) - { - /* Nothing to do */ - } -#endif - - /* check for error returned from MCU side, if so, return error */ - if (return_value < 0) - { - inst->w16_mode = MODE_ERROR; - dspInfo->lastMode = MODE_ERROR; - return return_value; - } - - blockPtr = &((inst->pw16_readAddress)[3]); - - /* Check for DTMF payload flag */ - if ((inst->pw16_readAddress[0] & DSP_DTMF_PAYLOAD) != 0) - { - playDtmf = 1; - dtmfValue = blockPtr[1]; - dtmfVolume = blockPtr[2]; - blockPtr += 3; - -#ifdef NETEQ_STEREO - if (msInfo->msMode == NETEQ_MASTER) - { - /* signal to slave that master is using DTMF */ - msInfo->extraInfo = DTMF_OVERDUB; - } -#endif - } - - blockLen = (((*blockPtr) & DSP_CODEC_MASK_RED_FLAG) + 1) >> 1; /* In # of int16_t */ - payloadLen = ((*blockPtr) & DSP_CODEC_MASK_RED_FLAG); - blockPtr++; - - /* Do we have to change our decoder? */ - if ((inst->pw16_readAddress[0] & 0x0f00) == DSP_CODEC_NEW_CODEC) - { - WEBRTC_SPL_MEMCPY_W16(&inst->codec_ptr_inst,blockPtr,(payloadLen+1)>>1); - if (inst->codec_ptr_inst.codec_fs != 0) - { - return_value = WebRtcNetEQ_DSPInit(inst, inst->codec_ptr_inst.codec_fs); - if (return_value != 0) - { /* error returned */ - instr = DSP_INSTR_FADE_TO_BGN; /* emergency instruction */ - } -#ifdef NETEQ_DELAY_LOGGING - temp_var = NETEQ_DELAY_LOGGING_SIGNAL_CHANGE_FS; - if ((fwrite(&temp_var, sizeof(int), - 1, delay_fid2) != 1) || - (fwrite(&inst->fs, sizeof(uint16_t), - 1, delay_fid2) != 1)) { - return -1; - } -#endif - } - - /* Copy it again since the init destroys this part */ - - WEBRTC_SPL_MEMCPY_W16(&inst->codec_ptr_inst,blockPtr,(payloadLen+1)>>1); - inst->endTimestamp = inst->codec_ptr_inst.timeStamp; - inst->videoSyncTimestamp = inst->codec_ptr_inst.timeStamp; - blockPtr += blockLen; - blockLen = (((*blockPtr) & DSP_CODEC_MASK_RED_FLAG) + 1) >> 1; - payloadLen = ((*blockPtr) & DSP_CODEC_MASK_RED_FLAG); - blockPtr++; - if (inst->codec_ptr_inst.funcDecodeInit != NULL) - { - inst->codec_ptr_inst.funcDecodeInit(inst->codec_ptr_inst.codec_state); - } - -#ifdef NETEQ_CNG_CODEC - - /* Also update the CNG state as this might be uninitialized */ - - WEBRTC_SPL_MEMCPY_W16(&inst->CNG_Codec_inst,blockPtr,(payloadLen+1)>>1); - blockPtr += blockLen; - blockLen = (((*blockPtr) & DSP_CODEC_MASK_RED_FLAG) + 1) >> 1; - payloadLen = ((*blockPtr) & DSP_CODEC_MASK_RED_FLAG); - blockPtr++; - if (inst->CNG_Codec_inst != NULL) - { - WebRtcCng_InitDec(inst->CNG_Codec_inst); - } -#endif - } - else if ((inst->pw16_readAddress[0] & 0x0f00) == DSP_CODEC_RESET) - { - /* Reset the current codec (but not DSP struct) */ - if (inst->codec_ptr_inst.funcDecodeInit != NULL) - { - inst->codec_ptr_inst.funcDecodeInit(inst->codec_ptr_inst.codec_state); - } - -#ifdef NETEQ_CNG_CODEC - /* And reset CNG */ - if (inst->CNG_Codec_inst != NULL) - { - WebRtcCng_InitDec(inst->CNG_Codec_inst); - } -#endif /*NETEQ_CNG_CODEC*/ - } - - fs_mult = WebRtcNetEQ_CalcFsMult(inst->fs); - - /* Add late packet? */ - if ((inst->pw16_readAddress[0] & 0x0f00) == DSP_CODEC_ADD_LATE_PKT) - { - if (inst->codec_ptr_inst.funcAddLatePkt != NULL) - { - /* Only do this if the codec has support for Add Late Pkt */ - inst->codec_ptr_inst.funcAddLatePkt(inst->codec_ptr_inst.codec_state, blockPtr, - payloadLen); - } - blockPtr += blockLen; - blockLen = (((*blockPtr) & DSP_CODEC_MASK_RED_FLAG) + 1) >> 1; /* In # of Word16 */ - payloadLen = ((*blockPtr) & DSP_CODEC_MASK_RED_FLAG); - blockPtr++; - } - - /* Do we have to decode data? */ - if ((instr == DSP_INSTR_NORMAL) || (instr == DSP_INSTR_ACCELERATE) || (instr - == DSP_INSTR_MERGE) || (instr == DSP_INSTR_PREEMPTIVE_EXPAND)) - { - /* Do we need to update codec-internal PLC state? */ - if ((instr == DSP_INSTR_MERGE) && (inst->codec_ptr_inst.funcDecodePLC != NULL)) - { - len = 0; - len = inst->codec_ptr_inst.funcDecodePLC(inst->codec_ptr_inst.codec_state, - &pw16_decoded_buffer[len], 1); - } - len = 0; - - /* Do decoding */ - while ((blockLen > 0) && (len < (240 * fs_mult))) /* Guard somewhat against overflow */ - { - if (inst->codec_ptr_inst.funcDecode != NULL) - { - int16_t dec_Len; - if (!BGNonly) - { - /* Check if this is a sync payload. */ - if (av_sync && WebRtcNetEQ_IsSyncPayload(blockPtr, - payloadLen)) { - /* Zero-stuffing with same size as the last frame. */ - dec_Len = inst->w16_frameLen; - memset(&pw16_decoded_buffer[len], 0, dec_Len * - sizeof(pw16_decoded_buffer[len])); - } else { - /* Do decoding as normal - * - * blockPtr is pointing to payload, at this point, - * the most significant bit of *(blockPtr - 1) is a flag if - * set to 1 indicates that the following payload is the - * redundant payload. - */ - if (((*(blockPtr - 1) & DSP_CODEC_RED_FLAG) != 0) - && (inst->codec_ptr_inst.funcDecodeRCU != NULL)) - { - dec_Len = inst->codec_ptr_inst.funcDecodeRCU( - inst->codec_ptr_inst.codec_state, blockPtr, - payloadLen, &pw16_decoded_buffer[len], &speechType); - } - else - { - /* Regular decoding. */ - dec_Len = inst->codec_ptr_inst.funcDecode( - inst->codec_ptr_inst.codec_state, blockPtr, - payloadLen, &pw16_decoded_buffer[len], &speechType); - } - } - } - else - { - /* - * Background noise mode: don't decode, just produce the same length BGN. - * Don't call Expand for BGN here, since Expand uses the memory where the - * bitstreams are stored (sharemem). - */ - dec_Len = inst->w16_frameLen; - } - - if (dec_Len > 0) - { - len += dec_Len; - /* Update frameLen */ - inst->w16_frameLen = dec_Len; - } - else if (dec_Len < 0) - { - /* Error */ - len = -1; - break; - } - /* - * Sanity check (although we might still write outside memory when this - * happens...) - */ - if (len > NETEQ_MAX_FRAME_SIZE) - { - WebRtcSpl_MemSetW16(pw16_outData, 0, inst->timestampsPerCall); - *pw16_len = inst->timestampsPerCall; - inst->w16_mode = MODE_ERROR; - dspInfo->lastMode = MODE_ERROR; - return RECOUT_ERROR_DECODED_TOO_MUCH; - } - - /* Verify that instance was not corrupted by decoder */ - if (mainInstBackup != inst->main_inst) - { - /* Instance is corrupt */ - return CORRUPT_INSTANCE; - } - - } - blockPtr += blockLen; - blockLen = (((*blockPtr) & DSP_CODEC_MASK_RED_FLAG) + 1) >> 1; /* In # of Word16 */ - payloadLen = ((*blockPtr) & DSP_CODEC_MASK_RED_FLAG); - blockPtr++; - } - - if (len < 0) - { - len = 0; - inst->endTimestamp += inst->w16_frameLen; /* advance one frame */ - if (inst->codec_ptr_inst.funcGetErrorCode != NULL) - { - return_value = -inst->codec_ptr_inst.funcGetErrorCode( - inst->codec_ptr_inst.codec_state); - } - else - { - return_value = RECOUT_ERROR_DECODING; - } - instr = DSP_INSTR_FADE_TO_BGN; - } - if (speechType != TYPE_CNG) - { - /* - * Don't increment timestamp if codec returned CNG speech type - * since in this case, the MCU side will increment the CNGplayedTS counter. - */ - inst->endTimestamp += len; - } - } - else if (instr == DSP_INSTR_NORMAL_ONE_DESC) - { - if (inst->codec_ptr_inst.funcDecode != NULL) - { - len = inst->codec_ptr_inst.funcDecode(inst->codec_ptr_inst.codec_state, NULL, 0, - pw16_decoded_buffer, &speechType); -#ifdef NETEQ_DELAY_LOGGING - temp_var = NETEQ_DELAY_LOGGING_SIGNAL_DECODE_ONE_DESC; - if (fwrite(&temp_var, sizeof(int), 1, delay_fid2) != 1) { - return -1; - } - if (fwrite(&inst->endTimestamp, sizeof(uint32_t), - 1, delay_fid2) != 1) { - return -1; - } - if (fwrite(&dspInfo->samplesLeft, sizeof(uint16_t), - 1, delay_fid2) != 1) { - return -1; - } - tot_received_packets++; -#endif - } - if (speechType != TYPE_CNG) - { - /* - * Don't increment timestamp if codec returned CNG speech type - * since in this case, the MCU side will increment the CNGplayedTS counter. - */ - inst->endTimestamp += len; - } - - /* Verify that instance was not corrupted by decoder */ - if (mainInstBackup != inst->main_inst) - { - /* Instance is corrupt */ - return CORRUPT_INSTANCE; - } - - if (len <= 0) - { - len = 0; - if (inst->codec_ptr_inst.funcGetErrorCode != NULL) - { - return_value = -inst->codec_ptr_inst.funcGetErrorCode( - inst->codec_ptr_inst.codec_state); - } - else - { - return_value = RECOUT_ERROR_DECODING; - } - if ((inst->codec_ptr_inst.funcDecodeInit != NULL) - && (inst->codec_ptr_inst.codec_state != NULL)) - { - /* Reinitialize codec state as something is obviously wrong */ - inst->codec_ptr_inst.funcDecodeInit(inst->codec_ptr_inst.codec_state); - } - inst->endTimestamp += inst->w16_frameLen; /* advance one frame */ - instr = DSP_INSTR_FADE_TO_BGN; - } - } - - if (len == 0 && lastModeBGNonly) /* no new data */ - { - BGNonly = 1; /* force BGN this time too */ - } - -#ifdef NETEQ_VAD - if ((speechType == TYPE_CNG) /* decoder responded with codec-internal CNG */ - || ((instr == DSP_INSTR_DO_RFC3389CNG) && (blockLen > 0)) /* ... or, SID frame */ - || (inst->fs > 16000)) /* ... or, if not NB or WB */ - { - /* disable post-decode VAD upon first sign of send-side DTX/VAD active, or if SWB */ - inst->VADInst.VADEnabled = 0; - inst->VADInst.VADDecision = 1; /* set to always active, just to be on the safe side */ - inst->VADInst.SIDintervalCounter = 0; /* reset SID interval counter */ - } - else if (!inst->VADInst.VADEnabled) /* VAD disabled and no SID/CNG data observed this time */ - { - inst->VADInst.SIDintervalCounter++; /* increase counter */ - } - - /* check for re-enabling the VAD */ - if (inst->VADInst.SIDintervalCounter >= POST_DECODE_VAD_AUTO_ENABLE) - { - /* - * It's been a while since the last CNG/SID frame was observed => re-enable VAD. - * (Do not care to look for a VAD instance, since this is done inside the init - * function) - */ - WebRtcNetEQ_InitVAD(&inst->VADInst, inst->fs); - } - - if (len > 0 /* if we decoded any data */ - && inst->VADInst.VADEnabled /* and VAD enabled */ - && inst->fs <= 16000) /* can only do VAD for NB and WB */ - { - int VADframeSize; /* VAD frame size in ms */ - int VADSamplePtr = 0; - - inst->VADInst.VADDecision = 0; - - if (inst->VADInst.VADFunction != NULL) /* make sure that VAD function is provided */ - { - /* divide the data into groups, as large as possible */ - for (VADframeSize = 30; VADframeSize >= 10; VADframeSize -= 10) - { - /* loop through 30, 20, 10 */ - - while (inst->VADInst.VADDecision == 0 - && len - VADSamplePtr >= VADframeSize * fs_mult * 8) - { - /* - * Only continue until first active speech found, and as long as there is - * one VADframeSize left. - */ - - /* call VAD with new decoded data */ - inst->VADInst.VADDecision |= inst->VADInst.VADFunction( - inst->VADInst.VADState, (int) inst->fs, - (int16_t *) &pw16_decoded_buffer[VADSamplePtr], - (VADframeSize * fs_mult * 8)); - - VADSamplePtr += VADframeSize * fs_mult * 8; /* increment sample counter */ - } - } - } - else - { /* VAD function is NULL */ - inst->VADInst.VADDecision = 1; /* set decision to active */ - inst->VADInst.VADEnabled = 0; /* disable VAD since we have no VAD function */ - } - - } -#endif /* NETEQ_VAD */ - - /* Adjust timestamp if needed */ - uw16_tmp = (uint16_t) inst->pw16_readAddress[1]; - inst->endTimestamp += (((uint32_t) uw16_tmp) << 16); - uw16_tmp = (uint16_t) inst->pw16_readAddress[2]; - inst->endTimestamp += uw16_tmp; - - if (BGNonly && len > 0) - { - /* - * If BGN mode, we did not produce any data at decoding. - * Do it now instead. - */ - - WebRtcNetEQ_GenerateBGN(inst, -#ifdef SCRATCH - pw16_scratchPtr + SCRATCH_NETEQ_EXPAND, -#endif - pw16_decoded_buffer, len); - } - - /* Switch on the instruction received from the MCU side. */ - switch (instr) - { - case DSP_INSTR_NORMAL: - - /* Allow for signal processing to apply gain-back etc */ - WebRtcNetEQ_Normal(inst, -#ifdef SCRATCH - pw16_scratchPtr + SCRATCH_NETEQ_NORMAL, -#endif - pw16_decoded_buffer, len, pw16_NetEqAlgorithm_buffer, &len); - - /* If last packet was decoded as a inband CNG set mode to CNG instead */ - if ((speechType == TYPE_CNG) || ((inst->w16_mode == MODE_CODEC_INTERNAL_CNG) - && (len == 0))) - { - inst->w16_mode = MODE_CODEC_INTERNAL_CNG; - } - -#ifdef NETEQ_ATEVENT_DECODE - if (playDtmf == 0) - { - inst->DTMFInst.reinit = 1; - } -#endif - break; - case DSP_INSTR_NORMAL_ONE_DESC: - - /* Allow for signal processing to apply gain-back etc */ - WebRtcNetEQ_Normal(inst, -#ifdef SCRATCH - pw16_scratchPtr + SCRATCH_NETEQ_NORMAL, -#endif - pw16_decoded_buffer, len, pw16_NetEqAlgorithm_buffer, &len); -#ifdef NETEQ_ATEVENT_DECODE - if (playDtmf == 0) - { - inst->DTMFInst.reinit = 1; - } -#endif - inst->w16_mode = MODE_ONE_DESCRIPTOR; - break; - case DSP_INSTR_MERGE: -#ifdef NETEQ_DELAY_LOGGING - temp_var = NETEQ_DELAY_LOGGING_SIGNAL_MERGE_INFO; - if (fwrite(&temp_var, sizeof(int), 1, delay_fid2) != 1) { - return -1; - } - temp_var = -len; -#endif - /* Call Merge with history*/ - return_value = WebRtcNetEQ_Merge(inst, -#ifdef SCRATCH - pw16_scratchPtr + SCRATCH_NETEQ_MERGE, -#endif - pw16_decoded_buffer, len, pw16_NetEqAlgorithm_buffer, &len); - - if (return_value < 0) - { - /* error */ - return return_value; - } - -#ifdef NETEQ_DELAY_LOGGING - temp_var += len; - if (fwrite(&temp_var, sizeof(int), 1, delay_fid2) != 1) { - return -1; - } -#endif - /* If last packet was decoded as a inband CNG set mode to CNG instead */ - if (speechType == TYPE_CNG) inst->w16_mode = MODE_CODEC_INTERNAL_CNG; -#ifdef NETEQ_ATEVENT_DECODE - if (playDtmf == 0) - { - inst->DTMFInst.reinit = 1; - } -#endif - break; - - case DSP_INSTR_EXPAND: - len = 0; - pos = 0; - while ((inst->endPosition - inst->curPosition - inst->ExpandInst.w16_overlap + pos) - < (inst->timestampsPerCall)) - { - return_value = WebRtcNetEQ_Expand(inst, -#ifdef SCRATCH - pw16_scratchPtr + SCRATCH_NETEQ_EXPAND, -#endif - pw16_NetEqAlgorithm_buffer, &len, BGNonly); - if (return_value < 0) - { - /* error */ - return return_value; - } - - /* - * Update buffer, but only end part (otherwise expand state is destroyed - * since it reuses speechBuffer[] memory - */ - - WEBRTC_SPL_MEMMOVE_W16(inst->pw16_speechHistory, - inst->pw16_speechHistory + len, - (inst->w16_speechHistoryLen-len)); - WEBRTC_SPL_MEMCPY_W16(&inst->pw16_speechHistory[inst->w16_speechHistoryLen-len], - pw16_NetEqAlgorithm_buffer, len); - - inst->curPosition -= len; - - /* Update variables for VQmon */ - inst->w16_concealedTS += len; -#ifdef NETEQ_DELAY_LOGGING - temp_var = NETEQ_DELAY_LOGGING_SIGNAL_EXPAND_INFO; - if (fwrite(&temp_var, sizeof(int), 1, delay_fid2) != 1) { - return -1; - } - temp_var = len; - if (fwrite(&temp_var, sizeof(int), 1, delay_fid2) != 1) { - return -1; - } -#endif - len = 0; /* already written the data, so do not write it again further down. */ - } -#ifdef NETEQ_ATEVENT_DECODE - if (playDtmf == 0) - { - inst->DTMFInst.reinit = 1; - } -#endif - break; - - case DSP_INSTR_ACCELERATE: - if (len < 3 * 80 * fs_mult) - { - /* We need to move data from the speechBuffer[] in order to get 30 ms */ - borrowedSamples = 3 * 80 * fs_mult - len; - - WEBRTC_SPL_MEMMOVE_W16(&pw16_decoded_buffer[borrowedSamples], - pw16_decoded_buffer, len); - WEBRTC_SPL_MEMCPY_W16(pw16_decoded_buffer, - &(inst->speechBuffer[inst->endPosition-borrowedSamples]), - borrowedSamples); - - return_value = WebRtcNetEQ_Accelerate(inst, -#ifdef SCRATCH - pw16_scratchPtr + SCRATCH_NETEQ_ACCELERATE, -#endif - pw16_decoded_buffer, 3 * inst->timestampsPerCall, - pw16_NetEqAlgorithm_buffer, &len, BGNonly); - - if (return_value < 0) - { - /* error */ - return return_value; - } - - /* Copy back samples to the buffer */ - if (len < borrowedSamples) - { - /* - * This destroys the beginning of the buffer, but will not cause any - * problems - */ - - WEBRTC_SPL_MEMCPY_W16(&inst->speechBuffer[inst->endPosition-borrowedSamples], - pw16_NetEqAlgorithm_buffer, len); - WEBRTC_SPL_MEMMOVE_W16(&inst->speechBuffer[borrowedSamples-len], - inst->speechBuffer, - (inst->endPosition-(borrowedSamples-len))); - - inst->curPosition += (borrowedSamples - len); -#ifdef NETEQ_DELAY_LOGGING - temp_var = NETEQ_DELAY_LOGGING_SIGNAL_ACCELERATE_INFO; - if (fwrite(&temp_var, sizeof(int), 1, delay_fid2) != 1) { - return -1; - } - temp_var = 3 * inst->timestampsPerCall - len; - if (fwrite(&temp_var, sizeof(int), 1, delay_fid2) != 1) { - return -1; - } -#endif - len = 0; - } - else - { - WEBRTC_SPL_MEMCPY_W16(&inst->speechBuffer[inst->endPosition-borrowedSamples], - pw16_NetEqAlgorithm_buffer, borrowedSamples); - WEBRTC_SPL_MEMMOVE_W16(pw16_NetEqAlgorithm_buffer, - &pw16_NetEqAlgorithm_buffer[borrowedSamples], - (len-borrowedSamples)); -#ifdef NETEQ_DELAY_LOGGING - temp_var = NETEQ_DELAY_LOGGING_SIGNAL_ACCELERATE_INFO; - if (fwrite(&temp_var, sizeof(int), 1, delay_fid2) != 1) { - return -1; - } - temp_var = 3 * inst->timestampsPerCall - len; - if (fwrite(&temp_var, sizeof(int), 1, delay_fid2) != 1) { - return -1; - } -#endif - len = len - borrowedSamples; - } - - } - else - { -#ifdef NETEQ_DELAY_LOGGING - temp_var = NETEQ_DELAY_LOGGING_SIGNAL_ACCELERATE_INFO; - if (fwrite(&temp_var, sizeof(int), 1, delay_fid2) != 1) { - return -1; - } - temp_var = len; -#endif - return_value = WebRtcNetEQ_Accelerate(inst, -#ifdef SCRATCH - pw16_scratchPtr + SCRATCH_NETEQ_ACCELERATE, -#endif - pw16_decoded_buffer, len, pw16_NetEqAlgorithm_buffer, &len, BGNonly); - - if (return_value < 0) - { - /* error */ - return return_value; - } - -#ifdef NETEQ_DELAY_LOGGING - temp_var -= len; - if (fwrite(&temp_var, sizeof(int), 1, delay_fid2) != 1) { - return -1; - } -#endif - } - /* If last packet was decoded as a inband CNG set mode to CNG instead */ - if (speechType == TYPE_CNG) inst->w16_mode = MODE_CODEC_INTERNAL_CNG; -#ifdef NETEQ_ATEVENT_DECODE - if (playDtmf == 0) - { - inst->DTMFInst.reinit = 1; - } -#endif - break; - - case DSP_INSTR_DO_RFC3389CNG: -#ifdef NETEQ_CNG_CODEC - if (blockLen > 0) - { - if (WebRtcCng_UpdateSid(inst->CNG_Codec_inst, (uint8_t*) blockPtr, - payloadLen) < 0) - { - /* error returned from CNG function */ - return_value = -WebRtcCng_GetErrorCodeDec(inst->CNG_Codec_inst); - len = inst->timestampsPerCall; - WebRtcSpl_MemSetW16(pw16_NetEqAlgorithm_buffer, 0, len); - break; - } - } - - if (BGNonly) - { - /* Get data from BGN function instead of CNG */ - len = WebRtcNetEQ_GenerateBGN(inst, -#ifdef SCRATCH - pw16_scratchPtr + SCRATCH_NETEQ_EXPAND, -#endif - pw16_NetEqAlgorithm_buffer, inst->timestampsPerCall); - if (len != inst->timestampsPerCall) - { - /* this is not good, treat this as an error */ - return_value = -1; - } - } - else - { - return_value = WebRtcNetEQ_Cng(inst, pw16_NetEqAlgorithm_buffer, - inst->timestampsPerCall); - } - len = inst->timestampsPerCall; - inst->ExpandInst.w16_consecExp = 0; - inst->w16_mode = MODE_RFC3389CNG; -#ifdef NETEQ_ATEVENT_DECODE - if (playDtmf == 0) - { - inst->DTMFInst.reinit = 1; - } -#endif - - if (return_value < 0) - { - /* error returned */ - WebRtcSpl_MemSetW16(pw16_NetEqAlgorithm_buffer, 0, len); - } - - break; -#else - return FAULTY_INSTRUCTION; -#endif - case DSP_INSTR_DO_CODEC_INTERNAL_CNG: - /* - * This represents the case when there is no transmission and the decoder should - * do internal CNG. - */ - len = 0; - if (inst->codec_ptr_inst.funcDecode != NULL && !BGNonly) - { - len = inst->codec_ptr_inst.funcDecode(inst->codec_ptr_inst.codec_state, - blockPtr, 0, pw16_decoded_buffer, &speechType); - } - else - { - /* get BGN data */ - len = WebRtcNetEQ_GenerateBGN(inst, -#ifdef SCRATCH - pw16_scratchPtr + SCRATCH_NETEQ_EXPAND, -#endif - pw16_decoded_buffer, inst->timestampsPerCall); - } - WebRtcNetEQ_Normal(inst, -#ifdef SCRATCH - pw16_scratchPtr + SCRATCH_NETEQ_NORMAL, -#endif - pw16_decoded_buffer, len, pw16_NetEqAlgorithm_buffer, &len); - inst->w16_mode = MODE_CODEC_INTERNAL_CNG; - inst->ExpandInst.w16_consecExp = 0; - break; - - case DSP_INSTR_DTMF_GENERATE: -#ifdef NETEQ_ATEVENT_DECODE - dtmfSwitch = 0; - if ((inst->w16_mode != MODE_DTMF) && (inst->DTMFInst.reinit == 0)) - { - /* Special case; see below. - * We must catch this before calling DTMFGenerate, - * since reinit is set to 0 in that call. - */ - dtmfSwitch = 1; - } - - len = WebRtcNetEQ_DTMFGenerate(&inst->DTMFInst, dtmfValue, dtmfVolume, - pw16_NetEqAlgorithm_buffer, inst->fs, -1); - if (len < 0) - { - /* error occurred */ - return_value = len; - len = inst->timestampsPerCall; - WebRtcSpl_MemSetW16(pw16_NetEqAlgorithm_buffer, 0, len); - } - - if (dtmfSwitch == 1) - { - /* - * This is the special case where the previous operation was DTMF overdub. - * but the current instruction is "regular" DTMF. We must make sure that the - * DTMF does not have any discontinuities. The first DTMF sample that we - * generate now must be played out immediately, wherefore it must be copied to - * the speech buffer. - */ - - /* - * Generate extra DTMF data to fill the space between - * curPosition and endPosition - */ - int16_t tempLen; - - tempLen = WebRtcNetEQ_DTMFGenerate(&inst->DTMFInst, dtmfValue, dtmfVolume, - &pw16_NetEqAlgorithm_buffer[len], inst->fs, - inst->endPosition - inst->curPosition); - if (tempLen < 0) - { - /* error occurred */ - return_value = tempLen; - len = inst->endPosition - inst->curPosition; - WebRtcSpl_MemSetW16(pw16_NetEqAlgorithm_buffer, 0, - inst->endPosition - inst->curPosition); - } - - /* Add to total length */ - len += tempLen; - - /* Overwrite the "future" part of the speech buffer with the new DTMF data */ - - WEBRTC_SPL_MEMCPY_W16(&inst->speechBuffer[inst->curPosition], - pw16_NetEqAlgorithm_buffer, - inst->endPosition - inst->curPosition); - - /* Shuffle the remaining data to the beginning of algorithm buffer */ - len -= (inst->endPosition - inst->curPosition); - WEBRTC_SPL_MEMMOVE_W16(pw16_NetEqAlgorithm_buffer, - &pw16_NetEqAlgorithm_buffer[inst->endPosition - inst->curPosition], - len); - } - - inst->endTimestamp += inst->timestampsPerCall; - inst->DTMFInst.reinit = 0; - inst->ExpandInst.w16_consecExp = 0; - inst->w16_mode = MODE_DTMF; - BGNonly = 0; /* override BGN only and let DTMF through */ - - playDtmf = 0; /* set to zero because the DTMF is already in the Algorithm buffer */ - /* - * If playDtmf is 1, an extra DTMF vector will be generated and overdubbed - * on the output. - */ - -#ifdef NETEQ_STEREO - if (msInfo->msMode == NETEQ_MASTER) - { - /* signal to slave that master is using DTMF only */ - msInfo->extraInfo = DTMF_ONLY; - } -#endif - - break; -#else - inst->w16_mode = MODE_ERROR; - dspInfo->lastMode = MODE_ERROR; - return FAULTY_INSTRUCTION; -#endif - - case DSP_INSTR_DO_ALTERNATIVE_PLC: - if (inst->codec_ptr_inst.funcDecodePLC != 0) - { - len = inst->codec_ptr_inst.funcDecodePLC(inst->codec_ptr_inst.codec_state, - pw16_NetEqAlgorithm_buffer, 1); - } - else - { - len = inst->timestampsPerCall; - /* ZeroStuffing... */ - WebRtcSpl_MemSetW16(pw16_NetEqAlgorithm_buffer, 0, len); - /* By not advancing the timestamp, NetEq inserts samples. */ - inst->statInst.addedSamples += len; - } - inst->ExpandInst.w16_consecExp = 0; - break; - case DSP_INSTR_DO_ALTERNATIVE_PLC_INC_TS: - if (inst->codec_ptr_inst.funcDecodePLC != 0) - { - len = inst->codec_ptr_inst.funcDecodePLC(inst->codec_ptr_inst.codec_state, - pw16_NetEqAlgorithm_buffer, 1); - } - else - { - len = inst->timestampsPerCall; - /* ZeroStuffing... */ - WebRtcSpl_MemSetW16(pw16_NetEqAlgorithm_buffer, 0, len); - } - inst->ExpandInst.w16_consecExp = 0; - inst->endTimestamp += len; - break; - case DSP_INSTR_DO_AUDIO_REPETITION: - len = inst->timestampsPerCall; - /* copy->paste... */ - WEBRTC_SPL_MEMCPY_W16(pw16_NetEqAlgorithm_buffer, - &inst->speechBuffer[inst->endPosition-len], len); - inst->ExpandInst.w16_consecExp = 0; - break; - case DSP_INSTR_DO_AUDIO_REPETITION_INC_TS: - len = inst->timestampsPerCall; - /* copy->paste... */ - WEBRTC_SPL_MEMCPY_W16(pw16_NetEqAlgorithm_buffer, - &inst->speechBuffer[inst->endPosition-len], len); - inst->ExpandInst.w16_consecExp = 0; - inst->endTimestamp += len; - break; - - case DSP_INSTR_PREEMPTIVE_EXPAND: - if (len < 3 * inst->timestampsPerCall) - { - /* borrow samples from sync buffer if necessary */ - borrowedSamples = 3 * inst->timestampsPerCall - len; /* borrow this many samples */ - /* calculate how many of these are already played out */ - oldBorrowedSamples = WEBRTC_SPL_MAX(0, - borrowedSamples - (inst->endPosition - inst->curPosition)); - WEBRTC_SPL_MEMMOVE_W16(&pw16_decoded_buffer[borrowedSamples], - pw16_decoded_buffer, len); - WEBRTC_SPL_MEMCPY_W16(pw16_decoded_buffer, - &(inst->speechBuffer[inst->endPosition-borrowedSamples]), - borrowedSamples); - } - else - { - borrowedSamples = 0; - oldBorrowedSamples = 0; - } - -#ifdef NETEQ_DELAY_LOGGING - w16_tmp1 = len; -#endif - /* do the expand */ - return_value = WebRtcNetEQ_PreEmptiveExpand(inst, -#ifdef SCRATCH - /* use same scratch memory as Accelerate */ - pw16_scratchPtr + SCRATCH_NETEQ_ACCELERATE, -#endif - pw16_decoded_buffer, len + borrowedSamples, oldBorrowedSamples, - pw16_NetEqAlgorithm_buffer, &len, BGNonly); - - if (return_value < 0) - { - /* error */ - return return_value; - } - - if (borrowedSamples > 0) - { - /* return borrowed samples */ - - /* Copy back to last part of speechBuffer from beginning of output buffer */ - WEBRTC_SPL_MEMCPY_W16( &(inst->speechBuffer[inst->endPosition-borrowedSamples]), - pw16_NetEqAlgorithm_buffer, - borrowedSamples); - - len -= borrowedSamples; /* remove the borrowed samples from new total length */ - - /* Move to beginning of output buffer from end of output buffer */ - WEBRTC_SPL_MEMMOVE_W16( pw16_NetEqAlgorithm_buffer, - &pw16_NetEqAlgorithm_buffer[borrowedSamples], - len); - } - -#ifdef NETEQ_DELAY_LOGGING - temp_var = NETEQ_DELAY_LOGGING_SIGNAL_PREEMPTIVE_INFO; - if (fwrite(&temp_var, sizeof(int), 1, delay_fid2) != 1) { - return -1; - } - temp_var = len - w16_tmp1; /* number of samples added */ - if (fwrite(&temp_var, sizeof(int), 1, delay_fid2) != 1) { - return -1; - } -#endif - /* If last packet was decoded as inband CNG, set mode to CNG instead */ - if (speechType == TYPE_CNG) inst->w16_mode = MODE_CODEC_INTERNAL_CNG; -#ifdef NETEQ_ATEVENT_DECODE - if (playDtmf == 0) - { - inst->DTMFInst.reinit = 1; - } -#endif - break; - - case DSP_INSTR_FADE_TO_BGN: - { - int tempReturnValue; - /* do not overwrite return_value, since it likely contains an error code */ - - /* calculate interpolation length */ - w16_tmp3 = WEBRTC_SPL_MIN(inst->endPosition - inst->curPosition, - inst->timestampsPerCall); - /* check that it will fit in pw16_NetEqAlgorithm_buffer */ - if (w16_tmp3 + inst->w16_frameLen > NETEQ_MAX_OUTPUT_SIZE) - { - w16_tmp3 = NETEQ_MAX_OUTPUT_SIZE - inst->w16_frameLen; - } - - /* call Expand */ - len = inst->timestampsPerCall + inst->ExpandInst.w16_overlap; - pos = 0; - - tempReturnValue = WebRtcNetEQ_Expand(inst, -#ifdef SCRATCH - pw16_scratchPtr + SCRATCH_NETEQ_EXPAND, -#endif - pw16_NetEqAlgorithm_buffer, &len, 1); - - if (tempReturnValue < 0) - { - /* error */ - /* this error value will override return_value */ - return tempReturnValue; - } - - pos += len; /* got len samples from expand */ - - /* copy to fill the demand */ - while (pos + len <= inst->w16_frameLen + w16_tmp3) - { - WEBRTC_SPL_MEMCPY_W16(&pw16_NetEqAlgorithm_buffer[pos], - pw16_NetEqAlgorithm_buffer, len); - pos += len; - } - - /* fill with fraction of the expand vector if needed */ - if (pos < inst->w16_frameLen + w16_tmp3) - { - WEBRTC_SPL_MEMCPY_W16(&pw16_NetEqAlgorithm_buffer[pos], pw16_NetEqAlgorithm_buffer, - inst->w16_frameLen + w16_tmp3 - pos); - } - - len = inst->w16_frameLen + w16_tmp3; /* truncate any surplus samples since we don't want these */ - - /* - * Mix with contents in sync buffer. Find largest power of two that is less than - * interpolate length divide 16384 with this number; result is in w16_tmp2. - */ - w16_tmp1 = 2; - w16_tmp2 = 16384; - while (w16_tmp1 <= w16_tmp3) - { - w16_tmp2 >>= 1; /* divide with 2 */ - w16_tmp1 <<= 1; /* increase with a factor of 2 */ - } - - w16_tmp1 = 0; - pos = 0; - while (w16_tmp1 < 16384) - { - inst->speechBuffer[inst->curPosition + pos] - = - (int16_t) WEBRTC_SPL_RSHIFT_W32( - WEBRTC_SPL_MUL_16_16( inst->speechBuffer[inst->endPosition - w16_tmp3 + pos], - 16384-w16_tmp1 ) + - WEBRTC_SPL_MUL_16_16( pw16_NetEqAlgorithm_buffer[pos], w16_tmp1 ), - 14 ); - w16_tmp1 += w16_tmp2; - pos++; - } - - /* overwrite remainder of speech buffer */ - - WEBRTC_SPL_MEMCPY_W16( &inst->speechBuffer[inst->endPosition - w16_tmp3 + pos], - &pw16_NetEqAlgorithm_buffer[pos], w16_tmp3 - pos); - - len -= w16_tmp3; - /* shift algorithm buffer */ - - WEBRTC_SPL_MEMMOVE_W16( pw16_NetEqAlgorithm_buffer, - &pw16_NetEqAlgorithm_buffer[w16_tmp3], - len ); - - /* Update variables for VQmon */ - inst->w16_concealedTS += len; - - inst->w16_mode = MODE_FADE_TO_BGN; -#ifdef NETEQ_DELAY_LOGGING - temp_var = NETEQ_DELAY_LOGGING_SIGNAL_EXPAND_INFO; - if (fwrite(&temp_var, sizeof(int), 1, delay_fid2) != 1) { - return -1; - } - temp_var = len; - if (fwrite(&temp_var, sizeof(int), 1, delay_fid2) != 1) { - return -1; - } -#endif - - break; - } - - default: - inst->w16_mode = MODE_ERROR; - dspInfo->lastMode = MODE_ERROR; - return FAULTY_INSTRUCTION; - } /* end of grand switch */ - - /* Copy data directly to output buffer */ - - w16_tmp2 = 0; - if ((inst->endPosition + len - inst->curPosition - inst->ExpandInst.w16_overlap) - >= inst->timestampsPerCall) - { - w16_tmp2 = inst->endPosition - inst->curPosition; - w16_tmp2 = WEBRTC_SPL_MAX(w16_tmp2, 0); /* Additional error protection, just in case */ - w16_tmp1 = WEBRTC_SPL_MIN(w16_tmp2, inst->timestampsPerCall); - w16_tmp2 = inst->timestampsPerCall - w16_tmp1; - WEBRTC_SPL_MEMCPY_W16(pw16_outData, &inst->speechBuffer[inst->curPosition], w16_tmp1); - WEBRTC_SPL_MEMCPY_W16(&pw16_outData[w16_tmp1], pw16_NetEqAlgorithm_buffer, w16_tmp2); - DataEnough = 1; - } - else - { - DataEnough = 0; - } - - if (playDtmf != 0) - { -#ifdef NETEQ_ATEVENT_DECODE - int16_t outDataIndex = 0; - int16_t overdubLen = -1; /* default len */ - int16_t dtmfLen; - - /* - * Overdub the output with DTMF. Note that this is not executed if the - * DSP_INSTR_DTMF_GENERATE operation is performed above. - */ - if (inst->DTMFInst.lastDtmfSample - inst->curPosition > 0) - { - /* special operation for transition from "DTMF only" to "DTMF overdub" */ - outDataIndex - = WEBRTC_SPL_MIN(inst->DTMFInst.lastDtmfSample - inst->curPosition, - inst->timestampsPerCall); - overdubLen = inst->timestampsPerCall - outDataIndex; - } - - dtmfLen = WebRtcNetEQ_DTMFGenerate(&inst->DTMFInst, dtmfValue, dtmfVolume, - &pw16_outData[outDataIndex], inst->fs, overdubLen); - if (dtmfLen < 0) - { - /* error occurred */ - return_value = dtmfLen; - } - inst->DTMFInst.reinit = 0; -#else - inst->w16_mode = MODE_ERROR; - dspInfo->lastMode = MODE_ERROR; - return FAULTY_INSTRUCTION; -#endif - } - - /* - * Shuffle speech buffer to allow more data. Move data from pw16_NetEqAlgorithm_buffer - * to speechBuffer. - */ - if (instr != DSP_INSTR_EXPAND) - { - w16_tmp1 = WEBRTC_SPL_MIN(inst->endPosition, len); - WEBRTC_SPL_MEMMOVE_W16(inst->speechBuffer, inst->speechBuffer + w16_tmp1, - (inst->endPosition-w16_tmp1)); - WEBRTC_SPL_MEMCPY_W16(&inst->speechBuffer[inst->endPosition-w16_tmp1], - &pw16_NetEqAlgorithm_buffer[len-w16_tmp1], w16_tmp1); -#ifdef NETEQ_ATEVENT_DECODE - /* Update index to end of DTMF data in speech buffer */ - if (instr == DSP_INSTR_DTMF_GENERATE) - { - /* We have written DTMF data to the end of speech buffer */ - inst->DTMFInst.lastDtmfSample = inst->endPosition; - } - else if (inst->DTMFInst.lastDtmfSample > 0) - { - /* The end of DTMF data in speech buffer has been shuffled */ - inst->DTMFInst.lastDtmfSample -= w16_tmp1; - } -#endif - /* - * Update the BGN history if last operation was not expand (nor Merge, Accelerate - * or Pre-emptive expand, to save complexity). - */ - if ((inst->w16_mode != MODE_EXPAND) && (inst->w16_mode != MODE_MERGE) - && (inst->w16_mode != MODE_SUCCESS_ACCELERATE) && (inst->w16_mode - != MODE_LOWEN_ACCELERATE) && (inst->w16_mode != MODE_SUCCESS_PREEMPTIVE) - && (inst->w16_mode != MODE_LOWEN_PREEMPTIVE) && (inst->w16_mode - != MODE_FADE_TO_BGN) && (inst->w16_mode != MODE_DTMF) && (!BGNonly)) - { - WebRtcNetEQ_BGNUpdate(inst -#ifdef SCRATCH - , pw16_scratchPtr + SCRATCH_NETEQ_BGN_UPDATE -#endif - ); - } - } - else /* instr == DSP_INSTR_EXPAND */ - { - /* Nothing should be done since data is already copied to output. */ - } - - inst->curPosition -= len; - - /* - * Extra protection in case something should go totally wrong in terms of sizes... - * If everything is ok this should NEVER happen. - */ - if (inst->curPosition < -inst->timestampsPerCall) - { - inst->curPosition = -inst->timestampsPerCall; - } - - if ((instr != DSP_INSTR_EXPAND) && (instr != DSP_INSTR_MERGE) && (instr - != DSP_INSTR_FADE_TO_BGN)) - { - /* Reset concealed TS parameter if it does not seem to have been flushed */ - if (inst->w16_concealedTS > inst->timestampsPerCall) - { - inst->w16_concealedTS = 0; - } - } - - /* - * Double-check that we actually have 10 ms to play. If we haven't, there has been a - * serious error.The decoder might have returned way too few samples - */ - if (!DataEnough) - { - /* This should not happen. Set outdata to zeros, and return error. */ - WebRtcSpl_MemSetW16(pw16_outData, 0, inst->timestampsPerCall); - *pw16_len = inst->timestampsPerCall; - inst->w16_mode = MODE_ERROR; - dspInfo->lastMode = MODE_ERROR; - return RECOUT_ERROR_SAMPLEUNDERRUN; - } - - /* - * Update Videosync timestamp (this special timestamp is needed since the endTimestamp - * stops during CNG and Expand periods. - */ - if ((inst->w16_mode != MODE_EXPAND) && (inst->w16_mode != MODE_RFC3389CNG)) - { - uint32_t uw32_tmpTS; - uw32_tmpTS = inst->endTimestamp - (inst->endPosition - inst->curPosition); - if ((int32_t) (uw32_tmpTS - inst->videoSyncTimestamp) > 0) - { - inst->videoSyncTimestamp = uw32_tmpTS; - } - } - else - { - inst->videoSyncTimestamp += inst->timestampsPerCall; - } - - /* After this, regardless of what has happened, deliver 10 ms of future data */ - inst->curPosition += inst->timestampsPerCall; - *pw16_len = inst->timestampsPerCall; - - /* Remember if BGNonly was used */ - if (BGNonly) - { - inst->w16_mode |= MODE_BGN_ONLY; - } - - return return_value; -} - -#undef SCRATCH_ALGORITHM_BUFFER -#undef SCRATCH_NETEQ_NORMAL -#undef SCRATCH_NETEQ_MERGE -#undef SCRATCH_NETEQ_BGN_UPDATE -#undef SCRATCH_NETEQ_EXPAND -#undef SCRATCH_DSP_INFO -#undef SCRATCH_NETEQ_ACCELERATE -#undef SIZE_SCRATCH_BUFFER |