/*
 *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include <assert.h>
#include <string.h>

#include "acm_codec_database.h"
#include "acm_common_defs.h"
#include "acm_generic_codec.h"
#include "acm_neteq.h"
#include "trace.h"
#include "webrtc_vad.h"
#include "webrtc_cng.h"

namespace webrtc
{

// Enum for CNG
enum
{
    kMaxPLCParamsCNG = WEBRTC_CNG_MAX_LPC_ORDER,
    kNewCNGNumPLCParams = 8
};

#define ACM_SID_INTERVAL_MSEC 100

// We set some of the variables to invalid values as a check point
// if a proper initialization has happened. Another approach is
// to initialize to a default codec that we are sure is always included.
ACMGenericCodec::ACMGenericCodec()
    : _inAudioIxWrite(0),
      _inAudioIxRead(0),
      _inTimestampIxWrite(0),
      _inAudio(NULL),
      _inTimestamp(NULL),
      _frameLenSmpl(-1),  // invalid value
      _noChannels(1),
      _codecID(-1),  // invalid value
      _noMissedSamples(0),
      _encoderExist(false),
      _decoderExist(false),
      _encoderInitialized(false),
      _decoderInitialized(false),
      _registeredInNetEq(false),
      _hasInternalDTX(false),
      _ptrVADInst(NULL),
      _vadEnabled(false),
      _vadMode(VADNormal),
      _dtxEnabled(false),
      _ptrDTXInst(NULL),
      _numLPCParams(kNewCNGNumPLCParams),
      _sentCNPrevious(false),
      _isMaster(true),
      _netEqDecodeLock(NULL),
      _codecWrapperLock(*RWLockWrapper::CreateRWLock()),
      _lastEncodedTimestamp(0),
      _lastTimestamp(0xD87F3F9F),
      _isAudioBuffFresh(true),
      _uniqueID(0) {
  // Initialize VAD vector.
  for (int i = 0; i < MAX_FRAME_SIZE_10MSEC; i++) {
    _vadLabel[i] = 0;
  }

  // Nullify memory for encoder and decoder, and set payload type to an
  // invalid value.
  memset(&_encoderParams, 0, sizeof(WebRtcACMCodecParams));
  _encoderParams.codecInstant.pltype = -1;
  memset(&_decoderParams, 0, sizeof(WebRtcACMCodecParams));
  _decoderParams.codecInstant.pltype = -1;
}

ACMGenericCodec::~ACMGenericCodec()
{
    // Check all the members which are pointers and
    // if they are not NULL delete/free them.

    if(_ptrVADInst != NULL)
    {
        WebRtcVad_Free(_ptrVADInst);
        _ptrVADInst = NULL;
    }

    if (_inAudio != NULL)
    {
        delete [] _inAudio;
        _inAudio = NULL;
    }

    if (_inTimestamp != NULL)
    {
        delete [] _inTimestamp;
        _inTimestamp = NULL;
    }
    if(_ptrDTXInst != NULL)
    {
        WebRtcCng_FreeEnc(_ptrDTXInst);
        _ptrDTXInst = NULL;
    }
    delete &_codecWrapperLock;
}

WebRtc_Word32
ACMGenericCodec::Add10MsData(
    const WebRtc_UWord32 timestamp,
    const WebRtc_Word16* data,
    const WebRtc_UWord16 lengthSmpl,
    const WebRtc_UWord8  audioChannel)
{
    WriteLockScoped wl(_codecWrapperLock);
    return Add10MsDataSafe(timestamp, data, lengthSmpl, audioChannel);
}

WebRtc_Word32
ACMGenericCodec::Add10MsDataSafe(
    const WebRtc_UWord32 timestamp,
    const WebRtc_Word16* data,
    const WebRtc_UWord16 lengthSmpl,
    const WebRtc_UWord8  audioChannel)
{
    // The codec expects to get data in correct sampling rate.
    // get the sampling frequency of the codec
    WebRtc_UWord16 plFreqHz;

    if(EncoderSampFreq(plFreqHz) < 0)
    {
        // _codecID is not correct, perhaps the codec is not initialized yet.
        return -1;
    }

    // Sanity check, if the length of the input corresponds to 10 ms.
    if((plFreqHz / 100) != lengthSmpl)
    {
        // This is not 10 ms of audio, given the sampling frequency of the
        // codec
        return -1;
    }
    if(_lastTimestamp == timestamp)
    {
        // Same timestamp as the last time, overwrite.
        if((_inAudioIxWrite >= lengthSmpl) && (_inTimestampIxWrite > 0))
        {
            _inAudioIxWrite -= lengthSmpl;
            _inTimestampIxWrite--;
            WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceAudioCoding, _uniqueID,
                "Adding 10ms with previous timestamp, \
overwriting the previous 10ms");
        }
        else
        {
            WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceAudioCoding, _uniqueID,
                "Adding 10ms with previous timestamp, this will sound bad");
        }
    }

    _lastTimestamp = timestamp;

    if ((_inAudioIxWrite + lengthSmpl*audioChannel) > AUDIO_BUFFER_SIZE_W16)
    {
        // Get the number of samples to be overwritten
        WebRtc_Word16 missedSamples = _inAudioIxWrite + lengthSmpl*audioChannel -
            AUDIO_BUFFER_SIZE_W16;

        // Move the data (overwite the old data)
        memmove(_inAudio, _inAudio + missedSamples,
            (AUDIO_BUFFER_SIZE_W16 - lengthSmpl*audioChannel)*sizeof(WebRtc_Word16));
        // Copy the new data
        memcpy(_inAudio + (AUDIO_BUFFER_SIZE_W16 - lengthSmpl*audioChannel), data,
            lengthSmpl*audioChannel * sizeof(WebRtc_Word16));

        // Get the number of 10 ms blocks which are overwritten
        WebRtc_Word16 missed10MsecBlocks =
            (WebRtc_Word16)((missedSamples/audioChannel * 100) / plFreqHz);

        // Move the timestamps
        memmove(_inTimestamp, _inTimestamp + missed10MsecBlocks,
            (_inTimestampIxWrite - missed10MsecBlocks) * sizeof(WebRtc_UWord32));
        _inTimestampIxWrite -= missed10MsecBlocks;
        _inTimestamp[_inTimestampIxWrite] = timestamp;
        _inTimestampIxWrite++;

        // Buffer is full
        _inAudioIxWrite = AUDIO_BUFFER_SIZE_W16;
        IncreaseNoMissedSamples(missedSamples);
        _isAudioBuffFresh = false;
        return -missedSamples;
    }
    memcpy(_inAudio + _inAudioIxWrite, data, lengthSmpl*audioChannel * sizeof(WebRtc_Word16));
    _inAudioIxWrite += lengthSmpl*audioChannel;

    assert(_inTimestampIxWrite < TIMESTAMP_BUFFER_SIZE_W32);
    assert(_inTimestampIxWrite >= 0);

    _inTimestamp[_inTimestampIxWrite] = timestamp;
    _inTimestampIxWrite++;
    _isAudioBuffFresh = false;
    return 0;
}

WebRtc_Word16
ACMGenericCodec::Encode(
    WebRtc_UWord8*         bitStream,
    WebRtc_Word16*         bitStreamLenByte,
    WebRtc_UWord32*        timeStamp,
    WebRtcACMEncodingType* encodingType)
{
    WriteLockScoped lockCodec(_codecWrapperLock);
    ReadLockScoped lockNetEq(*_netEqDecodeLock);
    return EncodeSafe(bitStream, bitStreamLenByte,
        timeStamp, encodingType);
}


WebRtc_Word16
ACMGenericCodec::EncodeSafe(
    WebRtc_UWord8*         bitStream,
    WebRtc_Word16*         bitStreamLenByte,
    WebRtc_UWord32*        timeStamp,
    WebRtcACMEncodingType* encodingType)
{
    // Do we have enough data to encode?
    // we wait until we have a full frame to encode.
    if(_inAudioIxWrite < _frameLenSmpl*_noChannels)
    {
        // There is not enough audio
        *timeStamp = 0;
        *bitStreamLenByte = 0;
        // Doesn't really matter what this parameter set to
        *encodingType = kNoEncoding;
        return 0;
    }

    // Not all codecs accept the whole frame to be pushed into
    // encoder at once.
    const WebRtc_Word16 myBasicCodingBlockSmpl =
        ACMCodecDB::BasicCodingBlock(_codecID);
    if((myBasicCodingBlockSmpl < 0) ||
        (!_encoderInitialized) ||
        (!_encoderExist))
    {
        // This should not happen
        *timeStamp = 0;
        *bitStreamLenByte = 0;
        *encodingType = kNoEncoding;
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
            "EncodeSafe: error, basic coding sample block is negative");
        return -1;
    }

    // This makes the internal encoder read from the begining of the buffer
    _inAudioIxRead = 0;
    *timeStamp = _inTimestamp[0];

    // Process the audio through VAD the function doesn't set _vadLabels.
    // If VAD is disabled all labels are set to ONE (active)
    WebRtc_Word16 status = 0;
    WebRtc_Word16 dtxProcessedSamples = 0;

    status = ProcessFrameVADDTX(bitStream, bitStreamLenByte,
        &dtxProcessedSamples);

    if(status < 0)
    {
        *timeStamp = 0;
        *bitStreamLenByte = 0;
        *encodingType = kNoEncoding;
    }
    else
    {
        if(dtxProcessedSamples > 0)
        {
            // Dtx have processed some samples may or may not a bit-stream
            // is generated we should not do any encoding (normally there
            // will be not enough data)

            // Setting the following makes that the move of audio data
            // and timestamps happen correctly
            _inAudioIxRead = dtxProcessedSamples;
            // This will let the owner of ACMGenericCodec to know that the
            // generated bit-stream is DTX to use correct payload type
            WebRtc_UWord16 sampFreqHz;
            EncoderSampFreq(sampFreqHz);
            if (sampFreqHz == 8000) {
                *encodingType = kPassiveDTXNB;
            } else if (sampFreqHz == 16000) {
                *encodingType = kPassiveDTXWB;
            } else if (sampFreqHz == 32000) {
                *encodingType = kPassiveDTXSWB;
            } else {
                status = -1;
                WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
                    "EncodeSafe: Wrong sampling frequency for DTX.");
            }

            // Transport empty frame if we have an empty bitstream
            if ((*bitStreamLenByte == 0)
                && (_sentCNPrevious || ((_inAudioIxWrite - _inAudioIxRead) <= 0))
                )
            {
                // Makes sure we transmit an empty frame
                *bitStreamLenByte = 1;
                *encodingType = kNoEncoding;
            }
            _sentCNPrevious = true;
        }
        else
        {
            _sentCNPrevious = false;
            // This will let the caller of the method to know if the frame is
            // Active or non-Active The caller of the method knows that the
            // stream is encoded by codec and can use the info for callbacks,
            // if any registered.
            if(myBasicCodingBlockSmpl == 0)
            {
                // This codec can handle all allowed frame sizes as basic
                // coding block
                status = InternalEncode(bitStream, bitStreamLenByte);

                if(status < 0)
                {
                    // TODO:
                    // Maybe reseting the encoder to be fresh for the next
                    // frame
                    WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
                        "EncodeSafe: error in internalEncode");
                    *bitStreamLenByte = 0;
                    *encodingType = kNoEncoding;
                }
            }
            else
            {
                // A basic-coding-block for this codec is defined so we loop
                // over the audio with the steps of the basic-coding-block.
                // It is not necessary that in each itteration
                WebRtc_Word16 tmpBitStreamLenByte;

                // Reset the variables which will be increamented in the loop
                *bitStreamLenByte = 0;
                bool done = false;
                while(!done)
                {
                    status = InternalEncode(&bitStream[*bitStreamLenByte],
                        &tmpBitStreamLenByte);
                    *bitStreamLenByte += tmpBitStreamLenByte;

                    // Guard Against errors and too large payloads
                    if((status < 0) ||
                        (*bitStreamLenByte > MAX_PAYLOAD_SIZE_BYTE))
                    {
                        // Error has happened if we are in the middle of a full
                        // frame we have to exit. Before exiting, whatever bits
                        // are in the buffer are probably corruptred. Anyways
                        // we ignore them.
                        *bitStreamLenByte = 0;
                        *encodingType = kNoEncoding;
                        // We might have come here because of the second
                        // condition.
                        status = -1;
                         WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding,
                            _uniqueID, "EncodeSafe: error in InternalEncode");
                        // break from the loop
                        break;
                    }

                    done = _inAudioIxRead >= _frameLenSmpl;
                }
            }
            if(status >= 0)
            {
                *encodingType = (_vadLabel[0] == 1)?
                kActiveNormalEncoded:kPassiveNormalEncoded;
                // Transport empty frame if we have an empty bitsteram
                if ((*bitStreamLenByte == 0) && ((_inAudioIxWrite - _inAudioIxRead) <= 0))
                {
                    // Makes sure we transmit an empty frame
                    *bitStreamLenByte = 1;
                    *encodingType = kNoEncoding;
                }
            }
        }
    }

    // Move the timestampe buffer according to the number of 10 ms blocks
    // which are read.
    WebRtc_UWord16 sampFreqHz;
    EncoderSampFreq(sampFreqHz);

    WebRtc_Word16 num10MsecBlocks =
            (WebRtc_Word16)((_inAudioIxRead/_noChannels * 100) / sampFreqHz);
    if(_inTimestampIxWrite > num10MsecBlocks)
    {
        memmove(_inTimestamp, _inTimestamp + num10MsecBlocks,
            (_inTimestampIxWrite - num10MsecBlocks) * sizeof(WebRtc_Word32));
    }
    _inTimestampIxWrite -= num10MsecBlocks;

    // We have to move the audio that is not encoded to the beginning
    // of the buffer and accordingly adjust the read and write indices.
    if(_inAudioIxRead < _inAudioIxWrite)
    {
        memmove(_inAudio, &_inAudio[_inAudioIxRead],
            (_inAudioIxWrite - _inAudioIxRead)*sizeof(WebRtc_Word16));
    }

    _inAudioIxWrite -= _inAudioIxRead;

    _inAudioIxRead = 0;
    _lastEncodedTimestamp = *timeStamp;
    return (status < 0) ? (-1):(*bitStreamLenByte);
}

WebRtc_Word16
ACMGenericCodec::Decode(
    WebRtc_UWord8* bitStream,
    WebRtc_Word16  bitStreamLenByte,
    WebRtc_Word16* audio,
    WebRtc_Word16* audioSamples,
    WebRtc_Word8*  speechType)
{
    WriteLockScoped wl(_codecWrapperLock);
    return DecodeSafe(bitStream, bitStreamLenByte, audio,
        audioSamples, speechType);
}

bool
ACMGenericCodec::EncoderInitialized()
{
    ReadLockScoped rl(_codecWrapperLock);
    return _encoderInitialized;
}

bool
ACMGenericCodec::DecoderInitialized()
{
    ReadLockScoped rl(_codecWrapperLock);
    return _decoderInitialized;
}


WebRtc_Word32
ACMGenericCodec::RegisterInNetEq(
    ACMNetEQ*   netEq,
    const CodecInst& codecInst)
{
    WebRtcNetEQ_CodecDef codecDef;
    WriteLockScoped wl(_codecWrapperLock);

    if(CodecDef(codecDef, codecInst) < 0)
    {
        // Failed to register
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
            "RegisterInNetEq: error, failed to register");
        _registeredInNetEq = false;
        return -1;
    }
    else
    {
        if(netEq->AddCodec(&codecDef, _isMaster) < 0)
        {
            WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
                "RegisterInNetEq: error, failed to add codec");
            _registeredInNetEq = false;
            return -1;
        }
        // Registered
        _registeredInNetEq = true;
        return 0;
    }
}

WebRtc_Word16
ACMGenericCodec::EncoderParams(
    WebRtcACMCodecParams* encParams)
{
    ReadLockScoped rl(_codecWrapperLock);
    return EncoderParamsSafe(encParams);
}

WebRtc_Word16
ACMGenericCodec::EncoderParamsSafe(
    WebRtcACMCodecParams* encParams)
{
    // Codec parameters are valid only if the encoder is initialized
    if(_encoderInitialized)
    {
        WebRtc_Word32 currentRate;
        memcpy(encParams, &_encoderParams, sizeof(WebRtcACMCodecParams));
        currentRate = encParams->codecInstant.rate;
        CurrentRate(currentRate);
        encParams->codecInstant.rate = currentRate;
        return 0;
    }
    else
    {
        encParams->codecInstant.plname[0] = '\0';
        encParams->codecInstant.pltype    = -1;
        encParams->codecInstant.pacsize   = 0;
        encParams->codecInstant.rate      = 0;
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
            "EncoderParamsSafe: error, encoder not initialized");
        return -1;
    }
}

bool
ACMGenericCodec::DecoderParams(
    WebRtcACMCodecParams* decParams,
    const WebRtc_UWord8   payloadType)
{
    ReadLockScoped rl(_codecWrapperLock);
    return DecoderParamsSafe(decParams, payloadType);
}

bool
ACMGenericCodec::DecoderParamsSafe(
    WebRtcACMCodecParams* decParams,
    const WebRtc_UWord8   payloadType)
{
    // Decoder parameters are valid only if decoder is initialized
    if(_decoderInitialized)
    {
        if(payloadType == _decoderParams.codecInstant.pltype)
        {
            memcpy(decParams, &_decoderParams, sizeof(WebRtcACMCodecParams));
            return true;
        }
    }

    decParams->codecInstant.plname[0] = '\0';
    decParams->codecInstant.pltype    = -1;
    decParams->codecInstant.pacsize   = 0;
    decParams->codecInstant.rate      = 0;
    return false;
}

WebRtc_Word16
ACMGenericCodec::ResetEncoder()
{
    WriteLockScoped lockCodec(_codecWrapperLock);
    ReadLockScoped lockNetEq(*_netEqDecodeLock);
    return ResetEncoderSafe();
}

WebRtc_Word16
ACMGenericCodec::ResetEncoderSafe()
{
    if(!_encoderExist || !_encoderInitialized)
    {
        // We don't reset if doesn't exists or not initialized yet
        return 0;
    }

    _inAudioIxWrite     = 0;
    _inAudioIxRead      = 0;
    _inTimestampIxWrite = 0;
    _noMissedSamples    = 0;
    _isAudioBuffFresh   = true;
    memset(_inAudio, 0, AUDIO_BUFFER_SIZE_W16 * sizeof(WebRtc_Word16));
    memset(_inTimestamp, 0, TIMESTAMP_BUFFER_SIZE_W32 * sizeof(WebRtc_Word32));

    // Store DTX/VAD params
    bool enableVAD = _vadEnabled;
    bool enableDTX = _dtxEnabled;
    ACMVADMode mode = _vadMode;

    // Reset the encoder
    if(InternalResetEncoder() < 0)
    {
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
            "ResetEncoderSafe: error in reset encoder");
        return -1;
    }

    // Disable DTX & VAD this deletes the states
    // we like to have fresh start
    DisableDTX();
    DisableVAD();

    // Set DTX/VAD
    return SetVADSafe(enableDTX, enableVAD, mode);
}

WebRtc_Word16
ACMGenericCodec::InternalResetEncoder()
{
    // For most of the codecs it is sufficient to
    // call their internal initialization.
    // There are some exceptions.
    // ----
    // For iSAC we don't want to lose BWE history,
    // so for iSAC we have to over-write this function.
    // ----
    return InternalInitEncoder(&_encoderParams);
}

WebRtc_Word16
ACMGenericCodec::InitEncoder(
    WebRtcACMCodecParams* codecParams,
    bool                  forceInitialization)
{
    WriteLockScoped lockCodec(_codecWrapperLock);
    ReadLockScoped lockNetEq(*_netEqDecodeLock);
    return InitEncoderSafe(codecParams, forceInitialization);
}

WebRtc_Word16
ACMGenericCodec::InitEncoderSafe(
    WebRtcACMCodecParams* codecParams,
    bool                  forceInitialization)
{
    // Check if we got a valid set of parameters
    int mirrorID;
    int codecNumber =
        ACMCodecDB::CodecNumber(&(codecParams->codecInstant), &mirrorID);

    if(codecNumber < 0)
    {
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
            "InitEncoderSafe: error, codec number negative");
        return -1;
    }
    // Check if the parameters are for this codec
    if((_codecID >= 0) && (_codecID != codecNumber) && (_codecID != mirrorID))
    {
        // The current codec is not the same as the one given by codecParams
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
            "InitEncoderSafe: current codec is not the same as the one given by codecParams");
        return -1;
    }

    if(!CanChangeEncodingParam(codecParams->codecInstant))
    {
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
            "InitEncoderSafe: cannot change encoding parameters");
        return -1;
    }

    if(_encoderInitialized && !forceInitialization)
    {
        // The encoder is already initialized
        return 0;
    }
    WebRtc_Word16 status;
    if(!_encoderExist)
    {
        _encoderInitialized = false;
        status = CreateEncoder();
        if(status < 0)
        {
            WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
            "InitEncoderSafe: cannot create encoder");
            return -1;
        }
        else
        {
            _encoderExist = true;
        }
    }
    _frameLenSmpl = (codecParams->codecInstant).pacsize;
    status = InternalInitEncoder(codecParams);
    if(status < 0)
    {
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
            "InitEncoderSafe: error in init encoder");
        _encoderInitialized = false;
        return -1;
    }
    else
    {
        memcpy(&_encoderParams, codecParams, sizeof(WebRtcACMCodecParams));
        _encoderInitialized = true;
        if(_inAudio == NULL)
        {
            _inAudio = new WebRtc_Word16[AUDIO_BUFFER_SIZE_W16];
            if(_inAudio == NULL)
            {
                return -1;
            }
            memset(_inAudio, 0, AUDIO_BUFFER_SIZE_W16 * sizeof(WebRtc_Word16));
        }
        if(_inTimestamp == NULL)
        {
            _inTimestamp = new WebRtc_UWord32[TIMESTAMP_BUFFER_SIZE_W32];
            if(_inTimestamp == NULL)
            {
                return -1;
            }
            memset(_inTimestamp, 0, sizeof(WebRtc_UWord32) *
                TIMESTAMP_BUFFER_SIZE_W32);
        }
        _isAudioBuffFresh = true;
    }
    status = SetVADSafe(codecParams->enableDTX, codecParams->enableVAD,
        codecParams->vadMode);

    _noChannels = codecParams->codecInstant.channels;

    return status;
}

bool
ACMGenericCodec::CanChangeEncodingParam(
    CodecInst& /*codecInst*/)
{
    return true;
}

