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

namespace webrtc {

#ifndef WEBRTC_CODEC_SPEEX
ACMSPEEX::ACMSPEEX(WebRtc_Word16 /* codecID*/)
    : _encoderInstPtr(NULL),
      _decoderInstPtr(NULL) {
  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;
}

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

#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 it's
    // 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;
}


WebRtc_Word16
ACMSPEEX::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;
    }


    switch(_samplingFrequency)
    {
    case 8000:
        {
            return netEq->RemoveCodec(kDecoderSPEEX_8);
        }
    case 16000:
        {
            return netEq->RemoveCodec(kDecoderSPEEX_16);
        }
    default:
        {
            WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, _uniqueID,
            "Could not unregister Speex from NetEQ. Sampling frequency doesn't match");
            return -1;
        }
    }
}


#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
