Move src/ -> webrtc/

TBR=niklas.enbom@webrtc.org

Review URL: https://webrtc-codereview.appspot.com/915006

git-svn-id: http://webrtc.googlecode.com/svn/trunk@2963 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
andrew@webrtc.org
2012-10-22 18:19:23 +00:00
parent 24a419c0c7
commit 14b43beb7c
1888 changed files with 23 additions and 23 deletions

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.
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_audio_coding
LOCAL_MODULE_TAGS := optional
LOCAL_CPP_EXTENSION := .cc
LOCAL_SRC_FILES := \
acm_cng.cc \
acm_codec_database.cc \
acm_dtmf_detection.cc \
acm_dtmf_playout.cc \
acm_g722.cc \
acm_generic_codec.cc \
acm_ilbc.cc \
acm_isac.cc \
acm_neteq.cc \
acm_pcm16b.cc \
acm_pcma.cc \
acm_pcmu.cc \
acm_red.cc \
acm_resampler.cc \
audio_coding_module.cc \
audio_coding_module_impl.cc
# Flags passed to both C and C++ files.
LOCAL_CFLAGS := \
$(MY_WEBRTC_COMMON_DEFS)
LOCAL_C_INCLUDES := \
$(LOCAL_PATH)/../interface \
$(LOCAL_PATH)/../../codecs/cng/include \
$(LOCAL_PATH)/../../codecs/g711/include \
$(LOCAL_PATH)/../../codecs/g722/include \
$(LOCAL_PATH)/../../codecs/ilbc/interface \
$(LOCAL_PATH)/../../codecs/iSAC/main/interface \
$(LOCAL_PATH)/../../codecs/iSAC/fix/interface \
$(LOCAL_PATH)/../../codecs/pcm16b/include \
$(LOCAL_PATH)/../../neteq/interface \
$(LOCAL_PATH)/../../../.. \
$(LOCAL_PATH)/../../../interface \
$(LOCAL_PATH)/../../../../common_audio/resampler/include \
$(LOCAL_PATH)/../../../../common_audio/signal_processing/include \
$(LOCAL_PATH)/../../../../common_audio/vad/include \
$(LOCAL_PATH)/../../../../system_wrappers/interface
LOCAL_SHARED_LIBRARIES := \
libcutils \
libdl \
libstlport
ifndef NDK_ROOT
include external/stlport/libstlport.mk
endif
include $(BUILD_STATIC_LIBRARY)

View File

@ -0,0 +1,424 @@
/*
* 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 "acm_amr.h"
#include "acm_common_defs.h"
#include "acm_neteq.h"
#include "audio_coding_module_typedefs.h"
#include "rw_lock_wrapper.h"
#include "trace.h"
#include "webrtc_neteq.h"
#include "webrtc_neteq_help_macros.h"
#ifdef WEBRTC_CODEC_AMR
// NOTE! GSM AMR is not included in the open-source package. The following
// interface file is needed:
//
// /modules/audio_coding/codecs/amr/main/interface/amr_interface.h
//
// The API in the header file should match the one below.
//
// int16_t WebRtcAmr_CreateEnc(AMR_encinst_t_** encInst);
// int16_t WebRtcAmr_CreateDec(AMR_decinst_t_** decInst);
// int16_t WebRtcAmr_FreeEnc(AMR_encinst_t_* encInst);
// int16_t WebRtcAmr_FreeDec(AMR_decinst_t_* decInst);
// int16_t WebRtcAmr_Encode(AMR_encinst_t_* encInst,
// int16_t* input,
// int16_t len,
// int16_t*output,
// int16_t mode);
// int16_t WebRtcAmr_EncoderInit(AMR_encinst_t_* encInst,
// int16_t dtxMode);
// int16_t WebRtcAmr_EncodeBitmode(AMR_encinst_t_* encInst,
// int format);
// int16_t WebRtcAmr_Decode(AMR_decinst_t_* decInst);
// int16_t WebRtcAmr_DecodePlc(AMR_decinst_t_* decInst);
// int16_t WebRtcAmr_DecoderInit(AMR_decinst_t_* decInst);
// int16_t WebRtcAmr_DecodeBitmode(AMR_decinst_t_* decInst,
// int format);
#include "amr_interface.h"
#endif
namespace webrtc {
#ifndef WEBRTC_CODEC_AMR
ACMAMR::ACMAMR(WebRtc_Word16 /* codecID */)
: _encoderInstPtr(NULL),
_decoderInstPtr(NULL),
_encodingMode(-1), // Invalid value.
_encodingRate(0), // Invalid value.
_encoderPackingFormat(AMRBandwidthEfficient),
_decoderPackingFormat(AMRBandwidthEfficient) {
return;
}
ACMAMR::~ACMAMR() {
return;
}
WebRtc_Word16 ACMAMR::InternalEncode(WebRtc_UWord8* /* bitStream */,
WebRtc_Word16* /* bitStreamLenByte */) {
return -1;
}
WebRtc_Word16 ACMAMR::DecodeSafe(WebRtc_UWord8* /* bitStream */,
WebRtc_Word16 /* bitStreamLenByte */,
WebRtc_Word16* /* audio */,
WebRtc_Word16* /* audioSamples */,
WebRtc_Word8* /* speechType */) {
return -1;
}
WebRtc_Word16 ACMAMR::EnableDTX() {
return -1;
}
WebRtc_Word16 ACMAMR::DisableDTX() {
return -1;
}
WebRtc_Word16 ACMAMR::InternalInitEncoder(
WebRtcACMCodecParams* /* codecParams */) {
return -1;
}
WebRtc_Word16 ACMAMR::InternalInitDecoder(
WebRtcACMCodecParams* /* codecParams */) {
return -1;
}
WebRtc_Word32 ACMAMR::CodecDef(WebRtcNetEQ_CodecDef& /* codecDef */,
const CodecInst& /* codecInst */) {
return -1;
}
ACMGenericCodec* ACMAMR::CreateInstance(void) {
return NULL;
}
WebRtc_Word16 ACMAMR::InternalCreateEncoder() {
return -1;
}
void ACMAMR::DestructEncoderSafe() {
return;
}
WebRtc_Word16 ACMAMR::InternalCreateDecoder() {
return -1;
}
void ACMAMR::DestructDecoderSafe() {
return;
}
WebRtc_Word16 ACMAMR::SetBitRateSafe(const WebRtc_Word32 /* rate */) {
return -1;
}
void ACMAMR::InternalDestructEncoderInst(void* /* ptrInst */) {
return;
}
WebRtc_Word16 ACMAMR::SetAMREncoderPackingFormat(
ACMAMRPackingFormat /* packingFormat */) {
return -1;
}
ACMAMRPackingFormat ACMAMR::AMREncoderPackingFormat() const {
return AMRUndefined;
}
WebRtc_Word16 ACMAMR::SetAMRDecoderPackingFormat(
ACMAMRPackingFormat /* packingFormat */) {
return -1;
}
ACMAMRPackingFormat ACMAMR::AMRDecoderPackingFormat() const {
return AMRUndefined;
}
#else //===================== Actual Implementation =======================
#define WEBRTC_AMR_MR475 0
#define WEBRTC_AMR_MR515 1
#define WEBRTC_AMR_MR59 2
#define WEBRTC_AMR_MR67 3
#define WEBRTC_AMR_MR74 4
#define WEBRTC_AMR_MR795 5
#define WEBRTC_AMR_MR102 6
#define WEBRTC_AMR_MR122 7
ACMAMR::ACMAMR(WebRtc_Word16 codecID)
: _encoderInstPtr(NULL),
_decoderInstPtr(NULL),
_encodingMode(-1), // invalid value
_encodingRate(0) { // invalid value
_codecID = codecID;
_hasInternalDTX = true;
_encoderPackingFormat = AMRBandwidthEfficient;
_decoderPackingFormat = AMRBandwidthEfficient;
return;
}
ACMAMR::~ACMAMR() {
if (_encoderInstPtr != NULL) {
WebRtcAmr_FreeEnc(_encoderInstPtr);
_encoderInstPtr = NULL;
}
if (_decoderInstPtr != NULL) {
WebRtcAmr_FreeDec(_decoderInstPtr);
_decoderInstPtr = NULL;
}
return;
}
WebRtc_Word16 ACMAMR::InternalEncode(WebRtc_UWord8* bitStream,
WebRtc_Word16* bitStreamLenByte) {
WebRtc_Word16 vadDecision = 1;
// sanity check, if the rate is set correctly. we might skip this
// sanity check. if rate is not set correctly, initialization flag
// should be false and should not be here.
if ((_encodingMode < WEBRTC_AMR_MR475) ||
(_encodingMode > WEBRTC_AMR_MR122)) {
*bitStreamLenByte = 0;
return -1;
}
*bitStreamLenByte = WebRtcAmr_Encode(_encoderInstPtr,
&_inAudio[_inAudioIxRead],
_frameLenSmpl,
(WebRtc_Word16*) bitStream,
_encodingMode);
// Update VAD, if internal DTX is used
if (_hasInternalDTX && _dtxEnabled) {
if (*bitStreamLenByte <= (7 * _frameLenSmpl / 160)) {
vadDecision = 0;
}
for (WebRtc_Word16 n = 0; n < MAX_FRAME_SIZE_10MSEC; n++) {
_vadLabel[n] = vadDecision;
}
}
// increment the read index
_inAudioIxRead += _frameLenSmpl;
return *bitStreamLenByte;
}
WebRtc_Word16 ACMAMR::DecodeSafe(WebRtc_UWord8* /* bitStream */,
WebRtc_Word16 /* bitStreamLenByte */,
WebRtc_Word16* /* audio */,
WebRtc_Word16* /* audioSamples */,
WebRtc_Word8* /* speechType */) {
return 0;
}
WebRtc_Word16 ACMAMR::EnableDTX() {
if (_dtxEnabled) {
return 0;
} else if (_encoderExist) { // check if encoder exist
// enable DTX
if (WebRtcAmr_EncoderInit(_encoderInstPtr, 1) < 0) {
return -1;
}
_dtxEnabled = true;
return 0;
} else {
return -1;
}
}
WebRtc_Word16 ACMAMR::DisableDTX() {
if (!_dtxEnabled) {
return 0;
} else if (_encoderExist) { // check if encoder exist
// disable DTX
if (WebRtcAmr_EncoderInit(_encoderInstPtr, 0) < 0) {
return -1;
}
_dtxEnabled = false;
return 0;
} else {
// encoder doesn't exists, therefore disabling is harmless
return 0;
}
}
WebRtc_Word16 ACMAMR::InternalInitEncoder(WebRtcACMCodecParams* codecParams) {
WebRtc_Word16 status = SetBitRateSafe((codecParams->codecInstant).rate);
status += (WebRtcAmr_EncoderInit(
_encoderInstPtr, ((codecParams->enableDTX) ? 1 : 0)) < 0) ? -1 : 0;
status += (WebRtcAmr_EncodeBitmode(
_encoderInstPtr, _encoderPackingFormat) < 0) ? -1 : 0;
return (status < 0) ? -1 : 0;
}
WebRtc_Word16 ACMAMR::InternalInitDecoder(
WebRtcACMCodecParams* /* codecParams */) {
WebRtc_Word16 status =
((WebRtcAmr_DecoderInit(_decoderInstPtr) < 0) ? -1 : 0);
status += WebRtcAmr_DecodeBitmode(_decoderInstPtr, _decoderPackingFormat);
return (status < 0) ? -1 : 0;
}
WebRtc_Word32 ACMAMR::CodecDef(WebRtcNetEQ_CodecDef& codecDef,
const CodecInst& codecInst) {
if (!_decoderInitialized) {
// Todo:
// log error
return -1;
}
// Fill up the structure by calling
// "SET_CODEC_PAR" & "SET_AMR_FUNCTION."
// Then call NetEQ to add the codec to it's
// database.
SET_CODEC_PAR((codecDef), kDecoderAMR, codecInst.pltype, _decoderInstPtr,
8000);
SET_AMR_FUNCTIONS((codecDef));
return 0;
}
ACMGenericCodec* ACMAMR::CreateInstance(void) {
return NULL;
}
WebRtc_Word16 ACMAMR::InternalCreateEncoder() {
return WebRtcAmr_CreateEnc(&_encoderInstPtr);
}
void ACMAMR::DestructEncoderSafe() {
if (_encoderInstPtr != NULL) {
WebRtcAmr_FreeEnc(_encoderInstPtr);
_encoderInstPtr = NULL;
}
// there is no encoder set the following
_encoderExist = false;
_encoderInitialized = false;
_encodingMode = -1; // invalid value
_encodingRate = 0; // invalid value
}
WebRtc_Word16 ACMAMR::InternalCreateDecoder() {
return WebRtcAmr_CreateDec(&_decoderInstPtr);
}
void ACMAMR::DestructDecoderSafe() {
if (_decoderInstPtr != NULL) {
WebRtcAmr_FreeDec(_decoderInstPtr);
_decoderInstPtr = NULL;
}
// there is no encoder instance set the followings
_decoderExist = false;
_decoderInitialized = false;
}
WebRtc_Word16 ACMAMR::SetBitRateSafe(const WebRtc_Word32 rate) {
switch (rate) {
case 4750: {
_encodingMode = WEBRTC_AMR_MR475;
_encodingRate = 4750;
break;
}
case 5150: {
_encodingMode = WEBRTC_AMR_MR515;
_encodingRate = 5150;
break;
}
case 5900: {
_encodingMode = WEBRTC_AMR_MR59;
_encodingRate = 5900;
break;
}
case 6700: {
_encodingMode = WEBRTC_AMR_MR67;
_encodingRate = 6700;
break;
}
case 7400: {
_encodingMode = WEBRTC_AMR_MR74;
_encodingRate = 7400;
break;
}
case 7950: {
_encodingMode = WEBRTC_AMR_MR795;
_encodingRate = 7950;
break;
}
case 10200: {
_encodingMode = WEBRTC_AMR_MR102;
_encodingRate = 10200;
break;
}
case 12200: {
_encodingMode = WEBRTC_AMR_MR122;
_encodingRate = 12200;
break;
}
default: {
return -1;
}
}
return 0;
}
void ACMAMR::InternalDestructEncoderInst(void* ptrInst) {
// Free the memory where ptrInst is pointing to
if (ptrInst != NULL) {
WebRtcAmr_FreeEnc(reinterpret_cast<AMR_encinst_t_*>(ptrInst));
}
return;
}
WebRtc_Word16 ACMAMR::SetAMREncoderPackingFormat(
ACMAMRPackingFormat packingFormat) {
if ((packingFormat != AMRBandwidthEfficient) &&
(packingFormat != AMROctetAlligned) &&
(packingFormat != AMRFileStorage)) {
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
"Invalid AMR Encoder packing-format.");
return -1;
} else {
if (WebRtcAmr_EncodeBitmode(_encoderInstPtr, packingFormat) < 0) {
return -1;
} else {
_encoderPackingFormat = packingFormat;
return 0;
}
}
}
ACMAMRPackingFormat ACMAMR::AMREncoderPackingFormat() const {
return _encoderPackingFormat;
}
WebRtc_Word16 ACMAMR::SetAMRDecoderPackingFormat(
ACMAMRPackingFormat packingFormat) {
if ((packingFormat != AMRBandwidthEfficient) &&
(packingFormat != AMROctetAlligned) &&
(packingFormat != AMRFileStorage)) {
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
"Invalid AMR decoder packing-format.");
return -1;
} else {
if (WebRtcAmr_DecodeBitmode(_decoderInstPtr, packingFormat) < 0) {
return -1;
} else {
_decoderPackingFormat = packingFormat;
return 0;
}
}
}
ACMAMRPackingFormat ACMAMR::AMRDecoderPackingFormat() const {
return _decoderPackingFormat;
}
#endif
}

View File

@ -0,0 +1,83 @@
/*
* 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_MAIN_SOURCE_ACM_AMR_H_
#define WEBRTC_MODULES_AUDIO_CODING_MAIN_SOURCE_ACM_AMR_H_
#include "acm_generic_codec.h"
// forward declaration
struct AMR_encinst_t_;
struct AMR_decinst_t_;
namespace webrtc {
enum ACMAMRPackingFormat;
class ACMAMR: public ACMGenericCodec {
public:
ACMAMR(WebRtc_Word16 codecID);
~ACMAMR();
// for FEC
ACMGenericCodec* CreateInstance(void);
WebRtc_Word16 InternalEncode(WebRtc_UWord8* bitstream,
WebRtc_Word16* bitStreamLenByte);
WebRtc_Word16 InternalInitEncoder(WebRtcACMCodecParams *codecParams);
WebRtc_Word16 InternalInitDecoder(WebRtcACMCodecParams *codecParams);
WebRtc_Word16 SetAMREncoderPackingFormat(
const ACMAMRPackingFormat packingFormat);
ACMAMRPackingFormat AMREncoderPackingFormat() const;
WebRtc_Word16 SetAMRDecoderPackingFormat(
const ACMAMRPackingFormat packingFormat);
ACMAMRPackingFormat AMRDecoderPackingFormat() const;
protected:
WebRtc_Word16 DecodeSafe(WebRtc_UWord8* bitStream,
WebRtc_Word16 bitStreamLenByte,
WebRtc_Word16* audio, WebRtc_Word16* audioSamples,
WebRtc_Word8* speechType);
WebRtc_Word32 CodecDef(WebRtcNetEQ_CodecDef& codecDef,
const CodecInst& codecInst);
void DestructEncoderSafe();
void DestructDecoderSafe();
WebRtc_Word16 InternalCreateEncoder();
WebRtc_Word16 InternalCreateDecoder();
void InternalDestructEncoderInst(void* ptrInst);
WebRtc_Word16 SetBitRateSafe(const WebRtc_Word32 rate);
WebRtc_Word16 EnableDTX();
WebRtc_Word16 DisableDTX();
AMR_encinst_t_* _encoderInstPtr;
AMR_decinst_t_* _decoderInstPtr;
WebRtc_Word16 _encodingMode;
WebRtc_Word16 _encodingRate;
ACMAMRPackingFormat _encoderPackingFormat;
ACMAMRPackingFormat _decoderPackingFormat;
};
} // namespace webrtc
#endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_SOURCE_ACM_AMR_H_

View File

@ -0,0 +1,431 @@
/*
* 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 "acm_amrwb.h"
#include "acm_common_defs.h"
#include "acm_neteq.h"
#include "audio_coding_module_typedefs.h"
#include "rw_lock_wrapper.h"
#include "trace.h"
#include "webrtc_neteq.h"
#include "webrtc_neteq_help_macros.h"
#ifdef WEBRTC_CODEC_AMRWB
// NOTE! GSM AMR-wb is not included in the open-source package. The
// following interface file is needed:
//
// /modules/audio_coding/codecs/amrwb/main/interface/amrwb_interface.h
//
// The API in the header file should match the one below.
//
// int16_t WebRtcAmrWb_CreateEnc(AMRWB_encinst_t_** encInst);
// int16_t WebRtcAmrWb_CreateDec(AMRWB_decinst_t_** decInst);
// int16_t WebRtcAmrWb_FreeEnc(AMRWB_encinst_t_* encInst);
// int16_t WebRtcAmrWb_FreeDec(AMRWB_decinst_t_* decInst);
// int16_t WebRtcAmrWb_Encode(AMRWB_encinst_t_* encInst, int16_t* input,
// int16_t len, int16_t* output, int16_t mode);
// int16_t WebRtcAmrWb_EncoderInit(AMRWB_encinst_t_* encInst,
// int16_t dtxMode);
// int16_t WebRtcAmrWb_EncodeBitmode(AMRWB_encinst_t_* encInst,
// int format);
// int16_t WebRtcAmrWb_Decode(AMRWB_decinst_t_* decInst);
// int16_t WebRtcAmrWb_DecodePlc(AMRWB_decinst_t_* decInst);
// int16_t WebRtcAmrWb_DecoderInit(AMRWB_decinst_t_* decInst);
// int16_t WebRtcAmrWb_DecodeBitmode(AMRWB_decinst_t_* decInst,
// int format);
#include "amrwb_interface.h"
#endif
namespace webrtc {
#ifndef WEBRTC_CODEC_AMRWB
ACMAMRwb::ACMAMRwb(WebRtc_Word16 /* codecID*/)
: _encoderInstPtr(NULL),
_decoderInstPtr(NULL),
_encodingMode(-1), // invalid value
_encodingRate(0), // invalid value
_encoderPackingFormat(AMRBandwidthEfficient),
_decoderPackingFormat(AMRBandwidthEfficient) {
return;
}
ACMAMRwb::~ACMAMRwb() {
return;
}
WebRtc_Word16 ACMAMRwb::InternalEncode(WebRtc_UWord8* /* bitStream */,
WebRtc_Word16* /* bitStreamLenByte */) {
return -1;
}
WebRtc_Word16 ACMAMRwb::DecodeSafe(WebRtc_UWord8* /* bitStream */,
WebRtc_Word16 /* bitStreamLenByte */,
WebRtc_Word16* /* audio */,
WebRtc_Word16* /* audioSamples */,
WebRtc_Word8* /* speechType */) {
return -1;
}
WebRtc_Word16 ACMAMRwb::EnableDTX() {
return -1;
}
WebRtc_Word16 ACMAMRwb::DisableDTX() {
return -1;
}
WebRtc_Word16 ACMAMRwb::InternalInitEncoder(
WebRtcACMCodecParams* /* codecParams */) {
return -1;
}
WebRtc_Word16 ACMAMRwb::InternalInitDecoder(
WebRtcACMCodecParams* /* codecParams */) {
return -1;
}
WebRtc_Word32 ACMAMRwb::CodecDef(WebRtcNetEQ_CodecDef& /* codecDef */,
const CodecInst& /* codecInst */) {
return -1;
}
ACMGenericCodec*
ACMAMRwb::CreateInstance(void) {
return NULL;
}
WebRtc_Word16 ACMAMRwb::InternalCreateEncoder() {
return -1;
}
void ACMAMRwb::DestructEncoderSafe() {
return;
}
WebRtc_Word16 ACMAMRwb::InternalCreateDecoder() {
return -1;
}
void ACMAMRwb::DestructDecoderSafe() {
return;
}
WebRtc_Word16 ACMAMRwb::SetBitRateSafe(const WebRtc_Word32 /* rate */) {
return -1;
}
void ACMAMRwb::InternalDestructEncoderInst(void* /* ptrInst */) {
return;
}
WebRtc_Word16 ACMAMRwb::SetAMRwbEncoderPackingFormat(
ACMAMRPackingFormat /* packingFormat */) {
return -1;
}
ACMAMRPackingFormat ACMAMRwb::AMRwbEncoderPackingFormat() const {
return AMRUndefined;
}
WebRtc_Word16 ACMAMRwb::SetAMRwbDecoderPackingFormat(
ACMAMRPackingFormat /* packingFormat */) {
return -1;
}
ACMAMRPackingFormat ACMAMRwb::AMRwbDecoderPackingFormat() const {
return AMRUndefined;
}
#else //===================== Actual Implementation =======================
#define AMRWB_MODE_7k 0
#define AMRWB_MODE_9k 1
#define AMRWB_MODE_12k 2
#define AMRWB_MODE_14k 3
#define AMRWB_MODE_16k 4
#define AMRWB_MODE_18k 5
#define AMRWB_MODE_20k 6
#define AMRWB_MODE_23k 7
#define AMRWB_MODE_24k 8
ACMAMRwb::ACMAMRwb(WebRtc_Word16 codecID)
: _encoderInstPtr(NULL),
_decoderInstPtr(NULL),
_encodingMode(-1), // invalid value
_encodingRate(0) { // invalid value
_codecID = codecID;
_hasInternalDTX = true;
_encoderPackingFormat = AMRBandwidthEfficient;
_decoderPackingFormat = AMRBandwidthEfficient;
return;
}
ACMAMRwb::~ACMAMRwb() {
if (_encoderInstPtr != NULL) {
WebRtcAmrWb_FreeEnc(_encoderInstPtr);
_encoderInstPtr = NULL;
}
if (_decoderInstPtr != NULL) {
WebRtcAmrWb_FreeDec(_decoderInstPtr);
_decoderInstPtr = NULL;
}
return;
}
WebRtc_Word16 ACMAMRwb::InternalEncode(WebRtc_UWord8* bitStream,
WebRtc_Word16* bitStreamLenByte) {
WebRtc_Word16 vadDecision = 1;
// sanity check, if the rate is set correctly. we might skip this
// sanity check. if rate is not set correctly, initialization flag
// should be false and should not be here.
if ((_encodingMode < AMRWB_MODE_7k) || (_encodingMode > AMRWB_MODE_24k)) {
*bitStreamLenByte = 0;
return -1;
}
*bitStreamLenByte = WebRtcAmrWb_Encode(_encoderInstPtr,
&_inAudio[_inAudioIxRead],
_frameLenSmpl,
(WebRtc_Word16*) bitStream,
_encodingMode);
// Update VAD, if internal DTX is used
if (_hasInternalDTX && _dtxEnabled) {
if (*bitStreamLenByte <= (7 * _frameLenSmpl / 160)) {
vadDecision = 0;
}
for (WebRtc_Word16 n = 0; n < MAX_FRAME_SIZE_10MSEC; n++) {
_vadLabel[n] = vadDecision;
}
}
// increment the read index this tell the caller that how far
// we have gone forward in reading the audio buffer
_inAudioIxRead += _frameLenSmpl;
return *bitStreamLenByte;
}
WebRtc_Word16 ACMAMRwb::DecodeSafe(WebRtc_UWord8* /* bitStream */,
WebRtc_Word16 /* bitStreamLenByte */,
WebRtc_Word16* /* audio */,
WebRtc_Word16* /* audioSamples */,
WebRtc_Word8* /* speechType */) {
return 0;
}
WebRtc_Word16 ACMAMRwb::EnableDTX() {
if (_dtxEnabled) {
return 0;
} else if (_encoderExist) { // check if encoder exist
// enable DTX
if (WebRtcAmrWb_EncoderInit(_encoderInstPtr, 1) < 0) {
return -1;
}
_dtxEnabled = true;
return 0;
} else {
return -1;
}
}
WebRtc_Word16 ACMAMRwb::DisableDTX() {
if (!_dtxEnabled) {
return 0;
} else if (_encoderExist) { // check if encoder exist
// disable DTX
if (WebRtcAmrWb_EncoderInit(_encoderInstPtr, 0) < 0) {
return -1;
}
_dtxEnabled = false;
return 0;
} else {
// encoder doesn't exists, therefore disabling is harmless
return 0;
}
}
WebRtc_Word16 ACMAMRwb::InternalInitEncoder(WebRtcACMCodecParams* codecParams) {
// sanity check
if (_encoderInstPtr == NULL) {
return -1;
}
WebRtc_Word16 status = SetBitRateSafe((codecParams->codecInstant).rate);
status += (WebRtcAmrWb_EncoderInit(
_encoderInstPtr, ((codecParams->enableDTX) ? 1 : 0)) < 0) ? -1 : 0;
status += (WebRtcAmrWb_EncodeBitmode(
_encoderInstPtr, _encoderPackingFormat) < 0) ? -1 : 0;
return (status < 0) ? -1 : 0;
}
WebRtc_Word16 ACMAMRwb::InternalInitDecoder(
WebRtcACMCodecParams* /* codecParams */) {
WebRtc_Word16 status = WebRtcAmrWb_DecodeBitmode(_decoderInstPtr,
_decoderPackingFormat);
status += ((WebRtcAmrWb_DecoderInit(_decoderInstPtr) < 0) ? -1 : 0);
return (status < 0) ? -1 : 0;
}
WebRtc_Word32 ACMAMRwb::CodecDef(WebRtcNetEQ_CodecDef& codecDef,
const CodecInst& codecInst) {
if (!_decoderInitialized) {
return -1;
}
// Fill up the structure by calling
// "SET_CODEC_PAR" & "SET_AMRWB_FUNCTION."
// Then call NetEQ to add the codec to it's
// database.
SET_CODEC_PAR((codecDef), kDecoderAMRWB, codecInst.pltype, _decoderInstPtr,
16000);
SET_AMRWB_FUNCTIONS((codecDef));
return 0;
}
ACMGenericCodec* ACMAMRwb::CreateInstance(void) {
return NULL;
}
WebRtc_Word16 ACMAMRwb::InternalCreateEncoder() {
return WebRtcAmrWb_CreateEnc(&_encoderInstPtr);
}
void ACMAMRwb::DestructEncoderSafe() {
if (_encoderInstPtr != NULL) {
WebRtcAmrWb_FreeEnc(_encoderInstPtr);
_encoderInstPtr = NULL;
}
// there is no encoder set the following
_encoderExist = false;
_encoderInitialized = false;
_encodingMode = -1; // invalid value
_encodingRate = 0;
}
WebRtc_Word16 ACMAMRwb::InternalCreateDecoder() {
return WebRtcAmrWb_CreateDec(&_decoderInstPtr);
}
void ACMAMRwb::DestructDecoderSafe() {
if (_decoderInstPtr != NULL) {
WebRtcAmrWb_FreeDec(_decoderInstPtr);
_decoderInstPtr = NULL;
}
// there is no encoder instance set the followings
_decoderExist = false;
_decoderInitialized = false;
}
WebRtc_Word16 ACMAMRwb::SetBitRateSafe(const WebRtc_Word32 rate) {
switch (rate) {
case 7000: {
_encodingMode = AMRWB_MODE_7k;
_encodingRate = 7000;
break;
}
case 9000: {
_encodingMode = AMRWB_MODE_9k;
_encodingRate = 9000;
break;
}
case 12000: {
_encodingMode = AMRWB_MODE_12k;
_encodingRate = 12000;
break;
}
case 14000: {
_encodingMode = AMRWB_MODE_14k;
_encodingRate = 14000;
break;
}
case 16000: {
_encodingMode = AMRWB_MODE_16k;
_encodingRate = 16000;
break;
}
case 18000: {
_encodingMode = AMRWB_MODE_18k;
_encodingRate = 18000;
break;
}
case 20000: {
_encodingMode = AMRWB_MODE_20k;
_encodingRate = 20000;
break;
}
case 23000: {
_encodingMode = AMRWB_MODE_23k;
_encodingRate = 23000;
break;
}
case 24000: {
_encodingMode = AMRWB_MODE_24k;
_encodingRate = 24000;
break;
}
default: {
return -1;
}
}
return 0;
}
void ACMAMRwb::InternalDestructEncoderInst(void* ptrInst) {
if (ptrInst != NULL) {
WebRtcAmrWb_FreeEnc(static_cast<AMRWB_encinst_t_*>(ptrInst));
}
return;
}
WebRtc_Word16 ACMAMRwb::SetAMRwbEncoderPackingFormat(
ACMAMRPackingFormat packingFormat) {
if ((packingFormat != AMRBandwidthEfficient) &&
(packingFormat != AMROctetAlligned) &&
(packingFormat != AMRFileStorage)) {
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
"Invalid AMRwb encoder packing-format.");
return -1;
} else {
if (WebRtcAmrWb_EncodeBitmode(_encoderInstPtr, packingFormat) < 0) {
return -1;
} else {
_encoderPackingFormat = packingFormat;
return 0;
}
}
}
ACMAMRPackingFormat ACMAMRwb::AMRwbEncoderPackingFormat() const {
return _encoderPackingFormat;
}
WebRtc_Word16 ACMAMRwb::SetAMRwbDecoderPackingFormat(
ACMAMRPackingFormat packingFormat) {
if ((packingFormat != AMRBandwidthEfficient) &&
(packingFormat != AMROctetAlligned) &&
(packingFormat != AMRFileStorage)) {
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
"Invalid AMRwb decoder packing-format.");
return -1;
} else {
if (WebRtcAmrWb_DecodeBitmode(_decoderInstPtr, packingFormat) < 0) {
return -1;
} else {
_decoderPackingFormat = packingFormat;
return 0;
}
}
}
ACMAMRPackingFormat ACMAMRwb::AMRwbDecoderPackingFormat() const {
return _decoderPackingFormat;
}
#endif
} // namespace webrtc

View File