WebRtc_Word16
ACMGenericCodec::InitDecoder(
    WebRtcACMCodecParams* codecParams,
    bool                  forceInitialization)
{
    WriteLockScoped lockCodc(_codecWrapperLock);
    WriteLockScoped lockNetEq(*_netEqDecodeLock);
    return InitDecoderSafe(codecParams, forceInitialization);
}

WebRtc_Word16
ACMGenericCodec::InitDecoderSafe(
    WebRtcACMCodecParams* codecParams,
    bool                  forceInitialization)
{
    int mirrorID;
    // Check if we got a valid set of parameters
    int codecNumber =
        ACMCodecDB::ReceiverCodecNumber(&codecParams->codecInstant, &mirrorID);

    if(codecNumber < 0)
    {
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
                    "InitDecoderSafe: error, invalid codec number");
        return -1;
    }
    // Check if the parameters are for this codec
    if((_codecID >= 0) && (_codecID != codecNumber) && (_codecID != mirrorID))
    {
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
                    "InitDecoderSafe: current codec is not the same as the one given "
                    "by codecParams");
        // The current codec is not the same as the one given by codecParams
        return -1;
    }


    if(_decoderInitialized && !forceInitialization)
    {
        // The encoder is already initialized
        return 0;
    }

    WebRtc_Word16 status;
    if(!_decoderExist)
    {
        _decoderInitialized = false;
        status = CreateDecoder();
        if(status < 0)
        {
            WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
                    "InitDecoderSafe: cannot create decoder");
            return -1;
        }
        else
        {
            _decoderExist = true;
        }
    }

    status = InternalInitDecoder(codecParams);
    if(status < 0)
    {
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
                "InitDecoderSafe: cannot init decoder");
        _decoderInitialized = false;
        return -1;
    }
    else
    {
        // Store the parameters
        SaveDecoderParamSafe(codecParams);
        _decoderInitialized = true;
    }
    return 0;
}

