- work on evs decoder
This commit is contained in:
parent
9ec2f734d8
commit
46c355e29a
|
|
@ -57,11 +57,16 @@ set (CMAKE_CXX_STANDARD_REQUIRED ON)
|
|||
set (rtphone_libs libs)
|
||||
set (rtphone_engine engine)
|
||||
|
||||
set (USE_AMR_CODEC OFF CACHE BOOL "Use AMR codec. Requires libraries.")
|
||||
set (USE_EVS_CODEC OFF CACHE BOOL "Use EVS codec.")
|
||||
option (USE_AMR_CODEC "Use AMR codec. Requires libraries." OFF)
|
||||
option (USE_EVS_CODEC "Use EVS codec." OFF)
|
||||
|
||||
set (CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||
|
||||
if (NOT DEFINED LIB_PLATFORM)
|
||||
set (LIB_PLATFORM ${CMAKE_CURRENT_SOURCE_DIR}/../../libraries)
|
||||
endif()
|
||||
|
||||
message("Libraries: ${LIB_PLATFORM}")
|
||||
set (OPENSSL_INCLUDE ${LIB_PLATFORM}/openssl/1.0/include)
|
||||
message ("Using OpenSSL include files from ${OPENSSL_INCLUDE}")
|
||||
|
||||
|
|
@ -164,6 +169,10 @@ if (USE_AMR_CODEC)
|
|||
set (LIBS ${LIBS} opencore-amrnb opencore-amrwb)
|
||||
endif (USE_AMR_CODEC)
|
||||
|
||||
if (USE_EVS_CODEC)
|
||||
add_definitions(-DUSE_EVS_CODEC)
|
||||
endif()
|
||||
|
||||
target_link_libraries(rtphone
|
||||
ice_stack jrtplib g729_codec gsm_codec
|
||||
gsmhr_codec g722_codec srtp resiprocate
|
||||
|
|
@ -186,6 +195,9 @@ target_include_directories(rtphone
|
|||
${LIB_PLATFORM}/opus/include
|
||||
PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/libs/
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/libs/libevs/lib_com
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/libs/libevs/lib_enc
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/libs/libevs/lib_dec
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/libs/speex/include
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/libs/opus/include/
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/libs/json
|
||||
|
|
|
|||
|
|
@ -35,8 +35,16 @@ target_include_directories(media_lib
|
|||
${CMAKE_CURRENT_SOURCE_DIR}/../../libs/webrtc
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../libs/opus/include/
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../libs/resiprocate/
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../libs/libevs/
|
||||
)
|
||||
|
||||
target_include_directories(media_lib
|
||||
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../../libs/libevs/lib_com
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../libs/libevs/lib_dec
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../libs/libevs/lib_enc
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../libs/libevs/basic_op
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../libs/libevs/basic_math
|
||||
)
|
||||
if (USE_RESIP_INTEGRATION)
|
||||
message("USE_RESIP_INTEGRATION is turned on!")
|
||||
target_compile_definitions(media_lib PUBLIC -DUSE_RESIP_INTEGRATION)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,206 @@
|
|||
#include "MT_EvsCodec.h"
|
||||
|
||||
//bool
|
||||
|
||||
EVSCodec::EVSFactory::EVSFactory(StreamParameters sp) : _sp(sp)
|
||||
{}
|
||||
|
||||
int EVSCodec::EVSFactory::samplerate()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int EVSCodec::EVSFactory::payloadType()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
PCodec EVSCodec::EVSFactory::create()
|
||||
{
|
||||
return std::static_pointer_cast<Codec>(std::make_shared<EVSCodec>(_sp));
|
||||
}
|
||||
|
||||
EVSCodec::EVSCodec(): EVSCodec(StreamParameters())
|
||||
{
|
||||
}
|
||||
|
||||
EVSCodec::EVSCodec(const StreamParameters &sp)
|
||||
{
|
||||
EVSCodec::sp = sp;
|
||||
|
||||
if ((st_dec = (Decoder_State*)malloc(sizeof(Decoder_State))) == NULL)
|
||||
{
|
||||
std::stringstream out;
|
||||
out << "Can not allocate memory for decoder state structure\n";
|
||||
throw std::out_of_range(out.str());
|
||||
}
|
||||
/*if ((st_enc = (Encoder_State*)malloc(sizeof(Encoder_State))) == NULL)
|
||||
{
|
||||
std::stringstream out;
|
||||
out << "Can not allocate memory for encoder state structure\n";
|
||||
throw std::out_of_range(out.str());
|
||||
}*/
|
||||
initDecoder(sp);
|
||||
}
|
||||
|
||||
EVSCodec::~EVSCodec()
|
||||
{
|
||||
if (st_dec)
|
||||
{
|
||||
destroy_decoder(st_dec);
|
||||
free(st_dec);
|
||||
}
|
||||
}
|
||||
|
||||
int EVSCodec::samplerate()
|
||||
{
|
||||
return st_dec->output_Fs;
|
||||
}
|
||||
|
||||
int EVSCodec::samplerate(int CodecMode)
|
||||
{
|
||||
return samplerate();
|
||||
}
|
||||
|
||||
int EVSCodec::pcmLength()
|
||||
{
|
||||
return samplerate() / 50;
|
||||
}
|
||||
|
||||
int EVSCodec::pcmLength(int CodecMode)
|
||||
{
|
||||
return pcmLength();
|
||||
}
|
||||
|
||||
int EVSCodec::frameTime()
|
||||
{
|
||||
return sp.ptime;
|
||||
}
|
||||
|
||||
int EVSCodec::rtpLength()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int EVSCodec::encode(const void* input, int inputBytes, void* output, int outputCapacity)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int EVSCodec::decode(const void* input, int input_length, void* output, int outputCapacity)
|
||||
{
|
||||
if (outputCapacity < L_FRAME8k)
|
||||
{
|
||||
std::stringstream out;
|
||||
out << "Buffer for pcm frame is to small\n";
|
||||
throw std::out_of_range(out.str());
|
||||
}
|
||||
|
||||
std::string buffer;
|
||||
|
||||
/*if we have FixedPayload without ToC*/
|
||||
if (FixedPayload_EVSPrimary.find(input_length * 8) != FixedPayload_EVSPrimary.end())
|
||||
{
|
||||
char c = rate2EVSmode(FixedPayload_EVSPrimary.find(input_length * 8)->second);
|
||||
/* Add ToC byte.
|
||||
* WARNING maybe it will be work incorrect with 56bit payload,
|
||||
* see 3GPP TS 26.445 Annex A, A.2.1.3 */
|
||||
buffer += c;
|
||||
}
|
||||
|
||||
buffer += std::string(reinterpret_cast<const char*>(input), input_length);
|
||||
|
||||
// Output buffer for 48 KHz
|
||||
float data[L_FRAME48k];
|
||||
int offset = 0;
|
||||
|
||||
/* Decode process */
|
||||
size_t buffer_processed = 0;
|
||||
|
||||
while (st_dec->bitstreamformat == G192 ? read_indices(st_dec, buffer.c_str(), buffer.size(), &buffer_processed, 0) : read_indices_mime(st_dec, buffer.c_str(), buffer.size(), &buffer_processed, 0))
|
||||
{
|
||||
if (st_dec->codec_mode == MODE1)
|
||||
{
|
||||
if (st_dec->Opt_AMR_WB)
|
||||
{
|
||||
amr_wb_dec(st_dec, data);
|
||||
}
|
||||
else
|
||||
{
|
||||
evs_dec(st_dec, data, FRAMEMODE_NORMAL);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!st_dec->bfi)
|
||||
{
|
||||
evs_dec(st_dec, data, FRAMEMODE_NORMAL);
|
||||
}
|
||||
else
|
||||
{
|
||||
evs_dec(st_dec, data, FRAMEMODE_MISSING);
|
||||
}
|
||||
}
|
||||
|
||||
/* convert 'float' output data to 'short' */
|
||||
syn_output(data, this->pcmLength(), static_cast<short*>(output) + offset);
|
||||
offset += this->pcmLength();
|
||||
if (st_dec->ini_frame < MAX_FRAME_COUNTER)
|
||||
{
|
||||
st_dec->ini_frame++;
|
||||
}
|
||||
}
|
||||
// std::fclose(temp);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int EVSCodec::plc(int lostFrames, void* output, int outputCapacity)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void EVSCodec::initDecoder(const StreamParameters& sp)
|
||||
{
|
||||
/* set to NULL, to avoid reading of uninitialized memory in case of early abort */
|
||||
st_dec->cldfbAna = st_dec->cldfbBPF = st_dec->cldfbSyn = nullptr;
|
||||
st_dec->hFdCngDec = nullptr;
|
||||
st_dec->codec_mode = 0; /* unknown before first frame */
|
||||
st_dec->Opt_AMR_WB = 0;
|
||||
st_dec->Opt_VOIP = 0;
|
||||
|
||||
st_dec->bitstreamformat = G192;
|
||||
st_dec->amrwb_rfc4867_flag = -1;
|
||||
|
||||
/*Set MIME type*/
|
||||
if (sp.mime) {
|
||||
st_dec->bitstreamformat = MIME;
|
||||
st_dec->amrwb_rfc4867_flag = 0;
|
||||
}
|
||||
/*Set Bandwidth*/
|
||||
switch (sp.bw) {
|
||||
case NB :
|
||||
st_dec->output_Fs = 8000;
|
||||
break;
|
||||
case WB:
|
||||
st_dec->output_Fs = 16000;
|
||||
break;
|
||||
case SWB:
|
||||
st_dec->output_Fs = 32000;
|
||||
break;
|
||||
case FB:
|
||||
st_dec->output_Fs = 48000;
|
||||
break;
|
||||
}
|
||||
// st_enc->input_Fs = st_dec->output_Fs; //TODO: remove when func initEncoder() is added
|
||||
/*------------------------------------------------------------------------------------------*
|
||||
* Allocate memory for static variables
|
||||
* Decoder initialization
|
||||
*------------------------------------------------------------------------------------------*/
|
||||
|
||||
// TODO: add ability of reinit Decoder_state, may be need use destroy_decoder()
|
||||
init_decoder(st_dec);
|
||||
reset_indices_dec(st_dec);
|
||||
|
||||
srand(static_cast<unsigned int>(time(nullptr)));
|
||||
|
||||
}
|
||||
|
|
@ -1,157 +1,210 @@
|
|||
#ifndef MT_EVSCODEC_H
|
||||
#define MT_EVSCODEC_H
|
||||
#pragma once
|
||||
|
||||
#include "../config.h"
|
||||
#include <set>
|
||||
#include <map>
|
||||
#include "MT_Codec.h"
|
||||
#include "../helper/HL_Pointer.h"
|
||||
#include <memory>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <assert.h>
|
||||
#include <sstream>
|
||||
|
||||
#if defined(USE_EVS_CODEC)
|
||||
namespace MT
|
||||
extern "C" {
|
||||
//#include "lib_dec/EvsRXlib.h"
|
||||
#include "libevs/lib_com/prot.h"
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------*
|
||||
* rate2AMRWB_IOmode()
|
||||
*
|
||||
* lookup AMRWB IO mode
|
||||
*-------------------------------------------------------------------*/
|
||||
|
||||
static Word16 rate2AMRWB_IOmode(
|
||||
Word32 rate /* i: bit rate */
|
||||
);
|
||||
|
||||
/*Revers Function*/
|
||||
extern Word16 AMRWB_IOmode2rate(
|
||||
Word32 mode
|
||||
);
|
||||
|
||||
/*-------------------------------------------------------------------*
|
||||
* rate2EVSmode()
|
||||
*
|
||||
* lookup EVS mode
|
||||
*-------------------------------------------------------------------*/
|
||||
extern Word16 rate2EVSmode(
|
||||
Word32 rate /* i: bit rate */
|
||||
);
|
||||
|
||||
/*Revers Function*/
|
||||
extern Word16 EVSmode2rate(
|
||||
Word32 mode
|
||||
);
|
||||
|
||||
class Codec;
|
||||
typedef std::shared_ptr<Codec> PCodec;
|
||||
|
||||
#define CMR_OFF -1
|
||||
#define CMR_ON 0
|
||||
#define CMR_ONLY 1
|
||||
|
||||
|
||||
static const std::map<int, std::set<int>> BitrateToBandwidth_Tab{
|
||||
{5900, {NB, WB}},
|
||||
{7200, {NB, WB}},
|
||||
{8000, {NB, WB}},
|
||||
{9600, {NB, WB, SWB}},
|
||||
{13200, {NB, WB, SWB}}, //if channel aware mode - WB, SWB
|
||||
{16400, {NB, WB, SWB, FB}},
|
||||
{24400, {NB, WB, SWB, FB}},
|
||||
{32000, {WB, SWB, FB}},
|
||||
{48000, {WB, SWB, FB}},
|
||||
{64000, {WB, SWB, FB}},
|
||||
{96000, {WB, SWB, FB}},
|
||||
{128000, {WB, SWB, FB}}
|
||||
};
|
||||
|
||||
/* Protected payload size/Fixed bitrate to EVS ()*/
|
||||
static const std::map<int, int> Bitrate2PayloadSize_EVSAMR_WB{
|
||||
/*{bitrate, payload size}*/
|
||||
{ SID_1k75, 56}, //AMR-WB I/O SIB
|
||||
{ACELP_6k60, 136},
|
||||
{ACELP_8k85, 184},
|
||||
{ACELP_12k65, 256},
|
||||
{ACELP_14k25, 288},
|
||||
{ACELP_15k85, 320},
|
||||
{ACELP_18k25, 368},
|
||||
{ACELP_19k85, 400},
|
||||
{ACELP_23k05, 464},
|
||||
{ACELP_23k85, 480}
|
||||
};
|
||||
|
||||
static const std::map<int, int> Bitrate2PayloadSize_EVS{
|
||||
/*{bitrate, payload size}*/
|
||||
{FRAME__NO_DATA, 0},
|
||||
{SID_2k40, 48}, //EVS Primary SID
|
||||
{PPP_NELP_2k80, 56}, //special for full header
|
||||
{ACELP_7k20, 144},
|
||||
{ACELP_8k00, 160},
|
||||
{ACELP_9k60, 192},
|
||||
{ACELP_13k20, 264},
|
||||
{ACELP_16k40, 328},
|
||||
{ACELP_24k40, 488},
|
||||
{ACELP_32k, 640},
|
||||
{ACELP_48k, 960},
|
||||
{ACELP_64k, 1280},
|
||||
{HQ_96k, 1920},
|
||||
{HQ_128k, 2560}
|
||||
};
|
||||
|
||||
/* Protected payload size/Fixed bitrate to EVS ()*/
|
||||
static const std::map<int, int> FixedPayload_EVSPrimary{
|
||||
/*{payload size , bitrate}*/
|
||||
{48, 2400}, //EVS Primary SID
|
||||
{56, 2800}, //special for full header
|
||||
{144, 7200},
|
||||
{160, 8000},
|
||||
{192, 9600},
|
||||
{264, 13200},
|
||||
{328, 16400},
|
||||
{488, 24400},
|
||||
{640, 32000},
|
||||
{960, 48000},
|
||||
{1280, 64000},
|
||||
{1920, 96000},
|
||||
{2560, 128000}
|
||||
};
|
||||
|
||||
static const std::map<int, int> FixedPayload_EVSAMR_WB{
|
||||
/*{payload size , bitrate}*/
|
||||
{136, 6600},
|
||||
{184, 8850},
|
||||
{256, 12650},
|
||||
{288, 14250},
|
||||
{320, 15850},
|
||||
{368, 18250},
|
||||
{400, 19850},
|
||||
{464, 23050},
|
||||
{480, 23850}
|
||||
};
|
||||
|
||||
struct StreamParameters {
|
||||
bool mime = false;
|
||||
bool fh_only = false; /*not use*/
|
||||
int CRMByte = CMR_OFF;/*not use*/
|
||||
int br = 0; /*not use*/
|
||||
int bw = NB;
|
||||
int ptime = 20;
|
||||
}; //Emulated SDP config/meadia type parameters
|
||||
|
||||
class Codec
|
||||
{
|
||||
struct AmrCodecConfig
|
||||
{
|
||||
bool mIuUP;
|
||||
bool mOctetAligned;
|
||||
int mPayloadType;
|
||||
};
|
||||
|
||||
class AmrNbCodec : public Codec
|
||||
{
|
||||
protected:
|
||||
void* mEncoderCtx;
|
||||
void* mDecoderCtx;
|
||||
AmrCodecConfig mConfig;
|
||||
unsigned mCurrentDecoderTimestamp;
|
||||
int mSwitchCounter;
|
||||
int mPreviousPacketLength;
|
||||
|
||||
public:
|
||||
class CodecFactory: public Factory
|
||||
public:
|
||||
class Factory
|
||||
{
|
||||
public:
|
||||
CodecFactory(const AmrCodecConfig& config);
|
||||
virtual ~Factory() {}
|
||||
virtual const char* name() = 0;
|
||||
virtual int samplerate() = 0;
|
||||
virtual int payloadType() = 0;
|
||||
virtual PCodec create() = 0;
|
||||
|
||||
const char* name() override;
|
||||
int samplerate() override;
|
||||
int payloadType() override;
|
||||
|
||||
#if defined(USE_RESIP_INTEGRATION)
|
||||
void updateSdp(resip::SdpContents::Session::Medium::CodecContainer& codecs, SdpDirection direction) override;
|
||||
int processSdp(const resip::SdpContents::Session::Medium::CodecContainer& codecs, SdpDirection direction) override;
|
||||
void create(CodecMap& codecs) override;
|
||||
#endif
|
||||
PCodec create() override;
|
||||
|
||||
protected:
|
||||
AmrCodecConfig mConfig;
|
||||
virtual int channels() = 0;
|
||||
};
|
||||
virtual ~Codec() {}
|
||||
virtual const char* name() = 0;
|
||||
virtual int samplerate() = 0;
|
||||
virtual float timestampUnit() { return float(1.0 / samplerate()); }
|
||||
virtual int pcmLength() = 0;
|
||||
virtual int frameTime() = 0;
|
||||
virtual int rtpLength() = 0;
|
||||
virtual int channels() { return 1; }
|
||||
virtual int encode(const void* input, int inputBytes, void* output, int outputCapacity) = 0;
|
||||
virtual int decode(const void* input, int inputBytes, void* output, int outputCapacity) = 0;
|
||||
virtual int plc(int lostFrames, void* output, int outputCapacity) = 0;
|
||||
|
||||
AmrNbCodec(const AmrCodecConfig& config);
|
||||
// Returns size of codec in memory
|
||||
virtual int getSize() const { return 0; };
|
||||
};
|
||||
|
||||
virtual ~AmrNbCodec();
|
||||
const char* name() override;
|
||||
int pcmLength() override;
|
||||
int rtpLength() override;
|
||||
int frameTime() override;
|
||||
int samplerate() override;
|
||||
int encode(const void* input, int inputBytes, void* output, int outputCapacity) override;
|
||||
int decode(const void* input, int inputBytes, void* output, int outputCapacity) override;
|
||||
int plc(int lostFrames, void* output, int outputCapacity) override;
|
||||
int getSwitchCounter() const;
|
||||
};
|
||||
class EVSCodec : public Codec
|
||||
{
|
||||
private:
|
||||
Decoder_State* st_dec;
|
||||
//Encoder_State_fx* st_enc;
|
||||
StreamParameters sp;
|
||||
|
||||
class AmrWbCodec : public Codec
|
||||
{
|
||||
protected:
|
||||
void* mEncoderCtx;
|
||||
void* mDecoderCtx;
|
||||
AmrCodecConfig mConfig;
|
||||
uint64_t mCurrentDecoderTimestamp;
|
||||
int mSwitchCounter;
|
||||
int mPreviousPacketLength;
|
||||
|
||||
public:
|
||||
class CodecFactory: public Factory
|
||||
public:
|
||||
class EVSFactory : public Factory
|
||||
{
|
||||
public:
|
||||
CodecFactory(const AmrCodecConfig& config);
|
||||
|
||||
const char* name() override;
|
||||
int samplerate() override;
|
||||
int payloadType() override;
|
||||
|
||||
#if defined(USE_RESIP_INTEGRATION)
|
||||
void updateSdp(resip::SdpContents::Session::Medium::CodecContainer& codecs, SdpDirection direction) override;
|
||||
int processSdp(const resip::SdpContents::Session::Medium::CodecContainer& codecs, SdpDirection direction) override;
|
||||
void create(CodecMap& codecs) override;
|
||||
#endif
|
||||
PCodec create() override;
|
||||
|
||||
protected:
|
||||
AmrCodecConfig mConfig;
|
||||
StreamParameters _sp;
|
||||
|
||||
public:
|
||||
EVSFactory(StreamParameters sp);
|
||||
const char* name() { return "EVS"; };
|
||||
int samplerate();
|
||||
int payloadType();
|
||||
PCodec create();
|
||||
int channels() { return 1; } //without support stereo audio transmition
|
||||
};
|
||||
|
||||
AmrWbCodec(const AmrCodecConfig& config);
|
||||
virtual ~AmrWbCodec();
|
||||
|
||||
const char* name() override;
|
||||
int pcmLength() override;
|
||||
int rtpLength() override;
|
||||
int frameTime() override;
|
||||
int samplerate() override;
|
||||
int encode(const void* input, int inputBytes, void* output, int outputCapacity) override;
|
||||
int decode(const void* input, int inputBytes, void* output, int outputCapacity) override;
|
||||
int plc(int lostFrames, void* output, int outputCapacity) override;
|
||||
int getSwitchCounter() const;
|
||||
};
|
||||
|
||||
class GsmEfrCodec : public Codec
|
||||
{
|
||||
protected:
|
||||
void* mEncoderCtx;
|
||||
void* mDecoderCtx;
|
||||
bool mIuUP;
|
||||
|
||||
public:
|
||||
class GsmEfrFactory: public Factory
|
||||
{
|
||||
public:
|
||||
GsmEfrFactory(bool iuup, int ptype);
|
||||
|
||||
const char* name() override;
|
||||
int samplerate() override;
|
||||
int payloadType() override;
|
||||
|
||||
#if defined(USE_RESIP_INTEGRATION)
|
||||
void updateSdp(resip::SdpContents::Session::Medium::CodecContainer& codecs, SdpDirection direction) override;
|
||||
int processSdp(const resip::SdpContents::Session::Medium::CodecContainer& codecs, SdpDirection direction) override;
|
||||
void create(CodecMap& codecs) override;
|
||||
#endif
|
||||
PCodec create() override;
|
||||
|
||||
protected:
|
||||
bool mIuUP;
|
||||
int mPayloadType;
|
||||
};
|
||||
|
||||
GsmEfrCodec(bool iuup = false);
|
||||
|
||||
virtual ~GsmEfrCodec();
|
||||
const char* name() override;
|
||||
int pcmLength() override;
|
||||
int rtpLength() override;
|
||||
int frameTime() override;
|
||||
int samplerate() override;
|
||||
int encode(const void* input, int inputBytes, void* output, int outputCapacity) override;
|
||||
int decode(const void* input, int inputBytes, void* output, int outputCapacity) override;
|
||||
int plc(int lostFrames, void* output, int outputCapacity) override;
|
||||
};
|
||||
|
||||
} // End of MT namespace
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#endif // MT_EVSCODE_H
|
||||
EVSCodec();
|
||||
EVSCodec(const StreamParameters& sp);
|
||||
~EVSCodec() override;
|
||||
|
||||
const char* name() { return "EVS"; };
|
||||
int samplerate();
|
||||
int samplerate(int CodecMode); // DEC or ENC defined in cnst.h
|
||||
int pcmLength();
|
||||
int pcmLength(int CodecMode); // DEC or ENC defined in cnst.h
|
||||
int frameTime();
|
||||
int rtpLength();
|
||||
int encode(const void* input, int inputBytes, void* output, int outputCapacity);
|
||||
int decode(const void* input, int inputBytes, void* output, int outputCapacity);
|
||||
int plc(int lostFrames, void* output, int outputCapacity) ;
|
||||
void initDecoder(const StreamParameters& sp);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
@ -1,81 +1,73 @@
|
|||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
EVS Codec 3GPP TS26.443 Nov 13, 2018. Version 12.11.0 / 13.7.0 / 14.3.0 / 15.1.0
|
||||
====================================================================================*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include "options.h"
|
||||
#include "basop_util.h"
|
||||
#include "cnst_fx.h"
|
||||
#include "prot_fx.h"
|
||||
#include "rom_com_fx.h"
|
||||
#include "stl.h"
|
||||
#include "cnst.h"
|
||||
#include "prot.h"
|
||||
|
||||
/* Returns: index of next coefficient */
|
||||
Word16 get_next_coeff_mapped(
|
||||
Word16 ii[2], /* i/o: coefficient indexes */
|
||||
Word16 *pp, /* o : peak(1)/hole(0) indicator */
|
||||
Word16 *idx, /* o : index in unmapped domain */
|
||||
|
||||
/*-------------------------------------------------------------------*
|
||||
* get_next_coeff_mapped()
|
||||
*
|
||||
*
|
||||
*-------------------------------------------------------------------*/
|
||||
|
||||
int get_next_coeff_mapped( /* o : index of next coefficient */
|
||||
int ii[2], /* i/o: coefficient indexes */
|
||||
int *pp, /* o : peak(1)/hole(0) indicator */
|
||||
int *idx, /* o : index in unmapped domain */
|
||||
CONTEXT_HM_CONFIG *hm_cfg /* i : HM configuration */
|
||||
)
|
||||
{
|
||||
Word16 p;
|
||||
unsigned int p;
|
||||
|
||||
p = s_and(sub(ii[1], hm_cfg->numPeakIndices), sub(hm_cfg->indexBuffer[ii[1]], hm_cfg->indexBuffer[ii[0]]));
|
||||
if (p > 0)
|
||||
{
|
||||
p = 0;
|
||||
move16();
|
||||
}
|
||||
if (p < 0)
|
||||
{
|
||||
p = 1;
|
||||
move16();
|
||||
}
|
||||
p = (ii[1] - hm_cfg->numPeakIndices) & (hm_cfg->indexBuffer[ii[1]] - hm_cfg->indexBuffer[ii[0]]);
|
||||
p >>= sizeof(p)*8-1;
|
||||
*pp = p;
|
||||
move16();
|
||||
*idx = ii[p];
|
||||
move16();
|
||||
ii[p] = add(ii[p], 1);
|
||||
move16();
|
||||
ii[p]++;
|
||||
|
||||
return hm_cfg->indexBuffer[*idx];
|
||||
}
|
||||
|
||||
/* Returns: index of next coefficient */
|
||||
Word16 get_next_coeff_unmapped(
|
||||
Word16 ii[2], /* i/o: coefficient indexes */
|
||||
Word16 *pp, /* o : peak(1)/hole(0) indicator */
|
||||
Word16 *idx, /* o : index in unmapped domain */
|
||||
CONTEXT_HM_CONFIG *hm_cfg /* i : HM configuration */
|
||||
|
||||
/*-------------------------------------------------------------------*
|
||||
* get_next_coeff_unmapped()
|
||||
*
|
||||
*
|
||||
*-------------------------------------------------------------------*/
|
||||
|
||||
int get_next_coeff_unmapped(/* o : index of next coefficient */
|
||||
int *ii, /* i/o: coefficient indexes */
|
||||
int *idx /* o : index in unmapped domain */
|
||||
)
|
||||
{
|
||||
(void)pp;
|
||||
(void)hm_cfg;
|
||||
*idx = *ii;
|
||||
(*ii)++;
|
||||
|
||||
*idx = ii[0];
|
||||
move16();
|
||||
ii[0] = add(ii[0], 1);
|
||||
move16();
|
||||
return *idx;
|
||||
}
|
||||
|
||||
Word16 update_mixed_context(Word16 ctx, Word16 a)
|
||||
/*-------------------------------------------------------------------*
|
||||
* update_mixed_context()
|
||||
*
|
||||
*
|
||||
*-------------------------------------------------------------------*/
|
||||
|
||||
int update_mixed_context(
|
||||
int ctx,
|
||||
int a
|
||||
)
|
||||
{
|
||||
Word32 t32;
|
||||
Word16 t=0; /* initialize just to avoid compiler warning */
|
||||
int t;
|
||||
|
||||
t32 = L_mac0(1-13, s_and(a, ~1), add(shr(a, 2), 1));
|
||||
if (t32 <= 0)
|
||||
t = 1-13 + (a & ~1)*((a>>2)+1);
|
||||
|
||||
if (t > 0)
|
||||
{
|
||||
t = extract_l(t32);
|
||||
t = min((a>>3), 2);
|
||||
}
|
||||
a = shr(a, 3);
|
||||
if (t32 > 0)
|
||||
{
|
||||
t = s_min(a, 2);
|
||||
}
|
||||
return add(shl(s_and(ctx, 0xf), 4), add(t, 13));
|
||||
|
||||
return (ctx & 0xf) * 16 + t + 13;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,57 +1,39 @@
|
|||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
EVS Codec 3GPP TS26.443 Nov 13, 2018. Version 12.11.0 / 13.7.0 / 14.3.0 / 15.1.0
|
||||
====================================================================================*/
|
||||
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include "cnst.h"
|
||||
#include "prot.h"
|
||||
#include "stat_com.h"
|
||||
#include "assert.h"
|
||||
#include "prot_fx.h"
|
||||
#include "basop_mpy.h"
|
||||
#include "cnst_fx.h"
|
||||
#include "stl.h"
|
||||
#include "basop_util.h"
|
||||
|
||||
/**
|
||||
* \brief 31x16 Bit multiply (x*y)
|
||||
*
|
||||
* \param[i] xh high part, bit [30..15]
|
||||
* \param[i] xl low part, 15 LSBits
|
||||
* \param[i] y
|
||||
*
|
||||
* \return x*y
|
||||
*/
|
||||
Word32 L_multi31x16_X2(Word16 xh, Word16 xl, Word16 y)
|
||||
{
|
||||
Word32 z;
|
||||
#ifndef int32
|
||||
#define int32 int
|
||||
#endif
|
||||
|
||||
z = L_shl(L_mult0(xh,y),15);
|
||||
z = L_mac0(z,xl,y);
|
||||
|
||||
return z;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
Ari 14 bits common routines
|
||||
-------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* \brief Integer Multiply
|
||||
* \brief Integer Multiply
|
||||
*
|
||||
* \param[i] r
|
||||
* \param[i] c
|
||||
*
|
||||
* \return r*c
|
||||
*/
|
||||
Word32 mul_sbc_14bits(Word32 r, Word16 c)
|
||||
long mul_sbc_14bits(long r,long c)
|
||||
{
|
||||
Word32 ret;
|
||||
long temp;
|
||||
/*function in line*/
|
||||
temp = (((int32) r)*((int32) c))>>stat_bitsnew;
|
||||
return temp;
|
||||
|
||||
|
||||
/*
|
||||
temp = (((int32) r)*((int32) c))>>stat_bitsnew;
|
||||
*/
|
||||
assert(stat_bitsnew == 14);
|
||||
ret = Mpy_32_16_1(L_shl(r,15-stat_bitsnew), c);
|
||||
|
||||
/*assert( (((int) r)*((int) c))>>stat_bitsnew == ret);*/
|
||||
|
||||
return (ret);
|
||||
/*function in line*/
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,211 +1,196 @@
|
|||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
EVS Codec 3GPP TS26.443 Nov 13, 2018. Version 12.11.0 / 13.7.0 / 14.3.0 / 15.1.0
|
||||
====================================================================================*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
#include "cnst.h"
|
||||
#include "stl.h"
|
||||
#include "cnst_fx.h"
|
||||
#include "basop_util.h"
|
||||
#include "rom_com_fx.h"
|
||||
#include "prot_fx.h"
|
||||
#include "prot.h"
|
||||
#include "rom_com.h"
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------*
|
||||
* UnmapIndex()
|
||||
*
|
||||
*
|
||||
*-------------------------------------------------------------------*/
|
||||
|
||||
void UnmapIndex(
|
||||
Word16 PeriodicityIndex,
|
||||
Word16 Bandwidth,
|
||||
Word16 LtpPitchLag,
|
||||
Word8 SmallerLags,
|
||||
Word16 *FractionalResolution,
|
||||
Word32 *Lag)
|
||||
int PeriodicityIndex,
|
||||
int Bandwidth,
|
||||
short LtpPitchLag,
|
||||
int SmallerLags,
|
||||
int *FractionalResolution,
|
||||
int *Lag)
|
||||
{
|
||||
Word16 LtpPitchIndex, Multiplier;
|
||||
Word16 Lag16;
|
||||
|
||||
test();
|
||||
IF ((LtpPitchLag > 0) && (s_and(PeriodicityIndex, kLtpHmFlag) != 0))
|
||||
if ((LtpPitchLag > 0) && (PeriodicityIndex & kLtpHmFlag))
|
||||
{
|
||||
LtpPitchIndex = shr(PeriodicityIndex, 9);
|
||||
Multiplier = s_and(PeriodicityIndex, 0xff);
|
||||
|
||||
int LtpPitchIndex, Multiplier;
|
||||
LtpPitchIndex = PeriodicityIndex >> 9;
|
||||
Multiplier = PeriodicityIndex & 0xff;
|
||||
assert(0 <= LtpPitchIndex && LtpPitchIndex <= 16);
|
||||
assert(1 <= Multiplier && Multiplier <= (1 << NumRatioBits[Bandwidth][LtpPitchIndex]));
|
||||
|
||||
*FractionalResolution = kLtpHmFractionalResolution;
|
||||
move16();
|
||||
*Lag = L_shr(L_mult0(LtpPitchLag, Ratios[Bandwidth][LtpPitchIndex][Multiplier-1]), 8);
|
||||
move32();
|
||||
*Lag = (LtpPitchLag * (int)(4 * Ratios[Bandwidth][LtpPitchIndex][Multiplier-1])) >> 2;
|
||||
}
|
||||
ELSE
|
||||
else
|
||||
{
|
||||
IF (sub(PeriodicityIndex, 16) < 0)
|
||||
if (PeriodicityIndex < 16)
|
||||
{
|
||||
*FractionalResolution = 3;
|
||||
move16();
|
||||
Lag16 = add(PeriodicityIndex, GET_ADJ2(0, 6, 3));
|
||||
*Lag = PeriodicityIndex + GET_ADJ(0, 6);
|
||||
}
|
||||
ELSE IF (sub(PeriodicityIndex, 80) < 0)
|
||||
else if (PeriodicityIndex < 80)
|
||||
{
|
||||
*FractionalResolution = 4;
|
||||
move16();
|
||||
Lag16 = add(PeriodicityIndex, GET_ADJ2(16, 8, 4));
|
||||
*Lag = PeriodicityIndex + GET_ADJ(16, 8);
|
||||
}
|
||||
ELSE IF (sub(PeriodicityIndex, 208) < 0)
|
||||
else if (PeriodicityIndex < 208)
|
||||
{
|
||||
*FractionalResolution = 3;
|
||||
move16();
|
||||
Lag16 = add(PeriodicityIndex, GET_ADJ2(80, 12, 3));
|
||||
*Lag = PeriodicityIndex + GET_ADJ(80, 12);
|
||||
}
|
||||
ELSE {
|
||||
test();
|
||||
IF (sub(PeriodicityIndex, 224) < 0 || SmallerLags != 0)
|
||||
{
|
||||
*FractionalResolution = 1;
|
||||
move16();
|
||||
Lag16 = add(PeriodicityIndex, GET_ADJ2(208, 28, 1));
|
||||
}
|
||||
ELSE {
|
||||
*FractionalResolution = 0;
|
||||
move16();
|
||||
Lag16 = add(PeriodicityIndex, GET_ADJ2(224, 188, 0));
|
||||
}
|
||||
else if (PeriodicityIndex < 224 || SmallerLags)
|
||||
{
|
||||
*FractionalResolution = 1;
|
||||
*Lag = PeriodicityIndex + GET_ADJ(208, 28);
|
||||
}
|
||||
else
|
||||
{
|
||||
*FractionalResolution = 0;
|
||||
*Lag = PeriodicityIndex + GET_ADJ(224, 188);
|
||||
}
|
||||
*Lag = L_deposit_l(Lag16);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------*
|
||||
* ConfigureContextHm()
|
||||
*
|
||||
*
|
||||
*-------------------------------------------------------------------*/
|
||||
|
||||
void ConfigureContextHm(
|
||||
Word16 NumCoeffs, /* (I) Number of coefficients */
|
||||
Word16 TargetBits, /* (I) Target bit budget (excl. Done flag) */
|
||||
Word16 PeriodicityIndex, /* (I) Pitch related index */
|
||||
Word16 LtpPitchLag, /* (I) TCX-LTP pitch in F.D. */
|
||||
int NumCoeffs, /* (I) Number of coefficients */
|
||||
int TargetBits, /* (I) Target bit budget (excl. Done flag) */
|
||||
int PeriodicityIndex, /* (I) Pitch related index */
|
||||
short LtpPitchLag, /* (I) TCX-LTP pitch in F.D. */
|
||||
CONTEXT_HM_CONFIG *hm_cfg /* (O) Context-based harmonic model configuration */
|
||||
)
|
||||
{
|
||||
Word8 Bandwidth, SmallerLags;
|
||||
Word32 i, Limit, Lag;
|
||||
Word16 j, Index, FractionalResolution;
|
||||
Word16 *tmp;
|
||||
|
||||
int Bandwidth, SmallerLags;
|
||||
int i, Limit, Lag;
|
||||
int j, Index, FractionalResolution;
|
||||
int *tmp;
|
||||
|
||||
Bandwidth = 0;
|
||||
move16();
|
||||
if (sub(NumCoeffs, 256) >= 0)
|
||||
if (NumCoeffs >= 256)
|
||||
{
|
||||
Bandwidth = 1;
|
||||
move16();
|
||||
}
|
||||
|
||||
SmallerLags = 0;
|
||||
move16();
|
||||
test();
|
||||
if ((sub(TargetBits, kSmallerLagsTargetBitsThreshold) <= 0) || (Bandwidth == 0))
|
||||
|
||||
if (TargetBits <= kSmallerLagsTargetBitsThreshold || Bandwidth == 0)
|
||||
{
|
||||
SmallerLags = 1;
|
||||
move16();
|
||||
}
|
||||
|
||||
UnmapIndex(PeriodicityIndex,
|
||||
Bandwidth,
|
||||
LtpPitchLag,
|
||||
SmallerLags,
|
||||
&FractionalResolution, &Lag);
|
||||
UnmapIndex(PeriodicityIndex, Bandwidth, LtpPitchLag, SmallerLags, &FractionalResolution, &Lag );
|
||||
|
||||
/* Set up and fill peakIndices */
|
||||
hm_cfg->peakIndices = hm_cfg->indexBuffer;
|
||||
tmp = hm_cfg->peakIndices;
|
||||
Limit = L_shl(L_deposit_l(sub(NumCoeffs, 1)), FractionalResolution);
|
||||
IF (L_sub(Lag, Limit) < 0)
|
||||
Limit = (NumCoeffs - 1) << FractionalResolution;
|
||||
|
||||
for (i=Lag; i<Limit; i+=Lag)
|
||||
{
|
||||
FOR (i=Lag; i<Limit; i+=Lag)
|
||||
{
|
||||
Index = extract_l(L_shr(i, FractionalResolution));
|
||||
*tmp++ = sub(Index, 1);
|
||||
move16();
|
||||
*tmp++ = Index;
|
||||
move16();
|
||||
*tmp++ = add(Index, 1);
|
||||
move16();
|
||||
}
|
||||
Index = i >> FractionalResolution;
|
||||
*tmp++ = Index - 1;
|
||||
*tmp++ = Index;
|
||||
*tmp++ = Index + 1;
|
||||
}
|
||||
hm_cfg->numPeakIndices = (Word16)(tmp - hm_cfg->indexBuffer);
|
||||
hm_cfg->numPeakIndices = tmp - hm_cfg->indexBuffer;
|
||||
|
||||
/* Set up and fill holeIndices */
|
||||
hm_cfg->holeIndices = hm_cfg->indexBuffer + hm_cfg->numPeakIndices;
|
||||
tmp = hm_cfg->holeIndices;
|
||||
Index = 0;
|
||||
move16();
|
||||
IF (hm_cfg->numPeakIndices > 0)
|
||||
|
||||
for (j=0; j<hm_cfg->numPeakIndices; j+=3)
|
||||
{
|
||||
FOR (j=0; j<hm_cfg->numPeakIndices; j+=3)
|
||||
{
|
||||
FOR (; Index<hm_cfg->peakIndices[j]; ++Index)
|
||||
{
|
||||
*tmp++ = Index;
|
||||
move16();
|
||||
}
|
||||
Index = add(Index, 3); /* Skip the peak */
|
||||
}
|
||||
}
|
||||
IF (sub(Index, NumCoeffs) < 0)
|
||||
{
|
||||
FOR (; Index<NumCoeffs; ++Index)
|
||||
for (; Index<hm_cfg->peakIndices[j]; ++Index)
|
||||
{
|
||||
*tmp++ = Index;
|
||||
move16();
|
||||
}
|
||||
Index += 3; /* Skip the peak */
|
||||
}
|
||||
hm_cfg->numHoleIndices = (Word16)(tmp - hm_cfg->holeIndices);
|
||||
*tmp++ = NumCoeffs;
|
||||
move16(); /* Add extremal element signaling the end of the buffer */
|
||||
|
||||
}
|
||||
|
||||
Word16 CountIndexBits(
|
||||
Word16 Bandwidth,
|
||||
Word16 PeriodicityIndex)
|
||||
{
|
||||
Word16 result;
|
||||
Word16 PeriodicityIndexS;
|
||||
|
||||
result = 8;
|
||||
move16();
|
||||
PeriodicityIndexS = shr(PeriodicityIndex, 9);
|
||||
|
||||
if (s_and(PeriodicityIndex, kLtpHmFlag) != 0)
|
||||
for (; Index<NumCoeffs; ++Index)
|
||||
{
|
||||
result = NumRatioBits[Bandwidth][PeriodicityIndexS];
|
||||
move16();
|
||||
*tmp++ = Index;
|
||||
}
|
||||
hm_cfg->numHoleIndices = tmp - hm_cfg->holeIndices;
|
||||
/* Add extremal element signaling the end of the buffer */
|
||||
*tmp++ = NumCoeffs;
|
||||
|
||||
return result;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------*
|
||||
* CountIndexBits()
|
||||
*
|
||||
*
|
||||
*-------------------------------------------------------------------*/
|
||||
|
||||
int CountIndexBits(
|
||||
int Bandwidth,
|
||||
int PeriodicityIndex)
|
||||
{
|
||||
|
||||
if (PeriodicityIndex & kLtpHmFlag)
|
||||
{
|
||||
int LtpPitchIndex = PeriodicityIndex >> 9;
|
||||
return NumRatioBits[Bandwidth][LtpPitchIndex];
|
||||
}
|
||||
return 8;
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------*
|
||||
* tcx_hm_render()
|
||||
*
|
||||
*
|
||||
*-------------------------------------------------------------------*/
|
||||
|
||||
int tcx_hm_render(
|
||||
Word32 lag, /* i: pitch lag Q0 */
|
||||
Word16 fract_res, /* i: fractional resolution of the lag Q0 */
|
||||
Word16 p[] /* o: harmonic model Q13 */
|
||||
int lag, /* i: pitch lag */
|
||||
int fract_res, /* i: fractional resolution of the lag */
|
||||
float LtpGain, /* i: LTP gain */
|
||||
Word16 p[] /* o: harmonic model (Q13) */
|
||||
)
|
||||
{
|
||||
Word16 k, tmp, height;
|
||||
Word16 PeakDeviation;
|
||||
int k;
|
||||
Word32 f0, tmp32;
|
||||
Word16 height, PeakDeviation, tmp;
|
||||
|
||||
/* Set up overall shape */
|
||||
f0 = L_shl(lag, sub(15, fract_res)); /* Q31 */
|
||||
(void)LtpGain;
|
||||
|
||||
tmp32 = Mpy_32_16_1(f0, -26474);
|
||||
f0 = L_shl(lag, sub(15, fract_res)); /* Q15 */
|
||||
|
||||
tmp32 = Mpy_32_16(f0, -26474);
|
||||
tmp32 = L_shr_r(BASOP_Util_InvLog2(L_shl(tmp32, 7)), 2);
|
||||
tmp32 = L_sub(603979776L, tmp32);
|
||||
tmp32 = L_add(L_add(tmp32, tmp32), Mpy_32_16_1(tmp32, 26214));
|
||||
tmp32 = L_add(L_add(tmp32, tmp32), Mpy_32_16(tmp32, 26214));
|
||||
height = round_fx(tmp32); /* Q13 */
|
||||
|
||||
tmp32 = Mpy_32_16_1(f0, -18910);
|
||||
tmp32 = Mpy_32_16(f0, -18910);
|
||||
tmp32 = L_shr_r(BASOP_Util_InvLog2(L_shl(tmp32, 7)), 2);
|
||||
tmp32 = L_sub(1395864371L, tmp32);
|
||||
PeakDeviation = round_fx(tmp32); /* Q14 */
|
||||
|
|
@ -221,72 +206,65 @@ int tcx_hm_render(
|
|||
tmp = mult_r(tmp, tmp); /* Q15 */
|
||||
}
|
||||
|
||||
tmp = div_s(13915, PeakDeviation);
|
||||
tmp = mult_r(tmp, tmp); /* Q15 */
|
||||
|
||||
/* Render the prototype peak */
|
||||
p[kTcxHmParabolaHalfWidth] = height;
|
||||
move16();
|
||||
|
||||
FOR (k=1; k<=kTcxHmParabolaHalfWidth; ++k)
|
||||
for (k=1; k<=kTcxHmParabolaHalfWidth; ++k)
|
||||
{
|
||||
p[kTcxHmParabolaHalfWidth+k] = round_fx(Mpy_32_16_1(BASOP_Util_InvLog2(L_shl(L_mult0(i_mult2(negate(k),k), tmp),10)), height));
|
||||
p[kTcxHmParabolaHalfWidth+k] = round_fx(Mpy_32_16(BASOP_Util_InvLog2(L_shl(L_mult0(mult0(negate(k),k), tmp),10)), height));
|
||||
}
|
||||
/* Mirror */
|
||||
FOR (k=-kTcxHmParabolaHalfWidth; k<0; ++k)
|
||||
for (k=-kTcxHmParabolaHalfWidth; k<0; ++k)
|
||||
{
|
||||
p[kTcxHmParabolaHalfWidth+k] = p[kTcxHmParabolaHalfWidth-k];
|
||||
move16();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------*
|
||||
* tcx_hm_modify_envelope()
|
||||
*
|
||||
*
|
||||
*-------------------------------------------------------------------*/
|
||||
|
||||
void tcx_hm_modify_envelope(
|
||||
Word16 gain, /* i: HM gain Q11 */
|
||||
Word32 lag, /* i: pitch lag Q0 */
|
||||
Word16 fract_res, /* i: fractional resolution of the lag Q0 */
|
||||
Word16 p[], /* i: harmonic model Q13 */
|
||||
Word32 env[], /* i/o: envelope Q16 */
|
||||
Word16 L_frame /* i: number of spectral lines Q0 */
|
||||
Word16 gain, /* i: HM gain (Q11) */
|
||||
int lag,
|
||||
int fract_res,
|
||||
Word16 p[], /* i: harmonic model (Q13) */
|
||||
Word32 env[], /* i/o: envelope (Q16) */
|
||||
int L_frame /* i: number of spectral lines */
|
||||
)
|
||||
{
|
||||
Word16 k, h, x, l1,l2, L_frame_m1, L_frame_for_loop;
|
||||
Word16 inv_shape[2*kTcxHmParabolaHalfWidth+1];
|
||||
int k;
|
||||
int h, x;
|
||||
Word16 inv_shape[2*kTcxHmParabolaHalfWidth+1]; /* Q15 */
|
||||
|
||||
IF ( gain == 0 )
|
||||
if (gain == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
FOR (k=0; k<2*kTcxHmParabolaHalfWidth+1; ++k)
|
||||
for (k=0; k<2*kTcxHmParabolaHalfWidth+1; ++k)
|
||||
{
|
||||
/* Q24 = Q11 * Q13; 512 = 1.0 in Q24 format */
|
||||
inv_shape[k] = div_s(512, add(512, mult_r(gain, p[k])));
|
||||
move16();
|
||||
inv_shape[k] = div_s(512, add(512, round_fx(L_mult(gain, p[k]))));
|
||||
}
|
||||
|
||||
h = 1;
|
||||
move16();
|
||||
k = extract_l(L_shr(lag,fract_res));
|
||||
k = lag >> fract_res;
|
||||
|
||||
L_frame_m1 = sub(L_frame,1);
|
||||
L_frame_for_loop = add(L_frame,kTcxHmParabolaHalfWidth - 1);
|
||||
|
||||
WHILE ( sub(k,L_frame_for_loop) <= 0 )
|
||||
while (k <= L_frame + kTcxHmParabolaHalfWidth - 1)
|
||||
{
|
||||
l1 = s_max(0, sub(k,kTcxHmParabolaHalfWidth));
|
||||
l2 = s_min(add(k,kTcxHmParabolaHalfWidth), L_frame_m1);
|
||||
FOR (x=l1; x<=l2; ++x)
|
||||
{
|
||||
env[x] = Mpy_32_16_1(env[x], inv_shape[x-k+kTcxHmParabolaHalfWidth]);
|
||||
move32();
|
||||
}
|
||||
|
||||
h = add(h,1);
|
||||
k = extract_l(L_shr(imult3216(lag,h),fract_res));
|
||||
for (x=max(0, k-kTcxHmParabolaHalfWidth); x<=min(k+kTcxHmParabolaHalfWidth, L_frame-1); ++x)
|
||||
{
|
||||
env[x] = Mpy_32_16(env[x], inv_shape[x-k+kTcxHmParabolaHalfWidth]);
|
||||
}
|
||||
++h;
|
||||
k = (h * lag) >> fract_res;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,31 +1,35 @@
|
|||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
EVS Codec 3GPP TS26.443 Nov 13, 2018. Version 12.11.0 / 13.7.0 / 14.3.0 / 15.1.0
|
||||
====================================================================================*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "prot_fx.h"
|
||||
#include "basop_util.h"
|
||||
#include "options.h"
|
||||
#include "cnst_fx.h"
|
||||
#include "stl.h"
|
||||
#include "cnst.h"
|
||||
#include "prot.h"
|
||||
#include "basop_util.h"
|
||||
#include "basop_proto_func.h"
|
||||
|
||||
/* Fixed point implementation of exp(negate()) */
|
||||
Word32 expfp( /* o: Q31 */
|
||||
Word16 x, /* i: mantissa Q-e */
|
||||
Word16 x_e) /* i: exponent Q0 */
|
||||
|
||||
|
||||
|
||||
/*-------------------------------------------------------*
|
||||
* expfp()
|
||||
*
|
||||
* Fixed point implementation of exp()
|
||||
*-------------------------------------------------------*/
|
||||
|
||||
Word16 expfp( /* o: Q15 */
|
||||
Word16 x, /* i: mantissa Q15-e */
|
||||
Word16 x_e) /* i: exponent Q0 */
|
||||
{
|
||||
Word16 xi, xf, tmp;
|
||||
Word16 b0, b1, b2, b3;
|
||||
Word32 y, L_tmp;
|
||||
|
||||
assert(x <= 0);
|
||||
|
||||
assert(x > 0);
|
||||
|
||||
L_tmp = L_shl(L_deposit_h(x), x_e);
|
||||
L_tmp = L_negate(L_shl(L_deposit_h(x), sub(x_e, 15)));
|
||||
|
||||
/* split into integer and fractional parts */
|
||||
xi = round_fx(L_tmp);
|
||||
|
|
@ -55,10 +59,10 @@ Word32 expfp( /* o: Q31 */
|
|||
b2 = s_and(xi, 4);
|
||||
b3 = s_and(xi, 8);
|
||||
|
||||
if (b0 != 0) y = Mpy_32_16_1(y, 24109); /* exp(-1) in -1Q16 */
|
||||
if (b1 != 0) y = Mpy_32_16_1(y, 17739); /* exp(-2) in -2Q17 */
|
||||
if (b2 != 0) y = Mpy_32_16_1(y, 19205); /* exp(-4) in -5Q20 */
|
||||
if (b3 != 0) y = Mpy_32_16_1(y, 22513); /* exp(-8) in -11Q26 */
|
||||
if (b0 != 0) y = Mpy_32_16(y, 24109); /* exp(-1) in -1Q16 */
|
||||
if (b1 != 0) y = Mpy_32_16(y, 17739); /* exp(-2) in -2Q17 */
|
||||
if (b2 != 0) y = Mpy_32_16(y, 19205); /* exp(-4) in -5Q20 */
|
||||
if (b3 != 0) y = Mpy_32_16(y, 22513); /* exp(-8) in -11Q26 */
|
||||
|
||||
/* scaling: -1*b0 - 2*b1 -5*b2 -11*b3 */
|
||||
y = L_shr(y, add(add(xi, shr(xi, 2)), shr(b3, 3)));
|
||||
|
|
@ -67,22 +71,31 @@ Word32 expfp( /* o: Q31 */
|
|||
if (shr(xi, 4) > 0)
|
||||
{
|
||||
y = L_deposit_l(0);
|
||||
move16();
|
||||
}
|
||||
|
||||
|
||||
return L_shl(y, 15);
|
||||
return round_fx(L_shl(y, 15));
|
||||
}
|
||||
|
||||
/* Fixed point implementation of pow(), where base is fixed point (16/16) and exponent a small *odd* integer
|
||||
|
||||
/*-------------------------------------------------------*
|
||||
* powfp_odd2()
|
||||
*
|
||||
* Fixed point implementation of pow(), where base is fixed point (16/16) and exponent a small *odd* integer
|
||||
*-------------------------------------------------------*/
|
||||
/*
|
||||
*
|
||||
* Returns: *pout1 = ( (base/65536)^(2*exp - 1) ) * 65536
|
||||
* *pout2 = ( (base/65536)^(2*exp + 1) ) * 65536
|
||||
*
|
||||
* NOTE: This function must be in sync with ari_decode_14bits_pow() */
|
||||
void powfp_odd2(Word16 base, /* Q15 */
|
||||
Word16 exp, /* Q0 */
|
||||
Word16 *pout1, /* Q15 */
|
||||
Word16 *pout2) /* Q15 */
|
||||
|
||||
void powfp_odd2(
|
||||
Word16 base, /* Q15 */
|
||||
Word16 exp, /* Q0 */
|
||||
Word16 *pout1, /* Q15 */
|
||||
Word16 *pout2 /* Q15 */
|
||||
)
|
||||
{
|
||||
/* this version is in sync with ari_enc_14bits_pow()
|
||||
* that is, we have to start multiplication from the largest power-of-two, in order to
|
||||
|
|
@ -144,8 +157,10 @@ void powfp_odd2(Word16 base, /* Q15 */
|
|||
*pout2 = out;
|
||||
move16();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------
|
||||
* Function: tcx_arith_scale_envelope
|
||||
*
|
||||
|
|
@ -167,12 +182,13 @@ void powfp_odd2(Word16 base, /* Q15 */
|
|||
* NOTE: This function must be bit-exact on all platforms such that encoder
|
||||
* and decoder remain synchronized.
|
||||
*-------------------------------------------------------------------------*/
|
||||
|
||||
void tcx_arith_scale_envelope(
|
||||
Word16 L_spec_core, /* i: number of lines to scale Q0 */
|
||||
Word16 L_frame, /* i: number of lines Q0 */
|
||||
Word32 env[], /* i: unscaled envelope Q16 */
|
||||
Word16 target_bits, /* i: number of available bits Q0 */
|
||||
Word16 low_complexity, /* i: low-complexity flag Q0 */
|
||||
Word16 low_complexity, /* i: low-complexity Q0 */
|
||||
Word16 s_env[], /* o: scaled envelope Q15-e */
|
||||
Word16 *s_env_e /* o: scaled envelope exponent Q0 */
|
||||
)
|
||||
|
|
@ -186,7 +202,6 @@ void tcx_arith_scale_envelope(
|
|||
Word16 mean_e, tmp, tmp2;
|
||||
|
||||
|
||||
|
||||
lob_bits = 0;
|
||||
move16();
|
||||
hib_bits = 0;
|
||||
|
|
@ -194,10 +209,10 @@ void tcx_arith_scale_envelope(
|
|||
|
||||
/* Boosting to account for expected spectrum truncation (kMax) */
|
||||
/* target_bits = (int)(target_bits * (1.2f - 0.00045f * target_bits + 0.00000025f * target_bits * target_bits)); */
|
||||
L_tmp = L_shr(Mpy_32_16_1(L_mult0(target_bits, target_bits), 17180), 6); /* Q15; 17180 -> 0.00000025f (Q36) */
|
||||
L_tmp = L_shr(Mpy_32_16(L_mult0(target_bits, target_bits), 17180), 6); /* Q15; 17180 -> 0.00000025f (Q36) */
|
||||
L_tmp = L_sub(L_tmp, L_shr(L_mult0(target_bits, 30199), 11)); /* Q15; 30199 -> 0.00045f (Q26) */
|
||||
L_tmp = L_add(L_tmp, 39322); /* Q15; 39322 -> 1.2f (Q15) */
|
||||
L_tmp = Mpy_32_16_1(L_tmp, target_bits); /* Q0 */
|
||||
L_tmp = Mpy_32_16(L_tmp, target_bits); /* Q0 */
|
||||
assert(L_tmp < 32768);
|
||||
target_bits = extract_l(L_tmp);
|
||||
|
||||
|
|
@ -216,12 +231,12 @@ void tcx_arith_scale_envelope(
|
|||
}
|
||||
tmp = norm_s(L_frame);
|
||||
tmp = shl(div_s(8192, shl(L_frame, tmp)), sub(tmp, 7));
|
||||
mean = L_shr(Mpy_32_16_1(mean, tmp), 6); /* Q16 */
|
||||
mean = L_shr(Mpy_32_16(mean, tmp), 6); /* Q16 */
|
||||
|
||||
/* Rate dependent compensation to get closer to the target on average */
|
||||
/* mean = (float)pow(mean, (float)L_frame / (float)target_bits * 0.357f); */
|
||||
tmp = BASOP_Util_Divide1616_Scale(L_frame, target_bits, &tmp2);
|
||||
tmp = mult_r(tmp, 11698/*0.357f Q15*/);
|
||||
tmp = mult_r(tmp, FL2WORD16(0.357f));
|
||||
mean = BASOP_Util_fPow(mean, 15, L_deposit_h(tmp), tmp2, &mean_e);
|
||||
|
||||
/* Find first-guess scaling coefficient "scale" such that if "mean" is the
|
||||
|
|
@ -231,23 +246,28 @@ void tcx_arith_scale_envelope(
|
|||
*/
|
||||
/* a = 2*2.71828183f*mean*mean; */
|
||||
tmp = round_fx(mean);
|
||||
a = L_mult(mult_r(tmp, 22268/*2.71828183f Q13*/), tmp);
|
||||
a = L_mult(mult_r(tmp, FL2WORD16_SCALE(2.71828183f, 2)), tmp);
|
||||
a_e = add(shl(mean_e, 1), 3);
|
||||
|
||||
/* b = (0.15f - (float)pow(2.0f, target_bits/(float)L_frame)) * mean; */
|
||||
tmp = BASOP_Util_Divide1616_Scale(target_bits, L_frame, &tmp2);
|
||||
tmp = round_fx(BASOP_util_Pow2(L_deposit_h(tmp), tmp2, &tmp2));
|
||||
b_e = BASOP_Util_Add_MantExp(4915/*0.15f Q15*/, 0, negate(tmp), tmp2, &b);
|
||||
b_e = BASOP_Util_Add_MantExp(FL2WORD16(0.15f), 0, negate(tmp), tmp2, &b);
|
||||
b = mult_r(b, round_fx(mean));
|
||||
b_e = add(b_e, mean_e);
|
||||
|
||||
/* scale = (-b + (float)sqrt(b*b - 4.0f*a*0.035f)) / (2.0f * a); */
|
||||
tmp = round_fx(BASOP_Util_Add_Mant32Exp(L_mult(b, b), shl(b_e, 1), Mpy_32_16_1(a, -4588/*-4.0f*0.035f Q15*/), a_e, &tmp2));
|
||||
tmp = round_fx(BASOP_Util_Add_Mant32Exp(L_mult(b, b), shl(b_e, 1), Mpy_32_16(a, FL2WORD16(-4.0f*0.035f)), a_e, &tmp2));
|
||||
|
||||
IF( tmp <= 0 )
|
||||
{
|
||||
tmp = 0;
|
||||
set16_fx(s_env, 0, L_frame);
|
||||
|
||||
FOR( k=0; k<L_frame; k++ )
|
||||
{
|
||||
s_env[k] = 0;
|
||||
move16();
|
||||
}
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
|
|
@ -285,24 +305,24 @@ void tcx_arith_scale_envelope(
|
|||
|
||||
FOR (k = 0; k < L_frame; k++)
|
||||
{
|
||||
s = Mpy_32_16_1(ienv[k], scale); /* Q16 */
|
||||
s = Mpy_32_16(ienv[k], scale); /* Q16 */
|
||||
|
||||
IF (L_sub(s, 5243l/*0.08f Q16*/) <= 0)
|
||||
IF (L_sub(s, FL2WORD32_SCALE(0.08f, 15)) <= 0)
|
||||
{
|
||||
/* If s = 0.08, the expected bit-consumption is log2(1.0224). Below 0.08, the bit-consumption
|
||||
estimate function becomes inaccurate, so use log2(1.0224) for all values below 0.08. */
|
||||
/* round(state * 1.0224 * 32768) */
|
||||
statesi = mult_r(statesi, 16751/*1.0224 Q14*/);
|
||||
statesi = mult_r(statesi, FL2WORD16_SCALE(1.0224, 1));
|
||||
tmp = norm_s(statesi);
|
||||
statesi = shl(statesi, tmp);
|
||||
bits = add(bits, sub(1, tmp));
|
||||
}
|
||||
ELSE IF (L_sub(s, 16711680l/*255.0 Q16*/) <= 0)
|
||||
ELSE IF (L_sub(s, FL2WORD32_SCALE(255.0, 15)) <= 0)
|
||||
{
|
||||
/* a = 5.436564f * s + 0.15f + 0.035f * env[k] * iscale; */
|
||||
L_tmp = L_shl(Mpy_32_16_1(s, 22268/*5.436564f Q12*/), 3);
|
||||
L_tmp = L_add(L_tmp, 9830l/*0.15f Q16*/);
|
||||
L_tmp = L_add(L_tmp, L_shl(Mpy_32_16_1(env[k], mult_r(1147/*0.035f Q15*/, iscale)), iscale_e));
|
||||
L_tmp = L_shl(Mpy_32_16(s, FL2WORD16_SCALE(5.436564f, 3)), 3);
|
||||
L_tmp = L_add(L_tmp, FL2WORD32_SCALE(0.15f, 15));
|
||||
L_tmp = L_add(L_tmp, L_shl(Mpy_32_16(env[k], mult_r(FL2WORD16(0.035f), iscale)), iscale_e));
|
||||
|
||||
tmp = norm_l(L_tmp);
|
||||
statesi = mult_r(statesi, round_fx(L_shl(L_tmp, tmp)));
|
||||
|
|
@ -317,13 +337,14 @@ void tcx_arith_scale_envelope(
|
|||
/* for large envelope values, s > 255, bit consumption is approx log2(2*e*s)
|
||||
* further, we use round(log2(x)) = floor(log2(x)+0.5) = floor(log2(x*sqrt(2))) */
|
||||
/* a = 5.436564f * s; */
|
||||
L_tmp = Mpy_32_16_1(s, 31492/*5.436564f * 1.4142f Q12*/); /* Q13 */
|
||||
L_tmp = Mpy_32_16(s, FL2WORD16_SCALE(5.436564f * 1.4142f, 3)); /* Q13 */
|
||||
bits = add(bits, sub(17, norm_l(L_tmp)));
|
||||
}
|
||||
}
|
||||
|
||||
IF (sub(bits, target_bits) <= 0) /* Bits leftover => scale is too small */
|
||||
IF (sub(bits, target_bits) <= 0)
|
||||
{
|
||||
/* Bits leftover => scale is too small */
|
||||
lob = scale;
|
||||
move16();
|
||||
lob_bits = bits;
|
||||
|
|
@ -334,17 +355,19 @@ void tcx_arith_scale_envelope(
|
|||
adjust = div_s(sub(hib_bits, target_bits), sub(hib_bits, lob_bits));
|
||||
scale = add(mult_r(sub(lob, hib), adjust), hib);
|
||||
}
|
||||
ELSE /* Initial scale adaptation */
|
||||
ELSE
|
||||
{
|
||||
/* Initial scale adaptation */
|
||||
/* adjust = 1.05f * target_bits / (float)bits;
|
||||
scale *= adjust; */
|
||||
adjust = mult_r(17203/*1.05f Q14*/, target_bits);
|
||||
adjust = mult_r(FL2WORD16_SCALE(1.05f, 1), target_bits);
|
||||
adjust = BASOP_Util_Divide1616_Scale(adjust, bits, &tmp);
|
||||
scale = shl(mult_r(scale, adjust), add(1, tmp));
|
||||
}
|
||||
}
|
||||
ELSE /* Ran out of bits => scale is too large */
|
||||
ELSE
|
||||
{
|
||||
/* Ran out of bits => scale is too large */
|
||||
hib = scale;
|
||||
move16();
|
||||
hib_bits = bits;
|
||||
|
|
@ -355,13 +378,19 @@ void tcx_arith_scale_envelope(
|
|||
adjust = div_s(sub(hib_bits, target_bits), sub(hib_bits, lob_bits));
|
||||
scale = add(mult_r(sub(lob, hib), adjust), hib);
|
||||
}
|
||||
ELSE { /* Initial scale adaptation */
|
||||
ELSE
|
||||
{ /* Initial scale adaptation */
|
||||
test();
|
||||
IF( target_bits <= 0 || bits <= 0 ) /* safety check in case of bit errors */
|
||||
{
|
||||
adjust = 0;
|
||||
move16();
|
||||
set16_fx( s_env, 0, L_frame );
|
||||
|
||||
FOR( k=0; k<L_frame; k++ )
|
||||
{
|
||||
s_env[k] = 0;
|
||||
move16();
|
||||
}
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
|
|
@ -377,7 +406,12 @@ void tcx_arith_scale_envelope(
|
|||
{
|
||||
iscale = 0;
|
||||
move16();
|
||||
set16_fx( s_env, 0, L_frame );
|
||||
|
||||
FOR( k=0; k<L_frame; k++ )
|
||||
{
|
||||
s_env[k] = 0;
|
||||
move16();
|
||||
}
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
|
|
@ -396,11 +430,14 @@ void tcx_arith_scale_envelope(
|
|||
|
||||
FOR (k = 0; k < L_frame; k++)
|
||||
{
|
||||
L_tmp = Mpy_32_16_1(L_shl(env[k], tmp), iscale);
|
||||
L_tmp = Mpy_32_16(L_shl(env[k], tmp), iscale);
|
||||
L_tmp = L_min(L_tmp, a);
|
||||
s_env[k] = round_fx(L_tmp);
|
||||
move16();
|
||||
}
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------
|
||||
|
|
@ -415,14 +452,15 @@ void tcx_arith_scale_envelope(
|
|||
* NOTE: This function must be bit-exact on all platforms such that encoder
|
||||
* and decoder remain synchronized.
|
||||
*-------------------------------------------------------------------------*/
|
||||
|
||||
void tcx_arith_render_envelope(
|
||||
const Word16 A_ind[], /* i: LPC coefficients of signal envelope */
|
||||
Word16 L_frame, /* i: number of spectral lines */
|
||||
const Word16 A_ind[], /* i: LPC coefficients of signal envelope */
|
||||
Word16 L_frame, /* i: number of spectral lines */
|
||||
Word16 L_spec,
|
||||
Word16 preemph_fac, /* i: pre-emphasis factor */
|
||||
Word16 gamma_w, /* i: A_ind -> weighted envelope factor */
|
||||
Word16 gamma_uw, /* i: A_ind -> non-weighted envelope factor */
|
||||
Word32 env[] /* o: shaped signal envelope */
|
||||
Word16 preemph_fac, /* i: pre-emphasis factor */
|
||||
Word16 gamma_w, /* i: A_ind -> weighted envelope factor */
|
||||
Word16 gamma_uw, /* i: A_ind -> non-weighted envelope factor */
|
||||
Word32 env[] /* o: shaped signal envelope */
|
||||
)
|
||||
{
|
||||
Word16 k;
|
||||
|
|
@ -431,15 +469,14 @@ void tcx_arith_render_envelope(
|
|||
Word16 gainlpc[FDNS_NPTS], gainlpc_e[FDNS_NPTS];
|
||||
|
||||
|
||||
|
||||
/* Compute perceptual LPC envelope, transform it into freq.-domain gains */
|
||||
weight_a_fx( A_ind, tmpA, gamma_w, M );
|
||||
lpc2mdct( tmpA, M, NULL, NULL, gainlpc, gainlpc_e );
|
||||
basop_weight_a(A_ind, tmpA, gamma_w);
|
||||
basop_lpc2mdct(tmpA, M, NULL, NULL, gainlpc, gainlpc_e);
|
||||
|
||||
/* Add pre-emphasis tilt to LPC envelope, transform LPC into MDCT gains */
|
||||
E_LPC_a_weight_inv(A_ind, signal_env, gamma_uw, M);
|
||||
E_LPC_a_add_tilt(signal_env, tmpA, preemph_fac, M);
|
||||
lpc2mdct(tmpA, M+1, signal_env, signal_env_e, NULL, NULL);
|
||||
basop_weight_a_inv(A_ind, signal_env, gamma_uw);
|
||||
basop_E_LPC_a_add_tilt(signal_env, tmpA, preemph_fac);
|
||||
basop_lpc2mdct(tmpA, M+1, signal_env, signal_env_e, NULL, NULL);
|
||||
|
||||
/* Compute weighted signal envelope in perceptual domain */
|
||||
FOR (k = 0; k < FDNS_NPTS; k++)
|
||||
|
|
@ -451,15 +488,16 @@ void tcx_arith_render_envelope(
|
|||
}
|
||||
|
||||
/* Adaptive low frequency emphasis */
|
||||
set32_fx(env, 0x10000, L_frame);
|
||||
FOR (k = 0; k < L_frame; k++)
|
||||
{
|
||||
env[k] = 0x10000;
|
||||
move32();
|
||||
}
|
||||
|
||||
AdaptLowFreqDeemph(env, 15,
|
||||
1,
|
||||
gainlpc, gainlpc_e,
|
||||
L_frame, NULL);
|
||||
basop_PsychAdaptLowFreqDeemph(env, gainlpc, gainlpc_e, NULL);
|
||||
|
||||
/* Scale from FDNS_NPTS to L_frame and multiply LFE gains */
|
||||
mdct_noiseShaping_interp(env, L_frame, signal_env, signal_env_e);
|
||||
basop_mdct_noiseShaping_interp(env, L_frame, signal_env, signal_env_e);
|
||||
|
||||
FOR (k=L_frame; k<L_spec; ++k)
|
||||
{
|
||||
|
|
@ -467,5 +505,6 @@ void tcx_arith_render_envelope(
|
|||
move32();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
348
src/libs/libevs/basic_op/basop32.cpp → src/libs/libevs/lib_com/basop32.cpp
Executable file → Normal file
348
src/libs/libevs/basic_op/basop32.cpp → src/libs/libevs/lib_com/basop32.cpp
Executable file → Normal file
|
|
@ -1,3 +1,4 @@
|
|||
|
||||
/* v.2.3 - 30.Nov.2009
|
||||
=============================================================================
|
||||
|
||||
|
|
@ -121,18 +122,15 @@ HISTORY:
|
|||
| Include-Files |
|
||||
|___________________________________________________________________________|
|
||||
*/
|
||||
#ifndef _CRT_SECURE_NO_WARNINGS
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "stl.h"
|
||||
|
||||
|
||||
#if (WMOPS)
|
||||
extern BASIC_OP multiCounter[MAXCOUNTERS];
|
||||
extern int currCounter;
|
||||
#endif
|
||||
|
||||
|
||||
/*___________________________________________________________________________
|
||||
| |
|
||||
| Local Functions |
|
||||
|
|
@ -203,9 +201,6 @@ static Word16 saturate (Word32 L_var1)
|
|||
else
|
||||
{
|
||||
var_out = extract_l (L_var1);
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].extract_l--;
|
||||
#endif
|
||||
}
|
||||
|
||||
BASOP_CHECK();
|
||||
|
|
@ -255,9 +250,7 @@ Word16 add (Word16 var1, Word16 var2)
|
|||
L_sum = (Word32) var1 + var2;
|
||||
var_out = saturate (L_sum);
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].add++;
|
||||
#endif
|
||||
|
||||
return (var_out);
|
||||
}
|
||||
|
||||
|
|
@ -303,9 +296,7 @@ Word16 sub (Word16 var1, Word16 var2)
|
|||
L_diff = (Word32) var1 - var2;
|
||||
var_out = saturate (L_diff);
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].sub++;
|
||||
#endif
|
||||
|
||||
return (var_out);
|
||||
}
|
||||
|
||||
|
|
@ -357,12 +348,9 @@ Word16 abs_s (Word16 var1)
|
|||
}
|
||||
}
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].abs_s++;
|
||||
#endif
|
||||
|
||||
BASOP_CHECK();
|
||||
|
||||
|
||||
return (var_out);
|
||||
}
|
||||
|
||||
|
|
@ -412,10 +400,6 @@ Word16 shl (Word16 var1, Word16 var2)
|
|||
var2 = -16;
|
||||
var2 = -var2;
|
||||
var_out = shr (var1, var2);
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].shr--;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -429,19 +413,12 @@ Word16 shl (Word16 var1, Word16 var2)
|
|||
else
|
||||
{
|
||||
var_out = extract_l (result);
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].extract_l--;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].shl++;
|
||||
#endif
|
||||
|
||||
BASOP_CHECK();
|
||||
|
||||
|
||||
return (var_out);
|
||||
}
|
||||
|
||||
|
|
@ -490,10 +467,6 @@ Word16 shr (Word16 var1, Word16 var2)
|
|||
var2 = -16;
|
||||
var2 = -var2;
|
||||
var_out = shl (var1, var2);
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].shl--;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -514,12 +487,9 @@ Word16 shr (Word16 var1, Word16 var2)
|
|||
}
|
||||
}
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].shr++;
|
||||
#endif
|
||||
|
||||
BASOP_CHECK();
|
||||
|
||||
|
||||
return (var_out);
|
||||
}
|
||||
|
||||
|
|
@ -572,9 +542,7 @@ Word16 mult (Word16 var1, Word16 var2)
|
|||
|
||||
var_out = saturate (L_product);
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].mult++;
|
||||
#endif
|
||||
|
||||
return (var_out);
|
||||
}
|
||||
|
||||
|
|
@ -629,12 +597,9 @@ Word32 L_mult (Word16 var1, Word16 var2)
|
|||
L_var_out = MAX_32;
|
||||
}
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_mult++;
|
||||
#endif
|
||||
|
||||
BASOP_CHECK();
|
||||
|
||||
|
||||
return (L_var_out);
|
||||
}
|
||||
|
||||
|
|
@ -674,12 +639,9 @@ Word16 negate (Word16 var1)
|
|||
var_out = (var1 == MIN_16) ? MAX_16 : -var1;
|
||||
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].negate++;
|
||||
#endif
|
||||
|
||||
BASOP_CHECK();
|
||||
|
||||
|
||||
return (var_out);
|
||||
}
|
||||
|
||||
|
|
@ -717,12 +679,9 @@ Word16 extract_h (Word32 L_var1)
|
|||
|
||||
var_out = (Word16) (L_var1 >> 16);
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].extract_h++;
|
||||
#endif
|
||||
|
||||
BASOP_CHECK();
|
||||
|
||||
|
||||
return (var_out);
|
||||
}
|
||||
|
||||
|
|
@ -760,12 +719,9 @@ Word16 extract_l (Word32 L_var1)
|
|||
|
||||
var_out = (Word16) L_var1;
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].extract_l++;
|
||||
#endif
|
||||
|
||||
BASOP_CHECK();
|
||||
|
||||
|
||||
return (var_out);
|
||||
}
|
||||
|
||||
|
|
@ -805,19 +761,14 @@ Word16 round_fx (Word32 L_var1)
|
|||
Word16 var_out;
|
||||
Word32 L_rounded;
|
||||
|
||||
BASOP_SATURATE_WARNING_OFF
|
||||
BASOP_SATURATE_WARNING_OFF
|
||||
L_rounded = L_add (L_var1, (Word32) 0x00008000L);
|
||||
BASOP_SATURATE_WARNING_ON
|
||||
BASOP_SATURATE_WARNING_ON
|
||||
var_out = extract_h (L_rounded);
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_add--;
|
||||
multiCounter[currCounter].extract_h--;
|
||||
multiCounter[currCounter].round++;
|
||||
#endif
|
||||
|
||||
BASOP_CHECK();
|
||||
|
||||
|
||||
return (var_out);
|
||||
}
|
||||
|
||||
|
|
@ -866,14 +817,9 @@ Word32 L_mac (Word32 L_var3, Word16 var1, Word16 var2)
|
|||
L_product = L_mult (var1, var2);
|
||||
L_var_out = L_add (L_var3, L_product);
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_mult--;
|
||||
multiCounter[currCounter].L_add--;
|
||||
multiCounter[currCounter].L_mac++;
|
||||
#endif
|
||||
|
||||
BASOP_CHECK();
|
||||
|
||||
|
||||
return (L_var_out);
|
||||
}
|
||||
|
||||
|
|
@ -922,14 +868,9 @@ Word32 L_msu (Word32 L_var3, Word16 var1, Word16 var2)
|
|||
L_product = L_mult (var1, var2);
|
||||
L_var_out = L_sub (L_var3, L_product);
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_mult--;
|
||||
multiCounter[currCounter].L_sub--;
|
||||
multiCounter[currCounter].L_msu++;
|
||||
#endif
|
||||
|
||||
BASOP_CHECK();
|
||||
|
||||
|
||||
return (L_var_out);
|
||||
}
|
||||
|
||||
|
|
@ -983,12 +924,6 @@ Word32 L_macNs (Word32 L_var3, Word16 var1, Word16 var2)
|
|||
L_var_out = L_mult (var1, var2);
|
||||
L_var_out = L_add_c (L_var3, L_var_out);
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_mult--;
|
||||
multiCounter[currCounter].L_add_c--;
|
||||
multiCounter[currCounter].L_macNs++;
|
||||
#endif
|
||||
|
||||
/* BASOP_CHECK(); Do not check for overflow here, function produces the carry bit instead */
|
||||
|
||||
|
||||
|
|
@ -1045,15 +980,9 @@ Word32 L_msuNs (Word32 L_var3, Word16 var1, Word16 var2)
|
|||
L_var_out = L_mult (var1, var2);
|
||||
L_var_out = L_sub_c (L_var3, L_var_out);
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_mult--;
|
||||
multiCounter[currCounter].L_sub_c--;
|
||||
multiCounter[currCounter].L_msuNs++;
|
||||
|
||||
#endif
|
||||
|
||||
/* BASOP_CHECK(); Do not check for overflow here, function produces the carry bit instead */
|
||||
|
||||
|
||||
return (L_var_out);
|
||||
}
|
||||
|
||||
|
|
@ -1104,12 +1033,9 @@ Word32 L_add (Word32 L_var1, Word32 L_var2)
|
|||
}
|
||||
}
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_add++;
|
||||
#endif
|
||||
|
||||
BASOP_CHECK();
|
||||
|
||||
|
||||
return (L_var_out);
|
||||
}
|
||||
|
||||
|
|
@ -1160,12 +1086,9 @@ Word32 L_sub (Word32 L_var1, Word32 L_var2)
|
|||
}
|
||||
}
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_sub++;
|
||||
#endif
|
||||
|
||||
BASOP_CHECK();
|
||||
|
||||
|
||||
return (L_var_out);
|
||||
}
|
||||
|
||||
|
|
@ -1276,12 +1199,9 @@ Word32 L_add_c (Word32 L_var1, Word32 L_var2)
|
|||
Carry = carry_int;
|
||||
}
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_add_c++;
|
||||
#endif
|
||||
|
||||
/* BASOP_CHECK(); Do not check for overflow here, function produces the carry bit instead */
|
||||
|
||||
|
||||
return (L_var_out);
|
||||
}
|
||||
|
||||
|
|
@ -1335,9 +1255,6 @@ Word32 L_sub_c (Word32 L_var1, Word32 L_var2)
|
|||
if (L_var2 != MIN_32)
|
||||
{
|
||||
L_var_out = L_add_c (L_var1, -L_var2);
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_add_c--;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1380,12 +1297,9 @@ Word32 L_sub_c (Word32 L_var1, Word32 L_var2)
|
|||
}
|
||||
}
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_sub_c++;
|
||||
#endif
|
||||
|
||||
/* BASOP_CHECK(); Do not check for overflow here, function produces the carry bit instead */
|
||||
|
||||
|
||||
return (L_var_out);
|
||||
}
|
||||
|
||||
|
|
@ -1424,12 +1338,9 @@ Word32 L_negate (Word32 L_var1)
|
|||
L_var_out = (L_var1 == MIN_32) ? MAX_32 : -L_var1;
|
||||
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_negate++;
|
||||
#endif
|
||||
|
||||
BASOP_CHECK();
|
||||
|
||||
|
||||
return (L_var_out);
|
||||
}
|
||||
|
||||
|
|
@ -1483,9 +1394,7 @@ Word16 mult_r (Word16 var1, Word16 var2)
|
|||
}
|
||||
var_out = saturate (L_product_arr);
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].mult_r++;
|
||||
#endif
|
||||
|
||||
return (var_out);
|
||||
}
|
||||
|
||||
|
|
@ -1534,9 +1443,6 @@ Word32 L_shl (Word32 L_var1, Word16 var2)
|
|||
var2 = -32;
|
||||
var2 = -var2;
|
||||
L_var_out = L_shr (L_var1, var2);
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_shr--;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1561,12 +1467,10 @@ Word32 L_shl (Word32 L_var1, Word16 var2)
|
|||
L_var_out = L_var1;
|
||||
}
|
||||
}
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_shl++;
|
||||
#endif
|
||||
|
||||
BASOP_CHECK();
|
||||
|
||||
|
||||
return (L_var_out);
|
||||
}
|
||||
|
||||
|
|
@ -1614,9 +1518,6 @@ Word32 L_shr (Word32 L_var1, Word16 var2)
|
|||
var2 = -32;
|
||||
var2 = -var2;
|
||||
L_var_out = L_shl (L_var1, var2);
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_shl--;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1636,12 +1537,10 @@ Word32 L_shr (Word32 L_var1, Word16 var2)
|
|||
}
|
||||
}
|
||||
}
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_shr++;
|
||||
#endif
|
||||
|
||||
BASOP_CHECK();
|
||||
|
||||
|
||||
return (L_var_out);
|
||||
}
|
||||
|
||||
|
|
@ -1699,10 +1598,6 @@ Word16 shr_r (Word16 var1, Word16 var2)
|
|||
{
|
||||
var_out = shr (var1, var2);
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].shr--;
|
||||
#endif
|
||||
|
||||
if (var2 > 0)
|
||||
{
|
||||
if ((var1 & ((Word16) 1 << (var2 - 1))) != 0)
|
||||
|
|
@ -1712,12 +1607,9 @@ Word16 shr_r (Word16 var1, Word16 var2)
|
|||
}
|
||||
}
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].shr_r++;
|
||||
#endif
|
||||
|
||||
BASOP_CHECK();
|
||||
|
||||
|
||||
return (var_out);
|
||||
}
|
||||
|
||||
|
|
@ -1768,15 +1660,9 @@ Word16 mac_r (Word32 L_var3, Word16 var1, Word16 var2)
|
|||
L_var3 = L_add (L_var3, (Word32) 0x00008000L);
|
||||
var_out = extract_h (L_var3);
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_mac--;
|
||||
multiCounter[currCounter].L_add--;
|
||||
multiCounter[currCounter].extract_h--;
|
||||
multiCounter[currCounter].mac_r++;
|
||||
#endif
|
||||
|
||||
BASOP_CHECK();
|
||||
|
||||
|
||||
return (var_out);
|
||||
}
|
||||
|
||||
|
|
@ -1827,15 +1713,9 @@ Word16 msu_r (Word32 L_var3, Word16 var1, Word16 var2)
|
|||
L_var3 = L_add (L_var3, (Word32) 0x00008000L);
|
||||
var_out = extract_h (L_var3);
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_msu--;
|
||||
multiCounter[currCounter].L_add--;
|
||||
multiCounter[currCounter].extract_h--;
|
||||
multiCounter[currCounter].msu_r++;
|
||||
#endif
|
||||
|
||||
BASOP_CHECK();
|
||||
|
||||
|
||||
return (var_out);
|
||||
}
|
||||
|
||||
|
|
@ -1874,12 +1754,9 @@ Word32 L_deposit_h (Word16 var1)
|
|||
|
||||
L_var_out = (Word32) var1 << 16;
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_deposit_h++;
|
||||
#endif
|
||||
|
||||
BASOP_CHECK();
|
||||
|
||||
|
||||
return (L_var_out);
|
||||
}
|
||||
|
||||
|
|
@ -1918,12 +1795,9 @@ Word32 L_deposit_l (Word16 var1)
|
|||
|
||||
L_var_out = (Word32) var1;
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_deposit_l++;
|
||||
#endif
|
||||
|
||||
BASOP_CHECK();
|
||||
|
||||
|
||||
return (L_var_out);
|
||||
}
|
||||
|
||||
|
|
@ -1981,9 +1855,6 @@ Word32 L_shr_r (Word32 L_var1, Word16 var2)
|
|||
{
|
||||
L_var_out = L_shr (L_var1, var2);
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_shr--;
|
||||
#endif
|
||||
if (var2 > 0)
|
||||
{
|
||||
if ((L_var1 & ((Word32) 1 << (var2 - 1))) != 0)
|
||||
|
|
@ -1993,12 +1864,9 @@ Word32 L_shr_r (Word32 L_var1, Word16 var2)
|
|||
}
|
||||
}
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_shr_r++;
|
||||
#endif
|
||||
|
||||
BASOP_CHECK();
|
||||
|
||||
|
||||
return (L_var_out);
|
||||
}
|
||||
|
||||
|
|
@ -2051,12 +1919,9 @@ Word32 L_abs (Word32 L_var1)
|
|||
}
|
||||
}
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_abs++;
|
||||
#endif
|
||||
|
||||
BASOP_CHECK();
|
||||
|
||||
|
||||
return (L_var_out);
|
||||
}
|
||||
|
||||
|
|
@ -2113,12 +1978,9 @@ Word32 L_sat (Word32 L_var1)
|
|||
Overflow = 0;
|
||||
}
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_sat++;
|
||||
#endif
|
||||
|
||||
BASOP_CHECK();
|
||||
|
||||
|
||||
return (L_var_out);
|
||||
}
|
||||
|
||||
|
|
@ -2182,12 +2044,9 @@ Word16 norm_s (Word16 var1)
|
|||
}
|
||||
}
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].norm_s++;
|
||||
#endif
|
||||
|
||||
BASOP_CHECK();
|
||||
|
||||
|
||||
return (var_out);
|
||||
}
|
||||
|
||||
|
|
@ -2239,7 +2098,7 @@ Word16 div_s (Word16 var1, Word16 var2)
|
|||
{
|
||||
/* printf ("Division Error var1=%d var2=%d in ", var1, var2); printStack(); */
|
||||
char text[60];
|
||||
sprintf (text, "\nDivision Error var1=%d var2=%d in ", var1, var2);
|
||||
sprintf (text, "Division Error var1=%d var2=%d in ", var1, var2);
|
||||
abort(); /* exit (0); */
|
||||
}
|
||||
if (var2 == 0)
|
||||
|
|
@ -2262,11 +2121,6 @@ Word16 div_s (Word16 var1, Word16 var2)
|
|||
L_num = L_deposit_l (var1);
|
||||
L_denom = L_deposit_l (var2);
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_deposit_l--;
|
||||
multiCounter[currCounter].L_deposit_l--;
|
||||
#endif
|
||||
|
||||
for (iteration = 0; iteration < 15; iteration++)
|
||||
{
|
||||
var_out <<= 1;
|
||||
|
|
@ -2276,21 +2130,14 @@ Word16 div_s (Word16 var1, Word16 var2)
|
|||
{
|
||||
L_num = L_sub (L_num, L_denom);
|
||||
var_out = add (var_out, 1);
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_sub--;
|
||||
multiCounter[currCounter].add--;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].div_s++;
|
||||
#endif
|
||||
|
||||
BASOP_CHECK();
|
||||
|
||||
|
||||
return (var_out);
|
||||
}
|
||||
|
||||
|
|
@ -2354,12 +2201,9 @@ Word16 norm_l (Word32 L_var1)
|
|||
}
|
||||
}
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].norm_l++;
|
||||
#endif
|
||||
|
||||
BASOP_CHECK();
|
||||
|
||||
|
||||
return (var_out);
|
||||
}
|
||||
|
||||
|
|
@ -2411,24 +2255,17 @@ Word16 norm_l (Word32 L_var1)
|
|||
*/
|
||||
Word32 L_mls (Word32 Lv, Word16 v)
|
||||
{
|
||||
Word32 Temp ;
|
||||
Word32 Temp ;
|
||||
|
||||
Temp = Lv & (Word32) 0x0000ffff ;
|
||||
Temp = Temp * (Word32) v ;
|
||||
Temp = L_shr( Temp, (Word16) 15 ) ;
|
||||
Temp = L_mac( Temp, v, extract_h(Lv) ) ;
|
||||
Temp = Lv & (Word32) 0x0000ffff ;
|
||||
Temp = Temp * (Word32) v ;
|
||||
Temp = L_shr( Temp, (Word16) 15 ) ;
|
||||
Temp = L_mac( Temp, v, extract_h(Lv) ) ;
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_shr--;
|
||||
multiCounter[currCounter].L_mac--;
|
||||
multiCounter[currCounter].extract_h--;
|
||||
multiCounter[currCounter].L_mls++;
|
||||
#endif
|
||||
BASOP_CHECK();
|
||||
|
||||
|
||||
BASOP_CHECK();
|
||||
|
||||
return Temp ;
|
||||
return Temp ;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -2476,55 +2313,44 @@ Word16 div_l (Word32 L_num, Word16 den)
|
|||
Word32 L_den;
|
||||
Word16 iteration;
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].div_l++;
|
||||
#endif
|
||||
|
||||
if ( den == (Word16) 0 ) {
|
||||
if ( den == (Word16) 0 )
|
||||
{
|
||||
/* printf("Division by 0 in div_l, Fatal error in "); printStack(); */
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if ( (L_num < (Word32) 0) || (den < (Word16) 0) ) {
|
||||
if ( (L_num < (Word32) 0) || (den < (Word16) 0) )
|
||||
{
|
||||
/* printf("Division Error in div_l, Fatal error in "); printStack(); */
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
L_den = L_deposit_h( den ) ;
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_deposit_h--;
|
||||
#endif
|
||||
|
||||
if ( L_num >= L_den ){
|
||||
if ( L_num >= L_den )
|
||||
{
|
||||
|
||||
|
||||
BASOP_CHECK();
|
||||
|
||||
return MAX_16 ;
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
L_num = L_shr(L_num, (Word16)1) ;
|
||||
L_den = L_shr(L_den, (Word16)1);
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_shr-=2;
|
||||
#endif
|
||||
for(iteration=(Word16)0; iteration< (Word16)15;iteration++) {
|
||||
for(iteration=(Word16)0; iteration< (Word16)15; iteration++)
|
||||
{
|
||||
var_out = shl( var_out, (Word16)1);
|
||||
L_num = L_shl( L_num, (Word16)1);
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].shl--;
|
||||
multiCounter[currCounter].L_shl--;
|
||||
#endif
|
||||
if (L_num >= L_den) {
|
||||
if (L_num >= L_den)
|
||||
{
|
||||
L_num = L_sub(L_num,L_den);
|
||||
var_out = add(var_out, (Word16)1);
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_sub--;
|
||||
multiCounter[currCounter].add--;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BASOP_CHECK();
|
||||
|
||||
return var_out;
|
||||
|
|
@ -2565,13 +2391,10 @@ Word16 div_l (Word32 L_num, Word16 den)
|
|||
Word16 i_mult (Word16 a, Word16 b)
|
||||
{
|
||||
#ifdef ORIGINAL_G7231
|
||||
return a*b ;
|
||||
return a*b ;
|
||||
#else
|
||||
Word32 /*register*/ c=a*b;
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].i_mult++;
|
||||
#endif
|
||||
return saturate(c) ;
|
||||
Word32 /*register*/ c=a*b;
|
||||
return saturate(c) ;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -2612,17 +2435,14 @@ Word16 i_mult (Word16 a, Word16 b)
|
|||
*/
|
||||
Word32 L_mult0 (Word16 var1,Word16 var2)
|
||||
{
|
||||
Word32 L_var_out;
|
||||
Word32 L_var_out;
|
||||
|
||||
L_var_out = (Word32)var1 * (Word32)var2;
|
||||
L_var_out = (Word32)var1 * (Word32)var2;
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_mult0++;
|
||||
#endif
|
||||
BASOP_CHECK();
|
||||
|
||||
BASOP_CHECK();
|
||||
|
||||
return(L_var_out);
|
||||
return(L_var_out);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -2658,21 +2478,16 @@ Word32 L_mult0 (Word16 var1,Word16 var2)
|
|||
*/
|
||||
Word32 L_mac0 (Word32 L_var3, Word16 var1, Word16 var2)
|
||||
{
|
||||
Word32 L_var_out;
|
||||
Word32 L_product;
|
||||
Word32 L_var_out;
|
||||
Word32 L_product;
|
||||
|
||||
L_product = L_mult0(var1,var2);
|
||||
L_var_out = L_add(L_var3,L_product);
|
||||
L_product = L_mult0(var1,var2);
|
||||
L_var_out = L_add(L_var3,L_product);
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_mac0++;
|
||||
multiCounter[currCounter].L_mult0--;
|
||||
multiCounter[currCounter].L_add--;
|
||||
#endif
|
||||
BASOP_CHECK();
|
||||
|
||||
BASOP_CHECK();
|
||||
|
||||
return(L_var_out);
|
||||
return(L_var_out);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -2708,21 +2523,16 @@ Word32 L_mac0 (Word32 L_var3, Word16 var1, Word16 var2)
|
|||
*/
|
||||
Word32 L_msu0 (Word32 L_var3, Word16 var1, Word16 var2)
|
||||
{
|
||||
Word32 L_var_out;
|
||||
Word32 L_product;
|
||||
Word32 L_var_out;
|
||||
Word32 L_product;
|
||||
|
||||
L_product = L_mult0(var1,var2);
|
||||
L_var_out = L_sub(L_var3,L_product);
|
||||
L_product = L_mult0(var1,var2);
|
||||
L_var_out = L_sub(L_var3,L_product);
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_msu0++;
|
||||
multiCounter[currCounter].L_mult0--;
|
||||
multiCounter[currCounter].L_sub--;
|
||||
#endif
|
||||
BASOP_CHECK();
|
||||
|
||||
BASOP_CHECK();
|
||||
|
||||
return(L_var_out);
|
||||
return(L_var_out);
|
||||
}
|
||||
|
||||
|
||||
6
src/libs/libevs/basic_op/basop32.h → src/libs/libevs/lib_com/basop32.h
Executable file → Normal file
6
src/libs/libevs/basic_op/basop32.h → src/libs/libevs/lib_com/basop32.h
Executable file → Normal file
|
|
@ -8,13 +8,13 @@
|
|||
GLOBAL FUNCTION PROTOTYPES
|
||||
|
||||
History:
|
||||
26.Jan.00 v1.0 Incorporated to the STL from updated G.723.1/G.729
|
||||
basic operator library (based on basic_op.h) and
|
||||
26.Jan.00 v1.0 Incorporated to the STL from updated G.723.1/G.729
|
||||
basic operator library (based on basic_op.h) and
|
||||
G.723.1's basop.h.
|
||||
05.Jul.00 v1.1 Added 32-bit shiftless mult/mac/msub operators
|
||||
|
||||
03 Nov 04 v2.0 Incorporation of new 32-bit / 40-bit / control
|
||||
operators for the ITU-T Standard Tool Library as
|
||||
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.
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -1,10 +1,10 @@
|
|||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
EVS Codec 3GPP TS26.443 Nov 13, 2018. Version 12.11.0 / 13.7.0 / 14.3.0 / 15.1.0
|
||||
====================================================================================*/
|
||||
|
||||
|
||||
#include "basop_mpy.h"
|
||||
#include "stl.h"
|
||||
#include "options.h" /* Needed for Stack Counting Mechanism Macros (when Instrumented) */
|
||||
#include "options.h"
|
||||
|
||||
Word32 Mpy_32_16_1(Word32 x, Word16 y)
|
||||
{
|
||||
|
|
@ -16,6 +16,16 @@ Word32 Mpy_32_16_1(Word32 x, Word16 y)
|
|||
return (mh);
|
||||
}
|
||||
|
||||
Word32 Mpy_32_16(Word32 x, Word16 y)
|
||||
{
|
||||
Word32 mh;
|
||||
UWord16 ml;
|
||||
|
||||
Mpy_32_16_ss(x, y, &mh, &ml);
|
||||
|
||||
return (mh);
|
||||
}
|
||||
|
||||
Word32 Mpy_32_16_r(Word32 x, Word16 y)
|
||||
{
|
||||
Word32 mh;
|
||||
|
|
@ -31,6 +41,7 @@ Word32 Mpy_32_16_r(Word32 x, Word16 y)
|
|||
return (mh);
|
||||
}
|
||||
|
||||
|
||||
Word32 Mpy_32_32(Word32 x, Word32 y)
|
||||
{
|
||||
Word32 mh;
|
||||
|
|
@ -41,18 +52,3 @@ Word32 Mpy_32_32(Word32 x, Word32 y)
|
|||
return (mh);
|
||||
}
|
||||
|
||||
Word32 Mpy_32_32_r(Word32 x, Word32 y)
|
||||
{
|
||||
Word32 mh;
|
||||
UWord32 ml;
|
||||
|
||||
Mpy_32_32_ss(x, y, &mh, &ml);
|
||||
|
||||
if(L_and(ml, 0x80000000))
|
||||
{
|
||||
mh = L_add(mh, 1);
|
||||
}
|
||||
|
||||
return (mh);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
EVS Codec 3GPP TS26.443 Nov 13, 2018. Version 12.11.0 / 13.7.0 / 14.3.0 / 15.1.0
|
||||
====================================================================================*/
|
||||
|
||||
#ifndef __BASOP_MPY_H
|
||||
|
|
@ -9,7 +9,7 @@
|
|||
#include "options.h"
|
||||
|
||||
/**
|
||||
* \brief 32*16 Bit fractional Multiplication using 40 bit OPS
|
||||
* \brief 32*16 Bit fractional Multiplication using 40 bit OPS
|
||||
* Performs a multiplication of a 32-bit variable x by
|
||||
* a 16-bit variable y, returning a 32-bit value.
|
||||
*
|
||||
|
|
@ -21,18 +21,33 @@
|
|||
Word32 Mpy_32_16_1(Word32 x,
|
||||
Word16 y);
|
||||
|
||||
|
||||
/**
|
||||
* \brief 32*16 Bit fractional Multiplication using 40 bit OPS
|
||||
* Performs a multiplication of a 32-bit variable x by
|
||||
* a 16-bit variable y incl. rounding, returning a 32-bit value.
|
||||
* a 16-bit variable y, returning a 32-bit value.
|
||||
*
|
||||
* \param[i] x
|
||||
* \param[i] y
|
||||
*
|
||||
* \return x*y
|
||||
*/
|
||||
Word32 Mpy_32_16_r(Word32 x,
|
||||
Word16 y);
|
||||
Word32 Mpy_32_16(Word32 x,
|
||||
Word16 y);
|
||||
|
||||
|
||||
/**
|
||||
* \brief 32*16 Bit fractional Multiplication using 40 bit OPS
|
||||
* Performs a multiplication of a 32-bit variable x by
|
||||
* a 16-bit variable y including rounding, returning a 32-bit value.
|
||||
*
|
||||
* \param[i] x
|
||||
* \param[i] y
|
||||
*
|
||||
* \return x*y
|
||||
*/
|
||||
Word32 Mpy_32_16_r(Word32 x, Word16 y);
|
||||
|
||||
|
||||
/**
|
||||
* \brief 32*32 Bit fractional Multiplication using 40 bit OPS
|
||||
|
|
@ -45,60 +60,8 @@ Word32 Mpy_32_16_r(Word32 x,
|
|||
*
|
||||
* \return x*y
|
||||
*/
|
||||
|
||||
Word32 Mpy_32_32(Word32 x,
|
||||
Word32 y);
|
||||
|
||||
/**
|
||||
* \brief 32*32 Bit fractional Multiplication using 40 bit OPS including rounding
|
||||
*
|
||||
* Performs a multiplication of a 32-bit variable x by
|
||||
* a 32-bit variable y, returning a 32-bit value.
|
||||
*
|
||||
* \param[i] x
|
||||
* \param[i] y
|
||||
*
|
||||
* \return x*y
|
||||
*/
|
||||
Word32 Mpy_32_32_r(Word32 x, Word32 y);
|
||||
|
||||
/**
|
||||
* \brief 32*16 Bit integer Multiplication using 40 bit OPS
|
||||
*
|
||||
* Performs a multiplication of a 32-bit variable x by
|
||||
* a 16-bit variable y, returning a 32-bit value.
|
||||
*
|
||||
* \param[i] x
|
||||
* \param[i] y
|
||||
*
|
||||
* \return x*y
|
||||
*/
|
||||
Word32 Mpy_32_16_2(Word32 x,
|
||||
Word16 y);
|
||||
|
||||
|
||||
/**
|
||||
* \brief 32*16 Bit complex fractional multiplication using 40 Bit and 32 Bit operators
|
||||
*
|
||||
* The function mixes 40 Bit and 32 Bit operators, thus it must not be applied
|
||||
* inside of loops where 32 and 16 bit operators are used.
|
||||
*
|
||||
* \param[i] c_Re
|
||||
* \param[i] c_Im
|
||||
* \param[i] a_Re
|
||||
* \param[i] a_Im
|
||||
* \param[i] b_Re
|
||||
* \param[i] b_Im
|
||||
*
|
||||
* \return none
|
||||
*/
|
||||
void cplxMpy_32_16(Word32 *c_Re,
|
||||
Word32 *c_Im,
|
||||
const Word32 a_Re,
|
||||
const Word32 a_Im,
|
||||
const Word16 b_Re,
|
||||
const Word16 b_Im
|
||||
);
|
||||
|
||||
#define MUL_F(A,B) Mpy_32_16_1((A),(B))
|
||||
|
||||
#endif /* __BASOP_SETTINGS_H */
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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 */
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,61 +1,27 @@
|
|||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
EVS Codec 3GPP TS26.443 Nov 13, 2018. Version 12.11.0 / 13.7.0 / 14.3.0 / 15.1.0
|
||||
====================================================================================*/
|
||||
|
||||
#ifndef __BASOP_UTIL_H__
|
||||
#define __BASOP_UTIL_H__
|
||||
|
||||
#include "stl.h"
|
||||
#include "basop_settings.h"
|
||||
#include "typedef.h"
|
||||
#include "basop32.h"
|
||||
#include "basop_mpy.h"
|
||||
|
||||
|
||||
#define _LONG long
|
||||
#define _SHORT short
|
||||
#ifdef _WIN32
|
||||
#define _INT64 __int64
|
||||
#else
|
||||
#define _INT64 long long
|
||||
#endif
|
||||
|
||||
#define WORD32_BITS 32
|
||||
#define MAXVAL_WORD32 ((signed)0x7FFFFFFF)
|
||||
#define MINVAL_WORD32 ((signed)0x80000000)
|
||||
#define WORD32_FIX_SCALE ((_INT64)(1)<<(WORD32_BITS-1))
|
||||
|
||||
#define WORD16_BITS 16
|
||||
#define MAXVAL_WORD16 (((signed)0x7FFFFFFF)>>16)
|
||||
#define MINVAL_WORD16 (((signed)0x80000000)>>16)
|
||||
#define WORD16_FIX_SCALE ((_INT64)(1)<<(WORD16_BITS-1))
|
||||
|
||||
/*!
|
||||
\def Macro converts a Word32 fixed point to Word16 fixed point <1 with saturation
|
||||
*/
|
||||
#define WORD322WORD16(val) \
|
||||
( ( ((((val) >> (WORD32_BITS-WORD16_BITS-1)) + 1) > (((_LONG)1<<WORD16_BITS)-1)) && ((_LONG)(val) > 0) ) ? \
|
||||
(Word16)(_SHORT)(((_LONG)1<<(WORD16_BITS-1))-1):(Word16)(_SHORT)((((val) >> (WORD32_BITS-WORD16_BITS-1)) + 1) >> 1) )
|
||||
|
||||
|
||||
/* Word16 Packed Type */
|
||||
typedef struct
|
||||
{
|
||||
struct
|
||||
{
|
||||
Word16 re;
|
||||
Word16 im;
|
||||
} v;
|
||||
} PWord16;
|
||||
|
||||
#define cast16 move16
|
||||
|
||||
|
||||
#define LD_DATA_SCALE (6)
|
||||
|
||||
#define LD_DATA_SHIFT_I5 (7)
|
||||
|
||||
#define modDiv2(x) sub(x,shl(shr(x,1),1))
|
||||
#define modDiv8(x) L_sub(x,L_shl(L_shr(x,3),3))
|
||||
|
||||
#ifndef CHEAP_NORM_SIZE
|
||||
#define CHEAP_NORM_SIZE 161
|
||||
#endif
|
||||
|
||||
static __inline Word16 limitScale16( Word16 s)
|
||||
{
|
||||
/* It is assumed, that s is calculated just before, therefore we can switch upon sign */
|
||||
|
|
@ -76,6 +42,7 @@ static __inline Word16 limitScale32( Word16 s)
|
|||
return (s);
|
||||
}
|
||||
|
||||
|
||||
/*!**********************************************************************
|
||||
\brief Add two values given by mantissa and exponent.
|
||||
|
||||
|
|
@ -90,23 +57,7 @@ Word16 BASOP_Util_Add_MantExp /*!< Exponent of result
|
|||
Word16 b_e, /*!< Exponent of 2nd operand b */
|
||||
Word16 *ptrSum_m); /*!< Mantissa of result */
|
||||
|
||||
/************************************************************************/
|
||||
/*!
|
||||
\brief Divide two values given by mantissa and exponent.
|
||||
|
||||
Mantissas are in 16-bit-fractional format with values between 0 and 1. <br>
|
||||
The base for exponents is 2. Example: \f$ a = a\_m * 2^{a\_e} \f$<br>
|
||||
|
||||
For performance reasons, the division is based on a table lookup
|
||||
which limits accuracy.
|
||||
*/
|
||||
void BASOP_Util_Divide_MantExp (Word16 a_m, /*!< Mantissa of dividend a */
|
||||
Word16 a_e, /*!< Exponent of dividend a */
|
||||
Word16 b_m, /*!< Mantissa of divisor b */
|
||||
Word16 b_e, /*!< Exponent of divisor b */
|
||||
Word16 *ptrResult_m, /*!< Mantissa of quotient a/b */
|
||||
Word16 *ptrResult_e /*!< Exponent of quotient a/b */
|
||||
);
|
||||
|
||||
/************************************************************************/
|
||||
/*!
|
||||
|
|
@ -122,60 +73,6 @@ Word16 Sqrt16( /*!< output mantissa */
|
|||
Word16 *exponent /*!< pointer to exponent */
|
||||
);
|
||||
|
||||
Word16 Sqrt16norm( /*!< output mantissa */
|
||||
Word16 mantissa, /*!< normalized input mantissa */
|
||||
Word16 *exponent /*!< pointer to exponent */
|
||||
);
|
||||
|
||||
Word32 Sqrt32( /*!< output mantissa */
|
||||
Word32 mantissa, /*!< input mantissa */
|
||||
Word16 *exponent /*!< pointer to exponent */
|
||||
);
|
||||
|
||||
Word32 Sqrt32norm( /*!< output mantissa */
|
||||
Word32 mantissa, /*!< normalized input mantissa */
|
||||
Word16 *exponent /*!< pointer to exponent */
|
||||
);
|
||||
|
||||
/* deprecated, use Sqrt16! */
|
||||
void BASOP_Util_Sqrt_MantExp (Word16 *mantissa, /*!< Pointer to mantissa */
|
||||
Word16 *exponent /*!< Pointer to exponent */
|
||||
);
|
||||
|
||||
/* deprecated, use Sqrt16norm! */
|
||||
void BASOP_Util_Sqrt_MantExpNorm (Word16 *mantissa, /*!< Pointer to normalized mantissa */
|
||||
Word16 *exponent /*!< Pointer to exponent */
|
||||
);
|
||||
|
||||
/****************************************************************************/
|
||||
/*!
|
||||
\brief Calculate the inverse of the squareroot of a number given by mantissa and exponent
|
||||
|
||||
Mantissa is in 16/32-bit-fractional format with values between 0 and 1. <br>
|
||||
For *norm versions mantissa has to be between 0.5 and 1. <br>
|
||||
The base for the exponent is 2. Example: \f$ a = a\_m * 2^{a\_e} \f$<br>
|
||||
The exponent is addressed via pointers and will be overwritten with the result.
|
||||
*/
|
||||
Word16 ISqrt16( /*!< output mantissa */
|
||||
Word16 mantissa, /*!< input mantissa */
|
||||
Word16 *exponent /*!< pointer to exponent */
|
||||
);
|
||||
|
||||
Word32 ISqrt32( /*!< output mantissa */
|
||||
Word32 mantissa, /*!< input mantissa */
|
||||
Word16 *exponent /*!< pointer to exponent */
|
||||
);
|
||||
|
||||
Word32 ISqrt32norm( /*!< output mantissa */
|
||||
Word32 mantissa, /*!< normalized input mantissa */
|
||||
Word16 *exponent /*!< pointer to exponent */
|
||||
);
|
||||
|
||||
/* deprecated, use ISqrt16! */
|
||||
void BASOP_Util_InvSqrt_MantExp (Word16 *mantissa, /*!< Pointer to mantissa */
|
||||
Word16 *exponent /*!< Pointer to exponent */
|
||||
);
|
||||
|
||||
/*****************************************************************************/
|
||||
/*!
|
||||
\brief Calculate the inverse of a number given by mantissa and exponent
|
||||
|
|
@ -190,6 +87,7 @@ Word16 Inv16( /*!< output mantissa */
|
|||
Word16 mantissa, /*!< input mantissa */
|
||||
Word16 *exponent /*!< pointer to exponent */
|
||||
);
|
||||
|
||||
/******************************************************************************/
|
||||
/*!
|
||||
\brief Calculate the squareroot and inverse of squareroot of a number given by mantissa and exponent
|
||||
|
|
@ -205,19 +103,7 @@ void BASOP_Util_Sqrt_InvSqrt_MantExp (Word16 mantissa, /*!< mantissa */
|
|||
Word16 *isqrt_exp /*!< Pointer to 1/sqrt exponent */
|
||||
);
|
||||
|
||||
/********************************************************************/
|
||||
/*!
|
||||
\brief Calculates the scalefactor needed to normalize input array
|
||||
|
||||
The scalefactor needed to normalize the Word16 input array is returned <br>
|
||||
If the input array contains only '0', a scalefactor 0 is returned <br>
|
||||
Scaling factor is determined wrt a normalized target x: 16384 <= x <= 32767 for positive x <br>
|
||||
and -32768 <= x <= -16384 for negative x
|
||||
*/
|
||||
|
||||
Word16 getScaleFactor16( /* o: measured headroom in range [0..15], 0 if all x[i] == 0 */
|
||||
const Word16 *x, /* i: array containing 16-bit data */
|
||||
const Word16 len_x); /* i: length of the array to scan */
|
||||
|
||||
/********************************************************************/
|
||||
/*!
|
||||
|
|
@ -233,106 +119,17 @@ Word16 getScaleFactor32( /* o: measured headroom in range [0..31
|
|||
const Word32 *x, /* i: array containing 32-bit data */
|
||||
const Word16 len_x); /* i: length of the array to scan */
|
||||
|
||||
/**
|
||||
* \brief normalize mantissa and update the exponent accordingly.
|
||||
* \param mantissa the mantissa to be normalized
|
||||
* \param pexponent pointer to the exponent.
|
||||
* \return the normalized mantissa.
|
||||
/************************************************************************/
|
||||
/*!
|
||||
\brief Binary logarithm with 7 iterations
|
||||
|
||||
\param x
|
||||
|
||||
\return log2(x)/64
|
||||
*/
|
||||
Word16 normalize16(Word16 mantissa, Word16 *pexponent);
|
||||
/****************************************************************************/
|
||||
/*!
|
||||
\brief Does fractional integer division of Word32 arg1 by Word16 arg2
|
||||
/************************************************************************/
|
||||
Word32 BASOP_Util_Log2(Word32 x);
|
||||
|
||||
both input arguments may be positive or negative <br>
|
||||
the result is truncated to Word16
|
||||
|
||||
\return fractional integer Word16 result of arg1/arg2
|
||||
*/
|
||||
Word16 divide3216( Word32 x, /*!< Numerator*/
|
||||
Word16 y); /*!< Denominator*/
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
/*!
|
||||
\brief Does fractional integer division of Word16 arg1 by Word16 arg2
|
||||
|
||||
both input arguments may be positive or negative <br>
|
||||
the result is truncated to Word16
|
||||
|
||||
\return fractional integer Word16 result of arg1/arg2
|
||||
*/
|
||||
Word16 divide1616( Word16 x, /*!< Numerator*/
|
||||
Word16 y); /*!< Denominator*/
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
/*!
|
||||
\brief Does fractional integer division of Word32 arg1 by Word32 arg2
|
||||
|
||||
this function makes both the numerator and the denominator positive integers,
|
||||
and scales up both values to avoid losing the accuracy of the outcome
|
||||
too much
|
||||
|
||||
WARNING: it should be arg1 < arg2 because of the maximum degree of scaling for the mantissa!
|
||||
|
||||
\return fractional Word16 integer z = arg1(32bits)/arg2(32bits)
|
||||
*/
|
||||
Word16 divide3232( Word32 x, /*!< Numerator*/
|
||||
Word32 y); /*!< Denominator*/
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
/*!
|
||||
\brief Does fractional integer division of UWord32 arg1 by UWord32 arg2
|
||||
|
||||
This function ensures both the numerator and the denominator are positive integers,
|
||||
and scales up both values to avoid losing the accuracy of the outcome
|
||||
too much.<br>
|
||||
|
||||
CAUTION: Arg 3 is a Word16 pointer which will point to the scalefactor difference
|
||||
s_diff = sub(s2,s1), where s1 and s2 are the scalefactors of the arguments, which
|
||||
were shifted in order to e.g. preserve accuracy.
|
||||
I.e. the result has to be scaled due to shifting it
|
||||
s_diff to the right to obtain the real result of the division.
|
||||
|
||||
\return fractional Word16 integer z = arg1(32bits)/arg2(32bits)
|
||||
*/
|
||||
Word16 BASOP_Util_Divide3232_uu_1616_Scale( Word32 x, /*!< i : Numerator*/
|
||||
Word32 y, /*!< i : Denominator*/
|
||||
Word16 *s); /*!< o : Additional scalefactor difference*/
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
/*!
|
||||
\brief Does fractional integer division of Word32 arg1 by Word32 arg2
|
||||
|
||||
This function scales up both values to avoid losing the accuracy of the outcome
|
||||
too much.<br>
|
||||
|
||||
CAUTION: Arg 3 is a Word16 pointer which will point to the scalefactor difference
|
||||
s_diff = sub(s2,s1), where s1 and s2 are the scalefactors of the arguments, which
|
||||
were shifted in order to e.g. preserve accuracy.
|
||||
I.e. the result has to be scaled due to shifting it
|
||||
s_diff to the right to obtain the real result of the division.
|
||||
|
||||
\return fractional Word16 integer z = arg1(32bits)/arg2(32bits)
|
||||
*/
|
||||
Word16 BASOP_Util_Divide3232_Scale( Word32 x, /*!< i : Numerator*/
|
||||
Word32 y, /*!< i : Denominator*/
|
||||
Word16 *s); /*!< o : Additional scalefactor difference*/
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
/*!
|
||||
\brief Does fractional integer division of Word32 arg1 by Word16 arg2
|
||||
|
||||
|
||||
\return fractional Word16 integer z = arg1(32bits)/arg2(16bits) , z not normalized
|
||||
*/
|
||||
Word16 BASOP_Util_Divide3216_Scale( Word32 x, /*!< i : Numerator */
|
||||
Word16 y, /*!< i : Denominator*/
|
||||
Word16 *s); /*!< o : Additional scalefactor difference*/
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
|
|
@ -346,17 +143,28 @@ Word16 BASOP_Util_Divide1616_Scale( Word16 x, /*!< i : Numerator*/
|
|||
Word16 y, /*!< i : Denominator*/
|
||||
Word16 *s); /*!< o : Additional scalefactor difference*/
|
||||
|
||||
/****************************************************************************/
|
||||
/*!
|
||||
\brief Does fractional integer division of Word32 arg1 by Word16 arg2
|
||||
|
||||
|
||||
\return fractional Word16 integer z = arg1(32bits)/arg2(16bits) , z not normalized
|
||||
*/
|
||||
Word16 BASOP_Util_Divide3216_Scale( Word32 x, /*!< i : Numerator */
|
||||
Word16 y, /*!< i : Denominator*/
|
||||
Word16 *s); /*!< o : Additional scalefactor difference*/
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/*!
|
||||
\brief Binary logarithm with 7 iterations
|
||||
|
||||
\param x
|
||||
|
||||
\return log2(x)/64
|
||||
* \brief Binary logarithm with 5 iterations
|
||||
*
|
||||
* \param[i] val
|
||||
*
|
||||
* \return basop_log2(val)/128
|
||||
*/
|
||||
/************************************************************************/
|
||||
Word32 BASOP_Util_Log2(Word32 x);
|
||||
|
||||
Word32 BASOP_Util_log2_i5(Word32 val);
|
||||
|
||||
/************************************************************************/
|
||||
/*!
|
||||
|
|
@ -399,49 +207,33 @@ Word32 BASOP_Util_Log2(Word32 x);
|
|||
/************************************************************************/
|
||||
Word32 BASOP_Util_InvLog2(Word32 x);
|
||||
|
||||
Word16 BASOP_util_norm_s_bands2shift (Word16 x);
|
||||
|
||||
/***********************************************************************/
|
||||
/*!
|
||||
\brief Calculate the headroom of the complex data in a 2 dimensional array
|
||||
|
||||
\return number of headroom bits
|
||||
*/
|
||||
Word16 BASOP_util_norm_l_dim2_cplx (const Word32 * const *re, /*!< Real part of 32 Bit input */
|
||||
const Word32 * const *im, /*!< Imag part if 32 Bit input */
|
||||
Word16 startBand, /*!< start band of cplx data */
|
||||
Word16 stopBand, /*!< stop band of cplx data */
|
||||
Word16 startSlot, /*!< start slot of cplx data */
|
||||
Word16 stopSlot /*!< stop slot of cplx data */
|
||||
);
|
||||
/****************************************************************************/
|
||||
/*!
|
||||
\brief Does a data copy of Word8 *arg1 to Word8 *arg2 with Word16 arg3 number of moves
|
||||
\brief Sets Array Word16 arg1 to value Word16 arg2 for Word16 arg3 elements
|
||||
*/
|
||||
void copyWord8( const Word8 *src, /*!< i : Source address */
|
||||
Word8 *dst, /*!< i : Destination address */
|
||||
const Word32 n); /*!< i : Number of elements to copy */
|
||||
void set_val_Word16( Word16 X[], /*!< Address of array */
|
||||
const Word16 val, /*!< Value to copy into array */
|
||||
Word16 n); /*!< Number of elements to process */
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
/*!
|
||||
\brief Sets Word8 array arg1[] to zero for a length of Word16 arg2 elements
|
||||
\brief Sets Array Word32 arg1 to value Word32 arg2 for Word16 arg3 elements
|
||||
*/
|
||||
void set_zero_Word8( Word8 X[], /*!< i : Address of array */
|
||||
Word32 n); /*!< i : Number of elements to set to zero */
|
||||
void set_val_Word32( Word32 X[], /*!< Address of array */
|
||||
const Word32 val, /*!< Value to copy into array */
|
||||
Word16 n); /*!< Number of elements to process */
|
||||
|
||||
/****************************************************************************/
|
||||
/*!
|
||||
\brief Does a multiplication of Word32 * Word16 input values
|
||||
\brief Does a multiplication of Word16 input values
|
||||
|
||||
\return z32 = x32 * y16
|
||||
\return z16 = x16 * y16
|
||||
*/
|
||||
Word32 L_mult0_3216( Word32 x, /*!< : Multiplier */
|
||||
Word16 y); /*!< : Multiplicand */
|
||||
Word16 mult0 ( Word16 x, /*!< i : Multiplier */
|
||||
Word16 y); /*!< i : Multiplicand */
|
||||
|
||||
/* Calculate sin/cos. Angle in 2Q13 format, result has exponent = 1 */
|
||||
Word16 getCosWord16(Word16 theta);
|
||||
Word32 getCosWord32(Word32 theta);
|
||||
/**
|
||||
* \brief calculate cosine of angle. Tuned for ISF domain.
|
||||
* \param theta Angle normalized to radix 2, theta = (angle in radians)*2.0/pi
|
||||
|
|
@ -449,62 +241,6 @@ Word32 getCosWord32(Word32 theta);
|
|||
*/
|
||||
Word16 getCosWord16R2(Word16 theta);
|
||||
|
||||
/****************************************************************************/
|
||||
/*!
|
||||
\brief square root abacus algorithm
|
||||
|
||||
\return integer sqrt(x)
|
||||
*/
|
||||
Word16 getSqrtWord32(Word32 x);
|
||||
|
||||
/****************************************************************************/
|
||||
/*!
|
||||
\brief finds index of min Word16 in array
|
||||
|
||||
\return index of min Word16
|
||||
*/
|
||||
Word16 findIndexOfMinWord16(Word16 *x, const Word16 len);
|
||||
|
||||
/****************************************************************************/
|
||||
/*!
|
||||
\brief finds index of min Word32 in array
|
||||
|
||||
\return index of min Word32
|
||||
*/
|
||||
Word16 findIndexOfMinWord32(Word32 *x, const Word16 len);
|
||||
|
||||
/****************************************************************************/
|
||||
/*!
|
||||
\brief finds index of max Word16 in array
|
||||
|
||||
\return index of max Word16
|
||||
*/
|
||||
Word16 findIndexOfMaxWord16(Word16 *x, const Word16 len);
|
||||
|
||||
/****************************************************************************/
|
||||
/*!
|
||||
\brief finds index of max Word32 in array
|
||||
|
||||
\return index of max Word32
|
||||
*/
|
||||
Word16 findIndexOfMaxWord32(Word32 *x, const Word16 len);
|
||||
|
||||
/****************************************************************************/
|
||||
/*!
|
||||
\brief 16x16->16 integer multiplication without overflow control
|
||||
|
||||
\return 16x16->16 integer
|
||||
*/
|
||||
Word16 imult1616(Word16 x, Word16 y);
|
||||
|
||||
/****************************************************************************/
|
||||
/*!
|
||||
\brief 32x16->32 integer multiplication with overflow control
|
||||
|
||||
\return 32x16->32 integer
|
||||
*/
|
||||
Word32 imult3216(Word32 x, Word16 y);
|
||||
|
||||
/****************************************************************************/
|
||||
/*!
|
||||
\brief 16/16->16 unsigned integer division
|
||||
|
|
@ -516,100 +252,7 @@ Word32 imult3216(Word32 x, Word16 y);
|
|||
|
||||
Word16 idiv1616U(Word16 x, Word16 y);
|
||||
|
||||
/****************************************************************************/
|
||||
/*!
|
||||
\brief 16/16->16 signed integer division
|
||||
|
||||
x and y have to be positive, x has to be < 16384
|
||||
|
||||
\return 16/16->16 integer
|
||||
*/
|
||||
|
||||
Word16 idiv1616(Word16 x, Word16 y);
|
||||
|
||||
/*------------------------------------------------------------------*
|
||||
* Dot_product16HQ:
|
||||
*
|
||||
* \brief Compute scalar product of <x[],y[]> using 64-bit accumulator.
|
||||
*
|
||||
* Performs normalization of the result, returns the exponent
|
||||
* Note: In contrast to dotWord32, no headroom is required for data
|
||||
* in x[] and y[], means, they may have any format Qn
|
||||
*------------------------------------------------------------------*/
|
||||
Word32 Dot_product16HQ( /*<! o : normalized result Q31 */
|
||||
const Word32 L_off, /*<! i : initial sum value Qn */
|
||||
const Word16 x[], /*<! i : x vector Qn */
|
||||
const Word16 y[], /*<! i : y vector Qn */
|
||||
const Word16 lg, /*<! i : vector length, range [0..7FFF] Q0 */
|
||||
Word16 * exp /*<! o : exponent of result in [-32,31] Q0 */
|
||||
);
|
||||
|
||||
|
||||
/*------------------------------------------------------------------*
|
||||
* norm_llQ31:
|
||||
*
|
||||
* \brief Compute normalized Q31 Values out of overflowed Q31 value
|
||||
*
|
||||
* Performs the calculation of a normalized Q31 Value with its
|
||||
* scalingfactor, taking into account the overflowed Q31 input value
|
||||
* and the number of Carrys, collected.
|
||||
*------------------------------------------------------------------*/
|
||||
Word32 norm_llQ31( /* o : normalized result Q31 */
|
||||
Word32 L_c, /* i : upper bits of accu Q-1 */
|
||||
Word32 L_sum, /* i : lower bits of accu, unsigned Q31 */
|
||||
Word16 * exp /* o : exponent of result in [-32,31] Q0 */
|
||||
);
|
||||
|
||||
/**
|
||||
* \brief Compute dot product of 1 32 bit vectors with itself
|
||||
* \param x input vector 1
|
||||
* \param headroom amount of headroom bits the input vector
|
||||
* \param length the length of the input vector
|
||||
* \param result_e pointer to where the exponent of the result will be stored into
|
||||
* \return the dot product of x and x.
|
||||
*/
|
||||
Word32 Norm32Norm(const Word32 *x, const Word16 headroom, const Word16 length, Word16 *result_e);
|
||||
|
||||
|
||||
/*------------------------------------------------------------------*
|
||||
* Dot_productSq16HQ:
|
||||
*
|
||||
* \brief Compute scalar product of <x[],x[]> using 64-bit accumulator.
|
||||
*
|
||||
* Performs normalization of the result, returns the exponent
|
||||
* Note: In contrast to dotWord32, no headroom is required for data
|
||||
* in x[], means, they may have any format Qn
|
||||
*------------------------------------------------------------------*/
|
||||
Word32 Dot_productSq16HQ( /*<! o : normalized result Q31 */
|
||||
const Word32 L_off, /*<! i : initial sum value Qn */
|
||||
const Word16 x[], /*<! i : x vector Qn */
|
||||
const Word16 lg, /*<! i : vector length, range [0..7FFF] Q0 */
|
||||
Word16 * exp /*<! o : exponent of result in [-32,31] Q0 */
|
||||
);
|
||||
|
||||
/*------------------------------------------------------------------*
|
||||
* dotp_s_fx:
|
||||
*
|
||||
* \brief Compute scalar product of <x[],y[]> using 64-bit accumulator.
|
||||
*
|
||||
* Performs no normalization of the result
|
||||
*------------------------------------------------------------------*/
|
||||
Word32 dotp_s_fx( /*<! o : dot product of vector x and y 16Q15 */
|
||||
const Word16 *x, /*<! i : vector x 6Q9 */
|
||||
const Word16 *y, /*<! i : vector y 6Q9 */
|
||||
const Word16 n, /*<! i : vector length Q0 */
|
||||
Word16 s /*<! i : headroom Q0 */
|
||||
);
|
||||
|
||||
/*-------------------------------------------------------------------*
|
||||
* Sum32:
|
||||
*
|
||||
* \brief Return the sum of one 32 bits vector
|
||||
*-------------------------------------------------------------------*/
|
||||
Word32 Sum32( /*<! o : the sum of the elements of the vector */
|
||||
const Word32 *vec, /*<! i : input vector */
|
||||
const Word16 lvec /*<! i : length of input vector */
|
||||
);
|
||||
/**
|
||||
* \brief return 2 ^ (exp * 2^exp_e)
|
||||
* \param exp_m mantissa of the exponent to 2.0f
|
||||
|
|
@ -623,26 +266,61 @@ Word32 BASOP_util_Pow2(
|
|||
);
|
||||
|
||||
|
||||
/* deprecated, use ISqrt32norm! */
|
||||
Word32 Isqrt_lc(
|
||||
Word32 frac, /*!< (i) Q31: normalized value (1.0 < frac <= 0.5) */
|
||||
Word16 * exp /*!< (i/o) : exponent (value = frac x 2^exponent) */
|
||||
Word32 Isqrt_lc1(
|
||||
Word32 frac, /* (i) Q31: normalized value (1.0 < frac <= 0.5) */
|
||||
Word16 * exp /* (i/o) : exponent (value = frac x 2^exponent) */
|
||||
);
|
||||
|
||||
/**
|
||||
* \brief return 1/x
|
||||
* \param x index of lookup table
|
||||
* \return Word16 value of 1/x
|
||||
*/
|
||||
Word16 getNormReciprocalWord16(Word16 x);
|
||||
/*****************************************************************************/
|
||||
/*!
|
||||
|
||||
/**
|
||||
* \brief return (1/x) << s
|
||||
* \param x index of lookup table
|
||||
* \param s shift factor
|
||||
* \return Word16 value of (1/x) << s
|
||||
*/
|
||||
Word16 getNormReciprocalWord16Scale(Word16 x, Word16 s);
|
||||
\brief Calculates pow(2,x)
|
||||
___________________________________________________________________________
|
||||
| |
|
||||
| Function Name : Pow2() |
|
||||
| |
|
||||
| L_x = pow(2.0, exponant.fraction) (exponent = interger part) |
|
||||
| = pow(2.0, 0.fraction) << exponent |
|
||||
|---------------------------------------------------------------------------|
|
||||
| Algorithm: |
|
||||
| |
|
||||
| The function Pow2(L_x) is approximated by a table and linear |
|
||||
| interpolation. |
|
||||
| |
|
||||
| 1- i = bit10-b15 of fraction, 0 <= i <= 31 |
|
||||
| 2- a = bit0-b9 of fraction |
|
||||
| 3- L_x = table[i]<<16 - (table[i] - table[i+1]) * a * 2 |
|
||||
| 4- L_x = L_x >> (30-exponant) (with rounding) |
|
||||
|___________________________________________________________________________|
|
||||
*/
|
||||
Word32 Pow2( /*!< (o) Q0 : result (range: 0<=val<=0x7fffffff) */
|
||||
Word16 exponant, /*!< (i) Q0 : Integer part. (range: 0<=val<=30) */
|
||||
Word16 fraction /*!< (i) Q15 : Fractionnal part. (range: 0.0<=val<1.0) */
|
||||
);
|
||||
|
||||
/*************************************************************************
|
||||
*
|
||||
* FUNCTION: Log2_norm()
|
||||
*
|
||||
* PURPOSE: Computes log2(L_x, exp), where L_x is positive and
|
||||
* normalized, and exp is the normalisation exponent
|
||||
* If L_x is negative or zero, the result is 0.
|
||||
*
|
||||
* DESCRIPTION:
|
||||
* The function Log2(L_x) is approximated by a table and linear
|
||||
* interpolation. The following steps are used to compute Log2(L_x)
|
||||
*
|
||||
* 1- exponent = 30-norm_exponent
|
||||
* 2- i = bit25-b31 of L_x; 32<=i<=63 (because of normalization).
|
||||
* 3- a = bit10-b24
|
||||
* 4- i -=32
|
||||
* 5- fraction = table[i]<<16 - (table[i] - table[i+1]) * a * 2
|
||||
*
|
||||
*************************************************************************/
|
||||
|
||||
Word16 Log2_norm_lc ( /* (o) : Fractional part of Log2. (range: 0<=val<1) */
|
||||
Word32 L_x /* (i) : input value (normalized) */
|
||||
);
|
||||
|
||||
/*************************************************************************
|
||||
*
|
||||
|
|
@ -674,41 +352,6 @@ Word32 BASOP_Util_fPow( /* (o) : mantissa of result
|
|||
Word16 *result_e /* (o) : output pointer to exponent of result */
|
||||
);
|
||||
|
||||
/*___________________________________________________________________________
|
||||
| |
|
||||
| Function Name : Dot_product12_offs() |
|
||||
| |
|
||||
| Compute scalar product of <x[],y[]> using accumulator. |
|
||||
| The parameter 'L_off' is added to the accumulation result. |
|
||||
| The result is normalized (in Q31) with exponent (0..30). |
|
||||
| Notes: |
|
||||
| o data in x[],y[] must provide enough headroom for accumulation |
|
||||
| o L_off must correspond in format with product of x,y |
|
||||
| Example: 0.01f for Q9 x Q9: 0x0000147B in Q19 |
|
||||
| means: L_off = FL2WORD32_SCALE(0.01f,31-19) |
|
||||
|---------------------------------------------------------------------------|
|
||||
| Algorithm: |
|
||||
| |
|
||||
| dot_product = L_off + sum(x[i]*y[i]) i=0..N-1 |
|
||||
|___________________________________________________________________________|
|
||||
*/
|
||||
|
||||
Word32 Dot_product12_offs( /* (o) Q31: normalized result (1 < val <= -1) */
|
||||
const Word16 x[], /* (i) 12bits: x vector */
|
||||
const Word16 y[], /* (i) 12bits: y vector */
|
||||
const Word16 lg, /* (i) : vector length in range [1..256] */
|
||||
Word16 * exp, /* (o) : exponent of result (0..+30) */
|
||||
Word32 L_off /* (i) initial summation offset /2 */
|
||||
);
|
||||
|
||||
Word32 Dot_product15_offs( /* (o) Q31: normalized result (1 < val <= -1) */
|
||||
const Word16 x[], /* (i) 15bits: x vector */
|
||||
const Word16 y[], /* (i) 15bits: y vector */
|
||||
const Word16 lg, /* (i) : vector length in range [1..256] */
|
||||
Word16 *exp, /* (o) : exponent of result (0..+30) */
|
||||
Word32 L_off /* (i) initial summation offset */
|
||||
);
|
||||
|
||||
/*!**********************************************************************
|
||||
\brief Add two values given by mantissa and exponent.
|
||||
|
||||
|
|
@ -722,96 +365,22 @@ Word32 BASOP_Util_Add_Mant32Exp /*!< o: normalized result manti
|
|||
Word32 b_m, /*!< i: Mantissa of 2nd operand b */
|
||||
Word16 b_e, /*!< i: Exponent of 2nd operand b */
|
||||
Word16 *ptr_e); /*!< o: exponent of result */
|
||||
/*!**********************************************************************
|
||||
\brief Returns the comparison result of two normalized values given by mantissa and exponent.
|
||||
return value: -1: a < b, 0: a == b, 1; a > b
|
||||
|
||||
Mantissas are in 32-bit-fractional format with values between 0 and 1. <br>
|
||||
The base for exponents is 2. Example: \f$ a = a\_m * 2^{a\_e} \f$<br>
|
||||
|
||||
************************************************************************/
|
||||
Word16 BASOP_Util_Cmp_Mant32Exp /*!< o: flag: result of comparison */
|
||||
(Word32 a_m, /*!< i: Mantissa of 1st operand a */
|
||||
Word16 a_e, /*!< i: Exponent of 1st operand a */
|
||||
Word32 b_m, /*!< i: Mantissa of 2nd operand b */
|
||||
Word16 b_e); /*!< i: Exponent of 2nd operand b */
|
||||
|
||||
/********************************************************************
|
||||
* bufferCopyFx
|
||||
*
|
||||
* \brief copies buffer while preserving Format of destination buffer
|
||||
*********************************************************************
|
||||
*/
|
||||
void bufferCopyFx(
|
||||
Word16* src, /*<! Qx pointer to input buffer */
|
||||
Word16* dest, /*<! Qx pointer to output buffer */
|
||||
Word16 length, /*<! Q0 length of buffer to copy */
|
||||
Word16 Qf_src, /*<! Q0 Q format (frac-bits) of source buffer */
|
||||
Word16 Qf_dest, /*<! Q0 Q format (frac-bits )of dest buffer */
|
||||
Word16 Q_src, /*<! Q0 exponent of source buffer */
|
||||
Word16 Q_dest /*<! Q0 exponent of destination buffer */
|
||||
);
|
||||
|
||||
/****************************************************************************/
|
||||
/*!
|
||||
\brief Accumulates multiplications
|
||||
|
||||
Accumulates the elementwise multiplications of Word32 Array bufX32 with Word16 Array bufY16
|
||||
pointed to by arg1 to arg4 including the corresponding exponents. Length of to be multiplied arrays is arg5,
|
||||
Accumulates the elementwise multiplications of Word32 Array X with Word16 Array Y
|
||||
pointed to by arg1 and arg2 with specified headroom. Length of to be multiplied arrays is arg3,
|
||||
headroom with has to be taken into account is specified in arg4
|
||||
|
||||
\return Word32 result of accumulated multiplications over Word32 array arg1 and Word16 array arg3 and Word16 pointer
|
||||
to exponent of the result
|
||||
\return Word32 result of accumulated multiplications over Word32 array arg1 and Word16 array arg2 and Word16 pointer
|
||||
to exponent correction factor which needs to be added to the exponent of the result vector
|
||||
*/
|
||||
Word32 dotWord32_16_Mant32Exp(const Word32 *bufX32,/* i: 32-bit buffer with unknown headroom */
|
||||
Word16 bufX32_exp, /* i: exponent of buffer bufX32 */
|
||||
const Word16 *bufY16,/* i: 16-bit buffer quite right-aligned */
|
||||
Word16 bufY16_exp, /* i: exponent of buffer bufY16 */
|
||||
Word16 len, /* i: buffer len to process */
|
||||
Word16 *exp); /* o: result exponent */
|
||||
|
||||
/*!**********************************************************************
|
||||
\brief Converts linear factor or energy to Decibel
|
||||
return value: fEnergy=0: 20 * log10(x * 2^{x\_e}),
|
||||
fEnergy=1: 10 * log10(x * 2^{x\_e})
|
||||
|
||||
Mantissa x is in 32-bit-fractional format with values between 0 and 1. <br>
|
||||
The base for exponent x_e is 2. <br>
|
||||
|
||||
************************************************************************/
|
||||
Word16 BASOP_Util_lin2dB( /*!< o: dB value (7Q8) */
|
||||
Word32 x, /*!< i: mantissa */
|
||||
Word16 x_e, /*!< i: exponent */
|
||||
Word16 fEnergy); /*!< i: flag indicating if x is energy */
|
||||
|
||||
/*!**********************************************************************
|
||||
\brief Calculates atan(x).
|
||||
************************************************************************/
|
||||
Word16 BASOP_util_atan( /*!< o: atan(x) [-pi/2;pi/2] 1Q14 */
|
||||
Word32 x /*!< i: input data (-64;64) 6Q25 */
|
||||
);
|
||||
|
||||
/*!**********************************************************************
|
||||
\brief Calculates atan2(y,x).
|
||||
************************************************************************/
|
||||
Word16 BASOP_util_atan2( /*!< o: atan2(y,x) [-pi,pi] Q13 */
|
||||
Word32 y, /*!< i: */
|
||||
Word32 x, /*!< i: */
|
||||
Word16 e /*!< i: exponent difference (exp_y - exp_x) */
|
||||
);
|
||||
/*!**********************************************************************
|
||||
\brief norm_llQ31 returns Word32 with scalingfactor, with 2 32bit accus as input
|
||||
|
||||
************************************************************************/
|
||||
Word32 norm_llQ31( /* o : normalized result Q31 */
|
||||
Word32 L_c, /* i : upper bits of accu Q-1 */
|
||||
Word32 L_sum, /* i : lower bits of accu, unsigned Q31 */
|
||||
Word16 * exp /* o : exponent of result in [-32,31] Q0 */
|
||||
);
|
||||
|
||||
/* compare two positive normalized 16 bit mantissa/exponent values */
|
||||
/* return value: positive if first value greater, negative if second value greater, zero if equal */
|
||||
Word16 compMantExp16Unorm(Word16 m1, Word16 e1, Word16 m2, Word16 e2);
|
||||
Word32 dotWord32_16_guards(const Word32 * X, const Word16 * Y, Word16 n, Word16 hr, Word16 * shift);
|
||||
|
||||
|
||||
|
||||
Word32 Sqrt_l(Word32 L_x, Word16 *exp);
|
||||
|
||||
#endif /* __BASOP_UTIL_H__ */
|
||||
|
|
|
|||
|
|
@ -0,0 +1,46 @@
|
|||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.443 Nov 13, 2018. Version 12.11.0 / 13.7.0 / 14.3.0 / 15.1.0
|
||||
====================================================================================*/
|
||||
|
||||
#ifndef __BASTYPES_H
|
||||
#define __BASTYPES_H
|
||||
|
||||
typedef unsigned char BYTE;
|
||||
typedef unsigned short WORD;
|
||||
#if defined(__alpha__) || defined(__alpha) || defined(__sgi)
|
||||
typedef unsigned int DWORD; /* long is 64 bits on these machines */
|
||||
#else
|
||||
typedef unsigned long DWORD;
|
||||
#endif
|
||||
|
||||
typedef int BOOL;
|
||||
typedef signed int INT;
|
||||
typedef signed long LONG;
|
||||
typedef unsigned long ULONG;
|
||||
typedef unsigned int UINT;
|
||||
typedef float FLOAT;
|
||||
typedef double DOUBLE;
|
||||
typedef unsigned char UCHAR;
|
||||
typedef char CHAR;
|
||||
|
||||
/* from uld_types.h: */
|
||||
typedef short SHORT;
|
||||
typedef unsigned short USHORT;
|
||||
typedef long int LINT;
|
||||
typedef unsigned long int ULINT;
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#endif
|
||||
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#endif
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
#define INVALID_HANDLE NULL
|
||||
|
||||
#endif
|
||||
504
src/libs/libevs/lib_com/bitalloc_fx.cpp → src/libs/libevs/lib_com/bitalloc.cpp
Executable file → Normal file
504
src/libs/libevs/lib_com/bitalloc_fx.cpp → src/libs/libevs/lib_com/bitalloc.cpp
Executable file → Normal file
|
|
@ -1,209 +1,181 @@
|
|||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
EVS Codec 3GPP TS26.443 Nov 13, 2018. Version 12.11.0 / 13.7.0 / 14.3.0 / 15.1.0
|
||||
====================================================================================*/
|
||||
|
||||
#include "options.h"
|
||||
#include "cnst.h"
|
||||
#include "rom_com.h"
|
||||
#include "prot.h"
|
||||
#include "basop_util.h"
|
||||
#include "basop_proto_func.h"
|
||||
|
||||
#include "options.h" /* Compilation switches */
|
||||
#include "cnst_fx.h" /* Common constants */
|
||||
#include "rom_com_fx.h" /* Static table prototypes */
|
||||
#include "prot_fx.h" /* Function prototypes */
|
||||
#include "stl.h" /* required for wmc_tool */
|
||||
|
||||
void bitalloc_fx (
|
||||
Word16 *y, /* i : reordered norm of sub-vectors Q0 */
|
||||
Word16 *idx, /* i : reordered sub-vector indices Q0 */
|
||||
Word16 sum, /* i : number of available bits Q0 */
|
||||
Word16 N, /* i : number of norms Q0 */
|
||||
Word16 K, /* i : maximum number of bits per dimension Q0 */
|
||||
Word16 *r, /* o : bit-allacation vector Q0 */
|
||||
const Word16 *sfmsize, /* i : band length Q0 */
|
||||
const Word16 hqswb_clas /* i : signal classification flag Q0 */
|
||||
/*--------------------------------------------------------------------------
|
||||
* bitalloc()
|
||||
*
|
||||
* Adaptive bit allocation for 20kHz audio codec
|
||||
*--------------------------------------------------------------------------*/
|
||||
|
||||
void bitalloc (
|
||||
short *y, /* i : reordered norm of sub-vectors */
|
||||
short *idx, /* i : reordered sub-vector indices */
|
||||
short sum, /* i : number of available bits */
|
||||
short N, /* i : number of norms */
|
||||
short K, /* i : maximum number of bits per dimension */
|
||||
short *r, /* o : bit-allacation vector */
|
||||
const short *sfmsize, /* i : band length */
|
||||
const short hqswb_clas /* i : signal classification flag */
|
||||
)
|
||||
{
|
||||
Word16 i, j, k, n, m, v, im;
|
||||
Word16 diff, temp;
|
||||
Word16 fac;
|
||||
Word16 ii;
|
||||
Word16 SFM_thr = SFM_G1G2;
|
||||
move16();
|
||||
short i, j, k, n, m, v, im;
|
||||
short diff, temp;
|
||||
short fac;
|
||||
short ii;
|
||||
short SFM_thr = SFM_G1G2;
|
||||
|
||||
N = sub(N, 1);
|
||||
N -= 1;
|
||||
|
||||
if ( sub(hqswb_clas, HQ_HARMONIC) == 0 )
|
||||
if ( hqswb_clas == HQ_HARMONIC )
|
||||
{
|
||||
SFM_thr = 22;
|
||||
move16();
|
||||
}
|
||||
|
||||
fac = 3;
|
||||
move16();
|
||||
K = sub(K,2);
|
||||
K -= 2;
|
||||
im = 1;
|
||||
move16();
|
||||
diff = sum;
|
||||
move16();
|
||||
n = shr(sum,3);
|
||||
FOR ( i=0; i<n; i++ )
|
||||
n = sum >> 3;
|
||||
for ( i=0; i<n; i++ )
|
||||
{
|
||||
k = 0;
|
||||
move16();
|
||||
temp = y[0];
|
||||
move16();
|
||||
FOR ( m=1; m<im; m++)
|
||||
for (m=1; m<im; m++)
|
||||
{
|
||||
v = sub( temp, y[m] );
|
||||
temp = s_max(temp, y[m]);
|
||||
if ( v < 0 )
|
||||
if ( temp < y[m] )
|
||||
{
|
||||
temp = y[m];
|
||||
k = m;
|
||||
move16();
|
||||
}
|
||||
}
|
||||
|
||||
IF ( sub(temp, y[m]) < 0 )
|
||||
if ( temp < y[m] )
|
||||
{
|
||||
k = m;
|
||||
move16();
|
||||
if ( sub(im, N) < 0 )
|
||||
if ( im < N)
|
||||
{
|
||||
im = add(im, 1);
|
||||
im++;
|
||||
}
|
||||
}
|
||||
|
||||
j = idx[k];
|
||||
move16();
|
||||
|
||||
test();
|
||||
IF ( sub(sum,sfmsize[j]) >= 0 && sub(r[j],K) < 0 )
|
||||
if ( sum >= sfmsize[j] && r[j] < K )
|
||||
{
|
||||
y[k] = sub(y[k], fac);
|
||||
move16();
|
||||
r[j] = add(r[j], 1);
|
||||
move16();
|
||||
|
||||
if ( sub(r[j], K) >= 0 )
|
||||
y[k] -= fac;
|
||||
r[j]++;
|
||||
if ( r[j] >= K )
|
||||
{
|
||||
y[k] = -32768;
|
||||
move16();
|
||||
y[k] = MIN16B;
|
||||
}
|
||||
sum = sub(sum,sfmsize[j]);
|
||||
sum -= sfmsize[j];
|
||||
}
|
||||
ELSE
|
||||
else
|
||||
{
|
||||
y[k] = -32768;
|
||||
move16();
|
||||
k = add(k, 1);
|
||||
test();
|
||||
if ( sub(k, im) == 0 && sub(im, N) < 0 )
|
||||
y[k] = MIN16B;
|
||||
k++;
|
||||
if ( k == im && im < N )
|
||||
{
|
||||
im = add(im, 1);
|
||||
im++;
|
||||
}
|
||||
}
|
||||
|
||||
test();
|
||||
IF ( (sub(sum, WID_G1)<0) || (sub(diff, sum)==0) )
|
||||
if ( sum < WID_G1 || diff == sum )
|
||||
{
|
||||
BREAK;
|
||||
break;
|
||||
}
|
||||
|
||||
diff = sum;
|
||||
move16();
|
||||
v = sub(N, 1);
|
||||
v = N - 1;
|
||||
|
||||
IF ( sub(k, v) > 0 )
|
||||
if (k > v)
|
||||
{
|
||||
FOR ( ii=0; ii<=N; ii++ )
|
||||
for ( ii=0; ii<=N; ii++ )
|
||||
{
|
||||
IF ( sub(y[ii], -32768) > 0 )
|
||||
if ( y[ii] > MIN16B )
|
||||
{
|
||||
if ( sub(ii, N) < 0 )
|
||||
if( ii < N )
|
||||
{
|
||||
im = add(ii, 1);
|
||||
im = ii + 1;
|
||||
}
|
||||
BREAK;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
IF ( sub(sum, WID_G2) >= 0 )
|
||||
if ( sum >= WID_G2)
|
||||
{
|
||||
FOR (i=0; i<=N; i++)
|
||||
for (i=0; i<=N; i++)
|
||||
{
|
||||
j = idx[i];
|
||||
move16();
|
||||
test();
|
||||
test();
|
||||
IF ( sub(j, SFM_G1) >= 0 && sub(j, SFM_thr) < 0 && r[j] == 0 )
|
||||
if ( j >= SFM_G1 && j < SFM_thr && r[j] == 0 )
|
||||
{
|
||||
r[j] = 1;
|
||||
move16();
|
||||
sum = sub(sum, WID_G2);
|
||||
IF (sub(sum, WID_G2) < 0)
|
||||
sum -= WID_G2;
|
||||
if ( sum < WID_G2 )
|
||||
{
|
||||
BREAK;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IF ( sub(sum, WID_G2) >= 0 )
|
||||
if ( sum >= WID_G2 )
|
||||
{
|
||||
FOR (i=0; i<=N; i++)
|
||||
for (i=0; i<=N; i++)
|
||||
{
|
||||
j = idx[i];
|
||||
move16();
|
||||
test();
|
||||
test();
|
||||
IF ( sub(j,SFM_G1) >= 0 && sub(j, SFM_thr) < 0 && sub(r[j], 1) == 0 )
|
||||
if ( j >= SFM_G1 && j < SFM_thr && r[j] == 1 )
|
||||
{
|
||||
r[j] = 2;
|
||||
move16();
|
||||
sum = sub(sum, WID_G2);
|
||||
IF ( sub(sum, WID_G2) < 0 )
|
||||
sum -= WID_G2;
|
||||
if ( sum < WID_G2 )
|
||||
{
|
||||
BREAK;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IF ( sub(sum, WID_G1) >= 0 )
|
||||
if ( sum >= WID_G1 )
|
||||
{
|
||||
FOR (i=0; i<=N; i++)
|
||||
for (i=0; i<=N; i++)
|
||||
{
|
||||
j = idx[i];
|
||||
move16();
|
||||
test();
|
||||
IF ( sub(j, SFM_G1) < 0 && r[j] == 0 )
|
||||
if ( j < SFM_G1 && r[j] == 0 )
|
||||
{
|
||||
r[j] = 1;
|
||||
move16();
|
||||
sum = sub(sum, WID_G1);
|
||||
IF ( sub(sum, WID_G1) < 0 )
|
||||
sum -= WID_G1;
|
||||
if ( sum < WID_G1 )
|
||||
{
|
||||
BREAK;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IF ( sub(sum, WID_G1) >= 0 )
|
||||
if ( sum >= WID_G1 )
|
||||
{
|
||||
FOR (i=0; i<=N; i++)
|
||||
for (i=0; i<=N; i++)
|
||||
{
|
||||
j = idx[i];
|
||||
move16();
|
||||
test();
|
||||
IF ( sub(j, SFM_G1) < 0 && sub(r[j], 1) == 0 )
|
||||
if ( j < SFM_G1 && r[j] == 1 )
|
||||
{
|
||||
r[j] = 2;
|
||||
move16();
|
||||
sum = sub(sum, WID_G1);
|
||||
IF ( sub(sum, WID_G1) < 0 )
|
||||
sum -= WID_G1;
|
||||
if ( sum < WID_G1 )
|
||||
{
|
||||
BREAK;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -212,21 +184,22 @@ void bitalloc_fx (
|
|||
return;
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------*
|
||||
* BitAllocF()
|
||||
*
|
||||
* Fractional bit allocation
|
||||
*-------------------------------------------------------------------*/
|
||||
|
||||
Word16 BitAllocF_fx (
|
||||
Word16 *y, /* i : norm of sub-vectors :Q0 */
|
||||
Word32 bit_rate, /* i : bitrate :Q0 */
|
||||
Word16 B, /* i : number of available bits :Q0 */
|
||||
Word16 N, /* i : number of sub-vectors :Q0 */
|
||||
Word16 *R, /* o : bit-allocation indicator :Q0 */
|
||||
Word16 *Rsubband_fx /* o : sub-band bit-allocation vector :Q3 */
|
||||
,const Word16 hqswb_clas, /* i : hq swb class :Q0 */
|
||||
const Word16 num_env_bands/* i : Number sub bands to be encoded for HF GNERIC :Q0 */
|
||||
short BitAllocF (
|
||||
short *y, /* i : norm of sub-vectors */
|
||||
long bit_rate, /* i : bitrate */
|
||||
short B, /* i : number of available bits */
|
||||
short N, /* i : number of sub-vectors */
|
||||
short *R, /* o : bit-allocation indicator */
|
||||
short *Rsubband, /* o : sub-band bit-allocation vector (Q3) */
|
||||
const short hqswb_clas, /* i : hq swb class */
|
||||
const short num_env_bands /* i : Number sub bands to be encoded for HQ_SWB_BWE */
|
||||
)
|
||||
{
|
||||
Word16 fac;
|
||||
|
|
@ -234,55 +207,44 @@ Word16 BitAllocF_fx (
|
|||
|
||||
Word16 m_fx;
|
||||
Word32 t_fx, B_fx;
|
||||
Word32 L_tmp1, L_tmp2, L_tmp3;
|
||||
Word32 L_tmp1, L_tmp2;
|
||||
Word16 tmp, exp1, exp2;
|
||||
Word32 Rsubband_w32_fx[NB_SFM]; /* Q15 */
|
||||
Word16 B_w16_fx;
|
||||
|
||||
set32_fx( Rsubband_w32_fx, 0, NB_SFM);
|
||||
set_i( Rsubband_w32_fx, 0, NB_SFM);
|
||||
|
||||
fac = 3;
|
||||
move16();
|
||||
|
||||
IF (L_sub(bit_rate, 32000) < 0)
|
||||
if (L_sub(bit_rate, 32000) < 0)
|
||||
{
|
||||
bs = 2;
|
||||
move16();
|
||||
}
|
||||
ELSE
|
||||
else
|
||||
{
|
||||
bs = 3;
|
||||
move16();
|
||||
}
|
||||
low_rate = 1;
|
||||
move16();
|
||||
|
||||
Nmin = N;
|
||||
move16();
|
||||
if ( sub(Nmin,SFM_N) > 0)
|
||||
{
|
||||
Nmin = SFM_N;
|
||||
move16();
|
||||
}
|
||||
|
||||
/* Initial bits distribution */
|
||||
test();
|
||||
IF (sub(hqswb_clas , HQ_GEN_SWB) == 0 || sub(hqswb_clas , HQ_GEN_FB) == 0)
|
||||
if (sub(hqswb_clas , HQ_GEN_SWB) == 0 || sub(hqswb_clas , HQ_GEN_FB) == 0)
|
||||
{
|
||||
/* Initial bits distribution */
|
||||
L_tmp1 = 0;
|
||||
move16();
|
||||
m_fx = 0;
|
||||
move16();
|
||||
FOR ( i = 0; i < num_env_bands ; i++)
|
||||
for ( i = 0; i < num_env_bands ; i++)
|
||||
{
|
||||
L_tmp1 = L_mac0(L_tmp1, Nb[i], y[i]);
|
||||
}
|
||||
L_tmp1 = L_msu0(L_tmp1, fac, B);
|
||||
|
||||
t_fx = L_deposit_l(0);
|
||||
t_fx = 0;
|
||||
n = 0;
|
||||
move16();
|
||||
tmp = add(band_end_HQ[num_env_bands-1], shl(band_end_HQ[num_env_bands-1], 1));
|
||||
exp1 = norm_s(tmp);
|
||||
tmp = div_s(16384, shl(tmp, exp1));/*15 + 14 - exp1*/
|
||||
|
|
@ -290,65 +252,65 @@ Word16 BitAllocF_fx (
|
|||
tmp = shl(tmp, exp2);
|
||||
exp1 = add(29, sub(exp2, exp1));
|
||||
|
||||
FOR ( i = 0; i < N; i++)
|
||||
for ( i = 0; i < N; i++)
|
||||
{
|
||||
L_tmp2 = L_sub(L_mult0(y[i], band_end_HQ[num_env_bands-1]), L_tmp1);
|
||||
Rsubband_w32_fx[i] = L_mult0(extract_l(L_tmp2), Nb[i]);
|
||||
move32();/*Q0*/
|
||||
IF (Rsubband_w32_fx[i] > 0)
|
||||
if (Rsubband_w32_fx[i] > 0)
|
||||
{
|
||||
n = add(n,Nb[i]);
|
||||
Rsubband_w32_fx[i] = Mult_32_16(Rsubband_w32_fx[i], tmp);
|
||||
Rsubband_w32_fx[i] = Mpy_32_16(Rsubband_w32_fx[i], tmp);
|
||||
move32();/*exp1 - 15*/
|
||||
Rsubband_w32_fx[i] = L_shl(Rsubband_w32_fx[i], sub(30, exp1));/*Q15*/
|
||||
|
||||
t_fx = L_add(t_fx, Rsubband_w32_fx[i]);/*Q0*/
|
||||
}
|
||||
ELSE
|
||||
else
|
||||
{
|
||||
Rsubband_w32_fx[i] = L_deposit_l(0);
|
||||
Rsubband_w32_fx[i] = 0;
|
||||
move32();
|
||||
}
|
||||
}
|
||||
}
|
||||
ELSE
|
||||
else
|
||||
{
|
||||
/* Initial bits distribution */
|
||||
L_tmp1 = 0;
|
||||
move16();
|
||||
m_fx = 0;
|
||||
move16();
|
||||
FOR ( i = 0; i < N ; i++)
|
||||
for ( i = 0; i < N ; i++)
|
||||
{
|
||||
L_tmp1 = L_mac0(L_tmp1, Nb[i], y[i]);
|
||||
}
|
||||
L_tmp1 = L_msu0(L_tmp1, fac, B);
|
||||
|
||||
|
||||
t_fx = L_deposit_l(0);
|
||||
t_fx = 0;
|
||||
n = 0;
|
||||
move16();
|
||||
tmp = add(band_end_HQ[N-1], shl(band_end_HQ[N-1], 1));
|
||||
exp1 = norm_s(tmp);
|
||||
tmp = div_s(16384, shl(tmp, exp1));/*15 + 14 - exp1*/
|
||||
exp2 = norm_s(tmp);
|
||||
tmp = shl(tmp, exp2);
|
||||
exp1 = add(29, sub(exp2, exp1));
|
||||
FOR ( i = 0; i < N; i++)
|
||||
for ( i = 0; i < N; i++)
|
||||
{
|
||||
L_tmp2 = L_sub(L_mult0(y[i], band_end_HQ[N-1]), L_tmp1);
|
||||
Rsubband_w32_fx[i] = L_mult0(extract_l(L_tmp2), Nb[i]);
|
||||
move32();/*Q0*/
|
||||
IF (Rsubband_w32_fx[i] > 0)
|
||||
if (Rsubband_w32_fx[i] > 0)
|
||||
{
|
||||
n = add(n,Nb[i]);
|
||||
L_tmp3 = Mult_32_16(Rsubband_w32_fx[i], tmp); /*exp1 - 15*/
|
||||
Rsubband_w32_fx[i] = L_shl(L_tmp3, sub(30, exp1)); /*Q15*/ move32();
|
||||
Rsubband_w32_fx[i] = Mpy_32_16(Rsubband_w32_fx[i], tmp);
|
||||
move32();/*exp1 - 15*/
|
||||
Rsubband_w32_fx[i] = L_shl(Rsubband_w32_fx[i], sub(30, exp1));/*Q15*/
|
||||
|
||||
t_fx = L_add(t_fx, Rsubband_w32_fx[i]);/*Q0*/
|
||||
}
|
||||
ELSE
|
||||
else
|
||||
{
|
||||
Rsubband_w32_fx[i] = L_deposit_l(0);
|
||||
Rsubband_w32_fx[i] = 0;
|
||||
move32();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -363,52 +325,52 @@ Word16 BitAllocF_fx (
|
|||
tmp = div_s(extract_h(L_shl(L_tmp1, exp1)), shl(n, exp2));/*15 + 15 + exp1 - 16 - exp2*/
|
||||
m_fx = shl(tmp, sub(exp2, exp1));/*Q14*/
|
||||
|
||||
t_fx = L_deposit_l(0);
|
||||
t_fx = 0;
|
||||
n = 0;
|
||||
move16();
|
||||
FOR ( i = 0; i < N; i++)
|
||||
for ( i = 0; i < N; i++)
|
||||
{
|
||||
IF (Rsubband_w32_fx[i] > 0)
|
||||
if (Rsubband_w32_fx[i] > 0)
|
||||
{
|
||||
Rsubband_w32_fx[i] = L_msu(Rsubband_w32_fx[i], m_fx, Nb[i]);
|
||||
move32();
|
||||
|
||||
IF (Rsubband_w32_fx[i] > 0)
|
||||
if (Rsubband_w32_fx[i] > 0)
|
||||
{
|
||||
n = add(n,Nb[i]);
|
||||
|
||||
t_fx = L_add(t_fx, Rsubband_w32_fx[i]);
|
||||
}
|
||||
ELSE
|
||||
else
|
||||
{
|
||||
Rsubband_w32_fx[i] = L_deposit_l(0);
|
||||
Rsubband_w32_fx[i] = 0;
|
||||
move32();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Bits = B;
|
||||
move16();
|
||||
|
||||
/* Impose bit-constraints to subbands with less than minimum bits*/
|
||||
t_fx = L_deposit_l(0);
|
||||
t_fx = 0;
|
||||
n = 0;
|
||||
move16();
|
||||
FOR ( i = 0; i < N; i++)
|
||||
for ( i = 0; i < N; i++)
|
||||
{
|
||||
IF (Rsubband_w32_fx[i] > 0)
|
||||
if (Rsubband_w32_fx[i] > 0)
|
||||
{
|
||||
test();
|
||||
IF ((L_sub(Rsubband_w32_fx[i] , L_shl(add(bs, LNb[i]), 15)) <0) && (sub(low_rate,1) == 0))
|
||||
test();
|
||||
if ((L_sub(Rsubband_w32_fx[i] , L_shl(add(bs, LNb[i]), 15)) <0) && (sub(low_rate,1) == 0))
|
||||
{
|
||||
Rsubband_w32_fx[i] = L_deposit_l(0);
|
||||
Rsubband_w32_fx[i] = 0;
|
||||
move32();
|
||||
}
|
||||
ELSE IF ( L_sub(Rsubband_w32_fx[i] , L_shl(Nb[i], 15)) <=0)
|
||||
else if ( L_sub(Rsubband_w32_fx[i] , L_shl(Nb[i], 15)) <=0)
|
||||
{
|
||||
B = sub(B,Nb[i]);
|
||||
Rsubband_w32_fx[i] = L_shl(Nb[i], 15);
|
||||
move32();
|
||||
}
|
||||
ELSE
|
||||
else
|
||||
{
|
||||
n = add(n,Nb[i]);
|
||||
t_fx = L_add(t_fx, Rsubband_w32_fx[i]);
|
||||
|
|
@ -422,7 +384,7 @@ Word16 BitAllocF_fx (
|
|||
L_tmp1 = L_sub(t_fx, L_shl(B, 15));
|
||||
L_tmp2 = L_abs(L_tmp1);
|
||||
|
||||
if (n>0)
|
||||
if( n>0 )
|
||||
{
|
||||
exp1 = sub(norm_l(L_tmp2), 1);
|
||||
exp2 = norm_s(n);
|
||||
|
|
@ -433,22 +395,20 @@ Word16 BitAllocF_fx (
|
|||
m_fx = negate(m_fx);
|
||||
}
|
||||
|
||||
t_fx = L_deposit_l(0);
|
||||
t_fx = 0;
|
||||
n = 0;
|
||||
move16();
|
||||
FOR( i = 0; i < N; i++)
|
||||
for( i = 0; i < N; i++)
|
||||
{
|
||||
IF (L_sub(Rsubband_w32_fx[i] , L_shl(Nb[i], 15)) > 0)
|
||||
if (L_sub(Rsubband_w32_fx[i] , L_shl(Nb[i], 15)) > 0)
|
||||
{
|
||||
Rsubband_w32_fx[i] = L_msu(Rsubband_w32_fx[i], m_fx, Nb[i]);
|
||||
move32();
|
||||
IF (L_sub(Rsubband_w32_fx[i] ,L_shl(Nb[i], 15)) > 0)
|
||||
if (L_sub(Rsubband_w32_fx[i] ,L_shl(Nb[i], 15)) > 0)
|
||||
{
|
||||
n = add(n,Nb[i]);
|
||||
|
||||
t_fx = L_add(t_fx, Rsubband_w32_fx[i]);
|
||||
}
|
||||
ELSE
|
||||
else
|
||||
{
|
||||
B = sub(B,Nb[i]);
|
||||
|
||||
|
|
@ -459,15 +419,16 @@ Word16 BitAllocF_fx (
|
|||
}
|
||||
}
|
||||
/*In case no subband has enough bits more than 1-bit per sample, take bits off the higher subbands */
|
||||
IF (t_fx == 0)
|
||||
if (t_fx == 0)
|
||||
{
|
||||
FOR ( i = N-1; i >= 0; i--)
|
||||
for ( i = N-1; i >= 0; i--)
|
||||
{
|
||||
IF (Rsubband_w32_fx[i] > 0)
|
||||
if (Rsubband_w32_fx[i] > 0)
|
||||
{
|
||||
B = add( B, Nb[i] );
|
||||
Rsubband_w32_fx[i] = L_deposit_l(0);
|
||||
IF ( B >= 0)
|
||||
Rsubband_w32_fx[i] = 0;
|
||||
move32();
|
||||
if ( B >= 0)
|
||||
{
|
||||
BREAK;
|
||||
}
|
||||
|
|
@ -479,60 +440,56 @@ Word16 BitAllocF_fx (
|
|||
|
||||
/* fine redistribution of over-allocated or under-allocated bits */
|
||||
tmp = 0;
|
||||
move16();
|
||||
FOR ( i = 0; i < N; i++)
|
||||
for ( i = 0; i < N; i++)
|
||||
{
|
||||
Rsubband_fx[i] = extract_l(L_shr(Rsubband_w32_fx[i], 12));
|
||||
tmp = add(tmp, Rsubband_fx[i]);
|
||||
Rsubband[i] = extract_l(L_shr(Rsubband_w32_fx[i], 12));
|
||||
tmp = add(tmp, Rsubband[i]);
|
||||
}
|
||||
|
||||
B = Bits;
|
||||
B_w16_fx = shl(B, 3);
|
||||
IF (sub(tmp ,B_w16_fx)>0)
|
||||
if (sub(tmp ,B_w16_fx)>0)
|
||||
{
|
||||
tmp = sub(tmp, B_w16_fx);
|
||||
FOR ( i = 0; i < N; i++)
|
||||
for ( i = 0; i < N; i++)
|
||||
{
|
||||
IF (sub(Rsubband_fx[i], add(shl(Nb[i], 3), tmp)) >= 0)
|
||||
if (sub(Rsubband[i], add(shl(Nb[i], 3), tmp)) >= 0)
|
||||
{
|
||||
Rsubband_fx[i] = sub(Rsubband_fx[i], tmp);
|
||||
move16();
|
||||
Rsubband[i] = sub(Rsubband[i], tmp);
|
||||
BREAK;
|
||||
}
|
||||
}
|
||||
}
|
||||
ELSE
|
||||
else
|
||||
{
|
||||
tmp = sub(tmp, B_w16_fx);
|
||||
FOR ( i = 0; i < N; i++)
|
||||
for ( i = 0; i < N; i++)
|
||||
{
|
||||
IF (Rsubband_fx[i] > 0)
|
||||
if (Rsubband[i] > 0)
|
||||
{
|
||||
Rsubband_fx[i] = sub(Rsubband_fx[i], tmp);
|
||||
move16();
|
||||
Rsubband[i] = sub(Rsubband[i], tmp);
|
||||
BREAK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Calcuate total used bits and initialize R to be used for Noise Filling */
|
||||
/* Calculate total used bits and initialize R to be used for Noise Filling */
|
||||
tmp = 0;
|
||||
move16();
|
||||
FOR ( i = 0; i < N; i++)
|
||||
for ( i = 0; i < N; i++)
|
||||
{
|
||||
tmp = add(tmp, Rsubband_fx[i]);
|
||||
R[i] = shr(Rsubband_fx[i], 3);
|
||||
move16();
|
||||
tmp = add(tmp, Rsubband[i]);
|
||||
R[i] = shr(Rsubband[i], 3);
|
||||
}
|
||||
|
||||
return shr(tmp, 3);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------*
|
||||
* Bit_group()
|
||||
*
|
||||
* bit allocation in group
|
||||
*-------------------------------------------------------------------*/
|
||||
static
|
||||
void Bit_group_fx (
|
||||
static void Bit_group_fx (
|
||||
Word16 *y, /* i : norm of sub-band Q0*/
|
||||
Word16 start_band, /* i : start band indices Q0*/
|
||||
Word16 end_band, /* i : end band indices Q0*/
|
||||
|
|
@ -547,21 +504,22 @@ void Bit_group_fx (
|
|||
Word16 factor_fx;
|
||||
Word32 R_temp_fx[16], R_sum_fx = 0, R_sum_org_fx = 0, Bits_avg_fx = 0;
|
||||
Word32 L_tmp;
|
||||
UWord32 lo;
|
||||
|
||||
/* initialization for bit allocation in one group*/
|
||||
tmp = 6554;
|
||||
move16(); /*Q15 1/5 */
|
||||
if(sub(thr,5) == 0)
|
||||
IF(sub(thr,5) == 0)
|
||||
{
|
||||
tmp = 6554;
|
||||
move16(); /*Q15 1/5 */
|
||||
}
|
||||
if(sub(thr,6) == 0)
|
||||
IF(sub(thr,6) == 0)
|
||||
{
|
||||
tmp = 5462;
|
||||
move16();/*Q15 1/6 */
|
||||
}
|
||||
if(sub(thr,7) == 0)
|
||||
IF(sub(thr,7) == 0)
|
||||
{
|
||||
tmp = 4682;
|
||||
move16();/*Q15 1/7 */
|
||||
|
|
@ -578,7 +536,7 @@ void Bit_group_fx (
|
|||
}
|
||||
|
||||
/* Rearrange norm vector in decreasing order */
|
||||
reordvct_fx(y_index, band_num, index);
|
||||
reordvct(y_index, band_num, index);
|
||||
/* norm vector modification */
|
||||
|
||||
factor_fx = div_s(1, band_num);/*Q15 */
|
||||
|
|
@ -612,7 +570,7 @@ void Bit_group_fx (
|
|||
{
|
||||
FOR ( j = 0; j < band_num; j++)
|
||||
{
|
||||
if ( y_index[j] < 0 )
|
||||
IF ( y_index[j] < 0 )
|
||||
{
|
||||
y_index[j] = 0;
|
||||
move16();
|
||||
|
|
@ -634,7 +592,8 @@ void Bit_group_fx (
|
|||
{
|
||||
FOR (k = 0; k <= i; k++)
|
||||
{
|
||||
R_temp_fx[k] = L_deposit_h(0);/*Q21 */
|
||||
R_temp_fx[k] = 0;
|
||||
move32();/*Q21 */
|
||||
}
|
||||
}
|
||||
ELSE
|
||||
|
|
@ -647,7 +606,7 @@ void Bit_group_fx (
|
|||
FOR (k = 0; k <= i; k++)
|
||||
{
|
||||
L_tmp = L_shl(L_deposit_l(y_index[k]),24);
|
||||
L_tmp = Mult_32_32(Bits_avg_fx,L_tmp);/*Q(23-exp) */
|
||||
Mpy_32_32_ss(Bits_avg_fx,L_tmp,&L_tmp,&lo);
|
||||
|
||||
R_temp_fx[k] = L_shl(L_tmp,sub(exp,2));
|
||||
move32();/*Q21 */
|
||||
|
|
@ -657,7 +616,8 @@ void Bit_group_fx (
|
|||
L_tmp = L_shl(L_deposit_l(thr),21);/*Q21 */
|
||||
IF ( L_sub(R_temp_fx[i],L_tmp) < 0 )
|
||||
{
|
||||
R_temp_fx[i] = L_deposit_h(0);
|
||||
R_temp_fx[i] = 0;
|
||||
move32();
|
||||
norm_sum = sub(norm_sum,y_index[i]);
|
||||
i--;
|
||||
}
|
||||
|
|
@ -671,7 +631,7 @@ void Bit_group_fx (
|
|||
{
|
||||
FOR ( j = 0; j < bit_band; j++ )
|
||||
{
|
||||
if ( y_index[j] < 0 )
|
||||
IF ( y_index[j] < 0 )
|
||||
{
|
||||
y_index[j] = 0;
|
||||
move16();
|
||||
|
|
@ -682,7 +642,8 @@ void Bit_group_fx (
|
|||
|
||||
FOR ( j = bit_band; j < band_num; j++ )
|
||||
{
|
||||
R_temp_fx[j] = L_deposit_l(0);
|
||||
R_temp_fx[j] = 0;
|
||||
move32();
|
||||
}
|
||||
|
||||
norm_sum = 0;
|
||||
|
|
@ -698,7 +659,8 @@ void Bit_group_fx (
|
|||
{
|
||||
FOR (k = 0; k < i; k++)
|
||||
{
|
||||
R_temp_fx[k] = L_deposit_l(0); /*Q21 */
|
||||
R_temp_fx[k] = 0;
|
||||
move32();/*Q21 */
|
||||
}
|
||||
}
|
||||
ELSE
|
||||
|
|
@ -710,8 +672,7 @@ void Bit_group_fx (
|
|||
FOR (k = 0; k < i; k++)
|
||||
{
|
||||
L_tmp = L_shl(L_deposit_l(y_index[k]),24);
|
||||
L_tmp = Mult_32_32(Bits_avg_fx,L_tmp);/*Q(23-exp) */
|
||||
|
||||
Mpy_32_32_ss(Bits_avg_fx,L_tmp,&L_tmp,&lo);
|
||||
R_temp_fx[k] = L_shl(L_tmp,sub(exp,2));
|
||||
move32();/*Q21 */
|
||||
}
|
||||
|
|
@ -725,7 +686,8 @@ void Bit_group_fx (
|
|||
FOR(m = k; m < i; m++)
|
||||
{
|
||||
norm_sum = sub(norm_sum,y_index[m]);
|
||||
R_temp_fx[m] = L_deposit_l(0); /*Q21 */
|
||||
R_temp_fx[m] = 0;
|
||||
move32();/*Q21 */
|
||||
}
|
||||
i = k;
|
||||
BREAK;
|
||||
|
|
@ -763,12 +725,12 @@ void Bit_group_fx (
|
|||
* WB bit allocation
|
||||
*-------------------------------------------------------------------*/
|
||||
|
||||
Word16 BitAllocWB_fx( /* o : t Q0*/
|
||||
Word16 *y, /* i : norm of sub-vectors Q0*/
|
||||
Word16 B, /* i : number of available bits Q0*/
|
||||
Word16 N, /* i : number of sub-vectors Q0*/
|
||||
Word16 *R, /* o : bit-allocation indicator Q0*/
|
||||
Word16 *Rsubband_fx /* o : sub-band bit-allocation vector Q3*/
|
||||
short BitAllocWB (
|
||||
short *y, /* i : norm of sub-vectors */
|
||||
short B, /* i : number of available bits */
|
||||
short N, /* i : number of sub-vectors */
|
||||
short *R, /* o : bit-allocation indicator */
|
||||
short *Rsubband /* o : sub-band bit-allocation vector (Q3) */
|
||||
)
|
||||
{
|
||||
Word16 t_fx;
|
||||
|
|
@ -778,13 +740,13 @@ Word16 BitAllocWB_fx( /* o : t
|
|||
Word16 factor_fx[2];/*Q13 */
|
||||
Word16 BANDS;
|
||||
Word16 tmp,exp;
|
||||
Word16 Rsum_sub_fx_tmp=0; /* initialize just to avoid compiler warning */
|
||||
Word32 L_tmp,L_tmp1;
|
||||
Word32 Rsubband_buf[NB_SFM];
|
||||
UWord16 lo;
|
||||
|
||||
BANDS = N;
|
||||
move16();
|
||||
if( sub(BANDS,SFM_N) > 0)
|
||||
IF( sub(BANDS,SFM_N) > 0)
|
||||
{
|
||||
BANDS = SFM_N;
|
||||
move16();
|
||||
|
|
@ -797,49 +759,36 @@ Word16 BitAllocWB_fx( /* o : t
|
|||
}
|
||||
/* Calculate the norm sum and average of sub-band */
|
||||
Rsum_sub_fx[0] = 0;
|
||||
move16();
|
||||
FOR ( j = 0; j < SFM_G1; j++ )
|
||||
{
|
||||
if ( y[j] > 0 )
|
||||
IF ( y[j] > 0 )
|
||||
{
|
||||
Rsum_sub_fx_tmp = add(Rsum_sub_fx[0],y[j]); /*Q0 */
|
||||
}
|
||||
if (y[j] > 0)
|
||||
{
|
||||
Rsum_sub_fx[0] = Rsum_sub_fx_tmp;
|
||||
move16(); /*Q0 */
|
||||
}
|
||||
}
|
||||
Ravg_sub_32_fx[0] = L_mult(Rsum_sub_fx[0], 2048);
|
||||
move32();/*Q16 0+15+1 //q15 1/16 =2048 */
|
||||
|
||||
Rsum_sub_fx[1] = 0;
|
||||
move16();
|
||||
FOR ( j = SFM_G1; j < SFM_G1G2; j++ )
|
||||
{
|
||||
if ( y[j] > 0 )
|
||||
{
|
||||
Rsum_sub_fx_tmp = add(Rsum_sub_fx[1],y[j]); /*Q0 */
|
||||
}
|
||||
if ( y[j] > 0 )
|
||||
{
|
||||
Rsum_sub_fx[1] = Rsum_sub_fx_tmp;
|
||||
Rsum_sub_fx[0] = add(Rsum_sub_fx[0],y[j]);
|
||||
move16();/*Q0 */
|
||||
}
|
||||
}
|
||||
Ravg_sub_32_fx[1] = L_mult(Rsum_sub_fx[1], 4096); /*16 0+15+1 //q15 1/8 =4096 */
|
||||
Ravg_sub_32_fx[0] = L_mult(Rsum_sub_fx[0], 2048);
|
||||
move32();/*Q16 0+15+1 , q15 1/16 =2048 */
|
||||
|
||||
Rsum_sub_fx[1] = 0;
|
||||
move32();
|
||||
FOR ( j = SFM_G1; j < SFM_G1G2; j++ )
|
||||
{
|
||||
IF ( y[j] > 0 )
|
||||
{
|
||||
Rsum_sub_fx[1] = add(Rsum_sub_fx[1],y[j]);
|
||||
move16();/*Q0 */
|
||||
}
|
||||
}
|
||||
Ravg_sub_32_fx[1] = L_mult(Rsum_sub_fx[1], 4096); /*16 0+15+1 , q15 1/8 =4096 */
|
||||
|
||||
Rsum_sub_fx[2] = 0;
|
||||
move16();
|
||||
FOR ( j = SFM_G1G2; j < BANDS; j++ )
|
||||
{
|
||||
if ( y[j] > 0 )
|
||||
IF ( y[j] > 0 )
|
||||
{
|
||||
Rsum_sub_fx_tmp = add(Rsum_sub_fx[2],y[j]); /*Q0 */
|
||||
}
|
||||
if ( y[j] > 0 )
|
||||
{
|
||||
Rsum_sub_fx[2] = Rsum_sub_fx_tmp;
|
||||
Rsum_sub_fx[2] = add(Rsum_sub_fx[2],y[j]);
|
||||
move16();/*Q0 */
|
||||
}
|
||||
}
|
||||
|
|
@ -859,7 +808,6 @@ Word16 BitAllocWB_fx( /* o : t
|
|||
R_diff_32_fx[1] = L_sub(Ravg_sub_32_fx[1], Ravg_sub_32_fx[2]);
|
||||
move32();/*Q16 */
|
||||
|
||||
test();
|
||||
IF ( L_sub(R_diff_32_fx[0],393216) < 0 && L_sub(R_diff_32_fx[1],245760) < 0 )
|
||||
{
|
||||
IF(Rsum_fx == 0)
|
||||
|
|
@ -877,26 +825,23 @@ Word16 BitAllocWB_fx( /* o : t
|
|||
tmp = shl(Rsum_fx,exp);/*Q(exp) */
|
||||
tmp = div_s(16384,tmp);/*Q(15+14-exp) */
|
||||
L_tmp1 = L_mult(B,Rsum_sub_fx[0]);/*Q1 */
|
||||
L_tmp = Mult_32_16(L_tmp1,tmp);/*Q(15-exp) */
|
||||
Mpy_32_16_ss(L_tmp1,tmp,&L_tmp,&lo);
|
||||
B1 = extract_h(L_shl(L_tmp,add(exp,1)));/*Q0 */
|
||||
test();
|
||||
if(L_sub(L_tmp1,L_mult(B1,Rsum_fx)) > 0 && L_sub(L_tmp1,L_mult(add(B1,1),Rsum_fx)) >= 0)
|
||||
IF(L_sub(L_tmp1,L_mult(B1,Rsum_fx)) > 0 && L_sub(L_tmp1,L_mult(add(B1,1),Rsum_fx)) >= 0)
|
||||
{
|
||||
B1 = add(B1,1);
|
||||
}
|
||||
L_tmp1 = L_mult(B,Rsum_sub_fx[1]);/*Q1 */
|
||||
L_tmp = Mult_32_16(L_tmp1,tmp);/*Q(15-exp) */
|
||||
Mpy_32_16_ss(L_tmp1,tmp,&L_tmp,&lo);
|
||||
B2 = extract_h(L_shl(L_tmp,add(exp,1)));/*Q0 */
|
||||
test();
|
||||
if(L_sub(L_tmp1,L_mult(B2,Rsum_fx)) > 0 && L_sub(L_tmp1,L_mult(add(B2,1),Rsum_fx)) >= 0)
|
||||
IF(L_sub(L_tmp1,L_mult(B2,Rsum_fx)) > 0 && L_sub(L_tmp1,L_mult(add(B2,1),Rsum_fx)) >= 0)
|
||||
{
|
||||
B2 = add(B2,1);
|
||||
}
|
||||
L_tmp1 = L_mult(B,Rsum_sub_fx[2]);/*Q1 */
|
||||
L_tmp = Mult_32_16(L_tmp1,tmp);/*Q(15-exp) */
|
||||
Mpy_32_16_ss(L_tmp1,tmp,&L_tmp,&lo);
|
||||
B3 = extract_h(L_shl(L_tmp,add(exp,1)));/*Q0 */
|
||||
test();
|
||||
if(L_sub(L_tmp1,L_mult(B3,Rsum_fx)) > 0 && L_sub(L_tmp1,L_mult(add(B3,1),Rsum_fx)) >= 0)
|
||||
IF(L_sub(L_tmp1,L_mult(B3,Rsum_fx)) > 0 && L_sub(L_tmp1,L_mult(add(B3,1),Rsum_fx)) >= 0)
|
||||
{
|
||||
B3 = add(B3,1);
|
||||
}
|
||||
|
|
@ -977,19 +922,17 @@ Word16 BitAllocWB_fx( /* o : t
|
|||
tmp = shl(Rsum_fx,exp);/*Q(exp) */
|
||||
tmp = div_s(16384,tmp);/*Q(15+14-exp) */
|
||||
L_tmp1 = L_mult(B,Rsum_sub_fx[0]);/*Q1 */
|
||||
L_tmp = Mult_32_16(L_tmp1,tmp);/*Q(15-exp) */
|
||||
Mpy_32_16_ss(L_tmp1,tmp,&L_tmp,&lo);
|
||||
B1 = extract_h(L_shl(L_tmp,add(exp,1)));/*Q0 */
|
||||
test();
|
||||
if(L_sub(L_tmp1,L_mult(B1,Rsum_fx)) > 0 && L_sub(L_tmp1,L_mult(add(B1,1),Rsum_fx)) >= 0)
|
||||
IF(L_sub(L_tmp1,L_mult(B1,Rsum_fx)) > 0 && L_sub(L_tmp1,L_mult(add(B1,1),Rsum_fx)) >= 0)
|
||||
{
|
||||
B1 = add(B1,1);
|
||||
}
|
||||
L_tmp1 = Mult_32_16(1975684956,shl(B,5));/*Q(31+5-15=21) */
|
||||
L_tmp1 = Mult_32_16(L_tmp1,shl(Rsum_sub_fx[1],7));/*Q(21+7-15=13) */
|
||||
L_tmp = Mult_32_16(L_tmp1,tmp);/*Q(27-exp) */
|
||||
Mpy_32_16_ss(1975684956,shl(B,5),&L_tmp1,&lo);
|
||||
Mpy_32_16_ss(L_tmp1,shl(Rsum_sub_fx[1],7),&L_tmp1,&lo);
|
||||
Mpy_32_16_ss(L_tmp1,tmp,&L_tmp,&lo);
|
||||
B2 = extract_h(L_shl(L_tmp,sub(exp,11)));/*Q0 */
|
||||
test();
|
||||
if(L_sub(L_tmp1,L_shl(L_mult(B2,Rsum_fx),12)) > 0 && L_sub(L_add(L_tmp1,2),L_shl(L_mult(add(B2,1),Rsum_fx),12)) >= 0)
|
||||
IF(L_sub(L_tmp1,L_shl(L_mult(B2,Rsum_fx),12)) > 0 && L_sub(L_add(L_tmp1,2),L_shl(L_mult(add(B2,1),Rsum_fx),12)) >= 0)
|
||||
{
|
||||
B2 = add(B2,1);
|
||||
}
|
||||
|
|
@ -1012,11 +955,13 @@ Word16 BitAllocWB_fx( /* o : t
|
|||
Bit_group_fx( y, SFM_G1G2, BANDS, B3, 7, Rsubband_buf, factor_fx);
|
||||
FOR (i = 0; i < BANDS; i++)
|
||||
{
|
||||
Rsubband_fx[i] = extract_l(L_shr(Rsubband_buf[i], 18));
|
||||
Rsubband[i] = extract_l(L_shr(Rsubband_buf[i], 18));
|
||||
move16();
|
||||
}
|
||||
|
||||
/* Calcuate total used bits and initialize R to be used for Noise Filling */
|
||||
L_tmp = L_deposit_l(0);
|
||||
L_tmp = 0;
|
||||
move32();
|
||||
FOR( i = 0; i < N; i++)
|
||||
{
|
||||
L_tmp = L_add(L_tmp,Rsubband_buf[i]);/*Q21 */
|
||||
|
|
@ -1025,5 +970,4 @@ Word16 BitAllocWB_fx( /* o : t
|
|||
t_fx = extract_h(L_shr(L_tmp, 5)); /*Q0 */
|
||||
|
||||
return (Word16)t_fx;
|
||||
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -1,384 +1,308 @@
|
|||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
EVS Codec 3GPP TS26.443 Nov 13, 2018. Version 12.11.0 / 13.7.0 / 14.3.0 / 15.1.0
|
||||
====================================================================================*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <assert.h>
|
||||
#include "options.h"
|
||||
#include "prot_fx.h"
|
||||
#include "basop_util.h"
|
||||
#include "stl.h"
|
||||
#include "options.h"
|
||||
#include "rom_com_fx.h"
|
||||
#include "rom_com.h"
|
||||
#include "prot.h"
|
||||
|
||||
/*-------------------------------------------------------------------*
|
||||
* Local function
|
||||
*--------------------------------------------------------------------*/
|
||||
|
||||
static int BITS_ALLOC_adjust_acelp_fixed_cdk( int bits_frame, int *fixed_cdk_index, int nb_subfr );
|
||||
|
||||
|
||||
/*
|
||||
* function BITS_ALLOC_init_config_acelp()
|
||||
*
|
||||
* description: initial configuration for ACELP
|
||||
*
|
||||
* return: void
|
||||
*/
|
||||
/*-------------------------------------------------------------------*
|
||||
* BITS_ALLOC_init_config_acelp()
|
||||
*
|
||||
* initial configuration for Mode 2 ACELP
|
||||
*--------------------------------------------------------------------*/
|
||||
|
||||
void BITS_ALLOC_init_config_acelp(
|
||||
const Word32 bit_rate,
|
||||
const Word8 narrowBand,
|
||||
const Word16 nb_subfr,
|
||||
ACELP_config *pConfigAcelp /*o: configuration structure of ACELP*/
|
||||
int bit_rate,
|
||||
int narrowBand,
|
||||
int nb_subfr,
|
||||
ACELP_config *acelp_cfg /*o: configuration structure of ACELP*/
|
||||
)
|
||||
{
|
||||
Word8 rate_mode_index;
|
||||
short rate_mode_index;
|
||||
|
||||
if( bit_rate <= ACELP_9k60 )
|
||||
{
|
||||
rate_mode_index=0;
|
||||
}
|
||||
else
|
||||
{
|
||||
rate_mode_index=1;
|
||||
}
|
||||
|
||||
move16();
|
||||
move16();
|
||||
move16();
|
||||
rate_mode_index=(bit_rate > ACELP_9k60);
|
||||
|
||||
pConfigAcelp->mode_index=rate_mode_index;
|
||||
|
||||
acelp_cfg->mode_index=rate_mode_index;
|
||||
|
||||
/*LPC: midLpc should be swithced off?*/
|
||||
pConfigAcelp->midLpc_enable = 1;
|
||||
move16();
|
||||
acelp_cfg->midLpc_enable = 1;
|
||||
|
||||
/*ACELP ICB config*/
|
||||
test();
|
||||
IF( (rate_mode_index==0) || narrowBand != 0 )
|
||||
if( (rate_mode_index==0) || (narrowBand==1) )
|
||||
{
|
||||
move16();
|
||||
move16();
|
||||
move16();
|
||||
move16();
|
||||
move16();
|
||||
move16();
|
||||
pConfigAcelp->pre_emphasis = 1;
|
||||
pConfigAcelp->formant_enh = 1;
|
||||
pConfigAcelp->formant_enh_num = FORMANT_SHARPENING_G1;
|
||||
pConfigAcelp->formant_enh_den = FORMANT_SHARPENING_G2;
|
||||
pConfigAcelp->formant_tilt = 0;
|
||||
pConfigAcelp->voice_tilt = 0;
|
||||
acelp_cfg->pre_emphasis = 1;
|
||||
acelp_cfg->formant_enh = 1;
|
||||
acelp_cfg->formant_enh_num = FORMANT_SHARPENING_G1;
|
||||
acelp_cfg->formant_enh_den = FORMANT_SHARPENING_G2;
|
||||
acelp_cfg->formant_tilt = 0;
|
||||
acelp_cfg->voice_tilt = 0;
|
||||
}
|
||||
ELSE
|
||||
else
|
||||
{
|
||||
move16();
|
||||
move16();
|
||||
move16();
|
||||
move16();
|
||||
move16();
|
||||
move16();
|
||||
pConfigAcelp->pre_emphasis = 0;
|
||||
pConfigAcelp->formant_enh = 1;
|
||||
pConfigAcelp->formant_enh_num = FORMANT_SHARPENING_G1;
|
||||
pConfigAcelp->formant_enh_den = FORMANT_SHARPENING_G2;
|
||||
pConfigAcelp->formant_tilt = 1;
|
||||
pConfigAcelp->voice_tilt = 1;
|
||||
acelp_cfg->pre_emphasis = 0;
|
||||
acelp_cfg->formant_enh = 1;
|
||||
acelp_cfg->formant_enh_num = FORMANT_SHARPENING_G1;
|
||||
acelp_cfg->formant_enh_den = FORMANT_SHARPENING_G2;
|
||||
acelp_cfg->formant_tilt = 1;
|
||||
acelp_cfg->voice_tilt = 1;
|
||||
}
|
||||
|
||||
/*Wide band @ 16kHz*/
|
||||
IF ( sub(nb_subfr,NB_SUBFR16k) == 0 )
|
||||
if ( nb_subfr == NB_SUBFR16k )
|
||||
{
|
||||
move16();
|
||||
move16();
|
||||
move16();
|
||||
move16();
|
||||
move16();
|
||||
move16();
|
||||
pConfigAcelp->pre_emphasis = 1;
|
||||
pConfigAcelp->formant_enh = 1;
|
||||
pConfigAcelp->formant_enh_num = FORMANT_SHARPENING_G1_16k;
|
||||
pConfigAcelp->formant_enh_den = FORMANT_SHARPENING_G2_16k;
|
||||
pConfigAcelp->formant_tilt = 0;
|
||||
pConfigAcelp->voice_tilt = 2;
|
||||
acelp_cfg->pre_emphasis = 1;
|
||||
acelp_cfg->formant_enh = 1;
|
||||
acelp_cfg->formant_enh_num = FORMANT_SHARPENING_G1_16k;
|
||||
acelp_cfg->formant_enh_den = FORMANT_SHARPENING_G2_16k;
|
||||
acelp_cfg->formant_tilt = 0;
|
||||
acelp_cfg->voice_tilt = 2;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------*
|
||||
* BITS_ALLOC_config_acelp()
|
||||
*
|
||||
* configure all Mode 2 ACELP modes and allocate the bits
|
||||
*--------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* function BITS_ALLOC_config_acelp()
|
||||
*
|
||||
* description: configure all acelp modes and allocate the bits
|
||||
*
|
||||
* return: bit demand
|
||||
*/
|
||||
Word16 BITS_ALLOC_config_acelp(
|
||||
const Word16 bits_frame, /*i: remaining bit budget for the frame*/
|
||||
const Word16 coder_type, /*i: acelp coder type*/
|
||||
ACELP_config *pConfigAcelp, /*i/o: configuration structure of ACELP*/
|
||||
const Word16 narrowBand,
|
||||
const Word16 nb_subfr
|
||||
int BITS_ALLOC_config_acelp(
|
||||
const int bits_frame, /* i : remaining bit budget for the frame */
|
||||
const short coder_type, /* i : acelp extended mode index */
|
||||
ACELP_config *acelp_cfg, /* i/o: configuration structure of ACELP */
|
||||
const short narrowBand, /* i : narrowband flag */
|
||||
const short nb_subfr /* i : number of subframes */
|
||||
)
|
||||
{
|
||||
Word16 mode_index;
|
||||
Word16 band_index;
|
||||
Word16 i;
|
||||
Word16 remaining_bits, bits;
|
||||
short mode_index;
|
||||
short band_index;
|
||||
short i;
|
||||
short remaining_bits, bits;
|
||||
|
||||
/*Sanity check*/
|
||||
|
||||
|
||||
move16();
|
||||
move16();
|
||||
move16();
|
||||
mode_index = pConfigAcelp->mode_index;
|
||||
mode_index = acelp_cfg->mode_index;
|
||||
band_index = (narrowBand==0);
|
||||
bits=0;
|
||||
bits = 0;
|
||||
|
||||
IF ( band_index==0 )
|
||||
if ( band_index==0 )
|
||||
{
|
||||
move16();
|
||||
pConfigAcelp->formant_enh = 1;
|
||||
if(sub(coder_type,INACTIVE) == 0)
|
||||
if(coder_type == INACTIVE)
|
||||
{
|
||||
move16();
|
||||
pConfigAcelp->formant_enh = 0;
|
||||
acelp_cfg->formant_enh = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
acelp_cfg->formant_enh = 1;
|
||||
}
|
||||
}
|
||||
|
||||
IF ( s_and(sub(band_index,1)==0, sub(nb_subfr,4)==0) )
|
||||
if( band_index==1 && nb_subfr == NB_SUBFR )
|
||||
{
|
||||
IF(sub(coder_type,INACTIVE) == 0)
|
||||
|
||||
if( coder_type == INACTIVE)
|
||||
{
|
||||
pConfigAcelp->pre_emphasis = 0;
|
||||
move16();
|
||||
pConfigAcelp->formant_enh = 0;
|
||||
move16();
|
||||
pConfigAcelp->formant_enh_num = FORMANT_SHARPENING_G1_16k;
|
||||
move16();
|
||||
pConfigAcelp->voice_tilt = 1;
|
||||
move16();
|
||||
pConfigAcelp->formant_tilt = 1;
|
||||
move16();
|
||||
acelp_cfg->pre_emphasis = 0;
|
||||
acelp_cfg->formant_enh = 0;
|
||||
acelp_cfg->formant_enh_num = FORMANT_SHARPENING_G1_16k;
|
||||
acelp_cfg->formant_tilt = 1;
|
||||
acelp_cfg->voice_tilt = 1;
|
||||
}
|
||||
ELSE
|
||||
else
|
||||
{
|
||||
pConfigAcelp->pre_emphasis = 1;
|
||||
move16();
|
||||
pConfigAcelp->formant_enh = 1;
|
||||
move16();
|
||||
pConfigAcelp->formant_enh_num = FORMANT_SHARPENING_G1;
|
||||
move16();
|
||||
pConfigAcelp->voice_tilt = 0;
|
||||
move16();
|
||||
pConfigAcelp->formant_tilt = 0;
|
||||
move16();
|
||||
acelp_cfg->pre_emphasis = 1;
|
||||
acelp_cfg->formant_enh = 1;
|
||||
acelp_cfg->formant_enh_num = FORMANT_SHARPENING_G1;
|
||||
acelp_cfg->formant_tilt = 0;
|
||||
acelp_cfg->voice_tilt = 0;
|
||||
}
|
||||
}
|
||||
IF (sub(coder_type,UNVOICED) == 0 )
|
||||
{
|
||||
IF(sub(ACELP_GAINS_MODE[mode_index][band_index][coder_type], 6) == 0)
|
||||
{
|
||||
pConfigAcelp->pitch_sharpening = 0;
|
||||
move16();
|
||||
pConfigAcelp->phase_scrambling = 1;
|
||||
move16();
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
pConfigAcelp->pitch_sharpening = 0;
|
||||
move16();
|
||||
pConfigAcelp->phase_scrambling = 0;
|
||||
move16();
|
||||
}
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
pConfigAcelp->pitch_sharpening = 1;
|
||||
move16();
|
||||
pConfigAcelp->phase_scrambling = 0;
|
||||
move16();
|
||||
}
|
||||
|
||||
IF(sub(coder_type,ACELP_MODE_MAX) > 0) /* keep pitch sharpening for RF_ALLPRED mode */
|
||||
if( coder_type == UNVOICED )
|
||||
{
|
||||
pConfigAcelp->pitch_sharpening = 0;
|
||||
pConfigAcelp->phase_scrambling = 0;
|
||||
if( ACELP_GAINS_MODE[mode_index][band_index][coder_type]==6 )
|
||||
{
|
||||
acelp_cfg->pitch_sharpening = 0;
|
||||
acelp_cfg->phase_scrambling = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
acelp_cfg->pitch_sharpening = 0;
|
||||
acelp_cfg->phase_scrambling = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
acelp_cfg->pitch_sharpening = 1;
|
||||
acelp_cfg->phase_scrambling = 0;
|
||||
}
|
||||
|
||||
if( coder_type > ACELP_MODE_MAX )
|
||||
{
|
||||
/* keep pitch sharpening for RF_ALLPRED mode */
|
||||
acelp_cfg->pitch_sharpening = 0;
|
||||
acelp_cfg->phase_scrambling = 0;
|
||||
}
|
||||
|
||||
/*Allocate bits and different modes*/
|
||||
move16();
|
||||
pConfigAcelp->bpf_mode=ACELP_BPF_MODE[mode_index][band_index][coder_type];
|
||||
bits = add(bits, ACELP_BPF_BITS[pConfigAcelp->bpf_mode]);
|
||||
acelp_cfg->bpf_mode=ACELP_BPF_MODE[mode_index][band_index][coder_type];
|
||||
bits+=ACELP_BPF_BITS[acelp_cfg->bpf_mode];
|
||||
|
||||
move16();
|
||||
move16();
|
||||
pConfigAcelp->nrg_mode=ACELP_NRG_MODE[mode_index][band_index][coder_type];
|
||||
pConfigAcelp->nrg_bits=ACELP_NRG_BITS[pConfigAcelp->nrg_mode];
|
||||
bits = add(bits, pConfigAcelp->nrg_bits);
|
||||
acelp_cfg->nrg_mode=ACELP_NRG_MODE[mode_index][band_index][coder_type];
|
||||
acelp_cfg->nrg_bits=ACELP_NRG_BITS[acelp_cfg->nrg_mode];
|
||||
bits+=acelp_cfg->nrg_bits;
|
||||
|
||||
move16();
|
||||
pConfigAcelp->ltp_mode=ACELP_LTP_MODE[mode_index][band_index][coder_type];
|
||||
acelp_cfg->ltp_mode=ACELP_LTP_MODE[mode_index][band_index][coder_type];
|
||||
acelp_cfg->ltp_bits=0;
|
||||
acelp_cfg->ltf_mode=ACELP_LTF_MODE[mode_index][band_index][coder_type];
|
||||
acelp_cfg->ltf_bits=ACELP_LTF_BITS[acelp_cfg->ltf_mode];
|
||||
|
||||
move16();
|
||||
pConfigAcelp->ltp_bits=0;
|
||||
|
||||
move16();
|
||||
pConfigAcelp->ltf_mode=ACELP_LTF_MODE[mode_index][band_index][coder_type];
|
||||
|
||||
move16();
|
||||
pConfigAcelp->ltf_bits=ACELP_LTF_BITS[pConfigAcelp->ltf_mode];
|
||||
if ( s_and(sub(nb_subfr,5)==0, sub(pConfigAcelp->ltf_bits,4)==0) )
|
||||
if( nb_subfr == NB_SUBFR16k && acelp_cfg->ltf_bits == 4 )
|
||||
{
|
||||
pConfigAcelp->ltf_bits = add(pConfigAcelp->ltf_bits,1);
|
||||
acelp_cfg->ltf_bits++;
|
||||
}
|
||||
bits = add(bits,pConfigAcelp->ltf_bits);
|
||||
bits+=acelp_cfg->ltf_bits;
|
||||
|
||||
|
||||
FOR ( i=0; i<nb_subfr; i++ )
|
||||
for ( i=0; i<nb_subfr; i++ )
|
||||
{
|
||||
pConfigAcelp->gains_mode[i] = ACELP_GAINS_MODE[mode_index][band_index][coder_type];
|
||||
move16();
|
||||
acelp_cfg->gains_mode[i] = ACELP_GAINS_MODE[mode_index][band_index][coder_type];
|
||||
|
||||
/* skip subframe 1, 3 gain encoding, and use from subframe 0, and 3, respectively */
|
||||
test();
|
||||
test();
|
||||
IF(sub(coder_type,ACELP_MODE_MAX) >= 0 && (sub(i,1) == 0 || sub(i,3) == 0))
|
||||
if(coder_type >= ACELP_MODE_MAX && (i == 1 || i == 3))
|
||||
{
|
||||
pConfigAcelp->gains_mode[i] = 0;
|
||||
acelp_cfg->gains_mode[i] = 0;
|
||||
}
|
||||
|
||||
bits = add(bits, ACELP_GAINS_BITS[pConfigAcelp->gains_mode[i]]);
|
||||
|
||||
move16();
|
||||
bits = add(bits, ACELP_LTP_BITS_SFR[pConfigAcelp->ltp_mode][i]);
|
||||
pConfigAcelp->ltp_bits= add( pConfigAcelp->ltp_bits,ACELP_LTP_BITS_SFR[pConfigAcelp->ltp_mode][i]);
|
||||
bits += ACELP_GAINS_BITS[acelp_cfg->gains_mode[i]];
|
||||
bits += ACELP_LTP_BITS_SFR[acelp_cfg->ltp_mode][i];
|
||||
acelp_cfg->ltp_bits += ACELP_LTP_BITS_SFR[acelp_cfg->ltp_mode][i];
|
||||
}
|
||||
|
||||
/*Innovation*/
|
||||
|
||||
if ( sub(bits_frame,bits) < 0)
|
||||
if( bits_frame < bits )
|
||||
{
|
||||
printf("Warning: bits per frame too low\n");
|
||||
printf("\nWarning: bits per frame too low\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
IF( sub(coder_type,RF_ALLPRED) == 0 )
|
||||
if( coder_type == RF_ALLPRED )
|
||||
{
|
||||
set16_fx(pConfigAcelp->fixed_cdk_index, -1, nb_subfr);
|
||||
set_i(acelp_cfg->fixed_cdk_index, -1, nb_subfr);
|
||||
}
|
||||
ELSE IF ( sub(coder_type,RF_GENPRED) == 0 )
|
||||
else if ( coder_type == RF_GENPRED )
|
||||
{
|
||||
pConfigAcelp->fixed_cdk_index[0] = 0; /* 7 bits */
|
||||
pConfigAcelp->fixed_cdk_index[1] = -1;
|
||||
pConfigAcelp->fixed_cdk_index[2] = 0; /* 7 bits */
|
||||
pConfigAcelp->fixed_cdk_index[3] = -1;
|
||||
pConfigAcelp->fixed_cdk_index[4] = -1;
|
||||
bits = add(bits,14);
|
||||
acelp_cfg->fixed_cdk_index[0] = 0; /* 7 bits */
|
||||
acelp_cfg->fixed_cdk_index[1] = -1;
|
||||
acelp_cfg->fixed_cdk_index[2] = 0; /* 7 bits */
|
||||
acelp_cfg->fixed_cdk_index[3] = -1;
|
||||
acelp_cfg->fixed_cdk_index[4] = -1;
|
||||
bits += 14;
|
||||
}
|
||||
ELSE IF( sub(coder_type,RF_NOPRED) == 0 )
|
||||
else if( coder_type == RF_NOPRED )
|
||||
{
|
||||
set16_fx(pConfigAcelp->fixed_cdk_index, 0, nb_subfr);
|
||||
bits = add(bits,28);
|
||||
set_i(acelp_cfg->fixed_cdk_index, 0, nb_subfr);
|
||||
bits += 28;
|
||||
}
|
||||
ELSE
|
||||
else
|
||||
{
|
||||
bits = add(bits, BITS_ALLOC_adjust_acelp_fixed_cdk(sub(bits_frame,bits), pConfigAcelp->fixed_cdk_index, nb_subfr ));
|
||||
bits += BITS_ALLOC_adjust_acelp_fixed_cdk(bits_frame - bits, acelp_cfg->fixed_cdk_index, nb_subfr );
|
||||
}
|
||||
|
||||
remaining_bits = sub(bits_frame, bits);
|
||||
remaining_bits = bits_frame-bits;
|
||||
|
||||
/*Sanity check*/
|
||||
if (remaining_bits<0)
|
||||
if( remaining_bits < 0 )
|
||||
{
|
||||
move16();
|
||||
bits = -1;
|
||||
}
|
||||
|
||||
|
||||
return(bits);
|
||||
return( bits );
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------*
|
||||
* BITS_ALLOC_adjust_acelp_fixed_cdk()
|
||||
*
|
||||
*
|
||||
*--------------------------------------------------------------------*/
|
||||
|
||||
static
|
||||
Word16 BITS_ALLOC_adjust_generic(
|
||||
const Word16 bits_frame, /*i: bit budget*/
|
||||
Word16 *fixed_cdk_index,
|
||||
const Word16 nb_subfr,
|
||||
const Word16 *pulseconfigbits,
|
||||
const Word16 pulseconfig_size
|
||||
static int BITS_ALLOC_adjust_acelp_fixed_cdk(
|
||||
int bits_frame, /*i: bit budget*/
|
||||
int *fixed_cdk_index,
|
||||
int nb_subfr
|
||||
)
|
||||
{
|
||||
Word16 bits_subframe2, inb_subfr;
|
||||
Word16 sfr, k, bitsused, bits_currsubframe;
|
||||
int bits_subframe2;
|
||||
int sfr, k, bitsused, bits_currsubframe;
|
||||
|
||||
bits_subframe2 = bits_frame;
|
||||
move16();
|
||||
inb_subfr = 8192/*1.0f/NB_SUBFR Q15*/;
|
||||
move16();
|
||||
if ( sub(nb_subfr,NB_SUBFR16k) == 0 )
|
||||
{
|
||||
inb_subfr = 6554/*1.0f/NB_SUBFR16k Q15*/;
|
||||
move16();
|
||||
}
|
||||
|
||||
IF ( sub(bits_subframe2, i_mult2(pulseconfigbits[0], nb_subfr)) < 0 ) /* not in final code - not instrumented */
|
||||
if( bits_subframe2 < ACELP_FIXED_CDK_BITS(0)*nb_subfr )
|
||||
{
|
||||
return add(bits_frame,1); /* Not enough bits for lowest mode. -> trigger alarm*/
|
||||
return(bits_frame+1 ); /* Not enough bits for lowest mode. -> trigger alarm*/
|
||||
}
|
||||
|
||||
/* search cdk-index for first subframe */
|
||||
FOR (k=0; k<pulseconfig_size-1; k++)
|
||||
for (k=0; k<ACELP_FIXED_CDK_NB-1; k++)
|
||||
{
|
||||
|
||||
IF (i_mult2(pulseconfigbits[k], nb_subfr) > bits_subframe2)
|
||||
if (ACELP_FIXED_CDK_BITS(k)*nb_subfr > bits_subframe2)
|
||||
{
|
||||
k = sub(k,1); /* previous mode did not exceed bit-budget */
|
||||
BREAK;
|
||||
k--; /* previous mode did not exceed bit-budget */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i_mult2(pulseconfigbits[k], nb_subfr) > bits_subframe2)
|
||||
if( ACELP_FIXED_CDK_BITS(k)*nb_subfr > bits_subframe2 )
|
||||
{
|
||||
k = sub(k,1); /* previous mode did not exceed bit-budget */
|
||||
k--; /* previous mode did not exceed bit-budget */
|
||||
}
|
||||
|
||||
move16();
|
||||
fixed_cdk_index[0] = k;
|
||||
bitsused = i_mult2(pulseconfigbits[k], nb_subfr);
|
||||
bitsused = ACELP_FIXED_CDK_BITS(k);
|
||||
|
||||
FOR (sfr=1; sfr < nb_subfr; sfr++)
|
||||
for (sfr=1; sfr < nb_subfr; sfr++)
|
||||
{
|
||||
/*bits_currsubframe = (int)(((float)sfr+1.0f)*bits_subframe) - bitsused;*/
|
||||
bits_currsubframe = sub(add(i_mult2(sfr, bits_subframe2), bits_subframe2), bitsused);
|
||||
bits_currsubframe = (sfr*bits_subframe2 + bits_subframe2) - bitsused*nb_subfr;
|
||||
|
||||
/* try increasing mode while below threshold */
|
||||
WHILE ( (sub(k, pulseconfig_size-1) < 0) && (sub(i_mult2(pulseconfigbits[add(k,1)], nb_subfr),bits_currsubframe) <= 0) )
|
||||
while ( (k < ACELP_FIXED_CDK_NB-1) && (ACELP_FIXED_CDK_BITS(k+1)*nb_subfr <= bits_currsubframe) )
|
||||
{
|
||||
test();
|
||||
k = add(k,1);
|
||||
k++;
|
||||
}
|
||||
|
||||
/* try decreasing mode until below threshold */
|
||||
WHILE (i_mult2(pulseconfigbits[k], nb_subfr) > bits_currsubframe)
|
||||
while (ACELP_FIXED_CDK_BITS(k)*nb_subfr > bits_currsubframe)
|
||||
{
|
||||
k = sub(k,1);
|
||||
|
||||
IF (k == 0)
|
||||
k--;
|
||||
if ( k == 0 )
|
||||
{
|
||||
BREAK;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* store mode */
|
||||
move16();
|
||||
fixed_cdk_index[sfr] = k;
|
||||
bitsused = add(bitsused, i_mult2(pulseconfigbits[k], nb_subfr));
|
||||
bitsused += ACELP_FIXED_CDK_BITS(k);
|
||||
}
|
||||
|
||||
return mult_r(bitsused, inb_subfr);
|
||||
}
|
||||
|
||||
Word16 BITS_ALLOC_adjust_acelp_fixed_cdk(
|
||||
const Word16 bits_frame, /*i: bit budget*/
|
||||
Word16 *fixed_cdk_index,
|
||||
const Word16 nb_subfr
|
||||
)
|
||||
{
|
||||
Word16 bitsused;
|
||||
|
||||
|
||||
bitsused = BITS_ALLOC_adjust_generic(bits_frame, fixed_cdk_index, nb_subfr, ACELP_CDK_BITS, ACELP_FIXED_CDK_NB);
|
||||
|
||||
|
||||
return bitsused;
|
||||
}
|
||||
|
||||
|
|
|
|||
1925
src/libs/libevs/lib_com/bitstream_fx.cpp → src/libs/libevs/lib_com/bitstream.cpp
Executable file → Normal file
1925
src/libs/libevs/lib_com/bitstream_fx.cpp → src/libs/libevs/lib_com/bitstream.cpp
Executable file → Normal file
File diff suppressed because it is too large
Load Diff
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -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
|
|
@ -1,288 +1,173 @@
|
|||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
EVS Codec 3GPP TS26.443 Nov 13, 2018. Version 12.11.0 / 13.7.0 / 14.3.0 / 15.1.0
|
||||
====================================================================================*/
|
||||
|
||||
#include <assert.h>
|
||||
#include "prot_fx.h"
|
||||
#include <math.h>
|
||||
#include "prot.h"
|
||||
#include "options.h"
|
||||
|
||||
#include "stl.h"
|
||||
#include "prot_fx.h"
|
||||
#include "basop_util.h"
|
||||
#include "rom_basop_util.h"
|
||||
#define inv_int InvIntTable
|
||||
/*-------------------------------------------------------------------*
|
||||
* tcxGetNoiseFillingTilt()
|
||||
*
|
||||
*
|
||||
*-------------------------------------------------------------------*/
|
||||
|
||||
|
||||
|
||||
Word16 tcxGetNoiseFillingTilt(Word16 A[], Word16 lpcorder, Word16 L_frame, Word16 mode, Word16 *noiseTiltFactor)
|
||||
int tcxGetNoiseFillingTilt(
|
||||
float A[],
|
||||
int L_frame,
|
||||
int mode,
|
||||
float *noiseTiltFactor
|
||||
)
|
||||
{
|
||||
Word16 firstLine;
|
||||
Word32 tmp;
|
||||
Word16 As[M+1];
|
||||
int firstLine;
|
||||
|
||||
|
||||
IF (mode != 0)
|
||||
if (mode)
|
||||
{
|
||||
firstLine = idiv1616U(L_frame, 6);
|
||||
*noiseTiltFactor = 18432/*0.5625f Q15*/;
|
||||
move16();
|
||||
firstLine = L_frame / 6;
|
||||
*noiseTiltFactor = 0.5625f;
|
||||
}
|
||||
ELSE
|
||||
else
|
||||
{
|
||||
firstLine = shr(L_frame, 3);
|
||||
|
||||
Copy_Scale_sig( A, As, lpcorder+1, sub(norm_s(A[0]),2) );
|
||||
tmp = get_gain(As+1, As, lpcorder);
|
||||
BASOP_SATURATE_WARNING_OFF;
|
||||
*noiseTiltFactor = add(round_fx(L_shl(tmp, 15)), 3072/*0.09375f Q15*/);
|
||||
move16();
|
||||
BASOP_SATURATE_WARNING_ON;
|
||||
firstLine = L_frame / 8;
|
||||
*noiseTiltFactor = get_gain( A+1, A, M, NULL );
|
||||
*noiseTiltFactor = min(1.0f, (*noiseTiltFactor) + 0.09375f);
|
||||
}
|
||||
|
||||
|
||||
return firstLine;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------*
|
||||
* tcxFormantEnhancement()
|
||||
*
|
||||
*
|
||||
*-------------------------------------------------------------------*/
|
||||
|
||||
void tcxFormantEnhancement(
|
||||
Word16 xn_buf[],
|
||||
Word16 gainlpc[], Word16 gainlpc_e[],
|
||||
Word32 spectrum[], Word16 *spectrum_e,
|
||||
Word16 L_frame,
|
||||
Word16 L_frameTCX
|
||||
float xn_buf[],
|
||||
float gainlpc[],
|
||||
float spectrum[],
|
||||
int L_frame
|
||||
)
|
||||
{
|
||||
Word16 i, j, k, l, n;
|
||||
Word16 fac, fac0, fac1, fac_e, d, tmp;
|
||||
Word16 xn_buf_e, xn_one, m, e;
|
||||
int k;
|
||||
int i, j, l = 0;
|
||||
float fac, step;
|
||||
|
||||
|
||||
k = shr(L_frame, 6); /* FDNS_NPTS = 64 */
|
||||
l = 0;
|
||||
move16();
|
||||
|
||||
/* get exponent */
|
||||
xn_buf_e = 0;
|
||||
move16();
|
||||
FOR (i = 0; i < FDNS_NPTS; i++)
|
||||
{
|
||||
xn_buf_e = s_max(xn_buf_e, gainlpc_e[i]);
|
||||
}
|
||||
xn_buf_e = shr(add(xn_buf_e, 1), 1); /* max exponent after sqrt */
|
||||
xn_one = shr(0x4000, sub(xn_buf_e, 1)); /* 1.0 scaled to xn_buf_e */
|
||||
k = L_frame / FDNS_NPTS;
|
||||
|
||||
/* Formant enhancement via square root of the LPC gains */
|
||||
e = gainlpc_e[0];
|
||||
move16();
|
||||
m = Sqrt16(gainlpc[0], &e);
|
||||
xn_buf[0] = shl(m, sub(e, xn_buf_e));
|
||||
move16();
|
||||
xn_buf[0] = (float)sqrt(gainlpc[0]);
|
||||
xn_buf[1] = (float)sqrt(gainlpc[1]);
|
||||
fac = 1.0f / min(xn_buf[0], xn_buf[1]);
|
||||
|
||||
e = gainlpc_e[1];
|
||||
move16();
|
||||
m = Sqrt16(gainlpc[1], &e);
|
||||
xn_buf[1] = shl(m, sub(e, xn_buf_e));
|
||||
move16();
|
||||
|
||||
fac0 = s_min(xn_buf[0], xn_buf[1]);
|
||||
fac_e = xn_buf_e;
|
||||
move16();
|
||||
fac0 = Inv16(fac0, &fac_e);
|
||||
|
||||
FOR (i = 1; i < FDNS_NPTS-1; i++)
|
||||
for (i = 1; i < FDNS_NPTS - 1; i++)
|
||||
{
|
||||
e = gainlpc_e[i+1];
|
||||
move16();
|
||||
m = Sqrt16(gainlpc[i+1], &e);
|
||||
xn_buf[i+1] = shl(m, sub(e, xn_buf_e));
|
||||
move16();
|
||||
xn_buf[i+1] = (float)sqrt(gainlpc[i+1]);
|
||||
|
||||
test();
|
||||
IF ((sub(xn_buf[i-1], xn_buf[i]) <= 0) && (sub(xn_buf[i+1], xn_buf[i]) <= 0))
|
||||
if ((xn_buf[i-1] <= xn_buf[i]) && (xn_buf[i+1] <= xn_buf[i]))
|
||||
{
|
||||
m = s_max(xn_buf[i-1], xn_buf[i+1]);
|
||||
e = xn_buf_e;
|
||||
move16();
|
||||
m = Inv16(m, &e);
|
||||
|
||||
fac1 = m;
|
||||
move16();
|
||||
tmp = sub(e, fac_e);
|
||||
|
||||
if (tmp > 0) fac0 = shr(fac0, tmp);
|
||||
if (tmp < 0) fac1 = shl(fac1, tmp);
|
||||
|
||||
if (tmp > 0)
|
||||
step = max(xn_buf[i-1], xn_buf[i+1]);
|
||||
step = (1.0f / step - fac) / (float)(i - l);
|
||||
xn_buf[l] = 1.0f;
|
||||
fac += step;
|
||||
for (j = l + 1; j < i; j++)
|
||||
{
|
||||
fac_e = e;
|
||||
move16();
|
||||
xn_buf[j] = min(1.0f, xn_buf[j] * fac);
|
||||
fac += step;
|
||||
}
|
||||
|
||||
d = sub(fac1, fac0);
|
||||
n = sub(i, l);
|
||||
assert(n <= 64);
|
||||
|
||||
xn_buf[l] = xn_one;
|
||||
move16();
|
||||
FOR (j = 1; j < n; j++)
|
||||
{
|
||||
fac = add(fac0, mult(d, extract_l(L_mult0(j, inv_int[n]))));
|
||||
BASOP_SATURATE_WARNING_OFF;
|
||||
xn_buf[l+j] = s_min(xn_one, shl(mult(xn_buf[l+j], fac), fac_e));
|
||||
move16();
|
||||
BASOP_SATURATE_WARNING_ON;
|
||||
}
|
||||
|
||||
l = i;
|
||||
move16();
|
||||
|
||||
fac0 = m;
|
||||
move16();
|
||||
fac_e = e;
|
||||
move16();
|
||||
}
|
||||
}
|
||||
/* i = FDNS_NPTS - 1; Completing changes to gains */
|
||||
m = s_min(xn_buf[i-1], xn_buf[i]);
|
||||
e = xn_buf_e;
|
||||
move16();
|
||||
m = Inv16(m, &e);
|
||||
|
||||
fac1 = m;
|
||||
move16();
|
||||
tmp = sub(e, fac_e);
|
||||
|
||||
if (tmp > 0) fac0 = shr(fac0, tmp);
|
||||
if (tmp < 0) fac1 = shl(fac1, tmp);
|
||||
|
||||
if (tmp > 0)
|
||||
/* i = tcx_cfg->fdns_npts - 1; Completing changes to gains */
|
||||
step = min(xn_buf[i-1], xn_buf[i]);
|
||||
step = (1.0f / step - fac) / (float)(i - l);
|
||||
xn_buf[l] = 1.0f;
|
||||
fac += step;
|
||||
for (j = l + 1; j < i; j++)
|
||||
{
|
||||
fac_e = e;
|
||||
move16();
|
||||
xn_buf[j] = min(1.0f, xn_buf[j] * fac);
|
||||
fac += step;
|
||||
}
|
||||
|
||||
d = sub(fac1, fac0);
|
||||
n = sub(i, l);
|
||||
assert(n <= 64);
|
||||
|
||||
xn_buf[l] = xn_one;
|
||||
move16();
|
||||
FOR (j = 1; j < n; j++)
|
||||
{
|
||||
fac = add(fac0, mult(d, extract_l(L_mult0(j, inv_int[n]))));
|
||||
BASOP_SATURATE_WARNING_OFF;
|
||||
xn_buf[l+j] = s_min(xn_one, shl(mult(xn_buf[l+j], fac), fac_e));
|
||||
move16();
|
||||
BASOP_SATURATE_WARNING_ON;
|
||||
}
|
||||
|
||||
xn_buf[i] = xn_one;
|
||||
move16();
|
||||
xn_buf[i] = 1.0f;
|
||||
|
||||
/* Application of changed gains onto decoded MDCT lines */
|
||||
FOR (i = 0; i < L_frame; i += k)
|
||||
for (i = j = 0; i < L_frame; j++)
|
||||
{
|
||||
FOR (l = 0; l < k; l++)
|
||||
for (l = 0; l < k; i++, l++)
|
||||
{
|
||||
*spectrum = Mpy_32_16_1(*spectrum, *xn_buf);
|
||||
move32();
|
||||
spectrum++;
|
||||
spectrum[i] *= xn_buf[j];
|
||||
}
|
||||
xn_buf++;
|
||||
}
|
||||
|
||||
tmp = sub(L_frameTCX, L_frame);
|
||||
FOR (i = 0; i < tmp; i++)
|
||||
{
|
||||
spectrum[i] = L_shr(spectrum[i], xn_buf_e);
|
||||
move32();
|
||||
}
|
||||
*spectrum_e = add(*spectrum_e, xn_buf_e);
|
||||
move16();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void tcxInvertWindowGrouping(TCX_config *tcx_cfg,
|
||||
Word32 xn_buf[],
|
||||
Word32 spectrum[],
|
||||
Word16 L_frame,
|
||||
Word8 fUseTns,
|
||||
Word16 last_core,
|
||||
Word16 index,
|
||||
Word16 frame_cnt,
|
||||
Word16 bfi)
|
||||
/*-------------------------------------------------------------------*
|
||||
* tcxGetNoiseFillingTilt()
|
||||
*
|
||||
*
|
||||
*-------------------------------------------------------------------*/
|
||||
|
||||
void tcxInvertWindowGrouping(
|
||||
TCX_config *tcx_cfg,
|
||||
float xn_buf[],
|
||||
float spectrum[],
|
||||
int L_frame,
|
||||
int fUseTns,
|
||||
int last_core,
|
||||
int index,
|
||||
int frame_cnt,
|
||||
int bfi
|
||||
)
|
||||
{
|
||||
Word16 i, L_win, L_spec;
|
||||
Word32 *p;
|
||||
short i, w, t_integer;
|
||||
int L_win, L_spec;
|
||||
|
||||
|
||||
L_win = shr(L_frame, 1);
|
||||
L_spec = tcx_cfg->tnsConfig[0][0].iFilterBorders[0];
|
||||
move16();
|
||||
|
||||
test();
|
||||
test();
|
||||
if ((frame_cnt != 0) && (bfi == 0) && (last_core != ACELP_CORE)) /* fix sub-window overlap */
|
||||
if (frame_cnt && !bfi && last_core!=0)
|
||||
{
|
||||
/* fix sub-window overlap */
|
||||
tcx_cfg->tcx_last_overlap_mode = tcx_cfg->tcx_curr_overlap_mode;
|
||||
move16();
|
||||
}
|
||||
test();
|
||||
test();
|
||||
test();
|
||||
test();
|
||||
test();
|
||||
test();
|
||||
test();
|
||||
IF (((bfi==0) &&((tcx_cfg->tcx_last_overlap_mode != FULL_OVERLAP) ||
|
||||
((tcx_cfg->tcx_curr_overlap_mode == FULL_OVERLAP) && (frame_cnt == 0) && (index == 0))))
|
||||
||
|
||||
((bfi!=0) &&((tcx_cfg->tcx_last_overlap_mode != FULL_OVERLAP) &&
|
||||
!(tcx_cfg->tcx_curr_overlap_mode == FULL_OVERLAP))))
|
||||
|
||||
if (((!bfi) &&((tcx_cfg->tcx_last_overlap_mode != FULL_OVERLAP) ||
|
||||
((tcx_cfg->tcx_curr_overlap_mode == FULL_OVERLAP) && (frame_cnt == 0) && (index == 0))))
|
||||
||
|
||||
((bfi) &&((tcx_cfg->tcx_last_overlap_mode != FULL_OVERLAP) &&
|
||||
!(tcx_cfg->tcx_curr_overlap_mode == FULL_OVERLAP))))
|
||||
{
|
||||
|
||||
/* ungroup sub-windows: deinterleave MDCT bins into separate windows */
|
||||
p = xn_buf;
|
||||
FOR (i = 1; i < L_win; i += 2)
|
||||
for (t_integer = w = 0; w < 2; w++)
|
||||
{
|
||||
*p++ = spectrum[i];
|
||||
move32();
|
||||
}
|
||||
|
||||
p = spectrum;
|
||||
FOR (i = 0; i < L_frame; i += 2)
|
||||
{
|
||||
*p++ = spectrum[i];
|
||||
move32();
|
||||
}
|
||||
|
||||
p = spectrum + L_frame - 1;
|
||||
FOR (i = sub(L_frame, 1); i > L_win; i -= 2)
|
||||
{
|
||||
*p-- = spectrum[i];
|
||||
move32();
|
||||
}
|
||||
Copy32(xn_buf, spectrum + L_win, shr(L_win, 1));
|
||||
|
||||
test();
|
||||
test();
|
||||
IF ((tcx_cfg->fIsTNSAllowed != 0) && (bfi == 0) && (fUseTns != 0))
|
||||
{
|
||||
/* rearrange LF sub-window lines prior to TNS synthesis filtering */
|
||||
IF (sub(L_spec, L_frame) < 0)
|
||||
for (i = w; i < L_frame; i += 2)
|
||||
{
|
||||
Copy32(spectrum+8, spectrum+16, sub(shr(L_spec,1),8));
|
||||
Copy32(spectrum+L_frame/2, spectrum+8, 8);
|
||||
Copy32(spectrum+L_frame/2+8, spectrum+L_spec/2+8, sub(shr(L_spec,1),8));
|
||||
xn_buf[t_integer++] = spectrum[i];
|
||||
}
|
||||
ELSE
|
||||
}
|
||||
|
||||
mvr2r( xn_buf, spectrum, L_frame );
|
||||
|
||||
if( tcx_cfg->fIsTNSAllowed && !bfi && fUseTns )
|
||||
{
|
||||
L_win = L_frame >> 1;
|
||||
L_spec = tcx_cfg->tnsConfig[0][0].iFilterBorders[0];
|
||||
|
||||
/* rearrange LF sub-window lines prior to TNS synthesis filtering */
|
||||
if( L_spec < L_frame )
|
||||
{
|
||||
Copy32(spectrum+L_win, xn_buf, 8);
|
||||
Copy32(spectrum+8, spectrum+16, sub(L_win, 8));
|
||||
Copy32(xn_buf, spectrum+8, 8);
|
||||
mvr2r( spectrum+8, spectrum+16, L_spec/2-8 );
|
||||
mvr2r( spectrum+L_frame/2, spectrum+8, 8 );
|
||||
mvr2r( spectrum+L_frame/2+8, spectrum+L_spec/2+8, L_spec/2-8 );
|
||||
}
|
||||
else
|
||||
{
|
||||
mvr2r( spectrum+8, xn_buf, L_win );
|
||||
mvr2r( xn_buf, spectrum+16, L_win-8 );
|
||||
mvr2r( xn_buf+L_win-8, spectrum+8, 8);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -1,41 +1,37 @@
|
|||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
EVS Codec 3GPP TS26.443 Nov 13, 2018. Version 12.11.0 / 13.7.0 / 14.3.0 / 15.1.0
|
||||
====================================================================================*/
|
||||
|
||||
#include "options.h" /* Compilation switches */
|
||||
#include "stl.h"
|
||||
#include "prot_fx.h"
|
||||
#include "options.h"
|
||||
#include "prot.h"
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
* get_delay_fx()
|
||||
*
|
||||
* Function returns various types of delays in the codec in ms.
|
||||
*--------------------------------------------------------------------------*/
|
||||
* get_delay()
|
||||
*
|
||||
* Function returns various types of delays in the codec in ms.
|
||||
*--------------------------------------------------------------------------*/
|
||||
|
||||
Word32 get_delay_fx( /* o : delay value in ms */
|
||||
const Word16 what_delay, /* i : what delay? (ENC or DEC) */
|
||||
const Word32 io_fs /* i : input/output sampling frequency */
|
||||
float get_delay( /* o : delay value in ms */
|
||||
const short what_delay, /* i : what delay? (ENC or DEC) */
|
||||
const int io_fs /* i : input/output sampling frequency */
|
||||
)
|
||||
{
|
||||
Word32 delay = 0;
|
||||
float delay = 0;
|
||||
|
||||
IF( sub(what_delay,ENC) == 0 )
|
||||
if( what_delay == ENC )
|
||||
{
|
||||
delay = (DELAY_FIR_RESAMPL_NS + ACELP_LOOK_NS);
|
||||
move32();
|
||||
}
|
||||
ELSE
|
||||
else
|
||||
{
|
||||
IF( L_sub(io_fs,8000) == 0 )
|
||||
if( io_fs == 8000 )
|
||||
{
|
||||
delay = DELAY_CLDFB_NS;
|
||||
move32();
|
||||
}
|
||||
ELSE
|
||||
else
|
||||
{
|
||||
delay = DELAY_BWE_TOTAL_NS;
|
||||
move32();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,18 +1,17 @@
|
|||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
EVS Codec 3GPP TS26.443 Nov 13, 2018. Version 12.11.0 / 13.7.0 / 14.3.0 / 15.1.0
|
||||
====================================================================================*/
|
||||
|
||||
#include "disclaimer.h"
|
||||
#include "options.h"
|
||||
#include "stl.h"
|
||||
|
||||
/* WMC_TOOL_SKIP_FILE */
|
||||
#include "options.h"
|
||||
#include "prot.h"
|
||||
|
||||
int print_disclaimer(FILE *fPtr)
|
||||
{
|
||||
|
||||
fprintf(fPtr, "\n==============================================================================\n");
|
||||
fprintf(fPtr, " EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0\n");
|
||||
fprintf(fPtr, "==============================================================================\n\n\n");
|
||||
fprintf(fPtr, "\n===================================================================================================\n");
|
||||
fprintf(fPtr, " EVS Codec (Floating Point) 3GPP TS26.443 Nov 13, 2018. Version 12.11.0 / 13.7.0 / 14.3.0 / 15.1.0\n");
|
||||
fprintf(fPtr, "===================================================================================================\n\n\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,15 +0,0 @@
|
|||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#ifndef __INCLUDED_DISCLAIMER_H
|
||||
#define __INCLUDED_DISCLAIMER_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
int print_disclaimer(FILE *fPtr);
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* __INCLUDED_DISCLAIMER_H */
|
||||
|
|
@ -1,55 +1,48 @@
|
|||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
EVS Codec 3GPP TS26.443 Nov 13, 2018. Version 12.11.0 / 13.7.0 / 14.3.0 / 15.1.0
|
||||
====================================================================================*/
|
||||
|
||||
|
||||
/* Header files */
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "prot_fx.h"
|
||||
#include "stl.h"
|
||||
#include "prot_fx.h"
|
||||
#include "options.h"
|
||||
#include "prot.h"
|
||||
#include "rom_com.h"
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------*
|
||||
* routine: dlpc_bfi()
|
||||
*
|
||||
*
|
||||
*---------------------------------------------------------------------*/
|
||||
|
||||
void dlpc_bfi(
|
||||
const Word16 L_frame,
|
||||
Word16 *lsf_q, /* o : quantized LSFs */
|
||||
const Word16 *lsfold, /* i : past quantized LSF */
|
||||
const Word16 last_good, /* i : last good received frame */
|
||||
const Word16 nbLostCmpt, /* i : counter of consecutive bad frames */
|
||||
Word16 mem_MA[], /* i/o: quantizer memory for MA model */
|
||||
Word16 mem_AR[], /* i/o: quantizer memory for AR model */
|
||||
Word16 *stab_fac, /* i : LSF stability factor */
|
||||
Word16 *lsf_adaptive_mean,/* i : LSF adaptive mean, updated when BFI==0 */
|
||||
Word16 numlpc, /* i : Number of division per superframe */
|
||||
Word16 lsf_cng[],
|
||||
Word8 plcBackgroundNoiseUpdated,
|
||||
Word16 *lsf_q_cng, /* o : quantized LSFs */
|
||||
Word16 *old_lsf_q_cng, /* o : old quantized LSFs for background noise */
|
||||
const Word16* lsfBase, /* i : base for differential LSF coding */
|
||||
Word8 tcxonly
|
||||
int L_frame,
|
||||
float *lsf_q, /* o : quantized lsfs */
|
||||
const float *lsfold, /* i : past quantized lsf */
|
||||
const short last_good, /* i : last good received frame */
|
||||
const short nbLostCmpt, /* i : counter of consecutive bad frames */
|
||||
float mem_MA[], /* i/o: quantizer memory for MA model */
|
||||
float *mem_AR, /* i/o: quantizer memory for AR model */
|
||||
float *stab_fac, /* i : lsf stability factor */
|
||||
float *lsf_adaptive_mean,/* i : lsf adaptive mean, updated when BFI==0 */
|
||||
int numlpc, /* i : Number of division per superframe */
|
||||
float lsf_cng[],
|
||||
int plcBackgroundNoiseUpdated,
|
||||
float *lsf_q_cng, /* o : quantized lsfs of background noise */
|
||||
float *old_lsf_q_cng, /* o : old quantized lsfs for background noise */
|
||||
const float lsfBase[] /* i : base for differential lsf coding */
|
||||
)
|
||||
{
|
||||
lsf_dec_bfi( MODE2, &lsf_q[0], lsfold, lsf_adaptive_mean, lsfBase, mem_MA, mem_AR, *stab_fac, 0, L_frame, last_good,
|
||||
nbLostCmpt, plcBackgroundNoiseUpdated, lsf_q_cng, lsf_cng, old_lsf_q_cng, 0, 0, 0 );
|
||||
|
||||
lsf_dec_bfi(
|
||||
MODE2,
|
||||
&lsf_q[0], lsfold, lsf_adaptive_mean, lsfBase, mem_MA, mem_AR, *stab_fac,
|
||||
0, L_frame, last_good, nbLostCmpt,
|
||||
plcBackgroundNoiseUpdated, lsf_q_cng, lsf_cng, old_lsf_q_cng, 0, 0, tcxonly
|
||||
,0
|
||||
|
||||
);
|
||||
IF ( sub(numlpc,2)==0 )
|
||||
if( numlpc == 2 )
|
||||
{
|
||||
/* Decode the second LPC */
|
||||
lsf_dec_bfi(
|
||||
MODE2,
|
||||
&lsf_q[M], &lsf_q[0], lsf_adaptive_mean, lsfBase, mem_MA, mem_AR, *stab_fac,
|
||||
0, L_frame, last_good, nbLostCmpt+1,
|
||||
plcBackgroundNoiseUpdated, lsf_q_cng, lsf_cng, old_lsf_q_cng, 0, 0, tcxonly
|
||||
,0
|
||||
);
|
||||
lsf_dec_bfi( MODE2, &lsf_q[M], &lsf_q[0], lsf_adaptive_mean, lsfBase, mem_MA, mem_AR, *stab_fac, 0, L_frame, last_good,
|
||||
nbLostCmpt+1, plcBackgroundNoiseUpdated, lsf_q_cng, lsf_cng, old_lsf_q_cng, 0, 0, 0 );
|
||||
}
|
||||
/**/ /*No local variabvles defined*/
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
461
src/libs/libevs/basic_op/enh1632.cpp → src/libs/libevs/lib_com/enh1632.cpp
Executable file → Normal file
461
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
|
||||
|
|
@ -9,7 +10,7 @@
|
|||
|
||||
History:
|
||||
07 Nov 04 v2.0 Incorporation of new 32-bit / 40-bit / control
|
||||
operators for the ITU-T Standard Tool Library as
|
||||
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.
|
||||
|
|
@ -18,33 +19,33 @@
|
|||
*/
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Enhanced 16/32 bit operators :
|
||||
* s_max()
|
||||
* s_min()
|
||||
* L_max()
|
||||
* L_min()
|
||||
* shl_r()
|
||||
* L_shl_r()
|
||||
* L_mac0()
|
||||
* L_mult0()
|
||||
* L_msu0()
|
||||
* s_and()
|
||||
* s_or()
|
||||
* s_xor()
|
||||
* L_and()
|
||||
* L_or()
|
||||
* lshl()
|
||||
* lshr()
|
||||
* L_lshl()
|
||||
* L_lshr()
|
||||
* rotr()
|
||||
* rotl()
|
||||
* L_rotr()
|
||||
* L_rotl()
|
||||
*
|
||||
*****************************************************************************/
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Enhanced 16/32 bit operators :
|
||||
* s_max()
|
||||
* s_min()
|
||||
* L_max()
|
||||
* L_min()
|
||||
* shl_r()
|
||||
* L_shl_r()
|
||||
* L_mac0()
|
||||
* L_mult0()
|
||||
* L_msu0()
|
||||
* s_and()
|
||||
* s_or()
|
||||
* s_xor()
|
||||
* L_and()
|
||||
* L_or()
|
||||
* lshl()
|
||||
* lshr()
|
||||
* L_lshl()
|
||||
* L_lshr()
|
||||
* rotr()
|
||||
* rotl()
|
||||
* L_rotr()
|
||||
* L_rotl()
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
|
|
@ -52,17 +53,11 @@
|
|||
* Include-Files
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "stl.h"
|
||||
|
||||
#if (WMOPS)
|
||||
extern BASIC_OP multiCounter[MAXCOUNTERS];
|
||||
extern int currCounter;
|
||||
#endif /* if WMOPS */
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Constants and Globals
|
||||
|
|
@ -93,10 +88,10 @@ extern int currCounter;
|
|||
*
|
||||
* Inputs :
|
||||
*
|
||||
* var1 16 bit short signed integer (Word16) whose value falls in
|
||||
* var1 16 bit short signed integer (Word16) whose value falls in
|
||||
* the range 0xffff 8000 <= var1 <= 0x0000 7fff.
|
||||
*
|
||||
* var2 16 bit short signed integer (Word16) whose value falls in
|
||||
* var2 16 bit short signed integer (Word16) whose value falls in
|
||||
* the range 0xffff 8000 <= var2 <= 0x0000 7fff.
|
||||
*
|
||||
* Outputs :
|
||||
|
|
@ -105,37 +100,39 @@ extern int currCounter;
|
|||
*
|
||||
* Return Value:
|
||||
*
|
||||
* var_out 16 bit short signed integer (Word16) whose value falls in
|
||||
* var_out 16 bit short signed integer (Word16) whose value falls in
|
||||
* the range 0xffff 8000 <= var_out <= 0x0000 7fff.
|
||||
*
|
||||
*****************************************************************************/
|
||||
Word16 lshl( Word16 var1, Word16 var2) {
|
||||
Word16 var_out=0;
|
||||
Word16 lshl( Word16 var1, Word16 var2)
|
||||
{
|
||||
Word16 var_out=0;
|
||||
|
||||
if( var2 < 0) {
|
||||
var2 = -var2;
|
||||
var_out = lshr( var1, var2);
|
||||
if( var2 < 0)
|
||||
{
|
||||
var2 = -var2;
|
||||
var_out = lshr( var1, var2);
|
||||
}
|
||||
else
|
||||
{
|
||||
if( var2 == 0 || var1 == 0)
|
||||
{
|
||||
var_out = var1;
|
||||
}
|
||||
else if( var2 >= 16)
|
||||
{
|
||||
var_out = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
var_out = var1 << var2;
|
||||
}
|
||||
}
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].lshr--;
|
||||
#endif /* if WMOPS */
|
||||
BASOP_CHECK();
|
||||
|
||||
} else {
|
||||
if( var2 == 0 || var1 == 0) {
|
||||
var_out = var1;
|
||||
} else if( var2 >= 16) {
|
||||
var_out = 0;
|
||||
} else {
|
||||
var_out = var1 << var2;
|
||||
}
|
||||
}
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].lshl++;
|
||||
#endif /* if WMOPS */
|
||||
|
||||
BASOP_CHECK();
|
||||
|
||||
return( var_out);
|
||||
return( var_out);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
|
|
@ -154,10 +151,10 @@ Word16 lshl( Word16 var1, Word16 var2) {
|
|||
*
|
||||
* Inputs :
|
||||
*
|
||||
* var1 16 bit short signed integer (Word16) whose value falls in
|
||||
* var1 16 bit short signed integer (Word16) whose value falls in
|
||||
* the range 0xffff 8000 <= var1 <= 0x0000 7fff.
|
||||
*
|
||||
* var2 16 bit short signed integer (Word16) whose value falls in
|
||||
* var2 16 bit short signed integer (Word16) whose value falls in
|
||||
* the range 0xffff 8000 <= var2 <= 0x0000 7fff.
|
||||
*
|
||||
* Outputs :
|
||||
|
|
@ -166,39 +163,41 @@ Word16 lshl( Word16 var1, Word16 var2) {
|
|||
*
|
||||
* Return Value:
|
||||
*
|
||||
* var_out 16 bit short signed integer (Word16) whose value falls in
|
||||
* var_out 16 bit short signed integer (Word16) whose value falls in
|
||||
* the range 0xffff 8000 <= var_out <= 0x0000 7fff.
|
||||
*
|
||||
*****************************************************************************/
|
||||
Word16 lshr( Word16 var1, Word16 var2) {
|
||||
Word16 var_out;
|
||||
Word16 lshr( Word16 var1, Word16 var2)
|
||||
{
|
||||
Word16 var_out;
|
||||
|
||||
if( var2 < 0) {
|
||||
var2 = -var2;
|
||||
var_out = lshl( var1, var2);
|
||||
if( var2 < 0)
|
||||
{
|
||||
var2 = -var2;
|
||||
var_out = lshl( var1, var2);
|
||||
}
|
||||
else
|
||||
{
|
||||
if( var2 == 0 || var1 == 0)
|
||||
{
|
||||
var_out = var1;
|
||||
}
|
||||
else if( var2 >= 16)
|
||||
{
|
||||
var_out = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
var_out = var1 >> 1;
|
||||
var_out = var_out & 0x7fff;
|
||||
var_out = var_out >> ( var2-1);
|
||||
}
|
||||
}
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].lshl--;
|
||||
#endif /* if WMOPS */
|
||||
BASOP_CHECK();
|
||||
|
||||
} else {
|
||||
if( var2 == 0 || var1 == 0) {
|
||||
var_out = var1;
|
||||
} else if( var2 >= 16) {
|
||||
var_out = 0;
|
||||
} else {
|
||||
var_out = var1 >> 1;
|
||||
var_out = var_out & 0x7fff;
|
||||
var_out = var_out >> ( var2-1);
|
||||
}
|
||||
}
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].lshr++;
|
||||
#endif /* if WMOPS */
|
||||
|
||||
BASOP_CHECK();
|
||||
|
||||
return( var_out);
|
||||
return( var_out);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -218,10 +217,10 @@ Word16 lshr( Word16 var1, Word16 var2) {
|
|||
*
|
||||
* Inputs :
|
||||
*
|
||||
* L_var1 32 bit long signed integer (Word32) whose value falls in
|
||||
* 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
|
||||
* var2 16 bit short signed integer (Word16) whose value falls in
|
||||
* the range 0xffff 8000 <= var2 <= 0x0000 7fff.
|
||||
*
|
||||
* Outputs :
|
||||
|
|
@ -230,37 +229,39 @@ Word16 lshr( Word16 var1, Word16 var2) {
|
|||
*
|
||||
* Return Value:
|
||||
*
|
||||
* L_var_out 32 bit long signed integer (Word32) whose value falls in
|
||||
* L_var_out 32 bit long signed integer (Word32) whose value falls in
|
||||
* the range 0x8000 0000 <= L_var_out <= 0x7fff ffff.
|
||||
*
|
||||
*****************************************************************************/
|
||||
Word32 L_lshl( Word32 L_var1, Word16 var2) {
|
||||
Word32 L_var_out=0;
|
||||
Word32 L_lshl( Word32 L_var1, Word16 var2)
|
||||
{
|
||||
Word32 L_var_out=0;
|
||||
|
||||
if( var2 < 0) {
|
||||
var2 = -var2;
|
||||
L_var_out = L_lshr( L_var1, var2);
|
||||
if( var2 < 0)
|
||||
{
|
||||
var2 = -var2;
|
||||
L_var_out = L_lshr( L_var1, var2);
|
||||
}
|
||||
else
|
||||
{
|
||||
if( var2 == 0 || L_var1 == 0)
|
||||
{
|
||||
L_var_out = L_var1;
|
||||
}
|
||||
else if( var2 >= 32)
|
||||
{
|
||||
L_var_out = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
L_var_out = L_var1 << var2;
|
||||
}
|
||||
}
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_lshr--;
|
||||
#endif /* if WMOPS */
|
||||
BASOP_CHECK();
|
||||
|
||||
} else {
|
||||
if( var2 == 0 || L_var1 == 0) {
|
||||
L_var_out = L_var1;
|
||||
} else if( var2 >= 32) {
|
||||
L_var_out = 0;
|
||||
} else {
|
||||
L_var_out = L_var1 << var2;
|
||||
}
|
||||
}
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_lshl++;
|
||||
#endif /* if WMOPS */
|
||||
|
||||
BASOP_CHECK();
|
||||
|
||||
return( L_var_out);
|
||||
return( L_var_out);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -280,10 +281,10 @@ Word32 L_lshl( Word32 L_var1, Word16 var2) {
|
|||
*
|
||||
* Inputs :
|
||||
*
|
||||
* L_var1 32 bit long signed integer (Word32) whose value falls in
|
||||
* 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
|
||||
* var2 16 bit short signed integer (Word16) whose value falls in
|
||||
* the range 0xffff 8000 <= var2 <= 0x0000 7fff.
|
||||
*
|
||||
* Outputs :
|
||||
|
|
@ -292,39 +293,41 @@ Word32 L_lshl( Word32 L_var1, Word16 var2) {
|
|||
*
|
||||
* Return Value:
|
||||
*
|
||||
* L_var_out 32 bit long signed integer (Word32) whose value falls in
|
||||
* L_var_out 32 bit long signed integer (Word32) whose value falls in
|
||||
* the range 0x8000 0000 <= L_var_out <= 0x7fff ffff.
|
||||
*
|
||||
*****************************************************************************/
|
||||
Word32 L_lshr( Word32 L_var1, Word16 var2) {
|
||||
Word32 L_var_out;
|
||||
Word32 L_lshr( Word32 L_var1, Word16 var2)
|
||||
{
|
||||
Word32 L_var_out;
|
||||
|
||||
if( var2 < 0) {
|
||||
var2 = -var2;
|
||||
L_var_out = L_lshl( L_var1, var2);
|
||||
if( var2 < 0)
|
||||
{
|
||||
var2 = -var2;
|
||||
L_var_out = L_lshl( L_var1, var2);
|
||||
}
|
||||
else
|
||||
{
|
||||
if( var2 == 0 || L_var1 == 0)
|
||||
{
|
||||
L_var_out = L_var1;
|
||||
}
|
||||
else if( var2 >= 32)
|
||||
{
|
||||
L_var_out = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
L_var_out = L_var1 >> 1;
|
||||
L_var_out = L_var_out & 0x7fffffff;
|
||||
L_var_out = L_var_out >> (var2 - 1);
|
||||
}
|
||||
}
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_lshl--;
|
||||
#endif /* if WMOPS */
|
||||
BASOP_CHECK();
|
||||
|
||||
} else {
|
||||
if( var2 == 0 || L_var1 == 0) {
|
||||
L_var_out = L_var1;
|
||||
} else if( var2 >= 32) {
|
||||
L_var_out = 0;
|
||||
} else {
|
||||
L_var_out = L_var1 >> 1;
|
||||
L_var_out = L_var_out & 0x7fffffff;
|
||||
L_var_out = L_var_out >> (var2 - 1);
|
||||
}
|
||||
}
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_lshr++;
|
||||
#endif /* if WMOPS */
|
||||
|
||||
BASOP_CHECK();
|
||||
|
||||
return( L_var_out);
|
||||
return( L_var_out);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -341,10 +344,10 @@ Word32 L_lshr( Word32 L_var1, Word16 var2) {
|
|||
*
|
||||
* Inputs :
|
||||
*
|
||||
* var1 16 bit short signed integer (Word16) whose value falls in
|
||||
* var1 16 bit short signed integer (Word16) whose value falls in
|
||||
* the range : 0xffff 8000 <= var1 <= 0x0000 7fff.
|
||||
*
|
||||
* var2 16 bit short signed integer (Word16) whose value falls in
|
||||
* var2 16 bit short signed integer (Word16) whose value falls in
|
||||
* the range : 0xffff 8000 <= var2 <= 0x0000 7fff.
|
||||
*
|
||||
* Outputs :
|
||||
|
|
@ -353,34 +356,26 @@ Word32 L_lshr( Word32 L_var1, Word16 var2) {
|
|||
*
|
||||
* Return Value :
|
||||
*
|
||||
* var_out 16 bit short signed integer (Word16) whose value falls in
|
||||
* var_out 16 bit short signed integer (Word16) whose value falls in
|
||||
* the range : 0xffff 8000 <= var_out <= 0x0000 7fff.
|
||||
*
|
||||
*****************************************************************************/
|
||||
Word16 shl_r( Word16 var1, Word16 var2){
|
||||
Word16 var_out;
|
||||
Word16 shl_r( Word16 var1, Word16 var2)
|
||||
{
|
||||
Word16 var_out;
|
||||
|
||||
if( var2 >= 0) {
|
||||
var_out = shl( var1, var2);
|
||||
if( var2 >= 0)
|
||||
{
|
||||
var_out = shl( var1, var2);
|
||||
}
|
||||
else
|
||||
{
|
||||
var2 = -var2;
|
||||
var_out = shr_r( var1, var2);
|
||||
}
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].shl--;
|
||||
#endif /* if WMOPS */
|
||||
|
||||
} else {
|
||||
var2 = -var2;
|
||||
var_out = shr_r( var1, var2);
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].shr_r--;
|
||||
#endif /* if WMOPS */
|
||||
}
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].shl_r++;
|
||||
#endif /* if WMOPS */
|
||||
|
||||
return( var_out);
|
||||
return( var_out);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -397,10 +392,10 @@ Word16 shl_r( Word16 var1, Word16 var2){
|
|||
*
|
||||
* Inputs :
|
||||
*
|
||||
* L_var1 32 bit long signed integer (Word32) whose value falls in
|
||||
* 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
|
||||
* var2 16 bit short signed integer (Word16) whose value falls in
|
||||
* the range : 0xffff 8000 <= var2 <= 0x0000 7fff.
|
||||
*
|
||||
* Outputs :
|
||||
|
|
@ -409,34 +404,26 @@ Word16 shl_r( Word16 var1, Word16 var2){
|
|||
*
|
||||
* Return Value :
|
||||
*
|
||||
* L_var_out 32 bit long signed integer (Word32) whose value falls in
|
||||
* L_var_out 32 bit long signed integer (Word32) whose value falls in
|
||||
* the range : 0x8000 0000 <= var_out <= 0x7fff ffff.
|
||||
*
|
||||
*****************************************************************************/
|
||||
Word32 L_shl_r( Word32 L_var1, Word16 var2) {
|
||||
Word32 var_out;
|
||||
Word32 L_shl_r( Word32 L_var1, Word16 var2)
|
||||
{
|
||||
Word32 var_out;
|
||||
|
||||
if( var2 >= 0) {
|
||||
var_out = L_shl( L_var1, var2);
|
||||
if( var2 >= 0)
|
||||
{
|
||||
var_out = L_shl( L_var1, var2);
|
||||
}
|
||||
else
|
||||
{
|
||||
var2 = -var2;
|
||||
var_out = L_shr_r( L_var1, var2);
|
||||
}
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_shl--;
|
||||
#endif /* if WMOPS */
|
||||
|
||||
} else {
|
||||
var2 = -var2;
|
||||
var_out = L_shr_r( L_var1, var2);
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_shr_r--;
|
||||
#endif /* if WMOPS */
|
||||
}
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_shl_r++;
|
||||
#endif /* if WMOPS */
|
||||
|
||||
return( var_out);
|
||||
return( var_out);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -461,7 +448,7 @@ Word32 L_shl_r( Word32 L_var1, Word16 var2) {
|
|||
*
|
||||
* Outputs :
|
||||
*
|
||||
* *var3 Points on a 16 bit short signed integer (Word16) whose
|
||||
* *var3 Points on a 16 bit short signed integer (Word16) whose
|
||||
* value will be 0 or 1.
|
||||
*
|
||||
* Return Value :
|
||||
|
|
@ -470,22 +457,16 @@ Word32 L_shl_r( Word32 L_var1, Word16 var2) {
|
|||
* the range : 0xffff 8000 <= var_out <= 0x0000 7fff.
|
||||
*
|
||||
*****************************************************************************/
|
||||
Word16 rotr( Word16 var1, Word16 var2, Word16 *var3) {
|
||||
Word16 var_out;
|
||||
Word16 rotr( Word16 var1, Word16 var2, Word16 *var3)
|
||||
{
|
||||
Word16 var_out;
|
||||
|
||||
*var3 = s_and( var1, 0x1);
|
||||
var_out = s_or( lshr( var1, 1),
|
||||
lshl( var2, 15));
|
||||
*var3 = s_and( var1, 0x1);
|
||||
var_out = s_or( lshr( var1, 1),
|
||||
lshl( var2, 15));
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].s_and--;
|
||||
multiCounter[currCounter].lshl--;
|
||||
multiCounter[currCounter].lshr--;
|
||||
multiCounter[currCounter].s_or--;
|
||||
multiCounter[currCounter].rotr++;
|
||||
#endif /* if WMOPS */
|
||||
|
||||
return( var_out);
|
||||
return( var_out);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -510,7 +491,7 @@ Word16 rotr( Word16 var1, Word16 var2, Word16 *var3) {
|
|||
*
|
||||
* Outputs :
|
||||
*
|
||||
* *var3 Points on a 16 bit short signed integer (Word16) whose
|
||||
* *var3 Points on a 16 bit short signed integer (Word16) whose
|
||||
* value will be 0 or 1.
|
||||
*
|
||||
* Return Value :
|
||||
|
|
@ -519,23 +500,17 @@ Word16 rotr( Word16 var1, Word16 var2, Word16 *var3) {
|
|||
* the range : 0xffff 8000 <= var_out <= 0x0000 7fff.
|
||||
*
|
||||
*****************************************************************************/
|
||||
Word16 rotl( Word16 var1, Word16 var2, Word16 *var3) {
|
||||
Word16 var_out;
|
||||
Word16 rotl( Word16 var1, Word16 var2, Word16 *var3)
|
||||
{
|
||||
Word16 var_out;
|
||||
|
||||
*var3 = lshr( var1, 15);
|
||||
*var3 = lshr( var1, 15);
|
||||
|
||||
var_out = s_or( lshl( var1, 1),
|
||||
s_and( var2, 0x1));
|
||||
var_out = s_or( lshl( var1, 1),
|
||||
s_and( var2, 0x1));
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].lshr--;
|
||||
multiCounter[currCounter].s_and--;
|
||||
multiCounter[currCounter].lshl--;
|
||||
multiCounter[currCounter].s_or--;
|
||||
multiCounter[currCounter].rotl++;
|
||||
#endif /* if WMOPS */
|
||||
|
||||
return( var_out);
|
||||
return( var_out);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -560,7 +535,7 @@ Word16 rotl( Word16 var1, Word16 var2, Word16 *var3) {
|
|||
*
|
||||
* Outputs :
|
||||
*
|
||||
* *var3 Points on a 16 bit short signed integer (Word16) whose
|
||||
* *var3 Points on a 16 bit short signed integer (Word16) whose
|
||||
* value will be 0 or 1.
|
||||
*
|
||||
* Return Value :
|
||||
|
|
@ -569,25 +544,17 @@ Word16 rotl( Word16 var1, Word16 var2, Word16 *var3) {
|
|||
* the range : 0x8000 0000 <= L_var_out <= 0x7fff ffff.
|
||||
*
|
||||
*****************************************************************************/
|
||||
Word32 L_rotr( Word32 L_var1, Word16 var2, Word16 *var3) {
|
||||
Word32 L_var_out;
|
||||
Word32 L_rotr( Word32 L_var1, Word16 var2, Word16 *var3)
|
||||
{
|
||||
Word32 L_var_out;
|
||||
|
||||
*var3 = s_and( extract_l( L_var1), 0x1);
|
||||
*var3 = s_and( extract_l( L_var1), 0x1);
|
||||
|
||||
L_var_out = L_or( L_lshr( L_var1, 1),
|
||||
L_lshl( L_deposit_l( var2), 31));
|
||||
L_var_out = L_or( L_lshr( L_var1, 1),
|
||||
L_lshl( L_deposit_l( var2), 31));
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].extract_l--;
|
||||
multiCounter[currCounter].s_and--;
|
||||
multiCounter[currCounter].L_deposit_l--;
|
||||
multiCounter[currCounter].L_lshl--;
|
||||
multiCounter[currCounter].L_lshr--;
|
||||
multiCounter[currCounter].L_or--;
|
||||
multiCounter[currCounter].L_rotr++;
|
||||
#endif /* if WMOPS */
|
||||
|
||||
return( L_var_out);
|
||||
return( L_var_out);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -612,7 +579,7 @@ Word32 L_rotr( Word32 L_var1, Word16 var2, Word16 *var3) {
|
|||
*
|
||||
* Outputs :
|
||||
*
|
||||
* *var3 Points on a 16 bit short signed integer (Word16) whose
|
||||
* *var3 Points on a 16 bit short signed integer (Word16) whose
|
||||
* value will be 0 or 1.
|
||||
*
|
||||
* Return Value :
|
||||
|
|
@ -621,25 +588,17 @@ Word32 L_rotr( Word32 L_var1, Word16 var2, Word16 *var3) {
|
|||
* the range : 0x8000 0000 <= L_var_out <= 0x7fff ffff.
|
||||
*
|
||||
*****************************************************************************/
|
||||
Word32 L_rotl( Word32 L_var1, Word16 var2, Word16 *var3) {
|
||||
Word32 L_var_out;
|
||||
Word32 L_rotl( Word32 L_var1, Word16 var2, Word16 *var3)
|
||||
{
|
||||
Word32 L_var_out;
|
||||
|
||||
*var3 = extract_l( L_lshr( L_var1, 31));
|
||||
*var3 = extract_l( L_lshr( L_var1, 31));
|
||||
|
||||
L_var_out = L_or( L_lshl( L_var1, 1),
|
||||
L_deposit_l( s_and( var2, 0x1)));
|
||||
L_var_out = L_or( L_lshl( L_var1, 1),
|
||||
L_deposit_l( s_and( var2, 0x1)));
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_lshr--;
|
||||
multiCounter[currCounter].extract_l--;
|
||||
multiCounter[currCounter].s_and--;
|
||||
multiCounter[currCounter].L_deposit_l--;
|
||||
multiCounter[currCounter].L_lshl--;
|
||||
multiCounter[currCounter].L_or--;
|
||||
multiCounter[currCounter].L_rotl++;
|
||||
#endif /* if WMOPS */
|
||||
|
||||
return( L_var_out);
|
||||
return( L_var_out);
|
||||
}
|
||||
|
||||
|
||||
165
src/libs/libevs/basic_op/enh1632.h → src/libs/libevs/lib_com/enh1632.h
Executable file → Normal file
165
src/libs/libevs/basic_op/enh1632.h → src/libs/libevs/lib_com/enh1632.h
Executable file → Normal file
|
|
@ -9,13 +9,13 @@
|
|||
|
||||
History:
|
||||
07 Nov 04 v2.0 Incorporation of new 32-bit / 40-bit / control
|
||||
operators for the ITU-T Standard Tool Library as
|
||||
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.
|
||||
Some counters incrementations were missing (s_and,
|
||||
s_or, s_xor).
|
||||
Some counters incrementations were missing (s_and,
|
||||
s_or, s_xor).
|
||||
30 Nov 09 v2.3 saturate() removed
|
||||
|
||||
============================================================================
|
||||
|
|
@ -36,13 +36,6 @@
|
|||
#include "stl.h"
|
||||
|
||||
|
||||
#if (WMOPS)
|
||||
#include "count.h"
|
||||
extern BASIC_OP multiCounter[MAXCOUNTERS];
|
||||
extern int currCounter;
|
||||
#endif /* if WMOPS */
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Prototypes for enhanced 16/32 bit arithmetic operators
|
||||
|
|
@ -82,7 +75,7 @@ Word32 L_rotl( Word32 var1, Word16 var2, Word16 *var3);
|
|||
*
|
||||
* Inputs :
|
||||
*
|
||||
* var1 16 bit short signed integer (Word16) whose value falls in
|
||||
* var1 16 bit short signed integer (Word16) whose value falls in
|
||||
* the range : 0x8000 <= var1 <= 0x7fff.
|
||||
*
|
||||
* var2 16 bit short signed integer (Word16) whose value falls in
|
||||
|
|
@ -98,19 +91,17 @@ Word32 L_rotl( Word32 var1, Word16 var2, Word16 *var3);
|
|||
* the range : 0x8000 <= L_var_out <= 0x7fff.
|
||||
*
|
||||
*****************************************************************************/
|
||||
static __inline Word16 s_max( Word16 var1, Word16 var2) {
|
||||
Word16 var_out;
|
||||
static __inline Word16 s_max( Word16 var1, Word16 var2)
|
||||
{
|
||||
Word16 var_out;
|
||||
|
||||
if( var1 >= var2)
|
||||
var_out = var1;
|
||||
else
|
||||
var_out = var2;
|
||||
if( var1 >= var2)
|
||||
var_out = var1;
|
||||
else
|
||||
var_out = var2;
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].s_max++;
|
||||
#endif /* if WMOPS */
|
||||
|
||||
return( var_out);
|
||||
return( var_out);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -126,10 +117,10 @@ static __inline Word16 s_max( Word16 var1, Word16 var2) {
|
|||
*
|
||||
* Inputs :
|
||||
*
|
||||
* var1 16 bit short signed integer (Word16) whose value falls in
|
||||
* var1 16 bit short signed integer (Word16) whose value falls in
|
||||
* the range : 0x8000 <= var1 <= 0x7fff.
|
||||
*
|
||||
* var2 16 bit short signed integer (Word16) whose value falls in
|
||||
* var2 16 bit short signed integer (Word16) whose value falls in
|
||||
* the range : 0x8000 <= var2 <= 0x7fff.
|
||||
*
|
||||
* Outputs :
|
||||
|
|
@ -138,23 +129,21 @@ static __inline Word16 s_max( Word16 var1, Word16 var2) {
|
|||
*
|
||||
* Return Value :
|
||||
*
|
||||
* var_out 16 bit short signed integer (Word16) whose value falls in
|
||||
* var_out 16 bit short signed integer (Word16) whose value falls in
|
||||
* the range : 0x8000 <= var_out <= 0x7fff.
|
||||
*
|
||||
*****************************************************************************/
|
||||
static __inline Word16 s_min( Word16 var1, Word16 var2) {
|
||||
Word16 var_out;
|
||||
static __inline Word16 s_min( Word16 var1, Word16 var2)
|
||||
{
|
||||
Word16 var_out;
|
||||
|
||||
if( var1 <= var2)
|
||||
var_out = var1;
|
||||
else
|
||||
var_out = var2;
|
||||
if( var1 <= var2)
|
||||
var_out = var1;
|
||||
else
|
||||
var_out = var2;
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].s_min++;
|
||||
#endif /* if WMOPS */
|
||||
|
||||
return( var_out);
|
||||
return( var_out);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -186,19 +175,17 @@ static __inline Word16 s_min( Word16 var1, Word16 var2) {
|
|||
* range : 0x8000 0000 <= L_var_out <= 0x7fff ffff.
|
||||
*
|
||||
*****************************************************************************/
|
||||
static __inline Word32 L_max( Word32 L_var1, Word32 L_var2) {
|
||||
Word32 L_var_out;
|
||||
static __inline Word32 L_max( Word32 L_var1, Word32 L_var2)
|
||||
{
|
||||
Word32 L_var_out;
|
||||
|
||||
if( L_var1 >= L_var2)
|
||||
L_var_out = L_var1;
|
||||
else
|
||||
L_var_out = L_var2;
|
||||
if( L_var1 >= L_var2)
|
||||
L_var_out = L_var1;
|
||||
else
|
||||
L_var_out = L_var2;
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_max++;
|
||||
#endif /* if WMOPS */
|
||||
|
||||
return( L_var_out);
|
||||
return( L_var_out);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -230,19 +217,17 @@ static __inline Word32 L_max( Word32 L_var1, Word32 L_var2) {
|
|||
* range : 0x8000 0000 <= L_var_out <= 0x7fff ffff.
|
||||
*
|
||||
*****************************************************************************/
|
||||
static __inline Word32 L_min( Word32 L_var1, Word32 L_var2) {
|
||||
Word32 L_var_out;
|
||||
static __inline Word32 L_min( Word32 L_var1, Word32 L_var2)
|
||||
{
|
||||
Word32 L_var_out;
|
||||
|
||||
if( L_var1 <= L_var2)
|
||||
L_var_out = L_var1;
|
||||
else
|
||||
L_var_out = L_var2;
|
||||
if( L_var1 <= L_var2)
|
||||
L_var_out = L_var1;
|
||||
else
|
||||
L_var_out = L_var2;
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_min++;
|
||||
#endif /* if WMOPS */
|
||||
|
||||
return( L_var_out);
|
||||
return( L_var_out);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -283,16 +268,14 @@ static __inline Word32 L_min( Word32 L_var1, Word32 L_var2) {
|
|||
* falls in the range 0xffff 8000 <= var_out <= 0x0000 7fff.
|
||||
*
|
||||
*****************************************************************************/
|
||||
static __inline Word16 s_and( Word16 var1, Word16 var2) {
|
||||
Word16 var_out;
|
||||
static __inline Word16 s_and( Word16 var1, Word16 var2)
|
||||
{
|
||||
Word16 var_out;
|
||||
|
||||
var_out = var1 & var2;
|
||||
var_out = var1 & var2;
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].s_and++;
|
||||
#endif /* if WMOPS */
|
||||
|
||||
return( var_out);
|
||||
return( var_out);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -325,16 +308,14 @@ static __inline Word16 s_and( Word16 var1, Word16 var2) {
|
|||
* falls in the range 0x8000 0000 <= L_var_out <= 0x7fff ffff.
|
||||
*
|
||||
*****************************************************************************/
|
||||
static __inline Word32 L_and( Word32 L_var1, Word32 L_var2) {
|
||||
Word32 L_var_out;
|
||||
static __inline Word32 L_and( Word32 L_var1, Word32 L_var2)
|
||||
{
|
||||
Word32 L_var_out;
|
||||
|
||||
L_var_out = L_var1 & L_var2;
|
||||
L_var_out = L_var1 & L_var2;
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_and++;
|
||||
#endif /* if WMOPS */
|
||||
|
||||
return( L_var_out);
|
||||
return( L_var_out);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -367,16 +348,14 @@ static __inline Word32 L_and( Word32 L_var1, Word32 L_var2) {
|
|||
* falls in the range 0xffff 8000 <= var_out <= 0x0000 7fff.
|
||||
*
|
||||
*****************************************************************************/
|
||||
static __inline Word16 s_or( Word16 var1, Word16 var2) {
|
||||
Word16 var_out;
|
||||
static __inline Word16 s_or( Word16 var1, Word16 var2)
|
||||
{
|
||||
Word16 var_out;
|
||||
|
||||
var_out = var1 | var2;
|
||||
var_out = var1 | var2;
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].s_or++;
|
||||
#endif /* if WMOPS */
|
||||
|
||||
return( var_out);
|
||||
return( var_out);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -409,17 +388,15 @@ static __inline Word16 s_or( Word16 var1, Word16 var2) {
|
|||
* falls in the range 0x8000 0000 <= L_var_out <= 0x7fff ffff.
|
||||
*
|
||||
*****************************************************************************/
|
||||
static __inline Word32 L_or( Word32 L_var1, Word32 L_var2) {
|
||||
static __inline Word32 L_or( Word32 L_var1, Word32 L_var2)
|
||||
{
|
||||
|
||||
Word32 L_var_out;
|
||||
Word32 L_var_out;
|
||||
|
||||
L_var_out = L_var1 | L_var2;
|
||||
L_var_out = L_var1 | L_var2;
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_or++;
|
||||
#endif /* if WMOPS */
|
||||
|
||||
return( L_var_out);
|
||||
return( L_var_out);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -452,16 +429,14 @@ static __inline Word32 L_or( Word32 L_var1, Word32 L_var2) {
|
|||
* falls in the range 0xffff 8000 <= var_out <= 0x0000 7fff.
|
||||
*
|
||||
*****************************************************************************/
|
||||
static __inline Word16 s_xor( Word16 var1, Word16 var2) {
|
||||
Word16 var_out;
|
||||
static __inline Word16 s_xor( Word16 var1, Word16 var2)
|
||||
{
|
||||
Word16 var_out;
|
||||
|
||||
var_out = var1 ^ var2;
|
||||
var_out = var1 ^ var2;
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].s_xor++;
|
||||
#endif /* if WMOPS */
|
||||
|
||||
return( var_out);
|
||||
return( var_out);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -494,16 +469,14 @@ static __inline Word16 s_xor( Word16 var1, Word16 var2) {
|
|||
* falls in the range 0x8000 0000 <= L_var_out <= 0x7fff ffff.
|
||||
*
|
||||
*****************************************************************************/
|
||||
static __inline Word32 L_xor( Word32 L_var1, Word32 L_var2) {
|
||||
Word32 L_var_out;
|
||||
static __inline Word32 L_xor( Word32 L_var1, Word32 L_var2)
|
||||
{
|
||||
Word32 L_var_out;
|
||||
|
||||
L_var_out = L_var1 ^ L_var2;
|
||||
L_var_out = L_var1 ^ L_var2;
|
||||
|
||||
#if (WMOPS)
|
||||
multiCounter[currCounter].L_xor++;
|
||||
#endif /* if WMOPS */
|
||||
|
||||
return( L_var_out);
|
||||
return( L_var_out);
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -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 */
|
||||
|
||||
|
||||
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -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 */
|
||||
}
|
||||
|
|
@ -0,0 +1,133 @@
|
|||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.443 Nov 13, 2018. Version 12.11.0 / 13.7.0 / 14.3.0 / 15.1.0
|
||||
====================================================================================*/
|
||||
|
||||
#include <math.h>
|
||||
#include "options.h"
|
||||
#include "cnst.h"
|
||||
#include "rom_com.h"
|
||||
#include "prot.h"
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------*
|
||||
* env_adj()
|
||||
*
|
||||
* Adjust the band energies of noise-fill and low resolution bands
|
||||
*--------------------------------------------------------------------------*/
|
||||
|
||||
void env_adj (
|
||||
const short *pulses, /* i : number of pulses per band */
|
||||
const short length, /* i : length of spectrum */
|
||||
const short last_sfm, /* i : index of the last band */
|
||||
float *adj, /* o : adjustment factors for the envelope */
|
||||
const float env_stab, /* i : Envelope stability parameter */
|
||||
const short *sfmsize /* i : Band widths */
|
||||
)
|
||||
{
|
||||
short i, j, group;
|
||||
int npul;
|
||||
short att_state;
|
||||
short start, len;
|
||||
float tmp;
|
||||
float gain_adj;
|
||||
short idx;
|
||||
|
||||
att_state = 0;
|
||||
len = 0;
|
||||
start = 0;
|
||||
|
||||
/* Find attenuation levels */
|
||||
for( i = 0; i <= last_sfm ; i++ )
|
||||
{
|
||||
group = (sfmsize[i] >> 3) - 1;
|
||||
npul = pulses[i];
|
||||
|
||||
if( length == L_FRAME32k )
|
||||
{
|
||||
if( npul == 0 )
|
||||
{
|
||||
/* Noise filled band */
|
||||
if ( group <= 1 )
|
||||
{
|
||||
if ( i > 0 && pulses[i-1] != 0 && pulses[i+1] != 0 )
|
||||
{
|
||||
adj[i] = 0.36f;
|
||||
}
|
||||
else if ( i > 0 && ( pulses[i-1] == 0 || pulses[i+1] == 0) )
|
||||
{
|
||||
adj[i] = 0.54f;
|
||||
}
|
||||
else
|
||||
{
|
||||
adj[i] = 0.72f;
|
||||
}
|
||||
}
|
||||
else if (i < last_sfm)
|
||||
{
|
||||
if ( pulses[i-1] != 0 && pulses[i+1] != 0 )
|
||||
{
|
||||
adj[i] = 0.54f;
|
||||
}
|
||||
else
|
||||
{
|
||||
adj[i] = 0.72f;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
adj[i] = 0.72f;
|
||||
}
|
||||
|
||||
if( att_state == 0 )
|
||||
{
|
||||
start = i;
|
||||
}
|
||||
|
||||
len++;
|
||||
att_state = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
adj[i] = 1.0f;
|
||||
if(att_state == 1) /* End of attenuation region found */
|
||||
{
|
||||
tmp = min(1, max(0, len-ENV_ADJ_START)*(1.0f/ENV_ADJ_INCL));
|
||||
for( j = start; j < i ; j++ )
|
||||
{
|
||||
adj[j] = max(tmp + (1-tmp)*adj[j],env_stab);
|
||||
}
|
||||
len = 0;
|
||||
att_state = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* length == L_FRAME16k */
|
||||
else
|
||||
{
|
||||
/* Calculate low accuracy band attenuation */
|
||||
gain_adj = 1.0f;
|
||||
if( npul > 0 && npul < MAX_P_ATT )
|
||||
{
|
||||
idx = (short)(npul * att_step[group] + 0.5f) - 1;
|
||||
if( idx < MAX_P_ATT )
|
||||
{
|
||||
gain_adj = gain_att[idx];
|
||||
}
|
||||
}
|
||||
adj[i] = gain_adj;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if the sequence ended with an attenuation region */
|
||||
if( att_state == 1 )
|
||||
{
|
||||
tmp = min(1, max(0, len-ENV_ADJ_START)*(1.0f/ENV_ADJ_INCL));
|
||||
|
||||
for( j = start; j < i ; j++ )
|
||||
{
|
||||
adj[j] = max(tmp + (1-tmp)*adj[j],env_stab);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
@ -1,158 +0,0 @@
|
|||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#include "options.h" /* Compilation switches */
|
||||
#include "cnst_fx.h" /* Common constants */
|
||||
#include "rom_com_fx.h" /* Static table prototypes */
|
||||
#include "prot_fx.h" /* Function prototypes */
|
||||
#include "stl.h" /* required by wmc_tool */
|
||||
|
||||
/*--------------------------------------------------------------------------*
|
||||
* env_adj()
|
||||
*
|
||||
* Adjust the band energies of noise-fill and low resolution bands
|
||||
*--------------------------------------------------------------------------*/
|
||||
void env_adj_fx
|
||||
(
|
||||
const Word16 *pulses, /* i : number of pulses per band Q0 */
|
||||
const Word16 length, /* i : length of spectrum Q0 */
|
||||
const Word16 last_sfm, /* i : index of the last band Q0 */
|
||||
Word16 *adj, /* o : adjustment factors for the envelope Q15 */
|
||||
const Word16 env_stab, /* i : envelope stability Q15 */
|
||||
const Word16 *sfmsize /* i : subband sizes Q0 */
|
||||
)
|
||||
{
|
||||
Word16 i, j, group;
|
||||
Word16 npul;
|
||||
Word16 att_state;
|
||||
Word16 start, len;
|
||||
Word16 tmp, tmp_diff;
|
||||
Word16 gain_adj;
|
||||
Word16 idx;
|
||||
|
||||
att_state = 0;
|
||||
move16();
|
||||
len = 0;
|
||||
move16();
|
||||
start = 0;
|
||||
move16();
|
||||
|
||||
/* Find attenuation levels */
|
||||
FOR( i = 0; i <= last_sfm ; i++ )
|
||||
{
|
||||
group = sub(shr(sfmsize[i],3),1);
|
||||
npul = pulses[i];
|
||||
move16();
|
||||
|
||||
IF( sub(length, L_FRAME32k) == 0 )
|
||||
{
|
||||
|
||||
IF( npul == 0 )
|
||||
{
|
||||
/* Noise filled band */
|
||||
IF ( sub(group,1) <= 0 )
|
||||
{
|
||||
test();
|
||||
test();
|
||||
test();
|
||||
test();
|
||||
IF ( i > 0 && pulses[i-1] != 0 && pulses[i+1] != 0 )
|
||||
{
|
||||
adj[i] = 11796; /* Q15, 0.36f */ move16();
|
||||
}
|
||||
ELSE IF ( i > 0 && ( pulses[i-1] == 0 || pulses[i+1] == 0) )
|
||||
{
|
||||
adj[i] = 17695; /* Q15, 0.54f */ move16();
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
adj[i] = 23593; /* Q15, 0.72f */ move16();
|
||||
}
|
||||
}
|
||||
ELSE IF ( sub(i,last_sfm) < 0 )
|
||||
{
|
||||
test();
|
||||
IF ( pulses[i-1] != 0 && pulses[i+1] != 0 )
|
||||
{
|
||||
adj[i] = 17695; /* Q15, 0.54f */ move16();
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
adj[i] = 23593; /* Q15, 0.72f */ move16();
|
||||
}
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
adj[i] = 23593; /* Q15, 0.72f */ move16();
|
||||
}
|
||||
|
||||
if( att_state == 0 )
|
||||
{
|
||||
start = i;
|
||||
move16();
|
||||
}
|
||||
|
||||
len = add(len,1);
|
||||
move16();
|
||||
att_state = 1;
|
||||
move16();
|
||||
}
|
||||
ELSE
|
||||
{
|
||||
adj[i] = MAX_16; /* Q15, 1.0f (saturated) */
|
||||
IF( sub(att_state, 1) == 0 ) /* End of attenuation region found */
|
||||
{
|
||||
/* tmp = min(1, max(0, len-ENV_ADJ_START)*(1.0f/ENV_ADJ_INCL)); */
|
||||
tmp = round_fx(L_shl(L_mult0(s_max( 0, sub(len, ENV_ADJ_START_FX)), ENV_ADJ_INV_INCL_FX),16)); /* Q15 (15+16-16) */
|
||||
tmp_diff = sub(MAX_16, tmp); /* Q15 */ move16();
|
||||
FOR( j = start; j < i ; j++ )
|
||||
{
|
||||
/* adj[j] = max(tmp + (1-tmp)*adj[j],env_stab); */
|
||||
adj[j] = s_max(add(tmp, mult(tmp_diff, adj[j])), env_stab); /* Q15 (15+15-15) */ move16();
|
||||
}
|
||||
len = 0;
|
||||
move16();
|
||||
att_state = 0;
|
||||
move16();
|
||||
}
|
||||
}
|
||||
}
|
||||
/* length == L_FRAME16k */
|
||||
ELSE
|
||||
{
|
||||
|
||||
/* Calculate low accuracy band attenuation */
|
||||
gain_adj = 32767; /* Q15, 1.0f (saturated) */ move16();
|
||||
|
||||
test();
|
||||
IF( npul > 0 && sub(npul, MAX_P_ATT) < 0 )
|
||||
{
|
||||
/*idx = (short)(npul * att_step[group] + 0.5f) - 1; */
|
||||
idx = sub(mult_r(shl(npul,2),att_step_fx[group]), 1); /* Q0 (2+13+1-16) */
|
||||
if( sub(idx, MAX_P_ATT) < 0 )
|
||||
{
|
||||
gain_adj = gain_att_fx[idx]; /* Q15 */ move16();
|
||||
}
|
||||
}
|
||||
adj[i] = gain_adj;
|
||||
move16();
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if the sequence ended with an attenuation region */
|
||||
IF( sub(att_state, 1) == 0 )
|
||||
{
|
||||
/* tmp = min(1, max(0, len-ENV_ADJ_START)*(1.0f/ENV_ADJ_INCL)); */
|
||||
tmp = round_fx(L_shl(L_mult0(s_max( 0, sub(len, ENV_ADJ_START_FX)), ENV_ADJ_INV_INCL_FX),16)); /* Q15 (15+16-16) */
|
||||
tmp_diff = sub(MAX_16, tmp); /* Q15 */ move16();
|
||||
FOR( j = start; j < i ; j++ )
|
||||
{
|
||||
|
||||
/* adj[j] = max(tmp + (1-tmp)*adj[j],env_stab); */
|
||||
adj[j] = s_max(add(tmp, mult(tmp_diff, adj[j])), env_stab); /* Q15 (15+15-15) */ move16();
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
122
src/libs/libevs/lib_com/env_stab_fx.cpp → src/libs/libevs/lib_com/env_stab.cpp
Executable file → Normal file
122
src/libs/libevs/lib_com/env_stab_fx.cpp → src/libs/libevs/lib_com/env_stab.cpp
Executable file → Normal file
|
|
@ -1,30 +1,31 @@
|
|||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
EVS Codec 3GPP TS26.443 Nov 13, 2018. Version 12.11.0 / 13.7.0 / 14.3.0 / 15.1.0
|
||||
====================================================================================*/
|
||||
|
||||
#include "options.h" /* Compilation switches */
|
||||
#include "cnst_fx.h" /* Common constants */
|
||||
#include "prot_fx.h" /* Function prototypes */
|
||||
#include "rom_com_fx.h" /* Static table prototypes */
|
||||
#include "stl.h" /* required by wmc_tool */
|
||||
#include "options.h"
|
||||
#include "cnst.h"
|
||||
#include "prot.h"
|
||||
#include "rom_com.h"
|
||||
#include <math.h>
|
||||
|
||||
/*--------------------------------------------------------------------------*
|
||||
* Local constants
|
||||
*--------------------------------------------------------------------------*/
|
||||
|
||||
#define ENV_STAB_SMO_HO 10 /* number of hangover frames when switching from music to speech state */
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* Function env_stability_fx */
|
||||
/* ~~~~~~~~~~~~~~~~~~~~~ */
|
||||
/* Function env_stability() */
|
||||
/* ~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
||||
/* */
|
||||
/* Envelope stability measure */
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
Word16 env_stability_fx( /* in Q15 */
|
||||
const Word16 *ynrm, /*i: Norm vector for current frame */
|
||||
const Word16 nb_sfm, /*i: Number of sub-bands */
|
||||
Word16 *mem_norm, /*i/o: Norm vector memory from past frame */
|
||||
Word16 *mem_env_delta /*i/o: Envelope stability memory for smoothing in Q12 */
|
||||
float env_stability(
|
||||
const short *ynrm, /*i : Norm vector for current frame */
|
||||
const short nb_sfm, /*i : Number of sub-bands */
|
||||
short *mem_norm, /*i/o: Norm vector memory from past frame */
|
||||
float *mem_env_delta /*i/o: Envelope stability memory for smoothing*/
|
||||
)
|
||||
{
|
||||
Word16 env_delta;
|
||||
|
|
@ -35,21 +36,21 @@ Word16 env_stability_fx( /* in Q15 */
|
|||
Word16 exp, exp2;
|
||||
Word32 L_tmp, L_env_delta;
|
||||
Word16 inv_nb_sfm;
|
||||
float env_stab_f;
|
||||
|
||||
/* Calculate envelope stability parameter */
|
||||
L_env_delta = L_deposit_l(0);
|
||||
FOR (i = 0; i < nb_sfm; i++)
|
||||
for (i = 0; i < nb_sfm; i++)
|
||||
{
|
||||
tmp = sub(mem_norm[i],ynrm[i]);
|
||||
L_env_delta = L_mac0(L_env_delta, tmp, tmp);
|
||||
mem_norm[i] = ynrm[i];
|
||||
move16();
|
||||
}
|
||||
|
||||
inv_nb_sfm = 19418; /* Q19 */ move16();
|
||||
inv_nb_sfm = 19418; /* Q19 */
|
||||
if (nb_sfm == 26)
|
||||
{
|
||||
inv_nb_sfm = 20165; /* Q19 */ move16();
|
||||
inv_nb_sfm = 20165; /* Q19 */
|
||||
}
|
||||
exp = norm_l(L_env_delta);
|
||||
L_env_delta = Mult_32_16(L_shl(L_env_delta, exp), inv_nb_sfm); /* 0+exp+19-15 */
|
||||
|
|
@ -70,12 +71,13 @@ Word16 env_stability_fx( /* in Q15 */
|
|||
|
||||
*mem_env_delta = round_fx(L_tmp); /* Q12 */
|
||||
Overflow = 0;
|
||||
move16();
|
||||
env_delta = round_fx(L_shl(L_tmp, 1)); /* Q13 */
|
||||
|
||||
IF (Overflow != 0) /* Saturated due to the above up-shifting operation. */
|
||||
if (Overflow != 0) /* Saturated due to the above up-shifting operation. */
|
||||
{
|
||||
return stab_trans_fx[L_STAB_TBL-1]; /* The highest quantized index. */
|
||||
env_stab = stab_trans_fx[L_STAB_TBL-1]; /* The highest quantized index. */
|
||||
env_stab_f = ((float)env_stab)/32768.0f; /* Convert env_stab(Q15) to float */
|
||||
return env_stab_f;
|
||||
}
|
||||
|
||||
/* If tmp_stab > (D_STAB_TBL*L_STAB_TBL + M_STAB_TBL), i.e., 0.103138*10+2.51757=3.603137,
|
||||
|
|
@ -91,26 +93,27 @@ Word16 env_stability_fx( /* in Q15 */
|
|||
#error env_stability_fx: Use more efficient usquant()
|
||||
#endif
|
||||
tmp_stab = sub(tmp_stab, HALF_D_STAB_TBL_FX); /* in Q13 */
|
||||
FOR (i = 0; i < L_STAB_TBL-1; i++)
|
||||
for (i = 0; i < L_STAB_TBL-1; i++)
|
||||
{
|
||||
IF (tmp_stab < 0)
|
||||
if (tmp_stab < 0)
|
||||
{
|
||||
BREAK;
|
||||
break;
|
||||
}
|
||||
ELSE
|
||||
else
|
||||
{
|
||||
tmp_stab = sub(tmp_stab, D_STAB_TBL_FX); /* in Q13 */
|
||||
}
|
||||
}
|
||||
|
||||
env_stab = stab_trans_fx[i];
|
||||
move16();
|
||||
if(sub(env_delta, M_STAB_TBL_FX) < 0)
|
||||
{
|
||||
env_stab = sub(0x7FFF,stab_trans_fx[i]);
|
||||
}
|
||||
|
||||
return env_stab;
|
||||
env_stab_f = ((float)env_stab)/32768.0f; /* Convert env_stab(Q15) to float */
|
||||
|
||||
return env_stab_f;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*
|
||||
|
|
@ -118,70 +121,47 @@ Word16 env_stability_fx( /* in Q15 */
|
|||
*
|
||||
*
|
||||
*--------------------------------------------------------------------------*/
|
||||
Word16 env_stab_smo_fx( /* Q0 */
|
||||
Word16 env_stab, /*i : env_stab value Q15 */
|
||||
Word16 *env_stab_state_p, /*i/o: env_stab state probabilities Q15 */
|
||||
Word16 *ho_cnt /*i/o: hangover counter for speech state */
|
||||
|
||||
float env_stab_smo(
|
||||
float env_stab, /*i : env_stab value */
|
||||
float *env_stab_state_p, /*i/o: env_stab state probabilities */
|
||||
short *ho_cnt /*i/o: hangover counter for speech state */
|
||||
)
|
||||
{
|
||||
Word16 state, prev_state;
|
||||
Word16 maxval, pp[NUM_ENV_STAB_PLC_STATES], pa[NUM_ENV_STAB_PLC_STATES];
|
||||
Word16 i;
|
||||
Word16 tmp, sum, exp;
|
||||
|
||||
short state, prev_state;
|
||||
float maxval, pp[NUM_ENV_STAB_PLC_STATES], pa[NUM_ENV_STAB_PLC_STATES];
|
||||
/* get previous state */
|
||||
prev_state = maximum_fx(env_stab_state_p, NUM_ENV_STAB_PLC_STATES, &maxval);
|
||||
prev_state = maximum(env_stab_state_p,NUM_ENV_STAB_PLC_STATES,&maxval);
|
||||
|
||||
/* assume two states: speech(0), music(1) */
|
||||
/* set a posteriori likelihoods for the two states according to env_stab */
|
||||
/* re-scale. Unclear if needed */
|
||||
/* env_stab = (env_stab - stab_trans_fx[L_STAB_TBL-1])/(1-2*stab_trans_fx[L_STAB_TBL-1]); */
|
||||
tmp = sub(env_stab, stab_trans_fx[L_STAB_TBL-1]);
|
||||
tmp = round_fx(L_shl(L_mult(tmp, INV_STAB_TRANS_FX), 1)); /* Q15 */
|
||||
|
||||
pp[0] = sub(32767, tmp);
|
||||
move16(); /* 1 in Q15 */
|
||||
pp[1] = tmp;
|
||||
move16();
|
||||
env_stab = (env_stab - stab_trans[L_STAB_TBL-1])/(1-2*stab_trans[L_STAB_TBL-1]);
|
||||
pp[0] = 1.0f-env_stab;
|
||||
pp[1] = env_stab;
|
||||
|
||||
/* calculate a priori likelihoods */
|
||||
pa[0] = round_fx(Dot_product(env_stab_tp_fx[0], env_stab_state_p, NUM_ENV_STAB_PLC_STATES)); /* Q15*/
|
||||
pa[1] = round_fx(Dot_product(env_stab_tp_fx[1], env_stab_state_p, NUM_ENV_STAB_PLC_STATES));
|
||||
pa[0] = dotp(env_stab_tp[0],env_stab_state_p,NUM_ENV_STAB_PLC_STATES);
|
||||
pa[1] = dotp(env_stab_tp[1],env_stab_state_p,NUM_ENV_STAB_PLC_STATES);
|
||||
|
||||
/* multiply elementwise with a posteriori likelihoods */
|
||||
sum = 0;
|
||||
move16();
|
||||
FOR (i = 0; i < NUM_ENV_STAB_PLC_STATES; i++)
|
||||
{
|
||||
env_stab_state_p[i] = mult_r(pa[i], pp[i]);
|
||||
move16(); /* Q15 */
|
||||
sum = add(sum, env_stab_state_p[i]);
|
||||
}
|
||||
v_mult(pa,pp,env_stab_state_p,NUM_ENV_STAB_PLC_STATES);
|
||||
|
||||
/* renormalize state probabilities */
|
||||
exp = norm_s(sum);
|
||||
tmp = div_s(16384, shl(sum, exp)); /* Q(14-exp) */
|
||||
/*tmp = shl(tmp, add(exp, 1));*/ /* Q15 */
|
||||
FOR (i = 0; i < NUM_ENV_STAB_PLC_STATES; i++)
|
||||
{
|
||||
env_stab_state_p[i] = round_fx(L_shl(L_mult(env_stab_state_p[i], tmp), add(exp, 1))); /* Q15 */
|
||||
}
|
||||
v_multc(env_stab_state_p,1.0f/sum_f(env_stab_state_p,NUM_ENV_STAB_PLC_STATES),env_stab_state_p,NUM_ENV_STAB_PLC_STATES);
|
||||
|
||||
/* find maximum index as return value */
|
||||
state = maximum_fx(env_stab_state_p, NUM_ENV_STAB_PLC_STATES, &maxval);
|
||||
state = maximum(env_stab_state_p,NUM_ENV_STAB_PLC_STATES,&maxval);
|
||||
|
||||
/* apply some hangover for speech */
|
||||
test();
|
||||
if (state == 0 && sub(prev_state, 1) == 0)
|
||||
if (state==0 && prev_state==1)
|
||||
{
|
||||
*ho_cnt = ENV_STAB_SMO_HO;
|
||||
move16();
|
||||
*ho_cnt=ENV_STAB_SMO_HO;
|
||||
}
|
||||
|
||||
IF (*ho_cnt > 0)
|
||||
if (*ho_cnt>0)
|
||||
{
|
||||
*ho_cnt = sub(*ho_cnt, 1);
|
||||
move16();
|
||||
pp[0]=1;
|
||||
pp[1]=0;
|
||||
(*ho_cnt)--;
|
||||
}
|
||||
|
||||
return state;
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
@ -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;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -1,17 +1,18 @@
|
|||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
EVS Codec 3GPP TS26.443 Nov 13, 2018. Version 12.11.0 / 13.7.0 / 14.3.0 / 15.1.0
|
||||
====================================================================================*/
|
||||
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <netinet/in.h>
|
||||
#include <stdint.h>
|
||||
#else
|
||||
#include <Winsock2.h>
|
||||
|
||||
typedef unsigned short uint16_t;
|
||||
typedef signed short int16_t;
|
||||
typedef unsigned int uint32_t;
|
||||
|
|
@ -20,7 +21,6 @@ typedef unsigned __int64 uint64_t;
|
|||
typedef signed __int64 int64_t;
|
||||
#endif
|
||||
#include "options.h"
|
||||
#include "stl.h"
|
||||
#include "g192.h"
|
||||
|
||||
|
||||
|
|
@ -28,12 +28,15 @@ typedef signed __int64 int64_t;
|
|||
#pragma warning( disable : 4996 )
|
||||
#endif
|
||||
|
||||
#define G192_SYNC_GOOD_FRAME (Word16)0x6B21
|
||||
#define G192_SYNC_BAD_FRAME (Word16)0x6B20
|
||||
#define G192_BIT0 (Word16)0x007F
|
||||
#define G192_BIT1 (Word16)0x0081
|
||||
#define MAX_BITS_PER_FRAME 2560
|
||||
#define RTP_HEADER_PART1 (Word16)22 /* magic number by network simulator */
|
||||
#define G192_SYNC_GOOD_FRAME (unsigned short) 0x6B21
|
||||
#define G192_SYNC_BAD_FRAME (unsigned short) 0x6B20
|
||||
#define G192_BIT0 (unsigned short) 0x007F
|
||||
#define G192_BIT1 (unsigned short) 0x0081
|
||||
#define RTP_HEADER_PART1 (short)22 /* magic number by network simulator */
|
||||
|
||||
#ifndef MAX_BITS_PER_FRAME
|
||||
#define MAX_BITS_PER_FRAME 2560
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Structures
|
||||
|
|
@ -58,7 +61,6 @@ G192_Reader_Open(G192_HANDLE* phG192, FILE * filename)
|
|||
{
|
||||
return G192_MEMORY_ERROR;
|
||||
}
|
||||
|
||||
memset(*phG192, 0, sizeof(struct __G192));
|
||||
|
||||
/* associate file stream */
|
||||
|
|
@ -68,27 +70,24 @@ G192_Reader_Open(G192_HANDLE* phG192, FILE * filename)
|
|||
G192_Reader_Close(phG192);
|
||||
return G192_FILE_NOT_FOUND;
|
||||
}
|
||||
|
||||
return G192_NO_ERROR;
|
||||
}
|
||||
|
||||
G192_ERROR
|
||||
G192_ReadVoipFrame_compact(G192_HANDLE const hG192,
|
||||
unsigned char * const serial,
|
||||
Word16 * const num_bits,
|
||||
Word16 *rtpSequenceNumber,
|
||||
Word32 *rtpTimeStamp,
|
||||
Word32 *rcvTime_ms)
|
||||
short * const num_bits,
|
||||
unsigned short * const rtpSequenceNumber,
|
||||
unsigned int * const rtpTimeStamp,
|
||||
unsigned int * const rcvTime_ms)
|
||||
{
|
||||
Word16 short_serial [MAX_BITS_PER_FRAME];
|
||||
short short_serial [MAX_BITS_PER_FRAME];
|
||||
G192_ERROR err;
|
||||
Word16 i;
|
||||
short i;
|
||||
|
||||
err = G192_ReadVoipFrame_short(hG192, short_serial, num_bits, rtpSequenceNumber, rtpTimeStamp, rcvTime_ms);
|
||||
if(err != G192_NO_ERROR)
|
||||
{
|
||||
return err;
|
||||
}
|
||||
|
||||
for(i=0; i<*num_bits; i++)
|
||||
{
|
||||
|
|
@ -98,23 +97,22 @@ G192_ReadVoipFrame_compact(G192_HANDLE const hG192,
|
|||
serial[i>>3] = 0;
|
||||
serial[i>>3] |= bitinbyte;
|
||||
}
|
||||
|
||||
return G192_NO_ERROR;
|
||||
}
|
||||
|
||||
G192_ERROR
|
||||
G192_ReadVoipFrame_short(G192_HANDLE const hG192,
|
||||
Word16 * const serial,
|
||||
Word16 *num_bits,
|
||||
Word16 *rtpSequenceNumber,
|
||||
Word32 *rtpTimeStamp,
|
||||
Word32 *rcvTime_ms)
|
||||
short * const serial,
|
||||
short * const num_bits,
|
||||
unsigned short * const rtpSequenceNumber,
|
||||
unsigned int * const rtpTimeStamp,
|
||||
unsigned int * const rcvTime_ms)
|
||||
{
|
||||
Word32 rtpPacketSize;
|
||||
Word16 rtpPacketHeaderPart1;
|
||||
Word32 ssrc;
|
||||
Word16 rtpPayloadG192[2];
|
||||
Word16 rtpPayloadSize;
|
||||
uint32_t rtpPacketSize;
|
||||
uint16_t rtpPacketHeaderPart1;
|
||||
uint32_t ssrc;
|
||||
uint16_t rtpPayloadG192[2];
|
||||
uint16_t rtpPayloadSize;
|
||||
|
||||
/* RTP packet size */
|
||||
if(fread(&rtpPacketSize, sizeof(rtpPacketSize), 1, hG192->file) != 1)
|
||||
|
|
@ -124,12 +122,13 @@ G192_ReadVoipFrame_short(G192_HANDLE const hG192,
|
|||
return G192_EOF;
|
||||
}
|
||||
fprintf(stderr, "RTP Packet Size could't be read\n");
|
||||
|
||||
return G192_READ_ERROR;
|
||||
}
|
||||
|
||||
if(rtpPacketSize <= 12)
|
||||
{
|
||||
fprintf(stderr, "RTP Packet size too small: %d\n", rtpPacketSize);
|
||||
fprintf(stderr, "RTP Packet size too small: %ud\n", rtpPacketSize);
|
||||
return G192_INVALID_DATA;
|
||||
}
|
||||
|
||||
|
|
@ -141,6 +140,7 @@ G192_ReadVoipFrame_short(G192_HANDLE const hG192,
|
|||
return G192_EOF;
|
||||
}
|
||||
fprintf(stderr, "Reception Time in ms could't be read\n");
|
||||
|
||||
return G192_READ_ERROR;
|
||||
}
|
||||
|
||||
|
|
@ -152,6 +152,7 @@ G192_ReadVoipFrame_short(G192_HANDLE const hG192,
|
|||
return G192_EOF;
|
||||
}
|
||||
fprintf(stderr, "RTP Header couldn't be read\n");
|
||||
|
||||
return G192_READ_ERROR;
|
||||
}
|
||||
|
||||
|
|
@ -169,10 +170,11 @@ G192_ReadVoipFrame_short(G192_HANDLE const hG192,
|
|||
return G192_EOF;
|
||||
}
|
||||
fprintf(stderr, "RTP Sequence Number be read\n");
|
||||
|
||||
return G192_READ_ERROR;
|
||||
}
|
||||
|
||||
*rtpSequenceNumber = ntohs(*rtpSequenceNumber);
|
||||
|
||||
/* RTP timestamp */
|
||||
if(fread(rtpTimeStamp, sizeof(*rtpTimeStamp), 1, hG192->file) != 1)
|
||||
{
|
||||
|
|
@ -181,10 +183,11 @@ G192_ReadVoipFrame_short(G192_HANDLE const hG192,
|
|||
return G192_EOF;
|
||||
}
|
||||
fprintf(stderr, "RTP Timestamp could't be read\n");
|
||||
|
||||
return G192_READ_ERROR;
|
||||
}
|
||||
|
||||
*rtpTimeStamp = ntohl(*rtpTimeStamp);
|
||||
|
||||
/* RTP ssrc */
|
||||
if(fread(&ssrc, sizeof(ssrc), 1, hG192->file) != 1)
|
||||
{
|
||||
|
|
@ -193,18 +196,20 @@ G192_ReadVoipFrame_short(G192_HANDLE const hG192,
|
|||
return G192_EOF;
|
||||
}
|
||||
fprintf(stderr, "RTP SSRC could't be read\n");
|
||||
|
||||
return G192_READ_ERROR;
|
||||
}
|
||||
|
||||
/* RTP payload size */
|
||||
rtpPayloadSize = (Word16)(rtpPacketSize - 12);
|
||||
rtpPayloadSize = rtpPacketSize - 12;
|
||||
if(rtpPayloadSize <= 2)
|
||||
{
|
||||
fprintf(stderr, "RTP payload size too small: %d\n", rtpPayloadSize);
|
||||
fprintf(stderr, "RTP payload size too small: %u\n", rtpPayloadSize);
|
||||
return G192_INVALID_DATA;
|
||||
}
|
||||
|
||||
/* RTP payload */
|
||||
if(fread(rtpPayloadG192, sizeof(Word16), 2, hG192->file) != 2)
|
||||
if(fread(rtpPayloadG192, sizeof(short), 2, hG192->file) != 2)
|
||||
{
|
||||
if(feof( hG192->file) != 0)
|
||||
{
|
||||
|
|
@ -219,18 +224,14 @@ G192_ReadVoipFrame_short(G192_HANDLE const hG192,
|
|||
return G192_INVALID_DATA;
|
||||
}
|
||||
*num_bits = rtpPayloadG192[1];
|
||||
if(*num_bits == 0 || *num_bits + 2 != rtpPayloadSize || *num_bits > MAX_BITS_PER_FRAME)
|
||||
if(*num_bits == 0u || *num_bits + 2u != rtpPayloadSize || *num_bits > MAX_BITS_PER_FRAME)
|
||||
{
|
||||
fprintf(stderr, "error in parsing RTP payload: rtpPayloadSize=%u nBits=%d",
|
||||
rtpPayloadSize, *num_bits);
|
||||
return G192_INVALID_DATA;
|
||||
}
|
||||
if( (Word16)fread(serial, sizeof(Word16), *num_bits, hG192->file) != *num_bits)
|
||||
if( fread(serial, sizeof(short), *num_bits, hG192->file) != (unsigned short)*num_bits)
|
||||
{
|
||||
if(feof( hG192->file) != 0)
|
||||
{
|
||||
return G192_EOF;
|
||||
}
|
||||
fprintf(stderr, "Premature end of file, cannot read G.192 payload\n");
|
||||
return G192_READ_ERROR;
|
||||
}
|
||||
|
|
@ -242,13 +243,11 @@ G192_ERROR
|
|||
G192_Reader_Close(G192_HANDLE* phG192)
|
||||
{
|
||||
if(phG192 == NULL || *phG192 == NULL)
|
||||
{
|
||||
return G192_NO_ERROR;
|
||||
}
|
||||
|
||||
free( *phG192 );
|
||||
*phG192 = NULL;
|
||||
phG192 = NULL;
|
||||
|
||||
return G192_NO_ERROR;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,12 @@
|
|||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
EVS Codec 3GPP TS26.443 Nov 13, 2018. Version 12.11.0 / 13.7.0 / 14.3.0 / 15.1.0
|
||||
====================================================================================*/
|
||||
|
||||
#ifndef G192_H
|
||||
#define G192_H G192_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/*
|
||||
* ENUMS
|
||||
*/
|
||||
|
|
@ -45,18 +47,18 @@ G192_Reader_Open(G192_HANDLE* phG192, FILE * filename);
|
|||
G192_ERROR
|
||||
G192_ReadVoipFrame_compact(G192_HANDLE const hG192,
|
||||
unsigned char * const serial,
|
||||
Word16 * const num_bits,
|
||||
Word16 *rtpSequenceNumber,
|
||||
Word32 *rtpTimeStamp,
|
||||
Word32 *rcvTime_ms);
|
||||
short * const num_bits,
|
||||
unsigned short * const rtpSequenceNumber,
|
||||
unsigned int * const rtpTimeStamp,
|
||||
unsigned int * const rcvTime_ms);
|
||||
|
||||
G192_ERROR
|
||||
G192_ReadVoipFrame_short(G192_HANDLE const hG192,
|
||||
Word16 * const serial,
|
||||
Word16 *num_bits,
|
||||
Word16 *rtpSequenceNumber,
|
||||
Word32 *rtpTimeStamp,
|
||||
Word32 *rcvTime_ms);
|
||||
short * const serial,
|
||||
short * const num_bits,
|
||||
unsigned short * const rtpSequenceNumber,
|
||||
unsigned int * const rtpTimeStamp,
|
||||
unsigned int * const rcvTime_ms);
|
||||
|
||||
G192_ERROR
|
||||
G192_Reader_Close(G192_HANDLE* phG192);
|
||||
|
|
|
|||
|
|
@ -1,54 +0,0 @@
|
|||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
====================================================================================*/
|
||||
|
||||
#include <assert.h>
|
||||
#include "prot_fx.h"
|
||||
#include "stl.h"
|
||||
#include "basop_util.h"
|
||||
#include "rom_com_fx.h"
|
||||
|
||||
|
||||
Word32 calc_gain_inov( /* returns innovation gain Q16 */
|
||||
const Word16 *code, /* i : algebraic excitation Q9 */
|
||||
Word16 lcode, /* i : Subframe size Q0 */
|
||||
Word32 *dotp, /* o : intermediate result Q31-e */
|
||||
Word16 *dotp_e /* o : intermediate result exponent Q0 */
|
||||
)
|
||||
{
|
||||
Word32 L_tmp;
|
||||
Word16 exp_L_tmp, i;
|
||||
|
||||
/* L_tmp = dot_product(code, code, lcode) + 0.01 */
|
||||
L_tmp = Dot_product12_offs(code, code, lcode, &exp_L_tmp, 2621l/*0.01f/2.0f Q19*/);
|
||||
exp_L_tmp = sub(exp_L_tmp, 18);
|
||||
|
||||
/* gain_inov = 1.0f / sqrt((dot_product(code, code, lcode) + 0.01) / lcode) */
|
||||
/* Note: lcode is in range: 32,40,64,80 */
|
||||
assert((lcode == 32) || (lcode == 40) || (lcode == 64) || (lcode == 80));
|
||||
if (s_and(lcode, sub(lcode, 1)) != 0)
|
||||
{
|
||||
L_tmp = Mpy_32_32(L_tmp, 1717986918l/*64.0/80.0 Q31*/);
|
||||
}
|
||||
exp_L_tmp = sub(exp_L_tmp, sub(14, norm_s(lcode)));
|
||||
|
||||
i = norm_l(L_tmp);
|
||||
L_tmp = L_shl(L_tmp, i);
|
||||
exp_L_tmp = sub(exp_L_tmp, i);
|
||||
|
||||
if (dotp != NULL)
|
||||
{
|
||||
*dotp = L_tmp;
|
||||
move32();
|
||||
}
|
||||
if (dotp_e != NULL)
|
||||
{
|
||||
*dotp_e = exp_L_tmp;
|
||||
move16();
|
||||
}
|
||||
|
||||
L_tmp = ISqrt32norm(L_tmp, &exp_L_tmp);
|
||||
|
||||
return L_shl(L_tmp, sub(exp_L_tmp, 15)); /* 15Q16 */
|
||||
}
|
||||
|
||||
|
|
@ -1,97 +1,37 @@
|
|||
/*====================================================================================
|
||||
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
||||
EVS Codec 3GPP TS26.443 Nov 13, 2018. Version 12.11.0 / 13.7.0 / 14.3.0 / 15.1.0
|
||||
====================================================================================*/
|
||||
|
||||
#include "options.h"
|
||||
#include "prot_fx.h"
|
||||
#include "stl.h"
|
||||
#include "basop_util.h"
|
||||
#include "prot.h"
|
||||
|
||||
Word32 get_gain( /* output: codebook gain (adaptive or fixed) Q16 */
|
||||
Word16 x[], /* input : target signal */
|
||||
Word16 y[], /* input : filtered codebook excitation */
|
||||
Word16 n /* input : segment length */
|
||||
|
||||
/*----------------------------------------------------------------------------------*
|
||||
* get_gain()
|
||||
*
|
||||
*
|
||||
*----------------------------------------------------------------------------------*/
|
||||
|
||||
float get_gain( /* output: codebook gain (adaptive or fixed) */
|
||||
float x[], /* input : target signal */
|
||||
float y[], /* input : filtered codebook excitation */
|
||||
int n, /* input : segment length */
|
||||
float *en_y /* output: energy of y (sum of y[]^2, optional) */
|
||||
)
|
||||
{
|
||||
Word32 tcorr, tener, Lgain;
|
||||
Word16 exp_c, exp_e, exp, tmp;
|
||||
float corr = 0.0f, ener = 1e-6f;
|
||||
short i;
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
corr += x[i]*y[i];
|
||||
ener += y[i]*y[i];
|
||||
}
|
||||
|
||||
tcorr = L_deposit_l(0);
|
||||
tener = L_deposit_l(0);
|
||||
if (en_y)
|
||||
{
|
||||
*en_y = ener;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*----------------------------------------------------------------*
|
||||
* Find gain based on inter-correlation product
|
||||
*----------------------------------------------------------------*/
|
||||
|
||||
tcorr = Dot_product16HQ( 0, x, y, n, &exp_c );
|
||||
tener = Dot_productSq16HQ( 0, y, n, &exp_e );
|
||||
|
||||
BASOP_Util_Divide_MantExp(round_fx(tcorr), exp_c, s_max(round_fx(tener),1), exp_e, &tmp,&exp);
|
||||
Lgain = L_shl(L_deposit_l(tmp)/*Q15*/,add(1,exp))/*Q16*/;
|
||||
|
||||
return Lgain;
|
||||
}
|
||||
|
||||
Word32 get_gain2( /* output: codebook gain (adaptive or fixed) Q16 */
|
||||
Word16 x[], /* input : target signal */
|
||||
Word16 y[], /* input : filtered codebook excitation */
|
||||
Word16 n /* input : segment length */
|
||||
)
|
||||
{
|
||||
Word32 tcorr, tener, Lgain;
|
||||
Word16 m_corr, m_ener, negative, Q_corr, Q_ener;
|
||||
|
||||
negative = 0;
|
||||
move16();
|
||||
|
||||
/*----------------------------------------------------------------*
|
||||
* Find gain based on inter-correlation product
|
||||
*----------------------------------------------------------------*/
|
||||
tcorr = Dot_product16HQ(0, x, y, n, &Q_corr);
|
||||
tener = Dot_productSq16HQ(0, y, n, &Q_ener);
|
||||
|
||||
tener = L_max(tener, 1);
|
||||
|
||||
if (tcorr <= 0)
|
||||
{
|
||||
negative = 1;
|
||||
move16();
|
||||
}
|
||||
BASOP_SATURATE_WARNING_OFF /*tcorr max be negative maxvall - not critical*/
|
||||
tcorr = L_abs(tcorr);
|
||||
BASOP_SATURATE_WARNING_ON
|
||||
|
||||
m_corr = extract_h(tcorr);
|
||||
|
||||
m_ener = extract_h(tener);
|
||||
|
||||
IF (sub(m_corr, m_ener) > 0)
|
||||
{
|
||||
m_corr = shr(m_corr, 1);
|
||||
Q_corr = add(Q_corr,1);
|
||||
}
|
||||
if (m_ener==0)
|
||||
{
|
||||
move16();
|
||||
m_corr = 0x7FFF;
|
||||
}
|
||||
if (m_ener != 0)
|
||||
{
|
||||
m_corr = div_s(m_corr, m_ener);
|
||||
}
|
||||
|
||||
Q_corr = sub(Q_corr,Q_ener);
|
||||
|
||||
Lgain = L_shl(L_deposit_l(m_corr), add(Q_corr, 1)); /* Lgain in Q16 */
|
||||
|
||||
if (negative != 0)
|
||||
{
|
||||
Lgain = L_negate(Lgain); /* Lgain in Q16 */
|
||||
}
|
||||
|
||||
|
||||
return Lgain;
|
||||
return(corr/ener);
|
||||
}
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue