- work on evs decoder
This commit is contained in:
@@ -57,11 +57,16 @@ set (CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set (rtphone_libs libs)
|
||||
set (rtphone_engine engine)
|
||||
|
||||
set (USE_AMR_CODEC OFF CACHE BOOL "Use AMR codec. Requires libraries.")
|
||||
set (USE_EVS_CODEC OFF CACHE BOOL "Use EVS codec.")
|
||||
option (USE_AMR_CODEC "Use AMR codec. Requires libraries." OFF)
|
||||
option (USE_EVS_CODEC "Use EVS codec." OFF)
|
||||
|
||||
set (CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||
|
||||
if (NOT DEFINED LIB_PLATFORM)
|
||||
set (LIB_PLATFORM ${CMAKE_CURRENT_SOURCE_DIR}/../../libraries)
|
||||
endif()
|
||||
|
||||
message("Libraries: ${LIB_PLATFORM}")
|
||||
set (OPENSSL_INCLUDE ${LIB_PLATFORM}/openssl/1.0/include)
|
||||
message ("Using OpenSSL include files from ${OPENSSL_INCLUDE}")
|
||||
|
||||
@@ -164,6 +169,10 @@ if (USE_AMR_CODEC)
|
||||
set (LIBS ${LIBS} opencore-amrnb opencore-amrwb)
|
||||
endif (USE_AMR_CODEC)
|
||||
|
||||
if (USE_EVS_CODEC)
|
||||
add_definitions(-DUSE_EVS_CODEC)
|
||||
endif()
|
||||
|
||||
target_link_libraries(rtphone
|
||||
ice_stack jrtplib g729_codec gsm_codec
|
||||
gsmhr_codec g722_codec srtp resiprocate
|
||||
@@ -186,6 +195,9 @@ target_include_directories(rtphone
|
||||
${LIB_PLATFORM}/opus/include
|
||||
PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/libs/
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/libs/libevs/lib_com
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/libs/libevs/lib_enc
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/libs/libevs/lib_dec
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/libs/speex/include
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/libs/opus/include/
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/libs/json
|
||||
|
||||
@@ -35,8 +35,16 @@ target_include_directories(media_lib
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../libs/webrtc
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../libs/opus/include/
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../libs/resiprocate/
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../libs/libevs/
|
||||
)
|
||||
|
||||
target_include_directories(media_lib
|
||||
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../../libs/libevs/lib_com
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../libs/libevs/lib_dec
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../libs/libevs/lib_enc
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../libs/libevs/basic_op
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../libs/libevs/basic_math
|
||||
)
|
||||
if (USE_RESIP_INTEGRATION)
|
||||
message("USE_RESIP_INTEGRATION is turned on!")
|
||||
target_compile_definitions(media_lib PUBLIC -DUSE_RESIP_INTEGRATION)
|
||||
|
||||
@@ -0,0 +1,206 @@
|
||||
#include "MT_EvsCodec.h"
|
||||
|
||||
//bool
|
||||
|
||||
EVSCodec::EVSFactory::EVSFactory(StreamParameters sp) : _sp(sp)
|
||||
{}
|
||||
|
||||
int EVSCodec::EVSFactory::samplerate()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int EVSCodec::EVSFactory::payloadType()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
PCodec EVSCodec::EVSFactory::create()
|
||||
{
|
||||
return std::static_pointer_cast<Codec>(std::make_shared<EVSCodec>(_sp));
|
||||
}
|
||||
|
||||
EVSCodec::EVSCodec(): EVSCodec(StreamParameters())
|
||||
{
|
||||
}
|
||||
|
||||
EVSCodec::EVSCodec(const StreamParameters &sp)
|
||||
{
|
||||
EVSCodec::sp = sp;
|
||||
|
||||
if ((st_dec = (Decoder_State*)malloc(sizeof(Decoder_State))) == NULL)
|
||||
{
|
||||
std::stringstream out;
|
||||
out << "Can not allocate memory for decoder state structure\n";
|
||||
throw std::out_of_range(out.str());
|
||||
}
|
||||
/*if ((st_enc = (Encoder_State*)malloc(sizeof(Encoder_State))) == NULL)
|
||||
{
|
||||
std::stringstream out;
|
||||
out << "Can not allocate memory for encoder state structure\n";
|
||||
throw std::out_of_range(out.str());
|
||||
}*/
|
||||
initDecoder(sp);
|
||||
}
|
||||
|
||||
EVSCodec::~EVSCodec()
|
||||
{
|
||||
if (st_dec)
|
||||
{
|
||||
destroy_decoder(st_dec);
|
||||
free(st_dec);
|
||||
}
|
||||
}
|
||||
|
||||
int EVSCodec::samplerate()
|
||||
{
|
||||
return st_dec->output_Fs;
|
||||
}
|
||||
|
||||
int EVSCodec::samplerate(int CodecMode)
|
||||
{
|
||||
return samplerate();
|
||||
}
|
||||
|
||||
int EVSCodec::pcmLength()
|
||||
{
|
||||
return samplerate() / 50;
|
||||
}
|
||||
|
||||
int EVSCodec::pcmLength(int CodecMode)
|
||||
{
|
||||
return pcmLength();
|
||||
}
|
||||
|
||||
int EVSCodec::frameTime()
|
||||
{
|
||||
return sp.ptime;
|
||||
}
|
||||
|
||||
int EVSCodec::rtpLength()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int EVSCodec::encode(const void* input, int inputBytes, void* output, int outputCapacity)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int EVSCodec::decode(const void* input, int input_length, void* output, int outputCapacity)
|
||||
{
|
||||
if (outputCapacity < L_FRAME8k)
|
||||
{
|
||||
std::stringstream out;
|
||||
out << "Buffer for pcm frame is to small\n";
|
||||
throw std::out_of_range(out.str());
|
||||
}
|
||||
|
||||
std::string buffer;
|
||||
|
||||
/*if we have FixedPayload without ToC*/
|
||||
if (FixedPayload_EVSPrimary.find(input_length * 8) != FixedPayload_EVSPrimary.end())
|
||||
{
|
||||
char c = rate2EVSmode(FixedPayload_EVSPrimary.find(input_length * 8)->second);
|
||||
/* Add ToC byte.
|
||||
* WARNING maybe it will be work incorrect with 56bit payload,
|
||||
* see 3GPP TS 26.445 Annex A, A.2.1.3 */
|
||||
buffer += c;
|
||||
}
|
||||
|
||||
buffer += std::string(reinterpret_cast<const char*>(input), input_length);
|
||||
|
||||
// Output buffer for 48 KHz
|
||||
float data[L_FRAME48k];
|
||||
int offset = 0;
|
||||
|
||||
/* Decode process */
|
||||
size_t buffer_processed = 0;
|
||||
|
||||
while (st_dec->bitstreamformat == G192 ? read_indices(st_dec, buffer.c_str(), buffer.size(), &buffer_processed, 0) : read_indices_mime(st_dec, buffer.c_str(), buffer.size(), &buffer_processed, 0))
|
||||
{
|
||||
if (st_dec->codec_mode == MODE1)
|
||||
{
|
||||
if (st_dec->Opt_AMR_WB)
|
||||
{
|
||||
amr_wb_dec(st_dec, data);
|
||||
}
|
||||
else
|
||||
{
|
||||
evs_dec(st_dec, data, FRAMEMODE_NORMAL);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!st_dec->bfi)
|
||||
{
|
||||
evs_dec(st_dec, data, FRAMEMODE_NORMAL);
|
||||
}
|
||||
else
|
||||
{
|
||||
evs_dec(st_dec, data, FRAMEMODE_MISSING);
|
||||
}
|
||||
}
|
||||
|
||||
/* convert 'float' output data to 'short' */
|
||||
syn_output(data, this->pcmLength(), static_cast<short*>(output) + offset);
|
||||
offset += this->pcmLength();
|
||||
if (st_dec->ini_frame < MAX_FRAME_COUNTER)
|
||||
{
|
||||
st_dec->ini_frame++;
|
||||
}
|
||||
}
|
||||
// std::fclose(temp);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int EVSCodec::plc(int lostFrames, void* output, int outputCapacity)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void EVSCodec::initDecoder(const StreamParameters& sp)
|
||||
{
|
||||
/* set to NULL, to avoid reading of uninitialized memory in case of early abort */
|
||||
st_dec->cldfbAna = st_dec->cldfbBPF = st_dec->cldfbSyn = nullptr;
|
||||
st_dec->hFdCngDec = nullptr;
|
||||
st_dec->codec_mode = 0; /* unknown before first frame */
|
||||
st_dec->Opt_AMR_WB = 0;
|
||||
st_dec->Opt_VOIP = 0;
|
||||
|
||||
st_dec->bitstreamformat = G192;
|
||||
st_dec->amrwb_rfc4867_flag = -1;
|
||||
|
||||
/*Set MIME type*/
|
||||
if (sp.mime) {
|
||||
st_dec->bitstreamformat = MIME;
|
||||
st_dec->amrwb_rfc4867_flag = 0;
|
||||
}
|
||||
/*Set Bandwidth*/
|
||||
switch (sp.bw) {
|
||||
case NB :
|
||||
st_dec->output_Fs = 8000;
|
||||
break;
|
||||
case WB:
|
||||
st_dec->output_Fs = 16000;
|
||||
break;
|
||||
case SWB:
|
||||
st_dec->output_Fs = 32000;
|
||||
break;
|
||||
case FB:
|
||||
st_dec->output_Fs = 48000;
|
||||
break;
|
||||
}
|
||||
// st_enc->input_Fs = st_dec->output_Fs; //TODO: remove when func initEncoder() is added
|
||||
/*------------------------------------------------------------------------------------------*
|
||||
* Allocate memory for static variables
|
||||
* Decoder initialization
|
||||
*------------------------------------------------------------------------------------------*/
|
||||
|
||||
// TODO: add ability of reinit Decoder_state, may be need use destroy_decoder()
|
||||
init_decoder(st_dec);
|
||||
reset_indices_dec(st_dec);
|
||||
|
||||
srand(static_cast<unsigned int>(time(nullptr)));
|
||||
|
||||
}
|
||||
|
||||
@@ -1,157 +1,210 @@
|
||||
#ifndef MT_EVSCODEC_H
|
||||
#define MT_EVSCODEC_H
|
||||
#pragma once
|
||||
|
||||
#include "../config.h"
|
||||
#include <set>
|
||||
#include <map>
|
||||
#include "MT_Codec.h"
|
||||
#include "../helper/HL_Pointer.h"
|
||||
#include <memory>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <assert.h>
|
||||
#include <sstream>
|
||||
|
||||
#if defined(USE_EVS_CODEC)
|
||||
namespace MT
|
||||
extern "C" {
|
||||
//#include "lib_dec/EvsRXlib.h"
|
||||
#include "libevs/lib_com/prot.h"
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------*
|
||||
* rate2AMRWB_IOmode()
|
||||
*
|
||||
* lookup AMRWB IO mode
|
||||
*-------------------------------------------------------------------*/
|
||||
|
||||
static Word16 rate2AMRWB_IOmode(
|
||||
Word32 rate /* i: bit rate */
|
||||
);
|
||||
|
||||
/*Revers Function*/
|
||||
extern Word16 AMRWB_IOmode2rate(
|
||||
Word32 mode
|
||||
);
|
||||
|
||||
/*-------------------------------------------------------------------*
|
||||
* rate2EVSmode()
|
||||
*
|
||||
* lookup EVS mode
|
||||
*-------------------------------------------------------------------*/
|
||||
extern Word16 rate2EVSmode(
|
||||
Word32 rate /* i: bit rate */
|
||||
);
|
||||
|
||||
/*Revers Function*/
|
||||
extern Word16 EVSmode2rate(
|
||||
Word32 mode
|
||||
);
|
||||
|
||||
class Codec;
|
||||
typedef std::shared_ptr<Codec> PCodec;
|
||||
|
||||
#define CMR_OFF -1
|
||||
#define CMR_ON 0
|
||||
#define CMR_ONLY 1
|
||||
|
||||
|
||||
static const std::map<int, std::set<int>> BitrateToBandwidth_Tab{
|
||||
{5900, {NB, WB}},
|
||||
{7200, {NB, WB}},
|
||||
{8000, {NB, WB}},
|
||||
{9600, {NB, WB, SWB}},
|
||||
{13200, {NB, WB, SWB}}, //if channel aware mode - WB, SWB
|
||||
{16400, {NB, WB, SWB, FB}},
|
||||
{24400, {NB, WB, SWB, FB}},
|
||||
{32000, {WB, SWB, FB}},
|
||||
{48000, {WB, SWB, FB}},
|
||||
{64000, {WB, SWB, FB}},
|
||||
{96000, {WB, SWB, FB}},
|
||||
{128000, {WB, SWB, FB}}
|
||||
};
|
||||
|
||||
/* Protected payload size/Fixed bitrate to EVS ()*/
|
||||
static const std::map<int, int> Bitrate2PayloadSize_EVSAMR_WB{
|
||||
/*{bitrate, payload size}*/
|
||||
{ SID_1k75, 56}, //AMR-WB I/O SIB
|
||||
{ACELP_6k60, 136},
|
||||
{ACELP_8k85, 184},
|
||||
{ACELP_12k65, 256},
|
||||
{ACELP_14k25, 288},
|
||||
{ACELP_15k85, 320},
|
||||
{ACELP_18k25, 368},
|
||||
{ACELP_19k85, 400},
|
||||
{ACELP_23k05, 464},
|
||||
{ACELP_23k85, 480}
|
||||
};
|
||||
|
||||
static const std::map<int, int> Bitrate2PayloadSize_EVS{
|
||||
/*{bitrate, payload size}*/
|
||||
{FRAME__NO_DATA, 0},
|
||||
{SID_2k40, 48}, //EVS Primary SID
|
||||
{PPP_NELP_2k80, 56}, //special for full header
|
||||
{ACELP_7k20, 144},
|
||||
{ACELP_8k00, 160},
|
||||
{ACELP_9k60, 192},
|
||||
{ACELP_13k20, 264},
|
||||
{ACELP_16k40, 328},
|
||||
{ACELP_24k40, 488},
|
||||
{ACELP_32k, 640},
|
||||
{ACELP_48k, 960},
|
||||
{ACELP_64k, 1280},
|
||||
{HQ_96k, 1920},
|
||||
{HQ_128k, 2560}
|
||||
};
|
||||
|
||||
/* Protected payload size/Fixed bitrate to EVS ()*/
|
||||
static const std::map<int, int> FixedPayload_EVSPrimary{
|
||||
/*{payload size , bitrate}*/
|
||||
{48, 2400}, //EVS Primary SID
|
||||
{56, 2800}, //special for full header
|
||||
{144, 7200},
|
||||
{160, 8000},
|
||||
{192, 9600},
|
||||
{264, 13200},
|
||||
{328, 16400},
|
||||
{488, 24400},
|
||||
{640, 32000},
|
||||
{960, 48000},
|
||||
{1280, 64000},
|
||||
{1920, 96000},
|
||||
{2560, 128000}
|
||||
};
|
||||
|
||||
static const std::map<int, int> FixedPayload_EVSAMR_WB{
|
||||
/*{payload size , bitrate}*/
|
||||
{136, 6600},
|
||||
{184, 8850},
|
||||
{256, 12650},
|
||||
{288, 14250},
|
||||
{320, 15850},
|
||||
{368, 18250},
|
||||
{400, 19850},
|
||||
{464, 23050},
|
||||
{480, 23850}
|
||||
};
|
||||
|
||||
struct StreamParameters {
|
||||
bool mime = false;
|
||||
bool fh_only = false; /*not use*/
|
||||
int CRMByte = CMR_OFF;/*not use*/
|
||||
int br = 0; /*not use*/
|
||||
int bw = NB;
|
||||
int ptime = 20;
|
||||
}; //Emulated SDP config/meadia type parameters
|
||||
|
||||
class Codec
|
||||
{
|
||||
struct AmrCodecConfig
|
||||
{
|
||||
bool mIuUP;
|
||||
bool mOctetAligned;
|
||||
int mPayloadType;
|
||||
};
|
||||
|
||||
class AmrNbCodec : public Codec
|
||||
{
|
||||
protected:
|
||||
void* mEncoderCtx;
|
||||
void* mDecoderCtx;
|
||||
AmrCodecConfig mConfig;
|
||||
unsigned mCurrentDecoderTimestamp;
|
||||
int mSwitchCounter;
|
||||
int mPreviousPacketLength;
|
||||
|
||||
public:
|
||||
class CodecFactory: public Factory
|
||||
public:
|
||||
class Factory
|
||||
{
|
||||
public:
|
||||
CodecFactory(const AmrCodecConfig& config);
|
||||
virtual ~Factory() {}
|
||||
virtual const char* name() = 0;
|
||||
virtual int samplerate() = 0;
|
||||
virtual int payloadType() = 0;
|
||||
virtual PCodec create() = 0;
|
||||
|
||||
const char* name() override;
|
||||
int samplerate() override;
|
||||
int payloadType() override;
|
||||
|
||||
#if defined(USE_RESIP_INTEGRATION)
|
||||
void updateSdp(resip::SdpContents::Session::Medium::CodecContainer& codecs, SdpDirection direction) override;
|
||||
int processSdp(const resip::SdpContents::Session::Medium::CodecContainer& codecs, SdpDirection direction) override;
|
||||
void create(CodecMap& codecs) override;
|
||||
#endif
|
||||
PCodec create() override;
|
||||
|
||||
protected:
|
||||
AmrCodecConfig mConfig;
|
||||
virtual int channels() = 0;
|
||||
};
|
||||
virtual ~Codec() {}
|
||||
virtual const char* name() = 0;
|
||||
virtual int samplerate() = 0;
|
||||
virtual float timestampUnit() { return float(1.0 / samplerate()); }
|
||||
virtual int pcmLength() = 0;
|
||||
virtual int frameTime() = 0;
|
||||
virtual int rtpLength() = 0;
|
||||
virtual int channels() { return 1; }
|
||||
virtual int encode(const void* input, int inputBytes, void* output, int outputCapacity) = 0;
|
||||
virtual int decode(const void* input, int inputBytes, void* output, int outputCapacity) = 0;
|
||||
virtual int plc(int lostFrames, void* output, int outputCapacity) = 0;
|
||||
|
||||
AmrNbCodec(const AmrCodecConfig& config);
|
||||
// Returns size of codec in memory
|
||||
virtual int getSize() const { return 0; };
|
||||
};
|
||||
|
||||
virtual ~AmrNbCodec();
|
||||
const char* name() override;
|
||||
int pcmLength() override;
|
||||
int rtpLength() override;
|
||||
int frameTime() override;
|
||||
int samplerate() override;
|
||||
int encode(const void* input, int inputBytes, void* output, int outputCapacity) override;
|
||||
int decode(const void* input, int inputBytes, void* output, int outputCapacity) override;
|
||||
int plc(int lostFrames, void* output, int outputCapacity) override;
|
||||
int getSwitchCounter() const;
|
||||
};
|
||||
class EVSCodec : public Codec
|
||||
{
|
||||
private:
|
||||
Decoder_State* st_dec;
|
||||
//Encoder_State_fx* st_enc;
|
||||
StreamParameters sp;
|
||||
|
||||
class AmrWbCodec : public Codec
|
||||
{
|
||||
protected:
|
||||
void* mEncoderCtx;
|
||||
void* mDecoderCtx;
|
||||
AmrCodecConfig mConfig;
|
||||
uint64_t mCurrentDecoderTimestamp;
|
||||
int mSwitchCounter;
|
||||
int mPreviousPacketLength;
|
||||
|
||||
public:
|
||||
class CodecFactory: public Factory
|
||||
public:
|
||||
class EVSFactory : public Factory
|
||||
{
|
||||
public:
|
||||
CodecFactory(const AmrCodecConfig& config);
|
||||
|
||||
const char* name() override;
|
||||
int samplerate() override;
|
||||
int payloadType() override;
|
||||
|
||||
#if defined(USE_RESIP_INTEGRATION)
|
||||
void updateSdp(resip::SdpContents::Session::Medium::CodecContainer& codecs, SdpDirection direction) override;
|
||||
int processSdp(const resip::SdpContents::Session::Medium::CodecContainer& codecs, SdpDirection direction) override;
|
||||
void create(CodecMap& codecs) override;
|
||||
#endif
|
||||
PCodec create() override;
|
||||
|
||||
protected:
|
||||
AmrCodecConfig mConfig;
|
||||
StreamParameters _sp;
|
||||
|
||||
public:
|
||||
EVSFactory(StreamParameters sp);
|
||||
const char* name() { return "EVS"; };
|
||||
int samplerate();
|
||||
int payloadType();
|
||||
PCodec create();
|
||||
int channels() { return 1; } //without support stereo audio transmition
|
||||
};
|
||||
|
||||
AmrWbCodec(const AmrCodecConfig& config);
|
||||
virtual ~AmrWbCodec();
|
||||
|
||||
const char* name() override;
|
||||
int pcmLength() override;
|
||||
int rtpLength() override;
|
||||
int frameTime() override;
|
||||
int samplerate() override;
|
||||
int encode(const void* input, int inputBytes, void* output, int outputCapacity) override;
|
||||
int decode(const void* input, int inputBytes, void* output, int outputCapacity) override;
|
||||
int plc(int lostFrames, void* output, int outputCapacity) override;
|
||||
int getSwitchCounter() const;
|
||||
};
|
||||
|
||||
class GsmEfrCodec : public Codec
|
||||
{
|
||||
protected:
|
||||
void* mEncoderCtx;
|
||||
void* mDecoderCtx;
|
||||
bool mIuUP;
|
||||
|
||||
public:
|
||||
class GsmEfrFactory: public Factory
|
||||
{
|
||||
public:
|
||||
GsmEfrFactory(bool iuup, int ptype);
|
||||
|
||||
const char* name() override;
|
||||
int samplerate() override;
|
||||
int payloadType() override;
|
||||
|
||||
#if defined(USE_RESIP_INTEGRATION)
|
||||
void updateSdp(resip::SdpContents::Session::Medium::CodecContainer& codecs, SdpDirection direction) override;
|
||||
int processSdp(const resip::SdpContents::Session::Medium::CodecContainer& codecs, SdpDirection direction) override;
|
||||
void create(CodecMap& codecs) override;
|
||||
#endif
|
||||
PCodec create() override;
|
||||
|
||||
protected:
|
||||
bool mIuUP;
|
||||
int mPayloadType;
|
||||
};
|
||||
|
||||
GsmEfrCodec(bool iuup = false);
|
||||
|
||||
virtual ~GsmEfrCodec();
|
||||
const char* name() override;
|
||||
int pcmLength() override;
|
||||
int rtpLength() override;
|
||||
int frameTime() override;
|
||||
int samplerate() override;
|
||||
int encode(const void* input, int inputBytes, void* output, int outputCapacity) override;
|
||||
int decode(const void* input, int inputBytes, void* output, int outputCapacity) override;
|
||||
int plc(int lostFrames, void* output, int outputCapacity) override;
|
||||
};
|
||||
|
||||
} // End of MT namespace
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#endif // MT_EVSCODE_H
|
||||
EVSCodec();
|
||||
EVSCodec(const StreamParameters& sp);
|
||||
~EVSCodec() override;
|
||||
|
||||
const char* name() { return "EVS"; };
|
||||
int samplerate();
|
||||
int samplerate(int CodecMode); // DEC or ENC defined in cnst.h
|
||||
int pcmLength();
|
||||
int pcmLength(int CodecMode); // DEC or ENC defined in cnst.h
|
||||
int frameTime();
|
||||
int rtpLength();
|
||||
int encode(const void* input, int inputBytes, void* output, int outputCapacity);
|
||||
int decode(const void* input, int inputBytes, void* output, int outputCapacity);
|
||||
int plc(int lostFrames, void* output, int outputCapacity) ;
|
||||
void initDecoder(const StreamParameters& sp);
|
||||
};
|
||||
|
||||
345
src/libs/libevs/CMakeLists.txt.user
Normal file
345
src/libs/libevs/CMakeLists.txt.user
Normal file
@@ -0,0 +1,345 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE QtCreatorProject>
|
||||
<!-- Written by QtCreator 4.11.0, 2020-06-15T13:37:04. -->
|
||||
<qtcreator>
|
||||
<data>
|
||||
<variable>EnvironmentId</variable>
|
||||
<value type="QByteArray">{3afbbbef-07ad-4e54-a4d3-e24ca448be01}</value>
|
||||
</data>
|
||||
<data>
|
||||
<variable>ProjectExplorer.Project.ActiveTarget</variable>
|
||||
<value type="int">0</value>
|
||||
</data>
|
||||
<data>
|
||||
<variable>ProjectExplorer.Project.EditorSettings</variable>
|
||||
<valuemap type="QVariantMap">
|
||||
<value type="bool" key="EditorConfiguration.AutoIndent">true</value>
|
||||
<value type="bool" key="EditorConfiguration.AutoSpacesForTabs">false</value>
|
||||
<value type="bool" key="EditorConfiguration.CamelCaseNavigation">true</value>
|
||||
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.0">
|
||||
<value type="QString" key="language">Cpp</value>
|
||||
<valuemap type="QVariantMap" key="value">
|
||||
<value type="QByteArray" key="CurrentPreferences">CppGlobal</value>
|
||||
</valuemap>
|
||||
</valuemap>
|
||||
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.1">
|
||||
<value type="QString" key="language">QmlJS</value>
|
||||
<valuemap type="QVariantMap" key="value">
|
||||
<value type="QByteArray" key="CurrentPreferences">QmlJSGlobal</value>
|
||||
</valuemap>
|
||||
</valuemap>
|
||||
<value type="int" key="EditorConfiguration.CodeStyle.Count">2</value>
|
||||
<value type="QByteArray" key="EditorConfiguration.Codec">UTF-8</value>
|
||||
<value type="bool" key="EditorConfiguration.ConstrainTooltips">false</value>
|
||||
<value type="int" key="EditorConfiguration.IndentSize">4</value>
|
||||
<value type="bool" key="EditorConfiguration.KeyboardTooltips">false</value>
|
||||
<value type="int" key="EditorConfiguration.MarginColumn">80</value>
|
||||
<value type="bool" key="EditorConfiguration.MouseHiding">true</value>
|
||||
<value type="bool" key="EditorConfiguration.MouseNavigation">true</value>
|
||||
<value type="int" key="EditorConfiguration.PaddingMode">1</value>
|
||||
<value type="bool" key="EditorConfiguration.ScrollWheelZooming">true</value>
|
||||
<value type="bool" key="EditorConfiguration.ShowMargin">false</value>
|
||||
<value type="int" key="EditorConfiguration.SmartBackspaceBehavior">0</value>
|
||||
<value type="bool" key="EditorConfiguration.SmartSelectionChanging">true</value>
|
||||
<value type="bool" key="EditorConfiguration.SpacesForTabs">true</value>
|
||||
<value type="int" key="EditorConfiguration.TabKeyBehavior">0</value>
|
||||
<value type="int" key="EditorConfiguration.TabSize">8</value>
|
||||
<value type="bool" key="EditorConfiguration.UseGlobal">true</value>
|
||||
<value type="int" key="EditorConfiguration.Utf8BomBehavior">1</value>
|
||||
<value type="bool" key="EditorConfiguration.addFinalNewLine">true</value>
|
||||
<value type="bool" key="EditorConfiguration.cleanIndentation">true</value>
|
||||
<value type="bool" key="EditorConfiguration.cleanWhitespace">true</value>
|
||||
<value type="bool" key="EditorConfiguration.inEntireDocument">false</value>
|
||||
</valuemap>
|
||||
</data>
|
||||
<data>
|
||||
<variable>ProjectExplorer.Project.PluginSettings</variable>
|
||||
<valuemap type="QVariantMap">
|
||||
<valuelist type="QVariantList" key="ClangCodeModel.CustomCommandLineKey"/>
|
||||
<value type="bool" key="ClangCodeModel.UseGlobalConfig">true</value>
|
||||
</valuemap>
|
||||
</data>
|
||||
<data>
|
||||
<variable>ProjectExplorer.Project.Target.0</variable>
|
||||
<valuemap type="QVariantMap">
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop Qt 5.14.0 GCC 64bit</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop Qt 5.14.0 GCC 64bit</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">qt.qt5.5140.gcc_64_kit</value>
|
||||
<value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value>
|
||||
<value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
|
||||
<value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
|
||||
<valuelist type="QVariantList" key="CMake.Configuration">
|
||||
<value type="QString">CMAKE_BUILD_TYPE:STRING=Debug</value>
|
||||
<value type="QString">CMAKE_CXX_COMPILER:STRING=%{Compiler:Executable:Cxx}</value>
|
||||
<value type="QString">CMAKE_C_COMPILER:STRING=%{Compiler:Executable:C}</value>
|
||||
<value type="QString">CMAKE_PREFIX_PATH:STRING=%{Qt:QT_INSTALL_PREFIX}</value>
|
||||
<value type="QString">QT_QMAKE_EXECUTABLE:STRING=%{Qt:qmakeExecutable}</value>
|
||||
</valuelist>
|
||||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/anand/works/sevana/platform/rtphone/src/libs/build-libevs-Desktop_Qt_5_14_0_GCC_64bit-Debug</value>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||
<value type="QString" key="CMakeProjectManager.MakeStep.AdditionalArguments"></value>
|
||||
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
|
||||
<value type="QString">all</value>
|
||||
</valuelist>
|
||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
|
||||
</valuemap>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||
<value type="QString" key="CMakeProjectManager.MakeStep.AdditionalArguments"></value>
|
||||
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
|
||||
<value type="QString">clean</value>
|
||||
</valuelist>
|
||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Clean</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
|
||||
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
|
||||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Debug</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.CMakeBuildConfiguration</value>
|
||||
</valuemap>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.1">
|
||||
<valuelist type="QVariantList" key="CMake.Configuration">
|
||||
<value type="QString">CMAKE_BUILD_TYPE:STRING=Release</value>
|
||||
<value type="QString">CMAKE_CXX_COMPILER:STRING=%{Compiler:Executable:Cxx}</value>
|
||||
<value type="QString">CMAKE_C_COMPILER:STRING=%{Compiler:Executable:C}</value>
|
||||
<value type="QString">CMAKE_PREFIX_PATH:STRING=%{Qt:QT_INSTALL_PREFIX}</value>
|
||||
<value type="QString">QT_QMAKE_EXECUTABLE:STRING=%{Qt:qmakeExecutable}</value>
|
||||
</valuelist>
|
||||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/anand/works/sevana/platform/rtphone/src/libs/build-libevs-Desktop_Qt_5_14_0_GCC_64bit-Release</value>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||
<value type="QString" key="CMakeProjectManager.MakeStep.AdditionalArguments"></value>
|
||||
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
|
||||
<value type="QString">all</value>
|
||||
</valuelist>
|
||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
|
||||
</valuemap>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||
<value type="QString" key="CMakeProjectManager.MakeStep.AdditionalArguments"></value>
|
||||
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
|
||||
<value type="QString">clean</value>
|
||||
</valuelist>
|
||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Clean</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
|
||||
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
|
||||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Release</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.CMakeBuildConfiguration</value>
|
||||
</valuemap>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.2">
|
||||
<valuelist type="QVariantList" key="CMake.Configuration">
|
||||
<value type="QString">CMAKE_BUILD_TYPE:STRING=RelWithDebInfo</value>
|
||||
<value type="QString">CMAKE_CXX_COMPILER:STRING=%{Compiler:Executable:Cxx}</value>
|
||||
<value type="QString">CMAKE_C_COMPILER:STRING=%{Compiler:Executable:C}</value>
|
||||
<value type="QString">CMAKE_PREFIX_PATH:STRING=%{Qt:QT_INSTALL_PREFIX}</value>
|
||||
<value type="QString">QT_QMAKE_EXECUTABLE:STRING=%{Qt:qmakeExecutable}</value>
|
||||
</valuelist>
|
||||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/anand/works/sevana/platform/rtphone/src/libs/build-libevs-Desktop_Qt_5_14_0_GCC_64bit-RelWithDebInfo</value>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||
<value type="QString" key="CMakeProjectManager.MakeStep.AdditionalArguments"></value>
|
||||
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
|
||||
<value type="QString">all</value>
|
||||
</valuelist>
|
||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
|
||||
</valuemap>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||
<value type="QString" key="CMakeProjectManager.MakeStep.AdditionalArguments"></value>
|
||||
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
|
||||
<value type="QString">clean</value>
|
||||
</valuelist>
|
||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Clean</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
|
||||
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
|
||||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Release with Debug Information</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.CMakeBuildConfiguration</value>
|
||||
</valuemap>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.3">
|
||||
<valuelist type="QVariantList" key="CMake.Configuration">
|
||||
<value type="QString">CMAKE_BUILD_TYPE:STRING=MinSizeRel</value>
|
||||
<value type="QString">CMAKE_CXX_COMPILER:STRING=%{Compiler:Executable:Cxx}</value>
|
||||
<value type="QString">CMAKE_C_COMPILER:STRING=%{Compiler:Executable:C}</value>
|
||||
<value type="QString">CMAKE_PREFIX_PATH:STRING=%{Qt:QT_INSTALL_PREFIX}</value>
|
||||
<value type="QString">QT_QMAKE_EXECUTABLE:STRING=%{Qt:qmakeExecutable}</value>
|
||||
</valuelist>
|
||||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/anand/works/sevana/platform/rtphone/src/libs/build-libevs-Desktop_Qt_5_14_0_GCC_64bit-MinSizeRel</value>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||
<value type="QString" key="CMakeProjectManager.MakeStep.AdditionalArguments"></value>
|
||||
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
|
||||
<value type="QString">all</value>
|
||||
</valuelist>
|
||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
|
||||
</valuemap>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||
<value type="QString" key="CMakeProjectManager.MakeStep.AdditionalArguments"></value>
|
||||
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
|
||||
<value type="QString">clean</value>
|
||||
</valuelist>
|
||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Clean</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
|
||||
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
|
||||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Minimum Size Release</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.CMakeBuildConfiguration</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.Target.BuildConfigurationCount">4</value>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
||||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Deploy</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.PluginSettings"/>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
|
||||
<value type="QString" key="Analyzer.Perf.CallgraphMode">dwarf</value>
|
||||
<valuelist type="QVariantList" key="Analyzer.Perf.Events">
|
||||
<value type="QString">cpu-cycles</value>
|
||||
</valuelist>
|
||||
<valuelist type="QVariantList" key="Analyzer.Perf.ExtraArguments"/>
|
||||
<value type="int" key="Analyzer.Perf.Frequency">250</value>
|
||||
<valuelist type="QVariantList" key="Analyzer.Perf.RecordArguments">
|
||||
<value type="QString">-e</value>
|
||||
<value type="QString">cpu-cycles</value>
|
||||
<value type="QString">--call-graph</value>
|
||||
<value type="QString">dwarf,4096</value>
|
||||
<value type="QString">-F</value>
|
||||
<value type="QString">250</value>
|
||||
</valuelist>
|
||||
<value type="QString" key="Analyzer.Perf.SampleMode">-F</value>
|
||||
<value type="bool" key="Analyzer.Perf.Settings.UseGlobalSettings">true</value>
|
||||
<value type="int" key="Analyzer.Perf.StackSize">4096</value>
|
||||
<value type="bool" key="Analyzer.QmlProfiler.AggregateTraces">false</value>
|
||||
<value type="bool" key="Analyzer.QmlProfiler.FlushEnabled">false</value>
|
||||
<value type="uint" key="Analyzer.QmlProfiler.FlushInterval">1000</value>
|
||||
<value type="QString" key="Analyzer.QmlProfiler.LastTraceFile"></value>
|
||||
<value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
|
||||
<valuelist type="QVariantList" key="Analyzer.Valgrind.AddedSuppressionFiles"/>
|
||||
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectBusEvents">false</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectSystime">false</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableBranchSim">false</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableCacheSim">false</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableEventToolTips">true</value>
|
||||
<value type="double" key="Analyzer.Valgrind.Callgrind.MinimumCostRatio">0.01</value>
|
||||
<value type="double" key="Analyzer.Valgrind.Callgrind.VisualisationMinimumCostRatio">10</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.FilterExternalIssues">true</value>
|
||||
<value type="QString" key="Analyzer.Valgrind.KCachegrindExecutable">kcachegrind</value>
|
||||
<value type="int" key="Analyzer.Valgrind.LeakCheckOnFinish">1</value>
|
||||
<value type="int" key="Analyzer.Valgrind.NumCallers">25</value>
|
||||
<valuelist type="QVariantList" key="Analyzer.Valgrind.RemovedSuppressionFiles"/>
|
||||
<value type="int" key="Analyzer.Valgrind.SelfModifyingCodeDetection">0</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.ShowReachable">false</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.TrackOrigins">false</value>
|
||||
<value type="QString" key="Analyzer.Valgrind.ValgrindExecutable">valgrind</value>
|
||||
<valuelist type="QVariantList" key="Analyzer.Valgrind.VisibleErrorKinds">
|
||||
<value type="int">0</value>
|
||||
<value type="int">1</value>
|
||||
<value type="int">2</value>
|
||||
<value type="int">3</value>
|
||||
<value type="int">4</value>
|
||||
<value type="int">5</value>
|
||||
<value type="int">6</value>
|
||||
<value type="int">7</value>
|
||||
<value type="int">8</value>
|
||||
<value type="int">9</value>
|
||||
<value type="int">10</value>
|
||||
<value type="int">11</value>
|
||||
<value type="int">12</value>
|
||||
<value type="int">13</value>
|
||||
<value type="int">14</value>
|
||||
</valuelist>
|
||||
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
|
||||
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
|
||||
<value type="QString" key="ProjectExplorer.CustomExecutableRunConfiguration.Executable"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.CustomExecutableRunConfiguration</value>
|
||||
<value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey"></value>
|
||||
<value type="QString" key="RunConfiguration.Arguments"></value>
|
||||
<value type="bool" key="RunConfiguration.Arguments.multi">false</value>
|
||||
<value type="QString" key="RunConfiguration.OverrideDebuggerStartup"></value>
|
||||
<value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
|
||||
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
|
||||
<value type="bool" key="RunConfiguration.UseMultiProcess">false</value>
|
||||
<value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
|
||||
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
|
||||
<value type="QString" key="RunConfiguration.WorkingDirectory"></value>
|
||||
<value type="QString" key="RunConfiguration.WorkingDirectory.default"></value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
|
||||
</valuemap>
|
||||
</data>
|
||||
<data>
|
||||
<variable>ProjectExplorer.Project.TargetCount</variable>
|
||||
<value type="int">1</value>
|
||||
</data>
|
||||
<data>
|
||||
<variable>ProjectExplorer.Project.Updater.FileVersion</variable>
|
||||
<value type="int">22</value>
|
||||
</data>
|
||||
<data>
|
||||
<variable>Version</variable>
|
||||
<value type="int">22</value>
|
||||
</data>
|
||||
</qtcreator>
|
||||
@@ -1,211 +0,0 @@
|
||||
/********************************************************************************
|
||||
*
|
||||
* File : log2.c
|
||||
* Purpose : Computes log2(L_x)
|
||||
*
|
||||
********************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
********************************************************************************
|
||||
* INCLUDE FILES
|
||||
********************************************************************************
|
||||
*/
|
||||
#include "stl.h"
|
||||
#include "math_op.h"
|
||||
#include <assert.h>
|
||||
#include "rom_basic_math.h"
|
||||
#include "options.h"
|
||||
|
||||
#define LW_SIGN (Word32)0x80000000 /* sign bit */
|
||||
#define LW_MIN (Word32)0x80000000
|
||||
#define LW_MAX (Word32)0x7fffffff
|
||||
|
||||
#define SW_SIGN (Word16)0x8000 /* sign bit for Word16 type */
|
||||
#define SW_MIN (Word16)0x8000 /* smallest Ram */
|
||||
#define SW_MAX (Word16)0x7fff /* largest Ram */
|
||||
|
||||
|
||||
/*
|
||||
********************************************************************************
|
||||
* PUBLIC PROGRAM CODE
|
||||
********************************************************************************
|
||||
*/
|
||||
|
||||
/*************************************************************************
|
||||
*
|
||||
* FUNCTION: Log2_norm_lc()
|
||||
*
|
||||
* PURPOSE: Computes log2(L_x, exp), where L_x is positive and
|
||||
* normalized, and exp is the normalisation exponent
|
||||
* If L_x is negative or zero, the result is 0.
|
||||
*
|
||||
* DESCRIPTION:
|
||||
* The function Log2(L_x) is approximated by a table and linear
|
||||
* interpolation. The following steps are used to compute Log2(L_x)
|
||||
*
|
||||
* 1- exponent = 30-norm_exponent
|
||||
* 2- i = bit25-b31 of L_x; 32<=i<=63 (because of normalization).
|
||||
* 3- a = bit10-b24
|
||||
* 4- i -=32
|
||||
* 5- fraction = table[i]<<16 - (table[i] - table[i+1]) * a * 2
|
||||
*
|
||||
*************************************************************************/
|
||||
Word16 Log2_norm_lc ( /* (o) : Fractional part of Log2. (range: 0<=val<1) */
|
||||
Word32 L_x /* (i) : input value (normalized) */
|
||||
)
|
||||
{
|
||||
Word16 i, a;
|
||||
Word16 y;
|
||||
|
||||
if (L_x <= 0)
|
||||
L_x = L_deposit_h(0x4000);
|
||||
|
||||
L_x = L_shr (L_x, 9);
|
||||
a = extract_l (L_x); /* Extract b10-b24 of fraction */
|
||||
a = lshr(a, 1);
|
||||
|
||||
i = mac_r(L_x, -32*2-1, 16384); /* Extract b25-b31 minus 32 */
|
||||
|
||||
y = mac_r(L_table_Log2_norm_lc[i], table_diff_Log2_norm_lc[i], a); /* table[i] << 16 - diff*a*2 */
|
||||
|
||||
return y;
|
||||
}
|
||||
|
||||
Word32 log10_fx(Word32 Linput)
|
||||
{
|
||||
Word16 n1, frac, p1, p2, q1;
|
||||
Word32 Ltemp1, Ltemp2;
|
||||
Word32 L_tmp;
|
||||
|
||||
if (Linput<=0) return(LW_MIN);
|
||||
n1=norm_l(Linput);
|
||||
Ltemp1=(Word32)L_shl(Linput,n1);
|
||||
|
||||
Ltemp2=L_mult(extract_h(Ltemp1),0x40);
|
||||
frac=extract_l(Ltemp2);
|
||||
|
||||
p1=log2_tab[sub(extract_h(Ltemp2),0x20)];
|
||||
p2=log2_tab[sub(extract_h(Ltemp2),0x1F)];
|
||||
Ltemp2=L_mult(n1,0x200);
|
||||
n1=extract_l(Ltemp2);
|
||||
|
||||
Ltemp1=L_add(L_deposit_h(p1),0x8000); /* Add rounding bit */
|
||||
|
||||
IF(frac >= 0)
|
||||
{
|
||||
Ltemp1=L_sub(Ltemp1,(Word32)L_mult0(p1,frac));
|
||||
Ltemp1=L_add(Ltemp1,(Word32)L_mult0(p2,frac));
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
L_tmp = L_add(65536,frac);
|
||||
L_tmp = L_tmp*p1;
|
||||
Ltemp1=L_sub(Ltemp1,L_tmp);
|
||||
|
||||
L_tmp = L_add(65536,frac);
|
||||
L_tmp = L_tmp*p2;
|
||||
Ltemp1=L_add(Ltemp1,L_tmp);
|
||||
}
|
||||
q1=extract_h(Ltemp1);
|
||||
Ltemp1=L_mult(q1,0x6054);
|
||||
Ltemp1=L_msu(Ltemp1,0x6054,n1);
|
||||
return(L_shr(Ltemp1,1));
|
||||
|
||||
}
|
||||
|
||||
Word32 pow_10(Word32 x , Word16 *Q)
|
||||
{
|
||||
Word16 xl,xh, t1, t2, n;
|
||||
Word32 Ltemp1;
|
||||
Word32 Lacc;
|
||||
Word32 L_tmp;
|
||||
Word16 n1,i;
|
||||
Word16 count = 0;
|
||||
|
||||
move16();;
|
||||
|
||||
xl=extract_l(x);
|
||||
xh=extract_h(x);
|
||||
|
||||
IF(xl < 0)
|
||||
{
|
||||
L_tmp = L_add(65536,xl);
|
||||
Ltemp1=(Word32) (0x6a4d*L_tmp );
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
Ltemp1=L_mult0(0x6a4d,xl);
|
||||
}
|
||||
Ltemp1=L_add(L_shr(Ltemp1,16),L_shr(L_mult(xh,0x6a4d),1));
|
||||
|
||||
|
||||
Lacc=L_sub(-1L, Ltemp1); /* Lacc=~Lacc, 1's complement */
|
||||
t1=extract_l(L_shr(Lacc,7));
|
||||
|
||||
Ltemp1=L_shr(Ltemp1,7);
|
||||
n1 = extract_h(Ltemp1);
|
||||
n=sub(n1,14);
|
||||
*Q = 14; move16();
|
||||
IF(t1<0)
|
||||
{
|
||||
L_tmp = L_add(65536,t1);
|
||||
t2=extract_h(L_tmp*L_tmp);
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
t2=extract_h(L_mult0(t1,t1));
|
||||
}
|
||||
|
||||
Lacc = L_deposit_h(0x1FEF);
|
||||
IF(t2 < 0)
|
||||
{
|
||||
L_tmp = L_add(65536,t2);
|
||||
Lacc = L_add(Lacc,(Word32)(L_tmp*0x057C));
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
Lacc = L_add(Lacc,(Word32)L_mult0(t2,0x057C));
|
||||
}
|
||||
|
||||
IF(t1 < 0)
|
||||
{
|
||||
L_tmp = L_add(65536,t1);
|
||||
Lacc = L_sub(Lacc,(Word32)(L_tmp*0x155C));
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
Lacc = L_sub(Lacc,(Word32)L_mult0(t1,0x155C));
|
||||
}
|
||||
|
||||
L_tmp = Lacc;
|
||||
FOR(i =1 ;i <= n ;i++)
|
||||
{
|
||||
Overflow = 0; move16();
|
||||
L_tmp = L_shl(L_tmp,i);
|
||||
IF(Overflow)
|
||||
{
|
||||
count = add(count,1);
|
||||
}
|
||||
}
|
||||
*Q = sub(*Q,count); move16();
|
||||
|
||||
return(L_shl(Lacc,sub(n,count)));
|
||||
|
||||
}
|
||||
|
||||
Word16 Log2_lc( /* (o) : Fractional part of Log2. (range: 0<=val<1) */
|
||||
Word32 L_x, /* (i) : input value */
|
||||
Word16 *exponent /* (o) : Integer part of Log2. (range: 0<=val<=30) */
|
||||
)
|
||||
{
|
||||
Word16 exp;
|
||||
|
||||
if (L_x <= 0)
|
||||
L_x = L_deposit_l(0x1);
|
||||
|
||||
exp = norm_l (L_x);
|
||||
*exponent = sub(30, exp); move16();
|
||||
|
||||
return Log2_norm_lc(L_shl(L_x, exp));
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
/********************************************************************************
|
||||
*
|
||||
* File : log2.h
|
||||
* Purpose : Computes log2(L_x)
|
||||
*
|
||||
********************************************************************************
|
||||
*/
|
||||
#ifndef log2_h
|
||||
#define log2_h "$Id $"
|
||||
|
||||
/*
|
||||
********************************************************************************
|
||||
* INCLUDE FILES
|
||||
********************************************************************************
|
||||
*/
|
||||
#include "typedef.h"
|
||||
#include "log2.h"
|
||||
|
||||
/*
|
||||
********************************************************************************
|
||||
* DEFINITION OF DATA TYPES
|
||||
********************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
********************************************************************************
|
||||
* DECLARATION OF PROTOTYPES
|
||||
********************************************************************************
|
||||
*/
|
||||
Word16 Log2_norm_lc ( /* (o) : Fractional part of Log2. (range: 0<=val<1) */
|
||||
Word32 L_x /* (i) : input value (normalized) */
|
||||
);
|
||||
|
||||
Word32 log10_fx(Word32 Linput);
|
||||
Word32 pow_10(Word32 x, Word16 *Q);
|
||||
Word16 Log2_lc( /* (o) : Fractional part of Log2. (range: 0<=val<1) */
|
||||
Word32 L_x, /* (i) : input value */
|
||||
Word16 *exponent /* (o) : Integer part of Log2. (range: 0<=val<=30) */
|
||||
);
|
||||
#endif
|
||||
@@ -1,77 +0,0 @@
|
||||
/*#include "options.h" */
|
||||
#include "stl.h"
|
||||
#ifdef ALLOW_40bits
|
||||
#include "enh40.h"
|
||||
#endif
|
||||
#include "oper_32b.h"
|
||||
|
||||
/* 32x16 multiply: */
|
||||
Word32 Mult_32_16(Word32 a, Word16 b)
|
||||
{
|
||||
Word32 result;
|
||||
#ifdef ALLOW_40bits /* if activated; need 40 bits basic-op files */
|
||||
UWord16 lo;
|
||||
/* use Mpy_32_16_ss(): */
|
||||
Mpy_32_16_ss(a, b, &result, &lo);
|
||||
#else
|
||||
Word16 lo, hi;
|
||||
/* do things by hand: */
|
||||
lo = L_Extract_lc(a, &hi);
|
||||
result = Mpy_32_16(hi, lo, b);
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
/* 32x32 multiply: */
|
||||
Word32 Mult_32_32(Word32 a, Word32 b)
|
||||
{
|
||||
Word32 result;
|
||||
#ifdef ALLOW_40bits /* if activated; need 40 bits basic-op files */
|
||||
UWord32 lo;
|
||||
/* use Mpy_32_32_ss(): */
|
||||
Mpy_32_32_ss(a, b, &result, &lo);
|
||||
#else
|
||||
Word16 hi, lo, b_hi, b_lo;
|
||||
/* do things by hand: */
|
||||
lo = L_Extract_lc(a, &hi);
|
||||
b_lo = L_Extract_lc(b, &b_hi);
|
||||
result = Mpy_32(hi, lo, b_hi, b_lo);
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
/* 32x16 multiply-accumulate: */
|
||||
Word32 Madd_32_16(Word32 L_num, Word32 a, Word16 b)
|
||||
{
|
||||
Word32 result;
|
||||
#ifdef ALLOW_40bits /* if activated; need 40 bits basic-op files */
|
||||
UWord16 lo;
|
||||
/* use Mpy_32_16_ss(): */
|
||||
Mpy_32_16_ss(a, b, &result, &lo);
|
||||
result = L_add(L_num, result);
|
||||
#else
|
||||
Word16 lo, hi;
|
||||
/* do things by hand: */
|
||||
lo = L_Extract_lc(a, &hi);
|
||||
result = Mac_32_16(L_num, hi, lo, b);
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
/* 32x16 multiply-substract: */
|
||||
Word32 Msub_32_16(Word32 L_num, Word32 a, Word16 b)
|
||||
{
|
||||
Word32 result;
|
||||
#ifdef ALLOW_40bits /* if activated; need 40 bits basic-op files */
|
||||
UWord16 lo;
|
||||
/* use Mpy_32_16_ss(): */
|
||||
Mpy_32_16_ss(a, b, &result, &lo);
|
||||
result = L_sub(L_num, result);
|
||||
#else
|
||||
Word16 lo, hi;
|
||||
/* do things by hand: */
|
||||
lo = L_Extract_lc(a, &hi);
|
||||
result = Msu_32_16(L_num, hi, lo, b);
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
#ifndef _MATH_32_H_
|
||||
#define _MATH_32_H_
|
||||
|
||||
#include "typedef.h"
|
||||
#include "basop32.h"
|
||||
|
||||
extern Word32 Mult_32_16(Word32 a, Word16 b);
|
||||
extern Word32 Madd_32_16(Word32 L_num, Word32 a, Word16 b);
|
||||
extern Word32 Msub_32_16(Word32 L_num, Word32 a, Word16 b);
|
||||
extern Word32 Mult_32_32(Word32 a, Word32 b);
|
||||
|
||||
#endif
|
||||
@@ -1,359 +0,0 @@
|
||||
/*___________________________________________________________________________
|
||||
| |
|
||||
| This file contains mathematic operations in fixed point. |
|
||||
| |
|
||||
| Isqrt() : inverse square root (16 bits precision). |
|
||||
| Pow2() : 2^x (16 bits precision). |
|
||||
| Log2() : log2 (16 bits precision). |
|
||||
| Dot_product() : scalar product of <x[],y[]> |
|
||||
| |
|
||||
| In this file, the values use theses representations: |
|
||||
| |
|
||||
| Word32 L_32 : standard signed 32 bits format |
|
||||
| Word16 hi, lo : L_32 = hi<<16 + lo<<1 (DPF - Double Precision Format) |
|
||||
| Word32 frac, Word16 exp : L_32 = frac << exp-31 (normalised format) |
|
||||
| Word16 int, frac : L_32 = int.frac (fractional format) |
|
||||
|___________________________________________________________________________|
|
||||
*/
|
||||
|
||||
#include "stl.h"
|
||||
#include "math_op.h"
|
||||
#include "rom_basic_math.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/*___________________________________________________________________________
|
||||
| |
|
||||
| Function Name : Isqrt |
|
||||
| |
|
||||
| Compute 1/sqrt(L_x). |
|
||||
| if L_x is negative or zero, result is 1 (7fffffff). |
|
||||
|---------------------------------------------------------------------------|
|
||||
| Algorithm: |
|
||||
| |
|
||||
| 1- Normalization of L_x. |
|
||||
| 2- call Isqrt_lc(L_x, exponant) |
|
||||
| 3- L_y = L_x << exponant |
|
||||
|___________________________________________________________________________|
|
||||
*/
|
||||
Word32 Isqrt( /* (o) Q31 : output value (range: 0<=val<1) */
|
||||
Word32 L_x /* (i) Q0 : input value (range: 0<=val<=7fffffff) */
|
||||
)
|
||||
{
|
||||
Word16 exp;
|
||||
Word32 L_y;
|
||||
|
||||
exp = norm_l(L_x);
|
||||
L_x = L_shl(L_x, exp); /* L_x is normalized */
|
||||
exp = sub(31, exp);
|
||||
|
||||
L_x = Isqrt_lc(L_x, &exp);
|
||||
|
||||
L_y = L_shl(L_x, exp); /* denormalization */
|
||||
|
||||
return (L_y);
|
||||
}
|
||||
|
||||
/*___________________________________________________________________________
|
||||
| |
|
||||
| Function Name : Isqrt_lc |
|
||||
| |
|
||||
| Compute 1/sqrt(value). |
|
||||
| if value is negative or zero, result is 1 (frac=7fffffff, exp=0). |
|
||||
|---------------------------------------------------------------------------|
|
||||
| Algorithm: |
|
||||
| |
|
||||
| The function 1/sqrt(value) is approximated by a table and linear |
|
||||
| interpolation. |
|
||||
| |
|
||||
| 1- If exponant is odd then shift fraction right once. |
|
||||
| 2- exponant = -((exponant-1)>>1) |
|
||||
| 3- i = bit25-b30 of fraction, 16 <= i <= 63 ->because of normalization. |
|
||||
| 4- a = bit10-b24 |
|
||||
| 5- i -=16 |
|
||||
| 6- fraction = table[i]<<16 - (table[i] - table[i+1]) * a * 2 |
|
||||
|___________________________________________________________________________|
|
||||
*/
|
||||
Word32 Isqrt_lc(
|
||||
Word32 frac, /* (i) Q31: normalized value (1.0 < frac <= 0.5) */
|
||||
Word16 * exp /* (i/o) : exponent (value = frac x 2^exponent) */
|
||||
)
|
||||
{
|
||||
Word16 i, a;
|
||||
Word32 L_tmp;
|
||||
|
||||
IF (frac <= (Word32) 0)
|
||||
{
|
||||
*exp = 0; move16();
|
||||
return 0x7fffffff; /*0x7fffffff*/
|
||||
}
|
||||
|
||||
/* If exponant odd -> shift right by 10 (otherwise 9) */
|
||||
L_tmp = L_shr(frac, shift_Isqrt_lc[s_and(*exp, 1)]);
|
||||
|
||||
/* 1) -16384 to shift left and change sign */
|
||||
/* 2) 32768 to Add 1 to Exponent like it was divided by 2 */
|
||||
/* 3) We let the mac_r add another 0.5 because it imitates */
|
||||
/* the behavior of shr on negative number that should */
|
||||
/* not be rounded towards negative infinity. */
|
||||
/* It replaces: */
|
||||
/* *exp = negate(shr(sub(*exp, 1), 1)); move16(); */
|
||||
*exp = mac_r(32768, *exp, -16384); move16();
|
||||
|
||||
a = extract_l(L_tmp); /* Extract b10-b24 */
|
||||
a = lshr(a, 1);
|
||||
|
||||
i = mac_r(L_tmp, -16*2-1, 16384); /* Extract b25-b31 minus 16 */
|
||||
|
||||
L_tmp = L_msu(L_table_isqrt[i], table_isqrt_diff[i], a);/* table[i] << 16 - diff*a*2 */
|
||||
|
||||
return L_tmp;
|
||||
}
|
||||
|
||||
/*___________________________________________________________________________
|
||||
| |
|
||||
| Function Name : Pow2() |
|
||||
| |
|
||||
| L_x = pow(2.0, exponant.fraction) (exponant = interger part) |
|
||||
| = pow(2.0, 0.fraction) << exponant |
|
||||
|---------------------------------------------------------------------------|
|
||||
| Algorithm: |
|
||||
| |
|
||||
| The function Pow2(L_x) is approximated by a table and linear |
|
||||
| interpolation. |
|
||||
| |
|
||||
| 1- i = bit10-b15 of fraction, 0 <= i <= 31 |
|
||||
| 2- a = bit0-b9 of fraction |
|
||||
| 3- L_x = table[i]<<16 - (table[i] - table[i+1]) * a * 2 |
|
||||
| 4- L_x = L_x >> (30-exponant) (with rounding) |
|
||||
|___________________________________________________________________________|
|
||||
*/
|
||||
|
||||
Word32 Pow2( /* (o) Q0 : result (range: 0<=val<=0x7fffffff) */
|
||||
Word16 exponant, /* (i) Q0 : Integer part. (range: 0<=val<=30) */
|
||||
Word16 fraction /* (i) Q15 : Fractionnal part. (range: 0.0<=val<1.0) */
|
||||
)
|
||||
{
|
||||
Word16 exp, i, a;
|
||||
Word32 L_x;
|
||||
|
||||
|
||||
|
||||
i = mac_r(-32768, fraction, 32); /* Extract b10-b16 of fraction */
|
||||
a = s_and(fraction, 0x3ff); /* Extract b0-b9 of fraction */
|
||||
|
||||
L_x = L_deposit_h(table_pow2[i]); /* table[i] << 16 */
|
||||
L_x = L_mac(L_x, table_pow2_diff_x32[i], a);/* L_x -= diff*a*2 */
|
||||
|
||||
exp = sub(30, exponant);
|
||||
|
||||
L_x = L_shr_r(L_x, exp);
|
||||
|
||||
|
||||
return L_x;
|
||||
}
|
||||
|
||||
/*___________________________________________________________________________
|
||||
| |
|
||||
| Function Name : Dot_product12() |
|
||||
| |
|
||||
| Compute scalar product of <x[],y[]> using accumulator. |
|
||||
| |
|
||||
| The result is normalized (in Q31) with exponent (0..30). |
|
||||
|---------------------------------------------------------------------------|
|
||||
| Algorithm: |
|
||||
| |
|
||||
| dot_product = sum(x[i]*y[i]) i=0..N-1 |
|
||||
|___________________________________________________________________________|
|
||||
*/
|
||||
|
||||
Word32 Dot_product12( /* (o) Q31: normalized result (1 < val <= -1) */
|
||||
const Word16 x[], /* (i) 12bits: x vector */
|
||||
const Word16 y[], /* (i) 12bits: y vector */
|
||||
const Word16 lg, /* (i) : vector length */
|
||||
Word16 * exp /* (o) : exponent of result (0..+30) */
|
||||
)
|
||||
{
|
||||
Word16 i, sft;
|
||||
Word32 L_sum;
|
||||
|
||||
L_sum = L_mac(1, x[0], y[0]);
|
||||
FOR (i = 1; i < lg; i++)
|
||||
L_sum = L_mac(L_sum, x[i], y[i]);
|
||||
|
||||
/* Normalize acc in Q31 */
|
||||
|
||||
sft = norm_l(L_sum);
|
||||
L_sum = L_shl(L_sum, sft);
|
||||
|
||||
*exp = sub(30, sft); move16(); /* exponent = 0..30 */
|
||||
|
||||
return L_sum;
|
||||
}
|
||||
|
||||
/*___________________________________________________________________________
|
||||
| |
|
||||
| Function Name : Energy_scale() |
|
||||
| |
|
||||
| Compute energy of signal (scaling the input if specified) |
|
||||
| |
|
||||
| The result is normalized (in Q31) with exponent (0..30). |
|
||||
|___________________________________________________________________________|
|
||||
*/
|
||||
|
||||
Word32 Energy_scale( /* (o) : Q31: normalized result (1 < val <= -1) */
|
||||
const Word16 x[], /* (i) : input vector x */
|
||||
const Word16 lg, /* (i) : vector length */
|
||||
Word16 expi, /* (i) : exponent of input */
|
||||
Word16 *exp /* (o) : exponent of result (0..+30) */
|
||||
)
|
||||
{
|
||||
Word16 i, sft, tmp;
|
||||
Word32 L_sum;
|
||||
|
||||
|
||||
L_sum = 0; /* just to avoid superflous compiler warning about uninitialized use of L_sum */
|
||||
|
||||
IF (expi == 0)
|
||||
{
|
||||
L_sum = L_mac(1, x[0], x[0]);
|
||||
FOR (i = 1; i < lg; i++)
|
||||
{
|
||||
L_sum = L_mac(L_sum, x[i], x[i]);
|
||||
}
|
||||
}
|
||||
IF (expi < 0)
|
||||
{
|
||||
sft = lshl(-32768 /* 0x8000 */, expi);
|
||||
tmp = mult_r(x[0], sft);
|
||||
L_sum = L_mac(1, tmp, tmp);
|
||||
FOR (i = 1; i < lg; i++)
|
||||
{
|
||||
tmp = mult_r(x[i], sft);
|
||||
L_sum = L_mac(L_sum, tmp, tmp);
|
||||
}
|
||||
}
|
||||
IF (expi > 0)
|
||||
{
|
||||
tmp = shl(x[0], expi);
|
||||
L_sum = L_mac(1, tmp, tmp);
|
||||
FOR (i = 1; i < lg; i++)
|
||||
{
|
||||
tmp = shl(x[i], expi);
|
||||
L_sum = L_mac(L_sum, tmp, tmp);
|
||||
}
|
||||
}
|
||||
|
||||
/* Normalize acc in Q31 */
|
||||
|
||||
sft = norm_l(L_sum);
|
||||
L_sum = L_shl(L_sum, sft);
|
||||
|
||||
*exp = sub(30, sft); move16(); /* exponent = 0..30 */
|
||||
|
||||
|
||||
return L_sum;
|
||||
}
|
||||
|
||||
Word32 Sqrt_l( /* o : output value, Q31 */
|
||||
Word32 L_x, /* i : input value, Q31 */
|
||||
Word16 *exp /* o : right shift to be applied to result, Q1 */
|
||||
)
|
||||
{
|
||||
/*
|
||||
y = sqrt(x)
|
||||
|
||||
x = f * 2^-e, 0.5 <= f < 1 (normalization)
|
||||
|
||||
y = sqrt(f) * 2^(-e/2)
|
||||
|
||||
a) e = 2k --> y = sqrt(f) * 2^-k (k = e div 2,
|
||||
0.707 <= sqrt(f) < 1)
|
||||
b) e = 2k+1 --> y = sqrt(f/2) * 2^-k (k = e div 2,
|
||||
0.5 <= sqrt(f/2) < 0.707)
|
||||
*/
|
||||
|
||||
Word16 e, i, a, tmp;
|
||||
Word32 L_y;
|
||||
|
||||
if (L_x <= 0)
|
||||
{
|
||||
*exp = 0; move16 ();
|
||||
return L_deposit_l(0);
|
||||
}
|
||||
|
||||
e = s_and(norm_l(L_x), 0x7FFE); /* get next lower EVEN norm. exp */
|
||||
L_x = L_shl(L_x, e); /* L_x is normalized to [0.25..1) */
|
||||
*exp = e; move16 (); /* return 2*exponent (or Q1) */
|
||||
|
||||
L_x = L_shr(L_x, 9);
|
||||
a = extract_l(L_x); /* Extract b10-b24 */
|
||||
a = lshr(a, 1);
|
||||
|
||||
i = mac_r(L_x, -16*2-1, 16384); /* Extract b25-b31 minus 16 */
|
||||
|
||||
L_y = L_deposit_h(sqrt_table[i]); /* table[i] << 16 */
|
||||
tmp = sub(sqrt_table[i], sqrt_table[i + 1]); /* table[i] - table[i+1]) */
|
||||
L_y = L_msu(L_y, tmp, a); /* L_y -= tmp*a*2 */
|
||||
|
||||
/* L_y = L_shr (L_y, *exp); */ /* denormalization done by caller */
|
||||
|
||||
return (L_y);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
* L_Frac_sqrtQ31
|
||||
*
|
||||
* Calculate square root from fractional values (Q31 -> Q31)
|
||||
* Uses 32 bit internal representation for precision
|
||||
*---------------------------------------------------------------------------*/
|
||||
Word32 L_Frac_sqrtQ31( /* o : Square root if input */
|
||||
const Word32 x /* i : Input */
|
||||
)
|
||||
{
|
||||
Word32 log2_work;
|
||||
Word16 log2_int, log2_frac;
|
||||
|
||||
test();
|
||||
if (x > 0)
|
||||
{
|
||||
log2_int = norm_l(x);
|
||||
log2_frac = Log2_norm_lc(L_shl(x, log2_int));
|
||||
|
||||
log2_work = L_msu((31+30)*65536L/2, 16384, log2_int);
|
||||
log2_work = L_mac0(log2_work, log2_frac, 1);
|
||||
|
||||
log2_frac = L_Extract_lc(log2_work, &log2_int);
|
||||
|
||||
return Pow2(log2_int, log2_frac);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------------*
|
||||
* Frac_sqrt
|
||||
*
|
||||
* Calculate square root from fractional values (Q15 -> Q15)
|
||||
*----------------------------------------------------------------------------------*/
|
||||
Word16 Frac_sqrt( /* o : Square root if input */
|
||||
const Word16 x /* i : Input */
|
||||
)
|
||||
{
|
||||
return round_fx(L_Frac_sqrtQ31(L_deposit_h(x)));
|
||||
}
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------------*
|
||||
* i_mult2
|
||||
*
|
||||
* Faster Integer Multiplication
|
||||
*----------------------------------------------------------------------------------*/
|
||||
|
||||
Word16 i_mult2 (Word16 a, Word16 b)
|
||||
{
|
||||
return extract_l(L_mult0(a, b));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
/*--------------------------------------------------------------------------*
|
||||
* MATH_OP.H *
|
||||
*--------------------------------------------------------------------------*
|
||||
* Mathematical operations *
|
||||
*--------------------------------------------------------------------------*/
|
||||
#include "oper_32b.h"
|
||||
#include "log2.h"
|
||||
|
||||
Word32 Isqrt( /* (o) Q31 : output value (range: 0<=val<1) */
|
||||
Word32 L_x /* (i) Q0 : input value (range: 0<=val<=7fffffff) */
|
||||
);
|
||||
Word32 Isqrt_lc(
|
||||
Word32 frac, /* (i/o) Q31: normalized value (1.0 < frac <= 0.5) */
|
||||
Word16 * exp /* (i/o) : exponent (value = frac x 2^exponent) */
|
||||
);
|
||||
|
||||
Word32 Pow2( /* (o) Q0 : result (range: 0<=val<=0x7fffffff) */
|
||||
Word16 exponant, /* (i) Q0 : Integer part. (range: 0<=val<=30) */
|
||||
Word16 fraction /* (i) Q15 : Fractionnal part. (range: 0.0<=val<1.0) */
|
||||
);
|
||||
Word32 Dot_product12( /* (o) Q31: normalized result (1 < val <= -1) */
|
||||
const Word16 x[], /* (i) 12bits: x vector */
|
||||
const Word16 y[], /* (i) 12bits: y vector */
|
||||
const Word16 lg, /* (i) : vector length */
|
||||
Word16 * exp /* (o) : exponent of result (0..+30) */
|
||||
);
|
||||
|
||||
Word32 Energy_scale( /* (o) Q31: normalized result (1 < val <= -1) */
|
||||
const Word16 x[], /* (i) 12bits: x vector */
|
||||
const Word16 lg, /* (i) : vector length */
|
||||
Word16 expi, /* (i) : exponent of input */
|
||||
Word16 *exp /* (o) : exponent of result (0..+30) */
|
||||
);
|
||||
|
||||
Word32 Sqrt_l(Word32 L_x, Word16 *exp);
|
||||
|
||||
Word32 L_Frac_sqrtQ31( /* o : Square root if input */
|
||||
const Word32 x /* i : Input */
|
||||
);
|
||||
|
||||
Word16 Frac_sqrt( /* o : Square root if input */
|
||||
const Word16 x /* i : Input */
|
||||
);
|
||||
|
||||
Word16 i_mult2 (Word16 a, Word16 b);
|
||||
|
||||
#include "math_32.h"
|
||||
|
||||
@@ -1,381 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* $Id: oper_32b.c 1094 2014-02-10 17:12:11Z jdr $
|
||||
*
|
||||
* This file contains operations in double precision. *
|
||||
* These operations are not standard double precision operations. *
|
||||
* They are used where single precision is not enough but the full 32 bits *
|
||||
* precision is not necessary. For example, the function Div_32() has a *
|
||||
* 24 bits precision which is enough for our purposes. *
|
||||
* *
|
||||
* The double precision numbers use a special representation: *
|
||||
* *
|
||||
* L_32 = hi<<16 + lo<<1 *
|
||||
* *
|
||||
* L_32 is a 32 bit integer. *
|
||||
* hi and lo are 16 bit signed integers. *
|
||||
* As the low part also contains the sign, this allows fast multiplication. *
|
||||
* *
|
||||
* 0x8000 0000 <= L_32 <= 0x7fff fffe. *
|
||||
* *
|
||||
* We will use DPF (Double Precision Format) in this file to specify *
|
||||
* this special format. *
|
||||
*****************************************************************************
|
||||
*/
|
||||
|
||||
#include "stl.h"
|
||||
#include "math_op.h"
|
||||
|
||||
/*****************************************************************************
|
||||
* *
|
||||
* Function L_Extract() *
|
||||
* *
|
||||
* Extract from a 32 bit integer two 16 bit DPF. *
|
||||
* *
|
||||
* Arguments: *
|
||||
* *
|
||||
* L_32 : 32 bit integer. *
|
||||
* 0x8000 0000 <= L_32 <= 0x7fff ffff. *
|
||||
* hi : b16 to b31 of L_32 *
|
||||
* lo : (L_32 - hi<<16)>>1 *
|
||||
*****************************************************************************
|
||||
*/
|
||||
|
||||
void L_Extract (Word32 L_32, Word16 *hi, Word16 *lo)
|
||||
{
|
||||
*hi = extract_h (L_32);
|
||||
*lo = extract_l (L_msu (L_shr (L_32, 1), *hi, 16384));
|
||||
return;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* *
|
||||
* Function L_Extract_lc() *
|
||||
* *
|
||||
* Extract from a 32 bit integer two 16 bit DPF. *
|
||||
* (lo is returned, store to memory is not accounted for) *
|
||||
* *
|
||||
* Arguments: *
|
||||
* *
|
||||
* L_32 : 32 bit integer. *
|
||||
* 0x8000 0000 <= L_32 <= 0x7fff ffff. *
|
||||
* hi : b16 to b31 of L_32 *
|
||||
* lo : (L_32 - hi<<16)>>1 *
|
||||
*****************************************************************************
|
||||
*/
|
||||
|
||||
Word16 L_Extract_lc (Word32 L_32, Word16 *hi)
|
||||
{
|
||||
*hi = extract_h (L_32);
|
||||
|
||||
return lshr(extract_l(L_32), 1);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* *
|
||||
* Function L_Comp() *
|
||||
* *
|
||||
* Compose from two 16 bit DPF a 32 bit integer. *
|
||||
* *
|
||||
* L_32 = hi<<16 + lo<<1 *
|
||||
* *
|
||||
* Arguments: *
|
||||
* *
|
||||
* hi msb *
|
||||
* lo lsf (with sign) *
|
||||
* *
|
||||
* Return Value : *
|
||||
* *
|
||||
* 32 bit long signed integer (Word32) whose value falls in the *
|
||||
* range : 0x8000 0000 <= L_32 <= 0x7fff fff0. *
|
||||
* *
|
||||
*****************************************************************************
|
||||
*/
|
||||
|
||||
Word32 L_Comp (Word16 hi, Word16 lo)
|
||||
{
|
||||
Word32 L_32;
|
||||
|
||||
L_32 = L_deposit_h (hi);
|
||||
return (L_mac (L_32, lo, 1)); /* = hi<<16 + lo<<1 */
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Function Mpy_32() *
|
||||
* *
|
||||
* Multiply two 32 bit integers (DPF). The result is divided by 2**31 *
|
||||
* *
|
||||
* L_32 = (hi1*hi2)<<1 + ( (hi1*lo2)>>15 + (lo1*hi2)>>15 )<<1 *
|
||||
* *
|
||||
* This operation can also be viewed as the multiplication of two Q31 *
|
||||
* number and the result is also in Q31. *
|
||||
* *
|
||||
* Arguments: *
|
||||
* *
|
||||
* hi1 hi part of first number *
|
||||
* lo1 lo part of first number *
|
||||
* hi2 hi part of second number *
|
||||
* lo2 lo part of second number *
|
||||
* *
|
||||
*****************************************************************************
|
||||
*/
|
||||
|
||||
Word32 Mpy_32 (Word16 hi1, Word16 lo1, Word16 hi2, Word16 lo2)
|
||||
{
|
||||
Word32 L_32;
|
||||
|
||||
L_32 = L_mult (hi1, hi2);
|
||||
L_32 = L_mac (L_32, mult (hi1, lo2), 1);
|
||||
L_32 = L_mac (L_32, mult (lo1, hi2), 1);
|
||||
|
||||
return (L_32);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Function Mac_32() *
|
||||
* *
|
||||
* Multiply two 32 bit integers (DPF). The result is divided by 2**31 *
|
||||
* Adds a 32 bit integer (non DFP) *
|
||||
* *
|
||||
* L_32 = L_num + (hi1*hi2)<<1 + ( (hi1*lo2)>>15 + (lo1*hi2)>>15 )<<1 *
|
||||
* *
|
||||
* This operation can also be viewed as the multiplication of two Q31 *
|
||||
* number and the result is also in Q31. *
|
||||
* *
|
||||
* Arguments: *
|
||||
* *
|
||||
* hi1 hi part of first number *
|
||||
* lo1 lo part of first number *
|
||||
* hi2 hi part of second number *
|
||||
* lo2 lo part of second number *
|
||||
* *
|
||||
*****************************************************************************
|
||||
*/
|
||||
|
||||
Word32 Mac_32 (Word32 L_num, Word16 hi1, Word16 lo1, Word16 hi2, Word16 lo2)
|
||||
{
|
||||
Word32 L_32;
|
||||
|
||||
L_32 = L_mac (L_num, hi1, hi2);
|
||||
L_32 = L_mac (L_32, mult (hi1, lo2), 1);
|
||||
L_32 = L_mac (L_32, mult (lo1, hi2), 1);
|
||||
|
||||
return (L_32);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Function Sqr_32() *
|
||||
* *
|
||||
* Square one 32 bit integer (DPF). The result is divided by 2**31 *
|
||||
* *
|
||||
* L_32 = (hi*hi)<<1 + ( (hi*lo)>>15 *2)<<1 *
|
||||
* *
|
||||
* This operation can also be viewed as the square of one Q31 *
|
||||
* number and the result is also in Q31. *
|
||||
* *
|
||||
* Arguments: *
|
||||
* *
|
||||
* hi1 hi part of first number *
|
||||
* lo1 lo part of first number *
|
||||
* hi2 hi part of second number *
|
||||
* lo2 lo part of second number *
|
||||
* *
|
||||
*****************************************************************************
|
||||
*/
|
||||
|
||||
Word32 Sqr_32 (Word16 hi, Word16 lo)
|
||||
{
|
||||
Word32 L_32;
|
||||
|
||||
L_32 = L_mult (hi, hi);
|
||||
L_32 = L_mac (L_32, mult (hi, lo), 2);
|
||||
|
||||
return (L_32);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Function Sad_32() *
|
||||
* *
|
||||
* Square one 32 bit integer (DPF). The result is divided by 2**31 *
|
||||
* Adds a 32 bit integer (non DFP) *
|
||||
* *
|
||||
* L_32 = L_num + (hi*hi)<<1 + ( (hi*lo)>>15 *2)<<1 *
|
||||
* *
|
||||
* This operation can also be viewed as the square of one Q31 *
|
||||
* number and the result is also in Q31. *
|
||||
* *
|
||||
* Arguments: *
|
||||
* *
|
||||
* hi1 hi part of first number *
|
||||
* lo1 lo part of first number *
|
||||
* hi2 hi part of second number *
|
||||
* lo2 lo part of second number *
|
||||
* *
|
||||
*****************************************************************************
|
||||
*/
|
||||
|
||||
Word32 Sad_32 (Word32 L_num, Word16 hi, Word16 lo)
|
||||
{
|
||||
Word32 L_32;
|
||||
|
||||
L_32 = L_mac (L_num, hi, hi);
|
||||
L_32 = L_mac (L_32, mult (hi, lo), 2);
|
||||
|
||||
return (L_32);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Function Mpy_32_16() *
|
||||
* *
|
||||
* Multiply a 16 bit integer by a 32 bit (DPF). The result is divided *
|
||||
* by 2**15 *
|
||||
* *
|
||||
* *
|
||||
* L_32 = (hi1*lo2)<<1 + ((lo1*lo2)>>15)<<1 *
|
||||
* *
|
||||
* Arguments: *
|
||||
* *
|
||||
* hi hi part of 32 bit number. *
|
||||
* lo lo part of 32 bit number. *
|
||||
* n 16 bit number. *
|
||||
* *
|
||||
*****************************************************************************
|
||||
*/
|
||||
|
||||
Word32 Mpy_32_16 (Word16 hi, Word16 lo, Word16 n)
|
||||
{
|
||||
Word32 L_32;
|
||||
|
||||
L_32 = L_mult (hi, n);
|
||||
L_32 = L_mac (L_32, mult (lo, n), 1);
|
||||
|
||||
return (L_32);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Function Mac_32_16() *
|
||||
* *
|
||||
* Multiply a 16 bit integer by a 32 bit (DPF). The result is divided *
|
||||
* by 2**15 *
|
||||
* Adds a 32 bit integer (non DFP) *
|
||||
* *
|
||||
* *
|
||||
* L_32 = L_num + (hi1*lo2)<<1 + ((lo1*lo2)>>15)<<1 *
|
||||
* *
|
||||
* Arguments: *
|
||||
* *
|
||||
* L_num 32 bit long signed integer (Word32) *
|
||||
* hi hi part of 32 bit number. *
|
||||
* lo lo part of 32 bit number. *
|
||||
* n 16 bit number. *
|
||||
* *
|
||||
*****************************************************************************
|
||||
*/
|
||||
|
||||
Word32 Mac_32_16 (Word32 L_num, Word16 hi, Word16 lo, Word16 n)
|
||||
{
|
||||
Word32 L_32;
|
||||
|
||||
L_32 = L_mac (L_num, hi, n);
|
||||
L_32 = L_mac (L_32, mult (lo, n), 1);
|
||||
|
||||
return (L_32);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Function Msu_32_16() *
|
||||
* *
|
||||
* Substract a 32 bit integer (non DFP) *
|
||||
* Multiply a 16 bit integer by a 32 bit (DPF). The result is divided *
|
||||
* by 2**15 *
|
||||
* *
|
||||
* *
|
||||
* L_32 = L_num - (hi1*lo2)<<1 + ((lo1*lo2)>>15)<<1 *
|
||||
* *
|
||||
* Arguments: *
|
||||
* *
|
||||
* L_num 32 bit long signed integer (Word32) *
|
||||
* hi hi part of 32 bit number. *
|
||||
* lo lo part of 32 bit number. *
|
||||
* n 16 bit number. *
|
||||
* *
|
||||
*****************************************************************************
|
||||
*/
|
||||
|
||||
Word32 Msu_32_16 (Word32 L_num, Word16 hi, Word16 lo, Word16 n)
|
||||
{
|
||||
Word32 L_32;
|
||||
|
||||
L_32 = L_msu (L_num, hi, n);
|
||||
L_32 = L_msu (L_32, mult (lo, n), 1);
|
||||
|
||||
return (L_32);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* *
|
||||
* Function Name : Div_32 *
|
||||
* *
|
||||
* Purpose : *
|
||||
* Fractional integer division of two 32 bit numbers. *
|
||||
* L_num / L_denom. *
|
||||
* L_num and L_denom must be positive and L_num < L_denom. *
|
||||
* L_denom = denom_hi<<16 + denom_lo<<1 *
|
||||
* denom_hi is a normalize number. *
|
||||
* *
|
||||
* Inputs : *
|
||||
* *
|
||||
* L_num *
|
||||
* 32 bit long signed integer (Word32) whose value falls in the *
|
||||
* range : 0x0000 0000 < L_num < L_denom *
|
||||
* *
|
||||
* L_denom = denom_hi<<16 + denom_lo<<1 (DPF) *
|
||||
* *
|
||||
* denom_hi *
|
||||
* 16 bit positive normalized integer whose value falls in the *
|
||||
* range : 0x4000 < hi < 0x7fff *
|
||||
* denom_lo *
|
||||
* 16 bit positive integer whose value falls in the *
|
||||
* range : 0 < lo < 0x7fff *
|
||||
* *
|
||||
* Return Value : *
|
||||
* *
|
||||
* L_div *
|
||||
* 32 bit long signed integer (Word32) whose value falls in the *
|
||||
* range : 0x0000 0000 <= L_div <= 0x7fff ffff. *
|
||||
* *
|
||||
* Algorithm: *
|
||||
* *
|
||||
* - find = 1/L_denom. *
|
||||
* First approximation: approx = 1 / denom_hi *
|
||||
* 1/L_denom = approx * (2.0 - L_denom * approx ) *
|
||||
* *
|
||||
* - result = L_num * (1/L_denom) *
|
||||
*****************************************************************************
|
||||
*/
|
||||
|
||||
Word32 Div_32 (Word32 L_num, Word16 denom_hi, Word16 denom_lo)
|
||||
{
|
||||
Word16 approx, hi, lo, n_hi, n_lo;
|
||||
Word32 L_32;
|
||||
|
||||
/* First approximation: 1 / L_denom = 1/denom_hi */
|
||||
|
||||
approx = div_s ((Word16) 0x3fff, denom_hi);
|
||||
|
||||
/* 1/L_denom = approx * (2.0 - L_denom * approx) */
|
||||
|
||||
L_32 = Msu_32_16 ((Word32) 0x7fffffffL, denom_hi, denom_lo, approx);
|
||||
|
||||
lo = L_Extract_lc (L_32, &hi);
|
||||
L_32 = Mpy_32_16 (hi, lo, approx);
|
||||
|
||||
/* L_num * (1/L_denom) */
|
||||
|
||||
lo = L_Extract_lc (L_32, &hi);
|
||||
n_lo = L_Extract_lc (L_num, &n_hi);
|
||||
L_32 = Mpy_32 (n_hi, n_lo, hi, lo);
|
||||
L_32 = L_shl (L_32, 2);
|
||||
|
||||
return (L_32);
|
||||
}
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
/* Double precision operations */
|
||||
/* $Id: oper_32b.h 1094 2014-02-10 17:12:11Z jdr $ */
|
||||
#ifndef _OPER_32b_H
|
||||
#define _OPER_32b_H
|
||||
|
||||
void L_Extract (Word32 L_32, Word16 *hi, Word16 *lo);
|
||||
Word16 L_Extract_lc (Word32 L_32, Word16 *hi);
|
||||
Word32 L_Comp (Word16 hi, Word16 lo);
|
||||
Word32 Mpy_32 (Word16 hi1, Word16 lo1, Word16 hi2, Word16 lo2);
|
||||
Word32 Mac_32 (Word32 L_num, Word16 hi1, Word16 lo1, Word16 hi2, Word16 lo2);
|
||||
Word32 Sqr_32 (Word16 hi, Word16 lo);
|
||||
Word32 Sad_32 (Word32 L_num, Word16 hi, Word16 lo);
|
||||
Word32 Mpy_32_16 (Word16 hi, Word16 lo, Word16 n);
|
||||
Word32 Mac_32_16 (Word32 L_num, Word16 hi, Word16 lo, Word16 n);
|
||||
Word32 Msu_32_16 (Word32 L_num, Word16 hi, Word16 lo, Word16 n);
|
||||
Word32 Div_32 (Word32 L_num, Word16 denom_hi, Word16 denom_lo);
|
||||
|
||||
#endif
|
||||
@@ -1,91 +0,0 @@
|
||||
#include "options.h" /* Compilation switches */
|
||||
#include "cnst_fx.h" /* Decoder static structure */
|
||||
#include "stl.h"
|
||||
|
||||
/* math_op.c */
|
||||
const Word32 L_table_isqrt[48] =
|
||||
{
|
||||
2147418112L, 2083389440L, 2024669184L, 1970667520L,
|
||||
1920794624L, 1874460672L, 1831403520L, 1791098880L,
|
||||
1753415680L, 1717960704L, 1684602880L, 1653145600L,
|
||||
1623326720L, 1595080704L, 1568276480L, 1542782976L,
|
||||
1518469120L, 1495334912L, 1473183744L, 1451950080L,
|
||||
1431633920L, 1412169728L, 1393491968L, 1375469568L,
|
||||
1358168064L, 1341521920L, 1325465600L, 1309933568L,
|
||||
1294991360L, 1280507904L, 1266548736L, 1252982784L,
|
||||
1239875584L, 1227161600L, 1214775296L, 1202847744L,
|
||||
1191182336L, 1179910144L, 1168965632L, 1158283264L,
|
||||
1147863040L, 1137770496L, 1127940096L, 1118306304L,
|
||||
1108934656L, 1099825152L, 1090912256L, 1082261504L
|
||||
};
|
||||
|
||||
/* table of table_isqrt[i] - table_isqrt[i+1] */
|
||||
const Word16 table_isqrt_diff[48] =
|
||||
{
|
||||
977, 896, 824, 761, 707, 657, 615, 575,
|
||||
541, 509, 480, 455, 431, 409, 389, 371,
|
||||
353, 338, 324, 310, 297, 285, 275, 264,
|
||||
254, 245, 237, 228, 221, 213, 207, 200,
|
||||
194, 189, 182, 178, 172, 167, 163, 159,
|
||||
154, 150, 147, 143, 139, 136, 132, 130
|
||||
};
|
||||
|
||||
const Word16 shift_Isqrt_lc[] = {9,10};
|
||||
|
||||
const Word16 table_pow2[32] =
|
||||
{
|
||||
16384, 16743, 17109, 17484, 17867, 18258, 18658, 19066, 19484, 19911,
|
||||
20347, 20792, 21247, 21713, 22188, 22674, 23170, 23678, 24196, 24726,
|
||||
25268, 25821, 26386, 26964, 27554, 28158, 28774, 29405, 30048, 30706,
|
||||
31379, 32066
|
||||
};
|
||||
|
||||
/* table of table_pow2[i+1] - table_pow2[i] */
|
||||
const Word16 table_pow2_diff_x32[32] =
|
||||
{
|
||||
11488, 11712, 12000, 12256, 12512, 12800, 13056, 13376, 13664, 13952,
|
||||
14240, 14560, 14912, 15200, 15552, 15872, 16256, 16576, 16960, 17344,
|
||||
17696, 18080, 18496, 18880, 19328, 19712, 20192, 20576, 21056, 21536,
|
||||
21984, 22432
|
||||
};
|
||||
|
||||
const Word16 sqrt_table[49] =
|
||||
{
|
||||
16384, 16888, 17378, 17854, 18318, 18770, 19212,
|
||||
19644, 20066, 20480, 20886, 21283, 21674, 22058,
|
||||
22435, 22806, 23170, 23530, 23884, 24232, 24576,
|
||||
24915, 25249, 25580, 25905, 26227, 26545, 26859,
|
||||
27170, 27477, 27780, 28081, 28378, 28672, 28963,
|
||||
29251, 29537, 29819, 30099, 30377, 30652, 30924,
|
||||
31194, 31462, 31727, 31991, 32252, 32511, 32767
|
||||
};
|
||||
|
||||
/* log2.c */
|
||||
const Word32 L_table_Log2_norm_lc[32] =
|
||||
{
|
||||
-32768L, 95322112L, 187793408L, 277577728L,
|
||||
364871680L, 449740800L, 532381696L, 612859904L,
|
||||
691306496L, 767787008L, 842432512L, 915308544L,
|
||||
986546176L, 1056210944L, 1124302848L, 1190887424L,
|
||||
1256095744L, 1319993344L, 1382580224L, 1443921920L,
|
||||
1504083968L, 1563131904L, 1621000192L, 1677885440L,
|
||||
1733722112L, 1788510208L, 1842380800L, 1895399424L,
|
||||
1947435008L, 1998618624L, 2049015808L, 2098626560L
|
||||
};
|
||||
|
||||
const Word16 table_diff_Log2_norm_lc[32] =
|
||||
{
|
||||
1455, 1411, 1370, 1332, 1295, 1261, 1228, 1197,
|
||||
1167, 1139, 1112, 1087, 1063, 1039, 1016, 995,
|
||||
975, 955, 936, 918, 901, 883, 868, 852,
|
||||
836, 822, 809, 794, 781, 769, 757, 744
|
||||
};
|
||||
|
||||
const Word16 log2_tab[33]={
|
||||
0x7800, 0x782D, 0x785A, 0x7884, 0x78AE, 0x78D6, 0x78FE, 0x7924,
|
||||
0x794A, 0x796E, 0x7992, 0x79B4, 0x79D6, 0x79F8, 0x7A18, 0x7A38,
|
||||
0x7A57, 0x7A75, 0x7A93, 0x7AB1, 0x7ACD, 0x7AE9, 0x7B05, 0x7B20,
|
||||
0x7B3B, 0x7B55, 0x7B6F, 0x7B88, 0x7BA1, 0x7BB9, 0x7BD1, 0x7BE9,
|
||||
0x7C00
|
||||
};
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
#include "options.h" /* Compilation switches */
|
||||
#include "cnst_fx.h" /* Decoder static structure */
|
||||
#include "stl.h"
|
||||
|
||||
|
||||
/* math_op.c */
|
||||
extern const Word32 L_table_isqrt[48];
|
||||
|
||||
/* table of table_isqrt[i] - table_isqrt[i+1] */
|
||||
extern const Word16 table_isqrt_diff[48];
|
||||
|
||||
extern const Word16 shift_Isqrt_lc[];
|
||||
|
||||
extern const Word16 table_pow2[32];
|
||||
|
||||
/* table of table_pow2[i+1] - table_pow2[i] */
|
||||
extern const Word16 table_pow2_diff_x32[32];
|
||||
|
||||
extern const Word16 sqrt_table[49];
|
||||
|
||||
/* log2.c */
|
||||
extern const Word32 L_table_Log2_norm_lc[32];
|
||||
|
||||
extern const Word16 table_diff_Log2_norm_lc[32];
|
||||
|
||||
extern const Word16 log2_tab[33];
|
||||
@@ -1,51 +0,0 @@
|
||||
|
||||
Read-me for ITU-T/UGST Basic Operator Module
|
||||
(12.November.2004)
|
||||
|
||||
=============================================================
|
||||
COPYRIGHT NOTE: This source code, and all of its derivations,
|
||||
is subject to the "ITU-T General Public License". Please have
|
||||
it read in the distribution disk, or in the ITU-T
|
||||
Recommendation G.191 on "SOFTWARE TOOLS FOR SPEECH AND AUDIO
|
||||
CODING STANDARDS".
|
||||
=============================================================
|
||||
|
||||
|
||||
The ITU-T/UGST Basic Operator module contails the following files:
|
||||
|
||||
|
||||
General:
|
||||
~~~~~~~~
|
||||
basop.rme: ....... Read-me file for Basic Operator module (this file)
|
||||
|
||||
|
||||
C code: ('model' directory)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
basop32.c: ....... 16/32 bit basic operators
|
||||
basop32.h: ....... Prototypes for basop32.c
|
||||
count.c: ......... Functions for WMOPS computation
|
||||
count.h: ......... Prototypes for count.c
|
||||
typedef.h: ....... Data type definitions
|
||||
typedefs.h: ...... New data type definitions
|
||||
move.h: .......... Move & miscellaneous legacy operators
|
||||
control.c: ....... Control operator internal variable decl.
|
||||
control.h: ....... Control operators
|
||||
enh1632.c: ....... Enhanced 16/32 bit basic operators
|
||||
enh1632.h: ....... Prototypes for enh1632.c
|
||||
enh40.c: ......... 40 bit basic operators
|
||||
enh40.h: ......... Prototypes for enh40.c
|
||||
patch.h: ......... Backward compatibility for operator names
|
||||
stl.h: ........... Main header file
|
||||
|
||||
Demos:
|
||||
~~~~~~
|
||||
Demo programs are not available for this module.
|
||||
|
||||
|
||||
Makefiles
|
||||
~~~~~~~~~
|
||||
Make files are not available for this module.
|
||||
|
||||
|
||||
-- <k-djafarian@ti.com>
|
||||
|
||||
@@ -1,307 +0,0 @@
|
||||
/*
|
||||
===========================================================================
|
||||
File: CONTROL.H v.2.3 - 30.Nov.2009
|
||||
===========================================================================
|
||||
|
||||
ITU-T STL BASIC OPERATORS
|
||||
|
||||
CONTROL FLOW OPERATORS
|
||||
|
||||
History:
|
||||
07 Nov 04 v2.0 Incorporation of new 32-bit / 40-bit / control
|
||||
operators for the ITU-T Standard Tool Library as
|
||||
described in Geneva, 20-30 January 2004 WP 3/16 Q10/16
|
||||
TD 11 document and subsequent discussions on the
|
||||
wp3audio@yahoogroups.com email reflector.
|
||||
March 06 v2.1 Changed to improve portability.
|
||||
|
||||
============================================================================
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _CONTROL_H
|
||||
#define _CONTROL_H
|
||||
|
||||
#include "stl.h"
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Constants and Globals
|
||||
*
|
||||
*****************************************************************************/
|
||||
#if (WMOPS)
|
||||
extern BASIC_OP multiCounter[MAXCOUNTERS];
|
||||
extern int currCounter;
|
||||
|
||||
/* Technical note :
|
||||
* The following 3 variables are only used for correct complexity
|
||||
* evaluation of the following structure :
|
||||
* IF{
|
||||
* ...
|
||||
* } ELSE IF {
|
||||
* ...
|
||||
* } ELSE IF {
|
||||
* ...
|
||||
* }
|
||||
* ...
|
||||
* } ELSE {
|
||||
* ...
|
||||
* }
|
||||
*/
|
||||
extern int funcId_where_last_call_to_else_occurred;
|
||||
extern long funcid_total_wmops_at_last_call_to_else;
|
||||
extern int call_occurred;
|
||||
#endif /* if WMOPS */
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Function Macros
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Function Name : FOR
|
||||
*
|
||||
* Purpose :
|
||||
*
|
||||
* The macro FOR should be used instead of the 'for' C statement.
|
||||
* The complexity is independent of the number of loop iterations that are
|
||||
* performed.
|
||||
*
|
||||
* Complexity weight : 3 (regardless of number of iterations).
|
||||
*
|
||||
*****************************************************************************/
|
||||
#if !(WMOPS)
|
||||
#define FOR( a) for( a)
|
||||
|
||||
#else /* if !(WMOPS) */
|
||||
#define FOR( a) if( incrFor(), 0); else for( a)
|
||||
|
||||
static __inline void incrFor( void) {
|
||||
multiCounter[currCounter].For++;
|
||||
}
|
||||
#endif /* if !(WMOPS) */
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Function Name : WHILE
|
||||
*
|
||||
* Purpose :
|
||||
*
|
||||
* The macro WHILE should be used instead of the 'while' C statement.
|
||||
* The complexity is proportional to the number of loop iterations that
|
||||
* are performed.
|
||||
*
|
||||
* Complexity weight : 4 x 'number of loop iterations'.
|
||||
*
|
||||
*****************************************************************************/
|
||||
#if !(WMOPS)
|
||||
#define WHILE( a) while( a)
|
||||
|
||||
#else /* if !(WMOPS) */
|
||||
#define WHILE( a) while( incrWhile(), a)
|
||||
|
||||
static __inline void incrWhile( void) {
|
||||
multiCounter[currCounter].While++;
|
||||
}
|
||||
#endif /* if !(WMOPS) */
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Function Name : DO
|
||||
*
|
||||
* Purpose :
|
||||
*
|
||||
* The macro DO should be used instead of the 'do' C statement.
|
||||
*
|
||||
* Complexity weight : 0 (complexity counted by WHILE macro).
|
||||
*
|
||||
*****************************************************************************/
|
||||
#if !(WMOPS)
|
||||
#define DO do
|
||||
|
||||
#else /* if !(WMOPS) */
|
||||
#define DO do
|
||||
|
||||
#endif /* if !(WMOPS) */
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Function Name : IF
|
||||
*
|
||||
* Purpose :
|
||||
*
|
||||
* The macro IF should :
|
||||
*
|
||||
* - not be used when :
|
||||
* - the 'if' structure does not have any 'else if' nor 'else' statement
|
||||
* - and it conditions only one DSP basic operations.
|
||||
*
|
||||
* - be used instead of the 'if' C statement in every other case :
|
||||
* - when there is an 'else' or 'else if' statement,
|
||||
* - or when the 'if' conditions several DSP basic operations,
|
||||
* - or when the 'if' conditions a function call.
|
||||
*
|
||||
* Complexity weight : 4
|
||||
*
|
||||
*****************************************************************************/
|
||||
#if !(WMOPS)
|
||||
#define IF( a) if( a)
|
||||
|
||||
#else /* if !(WMOPS) */
|
||||
#define IF( a) if( incrIf(), a)
|
||||
|
||||
static __inline void incrIf( void) {
|
||||
/* Technical note :
|
||||
* If the "IF" operator comes just after an "ELSE", its counter
|
||||
* must not be incremented.
|
||||
*/
|
||||
if ( (currCounter != funcId_where_last_call_to_else_occurred)
|
||||
|| (TotalWeightedOperation() != funcid_total_wmops_at_last_call_to_else)
|
||||
|| (call_occurred == 1))
|
||||
multiCounter[currCounter].If++;
|
||||
|
||||
call_occurred = 0;
|
||||
funcId_where_last_call_to_else_occurred = MAXCOUNTERS;
|
||||
}
|
||||
#endif /* if !(WMOPS) */
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Function Name : ELSE
|
||||
*
|
||||
* Purpose :
|
||||
*
|
||||
* The macro ELSE should be used instead of the 'else' C statement.
|
||||
*
|
||||
* Complexity weight : 4
|
||||
*
|
||||
*****************************************************************************/
|
||||
#if !(WMOPS)
|
||||
#define ELSE else
|
||||
|
||||
#else /* if !(WMOPS) */
|
||||
#define ELSE else if( incrElse(), 0) ; else
|
||||
|
||||
static __inline void incrElse( void) {
|
||||
multiCounter[currCounter].If++;
|
||||
|
||||
/* We keep track of the funcId of the last function
|
||||
* which used ELSE {...} structure.
|
||||
*/
|
||||
funcId_where_last_call_to_else_occurred = currCounter;
|
||||
|
||||
/* We keep track of the number of WMOPS of this funcId
|
||||
* when the ELSE macro was called.
|
||||
*/
|
||||
funcid_total_wmops_at_last_call_to_else = TotalWeightedOperation();
|
||||
|
||||
/* call_occurred is set to 0, in order to count the next IF (if necessary)
|
||||
*/
|
||||
call_occurred=0;
|
||||
}
|
||||
#endif /* if !(WMOPS) */
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Function Name : SWITCH
|
||||
*
|
||||
* Purpose :
|
||||
*
|
||||
* The macro SWITCH should be used instead of the 'switch' C statement.
|
||||
*
|
||||
* Complexity weight : 8
|
||||
*
|
||||
*****************************************************************************/
|
||||
#if !(WMOPS)
|
||||
#define SWITCH( a) switch( a)
|
||||
|
||||
#else /* if !(WMOPS) */
|
||||
#define SWITCH( a) switch( incrSwitch(), a)
|
||||
|
||||
static __inline void incrSwitch( void) {
|
||||
multiCounter[currCounter].Switch++;
|
||||
}
|
||||
#endif /* if !(WMOPS) */
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Function Name : CONTINUE
|
||||
*
|
||||
* Purpose :
|
||||
*
|
||||
* The macro CONTINUE should be used instead of the 'continue' C statement.
|
||||
*
|
||||
* Complexity weight : 4
|
||||
*
|
||||
*****************************************************************************/
|
||||
#if !(WMOPS)
|
||||
#define CONTINUE continue
|
||||
|
||||
#else /* if !(WMOPS) */
|
||||
#define CONTINUE if( incrContinue(), 0); else continue
|
||||
|
||||
static __inline void incrContinue( void) {
|
||||
multiCounter[currCounter].Continue++;
|
||||
}
|
||||
#endif /* if !(WMOPS) */
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Function Name : BREAK
|
||||
*
|
||||
* Purpose :
|
||||
*
|
||||
* The macro BREAK should be used instead of the 'break' C statement.
|
||||
*
|
||||
* Complexity weight : 4
|
||||
*
|
||||
*****************************************************************************/
|
||||
#if !(WMOPS)
|
||||
#define BREAK break
|
||||
|
||||
#else /* if !(WMOPS) */
|
||||
#define BREAK if( incrBreak(), 0) break; else break
|
||||
|
||||
static __inline void incrBreak( void) {
|
||||
multiCounter[currCounter].Break++;
|
||||
}
|
||||
#endif /* if !(WMOPS) */
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Function Name : GOTO
|
||||
*
|
||||
* Purpose :
|
||||
*
|
||||
* The macro GOTO should be used instead of the 'goto' C statement.
|
||||
*
|
||||
* Complexity weight : 4
|
||||
*
|
||||
*****************************************************************************/
|
||||
#if !(WMOPS)
|
||||
#define GOTO goto
|
||||
|
||||
#else /* if !(WMOPS) */
|
||||
#define GOTO if( incrGoto(), 0); else goto
|
||||
|
||||
static __inline void incrGoto( void) {
|
||||
multiCounter[currCounter].Goto++;
|
||||
}
|
||||
#endif /* if !(WMOPS) */
|
||||
|
||||
|
||||
#endif /* _CONTROL_H */
|
||||
|
||||
|
||||
/* end of file */
|
||||
@@ -1,624 +0,0 @@
|
||||
/*
|
||||
===========================================================================
|
||||
File: COUNT.C v.2.3 - 30.Nov.2009
|
||||
===========================================================================
|
||||
|
||||
ITU-T STL BASIC OPERATORS
|
||||
|
||||
COMPLEXITY EVALUATION FUNCTIONS
|
||||
|
||||
History:
|
||||
03 Nov 04 v2.0 Incorporation of new 32-bit / 40-bit / control
|
||||
operators for the ITU-T Standard Tool Library as
|
||||
described in Geneva, 20-30 January 2004 WP 3/16 Q10/16
|
||||
TD 11 document and subsequent discussions on the
|
||||
wp3audio@yahoogroups.com email reflector.
|
||||
norm_s() weight reduced from 15 to 1.
|
||||
norm_l() weight reduced from 30 to 1.
|
||||
L_abs() weight reduced from 2 to 1.
|
||||
L_add() weight reduced from 2 to 1.
|
||||
L_negate() weight reduced from 2 to 1.
|
||||
L_shl() weight reduced from 2 to 1.
|
||||
L_shr() weight reduced from 2 to 1.
|
||||
L_sub() weight reduced from 2 to 1.
|
||||
mac_r() weight reduced from 2 to 1.
|
||||
msu_r() weight reduced from 2 to 1.
|
||||
mult_r() weight reduced from 2 to 1.
|
||||
L_deposit_h() weight reduced from 2 to 1.
|
||||
L_deposit_l() weight reduced from 2 to 1.
|
||||
March 06 v2.1 Changed to improve portability.
|
||||
Dec 06 v2.2 Changed to specify frame rate using setFrameRate()
|
||||
Adding WMOPS_output_avg() for global average computation
|
||||
L_mls() weight of 5.
|
||||
div_l() weight of 32.
|
||||
i_mult() weight of 3.
|
||||
============================================================================
|
||||
*/
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* This file contains functions for the automatic complexity calculation
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "stl.h"
|
||||
|
||||
#ifdef WMOPS
|
||||
static double frameRate = FRAME_RATE; /* default value : 10 ms */
|
||||
#endif /* ifdef WMOPS */
|
||||
|
||||
#ifdef WMOPS
|
||||
/* Global counter variable for calculation of complexity weight */
|
||||
BASIC_OP multiCounter[MAXCOUNTERS];
|
||||
int currCounter=0; /* Zero equals global counter */
|
||||
#endif /* ifdef WMOPS */
|
||||
|
||||
#ifdef WMOPS
|
||||
void setFrameRate(int samplingFreq, int frameLength)
|
||||
{
|
||||
if(frameLength > 0)
|
||||
{
|
||||
frameRate = samplingFreq / 1000000.0 / frameLength;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
#endif /* ifdef WMOPS */
|
||||
|
||||
#ifdef WMOPS
|
||||
/*
|
||||
* Below list is used for displaying the code profiling information in
|
||||
* the file which name is defined by CODE_PROFILE_FILENAME.
|
||||
* For further details see generic_WMOPS_output() function.
|
||||
* Attention, the ordering in this table must be kept in synchronisation
|
||||
* with the structure definition BASIC_OP.
|
||||
*/
|
||||
char* BasicOperationList[] =
|
||||
{
|
||||
"add", "sub", "abs_s", "shl", "shr",
|
||||
"extract_h", "extract_l", "mult", "L_mult", "negate",
|
||||
"round", "L_mac", "L_msu", "L_macNs", "L_msuNs",
|
||||
"L_add", "L_sub", "L_add_c", "L_sub_c", "L_negate",
|
||||
"L_shl", "L_shr", "mult_r", "shr_r", "mac_r",
|
||||
|
||||
"msu_r", "L_deposit_h", "L_deposit_l", "L_shr_r", "L_abs",
|
||||
"L_sat", "norm_s", "div_s", "norm_l", "move16",
|
||||
"move32", "Logic16", "Logic32", "Test", "s_max",
|
||||
"s_min", "L_max", "L_min", "L40_max", "L40_min",
|
||||
"shl_r", "L_shl_r", "L40_shr_r", "L40_shl_r", "norm_L40",
|
||||
|
||||
"L40_shl", "L40_shr", "L40_negate", "L40_add", "L40_sub",
|
||||
"L40_abs", "L40_mult", "L40_mac", "mac_r40",
|
||||
"L40_msu", "msu_r40", "Mpy_32_16_ss", "Mpy_32_32_ss", "L_mult0",
|
||||
"L_mac0", "L_msu0", "lshl", "lshr", "L_lshl",
|
||||
"L_lshr", "L40_lshl", "L40_lshr", "s_and", "s_or",
|
||||
|
||||
"s_xor", "L_and", "L_or", "L_xor", "rotl",
|
||||
"rotr", "L_rotl", "L_rotr", "L40_set", "L40_deposit_h",
|
||||
"L40_deposit_l", "L40_deposit32", "Extract40_H", "Extract40_L", "L_Extract40",
|
||||
"L40_round", "L_saturate40", "round40", "IF", "GOTO",
|
||||
"BREAK", "SWITCH", "FOR", "WHILE", "CONTINUE"
|
||||
|
||||
, "L_mls", "div_l", "i_mult"
|
||||
};
|
||||
#endif /* ifdef WMOPS */
|
||||
|
||||
|
||||
#ifdef WMOPS
|
||||
const BASIC_OP op_weight =
|
||||
{
|
||||
1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1,
|
||||
1, 1, 2, 2, 1,
|
||||
1, 1, 1, 3, 1,
|
||||
|
||||
1, 1, 1, 3, 1,
|
||||
4, 1, 18, 1, 1,
|
||||
2, 1, 2, 2, 1,
|
||||
1, 1, 1, 1, 1,
|
||||
3, 3, 3, 3, 1,
|
||||
|
||||
1, 1, 1, 1, 1,
|
||||
1, 1, 1, 2,
|
||||
1, 2, 2, 4, 1,
|
||||
1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1,
|
||||
|
||||
1, 1, 1, 1, 3,
|
||||
3, 3, 3, 3, 1,
|
||||
1, 1, 1, 1, 1,
|
||||
1, 1, 1, 4, 4,
|
||||
4, 8, 3, 4, 4
|
||||
|
||||
, 5, 32, 3
|
||||
};
|
||||
#endif /* ifdef WMOPS */
|
||||
|
||||
|
||||
Word32 TotalWeightedOperation (void);
|
||||
Word32 DeltaWeightedOperation (void);
|
||||
|
||||
|
||||
#ifdef WMOPS
|
||||
/* Counters for separating counting for different objects */
|
||||
|
||||
|
||||
static int maxCounter=0;
|
||||
static char* objectName[MAXCOUNTERS+1];
|
||||
|
||||
static Word16 fwc_corr[MAXCOUNTERS+1];
|
||||
static long int nbTimeObjectIsCalled[MAXCOUNTERS+1];
|
||||
|
||||
#define NbFuncMax 1024
|
||||
|
||||
static Word16 funcid[MAXCOUNTERS], nbframe[MAXCOUNTERS];
|
||||
static Word32 glob_wc[MAXCOUNTERS], wc[MAXCOUNTERS][NbFuncMax];
|
||||
static float total_wmops[MAXCOUNTERS];
|
||||
|
||||
static Word32 LastWOper[MAXCOUNTERS];
|
||||
#endif /* ifdef WMOPS */
|
||||
|
||||
|
||||
#ifdef WMOPS
|
||||
static char* my_strdup(const char *s) {
|
||||
/*
|
||||
* duplicates UNIX function strdup() which is not ANSI standard:
|
||||
* -- malloc() memory area big enough to hold the string s
|
||||
* -- copy string into new area
|
||||
* -- return pointer to new area
|
||||
*
|
||||
* returns NULL if either s==NULL or malloc() fails
|
||||
*/
|
||||
char *dup;
|
||||
|
||||
if (s == NULL)
|
||||
return NULL;
|
||||
|
||||
/* allocate memory for copy of ID string (including string terminator) */
|
||||
/* NOTE: the ID strings will never be deallocated because there is no
|
||||
way to "destroy" a counter that is not longer needed */
|
||||
if ((dup = (char *) malloc(strlen(s)+1)) == NULL)
|
||||
return NULL;
|
||||
|
||||
return strcpy(dup, s);
|
||||
}
|
||||
#endif /* ifdef WMOPS */
|
||||
|
||||
|
||||
int getCounterId( char *objectNameArg) {
|
||||
#if WMOPS
|
||||
if(maxCounter>=MAXCOUNTERS-1) return 0;
|
||||
objectName[++maxCounter]=my_strdup(objectNameArg);
|
||||
return maxCounter;
|
||||
|
||||
#else /* ifdef WMOPS */
|
||||
(void)objectNameArg;
|
||||
return 0; /* Dummy */
|
||||
|
||||
#endif /* ifdef WMOPS */
|
||||
}
|
||||
|
||||
|
||||
#if WMOPS
|
||||
int readCounterId() {
|
||||
return currCounter;
|
||||
}
|
||||
#endif /* ifdef WMOPS */
|
||||
|
||||
|
||||
#ifdef WMOPS
|
||||
char * readCounterIdName() {
|
||||
return objectName[currCounter];
|
||||
}
|
||||
#endif /* ifdef WMOPS */
|
||||
|
||||
void setCounter( int counterId) {
|
||||
#if WMOPS
|
||||
if( (counterId > maxCounter)
|
||||
|| (counterId < 0)) {
|
||||
currCounter=0;
|
||||
return;
|
||||
}
|
||||
currCounter=counterId;
|
||||
call_occurred = 1;
|
||||
#else
|
||||
(void)counterId;
|
||||
#endif /* ifdef WMOPS */
|
||||
}
|
||||
|
||||
|
||||
void incrementNbTimeObjectIsCalled( int counterId) {
|
||||
#if WMOPS
|
||||
if( (counterId > maxCounter)
|
||||
|| (counterId < 0)) {
|
||||
nbTimeObjectIsCalled[0]++;
|
||||
return;
|
||||
}
|
||||
nbTimeObjectIsCalled[counterId]++;
|
||||
#else
|
||||
(void)counterId;
|
||||
#endif /* ifdef WMOPS */
|
||||
}
|
||||
|
||||
|
||||
#if WMOPS
|
||||
static Word32 WMOPS_frameStat() {
|
||||
/* calculate the WMOPS seen so far and update the global
|
||||
per-frame maximum (glob_wc)
|
||||
*/
|
||||
Word32 tot;
|
||||
|
||||
tot = TotalWeightedOperation ();
|
||||
if (tot > glob_wc[currCounter])
|
||||
glob_wc[currCounter] = tot;
|
||||
|
||||
/* check if fwc() was forgotten at end of last frame */
|
||||
if (tot > LastWOper[currCounter]) {
|
||||
if (!fwc_corr[currCounter]) {
|
||||
fprintf(stderr,
|
||||
"count: operations counted after last fwc() for '%s'; "
|
||||
"-> fwc() called\n",
|
||||
objectName[currCounter]?objectName[currCounter]:"");
|
||||
}
|
||||
fwc();
|
||||
}
|
||||
|
||||
return tot;
|
||||
}
|
||||
#endif /* ifdef WMOPS */
|
||||
|
||||
|
||||
#ifdef WMOPS
|
||||
static void WMOPS_clearMultiCounter() {
|
||||
Word16 i;
|
||||
|
||||
Word32 *ptr = (Word32 *) &multiCounter[currCounter];
|
||||
for( i = 0; i < (Word16)(sizeof (multiCounter[currCounter])/ sizeof (Word32)); i++) {
|
||||
*ptr++ = 0;
|
||||
}
|
||||
}
|
||||
#endif /* ifdef WMOPS */
|
||||
|
||||
|
||||
void ClearNbTimeObjectsAreCalled() {
|
||||
#if WMOPS
|
||||
Word16 i;
|
||||
|
||||
for (i = 0; i < (Word16)(sizeof (multiCounter[currCounter])/ sizeof (Word32)); i++) {
|
||||
nbTimeObjectIsCalled[i] = 0;
|
||||
}
|
||||
#endif /* ifdef WMOPS */
|
||||
}
|
||||
|
||||
Word32 TotalWeightedOperation () {
|
||||
#if WMOPS
|
||||
Word16 i;
|
||||
Word32 tot, *ptr, *ptr2;
|
||||
|
||||
tot = 0;
|
||||
ptr = (Word32 *) &multiCounter[currCounter];
|
||||
ptr2 = (Word32 *) &op_weight;
|
||||
for (i = 0; i < (Word16)(sizeof (multiCounter[currCounter])/ sizeof (Word32)); i++) {
|
||||
tot += ((*ptr++) * (*ptr2++));
|
||||
}
|
||||
|
||||
return ((Word32) tot);
|
||||
|
||||
#else /* ifdef WMOPS */
|
||||
return 0; /* Dummy */
|
||||
|
||||
#endif /* ifdef WMOPS */
|
||||
|
||||
}
|
||||
|
||||
Word32 DeltaWeightedOperation () {
|
||||
#if WMOPS
|
||||
Word32 NewWOper, delta;
|
||||
|
||||
NewWOper = TotalWeightedOperation ();
|
||||
delta = NewWOper - LastWOper[currCounter];
|
||||
LastWOper[currCounter] = NewWOper;
|
||||
return (delta);
|
||||
|
||||
#else /* ifdef WMOPS */
|
||||
return 0; /* Dummy */
|
||||
|
||||
#endif /* ifdef WMOPS */
|
||||
}
|
||||
|
||||
|
||||
void Init_WMOPS_counter (void) {
|
||||
#if WMOPS
|
||||
Word16 i;
|
||||
|
||||
/* reset function weight operation counter variable */
|
||||
|
||||
for (i = 0; i < NbFuncMax; i++)
|
||||
wc[currCounter][i] = (Word32) 0;
|
||||
glob_wc[currCounter] = 0;
|
||||
nbframe[currCounter] = 0;
|
||||
total_wmops[currCounter] = 0.0;
|
||||
|
||||
/* initially clear all counters */
|
||||
WMOPS_clearMultiCounter();
|
||||
LastWOper[currCounter] = 0;
|
||||
funcid[currCounter] = 0;
|
||||
|
||||
/* Following line is useful for incrIf(), see control.h */
|
||||
call_occurred = 1;
|
||||
funcId_where_last_call_to_else_occurred=MAXCOUNTERS;
|
||||
#endif /* ifdef WMOPS */
|
||||
}
|
||||
|
||||
|
||||
void Reset_WMOPS_counter (void) {
|
||||
#if WMOPS
|
||||
Word32 tot = WMOPS_frameStat();
|
||||
|
||||
/* increase the frame counter --> a frame is counted WHEN IT BEGINS */
|
||||
nbframe[currCounter]++;
|
||||
/* add wmops used in last frame to count, then reset counter */
|
||||
/* (in first frame, this is a no-op */
|
||||
total_wmops[currCounter] += (float)( tot * frameRate );
|
||||
|
||||
/* clear counter before new frame starts */
|
||||
WMOPS_clearMultiCounter();
|
||||
LastWOper[currCounter] = 0;
|
||||
funcid[currCounter] = 0; /* new frame, set function id to zero */
|
||||
#endif /* ifdef WMOPS */
|
||||
}
|
||||
|
||||
|
||||
Word32 fwc (void) {
|
||||
/* function worst case */
|
||||
#if WMOPS
|
||||
Word32 tot;
|
||||
|
||||
tot = DeltaWeightedOperation ();
|
||||
if (tot > wc[currCounter][funcid[currCounter]])
|
||||
wc[currCounter][funcid[currCounter]] = tot;
|
||||
|
||||
funcid[currCounter]++;
|
||||
return (tot);
|
||||
|
||||
#else /* ifdef WMOPS */
|
||||
return 0; /* Dummy */
|
||||
|
||||
#endif /* ifdef WMOPS */
|
||||
}
|
||||
|
||||
void WMOPS_output (Word16 dtx_mode) {
|
||||
#if WMOPS
|
||||
Word16 i;
|
||||
Word32 tot, tot_wm, tot_wc;
|
||||
|
||||
/* get operations since last reset (or init),
|
||||
but do not update the counters (except the glob_wc[] maximum)
|
||||
so output CAN be called in each frame without problems.
|
||||
The frame counter is NOT updated!
|
||||
*/
|
||||
tot = WMOPS_frameStat();
|
||||
tot_wm = (Word32)(total_wmops[currCounter] + ((float) tot) * frameRate);
|
||||
|
||||
fprintf (stdout, "%10s:WMOPS=%.3f",
|
||||
objectName[currCounter]?objectName[currCounter]:"",
|
||||
((float) tot) * frameRate);
|
||||
|
||||
if (nbframe[currCounter] != 0)
|
||||
{
|
||||
fprintf (stdout, " Average=%.3f",
|
||||
tot_wm / (float) nbframe[currCounter]);
|
||||
}
|
||||
fprintf (stdout, " WorstCase=%.3f",
|
||||
((float) glob_wc[currCounter]) * frameRate);
|
||||
|
||||
/* Worst worst case printed only when not in DTX mode */
|
||||
if (dtx_mode == 0)
|
||||
{
|
||||
tot_wc = 0L;
|
||||
for (i = 0; i < funcid[currCounter]; i++)
|
||||
tot_wc += wc[currCounter][i];
|
||||
fprintf (stdout, " WorstWC=%.3f", ((float) tot_wc) * frameRate);
|
||||
}
|
||||
fprintf (stdout, " (%d frames)\n", nbframe[currCounter]);
|
||||
|
||||
#else
|
||||
(void)dtx_mode;
|
||||
#endif /* ifdef WMOPS */
|
||||
}
|
||||
|
||||
|
||||
void WMOPS_output_avg (Word16 dtx_mode, Word32 *tot_wm, Word16 *num_frames) {
|
||||
#if WMOPS
|
||||
Word16 i;
|
||||
Word32 tot, tot_wc;
|
||||
|
||||
/* get operations since last reset (or init),
|
||||
but do not update the counters (except the glob_wc[] maximum)
|
||||
so output CAN be called in each frame without problems.
|
||||
The frame counter is NOT updated!
|
||||
*/
|
||||
tot = WMOPS_frameStat();
|
||||
*tot_wm = (Word32)(total_wmops[currCounter] + ((float) tot) * frameRate);
|
||||
*num_frames = nbframe[currCounter];
|
||||
|
||||
fprintf (stdout, "%10s:WMOPS=%.3f",
|
||||
objectName[currCounter]?objectName[currCounter]:"",
|
||||
((float) tot) * frameRate);
|
||||
|
||||
if (nbframe[currCounter] != 0)
|
||||
{
|
||||
fprintf (stdout, " Average=%.3f",
|
||||
*tot_wm / (float) nbframe[currCounter]);
|
||||
}
|
||||
fprintf (stdout, " WorstCase=%.3f",
|
||||
((float) glob_wc[currCounter]) * frameRate);
|
||||
|
||||
/* Worst worst case printed only when not in DTX mode */
|
||||
if (dtx_mode == 0)
|
||||
{
|
||||
tot_wc = 0L;
|
||||
for (i = 0; i < funcid[currCounter]; i++)
|
||||
tot_wc += wc[currCounter][i];
|
||||
fprintf (stdout, " WorstWC=%.3f", ((float) tot_wc) * frameRate);
|
||||
}
|
||||
fprintf (stdout, " (%d frames)\n", nbframe[currCounter]);
|
||||
#else
|
||||
(void)dtx_mode;
|
||||
(void)tot_wm;
|
||||
(void)num_frames;
|
||||
#endif /* ifdef WMOPS */
|
||||
}
|
||||
|
||||
void generic_WMOPS_output (Word16 dtx_mode, char *test_file_name)
|
||||
{
|
||||
#if WMOPS
|
||||
int saved_value;
|
||||
Word16 i;
|
||||
Word32 tot, tot_wm, tot_wc, *ptr, *ptr2;
|
||||
Word40 grand_total;
|
||||
FILE *WMOPS_file;
|
||||
|
||||
saved_value = currCounter;
|
||||
|
||||
/*Count the grand_total WMOPS so that % ratio per function group
|
||||
can be displayed. */
|
||||
grand_total = 0;
|
||||
for( currCounter = 0; currCounter <= maxCounter; currCounter++) {
|
||||
tot = WMOPS_frameStat();
|
||||
grand_total += tot;
|
||||
|
||||
}
|
||||
|
||||
|
||||
if( (WMOPS_file=fopen(WMOPS_DATA_FILENAME,"a"))!=NULL) {
|
||||
|
||||
printf( "opened file %s in order to print WMOPS for each function group.\n", WMOPS_DATA_FILENAME);
|
||||
|
||||
/* Print the file header line. */
|
||||
fprintf (WMOPS_file, "Test file name\tFunction Name \tFrame\tNb Times Called\tWMOPS\t%% versus grand total");
|
||||
|
||||
if (nbframe[saved_value] != 0)
|
||||
fprintf (WMOPS_file, "\tAverage");
|
||||
|
||||
fprintf (WMOPS_file, "\tWorstCase");
|
||||
|
||||
/* Worst worst case printed only when not in DTX mode */
|
||||
if (dtx_mode == 0)
|
||||
fprintf (WMOPS_file, "\tWorstWC");
|
||||
|
||||
fprintf (WMOPS_file, "\n");
|
||||
|
||||
/* Print the WMOPS for each Function Group by scanning
|
||||
all the function groups with currCounter index.*/
|
||||
for( currCounter = 0; currCounter <= maxCounter; currCounter++) {
|
||||
|
||||
fprintf (WMOPS_file, "%s", test_file_name);
|
||||
fprintf (WMOPS_file, "\t%s",
|
||||
objectName[currCounter] ? objectName[currCounter] : "");
|
||||
fprintf (WMOPS_file, "\t%d", nbframe[currCounter]);
|
||||
|
||||
tot = WMOPS_frameStat();
|
||||
tot_wm = (Word32)(total_wmops[currCounter] + ((float) tot) * frameRate);
|
||||
|
||||
fprintf (WMOPS_file, "\t\t%ld", nbTimeObjectIsCalled[currCounter]);
|
||||
fprintf (WMOPS_file, "\t%.6f", ((float) tot) * frameRate);
|
||||
fprintf (WMOPS_file, "\t%.3f", ((float) tot) / grand_total * 100);
|
||||
|
||||
if (nbframe[currCounter] != 0)
|
||||
fprintf (WMOPS_file, "\t%.3f", tot_wm / (float) nbframe[currCounter]);
|
||||
|
||||
fprintf (WMOPS_file, "\t%.3f", ((float) glob_wc[currCounter]) * frameRate);
|
||||
|
||||
/* Worst worst case printed only when not in DTX mode */
|
||||
if (dtx_mode == 0) {
|
||||
tot_wc = 0L;
|
||||
for (i = 0; i < funcid[currCounter]; i++)
|
||||
tot_wc += wc[currCounter][i];
|
||||
fprintf (WMOPS_file, "\t%.3f", ((float) tot_wc) * frameRate);
|
||||
}
|
||||
fprintf (WMOPS_file, "\n");
|
||||
|
||||
}
|
||||
|
||||
/* Print the file Grand Total line */
|
||||
fprintf (WMOPS_file, "%s", test_file_name);
|
||||
fprintf (WMOPS_file, "\tGrand Total");
|
||||
fprintf (WMOPS_file, "\t%d", nbframe[saved_value]);
|
||||
fprintf (WMOPS_file, "\t\t%.6f", ((float) grand_total) * frameRate);
|
||||
fprintf (WMOPS_file, "\t100.000");
|
||||
fprintf (WMOPS_file, "\n");
|
||||
fclose(WMOPS_file);
|
||||
|
||||
} else
|
||||
printf( "Can not open file %s for WMOPS editing\n", WMOPS_DATA_FILENAME);
|
||||
|
||||
|
||||
if( (WMOPS_file=fopen(WMOPS_TOTAL_FILENAME,"a"))!=NULL) {
|
||||
printf( "opened file %s in order to print application's total WMOPS.\n", WMOPS_TOTAL_FILENAME);
|
||||
fprintf (WMOPS_file, "%s", test_file_name);
|
||||
fprintf (WMOPS_file, "\tframe=%d", nbframe[currCounter]);
|
||||
fprintf (WMOPS_file, "\tWMOPS=%.6f", ((float) grand_total) * frameRate);
|
||||
fprintf (WMOPS_file, "\n");
|
||||
fclose(WMOPS_file);
|
||||
|
||||
} else
|
||||
printf( "Can not open file %s for WMOPS editing.\n", WMOPS_TOTAL_FILENAME);
|
||||
|
||||
|
||||
if( (WMOPS_file=fopen(CODE_PROFILE_FILENAME,"a"))!=NULL) {
|
||||
|
||||
printf( "opened file %s in order to print basic operation distribution statistics.\n", CODE_PROFILE_FILENAME);
|
||||
|
||||
/* Print the file header line. */
|
||||
fprintf (WMOPS_file, "Test file name\tBasic Operation Name\tframe\tWMOPS\t\t%% versus grand total\n");
|
||||
|
||||
/* Print the WMOPS for each Basic Operation across all the defined */
|
||||
/* Function Groups. */
|
||||
for( i = 0; i <(Word16)(sizeof(op_weight) / sizeof(Word32)); i++) {
|
||||
fprintf (WMOPS_file, "%-16s", test_file_name);
|
||||
fprintf (WMOPS_file, "\t%s", BasicOperationList[i]);
|
||||
fprintf (WMOPS_file, "\t%d", nbframe[0]);
|
||||
|
||||
tot = 0;
|
||||
ptr = (Word32 *) &multiCounter[0] + i;
|
||||
ptr2 = (Word32 *) &op_weight + i;
|
||||
for( currCounter = 0; currCounter <= maxCounter; currCounter++) {
|
||||
tot += ((*ptr) * (*ptr2));
|
||||
ptr += (sizeof(op_weight) / sizeof(Word32));
|
||||
}
|
||||
|
||||
fprintf (WMOPS_file, "\t%.6f", ((float) tot) * frameRate);
|
||||
fprintf (WMOPS_file, "\t%.3f", ((float) tot) / grand_total * 100);
|
||||
fprintf (WMOPS_file, "\n");
|
||||
}
|
||||
|
||||
/* Print the file Grand Total line */
|
||||
fprintf (WMOPS_file, "%s", test_file_name);
|
||||
fprintf (WMOPS_file, "\tGrand Total");
|
||||
fprintf (WMOPS_file, "\t%d", nbframe[saved_value]);
|
||||
fprintf (WMOPS_file, "\t%.6f", ((float) grand_total) * frameRate);
|
||||
fprintf (WMOPS_file, "\t100.000");
|
||||
fprintf (WMOPS_file, "\n");
|
||||
fclose(WMOPS_file);
|
||||
|
||||
} else
|
||||
printf( "Can not open file %s for basic operations distribution statistic editing\n", CODE_PROFILE_FILENAME);
|
||||
|
||||
currCounter = saved_value;
|
||||
|
||||
#else
|
||||
(void)dtx_mode;
|
||||
(void)test_file_name;
|
||||
#endif /* ifdef WMOPS */
|
||||
}
|
||||
|
||||
|
||||
/* end of file */
|
||||
|
||||
@@ -1,410 +0,0 @@
|
||||
/*
|
||||
===========================================================================
|
||||
File: COUNT.H v.2.3 - 30.Nov.2009
|
||||
===========================================================================
|
||||
|
||||
ITU-T STL BASIC OPERATORS
|
||||
|
||||
PROTOTYPES & DEFINITION FOR COUNTING OPERATIONS
|
||||
|
||||
History
|
||||
09.Aug.1999 V1.0.0 Input to UGST from ETSI AMR (count.h);
|
||||
|
||||
26.Jan.2000 V1.1.0 Added counter entries for G.723.1's
|
||||
L_mls(), div_l(), i_mult() [from basop32.c]
|
||||
|
||||
05.Jul.2000 V1.2.0 Added counter entries for 32bit shiftless
|
||||
operators L_mult0(), L_mac0(), L_msu0()
|
||||
|
||||
03 Nov 04 v2.0 Incorporation of new 32-bit / 40-bit / control
|
||||
operators for the ITU-T Standard Tool Library as
|
||||
described in Geneva, 20-30 January 2004 WP 3/16 Q10/16
|
||||
TD 11 document and subsequent discussions on the
|
||||
wp3audio@yahoogroups.com email reflector.
|
||||
March 06 v2.1 Changed to improve portability.
|
||||
Dec 06 v2.2 Changed to specify frame rate using setFrameRate()
|
||||
Adding WMOPS_output_avg() for global average computation
|
||||
L_mls() weight of 5.
|
||||
div_l() weight of 32.
|
||||
i_mult() weight of 3.
|
||||
============================================================================
|
||||
*/
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* Functions for counting operations.
|
||||
*
|
||||
* These functions make it possible to measure the wMOPS of a codec.
|
||||
*
|
||||
* All functions in this file, and in other *.h files, update a structure so
|
||||
* that it will be possible to track how many calls to add(), sub(), L_mult()
|
||||
* ... was made by the code and to estimate the wMOPS (and MIPS) for a certain
|
||||
* part of the code.
|
||||
*
|
||||
* It is also possible to measure the wMOPS separatly for different parts
|
||||
* of the codec.
|
||||
*
|
||||
* This is done by creating a counter group (getCounterId) for each part of
|
||||
* the code that one wants a seperate measure for. Before a part of the code
|
||||
* is executed a call to the "setCounter" function is needed to identify
|
||||
* which counter group to use.
|
||||
*
|
||||
* Currently there is a limit of 255 different counter groups.
|
||||
*
|
||||
* In the end of this file, there is a piece of code illustrating how the
|
||||
* functions can be used.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
#ifndef _COUNT_H
|
||||
#define _COUNT_H
|
||||
/* #define WMOPS 1 */ /* enable WMOPS profiling features */
|
||||
/* #undef WMOPS */ /* disable WMOPS profiling features */
|
||||
#define MAXCOUNTERS (256)
|
||||
|
||||
#define BASOP_sub_start(label)
|
||||
#define BASOP_sub_end()
|
||||
#define SUB_WMOPS_INIT(label) BASOP_sub_start(label)
|
||||
#define END_SUB_WMOPS BASOP_sub_end()
|
||||
#define BASOP_push_wmops(label)
|
||||
#define BASOP_pop_wmops()
|
||||
#define BASOP_end_noprint
|
||||
#define BASOP_end
|
||||
#define BASOP_init
|
||||
|
||||
int getCounterId( char *objectName);
|
||||
/*
|
||||
* Create a counter group, the "objectname" will be used when printing
|
||||
* statistics for this counter group.
|
||||
*
|
||||
* Returns 0 if no more counter groups are available.
|
||||
*/
|
||||
|
||||
|
||||
int readCounterId(void);
|
||||
/*
|
||||
* Returns the current CounterId.
|
||||
*/
|
||||
|
||||
|
||||
void setCounter( int counterId);
|
||||
/*
|
||||
* Defines which counter group to use, default is zero.
|
||||
*/
|
||||
|
||||
|
||||
char *readCounterIdName(void);
|
||||
/*
|
||||
* Returns the current CounterId name.
|
||||
*/
|
||||
|
||||
|
||||
void incrementNbTimeObjectIsCalled( int counterId);
|
||||
/*
|
||||
* This function enables to increment by 1 a counter
|
||||
* tracking the number of times the application enters a groups of functions.
|
||||
* If the counterId is not refering to a defined function counter group, then it is
|
||||
* the default function group (0) which is impacted.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
void ClearNbTimeObjectsAreCalled(void);
|
||||
/*
|
||||
* This function enables to clear to 0 all the counters enabling to
|
||||
* track the number of times the application enters any groups of functions.
|
||||
*/
|
||||
|
||||
|
||||
void Init_WMOPS_counter( void);
|
||||
/*
|
||||
* Initiates the current counter group.
|
||||
*/
|
||||
|
||||
|
||||
void Reset_WMOPS_counter( void);
|
||||
/*
|
||||
* Resets the current counter group.
|
||||
*/
|
||||
|
||||
|
||||
void WMOPS_output ( Word16 notPrintWorstWorstCase);
|
||||
/*
|
||||
* Prints the statistics to the screen, if the argument is non zero
|
||||
* the statistics for worst worst case will not be printed. This is typically
|
||||
* done for dtx frames.
|
||||
*
|
||||
*/
|
||||
|
||||
void WMOPS_output_avg (Word16 dtx_mode, Word32 *tot_wm, Word16 *num_frames);
|
||||
/*
|
||||
* same as WMOPS_output + returns the total wmops counter and the number of frames
|
||||
* to support the computation of global average.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
Word32 fwc( void);
|
||||
/*
|
||||
* worst worst case counter.
|
||||
*
|
||||
* This function calculates the worst possible case that can be reached.
|
||||
*
|
||||
* This is done by calling this function for each subpart of the calculations
|
||||
* for a frame. This function then stores the maximum wMOPS for each part.
|
||||
*
|
||||
* The WMOPS_output function add together all parts and presents the sum.
|
||||
*/
|
||||
|
||||
void setFrameRate(int samplingFreq, int frameLength);
|
||||
/*
|
||||
* This function can overwrite the value of the frameRate variable that is
|
||||
* initialized by the FRAME_RATE constant.
|
||||
*/
|
||||
|
||||
|
||||
#define WMOPS_DATA_FILENAME "wmops_data.txt"
|
||||
/*
|
||||
* WMOPS_DATA_FILENAME is the macro defining the name of the file
|
||||
* where the Weighted Million of Operations per Second (wMOPS)
|
||||
* are appended, function group by function group.
|
||||
*/
|
||||
|
||||
|
||||
#define CODE_PROFILE_FILENAME "code_profile.txt"
|
||||
/*
|
||||
* CODE_PROFILE_FILENAME is the macro defining the name of the file
|
||||
* where the Weighted Million of Operations per Second (WMOPS)
|
||||
* are appended, basic operation by basic operation.
|
||||
*/
|
||||
|
||||
|
||||
#define WMOPS_TOTAL_FILENAME "wmops_total.txt"
|
||||
/*
|
||||
* WMOPS_TOTAL_FILENAME is the macro defining the name of the file
|
||||
* where the Weighted Million of Operations per Second (WMOPS)
|
||||
* are printed, globally for the application.
|
||||
*/
|
||||
|
||||
|
||||
#define FRAME_RATE (0.0001F) /*in this version frame_rate can be overwriten online by the new setFrameRate function */
|
||||
/* FRAME_RATE of 0.000025 is corresponding to 40ms frame.*/
|
||||
/* FRAME_RATE of 0.00005 is corresponding to 20ms frame.*/
|
||||
/* FRAME_RATE of 0.0001 is corresponding to 10ms frame.*/
|
||||
/*
|
||||
* FRAME_RATE is the macro defining the calling rate of the
|
||||
* application to benchmark.
|
||||
*/
|
||||
|
||||
|
||||
/* Global counter variable for calculation of complexity weight */
|
||||
typedef struct
|
||||
{
|
||||
UWord32 add; /* Complexity Weight of 1 */
|
||||
UWord32 sub; /* Complexity Weight of 1 */
|
||||
UWord32 abs_s; /* Complexity Weight of 1 */
|
||||
UWord32 shl; /* Complexity Weight of 1 */
|
||||
UWord32 shr; /* Complexity Weight of 1 */
|
||||
|
||||
UWord32 extract_h; /* Complexity Weight of 1 */
|
||||
UWord32 extract_l; /* Complexity Weight of 1 */
|
||||
UWord32 mult; /* Complexity Weight of 1 */
|
||||
UWord32 L_mult; /* Complexity Weight of 1 */
|
||||
UWord32 negate; /* Complexity Weight of 1 */
|
||||
|
||||
UWord32 round; /* Complexity Weight of 1 */
|
||||
UWord32 L_mac; /* Complexity Weight of 1 */
|
||||
UWord32 L_msu; /* Complexity Weight of 1 */
|
||||
UWord32 L_macNs; /* Complexity Weight of 1 */
|
||||
UWord32 L_msuNs; /* Complexity Weight of 1 */
|
||||
|
||||
UWord32 L_add; /* Complexity Weight of 1 */
|
||||
UWord32 L_sub; /* Complexity Weight of 1 */
|
||||
UWord32 L_add_c; /* Complexity Weight of 2 */
|
||||
UWord32 L_sub_c; /* Complexity Weight of 2 */
|
||||
UWord32 L_negate; /* Complexity Weight of 1 */
|
||||
|
||||
UWord32 L_shl; /* Complexity Weight of 1 */
|
||||
UWord32 L_shr; /* Complexity Weight of 1 */
|
||||
UWord32 mult_r; /* Complexity Weight of 1 */
|
||||
UWord32 shr_r; /* Complexity Weight of 3 */
|
||||
UWord32 mac_r; /* Complexity Weight of 1 */
|
||||
|
||||
UWord32 msu_r; /* Complexity Weight of 1 */
|
||||
UWord32 L_deposit_h; /* Complexity Weight of 1 */
|
||||
UWord32 L_deposit_l; /* Complexity Weight of 1 */
|
||||
UWord32 L_shr_r; /* Complexity Weight of 3 */
|
||||
UWord32 L_abs; /* Complexity Weight of 1 */
|
||||
|
||||
UWord32 L_sat; /* Complexity Weight of 4 */
|
||||
UWord32 norm_s; /* Complexity Weight of 1 */
|
||||
UWord32 div_s; /* Complexity Weight of 18 */
|
||||
UWord32 norm_l; /* Complexity Weight of 1 */
|
||||
UWord32 move16; /* Complexity Weight of 1 */
|
||||
|
||||
UWord32 move32; /* Complexity Weight of 2 */
|
||||
UWord32 Logic16; /* Complexity Weight of 1 */
|
||||
UWord32 Logic32; /* Complexity Weight of 2 */
|
||||
UWord32 Test; /* Complexity Weight of 2 */
|
||||
UWord32 s_max; /* Complexity Weight of 1 */
|
||||
|
||||
UWord32 s_min; /* Complexity Weight of 1 */
|
||||
UWord32 L_max; /* Complexity Weight of 1 */
|
||||
UWord32 L_min; /* Complexity Weight of 1 */
|
||||
UWord32 L40_max; /* Complexity Weight of 1 */
|
||||
UWord32 L40_min; /* Complexity Weight of 1 */
|
||||
|
||||
UWord32 shl_r; /* Complexity Weight of 3 */
|
||||
UWord32 L_shl_r; /* Complexity Weight of 3 */
|
||||
UWord32 L40_shr_r; /* Complexity Weight of 3 */
|
||||
UWord32 L40_shl_r; /* Complexity Weight of 3 */
|
||||
UWord32 norm_L40; /* Complexity Weight of 1 */
|
||||
|
||||
UWord32 L40_shl; /* Complexity Weight of 1 */
|
||||
UWord32 L40_shr; /* Complexity Weight of 1 */
|
||||
UWord32 L40_negate; /* Complexity Weight of 1 */
|
||||
UWord32 L40_add; /* Complexity Weight of 1 */
|
||||
UWord32 L40_sub; /* Complexity Weight of 1 */
|
||||
|
||||
UWord32 L40_abs; /* Complexity Weight of 1 */
|
||||
UWord32 L40_mult; /* Complexity Weight of 1 */
|
||||
UWord32 L40_mac; /* Complexity Weight of 1 */
|
||||
UWord32 mac_r40; /* Complexity Weight of 2 */
|
||||
|
||||
UWord32 L40_msu; /* Complexity Weight of 1 */
|
||||
UWord32 msu_r40; /* Complexity Weight of 2 */
|
||||
UWord32 Mpy_32_16_ss; /* Complexity Weight of 2 */
|
||||
UWord32 Mpy_32_32_ss; /* Complexity Weight of 4 */
|
||||
UWord32 L_mult0; /* Complexity Weight of 1 */
|
||||
|
||||
UWord32 L_mac0; /* Complexity Weight of 1 */
|
||||
UWord32 L_msu0; /* Complexity Weight of 1 */
|
||||
UWord32 lshl; /* Complexity Weight of 1 */
|
||||
UWord32 lshr; /* Complexity Weight of 1 */
|
||||
UWord32 L_lshl; /* Complexity Weight of 1 */
|
||||
|
||||
UWord32 L_lshr; /* Complexity Weight of 1 */
|
||||
UWord32 L40_lshl; /* Complexity Weight of 1 */
|
||||
UWord32 L40_lshr; /* Complexity Weight of 1 */
|
||||
UWord32 s_and; /* Complexity Weight of 1 */
|
||||
UWord32 s_or; /* Complexity Weight of 1 */
|
||||
|
||||
UWord32 s_xor; /* Complexity Weight of 1 */
|
||||
UWord32 L_and; /* Complexity Weight of 1 */
|
||||
UWord32 L_or; /* Complexity Weight of 1 */
|
||||
UWord32 L_xor; /* Complexity Weight of 1 */
|
||||
UWord32 rotl; /* Complexity Weight of 3 */
|
||||
|
||||
UWord32 rotr; /* Complexity Weight of 3 */
|
||||
UWord32 L_rotl; /* Complexity Weight of 3 */
|
||||
UWord32 L_rotr; /* Complexity Weight of 3 */
|
||||
UWord32 L40_set; /* Complexity Weight of 3 */
|
||||
UWord32 L40_deposit_h; /* Complexity Weight of 1 */
|
||||
|
||||
UWord32 L40_deposit_l; /* Complexity Weight of 1 */
|
||||
UWord32 L40_deposit32; /* Complexity Weight of 1 */
|
||||
UWord32 Extract40_H; /* Complexity Weight of 1 */
|
||||
UWord32 Extract40_L; /* Complexity Weight of 1 */
|
||||
UWord32 L_Extract40; /* Complexity Weight of 1 */
|
||||
|
||||
UWord32 L40_round; /* Complexity Weight of 1 */
|
||||
UWord32 L_saturate40; /* Complexity Weight of 1 */
|
||||
UWord32 round40; /* Complexity Weight of 1 */
|
||||
UWord32 If; /* Complexity Weight of 4 */
|
||||
UWord32 Goto; /* Complexity Weight of 4 */
|
||||
|
||||
UWord32 Break; /* Complexity Weight of 4 */
|
||||
UWord32 Switch; /* Complexity Weight of 8 */
|
||||
UWord32 For; /* Complexity Weight of 3 */
|
||||
UWord32 While; /* Complexity Weight of 4 */
|
||||
UWord32 Continue; /* Complexity Weight of 4 */
|
||||
|
||||
UWord32 L_mls; /* Complexity Weight of 6 */
|
||||
UWord32 div_l; /* Complexity Weight of 32 */
|
||||
UWord32 i_mult; /* Complexity Weight of 3 */
|
||||
}
|
||||
BASIC_OP;
|
||||
|
||||
|
||||
Word32 TotalWeightedOperation( void);
|
||||
Word32 DeltaWeightedOperation( void);
|
||||
|
||||
|
||||
void generic_WMOPS_output ( Word16 notPrintWorstWorstCase, char *test_file_name);
|
||||
/*
|
||||
* This function enable to append :
|
||||
* - to WMOPS_DATA_FILENAME file, the WMOPS information related
|
||||
* to the execution of the application, function group by function
|
||||
* group.
|
||||
* - to CODE_PROFILE_FILENAME file, the WMOPS information related
|
||||
* to the execution of the application, basic operation by basic
|
||||
* operation.
|
||||
* - to WMOPS_TOTAL_FILENAME file, the total WMOPS information related
|
||||
* to the execution of the application.
|
||||
*
|
||||
* Note that :
|
||||
* if the files exists, the data will be written at the end of file.
|
||||
*
|
||||
* test_file_name : Is a character string referencing each calls to
|
||||
* generic_WMOPS_output(). Usually, it is the name of a test
|
||||
* sequence file.
|
||||
*
|
||||
* notPrintWorstWorstCase : Same usage as in WMOPS_output().
|
||||
*/
|
||||
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* Example of how count.h could be used.
|
||||
*
|
||||
* In the example below it is assumed that the init_OBJECT functions
|
||||
* does not use any calls to counter.h or basic_op.h. If this is the case
|
||||
* a call to the function Reset_WMOPS_counter() must be done after each call
|
||||
* to init_OBJECT if these operations is not to be included in the statistics.
|
||||
*/
|
||||
|
||||
int main(){
|
||||
int spe1Id,spe2Id,cheId;
|
||||
|
||||
/* initiate counters and objects */
|
||||
spe1Id=getCounterId("Spe 5k8");
|
||||
setCounter(spe1Id);
|
||||
Init_WMOPS_counter ();
|
||||
init_spe1(...);
|
||||
|
||||
spe2Id=getCounterId("Spe 12k2");
|
||||
setCounter(spe2Id);
|
||||
Init_WMOPS_counter ();
|
||||
init_spe2(...);
|
||||
|
||||
cheId=getCounterId("Channel encoder");
|
||||
setCounter(cheId);
|
||||
Init_WMOPS_counter ();
|
||||
init_che(...);
|
||||
...
|
||||
while(data){
|
||||
test(); /* Note this call to test(); */
|
||||
if(useSpe1)
|
||||
setCounter(spe1Id);
|
||||
else
|
||||
setCounter(spe2Id);
|
||||
Reset_WMOPS_counter();
|
||||
speEncode(...);
|
||||
WMOPS_output(0); /* Normal routine for displaying WMOPS info */
|
||||
|
||||
setCounter(cheId);
|
||||
Reset_WMOPS_counter();
|
||||
preChannelInter(...); fwc(); /* Note the call to fwc() for each part*/
|
||||
convolve(...); fwc(); /* of the channel encoder. */
|
||||
interleave(...); fwc();
|
||||
WMOPS_output(0); /* Normal routine for displaying WMOPS info */
|
||||
}
|
||||
}
|
||||
#endif /* #if 0*/
|
||||
|
||||
|
||||
#endif /* _COUNT_H */
|
||||
|
||||
|
||||
/* end of file */
|
||||
@@ -1,688 +0,0 @@
|
||||
/*
|
||||
===========================================================================
|
||||
File: ENH40.C v.2.3 - 30.Nov.2009
|
||||
===========================================================================
|
||||
|
||||
ITU-T STL BASIC OPERATORS
|
||||
|
||||
40-BIT ARITHMETIC OPERATORS
|
||||
|
||||
History:
|
||||
07 Nov 04 v2.0 Incorporation of new 32-bit / 40-bit / control
|
||||
operators for the ITU-T Standard Tool Library as
|
||||
described in Geneva, 20-30 January 2004 WP 3/16 Q10/16
|
||||
TD 11 document and subsequent discussions on the
|
||||
wp3audio@yahoogroups.com email reflector.
|
||||
|
||||
31 Mar 15 v2.1E Removal of operators not used in the EVS codec.
|
||||
|
||||
============================================================================
|
||||
*/
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Enhanced 40 bit operators :
|
||||
*
|
||||
* Mpy_32_16_ss()
|
||||
* Mpy_32_32_ss()
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Include-Files
|
||||
*
|
||||
*****************************************************************************/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "stl.h"
|
||||
|
||||
#if (WMOPS)
|
||||
extern BASIC_OP multiCounter[MAXCOUNTERS];
|
||||
extern int currCounter;
|
||||
#endif /* if WMOPS */
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Local Functions
|
||||
*
|
||||
*****************************************************************************/
|
||||
static __inline Word40 L40_shr( Word40 L40_var1, Word16 var2);
|
||||
static __inline Word40 L40_shl( Word40 L40_var1, Word16 var2);
|
||||
static __inline Word40 L40_set( Word40 L40_var1);
|
||||
static __inline UWord16 Extract40_L( Word40 L40_var1);
|
||||
static __inline Word40 L40_mult( Word16 var1, Word16 var2);
|
||||
static __inline Word40 L40_add( Word40 L40_var1, Word40 L40_var2);
|
||||
static __inline Word40 L40_mac( Word40 L40_var1, Word16 var2, Word16 var3);
|
||||
static __inline UWord32 L_Extract40( Word40 L40_var1) ;
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Macros for 40 bit arithmetic overflow management :
|
||||
* Upon 40-bit overflow beyond MAX_40 or underflow beyond MIN_40,
|
||||
* the application will exit.
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define L40_OVERFLOW_OCCURED( L40_var1) (Overflow = 1, exit(1), L40_var1)
|
||||
#define L40_UNDERFLOW_OCCURED( L40_var1) (Overflow = 1, exit(2), L40_var1)
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Constants and Globals
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Functions
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Function Name : Mpy_32_16_ss
|
||||
*
|
||||
* Purpose :
|
||||
*
|
||||
* Multiplies the 2 signed values L_var1 and var2 with saturation control
|
||||
* on 48-bit. The operation is performed in fractional mode :
|
||||
* - L_var1 is supposed to be in 1Q31 format.
|
||||
* - var2 is supposed to be in 1Q15 format.
|
||||
* - The result is produced in 1Q47 format : L_varout_h points to the
|
||||
* 32 MSBits while varout_l points to the 16 LSBits.
|
||||
*
|
||||
* Complexity weight : 2
|
||||
*
|
||||
* Inputs :
|
||||
*
|
||||
* L_var1 32 bit long signed integer (Word32) whose value falls in
|
||||
* the range : 0x8000 0000 <= L_var1 <= 0x7fff ffff.
|
||||
*
|
||||
* var2 16 bit short signed integer (Word16) whose value falls in
|
||||
* the range : 0xffff 8000 <= var2 <= 0x0000 7fff.
|
||||
*
|
||||
* Outputs :
|
||||
*
|
||||
* *L_varout_h 32 bit long signed integer (Word32) whose value falls in
|
||||
* the range : 0x8000 0000 <= L_varout_h <= 0x7fff ffff.
|
||||
*
|
||||
* *varout_l 16 bit short unsigned integer (UWord16) whose value falls in
|
||||
* the range : 0x0000 0000 <= varout_l <= 0x0000 ffff.
|
||||
*
|
||||
* Return Value :
|
||||
*
|
||||
* none
|
||||
*
|
||||
*****************************************************************************/
|
||||
void Mpy_32_16_ss( Word32 L_var1, Word16 var2, Word32 *L_varout_h, UWord16 *varout_l) {
|
||||
Word16 var1_h;
|
||||
UWord16 uvar1_l;
|
||||
Word40 L40_var1;
|
||||
|
||||
if( (L_var1 == ( Word32) 0x80000000)
|
||||
&& (var2 == ( Word16) 0x8000)) {
|
||||
*L_varout_h = 0x7fffffff;
|
||||
*varout_l = ( UWord16) 0xffff;
|
||||
|
||||
} else {
|
||||
uvar1_l = extract_l( L_var1);
|
||||
var1_h = extract_h( L_var1);
|
||||
|
||||
/* Below line can not overflow, so we can use << instead of L40_shl. */
|
||||
L40_var1 = (( Word40) (( Word32) var2 * ( Word32) uvar1_l)) << 1;
|
||||
|
||||
*varout_l = Extract40_L( L40_var1);
|
||||
|
||||
L40_var1 = L40_shr( L40_var1, 16);
|
||||
L40_var1 = L40_mac( L40_var1, var2, var1_h);
|
||||
|
||||
*L_varout_h = L_Extract40( L40_var1);
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].extract_l--;
|
||||
multiCounter[currCounter].extract_h--;
|
||||
multiCounter[currCounter].Extract40_L--;
|
||||
multiCounter[currCounter].L40_shr--;
|
||||
multiCounter[currCounter].L40_mac--;
|
||||
multiCounter[currCounter].L_Extract40--;
|
||||
#endif /* if WMOPS */
|
||||
}
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].Mpy_32_16_ss++;
|
||||
#endif /* if WMOPS */
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Function Name : Mpy_32_32_ss
|
||||
*
|
||||
* Purpose :
|
||||
*
|
||||
* Multiplies the 2 signed values L_var1 and L_var2 with saturation control
|
||||
* on 64-bit. The operation is performed in fractional mode :
|
||||
* - L_var1 and L_var2 are supposed to be in 1Q31 format.
|
||||
* - The result is produced in 1Q63 format : L_varout_h points to the
|
||||
* 32 MSBits while L_varout_l points to the 32 LSBits.
|
||||
*
|
||||
* Complexity weight : 4
|
||||
*
|
||||
* Inputs :
|
||||
*
|
||||
* L_var1 32 bit long signed integer (Word32) whose value falls in the
|
||||
* range : 0x8000 0000 <= L_var1 <= 0x7fff ffff.
|
||||
*
|
||||
* L_var2 32 bit long signed integer (Word32) whose value falls in the
|
||||
* range : 0x8000 0000 <= L_var2 <= 0x7fff ffff.
|
||||
*
|
||||
* Outputs :
|
||||
*
|
||||
* *L_varout_h 32 bit long signed integer (Word32) whose value falls in
|
||||
* the range : 0x8000 0000 <= L_varout_h <= 0x7fff ffff.
|
||||
*
|
||||
* *L_varout_l 32 bit short unsigned integer (UWord32) whose value falls in
|
||||
* the range : 0x0000 0000 <= L_varout_l <= 0xffff ffff.
|
||||
*
|
||||
*
|
||||
* Return Value :
|
||||
*
|
||||
* none
|
||||
*
|
||||
*****************************************************************************/
|
||||
void Mpy_32_32_ss( Word32 L_var1, Word32 L_var2, Word32 *L_varout_h, UWord32 *L_varout_l) {
|
||||
UWord16 uvar1_l, uvar2_l;
|
||||
Word16 var1_h, var2_h;
|
||||
Word40 L40_var1;
|
||||
|
||||
if( (L_var1 == ( Word32)0x80000000)
|
||||
&& (L_var2 == ( Word32)0x80000000)) {
|
||||
*L_varout_h = 0x7fffffff;
|
||||
*L_varout_l = ( UWord32)0xffffffff;
|
||||
|
||||
} else {
|
||||
|
||||
uvar1_l = extract_l( L_var1);
|
||||
var1_h = extract_h( L_var1);
|
||||
uvar2_l = extract_l( L_var2);
|
||||
var2_h = extract_h( L_var2);
|
||||
|
||||
/* Below line can not overflow, so we can use << instead of L40_shl. */
|
||||
L40_var1 = (( Word40) (( UWord32) uvar2_l * ( UWord32) uvar1_l)) << 1;
|
||||
|
||||
*L_varout_l = 0x0000ffff & L_Extract40( L40_var1);
|
||||
|
||||
L40_var1 = L40_shr( L40_var1, 16);
|
||||
L40_var1 = L40_add( L40_var1, (( Word40) (( Word32) var2_h * ( Word32) uvar1_l)) << 1);
|
||||
L40_var1 = L40_add( L40_var1, (( Word40) (( Word32) var1_h * ( Word32) uvar2_l)) << 1);
|
||||
*L_varout_l |= (L_Extract40( L40_var1)) << 16;
|
||||
|
||||
L40_var1 = L40_shr( L40_var1, 16);
|
||||
L40_var1 = L40_mac( L40_var1, var1_h, var2_h);
|
||||
|
||||
*L_varout_h = L_Extract40( L40_var1);
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].extract_l-=2;
|
||||
multiCounter[currCounter].extract_h-=2;
|
||||
multiCounter[currCounter].L_Extract40-=3;
|
||||
multiCounter[currCounter].L40_shr-=2;
|
||||
multiCounter[currCounter].L40_add-=2;
|
||||
multiCounter[currCounter].L40_mac--;
|
||||
#endif /* if WMOPS */
|
||||
}
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].Mpy_32_32_ss++;
|
||||
#endif /* if WMOPS */
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Function Name : L40_set
|
||||
*
|
||||
* Purpose :
|
||||
*
|
||||
* Assigns a 40 constant to a Word40 with adequate initialization depending
|
||||
* on underlying architecture constraints (for example to keep consistency
|
||||
* of sign bits). Current implementation only validated on MSVC++6.0.
|
||||
*
|
||||
* Complexity weight : 3
|
||||
*
|
||||
* Inputs :
|
||||
*
|
||||
* L40_var1 40 bit long signed integer (Word40) whose value falls in the
|
||||
* range : MIN_40 <= L40_var1 <= MAX_40.
|
||||
*
|
||||
* Outputs :
|
||||
*
|
||||
* none
|
||||
*
|
||||
* Return Value :
|
||||
*
|
||||
* L40_var_out 40 bit long signed integer (Word40) whose value falls in
|
||||
* the range : MIN_40 <= L40_var_out <= MAX_40.
|
||||
*
|
||||
*****************************************************************************/
|
||||
/*#ifdef _MSC_VER*/
|
||||
static __inline Word40 L40_set( Word40 L40_var1) {
|
||||
Word40 L40_var_out;
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER <= 1200)
|
||||
L40_var_out = L40_var1 & 0x000000ffffffffff;
|
||||
|
||||
if( L40_var1 & 0x8000000000)
|
||||
L40_var_out = L40_var_out | 0xffffff0000000000;
|
||||
#else
|
||||
L40_var_out = L40_var1 & 0x000000ffffffffffLL;
|
||||
|
||||
if( L40_var1 & 0x8000000000LL)
|
||||
L40_var_out = L40_var_out | 0xffffff0000000000LL;
|
||||
#endif
|
||||
|
||||
#if WMOPS
|
||||
multiCounter[currCounter].L40_set++;
|
||||
#endif /* if WMOPS */
|
||||
|
||||
return( L40_var_out);
|
||||
}
|
||||
/*#endif*/ /* ifdef _MSC_VER */
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Function Name : Extract40_L
|
||||
*
|
||||
* Purpose :
|
||||
*
|
||||
* Returns the bits [15-0] of L40_var1.
|
||||
*
|
||||
* Complexity weight : 1
|
||||
*
|
||||
* Inputs :
|
||||
*
|
||||
* L40_var1 40 bit long signed integer (Word40) whose value falls in the
|
||||
* range : MIN_40 <= L40_var1 <= MAX_40.
|
||||
*
|
||||
* Outputs :
|
||||
*
|
||||
* none
|
||||
*
|
||||
* Return Value :
|
||||
*
|
||||
* var_out 16 bit short unsigned integer (UWord16) whose value falls in
|
||||
* the range : MIN_U_16 <= var_out <= MAX_U_16.
|
||||
*
|
||||
*****************************************************************************/
|
||||
static __inline UWord16 Extract40_L( Word40 L40_var1) {
|
||||
UWord16 var_out;
|
||||
|
||||
var_out = ( UWord16)( L40_var1);
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].Extract40_L++;
|
||||
#endif /* if WMOPS */
|
||||
|
||||
return( var_out);
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Function Name : L40_mult
|
||||
*
|
||||
* Purpose :
|
||||
*
|
||||
* Multiplies var1 by var2 and shifts the result left by 1. Returns the
|
||||
* full precision result on 40-bit.
|
||||
* L40_mult( var1, var2) = shiftleft(( var1 times var2), 1)
|
||||
*
|
||||
* Complexity weight : 1
|
||||
*
|
||||
* Inputs :
|
||||
*
|
||||
* var1 16 bit short signed integer (Word16) whose value falls in
|
||||
* the range : MIN_16 <= var1 <= MAX_16.
|
||||
*
|
||||
* var2 16 bit short signed integer (Word16) whose value falls in
|
||||
* the range : MIN_16 <= var2 <= MAX_16.
|
||||
*
|
||||
* Outputs :
|
||||
*
|
||||
* none
|
||||
*
|
||||
* Return Value :
|
||||
*
|
||||
* L40_var_out 40 bit long signed integer (Word40) whose value falls in
|
||||
* the range : MIN_40 <= L40_var_out <= MAX_40.
|
||||
*
|
||||
*****************************************************************************/
|
||||
static __inline Word40 L40_mult( Word16 var1, Word16 var2) {
|
||||
Word32 L_var_out;
|
||||
Word40 L40_var_out;
|
||||
|
||||
L_var_out = ( Word32) var1 * ( Word32) var2;
|
||||
L40_var_out = ( Word40) L_var_out;
|
||||
|
||||
/* Below line can not overflow, so we can use << instead of L40_shl. */
|
||||
L40_var_out = L40_var_out << 1;
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L40_mult++;
|
||||
#endif /* if WMOPS */
|
||||
|
||||
return( L40_var_out);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Function Name : L40_add
|
||||
*
|
||||
* Purpose :
|
||||
*
|
||||
* Adds L40_var1 and L40_var2 and returns the 40-bit result.
|
||||
* Calls the macro L40_UNDERFLOW_OCCURED() in case of underflow on 40-bit.
|
||||
* Calls the macro L40_OVERFLOW_OCCURED() in case of overflow on 40-bit.
|
||||
*
|
||||
* Complexity weight : 1
|
||||
*
|
||||
* Inputs :
|
||||
*
|
||||
* L40_var1 40 bit long signed integer (Word40) whose value falls in the
|
||||
* range : MIN_40 <= L40_var1 <= MAX_40.
|
||||
*
|
||||
* L40_var2 40 bit long signed integer (Word40) whose value falls in the
|
||||
* range : MIN_40 <= L40_var2 <= MAX_40.
|
||||
*
|
||||
* Outputs :
|
||||
*
|
||||
* none
|
||||
*
|
||||
* Return Value :
|
||||
*
|
||||
* L40_var_out 40 bit long signed integer (Word40) whose value falls in
|
||||
* the range : MIN_40 <= L40_var_out <= MAX_40.
|
||||
*
|
||||
*****************************************************************************/
|
||||
static __inline Word40 L40_add( Word40 L40_var1, Word40 L40_var2) {
|
||||
Word40 L40_var_out;
|
||||
|
||||
L40_var_out = L40_var1 + L40_var2;
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER <= 1200)
|
||||
if( ((( L40_var1 & 0x8000000000) >> 39) != 0)
|
||||
&& ((( L40_var2 & 0x8000000000) >> 39) != 0)
|
||||
&& ((( L40_var_out & 0x8000000000) >> 39) == 0)) {
|
||||
L40_var_out = L40_UNDERFLOW_OCCURED( L40_var_out);
|
||||
|
||||
} else if( (((L40_var1 & 0x8000000000) >> 39) == 0)
|
||||
&& (((L40_var2 & 0x8000000000) >> 39) == 0)
|
||||
&& (((L40_var_out & 0x8000000000) >> 39) != 0)) {
|
||||
L40_var_out = L40_OVERFLOW_OCCURED( L40_var_out);
|
||||
}
|
||||
#else
|
||||
if( ((( L40_var1 & 0x8000000000LL) >> 39) != 0)
|
||||
&& ((( L40_var2 & 0x8000000000LL) >> 39) != 0)
|
||||
&& ((( L40_var_out & 0x8000000000LL) >> 39) == 0)) {
|
||||
L40_var_out = L40_UNDERFLOW_OCCURED( L40_var_out);
|
||||
|
||||
} else if( (((L40_var1 & 0x8000000000LL) >> 39) == 0)
|
||||
&& (((L40_var2 & 0x8000000000LL) >> 39) == 0)
|
||||
&& (((L40_var_out & 0x8000000000LL) >> 39) != 0)) {
|
||||
L40_var_out = L40_OVERFLOW_OCCURED( L40_var_out);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L40_add++;
|
||||
#endif /* if WMOPS */
|
||||
|
||||
BASOP_CHECK();
|
||||
|
||||
return( L40_var_out);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Function Name : L40_mac
|
||||
*
|
||||
* Purpose :
|
||||
*
|
||||
* Multiplies var2 by var3. Shifts left the 40-bit result by 1 and adds
|
||||
* the result to L40_var1. Returns a 40 bit result.
|
||||
* L40_mac( L40_var1, var2, var3)
|
||||
* = L40_add( L40_var1, L40_mult( var2, var3))
|
||||
* Calls the macro L40_UNDERFLOW_OCCURED() in case of underflow on 40-bit.
|
||||
* Calls the macro L40_OVERFLOW_OCCURED() in case of overflow on 40-bit.
|
||||
*
|
||||
* Complexity weight : 1
|
||||
*
|
||||
* Inputs :
|
||||
*
|
||||
* L40_var1 40 bit long signed integer (Word40) whose value falls in the
|
||||
* range : MIN_40 <= L40_var1 <= MAX_40.
|
||||
*
|
||||
* var2 16 bit short signed integer (Word16) whose value falls in
|
||||
* the range : MIN_16 <= var2 <= MAX_16.
|
||||
*
|
||||
* var3 16 bit short signed integer (Word16) whose value falls in
|
||||
* the range : MIN_16 <= var3 <= MAX_16.
|
||||
*
|
||||
* Outputs :
|
||||
*
|
||||
* none
|
||||
*
|
||||
* Return Value :
|
||||
*
|
||||
* L40_var_out 40 bit long signed integer (Word40) whose value falls in
|
||||
* the range : MIN_40 <= L40_var_out <= MAX_40.
|
||||
*
|
||||
*****************************************************************************/
|
||||
static __inline Word40 L40_mac( Word40 L40_var1, Word16 var2, Word16 var3) {
|
||||
Word40 L40_var_out;
|
||||
|
||||
L40_var_out = L40_mult( var2, var3);
|
||||
L40_var_out = L40_add( L40_var1, L40_var_out);
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L40_mult--;
|
||||
multiCounter[currCounter].L40_add--;
|
||||
multiCounter[currCounter].L40_mac++;
|
||||
#endif /* if WMOPS */
|
||||
|
||||
return( L40_var_out);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Function Name : L_Extract40
|
||||
*
|
||||
* Purpose :
|
||||
*
|
||||
* Returns the bits [31-0] of L40_var1.
|
||||
*
|
||||
* Complexity weight : 1
|
||||
*
|
||||
* Inputs :
|
||||
*
|
||||
* L40_var1 40 bit long signed integer (Word40) whose value falls in the
|
||||
* range : MIN_40 <= L40_var1 <= MAX_40.
|
||||
*
|
||||
* Outputs :
|
||||
*
|
||||
* none
|
||||
*
|
||||
* Return Value :
|
||||
*
|
||||
* L_var_out 32 bit long unsigned integer (UWord32) whose value falls in
|
||||
* range : MIN_U_32 <= L_var_out <= MAX_U_32.
|
||||
*
|
||||
*****************************************************************************/
|
||||
static __inline UWord32 L_Extract40( Word40 L40_var1) {
|
||||
UWord32 L_var_out;
|
||||
|
||||
L_var_out = ( UWord32) L40_var1;
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_Extract40++;
|
||||
#endif /* if WMOPS */
|
||||
|
||||
return(L_var_out);
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Function Name : L40_shl
|
||||
*
|
||||
* Purpose :
|
||||
*
|
||||
* Arithmetically shifts left L40_var1 by var2 positions.
|
||||
* - If var2 is negative, L40_var1 is shifted to the LSBits by (-var2)
|
||||
* positions with extension of the sign bit.
|
||||
* - If var2 is positive, L40_var1 is shifted to the MSBits by (var2)
|
||||
* positions.
|
||||
* Calls the macro L40_UNDERFLOW_OCCURED() in case of underflow on 40-bit.
|
||||
* Calls the macro L40_OVERFLOW_OCCURED() in case of overflow on 40-bit.
|
||||
*
|
||||
* Complexity weight : 1
|
||||
*
|
||||
* Inputs :
|
||||
*
|
||||
* L40_var1 40 bit long signed integer (Word40) whose value falls in the
|
||||
* range : MIN_40 <= L40_var1 <= MAX_40.
|
||||
*
|
||||
* var2 16 bit short signed integer (Word16) whose value falls in
|
||||
* the range : MIN_16 <= var2 <= MAX_16.
|
||||
*
|
||||
* Outputs :
|
||||
*
|
||||
* none
|
||||
*
|
||||
* Return Value :
|
||||
*
|
||||
* L40_var_out 40 bit long signed integer (Word40) whose value falls in
|
||||
* the range : MIN_40 <= L40_var_out <= MAX_40.
|
||||
*
|
||||
*****************************************************************************/
|
||||
static __inline Word40 L40_shl( Word40 L40_var1, Word16 var2) {
|
||||
|
||||
Word40 L40_var_out;
|
||||
#if defined(_MSC_VER) && (_MSC_VER <= 1200)
|
||||
Word40 L40_constant = L40_set( 0xc000000000);
|
||||
#else
|
||||
Word40 L40_constant = L40_set( 0xc000000000LL);
|
||||
#endif
|
||||
|
||||
if( var2 < 0) {
|
||||
var2 = -var2;
|
||||
L40_var_out = L40_shr( L40_var1, var2);
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L40_shr--;
|
||||
#endif /* if WMOPS */
|
||||
}
|
||||
|
||||
else {
|
||||
L40_var_out = L40_var1;
|
||||
|
||||
for ( ; var2 > 0; var2--) {
|
||||
#if defined(_MSC_VER) && (_MSC_VER <= 1200)
|
||||
if( L40_var_out > 0x003fffffffff) {
|
||||
#else
|
||||
if( L40_var_out > 0x003fffffffffLL) {
|
||||
#endif
|
||||
L40_var_out = L40_OVERFLOW_OCCURED( L40_var_out);
|
||||
break;
|
||||
}
|
||||
|
||||
else if ( L40_var_out < L40_constant) {
|
||||
L40_var_out = L40_UNDERFLOW_OCCURED( L40_var_out);
|
||||
break;
|
||||
}
|
||||
|
||||
else {
|
||||
L40_var_out = L40_var_out << 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L40_set--;
|
||||
multiCounter[currCounter].L40_shl++;
|
||||
#endif /* if WMOPS */
|
||||
|
||||
BASOP_CHECK();
|
||||
|
||||
return( L40_var_out);
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Function Name : L40_shr
|
||||
*
|
||||
* Purpose :
|
||||
*
|
||||
* Arithmetically shifts right L40_var1 by var2 positions.
|
||||
* - If var2 is positive, L40_var1 is shifted to the LSBits by (var2)
|
||||
* positions with extension of the sign bit.
|
||||
* - If var2 is negative, L40_var1 is shifted to the MSBits by (-var2)
|
||||
* positions.
|
||||
* Calls the macro L40_UNDERFLOW_OCCURED() in case of underflow on 40-bit.
|
||||
* Calls the macro L40_OVERFLOW_OCCURED() in case of overflow on 40-bit.
|
||||
*
|
||||
* Complexity weight : 1
|
||||
*
|
||||
* Inputs :
|
||||
*
|
||||
* L40_var1 40 bit long signed integer (Word40) whose value falls in the
|
||||
* range : MIN_40 <= L40_var1 <= MAX_40.
|
||||
*
|
||||
* var2 16 bit short signed integer (Word16) whose value falls in
|
||||
* the range : MIN_16 <= var2 <= MAX_16.
|
||||
*
|
||||
* Outputs :
|
||||
*
|
||||
* none
|
||||
*
|
||||
* Return Value :
|
||||
*
|
||||
* L40_var_out 40 bit long signed integer (Word40) whose value falls in
|
||||
* the range : MIN_40 <= L40_var_out <= MAX_40.
|
||||
*
|
||||
*****************************************************************************/
|
||||
static __inline Word40 L40_shr( Word40 L40_var1, Word16 var2) {
|
||||
Word40 L40_var_out;
|
||||
|
||||
if( var2 < 0) {
|
||||
var2 = -var2;
|
||||
L40_var_out = L40_shl ( L40_var1, var2);
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L40_shl--;
|
||||
#endif /* if WMOPS */
|
||||
|
||||
} else {
|
||||
L40_var_out = L40_var1 >> var2;
|
||||
|
||||
}
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L40_shr++;
|
||||
#endif /* if WMOPS */
|
||||
|
||||
return( L40_var_out);
|
||||
}
|
||||
|
||||
/* end of file */
|
||||
@@ -1,44 +0,0 @@
|
||||
/*
|
||||
===========================================================================
|
||||
File: ENH40.H v.2.3 - 30.Nov.2009
|
||||
===========================================================================
|
||||
|
||||
ITU-T STL BASIC OPERATORS
|
||||
|
||||
40-BIT ARITHMETIC OPERATORS
|
||||
|
||||
History:
|
||||
07 Nov 04 v2.0 Incorporation of new 32-bit / 40-bit / control
|
||||
operators for the ITU-T Standard Tool Library as
|
||||
described in Geneva, 20-30 January 2004 WP 3/16 Q10/16
|
||||
TD 11 document and subsequent discussions on the
|
||||
wp3audio@yahoogroups.com email reflector.
|
||||
|
||||
March 06 v2.1 Changed to improve portability.
|
||||
|
||||
31 Mar 15 v2.1E Removal of operators not used in the EVS codec.
|
||||
|
||||
============================================================================
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _ENH40_H
|
||||
#define _ENH40_H
|
||||
|
||||
#include "stl.h"
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Prototypes for enhanced 40 bit arithmetic operators
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
void Mpy_32_16_ss( Word32 L_var1, Word16 var2, Word32 *L_varout_h, UWord16 *varout_l);
|
||||
void Mpy_32_32_ss( Word32 L_var1, Word32 L_var2, Word32 *L_varout_h, UWord32 *L_varout_l);
|
||||
|
||||
#endif /*_ENH40_H*/
|
||||
|
||||
|
||||
/* end of file */
|
||||
|
||||
|
||||
@@ -1,430 +0,0 @@
|
||||
/*
|
||||
===========================================================================
|
||||
File: ENHUL32.C v.0.5 - 21.March.2014
|
||||
===========================================================================
|
||||
|
||||
ENHANCED UNSIGNED 32-BIT ARITHMETIC OPERATORS
|
||||
History:
|
||||
|
||||
============================================================================
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Enhanced Unsigned 32 bit operators :
|
||||
* see complete list in .h file
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Include-Files
|
||||
*
|
||||
*****************************************************************************/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "stl.h"
|
||||
#include "enhUL32.h"
|
||||
|
||||
|
||||
#if (WMOPS)
|
||||
extern BASIC_OP multiCounter[MAXCOUNTERS];
|
||||
extern int currCounter;
|
||||
#endif /* if WMOPS */
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Constants and Globals
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Functions
|
||||
*
|
||||
*****************************************************************************/
|
||||
#ifdef ENHUL32
|
||||
|
||||
/*___________________________________________________________________________
|
||||
| |
|
||||
| Function Name : UL_deposit_l |
|
||||
| |
|
||||
| Purpose : |
|
||||
| |
|
||||
| Deposit the 16 bit var1 into the 16 LS bits of the 32 bit output. The |
|
||||
| 16 MS bits of the output are not sign extended. |
|
||||
| |
|
||||
|___________________________________________________________________________ */
|
||||
|
||||
UWord32 UL_deposit_l(UWord16 uvar){
|
||||
UWord32 UL_result;
|
||||
UL_result = (UWord32)uvar; /* no sign extension*/
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_deposit_l++;
|
||||
#endif
|
||||
return (UL_result);
|
||||
}
|
||||
|
||||
|
||||
/*___________________________________________________________________________
|
||||
| |
|
||||
| Function Name : norm_ul |
|
||||
| |
|
||||
| Purpose : |
|
||||
| |
|
||||
| Produces the number of left shifts needed to normalize the 32 bit varia-|
|
||||
| ble UL_var1 for positive values on the interval with minimum of |
|
||||
| 0 and maximum of 0xffffffff, ; in order to normalize the |
|
||||
| result, the following operation must be done : |
|
||||
| |
|
||||
| norm_UL_var1 = UL_lshl(UL_var1, norm_ul(UL_var1)). |
|
||||
| |
|
||||
| Complexity weight : 1 |
|
||||
| |
|
||||
| Inputs : |
|
||||
| |
|
||||
| UL_var1 |
|
||||
| 32 bit long unsigned integer (UWord32) whose value falls in the |
|
||||
| range : 0x0000 0000 <= var1 <= 0xffff ffff. |
|
||||
| |
|
||||
| Outputs : |
|
||||
| |
|
||||
| none |
|
||||
| |
|
||||
| Return Value : |
|
||||
| |
|
||||
| var_out |
|
||||
| 16 bit short signed integer (Word16) whose value falls in the |
|
||||
| range : 0x0000 0000 <= var_out <= 0x0000 001f. (0..31d) |
|
||||
|___________________________________________________________________________|
|
||||
*/
|
||||
Word16 norm_ul( UWord32 UL_var1)
|
||||
{
|
||||
Word16 var_out;
|
||||
|
||||
if (UL_var1 == 0)
|
||||
{
|
||||
var_out = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* simply test shift up until highest bit is set */
|
||||
for (var_out = 0; UL_var1 < (UWord32) 0x80000000U; var_out++)
|
||||
{
|
||||
UL_var1 <<= 1;
|
||||
}
|
||||
}
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].norm_l++; /* now new counter added for UL_ */
|
||||
#endif
|
||||
return (var_out);
|
||||
}
|
||||
|
||||
|
||||
/*___________________________________________________________________________
|
||||
| |
|
||||
| Function Name : UL_addNs |
|
||||
| |
|
||||
| Purpose : |
|
||||
| |
|
||||
| 32 bits addition of the two unsigned 32 bits variables |
|
||||
| (L_var1+L_var2) with overflow control, but without saturation |
|
||||
|
|
||||
| Outputs : |
|
||||
| *wrap = 1 if wrap occured, otherwize 0 |
|
||||
|
|
||||
| Return Value :
|
||||
| UL_var3 = modulo(UL_var1+UL_var2,32)
|
||||
|___________________________________________________________________________|
|
||||
*/
|
||||
|
||||
UWord32 UL_addNs(UWord32 UL_var1, UWord32 UL_var2, UWord16 * wrap )
|
||||
{
|
||||
UWord32 UL_var3;
|
||||
|
||||
/* STL Overflow flag is not updated */
|
||||
|
||||
UL_var3 = UL_var1 + UL_var2; /* 32bit wrap may occur, like in C */
|
||||
|
||||
if ( ( ((UWord64)UL_var1 + (UWord64)UL_var2) ) > ((UWord64) maxUWord32 ) )
|
||||
{
|
||||
*wrap = 1; /* wrapped output */
|
||||
}
|
||||
else
|
||||
{
|
||||
*wrap = 0;
|
||||
}
|
||||
|
||||
#if WMOPS
|
||||
multiCounter[currCounter].L_add++; /* now new counter added for UL_ */
|
||||
#endif
|
||||
return UL_var3;
|
||||
}
|
||||
|
||||
/*___________________________________________________________________________
|
||||
| |
|
||||
| Function Name : UL_subNs |
|
||||
| |
|
||||
| Purpose : |
|
||||
| |
|
||||
| 32 bits subtraction of the two unsigned 32 bits variables |
|
||||
| (L_var1-L_var2) with overflow control, but without saturation |
|
||||
|
|
||||
| Outputs : |
|
||||
| *sgn = 1 if wrap (to "negative" occured, otherwise 0 |
|
||||
|
|
||||
| Return Value :
|
||||
| UL_var3 = modulo(UL_var1-UL_var2,32)
|
||||
|___________________________________________________________________________|
|
||||
*/
|
||||
|
||||
UWord32 UL_subNs(UWord32 UL_var1, UWord32 UL_var2, UWord16 * sgn)
|
||||
{
|
||||
UWord32 UL_var3;
|
||||
|
||||
UL_var3 = UL_var1 - UL_var2; /*wrap may occur, like in C */
|
||||
if (UL_var1 >= UL_var2)
|
||||
{
|
||||
*sgn = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
*sgn = 1; /* "negative" , wrapped output */
|
||||
}
|
||||
|
||||
#if WMOPS
|
||||
multiCounter[currCounter].L_sub++; /* now new counter added for UL_ */
|
||||
#endif
|
||||
return UL_var3;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Function Name : Mpy_32_16_uu
|
||||
*
|
||||
* Purpose :
|
||||
*
|
||||
* Multiplies the 2 unsigned values UL_var1 and uvar2
|
||||
* with saturation control on 48-bit.( does not happen for unsigned)
|
||||
* The operation is performed in fractional mode :
|
||||
* - UL_var1 is supposed to be in Q32 format.
|
||||
* - var2 is supposed to be in Q16 format.
|
||||
* - The result is produced in Q48 format : UL_varout_h points to the
|
||||
* 32 MSBits while varout_l points to the 16 LSBits.
|
||||
*
|
||||
* Complexity weight : 2
|
||||
*
|
||||
* Inputs :
|
||||
*
|
||||
* UL_var1 32 bit long unsigned integer (UWord32) whose value falls in
|
||||
* the range : 0x0000 0000 <= L_var1 <= 0xffff ffff.
|
||||
*
|
||||
* var2 16 bit short unsigned integer (UWord16) whose value falls in
|
||||
* the range : 0x0000 <= var2 <= 0x0000 ffff.
|
||||
*
|
||||
* Outputs :
|
||||
*
|
||||
* *UL_varout_h 32 bit long unsigned integer (UWord32) whose value falls in
|
||||
* the range : 0x0000 0000 <= UL_varout_h <= 0xffff ffff.
|
||||
*
|
||||
* *varout_l 16 bit short unsigned integer (UWord16) whose value falls in
|
||||
* the range : 0x0000 0000 <= varout_l <= 0x0000 ffff.
|
||||
*
|
||||
* Return Value :
|
||||
*
|
||||
* none
|
||||
*
|
||||
*****************************************************************************/
|
||||
void Mpy_32_16_uu( UWord32 UL_var1, UWord16 uvar2, UWord32 *UL_varout_h, UWord16 *varout_l) {
|
||||
UWord64 UL64_var1;
|
||||
|
||||
/* 4294967295 * 65535 < 281474976710655 */
|
||||
/* (uint64(2)^16-1 )*(uint64(2)^32-1) < (uint64(2)^(16+32)-1) */
|
||||
{
|
||||
UL64_var1 = ( UWord64) UL_var1 * ( UWord64)uvar2 ;
|
||||
|
||||
*varout_l = ( UWord16)( UL64_var1 );
|
||||
|
||||
*UL_varout_h = (UWord32)(UL64_var1>>16);
|
||||
}
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].Mpy_32_16_ss++; /* now new counter added for UL_ */
|
||||
#endif /* if WMOPS */
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Function Name : Mpy_32_32_uu
|
||||
*
|
||||
* Purpose :
|
||||
*
|
||||
* Multiplies the 2 unsigned values UL_var1 and UL_var2
|
||||
* with saturation control on 64-bit. (not needed for unsigned)
|
||||
* The operation is performed in fractional mode :
|
||||
* - UL_var1 and UL_var2 are supposed to be in Q32 format.
|
||||
* - The result is produced in Q64 format : UL_varout_h points to the
|
||||
* 32 MSBits while UL_varout_l points to the 32 LSBits.
|
||||
*
|
||||
* Complexity weight : 4
|
||||
*
|
||||
* Inputs :
|
||||
*
|
||||
* UL_var1 32 bit long unsigned integer (UWord32) whose value falls in the
|
||||
* range : 0x0000 0000 <= L_var1 <= 0xffff ffff.
|
||||
*
|
||||
* UL_var2 32 bit long unsigned integer (UWord32) whose value falls in the
|
||||
* range : 0x0000 0000 <= L_var2 <= 0xffff ffff.
|
||||
*
|
||||
* Outputs :
|
||||
*
|
||||
* *UL_varout_h 32 bit long signed integer (Word32) whose value falls in
|
||||
* the range : 0x0000 0000 <= UL_varout_h <= 0xffff ffff.
|
||||
*
|
||||
* *UL_varout_l 32 bit short unsigned integer (UWord32) whose value falls in
|
||||
* the range : 0x0000 0000 <= UL_varout_l <= 0xffff ffff.
|
||||
*
|
||||
*
|
||||
* Return Value :
|
||||
*
|
||||
* none
|
||||
*
|
||||
*****************************************************************************/
|
||||
void Mpy_32_32_uu( UWord32 UL_var1, UWord32 UL_var2, UWord32 *UL_varout_h, UWord32 *UL_varout_l)
|
||||
{
|
||||
UWord64 UL64_var1;
|
||||
|
||||
/* (uint64(2)^32-1 )*(uint64(2)^32-1) < (uint64(2)^(32+32)-1) */
|
||||
{
|
||||
UL64_var1 = ((UWord64) UL_var1)*((UWord64) UL_var2);
|
||||
*UL_varout_h = (UWord32)(UL64_var1>>32);
|
||||
*UL_varout_l = (UWord32)(UL64_var1);
|
||||
}
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].Mpy_32_32_ss++; /* now new counter added for UL_ */
|
||||
#endif /* if WMOPS */
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Function Name : UL_Mpy_32_32
|
||||
*
|
||||
* Purpose :
|
||||
*
|
||||
* Multiplies the 2 unsigned values UL_var1 and UL_var2
|
||||
* and returns the lower 32 bits, without saturation control.
|
||||
*
|
||||
* - UL_var1 and UL_var2 are supposed to be in Q32 format.
|
||||
* - The result is produced in Q64 format, (the 32 LSBits. )
|
||||
*
|
||||
* operates like a regular 32-by-32 bit unsigned int multiplication in ANSI-C.
|
||||
* UWord32) = (unsigned int)*(unsigned int);
|
||||
*
|
||||
*
|
||||
* Complexity weight : 2
|
||||
*
|
||||
* Inputs :
|
||||
*
|
||||
* UL_var1 32 bit long unsigned integer (UWord32) whose value falls in the
|
||||
* range : 0x0000 0000 <= UL_var1 <= 0xffff ffff.
|
||||
*
|
||||
* UL_var2 32 bit long unsigned integer (UWord32) whose value falls in the
|
||||
* range : 0x0000 0000 <= UL_var2 <= 0xffff ffff.
|
||||
*
|
||||
* Outputs :
|
||||
*
|
||||
* Return Value :
|
||||
* *UL_varout_l 32 bit short unsigned integer (UWord32) whose value falls in
|
||||
* the range : 0x0000 0000 <= UL_varout_l <= 0xffff ffff.
|
||||
*
|
||||
* none
|
||||
*
|
||||
*****************************************************************************/
|
||||
UWord32 UL_Mpy_32_32( UWord32 UL_var1, UWord32 UL_var2)
|
||||
{
|
||||
UWord32 UL_varout_l;
|
||||
|
||||
#define MASK32 0xFFFFFFFFU
|
||||
/* MASK32 may be needed in case Hardware is using larger than 32 bits for UWord32 type) */
|
||||
UL_varout_l = (UL_var1&MASK32)*(UL_var2&MASK32);
|
||||
UL_varout_l = (UL_varout_l&MASK32);
|
||||
#undef MASK32
|
||||
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].Mpy_32_16_ss++; /* now new counters added for UL_ ops*/
|
||||
#endif /* if WMOPS */
|
||||
|
||||
return UL_varout_l;
|
||||
}
|
||||
|
||||
#ifdef STL_TYPECASTS
|
||||
/* (Reuse of existing signed STL "L" operators) with
|
||||
typecasting to make the resulting "UL" code a lot cleaner and more readable. */
|
||||
|
||||
UWord32 UL_lshl( UWord32 UL_var1, Word16 var2) {
|
||||
return( (UWord32)L_lshl( (Word32) UL_var1, var2));
|
||||
}
|
||||
|
||||
UWord32 UL_lshr( UWord32 UL_var1, Word16 var2) {
|
||||
return( (UWord32)L_lshr( (Word32) UL_var1, var2) );
|
||||
}
|
||||
|
||||
UWord32 UL_and(UWord32 UL_var1, UWord32 UL_var2 )
|
||||
{
|
||||
return (UWord32) L_and((Word32)UL_var1,(Word32) UL_var2);
|
||||
}
|
||||
|
||||
UWord32 UL_or(UWord32 UL_var1, UWord32 UL_var2 )
|
||||
{
|
||||
return (UWord32) L_or((Word32)UL_var1,(Word32) UL_var2);
|
||||
}
|
||||
|
||||
UWord32 UL_xor(UWord32 UL_var1, UWord32 UL_var2 )
|
||||
{
|
||||
return (UWord32) L_xor((Word32)UL_var1,(Word32) UL_var2);
|
||||
}
|
||||
|
||||
UWord32 UL_deposit_h(UWord16 uvar1)
|
||||
{
|
||||
return (UWord32) L_deposit_h((Word32)uvar1);
|
||||
}
|
||||
|
||||
UWord16 u_extract_h(UWord32 UL_var1)
|
||||
{
|
||||
return (UWord16) extract_h((Word32)UL_var1);
|
||||
}
|
||||
|
||||
UWord16 u_extract_l(UWord32 UL_var1)
|
||||
{
|
||||
return (UWord32)extract_l((Word32)UL_var1);
|
||||
}
|
||||
|
||||
/* enable convenient reuse of Non-saturating UL_subNs , UL_addNs while "D"iscarding the sgn/wrap output flags */
|
||||
UWord32 UL_subNsD(UWord32 UL_var1, UWord32 UL_var2 )
|
||||
{
|
||||
UWord16 dummy_sign;
|
||||
return UL_subNs(UL_var1,UL_var2,&dummy_sign );
|
||||
}
|
||||
|
||||
UWord32 UL_addNsD(UWord32 UL_var1, UWord32 UL_var2 )
|
||||
{
|
||||
UWord16 dummy_wrap;
|
||||
return UL_addNs(UL_var1,UL_var2,&dummy_wrap );
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ENHUL32 */
|
||||
|
||||
/* end of file */
|
||||
@@ -1,82 +0,0 @@
|
||||
/*
|
||||
===========================================================================
|
||||
File: ENHUL32.H v.0.5 - 19.Mar.2014
|
||||
===========================================================================
|
||||
|
||||
|
||||
============================================================================
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _ENHUL32_H
|
||||
#define _ENHUL32_H
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Constants and Globals
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define ENHUL32 /* all the enhanced unsigned operators */
|
||||
#define STL_TYPECASTS /* logical shift and bitwise manipulation functions */
|
||||
/* algorithmically exact to existing signed L_lshr and L_lshr */
|
||||
#include "stl.h"
|
||||
|
||||
|
||||
#ifndef UWord64
|
||||
#define UWord64 unsigned long long /* for local use inside UL_Mpy_32_* */
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
#if (WMOPS)
|
||||
#include "count.h"
|
||||
extern BASIC_OP multiCounter[MAXCOUNTERS]; /* existing signed counters are reused for unsigedn operators */
|
||||
extern int currCounter;
|
||||
#endif /* if WMOPS */
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Prototypes for enhanced unsigned 32 bit arithmetic operators
|
||||
*
|
||||
*****************************************************************************/
|
||||
UWord32 UL_addNs(UWord32 a, UWord32 b, UWord16* wrap);
|
||||
UWord32 UL_subNs(UWord32 a, UWord32 b, UWord16* sgn);
|
||||
|
||||
UWord32 UL_Mpy_32_32(UWord32 a, UWord32 b);
|
||||
void Mpy_32_32_uu( UWord32 a, UWord32 b, UWord32 *c_h, UWord32 *c_l); /* does not saturate */
|
||||
void Mpy_32_16_uu( UWord32 a, UWord16 b,UWord32 *c_h, UWord16 *c_l); /* does not saturate */
|
||||
|
||||
/* Other */
|
||||
Word16 norm_ul (UWord32 UL_var1);
|
||||
UWord32 UL_deposit_l(UWord16); /* deposit low without sign extension ) */
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Inline Functions
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifdef STL_TYPECASTS
|
||||
/* (Reuse of existing signed STL "L" operators) with
|
||||
typecasting to make the resulting "UL" code a lot cleaner and more readable. */
|
||||
UWord32 UL_lshl( UWord32 UL_var1, Word16 var2);
|
||||
UWord32 UL_lshr( UWord32 UL_var1, Word16 var2);
|
||||
UWord32 UL_and(UWord32 UL_var1, UWord32 UL_var2 );
|
||||
UWord32 UL_or(UWord32 UL_var1, UWord32 UL_var2 );
|
||||
UWord32 UL_xor(UWord32 UL_var1, UWord32 UL_var2 );
|
||||
UWord32 UL_deposit_h(UWord16 uvar1);
|
||||
UWord16 u_extract_h(UWord32 UL_var1);
|
||||
UWord16 u_extract_l(UWord32 UL_var1);
|
||||
|
||||
/* enable convenient reuse of Non-saturating UL_subNs , UL_addNs
|
||||
while "D"iscarding the sgn/wrap output flags */
|
||||
UWord32 UL_subNsD(UWord32 UL_var1, UWord32 UL_var2 );
|
||||
UWord32 UL_addNsD(UWord32 UL_var1, UWord32 UL_var2 );
|
||||
#endif
|
||||
|
||||
#endif /*_ENHUL32_H*/
|
||||
|
||||
/* end of file */
|
||||
@@ -1,88 +0,0 @@
|
||||
/*
|
||||
===========================================================================
|
||||
File: MOVE.H v.2.3 - 30.Nov.2009
|
||||
===========================================================================
|
||||
|
||||
ITU-T STL BASIC OPERATORS
|
||||
|
||||
MOVE & MISC LEGACY OPERATORS
|
||||
|
||||
History:
|
||||
07 Nov 04 v2.0 Incorporation of new 32-bit / 40-bit / control
|
||||
operators for the ITU-T Standard Tool Library as
|
||||
described in Geneva, 20-30 January 2004 WP 3/16 Q10/16
|
||||
TD 11 document and subsequent discussions on the
|
||||
wp3audio@yahoogroups.com email reflector.
|
||||
March 06 v2.1 Changed to improve portability.
|
||||
|
||||
============================================================================
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _MOVE_H
|
||||
#define _MOVE_H
|
||||
|
||||
|
||||
#include "stl.h"
|
||||
|
||||
#if (WMOPS)
|
||||
extern BASIC_OP multiCounter[MAXCOUNTERS];
|
||||
extern int currCounter;
|
||||
#endif /* if WMOPS */
|
||||
|
||||
|
||||
static __inline void move16( void) {
|
||||
#if WMOPS
|
||||
multiCounter[currCounter].move16++;
|
||||
#endif /* if WMOPS */
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static __inline void move32( void) {
|
||||
#if WMOPS
|
||||
multiCounter[currCounter].move32++;
|
||||
#endif /* if WMOPS */
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static __inline void test( void) {
|
||||
#if WMOPS
|
||||
multiCounter[currCounter].Test++;
|
||||
#endif /* if WMOPS */
|
||||
}
|
||||
|
||||
|
||||
static __inline void logic16( void) {
|
||||
#if WMOPS
|
||||
multiCounter[currCounter].Logic16++;
|
||||
#endif /* if WMOPS */
|
||||
}
|
||||
|
||||
|
||||
static __inline void logic32( void) {
|
||||
#if WMOPS
|
||||
multiCounter[currCounter].Logic32++;
|
||||
#endif /* if WMOPS */
|
||||
}
|
||||
|
||||
|
||||
/*-------- legacy ----------*/
|
||||
#define data_move() move16()
|
||||
#define L_data_move() move32()
|
||||
#define data_move_external() move16()
|
||||
#define compare_zero() test()
|
||||
/*-------- end legacy ----------*/
|
||||
|
||||
|
||||
#endif /* _MOVE_H */
|
||||
|
||||
|
||||
/* end of file */
|
||||
@@ -1,77 +0,0 @@
|
||||
/*
|
||||
===========================================================================
|
||||
File: STL.H v.2.3 - 30.Nov.2009
|
||||
===========================================================================
|
||||
|
||||
ITU-T STL BASIC OPERATORS
|
||||
|
||||
MAIN HEADER FILE
|
||||
|
||||
History:
|
||||
07 Nov 04 v2.0 Incorporation of new 32-bit / 40-bit / control
|
||||
operators for the ITU-T Standard Tool Library as
|
||||
described in Geneva, 20-30 January 2004 WP 3/16 Q10/16
|
||||
TD 11 document and subsequent discussions on the
|
||||
wp3audio@yahoogroups.com email reflector.
|
||||
March 06 v2.1 Changed to improve portability.
|
||||
31 Mar 15 v2.1E Clarified usage of operators needed for the EVS codec.
|
||||
|
||||
============================================================================
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _STL_H
|
||||
#define _STL_H
|
||||
|
||||
/* This is Defined right here, it should be put in an include file
|
||||
* that is included from every file. So far, only "stl.h" fit this
|
||||
* requirement as "options.h" and "options.h" are not included by
|
||||
* all code files. Also, these definitions are not enclosed by
|
||||
* #if DEBUG because in some files, "stl.h" is included before
|
||||
* DEBUG had been defined. This would lead to these macros not
|
||||
* being defined and the Stack Counting would be disabled for some
|
||||
* files. The Stack Counting would still work but some functions
|
||||
* would be missing from the tree. */
|
||||
extern int check_stack(const char*, const char*);
|
||||
#define STACK_DEPTH_FCT_CALL (BASOP_push_wmops(__FUNCTION__), check_stack( __FILE__, __FUNCTION__))
|
||||
//#define STACK_DEPTH_FCT_RETURN (BASOP_pop_wmops(), check_stack("-"__FILE__, __FUNCTION__))
|
||||
|
||||
#include <stdlib.h> /* for size_t */
|
||||
extern void* check_alloc_in(const char*, const char *, size_t, size_t);
|
||||
extern void check_alloc_out(void*);
|
||||
extern void check_alloc_exit(void);
|
||||
|
||||
//#define MALLOC_FCT_CALL(n1) check_alloc_in("m"##__FILE__, __FUNCTION__, n1, 0)
|
||||
//#define CALLOC_FCT_CALL(n1, n2) check_alloc_in("c"##__FILE__, __FUNCTION__, n1, n2)
|
||||
//#define FREE_FCT_CALL(ptr) check_alloc_out(ptr)
|
||||
|
||||
/* both ALLOW_40bits and ALLOW_ENH_UL32 shall be enabled for the EVS codec. */
|
||||
#define ALLOW_40bits /* allow 32x16 and 32x32 multiplications */
|
||||
#define ALLOW_ENH_UL32 /* allow enhanced unsigned 32bit operators */
|
||||
|
||||
|
||||
#if (defined _MSC_VER || defined __GNUC__ )
|
||||
#include "typedef.h"
|
||||
#include "basop32.h"
|
||||
#include "count.h"
|
||||
#include "move.h"
|
||||
#include "control.h"
|
||||
#include "enh1632.h"
|
||||
#include "oper_32b.h"
|
||||
#include "math_op.h"
|
||||
#include "log2.h"
|
||||
|
||||
#if defined (ALLOW_40bits)
|
||||
#include "enh40.h"
|
||||
#endif
|
||||
|
||||
#if defined (ALLOW_ENH_UL32)
|
||||
#include "enhUL32.h"
|
||||
#endif
|
||||
|
||||
#endif /* if (defined _MSC_VER || defined __CYGWIN__) */
|
||||
|
||||
#endif /* ifndef _STL_H */
|
||||
|
||||
|
||||
/* end of file */
|
||||
@@ -1,205 +0,0 @@
|
||||
/*
|
||||
===========================================================================
|
||||
File: TYPEDEFS.H v.2.3 - 30.Nov.2009
|
||||
===========================================================================
|
||||
|
||||
ITU-T STL BASIC OPERATORS
|
||||
|
||||
NEW TYPE DEFINITION PROTOTYPES
|
||||
|
||||
History:
|
||||
03 Nov 04 v2.0 Incorporation of new 32-bit / 40-bit / control
|
||||
operators for the ITU-T Standard Tool Library as
|
||||
described in Geneva, 20-30 January 2004 WP 3/16 Q10/16
|
||||
TD 11 document and subsequent discussions on the
|
||||
wp3audio@yahoogroups.com email reflector.
|
||||
|
||||
Editor comment :
|
||||
This file is not yet used or validated since
|
||||
ORIGINAL_TYPEDEF_H compilation flag is defined in
|
||||
typedef.h. This file is incorporated for future
|
||||
reference / usage.
|
||||
|
||||
============================================================================
|
||||
*/
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* File : typedefs.h
|
||||
* Description : Definition of platform independent data
|
||||
* types and constants
|
||||
*
|
||||
*
|
||||
* The following platform independent data types and corresponding
|
||||
* preprocessor (#define) constants are defined:
|
||||
*
|
||||
* defined type meaning corresponding constants
|
||||
* ----------------------------------------------------------
|
||||
* Char character (none)
|
||||
* Bool boolean true, false
|
||||
* Word8 8-bit signed minWord8, maxWord8
|
||||
* UWord8 8-bit unsigned minUWord8, maxUWord8
|
||||
* Word16 16-bit signed minWord16, maxWord16
|
||||
* UWord16 16-bit unsigned minUWord16, maxUWord16
|
||||
* Word32 32-bit signed minWord32, maxWord32
|
||||
* UWord32 32-bit unsigned minUWord32, maxUWord32
|
||||
* Float floating point minFloat, maxFloat
|
||||
*
|
||||
*
|
||||
* The following compile switches are #defined:
|
||||
*
|
||||
* PLATFORM string indicating platform progam is compiled on
|
||||
* possible values: "OSF", "PC", "SUN"
|
||||
*
|
||||
* OSF only defined if the current platform is an Alpha
|
||||
* PC only defined if the current platform is a PC
|
||||
* SUN only defined if the current platform is a Sun
|
||||
*
|
||||
* LSBFIRST is defined if the byte order on this platform is
|
||||
* "least significant byte first" -> defined on DEC Alpha
|
||||
* and PC, undefined on Sun
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
#ifndef _TYPEDEFS_H
|
||||
#define _TYPEDEFS_H "$Id $"
|
||||
|
||||
/*****************************************************************************
|
||||
* INCLUDE FILES
|
||||
*****************************************************************************/
|
||||
#include <float.h>
|
||||
#include <limits.h>
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* DEFINITION OF CONSTANTS
|
||||
*****************************************************************************/
|
||||
/*
|
||||
********* define char type
|
||||
*/
|
||||
typedef char Char;
|
||||
|
||||
typedef unsigned short int UNS_Word16; /* 16 bit "register" (sw*) */
|
||||
#ifdef UNS_Word16
|
||||
#pragma message ("UNS_Word16 is defined but not officially part of STL2009@")
|
||||
#endif
|
||||
/*
|
||||
********* define 8 bit signed/unsigned types & constants
|
||||
*/
|
||||
#if SCHAR_MAX == 127
|
||||
typedef signed char Word8;
|
||||
#define minWord8 SCHAR_MIN
|
||||
#define maxWord8 SCHAR_MAX
|
||||
|
||||
typedef unsigned char UWord8;
|
||||
#define minUWord8 0
|
||||
#define maxUWord8 UCHAR_MAX
|
||||
#else
|
||||
#error cannot find 8-bit type
|
||||
#endif
|
||||
|
||||
/*
|
||||
********* define 16 bit signed/unsigned types & constants
|
||||
*/
|
||||
#if INT_MAX == 32767
|
||||
typedef int Word16;
|
||||
#define minWord16 INT_MIN
|
||||
#define maxWord16 INT_MAX
|
||||
typedef unsigned int UWord16;
|
||||
#define minUWord16 0
|
||||
#define maxUWord16 UINT_MAX
|
||||
#elif SHRT_MAX == 32767
|
||||
typedef short Word16;
|
||||
#define minWord16 SHRT_MIN
|
||||
#define maxWord16 SHRT_MAX
|
||||
typedef unsigned short UWord16;
|
||||
#define minUWord16 0
|
||||
#define maxUWord16 USHRT_MAX
|
||||
#else
|
||||
#error cannot find 16-bit type
|
||||
#endif
|
||||
|
||||
/* Definition of Word40 was missing 10/06/2013 */
|
||||
#define Word40 long long
|
||||
|
||||
/*
|
||||
********* define 32 bit signed/unsigned types & constants
|
||||
*/
|
||||
#if INT_MAX == 2147483647
|
||||
typedef int Word32;
|
||||
#define minWord32 INT_MIN
|
||||
#define maxWord32 INT_MAX
|
||||
typedef unsigned int UWord32;
|
||||
#define minUWord32 0
|
||||
#define maxUWord32 UINT_MAX
|
||||
#elif LONG_MAX == 2147483647
|
||||
typedef long Word32;
|
||||
#define minWord32 LONG_MIN
|
||||
#define maxWord32 LONG_MAX
|
||||
typedef unsigned long UWord32;
|
||||
#define minUWord32 0
|
||||
#define maxUWord32 ULONG_MAX
|
||||
#else
|
||||
#error cannot find 32-bit type
|
||||
#endif
|
||||
|
||||
/*
|
||||
********* define floating point type & constants
|
||||
*/
|
||||
/* use "if 0" below if Float should be double;
|
||||
use "if 1" below if Float should be float
|
||||
*/
|
||||
typedef double Float;
|
||||
#define maxFloat DBL_MAX
|
||||
#define minFloat DBL_MIN
|
||||
|
||||
/*
|
||||
********* define complex type
|
||||
*/
|
||||
typedef struct {
|
||||
Float r; /* real part */
|
||||
Float i; /* imaginary part */
|
||||
} CPX;
|
||||
|
||||
/*
|
||||
********* define boolean type
|
||||
*/
|
||||
typedef int Bool;
|
||||
#define false 0
|
||||
#define true 1
|
||||
|
||||
/*
|
||||
********* Check current platform
|
||||
*/
|
||||
#if defined(__MSDOS__)
|
||||
#define PC
|
||||
#define PLATFORM "PC"
|
||||
#define LSBFIRST
|
||||
#elif defined(__osf__)
|
||||
#define OSF
|
||||
#define PLATFORM "OSF"
|
||||
#define LSBFIRST
|
||||
#elif defined(__sun__) || defined(__sun)
|
||||
#define SUN
|
||||
#define PLATFORM "SUN"
|
||||
#undef LSBFIRST
|
||||
#elif defined(linux) && defined(i386)
|
||||
#define PC
|
||||
#define PLATFORM "PC"
|
||||
#define LSBFIRST
|
||||
#else
|
||||
/*#error "can't determine architecture; adapt typedefs.h to your platform"*/
|
||||
/* for MSVC 2008 10/06/2013 */
|
||||
#define PC
|
||||
#define PLATFORM "PC"
|
||||
#define LSBFIRST
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* ifndef _TYPEDEFS_H */
|
||||
|
||||
|
||||
/* end of file */
|
||||
104
src/libs/libevs/lib_com/ACcontextMapping.cpp
Executable file → Normal file
104
src/libs/libevs/lib_com/ACcontextMapping.cpp
Executable file → Normal file
@@ -1,81 +1,73 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
EVS Codec 3GPP TS26.443 Nov 13, 2018. Version 12.11.0 / 13.7.0 / 14.3.0 / 15.1.0
|
||||
====================================================================================*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include "options.h"
|
||||
#include "basop_util.h"
|
||||
#include "cnst_fx.h"
|
||||
#include "prot_fx.h"
|
||||
#include "rom_com_fx.h"
|
||||
#include "stl.h"
|
||||
#include "cnst.h"
|
||||
#include "prot.h"
|
||||
|
||||
/* Returns: index of next coefficient */
|
||||
Word16 get_next_coeff_mapped(
|
||||
Word16 ii[2], /* i/o: coefficient indexes */
|
||||
Word16 *pp, /* o : peak(1)/hole(0) indicator */
|
||||
Word16 *idx, /* o : index in unmapped domain */
|
||||
|
||||
/*-------------------------------------------------------------------*
|
||||
* get_next_coeff_mapped()
|
||||
*
|
||||
*
|
||||
*-------------------------------------------------------------------*/
|
||||
|
||||
int get_next_coeff_mapped( /* o : index of next coefficient */
|
||||
int ii[2], /* i/o: coefficient indexes */
|
||||
int *pp, /* o : peak(1)/hole(0) indicator */
|
||||
int *idx, /* o : index in unmapped domain */
|
||||
CONTEXT_HM_CONFIG *hm_cfg /* i : HM configuration */
|
||||
)
|
||||
{
|
||||
Word16 p;
|
||||
unsigned int p;
|
||||
|
||||
p = s_and(sub(ii[1], hm_cfg->numPeakIndices), sub(hm_cfg->indexBuffer[ii[1]], hm_cfg->indexBuffer[ii[0]]));
|
||||
if (p > 0)
|
||||
{
|
||||
p = 0;
|
||||
move16();
|
||||
}
|
||||
if (p < 0)
|
||||
{
|
||||
p = 1;
|
||||
move16();
|
||||
}
|
||||
p = (ii[1] - hm_cfg->numPeakIndices) & (hm_cfg->indexBuffer[ii[1]] - hm_cfg->indexBuffer[ii[0]]);
|
||||
p >>= sizeof(p)*8-1;
|
||||
*pp = p;
|
||||
move16();
|
||||
*idx = ii[p];
|
||||
move16();
|
||||
ii[p] = add(ii[p], 1);
|
||||
move16();
|
||||
ii[p]++;
|
||||
|
||||
return hm_cfg->indexBuffer[*idx];
|
||||
}
|
||||
|
||||
/* Returns: index of next coefficient */
|
||||
Word16 get_next_coeff_unmapped(
|
||||
Word16 ii[2], /* i/o: coefficient indexes */
|
||||
Word16 *pp, /* o : peak(1)/hole(0) indicator */
|
||||
Word16 *idx, /* o : index in unmapped domain */
|
||||
CONTEXT_HM_CONFIG *hm_cfg /* i : HM configuration */
|
||||
|
||||
/*-------------------------------------------------------------------*
|
||||
* get_next_coeff_unmapped()
|
||||
*
|
||||
*
|
||||
*-------------------------------------------------------------------*/
|
||||
|
||||
int get_next_coeff_unmapped(/* o : index of next coefficient */
|
||||
int *ii, /* i/o: coefficient indexes */
|
||||
int *idx /* o : index in unmapped domain */
|
||||
)
|
||||
{
|
||||
(void)pp;
|
||||
(void)hm_cfg;
|
||||
*idx = *ii;
|
||||
(*ii)++;
|
||||
|
||||
*idx = ii[0];
|
||||
move16();
|
||||
ii[0] = add(ii[0], 1);
|
||||
move16();
|
||||
return *idx;
|
||||
}
|
||||
|
||||
Word16 update_mixed_context(Word16 ctx, Word16 a)
|
||||
/*-------------------------------------------------------------------*
|
||||
* update_mixed_context()
|
||||
*
|
||||
*
|
||||
*-------------------------------------------------------------------*/
|
||||
|
||||
int update_mixed_context(
|
||||
int ctx,
|
||||
int a
|
||||
)
|
||||
{
|
||||
Word32 t32;
|
||||
Word16 t=0; /* initialize just to avoid compiler warning */
|
||||
int t;
|
||||
|
||||
t32 = L_mac0(1-13, s_and(a, ~1), add(shr(a, 2), 1));
|
||||
if (t32 <= 0)
|
||||
t = 1-13 + (a & ~1)*((a>>2)+1);
|
||||
|
||||
if (t > 0)
|
||||
{
|
||||
t = extract_l(t32);
|
||||
t = min((a>>3), 2);
|
||||
}
|
||||
a = shr(a, 3);
|
||||
if (t32 > 0)
|
||||
{
|
||||
t = s_min(a, 2);
|
||||
}
|
||||
return add(shl(s_and(ctx, 0xf), 4), add(t, 13));
|
||||
|
||||
return (ctx & 0xf) * 16 + t + 13;
|
||||
}
|
||||
|
||||
|
||||
50
src/libs/libevs/lib_com/ari.cpp
Executable file → Normal file
50
src/libs/libevs/lib_com/ari.cpp
Executable file → Normal file
@@ -1,57 +1,39 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
EVS Codec 3GPP TS26.443 Nov 13, 2018. Version 12.11.0 / 13.7.0 / 14.3.0 / 15.1.0
|
||||
====================================================================================*/
|
||||
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include "cnst.h"
|
||||
#include "prot.h"
|
||||
#include "stat_com.h"
|
||||
#include "assert.h"
|
||||
#include "prot_fx.h"
|
||||
#include "basop_mpy.h"
|
||||
#include "cnst_fx.h"
|
||||
#include "stl.h"
|
||||
#include "basop_util.h"
|
||||
|
||||
/**
|
||||
* \brief 31x16 Bit multiply (x*y)
|
||||
*
|
||||
* \param[i] xh high part, bit [30..15]
|
||||
* \param[i] xl low part, 15 LSBits
|
||||
* \param[i] y
|
||||
*
|
||||
* \return x*y
|
||||
*/
|
||||
Word32 L_multi31x16_X2(Word16 xh, Word16 xl, Word16 y)
|
||||
{
|
||||
Word32 z;
|
||||
#ifndef int32
|
||||
#define int32 int
|
||||
#endif
|
||||
|
||||
z = L_shl(L_mult0(xh,y),15);
|
||||
z = L_mac0(z,xl,y);
|
||||
|
||||
return z;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
Ari 14 bits common routines
|
||||
-------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* \brief Integer Multiply
|
||||
* \brief Integer Multiply
|
||||
*
|
||||
* \param[i] r
|
||||
* \param[i] c
|
||||
*
|
||||
* \return r*c
|
||||
*/
|
||||
Word32 mul_sbc_14bits(Word32 r, Word16 c)
|
||||
long mul_sbc_14bits(long r,long c)
|
||||
{
|
||||
Word32 ret;
|
||||
long temp;
|
||||
/*function in line*/
|
||||
temp = (((int32) r)*((int32) c))>>stat_bitsnew;
|
||||
return temp;
|
||||
|
||||
|
||||
/*
|
||||
temp = (((int32) r)*((int32) c))>>stat_bitsnew;
|
||||
*/
|
||||
assert(stat_bitsnew == 14);
|
||||
ret = Mpy_32_16_1(L_shl(r,15-stat_bitsnew), c);
|
||||
|
||||
/*assert( (((int) r)*((int) c))>>stat_bitsnew == ret);*/
|
||||
|
||||
return (ret);
|
||||
/*function in line*/
|
||||
}
|
||||
|
||||
312
src/libs/libevs/lib_com/ari_hm.cpp
Executable file → Normal file
312
src/libs/libevs/lib_com/ari_hm.cpp
Executable file → Normal file
@@ -1,211 +1,196 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
EVS Codec 3GPP TS26.443 Nov 13, 2018. Version 12.11.0 / 13.7.0 / 14.3.0 / 15.1.0
|
||||
====================================================================================*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
#include "cnst.h"
|
||||
#include "stl.h"
|
||||
#include "cnst_fx.h"
|
||||
#include "basop_util.h"
|
||||
#include "rom_com_fx.h"
|
||||
#include "prot_fx.h"
|
||||
#include "prot.h"
|
||||
#include "rom_com.h"
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------*
|
||||
* UnmapIndex()
|
||||
*
|
||||
*
|
||||
*-------------------------------------------------------------------*/
|
||||
|
||||
void UnmapIndex(
|
||||
Word16 PeriodicityIndex,
|
||||
Word16 Bandwidth,
|
||||
Word16 LtpPitchLag,
|
||||
Word8 SmallerLags,
|
||||
Word16 *FractionalResolution,
|
||||
Word32 *Lag)
|
||||
int PeriodicityIndex,
|
||||
int Bandwidth,
|
||||
short LtpPitchLag,
|
||||
int SmallerLags,
|
||||
int *FractionalResolution,
|
||||
int *Lag)
|
||||
{
|
||||
Word16 LtpPitchIndex, Multiplier;
|
||||
Word16 Lag16;
|
||||
|
||||
test();
|
||||
IF ((LtpPitchLag > 0) && (s_and(PeriodicityIndex, kLtpHmFlag) != 0))
|
||||
if ((LtpPitchLag > 0) && (PeriodicityIndex & kLtpHmFlag))
|
||||
{
|
||||
LtpPitchIndex = shr(PeriodicityIndex, 9);
|
||||
Multiplier = s_and(PeriodicityIndex, 0xff);
|
||||
|
||||
int LtpPitchIndex, Multiplier;
|
||||
LtpPitchIndex = PeriodicityIndex >> 9;
|
||||
Multiplier = PeriodicityIndex & 0xff;
|
||||
assert(0 <= LtpPitchIndex && LtpPitchIndex <= 16);
|
||||
assert(1 <= Multiplier && Multiplier <= (1 << NumRatioBits[Bandwidth][LtpPitchIndex]));
|
||||
|
||||
*FractionalResolution = kLtpHmFractionalResolution;
|
||||
move16();
|
||||
*Lag = L_shr(L_mult0(LtpPitchLag, Ratios[Bandwidth][LtpPitchIndex][Multiplier-1]), 8);
|
||||
move32();
|
||||
*Lag = (LtpPitchLag * (int)(4 * Ratios[Bandwidth][LtpPitchIndex][Multiplier-1])) >> 2;
|
||||
}
|
||||
ELSE
|
||||
else
|
||||
{
|
||||
IF (sub(PeriodicityIndex, 16) < 0)
|
||||
if (PeriodicityIndex < 16)
|
||||
{
|
||||
*FractionalResolution = 3;
|
||||
move16();
|
||||
Lag16 = add(PeriodicityIndex, GET_ADJ2(0, 6, 3));
|
||||
*Lag = PeriodicityIndex + GET_ADJ(0, 6);
|
||||
}
|
||||
ELSE IF (sub(PeriodicityIndex, 80) < 0)
|
||||
else if (PeriodicityIndex < 80)
|
||||
{
|
||||
*FractionalResolution = 4;
|
||||
move16();
|
||||
Lag16 = add(PeriodicityIndex, GET_ADJ2(16, 8, 4));
|
||||
*Lag = PeriodicityIndex + GET_ADJ(16, 8);
|
||||
}
|
||||
ELSE IF (sub(PeriodicityIndex, 208) < 0)
|
||||
else if (PeriodicityIndex < 208)
|
||||
{
|
||||
*FractionalResolution = 3;
|
||||
move16();
|
||||
Lag16 = add(PeriodicityIndex, GET_ADJ2(80, 12, 3));
|
||||
*Lag = PeriodicityIndex + GET_ADJ(80, 12);
|
||||
}
|
||||
ELSE {
|
||||
test();
|
||||
IF (sub(PeriodicityIndex, 224) < 0 || SmallerLags != 0)
|
||||
{
|
||||
*FractionalResolution = 1;
|
||||
move16();
|
||||
Lag16 = add(PeriodicityIndex, GET_ADJ2(208, 28, 1));
|
||||
}
|
||||
ELSE {
|
||||
*FractionalResolution = 0;
|
||||
move16();
|
||||
Lag16 = add(PeriodicityIndex, GET_ADJ2(224, 188, 0));
|
||||
}
|
||||
else if (PeriodicityIndex < 224 || SmallerLags)
|
||||
{
|
||||
*FractionalResolution = 1;
|
||||
*Lag = PeriodicityIndex + GET_ADJ(208, 28);
|
||||
}
|
||||
else
|
||||
{
|
||||
*FractionalResolution = 0;
|
||||
*Lag = PeriodicityIndex + GET_ADJ(224, 188);
|
||||
}
|
||||
*Lag = L_deposit_l(Lag16);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------*
|
||||
* ConfigureContextHm()
|
||||
*
|
||||
*
|
||||
*-------------------------------------------------------------------*/
|
||||
|
||||
void ConfigureContextHm(
|
||||
Word16 NumCoeffs, /* (I) Number of coefficients */
|
||||
Word16 TargetBits, /* (I) Target bit budget (excl. Done flag) */
|
||||
Word16 PeriodicityIndex, /* (I) Pitch related index */
|
||||
Word16 LtpPitchLag, /* (I) TCX-LTP pitch in F.D. */
|
||||
int NumCoeffs, /* (I) Number of coefficients */
|
||||
int TargetBits, /* (I) Target bit budget (excl. Done flag) */
|
||||
int PeriodicityIndex, /* (I) Pitch related index */
|
||||
short LtpPitchLag, /* (I) TCX-LTP pitch in F.D. */
|
||||
CONTEXT_HM_CONFIG *hm_cfg /* (O) Context-based harmonic model configuration */
|
||||
)
|
||||
{
|
||||
Word8 Bandwidth, SmallerLags;
|
||||
Word32 i, Limit, Lag;
|
||||
Word16 j, Index, FractionalResolution;
|
||||
Word16 *tmp;
|
||||
|
||||
int Bandwidth, SmallerLags;
|
||||
int i, Limit, Lag;
|
||||
int j, Index, FractionalResolution;
|
||||
int *tmp;
|
||||
|
||||
Bandwidth = 0;
|
||||
move16();
|
||||
if (sub(NumCoeffs, 256) >= 0)
|
||||
if (NumCoeffs >= 256)
|
||||
{
|
||||
Bandwidth = 1;
|
||||
move16();
|
||||
}
|
||||
|
||||
SmallerLags = 0;
|
||||
move16();
|
||||
test();
|
||||
if ((sub(TargetBits, kSmallerLagsTargetBitsThreshold) <= 0) || (Bandwidth == 0))
|
||||
|
||||
if (TargetBits <= kSmallerLagsTargetBitsThreshold || Bandwidth == 0)
|
||||
{
|
||||
SmallerLags = 1;
|
||||
move16();
|
||||
}
|
||||
|
||||
UnmapIndex(PeriodicityIndex,
|
||||
Bandwidth,
|
||||
LtpPitchLag,
|
||||
SmallerLags,
|
||||
&FractionalResolution, &Lag);
|
||||
UnmapIndex(PeriodicityIndex, Bandwidth, LtpPitchLag, SmallerLags, &FractionalResolution, &Lag );
|
||||
|
||||
/* Set up and fill peakIndices */
|
||||
hm_cfg->peakIndices = hm_cfg->indexBuffer;
|
||||
tmp = hm_cfg->peakIndices;
|
||||
Limit = L_shl(L_deposit_l(sub(NumCoeffs, 1)), FractionalResolution);
|
||||
IF (L_sub(Lag, Limit) < 0)
|
||||
Limit = (NumCoeffs - 1) << FractionalResolution;
|
||||
|
||||
for (i=Lag; i<Limit; i+=Lag)
|
||||
{
|
||||
FOR (i=Lag; i<Limit; i+=Lag)
|
||||
{
|
||||
Index = extract_l(L_shr(i, FractionalResolution));
|
||||
*tmp++ = sub(Index, 1);
|
||||
move16();
|
||||
*tmp++ = Index;
|
||||
move16();
|
||||
*tmp++ = add(Index, 1);
|
||||
move16();
|
||||
}
|
||||
Index = i >> FractionalResolution;
|
||||
*tmp++ = Index - 1;
|
||||
*tmp++ = Index;
|
||||
*tmp++ = Index + 1;
|
||||
}
|
||||
hm_cfg->numPeakIndices = (Word16)(tmp - hm_cfg->indexBuffer);
|
||||
hm_cfg->numPeakIndices = tmp - hm_cfg->indexBuffer;
|
||||
|
||||
/* Set up and fill holeIndices */
|
||||
hm_cfg->holeIndices = hm_cfg->indexBuffer + hm_cfg->numPeakIndices;
|
||||
tmp = hm_cfg->holeIndices;
|
||||
Index = 0;
|
||||
move16();
|
||||
IF (hm_cfg->numPeakIndices > 0)
|
||||
|
||||
for (j=0; j<hm_cfg->numPeakIndices; j+=3)
|
||||
{
|
||||
FOR (j=0; j<hm_cfg->numPeakIndices; j+=3)
|
||||
{
|
||||
FOR (; Index<hm_cfg->peakIndices[j]; ++Index)
|
||||
{
|
||||
*tmp++ = Index;
|
||||
move16();
|
||||
}
|
||||
Index = add(Index, 3); /* Skip the peak */
|
||||
}
|
||||
}
|
||||
IF (sub(Index, NumCoeffs) < 0)
|
||||
{
|
||||
FOR (; Index<NumCoeffs; ++Index)
|
||||
for (; Index<hm_cfg->peakIndices[j]; ++Index)
|
||||
{
|
||||
*tmp++ = Index;
|
||||
move16();
|
||||
}
|
||||
Index += 3; /* Skip the peak */
|
||||
}
|
||||
hm_cfg->numHoleIndices = (Word16)(tmp - hm_cfg->holeIndices);
|
||||
*tmp++ = NumCoeffs;
|
||||
move16(); /* Add extremal element signaling the end of the buffer */
|
||||
|
||||
}
|
||||
|
||||
Word16 CountIndexBits(
|
||||
Word16 Bandwidth,
|
||||
Word16 PeriodicityIndex)
|
||||
{
|
||||
Word16 result;
|
||||
Word16 PeriodicityIndexS;
|
||||
|
||||
result = 8;
|
||||
move16();
|
||||
PeriodicityIndexS = shr(PeriodicityIndex, 9);
|
||||
|
||||
if (s_and(PeriodicityIndex, kLtpHmFlag) != 0)
|
||||
for (; Index<NumCoeffs; ++Index)
|
||||
{
|
||||
result = NumRatioBits[Bandwidth][PeriodicityIndexS];
|
||||
move16();
|
||||
*tmp++ = Index;
|
||||
}
|
||||
hm_cfg->numHoleIndices = tmp - hm_cfg->holeIndices;
|
||||
/* Add extremal element signaling the end of the buffer */
|
||||
*tmp++ = NumCoeffs;
|
||||
|
||||
return result;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------*
|
||||
* CountIndexBits()
|
||||
*
|
||||
*
|
||||
*-------------------------------------------------------------------*/
|
||||
|
||||
int CountIndexBits(
|
||||
int Bandwidth,
|
||||
int PeriodicityIndex)
|
||||
{
|
||||
|
||||
if (PeriodicityIndex & kLtpHmFlag)
|
||||
{
|
||||
int LtpPitchIndex = PeriodicityIndex >> 9;
|
||||
return NumRatioBits[Bandwidth][LtpPitchIndex];
|
||||
}
|
||||
return 8;
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------*
|
||||
* tcx_hm_render()
|
||||
*
|
||||
*
|
||||
*-------------------------------------------------------------------*/
|
||||
|
||||
int tcx_hm_render(
|
||||
Word32 lag, /* i: pitch lag Q0 */
|
||||
Word16 fract_res, /* i: fractional resolution of the lag Q0 */
|
||||
Word16 p[] /* o: harmonic model Q13 */
|
||||
int lag, /* i: pitch lag */
|
||||
int fract_res, /* i: fractional resolution of the lag */
|
||||
float LtpGain, /* i: LTP gain */
|
||||
Word16 p[] /* o: harmonic model (Q13) */
|
||||
)
|
||||
{
|
||||
Word16 k, tmp, height;
|
||||
Word16 PeakDeviation;
|
||||
int k;
|
||||
Word32 f0, tmp32;
|
||||
Word16 height, PeakDeviation, tmp;
|
||||
|
||||
/* Set up overall shape */
|
||||
f0 = L_shl(lag, sub(15, fract_res)); /* Q31 */
|
||||
(void)LtpGain;
|
||||
|
||||
tmp32 = Mpy_32_16_1(f0, -26474);
|
||||
f0 = L_shl(lag, sub(15, fract_res)); /* Q15 */
|
||||
|
||||
tmp32 = Mpy_32_16(f0, -26474);
|
||||
tmp32 = L_shr_r(BASOP_Util_InvLog2(L_shl(tmp32, 7)), 2);
|
||||
tmp32 = L_sub(603979776L, tmp32);
|
||||
tmp32 = L_add(L_add(tmp32, tmp32), Mpy_32_16_1(tmp32, 26214));
|
||||
tmp32 = L_add(L_add(tmp32, tmp32), Mpy_32_16(tmp32, 26214));
|
||||
height = round_fx(tmp32); /* Q13 */
|
||||
|
||||
tmp32 = Mpy_32_16_1(f0, -18910);
|
||||
tmp32 = Mpy_32_16(f0, -18910);
|
||||
tmp32 = L_shr_r(BASOP_Util_InvLog2(L_shl(tmp32, 7)), 2);
|
||||
tmp32 = L_sub(1395864371L, tmp32);
|
||||
PeakDeviation = round_fx(tmp32); /* Q14 */
|
||||
@@ -221,72 +206,65 @@ int tcx_hm_render(
|
||||
tmp = mult_r(tmp, tmp); /* Q15 */
|
||||
}
|
||||
|
||||
tmp = div_s(13915, PeakDeviation);
|
||||
tmp = mult_r(tmp, tmp); /* Q15 */
|
||||
|
||||
/* Render the prototype peak */
|
||||
p[kTcxHmParabolaHalfWidth] = height;
|
||||
move16();
|
||||
|
||||
FOR (k=1; k<=kTcxHmParabolaHalfWidth; ++k)
|
||||
for (k=1; k<=kTcxHmParabolaHalfWidth; ++k)
|
||||
{
|
||||
p[kTcxHmParabolaHalfWidth+k] = round_fx(Mpy_32_16_1(BASOP_Util_InvLog2(L_shl(L_mult0(i_mult2(negate(k),k), tmp),10)), height));
|
||||
p[kTcxHmParabolaHalfWidth+k] = round_fx(Mpy_32_16(BASOP_Util_InvLog2(L_shl(L_mult0(mult0(negate(k),k), tmp),10)), height));
|
||||
}
|
||||
/* Mirror */
|
||||
FOR (k=-kTcxHmParabolaHalfWidth; k<0; ++k)
|
||||
for (k=-kTcxHmParabolaHalfWidth; k<0; ++k)
|
||||
{
|
||||
p[kTcxHmParabolaHalfWidth+k] = p[kTcxHmParabolaHalfWidth-k];
|
||||
move16();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------*
|
||||
* tcx_hm_modify_envelope()
|
||||
*
|
||||
*
|
||||
*-------------------------------------------------------------------*/
|
||||
|
||||
void tcx_hm_modify_envelope(
|
||||
Word16 gain, /* i: HM gain Q11 */
|
||||
Word32 lag, /* i: pitch lag Q0 */
|
||||
Word16 fract_res, /* i: fractional resolution of the lag Q0 */
|
||||
Word16 p[], /* i: harmonic model Q13 */
|
||||
Word32 env[], /* i/o: envelope Q16 */
|
||||
Word16 L_frame /* i: number of spectral lines Q0 */
|
||||
Word16 gain, /* i: HM gain (Q11) */
|
||||
int lag,
|
||||
int fract_res,
|
||||
Word16 p[], /* i: harmonic model (Q13) */
|
||||
Word32 env[], /* i/o: envelope (Q16) */
|
||||
int L_frame /* i: number of spectral lines */
|
||||
)
|
||||
{
|
||||
Word16 k, h, x, l1,l2, L_frame_m1, L_frame_for_loop;
|
||||
Word16 inv_shape[2*kTcxHmParabolaHalfWidth+1];
|
||||
int k;
|
||||
int h, x;
|
||||
Word16 inv_shape[2*kTcxHmParabolaHalfWidth+1]; /* Q15 */
|
||||
|
||||
IF ( gain == 0 )
|
||||
if (gain == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
FOR (k=0; k<2*kTcxHmParabolaHalfWidth+1; ++k)
|
||||
for (k=0; k<2*kTcxHmParabolaHalfWidth+1; ++k)
|
||||
{
|
||||
/* Q24 = Q11 * Q13; 512 = 1.0 in Q24 format */
|
||||
inv_shape[k] = div_s(512, add(512, mult_r(gain, p[k])));
|
||||
move16();
|
||||
inv_shape[k] = div_s(512, add(512, round_fx(L_mult(gain, p[k]))));
|
||||
}
|
||||
|
||||
h = 1;
|
||||
move16();
|
||||
k = extract_l(L_shr(lag,fract_res));
|
||||
k = lag >> fract_res;
|
||||
|
||||
L_frame_m1 = sub(L_frame,1);
|
||||
L_frame_for_loop = add(L_frame,kTcxHmParabolaHalfWidth - 1);
|
||||
|
||||
WHILE ( sub(k,L_frame_for_loop) <= 0 )
|
||||
while (k <= L_frame + kTcxHmParabolaHalfWidth - 1)
|
||||
{
|
||||
l1 = s_max(0, sub(k,kTcxHmParabolaHalfWidth));
|
||||
l2 = s_min(add(k,kTcxHmParabolaHalfWidth), L_frame_m1);
|
||||
FOR (x=l1; x<=l2; ++x)
|
||||
{
|
||||
env[x] = Mpy_32_16_1(env[x], inv_shape[x-k+kTcxHmParabolaHalfWidth]);
|
||||
move32();
|
||||
}
|
||||
|
||||
h = add(h,1);
|
||||
k = extract_l(L_shr(imult3216(lag,h),fract_res));
|
||||
for (x=max(0, k-kTcxHmParabolaHalfWidth); x<=min(k+kTcxHmParabolaHalfWidth, L_frame-1); ++x)
|
||||
{
|
||||
env[x] = Mpy_32_16(env[x], inv_shape[x-k+kTcxHmParabolaHalfWidth]);
|
||||
}
|
||||
++h;
|
||||
k = (h * lag) >> fract_res;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
183
src/libs/libevs/lib_com/arith_coder.cpp
Executable file → Normal file
183
src/libs/libevs/lib_com/arith_coder.cpp
Executable file → Normal file
@@ -1,31 +1,35 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
EVS Codec 3GPP TS26.443 Nov 13, 2018. Version 12.11.0 / 13.7.0 / 14.3.0 / 15.1.0
|
||||
====================================================================================*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "prot_fx.h"
|
||||
#include "basop_util.h"
|
||||
#include "options.h"
|
||||
#include "cnst_fx.h"
|
||||
#include "stl.h"
|
||||
#include "cnst.h"
|
||||
#include "prot.h"
|
||||
#include "basop_util.h"
|
||||
#include "basop_proto_func.h"
|
||||
|
||||
/* Fixed point implementation of exp(negate()) */
|
||||
Word32 expfp( /* o: Q31 */
|
||||
Word16 x, /* i: mantissa Q-e */
|
||||
Word16 x_e) /* i: exponent Q0 */
|
||||
|
||||
|
||||
|
||||
/*-------------------------------------------------------*
|
||||
* expfp()
|
||||
*
|
||||
* Fixed point implementation of exp()
|
||||
*-------------------------------------------------------*/
|
||||
|
||||
Word16 expfp( /* o: Q15 */
|
||||
Word16 x, /* i: mantissa Q15-e */
|
||||
Word16 x_e) /* i: exponent Q0 */
|
||||
{
|
||||
Word16 xi, xf, tmp;
|
||||
Word16 b0, b1, b2, b3;
|
||||
Word32 y, L_tmp;
|
||||
|
||||
assert(x <= 0);
|
||||
|
||||
assert(x > 0);
|
||||
|
||||
L_tmp = L_shl(L_deposit_h(x), x_e);
|
||||
L_tmp = L_negate(L_shl(L_deposit_h(x), sub(x_e, 15)));
|
||||
|
||||
/* split into integer and fractional parts */
|
||||
xi = round_fx(L_tmp);
|
||||
@@ -55,10 +59,10 @@ Word32 expfp( /* o: Q31 */
|
||||
b2 = s_and(xi, 4);
|
||||
b3 = s_and(xi, 8);
|
||||
|
||||
if (b0 != 0) y = Mpy_32_16_1(y, 24109); /* exp(-1) in -1Q16 */
|
||||
if (b1 != 0) y = Mpy_32_16_1(y, 17739); /* exp(-2) in -2Q17 */
|
||||
if (b2 != 0) y = Mpy_32_16_1(y, 19205); /* exp(-4) in -5Q20 */
|
||||
if (b3 != 0) y = Mpy_32_16_1(y, 22513); /* exp(-8) in -11Q26 */
|
||||
if (b0 != 0) y = Mpy_32_16(y, 24109); /* exp(-1) in -1Q16 */
|
||||
if (b1 != 0) y = Mpy_32_16(y, 17739); /* exp(-2) in -2Q17 */
|
||||
if (b2 != 0) y = Mpy_32_16(y, 19205); /* exp(-4) in -5Q20 */
|
||||
if (b3 != 0) y = Mpy_32_16(y, 22513); /* exp(-8) in -11Q26 */
|
||||
|
||||
/* scaling: -1*b0 - 2*b1 -5*b2 -11*b3 */
|
||||
y = L_shr(y, add(add(xi, shr(xi, 2)), shr(b3, 3)));
|
||||
@@ -67,22 +71,31 @@ Word32 expfp( /* o: Q31 */
|
||||
if (shr(xi, 4) > 0)
|
||||
{
|
||||
y = L_deposit_l(0);
|
||||
move16();
|
||||
}
|
||||
|
||||
|
||||
return L_shl(y, 15);
|
||||
return round_fx(L_shl(y, 15));
|
||||
}
|
||||
|
||||
/* Fixed point implementation of pow(), where base is fixed point (16/16) and exponent a small *odd* integer
|
||||
|
||||
/*-------------------------------------------------------*
|
||||
* powfp_odd2()
|
||||
*
|
||||
* Fixed point implementation of pow(), where base is fixed point (16/16) and exponent a small *odd* integer
|
||||
*-------------------------------------------------------*/
|
||||
/*
|
||||
*
|
||||
* Returns: *pout1 = ( (base/65536)^(2*exp - 1) ) * 65536
|
||||
* *pout2 = ( (base/65536)^(2*exp + 1) ) * 65536
|
||||
*
|
||||
* NOTE: This function must be in sync with ari_decode_14bits_pow() */
|
||||
void powfp_odd2(Word16 base, /* Q15 */
|
||||
Word16 exp, /* Q0 */
|
||||
Word16 *pout1, /* Q15 */
|
||||
Word16 *pout2) /* Q15 */
|
||||
|
||||
void powfp_odd2(
|
||||
Word16 base, /* Q15 */
|
||||
Word16 exp, /* Q0 */
|
||||
Word16 *pout1, /* Q15 */
|
||||
Word16 *pout2 /* Q15 */
|
||||
)
|
||||
{
|
||||
/* this version is in sync with ari_enc_14bits_pow()
|
||||
* that is, we have to start multiplication from the largest power-of-two, in order to
|
||||
@@ -144,8 +157,10 @@ void powfp_odd2(Word16 base, /* Q15 */
|
||||
*pout2 = out;
|
||||
move16();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------
|
||||
* Function: tcx_arith_scale_envelope
|
||||
*
|
||||
@@ -167,12 +182,13 @@ void powfp_odd2(Word16 base, /* Q15 */
|
||||
* NOTE: This function must be bit-exact on all platforms such that encoder
|
||||
* and decoder remain synchronized.
|
||||
*-------------------------------------------------------------------------*/
|
||||
|
||||
void tcx_arith_scale_envelope(
|
||||
Word16 L_spec_core, /* i: number of lines to scale Q0 */
|
||||
Word16 L_frame, /* i: number of lines Q0 */
|
||||
Word32 env[], /* i: unscaled envelope Q16 */
|
||||
Word16 target_bits, /* i: number of available bits Q0 */
|
||||
Word16 low_complexity, /* i: low-complexity flag Q0 */
|
||||
Word16 low_complexity, /* i: low-complexity Q0 */
|
||||
Word16 s_env[], /* o: scaled envelope Q15-e */
|
||||
Word16 *s_env_e /* o: scaled envelope exponent Q0 */
|
||||
)
|
||||
@@ -186,7 +202,6 @@ void tcx_arith_scale_envelope(
|
||||
Word16 mean_e, tmp, tmp2;
|
||||
|
||||
|
||||
|
||||
lob_bits = 0;
|
||||
move16();
|
||||
hib_bits = 0;
|
||||
@@ -194,10 +209,10 @@ void tcx_arith_scale_envelope(
|
||||
|
||||
/* Boosting to account for expected spectrum truncation (kMax) */
|
||||
/* target_bits = (int)(target_bits * (1.2f - 0.00045f * target_bits + 0.00000025f * target_bits * target_bits)); */
|
||||
L_tmp = L_shr(Mpy_32_16_1(L_mult0(target_bits, target_bits), 17180), 6); /* Q15; 17180 -> 0.00000025f (Q36) */
|
||||
L_tmp = L_shr(Mpy_32_16(L_mult0(target_bits, target_bits), 17180), 6); /* Q15; 17180 -> 0.00000025f (Q36) */
|
||||
L_tmp = L_sub(L_tmp, L_shr(L_mult0(target_bits, 30199), 11)); /* Q15; 30199 -> 0.00045f (Q26) */
|
||||
L_tmp = L_add(L_tmp, 39322); /* Q15; 39322 -> 1.2f (Q15) */
|
||||
L_tmp = Mpy_32_16_1(L_tmp, target_bits); /* Q0 */
|
||||
L_tmp = Mpy_32_16(L_tmp, target_bits); /* Q0 */
|
||||
assert(L_tmp < 32768);
|
||||
target_bits = extract_l(L_tmp);
|
||||
|
||||
@@ -216,12 +231,12 @@ void tcx_arith_scale_envelope(
|
||||
}
|
||||
tmp = norm_s(L_frame);
|
||||
tmp = shl(div_s(8192, shl(L_frame, tmp)), sub(tmp, 7));
|
||||
mean = L_shr(Mpy_32_16_1(mean, tmp), 6); /* Q16 */
|
||||
mean = L_shr(Mpy_32_16(mean, tmp), 6); /* Q16 */
|
||||
|
||||
/* Rate dependent compensation to get closer to the target on average */
|
||||
/* mean = (float)pow(mean, (float)L_frame / (float)target_bits * 0.357f); */
|
||||
tmp = BASOP_Util_Divide1616_Scale(L_frame, target_bits, &tmp2);
|
||||
tmp = mult_r(tmp, 11698/*0.357f Q15*/);
|
||||
tmp = mult_r(tmp, FL2WORD16(0.357f));
|
||||
mean = BASOP_Util_fPow(mean, 15, L_deposit_h(tmp), tmp2, &mean_e);
|
||||
|
||||
/* Find first-guess scaling coefficient "scale" such that if "mean" is the
|
||||
@@ -231,23 +246,28 @@ void tcx_arith_scale_envelope(
|
||||
*/
|
||||
/* a = 2*2.71828183f*mean*mean; */
|
||||
tmp = round_fx(mean);
|
||||
a = L_mult(mult_r(tmp, 22268/*2.71828183f Q13*/), tmp);
|
||||
a = L_mult(mult_r(tmp, FL2WORD16_SCALE(2.71828183f, 2)), tmp);
|
||||
a_e = add(shl(mean_e, 1), 3);
|
||||
|
||||
/* b = (0.15f - (float)pow(2.0f, target_bits/(float)L_frame)) * mean; */
|
||||
tmp = BASOP_Util_Divide1616_Scale(target_bits, L_frame, &tmp2);
|
||||
tmp = round_fx(BASOP_util_Pow2(L_deposit_h(tmp), tmp2, &tmp2));
|
||||
b_e = BASOP_Util_Add_MantExp(4915/*0.15f Q15*/, 0, negate(tmp), tmp2, &b);
|
||||
b_e = BASOP_Util_Add_MantExp(FL2WORD16(0.15f), 0, negate(tmp), tmp2, &b);
|
||||
b = mult_r(b, round_fx(mean));
|
||||
b_e = add(b_e, mean_e);
|
||||
|
||||
/* scale = (-b + (float)sqrt(b*b - 4.0f*a*0.035f)) / (2.0f * a); */
|
||||
tmp = round_fx(BASOP_Util_Add_Mant32Exp(L_mult(b, b), shl(b_e, 1), Mpy_32_16_1(a, -4588/*-4.0f*0.035f Q15*/), a_e, &tmp2));
|
||||
tmp = round_fx(BASOP_Util_Add_Mant32Exp(L_mult(b, b), shl(b_e, 1), Mpy_32_16(a, FL2WORD16(-4.0f*0.035f)), a_e, &tmp2));
|
||||
|
||||
IF( tmp <= 0 )
|
||||
{
|
||||
tmp = 0;
|
||||
set16_fx(s_env, 0, L_frame);
|
||||
|
||||
FOR( k=0; k<L_frame; k++ )
|
||||
{
|
||||
s_env[k] = 0;
|
||||
move16();
|
||||
}
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
@@ -285,24 +305,24 @@ void tcx_arith_scale_envelope(
|
||||
|
||||
FOR (k = 0; k < L_frame; k++)
|
||||
{
|
||||
s = Mpy_32_16_1(ienv[k], scale); /* Q16 */
|
||||
s = Mpy_32_16(ienv[k], scale); /* Q16 */
|
||||
|
||||
IF (L_sub(s, 5243l/*0.08f Q16*/) <= 0)
|
||||
IF (L_sub(s, FL2WORD32_SCALE(0.08f, 15)) <= 0)
|
||||
{
|
||||
/* If s = 0.08, the expected bit-consumption is log2(1.0224). Below 0.08, the bit-consumption
|
||||
estimate function becomes inaccurate, so use log2(1.0224) for all values below 0.08. */
|
||||
/* round(state * 1.0224 * 32768) */
|
||||
statesi = mult_r(statesi, 16751/*1.0224 Q14*/);
|
||||
statesi = mult_r(statesi, FL2WORD16_SCALE(1.0224, 1));
|
||||
tmp = norm_s(statesi);
|
||||
statesi = shl(statesi, tmp);
|
||||
bits = add(bits, sub(1, tmp));
|
||||
}
|
||||
ELSE IF (L_sub(s, 16711680l/*255.0 Q16*/) <= 0)
|
||||
ELSE IF (L_sub(s, FL2WORD32_SCALE(255.0, 15)) <= 0)
|
||||
{
|
||||
/* a = 5.436564f * s + 0.15f + 0.035f * env[k] * iscale; */
|
||||
L_tmp = L_shl(Mpy_32_16_1(s, 22268/*5.436564f Q12*/), 3);
|
||||
L_tmp = L_add(L_tmp, 9830l/*0.15f Q16*/);
|
||||
L_tmp = L_add(L_tmp, L_shl(Mpy_32_16_1(env[k], mult_r(1147/*0.035f Q15*/, iscale)), iscale_e));
|
||||
L_tmp = L_shl(Mpy_32_16(s, FL2WORD16_SCALE(5.436564f, 3)), 3);
|
||||
L_tmp = L_add(L_tmp, FL2WORD32_SCALE(0.15f, 15));
|
||||
L_tmp = L_add(L_tmp, L_shl(Mpy_32_16(env[k], mult_r(FL2WORD16(0.035f), iscale)), iscale_e));
|
||||
|
||||
tmp = norm_l(L_tmp);
|
||||
statesi = mult_r(statesi, round_fx(L_shl(L_tmp, tmp)));
|
||||
@@ -317,13 +337,14 @@ void tcx_arith_scale_envelope(
|
||||
/* for large envelope values, s > 255, bit consumption is approx log2(2*e*s)
|
||||
* further, we use round(log2(x)) = floor(log2(x)+0.5) = floor(log2(x*sqrt(2))) */
|
||||
/* a = 5.436564f * s; */
|
||||
L_tmp = Mpy_32_16_1(s, 31492/*5.436564f * 1.4142f Q12*/); /* Q13 */
|
||||
L_tmp = Mpy_32_16(s, FL2WORD16_SCALE(5.436564f * 1.4142f, 3)); /* Q13 */
|
||||
bits = add(bits, sub(17, norm_l(L_tmp)));
|
||||
}
|
||||
}
|
||||
|
||||
IF (sub(bits, target_bits) <= 0) /* Bits leftover => scale is too small */
|
||||
IF (sub(bits, target_bits) <= 0)
|
||||
{
|
||||
/* Bits leftover => scale is too small */
|
||||
lob = scale;
|
||||
move16();
|
||||
lob_bits = bits;
|
||||
@@ -334,17 +355,19 @@ void tcx_arith_scale_envelope(
|
||||
adjust = div_s(sub(hib_bits, target_bits), sub(hib_bits, lob_bits));
|
||||
scale = add(mult_r(sub(lob, hib), adjust), hib);
|
||||
}
|
||||
ELSE /* Initial scale adaptation */
|
||||
ELSE
|
||||
{
|
||||
/* Initial scale adaptation */
|
||||
/* adjust = 1.05f * target_bits / (float)bits;
|
||||
scale *= adjust; */
|
||||
adjust = mult_r(17203/*1.05f Q14*/, target_bits);
|
||||
adjust = mult_r(FL2WORD16_SCALE(1.05f, 1), target_bits);
|
||||
adjust = BASOP_Util_Divide1616_Scale(adjust, bits, &tmp);
|
||||
scale = shl(mult_r(scale, adjust), add(1, tmp));
|
||||
}
|
||||
}
|
||||
ELSE /* Ran out of bits => scale is too large */
|
||||
ELSE
|
||||
{
|
||||
/* Ran out of bits => scale is too large */
|
||||
hib = scale;
|
||||
move16();
|
||||
hib_bits = bits;
|
||||
@@ -355,13 +378,19 @@ void tcx_arith_scale_envelope(
|
||||
adjust = div_s(sub(hib_bits, target_bits), sub(hib_bits, lob_bits));
|
||||
scale = add(mult_r(sub(lob, hib), adjust), hib);
|
||||
}
|
||||
ELSE { /* Initial scale adaptation */
|
||||
ELSE
|
||||
{ /* Initial scale adaptation */
|
||||
test();
|
||||
IF( target_bits <= 0 || bits <= 0 ) /* safety check in case of bit errors */
|
||||
{
|
||||
adjust = 0;
|
||||
move16();
|
||||
set16_fx( s_env, 0, L_frame );
|
||||
|
||||
FOR( k=0; k<L_frame; k++ )
|
||||
{
|
||||
s_env[k] = 0;
|
||||
move16();
|
||||
}
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
@@ -377,7 +406,12 @@ void tcx_arith_scale_envelope(
|
||||
{
|
||||
iscale = 0;
|
||||
move16();
|
||||
set16_fx( s_env, 0, L_frame );
|
||||
|
||||
FOR( k=0; k<L_frame; k++ )
|
||||
{
|
||||
s_env[k] = 0;
|
||||
move16();
|
||||
}
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
@@ -396,11 +430,14 @@ void tcx_arith_scale_envelope(
|
||||
|
||||
FOR (k = 0; k < L_frame; k++)
|
||||
{
|
||||
L_tmp = Mpy_32_16_1(L_shl(env[k], tmp), iscale);
|
||||
L_tmp = Mpy_32_16(L_shl(env[k], tmp), iscale);
|
||||
L_tmp = L_min(L_tmp, a);
|
||||
s_env[k] = round_fx(L_tmp);
|
||||
move16();
|
||||
}
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------
|
||||
@@ -415,14 +452,15 @@ void tcx_arith_scale_envelope(
|
||||
* NOTE: This function must be bit-exact on all platforms such that encoder
|
||||
* and decoder remain synchronized.
|
||||
*-------------------------------------------------------------------------*/
|
||||
|
||||
void tcx_arith_render_envelope(
|
||||
const Word16 A_ind[], /* i: LPC coefficients of signal envelope */
|
||||
Word16 L_frame, /* i: number of spectral lines */
|
||||
const Word16 A_ind[], /* i: LPC coefficients of signal envelope */
|
||||
Word16 L_frame, /* i: number of spectral lines */
|
||||
Word16 L_spec,
|
||||
Word16 preemph_fac, /* i: pre-emphasis factor */
|
||||
Word16 gamma_w, /* i: A_ind -> weighted envelope factor */
|
||||
Word16 gamma_uw, /* i: A_ind -> non-weighted envelope factor */
|
||||
Word32 env[] /* o: shaped signal envelope */
|
||||
Word16 preemph_fac, /* i: pre-emphasis factor */
|
||||
Word16 gamma_w, /* i: A_ind -> weighted envelope factor */
|
||||
Word16 gamma_uw, /* i: A_ind -> non-weighted envelope factor */
|
||||
Word32 env[] /* o: shaped signal envelope */
|
||||
)
|
||||
{
|
||||
Word16 k;
|
||||
@@ -431,15 +469,14 @@ void tcx_arith_render_envelope(
|
||||
Word16 gainlpc[FDNS_NPTS], gainlpc_e[FDNS_NPTS];
|
||||
|
||||
|
||||
|
||||
/* Compute perceptual LPC envelope, transform it into freq.-domain gains */
|
||||
weight_a_fx( A_ind, tmpA, gamma_w, M );
|
||||
lpc2mdct( tmpA, M, NULL, NULL, gainlpc, gainlpc_e );
|
||||
basop_weight_a(A_ind, tmpA, gamma_w);
|
||||
basop_lpc2mdct(tmpA, M, NULL, NULL, gainlpc, gainlpc_e);
|
||||
|
||||
/* Add pre-emphasis tilt to LPC envelope, transform LPC into MDCT gains */
|
||||
E_LPC_a_weight_inv(A_ind, signal_env, gamma_uw, M);
|
||||
E_LPC_a_add_tilt(signal_env, tmpA, preemph_fac, M);
|
||||
lpc2mdct(tmpA, M+1, signal_env, signal_env_e, NULL, NULL);
|
||||
basop_weight_a_inv(A_ind, signal_env, gamma_uw);
|
||||
basop_E_LPC_a_add_tilt(signal_env, tmpA, preemph_fac);
|
||||
basop_lpc2mdct(tmpA, M+1, signal_env, signal_env_e, NULL, NULL);
|
||||
|
||||
/* Compute weighted signal envelope in perceptual domain */
|
||||
FOR (k = 0; k < FDNS_NPTS; k++)
|
||||
@@ -451,15 +488,16 @@ void tcx_arith_render_envelope(
|
||||
}
|
||||
|
||||
/* Adaptive low frequency emphasis */
|
||||
set32_fx(env, 0x10000, L_frame);
|
||||
FOR (k = 0; k < L_frame; k++)
|
||||
{
|
||||
env[k] = 0x10000;
|
||||
move32();
|
||||
}
|
||||
|
||||
AdaptLowFreqDeemph(env, 15,
|
||||
1,
|
||||
gainlpc, gainlpc_e,
|
||||
L_frame, NULL);
|
||||
basop_PsychAdaptLowFreqDeemph(env, gainlpc, gainlpc_e, NULL);
|
||||
|
||||
/* Scale from FDNS_NPTS to L_frame and multiply LFE gains */
|
||||
mdct_noiseShaping_interp(env, L_frame, signal_env, signal_env_e);
|
||||
basop_mdct_noiseShaping_interp(env, L_frame, signal_env, signal_env_e);
|
||||
|
||||
FOR (k=L_frame; k<L_spec; ++k)
|
||||
{
|
||||
@@ -467,5 +505,6 @@ void tcx_arith_render_envelope(
|
||||
move32();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
348
src/libs/libevs/basic_op/basop32.cpp → src/libs/libevs/lib_com/basop32.cpp
Executable file → Normal file
348
src/libs/libevs/basic_op/basop32.cpp → src/libs/libevs/lib_com/basop32.cpp
Executable file → Normal file
@@ -1,3 +1,4 @@
|
||||
|
||||
/* v.2.3 - 30.Nov.2009
|
||||
=============================================================================
|
||||
|
||||
@@ -121,18 +122,15 @@ HISTORY:
|
||||
| Include-Files |
|
||||
|___________________________________________________________________________|
|
||||
*/
|
||||
#ifndef _CRT_SECURE_NO_WARNINGS
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "stl.h"
|
||||
|
||||
|
||||
#if (WMOPS)
|
||||
extern BASIC_OP multiCounter[MAXCOUNTERS];
|
||||
extern int currCounter;
|
||||
#endif
|
||||
|
||||
|
||||
/*___________________________________________________________________________
|
||||
| |
|
||||
| Local Functions |
|
||||
@@ -203,9 +201,6 @@ static Word16 saturate (Word32 L_var1)
|
||||
else
|
||||
{
|
||||
var_out = extract_l (L_var1);
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].extract_l--;
|
||||
#endif
|
||||
}
|
||||
|
||||
BASOP_CHECK();
|
||||
@@ -255,9 +250,7 @@ Word16 add (Word16 var1, Word16 var2)
|
||||
L_sum = (Word32) var1 + var2;
|
||||
var_out = saturate (L_sum);
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].add++;
|
||||
#endif
|
||||
|
||||
return (var_out);
|
||||
}
|
||||
|
||||
@@ -303,9 +296,7 @@ Word16 sub (Word16 var1, Word16 var2)
|
||||
L_diff = (Word32) var1 - var2;
|
||||
var_out = saturate (L_diff);
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].sub++;
|
||||
#endif
|
||||
|
||||
return (var_out);
|
||||
}
|
||||
|
||||
@@ -357,12 +348,9 @@ Word16 abs_s (Word16 var1)
|
||||
}
|
||||
}
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].abs_s++;
|
||||
#endif
|
||||
|
||||
BASOP_CHECK();
|
||||
|
||||
|
||||
return (var_out);
|
||||
}
|
||||
|
||||
@@ -412,10 +400,6 @@ Word16 shl (Word16 var1, Word16 var2)
|
||||
var2 = -16;
|
||||
var2 = -var2;
|
||||
var_out = shr (var1, var2);
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].shr--;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -429,19 +413,12 @@ Word16 shl (Word16 var1, Word16 var2)
|
||||
else
|
||||
{
|
||||
var_out = extract_l (result);
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].extract_l--;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].shl++;
|
||||
#endif
|
||||
|
||||
BASOP_CHECK();
|
||||
|
||||
|
||||
return (var_out);
|
||||
}
|
||||
|
||||
@@ -490,10 +467,6 @@ Word16 shr (Word16 var1, Word16 var2)
|
||||
var2 = -16;
|
||||
var2 = -var2;
|
||||
var_out = shl (var1, var2);
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].shl--;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -514,12 +487,9 @@ Word16 shr (Word16 var1, Word16 var2)
|
||||
}
|
||||
}
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].shr++;
|
||||
#endif
|
||||
|
||||
BASOP_CHECK();
|
||||
|
||||
|
||||
return (var_out);
|
||||
}
|
||||
|
||||
@@ -572,9 +542,7 @@ Word16 mult (Word16 var1, Word16 var2)
|
||||
|
||||
var_out = saturate (L_product);
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].mult++;
|
||||
#endif
|
||||
|
||||
return (var_out);
|
||||
}
|
||||
|
||||
@@ -629,12 +597,9 @@ Word32 L_mult (Word16 var1, Word16 var2)
|
||||
L_var_out = MAX_32;
|
||||
}
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_mult++;
|
||||
#endif
|
||||
|
||||
BASOP_CHECK();
|
||||
|
||||
|
||||
return (L_var_out);
|
||||
}
|
||||
|
||||
@@ -674,12 +639,9 @@ Word16 negate (Word16 var1)
|
||||
var_out = (var1 == MIN_16) ? MAX_16 : -var1;
|
||||
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].negate++;
|
||||
#endif
|
||||
|
||||
BASOP_CHECK();
|
||||
|
||||
|
||||
return (var_out);
|
||||
}
|
||||
|
||||
@@ -717,12 +679,9 @@ Word16 extract_h (Word32 L_var1)
|
||||
|
||||
var_out = (Word16) (L_var1 >> 16);
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].extract_h++;
|
||||
#endif
|
||||
|
||||
BASOP_CHECK();
|
||||
|
||||
|
||||
return (var_out);
|
||||
}
|
||||
|
||||
@@ -760,12 +719,9 @@ Word16 extract_l (Word32 L_var1)
|
||||
|
||||
var_out = (Word16) L_var1;
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].extract_l++;
|
||||
#endif
|
||||
|
||||
BASOP_CHECK();
|
||||
|
||||
|
||||
return (var_out);
|
||||
}
|
||||
|
||||
@@ -805,19 +761,14 @@ Word16 round_fx (Word32 L_var1)
|
||||
Word16 var_out;
|
||||
Word32 L_rounded;
|
||||
|
||||
BASOP_SATURATE_WARNING_OFF
|
||||
BASOP_SATURATE_WARNING_OFF
|
||||
L_rounded = L_add (L_var1, (Word32) 0x00008000L);
|
||||
BASOP_SATURATE_WARNING_ON
|
||||
BASOP_SATURATE_WARNING_ON
|
||||
var_out = extract_h (L_rounded);
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_add--;
|
||||
multiCounter[currCounter].extract_h--;
|
||||
multiCounter[currCounter].round++;
|
||||
#endif
|
||||
|
||||
BASOP_CHECK();
|
||||
|
||||
|
||||
return (var_out);
|
||||
}
|
||||
|
||||
@@ -866,14 +817,9 @@ Word32 L_mac (Word32 L_var3, Word16 var1, Word16 var2)
|
||||
L_product = L_mult (var1, var2);
|
||||
L_var_out = L_add (L_var3, L_product);
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_mult--;
|
||||
multiCounter[currCounter].L_add--;
|
||||
multiCounter[currCounter].L_mac++;
|
||||
#endif
|
||||
|
||||
BASOP_CHECK();
|
||||
|
||||
|
||||
return (L_var_out);
|
||||
}
|
||||
|
||||
@@ -922,14 +868,9 @@ Word32 L_msu (Word32 L_var3, Word16 var1, Word16 var2)
|
||||
L_product = L_mult (var1, var2);
|
||||
L_var_out = L_sub (L_var3, L_product);
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_mult--;
|
||||
multiCounter[currCounter].L_sub--;
|
||||
multiCounter[currCounter].L_msu++;
|
||||
#endif
|
||||
|
||||
BASOP_CHECK();
|
||||
|
||||
|
||||
return (L_var_out);
|
||||
}
|
||||
|
||||
@@ -983,12 +924,6 @@ Word32 L_macNs (Word32 L_var3, Word16 var1, Word16 var2)
|
||||
L_var_out = L_mult (var1, var2);
|
||||
L_var_out = L_add_c (L_var3, L_var_out);
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_mult--;
|
||||
multiCounter[currCounter].L_add_c--;
|
||||
multiCounter[currCounter].L_macNs++;
|
||||
#endif
|
||||
|
||||
/* BASOP_CHECK(); Do not check for overflow here, function produces the carry bit instead */
|
||||
|
||||
|
||||
@@ -1045,15 +980,9 @@ Word32 L_msuNs (Word32 L_var3, Word16 var1, Word16 var2)
|
||||
L_var_out = L_mult (var1, var2);
|
||||
L_var_out = L_sub_c (L_var3, L_var_out);
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_mult--;
|
||||
multiCounter[currCounter].L_sub_c--;
|
||||
multiCounter[currCounter].L_msuNs++;
|
||||
|
||||
#endif
|
||||
|
||||
/* BASOP_CHECK(); Do not check for overflow here, function produces the carry bit instead */
|
||||
|
||||
|
||||
return (L_var_out);
|
||||
}
|
||||
|
||||
@@ -1104,12 +1033,9 @@ Word32 L_add (Word32 L_var1, Word32 L_var2)
|
||||
}
|
||||
}
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_add++;
|
||||
#endif
|
||||
|
||||
BASOP_CHECK();
|
||||
|
||||
|
||||
return (L_var_out);
|
||||
}
|
||||
|
||||
@@ -1160,12 +1086,9 @@ Word32 L_sub (Word32 L_var1, Word32 L_var2)
|
||||
}
|
||||
}
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_sub++;
|
||||
#endif
|
||||
|
||||
BASOP_CHECK();
|
||||
|
||||
|
||||
return (L_var_out);
|
||||
}
|
||||
|
||||
@@ -1276,12 +1199,9 @@ Word32 L_add_c (Word32 L_var1, Word32 L_var2)
|
||||
Carry = carry_int;
|
||||
}
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_add_c++;
|
||||
#endif
|
||||
|
||||
/* BASOP_CHECK(); Do not check for overflow here, function produces the carry bit instead */
|
||||
|
||||
|
||||
return (L_var_out);
|
||||
}
|
||||
|
||||
@@ -1335,9 +1255,6 @@ Word32 L_sub_c (Word32 L_var1, Word32 L_var2)
|
||||
if (L_var2 != MIN_32)
|
||||
{
|
||||
L_var_out = L_add_c (L_var1, -L_var2);
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_add_c--;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1380,12 +1297,9 @@ Word32 L_sub_c (Word32 L_var1, Word32 L_var2)
|
||||
}
|
||||
}
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_sub_c++;
|
||||
#endif
|
||||
|
||||
/* BASOP_CHECK(); Do not check for overflow here, function produces the carry bit instead */
|
||||
|
||||
|
||||
return (L_var_out);
|
||||
}
|
||||
|
||||
@@ -1424,12 +1338,9 @@ Word32 L_negate (Word32 L_var1)
|
||||
L_var_out = (L_var1 == MIN_32) ? MAX_32 : -L_var1;
|
||||
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_negate++;
|
||||
#endif
|
||||
|
||||
BASOP_CHECK();
|
||||
|
||||
|
||||
return (L_var_out);
|
||||
}
|
||||
|
||||
@@ -1483,9 +1394,7 @@ Word16 mult_r (Word16 var1, Word16 var2)
|
||||
}
|
||||
var_out = saturate (L_product_arr);
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].mult_r++;
|
||||
#endif
|
||||
|
||||
return (var_out);
|
||||
}
|
||||
|
||||
@@ -1534,9 +1443,6 @@ Word32 L_shl (Word32 L_var1, Word16 var2)
|
||||
var2 = -32;
|
||||
var2 = -var2;
|
||||
L_var_out = L_shr (L_var1, var2);
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_shr--;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1561,12 +1467,10 @@ Word32 L_shl (Word32 L_var1, Word16 var2)
|
||||
L_var_out = L_var1;
|
||||
}
|
||||
}
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_shl++;
|
||||
#endif
|
||||
|
||||
BASOP_CHECK();
|
||||
|
||||
|
||||
return (L_var_out);
|
||||
}
|
||||
|
||||
@@ -1614,9 +1518,6 @@ Word32 L_shr (Word32 L_var1, Word16 var2)
|
||||
var2 = -32;
|
||||
var2 = -var2;
|
||||
L_var_out = L_shl (L_var1, var2);
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_shl--;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1636,12 +1537,10 @@ Word32 L_shr (Word32 L_var1, Word16 var2)
|
||||
}
|
||||
}
|
||||
}
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_shr++;
|
||||
#endif
|
||||
|
||||
BASOP_CHECK();
|
||||
|
||||
|
||||
return (L_var_out);
|
||||
}
|
||||
|
||||
@@ -1699,10 +1598,6 @@ Word16 shr_r (Word16 var1, Word16 var2)
|
||||
{
|
||||
var_out = shr (var1, var2);
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].shr--;
|
||||
#endif
|
||||
|
||||
if (var2 > 0)
|
||||
{
|
||||
if ((var1 & ((Word16) 1 << (var2 - 1))) != 0)
|
||||
@@ -1712,12 +1607,9 @@ Word16 shr_r (Word16 var1, Word16 var2)
|
||||
}
|
||||
}
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].shr_r++;
|
||||
#endif
|
||||
|
||||
BASOP_CHECK();
|
||||
|
||||
|
||||
return (var_out);
|
||||
}
|
||||
|
||||
@@ -1768,15 +1660,9 @@ Word16 mac_r (Word32 L_var3, Word16 var1, Word16 var2)
|
||||
L_var3 = L_add (L_var3, (Word32) 0x00008000L);
|
||||
var_out = extract_h (L_var3);
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_mac--;
|
||||
multiCounter[currCounter].L_add--;
|
||||
multiCounter[currCounter].extract_h--;
|
||||
multiCounter[currCounter].mac_r++;
|
||||
#endif
|
||||
|
||||
BASOP_CHECK();
|
||||
|
||||
|
||||
return (var_out);
|
||||
}
|
||||
|
||||
@@ -1827,15 +1713,9 @@ Word16 msu_r (Word32 L_var3, Word16 var1, Word16 var2)
|
||||
L_var3 = L_add (L_var3, (Word32) 0x00008000L);
|
||||
var_out = extract_h (L_var3);
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_msu--;
|
||||
multiCounter[currCounter].L_add--;
|
||||
multiCounter[currCounter].extract_h--;
|
||||
multiCounter[currCounter].msu_r++;
|
||||
#endif
|
||||
|
||||
BASOP_CHECK();
|
||||
|
||||
|
||||
return (var_out);
|
||||
}
|
||||
|
||||
@@ -1874,12 +1754,9 @@ Word32 L_deposit_h (Word16 var1)
|
||||
|
||||
L_var_out = (Word32) var1 << 16;
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_deposit_h++;
|
||||
#endif
|
||||
|
||||
BASOP_CHECK();
|
||||
|
||||
|
||||
return (L_var_out);
|
||||
}
|
||||
|
||||
@@ -1918,12 +1795,9 @@ Word32 L_deposit_l (Word16 var1)
|
||||
|
||||
L_var_out = (Word32) var1;
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_deposit_l++;
|
||||
#endif
|
||||
|
||||
BASOP_CHECK();
|
||||
|
||||
|
||||
return (L_var_out);
|
||||
}
|
||||
|
||||
@@ -1981,9 +1855,6 @@ Word32 L_shr_r (Word32 L_var1, Word16 var2)
|
||||
{
|
||||
L_var_out = L_shr (L_var1, var2);
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_shr--;
|
||||
#endif
|
||||
if (var2 > 0)
|
||||
{
|
||||
if ((L_var1 & ((Word32) 1 << (var2 - 1))) != 0)
|
||||
@@ -1993,12 +1864,9 @@ Word32 L_shr_r (Word32 L_var1, Word16 var2)
|
||||
}
|
||||
}
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_shr_r++;
|
||||
#endif
|
||||
|
||||
BASOP_CHECK();
|
||||
|
||||
|
||||
return (L_var_out);
|
||||
}
|
||||
|
||||
@@ -2051,12 +1919,9 @@ Word32 L_abs (Word32 L_var1)
|
||||
}
|
||||
}
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_abs++;
|
||||
#endif
|
||||
|
||||
BASOP_CHECK();
|
||||
|
||||
|
||||
return (L_var_out);
|
||||
}
|
||||
|
||||
@@ -2113,12 +1978,9 @@ Word32 L_sat (Word32 L_var1)
|
||||
Overflow = 0;
|
||||
}
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_sat++;
|
||||
#endif
|
||||
|
||||
BASOP_CHECK();
|
||||
|
||||
|
||||
return (L_var_out);
|
||||
}
|
||||
|
||||
@@ -2182,12 +2044,9 @@ Word16 norm_s (Word16 var1)
|
||||
}
|
||||
}
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].norm_s++;
|
||||
#endif
|
||||
|
||||
BASOP_CHECK();
|
||||
|
||||
|
||||
return (var_out);
|
||||
}
|
||||
|
||||
@@ -2239,7 +2098,7 @@ Word16 div_s (Word16 var1, Word16 var2)
|
||||
{
|
||||
/* printf ("Division Error var1=%d var2=%d in ", var1, var2); printStack(); */
|
||||
char text[60];
|
||||
sprintf (text, "\nDivision Error var1=%d var2=%d in ", var1, var2);
|
||||
sprintf (text, "Division Error var1=%d var2=%d in ", var1, var2);
|
||||
abort(); /* exit (0); */
|
||||
}
|
||||
if (var2 == 0)
|
||||
@@ -2262,11 +2121,6 @@ Word16 div_s (Word16 var1, Word16 var2)
|
||||
L_num = L_deposit_l (var1);
|
||||
L_denom = L_deposit_l (var2);
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_deposit_l--;
|
||||
multiCounter[currCounter].L_deposit_l--;
|
||||
#endif
|
||||
|
||||
for (iteration = 0; iteration < 15; iteration++)
|
||||
{
|
||||
var_out <<= 1;
|
||||
@@ -2276,21 +2130,14 @@ Word16 div_s (Word16 var1, Word16 var2)
|
||||
{
|
||||
L_num = L_sub (L_num, L_denom);
|
||||
var_out = add (var_out, 1);
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_sub--;
|
||||
multiCounter[currCounter].add--;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].div_s++;
|
||||
#endif
|
||||
|
||||
BASOP_CHECK();
|
||||
|
||||
|
||||
return (var_out);
|
||||
}
|
||||
|
||||
@@ -2354,12 +2201,9 @@ Word16 norm_l (Word32 L_var1)
|
||||
}
|
||||
}
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].norm_l++;
|
||||
#endif
|
||||
|
||||
BASOP_CHECK();
|
||||
|
||||
|
||||
return (var_out);
|
||||
}
|
||||
|
||||
@@ -2411,24 +2255,17 @@ Word16 norm_l (Word32 L_var1)
|
||||
*/
|
||||
Word32 L_mls (Word32 Lv, Word16 v)
|
||||
{
|
||||
Word32 Temp ;
|
||||
Word32 Temp ;
|
||||
|
||||
Temp = Lv & (Word32) 0x0000ffff ;
|
||||
Temp = Temp * (Word32) v ;
|
||||
Temp = L_shr( Temp, (Word16) 15 ) ;
|
||||
Temp = L_mac( Temp, v, extract_h(Lv) ) ;
|
||||
Temp = Lv & (Word32) 0x0000ffff ;
|
||||
Temp = Temp * (Word32) v ;
|
||||
Temp = L_shr( Temp, (Word16) 15 ) ;
|
||||
Temp = L_mac( Temp, v, extract_h(Lv) ) ;
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_shr--;
|
||||
multiCounter[currCounter].L_mac--;
|
||||
multiCounter[currCounter].extract_h--;
|
||||
multiCounter[currCounter].L_mls++;
|
||||
#endif
|
||||
BASOP_CHECK();
|
||||
|
||||
|
||||
BASOP_CHECK();
|
||||
|
||||
return Temp ;
|
||||
return Temp ;
|
||||
}
|
||||
|
||||
|
||||
@@ -2476,55 +2313,44 @@ Word16 div_l (Word32 L_num, Word16 den)
|
||||
Word32 L_den;
|
||||
Word16 iteration;
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].div_l++;
|
||||
#endif
|
||||
|
||||
if ( den == (Word16) 0 ) {
|
||||
if ( den == (Word16) 0 )
|
||||
{
|
||||
/* printf("Division by 0 in div_l, Fatal error in "); printStack(); */
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if ( (L_num < (Word32) 0) || (den < (Word16) 0) ) {
|
||||
if ( (L_num < (Word32) 0) || (den < (Word16) 0) )
|
||||
{
|
||||
/* printf("Division Error in div_l, Fatal error in "); printStack(); */
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
L_den = L_deposit_h( den ) ;
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_deposit_h--;
|
||||
#endif
|
||||
|
||||
if ( L_num >= L_den ){
|
||||
if ( L_num >= L_den )
|
||||
{
|
||||
|
||||
|
||||
BASOP_CHECK();
|
||||
|
||||
return MAX_16 ;
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
L_num = L_shr(L_num, (Word16)1) ;
|
||||
L_den = L_shr(L_den, (Word16)1);
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_shr-=2;
|
||||
#endif
|
||||
for(iteration=(Word16)0; iteration< (Word16)15;iteration++) {
|
||||
for(iteration=(Word16)0; iteration< (Word16)15; iteration++)
|
||||
{
|
||||
var_out = shl( var_out, (Word16)1);
|
||||
L_num = L_shl( L_num, (Word16)1);
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].shl--;
|
||||
multiCounter[currCounter].L_shl--;
|
||||
#endif
|
||||
if (L_num >= L_den) {
|
||||
if (L_num >= L_den)
|
||||
{
|
||||
L_num = L_sub(L_num,L_den);
|
||||
var_out = add(var_out, (Word16)1);
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_sub--;
|
||||
multiCounter[currCounter].add--;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BASOP_CHECK();
|
||||
|
||||
return var_out;
|
||||
@@ -2565,13 +2391,10 @@ Word16 div_l (Word32 L_num, Word16 den)
|
||||
Word16 i_mult (Word16 a, Word16 b)
|
||||
{
|
||||
#ifdef ORIGINAL_G7231
|
||||
return a*b ;
|
||||
return a*b ;
|
||||
#else
|
||||
Word32 /*register*/ c=a*b;
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].i_mult++;
|
||||
#endif
|
||||
return saturate(c) ;
|
||||
Word32 /*register*/ c=a*b;
|
||||
return saturate(c) ;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -2612,17 +2435,14 @@ Word16 i_mult (Word16 a, Word16 b)
|
||||
*/
|
||||
Word32 L_mult0 (Word16 var1,Word16 var2)
|
||||
{
|
||||
Word32 L_var_out;
|
||||
Word32 L_var_out;
|
||||
|
||||
L_var_out = (Word32)var1 * (Word32)var2;
|
||||
L_var_out = (Word32)var1 * (Word32)var2;
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_mult0++;
|
||||
#endif
|
||||
BASOP_CHECK();
|
||||
|
||||
BASOP_CHECK();
|
||||
|
||||
return(L_var_out);
|
||||
return(L_var_out);
|
||||
}
|
||||
|
||||
|
||||
@@ -2658,21 +2478,16 @@ Word32 L_mult0 (Word16 var1,Word16 var2)
|
||||
*/
|
||||
Word32 L_mac0 (Word32 L_var3, Word16 var1, Word16 var2)
|
||||
{
|
||||
Word32 L_var_out;
|
||||
Word32 L_product;
|
||||
Word32 L_var_out;
|
||||
Word32 L_product;
|
||||
|
||||
L_product = L_mult0(var1,var2);
|
||||
L_var_out = L_add(L_var3,L_product);
|
||||
L_product = L_mult0(var1,var2);
|
||||
L_var_out = L_add(L_var3,L_product);
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_mac0++;
|
||||
multiCounter[currCounter].L_mult0--;
|
||||
multiCounter[currCounter].L_add--;
|
||||
#endif
|
||||
BASOP_CHECK();
|
||||
|
||||
BASOP_CHECK();
|
||||
|
||||
return(L_var_out);
|
||||
return(L_var_out);
|
||||
}
|
||||
|
||||
|
||||
@@ -2708,21 +2523,16 @@ Word32 L_mac0 (Word32 L_var3, Word16 var1, Word16 var2)
|
||||
*/
|
||||
Word32 L_msu0 (Word32 L_var3, Word16 var1, Word16 var2)
|
||||
{
|
||||
Word32 L_var_out;
|
||||
Word32 L_product;
|
||||
Word32 L_var_out;
|
||||
Word32 L_product;
|
||||
|
||||
L_product = L_mult0(var1,var2);
|
||||
L_var_out = L_sub(L_var3,L_product);
|
||||
L_product = L_mult0(var1,var2);
|
||||
L_var_out = L_sub(L_var3,L_product);
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_msu0++;
|
||||
multiCounter[currCounter].L_mult0--;
|
||||
multiCounter[currCounter].L_sub--;
|
||||
#endif
|
||||
BASOP_CHECK();
|
||||
|
||||
BASOP_CHECK();
|
||||
|
||||
return(L_var_out);
|
||||
return(L_var_out);
|
||||
}
|
||||
|
||||
|
||||
0
src/libs/libevs/basic_op/basop32.h → src/libs/libevs/lib_com/basop32.h
Executable file → Normal file
0
src/libs/libevs/basic_op/basop32.h → src/libs/libevs/lib_com/basop32.h
Executable file → Normal file
237
src/libs/libevs/lib_com/basop_com_lpc.cpp
Normal file
237
src/libs/libevs/lib_com/basop_com_lpc.cpp
Normal file
@@ -0,0 +1,237 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.443 Nov 13, 2018. Version 12.11.0 / 13.7.0 / 14.3.0 / 15.1.0
|
||||
====================================================================================*/
|
||||
|
||||
|
||||
#include <math.h>
|
||||
#include <memory.h>
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include "typedef.h"
|
||||
#include "basop_proto_func.h"
|
||||
#include "cnst.h"
|
||||
|
||||
#include "basop_util.h"
|
||||
#include "stl.h"
|
||||
|
||||
#define UNROLL_CHEBYSHEV_INNER_LOOP
|
||||
#define NC_MAX 8
|
||||
#define GUESS_TBL_SZ 256
|
||||
|
||||
#define Madd_32_16(accu, x, y) L_add(accu, Mpy_32_16(x, y))
|
||||
#define Msub_32_16(accu, x, y) L_sub(accu, Mpy_32_16(x, y))
|
||||
|
||||
|
||||
/*
|
||||
* weight_a
|
||||
*
|
||||
* Parameters:
|
||||
* a I: LP filter coefficients Q12
|
||||
* ap O: weighted LP filter coefficients Q12
|
||||
* gamma I: weighting factor Q15
|
||||
*
|
||||
* Function:
|
||||
* Weighting of LP filter coefficients, ap[i] = a[i] * (gamma^i).
|
||||
*
|
||||
* Returns:
|
||||
* void
|
||||
*/
|
||||
void basop_weight_a(const Word16 *a, Word16 *ap, const Word16 gamma)
|
||||
{
|
||||
Word16 i, fac;
|
||||
Word32 Amax;
|
||||
Word16 shift;
|
||||
|
||||
|
||||
|
||||
fac = gamma;
|
||||
Amax = L_mult( 16384, a[0] );
|
||||
FOR (i = 1; i < M; i++)
|
||||
{
|
||||
Amax = L_max( Amax, L_abs( L_mult0( fac, a[i] ) ) );
|
||||
fac = mult_r( fac, gamma );
|
||||
}
|
||||
Amax = L_max( Amax, L_abs( L_mult0( fac, a[M] ) ) );
|
||||
shift = norm_l( Amax );
|
||||
fac = gamma;
|
||||
ap[0] = shl( a[0], sub(shift,1) );
|
||||
move16();
|
||||
FOR (i = 1; i < M; i++)
|
||||
{
|
||||
ap[i] = round_fx(L_shl(L_mult0(a[i], fac),shift));
|
||||
move16();
|
||||
fac = mult_r( fac, gamma );
|
||||
}
|
||||
ap[M] = round_fx(L_shl(L_mult0(a[M], fac),shift));
|
||||
move16();
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* weight_a_inv
|
||||
*
|
||||
* Parameters:
|
||||
* a I: LP filter coefficients Q12
|
||||
* ap O: weighted LP filter coefficients Q12
|
||||
* inv_gamma I: inverse weighting factor Q14
|
||||
*
|
||||
* Function:
|
||||
* Weighting of LP filter coefficients, ap[i] = a[i] * (inv_gamma^i).
|
||||
*
|
||||
* Returns:
|
||||
* void
|
||||
*/
|
||||
void basop_weight_a_inv(const Word16 *a, Word16 *ap, const Word16 inv_gamma)
|
||||
{
|
||||
Word16 i;
|
||||
static const Word16 inv_gamma_tab_12k8[16] = { 17809, 19357, 21041, 22870, 24859, 27020, 29370, 31924, /* Q14 */
|
||||
17350, 18859, 20499, 22281, 24219, 26325, 28614, 31102
|
||||
}; /* Q13 */
|
||||
static const Word16 inv_gamma_tab_16k[16] = { 17430, 18542, 19726, 20985, 22324, 23749, 25265, 26878, /* Q14 */
|
||||
14297, 15209, 16180, 17213, 18312, 19480, 20724, 22047
|
||||
}; /* Q13 */
|
||||
const Word16 *inv_gamma_tab;
|
||||
Word32 L_tmp;
|
||||
Word32 Amax;
|
||||
Word16 shift;
|
||||
|
||||
|
||||
IF (inv_gamma == 16384)
|
||||
{
|
||||
FOR (i = 0; i <= M; i++)
|
||||
{
|
||||
ap[i] = a[i];
|
||||
move16();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
assert( inv_gamma==GAMMA1_INV || inv_gamma==GAMMA16k_INV );
|
||||
|
||||
inv_gamma_tab = inv_gamma_tab_12k8;
|
||||
move16();
|
||||
if (sub(inv_gamma,GAMMA16k_INV) == 0)
|
||||
{
|
||||
inv_gamma_tab = inv_gamma_tab_16k;
|
||||
move16();
|
||||
}
|
||||
|
||||
Amax = L_mult( 16384, a[0] );
|
||||
FOR (i = 1; i < 9; i++)
|
||||
{
|
||||
Amax = L_max( Amax, L_abs( L_mult( a[i], inv_gamma_tab[i-1] ) ) );
|
||||
}
|
||||
FOR (i = 9; i < 17; i++)
|
||||
{
|
||||
Amax = L_max( Amax, L_abs( L_shl( L_mult( a[i], inv_gamma_tab[i-1] ), 1 ) ) );
|
||||
}
|
||||
shift = norm_l( Amax );
|
||||
ap[0] = shl( a[0], sub(shift,1) );
|
||||
move16();
|
||||
FOR (i = 1; i < 9; i++)
|
||||
{
|
||||
L_tmp = L_mult( a[i], inv_gamma_tab[i-1] );
|
||||
ap[i] = round_fx( L_shl( L_tmp, shift ) );
|
||||
move16();
|
||||
}
|
||||
shift = add(shift,1);
|
||||
FOR (i = 9; i < 17; i++)
|
||||
{
|
||||
L_tmp = L_mult( a[i], inv_gamma_tab[i-1] );
|
||||
ap[i] = round_fx( L_shl( L_tmp, shift ) );
|
||||
move16();
|
||||
}
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* basop_E_LPC_a_add_tilt
|
||||
*
|
||||
* Parameters:
|
||||
* a I: LP filter coefficients (m+1 coeffs)
|
||||
* ap O: modified LP filter coefficients (m+2 coeffs)
|
||||
* gamma I: tilt factor
|
||||
*
|
||||
* Function:
|
||||
* Modified LP filter by adding 1st order pre-premphasis, Ap(z)=A(z).(1-gamma.z^(-1))
|
||||
*
|
||||
* Returns:
|
||||
* void
|
||||
*/
|
||||
void basop_E_LPC_a_add_tilt(const Word16 *a, Word16 *ap, Word16 gamma)
|
||||
{
|
||||
Word16 i;
|
||||
Word32 Amax, Atmp[M+2];
|
||||
Word16 shift;
|
||||
|
||||
|
||||
|
||||
|
||||
Amax = L_mult( 16384, a[0] );
|
||||
FOR (i = 1; i <= M; i++)
|
||||
{
|
||||
Atmp[i] = L_sub( L_mult(16384, a[i]), L_mult0(gamma, a[i-1]) );
|
||||
move32();
|
||||
Amax = L_max( Amax, L_abs( Atmp[i] ) );
|
||||
}
|
||||
Atmp[M+1] = L_negate( L_mult0(gamma, a[M]) );
|
||||
move32();
|
||||
Amax = L_max( Amax, L_abs( Atmp[M+1] ) );
|
||||
shift = norm_l( Amax );
|
||||
ap[0] = shl( a[0], sub(shift,1) );
|
||||
move16();
|
||||
FOR (i = 1; i <= M; i++)
|
||||
{
|
||||
ap[i] = round_fx( L_shl( Atmp[i], shift ) );
|
||||
move16();
|
||||
}
|
||||
ap[M+1] = round_fx( L_shl( Atmp[M+1], shift ) );
|
||||
move16();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static Word16 xsf_to_xsp(Word16 xsf)
|
||||
{
|
||||
/* xsp = cos(xsf * 3.1415/6400); */
|
||||
return getCosWord16R2(xsf);
|
||||
}
|
||||
|
||||
/*
|
||||
* lsf2lsp
|
||||
*
|
||||
* Parameters:
|
||||
* lsf I: lsf[m] normalized (range: 0 <= val <= 0.5) x2.56
|
||||
* lsp O: lsp[m] (range: -1 <= val < 1) Q15
|
||||
*
|
||||
* Function:
|
||||
* Transformation lsf to lsp
|
||||
*
|
||||
* LSF are line spectral pair in frequency domain (0 to 6400).
|
||||
* LSP are line spectral pair in cosine domain (-1 to 1).
|
||||
*
|
||||
* Returns:
|
||||
* void
|
||||
*/
|
||||
void basop_lsf2lsp(const Word16 lsf[], Word16 lsp[])
|
||||
{
|
||||
Word16 i;
|
||||
|
||||
|
||||
|
||||
/* convert ISFs to the cosine domain */
|
||||
FOR (i = 0; i < M; i++)
|
||||
{
|
||||
*lsp++ = xsf_to_xsp(*lsf++);
|
||||
move16();
|
||||
}
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
262
src/libs/libevs/lib_com/basop_lsf_tools.cpp
Normal file
262
src/libs/libevs/lib_com/basop_lsf_tools.cpp
Normal file
@@ -0,0 +1,262 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.443 Nov 13, 2018. Version 12.11.0 / 13.7.0 / 14.3.0 / 15.1.0
|
||||
====================================================================================*/
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include "basop_proto_func.h"
|
||||
#include "control.h"
|
||||
#include "basop_util.h"
|
||||
|
||||
#define NC_MAX 8
|
||||
|
||||
static Word16 E_LPC_f_lsp_pol_get(const Word16 lsp[], Word32 f[], const Word16 n, const Word16 past_Ovf, const Word16 isMODE1);
|
||||
|
||||
|
||||
/*
|
||||
* E_LPC_f_lsp_a_conversion
|
||||
*
|
||||
* Parameters:
|
||||
* lsp I: Line spectral pairs Q15
|
||||
* a O: Predictor coefficients (order = m) Qx (The Q factor of the output to be deduced from a(0))
|
||||
* m I: order of LP filter
|
||||
*
|
||||
* Function:
|
||||
* Convert ISPs to predictor coefficients a[]
|
||||
*
|
||||
* Returns:
|
||||
* void
|
||||
*/
|
||||
void basop_E_LPC_f_lsp_a_conversion(const Word16 *lsp, Word16 *a, const Word16 m)
|
||||
{
|
||||
Word16 i, j, k;
|
||||
Word32 f1[NC_MAX+1], f2[NC_MAX+1];
|
||||
Word16 nc;
|
||||
Word32 t0;
|
||||
Word16 Ovf, Ovf2;
|
||||
|
||||
|
||||
/*-----------------------------------------------------*
|
||||
* Find the polynomials F1(z) and F2(z) *
|
||||
*-----------------------------------------------------*/
|
||||
|
||||
nc = shr(m, 1);
|
||||
|
||||
assert(m == 16 || m == 10);
|
||||
|
||||
Ovf = 0;
|
||||
move16();
|
||||
Ovf = E_LPC_f_lsp_pol_get(&lsp[0], f1, nc, Ovf, 1);
|
||||
Ovf2 = E_LPC_f_lsp_pol_get(&lsp[1], f2, nc, Ovf, 1);
|
||||
IF(sub(Ovf2,Ovf) !=0)
|
||||
{
|
||||
/* to ensure similar scaling for f1 and f2 in case
|
||||
an overflow would be detected only in f2,
|
||||
but this case never happen on my dtb */
|
||||
E_LPC_f_lsp_pol_get(&lsp[0], f1, nc, s_max(Ovf2,Ovf), 1);
|
||||
}
|
||||
/*-----------------------------------------------------*
|
||||
* Multiply F1(z) by (1+z^-1) and F2(z) by (1-z^-1) *
|
||||
*-----------------------------------------------------*/
|
||||
/*modification*/
|
||||
k = sub(nc,1);
|
||||
FOR (i = 0; i <= k; i++)
|
||||
{
|
||||
f1[nc-i] = L_add(f1[nc-i],f1[nc-i-1]);
|
||||
move32();
|
||||
f2[nc-i] = L_sub(f2[nc-i],f2[nc-i-1]);
|
||||
move32();
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*
|
||||
* A(z) = (F1(z)+F2(z))/2 *
|
||||
* F1(z) is symmetric and F2(z) is antisymmetric *
|
||||
*-----------------------------------------------------*/
|
||||
|
||||
t0 = L_deposit_l(0);
|
||||
FOR (i = 1; i <= nc; i++)
|
||||
{
|
||||
t0 = L_max( t0, L_abs(L_add(f1[i], f2[i])) );
|
||||
t0 = L_max( t0, L_abs(L_sub(f1[i], f2[i])) );
|
||||
}
|
||||
k = s_min( norm_l(t0), 6 );
|
||||
a[0] = shl( 256, k );
|
||||
move16();
|
||||
test();
|
||||
IF( Ovf || Ovf2)
|
||||
{
|
||||
a[0] = shl( 256, sub(k,Ovf) );
|
||||
move16();
|
||||
}
|
||||
j = m;
|
||||
FOR (i = 1; i <= nc; i++)
|
||||
{
|
||||
/* a[i] = 0.5*(f1[i] + f2[i]) */
|
||||
t0 = L_add(f1[i],f2[i]);
|
||||
t0 = L_shl(t0, k);
|
||||
a[i] = round_fx(t0); /* from Q23 to Qx and * 0.5 */
|
||||
|
||||
/* a[j] = 0.5*(f1[i] - f2[i]) */
|
||||
t0 = L_sub(f1[i],f2[i]);
|
||||
t0 = L_shl(t0, k);
|
||||
a[j] = round_fx(t0); /* from Q23 to Qx and * 0.5 */
|
||||
j--;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
* procedure reorder_lsf()
|
||||
*
|
||||
* To make sure that the lsfs are properly ordered and to keep a certain
|
||||
* minimum distance between consecutive lsfs.
|
||||
*--------------------------------------------------------------------------*/
|
||||
void basop_reorder_lsf(
|
||||
Word16 *lsf, /* i/o: LSFs in the frequency domain (0..0.5) Q(x2.56)*/
|
||||
const Word16 min_dist, /* i : minimum required distance x2.56*/
|
||||
const Word16 n, /* i : LPC order */
|
||||
const Word32 fs /* i : sampling frequency */
|
||||
)
|
||||
{
|
||||
Word16 i, lsf_min, n_m_1;
|
||||
Word16 lsf_max;
|
||||
|
||||
lsf_min = min_dist;
|
||||
move16();
|
||||
|
||||
/*-----------------------------------------------------------------------*
|
||||
* Verify the LSF ordering and minimum GAP
|
||||
*-----------------------------------------------------------------------*/
|
||||
|
||||
FOR (i = 0; i < n; i++)
|
||||
{
|
||||
if (sub(lsf[i], lsf_min) < 0)
|
||||
{
|
||||
lsf[i] = lsf_min;
|
||||
move16();
|
||||
}
|
||||
lsf_min = add(lsf[i], min_dist);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------*
|
||||
* Reverify the LSF ordering and minimum GAP in the reverse order (security)
|
||||
*-----------------------------------------------------------------------*/
|
||||
lsf_max = round_fx(L_sub(L_shr(L_mult0(extract_l(L_shr(fs,1)), 1311),9-16), L_deposit_h(min_dist))); /* Q0 + Q9 , 1311 is 2.56 in Q9 */
|
||||
n_m_1 = sub(n,1);
|
||||
IF (sub(lsf[n_m_1], lsf_max) > 0) /* If danger of unstable filter in case of resonance in HF */
|
||||
{
|
||||
FOR (i = n_m_1; i >= 0; i--) /* Reverify the minimum LSF gap in the reverse direction */
|
||||
{
|
||||
if (sub(lsf[i], lsf_max) > 0)
|
||||
{
|
||||
lsf[i] = lsf_max;
|
||||
move16();
|
||||
}
|
||||
lsf_max = sub(lsf[i], min_dist);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* E_LPC_f_lsp_pol_get
|
||||
*
|
||||
* Parameters:
|
||||
* lsp/isp I: Line spectral pairs (cosine domaine) Q15
|
||||
* f O: the coefficients of F1 or F2 Q23
|
||||
* n I: no of coefficients (m/2)
|
||||
* == NC for F1(z); == NC-1 for F2(z)
|
||||
* fact I: scaling factor
|
||||
*
|
||||
*-----------------------------------------------------------*
|
||||
* procedure E_LPC_f_lsp_pol_get: *
|
||||
* ~~~~~~~~~~~ *
|
||||
* Find the polynomial F1(z) or F2(z) from the LSPs. *
|
||||
* This is performed by expanding the product polynomials: *
|
||||
* *
|
||||
* F1(z) = product ( 1 - 2 LSF_i z^-1 + z^-2 ) *
|
||||
* i=0,2,4,6,8 *
|
||||
* F2(z) = product ( 1 - 2 LSF_i z^-1 + z^-2 ) *
|
||||
* i=1,3,5,7,9 *
|
||||
* *
|
||||
* where LSP_i are the LSPs in the cosine domain. *
|
||||
* *
|
||||
*-----------------------------------------------------------*
|
||||
* R.A.Salami October 1990 *
|
||||
*-----------------------------------------------------------*
|
||||
*/
|
||||
static
|
||||
Word16 E_LPC_f_lsp_pol_get(const Word16 lsp[], Word32 f[], const Word16 n, const Word16 past_Ovf, const Word16 isMODE1)
|
||||
{
|
||||
/* All computation in Q23 */
|
||||
const Word16 *plsp;
|
||||
Word16 i, j;
|
||||
Word16 b;
|
||||
Word32 b32;
|
||||
Word16 Ovf = 0;
|
||||
Word16 Q_out;
|
||||
Word16 m2;
|
||||
|
||||
|
||||
Q_out = 31-23;
|
||||
move16();
|
||||
Ovf = past_Ovf;
|
||||
move16();
|
||||
|
||||
test();
|
||||
if(past_Ovf && isMODE1) /* Currently this feature is implemented only in MODE1 */
|
||||
{
|
||||
/* In some NB cases, overflow where detectected
|
||||
in f1 or f2 polynomial computation when it
|
||||
happen we reduce the precision of the computing
|
||||
to limit the risk of saturation*/
|
||||
Q_out = add(Q_out, past_Ovf);
|
||||
}
|
||||
Overflow = 0;
|
||||
move16();
|
||||
plsp = lsp;
|
||||
f[0] = L_shl(1, sub(31, Q_out));
|
||||
move32();
|
||||
/*b = -2.0f * *plsp;*/
|
||||
b = *plsp;
|
||||
move16();
|
||||
m2 = shl(-2, sub(15, Q_out));
|
||||
f[1] = L_mult(b, m2);
|
||||
move32();
|
||||
|
||||
FOR (i = 2; i <= n; i++)
|
||||
{
|
||||
plsp += 2;
|
||||
/*b = 2.0f * *plsp;*/
|
||||
move16();
|
||||
b = *plsp;
|
||||
b32 = L_mult(b, m2);
|
||||
|
||||
/*f[i] = -b*f[i-1] + 2.0f*f[i-2];*/
|
||||
move32();
|
||||
f[i] = L_shl(L_sub(f[i-2], Mpy_32_16(f[i-1], b)),1);
|
||||
|
||||
FOR (j = i-1; j > 1; j--)
|
||||
{
|
||||
/*f[j] += b*f[j-1] + f[j-2];*/
|
||||
move32();
|
||||
f[j] = L_add(f[j], L_sub(f[j-2], L_shl(Mpy_32_16(f[j-1], b),1)));
|
||||
}
|
||||
move32();
|
||||
f[1] = L_add(f[1], b32);
|
||||
}
|
||||
|
||||
|
||||
test();
|
||||
IF (Overflow>0 && isMODE1)
|
||||
{
|
||||
/* If an overflow is detected, redo the computation with 1 bit less */
|
||||
Ovf = add(Ovf,1);
|
||||
Ovf = E_LPC_f_lsp_pol_get(lsp, f, n ,Ovf, isMODE1);
|
||||
}
|
||||
return Ovf;
|
||||
}
|
||||
32
src/libs/libevs/lib_com/basop_mpy.cpp
Executable file → Normal file
32
src/libs/libevs/lib_com/basop_mpy.cpp
Executable file → Normal file
@@ -1,10 +1,10 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
EVS Codec 3GPP TS26.443 Nov 13, 2018. Version 12.11.0 / 13.7.0 / 14.3.0 / 15.1.0
|
||||
====================================================================================*/
|
||||
|
||||
|
||||
#include "basop_mpy.h"
|
||||
#include "stl.h"
|
||||
#include "options.h" /* Needed for Stack Counting Mechanism Macros (when Instrumented) */
|
||||
#include "options.h"
|
||||
|
||||
Word32 Mpy_32_16_1(Word32 x, Word16 y)
|
||||
{
|
||||
@@ -16,6 +16,16 @@ Word32 Mpy_32_16_1(Word32 x, Word16 y)
|
||||
return (mh);
|
||||
}
|
||||
|
||||
Word32 Mpy_32_16(Word32 x, Word16 y)
|
||||
{
|
||||
Word32 mh;
|
||||
UWord16 ml;
|
||||
|
||||
Mpy_32_16_ss(x, y, &mh, &ml);
|
||||
|
||||
return (mh);
|
||||
}
|
||||
|
||||
Word32 Mpy_32_16_r(Word32 x, Word16 y)
|
||||
{
|
||||
Word32 mh;
|
||||
@@ -31,6 +41,7 @@ Word32 Mpy_32_16_r(Word32 x, Word16 y)
|
||||
return (mh);
|
||||
}
|
||||
|
||||
|
||||
Word32 Mpy_32_32(Word32 x, Word32 y)
|
||||
{
|
||||
Word32 mh;
|
||||
@@ -41,18 +52,3 @@ Word32 Mpy_32_32(Word32 x, Word32 y)
|
||||
return (mh);
|
||||
}
|
||||
|
||||
Word32 Mpy_32_32_r(Word32 x, Word32 y)
|
||||
{
|
||||
Word32 mh;
|
||||
UWord32 ml;
|
||||
|
||||
Mpy_32_32_ss(x, y, &mh, &ml);
|
||||
|
||||
if(L_and(ml, 0x80000000))
|
||||
{
|
||||
mh = L_add(mh, 1);
|
||||
}
|
||||
|
||||
return (mh);
|
||||
}
|
||||
|
||||
|
||||
79
src/libs/libevs/lib_com/basop_mpy.h
Executable file → Normal file
79
src/libs/libevs/lib_com/basop_mpy.h
Executable file → Normal file
@@ -1,5 +1,5 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
EVS Codec 3GPP TS26.443 Nov 13, 2018. Version 12.11.0 / 13.7.0 / 14.3.0 / 15.1.0
|
||||
====================================================================================*/
|
||||
|
||||
#ifndef __BASOP_MPY_H
|
||||
@@ -9,7 +9,7 @@
|
||||
#include "options.h"
|
||||
|
||||
/**
|
||||
* \brief 32*16 Bit fractional Multiplication using 40 bit OPS
|
||||
* \brief 32*16 Bit fractional Multiplication using 40 bit OPS
|
||||
* Performs a multiplication of a 32-bit variable x by
|
||||
* a 16-bit variable y, returning a 32-bit value.
|
||||
*
|
||||
@@ -21,18 +21,33 @@
|
||||
Word32 Mpy_32_16_1(Word32 x,
|
||||
Word16 y);
|
||||
|
||||
|
||||
/**
|
||||
* \brief 32*16 Bit fractional Multiplication using 40 bit OPS
|
||||
* Performs a multiplication of a 32-bit variable x by
|
||||
* a 16-bit variable y incl. rounding, returning a 32-bit value.
|
||||
* a 16-bit variable y, returning a 32-bit value.
|
||||
*
|
||||
* \param[i] x
|
||||
* \param[i] y
|
||||
*
|
||||
* \return x*y
|
||||
*/
|
||||
Word32 Mpy_32_16_r(Word32 x,
|
||||
Word16 y);
|
||||
Word32 Mpy_32_16(Word32 x,
|
||||
Word16 y);
|
||||
|
||||
|
||||
/**
|
||||
* \brief 32*16 Bit fractional Multiplication using 40 bit OPS
|
||||
* Performs a multiplication of a 32-bit variable x by
|
||||
* a 16-bit variable y including rounding, returning a 32-bit value.
|
||||
*
|
||||
* \param[i] x
|
||||
* \param[i] y
|
||||
*
|
||||
* \return x*y
|
||||
*/
|
||||
Word32 Mpy_32_16_r(Word32 x, Word16 y);
|
||||
|
||||
|
||||
/**
|
||||
* \brief 32*32 Bit fractional Multiplication using 40 bit OPS
|
||||
@@ -45,60 +60,8 @@ Word32 Mpy_32_16_r(Word32 x,
|
||||
*
|
||||
* \return x*y
|
||||
*/
|
||||
|
||||
Word32 Mpy_32_32(Word32 x,
|
||||
Word32 y);
|
||||
|
||||
/**
|
||||
* \brief 32*32 Bit fractional Multiplication using 40 bit OPS including rounding
|
||||
*
|
||||
* Performs a multiplication of a 32-bit variable x by
|
||||
* a 32-bit variable y, returning a 32-bit value.
|
||||
*
|
||||
* \param[i] x
|
||||
* \param[i] y
|
||||
*
|
||||
* \return x*y
|
||||
*/
|
||||
Word32 Mpy_32_32_r(Word32 x, Word32 y);
|
||||
|
||||
/**
|
||||
* \brief 32*16 Bit integer Multiplication using 40 bit OPS
|
||||
*
|
||||
* Performs a multiplication of a 32-bit variable x by
|
||||
* a 16-bit variable y, returning a 32-bit value.
|
||||
*
|
||||
* \param[i] x
|
||||
* \param[i] y
|
||||
*
|
||||
* \return x*y
|
||||
*/
|
||||
Word32 Mpy_32_16_2(Word32 x,
|
||||
Word16 y);
|
||||
|
||||
|
||||
/**
|
||||
* \brief 32*16 Bit complex fractional multiplication using 40 Bit and 32 Bit operators
|
||||
*
|
||||
* The function mixes 40 Bit and 32 Bit operators, thus it must not be applied
|
||||
* inside of loops where 32 and 16 bit operators are used.
|
||||
*
|
||||
* \param[i] c_Re
|
||||
* \param[i] c_Im
|
||||
* \param[i] a_Re
|
||||
* \param[i] a_Im
|
||||
* \param[i] b_Re
|
||||
* \param[i] b_Im
|
||||
*
|
||||
* \return none
|
||||
*/
|
||||
void cplxMpy_32_16(Word32 *c_Re,
|
||||
Word32 *c_Im,
|
||||
const Word32 a_Re,
|
||||
const Word32 a_Im,
|
||||
const Word16 b_Re,
|
||||
const Word16 b_Im
|
||||
);
|
||||
|
||||
#define MUL_F(A,B) Mpy_32_16_1((A),(B))
|
||||
|
||||
#endif /* __BASOP_SETTINGS_H */
|
||||
|
||||
39
src/libs/libevs/lib_com/basop_proto_func.h
Normal file
39
src/libs/libevs/lib_com/basop_proto_func.h
Normal file
@@ -0,0 +1,39 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.443 Nov 13, 2018. Version 12.11.0 / 13.7.0 / 14.3.0 / 15.1.0
|
||||
====================================================================================*/
|
||||
|
||||
#ifndef BASOP_PROTO_FUNC_H
|
||||
#define BASOP_PROTO_FUNC_H
|
||||
|
||||
#include "stl.h"
|
||||
#include "basop_util.h"
|
||||
|
||||
|
||||
/* tcx_lpc_cdk.h */
|
||||
#define LSF_GAP_VAL(x) (Word16)((x)*2.0f*1.28f)
|
||||
#define LSFM(x) FL2WORD16_SCALE(x*1.28, 15-1) /* 14Q1*1.28 */
|
||||
|
||||
/* cnst.h */
|
||||
#define GAMMA1_INV 17809 /* weighting factor (numerator) default:0.92 (1Q14format) */
|
||||
#define GAMMA16k_INV 17430 /* weighting factor (numerator) default:0.94 (1Q14format) */
|
||||
#define FS_2 16384 /* isf max value (Use in reorder_fx.c) */
|
||||
#define INT_FS_FX 12800 /* internal sampling frequency */
|
||||
|
||||
void basop_lsp2a_stab(const Word16 *lsp, Word16 *a);
|
||||
void basop_lsf2lsp(const Word16 lsf[], Word16 lsp[]);
|
||||
void basop_weight_a(const Word16 *a, Word16 *ap, const Word16 gamma);
|
||||
void basop_weight_a_inv(const Word16 *a, Word16 *ap, const Word16 inv_gamma);
|
||||
void basop_E_LPC_a_add_tilt(const Word16 *a, Word16 *ap, Word16 gamma);
|
||||
void basop_reorder_lsf(Word16 *lsf, const Word16 min_dist, const Word16 n, const Word32 fs);
|
||||
void basop_E_LPC_f_lsp_a_conversion(const Word16 *lsp, Word16 *a, const Word16 m);
|
||||
|
||||
/* tcx_utils.c */
|
||||
void basop_lpc2mdct(Word16 *lpcCoeffs, Word16 lpcOrder,
|
||||
Word16 *mdct_gains, Word16 *mdct_gains_exp,
|
||||
Word16 *mdct_inv_gains, Word16 *mdct_inv_gains_exp);
|
||||
|
||||
void basop_PsychAdaptLowFreqDeemph(Word32 x[], const Word16 lpcGains[], const Word16 lpcGains_e[], Word16 lf_deemph_factors[]);
|
||||
void basop_mdct_noiseShaping_interp(Word32 x[], Word16 lg, Word16 gains[], Word16 gains_exp[]);
|
||||
|
||||
|
||||
#endif
|
||||
85
src/libs/libevs/lib_com/basop_settings.h
Normal file
85
src/libs/libevs/lib_com/basop_settings.h
Normal file
@@ -0,0 +1,85 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.443 Nov 13, 2018. Version 12.11.0 / 13.7.0 / 14.3.0 / 15.1.0
|
||||
====================================================================================*/
|
||||
|
||||
#ifndef __BASOP_SETTINGS_H
|
||||
#define __BASOP_SETTINGS_H
|
||||
|
||||
#include "stl.h"
|
||||
#include "basop_mpy.h"
|
||||
|
||||
#define _LONG long
|
||||
#define _SHORT short
|
||||
#ifdef _WIN32
|
||||
#define _INT64 __int64
|
||||
#else
|
||||
#define _INT64 long long
|
||||
#endif
|
||||
|
||||
#define WORD32_BITS 32
|
||||
#define MAXVAL_WORD32 ((signed)0x7FFFFFFF)
|
||||
#define MINVAL_WORD32 ((signed)0x80000000)
|
||||
#define WORD32_FIX_SCALE ((_INT64)(1)<<(WORD32_BITS-1))
|
||||
|
||||
#define WORD16_BITS 16
|
||||
#define MAXVAL_WORD16 (((signed)0x7FFFFFFF)>>16)
|
||||
#define MINVAL_WORD16 (((signed)0x80000000)>>16)
|
||||
#define WORD16_FIX_SCALE ((_INT64)(1)<<(WORD16_BITS-1))
|
||||
|
||||
/*!
|
||||
\def Macro converts a float < 1 to Word32 fixed point with saturation and rounding
|
||||
*/
|
||||
#define FL2WORD32(val) \
|
||||
(Word32)( ( (val) >= 0) ? \
|
||||
((( (double)(val) * (WORD32_FIX_SCALE) + 0.5 ) >= (double)(MAXVAL_WORD32) ) ? (_LONG)(MAXVAL_WORD32) : (_LONG)( (double)(val) * (double)(WORD32_FIX_SCALE) + 0.5)) : \
|
||||
((( (double)(val) * (WORD32_FIX_SCALE) - 0.5) <= (double)(MINVAL_WORD32) ) ? (_LONG)(MINVAL_WORD32) : (_LONG)( (double)(val) * (double)(WORD32_FIX_SCALE) - 0.5)) )
|
||||
|
||||
/*!
|
||||
\def Macro converts a float < 1 to Word16 fixed point with saturation and rounding
|
||||
*/
|
||||
#define FL2WORD16(val) \
|
||||
(Word16)( ( (val) >= 0) ? \
|
||||
((( (double)(val) * (WORD16_FIX_SCALE) + 0.5 ) >= (double)(MAXVAL_WORD16) ) ? (_LONG)(MAXVAL_WORD16) : (_LONG)( (double)(val) * (double)(WORD16_FIX_SCALE) + 0.5)) : \
|
||||
((( (double)(val) * (WORD16_FIX_SCALE) - 0.5) <= (double)(MINVAL_WORD16) ) ? (_LONG)(MINVAL_WORD16) : (_LONG)( (double)(val) * (double)(WORD16_FIX_SCALE) - 0.5)) )
|
||||
|
||||
/*!
|
||||
\def Macro converts a Word32 fixed point to Word16 fixed point <1 with saturation
|
||||
*/
|
||||
#define WORD322WORD16(val) \
|
||||
( ( ((((val) >> (WORD32_BITS-WORD16_BITS-1)) + 1) > (((_LONG)1<<WORD16_BITS)-1)) && ((_LONG)(val) > 0) ) ? \
|
||||
(Word16)(_SHORT)(((_LONG)1<<(WORD16_BITS-1))-1):(Word16)(_SHORT)((((val) >> (WORD32_BITS-WORD16_BITS-1)) + 1) >> 1) )
|
||||
|
||||
/*!
|
||||
\def Macro converts a Word32 fixed point < 1 to float shifts result left by scale
|
||||
*/
|
||||
#define WORD322FL_SCALE(x,scale) ( ((float)((_LONG)(x))) / (((_INT64)1<<(WORD32_BITS-1 - (scale)))) )
|
||||
|
||||
/*!
|
||||
\def Macro converts a float < 1 to Word32 fixed point with saturation and rounding, shifts result right by scale
|
||||
*/
|
||||
/* Note: Both x and scale must be constants at compile time, scale must be in range -31..31 */
|
||||
#define FL2WORD32_SCALE(x,scale) FL2WORD32((double)(x) *(((_INT64)1<<(WORD32_BITS-1 - (scale)))) / ((_INT64)1<<(WORD32_BITS-1)))
|
||||
|
||||
/*!
|
||||
\def Macro converts a Word16 fixed point < 1 to float shifts result left by scale
|
||||
*/
|
||||
#define WORD162FL_SCALE(x,scale) ( ((float)((_LONG)(x))) / (((_INT64)1<<(WORD16_BITS-1 - (scale)))) )
|
||||
|
||||
/*!
|
||||
\def Macro converts a float < 1 to Word16 fixed point with saturation and rounding, shifts result right by scale
|
||||
*/
|
||||
/* Note: At compile time, x must be a float constant and scale must be an integer constant in range -15..15 */
|
||||
#define FL2WORD16_SCALE(x,scale) FL2WORD16((float)(x) *(((_INT64)1<<(WORD16_BITS-1 - (scale)))) / ((_INT64)1<<(WORD16_BITS-1)))
|
||||
|
||||
|
||||
/* Word16 Packed Type */
|
||||
typedef struct
|
||||
{
|
||||
struct
|
||||
{
|
||||
Word16 re;
|
||||
Word16 im;
|
||||
} v;
|
||||
} PWord16;
|
||||
|
||||
#endif /* __BASOP_SETTINGS_H */
|
||||
407
src/libs/libevs/lib_com/basop_tcx_utils.cpp
Normal file
407
src/libs/libevs/lib_com/basop_tcx_utils.cpp
Normal file
@@ -0,0 +1,407 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.443 Nov 13, 2018. Version 12.11.0 / 13.7.0 / 14.3.0 / 15.1.0
|
||||
====================================================================================*/
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include "options.h"
|
||||
#include "cnst.h"
|
||||
#include "basop_proto_func.h"
|
||||
#include "stl.h"
|
||||
#include "prot.h"
|
||||
#include "rom_com.h"
|
||||
|
||||
/* compare two positive normalized 16 bit mantissa/exponent values */
|
||||
/* return value: positive if first value greater, negative if second value greater, zero if equal */
|
||||
static Word16 compMantExp16Unorm(Word16 m1, Word16 e1, Word16 m2, Word16 e2)
|
||||
{
|
||||
Word16 tmp;
|
||||
|
||||
assert((m1 >= 0x4000) && (m2 >= 0x4000)); /* comparisons below work only for normalized mantissas */
|
||||
|
||||
tmp = sub(e1, e2);
|
||||
if (tmp == 0) tmp = sub(m1, m2);
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
void basop_lpc2mdct(Word16 *lpcCoeffs, Word16 lpcOrder,
|
||||
Word16 *mdct_gains, Word16 *mdct_gains_exp,
|
||||
Word16 *mdct_inv_gains, Word16 *mdct_inv_gains_exp)
|
||||
{
|
||||
Word32 RealData[FDNS_NPTS];
|
||||
Word32 ImagData[FDNS_NPTS];
|
||||
Word16 i, j, k, step, scale, s, tmp16;
|
||||
Word16 g, g_e, ig, ig_e;
|
||||
Word32 tmp32;
|
||||
const PWord16 *ptwiddle;
|
||||
|
||||
|
||||
|
||||
/* short-cut, to avoid calling of BASOP_getTables() */
|
||||
ptwiddle = SineTable512_fx;
|
||||
step = 8;
|
||||
|
||||
/*ODFT*/
|
||||
assert(lpcOrder < FDNS_NPTS);
|
||||
|
||||
/* pre-twiddle */
|
||||
FOR (i=0; i<=lpcOrder; i++)
|
||||
{
|
||||
RealData[i] = L_mult(lpcCoeffs[i], ptwiddle->v.re);
|
||||
move32();
|
||||
ImagData[i] = L_negate(L_mult(lpcCoeffs[i], ptwiddle->v.im));
|
||||
move32();
|
||||
ptwiddle += step;
|
||||
}
|
||||
|
||||
/* zero padding */
|
||||
FOR ( ; i<FDNS_NPTS; i++)
|
||||
{
|
||||
RealData[i] = 0;
|
||||
move32();
|
||||
ImagData[i] = 0;
|
||||
move32();
|
||||
}
|
||||
|
||||
/* half length FFT */
|
||||
scale = add(norm_s(lpcCoeffs[0]),1);
|
||||
move16();
|
||||
BASOP_cfft( RealData, ImagData, 1, &scale ); /* sizeOfFft == FDNS_NPTS == 8 */
|
||||
|
||||
|
||||
/*Get amplitude*/
|
||||
j = FDNS_NPTS - 1;
|
||||
k = 0;
|
||||
move16();
|
||||
|
||||
FOR (i=0; i<FDNS_NPTS/2; i++)
|
||||
{
|
||||
s = sub(norm_l(L_max(L_abs(RealData[i]), L_abs(ImagData[i]))), 1);
|
||||
|
||||
tmp16 = extract_h(L_shl(RealData[i], s));
|
||||
tmp32 = L_mult(tmp16, tmp16);
|
||||
|
||||
tmp16 = extract_h(L_shl(ImagData[i], s));
|
||||
tmp16 = mac_r(tmp32, tmp16, tmp16);
|
||||
|
||||
s = shl(sub(scale, s), 1);
|
||||
|
||||
if (tmp16 == 0)
|
||||
{
|
||||
s = -16;
|
||||
move16();
|
||||
}
|
||||
if (tmp16 == 0)
|
||||
{
|
||||
tmp16 = 1;
|
||||
move16();
|
||||
}
|
||||
|
||||
BASOP_Util_Sqrt_InvSqrt_MantExp(tmp16, s, &g, &g_e, &ig, &ig_e);
|
||||
|
||||
if (mdct_gains != 0)
|
||||
{
|
||||
mdct_gains[k] = g;
|
||||
move16();
|
||||
}
|
||||
|
||||
if (mdct_gains_exp != 0)
|
||||
{
|
||||
mdct_gains_exp[k] = g_e;
|
||||
move16();
|
||||
}
|
||||
|
||||
if (mdct_inv_gains != 0)
|
||||
{
|
||||
mdct_inv_gains[k] = ig;
|
||||
move16();
|
||||
}
|
||||
|
||||
if (mdct_inv_gains_exp != 0)
|
||||
{
|
||||
mdct_inv_gains_exp[k] = ig_e;
|
||||
move16();
|
||||
}
|
||||
|
||||
k = add(k, 1);
|
||||
|
||||
|
||||
s = sub(norm_l(L_max(L_abs(RealData[j]), L_abs(ImagData[j]))), 1);
|
||||
|
||||
tmp16 = extract_h(L_shl(RealData[j], s));
|
||||
tmp32 = L_mult(tmp16, tmp16);
|
||||
|
||||
tmp16 = extract_h(L_shl(ImagData[j], s));
|
||||
tmp16 = mac_r(tmp32, tmp16, tmp16);
|
||||
|
||||
s = shl(sub(scale, s), 1);
|
||||
|
||||
if (tmp16 == 0)
|
||||
{
|
||||
s = -16;
|
||||
move16();
|
||||
}
|
||||
if (tmp16 == 0)
|
||||
{
|
||||
tmp16 = 1;
|
||||
move16();
|
||||
}
|
||||
|
||||
BASOP_Util_Sqrt_InvSqrt_MantExp(tmp16, s, &g, &g_e, &ig, &ig_e);
|
||||
|
||||
if (mdct_gains != 0)
|
||||
{
|
||||
mdct_gains[k] = g;
|
||||
move16();
|
||||
}
|
||||
|
||||
if (mdct_gains_exp != 0)
|
||||
{
|
||||
mdct_gains_exp[k] = g_e;
|
||||
move16();
|
||||
}
|
||||
|
||||
if (mdct_inv_gains != 0)
|
||||
{
|
||||
mdct_inv_gains[k] = ig;
|
||||
move16();
|
||||
}
|
||||
|
||||
if (mdct_inv_gains_exp != 0)
|
||||
{
|
||||
mdct_inv_gains_exp[k] = ig_e;
|
||||
move16();
|
||||
}
|
||||
|
||||
j = sub(j, 1);
|
||||
k = add(k, 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void basop_mdct_noiseShaping_interp(Word32 x[], Word16 lg, Word16 gains[], Word16 gains_exp[])
|
||||
{
|
||||
Word16 i, j, jp, jn, k, l;
|
||||
Word16 g, pg, ng, e, tmp;
|
||||
|
||||
|
||||
assert(lg % FDNS_NPTS == 0);
|
||||
k = shr(lg, 6); /* FDNS_NPTS = 64 */
|
||||
|
||||
IF (gains)
|
||||
{
|
||||
/* Linear interpolation */
|
||||
IF (sub(k, 4) == 0)
|
||||
{
|
||||
jp = 0;
|
||||
move16();
|
||||
j = 0;
|
||||
move16();
|
||||
jn = 1;
|
||||
move16();
|
||||
|
||||
FOR (i = 0; i < lg; i += 4)
|
||||
{
|
||||
pg = gains[jp];
|
||||
move16();
|
||||
g = gains[j];
|
||||
move16();
|
||||
ng = gains[jn];
|
||||
move16();
|
||||
|
||||
/* common exponent for pg and g */
|
||||
tmp = sub(gains_exp[j], gains_exp[jp]);
|
||||
if (tmp > 0) pg = shr(pg, tmp);
|
||||
if (tmp < 0) g = shl(g, tmp);
|
||||
e = s_max(gains_exp[j], gains_exp[jp]);
|
||||
|
||||
tmp = mac_r(L_mult(pg, FL2WORD16(0.375f)), g, FL2WORD16(0.625f));
|
||||
x[i] = L_shl(Mpy_32_16(x[i], tmp), e);
|
||||
move32();
|
||||
|
||||
tmp = mac_r(L_mult(pg, FL2WORD16(0.125f)), g, FL2WORD16(0.875f));
|
||||
x[i+1] = L_shl(Mpy_32_16(x[i+1], tmp), e);
|
||||
move32();
|
||||
|
||||
/* common exponent for g and ng */
|
||||
g = gains[j];
|
||||
move16();
|
||||
tmp = sub(gains_exp[j], gains_exp[jn]);
|
||||
if (tmp > 0) ng = shr(ng, tmp);
|
||||
if (tmp < 0) g = shl(g, tmp);
|
||||
e = s_max(gains_exp[j], gains_exp[jn]);
|
||||
|
||||
tmp = mac_r(L_mult(g, FL2WORD16(0.875f)), ng, FL2WORD16(0.125f));
|
||||
x[i+2] = L_shl(Mpy_32_16(x[i+2], tmp), e);
|
||||
move32();
|
||||
|
||||
tmp = mac_r(L_mult(g, FL2WORD16(0.625f)), ng, FL2WORD16(0.375f));
|
||||
x[i+3] = L_shl(Mpy_32_16(x[i+3], tmp), e);
|
||||
move32();
|
||||
|
||||
jp = j;
|
||||
move16();
|
||||
j = jn;
|
||||
move16();
|
||||
jn = s_min(add(jn, 1), FDNS_NPTS-1);
|
||||
}
|
||||
}
|
||||
ELSE IF (sub(k, 5) == 0)
|
||||
{
|
||||
jp = 0;
|
||||
move16();
|
||||
j = 0;
|
||||
move16();
|
||||
jn = 1;
|
||||
move16();
|
||||
|
||||
FOR (i = 0; i < lg; i += 5)
|
||||
{
|
||||
pg = gains[jp];
|
||||
move16();
|
||||
g = gains[j];
|
||||
move16();
|
||||
ng = gains[jn];
|
||||
move16();
|
||||
|
||||
/* common exponent for pg and g */
|
||||
tmp = sub(gains_exp[j], gains_exp[jp]);
|
||||
if (tmp > 0) pg = shr(pg, tmp);
|
||||
if (tmp < 0) g = shl(g, tmp);
|
||||
e = s_max(gains_exp[j], gains_exp[jp]);
|
||||
|
||||
tmp = mac_r(L_mult(pg, FL2WORD16(0.40f)), g, FL2WORD16(0.60f));
|
||||
x[i] = L_shl(Mpy_32_16(x[i], tmp), e);
|
||||
move32();
|
||||
|
||||
tmp = mac_r(L_mult(pg, FL2WORD16(0.20f)), g, FL2WORD16(0.80f));
|
||||
x[i+1] = L_shl(Mpy_32_16(x[i+1], tmp), e);
|
||||
move32();
|
||||
|
||||
|
||||
x[i+2] = L_shl(Mpy_32_16(x[i+2], gains[j]), gains_exp[j]);
|
||||
move32();
|
||||
|
||||
/* common exponent for g and ng */
|
||||
g = gains[j];
|
||||
move16();
|
||||
tmp = sub(gains_exp[j], gains_exp[jn]);
|
||||
if (tmp > 0) ng = shr(ng, tmp);
|
||||
if (tmp < 0) g = shl(g, tmp);
|
||||
e = s_max(gains_exp[j], gains_exp[jn]);
|
||||
|
||||
tmp = mac_r(L_mult(g, FL2WORD16(0.80f)), ng, FL2WORD16(0.20f));
|
||||
x[i+3] = L_shl(Mpy_32_16(x[i+3], tmp), e);
|
||||
move32();
|
||||
|
||||
tmp = mac_r(L_mult(g, FL2WORD16(0.60f)), ng, FL2WORD16(0.40f));
|
||||
x[i+4] = L_shl(Mpy_32_16(x[i+4], tmp), e);
|
||||
move32();
|
||||
|
||||
jp = j;
|
||||
move16();
|
||||
j = jn;
|
||||
move16();
|
||||
jn = s_min(add(jn, 1), FDNS_NPTS-1);
|
||||
}
|
||||
}
|
||||
ELSE /* no interpolation */
|
||||
{
|
||||
FOR (i = 0; i < FDNS_NPTS; i++)
|
||||
{
|
||||
FOR (l = 0; l < k; l++)
|
||||
{
|
||||
*x = L_shl(Mpy_32_16(*x, *gains), *gains_exp);
|
||||
move32();
|
||||
x++;
|
||||
}
|
||||
|
||||
gains++;
|
||||
gains_exp++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void basop_PsychAdaptLowFreqDeemph(Word32 x[],
|
||||
const Word16 lpcGains[], const Word16 lpcGains_e[],
|
||||
Word16 lf_deemph_factors[]
|
||||
)
|
||||
{
|
||||
Word16 i;
|
||||
Word16 max, max_e, fac, min, min_e, tmp, tmp_e;
|
||||
Word32 L_tmp;
|
||||
|
||||
|
||||
|
||||
assert(lpcGains[0] >= 0x4000);
|
||||
|
||||
max = lpcGains[0];
|
||||
move16();
|
||||
max_e = lpcGains_e[0];
|
||||
move16();
|
||||
min = lpcGains[0];
|
||||
move16();
|
||||
min_e = lpcGains_e[0];
|
||||
move16();
|
||||
|
||||
/* find minimum (min) and maximum (max) of LPC gains in low frequencies */
|
||||
FOR (i = 1; i < 9; i++)
|
||||
{
|
||||
IF (compMantExp16Unorm(lpcGains[i], lpcGains_e[i], min, min_e) < 0)
|
||||
{
|
||||
min = lpcGains[i];
|
||||
move16();
|
||||
min_e = lpcGains_e[i];
|
||||
move16();
|
||||
}
|
||||
|
||||
IF (compMantExp16Unorm(lpcGains[i], lpcGains_e[i], max, max_e) > 0)
|
||||
{
|
||||
max = lpcGains[i];
|
||||
move16();
|
||||
max_e = lpcGains_e[i];
|
||||
move16();
|
||||
}
|
||||
}
|
||||
|
||||
min_e = add(min_e, 5); /* min *= 32.0f; */
|
||||
|
||||
test();
|
||||
IF ((compMantExp16Unorm(max, max_e, min, min_e) < 0) && (min > 0))
|
||||
{
|
||||
/* fac = tmp = (float)pow(max / min, 0.0078125f); */
|
||||
tmp_e = min_e;
|
||||
move16();
|
||||
tmp = Inv16(min, &tmp_e);
|
||||
L_tmp = L_shl(L_mult(tmp, max), add(tmp_e, max_e)); /* Q31 */
|
||||
L_tmp = BASOP_Util_Log2(L_tmp); /* Q25 */
|
||||
L_tmp = L_shr(L_tmp, 7); /* 0.0078125f = 1.f/(1<<7) */
|
||||
L_tmp = BASOP_Util_InvLog2(L_tmp); /* Q31 */
|
||||
tmp = round_fx(L_tmp); /* Q15 */
|
||||
fac = tmp; /* Q15 */ move16();
|
||||
|
||||
/* gradual lowering of lowest 32 bins; DC is lowered by (max/tmp)^1/4 */
|
||||
FOR (i = 31; i >= 0; i--)
|
||||
{
|
||||
x[i] = Mpy_32_16(x[i], fac);
|
||||
move32();
|
||||
if (lf_deemph_factors != NULL)
|
||||
{
|
||||
lf_deemph_factors[i] = mult_r(lf_deemph_factors[i], fac);
|
||||
move16();
|
||||
}
|
||||
fac = mult_r(fac, tmp);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
1796
src/libs/libevs/lib_com/basop_util.cpp
Executable file → Normal file
1796
src/libs/libevs/lib_com/basop_util.cpp
Executable file → Normal file
File diff suppressed because it is too large
Load Diff
647
src/libs/libevs/lib_com/basop_util.h
Executable file → Normal file
647
src/libs/libevs/lib_com/basop_util.h
Executable file → Normal file
@@ -1,61 +1,27 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
EVS Codec 3GPP TS26.443 Nov 13, 2018. Version 12.11.0 / 13.7.0 / 14.3.0 / 15.1.0
|
||||
====================================================================================*/
|
||||
|
||||
#ifndef __BASOP_UTIL_H__
|
||||
#define __BASOP_UTIL_H__
|
||||
|
||||
#include "stl.h"
|
||||
#include "basop_settings.h"
|
||||
#include "typedef.h"
|
||||
#include "basop32.h"
|
||||
#include "basop_mpy.h"
|
||||
|
||||
|
||||
#define _LONG long
|
||||
#define _SHORT short
|
||||
#ifdef _WIN32
|
||||
#define _INT64 __int64
|
||||
#else
|
||||
#define _INT64 long long
|
||||
#endif
|
||||
|
||||
#define WORD32_BITS 32
|
||||
#define MAXVAL_WORD32 ((signed)0x7FFFFFFF)
|
||||
#define MINVAL_WORD32 ((signed)0x80000000)
|
||||
#define WORD32_FIX_SCALE ((_INT64)(1)<<(WORD32_BITS-1))
|
||||
|
||||
#define WORD16_BITS 16
|
||||
#define MAXVAL_WORD16 (((signed)0x7FFFFFFF)>>16)
|
||||
#define MINVAL_WORD16 (((signed)0x80000000)>>16)
|
||||
#define WORD16_FIX_SCALE ((_INT64)(1)<<(WORD16_BITS-1))
|
||||
|
||||
/*!
|
||||
\def Macro converts a Word32 fixed point to Word16 fixed point <1 with saturation
|
||||
*/
|
||||
#define WORD322WORD16(val) \
|
||||
( ( ((((val) >> (WORD32_BITS-WORD16_BITS-1)) + 1) > (((_LONG)1<<WORD16_BITS)-1)) && ((_LONG)(val) > 0) ) ? \
|
||||
(Word16)(_SHORT)(((_LONG)1<<(WORD16_BITS-1))-1):(Word16)(_SHORT)((((val) >> (WORD32_BITS-WORD16_BITS-1)) + 1) >> 1) )
|
||||
|
||||
|
||||
/* Word16 Packed Type */
|
||||
typedef struct
|
||||
{
|
||||
struct
|
||||
{
|
||||
Word16 re;
|
||||
Word16 im;
|
||||
} v;
|
||||
} PWord16;
|
||||
|
||||
#define cast16 move16
|
||||
|
||||
|
||||
#define LD_DATA_SCALE (6)
|
||||
|
||||
#define LD_DATA_SHIFT_I5 (7)
|
||||
|
||||
#define modDiv2(x) sub(x,shl(shr(x,1),1))
|
||||
#define modDiv8(x) L_sub(x,L_shl(L_shr(x,3),3))
|
||||
|
||||
#ifndef CHEAP_NORM_SIZE
|
||||
#define CHEAP_NORM_SIZE 161
|
||||
#endif
|
||||
|
||||
static __inline Word16 limitScale16( Word16 s)
|
||||
{
|
||||
/* It is assumed, that s is calculated just before, therefore we can switch upon sign */
|
||||
@@ -76,6 +42,7 @@ static __inline Word16 limitScale32( Word16 s)
|
||||
return (s);
|
||||
}
|
||||
|
||||
|
||||
/*!**********************************************************************
|
||||
\brief Add two values given by mantissa and exponent.
|
||||
|
||||
@@ -90,23 +57,7 @@ Word16 BASOP_Util_Add_MantExp /*!< Exponent of result
|
||||
Word16 b_e, /*!< Exponent of 2nd operand b */
|
||||
Word16 *ptrSum_m); /*!< Mantissa of result */
|
||||
|
||||
/************************************************************************/
|
||||
/*!
|
||||
\brief Divide two values given by mantissa and exponent.
|
||||
|
||||
Mantissas are in 16-bit-fractional format with values between 0 and 1. <br>
|
||||
The base for exponents is 2. Example: \f$ a = a\_m * 2^{a\_e} \f$<br>
|
||||
|
||||
For performance reasons, the division is based on a table lookup
|
||||
which limits accuracy.
|
||||
*/
|
||||
void BASOP_Util_Divide_MantExp (Word16 a_m, /*!< Mantissa of dividend a */
|
||||
Word16 a_e, /*!< Exponent of dividend a */
|
||||
Word16 b_m, /*!< Mantissa of divisor b */
|
||||
Word16 b_e, /*!< Exponent of divisor b */
|
||||
Word16 *ptrResult_m, /*!< Mantissa of quotient a/b */
|
||||
Word16 *ptrResult_e /*!< Exponent of quotient a/b */
|
||||
);
|
||||
|
||||
/************************************************************************/
|
||||
/*!
|
||||
@@ -122,60 +73,6 @@ Word16 Sqrt16( /*!< output mantissa */
|
||||
Word16 *exponent /*!< pointer to exponent */
|
||||
);
|
||||
|
||||
Word16 Sqrt16norm( /*!< output mantissa */
|
||||
Word16 mantissa, /*!< normalized input mantissa */
|
||||
Word16 *exponent /*!< pointer to exponent */
|
||||
);
|
||||
|
||||
Word32 Sqrt32( /*!< output mantissa */
|
||||
Word32 mantissa, /*!< input mantissa */
|
||||
Word16 *exponent /*!< pointer to exponent */
|
||||
);
|
||||
|
||||
Word32 Sqrt32norm( /*!< output mantissa */
|
||||
Word32 mantissa, /*!< normalized input mantissa */
|
||||
Word16 *exponent /*!< pointer to exponent */
|
||||
);
|
||||
|
||||
/* deprecated, use Sqrt16! */
|
||||
void BASOP_Util_Sqrt_MantExp (Word16 *mantissa, /*!< Pointer to mantissa */
|
||||
Word16 *exponent /*!< Pointer to exponent */
|
||||
);
|
||||
|
||||
/* deprecated, use Sqrt16norm! */
|
||||
void BASOP_Util_Sqrt_MantExpNorm (Word16 *mantissa, /*!< Pointer to normalized mantissa */
|
||||
Word16 *exponent /*!< Pointer to exponent */
|
||||
);
|
||||
|
||||
/****************************************************************************/
|
||||
/*!
|
||||
\brief Calculate the inverse of the squareroot of a number given by mantissa and exponent
|
||||
|
||||
Mantissa is in 16/32-bit-fractional format with values between 0 and 1. <br>
|
||||
For *norm versions mantissa has to be between 0.5 and 1. <br>
|
||||
The base for the exponent is 2. Example: \f$ a = a\_m * 2^{a\_e} \f$<br>
|
||||
The exponent is addressed via pointers and will be overwritten with the result.
|
||||
*/
|
||||
Word16 ISqrt16( /*!< output mantissa */
|
||||
Word16 mantissa, /*!< input mantissa */
|
||||
Word16 *exponent /*!< pointer to exponent */
|
||||
);
|
||||
|
||||
Word32 ISqrt32( /*!< output mantissa */
|
||||
Word32 mantissa, /*!< input mantissa */
|
||||
Word16 *exponent /*!< pointer to exponent */
|
||||
);
|
||||
|
||||
Word32 ISqrt32norm( /*!< output mantissa */
|
||||
Word32 mantissa, /*!< normalized input mantissa */
|
||||
Word16 *exponent /*!< pointer to exponent */
|
||||
);
|
||||
|
||||
/* deprecated, use ISqrt16! */
|
||||
void BASOP_Util_InvSqrt_MantExp (Word16 *mantissa, /*!< Pointer to mantissa */
|
||||
Word16 *exponent /*!< Pointer to exponent */
|
||||
);
|
||||
|
||||
/*****************************************************************************/
|
||||
/*!
|
||||
\brief Calculate the inverse of a number given by mantissa and exponent
|
||||
@@ -190,6 +87,7 @@ Word16 Inv16( /*!< output mantissa */
|
||||
Word16 mantissa, /*!< input mantissa */
|
||||
Word16 *exponent /*!< pointer to exponent */
|
||||
);
|
||||
|
||||
/******************************************************************************/
|
||||
/*!
|
||||
\brief Calculate the squareroot and inverse of squareroot of a number given by mantissa and exponent
|
||||
@@ -205,19 +103,7 @@ void BASOP_Util_Sqrt_InvSqrt_MantExp (Word16 mantissa, /*!< mantissa */
|
||||
Word16 *isqrt_exp /*!< Pointer to 1/sqrt exponent */
|
||||
);
|
||||
|
||||
/********************************************************************/
|
||||
/*!
|
||||
\brief Calculates the scalefactor needed to normalize input array
|
||||
|
||||
The scalefactor needed to normalize the Word16 input array is returned <br>
|
||||
If the input array contains only '0', a scalefactor 0 is returned <br>
|
||||
Scaling factor is determined wrt a normalized target x: 16384 <= x <= 32767 for positive x <br>
|
||||
and -32768 <= x <= -16384 for negative x
|
||||
*/
|
||||
|
||||
Word16 getScaleFactor16( /* o: measured headroom in range [0..15], 0 if all x[i] == 0 */
|
||||
const Word16 *x, /* i: array containing 16-bit data */
|
||||
const Word16 len_x); /* i: length of the array to scan */
|
||||
|
||||
/********************************************************************/
|
||||
/*!
|
||||
@@ -233,106 +119,17 @@ Word16 getScaleFactor32( /* o: measured headroom in range [0..31
|
||||
const Word32 *x, /* i: array containing 32-bit data */
|
||||
const Word16 len_x); /* i: length of the array to scan */
|
||||
|
||||
/**
|
||||
* \brief normalize mantissa and update the exponent accordingly.
|
||||
* \param mantissa the mantissa to be normalized
|
||||
* \param pexponent pointer to the exponent.
|
||||
* \return the normalized mantissa.
|
||||
/************************************************************************/
|
||||
/*!
|
||||
\brief Binary logarithm with 7 iterations
|
||||
|
||||
\param x
|
||||
|
||||
\return log2(x)/64
|
||||
*/
|
||||
Word16 normalize16(Word16 mantissa, Word16 *pexponent);
|
||||
/****************************************************************************/
|
||||
/*!
|
||||
\brief Does fractional integer division of Word32 arg1 by Word16 arg2
|
||||
/************************************************************************/
|
||||
Word32 BASOP_Util_Log2(Word32 x);
|
||||
|
||||
both input arguments may be positive or negative <br>
|
||||
the result is truncated to Word16
|
||||
|
||||
\return fractional integer Word16 result of arg1/arg2
|
||||
*/
|
||||
Word16 divide3216( Word32 x, /*!< Numerator*/
|
||||
Word16 y); /*!< Denominator*/
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
/*!
|
||||
\brief Does fractional integer division of Word16 arg1 by Word16 arg2
|
||||
|
||||
both input arguments may be positive or negative <br>
|
||||
the result is truncated to Word16
|
||||
|
||||
\return fractional integer Word16 result of arg1/arg2
|
||||
*/
|
||||
Word16 divide1616( Word16 x, /*!< Numerator*/
|
||||
Word16 y); /*!< Denominator*/
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
/*!
|
||||
\brief Does fractional integer division of Word32 arg1 by Word32 arg2
|
||||
|
||||
this function makes both the numerator and the denominator positive integers,
|
||||
and scales up both values to avoid losing the accuracy of the outcome
|
||||
too much
|
||||
|
||||
WARNING: it should be arg1 < arg2 because of the maximum degree of scaling for the mantissa!
|
||||
|
||||
\return fractional Word16 integer z = arg1(32bits)/arg2(32bits)
|
||||
*/
|
||||
Word16 divide3232( Word32 x, /*!< Numerator*/
|
||||
Word32 y); /*!< Denominator*/
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
/*!
|
||||
\brief Does fractional integer division of UWord32 arg1 by UWord32 arg2
|
||||
|
||||
This function ensures both the numerator and the denominator are positive integers,
|
||||
and scales up both values to avoid losing the accuracy of the outcome
|
||||
too much.<br>
|
||||
|
||||
CAUTION: Arg 3 is a Word16 pointer which will point to the scalefactor difference
|
||||
s_diff = sub(s2,s1), where s1 and s2 are the scalefactors of the arguments, which
|
||||
were shifted in order to e.g. preserve accuracy.
|
||||
I.e. the result has to be scaled due to shifting it
|
||||
s_diff to the right to obtain the real result of the division.
|
||||
|
||||
\return fractional Word16 integer z = arg1(32bits)/arg2(32bits)
|
||||
*/
|
||||
Word16 BASOP_Util_Divide3232_uu_1616_Scale( Word32 x, /*!< i : Numerator*/
|
||||
Word32 y, /*!< i : Denominator*/
|
||||
Word16 *s); /*!< o : Additional scalefactor difference*/
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
/*!
|
||||
\brief Does fractional integer division of Word32 arg1 by Word32 arg2
|
||||
|
||||
This function scales up both values to avoid losing the accuracy of the outcome
|
||||
too much.<br>
|
||||
|
||||
CAUTION: Arg 3 is a Word16 pointer which will point to the scalefactor difference
|
||||
s_diff = sub(s2,s1), where s1 and s2 are the scalefactors of the arguments, which
|
||||
were shifted in order to e.g. preserve accuracy.
|
||||
I.e. the result has to be scaled due to shifting it
|
||||
s_diff to the right to obtain the real result of the division.
|
||||
|
||||
\return fractional Word16 integer z = arg1(32bits)/arg2(32bits)
|
||||
*/
|
||||
Word16 BASOP_Util_Divide3232_Scale( Word32 x, /*!< i : Numerator*/
|
||||
Word32 y, /*!< i : Denominator*/
|
||||
Word16 *s); /*!< o : Additional scalefactor difference*/
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
/*!
|
||||
\brief Does fractional integer division of Word32 arg1 by Word16 arg2
|
||||
|
||||
|
||||
\return fractional Word16 integer z = arg1(32bits)/arg2(16bits) , z not normalized
|
||||
*/
|
||||
Word16 BASOP_Util_Divide3216_Scale( Word32 x, /*!< i : Numerator */
|
||||
Word16 y, /*!< i : Denominator*/
|
||||
Word16 *s); /*!< o : Additional scalefactor difference*/
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
@@ -346,17 +143,28 @@ Word16 BASOP_Util_Divide1616_Scale( Word16 x, /*!< i : Numerator*/
|
||||
Word16 y, /*!< i : Denominator*/
|
||||
Word16 *s); /*!< o : Additional scalefactor difference*/
|
||||
|
||||
/****************************************************************************/
|
||||
/*!
|
||||
\brief Does fractional integer division of Word32 arg1 by Word16 arg2
|
||||
|
||||
|
||||
\return fractional Word16 integer z = arg1(32bits)/arg2(16bits) , z not normalized
|
||||
*/
|
||||
Word16 BASOP_Util_Divide3216_Scale( Word32 x, /*!< i : Numerator */
|
||||
Word16 y, /*!< i : Denominator*/
|
||||
Word16 *s); /*!< o : Additional scalefactor difference*/
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/*!
|
||||
\brief Binary logarithm with 7 iterations
|
||||
|
||||
\param x
|
||||
|
||||
\return log2(x)/64
|
||||
* \brief Binary logarithm with 5 iterations
|
||||
*
|
||||
* \param[i] val
|
||||
*
|
||||
* \return basop_log2(val)/128
|
||||
*/
|
||||
/************************************************************************/
|
||||
Word32 BASOP_Util_Log2(Word32 x);
|
||||
|
||||
Word32 BASOP_Util_log2_i5(Word32 val);
|
||||
|
||||
/************************************************************************/
|
||||
/*!
|
||||
@@ -399,49 +207,33 @@ Word32 BASOP_Util_Log2(Word32 x);
|
||||
/************************************************************************/
|
||||
Word32 BASOP_Util_InvLog2(Word32 x);
|
||||
|
||||
Word16 BASOP_util_norm_s_bands2shift (Word16 x);
|
||||
|
||||
/***********************************************************************/
|
||||
/*!
|
||||
\brief Calculate the headroom of the complex data in a 2 dimensional array
|
||||
|
||||
\return number of headroom bits
|
||||
*/
|
||||
Word16 BASOP_util_norm_l_dim2_cplx (const Word32 * const *re, /*!< Real part of 32 Bit input */
|
||||
const Word32 * const *im, /*!< Imag part if 32 Bit input */
|
||||
Word16 startBand, /*!< start band of cplx data */
|
||||
Word16 stopBand, /*!< stop band of cplx data */
|
||||
Word16 startSlot, /*!< start slot of cplx data */
|
||||
Word16 stopSlot /*!< stop slot of cplx data */
|
||||
);
|
||||
/****************************************************************************/
|
||||
/*!
|
||||
\brief Does a data copy of Word8 *arg1 to Word8 *arg2 with Word16 arg3 number of moves
|
||||
\brief Sets Array Word16 arg1 to value Word16 arg2 for Word16 arg3 elements
|
||||
*/
|
||||
void copyWord8( const Word8 *src, /*!< i : Source address */
|
||||
Word8 *dst, /*!< i : Destination address */
|
||||
const Word32 n); /*!< i : Number of elements to copy */
|
||||
void set_val_Word16( Word16 X[], /*!< Address of array */
|
||||
const Word16 val, /*!< Value to copy into array */
|
||||
Word16 n); /*!< Number of elements to process */
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
/*!
|
||||
\brief Sets Word8 array arg1[] to zero for a length of Word16 arg2 elements
|
||||
\brief Sets Array Word32 arg1 to value Word32 arg2 for Word16 arg3 elements
|
||||
*/
|
||||
void set_zero_Word8( Word8 X[], /*!< i : Address of array */
|
||||
Word32 n); /*!< i : Number of elements to set to zero */
|
||||
void set_val_Word32( Word32 X[], /*!< Address of array */
|
||||
const Word32 val, /*!< Value to copy into array */
|
||||
Word16 n); /*!< Number of elements to process */
|
||||
|
||||
/****************************************************************************/
|
||||
/*!
|
||||
\brief Does a multiplication of Word32 * Word16 input values
|
||||
\brief Does a multiplication of Word16 input values
|
||||
|
||||
\return z32 = x32 * y16
|
||||
\return z16 = x16 * y16
|
||||
*/
|
||||
Word32 L_mult0_3216( Word32 x, /*!< : Multiplier */
|
||||
Word16 y); /*!< : Multiplicand */
|
||||
Word16 mult0 ( Word16 x, /*!< i : Multiplier */
|
||||
Word16 y); /*!< i : Multiplicand */
|
||||
|
||||
/* Calculate sin/cos. Angle in 2Q13 format, result has exponent = 1 */
|
||||
Word16 getCosWord16(Word16 theta);
|
||||
Word32 getCosWord32(Word32 theta);
|
||||
/**
|
||||
* \brief calculate cosine of angle. Tuned for ISF domain.
|
||||
* \param theta Angle normalized to radix 2, theta = (angle in radians)*2.0/pi
|
||||
@@ -449,62 +241,6 @@ Word32 getCosWord32(Word32 theta);
|
||||
*/
|
||||
Word16 getCosWord16R2(Word16 theta);
|
||||
|
||||
/****************************************************************************/
|
||||
/*!
|
||||
\brief square root abacus algorithm
|
||||
|
||||
\return integer sqrt(x)
|
||||
*/
|
||||
Word16 getSqrtWord32(Word32 x);
|
||||
|
||||
/****************************************************************************/
|
||||
/*!
|
||||
\brief finds index of min Word16 in array
|
||||
|
||||
\return index of min Word16
|
||||
*/
|
||||
Word16 findIndexOfMinWord16(Word16 *x, const Word16 len);
|
||||
|
||||
/****************************************************************************/
|
||||
/*!
|
||||
\brief finds index of min Word32 in array
|
||||
|
||||
\return index of min Word32
|
||||
*/
|
||||
Word16 findIndexOfMinWord32(Word32 *x, const Word16 len);
|
||||
|
||||
/****************************************************************************/
|
||||
/*!
|
||||
\brief finds index of max Word16 in array
|
||||
|
||||
\return index of max Word16
|
||||
*/
|
||||
Word16 findIndexOfMaxWord16(Word16 *x, const Word16 len);
|
||||
|
||||
/****************************************************************************/
|
||||
/*!
|
||||
\brief finds index of max Word32 in array
|
||||
|
||||
\return index of max Word32
|
||||
*/
|
||||
Word16 findIndexOfMaxWord32(Word32 *x, const Word16 len);
|
||||
|
||||
/****************************************************************************/
|
||||
/*!
|
||||
\brief 16x16->16 integer multiplication without overflow control
|
||||
|
||||
\return 16x16->16 integer
|
||||
*/
|
||||
Word16 imult1616(Word16 x, Word16 y);
|
||||
|
||||
/****************************************************************************/
|
||||
/*!
|
||||
\brief 32x16->32 integer multiplication with overflow control
|
||||
|
||||
\return 32x16->32 integer
|
||||
*/
|
||||
Word32 imult3216(Word32 x, Word16 y);
|
||||
|
||||
/****************************************************************************/
|
||||
/*!
|
||||
\brief 16/16->16 unsigned integer division
|
||||
@@ -516,100 +252,7 @@ Word32 imult3216(Word32 x, Word16 y);
|
||||
|
||||
Word16 idiv1616U(Word16 x, Word16 y);
|
||||
|
||||
/****************************************************************************/
|
||||
/*!
|
||||
\brief 16/16->16 signed integer division
|
||||
|
||||
x and y have to be positive, x has to be < 16384
|
||||
|
||||
\return 16/16->16 integer
|
||||
*/
|
||||
|
||||
Word16 idiv1616(Word16 x, Word16 y);
|
||||
|
||||
/*------------------------------------------------------------------*
|
||||
* Dot_product16HQ:
|
||||
*
|
||||
* \brief Compute scalar product of <x[],y[]> using 64-bit accumulator.
|
||||
*
|
||||
* Performs normalization of the result, returns the exponent
|
||||
* Note: In contrast to dotWord32, no headroom is required for data
|
||||
* in x[] and y[], means, they may have any format Qn
|
||||
*------------------------------------------------------------------*/
|
||||
Word32 Dot_product16HQ( /*<! o : normalized result Q31 */
|
||||
const Word32 L_off, /*<! i : initial sum value Qn */
|
||||
const Word16 x[], /*<! i : x vector Qn */
|
||||
const Word16 y[], /*<! i : y vector Qn */
|
||||
const Word16 lg, /*<! i : vector length, range [0..7FFF] Q0 */
|
||||
Word16 * exp /*<! o : exponent of result in [-32,31] Q0 */
|
||||
);
|
||||
|
||||
|
||||
/*------------------------------------------------------------------*
|
||||
* norm_llQ31:
|
||||
*
|
||||
* \brief Compute normalized Q31 Values out of overflowed Q31 value
|
||||
*
|
||||
* Performs the calculation of a normalized Q31 Value with its
|
||||
* scalingfactor, taking into account the overflowed Q31 input value
|
||||
* and the number of Carrys, collected.
|
||||
*------------------------------------------------------------------*/
|
||||
Word32 norm_llQ31( /* o : normalized result Q31 */
|
||||
Word32 L_c, /* i : upper bits of accu Q-1 */
|
||||
Word32 L_sum, /* i : lower bits of accu, unsigned Q31 */
|
||||
Word16 * exp /* o : exponent of result in [-32,31] Q0 */
|
||||
);
|
||||
|
||||
/**
|
||||
* \brief Compute dot product of 1 32 bit vectors with itself
|
||||
* \param x input vector 1
|
||||
* \param headroom amount of headroom bits the input vector
|
||||
* \param length the length of the input vector
|
||||
* \param result_e pointer to where the exponent of the result will be stored into
|
||||
* \return the dot product of x and x.
|
||||
*/
|
||||
Word32 Norm32Norm(const Word32 *x, const Word16 headroom, const Word16 length, Word16 *result_e);
|
||||
|
||||
|
||||
/*------------------------------------------------------------------*
|
||||
* Dot_productSq16HQ:
|
||||
*
|
||||
* \brief Compute scalar product of <x[],x[]> using 64-bit accumulator.
|
||||
*
|
||||
* Performs normalization of the result, returns the exponent
|
||||
* Note: In contrast to dotWord32, no headroom is required for data
|
||||
* in x[], means, they may have any format Qn
|
||||
*------------------------------------------------------------------*/
|
||||
Word32 Dot_productSq16HQ( /*<! o : normalized result Q31 */
|
||||
const Word32 L_off, /*<! i : initial sum value Qn */
|
||||
const Word16 x[], /*<! i : x vector Qn */
|
||||
const Word16 lg, /*<! i : vector length, range [0..7FFF] Q0 */
|
||||
Word16 * exp /*<! o : exponent of result in [-32,31] Q0 */
|
||||
);
|
||||
|
||||
/*------------------------------------------------------------------*
|
||||
* dotp_s_fx:
|
||||
*
|
||||
* \brief Compute scalar product of <x[],y[]> using 64-bit accumulator.
|
||||
*
|
||||
* Performs no normalization of the result
|
||||
*------------------------------------------------------------------*/
|
||||
Word32 dotp_s_fx( /*<! o : dot product of vector x and y 16Q15 */
|
||||
const Word16 *x, /*<! i : vector x 6Q9 */
|
||||
const Word16 *y, /*<! i : vector y 6Q9 */
|
||||
const Word16 n, /*<! i : vector length Q0 */
|
||||
Word16 s /*<! i : headroom Q0 */
|
||||
);
|
||||
|
||||
/*-------------------------------------------------------------------*
|
||||
* Sum32:
|
||||
*
|
||||
* \brief Return the sum of one 32 bits vector
|
||||
*-------------------------------------------------------------------*/
|
||||
Word32 Sum32( /*<! o : the sum of the elements of the vector */
|
||||
const Word32 *vec, /*<! i : input vector */
|
||||
const Word16 lvec /*<! i : length of input vector */
|
||||
);
|
||||
/**
|
||||
* \brief return 2 ^ (exp * 2^exp_e)
|
||||
* \param exp_m mantissa of the exponent to 2.0f
|
||||
@@ -623,26 +266,61 @@ Word32 BASOP_util_Pow2(
|
||||
);
|
||||
|
||||
|
||||
/* deprecated, use ISqrt32norm! */
|
||||
Word32 Isqrt_lc(
|
||||
Word32 frac, /*!< (i) Q31: normalized value (1.0 < frac <= 0.5) */
|
||||
Word16 * exp /*!< (i/o) : exponent (value = frac x 2^exponent) */
|
||||
Word32 Isqrt_lc1(
|
||||
Word32 frac, /* (i) Q31: normalized value (1.0 < frac <= 0.5) */
|
||||
Word16 * exp /* (i/o) : exponent (value = frac x 2^exponent) */
|
||||
);
|
||||
|
||||
/**
|
||||
* \brief return 1/x
|
||||
* \param x index of lookup table
|
||||
* \return Word16 value of 1/x
|
||||
*/
|
||||
Word16 getNormReciprocalWord16(Word16 x);
|
||||
/*****************************************************************************/
|
||||
/*!
|
||||
|
||||
/**
|
||||
* \brief return (1/x) << s
|
||||
* \param x index of lookup table
|
||||
* \param s shift factor
|
||||
* \return Word16 value of (1/x) << s
|
||||
*/
|
||||
Word16 getNormReciprocalWord16Scale(Word16 x, Word16 s);
|
||||
\brief Calculates pow(2,x)
|
||||
___________________________________________________________________________
|
||||
| |
|
||||
| Function Name : Pow2() |
|
||||
| |
|
||||
| L_x = pow(2.0, exponant.fraction) (exponent = interger part) |
|
||||
| = pow(2.0, 0.fraction) << exponent |
|
||||
|---------------------------------------------------------------------------|
|
||||
| Algorithm: |
|
||||
| |
|
||||
| The function Pow2(L_x) is approximated by a table and linear |
|
||||
| interpolation. |
|
||||
| |
|
||||
| 1- i = bit10-b15 of fraction, 0 <= i <= 31 |
|
||||
| 2- a = bit0-b9 of fraction |
|
||||
| 3- L_x = table[i]<<16 - (table[i] - table[i+1]) * a * 2 |
|
||||
| 4- L_x = L_x >> (30-exponant) (with rounding) |
|
||||
|___________________________________________________________________________|
|
||||
*/
|
||||
Word32 Pow2( /*!< (o) Q0 : result (range: 0<=val<=0x7fffffff) */
|
||||
Word16 exponant, /*!< (i) Q0 : Integer part. (range: 0<=val<=30) */
|
||||
Word16 fraction /*!< (i) Q15 : Fractionnal part. (range: 0.0<=val<1.0) */
|
||||
);
|
||||
|
||||
/*************************************************************************
|
||||
*
|
||||
* FUNCTION: Log2_norm()
|
||||
*
|
||||
* PURPOSE: Computes log2(L_x, exp), where L_x is positive and
|
||||
* normalized, and exp is the normalisation exponent
|
||||
* If L_x is negative or zero, the result is 0.
|
||||
*
|
||||
* DESCRIPTION:
|
||||
* The function Log2(L_x) is approximated by a table and linear
|
||||
* interpolation. The following steps are used to compute Log2(L_x)
|
||||
*
|
||||
* 1- exponent = 30-norm_exponent
|
||||
* 2- i = bit25-b31 of L_x; 32<=i<=63 (because of normalization).
|
||||
* 3- a = bit10-b24
|
||||
* 4- i -=32
|
||||
* 5- fraction = table[i]<<16 - (table[i] - table[i+1]) * a * 2
|
||||
*
|
||||
*************************************************************************/
|
||||
|
||||
Word16 Log2_norm_lc ( /* (o) : Fractional part of Log2. (range: 0<=val<1) */
|
||||
Word32 L_x /* (i) : input value (normalized) */
|
||||
);
|
||||
|
||||
/*************************************************************************
|
||||
*
|
||||
@@ -674,41 +352,6 @@ Word32 BASOP_Util_fPow( /* (o) : mantissa of result
|
||||
Word16 *result_e /* (o) : output pointer to exponent of result */
|
||||
);
|
||||
|
||||
/*___________________________________________________________________________
|
||||
| |
|
||||
| Function Name : Dot_product12_offs() |
|
||||
| |
|
||||
| Compute scalar product of <x[],y[]> using accumulator. |
|
||||
| The parameter 'L_off' is added to the accumulation result. |
|
||||
| The result is normalized (in Q31) with exponent (0..30). |
|
||||
| Notes: |
|
||||
| o data in x[],y[] must provide enough headroom for accumulation |
|
||||
| o L_off must correspond in format with product of x,y |
|
||||
| Example: 0.01f for Q9 x Q9: 0x0000147B in Q19 |
|
||||
| means: L_off = FL2WORD32_SCALE(0.01f,31-19) |
|
||||
|---------------------------------------------------------------------------|
|
||||
| Algorithm: |
|
||||
| |
|
||||
| dot_product = L_off + sum(x[i]*y[i]) i=0..N-1 |
|
||||
|___________________________________________________________________________|
|
||||
*/
|
||||
|
||||
Word32 Dot_product12_offs( /* (o) Q31: normalized result (1 < val <= -1) */
|
||||
const Word16 x[], /* (i) 12bits: x vector */
|
||||
const Word16 y[], /* (i) 12bits: y vector */
|
||||
const Word16 lg, /* (i) : vector length in range [1..256] */
|
||||
Word16 * exp, /* (o) : exponent of result (0..+30) */
|
||||
Word32 L_off /* (i) initial summation offset /2 */
|
||||
);
|
||||
|
||||
Word32 Dot_product15_offs( /* (o) Q31: normalized result (1 < val <= -1) */
|
||||
const Word16 x[], /* (i) 15bits: x vector */
|
||||
const Word16 y[], /* (i) 15bits: y vector */
|
||||
const Word16 lg, /* (i) : vector length in range [1..256] */
|
||||
Word16 *exp, /* (o) : exponent of result (0..+30) */
|
||||
Word32 L_off /* (i) initial summation offset */
|
||||
);
|
||||
|
||||
/*!**********************************************************************
|
||||
\brief Add two values given by mantissa and exponent.
|
||||
|
||||
@@ -722,96 +365,22 @@ Word32 BASOP_Util_Add_Mant32Exp /*!< o: normalized result manti
|
||||
Word32 b_m, /*!< i: Mantissa of 2nd operand b */
|
||||
Word16 b_e, /*!< i: Exponent of 2nd operand b */
|
||||
Word16 *ptr_e); /*!< o: exponent of result */
|
||||
/*!**********************************************************************
|
||||
\brief Returns the comparison result of two normalized values given by mantissa and exponent.
|
||||
return value: -1: a < b, 0: a == b, 1; a > b
|
||||
|
||||
Mantissas are in 32-bit-fractional format with values between 0 and 1. <br>
|
||||
The base for exponents is 2. Example: \f$ a = a\_m * 2^{a\_e} \f$<br>
|
||||
|
||||
************************************************************************/
|
||||
Word16 BASOP_Util_Cmp_Mant32Exp /*!< o: flag: result of comparison */
|
||||
(Word32 a_m, /*!< i: Mantissa of 1st operand a */
|
||||
Word16 a_e, /*!< i: Exponent of 1st operand a */
|
||||
Word32 b_m, /*!< i: Mantissa of 2nd operand b */
|
||||
Word16 b_e); /*!< i: Exponent of 2nd operand b */
|
||||
|
||||
/********************************************************************
|
||||
* bufferCopyFx
|
||||
*
|
||||
* \brief copies buffer while preserving Format of destination buffer
|
||||
*********************************************************************
|
||||
*/
|
||||
void bufferCopyFx(
|
||||
Word16* src, /*<! Qx pointer to input buffer */
|
||||
Word16* dest, /*<! Qx pointer to output buffer */
|
||||
Word16 length, /*<! Q0 length of buffer to copy */
|
||||
Word16 Qf_src, /*<! Q0 Q format (frac-bits) of source buffer */
|
||||
Word16 Qf_dest, /*<! Q0 Q format (frac-bits )of dest buffer */
|
||||
Word16 Q_src, /*<! Q0 exponent of source buffer */
|
||||
Word16 Q_dest /*<! Q0 exponent of destination buffer */
|
||||
);
|
||||
|
||||
/****************************************************************************/
|
||||
/*!
|
||||
\brief Accumulates multiplications
|
||||
|
||||
Accumulates the elementwise multiplications of Word32 Array bufX32 with Word16 Array bufY16
|
||||
pointed to by arg1 to arg4 including the corresponding exponents. Length of to be multiplied arrays is arg5,
|
||||
Accumulates the elementwise multiplications of Word32 Array X with Word16 Array Y
|
||||
pointed to by arg1 and arg2 with specified headroom. Length of to be multiplied arrays is arg3,
|
||||
headroom with has to be taken into account is specified in arg4
|
||||
|
||||
\return Word32 result of accumulated multiplications over Word32 array arg1 and Word16 array arg3 and Word16 pointer
|
||||
to exponent of the result
|
||||
\return Word32 result of accumulated multiplications over Word32 array arg1 and Word16 array arg2 and Word16 pointer
|
||||
to exponent correction factor which needs to be added to the exponent of the result vector
|
||||
*/
|
||||
Word32 dotWord32_16_Mant32Exp(const Word32 *bufX32,/* i: 32-bit buffer with unknown headroom */
|
||||
Word16 bufX32_exp, /* i: exponent of buffer bufX32 */
|
||||
const Word16 *bufY16,/* i: 16-bit buffer quite right-aligned */
|
||||
Word16 bufY16_exp, /* i: exponent of buffer bufY16 */
|
||||
Word16 len, /* i: buffer len to process */
|
||||
Word16 *exp); /* o: result exponent */
|
||||
|
||||
/*!**********************************************************************
|
||||
\brief Converts linear factor or energy to Decibel
|
||||
return value: fEnergy=0: 20 * log10(x * 2^{x\_e}),
|
||||
fEnergy=1: 10 * log10(x * 2^{x\_e})
|
||||
|
||||
Mantissa x is in 32-bit-fractional format with values between 0 and 1. <br>
|
||||
The base for exponent x_e is 2. <br>
|
||||
|
||||
************************************************************************/
|
||||
Word16 BASOP_Util_lin2dB( /*!< o: dB value (7Q8) */
|
||||
Word32 x, /*!< i: mantissa */
|
||||
Word16 x_e, /*!< i: exponent */
|
||||
Word16 fEnergy); /*!< i: flag indicating if x is energy */
|
||||
|
||||
/*!**********************************************************************
|
||||
\brief Calculates atan(x).
|
||||
************************************************************************/
|
||||
Word16 BASOP_util_atan( /*!< o: atan(x) [-pi/2;pi/2] 1Q14 */
|
||||
Word32 x /*!< i: input data (-64;64) 6Q25 */
|
||||
);
|
||||
|
||||
/*!**********************************************************************
|
||||
\brief Calculates atan2(y,x).
|
||||
************************************************************************/
|
||||
Word16 BASOP_util_atan2( /*!< o: atan2(y,x) [-pi,pi] Q13 */
|
||||
Word32 y, /*!< i: */
|
||||
Word32 x, /*!< i: */
|
||||
Word16 e /*!< i: exponent difference (exp_y - exp_x) */
|
||||
);
|
||||
/*!**********************************************************************
|
||||
\brief norm_llQ31 returns Word32 with scalingfactor, with 2 32bit accus as input
|
||||
|
||||
************************************************************************/
|
||||
Word32 norm_llQ31( /* o : normalized result Q31 */
|
||||
Word32 L_c, /* i : upper bits of accu Q-1 */
|
||||
Word32 L_sum, /* i : lower bits of accu, unsigned Q31 */
|
||||
Word16 * exp /* o : exponent of result in [-32,31] Q0 */
|
||||
);
|
||||
|
||||
/* compare two positive normalized 16 bit mantissa/exponent values */
|
||||
/* return value: positive if first value greater, negative if second value greater, zero if equal */
|
||||
Word16 compMantExp16Unorm(Word16 m1, Word16 e1, Word16 m2, Word16 e2);
|
||||
Word32 dotWord32_16_guards(const Word32 * X, const Word16 * Y, Word16 n, Word16 hr, Word16 * shift);
|
||||
|
||||
|
||||
|
||||
Word32 Sqrt_l(Word32 L_x, Word16 *exp);
|
||||
|
||||
#endif /* __BASOP_UTIL_H__ */
|
||||
|
||||
46
src/libs/libevs/lib_com/bastypes.h
Normal file
46
src/libs/libevs/lib_com/bastypes.h
Normal file
@@ -0,0 +1,46 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.443 Nov 13, 2018. Version 12.11.0 / 13.7.0 / 14.3.0 / 15.1.0
|
||||
====================================================================================*/
|
||||
|
||||
#ifndef __BASTYPES_H
|
||||
#define __BASTYPES_H
|
||||
|
||||
typedef unsigned char BYTE;
|
||||
typedef unsigned short WORD;
|
||||
#if defined(__alpha__) || defined(__alpha) || defined(__sgi)
|
||||
typedef unsigned int DWORD; /* long is 64 bits on these machines */
|
||||
#else
|
||||
typedef unsigned long DWORD;
|
||||
#endif
|
||||
|
||||
typedef int BOOL;
|
||||
typedef signed int INT;
|
||||
typedef signed long LONG;
|
||||
typedef unsigned long ULONG;
|
||||
typedef unsigned int UINT;
|
||||
typedef float FLOAT;
|
||||
typedef double DOUBLE;
|
||||
typedef unsigned char UCHAR;
|
||||
typedef char CHAR;
|
||||
|
||||
/* from uld_types.h: */
|
||||
typedef short SHORT;
|
||||
typedef unsigned short USHORT;
|
||||
typedef long int LINT;
|
||||
typedef unsigned long int ULINT;
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#endif
|
||||
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#endif
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
#define INVALID_HANDLE NULL
|
||||
|
||||
#endif
|
||||
504
src/libs/libevs/lib_com/bitalloc_fx.cpp → src/libs/libevs/lib_com/bitalloc.cpp
Executable file → Normal file
504
src/libs/libevs/lib_com/bitalloc_fx.cpp → src/libs/libevs/lib_com/bitalloc.cpp
Executable file → Normal file
@@ -1,209 +1,181 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
EVS Codec 3GPP TS26.443 Nov 13, 2018. Version 12.11.0 / 13.7.0 / 14.3.0 / 15.1.0
|
||||
====================================================================================*/
|
||||
|
||||
#include "options.h"
|
||||
#include "cnst.h"
|
||||
#include "rom_com.h"
|
||||
#include "prot.h"
|
||||
#include "basop_util.h"
|
||||
#include "basop_proto_func.h"
|
||||
|
||||
#include "options.h" /* Compilation switches */
|
||||
#include "cnst_fx.h" /* Common constants */
|
||||
#include "rom_com_fx.h" /* Static table prototypes */
|
||||
#include "prot_fx.h" /* Function prototypes */
|
||||
#include "stl.h" /* required for wmc_tool */
|
||||
|
||||
void bitalloc_fx (
|
||||
Word16 *y, /* i : reordered norm of sub-vectors Q0 */
|
||||
Word16 *idx, /* i : reordered sub-vector indices Q0 */
|
||||
Word16 sum, /* i : number of available bits Q0 */
|
||||
Word16 N, /* i : number of norms Q0 */
|
||||
Word16 K, /* i : maximum number of bits per dimension Q0 */
|
||||
Word16 *r, /* o : bit-allacation vector Q0 */
|
||||
const Word16 *sfmsize, /* i : band length Q0 */
|
||||
const Word16 hqswb_clas /* i : signal classification flag Q0 */
|
||||
/*--------------------------------------------------------------------------
|
||||
* bitalloc()
|
||||
*
|
||||
* Adaptive bit allocation for 20kHz audio codec
|
||||
*--------------------------------------------------------------------------*/
|
||||
|
||||
void bitalloc (
|
||||
short *y, /* i : reordered norm of sub-vectors */
|
||||
short *idx, /* i : reordered sub-vector indices */
|
||||
short sum, /* i : number of available bits */
|
||||
short N, /* i : number of norms */
|
||||
short K, /* i : maximum number of bits per dimension */
|
||||
short *r, /* o : bit-allacation vector */
|
||||
const short *sfmsize, /* i : band length */
|
||||
const short hqswb_clas /* i : signal classification flag */
|
||||
)
|
||||
{
|
||||
Word16 i, j, k, n, m, v, im;
|
||||
Word16 diff, temp;
|
||||
Word16 fac;
|
||||
Word16 ii;
|
||||
Word16 SFM_thr = SFM_G1G2;
|
||||
move16();
|
||||
short i, j, k, n, m, v, im;
|
||||
short diff, temp;
|
||||
short fac;
|
||||
short ii;
|
||||
short SFM_thr = SFM_G1G2;
|
||||
|
||||
N = sub(N, 1);
|
||||
N -= 1;
|
||||
|
||||
if ( sub(hqswb_clas, HQ_HARMONIC) == 0 )
|
||||
if ( hqswb_clas == HQ_HARMONIC )
|
||||
{
|
||||
SFM_thr = 22;
|
||||
move16();
|
||||
}
|
||||
|
||||
fac = 3;
|
||||
move16();
|
||||
K = sub(K,2);
|
||||
K -= 2;
|
||||
im = 1;
|
||||
move16();
|
||||
diff = sum;
|
||||
move16();
|
||||
n = shr(sum,3);
|
||||
FOR ( i=0; i<n; i++ )
|
||||
n = sum >> 3;
|
||||
for ( i=0; i<n; i++ )
|
||||
{
|
||||
k = 0;
|
||||
move16();
|
||||
temp = y[0];
|
||||
move16();
|
||||
FOR ( m=1; m<im; m++)
|
||||
for (m=1; m<im; m++)
|
||||
{
|
||||
v = sub( temp, y[m] );
|
||||
temp = s_max(temp, y[m]);
|
||||
if ( v < 0 )
|
||||
if ( temp < y[m] )
|
||||
{
|
||||
temp = y[m];
|
||||
k = m;
|
||||
move16();
|
||||
}
|
||||
}
|
||||
|
||||
IF ( sub(temp, y[m]) < 0 )
|
||||
if ( temp < y[m] )
|
||||
{
|
||||
k = m;
|
||||
move16();
|
||||
if ( sub(im, N) < 0 )
|
||||
if ( im < N)
|
||||
{
|
||||
im = add(im, 1);
|
||||
im++;
|
||||
}
|
||||
}
|
||||
|
||||
j = idx[k];
|
||||
move16();
|
||||
|
||||
test();
|
||||
IF ( sub(sum,sfmsize[j]) >= 0 && sub(r[j],K) < 0 )
|
||||
if ( sum >= sfmsize[j] && r[j] < K )
|
||||
{
|
||||
y[k] = sub(y[k], fac);
|
||||
move16();
|
||||
r[j] = add(r[j], 1);
|
||||
move16();
|
||||
|
||||
if ( sub(r[j], K) >= 0 )
|
||||
y[k] -= fac;
|
||||
r[j]++;
|
||||
if ( r[j] >= K )
|
||||
{
|
||||
y[k] = -32768;
|
||||
move16();
|
||||
y[k] = MIN16B;
|
||||
}
|
||||
sum = sub(sum,sfmsize[j]);
|
||||
sum -= sfmsize[j];
|
||||
}
|
||||
ELSE
|
||||
else
|
||||
{
|
||||
y[k] = -32768;
|
||||
move16();
|
||||
k = add(k, 1);
|
||||
test();
|
||||
if ( sub(k, im) == 0 && sub(im, N) < 0 )
|
||||
y[k] = MIN16B;
|
||||
k++;
|
||||
if ( k == im && im < N )
|
||||
{
|
||||
im = add(im, 1);
|
||||
im++;
|
||||
}
|
||||
}
|
||||
|
||||
test();
|
||||
IF ( (sub(sum, WID_G1)<0) || (sub(diff, sum)==0) )
|
||||
if ( sum < WID_G1 || diff == sum )
|
||||
{
|
||||
BREAK;
|
||||
break;
|
||||
}
|
||||
|
||||
diff = sum;
|
||||
move16();
|
||||
v = sub(N, 1);
|
||||
v = N - 1;
|
||||
|
||||
IF ( sub(k, v) > 0 )
|
||||
if (k > v)
|
||||
{
|
||||
FOR ( ii=0; ii<=N; ii++ )
|
||||
for ( ii=0; ii<=N; ii++ )
|
||||
{
|
||||
IF ( sub(y[ii], -32768) > 0 )
|
||||
if ( y[ii] > MIN16B )
|
||||
{
|
||||
if ( sub(ii, N) < 0 )
|
||||
if( ii < N )
|
||||
{
|
||||
im = add(ii, 1);
|
||||
im = ii + 1;
|
||||
}
|
||||
BREAK;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
IF ( sub(sum, WID_G2) >= 0 )
|
||||
if ( sum >= WID_G2)
|
||||
{
|
||||
FOR (i=0; i<=N; i++)
|
||||
for (i=0; i<=N; i++)
|
||||
{
|
||||
j = idx[i];
|
||||
move16();
|
||||
test();
|
||||
test();
|
||||
IF ( sub(j, SFM_G1) >= 0 && sub(j, SFM_thr) < 0 && r[j] == 0 )
|
||||
if ( j >= SFM_G1 && j < SFM_thr && r[j] == 0 )
|
||||
{
|
||||
r[j] = 1;
|
||||
move16();
|
||||
sum = sub(sum, WID_G2);
|
||||
IF (sub(sum, WID_G2) < 0)
|
||||
sum -= WID_G2;
|
||||
if ( sum < WID_G2 )
|
||||
{
|
||||
BREAK;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IF ( sub(sum, WID_G2) >= 0 )
|
||||
if ( sum >= WID_G2 )
|
||||
{
|
||||
FOR (i=0; i<=N; i++)
|
||||
for (i=0; i<=N; i++)
|
||||
{
|
||||
j = idx[i];
|
||||
move16();
|
||||
test();
|
||||
test();
|
||||
IF ( sub(j,SFM_G1) >= 0 && sub(j, SFM_thr) < 0 && sub(r[j], 1) == 0 )
|
||||
if ( j >= SFM_G1 && j < SFM_thr && r[j] == 1 )
|
||||
{
|
||||
r[j] = 2;
|
||||
move16();
|
||||
sum = sub(sum, WID_G2);
|
||||
IF ( sub(sum, WID_G2) < 0 )
|
||||
sum -= WID_G2;
|
||||
if ( sum < WID_G2 )
|
||||
{
|
||||
BREAK;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IF ( sub(sum, WID_G1) >= 0 )
|
||||
if ( sum >= WID_G1 )
|
||||
{
|
||||
FOR (i=0; i<=N; i++)
|
||||
for (i=0; i<=N; i++)
|
||||
{
|
||||
j = idx[i];
|
||||
move16();
|
||||
test();
|
||||
IF ( sub(j, SFM_G1) < 0 && r[j] == 0 )
|
||||
if ( j < SFM_G1 && r[j] == 0 )
|
||||
{
|
||||
r[j] = 1;
|
||||
move16();
|
||||
sum = sub(sum, WID_G1);
|
||||
IF ( sub(sum, WID_G1) < 0 )
|
||||
sum -= WID_G1;
|
||||
if ( sum < WID_G1 )
|
||||
{
|
||||
BREAK;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IF ( sub(sum, WID_G1) >= 0 )
|
||||
if ( sum >= WID_G1 )
|
||||
{
|
||||
FOR (i=0; i<=N; i++)
|
||||
for (i=0; i<=N; i++)
|
||||
{
|
||||
j = idx[i];
|
||||
move16();
|
||||
test();
|
||||
IF ( sub(j, SFM_G1) < 0 && sub(r[j], 1) == 0 )
|
||||
if ( j < SFM_G1 && r[j] == 1 )
|
||||
{
|
||||
r[j] = 2;
|
||||
move16();
|
||||
sum = sub(sum, WID_G1);
|
||||
IF ( sub(sum, WID_G1) < 0 )
|
||||
sum -= WID_G1;
|
||||
if ( sum < WID_G1 )
|
||||
{
|
||||
BREAK;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -212,21 +184,22 @@ void bitalloc_fx (
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------*
|
||||
* BitAllocF()
|
||||
*
|
||||
* Fractional bit allocation
|
||||
*-------------------------------------------------------------------*/
|
||||
|
||||
Word16 BitAllocF_fx (
|
||||
Word16 *y, /* i : norm of sub-vectors :Q0 */
|
||||
Word32 bit_rate, /* i : bitrate :Q0 */
|
||||
Word16 B, /* i : number of available bits :Q0 */
|
||||
Word16 N, /* i : number of sub-vectors :Q0 */
|
||||
Word16 *R, /* o : bit-allocation indicator :Q0 */
|
||||
Word16 *Rsubband_fx /* o : sub-band bit-allocation vector :Q3 */
|
||||
,const Word16 hqswb_clas, /* i : hq swb class :Q0 */
|
||||
const Word16 num_env_bands/* i : Number sub bands to be encoded for HF GNERIC :Q0 */
|
||||
short BitAllocF (
|
||||
short *y, /* i : norm of sub-vectors */
|
||||
long bit_rate, /* i : bitrate */
|
||||
short B, /* i : number of available bits */
|
||||
short N, /* i : number of sub-vectors */
|
||||
short *R, /* o : bit-allocation indicator */
|
||||
short *Rsubband, /* o : sub-band bit-allocation vector (Q3) */
|
||||
const short hqswb_clas, /* i : hq swb class */
|
||||
const short num_env_bands /* i : Number sub bands to be encoded for HQ_SWB_BWE */
|
||||
)
|
||||
{
|
||||
Word16 fac;
|
||||
@@ -234,55 +207,44 @@ Word16 BitAllocF_fx (
|
||||
|
||||
Word16 m_fx;
|
||||
Word32 t_fx, B_fx;
|
||||
Word32 L_tmp1, L_tmp2, L_tmp3;
|
||||
Word32 L_tmp1, L_tmp2;
|
||||
Word16 tmp, exp1, exp2;
|
||||
Word32 Rsubband_w32_fx[NB_SFM]; /* Q15 */
|
||||
Word16 B_w16_fx;
|
||||
|
||||
set32_fx( Rsubband_w32_fx, 0, NB_SFM);
|
||||
set_i( Rsubband_w32_fx, 0, NB_SFM);
|
||||
|
||||
fac = 3;
|
||||
move16();
|
||||
|
||||
IF (L_sub(bit_rate, 32000) < 0)
|
||||
if (L_sub(bit_rate, 32000) < 0)
|
||||
{
|
||||
bs = 2;
|
||||
move16();
|
||||
}
|
||||
ELSE
|
||||
else
|
||||
{
|
||||
bs = 3;
|
||||
move16();
|
||||
}
|
||||
low_rate = 1;
|
||||
move16();
|
||||
|
||||
Nmin = N;
|
||||
move16();
|
||||
if ( sub(Nmin,SFM_N) > 0)
|
||||
{
|
||||
Nmin = SFM_N;
|
||||
move16();
|
||||
}
|
||||
|
||||
/* Initial bits distribution */
|
||||
test();
|
||||
IF (sub(hqswb_clas , HQ_GEN_SWB) == 0 || sub(hqswb_clas , HQ_GEN_FB) == 0)
|
||||
if (sub(hqswb_clas , HQ_GEN_SWB) == 0 || sub(hqswb_clas , HQ_GEN_FB) == 0)
|
||||
{
|
||||
/* Initial bits distribution */
|
||||
L_tmp1 = 0;
|
||||
move16();
|
||||
m_fx = 0;
|
||||
move16();
|
||||
FOR ( i = 0; i < num_env_bands ; i++)
|
||||
for ( i = 0; i < num_env_bands ; i++)
|
||||
{
|
||||
L_tmp1 = L_mac0(L_tmp1, Nb[i], y[i]);
|
||||
}
|
||||
L_tmp1 = L_msu0(L_tmp1, fac, B);
|
||||
|
||||
t_fx = L_deposit_l(0);
|
||||
t_fx = 0;
|
||||
n = 0;
|
||||
move16();
|
||||
tmp = add(band_end_HQ[num_env_bands-1], shl(band_end_HQ[num_env_bands-1], 1));
|
||||
exp1 = norm_s(tmp);
|
||||
tmp = div_s(16384, shl(tmp, exp1));/*15 + 14 - exp1*/
|
||||
@@ -290,65 +252,65 @@ Word16 BitAllocF_fx (
|
||||
tmp = shl(tmp, exp2);
|
||||
exp1 = add(29, sub(exp2, exp1));
|
||||
|
||||
FOR ( i = 0; i < N; i++)
|
||||
for ( i = 0; i < N; i++)
|
||||
{
|
||||
L_tmp2 = L_sub(L_mult0(y[i], band_end_HQ[num_env_bands-1]), L_tmp1);
|
||||
Rsubband_w32_fx[i] = L_mult0(extract_l(L_tmp2), Nb[i]);
|
||||
move32();/*Q0*/
|
||||
IF (Rsubband_w32_fx[i] > 0)
|
||||
if (Rsubband_w32_fx[i] > 0)
|
||||
{
|
||||
n = add(n,Nb[i]);
|
||||
Rsubband_w32_fx[i] = Mult_32_16(Rsubband_w32_fx[i], tmp);
|
||||
Rsubband_w32_fx[i] = Mpy_32_16(Rsubband_w32_fx[i], tmp);
|
||||
move32();/*exp1 - 15*/
|
||||
Rsubband_w32_fx[i] = L_shl(Rsubband_w32_fx[i], sub(30, exp1));/*Q15*/
|
||||
|
||||
t_fx = L_add(t_fx, Rsubband_w32_fx[i]);/*Q0*/
|
||||
}
|
||||
ELSE
|
||||
else
|
||||
{
|
||||
Rsubband_w32_fx[i] = L_deposit_l(0);
|
||||
Rsubband_w32_fx[i] = 0;
|
||||
move32();
|
||||
}
|
||||
}
|
||||
}
|
||||
ELSE
|
||||
else
|
||||
{
|
||||
/* Initial bits distribution */
|
||||
L_tmp1 = 0;
|
||||
move16();
|
||||
m_fx = 0;
|
||||
move16();
|
||||
FOR ( i = 0; i < N ; i++)
|
||||
for ( i = 0; i < N ; i++)
|
||||
{
|
||||
L_tmp1 = L_mac0(L_tmp1, Nb[i], y[i]);
|
||||
}
|
||||
L_tmp1 = L_msu0(L_tmp1, fac, B);
|
||||
|
||||
|
||||
t_fx = L_deposit_l(0);
|
||||
t_fx = 0;
|
||||
n = 0;
|
||||
move16();
|
||||
tmp = add(band_end_HQ[N-1], shl(band_end_HQ[N-1], 1));
|
||||
exp1 = norm_s(tmp);
|
||||
tmp = div_s(16384, shl(tmp, exp1));/*15 + 14 - exp1*/
|
||||
exp2 = norm_s(tmp);
|
||||
tmp = shl(tmp, exp2);
|
||||
exp1 = add(29, sub(exp2, exp1));
|
||||
FOR ( i = 0; i < N; i++)
|
||||
for ( i = 0; i < N; i++)
|
||||
{
|
||||
L_tmp2 = L_sub(L_mult0(y[i], band_end_HQ[N-1]), L_tmp1);
|
||||
Rsubband_w32_fx[i] = L_mult0(extract_l(L_tmp2), Nb[i]);
|
||||
move32();/*Q0*/
|
||||
IF (Rsubband_w32_fx[i] > 0)
|
||||
if (Rsubband_w32_fx[i] > 0)
|
||||
{
|
||||
n = add(n,Nb[i]);
|
||||
L_tmp3 = Mult_32_16(Rsubband_w32_fx[i], tmp); /*exp1 - 15*/
|
||||
Rsubband_w32_fx[i] = L_shl(L_tmp3, sub(30, exp1)); /*Q15*/ move32();
|
||||
Rsubband_w32_fx[i] = Mpy_32_16(Rsubband_w32_fx[i], tmp);
|
||||
move32();/*exp1 - 15*/
|
||||
Rsubband_w32_fx[i] = L_shl(Rsubband_w32_fx[i], sub(30, exp1));/*Q15*/
|
||||
|
||||
t_fx = L_add(t_fx, Rsubband_w32_fx[i]);/*Q0*/
|
||||
}
|
||||
ELSE
|
||||
else
|
||||
{
|
||||
Rsubband_w32_fx[i] = L_deposit_l(0);
|
||||
Rsubband_w32_fx[i] = 0;
|
||||
move32();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -363,52 +325,52 @@ Word16 BitAllocF_fx (
|
||||
tmp = div_s(extract_h(L_shl(L_tmp1, exp1)), shl(n, exp2));/*15 + 15 + exp1 - 16 - exp2*/
|
||||
m_fx = shl(tmp, sub(exp2, exp1));/*Q14*/
|
||||
|
||||
t_fx = L_deposit_l(0);
|
||||
t_fx = 0;
|
||||
n = 0;
|
||||
move16();
|
||||
FOR ( i = 0; i < N; i++)
|
||||
for ( i = 0; i < N; i++)
|
||||
{
|
||||
IF (Rsubband_w32_fx[i] > 0)
|
||||
if (Rsubband_w32_fx[i] > 0)
|
||||
{
|
||||
Rsubband_w32_fx[i] = L_msu(Rsubband_w32_fx[i], m_fx, Nb[i]);
|
||||
move32();
|
||||
|
||||
IF (Rsubband_w32_fx[i] > 0)
|
||||
if (Rsubband_w32_fx[i] > 0)
|
||||
{
|
||||
n = add(n,Nb[i]);
|
||||
|
||||
t_fx = L_add(t_fx, Rsubband_w32_fx[i]);
|
||||
}
|
||||
ELSE
|
||||
else
|
||||
{
|
||||
Rsubband_w32_fx[i] = L_deposit_l(0);
|
||||
Rsubband_w32_fx[i] = 0;
|
||||
move32();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Bits = B;
|
||||
move16();
|
||||
|
||||
/* Impose bit-constraints to subbands with less than minimum bits*/
|
||||
t_fx = L_deposit_l(0);
|
||||
t_fx = 0;
|
||||
n = 0;
|
||||
move16();
|
||||
FOR ( i = 0; i < N; i++)
|
||||
for ( i = 0; i < N; i++)
|
||||
{
|
||||
IF (Rsubband_w32_fx[i] > 0)
|
||||
if (Rsubband_w32_fx[i] > 0)
|
||||
{
|
||||
test();
|
||||
IF ((L_sub(Rsubband_w32_fx[i] , L_shl(add(bs, LNb[i]), 15)) <0) && (sub(low_rate,1) == 0))
|
||||
test();
|
||||
if ((L_sub(Rsubband_w32_fx[i] , L_shl(add(bs, LNb[i]), 15)) <0) && (sub(low_rate,1) == 0))
|
||||
{
|
||||
Rsubband_w32_fx[i] = L_deposit_l(0);
|
||||
Rsubband_w32_fx[i] = 0;
|
||||
move32();
|
||||
}
|
||||
ELSE IF ( L_sub(Rsubband_w32_fx[i] , L_shl(Nb[i], 15)) <=0)
|
||||
else if ( L_sub(Rsubband_w32_fx[i] , L_shl(Nb[i], 15)) <=0)
|
||||
{
|
||||
B = sub(B,Nb[i]);
|
||||
Rsubband_w32_fx[i] = L_shl(Nb[i], 15);
|
||||
move32();
|
||||
}
|
||||
ELSE
|
||||
else
|
||||
{
|
||||
n = add(n,Nb[i]);
|
||||
t_fx = L_add(t_fx, Rsubband_w32_fx[i]);
|
||||
@@ -422,7 +384,7 @@ Word16 BitAllocF_fx (
|
||||
L_tmp1 = L_sub(t_fx, L_shl(B, 15));
|
||||
L_tmp2 = L_abs(L_tmp1);
|
||||
|
||||
if (n>0)
|
||||
if( n>0 )
|
||||
{
|
||||
exp1 = sub(norm_l(L_tmp2), 1);
|
||||
exp2 = norm_s(n);
|
||||
@@ -433,22 +395,20 @@ Word16 BitAllocF_fx (
|
||||
m_fx = negate(m_fx);
|
||||
}
|
||||
|
||||
t_fx = L_deposit_l(0);
|
||||
t_fx = 0;
|
||||
n = 0;
|
||||
move16();
|
||||
FOR( i = 0; i < N; i++)
|
||||
for( i = 0; i < N; i++)
|
||||
{
|
||||
IF (L_sub(Rsubband_w32_fx[i] , L_shl(Nb[i], 15)) > 0)
|
||||
if (L_sub(Rsubband_w32_fx[i] , L_shl(Nb[i], 15)) > 0)
|
||||
{
|
||||
Rsubband_w32_fx[i] = L_msu(Rsubband_w32_fx[i], m_fx, Nb[i]);
|
||||
move32();
|
||||
IF (L_sub(Rsubband_w32_fx[i] ,L_shl(Nb[i], 15)) > 0)
|
||||
if (L_sub(Rsubband_w32_fx[i] ,L_shl(Nb[i], 15)) > 0)
|
||||
{
|
||||
n = add(n,Nb[i]);
|
||||
|
||||
t_fx = L_add(t_fx, Rsubband_w32_fx[i]);
|
||||
}
|
||||
ELSE
|
||||
else
|
||||
{
|
||||
B = sub(B,Nb[i]);
|
||||
|
||||
@@ -459,15 +419,16 @@ Word16 BitAllocF_fx (
|
||||
}
|
||||
}
|
||||
/*In case no subband has enough bits more than 1-bit per sample, take bits off the higher subbands */
|
||||
IF (t_fx == 0)
|
||||
if (t_fx == 0)
|
||||
{
|
||||
FOR ( i = N-1; i >= 0; i--)
|
||||
for ( i = N-1; i >= 0; i--)
|
||||
{
|
||||
IF (Rsubband_w32_fx[i] > 0)
|
||||
if (Rsubband_w32_fx[i] > 0)
|
||||
{
|
||||
B = add( B, Nb[i] );
|
||||
Rsubband_w32_fx[i] = L_deposit_l(0);
|
||||
IF ( B >= 0)
|
||||
Rsubband_w32_fx[i] = 0;
|
||||
move32();
|
||||
if ( B >= 0)
|
||||
{
|
||||
BREAK;
|
||||
}
|
||||
@@ -479,60 +440,56 @@ Word16 BitAllocF_fx (
|
||||
|
||||
/* fine redistribution of over-allocated or under-allocated bits */
|
||||
tmp = 0;
|
||||
move16();
|
||||
FOR ( i = 0; i < N; i++)
|
||||
for ( i = 0; i < N; i++)
|
||||
{
|
||||
Rsubband_fx[i] = extract_l(L_shr(Rsubband_w32_fx[i], 12));
|
||||
tmp = add(tmp, Rsubband_fx[i]);
|
||||
Rsubband[i] = extract_l(L_shr(Rsubband_w32_fx[i], 12));
|
||||
tmp = add(tmp, Rsubband[i]);
|
||||
}
|
||||
|
||||
B = Bits;
|
||||
B_w16_fx = shl(B, 3);
|
||||
IF (sub(tmp ,B_w16_fx)>0)
|
||||
if (sub(tmp ,B_w16_fx)>0)
|
||||
{
|
||||
tmp = sub(tmp, B_w16_fx);
|
||||
FOR ( i = 0; i < N; i++)
|
||||
for ( i = 0; i < N; i++)
|
||||
{
|
||||
IF (sub(Rsubband_fx[i], add(shl(Nb[i], 3), tmp)) >= 0)
|
||||
if (sub(Rsubband[i], add(shl(Nb[i], 3), tmp)) >= 0)
|
||||
{
|
||||
Rsubband_fx[i] = sub(Rsubband_fx[i], tmp);
|
||||
move16();
|
||||
Rsubband[i] = sub(Rsubband[i], tmp);
|
||||
BREAK;
|
||||
}
|
||||
}
|
||||
}
|
||||
ELSE
|
||||
else
|
||||
{
|
||||
tmp = sub(tmp, B_w16_fx);
|
||||
FOR ( i = 0; i < N; i++)
|
||||
for ( i = 0; i < N; i++)
|
||||
{
|
||||
IF (Rsubband_fx[i] > 0)
|
||||
if (Rsubband[i] > 0)
|
||||
{
|
||||
Rsubband_fx[i] = sub(Rsubband_fx[i], tmp);
|
||||
move16();
|
||||
Rsubband[i] = sub(Rsubband[i], tmp);
|
||||
BREAK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Calcuate total used bits and initialize R to be used for Noise Filling */
|
||||
/* Calculate total used bits and initialize R to be used for Noise Filling */
|
||||
tmp = 0;
|
||||
move16();
|
||||
FOR ( i = 0; i < N; i++)
|
||||
for ( i = 0; i < N; i++)
|
||||
{
|
||||
tmp = add(tmp, Rsubband_fx[i]);
|
||||
R[i] = shr(Rsubband_fx[i], 3);
|
||||
move16();
|
||||
tmp = add(tmp, Rsubband[i]);
|
||||
R[i] = shr(Rsubband[i], 3);
|
||||
}
|
||||
|
||||
return shr(tmp, 3);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------*
|
||||
* Bit_group()
|
||||
*
|
||||
* bit allocation in group
|
||||
*-------------------------------------------------------------------*/
|
||||
static
|
||||
void Bit_group_fx (
|
||||
static void Bit_group_fx (
|
||||
Word16 *y, /* i : norm of sub-band Q0*/
|
||||
Word16 start_band, /* i : start band indices Q0*/
|
||||
Word16 end_band, /* i : end band indices Q0*/
|
||||
@@ -547,21 +504,22 @@ void Bit_group_fx (
|
||||
Word16 factor_fx;
|
||||
Word32 R_temp_fx[16], R_sum_fx = 0, R_sum_org_fx = 0, Bits_avg_fx = 0;
|
||||
Word32 L_tmp;
|
||||
UWord32 lo;
|
||||
|
||||
/* initialization for bit allocation in one group*/
|
||||
tmp = 6554;
|
||||
move16(); /*Q15 1/5 */
|
||||
if(sub(thr,5) == 0)
|
||||
IF(sub(thr,5) == 0)
|
||||
{
|
||||
tmp = 6554;
|
||||
move16(); /*Q15 1/5 */
|
||||
}
|
||||
if(sub(thr,6) == 0)
|
||||
IF(sub(thr,6) == 0)
|
||||
{
|
||||
tmp = 5462;
|
||||
move16();/*Q15 1/6 */
|
||||
}
|
||||
if(sub(thr,7) == 0)
|
||||
IF(sub(thr,7) == 0)
|
||||
{
|
||||
tmp = 4682;
|
||||
move16();/*Q15 1/7 */
|
||||
@@ -578,7 +536,7 @@ void Bit_group_fx (
|
||||
}
|
||||
|
||||
/* Rearrange norm vector in decreasing order */
|
||||
reordvct_fx(y_index, band_num, index);
|
||||
reordvct(y_index, band_num, index);
|
||||
/* norm vector modification */
|
||||
|
||||
factor_fx = div_s(1, band_num);/*Q15 */
|
||||
@@ -612,7 +570,7 @@ void Bit_group_fx (
|
||||
{
|
||||
FOR ( j = 0; j < band_num; j++)
|
||||
{
|
||||
if ( y_index[j] < 0 )
|
||||
IF ( y_index[j] < 0 )
|
||||
{
|
||||
y_index[j] = 0;
|
||||
move16();
|
||||
@@ -634,7 +592,8 @@ void Bit_group_fx (
|
||||
{
|
||||
FOR (k = 0; k <= i; k++)
|
||||
{
|
||||
R_temp_fx[k] = L_deposit_h(0);/*Q21 */
|
||||
R_temp_fx[k] = 0;
|
||||
move32();/*Q21 */
|
||||
}
|
||||
}
|
||||
ELSE
|
||||
@@ -647,7 +606,7 @@ void Bit_group_fx (
|
||||
FOR (k = 0; k <= i; k++)
|
||||
{
|
||||
L_tmp = L_shl(L_deposit_l(y_index[k]),24);
|
||||
L_tmp = Mult_32_32(Bits_avg_fx,L_tmp);/*Q(23-exp) */
|
||||
Mpy_32_32_ss(Bits_avg_fx,L_tmp,&L_tmp,&lo);
|
||||
|
||||
R_temp_fx[k] = L_shl(L_tmp,sub(exp,2));
|
||||
move32();/*Q21 */
|
||||
@@ -657,7 +616,8 @@ void Bit_group_fx (
|
||||
L_tmp = L_shl(L_deposit_l(thr),21);/*Q21 */
|
||||
IF ( L_sub(R_temp_fx[i],L_tmp) < 0 )
|
||||
{
|
||||
R_temp_fx[i] = L_deposit_h(0);
|
||||
R_temp_fx[i] = 0;
|
||||
move32();
|
||||
norm_sum = sub(norm_sum,y_index[i]);
|
||||
i--;
|
||||
}
|
||||
@@ -671,7 +631,7 @@ void Bit_group_fx (
|
||||
{
|
||||
FOR ( j = 0; j < bit_band; j++ )
|
||||
{
|
||||
if ( y_index[j] < 0 )
|
||||
IF ( y_index[j] < 0 )
|
||||
{
|
||||
y_index[j] = 0;
|
||||
move16();
|
||||
@@ -682,7 +642,8 @@ void Bit_group_fx (
|
||||
|
||||
FOR ( j = bit_band; j < band_num; j++ )
|
||||
{
|
||||
R_temp_fx[j] = L_deposit_l(0);
|
||||
R_temp_fx[j] = 0;
|
||||
move32();
|
||||
}
|
||||
|
||||
norm_sum = 0;
|
||||
@@ -698,7 +659,8 @@ void Bit_group_fx (
|
||||
{
|
||||
FOR (k = 0; k < i; k++)
|
||||
{
|
||||
R_temp_fx[k] = L_deposit_l(0); /*Q21 */
|
||||
R_temp_fx[k] = 0;
|
||||
move32();/*Q21 */
|
||||
}
|
||||
}
|
||||
ELSE
|
||||
@@ -710,8 +672,7 @@ void Bit_group_fx (
|
||||
FOR (k = 0; k < i; k++)
|
||||
{
|
||||
L_tmp = L_shl(L_deposit_l(y_index[k]),24);
|
||||
L_tmp = Mult_32_32(Bits_avg_fx,L_tmp);/*Q(23-exp) */
|
||||
|
||||
Mpy_32_32_ss(Bits_avg_fx,L_tmp,&L_tmp,&lo);
|
||||
R_temp_fx[k] = L_shl(L_tmp,sub(exp,2));
|
||||
move32();/*Q21 */
|
||||
}
|
||||
@@ -725,7 +686,8 @@ void Bit_group_fx (
|
||||
FOR(m = k; m < i; m++)
|
||||
{
|
||||
norm_sum = sub(norm_sum,y_index[m]);
|
||||
R_temp_fx[m] = L_deposit_l(0); /*Q21 */
|
||||
R_temp_fx[m] = 0;
|
||||
move32();/*Q21 */
|
||||
}
|
||||
i = k;
|
||||
BREAK;
|
||||
@@ -763,12 +725,12 @@ void Bit_group_fx (
|
||||
* WB bit allocation
|
||||
*-------------------------------------------------------------------*/
|
||||
|
||||
Word16 BitAllocWB_fx( /* o : t Q0*/
|
||||
Word16 *y, /* i : norm of sub-vectors Q0*/
|
||||
Word16 B, /* i : number of available bits Q0*/
|
||||
Word16 N, /* i : number of sub-vectors Q0*/
|
||||
Word16 *R, /* o : bit-allocation indicator Q0*/
|
||||
Word16 *Rsubband_fx /* o : sub-band bit-allocation vector Q3*/
|
||||
short BitAllocWB (
|
||||
short *y, /* i : norm of sub-vectors */
|
||||
short B, /* i : number of available bits */
|
||||
short N, /* i : number of sub-vectors */
|
||||
short *R, /* o : bit-allocation indicator */
|
||||
short *Rsubband /* o : sub-band bit-allocation vector (Q3) */
|
||||
)
|
||||
{
|
||||
Word16 t_fx;
|
||||
@@ -778,13 +740,13 @@ Word16 BitAllocWB_fx( /* o : t
|
||||
Word16 factor_fx[2];/*Q13 */
|
||||
Word16 BANDS;
|
||||
Word16 tmp,exp;
|
||||
Word16 Rsum_sub_fx_tmp=0; /* initialize just to avoid compiler warning */
|
||||
Word32 L_tmp,L_tmp1;
|
||||
Word32 Rsubband_buf[NB_SFM];
|
||||
UWord16 lo;
|
||||
|
||||
BANDS = N;
|
||||
move16();
|
||||
if( sub(BANDS,SFM_N) > 0)
|
||||
IF( sub(BANDS,SFM_N) > 0)
|
||||
{
|
||||
BANDS = SFM_N;
|
||||
move16();
|
||||
@@ -797,49 +759,36 @@ Word16 BitAllocWB_fx( /* o : t
|
||||
}
|
||||
/* Calculate the norm sum and average of sub-band */
|
||||
Rsum_sub_fx[0] = 0;
|
||||
move16();
|
||||
FOR ( j = 0; j < SFM_G1; j++ )
|
||||
{
|
||||
if ( y[j] > 0 )
|
||||
IF ( y[j] > 0 )
|
||||
{
|
||||
Rsum_sub_fx_tmp = add(Rsum_sub_fx[0],y[j]); /*Q0 */
|
||||
}
|
||||
if (y[j] > 0)
|
||||
{
|
||||
Rsum_sub_fx[0] = Rsum_sub_fx_tmp;
|
||||
move16(); /*Q0 */
|
||||
}
|
||||
}
|
||||
Ravg_sub_32_fx[0] = L_mult(Rsum_sub_fx[0], 2048);
|
||||
move32();/*Q16 0+15+1 //q15 1/16 =2048 */
|
||||
|
||||
Rsum_sub_fx[1] = 0;
|
||||
move16();
|
||||
FOR ( j = SFM_G1; j < SFM_G1G2; j++ )
|
||||
{
|
||||
if ( y[j] > 0 )
|
||||
{
|
||||
Rsum_sub_fx_tmp = add(Rsum_sub_fx[1],y[j]); /*Q0 */
|
||||
}
|
||||
if ( y[j] > 0 )
|
||||
{
|
||||
Rsum_sub_fx[1] = Rsum_sub_fx_tmp;
|
||||
Rsum_sub_fx[0] = add(Rsum_sub_fx[0],y[j]);
|
||||
move16();/*Q0 */
|
||||
}
|
||||
}
|
||||
Ravg_sub_32_fx[1] = L_mult(Rsum_sub_fx[1], 4096); /*16 0+15+1 //q15 1/8 =4096 */
|
||||
Ravg_sub_32_fx[0] = L_mult(Rsum_sub_fx[0], 2048);
|
||||
move32();/*Q16 0+15+1 , q15 1/16 =2048 */
|
||||
|
||||
Rsum_sub_fx[1] = 0;
|
||||
move32();
|
||||
FOR ( j = SFM_G1; j < SFM_G1G2; j++ )
|
||||
{
|
||||
IF ( y[j] > 0 )
|
||||
{
|
||||
Rsum_sub_fx[1] = add(Rsum_sub_fx[1],y[j]);
|
||||
move16();/*Q0 */
|
||||
}
|
||||
}
|
||||
Ravg_sub_32_fx[1] = L_mult(Rsum_sub_fx[1], 4096); /*16 0+15+1 , q15 1/8 =4096 */
|
||||
|
||||
Rsum_sub_fx[2] = 0;
|
||||
move16();
|
||||
FOR ( j = SFM_G1G2; j < BANDS; j++ )
|
||||
{
|
||||
if ( y[j] > 0 )
|
||||
IF ( y[j] > 0 )
|
||||
{
|
||||
Rsum_sub_fx_tmp = add(Rsum_sub_fx[2],y[j]); /*Q0 */
|
||||
}
|
||||
if ( y[j] > 0 )
|
||||
{
|
||||
Rsum_sub_fx[2] = Rsum_sub_fx_tmp;
|
||||
Rsum_sub_fx[2] = add(Rsum_sub_fx[2],y[j]);
|
||||
move16();/*Q0 */
|
||||
}
|
||||
}
|
||||
@@ -859,7 +808,6 @@ Word16 BitAllocWB_fx( /* o : t
|
||||
R_diff_32_fx[1] = L_sub(Ravg_sub_32_fx[1], Ravg_sub_32_fx[2]);
|
||||
move32();/*Q16 */
|
||||
|
||||
test();
|
||||
IF ( L_sub(R_diff_32_fx[0],393216) < 0 && L_sub(R_diff_32_fx[1],245760) < 0 )
|
||||
{
|
||||
IF(Rsum_fx == 0)
|
||||
@@ -877,26 +825,23 @@ Word16 BitAllocWB_fx( /* o : t
|
||||
tmp = shl(Rsum_fx,exp);/*Q(exp) */
|
||||
tmp = div_s(16384,tmp);/*Q(15+14-exp) */
|
||||
L_tmp1 = L_mult(B,Rsum_sub_fx[0]);/*Q1 */
|
||||
L_tmp = Mult_32_16(L_tmp1,tmp);/*Q(15-exp) */
|
||||
Mpy_32_16_ss(L_tmp1,tmp,&L_tmp,&lo);
|
||||
B1 = extract_h(L_shl(L_tmp,add(exp,1)));/*Q0 */
|
||||
test();
|
||||
if(L_sub(L_tmp1,L_mult(B1,Rsum_fx)) > 0 && L_sub(L_tmp1,L_mult(add(B1,1),Rsum_fx)) >= 0)
|
||||
IF(L_sub(L_tmp1,L_mult(B1,Rsum_fx)) > 0 && L_sub(L_tmp1,L_mult(add(B1,1),Rsum_fx)) >= 0)
|
||||
{
|
||||
B1 = add(B1,1);
|
||||
}
|
||||
L_tmp1 = L_mult(B,Rsum_sub_fx[1]);/*Q1 */
|
||||
L_tmp = Mult_32_16(L_tmp1,tmp);/*Q(15-exp) */
|
||||
Mpy_32_16_ss(L_tmp1,tmp,&L_tmp,&lo);
|
||||
B2 = extract_h(L_shl(L_tmp,add(exp,1)));/*Q0 */
|
||||
test();
|
||||
if(L_sub(L_tmp1,L_mult(B2,Rsum_fx)) > 0 && L_sub(L_tmp1,L_mult(add(B2,1),Rsum_fx)) >= 0)
|
||||
IF(L_sub(L_tmp1,L_mult(B2,Rsum_fx)) > 0 && L_sub(L_tmp1,L_mult(add(B2,1),Rsum_fx)) >= 0)
|
||||
{
|
||||
B2 = add(B2,1);
|
||||
}
|
||||
L_tmp1 = L_mult(B,Rsum_sub_fx[2]);/*Q1 */
|
||||
L_tmp = Mult_32_16(L_tmp1,tmp);/*Q(15-exp) */
|
||||
Mpy_32_16_ss(L_tmp1,tmp,&L_tmp,&lo);
|
||||
B3 = extract_h(L_shl(L_tmp,add(exp,1)));/*Q0 */
|
||||
test();
|
||||
if(L_sub(L_tmp1,L_mult(B3,Rsum_fx)) > 0 && L_sub(L_tmp1,L_mult(add(B3,1),Rsum_fx)) >= 0)
|
||||
IF(L_sub(L_tmp1,L_mult(B3,Rsum_fx)) > 0 && L_sub(L_tmp1,L_mult(add(B3,1),Rsum_fx)) >= 0)
|
||||
{
|
||||
B3 = add(B3,1);
|
||||
}
|
||||
@@ -977,19 +922,17 @@ Word16 BitAllocWB_fx( /* o : t
|
||||
tmp = shl(Rsum_fx,exp);/*Q(exp) */
|
||||
tmp = div_s(16384,tmp);/*Q(15+14-exp) */
|
||||
L_tmp1 = L_mult(B,Rsum_sub_fx[0]);/*Q1 */
|
||||
L_tmp = Mult_32_16(L_tmp1,tmp);/*Q(15-exp) */
|
||||
Mpy_32_16_ss(L_tmp1,tmp,&L_tmp,&lo);
|
||||
B1 = extract_h(L_shl(L_tmp,add(exp,1)));/*Q0 */
|
||||
test();
|
||||
if(L_sub(L_tmp1,L_mult(B1,Rsum_fx)) > 0 && L_sub(L_tmp1,L_mult(add(B1,1),Rsum_fx)) >= 0)
|
||||
IF(L_sub(L_tmp1,L_mult(B1,Rsum_fx)) > 0 && L_sub(L_tmp1,L_mult(add(B1,1),Rsum_fx)) >= 0)
|
||||
{
|
||||
B1 = add(B1,1);
|
||||
}
|
||||
L_tmp1 = Mult_32_16(1975684956,shl(B,5));/*Q(31+5-15=21) */
|
||||
L_tmp1 = Mult_32_16(L_tmp1,shl(Rsum_sub_fx[1],7));/*Q(21+7-15=13) */
|
||||
L_tmp = Mult_32_16(L_tmp1,tmp);/*Q(27-exp) */
|
||||
Mpy_32_16_ss(1975684956,shl(B,5),&L_tmp1,&lo);
|
||||
Mpy_32_16_ss(L_tmp1,shl(Rsum_sub_fx[1],7),&L_tmp1,&lo);
|
||||
Mpy_32_16_ss(L_tmp1,tmp,&L_tmp,&lo);
|
||||
B2 = extract_h(L_shl(L_tmp,sub(exp,11)));/*Q0 */
|
||||
test();
|
||||
if(L_sub(L_tmp1,L_shl(L_mult(B2,Rsum_fx),12)) > 0 && L_sub(L_add(L_tmp1,2),L_shl(L_mult(add(B2,1),Rsum_fx),12)) >= 0)
|
||||
IF(L_sub(L_tmp1,L_shl(L_mult(B2,Rsum_fx),12)) > 0 && L_sub(L_add(L_tmp1,2),L_shl(L_mult(add(B2,1),Rsum_fx),12)) >= 0)
|
||||
{
|
||||
B2 = add(B2,1);
|
||||
}
|
||||
@@ -1012,11 +955,13 @@ Word16 BitAllocWB_fx( /* o : t
|
||||
Bit_group_fx( y, SFM_G1G2, BANDS, B3, 7, Rsubband_buf, factor_fx);
|
||||
FOR (i = 0; i < BANDS; i++)
|
||||
{
|
||||
Rsubband_fx[i] = extract_l(L_shr(Rsubband_buf[i], 18));
|
||||
Rsubband[i] = extract_l(L_shr(Rsubband_buf[i], 18));
|
||||
move16();
|
||||
}
|
||||
|
||||
/* Calcuate total used bits and initialize R to be used for Noise Filling */
|
||||
L_tmp = L_deposit_l(0);
|
||||
L_tmp = 0;
|
||||
move32();
|
||||
FOR( i = 0; i < N; i++)
|
||||
{
|
||||
L_tmp = L_add(L_tmp,Rsubband_buf[i]);/*Q21 */
|
||||
@@ -1025,5 +970,4 @@ Word16 BitAllocWB_fx( /* o : t
|
||||
t_fx = extract_h(L_shr(L_tmp, 5)); /*Q0 */
|
||||
|
||||
return (Word16)t_fx;
|
||||
|
||||
}
|
||||
60
src/libs/libevs/lib_com/bitallocsum.cpp
Normal file
60
src/libs/libevs/lib_com/bitallocsum.cpp
Normal file
@@ -0,0 +1,60 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.443 Nov 13, 2018. Version 12.11.0 / 13.7.0 / 14.3.0 / 15.1.0
|
||||
====================================================================================*/
|
||||
|
||||
#include "options.h"
|
||||
#include "cnst.h"
|
||||
#include "prot.h"
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
* bitallocsum()
|
||||
*
|
||||
* Calculate the total number of bits allocated over frame
|
||||
*--------------------------------------------------------------------------*/
|
||||
|
||||
void bitallocsum(
|
||||
short *R, /* i : bit-allocation vector */
|
||||
const short nb_sfm, /* i : number of sub-vectors */
|
||||
short *sum, /* o : total number of bits allocated */
|
||||
short *Rsubband, /* o : rate per subband (Q3) */
|
||||
const short v, /* i : bit rate */
|
||||
const short length, /* i : length of spectrum (32 or 48 kHz samplerate) */
|
||||
const short *sfmsize /* i : band length */
|
||||
)
|
||||
{
|
||||
short i;
|
||||
short total, tmp;
|
||||
short diff;
|
||||
|
||||
total = 0;
|
||||
for (i = 0; i < nb_sfm; i++)
|
||||
{
|
||||
tmp = R[i] * sfmsize[i];
|
||||
Rsubband[i] = tmp*8;
|
||||
total += tmp;
|
||||
}
|
||||
*sum = total;
|
||||
|
||||
if ( length <= L_FRAME32k )
|
||||
{
|
||||
diff = v - *sum;
|
||||
i = 0;
|
||||
while ( diff > 0 )
|
||||
{
|
||||
if ( R[i] > 0 )
|
||||
{
|
||||
Rsubband[i] += 8;
|
||||
diff -= 1;
|
||||
*sum += 1;
|
||||
}
|
||||
i++;
|
||||
if ( i >= nb_sfm )
|
||||
{
|
||||
i = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#include "options.h" /* Compilation switches */
|
||||
#include "cnst_fx.h" /* Common constants */
|
||||
#include "prot_fx.h" /* Function prototypes */
|
||||
#include "stl.h" /* Common constants */
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
* bitallocsum_fx()
|
||||
*
|
||||
* Calculate the total number of bits allocated over frame
|
||||
*--------------------------------------------------------------------------*/
|
||||
void bitallocsum_fx(
|
||||
Word16 *R, /* i : bit-allocation vector Q0 */
|
||||
const Word16 nb_sfm, /* i : number of sub-vectors Q0 */
|
||||
Word16 *sum, /* o : total number of bits allocated Q0 */
|
||||
Word16 *Rsubband, /* o : rate per subband Q3 */
|
||||
const Word16 v, /* i : bit rate Q0 */
|
||||
const Word16 length, /* i : length of spectrum (32 or 48 kHz samplerate) Q0 */
|
||||
const Word16 *sfmsize /* i : band length Q0 */
|
||||
)
|
||||
{
|
||||
Word16 i;
|
||||
Word16 total, tmp;
|
||||
Word16 diff;
|
||||
|
||||
total = (Word16)0;
|
||||
move16();
|
||||
FOR (i = 0; i < nb_sfm; i++)
|
||||
{
|
||||
tmp = extract_l(L_mult0(R[i], sfmsize[i]));
|
||||
Rsubband[i] = shl(tmp, 3);
|
||||
move16();
|
||||
total = add(total, tmp);
|
||||
}
|
||||
*sum = total;
|
||||
|
||||
IF ( sub(length, L_FRAME32k) <= 0 )
|
||||
{
|
||||
diff = sub(v, *sum);
|
||||
i = (Word16)0;
|
||||
move16();
|
||||
WHILE ( diff > 0 )
|
||||
{
|
||||
IF ( R[i] > 0 )
|
||||
{
|
||||
Rsubband[i] = add(Rsubband[i], 8);
|
||||
move16();
|
||||
diff = sub(diff, 1);
|
||||
*sum = add(*sum, 1);
|
||||
}
|
||||
i = add(i, 1);
|
||||
if ( sub(i, nb_sfm) >= 0 )
|
||||
{
|
||||
i = (Word16)0;
|
||||
move16();
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
440
src/libs/libevs/lib_com/bits_alloc.cpp
Executable file → Normal file
440
src/libs/libevs/lib_com/bits_alloc.cpp
Executable file → Normal file
@@ -1,384 +1,308 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
EVS Codec 3GPP TS26.443 Nov 13, 2018. Version 12.11.0 / 13.7.0 / 14.3.0 / 15.1.0
|
||||
====================================================================================*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <assert.h>
|
||||
#include "options.h"
|
||||
#include "prot_fx.h"
|
||||
#include "basop_util.h"
|
||||
#include "stl.h"
|
||||
#include "options.h"
|
||||
#include "rom_com_fx.h"
|
||||
#include "rom_com.h"
|
||||
#include "prot.h"
|
||||
|
||||
/*-------------------------------------------------------------------*
|
||||
* Local function
|
||||
*--------------------------------------------------------------------*/
|
||||
|
||||
static int BITS_ALLOC_adjust_acelp_fixed_cdk( int bits_frame, int *fixed_cdk_index, int nb_subfr );
|
||||
|
||||
|
||||
/*
|
||||
* function BITS_ALLOC_init_config_acelp()
|
||||
*
|
||||
* description: initial configuration for ACELP
|
||||
*
|
||||
* return: void
|
||||
*/
|
||||
/*-------------------------------------------------------------------*
|
||||
* BITS_ALLOC_init_config_acelp()
|
||||
*
|
||||
* initial configuration for Mode 2 ACELP
|
||||
*--------------------------------------------------------------------*/
|
||||
|
||||
void BITS_ALLOC_init_config_acelp(
|
||||
const Word32 bit_rate,
|
||||
const Word8 narrowBand,
|
||||
const Word16 nb_subfr,
|
||||
ACELP_config *pConfigAcelp /*o: configuration structure of ACELP*/
|
||||
int bit_rate,
|
||||
int narrowBand,
|
||||
int nb_subfr,
|
||||
ACELP_config *acelp_cfg /*o: configuration structure of ACELP*/
|
||||
)
|
||||
{
|
||||
Word8 rate_mode_index;
|
||||
short rate_mode_index;
|
||||
|
||||
if( bit_rate <= ACELP_9k60 )
|
||||
{
|
||||
rate_mode_index=0;
|
||||
}
|
||||
else
|
||||
{
|
||||
rate_mode_index=1;
|
||||
}
|
||||
|
||||
move16();
|
||||
move16();
|
||||
move16();
|
||||
rate_mode_index=(bit_rate > ACELP_9k60);
|
||||
|
||||
pConfigAcelp->mode_index=rate_mode_index;
|
||||
|
||||
acelp_cfg->mode_index=rate_mode_index;
|
||||
|
||||
/*LPC: midLpc should be swithced off?*/
|
||||
pConfigAcelp->midLpc_enable = 1;
|
||||
move16();
|
||||
acelp_cfg->midLpc_enable = 1;
|
||||
|
||||
/*ACELP ICB config*/
|
||||
test();
|
||||
IF( (rate_mode_index==0) || narrowBand != 0 )
|
||||
if( (rate_mode_index==0) || (narrowBand==1) )
|
||||
{
|
||||
move16();
|
||||
move16();
|
||||
move16();
|
||||
move16();
|
||||
move16();
|
||||
move16();
|
||||
pConfigAcelp->pre_emphasis = 1;
|
||||
pConfigAcelp->formant_enh = 1;
|
||||
pConfigAcelp->formant_enh_num = FORMANT_SHARPENING_G1;
|
||||
pConfigAcelp->formant_enh_den = FORMANT_SHARPENING_G2;
|
||||
pConfigAcelp->formant_tilt = 0;
|
||||
pConfigAcelp->voice_tilt = 0;
|
||||
acelp_cfg->pre_emphasis = 1;
|
||||
acelp_cfg->formant_enh = 1;
|
||||
acelp_cfg->formant_enh_num = FORMANT_SHARPENING_G1;
|
||||
acelp_cfg->formant_enh_den = FORMANT_SHARPENING_G2;
|
||||
acelp_cfg->formant_tilt = 0;
|
||||
acelp_cfg->voice_tilt = 0;
|
||||
}
|
||||
ELSE
|
||||
else
|
||||
{
|
||||
move16();
|
||||
move16();
|
||||
move16();
|
||||
move16();
|
||||
move16();
|
||||
move16();
|
||||
pConfigAcelp->pre_emphasis = 0;
|
||||
pConfigAcelp->formant_enh = 1;
|
||||
pConfigAcelp->formant_enh_num = FORMANT_SHARPENING_G1;
|
||||
pConfigAcelp->formant_enh_den = FORMANT_SHARPENING_G2;
|
||||
pConfigAcelp->formant_tilt = 1;
|
||||
pConfigAcelp->voice_tilt = 1;
|
||||
acelp_cfg->pre_emphasis = 0;
|
||||
acelp_cfg->formant_enh = 1;
|
||||
acelp_cfg->formant_enh_num = FORMANT_SHARPENING_G1;
|
||||
acelp_cfg->formant_enh_den = FORMANT_SHARPENING_G2;
|
||||
acelp_cfg->formant_tilt = 1;
|
||||
acelp_cfg->voice_tilt = 1;
|
||||
}
|
||||
|
||||
/*Wide band @ 16kHz*/
|
||||
IF ( sub(nb_subfr,NB_SUBFR16k) == 0 )
|
||||
if ( nb_subfr == NB_SUBFR16k )
|
||||
{
|
||||
move16();
|
||||
move16();
|
||||
move16();
|
||||
move16();
|
||||
move16();
|
||||
move16();
|
||||
pConfigAcelp->pre_emphasis = 1;
|
||||
pConfigAcelp->formant_enh = 1;
|
||||
pConfigAcelp->formant_enh_num = FORMANT_SHARPENING_G1_16k;
|
||||
pConfigAcelp->formant_enh_den = FORMANT_SHARPENING_G2_16k;
|
||||
pConfigAcelp->formant_tilt = 0;
|
||||
pConfigAcelp->voice_tilt = 2;
|
||||
acelp_cfg->pre_emphasis = 1;
|
||||
acelp_cfg->formant_enh = 1;
|
||||
acelp_cfg->formant_enh_num = FORMANT_SHARPENING_G1_16k;
|
||||
acelp_cfg->formant_enh_den = FORMANT_SHARPENING_G2_16k;
|
||||
acelp_cfg->formant_tilt = 0;
|
||||
acelp_cfg->voice_tilt = 2;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------*
|
||||
* BITS_ALLOC_config_acelp()
|
||||
*
|
||||
* configure all Mode 2 ACELP modes and allocate the bits
|
||||
*--------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* function BITS_ALLOC_config_acelp()
|
||||
*
|
||||
* description: configure all acelp modes and allocate the bits
|
||||
*
|
||||
* return: bit demand
|
||||
*/
|
||||
Word16 BITS_ALLOC_config_acelp(
|
||||
const Word16 bits_frame, /*i: remaining bit budget for the frame*/
|
||||
const Word16 coder_type, /*i: acelp coder type*/
|
||||
ACELP_config *pConfigAcelp, /*i/o: configuration structure of ACELP*/
|
||||
const Word16 narrowBand,
|
||||
const Word16 nb_subfr
|
||||
int BITS_ALLOC_config_acelp(
|
||||
const int bits_frame, /* i : remaining bit budget for the frame */
|
||||
const short coder_type, /* i : acelp extended mode index */
|
||||
ACELP_config *acelp_cfg, /* i/o: configuration structure of ACELP */
|
||||
const short narrowBand, /* i : narrowband flag */
|
||||
const short nb_subfr /* i : number of subframes */
|
||||
)
|
||||
{
|
||||
Word16 mode_index;
|
||||
Word16 band_index;
|
||||
Word16 i;
|
||||
Word16 remaining_bits, bits;
|
||||
short mode_index;
|
||||
short band_index;
|
||||
short i;
|
||||
short remaining_bits, bits;
|
||||
|
||||
/*Sanity check*/
|
||||
|
||||
|
||||
move16();
|
||||
move16();
|
||||
move16();
|
||||
mode_index = pConfigAcelp->mode_index;
|
||||
mode_index = acelp_cfg->mode_index;
|
||||
band_index = (narrowBand==0);
|
||||
bits=0;
|
||||
bits = 0;
|
||||
|
||||
IF ( band_index==0 )
|
||||
if ( band_index==0 )
|
||||
{
|
||||
move16();
|
||||
pConfigAcelp->formant_enh = 1;
|
||||
if(sub(coder_type,INACTIVE) == 0)
|
||||
if(coder_type == INACTIVE)
|
||||
{
|
||||
move16();
|
||||
pConfigAcelp->formant_enh = 0;
|
||||
acelp_cfg->formant_enh = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
acelp_cfg->formant_enh = 1;
|
||||
}
|
||||
}
|
||||
|
||||
IF ( s_and(sub(band_index,1)==0, sub(nb_subfr,4)==0) )
|
||||
if( band_index==1 && nb_subfr == NB_SUBFR )
|
||||
{
|
||||
IF(sub(coder_type,INACTIVE) == 0)
|
||||
|
||||
if( coder_type == INACTIVE)
|
||||
{
|
||||
pConfigAcelp->pre_emphasis = 0;
|
||||
move16();
|
||||
pConfigAcelp->formant_enh = 0;
|
||||
move16();
|
||||
pConfigAcelp->formant_enh_num = FORMANT_SHARPENING_G1_16k;
|
||||
move16();
|
||||
pConfigAcelp->voice_tilt = 1;
|
||||
move16();
|
||||
pConfigAcelp->formant_tilt = 1;
|
||||
move16();
|
||||
acelp_cfg->pre_emphasis = 0;
|
||||
acelp_cfg->formant_enh = 0;
|
||||
acelp_cfg->formant_enh_num = FORMANT_SHARPENING_G1_16k;
|
||||
acelp_cfg->formant_tilt = 1;
|
||||
acelp_cfg->voice_tilt = 1;
|
||||
}
|
||||
ELSE
|
||||
else
|
||||
{
|
||||
pConfigAcelp->pre_emphasis = 1;
|
||||
move16();
|
||||
pConfigAcelp->formant_enh = 1;
|
||||
move16();
|
||||
pConfigAcelp->formant_enh_num = FORMANT_SHARPENING_G1;
|
||||
move16();
|
||||
pConfigAcelp->voice_tilt = 0;
|
||||
move16();
|
||||
pConfigAcelp->formant_tilt = 0;
|
||||
move16();
|
||||
acelp_cfg->pre_emphasis = 1;
|
||||
acelp_cfg->formant_enh = 1;
|
||||
acelp_cfg->formant_enh_num = FORMANT_SHARPENING_G1;
|
||||
acelp_cfg->formant_tilt = 0;
|
||||
acelp_cfg->voice_tilt = 0;
|
||||
}
|
||||
}
|
||||
IF (sub(coder_type,UNVOICED) == 0 )
|
||||
{
|
||||
IF(sub(ACELP_GAINS_MODE[mode_index][band_index][coder_type], 6) == 0)
|
||||
{
|
||||
pConfigAcelp->pitch_sharpening = 0;
|
||||
move16();
|
||||
pConfigAcelp->phase_scrambling = 1;
|
||||
move16();
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
pConfigAcelp->pitch_sharpening = 0;
|
||||
move16();
|
||||
pConfigAcelp->phase_scrambling = 0;
|
||||
move16();
|
||||
}
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
pConfigAcelp->pitch_sharpening = 1;
|
||||
move16();
|
||||
pConfigAcelp->phase_scrambling = 0;
|
||||
move16();
|
||||
}
|
||||
|
||||
IF(sub(coder_type,ACELP_MODE_MAX) > 0) /* keep pitch sharpening for RF_ALLPRED mode */
|
||||
if( coder_type == UNVOICED )
|
||||
{
|
||||
pConfigAcelp->pitch_sharpening = 0;
|
||||
pConfigAcelp->phase_scrambling = 0;
|
||||
if( ACELP_GAINS_MODE[mode_index][band_index][coder_type]==6 )
|
||||
{
|
||||
acelp_cfg->pitch_sharpening = 0;
|
||||
acelp_cfg->phase_scrambling = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
acelp_cfg->pitch_sharpening = 0;
|
||||
acelp_cfg->phase_scrambling = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
acelp_cfg->pitch_sharpening = 1;
|
||||
acelp_cfg->phase_scrambling = 0;
|
||||
}
|
||||
|
||||
if( coder_type > ACELP_MODE_MAX )
|
||||
{
|
||||
/* keep pitch sharpening for RF_ALLPRED mode */
|
||||
acelp_cfg->pitch_sharpening = 0;
|
||||
acelp_cfg->phase_scrambling = 0;
|
||||
}
|
||||
|
||||
/*Allocate bits and different modes*/
|
||||
move16();
|
||||
pConfigAcelp->bpf_mode=ACELP_BPF_MODE[mode_index][band_index][coder_type];
|
||||
bits = add(bits, ACELP_BPF_BITS[pConfigAcelp->bpf_mode]);
|
||||
acelp_cfg->bpf_mode=ACELP_BPF_MODE[mode_index][band_index][coder_type];
|
||||
bits+=ACELP_BPF_BITS[acelp_cfg->bpf_mode];
|
||||
|
||||
move16();
|
||||
move16();
|
||||
pConfigAcelp->nrg_mode=ACELP_NRG_MODE[mode_index][band_index][coder_type];
|
||||
pConfigAcelp->nrg_bits=ACELP_NRG_BITS[pConfigAcelp->nrg_mode];
|
||||
bits = add(bits, pConfigAcelp->nrg_bits);
|
||||
acelp_cfg->nrg_mode=ACELP_NRG_MODE[mode_index][band_index][coder_type];
|
||||
acelp_cfg->nrg_bits=ACELP_NRG_BITS[acelp_cfg->nrg_mode];
|
||||
bits+=acelp_cfg->nrg_bits;
|
||||
|
||||
move16();
|
||||
pConfigAcelp->ltp_mode=ACELP_LTP_MODE[mode_index][band_index][coder_type];
|
||||
acelp_cfg->ltp_mode=ACELP_LTP_MODE[mode_index][band_index][coder_type];
|
||||
acelp_cfg->ltp_bits=0;
|
||||
acelp_cfg->ltf_mode=ACELP_LTF_MODE[mode_index][band_index][coder_type];
|
||||
acelp_cfg->ltf_bits=ACELP_LTF_BITS[acelp_cfg->ltf_mode];
|
||||
|
||||
move16();
|
||||
pConfigAcelp->ltp_bits=0;
|
||||
|
||||
move16();
|
||||
pConfigAcelp->ltf_mode=ACELP_LTF_MODE[mode_index][band_index][coder_type];
|
||||
|
||||
move16();
|
||||
pConfigAcelp->ltf_bits=ACELP_LTF_BITS[pConfigAcelp->ltf_mode];
|
||||
if ( s_and(sub(nb_subfr,5)==0, sub(pConfigAcelp->ltf_bits,4)==0) )
|
||||
if( nb_subfr == NB_SUBFR16k && acelp_cfg->ltf_bits == 4 )
|
||||
{
|
||||
pConfigAcelp->ltf_bits = add(pConfigAcelp->ltf_bits,1);
|
||||
acelp_cfg->ltf_bits++;
|
||||
}
|
||||
bits = add(bits,pConfigAcelp->ltf_bits);
|
||||
bits+=acelp_cfg->ltf_bits;
|
||||
|
||||
|
||||
FOR ( i=0; i<nb_subfr; i++ )
|
||||
for ( i=0; i<nb_subfr; i++ )
|
||||
{
|
||||
pConfigAcelp->gains_mode[i] = ACELP_GAINS_MODE[mode_index][band_index][coder_type];
|
||||
move16();
|
||||
acelp_cfg->gains_mode[i] = ACELP_GAINS_MODE[mode_index][band_index][coder_type];
|
||||
|
||||
/* skip subframe 1, 3 gain encoding, and use from subframe 0, and 3, respectively */
|
||||
test();
|
||||
test();
|
||||
IF(sub(coder_type,ACELP_MODE_MAX) >= 0 && (sub(i,1) == 0 || sub(i,3) == 0))
|
||||
if(coder_type >= ACELP_MODE_MAX && (i == 1 || i == 3))
|
||||
{
|
||||
pConfigAcelp->gains_mode[i] = 0;
|
||||
acelp_cfg->gains_mode[i] = 0;
|
||||
}
|
||||
|
||||
bits = add(bits, ACELP_GAINS_BITS[pConfigAcelp->gains_mode[i]]);
|
||||
|
||||
move16();
|
||||
bits = add(bits, ACELP_LTP_BITS_SFR[pConfigAcelp->ltp_mode][i]);
|
||||
pConfigAcelp->ltp_bits= add( pConfigAcelp->ltp_bits,ACELP_LTP_BITS_SFR[pConfigAcelp->ltp_mode][i]);
|
||||
bits += ACELP_GAINS_BITS[acelp_cfg->gains_mode[i]];
|
||||
bits += ACELP_LTP_BITS_SFR[acelp_cfg->ltp_mode][i];
|
||||
acelp_cfg->ltp_bits += ACELP_LTP_BITS_SFR[acelp_cfg->ltp_mode][i];
|
||||
}
|
||||
|
||||
/*Innovation*/
|
||||
|
||||
if ( sub(bits_frame,bits) < 0)
|
||||
if( bits_frame < bits )
|
||||
{
|
||||
printf("Warning: bits per frame too low\n");
|
||||
printf("\nWarning: bits per frame too low\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
IF( sub(coder_type,RF_ALLPRED) == 0 )
|
||||
if( coder_type == RF_ALLPRED )
|
||||
{
|
||||
set16_fx(pConfigAcelp->fixed_cdk_index, -1, nb_subfr);
|
||||
set_i(acelp_cfg->fixed_cdk_index, -1, nb_subfr);
|
||||
}
|
||||
ELSE IF ( sub(coder_type,RF_GENPRED) == 0 )
|
||||
else if ( coder_type == RF_GENPRED )
|
||||
{
|
||||
pConfigAcelp->fixed_cdk_index[0] = 0; /* 7 bits */
|
||||
pConfigAcelp->fixed_cdk_index[1] = -1;
|
||||
pConfigAcelp->fixed_cdk_index[2] = 0; /* 7 bits */
|
||||
pConfigAcelp->fixed_cdk_index[3] = -1;
|
||||
pConfigAcelp->fixed_cdk_index[4] = -1;
|
||||
bits = add(bits,14);
|
||||
acelp_cfg->fixed_cdk_index[0] = 0; /* 7 bits */
|
||||
acelp_cfg->fixed_cdk_index[1] = -1;
|
||||
acelp_cfg->fixed_cdk_index[2] = 0; /* 7 bits */
|
||||
acelp_cfg->fixed_cdk_index[3] = -1;
|
||||
acelp_cfg->fixed_cdk_index[4] = -1;
|
||||
bits += 14;
|
||||
}
|
||||
ELSE IF( sub(coder_type,RF_NOPRED) == 0 )
|
||||
else if( coder_type == RF_NOPRED )
|
||||
{
|
||||
set16_fx(pConfigAcelp->fixed_cdk_index, 0, nb_subfr);
|
||||
bits = add(bits,28);
|
||||
set_i(acelp_cfg->fixed_cdk_index, 0, nb_subfr);
|
||||
bits += 28;
|
||||
}
|
||||
ELSE
|
||||
else
|
||||
{
|
||||
bits = add(bits, BITS_ALLOC_adjust_acelp_fixed_cdk(sub(bits_frame,bits), pConfigAcelp->fixed_cdk_index, nb_subfr ));
|
||||
bits += BITS_ALLOC_adjust_acelp_fixed_cdk(bits_frame - bits, acelp_cfg->fixed_cdk_index, nb_subfr );
|
||||
}
|
||||
|
||||
remaining_bits = sub(bits_frame, bits);
|
||||
remaining_bits = bits_frame-bits;
|
||||
|
||||
/*Sanity check*/
|
||||
if (remaining_bits<0)
|
||||
if( remaining_bits < 0 )
|
||||
{
|
||||
move16();
|
||||
bits = -1;
|
||||
}
|
||||
|
||||
|
||||
return(bits);
|
||||
return( bits );
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------*
|
||||
* BITS_ALLOC_adjust_acelp_fixed_cdk()
|
||||
*
|
||||
*
|
||||
*--------------------------------------------------------------------*/
|
||||
|
||||
static
|
||||
Word16 BITS_ALLOC_adjust_generic(
|
||||
const Word16 bits_frame, /*i: bit budget*/
|
||||
Word16 *fixed_cdk_index,
|
||||
const Word16 nb_subfr,
|
||||
const Word16 *pulseconfigbits,
|
||||
const Word16 pulseconfig_size
|
||||
static int BITS_ALLOC_adjust_acelp_fixed_cdk(
|
||||
int bits_frame, /*i: bit budget*/
|
||||
int *fixed_cdk_index,
|
||||
int nb_subfr
|
||||
)
|
||||
{
|
||||
Word16 bits_subframe2, inb_subfr;
|
||||
Word16 sfr, k, bitsused, bits_currsubframe;
|
||||
int bits_subframe2;
|
||||
int sfr, k, bitsused, bits_currsubframe;
|
||||
|
||||
bits_subframe2 = bits_frame;
|
||||
move16();
|
||||
inb_subfr = 8192/*1.0f/NB_SUBFR Q15*/;
|
||||
move16();
|
||||
if ( sub(nb_subfr,NB_SUBFR16k) == 0 )
|
||||
{
|
||||
inb_subfr = 6554/*1.0f/NB_SUBFR16k Q15*/;
|
||||
move16();
|
||||
}
|
||||
|
||||
IF ( sub(bits_subframe2, i_mult2(pulseconfigbits[0], nb_subfr)) < 0 ) /* not in final code - not instrumented */
|
||||
if( bits_subframe2 < ACELP_FIXED_CDK_BITS(0)*nb_subfr )
|
||||
{
|
||||
return add(bits_frame,1); /* Not enough bits for lowest mode. -> trigger alarm*/
|
||||
return(bits_frame+1 ); /* Not enough bits for lowest mode. -> trigger alarm*/
|
||||
}
|
||||
|
||||
/* search cdk-index for first subframe */
|
||||
FOR (k=0; k<pulseconfig_size-1; k++)
|
||||
for (k=0; k<ACELP_FIXED_CDK_NB-1; k++)
|
||||
{
|
||||
|
||||
IF (i_mult2(pulseconfigbits[k], nb_subfr) > bits_subframe2)
|
||||
if (ACELP_FIXED_CDK_BITS(k)*nb_subfr > bits_subframe2)
|
||||
{
|
||||
k = sub(k,1); /* previous mode did not exceed bit-budget */
|
||||
BREAK;
|
||||
k--; /* previous mode did not exceed bit-budget */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i_mult2(pulseconfigbits[k], nb_subfr) > bits_subframe2)
|
||||
if( ACELP_FIXED_CDK_BITS(k)*nb_subfr > bits_subframe2 )
|
||||
{
|
||||
k = sub(k,1); /* previous mode did not exceed bit-budget */
|
||||
k--; /* previous mode did not exceed bit-budget */
|
||||
}
|
||||
|
||||
move16();
|
||||
fixed_cdk_index[0] = k;
|
||||
bitsused = i_mult2(pulseconfigbits[k], nb_subfr);
|
||||
bitsused = ACELP_FIXED_CDK_BITS(k);
|
||||
|
||||
FOR (sfr=1; sfr < nb_subfr; sfr++)
|
||||
for (sfr=1; sfr < nb_subfr; sfr++)
|
||||
{
|
||||
/*bits_currsubframe = (int)(((float)sfr+1.0f)*bits_subframe) - bitsused;*/
|
||||
bits_currsubframe = sub(add(i_mult2(sfr, bits_subframe2), bits_subframe2), bitsused);
|
||||
bits_currsubframe = (sfr*bits_subframe2 + bits_subframe2) - bitsused*nb_subfr;
|
||||
|
||||
/* try increasing mode while below threshold */
|
||||
WHILE ( (sub(k, pulseconfig_size-1) < 0) && (sub(i_mult2(pulseconfigbits[add(k,1)], nb_subfr),bits_currsubframe) <= 0) )
|
||||
while ( (k < ACELP_FIXED_CDK_NB-1) && (ACELP_FIXED_CDK_BITS(k+1)*nb_subfr <= bits_currsubframe) )
|
||||
{
|
||||
test();
|
||||
k = add(k,1);
|
||||
k++;
|
||||
}
|
||||
|
||||
/* try decreasing mode until below threshold */
|
||||
WHILE (i_mult2(pulseconfigbits[k], nb_subfr) > bits_currsubframe)
|
||||
while (ACELP_FIXED_CDK_BITS(k)*nb_subfr > bits_currsubframe)
|
||||
{
|
||||
k = sub(k,1);
|
||||
|
||||
IF (k == 0)
|
||||
k--;
|
||||
if ( k == 0 )
|
||||
{
|
||||
BREAK;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* store mode */
|
||||
move16();
|
||||
fixed_cdk_index[sfr] = k;
|
||||
bitsused = add(bitsused, i_mult2(pulseconfigbits[k], nb_subfr));
|
||||
bitsused += ACELP_FIXED_CDK_BITS(k);
|
||||
}
|
||||
|
||||
return mult_r(bitsused, inb_subfr);
|
||||
}
|
||||
|
||||
Word16 BITS_ALLOC_adjust_acelp_fixed_cdk(
|
||||
const Word16 bits_frame, /*i: bit budget*/
|
||||
Word16 *fixed_cdk_index,
|
||||
const Word16 nb_subfr
|
||||
)
|
||||
{
|
||||
Word16 bitsused;
|
||||
|
||||
|
||||
bitsused = BITS_ALLOC_adjust_generic(bits_frame, fixed_cdk_index, nb_subfr, ACELP_CDK_BITS, ACELP_FIXED_CDK_NB);
|
||||
|
||||
|
||||
return bitsused;
|
||||
}
|
||||
|
||||
|
||||
1925
src/libs/libevs/lib_com/bitstream_fx.cpp → src/libs/libevs/lib_com/bitstream.cpp
Executable file → Normal file
1925
src/libs/libevs/lib_com/bitstream_fx.cpp → src/libs/libevs/lib_com/bitstream.cpp
Executable file → Normal file
File diff suppressed because it is too large
Load Diff
273
src/libs/libevs/lib_com/calc_st_com.cpp
Normal file
273
src/libs/libevs/lib_com/calc_st_com.cpp
Normal file
@@ -0,0 +1,273 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.443 Nov 13, 2018. Version 12.11.0 / 13.7.0 / 14.3.0 / 15.1.0
|
||||
====================================================================================*/
|
||||
|
||||
#include <math.h>
|
||||
#include "options.h"
|
||||
#include "cnst.h"
|
||||
#include "prot.h"
|
||||
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* calc_rc0_h()
|
||||
*
|
||||
* computes 1st parcor from composed filter impulse response
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
static void calc_rc0_h(
|
||||
const float *h, /* i : impulse response of composed filter */
|
||||
float *rc0 /* o : 1st parcor */
|
||||
)
|
||||
{
|
||||
float acf0, acf1;
|
||||
float temp, temp2;
|
||||
const float *ptrs;
|
||||
int i;
|
||||
|
||||
/* computation of the autocorrelation function acf */
|
||||
temp = (float) 0.;
|
||||
for (i = 0; i < LONG_H_ST; i++)
|
||||
{
|
||||
temp += h[i] * h[i];
|
||||
}
|
||||
acf0 = temp;
|
||||
|
||||
temp = (float) 0.;
|
||||
ptrs = h;
|
||||
for (i = 0; i < LONG_H_ST - 1; i++)
|
||||
{
|
||||
temp2 = *ptrs++;
|
||||
temp += temp2 * (*ptrs);
|
||||
}
|
||||
acf1 = temp;
|
||||
|
||||
/* Initialisation of the calculation */
|
||||
if (acf0 == (float) 0.)
|
||||
{
|
||||
*rc0 = (float) 0.;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Compute 1st parcor */
|
||||
if (acf0 < (float) fabs (acf1))
|
||||
{
|
||||
*rc0 = (float) 0.0;
|
||||
return;
|
||||
}
|
||||
*rc0 = -acf1 / acf0;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* calc_st_filt()
|
||||
*
|
||||
* computes impulse response of A(gamma2) / A(gamma1)
|
||||
* controls gain : computation of energy impulse response as
|
||||
* SUMn (abs (h[n])) and computes parcor0
|
||||
*---------------------------------------------------------------------------- */
|
||||
|
||||
void calc_st_filt(
|
||||
const float *apond2, /* i : coefficients of numerator */
|
||||
const float *apond1, /* i : coefficients of denominator */
|
||||
float *parcor0, /* o : 1st parcor calcul. on composed filter */
|
||||
float *sig_ltp_ptr, /* i/o: input of 1/A(gamma1) : scaled by 1/g0 */
|
||||
float *mem_zero, /* i/o: All zero memory */
|
||||
const short L_subfr, /* i : the length of subframe */
|
||||
const short extl /* i : extension layer info */
|
||||
|
||||
)
|
||||
{
|
||||
float h[LONG_H_ST];
|
||||
float g0, temp;
|
||||
int i;
|
||||
|
||||
/* compute i.r. of composed filter apond2 / apond1 */
|
||||
if( extl == SWB_TBE )
|
||||
{
|
||||
syn_filt( apond1, LPC_SHB_ORDER, apond2, h, LONG_H_ST, mem_zero, 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
syn_filt( apond1, M, apond2, h, LONG_H_ST, mem_zero, 0 );
|
||||
}
|
||||
|
||||
/* compute 1st parcor */
|
||||
calc_rc0_h( h, parcor0 );
|
||||
|
||||
/* compute g0 */
|
||||
g0 = (float) 0.;
|
||||
for (i = 0; i < LONG_H_ST; i++)
|
||||
{
|
||||
g0 += (float) fabs (h[i]);
|
||||
}
|
||||
|
||||
/* Scale signal input of 1/A(gamma1) */
|
||||
if (g0 > (float) 1.)
|
||||
{
|
||||
temp = (float) 1. / g0;
|
||||
|
||||
for (i = 0; i < L_subfr; i++)
|
||||
{
|
||||
sig_ltp_ptr[i] = sig_ltp_ptr[i] * temp;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* filt_mu()
|
||||
*
|
||||
* tilt filtering with : (1 + mu z-1) * (1/1-|mu|)
|
||||
* computes y[n] = (1/1-|mu|) (x[n]+mu*x[n-1])
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
void filt_mu(
|
||||
const float *sig_in, /* i : signal (beginning at sample -1) */
|
||||
float *sig_out, /* o : output signal */
|
||||
const float parcor0, /* i : parcor0 (mu = parcor0 * gamma3) */
|
||||
const short L_subfr, /* i : the length of subframe */
|
||||
const short extl /* i : extension layer info */
|
||||
)
|
||||
{
|
||||
short n;
|
||||
float mu, ga, temp;
|
||||
const float *ptrs;
|
||||
|
||||
if( extl == SWB_TBE )
|
||||
{
|
||||
if(parcor0 > 0.0f)
|
||||
{
|
||||
mu = parcor0 * GAMMA3_PLUS_WB;
|
||||
}
|
||||
else
|
||||
{
|
||||
mu = parcor0 * GAMMA3_MINUS_WB;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (parcor0 > 0.0f)
|
||||
{
|
||||
mu = parcor0 * GAMMA3_PLUS;
|
||||
}
|
||||
else
|
||||
{
|
||||
mu = parcor0 * GAMMA3_MINUS;
|
||||
}
|
||||
}
|
||||
|
||||
ga = (float) 1. / ((float) 1. - (float) fabs (mu));
|
||||
|
||||
ptrs = sig_in; /* points on sig_in(-1) */
|
||||
|
||||
for (n = 0; n < L_subfr; n++)
|
||||
{
|
||||
temp = mu * (*ptrs++);
|
||||
temp += (*ptrs);
|
||||
sig_out[n] = ga * temp;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* scale_st()
|
||||
*
|
||||
* control of the subframe gain
|
||||
* gain[n] = AGC_FAC_FX * gain[n-1] + (1 - AGC_FAC_FX) g_in/g_out
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
void scale_st(
|
||||
const float *sig_in, /* i : postfilter input signal */
|
||||
float *sig_out, /* i/o: postfilter output signal */
|
||||
float *gain_prec, /* i/o: last value of gain for subframe */
|
||||
const short L_subfr, /* i : the length of subframe */
|
||||
const short extl /* i : extension layer info */
|
||||
)
|
||||
{
|
||||
int i;
|
||||
float gain_in, gain_out;
|
||||
float g0, gain;
|
||||
float agc_fac1_para = 0.0f;
|
||||
float agc_fac_para = 0.0f;
|
||||
|
||||
if( extl == SWB_TBE )
|
||||
{
|
||||
agc_fac1_para = AGC_FAC1_WB;
|
||||
agc_fac_para = AGC_FAC_WB;
|
||||
}
|
||||
else
|
||||
{
|
||||
agc_fac1_para = AGC_FAC1;
|
||||
agc_fac_para = AGC_FAC;
|
||||
}
|
||||
|
||||
/* compute input gain */
|
||||
gain_in = (float) 0.;
|
||||
for (i = 0; i < L_subfr; i++)
|
||||
{
|
||||
gain_in += (float) fabs (sig_in[i]);
|
||||
}
|
||||
|
||||
if ( gain_in == 0.0f )
|
||||
{
|
||||
g0 = 0.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Compute output gain */
|
||||
gain_out = 0.0f;
|
||||
for (i = 0; i < L_subfr; i++)
|
||||
{
|
||||
gain_out += (float) fabs (sig_out[i]);
|
||||
}
|
||||
|
||||
if (gain_out == 0.0f)
|
||||
{
|
||||
*gain_prec = 0.0f;
|
||||
return;
|
||||
}
|
||||
|
||||
g0 = gain_in / gain_out;
|
||||
g0 *= agc_fac1_para;
|
||||
}
|
||||
|
||||
/* compute gain(n) = AGC_FAC gain(n-1) + (1-AGC_FAC)gain_in/gain_out */
|
||||
/* sig_out(n) = gain(n) sig_out(n) */
|
||||
gain = *gain_prec;
|
||||
for (i = 0; i < L_subfr; i++)
|
||||
{
|
||||
gain *= agc_fac_para;
|
||||
gain += g0;
|
||||
sig_out[i] *= gain;
|
||||
}
|
||||
|
||||
*gain_prec = gain;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void blend_subfr2( float *sigIn1, float *sigIn2, float *sigOut)
|
||||
{
|
||||
|
||||
float fac1 = 1.f - (1.f / L_SUBFR);
|
||||
float fac2 = 0.f + (1.f / L_SUBFR);
|
||||
float step = 1.f / (L_SUBFR/2);
|
||||
int i;
|
||||
|
||||
for(i=0; i<L_SUBFR/2; i++)
|
||||
{
|
||||
sigOut[i] = fac1 * sigIn1[i] + fac2 * sigIn2[i];
|
||||
fac1 -= step;
|
||||
fac2 += step;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
88
src/libs/libevs/lib_com/cb_shape.cpp
Normal file
88
src/libs/libevs/lib_com/cb_shape.cpp
Normal file
@@ -0,0 +1,88 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.443 Nov 13, 2018. Version 12.11.0 / 13.7.0 / 14.3.0 / 15.1.0
|
||||
====================================================================================*/
|
||||
|
||||
#include "options.h"
|
||||
#include "cnst.h"
|
||||
#include "prot.h"
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------*
|
||||
* cb_shape()
|
||||
*
|
||||
* pre-emphasis, pitch sharpening and formant sharpening of the algebraic codebook
|
||||
*-------------------------------------------------------------------*/
|
||||
|
||||
void cb_shape(
|
||||
const short preemphFlag, /* i : flag for pre-emphasis */
|
||||
const short pitchFlag, /* i : flag for pitch sharpening */
|
||||
const short scramblingFlag, /* i : flag for phase scrambling */
|
||||
const short formantFlag, /* i : flag for formant sharpening */
|
||||
const short formantTiltFlag, /* i : flag for formant tilt */
|
||||
const float g1, /* i : formant sharpening numerator weighting */
|
||||
const float g2, /* i : formant sharpening denominator weighting */
|
||||
const float *p_Aq, /* i : LP filter coefficients */
|
||||
float *code, /* i/o: signal to shape */
|
||||
const float tilt_code, /* i : tilt of code */
|
||||
const float pt_pitch /* i : pointer to current subframe fractional pitch */
|
||||
)
|
||||
{
|
||||
float buff[M+L_SUBFR], A_num[M+1], A_den[M+1];
|
||||
float tmp, tilt;
|
||||
short i, round_T0;
|
||||
|
||||
/* pre-emphasize the algebraic codebook */
|
||||
if ( preemphFlag )
|
||||
{
|
||||
tmp = 0.0f;
|
||||
preemph( code, tilt_code, L_SUBFR, &tmp );
|
||||
}
|
||||
|
||||
/* pitch sharpening */
|
||||
if ( pitchFlag )
|
||||
{
|
||||
round_T0 = (short)(pt_pitch + 0.4f);
|
||||
for (i = round_T0; i < L_SUBFR; i++)
|
||||
{
|
||||
code[i] += code[i - round_T0] * PIT_SHARP;
|
||||
}
|
||||
}
|
||||
|
||||
/* phase scrambling filter */
|
||||
if ( scramblingFlag )
|
||||
{
|
||||
buff[0] = code[0];
|
||||
for (i = 1; i < L_SUBFR; i++)
|
||||
{
|
||||
buff[i] = code[i];
|
||||
code[i] = 0.7f * buff[i] + buff[i-1] - 0.7f * code[i-1];
|
||||
}
|
||||
}
|
||||
|
||||
/* formant sharpening (only on active speech) */
|
||||
if ( formantFlag || formantTiltFlag )
|
||||
{
|
||||
weight_a( p_Aq, A_num, g1, M );
|
||||
weight_a( p_Aq, A_den, g2, M );
|
||||
|
||||
set_f( buff, 0, M+L_SUBFR );
|
||||
|
||||
/* formant tilt */
|
||||
if( formantTiltFlag )
|
||||
{
|
||||
mvr2r( A_num, buff+M, M+1 );
|
||||
syn_filt( A_den, M, buff+M, buff+M, L_SUBFR, buff, 0 );
|
||||
tilt = get_gain( buff+M+1, buff+M, L_SUBFR-1, NULL );
|
||||
tmp = 0.0;
|
||||
preemph( code, 0.5f*tilt_code-0.25f*tilt, L_SUBFR, &tmp );
|
||||
}
|
||||
else
|
||||
{
|
||||
mvr2r( code, buff+M, L_SUBFR );
|
||||
residu( A_num, M, buff+M, code, L_SUBFR );
|
||||
syn_filt( A_den, M, code, code, L_SUBFR, buff, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -1,134 +0,0 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#include "options.h" /* Compilation switches */
|
||||
#include "cnst_fx.h" /* Common constants */
|
||||
#include "prot_fx.h" /* Function prototypes */
|
||||
#include "rom_com_fx.h" /* */
|
||||
|
||||
#include "stl.h"
|
||||
|
||||
/*
|
||||
* E_GAIN_f_pitch_sharpening
|
||||
*
|
||||
* Parameters:
|
||||
* x I/O: impulse response (or algebraic code)
|
||||
* pit_lag I: pitch lag
|
||||
*
|
||||
* Function:
|
||||
* Performs Pitch sharpening routine for one subframe.
|
||||
* pitch sharpening factor is 0.85
|
||||
*
|
||||
* Returns:
|
||||
* void
|
||||
*/
|
||||
static void E_GAIN_f_pitch_sharpening(Word16 *x, Word16 pit_lag, Word16 L_subfr)
|
||||
{
|
||||
Word16 i, tmp;
|
||||
|
||||
FOR (i = pit_lag; i < L_subfr; i++)
|
||||
{
|
||||
/*x[i] += x[i - pit_lag] * F_PIT_SHARP;*/
|
||||
tmp = mult_r(x[i - pit_lag], 27853/*F_PIT_SHARP Q15*/);
|
||||
x[i] = add(x[i],tmp);
|
||||
move16();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------*
|
||||
* cb_shape()
|
||||
*
|
||||
* pre-emphasis, pitch sharpening and formant sharpening of the algebraic codebook
|
||||
*-------------------------------------------------------------------*/
|
||||
|
||||
void cb_shape_fx(
|
||||
const Word16 preemphFlag, /* i : flag for pre-emphasis */
|
||||
const Word16 pitchFlag, /* i : flag for pitch sharpening */
|
||||
const Word16 scramblingFlag, /* i : flag for phase scrambling */
|
||||
const Word16 sharpFlag, /* i : flag for formant sharpening */
|
||||
const Word16 formantTiltFlag, /* i : flag for formant tilt */
|
||||
const Word16 g1, /* i : formant sharpening numerator weighting */
|
||||
const Word16 g2, /* i : formant sharpening denominator weighting */
|
||||
const Word16 *p_Aq, /* i : LP filter coefficients */
|
||||
Word16 *code, /* i/o: signal to shape */
|
||||
const Word16 tilt_code, /* i : tilt of code */
|
||||
const Word16 pt_pitch, /* i : pointer to current subframe fractional pitch */
|
||||
const Word16 shift
|
||||
)
|
||||
{
|
||||
Word16 tmp, buff[L_SUBFR+M], A_num[M+1], A_den[M+1];
|
||||
Word16 i;
|
||||
Word32 L_tmp;
|
||||
Word16 tilt, mu;
|
||||
tmp = 0;
|
||||
move16();
|
||||
|
||||
/* Pre-emphasis */
|
||||
IF( preemphFlag )
|
||||
{
|
||||
preemph_copy_fx(code, code, tilt_code, L_SUBFR, &tmp);
|
||||
}
|
||||
|
||||
/* pitch sharpening */
|
||||
IF( pitchFlag )
|
||||
{
|
||||
E_GAIN_f_pitch_sharpening( code, pt_pitch, L_SUBFR );
|
||||
}
|
||||
|
||||
/* phase scrambling filter */
|
||||
IF( scramblingFlag )
|
||||
{
|
||||
buff[0] = code[0];
|
||||
move16();
|
||||
FOR (i = 1; i < L_SUBFR; i++)
|
||||
{
|
||||
buff[i]=code[i];
|
||||
move16();
|
||||
/*code[i] = 0.7f*buff[i] + buff[i-1] - 0.7f*code[i-1]; */
|
||||
L_tmp = L_mult(22938, buff[i]);
|
||||
tmp = mac_r(L_tmp,-22938, code[i-1]);
|
||||
code[i] = add(tmp,buff[i-1]);
|
||||
move16();
|
||||
}
|
||||
}
|
||||
|
||||
test();
|
||||
IF ( sharpFlag || formantTiltFlag )
|
||||
{
|
||||
weight_a_fx( p_Aq, A_num, g1, M );
|
||||
weight_a_fx( p_Aq, A_den, g2, M );
|
||||
set16_fx(buff, 0, M+L_SUBFR);
|
||||
IF( formantTiltFlag )
|
||||
{
|
||||
Copy(A_num, buff+M, M+1);
|
||||
|
||||
E_UTIL_synthesis(1, A_den, buff+M, buff+M, L_SUBFR, buff, 0, M);
|
||||
|
||||
/*Compute tilt of formant enhancement*/
|
||||
tilt = extract_l(L_shr(get_gain(buff+M+1, buff+M, L_SUBFR-1),1));
|
||||
|
||||
/*Combine tilt of code and fe*/
|
||||
tmp = 0;
|
||||
move16();
|
||||
/*mu = 0.5f*tilt_code-0.25f*tilt;*/
|
||||
mu = sub(shr(tilt_code,1),shr(tilt,2));
|
||||
preemph_copy_fx(code, code, mu, L_SUBFR, &tmp);
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
Copy( code, buff, L_SUBFR );
|
||||
|
||||
Overflow = 0;
|
||||
move16();
|
||||
Residu3_lc_fx(A_num, M, buff, code, L_SUBFR, shift);
|
||||
{
|
||||
syn_filt_s_lc_fx(shift, A_den, code, code, L_SUBFR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
1920
src/libs/libevs/lib_com/cldfb.cpp
Executable file → Normal file
1920
src/libs/libevs/lib_com/cldfb.cpp
Executable file → Normal file
File diff suppressed because it is too large
Load Diff
557
src/libs/libevs/lib_com/cng_exc.cpp
Normal file
557
src/libs/libevs/lib_com/cng_exc.cpp
Normal file
@@ -0,0 +1,557 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.443 Nov 13, 2018. Version 12.11.0 / 13.7.0 / 14.3.0 / 15.1.0
|
||||
====================================================================================*/
|
||||
|
||||
#include <math.h>
|
||||
#include <assert.h>
|
||||
#include "options.h"
|
||||
#include "cnst.h"
|
||||
#include "prot.h"
|
||||
#include "rom_com.h"
|
||||
|
||||
/*---------------------------------------------------------------------*
|
||||
* Local constants
|
||||
*---------------------------------------------------------------------*/
|
||||
|
||||
#define A2 0.2f
|
||||
#define GAIN_VAR 0.000011f
|
||||
|
||||
/*-------------------------------------------------------*
|
||||
* CNG_exc()
|
||||
*
|
||||
* Comfort noise generation routine
|
||||
*-------------------------------------------------------*/
|
||||
|
||||
void CNG_exc(
|
||||
const long core_brate, /* i : core bitrate */
|
||||
const short L_frame, /* i : length of the frame */
|
||||
float *Enew, /* i/o: decoded SID energy */
|
||||
short *seed, /* i/o: random generator seed */
|
||||
float exc[], /* o : current non-enhanced excitation */
|
||||
float exc2[], /* o : current enhanced excitation */
|
||||
float *lp_ener, /* i/o: LP filtered E */
|
||||
const long last_core_brate, /* i : previous frame core bitrate */
|
||||
short *first_CNG, /* i/o: first CNG frame flag for energy init. */
|
||||
short *cng_ener_seed, /* i/o: random generator seed for CNG energy */
|
||||
float bwe_exc[], /* o : excitation for SWB TBE */
|
||||
const short allow_cn_step, /* i : allow CN step */
|
||||
short *last_allow_cn_step, /* i/o: last allow step */
|
||||
const short num_ho, /* i : number of selected hangover frames */
|
||||
float q_env[],
|
||||
float *lp_env,
|
||||
float *old_env,
|
||||
float *exc_mem,
|
||||
float *exc_mem1,
|
||||
short *sid_bw,
|
||||
short *cng_ener_seed1,
|
||||
float exc3[],
|
||||
short Opt_AMR_WB
|
||||
)
|
||||
{
|
||||
float enr;
|
||||
short i;
|
||||
float ener_lp;
|
||||
short i_subfr;
|
||||
short pit_max;
|
||||
float ftmp;
|
||||
float *ptR,*ptI;
|
||||
float fft_io[L_FRAME16k];
|
||||
float itmp[129];
|
||||
float env[NUM_ENV_CNG];
|
||||
float enr1;
|
||||
float denv[NUM_ENV_CNG];
|
||||
|
||||
/*------------------------------------------------------------------*
|
||||
* Initializations
|
||||
*------------------------------------------------------------------*/
|
||||
|
||||
if( L_frame == L_FRAME )
|
||||
{
|
||||
pit_max = PIT_MAX;
|
||||
}
|
||||
else /* L_frame == L_FRAME16k */
|
||||
{
|
||||
pit_max = PIT16k_MAX;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------*
|
||||
* Initialization of CNG energy for the first CNG frame
|
||||
*---------------------------------------------------------------------*/
|
||||
|
||||
if( *first_CNG == 0 )
|
||||
{
|
||||
if( core_brate == FRAME__NO_DATA )
|
||||
{
|
||||
/* needed only in decoder when the very first SID frame was erased and this frame is FRAME__NO_DATA frame */
|
||||
*Enew = dotp( exc-pit_max, exc-pit_max, pit_max ) / pit_max;
|
||||
}
|
||||
|
||||
*lp_ener = *Enew;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------*
|
||||
* Update CNG energy
|
||||
*---------------------------------------------------------------------*/
|
||||
|
||||
if( last_core_brate != SID_1k75 && last_core_brate != FRAME__NO_DATA && last_core_brate != SID_2k40 )
|
||||
{
|
||||
/* Partially reset CNG energy after active speech period */
|
||||
if ( allow_cn_step == 0 && *last_allow_cn_step == 0 )
|
||||
{
|
||||
if( num_ho < 3 || *Enew < 1.5f * *lp_ener )
|
||||
{
|
||||
*lp_ener = 0.8f * *lp_ener + 0.2f * *Enew;
|
||||
}
|
||||
else
|
||||
{
|
||||
*lp_ener = 0.95f * *lp_ener + 0.05f * *Enew;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*lp_ener = *Enew;
|
||||
*last_allow_cn_step = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* normal CNG update */
|
||||
if ( *last_allow_cn_step == 0 )
|
||||
{
|
||||
*lp_ener = (float)(A2 **Enew + (1-A2) **lp_ener);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( core_brate == SID_1k75 || core_brate == SID_2k40 )
|
||||
{
|
||||
*last_allow_cn_step = 0;
|
||||
}
|
||||
|
||||
*lp_ener = *Enew;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if ( allow_cn_step == 1 )
|
||||
{
|
||||
*last_allow_cn_step = 1;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------*
|
||||
* Generate white noise vector
|
||||
*---------------------------------------------------------------------*/
|
||||
|
||||
for ( i=0; i<L_frame; i++ )
|
||||
{
|
||||
exc2[i] = (float)own_random( seed );
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------*
|
||||
* Insert random variation for excitation energy
|
||||
* (random variation is scaled according to *lp_ener value)
|
||||
*------------------------------------------------------------*/
|
||||
|
||||
for ( i_subfr=0; i_subfr<L_frame; i_subfr += L_SUBFR )
|
||||
{
|
||||
ener_lp = ( (own_random( cng_ener_seed ) * (*lp_ener) ) * GAIN_VAR ) + (*lp_ener);
|
||||
|
||||
if( ener_lp < 0.0f)
|
||||
{
|
||||
ener_lp = 0.01f;
|
||||
}
|
||||
enr = dotp( &exc2[i_subfr], &exc2[i_subfr], L_SUBFR ) + 0.01f;
|
||||
|
||||
enr = (float)sqrt( ener_lp * L_SUBFR / enr );
|
||||
|
||||
for ( i=0; i<L_SUBFR; i++ )
|
||||
{
|
||||
exc2[i_subfr+i] *= enr;
|
||||
}
|
||||
}
|
||||
|
||||
if ( Opt_AMR_WB != 1 )
|
||||
{
|
||||
mvr2r( exc2, exc3, L_FRAME16k);
|
||||
|
||||
enr1 = (float)log10( *Enew*L_frame + 0.1f ) / (float)log10( 2.0f );
|
||||
|
||||
if ( core_brate == SID_2k40 )
|
||||
{
|
||||
if ( *sid_bw == 0 )
|
||||
{
|
||||
for ( i=0; i<NUM_ENV_CNG; i++ )
|
||||
{
|
||||
/* get quantized envelope */
|
||||
env[i] = pow(2.0f,(enr1 - q_env[i]));
|
||||
}
|
||||
}
|
||||
|
||||
/* initialize CNG envelope */
|
||||
if( *first_CNG == 0 && *sid_bw == 0 )
|
||||
{
|
||||
mvr2r(env, lp_env, NUM_ENV_CNG);
|
||||
}
|
||||
|
||||
if ( *sid_bw == 0 )
|
||||
{
|
||||
mvr2r(env, old_env, NUM_ENV_CNG);
|
||||
}
|
||||
}
|
||||
|
||||
for ( i=0; i<NUM_ENV_CNG; i++ )
|
||||
{
|
||||
/* get AR low-passed envelope */
|
||||
lp_env[i] = 0.9f*lp_env[i] + (1-0.9f)*old_env[i];
|
||||
}
|
||||
|
||||
/* calculate the spectrum of random excitation signal */
|
||||
mvr2r(exc2, fft_io, L_frame);
|
||||
|
||||
if ( L_frame == L_FRAME16k )
|
||||
{
|
||||
modify_Fs( fft_io, L_FRAME16k, 16000, fft_io, 12800, exc_mem1, 0 );
|
||||
}
|
||||
|
||||
fft_rel(fft_io, L_FFT, LOG2_L_FFT);
|
||||
ptR = &fft_io[1];
|
||||
ptI = &fft_io[L_FFT-1];
|
||||
for ( i=0; i<NUM_ENV_CNG; i++ )
|
||||
{
|
||||
env[i] = 2.0f*(*ptR **ptR + *ptI **ptI)/L_FFT;
|
||||
ptR++;
|
||||
ptI--;
|
||||
}
|
||||
|
||||
for ( i=0; i<NUM_ENV_CNG; i++ )
|
||||
{
|
||||
denv[i] = lp_env[i] + 2*(*lp_ener) - env[i];
|
||||
|
||||
if ( denv[i] < 0 )
|
||||
{
|
||||
denv[i] = 0;
|
||||
}
|
||||
}
|
||||
set_f(itmp, 0.0f, NUM_ENV_CNG);
|
||||
|
||||
set_f(fft_io, 0.0f, L_FFT);
|
||||
ptR = &fft_io[1];
|
||||
ptI = &fft_io[L_FFT-1];
|
||||
for (i=0; i<NUM_ENV_CNG; i++)
|
||||
{
|
||||
*ptR = own_random( cng_ener_seed1 );
|
||||
*ptI = own_random( cng_ener_seed1 );
|
||||
|
||||
env[i] = 2.0f*(*ptR **ptR + *ptI **ptI)/L_FFT;
|
||||
ptR++;
|
||||
ptI--;
|
||||
}
|
||||
|
||||
for ( i=0; i<NUM_ENV_CNG; i++ )
|
||||
{
|
||||
itmp[i] += own_random( cng_ener_seed1 )*denv[i]*0.000011f + denv[i];
|
||||
|
||||
if (itmp[i] < 0.0f)
|
||||
{
|
||||
itmp[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
ptR = &fft_io[1];
|
||||
ptI = &fft_io[L_FFT-1];
|
||||
for ( i=0; i<NUM_ENV_CNG; i++ )
|
||||
{
|
||||
*ptR *= sqrt(itmp[i]/env[i]);
|
||||
*ptI *= sqrt(itmp[i]/env[i]);
|
||||
|
||||
ptR++;
|
||||
ptI--;
|
||||
}
|
||||
|
||||
ifft_rel(fft_io, L_FFT, LOG2_L_FFT);
|
||||
|
||||
if ( L_frame == L_FRAME16k )
|
||||
{
|
||||
modify_Fs( fft_io, L_FFT, 12800, fft_io, 16000, exc_mem, 0 );
|
||||
}
|
||||
|
||||
enr1 = dotp( fft_io, fft_io, L_frame ) / L_frame;
|
||||
|
||||
/* add time domain randomization */
|
||||
for ( i_subfr=0; i_subfr<L_frame; i_subfr += L_SUBFR )
|
||||
{
|
||||
enr = dotp( &fft_io[i_subfr], &fft_io[i_subfr], L_SUBFR ) + 0.01f;
|
||||
ener_lp = ( (own_random( cng_ener_seed1 ) * (enr1) ) * 0.000011f ) + (enr1);
|
||||
ener_lp *= L_SUBFR;
|
||||
enr = (float)sqrt( ener_lp / enr );
|
||||
|
||||
if( last_core_brate != SID_2k40 && last_core_brate != SID_1k75 && last_core_brate != FRAME__NO_DATA && core_brate == SID_2k40 )
|
||||
{
|
||||
if ( enr > 1 )
|
||||
{
|
||||
enr = 1;
|
||||
}
|
||||
}
|
||||
|
||||
for ( i=0; i<L_SUBFR; i++ )
|
||||
{
|
||||
fft_io[i_subfr+i] *= enr;
|
||||
}
|
||||
}
|
||||
|
||||
for ( i=0; i<L_frame; i++ )
|
||||
{
|
||||
fft_io[i] = 0.75f*fft_io[i] + exc2[i];
|
||||
}
|
||||
|
||||
enr = (dotp( fft_io, fft_io, L_frame ) / L_frame) + 0.01f;
|
||||
enr = (*lp_ener)/enr;
|
||||
|
||||
if ( enr > 1 )
|
||||
{
|
||||
enr = 1;
|
||||
}
|
||||
|
||||
ftmp = sqrt(enr);
|
||||
for (i=0; i<L_frame; i++)
|
||||
{
|
||||
fft_io[i] *= ftmp;
|
||||
}
|
||||
|
||||
mvr2r( fft_io, exc2, L_frame );
|
||||
}
|
||||
if ( Opt_AMR_WB != 1 )
|
||||
{
|
||||
mvr2r( exc3, exc, L_frame );
|
||||
}
|
||||
else
|
||||
{
|
||||
mvr2r( exc2, exc, L_frame );
|
||||
}
|
||||
|
||||
if( L_frame == L_FRAME )
|
||||
{
|
||||
interp_code_5over2( exc2, bwe_exc, L_frame );
|
||||
}
|
||||
else
|
||||
{
|
||||
interp_code_4over2( exc2, bwe_exc, L_frame );
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------*
|
||||
* cng_params_postupd
|
||||
*
|
||||
* Post-update of CNG parameters
|
||||
*-------------------------------------------------------*/
|
||||
void cng_params_postupd(
|
||||
const short ho_circ_ptr, /* i : pointer for CNG averaging buffers */
|
||||
short *cng_buf_cnt, /* i/o: counter for CNG store buffers */
|
||||
const float *const cng_exc2_buf, /* i : Excitation buffer */
|
||||
const long *const cng_brate_buf, /* i : bit rate buffer */
|
||||
float ho_env_circ[] /* i/o: Envelope buffer */
|
||||
)
|
||||
{
|
||||
short i, j;
|
||||
const float *exc2;
|
||||
float fft_io[L_FFT];
|
||||
float sp[129];
|
||||
float *ptR,*ptI;
|
||||
float env[NUM_ENV_CNG];
|
||||
short CNG_mode;
|
||||
short ptr;
|
||||
float att;
|
||||
long last_active_brate;
|
||||
|
||||
ptr = ho_circ_ptr - *cng_buf_cnt + 1;
|
||||
if( ptr < 0 )
|
||||
{
|
||||
ptr += HO_HIST_SIZE;
|
||||
}
|
||||
|
||||
for( j = 0; j < *cng_buf_cnt; j++ )
|
||||
{
|
||||
exc2 = &cng_exc2_buf[ptr*L_FFT];
|
||||
last_active_brate = cng_brate_buf[ptr];
|
||||
|
||||
/* calculate the spectrum of residual signal */
|
||||
/* calculate the spectrum of residual signal */
|
||||
mvr2r(exc2, fft_io, L_FFT);
|
||||
|
||||
fft_rel(fft_io, L_FFT, LOG2_L_FFT);
|
||||
|
||||
ptR = &fft_io[1];
|
||||
ptI = &fft_io[L_FFT-1];
|
||||
for (i=0; i<NUM_ENV_CNG; i++)
|
||||
{
|
||||
sp[i] = 2.0f*(*ptR **ptR + *ptI **ptI)/L_FFT;
|
||||
ptR++;
|
||||
ptI--;
|
||||
}
|
||||
|
||||
mvr2r(sp,env,NUM_ENV_CNG);
|
||||
if( last_active_brate > ACELP_13k20 )
|
||||
{
|
||||
CNG_mode = 4;
|
||||
}
|
||||
else if( last_active_brate > ACELP_9k60 )
|
||||
{
|
||||
CNG_mode = 3;
|
||||
}
|
||||
else if( last_active_brate > ACELP_8k00 )
|
||||
{
|
||||
CNG_mode = 2;
|
||||
}
|
||||
else if( last_active_brate > ACELP_7k20 )
|
||||
{
|
||||
CNG_mode = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
CNG_mode = 0;
|
||||
}
|
||||
|
||||
att = 1/pow(2,ENR_ATT[CNG_mode]);
|
||||
|
||||
for ( i=0; i<NUM_ENV_CNG; i++ )
|
||||
{
|
||||
env[i] *= att;
|
||||
}
|
||||
|
||||
/* update the circular buffer of old residual envelope */
|
||||
mvr2r( env, &(ho_env_circ[(ho_circ_ptr)*NUM_ENV_CNG]), NUM_ENV_CNG );
|
||||
|
||||
ptr++;
|
||||
if(ptr == HO_HIST_SIZE)
|
||||
{
|
||||
ptr = 0;
|
||||
}
|
||||
}
|
||||
|
||||
*cng_buf_cnt = 0;
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-------------------------------------------------------*
|
||||
* cng_params_upd()
|
||||
*
|
||||
* update CNG parameters
|
||||
*-------------------------------------------------------*/
|
||||
|
||||
void cng_params_upd(
|
||||
const float lsp_new[], /* i : LSP parameters */
|
||||
const float exc2[], /* i : current enhanced excitation */
|
||||
const short L_frame, /* i : frame length */
|
||||
short *ho_circ_ptr, /* i/o: pointer for CNG averaging buffers */
|
||||
float ho_ener_circ[], /* o : energy buffer for CNG averaging */
|
||||
short *ho_circ_size, /* i/o: size of DTX hangover history buffer for averaging */
|
||||
float ho_lsp_circ[], /* o : old LSP buffer for CNG averaging */
|
||||
const short enc_dec_flag, /* i : Flag indicating encoder or decoder (ENC,DEC) */
|
||||
float ho_env_circ[], /* i/o: Envelope buffer */
|
||||
short *cng_buf_cnt, /* i/o: Counter of postponed FFT-processing instances */
|
||||
float cng_exc2_buf[], /* i/o: Excitation buffer */
|
||||
long cng_brate_buf[], /* i/o: last_active_brate buffer */
|
||||
const long last_active_brate /* i : Last active bit rate */
|
||||
)
|
||||
{
|
||||
float enr;
|
||||
float fft_io[L_FRAME16k];
|
||||
float sp[129];
|
||||
float *ptR,*ptI;
|
||||
float env[NUM_ENV_CNG];
|
||||
short i;
|
||||
short CNG_mode;
|
||||
float att;
|
||||
|
||||
/* update the pointer to circular buffer of old LSP vectors */
|
||||
(*ho_circ_ptr)++;
|
||||
if( *ho_circ_ptr == HO_HIST_SIZE )
|
||||
{
|
||||
*ho_circ_ptr = 0;
|
||||
}
|
||||
|
||||
/* update the circular buffer of old LSP vectors with the new LSP vector */
|
||||
mvr2r( lsp_new, &(ho_lsp_circ[(*ho_circ_ptr)*M]), M );
|
||||
|
||||
/* calculate the residual signal energy */
|
||||
enr = dotp( exc2, exc2, L_frame ) / L_frame;
|
||||
|
||||
/* update the circular buffer of old energies */
|
||||
ho_ener_circ[*ho_circ_ptr] = enr;
|
||||
|
||||
if( enc_dec_flag == ENC)
|
||||
{
|
||||
/* Store residual signal for postponed FFT-processing*/
|
||||
(*cng_buf_cnt)++;
|
||||
if( *cng_buf_cnt > HO_HIST_SIZE)
|
||||
{
|
||||
*cng_buf_cnt = HO_HIST_SIZE;
|
||||
}
|
||||
mvr2r( exc2, &(cng_exc2_buf[(*ho_circ_ptr)*L_FFT]), L_FFT );
|
||||
cng_brate_buf[*ho_circ_ptr] = last_active_brate;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* calculate the spectrum of residual signal */
|
||||
mvr2r(exc2, fft_io, L_frame);
|
||||
|
||||
fft_rel(fft_io, L_FFT, LOG2_L_FFT);
|
||||
|
||||
ptR = &fft_io[1];
|
||||
ptI = &fft_io[L_FFT-1];
|
||||
for (i=0; i<NUM_ENV_CNG; i++)
|
||||
{
|
||||
sp[i] = 2.0f*(*ptR **ptR + *ptI **ptI)/L_FFT;
|
||||
ptR++;
|
||||
ptI--;
|
||||
}
|
||||
|
||||
mvr2r(sp,env,NUM_ENV_CNG);
|
||||
if( last_active_brate > ACELP_13k20 )
|
||||
{
|
||||
CNG_mode = 4;
|
||||
}
|
||||
else if( last_active_brate > ACELP_9k60 )
|
||||
{
|
||||
CNG_mode = 3;
|
||||
}
|
||||
else if( last_active_brate > ACELP_8k00 )
|
||||
{
|
||||
CNG_mode = 2;
|
||||
}
|
||||
else if( last_active_brate > ACELP_7k20 )
|
||||
{
|
||||
CNG_mode = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
CNG_mode = 0;
|
||||
}
|
||||
|
||||
att = 1/pow(2,ENR_ATT[CNG_mode]);
|
||||
|
||||
for ( i=0; i<NUM_ENV_CNG; i++ )
|
||||
{
|
||||
env[i] *= att;
|
||||
}
|
||||
|
||||
/* update the circular buffer of old residual envelope */
|
||||
mvr2r( env, &(ho_env_circ[(*ho_circ_ptr)*NUM_ENV_CNG]), NUM_ENV_CNG );
|
||||
|
||||
}
|
||||
|
||||
(*ho_circ_size)++;
|
||||
if( *ho_circ_size > HO_HIST_SIZE )
|
||||
{
|
||||
*ho_circ_size = HO_HIST_SIZE;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -1,889 +0,0 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#include "options.h" /* Compilation switches */
|
||||
#include "cnst_fx.h" /* Common constants */
|
||||
#include "prot_fx.h" /* Function prototypes */
|
||||
#include "stl.h"
|
||||
#include "rom_com_fx.h"
|
||||
|
||||
/*---------------------------------------------------------------------*
|
||||
* Local constants
|
||||
*---------------------------------------------------------------------*/
|
||||
#define A2 6554
|
||||
#define OmA2 (32768-A2)
|
||||
#define GAIN_VAR 11811 /* in Q31 divided by 2 (Q30) */
|
||||
|
||||
/*-------------------------------------------------------*
|
||||
* CNG_exc()
|
||||
*
|
||||
* Comfort noise generation routine
|
||||
*-------------------------------------------------------*/
|
||||
|
||||
void CNG_exc_fx(
|
||||
const Word32 core_brate, /* i : core bitrate */
|
||||
const Word16 L_frame, /* i : length of the frame */
|
||||
Word32 *Enew, /* i/o: decoded SID energy Q6 */
|
||||
Word16 *seed, /* i/o: random generator seed */
|
||||
Word16 exc[], /* o : current non-enhanced excitation Q_new */
|
||||
Word16 exc2[], /* o : current enhanced excitation Q_new */
|
||||
Word32 *lp_ener, /* i/o: LP filtered E */
|
||||
const Word32 last_core_brate, /* i : previous frame core bitrate */
|
||||
Word16 *first_CNG, /* i/o: first CNG frame flag for energy init. */
|
||||
Word16 *cng_ener_seed, /* i/o: random generator seed for CNG energy */
|
||||
Word16 bwe_exc[], /* o : excitation for SWB TBE */
|
||||
const Word16 allow_cn_step, /* i : allow CN step */
|
||||
Word16 *last_allow_cn_step, /* i/o: last allow step */
|
||||
const Word16 OldQ_exc, /* i : Old excitation scaling */
|
||||
const Word16 Q_exc /* i : excitation scaling */
|
||||
, const Word16 num_ho /* i : number of selected hangover frames */
|
||||
,Word32 q_env[]
|
||||
,Word32 *lp_env
|
||||
,Word32 *old_env
|
||||
,Word16 *exc_mem
|
||||
,Word16 *exc_mem1
|
||||
,Word16 *sid_bw
|
||||
,Word16 *cng_ener_seed1
|
||||
,Word16 exc3[]
|
||||
,Word16 Opt_AMR_WB
|
||||
)
|
||||
{
|
||||
Word16 i, tmp, tmp2, exp, exp2, Q_ener;
|
||||
Word32 L_tmp_ener, L_tmp;
|
||||
Word16 i_subfr;
|
||||
Word16 pit_max;
|
||||
Word16 ftmp,j;
|
||||
Word16 *ptR,*ptI;
|
||||
Word16 fft_io[L_FRAME16k];
|
||||
Word32 itmp[129];
|
||||
Word32 env[NUM_ENV_CNG];
|
||||
Word32 enr1;
|
||||
Word32 denv[NUM_ENV_CNG];
|
||||
Word16 fra;
|
||||
Word16 temp_lo_fx, temp_hi_fx;
|
||||
Word16 exp_pow;
|
||||
Word32 L_tmp2;
|
||||
Word16 *pt_fft_io;
|
||||
|
||||
/*------------------------------------------------------------------*
|
||||
* Initializations
|
||||
*------------------------------------------------------------------*/
|
||||
|
||||
pit_max = PIT16k_MAX;
|
||||
move16();
|
||||
if( sub(L_frame,L_FRAME) == 0 )
|
||||
{
|
||||
pit_max = PIT_MAX;
|
||||
move16();
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------*
|
||||
* Initialization of CNG energy for the first CNG frame
|
||||
*---------------------------------------------------------------------*/
|
||||
|
||||
IF(*first_CNG == 0 )
|
||||
{
|
||||
IF(L_sub(core_brate,FRAME_NO_DATA) == 0 )
|
||||
{
|
||||
/* needed only in decoder when the very first SID frame was erased and this frame is FRAME_NO_DATA frame */
|
||||
/*fenew = dotp( fexc, fexc, pit_max )/pit_max;*/
|
||||
L_tmp_ener = Calc_Energy_Autoscaled(exc-pit_max, OldQ_exc, pit_max, &Q_ener);
|
||||
L_tmp_ener = Mult_32_16(L_tmp_ener, 9079); /* divide by PIT_MAX (in Q15 + Q6 to get output in Q6)*/
|
||||
L_tmp_ener = L_shr(L_tmp_ener, Q_ener); /* -> If we want ener in Q6 */
|
||||
|
||||
if(sub(L_frame, L_FRAME16k) == 0)
|
||||
{
|
||||
L_tmp_ener = Mult_32_16(L_tmp_ener, 26214); /* Compensate for 16kHz */
|
||||
}
|
||||
*Enew = L_tmp_ener;
|
||||
move32();
|
||||
}
|
||||
|
||||
*lp_ener = *Enew;
|
||||
move32();
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------*
|
||||
* Update CNG energy
|
||||
*---------------------------------------------------------------------*/
|
||||
test();
|
||||
test();
|
||||
IF( L_sub(last_core_brate,SID_1k75) != 0 && L_sub(last_core_brate,FRAME_NO_DATA) != 0 && L_sub(last_core_brate,SID_2k40) != 0 )
|
||||
{
|
||||
/* Partially reset CNG energy after active speech period */
|
||||
test();
|
||||
IF ( allow_cn_step == 0 && *last_allow_cn_step == 0 )
|
||||
{
|
||||
test();
|
||||
IF( sub(num_ho,3) < 0 || L_sub(Mult_32_16(*Enew,21845 /*1/1.5f, Q15*/), *lp_ener) < 0 )
|
||||
{
|
||||
/**lp_ener = 0.8f * *lp_ener + 0.2f * *Enew;*/
|
||||
L_tmp_ener = Mult_32_16(*lp_ener, 26214);
|
||||
L_tmp_ener = Madd_32_16(L_tmp_ener, *Enew, 6554);
|
||||
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
/**lp_ener = 0.95f * *lp_ener + 0.05f * *Enew;*/
|
||||
L_tmp_ener = Mult_32_16(*lp_ener, 31130);
|
||||
L_tmp_ener = Madd_32_16(L_tmp_ener, *Enew, 1638);
|
||||
}
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
L_tmp_ener = L_add(0,*Enew);
|
||||
*last_allow_cn_step = 0;
|
||||
move16();
|
||||
}
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
/* normal CNG update */
|
||||
IF ( *last_allow_cn_step == 0 )
|
||||
{
|
||||
/**lp_ener = (float)(A2 * *Enew + (1-A2) * *lp_ener);*/
|
||||
L_tmp_ener = Mult_32_16(*Enew, A2);
|
||||
L_tmp_ener = Madd_32_16(L_tmp_ener, *lp_ener, OmA2);
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
test();
|
||||
if ( L_sub(core_brate,SID_1k75) == 0 || L_sub(core_brate,SID_2k40) == 0 )
|
||||
{
|
||||
*last_allow_cn_step = 0;
|
||||
move16();
|
||||
}
|
||||
|
||||
L_tmp_ener = *Enew;
|
||||
move32();
|
||||
|
||||
}
|
||||
}
|
||||
*lp_ener = L_max(L_tmp_ener,1);
|
||||
move32(); /*To avoid / per 0*/
|
||||
|
||||
if ( sub(allow_cn_step,1) == 0)
|
||||
{
|
||||
*last_allow_cn_step = 1;
|
||||
move16();
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------*
|
||||
* Generate white noise vector
|
||||
*---------------------------------------------------------------------*/
|
||||
|
||||
/*for ( i=0; i<L_frame; i++ )exc2[i] = (float)own_random( seed );*/
|
||||
Random_Fill(seed, L_frame, exc2, 4);
|
||||
/*------------------------------------------------------------*
|
||||
* Insert random variation for excitation energy
|
||||
* (random variation is scaled according to *lp_ener value)
|
||||
*------------------------------------------------------------*/
|
||||
|
||||
FOR ( i_subfr=0; i_subfr<L_frame; i_subfr += L_SUBFR )
|
||||
{
|
||||
/* ener_lp = own_random(cng_ener_seed) * *lp_ener * GAIN_VAR + *lp_ener */
|
||||
/*------------------------------------------------------------*
|
||||
* Insert random variation for excitation energy
|
||||
* (random variation is scaled according to *lp_ener value)
|
||||
*------------------------------------------------------------*/
|
||||
L_tmp = Mult_32_16(*lp_ener, Random(cng_ener_seed));
|
||||
L_tmp = Mult_32_16(L_tmp, GAIN_VAR);
|
||||
L_tmp = L_add(L_tmp, *lp_ener);
|
||||
L_tmp = L_max(L_tmp, 1);
|
||||
|
||||
/* enr = dot_product( exc2, exc2, L_SUBFR ) + 0.01f */
|
||||
tmp = extract_h(Dot_product12(&exc2[i_subfr], &exc2[i_subfr], L_SUBFR, &exp));
|
||||
exp = add(exp, 8-6); /* 8 from Q-4, -6 from L_SUBFR */
|
||||
|
||||
/* enr = (float)sqrt(*lp_ener * L_SUBFR / enr) */
|
||||
exp2 = norm_l(L_tmp);
|
||||
tmp2 = extract_h(L_shl(L_tmp, exp2));
|
||||
exp2 = sub(31-6, exp2); /* in Q15 (L_tmp in Q6)*/
|
||||
|
||||
exp = sub(exp, exp2);
|
||||
|
||||
if (sub(tmp, tmp2) > 0)
|
||||
{
|
||||
exp = add(exp, 1);
|
||||
}
|
||||
if (sub(tmp, tmp2) > 0)
|
||||
{
|
||||
tmp = shr(tmp, 1);
|
||||
}
|
||||
tmp = div_s(tmp, tmp2);
|
||||
|
||||
L_tmp = L_deposit_h(tmp);
|
||||
|
||||
L_tmp = Isqrt_lc(L_tmp, &exp);
|
||||
tmp = extract_h(L_tmp);
|
||||
|
||||
exp = add(exp, 4); /* From Q15 to Q19 */
|
||||
exp = add(exp, Q_exc); /* Q_exc+ Q19 */
|
||||
|
||||
FOR (i=0; i<L_SUBFR; i++)
|
||||
{
|
||||
/* exc2[i] *= enr */
|
||||
L_tmp = L_mult(exc2[i_subfr+i], tmp); /* Q-4 * Q_exc+19 -> Q_exc +16 */
|
||||
exc2[i_subfr+i] = round_fx(L_shl(L_tmp, exp));
|
||||
}
|
||||
}
|
||||
IF ( sub(Opt_AMR_WB,1) != 0 )
|
||||
{
|
||||
Copy( exc2, exc3, L_FRAME16k);
|
||||
|
||||
/* enr1 = (float)log10( *Enew*L_frame + 0.1f ) / (float)log10( 2.0f ); */
|
||||
exp = norm_l(*Enew);
|
||||
L_tmp = L_shl(*Enew,exp); /* Q(exp+6) */
|
||||
L_tmp = Mult_32_16(L_tmp,shl(L_frame,5)); /* Q(exp+6+5-15=exp-4) */
|
||||
L_tmp = L_shr(L_tmp,sub(exp,10)); /* Q6 */
|
||||
|
||||
exp = norm_l(L_tmp);
|
||||
fra = Log2_norm_lc(L_shl(L_tmp,exp));
|
||||
exp = sub(sub(30,exp),6);
|
||||
L_tmp = L_Comp(exp,fra);
|
||||
/* enr1 = round_fx(L_shl(L_tmp,8)); */ /*Q8 */
|
||||
enr1 = L_shr(L_tmp,10);/* Q6 */
|
||||
|
||||
|
||||
IF ( L_sub(core_brate,SID_2k40) == 0 )
|
||||
{
|
||||
IF ( *sid_bw == 0 )
|
||||
{
|
||||
FOR ( i=0; i<NUM_ENV_CNG; i++ )
|
||||
{
|
||||
/* get quantized envelope */
|
||||
/* env[i] = pow(2.0f,(enr1 - q_env[i])); */
|
||||
L_tmp = L_sub(enr1,q_env[i]);/* Q6 */
|
||||
L_tmp = L_shl(L_tmp, 10);/* 16 */
|
||||
temp_lo_fx = L_Extract_lc(L_tmp, &temp_hi_fx);
|
||||
|
||||
exp_pow = sub(14, temp_hi_fx);
|
||||
L_tmp = Pow2(14, temp_lo_fx); /* Qexp_pow */
|
||||
env[i] = L_shl(L_tmp, sub(6, exp_pow));
|
||||
move32();/* Q6 */
|
||||
}
|
||||
}
|
||||
|
||||
/* initialize CNG envelope */
|
||||
test();
|
||||
IF( *first_CNG == 0 && *sid_bw == 0 )
|
||||
{
|
||||
Copy32(env, lp_env, NUM_ENV_CNG);
|
||||
}
|
||||
|
||||
IF ( *sid_bw == 0 )
|
||||
{
|
||||
Copy32(env, old_env, NUM_ENV_CNG);
|
||||
}
|
||||
}
|
||||
|
||||
FOR ( i=0; i<NUM_ENV_CNG; i++ )
|
||||
{
|
||||
/* get AR low-passed envelope */
|
||||
/* lp_env[i] = 0.9f*lp_env[i] + (1-0.9f)*old_env[i]; */
|
||||
L_tmp = Mult_32_16(lp_env[i],29491);
|
||||
lp_env[i] = L_add(L_tmp,Mult_32_16(old_env[i],3277));
|
||||
move32();/* Q6 */
|
||||
}
|
||||
|
||||
/* calculate the spectrum of random excitation signal */
|
||||
Copy(exc2, fft_io, L_frame);
|
||||
|
||||
IF ( sub(L_frame,L_FRAME16k) == 0 )
|
||||
{
|
||||
modify_Fs_fx( fft_io, L_FRAME16k, 16000, fft_io, 12800, exc_mem1, 0 );
|
||||
}
|
||||
|
||||
/* fft_rel(fft_io, L_FFT, LOG2_L_FFT); */
|
||||
fft_rel_fx(fft_io, L_FFT, LOG2_L_FFT);/* ??????? */
|
||||
ptR = &fft_io[1];
|
||||
ptI = &fft_io[sub(L_FFT,1)];
|
||||
FOR ( i=0; i<NUM_ENV_CNG; i++ )
|
||||
{
|
||||
/* env[i] = 2.0f*(*ptR * *ptR + *ptI * *ptI)/L_FFT; */
|
||||
L_tmp = L_mult0(*ptR,*ptR);/* 2*Q_exc */
|
||||
L_tmp = L_mac0(L_tmp,*ptI,*ptI);/* 2*Q_exc */
|
||||
L_tmp = L_shr(L_tmp,1);/* 2*Q_exc+6 */
|
||||
tmp = add(Q_exc,Q_exc);
|
||||
env[i] = L_shr(L_tmp,tmp);
|
||||
move32();/* Q6 */
|
||||
ptR++;
|
||||
ptI--;
|
||||
}
|
||||
|
||||
FOR ( i=0; i<NUM_ENV_CNG; i++ )
|
||||
{
|
||||
/* denv[i] = lp_env[i] + 2*(*lp_ener) - env[i]; */
|
||||
L_tmp = L_add(*lp_ener,*lp_ener);
|
||||
denv[i] = L_sub(L_add(lp_env[i],L_tmp),env[i]);
|
||||
move32();/* Q6 */
|
||||
|
||||
if ( denv[i] < 0 )
|
||||
{
|
||||
denv[i] = L_deposit_l(0);
|
||||
}
|
||||
}
|
||||
set32_fx(itmp, 0, NUM_ENV_CNG);
|
||||
|
||||
set16_fx(fft_io, 0, L_FFT);
|
||||
ptR = &fft_io[1];
|
||||
ptI = &fft_io[sub(L_FFT,1)];
|
||||
FOR (i=0; i<NUM_ENV_CNG; i++)
|
||||
{
|
||||
/* *ptR = own_random( cng_ener_seed1 ); */
|
||||
/* *ptI = own_random( cng_ener_seed1 ); */
|
||||
*ptR = Random( cng_ener_seed1 );
|
||||
*ptI = Random( cng_ener_seed1 );
|
||||
|
||||
/* env[i] = 2.0f*(*ptR * *ptR + *ptI * *ptI)/L_FFT; */
|
||||
L_tmp = L_mult0(*ptR,*ptR);/* Q0 */
|
||||
L_tmp = L_mac0(L_tmp,*ptI,*ptI);/* Q0 */
|
||||
env[i] = L_shr(L_tmp,1);
|
||||
move32(); /* Q6 */
|
||||
ptR++;
|
||||
ptI--;
|
||||
}
|
||||
|
||||
FOR ( i=0; i<NUM_ENV_CNG; i++ )
|
||||
{
|
||||
/* itmp[i] += own_random( cng_ener_seed1 )*denv[i]*0.000011f + denv[i]; */
|
||||
L_tmp = Mult_32_16(denv[i], Random(cng_ener_seed1));
|
||||
L_tmp = Mult_32_16(L_tmp, GAIN_VAR);
|
||||
L_tmp = L_add(L_tmp, denv[i]);
|
||||
itmp[i] = L_add(L_tmp, itmp[i]);
|
||||
move32();/* Q6 */
|
||||
|
||||
if (itmp[i] < 0)
|
||||
{
|
||||
itmp[i] = L_deposit_l(0);
|
||||
}
|
||||
}
|
||||
ptR = &fft_io[1];
|
||||
ptI = &fft_io[sub(L_FFT,1)];
|
||||
FOR ( i=0; i<NUM_ENV_CNG; i++ )
|
||||
{
|
||||
/* *ptR *= sqrt(itmp[i]/env[i]); */
|
||||
/* *ptI *= sqrt(itmp[i]/env[i]); */
|
||||
L_tmp = L_max(1, itmp[i]); /*Q6*/
|
||||
exp = norm_l(L_tmp);
|
||||
tmp = extract_h(L_shl(L_tmp, exp));
|
||||
exp = sub(31-6, exp); /* in Q15 (L_tmp in Q6)*/
|
||||
|
||||
exp2 = norm_l(env[i]);
|
||||
tmp2 = extract_h(L_shl(env[i], exp2));
|
||||
exp2 = sub(31-6, exp2); /* in Q15 (L_tmp in Q6)*/
|
||||
|
||||
exp = sub(exp2, exp); /* Denormalize and substract */
|
||||
if (sub(tmp2, tmp) > 0)
|
||||
{
|
||||
exp = add(exp, 1);
|
||||
}
|
||||
if (sub(tmp2, tmp) > 0)
|
||||
{
|
||||
tmp2 = shr(tmp2, 1);
|
||||
}
|
||||
tmp = div_s(tmp2, tmp);
|
||||
L_tmp = L_deposit_h(tmp);
|
||||
L_tmp = Isqrt_lc(L_tmp, &exp); /*Q(31-exp)*/
|
||||
|
||||
L_tmp2 = Mult_32_16(L_tmp,*ptR);/*Q(16-exp)*/
|
||||
*ptR = extract_h(L_shl(L_tmp2,add(exp,Q_exc))); /*Q_exc*/
|
||||
L_tmp2 = Mult_32_16(L_tmp,*ptI);/*Q(16-exp)*/
|
||||
*ptI = extract_h(L_shl(L_tmp2,add(exp,Q_exc))); /*Q_exc*/
|
||||
|
||||
ptR++;
|
||||
ptI--;
|
||||
}
|
||||
|
||||
ifft_rel_fx(fft_io, L_FFT, LOG2_L_FFT);
|
||||
|
||||
IF ( sub(L_frame,L_FRAME16k) == 0 )
|
||||
{
|
||||
modify_Fs_fx( fft_io, L_FFT, 12800, fft_io, 16000, exc_mem, 0 );
|
||||
}
|
||||
|
||||
/* enr1 = dotp( fft_io, fft_io, L_frame ) / L_frame; */
|
||||
|
||||
enr1 = L_deposit_l(1);
|
||||
pt_fft_io = fft_io;
|
||||
IF( sub(L_frame, L_FRAME) == 0)
|
||||
{
|
||||
FOR (j=0; j<128; j++)
|
||||
{
|
||||
L_tmp = L_mult0(*pt_fft_io, *pt_fft_io);
|
||||
pt_fft_io++;
|
||||
L_tmp = L_mac0(L_tmp, *pt_fft_io, *pt_fft_io); /* 2*(Q_exc) */
|
||||
pt_fft_io++;
|
||||
enr1 = L_add(enr1, L_shr(L_tmp, 7)); /* 2*(Q_exc)+1, divide by L_frame done here */
|
||||
}
|
||||
}
|
||||
ELSE /* L_FRAME16k */
|
||||
{
|
||||
FOR (j=0; j<160; j++)
|
||||
{
|
||||
L_tmp = L_mult0(*pt_fft_io, *pt_fft_io);
|
||||
pt_fft_io++;
|
||||
L_tmp = L_mac0(L_tmp, *pt_fft_io, *pt_fft_io); /* 2*(Q_exc) */
|
||||
pt_fft_io++;
|
||||
enr1 = L_add(enr1, L_shr(Mult_32_16(L_tmp,26214 /* 256/320, Q15 */), 7)); /* 2*(Q_exc)+15+1-16+1, divide by L_frame done here */
|
||||
}
|
||||
}
|
||||
enr1 = L_shr(enr1,sub(add(Q_exc,Q_exc),5));/*Q6*/
|
||||
|
||||
/* add time domain randomization */
|
||||
FOR ( i_subfr=0; i_subfr<L_frame; i_subfr += L_SUBFR )
|
||||
{
|
||||
|
||||
L_tmp = Mult_32_16(enr1, Random(cng_ener_seed1));
|
||||
L_tmp = Mult_32_16(L_tmp, GAIN_VAR);
|
||||
L_tmp = L_add(L_tmp, enr1);
|
||||
L_tmp = L_max(L_tmp, 1);
|
||||
|
||||
/* enr = dot_product( fft_io, fft_io, L_SUBFR ) + 0.01f */
|
||||
tmp = extract_h(Dot_product12(&fft_io[i_subfr], &fft_io[i_subfr], L_SUBFR, &exp));
|
||||
exp = add(exp, sub(-6, add(Q_exc, Q_exc))); /* -2*Q_exc from fft_io, -6 from L_SUBFR */
|
||||
|
||||
/* enr = (float)sqrt( ener_lp*L_SUBFR / enr ) */
|
||||
exp2 = norm_l(L_tmp);
|
||||
tmp2 = extract_h(L_shl(L_tmp, exp2));
|
||||
exp2 = sub(31-6, exp2); /* in Q15 (L_tmp in Q6)*/
|
||||
|
||||
exp = sub(exp, exp2);
|
||||
|
||||
if (sub(tmp, tmp2) > 0)
|
||||
{
|
||||
exp = add(exp, 1);
|
||||
}
|
||||
if (sub(tmp, tmp2) > 0)
|
||||
{
|
||||
tmp = shr(tmp, 1);
|
||||
}
|
||||
tmp = div_s(tmp, tmp2);
|
||||
|
||||
L_tmp = L_deposit_h(tmp);
|
||||
L_tmp = Isqrt_lc(L_tmp, &exp);/*Q(31-exp)*/
|
||||
test();
|
||||
test();
|
||||
test();
|
||||
IF( L_sub(last_core_brate,SID_2k40) != 0 && L_sub(last_core_brate,SID_1k75) != 0 && L_sub(last_core_brate,FRAME_NO_DATA) != 0 && L_sub(core_brate,SID_2k40) == 0 )
|
||||
{
|
||||
IF ( L_sub(L_tmp,L_shl(1,sub(31,exp))) > 0 )
|
||||
{
|
||||
L_tmp = L_shl(1,sub(31,exp));
|
||||
}
|
||||
}
|
||||
|
||||
tmp = extract_h(L_tmp);
|
||||
FOR (i=0; i<L_SUBFR; i++)
|
||||
{
|
||||
/* fft_io[i] *= enr */
|
||||
L_tmp = L_mult(fft_io[i_subfr+i], tmp); /* Q_exc + 16 - exp */
|
||||
fft_io[i_subfr+i] = round_fx(L_shl(L_tmp, exp));/*Q_exc*/
|
||||
}
|
||||
}
|
||||
|
||||
FOR ( i=0; i<L_frame; i++ )
|
||||
{
|
||||
/* fft_io[i] = 0.75f*fft_io[i] + exc2[i];*/
|
||||
tmp = mult(fft_io[i],24576);
|
||||
fft_io[i] = add(tmp,exc2[i]);
|
||||
move16();/*Q_exc*/
|
||||
}
|
||||
|
||||
/* enr = (dotp( fft_io, fft_io, L_frame ) / L_frame) + 0.01f */
|
||||
|
||||
L_tmp2 = L_deposit_l(1);
|
||||
pt_fft_io = fft_io;
|
||||
IF( sub(L_frame, L_FRAME) == 0)
|
||||
{
|
||||
FOR (j=0; j<128; j++)
|
||||
{
|
||||
L_tmp = L_mult0(*pt_fft_io, *pt_fft_io);
|
||||
pt_fft_io++;
|
||||
L_tmp = L_mac0(L_tmp, *pt_fft_io, *pt_fft_io); /* 2*(Q_exc) */
|
||||
pt_fft_io++;
|
||||
L_tmp2 = L_add(L_tmp2, L_shr(L_tmp, 7)); /* 2*(Q_exc)+1, divide by L_frame done here */
|
||||
}
|
||||
}
|
||||
ELSE /* L_FRAME16k */
|
||||
{
|
||||
FOR (j=0; j<160; j++)
|
||||
{
|
||||
L_tmp = L_mult0(*pt_fft_io, *pt_fft_io);
|
||||
pt_fft_io++;
|
||||
L_tmp = L_mac0(L_tmp, *pt_fft_io, *pt_fft_io); /* 2*(Q_exc) */
|
||||
pt_fft_io++;
|
||||
L_tmp2 = L_add(L_tmp2, L_shr(Mult_32_16(L_tmp,26214 /* 256/320, Q15 */), 7)); /* 2*(Q_exc)+15+1-16+1, divide by L_frame done here */
|
||||
}
|
||||
}
|
||||
L_tmp2 = L_shr(L_tmp2,sub(add(Q_exc,Q_exc),5));/*Q6*/
|
||||
|
||||
|
||||
/* enr = (*lp_ener)/enr; */
|
||||
/* ftmp = sqrt(enr); */
|
||||
L_tmp = L_max(1, *lp_ener); /*Q6*/
|
||||
exp = norm_l(L_tmp);
|
||||
tmp = extract_h(L_shl(L_tmp, exp));
|
||||
exp = sub(31-6, exp); /* in Q15 (L_tmp in Q6)*/
|
||||
|
||||
exp2 = norm_l(L_tmp2);
|
||||
tmp2 = extract_h(L_shl(L_tmp2, exp2));
|
||||
exp2 = sub(31-6, exp2); /* in Q15 (L_tmp in Q6)*/
|
||||
|
||||
exp = sub(exp2, exp); /* Denormalize and substract */
|
||||
if (sub(tmp2, tmp) > 0)
|
||||
{
|
||||
exp = add(exp, 1);
|
||||
}
|
||||
if (sub(tmp2, tmp) > 0)
|
||||
{
|
||||
tmp2 = shr(tmp2, 1);
|
||||
}
|
||||
tmp = div_s(tmp2, tmp);
|
||||
L_tmp = L_deposit_h(tmp);
|
||||
L_tmp = Isqrt_lc(L_tmp, &exp); /*Q(31-exp)*/
|
||||
|
||||
ftmp = extract_h(L_shl(L_tmp,exp));/* Q15 */
|
||||
FOR (i=0; i<L_frame; i++)
|
||||
{
|
||||
/* fft_io[i] *= ftmp;*/
|
||||
fft_io[i] = mult(fft_io[i],ftmp);
|
||||
move16();/* Q_exc */
|
||||
}
|
||||
Copy( fft_io, exc2, L_frame );
|
||||
}
|
||||
IF ( sub(Opt_AMR_WB,1) != 0 )
|
||||
{
|
||||
Copy( exc3, exc, L_frame );
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
Copy( exc2, exc, L_frame );
|
||||
}
|
||||
|
||||
IF( sub(L_frame,L_FRAME) == 0)
|
||||
{
|
||||
interp_code_5over2_fx( exc2, bwe_exc, L_FRAME );
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
interp_code_4over2_fx( exc2, bwe_exc, L_frame );
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------*
|
||||
* cng_params_postupd_fx
|
||||
*
|
||||
* Post-update of CNG parameters
|
||||
*-------------------------------------------------------*/
|
||||
void cng_params_postupd_fx(
|
||||
const Word16 ho_circ_ptr, /* i : pointer for CNG averaging buffers Q0 */
|
||||
Word16 *cng_buf_cnt, /* i/o: counter for CNG store buffers Q0 */
|
||||
const Word16 *const cng_exc2_buf, /* i : Excitation buffer Q_exc */
|
||||
const Word16 *const cng_Qexc_buf, /* i : Q_exc buffer Q0 */
|
||||
const Word32 *const cng_brate_buf, /* i : bit rate buffer Q0 */
|
||||
Word32 ho_env_circ[] /* i/o: Envelope buffer */
|
||||
)
|
||||
{
|
||||
Word16 i, j;
|
||||
Word16 Q_exc;
|
||||
const Word16 *exc2;
|
||||
Word16 fft_io[L_FFT];
|
||||
Word32 sp[129];
|
||||
Word16 *ptR,*ptI;
|
||||
Word32 env[NUM_ENV_CNG];
|
||||
Word32 L_tmp;
|
||||
Word16 tmp;
|
||||
Word16 temp_lo_fx, temp_hi_fx;
|
||||
Word16 exp_pow;
|
||||
Word16 exp1;
|
||||
Word16 CNG_mode;
|
||||
Word16 ptr;
|
||||
Word32 last_active_brate;
|
||||
|
||||
ptr = add( sub(ho_circ_ptr, *cng_buf_cnt), 1);
|
||||
if( ptr < 0 )
|
||||
{
|
||||
ptr = add(ptr, HO_HIST_SIZE);
|
||||
}
|
||||
|
||||
FOR( j = 0; j < *cng_buf_cnt; j++ )
|
||||
{
|
||||
exc2 = &cng_exc2_buf[ptr*L_FFT];
|
||||
Q_exc = cng_Qexc_buf[ptr];
|
||||
last_active_brate = cng_brate_buf[ptr];
|
||||
|
||||
/* calculate the spectrum of residual signal */
|
||||
Copy(exc2, fft_io, L_FFT);
|
||||
|
||||
fft_rel_fx(fft_io, L_FFT, LOG2_L_FFT);
|
||||
|
||||
ptR = &fft_io[1];
|
||||
ptI = &fft_io[L_FFT-1];
|
||||
FOR (i=0; i<NUM_ENV_CNG; i++)
|
||||
{
|
||||
/* sp[i] = 2.0f*(*ptR * *ptR + *ptI * *ptI)/L_FFT; */
|
||||
L_tmp = L_mult(*ptR,*ptR);/* 2*Q_exc+1 */
|
||||
L_tmp = L_add(L_tmp,L_mult(*ptI,*ptI));/* 2*Q_exc+1 */
|
||||
L_tmp = L_add(L_tmp,L_tmp);/* 2*Q_exc+1 */
|
||||
L_tmp = Mult_32_16(L_tmp,128);/* 2*Q_exc+1 */
|
||||
tmp = add(add(Q_exc,Q_exc),1);
|
||||
sp[i] = L_shr(L_tmp,sub(tmp,6));
|
||||
move32();/* Q6 */
|
||||
|
||||
ptR++;
|
||||
ptI--;
|
||||
}
|
||||
|
||||
Copy32(sp,env,NUM_ENV_CNG);
|
||||
IF( L_sub(last_active_brate,ACELP_13k20) > 0 )
|
||||
{
|
||||
CNG_mode = 4;
|
||||
}
|
||||
ELSE IF( L_sub(last_active_brate,ACELP_9k60) > 0 )
|
||||
{
|
||||
CNG_mode = 3;
|
||||
}
|
||||
ELSE IF( L_sub(last_active_brate,ACELP_8k00) > 0 )
|
||||
{
|
||||
CNG_mode = 2;
|
||||
}
|
||||
ELSE IF( L_sub(last_active_brate,ACELP_7k20) > 0 )
|
||||
{
|
||||
CNG_mode = 1;
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
CNG_mode = 0;
|
||||
}
|
||||
|
||||
/* att = 1/pow(2,ENR_ATT_fx[CNG_mode]); */
|
||||
L_tmp = L_shl(L_deposit_l(ENR_ATT_fx[CNG_mode]), 8);/* 16 */
|
||||
temp_lo_fx = L_Extract_lc(L_tmp, &temp_hi_fx);
|
||||
|
||||
exp_pow = sub(14, temp_hi_fx);
|
||||
L_tmp = Pow2(14, temp_lo_fx); /* Qexp_pow */
|
||||
L_tmp = L_shl(L_tmp, sub(13, exp_pow)); /* Q13 */
|
||||
tmp = extract_l(L_tmp);/* Q13 */
|
||||
|
||||
exp1 = norm_s(tmp);
|
||||
tmp = shl(tmp, exp1);/*Q(exp1+13) */
|
||||
tmp = div_s(16384,tmp); /*Q(15+14-exp1-13) */
|
||||
tmp = shr(tmp,sub(1,exp1));/* Q15 */
|
||||
|
||||
FOR ( i=0; i<NUM_ENV_CNG; i++ )
|
||||
{
|
||||
env[i] = Mult_32_16(env[i],tmp);
|
||||
move32();
|
||||
}
|
||||
|
||||
/* update the circular buffer of old residual envelope */
|
||||
Copy32( env, &(ho_env_circ[(ptr)*NUM_ENV_CNG]), NUM_ENV_CNG );
|
||||
|
||||
ptr = add(ptr, 1);
|
||||
if(sub(ptr, HO_HIST_SIZE) == 0)
|
||||
{
|
||||
ptr = 0;
|
||||
}
|
||||
}
|
||||
|
||||
*cng_buf_cnt = 0;
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-------------------------------------------------------*
|
||||
* cng_params_upd_fx()
|
||||
*
|
||||
* update CNG parameters
|
||||
*-------------------------------------------------------*/
|
||||
void cng_params_upd_fx(
|
||||
const Word16 lsp_new[], /* i : LSP aprameters Q15 */
|
||||
const Word16 exc2[], /* i : current enhanced excitation Q_exc */
|
||||
const Word16 L_frame, /* i : frame length Q0 */
|
||||
Word16 *ho_circ_ptr, /* i/o: pointer for CNG averaging buffers Q0 */
|
||||
Word32 ho_ener_circ[], /* o : energy buffer for CNG averaging Q6 */
|
||||
Word16 *ho_circ_size, /* i/o: size of DTX hangover history buffer for averaging Q0 */
|
||||
Word16 ho_lsp_circ[], /* o : old LSP buffer for CNG averaging Q15 */
|
||||
const Word16 Q_exc, /* i : Q value of excitation */
|
||||
const Word16 enc_dec_flag, /* i : Flag indicating encoder or decoder (ENC,DEC) */
|
||||
Word32 ho_env_circ[], /* i/o: Envelope buffer */
|
||||
Word16 *cng_buf_cnt, /* i/o: Counter of postponed FFT-processing instances */
|
||||
Word16 cng_exc2_buf[], /* i/o: Excitation buffer Q_exc */
|
||||
Word16 cng_Qexc_buf[], /* i/o: Q_exc buffer Q0 */
|
||||
Word32 cng_brate_buf[], /* i/o: last_active_brate buffer Q0 */
|
||||
const Word32 last_active_brate /* i : Last active bit rate Q0 */
|
||||
)
|
||||
{
|
||||
Word32 L_ener, L_tmp;
|
||||
Word16 i, j;
|
||||
const Word16 *pt_exc2;
|
||||
Word16 tmpv, maxv, scale;
|
||||
Word16 fft_io[L_FRAME16k];
|
||||
Word32 sp[129];
|
||||
Word16 *ptR,*ptI;
|
||||
Word32 env[NUM_ENV_CNG];
|
||||
Word16 exp1;
|
||||
Word16 CNG_mode;
|
||||
Word16 tmp;
|
||||
Word16 temp_lo_fx, temp_hi_fx;
|
||||
Word16 exp_pow;
|
||||
|
||||
|
||||
/* update the pointer to circular buffer of old LSP vectors */
|
||||
*ho_circ_ptr = add(*ho_circ_ptr,1);
|
||||
|
||||
if( sub(*ho_circ_ptr, HO_HIST_SIZE) == 0 )
|
||||
{
|
||||
*ho_circ_ptr = 0;
|
||||
move16();
|
||||
}
|
||||
|
||||
/* update the circular buffer of old LSP vectors with the new LSP vector */
|
||||
Copy( lsp_new, &(ho_lsp_circ[(*ho_circ_ptr)*M]), M );
|
||||
|
||||
/* calculate the residual signal energy */
|
||||
/*enr = dotp( exc2, exc2, L_frame ) / L_frame; */
|
||||
|
||||
maxv = 0;
|
||||
move16();
|
||||
FOR(i = 0; i < L_frame; i++)
|
||||
{
|
||||
maxv = s_max(maxv, abs_s(exc2[i]));
|
||||
}
|
||||
scale = norm_s(maxv);
|
||||
|
||||
pt_exc2 = exc2;
|
||||
move16();
|
||||
L_ener = L_deposit_l(0);
|
||||
IF( sub(L_frame, L_FRAME) == 0)
|
||||
{
|
||||
FOR (j=0; j<128; j++)
|
||||
{
|
||||
tmpv = shl(*pt_exc2,scale);
|
||||
L_tmp = L_mult0(tmpv, tmpv); /* 2*(Q_exc+scale) */
|
||||
pt_exc2++;
|
||||
tmpv = shl(*pt_exc2,scale);
|
||||
L_tmp = L_mac0(L_tmp, tmpv, tmpv);
|
||||
pt_exc2++;
|
||||
L_ener = L_add(L_ener, L_shr(L_tmp, 7)); /* Q(2*(Q_exc+scale)+1) ,division by L_frame done here */
|
||||
}
|
||||
}
|
||||
ELSE /* L_FRAME16k */
|
||||
{
|
||||
FOR (j=0; j<160; j++)
|
||||
{
|
||||
tmpv = shl(*pt_exc2,scale);
|
||||
L_tmp = L_mult0(tmpv, tmpv); /* 2*(Q_exc+scale) */
|
||||
pt_exc2++;
|
||||
tmpv = shl(*pt_exc2,scale);
|
||||
L_tmp = L_mac0(L_tmp, tmpv, tmpv);
|
||||
pt_exc2++;
|
||||
L_ener = L_add(L_ener, L_shr( Mult_32_16(L_tmp,26214 /* 256/320, Q15 */), 7)); /* Q(2*(Q_exc+scale)+15+1-16+1) ,division by L_frame done here */
|
||||
}
|
||||
}
|
||||
L_ener = L_shr(L_ener, sub(shl(add(Q_exc,scale),1),5)); /* Q6 (2*(Q_exc+scale)+1-2*(Q_exc+scale)+5) */
|
||||
|
||||
/* update the circular buffer of old energies */
|
||||
ho_ener_circ[*ho_circ_ptr] = L_ener;
|
||||
move32();
|
||||
|
||||
IF( sub(enc_dec_flag, ENC) == 0 )
|
||||
{
|
||||
/* Store residual signal for postponed FFT-processing*/
|
||||
*cng_buf_cnt = add(*cng_buf_cnt,1);
|
||||
if( sub(*cng_buf_cnt, HO_HIST_SIZE) > 0 )
|
||||
{
|
||||
*cng_buf_cnt = HO_HIST_SIZE;
|
||||
move16();
|
||||
}
|
||||
Copy( exc2, &(cng_exc2_buf[(*ho_circ_ptr)*L_FFT]), L_FFT );
|
||||
cng_Qexc_buf[*ho_circ_ptr] = Q_exc;
|
||||
move16();
|
||||
cng_brate_buf[*ho_circ_ptr] = last_active_brate;
|
||||
move16();
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
/* calculate the spectrum of residual signal */
|
||||
Copy(exc2, fft_io, L_frame);
|
||||
|
||||
fft_rel_fx(fft_io, L_FFT, LOG2_L_FFT);
|
||||
|
||||
ptR = &fft_io[1];
|
||||
ptI = &fft_io[L_FFT-1];
|
||||
FOR (i=0; i<NUM_ENV_CNG; i++)
|
||||
{
|
||||
/* sp[i] = 2.0f*(*ptR * *ptR + *ptI * *ptI)/L_FFT; */
|
||||
L_tmp = L_mult(*ptR,*ptR);/* 2*Q_exc+1 */
|
||||
L_tmp = L_add(L_tmp,L_mult(*ptI,*ptI));/* 2*Q_exc+1 */
|
||||
L_tmp = L_add(L_tmp,L_tmp);/* 2*Q_exc+1 */
|
||||
L_tmp = Mult_32_16(L_tmp,128);/* 2*Q_exc+1 */
|
||||
tmp = add(add(Q_exc,Q_exc),1);
|
||||
sp[i] = L_shr(L_tmp,sub(tmp,6));
|
||||
move32();/* Q6 */
|
||||
|
||||
ptR++;
|
||||
ptI--;
|
||||
}
|
||||
|
||||
Copy32(sp,env,NUM_ENV_CNG);
|
||||
IF( L_sub(last_active_brate,ACELP_13k20) > 0 )
|
||||
{
|
||||
CNG_mode = 4;
|
||||
}
|
||||
ELSE IF( L_sub(last_active_brate,ACELP_9k60) > 0 )
|
||||
{
|
||||
CNG_mode = 3;
|
||||
}
|
||||
ELSE IF( L_sub(last_active_brate,ACELP_8k00) > 0 )
|
||||
{
|
||||
CNG_mode = 2;
|
||||
}
|
||||
ELSE IF( L_sub(last_active_brate,ACELP_7k20) > 0 )
|
||||
{
|
||||
CNG_mode = 1;
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
CNG_mode = 0;
|
||||
}
|
||||
|
||||
/* att = 1/pow(2,ENR_ATT_fx[CNG_mode]); */
|
||||
L_tmp = L_shl(L_deposit_l(ENR_ATT_fx[CNG_mode]), 8);/* 16 */
|
||||
temp_lo_fx = L_Extract_lc(L_tmp, &temp_hi_fx);
|
||||
|
||||
exp_pow = sub(14, temp_hi_fx);
|
||||
L_tmp = Pow2(14, temp_lo_fx); /* Qexp_pow */
|
||||
L_tmp = L_shl(L_tmp, sub(13, exp_pow)); /* Q13 */
|
||||
tmp = extract_l(L_tmp);/* Q13 */
|
||||
|
||||
exp1 = norm_s(tmp);
|
||||
tmp = shl(tmp, exp1);/*Q(exp1+13) */
|
||||
tmp = div_s(16384,tmp); /*Q(15+14-exp1-13) */
|
||||
tmp = shr(tmp,sub(1,exp1));/* Q15 */
|
||||
|
||||
FOR ( i=0; i<NUM_ENV_CNG; i++ )
|
||||
{
|
||||
env[i] = Mult_32_16(env[i],tmp);
|
||||
move32();
|
||||
}
|
||||
|
||||
/* update the circular buffer of old residual envelope */
|
||||
/* Copy32( env, &(ho_env_circ[add(shl(*ho_circ_ptr,4),shl(*ho_circ_ptr,2))]), NUM_ENV_CNG ); */
|
||||
Copy32( env, &(ho_env_circ[(*ho_circ_ptr)*NUM_ENV_CNG]), NUM_ENV_CNG );
|
||||
}
|
||||
*ho_circ_size = add(*ho_circ_size,1);
|
||||
if( sub(*ho_circ_size,HO_HIST_SIZE) > 0 )
|
||||
{
|
||||
*ho_circ_size = HO_HIST_SIZE;
|
||||
move16();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
1534
src/libs/libevs/lib_com/cnst_fx.h → src/libs/libevs/lib_com/cnst.h
Executable file → Normal file
1534
src/libs/libevs/lib_com/cnst_fx.h → src/libs/libevs/lib_com/cnst.h
Executable file → Normal file
File diff suppressed because it is too large
Load Diff
341
src/libs/libevs/lib_com/codec_tcx_common.cpp
Executable file → Normal file
341
src/libs/libevs/lib_com/codec_tcx_common.cpp
Executable file → Normal file
@@ -1,288 +1,173 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
EVS Codec 3GPP TS26.443 Nov 13, 2018. Version 12.11.0 / 13.7.0 / 14.3.0 / 15.1.0
|
||||
====================================================================================*/
|
||||
|
||||
#include <assert.h>
|
||||
#include "prot_fx.h"
|
||||
#include <math.h>
|
||||
#include "prot.h"
|
||||
#include "options.h"
|
||||
|
||||
#include "stl.h"
|
||||
#include "prot_fx.h"
|
||||
#include "basop_util.h"
|
||||
#include "rom_basop_util.h"
|
||||
#define inv_int InvIntTable
|
||||
/*-------------------------------------------------------------------*
|
||||
* tcxGetNoiseFillingTilt()
|
||||
*
|
||||
*
|
||||
*-------------------------------------------------------------------*/
|
||||
|
||||
|
||||
|
||||
Word16 tcxGetNoiseFillingTilt(Word16 A[], Word16 lpcorder, Word16 L_frame, Word16 mode, Word16 *noiseTiltFactor)
|
||||
int tcxGetNoiseFillingTilt(
|
||||
float A[],
|
||||
int L_frame,
|
||||
int mode,
|
||||
float *noiseTiltFactor
|
||||
)
|
||||
{
|
||||
Word16 firstLine;
|
||||
Word32 tmp;
|
||||
Word16 As[M+1];
|
||||
int firstLine;
|
||||
|
||||
|
||||
IF (mode != 0)
|
||||
if (mode)
|
||||
{
|
||||
firstLine = idiv1616U(L_frame, 6);
|
||||
*noiseTiltFactor = 18432/*0.5625f Q15*/;
|
||||
move16();
|
||||
firstLine = L_frame / 6;
|
||||
*noiseTiltFactor = 0.5625f;
|
||||
}
|
||||
ELSE
|
||||
else
|
||||
{
|
||||
firstLine = shr(L_frame, 3);
|
||||
|
||||
Copy_Scale_sig( A, As, lpcorder+1, sub(norm_s(A[0]),2) );
|
||||
tmp = get_gain(As+1, As, lpcorder);
|
||||
BASOP_SATURATE_WARNING_OFF;
|
||||
*noiseTiltFactor = add(round_fx(L_shl(tmp, 15)), 3072/*0.09375f Q15*/);
|
||||
move16();
|
||||
BASOP_SATURATE_WARNING_ON;
|
||||
firstLine = L_frame / 8;
|
||||
*noiseTiltFactor = get_gain( A+1, A, M, NULL );
|
||||
*noiseTiltFactor = min(1.0f, (*noiseTiltFactor) + 0.09375f);
|
||||
}
|
||||
|
||||
|
||||
return firstLine;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------*
|
||||
* tcxFormantEnhancement()
|
||||
*
|
||||
*
|
||||
*-------------------------------------------------------------------*/
|
||||
|
||||
void tcxFormantEnhancement(
|
||||
Word16 xn_buf[],
|
||||
Word16 gainlpc[], Word16 gainlpc_e[],
|
||||
Word32 spectrum[], Word16 *spectrum_e,
|
||||
Word16 L_frame,
|
||||
Word16 L_frameTCX
|
||||
float xn_buf[],
|
||||
float gainlpc[],
|
||||
float spectrum[],
|
||||
int L_frame
|
||||
)
|
||||
{
|
||||
Word16 i, j, k, l, n;
|
||||
Word16 fac, fac0, fac1, fac_e, d, tmp;
|
||||
Word16 xn_buf_e, xn_one, m, e;
|
||||
int k;
|
||||
int i, j, l = 0;
|
||||
float fac, step;
|
||||
|
||||
|
||||
k = shr(L_frame, 6); /* FDNS_NPTS = 64 */
|
||||
l = 0;
|
||||
move16();
|
||||
|
||||
/* get exponent */
|
||||
xn_buf_e = 0;
|
||||
move16();
|
||||
FOR (i = 0; i < FDNS_NPTS; i++)
|
||||
{
|
||||
xn_buf_e = s_max(xn_buf_e, gainlpc_e[i]);
|
||||
}
|
||||
xn_buf_e = shr(add(xn_buf_e, 1), 1); /* max exponent after sqrt */
|
||||
xn_one = shr(0x4000, sub(xn_buf_e, 1)); /* 1.0 scaled to xn_buf_e */
|
||||
k = L_frame / FDNS_NPTS;
|
||||
|
||||
/* Formant enhancement via square root of the LPC gains */
|
||||
e = gainlpc_e[0];
|
||||
move16();
|
||||
m = Sqrt16(gainlpc[0], &e);
|
||||
xn_buf[0] = shl(m, sub(e, xn_buf_e));
|
||||
move16();
|
||||
xn_buf[0] = (float)sqrt(gainlpc[0]);
|
||||
xn_buf[1] = (float)sqrt(gainlpc[1]);
|
||||
fac = 1.0f / min(xn_buf[0], xn_buf[1]);
|
||||
|
||||
e = gainlpc_e[1];
|
||||
move16();
|
||||
m = Sqrt16(gainlpc[1], &e);
|
||||
xn_buf[1] = shl(m, sub(e, xn_buf_e));
|
||||
move16();
|
||||
|
||||
fac0 = s_min(xn_buf[0], xn_buf[1]);
|
||||
fac_e = xn_buf_e;
|
||||
move16();
|
||||
fac0 = Inv16(fac0, &fac_e);
|
||||
|
||||
FOR (i = 1; i < FDNS_NPTS-1; i++)
|
||||
for (i = 1; i < FDNS_NPTS - 1; i++)
|
||||
{
|
||||
e = gainlpc_e[i+1];
|
||||
move16();
|
||||
m = Sqrt16(gainlpc[i+1], &e);
|
||||
xn_buf[i+1] = shl(m, sub(e, xn_buf_e));
|
||||
move16();
|
||||
xn_buf[i+1] = (float)sqrt(gainlpc[i+1]);
|
||||
|
||||
test();
|
||||
IF ((sub(xn_buf[i-1], xn_buf[i]) <= 0) && (sub(xn_buf[i+1], xn_buf[i]) <= 0))
|
||||
if ((xn_buf[i-1] <= xn_buf[i]) && (xn_buf[i+1] <= xn_buf[i]))
|
||||
{
|
||||
m = s_max(xn_buf[i-1], xn_buf[i+1]);
|
||||
e = xn_buf_e;
|
||||
move16();
|
||||
m = Inv16(m, &e);
|
||||
|
||||
fac1 = m;
|
||||
move16();
|
||||
tmp = sub(e, fac_e);
|
||||
|
||||
if (tmp > 0) fac0 = shr(fac0, tmp);
|
||||
if (tmp < 0) fac1 = shl(fac1, tmp);
|
||||
|
||||
if (tmp > 0)
|
||||
step = max(xn_buf[i-1], xn_buf[i+1]);
|
||||
step = (1.0f / step - fac) / (float)(i - l);
|
||||
xn_buf[l] = 1.0f;
|
||||
fac += step;
|
||||
for (j = l + 1; j < i; j++)
|
||||
{
|
||||
fac_e = e;
|
||||
move16();
|
||||
xn_buf[j] = min(1.0f, xn_buf[j] * fac);
|
||||
fac += step;
|
||||
}
|
||||
|
||||
d = sub(fac1, fac0);
|
||||
n = sub(i, l);
|
||||
assert(n <= 64);
|
||||
|
||||
xn_buf[l] = xn_one;
|
||||
move16();
|
||||
FOR (j = 1; j < n; j++)
|
||||
{
|
||||
fac = add(fac0, mult(d, extract_l(L_mult0(j, inv_int[n]))));
|
||||
BASOP_SATURATE_WARNING_OFF;
|
||||
xn_buf[l+j] = s_min(xn_one, shl(mult(xn_buf[l+j], fac), fac_e));
|
||||
move16();
|
||||
BASOP_SATURATE_WARNING_ON;
|
||||
}
|
||||
|
||||
l = i;
|
||||
move16();
|
||||
|
||||
fac0 = m;
|
||||
move16();
|
||||
fac_e = e;
|
||||
move16();
|
||||
}
|
||||
}
|
||||
/* i = FDNS_NPTS - 1; Completing changes to gains */
|
||||
m = s_min(xn_buf[i-1], xn_buf[i]);
|
||||
e = xn_buf_e;
|
||||
move16();
|
||||
m = Inv16(m, &e);
|
||||
|
||||
fac1 = m;
|
||||
move16();
|
||||
tmp = sub(e, fac_e);
|
||||
|
||||
if (tmp > 0) fac0 = shr(fac0, tmp);
|
||||
if (tmp < 0) fac1 = shl(fac1, tmp);
|
||||
|
||||
if (tmp > 0)
|
||||
/* i = tcx_cfg->fdns_npts - 1; Completing changes to gains */
|
||||
step = min(xn_buf[i-1], xn_buf[i]);
|
||||
step = (1.0f / step - fac) / (float)(i - l);
|
||||
xn_buf[l] = 1.0f;
|
||||
fac += step;
|
||||
for (j = l + 1; j < i; j++)
|
||||
{
|
||||
fac_e = e;
|
||||
move16();
|
||||
xn_buf[j] = min(1.0f, xn_buf[j] * fac);
|
||||
fac += step;
|
||||
}
|
||||
|
||||
d = sub(fac1, fac0);
|
||||
n = sub(i, l);
|
||||
assert(n <= 64);
|
||||
|
||||
xn_buf[l] = xn_one;
|
||||
move16();
|
||||
FOR (j = 1; j < n; j++)
|
||||
{
|
||||
fac = add(fac0, mult(d, extract_l(L_mult0(j, inv_int[n]))));
|
||||
BASOP_SATURATE_WARNING_OFF;
|
||||
xn_buf[l+j] = s_min(xn_one, shl(mult(xn_buf[l+j], fac), fac_e));
|
||||
move16();
|
||||
BASOP_SATURATE_WARNING_ON;
|
||||
}
|
||||
|
||||
xn_buf[i] = xn_one;
|
||||
move16();
|
||||
xn_buf[i] = 1.0f;
|
||||
|
||||
/* Application of changed gains onto decoded MDCT lines */
|
||||
FOR (i = 0; i < L_frame; i += k)
|
||||
for (i = j = 0; i < L_frame; j++)
|
||||
{
|
||||
FOR (l = 0; l < k; l++)
|
||||
for (l = 0; l < k; i++, l++)
|
||||
{
|
||||
*spectrum = Mpy_32_16_1(*spectrum, *xn_buf);
|
||||
move32();
|
||||
spectrum++;
|
||||
spectrum[i] *= xn_buf[j];
|
||||
}
|
||||
xn_buf++;
|
||||
}
|
||||
|
||||
tmp = sub(L_frameTCX, L_frame);
|
||||
FOR (i = 0; i < tmp; i++)
|
||||
{
|
||||
spectrum[i] = L_shr(spectrum[i], xn_buf_e);
|
||||
move32();
|
||||
}
|
||||
*spectrum_e = add(*spectrum_e, xn_buf_e);
|
||||
move16();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void tcxInvertWindowGrouping(TCX_config *tcx_cfg,
|
||||
Word32 xn_buf[],
|
||||
Word32 spectrum[],
|
||||
Word16 L_frame,
|
||||
Word8 fUseTns,
|
||||
Word16 last_core,
|
||||
Word16 index,
|
||||
Word16 frame_cnt,
|
||||
Word16 bfi)
|
||||
/*-------------------------------------------------------------------*
|
||||
* tcxGetNoiseFillingTilt()
|
||||
*
|
||||
*
|
||||
*-------------------------------------------------------------------*/
|
||||
|
||||
void tcxInvertWindowGrouping(
|
||||
TCX_config *tcx_cfg,
|
||||
float xn_buf[],
|
||||
float spectrum[],
|
||||
int L_frame,
|
||||
int fUseTns,
|
||||
int last_core,
|
||||
int index,
|
||||
int frame_cnt,
|
||||
int bfi
|
||||
)
|
||||
{
|
||||
Word16 i, L_win, L_spec;
|
||||
Word32 *p;
|
||||
short i, w, t_integer;
|
||||
int L_win, L_spec;
|
||||
|
||||
|
||||
L_win = shr(L_frame, 1);
|
||||
L_spec = tcx_cfg->tnsConfig[0][0].iFilterBorders[0];
|
||||
move16();
|
||||
|
||||
test();
|
||||
test();
|
||||
if ((frame_cnt != 0) && (bfi == 0) && (last_core != ACELP_CORE)) /* fix sub-window overlap */
|
||||
if (frame_cnt && !bfi && last_core!=0)
|
||||
{
|
||||
/* fix sub-window overlap */
|
||||
tcx_cfg->tcx_last_overlap_mode = tcx_cfg->tcx_curr_overlap_mode;
|
||||
move16();
|
||||
}
|
||||
test();
|
||||
test();
|
||||
test();
|
||||
test();
|
||||
test();
|
||||
test();
|
||||
test();
|
||||
IF (((bfi==0) &&((tcx_cfg->tcx_last_overlap_mode != FULL_OVERLAP) ||
|
||||
((tcx_cfg->tcx_curr_overlap_mode == FULL_OVERLAP) && (frame_cnt == 0) && (index == 0))))
|
||||
||
|
||||
((bfi!=0) &&((tcx_cfg->tcx_last_overlap_mode != FULL_OVERLAP) &&
|
||||
!(tcx_cfg->tcx_curr_overlap_mode == FULL_OVERLAP))))
|
||||
|
||||
if (((!bfi) &&((tcx_cfg->tcx_last_overlap_mode != FULL_OVERLAP) ||
|
||||
((tcx_cfg->tcx_curr_overlap_mode == FULL_OVERLAP) && (frame_cnt == 0) && (index == 0))))
|
||||
||
|
||||
((bfi) &&((tcx_cfg->tcx_last_overlap_mode != FULL_OVERLAP) &&
|
||||
!(tcx_cfg->tcx_curr_overlap_mode == FULL_OVERLAP))))
|
||||
{
|
||||
|
||||
/* ungroup sub-windows: deinterleave MDCT bins into separate windows */
|
||||
p = xn_buf;
|
||||
FOR (i = 1; i < L_win; i += 2)
|
||||
for (t_integer = w = 0; w < 2; w++)
|
||||
{
|
||||
*p++ = spectrum[i];
|
||||
move32();
|
||||
}
|
||||
|
||||
p = spectrum;
|
||||
FOR (i = 0; i < L_frame; i += 2)
|
||||
{
|
||||
*p++ = spectrum[i];
|
||||
move32();
|
||||
}
|
||||
|
||||
p = spectrum + L_frame - 1;
|
||||
FOR (i = sub(L_frame, 1); i > L_win; i -= 2)
|
||||
{
|
||||
*p-- = spectrum[i];
|
||||
move32();
|
||||
}
|
||||
Copy32(xn_buf, spectrum + L_win, shr(L_win, 1));
|
||||
|
||||
test();
|
||||
test();
|
||||
IF ((tcx_cfg->fIsTNSAllowed != 0) && (bfi == 0) && (fUseTns != 0))
|
||||
{
|
||||
/* rearrange LF sub-window lines prior to TNS synthesis filtering */
|
||||
IF (sub(L_spec, L_frame) < 0)
|
||||
for (i = w; i < L_frame; i += 2)
|
||||
{
|
||||
Copy32(spectrum+8, spectrum+16, sub(shr(L_spec,1),8));
|
||||
Copy32(spectrum+L_frame/2, spectrum+8, 8);
|
||||
Copy32(spectrum+L_frame/2+8, spectrum+L_spec/2+8, sub(shr(L_spec,1),8));
|
||||
xn_buf[t_integer++] = spectrum[i];
|
||||
}
|
||||
ELSE
|
||||
}
|
||||
|
||||
mvr2r( xn_buf, spectrum, L_frame );
|
||||
|
||||
if( tcx_cfg->fIsTNSAllowed && !bfi && fUseTns )
|
||||
{
|
||||
L_win = L_frame >> 1;
|
||||
L_spec = tcx_cfg->tnsConfig[0][0].iFilterBorders[0];
|
||||
|
||||
/* rearrange LF sub-window lines prior to TNS synthesis filtering */
|
||||
if( L_spec < L_frame )
|
||||
{
|
||||
Copy32(spectrum+L_win, xn_buf, 8);
|
||||
Copy32(spectrum+8, spectrum+16, sub(L_win, 8));
|
||||
Copy32(xn_buf, spectrum+8, 8);
|
||||
mvr2r( spectrum+8, spectrum+16, L_spec/2-8 );
|
||||
mvr2r( spectrum+L_frame/2, spectrum+8, 8 );
|
||||
mvr2r( spectrum+L_frame/2+8, spectrum+L_spec/2+8, L_spec/2-8 );
|
||||
}
|
||||
else
|
||||
{
|
||||
mvr2r( spectrum+8, xn_buf, L_win );
|
||||
mvr2r( xn_buf, spectrum+16, L_win-8 );
|
||||
mvr2r( xn_buf+L_win-8, spectrum+8, 8);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
42
src/libs/libevs/lib_com/control.h
Normal file
42
src/libs/libevs/lib_com/control.h
Normal file
@@ -0,0 +1,42 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.443 Nov 13, 2018. Version 12.11.0 / 13.7.0 / 14.3.0 / 15.1.0
|
||||
====================================================================================*/
|
||||
|
||||
#ifndef _CONTROL_H
|
||||
#define _CONTROL_H
|
||||
|
||||
/* BASOP -> FLC brigde: flow control instructions */
|
||||
|
||||
#include "stl.h"
|
||||
|
||||
#define FOR( a) if( incrFor(), 0); else for( a)
|
||||
static __inline void incrFor( void)
|
||||
{
|
||||
}
|
||||
|
||||
#define WHILE( a) if (incrFlcWhile(), 0); else while(a)
|
||||
static __inline void incrFlcWhile(void)
|
||||
{
|
||||
}
|
||||
|
||||
#define DO do
|
||||
|
||||
#define IF( a) if( incrIf(), a)
|
||||
static __inline void incrIf( void)
|
||||
{
|
||||
}
|
||||
|
||||
#define ELSE else
|
||||
|
||||
#define SWITCH( a) switch( incrSwitch(), a)
|
||||
static __inline void incrSwitch( void)
|
||||
{
|
||||
}
|
||||
|
||||
#define CONTINUE continue
|
||||
|
||||
#define BREAK break
|
||||
|
||||
#define GOTO goto
|
||||
|
||||
#endif /* _CONTROL_H */
|
||||
419
src/libs/libevs/lib_com/core_com_config.cpp
Normal file
419
src/libs/libevs/lib_com/core_com_config.cpp
Normal file
@@ -0,0 +1,419 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.443 Nov 13, 2018. Version 12.11.0 / 13.7.0 / 14.3.0 / 15.1.0
|
||||
====================================================================================*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "options.h"
|
||||
#include "rom_com.h"
|
||||
#include "prot.h"
|
||||
|
||||
/*-------------------------------------------------------------------*
|
||||
* getTcxonly()
|
||||
*
|
||||
*
|
||||
*-------------------------------------------------------------------*/
|
||||
|
||||
short getTcxonly(
|
||||
const int bitrate
|
||||
)
|
||||
{
|
||||
short tcxonly = 0;
|
||||
|
||||
if( bitrate > ACELP_32k )
|
||||
{
|
||||
tcxonly = 1;
|
||||
}
|
||||
|
||||
return tcxonly;
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------*
|
||||
* getCtxHm()
|
||||
*
|
||||
*
|
||||
*-------------------------------------------------------------------*/
|
||||
|
||||
short getCtxHm(
|
||||
const int bitrate,
|
||||
const short rf_flag
|
||||
)
|
||||
{
|
||||
short ctx_hm = 0;
|
||||
if( (bitrate > LPC_SHAPED_ARI_MAX_RATE) && (bitrate <= 64000) && !rf_flag)
|
||||
{
|
||||
ctx_hm = 1;
|
||||
}
|
||||
|
||||
return ctx_hm;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------*
|
||||
* getResq()
|
||||
*
|
||||
*
|
||||
*-------------------------------------------------------------------*/
|
||||
|
||||
short getResq(
|
||||
const int bitrate
|
||||
)
|
||||
{
|
||||
short resq = 0;
|
||||
|
||||
if(bitrate <= HQ_64k)
|
||||
{
|
||||
resq = 1;
|
||||
}
|
||||
|
||||
return resq;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------*
|
||||
* getTnsAllowed()
|
||||
*
|
||||
*
|
||||
*-------------------------------------------------------------------*/
|
||||
|
||||
short getTnsAllowed(
|
||||
const int bitrate,
|
||||
const short igf
|
||||
)
|
||||
{
|
||||
short tnsAllowed = 0;
|
||||
|
||||
if( igf )
|
||||
{
|
||||
if( bitrate > HQ_16k40 )
|
||||
{
|
||||
tnsAllowed = 1;
|
||||
}
|
||||
}
|
||||
else if( bitrate > HQ_32k )
|
||||
{
|
||||
tnsAllowed = 1;
|
||||
}
|
||||
|
||||
return tnsAllowed;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------*
|
||||
* getRestrictedMode()
|
||||
*
|
||||
*
|
||||
*-------------------------------------------------------------------*/
|
||||
|
||||
short getRestrictedMode(
|
||||
const int bitrate,
|
||||
const short Opt_AMR_WB
|
||||
)
|
||||
{
|
||||
short restrictedMode = 3;
|
||||
|
||||
if ( !Opt_AMR_WB && (bitrate > HQ_32k) )
|
||||
{
|
||||
restrictedMode = 6;
|
||||
}
|
||||
else if ( Opt_AMR_WB )
|
||||
{
|
||||
restrictedMode = 1;
|
||||
}
|
||||
|
||||
return restrictedMode;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------*
|
||||
* getMdctWindowLength()
|
||||
*
|
||||
*
|
||||
*-------------------------------------------------------------------*/
|
||||
|
||||
short getMdctWindowLength(
|
||||
const float fscale
|
||||
)
|
||||
{
|
||||
|
||||
short mdctWindowLength;
|
||||
|
||||
mdctWindowLength = (L_LOOK_12k8 * fscale)/FSCALE_DENOM;
|
||||
|
||||
return mdctWindowLength;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------*
|
||||
* sr2fscale()
|
||||
*
|
||||
*
|
||||
*-------------------------------------------------------------------*/
|
||||
|
||||
short sr2fscale(
|
||||
const int sr
|
||||
)
|
||||
{
|
||||
|
||||
return (FSCALE_DENOM*sr)/12800;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------*
|
||||
* getCoreSamplerateMode2()
|
||||
*
|
||||
*
|
||||
*-------------------------------------------------------------------*/
|
||||
|
||||
int getCoreSamplerateMode2(
|
||||
const int bitrate,
|
||||
const int bandwidth,
|
||||
const short rf_mode
|
||||
)
|
||||
{
|
||||
int sr_core = 0;
|
||||
|
||||
if( bandwidth == NB )
|
||||
{
|
||||
sr_core = 12800;
|
||||
}
|
||||
else if( (bandwidth == WB && bitrate < ACELP_13k20) ||
|
||||
(bandwidth == SWB && bitrate <= ACELP_13k20) || (rf_mode == 1) )
|
||||
{
|
||||
sr_core = 12800;
|
||||
}
|
||||
else if( bandwidth == WB || (bandwidth == SWB && bitrate <= ACELP_32k)
|
||||
|| (bandwidth == FB && bitrate <= ACELP_32k) )
|
||||
{
|
||||
sr_core = 16000;
|
||||
}
|
||||
else if( (bandwidth == SWB || bandwidth == FB) && bitrate <= HQ_64k)
|
||||
{
|
||||
sr_core = 25600;
|
||||
}
|
||||
else if( bandwidth == SWB || bandwidth == FB )
|
||||
{
|
||||
sr_core = 32000;
|
||||
}
|
||||
|
||||
return sr_core;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------*
|
||||
* getTcxBandwidth()
|
||||
*
|
||||
*
|
||||
*-------------------------------------------------------------------*/
|
||||
|
||||
float getTcxBandwidth(
|
||||
const int bandwidth
|
||||
)
|
||||
{
|
||||
float tcxBandwidth = 0.5f;
|
||||
|
||||
if( bandwidth == NB )
|
||||
{
|
||||
tcxBandwidth = 0.3125f;
|
||||
}
|
||||
|
||||
return tcxBandwidth;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------*
|
||||
* getIgfPresent()
|
||||
*
|
||||
*
|
||||
*-------------------------------------------------------------------*/
|
||||
|
||||
short getIgfPresent(
|
||||
const int bitrate,
|
||||
const int bandwidth,
|
||||
const short rf_mode
|
||||
)
|
||||
{
|
||||
short igfPresent = 0;
|
||||
|
||||
if( bandwidth == SWB && bitrate >= ACELP_9k60 && bitrate < HQ_96k )
|
||||
{
|
||||
igfPresent = 1;
|
||||
}
|
||||
else if( bandwidth == FB && bitrate >= ACELP_16k40 )
|
||||
{
|
||||
igfPresent = 1;
|
||||
}
|
||||
else if( bandwidth == WB && bitrate == ACELP_9k60 )
|
||||
{
|
||||
igfPresent = 1;
|
||||
}
|
||||
if( ((bandwidth == WB) || (bandwidth == SWB)) && (rf_mode == 1) && (bitrate == ACELP_13k20) )
|
||||
{
|
||||
igfPresent = 1;
|
||||
}
|
||||
|
||||
return igfPresent;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------*
|
||||
* getCnaPresent()
|
||||
*
|
||||
*
|
||||
*-------------------------------------------------------------------*/
|
||||
|
||||
short getCnaPresent(
|
||||
const int bitrate,
|
||||
const int bandwidth
|
||||
)
|
||||
{
|
||||
short flag_cna = 0;
|
||||
|
||||
if( bandwidth == NB && bitrate <= ACELP_13k20 )
|
||||
{
|
||||
flag_cna = 1;
|
||||
}
|
||||
|
||||
if( bandwidth == WB && bitrate <= ACELP_13k20 )
|
||||
{
|
||||
flag_cna = 1;
|
||||
}
|
||||
|
||||
if( bandwidth == SWB && bitrate <= ACELP_13k20 )
|
||||
{
|
||||
flag_cna = 1;
|
||||
}
|
||||
|
||||
return flag_cna;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------*
|
||||
* getTcxLtp()
|
||||
*
|
||||
*
|
||||
*-------------------------------------------------------------------*/
|
||||
short getTcxLtp(
|
||||
const int sr_core
|
||||
)
|
||||
{
|
||||
short tcxltp = 0;
|
||||
|
||||
if ( (sr_core <= 25600) )
|
||||
{
|
||||
tcxltp = 1;
|
||||
}
|
||||
|
||||
return tcxltp;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------*
|
||||
* initPitchLagParameters()
|
||||
*
|
||||
*
|
||||
*-------------------------------------------------------------------*/
|
||||
|
||||
short initPitchLagParameters(
|
||||
const int sr_core,
|
||||
int *pit_min,
|
||||
int *pit_fr1,
|
||||
int *pit_fr1b,
|
||||
int *pit_fr2,
|
||||
int *pit_max
|
||||
)
|
||||
{
|
||||
|
||||
short pit_res_max;
|
||||
|
||||
|
||||
if (sr_core==12800)
|
||||
{
|
||||
*pit_min = PIT_MIN_12k8;
|
||||
*pit_max = PIT_MAX_12k8;
|
||||
*pit_fr2 = PIT_FR2_12k8;
|
||||
*pit_fr1 = PIT_FR1_12k8;
|
||||
*pit_fr1b = PIT_FR1_8b_12k8;
|
||||
pit_res_max = 4;
|
||||
}
|
||||
else if (sr_core==16000)
|
||||
{
|
||||
*pit_min = PIT_MIN_16k;
|
||||
*pit_max = PIT16k_MAX;
|
||||
*pit_fr2 = PIT_FR2_16k;
|
||||
*pit_fr1 = PIT_FR1_16k;
|
||||
*pit_fr1b = PIT_FR1_8b_16k;
|
||||
pit_res_max = 6;
|
||||
}
|
||||
else if (sr_core==25600)
|
||||
{
|
||||
*pit_min = PIT_MIN_25k6;
|
||||
*pit_max = PIT_MAX_25k6;
|
||||
*pit_fr2 = PIT_FR2_25k6;
|
||||
*pit_fr1 = PIT_FR1_25k6;
|
||||
*pit_fr1b = PIT_FR1_8b_25k6;
|
||||
pit_res_max = 4;
|
||||
}
|
||||
else /* sr_core==32000 */
|
||||
{
|
||||
*pit_min = PIT_MIN_32k;
|
||||
*pit_max = PIT_MAX_32k;
|
||||
*pit_fr2 = PIT_FR2_32k;
|
||||
*pit_fr1 = PIT_FR1_32k;
|
||||
*pit_fr1b = PIT_FR1_8b_32k;
|
||||
pit_res_max = 6;
|
||||
}
|
||||
|
||||
return pit_res_max;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------*
|
||||
* getNumTcxCodedLines()
|
||||
*
|
||||
*
|
||||
*-------------------------------------------------------------------*/
|
||||
|
||||
short getNumTcxCodedLines(
|
||||
const short bwidth
|
||||
)
|
||||
{
|
||||
short tcx_coded_lines;
|
||||
|
||||
switch (bwidth)
|
||||
{
|
||||
case NB:
|
||||
tcx_coded_lines = 160;
|
||||
break;
|
||||
case WB:
|
||||
tcx_coded_lines = 320;
|
||||
break;
|
||||
case SWB:
|
||||
tcx_coded_lines = 640;
|
||||
break;
|
||||
case FB:
|
||||
tcx_coded_lines = 960;
|
||||
break;
|
||||
default:
|
||||
tcx_coded_lines = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return tcx_coded_lines;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------*
|
||||
* getTcxLpcShapedAri()
|
||||
*
|
||||
*
|
||||
*-------------------------------------------------------------------*/
|
||||
|
||||
short getTcxLpcShapedAri(
|
||||
const int total_brate,
|
||||
const short bwidth,
|
||||
const short rf_mode
|
||||
)
|
||||
{
|
||||
short tcx_lpc_shaped_ari = 0;
|
||||
|
||||
(void) bwidth;
|
||||
|
||||
if( total_brate <= LPC_SHAPED_ARI_MAX_RATE || rf_mode )
|
||||
{
|
||||
tcx_lpc_shaped_ari = 1;
|
||||
}
|
||||
|
||||
return tcx_lpc_shaped_ari;
|
||||
}
|
||||
@@ -1,471 +0,0 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "options.h"
|
||||
#include "stl.h"
|
||||
#include "basop_util.h"
|
||||
#include "prot_fx.h"
|
||||
#include "rom_com_fx.h"
|
||||
|
||||
|
||||
Word8 getTcxonly(const Word32 bitrate)
|
||||
{
|
||||
|
||||
Word8 tcxonly;
|
||||
|
||||
tcxonly = 0;
|
||||
move16();
|
||||
if( L_sub(bitrate,32000) > 0 )
|
||||
{
|
||||
tcxonly = 1;
|
||||
move16();
|
||||
}
|
||||
|
||||
return tcxonly;
|
||||
}
|
||||
|
||||
Word8 getCtxHm(const Word32 bitrate, const Word16 rf_flag)
|
||||
{
|
||||
|
||||
Word8 ctx_hm;
|
||||
|
||||
ctx_hm = 0;
|
||||
move16();
|
||||
test();
|
||||
if( (bitrate > LPC_SHAPED_ARI_MAX_RATE) && (bitrate <= 64000) && !rf_flag)
|
||||
{
|
||||
|
||||
ctx_hm = 1;
|
||||
move16();
|
||||
}
|
||||
|
||||
|
||||
return ctx_hm;
|
||||
}
|
||||
|
||||
|
||||
Word8 getResq(const Word32 bitrate)
|
||||
{
|
||||
|
||||
Word8 resq;
|
||||
|
||||
resq = 0;
|
||||
move16();
|
||||
if (L_sub(bitrate,64000) <= 0)
|
||||
{
|
||||
resq = 1;
|
||||
move16();
|
||||
}
|
||||
|
||||
return resq;
|
||||
}
|
||||
|
||||
|
||||
Word8 getTnsAllowed(const Word32 bitrate
|
||||
,const Word16 igf
|
||||
)
|
||||
{
|
||||
Word8 tnsAllowed;
|
||||
|
||||
tnsAllowed = 0;
|
||||
move16();
|
||||
IF ( igf != 0 )
|
||||
{
|
||||
if( L_sub(bitrate, HQ_16k40) > 0 )
|
||||
{
|
||||
tnsAllowed = 1;
|
||||
move16();
|
||||
}
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
if( L_sub(bitrate, HQ_32k) > 0)
|
||||
{
|
||||
tnsAllowed = 1;
|
||||
move16();
|
||||
}
|
||||
}
|
||||
|
||||
return tnsAllowed;
|
||||
}
|
||||
|
||||
|
||||
Word8 getRestrictedMode(const Word32 bitrate, const Word16 Opt_AMR_WB)
|
||||
{
|
||||
|
||||
Word8 restrictedMode;
|
||||
|
||||
restrictedMode = 3;
|
||||
move16();
|
||||
|
||||
test();
|
||||
IF ( (Opt_AMR_WB == 0) && (L_sub(bitrate,32000) > 0 ) )
|
||||
{
|
||||
restrictedMode = 6;
|
||||
move16();
|
||||
}
|
||||
ELSE IF( Opt_AMR_WB )
|
||||
{
|
||||
restrictedMode = 1;
|
||||
move16();
|
||||
}
|
||||
|
||||
return restrictedMode;
|
||||
}
|
||||
|
||||
|
||||
Word16 sr2fscale(const Word32 sr)
|
||||
{
|
||||
Word16 fscale;
|
||||
|
||||
SWITCH(sr)
|
||||
{
|
||||
case 8000:
|
||||
fscale = (FSCALE_DENOM*8000)/12800;
|
||||
move16();
|
||||
BREAK;
|
||||
|
||||
case 12800:
|
||||
fscale = FSCALE_DENOM;
|
||||
move16();
|
||||
BREAK;
|
||||
|
||||
case 16000:
|
||||
fscale = (FSCALE_DENOM*16000)/12800;
|
||||
move16();
|
||||
BREAK;
|
||||
|
||||
case 25600:
|
||||
fscale = (FSCALE_DENOM*25600)/12800;
|
||||
move16();
|
||||
BREAK;
|
||||
|
||||
case 32000:
|
||||
fscale = (FSCALE_DENOM*32000)/12800;
|
||||
move16();
|
||||
BREAK;
|
||||
|
||||
case 48000:
|
||||
fscale = (FSCALE_DENOM*48000)/12800;
|
||||
move16();
|
||||
BREAK;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
fscale = 0; /* just to avoid compiler warning */
|
||||
BREAK;
|
||||
}
|
||||
return fscale;
|
||||
}
|
||||
|
||||
Word32 getCoreSamplerateMode2(const Word32 bitrate, const Word16 bandwidth, const Word16 rf_mode)
|
||||
{
|
||||
|
||||
Word32 sr_core;
|
||||
sr_core = -1; /* to suppress MSVC warning */ move32();
|
||||
|
||||
test();
|
||||
test();
|
||||
test();
|
||||
test();
|
||||
test();
|
||||
test();
|
||||
test();
|
||||
test();
|
||||
|
||||
IF( L_sub( bandwidth,NB) == 0 )
|
||||
{
|
||||
sr_core = 12800;
|
||||
move32();
|
||||
}
|
||||
|
||||
ELSE IF ( L_and(L_sub(bandwidth,WB)==0, L_sub(bitrate,13200)<0) ||
|
||||
L_and(L_sub(bandwidth,SWB)==0, L_sub(bitrate,13200)<=0) || sub(rf_mode,1) == 0 )
|
||||
|
||||
{
|
||||
sr_core = 12800;
|
||||
move32();
|
||||
}
|
||||
ELSE IF (L_sub(bandwidth,WB)==0 || ( (L_sub(bitrate,32000)<=0) && ((L_sub(bandwidth,SWB)==0) || (L_sub(bandwidth,FB)==0)) ) )
|
||||
{
|
||||
sr_core = 16000;
|
||||
move32();
|
||||
}
|
||||
ELSE IF ( ((L_sub(bandwidth,SWB)==0) || (L_sub(bandwidth,FB)==0)) && (L_sub(bitrate,64000)<=0) )
|
||||
{
|
||||
sr_core = 25600;
|
||||
move32();
|
||||
}
|
||||
ELSE IF (L_sub(bandwidth,SWB)==0 || L_sub(bandwidth,FB)==0)
|
||||
{
|
||||
sr_core = 32000;
|
||||
move32();
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
|
||||
return sr_core;
|
||||
}
|
||||
|
||||
Word16 getTcxBandwidth(const Word16 bandwidth)
|
||||
{
|
||||
|
||||
Word16 tcxBandwidth;
|
||||
|
||||
tcxBandwidth = 16384/*0.5f Q15*/;
|
||||
move16();
|
||||
if(sub(bandwidth, NB) == 0)
|
||||
{
|
||||
tcxBandwidth = 10240/*0.3125f Q15*/;
|
||||
move16();
|
||||
|
||||
}
|
||||
|
||||
return tcxBandwidth;
|
||||
}
|
||||
|
||||
|
||||
Word8 getIgfPresent(
|
||||
const Word32 bitrate,
|
||||
const Word16 bandwidth
|
||||
,const Word16 rf_mode
|
||||
)
|
||||
{
|
||||
Word8 igfPresent;
|
||||
|
||||
igfPresent = 0;
|
||||
move16();
|
||||
|
||||
test();
|
||||
test();
|
||||
if( (sub(bandwidth, SWB) == 0) && (L_sub(bitrate, ACELP_9k60) >= 0) && (L_sub(bitrate, HQ_96k) < 0) )
|
||||
{
|
||||
igfPresent = 1;
|
||||
move16();
|
||||
}
|
||||
|
||||
test();
|
||||
if( sub(bandwidth, FB) == 0 && (L_sub(bitrate, ACELP_16k40) >= 0))
|
||||
{
|
||||
igfPresent = 1;
|
||||
move16();
|
||||
}
|
||||
|
||||
test();
|
||||
if( (sub(bandwidth, WB) == 0) && (L_sub(bitrate, ACELP_9k60) == 0) )
|
||||
{
|
||||
igfPresent = 1;
|
||||
move16();
|
||||
}
|
||||
|
||||
test();
|
||||
test();
|
||||
test();
|
||||
if( ((sub(bandwidth, WB) == 0) || (sub(bandwidth, SWB) == 0)) && (sub(rf_mode, 1) == 0) && (L_sub(bitrate, ACELP_13k20) == 0) )
|
||||
{
|
||||
igfPresent = 1;
|
||||
move16();
|
||||
}
|
||||
|
||||
return igfPresent;
|
||||
}
|
||||
|
||||
|
||||
Word8 getCnaPresent(
|
||||
const Word32 bitrate,
|
||||
const Word16 bandwidth
|
||||
)
|
||||
{
|
||||
Word8 flag_cna = 0;
|
||||
|
||||
flag_cna = 0;
|
||||
move16();
|
||||
test();
|
||||
if( sub(bandwidth, NB) == 0 && (L_sub(bitrate, ACELP_13k20) <= 0) )
|
||||
{
|
||||
flag_cna = 1;
|
||||
move16();
|
||||
}
|
||||
|
||||
test();
|
||||
if( (sub(bandwidth, WB) == 0) && (L_sub(bitrate, ACELP_13k20) <= 0) )
|
||||
{
|
||||
flag_cna = 1;
|
||||
move16();
|
||||
}
|
||||
|
||||
test();
|
||||
if( (sub(bandwidth, SWB) == 0) && (L_sub(bitrate, ACELP_13k20) <= 0) )
|
||||
{
|
||||
flag_cna = 1;
|
||||
move16();
|
||||
}
|
||||
|
||||
return flag_cna;
|
||||
}
|
||||
|
||||
Word8 getTcxLtp(const Word32 sr_core)
|
||||
{
|
||||
|
||||
Word8 tcxltp = 0;
|
||||
|
||||
tcxltp = 0;
|
||||
move16();
|
||||
test();
|
||||
if ( (L_sub(sr_core, 25600) <= 0) )
|
||||
{
|
||||
tcxltp = 1;
|
||||
move16();
|
||||
}
|
||||
|
||||
return tcxltp;
|
||||
}
|
||||
|
||||
|
||||
Word16 initPitchLagParameters(
|
||||
const Word32 sr_core,
|
||||
Word16 *pit_min,
|
||||
Word16 *pit_fr1,
|
||||
Word16 *pit_fr1b,
|
||||
Word16 *pit_fr2,
|
||||
Word16 *pit_max
|
||||
)
|
||||
{
|
||||
|
||||
Word16 pit_res_max;
|
||||
|
||||
IF (L_sub(sr_core, 12800) == 0)
|
||||
{
|
||||
|
||||
*pit_min = PIT_MIN_12k8;
|
||||
move16();
|
||||
*pit_max = PIT_MAX_12k8;
|
||||
move16();
|
||||
*pit_fr2 = PIT_FR2_12k8;
|
||||
move16();
|
||||
*pit_fr1 = PIT_FR1_12k8;
|
||||
move16();
|
||||
*pit_fr1b = PIT_FR1_8b_12k8;
|
||||
move16();
|
||||
pit_res_max = 4;
|
||||
move16();
|
||||
|
||||
}
|
||||
ELSE IF (L_sub(sr_core, 16000) == 0)
|
||||
{
|
||||
|
||||
*pit_min = PIT_MIN_16k;
|
||||
move16();
|
||||
*pit_max = PIT_MAX_16k;
|
||||
move16();
|
||||
*pit_fr2 = PIT_FR2_16k;
|
||||
move16();
|
||||
*pit_fr1 = PIT_FR1_16k;
|
||||
move16();
|
||||
*pit_fr1b = PIT_FR1_8b_16k;
|
||||
move16();
|
||||
pit_res_max = 6;
|
||||
move16();
|
||||
|
||||
}
|
||||
ELSE IF (L_sub(sr_core, 25600) == 0)
|
||||
{
|
||||
|
||||
*pit_min = PIT_MIN_25k6;
|
||||
move16();
|
||||
*pit_max = PIT_MAX_25k6;
|
||||
move16();
|
||||
*pit_fr2 = PIT_FR2_25k6;
|
||||
move16();
|
||||
*pit_fr1 = PIT_FR1_25k6;
|
||||
move16();
|
||||
*pit_fr1b = PIT_FR1_8b_25k6;
|
||||
move16();
|
||||
pit_res_max = 4;
|
||||
move16();
|
||||
}
|
||||
ELSE /* sr_core==32000 */
|
||||
{
|
||||
|
||||
*pit_min = PIT_MIN_32k;
|
||||
move16();
|
||||
*pit_max = PIT_MAX_32k;
|
||||
move16();
|
||||
*pit_fr2 = PIT_FR2_32k;
|
||||
move16();
|
||||
*pit_fr1 = PIT_FR1_32k;
|
||||
move16();
|
||||
*pit_fr1b = PIT_FR1_8b_32k;
|
||||
move16();
|
||||
pit_res_max = 6;
|
||||
move16();
|
||||
|
||||
}
|
||||
|
||||
return pit_res_max;
|
||||
}
|
||||
|
||||
Word16 getNumTcxCodedLines(const Word16 bwidth)
|
||||
{
|
||||
|
||||
Word16 tcx_coded_lines;
|
||||
|
||||
tcx_coded_lines = 0;
|
||||
move16();
|
||||
|
||||
if(sub(bwidth, NB) == 0)
|
||||
{
|
||||
tcx_coded_lines = 160;
|
||||
move16();
|
||||
}
|
||||
|
||||
if(sub(bwidth, WB) == 0)
|
||||
{
|
||||
tcx_coded_lines = 320;
|
||||
move16();
|
||||
}
|
||||
|
||||
if(sub(bwidth, SWB) == 0)
|
||||
{
|
||||
tcx_coded_lines = 640;
|
||||
move16();
|
||||
}
|
||||
|
||||
if(sub(bwidth, FB) == 0)
|
||||
{
|
||||
tcx_coded_lines = 960;
|
||||
move16();
|
||||
}
|
||||
|
||||
return tcx_coded_lines;
|
||||
}
|
||||
|
||||
Word16 getTcxLpcShapedAri(
|
||||
const Word32 total_brate,
|
||||
const Word16 bwidth
|
||||
,const Word16 rf_mode
|
||||
)
|
||||
{
|
||||
Word16 tcx_lpc_shaped_ari = 0;
|
||||
move16();
|
||||
|
||||
(void) bwidth;
|
||||
|
||||
test();
|
||||
if( (L_sub(total_brate, LPC_SHAPED_ARI_MAX_RATE) <= 0) || rf_mode )
|
||||
{
|
||||
tcx_lpc_shaped_ari = 1;
|
||||
move16();
|
||||
}
|
||||
|
||||
|
||||
return tcx_lpc_shaped_ari;
|
||||
}
|
||||
37
src/libs/libevs/lib_com/deemph.cpp
Normal file
37
src/libs/libevs/lib_com/deemph.cpp
Normal file
@@ -0,0 +1,37 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.443 Nov 13, 2018. Version 12.11.0 / 13.7.0 / 14.3.0 / 15.1.0
|
||||
====================================================================================*/
|
||||
|
||||
#include "options.h"
|
||||
#include "prot.h"
|
||||
|
||||
/*-------------------------------------------------------------------*
|
||||
* deemph()
|
||||
*
|
||||
* Deemphasis: filtering through 1/(1-mu z^-1)
|
||||
*-------------------------------------------------------------------*/
|
||||
|
||||
void deemph(
|
||||
float *signal, /* i/o: signal */
|
||||
const float mu, /* i : deemphasis factor */
|
||||
const short L, /* i : vector size */
|
||||
float *mem /* i/o: memory (y[-1]) */
|
||||
)
|
||||
{
|
||||
short i;
|
||||
|
||||
signal[0] = signal[0] + mu * (*mem);
|
||||
for (i=1; i<L; i++)
|
||||
{
|
||||
signal[i] = signal[i] + mu * signal[i-1];
|
||||
}
|
||||
|
||||
*mem = signal[L-1];
|
||||
|
||||
if( (*mem < 1e-10) & (*mem > -1e-10) )
|
||||
{
|
||||
*mem = 0;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -1,136 +0,0 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#include "options.h" /* Compilation switches */
|
||||
#include "prot_fx.h" /* Function prototypes */
|
||||
#include "stl.h"
|
||||
#include "basop_util.h"
|
||||
|
||||
/*========================================================================*/
|
||||
/* FUNCTION : deemph_fx() */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* PURPOSE : Deemphasis: filtering through 1/(1-mu z^-1) */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* INPUT ARGUMENTS : */
|
||||
/* _ (Word16) mu : deemphasis factor Q15 */
|
||||
/* _ (Word16) L : vector size */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* INPUT/OUTPUT ARGUMENTS : */
|
||||
/* _ (Word16*) signal : signal Q_syn2-1 */
|
||||
/* _ (Word16*) mem : memory (y[-1]) Q_syn2-1 */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* OUTPUT ARGUMENTS : */
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* RETURN ARGUMENTS : */
|
||||
/* _ None */
|
||||
/*========================================================================*/
|
||||
void deemph_fx(
|
||||
Word16 *signal, /* i/o: signal Qx */
|
||||
const Word16 mu, /* i : deemphasis factor Q15 */
|
||||
const Word16 L, /* i : vector size Q0 */
|
||||
Word16 *mem /* i/o: memory (y[-1]) Qx */
|
||||
)
|
||||
{
|
||||
Word16 i;
|
||||
Word32 L_tmp;
|
||||
|
||||
L_tmp = L_deposit_h(signal[0]);
|
||||
L_tmp = L_mac(L_tmp, *mem, mu);
|
||||
signal[0] = round_fx(L_tmp);
|
||||
|
||||
FOR (i = 1; i < L; i++)
|
||||
{
|
||||
L_tmp = L_deposit_h(signal[i]);
|
||||
L_tmp = L_mac(L_tmp, signal[i - 1], mu);
|
||||
signal[i] = round_fx(L_tmp);
|
||||
}
|
||||
|
||||
*mem = signal[L - 1];
|
||||
move16();
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------*
|
||||
* Deeemph2 :
|
||||
*
|
||||
* Deemphasis: filtering through 1/(1-mu z^-1)
|
||||
* Output divided by 2
|
||||
*-------------------------------------------------------------------*/
|
||||
void Deemph2(
|
||||
Word16 x[], /* i/o: input signal overwritten by the output Qx/Qx-1 */
|
||||
const Word16 mu, /* i : deemphasis factor Q15 */
|
||||
const Word16 L, /* i : vector size Q0 */
|
||||
Word16 *mem /* i/o: memory (y[-1]) Qx-1 */
|
||||
)
|
||||
{
|
||||
Word16 i;
|
||||
Word32 L_tmp;
|
||||
|
||||
/* saturation can occur in L_mac() */
|
||||
|
||||
L_tmp = L_mult(x[0], 16384);
|
||||
x[0] = mac_r(L_tmp, *mem, mu);
|
||||
move16();
|
||||
|
||||
FOR (i = 1; i < L; i++)
|
||||
{
|
||||
L_tmp = L_mult(x[i], 16384);
|
||||
x[i] = mac_r(L_tmp, x[i - 1], mu);
|
||||
move16();
|
||||
}
|
||||
|
||||
*mem = x[L - 1];
|
||||
move16();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* E_UTIL_deemph2
|
||||
*
|
||||
* Parameters:
|
||||
* shift I: scale output
|
||||
* x I/O: signal Qx/Qx-shift
|
||||
* mu I: deemphasis factor Qx
|
||||
* L I: vector size
|
||||
* mem I/O: memory (signal[-1]) Qx
|
||||
*
|
||||
* Function:
|
||||
* Filtering through 1/(1-mu z^-1)
|
||||
* Signal is divided by 2.
|
||||
*
|
||||
* Returns:
|
||||
* void
|
||||
*/
|
||||
void E_UTIL_deemph2(Word16 shift, Word16 *x, const Word16 mu, const Word16 L, Word16 *mem)
|
||||
{
|
||||
Word16 i;
|
||||
Word32 L_tmp;
|
||||
|
||||
/* signal[0] = signal[0] + mu * (*mem); */
|
||||
L_tmp = L_deposit_h(*mem);
|
||||
IF(shift >= 0)
|
||||
{
|
||||
shift = shr(-32768, shift);
|
||||
FOR (i = 0; i < L; i++)
|
||||
{
|
||||
L_tmp = L_msu(Mpy_32_16_1(L_tmp, mu), x[i],shift);
|
||||
x[i] = round_fx(L_tmp);
|
||||
}
|
||||
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
FOR (i = 0; i < L; i++)
|
||||
{
|
||||
L_tmp = L_msu(Mpy_32_16_1(L_tmp, mu), shr(x[i],shift),-32768);
|
||||
x[i] = round_fx(L_tmp);
|
||||
}
|
||||
}
|
||||
|
||||
*mem = x[L - 1];
|
||||
move16();
|
||||
|
||||
return;
|
||||
}
|
||||
34
src/libs/libevs/lib_com/delay_comp.cpp
Executable file → Normal file
34
src/libs/libevs/lib_com/delay_comp.cpp
Executable file → Normal file
@@ -1,41 +1,37 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
EVS Codec 3GPP TS26.443 Nov 13, 2018. Version 12.11.0 / 13.7.0 / 14.3.0 / 15.1.0
|
||||
====================================================================================*/
|
||||
|
||||
#include "options.h" /* Compilation switches */
|
||||
#include "stl.h"
|
||||
#include "prot_fx.h"
|
||||
#include "options.h"
|
||||
#include "prot.h"
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
* get_delay_fx()
|
||||
*
|
||||
* Function returns various types of delays in the codec in ms.
|
||||
*--------------------------------------------------------------------------*/
|
||||
* get_delay()
|
||||
*
|
||||
* Function returns various types of delays in the codec in ms.
|
||||
*--------------------------------------------------------------------------*/
|
||||
|
||||
Word32 get_delay_fx( /* o : delay value in ms */
|
||||
const Word16 what_delay, /* i : what delay? (ENC or DEC) */
|
||||
const Word32 io_fs /* i : input/output sampling frequency */
|
||||
float get_delay( /* o : delay value in ms */
|
||||
const short what_delay, /* i : what delay? (ENC or DEC) */
|
||||
const int io_fs /* i : input/output sampling frequency */
|
||||
)
|
||||
{
|
||||
Word32 delay = 0;
|
||||
float delay = 0;
|
||||
|
||||
IF( sub(what_delay,ENC) == 0 )
|
||||
if( what_delay == ENC )
|
||||
{
|
||||
delay = (DELAY_FIR_RESAMPL_NS + ACELP_LOOK_NS);
|
||||
move32();
|
||||
}
|
||||
ELSE
|
||||
else
|
||||
{
|
||||
IF( L_sub(io_fs,8000) == 0 )
|
||||
if( io_fs == 8000 )
|
||||
{
|
||||
delay = DELAY_CLDFB_NS;
|
||||
move32();
|
||||
}
|
||||
ELSE
|
||||
else
|
||||
{
|
||||
delay = DELAY_BWE_TOTAL_NS;
|
||||
move32();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
15
src/libs/libevs/lib_com/disclaimer.cpp
Executable file → Normal file
15
src/libs/libevs/lib_com/disclaimer.cpp
Executable file → Normal file
@@ -1,18 +1,17 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
EVS Codec 3GPP TS26.443 Nov 13, 2018. Version 12.11.0 / 13.7.0 / 14.3.0 / 15.1.0
|
||||
====================================================================================*/
|
||||
|
||||
#include "disclaimer.h"
|
||||
#include "options.h"
|
||||
#include "stl.h"
|
||||
|
||||
/* WMC_TOOL_SKIP_FILE */
|
||||
#include "options.h"
|
||||
#include "prot.h"
|
||||
|
||||
int print_disclaimer(FILE *fPtr)
|
||||
{
|
||||
|
||||
fprintf(fPtr, "\n==============================================================================\n");
|
||||
fprintf(fPtr, " EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0\n");
|
||||
fprintf(fPtr, "==============================================================================\n\n\n");
|
||||
fprintf(fPtr, "\n===================================================================================================\n");
|
||||
fprintf(fPtr, " EVS Codec (Floating Point) 3GPP TS26.443 Nov 13, 2018. Version 12.11.0 / 13.7.0 / 14.3.0 / 15.1.0\n");
|
||||
fprintf(fPtr, "===================================================================================================\n\n\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#ifndef __INCLUDED_DISCLAIMER_H
|
||||
#define __INCLUDED_DISCLAIMER_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
int print_disclaimer(FILE *fPtr);
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* __INCLUDED_DISCLAIMER_H */
|
||||
73
src/libs/libevs/lib_com/dlpc_bfi.cpp
Executable file → Normal file
73
src/libs/libevs/lib_com/dlpc_bfi.cpp
Executable file → Normal file
@@ -1,55 +1,48 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
EVS Codec 3GPP TS26.443 Nov 13, 2018. Version 12.11.0 / 13.7.0 / 14.3.0 / 15.1.0
|
||||
====================================================================================*/
|
||||
|
||||
|
||||
/* Header files */
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "prot_fx.h"
|
||||
#include "stl.h"
|
||||
#include "prot_fx.h"
|
||||
#include "options.h"
|
||||
#include "prot.h"
|
||||
#include "rom_com.h"
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------*
|
||||
* routine: dlpc_bfi()
|
||||
*
|
||||
*
|
||||
*---------------------------------------------------------------------*/
|
||||
|
||||
void dlpc_bfi(
|
||||
const Word16 L_frame,
|
||||
Word16 *lsf_q, /* o : quantized LSFs */
|
||||
const Word16 *lsfold, /* i : past quantized LSF */
|
||||
const Word16 last_good, /* i : last good received frame */
|
||||
const Word16 nbLostCmpt, /* i : counter of consecutive bad frames */
|
||||
Word16 mem_MA[], /* i/o: quantizer memory for MA model */
|
||||
Word16 mem_AR[], /* i/o: quantizer memory for AR model */
|
||||
Word16 *stab_fac, /* i : LSF stability factor */
|
||||
Word16 *lsf_adaptive_mean,/* i : LSF adaptive mean, updated when BFI==0 */
|
||||
Word16 numlpc, /* i : Number of division per superframe */
|
||||
Word16 lsf_cng[],
|
||||
Word8 plcBackgroundNoiseUpdated,
|
||||
Word16 *lsf_q_cng, /* o : quantized LSFs */
|
||||
Word16 *old_lsf_q_cng, /* o : old quantized LSFs for background noise */
|
||||
const Word16* lsfBase, /* i : base for differential LSF coding */
|
||||
Word8 tcxonly
|
||||
int L_frame,
|
||||
float *lsf_q, /* o : quantized lsfs */
|
||||
const float *lsfold, /* i : past quantized lsf */
|
||||
const short last_good, /* i : last good received frame */
|
||||
const short nbLostCmpt, /* i : counter of consecutive bad frames */
|
||||
float mem_MA[], /* i/o: quantizer memory for MA model */
|
||||
float *mem_AR, /* i/o: quantizer memory for AR model */
|
||||
float *stab_fac, /* i : lsf stability factor */
|
||||
float *lsf_adaptive_mean,/* i : lsf adaptive mean, updated when BFI==0 */
|
||||
int numlpc, /* i : Number of division per superframe */
|
||||
float lsf_cng[],
|
||||
int plcBackgroundNoiseUpdated,
|
||||
float *lsf_q_cng, /* o : quantized lsfs of background noise */
|
||||
float *old_lsf_q_cng, /* o : old quantized lsfs for background noise */
|
||||
const float lsfBase[] /* i : base for differential lsf coding */
|
||||
)
|
||||
{
|
||||
lsf_dec_bfi( MODE2, &lsf_q[0], lsfold, lsf_adaptive_mean, lsfBase, mem_MA, mem_AR, *stab_fac, 0, L_frame, last_good,
|
||||
nbLostCmpt, plcBackgroundNoiseUpdated, lsf_q_cng, lsf_cng, old_lsf_q_cng, 0, 0, 0 );
|
||||
|
||||
lsf_dec_bfi(
|
||||
MODE2,
|
||||
&lsf_q[0], lsfold, lsf_adaptive_mean, lsfBase, mem_MA, mem_AR, *stab_fac,
|
||||
0, L_frame, last_good, nbLostCmpt,
|
||||
plcBackgroundNoiseUpdated, lsf_q_cng, lsf_cng, old_lsf_q_cng, 0, 0, tcxonly
|
||||
,0
|
||||
|
||||
);
|
||||
IF ( sub(numlpc,2)==0 )
|
||||
if( numlpc == 2 )
|
||||
{
|
||||
/* Decode the second LPC */
|
||||
lsf_dec_bfi(
|
||||
MODE2,
|
||||
&lsf_q[M], &lsf_q[0], lsf_adaptive_mean, lsfBase, mem_MA, mem_AR, *stab_fac,
|
||||
0, L_frame, last_good, nbLostCmpt+1,
|
||||
plcBackgroundNoiseUpdated, lsf_q_cng, lsf_cng, old_lsf_q_cng, 0, 0, tcxonly
|
||||
,0
|
||||
);
|
||||
lsf_dec_bfi( MODE2, &lsf_q[M], &lsf_q[0], lsf_adaptive_mean, lsfBase, mem_MA, mem_AR, *stab_fac, 0, L_frame, last_good,
|
||||
nbLostCmpt+1, plcBackgroundNoiseUpdated, lsf_q_cng, lsf_cng, old_lsf_q_cng, 0, 0, 0 );
|
||||
}
|
||||
/**/ /*No local variabvles defined*/
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
193
src/libs/libevs/lib_com/edct.cpp
Normal file
193
src/libs/libevs/lib_com/edct.cpp
Normal file
@@ -0,0 +1,193 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.443 Nov 13, 2018. Version 12.11.0 / 13.7.0 / 14.3.0 / 15.1.0
|
||||
====================================================================================*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include "options.h"
|
||||
#include "cnst.h"
|
||||
#include "rom_com.h"
|
||||
#include "prot.h"
|
||||
|
||||
static float const * get_edct_table(short length)
|
||||
{
|
||||
float const * edct_table = NULL;
|
||||
switch (length)
|
||||
{
|
||||
case 1200:
|
||||
edct_table = edct_table_600;
|
||||
break;
|
||||
case 960:
|
||||
edct_table = edct_table_480;
|
||||
break;
|
||||
case 640:
|
||||
edct_table = edct_table_320;
|
||||
break;
|
||||
case 320:
|
||||
edct_table = edct_table_160;
|
||||
break;
|
||||
case 256:
|
||||
edct_table = edct_table_128;
|
||||
break;
|
||||
case 240:
|
||||
edct_table = edct_table_120;
|
||||
break;
|
||||
case 200:
|
||||
edct_table = edct_table_100;
|
||||
break;
|
||||
case 160:
|
||||
edct_table = edct_table_80;
|
||||
break;
|
||||
case 40:
|
||||
edct_table = edct_table_20;
|
||||
break;
|
||||
case 800:
|
||||
edct_table = edct_table_400;
|
||||
break;
|
||||
case 512:
|
||||
edct_table = edct_table_256;
|
||||
break;
|
||||
case 480:
|
||||
edct_table = edct_table_240;
|
||||
break;
|
||||
case 400:
|
||||
edct_table = edct_table_200;
|
||||
break;
|
||||
case 128:
|
||||
edct_table = edct_table_64;
|
||||
break;
|
||||
case 80:
|
||||
edct_table = edct_table_40;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "edct/edst(): length is not in table!");
|
||||
exit(-1);
|
||||
break;
|
||||
}
|
||||
return edct_table;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------*
|
||||
* edct()
|
||||
*
|
||||
* DCT transform
|
||||
*-----------------------------------------------------------------*/
|
||||
|
||||
void edct(
|
||||
const float *x, /* i : input signal */
|
||||
float *y, /* o : output transform */
|
||||
short length /* i : length */
|
||||
)
|
||||
{
|
||||
short i;
|
||||
float re[L_FRAME_PLUS/2];
|
||||
float im[L_FRAME_PLUS/2];
|
||||
const float *edct_table = 0;
|
||||
float local;
|
||||
|
||||
edct_table = get_edct_table(length);
|
||||
|
||||
/* Twiddling and Pre-rotate */
|
||||
for (i = 0; i < length/2; i++)
|
||||
{
|
||||
re[i] = x[2*i] * edct_table[i] + x[length-1-2*i] * edct_table[length/2-1-i];
|
||||
im[i] = x[length-1-2*i] * edct_table[i] - x[2*i] * edct_table[length/2-1-i];
|
||||
}
|
||||
|
||||
DoFFT(re, im, length/2);
|
||||
|
||||
local = (0.75f * EVS_PI)/ length;
|
||||
|
||||
for (i = 0; i < length/2; i++)
|
||||
{
|
||||
float tmp;
|
||||
tmp = re[i] - im[i] * local; /* 3*pi/(4*length) is a constant */
|
||||
im[i] = im[i] + re[i] * local;
|
||||
re[i] = tmp;
|
||||
}
|
||||
|
||||
/* Post-rotate and obtain the output data */
|
||||
for (i = 0; i < length/2; i++)
|
||||
{
|
||||
y[2*i] = re[i] * edct_table[i] + im[i] * edct_table[length/2-1-i];
|
||||
y[length-1-2*i] = re[i] * edct_table[length/2-1-i] - im[i] * edct_table[i];
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*
|
||||
* FUNCTION : edst()
|
||||
*
|
||||
* PURPOSE : DST_IV transform
|
||||
*-------------------------------------------------------------------------*/
|
||||
void edst(
|
||||
const float *x, /* i : input signal */
|
||||
float *y, /* o : output transform */
|
||||
short length /* i : length */
|
||||
)
|
||||
{
|
||||
short i;
|
||||
float re[L_FRAME_PLUS/2];
|
||||
float im[L_FRAME_PLUS/2];
|
||||
const float *edct_table = 0;
|
||||
float local;
|
||||
|
||||
edct_table = get_edct_table(length);
|
||||
|
||||
/* Twiddling and Pre-rotate */
|
||||
for (i = 0; i < length/2; i++)
|
||||
{
|
||||
re[i] = x[length-1-2*i] * edct_table[i] + x[2*i] *edct_table[length/2-1-i];
|
||||
im[i] = x[2*i] * edct_table[i] - x[length-1-2*i] * edct_table[length/2-1-i];
|
||||
}
|
||||
|
||||
DoFFT(re, im, length/2);
|
||||
|
||||
local = (0.75f * EVS_PI)/ length;
|
||||
|
||||
for (i = 0; i < length/2; i++)
|
||||
{
|
||||
float tmp;
|
||||
tmp = re[i] - im[i] * local; /* 3*pi/(4*length) is a constant */
|
||||
im[i] = im[i] + re[i] * local;
|
||||
re[i] = tmp;
|
||||
}
|
||||
|
||||
/* Post-rotate and obtain the output data */
|
||||
for (i = 0; i < length/2; i++)
|
||||
{
|
||||
y[2*i] = re[i] * edct_table[i] + im[i] * edct_table[length/2-1-i];
|
||||
y[length-1-2*i] = im[i] * edct_table[i] - re[i] * edct_table[length/2-1-i];
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------*
|
||||
* iedct_short()
|
||||
*
|
||||
* Inverse EDCT for short frames
|
||||
*-----------------------------------------------------------------*/
|
||||
|
||||
void iedct_short(
|
||||
const float *in, /* i : input vector */
|
||||
float *out, /* o : output vector */
|
||||
const short segment_length /* i : length */
|
||||
)
|
||||
{
|
||||
float alias[MAX_SEGMENT_LENGTH];
|
||||
short i;
|
||||
|
||||
edct(in, alias, segment_length/2);
|
||||
|
||||
for (i = 0; i < segment_length/4; i++)
|
||||
{
|
||||
out[i] = alias[segment_length/4 + i];
|
||||
out[segment_length/4 + i] = -alias[segment_length/2 - 1 - i];
|
||||
out[segment_length/2 + i] = -alias[segment_length/4 - 1 - i];
|
||||
out[3*segment_length/4 + i] = -alias[i];
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -1,426 +0,0 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include "options.h" /* Compilation switches */
|
||||
#include "cnst_fx.h" /* Common constants */
|
||||
#include "rom_com_fx.h" /* Static table prototypes */
|
||||
#include "prot_fx.h" /* Function prototypes */
|
||||
#include "stl.h"
|
||||
|
||||
|
||||
#include "math_32.h"
|
||||
|
||||
static Word16 const * get_edct_table(Word16 length, Word16 *q)
|
||||
{
|
||||
Word16 const * edct_table = NULL;
|
||||
SWITCH (length)
|
||||
{
|
||||
case 1200:
|
||||
edct_table = edct_table_600_fx;
|
||||
move16();
|
||||
*q = add(*q, 2);
|
||||
BREAK;
|
||||
case 960 :
|
||||
edct_table = edct_table_480_fx;
|
||||
move16();
|
||||
BREAK;
|
||||
case 640 :
|
||||
edct_table = edct_table_320_fx;
|
||||
move16();
|
||||
BREAK;
|
||||
case 320 :
|
||||
edct_table = edct_table_160_fx;
|
||||
move16();
|
||||
BREAK;
|
||||
case 256 :
|
||||
edct_table = edct_table_128_fx;
|
||||
move16();
|
||||
BREAK;
|
||||
case 240 :
|
||||
edct_table = edct_table_120_fx;
|
||||
move16();
|
||||
BREAK;
|
||||
case 200 :
|
||||
edct_table = edct_table_100_fx;
|
||||
move16();
|
||||
BREAK;
|
||||
case 160 :
|
||||
edct_table = edct_table_80_fx ;
|
||||
move16();
|
||||
BREAK;
|
||||
case 40 :
|
||||
edct_table = edct_table_20_fx ;
|
||||
move16();
|
||||
BREAK;
|
||||
case 800 :
|
||||
edct_table = edct_table_400_fx;
|
||||
move16();
|
||||
*q = add(*q, 2);
|
||||
BREAK;
|
||||
case 512 :
|
||||
edct_table = edct_table_256_fx;
|
||||
move16();
|
||||
BREAK;
|
||||
case 480 :
|
||||
edct_table = edct_table_240_fx;
|
||||
move16();
|
||||
BREAK;
|
||||
case 400 :
|
||||
edct_table = edct_table_200_fx;
|
||||
move16();
|
||||
BREAK;
|
||||
case 128 :
|
||||
edct_table = edct_table_64_fx ;
|
||||
move16();
|
||||
BREAK;
|
||||
case 80 :
|
||||
edct_table = edct_table_40_fx ;
|
||||
move16();
|
||||
BREAK;
|
||||
default:
|
||||
BREAK;
|
||||
}
|
||||
return edct_table;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*
|
||||
* FUNCTION : edct_fx()
|
||||
*
|
||||
* PURPOSE : DCT transform
|
||||
*
|
||||
* INPUT ARGUMENTS :
|
||||
* _ (Word16) length : length
|
||||
* _ (Word16*) x : input signal Qx
|
||||
* _ (Word16*) edct_table_128_fx : edct table Q16
|
||||
*
|
||||
* OUTPUT ARGUMENTS :
|
||||
* _ (Word16[]) y : output transform Qx
|
||||
*-------------------------------------------------------------------------*/
|
||||
void edct_fx(
|
||||
const Word32 *x, /* i : input signal Qq */
|
||||
Word32 *y, /* o : output transform Qq */
|
||||
Word16 length, /* i : length */
|
||||
Word16 *q /* i : Q value of input signal */
|
||||
)
|
||||
{
|
||||
Word16 i;
|
||||
Word32 re;
|
||||
Word32 im;
|
||||
const Word16 *edct_table = 0; /*Q16 */
|
||||
Word32 re2[L_FRAME48k/2+240];
|
||||
Word32 im2[L_FRAME48k/2+240];
|
||||
Word32 L_tmp;
|
||||
Word16 tmp;
|
||||
Word16 len1;
|
||||
|
||||
edct_table = get_edct_table(length, q);
|
||||
len1 = shr(length, 1);
|
||||
/* Twiddling and Pre-rotate */
|
||||
FOR (i = 0; i < len1; i++)
|
||||
{
|
||||
L_tmp = Mult_32_16(x[2*i], edct_table[i]); /*Q(q+1) */
|
||||
re2[i] = Madd_32_16(L_tmp, x[length-1-2*i], edct_table[len1-1-i]); /*Q(q+1) */ move32();
|
||||
|
||||
L_tmp = Mult_32_16(x[length-1-2*i], edct_table[i]); /*Q(q+1) */
|
||||
|
||||
im2[i] = Msub_32_16(L_tmp, x[2*i], edct_table[len1-1-i]); /*Q(q+1) */ move32();
|
||||
}
|
||||
|
||||
*q = sub(15, *q);
|
||||
BASOP_cfft(re2, im2, len1, 1, q, y);
|
||||
|
||||
tmp = div_s(1, length); /*Q15 */
|
||||
tmp = round_fx(L_shl(L_mult(tmp, 19302), 2)); /*Q15 */
|
||||
FOR (i = 0; i < len1; i++)
|
||||
{
|
||||
re = Msub_32_16(re2[i], im2[i], tmp);
|
||||
im = Madd_32_16(im2[i], re2[i], tmp);
|
||||
y[2 * i] = L_add(Mult_32_16(re, edct_table[i]), Mult_32_16(im, edct_table[len1 - 1 - i]));
|
||||
move32();
|
||||
y[length - 1 - 2 * i] = L_sub(Mult_32_16(re, edct_table[len1 - 1 - i]), Mult_32_16(im, edct_table[i]));
|
||||
move32();
|
||||
} /*Q(q-2) */
|
||||
|
||||
*q = sub(15+2, *q);
|
||||
return;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*
|
||||
* FUNCTION : edst_fx()
|
||||
*
|
||||
* PURPOSE : DST_IV transform
|
||||
*
|
||||
* INPUT ARGUMENTS :
|
||||
* _ (Word16) length : length
|
||||
* _ (Word16*) x : input signal Qx
|
||||
* _ (Word16*) edct_table_128_fx : edct table Q16
|
||||
*
|
||||
* OUTPUT ARGUMENTS :
|
||||
* _ (Word16[]) y : output transform Qx
|
||||
*-------------------------------------------------------------------------*/
|
||||
void edst_fx(
|
||||
const Word32 *x, /* i : input signal Qq */
|
||||
Word32 *y, /* o : output transform Qq */
|
||||
Word16 length, /* i : length */
|
||||
Word16 *q /* i : Q value of input signal */
|
||||
)
|
||||
{
|
||||
Word16 i;
|
||||
Word32 re;
|
||||
Word32 im;
|
||||
const Word16 *edct_table = 0; /*Q16 */
|
||||
Word32 re2[L_FRAME48k/2+240];
|
||||
Word32 im2[L_FRAME48k/2+240];
|
||||
Word32 L_tmp;
|
||||
Word16 tmp;
|
||||
Word16 len1;
|
||||
|
||||
edct_table = get_edct_table(length, q);
|
||||
len1 = shr(length, 1);
|
||||
/* Twiddling and Pre-rotate */
|
||||
FOR (i = 0; i < len1; i++)
|
||||
{
|
||||
L_tmp = Mult_32_16(x[length-1-2*i], edct_table[i]);
|
||||
re2[i] = Madd_32_16(L_tmp, x[2*i], edct_table[len1-1-i]);
|
||||
move32();
|
||||
|
||||
L_tmp = Mult_32_16(x[2*i], edct_table[i]);
|
||||
im2[i] = Msub_32_16(L_tmp, x[length-1-2*i], edct_table[len1-1-i]);
|
||||
move32();
|
||||
}
|
||||
|
||||
*q = sub(15, *q);
|
||||
BASOP_cfft(re2, im2, len1, 1, q, y);
|
||||
|
||||
tmp = div_s(1, length); /*Q15 */
|
||||
tmp = round_fx(L_shl(L_mult(tmp, 19302), 2)); /*Q15 */
|
||||
FOR (i = 0; i < len1; i++)
|
||||
{
|
||||
re = Msub_32_16(re2[i], im2[i], tmp);
|
||||
im = Madd_32_16(im2[i], re2[i], tmp);
|
||||
y[2 * i] = L_add(Mult_32_16(re, edct_table[i]), Mult_32_16(im, edct_table[len1 - 1 - i]));
|
||||
move32();
|
||||
y[length - 1 - 2 * i] = L_sub(Mult_32_16(im, edct_table[i]), Mult_32_16(re, edct_table[len1 - 1 - i]));
|
||||
move32();
|
||||
} /*Q(q) */
|
||||
|
||||
*q = sub(15+2, *q);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*========================================================================*/
|
||||
/* FUNCTION : edct_fx() */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* PURPOSE : DCT transform */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* INPUT ARGUMENTS : */
|
||||
/* _ (Word16) length : length */
|
||||
/* _ (Word16*) x : input signal Qx */
|
||||
/* _ (Word16*) edct_table_128_fx : edct table Q15 */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* INPUT/OUTPUT ARGUMENTS : */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* OUTPUT ARGUMENTS : */
|
||||
/* _ (Word16[]) y : output transform Qx */
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* RETURN ARGUMENTS : */
|
||||
/* _ None */
|
||||
/*========================================================================*/
|
||||
void edct_16fx(
|
||||
const Word16 *x, /* i : input signal Qx */
|
||||
Word16 *y, /* o : output transform Qx */
|
||||
Word16 length, /* i : length */
|
||||
Word16 bh /* bit-headroom */
|
||||
)
|
||||
{
|
||||
Word16 i;
|
||||
Word16 re[L_FRAME48k/2];
|
||||
Word16 im[L_FRAME48k/2];
|
||||
const Word16 *edct_table = 0;
|
||||
Word16 re2[L_FRAME48k/2];
|
||||
Word16 im2[L_FRAME48k/2];
|
||||
|
||||
Word32 L_tmp, Lacc, Lmax;
|
||||
Word16 tmp, fact;
|
||||
Word16 Q_edct;
|
||||
Word16 Len2, i2;
|
||||
const Word16 *px, *pt;
|
||||
Word16 *py;
|
||||
|
||||
/*COMPLETE: some eDCT sub function are missing */
|
||||
|
||||
IF (sub(length,L_FRAME32k) == 0)
|
||||
{
|
||||
edct_table = &edct_table_320_16fx[0];
|
||||
move16();
|
||||
}
|
||||
ELSE IF (sub(length,L_FRAME) == 0)
|
||||
{
|
||||
edct_table = &edct_table_128_16fx[0];
|
||||
move16();
|
||||
}
|
||||
ELSE IF (sub(length,L_FRAME16k) == 0)
|
||||
{
|
||||
edct_table = &edct_table_160_16fx[0];
|
||||
move16();
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
}
|
||||
|
||||
/* Twiddling and Pre-rotate */
|
||||
Lmax = L_deposit_l(0);
|
||||
Len2 = shr(length,1);
|
||||
px = x + length - 1;
|
||||
pt = edct_table + Len2 - 1;
|
||||
FOR (i = 0; i < Len2; i++)
|
||||
{
|
||||
i2 = shl(i,1);
|
||||
L_tmp = L_mult(x[i2],edct_table[i]);/*Q(Qx+16) */
|
||||
|
||||
Lacc = L_mac(L_tmp,*px,*pt);/*Q(Qx+16) */
|
||||
|
||||
Lmax = L_max(Lmax, Lacc);
|
||||
|
||||
L_tmp = L_mult(*px,edct_table[i]);/*Q(Qx+16) */
|
||||
Lacc = L_msu(L_tmp,x[i2],*pt);/*Q(Qx+16) */
|
||||
Lmax = L_max(Lmax, Lacc);
|
||||
|
||||
px -= 2;
|
||||
pt--;
|
||||
}
|
||||
|
||||
tmp = 31;
|
||||
if( Lmax != 0 )
|
||||
{
|
||||
tmp = norm_l(Lmax);
|
||||
}
|
||||
Q_edct = sub(tmp,bh); /*creating a bit-headroom */
|
||||
|
||||
px = x + length - 1;
|
||||
pt = edct_table + Len2 - 1;
|
||||
FOR (i = 0; i < Len2; i++)
|
||||
{
|
||||
i2 = shl(i,1);
|
||||
|
||||
L_tmp = L_mult(x[i2],edct_table[i]);/*Q(Qx+16) */
|
||||
Lacc = L_mac(L_tmp,*px,*pt);/*Q(Qx+16) */
|
||||
re2[i] = round_fx(L_shl(Lacc, Q_edct)); /* Q(Qx+Q_edct) */
|
||||
|
||||
L_tmp = L_mult(*px,edct_table[i]);/*Q(Qx+16) */
|
||||
Lacc = L_msu(L_tmp,x[i2],*pt);/*Q(Qx+16) */
|
||||
im2[i] = round_fx(L_shl(Lacc, Q_edct)); /* Q(Qx+Q_edct) */
|
||||
|
||||
px -= 2;
|
||||
pt--;
|
||||
}
|
||||
IF (sub(length,L_FRAME32k) == 0)
|
||||
{
|
||||
DoRTFT320_16fx(re2, im2);
|
||||
}
|
||||
ELSE IF (sub(length,L_FRAME )== 0)
|
||||
{
|
||||
DoRTFT128_16fx(re2, im2);
|
||||
}
|
||||
ELSE IF (sub(length,L_FRAME16k) == 0)
|
||||
{
|
||||
DoRTFT160_16fx(re2, im2);
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
}
|
||||
tmp = div_s(1,length); /*Q15 */
|
||||
L_tmp = L_mult(tmp,19302); /*Q29, (3*PI/4) in Q13 */
|
||||
fact = round_fx(L_shl(L_tmp,2)); /*Q15 */
|
||||
FOR (i = 0; i < length/2; i++)
|
||||
{
|
||||
tmp = mult_r(im2[i],fact); /*Q(Qx+Q_edct) */
|
||||
re[i] = sub(re2[i],tmp); /*Q(Qx+Q_edct) */ move16();
|
||||
|
||||
tmp = mult_r(re2[i],fact); /*Q(Qx+Q_edct) */
|
||||
im[i] = add(im2[i],tmp); /*Q(Qx+Q_edct) */ move16();
|
||||
}
|
||||
|
||||
/* Post-rotate and obtain the output data */
|
||||
py = y + length - 1;
|
||||
pt = edct_table + Len2 - 1;
|
||||
FOR (i = 0; i < Len2; i++)
|
||||
{
|
||||
i2 = shl(i,1);
|
||||
|
||||
L_tmp = L_mult(re[i],edct_table[i]);/*Q(Qx+Q_edct+16) */
|
||||
Lacc = L_mac(L_tmp,im[i],*pt);/*Q(Qx+Q_edct+16) */
|
||||
y[i2] = round_fx(L_shr(Lacc,Q_edct)); /* Q(Qx) */
|
||||
|
||||
L_tmp = L_mult(re[i],edct_table[length/2-1-i]);/*Q(Qx+Q_edct+16) */
|
||||
Lacc = L_msu(L_tmp,im[i],edct_table[i]);/*Q(Qx+Q_edct+16) */
|
||||
*py = round_fx(L_shr(Lacc,Q_edct)); /* Q(Qx) */
|
||||
|
||||
py -= 2;
|
||||
pt--;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------*
|
||||
* iedct_short_fx()
|
||||
*
|
||||
* Inverse EDCT for short frames
|
||||
*-----------------------------------------------------------------*/
|
||||
|
||||
void iedct_short_fx(
|
||||
const Word32 *in, /* i : input vector */
|
||||
Word16 *Q, /* i/o: Q value of input */
|
||||
Word32 *out, /* o : output vector */
|
||||
const Word16 segment_length /* i : length */
|
||||
)
|
||||
{
|
||||
Word32 alias[MAX_SEGMENT_LENGTH];
|
||||
Word16 seg_len_div2, seg_len_div4, seg_len_3mul_div4;
|
||||
Word16 i;
|
||||
Word16 qtmp, tmp;
|
||||
|
||||
qtmp = *Q;
|
||||
move16();
|
||||
tmp = 0;
|
||||
move16();
|
||||
seg_len_div2 = shr(segment_length, 1);
|
||||
seg_len_div4 = shr(segment_length, 2);
|
||||
seg_len_3mul_div4 = add(seg_len_div2, seg_len_div4);
|
||||
|
||||
edct_fx(in, alias, seg_len_div2, Q);
|
||||
FOR (i = 0; i < seg_len_div2; i++)
|
||||
{
|
||||
IF (alias[i] != 0)
|
||||
{
|
||||
tmp = 1;
|
||||
move16();
|
||||
BREAK;
|
||||
}
|
||||
}
|
||||
if (tmp == 0)
|
||||
{
|
||||
*Q = qtmp;
|
||||
move16();
|
||||
}
|
||||
FOR (i = 0; i < seg_len_div4; i++)
|
||||
{
|
||||
out[i] = alias[seg_len_div4 + i];
|
||||
move32();
|
||||
out[seg_len_div4 + i] = L_negate(alias[seg_len_div2 - 1 - i]);
|
||||
move32();
|
||||
out[seg_len_div2 + i] = L_negate(alias[seg_len_div4 - 1 - i]);
|
||||
move32();
|
||||
out[seg_len_3mul_div4 + i] = L_negate(alias[i]);
|
||||
move32();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
415
src/libs/libevs/basic_op/enh1632.cpp → src/libs/libevs/lib_com/enh1632.cpp
Executable file → Normal file
415
src/libs/libevs/basic_op/enh1632.cpp → src/libs/libevs/lib_com/enh1632.cpp
Executable file → Normal file
@@ -1,3 +1,4 @@
|
||||
|
||||
/*
|
||||
===========================================================================
|
||||
File: ENH1632.C v.2.3 - 30.Nov.2009
|
||||
@@ -18,33 +19,33 @@
|
||||
*/
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Enhanced 16/32 bit operators :
|
||||
* s_max()
|
||||
* s_min()
|
||||
* L_max()
|
||||
* L_min()
|
||||
* shl_r()
|
||||
* L_shl_r()
|
||||
* L_mac0()
|
||||
* L_mult0()
|
||||
* L_msu0()
|
||||
* s_and()
|
||||
* s_or()
|
||||
* s_xor()
|
||||
* L_and()
|
||||
* L_or()
|
||||
* lshl()
|
||||
* lshr()
|
||||
* L_lshl()
|
||||
* L_lshr()
|
||||
* rotr()
|
||||
* rotl()
|
||||
* L_rotr()
|
||||
* L_rotl()
|
||||
*
|
||||
*****************************************************************************/
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Enhanced 16/32 bit operators :
|
||||
* s_max()
|
||||
* s_min()
|
||||
* L_max()
|
||||
* L_min()
|
||||
* shl_r()
|
||||
* L_shl_r()
|
||||
* L_mac0()
|
||||
* L_mult0()
|
||||
* L_msu0()
|
||||
* s_and()
|
||||
* s_or()
|
||||
* s_xor()
|
||||
* L_and()
|
||||
* L_or()
|
||||
* lshl()
|
||||
* lshr()
|
||||
* L_lshl()
|
||||
* L_lshr()
|
||||
* rotr()
|
||||
* rotl()
|
||||
* L_rotr()
|
||||
* L_rotl()
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
@@ -52,17 +53,11 @@
|
||||
* Include-Files
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "stl.h"
|
||||
|
||||
#if (WMOPS)
|
||||
extern BASIC_OP multiCounter[MAXCOUNTERS];
|
||||
extern int currCounter;
|
||||
#endif /* if WMOPS */
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Constants and Globals
|
||||
@@ -109,33 +104,35 @@ extern int currCounter;
|
||||
* the range 0xffff 8000 <= var_out <= 0x0000 7fff.
|
||||
*
|
||||
*****************************************************************************/
|
||||
Word16 lshl( Word16 var1, Word16 var2) {
|
||||
Word16 var_out=0;
|
||||
Word16 lshl( Word16 var1, Word16 var2)
|
||||
{
|
||||
Word16 var_out=0;
|
||||
|
||||
if( var2 < 0) {
|
||||
var2 = -var2;
|
||||
var_out = lshr( var1, var2);
|
||||
if( var2 < 0)
|
||||
{
|
||||
var2 = -var2;
|
||||
var_out = lshr( var1, var2);
|
||||
}
|
||||
else
|
||||
{
|
||||
if( var2 == 0 || var1 == 0)
|
||||
{
|
||||
var_out = var1;
|
||||
}
|
||||
else if( var2 >= 16)
|
||||
{
|
||||
var_out = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
var_out = var1 << var2;
|
||||
}
|
||||
}
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].lshr--;
|
||||
#endif /* if WMOPS */
|
||||
BASOP_CHECK();
|
||||
|
||||
} else {
|
||||
if( var2 == 0 || var1 == 0) {
|
||||
var_out = var1;
|
||||
} else if( var2 >= 16) {
|
||||
var_out = 0;
|
||||
} else {
|
||||
var_out = var1 << var2;
|
||||
}
|
||||
}
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].lshl++;
|
||||
#endif /* if WMOPS */
|
||||
|
||||
BASOP_CHECK();
|
||||
|
||||
return( var_out);
|
||||
return( var_out);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
@@ -170,35 +167,37 @@ Word16 lshl( Word16 var1, Word16 var2) {
|
||||
* the range 0xffff 8000 <= var_out <= 0x0000 7fff.
|
||||
*
|
||||
*****************************************************************************/
|
||||
Word16 lshr( Word16 var1, Word16 var2) {
|
||||
Word16 var_out;
|
||||
Word16 lshr( Word16 var1, Word16 var2)
|
||||
{
|
||||
Word16 var_out;
|
||||
|
||||
if( var2 < 0) {
|
||||
var2 = -var2;
|
||||
var_out = lshl( var1, var2);
|
||||
if( var2 < 0)
|
||||
{
|
||||
var2 = -var2;
|
||||
var_out = lshl( var1, var2);
|
||||
}
|
||||
else
|
||||
{
|
||||
if( var2 == 0 || var1 == 0)
|
||||
{
|
||||
var_out = var1;
|
||||
}
|
||||
else if( var2 >= 16)
|
||||
{
|
||||
var_out = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
var_out = var1 >> 1;
|
||||
var_out = var_out & 0x7fff;
|
||||
var_out = var_out >> ( var2-1);
|
||||
}
|
||||
}
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].lshl--;
|
||||
#endif /* if WMOPS */
|
||||
BASOP_CHECK();
|
||||
|
||||
} else {
|
||||
if( var2 == 0 || var1 == 0) {
|
||||
var_out = var1;
|
||||
} else if( var2 >= 16) {
|
||||
var_out = 0;
|
||||
} else {
|
||||
var_out = var1 >> 1;
|
||||
var_out = var_out & 0x7fff;
|
||||
var_out = var_out >> ( var2-1);
|
||||
}
|
||||
}
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].lshr++;
|
||||
#endif /* if WMOPS */
|
||||
|
||||
BASOP_CHECK();
|
||||
|
||||
return( var_out);
|
||||
return( var_out);
|
||||
}
|
||||
|
||||
|
||||
@@ -234,33 +233,35 @@ Word16 lshr( Word16 var1, Word16 var2) {
|
||||
* the range 0x8000 0000 <= L_var_out <= 0x7fff ffff.
|
||||
*
|
||||
*****************************************************************************/
|
||||
Word32 L_lshl( Word32 L_var1, Word16 var2) {
|
||||
Word32 L_var_out=0;
|
||||
Word32 L_lshl( Word32 L_var1, Word16 var2)
|
||||
{
|
||||
Word32 L_var_out=0;
|
||||
|
||||
if( var2 < 0) {
|
||||
var2 = -var2;
|
||||
L_var_out = L_lshr( L_var1, var2);
|
||||
if( var2 < 0)
|
||||
{
|
||||
var2 = -var2;
|
||||
L_var_out = L_lshr( L_var1, var2);
|
||||
}
|
||||
else
|
||||
{
|
||||
if( var2 == 0 || L_var1 == 0)
|
||||
{
|
||||
L_var_out = L_var1;
|
||||
}
|
||||
else if( var2 >= 32)
|
||||
{
|
||||
L_var_out = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
L_var_out = L_var1 << var2;
|
||||
}
|
||||
}
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_lshr--;
|
||||
#endif /* if WMOPS */
|
||||
BASOP_CHECK();
|
||||
|
||||
} else {
|
||||
if( var2 == 0 || L_var1 == 0) {
|
||||
L_var_out = L_var1;
|
||||
} else if( var2 >= 32) {
|
||||
L_var_out = 0;
|
||||
} else {
|
||||
L_var_out = L_var1 << var2;
|
||||
}
|
||||
}
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_lshl++;
|
||||
#endif /* if WMOPS */
|
||||
|
||||
BASOP_CHECK();
|
||||
|
||||
return( L_var_out);
|
||||
return( L_var_out);
|
||||
}
|
||||
|
||||
|
||||
@@ -296,35 +297,37 @@ Word32 L_lshl( Word32 L_var1, Word16 var2) {
|
||||
* the range 0x8000 0000 <= L_var_out <= 0x7fff ffff.
|
||||
*
|
||||
*****************************************************************************/
|
||||
Word32 L_lshr( Word32 L_var1, Word16 var2) {
|
||||
Word32 L_var_out;
|
||||
Word32 L_lshr( Word32 L_var1, Word16 var2)
|
||||
{
|
||||
Word32 L_var_out;
|
||||
|
||||
if( var2 < 0) {
|
||||
var2 = -var2;
|
||||
L_var_out = L_lshl( L_var1, var2);
|
||||
if( var2 < 0)
|
||||
{
|
||||
var2 = -var2;
|
||||
L_var_out = L_lshl( L_var1, var2);
|
||||
}
|
||||
else
|
||||
{
|
||||
if( var2 == 0 || L_var1 == 0)
|
||||
{
|
||||
L_var_out = L_var1;
|
||||
}
|
||||
else if( var2 >= 32)
|
||||
{
|
||||
L_var_out = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
L_var_out = L_var1 >> 1;
|
||||
L_var_out = L_var_out & 0x7fffffff;
|
||||
L_var_out = L_var_out >> (var2 - 1);
|
||||
}
|
||||
}
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_lshl--;
|
||||
#endif /* if WMOPS */
|
||||
BASOP_CHECK();
|
||||
|
||||
} else {
|
||||
if( var2 == 0 || L_var1 == 0) {
|
||||
L_var_out = L_var1;
|
||||
} else if( var2 >= 32) {
|
||||
L_var_out = 0;
|
||||
} else {
|
||||
L_var_out = L_var1 >> 1;
|
||||
L_var_out = L_var_out & 0x7fffffff;
|
||||
L_var_out = L_var_out >> (var2 - 1);
|
||||
}
|
||||
}
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_lshr++;
|
||||
#endif /* if WMOPS */
|
||||
|
||||
BASOP_CHECK();
|
||||
|
||||
return( L_var_out);
|
||||
return( L_var_out);
|
||||
}
|
||||
|
||||
|
||||
@@ -357,30 +360,22 @@ Word32 L_lshr( Word32 L_var1, Word16 var2) {
|
||||
* the range : 0xffff 8000 <= var_out <= 0x0000 7fff.
|
||||
*
|
||||
*****************************************************************************/
|
||||
Word16 shl_r( Word16 var1, Word16 var2){
|
||||
Word16 var_out;
|
||||
Word16 shl_r( Word16 var1, Word16 var2)
|
||||
{
|
||||
Word16 var_out;
|
||||
|
||||
if( var2 >= 0) {
|
||||
var_out = shl( var1, var2);
|
||||
if( var2 >= 0)
|
||||
{
|
||||
var_out = shl( var1, var2);
|
||||
}
|
||||
else
|
||||
{
|
||||
var2 = -var2;
|
||||
var_out = shr_r( var1, var2);
|
||||
}
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].shl--;
|
||||
#endif /* if WMOPS */
|
||||
|
||||
} else {
|
||||
var2 = -var2;
|
||||
var_out = shr_r( var1, var2);
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].shr_r--;
|
||||
#endif /* if WMOPS */
|
||||
}
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].shl_r++;
|
||||
#endif /* if WMOPS */
|
||||
|
||||
return( var_out);
|
||||
return( var_out);
|
||||
}
|
||||
|
||||
|
||||
@@ -413,30 +408,22 @@ Word16 shl_r( Word16 var1, Word16 var2){
|
||||
* the range : 0x8000 0000 <= var_out <= 0x7fff ffff.
|
||||
*
|
||||
*****************************************************************************/
|
||||
Word32 L_shl_r( Word32 L_var1, Word16 var2) {
|
||||
Word32 var_out;
|
||||
Word32 L_shl_r( Word32 L_var1, Word16 var2)
|
||||
{
|
||||
Word32 var_out;
|
||||
|
||||
if( var2 >= 0) {
|
||||
var_out = L_shl( L_var1, var2);
|
||||
if( var2 >= 0)
|
||||
{
|
||||
var_out = L_shl( L_var1, var2);
|
||||
}
|
||||
else
|
||||
{
|
||||
var2 = -var2;
|
||||
var_out = L_shr_r( L_var1, var2);
|
||||
}
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_shl--;
|
||||
#endif /* if WMOPS */
|
||||
|
||||
} else {
|
||||
var2 = -var2;
|
||||
var_out = L_shr_r( L_var1, var2);
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_shr_r--;
|
||||
#endif /* if WMOPS */
|
||||
}
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_shl_r++;
|
||||
#endif /* if WMOPS */
|
||||
|
||||
return( var_out);
|
||||
return( var_out);
|
||||
}
|
||||
|
||||
|
||||
@@ -470,22 +457,16 @@ Word32 L_shl_r( Word32 L_var1, Word16 var2) {
|
||||
* the range : 0xffff 8000 <= var_out <= 0x0000 7fff.
|
||||
*
|
||||
*****************************************************************************/
|
||||
Word16 rotr( Word16 var1, Word16 var2, Word16 *var3) {
|
||||
Word16 var_out;
|
||||
Word16 rotr( Word16 var1, Word16 var2, Word16 *var3)
|
||||
{
|
||||
Word16 var_out;
|
||||
|
||||
*var3 = s_and( var1, 0x1);
|
||||
var_out = s_or( lshr( var1, 1),
|
||||
lshl( var2, 15));
|
||||
*var3 = s_and( var1, 0x1);
|
||||
var_out = s_or( lshr( var1, 1),
|
||||
lshl( var2, 15));
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].s_and--;
|
||||
multiCounter[currCounter].lshl--;
|
||||
multiCounter[currCounter].lshr--;
|
||||
multiCounter[currCounter].s_or--;
|
||||
multiCounter[currCounter].rotr++;
|
||||
#endif /* if WMOPS */
|
||||
|
||||
return( var_out);
|
||||
return( var_out);
|
||||
}
|
||||
|
||||
|
||||
@@ -519,23 +500,17 @@ Word16 rotr( Word16 var1, Word16 var2, Word16 *var3) {
|
||||
* the range : 0xffff 8000 <= var_out <= 0x0000 7fff.
|
||||
*
|
||||
*****************************************************************************/
|
||||
Word16 rotl( Word16 var1, Word16 var2, Word16 *var3) {
|
||||
Word16 var_out;
|
||||
Word16 rotl( Word16 var1, Word16 var2, Word16 *var3)
|
||||
{
|
||||
Word16 var_out;
|
||||
|
||||
*var3 = lshr( var1, 15);
|
||||
*var3 = lshr( var1, 15);
|
||||
|
||||
var_out = s_or( lshl( var1, 1),
|
||||
s_and( var2, 0x1));
|
||||
var_out = s_or( lshl( var1, 1),
|
||||
s_and( var2, 0x1));
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].lshr--;
|
||||
multiCounter[currCounter].s_and--;
|
||||
multiCounter[currCounter].lshl--;
|
||||
multiCounter[currCounter].s_or--;
|
||||
multiCounter[currCounter].rotl++;
|
||||
#endif /* if WMOPS */
|
||||
|
||||
return( var_out);
|
||||
return( var_out);
|
||||
}
|
||||
|
||||
|
||||
@@ -569,25 +544,17 @@ Word16 rotl( Word16 var1, Word16 var2, Word16 *var3) {
|
||||
* the range : 0x8000 0000 <= L_var_out <= 0x7fff ffff.
|
||||
*
|
||||
*****************************************************************************/
|
||||
Word32 L_rotr( Word32 L_var1, Word16 var2, Word16 *var3) {
|
||||
Word32 L_var_out;
|
||||
Word32 L_rotr( Word32 L_var1, Word16 var2, Word16 *var3)
|
||||
{
|
||||
Word32 L_var_out;
|
||||
|
||||
*var3 = s_and( extract_l( L_var1), 0x1);
|
||||
*var3 = s_and( extract_l( L_var1), 0x1);
|
||||
|
||||
L_var_out = L_or( L_lshr( L_var1, 1),
|
||||
L_lshl( L_deposit_l( var2), 31));
|
||||
L_var_out = L_or( L_lshr( L_var1, 1),
|
||||
L_lshl( L_deposit_l( var2), 31));
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].extract_l--;
|
||||
multiCounter[currCounter].s_and--;
|
||||
multiCounter[currCounter].L_deposit_l--;
|
||||
multiCounter[currCounter].L_lshl--;
|
||||
multiCounter[currCounter].L_lshr--;
|
||||
multiCounter[currCounter].L_or--;
|
||||
multiCounter[currCounter].L_rotr++;
|
||||
#endif /* if WMOPS */
|
||||
|
||||
return( L_var_out);
|
||||
return( L_var_out);
|
||||
}
|
||||
|
||||
|
||||
@@ -621,25 +588,17 @@ Word32 L_rotr( Word32 L_var1, Word16 var2, Word16 *var3) {
|
||||
* the range : 0x8000 0000 <= L_var_out <= 0x7fff ffff.
|
||||
*
|
||||
*****************************************************************************/
|
||||
Word32 L_rotl( Word32 L_var1, Word16 var2, Word16 *var3) {
|
||||
Word32 L_var_out;
|
||||
Word32 L_rotl( Word32 L_var1, Word16 var2, Word16 *var3)
|
||||
{
|
||||
Word32 L_var_out;
|
||||
|
||||
*var3 = extract_l( L_lshr( L_var1, 31));
|
||||
*var3 = extract_l( L_lshr( L_var1, 31));
|
||||
|
||||
L_var_out = L_or( L_lshl( L_var1, 1),
|
||||
L_deposit_l( s_and( var2, 0x1)));
|
||||
L_var_out = L_or( L_lshl( L_var1, 1),
|
||||
L_deposit_l( s_and( var2, 0x1)));
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_lshr--;
|
||||
multiCounter[currCounter].extract_l--;
|
||||
multiCounter[currCounter].s_and--;
|
||||
multiCounter[currCounter].L_deposit_l--;
|
||||
multiCounter[currCounter].L_lshl--;
|
||||
multiCounter[currCounter].L_or--;
|
||||
multiCounter[currCounter].L_rotl++;
|
||||
#endif /* if WMOPS */
|
||||
|
||||
return( L_var_out);
|
||||
return( L_var_out);
|
||||
}
|
||||
|
||||
|
||||
151
src/libs/libevs/basic_op/enh1632.h → src/libs/libevs/lib_com/enh1632.h
Executable file → Normal file
151
src/libs/libevs/basic_op/enh1632.h → src/libs/libevs/lib_com/enh1632.h
Executable file → Normal file
@@ -36,13 +36,6 @@
|
||||
#include "stl.h"
|
||||
|
||||
|
||||
#if (WMOPS)
|
||||
#include "count.h"
|
||||
extern BASIC_OP multiCounter[MAXCOUNTERS];
|
||||
extern int currCounter;
|
||||
#endif /* if WMOPS */
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Prototypes for enhanced 16/32 bit arithmetic operators
|
||||
@@ -98,19 +91,17 @@ Word32 L_rotl( Word32 var1, Word16 var2, Word16 *var3);
|
||||
* the range : 0x8000 <= L_var_out <= 0x7fff.
|
||||
*
|
||||
*****************************************************************************/
|
||||
static __inline Word16 s_max( Word16 var1, Word16 var2) {
|
||||
Word16 var_out;
|
||||
static __inline Word16 s_max( Word16 var1, Word16 var2)
|
||||
{
|
||||
Word16 var_out;
|
||||
|
||||
if( var1 >= var2)
|
||||
var_out = var1;
|
||||
else
|
||||
var_out = var2;
|
||||
if( var1 >= var2)
|
||||
var_out = var1;
|
||||
else
|
||||
var_out = var2;
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].s_max++;
|
||||
#endif /* if WMOPS */
|
||||
|
||||
return( var_out);
|
||||
return( var_out);
|
||||
}
|
||||
|
||||
|
||||
@@ -142,19 +133,17 @@ static __inline Word16 s_max( Word16 var1, Word16 var2) {
|
||||
* the range : 0x8000 <= var_out <= 0x7fff.
|
||||
*
|
||||
*****************************************************************************/
|
||||
static __inline Word16 s_min( Word16 var1, Word16 var2) {
|
||||
Word16 var_out;
|
||||
static __inline Word16 s_min( Word16 var1, Word16 var2)
|
||||
{
|
||||
Word16 var_out;
|
||||
|
||||
if( var1 <= var2)
|
||||
var_out = var1;
|
||||
else
|
||||
var_out = var2;
|
||||
if( var1 <= var2)
|
||||
var_out = var1;
|
||||
else
|
||||
var_out = var2;
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].s_min++;
|
||||
#endif /* if WMOPS */
|
||||
|
||||
return( var_out);
|
||||
return( var_out);
|
||||
}
|
||||
|
||||
|
||||
@@ -186,19 +175,17 @@ static __inline Word16 s_min( Word16 var1, Word16 var2) {
|
||||
* range : 0x8000 0000 <= L_var_out <= 0x7fff ffff.
|
||||
*
|
||||
*****************************************************************************/
|
||||
static __inline Word32 L_max( Word32 L_var1, Word32 L_var2) {
|
||||
Word32 L_var_out;
|
||||
static __inline Word32 L_max( Word32 L_var1, Word32 L_var2)
|
||||
{
|
||||
Word32 L_var_out;
|
||||
|
||||
if( L_var1 >= L_var2)
|
||||
L_var_out = L_var1;
|
||||
else
|
||||
L_var_out = L_var2;
|
||||
if( L_var1 >= L_var2)
|
||||
L_var_out = L_var1;
|
||||
else
|
||||
L_var_out = L_var2;
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_max++;
|
||||
#endif /* if WMOPS */
|
||||
|
||||
return( L_var_out);
|
||||
return( L_var_out);
|
||||
}
|
||||
|
||||
|
||||
@@ -230,19 +217,17 @@ static __inline Word32 L_max( Word32 L_var1, Word32 L_var2) {
|
||||
* range : 0x8000 0000 <= L_var_out <= 0x7fff ffff.
|
||||
*
|
||||
*****************************************************************************/
|
||||
static __inline Word32 L_min( Word32 L_var1, Word32 L_var2) {
|
||||
Word32 L_var_out;
|
||||
static __inline Word32 L_min( Word32 L_var1, Word32 L_var2)
|
||||
{
|
||||
Word32 L_var_out;
|
||||
|
||||
if( L_var1 <= L_var2)
|
||||
L_var_out = L_var1;
|
||||
else
|
||||
L_var_out = L_var2;
|
||||
if( L_var1 <= L_var2)
|
||||
L_var_out = L_var1;
|
||||
else
|
||||
L_var_out = L_var2;
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_min++;
|
||||
#endif /* if WMOPS */
|
||||
|
||||
return( L_var_out);
|
||||
return( L_var_out);
|
||||
}
|
||||
|
||||
|
||||
@@ -283,16 +268,14 @@ static __inline Word32 L_min( Word32 L_var1, Word32 L_var2) {
|
||||
* falls in the range 0xffff 8000 <= var_out <= 0x0000 7fff.
|
||||
*
|
||||
*****************************************************************************/
|
||||
static __inline Word16 s_and( Word16 var1, Word16 var2) {
|
||||
Word16 var_out;
|
||||
static __inline Word16 s_and( Word16 var1, Word16 var2)
|
||||
{
|
||||
Word16 var_out;
|
||||
|
||||
var_out = var1 & var2;
|
||||
var_out = var1 & var2;
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].s_and++;
|
||||
#endif /* if WMOPS */
|
||||
|
||||
return( var_out);
|
||||
return( var_out);
|
||||
}
|
||||
|
||||
|
||||
@@ -325,16 +308,14 @@ static __inline Word16 s_and( Word16 var1, Word16 var2) {
|
||||
* falls in the range 0x8000 0000 <= L_var_out <= 0x7fff ffff.
|
||||
*
|
||||
*****************************************************************************/
|
||||
static __inline Word32 L_and( Word32 L_var1, Word32 L_var2) {
|
||||
Word32 L_var_out;
|
||||
static __inline Word32 L_and( Word32 L_var1, Word32 L_var2)
|
||||
{
|
||||
Word32 L_var_out;
|
||||
|
||||
L_var_out = L_var1 & L_var2;
|
||||
L_var_out = L_var1 & L_var2;
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_and++;
|
||||
#endif /* if WMOPS */
|
||||
|
||||
return( L_var_out);
|
||||
return( L_var_out);
|
||||
}
|
||||
|
||||
|
||||
@@ -367,16 +348,14 @@ static __inline Word32 L_and( Word32 L_var1, Word32 L_var2) {
|
||||
* falls in the range 0xffff 8000 <= var_out <= 0x0000 7fff.
|
||||
*
|
||||
*****************************************************************************/
|
||||
static __inline Word16 s_or( Word16 var1, Word16 var2) {
|
||||
Word16 var_out;
|
||||
static __inline Word16 s_or( Word16 var1, Word16 var2)
|
||||
{
|
||||
Word16 var_out;
|
||||
|
||||
var_out = var1 | var2;
|
||||
var_out = var1 | var2;
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].s_or++;
|
||||
#endif /* if WMOPS */
|
||||
|
||||
return( var_out);
|
||||
return( var_out);
|
||||
}
|
||||
|
||||
|
||||
@@ -409,17 +388,15 @@ static __inline Word16 s_or( Word16 var1, Word16 var2) {
|
||||
* falls in the range 0x8000 0000 <= L_var_out <= 0x7fff ffff.
|
||||
*
|
||||
*****************************************************************************/
|
||||
static __inline Word32 L_or( Word32 L_var1, Word32 L_var2) {
|
||||
static __inline Word32 L_or( Word32 L_var1, Word32 L_var2)
|
||||
{
|
||||
|
||||
Word32 L_var_out;
|
||||
Word32 L_var_out;
|
||||
|
||||
L_var_out = L_var1 | L_var2;
|
||||
L_var_out = L_var1 | L_var2;
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_or++;
|
||||
#endif /* if WMOPS */
|
||||
|
||||
return( L_var_out);
|
||||
return( L_var_out);
|
||||
}
|
||||
|
||||
|
||||
@@ -452,16 +429,14 @@ static __inline Word32 L_or( Word32 L_var1, Word32 L_var2) {
|
||||
* falls in the range 0xffff 8000 <= var_out <= 0x0000 7fff.
|
||||
*
|
||||
*****************************************************************************/
|
||||
static __inline Word16 s_xor( Word16 var1, Word16 var2) {
|
||||
Word16 var_out;
|
||||
static __inline Word16 s_xor( Word16 var1, Word16 var2)
|
||||
{
|
||||
Word16 var_out;
|
||||
|
||||
var_out = var1 ^ var2;
|
||||
var_out = var1 ^ var2;
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].s_xor++;
|
||||
#endif /* if WMOPS */
|
||||
|
||||
return( var_out);
|
||||
return( var_out);
|
||||
}
|
||||
|
||||
|
||||
@@ -494,16 +469,14 @@ static __inline Word16 s_xor( Word16 var1, Word16 var2) {
|
||||
* falls in the range 0x8000 0000 <= L_var_out <= 0x7fff ffff.
|
||||
*
|
||||
*****************************************************************************/
|
||||
static __inline Word32 L_xor( Word32 L_var1, Word32 L_var2) {
|
||||
Word32 L_var_out;
|
||||
static __inline Word32 L_xor( Word32 L_var1, Word32 L_var2)
|
||||
{
|
||||
Word32 L_var_out;
|
||||
|
||||
L_var_out = L_var1 ^ L_var2;
|
||||
L_var_out = L_var1 ^ L_var2;
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_xor++;
|
||||
#endif /* if WMOPS */
|
||||
|
||||
return( L_var_out);
|
||||
return( L_var_out);
|
||||
}
|
||||
|
||||
|
||||
1069
src/libs/libevs/lib_com/enh40.cpp
Normal file
1069
src/libs/libevs/lib_com/enh40.cpp
Normal file
File diff suppressed because it is too large
Load Diff
383
src/libs/libevs/lib_com/enh40.h
Normal file
383
src/libs/libevs/lib_com/enh40.h
Normal file
@@ -0,0 +1,383 @@
|
||||
/*
|
||||
===========================================================================
|
||||
File: ENH40.H v.2.3 - 30.Nov.2009
|
||||
===========================================================================
|
||||
|
||||
ITU-T STL BASIC OPERATORS
|
||||
|
||||
40-BIT ARITHMETIC OPERATORS
|
||||
|
||||
History:
|
||||
07 Nov 04 v2.0 Incorporation of new 32-bit / 40-bit / control
|
||||
operators for the ITU-T Standard Tool Library as
|
||||
described in Geneva, 20-30 January 2004 WP 3/16 Q10/16
|
||||
TD 11 document and subsequent discussions on the
|
||||
wp3audio@yahoogroups.com email reflector.
|
||||
March 06 v2.1 Changed to improve portability.
|
||||
|
||||
============================================================================
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _ENH40_H
|
||||
#define _ENH40_H
|
||||
|
||||
|
||||
#include "stl.h"
|
||||
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define MAX_40 (0x0000007fffffffff)
|
||||
#define MIN_40 (0xffffff8000000000)
|
||||
#endif /* ifdef _MSC_VER */
|
||||
|
||||
|
||||
|
||||
#define L40_OVERFLOW_OCCURED( L40_var1) (Overflow = 1, exit(1), L40_var1)
|
||||
#define L40_UNDERFLOW_OCCURED( L40_var1) (Overflow = 1, exit(2), L40_var1)
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Prototypes for enhanced 40 bit arithmetic operators
|
||||
*
|
||||
*****************************************************************************/
|
||||
Word40 L40_shr( Word40 L40_var1, Word16 var2);
|
||||
Word40 L40_shr_r( Word40 L40_var1, Word16 var2);
|
||||
Word40 L40_shl( Word40 L40_var1, Word16 var2);
|
||||
Word40 L40_shl_r( Word40 L40_var1, Word16 var2);
|
||||
|
||||
static __inline Word40 L40_mult( Word16 var1, Word16 var2);
|
||||
|
||||
static __inline Word40 L40_mac( Word40 L40_var1, Word16 var1, Word16 var2);
|
||||
static __inline Word16 mac_r40( Word40 L40_var1, Word16 var1, Word16 var2);
|
||||
|
||||
static __inline Word40 L40_msu( Word40 L40_var1, Word16 var1, Word16 var2);
|
||||
static __inline Word16 msu_r40( Word40 L40_var1, Word16 var1, Word16 var2);
|
||||
|
||||
|
||||
void Mpy_32_16_ss( Word32 L_var1, Word16 var2, Word32 *L_varout_h, UWord16 *varout_l);
|
||||
void Mpy_32_32_ss( Word32 L_var1, Word32 L_var2, Word32 *L_varout_h, UWord32 *L_varout_l);
|
||||
|
||||
|
||||
Word40 L40_lshl( Word40 L40_var1, Word16 var2);
|
||||
Word40 L40_lshr( Word40 L40_var1, Word16 var2);
|
||||
|
||||
static __inline Word40 L40_set( Word40 L40_var1);
|
||||
static __inline UWord16 Extract40_H( Word40 L40_var1);
|
||||
static __inline UWord16 Extract40_L( Word40 L40_var1);
|
||||
static __inline UWord32 L_Extract40( Word40 L40_var1);
|
||||
|
||||
static __inline Word40 L40_deposit_h( Word16 var1);
|
||||
static __inline Word40 L40_deposit_l( Word16 var1);
|
||||
static __inline Word40 L40_deposit32( Word32 L_var1);
|
||||
|
||||
static __inline Word40 L40_round( Word40 L40_var1);
|
||||
static __inline Word16 round40( Word40 L40_var1);
|
||||
|
||||
|
||||
Word40 L40_add( Word40 L40_var1, Word40 L40_var2);
|
||||
Word40 L40_sub( Word40 L40_var1, Word40 L40_var2);
|
||||
Word40 L40_abs( Word40 L40_var1);
|
||||
Word40 L40_negate( Word40 L40_var1);
|
||||
Word40 L40_max( Word40 L40_var1, Word40 L40_var2);
|
||||
Word40 L40_min( Word40 L40_var1, Word40 L40_var2);
|
||||
Word32 L_saturate40( Word40 L40_var1);
|
||||
Word16 norm_L40( Word40 L40_var1);
|
||||
|
||||
|
||||
|
||||
/*#ifdef _MSC_VER*/
|
||||
static __inline Word40 L40_set( Word40 L40_var1)
|
||||
{
|
||||
Word40 L40_var_out;
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER <= 1200)
|
||||
L40_var_out = L40_var1 & 0x000000ffffffffff;
|
||||
|
||||
if( L40_var1 & 0x8000000000)
|
||||
L40_var_out = L40_var_out | 0xffffff0000000000;
|
||||
#else
|
||||
L40_var_out = L40_var1 & 0x000000ffffffffffLL;
|
||||
|
||||
if( L40_var1 & 0x8000000000LL)
|
||||
L40_var_out = L40_var_out | 0xffffff0000000000LL;
|
||||
#endif
|
||||
|
||||
|
||||
return( L40_var_out);
|
||||
}
|
||||
/*#endif*/ /* ifdef _MSC_VER */
|
||||
|
||||
|
||||
|
||||
static __inline UWord16 Extract40_H( Word40 L40_var1)
|
||||
{
|
||||
UWord16 var_out;
|
||||
|
||||
var_out = ( UWord16)( L40_var1 >> 16);
|
||||
|
||||
|
||||
return( var_out);
|
||||
}
|
||||
|
||||
|
||||
static __inline UWord16 Extract40_L( Word40 L40_var1)
|
||||
{
|
||||
UWord16 var_out;
|
||||
|
||||
var_out = ( UWord16)( L40_var1);
|
||||
|
||||
|
||||
return( var_out);
|
||||
}
|
||||
|
||||
|
||||
static __inline UWord32 L_Extract40( Word40 L40_var1)
|
||||
{
|
||||
UWord32 L_var_out;
|
||||
|
||||
L_var_out = ( UWord32) L40_var1;
|
||||
|
||||
|
||||
return(L_var_out);
|
||||
}
|
||||
|
||||
|
||||
static __inline Word40 L40_deposit_h( Word16 var1)
|
||||
{
|
||||
Word40 L40_var_out;
|
||||
|
||||
L40_var_out = (( Word40) var1) << 16;
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER <= 1200)
|
||||
if( var1 & 0x8000)
|
||||
{
|
||||
L40_var_out = L40_set( L40_var_out | 0xff00000000);
|
||||
#else
|
||||
if( var1 & 0x8000)
|
||||
{
|
||||
L40_var_out = L40_set( L40_var_out | 0xff00000000LL);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
return( L40_var_out);
|
||||
}
|
||||
|
||||
|
||||
static __inline Word40 L40_deposit_l( Word16 var1)
|
||||
{
|
||||
Word40 L40_var_out;
|
||||
|
||||
L40_var_out = var1;
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER <= 1200)
|
||||
if( var1 & 0x8000)
|
||||
{
|
||||
L40_var_out = L40_set( L40_var_out | 0xffffff0000);
|
||||
#else
|
||||
if( var1 & 0x8000)
|
||||
{
|
||||
L40_var_out = L40_set( L40_var_out | 0xffffff0000LL);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
return( L40_var_out);
|
||||
}
|
||||
|
||||
|
||||
static __inline Word40 L40_deposit32( Word32 L_var1)
|
||||
{
|
||||
Word40 L40_var_out;
|
||||
|
||||
L40_var_out = ( Word40) L_var1;
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER <= 1200)
|
||||
if( L_var1 & 0x80000000)
|
||||
{
|
||||
L40_var_out = L40_set( L40_var_out | 0xff00000000);
|
||||
#else
|
||||
if( L_var1 & 0x80000000)
|
||||
{
|
||||
L40_var_out = L40_set( L40_var_out | 0xff00000000LL);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
return( L40_var_out);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static __inline Word40 L40_round( Word40 L40_var1)
|
||||
{
|
||||
Word40 L40_var_out;
|
||||
Word40 L40_constant;
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER <= 1200)
|
||||
L40_constant = L40_set( 0xffffff0000);
|
||||
#else
|
||||
L40_constant = L40_set( 0xffffff0000LL);
|
||||
#endif
|
||||
|
||||
L40_var_out = L40_add( 0x8000, L40_var1);
|
||||
L40_var_out = L40_var_out & L40_constant;
|
||||
|
||||
|
||||
return( L40_var_out);
|
||||
}
|
||||
|
||||
|
||||
static __inline Word16 round40( Word40 L40_var1)
|
||||
{
|
||||
Word16 var_out;
|
||||
|
||||
var_out = extract_h( L_saturate40( L40_round( L40_var1)));
|
||||
|
||||
|
||||
return( var_out);
|
||||
}
|
||||
|
||||
|
||||
static __inline Word40 L40_mult( Word16 var1, Word16 var2)
|
||||
{
|
||||
Word32 L_var_out;
|
||||
Word40 L40_var_out;
|
||||
|
||||
L_var_out = ( Word32) var1 * ( Word32) var2;
|
||||
L40_var_out = ( Word40) L_var_out;
|
||||
|
||||
/* Below line can not overflow, so we can use << instead of L40_shl. */
|
||||
L40_var_out = L40_var_out << 1;
|
||||
|
||||
|
||||
return( L40_var_out);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static __inline Word40 L40_mac( Word40 L40_var1, Word16 var2, Word16 var3)
|
||||
{
|
||||
Word40 L40_var_out;
|
||||
|
||||
L40_var_out = L40_mult( var2, var3);
|
||||
L40_var_out = L40_add( L40_var1, L40_var_out);
|
||||
|
||||
|
||||
return( L40_var_out);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static __inline Word16 mac_r40( Word40 L40_var1, Word16 var2, Word16 var3)
|
||||
{
|
||||
Word40 L40_var_out;
|
||||
Word16 var_out;
|
||||
|
||||
L40_var_out = L40_mac( L40_var1, var2, var3);
|
||||
var_out = round40( L40_var_out);
|
||||
|
||||
|
||||
return( var_out);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static __inline Word40 L40_msu( Word40 L40_var1, Word16 var2, Word16 var3)
|
||||
{
|
||||
Word40 L40_var_out;
|
||||
|
||||
L40_var_out = L40_mult( var2, var3);
|
||||
L40_var_out = L40_sub( L40_var1, L40_var_out);
|
||||
|
||||
|
||||
return( L40_var_out);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static __inline Word16 msu_r40( Word40 L40_var1, Word16 var2, Word16 var3)
|
||||
{
|
||||
Word40 L40_var_out;
|
||||
Word16 var_out;
|
||||
|
||||
L40_var_out = L40_msu( L40_var1, var2, var3);
|
||||
var_out = round40( L40_var_out);
|
||||
|
||||
|
||||
return( var_out);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /*_ENH40_H*/
|
||||
|
||||
|
||||
/* end of file */
|
||||
|
||||
|
||||
243
src/libs/libevs/lib_com/enhancer.cpp
Normal file
243
src/libs/libevs/lib_com/enhancer.cpp
Normal file
@@ -0,0 +1,243 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.443 Nov 13, 2018. Version 12.11.0 / 13.7.0 / 14.3.0 / 15.1.0
|
||||
====================================================================================*/
|
||||
|
||||
#include <math.h>
|
||||
#include "options.h"
|
||||
#include "cnst.h"
|
||||
#include "prot.h"
|
||||
#include "rom_com.h"
|
||||
|
||||
/*---------------------------------------------------------------------*
|
||||
* Local functions
|
||||
*---------------------------------------------------------------------*/
|
||||
|
||||
static void agc2( const float *sig_in, float *sig_out,const short l_trm );
|
||||
|
||||
/*---------------------------------------------------------------------*
|
||||
* enhancer()
|
||||
*
|
||||
* Enhancement of the excitation signal before synthesis
|
||||
*---------------------------------------------------------------------*/
|
||||
|
||||
void enhancer(
|
||||
const short codec_mode, /* i : flag indicating Codec Mode */
|
||||
const long core_brate, /* i : core bitrate */
|
||||
const short cbk_index, /* i : */
|
||||
const short Opt_AMR_WB, /* i : flag indicating AMR-WB IO mode */
|
||||
const short coder_type, /* i : coding type */
|
||||
const short L_frame, /* i : frame size */
|
||||
const float voice_fac, /* i : subframe voicing estimation */
|
||||
const float stab_fac, /* i : LP filter stablility measure */
|
||||
const float norm_gain_code, /* i : normalized innovative cb. gain */
|
||||
const float gain_inov, /* i : gain of the unscaled innovation */
|
||||
float *gc_threshold, /* i/o: code threshold */
|
||||
float *code, /* i/o: innovation */
|
||||
float *pt_exc2, /* i/o: adapt. excitation/total exc. */
|
||||
const float gain_pit, /* i : Quantized pitch gain */
|
||||
float *dispMem /* i/o: Phase dispersion algorithm memory */
|
||||
)
|
||||
{
|
||||
float tmp, gain_code, new_norm_gain_code, fac;
|
||||
short i;
|
||||
float pit_sharp;
|
||||
float excp[L_SUBFR];
|
||||
|
||||
pit_sharp = gain_pit;
|
||||
|
||||
/*-----------------------------------------------------------------*
|
||||
* Phase dispersion
|
||||
*
|
||||
* Enhance noise at low bit rates
|
||||
*-----------------------------------------------------------------*/
|
||||
|
||||
i = 2; /* no dispersion */
|
||||
if( Opt_AMR_WB )
|
||||
{
|
||||
if ( core_brate <= ACELP_6k60 )
|
||||
{
|
||||
i = 0; /* high dispersion */
|
||||
}
|
||||
else if ( core_brate <= ACELP_8k85 )
|
||||
{
|
||||
i = 1; /* low dispersion */
|
||||
}
|
||||
}
|
||||
else if( codec_mode == MODE1 && coder_type != UNVOICED )
|
||||
{
|
||||
if ( core_brate <= ACELP_7k20 )
|
||||
{
|
||||
i = 0; /* high dispersion */
|
||||
}
|
||||
else if ( ( coder_type == GENERIC || coder_type == TRANSITION || coder_type == AUDIO || coder_type == INACTIVE ) && core_brate <= ACELP_9k60 )
|
||||
{
|
||||
i = 1; /* low dispersion */
|
||||
}
|
||||
}
|
||||
else if( codec_mode == MODE2 )
|
||||
{
|
||||
if( ((coder_type!=VOICED) && cbk_index<=2) || ((coder_type==UNVOICED) && L_frame==L_FRAME && cbk_index<=10) || ((coder_type==UNVOICED) && L_frame==L_FRAME16k && cbk_index<=14))
|
||||
{
|
||||
i = 0; /* high dispersion */
|
||||
}
|
||||
else if( (coder_type!=VOICED) && (cbk_index<=7) )
|
||||
{
|
||||
i = 1; /* low dispersion */
|
||||
}
|
||||
}
|
||||
|
||||
phase_dispersion( norm_gain_code, gain_pit, code, i, dispMem );
|
||||
|
||||
/*------------------------------------------------------------
|
||||
* Noise enhancer
|
||||
*
|
||||
* Enhance excitation on noise (modify code gain). If signal is noisy and LPC filter is stable,
|
||||
* move code gain 1.5 dB towards its threshold. This decreases by 3 dB noise energy variation.
|
||||
*-----------------------------------------------------------*/
|
||||
|
||||
if ( norm_gain_code < *gc_threshold )
|
||||
{
|
||||
new_norm_gain_code = (float)(norm_gain_code * 1.19f);
|
||||
if ( new_norm_gain_code > *gc_threshold )
|
||||
{
|
||||
new_norm_gain_code = *gc_threshold;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
new_norm_gain_code = (float)(norm_gain_code / 1.19f);
|
||||
if ( new_norm_gain_code < *gc_threshold )
|
||||
{
|
||||
new_norm_gain_code = *gc_threshold;
|
||||
}
|
||||
}
|
||||
*gc_threshold = new_norm_gain_code;
|
||||
|
||||
/* calculate new code gain */
|
||||
fac = stab_fac * (0.5f * (1.0f - voice_fac)); /* 1 = unvoiced, 0 = voiced */
|
||||
gain_code = fac * new_norm_gain_code + (1.0f - fac) * norm_gain_code;
|
||||
gain_code *= gain_inov;
|
||||
|
||||
for (i=0; i<L_SUBFR; i++)
|
||||
{
|
||||
code[i] *= gain_code;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------*
|
||||
* Pitch enhancer
|
||||
*
|
||||
* Enhance excitation on voiced (HP filtering of code). On voiced signal, filter code by a smooth HP
|
||||
* filter to decrease the energy of code at low frequency
|
||||
*------------------------------------------------------------*/
|
||||
|
||||
if( !Opt_AMR_WB && codec_mode == MODE1 && coder_type == UNVOICED )
|
||||
{
|
||||
mvr2r( code, pt_exc2, L_SUBFR );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( Opt_AMR_WB && ( core_brate == ACELP_8k85 || core_brate == ACELP_6k60 ) )
|
||||
{
|
||||
pit_sharp = gain_pit;
|
||||
if( pit_sharp > 1.0 )
|
||||
{
|
||||
pit_sharp = 1.0;
|
||||
}
|
||||
|
||||
if ( pit_sharp > 0.5 )
|
||||
{
|
||||
for (i = 0; i < L_SUBFR; i++)
|
||||
{
|
||||
excp[i] = pt_exc2[i] * pit_sharp * 0.25f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------
|
||||
* Do a simple noncasual "sharpening": effectively an FIR
|
||||
* filter with coefs [-tmp 1.0 -tmp] where tmp = 0 ... 0.25
|
||||
* This is applied to code and added to exc2
|
||||
*-----------------------------------------------------------------*/
|
||||
if( L_frame == L_FRAME16k )
|
||||
{
|
||||
tmp = (float)(0.150f*(1.0f+voice_fac)); /* 0.30=voiced, 0=unvoiced */
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp = (float)(0.125f * (1.0f + voice_fac)); /* 0.25=voiced, 0=unvoiced */
|
||||
}
|
||||
pt_exc2[0] += code[0] - (tmp * code[1]);
|
||||
for ( i=1; i<L_SUBFR-1; i++ )
|
||||
{
|
||||
pt_exc2[i] += code[i] - (tmp*code[i-1]) - (tmp*code[i+1]);
|
||||
}
|
||||
pt_exc2[L_SUBFR-1] += code[L_SUBFR-1] - (tmp*code[L_SUBFR-2]);
|
||||
|
||||
if ( Opt_AMR_WB && ( core_brate == ACELP_8k85 || core_brate == ACELP_6k60 ) )
|
||||
{
|
||||
if ( pit_sharp > 0.5f )
|
||||
{
|
||||
for (i = 0; i < L_SUBFR; i++)
|
||||
{
|
||||
excp[i] += pt_exc2[i];
|
||||
}
|
||||
|
||||
agc2( pt_exc2, excp, L_SUBFR );
|
||||
mvr2r( excp, pt_exc2, L_SUBFR );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------*
|
||||
* agc2()
|
||||
*
|
||||
* Adaptive gain control
|
||||
*-----------------------------------------------------------------------*/
|
||||
|
||||
static void agc2(
|
||||
const float *sig_in, /* i : postfilter input signal */
|
||||
float *sig_out, /* i/o: postfilter output signal */
|
||||
const short l_trm /* i : subframe size */
|
||||
)
|
||||
{
|
||||
short i;
|
||||
float gain_in, gain_out;
|
||||
float g0, gain;
|
||||
|
||||
|
||||
gain_out = 0.0f;
|
||||
for(i=0; i<l_trm; i++)
|
||||
{
|
||||
gain_out += sig_out[i]*sig_out[i];
|
||||
}
|
||||
|
||||
if (gain_out == 0.0f)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
gain_in = 0.0f;
|
||||
for(i=0; i<l_trm; i++)
|
||||
{
|
||||
gain_in += sig_in[i]*sig_in[i];
|
||||
}
|
||||
if (gain_in == 0.0f)
|
||||
{
|
||||
g0 = 0.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
g0 = (float) sqrt(gain_in / gain_out);
|
||||
}
|
||||
|
||||
gain = g0;
|
||||
for (i=0; i<l_trm; i++)
|
||||
{
|
||||
sig_out[i] *= gain;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -1,678 +0,0 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#include "options.h" /* Compilation switches */
|
||||
#include "cnst_fx.h" /* Common constants */
|
||||
#include "prot_fx.h" /* Function prototypes */
|
||||
#include "rom_com_fx.h" /* Static table prototypes */
|
||||
#include "stl.h"
|
||||
#include "basop_util.h"
|
||||
|
||||
/*---------------------------------------------------------------------*
|
||||
* Local constants
|
||||
*---------------------------------------------------------------------*/
|
||||
#define pitch_0_9 14746 /* 0.9 in Q14 */
|
||||
#define pitch_0_6 9830 /* 0.6 in Q14 */
|
||||
#define SIZE 64
|
||||
#define SIZE2 32
|
||||
#define NUM_STAGES 5
|
||||
|
||||
/*---------------------------------------------------------------------*
|
||||
* Local functions
|
||||
*---------------------------------------------------------------------*/
|
||||
static void phase_dispersion_fx(Word32 gain_code,Word16 gain_pit,Word16 code[],Word16 mode,struct dispMem_fx *dm_fx);
|
||||
static void agc2_fx(const Word16 *sig_in,Word16 *sig_out,const Word16 l_trm);
|
||||
|
||||
/*======================================================================================*/
|
||||
/* FUNCTION : enhancer_fx() */
|
||||
/*--------------------------------------------------------------------------------------*/
|
||||
/* PURPOSE : Enhancement of the excitation signal before synthesis */
|
||||
/*--------------------------------------------------------------------------------------*/
|
||||
/* INPUT ARGUMENTS : */
|
||||
/* _ (Word32) core_brate : decoder bitrate */
|
||||
/* _ (Word16) Opt_AMR_WB : flag indicating AMR-WB IO mode */
|
||||
/* _ (Word16) coder_type : coder type */
|
||||
/* _ (Word16) i_subfr : subframe number */
|
||||
/* _ (Word16) voice_fac : subframe voicing estimation (Q15) */
|
||||
/* _ (Word16) stab_fac : LP filter stablility measure (Q15) */
|
||||
/* _ (Word32) norm_gain_code : normalised innovative cb. gain (Q16) */
|
||||
/* _ (Word16) gain_inov : gain of the unscaled innovation (Q12) */
|
||||
/* _ (Word16) gain_pit_fx : Pitch gain (Q14) */
|
||||
/* _ (Word16) Q_exc : Q of the excitation */
|
||||
/* _ (Word16) Enc : Encoder = 1; decoder = 0 */
|
||||
/*--------------------------------------------------------------------------------------*/
|
||||
/* OUTPUT ARGUMENTS : */
|
||||
/* _ (Word16*) voice_factors_fx : TBE voicing factor (Q15) */
|
||||
/*--------------------------------------------------------------------------------------*/
|
||||
/* INPUT/OUTPUT ARGUMENTS : */
|
||||
/* _ (Word32*) gc_threshold : gain code threshold (Q16) */
|
||||
/* _ (Word16*[]) code : innovation (Q12) */
|
||||
/* _ (Word16*[]) exc2 : adapt. excitation/total exc (Q0) */
|
||||
/* _ (struct dispMem_fx*) dm_fx : phase dispersion algorithm memory */
|
||||
/* (a[0]->Q0,a[1]->Q16,a[2-7]->Q14) */
|
||||
/*--------------------------------------------------------------------------------------*/
|
||||
|
||||
/* _ None */
|
||||
/*--------------------------------------------------------------------------------------*/
|
||||
/* RETURN ARGUMENTS : */
|
||||
/* _ None */
|
||||
/*======================================================================================*/
|
||||
void enhancer_fx(
|
||||
const Word32 core_brate, /* i : decoder bitrate */
|
||||
const Word16 Opt_AMR_WB, /* i : flag indicating AMR-WB IO mode */
|
||||
const Word16 coder_type, /* i : coder type */
|
||||
const Word16 i_subfr, /* i : subframe number */
|
||||
const Word16 L_frame, /* i : frame size */
|
||||
const Word16 voice_fac, /* i : subframe voicing estimation Q15 */
|
||||
const Word16 stab_fac, /* i : LP filter stablility measure Q15 */
|
||||
Word32 norm_gain_code, /* i : normalised innovative cb. gain Q16 */
|
||||
const Word16 gain_inov, /* i : gain of the unscaled innovation Q12 */
|
||||
Word32 *gc_threshold,/* i/o: gain code threshold Q16 */
|
||||
Word16 *code, /* i/o: innovation Q12 */
|
||||
Word16 *exc2, /* i/o: adapt. excitation/total exc. Q_exc*/
|
||||
const Word16 gain_pit, /* i : quantized pitch gain Q14 */
|
||||
struct dispMem_fx *dm_fx, /* i/o: phase dispersion algorithm memory */
|
||||
const Word16 Q_exc /* i : Q of the excitation */
|
||||
)
|
||||
{
|
||||
Word16 tmp, fac, *pt_exc2;
|
||||
Word16 i;
|
||||
Word32 L_tmp;
|
||||
Word16 gain_code_hi;
|
||||
Word16 pit_sharp, tmp16;
|
||||
Word16 excp[L_SUBFR], sc;
|
||||
|
||||
pit_sharp = gain_pit;
|
||||
move16(); /* to remove gcc warning */
|
||||
pt_exc2 = exc2 + i_subfr;
|
||||
move16();
|
||||
|
||||
/*------------------------------------------------------------*
|
||||
* Phase dispersion to enhance noise at low bit rate
|
||||
*------------------------------------------------------------*/
|
||||
|
||||
i = 2;
|
||||
move16(); /* no dispersion */
|
||||
IF (Opt_AMR_WB)
|
||||
{
|
||||
IF ( L_sub(core_brate,ACELP_6k60) <= 0)
|
||||
{
|
||||
i = 0;
|
||||
move16(); /* high dispersion */
|
||||
}
|
||||
ELSE if ( L_sub(core_brate,ACELP_8k85) <= 0)
|
||||
{
|
||||
i = 1;
|
||||
move16(); /* low dispersion */
|
||||
}
|
||||
}
|
||||
ELSE IF( sub(coder_type,UNVOICED) != 0)
|
||||
|
||||
{
|
||||
test();
|
||||
test();
|
||||
test();
|
||||
test();
|
||||
IF ( L_sub(core_brate,ACELP_7k20) <= 0 )
|
||||
{
|
||||
i = 0;
|
||||
move16(); /* high dispersion */
|
||||
}
|
||||
ELSE if ( ( sub(coder_type,GENERIC) == 0 || sub(coder_type,TRANSITION) == 0 || sub(coder_type,AUDIO) == 0 || sub(coder_type,INACTIVE) == 0 ) && L_sub(core_brate,ACELP_9k60) <= 0 )
|
||||
{
|
||||
i = 1;
|
||||
move16(); /* low dispersion */
|
||||
}
|
||||
}
|
||||
phase_dispersion_fx(norm_gain_code, gain_pit, code, i, dm_fx);
|
||||
|
||||
/*------------------------------------------------------------
|
||||
* noise enhancer
|
||||
*
|
||||
* - Enhance excitation on noise. (modify gain of code)
|
||||
* If signal is noisy and LPC filter is stable, move gain
|
||||
* of code 1.5 dB toward gain of code threshold.
|
||||
* This decreases by 3 dB noise energy variation.
|
||||
*-----------------------------------------------------------*/
|
||||
|
||||
/* tmp = 0.5f * (1.0f - voice_fac) */
|
||||
tmp = msu_r(0x40000000, voice_fac, 16384); /*Q15 */ /* 1=unvoiced, 0=voiced */
|
||||
/* fac = stab_fac * tmp */
|
||||
fac = mult(stab_fac, tmp); /*Q15*/
|
||||
|
||||
IF (L_sub(norm_gain_code, *gc_threshold) < 0)
|
||||
{
|
||||
L_tmp = Madd_32_16(norm_gain_code, norm_gain_code, 6226);/*Q16 */
|
||||
L_tmp = L_min(L_tmp, *gc_threshold);/*Q16 */
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
L_tmp = Mult_32_16(norm_gain_code, 27536);/*Q16 */
|
||||
L_tmp = L_max(L_tmp, *gc_threshold); /*Q16 */
|
||||
}
|
||||
*gc_threshold = L_tmp;
|
||||
move32(); /*Q16 */
|
||||
|
||||
/* gain_code = (fac * tmp) + (1.0 - fac) * gain_code ==> fac * (tmp - gain_code) + gain_code */
|
||||
L_tmp = L_sub(L_tmp, norm_gain_code); /*Q16 */
|
||||
norm_gain_code = Madd_32_16(norm_gain_code, L_tmp, fac);/*Q16 */
|
||||
|
||||
/* gain_code *= gain_inov - Inverse the normalization */
|
||||
L_tmp = Mult_32_16(norm_gain_code, gain_inov); /*Q13*/ /* gain_inov in Q12 */
|
||||
|
||||
sc = 6;
|
||||
move16();
|
||||
|
||||
gain_code_hi = round_fx(L_shl(L_tmp, add(Q_exc, 3))); /* in Q_exc */
|
||||
|
||||
/*------------------------------------------------------------*
|
||||
* pitch enhancer
|
||||
*
|
||||
* - Enhance excitation on voiced. (HP filtering of code)
|
||||
* On voiced signal, filtering of code by a smooth fir HP
|
||||
* filter to decrease energy of code at low frequency.
|
||||
*------------------------------------------------------------*/
|
||||
test();
|
||||
IF( !Opt_AMR_WB && sub(coder_type,UNVOICED) == 0 )
|
||||
{
|
||||
/* Copy(code, exc2, L_SUBFR) */
|
||||
FOR (i = 0; i < L_SUBFR; i++)
|
||||
{
|
||||
pt_exc2[i] = round_fx(L_shl(L_mult(gain_code_hi, code[i]), sc)); /*Q0 */ /* code in Q12 (Q9 for encoder) */
|
||||
}
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
test();
|
||||
test();
|
||||
IF ( Opt_AMR_WB && ( L_sub(core_brate,ACELP_8k85) == 0|| L_sub(core_brate,ACELP_6k60) == 0 ) )
|
||||
{
|
||||
pit_sharp = shl(gain_pit, 1); /* saturation can occur here Q14 -> Q15 */
|
||||
|
||||
/* saturation takes care of "if (pit_sharp > 1.0) { pit_sharp=1.0; }" */
|
||||
IF (sub(pit_sharp, 16384) > 0)
|
||||
{
|
||||
tmp16 = mult(pit_sharp, 8192);
|
||||
FOR (i = 0; i < L_SUBFR; i++)
|
||||
{
|
||||
/* excp[i] = pt_exc2[i] * pit_sharp * 0.25 */
|
||||
excp[i] = mult_r(pt_exc2[i], tmp16);
|
||||
move16();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IF ( sub(L_frame, L_FRAME16k) == 0 )
|
||||
{
|
||||
/* tmp = 0.150 * (1.0 + voice_fac) */
|
||||
/* 0.30=voiced, 0=unvoiced */
|
||||
tmp = mac_r(0x10000000L, voice_fac, 4915);/*Q15 */
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
/* tmp = 0.125 * (1.0 + voice_fac) */
|
||||
/* 0.25=voiced, 0=unvoiced */
|
||||
tmp = mac_r(0x10000000L, voice_fac, 4096);/*Q15 */
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------
|
||||
* Do a simple noncasual "sharpening": effectively an FIR
|
||||
* filter with coefs [-tmp 1.0 -tmp] where tmp=0...0.25.
|
||||
* This is applied to code and add_fxed to exc2
|
||||
*-----------------------------------------------------------------*/
|
||||
/* pt_exc2[0] += code[0] - tmp * code[1] */
|
||||
L_tmp = L_deposit_h(code[0]); /* if Enc :Q9 * Q15 -> Q25 */
|
||||
L_tmp = L_msu(L_tmp, code[1], tmp); /* Q12 * Q15 -> Q28 */
|
||||
L_tmp = L_shl(L_mult(gain_code_hi, extract_h(L_tmp)), sc);
|
||||
pt_exc2[0] = msu_r(L_tmp, -32768, pt_exc2[0]);
|
||||
move16();/* in Q_exc */
|
||||
|
||||
FOR (i = 1; i < L_SUBFR-1; i++)
|
||||
{
|
||||
/* pt_exc2[i] += code[i] - tmp * code[i-1] - tmp * code[i+1] */
|
||||
L_tmp = L_msu(-32768, code[i], -32768);
|
||||
L_tmp = L_msu(L_tmp, code[i + 1], tmp);
|
||||
tmp16 = msu_r(L_tmp, code[i - 1], tmp);
|
||||
L_tmp = L_shl(L_mult(gain_code_hi, tmp16), sc);
|
||||
pt_exc2[i] = msu_r(L_tmp, -32768, pt_exc2[i]);
|
||||
move16(); /* in Q_exc */
|
||||
}
|
||||
|
||||
/* pt_exc2[L_SUBFR-1] += code[L_SUBFR-1] - tmp * code[L_SUBFR-2] */
|
||||
L_tmp = L_deposit_h(code[L_SUBFR - 1]);/*Q28 */
|
||||
L_tmp = L_msu(L_tmp, code[L_SUBFR - 2], tmp);/*Q28 */
|
||||
L_tmp = L_shl(L_mult(gain_code_hi, extract_h(L_tmp)), sc);
|
||||
pt_exc2[L_SUBFR - 1] = msu_r(L_tmp, -32768, pt_exc2[L_SUBFR - 1]);
|
||||
move16();/* in Q_exc */
|
||||
test();
|
||||
test();
|
||||
IF ( Opt_AMR_WB && ( L_sub(core_brate,ACELP_8k85) == 0 || L_sub(core_brate,ACELP_6k60) == 0 ) )
|
||||
{
|
||||
IF (sub(pit_sharp, 16384) > 0)
|
||||
{
|
||||
FOR (i = 0; i < L_SUBFR; i++)
|
||||
{
|
||||
/* excp[i] += pt_exc2[i] */
|
||||
excp[i] = add(excp[i], pt_exc2[i]);
|
||||
move16();
|
||||
}
|
||||
agc2_fx(pt_exc2, excp, L_SUBFR);
|
||||
Copy(excp, pt_exc2, L_SUBFR);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*
|
||||
* Enhancement of the excitation signal before synthesis
|
||||
*---------------------------------------------------------*/
|
||||
|
||||
Word16 E_UTIL_enhancer(
|
||||
Word16 voice_fac, /* i : subframe voicing estimation Q15 */
|
||||
Word16 stab_fac, /* i : LP filter stability measure Q15 */
|
||||
Word32 gain_code, /* i : innovative cb. gain 15Q16 */
|
||||
Word16 gain_inov, /* i : gain of the unscaled innovation Q11 */
|
||||
Word32 *gc_threshold, /* i/o: gain code threshold 15Q16 */
|
||||
Word16 *code, /* i/o: innovation(in: Q9) code_exp */
|
||||
Word16 *exc2, /* i/o: adapt. excitation/total exc. */
|
||||
Word16 gain_pit, /* i : Quantized pitch gain 1Q14 */
|
||||
Word32 *prev_gain_code, /* i/o: previous codebook gain 15Q16 */
|
||||
Word16 prev_gain_pit[], /* i/o: previous pitch gain, size=6 1Q14 */
|
||||
Word16 *prev_state, /* i/o: Phase dispersion algorithm memory Q0 */
|
||||
Word16 coder_type, /* i : coder type */
|
||||
Word16 cdk_index, /* i : */
|
||||
Word16 L_subfr, /* i : length of subframe */
|
||||
Word16 L_frame, /* i : frame size */
|
||||
Word16 Q_new
|
||||
)
|
||||
{
|
||||
Word16 disp_mode, i;
|
||||
Word16 tmp, fac, gain;
|
||||
Word32 L_tmp;
|
||||
Word16 code_exp, exc2_exp;
|
||||
Word16 max_cdk_index_uv;
|
||||
|
||||
move16();
|
||||
code_exp = 15-9;
|
||||
exc2_exp = 15-Q_new;
|
||||
gain_inov = shr(gain_inov,1);
|
||||
/*-----------------------------------------------------------------*
|
||||
* Phase dispersion to enhance noise at low bit rates
|
||||
*-----------------------------------------------------------------*/
|
||||
|
||||
max_cdk_index_uv = 10;
|
||||
move16();
|
||||
if ( sub(L_frame, L_FRAME16k) == 0 )
|
||||
{
|
||||
max_cdk_index_uv = 14;
|
||||
move16();
|
||||
}
|
||||
disp_mode = 2; /* any=off */ move16();
|
||||
test();
|
||||
test();
|
||||
test();
|
||||
test();
|
||||
IF ( ( (sub(coder_type, VOICED) != 0) && (sub(cdk_index, 2) <= 0) ) || ( (sub(coder_type, UNVOICED) == 0) && (sub(cdk_index, max_cdk_index_uv) <= 0) ) )
|
||||
{
|
||||
disp_mode = 0; /* high */ move16();
|
||||
}
|
||||
ELSE IF ( (sub(coder_type, VOICED) != 0) && (sub(cdk_index, 7) <= 0) )
|
||||
{
|
||||
disp_mode = 1; /* low */ move16();
|
||||
}
|
||||
|
||||
phase_dispersion(gain_code, gain_pit,code, &code_exp, disp_mode, prev_gain_code, prev_gain_pit, prev_state, L_subfr);
|
||||
|
||||
/*------------------------------------------------------------*
|
||||
* noise enhancer *
|
||||
* ~~~~~~~~~~~~~~ *
|
||||
* - Enhance excitation on noise. (modify gain of code) *
|
||||
* If signal is noisy and LPC filter is stable, move gain *
|
||||
* of code 1.5 dB toward gain of code threshold. *
|
||||
* This decrease by 3 dB noise energy variation. *
|
||||
*------------------------------------------------------------*/
|
||||
fac = 0;
|
||||
move16();
|
||||
|
||||
/* if gain_code is computed function of energy, noise enhancer is by-passed.*/
|
||||
BASOP_SATURATE_WARNING_OFF
|
||||
tmp = msu_r(1073741824l/*0.5f Q31*/, 16384/*0.5f Q15*/, voice_fac); /* 1=unvoiced, 0=voiced */
|
||||
BASOP_SATURATE_WARNING_ON
|
||||
fac = mult_r(stab_fac, tmp); /* fac in Q15 */
|
||||
|
||||
L_tmp = L_add(0,gain_code); /* L_tmp in 15Q16 */
|
||||
|
||||
IF (L_sub(L_tmp,*gc_threshold) < 0)
|
||||
{
|
||||
L_tmp = L_shl(Mpy_32_32(L_tmp, 1277752832l/*1.19f/2.0f Q31*/),1);
|
||||
L_tmp = L_min(L_tmp, *gc_threshold);
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
L_tmp = Mpy_32_32(L_tmp, 1804608000l/*1.0f/1.19f Q31*/);
|
||||
L_tmp = L_max(L_tmp, *gc_threshold);
|
||||
}
|
||||
move32();
|
||||
*gc_threshold = L_tmp; /* in 15Q16 */
|
||||
|
||||
/* gain = ( (fac * L_tmp) + (gain_code - fac*gain_code) ) * gain_inov */
|
||||
/* exponent of L_tmp: 31-16 + 15-11 */
|
||||
L_tmp = Mpy_32_16_1(L_add(Mpy_32_16_1(L_tmp, fac), L_sub(gain_code, Mpy_32_16_1(gain_code, fac))), gain_inov);
|
||||
|
||||
/* exponent gain: 31-16 + 15-11 - tmp */
|
||||
tmp = norm_l(L_tmp);
|
||||
|
||||
/* exponent of code: 31-16 + 15-11 - tmp + code_exp */
|
||||
move16();
|
||||
code_exp = sub(add(31-16 + 15-11, code_exp), tmp);
|
||||
|
||||
L_tmp = L_shl(L_tmp, tmp);
|
||||
gain = round_fx(L_tmp);
|
||||
|
||||
FOR (i=0; i<L_subfr; i++)
|
||||
{
|
||||
code[i] = mult_r(code[i], gain);
|
||||
move16();
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------*
|
||||
* pitch enhancer *
|
||||
* ~~~~~~~~~~~~~~ *
|
||||
* - Enhance excitation on voice. (HP filtering of code) *
|
||||
* On voiced signal, filtering of code by a smooth fir HP *
|
||||
* filter to decrease energy of code in low frequency. *
|
||||
*------------------------------------------------------------*/
|
||||
|
||||
/* exponent difference of code and exc2. +1 accounts for headroom required below. */
|
||||
gain = add(sub(code_exp, exc2_exp), 1);
|
||||
|
||||
tmp = mac_r(268435456l/*0.125f Q31*/, 4096/*0.125f Q15*/, voice_fac); /* 0.25=voiced, 0=unvoiced */
|
||||
if ( sub(L_frame, L_FRAME16k) == 0 )
|
||||
{
|
||||
tmp = mac_r(322122560l/*0.150f Q31*/, 4915/*0.150f Q15*/, voice_fac); /* 0.30=voiced, 0=unvoiced */
|
||||
}
|
||||
|
||||
/* exc2[0] = exc2[0] + code[0] - tmp*code[1]; */
|
||||
L_tmp = L_mult(code[0], 16384);
|
||||
L_tmp = L_msu0(L_tmp,tmp,code[1]);
|
||||
if (gain)
|
||||
{
|
||||
L_tmp = L_shl(L_tmp,gain);
|
||||
}
|
||||
exc2[0] = msu_r(L_tmp,-32768, exc2[0]);
|
||||
move16();
|
||||
|
||||
FOR (i=1; i<L_subfr-1; i++)
|
||||
{
|
||||
/* exc2[i] = exc2[i] + code[i] - tmp*(code[i+1]+code[i-1]); */
|
||||
L_tmp = L_mult(code[i], 16384);
|
||||
L_tmp = L_msu0(L_tmp,tmp,code[i-1]);
|
||||
L_tmp = L_msu0(L_tmp,tmp,code[i+1]);
|
||||
if (gain)
|
||||
{
|
||||
L_tmp = L_shl(L_tmp,gain);
|
||||
}
|
||||
exc2[i] = msu_r(L_tmp,-32768, exc2[i]);
|
||||
move16();
|
||||
}
|
||||
/* exc2[L_subfr-1] = exc2[L_subfr-1] + code[L_subfr-1] - tmp*code[L_subfr-2]; */
|
||||
L_tmp = L_mult(code[i], 16384);
|
||||
L_tmp = L_msu0(L_tmp,tmp,code[i-1]);
|
||||
if (gain)
|
||||
{
|
||||
L_tmp = L_shl(L_tmp,gain);
|
||||
}
|
||||
|
||||
exc2[i] = msu_r(L_tmp,-32768, exc2[i]);
|
||||
move16();
|
||||
|
||||
return code_exp;
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*
|
||||
* Phase_dispersion:
|
||||
*
|
||||
* post-processing to enhance noise in low bit rate.
|
||||
*-----------------------------------------------------------------------*/
|
||||
/*======================================================================================*/
|
||||
/* FUNCTION : phase_dispersion_fx() */
|
||||
/*--------------------------------------------------------------------------------------*/
|
||||
/* PURPOSE : post-processing to enhance noise in low bit rate. */
|
||||
/*--------------------------------------------------------------------------------------*/
|
||||
/* INPUT ARGUMENTS : */
|
||||
/* _ (Word32) gain_code : gain of code Q16 */
|
||||
/* _ (Word16) gain_pit : gain of pitch Q14 */
|
||||
/* _ (Word16) mode : level, 0=hi, 1=lo, 2=off */
|
||||
/*--------------------------------------------------------------------------------------*/
|
||||
/* OUTPUT ARGUMENTS : */
|
||||
/* _ None */
|
||||
/*--------------------------------------------------------------------------------------*/
|
||||
/* INPUT/OUTPUT ARGUMENTS : */
|
||||
/* _ (Word16[]) code : code vector (Q12) */
|
||||
/* _ (struct dispMem_fx*) dm_fx : static memory (size = 8) */
|
||||
/* (a[0]->Q0,a[1]->Q16,a[2-7]->Q14) */
|
||||
/*--------------------------------------------------------------------------------------*/
|
||||
|
||||
/* _ None */
|
||||
/*--------------------------------------------------------------------------------------*/
|
||||
/* RETURN ARGUMENTS : */
|
||||
/* _ None */
|
||||
/*======================================================================================*/
|
||||
static void phase_dispersion_fx(
|
||||
Word32 gain_code, /* i : gain of code Q16 */
|
||||
Word16 gain_pit, /* i : gain of pitch Q14 */
|
||||
Word16 code[], /* i/o: code vector */
|
||||
Word16 mode, /* i : level, 0=hi, 1=lo, 2=off */
|
||||
struct dispMem_fx *dm_fx /* i/o: static memory (size = 8) */
|
||||
)
|
||||
{
|
||||
Word16 i, j, state;
|
||||
Word16 *prev_gain_pit, *prev_state;
|
||||
Word32 *prev_gain_code;
|
||||
Word16 *code2_real, *code2_imag;
|
||||
Word16 *code_real, *code_imag;
|
||||
const Word16 *h_real, *h_imag;
|
||||
|
||||
Word16 code2[2 * L_SUBFR];
|
||||
|
||||
prev_state = &(dm_fx->prev_state);
|
||||
prev_gain_code = &(dm_fx->prev_gain_code);
|
||||
prev_gain_pit = dm_fx->prev_gain_pit;
|
||||
|
||||
state = 2;
|
||||
move16();
|
||||
if (sub(gain_pit, pitch_0_9) < 0)
|
||||
{
|
||||
state = 1;
|
||||
move16();
|
||||
}
|
||||
|
||||
if (sub(gain_pit, pitch_0_6) < 0)
|
||||
{
|
||||
state = 0;
|
||||
move16();
|
||||
}
|
||||
|
||||
FOR (i = 5; i > 0; i--)
|
||||
{
|
||||
prev_gain_pit[i] = prev_gain_pit[i - 1];
|
||||
move16();
|
||||
}
|
||||
prev_gain_pit[0] = gain_pit;
|
||||
move16();
|
||||
|
||||
IF (L_sub(L_sub(gain_code, *prev_gain_code), L_shl(*prev_gain_code, 1)) > 0)
|
||||
{
|
||||
state = s_min(add(state, 1), 2);
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
j = 0;
|
||||
move16();
|
||||
|
||||
FOR (i = 0; i < 6; i++)
|
||||
{
|
||||
j = sub(j, shr(sub(prev_gain_pit[i], pitch_0_6), 15));
|
||||
}
|
||||
|
||||
if (sub(j, 2) > 0)
|
||||
{
|
||||
state = 0;
|
||||
move16();
|
||||
}
|
||||
|
||||
if (sub(sub(state, *prev_state), 1) > 0)
|
||||
{
|
||||
state = sub(state, 1);
|
||||
}
|
||||
}
|
||||
|
||||
*prev_gain_code = gain_code;
|
||||
move32();
|
||||
*prev_state = state;
|
||||
move16();
|
||||
|
||||
/*-----------------------------------------------------------------*
|
||||
* circular convolution
|
||||
*-----------------------------------------------------------------*/
|
||||
|
||||
state = add(state, mode); /* level of dispersion */
|
||||
|
||||
IF (sub(state, 2) < 0)
|
||||
{
|
||||
r_fft_fx_lc(phs_tbl_dec, SIZE, SIZE2, NUM_STAGES, code, code2, 1);
|
||||
|
||||
h_real = Mid_H_phasedisp;
|
||||
move16();
|
||||
if (state == 0)
|
||||
{
|
||||
h_real = Low_H_phasedisp;
|
||||
move16();
|
||||
}
|
||||
|
||||
/* FFT Coefs are in code2 */
|
||||
code2_real = code2;
|
||||
move16();
|
||||
code2_imag = code2 + L_SUBFR - 1;
|
||||
move16();
|
||||
|
||||
code_real = code;
|
||||
move16();
|
||||
code_imag = code + L_SUBFR - 1;
|
||||
move16();
|
||||
|
||||
h_imag = h_real + L_SUBFR - 1;
|
||||
move16();
|
||||
|
||||
*code_real++ = mult(*code2_real++, *h_real++);
|
||||
move16(); /* DC */
|
||||
|
||||
FOR (i=1; i<L_SUBFR/2; i++)
|
||||
{
|
||||
*code_real++ = msu_r(L_mult(*code2_real, *h_real), *code2_imag, *h_imag);
|
||||
move16();
|
||||
*code_imag-- = mac_r(L_mult(*code2_real, *h_imag), *code2_imag, *h_real);
|
||||
move16();
|
||||
|
||||
code2_real++;
|
||||
h_imag--;
|
||||
h_real++;
|
||||
code2_imag--;
|
||||
}
|
||||
*code_real++ = mult(*code2_real++, *h_real++);
|
||||
move16(); /* DC */
|
||||
|
||||
r_fft_fx_lc(phs_tbl_dec, SIZE, SIZE2, NUM_STAGES, code, code2, 0);
|
||||
|
||||
FOR (i = 0; i < L_SUBFR; i++)
|
||||
{
|
||||
/* saturation can occur here */
|
||||
code[i] = shl(code2[i], 1); /*Q12 */ move16();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*======================================================================================*/
|
||||
/* FUNCTION : agc2_fx() */
|
||||
/*--------------------------------------------------------------------------------------*/
|
||||
/* PURPOSE : AGC post-processing for lower G722.2 modes */
|
||||
/*--------------------------------------------------------------------------------------*/
|
||||
/* INPUT ARGUMENTS : */
|
||||
/* _ (Word16*[]) sig_in : postfilter input signal (Q0) */
|
||||
/* _ (Word16) l_trm : subframe size */
|
||||
/*--------------------------------------------------------------------------------------*/
|
||||
/* OUTPUT ARGUMENTS : */
|
||||
/* _ None */
|
||||
/*--------------------------------------------------------------------------------------*/
|
||||
/* INPUT/OUTPUT ARGUMENTS : */
|
||||
/* _ (Word16*[]) sig_out : postfilter output signal (Q0) */
|
||||
/*--------------------------------------------------------------------------------------*/
|
||||
|
||||
/* _ None */
|
||||
/*--------------------------------------------------------------------------------------*/
|
||||
/* RETURN ARGUMENTS : */
|
||||
/* _ None */
|
||||
/*======================================================================================*/
|
||||
static void agc2_fx(
|
||||
const Word16 *sig_in, /* i : postfilter input signal */
|
||||
Word16 *sig_out, /* i/o: postfilter output signal */
|
||||
const Word16 l_trm /* i : subframe size */
|
||||
)
|
||||
{
|
||||
|
||||
Word16 i, exp;
|
||||
Word16 gain_in, gain_out, g0;
|
||||
Word32 s;
|
||||
|
||||
Word16 temp;
|
||||
|
||||
/* calculate gain_out with exponent */
|
||||
temp = shr(sig_out[0], 2);
|
||||
s = L_mult0(temp, temp);
|
||||
FOR (i = 1; i < l_trm; i++)
|
||||
{
|
||||
temp = shr(sig_out[i], 2);
|
||||
s = L_mac0(s, temp, temp);
|
||||
}
|
||||
IF (s != 0)
|
||||
{
|
||||
exp = sub(norm_l(s), 1);
|
||||
gain_out = round_fx(L_shl(s, exp));
|
||||
|
||||
/* calculate gain_in with exponent */
|
||||
temp = shr(sig_in[0], 2);
|
||||
s = L_mult0(temp, temp);
|
||||
FOR (i = 1; i < l_trm; i++)
|
||||
{
|
||||
temp = shr(sig_in[i], 2);
|
||||
s = L_mac0(s, temp, temp);
|
||||
}
|
||||
|
||||
g0 = 0;
|
||||
move16();
|
||||
IF (s != 0)
|
||||
{
|
||||
i = norm_l(s);
|
||||
gain_in = round_fx(L_shl(s, i));
|
||||
exp = sub(exp, i);
|
||||
|
||||
/*---------------------------------------------------*
|
||||
* g0 = sqrt(gain_in / gain_out)
|
||||
*---------------------------------------------------*/
|
||||
s = L_mult0(128, div_s(gain_out, gain_in)); /* s = gain_out / gain_in */
|
||||
s = L_shr(s, exp); /* add exponent */
|
||||
|
||||
s = Isqrt(s);
|
||||
g0 = round_fx(L_shl(s, 9));
|
||||
}
|
||||
|
||||
/* sig_out(n) = gain(n) sig_out(n) */
|
||||
FOR (i = 0; i < l_trm; i++)
|
||||
{
|
||||
sig_out[i] = round_fx(L_shl(L_mac(-8192, sig_out[i], g0), 2));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
30
src/libs/libevs/lib_com/enr_1_az.cpp
Normal file
30
src/libs/libevs/lib_com/enr_1_az.cpp
Normal file
@@ -0,0 +1,30 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.443 Nov 13, 2018. Version 12.11.0 / 13.7.0 / 14.3.0 / 15.1.0
|
||||
====================================================================================*/
|
||||
|
||||
#include "options.h"
|
||||
#include "cnst.h"
|
||||
#include "prot.h"
|
||||
|
||||
/*-------------------------------------------------------------------*
|
||||
* enr_1_Az()
|
||||
*
|
||||
* Find Energy of the 1/A(z) impulse response
|
||||
*-------------------------------------------------------------------*/
|
||||
|
||||
float enr_1_Az( /* o : impulse response energy */
|
||||
const float Aq[], /* i : LP filter coefs */
|
||||
const short len /* i : impulse response length */
|
||||
)
|
||||
{
|
||||
float enr_LP, h1[2*L_SUBFR], mem[M];
|
||||
|
||||
|
||||
set_f( h1, 0, len ); /* Find the impulse response */
|
||||
set_f( mem, 0, M );
|
||||
h1[0] = 1.0f;
|
||||
syn_filt( Aq, M, h1, h1, len, mem, 0 );
|
||||
enr_LP = dotp( h1, h1, len ) + 0.01f; /* Find the impulse response energy */
|
||||
|
||||
return enr_LP;
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#include "options.h" /* Compilation switches */
|
||||
#include "cnst_fx.h" /* Common constants */
|
||||
#include "prot_fx.h" /* Function prototypes */
|
||||
#include "stl.h"
|
||||
|
||||
/*-------------------------------------------------------------------*
|
||||
* Enr_1_Az_fx_12Q3()
|
||||
*
|
||||
* Find Energy of the 1/A(z) impulse response
|
||||
*-------------------------------------------------------------------*/
|
||||
Word16 Enr_1_Az_fx( /* o : impulse response energy Q3 */
|
||||
const Word16 Aq[], /* i : LP filter coefs Qx based on the fact that Aq[0] == 1.0 */
|
||||
const Word16 len /* i : impulse response length Q0 */
|
||||
)
|
||||
{
|
||||
Word16 h1[2*L_SUBFR];
|
||||
Word16 *y;
|
||||
Word16 i, j, a0, q;
|
||||
Word32 L_tmp, L_tmp2;
|
||||
|
||||
/* Find the impulse response */
|
||||
|
||||
q = sub( 3, norm_s(Aq[0]) );
|
||||
a0 = shr(Aq[0], q); /* Q11 */
|
||||
q = sub(4, q);
|
||||
|
||||
/*-----------------------------------------------------------------------*
|
||||
* Do the filtering (first two iters unrolled to avoid multiplies with 0)
|
||||
*-----------------------------------------------------------------------*/
|
||||
|
||||
y = h1;
|
||||
/* h1_in Q11, h1_out Q10 */
|
||||
L_tmp = L_mult(a0, 1<<13); /* Q25 = L_mult(Q11,Q13) */
|
||||
*y = round_fx(L_tmp); /* Q25 to Q9 */
|
||||
L_tmp2 = L_mult(*y, *y); /* Q19 = L_mult(Q9,Q9) */
|
||||
y++;
|
||||
|
||||
L_tmp = L_msu(0, Aq[1], y[-1]); /* Q23 = L_mult(Q14,Q9) */
|
||||
L_tmp = L_shl(L_tmp, q);
|
||||
*y = round_fx(L_tmp); /* Q25 to Q9 */
|
||||
L_tmp2 = L_mac(L_tmp2, *y, *y); /* Q19 = L_mult(Q9,Q9) */
|
||||
y++;
|
||||
|
||||
/* Skip Zeros */
|
||||
FOR (i = 2; i < M; i++)
|
||||
{
|
||||
L_tmp = L_msu(0, Aq[1], y[-1]);
|
||||
FOR (j = 2; j <= i; j++)
|
||||
{
|
||||
L_tmp = L_msu(L_tmp, Aq[j], y[-j]);
|
||||
}
|
||||
|
||||
L_tmp = L_shl(L_tmp, q);
|
||||
*y = round_fx(L_tmp);
|
||||
L_tmp2 = L_mac(L_tmp2, *y, *y);
|
||||
y++;
|
||||
}
|
||||
/* Normal Filtering */
|
||||
FOR (; i < len; i++)
|
||||
{
|
||||
L_tmp = L_msu(0, Aq[1], y[-1]);
|
||||
FOR (j = 2; j <= M; j++)
|
||||
{
|
||||
L_tmp = L_msu(L_tmp, Aq[j], y[-j]);
|
||||
}
|
||||
|
||||
L_tmp = L_shl(L_tmp, q);
|
||||
*y = round_fx(L_tmp);
|
||||
L_tmp2 = L_mac(L_tmp2, *y, *y);
|
||||
y++;
|
||||
}
|
||||
|
||||
return round_fx(L_tmp2); /* Q19 to Q3 */
|
||||
}
|
||||
133
src/libs/libevs/lib_com/env_adj.cpp
Normal file
133
src/libs/libevs/lib_com/env_adj.cpp
Normal file
@@ -0,0 +1,133 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.443 Nov 13, 2018. Version 12.11.0 / 13.7.0 / 14.3.0 / 15.1.0
|
||||
====================================================================================*/
|
||||
|
||||
#include <math.h>
|
||||
#include "options.h"
|
||||
#include "cnst.h"
|
||||
#include "rom_com.h"
|
||||
#include "prot.h"
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------*
|
||||
* env_adj()
|
||||
*
|
||||
* Adjust the band energies of noise-fill and low resolution bands
|
||||
*--------------------------------------------------------------------------*/
|
||||
|
||||
void env_adj (
|
||||
const short *pulses, /* i : number of pulses per band */
|
||||
const short length, /* i : length of spectrum */
|
||||
const short last_sfm, /* i : index of the last band */
|
||||
float *adj, /* o : adjustment factors for the envelope */
|
||||
const float env_stab, /* i : Envelope stability parameter */
|
||||
const short *sfmsize /* i : Band widths */
|
||||
)
|
||||
{
|
||||
short i, j, group;
|
||||
int npul;
|
||||
short att_state;
|
||||
short start, len;
|
||||
float tmp;
|
||||
float gain_adj;
|
||||
short idx;
|
||||
|
||||
att_state = 0;
|
||||
len = 0;
|
||||
start = 0;
|
||||
|
||||
/* Find attenuation levels */
|
||||
for( i = 0; i <= last_sfm ; i++ )
|
||||
{
|
||||
group = (sfmsize[i] >> 3) - 1;
|
||||
npul = pulses[i];
|
||||
|
||||
if( length == L_FRAME32k )
|
||||
{
|
||||
if( npul == 0 )
|
||||
{
|
||||
/* Noise filled band */
|
||||
if ( group <= 1 )
|
||||
{
|
||||
if ( i > 0 && pulses[i-1] != 0 && pulses[i+1] != 0 )
|
||||
{
|
||||
adj[i] = 0.36f;
|
||||
}
|
||||
else if ( i > 0 && ( pulses[i-1] == 0 || pulses[i+1] == 0) )
|
||||
{
|
||||
adj[i] = 0.54f;
|
||||
}
|
||||
else
|
||||
{
|
||||
adj[i] = 0.72f;
|
||||
}
|
||||
}
|
||||
else if (i < last_sfm)
|
||||
{
|
||||
if ( pulses[i-1] != 0 && pulses[i+1] != 0 )
|
||||
{
|
||||
adj[i] = 0.54f;
|
||||
}
|
||||
else
|
||||
{
|
||||
adj[i] = 0.72f;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
adj[i] = 0.72f;
|
||||
}
|
||||
|
||||
if( att_state == 0 )
|
||||
{
|
||||
start = i;
|
||||
}
|
||||
|
||||
len++;
|
||||
att_state = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
adj[i] = 1.0f;
|
||||
if(att_state == 1) /* End of attenuation region found */
|
||||
{
|
||||
tmp = min(1, max(0, len-ENV_ADJ_START)*(1.0f/ENV_ADJ_INCL));
|
||||
for( j = start; j < i ; j++ )
|
||||
{
|
||||
adj[j] = max(tmp + (1-tmp)*adj[j],env_stab);
|
||||
}
|
||||
len = 0;
|
||||
att_state = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* length == L_FRAME16k */
|
||||
else
|
||||
{
|
||||
/* Calculate low accuracy band attenuation */
|
||||
gain_adj = 1.0f;
|
||||
if( npul > 0 && npul < MAX_P_ATT )
|
||||
{
|
||||
idx = (short)(npul * att_step[group] + 0.5f) - 1;
|
||||
if( idx < MAX_P_ATT )
|
||||
{
|
||||
gain_adj = gain_att[idx];
|
||||
}
|
||||
}
|
||||
adj[i] = gain_adj;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if the sequence ended with an attenuation region */
|
||||
if( att_state == 1 )
|
||||
{
|
||||
tmp = min(1, max(0, len-ENV_ADJ_START)*(1.0f/ENV_ADJ_INCL));
|
||||
|
||||
for( j = start; j < i ; j++ )
|
||||
{
|
||||
adj[j] = max(tmp + (1-tmp)*adj[j],env_stab);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -1,158 +0,0 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#include "options.h" /* Compilation switches */
|
||||
#include "cnst_fx.h" /* Common constants */
|
||||
#include "rom_com_fx.h" /* Static table prototypes */
|
||||
#include "prot_fx.h" /* Function prototypes */
|
||||
#include "stl.h" /* required by wmc_tool */
|
||||
|
||||
/*--------------------------------------------------------------------------*
|
||||
* env_adj()
|
||||
*
|
||||
* Adjust the band energies of noise-fill and low resolution bands
|
||||
*--------------------------------------------------------------------------*/
|
||||
void env_adj_fx
|
||||
(
|
||||
const Word16 *pulses, /* i : number of pulses per band Q0 */
|
||||
const Word16 length, /* i : length of spectrum Q0 */
|
||||
const Word16 last_sfm, /* i : index of the last band Q0 */
|
||||
Word16 *adj, /* o : adjustment factors for the envelope Q15 */
|
||||
const Word16 env_stab, /* i : envelope stability Q15 */
|
||||
const Word16 *sfmsize /* i : subband sizes Q0 */
|
||||
)
|
||||
{
|
||||
Word16 i, j, group;
|
||||
Word16 npul;
|
||||
Word16 att_state;
|
||||
Word16 start, len;
|
||||
Word16 tmp, tmp_diff;
|
||||
Word16 gain_adj;
|
||||
Word16 idx;
|
||||
|
||||
att_state = 0;
|
||||
move16();
|
||||
len = 0;
|
||||
move16();
|
||||
start = 0;
|
||||
move16();
|
||||
|
||||
/* Find attenuation levels */
|
||||
FOR( i = 0; i <= last_sfm ; i++ )
|
||||
{
|
||||
group = sub(shr(sfmsize[i],3),1);
|
||||
npul = pulses[i];
|
||||
move16();
|
||||
|
||||
IF( sub(length, L_FRAME32k) == 0 )
|
||||
{
|
||||
|
||||
IF( npul == 0 )
|
||||
{
|
||||
/* Noise filled band */
|
||||
IF ( sub(group,1) <= 0 )
|
||||
{
|
||||
test();
|
||||
test();
|
||||
test();
|
||||
test();
|
||||
IF ( i > 0 && pulses[i-1] != 0 && pulses[i+1] != 0 )
|
||||
{
|
||||
adj[i] = 11796; /* Q15, 0.36f */ move16();
|
||||
}
|
||||
ELSE IF ( i > 0 && ( pulses[i-1] == 0 || pulses[i+1] == 0) )
|
||||
{
|
||||
adj[i] = 17695; /* Q15, 0.54f */ move16();
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
adj[i] = 23593; /* Q15, 0.72f */ move16();
|
||||
}
|
||||
}
|
||||
ELSE IF ( sub(i,last_sfm) < 0 )
|
||||
{
|
||||
test();
|
||||
IF ( pulses[i-1] != 0 && pulses[i+1] != 0 )
|
||||
{
|
||||
adj[i] = 17695; /* Q15, 0.54f */ move16();
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
adj[i] = 23593; /* Q15, 0.72f */ move16();
|
||||
}
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
adj[i] = 23593; /* Q15, 0.72f */ move16();
|
||||
}
|
||||
|
||||
if( att_state == 0 )
|
||||
{
|
||||
start = i;
|
||||
move16();
|
||||
}
|
||||
|
||||
len = add(len,1);
|
||||
move16();
|
||||
att_state = 1;
|
||||
move16();
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
adj[i] = MAX_16; /* Q15, 1.0f (saturated) */
|
||||
IF( sub(att_state, 1) == 0 ) /* End of attenuation region found */
|
||||
{
|
||||
/* tmp = min(1, max(0, len-ENV_ADJ_START)*(1.0f/ENV_ADJ_INCL)); */
|
||||
tmp = round_fx(L_shl(L_mult0(s_max( 0, sub(len, ENV_ADJ_START_FX)), ENV_ADJ_INV_INCL_FX),16)); /* Q15 (15+16-16) */
|
||||
tmp_diff = sub(MAX_16, tmp); /* Q15 */ move16();
|
||||
FOR( j = start; j < i ; j++ )
|
||||
{
|
||||
/* adj[j] = max(tmp + (1-tmp)*adj[j],env_stab); */
|
||||
adj[j] = s_max(add(tmp, mult(tmp_diff, adj[j])), env_stab); /* Q15 (15+15-15) */ move16();
|
||||
}
|
||||
len = 0;
|
||||
move16();
|
||||
att_state = 0;
|
||||
move16();
|
||||
}
|
||||
}
|
||||
}
|
||||
/* length == L_FRAME16k */
|
||||
ELSE
|
||||
{
|
||||
|
||||
/* Calculate low accuracy band attenuation */
|
||||
gain_adj = 32767; /* Q15, 1.0f (saturated) */ move16();
|
||||
|
||||
test();
|
||||
IF( npul > 0 && sub(npul, MAX_P_ATT) < 0 )
|
||||
{
|
||||
/*idx = (short)(npul * att_step[group] + 0.5f) - 1; */
|
||||
idx = sub(mult_r(shl(npul,2),att_step_fx[group]), 1); /* Q0 (2+13+1-16) */
|
||||
if( sub(idx, MAX_P_ATT) < 0 )
|
||||
{
|
||||
gain_adj = gain_att_fx[idx]; /* Q15 */ move16();
|
||||
}
|
||||
}
|
||||
adj[i] = gain_adj;
|
||||
move16();
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if the sequence ended with an attenuation region */
|
||||
IF( sub(att_state, 1) == 0 )
|
||||
{
|
||||
/* tmp = min(1, max(0, len-ENV_ADJ_START)*(1.0f/ENV_ADJ_INCL)); */
|
||||
tmp = round_fx(L_shl(L_mult0(s_max( 0, sub(len, ENV_ADJ_START_FX)), ENV_ADJ_INV_INCL_FX),16)); /* Q15 (15+16-16) */
|
||||
tmp_diff = sub(MAX_16, tmp); /* Q15 */ move16();
|
||||
FOR( j = start; j < i ; j++ )
|
||||
{
|
||||
|
||||
/* adj[j] = max(tmp + (1-tmp)*adj[j],env_stab); */
|
||||
adj[j] = s_max(add(tmp, mult(tmp_diff, adj[j])), env_stab); /* Q15 (15+15-15) */ move16();
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
122
src/libs/libevs/lib_com/env_stab_fx.cpp → src/libs/libevs/lib_com/env_stab.cpp
Executable file → Normal file
122
src/libs/libevs/lib_com/env_stab_fx.cpp → src/libs/libevs/lib_com/env_stab.cpp
Executable file → Normal file
@@ -1,30 +1,31 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
EVS Codec 3GPP TS26.443 Nov 13, 2018. Version 12.11.0 / 13.7.0 / 14.3.0 / 15.1.0
|
||||
====================================================================================*/
|
||||
|
||||
#include "options.h" /* Compilation switches */
|
||||
#include "cnst_fx.h" /* Common constants */
|
||||
#include "prot_fx.h" /* Function prototypes */
|
||||
#include "rom_com_fx.h" /* Static table prototypes */
|
||||
#include "stl.h" /* required by wmc_tool */
|
||||
#include "options.h"
|
||||
#include "cnst.h"
|
||||
#include "prot.h"
|
||||
#include "rom_com.h"
|
||||
#include <math.h>
|
||||
|
||||
/*--------------------------------------------------------------------------*
|
||||
* Local constants
|
||||
*--------------------------------------------------------------------------*/
|
||||
|
||||
#define ENV_STAB_SMO_HO 10 /* number of hangover frames when switching from music to speech state */
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* Function env_stability_fx */
|
||||
/* ~~~~~~~~~~~~~~~~~~~~~ */
|
||||
/* Function env_stability() */
|
||||
/* ~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
||||
/* */
|
||||
/* Envelope stability measure */
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
Word16 env_stability_fx( /* in Q15 */
|
||||
const Word16 *ynrm, /*i: Norm vector for current frame */
|
||||
const Word16 nb_sfm, /*i: Number of sub-bands */
|
||||
Word16 *mem_norm, /*i/o: Norm vector memory from past frame */
|
||||
Word16 *mem_env_delta /*i/o: Envelope stability memory for smoothing in Q12 */
|
||||
float env_stability(
|
||||
const short *ynrm, /*i : Norm vector for current frame */
|
||||
const short nb_sfm, /*i : Number of sub-bands */
|
||||
short *mem_norm, /*i/o: Norm vector memory from past frame */
|
||||
float *mem_env_delta /*i/o: Envelope stability memory for smoothing*/
|
||||
)
|
||||
{
|
||||
Word16 env_delta;
|
||||
@@ -35,21 +36,21 @@ Word16 env_stability_fx( /* in Q15 */
|
||||
Word16 exp, exp2;
|
||||
Word32 L_tmp, L_env_delta;
|
||||
Word16 inv_nb_sfm;
|
||||
float env_stab_f;
|
||||
|
||||
/* Calculate envelope stability parameter */
|
||||
L_env_delta = L_deposit_l(0);
|
||||
FOR (i = 0; i < nb_sfm; i++)
|
||||
for (i = 0; i < nb_sfm; i++)
|
||||
{
|
||||
tmp = sub(mem_norm[i],ynrm[i]);
|
||||
L_env_delta = L_mac0(L_env_delta, tmp, tmp);
|
||||
mem_norm[i] = ynrm[i];
|
||||
move16();
|
||||
}
|
||||
|
||||
inv_nb_sfm = 19418; /* Q19 */ move16();
|
||||
inv_nb_sfm = 19418; /* Q19 */
|
||||
if (nb_sfm == 26)
|
||||
{
|
||||
inv_nb_sfm = 20165; /* Q19 */ move16();
|
||||
inv_nb_sfm = 20165; /* Q19 */
|
||||
}
|
||||
exp = norm_l(L_env_delta);
|
||||
L_env_delta = Mult_32_16(L_shl(L_env_delta, exp), inv_nb_sfm); /* 0+exp+19-15 */
|
||||
@@ -70,12 +71,13 @@ Word16 env_stability_fx( /* in Q15 */
|
||||
|
||||
*mem_env_delta = round_fx(L_tmp); /* Q12 */
|
||||
Overflow = 0;
|
||||
move16();
|
||||
env_delta = round_fx(L_shl(L_tmp, 1)); /* Q13 */
|
||||
|
||||
IF (Overflow != 0) /* Saturated due to the above up-shifting operation. */
|
||||
if (Overflow != 0) /* Saturated due to the above up-shifting operation. */
|
||||
{
|
||||
return stab_trans_fx[L_STAB_TBL-1]; /* The highest quantized index. */
|
||||
env_stab = stab_trans_fx[L_STAB_TBL-1]; /* The highest quantized index. */
|
||||
env_stab_f = ((float)env_stab)/32768.0f; /* Convert env_stab(Q15) to float */
|
||||
return env_stab_f;
|
||||
}
|
||||
|
||||
/* If tmp_stab > (D_STAB_TBL*L_STAB_TBL + M_STAB_TBL), i.e., 0.103138*10+2.51757=3.603137,
|
||||
@@ -91,26 +93,27 @@ Word16 env_stability_fx( /* in Q15 */
|
||||
#error env_stability_fx: Use more efficient usquant()
|
||||
#endif
|
||||
tmp_stab = sub(tmp_stab, HALF_D_STAB_TBL_FX); /* in Q13 */
|
||||
FOR (i = 0; i < L_STAB_TBL-1; i++)
|
||||
for (i = 0; i < L_STAB_TBL-1; i++)
|
||||
{
|
||||
IF (tmp_stab < 0)
|
||||
if (tmp_stab < 0)
|
||||
{
|
||||
BREAK;
|
||||
break;
|
||||
}
|
||||
ELSE
|
||||
else
|
||||
{
|
||||
tmp_stab = sub(tmp_stab, D_STAB_TBL_FX); /* in Q13 */
|
||||
}
|
||||
}
|
||||
|
||||
env_stab = stab_trans_fx[i];
|
||||
move16();
|
||||
if(sub(env_delta, M_STAB_TBL_FX) < 0)
|
||||
{
|
||||
env_stab = sub(0x7FFF,stab_trans_fx[i]);
|
||||
}
|
||||
|
||||
return env_stab;
|
||||
env_stab_f = ((float)env_stab)/32768.0f; /* Convert env_stab(Q15) to float */
|
||||
|
||||
return env_stab_f;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*
|
||||
@@ -118,70 +121,47 @@ Word16 env_stability_fx( /* in Q15 */
|
||||
*
|
||||
*
|
||||
*--------------------------------------------------------------------------*/
|
||||
Word16 env_stab_smo_fx( /* Q0 */
|
||||
Word16 env_stab, /*i : env_stab value Q15 */
|
||||
Word16 *env_stab_state_p, /*i/o: env_stab state probabilities Q15 */
|
||||
Word16 *ho_cnt /*i/o: hangover counter for speech state */
|
||||
|
||||
float env_stab_smo(
|
||||
float env_stab, /*i : env_stab value */
|
||||
float *env_stab_state_p, /*i/o: env_stab state probabilities */
|
||||
short *ho_cnt /*i/o: hangover counter for speech state */
|
||||
)
|
||||
{
|
||||
Word16 state, prev_state;
|
||||
Word16 maxval, pp[NUM_ENV_STAB_PLC_STATES], pa[NUM_ENV_STAB_PLC_STATES];
|
||||
Word16 i;
|
||||
Word16 tmp, sum, exp;
|
||||
|
||||
short state, prev_state;
|
||||
float maxval, pp[NUM_ENV_STAB_PLC_STATES], pa[NUM_ENV_STAB_PLC_STATES];
|
||||
/* get previous state */
|
||||
prev_state = maximum_fx(env_stab_state_p, NUM_ENV_STAB_PLC_STATES, &maxval);
|
||||
prev_state = maximum(env_stab_state_p,NUM_ENV_STAB_PLC_STATES,&maxval);
|
||||
|
||||
/* assume two states: speech(0), music(1) */
|
||||
/* set a posteriori likelihoods for the two states according to env_stab */
|
||||
/* re-scale. Unclear if needed */
|
||||
/* env_stab = (env_stab - stab_trans_fx[L_STAB_TBL-1])/(1-2*stab_trans_fx[L_STAB_TBL-1]); */
|
||||
tmp = sub(env_stab, stab_trans_fx[L_STAB_TBL-1]);
|
||||
tmp = round_fx(L_shl(L_mult(tmp, INV_STAB_TRANS_FX), 1)); /* Q15 */
|
||||
|
||||
pp[0] = sub(32767, tmp);
|
||||
move16(); /* 1 in Q15 */
|
||||
pp[1] = tmp;
|
||||
move16();
|
||||
env_stab = (env_stab - stab_trans[L_STAB_TBL-1])/(1-2*stab_trans[L_STAB_TBL-1]);
|
||||
pp[0] = 1.0f-env_stab;
|
||||
pp[1] = env_stab;
|
||||
|
||||
/* calculate a priori likelihoods */
|
||||
pa[0] = round_fx(Dot_product(env_stab_tp_fx[0], env_stab_state_p, NUM_ENV_STAB_PLC_STATES)); /* Q15*/
|
||||
pa[1] = round_fx(Dot_product(env_stab_tp_fx[1], env_stab_state_p, NUM_ENV_STAB_PLC_STATES));
|
||||
pa[0] = dotp(env_stab_tp[0],env_stab_state_p,NUM_ENV_STAB_PLC_STATES);
|
||||
pa[1] = dotp(env_stab_tp[1],env_stab_state_p,NUM_ENV_STAB_PLC_STATES);
|
||||
|
||||
/* multiply elementwise with a posteriori likelihoods */
|
||||
sum = 0;
|
||||
move16();
|
||||
FOR (i = 0; i < NUM_ENV_STAB_PLC_STATES; i++)
|
||||
{
|
||||
env_stab_state_p[i] = mult_r(pa[i], pp[i]);
|
||||
move16(); /* Q15 */
|
||||
sum = add(sum, env_stab_state_p[i]);
|
||||
}
|
||||
v_mult(pa,pp,env_stab_state_p,NUM_ENV_STAB_PLC_STATES);
|
||||
|
||||
/* renormalize state probabilities */
|
||||
exp = norm_s(sum);
|
||||
tmp = div_s(16384, shl(sum, exp)); /* Q(14-exp) */
|
||||
/*tmp = shl(tmp, add(exp, 1));*/ /* Q15 */
|
||||
FOR (i = 0; i < NUM_ENV_STAB_PLC_STATES; i++)
|
||||
{
|
||||
env_stab_state_p[i] = round_fx(L_shl(L_mult(env_stab_state_p[i], tmp), add(exp, 1))); /* Q15 */
|
||||
}
|
||||
v_multc(env_stab_state_p,1.0f/sum_f(env_stab_state_p,NUM_ENV_STAB_PLC_STATES),env_stab_state_p,NUM_ENV_STAB_PLC_STATES);
|
||||
|
||||
/* find maximum index as return value */
|
||||
state = maximum_fx(env_stab_state_p, NUM_ENV_STAB_PLC_STATES, &maxval);
|
||||
state = maximum(env_stab_state_p,NUM_ENV_STAB_PLC_STATES,&maxval);
|
||||
|
||||
/* apply some hangover for speech */
|
||||
test();
|
||||
if (state == 0 && sub(prev_state, 1) == 0)
|
||||
if (state==0 && prev_state==1)
|
||||
{
|
||||
*ho_cnt = ENV_STAB_SMO_HO;
|
||||
move16();
|
||||
*ho_cnt=ENV_STAB_SMO_HO;
|
||||
}
|
||||
|
||||
IF (*ho_cnt > 0)
|
||||
if (*ho_cnt>0)
|
||||
{
|
||||
*ho_cnt = sub(*ho_cnt, 1);
|
||||
move16();
|
||||
pp[0]=1;
|
||||
pp[1]=0;
|
||||
(*ho_cnt)--;
|
||||
}
|
||||
|
||||
return state;
|
||||
123
src/libs/libevs/lib_com/env_stab_trans.cpp
Normal file
123
src/libs/libevs/lib_com/env_stab_trans.cpp
Normal file
@@ -0,0 +1,123 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.443 Nov 13, 2018. Version 12.11.0 / 13.7.0 / 14.3.0 / 15.1.0
|
||||
====================================================================================*/
|
||||
|
||||
#include "options.h"
|
||||
#include "cnst.h"
|
||||
#include "prot.h"
|
||||
#include "rom_com.h"
|
||||
#include <math.h>
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------*
|
||||
* env_stab_transient_detect()
|
||||
*
|
||||
* Transient detector for envelope stability measure
|
||||
*--------------------------------------------------------------------------*/
|
||||
|
||||
void env_stab_transient_detect(
|
||||
const short is_transient, /* i: Transient flag */
|
||||
const short length, /* i : Length of spectrum (32 or 48 kHz) */
|
||||
const short norm[], /* i : quantization indices for norms */
|
||||
short *no_att_hangover, /* i/o: Frame counter for attenuation hangover */
|
||||
float *energy_lt, /* i/o: Long-term energy measure for transient detection */
|
||||
const short HQ_mode, /* i : HQ coding mode */
|
||||
const short bin_th, /* i : HVQ cross-over frequency bin */
|
||||
const float *coeff /* i : Coded spectral coefficients */
|
||||
)
|
||||
{
|
||||
float d_max;
|
||||
float e_frame;
|
||||
short blk;
|
||||
short i;
|
||||
float E_sub[4];
|
||||
float delta_e_sub;
|
||||
short norm_ind;
|
||||
|
||||
short num_subframes = 4;
|
||||
short bands_per_subframe = 9;
|
||||
|
||||
if( HQ_mode == HQ_HVQ )
|
||||
{
|
||||
e_frame = 0.0f;
|
||||
|
||||
for (i = 0; i < bin_th; i++)
|
||||
{
|
||||
e_frame += coeff[i]*coeff[i];
|
||||
}
|
||||
|
||||
e_frame = (float)sqrt(e_frame / bin_th);
|
||||
|
||||
if (e_frame > ENERGY_TH)
|
||||
{
|
||||
*energy_lt = ENERGY_LT_BETA*(*energy_lt) + (1-ENERGY_LT_BETA)*e_frame;
|
||||
}
|
||||
|
||||
if (*no_att_hangover > 0)
|
||||
{
|
||||
(*no_att_hangover)--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
d_max = 0.0f;
|
||||
e_frame = 0.0f;
|
||||
if (is_transient && length == L_FRAME32k)
|
||||
{
|
||||
/* Measure subframe energies */
|
||||
for (blk = 0; blk < num_subframes; blk++)
|
||||
{
|
||||
E_sub[blk] = 0.0f;
|
||||
for (i=0; i<bands_per_subframe; i++)
|
||||
{
|
||||
norm_ind = subf_norm_groups[blk][i];
|
||||
E_sub[blk] += dicn[norm[norm_ind]];
|
||||
}
|
||||
E_sub[blk] = E_sub[blk] / bands_per_subframe;
|
||||
e_frame += E_sub[blk];
|
||||
}
|
||||
/* Test for transient */
|
||||
if (e_frame > ENERGY_TH * num_subframes)
|
||||
{
|
||||
for (blk = 0; blk < num_subframes-1; blk++)
|
||||
{
|
||||
delta_e_sub = (E_sub[blk+1]-E_sub[blk]) / *energy_lt;
|
||||
if (delta_e_sub > d_max)
|
||||
{
|
||||
d_max = delta_e_sub;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Update long-term energy measure */
|
||||
e_frame = 0.0f;
|
||||
|
||||
for (i = 0; i < SFM_N_ENV_STAB; i++)
|
||||
{
|
||||
e_frame += dicn[norm[i]];
|
||||
}
|
||||
|
||||
e_frame = e_frame / SFM_N_ENV_STAB;
|
||||
|
||||
if (e_frame > ENERGY_TH)
|
||||
{
|
||||
*energy_lt = ENERGY_LT_BETA*(*energy_lt) + (1-ENERGY_LT_BETA)*e_frame;
|
||||
}
|
||||
}
|
||||
|
||||
/* Add hang-over for conservative application of stability-dependent attenuation */
|
||||
if(d_max > DELTA_TH)
|
||||
{
|
||||
*no_att_hangover = ATT_LIM_HANGOVER;
|
||||
}
|
||||
else if (*no_att_hangover > 0)
|
||||
{
|
||||
(*no_att_hangover)--;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -1,160 +0,0 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#include "options.h" /* Compilation switches */
|
||||
#include "cnst_fx.h" /* Common constants */
|
||||
#include "prot_fx.h" /* Function prototypes */
|
||||
#include "rom_com_fx.h" /* Static table prototypes */
|
||||
#include "math_op.h" /* WMOPS macros */
|
||||
#include "stl.h" /* required by wmc_tool */
|
||||
|
||||
/*--------------------------------------------------------------------------*
|
||||
* env_stab_transient_detect()
|
||||
*
|
||||
* Transient detector for envelope stability measure
|
||||
*--------------------------------------------------------------------------*/
|
||||
|
||||
void env_stab_transient_detect_fx(
|
||||
const Word16 is_transient, /* i: Transient flag */
|
||||
const Word16 length, /* i : Length of spectrum (32 or 48 kHz) */
|
||||
const Word16 norm[], /* i : quantization indices for norms */
|
||||
Word16 *no_att_hangover, /* i/o: Frame counter for attenuation hangover (Q0) */
|
||||
Word32 *L_energy_lt, /* i/o: Long-term energy measure for transient detection (Q13) */
|
||||
const Word16 HQ_mode, /* i : HQ coding mode */
|
||||
const Word16 bin_th, /* i : HVQ cross-over frequency bin */
|
||||
const Word32 *L_coeff, /* i : Coded spectral coefficients */
|
||||
const Word16 Qcoeff /* i : Q of coded spectral coefficients */
|
||||
)
|
||||
{
|
||||
Word16 i, blk, norm_ind, sqrt_exp, bin_th_1, temp, sh;
|
||||
Word32 L_e_frame, L_temp, L_d_max;
|
||||
Word32 L_energy_lt_local;
|
||||
Word32 L_E_sub[4];
|
||||
Word32 L_delta_e_sub;
|
||||
|
||||
L_energy_lt_local = *L_energy_lt;
|
||||
move32();
|
||||
|
||||
L_d_max = L_deposit_l(0);
|
||||
L_e_frame = L_deposit_l(0);
|
||||
temp = 32;
|
||||
move16();
|
||||
|
||||
IF( sub(HQ_mode,HQ_HVQ) == 0 )
|
||||
{
|
||||
FOR (i = 0; i < bin_th; i++) /* find adaptive shift */
|
||||
{
|
||||
temp = s_min(temp,norm_l(L_coeff[i]));
|
||||
}
|
||||
sh = sub(temp,2); /* scale such that 2 msbs are not used, the resulting adaptive Qcoeff will be: Qcoeff+sh-16 */
|
||||
FOR (i = 0; i < bin_th; i++) /* Maximum number of loop runs 320 */
|
||||
{
|
||||
temp = extract_h(L_shl(L_coeff[i],sh));
|
||||
L_e_frame = L_mac(L_e_frame,temp,temp); /* Q(2*(Qcoeff+sh-16)+1)=Q(2*(Qcoeff+sh)-31 */
|
||||
}
|
||||
|
||||
bin_th_1 = INV_HVQ_THRES_BIN_24k;
|
||||
move16();
|
||||
if (sub(bin_th, HVQ_THRES_BIN_32k) == 0)
|
||||
{
|
||||
bin_th_1 = INV_HVQ_THRES_BIN_32k;
|
||||
move16();
|
||||
}
|
||||
L_temp = Mult_32_16(L_e_frame,bin_th_1); /* Q(2*(Qcoeff-16+sh)+1+21-15) -> Q(2*(Qcoeff+sh)-25) */
|
||||
L_e_frame = Sqrt_l(L_temp,&sqrt_exp);
|
||||
L_e_frame = L_shr(L_e_frame, add(sub(add(sh,Qcoeff),10),shr(sqrt_exp,1))); /* Adjust by (Qcoeff+sh-10) to fixed Q13: Qcoeff+sh+(-25+31)/2 - (Qcoeff+sh-10) -> Q13 */
|
||||
|
||||
IF ( L_sub(L_e_frame, ENERGY_TH_FX) > 0 )
|
||||
{
|
||||
L_energy_lt_local = Mult_32_16(*L_energy_lt, ENERGY_LT_BETA_FX);
|
||||
L_temp = Mult_32_16(L_e_frame, ENERGY_LT_BETA_1_FX);
|
||||
*L_energy_lt = L_add(L_energy_lt_local,L_temp);
|
||||
move32();
|
||||
}
|
||||
|
||||
IF (*no_att_hangover > 0)
|
||||
{
|
||||
(*no_att_hangover) = sub((*no_att_hangover), 1);
|
||||
move16();
|
||||
}
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
L_e_frame = L_deposit_l(0);
|
||||
|
||||
test();
|
||||
IF (is_transient && sub(length,L_FRAME32k) == 0)
|
||||
{
|
||||
/* Measure subframe energies */
|
||||
FOR (blk = 0; blk < NUM_SUBFRAMES; blk++)
|
||||
{
|
||||
L_E_sub[blk] = L_deposit_l(0); /* Q9 */
|
||||
|
||||
FOR (i=0; i<BANDS_PER_SUBFRAMES; i++) /* 9 times -> < 2^4 */
|
||||
{
|
||||
norm_ind = subf_norm_groups_fx[blk][i];
|
||||
move16();
|
||||
L_E_sub[blk] = L_add(L_E_sub[blk],L_shr(dicn_fx[norm[norm_ind]],4));
|
||||
move32(); ; /* Q10 */
|
||||
}
|
||||
|
||||
L_E_sub[blk] = Mult_32_16(L_E_sub[blk], INV_BANDS_PER_SUBFRAMES);
|
||||
move32(); /* Q(10+17-15) -> Q12 */
|
||||
|
||||
L_e_frame = L_add(L_e_frame,L_E_sub[blk]); /* Q12 */
|
||||
}
|
||||
|
||||
/* Test for transient */
|
||||
/* if (e_frame > ENERGY_TH * NUM_SUBFRAMES) */
|
||||
IF (L_sub(L_e_frame, ENERGY_TH_NUM_SUBFRAMES) > 0)
|
||||
{
|
||||
FOR (blk = 0; blk < NUM_SUBFRAMES-1; blk++)
|
||||
{
|
||||
L_delta_e_sub = L_sub(L_E_sub[blk+1],L_E_sub[blk]); /* Q12 */
|
||||
if (L_sub(L_delta_e_sub,L_d_max)>0)
|
||||
{
|
||||
L_d_max = L_add(L_delta_e_sub,0); /* L_d_max is NOT normalized with *energy_lt */
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
/* Update long-term energy measure */
|
||||
L_e_frame = L_deposit_l(0); /* Q9 */
|
||||
FOR (i = 0; i < SFM_N_ENV_STAB; i++) /* 27 times -> < 2^5 */
|
||||
{
|
||||
L_e_frame = L_add(L_e_frame,L_shr(dicn_fx[norm[i]],5));
|
||||
/* Q9 */
|
||||
}
|
||||
|
||||
L_e_frame = Mult_32_16(L_e_frame, INV_SFM_N_ENV_STAB); /* Q(9+19-15) -> Q13 */
|
||||
|
||||
IF ( L_sub(L_e_frame, ENERGY_TH_FX) > 0 )
|
||||
{
|
||||
L_energy_lt_local = Mult_32_16(*L_energy_lt, ENERGY_LT_BETA_FX);
|
||||
L_temp = Mult_32_16(L_e_frame, ENERGY_LT_BETA_1_FX);
|
||||
*L_energy_lt = L_add(L_energy_lt_local,L_temp);
|
||||
move32();
|
||||
}
|
||||
}
|
||||
|
||||
/* Add hang-over for conservative application of stability dependent attenuation */
|
||||
/* -> Note: L_d_max not normalized with *energy_lt */
|
||||
/* Hence, we compare L_d_max/DELTA_TH with *energy_lt */
|
||||
IF (L_sub(Mult_32_16(L_d_max, INV_DELTA_TH),L_energy_lt_local) > 0) /* Q13 = Q(12 + 16 -15) */
|
||||
{
|
||||
*no_att_hangover = ATT_LIM_HANGOVER;
|
||||
move16();
|
||||
}
|
||||
ELSE if (*no_att_hangover > 0)
|
||||
{
|
||||
*no_att_hangover = sub(*no_att_hangover,1);
|
||||
move16();
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
57
src/libs/libevs/lib_com/est_tilt.cpp
Normal file
57
src/libs/libevs/lib_com/est_tilt.cpp
Normal file
@@ -0,0 +1,57 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.443 Nov 13, 2018. Version 12.11.0 / 13.7.0 / 14.3.0 / 15.1.0
|
||||
====================================================================================*/
|
||||
|
||||
#include "options.h"
|
||||
#include "cnst.h"
|
||||
#include "prot.h"
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------*
|
||||
* est_tilt()
|
||||
*
|
||||
* Estimate spectral tilt based on the relative E of adaptive
|
||||
* and innovative excitations
|
||||
*-------------------------------------------------------------------*/
|
||||
|
||||
float est_tilt( /* o : tilt of the code */
|
||||
const float *adpt_exc, /* i : adaptive excitation vector */
|
||||
const float gain_pit, /* i : adaptive gain */
|
||||
const float *fixe_exc, /* i : algebraic exctitation vector */
|
||||
const float gain_code, /* i : algebraic code gain */
|
||||
float *voice_fac, /* o : voicing factor */
|
||||
const short L_subfr, /* i : subframe size */
|
||||
const short flag_tilt /* i : flag for special tilt */
|
||||
)
|
||||
{
|
||||
float ener, tmp, tilt_code;
|
||||
|
||||
ener = dotp( adpt_exc, adpt_exc, L_subfr );
|
||||
ener *= gain_pit * gain_pit; /* energy of pitch excitation */
|
||||
|
||||
tmp = dotp( fixe_exc, fixe_exc, L_subfr );
|
||||
tmp *= gain_code * gain_code; /* energy of innovative code excitation */
|
||||
|
||||
/* find voice factor (1=voiced, -1=unvoiced) */
|
||||
*voice_fac = (float)((ener - tmp) / (ener + tmp + 0.01f));
|
||||
|
||||
/* find tilt of code for next subframe */
|
||||
if (flag_tilt==0)
|
||||
{
|
||||
/*Between 0 (=unvoiced) and 0.5 (=voiced)*/
|
||||
tilt_code = (float)(0.25f*(1.0f + *voice_fac));
|
||||
}
|
||||
else if (flag_tilt==1)
|
||||
{
|
||||
/*Between 0.25 (=unvoiced) and 0.5 (=voiced)*/
|
||||
tilt_code = (float)(0.25f + (*voice_fac+1.0f)*0.125f);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*Between 0.28 (=unvoiced) and 0.56 (=voiced)*/
|
||||
tilt_code = (float)(0.28f + (*voice_fac+1.0f)*0.14f);
|
||||
}
|
||||
|
||||
return tilt_code;
|
||||
}
|
||||
|
||||
@@ -1,265 +0,0 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#include "options.h" /* Compilation switches */
|
||||
#include "cnst_fx.h" /* Common constants */
|
||||
#include "prot_fx.h" /* Function prototypes */
|
||||
#include "stl.h"
|
||||
#include "basop_mpy.h"
|
||||
#include "basop_util.h"
|
||||
|
||||
|
||||
/*======================================================================*/
|
||||
/* FUNCTION : est_tilt_fx() */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* PURPOSE : Estimate spectral tilt based on the relative E of adaptive */
|
||||
/* and innovative excitations */
|
||||
/* */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* INPUT ARGUMENTS : */
|
||||
/* _ (Word16 *) exc : adaptive excitation vector Q0 */
|
||||
/* _ (Word16) gain_pit : adaptive gain Q14 */
|
||||
/* _ (Word16 *) code : algebraic exctitation vector Q12 */
|
||||
/* _ (Word32) gain_code : algebraic code gain Q16 */
|
||||
/* _ (Word16) Q_exc : Scaling factor of excitation Q0 */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* OUTPUT ARGUMENTS : */
|
||||
/* _ (Word16 *) voice_fac : voicing factor Q15 */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* INPUT OUTPUT ARGUMENTS */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* RETURN ARGUMENTS : */
|
||||
/* _ (Word16) tolt_code : tilt of the code Q15 */
|
||||
/*=======================================================================*/
|
||||
Word16 est_tilt_fx( /* o : tilt of the code Q15 */
|
||||
const Word16 *exc, /* i : adaptive excitation vector Qx */
|
||||
const Word16 gain_pit, /* i : adaptive gain Q14 */
|
||||
const Word16 *code, /* i : algebraic exctitation vector Q9 */
|
||||
const Word32 gain_code, /* i : algebraic code gain Q16 */
|
||||
Word16 *voice_fac, /* o : voicing factor Q15 */
|
||||
const Word16 Q_exc /* i : Scaling factor of excitation Q0 */
|
||||
)
|
||||
{
|
||||
Word16 i, tmp, exp, ener1, exp1, ener2, exp2;
|
||||
Word32 L_tmp;
|
||||
Word16 tilt_code;
|
||||
|
||||
ener1 = extract_h(Dot_product12(exc, exc, L_SUBFR, &exp1));
|
||||
exp1 = sub(exp1, add(Q_exc, Q_exc));
|
||||
L_tmp = L_mult(gain_pit, gain_pit); /* energy of pitch excitation */
|
||||
exp = norm_l(L_tmp);
|
||||
tmp = extract_h(L_shl(L_tmp, exp));
|
||||
ener1 = mult(ener1, tmp);
|
||||
exp1 = sub(sub(exp1, exp), 10); /* 10 -> gain_pit Q14 to Q9 */
|
||||
|
||||
ener2 = extract_h(Dot_product12(code, code, L_SUBFR, &exp2));
|
||||
|
||||
exp = norm_l(gain_code);
|
||||
tmp = extract_h(L_shl(gain_code, exp));
|
||||
tmp = mult(tmp, tmp); /* energy of innovative code excitation */
|
||||
ener2 = mult(ener2, tmp);
|
||||
exp2 = sub(exp2, add(exp, exp));
|
||||
|
||||
i = sub(exp1, exp2);
|
||||
BASOP_SATURATE_WARNING_OFF
|
||||
ener1 = shr(ener1, sub(1, s_min(i, 0)));
|
||||
ener2 = shr(ener2, add(s_max(0, i), 1));
|
||||
BASOP_SATURATE_WARNING_ON
|
||||
tmp = sub(ener1, ener2);
|
||||
ener1 = add(add(ener1, ener2), 1);
|
||||
|
||||
/* find voice factor (1=voiced, -1=unvoiced) */
|
||||
exp = div_s(abs_s(tmp), ener1);
|
||||
if (tmp < 0)
|
||||
{
|
||||
exp = negate(exp);
|
||||
}
|
||||
*voice_fac = exp;
|
||||
move16();
|
||||
|
||||
/* tilt of code for next subframe: 0.5=voiced, 0=unvoiced */
|
||||
|
||||
/* tilt_code = (float)(0.25*(1.0 + *voice_fac)) */
|
||||
tilt_code = mac_r(8192L*65536-0x8000, *voice_fac, 8192); /*Q15 */
|
||||
|
||||
return tilt_code;
|
||||
}
|
||||
/*-------------------------------------------------------------------*
|
||||
* Est_tilt2:
|
||||
*
|
||||
* Estimate spectral tilt based on the relative E of adaptive
|
||||
* and innovative excitations
|
||||
*-------------------------------------------------------------------*/
|
||||
Word16 Est_tilt2( /* o : tilt of the code */
|
||||
const Word16 *exc, /* i : adaptive excitation vector Qx */
|
||||
const Word16 gain_pit, /* i : adaptive gain Q14 */
|
||||
const Word16 *code, /* i : algebraic exctitation vector Q9 */
|
||||
const Word32 gain_code, /* i : algebraic code gain Q16 */
|
||||
Word16 *voice_fac, /* o : voicing factor Q15 */
|
||||
const Word16 Q_exc /* i : Scaling factor of excitation Q0 */
|
||||
)
|
||||
{
|
||||
Word16 i, tmp, exp, ener1, exp1, ener2, exp2;
|
||||
Word32 L_tmp;
|
||||
Word16 tilt_code;
|
||||
|
||||
/* Scale exc to avoid overflow */
|
||||
ener1 = extract_h(Energy_scale(exc, L_SUBFR, Q_exc, &exp1));
|
||||
|
||||
exp1 = sub(exp1, add(Q_exc, Q_exc));
|
||||
L_tmp = L_mult(gain_pit, gain_pit); /* energy of pitch excitation */
|
||||
exp = norm_l(L_tmp);
|
||||
tmp = extract_h(L_shl(L_tmp, exp));
|
||||
ener1 = mult(ener1, tmp);
|
||||
exp1 = sub(sub(exp1, exp), 10); /* 10 -> gain_pit Q14 to Q9 */
|
||||
|
||||
ener2 = extract_h(Dot_product12(code, code, L_SUBFR, &exp2));
|
||||
|
||||
exp = norm_l(gain_code);
|
||||
tmp = extract_h(L_shl(gain_code, exp));
|
||||
tmp = mult(tmp, tmp); /* energy of innovative code excitation */
|
||||
ener2 = mult(ener2, tmp);
|
||||
exp2 = sub(exp2, add(exp, exp));
|
||||
|
||||
i = sub(exp1, exp2);
|
||||
ener1 = shr(ener1, sub(1, s_min(i, 0)));
|
||||
ener2 = shr(ener2, add(s_max(0, i), 1));
|
||||
|
||||
tmp = sub(ener1, ener2);
|
||||
ener1 = add(add(ener1, ener2), 1);
|
||||
|
||||
/* find voice factor (1=voiced, -1=unvoiced) */
|
||||
exp = div_s(abs_s(tmp), ener1);
|
||||
if (tmp < 0)
|
||||
{
|
||||
exp = negate(exp);
|
||||
}
|
||||
*voice_fac = exp;
|
||||
move16();
|
||||
|
||||
/* tilt of code for next subframe: 0.5=voiced, 0=unvoiced */
|
||||
|
||||
/* tilt_code = (float)(0.25*(1.0 + *voice_fac)) */
|
||||
tilt_code = mac_r(8192L*65536-0x8000, *voice_fac, 8192);
|
||||
|
||||
return tilt_code;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*
|
||||
* Find voice factor and tilt code *
|
||||
*---------------------------------------------------------*/
|
||||
void E_UTIL_voice_factor( Word16 *exc, /* i : pointer to the excitation frame Q_new */
|
||||
Word16 i_subfr, /* i : subframe index */
|
||||
Word16 *code, /* i : innovative codebook Q9 */
|
||||
Word16 gain_pit, /* i : adaptive codebook gain 1Q14 */
|
||||
Word32 gain_code, /* i : innovative cb. gain 15Q16 */
|
||||
Word16 *voice_fac, /* o : subframe voicing estimation Q15 */
|
||||
Word16 *tilt_code, /* o : tilt factor Q15 */
|
||||
Word16 L_subfr, /* i : subframe length */
|
||||
Word16 flag_tilt, /* i : Flag for triggering new voice factor tilt*/
|
||||
Word16 Q_new, /* i : excitation buffer format */
|
||||
Word16 shift /* i : scaling to get 12bit */
|
||||
)
|
||||
{
|
||||
Word16 i, e, e2, stmp, exp_ener, fac;
|
||||
Word32 ener, tmp, num;
|
||||
|
||||
BASOP_SATURATE_ERROR_ON;
|
||||
|
||||
IF(shift != 0)
|
||||
{
|
||||
fac = shl(0x4000,add(1,shift));
|
||||
/* energy of pitch excitation */
|
||||
stmp = mult_r(exc[0+i_subfr], fac); /* remove fac bits */
|
||||
ener = L_mac0(0L,stmp, stmp);
|
||||
FOR (i=1; i<L_subfr; i++)
|
||||
{
|
||||
stmp = mult_r(exc[i+i_subfr], fac); /* remove fac bits */
|
||||
ener = L_mac0(ener, stmp, stmp);
|
||||
}
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
ener = L_mult0(exc[0+i_subfr], exc[0+i_subfr]);
|
||||
FOR (i=1; i<L_subfr; i++)
|
||||
{
|
||||
ener = L_mac0(ener, exc[i+i_subfr], exc[i+i_subfr]); /* Q_new -> exponent = (15-Q_new)*2+1 */
|
||||
}
|
||||
}
|
||||
|
||||
/* exponent of ener: (2*(15-Q_new+shift)+1+2-exp_ener-2*e2) */
|
||||
exp_ener = norm_l(ener);
|
||||
if(ener == 0)
|
||||
{
|
||||
exp_ener = 31;
|
||||
move16();
|
||||
}
|
||||
ener = L_shl(ener,exp_ener);
|
||||
e2 = norm_s(gain_pit);
|
||||
gain_pit = shl(gain_pit,e2);
|
||||
ener = Mpy_32_16_1(ener, mult_r(gain_pit, gain_pit));
|
||||
|
||||
|
||||
/* energy of innovative code excitation */
|
||||
tmp = L_deposit_l(1);
|
||||
|
||||
FOR (i=0; i<L_subfr; i++)
|
||||
{
|
||||
tmp = L_mac0(tmp, code[i], code[i]); /* 6Q9 -> 13Q18 */
|
||||
}
|
||||
/* exponent of tmp: 2*(15-9)+1+2*(15-e)) */
|
||||
e = norm_l(gain_code);
|
||||
gain_code = L_shl(gain_code, e);
|
||||
tmp = Mpy_32_32(tmp, Mpy_32_32(gain_code,gain_code));
|
||||
|
||||
/* find voice factor (1=voiced, -1=unvoiced) */
|
||||
/*i = (2*(15-Q_new+shift)+1+2-exp_ener-2*e2) - (2*(15-9)+1 + 2*(15-e));*/
|
||||
i = sub(sub(sub(sub(sub(33,add(shift,shift)),add(Q_new,Q_new)),exp_ener),add(e2,e2)),sub(43,add(e,e)));
|
||||
IF(i >= 0)
|
||||
{
|
||||
ener = L_shr(ener,1);
|
||||
tmp = L_shr(tmp, add(1,i));
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
tmp = L_shr(tmp,1);
|
||||
BASOP_SATURATE_WARNING_OFF
|
||||
ener = L_shr(ener, sub(1,i));
|
||||
BASOP_SATURATE_WARNING_ON
|
||||
}
|
||||
|
||||
*voice_fac = 0;
|
||||
move16();
|
||||
num = L_sub(ener, tmp);
|
||||
IF(num != 0)
|
||||
{
|
||||
BASOP_SATURATE_WARNING_OFF /* Allow saturating the voice factor because if has a limited range by definition. */
|
||||
*voice_fac = divide3232(num, L_add(ener, tmp));
|
||||
move16();
|
||||
BASOP_SATURATE_WARNING_ON
|
||||
}
|
||||
|
||||
/* find tilt of code for next subframe */
|
||||
IF (flag_tilt==0)
|
||||
{
|
||||
/*Between 0 (=unvoiced) and 0.5 (=voiced)*/
|
||||
move16();
|
||||
*tilt_code = add(8192/*0.25f Q15*/, mult_r(8192/*0.25f Q15*/, *voice_fac));
|
||||
}
|
||||
ELSE IF (flag_tilt==1)
|
||||
{
|
||||
/*Between 0.25 (=unvoiced) and 0.5 (=voiced)*/
|
||||
move16();
|
||||
*tilt_code = add(mult_r(4096/*0.125f Q15*/, *voice_fac), 12288/*0.125f+0.25f Q15*/);
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
/*Between 0.28 (=unvoiced) and 0.56 (=voiced)*/
|
||||
move16();
|
||||
*tilt_code = add(mult_r(4588/*0.14f Q15*/, *voice_fac), 13763/*0.14f+0.28f Q15*/);
|
||||
}
|
||||
BASOP_SATURATE_ERROR_OFF;
|
||||
}
|
||||
2035
src/libs/libevs/lib_com/fd_cng_com.cpp
Executable file → Normal file
2035
src/libs/libevs/lib_com/fd_cng_com.cpp
Executable file → Normal file
File diff suppressed because it is too large
Load Diff
7095
src/libs/libevs/lib_com/fft.cpp
Executable file → Normal file
7095
src/libs/libevs/lib_com/fft.cpp
Executable file → Normal file
File diff suppressed because it is too large
Load Diff
1194
src/libs/libevs/lib_com/fft_cldfb.cpp
Normal file
1194
src/libs/libevs/lib_com/fft_cldfb.cpp
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
266
src/libs/libevs/lib_com/fft_rel.cpp
Normal file
266
src/libs/libevs/lib_com/fft_rel.cpp
Normal file
@@ -0,0 +1,266 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.443 Nov 13, 2018. Version 12.11.0 / 13.7.0 / 14.3.0 / 15.1.0
|
||||
====================================================================================*/
|
||||
|
||||
#include "options.h"
|
||||
#include "prot.h"
|
||||
#include "rom_com.h"
|
||||
|
||||
/*---------------------------------------------------------------------*
|
||||
* Local constants
|
||||
*---------------------------------------------------------------------*/
|
||||
|
||||
#define N_MAX_FFT 1024
|
||||
#define N_MAX_DIV2 (N_MAX_FFT>>1)
|
||||
#define N_MAX_DIV4 (N_MAX_DIV2>>1)
|
||||
|
||||
/*---------------------------------------------------------------------*
|
||||
* fft_rel()
|
||||
*
|
||||
* Computes the split-radix FFT in place for the real-valued
|
||||
* signal x of length n. The algorithm has been ported from
|
||||
* the Fortran code of [1].
|
||||
*
|
||||
* The function needs sine and cosine tables t_sin and t_cos,
|
||||
* and the constant N_MAX_FFT. The table entries are defined as
|
||||
* sin(2*pi*i) and cos(2*pi*i) for i = 0, 1, ..., N_MAX_FFT-1. The
|
||||
* implementation assumes that any entry will not be needed
|
||||
* outside the tables. Therefore, N_MAX_FFT and n must be properly
|
||||
* set. The function has been tested with the values n = 16,
|
||||
* 32, 64, 128, 256, and N_MAX_FFT = 1280.
|
||||
*
|
||||
* References
|
||||
* [1] H.V. Sorensen, D.L. Jones, M.T. Heideman, C.S. Burrus,
|
||||
* "Real-valued fast Fourier transform algorithm," IEEE
|
||||
* Trans. on Signal Processing, Vol.35, No.6, pp 849-863,
|
||||
* 1987.
|
||||
*
|
||||
* OUTPUT
|
||||
* x[0:n-1] Transform coeffients in the order re[0], re[1],
|
||||
* ..., re[n/2], im[n/2-1], ..., im[1].
|
||||
*---------------------------------------------------------------------*/
|
||||
|
||||
void fft_rel(
|
||||
float x[], /* i/o: input/output vector */
|
||||
const short n, /* i : vector length */
|
||||
const short m /* i : log2 of vector length */
|
||||
)
|
||||
{
|
||||
short i, j, k, n1, n2, n4;
|
||||
short step;
|
||||
float xt, t1, t2;
|
||||
float *x0, *x1, *x2;
|
||||
float *xi2, *xi3, *xi4, *xi1;
|
||||
const float *s, *c;
|
||||
const short *idx;
|
||||
|
||||
/* !!!! NMAX = 256 is hardcoded here (similar optimizations should be done for NMAX > 256) !!! */
|
||||
|
||||
float *x2even, *x2odd;
|
||||
float temp[512];
|
||||
|
||||
if ( n == 128 || n == 256 || n == 512 )
|
||||
{
|
||||
idx = fft256_read_indexes;
|
||||
|
||||
/* Combined Digit reverse counter & Length two butterflies */
|
||||
if (n == 128)
|
||||
{
|
||||
x2 = temp;
|
||||
for (i = 0; i < 64; i++)
|
||||
{
|
||||
j = *idx++;
|
||||
k = *idx++;
|
||||
|
||||
*x2++ = x[j>>1] + x[k>>1];
|
||||
*x2++ = x[j>>1] - x[k>>1];
|
||||
}
|
||||
}
|
||||
else if (n == 256)
|
||||
{
|
||||
x2 = temp;
|
||||
for (i = 0; i < 128; i++)
|
||||
{
|
||||
j = *idx++;
|
||||
k = *idx++;
|
||||
|
||||
*x2++ = x[j] + x[k];
|
||||
*x2++ = x[j] - x[k];
|
||||
}
|
||||
}
|
||||
else if (n == 512)
|
||||
{
|
||||
x2even = temp;
|
||||
x2odd = temp + 256;
|
||||
|
||||
for (i = 0; i < 128; i++)
|
||||
{
|
||||
j = 2 * *idx++;
|
||||
k = 2 * *idx++;
|
||||
|
||||
*x2even++ = x[j] + x[k];
|
||||
*x2even++ = x[j] - x[k];
|
||||
*x2odd++ = x[++j] + x[++k];
|
||||
*x2odd++ = x[j] - x[k];
|
||||
}
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------*
|
||||
* 1st Stage Loop has been Unrolled because n4 is '1' and that
|
||||
* allows the elimination of the 'for_ (j = 1; j < n4; j++)' loop
|
||||
* and the associated pointers initialization.
|
||||
* Also, it allows to Put the Data from 'temp' back into 'x' due
|
||||
* to the previous Combined Digit Reverse and Length two butterflies
|
||||
*-----------------------------------------------------------------*/
|
||||
|
||||
/*for_ (k = 2; k < 3; k++)*/
|
||||
{
|
||||
x0 = temp;
|
||||
x1 = x0 + 2;
|
||||
x2 = x;
|
||||
|
||||
for (i = 0; i < n; i += 4)
|
||||
{
|
||||
*x2++ = *x0++ + *x1; /* x[i] = xt + x[i+n2]; */
|
||||
*x2++ = *x0;
|
||||
*x2++ = *--x0 - *x1++; /* x[i+n2] = xt - x[i+n2]; */
|
||||
*x2++ = -*x1; /* x[i+n2+n4] = -x[i+n2+n4]; */
|
||||
|
||||
x0 += 4;
|
||||
x1 += 3; /* x1 has already advanced */
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*-----------------------------------------------------------------*
|
||||
* Digit reverse counter
|
||||
*-----------------------------------------------------------------*/
|
||||
|
||||
j = 0;
|
||||
x0 = &x[0];
|
||||
for (i = 0; i < n-1; i++)
|
||||
{
|
||||
if (i < j)
|
||||
{
|
||||
xt = x[j];
|
||||
x[j] = *x0;
|
||||
*x0 = xt;
|
||||
}
|
||||
x0++;
|
||||
k = n/2;
|
||||
while (k <= j)
|
||||
{
|
||||
j -= k;
|
||||
k = k>>1;
|
||||
}
|
||||
j += k;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------*
|
||||
* Length two butterflies
|
||||
*-----------------------------------------------------------------*/
|
||||
|
||||
x0 = &x[0];
|
||||
x1 = &x[1];
|
||||
for (i = 0; i < n/2; i++)
|
||||
{
|
||||
*x1 = *x0 - *x1;
|
||||
*x0 = *x0*2 - *x1;
|
||||
|
||||
x0++;
|
||||
x0++;
|
||||
x1++;
|
||||
x1++;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------*
|
||||
* 1st Stage Loop has been Unrolled because n4 is '1' and that
|
||||
* allows the elimination of the 'for_ (j = 1; j < n4; j++)' loop
|
||||
* and the associated pointers initialization.
|
||||
*-----------------------------------------------------------------*/
|
||||
|
||||
/* for_ (k = 2; k < 3; k++) */
|
||||
{
|
||||
x0 = x;
|
||||
x1 = x0 + 2;
|
||||
|
||||
for (i = 0; i < n; i += 4)
|
||||
{
|
||||
*x1 = *x0 - *x1; /* x[i+n2] = xt - x[i+n2]; */
|
||||
*x0 = *x0*2 - *x1++; /* x[i] = xt + x[i+n2]; */
|
||||
*x1 = -*x1; /* x[i+n2+n4] = -x[i+n2+n4]; */
|
||||
|
||||
x0 += 4;
|
||||
x1 += 3; /* x1 has already advanced */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------*
|
||||
* Other butterflies
|
||||
*
|
||||
* The implementation described in [1] has been changed by using
|
||||
* table lookup for evaluating sine and cosine functions. The
|
||||
* variable ind and its increment step are needed to access table
|
||||
* entries. Note that this implementation assumes n4 to be so
|
||||
* small that ind will never exceed the table. Thus the input
|
||||
* argument n and the constant N_MAX_FFT must be set properly.
|
||||
*-----------------------------------------------------------------*/
|
||||
|
||||
n4 = 1;
|
||||
n2 = 2;
|
||||
n1 = 4;
|
||||
|
||||
step = N_MAX_DIV4;
|
||||
|
||||
for (k = 3; k <= m; k++)
|
||||
{
|
||||
step >>= 1;
|
||||
n4 <<= 1;
|
||||
n2 <<= 1;
|
||||
n1 <<= 1;
|
||||
|
||||
x0 = x;
|
||||
x1 = x0 + n2;
|
||||
x2 = x1 + n4;
|
||||
|
||||
for (i = 0; i < n; i += n1)
|
||||
{
|
||||
*x1 = *x0 - *x1; /* x[i+n2] = xt - x[i+n2]; */
|
||||
*x0 = *x0*2 - *x1; /* x[i] = xt + x[i+n2]; */
|
||||
*x2 = -*x2; /* x[i+n2+n4] = -x[i+n2+n4]; */
|
||||
|
||||
s = sincos_t_ext;
|
||||
c = s + N_MAX_FFT/4; /* 1024/4 = 256, 256/4=64 */
|
||||
xi1 = x0;
|
||||
xi3 = xi1 + n2;
|
||||
xi2 = xi3;
|
||||
x0 += n1;
|
||||
xi4 = x0;
|
||||
|
||||
for (j = 1; j < n4; j++)
|
||||
{
|
||||
xi3++;
|
||||
xi1++;
|
||||
xi4--;
|
||||
xi2--;
|
||||
c += step;
|
||||
s+= step; /* autoincrement by ar0 */
|
||||
|
||||
t1 = *xi3**c + *xi4**s; /* t1 = *xi3**(pt_c+ind) + *xi4**(pt_s+ind); */
|
||||
t2 = *xi3**s - *xi4**c; /* t2 = *xi3**(pt_s+ind) - *xi4**(pt_c+ind); */
|
||||
|
||||
*xi4 = *xi2 - t2;
|
||||
*xi2 = *xi1 - t1;
|
||||
*xi1 = *xi1*2 - *xi2;
|
||||
*xi3 = -2*t2 - *xi4;
|
||||
}
|
||||
|
||||
x1 += n1;
|
||||
x2 += n1;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -1,431 +0,0 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#include "options.h" /* Compilation switches */
|
||||
#include "prot_fx.h" /* Function prototypes */
|
||||
#include "rom_com_fx.h" /* Static table prototypes */
|
||||
#include "stl.h"
|
||||
|
||||
/*------------------------------------------------------------------
|
||||
*
|
||||
* This is an implementation of decimation-in-time FFT algorithm for
|
||||
* real sequences. The techniques used here can be found in several
|
||||
* books, e.g., i) Proakis and Manolakis, "Digital Signal Processing",
|
||||
* 2nd Edition, Chapter 9, and ii) W.H. Press et. al., "Numerical
|
||||
* Recipes in C", 2nd Edition, Chapter 12.
|
||||
*
|
||||
* Input - There are two inputs to this function:
|
||||
*
|
||||
* 1) An integer pointer to the input data array
|
||||
* 2) An integer value which should be set as +1 for FFT
|
||||
* and some other value, e.g., -1 for ifFT
|
||||
*
|
||||
* Output - There is no return value.
|
||||
* The input data are replaced with transformed data. if the
|
||||
* input is a real time domain sequence, it is replaced with
|
||||
* the complex FFT for positive frequencies. The FFT value
|
||||
* for DC and the foldover frequency are combined to form the
|
||||
* first complex number in the array. The remaining complex
|
||||
* numbers correspond to increasing frequencies. if the input
|
||||
* is a complex frequency domain sequence arranged as above,
|
||||
* it is replaced with the corresponding time domain sequence.
|
||||
*
|
||||
* Notes:
|
||||
*
|
||||
* 1) This function is designed to be a part of a noise supp-
|
||||
* ression algorithm that requires 128-point FFT of real
|
||||
* sequences. This is achieved here through a 64-point
|
||||
* complex FFT. Consequently, the FFT size information is
|
||||
* not transmitted explicitly. However, some flexibility
|
||||
* is provided in the function to change the size of the
|
||||
* FFT by specifying the size information through "define"
|
||||
* statements.
|
||||
*
|
||||
* 2) The values of the complex sinusoids used in the FFT
|
||||
* algorithm are computed once (i.e., the first time the
|
||||
* r_fft function is called) and stored in a table. To
|
||||
* further speed up the algorithm, these values can be
|
||||
* precomputed and stored in a ROM table in actual DSP
|
||||
* based implementations.
|
||||
*
|
||||
* 3) In the c_fft function, the FFT values are divided by
|
||||
* 2 after each stage of computation thus dividing the
|
||||
* final FFT values by 64. No multiplying factor is used
|
||||
* for the ifFT. This is somewhat different from the usual
|
||||
* definition of FFT where the factor 1/N, i.e., 1/64, is
|
||||
* used for the ifFT and not the FFT. No factor is used in
|
||||
* the r_fft function.
|
||||
*
|
||||
* 4) Much of the code for the FFT and ifFT parts in r_fft
|
||||
* and c_fft functions are similar and can be combined.
|
||||
* They are, however, kept separate here to speed up the
|
||||
* execution.
|
||||
*------------------------------------------------------------------------*/
|
||||
/*------------------------------------------------------------------------*
|
||||
* c_fft_fx:
|
||||
*
|
||||
* Computes the complex part of the split-radix FFT
|
||||
*------------------------------------------------------------------------*/
|
||||
|
||||
static void c_fft_fx(
|
||||
const Word16 *phs_tbl, /* i : Table of phases */
|
||||
Word16 SIZE, /* i : Size of the FFT */
|
||||
Word16 NUM_STAGE, /* i : Number of stages */
|
||||
const Word16 *in_ptr, /* i : coefficients in the order re[0], re[n/2], re[1], im[1], ..., re[n/2-1], im[n/2-1] */
|
||||
Word16 *out_ptr, /* o : coefficients in the order re[0], re[n/2], re[1], im[1], ..., re[n/2-1], im[n/2-1] */
|
||||
/* in_ptr & out_ptr must not overlap! */
|
||||
const Word16 isign) /* i : 1=fft, otherwise it is ifft*/
|
||||
{
|
||||
Word16 i, j, k, ii, jj, kk, ji, kj;
|
||||
Word32 L_tmp1, L_tmp2;
|
||||
Word16 tmp1,tmp2,tmp3,tmp4;
|
||||
const Word16 *table_ptr;
|
||||
const Word16 *input_ptr1,*input_ptr2,*input_ptr3,*input_ptr4;
|
||||
|
||||
/* Setup Reorder Variables */
|
||||
table_ptr = NULL;
|
||||
SWITCH (SIZE)
|
||||
{
|
||||
case 1024:
|
||||
table_ptr = FFT_REORDER_1024;
|
||||
BREAK;
|
||||
case 512:
|
||||
table_ptr = FFT_REORDER_512;
|
||||
BREAK;
|
||||
case 256:
|
||||
table_ptr = FFT_reorder_256;
|
||||
BREAK;
|
||||
case 128:
|
||||
table_ptr = FFT_REORDER_128;
|
||||
BREAK;
|
||||
case 64:
|
||||
table_ptr = FFT_reorder_64;
|
||||
BREAK;
|
||||
}
|
||||
/* The FFT part */
|
||||
IF (isign != 0)
|
||||
{
|
||||
/* Unrolled 1st/2nd Stage
|
||||
* 1) to take advantage of Table Values (0 & +/- 16384)
|
||||
* 2) to perform reordering of Input Values
|
||||
*/
|
||||
FOR (k = 0; k < SIZE; k += 8)
|
||||
{
|
||||
/*
|
||||
* This loop use:
|
||||
* 4 Word16 (tmp1...tmp4)
|
||||
* 2 Word32 (L_tmp1 & L_tmp2)
|
||||
* 4 Pointers (table_ptr, input_ptr1, input_ptr2, input_ptr3)
|
||||
*
|
||||
* The addition of 'in_ptr' + and index value from 'reorder_ptr'
|
||||
* is counted as a move16()
|
||||
*/
|
||||
|
||||
input_ptr1 = in_ptr + *table_ptr++;
|
||||
|
||||
L_tmp1 = L_mult(*input_ptr1++, 16384);
|
||||
L_tmp2 = L_mult(*input_ptr1, 16384);
|
||||
|
||||
input_ptr1 = in_ptr + *table_ptr++;
|
||||
|
||||
tmp1 = msu_r(L_tmp1, *input_ptr1, 16384);
|
||||
tmp3 = mac_r(L_tmp1, *input_ptr1++, 16384);
|
||||
|
||||
input_ptr2 = in_ptr + *table_ptr++;
|
||||
input_ptr3 = in_ptr + *table_ptr++;
|
||||
|
||||
L_tmp1 = L_mult(*input_ptr2++, 16384);
|
||||
tmp2 = mac_r(L_tmp1, *input_ptr3, 16384);
|
||||
tmp4 = msu_r(L_tmp1, *input_ptr3++, 16384);
|
||||
|
||||
L_tmp1 = L_mult(tmp3, 16384);
|
||||
out_ptr[k] = mac_r(L_tmp1, tmp2, 16384);
|
||||
move16();
|
||||
out_ptr[k+4] = msu_r(L_tmp1, tmp2, 16384);
|
||||
move16();
|
||||
|
||||
tmp2 = mac_r(L_tmp2, *input_ptr1, 16384);
|
||||
tmp3 = msu_r(L_tmp2, *input_ptr1, 16384);
|
||||
|
||||
L_tmp2 = L_mult(*input_ptr2, 16384);
|
||||
|
||||
L_tmp1 = L_mult(tmp1, 16384);
|
||||
tmp1 = msu_r(L_tmp2, *input_ptr3, 16384);
|
||||
out_ptr[k+2] = mac_r(L_tmp1, tmp1, 16384);
|
||||
move16();
|
||||
out_ptr[k+6] = msu_r(L_tmp1, tmp1, 16384);
|
||||
move16();
|
||||
|
||||
L_tmp1 = L_mult(tmp2, 16384);
|
||||
tmp2 = mac_r(L_tmp2, *input_ptr3, 16384);
|
||||
out_ptr[k+1] = mac_r(L_tmp1, tmp2, 16384);
|
||||
move16();
|
||||
out_ptr[k+5] = msu_r(L_tmp1, tmp2, 16384);
|
||||
move16();
|
||||
|
||||
L_tmp1 = L_mult(tmp3, 16384);
|
||||
out_ptr[k+3] = msu_r(L_tmp1, tmp4, 16384);
|
||||
move16();
|
||||
out_ptr[k+7] = mac_r(L_tmp1, tmp4, 16384);
|
||||
move16();
|
||||
}
|
||||
|
||||
/* Remaining Stages */
|
||||
FOR (i = 2; i < NUM_STAGE; i++)
|
||||
{
|
||||
/* i is stage counter */
|
||||
jj = shl(2, i); /* FFT size */
|
||||
kk = shl(jj, 1); /* 2 * FFT size */
|
||||
ii = shr(SIZE, i);
|
||||
ji = 0;
|
||||
move16(); /* ji is phase table index */
|
||||
|
||||
FOR (j = 0; j < jj; j += 2)
|
||||
{
|
||||
/* j is sample counter */
|
||||
FOR (k = j; k < SIZE; k += kk)
|
||||
{
|
||||
/* k is butterfly top */
|
||||
kj = add(k, jj); /* kj is butterfly bottom */
|
||||
|
||||
/* Butterfly computations */
|
||||
L_tmp1 = L_msu(L_mult(*(out_ptr + kj), phs_tbl[ji]),
|
||||
*(out_ptr + kj + 1), phs_tbl[ji + 1]);
|
||||
L_tmp2 = L_mac(L_mult(*(out_ptr + kj + 1), phs_tbl[ji]),
|
||||
*(out_ptr + kj), phs_tbl[ji + 1]);
|
||||
|
||||
out_ptr[kj] = mac_r(L_negate(L_tmp1), out_ptr[k], 16384);
|
||||
move16();
|
||||
out_ptr[kj+1] = mac_r(L_negate(L_tmp2), out_ptr[k+1], 16384);
|
||||
move16();
|
||||
out_ptr[k] = mac_r(L_tmp1, out_ptr[k], 16384);
|
||||
move16();
|
||||
out_ptr[k+1] = mac_r(L_tmp2, out_ptr[k+1], 16384);
|
||||
move16();
|
||||
}
|
||||
ji = add(ji, ii);
|
||||
}
|
||||
}
|
||||
}
|
||||
ELSE /* The ifFT part */
|
||||
{
|
||||
/* Unrolled 1st/2nd Stage
|
||||
* 1) to take advantage of Table Values (0 & +/- 16384)
|
||||
* 2) to perform reordering of Input Values
|
||||
*/
|
||||
FOR (k = 0; k < SIZE; k += 8)
|
||||
{
|
||||
/*
|
||||
* This loop use:
|
||||
* 4 Word16 (tmp1...tmp4)
|
||||
* 2 Word32 (L_tmp1 & L_tmp2)
|
||||
* 5 Pointers (reorder_ptr, input_ptr1...input_ptr4)
|
||||
*
|
||||
* The addition of 'in_ptr' + and index value from 'reorder_ptr'
|
||||
* is counted as a move16()
|
||||
*/
|
||||
|
||||
input_ptr1 = in_ptr + *table_ptr++;
|
||||
input_ptr2 = in_ptr + *table_ptr++;
|
||||
|
||||
input_ptr3 = in_ptr + *table_ptr++;
|
||||
input_ptr4 = in_ptr + *table_ptr++;
|
||||
|
||||
tmp3 = sub(*input_ptr1, *input_ptr2);
|
||||
tmp4 = add(*input_ptr1++, *input_ptr2++);
|
||||
|
||||
tmp2 = sub(input_ptr3[0], input_ptr4[0]);
|
||||
tmp1 = sub(input_ptr3[1], input_ptr4[1]);
|
||||
|
||||
out_ptr[k+2] = sub(tmp3, tmp1);
|
||||
move16();
|
||||
out_ptr[k+6] = add(tmp3, tmp1);
|
||||
move16();
|
||||
|
||||
tmp1 = sub(*input_ptr1, *input_ptr2);
|
||||
out_ptr[k+3] = add(tmp1, tmp2);
|
||||
move16();
|
||||
out_ptr[k+7] = sub(tmp1, tmp2);
|
||||
move16();
|
||||
|
||||
tmp1 = add(input_ptr3[0], input_ptr4[0]);
|
||||
tmp3 = add(input_ptr3[1], input_ptr4[1]);
|
||||
|
||||
out_ptr[k] = add(tmp4, tmp1);
|
||||
move16();
|
||||
out_ptr[k+4] = sub(tmp4, tmp1);
|
||||
move16();
|
||||
|
||||
tmp4 = add(*input_ptr1, *input_ptr2);
|
||||
out_ptr[k+1] = add(tmp4, tmp3);
|
||||
move16();
|
||||
out_ptr[k+5] = sub(tmp4, tmp3);
|
||||
move16();
|
||||
}
|
||||
|
||||
table_ptr = phs_tbl + SIZE; /* access part of table that is scaled by 2 */
|
||||
|
||||
/* Remaining Stages */
|
||||
FOR (i = 2; i < NUM_STAGE; i++)
|
||||
{
|
||||
/* i is stage counter */
|
||||
jj = shl(2, i); /* FFT size */
|
||||
kk = shl(jj, 1); /* 2 * FFT size */
|
||||
ii = shr(SIZE, i);
|
||||
ji = 0;
|
||||
move16(); /* ji is phase table index */
|
||||
|
||||
FOR (j = 0; j < jj; j += 2)
|
||||
{
|
||||
/* j is sample counter */
|
||||
/* This can be computed by successive add_fxitions of ii to ji, starting from 0
|
||||
hence line-count it as a one-line add (still need to increment op count!!) */
|
||||
|
||||
FOR (k = j; k < SIZE; k += kk)
|
||||
{
|
||||
/* k is butterfly top */
|
||||
kj = add(k, jj); /* kj is butterfly bottom */
|
||||
|
||||
/* Butterfly computations */
|
||||
tmp1 = mac_r(L_mult(out_ptr[kj], table_ptr[ji]),
|
||||
out_ptr[kj+1], table_ptr[ji + 1]);
|
||||
|
||||
tmp2 = msu_r(L_mult(out_ptr[kj+1], table_ptr[ji]),
|
||||
out_ptr[kj], table_ptr[ji+1]);
|
||||
|
||||
out_ptr[kj] = sub(out_ptr[k], tmp1);
|
||||
move16();
|
||||
out_ptr[kj+1] = sub(out_ptr[k+1], tmp2);
|
||||
move16();
|
||||
out_ptr[k] = add(out_ptr[k], tmp1);
|
||||
move16();
|
||||
out_ptr[k+1] = add(out_ptr[k+1], tmp2);
|
||||
move16();
|
||||
}
|
||||
ji = add(ji, ii);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------------*
|
||||
* r_fft_fx:
|
||||
*
|
||||
* Perform FFT fixed-point for real-valued sequences of length 32, 64 or 128
|
||||
*--------------------------------------------------------------------------------*/
|
||||
void r_fft_fx_lc(
|
||||
const Word16 *phs_tbl, /* i : Table of phase */
|
||||
const Word16 SIZE, /* i : Size of the FFT */
|
||||
const Word16 SIZE2, /* i : Size / 2 */
|
||||
const Word16 NUM_STAGE, /* i : Number of stage */
|
||||
const Word16 *in_ptr, /* i : coefficients in the order re[0], re[1], ... re[n/2], im[n/2-1], im[n/2-2], ..., im[1] */
|
||||
Word16 *out_ptr, /* o : coefficients in the order re[0], re[1], ... re[n/2], im[n/2-1], im[n/2-2], ..., im[1] */
|
||||
const Word16 isign /* i : 1=fft, otherwize it's ifft */
|
||||
)
|
||||
{
|
||||
Word16 tmp2_real, tmp2_imag;
|
||||
Word32 Ltmp1_real, Ltmp1_imag;
|
||||
Word16 i;
|
||||
Word32 Ltmp1;
|
||||
const Word16 *phstbl_ptrDn;
|
||||
Word16 *ptrDn;
|
||||
Word16 temp[1024]; /* Accommodates real input FFT size up to 1024. */
|
||||
|
||||
/* Setup Pointers */
|
||||
phstbl_ptrDn = &phs_tbl[SIZE-1];
|
||||
|
||||
/* The FFT part */
|
||||
IF (isign != 0)
|
||||
{
|
||||
Word16 *ptRealUp, *ptRealDn, *ptImaUp, *ptImaDn;
|
||||
|
||||
/* Perform the complex FFT */
|
||||
c_fft_fx(phs_tbl, SIZE, NUM_STAGE, in_ptr, temp, isign);
|
||||
|
||||
/* First, handle the DC and foldover frequencies */
|
||||
out_ptr[SIZE2] = sub(temp[0], temp[1]);
|
||||
move16();
|
||||
out_ptr[0] = sub(add(temp[0], temp[1]), shr(NUM_STAGE, 1));
|
||||
move16();/* DC have a small offset */
|
||||
|
||||
ptrDn = &temp[SIZE-1];
|
||||
|
||||
ptImaDn = &out_ptr[SIZE-1];
|
||||
ptRealUp = &out_ptr[1];
|
||||
ptImaUp = &out_ptr[SIZE2+1];
|
||||
ptRealDn = &out_ptr[SIZE2-1];
|
||||
|
||||
/* Now, handle the remaining positive frequencies */
|
||||
FOR (i = 2; i <= SIZE2; i += 2)
|
||||
{
|
||||
Ltmp1_imag = L_mult(temp[i+1], 16384);
|
||||
Ltmp1_imag = L_msu(Ltmp1_imag, *ptrDn, 16384);
|
||||
tmp2_real = add(temp[i+1], *ptrDn--);
|
||||
|
||||
Ltmp1_real = L_mult(temp[i], 16384);
|
||||
Ltmp1_real = L_mac(Ltmp1_real, *ptrDn, 16384);
|
||||
tmp2_imag = sub(*ptrDn--, temp[i]);
|
||||
|
||||
|
||||
*ptRealUp++ = msu_r(L_mac(Ltmp1_real, tmp2_real, phs_tbl[i]), tmp2_imag, phs_tbl[i+1]);
|
||||
move16();
|
||||
*ptImaDn-- = mac_r(L_mac(Ltmp1_imag, tmp2_imag, phs_tbl[i]), tmp2_real, phs_tbl[i+1]);
|
||||
move16();
|
||||
Ltmp1 = L_mac(L_negate(Ltmp1_imag), tmp2_real, *phstbl_ptrDn);
|
||||
Ltmp1_real = L_mac(Ltmp1_real, tmp2_imag, *phstbl_ptrDn--);
|
||||
*ptImaUp++ = msu_r(Ltmp1, tmp2_imag, *phstbl_ptrDn);
|
||||
move16();
|
||||
*ptRealDn-- = mac_r(Ltmp1_real, tmp2_real, *phstbl_ptrDn--);
|
||||
move16();
|
||||
}
|
||||
}
|
||||
ELSE /* The ifFT part */
|
||||
{
|
||||
const Word16 *ptRealUp, *ptRealDn, *ptImaUp, *ptImaDn;
|
||||
|
||||
/* First, handle the DC and foldover frequencies */
|
||||
Ltmp1 = L_mult(in_ptr[0], 16384);
|
||||
temp[0] = mac_r(Ltmp1, in_ptr[SIZE2], 16384);
|
||||
move16();
|
||||
temp[1] = msu_r(Ltmp1, in_ptr[SIZE2], 16384);
|
||||
move16();
|
||||
|
||||
ptrDn = &temp[SIZE-1];
|
||||
|
||||
/* Here we cast to Word16 * from a const Word16 *. */
|
||||
/* This is ok because we use these pointers for */
|
||||
/* reading only. This is just to avoid declaring a */
|
||||
/* bunch of 4 other pointer with const Word16 *. */
|
||||
ptImaDn = &in_ptr[SIZE-1];
|
||||
ptRealUp = &in_ptr[1];
|
||||
ptImaUp = &in_ptr[SIZE2+1];
|
||||
ptRealDn = &in_ptr[SIZE2-1];
|
||||
|
||||
/* Now, handle the remaining positive frequencies */
|
||||
FOR (i = 2; i <= SIZE2; i += 2)
|
||||
{
|
||||
Ltmp1_imag = L_mult(*ptImaDn, 16384);
|
||||
Ltmp1_imag = L_msu(Ltmp1_imag, *ptImaUp, 16384);
|
||||
tmp2_real = add(*ptImaDn--, *ptImaUp++);
|
||||
Ltmp1_real = L_mult(*ptRealUp, 16384);
|
||||
Ltmp1_real = L_mac(Ltmp1_real, *ptRealDn, 16384);
|
||||
tmp2_imag = sub(*ptRealUp++, *ptRealDn--);
|
||||
|
||||
|
||||
temp[i] = mac_r(L_msu(Ltmp1_real, tmp2_real, phs_tbl[i]), tmp2_imag, phs_tbl[i+1]);
|
||||
move16();
|
||||
temp[i+1] = mac_r(L_mac(Ltmp1_imag, tmp2_imag, phs_tbl[i]), tmp2_real, phs_tbl[i+1]);
|
||||
move16();
|
||||
Ltmp1 = L_mac(L_negate(Ltmp1_imag), tmp2_real, *phstbl_ptrDn);
|
||||
Ltmp1_real = L_msu(Ltmp1_real, tmp2_imag, *phstbl_ptrDn--);
|
||||
*ptrDn-- = msu_r(Ltmp1, tmp2_imag, *phstbl_ptrDn);
|
||||
move16();
|
||||
*ptrDn-- = msu_r(Ltmp1_real, tmp2_real, *phstbl_ptrDn--);
|
||||
move16();
|
||||
}
|
||||
|
||||
/* Perform the complex ifFT */
|
||||
c_fft_fx(phs_tbl, SIZE, NUM_STAGE, temp, out_ptr, isign);
|
||||
}
|
||||
}
|
||||
@@ -1,456 +0,0 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#include "options.h" /* Compilation switches */
|
||||
#include "prot_fx.h" /* Function prototypes */
|
||||
#include "rom_com_fx.h" /* Static table prototypes */
|
||||
#include "prot_fx.h" /* Function prototypes */
|
||||
#include "stl.h"
|
||||
|
||||
/*---------------------------------------------------------------------*
|
||||
* Local constants
|
||||
*---------------------------------------------------------------------*/
|
||||
|
||||
#define INV_SQR2_FX 23170
|
||||
#define N_MAX_SAS 256
|
||||
|
||||
/*---------------------------------------------------------------------*
|
||||
* fft_rel_fx()
|
||||
*
|
||||
* Computes the split-radix FFT in place for the real-valued
|
||||
* signal x of length n. The algorithm has been ported from
|
||||
* the fortran code of [1].
|
||||
*
|
||||
* The function needs sine and cosine tables t_sin and t_cos,
|
||||
* and the constant N_MAX_SAS. The table entries are defined as
|
||||
* sin(2*pi*i) and cos(2*pi*i) for i = 0, 1, ..., N_MAX_SAS-1. The
|
||||
* implementation assumes that any entry will not be needed
|
||||
* outside the tables. Therefore, N_MAX_SAS and n must be properly
|
||||
* set. The function has been tested with the values n = 16,
|
||||
* 32, 64, 128, 256, and N_MAX_SAS = 1280.
|
||||
*
|
||||
* References
|
||||
* [1] H.V. Sorensen, D.L. Jones, M.T. Heideman, C.S. Burrus,
|
||||
* "Real-valued fast Fourier transform algorithm," IEEE
|
||||
* Trans. on Signal Processing, Vol.35, No.6, pp 849-863,
|
||||
* 1987.
|
||||
*
|
||||
* OUTPUT
|
||||
* x[0:n-1] Transform coeffients in the order re[0], re[1],
|
||||
* ..., re[n/2], im[n/2-1], ..., im[1].
|
||||
*---------------------------------------------------------------------*/
|
||||
/*MERGE fft_rel_fx and fft_rel_fx_lc */
|
||||
void fft_rel_fx(
|
||||
Word16 x[], /* i/o: input/output vector */
|
||||
const Word16 n, /* i : vector length */
|
||||
const Word16 m /* i : log2 of vector length */
|
||||
)
|
||||
{
|
||||
Word16 i, j, k, n1, n2, n4;
|
||||
Word16 step;
|
||||
Word16 xt, t1, t2;
|
||||
Word16 *x0, *x1, *x2;
|
||||
const Word16 *s, *c;
|
||||
Word16 *xi2, *xi3, *xi4, *xi1;
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------*
|
||||
* Digit reverse counter
|
||||
*-----------------------------------------------------------------*/
|
||||
|
||||
j = 0;
|
||||
move16();
|
||||
x0 = &x[0];
|
||||
move16();
|
||||
FOR (i = 0; i < n-1; i++)
|
||||
{
|
||||
IF (sub(i,j) < 0)
|
||||
{
|
||||
xt = x[j];
|
||||
move16();
|
||||
x[j] = *x0;
|
||||
move16();
|
||||
*x0 = xt;
|
||||
move16();
|
||||
}
|
||||
x0++;
|
||||
k = shr(n,1);
|
||||
WHILE (sub(k,j) <= 0)
|
||||
{
|
||||
j = sub(j,k);
|
||||
k = shr(k,1);
|
||||
}
|
||||
j = add(j,k);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------*
|
||||
* Length two butterflies
|
||||
*-----------------------------------------------------------------*/
|
||||
|
||||
x0 = &x[0];
|
||||
move16();
|
||||
x1 = &x[1];
|
||||
move16();
|
||||
FOR (i = 0; i < n/2; i++)
|
||||
{
|
||||
xt = *x0;
|
||||
move16();
|
||||
*x0 = add(xt,*x1);
|
||||
move16();
|
||||
*x1 = sub(xt,*x1);
|
||||
move16();
|
||||
x0++;
|
||||
x0++;
|
||||
x1++;
|
||||
x1++;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------*
|
||||
* Other butterflies
|
||||
*
|
||||
* The implementation described in [1] has been changed by using
|
||||
* table lookup for evaluating sine and cosine functions. The
|
||||
* variable ind and its increment step are needed to access table
|
||||
* entries. Note that this implementation assumes n4 to be so
|
||||
* small that ind will never exceed the table. Thus the input
|
||||
* argument n and the constant N_MAX_SAS must be set properly.
|
||||
*-----------------------------------------------------------------*/
|
||||
|
||||
n2 = 1;
|
||||
move16();
|
||||
/* step = N_MAX_SAS/4; */
|
||||
FOR (k = 2; k <= m; k++)
|
||||
{
|
||||
n4 = n2;
|
||||
move16();
|
||||
n2 = shl(n4,1);
|
||||
n1 = shl(n2,1);
|
||||
|
||||
step = N_MAX_SAS/n1;
|
||||
|
||||
x0 = x;
|
||||
x1 = x + n2;
|
||||
x2 = x + add(n2, n4);
|
||||
FOR (i = 0; i < n; i += n1)
|
||||
{
|
||||
xt = *x0;
|
||||
move16(); /* xt = x[i]; */
|
||||
*x0 = add(xt,*x1);
|
||||
move16(); /* x[i] = xt + x[i+n2]; */
|
||||
*x1 = sub(xt,*x1);
|
||||
move16(); /* x[i+n2] = xt - x[i+n2]; */
|
||||
*x2 = negate(*x2);
|
||||
move16(); /* x[i+n2+n4] = -x[i+n2+n4]; */
|
||||
|
||||
|
||||
s = sincos_t_fx + step;
|
||||
c = s + 64;
|
||||
xi1 = x + add(i, 1);
|
||||
xi3 = xi1 + n2;
|
||||
xi2 = xi3 - 2;
|
||||
xi4 = xi1 + sub(n1, 2);
|
||||
|
||||
FOR (j = 1; j < n4; j++)
|
||||
{
|
||||
t1 = add(mult_r(*xi3,*c),mult_r(*xi4,*s)); /* t1 = *xi3**(pt_c+ind) + *xi4**(pt_s+ind); */
|
||||
t2 = sub(mult_r(*xi3,*s),mult_r(*xi4,*c)); /* t2 = *xi3**(pt_s+ind) - *xi4**(pt_c+ind); */
|
||||
*xi4 = sub(*xi2,t2);
|
||||
move16();
|
||||
*xi3 = negate(add(*xi2,t2));
|
||||
move16();
|
||||
*xi2 = sub(*xi1,t1);
|
||||
move16();
|
||||
*xi1 = add(*xi1,t1);
|
||||
move16();
|
||||
|
||||
xi4--;
|
||||
xi2--;
|
||||
xi3++;
|
||||
xi1++;
|
||||
c += step;
|
||||
s += step; /* autoincrement by ar0 */
|
||||
}
|
||||
|
||||
x0 += n1;
|
||||
x1 += n1;
|
||||
x2 += n1;
|
||||
}
|
||||
/* step = shr(step, 1); */
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void ifft_rel_fx(
|
||||
Word16 io[], /* i/o: input/output vector */
|
||||
const Word16 n, /* i : vector length */
|
||||
const Word16 m /* i : log2 of vector length */
|
||||
)
|
||||
{
|
||||
Word16 i, j, k;
|
||||
Word16 step;
|
||||
Word16 n2, n4, n8, i0;
|
||||
Word16 is, id;
|
||||
Word16 *x,*xi0, *xi1, *xi2, *xi3, *xi4, *xup1, *xdn6, *xup3, *xdn8;
|
||||
Word16 xt;
|
||||
Word16 r1;
|
||||
Word16 t1, t2, t3, t4, t5;
|
||||
const Word16 *s, *c, *s3, *c3;
|
||||
|
||||
Word16 cc1, cc3, ss1, ss3;
|
||||
Word16 tmp;
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------*
|
||||
* ifft
|
||||
*-----------------------------------------------------------------*/
|
||||
|
||||
x = &io[-1];
|
||||
move16();
|
||||
n2 = shl(n,1);
|
||||
FOR (k=1; k<m; k++)
|
||||
{
|
||||
is = 0;
|
||||
move16();
|
||||
id = n2;
|
||||
move16();
|
||||
n2 = shr(n2,1);
|
||||
move16();
|
||||
n4 = shr(n2,2);
|
||||
move16();
|
||||
n8 = shr(n4,1);
|
||||
move16();
|
||||
tmp = sub(n,1);
|
||||
WHILE( sub(is,tmp) < 0 )
|
||||
{
|
||||
xi1 = x + is + 1;
|
||||
move16();
|
||||
xi2 = xi1 + n4;
|
||||
move16();
|
||||
xi3 = xi2 + n4;
|
||||
move16();
|
||||
xi4 = xi3 + n4;
|
||||
move16();
|
||||
|
||||
FOR (i=is; i<n; i+= id)
|
||||
{
|
||||
t1 = sub(*xi1,*xi3);
|
||||
*xi1 = add(*xi1,*xi3);
|
||||
move16();
|
||||
*xi2 = shl(*xi2,1);
|
||||
move16();
|
||||
*xi3 = sub(t1,shl(*xi4,1));
|
||||
move16();
|
||||
*xi4 = add(t1,shl(*xi4,1));
|
||||
move16();
|
||||
|
||||
IF (sub(n4,1) != 0)
|
||||
{
|
||||
t1 = mult_r(sub(*(xi2+n8),*(xi1+n8)),INV_SQR2_FX);
|
||||
t2 = mult_r(add(*(xi4+n8),*(xi3+n8)),INV_SQR2_FX);
|
||||
|
||||
*(xi1+n8) = add(*(xi1+n8),*(xi2+n8));
|
||||
move16();
|
||||
*(xi2+n8) = sub(*(xi4+n8),*(xi3+n8));
|
||||
move16();
|
||||
*(xi3+n8) = negate(shl(add(t2,t1),1));
|
||||
move16();
|
||||
*(xi4+n8) = shl(sub(t1,t2),1);
|
||||
move16();
|
||||
}
|
||||
xi1 += id;
|
||||
move16();
|
||||
xi2 += id;
|
||||
move16();
|
||||
xi3 += id;
|
||||
move16();
|
||||
xi4 += id;
|
||||
move16();
|
||||
}
|
||||
is = sub(shl(id,1),n2);
|
||||
id = shl(id,2);
|
||||
}
|
||||
/*Can be acheived with a shr */
|
||||
step = N_MAX_SAS/n2;
|
||||
move16();
|
||||
|
||||
s = sincos_t_fx + step;
|
||||
move16();
|
||||
c = s + 64;
|
||||
move16();
|
||||
s3 = sincos_t_fx + i_mult2(step,3);
|
||||
move16();
|
||||
c3 = s3 + 64;
|
||||
move16();
|
||||
FOR (j=2; j<=n8; j++)
|
||||
{
|
||||
cc1 = *c ;
|
||||
move16();
|
||||
ss1 = *s;
|
||||
move16();
|
||||
cc3 = *c3;
|
||||
move16();
|
||||
ss3 = *s3;
|
||||
move16();
|
||||
|
||||
is = 0;
|
||||
move16();
|
||||
id = shl(n2,1);
|
||||
|
||||
c += step;
|
||||
move16();
|
||||
s += step;
|
||||
move16();
|
||||
|
||||
c3 += 3*step;
|
||||
move16();
|
||||
s3 += 3*step;
|
||||
move16();
|
||||
WHILE (sub(is,sub(n,1)) < 0)
|
||||
{
|
||||
xup1 = x + j + is;
|
||||
move16();
|
||||
xup3 = xup1 + shl(n4,1);
|
||||
move16();
|
||||
xdn6 = xup3 - shl(j,1) +2;
|
||||
move16();
|
||||
|
||||
xdn8 = xdn6 + shl(n4,1);
|
||||
move16();
|
||||
|
||||
FOR (i=is; i<n; i+=id)
|
||||
{
|
||||
t1 = sub(*xup1,*xdn6);
|
||||
*xup1 = add(*xup1,*xdn6);
|
||||
move16();
|
||||
xup1 += n4;
|
||||
move16();
|
||||
xdn6 -= n4;
|
||||
move16();
|
||||
|
||||
t2 = sub(*xdn6,*xup1);
|
||||
*xdn6 = add(*xup1,*xdn6);
|
||||
move16();
|
||||
|
||||
xdn6 += n4;
|
||||
move16();
|
||||
t3 = add(*xdn8,*xup3);
|
||||
*xdn6 = sub(*xdn8,*xup3);
|
||||
move16();
|
||||
|
||||
xup3 += n4;
|
||||
move16();
|
||||
xdn8 -= n4;
|
||||
move16();
|
||||
|
||||
t4 = add(*xup3,*xdn8);
|
||||
*xup1= sub(*xup3,*xdn8);
|
||||
move16();
|
||||
|
||||
t5 = sub(t1,t4);
|
||||
t1 = add(t1,t4);
|
||||
t4 = sub(t2,t3);
|
||||
t2 = add(t2,t3);
|
||||
*xup3 = sub(mult_r(t1,cc3),mult_r(t2,ss3));
|
||||
move16();
|
||||
xup3 -= n4;
|
||||
move16();
|
||||
*xup3 = add(mult_r(t5,cc1),mult_r(t4,ss1));
|
||||
move16();
|
||||
*xdn8 = sub(mult_r(t5,ss1),mult_r(t4,cc1));
|
||||
move16();
|
||||
|
||||
xdn8 += n4;
|
||||
move16();
|
||||
*xdn8 = add(mult_r(t2,cc3),mult_r(t1,ss3));
|
||||
move16();
|
||||
|
||||
xup1 -= n4;
|
||||
move16();
|
||||
xup1 += id;
|
||||
move16();
|
||||
xup3 += id;
|
||||
move16();
|
||||
xdn6 += id;
|
||||
move16();
|
||||
xdn8 += id;
|
||||
move16();
|
||||
}
|
||||
is = sub(shl(id,1),n2);
|
||||
id = shl(id,2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------*
|
||||
* Length two butterflies
|
||||
*-----------------------------------------------------------------*/
|
||||
|
||||
is = 1;
|
||||
move16();
|
||||
id = 4;
|
||||
move16();
|
||||
WHILE (is < n)
|
||||
{
|
||||
xi0 = x + is ;
|
||||
move16();
|
||||
xi1 = xi0 + 1;
|
||||
move16();
|
||||
|
||||
FOR (i0=is; i0<=n; i0+=id)
|
||||
{
|
||||
r1 = *xi0;
|
||||
move16();
|
||||
*xi0= add(r1,*xi1);
|
||||
move16();
|
||||
*xi1 = sub(r1,*xi1);
|
||||
move16();
|
||||
xi0 += id;
|
||||
move16();
|
||||
xi1 += id;
|
||||
move16();
|
||||
}
|
||||
is = sub(shl(id,1),1);
|
||||
id = shl(id,2);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------*
|
||||
* Digit reverse counter
|
||||
*-----------------------------------------------------------------*/
|
||||
|
||||
j = 1;
|
||||
move16();
|
||||
FOR (i=1; i<n; i++)
|
||||
{
|
||||
IF (sub(i,j) < 0)
|
||||
{
|
||||
xt = x[j];
|
||||
move16();
|
||||
x[j] = x[i];
|
||||
move16();
|
||||
x[i] = xt;
|
||||
move16();
|
||||
}
|
||||
k = shr(n, 1);
|
||||
WHILE (sub(k,j) < 0)
|
||||
{
|
||||
j = sub(j,k);
|
||||
k =shr(k, 1);
|
||||
}
|
||||
j = add(j,k);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------*
|
||||
* Normalization
|
||||
*-----------------------------------------------------------------*/
|
||||
|
||||
tmp = div_s(1,n); /*Q15 */
|
||||
FOR (i=1; i<=n; i++)
|
||||
{
|
||||
x[i] = mult_r(x[i],tmp);
|
||||
move16();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
236
src/libs/libevs/lib_com/fill_spectrum.cpp
Normal file
236
src/libs/libevs/lib_com/fill_spectrum.cpp
Normal file
@@ -0,0 +1,236 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.443 Nov 13, 2018. Version 12.11.0 / 13.7.0 / 14.3.0 / 15.1.0
|
||||
====================================================================================*/
|
||||
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include "options.h"
|
||||
#include "cnst.h"
|
||||
#include "rom_com.h"
|
||||
#include "prot.h"
|
||||
|
||||
/*--------------------------------------------------------------------------*
|
||||
* fill_spectrum()
|
||||
*
|
||||
* Apply spectral filling by
|
||||
* - filling zero-bit bands below BWE region
|
||||
* - applying BWE above transition frequency
|
||||
*--------------------------------------------------------------------------*/
|
||||
|
||||
void fill_spectrum(
|
||||
float *coeff, /* i/o: normalized MLT spectrum / nf spectrum */
|
||||
short *R, /* i : number of pulses per band */
|
||||
const short is_transient, /* i : transient flag */
|
||||
short norm[], /* i : quantization indices for norms */
|
||||
const float *hq_generic_fenv, /* i : HQ GENERIC envelope */
|
||||
const short hq_generic_offset, /* i : HQ GENERIC offset */
|
||||
const short nf_idx, /* i : noise fill index */
|
||||
const short length, /* i : Length of spectrum (32 or 48 kHz) */
|
||||
const float env_stab, /* i : Envelope stability measure [0..1] */
|
||||
short *no_att_hangover, /* i/o: Frame counter for attenuation hangover */
|
||||
float *energy_lt, /* i/o: Long-term energy measure for transient detection */
|
||||
short *bwe_seed, /* i/o: random seed for generating BWE input */
|
||||
const short hq_generic_exc_clas, /* i : HQ generic hf excitation class */
|
||||
const short core_sfm, /* i : index of the end band for core */
|
||||
short HQ_mode, /* i : HQ mode */
|
||||
float noise_level[], /* i : noise levels for harmonic modes */
|
||||
long core_brate, /* i : target bit-rate */
|
||||
float prev_noise_level[], /* i/o: noise factor in previous frame */
|
||||
short *prev_R, /* i/o: bit allocation info. in previous frame */
|
||||
float *prev_coeff_out, /* i/o: decoded spectrum in previous frame */
|
||||
const short *peak_idx, /* i : HVQ peak indices */
|
||||
const short Npeaks, /* i : Number of HVQ peaks */
|
||||
const short *npulses, /* i : Number of assigned pulses per band */
|
||||
short prev_is_transient, /* i : previous transient flag */
|
||||
float *prev_normq, /* i : previous norms */
|
||||
float *prev_env, /* i : previous noise envelopes */
|
||||
short prev_bfi, /* i : previous bad frame indicator */
|
||||
const short *sfmsize, /* i : Length of bands */
|
||||
const short *sfm_start, /* i : Start of bands */
|
||||
const short *sfm_end, /* i : End of bands */
|
||||
short *prev_L_swb_norm, /* i/o: last normalize length for harmonic mode */
|
||||
short prev_hq_mode, /* i : previous HQ mode */
|
||||
const short num_sfm, /* i : Number of bands */
|
||||
const short num_env_bands /* i : Number of envelope bands */
|
||||
)
|
||||
{
|
||||
float CodeBook[FREQ_LENGTH];
|
||||
short cb_size = 0;
|
||||
short last_sfm;
|
||||
float CodeBook_mod[FREQ_LENGTH];
|
||||
float norm_adj[NB_SFM];
|
||||
short high_sfm = 23;
|
||||
short flag_32K_env_hangover;
|
||||
short bin_th = 0;
|
||||
short peak_pos[L_HARMONIC_EXC];
|
||||
short bwe_peaks[L_FRAME48k];
|
||||
float normq_v[NB_SFM];
|
||||
float coeff_fine[L_FRAME48k];
|
||||
float coeff_out[L_FRAME48k];
|
||||
|
||||
set_s( peak_pos, 0, L_HARMONIC_EXC );
|
||||
set_s( bwe_peaks, 0, L_FRAME48k );
|
||||
set_f( norm_adj, 1.0f, num_sfm );
|
||||
set_f( coeff_out, 0.0f, L_FRAME48k );
|
||||
|
||||
if ( HQ_mode == HQ_TRANSIENT )
|
||||
{
|
||||
last_sfm = num_sfm-1;
|
||||
}
|
||||
else if (HQ_mode == HQ_GEN_SWB || HQ_mode == HQ_GEN_FB)
|
||||
{
|
||||
last_sfm = max(core_sfm,num_env_bands-1);
|
||||
}
|
||||
else
|
||||
{
|
||||
last_sfm = core_sfm;
|
||||
}
|
||||
|
||||
if ( HQ_mode == HQ_HARMONIC )
|
||||
{
|
||||
high_sfm = (core_brate == HQ_24k40) ? HVQ_THRES_SFM_24k-1 : HVQ_THRES_SFM_32k-1;
|
||||
if( last_sfm < high_sfm )
|
||||
{
|
||||
last_sfm = high_sfm;
|
||||
}
|
||||
}
|
||||
else if ( HQ_mode == HQ_HVQ )
|
||||
{
|
||||
bin_th = sfm_end[last_sfm];
|
||||
}
|
||||
|
||||
/* Transient analysis for envelope stability measure */
|
||||
if( length == L_FRAME32k )
|
||||
{
|
||||
env_stab_transient_detect( is_transient, length, norm, no_att_hangover, energy_lt, HQ_mode, bin_th, coeff );
|
||||
}
|
||||
|
||||
if ( length == L_FRAME16k || ((length == L_FRAME32k && HQ_mode != HQ_HARMONIC && HQ_mode != HQ_HVQ) && *no_att_hangover == 0) )
|
||||
{
|
||||
/* Norm adjustment function */
|
||||
env_adj( npulses, length, last_sfm, norm_adj, env_stab, sfmsize );
|
||||
}
|
||||
|
||||
flag_32K_env_hangover = ( length == L_FRAME32k && ( (env_stab < 0.5f && *no_att_hangover == 0) || HQ_mode == HQ_HVQ ) );
|
||||
|
||||
/*----------------------------------------------------------------*
|
||||
* Build noise-fill codebook
|
||||
*----------------------------------------------------------------*/
|
||||
|
||||
if ( HQ_mode != HQ_HVQ )
|
||||
{
|
||||
cb_size = build_nf_codebook( flag_32K_env_hangover, coeff, sfm_start, sfmsize, sfm_end, last_sfm, R, CodeBook, CodeBook_mod );
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------*
|
||||
* Prepare fine structure for Harmonic and HVQ
|
||||
*----------------------------------------------------------------*/
|
||||
|
||||
if ( HQ_mode == HQ_HARMONIC )
|
||||
{
|
||||
harm_bwe_fine( R, last_sfm, high_sfm, num_sfm, norm, sfm_start, sfm_end, prev_L_swb_norm, coeff, coeff_out, coeff_fine );
|
||||
}
|
||||
else if ( HQ_mode == HQ_HVQ )
|
||||
{
|
||||
hvq_bwe_fine( last_sfm, num_sfm, sfm_end, peak_idx, Npeaks, peak_pos, prev_L_swb_norm, coeff, bwe_peaks, coeff_fine );
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------*
|
||||
* Apply noise-fill
|
||||
*----------------------------------------------------------------*/
|
||||
|
||||
if( HQ_mode != HQ_HVQ && cb_size > 0 )
|
||||
{
|
||||
apply_noisefill_HQ( R, length, flag_32K_env_hangover, core_brate, last_sfm, CodeBook, CodeBook_mod, cb_size, sfm_start, sfm_end, sfmsize, coeff );
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------*
|
||||
* Normal mode BWE
|
||||
*----------------------------------------------------------------*/
|
||||
|
||||
if ( HQ_mode == HQ_NORMAL )
|
||||
{
|
||||
hq_fold_bwe( last_sfm, sfm_end, num_sfm, coeff );
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------*
|
||||
* Apply noise-fill adjustment
|
||||
*----------------------------------------------------------------*/
|
||||
|
||||
if( (length >= L_FRAME32k || core_brate > HQ_32k || core_brate < HQ_24k40) && HQ_mode != HQ_HVQ )
|
||||
{
|
||||
apply_nf_gain( nf_idx, last_sfm, R, sfm_start, sfm_end, coeff );
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------*
|
||||
* Prepare fine strucutre for HQ GENERIC
|
||||
*----------------------------------------------------------------*/
|
||||
if ( HQ_mode == HQ_GEN_SWB || HQ_mode == HQ_GEN_FB )
|
||||
{
|
||||
hq_generic_fine( coeff, last_sfm, sfm_start, sfm_end, bwe_seed, coeff_fine );
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------*
|
||||
* Apply envelope
|
||||
*----------------------------------------------------------------*/
|
||||
|
||||
if ( HQ_mode != HQ_HARMONIC && HQ_mode != HQ_HVQ )
|
||||
{
|
||||
apply_envelope( coeff, norm, norm_adj, num_sfm, last_sfm, HQ_mode, length, sfm_start, sfm_end, normq_v, coeff_out, coeff_fine );
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------*
|
||||
* Harmonic BWE, HVQ BWE and HQ SWB BWE
|
||||
*----------------------------------------------------------------*/
|
||||
|
||||
if( HQ_mode == HQ_HARMONIC )
|
||||
{
|
||||
harm_bwe( coeff_fine, coeff, num_sfm, sfm_start, sfm_end, last_sfm, high_sfm, R, prev_hq_mode, norm, noise_level, prev_noise_level, bwe_seed, coeff_out );
|
||||
}
|
||||
else if ( HQ_mode == HQ_HVQ )
|
||||
{
|
||||
hvq_bwe( coeff, coeff_fine, sfm_start, sfm_end, sfmsize, last_sfm,
|
||||
prev_hq_mode, bwe_peaks, bin_th, num_sfm, core_brate, R, norm,
|
||||
noise_level, prev_noise_level, bwe_seed, coeff_out );
|
||||
}
|
||||
else if ( HQ_mode == HQ_GEN_SWB || HQ_mode == HQ_GEN_FB )
|
||||
{
|
||||
hq_generic_bwe( HQ_mode, coeff_fine, hq_generic_fenv, coeff_out, hq_generic_offset, prev_L_swb_norm,
|
||||
hq_generic_exc_clas, sfm_end, num_sfm, num_env_bands, R );
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------*
|
||||
* HQ WB BWE refinements
|
||||
*----------------------------------------------------------------*/
|
||||
|
||||
if( length == L_FRAME16k && core_brate == HQ_32k )
|
||||
{
|
||||
hq_wb_nf_bwe( coeff, is_transient, prev_bfi, normq_v, num_sfm, sfm_start, sfm_end, sfmsize, last_sfm, R,
|
||||
prev_is_transient, prev_normq, prev_env, bwe_seed, prev_coeff_out, prev_R, coeff_out );
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------*
|
||||
* Update memories
|
||||
*----------------------------------------------------------------*/
|
||||
|
||||
if ( HQ_mode != HQ_HARMONIC && HQ_mode != HQ_HVQ )
|
||||
{
|
||||
prev_noise_level[0] = 0.1f;
|
||||
prev_noise_level[1] = 0.1f;
|
||||
}
|
||||
if ( !(length == L_FRAME16k && core_brate == HQ_32k ) )
|
||||
{
|
||||
set_f( prev_env, 0, SFM_N_WB );
|
||||
set_f( prev_normq, 0, SFM_N_WB );
|
||||
}
|
||||
|
||||
if ( length == L_FRAME32k && core_brate <= HQ_32k )
|
||||
{
|
||||
*prev_R = R[SFM_N_WB-1];
|
||||
mvr2r( coeff_out + L_FRAME16k - L_HQ_WB_BWE, prev_coeff_out, L_HQ_WB_BWE );
|
||||
}
|
||||
|
||||
mvr2r( coeff_out, coeff, L_FRAME48k );
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -1,278 +0,0 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "options.h" /* Compilation switches */
|
||||
#include "cnst_fx.h" /* Common constants */
|
||||
#include "prot_fx.h" /* Function prototypes */
|
||||
#include "stl.h" /* required for wmc_tool */
|
||||
|
||||
/*--------------------------------------------------------------------------*
|
||||
* fill_spectrum()
|
||||
*
|
||||
* Apply spectral filling by
|
||||
* - filling zero-bit bands below BWE region
|
||||
* - applying BWE above transition frequency
|
||||
*--------------------------------------------------------------------------*/
|
||||
|
||||
void fill_spectrum_fx(
|
||||
Word16 *coeff, /* i/o: normalized MLT spectrum / nf spectrum Q12 */
|
||||
Word32 *L_coeff_out, /* i/o: Noisefilled MLT spectrum Q12 */
|
||||
const Word16 *R, /* i : number of pulses per band Q0 */
|
||||
const Word16 is_transient, /* i : transient flag Q0 */
|
||||
Word16 norm[], /* i : quantization indices for norms Q0 */
|
||||
const Word16 *hq_generic_fenv, /* i : HQ GENERIC envelope Q1 */
|
||||
const Word16 hq_generic_offset, /* i : HQ GENERIC offset Q0 */
|
||||
const Word16 nf_idx, /* i : noise fill index Q0 */
|
||||
const Word16 length, /* i : Length of spectrum (32 or 48 kHz) Q0 */
|
||||
const Word16 env_stab, /* i : Envelope stability measure [0..1] Q15 */
|
||||
Word16 *no_att_hangover, /* i/o: Frame counter for attenuation hangover Q0 */
|
||||
Word32 *L_energy_lt, /* i/o: Long-term energy measure for transient detection Q13 */
|
||||
Word16 *bwe_seed, /* i/o: random seed for generating BWE input Q0 */
|
||||
const Word16 hq_generic_exc_clas, /* i : BWE excitation class Q0 */
|
||||
const Word16 core_sfm, /* i : index of the end band for core Q0 */
|
||||
const Word16 HQ_mode, /* i : HQ mode Q0 */
|
||||
Word16 noise_level[], /* i : noise levels for harmonic modes Q15 */
|
||||
const Word32 L_core_brate, /* i : target bit-rate Q0 */
|
||||
Word16 prev_noise_level[], /* i/o: noise factor in previous frame Q15 */
|
||||
Word16 *prev_R, /* i/o: bit allocation info. in previous frame Q0 */
|
||||
Word32 *prev_coeff_out, /* i/o: decoded spectrum in previous frame Q12 */
|
||||
const Word16 *peak_idx, /* i : peak indices for hvq Q0 */
|
||||
const Word16 Npeaks, /* i : number of peaks in hvq Q0 */
|
||||
const Word16 *npulses, /* i : number of pulses per band Q0 */
|
||||
const Word16 prev_is_transient, /* i : previous transient flag Q0 */
|
||||
Word32 *prev_normq, /* i/o: previous norms Q14 */
|
||||
Word32 *prev_env, /* i/o: previous noise envelopes Q(prev_env_Q) */
|
||||
const Word16 prev_bfi, /* i : previous bad frame indicator Q0 */
|
||||
const Word16 *sfmsize, /* i : Length of bands Q0 */
|
||||
const Word16 *sfm_start, /* i : Start of bands Q0 */
|
||||
const Word16 *sfm_end, /* i : End of bands Q0 */
|
||||
Word16 *prev_L_swb_norm, /* i/o: HVQ/Harmonic mode normalization length Q0 */
|
||||
const Word16 prev_hq_mode, /* i : Previous HQ mode Q0 */
|
||||
const Word16 num_sfm /* i : Total number of bands Q0 */
|
||||
,Word16 *prev_env_Q
|
||||
,const Word16 num_env_bands /* i : Number sub bands to be encoded for HQ_GEN Q0 */
|
||||
)
|
||||
{
|
||||
Word16 CodeBook[FREQ_LENGTH]; /* Q12 */
|
||||
Word16 cb_size;
|
||||
Word16 last_sfm;
|
||||
Word16 CodeBook_mod[FREQ_LENGTH]; /*Q12 */
|
||||
Word16 norm_adj[NB_SFM]; /*Q15 */
|
||||
Word16 high_sfm;
|
||||
Word16 flag_32K_env_hangover;
|
||||
Word16 bin_th;
|
||||
Word16 peak_pos[L_HARMONIC_EXC];
|
||||
Word16 bwe_peaks[L_FRAME48k];
|
||||
Word32 L_normq_v[NB_SFM]; /*Q14 */
|
||||
Word16 coeff_fine[L_FRAME48k]; /*Q15 */
|
||||
Word32 L_coeff_out1[L_FRAME48k]; /*Q12 */
|
||||
|
||||
set16_fx( peak_pos, 0, L_HARMONIC_EXC );
|
||||
set16_fx( bwe_peaks, 0, L_FRAME48k );
|
||||
set16_fx(norm_adj, 32767, num_sfm); /* 1.0, Q15 */
|
||||
cb_size = 0;
|
||||
move16();
|
||||
bin_th = 0;
|
||||
move16();
|
||||
high_sfm = 23;
|
||||
move16();
|
||||
|
||||
test();
|
||||
IF ( sub(HQ_mode, HQ_TRANSIENT) == 0 )
|
||||
{
|
||||
last_sfm = sub(num_sfm, 1);
|
||||
}
|
||||
ELSE IF ( sub(HQ_mode,HQ_GEN_SWB) == 0 || sub(HQ_mode,HQ_GEN_FB) == 0 )
|
||||
{
|
||||
last_sfm = s_max(core_sfm,sub(num_env_bands,1));
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
last_sfm = core_sfm;
|
||||
move16();
|
||||
}
|
||||
|
||||
IF ( sub(HQ_mode, HQ_HARMONIC) == 0 )
|
||||
{
|
||||
/*high_sfm = (core_brate == HQ_24k40) ? HVQ_THRES_SFM_24k-1 : HVQ_THRES_SFM_32k-3; */
|
||||
high_sfm = sub(HVQ_THRES_SFM_32k, 1);
|
||||
if (L_sub(L_core_brate, HQ_24k40) == 0)
|
||||
{
|
||||
high_sfm = sub(HVQ_THRES_SFM_24k, 1);
|
||||
}
|
||||
|
||||
if( sub(last_sfm, high_sfm) < 0 )
|
||||
{
|
||||
last_sfm = high_sfm;
|
||||
move16();
|
||||
}
|
||||
}
|
||||
ELSE if ( sub(HQ_mode, HQ_HVQ) == 0 )
|
||||
{
|
||||
bin_th = sfm_end[last_sfm];
|
||||
move16();
|
||||
}
|
||||
|
||||
/* Transient analysis for envelope stability measure */
|
||||
IF ( sub(length, L_FRAME32k) == 0 )
|
||||
{
|
||||
env_stab_transient_detect_fx( is_transient, length, norm, no_att_hangover, L_energy_lt, HQ_mode, bin_th, L_coeff_out, 12 );
|
||||
}
|
||||
|
||||
test();
|
||||
test();
|
||||
test();
|
||||
test();
|
||||
IF ( sub(length, L_FRAME16k) == 0 ||
|
||||
((sub(length, L_FRAME32k) == 0 && sub(HQ_mode, HQ_HARMONIC) != 0 && sub(HQ_mode, HQ_HVQ) != 0) && *no_att_hangover == 0) )
|
||||
{
|
||||
/* Norm adjustment function */
|
||||
env_adj_fx( npulses, length, last_sfm, norm_adj, env_stab, sfmsize );
|
||||
}
|
||||
|
||||
/*flag_32K_env_hangover = ( length == L_FRAME32k && ( (env_stab < 0.5f && *no_att_hangover == 0) || HQ_mode == HQ_HVQ ) ); */
|
||||
flag_32K_env_hangover = 0;
|
||||
move16();
|
||||
test();
|
||||
test();
|
||||
test();
|
||||
if ( sub(length, L_FRAME32k) == 0 && ( (sub(env_stab, 16384) < 0 && *no_att_hangover == 0) || sub(HQ_mode, HQ_HVQ) == 0 ) )
|
||||
{
|
||||
flag_32K_env_hangover = 1;
|
||||
move16();
|
||||
}
|
||||
|
||||
|
||||
/*----------------------------------------------------------------*
|
||||
* Build noise-fill codebook
|
||||
*----------------------------------------------------------------*/
|
||||
|
||||
IF ( sub(HQ_mode, HQ_HVQ) != 0 )
|
||||
{
|
||||
cb_size = build_nf_codebook_fx(flag_32K_env_hangover, coeff, sfm_start, sfmsize, sfm_end, last_sfm, R, CodeBook, CodeBook_mod);
|
||||
}
|
||||
/*----------------------------------------------------------------*
|
||||
* Prepare fine structure for Harmonic and HVQ
|
||||
*----------------------------------------------------------------*/
|
||||
|
||||
IF ( sub(HQ_mode, HQ_HARMONIC) == 0 )
|
||||
{
|
||||
harm_bwe_fine_fx( R, last_sfm, high_sfm, num_sfm, norm, sfm_start, sfm_end, prev_L_swb_norm, coeff, L_coeff_out, coeff_fine );
|
||||
}
|
||||
ELSE IF ( sub(HQ_mode, HQ_HVQ) == 0 )
|
||||
{
|
||||
hvq_bwe_fine_fx( last_sfm, num_sfm, sfm_end, peak_idx, Npeaks, peak_pos, prev_L_swb_norm, L_coeff_out, bwe_peaks, coeff_fine );
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------*
|
||||
* Apply noise-fill
|
||||
*----------------------------------------------------------------*/
|
||||
|
||||
test();
|
||||
IF ( sub(HQ_mode, HQ_HVQ) != 0 && cb_size > 0 )
|
||||
{
|
||||
apply_noisefill_HQ_fx( R, length, flag_32K_env_hangover, L_core_brate, last_sfm, CodeBook,
|
||||
CodeBook_mod, cb_size, sfm_start, sfm_end, sfmsize, coeff );
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------*
|
||||
* Normal mode BWE
|
||||
*----------------------------------------------------------------*/
|
||||
|
||||
IF ( HQ_mode == HQ_NORMAL )
|
||||
{
|
||||
hq_fold_bwe_fx(last_sfm, sfm_end, num_sfm, coeff);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------*
|
||||
* Apply noise-fill adjustment
|
||||
*----------------------------------------------------------------*/
|
||||
|
||||
test();
|
||||
test();
|
||||
test();
|
||||
IF( (sub(length, L_FRAME32k) >= 0 || L_sub(L_core_brate, HQ_32k) > 0 || L_sub(L_core_brate, HQ_24k40) < 0)
|
||||
&& sub(HQ_mode, HQ_HVQ) != 0 )
|
||||
{
|
||||
apply_nf_gain_fx(nf_idx, last_sfm, R, sfm_start, sfm_end, coeff);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------*
|
||||
* Prepare fine strucutre for HQ GENERIC
|
||||
*----------------------------------------------------------------*/
|
||||
test();
|
||||
IF ( sub(HQ_mode, HQ_GEN_SWB) == 0 || sub(HQ_mode, HQ_GEN_FB) == 0 )
|
||||
{
|
||||
hq_generic_fine_fx( coeff, last_sfm, sfm_start, sfm_end, bwe_seed, coeff_fine );
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------*
|
||||
* Apply envelope
|
||||
*----------------------------------------------------------------*/
|
||||
|
||||
test();
|
||||
IF ( sub(HQ_mode, HQ_HARMONIC) != 0 && sub(HQ_mode, HQ_HVQ) != 0 )
|
||||
{
|
||||
apply_envelope_fx( coeff, norm, norm_adj, num_sfm, last_sfm, HQ_mode, length, sfm_start, sfm_end,
|
||||
L_normq_v, L_coeff_out, coeff_fine, L_coeff_out1 );
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------*
|
||||
* Harmonic BWE, HVQ BWE and HQ SWB BWE
|
||||
*----------------------------------------------------------------*/
|
||||
test();
|
||||
IF ( sub(HQ_mode, HQ_HARMONIC) == 0 )
|
||||
{
|
||||
harm_bwe_fx( coeff_fine, coeff, num_sfm, sfm_start, sfm_end, last_sfm, R, prev_hq_mode, norm, noise_level, prev_noise_level, bwe_seed, L_coeff_out );
|
||||
}
|
||||
ELSE IF ( sub(HQ_mode, HQ_HVQ) == 0 )
|
||||
{
|
||||
hvq_bwe_fx( L_coeff_out, coeff_fine, sfm_start, sfm_end, sfmsize, last_sfm,
|
||||
prev_hq_mode, bwe_peaks, bin_th, num_sfm, L_core_brate, R, norm,
|
||||
noise_level, prev_noise_level, bwe_seed, L_coeff_out, 15, 12 );
|
||||
}
|
||||
ELSE IF ( sub(HQ_mode, HQ_GEN_SWB) == 0 || sub(HQ_mode, HQ_GEN_FB) == 0 )
|
||||
{
|
||||
hq_bwe_fx( HQ_mode, L_coeff_out1, hq_generic_fenv, L_coeff_out, hq_generic_offset, prev_L_swb_norm, hq_generic_exc_clas, sfm_end, num_sfm, num_env_bands, R );
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------*
|
||||
* HQ WB BWE refinements
|
||||
*----------------------------------------------------------------*/
|
||||
test();
|
||||
IF ( sub(length, L_FRAME16k) == 0 && L_sub(L_core_brate, HQ_32k) == 0 )
|
||||
{
|
||||
hq_wb_nf_bwe_fx( coeff, is_transient, prev_bfi, L_normq_v, num_sfm, sfm_start, sfm_end, sfmsize, last_sfm, R,
|
||||
prev_is_transient, prev_normq, prev_env, bwe_seed, prev_coeff_out, prev_R, L_coeff_out, prev_env_Q );
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------*
|
||||
* Update memories
|
||||
*----------------------------------------------------------------*/
|
||||
|
||||
test();
|
||||
IF ( sub(HQ_mode, HQ_HARMONIC) != 0 && sub(HQ_mode, HQ_HVQ) != 0 )
|
||||
{
|
||||
prev_noise_level[0] = 3277;
|
||||
move16();/* 0.1 in Q15 */
|
||||
prev_noise_level[1] = 3277;
|
||||
move16();/* 0.1 in Q15 */
|
||||
}
|
||||
test();
|
||||
IF ( !(sub(length, L_FRAME16k) == 0 && L_sub(L_core_brate, HQ_32k) == 0) )
|
||||
{
|
||||
set32_fx( prev_env, 0, SFM_N_WB );
|
||||
set32_fx( prev_normq, 0, SFM_N_WB );
|
||||
}
|
||||
|
||||
test();
|
||||
IF ( sub(length, L_FRAME32k) == 0 && L_sub(L_core_brate, HQ_32k) <= 0 )
|
||||
{
|
||||
*prev_R = R[SFM_N_WB-1];
|
||||
Copy32( L_coeff_out + L_FRAME16k - L_HQ_WB_BWE, prev_coeff_out, L_HQ_WB_BWE );
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
106
src/libs/libevs/lib_com/findpulse.cpp
Normal file
106
src/libs/libevs/lib_com/findpulse.cpp
Normal file
@@ -0,0 +1,106 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.443 Nov 13, 2018. Version 12.11.0 / 13.7.0 / 14.3.0 / 15.1.0
|
||||
====================================================================================*/
|
||||
|
||||
#include <math.h>
|
||||
#include "options.h"
|
||||
#include "prot.h"
|
||||
#include "cnst.h"
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------------*
|
||||
* findpulse()
|
||||
*
|
||||
* Find first pitch pulse in a frame
|
||||
*----------------------------------------------------------------------------------*/
|
||||
|
||||
short findpulse( /* o : pulse position */
|
||||
const short L_frame, /* i : length of the frame */
|
||||
const float res[], /* i : residual signal */
|
||||
const short T0, /* i : integer pitch */
|
||||
const short enc_dec, /* i : flag enc/dec, 0 - enc, 1 - dec */
|
||||
short *sign /* i/o: sign of the maximum */
|
||||
)
|
||||
{
|
||||
const float *ptr;
|
||||
float val, maxval;
|
||||
short i, maxi;
|
||||
float resf[L_FRAME16k]; /* Low pass filtered residual */
|
||||
|
||||
if ( enc_dec == ENC )
|
||||
{
|
||||
/*-----------------------------------------------------------------*
|
||||
* Very simple LP filter
|
||||
*-----------------------------------------------------------------*/
|
||||
|
||||
resf[0] = 0.50f * res[0] + 0.25f * res[1];
|
||||
for (i=1; i<L_frame-1; i++)
|
||||
{
|
||||
resf[i] = 0.25f * res[i-1] + 0.5f * res[i] + 0.25f * res[i+1];
|
||||
}
|
||||
resf[L_frame-1] = 0.25f * res[L_frame-2] + 0.50f * res[L_frame-1];
|
||||
|
||||
/*-----------------------------------------------------------------*
|
||||
* Find "biggest" pulse in the last pitch section
|
||||
*-----------------------------------------------------------------*/
|
||||
|
||||
ptr = resf + L_frame - 1;
|
||||
maxval = 0;
|
||||
maxi = 0;
|
||||
for (i=0; i<T0; i++)
|
||||
{
|
||||
val = (float)fabs(*ptr);
|
||||
if (val>maxval)
|
||||
{
|
||||
maxval = val;
|
||||
maxi = i;
|
||||
if(*ptr >= 0)
|
||||
{
|
||||
*sign = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
*sign = 1;
|
||||
}
|
||||
}
|
||||
ptr--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*-----------------------------------------------------------------*
|
||||
* Find "biggest" pulse in the last pitch section according to the sign
|
||||
*-----------------------------------------------------------------*/
|
||||
|
||||
ptr = res;
|
||||
maxval = 0;
|
||||
maxi = 0;
|
||||
|
||||
if( *sign == 0 )
|
||||
{
|
||||
for (i=1; i<=T0; i++)
|
||||
{
|
||||
val = *ptr++;
|
||||
if ( val >= maxval )
|
||||
{
|
||||
maxval = val;
|
||||
maxi = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i=1; i<=T0; i++)
|
||||
{
|
||||
val = *ptr++;
|
||||
if (val<=maxval)
|
||||
{
|
||||
maxval = val;
|
||||
maxi = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return(maxi);
|
||||
}
|
||||
@@ -1,117 +0,0 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#include "options.h" /* Compilation switches */
|
||||
#include "cnst_fx.h" /* Common constants */
|
||||
#include "prot_fx.h" /* Function prototypes */
|
||||
#include "stl.h"
|
||||
|
||||
/*----------------------------------------------------------------------------------*
|
||||
* findpulse()
|
||||
*
|
||||
* Find first pitch pulse in a frame
|
||||
*----------------------------------------------------------------------------------*/
|
||||
Word16 findpulse_fx( /* o : pulse position */
|
||||
const Word16 L_frame, /* i : length of the frame */
|
||||
const Word16 res[], /* i : Residual signal <12 bits */
|
||||
const Word16 T0, /* i : Pitch estimation Q0 */
|
||||
const Word16 enc, /* i : enc = 1 -> encoder side; enc = 0 -> decoder side */
|
||||
Word16 *sign /* i/o: sign of the maximum */
|
||||
)
|
||||
{
|
||||
const Word16 *ptr;
|
||||
Word16 maxval;
|
||||
Word16 i, maxi;
|
||||
Word32 Ltmp;
|
||||
Word16 resf[L_FRAME16k]; /* Low pass filtered residual */
|
||||
|
||||
IF (enc != DEC)
|
||||
{
|
||||
/*------------------------------------------------------------------------*
|
||||
* 1. Very simple LP filter
|
||||
*------------------------------------------------------------------------*/
|
||||
|
||||
/* resf[0] = 0.50f * res[0] + 0.25f * res[1] */
|
||||
Ltmp = L_mult(res[0], 16384);
|
||||
resf[0] = mac_r(Ltmp, res[1], 8192);
|
||||
move16();
|
||||
FOR (i=1; i<L_frame-1; i++)
|
||||
{
|
||||
/* resf[i] = 0.25f * res[i-1] + 0.5f * res[i] + 0.25f * res[i+1] */
|
||||
Ltmp = L_mult(8192, res[i-1]);
|
||||
Ltmp = L_mac(Ltmp, 16384, res[i]);
|
||||
resf[i] = mac_r(Ltmp, 8192, res[i+1]);
|
||||
move16();
|
||||
}
|
||||
|
||||
/* resf[L_frame-1] = 0.25f * res[L_frame-2] + 0.50f * res[L_frame-1] */
|
||||
Ltmp = L_mult(res[L_frame-2], 8192);
|
||||
resf[L_frame-1] = mac_r(Ltmp, 16384, res[L_frame-1]);
|
||||
move16();
|
||||
|
||||
/*------------------------------------------------------------------------*
|
||||
* 2. Find "biggest" pitch pulse
|
||||
*------------------------------------------------------------------------*/
|
||||
|
||||
ptr = resf + L_frame - 1;
|
||||
move16();
|
||||
maxi = 0;
|
||||
move16();
|
||||
|
||||
FOR (i = 1; i < T0; i++)
|
||||
{
|
||||
Ltmp = L_mult0(ptr[-maxi], ptr[-maxi]);
|
||||
if (L_msu0(Ltmp, ptr[-i], ptr[-i]) < 0)
|
||||
{
|
||||
maxi = i;
|
||||
move16();
|
||||
}
|
||||
}
|
||||
/*
|
||||
*sign = 1; move16();
|
||||
test();
|
||||
if (ptr[-maxi] >= 0)
|
||||
{
|
||||
*sign = 0; move16();
|
||||
}*/
|
||||
*sign = negate(shr(ptr[-maxi], 15));
|
||||
move16();
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
/*-----------------------------------------------------------------*
|
||||
* 2. Find "biggest" pulse in the last pitch section according to the sign
|
||||
*-----------------------------------------------------------------*/
|
||||
|
||||
maxval = 0;
|
||||
move16();
|
||||
maxi = 0;
|
||||
move16();
|
||||
|
||||
IF (*sign == 0)
|
||||
{
|
||||
FOR (i = 0; i < T0; i++)
|
||||
{
|
||||
if (sub(res[i], maxval) >= 0)
|
||||
{
|
||||
maxi = add(i, 1);
|
||||
}
|
||||
maxval = s_max(res[i], maxval);
|
||||
}
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
FOR (i = 0; i < T0; i++)
|
||||
{
|
||||
if (sub(res[i], maxval) <= 0)
|
||||
{
|
||||
maxi = add(i, 1);
|
||||
}
|
||||
maxval = s_min(res[i], maxval);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return maxi;
|
||||
}
|
||||
100
src/libs/libevs/lib_com/fine_gain_bits.cpp
Normal file
100
src/libs/libevs/lib_com/fine_gain_bits.cpp
Normal file
@@ -0,0 +1,100 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.443 Nov 13, 2018. Version 12.11.0 / 13.7.0 / 14.3.0 / 15.1.0
|
||||
====================================================================================*/
|
||||
|
||||
#include "options.h"
|
||||
#include "rom_com.h"
|
||||
#include "prot.h"
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
* subband_gain_bits()
|
||||
*
|
||||
* HQ core encoder
|
||||
*--------------------------------------------------------------------------*/
|
||||
|
||||
void subband_gain_bits(
|
||||
const short *Rk, /* i : bit allocation per band (Q3)*/
|
||||
const short N, /* i : number of bands */
|
||||
short *bits, /* o : gain bits per band */
|
||||
const short *sfmsize /* i : Size of bands */
|
||||
)
|
||||
{
|
||||
short i,b,tot;
|
||||
short bps;
|
||||
|
||||
tot = 0;
|
||||
|
||||
for ( i = 0; i < N; i++ )
|
||||
{
|
||||
bps = (short)(((int) Rk[i]*(int)fg_inv_tbl_fx[sfmsize[i]>>3])>>18) ;
|
||||
if (((sfmsize[i]*(bps+1)) << 3) - Rk[i] == 0)
|
||||
{
|
||||
/* correct approx. division result, to obtain exact integer division output */
|
||||
bps++;
|
||||
}
|
||||
bps = min(7, bps);
|
||||
|
||||
|
||||
|
||||
b = fine_gain_bits[bps];
|
||||
|
||||
bits[i] = b;
|
||||
tot += b;
|
||||
}
|
||||
|
||||
if ( tot == 0)
|
||||
{
|
||||
/* If no gain bits were assigned, use one bit anyway for potential PVQ overage */
|
||||
bits[0] = 1;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*
|
||||
* assign_gain_bits()
|
||||
*
|
||||
* Assign gain adjustment bits and update bit budget
|
||||
*--------------------------------------------------------------------------*/
|
||||
|
||||
short assign_gain_bits( /* o : Number of assigned gain bits */
|
||||
const short core, /* i : HQ core */
|
||||
const short BANDS, /* i : Number of bands */
|
||||
const short *band_width, /* i : Sub band bandwidth */
|
||||
short *Rk, /* i/o: Bit allocation/Adjusted bit alloc. (Q3)*/
|
||||
short *gain_bits_array, /* o : Assigned gain bits */
|
||||
short *Rcalc /* o : Bit budget for shape quantizer (Q3)*/
|
||||
)
|
||||
{
|
||||
short subband_cnt;
|
||||
short gain_bits_tot;
|
||||
short i;
|
||||
|
||||
/* Allocate gain bits for every subband used, based on bit rate and bandwidth */
|
||||
if( core == HQ_CORE )
|
||||
{
|
||||
subband_gain_bits(Rk, BANDS, gain_bits_array, band_width);
|
||||
}
|
||||
else
|
||||
{
|
||||
set_s( gain_bits_array, 0, BANDS );
|
||||
}
|
||||
|
||||
/* Re-adjust bit budget for gain quantization */
|
||||
subband_cnt = 0;
|
||||
gain_bits_tot = 0;
|
||||
*Rcalc = 0.0f;
|
||||
for (i = 0; i < BANDS; i++)
|
||||
{
|
||||
if (Rk[i] > 0)
|
||||
{
|
||||
subband_cnt++;
|
||||
Rk[i] -= gain_bits_array[i] * 8;
|
||||
gain_bits_tot += gain_bits_array[i];
|
||||
*Rcalc += Rk[i];
|
||||
}
|
||||
}
|
||||
|
||||
return gain_bits_tot;
|
||||
}
|
||||
@@ -1,107 +0,0 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#include "options.h" /* Compilation switches */
|
||||
#include "rom_com_fx.h" /* Static table prototypes */
|
||||
#include "prot_fx.h" /* Function prototypes */
|
||||
#include "stl.h" /* required for wmc_tool */
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
* subband_gain_bits()
|
||||
*
|
||||
* HQ core encoder
|
||||
*--------------------------------------------------------------------------*/
|
||||
|
||||
void subband_gain_bits_fx(
|
||||
const Word16 *Rk, /* i : bit allocation per band Q3 */
|
||||
const Word16 N, /* i : number of bands */
|
||||
Word16 *bits, /* o : gain bits per band */
|
||||
const Word16 *sfmsize /* i : Size of bands */
|
||||
)
|
||||
{
|
||||
Word16 i,b,tot;
|
||||
Word16 bps;
|
||||
|
||||
tot = 0;
|
||||
move16();
|
||||
|
||||
FOR ( i = 0; i < N; i++ )
|
||||
{
|
||||
/*bps = (short)(Rk[i]*((word16)min(32767, ceil(32767.0f/sfmsize[i]); inexact C-integer division approx. */
|
||||
bps = extract_l(L_shr(L_mult0(Rk[i], inv_tbl_fx[sfmsize[i]]), 18)); /* 3+15 */
|
||||
if (L_sub(L_shl(L_mult0(sfmsize[i], add(bps, 1)), 3), Rk[i]) == 0)
|
||||
{
|
||||
bps = add(bps, 1);
|
||||
}
|
||||
|
||||
bps = s_min(7, bps);
|
||||
b = fine_gain_bits[bps];
|
||||
move16();
|
||||
bits[i] = b;
|
||||
move16();
|
||||
tot = add(tot, b);
|
||||
}
|
||||
|
||||
if ( tot == 0)
|
||||
{
|
||||
/* If no gain bits were assigned, use one bit anyway for potential PVQ overage */
|
||||
bits[0] = 1;
|
||||
move16();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*
|
||||
* assign_gain_bits()
|
||||
*
|
||||
* Assign gain adjustment bits and update bit budget
|
||||
*--------------------------------------------------------------------------*/
|
||||
|
||||
Word16 assign_gain_bits_fx( /* o : Number of assigned gain bits */
|
||||
const Word16 core, /* i : HQ core */
|
||||
const Word16 BANDS, /* i : Number of bands */
|
||||
const Word16 *band_width, /* i : Sub band bandwidth */
|
||||
Word16 *Rk, /* i/o: Bit allocation/Adjusted bit alloc. Q3 */
|
||||
Word16 *gain_bits_array, /* o : Assigned gain bits */
|
||||
Word16 *Rcalc /* o : Bit budget for shape quantizer Q3 */
|
||||
)
|
||||
{
|
||||
Word16 subband_cnt;
|
||||
Word16 gain_bits_tot;
|
||||
Word16 i;
|
||||
|
||||
/* Allocate gain bits for every subband used, based on bit rate and bandwidth */
|
||||
IF( sub(core, HQ_CORE) == 0 )
|
||||
{
|
||||
subband_gain_bits_fx(Rk, BANDS, gain_bits_array, band_width);
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
set16_fx( gain_bits_array, 0, BANDS );
|
||||
}
|
||||
|
||||
/* Re-adjust bit budget for gain quantization */
|
||||
subband_cnt = 0;
|
||||
move16();
|
||||
gain_bits_tot = 0;
|
||||
move16();
|
||||
*Rcalc = 0;
|
||||
move16();
|
||||
FOR (i = 0; i < BANDS; i++)
|
||||
{
|
||||
IF (Rk[i] > 0)
|
||||
{
|
||||
subband_cnt = add(subband_cnt, 1);
|
||||
Rk[i] = sub(Rk[i], shl(gain_bits_array[i], 3));
|
||||
move16();
|
||||
gain_bits_tot = add(gain_bits_tot, gain_bits_array[i]);
|
||||
*Rcalc = add(*Rcalc, Rk[i]);
|
||||
move16();
|
||||
}
|
||||
}
|
||||
|
||||
return gain_bits_tot;
|
||||
}
|
||||
96
src/libs/libevs/lib_com/frame_ener.cpp
Normal file
96
src/libs/libevs/lib_com/frame_ener.cpp
Normal file
@@ -0,0 +1,96 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.443 Nov 13, 2018. Version 12.11.0 / 13.7.0 / 14.3.0 / 15.1.0
|
||||
====================================================================================*/
|
||||
|
||||
#include <math.h>
|
||||
#include "options.h"
|
||||
#include "cnst.h"
|
||||
#include "prot.h"
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------------*
|
||||
* fer_energy()
|
||||
*
|
||||
* Estimation of pitch-synchronous (voiced sounds) or half-frame energy
|
||||
*----------------------------------------------------------------------------------*/
|
||||
|
||||
void fer_energy(
|
||||
const int L_frame, /* i : frame length */
|
||||
const short clas, /* i : frame classification */
|
||||
const float *synth, /* i : synthesized speech at Fs = 12k8 Hz */
|
||||
const float pitch, /* i : pitch period */
|
||||
float *enr, /* o : pitch-synchronous or half_frame energy */
|
||||
const short offset /* i : speech pointer offset (0 or L_frame) */
|
||||
)
|
||||
{
|
||||
short len;
|
||||
const float *pt_synth;
|
||||
|
||||
if( clas == VOICED_CLAS || clas == ONSET || clas == SIN_ONSET ) /* Voiced or Onset current frame */
|
||||
{
|
||||
len = (short)( pitch + 0.5f ); /* pitch value */
|
||||
|
||||
pt_synth = synth;
|
||||
if( offset != 0 )
|
||||
{
|
||||
pt_synth = synth + L_frame - len;
|
||||
}
|
||||
|
||||
emaximum( pt_synth, len, enr ); /* pitch synchronous E */
|
||||
}
|
||||
else
|
||||
{
|
||||
pt_synth = synth;
|
||||
if( offset != 0 )
|
||||
{
|
||||
pt_synth = synth + L_frame/2;
|
||||
}
|
||||
|
||||
*enr = dotp( pt_synth, pt_synth, L_frame/2 );
|
||||
*enr /= (float)(L_frame/2);
|
||||
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------*
|
||||
* frame_energy()
|
||||
*
|
||||
* Compute pitch-synchronous energy at the frame end
|
||||
*------------------------------------------------------------------------*/
|
||||
|
||||
float frame_energy(
|
||||
const short L_frame, /* i: length of the frame */
|
||||
const float *pitch, /* i: pitch values for each subframe */
|
||||
const float *speech, /* i: pointer to speech signal for E computation */
|
||||
const float lp_speech, /* i: long-term active speech energy average */
|
||||
float *frame_ener /* o: pitch-synchronous energy at frame end */
|
||||
)
|
||||
{
|
||||
float enern;
|
||||
const float *pt1;
|
||||
short len;
|
||||
float dotProd;
|
||||
|
||||
len = (short)( 0.5f * (pitch[2] + pitch[3]) + 0.5f );
|
||||
if( len < L_SUBFR )
|
||||
{
|
||||
len *= 2;
|
||||
}
|
||||
|
||||
pt1 = speech + L_frame - len;
|
||||
|
||||
dotProd = dotp( pt1, pt1, len );
|
||||
if ( 0 == dotProd )
|
||||
{
|
||||
*frame_ener = MIN_LOG_VAL_60dB;
|
||||
}
|
||||
else
|
||||
{
|
||||
*frame_ener = 10.0f * (float) log10( dotProd / (float) len );
|
||||
}
|
||||
enern = *frame_ener - lp_speech;
|
||||
|
||||
return enern;
|
||||
}
|
||||
@@ -1,196 +0,0 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#include <assert.h>
|
||||
#include "options.h" /* Compilation switches */
|
||||
#include "cnst_fx.h" /* Common constants */
|
||||
#include "prot_fx.h" /* Function prototypes */
|
||||
#include "stl.h"
|
||||
|
||||
/*----------------------------------------------------------------------------------*
|
||||
* frame_ener()
|
||||
*
|
||||
* Estimation of pitch-synchronous (voiced) or mean half-frame (unvoiced) energy
|
||||
*----------------------------------------------------------------------------------*/
|
||||
Word16 frame_ener_fx(
|
||||
const Word16 L_frame, /* i : length of the frame */
|
||||
const Word16 clas, /* i : frame classification */
|
||||
const Word16 *synth, /* i : synthesized speech at Fs = 12k8 Hz Q_new */
|
||||
const Word16 pitch, /* i : pitch period Q0 */
|
||||
Word32 *enr_q, /* o : pitch-synchronous or half_frame energy Q0 */
|
||||
const Word16 offset, /* i : speech pointer offset (0 or L_FRAME) */
|
||||
const Word16 Q_new, /* i : Scaling factor */
|
||||
Word16 shift, /* i : Shift need to obtain 12 bits vectors */
|
||||
const Word16 enc /* i : Encoder/decoder */
|
||||
)
|
||||
{
|
||||
Word16 len, exp_enrq, exp_tmp, pos;
|
||||
Word16 i;
|
||||
const Word16 *pt_synth;
|
||||
Word32 Ltmp;
|
||||
|
||||
exp_enrq = 0;
|
||||
move16();
|
||||
test();
|
||||
test();
|
||||
IF( (sub(clas, VOICED_CLAS) == 0) || (sub(clas, ONSET) == 0) || (sub(clas, SIN_ONSET) == 0) ) /* current frame is voiced */
|
||||
{
|
||||
/* current frame is voiced */
|
||||
len = pitch;
|
||||
move16(); /* pitch value at the end of frame */
|
||||
pt_synth = synth;
|
||||
move16();
|
||||
if (offset != 0)
|
||||
{
|
||||
pt_synth = synth + sub(L_frame, len);
|
||||
}
|
||||
emaximum_fx(Q_new, pt_synth, len, enr_q);
|
||||
move16();/* pitch synchronous E */
|
||||
IF (enc != 0)
|
||||
{
|
||||
exp_enrq = norm_l(*enr_q);
|
||||
*enr_q = L_shl(*enr_q, exp_enrq);
|
||||
move32();
|
||||
exp_enrq = sub(exp_enrq, 2);
|
||||
}
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
/* current frame is unvoiced */
|
||||
Word16 L_frame2, exp2, enr_q_tmp;
|
||||
|
||||
L_frame2 = shr(L_frame,1);
|
||||
pos = 0;
|
||||
move16();
|
||||
|
||||
if (offset != 0)
|
||||
{
|
||||
pos = sub(L_frame, L_frame2);
|
||||
}
|
||||
Ltmp = L_mult(synth[pos], synth[pos]);
|
||||
FOR (i = 1; i < L_frame2; i++)
|
||||
{
|
||||
Ltmp = L_mac(Ltmp, synth[pos+i], synth[pos+i]);
|
||||
}
|
||||
test();
|
||||
IF (L_sub(Ltmp, MAX_32) == 0 || enc != 0)
|
||||
{
|
||||
/* scale down when overflow occurs */
|
||||
*enr_q = Energy_scale(synth+pos, L_frame2, shift, &exp_enrq);
|
||||
move32();
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
shift = 0;
|
||||
move16();
|
||||
/* Normalize acc in Q31 (energy already calculated) */
|
||||
pos = norm_l(Ltmp);
|
||||
Ltmp = L_shl(Ltmp, pos);
|
||||
exp_enrq = sub(30, pos); /* exponent = 0..30 */
|
||||
*enr_q = Ltmp;
|
||||
move32();
|
||||
}
|
||||
|
||||
/* enr2 = 1.0f/L_FRAME2 * dot_product(synth, synth, L_FRAME2) */
|
||||
exp_enrq = sub(exp_enrq, shl(shift, 1));
|
||||
|
||||
IF (enc != 0)
|
||||
{
|
||||
assert(L_frame == 256 || L_frame == 320);
|
||||
|
||||
exp_tmp = add(shl(Q_new, 1), -2+7); /* L_subfr == L_SUBFR */
|
||||
exp_enrq = sub(exp_enrq, exp_tmp);
|
||||
exp_enrq = sub(31, exp_enrq);
|
||||
|
||||
IF(sub(L_frame, 320) == 0)
|
||||
{
|
||||
*enr_q = Mult_32_16(*enr_q, 26214); /*x 0.8 to get /160*/
|
||||
i = norm_l(*enr_q);
|
||||
*enr_q = L_shl(*enr_q, i);
|
||||
exp_enrq = add(i, exp_enrq);
|
||||
}
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
exp_enrq = sub(exp_enrq, add(Q_new, Q_new));
|
||||
enr_q_tmp /*Q30 exp2+exp_enrq*/ = BASOP_Util_Divide3216_Scale(*enr_q /*Q31*/, L_frame2 /*Q0*/, &exp2);
|
||||
*enr_q = L_shr(L_deposit_l(enr_q_tmp),sub(30,add(exp2,exp_enrq))); /*Q0*/
|
||||
*enr_q = L_add(*enr_q, 1);
|
||||
move32();
|
||||
exp_enrq = 0;
|
||||
move16();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
return exp_enrq;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*
|
||||
* frame_energy()
|
||||
*
|
||||
* Compute pitch-synchronous energy at the frame end
|
||||
*------------------------------------------------------------------------*/
|
||||
Word16 frame_energy_fx( /* o : Frame energy in Q8 */
|
||||
Word16 L_frame,
|
||||
const Word16 *pitch, /* i : pitch values for each subframe Q6 */
|
||||
const Word16 *speech, /* i : pointer to speech signal for E computation Q_syn*/
|
||||
const Word16 lp_speech, /* i : long term active speech energy average Q8 */
|
||||
Word16 *frame_ener, /* o : pitch-synchronous energy at frame end Q8 */
|
||||
const Word16 Q_syn /* i : Synthesis scaling */
|
||||
)
|
||||
{
|
||||
Word32 Ltmp;
|
||||
const Word16 *pt1;
|
||||
Word16 tmp16, exp1, exp2, tmp1, tmp2;
|
||||
Word16 len, enern;
|
||||
|
||||
/* len = (0.5f * (pitch[2]/64.0 + pitch[3]/64.0) + 0.5f) */
|
||||
len = mult_r(add(pitch[2], pitch[3]), 256);
|
||||
|
||||
if(sub(len,L_SUBFR) < 0 )
|
||||
{
|
||||
len = shl(len, 1);
|
||||
}
|
||||
pt1 = speech + sub(L_frame,len);
|
||||
|
||||
/* *frame_ener = 10.0f * log10(dot_product(pt1, pt1, len) / (float)len) */
|
||||
|
||||
tmp1 = norm_s(len);
|
||||
tmp2 = shl(len, tmp1);
|
||||
tmp1 = sub(15, tmp1);
|
||||
|
||||
Ltmp = Dot_productSq16HQ( 0, pt1, len, &exp1);
|
||||
exp1 = sub(exp1, shl(Q_syn, 1));
|
||||
exp1 = sub(exp1, 1); /* compensation of leftshift caused by mac operation in dot_productSq16HQ */
|
||||
tmp16 = BASOP_Util_Divide3216_Scale( Ltmp, len, &exp2);
|
||||
|
||||
exp1 = add(exp1, exp2);
|
||||
exp1 = add(exp1, 1); /* compensate result of division Q-1 */
|
||||
|
||||
|
||||
tmp2 = norm_s(tmp16);
|
||||
Ltmp = L_shl(L_deposit_h(tmp16),tmp2); /*Q16, (exp1-tmp2) = Q31, exp1-tmp2+15*/
|
||||
|
||||
Ltmp = BASOP_Util_Log2(Ltmp);/*Q(31-6) = Q25*/
|
||||
exp1 = sub(15+exp1,tmp2);
|
||||
|
||||
/*add ld(2^exp1)=exp1 but check format, first*/
|
||||
tmp16=sub(sub(15,norm_s(exp1)),5); /*factor to shift Ltmp and exp1 with (shr) to avoid overflows when adding*/
|
||||
Ltmp= L_shr(Ltmp,tmp16); /*Q25, tmp16*/
|
||||
exp2 = shr(exp1,tmp16); /*Q0 , tmp16*/
|
||||
Ltmp = L_add(Ltmp,L_shl(L_deposit_l(exp2),25)); /*Q25, tmp16, normalized*/
|
||||
|
||||
/*make 10*log10 out of log2*/
|
||||
Ltmp = Mpy_32_16_1(Ltmp,LG10); /*Q25,tmp16 * Q13 = Q23, tmp16*/
|
||||
*frame_ener = extract_h(L_shl(Ltmp,add(tmp16,1)));/*Q8*/ move16();
|
||||
enern = sub( *frame_ener ,lp_speech); /*Q8*/
|
||||
|
||||
return enern;
|
||||
}
|
||||
89
src/libs/libevs/lib_com/g192.cpp
Executable file → Normal file
89
src/libs/libevs/lib_com/g192.cpp
Executable file → Normal file
@@ -1,17 +1,18 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
EVS Codec 3GPP TS26.443 Nov 13, 2018. Version 12.11.0 / 13.7.0 / 14.3.0 / 15.1.0
|
||||
====================================================================================*/
|
||||
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <netinet/in.h>
|
||||
#include <stdint.h>
|
||||
#else
|
||||
#include <Winsock2.h>
|
||||
|
||||
typedef unsigned short uint16_t;
|
||||
typedef signed short int16_t;
|
||||
typedef unsigned int uint32_t;
|
||||
@@ -20,7 +21,6 @@ typedef unsigned __int64 uint64_t;
|
||||
typedef signed __int64 int64_t;
|
||||
#endif
|
||||
#include "options.h"
|
||||
#include "stl.h"
|
||||
#include "g192.h"
|
||||
|
||||
|
||||
@@ -28,12 +28,15 @@ typedef signed __int64 int64_t;
|
||||
#pragma warning( disable : 4996 )
|
||||
#endif
|
||||
|
||||
#define G192_SYNC_GOOD_FRAME (Word16)0x6B21
|
||||
#define G192_SYNC_BAD_FRAME (Word16)0x6B20
|
||||
#define G192_BIT0 (Word16)0x007F
|
||||
#define G192_BIT1 (Word16)0x0081
|
||||
#define MAX_BITS_PER_FRAME 2560
|
||||
#define RTP_HEADER_PART1 (Word16)22 /* magic number by network simulator */
|
||||
#define G192_SYNC_GOOD_FRAME (unsigned short) 0x6B21
|
||||
#define G192_SYNC_BAD_FRAME (unsigned short) 0x6B20
|
||||
#define G192_BIT0 (unsigned short) 0x007F
|
||||
#define G192_BIT1 (unsigned short) 0x0081
|
||||
#define RTP_HEADER_PART1 (short)22 /* magic number by network simulator */
|
||||
|
||||
#ifndef MAX_BITS_PER_FRAME
|
||||
#define MAX_BITS_PER_FRAME 2560
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Structures
|
||||
@@ -58,7 +61,6 @@ G192_Reader_Open(G192_HANDLE* phG192, FILE * filename)
|
||||
{
|
||||
return G192_MEMORY_ERROR;
|
||||
}
|
||||
|
||||
memset(*phG192, 0, sizeof(struct __G192));
|
||||
|
||||
/* associate file stream */
|
||||
@@ -68,27 +70,24 @@ G192_Reader_Open(G192_HANDLE* phG192, FILE * filename)
|
||||
G192_Reader_Close(phG192);
|
||||
return G192_FILE_NOT_FOUND;
|
||||
}
|
||||
|
||||
return G192_NO_ERROR;
|
||||
}
|
||||
|
||||
G192_ERROR
|
||||
G192_ReadVoipFrame_compact(G192_HANDLE const hG192,
|
||||
unsigned char * const serial,
|
||||
Word16 * const num_bits,
|
||||
Word16 *rtpSequenceNumber,
|
||||
Word32 *rtpTimeStamp,
|
||||
Word32 *rcvTime_ms)
|
||||
short * const num_bits,
|
||||
unsigned short * const rtpSequenceNumber,
|
||||
unsigned int * const rtpTimeStamp,
|
||||
unsigned int * const rcvTime_ms)
|
||||
{
|
||||
Word16 short_serial [MAX_BITS_PER_FRAME];
|
||||
short short_serial [MAX_BITS_PER_FRAME];
|
||||
G192_ERROR err;
|
||||
Word16 i;
|
||||
short i;
|
||||
|
||||
err = G192_ReadVoipFrame_short(hG192, short_serial, num_bits, rtpSequenceNumber, rtpTimeStamp, rcvTime_ms);
|
||||
if(err != G192_NO_ERROR)
|
||||
{
|
||||
return err;
|
||||
}
|
||||
|
||||
for(i=0; i<*num_bits; i++)
|
||||
{
|
||||
@@ -98,23 +97,22 @@ G192_ReadVoipFrame_compact(G192_HANDLE const hG192,
|
||||
serial[i>>3] = 0;
|
||||
serial[i>>3] |= bitinbyte;
|
||||
}
|
||||
|
||||
return G192_NO_ERROR;
|
||||
}
|
||||
|
||||
G192_ERROR
|
||||
G192_ReadVoipFrame_short(G192_HANDLE const hG192,
|
||||
Word16 * const serial,
|
||||
Word16 *num_bits,
|
||||
Word16 *rtpSequenceNumber,
|
||||
Word32 *rtpTimeStamp,
|
||||
Word32 *rcvTime_ms)
|
||||
short * const serial,
|
||||
short * const num_bits,
|
||||
unsigned short * const rtpSequenceNumber,
|
||||
unsigned int * const rtpTimeStamp,
|
||||
unsigned int * const rcvTime_ms)
|
||||
{
|
||||
Word32 rtpPacketSize;
|
||||
Word16 rtpPacketHeaderPart1;
|
||||
Word32 ssrc;
|
||||
Word16 rtpPayloadG192[2];
|
||||
Word16 rtpPayloadSize;
|
||||
uint32_t rtpPacketSize;
|
||||
uint16_t rtpPacketHeaderPart1;
|
||||
uint32_t ssrc;
|
||||
uint16_t rtpPayloadG192[2];
|
||||
uint16_t rtpPayloadSize;
|
||||
|
||||
/* RTP packet size */
|
||||
if(fread(&rtpPacketSize, sizeof(rtpPacketSize), 1, hG192->file) != 1)
|
||||
@@ -124,12 +122,13 @@ G192_ReadVoipFrame_short(G192_HANDLE const hG192,
|
||||
return G192_EOF;
|
||||
}
|
||||
fprintf(stderr, "RTP Packet Size could't be read\n");
|
||||
|
||||
return G192_READ_ERROR;
|
||||
}
|
||||
|
||||
if(rtpPacketSize <= 12)
|
||||
{
|
||||
fprintf(stderr, "RTP Packet size too small: %d\n", rtpPacketSize);
|
||||
fprintf(stderr, "RTP Packet size too small: %ud\n", rtpPacketSize);
|
||||
return G192_INVALID_DATA;
|
||||
}
|
||||
|
||||
@@ -141,6 +140,7 @@ G192_ReadVoipFrame_short(G192_HANDLE const hG192,
|
||||
return G192_EOF;
|
||||
}
|
||||
fprintf(stderr, "Reception Time in ms could't be read\n");
|
||||
|
||||
return G192_READ_ERROR;
|
||||
}
|
||||
|
||||
@@ -152,6 +152,7 @@ G192_ReadVoipFrame_short(G192_HANDLE const hG192,
|
||||
return G192_EOF;
|
||||
}
|
||||
fprintf(stderr, "RTP Header couldn't be read\n");
|
||||
|
||||
return G192_READ_ERROR;
|
||||
}
|
||||
|
||||
@@ -169,10 +170,11 @@ G192_ReadVoipFrame_short(G192_HANDLE const hG192,
|
||||
return G192_EOF;
|
||||
}
|
||||
fprintf(stderr, "RTP Sequence Number be read\n");
|
||||
|
||||
return G192_READ_ERROR;
|
||||
}
|
||||
|
||||
*rtpSequenceNumber = ntohs(*rtpSequenceNumber);
|
||||
|
||||
/* RTP timestamp */
|
||||
if(fread(rtpTimeStamp, sizeof(*rtpTimeStamp), 1, hG192->file) != 1)
|
||||
{
|
||||
@@ -181,10 +183,11 @@ G192_ReadVoipFrame_short(G192_HANDLE const hG192,
|
||||
return G192_EOF;
|
||||
}
|
||||
fprintf(stderr, "RTP Timestamp could't be read\n");
|
||||
|
||||
return G192_READ_ERROR;
|
||||
}
|
||||
|
||||
*rtpTimeStamp = ntohl(*rtpTimeStamp);
|
||||
|
||||
/* RTP ssrc */
|
||||
if(fread(&ssrc, sizeof(ssrc), 1, hG192->file) != 1)
|
||||
{
|
||||
@@ -193,18 +196,20 @@ G192_ReadVoipFrame_short(G192_HANDLE const hG192,
|
||||
return G192_EOF;
|
||||
}
|
||||
fprintf(stderr, "RTP SSRC could't be read\n");
|
||||
|
||||
return G192_READ_ERROR;
|
||||
}
|
||||
|
||||
/* RTP payload size */
|
||||
rtpPayloadSize = (Word16)(rtpPacketSize - 12);
|
||||
rtpPayloadSize = rtpPacketSize - 12;
|
||||
if(rtpPayloadSize <= 2)
|
||||
{
|
||||
fprintf(stderr, "RTP payload size too small: %d\n", rtpPayloadSize);
|
||||
fprintf(stderr, "RTP payload size too small: %u\n", rtpPayloadSize);
|
||||
return G192_INVALID_DATA;
|
||||
}
|
||||
|
||||
/* RTP payload */
|
||||
if(fread(rtpPayloadG192, sizeof(Word16), 2, hG192->file) != 2)
|
||||
if(fread(rtpPayloadG192, sizeof(short), 2, hG192->file) != 2)
|
||||
{
|
||||
if(feof( hG192->file) != 0)
|
||||
{
|
||||
@@ -219,18 +224,14 @@ G192_ReadVoipFrame_short(G192_HANDLE const hG192,
|
||||
return G192_INVALID_DATA;
|
||||
}
|
||||
*num_bits = rtpPayloadG192[1];
|
||||
if(*num_bits == 0 || *num_bits + 2 != rtpPayloadSize || *num_bits > MAX_BITS_PER_FRAME)
|
||||
if(*num_bits == 0u || *num_bits + 2u != rtpPayloadSize || *num_bits > MAX_BITS_PER_FRAME)
|
||||
{
|
||||
fprintf(stderr, "error in parsing RTP payload: rtpPayloadSize=%u nBits=%d",
|
||||
rtpPayloadSize, *num_bits);
|
||||
return G192_INVALID_DATA;
|
||||
}
|
||||
if( (Word16)fread(serial, sizeof(Word16), *num_bits, hG192->file) != *num_bits)
|
||||
if( fread(serial, sizeof(short), *num_bits, hG192->file) != (unsigned short)*num_bits)
|
||||
{
|
||||
if(feof( hG192->file) != 0)
|
||||
{
|
||||
return G192_EOF;
|
||||
}
|
||||
fprintf(stderr, "Premature end of file, cannot read G.192 payload\n");
|
||||
return G192_READ_ERROR;
|
||||
}
|
||||
@@ -242,13 +243,11 @@ G192_ERROR
|
||||
G192_Reader_Close(G192_HANDLE* phG192)
|
||||
{
|
||||
if(phG192 == NULL || *phG192 == NULL)
|
||||
{
|
||||
return G192_NO_ERROR;
|
||||
}
|
||||
|
||||
free( *phG192 );
|
||||
*phG192 = NULL;
|
||||
phG192 = NULL;
|
||||
|
||||
return G192_NO_ERROR;
|
||||
}
|
||||
|
||||
|
||||
22
src/libs/libevs/lib_com/g192.h
Executable file → Normal file
22
src/libs/libevs/lib_com/g192.h
Executable file → Normal file
@@ -1,10 +1,12 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
EVS Codec 3GPP TS26.443 Nov 13, 2018. Version 12.11.0 / 13.7.0 / 14.3.0 / 15.1.0
|
||||
====================================================================================*/
|
||||
|
||||
#ifndef G192_H
|
||||
#define G192_H G192_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/*
|
||||
* ENUMS
|
||||
*/
|
||||
@@ -45,18 +47,18 @@ G192_Reader_Open(G192_HANDLE* phG192, FILE * filename);
|
||||
G192_ERROR
|
||||
G192_ReadVoipFrame_compact(G192_HANDLE const hG192,
|
||||
unsigned char * const serial,
|
||||
Word16 * const num_bits,
|
||||
Word16 *rtpSequenceNumber,
|
||||
Word32 *rtpTimeStamp,
|
||||
Word32 *rcvTime_ms);
|
||||
short * const num_bits,
|
||||
unsigned short * const rtpSequenceNumber,
|
||||
unsigned int * const rtpTimeStamp,
|
||||
unsigned int * const rcvTime_ms);
|
||||
|
||||
G192_ERROR
|
||||
G192_ReadVoipFrame_short(G192_HANDLE const hG192,
|
||||
Word16 * const serial,
|
||||
Word16 *num_bits,
|
||||
Word16 *rtpSequenceNumber,
|
||||
Word32 *rtpTimeStamp,
|
||||
Word32 *rcvTime_ms);
|
||||
short * const serial,
|
||||
short * const num_bits,
|
||||
unsigned short * const rtpSequenceNumber,
|
||||
unsigned int * const rtpTimeStamp,
|
||||
unsigned int * const rcvTime_ms);
|
||||
|
||||
G192_ERROR
|
||||
G192_Reader_Close(G192_HANDLE* phG192);
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#include <assert.h>
|
||||
#include "prot_fx.h"
|
||||
#include "stl.h"
|
||||
#include "basop_util.h"
|
||||
#include "rom_com_fx.h"
|
||||
|
||||
|
||||
Word32 calc_gain_inov( /* returns innovation gain Q16 */
|
||||
const Word16 *code, /* i : algebraic excitation Q9 */
|
||||
Word16 lcode, /* i : Subframe size Q0 */
|
||||
Word32 *dotp, /* o : intermediate result Q31-e */
|
||||
Word16 *dotp_e /* o : intermediate result exponent Q0 */
|
||||
)
|
||||
{
|
||||
Word32 L_tmp;
|
||||
Word16 exp_L_tmp, i;
|
||||
|
||||
/* L_tmp = dot_product(code, code, lcode) + 0.01 */
|
||||
L_tmp = Dot_product12_offs(code, code, lcode, &exp_L_tmp, 2621l/*0.01f/2.0f Q19*/);
|
||||
exp_L_tmp = sub(exp_L_tmp, 18);
|
||||
|
||||
/* gain_inov = 1.0f / sqrt((dot_product(code, code, lcode) + 0.01) / lcode) */
|
||||
/* Note: lcode is in range: 32,40,64,80 */
|
||||
assert((lcode == 32) || (lcode == 40) || (lcode == 64) || (lcode == 80));
|
||||
if (s_and(lcode, sub(lcode, 1)) != 0)
|
||||
{
|
||||
L_tmp = Mpy_32_32(L_tmp, 1717986918l/*64.0/80.0 Q31*/);
|
||||
}
|
||||
exp_L_tmp = sub(exp_L_tmp, sub(14, norm_s(lcode)));
|
||||
|
||||
i = norm_l(L_tmp);
|
||||
L_tmp = L_shl(L_tmp, i);
|
||||
exp_L_tmp = sub(exp_L_tmp, i);
|
||||
|
||||
if (dotp != NULL)
|
||||
{
|
||||
*dotp = L_tmp;
|
||||
move32();
|
||||
}
|
||||
if (dotp_e != NULL)
|
||||
{
|
||||
*dotp_e = exp_L_tmp;
|
||||
move16();
|
||||
}
|
||||
|
||||
L_tmp = ISqrt32norm(L_tmp, &exp_L_tmp);
|
||||
|
||||
return L_shl(L_tmp, sub(exp_L_tmp, 15)); /* 15Q16 */
|
||||
}
|
||||
|
||||
112
src/libs/libevs/lib_com/get_gain.cpp
Executable file → Normal file
112
src/libs/libevs/lib_com/get_gain.cpp
Executable file → Normal file
@@ -1,97 +1,37 @@
|
||||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
EVS Codec 3GPP TS26.443 Nov 13, 2018. Version 12.11.0 / 13.7.0 / 14.3.0 / 15.1.0
|
||||
====================================================================================*/
|
||||
|
||||
#include "options.h"
|
||||
#include "prot_fx.h"
|
||||
#include "stl.h"
|
||||
#include "basop_util.h"
|
||||
#include "prot.h"
|
||||
|
||||
Word32 get_gain( /* output: codebook gain (adaptive or fixed) Q16 */
|
||||
Word16 x[], /* input : target signal */
|
||||
Word16 y[], /* input : filtered codebook excitation */
|
||||
Word16 n /* input : segment length */
|
||||
|
||||
/*----------------------------------------------------------------------------------*
|
||||
* get_gain()
|
||||
*
|
||||
*
|
||||
*----------------------------------------------------------------------------------*/
|
||||
|
||||
float get_gain( /* output: codebook gain (adaptive or fixed) */
|
||||
float x[], /* input : target signal */
|
||||
float y[], /* input : filtered codebook excitation */
|
||||
int n, /* input : segment length */
|
||||
float *en_y /* output: energy of y (sum of y[]^2, optional) */
|
||||
)
|
||||
{
|
||||
Word32 tcorr, tener, Lgain;
|
||||
Word16 exp_c, exp_e, exp, tmp;
|
||||
float corr = 0.0f, ener = 1e-6f;
|
||||
short i;
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
corr += x[i]*y[i];
|
||||
ener += y[i]*y[i];
|
||||
}
|
||||
|
||||
tcorr = L_deposit_l(0);
|
||||
tener = L_deposit_l(0);
|
||||
if (en_y)
|
||||
{
|
||||
*en_y = ener;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*----------------------------------------------------------------*
|
||||
* Find gain based on inter-correlation product
|
||||
*----------------------------------------------------------------*/
|
||||
|
||||
tcorr = Dot_product16HQ( 0, x, y, n, &exp_c );
|
||||
tener = Dot_productSq16HQ( 0, y, n, &exp_e );
|
||||
|
||||
BASOP_Util_Divide_MantExp(round_fx(tcorr), exp_c, s_max(round_fx(tener),1), exp_e, &tmp,&exp);
|
||||
Lgain = L_shl(L_deposit_l(tmp)/*Q15*/,add(1,exp))/*Q16*/;
|
||||
|
||||
return Lgain;
|
||||
}
|
||||
|
||||
Word32 get_gain2( /* output: codebook gain (adaptive or fixed) Q16 */
|
||||
Word16 x[], /* input : target signal */
|
||||
Word16 y[], /* input : filtered codebook excitation */
|
||||
Word16 n /* input : segment length */
|
||||
)
|
||||
{
|
||||
Word32 tcorr, tener, Lgain;
|
||||
Word16 m_corr, m_ener, negative, Q_corr, Q_ener;
|
||||
|
||||
negative = 0;
|
||||
move16();
|
||||
|
||||
/*----------------------------------------------------------------*
|
||||
* Find gain based on inter-correlation product
|
||||
*----------------------------------------------------------------*/
|
||||
tcorr = Dot_product16HQ(0, x, y, n, &Q_corr);
|
||||
tener = Dot_productSq16HQ(0, y, n, &Q_ener);
|
||||
|
||||
tener = L_max(tener, 1);
|
||||
|
||||
if (tcorr <= 0)
|
||||
{
|
||||
negative = 1;
|
||||
move16();
|
||||
}
|
||||
BASOP_SATURATE_WARNING_OFF /*tcorr max be negative maxvall - not critical*/
|
||||
tcorr = L_abs(tcorr);
|
||||
BASOP_SATURATE_WARNING_ON
|
||||
|
||||
m_corr = extract_h(tcorr);
|
||||
|
||||
m_ener = extract_h(tener);
|
||||
|
||||
IF (sub(m_corr, m_ener) > 0)
|
||||
{
|
||||
m_corr = shr(m_corr, 1);
|
||||
Q_corr = add(Q_corr,1);
|
||||
}
|
||||
if (m_ener==0)
|
||||
{
|
||||
move16();
|
||||
m_corr = 0x7FFF;
|
||||
}
|
||||
if (m_ener != 0)
|
||||
{
|
||||
m_corr = div_s(m_corr, m_ener);
|
||||
}
|
||||
|
||||
Q_corr = sub(Q_corr,Q_ener);
|
||||
|
||||
Lgain = L_shl(L_deposit_l(m_corr), add(Q_corr, 1)); /* Lgain in Q16 */
|
||||
|
||||
if (negative != 0)
|
||||
{
|
||||
Lgain = L_negate(Lgain); /* Lgain in Q16 */
|
||||
}
|
||||
|
||||
|
||||
return Lgain;
|
||||
return(corr/ener);
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user