WebRtc_Word16
ACMGenericCodec::ResetDecoder(WebRtc_Word16 payloadType)
{
    WriteLockScoped lockCodec(_codecWrapperLock);
    WriteLockScoped lockNetEq(*_netEqDecodeLock);
    return ResetDecoderSafe(payloadType);
}

WebRtc_Word16
ACMGenericCodec::ResetDecoderSafe(WebRtc_Word16 payloadType)
{
    WebRtcACMCodecParams decoderParams;
    if(!_decoderExist || !_decoderInitialized)
    {
        return 0;
    }
    // Initialization of the decoder should work for all
    // the codec. If there is a codec that has to keep
    // some states then we need to define a virtual and
    // overwrite in that codec
    DecoderParamsSafe(&decoderParams, (WebRtc_UWord8) payloadType);
    return InternalInitDecoder(&decoderParams);
}

void
ACMGenericCodec::ResetNoMissedSamples()
{
    WriteLockScoped cs(_codecWrapperLock);
    _noMissedSamples = 0;
}

void
ACMGenericCodec::IncreaseNoMissedSamples(
    const WebRtc_Word16 noSamples)
{
    _noMissedSamples += noSamples;
}

// Get the number of missed samples, this can be public
WebRtc_UWord32
ACMGenericCodec::NoMissedSamples() const
{
    ReadLockScoped cs(_codecWrapperLock);
    return _noMissedSamples;
}
void
ACMGenericCodec::DestructEncoder()
{
    WriteLockScoped wl(_codecWrapperLock);

    // Disable VAD and delete the instance
    if(_ptrVADInst != NULL)
    {
        WebRtcVad_Free(_ptrVADInst);
        _ptrVADInst = NULL;
    }
    _vadEnabled = false;
    _vadMode = VADNormal;

    //Disable DTX and delete the instance
    _dtxEnabled = false;
    if(_ptrDTXInst != NULL)
    {
        WebRtcCng_FreeEnc(_ptrDTXInst);
        _ptrDTXInst = NULL;
    }
    _numLPCParams = kNewCNGNumPLCParams;

    DestructEncoderSafe();
}

