/*
 *  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 "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);
    // void WebRtcAmr_Version(char *versionStr, short len);
    #include "amr_interface.h"
#endif

namespace webrtc {

#ifndef WEBRTC_CODEC_AMR
ACMAMR::ACMAMR(WebRtc_Word16 /* codecID */)
{
    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;
}

WebRtc_Word16
ACMAMR::UnregisterFromNetEqSafe(
    ACMNetEQ*     /* netEq       */,
    WebRtc_Word16 /* payloadType */)
{
    return -1;
}


#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;
        break;
    }
    return 0;
}


void 
ACMAMR::InternalDestructEncoderInst(
    void* ptrInst)
{
    // Free the memory where ptrInst is pointing to
    if(ptrInst != NULL)
    {
        WebRtcAmr_FreeEnc((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;
}

WebRtc_Word16
ACMAMR::UnregisterFromNetEqSafe(
    ACMNetEQ*     netEq,
    WebRtc_Word16 payloadType)
{
    if(payloadType != _decoderParams.codecInstant.pltype)
    {
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID, 
            "Cannot unregister codec %s given payload-type %d does not match \
the stored payload type", 
            _decoderParams.codecInstant.plname, 
            payloadType, 
            _decoderParams.codecInstant.pltype);
        return -1;
    }
    return netEq->RemoveCodec(kDecoderAMR);
}

#endif

}