@ -0,0 +1,84 @@
/*
* 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_MAIN_SOURCE_ACM_AMRWB_H_
#define WEBRTC_MODULES_AUDIO_CODING_MAIN_SOURCE_ACM_AMRWB_H_
#include "acm_generic_codec.h"
// forward declaration
struct AMRWB_encinst_t_;
struct AMRWB_decinst_t_;
namespace webrtc {
enum ACMAMRPackingFormat;
class ACMAMRwb: public ACMGenericCodec {
public:
ACMAMRwb(WebRtc_Word16 codecID);
~ACMAMRwb();
// for FEC
ACMGenericCodec* CreateInstance(void);
WebRtc_Word16 InternalEncode(WebRtc_UWord8* bitstream,
WebRtc_Word16* bitStreamLenByte);
WebRtc_Word16 InternalInitEncoder(WebRtcACMCodecParams* codecParams);
WebRtc_Word16 InternalInitDecoder(WebRtcACMCodecParams* codecParams);
WebRtc_Word16 SetAMRwbEncoderPackingFormat(
const ACMAMRPackingFormat packingFormat);
ACMAMRPackingFormat AMRwbEncoderPackingFormat() const;
WebRtc_Word16 SetAMRwbDecoderPackingFormat(
const ACMAMRPackingFormat packingFormat);
ACMAMRPackingFormat AMRwbDecoderPackingFormat() const;
protected:
WebRtc_Word16 DecodeSafe(WebRtc_UWord8* bitStream,
WebRtc_Word16 bitStreamLenByte,
WebRtc_Word16* audio, WebRtc_Word16* audioSamples,
WebRtc_Word8* speechType);
WebRtc_Word32 CodecDef(WebRtcNetEQ_CodecDef& codecDef,
const CodecInst& codecInst);
void DestructEncoderSafe();
void DestructDecoderSafe();
WebRtc_Word16 InternalCreateEncoder();
WebRtc_Word16 InternalCreateDecoder();
void InternalDestructEncoderInst(void* ptrInst);
WebRtc_Word16 SetBitRateSafe(const WebRtc_Word32 rate);
WebRtc_Word16 EnableDTX();
WebRtc_Word16 DisableDTX();
AMRWB_encinst_t_* _encoderInstPtr;
AMRWB_decinst_t_* _decoderInstPtr;
WebRtc_Word16 _encodingMode;
WebRtc_Word16 _encodingRate;
ACMAMRPackingFormat _encoderPackingFormat;
ACMAMRPackingFormat _decoderPackingFormat;
};
} // namespace webrtc
#endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_SOURCE_ACM_AMRWB_H_

View File

@ -0,0 +1,334 @@
/*
* 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 "acm_common_defs.h"
#include "acm_neteq.h"
#include "acm_celt.h"
#include "trace.h"
#include "webrtc_neteq.h"
#include "webrtc_neteq_help_macros.h"
// TODO(tlegrand): Add full paths.
#ifdef WEBRTC_CODEC_CELT
// NOTE! Celt is not included in the open-source package. Modify this file or
// your codec API to match the function call and name of used Celt API file.
#include "celt_interface.h"
#endif
namespace webrtc {
#ifndef WEBRTC_CODEC_CELT
ACMCELT::ACMCELT(int16_t /* codecID */)
: enc_inst_ptr_(NULL),
dec_inst_ptr_(NULL),
sampling_freq_(0),
bitrate_(0),
channels_(1),
dec_channels_(1) {
return;
}
ACMCELT::~ACMCELT() {
return;
}
int16_t ACMCELT::InternalEncode(uint8_t* /* bitStream */,
int16_t* /* bitStreamLenByte */) {
return -1;
}
int16_t ACMCELT::DecodeSafe(uint8_t* /* bitStream */,
int16_t /* bitStreamLenByte */,
int16_t* /* audio */,
int16_t* /* audioSamples */,
WebRtc_Word8* /* speechType */) {
return -1;
}
int16_t ACMCELT::InternalInitEncoder(WebRtcACMCodecParams* /* codecParams */) {
return -1;
}
int16_t ACMCELT::InternalInitDecoder(WebRtcACMCodecParams* /* codecParams */) {
return -1;
}
int32_t ACMCELT::CodecDef(WebRtcNetEQ_CodecDef& /* codecDef */,
const CodecInst& /* codecInst */) {
return -1;
}
ACMGenericCodec* ACMCELT::CreateInstance(void) {
return NULL;
}
int16_t ACMCELT::InternalCreateEncoder() {
return -1;
}
void ACMCELT::DestructEncoderSafe() {
return;
}
int16_t ACMCELT::InternalCreateDecoder() {
return -1;
}
void ACMCELT::DestructDecoderSafe() {
return;
}
void ACMCELT::InternalDestructEncoderInst(void* /* ptrInst */) {
return;
}
bool ACMCELT::IsTrueStereoCodec() {
return true;
}
int16_t ACMCELT::SetBitRateSafe(const int32_t /*rate*/) {
return -1;
}
void ACMCELT::SplitStereoPacket(uint8_t* /*payload*/,
int32_t* /*payload_length*/) {}
#else //===================== Actual Implementation =======================
ACMCELT::ACMCELT(int16_t codecID)
: enc_inst_ptr_(NULL),
dec_inst_ptr_(NULL),
sampling_freq_(32000), // Default sampling frequency.
bitrate_(64000), // Default rate.
channels_(1), // Default send mono.
dec_channels_(1) { // Default receive mono.
// TODO(tlegrand): remove later when ACMGenericCodec has a new constructor.
_codecID = codecID;
return;
}
ACMCELT::~ACMCELT() {
if (enc_inst_ptr_ != NULL) {
WebRtcCelt_FreeEnc(enc_inst_ptr_);
enc_inst_ptr_ = NULL;
}
if (dec_inst_ptr_ != NULL) {
WebRtcCelt_FreeDec(dec_inst_ptr_);
dec_inst_ptr_ = NULL;
}
return;
}
int16_t ACMCELT::InternalEncode(uint8_t* bitStream, int16_t* bitStreamLenByte) {
*bitStreamLenByte = 0;
// Call Encoder.
*bitStreamLenByte = WebRtcCelt_Encode(enc_inst_ptr_,
&_inAudio[_inAudioIxRead],
bitStream);
// Increment the read index this tell the caller that how far
// we have gone forward in reading the audio buffer.
_inAudioIxRead += _frameLenSmpl * channels_;
if (*bitStreamLenByte < 0) {
// Error reported from the encoder.
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
"InternalEncode: Encode error for Celt");
*bitStreamLenByte = 0;
return -1;
}
return *bitStreamLenByte;
}
int16_t ACMCELT::DecodeSafe(uint8_t* /* bitStream */,
int16_t /* bitStreamLenByte */,
int16_t* /* audio */,
int16_t* /* audioSamples */,
WebRtc_Word8* /* speechType */) {
return 0;
}
int16_t ACMCELT::InternalInitEncoder(WebRtcACMCodecParams* codecParams) {
// Set bitrate and check that it is within the valid range.
int16_t status = SetBitRateSafe((codecParams->codecInstant).rate);
if (status < 0) {
return -1;
}
// If number of channels changed we need to re-create memory.
if (codecParams->codecInstant.channels != channels_) {
WebRtcCelt_FreeEnc(enc_inst_ptr_);
enc_inst_ptr_ = NULL;
// Store new number of channels.
channels_ = codecParams->codecInstant.channels;
if (WebRtcCelt_CreateEnc(&enc_inst_ptr_, channels_) < 0) {
return -1;
}
}
// Initiate encoder.
if (WebRtcCelt_EncoderInit(enc_inst_ptr_, channels_, bitrate_) >= 0) {
return 0;
} else {
return -1;
}
}
int16_t ACMCELT::InternalInitDecoder(WebRtcACMCodecParams* codecParams) {
// If number of channels changed we need to re-create memory.
if (codecParams->codecInstant.channels != dec_channels_) {
WebRtcCelt_FreeDec(dec_inst_ptr_);
dec_inst_ptr_ = NULL;
// Store new number of channels.
dec_channels_ = codecParams->codecInstant.channels;
if (WebRtcCelt_CreateDec(&dec_inst_ptr_, dec_channels_) < 0) {
return -1;
}
}
// Initiate decoder, both master and slave parts.
if (WebRtcCelt_DecoderInit(dec_inst_ptr_) < 0) {
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
"InternalInitDecoder: init decoder failed for Celt.");
return -1;
}
if (WebRtcCelt_DecoderInitSlave(dec_inst_ptr_) < 0) {
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
"InternalInitDecoder: init decoder failed for Celt.");
return -1;
}
return 0;
}
int32_t ACMCELT::CodecDef(WebRtcNetEQ_CodecDef& codecDef,
const CodecInst& codecInst) {
if (!_decoderInitialized) {
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
"CodecDef: Decoder uninitialized for Celt");
return -1;
}
// Fill up the structure by calling
// "SET_CODEC_PAR" and "SET_CELT_FUNCTIONS" or "SET_CELTSLAVE_FUNCTIONS".
// Then call NetEQ to add the codec to it's
// database.
if (codecInst.channels == 1) {
SET_CODEC_PAR(codecDef, kDecoderCELT_32, codecInst.pltype, dec_inst_ptr_,
32000);
} else {
SET_CODEC_PAR(codecDef, kDecoderCELT_32_2ch, codecInst.pltype,
dec_inst_ptr_, 32000);
}
// If this is the master of NetEQ, regular decoder will be added, otherwise
// the slave decoder will be used.
if (_isMaster) {
SET_CELT_FUNCTIONS(codecDef);
} else {
SET_CELTSLAVE_FUNCTIONS(codecDef);
}
return 0;
}
ACMGenericCodec* ACMCELT::CreateInstance(void) {
return NULL;
}
int16_t ACMCELT::InternalCreateEncoder() {
if (WebRtcCelt_CreateEnc(&enc_inst_ptr_, _noChannels) < 0) {
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
"InternalCreateEncoder: create encoder failed for Celt");
return -1;
}
channels_ = _noChannels;
return 0;
}
void ACMCELT::DestructEncoderSafe() {
_encoderExist = false;
_encoderInitialized = false;
if (enc_inst_ptr_ != NULL) {
WebRtcCelt_FreeEnc(enc_inst_ptr_);
enc_inst_ptr_ = NULL;
}
}
int16_t ACMCELT::InternalCreateDecoder() {
if (WebRtcCelt_CreateDec(&dec_inst_ptr_, dec_channels_) < 0) {
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
"InternalCreateDecoder: create decoder failed for Celt");
return -1;
}
return 0;
}
void ACMCELT::DestructDecoderSafe() {
_decoderExist = false;
_decoderInitialized = false;
if (dec_inst_ptr_ != NULL) {
WebRtcCelt_FreeDec(dec_inst_ptr_);
dec_inst_ptr_ = NULL;
}
}
void ACMCELT::InternalDestructEncoderInst(void* ptrInst) {
if (ptrInst != NULL) {
WebRtcCelt_FreeEnc(static_cast<CELT_encinst_t*>(ptrInst));
}
return;
}
bool ACMCELT::IsTrueStereoCodec() {
return true;
}
int16_t ACMCELT::SetBitRateSafe(const int32_t rate) {
// Check that rate is in the valid range.
if ((rate >= 48000) && (rate <= 128000)) {
// Store new rate.
bitrate_ = rate;
// Initiate encoder with new rate.
if (WebRtcCelt_EncoderInit(enc_inst_ptr_, channels_, bitrate_) >= 0) {
return 0;
} else {
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
"SetBitRateSafe: Failed to initiate Celt with rate %d",
rate);
return -1;
}
} else {
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
"SetBitRateSafe: Invalid rate Celt, %d", rate);
return -1;
}
}
// Copy the stereo packet so that NetEq will insert into both master and slave.
void ACMCELT::SplitStereoPacket(uint8_t* payload, int32_t* payload_length) {
// Check for valid inputs.
assert(payload != NULL);
assert(*payload_length > 0);
// Duplicate the payload.
memcpy(&payload[*payload_length], &payload[0],
sizeof(uint8_t) * (*payload_length));
// Double the size of the packet.
*payload_length *= 2;
}
#endif
} // namespace webrtc

View File

@ -0,0 +1,74 @@
/*
* 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_MAIN_SOURCE_ACM_CELT_H_
#define WEBRTC_MODULES_AUDIO_CODING_MAIN_SOURCE_ACM_CELT_H_
#include "acm_generic_codec.h"
// forward declaration
struct CELT_encinst_t_;
struct CELT_decinst_t_;
namespace webrtc {
class ACMCELT : public ACMGenericCodec {
public:
ACMCELT(int16_t codecID);
~ACMCELT();
ACMGenericCodec* CreateInstance(void);
int16_t InternalEncode(uint8_t* bitstream, int16_t* bitStreamLenByte);
int16_t InternalInitEncoder(WebRtcACMCodecParams *codecParams);
int16_t InternalInitDecoder(WebRtcACMCodecParams *codecParams);
protected:
WebRtc_Word16 DecodeSafe(
uint8_t* /* bitStream */,
int16_t /* bitStreamLenByte */,
int16_t* /* audio */,
int16_t* /* audioSamples */,
// TODO(leozwang): use int8_t here when WebRtc_Word8 is properly typed.
// http://code.google.com/p/webrtc/issues/detail?id=311
WebRtc_Word8* /* speechType */);
int32_t CodecDef(WebRtcNetEQ_CodecDef& codecDef, const CodecInst& codecInst);
void DestructEncoderSafe();
void DestructDecoderSafe();
int16_t InternalCreateEncoder();
int16_t InternalCreateDecoder();
void InternalDestructEncoderInst(void* ptrInst);
bool IsTrueStereoCodec();
int16_t SetBitRateSafe(const int32_t rate);
void SplitStereoPacket(uint8_t* payload, int32_t* payload_length);
CELT_encinst_t_* enc_inst_ptr_;
CELT_decinst_t_* dec_inst_ptr_;
uint16_t sampling_freq_;
int32_t bitrate_;
uint16_t channels_;
uint16_t dec_channels_;
};
} // namespace webrtc
#endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_SOURCE_ACM_CELT_H_

View File

@ -0,0 +1,142 @@
/*
* 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 "acm_cng.h"
#include "acm_codec_database.h"
#include "acm_common_defs.h"
#include "acm_neteq.h"
#include "trace.h"
#include "webrtc_cng.h"
#include "webrtc_neteq.h"
#include "webrtc_neteq_help_macros.h"
namespace webrtc {
ACMCNG::ACMCNG(WebRtc_Word16 codecID) {
_encoderInstPtr = NULL;
_decoderInstPtr = NULL;
_codecID = codecID;
_sampFreqHz = ACMCodecDB::CodecFreq(_codecID);
return;
}
ACMCNG::~ACMCNG() {
if (_encoderInstPtr != NULL) {
WebRtcCng_FreeEnc(_encoderInstPtr);
_encoderInstPtr = NULL;
}
if (_decoderInstPtr != NULL) {
WebRtcCng_FreeDec(_decoderInstPtr);
_decoderInstPtr = NULL;
}
return;
}
// CNG is not like a regular encoder, this function
// should not be called normally
// instead the following function is called from inside
// ACMGenericCodec::ProcessFrameVADDTX
WebRtc_Word16 ACMCNG::InternalEncode(WebRtc_UWord8* /* bitStream */,
WebRtc_Word16* /* bitStreamLenByte */) {
return -1;
}
WebRtc_Word16 ACMCNG::DecodeSafe(WebRtc_UWord8* /* bitStream */,
WebRtc_Word16 /* bitStreamLenByte */,
WebRtc_Word16* /* audio */,
WebRtc_Word16* /* audioSamples */,
WebRtc_Word8* /* speechType */) {
return 0;
}
// CNG is not like a regular encoder,
// this function should not be called normally
// instead the following function is called from inside
// ACMGenericCodec::ProcessFrameVADDTX
WebRtc_Word16 ACMCNG::InternalInitEncoder(
WebRtcACMCodecParams* /* codecParams */) {
return -1;
}
WebRtc_Word16 ACMCNG::InternalInitDecoder(
WebRtcACMCodecParams* /* codecParams */) {
return WebRtcCng_InitDec(_decoderInstPtr);
}
WebRtc_Word32 ACMCNG::CodecDef(WebRtcNetEQ_CodecDef& codecDef,
const CodecInst& codecInst) {
if (!_decoderInitialized) {
// TODO (tlegrand): log error
return -1;
}
// Fill up the structure by calling
// "SET_CODEC_PAR" & "SET_CNG_FUNCTION."
// Then return the structure back to NetEQ to add the codec to it's
// database.
if (_sampFreqHz == 8000 || _sampFreqHz == 16000 || _sampFreqHz == 32000 ||
_sampFreqHz == 48000) {
SET_CODEC_PAR((codecDef), kDecoderCNG, codecInst.pltype,
_decoderInstPtr, _sampFreqHz);
SET_CNG_FUNCTIONS((codecDef));
return 0;
} else {
return -1;
}
}
ACMGenericCodec* ACMCNG::CreateInstance(void) {
return NULL;
}
WebRtc_Word16 ACMCNG::InternalCreateEncoder() {
if (WebRtcCng_CreateEnc(&_encoderInstPtr) < 0) {
_encoderInstPtr = NULL;
return -1;
} else {
return 0;
}
}
void ACMCNG::DestructEncoderSafe() {
if (_encoderInstPtr != NULL) {
WebRtcCng_FreeEnc(_encoderInstPtr);
_encoderInstPtr = NULL;
}
_encoderExist = false;
_encoderInitialized = false;
}
WebRtc_Word16 ACMCNG::InternalCreateDecoder() {
if (WebRtcCng_CreateDec(&_decoderInstPtr) < 0) {
_decoderInstPtr = NULL;
return -1;
} else {
return 0;
}
}
void ACMCNG::DestructDecoderSafe() {
if (_decoderInstPtr != NULL) {
WebRtcCng_FreeDec(_decoderInstPtr);
_decoderInstPtr = NULL;
}
_decoderExist = false;
_decoderInitialized = false;
}
void ACMCNG::InternalDestructEncoderInst(void* ptrInst) {
if (ptrInst != NULL) {
WebRtcCng_FreeEnc(static_cast<CNG_enc_inst*>(ptrInst));
}
return;
}
} // namespace webrtc

View File

@ -0,0 +1,70 @@
/*
* 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_MAIN_SOURCE_ACM_CNG_H_
#define WEBRTC_MODULES_AUDIO_CODING_MAIN_SOURCE_ACM_CNG_H_
#include "acm_generic_codec.h"
// forward declaration
struct WebRtcCngEncInst;
struct WebRtcCngDecInst;
namespace webrtc {
class ACMCNG: public ACMGenericCodec {
public:
ACMCNG(WebRtc_Word16 codecID);
~ACMCNG();
// for FEC
ACMGenericCodec* CreateInstance(void);
WebRtc_Word16 InternalEncode(WebRtc_UWord8* bitstream,
WebRtc_Word16* bitStreamLenByte);
WebRtc_Word16 InternalInitEncoder(WebRtcACMCodecParams *codecParams);
WebRtc_Word16 InternalInitDecoder(WebRtcACMCodecParams *codecParams);
protected:
WebRtc_Word16 DecodeSafe(WebRtc_UWord8* bitStream,
WebRtc_Word16 bitStreamLenByte,
WebRtc_Word16* audio, WebRtc_Word16* audioSamples,
WebRtc_Word8* speechType);
WebRtc_Word32 CodecDef(WebRtcNetEQ_CodecDef& codecDef,
const CodecInst& codecInst);
void DestructEncoderSafe();
void DestructDecoderSafe();
WebRtc_Word16 InternalCreateEncoder();
WebRtc_Word16 InternalCreateDecoder();
void InternalDestructEncoderInst(void* ptrInst);
WebRtc_Word16 EnableDTX() {
return -1;
}
WebRtc_Word16 DisableDTX() {
return -1;
}
WebRtcCngEncInst* _encoderInstPtr;
WebRtcCngDecInst* _decoderInstPtr;
WebRtc_UWord16 _sampFreqHz;
};
} // namespace webrtc
#endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_SOURCE_ACM_CNG_H_

View File

@ -0,0 +1,988 @@
/*
* 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.
*/
/*
* This file generates databases with information about all supported audio
* codecs.
*/
// TODO(tlegrand): Change constant input pointers in all functions to constant
// references, where appropriate.
#include "acm_codec_database.h"
#include <stdio.h>
#include "acm_common_defs.h"
#include "trace.h"
// Includes needed to create the codecs.
// G.711, PCM mu-law and A-law.
#include "acm_pcma.h"
#include "acm_pcmu.h"
#include "g711_interface.h"
// CNG.
#include "acm_cng.h"
#include "webrtc_cng.h"
// NetEQ.
#include "webrtc_neteq.h"
#ifdef WEBRTC_CODEC_ISAC
#include "acm_isac.h"
#include "acm_isac_macros.h"
#include "isac.h"
#endif
#ifdef WEBRTC_CODEC_ISACFX
#include "acm_isac.h"
#include "acm_isac_macros.h"
#include "isacfix.h"
#endif
#ifdef WEBRTC_CODEC_PCM16
#include "pcm16b.h"
#include "acm_pcm16b.h"
#endif
#ifdef WEBRTC_CODEC_ILBC
#include "acm_ilbc.h"
#include "ilbc.h"
#endif
#ifdef WEBRTC_CODEC_AMR
#include "acm_amr.h"
#include "amr_interface.h"
#endif
#ifdef WEBRTC_CODEC_AMRWB
#include "acm_amrwb.h"
#include "amrwb_interface.h"
#endif
#ifdef WEBRTC_CODEC_CELT
#include "acm_celt.h"
#include "celt_interface.h"
#endif
#ifdef WEBRTC_CODEC_G722
#include "acm_g722.h"
#include "g722_interface.h"
#endif
#ifdef WEBRTC_CODEC_G722_1
#include "acm_g7221.h"
#include "g7221_interface.h"
#endif
#ifdef WEBRTC_CODEC_G722_1C
#include "acm_g7221c.h"
#include "g7221c_interface.h"
#endif
#ifdef WEBRTC_CODEC_G729
#include "acm_g729.h"
#include "g729_interface.h"
#endif
#ifdef WEBRTC_CODEC_G729_1
#include "acm_g7291.h"
#include "g7291_interface.h"
#endif
#ifdef WEBRTC_CODEC_GSMFR
#include "acm_gsmfr.h"
#include "gsmfr_interface.h"
#endif
#ifdef WEBRTC_CODEC_OPUS
#include "acm_opus.h"
#include "modules/audio_coding/codecs/opus/interface/opus_interface.h"
#endif
#ifdef WEBRTC_CODEC_SPEEX
#include "acm_speex.h"
#include "speex_interface.h"
#endif
#ifdef WEBRTC_CODEC_AVT
#include "acm_dtmf_playout.h"
#endif
#ifdef WEBRTC_CODEC_RED
#include "acm_red.h"
#endif
namespace webrtc {
// We dynamically allocate some of the dynamic payload types to the defined
// codecs. Note! There are a limited number of payload types. If more codecs
// are defined they will receive reserved fixed payload types (values 69-95).
const int kDynamicPayloadtypes[ACMCodecDB::kMaxNumCodecs] = {
105, 107, 108, 109, 111, 112, 113, 114, 115, 116, 117, 121,
92, 91, 90, 89, 88, 87, 86, 85, 84, 83, 82, 81,
80, 79, 78, 77, 76, 75, 74, 73, 72, 71, 70, 69,
68, 67
};
// Creates database with all supported codecs at compile time.
// Each entry needs the following parameters in the given order:
// payload type, name, sampling frequency, packet size in samples,
// number of channels, and default rate.
#if (defined(WEBRTC_CODEC_AMR) || defined(WEBRTC_CODEC_AMRWB) \
|| defined(WEBRTC_CODEC_CELT) || defined(WEBRTC_CODEC_G722_1) \
|| defined(WEBRTC_CODEC_G722_1C) || defined(WEBRTC_CODEC_G729_1) \
|| defined(WEBRTC_CODEC_PCM16) || defined(WEBRTC_CODEC_SPEEX))
static int count_database = 0;
#endif
const CodecInst ACMCodecDB::database_[] = {
#if (defined(WEBRTC_CODEC_ISAC) || defined(WEBRTC_CODEC_ISACFX))
{103, "ISAC", 16000, kIsacPacSize480, 1, kIsacWbDefaultRate},
# if (defined(WEBRTC_CODEC_ISAC))
{104, "ISAC", 32000, kIsacPacSize960, 1, kIsacSwbDefaultRate},
# endif
#endif
#ifdef WEBRTC_CODEC_PCM16
// Mono
{kDynamicPayloadtypes[count_database++], "L16", 8000, 80, 1, 128000},
{kDynamicPayloadtypes[count_database++], "L16", 16000, 160, 1, 256000},
{kDynamicPayloadtypes[count_database++], "L16", 32000, 320, 1, 512000},
// Stereo
{kDynamicPayloadtypes[count_database++], "L16", 8000, 80, 2, 128000},
{kDynamicPayloadtypes[count_database++], "L16", 16000, 160, 2, 256000},
{kDynamicPayloadtypes[count_database++], "L16", 32000, 320, 2, 512000},
#endif
// G.711, PCM mu-law and A-law.
// Mono
{0, "PCMU", 8000, 160, 1, 64000},
{8, "PCMA", 8000, 160, 1, 64000},
// Stereo
{110, "PCMU", 8000, 160, 2, 64000},
{118, "PCMA", 8000, 160, 2, 64000},
#ifdef WEBRTC_CODEC_ILBC
{102, "ILBC", 8000, 240, 1, 13300},
#endif
#ifdef WEBRTC_CODEC_AMR
{kDynamicPayloadtypes[count_database++], "AMR", 8000, 160, 1, 12200},
#endif
#ifdef WEBRTC_CODEC_AMRWB
{kDynamicPayloadtypes[count_database++], "AMR-WB", 16000, 320, 1, 20000},
#endif
#ifdef WEBRTC_CODEC_CELT
// Mono
{kDynamicPayloadtypes[count_database++], "CELT", 32000, 640, 1, 64000},
// Stereo
{kDynamicPayloadtypes[count_database++], "CELT", 32000, 640, 2, 64000},
#endif
#ifdef WEBRTC_CODEC_G722
// Mono
{9, "G722", 16000, 320, 1, 64000},
// Stereo
{119, "G722", 16000, 320, 2, 64000},
#endif
#ifdef WEBRTC_CODEC_G722_1
{kDynamicPayloadtypes[count_database++], "G7221", 16000, 320, 1, 32000},
{kDynamicPayloadtypes[count_database++], "G7221", 16000, 320, 1, 24000},
{kDynamicPayloadtypes[count_database++], "G7221", 16000, 320, 1, 16000},
#endif
#ifdef WEBRTC_CODEC_G722_1C
{kDynamicPayloadtypes[count_database++], "G7221", 32000, 640, 1, 48000},
{kDynamicPayloadtypes[count_database++], "G7221", 32000, 640, 1, 32000},
{kDynamicPayloadtypes[count_database++], "G7221", 32000, 640, 1, 24000},
#endif
#ifdef WEBRTC_CODEC_G729
{18, "G729", 8000, 240, 1, 8000},
#endif
#ifdef WEBRTC_CODEC_G729_1
{kDynamicPayloadtypes[count_database++], "G7291", 16000, 320, 1, 32000},
#endif
#ifdef WEBRTC_CODEC_GSMFR
{3, "GSM", 8000, 160, 1, 13200},
#endif
#ifdef WEBRTC_CODEC_OPUS
// Opus supports 48, 24, 16, 12, 8 kHz.
{120, "opus", 48000, 960, 1, 32000},
#endif
#ifdef WEBRTC_CODEC_SPEEX
{kDynamicPayloadtypes[count_database++], "speex", 8000, 160, 1, 11000},
{kDynamicPayloadtypes[count_database++], "speex", 16000, 320, 1, 22000},
#endif
// Comfort noise for four different sampling frequencies.
{13, "CN", 8000, 240, 1, 0},
{98, "CN", 16000, 480, 1, 0},
{99, "CN", 32000, 960, 1, 0},
{100, "CN", 48000, 1440, 1, 0},
#ifdef WEBRTC_CODEC_AVT
{106, "telephone-event", 8000, 240, 1, 0},
#endif
#ifdef WEBRTC_CODEC_RED
{127, "red", 8000, 0, 1, 0},
#endif
// To prevent compile errors due to trailing commas.
{-1, "Null", -1, -1, -1, -1}
};
// Create database with all codec settings at compile time.
// Each entry needs the following parameters in the given order:
// Number of allowed packet sizes, a vector with the allowed packet sizes,
// Basic block samples, max number of channels that are supported.
const ACMCodecDB::CodecSettings ACMCodecDB::codec_settings_[] = {
#if (defined(WEBRTC_CODEC_ISAC) || defined(WEBRTC_CODEC_ISACFX))
{2, {kIsacPacSize480, kIsacPacSize960}, 0, 1},
# if (defined(WEBRTC_CODEC_ISAC))
{1, {kIsacPacSize960}, 0, 1},
# endif
#endif
#ifdef WEBRTC_CODEC_PCM16
// Mono
{4, {80, 160, 240, 320}, 0, 2},
{4, {160, 320, 480, 640}, 0, 2},
{2, {320, 640}, 0, 2},
// Stereo
{4, {80, 160, 240, 320}, 0, 2},
{4, {160, 320, 480, 640}, 0, 2},
{2, {320, 640}, 0, 2},
#endif
// G.711, PCM mu-law and A-law.
// Mono
{6, {80, 160, 240, 320, 400, 480}, 0, 2},
{6, {80, 160, 240, 320, 400, 480}, 0, 2},
// Stereo
{6, {80, 160, 240, 320, 400, 480}, 0, 2},
{6, {80, 160, 240, 320, 400, 480}, 0, 2},
#ifdef WEBRTC_CODEC_ILBC
{4, {160, 240, 320, 480}, 0, 1},
#endif
#ifdef WEBRTC_CODEC_AMR
{3, {160, 320, 480}, 0, 1},
#endif
#ifdef WEBRTC_CODEC_AMRWB
{3, {320, 640, 960}, 0, 1},
#endif
#ifdef WEBRTC_CODEC_CELT
// Mono
{1, {640}, 0, 2},
// Stereo
{1, {640}, 0, 2},
#endif
#ifdef WEBRTC_CODEC_G722
// Mono
{6, {160, 320, 480, 640, 800, 960}, 0, 2},
// Stereo
{6, {160, 320, 480, 640, 800, 960}, 0, 2},
#endif
#ifdef WEBRTC_CODEC_G722_1
{1, {320}, 320, 1},
{1, {320}, 320, 1},
{1, {320}, 320, 1},
#endif
#ifdef WEBRTC_CODEC_G722_1C
{1, {640}, 640, 1},
{1, {640}, 640, 1},
{1, {640}, 640, 1},
#endif
#ifdef WEBRTC_CODEC_G729
{6, {80, 160, 240, 320, 400, 480}, 0, 1},
#endif
#ifdef WEBRTC_CODEC_G729_1
{3, {320, 640, 960}, 0, 1},
#endif
#ifdef WEBRTC_CODEC_GSMFR
{3, {160, 320, 480}, 160, 1},
#endif
#ifdef WEBRTC_CODEC_OPUS
// Opus supports frames shorter than 10ms,
// but it doesn't help us to use them.
{1, {960}, 0, 2},
#endif
#ifdef WEBRTC_CODEC_SPEEX
{3, {160, 320, 480}, 0, 1},
{3, {320, 640, 960}, 0, 1},
#endif
// Comfort noise for three different sampling frequencies.
{1, {240}, 240, 1},
{1, {480}, 480, 1},
{1, {960}, 960, 1},
{1, {1440}, 1440, 1},
#ifdef WEBRTC_CODEC_AVT
{1, {240}, 240, 1},
#endif
#ifdef WEBRTC_CODEC_RED
{1, {0}, 0, 1},
#endif
// To prevent compile errors due to trailing commas.
{-1, {-1}, -1, -1}
};
// Create a database of all NetEQ decoders at compile time.
const WebRtcNetEQDecoder ACMCodecDB::neteq_decoders_[] = {
#if (defined(WEBRTC_CODEC_ISAC) || defined(WEBRTC_CODEC_ISACFX))
kDecoderISAC,
# if (defined(WEBRTC_CODEC_ISAC))
kDecoderISACswb,
# endif
#endif
#ifdef WEBRTC_CODEC_PCM16
// Mono
kDecoderPCM16B,
kDecoderPCM16Bwb,
kDecoderPCM16Bswb32kHz,
// Stereo
kDecoderPCM16B_2ch,
kDecoderPCM16Bwb_2ch,
kDecoderPCM16Bswb32kHz_2ch,
#endif
// G.711, PCM mu-las and A-law.
// Mono
kDecoderPCMu,
kDecoderPCMa,
// Stereo
kDecoderPCMu_2ch,
kDecoderPCMa_2ch,
#ifdef WEBRTC_CODEC_ILBC
kDecoderILBC,
#endif
#ifdef WEBRTC_CODEC_AMR
kDecoderAMR,
#endif
#ifdef WEBRTC_CODEC_AMRWB
kDecoderAMRWB,
#endif
#ifdef WEBRTC_CODEC_CELT
// Mono
kDecoderCELT_32,
// Stereo
kDecoderCELT_32_2ch,
#endif
#ifdef WEBRTC_CODEC_G722
// Mono
kDecoderG722,
// Stereo
kDecoderG722_2ch,
#endif
#ifdef WEBRTC_CODEC_G722_1
kDecoderG722_1_32,
kDecoderG722_1_24,
kDecoderG722_1_16,
#endif
#ifdef WEBRTC_CODEC_G722_1C
kDecoderG722_1C_48,
kDecoderG722_1C_32,
kDecoderG722_1C_24,
#endif
#ifdef WEBRTC_CODEC_G729
kDecoderG729,
#endif
#ifdef WEBRTC_CODEC_G729_1
kDecoderG729_1,
#endif
#ifdef WEBRTC_CODEC_GSMFR
kDecoderGSMFR,
#endif
#ifdef WEBRTC_CODEC_OPUS
kDecoderOpus,
#endif
#ifdef WEBRTC_CODEC_SPEEX
kDecoderSPEEX_8,
kDecoderSPEEX_16,
#endif
// Comfort noise for three different sampling frequencies.
kDecoderCNG,
kDecoderCNG,
kDecoderCNG,
kDecoderCNG,
#ifdef WEBRTC_CODEC_AVT
kDecoderAVT,
#endif
#ifdef WEBRTC_CODEC_RED
kDecoderRED,
#endif
kDecoderReservedEnd
};
// Get codec information from database.
// TODO(tlegrand): replace memcpy with a pointer to the data base memory.
int ACMCodecDB::Codec(int codec_id, CodecInst* codec_inst) {
// Error check to see that codec_id is not out of bounds.
if ((codec_id < 0) || (codec_id >= kNumCodecs)) {
return -1;
}
// Copy database information for the codec to the output.
memcpy(codec_inst, &database_[codec_id], sizeof(CodecInst));
return 0;
}
// Enumerator for error codes when asking for codec database id.
enum {
kInvalidCodec = -10,
kInvalidPayloadtype = -30,
kInvalidPacketSize = -40,
kInvalidRate = -50
};
// Gets the codec id number from the database. If there is some mismatch in
// the codec settings, an error message will be recorded in the error string.
// NOTE! Only the first mismatch found will be recorded in the error string.
int ACMCodecDB::CodecNumber(const CodecInst* codec_inst, int* mirror_id,
char* err_message, int max_message_len_byte) {
int codec_id = ACMCodecDB::CodecNumber(codec_inst, mirror_id);
// Write error message if ACMCodecDB::CodecNumber() returned error.
if ((codec_id < 0) && (err_message != NULL)) {
char my_err_msg[1000];
if (codec_id == kInvalidCodec) {
sprintf(my_err_msg, "Call to ACMCodecDB::CodecNumber failed, Codec not "
"found");
} else if (codec_id == kInvalidPayloadtype) {
sprintf(my_err_msg, "Call to ACMCodecDB::CodecNumber failed, payload "
"number %d is out of range for %s", codec_inst->pltype,
codec_inst->plname);
} else if (codec_id == kInvalidPacketSize) {
sprintf(my_err_msg, "Call to ACMCodecDB::CodecNumber failed, Packet "
"size is out of range for %s", codec_inst->plname);
} else if (codec_id == kInvalidRate) {
sprintf(my_err_msg, "Call to ACMCodecDB::CodecNumber failed, rate=%d "
"is not a valid rate for %s", codec_inst->rate,
codec_inst->plname);
} else {
// Other error
sprintf(my_err_msg, "invalid codec parameters to be registered, "
"ACMCodecDB::CodecNumber failed");
}
strncpy(err_message, my_err_msg, max_message_len_byte - 1);
// make sure that the message is null-terminated.
err_message[max_message_len_byte - 1] = '\0';
}
return codec_id;
}
// Gets the codec id number from the database. If there is some mismatch in
// the codec settings, the function will return an error code.
// NOTE! The first mismatch found will generate the return value.
int ACMCodecDB::CodecNumber(const CodecInst* codec_inst, int* mirror_id) {
// Look for a matching codec in the database.
int codec_id = CodecId(codec_inst);
// Checks if we found a matching codec.
if (codec_id == -1) {
return kInvalidCodec;
}
// Checks the validity of payload type
if (!ValidPayloadType(codec_inst->pltype)) {
return kInvalidPayloadtype;
}
// Comfort Noise is special case, packet-size & rate is not checked.
if (STR_CASE_CMP(database_[codec_id].plname, "CN") == 0) {
*mirror_id = codec_id;
return codec_id;
}
// RED is special case, packet-size & rate is not checked.
if (STR_CASE_CMP(database_[codec_id].plname, "red") == 0) {
*mirror_id = codec_id;
return codec_id;
}
// Checks the validity of packet size.
if (codec_settings_[codec_id].num_packet_sizes > 0) {
bool packet_size_ok = false;
int i;
int packet_size_samples;
for (i = 0; i < codec_settings_[codec_id].num_packet_sizes; i++) {
packet_size_samples =
codec_settings_[codec_id].packet_sizes_samples[i];
if (codec_inst->pacsize == packet_size_samples) {
packet_size_ok = true;
break;
}
}
if (!packet_size_ok) {
return kInvalidPacketSize;
}
}
if (codec_inst->pacsize < 1) {
return kInvalidPacketSize;
}
// Check the validity of rate. Codecs with multiple rates have their own
// function for this.
*mirror_id = codec_id;
if (STR_CASE_CMP("isac", codec_inst->plname) == 0) {
if (IsISACRateValid(codec_inst->rate)) {
// Set mirrorID to iSAC WB which is only created once to be used both for
// iSAC WB and SWB, because they need to share struct.
*mirror_id = kISAC;
return codec_id;
} else {
return kInvalidRate;
}
} else if (STR_CASE_CMP("ilbc", codec_inst->plname) == 0) {
return IsILBCRateValid(codec_inst->rate, codec_inst->pacsize)
? codec_id : kInvalidRate;
} else if (STR_CASE_CMP("amr", codec_inst->plname) == 0) {
return IsAMRRateValid(codec_inst->rate)
? codec_id : kInvalidRate;
} else if (STR_CASE_CMP("amr-wb", codec_inst->plname) == 0) {
return IsAMRwbRateValid(codec_inst->rate)
? codec_id : kInvalidRate;
} else if (STR_CASE_CMP("g7291", codec_inst->plname) == 0) {
return IsG7291RateValid(codec_inst->rate)
? codec_id : kInvalidRate;
} else if (STR_CASE_CMP("opus", codec_inst->plname) == 0) {
return IsOpusRateValid(codec_inst->rate)
? codec_id : kInvalidRate;
} else if (STR_CASE_CMP("speex", codec_inst->plname) == 0) {
return IsSpeexRateValid(codec_inst->rate)
? codec_id : kInvalidRate;
} else if (STR_CASE_CMP("celt", codec_inst->plname) == 0) {
return IsCeltRateValid(codec_inst->rate)
? codec_id : kInvalidRate;
}
return IsRateValid(codec_id, codec_inst->rate) ?
codec_id : kInvalidRate;
}
// Looks for a matching payload name, frequency, and channels in the
// codec list. Need to check all three since some codecs have several codec
// entries with different frequencies and/or channels.
// Does not check other codec settings, such as payload type and packet size.
// Returns the id of the codec, or -1 if no match is found.
int ACMCodecDB::CodecId(const CodecInst* codec_inst) {
return (CodecId(codec_inst->plname, codec_inst->plfreq,
codec_inst->channels));
}
int ACMCodecDB::CodecId(const char* payload_name, int frequency, int channels) {
for (int id = 0; id < kNumCodecs; id++) {
bool name_match = false;
bool frequency_match = false;
bool channels_match = false;
// Payload name, sampling frequency and number of channels need to match.
// NOTE! If |frequency| is -1, the frequency is not applicable, and is
// always treated as true, like for RED.
name_match = (STR_CASE_CMP(database_[id].plname, payload_name) == 0);
frequency_match = (frequency == database_[id].plfreq) || (frequency == -1);
channels_match = (channels == database_[id].channels);
if (name_match && frequency_match && channels_match) {
// We have found a matching codec in the list.
return id;
}
}
// We didn't find a matching codec.
return -1;
}
// Gets codec id number, and mirror id, from database for the receiver.
int ACMCodecDB::ReceiverCodecNumber(const CodecInst* codec_inst,
int* mirror_id) {
// Look for a matching codec in the database.
int codec_id = CodecId(codec_inst);
// Set |mirror_id| to |codec_id|, except for iSAC. In case of iSAC we always
// set |mirror_id| to iSAC WB (kISAC) which is only created once to be used
// both for iSAC WB and SWB, because they need to share struct.
if (STR_CASE_CMP(codec_inst->plname, "ISAC") != 0) {
*mirror_id = codec_id;
} else {
*mirror_id = kISAC;
}
return codec_id;
}
// Returns the codec sampling frequency for codec with id = "codec_id" in
// database.
int ACMCodecDB::CodecFreq(int codec_id) {
// Error check to see that codec_id is not out of bounds.
if (codec_id < 0 || codec_id >= kNumCodecs) {
return -1;
}
return database_[codec_id].plfreq;
}
// Returns the codec's basic coding block size in samples.
int ACMCodecDB::BasicCodingBlock(int codec_id) {
// Error check to see that codec_id is not out of bounds.
if (codec_id < 0 || codec_id >= kNumCodecs) {
return -1;
}
return codec_settings_[codec_id].basic_block_samples;
}
// Returns the NetEQ decoder database.
const WebRtcNetEQDecoder* ACMCodecDB::NetEQDecoders() {
return neteq_decoders_;
}
// Gets mirror id. The Id is used for codecs sharing struct for settings that
// need different payload types.
int ACMCodecDB::MirrorID(int codec_id) {
if (STR_CASE_CMP(database_[codec_id].plname, "isac") == 0) {
return kISAC;
} else {
return codec_id;
}
}
// Creates memory/instance for storing codec state.
ACMGenericCodec* ACMCodecDB::CreateCodecInstance(const CodecInst* codec_inst) {
// All we have support for right now.
if (!STR_CASE_CMP(codec_inst->plname, "ISAC")) {
#if (defined(WEBRTC_CODEC_ISAC) || defined(WEBRTC_CODEC_ISACFX))
return new ACMISAC(kISAC);
#endif
} else if (!STR_CASE_CMP(codec_inst->plname, "PCMU")) {
if (codec_inst->channels == 1) {
return new ACMPCMU(kPCMU);
} else {
return new ACMPCMU(kPCMU_2ch);
}
} else if (!STR_CASE_CMP(codec_inst->plname, "PCMA")) {
if (codec_inst->channels == 1) {
return new ACMPCMA(kPCMA);
} else {
return new ACMPCMA(kPCMA_2ch);
}
} else if (!STR_CASE_CMP(codec_inst->plname, "ILBC")) {
#ifdef WEBRTC_CODEC_ILBC
return new ACMILBC(kILBC);
#endif
} else if (!STR_CASE_CMP(codec_inst->plname, "AMR")) {
#ifdef WEBRTC_CODEC_AMR
return new ACMAMR(kGSMAMR);
#endif
} else if (!STR_CASE_CMP(codec_inst->plname, "AMR-WB")) {
#ifdef WEBRTC_CODEC_AMRWB
return new ACMAMRwb(kGSMAMRWB);
#endif
} else if (!STR_CASE_CMP(codec_inst->plname, "CELT")) {
#ifdef WEBRTC_CODEC_CELT
if (codec_inst->channels == 1) {
return new ACMCELT(kCELT32);
} else {
return new ACMCELT(kCELT32_2ch);
}
#endif
} else if (!STR_CASE_CMP(codec_inst->plname, "G722")) {
#ifdef WEBRTC_CODEC_G722
if (codec_inst->channels == 1) {
return new ACMG722(kG722);
} else {
return new ACMG722(kG722_2ch);
}
#endif
} else if (!STR_CASE_CMP(codec_inst->plname, "G7221")) {
switch (codec_inst->plfreq) {
case 16000: {
#ifdef WEBRTC_CODEC_G722_1
int codec_id;
switch (codec_inst->rate) {
case 16000 : {
codec_id = kG722_1_16;
break;
}
case 24000 : {
codec_id = kG722_1_24;
break;
}
case 32000 : {
codec_id = kG722_1_32;
break;
}
default: {
return NULL;
}
return new ACMG722_1(codec_id);
}
#endif
}
case 32000: {
#ifdef WEBRTC_CODEC_G722_1C
int codec_id;
switch (codec_inst->rate) {
case 24000 : {
codec_id = kG722_1C_24;
break;
}
case 32000 : {
codec_id = kG722_1C_32;
break;
}
case 48000 : {
codec_id = kG722_1C_48;
break;
}
default: {
return NULL;
}
return new ACMG722_1C(codec_id);
}
#endif
}
}
} else if (!STR_CASE_CMP(codec_inst->plname, "CN")) {
// For CN we need to check sampling frequency to know what codec to create.
int codec_id;
switch (codec_inst->plfreq) {
case 8000: {
codec_id = kCNNB;
break;
}
case 16000: {
codec_id = kCNWB;
break;
}
case 32000: {
codec_id = kCNSWB;
break;
}
case 48000: {
codec_id = kCNFB;
break;
}
default: {
return NULL;
}
}
return new ACMCNG(codec_id);
} else if (!STR_CASE_CMP(codec_inst->plname, "G729")) {
#ifdef WEBRTC_CODEC_G729
return new ACMG729(kG729);
#endif
} else if (!STR_CASE_CMP(codec_inst->plname, "G7291")) {
#ifdef WEBRTC_CODEC_G729_1
return new ACMG729_1(kG729_1);
#endif
} else if (!STR_CASE_CMP(codec_inst->plname, "opus")) {
#ifdef WEBRTC_CODEC_OPUS
return new ACMOpus(kOpus);
#endif
} else if (!STR_CASE_CMP(codec_inst->plname, "speex")) {
#ifdef WEBRTC_CODEC_SPEEX
int codec_id;
switch (codec_inst->plfreq) {
case 8000: {
codec_id = kSPEEX8;
break;
}
case 16000: {
codec_id = kSPEEX16;
break;
}
default: {
return NULL;
}
}
return new ACMSPEEX(codec_id);
#endif
} else if (!STR_CASE_CMP(codec_inst->plname, "CN")) {
// For CN we need to check sampling frequency to know what codec to create.
int codec_id;
switch (codec_inst->plfreq) {
case 8000: {
codec_id = kCNNB;
break;
}
case 16000: {
codec_id = kCNWB;
break;
}
case 32000: {
codec_id = kCNSWB;
break;
}
case 48000: {
codec_id = kCNFB;
break;
}
default: {
return NULL;
}
}
return new ACMCNG(codec_id);
} else if (!STR_CASE_CMP(codec_inst->plname, "L16")) {
#ifdef WEBRTC_CODEC_PCM16
// For L16 we need to check sampling frequency to know what codec to create.
int codec_id;
if (codec_inst->channels == 1) {
switch (codec_inst->plfreq) {
case 8000: {
codec_id = kPCM16B;
break;
}
case 16000: {
codec_id = kPCM16Bwb;
break;
}
case 32000: {
codec_id = kPCM16Bswb32kHz;
break;
}
default: {
return NULL;
}
}
} else {
switch (codec_inst->plfreq) {
case 8000: {
codec_id = kPCM16B_2ch;
break;
}
case 16000: {
codec_id = kPCM16Bwb_2ch;
break;
}
case 32000: {
codec_id = kPCM16Bswb32kHz_2ch;
break;
}
default: {
return NULL;
}
}
}
return new ACMPCM16B(codec_id);
#endif
} else if (!STR_CASE_CMP(codec_inst->plname, "telephone-event")) {
#ifdef WEBRTC_CODEC_AVT
return new ACMDTMFPlayout(kAVT);
#endif
} else if (!STR_CASE_CMP(codec_inst->plname, "red")) {
#ifdef WEBRTC_CODEC_RED
return new ACMRED(kRED);
#endif
}
return NULL;
}
// Checks if the bitrate is valid for the codec.
bool ACMCodecDB::IsRateValid(int codec_id, int rate) {
if (database_[codec_id].rate == rate) {
return true;
} else {
return false;
}
}
// Checks if the bitrate is valid for iSAC.
bool ACMCodecDB::IsISACRateValid(int rate) {
if ((rate == -1) || ((rate <= 56000) && (rate >= 10000))) {
return true;
} else {
return false;
}
}
// Checks if the bitrate is valid for iLBC.
bool ACMCodecDB::IsILBCRateValid(int rate, int frame_size_samples) {
if (((frame_size_samples == 240) || (frame_size_samples == 480)) &&
(rate == 13300)) {
return true;
} else if (((frame_size_samples == 160) || (frame_size_samples == 320)) &&
(rate == 15200)) {
return true;
} else {
return false;
}
}
// Check if the bitrate is valid for the GSM-AMR.
bool ACMCodecDB::IsAMRRateValid(int rate) {
switch (rate) {
case 4750:
case 5150:
case 5900:
case 6700:
case 7400:
case 7950:
case 10200:
case 12200: {
return true;
}
default: {
return false;
}
}
}
// Check if the bitrate is valid for GSM-AMR-WB.
bool ACMCodecDB::IsAMRwbRateValid(int rate) {
switch (rate) {
case 7000:
case 9000:
case 12000:
case 14000:
case 16000:
case 18000:
case 20000:
case 23000:
case 24000: {
return true;
}
default: {
return false;
}
}
}
// Check if the bitrate is valid for G.729.1.
bool ACMCodecDB::IsG7291RateValid(int rate) {
switch (rate) {
case 8000:
case 12000:
case 14000:
case 16000:
case 18000:
case 20000:
case 22000:
case 24000:
case 26000:
case 28000:
case 30000:
case 32000: {
return true;
}
default: {
return false;
}
}
}
// Checks if the bitrate is valid for Speex.
bool ACMCodecDB::IsSpeexRateValid(int rate) {
if (rate > 2000) {
return true;
} else {
return false;
}
}
// Checks if the bitrate is valid for Opus.
bool ACMCodecDB::IsOpusRateValid(int rate) {
if ((rate < 6000) || (rate > 510000)) {
return false;
}
return true;
}
// Checks if the bitrate is valid for Celt.
bool ACMCodecDB::IsCeltRateValid(int rate) {
if ((rate >= 48000) && (rate <= 128000)) {
return true;
} else {
return false;
}
}
// Checks if the payload type is in the valid range.
bool ACMCodecDB::ValidPayloadType(int payload_type) {
if ((payload_type < 0) || (payload_type > 127)) {
return false;
}
return true;
}
} // namespace webrtc

View File

@ -0,0 +1,332 @@
/*
* 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.
*/
/*
* This file generates databases with information about all supported audio
* codecs.
*/
#ifndef WEBRTC_MODULES_AUDIO_CODING_MAIN_SOURCE_ACM_CODEC_DATABASE_H_
#define WEBRTC_MODULES_AUDIO_CODING_MAIN_SOURCE_ACM_CODEC_DATABASE_H_
#include "acm_generic_codec.h"
#include "common_types.h"
#include "webrtc_neteq.h"
namespace webrtc {
// TODO(tlegrand): replace class ACMCodecDB with a namespace.
class ACMCodecDB {
public:
// Enum with array indexes for the supported codecs. NOTE! The order MUST
// be the same as when creating the database in acm_codec_database.cc.
enum {
kNone = -1
#if (defined(WEBRTC_CODEC_ISAC) || defined(WEBRTC_CODEC_ISACFX))
, kISAC
# if (defined(WEBRTC_CODEC_ISAC))
, kISACSWB
# endif
#endif
#ifdef WEBRTC_CODEC_PCM16
// Mono
, kPCM16B
, kPCM16Bwb
, kPCM16Bswb32kHz
// Stereo
, kPCM16B_2ch
, kPCM16Bwb_2ch
, kPCM16Bswb32kHz_2ch
#endif
// Mono
, kPCMU
, kPCMA
// Stereo
, kPCMU_2ch
, kPCMA_2ch
#ifdef WEBRTC_CODEC_ILBC
, kILBC
#endif
#ifdef WEBRTC_CODEC_AMR
, kGSMAMR
#endif
#ifdef WEBRTC_CODEC_AMRWB
, kGSMAMRWB
#endif
#ifdef WEBRTC_CODEC_CELT
// Mono
, kCELT32
// Stereo
, kCELT32_2ch
#endif
#ifdef WEBRTC_CODEC_G722
// Mono
, kG722
// Stereo
, kG722_2ch
#endif
#ifdef WEBRTC_CODEC_G722_1
, kG722_1_32
, kG722_1_24
, kG722_1_16
#endif
#ifdef WEBRTC_CODEC_G722_1C
, kG722_1C_48
, kG722_1C_32
, kG722_1C_24
#endif
#ifdef WEBRTC_CODEC_G729
, kG729
#endif
#ifdef WEBRTC_CODEC_G729_1
, kG729_1
#endif
#ifdef WEBRTC_CODEC_GSMFR
, kGSMFR
#endif
#ifdef WEBRTC_CODEC_OPUS
, kOpus
#endif
#ifdef WEBRTC_CODEC_SPEEX
, kSPEEX8
, kSPEEX16
#endif
, kCNNB
, kCNWB
, kCNSWB
, kCNFB
#ifdef WEBRTC_CODEC_AVT
, kAVT
#endif
#ifdef WEBRTC_CODEC_RED
, kRED
#endif
, kNumCodecs
};
// Set unsupported codecs to -1
#ifndef WEBRTC_CODEC_ISAC
enum {kISACSWB = -1};
# ifndef WEBRTC_CODEC_ISACFX
enum {kISAC = -1};
# endif
#endif
#ifndef WEBRTC_CODEC_PCM16
// Mono
enum {kPCM16B = -1};
enum {kPCM16Bwb = -1};
enum {kPCM16Bswb32kHz = -1};
// Stereo
enum {kPCM16B_2ch = -1};
enum {kPCM16Bwb_2ch = -1};
enum {kPCM16Bswb32kHz_2ch = -1};
#endif
// 48 kHz not supported, always set to -1.
enum {kPCM16Bswb48kHz = -1};
#ifndef WEBRTC_CODEC_ILBC
enum {kILBC = -1};
#endif
#ifndef WEBRTC_CODEC_AMR
enum {kGSMAMR = -1};
#endif
#ifndef WEBRTC_CODEC_AMRWB
enum {kGSMAMRWB = -1};
#endif
#ifndef WEBRTC_CODEC_CELT
// Mono
enum {kCELT32 = -1};
// Stereo
enum {kCELT32_2ch = -1};
#endif
#ifndef WEBRTC_CODEC_G722
// Mono
enum {kG722 = -1};
// Stereo
enum {kG722_2ch = -1};
#endif
#ifndef WEBRTC_CODEC_G722_1
enum {kG722_1_32 = -1};
enum {kG722_1_24 = -1};
enum {kG722_1_16 = -1};
#endif
#ifndef WEBRTC_CODEC_G722_1C
enum {kG722_1C_48 = -1};
enum {kG722_1C_32 = -1};
enum {kG722_1C_24 = -1};
#endif
#ifndef WEBRTC_CODEC_G729
enum {kG729 = -1};
#endif
#ifndef WEBRTC_CODEC_G729_1
enum {kG729_1 = -1};
#endif
#ifndef WEBRTC_CODEC_GSMFR
enum {kGSMFR = -1};
#endif
#ifndef WEBRTC_CODEC_SPEEX
enum {kSPEEX8 = -1};
enum {kSPEEX16 = -1};
#endif
#ifndef WEBRTC_CODEC_OPUS
enum {kOpus = -1};
#endif
#ifndef WEBRTC_CODEC_AVT
enum {kAVT = -1};
#endif
#ifndef WEBRTC_CODEC_RED
enum {kRED = -1};
#endif
// kMaxNumCodecs - Maximum number of codecs that can be activated in one
// build.
// kMaxNumPacketSize - Maximum number of allowed packet sizes for one codec.
// These might need to be increased if adding a new codec to the database
static const int kMaxNumCodecs = 50;
static const int kMaxNumPacketSize = 6;
// Codec specific settings
//
// num_packet_sizes - number of allowed packet sizes.
// packet_sizes_samples - list of the allowed packet sizes.
// basic_block_samples - assigned a value different from 0 if the codec
// requires to be fed with a specific number of samples
// that can be different from packet size.
// channel_support - number of channels supported to encode;
// 1 = mono, 2 = stereo, etc.
struct CodecSettings {
int num_packet_sizes;
int packet_sizes_samples[kMaxNumPacketSize];
int basic_block_samples;
int channel_support;
};
// Gets codec information from database at the position in database given by
// [codec_id].
// Input:
// [codec_id] - number that specifies at what position in the database to
// get the information.
// Output:
// [codec_inst] - filled with information about the codec.
// Return:
// 0 if successful, otherwise -1.
static int Codec(int codec_id, CodecInst* codec_inst);
// Returns codec id and mirror id from database, given the information
// received in the input [codec_inst]. Mirror id is a number that tells
// where to find the codec's memory (instance). The number is either the
// same as codec id (most common), or a number pointing at a different
// entry in the database, if the codec has several entries with different
// payload types. This is used for codecs that must share one struct even if
// the payload type differs.
// One example is the codec iSAC which has the same struct for both 16 and
// 32 khz, but they have different entries in the database. Let's say the
// function is called with iSAC 32kHz. The function will return 1 as that is
// the entry in the data base, and [mirror_id] = 0, as that is the entry for
// iSAC 16 kHz, which holds the shared memory.
// Input:
// [codec_inst] - Information about the codec for which we require the
// database id.
// Output:
// [mirror_id] - mirror id, which most often is the same as the return
// value, see above.
// [err_message] - if present, in the event of a mismatch found between the
// input and the database, a descriptive error message is
// written here.
// [err_message] - if present, the length of error message is returned here.
// Return:
// codec id if successful, otherwise < 0.
static int CodecNumber(const CodecInst* codec_inst, int* mirror_id,
char* err_message, int max_message_len_byte);
static int CodecNumber(const CodecInst* codec_inst, int* mirror_id);
static int CodecId(const CodecInst* codec_inst);
static int CodecId(const char* payload_name, int frequency, int channels);
static int ReceiverCodecNumber(const CodecInst* codec_inst, int* mirror_id);
// Returns the codec sampling frequency for codec with id = "codec_id" in
// database.
// TODO(tlegrand): Check if function is needed, or if we can change
// to access database directly.
// Input:
// [codec_id] - number that specifies at what position in the database to
// get the information.
// Return:
// codec sampling frequency if successful, otherwise -1.
static int CodecFreq(int codec_id);
// Return the codec's basic coding block size in samples.
// TODO(tlegrand): Check if function is needed, or if we can change
// to access database directly.
// Input:
// [codec_id] - number that specifies at what position in the database to
// get the information.
// Return:
// codec basic block size if successful, otherwise -1.
static int BasicCodingBlock(int codec_id);
// Returns the NetEQ decoder database.
static const WebRtcNetEQDecoder* NetEQDecoders();
// Returns mirror id, which is a number that tells where to find the codec's
// memory (instance). It is either the same as codec id (most common), or a
// number pointing at a different entry in the database, if the codec have
// several entries with different payload types. This is used for codecs that
// must share struct even if the payload type differs.
// TODO(tlegrand): Check if function is needed, or if we can change
// to access database directly.
// Input:
// [codec_id] - number that specifies codec's position in the database.
// Return:
// Mirror id on success, otherwise -1.
static int MirrorID(int codec_id);
// Create memory/instance for storing codec state.
// Input:
// [codec_inst] - information about codec. Only name of codec, "plname", is
// used in this function.
static ACMGenericCodec* CreateCodecInstance(const CodecInst* codec_inst);
// Checks if the bitrate is valid for the codec.
// Input:
// [codec_id] - number that specifies codec's position in the database.
// [rate] - bitrate to check.
// [frame_size_samples] - (used for iLBC) specifies which frame size to go
// with the rate.
static bool IsRateValid(int codec_id, int rate);
static bool IsISACRateValid(int rate);
static bool IsILBCRateValid(int rate, int frame_size_samples);
static bool IsAMRRateValid(int rate);
static bool IsAMRwbRateValid(int rate);
static bool IsG7291RateValid(int rate);
static bool IsSpeexRateValid(int rate);
static bool IsOpusRateValid(int rate);
static bool IsCeltRateValid(int rate);
// Check if the payload type is valid, meaning that it is in the valid range
// of 0 to 127.
// Input:
// [payload_type] - payload type.
static bool ValidPayloadType(int payload_type);
// Databases with information about the supported codecs
// database_ - stored information about all codecs: payload type, name,
// sampling frequency, packet size in samples, default channel
// support, and default rate.
// codec_settings_ - stored codec settings: number of allowed packet sizes,
// a vector with the allowed packet sizes, basic block
// samples, and max number of channels that are supported.
// neteq_decoders_ - list of supported decoders in NetEQ.
static const CodecInst database_[kMaxNumCodecs];
static const CodecSettings codec_settings_[kMaxNumCodecs];
static const WebRtcNetEQDecoder neteq_decoders_[kMaxNumCodecs];
};
} // namespace webrtc
#endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_SOURCE_ACM_CODEC_DATABASE_H_

View File

@ -0,0 +1,116 @@
/*
* 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_MAIN_SOURCE_ACM_COMMON_DEFS_H_
#define WEBRTC_MODULES_AUDIO_CODING_MAIN_SOURCE_ACM_COMMON_DEFS_H_
#include <string.h>
#include "audio_coding_module_typedefs.h"
#include "common_types.h"
#include "engine_configurations.h"
#include "typedefs.h"
// Checks for enabled codecs, we prevent enabling codecs which are not
// compatible.
#if ((defined WEBRTC_CODEC_ISAC) && (defined WEBRTC_CODEC_ISACFX))
#error iSAC and iSACFX codecs cannot be enabled at the same time
#endif
#ifdef WIN32
// OS-dependent case-insensitive string comparison
#define STR_CASE_CMP(x,y) ::_stricmp(x,y)
#else
// OS-dependent case-insensitive string comparison
#define STR_CASE_CMP(x,y) ::strcasecmp(x,y)
#endif
namespace webrtc {
// 60 ms is the maximum block size we support. An extra 20 ms is considered
// for safety if process() method is not called when it should be, i.e. we
// accept 20 ms of jitter. 80 ms @ 32 kHz (super wide-band) is 2560 samples.
#define AUDIO_BUFFER_SIZE_W16 2560
// There is one timestamp per each 10 ms of audio
// the audio buffer, at max, may contain 32 blocks of 10ms
// audio if the sampling frequency is 8000 Hz (80 samples per block).
// Therefore, The size of the buffer where we keep timestamps
// is defined as follows
#define TIMESTAMP_BUFFER_SIZE_W32 (AUDIO_BUFFER_SIZE_W16/80)
// The maximum size of a payload, that is 60 ms of PCM-16 @ 32 kHz stereo
#define MAX_PAYLOAD_SIZE_BYTE 7680
// General codec specific defines
const int kIsacWbDefaultRate = 32000;
const int kIsacSwbDefaultRate = 56000;
const int kIsacPacSize480 = 480;
const int kIsacPacSize960 = 960;
// An encoded bit-stream is labeled by one of the following enumerators.
//
// kNoEncoding : There has been no encoding.
// kActiveNormalEncoded : Active audio frame coded by the codec.
// kPassiveNormalEncoded : Passive audio frame coded by the codec.
// kPassiveDTXNB : Passive audio frame coded by narrow-band CN.
// kPassiveDTXWB : Passive audio frame coded by wide-band CN.
// kPassiveDTXSWB : Passive audio frame coded by super-wide-band CN.
// kPassiveDTXFB : Passive audio frame coded by full-band CN.
enum WebRtcACMEncodingType {
kNoEncoding,
kActiveNormalEncoded,
kPassiveNormalEncoded,
kPassiveDTXNB,
kPassiveDTXWB,
kPassiveDTXSWB,
kPassiveDTXFB
};
// A structure which contains codec parameters. For instance, used when
// initializing encoder and decoder.
//
// codecInstant : c.f. common_types.h
// enableDTX : set true to enable DTX. If codec does not have
// internal DTX, this will enable VAD.
// enableVAD : set true to enable VAD.
// vadMode : VAD mode, c.f. audio_coding_module_typedefs.h
// for possible values.
struct WebRtcACMCodecParams {
CodecInst codecInstant;
bool enableDTX;
bool enableVAD;
ACMVADMode vadMode;
};
// A structure that encapsulates audio buffer and related parameters
// used for synchronization of audio of two ACMs.
//
// inAudio : same as ACMGenericCodec::_inAudio
// inAudioIxRead : same as ACMGenericCodec::_inAudioIxRead
// inAudioIxWrite : same as ACMGenericCodec::_inAudioIxWrite
// inTimestamp : same as ACMGenericCodec::_inTimestamp
// inTimestampIxWrite : same as ACMGenericCodec::_inTImestampIxWrite
// lastTimestamp : same as ACMGenericCodec::_lastTimestamp
// lastInTimestamp : same as AudioCodingModuleImpl::_lastInTimestamp
//
struct WebRtcACMAudioBuff {
WebRtc_Word16 inAudio[AUDIO_BUFFER_SIZE_W16];
WebRtc_Word16 inAudioIxRead;
WebRtc_Word16 inAudioIxWrite;
WebRtc_UWord32 inTimestamp[TIMESTAMP_BUFFER_SIZE_W32];
WebRtc_Word16 inTimestampIxWrite;
WebRtc_UWord32 lastTimestamp;
WebRtc_UWord32 lastInTimestamp;
};
} // namespace webrtc
#endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_SOURCE_ACM_COMMON_DEFS_H_

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.
*/
#include "acm_dtmf_detection.h"
#include "audio_coding_module_typedefs.h"
namespace webrtc {
ACMDTMFDetection::ACMDTMFDetection() {}
ACMDTMFDetection::~ACMDTMFDetection() {}
WebRtc_Word16 ACMDTMFDetection::Enable(ACMCountries /* cpt */) {
return -1;
}
WebRtc_Word16 ACMDTMFDetection::Disable() {
return -1;
}
WebRtc_Word16 ACMDTMFDetection::Detect(
const WebRtc_Word16* /* inAudioBuff */,
const WebRtc_UWord16 /* inBuffLenWord16 */,
const WebRtc_Word32 /* inFreqHz */,
bool& /* toneDetected */,
WebRtc_Word16& /* tone */) {
return -1;
}
} // namespace webrtc

View File

@ -0,0 +1,38 @@
/*
* 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_MAIN_SOURCE_ACM_DTMF_DETECTION_H_
#define WEBRTC_MODULES_AUDIO_CODING_MAIN_SOURCE_ACM_DTMF_DETECTION_H_
#include "acm_resampler.h"
#include "audio_coding_module_typedefs.h"
#include "typedefs.h"
namespace webrtc {
class ACMDTMFDetection {
public:
ACMDTMFDetection();
~ACMDTMFDetection();
WebRtc_Word16 Enable(ACMCountries cpt = ACMDisableCountryDetection);
WebRtc_Word16 Disable();
WebRtc_Word16 Detect(const WebRtc_Word16* inAudioBuff,
const WebRtc_UWord16 inBuffLenWord16,
const WebRtc_Word32 inFreqHz,
bool& toneDetected,
WebRtc_Word16& tone);
private:
ACMResampler _resampler;
};
} // namespace webrtc
#endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_SOURCE_ACM_DTMF_DETECTION_H_

View File

@ -0,0 +1,164 @@
/*
* 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 "acm_dtmf_playout.h"
#include "acm_common_defs.h"
#include "acm_neteq.h"
#include "trace.h"
#include "webrtc_neteq.h"
#include "webrtc_neteq_help_macros.h"
namespace webrtc {
#ifndef WEBRTC_CODEC_AVT
ACMDTMFPlayout::ACMDTMFPlayout(
WebRtc_Word16 /* codecID */) {
return;
}
ACMDTMFPlayout::~ACMDTMFPlayout() {
return;
}
WebRtc_Word16 ACMDTMFPlayout::InternalEncode(
WebRtc_UWord8* /* bitStream */,
WebRtc_Word16* /* bitStreamLenByte */) {
return -1;
}
WebRtc_Word16 ACMDTMFPlayout::DecodeSafe(WebRtc_UWord8* /* bitStream */,
WebRtc_Word16 /* bitStreamLenByte */,
WebRtc_Word16* /* audio */,
WebRtc_Word16* /* audioSamples */,
WebRtc_Word8* /* speechType */) {
return -1;
}
WebRtc_Word16 ACMDTMFPlayout::InternalInitEncoder(
WebRtcACMCodecParams* /* codecParams */) {
return -1;
}
WebRtc_Word16 ACMDTMFPlayout::InternalInitDecoder(
WebRtcACMCodecParams* /* codecParams */) {
return -1;
}
WebRtc_Word32 ACMDTMFPlayout::CodecDef(WebRtcNetEQ_CodecDef& /* codecDef */,
const CodecInst& /* codecInst */) {
return -1;
}
ACMGenericCodec* ACMDTMFPlayout::CreateInstance(void) {
return NULL;
}
WebRtc_Word16 ACMDTMFPlayout::InternalCreateEncoder() {
return -1;
}
WebRtc_Word16 ACMDTMFPlayout::InternalCreateDecoder() {
return -1;
}
void ACMDTMFPlayout::InternalDestructEncoderInst(void* /* ptrInst */) {
return;
}
void ACMDTMFPlayout::DestructEncoderSafe() {
return;
}
void ACMDTMFPlayout::DestructDecoderSafe() {
return;
}
#else //===================== Actual Implementation =======================
ACMDTMFPlayout::ACMDTMFPlayout(WebRtc_Word16 codecID) {
_codecID = codecID;
}
ACMDTMFPlayout::~ACMDTMFPlayout() {
return;
}
WebRtc_Word16 ACMDTMFPlayout::InternalEncode(
WebRtc_UWord8* /* bitStream */,
WebRtc_Word16* /* bitStreamLenByte */) {
return 0;
}
WebRtc_Word16 ACMDTMFPlayout::DecodeSafe(WebRtc_UWord8* /* bitStream */,
WebRtc_Word16 /* bitStreamLenByte */,
WebRtc_Word16* /* audio */,
WebRtc_Word16* /* audioSamples */,
WebRtc_Word8* /* speechType */) {
return 0;
}
WebRtc_Word16 ACMDTMFPlayout::InternalInitEncoder(
WebRtcACMCodecParams* /* codecParams */) {
// This codec does not need initialization,
// DTMFPlayout has no instance
return 0;
}
WebRtc_Word16 ACMDTMFPlayout::InternalInitDecoder(
WebRtcACMCodecParams* /* codecParams */) {
// This codec does not need initialization,
// DTMFPlayout has no instance
return 0;
}
WebRtc_Word32 ACMDTMFPlayout::CodecDef(WebRtcNetEQ_CodecDef& codecDef,
const CodecInst& codecInst) {
// Fill up the structure by calling
// "SET_CODEC_PAR" & "SET_AVT_FUNCTION."
// Then call NetEQ to add the codec to it's
// database.
SET_CODEC_PAR((codecDef), kDecoderAVT, codecInst.pltype, NULL, 8000);
SET_AVT_FUNCTIONS((codecDef));
return 0;
}
ACMGenericCodec* ACMDTMFPlayout::CreateInstance(void) {
return NULL;
}
WebRtc_Word16 ACMDTMFPlayout::InternalCreateEncoder() {
// DTMFPlayout has no instance
return 0;
}
WebRtc_Word16 ACMDTMFPlayout::InternalCreateDecoder() {
// DTMFPlayout has no instance
return 0;
}
void ACMDTMFPlayout::InternalDestructEncoderInst(void* /* ptrInst */) {
// DTMFPlayout has no instance
return;
}
void ACMDTMFPlayout::DestructEncoderSafe() {
// DTMFPlayout has no instance
return;
}
void ACMDTMFPlayout::DestructDecoderSafe() {
// DTMFPlayout has no instance
return;
}
#endif
} // namespace webrtc

View File

@ -0,0 +1,54 @@
/*
* 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_MAIN_SOURCE_ACM_DTMF_PLAYOUT_H_
#define WEBRTC_MODULES_AUDIO_CODING_MAIN_SOURCE_ACM_DTMF_PLAYOUT_H_
#include "acm_generic_codec.h"
namespace webrtc {
class ACMDTMFPlayout: public ACMGenericCodec {
public:
ACMDTMFPlayout(WebRtc_Word16 codecID);
~ACMDTMFPlayout();
// for FEC
ACMGenericCodec* CreateInstance(void);
WebRtc_Word16 InternalEncode(WebRtc_UWord8* bitstream,
WebRtc_Word16* bitStreamLenByte);
WebRtc_Word16 InternalInitEncoder(WebRtcACMCodecParams *codecParams);
WebRtc_Word16 InternalInitDecoder(WebRtcACMCodecParams *codecParams);
protected:
WebRtc_Word16 DecodeSafe(WebRtc_UWord8* bitStream,
WebRtc_Word16 bitStreamLenByte,
WebRtc_Word16* audio, WebRtc_Word16* audioSamples,
WebRtc_Word8* speechType);
WebRtc_Word32 CodecDef(WebRtcNetEQ_CodecDef& codecDef,
const CodecInst& codecInst);
void DestructEncoderSafe();
void DestructDecoderSafe();
WebRtc_Word16 InternalCreateEncoder();
WebRtc_Word16 InternalCreateDecoder();
void InternalDestructEncoderInst(void* ptrInst);
};
} // namespace webrtc
#endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_SOURCE_ACM_DTMF_PLAYOUT_H_

View File

@ -0,0 +1,353 @@
/*
* 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 "acm_g722.h"
#include "acm_codec_database.h"
#include "acm_common_defs.h"
#include "acm_neteq.h"
#include "trace.h"
#include "webrtc_neteq.h"
#include "webrtc_neteq_help_macros.h"
#include "g722_interface.h"
namespace webrtc {
#ifndef WEBRTC_CODEC_G722
ACMG722::ACMG722(WebRtc_Word16 /* codecID */)
: _ptrEncStr(NULL),
_ptrDecStr(NULL),
_encoderInstPtr(NULL),
_encoderInstPtrRight(NULL),
_decoderInstPtr(NULL) {
return;
}
ACMG722::~ACMG722() {
return;
}
WebRtc_Word32 ACMG722::Add10MsDataSafe(const WebRtc_UWord32 /* timestamp */,
const WebRtc_Word16* /* data */,
const WebRtc_UWord16 /* lengthSmpl */,
const WebRtc_UWord8 /* audioChannel */) {
return -1;
}
WebRtc_Word16 ACMG722::InternalEncode(WebRtc_UWord8* /* bitStream */,
WebRtc_Word16* /* bitStreamLenByte */) {
return -1;
}
WebRtc_Word16 ACMG722::DecodeSafe(WebRtc_UWord8* /* bitStream */,
WebRtc_Word16 /* bitStreamLenByte */,
WebRtc_Word16* /* audio */,
WebRtc_Word16* /* audioSamples */,
WebRtc_Word8* /* speechType */) {
return -1;
}
WebRtc_Word16 ACMG722::InternalInitEncoder(
WebRtcACMCodecParams* /* codecParams */) {
return -1;
}
WebRtc_Word16 ACMG722::InternalInitDecoder(
WebRtcACMCodecParams* /* codecParams */) {
return -1;
}
WebRtc_Word32 ACMG722::CodecDef(WebRtcNetEQ_CodecDef& /* codecDef */,
const CodecInst& /* codecInst */) {
return -1;
}
ACMGenericCodec* ACMG722::CreateInstance(void) {
return NULL;
}
WebRtc_Word16 ACMG722::InternalCreateEncoder() {
return -1;
}
void ACMG722::DestructEncoderSafe() {
return;
}
WebRtc_Word16 ACMG722::InternalCreateDecoder() {
return -1;
}
void ACMG722::DestructDecoderSafe() {
return;
}
void ACMG722::InternalDestructEncoderInst(void* /* ptrInst */) {
return;
}
void ACMG722::SplitStereoPacket(uint8_t* /*payload*/,
int32_t* /*payload_length*/) {}
#else //===================== Actual Implementation =======================
// Encoder and decoder memory
struct ACMG722EncStr {
G722EncInst* inst; // instance for left channel in case of stereo
G722EncInst* instRight; // instance for right channel in case of stereo
};
struct ACMG722DecStr {
G722DecInst* inst; // instance for left channel in case of stereo
G722DecInst* instRight; // instance for right channel in case of stereo
};
ACMG722::ACMG722(WebRtc_Word16 codecID)
: _encoderInstPtr(NULL),
_encoderInstPtrRight(NULL),
_decoderInstPtr(NULL) {
// Encoder
_ptrEncStr = new ACMG722EncStr;
if (_ptrEncStr != NULL) {
_ptrEncStr->inst = NULL;
_ptrEncStr->instRight = NULL;
}
// Decoder
_ptrDecStr = new ACMG722DecStr;
if (_ptrDecStr != NULL) {
_ptrDecStr->inst = NULL;
_ptrDecStr->instRight = NULL; // Not used
}
_codecID = codecID;
return;
}
ACMG722::~ACMG722() {
// Encoder
if (_ptrEncStr != NULL) {
if (_ptrEncStr->inst != NULL) {
WebRtcG722_FreeEncoder(_ptrEncStr->inst);
_ptrEncStr->inst = NULL;
}
if (_ptrEncStr->instRight != NULL) {
WebRtcG722_FreeEncoder(_ptrEncStr->instRight);
_ptrEncStr->instRight = NULL;
}
delete _ptrEncStr;
_ptrEncStr = NULL;
}
// Decoder
if (_ptrDecStr != NULL) {
if (_ptrDecStr->inst != NULL) {
WebRtcG722_FreeDecoder(_ptrDecStr->inst);
_ptrDecStr->inst = NULL;
}
if (_ptrDecStr->instRight != NULL) {
WebRtcG722_FreeDecoder(_ptrDecStr->instRight);
_ptrDecStr->instRight = NULL;
}
delete _ptrDecStr;
_ptrDecStr = NULL;
}
return;
}
WebRtc_Word32 ACMG722::Add10MsDataSafe(const WebRtc_UWord32 timestamp,
const WebRtc_Word16* data,
const WebRtc_UWord16 lengthSmpl,
const WebRtc_UWord8 audioChannel) {
return ACMGenericCodec::Add10MsDataSafe((timestamp >> 1), data, lengthSmpl,
audioChannel);
}
WebRtc_Word16 ACMG722::InternalEncode(WebRtc_UWord8* bitStream,
WebRtc_Word16* bitStreamLenByte) {
// If stereo, split input signal in left and right channel before encoding
if (_noChannels == 2) {
WebRtc_Word16 leftChannel[960];
WebRtc_Word16 rightChannel[960];
WebRtc_UWord8 outLeft[480];
WebRtc_UWord8 outRight[480];
WebRtc_Word16 lenInBytes;
for (int i = 0, j = 0; i < _frameLenSmpl * 2; i += 2, j++) {
leftChannel[j] = _inAudio[_inAudioIxRead + i];
rightChannel[j] = _inAudio[_inAudioIxRead + i + 1];
}
lenInBytes = WebRtcG722_Encode(_encoderInstPtr, leftChannel, _frameLenSmpl,
(WebRtc_Word16*) outLeft);
lenInBytes += WebRtcG722_Encode(_encoderInstPtrRight, rightChannel,
_frameLenSmpl, (WebRtc_Word16*) outRight);
*bitStreamLenByte = lenInBytes;
// Interleave the 4 bits per sample from left and right channel
for (int i = 0, j = 0; i < lenInBytes; i += 2, j++) {
bitStream[i] = (outLeft[j] & 0xF0) + (outRight[j] >> 4);
bitStream[i + 1] = ((outLeft[j] & 0x0F) << 4) + (outRight[j] & 0x0F);
}
} else {
*bitStreamLenByte = WebRtcG722_Encode(_encoderInstPtr,
&_inAudio[_inAudioIxRead],
_frameLenSmpl,
(WebRtc_Word16*) bitStream);
}
// increment the read index this tell the caller how far
// we have gone forward in reading the audio buffer
_inAudioIxRead += _frameLenSmpl * _noChannels;
return *bitStreamLenByte;
}
WebRtc_Word16 ACMG722::DecodeSafe(WebRtc_UWord8* /* bitStream */,
WebRtc_Word16 /* bitStreamLenByte */,
WebRtc_Word16* /* audio */,
WebRtc_Word16* /* audioSamples */,
WebRtc_Word8* /* speechType */) {
return 0;
}
WebRtc_Word16 ACMG722::InternalInitEncoder(WebRtcACMCodecParams* codecParams) {
if (codecParams->codecInstant.channels == 2) {
// Create codec struct for right channel
if (_ptrEncStr->instRight == NULL) {
WebRtcG722_CreateEncoder(&_ptrEncStr->instRight);
if (_ptrEncStr->instRight == NULL) {
return -1;
}
}
_encoderInstPtrRight = _ptrEncStr->instRight;
if (WebRtcG722_EncoderInit(_encoderInstPtrRight) < 0) {
return -1;
}
}
return WebRtcG722_EncoderInit(_encoderInstPtr);
}
WebRtc_Word16 ACMG722::InternalInitDecoder(
WebRtcACMCodecParams* /* codecParams */) {
return WebRtcG722_DecoderInit(_decoderInstPtr);
}
WebRtc_Word32 ACMG722::CodecDef(WebRtcNetEQ_CodecDef& codecDef,
const CodecInst& codecInst) {
if (!_decoderInitialized) {
// TODO: log error
return -1;
}
// Fill up the structure by calling
// "SET_CODEC_PAR" & "SET_G722_FUNCTION."
// Then call NetEQ to add the codec to it's
// database.
if (codecInst.channels == 1) {
SET_CODEC_PAR(codecDef, kDecoderG722, codecInst.pltype, _decoderInstPtr,
16000);
} else {
SET_CODEC_PAR(codecDef, kDecoderG722_2ch, codecInst.pltype,
_decoderInstPtr, 16000);
}
SET_G722_FUNCTIONS(codecDef);
return 0;
}
ACMGenericCodec* ACMG722::CreateInstance(void) {
return NULL;
}
WebRtc_Word16 ACMG722::InternalCreateEncoder() {
if (_ptrEncStr == NULL) {
// this structure must be created at the costructor
// if it is still NULL then there is a probelm and
// we dont continue
return -1;
}
WebRtcG722_CreateEncoder(&_ptrEncStr->inst);
if (_ptrEncStr->inst == NULL) {
return -1;
}
_encoderInstPtr = _ptrEncStr->inst;
return 0;
}
void ACMG722::DestructEncoderSafe() {
if (_ptrEncStr != NULL) {
if (_ptrEncStr->inst != NULL) {
WebRtcG722_FreeEncoder(_ptrEncStr->inst);
_ptrEncStr->inst = NULL;
}
}
_encoderExist = false;
_encoderInitialized = false;
}
WebRtc_Word16 ACMG722::InternalCreateDecoder() {
if (_ptrDecStr == NULL) {
// this structure must be created at the costructor
// if it is still NULL then there is a probelm and
// we dont continue
return -1;
}
WebRtcG722_CreateDecoder(&_ptrDecStr->inst);
if (_ptrDecStr->inst == NULL) {
return -1;
}
_decoderInstPtr = _ptrDecStr->inst;
return 0;
}
void ACMG722::DestructDecoderSafe() {
_decoderExist = false;
_decoderInitialized = false;
if (_ptrDecStr != NULL) {
if (_ptrDecStr->inst != NULL) {
WebRtcG722_FreeDecoder(_ptrDecStr->inst);
_ptrDecStr->inst = NULL;
}
}
}
void ACMG722::InternalDestructEncoderInst(void* ptrInst) {
if (ptrInst != NULL) {
WebRtcG722_FreeEncoder(static_cast<G722EncInst*>(ptrInst));
}
return;
}
// Split the stereo packet and place left and right channel after each other
// in the payload vector.
void ACMG722::SplitStereoPacket(uint8_t* payload, int32_t* payload_length) {
uint8_t right_byte;
// Check for valid inputs.
assert(payload != NULL);
assert(*payload_length > 0);
// Regroup the 4 bits/sample so to |l1 l2| |r1 r2| |l3 l4| |r3 r4| ...,
// where "lx" is 4 bits representing left sample number x, and "rx" right
// sample. Two samples fits in one byte, represented with |...|.
for (int i = 0; i < *payload_length; i += 2) {
right_byte = ((payload[i] & 0x0F) << 4) + (payload[i + 1] & 0x0F);
payload[i] = (payload[i] & 0xF0) + (payload[i + 1] >> 4);
payload[i + 1] = right_byte;
}
// Move one byte representing right channel each loop, and place it at the
// end of the bytestream vector. After looping the data is reordered to:
// |l1 l2| |l3 l4| ... |l(N-1) lN| |r1 r2| |r3 r4| ... |r(N-1) r(N)|,
// where N is the total number of samples.
for (int i = 0; i < *payload_length / 2; i++) {
right_byte = payload[i + 1];
memmove(&payload[i + 1], &payload[i + 2], *payload_length - i - 2);
payload[*payload_length - 1] = right_byte;
}
}
#endif
} // namespace webrtc

View File

@ -0,0 +1,75 @@
/*
* 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_MAIN_SOURCE_ACM_G722_H_
#define WEBRTC_MODULES_AUDIO_CODING_MAIN_SOURCE_ACM_G722_H_
#include "acm_generic_codec.h"
typedef struct WebRtcG722EncInst G722EncInst;
typedef struct WebRtcG722DecInst G722DecInst;
namespace webrtc {
// forward declaration
struct ACMG722EncStr;
struct ACMG722DecStr;
class ACMG722: public ACMGenericCodec {
public:
ACMG722(WebRtc_Word16 codecID);
~ACMG722();
// for FEC
ACMGenericCodec* CreateInstance(void);
WebRtc_Word16 InternalEncode(WebRtc_UWord8* bitstream,
WebRtc_Word16* bitStreamLenByte);
WebRtc_Word16 InternalInitEncoder(WebRtcACMCodecParams *codecParams);
WebRtc_Word16 InternalInitDecoder(WebRtcACMCodecParams *codecParams);
protected:
WebRtc_Word16 DecodeSafe(WebRtc_UWord8* bitStream,
WebRtc_Word16 bitStreamLenByte,
WebRtc_Word16* audio, WebRtc_Word16* audioSamples,
WebRtc_Word8* speechType);
WebRtc_Word32 CodecDef(WebRtcNetEQ_CodecDef& codecDef,
const CodecInst& codecInst);
WebRtc_Word32 Add10MsDataSafe(const WebRtc_UWord32 timestamp,
const WebRtc_Word16* data,
const WebRtc_UWord16 lengthSmpl,
const WebRtc_UWord8 audioChannel);
void DestructEncoderSafe();
void DestructDecoderSafe();
WebRtc_Word16 InternalCreateEncoder();
WebRtc_Word16 InternalCreateDecoder();
void InternalDestructEncoderInst(void* ptrInst);
void SplitStereoPacket(uint8_t* payload, int32_t* payload_length);
ACMG722EncStr* _ptrEncStr;
ACMG722DecStr* _ptrDecStr;
G722EncInst* _encoderInstPtr;
G722EncInst* _encoderInstPtrRight; // Prepared for stereo
G722DecInst* _decoderInstPtr;
};
} // namespace webrtc
#endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_SOURCE_ACM_G722_H_

View File

@ -0,0 +1,492 @@
/*
* 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 "acm_g7221.h"
#include "acm_codec_database.h"
#include "acm_common_defs.h"
#include "acm_neteq.h"
#include "trace.h"
#include "webrtc_neteq.h"
#include "webrtc_neteq_help_macros.h"
#ifdef WEBRTC_CODEC_G722_1
// NOTE! G.722.1 is not included in the open-source package. The following
// interface file is needed:
//
// /modules/audio_coding/codecs/g7221/main/interface/g7221_interface.h
//
// The API in the header file should match the one below.
//
// int16_t WebRtcG7221_CreateEnc16(G722_1_16_encinst_t_** encInst);
// int16_t WebRtcG7221_CreateEnc24(G722_1_24_encinst_t_** encInst);
// int16_t WebRtcG7221_CreateEnc32(G722_1_32_encinst_t_** encInst);
// int16_t WebRtcG7221_CreateDec16(G722_1_16_decinst_t_** decInst);
// int16_t WebRtcG7221_CreateDec24(G722_1_24_decinst_t_** decInst);
// int16_t WebRtcG7221_CreateDec32(G722_1_32_decinst_t_** decInst);
//
// int16_t WebRtcG7221_FreeEnc16(G722_1_16_encinst_t_** encInst);
// int16_t WebRtcG7221_FreeEnc24(G722_1_24_encinst_t_** encInst);
// int16_t WebRtcG7221_FreeEnc32(G722_1_32_encinst_t_** encInst);
// int16_t WebRtcG7221_FreeDec16(G722_1_16_decinst_t_** decInst);
// int16_t WebRtcG7221_FreeDec24(G722_1_24_decinst_t_** decInst);
// int16_t WebRtcG7221_FreeDec32(G722_1_32_decinst_t_** decInst);
//
// int16_t WebRtcG7221_EncoderInit16(G722_1_16_encinst_t_* encInst);
// int16_t WebRtcG7221_EncoderInit24(G722_1_24_encinst_t_* encInst);
// int16_t WebRtcG7221_EncoderInit32(G722_1_32_encinst_t_* encInst);
// int16_t WebRtcG7221_DecoderInit16(G722_1_16_decinst_t_* decInst);
// int16_t WebRtcG7221_DecoderInit24(G722_1_24_decinst_t_* decInst);
// int16_t WebRtcG7221_DecoderInit32(G722_1_32_decinst_t_* decInst);
//
// int16_t WebRtcG7221_Encode16(G722_1_16_encinst_t_* encInst,
// int16_t* input,
// int16_t len,
// int16_t* output);
// int16_t WebRtcG7221_Encode24(G722_1_24_encinst_t_* encInst,
// int16_t* input,
// int16_t len,
// int16_t* output);
// int16_t WebRtcG7221_Encode32(G722_1_32_encinst_t_* encInst,
// int16_t* input,
// int16_t len,
// int16_t* output);
//
// int16_t WebRtcG7221_Decode16(G722_1_16_decinst_t_* decInst,
// int16_t* bitstream,
// int16_t len,
// int16_t* output);
// int16_t WebRtcG7221_Decode24(G722_1_24_decinst_t_* decInst,
// int16_t* bitstream,
// int16_t len,
// int16_t* output);
// int16_t WebRtcG7221_Decode32(G722_1_32_decinst_t_* decInst,
// int16_t* bitstream,
// int16_t len,
// int16_t* output);
//
// int16_t WebRtcG7221_DecodePlc16(G722_1_16_decinst_t_* decInst,
// int16_t* output,
// int16_t nrLostFrames);
// int16_t WebRtcG7221_DecodePlc24(G722_1_24_decinst_t_* decInst,
// int16_t* output,
// int16_t nrLostFrames);
// int16_t WebRtcG7221_DecodePlc32(G722_1_32_decinst_t_* decInst,
// int16_t* output,
// int16_t nrLostFrames);
#include "g7221_interface.h"
#endif
namespace webrtc {
#ifndef WEBRTC_CODEC_G722_1
ACMG722_1::ACMG722_1(WebRtc_Word16 /* codecID */)
: _operationalRate(-1),
_encoderInstPtr(NULL),
_encoderInstPtrRight(NULL),
_decoderInstPtr(NULL),
_encoderInst16Ptr(NULL),
_encoderInst16PtrR(NULL),
_encoderInst24Ptr(NULL),
_encoderInst24PtrR(NULL),
_encoderInst32Ptr(NULL),
_encoderInst32PtrR(NULL),
_decoderInst16Ptr(NULL),
_decoderInst24Ptr(NULL),
_decoderInst32Ptr(NULL) {
return;
}
ACMG722_1::~ACMG722_1() {
return;
}
WebRtc_Word16 ACMG722_1::InternalEncode(WebRtc_UWord8* /* bitStream */,
WebRtc_Word16* /* bitStreamLenByte */) {
return -1;
}
WebRtc_Word16 ACMG722_1::DecodeSafe(WebRtc_UWord8* /* bitStream */,
WebRtc_Word16 /* bitStreamLenByte */,
WebRtc_Word16* /* audio */,
WebRtc_Word16* /* audioSamples */,
WebRtc_Word8* /* speechType */) {
return -1;
}
WebRtc_Word16 ACMG722_1::InternalInitEncoder(
WebRtcACMCodecParams* /* codecParams */) {
return -1;
}
WebRtc_Word16 ACMG722_1::InternalInitDecoder(
WebRtcACMCodecParams* /* codecParams */) {
return -1;
}
WebRtc_Word32 ACMG722_1::CodecDef(WebRtcNetEQ_CodecDef& /* codecDef */,
const CodecInst& /* codecInst */) {
return -1;
}
ACMGenericCodec* ACMG722_1::CreateInstance(void) {
return NULL;
}
WebRtc_Word16 ACMG722_1::InternalCreateEncoder() {
return -1;
}
void ACMG722_1::DestructEncoderSafe() {
return;
}
WebRtc_Word16 ACMG722_1::InternalCreateDecoder() {
return -1;
}
void ACMG722_1::DestructDecoderSafe() {
return;
}
void ACMG722_1::InternalDestructEncoderInst(void* /* ptrInst */) {
return;
}
#else //===================== Actual Implementation =======================
ACMG722_1::ACMG722_1(
WebRtc_Word16 codecID):
_encoderInstPtr(NULL),
_encoderInstPtrRight(NULL),
_decoderInstPtr(NULL),
_encoderInst16Ptr(NULL),
_encoderInst16PtrR(NULL),
_encoderInst24Ptr(NULL),
_encoderInst24PtrR(NULL),
_encoderInst32Ptr(NULL),
_encoderInst32PtrR(NULL),
_decoderInst16Ptr(NULL),
_decoderInst24Ptr(NULL),
_decoderInst32Ptr(NULL) {
_codecID = codecID;
if (_codecID == ACMCodecDB::kG722_1_16) {
_operationalRate = 16000;
} else if (_codecID == ACMCodecDB::kG722_1_24) {
_operationalRate = 24000;
} else if (_codecID == ACMCodecDB::kG722_1_32) {
_operationalRate = 32000;
} else {
_operationalRate = -1;
}
return;
}
ACMG722_1::~ACMG722_1() {
if (_encoderInstPtr != NULL) {
delete _encoderInstPtr;
_encoderInstPtr = NULL;
}
if (_encoderInstPtrRight != NULL) {
delete _encoderInstPtrRight;
_encoderInstPtrRight = NULL;
}
if (_decoderInstPtr != NULL) {
delete _decoderInstPtr;
_decoderInstPtr = NULL;
}
switch (_operationalRate) {
case 16000: {
_encoderInst16Ptr = NULL;
_encoderInst16PtrR = NULL;
_decoderInst16Ptr = NULL;
break;
}
case 24000: {
_encoderInst24Ptr = NULL;
_encoderInst24PtrR = NULL;
_decoderInst24Ptr = NULL;
break;
}
case 32000: {
_encoderInst32Ptr = NULL;
_encoderInst32PtrR = NULL;
_decoderInst32Ptr = NULL;
break;
}
default: {
break;
}
}
return;
}
WebRtc_Word16 ACMG722_1::InternalEncode(WebRtc_UWord8* bitStream,
WebRtc_Word16* bitStreamLenByte) {
WebRtc_Word16 leftChannel[320];
WebRtc_Word16 rightChannel[320];
WebRtc_Word16 lenInBytes;
WebRtc_Word16 outB[160];
// If stereo, split input signal in left and right channel before encoding
if (_noChannels == 2) {
for (int i = 0, j = 0; i < _frameLenSmpl * 2; i += 2, j++) {
leftChannel[j] = _inAudio[_inAudioIxRead + i];
rightChannel[j] = _inAudio[_inAudioIxRead + i + 1];
}
} else {
memcpy(leftChannel, &_inAudio[_inAudioIxRead], 320);
}
switch (_operationalRate) {
case 16000: {
Inst lenInBytes = WebRtcG7221_Encode16(_encoderInst16Ptr, leftChannel,
320, &outB[0]);
if (_noChannels == 2) {
lenInBytes += WebRtcG7221_Encode16(_encoderInst16PtrR, rightChannel,
320, &outB[lenInBytes / 2]);
}
break;
}
case 24000: {
lenInBytes = WebRtcG7221_Encode24(_encoderInst24Ptr, leftChannel, 320,
&outB[0]);
if (_noChannels == 2) {
lenInBytes += WebRtcG7221_Encode24(_encoderInst24PtrR, rightChannel,
320, &outB[lenInBytes / 2]);
}
break;
}
case 32000: {
lenInBytes = WebRtcG7221_Encode32(_encoderInst32Ptr, leftChannel, 320,
&outB[0]);
if (_noChannels == 2) {
lenInBytes += WebRtcG7221_Encode32(_encoderInst32PtrR, rightChannel,
320, &outB[lenInBytes / 2]);
}
break;
}
default: {
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
"InternalInitEncode: Wrong rate for G722_1.");
return -1;
}
}
memcpy(bitStream, outB, lenInBytes);
*bitStreamLenByte = lenInBytes;
// increment the read index this tell the caller that how far
// we have gone forward in reading the audio buffer
_inAudioIxRead += 320 * _noChannels;
return *bitStreamLenByte;
}
WebRtc_Word16 ACMG722_1::DecodeSafe(WebRtc_UWord8* /* bitStream */,
WebRtc_Word16 /* bitStreamLenByte */,
WebRtc_Word16* /* audio */,
WebRtc_Word16* /* audioSamples */,
WebRtc_Word8* /* speechType */) {
return 0;
}
WebRtc_Word16 ACMG722_1::InternalInitEncoder(
WebRtcACMCodecParams* codecParams) {
WebRtc_Word16 ret;
switch (_operationalRate) {
case 16000: {
ret = WebRtcG7221_EncoderInit16(_encoderInst16PtrR);
if (ret < 0) {
return ret;
}
return WebRtcG7221_EncoderInit16(_encoderInst16Ptr);
}
case 24000: {
ret = WebRtcG7221_EncoderInit24(_encoderInst24PtrR);
if (ret < 0) {
return ret;
}
return WebRtcG7221_EncoderInit24(_encoderInst24Ptr);
}
case 32000: {
ret = WebRtcG7221_EncoderInit32(_encoderInst32PtrR);
if (ret < 0) {
return ret;
}
return WebRtcG7221_EncoderInit32(_encoderInst32Ptr);
}
default: {
WEBRTC_TRACE(webrtc::kTraceError,Inst webrtc::kTraceAudioCoding,
_uniqueID, "InternalInitEncoder: Wrong rate for G722_1.");
return -1;
}
}
}
WebRtc_Word16 ACMG722_1::InternalInitDecoder(
WebRtcACMCodecParams* /* codecParams */) {
switch (_operationalRate) {
case 16000: {
return WebRtcG7221_DecoderInit16(_decoderInst16Ptr);
}
case 24000: {
return WebRtcG7221_DecoderInit24(_decoderInst24Ptr);
}
case 32000: {
return WebRtcG7221_DecoderInit32(_decoderInst32Ptr);
}
default: {
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
"InternalInitDecoder: Wrong rate for G722_1.");
return -1;
}
}
}
WebRtc_Word32 ACMG722_1::CodecDef(WebRtcNetEQ_CodecDef& codecDef,
const CodecInst& codecInst) {
if (!_decoderInitialized) {
// Todo:
// log error
return -1;
}
// NetEq has an array of pointers to WebRtcNetEQ_CodecDef.
// Get an entry of that array (neteq wrapper will allocate memory)
// by calling "netEq->CodecDef", where "NETEQ_CODEC_G722_1_XX" would
// be the index of the entry.
// Fill up the given structure by calling
// "SET_CODEC_PAR" & "SET_G722_1_XX_FUNCTION."
// Then return the structure back to NetEQ to add the codec to it's
// database.
switch (_operationalRate) {
case 16000: {
SET_CODEC_PAR((codecDef), kDecoderG722_1_16, codecInst.pltype,
_decoderInst16Ptr, 16000);
SET_G722_1_16_FUNCTIONS((codecDef));
break;
}
case 24000: {
SET_CODEC_PAR((codecDef), kDecoderG722_1_24, codecInst.pltype,
_decoderInst24Ptr, 16000);
SET_G722_1_24_FUNCTIONS((codecDef));
break;
}
case 32000: {
SET_CODEC_PAR((codecDef), kDecoderG722_1_32, codecInst.pltype,
_decoderInst32Ptr, 16000);
SET_G722_1_32_FUNCTIONS((codecDef));
break;
}
default: {
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
"CodecDef: Wrong rate for G722_1.");
return -1;
}
}
return 0;
}
ACMGenericCodec* ACMG722_1::CreateInstance(void) {
return NULL;
}
WebRtc_Word16 ACMG722_1::InternalCreateEncoder() {
if ((_encoderInstPtr == NULL) || (_encoderInstPtrRight == NULL)) {
return -1;
}
switch (_operationalRate) {
case 16000: {
WebRtcG7221_CreateEnc16(&_encoderInst16Ptr);
WebRtcG7221_CreateEnc16(&_encoderInst16PtrR);
break;
}
case 24000: {
WebRtcG7221_CreateEnc24(&_encoderInst24Ptr);
WebRtcG7221_CreateEnc24(&_encoderInst24PtrR);
break;
}
case 32000: {
WebRtcG7221_CreateEnc32(&_encoderInst32Ptr);
WebRtcG7221_CreateEnc32(&_encoderInst32PtrR);
break;
}
default: {
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
"InternalCreateEncoder: Wrong rate for G722_1.");
return -1;
}
}
return 0;
}
void ACMG722_1::DestructEncoderSafe() {
_encoderExist = false;
_encoderInitialized = false;
if (_encoderInstPtr != NULL) {
delete _encoderInstPtr;
_encoderInstPtr = NULL;
}
if (_encoderInstPtrRight != NULL) {
delete _encoderInstPtrRight;
_encoderInstPtrRight = NULL;
}
_encoderInst16Ptr = NULL;
_encoderInst24Ptr = NULL;
_encoderInst32Ptr = NULL;
}
WebRtc_Word16 ACMG722_1::InternalCreateDecoder() {
if (_decoderInstPtr == NULL) {
return -1;
}
switch (_operationalRate) {
case 16000: {
WebRtcG7221_CreateDec16(&_decoderInst16Ptr);
break;
}
case 24000: {
WebRtcG7221_CreateDec24(&_decoderInst24Ptr);
break;
}
case 32000: {
WebRtcG7221_CreateDec32(&_decoderInst32Ptr);
break;
}
default: {
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
"InternalCreateDecoder: Wrong rate for G722_1.");
return -1;
}
}
return 0;
}
void ACMG722_1::DestructDecoderSafe() {
_decoderExist = false;
_decoderInitialized = false;
if (_decoderInstPtr != NULL) {
delete _decoderInstPtr;
_decoderInstPtr = NULL;
}
_decoderInst16Ptr = NULL;
_decoderInst24Ptr = NULL;
_decoderInst32Ptr = NULL;
}
void ACMG722_1::InternalDestructEncoderInst(void* ptrInst) {
if (ptrInst != NULL) {
delete ptrInst;
}
return;
}
#endif
} // namespace webrtc

View File

@ -0,0 +1,82 @@
/*
* 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_MAIN_SOURCE_ACM_G722_1_H_
#define WEBRTC_MODULES_AUDIO_CODING_MAIN_SOURCE_ACM_G722_1_H_
#include "acm_generic_codec.h"
// forward declaration
struct G722_1_16_encinst_t_;
struct G722_1_16_decinst_t_;
struct G722_1_24_encinst_t_;
struct G722_1_24_decinst_t_;
struct G722_1_32_encinst_t_;
struct G722_1_32_decinst_t_;
struct G722_1_Inst_t_;
namespace webrtc {
class ACMG722_1: public ACMGenericCodec {
public:
ACMG722_1(WebRtc_Word16 codecID);
~ACMG722_1();
// for FEC
ACMGenericCodec* CreateInstance(void);
WebRtc_Word16 InternalEncode(WebRtc_UWord8* bitstream,
WebRtc_Word16* bitStreamLenByte);
WebRtc_Word16 InternalInitEncoder(WebRtcACMCodecParams *codecParams);
WebRtc_Word16 InternalInitDecoder(WebRtcACMCodecParams *codecParams);
protected:
WebRtc_Word16 DecodeSafe(WebRtc_UWord8* bitStream,
WebRtc_Word16 bitStreamLenByte,
WebRtc_Word16* audio, WebRtc_Word16* audioSamples,
WebRtc_Word8* speechType);
WebRtc_Word32 CodecDef(WebRtcNetEQ_CodecDef& codecDef,
const CodecInst& codecInst);
void DestructEncoderSafe();
void DestructDecoderSafe();
WebRtc_Word16 InternalCreateEncoder();
WebRtc_Word16 InternalCreateDecoder();
void InternalDestructEncoderInst(void* ptrInst);
WebRtc_Word32 _operationalRate;
G722_1_Inst_t_* _encoderInstPtr;
G722_1_Inst_t_* _encoderInstPtrRight; //Used in stereo mode
G722_1_Inst_t_* _decoderInstPtr;
// Only one set of these pointer is valid at any instance
G722_1_16_encinst_t_* _encoderInst16Ptr;
G722_1_16_encinst_t_* _encoderInst16PtrR;
G722_1_24_encinst_t_* _encoderInst24Ptr;
G722_1_24_encinst_t_* _encoderInst24PtrR;
G722_1_32_encinst_t_* _encoderInst32Ptr;
G722_1_32_encinst_t_* _encoderInst32PtrR;
// Only one of these pointer is valid at any instance
G722_1_16_decinst_t_* _decoderInst16Ptr;
G722_1_24_decinst_t_* _decoderInst24Ptr;
G722_1_32_decinst_t_* _decoderInst32Ptr;
};
} // namespace webrtc
#endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_SOURCE_ACM_G722_1_H_

View File

@ -0,0 +1,494 @@
/*
* 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 "acm_g7221c.h"
#include "acm_codec_database.h"
#include "acm_common_defs.h"
#include "acm_neteq.h"
#include "webrtc_neteq.h"
#include "webrtc_neteq_help_macros.h"
#include "trace.h"
#ifdef WEBRTC_CODEC_G722_1C
// NOTE! G.722.1C is not included in the open-source package. The following
// interface file is needed:
//
// /modules/audio_coding/codecs/g7221c/main/interface/g7221c_interface.h
//
// The API in the header file should match the one below.
//
// int16_t WebRtcG7221C_CreateEnc24(G722_1C_24_encinst_t_** encInst);
// int16_t WebRtcG7221C_CreateEnc32(G722_1C_32_encinst_t_** encInst);
// int16_t WebRtcG7221C_CreateEnc48(G722_1C_48_encinst_t_** encInst);
// int16_t WebRtcG7221C_CreateDec24(G722_1C_24_decinst_t_** decInst);
// int16_t WebRtcG7221C_CreateDec32(G722_1C_32_decinst_t_** decInst);
// int16_t WebRtcG7221C_CreateDec48(G722_1C_48_decinst_t_** decInst);
//
// int16_t WebRtcG7221C_FreeEnc24(G722_1C_24_encinst_t_** encInst);
// int16_t WebRtcG7221C_FreeEnc32(G722_1C_32_encinst_t_** encInst);
// int16_t WebRtcG7221C_FreeEnc48(G722_1C_48_encinst_t_** encInst);
// int16_t WebRtcG7221C_FreeDec24(G722_1C_24_decinst_t_** decInst);
// int16_t WebRtcG7221C_FreeDec32(G722_1C_32_decinst_t_** decInst);
// int16_t WebRtcG7221C_FreeDec48(G722_1C_48_decinst_t_** decInst);
//
// int16_t WebRtcG7221C_EncoderInit24(G722_1C_24_encinst_t_* encInst);
// int16_t WebRtcG7221C_EncoderInit32(G722_1C_32_encinst_t_* encInst);
// int16_t WebRtcG7221C_EncoderInit48(G722_1C_48_encinst_t_* encInst);
// int16_t WebRtcG7221C_DecoderInit24(G722_1C_24_decinst_t_* decInst);
// int16_t WebRtcG7221C_DecoderInit32(G722_1C_32_decinst_t_* decInst);
// int16_t WebRtcG7221C_DecoderInit48(G722_1C_48_decinst_t_* decInst);
//
// int16_t WebRtcG7221C_Encode24(G722_1C_24_encinst_t_* encInst,
// int16_t* input,
// int16_t len,
// int16_t* output);
// int16_t WebRtcG7221C_Encode32(G722_1C_32_encinst_t_* encInst,
// int16_t* input,
// int16_t len,
// int16_t* output);
// int16_t WebRtcG7221C_Encode48(G722_1C_48_encinst_t_* encInst,
// int16_t* input,
// int16_t len,
// int16_t* output);
//
// int16_t WebRtcG7221C_Decode24(G722_1C_24_decinst_t_* decInst,
// int16_t* bitstream,
// int16_t len,
// int16_t* output);
// int16_t WebRtcG7221C_Decode32(G722_1C_32_decinst_t_* decInst,
// int16_t* bitstream,
// int16_t len,
// int16_t* output);
// int16_t WebRtcG7221C_Decode48(G722_1C_48_decinst_t_* decInst,
// int16_t* bitstream,
// int16_t len,
// int16_t* output);
//
// int16_t WebRtcG7221C_DecodePlc24(G722_1C_24_decinst_t_* decInst,
// int16_t* output,
// int16_t nrLostFrames);
// int16_t WebRtcG7221C_DecodePlc32(G722_1C_32_decinst_t_* decInst,
// int16_t* output,
// int16_t nrLostFrames);
// int16_t WebRtcG7221C_DecodePlc48(G722_1C_48_decinst_t_* decInst,
// int16_t* output,
// int16_t nrLostFrames);
#include "g7221c_interface.h"
#endif
namespace webrtc {
#ifndef WEBRTC_CODEC_G722_1C
ACMG722_1C::ACMG722_1C(WebRtc_Word16 /* codecID */)
: _operationalRate(-1),
_encoderInstPtr(NULL),
_encoderInstPtrRight(NULL),
_decoderInstPtr(NULL),
_encoderInst24Ptr(NULL),
_encoderInst24PtrR(NULL),
_encoderInst32Ptr(NULL),
_encoderInst32PtrR(NULL),
_encoderInst48Ptr(NULL),
_encoderInst48PtrR(NULL),
_decoderInst24Ptr(NULL),
_decoderInst32Ptr(NULL),
_decoderInst48Ptr(NULL) {
return;
}
ACMG722_1C::~ACMG722_1C() {
return;
}
WebRtc_Word16 ACMG722_1C::InternalEncode(
WebRtc_UWord8* /* bitStream */,
WebRtc_Word16* /* bitStreamLenByte */) {
return -1;
}
WebRtc_Word16 ACMG722_1C::DecodeSafe(WebRtc_UWord8* /* bitStream */,
WebRtc_Word16 /* bitStreamLenByte */,
WebRtc_Word16* /* audio */,
WebRtc_Word16* /* audioSamples */,
WebRtc_Word8* /* speechType */) {
return -1;
}
WebRtc_Word16 ACMG722_1C::InternalInitEncoder(
WebRtcACMCodecParams* /* codecParams */) {
return -1;
}
WebRtc_Word16 ACMG722_1C::InternalInitDecoder(
WebRtcACMCodecParams* /* codecParams */) {
return -1;
}
WebRtc_Word32 ACMG722_1C::CodecDef(WebRtcNetEQ_CodecDef& /* codecDef */,
const CodecInst& /* codecInst */) {
return -1;
}
ACMGenericCodec* ACMG722_1C::CreateInstance(void) {
return NULL;
}
WebRtc_Word16 ACMG722_1C::InternalCreateEncoder() {
return -1;
}
void ACMG722_1C::DestructEncoderSafe() {
return;
}
WebRtc_Word16 ACMG722_1C::InternalCreateDecoder() {
return -1;
}
void ACMG722_1C::DestructDecoderSafe() {
return;
}
void ACMG722_1C::InternalDestructEncoderInst(void* /* ptrInst */) {
return;
}
#else //===================== Actual Implementation =======================
ACMG722_1C::ACMG722_1C(WebRtc_Word16 codecID) :
_encoderInstPtr(NULL), _encoderInstPtrRight(NULL), _decoderInstPtr(NULL),
_encoderInst24Ptr(NULL), _encoderInst24PtrR(NULL), _encoderInst32Ptr(NULL),
_encoderInst32PtrR(NULL), _encoderInst48Ptr(NULL), _encoderInst48PtrR(NULL),
_decoderInst24Ptr(NULL), _decoderInst32Ptr(NULL), _decoderInst48Ptr(NULL) {
_codecID = codecID;
if (_codecID == ACMCodecDB::kG722_1C_24) {
_operationalRate = 24000;
} else if (_codecID == ACMCodecDB::kG722_1C_32) {
_operationalRate = 32000;
} else if (_codecID == ACMCodecDB::kG722_1C_48) {
_operationalRate = 48000;
} else {
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
"Wrong codec id for G722_1c.");
_operationalRate = -1;
}
return;
}
ACMG722_1C::~ACMG722_1C() {
if (_encoderInstPtr != NULL) {
delete _encoderInstPtr;
_encoderInstPtr = NULL;
}
if (_encoderInstPtrRight != NULL) {
delete _encoderInstPtrRight;
_encoderInstPtrRight = NULL;
}
if (_decoderInstPtr != NULL) {
delete _decoderInstPtr;
_decoderInstPtr = NULL;
}
switch (_operationalRate) {
case 24000: {
_encoderInst24Ptr = NULL;
_encoderInst24PtrR = NULL;
_decoderInst24Ptr = NULL;
break;
}
case 32000: {
_encoderInst32Ptr = NULL;
_encoderInst32PtrR = NULL;
_decoderInst32Ptr = NULL;
break;
}
case 48000: {
_encoderInst48Ptr = NULL;
_encoderInst48PtrR = NULL;
_decoderInst48Ptr = NULL;
break;
}
default: {
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
"Wrong rate for G722_1c.");
break;
}
}
return;
}
WebRtc_Word16 ACMG722_1C::InternalEncode(WebRtc_UWord8* bitStream,
WebRtc_Word16* bitStreamLenByte) {
WebRtc_Word16 leftChannel[640];
WebRtc_Word16 rightChannel[640];
WebRtc_Word16 lenInBytes;
WebRtc_Word16 outB[240];
// If stereo, split input signal in left and right channel before encoding
if (_noChannels == 2) {
for (int i = 0, j = 0; i < _frameLenSmpl * 2; i += 2, j++) {
leftChannel[j] = _inAudio[_inAudioIxRead + i];
rightChannel[j] = _inAudio[_inAudioIxRead + i + 1];
}
} else {
memcpy(leftChannel, &_inAudio[_inAudioIxRead], 640);
}
switch (_operationalRate) {
case 24000: {
lenInBytes = WebRtcG7221C_Encode24(_encoderInst24Ptr, leftChannel, 640,
&outB[0]);
if (_noChannels == 2) {
lenInBytes += WebRtcG7221C_Encode24(_encoderInst24PtrR, rightChannel,
640, &outB[lenInBytes / 2]);
}
break;
}
case 32000: {
lenInBytes = WebRtcG7221C_Encode32(_encoderInst32Ptr, leftChannel, 640,
&outB[0]);
if (_noChannels == 2) {
lenInBytes += WebRtcG7221C_Encode32(_encoderInst32PtrR, rightChannel,
640, &outB[lenInBytes / 2]);
}
break;
}
case 48000: {
lenInBytes = WebRtcG7221C_Encode48(_encoderInst48Ptr, leftChannel, 640,
&outB[0]);
if (_noChannels == 2) {
lenInBytes += WebRtcG7221C_Encode48(_encoderInst48PtrR, rightChannel,
640, &outB[lenInBytes / 2]);
}
break;
}
default: {
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
"InternalEncode: Wrong rate for G722_1c.");
return -1;
}
}
memcpy(bitStream, outB, lenInBytes);
*bitStreamLenByte = lenInBytes;
// increment the read index this tell the caller that how far
// we have gone forward in reading the audio buffer
_inAudioIxRead += 640 * _noChannels;
return *bitStreamLenByte;
}
WebRtc_Word16 ACMG722_1C::DecodeSafe(WebRtc_UWord8* /* bitStream */,
WebRtc_Word16 /* bitStreamLenByte */,
WebRtc_Word16* /* audio */,
WebRtc_Word16* /* audioSamples */,
WebRtc_Word8* /* speechType */) {
return 0;
}
WebRtc_Word16 ACMG722_1C::InternalInitEncoder(
WebRtcACMCodecParams* codecParams) {
WebRtc_Word16 ret;
switch (_operationalRate) {
case 24000: {
ret = WebRtcG7221C_EncoderInit24(_encoderInst24PtrR);
if (ret < 0) {
return ret;
}
return WebRtcG7221C_EncoderInit24(_encoderInst24Ptr);
}
case 32000: {
ret = WebRtcG7221C_EncoderInit32(_encoderInst32PtrR);
if (ret < 0) {
return ret;
}
return WebRtcG7221C_EncoderInit32(_encoderInst32Ptr);
}
case 48000: {
ret = WebRtcG7221C_EncoderInit48(_encoderInst48PtrR);
if (ret < 0) {
return ret;
}
return WebRtcG7221C_EncoderInit48(_encoderInst48Ptr);
}
default: {
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
"InternalInitEncode: Wrong rate for G722_1c.");
return -1;
}
}
}
WebRtc_Word16 ACMG722_1C::InternalInitDecoder(
WebRtcACMCodecParams* /* codecParams */) {
switch (_operationalRate) {
case 24000: {
return WebRtcG7221C_DecoderInit24(_decoderInst24Ptr);
}
case 32000: {
return WebRtcG7221C_DecoderInit32(_decoderInst32Ptr);
}
case 48000: {
return WebRtcG7221C_DecoderInit48(_decoderInst48Ptr);
}
default: {
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
"InternalInitDecoder: Wrong rate for G722_1c.");
return -1;
}
}
}
WebRtc_Word32 ACMG722_1C::CodecDef(WebRtcNetEQ_CodecDef& codecDef,
const CodecInst& codecInst) {
if (!_decoderInitialized) {
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
"CodeDef: decoder not initialized for G722_1c");
return -1;
}
// NetEq has an array of pointers to WebRtcNetEQ_CodecDef.
// get an entry of that array (neteq wrapper will allocate memory)
// by calling "netEq->CodecDef", where "NETEQ_CODEC_G722_1_XX" would
// be the index of the entry.
// Fill up the given structure by calling
// "SET_CODEC_PAR" & "SET_G722_1_XX_FUNCTION."
// Then return the structure back to NetEQ to add the codec to it's
// database.
switch (_operationalRate) {
case 24000: {
SET_CODEC_PAR((codecDef), kDecoderG722_1C_24, codecInst.pltype,
_decoderInst24Ptr, 32000);
SET_G722_1C_24_FUNCTIONS((codecDef));
break;
}
case 32000: {
SET_CODEC_PAR((codecDef), kDecoderG722_1C_32, codecInst.pltype,
_decoderInst32Ptr, 32000);
SET_G722_1C_32_FUNCTIONS((codecDef));
break;
}
case 48000: {
SET_CODEC_PAR((codecDef), kDecoderG722_1C_32, codecInst.pltype,
_decoderInst48Ptr, 32000);
SET_G722_1C_48_FUNCTIONS((codecDef));
break;
}
default: {
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
"CodeDef: Wrong rate for G722_1c.");
return -1;
}
}
return 0;
}
ACMGenericCodec*
ACMG722_1C::CreateInstance(void) {
return NULL;
}
WebRtc_Word16 ACMG722_1C::InternalCreateEncoder() {
if ((_encoderInstPtr == NULL) || (_encoderInstPtrRight == NULL)) {
return -1;
}
switch (_operationalRate) {
case 24000: {
WebRtcG7221C_CreateEnc24(&_encoderInst24Ptr);
WebRtcG7221C_CreateEnc24(&_encoderInst24PtrR);
break;
}
case 32000: {
WebRtcG7221C_CreateEnc32(&_encoderInst32Ptr);
WebRtcG7221C_CreateEnc32(&_encoderInst32PtrR);
break;
}
case 48000: {
WebRtcG7221C_CreateEnc48(&_encoderInst48Ptr);
WebRtcG7221C_CreateEnc48(&_encoderInst48PtrR);
break;
}
default: {
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
"InternalCreateEncoder: Wrong rate for G722_1c.");
return -1;
}
}
return 0;
}
void ACMG722_1C::DestructEncoderSafe() {
_encoderExist = false;
_encoderInitialized = false;
if (_encoderInstPtr != NULL) {
delete _encoderInstPtr;
_encoderInstPtr = NULL;
}
if (_encoderInstPtrRight != NULL) {
delete _encoderInstPtrRight;
_encoderInstPtrRight = NULL;
}
_encoderInst24Ptr = NULL;
_encoderInst32Ptr = NULL;
_encoderInst48Ptr = NULL;
}
WebRtc_Word16 ACMG722_1C::InternalCreateDecoder() {
if (_decoderInstPtr == NULL) {
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
"InternalCreateEncoder: cannot create decoder");
return -1;
}
switch (_operationalRate) {
case 24000: {
WebRtcG7221C_CreateDec24(&_decoderInst24Ptr);
break;
}
case 32000: {
WebRtcG7221C_CreateDec32(&_decoderInst32Ptr);
break;
}
case 48000: {
WebRtcG7221C_CreateDec48(&_decoderInst48Ptr);
break;
}
default: {
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
"InternalCreateEncoder: Wrong rate for G722_1c.");
return -1;
}
}
return 0;
}
void ACMG722_1C::DestructDecoderSafe() {
_decoderExist = false;
_decoderInitialized = false;
if (_decoderInstPtr != NULL) {
delete _decoderInstPtr;
_decoderInstPtr = NULL;
}
_decoderInst24Ptr = NULL;
_decoderInst32Ptr = NULL;
_decoderInst48Ptr = NULL;
}
void ACMG722_1C::InternalDestructEncoderInst(void* ptrInst) {
if (ptrInst != NULL) {
delete ptrInst;
}
return;
}
#endif
} // namespace webrtc