void
ACMGenericCodec::DestructDecoder()
{
    WriteLockScoped wl(_codecWrapperLock);
    _decoderParams.codecInstant.pltype = -1;
    DestructDecoderSafe();
}

WebRtc_Word16
ACMGenericCodec::SetBitRate(
    const WebRtc_Word32 bitRateBPS)
{
    WriteLockScoped wl(_codecWrapperLock);
    return SetBitRateSafe(bitRateBPS);
}

WebRtc_Word16
ACMGenericCodec::SetBitRateSafe(
    const WebRtc_Word32 bitRateBPS)
{
    // If the codec can change the bit-rate this function
    // should be overwritten, otherewise the only acceptable
    // value is the one that is in database.
    CodecInst codecParams;
    if(ACMCodecDB::Codec(_codecID, &codecParams) < 0)
    {
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
            "SetBitRateSafe: error in ACMCodecDB::Codec");
        return -1;
    }
    if(codecParams.rate != bitRateBPS)
    {
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
            "SetBitRateSafe: rate value is not acceptable");
        return -1;
    }
    else
    {
        return 0;
    }
}

WebRtc_Word32
ACMGenericCodec::GetEstimatedBandwidth()
{
    WriteLockScoped wl(_codecWrapperLock);
    return GetEstimatedBandwidthSafe();
}

