- 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_libs libs)
|
||||||
set (rtphone_engine engine)
|
set (rtphone_engine engine)
|
||||||
|
|
||||||
set (USE_AMR_CODEC OFF CACHE BOOL "Use AMR codec. Requires libraries.")
|
option (USE_AMR_CODEC "Use AMR codec. Requires libraries." OFF)
|
||||||
set (USE_EVS_CODEC OFF CACHE BOOL "Use EVS codec.")
|
option (USE_EVS_CODEC "Use EVS codec." OFF)
|
||||||
|
|
||||||
set (CMAKE_POSITION_INDEPENDENT_CODE ON)
|
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)
|
set (OPENSSL_INCLUDE ${LIB_PLATFORM}/openssl/1.0/include)
|
||||||
message ("Using OpenSSL include files from ${OPENSSL_INCLUDE}")
|
message ("Using OpenSSL include files from ${OPENSSL_INCLUDE}")
|
||||||
|
|
||||||
@@ -164,6 +169,10 @@ if (USE_AMR_CODEC)
|
|||||||
set (LIBS ${LIBS} opencore-amrnb opencore-amrwb)
|
set (LIBS ${LIBS} opencore-amrnb opencore-amrwb)
|
||||||
endif (USE_AMR_CODEC)
|
endif (USE_AMR_CODEC)
|
||||||
|
|
||||||
|
if (USE_EVS_CODEC)
|
||||||
|
add_definitions(-DUSE_EVS_CODEC)
|
||||||
|
endif()
|
||||||
|
|
||||||
target_link_libraries(rtphone
|
target_link_libraries(rtphone
|
||||||
ice_stack jrtplib g729_codec gsm_codec
|
ice_stack jrtplib g729_codec gsm_codec
|
||||||
gsmhr_codec g722_codec srtp resiprocate
|
gsmhr_codec g722_codec srtp resiprocate
|
||||||
@@ -186,6 +195,9 @@ target_include_directories(rtphone
|
|||||||
${LIB_PLATFORM}/opus/include
|
${LIB_PLATFORM}/opus/include
|
||||||
PRIVATE
|
PRIVATE
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/libs/
|
${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/speex/include
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/libs/opus/include/
|
${CMAKE_CURRENT_SOURCE_DIR}/libs/opus/include/
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/libs/json
|
${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/webrtc
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/../../libs/opus/include/
|
${CMAKE_CURRENT_SOURCE_DIR}/../../libs/opus/include/
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/../../libs/resiprocate/
|
${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)
|
if (USE_RESIP_INTEGRATION)
|
||||||
message("USE_RESIP_INTEGRATION is turned on!")
|
message("USE_RESIP_INTEGRATION is turned on!")
|
||||||
target_compile_definitions(media_lib PUBLIC -DUSE_RESIP_INTEGRATION)
|
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
|
#pragma once
|
||||||
#define MT_EVSCODEC_H
|
|
||||||
|
|
||||||
#include "../config.h"
|
#include <set>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include "MT_Codec.h"
|
#include <memory>
|
||||||
#include "../helper/HL_Pointer.h"
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
#if defined(USE_EVS_CODEC)
|
extern "C" {
|
||||||
namespace MT
|
//#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
|
public:
|
||||||
{
|
class Factory
|
||||||
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:
|
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;
|
virtual int channels() = 0;
|
||||||
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 ~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();
|
class EVSCodec : public Codec
|
||||||
const char* name() override;
|
{
|
||||||
int pcmLength() override;
|
private:
|
||||||
int rtpLength() override;
|
Decoder_State* st_dec;
|
||||||
int frameTime() override;
|
//Encoder_State_fx* st_enc;
|
||||||
int samplerate() override;
|
StreamParameters sp;
|
||||||
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 AmrWbCodec : public Codec
|
public:
|
||||||
{
|
class EVSFactory : public Factory
|
||||||
protected:
|
|
||||||
void* mEncoderCtx;
|
|
||||||
void* mDecoderCtx;
|
|
||||||
AmrCodecConfig mConfig;
|
|
||||||
uint64_t mCurrentDecoderTimestamp;
|
|
||||||
int mSwitchCounter;
|
|
||||||
int mPreviousPacketLength;
|
|
||||||
|
|
||||||
public:
|
|
||||||
class CodecFactory: 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:
|
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);
|
EVSCodec();
|
||||||
virtual ~AmrWbCodec();
|
EVSCodec(const StreamParameters& sp);
|
||||||
|
~EVSCodec() override;
|
||||||
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
|
|
||||||
|
|
||||||
|
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 "options.h"
|
||||||
#include "basop_util.h"
|
#include "cnst.h"
|
||||||
#include "cnst_fx.h"
|
#include "prot.h"
|
||||||
#include "prot_fx.h"
|
|
||||||
#include "rom_com_fx.h"
|
|
||||||
#include "stl.h"
|
|
||||||
|
|
||||||
/* Returns: index of next coefficient */
|
|
||||||
Word16 get_next_coeff_mapped(
|
/*-------------------------------------------------------------------*
|
||||||
Word16 ii[2], /* i/o: coefficient indexes */
|
* get_next_coeff_mapped()
|
||||||
Word16 *pp, /* o : peak(1)/hole(0) indicator */
|
*
|
||||||
Word16 *idx, /* o : index in unmapped domain */
|
*
|
||||||
|
*-------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
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 */
|
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]]));
|
p = (ii[1] - hm_cfg->numPeakIndices) & (hm_cfg->indexBuffer[ii[1]] - hm_cfg->indexBuffer[ii[0]]);
|
||||||
if (p > 0)
|
p >>= sizeof(p)*8-1;
|
||||||
{
|
|
||||||
p = 0;
|
|
||||||
move16();
|
|
||||||
}
|
|
||||||
if (p < 0)
|
|
||||||
{
|
|
||||||
p = 1;
|
|
||||||
move16();
|
|
||||||
}
|
|
||||||
*pp = p;
|
*pp = p;
|
||||||
move16();
|
|
||||||
*idx = ii[p];
|
*idx = ii[p];
|
||||||
move16();
|
ii[p]++;
|
||||||
ii[p] = add(ii[p], 1);
|
|
||||||
move16();
|
|
||||||
return hm_cfg->indexBuffer[*idx];
|
return hm_cfg->indexBuffer[*idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Returns: index of next coefficient */
|
|
||||||
Word16 get_next_coeff_unmapped(
|
/*-------------------------------------------------------------------*
|
||||||
Word16 ii[2], /* i/o: coefficient indexes */
|
* get_next_coeff_unmapped()
|
||||||
Word16 *pp, /* o : peak(1)/hole(0) indicator */
|
*
|
||||||
Word16 *idx, /* o : index in unmapped domain */
|
*
|
||||||
CONTEXT_HM_CONFIG *hm_cfg /* i : HM configuration */
|
*-------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
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;
|
*idx = *ii;
|
||||||
(void)hm_cfg;
|
(*ii)++;
|
||||||
|
|
||||||
*idx = ii[0];
|
|
||||||
move16();
|
|
||||||
ii[0] = add(ii[0], 1);
|
|
||||||
move16();
|
|
||||||
return *idx;
|
return *idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
Word16 update_mixed_context(Word16 ctx, Word16 a)
|
/*-------------------------------------------------------------------*
|
||||||
|
* update_mixed_context()
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*-------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
int update_mixed_context(
|
||||||
|
int ctx,
|
||||||
|
int a
|
||||||
|
)
|
||||||
{
|
{
|
||||||
Word32 t32;
|
int t;
|
||||||
Word16 t=0; /* initialize just to avoid compiler warning */
|
|
||||||
|
|
||||||
t32 = L_mac0(1-13, s_and(a, ~1), add(shr(a, 2), 1));
|
t = 1-13 + (a & ~1)*((a>>2)+1);
|
||||||
if (t32 <= 0)
|
|
||||||
|
if (t > 0)
|
||||||
{
|
{
|
||||||
t = extract_l(t32);
|
t = min((a>>3), 2);
|
||||||
}
|
}
|
||||||
a = shr(a, 3);
|
|
||||||
if (t32 > 0)
|
return (ctx & 0xf) * 16 + t + 13;
|
||||||
{
|
|
||||||
t = s_min(a, 2);
|
|
||||||
}
|
|
||||||
return add(shl(s_and(ctx, 0xf), 4), add(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 <stdio.h>
|
||||||
|
#include "cnst.h"
|
||||||
|
#include "prot.h"
|
||||||
|
#include "stat_com.h"
|
||||||
#include "assert.h"
|
#include "assert.h"
|
||||||
#include "prot_fx.h"
|
#include "basop_util.h"
|
||||||
#include "basop_mpy.h"
|
|
||||||
#include "cnst_fx.h"
|
|
||||||
#include "stl.h"
|
|
||||||
|
|
||||||
/**
|
#ifndef int32
|
||||||
* \brief 31x16 Bit multiply (x*y)
|
#define int32 int
|
||||||
*
|
#endif
|
||||||
* \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;
|
|
||||||
|
|
||||||
z = L_shl(L_mult0(xh,y),15);
|
|
||||||
z = L_mac0(z,xl,y);
|
|
||||||
|
|
||||||
return z;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------
|
/*---------------------------------------------------------------
|
||||||
Ari 14 bits common routines
|
Ari 14 bits common routines
|
||||||
-------------------------------------------------------------*/
|
-------------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Integer Multiply
|
* \brief Integer Multiply
|
||||||
*
|
*
|
||||||
* \param[i] r
|
* \param[i] r
|
||||||
* \param[i] c
|
* \param[i] c
|
||||||
*
|
*
|
||||||
* \return r*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;
|
||||||
|
|
||||||
|
/*function in line*/
|
||||||
/*
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|||||||
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 <assert.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include "cnst.h"
|
||||||
#include "stl.h"
|
#include "stl.h"
|
||||||
#include "cnst_fx.h"
|
|
||||||
#include "basop_util.h"
|
#include "basop_util.h"
|
||||||
#include "rom_com_fx.h"
|
#include "prot.h"
|
||||||
#include "prot_fx.h"
|
#include "rom_com.h"
|
||||||
|
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------*
|
||||||
|
* UnmapIndex()
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*-------------------------------------------------------------------*/
|
||||||
|
|
||||||
void UnmapIndex(
|
void UnmapIndex(
|
||||||
Word16 PeriodicityIndex,
|
int PeriodicityIndex,
|
||||||
Word16 Bandwidth,
|
int Bandwidth,
|
||||||
Word16 LtpPitchLag,
|
short LtpPitchLag,
|
||||||
Word8 SmallerLags,
|
int SmallerLags,
|
||||||
Word16 *FractionalResolution,
|
int *FractionalResolution,
|
||||||
Word32 *Lag)
|
int *Lag)
|
||||||
{
|
{
|
||||||
Word16 LtpPitchIndex, Multiplier;
|
if ((LtpPitchLag > 0) && (PeriodicityIndex & kLtpHmFlag))
|
||||||
Word16 Lag16;
|
|
||||||
|
|
||||||
test();
|
|
||||||
IF ((LtpPitchLag > 0) && (s_and(PeriodicityIndex, kLtpHmFlag) != 0))
|
|
||||||
{
|
{
|
||||||
LtpPitchIndex = shr(PeriodicityIndex, 9);
|
int LtpPitchIndex, Multiplier;
|
||||||
Multiplier = s_and(PeriodicityIndex, 0xff);
|
LtpPitchIndex = PeriodicityIndex >> 9;
|
||||||
|
Multiplier = PeriodicityIndex & 0xff;
|
||||||
assert(0 <= LtpPitchIndex && LtpPitchIndex <= 16);
|
assert(0 <= LtpPitchIndex && LtpPitchIndex <= 16);
|
||||||
assert(1 <= Multiplier && Multiplier <= (1 << NumRatioBits[Bandwidth][LtpPitchIndex]));
|
assert(1 <= Multiplier && Multiplier <= (1 << NumRatioBits[Bandwidth][LtpPitchIndex]));
|
||||||
|
|
||||||
*FractionalResolution = kLtpHmFractionalResolution;
|
*FractionalResolution = kLtpHmFractionalResolution;
|
||||||
move16();
|
*Lag = (LtpPitchLag * (int)(4 * Ratios[Bandwidth][LtpPitchIndex][Multiplier-1])) >> 2;
|
||||||
*Lag = L_shr(L_mult0(LtpPitchLag, Ratios[Bandwidth][LtpPitchIndex][Multiplier-1]), 8);
|
|
||||||
move32();
|
|
||||||
}
|
}
|
||||||
ELSE
|
else
|
||||||
{
|
{
|
||||||
IF (sub(PeriodicityIndex, 16) < 0)
|
if (PeriodicityIndex < 16)
|
||||||
{
|
{
|
||||||
*FractionalResolution = 3;
|
*FractionalResolution = 3;
|
||||||
move16();
|
*Lag = PeriodicityIndex + GET_ADJ(0, 6);
|
||||||
Lag16 = add(PeriodicityIndex, GET_ADJ2(0, 6, 3));
|
|
||||||
}
|
}
|
||||||
ELSE IF (sub(PeriodicityIndex, 80) < 0)
|
else if (PeriodicityIndex < 80)
|
||||||
{
|
{
|
||||||
*FractionalResolution = 4;
|
*FractionalResolution = 4;
|
||||||
move16();
|
*Lag = PeriodicityIndex + GET_ADJ(16, 8);
|
||||||
Lag16 = add(PeriodicityIndex, GET_ADJ2(16, 8, 4));
|
|
||||||
}
|
}
|
||||||
ELSE IF (sub(PeriodicityIndex, 208) < 0)
|
else if (PeriodicityIndex < 208)
|
||||||
{
|
{
|
||||||
*FractionalResolution = 3;
|
*FractionalResolution = 3;
|
||||||
move16();
|
*Lag = PeriodicityIndex + GET_ADJ(80, 12);
|
||||||
Lag16 = add(PeriodicityIndex, GET_ADJ2(80, 12, 3));
|
|
||||||
}
|
}
|
||||||
ELSE {
|
else if (PeriodicityIndex < 224 || SmallerLags)
|
||||||
test();
|
{
|
||||||
IF (sub(PeriodicityIndex, 224) < 0 || SmallerLags != 0)
|
*FractionalResolution = 1;
|
||||||
{
|
*Lag = PeriodicityIndex + GET_ADJ(208, 28);
|
||||||
*FractionalResolution = 1;
|
}
|
||||||
move16();
|
else
|
||||||
Lag16 = add(PeriodicityIndex, GET_ADJ2(208, 28, 1));
|
{
|
||||||
}
|
*FractionalResolution = 0;
|
||||||
ELSE {
|
*Lag = PeriodicityIndex + GET_ADJ(224, 188);
|
||||||
*FractionalResolution = 0;
|
|
||||||
move16();
|
|
||||||
Lag16 = add(PeriodicityIndex, GET_ADJ2(224, 188, 0));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
*Lag = L_deposit_l(Lag16);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------*
|
||||||
|
* ConfigureContextHm()
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*-------------------------------------------------------------------*/
|
||||||
|
|
||||||
void ConfigureContextHm(
|
void ConfigureContextHm(
|
||||||
Word16 NumCoeffs, /* (I) Number of coefficients */
|
int NumCoeffs, /* (I) Number of coefficients */
|
||||||
Word16 TargetBits, /* (I) Target bit budget (excl. Done flag) */
|
int TargetBits, /* (I) Target bit budget (excl. Done flag) */
|
||||||
Word16 PeriodicityIndex, /* (I) Pitch related index */
|
int PeriodicityIndex, /* (I) Pitch related index */
|
||||||
Word16 LtpPitchLag, /* (I) TCX-LTP pitch in F.D. */
|
short LtpPitchLag, /* (I) TCX-LTP pitch in F.D. */
|
||||||
CONTEXT_HM_CONFIG *hm_cfg /* (O) Context-based harmonic model configuration */
|
CONTEXT_HM_CONFIG *hm_cfg /* (O) Context-based harmonic model configuration */
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
Word8 Bandwidth, SmallerLags;
|
int Bandwidth, SmallerLags;
|
||||||
Word32 i, Limit, Lag;
|
int i, Limit, Lag;
|
||||||
Word16 j, Index, FractionalResolution;
|
int j, Index, FractionalResolution;
|
||||||
Word16 *tmp;
|
int *tmp;
|
||||||
|
|
||||||
|
|
||||||
Bandwidth = 0;
|
Bandwidth = 0;
|
||||||
move16();
|
if (NumCoeffs >= 256)
|
||||||
if (sub(NumCoeffs, 256) >= 0)
|
|
||||||
{
|
{
|
||||||
Bandwidth = 1;
|
Bandwidth = 1;
|
||||||
move16();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SmallerLags = 0;
|
SmallerLags = 0;
|
||||||
move16();
|
|
||||||
test();
|
if (TargetBits <= kSmallerLagsTargetBitsThreshold || Bandwidth == 0)
|
||||||
if ((sub(TargetBits, kSmallerLagsTargetBitsThreshold) <= 0) || (Bandwidth == 0))
|
|
||||||
{
|
{
|
||||||
SmallerLags = 1;
|
SmallerLags = 1;
|
||||||
move16();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UnmapIndex(PeriodicityIndex,
|
UnmapIndex(PeriodicityIndex, Bandwidth, LtpPitchLag, SmallerLags, &FractionalResolution, &Lag );
|
||||||
Bandwidth,
|
|
||||||
LtpPitchLag,
|
|
||||||
SmallerLags,
|
|
||||||
&FractionalResolution, &Lag);
|
|
||||||
|
|
||||||
/* Set up and fill peakIndices */
|
/* Set up and fill peakIndices */
|
||||||
hm_cfg->peakIndices = hm_cfg->indexBuffer;
|
hm_cfg->peakIndices = hm_cfg->indexBuffer;
|
||||||
tmp = hm_cfg->peakIndices;
|
tmp = hm_cfg->peakIndices;
|
||||||
Limit = L_shl(L_deposit_l(sub(NumCoeffs, 1)), FractionalResolution);
|
Limit = (NumCoeffs - 1) << FractionalResolution;
|
||||||
IF (L_sub(Lag, Limit) < 0)
|
|
||||||
|
for (i=Lag; i<Limit; i+=Lag)
|
||||||
{
|
{
|
||||||
FOR (i=Lag; i<Limit; i+=Lag)
|
Index = i >> FractionalResolution;
|
||||||
{
|
*tmp++ = Index - 1;
|
||||||
Index = extract_l(L_shr(i, FractionalResolution));
|
*tmp++ = Index;
|
||||||
*tmp++ = sub(Index, 1);
|
*tmp++ = Index + 1;
|
||||||
move16();
|
|
||||||
*tmp++ = Index;
|
|
||||||
move16();
|
|
||||||
*tmp++ = add(Index, 1);
|
|
||||||
move16();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
hm_cfg->numPeakIndices = (Word16)(tmp - hm_cfg->indexBuffer);
|
hm_cfg->numPeakIndices = tmp - hm_cfg->indexBuffer;
|
||||||
|
|
||||||
/* Set up and fill holeIndices */
|
/* Set up and fill holeIndices */
|
||||||
hm_cfg->holeIndices = hm_cfg->indexBuffer + hm_cfg->numPeakIndices;
|
hm_cfg->holeIndices = hm_cfg->indexBuffer + hm_cfg->numPeakIndices;
|
||||||
tmp = hm_cfg->holeIndices;
|
tmp = hm_cfg->holeIndices;
|
||||||
Index = 0;
|
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)
|
||||||
{
|
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
*tmp++ = 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 */
|
|
||||||
|
|
||||||
}
|
for (; Index<NumCoeffs; ++Index)
|
||||||
|
|
||||||
Word16 CountIndexBits(
|
|
||||||
Word16 Bandwidth,
|
|
||||||
Word16 PeriodicityIndex)
|
|
||||||
{
|
|
||||||
Word16 result;
|
|
||||||
Word16 PeriodicityIndexS;
|
|
||||||
|
|
||||||
result = 8;
|
|
||||||
move16();
|
|
||||||
PeriodicityIndexS = shr(PeriodicityIndex, 9);
|
|
||||||
|
|
||||||
if (s_and(PeriodicityIndex, kLtpHmFlag) != 0)
|
|
||||||
{
|
{
|
||||||
result = NumRatioBits[Bandwidth][PeriodicityIndexS];
|
*tmp++ = Index;
|
||||||
move16();
|
|
||||||
}
|
}
|
||||||
|
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(
|
int tcx_hm_render(
|
||||||
Word32 lag, /* i: pitch lag Q0 */
|
int lag, /* i: pitch lag */
|
||||||
Word16 fract_res, /* i: fractional resolution of the lag Q0 */
|
int fract_res, /* i: fractional resolution of the lag */
|
||||||
Word16 p[] /* o: harmonic model Q13 */
|
float LtpGain, /* i: LTP gain */
|
||||||
|
Word16 p[] /* o: harmonic model (Q13) */
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
Word16 k, tmp, height;
|
int k;
|
||||||
Word16 PeakDeviation;
|
|
||||||
Word32 f0, tmp32;
|
Word32 f0, tmp32;
|
||||||
|
Word16 height, PeakDeviation, tmp;
|
||||||
|
|
||||||
/* Set up overall shape */
|
/* 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_shr_r(BASOP_Util_InvLog2(L_shl(tmp32, 7)), 2);
|
||||||
tmp32 = L_sub(603979776L, tmp32);
|
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 */
|
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_shr_r(BASOP_Util_InvLog2(L_shl(tmp32, 7)), 2);
|
||||||
tmp32 = L_sub(1395864371L, tmp32);
|
tmp32 = L_sub(1395864371L, tmp32);
|
||||||
PeakDeviation = round_fx(tmp32); /* Q14 */
|
PeakDeviation = round_fx(tmp32); /* Q14 */
|
||||||
@@ -221,72 +206,65 @@ int tcx_hm_render(
|
|||||||
tmp = mult_r(tmp, tmp); /* Q15 */
|
tmp = mult_r(tmp, tmp); /* Q15 */
|
||||||
}
|
}
|
||||||
|
|
||||||
tmp = div_s(13915, PeakDeviation);
|
|
||||||
tmp = mult_r(tmp, tmp); /* Q15 */
|
|
||||||
|
|
||||||
/* Render the prototype peak */
|
/* Render the prototype peak */
|
||||||
p[kTcxHmParabolaHalfWidth] = height;
|
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 */
|
/* Mirror */
|
||||||
FOR (k=-kTcxHmParabolaHalfWidth; k<0; ++k)
|
for (k=-kTcxHmParabolaHalfWidth; k<0; ++k)
|
||||||
{
|
{
|
||||||
p[kTcxHmParabolaHalfWidth+k] = p[kTcxHmParabolaHalfWidth-k];
|
p[kTcxHmParabolaHalfWidth+k] = p[kTcxHmParabolaHalfWidth-k];
|
||||||
move16();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------*
|
||||||
|
* tcx_hm_modify_envelope()
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*-------------------------------------------------------------------*/
|
||||||
|
|
||||||
void tcx_hm_modify_envelope(
|
void tcx_hm_modify_envelope(
|
||||||
Word16 gain, /* i: HM gain Q11 */
|
Word16 gain, /* i: HM gain (Q11) */
|
||||||
Word32 lag, /* i: pitch lag Q0 */
|
int lag,
|
||||||
Word16 fract_res, /* i: fractional resolution of the lag Q0 */
|
int fract_res,
|
||||||
Word16 p[], /* i: harmonic model Q13 */
|
Word16 p[], /* i: harmonic model (Q13) */
|
||||||
Word32 env[], /* i/o: envelope Q16 */
|
Word32 env[], /* i/o: envelope (Q16) */
|
||||||
Word16 L_frame /* i: number of spectral lines Q0 */
|
int L_frame /* i: number of spectral lines */
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
Word16 k, h, x, l1,l2, L_frame_m1, L_frame_for_loop;
|
int k;
|
||||||
Word16 inv_shape[2*kTcxHmParabolaHalfWidth+1];
|
int h, x;
|
||||||
|
Word16 inv_shape[2*kTcxHmParabolaHalfWidth+1]; /* Q15 */
|
||||||
|
|
||||||
IF ( gain == 0 )
|
if (gain == 0)
|
||||||
{
|
{
|
||||||
return;
|
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, round_fx(L_mult(gain, p[k]))));
|
||||||
inv_shape[k] = div_s(512, add(512, mult_r(gain, p[k])));
|
|
||||||
move16();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
h = 1;
|
h = 1;
|
||||||
move16();
|
k = lag >> fract_res;
|
||||||
k = extract_l(L_shr(lag,fract_res));
|
|
||||||
|
|
||||||
L_frame_m1 = sub(L_frame,1);
|
while (k <= L_frame + kTcxHmParabolaHalfWidth - 1)
|
||||||
L_frame_for_loop = add(L_frame,kTcxHmParabolaHalfWidth - 1);
|
|
||||||
|
|
||||||
WHILE ( sub(k,L_frame_for_loop) <= 0 )
|
|
||||||
{
|
{
|
||||||
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);
|
for (x=max(0, k-kTcxHmParabolaHalfWidth); x<=min(k+kTcxHmParabolaHalfWidth, L_frame-1); ++x)
|
||||||
k = extract_l(L_shr(imult3216(lag,h),fract_res));
|
{
|
||||||
|
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 <math.h>
|
||||||
#include <string.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
#include "prot_fx.h"
|
|
||||||
#include "basop_util.h"
|
|
||||||
#include "options.h"
|
#include "options.h"
|
||||||
#include "cnst_fx.h"
|
#include "cnst.h"
|
||||||
#include "stl.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 xi, xf, tmp;
|
||||||
Word16 b0, b1, b2, b3;
|
Word16 b0, b1, b2, b3;
|
||||||
Word32 y, L_tmp;
|
Word32 y, L_tmp;
|
||||||
|
|
||||||
|
assert(x <= 0);
|
||||||
|
|
||||||
assert(x > 0);
|
L_tmp = L_negate(L_shl(L_deposit_h(x), sub(x_e, 15)));
|
||||||
|
|
||||||
L_tmp = L_shl(L_deposit_h(x), x_e);
|
|
||||||
|
|
||||||
/* split into integer and fractional parts */
|
/* split into integer and fractional parts */
|
||||||
xi = round_fx(L_tmp);
|
xi = round_fx(L_tmp);
|
||||||
@@ -55,10 +59,10 @@ Word32 expfp( /* o: Q31 */
|
|||||||
b2 = s_and(xi, 4);
|
b2 = s_and(xi, 4);
|
||||||
b3 = s_and(xi, 8);
|
b3 = s_and(xi, 8);
|
||||||
|
|
||||||
if (b0 != 0) y = Mpy_32_16_1(y, 24109); /* exp(-1) in -1Q16 */
|
if (b0 != 0) y = Mpy_32_16(y, 24109); /* exp(-1) in -1Q16 */
|
||||||
if (b1 != 0) y = Mpy_32_16_1(y, 17739); /* exp(-2) in -2Q17 */
|
if (b1 != 0) y = Mpy_32_16(y, 17739); /* exp(-2) in -2Q17 */
|
||||||
if (b2 != 0) y = Mpy_32_16_1(y, 19205); /* exp(-4) in -5Q20 */
|
if (b2 != 0) y = Mpy_32_16(y, 19205); /* exp(-4) in -5Q20 */
|
||||||
if (b3 != 0) y = Mpy_32_16_1(y, 22513); /* exp(-8) in -11Q26 */
|
if (b3 != 0) y = Mpy_32_16(y, 22513); /* exp(-8) in -11Q26 */
|
||||||
|
|
||||||
/* scaling: -1*b0 - 2*b1 -5*b2 -11*b3 */
|
/* scaling: -1*b0 - 2*b1 -5*b2 -11*b3 */
|
||||||
y = L_shr(y, add(add(xi, shr(xi, 2)), shr(b3, 3)));
|
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)
|
if (shr(xi, 4) > 0)
|
||||||
{
|
{
|
||||||
y = L_deposit_l(0);
|
y = L_deposit_l(0);
|
||||||
|
move16();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return round_fx(L_shl(y, 15));
|
||||||
return 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
|
* Returns: *pout1 = ( (base/65536)^(2*exp - 1) ) * 65536
|
||||||
* *pout2 = ( (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() */
|
* NOTE: This function must be in sync with ari_decode_14bits_pow() */
|
||||||
void powfp_odd2(Word16 base, /* Q15 */
|
|
||||||
Word16 exp, /* Q0 */
|
void powfp_odd2(
|
||||||
Word16 *pout1, /* Q15 */
|
Word16 base, /* Q15 */
|
||||||
Word16 *pout2) /* Q15 */
|
Word16 exp, /* Q0 */
|
||||||
|
Word16 *pout1, /* Q15 */
|
||||||
|
Word16 *pout2 /* Q15 */
|
||||||
|
)
|
||||||
{
|
{
|
||||||
/* this version is in sync with ari_enc_14bits_pow()
|
/* 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
|
* 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;
|
*pout2 = out;
|
||||||
move16();
|
move16();
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------
|
/*------------------------------------------------------------------------
|
||||||
* Function: tcx_arith_scale_envelope
|
* 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
|
* NOTE: This function must be bit-exact on all platforms such that encoder
|
||||||
* and decoder remain synchronized.
|
* and decoder remain synchronized.
|
||||||
*-------------------------------------------------------------------------*/
|
*-------------------------------------------------------------------------*/
|
||||||
|
|
||||||
void tcx_arith_scale_envelope(
|
void tcx_arith_scale_envelope(
|
||||||
Word16 L_spec_core, /* i: number of lines to scale Q0 */
|
Word16 L_spec_core, /* i: number of lines to scale Q0 */
|
||||||
Word16 L_frame, /* i: number of lines Q0 */
|
Word16 L_frame, /* i: number of lines Q0 */
|
||||||
Word32 env[], /* i: unscaled envelope Q16 */
|
Word32 env[], /* i: unscaled envelope Q16 */
|
||||||
Word16 target_bits, /* i: number of available bits Q0 */
|
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[], /* o: scaled envelope Q15-e */
|
||||||
Word16 *s_env_e /* o: scaled envelope exponent Q0 */
|
Word16 *s_env_e /* o: scaled envelope exponent Q0 */
|
||||||
)
|
)
|
||||||
@@ -186,7 +202,6 @@ void tcx_arith_scale_envelope(
|
|||||||
Word16 mean_e, tmp, tmp2;
|
Word16 mean_e, tmp, tmp2;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
lob_bits = 0;
|
lob_bits = 0;
|
||||||
move16();
|
move16();
|
||||||
hib_bits = 0;
|
hib_bits = 0;
|
||||||
@@ -194,10 +209,10 @@ void tcx_arith_scale_envelope(
|
|||||||
|
|
||||||
/* Boosting to account for expected spectrum truncation (kMax) */
|
/* 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)); */
|
/* 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_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 = 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);
|
assert(L_tmp < 32768);
|
||||||
target_bits = extract_l(L_tmp);
|
target_bits = extract_l(L_tmp);
|
||||||
|
|
||||||
@@ -216,12 +231,12 @@ void tcx_arith_scale_envelope(
|
|||||||
}
|
}
|
||||||
tmp = norm_s(L_frame);
|
tmp = norm_s(L_frame);
|
||||||
tmp = shl(div_s(8192, shl(L_frame, tmp)), sub(tmp, 7));
|
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 */
|
/* Rate dependent compensation to get closer to the target on average */
|
||||||
/* mean = (float)pow(mean, (float)L_frame / (float)target_bits * 0.357f); */
|
/* mean = (float)pow(mean, (float)L_frame / (float)target_bits * 0.357f); */
|
||||||
tmp = BASOP_Util_Divide1616_Scale(L_frame, target_bits, &tmp2);
|
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);
|
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
|
/* 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; */
|
/* a = 2*2.71828183f*mean*mean; */
|
||||||
tmp = round_fx(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);
|
a_e = add(shl(mean_e, 1), 3);
|
||||||
|
|
||||||
/* b = (0.15f - (float)pow(2.0f, target_bits/(float)L_frame)) * mean; */
|
/* b = (0.15f - (float)pow(2.0f, target_bits/(float)L_frame)) * mean; */
|
||||||
tmp = BASOP_Util_Divide1616_Scale(target_bits, L_frame, &tmp2);
|
tmp = BASOP_Util_Divide1616_Scale(target_bits, L_frame, &tmp2);
|
||||||
tmp = round_fx(BASOP_util_Pow2(L_deposit_h(tmp), tmp2, &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 = mult_r(b, round_fx(mean));
|
||||||
b_e = add(b_e, mean_e);
|
b_e = add(b_e, mean_e);
|
||||||
|
|
||||||
/* scale = (-b + (float)sqrt(b*b - 4.0f*a*0.035f)) / (2.0f * a); */
|
/* 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 )
|
IF( tmp <= 0 )
|
||||||
{
|
{
|
||||||
tmp = 0;
|
tmp = 0;
|
||||||
set16_fx(s_env, 0, L_frame);
|
|
||||||
|
FOR( k=0; k<L_frame; k++ )
|
||||||
|
{
|
||||||
|
s_env[k] = 0;
|
||||||
|
move16();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ELSE
|
ELSE
|
||||||
{
|
{
|
||||||
@@ -285,24 +305,24 @@ void tcx_arith_scale_envelope(
|
|||||||
|
|
||||||
FOR (k = 0; k < L_frame; k++)
|
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
|
/* 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. */
|
estimate function becomes inaccurate, so use log2(1.0224) for all values below 0.08. */
|
||||||
/* round(state * 1.0224 * 32768) */
|
/* 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);
|
tmp = norm_s(statesi);
|
||||||
statesi = shl(statesi, tmp);
|
statesi = shl(statesi, tmp);
|
||||||
bits = add(bits, sub(1, 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; */
|
/* 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_shl(Mpy_32_16(s, FL2WORD16_SCALE(5.436564f, 3)), 3);
|
||||||
L_tmp = L_add(L_tmp, 9830l/*0.15f Q16*/);
|
L_tmp = L_add(L_tmp, FL2WORD32_SCALE(0.15f, 15));
|
||||||
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_add(L_tmp, L_shl(Mpy_32_16(env[k], mult_r(FL2WORD16(0.035f), iscale)), iscale_e));
|
||||||
|
|
||||||
tmp = norm_l(L_tmp);
|
tmp = norm_l(L_tmp);
|
||||||
statesi = mult_r(statesi, round_fx(L_shl(L_tmp, 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)
|
/* 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))) */
|
* further, we use round(log2(x)) = floor(log2(x)+0.5) = floor(log2(x*sqrt(2))) */
|
||||||
/* a = 5.436564f * s; */
|
/* 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)));
|
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;
|
lob = scale;
|
||||||
move16();
|
move16();
|
||||||
lob_bits = bits;
|
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));
|
adjust = div_s(sub(hib_bits, target_bits), sub(hib_bits, lob_bits));
|
||||||
scale = add(mult_r(sub(lob, hib), adjust), hib);
|
scale = add(mult_r(sub(lob, hib), adjust), hib);
|
||||||
}
|
}
|
||||||
ELSE /* Initial scale adaptation */
|
ELSE
|
||||||
{
|
{
|
||||||
|
/* Initial scale adaptation */
|
||||||
/* adjust = 1.05f * target_bits / (float)bits;
|
/* adjust = 1.05f * target_bits / (float)bits;
|
||||||
scale *= adjust; */
|
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);
|
adjust = BASOP_Util_Divide1616_Scale(adjust, bits, &tmp);
|
||||||
scale = shl(mult_r(scale, adjust), add(1, 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;
|
hib = scale;
|
||||||
move16();
|
move16();
|
||||||
hib_bits = bits;
|
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));
|
adjust = div_s(sub(hib_bits, target_bits), sub(hib_bits, lob_bits));
|
||||||
scale = add(mult_r(sub(lob, hib), adjust), hib);
|
scale = add(mult_r(sub(lob, hib), adjust), hib);
|
||||||
}
|
}
|
||||||
ELSE { /* Initial scale adaptation */
|
ELSE
|
||||||
|
{ /* Initial scale adaptation */
|
||||||
test();
|
test();
|
||||||
IF( target_bits <= 0 || bits <= 0 ) /* safety check in case of bit errors */
|
IF( target_bits <= 0 || bits <= 0 ) /* safety check in case of bit errors */
|
||||||
{
|
{
|
||||||
adjust = 0;
|
adjust = 0;
|
||||||
move16();
|
move16();
|
||||||
set16_fx( s_env, 0, L_frame );
|
|
||||||
|
FOR( k=0; k<L_frame; k++ )
|
||||||
|
{
|
||||||
|
s_env[k] = 0;
|
||||||
|
move16();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ELSE
|
ELSE
|
||||||
{
|
{
|
||||||
@@ -377,7 +406,12 @@ void tcx_arith_scale_envelope(
|
|||||||
{
|
{
|
||||||
iscale = 0;
|
iscale = 0;
|
||||||
move16();
|
move16();
|
||||||
set16_fx( s_env, 0, L_frame );
|
|
||||||
|
FOR( k=0; k<L_frame; k++ )
|
||||||
|
{
|
||||||
|
s_env[k] = 0;
|
||||||
|
move16();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ELSE
|
ELSE
|
||||||
{
|
{
|
||||||
@@ -396,11 +430,14 @@ void tcx_arith_scale_envelope(
|
|||||||
|
|
||||||
FOR (k = 0; k < L_frame; k++)
|
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);
|
L_tmp = L_min(L_tmp, a);
|
||||||
s_env[k] = round_fx(L_tmp);
|
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
|
* NOTE: This function must be bit-exact on all platforms such that encoder
|
||||||
* and decoder remain synchronized.
|
* and decoder remain synchronized.
|
||||||
*-------------------------------------------------------------------------*/
|
*-------------------------------------------------------------------------*/
|
||||||
|
|
||||||
void tcx_arith_render_envelope(
|
void tcx_arith_render_envelope(
|
||||||
const Word16 A_ind[], /* i: LPC coefficients of signal envelope */
|
const Word16 A_ind[], /* i: LPC coefficients of signal envelope */
|
||||||
Word16 L_frame, /* i: number of spectral lines */
|
Word16 L_frame, /* i: number of spectral lines */
|
||||||
Word16 L_spec,
|
Word16 L_spec,
|
||||||
Word16 preemph_fac, /* i: pre-emphasis factor */
|
Word16 preemph_fac, /* i: pre-emphasis factor */
|
||||||
Word16 gamma_w, /* i: A_ind -> weighted envelope factor */
|
Word16 gamma_w, /* i: A_ind -> weighted envelope factor */
|
||||||
Word16 gamma_uw, /* i: A_ind -> non-weighted envelope factor */
|
Word16 gamma_uw, /* i: A_ind -> non-weighted envelope factor */
|
||||||
Word32 env[] /* o: shaped signal envelope */
|
Word32 env[] /* o: shaped signal envelope */
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
Word16 k;
|
Word16 k;
|
||||||
@@ -431,15 +469,14 @@ void tcx_arith_render_envelope(
|
|||||||
Word16 gainlpc[FDNS_NPTS], gainlpc_e[FDNS_NPTS];
|
Word16 gainlpc[FDNS_NPTS], gainlpc_e[FDNS_NPTS];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Compute perceptual LPC envelope, transform it into freq.-domain gains */
|
/* Compute perceptual LPC envelope, transform it into freq.-domain gains */
|
||||||
weight_a_fx( A_ind, tmpA, gamma_w, M );
|
basop_weight_a(A_ind, tmpA, gamma_w);
|
||||||
lpc2mdct( tmpA, M, NULL, NULL, gainlpc, gainlpc_e );
|
basop_lpc2mdct(tmpA, M, NULL, NULL, gainlpc, gainlpc_e);
|
||||||
|
|
||||||
/* Add pre-emphasis tilt to LPC envelope, transform LPC into MDCT gains */
|
/* Add pre-emphasis tilt to LPC envelope, transform LPC into MDCT gains */
|
||||||
E_LPC_a_weight_inv(A_ind, signal_env, gamma_uw, M);
|
basop_weight_a_inv(A_ind, signal_env, gamma_uw);
|
||||||
E_LPC_a_add_tilt(signal_env, tmpA, preemph_fac, M);
|
basop_E_LPC_a_add_tilt(signal_env, tmpA, preemph_fac);
|
||||||
lpc2mdct(tmpA, M+1, signal_env, signal_env_e, NULL, NULL);
|
basop_lpc2mdct(tmpA, M+1, signal_env, signal_env_e, NULL, NULL);
|
||||||
|
|
||||||
/* Compute weighted signal envelope in perceptual domain */
|
/* Compute weighted signal envelope in perceptual domain */
|
||||||
FOR (k = 0; k < FDNS_NPTS; k++)
|
FOR (k = 0; k < FDNS_NPTS; k++)
|
||||||
@@ -451,15 +488,16 @@ void tcx_arith_render_envelope(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Adaptive low frequency emphasis */
|
/* Adaptive low frequency emphasis */
|
||||||
set32_fx(env, 0x10000, L_frame);
|
FOR (k = 0; k < L_frame; k++)
|
||||||
|
{
|
||||||
|
env[k] = 0x10000;
|
||||||
|
move32();
|
||||||
|
}
|
||||||
|
|
||||||
AdaptLowFreqDeemph(env, 15,
|
basop_PsychAdaptLowFreqDeemph(env, gainlpc, gainlpc_e, NULL);
|
||||||
1,
|
|
||||||
gainlpc, gainlpc_e,
|
|
||||||
L_frame, NULL);
|
|
||||||
|
|
||||||
/* Scale from FDNS_NPTS to L_frame and multiply LFE gains */
|
/* 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)
|
FOR (k=L_frame; k<L_spec; ++k)
|
||||||
{
|
{
|
||||||
@@ -467,5 +505,6 @@ void tcx_arith_render_envelope(
|
|||||||
move32();
|
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
|
/* v.2.3 - 30.Nov.2009
|
||||||
=============================================================================
|
=============================================================================
|
||||||
|
|
||||||
@@ -121,18 +122,15 @@ HISTORY:
|
|||||||
| Include-Files |
|
| Include-Files |
|
||||||
|___________________________________________________________________________|
|
|___________________________________________________________________________|
|
||||||
*/
|
*/
|
||||||
|
#ifndef _CRT_SECURE_NO_WARNINGS
|
||||||
|
#define _CRT_SECURE_NO_WARNINGS
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "stl.h"
|
#include "stl.h"
|
||||||
|
|
||||||
|
|
||||||
#if (WMOPS)
|
|
||||||
extern BASIC_OP multiCounter[MAXCOUNTERS];
|
|
||||||
extern int currCounter;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*___________________________________________________________________________
|
/*___________________________________________________________________________
|
||||||
| |
|
| |
|
||||||
| Local Functions |
|
| Local Functions |
|
||||||
@@ -203,9 +201,6 @@ static Word16 saturate (Word32 L_var1)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
var_out = extract_l (L_var1);
|
var_out = extract_l (L_var1);
|
||||||
#if (WMOPS)
|
|
||||||
multiCounter[currCounter].extract_l--;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BASOP_CHECK();
|
BASOP_CHECK();
|
||||||
@@ -255,9 +250,7 @@ Word16 add (Word16 var1, Word16 var2)
|
|||||||
L_sum = (Word32) var1 + var2;
|
L_sum = (Word32) var1 + var2;
|
||||||
var_out = saturate (L_sum);
|
var_out = saturate (L_sum);
|
||||||
|
|
||||||
#if (WMOPS)
|
|
||||||
multiCounter[currCounter].add++;
|
|
||||||
#endif
|
|
||||||
return (var_out);
|
return (var_out);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -303,9 +296,7 @@ Word16 sub (Word16 var1, Word16 var2)
|
|||||||
L_diff = (Word32) var1 - var2;
|
L_diff = (Word32) var1 - var2;
|
||||||
var_out = saturate (L_diff);
|
var_out = saturate (L_diff);
|
||||||
|
|
||||||
#if (WMOPS)
|
|
||||||
multiCounter[currCounter].sub++;
|
|
||||||
#endif
|
|
||||||
return (var_out);
|
return (var_out);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -357,12 +348,9 @@ Word16 abs_s (Word16 var1)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if (WMOPS)
|
|
||||||
multiCounter[currCounter].abs_s++;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
BASOP_CHECK();
|
BASOP_CHECK();
|
||||||
|
|
||||||
|
|
||||||
return (var_out);
|
return (var_out);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -412,10 +400,6 @@ Word16 shl (Word16 var1, Word16 var2)
|
|||||||
var2 = -16;
|
var2 = -16;
|
||||||
var2 = -var2;
|
var2 = -var2;
|
||||||
var_out = shr (var1, var2);
|
var_out = shr (var1, var2);
|
||||||
|
|
||||||
#if (WMOPS)
|
|
||||||
multiCounter[currCounter].shr--;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -429,19 +413,12 @@ Word16 shl (Word16 var1, Word16 var2)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
var_out = extract_l (result);
|
var_out = extract_l (result);
|
||||||
|
|
||||||
#if (WMOPS)
|
|
||||||
multiCounter[currCounter].extract_l--;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if (WMOPS)
|
|
||||||
multiCounter[currCounter].shl++;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
BASOP_CHECK();
|
BASOP_CHECK();
|
||||||
|
|
||||||
|
|
||||||
return (var_out);
|
return (var_out);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -490,10 +467,6 @@ Word16 shr (Word16 var1, Word16 var2)
|
|||||||
var2 = -16;
|
var2 = -16;
|
||||||
var2 = -var2;
|
var2 = -var2;
|
||||||
var_out = shl (var1, var2);
|
var_out = shl (var1, var2);
|
||||||
|
|
||||||
#if (WMOPS)
|
|
||||||
multiCounter[currCounter].shl--;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -514,12 +487,9 @@ Word16 shr (Word16 var1, Word16 var2)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if (WMOPS)
|
|
||||||
multiCounter[currCounter].shr++;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
BASOP_CHECK();
|
BASOP_CHECK();
|
||||||
|
|
||||||
|
|
||||||
return (var_out);
|
return (var_out);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -572,9 +542,7 @@ Word16 mult (Word16 var1, Word16 var2)
|
|||||||
|
|
||||||
var_out = saturate (L_product);
|
var_out = saturate (L_product);
|
||||||
|
|
||||||
#if (WMOPS)
|
|
||||||
multiCounter[currCounter].mult++;
|
|
||||||
#endif
|
|
||||||
return (var_out);
|
return (var_out);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -629,12 +597,9 @@ Word32 L_mult (Word16 var1, Word16 var2)
|
|||||||
L_var_out = MAX_32;
|
L_var_out = MAX_32;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if (WMOPS)
|
|
||||||
multiCounter[currCounter].L_mult++;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
BASOP_CHECK();
|
BASOP_CHECK();
|
||||||
|
|
||||||
|
|
||||||
return (L_var_out);
|
return (L_var_out);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -674,12 +639,9 @@ Word16 negate (Word16 var1)
|
|||||||
var_out = (var1 == MIN_16) ? MAX_16 : -var1;
|
var_out = (var1 == MIN_16) ? MAX_16 : -var1;
|
||||||
|
|
||||||
|
|
||||||
#if (WMOPS)
|
|
||||||
multiCounter[currCounter].negate++;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
BASOP_CHECK();
|
BASOP_CHECK();
|
||||||
|
|
||||||
|
|
||||||
return (var_out);
|
return (var_out);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -717,12 +679,9 @@ Word16 extract_h (Word32 L_var1)
|
|||||||
|
|
||||||
var_out = (Word16) (L_var1 >> 16);
|
var_out = (Word16) (L_var1 >> 16);
|
||||||
|
|
||||||
#if (WMOPS)
|
|
||||||
multiCounter[currCounter].extract_h++;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
BASOP_CHECK();
|
BASOP_CHECK();
|
||||||
|
|
||||||
|
|
||||||
return (var_out);
|
return (var_out);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -760,12 +719,9 @@ Word16 extract_l (Word32 L_var1)
|
|||||||
|
|
||||||
var_out = (Word16) L_var1;
|
var_out = (Word16) L_var1;
|
||||||
|
|
||||||
#if (WMOPS)
|
|
||||||
multiCounter[currCounter].extract_l++;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
BASOP_CHECK();
|
BASOP_CHECK();
|
||||||
|
|
||||||
|
|
||||||
return (var_out);
|
return (var_out);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -805,19 +761,14 @@ Word16 round_fx (Word32 L_var1)
|
|||||||
Word16 var_out;
|
Word16 var_out;
|
||||||
Word32 L_rounded;
|
Word32 L_rounded;
|
||||||
|
|
||||||
BASOP_SATURATE_WARNING_OFF
|
BASOP_SATURATE_WARNING_OFF
|
||||||
L_rounded = L_add (L_var1, (Word32) 0x00008000L);
|
L_rounded = L_add (L_var1, (Word32) 0x00008000L);
|
||||||
BASOP_SATURATE_WARNING_ON
|
BASOP_SATURATE_WARNING_ON
|
||||||
var_out = extract_h (L_rounded);
|
var_out = extract_h (L_rounded);
|
||||||
|
|
||||||
#if (WMOPS)
|
|
||||||
multiCounter[currCounter].L_add--;
|
|
||||||
multiCounter[currCounter].extract_h--;
|
|
||||||
multiCounter[currCounter].round++;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
BASOP_CHECK();
|
BASOP_CHECK();
|
||||||
|
|
||||||
|
|
||||||
return (var_out);
|
return (var_out);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -866,14 +817,9 @@ Word32 L_mac (Word32 L_var3, Word16 var1, Word16 var2)
|
|||||||
L_product = L_mult (var1, var2);
|
L_product = L_mult (var1, var2);
|
||||||
L_var_out = L_add (L_var3, L_product);
|
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();
|
BASOP_CHECK();
|
||||||
|
|
||||||
|
|
||||||
return (L_var_out);
|
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_product = L_mult (var1, var2);
|
||||||
L_var_out = L_sub (L_var3, L_product);
|
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();
|
BASOP_CHECK();
|
||||||
|
|
||||||
|
|
||||||
return (L_var_out);
|
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_mult (var1, var2);
|
||||||
L_var_out = L_add_c (L_var3, L_var_out);
|
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 */
|
/* 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_mult (var1, var2);
|
||||||
L_var_out = L_sub_c (L_var3, L_var_out);
|
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 */
|
/* BASOP_CHECK(); Do not check for overflow here, function produces the carry bit instead */
|
||||||
|
|
||||||
|
|
||||||
return (L_var_out);
|
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();
|
BASOP_CHECK();
|
||||||
|
|
||||||
|
|
||||||
return (L_var_out);
|
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();
|
BASOP_CHECK();
|
||||||
|
|
||||||
|
|
||||||
return (L_var_out);
|
return (L_var_out);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1276,12 +1199,9 @@ Word32 L_add_c (Word32 L_var1, Word32 L_var2)
|
|||||||
Carry = carry_int;
|
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 */
|
/* BASOP_CHECK(); Do not check for overflow here, function produces the carry bit instead */
|
||||||
|
|
||||||
|
|
||||||
return (L_var_out);
|
return (L_var_out);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1335,9 +1255,6 @@ Word32 L_sub_c (Word32 L_var1, Word32 L_var2)
|
|||||||
if (L_var2 != MIN_32)
|
if (L_var2 != MIN_32)
|
||||||
{
|
{
|
||||||
L_var_out = L_add_c (L_var1, -L_var2);
|
L_var_out = L_add_c (L_var1, -L_var2);
|
||||||
#if (WMOPS)
|
|
||||||
multiCounter[currCounter].L_add_c--;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
else
|
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 */
|
/* BASOP_CHECK(); Do not check for overflow here, function produces the carry bit instead */
|
||||||
|
|
||||||
|
|
||||||
return (L_var_out);
|
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;
|
L_var_out = (L_var1 == MIN_32) ? MAX_32 : -L_var1;
|
||||||
|
|
||||||
|
|
||||||
#if (WMOPS)
|
|
||||||
multiCounter[currCounter].L_negate++;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
BASOP_CHECK();
|
BASOP_CHECK();
|
||||||
|
|
||||||
|
|
||||||
return (L_var_out);
|
return (L_var_out);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1483,9 +1394,7 @@ Word16 mult_r (Word16 var1, Word16 var2)
|
|||||||
}
|
}
|
||||||
var_out = saturate (L_product_arr);
|
var_out = saturate (L_product_arr);
|
||||||
|
|
||||||
#if (WMOPS)
|
|
||||||
multiCounter[currCounter].mult_r++;
|
|
||||||
#endif
|
|
||||||
return (var_out);
|
return (var_out);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1534,9 +1443,6 @@ Word32 L_shl (Word32 L_var1, Word16 var2)
|
|||||||
var2 = -32;
|
var2 = -32;
|
||||||
var2 = -var2;
|
var2 = -var2;
|
||||||
L_var_out = L_shr (L_var1, var2);
|
L_var_out = L_shr (L_var1, var2);
|
||||||
#if (WMOPS)
|
|
||||||
multiCounter[currCounter].L_shr--;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -1561,12 +1467,10 @@ Word32 L_shl (Word32 L_var1, Word16 var2)
|
|||||||
L_var_out = L_var1;
|
L_var_out = L_var1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#if (WMOPS)
|
|
||||||
multiCounter[currCounter].L_shl++;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
BASOP_CHECK();
|
BASOP_CHECK();
|
||||||
|
|
||||||
|
|
||||||
return (L_var_out);
|
return (L_var_out);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1614,9 +1518,6 @@ Word32 L_shr (Word32 L_var1, Word16 var2)
|
|||||||
var2 = -32;
|
var2 = -32;
|
||||||
var2 = -var2;
|
var2 = -var2;
|
||||||
L_var_out = L_shl (L_var1, var2);
|
L_var_out = L_shl (L_var1, var2);
|
||||||
#if (WMOPS)
|
|
||||||
multiCounter[currCounter].L_shl--;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -1636,12 +1537,10 @@ Word32 L_shr (Word32 L_var1, Word16 var2)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#if (WMOPS)
|
|
||||||
multiCounter[currCounter].L_shr++;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
BASOP_CHECK();
|
BASOP_CHECK();
|
||||||
|
|
||||||
|
|
||||||
return (L_var_out);
|
return (L_var_out);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1699,10 +1598,6 @@ Word16 shr_r (Word16 var1, Word16 var2)
|
|||||||
{
|
{
|
||||||
var_out = shr (var1, var2);
|
var_out = shr (var1, var2);
|
||||||
|
|
||||||
#if (WMOPS)
|
|
||||||
multiCounter[currCounter].shr--;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (var2 > 0)
|
if (var2 > 0)
|
||||||
{
|
{
|
||||||
if ((var1 & ((Word16) 1 << (var2 - 1))) != 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();
|
BASOP_CHECK();
|
||||||
|
|
||||||
|
|
||||||
return (var_out);
|
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);
|
L_var3 = L_add (L_var3, (Word32) 0x00008000L);
|
||||||
var_out = extract_h (L_var3);
|
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();
|
BASOP_CHECK();
|
||||||
|
|
||||||
|
|
||||||
return (var_out);
|
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);
|
L_var3 = L_add (L_var3, (Word32) 0x00008000L);
|
||||||
var_out = extract_h (L_var3);
|
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();
|
BASOP_CHECK();
|
||||||
|
|
||||||
|
|
||||||
return (var_out);
|
return (var_out);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1874,12 +1754,9 @@ Word32 L_deposit_h (Word16 var1)
|
|||||||
|
|
||||||
L_var_out = (Word32) var1 << 16;
|
L_var_out = (Word32) var1 << 16;
|
||||||
|
|
||||||
#if (WMOPS)
|
|
||||||
multiCounter[currCounter].L_deposit_h++;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
BASOP_CHECK();
|
BASOP_CHECK();
|
||||||
|
|
||||||
|
|
||||||
return (L_var_out);
|
return (L_var_out);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1918,12 +1795,9 @@ Word32 L_deposit_l (Word16 var1)
|
|||||||
|
|
||||||
L_var_out = (Word32) var1;
|
L_var_out = (Word32) var1;
|
||||||
|
|
||||||
#if (WMOPS)
|
|
||||||
multiCounter[currCounter].L_deposit_l++;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
BASOP_CHECK();
|
BASOP_CHECK();
|
||||||
|
|
||||||
|
|
||||||
return (L_var_out);
|
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);
|
L_var_out = L_shr (L_var1, var2);
|
||||||
|
|
||||||
#if (WMOPS)
|
|
||||||
multiCounter[currCounter].L_shr--;
|
|
||||||
#endif
|
|
||||||
if (var2 > 0)
|
if (var2 > 0)
|
||||||
{
|
{
|
||||||
if ((L_var1 & ((Word32) 1 << (var2 - 1))) != 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();
|
BASOP_CHECK();
|
||||||
|
|
||||||
|
|
||||||
return (L_var_out);
|
return (L_var_out);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2051,12 +1919,9 @@ Word32 L_abs (Word32 L_var1)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if (WMOPS)
|
|
||||||
multiCounter[currCounter].L_abs++;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
BASOP_CHECK();
|
BASOP_CHECK();
|
||||||
|
|
||||||
|
|
||||||
return (L_var_out);
|
return (L_var_out);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2113,12 +1978,9 @@ Word32 L_sat (Word32 L_var1)
|
|||||||
Overflow = 0;
|
Overflow = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if (WMOPS)
|
|
||||||
multiCounter[currCounter].L_sat++;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
BASOP_CHECK();
|
BASOP_CHECK();
|
||||||
|
|
||||||
|
|
||||||
return (L_var_out);
|
return (L_var_out);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2182,12 +2044,9 @@ Word16 norm_s (Word16 var1)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if (WMOPS)
|
|
||||||
multiCounter[currCounter].norm_s++;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
BASOP_CHECK();
|
BASOP_CHECK();
|
||||||
|
|
||||||
|
|
||||||
return (var_out);
|
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(); */
|
/* printf ("Division Error var1=%d var2=%d in ", var1, var2); printStack(); */
|
||||||
char text[60];
|
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); */
|
abort(); /* exit (0); */
|
||||||
}
|
}
|
||||||
if (var2 == 0)
|
if (var2 == 0)
|
||||||
@@ -2262,11 +2121,6 @@ Word16 div_s (Word16 var1, Word16 var2)
|
|||||||
L_num = L_deposit_l (var1);
|
L_num = L_deposit_l (var1);
|
||||||
L_denom = L_deposit_l (var2);
|
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++)
|
for (iteration = 0; iteration < 15; iteration++)
|
||||||
{
|
{
|
||||||
var_out <<= 1;
|
var_out <<= 1;
|
||||||
@@ -2276,21 +2130,14 @@ Word16 div_s (Word16 var1, Word16 var2)
|
|||||||
{
|
{
|
||||||
L_num = L_sub (L_num, L_denom);
|
L_num = L_sub (L_num, L_denom);
|
||||||
var_out = add (var_out, 1);
|
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();
|
BASOP_CHECK();
|
||||||
|
|
||||||
|
|
||||||
return (var_out);
|
return (var_out);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2354,12 +2201,9 @@ Word16 norm_l (Word32 L_var1)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if (WMOPS)
|
|
||||||
multiCounter[currCounter].norm_l++;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
BASOP_CHECK();
|
BASOP_CHECK();
|
||||||
|
|
||||||
|
|
||||||
return (var_out);
|
return (var_out);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2411,24 +2255,17 @@ Word16 norm_l (Word32 L_var1)
|
|||||||
*/
|
*/
|
||||||
Word32 L_mls (Word32 Lv, Word16 v)
|
Word32 L_mls (Word32 Lv, Word16 v)
|
||||||
{
|
{
|
||||||
Word32 Temp ;
|
Word32 Temp ;
|
||||||
|
|
||||||
Temp = Lv & (Word32) 0x0000ffff ;
|
Temp = Lv & (Word32) 0x0000ffff ;
|
||||||
Temp = Temp * (Word32) v ;
|
Temp = Temp * (Word32) v ;
|
||||||
Temp = L_shr( Temp, (Word16) 15 ) ;
|
Temp = L_shr( Temp, (Word16) 15 ) ;
|
||||||
Temp = L_mac( Temp, v, extract_h(Lv) ) ;
|
Temp = L_mac( Temp, v, extract_h(Lv) ) ;
|
||||||
|
|
||||||
#if (WMOPS)
|
BASOP_CHECK();
|
||||||
multiCounter[currCounter].L_shr--;
|
|
||||||
multiCounter[currCounter].L_mac--;
|
|
||||||
multiCounter[currCounter].extract_h--;
|
|
||||||
multiCounter[currCounter].L_mls++;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
BASOP_CHECK();
|
return Temp ;
|
||||||
|
|
||||||
return Temp ;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -2476,55 +2313,44 @@ Word16 div_l (Word32 L_num, Word16 den)
|
|||||||
Word32 L_den;
|
Word32 L_den;
|
||||||
Word16 iteration;
|
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(); */
|
/* printf("Division by 0 in div_l, Fatal error in "); printStack(); */
|
||||||
exit(-1);
|
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(); */
|
/* printf("Division Error in div_l, Fatal error in "); printStack(); */
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
L_den = L_deposit_h( den ) ;
|
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();
|
BASOP_CHECK();
|
||||||
|
|
||||||
return MAX_16 ;
|
return MAX_16 ;
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
L_num = L_shr(L_num, (Word16)1) ;
|
L_num = L_shr(L_num, (Word16)1) ;
|
||||||
L_den = L_shr(L_den, (Word16)1);
|
L_den = L_shr(L_den, (Word16)1);
|
||||||
#if (WMOPS)
|
for(iteration=(Word16)0; iteration< (Word16)15; iteration++)
|
||||||
multiCounter[currCounter].L_shr-=2;
|
{
|
||||||
#endif
|
|
||||||
for(iteration=(Word16)0; iteration< (Word16)15;iteration++) {
|
|
||||||
var_out = shl( var_out, (Word16)1);
|
var_out = shl( var_out, (Word16)1);
|
||||||
L_num = L_shl( L_num, (Word16)1);
|
L_num = L_shl( L_num, (Word16)1);
|
||||||
#if (WMOPS)
|
if (L_num >= L_den)
|
||||||
multiCounter[currCounter].shl--;
|
{
|
||||||
multiCounter[currCounter].L_shl--;
|
|
||||||
#endif
|
|
||||||
if (L_num >= L_den) {
|
|
||||||
L_num = L_sub(L_num,L_den);
|
L_num = L_sub(L_num,L_den);
|
||||||
var_out = add(var_out, (Word16)1);
|
var_out = add(var_out, (Word16)1);
|
||||||
#if (WMOPS)
|
|
||||||
multiCounter[currCounter].L_sub--;
|
|
||||||
multiCounter[currCounter].add--;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BASOP_CHECK();
|
BASOP_CHECK();
|
||||||
|
|
||||||
return var_out;
|
return var_out;
|
||||||
@@ -2565,13 +2391,10 @@ Word16 div_l (Word32 L_num, Word16 den)
|
|||||||
Word16 i_mult (Word16 a, Word16 b)
|
Word16 i_mult (Word16 a, Word16 b)
|
||||||
{
|
{
|
||||||
#ifdef ORIGINAL_G7231
|
#ifdef ORIGINAL_G7231
|
||||||
return a*b ;
|
return a*b ;
|
||||||
#else
|
#else
|
||||||
Word32 /*register*/ c=a*b;
|
Word32 /*register*/ c=a*b;
|
||||||
#if (WMOPS)
|
return saturate(c) ;
|
||||||
multiCounter[currCounter].i_mult++;
|
|
||||||
#endif
|
|
||||||
return saturate(c) ;
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2612,17 +2435,14 @@ Word16 i_mult (Word16 a, Word16 b)
|
|||||||
*/
|
*/
|
||||||
Word32 L_mult0 (Word16 var1,Word16 var2)
|
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)
|
BASOP_CHECK();
|
||||||
multiCounter[currCounter].L_mult0++;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
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_mac0 (Word32 L_var3, Word16 var1, Word16 var2)
|
||||||
{
|
{
|
||||||
Word32 L_var_out;
|
Word32 L_var_out;
|
||||||
Word32 L_product;
|
Word32 L_product;
|
||||||
|
|
||||||
L_product = L_mult0(var1,var2);
|
L_product = L_mult0(var1,var2);
|
||||||
L_var_out = L_add(L_var3,L_product);
|
L_var_out = L_add(L_var3,L_product);
|
||||||
|
|
||||||
#if (WMOPS)
|
BASOP_CHECK();
|
||||||
multiCounter[currCounter].L_mac0++;
|
|
||||||
multiCounter[currCounter].L_mult0--;
|
|
||||||
multiCounter[currCounter].L_add--;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
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_msu0 (Word32 L_var3, Word16 var1, Word16 var2)
|
||||||
{
|
{
|
||||||
Word32 L_var_out;
|
Word32 L_var_out;
|
||||||
Word32 L_product;
|
Word32 L_product;
|
||||||
|
|
||||||
L_product = L_mult0(var1,var2);
|
L_product = L_mult0(var1,var2);
|
||||||
L_var_out = L_sub(L_var3,L_product);
|
L_var_out = L_sub(L_var3,L_product);
|
||||||
|
|
||||||
#if (WMOPS)
|
BASOP_CHECK();
|
||||||
multiCounter[currCounter].L_msu0++;
|
|
||||||
multiCounter[currCounter].L_mult0--;
|
|
||||||
multiCounter[currCounter].L_sub--;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
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 "basop_mpy.h"
|
||||||
#include "stl.h"
|
#include "options.h"
|
||||||
#include "options.h" /* Needed for Stack Counting Mechanism Macros (when Instrumented) */
|
|
||||||
|
|
||||||
Word32 Mpy_32_16_1(Word32 x, Word16 y)
|
Word32 Mpy_32_16_1(Word32 x, Word16 y)
|
||||||
{
|
{
|
||||||
@@ -16,6 +16,16 @@ Word32 Mpy_32_16_1(Word32 x, Word16 y)
|
|||||||
return (mh);
|
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 Mpy_32_16_r(Word32 x, Word16 y)
|
||||||
{
|
{
|
||||||
Word32 mh;
|
Word32 mh;
|
||||||
@@ -31,6 +41,7 @@ Word32 Mpy_32_16_r(Word32 x, Word16 y)
|
|||||||
return (mh);
|
return (mh);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Word32 Mpy_32_32(Word32 x, Word32 y)
|
Word32 Mpy_32_32(Word32 x, Word32 y)
|
||||||
{
|
{
|
||||||
Word32 mh;
|
Word32 mh;
|
||||||
@@ -41,18 +52,3 @@ Word32 Mpy_32_32(Word32 x, Word32 y)
|
|||||||
return (mh);
|
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
|
#ifndef __BASOP_MPY_H
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
#include "options.h"
|
#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
|
* Performs a multiplication of a 32-bit variable x by
|
||||||
* a 16-bit variable y, returning a 32-bit value.
|
* a 16-bit variable y, returning a 32-bit value.
|
||||||
*
|
*
|
||||||
@@ -21,18 +21,33 @@
|
|||||||
Word32 Mpy_32_16_1(Word32 x,
|
Word32 Mpy_32_16_1(Word32 x,
|
||||||
Word16 y);
|
Word16 y);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \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
|
* 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] x
|
||||||
* \param[i] y
|
* \param[i] y
|
||||||
*
|
*
|
||||||
* \return x*y
|
* \return x*y
|
||||||
*/
|
*/
|
||||||
Word32 Mpy_32_16_r(Word32 x,
|
Word32 Mpy_32_16(Word32 x,
|
||||||
Word16 y);
|
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
|
* \brief 32*32 Bit fractional Multiplication using 40 bit OPS
|
||||||
@@ -45,60 +60,8 @@ Word32 Mpy_32_16_r(Word32 x,
|
|||||||
*
|
*
|
||||||
* \return x*y
|
* \return x*y
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Word32 Mpy_32_32(Word32 x,
|
Word32 Mpy_32_32(Word32 x,
|
||||||
Word32 y);
|
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 */
|
#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__
|
#ifndef __BASOP_UTIL_H__
|
||||||
#define __BASOP_UTIL_H__
|
#define __BASOP_UTIL_H__
|
||||||
|
|
||||||
#include "stl.h"
|
#include "basop_settings.h"
|
||||||
#include "typedef.h"
|
#include "typedef.h"
|
||||||
#include "basop32.h"
|
#include "basop32.h"
|
||||||
#include "basop_mpy.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_SCALE (6)
|
||||||
|
|
||||||
#define LD_DATA_SHIFT_I5 (7)
|
#define LD_DATA_SHIFT_I5 (7)
|
||||||
|
|
||||||
#define modDiv2(x) sub(x,shl(shr(x,1),1))
|
#define modDiv2(x) sub(x,shl(shr(x,1),1))
|
||||||
#define modDiv8(x) L_sub(x,L_shl(L_shr(x,3),3))
|
#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)
|
static __inline Word16 limitScale16( Word16 s)
|
||||||
{
|
{
|
||||||
/* It is assumed, that s is calculated just before, therefore we can switch upon sign */
|
/* 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);
|
return (s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!**********************************************************************
|
/*!**********************************************************************
|
||||||
\brief Add two values given by mantissa and exponent.
|
\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 b_e, /*!< Exponent of 2nd operand b */
|
||||||
Word16 *ptrSum_m); /*!< Mantissa of result */
|
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 *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
|
\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 mantissa, /*!< input mantissa */
|
||||||
Word16 *exponent /*!< pointer to exponent */
|
Word16 *exponent /*!< pointer to exponent */
|
||||||
);
|
);
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
\brief Calculate the squareroot and inverse of squareroot of a number given by mantissa and 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 */
|
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 Word32 *x, /* i: array containing 32-bit data */
|
||||||
const Word16 len_x); /* i: length of the array to scan */
|
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
|
\brief Binary logarithm with 7 iterations
|
||||||
* \param pexponent pointer to the exponent.
|
|
||||||
* \return the normalized mantissa.
|
\param x
|
||||||
|
|
||||||
|
\return log2(x)/64
|
||||||
*/
|
*/
|
||||||
Word16 normalize16(Word16 mantissa, Word16 *pexponent);
|
/************************************************************************/
|
||||||
/****************************************************************************/
|
Word32 BASOP_Util_Log2(Word32 x);
|
||||||
/*!
|
|
||||||
\brief Does fractional integer division of Word32 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 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 y, /*!< i : Denominator*/
|
||||||
Word16 *s); /*!< o : Additional scalefactor difference*/
|
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
|
* \brief Binary logarithm with 5 iterations
|
||||||
|
*
|
||||||
\param x
|
* \param[i] val
|
||||||
|
*
|
||||||
\return log2(x)/64
|
* \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);
|
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 */
|
void set_val_Word16( Word16 X[], /*!< Address of array */
|
||||||
Word8 *dst, /*!< i : Destination address */
|
const Word16 val, /*!< Value to copy into array */
|
||||||
const Word32 n); /*!< i : Number of elements to copy */
|
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 */
|
void set_val_Word32( Word32 X[], /*!< Address of array */
|
||||||
Word32 n); /*!< i : Number of elements to set to zero */
|
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 mult0 ( Word16 x, /*!< i : Multiplier */
|
||||||
Word16 y); /*!< : Multiplicand */
|
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.
|
* \brief calculate cosine of angle. Tuned for ISF domain.
|
||||||
* \param theta Angle normalized to radix 2, theta = (angle in radians)*2.0/pi
|
* \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);
|
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
|
\brief 16/16->16 unsigned integer division
|
||||||
@@ -516,100 +252,7 @@ Word32 imult3216(Word32 x, Word16 y);
|
|||||||
|
|
||||||
Word16 idiv1616U(Word16 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)
|
* \brief return 2 ^ (exp * 2^exp_e)
|
||||||
* \param exp_m mantissa of the exponent to 2.0f
|
* \param exp_m mantissa of the exponent to 2.0f
|
||||||
@@ -623,26 +266,61 @@ Word32 BASOP_util_Pow2(
|
|||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
/* deprecated, use ISqrt32norm! */
|
Word32 Isqrt_lc1(
|
||||||
Word32 Isqrt_lc(
|
Word32 frac, /* (i) Q31: normalized value (1.0 < frac <= 0.5) */
|
||||||
Word32 frac, /*!< (i) Q31: normalized value (1.0 < frac <= 0.5) */
|
Word16 * exp /* (i/o) : exponent (value = frac x 2^exponent) */
|
||||||
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 Calculates pow(2,x)
|
||||||
* \brief return (1/x) << s
|
___________________________________________________________________________
|
||||||
* \param x index of lookup table
|
| |
|
||||||
* \param s shift factor
|
| Function Name : Pow2() |
|
||||||
* \return Word16 value of (1/x) << s
|
| |
|
||||||
*/
|
| L_x = pow(2.0, exponant.fraction) (exponent = interger part) |
|
||||||
Word16 getNormReciprocalWord16Scale(Word16 x, Word16 s);
|
| = 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 */
|
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.
|
\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 */
|
Word32 b_m, /*!< i: Mantissa of 2nd operand b */
|
||||||
Word16 b_e, /*!< i: Exponent of 2nd operand b */
|
Word16 b_e, /*!< i: Exponent of 2nd operand b */
|
||||||
Word16 *ptr_e); /*!< o: exponent of result */
|
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
|
\brief Accumulates multiplications
|
||||||
|
|
||||||
Accumulates the elementwise multiplications of Word32 Array bufX32 with Word16 Array bufY16
|
Accumulates the elementwise multiplications of Word32 Array X with Word16 Array Y
|
||||||
pointed to by arg1 to arg4 including the corresponding exponents. Length of to be multiplied arrays is arg5,
|
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
|
\return Word32 result of accumulated multiplications over Word32 array arg1 and Word16 array arg2 and Word16 pointer
|
||||||
to exponent of the result
|
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 */
|
Word32 dotWord32_16_guards(const Word32 * X, const Word16 * Y, Word16 n, Word16 hr, Word16 * shift);
|
||||||
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 Sqrt_l(Word32 L_x, Word16 *exp);
|
||||||
|
|
||||||
#endif /* __BASOP_UTIL_H__ */
|
#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 */
|
* bitalloc()
|
||||||
Word16 *idx, /* i : reordered sub-vector indices Q0 */
|
*
|
||||||
Word16 sum, /* i : number of available bits Q0 */
|
* Adaptive bit allocation for 20kHz audio codec
|
||||||
Word16 N, /* i : number of norms Q0 */
|
*--------------------------------------------------------------------------*/
|
||||||
Word16 K, /* i : maximum number of bits per dimension Q0 */
|
|
||||||
Word16 *r, /* o : bit-allacation vector Q0 */
|
void bitalloc (
|
||||||
const Word16 *sfmsize, /* i : band length Q0 */
|
short *y, /* i : reordered norm of sub-vectors */
|
||||||
const Word16 hqswb_clas /* i : signal classification flag Q0 */
|
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;
|
short i, j, k, n, m, v, im;
|
||||||
Word16 diff, temp;
|
short diff, temp;
|
||||||
Word16 fac;
|
short fac;
|
||||||
Word16 ii;
|
short ii;
|
||||||
Word16 SFM_thr = SFM_G1G2;
|
short SFM_thr = SFM_G1G2;
|
||||||
move16();
|
|
||||||
|
|
||||||
N = sub(N, 1);
|
N -= 1;
|
||||||
|
|
||||||
if ( sub(hqswb_clas, HQ_HARMONIC) == 0 )
|
if ( hqswb_clas == HQ_HARMONIC )
|
||||||
{
|
{
|
||||||
SFM_thr = 22;
|
SFM_thr = 22;
|
||||||
move16();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fac = 3;
|
fac = 3;
|
||||||
move16();
|
K -= 2;
|
||||||
K = sub(K,2);
|
|
||||||
im = 1;
|
im = 1;
|
||||||
move16();
|
|
||||||
diff = sum;
|
diff = sum;
|
||||||
move16();
|
n = sum >> 3;
|
||||||
n = shr(sum,3);
|
for ( i=0; i<n; i++ )
|
||||||
FOR ( i=0; i<n; i++ )
|
|
||||||
{
|
{
|
||||||
k = 0;
|
k = 0;
|
||||||
move16();
|
|
||||||
temp = y[0];
|
temp = y[0];
|
||||||
move16();
|
for (m=1; m<im; m++)
|
||||||
FOR ( m=1; m<im; m++)
|
|
||||||
{
|
{
|
||||||
v = sub( temp, y[m] );
|
if ( temp < y[m] )
|
||||||
temp = s_max(temp, y[m]);
|
|
||||||
if ( v < 0 )
|
|
||||||
{
|
{
|
||||||
|
temp = y[m];
|
||||||
k = m;
|
k = m;
|
||||||
move16();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
IF ( sub(temp, y[m]) < 0 )
|
if ( temp < y[m] )
|
||||||
{
|
{
|
||||||
k = m;
|
k = m;
|
||||||
move16();
|
if ( im < N)
|
||||||
if ( sub(im, N) < 0 )
|
|
||||||
{
|
{
|
||||||
im = add(im, 1);
|
im++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
j = idx[k];
|
j = idx[k];
|
||||||
move16();
|
if ( sum >= sfmsize[j] && r[j] < K )
|
||||||
|
|
||||||
test();
|
|
||||||
IF ( sub(sum,sfmsize[j]) >= 0 && sub(r[j],K) < 0 )
|
|
||||||
{
|
{
|
||||||
y[k] = sub(y[k], fac);
|
y[k] -= fac;
|
||||||
move16();
|
r[j]++;
|
||||||
r[j] = add(r[j], 1);
|
if ( r[j] >= K )
|
||||||
move16();
|
|
||||||
|
|
||||||
if ( sub(r[j], K) >= 0 )
|
|
||||||
{
|
{
|
||||||
y[k] = -32768;
|
y[k] = MIN16B;
|
||||||
move16();
|
|
||||||
}
|
}
|
||||||
sum = sub(sum,sfmsize[j]);
|
sum -= sfmsize[j];
|
||||||
}
|
}
|
||||||
ELSE
|
else
|
||||||
{
|
{
|
||||||
y[k] = -32768;
|
y[k] = MIN16B;
|
||||||
move16();
|
k++;
|
||||||
k = add(k, 1);
|
if ( k == im && im < N )
|
||||||
test();
|
|
||||||
if ( sub(k, im) == 0 && sub(im, N) < 0 )
|
|
||||||
{
|
{
|
||||||
im = add(im, 1);
|
im++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
test();
|
if ( sum < WID_G1 || diff == sum )
|
||||||
IF ( (sub(sum, WID_G1)<0) || (sub(diff, sum)==0) )
|
|
||||||
{
|
{
|
||||||
BREAK;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
diff = sum;
|
diff = sum;
|
||||||
move16();
|
v = N - 1;
|
||||||
v = sub(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 ( sum >= WID_G2)
|
||||||
IF ( sub(sum, WID_G2) >= 0 )
|
|
||||||
{
|
{
|
||||||
FOR (i=0; i<=N; i++)
|
for (i=0; i<=N; i++)
|
||||||
{
|
{
|
||||||
j = idx[i];
|
j = idx[i];
|
||||||
move16();
|
if ( j >= SFM_G1 && j < SFM_thr && r[j] == 0 )
|
||||||
test();
|
|
||||||
test();
|
|
||||||
IF ( sub(j, SFM_G1) >= 0 && sub(j, SFM_thr) < 0 && r[j] == 0 )
|
|
||||||
{
|
{
|
||||||
r[j] = 1;
|
r[j] = 1;
|
||||||
move16();
|
sum -= WID_G2;
|
||||||
sum = sub(sum, WID_G2);
|
if ( sum < WID_G2 )
|
||||||
IF (sub(sum, WID_G2) < 0)
|
|
||||||
{
|
{
|
||||||
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];
|
j = idx[i];
|
||||||
move16();
|
if ( j >= SFM_G1 && j < SFM_thr && r[j] == 1 )
|
||||||
test();
|
|
||||||
test();
|
|
||||||
IF ( sub(j,SFM_G1) >= 0 && sub(j, SFM_thr) < 0 && sub(r[j], 1) == 0 )
|
|
||||||
{
|
{
|
||||||
r[j] = 2;
|
r[j] = 2;
|
||||||
move16();
|
sum -= WID_G2;
|
||||||
sum = sub(sum, WID_G2);
|
if ( sum < WID_G2 )
|
||||||
IF ( sub(sum, WID_G2) < 0 )
|
|
||||||
{
|
{
|
||||||
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];
|
j = idx[i];
|
||||||
move16();
|
if ( j < SFM_G1 && r[j] == 0 )
|
||||||
test();
|
|
||||||
IF ( sub(j, SFM_G1) < 0 && r[j] == 0 )
|
|
||||||
{
|
{
|
||||||
r[j] = 1;
|
r[j] = 1;
|
||||||
move16();
|
sum -= WID_G1;
|
||||||
sum = sub(sum, WID_G1);
|
if ( sum < WID_G1 )
|
||||||
IF ( sub(sum, WID_G1) < 0 )
|
|
||||||
{
|
{
|
||||||
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];
|
j = idx[i];
|
||||||
move16();
|
if ( j < SFM_G1 && r[j] == 1 )
|
||||||
test();
|
|
||||||
IF ( sub(j, SFM_G1) < 0 && sub(r[j], 1) == 0 )
|
|
||||||
{
|
{
|
||||||
r[j] = 2;
|
r[j] = 2;
|
||||||
move16();
|
sum -= WID_G1;
|
||||||
sum = sub(sum, WID_G1);
|
if ( sum < WID_G1 )
|
||||||
IF ( sub(sum, WID_G1) < 0 )
|
|
||||||
{
|
{
|
||||||
BREAK;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -212,21 +184,22 @@ void bitalloc_fx (
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*-------------------------------------------------------------------*
|
/*-------------------------------------------------------------------*
|
||||||
* BitAllocF()
|
* BitAllocF()
|
||||||
*
|
*
|
||||||
* Fractional bit allocation
|
* Fractional bit allocation
|
||||||
*-------------------------------------------------------------------*/
|
*-------------------------------------------------------------------*/
|
||||||
|
|
||||||
Word16 BitAllocF_fx (
|
short BitAllocF (
|
||||||
Word16 *y, /* i : norm of sub-vectors :Q0 */
|
short *y, /* i : norm of sub-vectors */
|
||||||
Word32 bit_rate, /* i : bitrate :Q0 */
|
long bit_rate, /* i : bitrate */
|
||||||
Word16 B, /* i : number of available bits :Q0 */
|
short B, /* i : number of available bits */
|
||||||
Word16 N, /* i : number of sub-vectors :Q0 */
|
short N, /* i : number of sub-vectors */
|
||||||
Word16 *R, /* o : bit-allocation indicator :Q0 */
|
short *R, /* o : bit-allocation indicator */
|
||||||
Word16 *Rsubband_fx /* o : sub-band bit-allocation vector :Q3 */
|
short *Rsubband, /* o : sub-band bit-allocation vector (Q3) */
|
||||||
,const Word16 hqswb_clas, /* i : hq swb class :Q0 */
|
const short hqswb_clas, /* i : hq swb class */
|
||||||
const Word16 num_env_bands/* i : Number sub bands to be encoded for HF GNERIC :Q0 */
|
const short num_env_bands /* i : Number sub bands to be encoded for HQ_SWB_BWE */
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
Word16 fac;
|
Word16 fac;
|
||||||
@@ -234,55 +207,44 @@ Word16 BitAllocF_fx (
|
|||||||
|
|
||||||
Word16 m_fx;
|
Word16 m_fx;
|
||||||
Word32 t_fx, B_fx;
|
Word32 t_fx, B_fx;
|
||||||
Word32 L_tmp1, L_tmp2, L_tmp3;
|
Word32 L_tmp1, L_tmp2;
|
||||||
Word16 tmp, exp1, exp2;
|
Word16 tmp, exp1, exp2;
|
||||||
Word32 Rsubband_w32_fx[NB_SFM]; /* Q15 */
|
Word32 Rsubband_w32_fx[NB_SFM]; /* Q15 */
|
||||||
Word16 B_w16_fx;
|
Word16 B_w16_fx;
|
||||||
|
|
||||||
set32_fx( Rsubband_w32_fx, 0, NB_SFM);
|
set_i( Rsubband_w32_fx, 0, NB_SFM);
|
||||||
|
|
||||||
fac = 3;
|
fac = 3;
|
||||||
move16();
|
if (L_sub(bit_rate, 32000) < 0)
|
||||||
|
|
||||||
IF (L_sub(bit_rate, 32000) < 0)
|
|
||||||
{
|
{
|
||||||
bs = 2;
|
bs = 2;
|
||||||
move16();
|
|
||||||
}
|
}
|
||||||
ELSE
|
else
|
||||||
{
|
{
|
||||||
bs = 3;
|
bs = 3;
|
||||||
move16();
|
|
||||||
}
|
}
|
||||||
low_rate = 1;
|
low_rate = 1;
|
||||||
move16();
|
|
||||||
|
|
||||||
Nmin = N;
|
Nmin = N;
|
||||||
move16();
|
|
||||||
if ( sub(Nmin,SFM_N) > 0)
|
if ( sub(Nmin,SFM_N) > 0)
|
||||||
{
|
{
|
||||||
Nmin = SFM_N;
|
Nmin = SFM_N;
|
||||||
move16();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initial bits distribution */
|
/* 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 */
|
/* Initial bits distribution */
|
||||||
L_tmp1 = 0;
|
L_tmp1 = 0;
|
||||||
move16();
|
|
||||||
m_fx = 0;
|
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_mac0(L_tmp1, Nb[i], y[i]);
|
||||||
}
|
}
|
||||||
L_tmp1 = L_msu0(L_tmp1, fac, B);
|
L_tmp1 = L_msu0(L_tmp1, fac, B);
|
||||||
|
|
||||||
t_fx = L_deposit_l(0);
|
t_fx = 0;
|
||||||
n = 0;
|
n = 0;
|
||||||
move16();
|
|
||||||
tmp = add(band_end_HQ[num_env_bands-1], shl(band_end_HQ[num_env_bands-1], 1));
|
tmp = add(band_end_HQ[num_env_bands-1], shl(band_end_HQ[num_env_bands-1], 1));
|
||||||
exp1 = norm_s(tmp);
|
exp1 = norm_s(tmp);
|
||||||
tmp = div_s(16384, shl(tmp, exp1));/*15 + 14 - exp1*/
|
tmp = div_s(16384, shl(tmp, exp1));/*15 + 14 - exp1*/
|
||||||
@@ -290,65 +252,65 @@ Word16 BitAllocF_fx (
|
|||||||
tmp = shl(tmp, exp2);
|
tmp = shl(tmp, exp2);
|
||||||
exp1 = add(29, sub(exp2, exp1));
|
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);
|
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]);
|
Rsubband_w32_fx[i] = L_mult0(extract_l(L_tmp2), Nb[i]);
|
||||||
move32();/*Q0*/
|
move32();/*Q0*/
|
||||||
IF (Rsubband_w32_fx[i] > 0)
|
if (Rsubband_w32_fx[i] > 0)
|
||||||
{
|
{
|
||||||
n = add(n,Nb[i]);
|
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*/
|
move32();/*exp1 - 15*/
|
||||||
Rsubband_w32_fx[i] = L_shl(Rsubband_w32_fx[i], sub(30, exp1));/*Q15*/
|
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*/
|
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 */
|
/* Initial bits distribution */
|
||||||
L_tmp1 = 0;
|
L_tmp1 = 0;
|
||||||
move16();
|
|
||||||
m_fx = 0;
|
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_mac0(L_tmp1, Nb[i], y[i]);
|
||||||
}
|
}
|
||||||
L_tmp1 = L_msu0(L_tmp1, fac, B);
|
L_tmp1 = L_msu0(L_tmp1, fac, B);
|
||||||
|
|
||||||
|
|
||||||
t_fx = L_deposit_l(0);
|
t_fx = 0;
|
||||||
n = 0;
|
n = 0;
|
||||||
move16();
|
|
||||||
tmp = add(band_end_HQ[N-1], shl(band_end_HQ[N-1], 1));
|
tmp = add(band_end_HQ[N-1], shl(band_end_HQ[N-1], 1));
|
||||||
exp1 = norm_s(tmp);
|
exp1 = norm_s(tmp);
|
||||||
tmp = div_s(16384, shl(tmp, exp1));/*15 + 14 - exp1*/
|
tmp = div_s(16384, shl(tmp, exp1));/*15 + 14 - exp1*/
|
||||||
exp2 = norm_s(tmp);
|
exp2 = norm_s(tmp);
|
||||||
tmp = shl(tmp, exp2);
|
tmp = shl(tmp, exp2);
|
||||||
exp1 = add(29, sub(exp2, exp1));
|
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);
|
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]);
|
Rsubband_w32_fx[i] = L_mult0(extract_l(L_tmp2), Nb[i]);
|
||||||
move32();/*Q0*/
|
move32();/*Q0*/
|
||||||
IF (Rsubband_w32_fx[i] > 0)
|
if (Rsubband_w32_fx[i] > 0)
|
||||||
{
|
{
|
||||||
n = add(n,Nb[i]);
|
n = add(n,Nb[i]);
|
||||||
L_tmp3 = Mult_32_16(Rsubband_w32_fx[i], tmp); /*exp1 - 15*/
|
Rsubband_w32_fx[i] = Mpy_32_16(Rsubband_w32_fx[i], tmp);
|
||||||
Rsubband_w32_fx[i] = L_shl(L_tmp3, sub(30, exp1)); /*Q15*/ move32();
|
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*/
|
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*/
|
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*/
|
m_fx = shl(tmp, sub(exp2, exp1));/*Q14*/
|
||||||
|
|
||||||
t_fx = L_deposit_l(0);
|
t_fx = 0;
|
||||||
n = 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]);
|
Rsubband_w32_fx[i] = L_msu(Rsubband_w32_fx[i], m_fx, Nb[i]);
|
||||||
move32();
|
move32();
|
||||||
|
|
||||||
IF (Rsubband_w32_fx[i] > 0)
|
if (Rsubband_w32_fx[i] > 0)
|
||||||
{
|
{
|
||||||
n = add(n,Nb[i]);
|
n = add(n,Nb[i]);
|
||||||
|
|
||||||
t_fx = L_add(t_fx, Rsubband_w32_fx[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;
|
Bits = B;
|
||||||
move16();
|
|
||||||
|
|
||||||
/* Impose bit-constraints to subbands with less than minimum bits*/
|
/* Impose bit-constraints to subbands with less than minimum bits*/
|
||||||
t_fx = L_deposit_l(0);
|
t_fx = 0;
|
||||||
n = 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();
|
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]);
|
B = sub(B,Nb[i]);
|
||||||
Rsubband_w32_fx[i] = L_shl(Nb[i], 15);
|
Rsubband_w32_fx[i] = L_shl(Nb[i], 15);
|
||||||
move32();
|
move32();
|
||||||
}
|
}
|
||||||
ELSE
|
else
|
||||||
{
|
{
|
||||||
n = add(n,Nb[i]);
|
n = add(n,Nb[i]);
|
||||||
t_fx = L_add(t_fx, Rsubband_w32_fx[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_tmp1 = L_sub(t_fx, L_shl(B, 15));
|
||||||
L_tmp2 = L_abs(L_tmp1);
|
L_tmp2 = L_abs(L_tmp1);
|
||||||
|
|
||||||
if (n>0)
|
if( n>0 )
|
||||||
{
|
{
|
||||||
exp1 = sub(norm_l(L_tmp2), 1);
|
exp1 = sub(norm_l(L_tmp2), 1);
|
||||||
exp2 = norm_s(n);
|
exp2 = norm_s(n);
|
||||||
@@ -433,22 +395,20 @@ Word16 BitAllocF_fx (
|
|||||||
m_fx = negate(m_fx);
|
m_fx = negate(m_fx);
|
||||||
}
|
}
|
||||||
|
|
||||||
t_fx = L_deposit_l(0);
|
t_fx = 0;
|
||||||
n = 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]);
|
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]);
|
n = add(n,Nb[i]);
|
||||||
|
|
||||||
t_fx = L_add(t_fx, Rsubband_w32_fx[i]);
|
t_fx = L_add(t_fx, Rsubband_w32_fx[i]);
|
||||||
}
|
}
|
||||||
ELSE
|
else
|
||||||
{
|
{
|
||||||
B = sub(B,Nb[i]);
|
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 */
|
/*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] );
|
B = add( B, Nb[i] );
|
||||||
Rsubband_w32_fx[i] = L_deposit_l(0);
|
Rsubband_w32_fx[i] = 0;
|
||||||
IF ( B >= 0)
|
move32();
|
||||||
|
if ( B >= 0)
|
||||||
{
|
{
|
||||||
BREAK;
|
BREAK;
|
||||||
}
|
}
|
||||||
@@ -479,60 +440,56 @@ Word16 BitAllocF_fx (
|
|||||||
|
|
||||||
/* fine redistribution of over-allocated or under-allocated bits */
|
/* fine redistribution of over-allocated or under-allocated bits */
|
||||||
tmp = 0;
|
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));
|
Rsubband[i] = extract_l(L_shr(Rsubband_w32_fx[i], 12));
|
||||||
tmp = add(tmp, Rsubband_fx[i]);
|
tmp = add(tmp, Rsubband[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
B = Bits;
|
B = Bits;
|
||||||
B_w16_fx = shl(B, 3);
|
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);
|
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);
|
Rsubband[i] = sub(Rsubband[i], tmp);
|
||||||
move16();
|
|
||||||
BREAK;
|
BREAK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ELSE
|
else
|
||||||
{
|
{
|
||||||
tmp = sub(tmp, B_w16_fx);
|
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);
|
Rsubband[i] = sub(Rsubband[i], tmp);
|
||||||
move16();
|
|
||||||
BREAK;
|
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;
|
tmp = 0;
|
||||||
move16();
|
for ( i = 0; i < N; i++)
|
||||||
FOR ( i = 0; i < N; i++)
|
|
||||||
{
|
{
|
||||||
tmp = add(tmp, Rsubband_fx[i]);
|
tmp = add(tmp, Rsubband[i]);
|
||||||
R[i] = shr(Rsubband_fx[i], 3);
|
R[i] = shr(Rsubband[i], 3);
|
||||||
move16();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return shr(tmp, 3);
|
return shr(tmp, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-------------------------------------------------------------------*
|
/*-------------------------------------------------------------------*
|
||||||
* Bit_group()
|
* Bit_group()
|
||||||
*
|
*
|
||||||
* bit allocation in group
|
* bit allocation in group
|
||||||
*-------------------------------------------------------------------*/
|
*-------------------------------------------------------------------*/
|
||||||
static
|
static void Bit_group_fx (
|
||||||
void Bit_group_fx (
|
|
||||||
Word16 *y, /* i : norm of sub-band Q0*/
|
Word16 *y, /* i : norm of sub-band Q0*/
|
||||||
Word16 start_band, /* i : start band indices Q0*/
|
Word16 start_band, /* i : start band indices Q0*/
|
||||||
Word16 end_band, /* i : end band indices Q0*/
|
Word16 end_band, /* i : end band indices Q0*/
|
||||||
@@ -547,21 +504,22 @@ void Bit_group_fx (
|
|||||||
Word16 factor_fx;
|
Word16 factor_fx;
|
||||||
Word32 R_temp_fx[16], R_sum_fx = 0, R_sum_org_fx = 0, Bits_avg_fx = 0;
|
Word32 R_temp_fx[16], R_sum_fx = 0, R_sum_org_fx = 0, Bits_avg_fx = 0;
|
||||||
Word32 L_tmp;
|
Word32 L_tmp;
|
||||||
|
UWord32 lo;
|
||||||
|
|
||||||
/* initialization for bit allocation in one group*/
|
/* initialization for bit allocation in one group*/
|
||||||
tmp = 6554;
|
tmp = 6554;
|
||||||
move16(); /*Q15 1/5 */
|
move16(); /*Q15 1/5 */
|
||||||
if(sub(thr,5) == 0)
|
IF(sub(thr,5) == 0)
|
||||||
{
|
{
|
||||||
tmp = 6554;
|
tmp = 6554;
|
||||||
move16(); /*Q15 1/5 */
|
move16(); /*Q15 1/5 */
|
||||||
}
|
}
|
||||||
if(sub(thr,6) == 0)
|
IF(sub(thr,6) == 0)
|
||||||
{
|
{
|
||||||
tmp = 5462;
|
tmp = 5462;
|
||||||
move16();/*Q15 1/6 */
|
move16();/*Q15 1/6 */
|
||||||
}
|
}
|
||||||
if(sub(thr,7) == 0)
|
IF(sub(thr,7) == 0)
|
||||||
{
|
{
|
||||||
tmp = 4682;
|
tmp = 4682;
|
||||||
move16();/*Q15 1/7 */
|
move16();/*Q15 1/7 */
|
||||||
@@ -578,7 +536,7 @@ void Bit_group_fx (
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Rearrange norm vector in decreasing order */
|
/* Rearrange norm vector in decreasing order */
|
||||||
reordvct_fx(y_index, band_num, index);
|
reordvct(y_index, band_num, index);
|
||||||
/* norm vector modification */
|
/* norm vector modification */
|
||||||
|
|
||||||
factor_fx = div_s(1, band_num);/*Q15 */
|
factor_fx = div_s(1, band_num);/*Q15 */
|
||||||
@@ -612,7 +570,7 @@ void Bit_group_fx (
|
|||||||
{
|
{
|
||||||
FOR ( j = 0; j < band_num; j++)
|
FOR ( j = 0; j < band_num; j++)
|
||||||
{
|
{
|
||||||
if ( y_index[j] < 0 )
|
IF ( y_index[j] < 0 )
|
||||||
{
|
{
|
||||||
y_index[j] = 0;
|
y_index[j] = 0;
|
||||||
move16();
|
move16();
|
||||||
@@ -634,7 +592,8 @@ void Bit_group_fx (
|
|||||||
{
|
{
|
||||||
FOR (k = 0; k <= i; k++)
|
FOR (k = 0; k <= i; k++)
|
||||||
{
|
{
|
||||||
R_temp_fx[k] = L_deposit_h(0);/*Q21 */
|
R_temp_fx[k] = 0;
|
||||||
|
move32();/*Q21 */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ELSE
|
ELSE
|
||||||
@@ -647,7 +606,7 @@ void Bit_group_fx (
|
|||||||
FOR (k = 0; k <= i; k++)
|
FOR (k = 0; k <= i; k++)
|
||||||
{
|
{
|
||||||
L_tmp = L_shl(L_deposit_l(y_index[k]),24);
|
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));
|
R_temp_fx[k] = L_shl(L_tmp,sub(exp,2));
|
||||||
move32();/*Q21 */
|
move32();/*Q21 */
|
||||||
@@ -657,7 +616,8 @@ void Bit_group_fx (
|
|||||||
L_tmp = L_shl(L_deposit_l(thr),21);/*Q21 */
|
L_tmp = L_shl(L_deposit_l(thr),21);/*Q21 */
|
||||||
IF ( L_sub(R_temp_fx[i],L_tmp) < 0 )
|
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]);
|
norm_sum = sub(norm_sum,y_index[i]);
|
||||||
i--;
|
i--;
|
||||||
}
|
}
|
||||||
@@ -671,7 +631,7 @@ void Bit_group_fx (
|
|||||||
{
|
{
|
||||||
FOR ( j = 0; j < bit_band; j++ )
|
FOR ( j = 0; j < bit_band; j++ )
|
||||||
{
|
{
|
||||||
if ( y_index[j] < 0 )
|
IF ( y_index[j] < 0 )
|
||||||
{
|
{
|
||||||
y_index[j] = 0;
|
y_index[j] = 0;
|
||||||
move16();
|
move16();
|
||||||
@@ -682,7 +642,8 @@ void Bit_group_fx (
|
|||||||
|
|
||||||
FOR ( j = bit_band; j < band_num; j++ )
|
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;
|
norm_sum = 0;
|
||||||
@@ -698,7 +659,8 @@ void Bit_group_fx (
|
|||||||
{
|
{
|
||||||
FOR (k = 0; k < i; k++)
|
FOR (k = 0; k < i; k++)
|
||||||
{
|
{
|
||||||
R_temp_fx[k] = L_deposit_l(0); /*Q21 */
|
R_temp_fx[k] = 0;
|
||||||
|
move32();/*Q21 */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ELSE
|
ELSE
|
||||||
@@ -710,8 +672,7 @@ void Bit_group_fx (
|
|||||||
FOR (k = 0; k < i; k++)
|
FOR (k = 0; k < i; k++)
|
||||||
{
|
{
|
||||||
L_tmp = L_shl(L_deposit_l(y_index[k]),24);
|
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));
|
R_temp_fx[k] = L_shl(L_tmp,sub(exp,2));
|
||||||
move32();/*Q21 */
|
move32();/*Q21 */
|
||||||
}
|
}
|
||||||
@@ -725,7 +686,8 @@ void Bit_group_fx (
|
|||||||
FOR(m = k; m < i; m++)
|
FOR(m = k; m < i; m++)
|
||||||
{
|
{
|
||||||
norm_sum = sub(norm_sum,y_index[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;
|
i = k;
|
||||||
BREAK;
|
BREAK;
|
||||||
@@ -763,12 +725,12 @@ void Bit_group_fx (
|
|||||||
* WB bit allocation
|
* WB bit allocation
|
||||||
*-------------------------------------------------------------------*/
|
*-------------------------------------------------------------------*/
|
||||||
|
|
||||||
Word16 BitAllocWB_fx( /* o : t Q0*/
|
short BitAllocWB (
|
||||||
Word16 *y, /* i : norm of sub-vectors Q0*/
|
short *y, /* i : norm of sub-vectors */
|
||||||
Word16 B, /* i : number of available bits Q0*/
|
short B, /* i : number of available bits */
|
||||||
Word16 N, /* i : number of sub-vectors Q0*/
|
short N, /* i : number of sub-vectors */
|
||||||
Word16 *R, /* o : bit-allocation indicator Q0*/
|
short *R, /* o : bit-allocation indicator */
|
||||||
Word16 *Rsubband_fx /* o : sub-band bit-allocation vector Q3*/
|
short *Rsubband /* o : sub-band bit-allocation vector (Q3) */
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
Word16 t_fx;
|
Word16 t_fx;
|
||||||
@@ -778,13 +740,13 @@ Word16 BitAllocWB_fx( /* o : t
|
|||||||
Word16 factor_fx[2];/*Q13 */
|
Word16 factor_fx[2];/*Q13 */
|
||||||
Word16 BANDS;
|
Word16 BANDS;
|
||||||
Word16 tmp,exp;
|
Word16 tmp,exp;
|
||||||
Word16 Rsum_sub_fx_tmp=0; /* initialize just to avoid compiler warning */
|
|
||||||
Word32 L_tmp,L_tmp1;
|
Word32 L_tmp,L_tmp1;
|
||||||
Word32 Rsubband_buf[NB_SFM];
|
Word32 Rsubband_buf[NB_SFM];
|
||||||
|
UWord16 lo;
|
||||||
|
|
||||||
BANDS = N;
|
BANDS = N;
|
||||||
move16();
|
move16();
|
||||||
if( sub(BANDS,SFM_N) > 0)
|
IF( sub(BANDS,SFM_N) > 0)
|
||||||
{
|
{
|
||||||
BANDS = SFM_N;
|
BANDS = SFM_N;
|
||||||
move16();
|
move16();
|
||||||
@@ -797,49 +759,36 @@ Word16 BitAllocWB_fx( /* o : t
|
|||||||
}
|
}
|
||||||
/* Calculate the norm sum and average of sub-band */
|
/* Calculate the norm sum and average of sub-band */
|
||||||
Rsum_sub_fx[0] = 0;
|
Rsum_sub_fx[0] = 0;
|
||||||
move16();
|
|
||||||
FOR ( j = 0; j < SFM_G1; j++ )
|
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 */
|
Rsum_sub_fx[0] = add(Rsum_sub_fx[0],y[j]);
|
||||||
}
|
|
||||||
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;
|
|
||||||
move16();/*Q0 */
|
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;
|
Rsum_sub_fx[2] = 0;
|
||||||
move16();
|
move16();
|
||||||
FOR ( j = SFM_G1G2; j < BANDS; j++ )
|
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 */
|
Rsum_sub_fx[2] = add(Rsum_sub_fx[2],y[j]);
|
||||||
}
|
|
||||||
if ( y[j] > 0 )
|
|
||||||
{
|
|
||||||
Rsum_sub_fx[2] = Rsum_sub_fx_tmp;
|
|
||||||
move16();/*Q0 */
|
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]);
|
R_diff_32_fx[1] = L_sub(Ravg_sub_32_fx[1], Ravg_sub_32_fx[2]);
|
||||||
move32();/*Q16 */
|
move32();/*Q16 */
|
||||||
|
|
||||||
test();
|
|
||||||
IF ( L_sub(R_diff_32_fx[0],393216) < 0 && L_sub(R_diff_32_fx[1],245760) < 0 )
|
IF ( L_sub(R_diff_32_fx[0],393216) < 0 && L_sub(R_diff_32_fx[1],245760) < 0 )
|
||||||
{
|
{
|
||||||
IF(Rsum_fx == 0)
|
IF(Rsum_fx == 0)
|
||||||
@@ -877,26 +825,23 @@ Word16 BitAllocWB_fx( /* o : t
|
|||||||
tmp = shl(Rsum_fx,exp);/*Q(exp) */
|
tmp = shl(Rsum_fx,exp);/*Q(exp) */
|
||||||
tmp = div_s(16384,tmp);/*Q(15+14-exp) */
|
tmp = div_s(16384,tmp);/*Q(15+14-exp) */
|
||||||
L_tmp1 = L_mult(B,Rsum_sub_fx[0]);/*Q1 */
|
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 */
|
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);
|
B1 = add(B1,1);
|
||||||
}
|
}
|
||||||
L_tmp1 = L_mult(B,Rsum_sub_fx[1]);/*Q1 */
|
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 */
|
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);
|
B2 = add(B2,1);
|
||||||
}
|
}
|
||||||
L_tmp1 = L_mult(B,Rsum_sub_fx[2]);/*Q1 */
|
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 */
|
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);
|
B3 = add(B3,1);
|
||||||
}
|
}
|
||||||
@@ -977,19 +922,17 @@ Word16 BitAllocWB_fx( /* o : t
|
|||||||
tmp = shl(Rsum_fx,exp);/*Q(exp) */
|
tmp = shl(Rsum_fx,exp);/*Q(exp) */
|
||||||
tmp = div_s(16384,tmp);/*Q(15+14-exp) */
|
tmp = div_s(16384,tmp);/*Q(15+14-exp) */
|
||||||
L_tmp1 = L_mult(B,Rsum_sub_fx[0]);/*Q1 */
|
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 */
|
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);
|
B1 = add(B1,1);
|
||||||
}
|
}
|
||||||
L_tmp1 = Mult_32_16(1975684956,shl(B,5));/*Q(31+5-15=21) */
|
Mpy_32_16_ss(1975684956,shl(B,5),&L_tmp1,&lo);
|
||||||
L_tmp1 = Mult_32_16(L_tmp1,shl(Rsum_sub_fx[1],7));/*Q(21+7-15=13) */
|
Mpy_32_16_ss(L_tmp1,shl(Rsum_sub_fx[1],7),&L_tmp1,&lo);
|
||||||
L_tmp = Mult_32_16(L_tmp1,tmp);/*Q(27-exp) */
|
Mpy_32_16_ss(L_tmp1,tmp,&L_tmp,&lo);
|
||||||
B2 = extract_h(L_shl(L_tmp,sub(exp,11)));/*Q0 */
|
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);
|
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);
|
Bit_group_fx( y, SFM_G1G2, BANDS, B3, 7, Rsubband_buf, factor_fx);
|
||||||
FOR (i = 0; i < BANDS; i++)
|
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 */
|
/* 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++)
|
FOR( i = 0; i < N; i++)
|
||||||
{
|
{
|
||||||
L_tmp = L_add(L_tmp,Rsubband_buf[i]);/*Q21 */
|
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 */
|
t_fx = extract_h(L_shr(L_tmp, 5)); /*Q0 */
|
||||||
|
|
||||||
return (Word16)t_fx;
|
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 <stdlib.h>
|
||||||
|
#include <math.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include "options.h"
|
#include "options.h"
|
||||||
#include "prot_fx.h"
|
#include "rom_com.h"
|
||||||
#include "basop_util.h"
|
#include "prot.h"
|
||||||
#include "stl.h"
|
|
||||||
#include "options.h"
|
/*-------------------------------------------------------------------*
|
||||||
#include "rom_com_fx.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()
|
* BITS_ALLOC_init_config_acelp()
|
||||||
*
|
*
|
||||||
* description: initial configuration for ACELP
|
* initial configuration for Mode 2 ACELP
|
||||||
*
|
*--------------------------------------------------------------------*/
|
||||||
* return: void
|
|
||||||
*/
|
|
||||||
void BITS_ALLOC_init_config_acelp(
|
void BITS_ALLOC_init_config_acelp(
|
||||||
const Word32 bit_rate,
|
int bit_rate,
|
||||||
const Word8 narrowBand,
|
int narrowBand,
|
||||||
const Word16 nb_subfr,
|
int nb_subfr,
|
||||||
ACELP_config *pConfigAcelp /*o: configuration structure of ACELP*/
|
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();
|
acelp_cfg->mode_index=rate_mode_index;
|
||||||
move16();
|
|
||||||
move16();
|
|
||||||
rate_mode_index=(bit_rate > ACELP_9k60);
|
|
||||||
|
|
||||||
pConfigAcelp->mode_index=rate_mode_index;
|
|
||||||
|
|
||||||
|
|
||||||
/*LPC: midLpc should be swithced off?*/
|
/*LPC: midLpc should be swithced off?*/
|
||||||
pConfigAcelp->midLpc_enable = 1;
|
acelp_cfg->midLpc_enable = 1;
|
||||||
move16();
|
|
||||||
|
|
||||||
/*ACELP ICB config*/
|
/*ACELP ICB config*/
|
||||||
test();
|
if( (rate_mode_index==0) || (narrowBand==1) )
|
||||||
IF( (rate_mode_index==0) || narrowBand != 0 )
|
|
||||||
{
|
{
|
||||||
move16();
|
acelp_cfg->pre_emphasis = 1;
|
||||||
move16();
|
acelp_cfg->formant_enh = 1;
|
||||||
move16();
|
acelp_cfg->formant_enh_num = FORMANT_SHARPENING_G1;
|
||||||
move16();
|
acelp_cfg->formant_enh_den = FORMANT_SHARPENING_G2;
|
||||||
move16();
|
acelp_cfg->formant_tilt = 0;
|
||||||
move16();
|
acelp_cfg->voice_tilt = 0;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
ELSE
|
else
|
||||||
{
|
{
|
||||||
move16();
|
acelp_cfg->pre_emphasis = 0;
|
||||||
move16();
|
acelp_cfg->formant_enh = 1;
|
||||||
move16();
|
acelp_cfg->formant_enh_num = FORMANT_SHARPENING_G1;
|
||||||
move16();
|
acelp_cfg->formant_enh_den = FORMANT_SHARPENING_G2;
|
||||||
move16();
|
acelp_cfg->formant_tilt = 1;
|
||||||
move16();
|
acelp_cfg->voice_tilt = 1;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*Wide band @ 16kHz*/
|
/*Wide band @ 16kHz*/
|
||||||
IF ( sub(nb_subfr,NB_SUBFR16k) == 0 )
|
if ( nb_subfr == NB_SUBFR16k )
|
||||||
{
|
{
|
||||||
move16();
|
acelp_cfg->pre_emphasis = 1;
|
||||||
move16();
|
acelp_cfg->formant_enh = 1;
|
||||||
move16();
|
acelp_cfg->formant_enh_num = FORMANT_SHARPENING_G1_16k;
|
||||||
move16();
|
acelp_cfg->formant_enh_den = FORMANT_SHARPENING_G2_16k;
|
||||||
move16();
|
acelp_cfg->formant_tilt = 0;
|
||||||
move16();
|
acelp_cfg->voice_tilt = 2;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------*
|
||||||
|
* BITS_ALLOC_config_acelp()
|
||||||
|
*
|
||||||
|
* configure all Mode 2 ACELP modes and allocate the bits
|
||||||
|
*--------------------------------------------------------------------*/
|
||||||
|
|
||||||
/*
|
int BITS_ALLOC_config_acelp(
|
||||||
* function BITS_ALLOC_config_acelp()
|
const int bits_frame, /* i : remaining bit budget for the frame */
|
||||||
*
|
const short coder_type, /* i : acelp extended mode index */
|
||||||
* description: configure all acelp modes and allocate the bits
|
ACELP_config *acelp_cfg, /* i/o: configuration structure of ACELP */
|
||||||
*
|
const short narrowBand, /* i : narrowband flag */
|
||||||
* return: bit demand
|
const short nb_subfr /* i : number of subframes */
|
||||||
*/
|
|
||||||
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
|
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
Word16 mode_index;
|
short mode_index;
|
||||||
Word16 band_index;
|
short band_index;
|
||||||
Word16 i;
|
short i;
|
||||||
Word16 remaining_bits, bits;
|
short remaining_bits, bits;
|
||||||
|
|
||||||
|
/*Sanity check*/
|
||||||
|
|
||||||
|
mode_index = acelp_cfg->mode_index;
|
||||||
move16();
|
|
||||||
move16();
|
|
||||||
move16();
|
|
||||||
mode_index = pConfigAcelp->mode_index;
|
|
||||||
band_index = (narrowBand==0);
|
band_index = (narrowBand==0);
|
||||||
bits=0;
|
bits = 0;
|
||||||
|
|
||||||
IF ( band_index==0 )
|
if ( band_index==0 )
|
||||||
{
|
{
|
||||||
move16();
|
if(coder_type == INACTIVE)
|
||||||
pConfigAcelp->formant_enh = 1;
|
|
||||||
if(sub(coder_type,INACTIVE) == 0)
|
|
||||||
{
|
{
|
||||||
move16();
|
acelp_cfg->formant_enh = 0;
|
||||||
pConfigAcelp->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;
|
acelp_cfg->pre_emphasis = 0;
|
||||||
move16();
|
acelp_cfg->formant_enh = 0;
|
||||||
pConfigAcelp->formant_enh = 0;
|
acelp_cfg->formant_enh_num = FORMANT_SHARPENING_G1_16k;
|
||||||
move16();
|
acelp_cfg->formant_tilt = 1;
|
||||||
pConfigAcelp->formant_enh_num = FORMANT_SHARPENING_G1_16k;
|
acelp_cfg->voice_tilt = 1;
|
||||||
move16();
|
|
||||||
pConfigAcelp->voice_tilt = 1;
|
|
||||||
move16();
|
|
||||||
pConfigAcelp->formant_tilt = 1;
|
|
||||||
move16();
|
|
||||||
}
|
}
|
||||||
ELSE
|
else
|
||||||
{
|
{
|
||||||
pConfigAcelp->pre_emphasis = 1;
|
acelp_cfg->pre_emphasis = 1;
|
||||||
move16();
|
acelp_cfg->formant_enh = 1;
|
||||||
pConfigAcelp->formant_enh = 1;
|
acelp_cfg->formant_enh_num = FORMANT_SHARPENING_G1;
|
||||||
move16();
|
acelp_cfg->formant_tilt = 0;
|
||||||
pConfigAcelp->formant_enh_num = FORMANT_SHARPENING_G1;
|
acelp_cfg->voice_tilt = 0;
|
||||||
move16();
|
|
||||||
pConfigAcelp->voice_tilt = 0;
|
|
||||||
move16();
|
|
||||||
pConfigAcelp->formant_tilt = 0;
|
|
||||||
move16();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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;
|
if( ACELP_GAINS_MODE[mode_index][band_index][coder_type]==6 )
|
||||||
pConfigAcelp->phase_scrambling = 0;
|
{
|
||||||
|
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*/
|
/*Allocate bits and different modes*/
|
||||||
move16();
|
acelp_cfg->bpf_mode=ACELP_BPF_MODE[mode_index][band_index][coder_type];
|
||||||
pConfigAcelp->bpf_mode=ACELP_BPF_MODE[mode_index][band_index][coder_type];
|
bits+=ACELP_BPF_BITS[acelp_cfg->bpf_mode];
|
||||||
bits = add(bits, ACELP_BPF_BITS[pConfigAcelp->bpf_mode]);
|
|
||||||
|
|
||||||
move16();
|
acelp_cfg->nrg_mode=ACELP_NRG_MODE[mode_index][band_index][coder_type];
|
||||||
move16();
|
acelp_cfg->nrg_bits=ACELP_NRG_BITS[acelp_cfg->nrg_mode];
|
||||||
pConfigAcelp->nrg_mode=ACELP_NRG_MODE[mode_index][band_index][coder_type];
|
bits+=acelp_cfg->nrg_bits;
|
||||||
pConfigAcelp->nrg_bits=ACELP_NRG_BITS[pConfigAcelp->nrg_mode];
|
|
||||||
bits = add(bits, pConfigAcelp->nrg_bits);
|
|
||||||
|
|
||||||
move16();
|
acelp_cfg->ltp_mode=ACELP_LTP_MODE[mode_index][band_index][coder_type];
|
||||||
pConfigAcelp->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();
|
if( nb_subfr == NB_SUBFR16k && acelp_cfg->ltf_bits == 4 )
|
||||||
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) )
|
|
||||||
{
|
{
|
||||||
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];
|
acelp_cfg->gains_mode[i] = ACELP_GAINS_MODE[mode_index][band_index][coder_type];
|
||||||
move16();
|
|
||||||
|
|
||||||
/* skip subframe 1, 3 gain encoding, and use from subframe 0, and 3, respectively */
|
/* skip subframe 1, 3 gain encoding, and use from subframe 0, and 3, respectively */
|
||||||
test();
|
if(coder_type >= ACELP_MODE_MAX && (i == 1 || i == 3))
|
||||||
test();
|
|
||||||
IF(sub(coder_type,ACELP_MODE_MAX) >= 0 && (sub(i,1) == 0 || sub(i,3) == 0))
|
|
||||||
{
|
{
|
||||||
pConfigAcelp->gains_mode[i] = 0;
|
acelp_cfg->gains_mode[i] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bits = add(bits, ACELP_GAINS_BITS[pConfigAcelp->gains_mode[i]]);
|
bits += ACELP_GAINS_BITS[acelp_cfg->gains_mode[i]];
|
||||||
|
bits += ACELP_LTP_BITS_SFR[acelp_cfg->ltp_mode][i];
|
||||||
move16();
|
acelp_cfg->ltp_bits += ACELP_LTP_BITS_SFR[acelp_cfg->ltp_mode][i];
|
||||||
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]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*Innovation*/
|
/*Innovation*/
|
||||||
|
if( bits_frame < bits )
|
||||||
if ( sub(bits_frame,bits) < 0)
|
|
||||||
{
|
{
|
||||||
printf("Warning: bits per frame too low\n");
|
printf("\nWarning: bits per frame too low\n");
|
||||||
return -1;
|
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 */
|
acelp_cfg->fixed_cdk_index[0] = 0; /* 7 bits */
|
||||||
pConfigAcelp->fixed_cdk_index[1] = -1;
|
acelp_cfg->fixed_cdk_index[1] = -1;
|
||||||
pConfigAcelp->fixed_cdk_index[2] = 0; /* 7 bits */
|
acelp_cfg->fixed_cdk_index[2] = 0; /* 7 bits */
|
||||||
pConfigAcelp->fixed_cdk_index[3] = -1;
|
acelp_cfg->fixed_cdk_index[3] = -1;
|
||||||
pConfigAcelp->fixed_cdk_index[4] = -1;
|
acelp_cfg->fixed_cdk_index[4] = -1;
|
||||||
bits = add(bits,14);
|
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);
|
set_i(acelp_cfg->fixed_cdk_index, 0, nb_subfr);
|
||||||
bits = add(bits,28);
|
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*/
|
/*Sanity check*/
|
||||||
if (remaining_bits<0)
|
if( remaining_bits < 0 )
|
||||||
{
|
{
|
||||||
move16();
|
|
||||||
bits = -1;
|
bits = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return(bits);
|
return( bits );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------*
|
||||||
|
* BITS_ALLOC_adjust_acelp_fixed_cdk()
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*--------------------------------------------------------------------*/
|
||||||
|
|
||||||
static
|
static int BITS_ALLOC_adjust_acelp_fixed_cdk(
|
||||||
Word16 BITS_ALLOC_adjust_generic(
|
int bits_frame, /*i: bit budget*/
|
||||||
const Word16 bits_frame, /*i: bit budget*/
|
int *fixed_cdk_index,
|
||||||
Word16 *fixed_cdk_index,
|
int nb_subfr
|
||||||
const Word16 nb_subfr,
|
|
||||||
const Word16 *pulseconfigbits,
|
|
||||||
const Word16 pulseconfig_size
|
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
Word16 bits_subframe2, inb_subfr;
|
int bits_subframe2;
|
||||||
Word16 sfr, k, bitsused, bits_currsubframe;
|
int sfr, k, bitsused, bits_currsubframe;
|
||||||
|
|
||||||
bits_subframe2 = bits_frame;
|
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 */
|
/* 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 (ACELP_FIXED_CDK_BITS(k)*nb_subfr > bits_subframe2)
|
||||||
IF (i_mult2(pulseconfigbits[k], nb_subfr) > bits_subframe2)
|
|
||||||
{
|
{
|
||||||
k = sub(k,1); /* previous mode did not exceed bit-budget */
|
k--; /* previous mode did not exceed bit-budget */
|
||||||
BREAK;
|
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;
|
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 = (sfr*bits_subframe2 + bits_subframe2) - bitsused*nb_subfr;
|
||||||
bits_currsubframe = sub(add(i_mult2(sfr, bits_subframe2), bits_subframe2), bitsused);
|
|
||||||
|
|
||||||
/* try increasing mode while below threshold */
|
/* 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++;
|
||||||
k = add(k,1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* try decreasing mode until below threshold */
|
/* 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);
|
k--;
|
||||||
|
if ( k == 0 )
|
||||||
IF (k == 0)
|
|
||||||
{
|
{
|
||||||
BREAK;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* store mode */
|
/* store mode */
|
||||||
move16();
|
|
||||||
fixed_cdk_index[sfr] = k;
|
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;
|
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 <math.h>
|
||||||
#include "prot_fx.h"
|
#include "prot.h"
|
||||||
#include "options.h"
|
#include "options.h"
|
||||||
|
|
||||||
#include "stl.h"
|
/*-------------------------------------------------------------------*
|
||||||
#include "prot_fx.h"
|
* tcxGetNoiseFillingTilt()
|
||||||
#include "basop_util.h"
|
*
|
||||||
#include "rom_basop_util.h"
|
*
|
||||||
#define inv_int InvIntTable
|
*-------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
int tcxGetNoiseFillingTilt(
|
||||||
|
float A[],
|
||||||
Word16 tcxGetNoiseFillingTilt(Word16 A[], Word16 lpcorder, Word16 L_frame, Word16 mode, Word16 *noiseTiltFactor)
|
int L_frame,
|
||||||
|
int mode,
|
||||||
|
float *noiseTiltFactor
|
||||||
|
)
|
||||||
{
|
{
|
||||||
Word16 firstLine;
|
int firstLine;
|
||||||
Word32 tmp;
|
|
||||||
Word16 As[M+1];
|
|
||||||
|
|
||||||
|
if (mode)
|
||||||
IF (mode != 0)
|
|
||||||
{
|
{
|
||||||
firstLine = idiv1616U(L_frame, 6);
|
firstLine = L_frame / 6;
|
||||||
*noiseTiltFactor = 18432/*0.5625f Q15*/;
|
*noiseTiltFactor = 0.5625f;
|
||||||
move16();
|
|
||||||
}
|
}
|
||||||
ELSE
|
else
|
||||||
{
|
{
|
||||||
firstLine = shr(L_frame, 3);
|
firstLine = L_frame / 8;
|
||||||
|
*noiseTiltFactor = get_gain( A+1, A, M, NULL );
|
||||||
Copy_Scale_sig( A, As, lpcorder+1, sub(norm_s(A[0]),2) );
|
*noiseTiltFactor = min(1.0f, (*noiseTiltFactor) + 0.09375f);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return firstLine;
|
return firstLine;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------*
|
||||||
|
* tcxFormantEnhancement()
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*-------------------------------------------------------------------*/
|
||||||
|
|
||||||
void tcxFormantEnhancement(
|
void tcxFormantEnhancement(
|
||||||
Word16 xn_buf[],
|
float xn_buf[],
|
||||||
Word16 gainlpc[], Word16 gainlpc_e[],
|
float gainlpc[],
|
||||||
Word32 spectrum[], Word16 *spectrum_e,
|
float spectrum[],
|
||||||
Word16 L_frame,
|
int L_frame
|
||||||
Word16 L_frameTCX
|
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
Word16 i, j, k, l, n;
|
int k;
|
||||||
Word16 fac, fac0, fac1, fac_e, d, tmp;
|
int i, j, l = 0;
|
||||||
Word16 xn_buf_e, xn_one, m, e;
|
float fac, step;
|
||||||
|
|
||||||
|
k = L_frame / FDNS_NPTS;
|
||||||
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 */
|
|
||||||
|
|
||||||
/* Formant enhancement via square root of the LPC gains */
|
/* Formant enhancement via square root of the LPC gains */
|
||||||
e = gainlpc_e[0];
|
xn_buf[0] = (float)sqrt(gainlpc[0]);
|
||||||
move16();
|
xn_buf[1] = (float)sqrt(gainlpc[1]);
|
||||||
m = Sqrt16(gainlpc[0], &e);
|
fac = 1.0f / min(xn_buf[0], xn_buf[1]);
|
||||||
xn_buf[0] = shl(m, sub(e, xn_buf_e));
|
|
||||||
move16();
|
|
||||||
|
|
||||||
e = gainlpc_e[1];
|
for (i = 1; i < FDNS_NPTS - 1; i++)
|
||||||
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++)
|
|
||||||
{
|
{
|
||||||
e = gainlpc_e[i+1];
|
xn_buf[i+1] = (float)sqrt(gainlpc[i+1]);
|
||||||
move16();
|
|
||||||
m = Sqrt16(gainlpc[i+1], &e);
|
|
||||||
xn_buf[i+1] = shl(m, sub(e, xn_buf_e));
|
|
||||||
move16();
|
|
||||||
|
|
||||||
test();
|
if ((xn_buf[i-1] <= xn_buf[i]) && (xn_buf[i+1] <= xn_buf[i]))
|
||||||
IF ((sub(xn_buf[i-1], xn_buf[i]) <= 0) && (sub(xn_buf[i+1], xn_buf[i]) <= 0))
|
|
||||||
{
|
{
|
||||||
m = s_max(xn_buf[i-1], xn_buf[i+1]);
|
step = max(xn_buf[i-1], xn_buf[i+1]);
|
||||||
e = xn_buf_e;
|
step = (1.0f / step - fac) / (float)(i - l);
|
||||||
move16();
|
xn_buf[l] = 1.0f;
|
||||||
m = Inv16(m, &e);
|
fac += step;
|
||||||
|
for (j = l + 1; j < i; j++)
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
fac_e = e;
|
xn_buf[j] = min(1.0f, xn_buf[j] * fac);
|
||||||
move16();
|
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;
|
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;
|
/* i = tcx_cfg->fdns_npts - 1; Completing changes to gains */
|
||||||
move16();
|
step = min(xn_buf[i-1], xn_buf[i]);
|
||||||
tmp = sub(e, fac_e);
|
step = (1.0f / step - fac) / (float)(i - l);
|
||||||
|
xn_buf[l] = 1.0f;
|
||||||
if (tmp > 0) fac0 = shr(fac0, tmp);
|
fac += step;
|
||||||
if (tmp < 0) fac1 = shl(fac1, tmp);
|
for (j = l + 1; j < i; j++)
|
||||||
|
|
||||||
if (tmp > 0)
|
|
||||||
{
|
{
|
||||||
fac_e = e;
|
xn_buf[j] = min(1.0f, xn_buf[j] * fac);
|
||||||
move16();
|
fac += step;
|
||||||
}
|
}
|
||||||
|
xn_buf[i] = 1.0f;
|
||||||
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();
|
|
||||||
|
|
||||||
/* Application of changed gains onto decoded MDCT lines */
|
/* 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);
|
spectrum[i] *= xn_buf[j];
|
||||||
move32();
|
|
||||||
spectrum++;
|
|
||||||
}
|
}
|
||||||
xn_buf++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tmp = sub(L_frameTCX, L_frame);
|
return;
|
||||||
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();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void tcxInvertWindowGrouping(TCX_config *tcx_cfg,
|
/*-------------------------------------------------------------------*
|
||||||
Word32 xn_buf[],
|
* tcxGetNoiseFillingTilt()
|
||||||
Word32 spectrum[],
|
*
|
||||||
Word16 L_frame,
|
*
|
||||||
Word8 fUseTns,
|
*-------------------------------------------------------------------*/
|
||||||
Word16 last_core,
|
|
||||||
Word16 index,
|
void tcxInvertWindowGrouping(
|
||||||
Word16 frame_cnt,
|
TCX_config *tcx_cfg,
|
||||||
Word16 bfi)
|
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;
|
short i, w, t_integer;
|
||||||
Word32 *p;
|
int L_win, L_spec;
|
||||||
|
|
||||||
|
if (frame_cnt && !bfi && last_core!=0)
|
||||||
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 */
|
|
||||||
{
|
{
|
||||||
|
/* fix sub-window overlap */
|
||||||
tcx_cfg->tcx_last_overlap_mode = tcx_cfg->tcx_curr_overlap_mode;
|
tcx_cfg->tcx_last_overlap_mode = tcx_cfg->tcx_curr_overlap_mode;
|
||||||
move16();
|
|
||||||
}
|
}
|
||||||
test();
|
|
||||||
test();
|
if (((!bfi) &&((tcx_cfg->tcx_last_overlap_mode != FULL_OVERLAP) ||
|
||||||
test();
|
((tcx_cfg->tcx_curr_overlap_mode == FULL_OVERLAP) && (frame_cnt == 0) && (index == 0))))
|
||||||
test();
|
||
|
||||||
test();
|
((bfi) &&((tcx_cfg->tcx_last_overlap_mode != FULL_OVERLAP) &&
|
||||||
test();
|
!(tcx_cfg->tcx_curr_overlap_mode == FULL_OVERLAP))))
|
||||||
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))))
|
|
||||||
{
|
{
|
||||||
|
|
||||||
/* ungroup sub-windows: deinterleave MDCT bins into separate windows */
|
/* ungroup sub-windows: deinterleave MDCT bins into separate windows */
|
||||||
p = xn_buf;
|
for (t_integer = w = 0; w < 2; w++)
|
||||||
FOR (i = 1; i < L_win; i += 2)
|
|
||||||
{
|
{
|
||||||
*p++ = spectrum[i];
|
for (i = w; i < L_frame; i += 2)
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
Copy32(spectrum+8, spectrum+16, sub(shr(L_spec,1),8));
|
xn_buf[t_integer++] = spectrum[i];
|
||||||
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));
|
|
||||||
}
|
}
|
||||||
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);
|
mvr2r( spectrum+8, spectrum+16, L_spec/2-8 );
|
||||||
Copy32(spectrum+8, spectrum+16, sub(L_win, 8));
|
mvr2r( spectrum+L_frame/2, spectrum+8, 8 );
|
||||||
Copy32(xn_buf, 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 "options.h"
|
||||||
#include "stl.h"
|
#include "prot.h"
|
||||||
#include "prot_fx.h"
|
|
||||||
|
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------
|
/*--------------------------------------------------------------------------
|
||||||
* get_delay_fx()
|
* get_delay()
|
||||||
*
|
*
|
||||||
* Function returns various types of delays in the codec in ms.
|
* Function returns various types of delays in the codec in ms.
|
||||||
*--------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
Word32 get_delay_fx( /* o : delay value in ms */
|
float get_delay( /* o : delay value in ms */
|
||||||
const Word16 what_delay, /* i : what delay? (ENC or DEC) */
|
const short what_delay, /* i : what delay? (ENC or DEC) */
|
||||||
const Word32 io_fs /* i : input/output sampling frequency */
|
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);
|
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;
|
delay = DELAY_CLDFB_NS;
|
||||||
move32();
|
|
||||||
}
|
}
|
||||||
ELSE
|
else
|
||||||
{
|
{
|
||||||
delay = DELAY_BWE_TOTAL_NS;
|
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)
|
int print_disclaimer(FILE *fPtr)
|
||||||
{
|
{
|
||||||
|
|
||||||
fprintf(fPtr, "\n==============================================================================\n");
|
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, " 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");
|
fprintf(fPtr, "===================================================================================================\n\n\n");
|
||||||
|
|
||||||
return 0;
|
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 <assert.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "prot_fx.h"
|
#include "options.h"
|
||||||
#include "stl.h"
|
#include "prot.h"
|
||||||
#include "prot_fx.h"
|
#include "rom_com.h"
|
||||||
|
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------*
|
||||||
|
* routine: dlpc_bfi()
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*---------------------------------------------------------------------*/
|
||||||
|
|
||||||
void dlpc_bfi(
|
void dlpc_bfi(
|
||||||
const Word16 L_frame,
|
int L_frame,
|
||||||
Word16 *lsf_q, /* o : quantized LSFs */
|
float *lsf_q, /* o : quantized lsfs */
|
||||||
const Word16 *lsfold, /* i : past quantized LSF */
|
const float *lsfold, /* i : past quantized lsf */
|
||||||
const Word16 last_good, /* i : last good received frame */
|
const short last_good, /* i : last good received frame */
|
||||||
const Word16 nbLostCmpt, /* i : counter of consecutive bad frames */
|
const short nbLostCmpt, /* i : counter of consecutive bad frames */
|
||||||
Word16 mem_MA[], /* i/o: quantizer memory for MA model */
|
float mem_MA[], /* i/o: quantizer memory for MA model */
|
||||||
Word16 mem_AR[], /* i/o: quantizer memory for AR model */
|
float *mem_AR, /* i/o: quantizer memory for AR model */
|
||||||
Word16 *stab_fac, /* i : LSF stability factor */
|
float *stab_fac, /* i : lsf stability factor */
|
||||||
Word16 *lsf_adaptive_mean,/* i : LSF adaptive mean, updated when BFI==0 */
|
float *lsf_adaptive_mean,/* i : lsf adaptive mean, updated when BFI==0 */
|
||||||
Word16 numlpc, /* i : Number of division per superframe */
|
int numlpc, /* i : Number of division per superframe */
|
||||||
Word16 lsf_cng[],
|
float lsf_cng[],
|
||||||
Word8 plcBackgroundNoiseUpdated,
|
int plcBackgroundNoiseUpdated,
|
||||||
Word16 *lsf_q_cng, /* o : quantized LSFs */
|
float *lsf_q_cng, /* o : quantized lsfs of background noise */
|
||||||
Word16 *old_lsf_q_cng, /* o : old quantized LSFs for background noise */
|
float *old_lsf_q_cng, /* o : old quantized lsfs for background noise */
|
||||||
const Word16* lsfBase, /* i : base for differential LSF coding */
|
const float lsfBase[] /* i : base for differential lsf coding */
|
||||||
Word8 tcxonly
|
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
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(
|
if( numlpc == 2 )
|
||||||
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 )
|
|
||||||
{
|
{
|
||||||
/* Decode the second LPC */
|
/* Decode the second LPC */
|
||||||
lsf_dec_bfi(
|
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,
|
||||||
MODE2,
|
nbLostCmpt+1, plcBackgroundNoiseUpdated, lsf_q_cng, lsf_cng, old_lsf_q_cng, 0, 0, 0 );
|
||||||
&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
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
/**/ /*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
|
File: ENH1632.C v.2.3 - 30.Nov.2009
|
||||||
@@ -18,33 +19,33 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
*
|
*
|
||||||
* Enhanced 16/32 bit operators :
|
* Enhanced 16/32 bit operators :
|
||||||
* s_max()
|
* s_max()
|
||||||
* s_min()
|
* s_min()
|
||||||
* L_max()
|
* L_max()
|
||||||
* L_min()
|
* L_min()
|
||||||
* shl_r()
|
* shl_r()
|
||||||
* L_shl_r()
|
* L_shl_r()
|
||||||
* L_mac0()
|
* L_mac0()
|
||||||
* L_mult0()
|
* L_mult0()
|
||||||
* L_msu0()
|
* L_msu0()
|
||||||
* s_and()
|
* s_and()
|
||||||
* s_or()
|
* s_or()
|
||||||
* s_xor()
|
* s_xor()
|
||||||
* L_and()
|
* L_and()
|
||||||
* L_or()
|
* L_or()
|
||||||
* lshl()
|
* lshl()
|
||||||
* lshr()
|
* lshr()
|
||||||
* L_lshl()
|
* L_lshl()
|
||||||
* L_lshr()
|
* L_lshr()
|
||||||
* rotr()
|
* rotr()
|
||||||
* rotl()
|
* rotl()
|
||||||
* L_rotr()
|
* L_rotr()
|
||||||
* L_rotl()
|
* L_rotl()
|
||||||
*
|
*
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
@@ -52,17 +53,11 @@
|
|||||||
* Include-Files
|
* Include-Files
|
||||||
*
|
*
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "stl.h"
|
#include "stl.h"
|
||||||
|
|
||||||
#if (WMOPS)
|
|
||||||
extern BASIC_OP multiCounter[MAXCOUNTERS];
|
|
||||||
extern int currCounter;
|
|
||||||
#endif /* if WMOPS */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
*
|
*
|
||||||
* Constants and Globals
|
* Constants and Globals
|
||||||
@@ -109,33 +104,35 @@ extern int currCounter;
|
|||||||
* the range 0xffff 8000 <= var_out <= 0x0000 7fff.
|
* the range 0xffff 8000 <= var_out <= 0x0000 7fff.
|
||||||
*
|
*
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
Word16 lshl( Word16 var1, Word16 var2) {
|
Word16 lshl( Word16 var1, Word16 var2)
|
||||||
Word16 var_out=0;
|
{
|
||||||
|
Word16 var_out=0;
|
||||||
|
|
||||||
if( var2 < 0) {
|
if( var2 < 0)
|
||||||
var2 = -var2;
|
{
|
||||||
var_out = lshr( var1, var2);
|
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)
|
BASOP_CHECK();
|
||||||
multiCounter[currCounter].lshr--;
|
|
||||||
#endif /* if WMOPS */
|
|
||||||
|
|
||||||
} 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.
|
* the range 0xffff 8000 <= var_out <= 0x0000 7fff.
|
||||||
*
|
*
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
Word16 lshr( Word16 var1, Word16 var2) {
|
Word16 lshr( Word16 var1, Word16 var2)
|
||||||
Word16 var_out;
|
{
|
||||||
|
Word16 var_out;
|
||||||
|
|
||||||
if( var2 < 0) {
|
if( var2 < 0)
|
||||||
var2 = -var2;
|
{
|
||||||
var_out = lshl( var1, var2);
|
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)
|
BASOP_CHECK();
|
||||||
multiCounter[currCounter].lshl--;
|
|
||||||
#endif /* if WMOPS */
|
|
||||||
|
|
||||||
} 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.
|
* the range 0x8000 0000 <= L_var_out <= 0x7fff ffff.
|
||||||
*
|
*
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
Word32 L_lshl( Word32 L_var1, Word16 var2) {
|
Word32 L_lshl( Word32 L_var1, Word16 var2)
|
||||||
Word32 L_var_out=0;
|
{
|
||||||
|
Word32 L_var_out=0;
|
||||||
|
|
||||||
if( var2 < 0) {
|
if( var2 < 0)
|
||||||
var2 = -var2;
|
{
|
||||||
L_var_out = L_lshr( L_var1, var2);
|
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)
|
BASOP_CHECK();
|
||||||
multiCounter[currCounter].L_lshr--;
|
|
||||||
#endif /* if WMOPS */
|
|
||||||
|
|
||||||
} 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.
|
* the range 0x8000 0000 <= L_var_out <= 0x7fff ffff.
|
||||||
*
|
*
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
Word32 L_lshr( Word32 L_var1, Word16 var2) {
|
Word32 L_lshr( Word32 L_var1, Word16 var2)
|
||||||
Word32 L_var_out;
|
{
|
||||||
|
Word32 L_var_out;
|
||||||
|
|
||||||
if( var2 < 0) {
|
if( var2 < 0)
|
||||||
var2 = -var2;
|
{
|
||||||
L_var_out = L_lshl( L_var1, var2);
|
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)
|
BASOP_CHECK();
|
||||||
multiCounter[currCounter].L_lshl--;
|
|
||||||
#endif /* if WMOPS */
|
|
||||||
|
|
||||||
} 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.
|
* the range : 0xffff 8000 <= var_out <= 0x0000 7fff.
|
||||||
*
|
*
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
Word16 shl_r( Word16 var1, Word16 var2){
|
Word16 shl_r( Word16 var1, Word16 var2)
|
||||||
Word16 var_out;
|
{
|
||||||
|
Word16 var_out;
|
||||||
|
|
||||||
if( var2 >= 0) {
|
if( var2 >= 0)
|
||||||
var_out = shl( var1, var2);
|
{
|
||||||
|
var_out = shl( var1, var2);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var2 = -var2;
|
||||||
|
var_out = shr_r( var1, var2);
|
||||||
|
}
|
||||||
|
|
||||||
#if (WMOPS)
|
|
||||||
multiCounter[currCounter].shl--;
|
|
||||||
#endif /* if WMOPS */
|
|
||||||
|
|
||||||
} else {
|
return( var_out);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -413,30 +408,22 @@ Word16 shl_r( Word16 var1, Word16 var2){
|
|||||||
* the range : 0x8000 0000 <= var_out <= 0x7fff ffff.
|
* the range : 0x8000 0000 <= var_out <= 0x7fff ffff.
|
||||||
*
|
*
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
Word32 L_shl_r( Word32 L_var1, Word16 var2) {
|
Word32 L_shl_r( Word32 L_var1, Word16 var2)
|
||||||
Word32 var_out;
|
{
|
||||||
|
Word32 var_out;
|
||||||
|
|
||||||
if( var2 >= 0) {
|
if( var2 >= 0)
|
||||||
var_out = L_shl( L_var1, var2);
|
{
|
||||||
|
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 {
|
return( var_out);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -470,22 +457,16 @@ Word32 L_shl_r( Word32 L_var1, Word16 var2) {
|
|||||||
* the range : 0xffff 8000 <= var_out <= 0x0000 7fff.
|
* the range : 0xffff 8000 <= var_out <= 0x0000 7fff.
|
||||||
*
|
*
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
Word16 rotr( Word16 var1, Word16 var2, Word16 *var3) {
|
Word16 rotr( Word16 var1, Word16 var2, Word16 *var3)
|
||||||
Word16 var_out;
|
{
|
||||||
|
Word16 var_out;
|
||||||
|
|
||||||
*var3 = s_and( var1, 0x1);
|
*var3 = s_and( var1, 0x1);
|
||||||
var_out = s_or( lshr( var1, 1),
|
var_out = s_or( lshr( var1, 1),
|
||||||
lshl( var2, 15));
|
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.
|
* the range : 0xffff 8000 <= var_out <= 0x0000 7fff.
|
||||||
*
|
*
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
Word16 rotl( Word16 var1, Word16 var2, Word16 *var3) {
|
Word16 rotl( Word16 var1, Word16 var2, Word16 *var3)
|
||||||
Word16 var_out;
|
{
|
||||||
|
Word16 var_out;
|
||||||
|
|
||||||
*var3 = lshr( var1, 15);
|
*var3 = lshr( var1, 15);
|
||||||
|
|
||||||
var_out = s_or( lshl( var1, 1),
|
var_out = s_or( lshl( var1, 1),
|
||||||
s_and( var2, 0x1));
|
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.
|
* the range : 0x8000 0000 <= L_var_out <= 0x7fff ffff.
|
||||||
*
|
*
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
Word32 L_rotr( Word32 L_var1, Word16 var2, Word16 *var3) {
|
Word32 L_rotr( Word32 L_var1, Word16 var2, Word16 *var3)
|
||||||
Word32 L_var_out;
|
{
|
||||||
|
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_var_out = L_or( L_lshr( L_var1, 1),
|
||||||
L_lshl( L_deposit_l( var2), 31));
|
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.
|
* the range : 0x8000 0000 <= L_var_out <= 0x7fff ffff.
|
||||||
*
|
*
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
Word32 L_rotl( Word32 L_var1, Word16 var2, Word16 *var3) {
|
Word32 L_rotl( Word32 L_var1, Word16 var2, Word16 *var3)
|
||||||
Word32 L_var_out;
|
{
|
||||||
|
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_var_out = L_or( L_lshl( L_var1, 1),
|
||||||
L_deposit_l( s_and( var2, 0x1)));
|
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"
|
#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
|
* 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.
|
* the range : 0x8000 <= L_var_out <= 0x7fff.
|
||||||
*
|
*
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
static __inline Word16 s_max( Word16 var1, Word16 var2) {
|
static __inline Word16 s_max( Word16 var1, Word16 var2)
|
||||||
Word16 var_out;
|
{
|
||||||
|
Word16 var_out;
|
||||||
|
|
||||||
if( var1 >= var2)
|
if( var1 >= var2)
|
||||||
var_out = var1;
|
var_out = var1;
|
||||||
else
|
else
|
||||||
var_out = var2;
|
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.
|
* the range : 0x8000 <= var_out <= 0x7fff.
|
||||||
*
|
*
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
static __inline Word16 s_min( Word16 var1, Word16 var2) {
|
static __inline Word16 s_min( Word16 var1, Word16 var2)
|
||||||
Word16 var_out;
|
{
|
||||||
|
Word16 var_out;
|
||||||
|
|
||||||
if( var1 <= var2)
|
if( var1 <= var2)
|
||||||
var_out = var1;
|
var_out = var1;
|
||||||
else
|
else
|
||||||
var_out = var2;
|
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.
|
* range : 0x8000 0000 <= L_var_out <= 0x7fff ffff.
|
||||||
*
|
*
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
static __inline Word32 L_max( Word32 L_var1, Word32 L_var2) {
|
static __inline Word32 L_max( Word32 L_var1, Word32 L_var2)
|
||||||
Word32 L_var_out;
|
{
|
||||||
|
Word32 L_var_out;
|
||||||
|
|
||||||
if( L_var1 >= L_var2)
|
if( L_var1 >= L_var2)
|
||||||
L_var_out = L_var1;
|
L_var_out = L_var1;
|
||||||
else
|
else
|
||||||
L_var_out = L_var2;
|
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.
|
* range : 0x8000 0000 <= L_var_out <= 0x7fff ffff.
|
||||||
*
|
*
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
static __inline Word32 L_min( Word32 L_var1, Word32 L_var2) {
|
static __inline Word32 L_min( Word32 L_var1, Word32 L_var2)
|
||||||
Word32 L_var_out;
|
{
|
||||||
|
Word32 L_var_out;
|
||||||
|
|
||||||
if( L_var1 <= L_var2)
|
if( L_var1 <= L_var2)
|
||||||
L_var_out = L_var1;
|
L_var_out = L_var1;
|
||||||
else
|
else
|
||||||
L_var_out = L_var2;
|
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.
|
* falls in the range 0xffff 8000 <= var_out <= 0x0000 7fff.
|
||||||
*
|
*
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
static __inline Word16 s_and( Word16 var1, Word16 var2) {
|
static __inline Word16 s_and( Word16 var1, Word16 var2)
|
||||||
Word16 var_out;
|
{
|
||||||
|
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.
|
* falls in the range 0x8000 0000 <= L_var_out <= 0x7fff ffff.
|
||||||
*
|
*
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
static __inline Word32 L_and( Word32 L_var1, Word32 L_var2) {
|
static __inline Word32 L_and( 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_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.
|
* falls in the range 0xffff 8000 <= var_out <= 0x0000 7fff.
|
||||||
*
|
*
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
static __inline Word16 s_or( Word16 var1, Word16 var2) {
|
static __inline Word16 s_or( Word16 var1, Word16 var2)
|
||||||
Word16 var_out;
|
{
|
||||||
|
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.
|
* 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.
|
* falls in the range 0xffff 8000 <= var_out <= 0x0000 7fff.
|
||||||
*
|
*
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
static __inline Word16 s_xor( Word16 var1, Word16 var2) {
|
static __inline Word16 s_xor( Word16 var1, Word16 var2)
|
||||||
Word16 var_out;
|
{
|
||||||
|
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.
|
* falls in the range 0x8000 0000 <= L_var_out <= 0x7fff ffff.
|
||||||
*
|
*
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
static __inline Word32 L_xor( Word32 L_var1, Word32 L_var2) {
|
static __inline Word32 L_xor( 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_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 "options.h"
|
||||||
#include "cnst_fx.h" /* Common constants */
|
#include "cnst.h"
|
||||||
#include "prot_fx.h" /* Function prototypes */
|
#include "prot.h"
|
||||||
#include "rom_com_fx.h" /* Static table prototypes */
|
#include "rom_com.h"
|
||||||
#include "stl.h" /* required by wmc_tool */
|
#include <math.h>
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------*
|
/*--------------------------------------------------------------------------*
|
||||||
* Local constants
|
* Local constants
|
||||||
*--------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#define ENV_STAB_SMO_HO 10 /* number of hangover frames when switching from music to speech state */
|
#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 */
|
/* Envelope stability measure */
|
||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
Word16 env_stability_fx( /* in Q15 */
|
float env_stability(
|
||||||
const Word16 *ynrm, /*i: Norm vector for current frame */
|
const short *ynrm, /*i : Norm vector for current frame */
|
||||||
const Word16 nb_sfm, /*i: Number of sub-bands */
|
const short nb_sfm, /*i : Number of sub-bands */
|
||||||
Word16 *mem_norm, /*i/o: Norm vector memory from past frame */
|
short *mem_norm, /*i/o: Norm vector memory from past frame */
|
||||||
Word16 *mem_env_delta /*i/o: Envelope stability memory for smoothing in Q12 */
|
float *mem_env_delta /*i/o: Envelope stability memory for smoothing*/
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
Word16 env_delta;
|
Word16 env_delta;
|
||||||
@@ -35,21 +36,21 @@ Word16 env_stability_fx( /* in Q15 */
|
|||||||
Word16 exp, exp2;
|
Word16 exp, exp2;
|
||||||
Word32 L_tmp, L_env_delta;
|
Word32 L_tmp, L_env_delta;
|
||||||
Word16 inv_nb_sfm;
|
Word16 inv_nb_sfm;
|
||||||
|
float env_stab_f;
|
||||||
|
|
||||||
/* Calculate envelope stability parameter */
|
/* Calculate envelope stability parameter */
|
||||||
L_env_delta = L_deposit_l(0);
|
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]);
|
tmp = sub(mem_norm[i],ynrm[i]);
|
||||||
L_env_delta = L_mac0(L_env_delta, tmp, tmp);
|
L_env_delta = L_mac0(L_env_delta, tmp, tmp);
|
||||||
mem_norm[i] = ynrm[i];
|
mem_norm[i] = ynrm[i];
|
||||||
move16();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inv_nb_sfm = 19418; /* Q19 */ move16();
|
inv_nb_sfm = 19418; /* Q19 */
|
||||||
if (nb_sfm == 26)
|
if (nb_sfm == 26)
|
||||||
{
|
{
|
||||||
inv_nb_sfm = 20165; /* Q19 */ move16();
|
inv_nb_sfm = 20165; /* Q19 */
|
||||||
}
|
}
|
||||||
exp = norm_l(L_env_delta);
|
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 */
|
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 */
|
*mem_env_delta = round_fx(L_tmp); /* Q12 */
|
||||||
Overflow = 0;
|
Overflow = 0;
|
||||||
move16();
|
|
||||||
env_delta = round_fx(L_shl(L_tmp, 1)); /* Q13 */
|
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,
|
/* 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()
|
#error env_stability_fx: Use more efficient usquant()
|
||||||
#endif
|
#endif
|
||||||
tmp_stab = sub(tmp_stab, HALF_D_STAB_TBL_FX); /* in Q13 */
|
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 */
|
tmp_stab = sub(tmp_stab, D_STAB_TBL_FX); /* in Q13 */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
env_stab = stab_trans_fx[i];
|
env_stab = stab_trans_fx[i];
|
||||||
move16();
|
|
||||||
if(sub(env_delta, M_STAB_TBL_FX) < 0)
|
if(sub(env_delta, M_STAB_TBL_FX) < 0)
|
||||||
{
|
{
|
||||||
env_stab = sub(0x7FFF,stab_trans_fx[i]);
|
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 */
|
float env_stab_smo(
|
||||||
Word16 *env_stab_state_p, /*i/o: env_stab state probabilities Q15 */
|
float env_stab, /*i : env_stab value */
|
||||||
Word16 *ho_cnt /*i/o: hangover counter for speech state */
|
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;
|
short state, prev_state;
|
||||||
Word16 maxval, pp[NUM_ENV_STAB_PLC_STATES], pa[NUM_ENV_STAB_PLC_STATES];
|
float maxval, pp[NUM_ENV_STAB_PLC_STATES], pa[NUM_ENV_STAB_PLC_STATES];
|
||||||
Word16 i;
|
|
||||||
Word16 tmp, sum, exp;
|
|
||||||
|
|
||||||
/* get previous state */
|
/* 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) */
|
/* assume two states: speech(0), music(1) */
|
||||||
/* set a posteriori likelihoods for the two states according to env_stab */
|
/* set a posteriori likelihoods for the two states according to env_stab */
|
||||||
/* re-scale. Unclear if needed */
|
env_stab = (env_stab - stab_trans[L_STAB_TBL-1])/(1-2*stab_trans[L_STAB_TBL-1]);
|
||||||
/* env_stab = (env_stab - stab_trans_fx[L_STAB_TBL-1])/(1-2*stab_trans_fx[L_STAB_TBL-1]); */
|
pp[0] = 1.0f-env_stab;
|
||||||
tmp = sub(env_stab, stab_trans_fx[L_STAB_TBL-1]);
|
pp[1] = env_stab;
|
||||||
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();
|
|
||||||
|
|
||||||
/* calculate a priori likelihoods */
|
/* 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[0] = dotp(env_stab_tp[0],env_stab_state_p,NUM_ENV_STAB_PLC_STATES);
|
||||||
pa[1] = round_fx(Dot_product(env_stab_tp_fx[1], 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 */
|
/* multiply elementwise with a posteriori likelihoods */
|
||||||
sum = 0;
|
v_mult(pa,pp,env_stab_state_p,NUM_ENV_STAB_PLC_STATES);
|
||||||
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]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* renormalize state probabilities */
|
/* renormalize state probabilities */
|
||||||
exp = norm_s(sum);
|
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);
|
||||||
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 */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* find maximum index as return value */
|
/* 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 */
|
/* apply some hangover for speech */
|
||||||
test();
|
if (state==0 && prev_state==1)
|
||||||
if (state == 0 && sub(prev_state, 1) == 0)
|
|
||||||
{
|
{
|
||||||
*ho_cnt = ENV_STAB_SMO_HO;
|
*ho_cnt=ENV_STAB_SMO_HO;
|
||||||
move16();
|
|
||||||
}
|
}
|
||||||
|
if (*ho_cnt>0)
|
||||||
IF (*ho_cnt > 0)
|
|
||||||
{
|
{
|
||||||
*ho_cnt = sub(*ho_cnt, 1);
|
pp[0]=1;
|
||||||
move16();
|
pp[1]=0;
|
||||||
|
(*ho_cnt)--;
|
||||||
}
|
}
|
||||||
|
|
||||||
return state;
|
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 <assert.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#else
|
#else
|
||||||
#include <Winsock2.h>
|
#include <Winsock2.h>
|
||||||
|
|
||||||
typedef unsigned short uint16_t;
|
typedef unsigned short uint16_t;
|
||||||
typedef signed short int16_t;
|
typedef signed short int16_t;
|
||||||
typedef unsigned int uint32_t;
|
typedef unsigned int uint32_t;
|
||||||
@@ -20,7 +21,6 @@ typedef unsigned __int64 uint64_t;
|
|||||||
typedef signed __int64 int64_t;
|
typedef signed __int64 int64_t;
|
||||||
#endif
|
#endif
|
||||||
#include "options.h"
|
#include "options.h"
|
||||||
#include "stl.h"
|
|
||||||
#include "g192.h"
|
#include "g192.h"
|
||||||
|
|
||||||
|
|
||||||
@@ -28,12 +28,15 @@ typedef signed __int64 int64_t;
|
|||||||
#pragma warning( disable : 4996 )
|
#pragma warning( disable : 4996 )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define G192_SYNC_GOOD_FRAME (Word16)0x6B21
|
#define G192_SYNC_GOOD_FRAME (unsigned short) 0x6B21
|
||||||
#define G192_SYNC_BAD_FRAME (Word16)0x6B20
|
#define G192_SYNC_BAD_FRAME (unsigned short) 0x6B20
|
||||||
#define G192_BIT0 (Word16)0x007F
|
#define G192_BIT0 (unsigned short) 0x007F
|
||||||
#define G192_BIT1 (Word16)0x0081
|
#define G192_BIT1 (unsigned short) 0x0081
|
||||||
#define MAX_BITS_PER_FRAME 2560
|
#define RTP_HEADER_PART1 (short)22 /* magic number by network simulator */
|
||||||
#define RTP_HEADER_PART1 (Word16)22 /* magic number by network simulator */
|
|
||||||
|
#ifndef MAX_BITS_PER_FRAME
|
||||||
|
#define MAX_BITS_PER_FRAME 2560
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Structures
|
* Structures
|
||||||
@@ -58,7 +61,6 @@ G192_Reader_Open(G192_HANDLE* phG192, FILE * filename)
|
|||||||
{
|
{
|
||||||
return G192_MEMORY_ERROR;
|
return G192_MEMORY_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(*phG192, 0, sizeof(struct __G192));
|
memset(*phG192, 0, sizeof(struct __G192));
|
||||||
|
|
||||||
/* associate file stream */
|
/* associate file stream */
|
||||||
@@ -68,27 +70,24 @@ G192_Reader_Open(G192_HANDLE* phG192, FILE * filename)
|
|||||||
G192_Reader_Close(phG192);
|
G192_Reader_Close(phG192);
|
||||||
return G192_FILE_NOT_FOUND;
|
return G192_FILE_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
return G192_NO_ERROR;
|
return G192_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
G192_ERROR
|
G192_ERROR
|
||||||
G192_ReadVoipFrame_compact(G192_HANDLE const hG192,
|
G192_ReadVoipFrame_compact(G192_HANDLE const hG192,
|
||||||
unsigned char * const serial,
|
unsigned char * const serial,
|
||||||
Word16 * const num_bits,
|
short * const num_bits,
|
||||||
Word16 *rtpSequenceNumber,
|
unsigned short * const rtpSequenceNumber,
|
||||||
Word32 *rtpTimeStamp,
|
unsigned int * const rtpTimeStamp,
|
||||||
Word32 *rcvTime_ms)
|
unsigned int * const rcvTime_ms)
|
||||||
{
|
{
|
||||||
Word16 short_serial [MAX_BITS_PER_FRAME];
|
short short_serial [MAX_BITS_PER_FRAME];
|
||||||
G192_ERROR err;
|
G192_ERROR err;
|
||||||
Word16 i;
|
short i;
|
||||||
|
|
||||||
err = G192_ReadVoipFrame_short(hG192, short_serial, num_bits, rtpSequenceNumber, rtpTimeStamp, rcvTime_ms);
|
err = G192_ReadVoipFrame_short(hG192, short_serial, num_bits, rtpSequenceNumber, rtpTimeStamp, rcvTime_ms);
|
||||||
if(err != G192_NO_ERROR)
|
if(err != G192_NO_ERROR)
|
||||||
{
|
|
||||||
return err;
|
return err;
|
||||||
}
|
|
||||||
|
|
||||||
for(i=0; i<*num_bits; i++)
|
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] = 0;
|
||||||
serial[i>>3] |= bitinbyte;
|
serial[i>>3] |= bitinbyte;
|
||||||
}
|
}
|
||||||
|
|
||||||
return G192_NO_ERROR;
|
return G192_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
G192_ERROR
|
G192_ERROR
|
||||||
G192_ReadVoipFrame_short(G192_HANDLE const hG192,
|
G192_ReadVoipFrame_short(G192_HANDLE const hG192,
|
||||||
Word16 * const serial,
|
short * const serial,
|
||||||
Word16 *num_bits,
|
short * const num_bits,
|
||||||
Word16 *rtpSequenceNumber,
|
unsigned short * const rtpSequenceNumber,
|
||||||
Word32 *rtpTimeStamp,
|
unsigned int * const rtpTimeStamp,
|
||||||
Word32 *rcvTime_ms)
|
unsigned int * const rcvTime_ms)
|
||||||
{
|
{
|
||||||
Word32 rtpPacketSize;
|
uint32_t rtpPacketSize;
|
||||||
Word16 rtpPacketHeaderPart1;
|
uint16_t rtpPacketHeaderPart1;
|
||||||
Word32 ssrc;
|
uint32_t ssrc;
|
||||||
Word16 rtpPayloadG192[2];
|
uint16_t rtpPayloadG192[2];
|
||||||
Word16 rtpPayloadSize;
|
uint16_t rtpPayloadSize;
|
||||||
|
|
||||||
/* RTP packet size */
|
/* RTP packet size */
|
||||||
if(fread(&rtpPacketSize, sizeof(rtpPacketSize), 1, hG192->file) != 1)
|
if(fread(&rtpPacketSize, sizeof(rtpPacketSize), 1, hG192->file) != 1)
|
||||||
@@ -124,12 +122,13 @@ G192_ReadVoipFrame_short(G192_HANDLE const hG192,
|
|||||||
return G192_EOF;
|
return G192_EOF;
|
||||||
}
|
}
|
||||||
fprintf(stderr, "RTP Packet Size could't be read\n");
|
fprintf(stderr, "RTP Packet Size could't be read\n");
|
||||||
|
|
||||||
return G192_READ_ERROR;
|
return G192_READ_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(rtpPacketSize <= 12)
|
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;
|
return G192_INVALID_DATA;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -141,6 +140,7 @@ G192_ReadVoipFrame_short(G192_HANDLE const hG192,
|
|||||||
return G192_EOF;
|
return G192_EOF;
|
||||||
}
|
}
|
||||||
fprintf(stderr, "Reception Time in ms could't be read\n");
|
fprintf(stderr, "Reception Time in ms could't be read\n");
|
||||||
|
|
||||||
return G192_READ_ERROR;
|
return G192_READ_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -152,6 +152,7 @@ G192_ReadVoipFrame_short(G192_HANDLE const hG192,
|
|||||||
return G192_EOF;
|
return G192_EOF;
|
||||||
}
|
}
|
||||||
fprintf(stderr, "RTP Header couldn't be read\n");
|
fprintf(stderr, "RTP Header couldn't be read\n");
|
||||||
|
|
||||||
return G192_READ_ERROR;
|
return G192_READ_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -169,10 +170,11 @@ G192_ReadVoipFrame_short(G192_HANDLE const hG192,
|
|||||||
return G192_EOF;
|
return G192_EOF;
|
||||||
}
|
}
|
||||||
fprintf(stderr, "RTP Sequence Number be read\n");
|
fprintf(stderr, "RTP Sequence Number be read\n");
|
||||||
|
|
||||||
return G192_READ_ERROR;
|
return G192_READ_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
*rtpSequenceNumber = ntohs(*rtpSequenceNumber);
|
*rtpSequenceNumber = ntohs(*rtpSequenceNumber);
|
||||||
|
|
||||||
/* RTP timestamp */
|
/* RTP timestamp */
|
||||||
if(fread(rtpTimeStamp, sizeof(*rtpTimeStamp), 1, hG192->file) != 1)
|
if(fread(rtpTimeStamp, sizeof(*rtpTimeStamp), 1, hG192->file) != 1)
|
||||||
{
|
{
|
||||||
@@ -181,10 +183,11 @@ G192_ReadVoipFrame_short(G192_HANDLE const hG192,
|
|||||||
return G192_EOF;
|
return G192_EOF;
|
||||||
}
|
}
|
||||||
fprintf(stderr, "RTP Timestamp could't be read\n");
|
fprintf(stderr, "RTP Timestamp could't be read\n");
|
||||||
|
|
||||||
return G192_READ_ERROR;
|
return G192_READ_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
*rtpTimeStamp = ntohl(*rtpTimeStamp);
|
*rtpTimeStamp = ntohl(*rtpTimeStamp);
|
||||||
|
|
||||||
/* RTP ssrc */
|
/* RTP ssrc */
|
||||||
if(fread(&ssrc, sizeof(ssrc), 1, hG192->file) != 1)
|
if(fread(&ssrc, sizeof(ssrc), 1, hG192->file) != 1)
|
||||||
{
|
{
|
||||||
@@ -193,18 +196,20 @@ G192_ReadVoipFrame_short(G192_HANDLE const hG192,
|
|||||||
return G192_EOF;
|
return G192_EOF;
|
||||||
}
|
}
|
||||||
fprintf(stderr, "RTP SSRC could't be read\n");
|
fprintf(stderr, "RTP SSRC could't be read\n");
|
||||||
|
|
||||||
return G192_READ_ERROR;
|
return G192_READ_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* RTP payload size */
|
/* RTP payload size */
|
||||||
rtpPayloadSize = (Word16)(rtpPacketSize - 12);
|
rtpPayloadSize = rtpPacketSize - 12;
|
||||||
if(rtpPayloadSize <= 2)
|
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;
|
return G192_INVALID_DATA;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* RTP payload */
|
/* 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)
|
if(feof( hG192->file) != 0)
|
||||||
{
|
{
|
||||||
@@ -219,18 +224,14 @@ G192_ReadVoipFrame_short(G192_HANDLE const hG192,
|
|||||||
return G192_INVALID_DATA;
|
return G192_INVALID_DATA;
|
||||||
}
|
}
|
||||||
*num_bits = rtpPayloadG192[1];
|
*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",
|
fprintf(stderr, "error in parsing RTP payload: rtpPayloadSize=%u nBits=%d",
|
||||||
rtpPayloadSize, *num_bits);
|
rtpPayloadSize, *num_bits);
|
||||||
return G192_INVALID_DATA;
|
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");
|
fprintf(stderr, "Premature end of file, cannot read G.192 payload\n");
|
||||||
return G192_READ_ERROR;
|
return G192_READ_ERROR;
|
||||||
}
|
}
|
||||||
@@ -242,13 +243,11 @@ G192_ERROR
|
|||||||
G192_Reader_Close(G192_HANDLE* phG192)
|
G192_Reader_Close(G192_HANDLE* phG192)
|
||||||
{
|
{
|
||||||
if(phG192 == NULL || *phG192 == NULL)
|
if(phG192 == NULL || *phG192 == NULL)
|
||||||
{
|
|
||||||
return G192_NO_ERROR;
|
return G192_NO_ERROR;
|
||||||
}
|
|
||||||
|
|
||||||
free( *phG192 );
|
free( *phG192 );
|
||||||
*phG192 = NULL;
|
*phG192 = NULL;
|
||||||
phG192 = NULL;
|
phG192 = NULL;
|
||||||
|
|
||||||
return G192_NO_ERROR;
|
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
|
#ifndef G192_H
|
||||||
#define G192_H G192_H
|
#define G192_H G192_H
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ENUMS
|
* ENUMS
|
||||||
*/
|
*/
|
||||||
@@ -45,18 +47,18 @@ G192_Reader_Open(G192_HANDLE* phG192, FILE * filename);
|
|||||||
G192_ERROR
|
G192_ERROR
|
||||||
G192_ReadVoipFrame_compact(G192_HANDLE const hG192,
|
G192_ReadVoipFrame_compact(G192_HANDLE const hG192,
|
||||||
unsigned char * const serial,
|
unsigned char * const serial,
|
||||||
Word16 * const num_bits,
|
short * const num_bits,
|
||||||
Word16 *rtpSequenceNumber,
|
unsigned short * const rtpSequenceNumber,
|
||||||
Word32 *rtpTimeStamp,
|
unsigned int * const rtpTimeStamp,
|
||||||
Word32 *rcvTime_ms);
|
unsigned int * const rcvTime_ms);
|
||||||
|
|
||||||
G192_ERROR
|
G192_ERROR
|
||||||
G192_ReadVoipFrame_short(G192_HANDLE const hG192,
|
G192_ReadVoipFrame_short(G192_HANDLE const hG192,
|
||||||
Word16 * const serial,
|
short * const serial,
|
||||||
Word16 *num_bits,
|
short * const num_bits,
|
||||||
Word16 *rtpSequenceNumber,
|
unsigned short * const rtpSequenceNumber,
|
||||||
Word32 *rtpTimeStamp,
|
unsigned int * const rtpTimeStamp,
|
||||||
Word32 *rcvTime_ms);
|
unsigned int * const rcvTime_ms);
|
||||||
|
|
||||||
G192_ERROR
|
G192_ERROR
|
||||||
G192_Reader_Close(G192_HANDLE* phG192);
|
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 "options.h"
|
||||||
#include "prot_fx.h"
|
#include "prot.h"
|
||||||
#include "stl.h"
|
|
||||||
#include "basop_util.h"
|
|
||||||
|
|
||||||
Word32 get_gain( /* output: codebook gain (adaptive or fixed) Q16 */
|
|
||||||
Word16 x[], /* input : target signal */
|
/*----------------------------------------------------------------------------------*
|
||||||
Word16 y[], /* input : filtered codebook excitation */
|
* get_gain()
|
||||||
Word16 n /* input : segment length */
|
*
|
||||||
|
*
|
||||||
|
*----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
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;
|
float corr = 0.0f, ener = 1e-6f;
|
||||||
Word16 exp_c, exp_e, exp, tmp;
|
short i;
|
||||||
|
|
||||||
|
for (i = 0; i < n; i++)
|
||||||
|
{
|
||||||
|
corr += x[i]*y[i];
|
||||||
|
ener += y[i]*y[i];
|
||||||
|
}
|
||||||
|
|
||||||
tcorr = L_deposit_l(0);
|
if (en_y)
|
||||||
tener = L_deposit_l(0);
|
{
|
||||||
|
*en_y = ener;
|
||||||
|
}
|
||||||
|
|
||||||
|
return(corr/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;
|
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user