View File

@ -0,0 +1,90 @@
/*
* 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_MAIN_SOURCE_ACM_G722_1C_H_
#define WEBRTC_MODULES_AUDIO_CODING_MAIN_SOURCE_ACM_G722_1C_H_
#include "acm_generic_codec.h"
// forward declaration
struct G722_1C_24_encinst_t_;
struct G722_1C_24_decinst_t_;
struct G722_1C_32_encinst_t_;
struct G722_1C_32_decinst_t_;
struct G722_1C_48_encinst_t_;
struct G722_1C_48_decinst_t_;
struct G722_1_Inst_t_;
namespace webrtc {
class ACMG722_1C : public ACMGenericCodec
{
public:
ACMG722_1C(WebRtc_Word16 codecID);
~ACMG722_1C();
// for FEC
ACMGenericCodec* CreateInstance(void);
WebRtc_Word16 InternalEncode(
WebRtc_UWord8* bitstream,
WebRtc_Word16* bitStreamLenByte);
WebRtc_Word16 InternalInitEncoder(
WebRtcACMCodecParams *codecParams);
WebRtc_Word16 InternalInitDecoder(
WebRtcACMCodecParams *codecParams);
protected:
WebRtc_Word16 DecodeSafe(
WebRtc_UWord8* bitStream,
WebRtc_Word16 bitStreamLenByte,
WebRtc_Word16* audio,
WebRtc_Word16* audioSamples,
WebRtc_Word8* speechType);
WebRtc_Word32 CodecDef(
WebRtcNetEQ_CodecDef& codecDef,
const CodecInst& codecInst);
void DestructEncoderSafe();
void DestructDecoderSafe();
WebRtc_Word16 InternalCreateEncoder();
WebRtc_Word16 InternalCreateDecoder();
void InternalDestructEncoderInst(
void* ptrInst);
WebRtc_Word32 _operationalRate;
G722_1_Inst_t_* _encoderInstPtr;
G722_1_Inst_t_* _encoderInstPtrRight; //Used in stereo mode
G722_1_Inst_t_* _decoderInstPtr;
// Only one set of these pointer is valid at any instance
G722_1C_24_encinst_t_* _encoderInst24Ptr;
G722_1C_24_encinst_t_* _encoderInst24PtrR;
G722_1C_32_encinst_t_* _encoderInst32Ptr;
G722_1C_32_encinst_t_* _encoderInst32PtrR;
G722_1C_48_encinst_t_* _encoderInst48Ptr;
G722_1C_48_encinst_t_* _encoderInst48PtrR;
// Only one of these pointer is valid at any instance
G722_1C_24_decinst_t_* _decoderInst24Ptr;
G722_1C_32_decinst_t_* _decoderInst32Ptr;
G722_1C_48_decinst_t_* _decoderInst48Ptr;
};
} // namespace webrtc;
#endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_SOURCE_ACM_G722_1C_H_

View File

@ -0,0 +1,515 @@
/*
* 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 "acm_g729.h"
#include "acm_common_defs.h"
#include "acm_neteq.h"
#include "trace.h"
#include "webrtc_neteq.h"
#include "webrtc_neteq_help_macros.h"
#ifdef WEBRTC_CODEC_G729
// NOTE! G.729 is not included in the open-source package. The following
// interface file is needed:
//
// /modules/audio_coding/codecs/g729/main/interface/g729_interface.h
//
// The API in the header file should match the one below.
//
// int16_t WebRtcG729_CreateEnc(G729_encinst_t_** inst);
// int16_t WebRtcG729_CreateDec(G729_decinst_t_** inst);
// int16_t WebRtcG729_FreeEnc(G729_encinst_t_* inst);
// int16_t WebRtcG729_FreeDec(G729_decinst_t_* inst);
// int16_t WebRtcG729_Encode(G729_encinst_t_* encInst, int16_t* input,
// int16_t len, int16_t* output);
// int16_t WebRtcG729_EncoderInit(G729_encinst_t_* encInst, int16_t mode);
// int16_t WebRtcG729_Decode(G729_decinst_t_* decInst);
// int16_t WebRtcG729_DecodeBwe(G729_decinst_t_* decInst, int16_t* input);
// int16_t WebRtcG729_DecodePlc(G729_decinst_t_* decInst);
// int16_t WebRtcG729_DecoderInit(G729_decinst_t_* decInst);
#include "g729_interface.h"
#endif
namespace webrtc {
#ifndef WEBRTC_CODEC_G729
ACMG729::ACMG729(WebRtc_Word16 /* codecID */)
: _encoderInstPtr(NULL),
_decoderInstPtr(NULL) {
return;
}
ACMG729::~ACMG729()
{
return;
}
WebRtc_Word16
ACMG729::InternalEncode(
WebRtc_UWord8* /* bitStream */,
WebRtc_Word16* /* bitStreamLenByte */)
{
return -1;
}
WebRtc_Word16
ACMG729::EnableDTX()
{
return -1;
}
WebRtc_Word16
ACMG729::DisableDTX()
{
return -1;
}
WebRtc_Word32
ACMG729::ReplaceInternalDTXSafe(
const bool /*replaceInternalDTX*/)
{
return -1;
}
WebRtc_Word32
ACMG729::IsInternalDTXReplacedSafe(
bool* /* internalDTXReplaced */)
{
return -1;
}
WebRtc_Word16
ACMG729::DecodeSafe(
WebRtc_UWord8* /* bitStream */,
WebRtc_Word16 /* bitStreamLenByte */,
WebRtc_Word16* /* audio */,
WebRtc_Word16* /* audioSamples */,
WebRtc_Word8* /* speechType */)
{
return -1;
}
WebRtc_Word16
ACMG729::InternalInitEncoder(
WebRtcACMCodecParams* /* codecParams */)
{
return -1;
}
WebRtc_Word16
ACMG729::InternalInitDecoder(
WebRtcACMCodecParams* /* codecParams */)
{
return -1;
}
WebRtc_Word32
ACMG729::CodecDef(
WebRtcNetEQ_CodecDef& /* codecDef */,
const CodecInst& /* codecInst */)
{
return -1;
}
ACMGenericCodec*
ACMG729::CreateInstance(void)
{
return NULL;
}
WebRtc_Word16
ACMG729::InternalCreateEncoder()
{
return -1;
}
void
ACMG729::DestructEncoderSafe()
{
return;
}
WebRtc_Word16
ACMG729::InternalCreateDecoder()
{
return -1;
}
void
ACMG729::DestructDecoderSafe()
{
return;
}
void
ACMG729::InternalDestructEncoderInst(
void* /* ptrInst */)
{
return;
}
#else //===================== Actual Implementation =======================
ACMG729::ACMG729(
WebRtc_Word16 codecID):
_encoderInstPtr(NULL),
_decoderInstPtr(NULL)
{
_codecID = codecID;
_hasInternalDTX = true;
return;
}
ACMG729::~ACMG729()
{
if(_encoderInstPtr != NULL)
{
// Delete encoder memory
WebRtcG729_FreeEnc(_encoderInstPtr);
_encoderInstPtr = NULL;
}
if(_decoderInstPtr != NULL)
{
// Delete decoder memory
WebRtcG729_FreeDec(_decoderInstPtr);
_decoderInstPtr = NULL;
}
return;
}
WebRtc_Word16
ACMG729::InternalEncode(
WebRtc_UWord8* bitStream,
WebRtc_Word16* bitStreamLenByte)
{
// Initialize before entering the loop
WebRtc_Word16 noEncodedSamples = 0;
WebRtc_Word16 tmpLenByte = 0;
WebRtc_Word16 vadDecision = 0;
*bitStreamLenByte = 0;
while(noEncodedSamples < _frameLenSmpl)
{
// Call G.729 encoder with pointer to encoder memory, input
// audio, number of samples and bitsream
tmpLenByte = WebRtcG729_Encode(_encoderInstPtr,
&_inAudio[_inAudioIxRead], 80,
(WebRtc_Word16*)(&(bitStream[*bitStreamLenByte])));
// increment the read index this tell the caller that how far
// we have gone forward in reading the audio buffer
_inAudioIxRead += 80;
// sanity check
if(tmpLenByte < 0)
{
// error has happened
*bitStreamLenByte = 0;
return -1;
}
// increment number of written bytes
*bitStreamLenByte += tmpLenByte;
switch(tmpLenByte)
{
case 0:
{
if(0 == noEncodedSamples)
{
// this is the first 10 ms in this packet and there is
// no data generated, perhaps DTX is enabled and the
// codec is not generating any bit-stream for this 10 ms.
// we do not continue encoding this frame.
return 0;
}
break;
}
case 2:
{
// check if G.729 internal DTX is enabled
if(_hasInternalDTX && _dtxEnabled)
{
vadDecision = 0;
for(WebRtc_Word16 n = 0; n < MAX_FRAME_SIZE_10MSEC; n++)
{
_vadLabel[n] = vadDecision;
}
}
// we got a SID and have to send out this packet no matter
// how much audio we have encoded
return *bitStreamLenByte;
}
case 10:
{
vadDecision = 1;
// this is a valid length just continue encoding
break;
}
default:
{
return -1;
}
}
// update number of encoded samples
noEncodedSamples += 80;
}
// update VAD decision vector
if(_hasInternalDTX && !vadDecision && _dtxEnabled)
{
for(WebRtc_Word16 n = 0; n < MAX_FRAME_SIZE_10MSEC; n++)
{
_vadLabel[n] = vadDecision;
}
}
// done encoding, return number of encoded bytes
return *bitStreamLenByte;
}
WebRtc_Word16
ACMG729::EnableDTX()
{
if(_dtxEnabled)
{
// DTX already enabled, do nothing
return 0;
}
else if(_encoderExist)
{
// Re-init the G.729 encoder to turn on DTX
if(WebRtcG729_EncoderInit(_encoderInstPtr, 1) < 0)
{
return -1;
}
_dtxEnabled = true;
return 0;
}
else
{
return -1;
}
}
WebRtc_Word16
ACMG729::DisableDTX()
{
if(!_dtxEnabled)
{
// DTX already dissabled, do nothing
return 0;
}
else if(_encoderExist)
{
// Re-init the G.729 decoder to turn off DTX
if(WebRtcG729_EncoderInit(_encoderInstPtr, 0) < 0)
{
return -1;
}
_dtxEnabled = false;
return 0;
}
else
{
// encoder doesn't exists, therefore disabling is harmless
return 0;
}
}
WebRtc_Word32
ACMG729::ReplaceInternalDTXSafe(
const bool replaceInternalDTX)
{
// This function is used to dissable the G.729 built in DTX and use an
// external instead.
if(replaceInternalDTX == _hasInternalDTX)
{
// Make sure we keep the DTX/VAD setting if possible
bool oldEnableDTX = _dtxEnabled;
bool oldEnableVAD = _vadEnabled;
ACMVADMode oldMode = _vadMode;
if (replaceInternalDTX)
{
// Disable internal DTX before enabling external DTX
DisableDTX();
}
else
{
// Disable external DTX before enabling internal
ACMGenericCodec::DisableDTX();
}
_hasInternalDTX = !replaceInternalDTX;
WebRtc_Word16 status = SetVADSafe(oldEnableDTX, oldEnableVAD, oldMode);
// Check if VAD status has changed from inactive to active, or if error was
// reported
if (status == 1) {
_vadEnabled = true;
return status;
} else if (status < 0) {
_hasInternalDTX = replaceInternalDTX;
return -1;
}
}
return 0;
}
WebRtc_Word32
ACMG729::IsInternalDTXReplacedSafe(
bool* internalDTXReplaced)
{
// Get status of wether DTX is replaced or not
*internalDTXReplaced = !_hasInternalDTX;
return 0;
}
WebRtc_Word16
ACMG729::DecodeSafe(
WebRtc_UWord8* /* bitStream */,
WebRtc_Word16 /* bitStreamLenByte */,
WebRtc_Word16* /* audio */,
WebRtc_Word16* /* audioSamples */,
WebRtc_Word8* /* speechType */)
{
// This function is not used. G.729 decoder is called from inside NetEQ
return 0;
}
WebRtc_Word16
ACMG729::InternalInitEncoder(
WebRtcACMCodecParams* codecParams)
{
// Init G.729 encoder
return WebRtcG729_EncoderInit(_encoderInstPtr,
((codecParams->enableDTX)? 1:0));
}
WebRtc_Word16
ACMG729::InternalInitDecoder(
WebRtcACMCodecParams* /* codecParams */)
{
// Init G.729 decoder
return WebRtcG729_DecoderInit(_decoderInstPtr);
}
WebRtc_Word32
ACMG729::CodecDef(
WebRtcNetEQ_CodecDef& codecDef,
const CodecInst& codecInst)
{
if (!_decoderInitialized)
{
// Todo:
// log error
return -1;
}
// Fill up the structure by calling
// "SET_CODEC_PAR" & "SET_G729_FUNCTION."
// Then call NetEQ to add the codec to it's
// database.
SET_CODEC_PAR((codecDef), kDecoderG729, codecInst.pltype,
_decoderInstPtr, 8000);
SET_G729_FUNCTIONS((codecDef));
return 0;
}
ACMGenericCodec*
ACMG729::CreateInstance(void)
{
// Function not used
return NULL;
}
WebRtc_Word16
ACMG729::InternalCreateEncoder()
{
// Create encoder memory
return WebRtcG729_CreateEnc(&_encoderInstPtr);
}
void
ACMG729::DestructEncoderSafe()
{
// Free encoder memory
_encoderExist = false;
_encoderInitialized = false;
if(_encoderInstPtr != NULL)
{
WebRtcG729_FreeEnc(_encoderInstPtr);
_encoderInstPtr = NULL;
}
}
WebRtc_Word16
ACMG729::InternalCreateDecoder()
{
// Create decoder memory
return WebRtcG729_CreateDec(&_decoderInstPtr);
}
void
ACMG729::DestructDecoderSafe()
{
// Free decoder memory
_decoderExist = false;
_decoderInitialized = false;
if(_decoderInstPtr != NULL)
{
WebRtcG729_FreeDec(_decoderInstPtr);
_decoderInstPtr = NULL;
}
}
void
ACMG729::InternalDestructEncoderInst(
void* ptrInst)
{
if(ptrInst != NULL)
{
WebRtcG729_FreeEnc((G729_encinst_t_*)ptrInst);
}
return;
}
#endif
} // namespace webrtc

View File

@ -0,0 +1,80 @@
/*
* 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_MAIN_SOURCE_ACM_G729_H_
#define WEBRTC_MODULES_AUDIO_CODING_MAIN_SOURCE_ACM_G729_H_
#include "acm_generic_codec.h"
// forward declaration
struct G729_encinst_t_;
struct G729_decinst_t_;
namespace webrtc {
class ACMG729 : public ACMGenericCodec
{
public:
ACMG729(WebRtc_Word16 codecID);
~ACMG729();
// for FEC
ACMGenericCodec* CreateInstance(void);
WebRtc_Word16 InternalEncode(
WebRtc_UWord8* bitstream,
WebRtc_Word16* bitStreamLenByte);
WebRtc_Word16 InternalInitEncoder(
WebRtcACMCodecParams *codecParams);
WebRtc_Word16 InternalInitDecoder(
WebRtcACMCodecParams *codecParams);
protected:
WebRtc_Word16 DecodeSafe(
WebRtc_UWord8* bitStream,
WebRtc_Word16 bitStreamLenByte,
WebRtc_Word16* audio,
WebRtc_Word16* audioSamples,
WebRtc_Word8* speechType);
WebRtc_Word32 CodecDef(
WebRtcNetEQ_CodecDef& codecDef,
const CodecInst& codecInst);
void DestructEncoderSafe();
void DestructDecoderSafe();
WebRtc_Word16 InternalCreateEncoder();
WebRtc_Word16 InternalCreateDecoder();
void InternalDestructEncoderInst(
void* ptrInst);
WebRtc_Word16 EnableDTX();
WebRtc_Word16 DisableDTX();
WebRtc_Word32 ReplaceInternalDTXSafe(
const bool replaceInternalDTX);
WebRtc_Word32 IsInternalDTXReplacedSafe(
bool* internalDTXReplaced);
G729_encinst_t_* _encoderInstPtr;
G729_decinst_t_* _decoderInstPtr;
};
} // namespace webrtc
#endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_SOURCE_ACM_G729_H_

View File

@ -0,0 +1,471 @@
/*
* 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 "acm_g7291.h"
#include "acm_common_defs.h"
#include "acm_neteq.h"
#include "trace.h"
#include "webrtc_neteq.h"
#include "webrtc_neteq_help_macros.h"
#ifdef WEBRTC_CODEC_G729_1
// NOTE! G.729.1 is not included in the open-source package. The following
// interface file is needed:
//
// /modules/audio_coding/codecs/g7291/main/interface/g7291_interface.h
//
// The API in the header file should match the one below.
//
// int16_t WebRtcG7291_Create(G729_1_inst_t_** inst);
// int16_t WebRtcG7291_Free(G729_1_inst_t_* inst);
// int16_t WebRtcG7291_Encode(G729_1_inst_t_* encInst, int16_t* input,
// int16_t* output, int16_t myRate,
// int16_t nrFrames);
// int16_t WebRtcG7291_EncoderInit(G729_1_inst_t_* encInst, int16_t myRate,
// int16_t flag8kHz, int16_t flagG729mode);
// int16_t WebRtcG7291_Decode(G729_1_inst_t_* decInst);
// int16_t WebRtcG7291_DecodeBwe(G729_1_inst_t_* decInst, int16_t* input);
// int16_t WebRtcG7291_DecodePlc(G729_1_inst_t_* decInst);
// int16_t WebRtcG7291_DecoderInit(G729_1_inst_t_* decInst);
#include "g7291_interface.h"
#endif
namespace webrtc {
#ifndef WEBRTC_CODEC_G729_1
ACMG729_1::ACMG729_1( WebRtc_Word16 /* codecID */)
: _encoderInstPtr(NULL),
_decoderInstPtr(NULL),
_myRate(32000),
_flag8kHz(0),
_flagG729mode(0) {
return;
}
ACMG729_1::~ACMG729_1()
{
return;
}
WebRtc_Word16
ACMG729_1::InternalEncode(
WebRtc_UWord8* /* bitStream */,
WebRtc_Word16* /* bitStreamLenByte */)
{
return -1;
}
WebRtc_Word16
ACMG729_1::DecodeSafe(
WebRtc_UWord8* /* bitStream */,
WebRtc_Word16 /* bitStreamLenByte */,
WebRtc_Word16* /* audio */,
WebRtc_Word16* /* audioSamples */,
WebRtc_Word8* /* speechType */)
{
return -1;
}
WebRtc_Word16
ACMG729_1::InternalInitEncoder(
WebRtcACMCodecParams* /* codecParams */)
{
return -1;
}
WebRtc_Word16
ACMG729_1::InternalInitDecoder(
WebRtcACMCodecParams* /* codecParams */)
{
return -1;
}
WebRtc_Word32
ACMG729_1::CodecDef(
WebRtcNetEQ_CodecDef& /* codecDef */,
const CodecInst& /* codecInst */)
{
return -1;
}
ACMGenericCodec*
ACMG729_1::CreateInstance(void)
{
return NULL;
}
WebRtc_Word16
ACMG729_1::InternalCreateEncoder()
{
return -1;
}
void
ACMG729_1::DestructEncoderSafe()
{
return;
}
WebRtc_Word16
ACMG729_1::InternalCreateDecoder()
{
return -1;
}
void
ACMG729_1::DestructDecoderSafe()
{
return;
}
void
ACMG729_1::InternalDestructEncoderInst(
void* /* ptrInst */)
{
return;
}
WebRtc_Word16
ACMG729_1::SetBitRateSafe(
const WebRtc_Word32 /*rate*/ )
{
return -1;
}
#else //===================== Actual Implementation =======================
struct G729_1_inst_t_;
ACMG729_1::ACMG729_1(WebRtc_Word16 codecID)
: _encoderInstPtr(NULL),
_decoderInstPtr(NULL),
_myRate(32000), // Default rate.
_flag8kHz(0),
_flagG729mode(0) {
// TODO(tlegrand): We should add codecID as a input variable to the
// constructor of ACMGenericCodec.
_codecID = codecID;
return;
}
ACMG729_1::~ACMG729_1()
{
if(_encoderInstPtr != NULL)
{
WebRtcG7291_Free(_encoderInstPtr);
_encoderInstPtr = NULL;
}
if(_decoderInstPtr != NULL)
{
WebRtcG7291_Free(_decoderInstPtr);
_decoderInstPtr = NULL;
}
return;
}
WebRtc_Word16
ACMG729_1::InternalEncode(
WebRtc_UWord8* bitStream,
WebRtc_Word16* bitStreamLenByte)
{
// Initialize before entering the loop
WebRtc_Word16 noEncodedSamples = 0;
*bitStreamLenByte = 0;
WebRtc_Word16 byteLengthFrame = 0;
// Derive number of 20ms frames per encoded packet.
// [1,2,3] <=> [20,40,60]ms <=> [320,640,960] samples
WebRtc_Word16 n20msFrames = (_frameLenSmpl / 320);
// Byte length for the frame. +1 is for rate information.
byteLengthFrame = _myRate/(8*50) * n20msFrames + (1 - _flagG729mode);
// The following might be revised if we have G729.1 Annex C (support for DTX);
do
{
*bitStreamLenByte = WebRtcG7291_Encode(_encoderInstPtr, &_inAudio[_inAudioIxRead],
(WebRtc_Word16*)bitStream, _myRate, n20msFrames);
// increment the read index this tell the caller that how far
// we have gone forward in reading the audio buffer
_inAudioIxRead += 160;
// sanity check
if(*bitStreamLenByte < 0)
{
// error has happened
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
"InternalEncode: Encode error for G729_1");
*bitStreamLenByte = 0;
return -1;
}
noEncodedSamples += 160;
} while(*bitStreamLenByte == 0);
// This criteria will change if we have Annex C.
if(*bitStreamLenByte != byteLengthFrame)
{
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
"InternalEncode: Encode error for G729_1");
*bitStreamLenByte = 0;
return -1;
}
if(noEncodedSamples != _frameLenSmpl)
{
*bitStreamLenByte = 0;
return -1;
}
return *bitStreamLenByte;
}
WebRtc_Word16
ACMG729_1::DecodeSafe(
WebRtc_UWord8* /* bitStream */,
WebRtc_Word16 /* bitStreamLenByte */,
WebRtc_Word16* /* audio */,
WebRtc_Word16* /* audioSamples */,
WebRtc_Word8* /* speechType */)
{
return 0;
}
WebRtc_Word16
ACMG729_1::InternalInitEncoder(
WebRtcACMCodecParams* codecParams)
{
//set the bit rate and initialize
_myRate = codecParams->codecInstant.rate;
return SetBitRateSafe( (WebRtc_UWord32)_myRate);
}
WebRtc_Word16
ACMG729_1::InternalInitDecoder(
WebRtcACMCodecParams* /* codecParams */)
{
if (WebRtcG7291_DecoderInit(_decoderInstPtr) < 0)
{
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
"InternalInitDecoder: init decoder failed for G729_1");
return -1;
}
return 0;
}
WebRtc_Word32
ACMG729_1::CodecDef(
WebRtcNetEQ_CodecDef& codecDef,
const CodecInst& codecInst)
{
if (!_decoderInitialized)
{
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
"CodeDef: Decoder uninitialized for G729_1");
return -1;
}
// Fill up the structure by calling
// "SET_CODEC_PAR" & "SET_G729_FUNCTION."
// Then call NetEQ to add the codec to it's
// database.
SET_CODEC_PAR((codecDef), kDecoderG729_1, codecInst.pltype,
_decoderInstPtr, 16000);
SET_G729_1_FUNCTIONS((codecDef));
return 0;
}
ACMGenericCodec*
ACMG729_1::CreateInstance(void)
{
return NULL;
}
WebRtc_Word16
ACMG729_1::InternalCreateEncoder()
{
if (WebRtcG7291_Create(&_encoderInstPtr) < 0)
{
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
"InternalCreateEncoder: create encoder failed for G729_1");
return -1;
}
return 0;
}
void
ACMG729_1::DestructEncoderSafe()
{
_encoderExist = false;
_encoderInitialized = false;
if(_encoderInstPtr != NULL)
{
WebRtcG7291_Free(_encoderInstPtr);
_encoderInstPtr = NULL;
}
}
WebRtc_Word16
ACMG729_1::InternalCreateDecoder()
{
if (WebRtcG7291_Create(&_decoderInstPtr) < 0)
{
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
"InternalCreateDecoder: create decoder failed for G729_1");
return -1;
}
return 0;
}
void
ACMG729_1::DestructDecoderSafe()
{
_decoderExist = false;
_decoderInitialized = false;
if(_decoderInstPtr != NULL)
{
WebRtcG7291_Free(_decoderInstPtr);
_decoderInstPtr = NULL;
}
}
void
ACMG729_1::InternalDestructEncoderInst(
void* ptrInst)
{
if(ptrInst != NULL)
{
//WebRtcG7291_Free((G729_1_inst_t*)ptrInst);
}
return;
}
WebRtc_Word16
ACMG729_1::SetBitRateSafe(
const WebRtc_Word32 rate)
{
//allowed rates: { 8000, 12000, 14000, 16000, 18000, 20000,
// 22000, 24000, 26000, 28000, 30000, 32000};
// TODO(tlegrand): This check exists in one other place two. Should be
// possible to reuse code.
switch(rate)
{
case 8000:
{
_myRate = 8000;
break;
}
case 12000:
{
_myRate = 12000;
break;
}
case 14000:
{
_myRate = 14000;
break;
}
case 16000:
{
_myRate = 16000;
break;
}
case 18000:
{
_myRate = 18000;
break;
}
case 20000:
{
_myRate = 20000;
break;
}
case 22000:
{
_myRate = 22000;
break;
}
case 24000:
{
_myRate = 24000;
break;
}
case 26000:
{
_myRate = 26000;
break;
}
case 28000:
{
_myRate = 28000;
break;
}
case 30000:
{
_myRate = 30000;
break;
}
case 32000:
{
_myRate = 32000;
break;
}
default:
{
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
"SetBitRateSafe: Invalid rate G729_1");
return -1;
}
}
// Re-init with new rate
if (WebRtcG7291_EncoderInit(_encoderInstPtr, _myRate, _flag8kHz, _flagG729mode) >= 0)
{
_encoderParams.codecInstant.rate = _myRate;
return 0;
}
else
{
return -1;
}
}
#endif
} // namespace webrtc

View File