WebRtc_Word32
ACMGenericCodec::GetEstimatedBandwidthSafe()
{
    // All codecs but iSAC will return -1
    return -1;
}

WebRtc_Word32
ACMGenericCodec::SetEstimatedBandwidth(
    WebRtc_Word32 estimatedBandwidth)
{
    WriteLockScoped wl(_codecWrapperLock);
    return SetEstimatedBandwidthSafe(estimatedBandwidth);
}

WebRtc_Word32
ACMGenericCodec::SetEstimatedBandwidthSafe(
    WebRtc_Word32 /*estimatedBandwidth*/)
{
    // All codecs but iSAC will return -1
    return -1;
}

WebRtc_Word32
ACMGenericCodec::GetRedPayload(
    WebRtc_UWord8* redPayload,
    WebRtc_Word16* payloadBytes)
{
    WriteLockScoped wl(_codecWrapperLock);
    return GetRedPayloadSafe(redPayload, payloadBytes);
}

WebRtc_Word32
ACMGenericCodec::GetRedPayloadSafe(
    WebRtc_UWord8* /* redPayload   */,
    WebRtc_Word16* /* payloadBytes */)
{
    return -1; // Do nothing by default
}

WebRtc_Word16
ACMGenericCodec::CreateEncoder()
{
    WebRtc_Word16 status = 0;
    if(!_encoderExist)
    {
        status = InternalCreateEncoder();
        // We just created the codec and obviously it is not initialized
        _encoderInitialized = false;
    }

    if(status < 0)
    {
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
            "CreateEncoder: error in internal create encoder");
        _encoderExist = false;
    }
    else
    {
        _encoderExist = true;
    }
    return status;
}

