git-svn-id: http://webrtc.googlecode.com/svn/trunk@4 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
155
modules/audio_coding/NetEQ/main/source/cng_internal.c
Normal file
155
modules/audio_coding/NetEQ/main/source/cng_internal.c
Normal file
@@ -0,0 +1,155 @@
|
||||
/*
|
||||
* 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 obtaining comfort noise from noise parameters
|
||||
* according to IETF RFC 3389.
|
||||
*/
|
||||
|
||||
#include "dsp.h"
|
||||
|
||||
#include "signal_processing_library.h"
|
||||
#include "webrtc_cng.h"
|
||||
|
||||
#include "dsp_helpfunctions.h"
|
||||
#include "neteq_error_codes.h"
|
||||
|
||||
/****************************************************************************
|
||||
* WebRtcNetEQ_Cng(...)
|
||||
*
|
||||
* This function produces CNG according to RFC 3389.
|
||||
*
|
||||
* Input:
|
||||
* - inst : NetEQ DSP instance
|
||||
* - len : Number of samples to produce (max 640 or
|
||||
* 640 - fsHz*5/8000 for first-time CNG, governed by
|
||||
* the definition of WEBRTC_CNG_MAX_OUTSIZE_ORDER in
|
||||
* webrtc_cng.h)
|
||||
*
|
||||
* Output:
|
||||
* - pw16_outData : Output CNG
|
||||
*
|
||||
* Return value : 0 - Ok
|
||||
* <0 - Error
|
||||
*/
|
||||
|
||||
#ifdef NETEQ_CNG_CODEC
|
||||
/* Must compile NetEQ with CNG support to enable this function */
|
||||
|
||||
int WebRtcNetEQ_Cng(DSPInst_t *inst, WebRtc_Word16 *pw16_outData, int len)
|
||||
{
|
||||
WebRtc_Word16 w16_winMute = 0; /* mixing factor for overlap data */
|
||||
WebRtc_Word16 w16_winUnMute = 0; /* mixing factor for comfort noise */
|
||||
WebRtc_Word16 w16_winMuteInc = 0; /* mixing factor increment (negative) */
|
||||
WebRtc_Word16 w16_winUnMuteInc = 0; /* mixing factor increment */
|
||||
int i;
|
||||
|
||||
/*
|
||||
* Check if last RecOut call was other than RFC3389,
|
||||
* that is, this call is the first of a CNG period.
|
||||
*/
|
||||
if (inst->w16_mode != MODE_RFC3389CNG)
|
||||
{
|
||||
/* Reset generation and overlap slightly with old data */
|
||||
|
||||
/* Generate len samples + overlap */
|
||||
if (WebRtcCng_Generate(inst->CNG_Codec_inst, pw16_outData,
|
||||
(WebRtc_Word16) (len + inst->ExpandInst.w16_overlap), 1) < 0)
|
||||
{
|
||||
/* error returned */
|
||||
return -WebRtcCng_GetErrorCodeDec(inst->CNG_Codec_inst);
|
||||
}
|
||||
|
||||
/* Set windowing parameters depending on sample rate */
|
||||
if (inst->fs == 8000)
|
||||
{
|
||||
/* Windowing in Q15 */
|
||||
w16_winMute = NETEQ_OVERLAP_WINMUTE_8KHZ_START;
|
||||
w16_winMuteInc = NETEQ_OVERLAP_WINMUTE_8KHZ_INC;
|
||||
w16_winUnMute = NETEQ_OVERLAP_WINUNMUTE_8KHZ_START;
|
||||
w16_winUnMuteInc = NETEQ_OVERLAP_WINUNMUTE_8KHZ_INC;
|
||||
#ifdef NETEQ_WIDEBAND
|
||||
}
|
||||
else if (inst->fs == 16000)
|
||||
{
|
||||
/* Windowing in Q15 */
|
||||
w16_winMute = NETEQ_OVERLAP_WINMUTE_16KHZ_START;
|
||||
w16_winMuteInc = NETEQ_OVERLAP_WINMUTE_16KHZ_INC;
|
||||
w16_winUnMute = NETEQ_OVERLAP_WINUNMUTE_16KHZ_START;
|
||||
w16_winUnMuteInc = NETEQ_OVERLAP_WINUNMUTE_16KHZ_INC;
|
||||
#endif
|
||||
#ifdef NETEQ_32KHZ_WIDEBAND
|
||||
}
|
||||
else if (inst->fs == 32000)
|
||||
{
|
||||
/* Windowing in Q15 */
|
||||
w16_winMute = NETEQ_OVERLAP_WINMUTE_32KHZ_START;
|
||||
w16_winMuteInc = NETEQ_OVERLAP_WINMUTE_32KHZ_INC;
|
||||
w16_winUnMute = NETEQ_OVERLAP_WINUNMUTE_32KHZ_START;
|
||||
w16_winUnMuteInc = NETEQ_OVERLAP_WINUNMUTE_32KHZ_INC;
|
||||
#endif
|
||||
#ifdef NETEQ_48KHZ_WIDEBAND
|
||||
}
|
||||
else if (inst->fs == 48000)
|
||||
{
|
||||
/* Windowing in Q15 */
|
||||
w16_winMute = NETEQ_OVERLAP_WINMUTE_48KHZ_START;
|
||||
w16_winMuteInc = NETEQ_OVERLAP_WINMUTE_48KHZ_INC;
|
||||
w16_winUnMute = NETEQ_OVERLAP_WINUNMUTE_48KHZ_START;
|
||||
w16_winUnMuteInc = NETEQ_OVERLAP_WINUNMUTE_48KHZ_INC;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Unsupported sample rate (should not be possible) */
|
||||
return NETEQ_OTHER_ERROR;
|
||||
}
|
||||
|
||||
/* Do overlap add between new vector and overlap */
|
||||
for (i = 0; i < inst->ExpandInst.w16_overlap; i++)
|
||||
{
|
||||
/* overlapVec[i] = WinMute * overlapVec[i] + WinUnMute * outData[i] */
|
||||
inst->ExpandInst.pw16_overlapVec[i] = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(
|
||||
WEBRTC_SPL_MUL_16_16(
|
||||
inst->ExpandInst.pw16_overlapVec[i], w16_winMute) +
|
||||
WEBRTC_SPL_MUL_16_16(pw16_outData[i], w16_winUnMute)
|
||||
+ 16384, 15); /* shift with proper rounding */
|
||||
|
||||
w16_winMute += w16_winMuteInc; /* decrease mute factor (inc<0) */
|
||||
w16_winUnMute += w16_winUnMuteInc; /* increase unmute factor (inc>0) */
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Shift the contents of the outData buffer by overlap samples, since we
|
||||
* already used these first samples in the overlapVec above
|
||||
*/
|
||||
|
||||
WEBRTC_SPL_MEMMOVE_W16(pw16_outData, pw16_outData+inst->ExpandInst.w16_overlap, len);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
/* This is a subsequent CNG call; no special overlap needed */
|
||||
|
||||
/* Generate len samples */
|
||||
if (WebRtcCng_Generate(inst->CNG_Codec_inst, pw16_outData, (WebRtc_Word16) len, 0) < 0)
|
||||
{
|
||||
/* error returned */
|
||||
return -WebRtcCng_GetErrorCodeDec(inst->CNG_Codec_inst);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
#endif /* NETEQ_CNG_CODEC */
|
||||
|
||||
Reference in New Issue
Block a user