Files
platform-external-webrtc/webrtc/modules/audio_coding/main/source/acm_speex.cc
tina.legrand@webrtc.org f7fa6276e2 Reformating files in audio coding module.
This CL format the ramaining files on the audio coding module. No other changes are done, except for fixing a few long lines and TODOs without owner.

BUG=issue1024

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

git-svn-id: http://webrtc.googlecode.com/svn/trunk@3042 4adac7df-926f-26a2-2b94-8c16560cd09d
2012-11-05 09:35:51 +00:00

467 lines
12 KiB
C++

/*
* 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. Modify this file or
// your codec API to match the function calls and names of used Speex API file.
#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