WebRtc_Word16
ACMGenericCodec::CreateDecoder()
{
    WebRtc_Word16 status = 0;
    if(!_decoderExist)
    {
        status = InternalCreateDecoder();
        // Decoder just created and obviously it is not initialized
        _decoderInitialized = false;
    }

    if(status < 0)
    {
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
            "CreateDecoder: error in internal create decoder");
        _decoderExist = false;
    }
    else
    {
        _decoderExist = true;
    }
    return status;
}


void ACMGenericCodec::DestructEncoderInst(void* ptrInst)
{
    if(ptrInst != NULL)
    {
        WriteLockScoped lockCodec(_codecWrapperLock);
        ReadLockScoped lockNetEq(*_netEqDecodeLock);
        InternalDestructEncoderInst(ptrInst);
    }
}


WebRtc_Word16
ACMGenericCodec::AudioBuffer(
    WebRtcACMAudioBuff& audioBuff)
{
    ReadLockScoped cs(_codecWrapperLock);
    memcpy(audioBuff.inAudio, _inAudio,
        AUDIO_BUFFER_SIZE_W16 * sizeof(WebRtc_Word16));
    audioBuff.inAudioIxRead = _inAudioIxRead;
    audioBuff.inAudioIxWrite = _inAudioIxWrite;
    memcpy(audioBuff.inTimestamp, _inTimestamp,
        TIMESTAMP_BUFFER_SIZE_W32*sizeof(WebRtc_UWord32));
    audioBuff.inTimestampIxWrite = _inTimestampIxWrite;
    audioBuff.lastTimestamp = _lastTimestamp;
    return 0;
}


WebRtc_Word16
ACMGenericCodec::SetAudioBuffer(
    WebRtcACMAudioBuff& audioBuff)
{
    WriteLockScoped cs(_codecWrapperLock);
    memcpy(_inAudio, audioBuff.inAudio,
        AUDIO_BUFFER_SIZE_W16 * sizeof(WebRtc_Word16));
    _inAudioIxRead = audioBuff.inAudioIxRead;
    _inAudioIxWrite = audioBuff.inAudioIxWrite;
    memcpy(_inTimestamp, audioBuff.inTimestamp,
        TIMESTAMP_BUFFER_SIZE_W32*sizeof(WebRtc_UWord32));
    _inTimestampIxWrite = audioBuff.inTimestampIxWrite;
    _lastTimestamp = audioBuff.lastTimestamp;
    _isAudioBuffFresh = false;
    return 0;
}


WebRtc_UWord32
ACMGenericCodec::LastEncodedTimestamp() const
{
    ReadLockScoped cs(_codecWrapperLock);
    return _lastEncodedTimestamp;
}


WebRtc_UWord32
ACMGenericCodec::EarliestTimestamp() const
{
    ReadLockScoped cs(_codecWrapperLock);
    return _inTimestamp[0];
}


WebRtc_Word16
ACMGenericCodec::SetVAD(
    const bool       enableDTX,
    const bool       enableVAD,
    const ACMVADMode mode)
{
    WriteLockScoped cs(_codecWrapperLock);
    return SetVADSafe(enableDTX, enableVAD, mode);
}


WebRtc_Word16
ACMGenericCodec::SetVADSafe(
    const bool       enableDTX,
    const bool       enableVAD,
    const ACMVADMode mode)
{
    if(enableDTX)
    {
        // Make G729 AnnexB a special case
        if (!STR_CASE_CMP(_encoderParams.codecInstant.plname, "G729") && !_hasInternalDTX)
        {
            if (ACMGenericCodec::EnableDTX() < 0)
            {
            WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
                "SetVADSafe: error in enable DTX");
                return -1;
            }
        }
        else
        {
            if(EnableDTX() < 0)
            {
                WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
                    "SetVADSafe: error in enable DTX");
                return -1;
            }
        }

        if(_hasInternalDTX)
        {
            // Codec has internal DTX, practically we don't need WebRtc VAD,
            // however, we let the user to turn it on if they need call-backs
            // on silence. Store VAD mode for future even if VAD is off.
            _vadMode = mode;
            return (enableVAD)? EnableVAD(mode):DisableVAD();
        }
        else
        {
            // Codec does not have internal DTX so enabling DTX requires an
            // active VAD. 'enableDTX == true' overwrites VAD status.
            if(EnableVAD(mode) < 0)
            {
                // If we cannot create VAD we have to disable DTX
                if(!_vadEnabled)
                {
                    DisableDTX();
                }
                WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
                    "SetVADSafe: error in enable VAD");
                return -1;
            }

            // Return '1', to let the caller know VAD was turned on, even if the
            // function was called with VAD='false'
            if (enableVAD == false) {
                return 1;
            } else {
                return 0;
            }
        }
    }
    else
    {
        // Make G729 AnnexB a special case
        if (!STR_CASE_CMP(_encoderParams.codecInstant.plname, "G729") && !_hasInternalDTX)
        {
            ACMGenericCodec::DisableDTX();
        }
        else
        {
            DisableDTX();
        }
        return (enableVAD)? EnableVAD(mode):DisableVAD();
    }
}