@ -0,0 +1,77 @@
/*
* 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_MAIN_SOURCE_ACM_G729_1_H_
#define WEBRTC_MODULES_AUDIO_CODING_MAIN_SOURCE_ACM_G729_1_H_
#include "acm_generic_codec.h"
// forward declaration
struct G729_1_inst_t_;
struct G729_1_inst_t_;
namespace webrtc {
class ACMG729_1: public ACMGenericCodec
{
public:
ACMG729_1(WebRtc_Word16 codecID);
~ACMG729_1();
// for FEC
ACMGenericCodec* CreateInstance(void);
WebRtc_Word16 InternalEncode(
WebRtc_UWord8* bitstream,
WebRtc_Word16* bitStreamLenByte);
WebRtc_Word16 InternalInitEncoder(
WebRtcACMCodecParams *codecParams);
WebRtc_Word16 InternalInitDecoder(
WebRtcACMCodecParams *codecParams);
protected:
WebRtc_Word16 DecodeSafe(
WebRtc_UWord8* bitStream,
WebRtc_Word16 bitStreamLenByte,
WebRtc_Word16* audio,
WebRtc_Word16* audioSamples,
WebRtc_Word8* speechType);
WebRtc_Word32 CodecDef(
WebRtcNetEQ_CodecDef& codecDef,
const CodecInst& codecInst);
void DestructEncoderSafe();
void DestructDecoderSafe();
WebRtc_Word16 InternalCreateEncoder();
WebRtc_Word16 InternalCreateDecoder();
void InternalDestructEncoderInst(
void* ptrInst);
WebRtc_Word16 SetBitRateSafe(
const WebRtc_Word32 rate);
G729_1_inst_t_* _encoderInstPtr;
G729_1_inst_t_* _decoderInstPtr;
WebRtc_UWord16 _myRate;
WebRtc_Word16 _flag8kHz;
WebRtc_Word16 _flagG729mode;
};
} // namespace webrtc
#endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_SOURCE_ACM_G729_1_H_

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,386 @@
/*
* 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 "acm_gsmfr.h"
#include "acm_common_defs.h"
#include "acm_neteq.h"
#include "trace.h"
#include "webrtc_neteq.h"
#include "webrtc_neteq_help_macros.h"
#ifdef WEBRTC_CODEC_GSMFR
// NOTE! GSM-FR is not included in the open-source package. The following
// interface file is needed:
//
// /modules/audio_coding/codecs/gsmfr/main/interface/gsmfr_interface.h
//
// The API in the header file should match the one below.
//
// int16_t WebRtcGSMFR_CreateEnc(GSMFR_encinst_t_** inst);
// int16_t WebRtcGSMFR_CreateDec(GSMFR_decinst_t_** inst);
// int16_t WebRtcGSMFR_FreeEnc(GSMFR_encinst_t_* inst);
// int16_t WebRtcGSMFR_FreeDec(GSMFR_decinst_t_* inst);
// int16_t WebRtcGSMFR_Encode(GSMFR_encinst_t_* encInst, int16_t* input,
// int16_t len, int16_t* output);
// int16_t WebRtcGSMFR_EncoderInit(GSMFR_encinst_t_* encInst, int16_t mode);
// int16_t WebRtcGSMFR_Decode(GSMFR_decinst_t_* decInst);
// int16_t WebRtcGSMFR_DecodeBwe(GSMFR_decinst_t_* decInst, int16_t* input);
// int16_t WebRtcGSMFR_DecodePlc(GSMFR_decinst_t_* decInst);
// int16_t WebRtcGSMFR_DecoderInit(GSMFR_decinst_t_* decInst);
#include "gsmfr_interface.h"
#endif
namespace webrtc {
#ifndef WEBRTC_CODEC_GSMFR
ACMGSMFR::ACMGSMFR(WebRtc_Word16 /* codecID */)
: _encoderInstPtr(NULL),
_decoderInstPtr(NULL) {
return;
}
ACMGSMFR::~ACMGSMFR()
{
return;
}
WebRtc_Word16
ACMGSMFR::InternalEncode(
WebRtc_UWord8* /* bitStream */,
WebRtc_Word16* /* bitStreamLenByte */)
{
return -1;
}
WebRtc_Word16
ACMGSMFR::DecodeSafe(
WebRtc_UWord8* /* bitStream */,
WebRtc_Word16 /* bitStreamLenByte */,
WebRtc_Word16* /* audio */,
WebRtc_Word16* /* audioSamples */,
WebRtc_Word8* /* speechType */)
{
return -1;
}
WebRtc_Word16
ACMGSMFR::EnableDTX()
{
return -1;
}
WebRtc_Word16
ACMGSMFR::DisableDTX()
{
return -1;
}
WebRtc_Word16
ACMGSMFR::InternalInitEncoder(
WebRtcACMCodecParams* /* codecParams */)
{
return -1;
}
WebRtc_Word16
ACMGSMFR::InternalInitDecoder(
WebRtcACMCodecParams* /* codecParams */)
{
return -1;
}
WebRtc_Word32
ACMGSMFR::CodecDef(
WebRtcNetEQ_CodecDef& /* codecDef */,
const CodecInst& /* codecInst */)
{
return -1;
}
ACMGenericCodec*
ACMGSMFR::CreateInstance(void)
{
return NULL;
}
WebRtc_Word16
ACMGSMFR::InternalCreateEncoder()
{
return -1;
}
void
ACMGSMFR::DestructEncoderSafe()
{
return;
}
WebRtc_Word16
ACMGSMFR::InternalCreateDecoder()
{
return -1;
}
void
ACMGSMFR::DestructDecoderSafe()
{
return;
}
void
ACMGSMFR::InternalDestructEncoderInst(
void* /* ptrInst */)
{
return;
}
#else //===================== Actual Implementation =======================
ACMGSMFR::ACMGSMFR(
WebRtc_Word16 codecID):
_encoderInstPtr(NULL),
_decoderInstPtr(NULL)
{
_codecID = codecID;
_hasInternalDTX = true;
return;
}
ACMGSMFR::~ACMGSMFR()
{
if(_encoderInstPtr != NULL)
{
WebRtcGSMFR_FreeEnc(_encoderInstPtr);
_encoderInstPtr = NULL;
}
if(_decoderInstPtr != NULL)
{
WebRtcGSMFR_FreeDec(_decoderInstPtr);
_decoderInstPtr = NULL;
}
return;
}
WebRtc_Word16
ACMGSMFR::InternalEncode(
WebRtc_UWord8* bitStream,
WebRtc_Word16* bitStreamLenByte)
{
*bitStreamLenByte = WebRtcGSMFR_Encode(_encoderInstPtr,
&_inAudio[_inAudioIxRead], _frameLenSmpl, (WebRtc_Word16*)bitStream);
// increment the read index this tell the caller that how far
// we have gone forward in reading the audio buffer
_inAudioIxRead += _frameLenSmpl;
return *bitStreamLenByte;
}
WebRtc_Word16
ACMGSMFR::DecodeSafe(
WebRtc_UWord8* /* bitStream */,
WebRtc_Word16 /* bitStreamLenByte */,
WebRtc_Word16* /* audio */,
WebRtc_Word16* /* audioSamples */,
WebRtc_Word8* /* speechType */)
{
return 0;
}
WebRtc_Word16
ACMGSMFR::EnableDTX()
{
if(_dtxEnabled)
{
return 0;
}
else if(_encoderExist)
{
if(WebRtcGSMFR_EncoderInit(_encoderInstPtr, 1) < 0)
{
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
"EnableDTX: cannot init encoder for GSMFR");
return -1;
}
_dtxEnabled = true;
return 0;
}
else
{
return -1;
}
}
WebRtc_Word16
ACMGSMFR::DisableDTX()
{
if(!_dtxEnabled)
{
return 0;
}
else if(_encoderExist)
{
if(WebRtcGSMFR_EncoderInit(_encoderInstPtr, 0) < 0)
{
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
"DisableDTX: cannot init encoder for GSMFR");
return -1;
}
_dtxEnabled = false;
return 0;
}
else
{
// encoder doesn't exists, therefore disabling is harmless
return 0;
}
}
WebRtc_Word16
ACMGSMFR::InternalInitEncoder(
WebRtcACMCodecParams* codecParams)
{
if (WebRtcGSMFR_EncoderInit(_encoderInstPtr, ((codecParams->enableDTX)? 1:0)) < 0)
{
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
"InternalInitEncoder: cannot init encoder for GSMFR");
}
return 0;
}
WebRtc_Word16
ACMGSMFR::InternalInitDecoder(
WebRtcACMCodecParams* /* codecParams */)
{
if (WebRtcGSMFR_DecoderInit(_decoderInstPtr) < 0)
{
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
"InternalInitDecoder: cannot init decoder for GSMFR");
return -1;
}
return 0;
}
WebRtc_Word32
ACMGSMFR::CodecDef(
WebRtcNetEQ_CodecDef& codecDef,
const CodecInst& codecInst)
{
if (!_decoderInitialized)
{
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
"CodecDef: decoder is not initialized for GSMFR");
return -1;
}
// Fill up the structure by calling
// "SET_CODEC_PAR" & "SET_GSMFR_FUNCTION."
// Then call NetEQ to add the codec to it's
// database.
SET_CODEC_PAR((codecDef), kDecoderGSMFR, codecInst.pltype,
_decoderInstPtr, 8000);
SET_GSMFR_FUNCTIONS((codecDef));
return 0;
}
ACMGenericCodec*
ACMGSMFR::CreateInstance(void)
{
return NULL;
}
WebRtc_Word16
ACMGSMFR::InternalCreateEncoder()
{
if (WebRtcGSMFR_CreateEnc(&_encoderInstPtr) < 0)
{
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
"InternalCreateEncoder: cannot create instance for GSMFR encoder");
return -1;
}
return 0;
}
void
ACMGSMFR::DestructEncoderSafe()
{
if(_encoderInstPtr != NULL)
{
WebRtcGSMFR_FreeEnc(_encoderInstPtr);
_encoderInstPtr = NULL;
}
_encoderExist = false;
_encoderInitialized = false;
}
WebRtc_Word16
ACMGSMFR::InternalCreateDecoder()
{
if (WebRtcGSMFR_CreateDec(&_decoderInstPtr) < 0)
{
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
"InternalCreateDecoder: cannot create instance for GSMFR decoder");
return -1;
}
return 0;
}
void
ACMGSMFR::DestructDecoderSafe()
{
if(_decoderInstPtr != NULL)
{
WebRtcGSMFR_FreeDec(_decoderInstPtr);
_decoderInstPtr = NULL;
}
_decoderExist = false;
_decoderInitialized = false;
}
void
ACMGSMFR::InternalDestructEncoderInst(
void* ptrInst)
{
if(ptrInst != NULL)
{
WebRtcGSMFR_FreeEnc((GSMFR_encinst_t_*)ptrInst);
}
return;
}
#endif
} // namespace webrtc

View File

@ -0,0 +1,73 @@
/*
* 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_MAIN_SOURCE_ACM_GSMFR_H_
#define WEBRTC_MODULES_AUDIO_CODING_MAIN_SOURCE_ACM_GSMFR_H_
#include "acm_generic_codec.h"
// forward declaration
struct GSMFR_encinst_t_;
struct GSMFR_decinst_t_;
namespace webrtc {
class ACMGSMFR : public ACMGenericCodec
{
public:
ACMGSMFR(WebRtc_Word16 codecID);
~ACMGSMFR();
// for FEC
ACMGenericCodec* CreateInstance(void);
WebRtc_Word16 InternalEncode(
WebRtc_UWord8* bitstream,
WebRtc_Word16* bitStreamLenByte);
WebRtc_Word16 InternalInitEncoder(
WebRtcACMCodecParams *codecParams);
WebRtc_Word16 InternalInitDecoder(
WebRtcACMCodecParams *codecParams);
protected:
WebRtc_Word16 DecodeSafe(
WebRtc_UWord8* bitStream,
WebRtc_Word16 bitStreamLenByte,
WebRtc_Word16* audio,
WebRtc_Word16* audioSamples,
WebRtc_Word8* speechType);
WebRtc_Word32 CodecDef(
WebRtcNetEQ_CodecDef& codecDef,
const CodecInst& codecInst);
void DestructEncoderSafe();
void DestructDecoderSafe();
WebRtc_Word16 InternalCreateEncoder();
WebRtc_Word16 InternalCreateDecoder();
void InternalDestructEncoderInst(
void* ptrInst);
WebRtc_Word16 EnableDTX();
WebRtc_Word16 DisableDTX();
GSMFR_encinst_t_* _encoderInstPtr;
GSMFR_decinst_t_* _decoderInstPtr;
};
} // namespace webrtc
#endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_SOURCE_ACM_GSMFR_H_

View File

@ -0,0 +1,362 @@
/*
* 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 "acm_common_defs.h"
#include "acm_ilbc.h"
#include "acm_neteq.h"
#include "trace.h"
#include "webrtc_neteq.h"
#include "webrtc_neteq_help_macros.h"
#ifdef WEBRTC_CODEC_ILBC
#include "ilbc.h"
#endif
namespace webrtc
{
#ifndef WEBRTC_CODEC_ILBC
ACMILBC::ACMILBC(WebRtc_Word16 /* codecID */)
: _encoderInstPtr(NULL),
_decoderInstPtr(NULL) {
return;
}
ACMILBC::~ACMILBC()
{
return;
}
WebRtc_Word16
ACMILBC::InternalEncode(
WebRtc_UWord8* /* bitStream */,
WebRtc_Word16* /* bitStreamLenByte */)
{
return -1;
}
WebRtc_Word16
ACMILBC::DecodeSafe(
WebRtc_UWord8* /* bitStream */,
WebRtc_Word16 /* bitStreamLenByte */,
WebRtc_Word16* /* audio */,
WebRtc_Word16* /* audioSamples */,
WebRtc_Word8* /* speechType */)
{
return -1;
}
WebRtc_Word16
ACMILBC::InternalInitEncoder(
WebRtcACMCodecParams* /* codecParams */)
{
return -1;
}
WebRtc_Word16
ACMILBC::InternalInitDecoder(
WebRtcACMCodecParams* /* codecParams */)
{
return -1;
}
WebRtc_Word32
ACMILBC::CodecDef(
WebRtcNetEQ_CodecDef& /* codecDef */,
const CodecInst& /* codecInst */)
{
return -1;
}
ACMGenericCodec*
ACMILBC::CreateInstance(void)
{
return NULL;
}
WebRtc_Word16
ACMILBC::InternalCreateEncoder()
{
return -1;
}
void
ACMILBC::DestructEncoderSafe()
{
return;
}
WebRtc_Word16
ACMILBC::InternalCreateDecoder()
{
return -1;
}
void
ACMILBC::DestructDecoderSafe()
{
return;
}
void
ACMILBC::InternalDestructEncoderInst(
void* /* ptrInst */)
{
return;
}
WebRtc_Word16
ACMILBC::SetBitRateSafe(const WebRtc_Word32 /* rate */)
{
return -1;
}
#else //===================== Actual Implementation =======================
ACMILBC::ACMILBC(
WebRtc_Word16 codecID):
_encoderInstPtr(NULL),
_decoderInstPtr(NULL)
{
_codecID = codecID;
return;
}
ACMILBC::~ACMILBC()
{
if(_encoderInstPtr != NULL)
{
WebRtcIlbcfix_EncoderFree(_encoderInstPtr);
_encoderInstPtr = NULL;
}
if(_decoderInstPtr != NULL)
{
WebRtcIlbcfix_DecoderFree(_decoderInstPtr);
_decoderInstPtr = NULL;
}
return;
}
WebRtc_Word16
ACMILBC::InternalEncode(
WebRtc_UWord8* bitStream,
WebRtc_Word16* bitStreamLenByte)
{
*bitStreamLenByte = WebRtcIlbcfix_Encode(_encoderInstPtr,
&_inAudio[_inAudioIxRead], _frameLenSmpl, (WebRtc_Word16*)bitStream);
if (*bitStreamLenByte < 0)
{
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
"InternalEncode: error in encode for ILBC");
return -1;
}
// increment the read index this tell the caller that how far
// we have gone forward in reading the audio buffer
_inAudioIxRead += _frameLenSmpl;
return *bitStreamLenByte;
}
WebRtc_Word16
ACMILBC::DecodeSafe(
WebRtc_UWord8* /* bitStream */,
WebRtc_Word16 /* bitStreamLenByte */,
WebRtc_Word16* /* audio */,
WebRtc_Word16* /* audioSamples */,
WebRtc_Word8* /* speechType */)
{
return 0;
}
WebRtc_Word16
ACMILBC::InternalInitEncoder(
WebRtcACMCodecParams* codecParams)
{
// initialize with a correct processing block length
if((160 == (codecParams->codecInstant).pacsize) ||
(320 == (codecParams->codecInstant).pacsize))
{
// processing block of 20ms
return WebRtcIlbcfix_EncoderInit(_encoderInstPtr, 20);
}
else if((240 == (codecParams->codecInstant).pacsize) ||
(480 == (codecParams->codecInstant).pacsize))
{
// processing block of 30ms
return WebRtcIlbcfix_EncoderInit(_encoderInstPtr, 30);
}
else
{
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
"InternalInitEncoder: invalid processing block");
return -1;
}
}
WebRtc_Word16
ACMILBC::InternalInitDecoder(
WebRtcACMCodecParams* codecParams)
{
// initialize with a correct processing block length
if((160 == (codecParams->codecInstant).pacsize) ||
(320 == (codecParams->codecInstant).pacsize))
{
// processing block of 20ms
return WebRtcIlbcfix_DecoderInit(_decoderInstPtr, 20);
}
else if((240 == (codecParams->codecInstant).pacsize) ||
(480 == (codecParams->codecInstant).pacsize))
{
// processing block of 30ms
return WebRtcIlbcfix_DecoderInit(_decoderInstPtr, 30);
}
else
{
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
"InternalInitDecoder: invalid processing block");
return -1;
}
}
WebRtc_Word32
ACMILBC::CodecDef(
WebRtcNetEQ_CodecDef& codecDef,
const CodecInst& codecInst)
{
if (!_decoderInitialized)
{
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
"CodeDef: decoder not initialized for ILBC");
return -1;
}
// Fill up the structure by calling
// "SET_CODEC_PAR" & "SET_ILBC_FUNCTION."
// Then return the structure back to NetEQ to add the codec to it's
// database.
SET_CODEC_PAR((codecDef), kDecoderILBC, codecInst.pltype,
_decoderInstPtr, 8000);
SET_ILBC_FUNCTIONS((codecDef));
return 0;
}
ACMGenericCodec*
ACMILBC::CreateInstance(void)
{
return NULL;
}
WebRtc_Word16
ACMILBC::InternalCreateEncoder()
{
if (WebRtcIlbcfix_EncoderCreate(&_encoderInstPtr) < 0)
{
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
"InternalCreateEncoder: cannot create instance for ILBC encoder");
return -1;
}
return 0;
}
void
ACMILBC::DestructEncoderSafe()
{
_encoderInitialized = false;
_encoderExist = false;
if(_encoderInstPtr != NULL)
{
WebRtcIlbcfix_EncoderFree(_encoderInstPtr);
_encoderInstPtr = NULL;
}
}
WebRtc_Word16
ACMILBC::InternalCreateDecoder()
{
if (WebRtcIlbcfix_DecoderCreate(&_decoderInstPtr) < 0)
{
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
"InternalCreateDecoder: cannot create instance for ILBC decoder");
return -1;
}
return 0;
}
void
ACMILBC::DestructDecoderSafe()
{
_decoderInitialized = false;
_decoderExist = false;
if(_decoderInstPtr != NULL)
{
WebRtcIlbcfix_DecoderFree(_decoderInstPtr);
_decoderInstPtr = NULL;
}
}
void
ACMILBC::InternalDestructEncoderInst(
void* ptrInst)
{
if(ptrInst != NULL)
{
WebRtcIlbcfix_EncoderFree((iLBC_encinst_t_*)ptrInst);
}
return;
}
WebRtc_Word16
ACMILBC::SetBitRateSafe(const WebRtc_Word32 rate)
{
// Check that rate is valid. No need to store the value
if (rate == 13300)
{
WebRtcIlbcfix_EncoderInit(_encoderInstPtr, 30);
}
else if (rate == 15200)
{
WebRtcIlbcfix_EncoderInit(_encoderInstPtr, 20);
}
else
{
return -1;
}
_encoderParams.codecInstant.rate = rate;
return 0;
}
#endif
} // namespace webrtc

View File

@ -0,0 +1,74 @@
/*
* 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_MAIN_SOURCE_ACM_ILBC_H_
#define WEBRTC_MODULES_AUDIO_CODING_MAIN_SOURCE_ACM_ILBC_H_
#include "acm_generic_codec.h"
// forward declaration
struct iLBC_encinst_t_;
struct iLBC_decinst_t_;
namespace webrtc
{
class ACMILBC : public ACMGenericCodec
{
public:
ACMILBC(WebRtc_Word16 codecID);
~ACMILBC();
// for FEC
ACMGenericCodec* CreateInstance(void);
WebRtc_Word16 InternalEncode(
WebRtc_UWord8* bitstream,
WebRtc_Word16* bitStreamLenByte);
WebRtc_Word16 InternalInitEncoder(
WebRtcACMCodecParams *codecParams);
WebRtc_Word16 InternalInitDecoder(
WebRtcACMCodecParams *codecParams);
protected:
WebRtc_Word16 DecodeSafe(
WebRtc_UWord8* bitStream,
WebRtc_Word16 bitStreamLenByte,
WebRtc_Word16* audio,
WebRtc_Word16* audioSamples,
WebRtc_Word8* speechType);
WebRtc_Word32 CodecDef(
WebRtcNetEQ_CodecDef& codecDef,
const CodecInst& codecInst);
WebRtc_Word16 SetBitRateSafe(
const WebRtc_Word32 rate);
void DestructEncoderSafe();
void DestructDecoderSafe();
WebRtc_Word16 InternalCreateEncoder();
WebRtc_Word16 InternalCreateDecoder();
void InternalDestructEncoderInst(
void* ptrInst);
iLBC_encinst_t_* _encoderInstPtr;
iLBC_decinst_t_* _decoderInstPtr;
};
} // namespace webrtc
#endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_SOURCE_ACM_ILBC_H_

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,149 @@
/*
* 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_MAIN_SOURCE_ACM_ISAC_H_
#define WEBRTC_MODULES_AUDIO_CODING_MAIN_SOURCE_ACM_ISAC_H_
#include "acm_generic_codec.h"
namespace webrtc
{
struct ACMISACInst;
enum iSACCodingMode {ADAPTIVE, CHANNEL_INDEPENDENT};
class ACMISAC : public ACMGenericCodec
{
public:
ACMISAC(WebRtc_Word16 codecID);
~ACMISAC();
// for FEC
ACMGenericCodec* CreateInstance(void);
WebRtc_Word16 InternalEncode(
WebRtc_UWord8* bitstream,
WebRtc_Word16* bitStreamLenByte);
WebRtc_Word16 InternalInitEncoder(
WebRtcACMCodecParams *codecParams);
WebRtc_Word16 InternalInitDecoder(
WebRtcACMCodecParams *codecParams);
WebRtc_Word16 DeliverCachedIsacData(
WebRtc_UWord8* bitStream,
WebRtc_Word16* bitStreamLenByte,
WebRtc_UWord32* timestamp,
WebRtcACMEncodingType* encodingType,
const WebRtc_UWord16 isacRate,
const WebRtc_UWord8 isacBWestimate);
WebRtc_Word16 DeliverCachedData(
WebRtc_UWord8* /* bitStream */,
WebRtc_Word16* /* bitStreamLenByte */,
WebRtc_UWord32* /* timestamp */,
WebRtcACMEncodingType* /* encodingType */)
{
return -1;
}
WebRtc_Word16 UpdateDecoderSampFreq(
WebRtc_Word16 codecId);
WebRtc_Word16 UpdateEncoderSampFreq(
WebRtc_UWord16 sampFreqHz);
WebRtc_Word16 EncoderSampFreq(
WebRtc_UWord16& sampFreqHz);
WebRtc_Word32 ConfigISACBandwidthEstimator(
const WebRtc_UWord8 initFrameSizeMsec,
const WebRtc_UWord16 initRateBitPerSec,
const bool enforceFrameSize);
WebRtc_Word32 SetISACMaxPayloadSize(
const WebRtc_UWord16 maxPayloadLenBytes);
WebRtc_Word32 SetISACMaxRate(
const WebRtc_UWord32 maxRateBitPerSec);
WebRtc_Word16 REDPayloadISAC(
const WebRtc_Word32 isacRate,
const WebRtc_Word16 isacBwEstimate,
WebRtc_UWord8* payload,
WebRtc_Word16* payloadLenBytes);
protected:
WebRtc_Word16 DecodeSafe(
WebRtc_UWord8* bitStream,
WebRtc_Word16 bitStreamLenByte,
WebRtc_Word16* audio,
WebRtc_Word16* audioSamples,
WebRtc_Word8* speechType);
WebRtc_Word32 CodecDef(
WebRtcNetEQ_CodecDef& codecDef,
const CodecInst& codecInst);
void DestructEncoderSafe();
void DestructDecoderSafe();
WebRtc_Word16 SetBitRateSafe(
const WebRtc_Word32 bitRate);
WebRtc_Word32 GetEstimatedBandwidthSafe();
WebRtc_Word32 SetEstimatedBandwidthSafe(WebRtc_Word32 estimatedBandwidth);
WebRtc_Word32 GetRedPayloadSafe(
WebRtc_UWord8* redPayload,
WebRtc_Word16* payloadBytes);
WebRtc_Word16 InternalCreateEncoder();
WebRtc_Word16 InternalCreateDecoder();
void InternalDestructEncoderInst(
void* ptrInst);
WebRtc_Word16 Transcode(
WebRtc_UWord8* bitStream,
WebRtc_Word16* bitStreamLenByte,
WebRtc_Word16 qBWE,
WebRtc_Word32 rate,
bool isRED);
void CurrentRate(WebRtc_Word32& rateBitPerSec);
void UpdateFrameLen();
bool DecoderParamsSafe(
WebRtcACMCodecParams *decParams,
const WebRtc_UWord8 payloadType);
void SaveDecoderParamSafe(
const WebRtcACMCodecParams* codecParams);
ACMISACInst* _codecInstPtr;
bool _isEncInitialized;
iSACCodingMode _isacCodingMode;
bool _enforceFrameSize;
WebRtc_Word32 _isacCurrentBN;
WebRtc_UWord16 _samplesIn10MsAudio;
WebRtcACMCodecParams _decoderParams32kHz;
};
} //namespace
#endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_SOURCE_ACM_ISAC_H_

View File

@ -0,0 +1,74 @@
/*
* 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_MAIN_SOURCE_ACM_ISAC_MACROS_H_
#define WEBRTC_MODULES_AUDIO_CODING_MAIN_SOURCE_ACM_ISAC_MACROS_H_
#include "engine_configurations.h"
namespace webrtc
{
#ifdef WEBRTC_CODEC_ISAC
# define ACM_ISAC_CREATE WebRtcIsac_Create
# define ACM_ISAC_FREE WebRtcIsac_Free
# define ACM_ISAC_ENCODERINIT WebRtcIsac_EncoderInit
# define ACM_ISAC_ENCODE WebRtcIsac_Encode
# define ACM_ISAC_DECODERINIT WebRtcIsac_DecoderInit
# define ACM_ISAC_DECODE_BWE WebRtcIsac_UpdateBwEstimate
# define ACM_ISAC_DECODE_B WebRtcIsac_Decode
# define ACM_ISAC_DECODEPLC WebRtcIsac_DecodePlc
# define ACM_ISAC_CONTROL WebRtcIsac_Control
# define ACM_ISAC_CONTROL_BWE WebRtcIsac_ControlBwe
# define ACM_ISAC_GETFRAMELEN WebRtcIsac_ReadFrameLen
# define ACM_ISAC_GETERRORCODE WebRtcIsac_GetErrorCode
# define ACM_ISAC_GETSENDBITRATE WebRtcIsac_GetUplinkBw
# define ACM_ISAC_SETMAXPAYLOADSIZE WebRtcIsac_SetMaxPayloadSize
# define ACM_ISAC_SETMAXRATE WebRtcIsac_SetMaxRate
# define ACM_ISAC_GETNEWBITSTREAM WebRtcIsac_GetNewBitStream
# define ACM_ISAC_GETSENDBWE WebRtcIsac_GetDownLinkBwIndex
# define ACM_ISAC_SETBWE WebRtcIsac_UpdateUplinkBw
# define ACM_ISAC_GETBWE WebRtcIsac_ReadBwIndex
# define ACM_ISAC_GETNEWFRAMELEN WebRtcIsac_GetNewFrameLen
# define ACM_ISAC_STRUCT ISACStruct
# define ACM_ISAC_GETENCSAMPRATE WebRtcIsac_EncSampRate
# define ACM_ISAC_GETDECSAMPRATE WebRtcIsac_DecSampRate
#endif
#ifdef WEBRTC_CODEC_ISACFX
# define ACM_ISAC_CREATE WebRtcIsacfix_Create
# define ACM_ISAC_FREE WebRtcIsacfix_Free
# define ACM_ISAC_ENCODERINIT WebRtcIsacfix_EncoderInit
# define ACM_ISAC_ENCODE WebRtcIsacfix_Encode
# define ACM_ISAC_DECODERINIT WebRtcIsacfix_DecoderInit
# define ACM_ISAC_DECODE_BWE WebRtcIsacfix_UpdateBwEstimate
# define ACM_ISAC_DECODE_B WebRtcIsacfix_Decode
# define ACM_ISAC_DECODEPLC WebRtcIsacfix_DecodePlc
# define ACM_ISAC_CONTROL ACMISACFixControl // local Impl
# define ACM_ISAC_CONTROL_BWE ACMISACFixControlBWE // local Impl
# define ACM_ISAC_GETFRAMELEN WebRtcIsacfix_ReadFrameLen
# define ACM_ISAC_GETERRORCODE WebRtcIsacfix_GetErrorCode
# define ACM_ISAC_GETSENDBITRATE ACMISACFixGetSendBitrate // local Impl
# define ACM_ISAC_SETMAXPAYLOADSIZE WebRtcIsacfix_SetMaxPayloadSize
# define ACM_ISAC_SETMAXRATE WebRtcIsacfix_SetMaxRate
# define ACM_ISAC_GETNEWBITSTREAM ACMISACFixGetNewBitstream // local Impl
# define ACM_ISAC_GETSENDBWE ACMISACFixGetSendBWE // local Impl
# define ACM_ISAC_SETBWE WebRtcIsacfix_UpdateUplinkBw
# define ACM_ISAC_GETBWE WebRtcIsacfix_ReadBwIndex
# define ACM_ISAC_GETNEWFRAMELEN WebRtcIsacfix_GetNewFrameLen
# define ACM_ISAC_STRUCT ISACFIX_MainStruct
# define ACM_ISAC_GETENCSAMPRATE ACMISACFixGetEncSampRate // local Impl
# define ACM_ISAC_GETDECSAMPRATE ACMISACFixGetDecSampRate // local Impl
#endif
} //namespace
#endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_SOURCE_ACM_ISAC_MACROS_H_

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,369 @@
/*
* 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_MAIN_SOURCE_ACM_NETEQ_H_
#define WEBRTC_MODULES_AUDIO_CODING_MAIN_SOURCE_ACM_NETEQ_H_
#include "audio_coding_module.h"
#include "audio_coding_module_typedefs.h"
#include "engine_configurations.h"
#include "module_common_types.h"
#include "typedefs.h"
#include "webrtc_neteq.h"
#include "webrtc_vad.h"
namespace webrtc {
class CriticalSectionWrapper;
class RWLockWrapper;
struct CodecInst;
enum AudioPlayoutMode;
enum ACMSpeechType;
#define MAX_NUM_SLAVE_NETEQ 1
class ACMNetEQ
{
public:
// Constructor of the class
ACMNetEQ();
// Destructor of the class.
~ACMNetEQ();
//
// Init()
// Allocates memory for NetEQ and VAD and initializes them.
//
// Return value : 0 if ok.
// -1 if NetEQ or VAD returned an error or
// if out of memory.
//
WebRtc_Word32 Init();
//
// RecIn()
// Gives the payload to NetEQ.
//
// Input:
// - incomingPayload : Incoming audio payload.
// - payloadLength : Length of incoming audio payload.
// - rtpInfo : RTP header for the incoming payload containing
// information about payload type, sequence number,
// timestamp, ssrc and marker bit.
//
// Return value : 0 if ok.
// <0 if NetEQ returned an error.
//
WebRtc_Word32 RecIn(
const WebRtc_UWord8* incomingPayload,
const WebRtc_Word32 payloadLength,
const WebRtcRTPHeader& rtpInfo);
//
// RecOut()
// Asks NetEQ for 10 ms of decoded audio.
//
// Input:
// -audioFrame : an audio frame were output data and
// associated parameters are written to.
//
// Return value : 0 if ok.
// -1 if NetEQ returned an error.
//
WebRtc_Word32 RecOut(
AudioFrame& audioFrame);
//
// AddCodec()
// Adds a new codec to the NetEQ codec database.
//
// Input:
// - codecDef : The codec to be added.
// - toMaster : true if the codec has to be added to Master
// NetEq, otherwise will be added to the Slave
// NetEQ.
//
// Return value : 0 if ok.
// <0 if NetEQ returned an error.
//
WebRtc_Word32 AddCodec(
WebRtcNetEQ_CodecDef *codecDef,
bool toMaster = true);
//
// AllocatePacketBuffer()
// Allocates the NetEQ packet buffer.
//
// Input:
// - usedCodecs : An array of the codecs to be used by NetEQ.
// - noOfCodecs : Number of codecs in usedCodecs.
//
// Return value : 0 if ok.
// <0 if NetEQ returned an error.
//
WebRtc_Word32 AllocatePacketBuffer(
const WebRtcNetEQDecoder* usedCodecs,
WebRtc_Word16 noOfCodecs);
//
// SetExtraDelay()
// Sets an delayInMS milliseconds extra delay in NetEQ.
//
// Input:
// - delayInMS : Extra delay in milliseconds.
//
// Return value : 0 if ok.
// <0 if NetEQ returned an error.
//
WebRtc_Word32 SetExtraDelay(
const WebRtc_Word32 delayInMS);
//
// SetAVTPlayout()
// Enable/disable playout of AVT payloads.
//
// Input:
// - enable : Enable if true, disable if false.
//
// Return value : 0 if ok.
// <0 if NetEQ returned an error.
//
WebRtc_Word32 SetAVTPlayout(
const bool enable);
//
// AVTPlayout()
// Get the current AVT playout state.
//
// Return value : True if AVT playout is enabled.
// False if AVT playout is disabled.
//
bool AVTPlayout() const;
//
// CurrentSampFreqHz()
// Get the current sampling frequency in Hz.
//
// Return value : Sampling frequency in Hz.
//
WebRtc_Word32 CurrentSampFreqHz() const;
//
// SetPlayoutMode()
// Sets the playout mode to voice or fax.
//
// Input:
// - mode : The playout mode to be used, voice,
// fax, or streaming.
//
// Return value : 0 if ok.
// <0 if NetEQ returned an error.
//
WebRtc_Word32 SetPlayoutMode(
const AudioPlayoutMode mode);
//
// PlayoutMode()
// Get the current playout mode.
//
// Return value : The current playout mode.
//
AudioPlayoutMode PlayoutMode() const;
//
// NetworkStatistics()
// Get the current network statistics from NetEQ.
//
// Output:
// - statistics : The current network statistics.
//
// Return value : 0 if ok.
// <0 if NetEQ returned an error.
//
WebRtc_Word32 NetworkStatistics(
ACMNetworkStatistics* statistics) const;
//
// VADMode()
// Get the current VAD Mode.
//
// Return value : The current VAD mode.
//
ACMVADMode VADMode() const;
//
// SetVADMode()
// Set the VAD mode.
//
// Input:
// - mode : The new VAD mode.
//
// Return value : 0 if ok.
// -1 if an error occurred.
//
WebRtc_Word16 SetVADMode(
const ACMVADMode mode);
//
// DecodeLock()
// Get the decode lock used to protect decoder instances while decoding.
//
// Return value : Pointer to the decode lock.
//
RWLockWrapper* DecodeLock() const
{
return _decodeLock;
}
//
// FlushBuffers()
// Flushes the NetEQ packet and speech buffers.
//
// Return value : 0 if ok.
// -1 if NetEQ returned an error.
//
WebRtc_Word32 FlushBuffers();
//
// RemoveCodec()
// Removes a codec from the NetEQ codec database.
//
// Input:
// - codecIdx : Codec to be removed.
//
// Return value : 0 if ok.
// -1 if an error occurred.
//
WebRtc_Word16 RemoveCodec(
WebRtcNetEQDecoder codecIdx,
bool isStereo = false);
//
// SetBackgroundNoiseMode()
// Set the mode of the background noise.
//
// Input:
// - mode : an enumerator specifying the mode of the
// background noise.
//
// Return value : 0 if succeeded,
// -1 if failed to set the mode.
//
WebRtc_Word16 SetBackgroundNoiseMode(
const ACMBackgroundNoiseMode mode);
//
// BackgroundNoiseMode()
// return the mode of the background noise.
//
// Return value : The mode of background noise.
//
WebRtc_Word16 BackgroundNoiseMode(
ACMBackgroundNoiseMode& mode);
void SetUniqueId(
WebRtc_Word32 id);
WebRtc_Word32 PlayoutTimestamp(
WebRtc_UWord32& timestamp);
void SetReceivedStereo(
bool receivedStereo);
WebRtc_UWord8 NumSlaves();
enum JB {masterJB = 0, slaveJB = 1};
// Delete all slaves.
void RemoveSlaves();
WebRtc_Word16 AddSlave(
const WebRtcNetEQDecoder* usedCodecs,
WebRtc_Word16 noOfCodecs);
private:
//
// RTPPack()
// Creates a Word16 RTP packet out of the payload data in Word16 and
// a WebRtcRTPHeader.
//
// Input:
// - payload : Payload to be packetized.
// - payloadLengthW8 : Length of the payload in bytes.
// - rtpInfo : RTP header struct.
//
// Output:
// - rtpPacket : The RTP packet.
//
static void RTPPack(
WebRtc_Word16* rtpPacket,
const WebRtc_Word8* payload,
const WebRtc_Word32 payloadLengthW8,
const WebRtcRTPHeader& rtpInfo);
void LogError(
const char* neteqFuncName,
const WebRtc_Word16 idx) const;
WebRtc_Word16 InitByIdxSafe(
const WebRtc_Word16 idx);
// EnableVAD()
// Enable VAD.
//
// Return value : 0 if ok.
// -1 if an error occurred.
//
WebRtc_Word16 EnableVAD();
WebRtc_Word16 EnableVADByIdxSafe(
const WebRtc_Word16 idx);
WebRtc_Word16 AllocatePacketBufferByIdxSafe(
const WebRtcNetEQDecoder* usedCodecs,
WebRtc_Word16 noOfCodecs,
const WebRtc_Word16 idx);
// Delete the NetEQ corresponding to |index|.
void RemoveNetEQSafe(int index);
void RemoveSlavesSafe();
void* _inst[MAX_NUM_SLAVE_NETEQ + 1];
void* _instMem[MAX_NUM_SLAVE_NETEQ + 1];
WebRtc_Word16* _netEqPacketBuffer[MAX_NUM_SLAVE_NETEQ + 1];
WebRtc_Word32 _id;
float _currentSampFreqKHz;
bool _avtPlayout;
AudioPlayoutMode _playoutMode;
CriticalSectionWrapper* _netEqCritSect;
WebRtcVadInst* _ptrVADInst[MAX_NUM_SLAVE_NETEQ + 1];
bool _vadStatus;
ACMVADMode _vadMode;
RWLockWrapper* _decodeLock;
bool _isInitialized[MAX_NUM_SLAVE_NETEQ + 1];
WebRtc_UWord8 _numSlaves;
bool _receivedStereo;
void* _masterSlaveInfo;
AudioFrame::VADActivity _previousAudioActivity;
WebRtc_Word32 _extraDelay;
CriticalSectionWrapper* _callbackCritSect;
};
} //namespace webrtc
#endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_SOURCE_ACM_NETEQ_H_

View File

@ -0,0 +1,147 @@
/*
* 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.
*/
// This file contains unit tests for ACM's NetEQ wrapper (class ACMNetEQ).
#include <stdlib.h>
#include "gtest/gtest.h"
#include "modules/audio_coding/codecs/pcm16b/include/pcm16b.h"
#include "modules/audio_coding/main/interface/audio_coding_module_typedefs.h"
#include "modules/audio_coding/main/source/acm_codec_database.h"
#include "modules/audio_coding/main/source/acm_neteq.h"
#include "modules/audio_coding/neteq/interface/webrtc_neteq_help_macros.h"
#include "modules/interface/module_common_types.h"
#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
class AcmNetEqTest : public ::testing::Test {
protected:
static const size_t kMaxPayloadLen = 5760; // 60 ms, 48 kHz, 16 bit samples.
static const int kPcm16WbPayloadType = 94;
AcmNetEqTest() {}
virtual void SetUp();
virtual void TearDown() {}
void InsertZeroPacket(uint16_t sequence_number,
uint32_t timestamp,
uint8_t payload_type,
uint32_t ssrc,
bool marker_bit,
size_t len_payload_bytes);
void PullData(int expected_num_samples);
ACMNetEQ neteq_;
};
void AcmNetEqTest::SetUp() {
ASSERT_EQ(0, neteq_.Init());
ASSERT_EQ(0, neteq_.AllocatePacketBuffer(ACMCodecDB::NetEQDecoders(),
ACMCodecDB::kNumCodecs));
WebRtcNetEQ_CodecDef codec_def;
SET_CODEC_PAR(codec_def, kDecoderPCM16Bwb, kPcm16WbPayloadType, NULL, 16000);
SET_PCM16B_WB_FUNCTIONS(codec_def);
ASSERT_EQ(0, neteq_.AddCodec(&codec_def, true));
}
void AcmNetEqTest::InsertZeroPacket(uint16_t sequence_number,
uint32_t timestamp,
uint8_t payload_type,
uint32_t ssrc,
bool marker_bit,
size_t len_payload_bytes) {
ASSERT_TRUE(len_payload_bytes <= kMaxPayloadLen);
uint16_t payload[kMaxPayloadLen] = {0};
WebRtcRTPHeader rtp_header;
rtp_header.header.sequenceNumber = sequence_number;
rtp_header.header.timestamp = timestamp;
rtp_header.header.ssrc = ssrc;
rtp_header.header.payloadType = payload_type;
rtp_header.header.markerBit = marker_bit;
rtp_header.type.Audio.channel = 1;
ASSERT_EQ(0, neteq_.RecIn(reinterpret_cast<WebRtc_UWord8*>(payload),
len_payload_bytes, rtp_header));
}
void AcmNetEqTest::PullData(int expected_num_samples) {
AudioFrame out_frame;
ASSERT_EQ(0, neteq_.RecOut(out_frame));
ASSERT_EQ(expected_num_samples, out_frame.samples_per_channel_);
}
TEST_F(AcmNetEqTest, NetworkStatistics) {
// Use fax mode to avoid time-scaling. This is to simplify the testing of
// packet waiting times in the packet buffer.
neteq_.SetPlayoutMode(fax);
// Insert 31 dummy packets at once. Each packet contains 10 ms 16 kHz audio.
int num_frames = 30;
const int kSamples = 10 * 16;
const int kPayloadBytes = kSamples * 2;
int i, j;
for (i = 0; i < num_frames; ++i) {
InsertZeroPacket(i, i * kSamples, kPcm16WbPayloadType, 0x1234, false,
kPayloadBytes);
}
// Pull out data once.
PullData(kSamples);
// Insert one more packet (to produce different mean and median).
i = num_frames;
InsertZeroPacket(i, i * kSamples, kPcm16WbPayloadType, 0x1234, false,
kPayloadBytes);
// Pull out all data.
for (j = 1; j < num_frames + 1; ++j) {
PullData(kSamples);
}
ACMNetworkStatistics stats;
ASSERT_EQ(0, neteq_.NetworkStatistics(&stats));
EXPECT_EQ(0, stats.currentBufferSize);
EXPECT_EQ(0, stats.preferredBufferSize);
EXPECT_FALSE(stats.jitterPeaksFound);
EXPECT_EQ(0, stats.currentPacketLossRate);
EXPECT_EQ(0, stats.currentDiscardRate);
EXPECT_EQ(0, stats.currentExpandRate);
EXPECT_EQ(0, stats.currentPreemptiveRate);
EXPECT_EQ(0, stats.currentAccelerateRate);
EXPECT_EQ(-916, stats.clockDriftPPM); // Initial value is slightly off.
EXPECT_EQ(300, stats.maxWaitingTimeMs);
EXPECT_EQ(10, stats.minWaitingTimeMs);
EXPECT_EQ(159, stats.meanWaitingTimeMs);
EXPECT_EQ(160, stats.medianWaitingTimeMs);
}
TEST_F(AcmNetEqTest, TestZeroLengthWaitingTimesVector) {
// Insert one packet.
const int kSamples = 10 * 16;
const int kPayloadBytes = kSamples * 2;
int i = 0;
InsertZeroPacket(i, i * kSamples, kPcm16WbPayloadType, 0x1234, false,
kPayloadBytes);
// Do not pull out any data.
ACMNetworkStatistics stats;
ASSERT_EQ(0, neteq_.NetworkStatistics(&stats));
EXPECT_EQ(0, stats.currentBufferSize);
EXPECT_EQ(0, stats.preferredBufferSize);
EXPECT_FALSE(stats.jitterPeaksFound);
EXPECT_EQ(0, stats.currentPacketLossRate);
EXPECT_EQ(0, stats.currentDiscardRate);
EXPECT_EQ(0, stats.currentExpandRate);
EXPECT_EQ(0, stats.currentPreemptiveRate);
EXPECT_EQ(0, stats.currentAccelerateRate);
EXPECT_EQ(-916, stats.clockDriftPPM); // Initial value is slightly off.
EXPECT_EQ(-1, stats.minWaitingTimeMs);
EXPECT_EQ(-1, stats.maxWaitingTimeMs);
EXPECT_EQ(-1, stats.meanWaitingTimeMs);
EXPECT_EQ(-1, stats.medianWaitingTimeMs);
}
} // namespace

