Support for Signal calls.

Merge in RedPhone

// FREEBIE
This commit is contained in:
Moxie Marlinspike
2015-09-09 13:54:29 -07:00
parent 3d4ae60d81
commit d83a3d71bc
2585 changed files with 803492 additions and 45 deletions

View File

@@ -0,0 +1,13 @@
# Copyright (c) 2014 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.
import("../../build/webrtc.gni")
source_set("audio_coding") {
# TODO(andrew): Implement.
}

View File

@@ -0,0 +1 @@
per-file BUILD.gn=kjellander@webrtc.org

View File

@@ -0,0 +1,3 @@
tina.legrand@webrtc.org
turaj@webrtc.org
jan.skoglund@webrtc.org

View File

@@ -0,0 +1,41 @@
# 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.
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
include $(LOCAL_PATH)/../../../../../android-webrtc.mk
LOCAL_ARM_MODE := arm
LOCAL_MODULE_CLASS := STATIC_LIBRARIES
LOCAL_MODULE := libwebrtc_cng
LOCAL_MODULE_TAGS := optional
LOCAL_GENERATED_SOURCES :=
LOCAL_SRC_FILES := \
webrtc_cng.c \
cng_helpfuns.c
# Flags passed to both C and C++ files.
LOCAL_CFLAGS := \
$(MY_WEBRTC_COMMON_DEFS)
LOCAL_C_INCLUDES := \
$(LOCAL_PATH)/include \
$(LOCAL_PATH)/../../../.. \
$(LOCAL_PATH)/../../../../../ \
$(LOCAL_PATH)/../../../../common_audio/signal_processing/include
LOCAL_SHARED_LIBRARIES := \
libdl \
libstlport
ifndef NDK_ROOT
include external/stlport/libstlport.mk
endif
include $(BUILD_STATIC_LIBRARY)

View File

@@ -0,0 +1,5 @@
# These are for the common case of adding or renaming files. If you're doing
# structural changes, please get a review from a reviewer in this file.
per-file *.gyp=*
per-file *.gypi=*

View File

@@ -0,0 +1,35 @@
# 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.
{
'targets': [
{
'target_name': 'CNG',
'type': 'static_library',
'dependencies': [
'<(webrtc_root)/common_audio/common_audio.gyp:common_audio',
],
'include_dirs': [
'include',
'<(webrtc_root)',
],
'direct_dependent_settings': {
'include_dirs': [
'include',
'<(webrtc_root)',
],
},
'sources': [
'include/webrtc_cng.h',
'webrtc_cng.c',
'cng_helpfuns.c',
'cng_helpfuns.h',
],
},
], # targets
}

View File

@@ -0,0 +1,48 @@
/*
* 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.
*/
#include "cng_helpfuns.h"
#include "signal_processing_library.h"
#include "typedefs.h"
#include "webrtc_cng.h"
/* Values in |k| are Q15, and |a| Q12. */
void WebRtcCng_K2a16(int16_t* k, int useOrder, int16_t* a) {
int16_t any[WEBRTC_SPL_MAX_LPC_ORDER + 1];
int16_t *aptr, *aptr2, *anyptr;
const int16_t *kptr;
int m, i;
kptr = k;
*a = 4096; /* i.e., (Word16_MAX >> 3) + 1 */
*any = *a;
a[1] = (*k + 4) >> 3;
for (m = 1; m < useOrder; m++) {
kptr++;
aptr = a;
aptr++;
aptr2 = &a[m];
anyptr = any;
anyptr++;
any[m + 1] = (*kptr + 4) >> 3;
for (i = 0; i < m; i++) {
*anyptr++ = (*aptr++) +
(int16_t)((((int32_t)(*aptr2--) * (int32_t) * kptr) + 16384) >> 15);
}
aptr = a;
anyptr = any;
for (i = 0; i < (m + 2); i++) {
*aptr++ = *anyptr++;
}
}
}

View File

@@ -0,0 +1,25 @@
/*
* 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.
*/
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_CNG_CNG_HELPFUNS_H_
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_CNG_CNG_HELPFUNS_H_
#include "typedefs.h"
#ifdef __cplusplus
extern "C" {
#endif
void WebRtcCng_K2a16(int16_t* k, int useOrder, int16_t* a);
#ifdef __cplusplus
}
#endif
#endif // WEBRTC_MODULES_AUDIO_CODING_CODECS_CNG_CNG_HELPFUNS_H_

View File

@@ -0,0 +1,348 @@
/*
* 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.
*/
#include <string>
#include "gtest/gtest.h"
#include "webrtc/test/testsupport/fileutils.h"
#include "webrtc_cng.h"
namespace webrtc {
enum {
kSidShortIntervalUpdate = 1,
kSidNormalIntervalUpdate = 100,
kSidLongIntervalUpdate = 10000
};
enum {
kCNGNumParamsLow = 0,
kCNGNumParamsNormal = 8,
kCNGNumParamsHigh = WEBRTC_CNG_MAX_LPC_ORDER,
kCNGNumParamsTooHigh = WEBRTC_CNG_MAX_LPC_ORDER + 1
};
enum {
kNoSid,
kForceSid
};
class CngTest : public ::testing::Test {
protected:
CngTest();
virtual void SetUp();
CNG_enc_inst* cng_enc_inst_;
CNG_dec_inst* cng_dec_inst_;
int16_t speech_data_[640]; // Max size of CNG internal buffers.
};
CngTest::CngTest()
: cng_enc_inst_(NULL),
cng_dec_inst_(NULL) {
}
void CngTest::SetUp() {
FILE* input_file;
const std::string file_name =
webrtc::test::ResourcePath("audio_coding/testfile32kHz", "pcm");
input_file = fopen(file_name.c_str(), "rb");
ASSERT_TRUE(input_file != NULL);
ASSERT_EQ(640, static_cast<int32_t>(fread(speech_data_, sizeof(int16_t),
640, input_file)));
fclose(input_file);
input_file = NULL;
}
// Test failing Create.
TEST_F(CngTest, CngCreateFail) {
// Test to see that an invalid pointer is caught.
EXPECT_EQ(-1, WebRtcCng_CreateEnc(NULL));
EXPECT_EQ(-1, WebRtcCng_CreateDec(NULL));
}
// Test normal Create.
TEST_F(CngTest, CngCreate) {
EXPECT_EQ(0, WebRtcCng_CreateEnc(&cng_enc_inst_));
EXPECT_EQ(0, WebRtcCng_CreateDec(&cng_dec_inst_));
EXPECT_TRUE(cng_enc_inst_ != NULL);
EXPECT_TRUE(cng_dec_inst_ != NULL);
// Free encoder and decoder memory.
EXPECT_EQ(0, WebRtcCng_FreeEnc(cng_enc_inst_));
EXPECT_EQ(0, WebRtcCng_FreeDec(cng_dec_inst_));
}
// Create CNG encoder, init with faulty values, free CNG encoder.
TEST_F(CngTest, CngInitFail) {
// Create encoder memory.
EXPECT_EQ(0, WebRtcCng_CreateEnc(&cng_enc_inst_));
// Call with too few parameters.
EXPECT_EQ(-1, WebRtcCng_InitEnc(cng_enc_inst_, 8000, kSidNormalIntervalUpdate,
kCNGNumParamsLow));
EXPECT_EQ(6130, WebRtcCng_GetErrorCodeEnc(cng_enc_inst_));
// Call with too many parameters.
EXPECT_EQ(-1, WebRtcCng_InitEnc(cng_enc_inst_, 8000, kSidNormalIntervalUpdate,
kCNGNumParamsTooHigh));
EXPECT_EQ(6130, WebRtcCng_GetErrorCodeEnc(cng_enc_inst_));
// Free encoder memory.
EXPECT_EQ(0, WebRtcCng_FreeEnc(cng_enc_inst_));
}
TEST_F(CngTest, CngEncode) {
uint8_t sid_data[WEBRTC_CNG_MAX_LPC_ORDER + 1];
int16_t number_bytes;
// Create encoder memory.
EXPECT_EQ(0, WebRtcCng_CreateEnc(&cng_enc_inst_));
// 8 kHz, Normal number of parameters
EXPECT_EQ(0, WebRtcCng_InitEnc(cng_enc_inst_, 8000, kSidNormalIntervalUpdate,
kCNGNumParamsNormal));
EXPECT_EQ(0, WebRtcCng_Encode(cng_enc_inst_, speech_data_, 80, sid_data,
&number_bytes, kNoSid));
EXPECT_EQ(kCNGNumParamsNormal + 1, WebRtcCng_Encode(
cng_enc_inst_, speech_data_, 80, sid_data, &number_bytes, kForceSid));
// 16 kHz, Normal number of parameters
EXPECT_EQ(0, WebRtcCng_InitEnc(cng_enc_inst_, 16000, kSidNormalIntervalUpdate,
kCNGNumParamsNormal));
EXPECT_EQ(0, WebRtcCng_Encode(cng_enc_inst_, speech_data_, 160, sid_data,
&number_bytes, kNoSid));
EXPECT_EQ(kCNGNumParamsNormal + 1, WebRtcCng_Encode(
cng_enc_inst_, speech_data_, 160, sid_data, &number_bytes, kForceSid));
// 32 kHz, Max number of parameters
EXPECT_EQ(0, WebRtcCng_InitEnc(cng_enc_inst_, 32000, kSidNormalIntervalUpdate,
kCNGNumParamsHigh));
EXPECT_EQ(0, WebRtcCng_Encode(cng_enc_inst_, speech_data_, 320, sid_data,
&number_bytes, kNoSid));
EXPECT_EQ(kCNGNumParamsHigh + 1, WebRtcCng_Encode(
cng_enc_inst_, speech_data_, 320, sid_data, &number_bytes, kForceSid));
// 48 kHz, Normal number of parameters
EXPECT_EQ(0, WebRtcCng_InitEnc(cng_enc_inst_, 48000, kSidNormalIntervalUpdate,
kCNGNumParamsNormal));
EXPECT_EQ(0, WebRtcCng_Encode(cng_enc_inst_, speech_data_, 480, sid_data,
&number_bytes, kNoSid));
EXPECT_EQ(kCNGNumParamsNormal + 1, WebRtcCng_Encode(
cng_enc_inst_, speech_data_, 480, sid_data, &number_bytes, kForceSid));
// 64 kHz, Normal number of parameters
EXPECT_EQ(0, WebRtcCng_InitEnc(cng_enc_inst_, 64000, kSidNormalIntervalUpdate,
kCNGNumParamsNormal));
EXPECT_EQ(0, WebRtcCng_Encode(cng_enc_inst_, speech_data_, 640, sid_data,
&number_bytes, kNoSid));
EXPECT_EQ(kCNGNumParamsNormal + 1, WebRtcCng_Encode(
cng_enc_inst_, speech_data_, 640, sid_data, &number_bytes, kForceSid));
// Free encoder memory.
EXPECT_EQ(0, WebRtcCng_FreeEnc(cng_enc_inst_));
}
// Encode Cng with too long input vector.
TEST_F(CngTest, CngEncodeTooLong) {
uint8_t sid_data[WEBRTC_CNG_MAX_LPC_ORDER + 1];
int16_t number_bytes;
// Create and init encoder memory.
EXPECT_EQ(0, WebRtcCng_CreateEnc(&cng_enc_inst_));
EXPECT_EQ(0, WebRtcCng_InitEnc(cng_enc_inst_, 8000, kSidNormalIntervalUpdate,
kCNGNumParamsNormal));
// Run encoder with too much data.
EXPECT_EQ(-1, WebRtcCng_Encode(cng_enc_inst_, speech_data_, 641, sid_data,
&number_bytes, kNoSid));
EXPECT_EQ(6140, WebRtcCng_GetErrorCodeEnc(cng_enc_inst_));
// Free encoder memory.
EXPECT_EQ(0, WebRtcCng_FreeEnc(cng_enc_inst_));
}
// Call encode without calling init.
TEST_F(CngTest, CngEncodeNoInit) {
uint8_t sid_data[WEBRTC_CNG_MAX_LPC_ORDER + 1];
int16_t number_bytes;
// Create encoder memory.
EXPECT_EQ(0, WebRtcCng_CreateEnc(&cng_enc_inst_));
// Run encoder without calling init.
EXPECT_EQ(-1, WebRtcCng_Encode(cng_enc_inst_, speech_data_, 640, sid_data,
&number_bytes, kNoSid));
EXPECT_EQ(6120, WebRtcCng_GetErrorCodeEnc(cng_enc_inst_));
// Free encoder memory.
EXPECT_EQ(0, WebRtcCng_FreeEnc(cng_enc_inst_));
}
// Update SID parameters, for both 9 and 16 parameters.
TEST_F(CngTest, CngUpdateSid) {
uint8_t sid_data[WEBRTC_CNG_MAX_LPC_ORDER + 1];
int16_t number_bytes;
// Create and initialize encoder and decoder memory.
EXPECT_EQ(0, WebRtcCng_CreateEnc(&cng_enc_inst_));
EXPECT_EQ(0, WebRtcCng_CreateDec(&cng_dec_inst_));
EXPECT_EQ(0, WebRtcCng_InitEnc(cng_enc_inst_, 16000, kSidNormalIntervalUpdate,
kCNGNumParamsNormal));
EXPECT_EQ(0, WebRtcCng_InitDec(cng_dec_inst_));
// Run normal Encode and UpdateSid.
EXPECT_EQ(kCNGNumParamsNormal + 1, WebRtcCng_Encode(
cng_enc_inst_, speech_data_, 160, sid_data, &number_bytes, kForceSid));
EXPECT_EQ(0, WebRtcCng_UpdateSid(cng_dec_inst_, sid_data,
kCNGNumParamsNormal + 1));
// Reinit with new length.
EXPECT_EQ(0, WebRtcCng_InitEnc(cng_enc_inst_, 16000, kSidNormalIntervalUpdate,
kCNGNumParamsHigh));
EXPECT_EQ(0, WebRtcCng_InitDec(cng_dec_inst_));
// Expect 0 because of unstable parameters after switching length.
EXPECT_EQ(0, WebRtcCng_Encode(cng_enc_inst_, speech_data_, 160, sid_data,
&number_bytes, kForceSid));
EXPECT_EQ(kCNGNumParamsHigh + 1, WebRtcCng_Encode(
cng_enc_inst_, speech_data_ + 160, 160, sid_data, &number_bytes,
kForceSid));
EXPECT_EQ(0, WebRtcCng_UpdateSid(cng_dec_inst_, sid_data,
kCNGNumParamsNormal + 1));
// Free encoder and decoder memory.
EXPECT_EQ(0, WebRtcCng_FreeEnc(cng_enc_inst_));
EXPECT_EQ(0, WebRtcCng_FreeDec(cng_dec_inst_));
}
// Update SID parameters, with wrong parameters or without calling decode.
TEST_F(CngTest, CngUpdateSidErroneous) {
uint8_t sid_data[WEBRTC_CNG_MAX_LPC_ORDER + 1];
int16_t number_bytes;
// Create encoder and decoder memory.
EXPECT_EQ(0, WebRtcCng_CreateEnc(&cng_enc_inst_));
EXPECT_EQ(0, WebRtcCng_CreateDec(&cng_dec_inst_));
// Encode.
EXPECT_EQ(0, WebRtcCng_InitEnc(cng_enc_inst_, 16000, kSidNormalIntervalUpdate,
kCNGNumParamsNormal));
EXPECT_EQ(kCNGNumParamsNormal + 1, WebRtcCng_Encode(
cng_enc_inst_, speech_data_, 160, sid_data, &number_bytes, kForceSid));
// Update Sid before initializing decoder.
EXPECT_EQ(-1, WebRtcCng_UpdateSid(cng_dec_inst_, sid_data,
kCNGNumParamsNormal + 1));
EXPECT_EQ(6220, WebRtcCng_GetErrorCodeDec(cng_dec_inst_));
// Initialize decoder.
EXPECT_EQ(0, WebRtcCng_InitDec(cng_dec_inst_));
// First run with valid parameters, then with too many CNG parameters.
// The function will operate correctly by only reading the maximum number of
// parameters, skipping the extra.
EXPECT_EQ(0, WebRtcCng_UpdateSid(cng_dec_inst_, sid_data,
kCNGNumParamsNormal + 1));
EXPECT_EQ(0, WebRtcCng_UpdateSid(cng_dec_inst_, sid_data,
kCNGNumParamsTooHigh + 1));
// Free encoder and decoder memory.
EXPECT_EQ(0, WebRtcCng_FreeEnc(cng_enc_inst_));
EXPECT_EQ(0, WebRtcCng_FreeDec(cng_dec_inst_));
}
// Test to generate cng data, by forcing SID. Both normal and faulty condition.
TEST_F(CngTest, CngGenerate) {
uint8_t sid_data[WEBRTC_CNG_MAX_LPC_ORDER + 1];
int16_t out_data[640];
int16_t number_bytes;
// Create and initialize encoder and decoder memory.
EXPECT_EQ(0, WebRtcCng_CreateEnc(&cng_enc_inst_));
EXPECT_EQ(0, WebRtcCng_CreateDec(&cng_dec_inst_));
EXPECT_EQ(0, WebRtcCng_InitEnc(cng_enc_inst_, 16000, kSidNormalIntervalUpdate,
kCNGNumParamsNormal));
EXPECT_EQ(0, WebRtcCng_InitDec(cng_dec_inst_));
// Normal Encode.
EXPECT_EQ(kCNGNumParamsNormal + 1, WebRtcCng_Encode(
cng_enc_inst_, speech_data_, 160, sid_data, &number_bytes, kForceSid));
// Normal UpdateSid.
EXPECT_EQ(0, WebRtcCng_UpdateSid(cng_dec_inst_, sid_data,
kCNGNumParamsNormal + 1));
// Two normal Generate, one with new_period.
EXPECT_EQ(0, WebRtcCng_Generate(cng_dec_inst_, out_data, 640, 1));
EXPECT_EQ(0, WebRtcCng_Generate(cng_dec_inst_, out_data, 640, 0));
// Call Genereate with too much data.
EXPECT_EQ(-1, WebRtcCng_Generate(cng_dec_inst_, out_data, 641, 0));
EXPECT_EQ(6140, WebRtcCng_GetErrorCodeDec(cng_dec_inst_));
// Free encoder and decoder memory.
EXPECT_EQ(0, WebRtcCng_FreeEnc(cng_enc_inst_));
EXPECT_EQ(0, WebRtcCng_FreeDec(cng_dec_inst_));
}
// Test automatic SID.
TEST_F(CngTest, CngAutoSid) {
uint8_t sid_data[WEBRTC_CNG_MAX_LPC_ORDER + 1];
int16_t number_bytes;
// Create and initialize encoder and decoder memory.
EXPECT_EQ(0, WebRtcCng_CreateEnc(&cng_enc_inst_));
EXPECT_EQ(0, WebRtcCng_CreateDec(&cng_dec_inst_));
EXPECT_EQ(0, WebRtcCng_InitEnc(cng_enc_inst_, 16000, kSidNormalIntervalUpdate,
kCNGNumParamsNormal));
EXPECT_EQ(0, WebRtcCng_InitDec(cng_dec_inst_));
// Normal Encode, 100 msec, where no SID data should be generated.
for (int i = 0; i < 10; i++) {
EXPECT_EQ(0, WebRtcCng_Encode(cng_enc_inst_, speech_data_, 160, sid_data,
&number_bytes, kNoSid));
}
// We have reached 100 msec, and SID data should be generated.
EXPECT_EQ(kCNGNumParamsNormal + 1, WebRtcCng_Encode(
cng_enc_inst_, speech_data_, 160, sid_data, &number_bytes, kNoSid));
// Free encoder and decoder memory.
EXPECT_EQ(0, WebRtcCng_FreeEnc(cng_enc_inst_));
EXPECT_EQ(0, WebRtcCng_FreeDec(cng_dec_inst_));
}
// Test automatic SID, with very short interval.
TEST_F(CngTest, CngAutoSidShort) {
uint8_t sid_data[WEBRTC_CNG_MAX_LPC_ORDER + 1];
int16_t number_bytes;
// Create and initialize encoder and decoder memory.
EXPECT_EQ(0, WebRtcCng_CreateEnc(&cng_enc_inst_));
EXPECT_EQ(0, WebRtcCng_CreateDec(&cng_dec_inst_));
EXPECT_EQ(0, WebRtcCng_InitEnc(cng_enc_inst_, 16000, kSidShortIntervalUpdate,
kCNGNumParamsNormal));
EXPECT_EQ(0, WebRtcCng_InitDec(cng_dec_inst_));
// First call will never generate SID, unless forced to.
EXPECT_EQ(0, WebRtcCng_Encode(cng_enc_inst_, speech_data_, 160, sid_data,
&number_bytes, kNoSid));
// Normal Encode, 100 msec, SID data should be generated all the time.
for (int i = 0; i < 10; i++) {
EXPECT_EQ(kCNGNumParamsNormal + 1, WebRtcCng_Encode(
cng_enc_inst_, speech_data_, 160, sid_data, &number_bytes, kNoSid));
}
// Free encoder and decoder memory.
EXPECT_EQ(0, WebRtcCng_FreeEnc(cng_enc_inst_));
EXPECT_EQ(0, WebRtcCng_FreeDec(cng_dec_inst_));
}
} // namespace webrtc

View File

@@ -0,0 +1,162 @@
/*
* 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.
*/
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_CNG_MAIN_INTERFACE_WEBRTC_CNG_H_
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_CNG_MAIN_INTERFACE_WEBRTC_CNG_H_
#include "typedefs.h"
#ifdef __cplusplus
extern "C" {
#endif
#define WEBRTC_CNG_MAX_LPC_ORDER 12
#define WEBRTC_CNG_MAX_OUTSIZE_ORDER 640
/* Define Error codes. */
/* 6100 Encoder */
#define CNG_ENCODER_NOT_INITIATED 6120
#define CNG_DISALLOWED_LPC_ORDER 6130
#define CNG_DISALLOWED_FRAME_SIZE 6140
#define CNG_DISALLOWED_SAMPLING_FREQUENCY 6150
/* 6200 Decoder */
#define CNG_DECODER_NOT_INITIATED 6220
typedef struct WebRtcCngEncInst CNG_enc_inst;
typedef struct WebRtcCngDecInst CNG_dec_inst;
/****************************************************************************
* WebRtcCng_CreateEnc/Dec(...)
*
* These functions create an instance to the specified structure
*
* Input:
* - XXX_inst : Pointer to created instance that should be created
*
* Return value : 0 - Ok
* -1 - Error
*/
int16_t WebRtcCng_CreateEnc(CNG_enc_inst** cng_inst);
int16_t WebRtcCng_CreateDec(CNG_dec_inst** cng_inst);
/****************************************************************************
* WebRtcCng_InitEnc/Dec(...)
*
* This function initializes a instance
*
* Input:
* - cng_inst : Instance that should be initialized
*
* - fs : 8000 for narrowband and 16000 for wideband
* - interval : generate SID data every interval ms
* - quality : Number of refl. coefs, maximum allowed is 12
*
* Output:
* - cng_inst : Initialized instance
*
* Return value : 0 - Ok
* -1 - Error
*/
int16_t WebRtcCng_InitEnc(CNG_enc_inst* cng_inst, uint16_t fs, int16_t interval,
int16_t quality);
int16_t WebRtcCng_InitDec(CNG_dec_inst* cng_inst);
/****************************************************************************
* WebRtcCng_FreeEnc/Dec(...)
*
* These functions frees the dynamic memory of a specified instance
*
* Input:
* - cng_inst : Pointer to created instance that should be freed
*
* Return value : 0 - Ok
* -1 - Error
*/
int16_t WebRtcCng_FreeEnc(CNG_enc_inst* cng_inst);
int16_t WebRtcCng_FreeDec(CNG_dec_inst* cng_inst);
/****************************************************************************
* WebRtcCng_Encode(...)
*
* These functions analyzes background noise
*
* Input:
* - cng_inst : Pointer to created instance
* - speech : Signal to be analyzed
* - nrOfSamples : Size of speech vector
* - forceSID : not zero to force SID frame and reset
*
* Output:
* - bytesOut : Nr of bytes to transmit, might be 0
*
* Return value : 0 - Ok
* -1 - Error
*/
int16_t WebRtcCng_Encode(CNG_enc_inst* cng_inst, int16_t* speech,
int16_t nrOfSamples, uint8_t* SIDdata,
int16_t* bytesOut, int16_t forceSID);
/****************************************************************************
* WebRtcCng_UpdateSid(...)
*
* These functions updates the CN state, when a new SID packet arrives
*
* Input:
* - cng_inst : Pointer to created instance that should be freed
* - SID : SID packet, all headers removed
* - length : Length in bytes of SID packet
*
* Return value : 0 - Ok
* -1 - Error
*/
int16_t WebRtcCng_UpdateSid(CNG_dec_inst* cng_inst, uint8_t* SID,
int16_t length);
/****************************************************************************
* WebRtcCng_Generate(...)
*
* These functions generates CN data when needed
*
* Input:
* - cng_inst : Pointer to created instance that should be freed
* - outData : pointer to area to write CN data
* - nrOfSamples : How much data to generate
* - new_period : >0 if a new period of CNG, will reset history
*
* Return value : 0 - Ok
* -1 - Error
*/
int16_t WebRtcCng_Generate(CNG_dec_inst* cng_inst, int16_t* outData,
int16_t nrOfSamples, int16_t new_period);
/*****************************************************************************
* WebRtcCng_GetErrorCodeEnc/Dec(...)
*
* This functions can be used to check the error code of a CNG instance. When
* a function returns -1 a error code will be set for that instance. The
* function below extract the code of the last error that occurred in the
* specified instance.
*
* Input:
* - CNG_inst : CNG enc/dec instance
*
* Return value : Error code
*/
int16_t WebRtcCng_GetErrorCodeEnc(CNG_enc_inst* cng_inst);
int16_t WebRtcCng_GetErrorCodeDec(CNG_dec_inst* cng_inst);
#ifdef __cplusplus
}
#endif
#endif // WEBRTC_MODULES_AUDIO_CODING_CODECS_CNG_MAIN_INTERFACE_WEBRTC_CNG_H_

View File

@@ -0,0 +1,602 @@
/*
* 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.
*/
#include "webrtc_cng.h"
#include <string.h>
#include <stdlib.h>
#include "cng_helpfuns.h"
#include "signal_processing_library.h"
typedef struct WebRtcCngDecInst_t_ {
uint32_t dec_seed;
int32_t dec_target_energy;
int32_t dec_used_energy;
int16_t dec_target_reflCoefs[WEBRTC_CNG_MAX_LPC_ORDER + 1];
int16_t dec_used_reflCoefs[WEBRTC_CNG_MAX_LPC_ORDER + 1];
int16_t dec_filtstate[WEBRTC_CNG_MAX_LPC_ORDER + 1];
int16_t dec_filtstateLow[WEBRTC_CNG_MAX_LPC_ORDER + 1];
int16_t dec_Efiltstate[WEBRTC_CNG_MAX_LPC_ORDER + 1];
int16_t dec_EfiltstateLow[WEBRTC_CNG_MAX_LPC_ORDER + 1];
int16_t dec_order;
int16_t dec_target_scale_factor; /* Q29 */
int16_t dec_used_scale_factor; /* Q29 */
int16_t target_scale_factor; /* Q13 */
int16_t errorcode;
int16_t initflag;
} WebRtcCngDecInst_t;
typedef struct WebRtcCngEncInst_t_ {
int16_t enc_nrOfCoefs;
uint16_t enc_sampfreq;
int16_t enc_interval;
int16_t enc_msSinceSID;
int32_t enc_Energy;
int16_t enc_reflCoefs[WEBRTC_CNG_MAX_LPC_ORDER + 1];
int32_t enc_corrVector[WEBRTC_CNG_MAX_LPC_ORDER + 1];
uint32_t enc_seed;
int16_t errorcode;
int16_t initflag;
} WebRtcCngEncInst_t;
const int32_t WebRtcCng_kDbov[94] = {
1081109975, 858756178, 682134279, 541838517, 430397633, 341876992,
271562548, 215709799, 171344384, 136103682, 108110997, 85875618,
68213428, 54183852, 43039763, 34187699, 27156255, 21570980,
17134438, 13610368, 10811100, 8587562, 6821343, 5418385,
4303976, 3418770, 2715625, 2157098, 1713444, 1361037,
1081110, 858756, 682134, 541839, 430398, 341877,
271563, 215710, 171344, 136104, 108111, 85876,
68213, 54184, 43040, 34188, 27156, 21571,
17134, 13610, 10811, 8588, 6821, 5418,
4304, 3419, 2716, 2157, 1713, 1361,
1081, 859, 682, 542, 430, 342,
272, 216, 171, 136, 108, 86,
68, 54, 43, 34, 27, 22,
17, 14, 11, 9, 7, 5,
4, 3, 3, 2, 2, 1,
1, 1, 1, 1
};
const int16_t WebRtcCng_kCorrWindow[WEBRTC_CNG_MAX_LPC_ORDER] = {
32702, 32636, 32570, 32505, 32439, 32374,
32309, 32244, 32179, 32114, 32049, 31985
};
/****************************************************************************
* WebRtcCng_CreateEnc/Dec(...)
*
* These functions create an instance to the specified structure
*
* Input:
* - XXX_inst : Pointer to created instance that should be created
*
* Return value : 0 - Ok
* -1 - Error
*/
int16_t WebRtcCng_CreateEnc(CNG_enc_inst** cng_inst) {
if (cng_inst != NULL) {
*cng_inst = (CNG_enc_inst*) malloc(sizeof(WebRtcCngEncInst_t));
if (*cng_inst != NULL) {
(*(WebRtcCngEncInst_t**) cng_inst)->errorcode = 0;
(*(WebRtcCngEncInst_t**) cng_inst)->initflag = 0;
/* Needed to get the right function pointers in SPLIB. */
WebRtcSpl_Init();
return 0;
} else {
/* The memory could not be allocated. */
return -1;
}
} else {
/* The input pointer is invalid (NULL). */
return -1;
}
}
int16_t WebRtcCng_CreateDec(CNG_dec_inst** cng_inst) {
if (cng_inst != NULL ) {
*cng_inst = (CNG_dec_inst*) malloc(sizeof(WebRtcCngDecInst_t));
if (*cng_inst != NULL ) {
(*(WebRtcCngDecInst_t**) cng_inst)->errorcode = 0;
(*(WebRtcCngDecInst_t**) cng_inst)->initflag = 0;
/* Needed to get the right function pointers in SPLIB. */
WebRtcSpl_Init();
return 0;
} else {
/* The memory could not be allocated */
return -1;
}
} else {
/* The input pointer is invalid (NULL). */
return -1;
}
}
/****************************************************************************
* WebRtcCng_InitEnc/Dec(...)
*
* This function initializes a instance
*
* Input:
* - cng_inst : Instance that should be initialized
*
* - fs : 8000 for narrowband and 16000 for wideband
* - interval : generate SID data every interval ms
* - quality : TBD
*
* Output:
* - cng_inst : Initialized instance
*
* Return value : 0 - Ok
* -1 - Error
*/
int16_t WebRtcCng_InitEnc(CNG_enc_inst* cng_inst, uint16_t fs, int16_t interval,
int16_t quality) {
int i;
WebRtcCngEncInst_t* inst = (WebRtcCngEncInst_t*) cng_inst;
memset(inst, 0, sizeof(WebRtcCngEncInst_t));
/* Check LPC order */
if (quality > WEBRTC_CNG_MAX_LPC_ORDER || quality <= 0) {
inst->errorcode = CNG_DISALLOWED_LPC_ORDER;
return -1;
}
inst->enc_sampfreq = fs;
inst->enc_interval = interval;
inst->enc_nrOfCoefs = quality;
inst->enc_msSinceSID = 0;
inst->enc_seed = 7777; /* For debugging only. */
inst->enc_Energy = 0;
for (i = 0; i < (WEBRTC_CNG_MAX_LPC_ORDER + 1); i++) {
inst->enc_reflCoefs[i] = 0;
inst->enc_corrVector[i] = 0;
}
inst->initflag = 1;
return 0;
}
int16_t WebRtcCng_InitDec(CNG_dec_inst* cng_inst) {
int i;
WebRtcCngDecInst_t* inst = (WebRtcCngDecInst_t*) cng_inst;
memset(inst, 0, sizeof(WebRtcCngDecInst_t));
inst->dec_seed = 7777; /* For debugging only. */
inst->dec_order = 5;
inst->dec_target_scale_factor = 0;
inst->dec_used_scale_factor = 0;
for (i = 0; i < (WEBRTC_CNG_MAX_LPC_ORDER + 1); i++) {
inst->dec_filtstate[i] = 0;
inst->dec_target_reflCoefs[i] = 0;
inst->dec_used_reflCoefs[i] = 0;
}
inst->dec_target_reflCoefs[0] = 0;
inst->dec_used_reflCoefs[0] = 0;
inst->dec_used_energy = 0;
inst->initflag = 1;
return 0;
}
/****************************************************************************
* WebRtcCng_FreeEnc/Dec(...)
*
* These functions frees the dynamic memory of a specified instance
*
* Input:
* - cng_inst : Pointer to created instance that should be freed
*
* Return value : 0 - Ok
* -1 - Error
*/
int16_t WebRtcCng_FreeEnc(CNG_enc_inst* cng_inst) {
free(cng_inst);
return 0;
}
int16_t WebRtcCng_FreeDec(CNG_dec_inst* cng_inst) {
free(cng_inst);
return 0;
}
/****************************************************************************
* WebRtcCng_Encode(...)
*
* These functions analyzes background noise
*
* Input:
* - cng_inst : Pointer to created instance
* - speech : Signal (noise) to be analyzed
* - nrOfSamples : Size of speech vector
* - bytesOut : Nr of bytes to transmit, might be 0
*
* Return value : 0 - Ok
* -1 - Error
*/
int16_t WebRtcCng_Encode(CNG_enc_inst* cng_inst, int16_t* speech,
int16_t nrOfSamples, uint8_t* SIDdata,
int16_t* bytesOut, int16_t forceSID) {
WebRtcCngEncInst_t* inst = (WebRtcCngEncInst_t*) cng_inst;
int16_t arCoefs[WEBRTC_CNG_MAX_LPC_ORDER + 1];
int32_t corrVector[WEBRTC_CNG_MAX_LPC_ORDER + 1];
int16_t refCs[WEBRTC_CNG_MAX_LPC_ORDER + 1];
int16_t hanningW[WEBRTC_CNG_MAX_OUTSIZE_ORDER];
int16_t ReflBeta = 19661; /* 0.6 in q15. */
int16_t ReflBetaComp = 13107; /* 0.4 in q15. */
int32_t outEnergy;
int outShifts;
int i, stab;
int acorrScale;
int index;
int16_t ind, factor;
int32_t* bptr;
int32_t blo, bhi;
int16_t negate;
const int16_t* aptr;
int16_t speechBuf[WEBRTC_CNG_MAX_OUTSIZE_ORDER];
/* Check if encoder initiated. */
if (inst->initflag != 1) {
inst->errorcode = CNG_ENCODER_NOT_INITIATED;
return -1;
}
/* Check framesize. */
if (nrOfSamples > WEBRTC_CNG_MAX_OUTSIZE_ORDER) {
inst->errorcode = CNG_DISALLOWED_FRAME_SIZE;
return -1;
}
for (i = 0; i < nrOfSamples; i++) {
speechBuf[i] = speech[i];
}
factor = nrOfSamples;
/* Calculate energy and a coefficients. */
outEnergy = WebRtcSpl_Energy(speechBuf, nrOfSamples, &outShifts);
while (outShifts > 0) {
/* We can only do 5 shifts without destroying accuracy in
* division factor. */
if (outShifts > 5) {
outEnergy <<= (outShifts - 5);
outShifts = 5;
} else {
factor /= 2;
outShifts--;
}
}
outEnergy = WebRtcSpl_DivW32W16(outEnergy, factor);
if (outEnergy > 1) {
/* Create Hanning Window. */
WebRtcSpl_GetHanningWindow(hanningW, nrOfSamples / 2);
for (i = 0; i < (nrOfSamples / 2); i++)
hanningW[nrOfSamples - i - 1] = hanningW[i];
WebRtcSpl_ElementwiseVectorMult(speechBuf, hanningW, speechBuf, nrOfSamples,
14);
WebRtcSpl_AutoCorrelation(speechBuf, nrOfSamples, inst->enc_nrOfCoefs,
corrVector, &acorrScale);
if (*corrVector == 0)
*corrVector = WEBRTC_SPL_WORD16_MAX;
/* Adds the bandwidth expansion. */
aptr = WebRtcCng_kCorrWindow;
bptr = corrVector;
/* (zzz) lpc16_1 = 17+1+820+2+2 = 842 (ordo2=700). */
for (ind = 0; ind < inst->enc_nrOfCoefs; ind++) {
/* The below code multiplies the 16 b corrWindow values (Q15) with
* the 32 b corrvector (Q0) and shifts the result down 15 steps. */
negate = *bptr < 0;
if (negate)
*bptr = -*bptr;
blo = (int32_t) * aptr * (*bptr & 0xffff);
bhi = ((blo >> 16) & 0xffff)
+ ((int32_t)(*aptr++) * ((*bptr >> 16) & 0xffff));
blo = (blo & 0xffff) | ((bhi & 0xffff) << 16);
*bptr = (((bhi >> 16) & 0x7fff) << 17) | ((uint32_t) blo >> 15);
if (negate)
*bptr = -*bptr;
bptr++;
}
/* End of bandwidth expansion. */
stab = WebRtcSpl_LevinsonDurbin(corrVector, arCoefs, refCs,
inst->enc_nrOfCoefs);
if (!stab) {
/* Disregard from this frame */
*bytesOut = 0;
return 0;
}
} else {
for (i = 0; i < inst->enc_nrOfCoefs; i++)
refCs[i] = 0;
}
if (forceSID) {
/* Read instantaneous values instead of averaged. */
for (i = 0; i < inst->enc_nrOfCoefs; i++)
inst->enc_reflCoefs[i] = refCs[i];
inst->enc_Energy = outEnergy;
} else {
/* Average history with new values. */
for (i = 0; i < (inst->enc_nrOfCoefs); i++) {
inst->enc_reflCoefs[i] = (int16_t) WEBRTC_SPL_MUL_16_16_RSFT(
inst->enc_reflCoefs[i], ReflBeta, 15);
inst->enc_reflCoefs[i] += (int16_t) WEBRTC_SPL_MUL_16_16_RSFT(
refCs[i], ReflBetaComp, 15);
}
inst->enc_Energy = (outEnergy >> 2) + (inst->enc_Energy >> 1)
+ (inst->enc_Energy >> 2);
}
if (inst->enc_Energy < 1) {
inst->enc_Energy = 1;
}
if ((inst->enc_msSinceSID > (inst->enc_interval - 1)) || forceSID) {
/* Search for best dbov value. */
index = 0;
for (i = 1; i < 93; i++) {
/* Always round downwards. */
if ((inst->enc_Energy - WebRtcCng_kDbov[i]) > 0) {
index = i;
break;
}
}
if ((i == 93) && (index == 0))
index = 94;
SIDdata[0] = index;
/* Quantize coefficients with tweak for WebRtc implementation of RFC3389. */
if (inst->enc_nrOfCoefs == WEBRTC_CNG_MAX_LPC_ORDER) {
for (i = 0; i < inst->enc_nrOfCoefs; i++) {
/* Q15 to Q7 with rounding. */
SIDdata[i + 1] = ((inst->enc_reflCoefs[i] + 128) >> 8);
}
} else {
for (i = 0; i < inst->enc_nrOfCoefs; i++) {
/* Q15 to Q7 with rounding. */
SIDdata[i + 1] = (127 + ((inst->enc_reflCoefs[i] + 128) >> 8));
}
}
inst->enc_msSinceSID = 0;
*bytesOut = inst->enc_nrOfCoefs + 1;
inst->enc_msSinceSID += (1000 * nrOfSamples) / inst->enc_sampfreq;
return inst->enc_nrOfCoefs + 1;
} else {
inst->enc_msSinceSID += (1000 * nrOfSamples) / inst->enc_sampfreq;
*bytesOut = 0;
return 0;
}
}
/****************************************************************************
* WebRtcCng_UpdateSid(...)
*
* These functions updates the CN state, when a new SID packet arrives
*
* Input:
* - cng_inst : Pointer to created instance that should be freed
* - SID : SID packet, all headers removed
* - length : Length in bytes of SID packet
*
* Return value : 0 - Ok
* -1 - Error
*/
int16_t WebRtcCng_UpdateSid(CNG_dec_inst* cng_inst, uint8_t* SID,
int16_t length) {
WebRtcCngDecInst_t* inst = (WebRtcCngDecInst_t*) cng_inst;
int16_t refCs[WEBRTC_CNG_MAX_LPC_ORDER];
int32_t targetEnergy;
int i;
if (inst->initflag != 1) {
inst->errorcode = CNG_DECODER_NOT_INITIATED;
return -1;
}
/* Throw away reflection coefficients of higher order than we can handle. */
if (length > (WEBRTC_CNG_MAX_LPC_ORDER + 1))
length = WEBRTC_CNG_MAX_LPC_ORDER + 1;
inst->dec_order = length - 1;
if (SID[0] > 93)
SID[0] = 93;
targetEnergy = WebRtcCng_kDbov[SID[0]];
/* Take down target energy to 75%. */
targetEnergy = targetEnergy >> 1;
targetEnergy += targetEnergy >> 2;
inst->dec_target_energy = targetEnergy;
/* Reconstruct coeffs with tweak for WebRtc implementation of RFC3389. */
if (inst->dec_order == WEBRTC_CNG_MAX_LPC_ORDER) {
for (i = 0; i < (inst->dec_order); i++) {
refCs[i] = SID[i + 1] << 8; /* Q7 to Q15*/
inst->dec_target_reflCoefs[i] = refCs[i];
}
} else {
for (i = 0; i < (inst->dec_order); i++) {
refCs[i] = (SID[i + 1] - 127) << 8; /* Q7 to Q15. */
inst->dec_target_reflCoefs[i] = refCs[i];
}
}
for (i = (inst->dec_order); i < WEBRTC_CNG_MAX_LPC_ORDER; i++) {
refCs[i] = 0;
inst->dec_target_reflCoefs[i] = refCs[i];
}
return 0;
}
/****************************************************************************
* WebRtcCng_Generate(...)
*
* These functions generates CN data when needed
*
* Input:
* - cng_inst : Pointer to created instance that should be freed
* - outData : pointer to area to write CN data
* - nrOfSamples : How much data to generate
*
* Return value : 0 - Ok
* -1 - Error
*/
int16_t WebRtcCng_Generate(CNG_dec_inst* cng_inst, int16_t* outData,
int16_t nrOfSamples, int16_t new_period) {
WebRtcCngDecInst_t* inst = (WebRtcCngDecInst_t*) cng_inst;
int i;
int16_t excitation[WEBRTC_CNG_MAX_OUTSIZE_ORDER];
int16_t low[WEBRTC_CNG_MAX_OUTSIZE_ORDER];
int16_t lpPoly[WEBRTC_CNG_MAX_LPC_ORDER + 1];
int16_t ReflBetaStd = 26214; /* 0.8 in q15. */
int16_t ReflBetaCompStd = 6553; /* 0.2 in q15. */
int16_t ReflBetaNewP = 19661; /* 0.6 in q15. */
int16_t ReflBetaCompNewP = 13107; /* 0.4 in q15. */
int16_t Beta, BetaC, tmp1, tmp2, tmp3;
int32_t targetEnergy;
int16_t En;
int16_t temp16;
if (nrOfSamples > WEBRTC_CNG_MAX_OUTSIZE_ORDER) {
inst->errorcode = CNG_DISALLOWED_FRAME_SIZE;
return -1;
}
if (new_period) {
inst->dec_used_scale_factor = inst->dec_target_scale_factor;
Beta = ReflBetaNewP;
BetaC = ReflBetaCompNewP;
} else {
Beta = ReflBetaStd;
BetaC = ReflBetaCompStd;
}
/* Here we use a 0.5 weighting, should possibly be modified to 0.6. */
tmp1 = inst->dec_used_scale_factor << 2; /* Q13->Q15 */
tmp2 = inst->dec_target_scale_factor << 2; /* Q13->Q15 */
tmp3 = (int16_t) WEBRTC_SPL_MUL_16_16_RSFT(tmp1, Beta, 15);
tmp3 += (int16_t) WEBRTC_SPL_MUL_16_16_RSFT(tmp2, BetaC, 15);
inst->dec_used_scale_factor = tmp3 >> 2; /* Q15->Q13 */
inst->dec_used_energy = inst->dec_used_energy >> 1;
inst->dec_used_energy += inst->dec_target_energy >> 1;
/* Do the same for the reflection coeffs. */
for (i = 0; i < WEBRTC_CNG_MAX_LPC_ORDER; i++) {
inst->dec_used_reflCoefs[i] = (int16_t) WEBRTC_SPL_MUL_16_16_RSFT(
inst->dec_used_reflCoefs[i], Beta, 15);
inst->dec_used_reflCoefs[i] += (int16_t) WEBRTC_SPL_MUL_16_16_RSFT(
inst->dec_target_reflCoefs[i], BetaC, 15);
}
/* Compute the polynomial coefficients. */
WebRtcCng_K2a16(inst->dec_used_reflCoefs, WEBRTC_CNG_MAX_LPC_ORDER, lpPoly);
targetEnergy = inst->dec_used_energy;
/* Calculate scaling factor based on filter energy. */
En = 8192; /* 1.0 in Q13. */
for (i = 0; i < (WEBRTC_CNG_MAX_LPC_ORDER); i++) {
/* Floating point value for reference.
E *= 1.0 - (inst->dec_used_reflCoefs[i] / 32768.0) *
(inst->dec_used_reflCoefs[i] / 32768.0);
*/
/* Same in fixed point. */
/* K(i).^2 in Q15. */
temp16 = (int16_t) WEBRTC_SPL_MUL_16_16_RSFT(
inst->dec_used_reflCoefs[i], inst->dec_used_reflCoefs[i], 15);
/* 1 - K(i).^2 in Q15. */
temp16 = 0x7fff - temp16;
En = (int16_t) WEBRTC_SPL_MUL_16_16_RSFT(En, temp16, 15);
}
/* float scaling= sqrt(E * inst->dec_target_energy / (1 << 24)); */
/* Calculate sqrt(En * target_energy / excitation energy) */
targetEnergy = WebRtcSpl_Sqrt(inst->dec_used_energy);
En = (int16_t) WebRtcSpl_Sqrt(En) << 6;
En = (En * 3) >> 1; /* 1.5 estimates sqrt(2). */
inst->dec_used_scale_factor = (int16_t)((En * targetEnergy) >> 12);
/* Generate excitation. */
/* Excitation energy per sample is 2.^24 - Q13 N(0,1). */
for (i = 0; i < nrOfSamples; i++) {
excitation[i] = WebRtcSpl_RandN(&inst->dec_seed) >> 1;
}
/* Scale to correct energy. */
WebRtcSpl_ScaleVector(excitation, excitation, inst->dec_used_scale_factor,
nrOfSamples, 13);
/* |lpPoly| - Coefficients in Q12.
* |excitation| - Speech samples.
* |nst->dec_filtstate| - State preservation.
* |outData| - Filtered speech samples. */
WebRtcSpl_FilterAR(lpPoly, WEBRTC_CNG_MAX_LPC_ORDER + 1, excitation,
nrOfSamples, inst->dec_filtstate, WEBRTC_CNG_MAX_LPC_ORDER,
inst->dec_filtstateLow, WEBRTC_CNG_MAX_LPC_ORDER, outData,
low, nrOfSamples);
return 0;
}
/****************************************************************************
* WebRtcCng_GetErrorCodeEnc/Dec(...)
*
* This functions can be used to check the error code of a CNG instance. When
* a function returns -1 a error code will be set for that instance. The
* function below extract the code of the last error that occured in the
* specified instance.
*
* Input:
* - CNG_inst : CNG enc/dec instance
*
* Return value : Error code
*/
int16_t WebRtcCng_GetErrorCodeEnc(CNG_enc_inst* cng_inst) {
/* Typecast pointer to real structure. */
WebRtcCngEncInst_t* inst = (WebRtcCngEncInst_t*) cng_inst;
return inst->errorcode;
}
int16_t WebRtcCng_GetErrorCodeDec(CNG_dec_inst* cng_inst) {
/* Typecast pointer to real structure. */
WebRtcCngDecInst_t* inst = (WebRtcCngDecInst_t*) cng_inst;
return inst->errorcode;
}

View File

@@ -0,0 +1,40 @@
# 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.
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
include $(LOCAL_PATH)/../../../../../android-webrtc.mk
LOCAL_ARM_MODE := arm
LOCAL_MODULE_CLASS := STATIC_LIBRARIES
LOCAL_MODULE := libwebrtc_g711
LOCAL_MODULE_TAGS := optional
LOCAL_GENERATED_SOURCES :=
LOCAL_SRC_FILES := \
g711_interface.c \
g711.c
# Flags passed to both C and C++ files.
LOCAL_CFLAGS := \
$(MY_WEBRTC_COMMON_DEFS)
LOCAL_C_INCLUDES := \
$(LOCAL_PATH)/include \
$(LOCAL_PATH)/../../../..
LOCAL_SHARED_LIBRARIES := \
libcutils \
libdl \
libstlport
ifndef NDK_ROOT
include external/stlport/libstlport.mk
endif
include $(BUILD_STATIC_LIBRARY)

View File

@@ -0,0 +1,5 @@
# These are for the common case of adding or renaming files. If you're doing
# structural changes, please get a review from a reviewer in this file.
per-file *.gyp=*
per-file *.gypi=*

View File

@@ -0,0 +1,73 @@
/*
* SpanDSP - a series of DSP components for telephony
*
* g711.c - A-law and u-law transcoding routines
*
* Written by Steve Underwood <steveu@coppice.org>
*
* Copyright (C) 2006 Steve Underwood
*
* Despite my general liking of the GPL, I place this code in the
* public domain for the benefit of all mankind - even the slimy
* ones who might try to proprietize my work and use it to my
* detriment.
*
* $Id: g711.c,v 1.1 2006/06/07 15:46:39 steveu Exp $
*
* Modifications for WebRtc, 2011/04/28, by tlegrand:
* -Removed unused include files
* -Changed to use WebRtc types
* -Added option to run encoder bitexact with ITU-T reference implementation
*/
#include "g711.h"
#include "typedefs.h"
/* Copied from the CCITT G.711 specification */
static const uint8_t ulaw_to_alaw_table[256] = {
42, 43, 40, 41, 46, 47, 44, 45, 34, 35, 32, 33, 38, 39, 36,
37, 58, 59, 56, 57, 62, 63, 60, 61, 50, 51, 48, 49, 54, 55,
52, 53, 10, 11, 8, 9, 14, 15, 12, 13, 2, 3, 0, 1, 6,
7, 4, 26, 27, 24, 25, 30, 31, 28, 29, 18, 19, 16, 17, 22,
23, 20, 21, 106, 104, 105, 110, 111, 108, 109, 98, 99, 96, 97, 102,
103, 100, 101, 122, 120, 126, 127, 124, 125, 114, 115, 112, 113, 118, 119,
116, 117, 75, 73, 79, 77, 66, 67, 64, 65, 70, 71, 68, 69, 90,
91, 88, 89, 94, 95, 92, 93, 82, 82, 83, 83, 80, 80, 81, 81,
86, 86, 87, 87, 84, 84, 85, 85, 170, 171, 168, 169, 174, 175, 172,
173, 162, 163, 160, 161, 166, 167, 164, 165, 186, 187, 184, 185, 190, 191,
188, 189, 178, 179, 176, 177, 182, 183, 180, 181, 138, 139, 136, 137, 142,
143, 140, 141, 130, 131, 128, 129, 134, 135, 132, 154, 155, 152, 153, 158,
159, 156, 157, 146, 147, 144, 145, 150, 151, 148, 149, 234, 232, 233, 238,
239, 236, 237, 226, 227, 224, 225, 230, 231, 228, 229, 250, 248, 254, 255,
252, 253, 242, 243, 240, 241, 246, 247, 244, 245, 203, 201, 207, 205, 194,
195, 192, 193, 198, 199, 196, 197, 218, 219, 216, 217, 222, 223, 220, 221,
210, 210, 211, 211, 208, 208, 209, 209, 214, 214, 215, 215, 212, 212, 213,
213
};
/* These transcoding tables are copied from the CCITT G.711 specification. To
achieve optimal results, do not change them. */
static const uint8_t alaw_to_ulaw_table[256] = {
42, 43, 40, 41, 46, 47, 44, 45, 34, 35, 32, 33, 38, 39, 36,
37, 57, 58, 55, 56, 61, 62, 59, 60, 49, 50, 47, 48, 53, 54,
51, 52, 10, 11, 8, 9, 14, 15, 12, 13, 2, 3, 0, 1, 6,
7, 4, 5, 26, 27, 24, 25, 30, 31, 28, 29, 18, 19, 16, 17,
22, 23, 20, 21, 98, 99, 96, 97, 102, 103, 100, 101, 93, 93, 92,
92, 95, 95, 94, 94, 116, 118, 112, 114, 124, 126, 120, 122, 106, 107,
104, 105, 110, 111, 108, 109, 72, 73, 70, 71, 76, 77, 74, 75, 64,
65, 63, 63, 68, 69, 66, 67, 86, 87, 84, 85, 90, 91, 88, 89,
79, 79, 78, 78, 82, 83, 80, 81, 170, 171, 168, 169, 174, 175, 172,
173, 162, 163, 160, 161, 166, 167, 164, 165, 185, 186, 183, 184, 189, 190,
187, 188, 177, 178, 175, 176, 181, 182, 179, 180, 138, 139, 136, 137, 142,
143, 140, 141, 130, 131, 128, 129, 134, 135, 132, 133, 154, 155, 152, 153,
158, 159, 156, 157, 146, 147, 144, 145, 150, 151, 148, 149, 226, 227, 224,
225, 230, 231, 228, 229, 221, 221, 220, 220, 223, 223, 222, 222, 244, 246,
240, 242, 252, 254, 248, 250, 234, 235, 232, 233, 238, 239, 236, 237, 200,
201, 198, 199, 204, 205, 202, 203, 192, 193, 191, 191, 196, 197, 194, 195,
214, 215, 212, 213, 218, 219, 216, 217, 207, 207, 206, 206, 210, 211, 208,
209
};
uint8_t alaw_to_ulaw(uint8_t alaw) { return alaw_to_ulaw_table[alaw]; }
uint8_t ulaw_to_alaw(uint8_t ulaw) { return ulaw_to_alaw_table[ulaw]; }

View File

@@ -0,0 +1,48 @@
# 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.
{
'targets': [
{
'target_name': 'G711',
'type': 'static_library',
'include_dirs': [
'include',
'<(webrtc_root)',
],
'direct_dependent_settings': {
'include_dirs': [
'include',
'<(webrtc_root)',
],
},
'sources': [
'include/g711_interface.h',
'g711_interface.c',
'g711.c',
'g711.h',
],
},
], # targets
'conditions': [
['include_tests==1', {
'targets': [
{
'target_name': 'g711_test',
'type': 'executable',
'dependencies': [
'G711',
],
'sources': [
'test/testG711.cc',
],
},
], # targets
}], # include_tests
], # conditions
}

View File

@@ -0,0 +1,344 @@
/*
* SpanDSP - a series of DSP components for telephony
*
* g711.h - In line A-law and u-law conversion routines
*
* Written by Steve Underwood <steveu@coppice.org>
*
* Copyright (C) 2001 Steve Underwood
*
* Despite my general liking of the GPL, I place this code in the
* public domain for the benefit of all mankind - even the slimy
* ones who might try to proprietize my work and use it to my
* detriment.
*
* $Id: g711.h,v 1.1 2006/06/07 15:46:39 steveu Exp $
*
* Modifications for WebRtc, 2011/04/28, by tlegrand:
* -Changed to use WebRtc types
* -Changed __inline__ to __inline
* -Two changes to make implementation bitexact with ITU-T reference implementation
*/
/*! \page g711_page A-law and mu-law handling
Lookup tables for A-law and u-law look attractive, until you consider the impact
on the CPU cache. If it causes a substantial area of your processor cache to get
hit too often, cache sloshing will severely slow things down. The main reason
these routines are slow in C, is the lack of direct access to the CPU's "find
the first 1" instruction. A little in-line assembler fixes that, and the
conversion routines can be faster than lookup tables, in most real world usage.
A "find the first 1" instruction is available on most modern CPUs, and is a
much underused feature.
If an assembly language method of bit searching is not available, these routines
revert to a method that can be a little slow, so the cache thrashing might not
seem so bad :(
Feel free to submit patches to add fast "find the first 1" support for your own
favourite processor.
Look up tables are used for transcoding between A-law and u-law, since it is
difficult to achieve the precise transcoding procedure laid down in the G.711
specification by other means.
*/
#if !defined(_G711_H_)
#define _G711_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "typedefs.h"
#if defined(__i386__)
/*! \brief Find the bit position of the highest set bit in a word
\param bits The word to be searched
\return The bit number of the highest set bit, or -1 if the word is zero. */
static __inline__ int top_bit(unsigned int bits) {
int res;
__asm__ __volatile__(" movl $-1,%%edx;\n"
" bsrl %%eax,%%edx;\n"
: "=d" (res)
: "a" (bits));
return res;
}
/*! \brief Find the bit position of the lowest set bit in a word
\param bits The word to be searched
\return The bit number of the lowest set bit, or -1 if the word is zero. */
static __inline__ int bottom_bit(unsigned int bits) {
int res;
__asm__ __volatile__(" movl $-1,%%edx;\n"
" bsfl %%eax,%%edx;\n"
: "=d" (res)
: "a" (bits));
return res;
}
#elif defined(__x86_64__)
static __inline__ int top_bit(unsigned int bits) {
int res;
__asm__ __volatile__(" movq $-1,%%rdx;\n"
" bsrq %%rax,%%rdx;\n"
: "=d" (res)
: "a" (bits));
return res;
}
static __inline__ int bottom_bit(unsigned int bits) {
int res;
__asm__ __volatile__(" movq $-1,%%rdx;\n"
" bsfq %%rax,%%rdx;\n"
: "=d" (res)
: "a" (bits));
return res;
}
#else
static __inline int top_bit(unsigned int bits) {
int i;
if (bits == 0) {
return -1;
}
i = 0;
if (bits & 0xFFFF0000) {
bits &= 0xFFFF0000;
i += 16;
}
if (bits & 0xFF00FF00) {
bits &= 0xFF00FF00;
i += 8;
}
if (bits & 0xF0F0F0F0) {
bits &= 0xF0F0F0F0;
i += 4;
}
if (bits & 0xCCCCCCCC) {
bits &= 0xCCCCCCCC;
i += 2;
}
if (bits & 0xAAAAAAAA) {
bits &= 0xAAAAAAAA;
i += 1;
}
return i;
}
static __inline int bottom_bit(unsigned int bits) {
int i;
if (bits == 0) {
return -1;
}
i = 32;
if (bits & 0x0000FFFF) {
bits &= 0x0000FFFF;
i -= 16;
}
if (bits & 0x00FF00FF) {
bits &= 0x00FF00FF;
i -= 8;
}
if (bits & 0x0F0F0F0F) {
bits &= 0x0F0F0F0F;
i -= 4;
}
if (bits & 0x33333333) {
bits &= 0x33333333;
i -= 2;
}
if (bits & 0x55555555) {
bits &= 0x55555555;
i -= 1;
}
return i;
}
#endif
/* N.B. It is tempting to use look-up tables for A-law and u-law conversion.
* However, you should consider the cache footprint.
*
* A 64K byte table for linear to x-law and a 512 byte table for x-law to
* linear sound like peanuts these days, and shouldn't an array lookup be
* real fast? No! When the cache sloshes as badly as this one will, a tight
* calculation may be better. The messiest part is normally finding the
* segment, but a little inline assembly can fix that on an i386, x86_64 and
* many other modern processors.
*/
/*
* Mu-law is basically as follows:
*
* Biased Linear Input Code Compressed Code
* ------------------------ ---------------
* 00000001wxyza 000wxyz
* 0000001wxyzab 001wxyz
* 000001wxyzabc 010wxyz
* 00001wxyzabcd 011wxyz
* 0001wxyzabcde 100wxyz
* 001wxyzabcdef 101wxyz
* 01wxyzabcdefg 110wxyz
* 1wxyzabcdefgh 111wxyz
*
* Each biased linear code has a leading 1 which identifies the segment
* number. The value of the segment number is equal to 7 minus the number
* of leading 0's. The quantization interval is directly available as the
* four bits wxyz. * The trailing bits (a - h) are ignored.
*
* Ordinarily the complement of the resulting code word is used for
* transmission, and so the code word is complemented before it is returned.
*
* For further information see John C. Bellamy's Digital Telephony, 1982,
* John Wiley & Sons, pps 98-111 and 472-476.
*/
//#define ULAW_ZEROTRAP /* turn on the trap as per the MIL-STD */
#define ULAW_BIAS 0x84 /* Bias for linear code. */
/*! \brief Encode a linear sample to u-law
\param linear The sample to encode.
\return The u-law value.
*/
static __inline uint8_t linear_to_ulaw(int linear) {
uint8_t u_val;
int mask;
int seg;
/* Get the sign and the magnitude of the value. */
if (linear < 0) {
/* WebRtc, tlegrand: -1 added to get bitexact to reference implementation */
linear = ULAW_BIAS - linear - 1;
mask = 0x7F;
} else {
linear = ULAW_BIAS + linear;
mask = 0xFF;
}
seg = top_bit(linear | 0xFF) - 7;
/*
* Combine the sign, segment, quantization bits,
* and complement the code word.
*/
if (seg >= 8)
u_val = (uint8_t)(0x7F ^ mask);
else
u_val = (uint8_t)(((seg << 4) | ((linear >> (seg + 3)) & 0xF)) ^ mask);
#ifdef ULAW_ZEROTRAP
/* Optional ITU trap */
if (u_val == 0)
u_val = 0x02;
#endif
return u_val;
}
/*! \brief Decode an u-law sample to a linear value.
\param ulaw The u-law sample to decode.
\return The linear value.
*/
static __inline int16_t ulaw_to_linear(uint8_t ulaw) {
int t;
/* Complement to obtain normal u-law value. */
ulaw = ~ulaw;
/*
* Extract and bias the quantization bits. Then
* shift up by the segment number and subtract out the bias.
*/
t = (((ulaw & 0x0F) << 3) + ULAW_BIAS) << (((int) ulaw & 0x70) >> 4);
return (int16_t)((ulaw & 0x80) ? (ULAW_BIAS - t) : (t - ULAW_BIAS));
}
/*
* A-law is basically as follows:
*
* Linear Input Code Compressed Code
* ----------------- ---------------
* 0000000wxyza 000wxyz
* 0000001wxyza 001wxyz
* 000001wxyzab 010wxyz
* 00001wxyzabc 011wxyz
* 0001wxyzabcd 100wxyz
* 001wxyzabcde 101wxyz
* 01wxyzabcdef 110wxyz
* 1wxyzabcdefg 111wxyz
*
* For further information see John C. Bellamy's Digital Telephony, 1982,
* John Wiley & Sons, pps 98-111 and 472-476.
*/
#define ALAW_AMI_MASK 0x55
/*! \brief Encode a linear sample to A-law
\param linear The sample to encode.
\return The A-law value.
*/
static __inline uint8_t linear_to_alaw(int linear) {
int mask;
int seg;
if (linear >= 0) {
/* Sign (bit 7) bit = 1 */
mask = ALAW_AMI_MASK | 0x80;
} else {
/* Sign (bit 7) bit = 0 */
mask = ALAW_AMI_MASK;
/* WebRtc, tlegrand: Changed from -8 to -1 to get bitexact to reference
* implementation */
linear = -linear - 1;
}
/* Convert the scaled magnitude to segment number. */
seg = top_bit(linear | 0xFF) - 7;
if (seg >= 8) {
if (linear >= 0) {
/* Out of range. Return maximum value. */
return (uint8_t)(0x7F ^ mask);
}
/* We must be just a tiny step below zero */
return (uint8_t)(0x00 ^ mask);
}
/* Combine the sign, segment, and quantization bits. */
return (uint8_t)(((seg << 4) | ((linear >> ((seg) ? (seg + 3) : 4)) & 0x0F)) ^
mask);
}
/*! \brief Decode an A-law sample to a linear value.
\param alaw The A-law sample to decode.
\return The linear value.
*/
static __inline int16_t alaw_to_linear(uint8_t alaw) {
int i;
int seg;
alaw ^= ALAW_AMI_MASK;
i = ((alaw & 0x0F) << 4);
seg = (((int) alaw & 0x70) >> 4);
if (seg)
i = (i + 0x108) << (seg - 1);
else
i += 8;
return (int16_t)((alaw & 0x80) ? i : -i);
}
/*! \brief Transcode from A-law to u-law, using the procedure defined in G.711.
\param alaw The A-law sample to transcode.
\return The best matching u-law value.
*/
uint8_t alaw_to_ulaw(uint8_t alaw);
/*! \brief Transcode from u-law to A-law, using the procedure defined in G.711.
\param alaw The u-law sample to transcode.
\return The best matching A-law value.
*/
uint8_t ulaw_to_alaw(uint8_t ulaw);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,175 @@
/*
* 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.
*/
#include <string.h>
#include "g711.h"
#include "g711_interface.h"
#include "typedefs.h"
int16_t WebRtcG711_EncodeA(void* state,
int16_t* speechIn,
int16_t len,
int16_t* encoded) {
int n;
uint16_t tempVal, tempVal2;
// Set and discard to avoid getting warnings
(void)(state = NULL);
// Sanity check of input length
if (len < 0) {
return (-1);
}
// Loop over all samples
for (n = 0; n < len; n++) {
tempVal = (uint16_t) linear_to_alaw(speechIn[n]);
#ifdef WEBRTC_ARCH_BIG_ENDIAN
if ((n & 0x1) == 1) {
encoded[n >> 1] |= ((uint16_t) tempVal);
} else {
encoded[n >> 1] = ((uint16_t) tempVal) << 8;
}
#else
if ((n & 0x1) == 1) {
tempVal2 |= ((uint16_t) tempVal) << 8;
encoded[n >> 1] |= ((uint16_t) tempVal) << 8;
} else {
tempVal2 = ((uint16_t) tempVal);
encoded[n >> 1] = ((uint16_t) tempVal);
}
#endif
}
return (len);
}
int16_t WebRtcG711_EncodeU(void* state,
int16_t* speechIn,
int16_t len,
int16_t* encoded) {
int n;
uint16_t tempVal;
// Set and discard to avoid getting warnings
(void)(state = NULL);
// Sanity check of input length
if (len < 0) {
return (-1);
}
// Loop over all samples
for (n = 0; n < len; n++) {
tempVal = (uint16_t) linear_to_ulaw(speechIn[n]);
#ifdef WEBRTC_ARCH_BIG_ENDIAN
if ((n & 0x1) == 1) {
encoded[n >> 1] |= ((uint16_t) tempVal);
} else {
encoded[n >> 1] = ((uint16_t) tempVal) << 8;
}
#else
if ((n & 0x1) == 1) {
encoded[n >> 1] |= ((uint16_t) tempVal) << 8;
} else {
encoded[n >> 1] = ((uint16_t) tempVal);
}
#endif
}
return (len);
}
int16_t WebRtcG711_DecodeA(void* state,
int16_t* encoded,
int16_t len,
int16_t* decoded,
int16_t* speechType) {
int n;
uint16_t tempVal;
// Set and discard to avoid getting warnings
(void)(state = NULL);
// Sanity check of input length
if (len < 0) {
return (-1);
}
for (n = 0; n < len; n++) {
#ifdef WEBRTC_ARCH_BIG_ENDIAN
if ((n & 0x1) == 1) {
tempVal = ((uint16_t) encoded[n >> 1] & 0xFF);
} else {
tempVal = ((uint16_t) encoded[n >> 1] >> 8);
}
#else
if ((n & 0x1) == 1) {
tempVal = (encoded[n >> 1] >> 8);
} else {
tempVal = (encoded[n >> 1] & 0xFF);
}
#endif
decoded[n] = (int16_t) alaw_to_linear(tempVal);
}
*speechType = 1;
return (len);
}
int16_t WebRtcG711_DecodeU(void* state,
int16_t* encoded,
int16_t len,
int16_t* decoded,
int16_t* speechType) {
int n;
uint16_t tempVal;
// Set and discard to avoid getting warnings
(void)(state = NULL);
// Sanity check of input length
if (len < 0) {
return (-1);
}
for (n = 0; n < len; n++) {
#ifdef WEBRTC_ARCH_BIG_ENDIAN
if ((n & 0x1) == 1) {
tempVal = ((uint16_t) encoded[n >> 1] & 0xFF);
} else {
tempVal = ((uint16_t) encoded[n >> 1] >> 8);
}
#else
if ((n & 0x1) == 1) {
tempVal = (encoded[n >> 1] >> 8);
} else {
tempVal = (encoded[n >> 1] & 0xFF);
}
#endif
decoded[n] = (int16_t) ulaw_to_linear(tempVal);
}
*speechType = 1;
return (len);
}
int WebRtcG711_DurationEst(void* state,
const uint8_t* payload,
int payload_length_bytes) {
(void) state;
(void) payload;
/* G.711 is one byte per sample, so we can just return the number of bytes. */
return payload_length_bytes;
}
int16_t WebRtcG711_Version(char* version, int16_t lenBytes) {
strncpy(version, "2.0.0", lenBytes);
return 0;
}

View File

@@ -0,0 +1,167 @@
/*
* 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.
*/
#ifndef MODULES_AUDIO_CODING_CODECS_G711_MAIN_INTERFACE_G711_INTERFACE_H_
#define MODULES_AUDIO_CODING_CODECS_G711_MAIN_INTERFACE_G711_INTERFACE_H_
#include "typedefs.h"
// Comfort noise constants
#define G711_WEBRTC_SPEECH 1
#define G711_WEBRTC_CNG 2
#ifdef __cplusplus
extern "C" {
#endif
/****************************************************************************
* WebRtcG711_EncodeA(...)
*
* This function encodes a G711 A-law frame and inserts it into a packet.
* Input speech length has be of any length.
*
* Input:
* - state : Dummy state to make this codec look more like
* other codecs
* - speechIn : Input speech vector
* - len : Samples in speechIn
*
* Output:
* - encoded : The encoded data vector
*
* Return value : >0 - Length (in bytes) of coded data
* -1 - Error
*/
int16_t WebRtcG711_EncodeA(void* state,
int16_t* speechIn,
int16_t len,
int16_t* encoded);
/****************************************************************************
* WebRtcG711_EncodeU(...)
*
* This function encodes a G711 U-law frame and inserts it into a packet.
* Input speech length has be of any length.
*
* Input:
* - state : Dummy state to make this codec look more like
* other codecs
* - speechIn : Input speech vector
* - len : Samples in speechIn
*
* Output:
* - encoded : The encoded data vector
*
* Return value : >0 - Length (in bytes) of coded data
* -1 - Error
*/
int16_t WebRtcG711_EncodeU(void* state,
int16_t* speechIn,
int16_t len,
int16_t* encoded);
/****************************************************************************
* WebRtcG711_DecodeA(...)
*
* This function decodes a packet G711 A-law frame.
*
* Input:
* - state : Dummy state to make this codec look more like
* other codecs
* - encoded : Encoded data
* - len : Bytes in encoded vector
*
* Output:
* - decoded : The decoded vector
* - speechType : 1 normal, 2 CNG (for G711 it should
* always return 1 since G711 does not have a
* built-in DTX/CNG scheme)
*
* Return value : >0 - Samples in decoded vector
* -1 - Error
*/
int16_t WebRtcG711_DecodeA(void* state,
int16_t* encoded,
int16_t len,
int16_t* decoded,
int16_t* speechType);
/****************************************************************************
* WebRtcG711_DecodeU(...)
*
* This function decodes a packet G711 U-law frame.
*
* Input:
* - state : Dummy state to make this codec look more like
* other codecs
* - encoded : Encoded data
* - len : Bytes in encoded vector
*
* Output:
* - decoded : The decoded vector
* - speechType : 1 normal, 2 CNG (for G711 it should
* always return 1 since G711 does not have a
* built-in DTX/CNG scheme)
*
* Return value : >0 - Samples in decoded vector
* -1 - Error
*/
int16_t WebRtcG711_DecodeU(void* state,
int16_t* encoded,
int16_t len,
int16_t* decoded,
int16_t* speechType);
/****************************************************************************
* WebRtcG711_DurationEst(...)
*
* This function estimates the duration of a G711 packet in samples.
*
* Input:
* - state : Dummy state to make this codec look more like
* other codecs
* - payload : Encoded data
* - payloadLengthBytes : Bytes in encoded vector
*
* Return value : The duration of the packet in samples, which is
* just payload_length_bytes, since G.711 uses one
* byte per sample.
*/
int WebRtcG711_DurationEst(void* state,
const uint8_t* payload,
int payload_length_bytes);
/**********************************************************************
* WebRtcG711_Version(...)
*
* This function gives the version string of the G.711 codec.
*
* Input:
* - lenBytes: the size of Allocated space (in Bytes) where
* the version number is written to (in string format).
*
* Output:
* - version: Pointer to a buffer where the version number is
* written to.
*
*/
int16_t WebRtcG711_Version(char* version, int16_t lenBytes);
#ifdef __cplusplus
}
#endif
#endif /* MODULES_AUDIO_CODING_CODECS_G711_MAIN_INTERFACE_G711_INTERFACE_H_ */

View File

@@ -0,0 +1,180 @@
/*
* 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.
*/
/*
* testG711.cpp : Defines the entry point for the console application.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* include API */
#include "g711_interface.h"
/* Runtime statistics */
#include <time.h>
#define CLOCKS_PER_SEC_G711 1000
/* function for reading audio data from PCM file */
int readframe(int16_t* data, FILE* inp, int length) {
short k, rlen, status = 0;
rlen = (short) fread(data, sizeof(int16_t), length, inp);
if (rlen < length) {
for (k = rlen; k < length; k++)
data[k] = 0;
status = 1;
}
return status;
}
int main(int argc, char* argv[]) {
char inname[80], outname[40], bitname[40];
FILE* inp;
FILE* outp;
FILE* bitp = NULL;
int framecnt, endfile;
int16_t framelength = 80;
int err;
/* Runtime statistics */
double starttime;
double runtime;
double length_file;
int16_t stream_len = 0;
int16_t shortdata[480];
int16_t decoded[480];
int16_t streamdata[500];
int16_t speechType[1];
char law[2];
char versionNumber[40];
/* handling wrong input arguments in the command line */
if ((argc != 5) && (argc != 6)) {
printf("\n\nWrong number of arguments or flag values.\n\n");
printf("\n");
printf("\nG.711 test application\n\n");
printf("Usage:\n\n");
printf("./testG711.exe framelength law infile outfile \n\n");
printf("framelength: Framelength in samples.\n");
printf("law : Coding law, A och u.\n");
printf("infile : Normal speech input file\n");
printf("outfile : Speech output file\n\n");
printf("outbits : Output bitstream file [optional]\n\n");
exit(0);
}
/* Get version and print */
WebRtcG711_Version(versionNumber, 40);
printf("-----------------------------------\n");
printf("G.711 version: %s\n\n", versionNumber);
/* Get frame length */
framelength = atoi(argv[1]);
/* Get compression law */
strcpy(law, argv[2]);
/* Get Input and Output files */
sscanf(argv[3], "%s", inname);
sscanf(argv[4], "%s", outname);
if (argc == 6) {
sscanf(argv[5], "%s", bitname);
if ((bitp = fopen(bitname, "wb")) == NULL) {
printf(" G.711: Cannot read file %s.\n", bitname);
exit(1);
}
}
if ((inp = fopen(inname, "rb")) == NULL) {
printf(" G.711: Cannot read file %s.\n", inname);
exit(1);
}
if ((outp = fopen(outname, "wb")) == NULL) {
printf(" G.711: Cannot write file %s.\n", outname);
exit(1);
}
printf("\nInput: %s\nOutput: %s\n", inname, outname);
if (argc == 6) {
printf("\nBitfile: %s\n", bitname);
}
starttime = clock() / (double) CLOCKS_PER_SEC_G711; /* Runtime statistics */
/* Initialize encoder and decoder */
framecnt = 0;
endfile = 0;
while (endfile == 0) {
framecnt++;
/* Read speech block */
endfile = readframe(shortdata, inp, framelength);
/* G.711 encoding */
if (!strcmp(law, "A")) {
/* A-law encoding */
stream_len = WebRtcG711_EncodeA(NULL, shortdata, framelength, streamdata);
if (argc == 6) {
/* Write bits to file */
if (fwrite(streamdata, sizeof(unsigned char), stream_len, bitp) !=
static_cast<size_t>(stream_len)) {
return -1;
}
}
err = WebRtcG711_DecodeA(NULL, streamdata, stream_len, decoded,
speechType);
} else if (!strcmp(law, "u")) {
/* u-law encoding */
stream_len = WebRtcG711_EncodeU(NULL, shortdata, framelength, streamdata);
if (argc == 6) {
/* Write bits to file */
if (fwrite(streamdata, sizeof(unsigned char), stream_len, bitp) !=
static_cast<size_t>(stream_len)) {
return -1;
}
}
err = WebRtcG711_DecodeU(NULL, streamdata, stream_len, decoded,
speechType);
} else {
printf("Wrong law mode\n");
exit(1);
}
if (stream_len < 0 || err < 0) {
/* exit if returned with error */
printf("Error in encoder/decoder\n");
} else {
/* Write coded speech to file */
if (fwrite(decoded, sizeof(short), framelength, outp) !=
static_cast<size_t>(framelength)) {
return -1;
}
}
}
runtime = (double)(clock() / (double) CLOCKS_PER_SEC_G711 - starttime);
length_file = ((double) framecnt * (double) framelength / 8000);
printf("\n\nLength of speech file: %.1f s\n", length_file);
printf("Time to run G.711: %.2f s (%.2f %% of realtime)\n\n",
runtime,
(100 * runtime / length_file));
printf("---------------------END----------------------\n");
fclose(inp);
fclose(outp);
return 0;
}

View File

@@ -0,0 +1,5 @@
# These are for the common case of adding or renaming files. If you're doing
# structural changes, please get a review from a reviewer in this file.
per-file *.gyp=*
per-file *.gypi=*

View File

@@ -0,0 +1,48 @@
# 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.
{
'targets': [
{
'target_name': 'G722',
'type': 'static_library',
'include_dirs': [
'include',
'<(webrtc_root)',
],
'direct_dependent_settings': {
'include_dirs': [
'include',
'<(webrtc_root)',
],
},
'sources': [
'include/g722_interface.h',
'g722_interface.c',
'g722_encode.c',
'g722_decode.c',
'g722_enc_dec.h',
],
},
], # targets
'conditions': [
['include_tests==1', {
'targets': [
{
'target_name': 'G722Test',
'type': 'executable',
'dependencies': [
'G722',
],
'sources': [
'test/testG722.cc',
],
},
], # targets
}], # include_tests
], # conditions
}

View File

@@ -0,0 +1,410 @@
/*
* SpanDSP - a series of DSP components for telephony
*
* g722_decode.c - The ITU G.722 codec, decode part.
*
* Written by Steve Underwood <steveu@coppice.org>
*
* Copyright (C) 2005 Steve Underwood
*
* Despite my general liking of the GPL, I place my own contributions
* to this code in the public domain for the benefit of all mankind -
* even the slimy ones who might try to proprietize my work and use it
* to my detriment.
*
* Based in part on a single channel G.722 codec which is:
*
* Copyright (c) CMU 1993
* Computer Science, Speech Group
* Chengxiang Lu and Alex Hauptmann
*
* $Id: g722_decode.c,v 1.15 2006/07/07 16:37:49 steveu Exp $
*
* Modifications for WebRtc, 2011/04/28, by tlegrand:
* -Removed usage of inttypes.h and tgmath.h
* -Changed to use WebRtc types
* -Changed __inline__ to __inline
* -Added saturation check on output
*/
/*! \file */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h>
#include <memory.h>
#include <stdlib.h>
#include "typedefs.h"
#include "g722_enc_dec.h"
#if !defined(FALSE)
#define FALSE 0
#endif
#if !defined(TRUE)
#define TRUE (!FALSE)
#endif
static __inline int16_t saturate(int32_t amp)
{
int16_t amp16;
/* Hopefully this is optimised for the common case - not clipping */
amp16 = (int16_t) amp;
if (amp == amp16)
return amp16;
if (amp > WEBRTC_INT16_MAX)
return WEBRTC_INT16_MAX;
return WEBRTC_INT16_MIN;
}
/*- End of function --------------------------------------------------------*/
static void block4(g722_decode_state_t *s, int band, int d);
static void block4(g722_decode_state_t *s, int band, int d)
{
int wd1;
int wd2;
int wd3;
int i;
/* Block 4, RECONS */
s->band[band].d[0] = d;
s->band[band].r[0] = saturate(s->band[band].s + d);
/* Block 4, PARREC */
s->band[band].p[0] = saturate(s->band[band].sz + d);
/* Block 4, UPPOL2 */
for (i = 0; i < 3; i++)
s->band[band].sg[i] = s->band[band].p[i] >> 15;
wd1 = saturate(s->band[band].a[1] << 2);
wd2 = (s->band[band].sg[0] == s->band[band].sg[1]) ? -wd1 : wd1;
if (wd2 > 32767)
wd2 = 32767;
wd3 = (s->band[band].sg[0] == s->band[band].sg[2]) ? 128 : -128;
wd3 += (wd2 >> 7);
wd3 += (s->band[band].a[2]*32512) >> 15;
if (wd3 > 12288)
wd3 = 12288;
else if (wd3 < -12288)
wd3 = -12288;
s->band[band].ap[2] = wd3;
/* Block 4, UPPOL1 */
s->band[band].sg[0] = s->band[band].p[0] >> 15;
s->band[band].sg[1] = s->band[band].p[1] >> 15;
wd1 = (s->band[band].sg[0] == s->band[band].sg[1]) ? 192 : -192;
wd2 = (s->band[band].a[1]*32640) >> 15;
s->band[band].ap[1] = saturate(wd1 + wd2);
wd3 = saturate(15360 - s->band[band].ap[2]);
if (s->band[band].ap[1] > wd3)
s->band[band].ap[1] = wd3;
else if (s->band[band].ap[1] < -wd3)
s->band[band].ap[1] = -wd3;
/* Block 4, UPZERO */
wd1 = (d == 0) ? 0 : 128;
s->band[band].sg[0] = d >> 15;
for (i = 1; i < 7; i++)
{
s->band[band].sg[i] = s->band[band].d[i] >> 15;
wd2 = (s->band[band].sg[i] == s->band[band].sg[0]) ? wd1 : -wd1;
wd3 = (s->band[band].b[i]*32640) >> 15;
s->band[band].bp[i] = saturate(wd2 + wd3);
}
/* Block 4, DELAYA */
for (i = 6; i > 0; i--)
{
s->band[band].d[i] = s->band[band].d[i - 1];
s->band[band].b[i] = s->band[band].bp[i];
}
for (i = 2; i > 0; i--)
{
s->band[band].r[i] = s->band[band].r[i - 1];
s->band[band].p[i] = s->band[band].p[i - 1];
s->band[band].a[i] = s->band[band].ap[i];
}
/* Block 4, FILTEP */
wd1 = saturate(s->band[band].r[1] + s->band[band].r[1]);
wd1 = (s->band[band].a[1]*wd1) >> 15;
wd2 = saturate(s->band[band].r[2] + s->band[band].r[2]);
wd2 = (s->band[band].a[2]*wd2) >> 15;
s->band[band].sp = saturate(wd1 + wd2);
/* Block 4, FILTEZ */
s->band[band].sz = 0;
for (i = 6; i > 0; i--)
{
wd1 = saturate(s->band[band].d[i] + s->band[band].d[i]);
s->band[band].sz += (s->band[band].b[i]*wd1) >> 15;
}
s->band[band].sz = saturate(s->band[band].sz);
/* Block 4, PREDIC */
s->band[band].s = saturate(s->band[band].sp + s->band[band].sz);
}
/*- End of function --------------------------------------------------------*/
g722_decode_state_t *WebRtc_g722_decode_init(g722_decode_state_t *s,
int rate,
int options)
{
if (s == NULL)
{
if ((s = (g722_decode_state_t *) malloc(sizeof(*s))) == NULL)
return NULL;
}
memset(s, 0, sizeof(*s));
if (rate == 48000)
s->bits_per_sample = 6;
else if (rate == 56000)
s->bits_per_sample = 7;
else
s->bits_per_sample = 8;
if ((options & G722_SAMPLE_RATE_8000))
s->eight_k = TRUE;
if ((options & G722_PACKED) && s->bits_per_sample != 8)
s->packed = TRUE;
else
s->packed = FALSE;
s->band[0].det = 32;
s->band[1].det = 8;
return s;
}
/*- End of function --------------------------------------------------------*/
int WebRtc_g722_decode_release(g722_decode_state_t *s)
{
free(s);
return 0;
}
/*- End of function --------------------------------------------------------*/
int WebRtc_g722_decode(g722_decode_state_t *s, int16_t amp[],
const uint8_t g722_data[], int len)
{
static const int wl[8] = {-60, -30, 58, 172, 334, 538, 1198, 3042 };
static const int rl42[16] = {0, 7, 6, 5, 4, 3, 2, 1,
7, 6, 5, 4, 3, 2, 1, 0 };
static const int ilb[32] =
{
2048, 2093, 2139, 2186, 2233, 2282, 2332,
2383, 2435, 2489, 2543, 2599, 2656, 2714,
2774, 2834, 2896, 2960, 3025, 3091, 3158,
3228, 3298, 3371, 3444, 3520, 3597, 3676,
3756, 3838, 3922, 4008
};
static const int wh[3] = {0, -214, 798};
static const int rh2[4] = {2, 1, 2, 1};
static const int qm2[4] = {-7408, -1616, 7408, 1616};
static const int qm4[16] =
{
0, -20456, -12896, -8968,
-6288, -4240, -2584, -1200,
20456, 12896, 8968, 6288,
4240, 2584, 1200, 0
};
static const int qm5[32] =
{
-280, -280, -23352, -17560,
-14120, -11664, -9752, -8184,
-6864, -5712, -4696, -3784,
-2960, -2208, -1520, -880,
23352, 17560, 14120, 11664,
9752, 8184, 6864, 5712,
4696, 3784, 2960, 2208,
1520, 880, 280, -280
};
static const int qm6[64] =
{
-136, -136, -136, -136,
-24808, -21904, -19008, -16704,
-14984, -13512, -12280, -11192,
-10232, -9360, -8576, -7856,
-7192, -6576, -6000, -5456,
-4944, -4464, -4008, -3576,
-3168, -2776, -2400, -2032,
-1688, -1360, -1040, -728,
24808, 21904, 19008, 16704,
14984, 13512, 12280, 11192,
10232, 9360, 8576, 7856,
7192, 6576, 6000, 5456,
4944, 4464, 4008, 3576,
3168, 2776, 2400, 2032,
1688, 1360, 1040, 728,
432, 136, -432, -136
};
static const int qmf_coeffs[12] =
{
3, -11, 12, 32, -210, 951, 3876, -805, 362, -156, 53, -11,
};
int dlowt;
int rlow;
int ihigh;
int dhigh;
int rhigh;
int xout1;
int xout2;
int wd1;
int wd2;
int wd3;
int code;
int outlen;
int i;
int j;
outlen = 0;
rhigh = 0;
for (j = 0; j < len; )
{
if (s->packed)
{
/* Unpack the code bits */
if (s->in_bits < s->bits_per_sample)
{
s->in_buffer |= (g722_data[j++] << s->in_bits);
s->in_bits += 8;
}
code = s->in_buffer & ((1 << s->bits_per_sample) - 1);
s->in_buffer >>= s->bits_per_sample;
s->in_bits -= s->bits_per_sample;
}
else
{
code = g722_data[j++];
}
switch (s->bits_per_sample)
{
default:
case 8:
wd1 = code & 0x3F;
ihigh = (code >> 6) & 0x03;
wd2 = qm6[wd1];
wd1 >>= 2;
break;
case 7:
wd1 = code & 0x1F;
ihigh = (code >> 5) & 0x03;
wd2 = qm5[wd1];
wd1 >>= 1;
break;
case 6:
wd1 = code & 0x0F;
ihigh = (code >> 4) & 0x03;
wd2 = qm4[wd1];
break;
}
/* Block 5L, LOW BAND INVQBL */
wd2 = (s->band[0].det*wd2) >> 15;
/* Block 5L, RECONS */
rlow = s->band[0].s + wd2;
/* Block 6L, LIMIT */
if (rlow > 16383)
rlow = 16383;
else if (rlow < -16384)
rlow = -16384;
/* Block 2L, INVQAL */
wd2 = qm4[wd1];
dlowt = (s->band[0].det*wd2) >> 15;
/* Block 3L, LOGSCL */
wd2 = rl42[wd1];
wd1 = (s->band[0].nb*127) >> 7;
wd1 += wl[wd2];
if (wd1 < 0)
wd1 = 0;
else if (wd1 > 18432)
wd1 = 18432;
s->band[0].nb = wd1;
/* Block 3L, SCALEL */
wd1 = (s->band[0].nb >> 6) & 31;
wd2 = 8 - (s->band[0].nb >> 11);
wd3 = (wd2 < 0) ? (ilb[wd1] << -wd2) : (ilb[wd1] >> wd2);
s->band[0].det = wd3 << 2;
block4(s, 0, dlowt);
if (!s->eight_k)
{
/* Block 2H, INVQAH */
wd2 = qm2[ihigh];
dhigh = (s->band[1].det*wd2) >> 15;
/* Block 5H, RECONS */
rhigh = dhigh + s->band[1].s;
/* Block 6H, LIMIT */
if (rhigh > 16383)
rhigh = 16383;
else if (rhigh < -16384)
rhigh = -16384;
/* Block 2H, INVQAH */
wd2 = rh2[ihigh];
wd1 = (s->band[1].nb*127) >> 7;
wd1 += wh[wd2];
if (wd1 < 0)
wd1 = 0;
else if (wd1 > 22528)
wd1 = 22528;
s->band[1].nb = wd1;
/* Block 3H, SCALEH */
wd1 = (s->band[1].nb >> 6) & 31;
wd2 = 10 - (s->band[1].nb >> 11);
wd3 = (wd2 < 0) ? (ilb[wd1] << -wd2) : (ilb[wd1] >> wd2);
s->band[1].det = wd3 << 2;
block4(s, 1, dhigh);
}
if (s->itu_test_mode)
{
amp[outlen++] = (int16_t) (rlow << 1);
amp[outlen++] = (int16_t) (rhigh << 1);
}
else
{
if (s->eight_k)
{
amp[outlen++] = (int16_t) (rlow << 1);
}
else
{
/* Apply the receive QMF */
for (i = 0; i < 22; i++)
s->x[i] = s->x[i + 2];
s->x[22] = rlow + rhigh;
s->x[23] = rlow - rhigh;
xout1 = 0;
xout2 = 0;
for (i = 0; i < 12; i++)
{
xout2 += s->x[2*i]*qmf_coeffs[i];
xout1 += s->x[2*i + 1]*qmf_coeffs[11 - i];
}
/* We shift by 12 to allow for the QMF filters (DC gain = 4096), less 1
to allow for the 15 bit input to the G.722 algorithm. */
/* WebRtc, tlegrand: added saturation */
amp[outlen++] = saturate(xout1 >> 11);
amp[outlen++] = saturate(xout2 >> 11);
}
}
}
return outlen;
}
/*- End of function --------------------------------------------------------*/
/*- End of file ------------------------------------------------------------*/

View File

@@ -0,0 +1,158 @@
/*
* SpanDSP - a series of DSP components for telephony
*
* g722.h - The ITU G.722 codec.
*
* Written by Steve Underwood <steveu@coppice.org>
*
* Copyright (C) 2005 Steve Underwood
*
* Despite my general liking of the GPL, I place my own contributions
* to this code in the public domain for the benefit of all mankind -
* even the slimy ones who might try to proprietize my work and use it
* to my detriment.
*
* Based on a single channel G.722 codec which is:
*
***** Copyright (c) CMU 1993 *****
* Computer Science, Speech Group
* Chengxiang Lu and Alex Hauptmann
*
* $Id: g722.h,v 1.10 2006/06/16 12:45:53 steveu Exp $
*
* Modifications for WebRtc, 2011/04/28, by tlegrand:
* -Changed to use WebRtc types
* -Added new defines for minimum and maximum values of short int
*/
/*! \file */
#if !defined(_G722_ENC_DEC_H_)
#define _G722_ENC_DEC_H_
/*! \page g722_page G.722 encoding and decoding
\section g722_page_sec_1 What does it do?
The G.722 module is a bit exact implementation of the ITU G.722 specification for all three
specified bit rates - 64000bps, 56000bps and 48000bps. It passes the ITU tests.
To allow fast and flexible interworking with narrow band telephony, the encoder and decoder
support an option for the linear audio to be an 8k samples/second stream. In this mode the
codec is considerably faster, and still fully compatible with wideband terminals using G.722.
\section g722_page_sec_2 How does it work?
???.
*/
#define WEBRTC_INT16_MAX 32767
#define WEBRTC_INT16_MIN -32768
enum
{
G722_SAMPLE_RATE_8000 = 0x0001,
G722_PACKED = 0x0002
};
typedef struct
{
/*! TRUE if the operating in the special ITU test mode, with the band split filters
disabled. */
int itu_test_mode;
/*! TRUE if the G.722 data is packed */
int packed;
/*! TRUE if encode from 8k samples/second */
int eight_k;
/*! 6 for 48000kbps, 7 for 56000kbps, or 8 for 64000kbps. */
int bits_per_sample;
/*! Signal history for the QMF */
int x[24];
struct
{
int s;
int sp;
int sz;
int r[3];
int a[3];
int ap[3];
int p[3];
int d[7];
int b[7];
int bp[7];
int sg[7];
int nb;
int det;
} band[2];
unsigned int in_buffer;
int in_bits;
unsigned int out_buffer;
int out_bits;
} g722_encode_state_t;
typedef struct
{
/*! TRUE if the operating in the special ITU test mode, with the band split filters
disabled. */
int itu_test_mode;
/*! TRUE if the G.722 data is packed */
int packed;
/*! TRUE if decode to 8k samples/second */
int eight_k;
/*! 6 for 48000kbps, 7 for 56000kbps, or 8 for 64000kbps. */
int bits_per_sample;
/*! Signal history for the QMF */
int x[24];
struct
{
int s;
int sp;
int sz;
int r[3];
int a[3];
int ap[3];
int p[3];
int d[7];
int b[7];
int bp[7];
int sg[7];
int nb;
int det;
} band[2];
unsigned int in_buffer;
int in_bits;
unsigned int out_buffer;
int out_bits;
} g722_decode_state_t;
#ifdef __cplusplus
extern "C" {
#endif
g722_encode_state_t *WebRtc_g722_encode_init(g722_encode_state_t *s,
int rate,
int options);
int WebRtc_g722_encode_release(g722_encode_state_t *s);
int WebRtc_g722_encode(g722_encode_state_t *s,
uint8_t g722_data[],
const int16_t amp[],
int len);
g722_decode_state_t *WebRtc_g722_decode_init(g722_decode_state_t *s,
int rate,
int options);
int WebRtc_g722_decode_release(g722_decode_state_t *s);
int WebRtc_g722_decode(g722_decode_state_t *s,
int16_t amp[],
const uint8_t g722_data[],
int len);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,434 @@
/*
* SpanDSP - a series of DSP components for telephony
*
* g722_encode.c - The ITU G.722 codec, encode part.
*
* Written by Steve Underwood <steveu@coppice.org>
*
* Copyright (C) 2005 Steve Underwood
*
* All rights reserved.
*
* Despite my general liking of the GPL, I place my own contributions
* to this code in the public domain for the benefit of all mankind -
* even the slimy ones who might try to proprietize my work and use it
* to my detriment.
*
* Based on a single channel 64kbps only G.722 codec which is:
*
***** Copyright (c) CMU 1993 *****
* Computer Science, Speech Group
* Chengxiang Lu and Alex Hauptmann
*
* $Id: g722_encode.c,v 1.14 2006/07/07 16:37:49 steveu Exp $
*
* Modifications for WebRtc, 2011/04/28, by tlegrand:
* -Removed usage of inttypes.h and tgmath.h
* -Changed to use WebRtc types
* -Added option to run encoder bitexact with ITU-T reference implementation
*/
/*! \file */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h>
#include <memory.h>
#include <stdlib.h>
#include "typedefs.h"
#include "g722_enc_dec.h"
#if !defined(FALSE)
#define FALSE 0
#endif
#if !defined(TRUE)
#define TRUE (!FALSE)
#endif
static __inline int16_t saturate(int32_t amp)
{
int16_t amp16;
/* Hopefully this is optimised for the common case - not clipping */
amp16 = (int16_t) amp;
if (amp == amp16)
return amp16;
if (amp > WEBRTC_INT16_MAX)
return WEBRTC_INT16_MAX;
return WEBRTC_INT16_MIN;
}
/*- End of function --------------------------------------------------------*/
static void block4(g722_encode_state_t *s, int band, int d)
{
int wd1;
int wd2;
int wd3;
int i;
/* Block 4, RECONS */
s->band[band].d[0] = d;
s->band[band].r[0] = saturate(s->band[band].s + d);
/* Block 4, PARREC */
s->band[band].p[0] = saturate(s->band[band].sz + d);
/* Block 4, UPPOL2 */
for (i = 0; i < 3; i++)
s->band[band].sg[i] = s->band[band].p[i] >> 15;
wd1 = saturate(s->band[band].a[1] << 2);
wd2 = (s->band[band].sg[0] == s->band[band].sg[1]) ? -wd1 : wd1;
if (wd2 > 32767)
wd2 = 32767;
wd3 = (wd2 >> 7) + ((s->band[band].sg[0] == s->band[band].sg[2]) ? 128 : -128);
wd3 += (s->band[band].a[2]*32512) >> 15;
if (wd3 > 12288)
wd3 = 12288;
else if (wd3 < -12288)
wd3 = -12288;
s->band[band].ap[2] = wd3;
/* Block 4, UPPOL1 */
s->band[band].sg[0] = s->band[band].p[0] >> 15;
s->band[band].sg[1] = s->band[band].p[1] >> 15;
wd1 = (s->band[band].sg[0] == s->band[band].sg[1]) ? 192 : -192;
wd2 = (s->band[band].a[1]*32640) >> 15;
s->band[band].ap[1] = saturate(wd1 + wd2);
wd3 = saturate(15360 - s->band[band].ap[2]);
if (s->band[band].ap[1] > wd3)
s->band[band].ap[1] = wd3;
else if (s->band[band].ap[1] < -wd3)
s->band[band].ap[1] = -wd3;
/* Block 4, UPZERO */
wd1 = (d == 0) ? 0 : 128;
s->band[band].sg[0] = d >> 15;
for (i = 1; i < 7; i++)
{
s->band[band].sg[i] = s->band[band].d[i] >> 15;
wd2 = (s->band[band].sg[i] == s->band[band].sg[0]) ? wd1 : -wd1;
wd3 = (s->band[band].b[i]*32640) >> 15;
s->band[band].bp[i] = saturate(wd2 + wd3);
}
/* Block 4, DELAYA */
for (i = 6; i > 0; i--)
{
s->band[band].d[i] = s->band[band].d[i - 1];
s->band[band].b[i] = s->band[band].bp[i];
}
for (i = 2; i > 0; i--)
{
s->band[band].r[i] = s->band[band].r[i - 1];
s->band[band].p[i] = s->band[band].p[i - 1];
s->band[band].a[i] = s->band[band].ap[i];
}
/* Block 4, FILTEP */
wd1 = saturate(s->band[band].r[1] + s->band[band].r[1]);
wd1 = (s->band[band].a[1]*wd1) >> 15;
wd2 = saturate(s->band[band].r[2] + s->band[band].r[2]);
wd2 = (s->band[band].a[2]*wd2) >> 15;
s->band[band].sp = saturate(wd1 + wd2);
/* Block 4, FILTEZ */
s->band[band].sz = 0;
for (i = 6; i > 0; i--)
{
wd1 = saturate(s->band[band].d[i] + s->band[band].d[i]);
s->band[band].sz += (s->band[band].b[i]*wd1) >> 15;
}
s->band[band].sz = saturate(s->band[band].sz);
/* Block 4, PREDIC */
s->band[band].s = saturate(s->band[band].sp + s->band[band].sz);
}
/*- End of function --------------------------------------------------------*/
g722_encode_state_t *WebRtc_g722_encode_init(g722_encode_state_t *s,
int rate, int options)
{
if (s == NULL)
{
if ((s = (g722_encode_state_t *) malloc(sizeof(*s))) == NULL)
return NULL;
}
memset(s, 0, sizeof(*s));
if (rate == 48000)
s->bits_per_sample = 6;
else if (rate == 56000)
s->bits_per_sample = 7;
else
s->bits_per_sample = 8;
if ((options & G722_SAMPLE_RATE_8000))
s->eight_k = TRUE;
if ((options & G722_PACKED) && s->bits_per_sample != 8)
s->packed = TRUE;
else
s->packed = FALSE;
s->band[0].det = 32;
s->band[1].det = 8;
return s;
}
/*- End of function --------------------------------------------------------*/
int WebRtc_g722_encode_release(g722_encode_state_t *s)
{
free(s);
return 0;
}
/*- End of function --------------------------------------------------------*/
/* WebRtc, tlegrand:
* Only define the following if bit-exactness with reference implementation
* is needed. Will only have any effect if input signal is saturated.
*/
//#define RUN_LIKE_REFERENCE_G722
#ifdef RUN_LIKE_REFERENCE_G722
int16_t limitValues (int16_t rl)
{
int16_t yl;
yl = (rl > 16383) ? 16383 : ((rl < -16384) ? -16384 : rl);
return (yl);
}
#endif
int WebRtc_g722_encode(g722_encode_state_t *s, uint8_t g722_data[],
const int16_t amp[], int len)
{
static const int q6[32] =
{
0, 35, 72, 110, 150, 190, 233, 276,
323, 370, 422, 473, 530, 587, 650, 714,
786, 858, 940, 1023, 1121, 1219, 1339, 1458,
1612, 1765, 1980, 2195, 2557, 2919, 0, 0
};
static const int iln[32] =
{
0, 63, 62, 31, 30, 29, 28, 27,
26, 25, 24, 23, 22, 21, 20, 19,
18, 17, 16, 15, 14, 13, 12, 11,
10, 9, 8, 7, 6, 5, 4, 0
};
static const int ilp[32] =
{
0, 61, 60, 59, 58, 57, 56, 55,
54, 53, 52, 51, 50, 49, 48, 47,
46, 45, 44, 43, 42, 41, 40, 39,
38, 37, 36, 35, 34, 33, 32, 0
};
static const int wl[8] =
{
-60, -30, 58, 172, 334, 538, 1198, 3042
};
static const int rl42[16] =
{
0, 7, 6, 5, 4, 3, 2, 1, 7, 6, 5, 4, 3, 2, 1, 0
};
static const int ilb[32] =
{
2048, 2093, 2139, 2186, 2233, 2282, 2332,
2383, 2435, 2489, 2543, 2599, 2656, 2714,
2774, 2834, 2896, 2960, 3025, 3091, 3158,
3228, 3298, 3371, 3444, 3520, 3597, 3676,
3756, 3838, 3922, 4008
};
static const int qm4[16] =
{
0, -20456, -12896, -8968,
-6288, -4240, -2584, -1200,
20456, 12896, 8968, 6288,
4240, 2584, 1200, 0
};
static const int qm2[4] =
{
-7408, -1616, 7408, 1616
};
static const int qmf_coeffs[12] =
{
3, -11, 12, 32, -210, 951, 3876, -805, 362, -156, 53, -11,
};
static const int ihn[3] = {0, 1, 0};
static const int ihp[3] = {0, 3, 2};
static const int wh[3] = {0, -214, 798};
static const int rh2[4] = {2, 1, 2, 1};
int dlow;
int dhigh;
int el;
int wd;
int wd1;
int ril;
int wd2;
int il4;
int ih2;
int wd3;
int eh;
int mih;
int i;
int j;
/* Low and high band PCM from the QMF */
int xlow;
int xhigh;
int g722_bytes;
/* Even and odd tap accumulators */
int sumeven;
int sumodd;
int ihigh;
int ilow;
int code;
g722_bytes = 0;
xhigh = 0;
for (j = 0; j < len; )
{
if (s->itu_test_mode)
{
xlow =
xhigh = amp[j++] >> 1;
}
else
{
if (s->eight_k)
{
/* We shift by 1 to allow for the 15 bit input to the G.722 algorithm. */
xlow = amp[j++] >> 1;
}
else
{
/* Apply the transmit QMF */
/* Shuffle the buffer down */
for (i = 0; i < 22; i++)
s->x[i] = s->x[i + 2];
s->x[22] = amp[j++];
s->x[23] = amp[j++];
/* Discard every other QMF output */
sumeven = 0;
sumodd = 0;
for (i = 0; i < 12; i++)
{
sumodd += s->x[2*i]*qmf_coeffs[i];
sumeven += s->x[2*i + 1]*qmf_coeffs[11 - i];
}
/* We shift by 12 to allow for the QMF filters (DC gain = 4096), plus 1
to allow for us summing two filters, plus 1 to allow for the 15 bit
input to the G.722 algorithm. */
xlow = (sumeven + sumodd) >> 14;
xhigh = (sumeven - sumodd) >> 14;
#ifdef RUN_LIKE_REFERENCE_G722
/* The following lines are only used to verify bit-exactness
* with reference implementation of G.722. Higher precision
* is achieved without limiting the values.
*/
xlow = limitValues(xlow);
xhigh = limitValues(xhigh);
#endif
}
}
/* Block 1L, SUBTRA */
el = saturate(xlow - s->band[0].s);
/* Block 1L, QUANTL */
wd = (el >= 0) ? el : -(el + 1);
for (i = 1; i < 30; i++)
{
wd1 = (q6[i]*s->band[0].det) >> 12;
if (wd < wd1)
break;
}
ilow = (el < 0) ? iln[i] : ilp[i];
/* Block 2L, INVQAL */
ril = ilow >> 2;
wd2 = qm4[ril];
dlow = (s->band[0].det*wd2) >> 15;
/* Block 3L, LOGSCL */
il4 = rl42[ril];
wd = (s->band[0].nb*127) >> 7;
s->band[0].nb = wd + wl[il4];
if (s->band[0].nb < 0)
s->band[0].nb = 0;
else if (s->band[0].nb > 18432)
s->band[0].nb = 18432;
/* Block 3L, SCALEL */
wd1 = (s->band[0].nb >> 6) & 31;
wd2 = 8 - (s->band[0].nb >> 11);
wd3 = (wd2 < 0) ? (ilb[wd1] << -wd2) : (ilb[wd1] >> wd2);
s->band[0].det = wd3 << 2;
block4(s, 0, dlow);
if (s->eight_k)
{
/* Just leave the high bits as zero */
code = (0xC0 | ilow) >> (8 - s->bits_per_sample);
}
else
{
/* Block 1H, SUBTRA */
eh = saturate(xhigh - s->band[1].s);
/* Block 1H, QUANTH */
wd = (eh >= 0) ? eh : -(eh + 1);
wd1 = (564*s->band[1].det) >> 12;
mih = (wd >= wd1) ? 2 : 1;
ihigh = (eh < 0) ? ihn[mih] : ihp[mih];
/* Block 2H, INVQAH */
wd2 = qm2[ihigh];
dhigh = (s->band[1].det*wd2) >> 15;
/* Block 3H, LOGSCH */
ih2 = rh2[ihigh];
wd = (s->band[1].nb*127) >> 7;
s->band[1].nb = wd + wh[ih2];
if (s->band[1].nb < 0)
s->band[1].nb = 0;
else if (s->band[1].nb > 22528)
s->band[1].nb = 22528;
/* Block 3H, SCALEH */
wd1 = (s->band[1].nb >> 6) & 31;
wd2 = 10 - (s->band[1].nb >> 11);
wd3 = (wd2 < 0) ? (ilb[wd1] << -wd2) : (ilb[wd1] >> wd2);
s->band[1].det = wd3 << 2;
block4(s, 1, dhigh);
code = ((ihigh << 6) | ilow) >> (8 - s->bits_per_sample);
}
if (s->packed)
{
/* Pack the code bits */
s->out_buffer |= (code << s->out_bits);
s->out_bits += s->bits_per_sample;
if (s->out_bits >= 8)
{
g722_data[g722_bytes++] = (uint8_t) (s->out_buffer & 0xFF);
s->out_bits -= 8;
s->out_buffer >>= 8;
}
}
else
{
g722_data[g722_bytes++] = (uint8_t) code;
}
}
return g722_bytes;
}
/*- End of function --------------------------------------------------------*/
/*- End of file ------------------------------------------------------------*/

View File

@@ -0,0 +1,115 @@
/*
* 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.
*/
#include <stdlib.h>
#include <string.h>
#include "g722_interface.h"
#include "g722_enc_dec.h"
#include "typedefs.h"
int16_t WebRtcG722_CreateEncoder(G722EncInst **G722enc_inst)
{
*G722enc_inst=(G722EncInst*)malloc(sizeof(g722_encode_state_t));
if (*G722enc_inst!=NULL) {
return(0);
} else {
return(-1);
}
}
int16_t WebRtcG722_EncoderInit(G722EncInst *G722enc_inst)
{
// Create and/or reset the G.722 encoder
// Bitrate 64 kbps and wideband mode (2)
G722enc_inst = (G722EncInst *) WebRtc_g722_encode_init(
(g722_encode_state_t*) G722enc_inst, 64000, 2);
if (G722enc_inst == NULL) {
return -1;
} else {
return 0;
}
}
int16_t WebRtcG722_FreeEncoder(G722EncInst *G722enc_inst)
{
// Free encoder memory
return WebRtc_g722_encode_release((g722_encode_state_t*) G722enc_inst);
}
int16_t WebRtcG722_Encode(G722EncInst *G722enc_inst,
int16_t *speechIn,
int16_t len,
int16_t *encoded)
{
unsigned char *codechar = (unsigned char*) encoded;
// Encode the input speech vector
return WebRtc_g722_encode((g722_encode_state_t*) G722enc_inst,
codechar, speechIn, len);
}
int16_t WebRtcG722_CreateDecoder(G722DecInst **G722dec_inst)
{
*G722dec_inst=(G722DecInst*)malloc(sizeof(g722_decode_state_t));
if (*G722dec_inst!=NULL) {
return(0);
} else {
return(-1);
}
}
int16_t WebRtcG722_DecoderInit(G722DecInst *G722dec_inst)
{
// Create and/or reset the G.722 decoder
// Bitrate 64 kbps and wideband mode (2)
G722dec_inst = (G722DecInst *) WebRtc_g722_decode_init(
(g722_decode_state_t*) G722dec_inst, 64000, 2);
if (G722dec_inst == NULL) {
return -1;
} else {
return 0;
}
}
int16_t WebRtcG722_FreeDecoder(G722DecInst *G722dec_inst)
{
// Free encoder memory
return WebRtc_g722_decode_release((g722_decode_state_t*) G722dec_inst);
}
int16_t WebRtcG722_Decode(G722DecInst *G722dec_inst,
int16_t *encoded,
int16_t len,
int16_t *decoded,
int16_t *speechType)
{
// Decode the G.722 encoder stream
*speechType=G722_WEBRTC_SPEECH;
return WebRtc_g722_decode((g722_decode_state_t*) G722dec_inst,
decoded, (uint8_t*) encoded, len);
}
int16_t WebRtcG722_Version(char *versionStr, short len)
{
// Get version string
char version[30] = "2.0.0\n";
if (strlen(version) < (unsigned int)len)
{
strcpy(versionStr, version);
return 0;
}
else
{
return -1;
}
}

View File

@@ -0,0 +1,190 @@
/*
* 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.
*/
#ifndef MODULES_AUDIO_CODING_CODECS_G722_MAIN_INTERFACE_G722_INTERFACE_H_
#define MODULES_AUDIO_CODING_CODECS_G722_MAIN_INTERFACE_G722_INTERFACE_H_
#include "typedefs.h"
/*
* Solution to support multiple instances
*/
typedef struct WebRtcG722EncInst G722EncInst;
typedef struct WebRtcG722DecInst G722DecInst;
/*
* Comfort noise constants
*/
#define G722_WEBRTC_SPEECH 1
#define G722_WEBRTC_CNG 2
#ifdef __cplusplus
extern "C" {
#endif
/****************************************************************************
* WebRtcG722_CreateEncoder(...)
*
* Create memory used for G722 encoder
*
* Input:
* - G722enc_inst : G722 instance for encoder
*
* Return value : 0 - Ok
* -1 - Error
*/
int16_t WebRtcG722_CreateEncoder(G722EncInst **G722enc_inst);
/****************************************************************************
* WebRtcG722_EncoderInit(...)
*
* This function initializes a G722 instance
*
* Input:
* - G722enc_inst : G722 instance, i.e. the user that should receive
* be initialized
*
* Return value : 0 - Ok
* -1 - Error
*/
int16_t WebRtcG722_EncoderInit(G722EncInst *G722enc_inst);
/****************************************************************************
* WebRtcG722_FreeEncoder(...)
*
* Free the memory used for G722 encoder
*
* Input:
* - G722enc_inst : G722 instance for encoder
*
* Return value : 0 - Ok
* -1 - Error
*/
int16_t WebRtcG722_FreeEncoder(G722EncInst *G722enc_inst);
/****************************************************************************
* WebRtcG722_Encode(...)
*
* This function encodes G722 encoded data.
*
* Input:
* - G722enc_inst : G722 instance, i.e. the user that should encode
* a packet
* - speechIn : Input speech vector
* - len : Samples in speechIn
*
* Output:
* - encoded : The encoded data vector
*
* Return value : >0 - Length (in bytes) of coded data
* -1 - Error
*/
int16_t WebRtcG722_Encode(G722EncInst *G722enc_inst,
int16_t *speechIn,
int16_t len,
int16_t *encoded);
/****************************************************************************
* WebRtcG722_CreateDecoder(...)
*
* Create memory used for G722 encoder
*
* Input:
* - G722dec_inst : G722 instance for decoder
*
* Return value : 0 - Ok
* -1 - Error
*/
int16_t WebRtcG722_CreateDecoder(G722DecInst **G722dec_inst);
/****************************************************************************
* WebRtcG722_DecoderInit(...)
*
* This function initializes a G729 instance
*
* Input:
* - G729_decinst_t : G729 instance, i.e. the user that should receive
* be initialized
*
* Return value : 0 - Ok
* -1 - Error
*/
int16_t WebRtcG722_DecoderInit(G722DecInst *G722dec_inst);
/****************************************************************************
* WebRtcG722_FreeDecoder(...)
*
* Free the memory used for G722 decoder
*
* Input:
* - G722dec_inst : G722 instance for decoder
*
* Return value : 0 - Ok
* -1 - Error
*/
int16_t WebRtcG722_FreeDecoder(G722DecInst *G722dec_inst);
/****************************************************************************
* WebRtcG722_Decode(...)
*
* This function decodes a packet with G729 frame(s). Output speech length
* will be a multiple of 80 samples (80*frames/packet).
*
* Input:
* - G722dec_inst : G722 instance, i.e. the user that should decode
* a packet
* - encoded : Encoded G722 frame(s)
* - len : Bytes in encoded vector
*
* Output:
* - decoded : The decoded vector
* - speechType : 1 normal, 2 CNG (Since G722 does not have its own
* DTX/CNG scheme it should always return 1)
*
* Return value : >0 - Samples in decoded vector
* -1 - Error
*/
int16_t WebRtcG722_Decode(G722DecInst *G722dec_inst,
int16_t *encoded,
int16_t len,
int16_t *decoded,
int16_t *speechType);
/****************************************************************************
* WebRtcG722_Version(...)
*
* Get a string with the current version of the codec
*/
int16_t WebRtcG722_Version(char *versionStr, short len);
#ifdef __cplusplus
}
#endif
#endif /* MODULES_AUDIO_CODING_CODECS_G722_MAIN_INTERFACE_G722_INTERFACE_H_ */

View File

@@ -0,0 +1,162 @@
/*
* 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.
*/
/*
* testG722.cpp : Defines the entry point for the console application.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "typedefs.h"
/* include API */
#include "g722_interface.h"
/* Runtime statistics */
#include <time.h>
#define CLOCKS_PER_SEC_G722 100000
// Forward declaration
typedef struct WebRtcG722EncInst G722EncInst;
typedef struct WebRtcG722DecInst G722DecInst;
/* function for reading audio data from PCM file */
int readframe(int16_t *data, FILE *inp, int length)
{
short k, rlen, status = 0;
rlen = (short)fread(data, sizeof(int16_t), length, inp);
if (rlen < length) {
for (k = rlen; k < length; k++)
data[k] = 0;
status = 1;
}
return status;
}
int main(int argc, char* argv[])
{
char inname[60], outbit[40], outname[40];
FILE *inp, *outbitp, *outp;
int framecnt, endfile;
int16_t framelength = 160;
G722EncInst *G722enc_inst;
G722DecInst *G722dec_inst;
int err;
/* Runtime statistics */
double starttime;
double runtime = 0;
double length_file;
int16_t stream_len = 0;
int16_t shortdata[960];
int16_t decoded[960];
int16_t streamdata[80*3];
int16_t speechType[1];
/* handling wrong input arguments in the command line */
if (argc!=5) {
printf("\n\nWrong number of arguments or flag values.\n\n");
printf("\n");
printf("Usage:\n\n");
printf("./testG722.exe framelength infile outbitfile outspeechfile \n\n");
printf("with:\n");
printf("framelength : Framelength in samples.\n\n");
printf("infile : Normal speech input file\n\n");
printf("outbitfile : Bitstream output file\n\n");
printf("outspeechfile: Speech output file\n\n");
exit(0);
}
/* Get frame length */
framelength = atoi(argv[1]);
/* Get Input and Output files */
sscanf(argv[2], "%s", inname);
sscanf(argv[3], "%s", outbit);
sscanf(argv[4], "%s", outname);
if ((inp = fopen(inname,"rb")) == NULL) {
printf(" G.722: Cannot read file %s.\n", inname);
exit(1);
}
if ((outbitp = fopen(outbit,"wb")) == NULL) {
printf(" G.722: Cannot write file %s.\n", outbit);
exit(1);
}
if ((outp = fopen(outname,"wb")) == NULL) {
printf(" G.722: Cannot write file %s.\n", outname);
exit(1);
}
printf("\nInput:%s\nOutput bitstream:%s\nOutput:%s\n", inname, outbit, outname);
/* Create and init */
WebRtcG722_CreateEncoder((G722EncInst **)&G722enc_inst);
WebRtcG722_CreateDecoder((G722DecInst **)&G722dec_inst);
WebRtcG722_EncoderInit((G722EncInst *)G722enc_inst);
WebRtcG722_DecoderInit((G722DecInst *)G722dec_inst);
/* Initialize encoder and decoder */
framecnt = 0;
endfile = 0;
while (endfile == 0) {
framecnt++;
/* Read speech block */
endfile = readframe(shortdata, inp, framelength);
/* Start clock before call to encoder and decoder */
starttime = clock()/(double)CLOCKS_PER_SEC_G722;
/* G.722 encoding + decoding */
stream_len = WebRtcG722_Encode((G722EncInst *)G722enc_inst, shortdata, framelength, streamdata);
err = WebRtcG722_Decode((G722DecInst *)G722dec_inst, streamdata, stream_len, decoded, speechType);
/* Stop clock after call to encoder and decoder */
runtime += (double)((clock()/(double)CLOCKS_PER_SEC_G722)-starttime);
if (stream_len < 0 || err < 0) {
/* exit if returned with error */
printf("Error in encoder/decoder\n");
} else {
/* Write coded bits to file */
if (fwrite(streamdata, sizeof(short), stream_len/2,
outbitp) != static_cast<size_t>(stream_len/2)) {
return -1;
}
/* Write coded speech to file */
if (fwrite(decoded, sizeof(short), framelength,
outp) != static_cast<size_t>(framelength)) {
return -1;
}
}
}
WebRtcG722_FreeEncoder((G722EncInst *)G722enc_inst);
WebRtcG722_FreeDecoder((G722DecInst *)G722dec_inst);
length_file = ((double)framecnt*(double)framelength/16000);
printf("\n\nLength of speech file: %.1f s\n", length_file);
printf("Time to run G.722: %.2f s (%.2f %% of realtime)\n\n", runtime, (100*runtime/length_file));
printf("---------------------END----------------------\n");
fclose(inp);
fclose(outbitp);
fclose(outp);
return 0;
}

View File

@@ -0,0 +1,5 @@
# These are for the common case of adding or renaming files. If you're doing
# structural changes, please get a review from a reviewer in this file.
per-file *.gyp=*
per-file *.gypi=*

View File

@@ -0,0 +1,80 @@
/*
* 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.
*/
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
WebRtcIlbcfix_AbsQuant.c
******************************************************************/
#include "defines.h"
#include "constants.h"
#include "abs_quant_loop.h"
/*----------------------------------------------------------------*
* predictive noise shaping encoding of scaled start state
* (subrutine for WebRtcIlbcfix_StateSearch)
*---------------------------------------------------------------*/
void WebRtcIlbcfix_AbsQuant(
iLBC_Enc_Inst_t *iLBCenc_inst,
/* (i) Encoder instance */
iLBC_bits *iLBC_encbits, /* (i/o) Encoded bits (outputs idxForMax
and idxVec, uses state_first as
input) */
int16_t *in, /* (i) vector to encode */
int16_t *weightDenum /* (i) denominator of synthesis filter */
) {
int16_t *syntOut;
int16_t quantLen[2];
/* Stack based */
int16_t syntOutBuf[LPC_FILTERORDER+STATE_SHORT_LEN_30MS];
int16_t in_weightedVec[STATE_SHORT_LEN_30MS+LPC_FILTERORDER];
int16_t *in_weighted = &in_weightedVec[LPC_FILTERORDER];
/* Initialize the buffers */
WebRtcSpl_MemSetW16(syntOutBuf, 0, LPC_FILTERORDER+STATE_SHORT_LEN_30MS);
syntOut = &syntOutBuf[LPC_FILTERORDER];
/* Start with zero state */
WebRtcSpl_MemSetW16(in_weightedVec, 0, LPC_FILTERORDER);
/* Perform the quantization loop in two sections of length quantLen[i],
where the perceptual weighting filter is updated at the subframe
border */
if (iLBC_encbits->state_first) {
quantLen[0]=SUBL;
quantLen[1]=iLBCenc_inst->state_short_len-SUBL;
} else {
quantLen[0]=iLBCenc_inst->state_short_len-SUBL;
quantLen[1]=SUBL;
}
/* Calculate the weighted residual, switch perceptual weighting
filter at the subframe border */
WebRtcSpl_FilterARFastQ12(
in, in_weighted,
weightDenum, LPC_FILTERORDER+1, quantLen[0]);
WebRtcSpl_FilterARFastQ12(
&in[quantLen[0]], &in_weighted[quantLen[0]],
&weightDenum[LPC_FILTERORDER+1], LPC_FILTERORDER+1, quantLen[1]);
WebRtcIlbcfix_AbsQuantLoop(
syntOut,
in_weighted,
weightDenum,
quantLen,
iLBC_encbits->idxVec);
}

View File

@@ -0,0 +1,39 @@
/*
* 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.
*/
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
WebRtcIlbcfix_AbsQuant.h
******************************************************************/
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_ABS_QUANT_H_
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_ABS_QUANT_H_
#include "defines.h"
/*----------------------------------------------------------------*
* predictive noise shaping encoding of scaled start state
* (subrutine for WebRtcIlbcfix_StateSearch)
*---------------------------------------------------------------*/
void WebRtcIlbcfix_AbsQuant(
iLBC_Enc_Inst_t *iLBCenc_inst,
/* (i) Encoder instance */
iLBC_bits *iLBC_encbits, /* (i/o) Encoded bits (outputs idxForMax
and idxVec, uses state_first as
input) */
int16_t *in, /* (i) vector to encode */
int16_t *weightDenum /* (i) denominator of synthesis filter */
);
#endif

View File

@@ -0,0 +1,90 @@
/*
* 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.
*/
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
WebRtcIlbcfix_AbsQuantLoop.c
******************************************************************/
#include "defines.h"
#include "constants.h"
#include "sort_sq.h"
void WebRtcIlbcfix_AbsQuantLoop(int16_t *syntOutIN, int16_t *in_weightedIN,
int16_t *weightDenumIN, int16_t *quantLenIN,
int16_t *idxVecIN ) {
int n, k1, k2;
int16_t index;
int32_t toQW32;
int32_t toQ32;
int16_t tmp16a;
int16_t xq;
int16_t *syntOut = syntOutIN;
int16_t *in_weighted = in_weightedIN;
int16_t *weightDenum = weightDenumIN;
int16_t *quantLen = quantLenIN;
int16_t *idxVec = idxVecIN;
n=0;
for(k1=0;k1<2;k1++) {
for(k2=0;k2<quantLen[k1];k2++){
/* Filter to get the predicted value */
WebRtcSpl_FilterARFastQ12(
syntOut, syntOut,
weightDenum, LPC_FILTERORDER+1, 1);
/* the quantizer */
toQW32 = (int32_t)(*in_weighted) - (int32_t)(*syntOut);
toQ32 = (((int32_t)toQW32)<<2);
if (toQ32 > 32767) {
toQ32 = (int32_t) 32767;
} else if (toQ32 < -32768) {
toQ32 = (int32_t) -32768;
}
/* Quantize the state */
if (toQW32<(-7577)) {
/* To prevent negative overflow */
index=0;
} else if (toQW32>8151) {
/* To prevent positive overflow */
index=7;
} else {
/* Find the best quantization index
(state_sq3Tbl is in Q13 and toQ is in Q11)
*/
WebRtcIlbcfix_SortSq(&xq, &index,
(int16_t)toQ32,
WebRtcIlbcfix_kStateSq3, 8);
}
/* Store selected index */
(*idxVec++) = index;
/* Compute decoded sample and update of the prediction filter */
tmp16a = ((WebRtcIlbcfix_kStateSq3[index] + 2 ) >> 2);
*syntOut = (int16_t) (tmp16a + (int32_t)(*in_weighted) - toQW32);
n++;
syntOut++; in_weighted++;
}
/* Update perceptual weighting filter at subframe border */
weightDenum += 11;
}
}

View File

@@ -0,0 +1,33 @@
/*
* 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.
*/
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
WebRtcIlbcfix_AbsQuantLoop.h
******************************************************************/
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_ABS_QUANT_LOOP_H_
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_ABS_QUANT_LOOP_H_
#include "defines.h"
/*----------------------------------------------------------------*
* predictive noise shaping encoding of scaled start state
* (subrutine for WebRtcIlbcfix_StateSearch)
*---------------------------------------------------------------*/
void WebRtcIlbcfix_AbsQuantLoop(int16_t *syntOutIN, int16_t *in_weightedIN,
int16_t *weightDenumIN, int16_t *quantLenIN,
int16_t *idxVecIN);
#endif

View File

@@ -0,0 +1,63 @@
/*
* 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.
*/
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
WebRtcIlbcfix_AugmentedCbCorr.c
******************************************************************/
#include "defines.h"
#include "constants.h"
#include "augmented_cb_corr.h"
void WebRtcIlbcfix_AugmentedCbCorr(
int16_t *target, /* (i) Target vector */
int16_t *buffer, /* (i) Memory buffer */
int16_t *interpSamples, /* (i) buffer with
interpolated samples */
int32_t *crossDot, /* (o) The cross correlation between
the target and the Augmented
vector */
int16_t low, /* (i) Lag to start from (typically
20) */
int16_t high, /* (i) Lag to end at (typically 39) */
int16_t scale) /* (i) Scale factor to use for
the crossDot */
{
int lagcount;
int16_t ilow;
int16_t *targetPtr;
int32_t *crossDotPtr;
int16_t *iSPtr=interpSamples;
/* Calculate the correlation between the target and the
interpolated codebook. The correlation is calculated in
3 sections with the interpolated part in the middle */
crossDotPtr=crossDot;
for (lagcount=low; lagcount<=high; lagcount++) {
ilow = (int16_t) (lagcount-4);
/* Compute dot product for the first (lagcount-4) samples */
(*crossDotPtr) = WebRtcSpl_DotProductWithScale(target, buffer-lagcount, ilow, scale);
/* Compute dot product on the interpolated samples */
(*crossDotPtr) += WebRtcSpl_DotProductWithScale(target+ilow, iSPtr, 4, scale);
targetPtr = target + lagcount;
iSPtr += lagcount-ilow;
/* Compute dot product for the remaining samples */
(*crossDotPtr) += WebRtcSpl_DotProductWithScale(targetPtr, buffer-lagcount, SUBL-lagcount, scale);
crossDotPtr++;
}
}

View File

@@ -0,0 +1,42 @@
/*
* 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.
*/
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
WebRtcIlbcfix_AugmentedCbCorr.h
******************************************************************/
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_AUGMENTED_CB_CORR_H_
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_AUGMENTED_CB_CORR_H_
#include "defines.h"
/*----------------------------------------------------------------*
* Calculate correlation between target and Augmented codebooks
*---------------------------------------------------------------*/
void WebRtcIlbcfix_AugmentedCbCorr(
int16_t *target, /* (i) Target vector */
int16_t *buffer, /* (i) Memory buffer */
int16_t *interpSamples, /* (i) buffer with
interpolated samples */
int32_t *crossDot, /* (o) The cross correlation between
the target and the Augmented
vector */
int16_t low, /* (i) Lag to start from (typically
20) */
int16_t high, /* (i) Lag to end at (typically 39 */
int16_t scale); /* (i) Scale factor to use for
the crossDot */
#endif

View File

@@ -0,0 +1,42 @@
/*
* 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.
*/
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
WebRtcIlbcfix_BwExpand.c
******************************************************************/
#include "defines.h"
/*----------------------------------------------------------------*
* lpc bandwidth expansion
*---------------------------------------------------------------*/
/* The output is in the same domain as the input */
void WebRtcIlbcfix_BwExpand(
int16_t *out, /* (o) the bandwidth expanded lpc coefficients */
int16_t *in, /* (i) the lpc coefficients before bandwidth
expansion */
int16_t *coef, /* (i) the bandwidth expansion factor Q15 */
int16_t length /* (i) the length of lpc coefficient vectors */
) {
int i;
out[0] = in[0];
for (i = 1; i < length; i++) {
/* out[i] = coef[i] * in[i] with rounding.
in[] and out[] are in Q12 and coef[] is in Q15
*/
out[i] = (int16_t)((WEBRTC_SPL_MUL_16_16(coef[i], in[i])+16384)>>15);
}
}

View File

@@ -0,0 +1,36 @@
/*
* 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.
*/
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
WebRtcIlbcfix_BwExpand.h
******************************************************************/
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_BW_EXPAND_H_
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_BW_EXPAND_H_
#include "defines.h"
/*----------------------------------------------------------------*
* lpc bandwidth expansion
*---------------------------------------------------------------*/
void WebRtcIlbcfix_BwExpand(
int16_t *out, /* (o) the bandwidth expanded lpc coefficients */
int16_t *in, /* (i) the lpc coefficients before bandwidth
expansion */
int16_t *coef, /* (i) the bandwidth expansion factor Q15 */
int16_t length /* (i) the length of lpc coefficient vectors */
);
#endif

View File

@@ -0,0 +1,67 @@
/*
* 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.
*/
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
WebRtcIlbcfix_CbConstruct.c
******************************************************************/
#include "defines.h"
#include "gain_dequant.h"
#include "get_cd_vec.h"
/*----------------------------------------------------------------*
* Construct decoded vector from codebook and gains.
*---------------------------------------------------------------*/
void WebRtcIlbcfix_CbConstruct(
int16_t *decvector, /* (o) Decoded vector */
int16_t *index, /* (i) Codebook indices */
int16_t *gain_index, /* (i) Gain quantization indices */
int16_t *mem, /* (i) Buffer for codevector construction */
int16_t lMem, /* (i) Length of buffer */
int16_t veclen /* (i) Length of vector */
){
int j;
int16_t gain[CB_NSTAGES];
/* Stack based */
int16_t cbvec0[SUBL];
int16_t cbvec1[SUBL];
int16_t cbvec2[SUBL];
int32_t a32;
int16_t *gainPtr;
/* gain de-quantization */
gain[0] = WebRtcIlbcfix_GainDequant(gain_index[0], 16384, 0);
gain[1] = WebRtcIlbcfix_GainDequant(gain_index[1], gain[0], 1);
gain[2] = WebRtcIlbcfix_GainDequant(gain_index[2], gain[1], 2);
/* codebook vector construction and construction of total vector */
/* Stack based */
WebRtcIlbcfix_GetCbVec(cbvec0, mem, index[0], lMem, veclen);
WebRtcIlbcfix_GetCbVec(cbvec1, mem, index[1], lMem, veclen);
WebRtcIlbcfix_GetCbVec(cbvec2, mem, index[2], lMem, veclen);
gainPtr = &gain[0];
for (j=0;j<veclen;j++) {
a32 = WEBRTC_SPL_MUL_16_16(*gainPtr++, cbvec0[j]);
a32 += WEBRTC_SPL_MUL_16_16(*gainPtr++, cbvec1[j]);
a32 += WEBRTC_SPL_MUL_16_16(*gainPtr, cbvec2[j]);
gainPtr -= 2;
decvector[j] = (int16_t) WEBRTC_SPL_RSHIFT_W32(a32 + 8192, 14);
}
return;
}

View File

@@ -0,0 +1,38 @@
/*
* 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.
*/
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
WebRtcIlbcfix_CbConstruct.h
******************************************************************/
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_CB_CONSTRUCT_H_
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_CB_CONSTRUCT_H_
#include "defines.h"
/*----------------------------------------------------------------*
* Construct decoded vector from codebook and gains.
*---------------------------------------------------------------*/
void WebRtcIlbcfix_CbConstruct(
int16_t *decvector, /* (o) Decoded vector */
int16_t *index, /* (i) Codebook indices */
int16_t *gain_index, /* (i) Gain quantization indices */
int16_t *mem, /* (i) Buffer for codevector construction */
int16_t lMem, /* (i) Length of buffer */
int16_t veclen /* (i) Length of vector */
);
#endif

View File

@@ -0,0 +1,79 @@
/*
* 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.
*/
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
WebRtcIlbcfix_CbMemEnergy.c
******************************************************************/
#include "defines.h"
#include "constants.h"
#include "cb_mem_energy_calc.h"
/*----------------------------------------------------------------*
* Function WebRtcIlbcfix_CbMemEnergy computes the energy of all
* the vectors in the codebook memory that will be used in the
* following search for the best match.
*----------------------------------------------------------------*/
void WebRtcIlbcfix_CbMemEnergy(
int16_t range,
int16_t *CB, /* (i) The CB memory (1:st section) */
int16_t *filteredCB, /* (i) The filtered CB memory (2:nd section) */
int16_t lMem, /* (i) Length of the CB memory */
int16_t lTarget, /* (i) Length of the target vector */
int16_t *energyW16, /* (o) Energy in the CB vectors */
int16_t *energyShifts, /* (o) Shift value of the energy */
int16_t scale, /* (i) The scaling of all energy values */
int16_t base_size /* (i) Index to where the energy values should be stored */
) {
int16_t *ppi, *ppo, *pp;
int32_t energy, tmp32;
/* Compute the energy and store it in a vector. Also the
* corresponding shift values are stored. The energy values
* are reused in all three stages. */
/* Calculate the energy in the first block of 'lTarget' sampels. */
ppi = CB+lMem-lTarget-1;
ppo = CB+lMem-1;
pp=CB+lMem-lTarget;
energy = WebRtcSpl_DotProductWithScale( pp, pp, lTarget, scale);
/* Normalize the energy and store the number of shifts */
energyShifts[0] = (int16_t)WebRtcSpl_NormW32(energy);
tmp32 = WEBRTC_SPL_LSHIFT_W32(energy, energyShifts[0]);
energyW16[0] = (int16_t)WEBRTC_SPL_RSHIFT_W32(tmp32, 16);
/* Compute the energy of the rest of the cb memory
* by step wise adding and subtracting the next
* sample and the last sample respectively. */
WebRtcIlbcfix_CbMemEnergyCalc(energy, range, ppi, ppo, energyW16, energyShifts, scale, 0);
/* Next, precompute the energy values for the filtered cb section */
energy=0;
pp=filteredCB+lMem-lTarget;
energy = WebRtcSpl_DotProductWithScale( pp, pp, lTarget, scale);
/* Normalize the energy and store the number of shifts */
energyShifts[base_size] = (int16_t)WebRtcSpl_NormW32(energy);
tmp32 = WEBRTC_SPL_LSHIFT_W32(energy, energyShifts[base_size]);
energyW16[base_size] = (int16_t)WEBRTC_SPL_RSHIFT_W32(tmp32, 16);
ppi = filteredCB + lMem - 1 - lTarget;
ppo = filteredCB + lMem - 1;
WebRtcIlbcfix_CbMemEnergyCalc(energy, range, ppi, ppo, energyW16, energyShifts, scale, base_size);
}

View File

@@ -0,0 +1,34 @@
/*
* 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.
*/
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
WebRtcIlbcfix_CbMemEnergy.h
******************************************************************/
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_CB_MEM_ENERGY_H_
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_CB_MEM_ENERGY_H_
void WebRtcIlbcfix_CbMemEnergy(
int16_t range,
int16_t *CB, /* (i) The CB memory (1:st section) */
int16_t *filteredCB, /* (i) The filtered CB memory (2:nd section) */
int16_t lMem, /* (i) Length of the CB memory */
int16_t lTarget, /* (i) Length of the target vector */
int16_t *energyW16, /* (o) Energy in the CB vectors */
int16_t *energyShifts, /* (o) Shift value of the energy */
int16_t scale, /* (i) The scaling of all energy values */
int16_t base_size /* (i) Index to where the energy values should be stored */
);
#endif

View File

@@ -0,0 +1,67 @@
/*
* 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.
*/
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
WebRtcIlbcfix_CbMemEnergyAugmentation.c
******************************************************************/
#include "defines.h"
#include "constants.h"
void WebRtcIlbcfix_CbMemEnergyAugmentation(
int16_t *interpSamples, /* (i) The interpolated samples */
int16_t *CBmem, /* (i) The CB memory */
int16_t scale, /* (i) The scaling of all energy values */
int16_t base_size, /* (i) Index to where the energy values should be stored */
int16_t *energyW16, /* (o) Energy in the CB vectors */
int16_t *energyShifts /* (o) Shift value of the energy */
){
int32_t energy, tmp32;
int16_t *ppe, *pp, *interpSamplesPtr;
int16_t *CBmemPtr, lagcount;
int16_t *enPtr=&energyW16[base_size-20];
int16_t *enShPtr=&energyShifts[base_size-20];
int32_t nrjRecursive;
CBmemPtr = CBmem+147;
interpSamplesPtr = interpSamples;
/* Compute the energy for the first (low-5) noninterpolated samples */
nrjRecursive = WebRtcSpl_DotProductWithScale( CBmemPtr-19, CBmemPtr-19, 15, scale);
ppe = CBmemPtr - 20;
for (lagcount=20; lagcount<=39; lagcount++) {
/* Update the energy recursively to save complexity */
nrjRecursive = nrjRecursive +
WEBRTC_SPL_MUL_16_16_RSFT(*ppe, *ppe, scale);
ppe--;
energy = nrjRecursive;
/* interpolation */
energy += WebRtcSpl_DotProductWithScale(interpSamplesPtr, interpSamplesPtr, 4, scale);
interpSamplesPtr += 4;
/* Compute energy for the remaining samples */
pp = CBmemPtr - lagcount;
energy += WebRtcSpl_DotProductWithScale(pp, pp, SUBL-lagcount, scale);
/* Normalize the energy and store the number of shifts */
(*enShPtr) = (int16_t)WebRtcSpl_NormW32(energy);
tmp32 = WEBRTC_SPL_LSHIFT_W32(energy, (*enShPtr));
(*enPtr) = (int16_t)WEBRTC_SPL_RSHIFT_W32(tmp32, 16);
enShPtr++;
enPtr++;
}
}

View File

@@ -0,0 +1,31 @@
/*
* 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.
*/
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
WebRtcIlbcfix_CbMemEnergyAugmentation.h
******************************************************************/
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_CB_MEM_ENERGY_AUGMENTATION_H_
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_CB_MEM_ENERGY_AUGMENTATION_H_
void WebRtcIlbcfix_CbMemEnergyAugmentation(
int16_t *interpSamples, /* (i) The interpolated samples */
int16_t *CBmem, /* (i) The CB memory */
int16_t scale, /* (i) The scaling of all energy values */
int16_t base_size, /* (i) Index to where the energy values should be stored */
int16_t *energyW16, /* (o) Energy in the CB vectors */
int16_t *energyShifts /* (o) Shift value of the energy */
);
#endif

View File

@@ -0,0 +1,65 @@
/*
* 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.
*/
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
WebRtcIlbcfix_CbMemEnergyCalc.c
******************************************************************/
#include "defines.h"
/* Compute the energy of the rest of the cb memory
* by step wise adding and subtracting the next
* sample and the last sample respectively */
void WebRtcIlbcfix_CbMemEnergyCalc(
int32_t energy, /* (i) input start energy */
int16_t range, /* (i) number of iterations */
int16_t *ppi, /* (i) input pointer 1 */
int16_t *ppo, /* (i) input pointer 2 */
int16_t *energyW16, /* (o) Energy in the CB vectors */
int16_t *energyShifts, /* (o) Shift value of the energy */
int16_t scale, /* (i) The scaling of all energy values */
int16_t base_size /* (i) Index to where the energy values should be stored */
)
{
int16_t j,shft;
int32_t tmp;
int16_t *eSh_ptr;
int16_t *eW16_ptr;
eSh_ptr = &energyShifts[1+base_size];
eW16_ptr = &energyW16[1+base_size];
for(j=0;j<range-1;j++) {
/* Calculate next energy by a +/-
operation on the edge samples */
tmp = WEBRTC_SPL_MUL_16_16(*ppi, *ppi);
tmp -= WEBRTC_SPL_MUL_16_16(*ppo, *ppo);
energy += WEBRTC_SPL_RSHIFT_W32(tmp, scale);
energy = WEBRTC_SPL_MAX(energy, 0);
ppi--;
ppo--;
/* Normalize the energy into a int16_t and store
the number of shifts */
shft = (int16_t)WebRtcSpl_NormW32(energy);
*eSh_ptr++ = shft;
tmp = WEBRTC_SPL_LSHIFT_W32(energy, shft);
*eW16_ptr++ = (int16_t)WEBRTC_SPL_RSHIFT_W32(tmp, 16);
}
}

View File

@@ -0,0 +1,33 @@
/*
* 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.
*/
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
WebRtcIlbcfix_CbMemEnergyCalc.h
******************************************************************/
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_CB_MEM_ENERGY_CALC_H_
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_CB_MEM_ENERGY_CALC_H_
void WebRtcIlbcfix_CbMemEnergyCalc(
int32_t energy, /* (i) input start energy */
int16_t range, /* (i) number of iterations */
int16_t *ppi, /* (i) input pointer 1 */
int16_t *ppo, /* (i) input pointer 2 */
int16_t *energyW16, /* (o) Energy in the CB vectors */
int16_t *energyShifts, /* (o) Shift value of the energy */
int16_t scale, /* (i) The scaling of all energy values */
int16_t base_size /* (i) Index to where the energy values should be stored */
);
#endif

View File

@@ -0,0 +1,397 @@
/*
* 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.
*/
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
WebRtcIlbcfix_CbSearch.c
******************************************************************/
#include "defines.h"
#include "gain_quant.h"
#include "filtered_cb_vecs.h"
#include "constants.h"
#include "cb_mem_energy.h"
#include "interpolate_samples.h"
#include "cb_mem_energy_augmentation.h"
#include "cb_search_core.h"
#include "energy_inverse.h"
#include "augmented_cb_corr.h"
#include "cb_update_best_index.h"
#include "create_augmented_vec.h"
/*----------------------------------------------------------------*
* Search routine for codebook encoding and gain quantization.
*----------------------------------------------------------------*/
void WebRtcIlbcfix_CbSearch(
iLBC_Enc_Inst_t *iLBCenc_inst,
/* (i) the encoder state structure */
int16_t *index, /* (o) Codebook indices */
int16_t *gain_index, /* (o) Gain quantization indices */
int16_t *intarget, /* (i) Target vector for encoding */
int16_t *decResidual,/* (i) Decoded residual for codebook construction */
int16_t lMem, /* (i) Length of buffer */
int16_t lTarget, /* (i) Length of vector */
int16_t *weightDenum,/* (i) weighting filter coefficients in Q12 */
int16_t block /* (i) the subblock number */
) {
int16_t i, j, stage, range;
int16_t *pp, scale, tmp;
int16_t bits, temp1, temp2;
int16_t base_size;
int32_t codedEner, targetEner;
int16_t gains[CB_NSTAGES+1];
int16_t *cb_vecPtr;
int16_t indexOffset, sInd, eInd;
int32_t CritMax=0;
int16_t shTotMax=WEBRTC_SPL_WORD16_MIN;
int16_t bestIndex=0;
int16_t bestGain=0;
int16_t indexNew, CritNewSh;
int32_t CritNew;
int32_t *cDotPtr;
int16_t noOfZeros;
int16_t *gainPtr;
int32_t t32, tmpW32;
int16_t *WebRtcIlbcfix_kGainSq5_ptr;
/* Stack based */
int16_t CBbuf[CB_MEML+LPC_FILTERORDER+CB_HALFFILTERLEN];
int32_t cDot[128];
int32_t Crit[128];
int16_t targetVec[SUBL+LPC_FILTERORDER];
int16_t cbvectors[CB_MEML + 1]; /* Adding one extra position for
Coverity warnings. */
int16_t codedVec[SUBL];
int16_t interpSamples[20*4];
int16_t interpSamplesFilt[20*4];
int16_t energyW16[CB_EXPAND*128];
int16_t energyShifts[CB_EXPAND*128];
int16_t *inverseEnergy=energyW16; /* Reuse memory */
int16_t *inverseEnergyShifts=energyShifts; /* Reuse memory */
int16_t *buf = &CBbuf[LPC_FILTERORDER];
int16_t *target = &targetVec[LPC_FILTERORDER];
int16_t *aug_vec = (int16_t*)cDot; /* length [SUBL], reuse memory */
/* Determine size of codebook sections */
base_size=lMem-lTarget+1;
if (lTarget==SUBL) {
base_size=lMem-19;
}
/* weighting of the CB memory */
noOfZeros=lMem-WebRtcIlbcfix_kFilterRange[block];
WebRtcSpl_MemSetW16(&buf[-LPC_FILTERORDER], 0, noOfZeros+LPC_FILTERORDER);
WebRtcSpl_FilterARFastQ12(
decResidual+noOfZeros, buf+noOfZeros,
weightDenum, LPC_FILTERORDER+1, WebRtcIlbcfix_kFilterRange[block]);
/* weighting of the target vector */
WEBRTC_SPL_MEMCPY_W16(&target[-LPC_FILTERORDER], buf+noOfZeros+WebRtcIlbcfix_kFilterRange[block]-LPC_FILTERORDER, LPC_FILTERORDER);
WebRtcSpl_FilterARFastQ12(
intarget, target,
weightDenum, LPC_FILTERORDER+1, lTarget);
/* Store target, towards the end codedVec is calculated as
the initial target minus the remaining target */
WEBRTC_SPL_MEMCPY_W16(codedVec, target, lTarget);
/* Find the highest absolute value to calculate proper
vector scale factor (so that it uses 12 bits) */
temp1 = WebRtcSpl_MaxAbsValueW16(buf, (int16_t)lMem);
temp2 = WebRtcSpl_MaxAbsValueW16(target, (int16_t)lTarget);
if ((temp1>0)&&(temp2>0)) {
temp1 = WEBRTC_SPL_MAX(temp1, temp2);
scale = WebRtcSpl_GetSizeInBits(WEBRTC_SPL_MUL_16_16(temp1, temp1));
} else {
/* temp1 or temp2 is negative (maximum was -32768) */
scale = 30;
}
/* Scale to so that a mul-add 40 times does not overflow */
scale = scale - 25;
scale = WEBRTC_SPL_MAX(0, scale);
/* Compute energy of the original target */
targetEner = WebRtcSpl_DotProductWithScale(target, target, lTarget, scale);
/* Prepare search over one more codebook section. This section
is created by filtering the original buffer with a filter. */
WebRtcIlbcfix_FilteredCbVecs(cbvectors, buf, lMem, WebRtcIlbcfix_kFilterRange[block]);
range = WebRtcIlbcfix_kSearchRange[block][0];
if(lTarget == SUBL) {
/* Create the interpolated samples and store them for use in all stages */
/* First section, non-filtered half of the cb */
WebRtcIlbcfix_InterpolateSamples(interpSamples, buf, lMem);
/* Second section, filtered half of the cb */
WebRtcIlbcfix_InterpolateSamples(interpSamplesFilt, cbvectors, lMem);
/* Compute the CB vectors' energies for the first cb section (non-filtered) */
WebRtcIlbcfix_CbMemEnergyAugmentation(interpSamples, buf,
scale, 20, energyW16, energyShifts);
/* Compute the CB vectors' energies for the second cb section (filtered cb) */
WebRtcIlbcfix_CbMemEnergyAugmentation(interpSamplesFilt, cbvectors,
scale, (int16_t)(base_size+20), energyW16, energyShifts);
/* Compute the CB vectors' energies and store them in the vector
* energyW16. Also the corresponding shift values are stored. The
* energy values are used in all three stages. */
WebRtcIlbcfix_CbMemEnergy(range, buf, cbvectors, lMem,
lTarget, energyW16+20, energyShifts+20, scale, base_size);
} else {
/* Compute the CB vectors' energies and store them in the vector
* energyW16. Also the corresponding shift values are stored. The
* energy values are used in all three stages. */
WebRtcIlbcfix_CbMemEnergy(range, buf, cbvectors, lMem,
lTarget, energyW16, energyShifts, scale, base_size);
/* Set the energy positions 58-63 and 122-127 to zero
(otherwise they are uninitialized) */
WebRtcSpl_MemSetW16(energyW16+range, 0, (base_size-range));
WebRtcSpl_MemSetW16(energyW16+range+base_size, 0, (base_size-range));
}
/* Calculate Inverse Energy (energyW16 is already normalized
and will contain the inverse energy in Q29 after this call */
WebRtcIlbcfix_EnergyInverse(energyW16, base_size*CB_EXPAND);
/* The gain value computed in the previous stage is used
* as an upper limit to what the next stage gain value
* is allowed to be. In stage 0, 16384 (1.0 in Q14) is used as
* the upper limit. */
gains[0] = 16384;
for (stage=0; stage<CB_NSTAGES; stage++) {
/* Set up memories */
range = WebRtcIlbcfix_kSearchRange[block][stage];
/* initialize search measures */
CritMax=0;
shTotMax=-100;
bestIndex=0;
bestGain=0;
/* loop over lags 40+ in the first codebook section, full search */
cb_vecPtr = buf+lMem-lTarget;
/* Calculate all the cross correlations (augmented part of CB) */
if (lTarget==SUBL) {
WebRtcIlbcfix_AugmentedCbCorr(target, buf+lMem,
interpSamples, cDot,
20, 39, scale);
cDotPtr=&cDot[20];
} else {
cDotPtr=cDot;
}
/* Calculate all the cross correlations (main part of CB) */
WebRtcSpl_CrossCorrelation(cDotPtr, target, cb_vecPtr, lTarget, range, scale, -1);
/* Adjust the search range for the augmented vectors */
if (lTarget==SUBL) {
range=WebRtcIlbcfix_kSearchRange[block][stage]+20;
} else {
range=WebRtcIlbcfix_kSearchRange[block][stage];
}
indexOffset=0;
/* Search for best index in this part of the vector */
WebRtcIlbcfix_CbSearchCore(
cDot, range, stage, inverseEnergy,
inverseEnergyShifts, Crit,
&indexNew, &CritNew, &CritNewSh);
/* Update the global best index and the corresponding gain */
WebRtcIlbcfix_CbUpdateBestIndex(
CritNew, CritNewSh, (int16_t)(indexNew+indexOffset), cDot[indexNew+indexOffset],
inverseEnergy[indexNew+indexOffset], inverseEnergyShifts[indexNew+indexOffset],
&CritMax, &shTotMax, &bestIndex, &bestGain);
sInd=bestIndex-(int16_t)(CB_RESRANGE>>1);
eInd=sInd+CB_RESRANGE;
if (sInd<0) {
eInd-=sInd;
sInd=0;
}
if (eInd>=range) {
eInd=range-1;
sInd=eInd-CB_RESRANGE;
}
range = WebRtcIlbcfix_kSearchRange[block][stage];
if (lTarget==SUBL) {
i=sInd;
if (sInd<20) {
WebRtcIlbcfix_AugmentedCbCorr(target, cbvectors+lMem,
interpSamplesFilt, cDot,
(int16_t)(sInd+20), (int16_t)(WEBRTC_SPL_MIN(39, (eInd+20))), scale);
i=20;
}
cDotPtr=&cDot[WEBRTC_SPL_MAX(0,(20-sInd))];
cb_vecPtr = cbvectors+lMem-20-i;
/* Calculate the cross correlations (main part of the filtered CB) */
WebRtcSpl_CrossCorrelation(cDotPtr, target, cb_vecPtr, lTarget, (int16_t)(eInd-i+1), scale, -1);
} else {
cDotPtr = cDot;
cb_vecPtr = cbvectors+lMem-lTarget-sInd;
/* Calculate the cross correlations (main part of the filtered CB) */
WebRtcSpl_CrossCorrelation(cDotPtr, target, cb_vecPtr, lTarget, (int16_t)(eInd-sInd+1), scale, -1);
}
/* Adjust the search range for the augmented vectors */
indexOffset=base_size+sInd;
/* Search for best index in this part of the vector */
WebRtcIlbcfix_CbSearchCore(
cDot, (int16_t)(eInd-sInd+1), stage, inverseEnergy+indexOffset,
inverseEnergyShifts+indexOffset, Crit,
&indexNew, &CritNew, &CritNewSh);
/* Update the global best index and the corresponding gain */
WebRtcIlbcfix_CbUpdateBestIndex(
CritNew, CritNewSh, (int16_t)(indexNew+indexOffset), cDot[indexNew],
inverseEnergy[indexNew+indexOffset], inverseEnergyShifts[indexNew+indexOffset],
&CritMax, &shTotMax, &bestIndex, &bestGain);
index[stage] = bestIndex;
bestGain = WebRtcIlbcfix_GainQuant(bestGain,
(int16_t)WEBRTC_SPL_ABS_W16(gains[stage]), stage, &gain_index[stage]);
/* Extract the best (according to measure) codebook vector
Also adjust the index, so that the augmented vectors are last.
Above these vectors were first...
*/
if(lTarget==(STATE_LEN-iLBCenc_inst->state_short_len)) {
if(index[stage]<base_size) {
pp=buf+lMem-lTarget-index[stage];
} else {
pp=cbvectors+lMem-lTarget-
index[stage]+base_size;
}
} else {
if (index[stage]<base_size) {
if (index[stage]>=20) {
/* Adjust index and extract vector */
index[stage]-=20;
pp=buf+lMem-lTarget-index[stage];
} else {
/* Adjust index and extract vector */
index[stage]+=(base_size-20);
WebRtcIlbcfix_CreateAugmentedVec((int16_t)(index[stage]-base_size+40),
buf+lMem, aug_vec);
pp = aug_vec;
}
} else {
if ((index[stage] - base_size) >= 20) {
/* Adjust index and extract vector */
index[stage]-=20;
pp=cbvectors+lMem-lTarget-
index[stage]+base_size;
} else {
/* Adjust index and extract vector */
index[stage]+=(base_size-20);
WebRtcIlbcfix_CreateAugmentedVec((int16_t)(index[stage]-2*base_size+40),
cbvectors+lMem, aug_vec);
pp = aug_vec;
}
}
}
/* Subtract the best codebook vector, according
to measure, from the target vector */
WebRtcSpl_AddAffineVectorToVector(target, pp, (int16_t)(-bestGain), (int32_t)8192, (int16_t)14, (int)lTarget);
/* record quantized gain */
gains[stage+1] = bestGain;
} /* end of Main Loop. for (stage=0;... */
/* Calculte the coded vector (original target - what's left) */
for (i=0;i<lTarget;i++) {
codedVec[i]-=target[i];
}
/* Gain adjustment for energy matching */
codedEner = WebRtcSpl_DotProductWithScale(codedVec, codedVec, lTarget, scale);
j=gain_index[0];
temp1 = (int16_t)WebRtcSpl_NormW32(codedEner);
temp2 = (int16_t)WebRtcSpl_NormW32(targetEner);
if(temp1 < temp2) {
bits = 16 - temp1;
} else {
bits = 16 - temp2;
}
tmp = (int16_t) WEBRTC_SPL_MUL_16_16_RSFT(gains[1],gains[1], 14);
targetEner = WEBRTC_SPL_MUL_16_16(
WEBRTC_SPL_SHIFT_W32(targetEner, -bits), tmp);
tmpW32 = ((int32_t)(gains[1]-1))<<1;
/* Pointer to the table that contains
gain_sq5TblFIX * gain_sq5TblFIX in Q14 */
gainPtr=(int16_t*)WebRtcIlbcfix_kGainSq5Sq+gain_index[0];
temp1 = (int16_t)WEBRTC_SPL_SHIFT_W32(codedEner, -bits);
WebRtcIlbcfix_kGainSq5_ptr = (int16_t*)&WebRtcIlbcfix_kGainSq5[j];
/* targetEner and codedEner are in Q(-2*scale) */
for (i=gain_index[0];i<32;i++) {
/* Change the index if
(codedEnergy*gainTbl[i]*gainTbl[i])<(targetEn*gain[0]*gain[0]) AND
gainTbl[i] < 2*gain[0]
*/
t32 = WEBRTC_SPL_MUL_16_16(temp1, (*gainPtr));
t32 = t32 - targetEner;
if (t32 < 0) {
if ((*WebRtcIlbcfix_kGainSq5_ptr) < tmpW32) {
j=i;
WebRtcIlbcfix_kGainSq5_ptr = (int16_t*)&WebRtcIlbcfix_kGainSq5[i];
}
}
gainPtr++;
}
gain_index[0]=j;
return;
}

View File

@@ -0,0 +1,35 @@
/*
* 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.
*/
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
WebRtcIlbcfix_CbSearch.h
******************************************************************/
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_CB_SEARCH_H_
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_CB_SEARCH_H_
void WebRtcIlbcfix_CbSearch(
iLBC_Enc_Inst_t *iLBCenc_inst,
/* (i) the encoder state structure */
int16_t *index, /* (o) Codebook indices */
int16_t *gain_index, /* (o) Gain quantization indices */
int16_t *intarget, /* (i) Target vector for encoding */
int16_t *decResidual,/* (i) Decoded residual for codebook construction */
int16_t lMem, /* (i) Length of buffer */
int16_t lTarget, /* (i) Length of vector */
int16_t *weightDenum,/* (i) weighting filter coefficients in Q12 */
int16_t block /* (i) the subblock number */
);
#endif

View File

@@ -0,0 +1,113 @@
/*
* 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.
*/
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
WebRtcIlbcfix_CbSearchCore.c
******************************************************************/
#include "defines.h"
#include "constants.h"
void WebRtcIlbcfix_CbSearchCore(
int32_t *cDot, /* (i) Cross Correlation */
int16_t range, /* (i) Search range */
int16_t stage, /* (i) Stage of this search */
int16_t *inverseEnergy, /* (i) Inversed energy */
int16_t *inverseEnergyShift, /* (i) Shifts of inversed energy
with the offset 2*16-29 */
int32_t *Crit, /* (o) The criteria */
int16_t *bestIndex, /* (o) Index that corresponds to
maximum criteria (in this
vector) */
int32_t *bestCrit, /* (o) Value of critera for the
chosen index */
int16_t *bestCritSh) /* (o) The domain of the chosen
criteria */
{
int32_t maxW32, tmp32;
int16_t max, sh, tmp16;
int i;
int32_t *cDotPtr;
int16_t cDotSqW16;
int16_t *inverseEnergyPtr;
int32_t *critPtr;
int16_t *inverseEnergyShiftPtr;
/* Don't allow negative values for stage 0 */
if (stage==0) {
cDotPtr=cDot;
for (i=0;i<range;i++) {
*cDotPtr=WEBRTC_SPL_MAX(0, (*cDotPtr));
cDotPtr++;
}
}
/* Normalize cDot to int16_t, calculate the square of cDot and store the upper int16_t */
maxW32 = WebRtcSpl_MaxAbsValueW32(cDot, range);
sh = (int16_t)WebRtcSpl_NormW32(maxW32);
cDotPtr = cDot;
inverseEnergyPtr = inverseEnergy;
critPtr = Crit;
inverseEnergyShiftPtr=inverseEnergyShift;
max=WEBRTC_SPL_WORD16_MIN;
for (i=0;i<range;i++) {
/* Calculate cDot*cDot and put the result in a int16_t */
tmp32 = WEBRTC_SPL_LSHIFT_W32(*cDotPtr,sh);
tmp16 = (int16_t)WEBRTC_SPL_RSHIFT_W32(tmp32,16);
cDotSqW16 = (int16_t)(((int32_t)(tmp16)*(tmp16))>>16);
/* Calculate the criteria (cDot*cDot/energy) */
*critPtr=WEBRTC_SPL_MUL_16_16(cDotSqW16, (*inverseEnergyPtr));
/* Extract the maximum shift value under the constraint
that the criteria is not zero */
if ((*critPtr)!=0) {
max = WEBRTC_SPL_MAX((*inverseEnergyShiftPtr), max);
}
inverseEnergyPtr++;
inverseEnergyShiftPtr++;
critPtr++;
cDotPtr++;
}
/* If no max shifts still at initialization value, set shift to zero */
if (max==WEBRTC_SPL_WORD16_MIN) {
max = 0;
}
/* Modify the criterias, so that all of them use the same Q domain */
critPtr=Crit;
inverseEnergyShiftPtr=inverseEnergyShift;
for (i=0;i<range;i++) {
/* Guarantee that the shift value is less than 16
in order to simplify for DSP's (and guard against >31) */
tmp16 = WEBRTC_SPL_MIN(16, max-(*inverseEnergyShiftPtr));
(*critPtr)=WEBRTC_SPL_SHIFT_W32((*critPtr),-tmp16);
critPtr++;
inverseEnergyShiftPtr++;
}
/* Find the index of the best value */
*bestIndex = WebRtcSpl_MaxIndexW32(Crit, range);
*bestCrit = Crit[*bestIndex];
/* Calculate total shifts of this criteria */
*bestCritSh = 32 - 2*sh + max;
return;
}

View File

@@ -0,0 +1,40 @@
/*
* 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.
*/
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
WebRtcIlbcfix_CbSearchCore.h
******************************************************************/
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_CB_SEARCH_CORE_H_
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_CB_SEARCH_CORE_H_
#include "defines.h"
void WebRtcIlbcfix_CbSearchCore(
int32_t *cDot, /* (i) Cross Correlation */
int16_t range, /* (i) Search range */
int16_t stage, /* (i) Stage of this search */
int16_t *inverseEnergy, /* (i) Inversed energy */
int16_t *inverseEnergyShift, /* (i) Shifts of inversed energy
with the offset 2*16-29 */
int32_t *Crit, /* (o) The criteria */
int16_t *bestIndex, /* (o) Index that corresponds to
maximum criteria (in this
vector) */
int32_t *bestCrit, /* (o) Value of critera for the
chosen index */
int16_t *bestCritSh); /* (o) The domain of the chosen
criteria */
#endif

View File

@@ -0,0 +1,89 @@
/*
* 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.
*/
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
WebRtcIlbcfix_CbUpdateBestIndex.c
******************************************************************/
#include "defines.h"
#include "cb_update_best_index.h"
#include "constants.h"
void WebRtcIlbcfix_CbUpdateBestIndex(
int32_t CritNew, /* (i) New Potentially best Criteria */
int16_t CritNewSh, /* (i) Shift value of above Criteria */
int16_t IndexNew, /* (i) Index of new Criteria */
int32_t cDotNew, /* (i) Cross dot of new index */
int16_t invEnergyNew, /* (i) Inversed energy new index */
int16_t energyShiftNew, /* (i) Energy shifts of new index */
int32_t *CritMax, /* (i/o) Maximum Criteria (so far) */
int16_t *shTotMax, /* (i/o) Shifts of maximum criteria */
int16_t *bestIndex, /* (i/o) Index that corresponds to
maximum criteria */
int16_t *bestGain) /* (i/o) Gain in Q14 that corresponds
to maximum criteria */
{
int16_t shOld, shNew, tmp16;
int16_t scaleTmp;
int32_t gainW32;
/* Normalize the new and old Criteria to the same domain */
if (CritNewSh>(*shTotMax)) {
shOld=WEBRTC_SPL_MIN(31,CritNewSh-(*shTotMax));
shNew=0;
} else {
shOld=0;
shNew=WEBRTC_SPL_MIN(31,(*shTotMax)-CritNewSh);
}
/* Compare the two criterias. If the new one is better,
calculate the gain and store this index as the new best one
*/
if (WEBRTC_SPL_RSHIFT_W32(CritNew, shNew)>
WEBRTC_SPL_RSHIFT_W32((*CritMax),shOld)) {
tmp16 = (int16_t)WebRtcSpl_NormW32(cDotNew);
tmp16 = 16 - tmp16;
/* Calculate the gain in Q14
Compensate for inverseEnergyshift in Q29 and that the energy
value was stored in a int16_t (shifted down 16 steps)
=> 29-14+16 = 31 */
scaleTmp = -energyShiftNew-tmp16+31;
scaleTmp = WEBRTC_SPL_MIN(31, scaleTmp);
gainW32 = WEBRTC_SPL_MUL_16_16_RSFT(
((int16_t)WEBRTC_SPL_SHIFT_W32(cDotNew, -tmp16)), invEnergyNew, scaleTmp);
/* Check if criteria satisfies Gain criteria (max 1.3)
if it is larger set the gain to 1.3
(slightly different from FLP version)
*/
if (gainW32>21299) {
*bestGain=21299;
} else if (gainW32<-21299) {
*bestGain=-21299;
} else {
*bestGain=(int16_t)gainW32;
}
*CritMax=CritNew;
*shTotMax=CritNewSh;
*bestIndex = IndexNew;
}
return;
}

View File

@@ -0,0 +1,38 @@
/*
* 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.
*/
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
WebRtcIlbcfix_CbUpdateBestIndex.h
******************************************************************/
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_CB_UPDATE_BEST_INDEX_H_
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_CB_UPDATE_BEST_INDEX_H_
#include "defines.h"
void WebRtcIlbcfix_CbUpdateBestIndex(
int32_t CritNew, /* (i) New Potentially best Criteria */
int16_t CritNewSh, /* (i) Shift value of above Criteria */
int16_t IndexNew, /* (i) Index of new Criteria */
int32_t cDotNew, /* (i) Cross dot of new index */
int16_t invEnergyNew, /* (i) Inversed energy new index */
int16_t energyShiftNew, /* (i) Energy shifts of new index */
int32_t *CritMax, /* (i/o) Maximum Criteria (so far) */
int16_t *shTotMax, /* (i/o) Shifts of maximum criteria */
int16_t *bestIndex, /* (i/o) Index that corresponds to
maximum criteria */
int16_t *bestGain); /* (i/o) Gain in Q14 that corresponds
to maximum criteria */
#endif

View File

@@ -0,0 +1,82 @@
/*
* 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.
*/
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
WebRtcIlbcfix_Chebyshev.c
******************************************************************/
#include "defines.h"
#include "constants.h"
/*------------------------------------------------------------------*
* Calculate the Chevyshev polynomial series
* F(w) = 2*exp(-j5w)*C(x)
* C(x) = (T_0(x) + f(1)T_1(x) + ... + f(4)T_1(x) + f(5)/2)
* T_i(x) is the i:th order Chebyshev polynomial
*------------------------------------------------------------------*/
int16_t WebRtcIlbcfix_Chebyshev(
/* (o) Result of C(x) */
int16_t x, /* (i) Value to the Chevyshev polynomial */
int16_t *f /* (i) The coefficients in the polynomial */
) {
int16_t b1_high, b1_low; /* Use the high, low format to increase the accuracy */
int32_t b2;
int32_t tmp1W32;
int32_t tmp2W32;
int i;
b2 = (int32_t)0x1000000; /* b2 = 1.0 (Q23) */
/* Calculate b1 = 2*x + f[1] */
tmp1W32 = WEBRTC_SPL_LSHIFT_W32((int32_t)x, 10);
tmp1W32 += WEBRTC_SPL_LSHIFT_W32((int32_t)f[1], 14);
for (i = 2; i < 5; i++) {
tmp2W32 = tmp1W32;
/* Split b1 (in tmp1W32) into a high and low part */
b1_high = (int16_t)WEBRTC_SPL_RSHIFT_W32(tmp1W32, 16);
b1_low = (int16_t)WEBRTC_SPL_RSHIFT_W32(tmp1W32-WEBRTC_SPL_LSHIFT_W32(((int32_t)b1_high),16), 1);
/* Calculate 2*x*b1-b2+f[i] */
tmp1W32 = WEBRTC_SPL_LSHIFT_W32( (WEBRTC_SPL_MUL_16_16(b1_high, x) +
WEBRTC_SPL_MUL_16_16_RSFT(b1_low, x, 15)), 2);
tmp1W32 -= b2;
tmp1W32 += WEBRTC_SPL_LSHIFT_W32((int32_t)f[i], 14);
/* Update b2 for next round */
b2 = tmp2W32;
}
/* Split b1 (in tmp1W32) into a high and low part */
b1_high = (int16_t)WEBRTC_SPL_RSHIFT_W32(tmp1W32, 16);
b1_low = (int16_t)WEBRTC_SPL_RSHIFT_W32(tmp1W32-WEBRTC_SPL_LSHIFT_W32(((int32_t)b1_high),16), 1);
/* tmp1W32 = x*b1 - b2 + f[i]/2 */
tmp1W32 = WEBRTC_SPL_LSHIFT_W32(WEBRTC_SPL_MUL_16_16(b1_high, x), 1) +
WEBRTC_SPL_LSHIFT_W32(WEBRTC_SPL_MUL_16_16_RSFT(b1_low, x, 15), 1);
tmp1W32 -= b2;
tmp1W32 += WEBRTC_SPL_LSHIFT_W32((int32_t)f[i], 13);
/* Handle overflows and set to maximum or minimum int16_t instead */
if (tmp1W32>((int32_t)33553408)) {
return(WEBRTC_SPL_WORD16_MAX);
} else if (tmp1W32<((int32_t)-33554432)) {
return(WEBRTC_SPL_WORD16_MIN);
} else {
return((int16_t)WEBRTC_SPL_RSHIFT_W32(tmp1W32, 10));
}
}

View File

@@ -0,0 +1,37 @@
/*
* 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.
*/
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
WebRtcIlbcfix_Chebyshev.h
******************************************************************/
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_CHEBYSHEV_H_
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_CHEBYSHEV_H_
#include "defines.h"
/*------------------------------------------------------------------*
* Calculate the Chevyshev polynomial series
* F(w) = 2*exp(-j5w)*C(x)
* C(x) = (T_0(x) + f(1)T_1(x) + ... + f(4)T_1(x) + f(5)/2)
* T_i(x) is the i:th order Chebyshev polynomial
*------------------------------------------------------------------*/
int16_t WebRtcIlbcfix_Chebyshev(
/* (o) Result of C(x) */
int16_t x, /* (i) Value to the Chevyshev polynomial */
int16_t *f /* (i) The coefficients in the polynomial */
);
#endif

View File

@@ -0,0 +1,49 @@
/*
* 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.
*/
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
WebRtcIlbcfix_CompCorr.c
******************************************************************/
#include "defines.h"
/*----------------------------------------------------------------*
* Compute cross correlation and pitch gain for pitch prediction
* of last subframe at given lag.
*---------------------------------------------------------------*/
void WebRtcIlbcfix_CompCorr(
int32_t *corr, /* (o) cross correlation */
int32_t *ener, /* (o) energy */
int16_t *buffer, /* (i) signal buffer */
int16_t lag, /* (i) pitch lag */
int16_t bLen, /* (i) length of buffer */
int16_t sRange, /* (i) correlation search length */
int16_t scale /* (i) number of rightshifts to use */
){
int16_t *w16ptr;
w16ptr=&buffer[bLen-sRange-lag];
/* Calculate correlation and energy */
(*corr)=WebRtcSpl_DotProductWithScale(&buffer[bLen-sRange], w16ptr, sRange, scale);
(*ener)=WebRtcSpl_DotProductWithScale(w16ptr, w16ptr, sRange, scale);
/* For zero energy set the energy to 0 in order to avoid potential
problems for coming divisions */
if (*ener == 0) {
*corr = 0;
*ener = 1;
}
}

View File

@@ -0,0 +1,39 @@
/*
* 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.
*/
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
WebRtcIlbcfix_CompCorr.h
******************************************************************/
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_COMP_CORR_H_
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_COMP_CORR_H_
#include "defines.h"
/*----------------------------------------------------------------*
* Compute cross correlation and pitch gain for pitch prediction
* of last subframe at given lag.
*---------------------------------------------------------------*/
void WebRtcIlbcfix_CompCorr(
int32_t *corr, /* (o) cross correlation */
int32_t *ener, /* (o) energy */
int16_t *buffer, /* (i) signal buffer */
int16_t lag, /* (i) pitch lag */
int16_t bLen, /* (i) length of buffer */
int16_t sRange, /* (i) correlation search length */
int16_t scale /* (i) number of rightshifts to use */
);
#endif

View File

@@ -0,0 +1,49 @@
clear;
pack;
%
% Enter the path to YOUR executable and remember to define the perprocessor
% variable PRINT_MIPS te get the instructions printed to the screen.
%
command = '!iLBCtest.exe 30 speechAndBGnoise.pcm out1.bit out1.pcm tlm10_30ms.dat';
cout=' > st.txt'; %saves to matlab variable 'st'
eval(strcat(command,cout));
if(length(cout)>3)
load st.txt
else
disp('No cout file to load')
end
% initialize vector to zero
index = find(st(1:end,1)==-1);
indexnonzero = find(st(1:end,1)>0);
frames = length(index)-indexnonzero(1)+1;
start = indexnonzero(1) - 1;
functionOrder=max(st(:,2));
new=zeros(frames,functionOrder);
for i = 1:frames,
for j = index(start-1+i)+1:(index(start+i)-1),
new(i,st(j,2)) = new(i,st(j,2)) + st(j,1);
end
end
result=zeros(functionOrder,3);
for i=1:functionOrder
nonzeroelements = find(new(1:end,i)>0);
result(i,1)=i;
% Compute each function's mean complexity
% result(i,2)=(sum(new(nonzeroelements,i))/(length(nonzeroelements)*0.03))/1000000;
% Compute each function's maximum complexity in encoding
% and decoding respectively and then add it together:
% result(i,3)=(max(new(1:end,i))/0.03)/1000000;
result(i,3)=(max(new(1:size(new,1)/2,i))/0.03)/1000000 + (max(new(size(new,1)/2+1:end,i))/0.03)/1000000;
end
result
% Compute maximum complexity for a single frame (enc/dec separately and together)
maxEncComplexityInAFrame = (max(sum(new(1:size(new,1)/2,:),2))/0.03)/1000000
maxDecComplexityInAFrame = (max(sum(new(size(new,1)/2+1:end,:),2))/0.03)/1000000
totalComplexity = maxEncComplexityInAFrame + maxDecComplexityInAFrame

View File

@@ -0,0 +1,666 @@
/*
* 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.
*/
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
constants.c
******************************************************************/
#include "defines.h"
#include "constants.h"
/* HP Filters {b[0] b[1] b[2] -a[1] -a[2]} */
const int16_t WebRtcIlbcfix_kHpInCoefs[5] = {3798, -7596, 3798, 7807, -3733};
const int16_t WebRtcIlbcfix_kHpOutCoefs[5] = {3849, -7699, 3849, 7918, -3833};
/* Window in Q11 to window the energies of the 5 choises (3 for 20ms) in the choise for
the 80 sample start state
*/
const int16_t WebRtcIlbcfix_kStartSequenceEnrgWin[NSUB_MAX-1]= {
1638, 1843, 2048, 1843, 1638
};
/* LP Filter coeffs used for downsampling */
const int16_t WebRtcIlbcfix_kLpFiltCoefs[FILTERORDER_DS_PLUS1]= {
-273, 512, 1297, 1696, 1297, 512, -273
};
/* Constants used in the LPC calculations */
/* Hanning LPC window (in Q15) */
const int16_t WebRtcIlbcfix_kLpcWin[BLOCKL_MAX] = {
6, 22, 50, 89, 139, 200, 272, 355, 449, 554, 669, 795,
932, 1079, 1237, 1405, 1583, 1771, 1969, 2177, 2395, 2622, 2858, 3104,
3359, 3622, 3894, 4175, 4464, 4761, 5066, 5379, 5699, 6026, 6361, 6702,
7050, 7404, 7764, 8130, 8502, 8879, 9262, 9649, 10040, 10436, 10836, 11240,
11647, 12058, 12471, 12887, 13306, 13726, 14148, 14572, 14997, 15423, 15850, 16277,
16704, 17131, 17558, 17983, 18408, 18831, 19252, 19672, 20089, 20504, 20916, 21325,
21730, 22132, 22530, 22924, 23314, 23698, 24078, 24452, 24821, 25185, 25542, 25893,
26238, 26575, 26906, 27230, 27547, 27855, 28156, 28450, 28734, 29011, 29279, 29538,
29788, 30029, 30261, 30483, 30696, 30899, 31092, 31275, 31448, 31611, 31764, 31906,
32037, 32158, 32268, 32367, 32456, 32533, 32600, 32655, 32700, 32733, 32755, 32767,
32767, 32755, 32733, 32700, 32655, 32600, 32533, 32456, 32367, 32268, 32158, 32037,
31906, 31764, 31611, 31448, 31275, 31092, 30899, 30696, 30483, 30261, 30029, 29788,
29538, 29279, 29011, 28734, 28450, 28156, 27855, 27547, 27230, 26906, 26575, 26238,
25893, 25542, 25185, 24821, 24452, 24078, 23698, 23314, 22924, 22530, 22132, 21730,
21325, 20916, 20504, 20089, 19672, 19252, 18831, 18408, 17983, 17558, 17131, 16704,
16277, 15850, 15423, 14997, 14572, 14148, 13726, 13306, 12887, 12471, 12058, 11647,
11240, 10836, 10436, 10040, 9649, 9262, 8879, 8502, 8130, 7764, 7404, 7050,
6702, 6361, 6026, 5699, 5379, 5066, 4761, 4464, 4175, 3894, 3622, 3359,
3104, 2858, 2622, 2395, 2177, 1969, 1771, 1583, 1405, 1237, 1079, 932,
795, 669, 554, 449, 355, 272, 200, 139, 89, 50, 22, 6
};
/* Asymmetric LPC window (in Q15)*/
const int16_t WebRtcIlbcfix_kLpcAsymWin[BLOCKL_MAX] = {
2, 7, 15, 27, 42, 60, 81, 106, 135, 166, 201, 239,
280, 325, 373, 424, 478, 536, 597, 661, 728, 798, 872, 949,
1028, 1111, 1197, 1287, 1379, 1474, 1572, 1674, 1778, 1885, 1995, 2108,
2224, 2343, 2465, 2589, 2717, 2847, 2980, 3115, 3254, 3395, 3538, 3684,
3833, 3984, 4138, 4295, 4453, 4615, 4778, 4944, 5112, 5283, 5456, 5631,
5808, 5987, 6169, 6352, 6538, 6725, 6915, 7106, 7300, 7495, 7692, 7891,
8091, 8293, 8497, 8702, 8909, 9118, 9328, 9539, 9752, 9966, 10182, 10398,
10616, 10835, 11055, 11277, 11499, 11722, 11947, 12172, 12398, 12625, 12852, 13080,
13309, 13539, 13769, 14000, 14231, 14463, 14695, 14927, 15160, 15393, 15626, 15859,
16092, 16326, 16559, 16792, 17026, 17259, 17492, 17725, 17957, 18189, 18421, 18653,
18884, 19114, 19344, 19573, 19802, 20030, 20257, 20483, 20709, 20934, 21157, 21380,
21602, 21823, 22042, 22261, 22478, 22694, 22909, 23123, 23335, 23545, 23755, 23962,
24168, 24373, 24576, 24777, 24977, 25175, 25371, 25565, 25758, 25948, 26137, 26323,
26508, 26690, 26871, 27049, 27225, 27399, 27571, 27740, 27907, 28072, 28234, 28394,
28552, 28707, 28860, 29010, 29157, 29302, 29444, 29584, 29721, 29855, 29987, 30115,
30241, 30364, 30485, 30602, 30717, 30828, 30937, 31043, 31145, 31245, 31342, 31436,
31526, 31614, 31699, 31780, 31858, 31933, 32005, 32074, 32140, 32202, 32261, 32317,
32370, 32420, 32466, 32509, 32549, 32585, 32618, 32648, 32675, 32698, 32718, 32734,
32748, 32758, 32764, 32767, 32767, 32667, 32365, 31863, 31164, 30274, 29197, 27939,
26510, 24917, 23170, 21281, 19261, 17121, 14876, 12540, 10126, 7650, 5126, 2571
};
/* Lag window for LPC (Q31) */
const int32_t WebRtcIlbcfix_kLpcLagWin[LPC_FILTERORDER + 1]={
2147483647, 2144885453, 2137754373, 2125918626, 2109459810,
2088483140, 2063130336, 2033564590, 1999977009, 1962580174,
1921610283};
/* WebRtcIlbcfix_kLpcChirpSyntDenum vector in Q15 corresponding
* floating point vector {1 0.9025 0.9025^2 0.9025^3 ...}
*/
const int16_t WebRtcIlbcfix_kLpcChirpSyntDenum[LPC_FILTERORDER + 1] = {
32767, 29573, 26690, 24087,
21739, 19619, 17707, 15980,
14422, 13016, 11747};
/* WebRtcIlbcfix_kLpcChirpWeightDenum in Q15 corresponding to
* floating point vector {1 0.4222 0.4222^2... }
*/
const int16_t WebRtcIlbcfix_kLpcChirpWeightDenum[LPC_FILTERORDER + 1] = {
32767, 13835, 5841, 2466, 1041, 440,
186, 78, 33, 14, 6};
/* LSF quantization Q13 domain */
const int16_t WebRtcIlbcfix_kLsfCb[64 * 3 + 128 * 3 + 128 * 4] = {
1273, 2238, 3696,
3199, 5309, 8209,
3606, 5671, 7829,
2815, 5262, 8778,
2608, 4027, 5493,
1582, 3076, 5945,
2983, 4181, 5396,
2437, 4322, 6902,
1861, 2998, 4613,
2007, 3250, 5214,
1388, 2459, 4262,
2563, 3805, 5269,
2036, 3522, 5129,
1935, 4025, 6694,
2744, 5121, 7338,
2810, 4248, 5723,
3054, 5405, 7745,
1449, 2593, 4763,
3411, 5128, 6596,
2484, 4659, 7496,
1668, 2879, 4818,
1812, 3072, 5036,
1638, 2649, 3900,
2464, 3550, 4644,
1853, 2900, 4158,
2458, 4163, 5830,
2556, 4036, 6254,
2703, 4432, 6519,
3062, 4953, 7609,
1725, 3703, 6187,
2221, 3877, 5427,
2339, 3579, 5197,
2021, 4633, 7037,
2216, 3328, 4535,
2961, 4739, 6667,
2807, 3955, 5099,
2788, 4501, 6088,
1642, 2755, 4431,
3341, 5282, 7333,
2414, 3726, 5727,
1582, 2822, 5269,
2259, 3447, 4905,
3117, 4986, 7054,
1825, 3491, 5542,
3338, 5736, 8627,
1789, 3090, 5488,
2566, 3720, 4923,
2846, 4682, 7161,
1950, 3321, 5976,
1834, 3383, 6734,
3238, 4769, 6094,
2031, 3978, 5903,
1877, 4068, 7436,
2131, 4644, 8296,
2764, 5010, 8013,
2194, 3667, 6302,
2053, 3127, 4342,
3523, 6595, 10010,
3134, 4457, 5748,
3142, 5819, 9414,
2223, 4334, 6353,
2022, 3224, 4822,
2186, 3458, 5544,
2552, 4757, 6870,
10905, 12917, 14578,
9503, 11485, 14485,
9518, 12494, 14052,
6222, 7487, 9174,
7759, 9186, 10506,
8315, 12755, 14786,
9609, 11486, 13866,
8909, 12077, 13643,
7369, 9054, 11520,
9408, 12163, 14715,
6436, 9911, 12843,
7109, 9556, 11884,
7557, 10075, 11640,
6482, 9202, 11547,
6463, 7914, 10980,
8611, 10427, 12752,
7101, 9676, 12606,
7428, 11252, 13172,
10197, 12955, 15842,
7487, 10955, 12613,
5575, 7858, 13621,
7268, 11719, 14752,
7476, 11744, 13795,
7049, 8686, 11922,
8234, 11314, 13983,
6560, 11173, 14984,
6405, 9211, 12337,
8222, 12054, 13801,
8039, 10728, 13255,
10066, 12733, 14389,
6016, 7338, 10040,
6896, 8648, 10234,
7538, 9170, 12175,
7327, 12608, 14983,
10516, 12643, 15223,
5538, 7644, 12213,
6728, 12221, 14253,
7563, 9377, 12948,
8661, 11023, 13401,
7280, 8806, 11085,
7723, 9793, 12333,
12225, 14648, 16709,
8768, 13389, 15245,
10267, 12197, 13812,
5301, 7078, 11484,
7100, 10280, 11906,
8716, 12555, 14183,
9567, 12464, 15434,
7832, 12305, 14300,
7608, 10556, 12121,
8913, 11311, 12868,
7414, 9722, 11239,
8666, 11641, 13250,
9079, 10752, 12300,
8024, 11608, 13306,
10453, 13607, 16449,
8135, 9573, 10909,
6375, 7741, 10125,
10025, 12217, 14874,
6985, 11063, 14109,
9296, 13051, 14642,
8613, 10975, 12542,
6583, 10414, 13534,
6191, 9368, 13430,
5742, 6859, 9260,
7723, 9813, 13679,
8137, 11291, 12833,
6562, 8973, 10641,
6062, 8462, 11335,
6928, 8784, 12647,
7501, 8784, 10031,
8372, 10045, 12135,
8191, 9864, 12746,
5917, 7487, 10979,
5516, 6848, 10318,
6819, 9899, 11421,
7882, 12912, 15670,
9558, 11230, 12753,
7752, 9327, 11472,
8479, 9980, 11358,
11418, 14072, 16386,
7968, 10330, 14423,
8423, 10555, 12162,
6337, 10306, 14391,
8850, 10879, 14276,
6750, 11885, 15710,
7037, 8328, 9764,
6914, 9266, 13476,
9746, 13949, 15519,
11032, 14444, 16925,
8032, 10271, 11810,
10962, 13451, 15833,
10021, 11667, 13324,
6273, 8226, 12936,
8543, 10397, 13496,
7936, 10302, 12745,
6769, 8138, 10446,
6081, 7786, 11719,
8637, 11795, 14975,
8790, 10336, 11812,
7040, 8490, 10771,
7338, 10381, 13153,
6598, 7888, 9358,
6518, 8237, 12030,
9055, 10763, 12983,
6490, 10009, 12007,
9589, 12023, 13632,
6867, 9447, 10995,
7930, 9816, 11397,
10241, 13300, 14939,
5830, 8670, 12387,
9870, 11915, 14247,
9318, 11647, 13272,
6721, 10836, 12929,
6543, 8233, 9944,
8034, 10854, 12394,
9112, 11787, 14218,
9302, 11114, 13400,
9022, 11366, 13816,
6962, 10461, 12480,
11288, 13333, 15222,
7249, 8974, 10547,
10566, 12336, 14390,
6697, 11339, 13521,
11851, 13944, 15826,
6847, 8381, 11349,
7509, 9331, 10939,
8029, 9618, 11909,
13973, 17644, 19647, 22474,
14722, 16522, 20035, 22134,
16305, 18179, 21106, 23048,
15150, 17948, 21394, 23225,
13582, 15191, 17687, 22333,
11778, 15546, 18458, 21753,
16619, 18410, 20827, 23559,
14229, 15746, 17907, 22474,
12465, 15327, 20700, 22831,
15085, 16799, 20182, 23410,
13026, 16935, 19890, 22892,
14310, 16854, 19007, 22944,
14210, 15897, 18891, 23154,
14633, 18059, 20132, 22899,
15246, 17781, 19780, 22640,
16396, 18904, 20912, 23035,
14618, 17401, 19510, 21672,
15473, 17497, 19813, 23439,
18851, 20736, 22323, 23864,
15055, 16804, 18530, 20916,
16490, 18196, 19990, 21939,
11711, 15223, 21154, 23312,
13294, 15546, 19393, 21472,
12956, 16060, 20610, 22417,
11628, 15843, 19617, 22501,
14106, 16872, 19839, 22689,
15655, 18192, 20161, 22452,
12953, 15244, 20619, 23549,
15322, 17193, 19926, 21762,
16873, 18676, 20444, 22359,
14874, 17871, 20083, 21959,
11534, 14486, 19194, 21857,
17766, 19617, 21338, 23178,
13404, 15284, 19080, 23136,
15392, 17527, 19470, 21953,
14462, 16153, 17985, 21192,
17734, 19750, 21903, 23783,
16973, 19096, 21675, 23815,
16597, 18936, 21257, 23461,
15966, 17865, 20602, 22920,
15416, 17456, 20301, 22972,
18335, 20093, 21732, 23497,
15548, 17217, 20679, 23594,
15208, 16995, 20816, 22870,
13890, 18015, 20531, 22468,
13211, 15377, 19951, 22388,
12852, 14635, 17978, 22680,
16002, 17732, 20373, 23544,
11373, 14134, 19534, 22707,
17329, 19151, 21241, 23462,
15612, 17296, 19362, 22850,
15422, 19104, 21285, 23164,
13792, 17111, 19349, 21370,
15352, 17876, 20776, 22667,
15253, 16961, 18921, 22123,
14108, 17264, 20294, 23246,
15785, 17897, 20010, 21822,
17399, 19147, 20915, 22753,
13010, 15659, 18127, 20840,
16826, 19422, 22218, 24084,
18108, 20641, 22695, 24237,
18018, 20273, 22268, 23920,
16057, 17821, 21365, 23665,
16005, 17901, 19892, 23016,
13232, 16683, 21107, 23221,
13280, 16615, 19915, 21829,
14950, 18575, 20599, 22511,
16337, 18261, 20277, 23216,
14306, 16477, 21203, 23158,
12803, 17498, 20248, 22014,
14327, 17068, 20160, 22006,
14402, 17461, 21599, 23688,
16968, 18834, 20896, 23055,
15070, 17157, 20451, 22315,
15419, 17107, 21601, 23946,
16039, 17639, 19533, 21424,
16326, 19261, 21745, 23673,
16489, 18534, 21658, 23782,
16594, 18471, 20549, 22807,
18973, 21212, 22890, 24278,
14264, 18674, 21123, 23071,
15117, 16841, 19239, 23118,
13762, 15782, 20478, 23230,
14111, 15949, 20058, 22354,
14990, 16738, 21139, 23492,
13735, 16971, 19026, 22158,
14676, 17314, 20232, 22807,
16196, 18146, 20459, 22339,
14747, 17258, 19315, 22437,
14973, 17778, 20692, 23367,
15715, 17472, 20385, 22349,
15702, 18228, 20829, 23410,
14428, 16188, 20541, 23630,
16824, 19394, 21365, 23246,
13069, 16392, 18900, 21121,
12047, 16640, 19463, 21689,
14757, 17433, 19659, 23125,
15185, 16930, 19900, 22540,
16026, 17725, 19618, 22399,
16086, 18643, 21179, 23472,
15462, 17248, 19102, 21196,
17368, 20016, 22396, 24096,
12340, 14475, 19665, 23362,
13636, 16229, 19462, 22728,
14096, 16211, 19591, 21635,
12152, 14867, 19943, 22301,
14492, 17503, 21002, 22728,
14834, 16788, 19447, 21411,
14650, 16433, 19326, 22308,
14624, 16328, 19659, 23204,
13888, 16572, 20665, 22488,
12977, 16102, 18841, 22246,
15523, 18431, 21757, 23738,
14095, 16349, 18837, 20947,
13266, 17809, 21088, 22839,
15427, 18190, 20270, 23143,
11859, 16753, 20935, 22486,
12310, 17667, 21736, 23319,
14021, 15926, 18702, 22002,
12286, 15299, 19178, 21126,
15703, 17491, 21039, 23151,
12272, 14018, 18213, 22570,
14817, 16364, 18485, 22598,
17109, 19683, 21851, 23677,
12657, 14903, 19039, 22061,
14713, 16487, 20527, 22814,
14635, 16726, 18763, 21715,
15878, 18550, 20718, 22906
};
const int16_t WebRtcIlbcfix_kLsfDimCb[LSF_NSPLIT] = {3, 3, 4};
const int16_t WebRtcIlbcfix_kLsfSizeCb[LSF_NSPLIT] = {64,128,128};
const int16_t WebRtcIlbcfix_kLsfMean[LPC_FILTERORDER] = {
2308, 3652, 5434, 7885,
10255, 12559, 15160, 17513,
20328, 22752};
const int16_t WebRtcIlbcfix_kLspMean[LPC_FILTERORDER] = {
31476, 29565, 25819, 18725, 10276,
1236, -9049, -17600, -25884, -30618
};
/* Q14 */
const int16_t WebRtcIlbcfix_kLsfWeight20ms[4] = {12288, 8192, 4096, 0};
const int16_t WebRtcIlbcfix_kLsfWeight30ms[6] = {8192, 16384, 10923, 5461, 0, 0};
/*
cos(x) in Q15
WebRtcIlbcfix_kCos[i] = cos(pi*i/64.0)
used in WebRtcIlbcfix_Lsp2Lsf()
*/
const int16_t WebRtcIlbcfix_kCos[64] = {
32767, 32729, 32610, 32413, 32138, 31786, 31357, 30853,
30274, 29622, 28899, 28106, 27246, 26320, 25330, 24279,
23170, 22006, 20788, 19520, 18205, 16846, 15447, 14010,
12540, 11039, 9512, 7962, 6393, 4808, 3212, 1608,
0, -1608, -3212, -4808, -6393, -7962, -9512, -11039,
-12540, -14010, -15447, -16846, -18205, -19520, -20788, -22006,
-23170, -24279, -25330, -26320, -27246, -28106, -28899, -29622,
-30274, -30853, -31357, -31786, -32138, -32413, -32610, -32729
};
/*
Derivative in Q19, used to interpolate between the
WebRtcIlbcfix_kCos[] values to get a more exact y = cos(x)
*/
const int16_t WebRtcIlbcfix_kCosDerivative[64] = {
-632, -1893, -3150, -4399, -5638, -6863, -8072, -9261,
-10428, -11570, -12684, -13767, -14817, -15832, -16808, -17744,
-18637, -19486, -20287, -21039, -21741, -22390, -22986, -23526,
-24009, -24435, -24801, -25108, -25354, -25540, -25664, -25726,
-25726, -25664, -25540, -25354, -25108, -24801, -24435, -24009,
-23526, -22986, -22390, -21741, -21039, -20287, -19486, -18637,
-17744, -16808, -15832, -14817, -13767, -12684, -11570, -10428,
-9261, -8072, -6863, -5638, -4399, -3150, -1893, -632};
/*
Table in Q15, used for a2lsf conversion
WebRtcIlbcfix_kCosGrid[i] = cos((2*pi*i)/(float)(2*COS_GRID_POINTS));
*/
const int16_t WebRtcIlbcfix_kCosGrid[COS_GRID_POINTS + 1] = {
32760, 32723, 32588, 32364, 32051, 31651, 31164, 30591,
29935, 29196, 28377, 27481, 26509, 25465, 24351, 23170,
21926, 20621, 19260, 17846, 16384, 14876, 13327, 11743,
10125, 8480, 6812, 5126, 3425, 1714, 0, -1714, -3425,
-5126, -6812, -8480, -10125, -11743, -13327, -14876,
-16384, -17846, -19260, -20621, -21926, -23170, -24351,
-25465, -26509, -27481, -28377, -29196, -29935, -30591,
-31164, -31651, -32051, -32364, -32588, -32723, -32760
};
/*
Derivative of y = acos(x) in Q12
used in WebRtcIlbcfix_Lsp2Lsf()
*/
const int16_t WebRtcIlbcfix_kAcosDerivative[64] = {
-26887, -8812, -5323, -3813, -2979, -2444, -2081, -1811,
-1608, -1450, -1322, -1219, -1132, -1059, -998, -946,
-901, -861, -827, -797, -772, -750, -730, -713,
-699, -687, -677, -668, -662, -657, -654, -652,
-652, -654, -657, -662, -668, -677, -687, -699,
-713, -730, -750, -772, -797, -827, -861, -901,
-946, -998, -1059, -1132, -1219, -1322, -1450, -1608,
-1811, -2081, -2444, -2979, -3813, -5323, -8812, -26887
};
/* Tables for quantization of start state */
/* State quantization tables */
const int16_t WebRtcIlbcfix_kStateSq3[8] = { /* Values in Q13 */
-30473, -17838, -9257, -2537,
3639, 10893, 19958, 32636
};
/* This table defines the limits for the selection of the freqg
less or equal than value 0 => index = 0
less or equal than value k => index = k
*/
const int32_t WebRtcIlbcfix_kChooseFrgQuant[64] = {
118, 163, 222, 305, 425, 604,
851, 1174, 1617, 2222, 3080, 4191,
5525, 7215, 9193, 11540, 14397, 17604,
21204, 25209, 29863, 35720, 42531, 50375,
59162, 68845, 80108, 93754, 110326, 129488,
150654, 174328, 201962, 233195, 267843, 308239,
354503, 405988, 464251, 531550, 608652, 697516,
802526, 928793, 1080145, 1258120, 1481106, 1760881,
2111111, 2546619, 3078825, 3748642, 4563142, 5573115,
6887601, 8582108, 10797296, 14014513, 18625760, 25529599,
37302935, 58819185, 109782723, WEBRTC_SPL_WORD32_MAX
};
const int16_t WebRtcIlbcfix_kScale[64] = {
/* Values in Q16 */
29485, 25003, 21345, 18316, 15578, 13128, 10973, 9310, 7955,
6762, 5789, 4877, 4255, 3699, 3258, 2904, 2595, 2328,
2123, 1932, 1785, 1631, 1493, 1370, 1260, 1167, 1083,
/* Values in Q21 */
32081, 29611, 27262, 25229, 23432, 21803, 20226, 18883, 17609,
16408, 15311, 14327, 13390, 12513, 11693, 10919, 10163, 9435,
8739, 8100, 7424, 6813, 6192, 5648, 5122, 4639, 4207, 3798,
3404, 3048, 2706, 2348, 2036, 1713, 1393, 1087, 747
};
/*frgq in fixpoint, but already computed like this:
for(i=0; i<64; i++){
a = (pow(10,frgq[i])/4.5);
WebRtcIlbcfix_kFrgQuantMod[i] = round(a);
}
Value 0 :36 in Q8
37:58 in Q5
59:63 in Q3
*/
const int16_t WebRtcIlbcfix_kFrgQuantMod[64] = {
/* First 37 values in Q8 */
569, 671, 786, 916, 1077, 1278,
1529, 1802, 2109, 2481, 2898, 3440,
3943, 4535, 5149, 5778, 6464, 7208,
7904, 8682, 9397, 10285, 11240, 12246,
13313, 14382, 15492, 16735, 18131, 19693,
21280, 22912, 24624, 26544, 28432, 30488,
32720,
/* 22 values in Q5 */
4383, 4684, 5012, 5363, 5739, 6146,
6603, 7113, 7679, 8285, 9040, 9850,
10838, 11882, 13103, 14467, 15950, 17669,
19712, 22016, 24800, 28576,
/* 5 values in Q3 */
8240, 9792, 12040, 15440, 22472
};
/* Constants for codebook search and creation */
/* Expansion filter to get additional cb section.
* Q12 and reversed compared to flp
*/
const int16_t WebRtcIlbcfix_kCbFiltersRev[CB_FILTERLEN]={
-140, 446, -755, 3302, 2922, -590, 343, -138};
/* Weighting coefficients for short lags.
* [0.2 0.4 0.6 0.8] in Q15 */
const int16_t WebRtcIlbcfix_kAlpha[4]={
6554, 13107, 19661, 26214};
/* Ranges for search and filters at different subframes */
const int16_t WebRtcIlbcfix_kSearchRange[5][CB_NSTAGES]={
{58,58,58}, {108,44,44}, {108,108,108}, {108,108,108}, {108,108,108}};
const int16_t WebRtcIlbcfix_kFilterRange[5]={63, 85, 125, 147, 147};
/* Gain Quantization for the codebook gains of the 3 stages */
/* Q14 (one extra value (max int16_t) to simplify for the search) */
const int16_t WebRtcIlbcfix_kGainSq3[9]={
-16384, -10813, -5407, 0, 4096, 8192,
12288, 16384, 32767};
/* Q14 (one extra value (max int16_t) to simplify for the search) */
const int16_t WebRtcIlbcfix_kGainSq4[17]={
-17203, -14746, -12288, -9830, -7373, -4915,
-2458, 0, 2458, 4915, 7373, 9830,
12288, 14746, 17203, 19661, 32767};
/* Q14 (one extra value (max int16_t) to simplify for the search) */
const int16_t WebRtcIlbcfix_kGainSq5[33]={
614, 1229, 1843, 2458, 3072, 3686,
4301, 4915, 5530, 6144, 6758, 7373,
7987, 8602, 9216, 9830, 10445, 11059,
11674, 12288, 12902, 13517, 14131, 14746,
15360, 15974, 16589, 17203, 17818, 18432,
19046, 19661, 32767};
/* Q14 gain_sq5Tbl squared in Q14 */
const int16_t WebRtcIlbcfix_kGainSq5Sq[32] = {
23, 92, 207, 368, 576, 829,
1129, 1474, 1866, 2304, 2787, 3317,
3893, 4516, 5184, 5897, 6658, 7464,
8318, 9216, 10160, 11151, 12187, 13271,
14400, 15574, 16796, 18062, 19377, 20736,
22140, 23593
};
const int16_t* const WebRtcIlbcfix_kGain[3] =
{WebRtcIlbcfix_kGainSq5, WebRtcIlbcfix_kGainSq4, WebRtcIlbcfix_kGainSq3};
/* Tables for the Enhancer, using upsamling factor 4 (ENH_UPS0 = 4) */
const int16_t WebRtcIlbcfix_kEnhPolyPhaser[ENH_UPS0][ENH_FLO_MULT2_PLUS1]={
{0, 0, 0, 4096, 0, 0, 0},
{64, -315, 1181, 3531, -436, 77, -64},
{97, -509, 2464, 2464, -509, 97, -97},
{77, -436, 3531, 1181, -315, 64, -77}
};
const int16_t WebRtcIlbcfix_kEnhWt[3] = {
4800, 16384, 27968 /* Q16 */
};
const int16_t WebRtcIlbcfix_kEnhPlocs[ENH_NBLOCKS_TOT] = {
160, 480, 800, 1120, 1440, 1760, 2080, 2400 /* Q(-2) */
};
/* PLC table */
const int16_t WebRtcIlbcfix_kPlcPerSqr[6] = { /* Grid points for square of periodiciy in Q15 */
839, 1343, 2048, 2998, 4247, 5849
};
const int16_t WebRtcIlbcfix_kPlcPitchFact[6] = { /* Value of y=(x^4-0.4)/(0.7-0.4) in grid points in Q15 */
0, 5462, 10922, 16384, 21846, 27306
};
const int16_t WebRtcIlbcfix_kPlcPfSlope[6] = { /* Slope of y=(x^4-0.4)/(0.7-0.4) in Q11 */
26667, 18729, 13653, 10258, 7901, 6214
};

View File

@@ -0,0 +1,92 @@
/*
* 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.
*/
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
constants.h
******************************************************************/
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_CONSTANTS_H_
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_CONSTANTS_H_
#include "defines.h"
#include "typedefs.h"
/* high pass filters */
extern const int16_t WebRtcIlbcfix_kHpInCoefs[];
extern const int16_t WebRtcIlbcfix_kHpOutCoefs[];
/* Window for start state decision */
extern const int16_t WebRtcIlbcfix_kStartSequenceEnrgWin[];
/* low pass filter used for downsampling */
extern const int16_t WebRtcIlbcfix_kLpFiltCoefs[];
/* LPC analysis and quantization */
extern const int16_t WebRtcIlbcfix_kLpcWin[];
extern const int16_t WebRtcIlbcfix_kLpcAsymWin[];
extern const int32_t WebRtcIlbcfix_kLpcLagWin[];
extern const int16_t WebRtcIlbcfix_kLpcChirpSyntDenum[];
extern const int16_t WebRtcIlbcfix_kLpcChirpWeightDenum[];
extern const int16_t WebRtcIlbcfix_kLsfDimCb[];
extern const int16_t WebRtcIlbcfix_kLsfSizeCb[];
extern const int16_t WebRtcIlbcfix_kLsfCb[];
extern const int16_t WebRtcIlbcfix_kLsfWeight20ms[];
extern const int16_t WebRtcIlbcfix_kLsfWeight30ms[];
extern const int16_t WebRtcIlbcfix_kLsfMean[];
extern const int16_t WebRtcIlbcfix_kLspMean[];
extern const int16_t WebRtcIlbcfix_kCos[];
extern const int16_t WebRtcIlbcfix_kCosDerivative[];
extern const int16_t WebRtcIlbcfix_kCosGrid[];
extern const int16_t WebRtcIlbcfix_kAcosDerivative[];
/* state quantization tables */
extern const int16_t WebRtcIlbcfix_kStateSq3[];
extern const int32_t WebRtcIlbcfix_kChooseFrgQuant[];
extern const int16_t WebRtcIlbcfix_kScale[];
extern const int16_t WebRtcIlbcfix_kFrgQuantMod[];
/* Ranges for search and filters at different subframes */
extern const int16_t WebRtcIlbcfix_kSearchRange[5][CB_NSTAGES];
extern const int16_t WebRtcIlbcfix_kFilterRange[];
/* gain quantization tables */
extern const int16_t WebRtcIlbcfix_kGainSq3[];
extern const int16_t WebRtcIlbcfix_kGainSq4[];
extern const int16_t WebRtcIlbcfix_kGainSq5[];
extern const int16_t WebRtcIlbcfix_kGainSq5Sq[];
extern const int16_t* const WebRtcIlbcfix_kGain[];
/* adaptive codebook definitions */
extern const int16_t WebRtcIlbcfix_kCbFiltersRev[];
extern const int16_t WebRtcIlbcfix_kAlpha[];
/* enhancer definitions */
extern const int16_t WebRtcIlbcfix_kEnhPolyPhaser[ENH_UPS0][ENH_FLO_MULT2_PLUS1];
extern const int16_t WebRtcIlbcfix_kEnhWt[];
extern const int16_t WebRtcIlbcfix_kEnhPlocs[];
/* PLC tables */
extern const int16_t WebRtcIlbcfix_kPlcPerSqr[];
extern const int16_t WebRtcIlbcfix_kPlcPitchFact[];
extern const int16_t WebRtcIlbcfix_kPlcPfSlope[];
#endif

View File

@@ -0,0 +1,57 @@
/*
* 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.
*/
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
WebRtcIlbcfix_CreateAugmentedVec.c
******************************************************************/
#include "defines.h"
#include "constants.h"
/*----------------------------------------------------------------*
* Recreate a specific codebook vector from the augmented part.
*
*----------------------------------------------------------------*/
void WebRtcIlbcfix_CreateAugmentedVec(
int16_t index, /* (i) Index for the augmented vector to be created */
int16_t *buffer, /* (i) Pointer to the end of the codebook memory that
is used for creation of the augmented codebook */
int16_t *cbVec /* (o) The construced codebook vector */
) {
int16_t ilow;
int16_t *ppo, *ppi;
int16_t cbVecTmp[4];
ilow = index-4;
/* copy the first noninterpolated part */
ppo = buffer-index;
WEBRTC_SPL_MEMCPY_W16(cbVec, ppo, index);
/* interpolation */
ppo = buffer - 4;
ppi = buffer - index - 4;
/* perform cbVec[ilow+k] = ((ppi[k]*alphaTbl[k])>>15) + ((ppo[k]*alphaTbl[3-k])>>15);
for k = 0..3
*/
WebRtcSpl_ElementwiseVectorMult(&cbVec[ilow], ppi, WebRtcIlbcfix_kAlpha, 4, 15);
WebRtcSpl_ReverseOrderMultArrayElements(cbVecTmp, ppo, &WebRtcIlbcfix_kAlpha[3], 4, 15);
WebRtcSpl_AddVectorsAndShift(&cbVec[ilow], &cbVec[ilow], cbVecTmp, 4, 0);
/* copy the second noninterpolated part */
ppo = buffer - index;
WEBRTC_SPL_MEMCPY_W16(cbVec+index,ppo,(SUBL-index));
}

View File

@@ -0,0 +1,36 @@
/*
* 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.
*/
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
WebRtcIlbcfix_CreateAugmentedVec.h
******************************************************************/
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_CREATE_AUGMENTED_VEC_H_
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_CREATE_AUGMENTED_VEC_H_
#include "defines.h"
/*----------------------------------------------------------------*
* Recreate a specific codebook vector from the augmented part.
*
*----------------------------------------------------------------*/
void WebRtcIlbcfix_CreateAugmentedVec(
int16_t index, /* (i) Index for the augmented vector to be created */
int16_t *buffer, /* (i) Pointer to the end of the codebook memory that
is used for creation of the augmented codebook */
int16_t *cbVec /* (o) The construced codebook vector */
);
#endif

View File

@@ -0,0 +1,243 @@
/*
* 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.
*/
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
WebRtcIlbcfix_Decode.c
******************************************************************/
#include "defines.h"
#include "simple_lsf_dequant.h"
#include "decoder_interpolate_lsf.h"
#include "index_conv_dec.h"
#include "do_plc.h"
#include "constants.h"
#include "enhancer_interface.h"
#include "xcorr_coef.h"
#include "lsf_check.h"
#include "decode_residual.h"
#include "unpack_bits.h"
#include "hp_output.h"
#ifndef WEBRTC_ARCH_BIG_ENDIAN
#include "swap_bytes.h"
#endif
/*----------------------------------------------------------------*
* main decoder function
*---------------------------------------------------------------*/
void WebRtcIlbcfix_DecodeImpl(
int16_t *decblock, /* (o) decoded signal block */
const uint16_t *bytes, /* (i) encoded signal bits */
iLBC_Dec_Inst_t *iLBCdec_inst, /* (i/o) the decoder state
structure */
int16_t mode /* (i) 0: bad packet, PLC,
1: normal */
) {
int i;
int16_t order_plus_one;
int16_t last_bit;
int16_t *data;
/* Stack based */
int16_t decresidual[BLOCKL_MAX];
int16_t PLCresidual[BLOCKL_MAX + LPC_FILTERORDER];
int16_t syntdenum[NSUB_MAX*(LPC_FILTERORDER+1)];
int16_t PLClpc[LPC_FILTERORDER + 1];
#ifndef WEBRTC_ARCH_BIG_ENDIAN
uint16_t swapped[NO_OF_WORDS_30MS];
#endif
iLBC_bits *iLBCbits_inst = (iLBC_bits*)PLCresidual;
/* Reuse some buffers that are non overlapping in order to save stack memory */
data = &PLCresidual[LPC_FILTERORDER];
if (mode) { /* the data are good */
/* decode data */
/* Unpacketize bits into parameters */
#ifndef WEBRTC_ARCH_BIG_ENDIAN
WebRtcIlbcfix_SwapBytes(bytes, iLBCdec_inst->no_of_words, swapped);
last_bit = WebRtcIlbcfix_UnpackBits(swapped, iLBCbits_inst, iLBCdec_inst->mode);
#else
last_bit = WebRtcIlbcfix_UnpackBits(bytes, iLBCbits_inst, iLBCdec_inst->mode);
#endif
/* Check for bit errors */
if (iLBCbits_inst->startIdx<1)
mode = 0;
if ((iLBCdec_inst->mode==20) && (iLBCbits_inst->startIdx>3))
mode = 0;
if ((iLBCdec_inst->mode==30) && (iLBCbits_inst->startIdx>5))
mode = 0;
if (last_bit==1)
mode = 0;
if (mode) { /* No bit errors was detected, continue decoding */
/* Stack based */
int16_t lsfdeq[LPC_FILTERORDER*LPC_N_MAX];
int16_t weightdenum[(LPC_FILTERORDER + 1)*NSUB_MAX];
/* adjust index */
WebRtcIlbcfix_IndexConvDec(iLBCbits_inst->cb_index);
/* decode the lsf */
WebRtcIlbcfix_SimpleLsfDeQ(lsfdeq, (int16_t*)(iLBCbits_inst->lsf), iLBCdec_inst->lpc_n);
WebRtcIlbcfix_LsfCheck(lsfdeq, LPC_FILTERORDER, iLBCdec_inst->lpc_n);
WebRtcIlbcfix_DecoderInterpolateLsp(syntdenum, weightdenum,
lsfdeq, LPC_FILTERORDER, iLBCdec_inst);
/* Decode the residual using the cb and gain indexes */
WebRtcIlbcfix_DecodeResidual(iLBCdec_inst, iLBCbits_inst, decresidual, syntdenum);
/* preparing the plc for a future loss! */
WebRtcIlbcfix_DoThePlc( PLCresidual, PLClpc, 0,
decresidual, syntdenum + (LPC_FILTERORDER + 1)*(iLBCdec_inst->nsub - 1),
(int16_t)(iLBCdec_inst->last_lag), iLBCdec_inst);
/* Use the output from doThePLC */
WEBRTC_SPL_MEMCPY_W16(decresidual, PLCresidual, iLBCdec_inst->blockl);
}
}
if (mode == 0) {
/* the data is bad (either a PLC call
* was made or a bit error was detected)
*/
/* packet loss conceal */
WebRtcIlbcfix_DoThePlc( PLCresidual, PLClpc, 1,
decresidual, syntdenum, (int16_t)(iLBCdec_inst->last_lag), iLBCdec_inst);
WEBRTC_SPL_MEMCPY_W16(decresidual, PLCresidual, iLBCdec_inst->blockl);
order_plus_one = LPC_FILTERORDER + 1;
for (i = 0; i < iLBCdec_inst->nsub; i++) {
WEBRTC_SPL_MEMCPY_W16(syntdenum+(i*order_plus_one),
PLClpc, order_plus_one);
}
}
if ((*iLBCdec_inst).use_enhancer == 1) { /* Enhancer activated */
/* Update the filter and filter coefficients if there was a packet loss */
if (iLBCdec_inst->prev_enh_pl==2) {
for (i=0;i<iLBCdec_inst->nsub;i++) {
WEBRTC_SPL_MEMCPY_W16(&(iLBCdec_inst->old_syntdenum[i*(LPC_FILTERORDER+1)]),
syntdenum, (LPC_FILTERORDER+1));
}
}
/* post filtering */
(*iLBCdec_inst).last_lag =
WebRtcIlbcfix_EnhancerInterface(data, decresidual, iLBCdec_inst);
/* synthesis filtering */
/* Set up the filter state */
WEBRTC_SPL_MEMCPY_W16(&data[-LPC_FILTERORDER], iLBCdec_inst->syntMem, LPC_FILTERORDER);
if (iLBCdec_inst->mode==20) {
/* Enhancer has 40 samples delay */
i=0;
WebRtcSpl_FilterARFastQ12(
data, data,
iLBCdec_inst->old_syntdenum + (i+iLBCdec_inst->nsub-1)*(LPC_FILTERORDER+1),
LPC_FILTERORDER+1, SUBL);
for (i=1; i < iLBCdec_inst->nsub; i++) {
WebRtcSpl_FilterARFastQ12(
data+i*SUBL, data+i*SUBL,
syntdenum+(i-1)*(LPC_FILTERORDER+1),
LPC_FILTERORDER+1, SUBL);
}
} else if (iLBCdec_inst->mode==30) {
/* Enhancer has 80 samples delay */
for (i=0; i < 2; i++) {
WebRtcSpl_FilterARFastQ12(
data+i*SUBL, data+i*SUBL,
iLBCdec_inst->old_syntdenum + (i+4)*(LPC_FILTERORDER+1),
LPC_FILTERORDER+1, SUBL);
}
for (i=2; i < iLBCdec_inst->nsub; i++) {
WebRtcSpl_FilterARFastQ12(
data+i*SUBL, data+i*SUBL,
syntdenum+(i-2)*(LPC_FILTERORDER+1),
LPC_FILTERORDER+1, SUBL);
}
}
/* Save the filter state */
WEBRTC_SPL_MEMCPY_W16(iLBCdec_inst->syntMem, &data[iLBCdec_inst->blockl-LPC_FILTERORDER], LPC_FILTERORDER);
} else { /* Enhancer not activated */
int16_t lag;
/* Find last lag (since the enhancer is not called to give this info) */
lag = 20;
if (iLBCdec_inst->mode==20) {
lag = (int16_t)WebRtcIlbcfix_XcorrCoef(
&decresidual[iLBCdec_inst->blockl-60],
&decresidual[iLBCdec_inst->blockl-60-lag],
60,
80, lag, -1);
} else {
lag = (int16_t)WebRtcIlbcfix_XcorrCoef(
&decresidual[iLBCdec_inst->blockl-ENH_BLOCKL],
&decresidual[iLBCdec_inst->blockl-ENH_BLOCKL-lag],
ENH_BLOCKL,
100, lag, -1);
}
/* Store lag (it is needed if next packet is lost) */
(*iLBCdec_inst).last_lag = (int)lag;
/* copy data and run synthesis filter */
WEBRTC_SPL_MEMCPY_W16(data, decresidual, iLBCdec_inst->blockl);
/* Set up the filter state */
WEBRTC_SPL_MEMCPY_W16(&data[-LPC_FILTERORDER], iLBCdec_inst->syntMem, LPC_FILTERORDER);
for (i=0; i < iLBCdec_inst->nsub; i++) {
WebRtcSpl_FilterARFastQ12(
data+i*SUBL, data+i*SUBL,
syntdenum + i*(LPC_FILTERORDER+1),
LPC_FILTERORDER+1, SUBL);
}
/* Save the filter state */
WEBRTC_SPL_MEMCPY_W16(iLBCdec_inst->syntMem, &data[iLBCdec_inst->blockl-LPC_FILTERORDER], LPC_FILTERORDER);
}
WEBRTC_SPL_MEMCPY_W16(decblock,data,iLBCdec_inst->blockl);
/* High pass filter the signal (with upscaling a factor 2 and saturation) */
WebRtcIlbcfix_HpOutput(decblock, (int16_t*)WebRtcIlbcfix_kHpOutCoefs,
iLBCdec_inst->hpimemy, iLBCdec_inst->hpimemx,
iLBCdec_inst->blockl);
WEBRTC_SPL_MEMCPY_W16(iLBCdec_inst->old_syntdenum,
syntdenum, iLBCdec_inst->nsub*(LPC_FILTERORDER+1));
iLBCdec_inst->prev_enh_pl=0;
if (mode==0) { /* PLC was used */
iLBCdec_inst->prev_enh_pl=1;
}
}

View File

@@ -0,0 +1,37 @@
/*
* 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.
*/
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
WebRtcIlbcfix_Decode.h
******************************************************************/
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_DECODE_H_
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_DECODE_H_
#include "defines.h"
/*----------------------------------------------------------------*
* main decoder function
*---------------------------------------------------------------*/
void WebRtcIlbcfix_DecodeImpl(
int16_t *decblock, /* (o) decoded signal block */
const uint16_t *bytes, /* (i) encoded signal bits */
iLBC_Dec_Inst_t *iLBCdec_inst, /* (i/o) the decoder state
structure */
int16_t mode /* (i) 0: bad packet, PLC,
1: normal */
);
#endif

View File

@@ -0,0 +1,185 @@
/*
* 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.
*/
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
WebRtcIlbcfix_DecodeResidual.c
******************************************************************/
#include <string.h>
#include "defines.h"
#include "state_construct.h"
#include "cb_construct.h"
#include "index_conv_dec.h"
#include "do_plc.h"
#include "constants.h"
#include "enhancer_interface.h"
#include "xcorr_coef.h"
#include "lsf_check.h"
/*----------------------------------------------------------------*
* frame residual decoder function (subrutine to iLBC_decode)
*---------------------------------------------------------------*/
void WebRtcIlbcfix_DecodeResidual(
iLBC_Dec_Inst_t *iLBCdec_inst,
/* (i/o) the decoder state structure */
iLBC_bits *iLBC_encbits, /* (i/o) Encoded bits, which are used
for the decoding */
int16_t *decresidual, /* (o) decoded residual frame */
int16_t *syntdenum /* (i) the decoded synthesis filter
coefficients */
) {
int16_t meml_gotten, Nfor, Nback, diff, start_pos;
int16_t subcount, subframe;
int16_t *reverseDecresidual = iLBCdec_inst->enh_buf; /* Reversed decoded data, used for decoding backwards in time (reuse memory in state) */
int16_t *memVec = iLBCdec_inst->prevResidual; /* Memory for codebook and filter state (reuse memory in state) */
int16_t *mem = &memVec[CB_HALFFILTERLEN]; /* Memory for codebook */
diff = STATE_LEN - iLBCdec_inst->state_short_len;
if (iLBC_encbits->state_first == 1) {
start_pos = (iLBC_encbits->startIdx-1)*SUBL;
} else {
start_pos = (iLBC_encbits->startIdx-1)*SUBL + diff;
}
/* decode scalar part of start state */
WebRtcIlbcfix_StateConstruct(iLBC_encbits->idxForMax,
iLBC_encbits->idxVec, &syntdenum[(iLBC_encbits->startIdx-1)*(LPC_FILTERORDER+1)],
&decresidual[start_pos], iLBCdec_inst->state_short_len
);
if (iLBC_encbits->state_first) { /* put adaptive part in the end */
/* setup memory */
WebRtcSpl_MemSetW16(mem, 0, (int16_t)(CB_MEML-iLBCdec_inst->state_short_len));
WEBRTC_SPL_MEMCPY_W16(mem+CB_MEML-iLBCdec_inst->state_short_len, decresidual+start_pos,
iLBCdec_inst->state_short_len);
/* construct decoded vector */
WebRtcIlbcfix_CbConstruct(
&decresidual[start_pos+iLBCdec_inst->state_short_len],
iLBC_encbits->cb_index, iLBC_encbits->gain_index,
mem+CB_MEML-ST_MEM_L_TBL,
ST_MEM_L_TBL, (int16_t)diff
);
}
else {/* put adaptive part in the beginning */
/* setup memory */
meml_gotten = iLBCdec_inst->state_short_len;
WebRtcSpl_MemCpyReversedOrder(mem+CB_MEML-1,
decresidual+start_pos, meml_gotten);
WebRtcSpl_MemSetW16(mem, 0, (int16_t)(CB_MEML-meml_gotten));
/* construct decoded vector */
WebRtcIlbcfix_CbConstruct(
reverseDecresidual,
iLBC_encbits->cb_index, iLBC_encbits->gain_index,
mem+CB_MEML-ST_MEM_L_TBL,
ST_MEM_L_TBL, diff
);
/* get decoded residual from reversed vector */
WebRtcSpl_MemCpyReversedOrder(&decresidual[start_pos-1],
reverseDecresidual, diff);
}
/* counter for predicted subframes */
subcount=1;
/* forward prediction of subframes */
Nfor = iLBCdec_inst->nsub-iLBC_encbits->startIdx-1;
if( Nfor > 0 ) {
/* setup memory */
WebRtcSpl_MemSetW16(mem, 0, CB_MEML-STATE_LEN);
WEBRTC_SPL_MEMCPY_W16(mem+CB_MEML-STATE_LEN,
decresidual+(iLBC_encbits->startIdx-1)*SUBL, STATE_LEN);
/* loop over subframes to encode */
for (subframe=0; subframe<Nfor; subframe++) {
/* construct decoded vector */
WebRtcIlbcfix_CbConstruct(
&decresidual[(iLBC_encbits->startIdx+1+subframe)*SUBL],
iLBC_encbits->cb_index+subcount*CB_NSTAGES,
iLBC_encbits->gain_index+subcount*CB_NSTAGES,
mem, MEM_LF_TBL, SUBL
);
/* update memory */
memmove(mem, mem + SUBL, (CB_MEML - SUBL) * sizeof(*mem));
WEBRTC_SPL_MEMCPY_W16(mem+CB_MEML-SUBL,
&decresidual[(iLBC_encbits->startIdx+1+subframe)*SUBL], SUBL);
subcount++;
}
}
/* backward prediction of subframes */
Nback = iLBC_encbits->startIdx-1;
if( Nback > 0 ){
/* setup memory */
meml_gotten = SUBL*(iLBCdec_inst->nsub+1-iLBC_encbits->startIdx);
if( meml_gotten > CB_MEML ) {
meml_gotten=CB_MEML;
}
WebRtcSpl_MemCpyReversedOrder(mem+CB_MEML-1,
decresidual+(iLBC_encbits->startIdx-1)*SUBL, meml_gotten);
WebRtcSpl_MemSetW16(mem, 0, (int16_t)(CB_MEML-meml_gotten));
/* loop over subframes to decode */
for (subframe=0; subframe<Nback; subframe++) {
/* construct decoded vector */
WebRtcIlbcfix_CbConstruct(
&reverseDecresidual[subframe*SUBL],
iLBC_encbits->cb_index+subcount*CB_NSTAGES,
iLBC_encbits->gain_index+subcount*CB_NSTAGES,
mem, MEM_LF_TBL, SUBL
);
/* update memory */
memmove(mem, mem + SUBL, (CB_MEML - SUBL) * sizeof(*mem));
WEBRTC_SPL_MEMCPY_W16(mem+CB_MEML-SUBL,
&reverseDecresidual[subframe*SUBL], SUBL);
subcount++;
}
/* get decoded residual from reversed vector */
WebRtcSpl_MemCpyReversedOrder(decresidual+SUBL*Nback-1,
reverseDecresidual, SUBL*Nback);
}
}

View File

@@ -0,0 +1,38 @@
/*
* 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.
*/
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
WebRtcIlbcfix_DecodeResidual.h
******************************************************************/
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_DECODE_RESIDUAL_H_
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_DECODE_RESIDUAL_H_
#include "defines.h"
/*----------------------------------------------------------------*
* frame residual decoder function (subrutine to iLBC_decode)
*---------------------------------------------------------------*/
void WebRtcIlbcfix_DecodeResidual(
iLBC_Dec_Inst_t *iLBCdec_inst,
/* (i/o) the decoder state structure */
iLBC_bits *iLBC_encbits, /* (i/o) Encoded bits, which are used
for the decoding */
int16_t *decresidual, /* (o) decoded residual frame */
int16_t *syntdenum /* (i) the decoded synthesis filter
coefficients */
);
#endif

View File

@@ -0,0 +1,82 @@
/*
* 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.
*/
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
WebRtcIlbcfix_DecoderInterpolateLsp.c
******************************************************************/
#include "lsf_interpolate_to_poly_dec.h"
#include "bw_expand.h"
#include "defines.h"
#include "constants.h"
/*----------------------------------------------------------------*
* obtain synthesis and weighting filters form lsf coefficients
*---------------------------------------------------------------*/
void WebRtcIlbcfix_DecoderInterpolateLsp(
int16_t *syntdenum, /* (o) synthesis filter coefficients */
int16_t *weightdenum, /* (o) weighting denumerator
coefficients */
int16_t *lsfdeq, /* (i) dequantized lsf coefficients */
int16_t length, /* (i) length of lsf coefficient vector */
iLBC_Dec_Inst_t *iLBCdec_inst
/* (i) the decoder state structure */
){
int i, pos, lp_length;
int16_t lp[LPC_FILTERORDER + 1], *lsfdeq2;
lsfdeq2 = lsfdeq + length;
lp_length = length + 1;
if (iLBCdec_inst->mode==30) {
/* subframe 1: Interpolation between old and first LSF */
WebRtcIlbcfix_LspInterpolate2PolyDec(lp, (*iLBCdec_inst).lsfdeqold, lsfdeq,
WebRtcIlbcfix_kLsfWeight30ms[0], length);
WEBRTC_SPL_MEMCPY_W16(syntdenum,lp,lp_length);
WebRtcIlbcfix_BwExpand(weightdenum, lp, (int16_t*)WebRtcIlbcfix_kLpcChirpSyntDenum, (int16_t)lp_length);
/* subframes 2 to 6: interpolation between first and last LSF */
pos = lp_length;
for (i = 1; i < 6; i++) {
WebRtcIlbcfix_LspInterpolate2PolyDec(lp, lsfdeq, lsfdeq2,
WebRtcIlbcfix_kLsfWeight30ms[i], length);
WEBRTC_SPL_MEMCPY_W16(syntdenum + pos,lp,lp_length);
WebRtcIlbcfix_BwExpand(weightdenum + pos, lp,
(int16_t*)WebRtcIlbcfix_kLpcChirpSyntDenum, (int16_t)lp_length);
pos += lp_length;
}
} else { /* iLBCdec_inst->mode=20 */
/* subframes 1 to 4: interpolation between old and new LSF */
pos = 0;
for (i = 0; i < iLBCdec_inst->nsub; i++) {
WebRtcIlbcfix_LspInterpolate2PolyDec(lp, iLBCdec_inst->lsfdeqold, lsfdeq,
WebRtcIlbcfix_kLsfWeight20ms[i], length);
WEBRTC_SPL_MEMCPY_W16(syntdenum+pos,lp,lp_length);
WebRtcIlbcfix_BwExpand(weightdenum+pos, lp,
(int16_t*)WebRtcIlbcfix_kLpcChirpSyntDenum, (int16_t)lp_length);
pos += lp_length;
}
}
/* update memory */
if (iLBCdec_inst->mode==30) {
WEBRTC_SPL_MEMCPY_W16(iLBCdec_inst->lsfdeqold, lsfdeq2, length);
} else {
WEBRTC_SPL_MEMCPY_W16(iLBCdec_inst->lsfdeqold, lsfdeq, length);
}
}

View File

@@ -0,0 +1,38 @@
/*
* 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.
*/
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
WebRtcIlbcfix_DecoderInterpolateLsp.h
******************************************************************/
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_DECODER_INTERPOLATE_LSF_H_
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_DECODER_INTERPOLATE_LSF_H_
#include "defines.h"
/*----------------------------------------------------------------*
* obtain synthesis and weighting filters form lsf coefficients
*---------------------------------------------------------------*/
void WebRtcIlbcfix_DecoderInterpolateLsp(
int16_t *syntdenum, /* (o) synthesis filter coefficients */
int16_t *weightdenum, /* (o) weighting denumerator
coefficients */
int16_t *lsfdeq, /* (i) dequantized lsf coefficients */
int16_t length, /* (i) length of lsf coefficient vector */
iLBC_Dec_Inst_t *iLBCdec_inst
/* (i) the decoder state structure */
);
#endif

View File

@@ -0,0 +1,219 @@
/*
* 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.
*/
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
define.h
******************************************************************/
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_DEFINES_H_
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_DEFINES_H_
#include "typedefs.h"
#include "signal_processing_library.h"
#include <string.h>
/* general codec settings */
#define FS 8000
#define BLOCKL_20MS 160
#define BLOCKL_30MS 240
#define BLOCKL_MAX 240
#define NSUB_20MS 4
#define NSUB_30MS 6
#define NSUB_MAX 6
#define NASUB_20MS 2
#define NASUB_30MS 4
#define NASUB_MAX 4
#define SUBL 40
#define STATE_LEN 80
#define STATE_SHORT_LEN_30MS 58
#define STATE_SHORT_LEN_20MS 57
/* LPC settings */
#define LPC_FILTERORDER 10
#define LPC_LOOKBACK 60
#define LPC_N_20MS 1
#define LPC_N_30MS 2
#define LPC_N_MAX 2
#define LPC_ASYMDIFF 20
#define LSF_NSPLIT 3
#define LSF_NUMBER_OF_STEPS 4
#define LPC_HALFORDER 5
#define COS_GRID_POINTS 60
/* cb settings */
#define CB_NSTAGES 3
#define CB_EXPAND 2
#define CB_MEML 147
#define CB_FILTERLEN (2*4)
#define CB_HALFFILTERLEN 4
#define CB_RESRANGE 34
#define CB_MAXGAIN_FIXQ6 83 /* error = -0.24% */
#define CB_MAXGAIN_FIXQ14 21299
/* enhancer */
#define ENH_BLOCKL 80 /* block length */
#define ENH_BLOCKL_HALF (ENH_BLOCKL/2)
#define ENH_HL 3 /* 2*ENH_HL+1 is number blocks
in said second sequence */
#define ENH_SLOP 2 /* max difference estimated and
correct pitch period */
#define ENH_PLOCSL 8 /* pitch-estimates and
pitch-locations buffer length */
#define ENH_OVERHANG 2
#define ENH_UPS0 4 /* upsampling rate */
#define ENH_FL0 3 /* 2*FLO+1 is the length of each filter */
#define ENH_FLO_MULT2_PLUS1 7
#define ENH_VECTL (ENH_BLOCKL+2*ENH_FL0)
#define ENH_CORRDIM (2*ENH_SLOP+1)
#define ENH_NBLOCKS (BLOCKL/ENH_BLOCKL)
#define ENH_NBLOCKS_EXTRA 5
#define ENH_NBLOCKS_TOT 8 /* ENH_NBLOCKS+ENH_NBLOCKS_EXTRA */
#define ENH_BUFL (ENH_NBLOCKS_TOT)*ENH_BLOCKL
#define ENH_BUFL_FILTEROVERHEAD 3
#define ENH_A0 819 /* Q14 */
#define ENH_A0_MINUS_A0A0DIV4 848256041 /* Q34 */
#define ENH_A0DIV2 26843546 /* Q30 */
/* PLC */
/* Down sampling */
#define FILTERORDER_DS_PLUS1 7
#define DELAY_DS 3
#define FACTOR_DS 2
/* bit stream defs */
#define NO_OF_BYTES_20MS 38
#define NO_OF_BYTES_30MS 50
#define NO_OF_WORDS_20MS 19
#define NO_OF_WORDS_30MS 25
#define STATE_BITS 3
#define BYTE_LEN 8
#define ULP_CLASSES 3
/* help parameters */
#define TWO_PI_FIX 25736 /* Q12 */
/* Constants for codebook search and creation */
#define ST_MEM_L_TBL 85
#define MEM_LF_TBL 147
/* Struct for the bits */
typedef struct iLBC_bits_t_ {
int16_t lsf[LSF_NSPLIT*LPC_N_MAX];
int16_t cb_index[CB_NSTAGES*(NASUB_MAX+1)]; /* First CB_NSTAGES values contains extra CB index */
int16_t gain_index[CB_NSTAGES*(NASUB_MAX+1)]; /* First CB_NSTAGES values contains extra CB gain */
int16_t idxForMax;
int16_t state_first;
int16_t idxVec[STATE_SHORT_LEN_30MS];
int16_t firstbits;
int16_t startIdx;
} iLBC_bits;
/* type definition encoder instance */
typedef struct iLBC_Enc_Inst_t_ {
/* flag for frame size mode */
int16_t mode;
/* basic parameters for different frame sizes */
int16_t blockl;
int16_t nsub;
int16_t nasub;
int16_t no_of_bytes, no_of_words;
int16_t lpc_n;
int16_t state_short_len;
/* analysis filter state */
int16_t anaMem[LPC_FILTERORDER];
/* Fix-point old lsf parameters for interpolation */
int16_t lsfold[LPC_FILTERORDER];
int16_t lsfdeqold[LPC_FILTERORDER];
/* signal buffer for LP analysis */
int16_t lpc_buffer[LPC_LOOKBACK + BLOCKL_MAX];
/* state of input HP filter */
int16_t hpimemx[2];
int16_t hpimemy[4];
#ifdef SPLIT_10MS
int16_t weightdenumbuf[66];
int16_t past_samples[160];
uint16_t bytes[25];
int16_t section;
int16_t Nfor_flag;
int16_t Nback_flag;
int16_t start_pos;
int16_t diff;
#endif
} iLBC_Enc_Inst_t;
/* type definition decoder instance */
typedef struct iLBC_Dec_Inst_t_ {
/* flag for frame size mode */
int16_t mode;
/* basic parameters for different frame sizes */
int16_t blockl;
int16_t nsub;
int16_t nasub;
int16_t no_of_bytes, no_of_words;
int16_t lpc_n;
int16_t state_short_len;
/* synthesis filter state */
int16_t syntMem[LPC_FILTERORDER];
/* old LSF for interpolation */
int16_t lsfdeqold[LPC_FILTERORDER];
/* pitch lag estimated in enhancer and used in PLC */
int last_lag;
/* PLC state information */
int consPLICount, prev_enh_pl;
int16_t perSquare;
int16_t prevScale, prevPLI;
int16_t prevLag, prevLpc[LPC_FILTERORDER+1];
int16_t prevResidual[NSUB_MAX*SUBL];
int16_t seed;
/* previous synthesis filter parameters */
int16_t old_syntdenum[(LPC_FILTERORDER + 1)*NSUB_MAX];
/* state of output HP filter */
int16_t hpimemx[2];
int16_t hpimemy[4];
/* enhancer state information */
int use_enhancer;
int16_t enh_buf[ENH_BUFL+ENH_BUFL_FILTEROVERHEAD];
int16_t enh_period[ENH_NBLOCKS_TOT];
} iLBC_Dec_Inst_t;
#endif

View File

@@ -0,0 +1,308 @@
/*
* 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.
*/
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
WebRtcIlbcfix_DoThePlc.c
******************************************************************/
#include "defines.h"
#include "constants.h"
#include "comp_corr.h"
#include "bw_expand.h"
/*----------------------------------------------------------------*
* Packet loss concealment routine. Conceals a residual signal
* and LP parameters. If no packet loss, update state.
*---------------------------------------------------------------*/
void WebRtcIlbcfix_DoThePlc(
int16_t *PLCresidual, /* (o) concealed residual */
int16_t *PLClpc, /* (o) concealed LP parameters */
int16_t PLI, /* (i) packet loss indicator
0 - no PL, 1 = PL */
int16_t *decresidual, /* (i) decoded residual */
int16_t *lpc, /* (i) decoded LPC (only used for no PL) */
int16_t inlag, /* (i) pitch lag */
iLBC_Dec_Inst_t *iLBCdec_inst
/* (i/o) decoder instance */
){
int16_t i, pick;
int32_t cross, ener, cross_comp, ener_comp = 0;
int32_t measure, maxMeasure, energy;
int16_t max, crossSquareMax, crossSquare;
int16_t j, lag, tmp1, tmp2, randlag;
int16_t shift1, shift2, shift3, shiftMax;
int16_t scale3;
int16_t corrLen;
int32_t tmpW32, tmp2W32;
int16_t use_gain;
int16_t tot_gain;
int16_t max_perSquare;
int16_t scale1, scale2;
int16_t totscale;
int32_t nom;
int16_t denom;
int16_t pitchfact;
int16_t use_lag;
int ind;
int16_t randvec[BLOCKL_MAX];
/* Packet Loss */
if (PLI == 1) {
(*iLBCdec_inst).consPLICount += 1;
/* if previous frame not lost,
determine pitch pred. gain */
if (iLBCdec_inst->prevPLI != 1) {
/* Maximum 60 samples are correlated, preserve as high accuracy
as possible without getting overflow */
max = WebRtcSpl_MaxAbsValueW16((*iLBCdec_inst).prevResidual, (int16_t)iLBCdec_inst->blockl);
scale3 = (WebRtcSpl_GetSizeInBits(max)<<1) - 25;
if (scale3 < 0) {
scale3 = 0;
}
/* Store scale for use when interpolating between the
* concealment and the received packet */
iLBCdec_inst->prevScale = scale3;
/* Search around the previous lag +/-3 to find the
best pitch period */
lag = inlag - 3;
/* Guard against getting outside the frame */
corrLen = WEBRTC_SPL_MIN(60, iLBCdec_inst->blockl-(inlag+3));
WebRtcIlbcfix_CompCorr( &cross, &ener,
iLBCdec_inst->prevResidual, lag, iLBCdec_inst->blockl, corrLen, scale3);
/* Normalize and store cross^2 and the number of shifts */
shiftMax = WebRtcSpl_GetSizeInBits(WEBRTC_SPL_ABS_W32(cross))-15;
crossSquareMax = (int16_t)WEBRTC_SPL_MUL_16_16_RSFT(WEBRTC_SPL_SHIFT_W32(cross, -shiftMax),
WEBRTC_SPL_SHIFT_W32(cross, -shiftMax), 15);
for (j=inlag-2;j<=inlag+3;j++) {
WebRtcIlbcfix_CompCorr( &cross_comp, &ener_comp,
iLBCdec_inst->prevResidual, j, iLBCdec_inst->blockl, corrLen, scale3);
/* Use the criteria (corr*corr)/energy to compare if
this lag is better or not. To avoid the division,
do a cross multiplication */
shift1 = WebRtcSpl_GetSizeInBits(WEBRTC_SPL_ABS_W32(cross_comp))-15;
crossSquare = (int16_t)WEBRTC_SPL_MUL_16_16_RSFT(WEBRTC_SPL_SHIFT_W32(cross_comp, -shift1),
WEBRTC_SPL_SHIFT_W32(cross_comp, -shift1), 15);
shift2 = WebRtcSpl_GetSizeInBits(ener)-15;
measure = WEBRTC_SPL_MUL_16_16(WEBRTC_SPL_SHIFT_W32(ener, -shift2),
crossSquare);
shift3 = WebRtcSpl_GetSizeInBits(ener_comp)-15;
maxMeasure = WEBRTC_SPL_MUL_16_16(WEBRTC_SPL_SHIFT_W32(ener_comp, -shift3),
crossSquareMax);
/* Calculate shift value, so that the two measures can
be put in the same Q domain */
if(((shiftMax<<1)+shift3) > ((shift1<<1)+shift2)) {
tmp1 = WEBRTC_SPL_MIN(31, (shiftMax<<1)+shift3-(shift1<<1)-shift2);
tmp2 = 0;
} else {
tmp1 = 0;
tmp2 = WEBRTC_SPL_MIN(31, (shift1<<1)+shift2-(shiftMax<<1)-shift3);
}
if ((measure>>tmp1) > (maxMeasure>>tmp2)) {
/* New lag is better => record lag, measure and domain */
lag = j;
crossSquareMax = crossSquare;
cross = cross_comp;
shiftMax = shift1;
ener = ener_comp;
}
}
/* Calculate the periodicity for the lag with the maximum correlation.
Definition of the periodicity:
abs(corr(vec1, vec2))/(sqrt(energy(vec1))*sqrt(energy(vec2)))
Work in the Square domain to simplify the calculations
max_perSquare is less than 1 (in Q15)
*/
tmp2W32=WebRtcSpl_DotProductWithScale(&iLBCdec_inst->prevResidual[iLBCdec_inst->blockl-corrLen],
&iLBCdec_inst->prevResidual[iLBCdec_inst->blockl-corrLen],
corrLen, scale3);
if ((tmp2W32>0)&&(ener_comp>0)) {
/* norm energies to int16_t, compute the product of the energies and
use the upper int16_t as the denominator */
scale1=(int16_t)WebRtcSpl_NormW32(tmp2W32)-16;
tmp1=(int16_t)WEBRTC_SPL_SHIFT_W32(tmp2W32, scale1);
scale2=(int16_t)WebRtcSpl_NormW32(ener)-16;
tmp2=(int16_t)WEBRTC_SPL_SHIFT_W32(ener, scale2);
denom=(int16_t)WEBRTC_SPL_MUL_16_16_RSFT(tmp1, tmp2, 16); /* denom in Q(scale1+scale2-16) */
/* Square the cross correlation and norm it such that max_perSquare
will be in Q15 after the division */
totscale = scale1+scale2-1;
tmp1 = (int16_t)WEBRTC_SPL_SHIFT_W32(cross, (totscale>>1));
tmp2 = (int16_t)WEBRTC_SPL_SHIFT_W32(cross, totscale-(totscale>>1));
nom = WEBRTC_SPL_MUL_16_16(tmp1, tmp2);
max_perSquare = (int16_t)WebRtcSpl_DivW32W16(nom, denom);
} else {
max_perSquare = 0;
}
}
/* previous frame lost, use recorded lag and gain */
else {
lag = iLBCdec_inst->prevLag;
max_perSquare = iLBCdec_inst->perSquare;
}
/* Attenuate signal and scale down pitch pred gain if
several frames lost consecutively */
use_gain = 32767; /* 1.0 in Q15 */
if (iLBCdec_inst->consPLICount*iLBCdec_inst->blockl>320) {
use_gain = 29491; /* 0.9 in Q15 */
} else if (iLBCdec_inst->consPLICount*iLBCdec_inst->blockl>640) {
use_gain = 22938; /* 0.7 in Q15 */
} else if (iLBCdec_inst->consPLICount*iLBCdec_inst->blockl>960) {
use_gain = 16384; /* 0.5 in Q15 */
} else if (iLBCdec_inst->consPLICount*iLBCdec_inst->blockl>1280) {
use_gain = 0; /* 0.0 in Q15 */
}
/* Compute mixing factor of picth repeatition and noise:
for max_per>0.7 set periodicity to 1.0
0.4<max_per<0.7 set periodicity to (maxper-0.4)/0.7-0.4)
max_per<0.4 set periodicity to 0.0
*/
if (max_perSquare>7868) { /* periodicity > 0.7 (0.7^4=0.2401 in Q15) */
pitchfact = 32767;
} else if (max_perSquare>839) { /* 0.4 < periodicity < 0.7 (0.4^4=0.0256 in Q15) */
/* find best index and interpolate from that */
ind = 5;
while ((max_perSquare<WebRtcIlbcfix_kPlcPerSqr[ind])&&(ind>0)) {
ind--;
}
/* pitch fact is approximated by first order */
tmpW32 = (int32_t)WebRtcIlbcfix_kPlcPitchFact[ind] +
WEBRTC_SPL_MUL_16_16_RSFT(WebRtcIlbcfix_kPlcPfSlope[ind], (max_perSquare-WebRtcIlbcfix_kPlcPerSqr[ind]), 11);
pitchfact = (int16_t)WEBRTC_SPL_MIN(tmpW32, 32767); /* guard against overflow */
} else { /* periodicity < 0.4 */
pitchfact = 0;
}
/* avoid repetition of same pitch cycle (buzzyness) */
use_lag = lag;
if (lag<80) {
use_lag = 2*lag;
}
/* compute concealed residual */
energy = 0;
for (i=0; i<iLBCdec_inst->blockl; i++) {
/* noise component - 52 < randlagFIX < 117 */
iLBCdec_inst->seed = (int16_t)(WEBRTC_SPL_MUL_16_16(iLBCdec_inst->seed, 31821)+(int32_t)13849);
randlag = 53 + (int16_t)(iLBCdec_inst->seed & 63);
pick = i - randlag;
if (pick < 0) {
randvec[i] = iLBCdec_inst->prevResidual[iLBCdec_inst->blockl+pick];
} else {
randvec[i] = iLBCdec_inst->prevResidual[pick];
}
/* pitch repeatition component */
pick = i - use_lag;
if (pick < 0) {
PLCresidual[i] = iLBCdec_inst->prevResidual[iLBCdec_inst->blockl+pick];
} else {
PLCresidual[i] = PLCresidual[pick];
}
/* Attinuate total gain for each 10 ms */
if (i<80) {
tot_gain=use_gain;
} else if (i<160) {
tot_gain=(int16_t)WEBRTC_SPL_MUL_16_16_RSFT(31130, use_gain, 15); /* 0.95*use_gain */
} else {
tot_gain=(int16_t)WEBRTC_SPL_MUL_16_16_RSFT(29491, use_gain, 15); /* 0.9*use_gain */
}
/* mix noise and pitch repeatition */
PLCresidual[i] = (int16_t)WEBRTC_SPL_MUL_16_16_RSFT(tot_gain,
(int16_t)WEBRTC_SPL_RSHIFT_W32( (WEBRTC_SPL_MUL_16_16(pitchfact, PLCresidual[i]) +
WEBRTC_SPL_MUL_16_16((32767-pitchfact), randvec[i]) + 16384),
15),
15);
/* Shifting down the result one step extra to ensure that no overflow
will occur */
energy += WEBRTC_SPL_MUL_16_16_RSFT(PLCresidual[i],
PLCresidual[i], (iLBCdec_inst->prevScale+1));
}
/* less than 30 dB, use only noise */
if (energy < (WEBRTC_SPL_SHIFT_W32(((int32_t)iLBCdec_inst->blockl*900),-(iLBCdec_inst->prevScale+1)))) {
energy = 0;
for (i=0; i<iLBCdec_inst->blockl; i++) {
PLCresidual[i] = randvec[i];
}
}
/* use the old LPC */
WEBRTC_SPL_MEMCPY_W16(PLClpc, (*iLBCdec_inst).prevLpc, LPC_FILTERORDER+1);
/* Update state in case there are multiple frame losses */
iLBCdec_inst->prevLag = lag;
iLBCdec_inst->perSquare = max_perSquare;
}
/* no packet loss, copy input */
else {
WEBRTC_SPL_MEMCPY_W16(PLCresidual, decresidual, iLBCdec_inst->blockl);
WEBRTC_SPL_MEMCPY_W16(PLClpc, lpc, (LPC_FILTERORDER+1));
iLBCdec_inst->consPLICount = 0;
}
/* update state */
iLBCdec_inst->prevPLI = PLI;
WEBRTC_SPL_MEMCPY_W16(iLBCdec_inst->prevLpc, PLClpc, (LPC_FILTERORDER+1));
WEBRTC_SPL_MEMCPY_W16(iLBCdec_inst->prevResidual, PLCresidual, iLBCdec_inst->blockl);
return;
}

View File

@@ -0,0 +1,41 @@
/*
* 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.
*/
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
WebRtcIlbcfix_DoThePlc.h
******************************************************************/
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_DO_PLC_H_
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_DO_PLC_H_
#include "defines.h"
/*----------------------------------------------------------------*
* Packet loss concealment routine. Conceals a residual signal
* and LP parameters. If no packet loss, update state.
*---------------------------------------------------------------*/
void WebRtcIlbcfix_DoThePlc(
int16_t *PLCresidual, /* (o) concealed residual */
int16_t *PLClpc, /* (o) concealed LP parameters */
int16_t PLI, /* (i) packet loss indicator
0 - no PL, 1 = PL */
int16_t *decresidual, /* (i) decoded residual */
int16_t *lpc, /* (i) decoded LPC (only used for no PL) */
int16_t inlag, /* (i) pitch lag */
iLBC_Dec_Inst_t *iLBCdec_inst
/* (i/o) decoder instance */
);
#endif

View File

@@ -0,0 +1,519 @@
/*
* 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.
*/
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
WebRtcIlbcfix_Encode.c
******************************************************************/
#include <string.h>
#include "defines.h"
#include "lpc_encode.h"
#include "frame_classify.h"
#include "state_search.h"
#include "state_construct.h"
#include "constants.h"
#include "cb_search.h"
#include "cb_construct.h"
#include "index_conv_enc.h"
#include "pack_bits.h"
#include "hp_input.h"
#ifdef SPLIT_10MS
#include "unpack_bits.h"
#include "index_conv_dec.h"
#endif
#ifndef WEBRTC_ARCH_BIG_ENDIAN
#include "swap_bytes.h"
#endif
/*----------------------------------------------------------------*
* main encoder function
*---------------------------------------------------------------*/
void WebRtcIlbcfix_EncodeImpl(
uint16_t *bytes, /* (o) encoded data bits iLBC */
const int16_t *block, /* (i) speech vector to encode */
iLBC_Enc_Inst_t *iLBCenc_inst /* (i/o) the general encoder
state */
){
int n, meml_gotten, Nfor, Nback;
int16_t diff, start_pos;
int index;
int subcount, subframe;
int16_t start_count, end_count;
int16_t *residual;
int32_t en1, en2;
int16_t scale, max;
int16_t *syntdenum;
int16_t *decresidual;
int16_t *reverseResidual;
int16_t *reverseDecresidual;
/* Stack based */
int16_t weightdenum[(LPC_FILTERORDER + 1)*NSUB_MAX];
int16_t dataVec[BLOCKL_MAX + LPC_FILTERORDER];
int16_t memVec[CB_MEML+CB_FILTERLEN];
int16_t bitsMemory[sizeof(iLBC_bits)/sizeof(int16_t)];
iLBC_bits *iLBCbits_inst = (iLBC_bits*)bitsMemory;
#ifdef SPLIT_10MS
int16_t *weightdenumbuf = iLBCenc_inst->weightdenumbuf;
int16_t last_bit;
#endif
int16_t *data = &dataVec[LPC_FILTERORDER];
int16_t *mem = &memVec[CB_HALFFILTERLEN];
/* Reuse som buffers to save stack memory */
residual = &iLBCenc_inst->lpc_buffer[LPC_LOOKBACK+BLOCKL_MAX-iLBCenc_inst->blockl];
syntdenum = mem; /* syntdenum[(LPC_FILTERORDER + 1)*NSUB_MAX] and mem are used non overlapping in the code */
decresidual = residual; /* Already encoded residual is overwritten by the decoded version */
reverseResidual = data; /* data and reverseResidual are used non overlapping in the code */
reverseDecresidual = reverseResidual; /* Already encoded residual is overwritten by the decoded version */
#ifdef SPLIT_10MS
WebRtcSpl_MemSetW16 ( (int16_t *) iLBCbits_inst, 0,
(int16_t) (sizeof(iLBC_bits) / sizeof(int16_t)) );
start_pos = iLBCenc_inst->start_pos;
diff = iLBCenc_inst->diff;
if (iLBCenc_inst->section != 0){
WEBRTC_SPL_MEMCPY_W16 (weightdenum, weightdenumbuf,
SCRATCH_ENCODE_DATAVEC - SCRATCH_ENCODE_WEIGHTDENUM);
/* Un-Packetize the frame into parameters */
last_bit = WebRtcIlbcfix_UnpackBits (iLBCenc_inst->bytes, iLBCbits_inst, iLBCenc_inst->mode);
if (last_bit)
return;
/* adjust index */
WebRtcIlbcfix_IndexConvDec (iLBCbits_inst->cb_index);
if (iLBCenc_inst->section == 1){
/* Save first 80 samples of a 160/240 sample frame for 20/30msec */
WEBRTC_SPL_MEMCPY_W16 (iLBCenc_inst->past_samples, block, 80);
}
else{ // iLBCenc_inst->section == 2 AND mode = 30ms
/* Save second 80 samples of a 240 sample frame for 30msec */
WEBRTC_SPL_MEMCPY_W16 (iLBCenc_inst->past_samples + 80, block, 80);
}
}
else{ // iLBCenc_inst->section == 0
/* form a complete frame of 160/240 for 20msec/30msec mode */
WEBRTC_SPL_MEMCPY_W16 (data + (iLBCenc_inst->mode * 8) - 80, block, 80);
WEBRTC_SPL_MEMCPY_W16 (data, iLBCenc_inst->past_samples,
(iLBCenc_inst->mode * 8) - 80);
iLBCenc_inst->Nfor_flag = 0;
iLBCenc_inst->Nback_flag = 0;
#else
/* copy input block to data*/
WEBRTC_SPL_MEMCPY_W16(data,block,iLBCenc_inst->blockl);
#endif
/* high pass filtering of input signal and scale down the residual (*0.5) */
WebRtcIlbcfix_HpInput(data, (int16_t*)WebRtcIlbcfix_kHpInCoefs,
iLBCenc_inst->hpimemy, iLBCenc_inst->hpimemx,
iLBCenc_inst->blockl);
/* LPC of hp filtered input data */
WebRtcIlbcfix_LpcEncode(syntdenum, weightdenum, iLBCbits_inst->lsf, data,
iLBCenc_inst);
/* Set up state */
WEBRTC_SPL_MEMCPY_W16(dataVec, iLBCenc_inst->anaMem, LPC_FILTERORDER);
/* inverse filter to get residual */
for (n=0; n<iLBCenc_inst->nsub; n++ ) {
WebRtcSpl_FilterMAFastQ12(
&data[n*SUBL], &residual[n*SUBL],
&syntdenum[n*(LPC_FILTERORDER+1)],
LPC_FILTERORDER+1, SUBL);
}
/* Copy the state for next frame */
WEBRTC_SPL_MEMCPY_W16(iLBCenc_inst->anaMem, &data[iLBCenc_inst->blockl-LPC_FILTERORDER], LPC_FILTERORDER);
/* find state location */
iLBCbits_inst->startIdx = WebRtcIlbcfix_FrameClassify(iLBCenc_inst,residual);
/* check if state should be in first or last part of the
two subframes */
index = (iLBCbits_inst->startIdx-1)*SUBL;
max=WebRtcSpl_MaxAbsValueW16(&residual[index], 2*SUBL);
scale=WebRtcSpl_GetSizeInBits(WEBRTC_SPL_MUL_16_16(max,max));
/* Scale to maximum 25 bits so that the MAC won't cause overflow */
scale = scale - 25;
if(scale < 0) {
scale = 0;
}
diff = STATE_LEN - iLBCenc_inst->state_short_len;
en1=WebRtcSpl_DotProductWithScale(&residual[index], &residual[index],
iLBCenc_inst->state_short_len, scale);
index += diff;
en2=WebRtcSpl_DotProductWithScale(&residual[index], &residual[index],
iLBCenc_inst->state_short_len, scale);
if (en1 > en2) {
iLBCbits_inst->state_first = 1;
start_pos = (iLBCbits_inst->startIdx-1)*SUBL;
} else {
iLBCbits_inst->state_first = 0;
start_pos = (iLBCbits_inst->startIdx-1)*SUBL + diff;
}
/* scalar quantization of state */
WebRtcIlbcfix_StateSearch(iLBCenc_inst, iLBCbits_inst, &residual[start_pos],
&syntdenum[(iLBCbits_inst->startIdx-1)*(LPC_FILTERORDER+1)],
&weightdenum[(iLBCbits_inst->startIdx-1)*(LPC_FILTERORDER+1)]);
WebRtcIlbcfix_StateConstruct(iLBCbits_inst->idxForMax, iLBCbits_inst->idxVec,
&syntdenum[(iLBCbits_inst->startIdx-1)*(LPC_FILTERORDER+1)],
&decresidual[start_pos], iLBCenc_inst->state_short_len
);
/* predictive quantization in state */
if (iLBCbits_inst->state_first) { /* put adaptive part in the end */
/* setup memory */
WebRtcSpl_MemSetW16(mem, 0, (int16_t)(CB_MEML-iLBCenc_inst->state_short_len));
WEBRTC_SPL_MEMCPY_W16(mem+CB_MEML-iLBCenc_inst->state_short_len,
decresidual+start_pos, iLBCenc_inst->state_short_len);
/* encode subframes */
WebRtcIlbcfix_CbSearch(iLBCenc_inst, iLBCbits_inst->cb_index, iLBCbits_inst->gain_index,
&residual[start_pos+iLBCenc_inst->state_short_len],
mem+CB_MEML-ST_MEM_L_TBL, ST_MEM_L_TBL, diff,
&weightdenum[iLBCbits_inst->startIdx*(LPC_FILTERORDER+1)], 0);
/* construct decoded vector */
WebRtcIlbcfix_CbConstruct(&decresidual[start_pos+iLBCenc_inst->state_short_len],
iLBCbits_inst->cb_index, iLBCbits_inst->gain_index,
mem+CB_MEML-ST_MEM_L_TBL, ST_MEM_L_TBL,
diff
);
}
else { /* put adaptive part in the beginning */
/* create reversed vectors for prediction */
WebRtcSpl_MemCpyReversedOrder(&reverseResidual[diff-1],
&residual[(iLBCbits_inst->startIdx+1)*SUBL-STATE_LEN], diff);
/* setup memory */
meml_gotten = iLBCenc_inst->state_short_len;
WebRtcSpl_MemCpyReversedOrder(&mem[CB_MEML-1], &decresidual[start_pos], meml_gotten);
WebRtcSpl_MemSetW16(mem, 0, (int16_t)(CB_MEML-iLBCenc_inst->state_short_len));
/* encode subframes */
WebRtcIlbcfix_CbSearch(iLBCenc_inst, iLBCbits_inst->cb_index, iLBCbits_inst->gain_index,
reverseResidual, mem+CB_MEML-ST_MEM_L_TBL, ST_MEM_L_TBL, diff,
&weightdenum[(iLBCbits_inst->startIdx-1)*(LPC_FILTERORDER+1)],
0);
/* construct decoded vector */
WebRtcIlbcfix_CbConstruct(reverseDecresidual,
iLBCbits_inst->cb_index, iLBCbits_inst->gain_index,
mem+CB_MEML-ST_MEM_L_TBL, ST_MEM_L_TBL,
diff
);
/* get decoded residual from reversed vector */
WebRtcSpl_MemCpyReversedOrder(&decresidual[start_pos-1], reverseDecresidual, diff);
}
#ifdef SPLIT_10MS
iLBCenc_inst->start_pos = start_pos;
iLBCenc_inst->diff = diff;
iLBCenc_inst->section++;
/* adjust index */
WebRtcIlbcfix_IndexConvEnc (iLBCbits_inst->cb_index);
/* Packetize the parameters into the frame */
WebRtcIlbcfix_PackBits (iLBCenc_inst->bytes, iLBCbits_inst, iLBCenc_inst->mode);
WEBRTC_SPL_MEMCPY_W16 (weightdenumbuf, weightdenum,
SCRATCH_ENCODE_DATAVEC - SCRATCH_ENCODE_WEIGHTDENUM);
return;
}
#endif
/* forward prediction of subframes */
Nfor = iLBCenc_inst->nsub-iLBCbits_inst->startIdx-1;
/* counter for predicted subframes */
#ifdef SPLIT_10MS
if (iLBCenc_inst->mode == 20)
{
subcount = 1;
}
if (iLBCenc_inst->mode == 30)
{
if (iLBCenc_inst->section == 1)
{
subcount = 1;
}
if (iLBCenc_inst->section == 2)
{
subcount = 3;
}
}
#else
subcount=1;
#endif
if( Nfor > 0 ){
/* setup memory */
WebRtcSpl_MemSetW16(mem, 0, CB_MEML-STATE_LEN);
WEBRTC_SPL_MEMCPY_W16(mem+CB_MEML-STATE_LEN,
decresidual+(iLBCbits_inst->startIdx-1)*SUBL, STATE_LEN);
#ifdef SPLIT_10MS
if (iLBCenc_inst->Nfor_flag > 0)
{
for (subframe = 0; subframe < WEBRTC_SPL_MIN (Nfor, 2); subframe++)
{
/* update memory */
WEBRTC_SPL_MEMCPY_W16 (mem, mem + SUBL, (CB_MEML - SUBL));
WEBRTC_SPL_MEMCPY_W16 (mem + CB_MEML - SUBL,
&decresidual[(iLBCbits_inst->startIdx + 1 +
subframe) * SUBL], SUBL);
}
}
iLBCenc_inst->Nfor_flag++;
if (iLBCenc_inst->mode == 20)
{
start_count = 0;
end_count = Nfor;
}
if (iLBCenc_inst->mode == 30)
{
if (iLBCenc_inst->section == 1)
{
start_count = 0;
end_count = WEBRTC_SPL_MIN (Nfor, 2);
}
if (iLBCenc_inst->section == 2)
{
start_count = WEBRTC_SPL_MIN (Nfor, 2);
end_count = Nfor;
}
}
#else
start_count = 0;
end_count = (int16_t)Nfor;
#endif
/* loop over subframes to encode */
for (subframe = start_count; subframe < end_count; subframe++){
/* encode subframe */
WebRtcIlbcfix_CbSearch(iLBCenc_inst, iLBCbits_inst->cb_index+subcount*CB_NSTAGES,
iLBCbits_inst->gain_index+subcount*CB_NSTAGES,
&residual[(iLBCbits_inst->startIdx+1+subframe)*SUBL],
mem, MEM_LF_TBL, SUBL,
&weightdenum[(iLBCbits_inst->startIdx+1+subframe)*(LPC_FILTERORDER+1)],
(int16_t)subcount);
/* construct decoded vector */
WebRtcIlbcfix_CbConstruct(&decresidual[(iLBCbits_inst->startIdx+1+subframe)*SUBL],
iLBCbits_inst->cb_index+subcount*CB_NSTAGES,
iLBCbits_inst->gain_index+subcount*CB_NSTAGES,
mem, MEM_LF_TBL,
SUBL
);
/* update memory */
memmove(mem, mem + SUBL, (CB_MEML - SUBL) * sizeof(*mem));
WEBRTC_SPL_MEMCPY_W16(mem+CB_MEML-SUBL,
&decresidual[(iLBCbits_inst->startIdx+1+subframe)*SUBL], SUBL);
subcount++;
}
}
#ifdef SPLIT_10MS
if ((iLBCenc_inst->section == 1) &&
(iLBCenc_inst->mode == 30) && (Nfor > 0) && (end_count == 2))
{
iLBCenc_inst->section++;
/* adjust index */
WebRtcIlbcfix_IndexConvEnc (iLBCbits_inst->cb_index);
/* Packetize the parameters into the frame */
WebRtcIlbcfix_PackBits (iLBCenc_inst->bytes, iLBCbits_inst, iLBCenc_inst->mode);
WEBRTC_SPL_MEMCPY_W16 (weightdenumbuf, weightdenum,
SCRATCH_ENCODE_DATAVEC - SCRATCH_ENCODE_WEIGHTDENUM);
return;
}
#endif
/* backward prediction of subframes */
Nback = iLBCbits_inst->startIdx-1;
if( Nback > 0 ){
/* create reverse order vectors
(The decresidual does not need to be copied since it is
contained in the same vector as the residual)
*/
WebRtcSpl_MemCpyReversedOrder(&reverseResidual[Nback*SUBL-1], residual, Nback*SUBL);
/* setup memory */
meml_gotten = SUBL*(iLBCenc_inst->nsub+1-iLBCbits_inst->startIdx);
if( meml_gotten > CB_MEML ) {
meml_gotten=CB_MEML;
}
WebRtcSpl_MemCpyReversedOrder(&mem[CB_MEML-1], &decresidual[Nback*SUBL], meml_gotten);
WebRtcSpl_MemSetW16(mem, 0, (int16_t)(CB_MEML-meml_gotten));
#ifdef SPLIT_10MS
if (iLBCenc_inst->Nback_flag > 0)
{
for (subframe = 0; subframe < WEBRTC_SPL_MAX (2 - Nfor, 0); subframe++)
{
/* update memory */
WEBRTC_SPL_MEMCPY_W16 (mem, mem + SUBL, (CB_MEML - SUBL));
WEBRTC_SPL_MEMCPY_W16 (mem + CB_MEML - SUBL,
&reverseDecresidual[subframe * SUBL], SUBL);
}
}
iLBCenc_inst->Nback_flag++;
if (iLBCenc_inst->mode == 20)
{
start_count = 0;
end_count = Nback;
}
if (iLBCenc_inst->mode == 30)
{
if (iLBCenc_inst->section == 1)
{
start_count = 0;
end_count = WEBRTC_SPL_MAX (2 - Nfor, 0);
}
if (iLBCenc_inst->section == 2)
{
start_count = WEBRTC_SPL_MAX (2 - Nfor, 0);
end_count = Nback;
}
}
#else
start_count = 0;
end_count = (int16_t)Nback;
#endif
/* loop over subframes to encode */
for (subframe = start_count; subframe < end_count; subframe++){
/* encode subframe */
WebRtcIlbcfix_CbSearch(iLBCenc_inst, iLBCbits_inst->cb_index+subcount*CB_NSTAGES,
iLBCbits_inst->gain_index+subcount*CB_NSTAGES, &reverseResidual[subframe*SUBL],
mem, MEM_LF_TBL, SUBL,
&weightdenum[(iLBCbits_inst->startIdx-2-subframe)*(LPC_FILTERORDER+1)],
(int16_t)subcount);
/* construct decoded vector */
WebRtcIlbcfix_CbConstruct(&reverseDecresidual[subframe*SUBL],
iLBCbits_inst->cb_index+subcount*CB_NSTAGES,
iLBCbits_inst->gain_index+subcount*CB_NSTAGES,
mem, MEM_LF_TBL, SUBL
);
/* update memory */
memmove(mem, mem + SUBL, (CB_MEML - SUBL) * sizeof(*mem));
WEBRTC_SPL_MEMCPY_W16(mem+CB_MEML-SUBL,
&reverseDecresidual[subframe*SUBL], SUBL);
subcount++;
}
/* get decoded residual from reversed vector */
WebRtcSpl_MemCpyReversedOrder(&decresidual[SUBL*Nback-1], reverseDecresidual, SUBL*Nback);
}
/* end encoding part */
/* adjust index */
WebRtcIlbcfix_IndexConvEnc(iLBCbits_inst->cb_index);
/* Packetize the parameters into the frame */
#ifdef SPLIT_10MS
if( (iLBCenc_inst->mode==30) && (iLBCenc_inst->section==1) ){
WebRtcIlbcfix_PackBits(iLBCenc_inst->bytes, iLBCbits_inst, iLBCenc_inst->mode);
}
else{
WebRtcIlbcfix_PackBits(bytes, iLBCbits_inst, iLBCenc_inst->mode);
}
#else
WebRtcIlbcfix_PackBits(bytes, iLBCbits_inst, iLBCenc_inst->mode);
#endif
#ifndef WEBRTC_ARCH_BIG_ENDIAN
/* Swap bytes for LITTLE ENDIAN since the packbits()
function assumes BIG_ENDIAN machine */
#ifdef SPLIT_10MS
if (( (iLBCenc_inst->section == 1) && (iLBCenc_inst->mode == 20) ) ||
( (iLBCenc_inst->section == 2) && (iLBCenc_inst->mode == 30) )){
WebRtcIlbcfix_SwapBytes(bytes, iLBCenc_inst->no_of_words, bytes);
}
#else
WebRtcIlbcfix_SwapBytes(bytes, iLBCenc_inst->no_of_words, bytes);
#endif
#endif
#ifdef SPLIT_10MS
if (subcount == (iLBCenc_inst->nsub - 1))
{
iLBCenc_inst->section = 0;
}
else
{
iLBCenc_inst->section++;
WEBRTC_SPL_MEMCPY_W16 (weightdenumbuf, weightdenum,
SCRATCH_ENCODE_DATAVEC - SCRATCH_ENCODE_WEIGHTDENUM);
}
#endif
}

View File

@@ -0,0 +1,35 @@
/*
* 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.
*/
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
WebRtcIlbcfix_Encode.h
******************************************************************/
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_ENCODE_H_
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_ENCODE_H_
#include "defines.h"
/*----------------------------------------------------------------*
* main encoder function
*---------------------------------------------------------------*/
void WebRtcIlbcfix_EncodeImpl(
uint16_t *bytes, /* (o) encoded data bits iLBC */
const int16_t *block, /* (i) speech vector to encode */
iLBC_Enc_Inst_t *iLBCenc_inst /* (i/o) the general encoder
state */
);
#endif

View File

@@ -0,0 +1,46 @@
/*
* 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.
*/
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
WebRtcIlbcfix_EnergyInverse.c
******************************************************************/
/* Inverses the in vector in into Q29 domain */
#include "energy_inverse.h"
void WebRtcIlbcfix_EnergyInverse(
int16_t *energy, /* (i/o) Energy and inverse
energy (in Q29) */
int noOfEnergies) /* (i) The length of the energy
vector */
{
int32_t Nom=(int32_t)0x1FFFFFFF;
int16_t *energyPtr;
int i;
/* Set the minimum energy value to 16384 to avoid overflow */
energyPtr=energy;
for (i=0; i<noOfEnergies; i++) {
(*energyPtr)=WEBRTC_SPL_MAX((*energyPtr),16384);
energyPtr++;
}
/* Calculate inverse energy in Q29 */
energyPtr=energy;
for (i=0; i<noOfEnergies; i++) {
(*energyPtr) = (int16_t)WebRtcSpl_DivW32W16(Nom, (*energyPtr));
energyPtr++;
}
}

View File

@@ -0,0 +1,32 @@
/*
* 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.
*/
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
WebRtcIlbcfix_EnergyInverse.h
******************************************************************/
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_ENERGY_INVERSE_H_
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_ENERGY_INVERSE_H_
#include "defines.h"
/* Inverses the in vector in into Q29 domain */
void WebRtcIlbcfix_EnergyInverse(
int16_t *energy, /* (i/o) Energy and inverse
energy (in Q29) */
int noOfEnergies); /* (i) The length of the energy
vector */
#endif

View File

@@ -0,0 +1,110 @@
/*
* 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.
*/
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
WebRtcIlbcfix_EnhUpsample.c
******************************************************************/
#include "defines.h"
#include "constants.h"
/*----------------------------------------------------------------*
* upsample finite array assuming zeros outside bounds
*---------------------------------------------------------------*/
void WebRtcIlbcfix_EnhUpsample(
int32_t *useq1, /* (o) upsampled output sequence */
int16_t *seq1 /* (i) unupsampled sequence */
){
int j;
int32_t *pu1, *pu11;
int16_t *ps, *w16tmp;
const int16_t *pp;
/* filtering: filter overhangs left side of sequence */
pu1=useq1;
for (j=0;j<ENH_UPS0; j++) {
pu11=pu1;
/* i = 2 */
pp=WebRtcIlbcfix_kEnhPolyPhaser[j]+1;
ps=seq1+2;
(*pu11) = WEBRTC_SPL_MUL_16_16(*ps--,*pp++);
(*pu11) += WEBRTC_SPL_MUL_16_16(*ps--,*pp++);
(*pu11) += WEBRTC_SPL_MUL_16_16(*ps--,*pp++);
pu11+=ENH_UPS0;
/* i = 3 */
pp=WebRtcIlbcfix_kEnhPolyPhaser[j]+1;
ps=seq1+3;
(*pu11) = WEBRTC_SPL_MUL_16_16(*ps--,*pp++);
(*pu11) += WEBRTC_SPL_MUL_16_16(*ps--,*pp++);
(*pu11) += WEBRTC_SPL_MUL_16_16(*ps--,*pp++);
(*pu11) += WEBRTC_SPL_MUL_16_16(*ps--,*pp++);
pu11+=ENH_UPS0;
/* i = 4 */
pp=WebRtcIlbcfix_kEnhPolyPhaser[j]+1;
ps=seq1+4;
(*pu11) = WEBRTC_SPL_MUL_16_16(*ps--,*pp++);
(*pu11) += WEBRTC_SPL_MUL_16_16(*ps--,*pp++);
(*pu11) += WEBRTC_SPL_MUL_16_16(*ps--,*pp++);
(*pu11) += WEBRTC_SPL_MUL_16_16(*ps--,*pp++);
(*pu11) += WEBRTC_SPL_MUL_16_16(*ps--,*pp++);
pu1++;
}
/* filtering: simple convolution=inner products
(not needed since the sequence is so short)
*/
/* filtering: filter overhangs right side of sequence */
/* Code with loops, which is equivivalent to the expanded version below
filterlength = 5;
hf1 = 2;
for(j=0;j<ENH_UPS0; j++){
pu = useq1 + (filterlength-hfl)*ENH_UPS0 + j;
for(i=1; i<=hfl; i++){
*pu=0;
pp = polyp[j]+i;
ps = seq1+dim1-1;
for(k=0;k<filterlength-i;k++) {
*pu += WEBRTC_SPL_MUL_16_16(*ps--, *pp++);
}
pu+=ENH_UPS0;
}
}
*/
pu1 = useq1 + 12;
w16tmp = seq1+4;
for (j=0;j<ENH_UPS0; j++) {
pu11 = pu1;
/* i = 1 */
pp = WebRtcIlbcfix_kEnhPolyPhaser[j]+2;
ps = w16tmp;
(*pu11) = WEBRTC_SPL_MUL_16_16(*ps--, *pp++);
(*pu11) += WEBRTC_SPL_MUL_16_16(*ps--, *pp++);
(*pu11) += WEBRTC_SPL_MUL_16_16(*ps--, *pp++);
(*pu11) += WEBRTC_SPL_MUL_16_16(*ps--, *pp++);
pu11+=ENH_UPS0;
/* i = 2 */
pp = WebRtcIlbcfix_kEnhPolyPhaser[j]+3;
ps = w16tmp;
(*pu11) = WEBRTC_SPL_MUL_16_16(*ps--, *pp++);
(*pu11) += WEBRTC_SPL_MUL_16_16(*ps--, *pp++);
(*pu11) += WEBRTC_SPL_MUL_16_16(*ps--, *pp++);
pu11+=ENH_UPS0;
pu1++;
}
}

View File

@@ -0,0 +1,33 @@
/*
* 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.
*/
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
WebRtcIlbcfix_EnhUpsample.h
******************************************************************/
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_ENH_UPSAMPLE_H_
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_ENH_UPSAMPLE_H_
#include "defines.h"
/*----------------------------------------------------------------*
* upsample finite array assuming zeros outside bounds
*---------------------------------------------------------------*/
void WebRtcIlbcfix_EnhUpsample(
int32_t *useq1, /* (o) upsampled output sequence */
int16_t *seq1 /* (i) unupsampled sequence */
);
#endif

View File

@@ -0,0 +1,51 @@
/*
* 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.
*/
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
WebRtcIlbcfix_Enhancer.c
******************************************************************/
#include "defines.h"
#include "constants.h"
#include "get_sync_seq.h"
#include "smooth.h"
/*----------------------------------------------------------------*
* perform enhancement on idata+centerStartPos through
* idata+centerStartPos+ENH_BLOCKL-1
*---------------------------------------------------------------*/
void WebRtcIlbcfix_Enhancer(
int16_t *odata, /* (o) smoothed block, dimension blockl */
int16_t *idata, /* (i) data buffer used for enhancing */
int16_t idatal, /* (i) dimension idata */
int16_t centerStartPos, /* (i) first sample current block within idata */
int16_t *period, /* (i) pitch period array (pitch bward-in time) */
int16_t *plocs, /* (i) locations where period array values valid */
int16_t periodl /* (i) dimension of period and plocs */
){
/* Stack based */
int16_t surround[ENH_BLOCKL];
WebRtcSpl_MemSetW16(surround, 0, ENH_BLOCKL);
/* get said second sequence of segments */
WebRtcIlbcfix_GetSyncSeq(idata, idatal, centerStartPos, period, plocs,
periodl, ENH_HL, surround);
/* compute the smoothed output from said second sequence */
WebRtcIlbcfix_Smooth(odata, idata+centerStartPos, surround);
}

View File

@@ -0,0 +1,39 @@
/*
* 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.
*/
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
WebRtcIlbcfix_Enhancer.h
******************************************************************/
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_ENHANCER_H_
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_ENHANCER_H_
#include "defines.h"
/*----------------------------------------------------------------*
* perform enhancement on idata+centerStartPos through
* idata+centerStartPos+ENH_BLOCKL-1
*---------------------------------------------------------------*/
void WebRtcIlbcfix_Enhancer(
int16_t *odata, /* (o) smoothed block, dimension blockl */
int16_t *idata, /* (i) data buffer used for enhancing */
int16_t idatal, /* (i) dimension idata */
int16_t centerStartPos, /* (i) first sample current block within idata */
int16_t *period, /* (i) pitch period array (pitch bward-in time) */
int16_t *plocs, /* (i) locations where period array values valid */
int16_t periodl /* (i) dimension of period and plocs */
);
#endif

View File

@@ -0,0 +1,382 @@
/*
* 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.
*/
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
WebRtcIlbcfix_EnhancerInterface.c
******************************************************************/
#include <string.h>
#include "defines.h"
#include "constants.h"
#include "xcorr_coef.h"
#include "enhancer.h"
#include "hp_output.h"
/*----------------------------------------------------------------*
* interface for enhancer
*---------------------------------------------------------------*/
int WebRtcIlbcfix_EnhancerInterface( /* (o) Estimated lag in end of in[] */
int16_t *out, /* (o) enhanced signal */
int16_t *in, /* (i) unenhanced signal */
iLBC_Dec_Inst_t *iLBCdec_inst /* (i) buffers etc */
){
int iblock;
int lag=20, tlag=20;
int inLen=iLBCdec_inst->blockl+120;
int16_t scale, scale1, plc_blockl;
int16_t *enh_buf, *enh_period;
int32_t tmp1, tmp2, max, new_blocks;
int16_t *enh_bufPtr1;
int i, k;
int16_t EnChange;
int16_t SqrtEnChange;
int16_t inc;
int16_t win;
int16_t *tmpW16ptr;
int16_t startPos;
int16_t *plc_pred;
int16_t *target, *regressor;
int16_t max16;
int shifts;
int32_t ener;
int16_t enerSh;
int16_t corrSh;
int16_t ind, sh;
int16_t start, stop;
/* Stack based */
int16_t totsh[3];
int16_t downsampled[(BLOCKL_MAX+120)>>1]; /* length 180 */
int32_t corr32[50];
int32_t corrmax[3];
int16_t corr16[3];
int16_t en16[3];
int16_t lagmax[3];
plc_pred = downsampled; /* Reuse memory since plc_pred[ENH_BLOCKL] and
downsampled are non overlapping */
enh_buf=iLBCdec_inst->enh_buf;
enh_period=iLBCdec_inst->enh_period;
/* Copy in the new data into the enhancer buffer */
memmove(enh_buf, &enh_buf[iLBCdec_inst->blockl],
(ENH_BUFL - iLBCdec_inst->blockl) * sizeof(*enh_buf));
WEBRTC_SPL_MEMCPY_W16(&enh_buf[ENH_BUFL-iLBCdec_inst->blockl], in,
iLBCdec_inst->blockl);
/* Set variables that are dependent on frame size */
if (iLBCdec_inst->mode==30) {
plc_blockl=ENH_BLOCKL;
new_blocks=3;
startPos=320; /* Start position for enhancement
(640-new_blocks*ENH_BLOCKL-80) */
} else {
plc_blockl=40;
new_blocks=2;
startPos=440; /* Start position for enhancement
(640-new_blocks*ENH_BLOCKL-40) */
}
/* Update the pitch prediction for each enhancer block, move the old ones */
memmove(enh_period, &enh_period[new_blocks],
(ENH_NBLOCKS_TOT - new_blocks) * sizeof(*enh_period));
k=WebRtcSpl_DownsampleFast(
enh_buf+ENH_BUFL-inLen, /* Input samples */
(int16_t)(inLen+ENH_BUFL_FILTEROVERHEAD),
downsampled,
(int16_t)WEBRTC_SPL_RSHIFT_W16(inLen, 1),
(int16_t*)WebRtcIlbcfix_kLpFiltCoefs, /* Coefficients in Q12 */
FILTERORDER_DS_PLUS1, /* Length of filter (order-1) */
FACTOR_DS,
DELAY_DS);
/* Estimate the pitch in the down sampled domain. */
for(iblock = 0; iblock<new_blocks; iblock++){
/* references */
i=60+WEBRTC_SPL_MUL_16_16(iblock,ENH_BLOCKL_HALF);
target=downsampled+i;
regressor=downsampled+i-10;
/* scaling */
max16=WebRtcSpl_MaxAbsValueW16(&regressor[-50],
(int16_t)(ENH_BLOCKL_HALF+50-1));
shifts = WebRtcSpl_GetSizeInBits(WEBRTC_SPL_MUL_16_16(max16, max16)) - 25;
shifts = WEBRTC_SPL_MAX(0, shifts);
/* compute cross correlation */
WebRtcSpl_CrossCorrelation(corr32, target, regressor,
ENH_BLOCKL_HALF, 50, (int16_t)shifts, -1);
/* Find 3 highest correlations that should be compared for the
highest (corr*corr)/ener */
for (i=0;i<2;i++) {
lagmax[i] = WebRtcSpl_MaxIndexW32(corr32, 50);
corrmax[i] = corr32[lagmax[i]];
start = lagmax[i] - 2;
stop = lagmax[i] + 2;
start = WEBRTC_SPL_MAX(0, start);
stop = WEBRTC_SPL_MIN(49, stop);
for (k=start; k<=stop; k++) {
corr32[k] = 0;
}
}
lagmax[2] = WebRtcSpl_MaxIndexW32(corr32, 50);
corrmax[2] = corr32[lagmax[2]];
/* Calculate normalized corr^2 and ener */
for (i=0;i<3;i++) {
corrSh = 15-WebRtcSpl_GetSizeInBits(corrmax[i]);
ener = WebRtcSpl_DotProductWithScale(&regressor[-lagmax[i]],
&regressor[-lagmax[i]],
ENH_BLOCKL_HALF, shifts);
enerSh = 15-WebRtcSpl_GetSizeInBits(ener);
corr16[i] = (int16_t)WEBRTC_SPL_SHIFT_W32(corrmax[i], corrSh);
corr16[i] = (int16_t)WEBRTC_SPL_MUL_16_16_RSFT(corr16[i],
corr16[i], 16);
en16[i] = (int16_t)WEBRTC_SPL_SHIFT_W32(ener, enerSh);
totsh[i] = enerSh - WEBRTC_SPL_LSHIFT_W32(corrSh, 1);
}
/* Compare lagmax[0..3] for the (corr^2)/ener criteria */
ind = 0;
for (i=1; i<3; i++) {
if (totsh[ind] > totsh[i]) {
sh = WEBRTC_SPL_MIN(31, totsh[ind]-totsh[i]);
if ( WEBRTC_SPL_MUL_16_16(corr16[ind], en16[i]) <
WEBRTC_SPL_MUL_16_16_RSFT(corr16[i], en16[ind], sh)) {
ind = i;
}
} else {
sh = WEBRTC_SPL_MIN(31, totsh[i]-totsh[ind]);
if (WEBRTC_SPL_MUL_16_16_RSFT(corr16[ind], en16[i], sh) <
WEBRTC_SPL_MUL_16_16(corr16[i], en16[ind])) {
ind = i;
}
}
}
lag = lagmax[ind] + 10;
/* Store the estimated lag in the non-downsampled domain */
enh_period[ENH_NBLOCKS_TOT-new_blocks+iblock] =
(int16_t)WEBRTC_SPL_MUL_16_16(lag, 8);
/* Store the estimated lag for backward PLC */
if (iLBCdec_inst->prev_enh_pl==1) {
if (!iblock) {
tlag = WEBRTC_SPL_MUL_16_16(lag, 2);
}
} else {
if (iblock==1) {
tlag = WEBRTC_SPL_MUL_16_16(lag, 2);
}
}
lag = WEBRTC_SPL_MUL_16_16(lag, 2);
}
if ((iLBCdec_inst->prev_enh_pl==1)||(iLBCdec_inst->prev_enh_pl==2)) {
/* Calculate the best lag of the new frame
This is used to interpolate backwards and mix with the PLC'd data
*/
/* references */
target=in;
regressor=in+tlag-1;
/* scaling */
max16=WebRtcSpl_MaxAbsValueW16(regressor, (int16_t)(plc_blockl+3-1));
if (max16>5000)
shifts=2;
else
shifts=0;
/* compute cross correlation */
WebRtcSpl_CrossCorrelation(corr32, target, regressor,
plc_blockl, 3, (int16_t)shifts, 1);
/* find lag */
lag=WebRtcSpl_MaxIndexW32(corr32, 3);
lag+=tlag-1;
/* Copy the backward PLC to plc_pred */
if (iLBCdec_inst->prev_enh_pl==1) {
if (lag>plc_blockl) {
WEBRTC_SPL_MEMCPY_W16(plc_pred, &in[lag-plc_blockl], plc_blockl);
} else {
WEBRTC_SPL_MEMCPY_W16(&plc_pred[plc_blockl-lag], in, lag);
WEBRTC_SPL_MEMCPY_W16(
plc_pred, &enh_buf[ENH_BUFL-iLBCdec_inst->blockl-plc_blockl+lag],
(plc_blockl-lag));
}
} else {
int pos;
pos = plc_blockl;
while (lag<pos) {
WEBRTC_SPL_MEMCPY_W16(&plc_pred[pos-lag], in, lag);
pos = pos - lag;
}
WEBRTC_SPL_MEMCPY_W16(plc_pred, &in[lag-pos], pos);
}
if (iLBCdec_inst->prev_enh_pl==1) {
/* limit energy change
if energy in backward PLC is more than 4 times higher than the forward
PLC, then reduce the energy in the backward PLC vector:
sample 1...len-16 set energy of the to 4 times forward PLC
sample len-15..len interpolate between 4 times fw PLC and bw PLC energy
Note: Compared to floating point code there is a slight change,
the window is 16 samples long instead of 10 samples to simplify the
calculations
*/
max=WebRtcSpl_MaxAbsValueW16(
&enh_buf[ENH_BUFL-iLBCdec_inst->blockl-plc_blockl], plc_blockl);
max16=WebRtcSpl_MaxAbsValueW16(plc_pred, plc_blockl);
max = WEBRTC_SPL_MAX(max, max16);
scale=22-(int16_t)WebRtcSpl_NormW32(max);
scale=WEBRTC_SPL_MAX(scale,0);
tmp2 = WebRtcSpl_DotProductWithScale(
&enh_buf[ENH_BUFL-iLBCdec_inst->blockl-plc_blockl],
&enh_buf[ENH_BUFL-iLBCdec_inst->blockl-plc_blockl],
plc_blockl, scale);
tmp1 = WebRtcSpl_DotProductWithScale(plc_pred, plc_pred,
plc_blockl, scale);
/* Check the energy difference */
if ((tmp1>0)&&((tmp1>>2)>tmp2)) {
/* EnChange is now guaranteed to be <0.5
Calculate EnChange=tmp2/tmp1 in Q16
*/
scale1=(int16_t)WebRtcSpl_NormW32(tmp1);
tmp1=WEBRTC_SPL_SHIFT_W32(tmp1, (scale1-16)); /* using 15 bits */
tmp2=WEBRTC_SPL_SHIFT_W32(tmp2, (scale1));
EnChange = (int16_t)WebRtcSpl_DivW32W16(tmp2,
(int16_t)tmp1);
/* Calculate the Sqrt of the energy in Q15 ((14+16)/2) */
SqrtEnChange = (int16_t)WebRtcSpl_SqrtFloor(
WEBRTC_SPL_LSHIFT_W32((int32_t)EnChange, 14));
/* Multiply first part of vector with 2*SqrtEnChange */
WebRtcSpl_ScaleVector(plc_pred, plc_pred, SqrtEnChange,
(int16_t)(plc_blockl-16), 14);
/* Calculate increase parameter for window part (16 last samples) */
/* (1-2*SqrtEnChange)/16 in Q15 */
inc=(2048-WEBRTC_SPL_RSHIFT_W16(SqrtEnChange, 3));
win=0;
tmpW16ptr=&plc_pred[plc_blockl-16];
for (i=16;i>0;i--) {
(*tmpW16ptr)=(int16_t)WEBRTC_SPL_MUL_16_16_RSFT(
(*tmpW16ptr), (SqrtEnChange+(win>>1)), 14);
/* multiply by (2.0*SqrtEnChange+win) */
win += inc;
tmpW16ptr++;
}
}
/* Make the linear interpolation between the forward PLC'd data
and the backward PLC'd data (from the new frame)
*/
if (plc_blockl==40) {
inc=400; /* 1/41 in Q14 */
} else { /* plc_blockl==80 */
inc=202; /* 1/81 in Q14 */
}
win=0;
enh_bufPtr1=&enh_buf[ENH_BUFL-1-iLBCdec_inst->blockl];
for (i=0; i<plc_blockl; i++) {
win+=inc;
*enh_bufPtr1 =
(int16_t)WEBRTC_SPL_MUL_16_16_RSFT((*enh_bufPtr1), win, 14);
*enh_bufPtr1 += (int16_t)WEBRTC_SPL_MUL_16_16_RSFT(
(16384-win), plc_pred[plc_blockl-1-i], 14);
enh_bufPtr1--;
}
} else {
int16_t *synt = &downsampled[LPC_FILTERORDER];
enh_bufPtr1=&enh_buf[ENH_BUFL-iLBCdec_inst->blockl-plc_blockl];
WEBRTC_SPL_MEMCPY_W16(enh_bufPtr1, plc_pred, plc_blockl);
/* Clear fileter memory */
WebRtcSpl_MemSetW16(iLBCdec_inst->syntMem, 0, LPC_FILTERORDER);
WebRtcSpl_MemSetW16(iLBCdec_inst->hpimemy, 0, 4);
WebRtcSpl_MemSetW16(iLBCdec_inst->hpimemx, 0, 2);
/* Initialize filter memory by filtering through 2 lags */
WEBRTC_SPL_MEMCPY_W16(&synt[-LPC_FILTERORDER], iLBCdec_inst->syntMem,
LPC_FILTERORDER);
WebRtcSpl_FilterARFastQ12(
enh_bufPtr1,
synt,
&iLBCdec_inst->old_syntdenum[
(iLBCdec_inst->nsub-1)*(LPC_FILTERORDER+1)],
LPC_FILTERORDER+1, (int16_t)lag);
WEBRTC_SPL_MEMCPY_W16(&synt[-LPC_FILTERORDER], &synt[lag-LPC_FILTERORDER],
LPC_FILTERORDER);
WebRtcIlbcfix_HpOutput(synt, (int16_t*)WebRtcIlbcfix_kHpOutCoefs,
iLBCdec_inst->hpimemy, iLBCdec_inst->hpimemx,
(int16_t)lag);
WebRtcSpl_FilterARFastQ12(
enh_bufPtr1, synt,
&iLBCdec_inst->old_syntdenum[
(iLBCdec_inst->nsub-1)*(LPC_FILTERORDER+1)],
LPC_FILTERORDER+1, (int16_t)lag);
WEBRTC_SPL_MEMCPY_W16(iLBCdec_inst->syntMem, &synt[lag-LPC_FILTERORDER],
LPC_FILTERORDER);
WebRtcIlbcfix_HpOutput(synt, (int16_t*)WebRtcIlbcfix_kHpOutCoefs,
iLBCdec_inst->hpimemy, iLBCdec_inst->hpimemx,
(int16_t)lag);
}
}
/* Perform enhancement block by block */
for (iblock = 0; iblock<new_blocks; iblock++) {
WebRtcIlbcfix_Enhancer(out+WEBRTC_SPL_MUL_16_16(iblock, ENH_BLOCKL),
enh_buf,
ENH_BUFL,
(int16_t)(WEBRTC_SPL_MUL_16_16(iblock, ENH_BLOCKL)+startPos),
enh_period,
(int16_t*)WebRtcIlbcfix_kEnhPlocs, ENH_NBLOCKS_TOT);
}
return (lag);
}

View File

@@ -0,0 +1,34 @@
/*
* 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.
*/
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
WebRtcIlbcfix_EnhancerInterface.h
******************************************************************/
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_ENHANCER_INTERFACE_H_
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_ENHANCER_INTERFACE_H_
#include "defines.h"
/*----------------------------------------------------------------*
* interface for enhancer
*---------------------------------------------------------------*/
int WebRtcIlbcfix_EnhancerInterface( /* (o) Estimated lag in end of in[] */
int16_t *out, /* (o) enhanced signal */
int16_t *in, /* (i) unenhanced signal */
iLBC_Dec_Inst_t *iLBCdec_inst /* (i) buffers etc */
);
#endif

View File

@@ -0,0 +1,48 @@
/*
* 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.
*/
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
WebRtcIlbcfix_FilteredCbVecs.c
******************************************************************/
#include "defines.h"
#include "constants.h"
/*----------------------------------------------------------------*
* Construct an additional codebook vector by filtering the
* initial codebook buffer. This vector is then used to expand
* the codebook with an additional section.
*---------------------------------------------------------------*/
void WebRtcIlbcfix_FilteredCbVecs(
int16_t *cbvectors, /* (o) Codebook vector for the higher section */
int16_t *CBmem, /* (i) Codebook memory that is filtered to create a
second CB section */
int lMem, /* (i) Length of codebook memory */
int16_t samples /* (i) Number of samples to filter */
) {
/* Set up the memory, start with zero state */
WebRtcSpl_MemSetW16(CBmem+lMem, 0, CB_HALFFILTERLEN);
WebRtcSpl_MemSetW16(CBmem-CB_HALFFILTERLEN, 0, CB_HALFFILTERLEN);
WebRtcSpl_MemSetW16(cbvectors, 0, lMem-samples);
/* Filter to obtain the filtered CB memory */
WebRtcSpl_FilterMAFastQ12(
CBmem+CB_HALFFILTERLEN+lMem-samples, cbvectors+lMem-samples,
(int16_t*)WebRtcIlbcfix_kCbFiltersRev, CB_FILTERLEN, samples);
return;
}

View File

@@ -0,0 +1,38 @@
/*
* 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.
*/
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
WebRtcIlbcfix_FilteredCbVecs.h
******************************************************************/
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_FILTERED_CB_VECS_H_
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_FILTERED_CB_VECS_H_
#include "defines.h"
/*----------------------------------------------------------------*
* Construct an additional codebook vector by filtering the
* initial codebook buffer. This vector is then used to expand
* the codebook with an additional section.
*---------------------------------------------------------------*/
void WebRtcIlbcfix_FilteredCbVecs(
int16_t *cbvectors, /* (o) Codebook vector for the higher section */
int16_t *CBmem, /* (i) Codebook memory that is filtered to create a
second CB section */
int lMem, /* (i) Length of codebook memory */
int16_t samples /* (i) Number of samples to filter */
);
#endif

View File

@@ -0,0 +1,88 @@
/*
* 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.
*/
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
WebRtcIlbcfix_FrameClassify.c
******************************************************************/
#include "defines.h"
#include "constants.h"
/*----------------------------------------------------------------*
* Classification of subframes to localize start state
*---------------------------------------------------------------*/
int16_t WebRtcIlbcfix_FrameClassify(
/* (o) Index to the max-energy sub frame */
iLBC_Enc_Inst_t *iLBCenc_inst,
/* (i/o) the encoder state structure */
int16_t *residualFIX /* (i) lpc residual signal */
){
int16_t max, scale;
int32_t ssqEn[NSUB_MAX-1];
int16_t *ssqPtr;
int32_t *seqEnPtr;
int32_t maxW32;
int16_t scale1;
int16_t pos;
int n;
/*
Calculate the energy of each of the 80 sample blocks
in the draft the 4 first and last samples are windowed with 1/5...4/5
and 4/5...1/5 respectively. To simplify for the fixpoint we have changed
this to 0 0 1 1 and 1 1 0 0
*/
max = WebRtcSpl_MaxAbsValueW16(residualFIX, iLBCenc_inst->blockl);
scale=WebRtcSpl_GetSizeInBits(WEBRTC_SPL_MUL_16_16(max,max));
/* Scale to maximum 24 bits so that it won't overflow for 76 samples */
scale = scale-24;
scale1 = WEBRTC_SPL_MAX(0, scale);
/* Calculate energies */
ssqPtr=residualFIX + 2;
seqEnPtr=ssqEn;
for (n=(iLBCenc_inst->nsub-1); n>0; n--) {
(*seqEnPtr) = WebRtcSpl_DotProductWithScale(ssqPtr, ssqPtr, 76, scale1);
ssqPtr += 40;
seqEnPtr++;
}
/* Scale to maximum 20 bits in order to allow for the 11 bit window */
maxW32 = WebRtcSpl_MaxValueW32(ssqEn, (int16_t)(iLBCenc_inst->nsub-1));
scale = WebRtcSpl_GetSizeInBits(maxW32) - 20;
scale1 = WEBRTC_SPL_MAX(0, scale);
/* Window each 80 block with the ssqEn_winTbl window to give higher probability for
the blocks in the middle
*/
seqEnPtr=ssqEn;
if (iLBCenc_inst->mode==20) {
ssqPtr=(int16_t*)WebRtcIlbcfix_kStartSequenceEnrgWin+1;
} else {
ssqPtr=(int16_t*)WebRtcIlbcfix_kStartSequenceEnrgWin;
}
for (n=(iLBCenc_inst->nsub-1); n>0; n--) {
(*seqEnPtr)=WEBRTC_SPL_MUL(((*seqEnPtr)>>scale1), (*ssqPtr));
seqEnPtr++;
ssqPtr++;
}
/* Extract the best choise of start state */
pos = WebRtcSpl_MaxIndexW32(ssqEn, (int16_t)(iLBCenc_inst->nsub-1)) + 1;
return(pos);
}

View File

@@ -0,0 +1,29 @@
/*
* 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.
*/
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
WebRtcIlbcfix_FrameClassify.h
******************************************************************/
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_FRAME_CLASSIFY_H_
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_FRAME_CLASSIFY_H_
int16_t WebRtcIlbcfix_FrameClassify(
/* (o) Index to the max-energy sub frame */
iLBC_Enc_Inst_t *iLBCenc_inst,
/* (i/o) the encoder state structure */
int16_t *residualFIX /* (i) lpc residual signal */
);
#endif

View File

@@ -0,0 +1,45 @@
/*
* 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.
*/
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
WebRtcIlbcfix_GainDequant.c
******************************************************************/
#include "defines.h"
#include "constants.h"
/*----------------------------------------------------------------*
* decoder for quantized gains in the gain-shape coding of
* residual
*---------------------------------------------------------------*/
int16_t WebRtcIlbcfix_GainDequant(
/* (o) quantized gain value (Q14) */
int16_t index, /* (i) quantization index */
int16_t maxIn, /* (i) maximum of unquantized gain (Q14) */
int16_t stage /* (i) The stage of the search */
){
int16_t scale;
const int16_t *gain;
/* obtain correct scale factor */
scale=WEBRTC_SPL_ABS_W16(maxIn);
scale = WEBRTC_SPL_MAX(1638, scale); /* if lower than 0.1, set it to 0.1 */
/* select the quantization table and return the decoded value */
gain = WebRtcIlbcfix_kGain[stage];
return((int16_t)((WEBRTC_SPL_MUL_16_16(scale, gain[index])+8192)>>14));
}

View File

@@ -0,0 +1,36 @@
/*
* 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.
*/
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
WebRtcIlbcfix_GainDequant.h
******************************************************************/
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_GAIN_DEQUANT_H_
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_GAIN_DEQUANT_H_
#include "defines.h"
/*----------------------------------------------------------------*
* decoder for quantized gains in the gain-shape coding of
* residual
*---------------------------------------------------------------*/
int16_t WebRtcIlbcfix_GainDequant(
/* (o) quantized gain value (Q14) */
int16_t index, /* (i) quantization index */
int16_t maxIn, /* (i) maximum of unquantized gain (Q14) */
int16_t stage /* (i) The stage of the search */
);
#endif

View File

@@ -0,0 +1,106 @@
/*
* 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.
*/
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
WebRtcIlbcfix_GainQuant.c
******************************************************************/
#include "defines.h"
#include "constants.h"
/*----------------------------------------------------------------*
* quantizer for the gain in the gain-shape coding of residual
*---------------------------------------------------------------*/
int16_t WebRtcIlbcfix_GainQuant( /* (o) quantized gain value */
int16_t gain, /* (i) gain value Q14 */
int16_t maxIn, /* (i) maximum of gain value Q14 */
int16_t stage, /* (i) The stage of the search */
int16_t *index /* (o) quantization index */
) {
int16_t scale, returnVal, cblen;
int32_t gainW32, measure1, measure2;
const int16_t *cbPtr, *cb;
int loc, noMoves, noChecks, i;
/* ensure a lower bound (0.1) on the scaling factor */
scale = WEBRTC_SPL_MAX(1638, maxIn);
/* select the quantization table and calculate
the length of the table and the number of
steps in the binary search that are needed */
cb = WebRtcIlbcfix_kGain[stage];
cblen = 32>>stage;
noChecks = 4-stage;
/* Multiply the gain with 2^14 to make the comparison
easier and with higher precision */
gainW32 = WEBRTC_SPL_LSHIFT_W32((int32_t)gain, 14);
/* Do a binary search, starting in the middle of the CB
loc - defines the current position in the table
noMoves - defines the number of steps to move in the CB in order
to get next CB location
*/
loc = cblen>>1;
noMoves = loc;
cbPtr = cb + loc; /* Centre of CB */
for (i=noChecks;i>0;i--) {
noMoves>>=1;
measure1=WEBRTC_SPL_MUL_16_16(scale, (*cbPtr));
/* Move up if gain is larger, otherwise move down in table */
measure1 = measure1 - gainW32;
if (0>measure1) {
cbPtr+=noMoves;
loc+=noMoves;
} else {
cbPtr-=noMoves;
loc-=noMoves;
}
}
/* Check which value is the closest one: loc-1, loc or loc+1 */
measure1=WEBRTC_SPL_MUL_16_16(scale, (*cbPtr));
if (gainW32>measure1) {
/* Check against value above loc */
measure2=WEBRTC_SPL_MUL_16_16(scale, (*(cbPtr+1)));
if ((measure2-gainW32)<(gainW32-measure1)) {
loc+=1;
}
} else {
/* Check against value below loc */
measure2=WEBRTC_SPL_MUL_16_16(scale, (*(cbPtr-1)));
if ((gainW32-measure2)<=(measure1-gainW32)) {
loc-=1;
}
}
/* Guard against getting outside the table. The calculation above can give a location
which is one above the maximum value (in very rare cases) */
loc=WEBRTC_SPL_MIN(loc, (cblen-1));
*index=loc;
/* Calculate the quantized gain value (in Q14) */
returnVal=(int16_t)((WEBRTC_SPL_MUL_16_16(scale, cb[loc])+8192)>>14);
/* return the quantized value */
return(returnVal);
}

View File

@@ -0,0 +1,35 @@
/*
* 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.
*/
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
WebRtcIlbcfix_GainQuant.h
******************************************************************/
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_GAIN_QUANT_H_
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_GAIN_QUANT_H_
#include "defines.h"
/*----------------------------------------------------------------*
* quantizer for the gain in the gain-shape coding of residual
*---------------------------------------------------------------*/
int16_t WebRtcIlbcfix_GainQuant( /* (o) quantized gain value */
int16_t gain, /* (i) gain value Q14 */
int16_t maxIn, /* (i) maximum of gain value Q14 */
int16_t stage, /* (i) The stage of the search */
int16_t *index /* (o) quantization index */
);
#endif

View File

@@ -0,0 +1,111 @@
/*
* 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.
*/
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
WebRtcIlbcfix_GetCbVec.c
******************************************************************/
#include "defines.h"
#include "constants.h"
#include "create_augmented_vec.h"
/*----------------------------------------------------------------*
* Construct codebook vector for given index.
*---------------------------------------------------------------*/
void WebRtcIlbcfix_GetCbVec(
int16_t *cbvec, /* (o) Constructed codebook vector */
int16_t *mem, /* (i) Codebook buffer */
int16_t index, /* (i) Codebook index */
int16_t lMem, /* (i) Length of codebook buffer */
int16_t cbveclen /* (i) Codebook vector length */
){
int16_t k, base_size;
int16_t lag;
/* Stack based */
int16_t tempbuff2[SUBL+5];
/* Determine size of codebook sections */
base_size=lMem-cbveclen+1;
if (cbveclen==SUBL) {
base_size+=WEBRTC_SPL_RSHIFT_W16(cbveclen,1);
}
/* No filter -> First codebook section */
if (index<lMem-cbveclen+1) {
/* first non-interpolated vectors */
k=index+cbveclen;
/* get vector */
WEBRTC_SPL_MEMCPY_W16(cbvec, mem+lMem-k, cbveclen);
} else if (index < base_size) {
/* Calculate lag */
k=(int16_t)WEBRTC_SPL_MUL_16_16(2, (index-(lMem-cbveclen+1)))+cbveclen;
lag=WEBRTC_SPL_RSHIFT_W16(k, 1);
WebRtcIlbcfix_CreateAugmentedVec(lag, mem+lMem, cbvec);
}
/* Higher codebbok section based on filtering */
else {
int16_t memIndTest;
/* first non-interpolated vectors */
if (index-base_size<lMem-cbveclen+1) {
/* Set up filter memory, stuff zeros outside memory buffer */
memIndTest = lMem-(index-base_size+cbveclen);
WebRtcSpl_MemSetW16(mem-CB_HALFFILTERLEN, 0, CB_HALFFILTERLEN);
WebRtcSpl_MemSetW16(mem+lMem, 0, CB_HALFFILTERLEN);
/* do filtering to get the codebook vector */
WebRtcSpl_FilterMAFastQ12(
&mem[memIndTest+4], cbvec, (int16_t*)WebRtcIlbcfix_kCbFiltersRev,
CB_FILTERLEN, cbveclen);
}
/* interpolated vectors */
else {
/* Stuff zeros outside memory buffer */
memIndTest = lMem-cbveclen-CB_FILTERLEN;
WebRtcSpl_MemSetW16(mem+lMem, 0, CB_HALFFILTERLEN);
/* do filtering */
WebRtcSpl_FilterMAFastQ12(
&mem[memIndTest+7], tempbuff2, (int16_t*)WebRtcIlbcfix_kCbFiltersRev,
CB_FILTERLEN, (int16_t)(cbveclen+5));
/* Calculate lag index */
lag = (cbveclen<<1)-20+index-base_size-lMem-1;
WebRtcIlbcfix_CreateAugmentedVec(lag, tempbuff2+SUBL+5, cbvec);
}
}
}

View File

@@ -0,0 +1,30 @@
/*
* 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.
*/
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
WebRtcIlbcfix_GetCbVec.h
******************************************************************/
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_GET_CD_VEC_H_
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_GET_CD_VEC_H_
void WebRtcIlbcfix_GetCbVec(
int16_t *cbvec, /* (o) Constructed codebook vector */
int16_t *mem, /* (i) Codebook buffer */
int16_t index, /* (i) Codebook index */
int16_t lMem, /* (i) Length of codebook buffer */
int16_t cbveclen /* (i) Codebook vector length */
);
#endif

View File

@@ -0,0 +1,83 @@
/*
* 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.
*/
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
WebRtcIlbcfix_GetLspPoly.c
******************************************************************/
#include "defines.h"
/*----------------------------------------------------------------*
* Construct the polynomials F1(z) and F2(z) from the LSP
* (Computations are done in Q24)
*
* The expansion is performed using the following recursion:
*
* f[0] = 1;
* tmp = -2.0 * lsp[0];
* f[1] = tmp;
* for (i=2; i<=5; i++) {
* b = -2.0 * lsp[2*i-2];
* f[i] = tmp*f[i-1] + 2.0*f[i-2];
* for (j=i; j>=2; j--) {
* f[j] = f[j] + tmp*f[j-1] + f[j-2];
* }
* f[i] = f[i] + tmp;
* }
*---------------------------------------------------------------*/
void WebRtcIlbcfix_GetLspPoly(
int16_t *lsp, /* (i) LSP in Q15 */
int32_t *f) /* (o) polonymial in Q24 */
{
int32_t tmpW32;
int i, j;
int16_t high, low;
int16_t *lspPtr;
int32_t *fPtr;
lspPtr = lsp;
fPtr = f;
/* f[0] = 1.0 (Q24) */
(*fPtr) = (int32_t)16777216;
fPtr++;
(*fPtr) = WEBRTC_SPL_MUL((*lspPtr), -1024);
fPtr++;
lspPtr+=2;
for(i=2; i<=5; i++)
{
(*fPtr) = fPtr[-2];
for(j=i; j>1; j--)
{
/* Compute f[j] = f[j] + tmp*f[j-1] + f[j-2]; */
high = (int16_t)WEBRTC_SPL_RSHIFT_W32(fPtr[-1], 16);
low = (int16_t)WEBRTC_SPL_RSHIFT_W32(fPtr[-1]-WEBRTC_SPL_LSHIFT_W32(((int32_t)high),16), 1);
tmpW32 = WEBRTC_SPL_LSHIFT_W32(WEBRTC_SPL_MUL_16_16(high, (*lspPtr)), 2) +
WEBRTC_SPL_LSHIFT_W32(WEBRTC_SPL_MUL_16_16_RSFT(low, (*lspPtr), 15), 2);
(*fPtr) += fPtr[-2];
(*fPtr) -= tmpW32;
fPtr--;
}
(*fPtr) -= (int32_t)WEBRTC_SPL_LSHIFT_W32((int32_t)(*lspPtr), 10);
fPtr+=i;
lspPtr+=2;
}
return;
}

View File

@@ -0,0 +1,47 @@
/*
* 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.
*/
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
WebRtcIlbcfix_GetLspPoly.h
******************************************************************/
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_GET_LSP_POLY_H_
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_GET_LSP_POLY_H_
#include "defines.h"
/*----------------------------------------------------------------*
* Construct the polynomials F1(z) and F2(z) from the LSP
* (Computations are done in Q24)
*
* The expansion is performed using the following recursion:
*
* f[0] = 1;
* tmp = -2.0 * lsp[0];
* f[1] = tmp;
* for (i=2; i<=5; i++) {
* b = -2.0 * lsp[2*i-2];
* f[i] = tmp*f[i-1] + 2.0*f[i-2];
* for (j=i; j>=2; j--) {
* f[j] = f[j] + tmp*f[j-1] + f[j-2];
* }
* f[i] = f[i] + tmp;
* }
*---------------------------------------------------------------*/
void WebRtcIlbcfix_GetLspPoly(
int16_t *lsp, /* (i) LSP in Q15 */
int32_t *f); /* (o) polonymial in Q24 */
#endif

View File

@@ -0,0 +1,108 @@
/*
* 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.
*/
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
WebRtcIlbcfix_GetSyncSeq.c
******************************************************************/
#include "defines.h"
#include "constants.h"
#include "refiner.h"
#include "nearest_neighbor.h"
/*----------------------------------------------------------------*
* get the pitch-synchronous sample sequence
*---------------------------------------------------------------*/
void WebRtcIlbcfix_GetSyncSeq(
int16_t *idata, /* (i) original data */
int16_t idatal, /* (i) dimension of data */
int16_t centerStartPos, /* (i) where current block starts */
int16_t *period, /* (i) rough-pitch-period array (Q-2) */
int16_t *plocs, /* (i) where periods of period array are taken (Q-2) */
int16_t periodl, /* (i) dimension period array */
int16_t hl, /* (i) 2*hl+1 is the number of sequences */
int16_t *surround /* (i/o) The contribution from this sequence
summed with earlier contributions */
){
int16_t i,centerEndPos,q;
/* Stack based */
int16_t lagBlock[2*ENH_HL+1];
int16_t blockStartPos[2*ENH_HL+1]; /* Defines the position to search around (Q2) */
int16_t plocs2[ENH_PLOCSL];
centerEndPos=centerStartPos+ENH_BLOCKL-1;
/* present (find predicted lag from this position) */
WebRtcIlbcfix_NearestNeighbor(lagBlock+hl,plocs,
(int16_t)WEBRTC_SPL_MUL_16_16(2, (centerStartPos+centerEndPos)),
periodl);
blockStartPos[hl]=(int16_t)WEBRTC_SPL_MUL_16_16(4, centerStartPos);
/* past (find predicted position and perform a refined
search to find the best sequence) */
for(q=hl-1;q>=0;q--) {
blockStartPos[q]=blockStartPos[q+1]-period[lagBlock[q+1]];
WebRtcIlbcfix_NearestNeighbor(lagBlock+q, plocs,
(int16_t)(blockStartPos[q] + (int16_t)WEBRTC_SPL_MUL_16_16(4, ENH_BLOCKL_HALF)-period[lagBlock[q+1]]),
periodl);
if((blockStartPos[q]-(int16_t)WEBRTC_SPL_MUL_16_16(4, ENH_OVERHANG))>=0) {
/* Find the best possible sequence in the 4 times upsampled
domain around blockStartPos+q */
WebRtcIlbcfix_Refiner(blockStartPos+q,idata,idatal,
centerStartPos,blockStartPos[q],surround,WebRtcIlbcfix_kEnhWt[q]);
} else {
/* Don't add anything since this sequence would
be outside the buffer */
}
}
/* future (find predicted position and perform a refined
search to find the best sequence) */
for(i=0;i<periodl;i++) {
plocs2[i]=(plocs[i]-period[i]);
}
for(q=hl+1;q<=WEBRTC_SPL_MUL_16_16(2, hl);q++) {
WebRtcIlbcfix_NearestNeighbor(lagBlock+q,plocs2,
(int16_t)(blockStartPos[q-1]+
(int16_t)WEBRTC_SPL_MUL_16_16(4, ENH_BLOCKL_HALF)),periodl);
blockStartPos[q]=blockStartPos[q-1]+period[lagBlock[q]];
if( (blockStartPos[q]+(int16_t)WEBRTC_SPL_MUL_16_16(4, (ENH_BLOCKL+ENH_OVERHANG)))
<
(int16_t)WEBRTC_SPL_MUL_16_16(4, idatal)) {
/* Find the best possible sequence in the 4 times upsampled
domain around blockStartPos+q */
WebRtcIlbcfix_Refiner(blockStartPos+q, idata, idatal,
centerStartPos,blockStartPos[q],surround,WebRtcIlbcfix_kEnhWt[2*hl-q]);
}
else {
/* Don't add anything since this sequence would
be outside the buffer */
}
}
}

View File

@@ -0,0 +1,40 @@
/*
* 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.
*/
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
WebRtcIlbcfix_GetSyncSeq.h
******************************************************************/
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_GET_SYNC_SEQ_H_
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_GET_SYNC_SEQ_H_
#include "defines.h"
/*----------------------------------------------------------------*
* get the pitch-synchronous sample sequence
*---------------------------------------------------------------*/
void WebRtcIlbcfix_GetSyncSeq(
int16_t *idata, /* (i) original data */
int16_t idatal, /* (i) dimension of data */
int16_t centerStartPos, /* (i) where current block starts */
int16_t *period, /* (i) rough-pitch-period array (Q-2) */
int16_t *plocs, /* (i) where periods of period array are taken (Q-2) */
int16_t periodl, /* (i) dimension period array */
int16_t hl, /* (i) 2*hl+1 is the number of sequences */
int16_t *surround /* (i/o) The contribution from this sequence
summed with earlier contributions */
);
#endif

View File

@@ -0,0 +1,88 @@
/*
* 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.
*/
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
WebRtcIlbcfix_HpInput.c
******************************************************************/
#include "defines.h"
/*----------------------------------------------------------------*
* high-pass filter of input with *0.5 and saturation
*---------------------------------------------------------------*/
void WebRtcIlbcfix_HpInput(
int16_t *signal, /* (i/o) signal vector */
int16_t *ba, /* (i) B- and A-coefficients (2:nd order)
{b[0] b[1] b[2] -a[1] -a[2]} a[0]
is assumed to be 1.0 */
int16_t *y, /* (i/o) Filter state yhi[n-1] ylow[n-1]
yhi[n-2] ylow[n-2] */
int16_t *x, /* (i/o) Filter state x[n-1] x[n-2] */
int16_t len) /* (i) Number of samples to filter */
{
int i;
int32_t tmpW32;
int32_t tmpW32b;
for (i=0; i<len; i++) {
/*
y[i] = b[0]*x[i] + b[1]*x[i-1] + b[2]*x[i-2]
+ (-a[1])*y[i-1] + (-a[2])*y[i-2];
*/
tmpW32 = WEBRTC_SPL_MUL_16_16(y[1], ba[3]); /* (-a[1])*y[i-1] (low part) */
tmpW32 += WEBRTC_SPL_MUL_16_16(y[3], ba[4]); /* (-a[2])*y[i-2] (low part) */
tmpW32 = (tmpW32>>15);
tmpW32 += WEBRTC_SPL_MUL_16_16(y[0], ba[3]); /* (-a[1])*y[i-1] (high part) */
tmpW32 += WEBRTC_SPL_MUL_16_16(y[2], ba[4]); /* (-a[2])*y[i-2] (high part) */
tmpW32 = (tmpW32<<1);
tmpW32 += WEBRTC_SPL_MUL_16_16(signal[i], ba[0]); /* b[0]*x[0] */
tmpW32 += WEBRTC_SPL_MUL_16_16(x[0], ba[1]); /* b[1]*x[i-1] */
tmpW32 += WEBRTC_SPL_MUL_16_16(x[1], ba[2]); /* b[2]*x[i-2] */
/* Update state (input part) */
x[1] = x[0];
x[0] = signal[i];
/* Rounding in Q(12+1), i.e. add 2^12 */
tmpW32b = tmpW32 + 4096;
/* Saturate (to 2^28) so that the HP filtered signal does not overflow */
tmpW32b = WEBRTC_SPL_SAT((int32_t)268435455, tmpW32b, (int32_t)-268435456);
/* Convert back to Q0 and multiply with 0.5 */
signal[i] = (int16_t)WEBRTC_SPL_RSHIFT_W32(tmpW32b, 13);
/* Update state (filtered part) */
y[2] = y[0];
y[3] = y[1];
/* upshift tmpW32 by 3 with saturation */
if (tmpW32>268435455) {
tmpW32 = WEBRTC_SPL_WORD32_MAX;
} else if (tmpW32<-268435456) {
tmpW32 = WEBRTC_SPL_WORD32_MIN;
} else {
tmpW32 = WEBRTC_SPL_LSHIFT_W32(tmpW32, 3);
}
y[0] = (int16_t)(tmpW32 >> 16);
y[1] = (int16_t)((tmpW32 - WEBRTC_SPL_LSHIFT_W32((int32_t)y[0], 16))>>1);
}
return;
}

View File

@@ -0,0 +1,34 @@
/*
* 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.
*/
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
WebRtcIlbcfix_HpInput.h
******************************************************************/
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_HP_INPUT_H_
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_HP_INPUT_H_
#include "defines.h"
void WebRtcIlbcfix_HpInput(
int16_t *signal, /* (i/o) signal vector */
int16_t *ba, /* (i) B- and A-coefficients (2:nd order)
{b[0] b[1] b[2] -a[1] -a[2]} a[0]
is assumed to be 1.0 */
int16_t *y, /* (i/o) Filter state yhi[n-1] ylow[n-1]
yhi[n-2] ylow[n-2] */
int16_t *x, /* (i/o) Filter state x[n-1] x[n-2] */
int16_t len); /* (i) Number of samples to filter */
#endif

View File

@@ -0,0 +1,89 @@
/*
* 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.
*/
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
WebRtcIlbcfix_HpOutput.c
******************************************************************/
#include "defines.h"
/*----------------------------------------------------------------*
* high-pass filter of output and *2 with saturation
*---------------------------------------------------------------*/
void WebRtcIlbcfix_HpOutput(
int16_t *signal, /* (i/o) signal vector */
int16_t *ba, /* (i) B- and A-coefficients (2:nd order)
{b[0] b[1] b[2] -a[1] -a[2]} a[0]
is assumed to be 1.0 */
int16_t *y, /* (i/o) Filter state yhi[n-1] ylow[n-1]
yhi[n-2] ylow[n-2] */
int16_t *x, /* (i/o) Filter state x[n-1] x[n-2] */
int16_t len) /* (i) Number of samples to filter */
{
int i;
int32_t tmpW32;
int32_t tmpW32b;
for (i=0; i<len; i++) {
/*
y[i] = b[0]*x[i] + b[1]*x[i-1] + b[2]*x[i-2]
+ (-a[1])*y[i-1] + (-a[2])*y[i-2];
*/
tmpW32 = WEBRTC_SPL_MUL_16_16(y[1], ba[3]); /* (-a[1])*y[i-1] (low part) */
tmpW32 += WEBRTC_SPL_MUL_16_16(y[3], ba[4]); /* (-a[2])*y[i-2] (low part) */
tmpW32 = (tmpW32>>15);
tmpW32 += WEBRTC_SPL_MUL_16_16(y[0], ba[3]); /* (-a[1])*y[i-1] (high part) */
tmpW32 += WEBRTC_SPL_MUL_16_16(y[2], ba[4]); /* (-a[2])*y[i-2] (high part) */
tmpW32 = (tmpW32<<1);
tmpW32 += WEBRTC_SPL_MUL_16_16(signal[i], ba[0]); /* b[0]*x[0] */
tmpW32 += WEBRTC_SPL_MUL_16_16(x[0], ba[1]); /* b[1]*x[i-1] */
tmpW32 += WEBRTC_SPL_MUL_16_16(x[1], ba[2]); /* b[2]*x[i-2] */
/* Update state (input part) */
x[1] = x[0];
x[0] = signal[i];
/* Rounding in Q(12-1), i.e. add 2^10 */
tmpW32b = tmpW32 + 1024;
/* Saturate (to 2^26) so that the HP filtered signal does not overflow */
tmpW32b = WEBRTC_SPL_SAT((int32_t)67108863, tmpW32b, (int32_t)-67108864);
/* Convert back to Q0 and multiply with 2 */
signal[i] = (int16_t)WEBRTC_SPL_RSHIFT_W32(tmpW32b, 11);
/* Update state (filtered part) */
y[2] = y[0];
y[3] = y[1];
/* upshift tmpW32 by 3 with saturation */
if (tmpW32>268435455) {
tmpW32 = WEBRTC_SPL_WORD32_MAX;
} else if (tmpW32<-268435456) {
tmpW32 = WEBRTC_SPL_WORD32_MIN;
} else {
tmpW32 = WEBRTC_SPL_LSHIFT_W32(tmpW32, 3);
}
y[0] = (int16_t)(tmpW32 >> 16);
y[1] = (int16_t)((tmpW32 - WEBRTC_SPL_LSHIFT_W32((int32_t)y[0], 16))>>1);
}
return;
}

View File

@@ -0,0 +1,34 @@
/*
* 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.
*/
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
WebRtcIlbcfix_HpOutput.h
******************************************************************/
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_HP_OUTPUT_H_
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_HP_OUTPUT_H_
#include "defines.h"
void WebRtcIlbcfix_HpOutput(
int16_t *signal, /* (i/o) signal vector */
int16_t *ba, /* (i) B- and A-coefficients (2:nd order)
{b[0] b[1] b[2] -a[1] -a[2]} a[0]
is assumed to be 1.0 */
int16_t *y, /* (i/o) Filter state yhi[n-1] ylow[n-1]
yhi[n-2] ylow[n-2] */
int16_t *x, /* (i/o) Filter state x[n-1] x[n-2] */
int16_t len); /* (i) Number of samples to filter */
#endif

View File

@@ -0,0 +1,257 @@
/*
* 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.
*/
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
iLBCInterface.c
******************************************************************/
#include "ilbc.h"
#include "defines.h"
#include "init_encode.h"
#include "encode.h"
#include "init_decode.h"
#include "decode.h"
#include <stdlib.h>
int16_t WebRtcIlbcfix_EncoderAssign(iLBC_encinst_t **iLBC_encinst, int16_t *ILBCENC_inst_Addr, int16_t *size) {
*iLBC_encinst=(iLBC_encinst_t*)ILBCENC_inst_Addr;
*size=sizeof(iLBC_Enc_Inst_t)/sizeof(int16_t);
if (*iLBC_encinst!=NULL) {
return(0);
} else {
return(-1);
}
}
int16_t WebRtcIlbcfix_DecoderAssign(iLBC_decinst_t **iLBC_decinst, int16_t *ILBCDEC_inst_Addr, int16_t *size) {
*iLBC_decinst=(iLBC_decinst_t*)ILBCDEC_inst_Addr;
*size=sizeof(iLBC_Dec_Inst_t)/sizeof(int16_t);
if (*iLBC_decinst!=NULL) {
return(0);
} else {
return(-1);
}
}
int16_t WebRtcIlbcfix_EncoderCreate(iLBC_encinst_t **iLBC_encinst) {
*iLBC_encinst=(iLBC_encinst_t*)malloc(sizeof(iLBC_Enc_Inst_t));
if (*iLBC_encinst!=NULL) {
WebRtcSpl_Init();
return(0);
} else {
return(-1);
}
}
int16_t WebRtcIlbcfix_DecoderCreate(iLBC_decinst_t **iLBC_decinst) {
*iLBC_decinst=(iLBC_decinst_t*)malloc(sizeof(iLBC_Dec_Inst_t));
if (*iLBC_decinst!=NULL) {
WebRtcSpl_Init();
return(0);
} else {
return(-1);
}
}
int16_t WebRtcIlbcfix_EncoderFree(iLBC_encinst_t *iLBC_encinst) {
free(iLBC_encinst);
return(0);
}
int16_t WebRtcIlbcfix_DecoderFree(iLBC_decinst_t *iLBC_decinst) {
free(iLBC_decinst);
return(0);
}
int16_t WebRtcIlbcfix_EncoderInit(iLBC_encinst_t *iLBCenc_inst, int16_t mode)
{
if ((mode==20)||(mode==30)) {
WebRtcIlbcfix_InitEncode((iLBC_Enc_Inst_t*) iLBCenc_inst, mode);
return(0);
} else {
return(-1);
}
}
int16_t WebRtcIlbcfix_Encode(iLBC_encinst_t *iLBCenc_inst, const int16_t *speechIn, int16_t len, int16_t *encoded) {
int16_t pos = 0;
int16_t encpos = 0;
if ((len != ((iLBC_Enc_Inst_t*)iLBCenc_inst)->blockl) &&
#ifdef SPLIT_10MS
(len != 80) &&
#endif
(len != 2*((iLBC_Enc_Inst_t*)iLBCenc_inst)->blockl) &&
(len != 3*((iLBC_Enc_Inst_t*)iLBCenc_inst)->blockl))
{
/* A maximum of 3 frames/packet is allowed */
return(-1);
} else {
/* call encoder */
while (pos<len) {
WebRtcIlbcfix_EncodeImpl((uint16_t*) &encoded[encpos], &speechIn[pos], (iLBC_Enc_Inst_t*) iLBCenc_inst);
#ifdef SPLIT_10MS
pos += 80;
if(((iLBC_Enc_Inst_t*)iLBCenc_inst)->section == 0)
#else
pos += ((iLBC_Enc_Inst_t*)iLBCenc_inst)->blockl;
#endif
encpos += ((iLBC_Enc_Inst_t*)iLBCenc_inst)->no_of_words;
}
return (encpos*2);
}
}
int16_t WebRtcIlbcfix_DecoderInit(iLBC_decinst_t *iLBCdec_inst, int16_t mode) {
if ((mode==20)||(mode==30)) {
WebRtcIlbcfix_InitDecode((iLBC_Dec_Inst_t*) iLBCdec_inst, mode, 1);
return(0);
} else {
return(-1);
}
}
int16_t WebRtcIlbcfix_DecoderInit20Ms(iLBC_decinst_t *iLBCdec_inst) {
WebRtcIlbcfix_InitDecode((iLBC_Dec_Inst_t*) iLBCdec_inst, 20, 1);
return(0);
}
int16_t WebRtcIlbcfix_Decoderinit30Ms(iLBC_decinst_t *iLBCdec_inst) {
WebRtcIlbcfix_InitDecode((iLBC_Dec_Inst_t*) iLBCdec_inst, 30, 1);
return(0);
}
int16_t WebRtcIlbcfix_Decode(iLBC_decinst_t *iLBCdec_inst,
const int16_t *encoded,
int16_t len,
int16_t *decoded,
int16_t *speechType)
{
int i=0;
/* Allow for automatic switching between the frame sizes
(although you do get some discontinuity) */
if ((len==((iLBC_Dec_Inst_t*)iLBCdec_inst)->no_of_bytes)||
(len==2*((iLBC_Dec_Inst_t*)iLBCdec_inst)->no_of_bytes)||
(len==3*((iLBC_Dec_Inst_t*)iLBCdec_inst)->no_of_bytes)) {
/* ok, do nothing */
} else {
/* Test if the mode has changed */
if (((iLBC_Dec_Inst_t*)iLBCdec_inst)->mode==20) {
if ((len==NO_OF_BYTES_30MS)||
(len==2*NO_OF_BYTES_30MS)||
(len==3*NO_OF_BYTES_30MS)) {
WebRtcIlbcfix_InitDecode(((iLBC_Dec_Inst_t*)iLBCdec_inst), 30, ((iLBC_Dec_Inst_t*)iLBCdec_inst)->use_enhancer);
} else {
/* Unsupported frame length */
return(-1);
}
} else {
if ((len==NO_OF_BYTES_20MS)||
(len==2*NO_OF_BYTES_20MS)||
(len==3*NO_OF_BYTES_20MS)) {
WebRtcIlbcfix_InitDecode(((iLBC_Dec_Inst_t*)iLBCdec_inst), 20, ((iLBC_Dec_Inst_t*)iLBCdec_inst)->use_enhancer);
} else {
/* Unsupported frame length */
return(-1);
}
}
}
while ((i*((iLBC_Dec_Inst_t*)iLBCdec_inst)->no_of_bytes)<len) {
WebRtcIlbcfix_DecodeImpl(&decoded[i*((iLBC_Dec_Inst_t*)iLBCdec_inst)->blockl], (const uint16_t*) &encoded[i*((iLBC_Dec_Inst_t*)iLBCdec_inst)->no_of_words], (iLBC_Dec_Inst_t*) iLBCdec_inst, 1);
i++;
}
/* iLBC does not support VAD/CNG yet */
*speechType=1;
return(i*((iLBC_Dec_Inst_t*)iLBCdec_inst)->blockl);
}
int16_t WebRtcIlbcfix_Decode20Ms(iLBC_decinst_t *iLBCdec_inst,
const int16_t *encoded,
int16_t len,
int16_t *decoded,
int16_t *speechType)
{
int i=0;
if ((len==((iLBC_Dec_Inst_t*)iLBCdec_inst)->no_of_bytes)||
(len==2*((iLBC_Dec_Inst_t*)iLBCdec_inst)->no_of_bytes)||
(len==3*((iLBC_Dec_Inst_t*)iLBCdec_inst)->no_of_bytes)) {
/* ok, do nothing */
} else {
return(-1);
}
while ((i*((iLBC_Dec_Inst_t*)iLBCdec_inst)->no_of_bytes)<len) {
WebRtcIlbcfix_DecodeImpl(&decoded[i*((iLBC_Dec_Inst_t*)iLBCdec_inst)->blockl], (const uint16_t*) &encoded[i*((iLBC_Dec_Inst_t*)iLBCdec_inst)->no_of_words], (iLBC_Dec_Inst_t*) iLBCdec_inst, 1);
i++;
}
/* iLBC does not support VAD/CNG yet */
*speechType=1;
return(i*((iLBC_Dec_Inst_t*)iLBCdec_inst)->blockl);
}
int16_t WebRtcIlbcfix_Decode30Ms(iLBC_decinst_t *iLBCdec_inst,
const int16_t *encoded,
int16_t len,
int16_t *decoded,
int16_t *speechType)
{
int i=0;
if ((len==((iLBC_Dec_Inst_t*)iLBCdec_inst)->no_of_bytes)||
(len==2*((iLBC_Dec_Inst_t*)iLBCdec_inst)->no_of_bytes)||
(len==3*((iLBC_Dec_Inst_t*)iLBCdec_inst)->no_of_bytes)) {
/* ok, do nothing */
} else {
return(-1);
}
while ((i*((iLBC_Dec_Inst_t*)iLBCdec_inst)->no_of_bytes)<len) {
WebRtcIlbcfix_DecodeImpl(&decoded[i*((iLBC_Dec_Inst_t*)iLBCdec_inst)->blockl], (const uint16_t*) &encoded[i*((iLBC_Dec_Inst_t*)iLBCdec_inst)->no_of_words], (iLBC_Dec_Inst_t*) iLBCdec_inst, 1);
i++;
}
/* iLBC does not support VAD/CNG yet */
*speechType=1;
return(i*((iLBC_Dec_Inst_t*)iLBCdec_inst)->blockl);
}
int16_t WebRtcIlbcfix_DecodePlc(iLBC_decinst_t *iLBCdec_inst, int16_t *decoded, int16_t noOfLostFrames) {
int i;
uint16_t dummy;
for (i=0;i<noOfLostFrames;i++) {
/* call decoder */
WebRtcIlbcfix_DecodeImpl(&decoded[i*((iLBC_Dec_Inst_t*)iLBCdec_inst)->blockl], &dummy, (iLBC_Dec_Inst_t*) iLBCdec_inst, 0);
}
return (noOfLostFrames*((iLBC_Dec_Inst_t*)iLBCdec_inst)->blockl);
}
int16_t WebRtcIlbcfix_NetEqPlc(iLBC_decinst_t *iLBCdec_inst, int16_t *decoded, int16_t noOfLostFrames) {
/* Two input parameters not used, but needed for function pointers in NetEQ */
(void)(decoded = NULL);
(void)(noOfLostFrames = 0);
WebRtcSpl_MemSetW16(((iLBC_Dec_Inst_t*)iLBCdec_inst)->enh_buf, 0, ENH_BUFL);
((iLBC_Dec_Inst_t*)iLBCdec_inst)->prev_enh_pl = 2;
return (0);
}
void WebRtcIlbcfix_version(char *version)
{
strcpy((char*)version, "1.1.1");
}

View File

@@ -0,0 +1,186 @@
# 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.
{
'targets': [
{
'target_name': 'iLBC',
'type': 'static_library',
'dependencies': [
'<(webrtc_root)/common_audio/common_audio.gyp:common_audio',
],
'include_dirs': [
'interface',
'<(webrtc_root)',
],
'direct_dependent_settings': {
'include_dirs': [
'interface',
'<(webrtc_root)',
],
},
'sources': [
'interface/ilbc.h',
'abs_quant.c',
'abs_quant_loop.c',
'augmented_cb_corr.c',
'bw_expand.c',
'cb_construct.c',
'cb_mem_energy.c',
'cb_mem_energy_augmentation.c',
'cb_mem_energy_calc.c',
'cb_search.c',
'cb_search_core.c',
'cb_update_best_index.c',
'chebyshev.c',
'comp_corr.c',
'constants.c',
'create_augmented_vec.c',
'decode.c',
'decode_residual.c',
'decoder_interpolate_lsf.c',
'do_plc.c',
'encode.c',
'energy_inverse.c',
'enh_upsample.c',
'enhancer.c',
'enhancer_interface.c',
'filtered_cb_vecs.c',
'frame_classify.c',
'gain_dequant.c',
'gain_quant.c',
'get_cd_vec.c',
'get_lsp_poly.c',
'get_sync_seq.c',
'hp_input.c',
'hp_output.c',
'ilbc.c',
'index_conv_dec.c',
'index_conv_enc.c',
'init_decode.c',
'init_encode.c',
'interpolate.c',
'interpolate_samples.c',
'lpc_encode.c',
'lsf_check.c',
'lsf_interpolate_to_poly_dec.c',
'lsf_interpolate_to_poly_enc.c',
'lsf_to_lsp.c',
'lsf_to_poly.c',
'lsp_to_lsf.c',
'my_corr.c',
'nearest_neighbor.c',
'pack_bits.c',
'poly_to_lsf.c',
'poly_to_lsp.c',
'refiner.c',
'simple_interpolate_lsf.c',
'simple_lpc_analysis.c',
'simple_lsf_dequant.c',
'simple_lsf_quant.c',
'smooth.c',
'smooth_out_data.c',
'sort_sq.c',
'split_vq.c',
'state_construct.c',
'state_search.c',
'swap_bytes.c',
'unpack_bits.c',
'vq3.c',
'vq4.c',
'window32_w32.c',
'xcorr_coef.c',
'abs_quant.h',
'abs_quant_loop.h',
'augmented_cb_corr.h',
'bw_expand.h',
'cb_construct.h',
'cb_mem_energy.h',
'cb_mem_energy_augmentation.h',
'cb_mem_energy_calc.h',
'cb_search.h',
'cb_search_core.h',
'cb_update_best_index.h',
'chebyshev.h',
'comp_corr.h',
'constants.h',
'create_augmented_vec.h',
'decode.h',
'decode_residual.h',
'decoder_interpolate_lsf.h',
'do_plc.h',
'encode.h',
'energy_inverse.h',
'enh_upsample.h',
'enhancer.h',
'enhancer_interface.h',
'filtered_cb_vecs.h',
'frame_classify.h',
'gain_dequant.h',
'gain_quant.h',
'get_cd_vec.h',
'get_lsp_poly.h',
'get_sync_seq.h',
'hp_input.h',
'hp_output.h',
'defines.h',
'index_conv_dec.h',
'index_conv_enc.h',
'init_decode.h',
'init_encode.h',
'interpolate.h',
'interpolate_samples.h',
'lpc_encode.h',
'lsf_check.h',
'lsf_interpolate_to_poly_dec.h',
'lsf_interpolate_to_poly_enc.h',
'lsf_to_lsp.h',
'lsf_to_poly.h',
'lsp_to_lsf.h',
'my_corr.h',
'nearest_neighbor.h',
'pack_bits.h',
'poly_to_lsf.h',
'poly_to_lsp.h',
'refiner.h',
'simple_interpolate_lsf.h',
'simple_lpc_analysis.h',
'simple_lsf_dequant.h',
'simple_lsf_quant.h',
'smooth.h',
'smooth_out_data.h',
'sort_sq.h',
'split_vq.h',
'state_construct.h',
'state_search.h',
'swap_bytes.h',
'unpack_bits.h',
'vq3.h',
'vq4.h',
'window32_w32.h',
'xcorr_coef.h',
], # sources
}, # iLBC
], # targets
'conditions': [
['include_tests==1', {
'targets': [
{
'target_name': 'iLBCtest',
'type': 'executable',
'dependencies': [
'iLBC',
],
'sources': [
'test/iLBC_test.c',
],
}, # iLBCtest
], # targets
}], # include_tests
], # conditions
}

View File

@@ -0,0 +1,38 @@
/*
* 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.
*/
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
WebRtcIlbcfix_IndexConvDec.c
******************************************************************/
#include "defines.h"
void WebRtcIlbcfix_IndexConvDec(
int16_t *index /* (i/o) Codebook indexes */
){
int k;
for (k=4;k<6;k++) {
/* Readjust the second and third codebook index for the first 40 sample
so that they look the same as the first (in terms of lag)
*/
if ((index[k]>=44)&&(index[k]<108)) {
index[k]+=64;
} else if ((index[k]>=108)&&(index[k]<128)) {
index[k]+=128;
} else {
/* ERROR */
}
}
}

View File

@@ -0,0 +1,28 @@
/*
* 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.
*/
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
WebRtcIlbcfix_IndexConvDec.h
******************************************************************/
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_INDEX_CONV_DEC_H_
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_INDEX_CONV_DEC_H_
#include "defines.h"
void WebRtcIlbcfix_IndexConvDec(
int16_t *index /* (i/o) Codebook indexes */
);
#endif

Some files were not shown because too many files have changed in this diff Show More