WebRtc_Word16
ACMGenericCodec::EnableDTX()
{
    if(_hasInternalDTX)
    {
        // We should not be here if we have internal DTX
        // this function should be overwritten by the derived
        // class in this case
        return -1;
    }
    if(!_dtxEnabled)
    {
        if(WebRtcCng_CreateEnc(&_ptrDTXInst) < 0)
        {
            _ptrDTXInst = NULL;
            return -1;
        }
        WebRtc_UWord16 freqHz;
        EncoderSampFreq(freqHz);
        if(WebRtcCng_InitEnc(_ptrDTXInst, (WebRtc_Word16)freqHz,
            ACM_SID_INTERVAL_MSEC, _numLPCParams) < 0)
        {
            // Couldn't initialize, has to return -1, and free the memory
            WebRtcCng_FreeEnc(_ptrDTXInst);
            _ptrDTXInst = NULL;
            return -1;
        }
        _dtxEnabled = true;
    }
    return 0;
}

WebRtc_Word16
ACMGenericCodec::DisableDTX()
{
    if(_hasInternalDTX)
    {
        // We should not be here if we have internal DTX
        // this function should be overwritten by the derived
        // class in this case
        return -1;
    }
    if(_ptrDTXInst != NULL)
    {
        WebRtcCng_FreeEnc(_ptrDTXInst);
        _ptrDTXInst = NULL;
    }
    _dtxEnabled = false;
    return 0;
}

WebRtc_Word16
ACMGenericCodec::EnableVAD(
    ACMVADMode mode)
{
    if((mode < VADNormal) || (mode > VADVeryAggr))
    {
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
            "EnableVAD: error in VAD mode range");
        return -1;
    }

    if(!_vadEnabled)
    {
        if(WebRtcVad_Create(&_ptrVADInst) < 0)
        {
            _ptrVADInst = NULL;
            WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
                "EnableVAD: error in create VAD");
            return -1;
        }
        if(WebRtcVad_Init(_ptrVADInst) < 0)
        {
            WebRtcVad_Free(_ptrVADInst);
            _ptrVADInst = NULL;
            WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
                "EnableVAD: error in init VAD");
            return -1;
        }
    }

    // Set the vad mode to the given value
    if(WebRtcVad_set_mode(_ptrVADInst, mode) < 0)
    {
        // We failed to set the mode and we have to return -1. If
        // we already have a working VAD (_vadEnabled == true) then
        // we leave it to work. otherwise, the following will be
        // executed.
        if(!_vadEnabled)
        {
            // We just created the instance but cannot set the mode
            // we have to free the memomry.
            WebRtcVad_Free(_ptrVADInst);
            _ptrVADInst = NULL;
        }
        WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceAudioCoding, _uniqueID,
            "EnableVAD: failed to set the VAD mode");
        return -1;
    }
    _vadMode = mode;
    _vadEnabled = true;
    return 0;
}

WebRtc_Word16
ACMGenericCodec::DisableVAD()
{
    if(_ptrVADInst != NULL)
    {
        WebRtcVad_Free(_ptrVADInst);
        _ptrVADInst = NULL;
    }
    _vadEnabled = false;
    return 0;
}

WebRtc_Word32
ACMGenericCodec::ReplaceInternalDTX(
    const bool replaceInternalDTX)
{
    WriteLockScoped cs(_codecWrapperLock);
    return ReplaceInternalDTXSafe(replaceInternalDTX);
}

WebRtc_Word32
ACMGenericCodec::ReplaceInternalDTXSafe(
    const bool /* replaceInternalDTX */)
{
    return -1;
}

WebRtc_Word32
ACMGenericCodec::IsInternalDTXReplaced(
    bool* internalDTXReplaced)
{
    WriteLockScoped cs(_codecWrapperLock);
    return IsInternalDTXReplacedSafe(internalDTXReplaced);
}

WebRtc_Word32
ACMGenericCodec::IsInternalDTXReplacedSafe(
    bool* internalDTXReplaced)
{
    *internalDTXReplaced = false;
    return 0;
}

WebRtc_Word16
ACMGenericCodec::ProcessFrameVADDTX(
    WebRtc_UWord8* bitStream,
    WebRtc_Word16* bitStreamLenByte,
    WebRtc_Word16* samplesProcessed)
{
    if(!_vadEnabled)
    {
        // VAD not enabled, set all vadLable[] to 1 (speech detected)
        for(WebRtc_Word16 n = 0; n < MAX_FRAME_SIZE_10MSEC; n++)
        {
            _vadLabel[n] = 1;
        }
        *samplesProcessed = 0;
        return 0;
    }
    WebRtc_UWord16 freqHz;
    EncoderSampFreq(freqHz);

    // Calculate number of samples in 10 ms blocks, and number ms in one frame
    WebRtc_Word16 samplesIn10Msec = (WebRtc_Word16)(freqHz / 100);
    WebRtc_Word32 frameLenMsec = (((WebRtc_Word32)_frameLenSmpl * 1000) / freqHz);
    WebRtc_Word16 status;

    // Vector for storing maximum 30 ms of mono audio at 32 kHz
    WebRtc_Word16 audio[960];

    // Calculate number of VAD-blocks to process, and number of samples in each block.
    int noSamplesToProcess[2];
    if (frameLenMsec == 40)
    {
        // 20 ms in each VAD block
        noSamplesToProcess[0] = noSamplesToProcess[1] = 2*samplesIn10Msec;
    }
    else
    {
        // For 10-30 ms framesizes, second VAD block will be size zero ms,
        // for 50 and 60 ms first VAD block will be 30 ms.
        noSamplesToProcess[0] = (frameLenMsec > 30)? 3*samplesIn10Msec : _frameLenSmpl;
        noSamplesToProcess[1] = _frameLenSmpl-noSamplesToProcess[0];
    }

    int offSet = 0;
    int loops = (noSamplesToProcess[1]>0) ? 2 : 1;
    for (int i=0; i<loops; i++) {
        // If stereo, calculate mean of the two channels
        if(_noChannels == 2) {
            for (int j=0; j<noSamplesToProcess[i]; j++) {
                audio[j] = (_inAudio[(offSet+j)*2]+_inAudio[(offSet+j)*2+1])/2;
        }
        offSet = noSamplesToProcess[0];
        } else {
            // Mono, copy data from _inAudio to continue work on
            memcpy(audio, _inAudio, sizeof(WebRtc_Word16)*noSamplesToProcess[i]);
        }

        // Call VAD
        status = WebRtcVad_Process(_ptrVADInst, (WebRtc_Word16)freqHz,
            audio, noSamplesToProcess[i]);

        _vadLabel[i] = status;

        if(status < 0)
        {
            // This will force that the data be removed from the buffer
            *samplesProcessed += noSamplesToProcess[i];
            return -1;
        }

        // If VAD decision non-active, update DTX. NOTE! We only do this if the first part of
        // a frame gets the VAD decision "inactive". Otherwise DTX might say it is time to
        // transmit SID frame, but we will encode the whole frame, because the first part is
        // active.
        *samplesProcessed = 0;
        if((status == 0) && (i==0) && _dtxEnabled && !_hasInternalDTX)
        {
            WebRtc_Word16 bitStreamLen;
            WebRtc_Word16 num10MsecFrames = noSamplesToProcess[i] / samplesIn10Msec;
            *bitStreamLenByte = 0;
            for(WebRtc_Word16 n = 0; n < num10MsecFrames; n++)
            {
                // This block is (passive) && (vad enabled)
                status = WebRtcCng_Encode(_ptrDTXInst, &audio[n*samplesIn10Msec],
                    samplesIn10Msec, bitStream, &bitStreamLen, 0);
                if (status < 0) {
                    return -1;
                }

                *samplesProcessed += samplesIn10Msec*_noChannels;

                // bitStreamLen will only be > 0 once per 100 ms
                *bitStreamLenByte += bitStreamLen;
            }


            // Check if all samples got processed by the DTX
            if(*samplesProcessed != noSamplesToProcess[i]*_noChannels) {
                // Set to zero since something went wrong. Shouldn't happen.
                *samplesProcessed = 0;
            }
        }

        if(*samplesProcessed > 0)
        {
            // The block contains inactive speech, and is processed by DTX.
            // Discontinue running VAD.
            break;
        }
    }

    return status;
}