View File

@ -0,0 +1,263 @@
/*
* 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 "acm_opus.h"
#include "acm_codec_database.h"
#include "acm_common_defs.h"
#include "acm_neteq.h"
#include "trace.h"
#include "webrtc_neteq.h"
#include "webrtc_neteq_help_macros.h"
#ifdef WEBRTC_CODEC_OPUS
#include "modules/audio_coding/codecs/opus/interface/opus_interface.h"
#endif
namespace webrtc {
#ifndef WEBRTC_CODEC_OPUS
ACMOpus::ACMOpus(int16_t /* codecID */)
: _encoderInstPtr(NULL),
_decoderInstPtr(NULL),
_sampleFreq(0),
_bitrate(0) {
return;
}
ACMOpus::~ACMOpus() {
return;
}
int16_t ACMOpus::InternalEncode(uint8_t* /* bitStream */,
int16_t* /* bitStreamLenByte */) {
return -1;
}
int16_t ACMOpus::DecodeSafe(uint8_t* /* bitStream */,
int16_t /* bitStreamLenByte */,
int16_t* /* audio */,
int16_t* /* audioSamples */,
int8_t* /* speechType */) {
return -1;
}
int16_t ACMOpus::InternalInitEncoder(WebRtcACMCodecParams* /* codecParams */) {
return -1;
}
int16_t ACMOpus::InternalInitDecoder(WebRtcACMCodecParams* /* codecParams */) {
return -1;
}
int32_t ACMOpus::CodecDef(WebRtcNetEQ_CodecDef& /* codecDef */,
const CodecInst& /* codecInst */) {
return -1;
}
ACMGenericCodec* ACMOpus::CreateInstance(void) {
return NULL;
}
int16_t ACMOpus::InternalCreateEncoder() {
return -1;
}
void ACMOpus::DestructEncoderSafe() {
return;
}
int16_t ACMOpus::InternalCreateDecoder() {
return -1;
}
void ACMOpus::DestructDecoderSafe() {
return;
}
void ACMOpus::InternalDestructEncoderInst(void* /* ptrInst */) {
return;
}
int16_t ACMOpus::SetBitRateSafe(const int32_t /*rate*/) {
return -1;
}
#else //===================== Actual Implementation =======================
ACMOpus::ACMOpus(int16_t codecID)
: _encoderInstPtr(NULL),
_decoderInstPtr(NULL),
_sampleFreq(32000), // Default sampling frequency.
_bitrate(20000) { // Default bit-rate.
_codecID = codecID;
// Opus has internal DTX, but we dont use it for now.
_hasInternalDTX = false;
if (_codecID != ACMCodecDB::kOpus) {
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
"Wrong codec id for Opus.");
_sampleFreq = -1;
_bitrate = -1;
}
return;
}
ACMOpus::~ACMOpus() {
if (_encoderInstPtr != NULL) {
WebRtcOpus_EncoderFree(_encoderInstPtr);
_encoderInstPtr = NULL;
}
if (_decoderInstPtr != NULL) {
WebRtcOpus_DecoderFree(_decoderInstPtr);
_decoderInstPtr = NULL;
}
return;
}
int16_t ACMOpus::InternalEncode(uint8_t* bitStream, int16_t* bitStreamLenByte) {
// Call Encoder.
*bitStreamLenByte = WebRtcOpus_Encode(_encoderInstPtr,
&_inAudio[_inAudioIxRead],
_frameLenSmpl,
MAX_PAYLOAD_SIZE_BYTE,
bitStream);
// Check for error reported from encoder.
if (*bitStreamLenByte < 0) {
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
"InternalEncode: Encode error for Opus");
*bitStreamLenByte = 0;
return -1;
}
// Increment the read index. This tells the caller how far
// we have gone forward in reading the audio buffer.
_inAudioIxRead += _frameLenSmpl;
return *bitStreamLenByte;
}
int16_t ACMOpus::DecodeSafe(uint8_t* bitStream, int16_t bitStreamLenByte,
int16_t* audio, int16_t* audioSamples,
int8_t* speechType) {
return 0;
}
int16_t ACMOpus::InternalInitEncoder(WebRtcACMCodecParams* codecParams) {
int16_t ret;
if (_encoderInstPtr != NULL) {
WebRtcOpus_EncoderFree(_encoderInstPtr);
_encoderInstPtr = NULL;
}
ret = WebRtcOpus_EncoderCreate(&_encoderInstPtr,
codecParams->codecInstant.channels);
if (ret < 0) {
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
"Encoder creation failed for Opus");
return ret;
}
ret = WebRtcOpus_SetBitRate(_encoderInstPtr, codecParams->codecInstant.rate);
if (ret < 0) {
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
"Setting initial bitrate failed for Opus");
return ret;
}
return 0;
}
int16_t ACMOpus::InternalInitDecoder(WebRtcACMCodecParams* codecParams) {
if (_decoderInstPtr != NULL) {
WebRtcOpus_DecoderFree(_decoderInstPtr);
_decoderInstPtr = NULL;
}
if (WebRtcOpus_DecoderCreate(&_decoderInstPtr,
codecParams->codecInstant.channels) < 0) {
return -1;
}
return WebRtcOpus_DecoderInit(_decoderInstPtr);
}
int32_t ACMOpus::CodecDef(WebRtcNetEQ_CodecDef& codecDef,
const CodecInst& codecInst) {
if (!_decoderInitialized) {
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
"CodeDef: Decoder uninitialized for Opus");
return -1;
}
// Fill up the structure by calling "SET_CODEC_PAR" & "SET_OPUS_FUNCTION."
// Then call NetEQ to add the codec to its database.
// TODO(tlegrand): Decoder is registered in NetEQ as a 32 kHz decoder, which
// is true until we have a full 48 kHz system, and remove the downsampling
// in the Opus decoder wrapper.
SET_CODEC_PAR((codecDef), kDecoderOpus, codecInst.pltype, _decoderInstPtr,
32000);
SET_OPUS_FUNCTIONS((codecDef));
return 0;
}
ACMGenericCodec* ACMOpus::CreateInstance(void) {
return NULL;
}
int16_t ACMOpus::InternalCreateEncoder() {
// Real encoder will be created in InternalInitEncoder.
return 0;
}
void ACMOpus::DestructEncoderSafe() {
if (_encoderInstPtr) {
WebRtcOpus_EncoderFree(_encoderInstPtr);
_encoderInstPtr = NULL;
}
}
int16_t ACMOpus::InternalCreateDecoder() {
// Real decoder will be created in InternalInitDecoder
return 0;
}
void ACMOpus::DestructDecoderSafe() {
_decoderInitialized = false;
if (_decoderInstPtr) {
WebRtcOpus_DecoderFree(_decoderInstPtr);
_decoderInstPtr = NULL;
}
}
void ACMOpus::InternalDestructEncoderInst(void* ptrInst) {
if (ptrInst != NULL) {
WebRtcOpus_EncoderFree((OpusEncInst*) ptrInst);
}
return;
}
int16_t ACMOpus::SetBitRateSafe(const int32_t rate) {
if (rate < 6000 || rate > 510000) {
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
"SetBitRateSafe: Invalid rate Opus");
return -1;
}
_bitrate = rate;
// Ask the encoder for the new rate.
if (WebRtcOpus_SetBitRate(_encoderInstPtr, _bitrate) >= 0) {
_encoderParams.codecInstant.rate = _bitrate;
return 0;
}
return -1;
}
#endif // WEBRTC_CODEC_OPUS
} // namespace webrtc

View File

@ -0,0 +1,61 @@
/*
* 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_MAIN_SOURCE_ACM_OPUS_H_
#define WEBRTC_MODULES_AUDIO_CODING_MAIN_SOURCE_ACM_OPUS_H_
#include "acm_generic_codec.h"
#include "resampler.h"
struct WebRtcOpusEncInst;
struct WebRtcOpusDecInst;
namespace webrtc {
class ACMOpus : public ACMGenericCodec {
public:
ACMOpus(int16_t codecID);
~ACMOpus();
ACMGenericCodec* CreateInstance(void);
int16_t InternalEncode(uint8_t* bitstream, int16_t* bitStreamLenByte);
int16_t InternalInitEncoder(WebRtcACMCodecParams *codecParams);
int16_t InternalInitDecoder(WebRtcACMCodecParams *codecParams);
protected:
int16_t DecodeSafe(uint8_t* bitStream, int16_t bitStreamLenByte,
int16_t* audio, int16_t* audioSamples, int8_t* speechType);
int32_t CodecDef(WebRtcNetEQ_CodecDef& codecDef, const CodecInst& codecInst);
void DestructEncoderSafe();
void DestructDecoderSafe();
int16_t InternalCreateEncoder();
int16_t InternalCreateDecoder();
void InternalDestructEncoderInst(void* ptrInst);
int16_t SetBitRateSafe(const int32_t rate);
WebRtcOpusEncInst* _encoderInstPtr;
WebRtcOpusDecInst* _decoderInstPtr;
uint16_t _sampleFreq;
uint16_t _bitrate;
};
} // namespace webrtc
#endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_SOURCE_ACM_OPUS_H_

View File

@ -0,0 +1,247 @@
/*
* 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 "acm_pcm16b.h"
#include "acm_codec_database.h"
#include "acm_common_defs.h"
#include "acm_neteq.h"
#include "trace.h"
#include "webrtc_neteq.h"
#include "webrtc_neteq_help_macros.h"
#ifdef WEBRTC_CODEC_PCM16
#include "pcm16b.h"
#endif
namespace webrtc {
#ifndef WEBRTC_CODEC_PCM16
ACMPCM16B::ACMPCM16B(WebRtc_Word16 /* codecID */) {
return;
}
ACMPCM16B::~ACMPCM16B() {
return;
}
WebRtc_Word16 ACMPCM16B::InternalEncode(WebRtc_UWord8* /* bitStream */,
WebRtc_Word16* /* bitStreamLenByte */) {
return -1;
}
WebRtc_Word16 ACMPCM16B::DecodeSafe(WebRtc_UWord8* /* bitStream */,
WebRtc_Word16 /* bitStreamLenByte */,
WebRtc_Word16* /* audio */,
WebRtc_Word16* /* audioSamples */,
WebRtc_Word8* /* speechType */) {
return -1;
}
WebRtc_Word16 ACMPCM16B::InternalInitEncoder(
WebRtcACMCodecParams* /* codecParams */) {
return -1;
}
WebRtc_Word16 ACMPCM16B::InternalInitDecoder(
WebRtcACMCodecParams* /* codecParams */) {
return -1;
}
WebRtc_Word32 ACMPCM16B::CodecDef(WebRtcNetEQ_CodecDef& /* codecDef */,
const CodecInst& /* codecInst */) {
return -1;
}
ACMGenericCodec* ACMPCM16B::CreateInstance(void) {
return NULL;
}
WebRtc_Word16 ACMPCM16B::InternalCreateEncoder() {
return -1;
}
WebRtc_Word16 ACMPCM16B::InternalCreateDecoder() {
return -1;
}
void ACMPCM16B::InternalDestructEncoderInst(void* /* ptrInst */) {
return;
}
void ACMPCM16B::DestructEncoderSafe() {
return;
}
void ACMPCM16B::DestructDecoderSafe() {
return;
}
void ACMPCM16B::SplitStereoPacket(uint8_t* /*payload*/,
int32_t* /*payload_length*/) {
}
#else //===================== Actual Implementation =======================
ACMPCM16B::ACMPCM16B(WebRtc_Word16 codecID) {
_codecID = codecID;
_samplingFreqHz = ACMCodecDB::CodecFreq(_codecID);
}
ACMPCM16B::~ACMPCM16B() {
return;
}
WebRtc_Word16 ACMPCM16B::InternalEncode(WebRtc_UWord8* bitStream,
WebRtc_Word16* bitStreamLenByte) {
*bitStreamLenByte = WebRtcPcm16b_Encode(&_inAudio[_inAudioIxRead],
_frameLenSmpl * _noChannels,
bitStream);
// Increment the read index to tell the caller that how far
// we have gone forward in reading the audio buffer.
_inAudioIxRead += _frameLenSmpl * _noChannels;
return *bitStreamLenByte;
}
WebRtc_Word16 ACMPCM16B::DecodeSafe(WebRtc_UWord8* /* bitStream */,
WebRtc_Word16 /* bitStreamLenByte */,
WebRtc_Word16* /* audio */,
WebRtc_Word16* /* audioSamples */,
WebRtc_Word8* /* speechType */) {
return 0;
}
WebRtc_Word16 ACMPCM16B::InternalInitEncoder(
WebRtcACMCodecParams* /* codecParams */) {
// This codec does not need initialization, PCM has no instance.
return 0;
}
WebRtc_Word16 ACMPCM16B::InternalInitDecoder(
WebRtcACMCodecParams* /* codecParams */) {
// This codec does not need initialization, PCM has no instance.
return 0;
}
WebRtc_Word32 ACMPCM16B::CodecDef(WebRtcNetEQ_CodecDef& codecDef,
const CodecInst& codecInst) {
// Fill up the structure by calling "SET_CODEC_PAR" & "SET_PCMU_FUNCTION".
// Then call NetEQ to add the codec to it's database.
if (codecInst.channels == 1) {
switch(_samplingFreqHz) {
case 8000: {
SET_CODEC_PAR(codecDef, kDecoderPCM16B, codecInst.pltype, NULL, 8000);
SET_PCM16B_FUNCTIONS(codecDef);
break;
}
case 16000: {
SET_CODEC_PAR(codecDef, kDecoderPCM16Bwb, codecInst.pltype, NULL,
16000);
SET_PCM16B_WB_FUNCTIONS(codecDef);
break;
}
case 32000: {
SET_CODEC_PAR(codecDef, kDecoderPCM16Bswb32kHz, codecInst.pltype,
NULL, 32000);
SET_PCM16B_SWB32_FUNCTIONS(codecDef);
break;
}
default: {
return -1;
}
}
} else {
switch(_samplingFreqHz) {
case 8000: {
SET_CODEC_PAR(codecDef, kDecoderPCM16B_2ch, codecInst.pltype, NULL,
8000);
SET_PCM16B_FUNCTIONS(codecDef);
break;
}
case 16000: {
SET_CODEC_PAR(codecDef, kDecoderPCM16Bwb_2ch, codecInst.pltype,
NULL, 16000);
SET_PCM16B_WB_FUNCTIONS(codecDef);
break;
}
case 32000: {
SET_CODEC_PAR(codecDef, kDecoderPCM16Bswb32kHz_2ch, codecInst.pltype,
NULL, 32000);
SET_PCM16B_SWB32_FUNCTIONS(codecDef);
break;
}
default: {
return -1;
}
}
}
return 0;
}
ACMGenericCodec* ACMPCM16B::CreateInstance(void) {
return NULL;
}
WebRtc_Word16 ACMPCM16B::InternalCreateEncoder() {
// PCM has no instance.
return 0;
}
WebRtc_Word16 ACMPCM16B::InternalCreateDecoder() {
// PCM has no instance.
return 0;
}
void ACMPCM16B::InternalDestructEncoderInst(void* /* ptrInst */) {
// PCM has no instance.
return;
}
void ACMPCM16B::DestructEncoderSafe() {
// PCM has no instance.
_encoderExist = false;
_encoderInitialized = false;
return;
}
void ACMPCM16B::DestructDecoderSafe() {
// PCM has no instance.
_decoderExist = false;
_decoderInitialized = false;
return;
}
// Split the stereo packet and place left and right channel after each other
// in the payload vector.
void ACMPCM16B::SplitStereoPacket(uint8_t* payload, int32_t* payload_length) {
uint8_t right_byte_msb;
uint8_t right_byte_lsb;
// Check for valid inputs.
assert(payload != NULL);
assert(*payload_length > 0);
// Move two bytes representing right channel each loop, and place it at the
// end of the bytestream vector. After looping the data is reordered to:
// l1 l2 l3 l4 ... l(N-1) lN r1 r2 r3 r4 ... r(N-1) r(N),
// where N is the total number of samples.
for (int i = 0; i < *payload_length / 2; i += 2) {
right_byte_msb = payload[i + 2];
right_byte_lsb = payload[i + 3];
memmove(&payload[i + 2], &payload[i + 4], *payload_length - i - 4);
payload[*payload_length - 2] = right_byte_msb;
payload[*payload_length - 1] = right_byte_lsb;
}
}
#endif
} // namespace webrtc

View File

@ -0,0 +1,67 @@
/*
* 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_MAIN_SOURCE_ACM_PCM16B_H_
#define WEBRTC_MODULES_AUDIO_CODING_MAIN_SOURCE_ACM_PCM16B_H_
#include "acm_generic_codec.h"
namespace webrtc
{
class ACMPCM16B : public ACMGenericCodec
{
public:
ACMPCM16B(WebRtc_Word16 codecID);
~ACMPCM16B();
// for FEC
ACMGenericCodec* CreateInstance(void);
WebRtc_Word16 InternalEncode(
WebRtc_UWord8* bitstream,
WebRtc_Word16* bitStreamLenByte);
WebRtc_Word16 InternalInitEncoder(
WebRtcACMCodecParams *codecParams);
WebRtc_Word16 InternalInitDecoder(
WebRtcACMCodecParams *codecParams);
protected:
WebRtc_Word16 DecodeSafe(
WebRtc_UWord8* bitStream,
WebRtc_Word16 bitStreamLenByte,
WebRtc_Word16* audio,
WebRtc_Word16* audioSamples,
WebRtc_Word8* speechType);
WebRtc_Word32 CodecDef(
WebRtcNetEQ_CodecDef& codecDef,
const CodecInst& codecInst);
void DestructEncoderSafe();
void DestructDecoderSafe();
WebRtc_Word16 InternalCreateEncoder();
WebRtc_Word16 InternalCreateDecoder();
void InternalDestructEncoderInst(
void* ptrInst);
void SplitStereoPacket(uint8_t* payload, int32_t* payload_length);
WebRtc_Word32 _samplingFreqHz;
};
} // namespace webrtc
#endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_SOURCE_ACM_PCM16B_H_

View File

@ -0,0 +1,130 @@
/*
* 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 "acm_pcma.h"
#include "acm_common_defs.h"
#include "acm_neteq.h"
#include "trace.h"
#include "webrtc_neteq.h"
#include "webrtc_neteq_help_macros.h"
// Codec interface
#include "g711_interface.h"
namespace webrtc {
ACMPCMA::ACMPCMA(WebRtc_Word16 codecID) {
_codecID = codecID;
}
ACMPCMA::~ACMPCMA() {
return;
}
WebRtc_Word16 ACMPCMA::InternalEncode(WebRtc_UWord8* bitStream,
WebRtc_Word16* bitStreamLenByte) {
*bitStreamLenByte = WebRtcG711_EncodeA(NULL, &_inAudio[_inAudioIxRead],
_frameLenSmpl * _noChannels,
(WebRtc_Word16*) bitStream);
// Increment the read index this tell the caller that how far
// we have gone forward in reading the audio buffer.
_inAudioIxRead += _frameLenSmpl * _noChannels;
return *bitStreamLenByte;
}
WebRtc_Word16 ACMPCMA::DecodeSafe(WebRtc_UWord8* /* bitStream */,
WebRtc_Word16 /* bitStreamLenByte */,
WebRtc_Word16* /* audio */,
WebRtc_Word16* /* audioSamples */,
WebRtc_Word8* /* speechType */) {
return 0;
}
WebRtc_Word16 ACMPCMA::InternalInitEncoder(
WebRtcACMCodecParams* /* codecParams */) {
// This codec does not need initialization, PCM has no instance.
return 0;
}
WebRtc_Word16 ACMPCMA::InternalInitDecoder(
WebRtcACMCodecParams* /* codecParams */) {
// This codec does not need initialization, PCM has no instance.
return 0;
}
WebRtc_Word32 ACMPCMA::CodecDef(WebRtcNetEQ_CodecDef& codecDef,
const CodecInst& codecInst) {
// Fill up the structure by calling
// "SET_CODEC_PAR" & "SET_PCMA_FUNCTION."
// Then call NetEQ to add the codec to it's database.
if (codecInst.channels == 1) {
// Mono mode.
SET_CODEC_PAR(codecDef, kDecoderPCMa, codecInst.pltype, NULL, 8000);
} else {
// Stereo mode.
SET_CODEC_PAR(codecDef, kDecoderPCMa_2ch, codecInst.pltype, NULL, 8000);
}
SET_PCMA_FUNCTIONS(codecDef);
return 0;
}
ACMGenericCodec* ACMPCMA::CreateInstance(void) {
return NULL;
}
WebRtc_Word16 ACMPCMA::InternalCreateEncoder() {
// PCM has no instance.
return 0;
}
WebRtc_Word16 ACMPCMA::InternalCreateDecoder() {
// PCM has no instance.
return 0;
}
void ACMPCMA::InternalDestructEncoderInst(void* /* ptrInst */) {
// PCM has no instance.
return;
}
void ACMPCMA::DestructEncoderSafe() {
// PCM has no instance.
return;
}
void ACMPCMA::DestructDecoderSafe() {
// PCM has no instance.
_decoderInitialized = false;
_decoderExist = false;
return;
}
// Split the stereo packet and place left and right channel after each other
// in the payload vector.
void ACMPCMA::SplitStereoPacket(uint8_t* payload, int32_t* payload_length) {
uint8_t right_byte;
// Check for valid inputs.
assert(payload != NULL);
assert(*payload_length > 0);
// Move one bytes representing right channel each loop, and place it at the
// end of the bytestream vector. After looping the data is reordered to:
// l1 l2 l3 l4 ... l(N-1) lN r1 r2 r3 r4 ... r(N-1) r(N),
// where N is the total number of samples.
for (int i = 0; i < *payload_length / 2; i ++) {
right_byte = payload[i + 1];
memmove(&payload[i + 1], &payload[i + 2], *payload_length - i - 2);
payload[*payload_length - 1] = right_byte;
}
}
} // namespace webrtc

View File

@ -0,0 +1,65 @@
/*
* 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_MAIN_SOURCE_ACM_PCMA_H_
#define WEBRTC_MODULES_AUDIO_CODING_MAIN_SOURCE_ACM_PCMA_H_
#include "acm_generic_codec.h"
namespace webrtc
{
class ACMPCMA : public ACMGenericCodec
{
public:
ACMPCMA(WebRtc_Word16 codecID);
~ACMPCMA();
// for FEC
ACMGenericCodec* CreateInstance(void);
WebRtc_Word16 InternalEncode(
WebRtc_UWord8* bitstream,
WebRtc_Word16* bitStreamLenByte);
WebRtc_Word16 InternalInitEncoder(
WebRtcACMCodecParams *codecParams);
WebRtc_Word16 InternalInitDecoder(
WebRtcACMCodecParams *codecParams);
protected:
WebRtc_Word16 DecodeSafe(
WebRtc_UWord8* bitStream,
WebRtc_Word16 bitStreamLenByte,
WebRtc_Word16* audio,
WebRtc_Word16* audioSamples,
WebRtc_Word8* speechType);
WebRtc_Word32 CodecDef(
WebRtcNetEQ_CodecDef& codecDef,
const CodecInst& codecInst);
void DestructEncoderSafe();
void DestructDecoderSafe();
WebRtc_Word16 InternalCreateEncoder();
WebRtc_Word16 InternalCreateDecoder();
void InternalDestructEncoderInst(
void* ptrInst);
void SplitStereoPacket(uint8_t* payload, int32_t* payload_length);
};
} // namespace webrtc
#endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_SOURCE_ACM_PCMA_H_

View File

@ -0,0 +1,132 @@
/*
* 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 "acm_pcmu.h"
#include "acm_common_defs.h"
#include "acm_neteq.h"
#include "trace.h"
#include "webrtc_neteq.h"
#include "webrtc_neteq_help_macros.h"
// Codec interface
#include "g711_interface.h"
namespace webrtc {
ACMPCMU::ACMPCMU(WebRtc_Word16 codecID) {
_codecID = codecID;
}
ACMPCMU::~ACMPCMU() {
return;
}
WebRtc_Word16 ACMPCMU::InternalEncode(WebRtc_UWord8* bitStream,
WebRtc_Word16* bitStreamLenByte) {
*bitStreamLenByte = WebRtcG711_EncodeU(NULL, &_inAudio[_inAudioIxRead],
_frameLenSmpl * _noChannels,
(WebRtc_Word16*) bitStream);
// Increment the read index this tell the caller that how far
// we have gone forward in reading the audio buffer.
_inAudioIxRead += _frameLenSmpl * _noChannels;
return *bitStreamLenByte;
}
WebRtc_Word16 ACMPCMU::DecodeSafe(WebRtc_UWord8* /* bitStream */,
WebRtc_Word16 /* bitStreamLenByte */,
WebRtc_Word16* /* audio */,
WebRtc_Word16* /* audioSamples */,
WebRtc_Word8* /* speechType */) {
return 0;
}
WebRtc_Word16 ACMPCMU::InternalInitEncoder(
WebRtcACMCodecParams* /* codecParams */) {
// This codec does not need initialization, PCM has no instance.
return 0;
}
WebRtc_Word16 ACMPCMU::InternalInitDecoder(
WebRtcACMCodecParams* /* codecParams */) {
// This codec does not need initialization, PCM has no instance.
return 0;
}
WebRtc_Word32 ACMPCMU::CodecDef(WebRtcNetEQ_CodecDef& codecDef,
const CodecInst& codecInst) {
// Fill up the structure by calling
// "SET_CODEC_PAR" & "SET_PCMU_FUNCTION."
// Then call NetEQ to add the codec to it's database.
if (codecInst.channels == 1) {
// Mono mode.
SET_CODEC_PAR(codecDef, kDecoderPCMu, codecInst.pltype, NULL, 8000);
} else {
// Stereo mode.
SET_CODEC_PAR(codecDef, kDecoderPCMu_2ch, codecInst.pltype, NULL, 8000);
}
SET_PCMU_FUNCTIONS(codecDef);
return 0;
}
ACMGenericCodec* ACMPCMU::CreateInstance(void) {
return NULL;
}
WebRtc_Word16 ACMPCMU::InternalCreateEncoder() {
// PCM has no instance.
return 0;
}
WebRtc_Word16 ACMPCMU::InternalCreateDecoder() {
// PCM has no instance.
return 0;
}
void ACMPCMU::InternalDestructEncoderInst(void* /* ptrInst */) {
// PCM has no instance.
return;
}
void ACMPCMU::DestructEncoderSafe() {
// PCM has no instance.
_encoderExist = false;
_encoderInitialized = false;
return;
}
void ACMPCMU::DestructDecoderSafe() {
// PCM has no instance.
_decoderInitialized = false;
_decoderExist = false;
return;
}
// Split the stereo packet and place left and right channel after each other
// in the payload vector.
void ACMPCMU::SplitStereoPacket(uint8_t* payload, int32_t* payload_length) {
uint8_t right_byte;
// Check for valid inputs.
assert(payload != NULL);
assert(*payload_length > 0);
// Move one bytes representing right channel each loop, and place it at the
// end of the bytestream vector. After looping the data is reordered to:
// l1 l2 l3 l4 ... l(N-1) lN r1 r2 r3 r4 ... r(N-1) r(N),
// where N is the total number of samples.
for (int i = 0; i < *payload_length / 2; i ++) {
right_byte = payload[i + 1];
memmove(&payload[i + 1], &payload[i + 2], *payload_length - i - 2);
payload[*payload_length - 1] = right_byte;
}
}
} // namespace webrtc

View File

@ -0,0 +1,65 @@
/*
* 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_MAIN_SOURCE_ACM_PCMU_H_
#define WEBRTC_MODULES_AUDIO_CODING_MAIN_SOURCE_ACM_PCMU_H_
#include "acm_generic_codec.h"
namespace webrtc
{
class ACMPCMU : public ACMGenericCodec
{
public:
ACMPCMU(WebRtc_Word16 codecID);
~ACMPCMU();
// for FEC
ACMGenericCodec* CreateInstance(void);
WebRtc_Word16 InternalEncode(
WebRtc_UWord8* bitstream,
WebRtc_Word16* bitStreamLenByte);
WebRtc_Word16 InternalInitEncoder(
WebRtcACMCodecParams *codecParams);
WebRtc_Word16 InternalInitDecoder(
WebRtcACMCodecParams *codecParams);
protected:
WebRtc_Word16 DecodeSafe(
WebRtc_UWord8* bitStream,
WebRtc_Word16 bitStreamLenByte,
WebRtc_Word16* audio,
WebRtc_Word16* audioSamples,
WebRtc_Word8* speechType);
WebRtc_Word32 CodecDef(
WebRtcNetEQ_CodecDef& codecDef,
const CodecInst& codecInst);
void DestructEncoderSafe();
void DestructDecoderSafe();
WebRtc_Word16 InternalCreateEncoder();
WebRtc_Word16 InternalCreateDecoder();
void InternalDestructEncoderInst(
void* ptrInst);
void SplitStereoPacket(uint8_t* payload, int32_t* payload_length);
};
} // namespace webrtc
#endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_SOURCE_ACM_PCMU_H_

View File

@ -0,0 +1,143 @@
/*
* 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 "acm_red.h"
#include "acm_neteq.h"
#include "acm_common_defs.h"
#include "trace.h"
#include "webrtc_neteq.h"
#include "webrtc_neteq_help_macros.h"
namespace webrtc
{
ACMRED::ACMRED(WebRtc_Word16 codecID)
{
_codecID = codecID;
}
ACMRED::~ACMRED()
{
return;
}
WebRtc_Word16
ACMRED::InternalEncode(
WebRtc_UWord8* /* bitStream */,
WebRtc_Word16* /* bitStreamLenByte */)
{
// RED is never used as an encoder
// RED has no instance
return 0;
}
WebRtc_Word16
ACMRED::DecodeSafe(
WebRtc_UWord8* /* bitStream */,
WebRtc_Word16 /* bitStreamLenByte */,
WebRtc_Word16* /* audio */,
WebRtc_Word16* /* audioSamples */,
WebRtc_Word8* /* speechType */)
{
return 0;
}
WebRtc_Word16
ACMRED::InternalInitEncoder(
WebRtcACMCodecParams* /* codecParams */)
{
// This codec does not need initialization,
// RED has no instance
return 0;
}
WebRtc_Word16
ACMRED::InternalInitDecoder(
WebRtcACMCodecParams* /* codecParams */)
{
// This codec does not need initialization,
// RED has no instance
return 0;
}
WebRtc_Word32
ACMRED::CodecDef(
WebRtcNetEQ_CodecDef& codecDef,
const CodecInst& codecInst)
{
if (!_decoderInitialized)
{
// Todo:
// log error
return -1;
}
// Fill up the structure by calling
// "SET_CODEC_PAR" & "SET_PCMU_FUNCTION."
// Then call NetEQ to add the codec to it's
// database.
SET_CODEC_PAR((codecDef), kDecoderRED, codecInst.pltype, NULL, 8000);
SET_RED_FUNCTIONS((codecDef));
return 0;
}
ACMGenericCodec*
ACMRED::CreateInstance(void)
{
return NULL;
}
WebRtc_Word16
ACMRED::InternalCreateEncoder()
{
// RED has no instance
return 0;
}
WebRtc_Word16
ACMRED::InternalCreateDecoder()
{
// RED has no instance
return 0;
}
void
ACMRED::InternalDestructEncoderInst(
void* /* ptrInst */)
{
// RED has no instance
return;
}
void
ACMRED::DestructEncoderSafe()
{
// RED has no instance
return;
}
void ACMRED::DestructDecoderSafe()
{
// RED has no instance
return;
}
} // namespace webrtc

View File

@ -0,0 +1,63 @@
/*
* 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_MAIN_SOURCE_ACM_RED_H_
#define WEBRTC_MODULES_AUDIO_CODING_MAIN_SOURCE_ACM_RED_H_
#include "acm_generic_codec.h"
namespace webrtc
{
class ACMRED : public ACMGenericCodec
{
public:
ACMRED(WebRtc_Word16 codecID);
~ACMRED();
// for FEC
ACMGenericCodec* CreateInstance(void);
WebRtc_Word16 InternalEncode(
WebRtc_UWord8* bitstream,
WebRtc_Word16* bitStreamLenByte);
WebRtc_Word16 InternalInitEncoder(
WebRtcACMCodecParams *codecParams);
WebRtc_Word16 InternalInitDecoder(
WebRtcACMCodecParams *codecParams);
protected:
WebRtc_Word16 DecodeSafe(
WebRtc_UWord8* bitStream,
WebRtc_Word16 bitStreamLenByte,
WebRtc_Word16* audio,
WebRtc_Word16* audioSamples,
WebRtc_Word8* speechType);
WebRtc_Word32 CodecDef(
WebRtcNetEQ_CodecDef& codecDef,
const CodecInst& codecInst);
void DestructEncoderSafe();
void DestructDecoderSafe();
WebRtc_Word16 InternalCreateEncoder();
WebRtc_Word16 InternalCreateDecoder();
void InternalDestructEncoderInst(
void* ptrInst);
};
} // namespace webrtc
#endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_SOURCE_ACM_RED_H_

View File

@ -0,0 +1,72 @@
/*
* 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 <string.h>
#include "acm_resampler.h"
#include "critical_section_wrapper.h"
#include "resampler.h"
#include "signal_processing_library.h"
#include "trace.h"
namespace webrtc {
ACMResampler::ACMResampler()
: _resamplerCritSect(CriticalSectionWrapper::CreateCriticalSection()) {
}
ACMResampler::~ACMResampler() {
delete _resamplerCritSect;
}
WebRtc_Word16 ACMResampler::Resample10Msec(const WebRtc_Word16* inAudio,
WebRtc_Word32 inFreqHz,
WebRtc_Word16* outAudio,
WebRtc_Word32 outFreqHz,
WebRtc_UWord8 numAudioChannels) {
CriticalSectionScoped cs(_resamplerCritSect);
if (inFreqHz == outFreqHz) {
size_t length = static_cast<size_t>(inFreqHz * numAudioChannels / 100);
memcpy(outAudio, inAudio, length * sizeof(WebRtc_Word16));
return static_cast<WebRtc_Word16>(inFreqHz / 100);
}
// |maxLen| is maximum number of samples for 10ms at 48kHz.
int maxLen = 480 * numAudioChannels;
int lengthIn = (WebRtc_Word16)(inFreqHz / 100) * numAudioChannels;
int outLen;
WebRtc_Word32 ret;
ResamplerType type;
type = (numAudioChannels == 1) ? kResamplerSynchronous :
kResamplerSynchronousStereo;
ret = _resampler.ResetIfNeeded(inFreqHz, outFreqHz, type);
if (ret < 0) {
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, 0,
"Error in reset of resampler");
return -1;
}
ret = _resampler.Push(inAudio, lengthIn, outAudio, maxLen, outLen);
if (ret < 0) {
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, 0,
"Error in resampler: resampler.Push");
return -1;
}
WebRtc_Word16 outAudioLenSmpl = (WebRtc_Word16) outLen / numAudioChannels;
return outAudioLenSmpl;
}
} // namespace webrtc

View File

@ -0,0 +1,40 @@
/*
* 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_MAIN_SOURCE_ACM_RESAMPLER_H_
#define WEBRTC_MODULES_AUDIO_CODING_MAIN_SOURCE_ACM_RESAMPLER_H_
#include "resampler.h"
#include "typedefs.h"
namespace webrtc {
class CriticalSectionWrapper;
class ACMResampler {
public:
ACMResampler();
~ACMResampler();
WebRtc_Word16 Resample10Msec(const WebRtc_Word16* inAudio,
const WebRtc_Word32 inFreqHz,
WebRtc_Word16* outAudio,
const WebRtc_Word32 outFreqHz,
WebRtc_UWord8 numAudioChannels);
private:
// Use the Resampler class.
Resampler _resampler;
CriticalSectionWrapper* _resamplerCritSect;
};
} // namespace webrtc
#endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_SOURCE_ACM_RESAMPLER_H_

View File

@ -0,0 +1,622 @@
/*
* 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 "acm_speex.h"
#include "acm_codec_database.h"
#include "acm_common_defs.h"
#include "acm_neteq.h"
#include "trace.h"
#include "webrtc_neteq.h"
#include "webrtc_neteq_help_macros.h"
#ifdef WEBRTC_CODEC_SPEEX
// NOTE! Speex is not included in the open-source package. The following
// interface file is needed:
//
// /modules/audio_coding/codecs/speex/main/interface/speex_interface.h
//
// The API in the header file should match the one below.
//
// int16_t WebRtcSpeex_CreateEnc(SPEEX_encinst_t **SPEEXenc_inst,
// int32_t fs);
// int16_t WebRtcSpeex_FreeEnc(SPEEX_encinst_t *SPEEXenc_inst);
// int16_t WebRtcSpeex_CreateDec(SPEEX_decinst_t **SPEEXdec_inst,
// int32_t fs,
// int16_t enh_enabled);
// int16_t WebRtcSpeex_FreeDec(SPEEX_decinst_t *SPEEXdec_inst);
// int16_t WebRtcSpeex_Encode(SPEEX_encinst_t *SPEEXenc_inst,
// int16_t *speechIn,
// int32_t rate);
// int16_t WebRtcSpeex_EncoderInit(SPEEX_encinst_t *SPEEXenc_inst,
// int16_t vbr, int16_t complexity,
// int16_t vad_enable);
// int16_t WebRtcSpeex_GetBitstream(SPEEX_encinst_t *SPEEXenc_inst,
// int16_t *encoded);
// int16_t WebRtcSpeex_DecodePlc(SPEEX_decinst_t *SPEEXdec_inst,
// int16_t *decoded, int16_t noOfLostFrames);
// int16_t WebRtcSpeex_Decode(SPEEX_decinst_t *SPEEXdec_inst,
// int16_t *encoded, int16_t len,
// int16_t *decoded, int16_t *speechType);
// int16_t WebRtcSpeex_DecoderInit(SPEEX_decinst_t *SPEEXdec_inst);
#include "speex_interface.h"
#endif
namespace webrtc {
#ifndef WEBRTC_CODEC_SPEEX
ACMSPEEX::ACMSPEEX(WebRtc_Word16 /* codecID */)
: _encoderInstPtr(NULL),
_decoderInstPtr(NULL),
_complMode(0),
_vbrEnabled(false),
_encodingRate(-1),
_samplingFrequency(-1),
_samplesIn20MsAudio(-1) {
return;
}
ACMSPEEX::~ACMSPEEX()
{
return;
}
WebRtc_Word16
ACMSPEEX::InternalEncode(
WebRtc_UWord8* /* bitStream */,
WebRtc_Word16* /* bitStreamLenByte */)
{
return -1;
}
WebRtc_Word16
ACMSPEEX::DecodeSafe(
WebRtc_UWord8* /* bitStream */,
WebRtc_Word16 /* bitStreamLenByte */,
WebRtc_Word16* /* audio */,
WebRtc_Word16* /* audioSamples */,
WebRtc_Word8* /* speechType */)
{
return -1;
}
WebRtc_Word16
ACMSPEEX::EnableDTX()
{
return -1;
}
WebRtc_Word16
ACMSPEEX::DisableDTX()
{
return -1;
}
WebRtc_Word16
ACMSPEEX::InternalInitEncoder(
WebRtcACMCodecParams* /* codecParams */)
{
return -1;
}
WebRtc_Word16
ACMSPEEX::InternalInitDecoder(
WebRtcACMCodecParams* /* codecParams */)
{
return -1;
}
WebRtc_Word32
ACMSPEEX::CodecDef(
WebRtcNetEQ_CodecDef& /* codecDef */,
const CodecInst& /* codecInst */)
{
return -1;
}
ACMGenericCodec*
ACMSPEEX::CreateInstance(void)
{
return NULL;
}
WebRtc_Word16
ACMSPEEX::InternalCreateEncoder()
{
return -1;
}
void
ACMSPEEX::DestructEncoderSafe()
{
return;
}
WebRtc_Word16
ACMSPEEX::InternalCreateDecoder()
{
return -1;
}
void
ACMSPEEX::DestructDecoderSafe()
{
return;
}
WebRtc_Word16
ACMSPEEX::SetBitRateSafe(
const WebRtc_Word32 /* rate */)
{
return -1;
}
void
ACMSPEEX::InternalDestructEncoderInst(
void* /* ptrInst */)
{
return;
}
#ifdef UNUSEDSPEEX
WebRtc_Word16
ACMSPEEX::EnableVBR()
{
return -1;
}
WebRtc_Word16
ACMSPEEX::DisableVBR()
{
return -1;
}
WebRtc_Word16
ACMSPEEX::SetComplMode(
WebRtc_Word16 mode)
{
return -1;
}
#endif
#else //===================== Actual Implementation =======================
ACMSPEEX::ACMSPEEX(WebRtc_Word16 codecID):
_encoderInstPtr(NULL),
_decoderInstPtr(NULL)
{
_codecID = codecID;
// Set sampling frequency, frame size and rate Speex
if(_codecID == ACMCodecDB::kSPEEX8)
{
_samplingFrequency = 8000;
_samplesIn20MsAudio = 160;
_encodingRate = 11000;
}
else if(_codecID == ACMCodecDB::kSPEEX16)
{
_samplingFrequency = 16000;
_samplesIn20MsAudio = 320;
_encodingRate = 22000;
}
else
{
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
"Wrong codec id for Speex.");
_samplingFrequency = -1;
_samplesIn20MsAudio = -1;
_encodingRate = -1;
}
_hasInternalDTX = true;
_dtxEnabled = false;
_vbrEnabled = false;
_complMode = 3; // default complexity value
return;
}
ACMSPEEX::~ACMSPEEX()
{
if(_encoderInstPtr != NULL)
{
WebRtcSpeex_FreeEnc(_encoderInstPtr);
_encoderInstPtr = NULL;
}
if(_decoderInstPtr != NULL)
{
WebRtcSpeex_FreeDec(_decoderInstPtr);
_decoderInstPtr = NULL;
}
return;
}
WebRtc_Word16
ACMSPEEX::InternalEncode(
WebRtc_UWord8* bitStream,
WebRtc_Word16* bitStreamLenByte)
{
WebRtc_Word16 status;
WebRtc_Word16 numEncodedSamples = 0;
WebRtc_Word16 n = 0;
while( numEncodedSamples < _frameLenSmpl)
{
status = WebRtcSpeex_Encode(_encoderInstPtr, &_inAudio[_inAudioIxRead],
_encodingRate);
// increment the read index this tell the caller that how far
// we have gone forward in reading the audio buffer
_inAudioIxRead += _samplesIn20MsAudio;
numEncodedSamples += _samplesIn20MsAudio;
if(status < 0)
{
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
"Error in Speex encoder");
return status;
}
// Update VAD, if internal DTX is used
if(_hasInternalDTX && _dtxEnabled)
{
_vadLabel[n++] = status;
_vadLabel[n++] = status;
}
if(status == 0)
{
// This frame is detected as inactive. We need send whatever
// encoded so far.
*bitStreamLenByte = WebRtcSpeex_GetBitstream(_encoderInstPtr,
(WebRtc_Word16*)bitStream);
return *bitStreamLenByte;
}
}
*bitStreamLenByte = WebRtcSpeex_GetBitstream(_encoderInstPtr,
(WebRtc_Word16*)bitStream);
return *bitStreamLenByte;
}
WebRtc_Word16
ACMSPEEX::DecodeSafe(
WebRtc_UWord8* /* bitStream */,
WebRtc_Word16 /* bitStreamLenByte */,
WebRtc_Word16* /* audio */,
WebRtc_Word16* /* audioSamples */,
WebRtc_Word8* /* speechType */)
{
return 0;
}
WebRtc_Word16
ACMSPEEX::EnableDTX()
{
if(_dtxEnabled)
{
return 0;
}
else if(_encoderExist) // check if encoder exist
{
// enable DTX
if(WebRtcSpeex_EncoderInit(_encoderInstPtr, (_vbrEnabled ? 1:0), _complMode, 1) < 0)
{
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
"Cannot enable DTX for Speex");
return -1;
}
_dtxEnabled = true;
return 0;
}
else
{
return -1;
}
return 0;
}
WebRtc_Word16
ACMSPEEX::DisableDTX()
{
if(!_dtxEnabled)
{
return 0;
}
else if(_encoderExist) // check if encoder exist
{
// disable DTX
if(WebRtcSpeex_EncoderInit(_encoderInstPtr, (_vbrEnabled ? 1:0), _complMode, 0) < 0)
{
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
"Cannot disable DTX for Speex");
return -1;
}
_dtxEnabled = false;
return 0;
}
else
{
// encoder doesn't exists, therefore disabling is harmless
return 0;
}
return 0;
}
WebRtc_Word16
ACMSPEEX::InternalInitEncoder(
WebRtcACMCodecParams* codecParams)
{
// sanity check
if (_encoderInstPtr == NULL)
{
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
"Cannot initialize Speex encoder, instance does not exist");
return -1;
}
WebRtc_Word16 status = SetBitRateSafe((codecParams->codecInstant).rate);
status += (WebRtcSpeex_EncoderInit(_encoderInstPtr, _vbrEnabled, _complMode, ((codecParams->enableDTX)? 1:0)) < 0)? -1:0;
if (status >= 0) {
return 0;
} else {
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
"Error in initialization of Speex encoder");
return -1;
}
}
WebRtc_Word16
ACMSPEEX::InternalInitDecoder(
WebRtcACMCodecParams* /* codecParams */)
{
WebRtc_Word16 status;
// sanity check
if (_decoderInstPtr == NULL)
{
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
"Cannot initialize Speex decoder, instance does not exist");
return -1;
}
status = ((WebRtcSpeex_DecoderInit(_decoderInstPtr) < 0)? -1:0);
if (status >= 0) {
return 0;
} else {
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
"Error in initialization of Speex decoder");
return -1;
}
}
WebRtc_Word32
ACMSPEEX::CodecDef(
WebRtcNetEQ_CodecDef& codecDef,
const CodecInst& codecInst)
{
if (!_decoderInitialized)
{
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
"Error, Speex decoder is not initialized");
return -1;
}
// Fill up the structure by calling
// "SET_CODEC_PAR" & "SET_SPEEX_FUNCTION."
// Then call NetEQ to add the codec to its
// database.
switch(_samplingFrequency)
{
case 8000:
{
SET_CODEC_PAR((codecDef), kDecoderSPEEX_8, codecInst.pltype,
_decoderInstPtr, 8000);
break;
}
case 16000:
{
SET_CODEC_PAR((codecDef), kDecoderSPEEX_16, codecInst.pltype,
_decoderInstPtr, 16000);
break;
}
default:
{
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
"Unsupported sampling frequency for Speex");
return -1;
}
}
SET_SPEEX_FUNCTIONS((codecDef));
return 0;
}
ACMGenericCodec*
ACMSPEEX::CreateInstance(void)
{
return NULL;
}
WebRtc_Word16
ACMSPEEX::InternalCreateEncoder()
{
return WebRtcSpeex_CreateEnc(&_encoderInstPtr, _samplingFrequency);
}
void
ACMSPEEX::DestructEncoderSafe()
{
if(_encoderInstPtr != NULL)
{
WebRtcSpeex_FreeEnc(_encoderInstPtr);
_encoderInstPtr = NULL;
}
// there is no encoder set the following
_encoderExist = false;
_encoderInitialized = false;
_encodingRate = 0;
}
WebRtc_Word16
ACMSPEEX::InternalCreateDecoder()
{
return WebRtcSpeex_CreateDec(&_decoderInstPtr, _samplingFrequency, 1);
}
void
ACMSPEEX::DestructDecoderSafe()
{
if(_decoderInstPtr != NULL)
{
WebRtcSpeex_FreeDec(_decoderInstPtr);
_decoderInstPtr = NULL;
}
// there is no encoder instance set the followings
_decoderExist = false;
_decoderInitialized = false;
}
WebRtc_Word16
ACMSPEEX::SetBitRateSafe(
const WebRtc_Word32 rate)
{
// Check if changed rate
if (rate == _encodingRate) {
return 0;
} else if (rate > 2000) {
_encodingRate = rate;
_encoderParams.codecInstant.rate = rate;
} else {
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
"Unsupported encoding rate for Speex");
return -1;
}
return 0;
}
void
ACMSPEEX::InternalDestructEncoderInst(
void* ptrInst)
{
if(ptrInst != NULL)
{
WebRtcSpeex_FreeEnc((SPEEX_encinst_t_*)ptrInst);
}
return;
}
#ifdef UNUSEDSPEEX
// This API is currently not in use. If requested to be able to enable/disable VBR
// an ACM API need to be added.
WebRtc_Word16
ACMSPEEX::EnableVBR()
{
if(_vbrEnabled)
{
return 0;
}
else if(_encoderExist) // check if encoder exist
{
// enable Variable Bit Rate (VBR)
if(WebRtcSpeex_EncoderInit(_encoderInstPtr, 1, _complMode, (_dtxEnabled? 1:0)) < 0)
{
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
"Cannot enable VBR mode for Speex");
return -1;
}
_vbrEnabled = true;
return 0;
}
else
{
return -1;
}
}
// This API is currently not in use. If requested to be able to enable/disable VBR
// an ACM API need to be added.
WebRtc_Word16
ACMSPEEX::DisableVBR()
{
if(!_vbrEnabled)
{
return 0;
}
else if(_encoderExist) // check if encoder exist
{
// disable DTX
if(WebRtcSpeex_EncoderInit(_encoderInstPtr, 0, _complMode, (_dtxEnabled? 1:0)) < 0)
{
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
"Cannot disable DTX for Speex");
return -1;
}
_vbrEnabled = false;
return 0;
}
else
{
// encoder doesn't exists, therefore disabling is harmless
return 0;
}
}
// This API is currently not in use. If requested to be able to set complexity
// an ACM API need to be added.
WebRtc_Word16
ACMSPEEX::SetComplMode(
WebRtc_Word16 mode)
{
// Check if new mode
if(mode == _complMode)
{
return 0;
}
else if(_encoderExist) // check if encoder exist
{
// Set new mode
if(WebRtcSpeex_EncoderInit(_encoderInstPtr, 0, mode, (_dtxEnabled? 1:0)) < 0)
{
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
"Error in complexity mode for Speex");
return -1;
}
_complMode = mode;
return 0;
}
else
{
// encoder doesn't exists, therefore disabling is harmless
return 0;
}
}
#endif
#endif
} // namespace webrtc

View File

@ -0,0 +1,90 @@
/*
* 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_MAIN_SOURCE_ACM_SPEEX_H_
#define WEBRTC_MODULES_AUDIO_CODING_MAIN_SOURCE_ACM_SPEEX_H_
#include "acm_generic_codec.h"
// forward declaration
struct SPEEX_encinst_t_;
struct SPEEX_decinst_t_;
namespace webrtc {
class ACMSPEEX : public ACMGenericCodec
{
public:
ACMSPEEX(WebRtc_Word16 codecID);
~ACMSPEEX();
// for FEC
ACMGenericCodec* CreateInstance(void);
WebRtc_Word16 InternalEncode(
WebRtc_UWord8* bitstream,
WebRtc_Word16* bitStreamLenByte);
WebRtc_Word16 InternalInitEncoder(
WebRtcACMCodecParams *codecParams);
WebRtc_Word16 InternalInitDecoder(
WebRtcACMCodecParams *codecParams);
protected:
WebRtc_Word16 DecodeSafe(
WebRtc_UWord8* bitStream,
WebRtc_Word16 bitStreamLenByte,
WebRtc_Word16* audio,
WebRtc_Word16* audioSamples,
WebRtc_Word8* speechType);
WebRtc_Word32 CodecDef(
WebRtcNetEQ_CodecDef& codecDef,
const CodecInst& codecInst);
void DestructEncoderSafe();
void DestructDecoderSafe();
WebRtc_Word16 InternalCreateEncoder();
WebRtc_Word16 InternalCreateDecoder();
void InternalDestructEncoderInst(
void* ptrInst);
WebRtc_Word16 SetBitRateSafe(
const WebRtc_Word32 rate);
WebRtc_Word16 EnableDTX();
WebRtc_Word16 DisableDTX();
#ifdef UNUSEDSPEEX
WebRtc_Word16 EnableVBR();
WebRtc_Word16 DisableVBR();
WebRtc_Word16 SetComplMode(
WebRtc_Word16 mode);
#endif
SPEEX_encinst_t_* _encoderInstPtr;
SPEEX_decinst_t_* _decoderInstPtr;
WebRtc_Word16 _complMode;
bool _vbrEnabled;
WebRtc_Word32 _encodingRate;
WebRtc_Word16 _samplingFrequency;
WebRtc_UWord16 _samplesIn20MsAudio;
};
} // namespace webrtc
#endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_SOURCE_ACM_SPEEX_H_

View File

@ -0,0 +1,106 @@
/*
* 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 "acm_dtmf_detection.h"
#include "audio_coding_module.h"
#include "audio_coding_module_impl.h"
#include "trace.h"
namespace webrtc
{
// Create module
AudioCodingModule*
AudioCodingModule::Create(
const WebRtc_Word32 id)
{
return new AudioCodingModuleImpl(id);
}
// Destroy module
void
AudioCodingModule::Destroy(
AudioCodingModule* module)
{
delete static_cast<AudioCodingModuleImpl*> (module);
}
// Get number of supported codecs
WebRtc_UWord8 AudioCodingModule::NumberOfCodecs()
{
return static_cast<WebRtc_UWord8>(ACMCodecDB::kNumCodecs);
}
// Get supported codec param with id
WebRtc_Word32
AudioCodingModule::Codec(
const WebRtc_UWord8 listId,
CodecInst& codec)
{
// Get the codec settings for the codec with the given list ID
return ACMCodecDB::Codec(listId, &codec);
}
// Get supported codec Param with name, frequency and number of channels.
WebRtc_Word32 AudioCodingModule::Codec(const char* payload_name,
CodecInst& codec,
int sampling_freq_hz,
int channels) {
int codec_id;
// Get the id of the codec from the database.
codec_id = ACMCodecDB::CodecId(payload_name, sampling_freq_hz, channels);
if (codec_id < 0) {
// We couldn't find a matching codec, set the parameterss to unacceptable
// values and return.
codec.plname[0] = '\0';
codec.pltype = -1;
codec.pacsize = 0;
codec.rate = 0;
codec.plfreq = 0;
return -1;
}
// Get default codec settings.
ACMCodecDB::Codec(codec_id, &codec);
return 0;
}
// Get supported codec Index with name, frequency and number of channels.
WebRtc_Word32 AudioCodingModule::Codec(const char* payload_name,
int sampling_freq_hz,
int channels) {
return ACMCodecDB::CodecId(payload_name, sampling_freq_hz, channels);
}
// Checks the validity of the parameters of the given codec
bool
AudioCodingModule::IsCodecValid(
const CodecInst& codec)
{
int mirrorID;
char errMsg[500];
int codecNumber = ACMCodecDB::CodecNumber(&codec, &mirrorID, errMsg, 500);
if(codecNumber < 0)
{
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, -1, errMsg);
return false;
}
else
{
return true;
}
}
} // namespace webrtc

View File

@ -0,0 +1,166 @@
# 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.
{
'variables': {
'audio_coding_dependencies': [
'CNG',
'G711',
'G722',
'iLBC',
'iSAC',
'iSACFix',
'PCM16B',
'NetEq',
'<(webrtc_root)/common_audio/common_audio.gyp:resampler',
'<(webrtc_root)/common_audio/common_audio.gyp:signal_processing',
'<(webrtc_root)/common_audio/common_audio.gyp:vad',
'<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:system_wrappers',
],
'audio_coding_defines': [],
'conditions': [
['include_opus==1', {
'audio_coding_dependencies': ['webrtc_opus',],
'audio_coding_defines': ['WEBRTC_CODEC_OPUS',],
}],
],
},
'targets': [
{
'target_name': 'audio_coding_module',
'type': '<(library)',
'defines': [
'<@(audio_coding_defines)',
],
'dependencies': [
'<@(audio_coding_dependencies)',
],
'include_dirs': [
'../interface',
'../../../interface',
],
'direct_dependent_settings': {
'include_dirs': [
'../interface',
'../../../interface',
],
},
'sources': [
'../interface/audio_coding_module.h',
'../interface/audio_coding_module_typedefs.h',
'acm_amr.cc',
'acm_amr.h',
'acm_amrwb.cc',
'acm_amrwb.h',
'acm_celt.cc',
'acm_celt.h',
'acm_cng.cc',
'acm_cng.h',
'acm_codec_database.cc',
'acm_codec_database.h',
'acm_dtmf_detection.cc',
'acm_dtmf_detection.h',
'acm_dtmf_playout.cc',
'acm_dtmf_playout.h',
'acm_g722.cc',
'acm_g722.h',
'acm_g7221.cc',
'acm_g7221.h',
'acm_g7221c.cc',
'acm_g7221c.h',
'acm_g729.cc',
'acm_g729.h',
'acm_g7291.cc',
'acm_g7291.h',
'acm_generic_codec.cc',
'acm_generic_codec.h',
'acm_gsmfr.cc',
'acm_gsmfr.h',
'acm_ilbc.cc',
'acm_ilbc.h',
'acm_isac.cc',
'acm_isac.h',
'acm_isac_macros.h',
'acm_neteq.cc',
'acm_neteq.h',
'acm_opus.cc',
'acm_opus.h',
'acm_speex.cc',
'acm_speex.h',
'acm_pcm16b.cc',
'acm_pcm16b.h',
'acm_pcma.cc',
'acm_pcma.h',
'acm_pcmu.cc',
'acm_pcmu.h',
'acm_red.cc',
'acm_red.h',
'acm_resampler.cc',
'acm_resampler.h',
'audio_coding_module.cc',
'audio_coding_module_impl.cc',
'audio_coding_module_impl.h',
],
},
],
'conditions': [
['include_tests==1', {
'targets': [
{
'target_name': 'audio_coding_module_test',
'type': 'executable',
'dependencies': [
'audio_coding_module',
'<(webrtc_root)/test/test.gyp:test_support_main',
'<(DEPTH)/testing/gtest.gyp:gtest',
'<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:system_wrappers',
],
'sources': [
'../test/ACMTest.cc',
'../test/APITest.cc',
'../test/Channel.cc',
'../test/EncodeDecodeTest.cc',
'../test/iSACTest.cc',
'../test/PCMFile.cc',
'../test/RTPFile.cc',
'../test/SpatialAudio.cc',
'../test/TestAllCodecs.cc',
'../test/Tester.cc',
'../test/TestFEC.cc',
'../test/TestStereo.cc',
'../test/TestVADDTX.cc',
'../test/TimedTrace.cc',
'../test/TwoWayCommunication.cc',
'../test/utility.cc',
],
},
{
'target_name': 'audio_coding_unittests',
'type': 'executable',
'dependencies': [
'audio_coding_module',
'NetEq',
'<(webrtc_root)/common_audio/common_audio.gyp:vad',
'<(DEPTH)/testing/gtest.gyp:gtest',
'<(webrtc_root)/test/test.gyp:test_support_main',
'<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:system_wrappers',
],
'sources': [
'acm_neteq_unittest.cc',
],
}, # audio_coding_unittests
],
}],
],
}
# Local Variables:
# tab-width:2
# indent-tabs-mode:nil
# End:
# vim: set expandtab tabstop=2 shiftwidth=2:

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,347 @@
/*
* 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_MAIN_SOURCE_AUDIO_CODING_MODULE_IMPL_H_
#define WEBRTC_MODULES_AUDIO_CODING_MAIN_SOURCE_AUDIO_CODING_MODULE_IMPL_H_
#include "acm_codec_database.h"
#include "acm_neteq.h"
#include "acm_resampler.h"
#include "common_types.h"
#include "engine_configurations.h"
namespace webrtc {
class ACMDTMFDetection;
class ACMGenericCodec;
class CriticalSectionWrapper;
class RWLockWrapper;
#ifdef ACM_QA_TEST
# include <stdio.h>
#endif
class AudioCodingModuleImpl : public AudioCodingModule {
public:
// Constructor
AudioCodingModuleImpl(const WebRtc_Word32 id);
// Destructor
~AudioCodingModuleImpl();
// Change the unique identifier of this object.
virtual WebRtc_Word32 ChangeUniqueId(const WebRtc_Word32 id);
// Returns the number of milliseconds until the module want a worker thread
// to call Process.
WebRtc_Word32 TimeUntilNextProcess();
// Process any pending tasks such as timeouts.
WebRtc_Word32 Process();
/////////////////////////////////////////
// Sender
//
// Initialize send codec.
WebRtc_Word32 InitializeSender();
// Reset send codec.
WebRtc_Word32 ResetEncoder();
// Can be called multiple times for Codec, CNG, RED.
WebRtc_Word32 RegisterSendCodec(const CodecInst& send_codec);
// Get current send codec.
WebRtc_Word32 SendCodec(CodecInst& current_codec) const;
// Get current send frequency.
WebRtc_Word32 SendFrequency() const;
// Get encode bitrate.
// Adaptive rate codecs return their current encode target rate, while other
// codecs return there longterm avarage or their fixed rate.
WebRtc_Word32 SendBitrate() const;
// Set available bandwidth, inform the encoder about the
// estimated bandwidth received from the remote party.
virtual WebRtc_Word32 SetReceivedEstimatedBandwidth(const WebRtc_Word32 bw);
// Register a transport callback which will be
// called to deliver the encoded buffers.
WebRtc_Word32 RegisterTransportCallback(
AudioPacketizationCallback* transport);
// Used by the module to deliver messages to the codec module/application
// AVT(DTMF).
WebRtc_Word32 RegisterIncomingMessagesCallback(
AudioCodingFeedback* incoming_message, const ACMCountries cpt);
// Add 10MS of raw (PCM) audio data to the encoder.
WebRtc_Word32 Add10MsData(const AudioFrame& audio_frame);
// Set background noise mode for NetEQ, on, off or fade.
WebRtc_Word32 SetBackgroundNoiseMode(const ACMBackgroundNoiseMode mode);
// Get current background noise mode.
WebRtc_Word32 BackgroundNoiseMode(ACMBackgroundNoiseMode& mode);
/////////////////////////////////////////
// (FEC) Forward Error Correction
//
// Configure FEC status i.e on/off.
WebRtc_Word32 SetFECStatus(const bool enable_fec);
// Get FEC status.
bool FECStatus() const;
/////////////////////////////////////////
// (VAD) Voice Activity Detection
// and
// (CNG) Comfort Noise Generation
//
WebRtc_Word32 SetVAD(const bool enable_dtx = true,
const bool enable_vad = false,
const ACMVADMode mode = VADNormal);
WebRtc_Word32 VAD(bool& dtx_enabled, bool& vad_enabled,
ACMVADMode& mode) const;
WebRtc_Word32 RegisterVADCallback(ACMVADCallback* vadCallback);
// Get VAD aggressiveness on the incoming stream.
ACMVADMode ReceiveVADMode() const;
// Configure VAD aggressiveness on the incoming stream.
WebRtc_Word16 SetReceiveVADMode(const ACMVADMode mode);
/////////////////////////////////////////
// Receiver
//
// Initialize receiver, resets codec database etc.
WebRtc_Word32 InitializeReceiver();
// Reset the decoder state.
WebRtc_Word32 ResetDecoder();
// Get current receive frequency.
WebRtc_Word32 ReceiveFrequency() const;
// Get current playout frequency.
WebRtc_Word32 PlayoutFrequency() const;
// Register possible reveive codecs, can be called multiple times,
// for codecs, CNG, DTMF, RED.
WebRtc_Word32 RegisterReceiveCodec(const CodecInst& receive_codec);
// Get current received codec.
WebRtc_Word32 ReceiveCodec(CodecInst& current_codec) const;
// Incoming packet from network parsed and ready for decode.
WebRtc_Word32 IncomingPacket(const WebRtc_UWord8* incoming_payload,
const WebRtc_Word32 payload_length,
const WebRtcRTPHeader& rtp_info);
// Incoming payloads, without rtp-info, the rtp-info will be created in ACM.
// One usage for this API is when pre-encoded files are pushed in ACM.
WebRtc_Word32 IncomingPayload(const WebRtc_UWord8* incoming_payload,
const WebRtc_Word32 payload_length,
const WebRtc_UWord8 payload_type,
const WebRtc_UWord32 timestamp = 0);
// Minimum playout dealy (used for lip-sync).
WebRtc_Word32 SetMinimumPlayoutDelay(const WebRtc_Word32 time_ms);
// Configure Dtmf playout status i.e on/off playout the incoming outband Dtmf
// tone.
WebRtc_Word32 SetDtmfPlayoutStatus(const bool enable);
// Get Dtmf playout status.
bool DtmfPlayoutStatus() const;
// Estimate the Bandwidth based on the incoming stream, needed
// for one way audio where the RTCP send the BW estimate.
// This is also done in the RTP module .
WebRtc_Word32 DecoderEstimatedBandwidth() const;
// Set playout mode voice, fax.
WebRtc_Word32 SetPlayoutMode(const AudioPlayoutMode mode);
// Get playout mode voice, fax.
AudioPlayoutMode PlayoutMode() const;
// Get playout timestamp.
WebRtc_Word32 PlayoutTimestamp(WebRtc_UWord32& timestamp);
// Get 10 milliseconds of raw audio data to play out, and
// automatic resample to the requested frequency if > 0.
WebRtc_Word32 PlayoutData10Ms(const WebRtc_Word32 desired_freq_hz,
AudioFrame &audio_frame);
/////////////////////////////////////////
// Statistics
//
WebRtc_Word32 NetworkStatistics(ACMNetworkStatistics& statistics) const;
void DestructEncoderInst(void* inst);
WebRtc_Word16 AudioBuffer(WebRtcACMAudioBuff& buffer);
// GET RED payload for iSAC. The method id called when 'this' ACM is
// the default ACM.
WebRtc_Word32 REDPayloadISAC(const WebRtc_Word32 isac_rate,
const WebRtc_Word16 isac_bw_estimate,
WebRtc_UWord8* payload,
WebRtc_Word16* length_bytes);
WebRtc_Word16 SetAudioBuffer(WebRtcACMAudioBuff& buffer);
WebRtc_UWord32 EarliestTimestamp() const;
WebRtc_Word32 LastEncodedTimestamp(WebRtc_UWord32& timestamp) const;
WebRtc_Word32 ReplaceInternalDTXWithWebRtc(const bool use_webrtc_dtx);
WebRtc_Word32 IsInternalDTXReplacedWithWebRtc(bool& uses_webrtc_dtx);
WebRtc_Word32 SetISACMaxRate(const WebRtc_UWord32 max_bit_per_sec);
WebRtc_Word32 SetISACMaxPayloadSize(const WebRtc_UWord16 max_size_bytes);
WebRtc_Word32 ConfigISACBandwidthEstimator(
const WebRtc_UWord8 frame_size_ms,
const WebRtc_UWord16 rate_bit_per_sec,
const bool enforce_frame_size = false);
WebRtc_Word32 UnregisterReceiveCodec(const WebRtc_Word16 payload_type);
protected:
void UnregisterSendCodec();
WebRtc_Word32 UnregisterReceiveCodecSafe(const WebRtc_Word16 id);
ACMGenericCodec* CreateCodec(const CodecInst& codec);
WebRtc_Word16 DecoderParamByPlType(const WebRtc_UWord8 payload_type,
WebRtcACMCodecParams& codec_params) const;
WebRtc_Word16 DecoderListIDByPlName(
const char* name, const WebRtc_UWord16 frequency = 0) const;
WebRtc_Word32 InitializeReceiverSafe();
bool HaveValidEncoder(const char* caller_name) const;
WebRtc_Word32 RegisterRecCodecMSSafe(const CodecInst& receive_codec,
WebRtc_Word16 codec_id,
WebRtc_Word16 mirror_id,
ACMNetEQ::JB jitter_buffer);
private:
// Change required states after starting to receive the codec corresponding
// to |index|.
int UpdateUponReceivingCodec(int index);
// Remove all slaves and initialize a stereo slave with required codecs
// from the master.
int InitStereoSlave();
// Returns true if the codec's |index| is registered with the master and
// is a stereo codec, RED or CN.
bool IsCodecForSlave(int index) const;
// Returns true if the |codec| is RED.
bool IsCodecRED(const CodecInst* codec) const;
// ...or if its |index| is RED.
bool IsCodecRED(int index) const;
// Returns true if the |codec| is CN.
bool IsCodecCN(int index) const;
// ...or if its |index| is CN.
bool IsCodecCN(const CodecInst* codec) const;
AudioPacketizationCallback* _packetizationCallback;
WebRtc_Word32 _id;
WebRtc_UWord32 _lastTimestamp;
WebRtc_UWord32 _lastInTimestamp;
CodecInst _sendCodecInst;
uint8_t _cng_nb_pltype;
uint8_t _cng_wb_pltype;
uint8_t _cng_swb_pltype;
uint8_t _cng_fb_pltype;
uint8_t _red_pltype;
bool _vadEnabled;
bool _dtxEnabled;
ACMVADMode _vadMode;
ACMGenericCodec* _codecs[ACMCodecDB::kMaxNumCodecs];
ACMGenericCodec* _slaveCodecs[ACMCodecDB::kMaxNumCodecs];
WebRtc_Word16 _mirrorCodecIdx[ACMCodecDB::kMaxNumCodecs];
bool _stereoReceive[ACMCodecDB::kMaxNumCodecs];
bool _stereoReceiveRegistered;
bool _stereoSend;
int _prev_received_channel;
int _expected_channels;
WebRtc_Word32 _currentSendCodecIdx;
int _current_receive_codec_idx;
bool _sendCodecRegistered;
ACMResampler _inputResampler;
ACMResampler _outputResampler;
ACMNetEQ _netEq;
CriticalSectionWrapper* _acmCritSect;
ACMVADCallback* _vadCallback;
WebRtc_UWord8 _lastRecvAudioCodecPlType;
// RED/FEC.
bool _isFirstRED;
bool _fecEnabled;
WebRtc_UWord8* _redBuffer;
RTPFragmentationHeader* _fragmentation;
WebRtc_UWord32 _lastFECTimestamp;
// If no RED is registered as receive codec this
// will have an invalid value.
WebRtc_UWord8 _receiveREDPayloadType;
// This is to keep track of CN instances where we can send DTMFs.
WebRtc_UWord8 _previousPayloadType;
// This keeps track of payload types associated with _codecs[].
// We define it as signed variable and initialize with -1 to indicate
// unused elements.
WebRtc_Word16 _registeredPlTypes[ACMCodecDB::kMaxNumCodecs];
// Used when payloads are pushed into ACM without any RTP info
// One example is when pre-encoded bit-stream is pushed from
// a file.
WebRtcRTPHeader* _dummyRTPHeader;
WebRtc_UWord16 _recvPlFrameSizeSmpls;
bool _receiverInitialized;
ACMDTMFDetection* _dtmfDetector;
AudioCodingFeedback* _dtmfCallback;
WebRtc_Word16 _lastDetectedTone;
CriticalSectionWrapper* _callbackCritSect;
AudioFrame _audioFrame;
#ifdef ACM_QA_TEST
FILE* _outgoingPL;
FILE* _incomingPL;
#endif
};
} // namespace webrtc
#endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_SOURCE_AUDIO_CODING_MODULE_IMPL_H_