WebRtc_Word16
ACMGenericCodec::SamplesLeftToEncode()
{
    ReadLockScoped rl(_codecWrapperLock);
    return (_frameLenSmpl <= _inAudioIxWrite)?
        0:(_frameLenSmpl - _inAudioIxWrite);
}

WebRtc_Word32
ACMGenericCodec::UnregisterFromNetEq(
    ACMNetEQ*     netEq,
    WebRtc_Word16 payloadType)
{
    WriteLockScoped wl(_codecWrapperLock);
    if(!_registeredInNetEq)
    {
        return 0;
    }
    if(UnregisterFromNetEqSafe(netEq, payloadType) < 0)
    {
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
            "UnregisterFromNetEq: error, cannot unregister from NetEq");
        _registeredInNetEq = true;
        return -1;
    }
    else
    {
        _registeredInNetEq = false;
        return 0;
    }
}

void
ACMGenericCodec::SetUniqueID(
    const WebRtc_UWord32 id)
{
    _uniqueID = id;
}

bool
ACMGenericCodec::IsAudioBufferFresh() const
{
    ReadLockScoped rl(_codecWrapperLock);
    return _isAudioBuffFresh;
}

// This function is replaced by codec specific functions for some codecs
WebRtc_Word16
ACMGenericCodec::EncoderSampFreq(WebRtc_UWord16& sampFreqHz)
{
    WebRtc_Word32 f;
    f = ACMCodecDB::CodecFreq(_codecID);
    if(f < 0)
    {
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
                     "EncoderSampFreq: codec frequency is negative");
        return -1;
    }
    else
    {
        sampFreqHz = (WebRtc_UWord16)f;
        return 0;
    }
}


WebRtc_Word32
ACMGenericCodec::ConfigISACBandwidthEstimator(
    const WebRtc_UWord8  /* initFrameSizeMsec */,
    const WebRtc_UWord16 /* initRateBitPerSec */,
    const bool           /* enforceFrameSize  */)
{
    WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, _uniqueID,
        "The send-codec is not iSAC, failed to config iSAC bandwidth estimator.");
    return -1;
}

WebRtc_Word32
ACMGenericCodec::SetISACMaxRate(
    const WebRtc_UWord32 /* maxRateBitPerSec */)
{
    WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, _uniqueID,
        "The send-codec is not iSAC, failed to set iSAC max rate.");
    return -1;
}

WebRtc_Word32
ACMGenericCodec::SetISACMaxPayloadSize(
    const WebRtc_UWord16 /* maxPayloadLenBytes */)
{
    WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, _uniqueID,
        "The send-codec is not iSAC, failed to set iSAC max payload-size.");
    return -1;
}


void
ACMGenericCodec::SaveDecoderParam(
    const WebRtcACMCodecParams* codecParams)
{
    WriteLockScoped wl(_codecWrapperLock);
    SaveDecoderParamSafe(codecParams);
}


void
ACMGenericCodec::SaveDecoderParamSafe(
    const WebRtcACMCodecParams* codecParams)
{
    memcpy(&_decoderParams, codecParams, sizeof(WebRtcACMCodecParams));
}

WebRtc_Word16
ACMGenericCodec::UpdateEncoderSampFreq(
    WebRtc_UWord16 /* encoderSampFreqHz */)
{
    WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
        "It is asked for a change in smapling frequency while the \
current send-codec supports only one sampling rate.");
    return -1;
}


void
ACMGenericCodec::SetIsMaster(
    bool isMaster)
{
    WriteLockScoped wl(_codecWrapperLock);
    _isMaster = isMaster;
}



WebRtc_Word16
ACMGenericCodec::REDPayloadISAC(
        const WebRtc_Word32  /* isacRate        */,
        const WebRtc_Word16  /* isacBwEstimate  */,
        WebRtc_UWord8*       /* payload         */,
        WebRtc_Word16*       /* payloadLenBytes */)
{
   WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
       "Error: REDPayloadISAC is an iSAC specific function");
    return -1;
}

} // namespace webrtc
