📄 g726.cpp
字号:
/**
@file
@brief Implementation of ITU-T (formerly CCITT) Recomendation %G726
For latest source code see http://www.tixy.clara.net/source/
Copyright (C) 2004 J.D.Medhurst (a.k.a. Tixy)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "common_g726.h"
#include "G726.h"
#include "G711.h"
/**
@defgroup g726_section4 Internal - Individual functions from Section 4 of G726
@ingroup g726
@{
*/
/**
@defgroup g726_section4m Internal - Range checking macros
@ingroup g726_section4
Macros for checking the range of variables used within the codec algorithm.
They are also useful as they indicate the type of the variable being checked.
@{
*/
/**
Check that a signed magnitude value lies entirely withing the given number of bits
@param x The value
@param bits Number of bits
*/
#define CHECK_SM(x,bits) ASSERT_DEBUG(((x)>>bits)==0)
/**
Check that a unsigned magnitude value lies entirely withing the given number of bits
@param x The value
@param bits Number of bits
*/
#define CHECK_UM(x,bits) ASSERT_DEBUG(((x)>>bits)==0)
/**
Check that a twos compliment value lies entirely withing the given number of bits
@param x The value
@param bits Number of bits
*/
#define CHECK_TC(x,bits) ASSERT_DEBUG(((x)>>(bits-1))==((x)<0?-1:0))
/**
Check that a float value lies entirely withing the given number of bits
@param x The value
@param bits Number of bits
*/
#define CHECK_FL(x,bits) ASSERT_DEBUG(((x)>>bits)==0)
/**
Check that an unsigned integer value lies entirely withing the given number of bits
@param x The value
@param bits Number of bits
*/
#define CHECK_UNSIGNED(x,bits) ASSERT_DEBUG(((x)>>bits)==0)
/** @} */ // End of group
/**
@brief EXPAND function from %G726 Section 4.2.1 - Input PCM format conversion and difference signal computation
*/
static void EXPAND(uint S,uint LAW,int& SL)
{
CHECK_UNSIGNED(S,8);
CHECK_UNSIGNED(LAW,1);
int linear;
if(LAW)
linear = G711::ALawDecode(S);
else
linear = G711::ULawDecode(S);
SL = linear>>2;
CHECK_TC(SL,14);
}
/**
@brief SUBTA function from %G726 Section 4.2.1 - Input PCM format conversion and difference signal computation
*/
inline static void SUBTA(int SL,int SE,int& D)
{
CHECK_TC(SL,14);
CHECK_TC(SE,15);
D = SL-SE;
CHECK_TC(D,16);
}
/**
@brief LOG function from %G726 Section 4.2.2 - Adaptive quantizer
*/
static void LOG(int D,uint& DL,int& DS)
{
CHECK_TC(D,16);
DS = D>>15;
uint DQM = (D<0) ? -D : D;
DQM &= 0x7fff;
uint EXP = 0;
uint x = DQM;
if(x>=(1<<8))
{
EXP |= 8;
x >>= 8;
}
if(x>=(1<<4))
{
EXP |= 4;
x >>= 4;
}
if(x>=(1<<2))
{
EXP |= 2;
x >>= 2;
}
EXP |= x>>1;
uint MANT = ((DQM<<7)>>EXP)&0x7f;
DL = (EXP<<7) + MANT;
CHECK_UM(DL,11);
CHECK_TC(DS,1);
}
/**
@brief QUAN function from %G726 Section 4.2.2 - Adaptive quantizer
*/
static void QUAN(uint RATE,int DLN,int DS,uint& I)
{
CHECK_TC(DLN,12);
CHECK_TC(DS,1);
int x;
if(RATE==2)
x = (DLN>=261);
else
{
static const int16 quan3[4] = {8,218,331,0x7fff};
static const int16 quan4[8] = {3972-0x1000,80,178,246,300,349,400,0x7fff};
static const int16 quan5[16] = {3974-0x1000,4080-0x1000,68,139,198,250,298,339,378,413,445,475,502,528,553,0x7fff};
static const int16* const quan[3] = {quan3,quan4,quan5};
const int16* levels = quan[RATE-3];
const int16* levels0 = levels;
while(DLN>=*levels++) {}
x = levels-levels0-1;
if(!x)
x = ~DS;
}
int mask = (1<<RATE)-1;
I = (x^DS)&mask;
CHECK_UNSIGNED(I,RATE);
}
/**
@brief SUBTB function from %G726 Section 4.2.2 - Adaptive quantizer
*/
inline static void SUBTB(uint DL,uint Y,int& DLN)
{
CHECK_UM(DL,11);
CHECK_UM(Y,13);
DLN = DL-(Y>>2);
CHECK_TC(DLN,12);
}
/**
@brief ADDA function from %G726 Section 4.2.3 - Inverse adaptive quantizer
*/
inline static void ADDA(int DQLN,uint Y,int& DQL)
{
CHECK_TC(DQLN,12);
CHECK_UM(Y,13);
DQL = DQLN+(Y>>2);
CHECK_TC(DQL,12);
}
/**
@brief ANTILOG function from %G726 Section 4.2.3 - Inverse adaptive quantizer
*/
inline static void ANTILOG(int DQL,int DQS,uint& DQ)
{
CHECK_TC(DQL,12);
CHECK_TC(DQS,1);
uint DEX = (DQL >> 7) & 15;
uint DMN = DQL & 127;
uint DQT = (1 << 7) + DMN;
uint DQMAG;
if(DQL>=0)
DQMAG = (DQT << 7) >> (14 - DEX);
else
DQMAG = 0;
DQ = DQS ? DQMAG+(1<<15) : DQMAG;
CHECK_SM(DQ,16);
}
/**
@brief RECONST function from %G726 Section 4.2.3 - Inverse adaptive quantizer
*/
inline static void RECONST(uint RATE,uint I,int& DQLN,int& DQS)
{
CHECK_UNSIGNED(I,RATE);
// Tables 11-14
static const int16 reconst2[2] = {116,365};
static const int16 reconst3[4] = {2048-4096,135,273,373};
static const int16 reconst4[8] = {2048-4096,4,135,213,273,323,373,425};
static const int16 reconst5[16] = {2048-4096,4030-4096,28,104,169,224,274,318,358,395,429,459,488,514,539,566};
static const int16* const reconst[4] = {reconst2,reconst3,reconst4,reconst5};
int x = I;
int m = 1<<(RATE-1);
if(x&m)
{
DQS = -1;
x = ~x;
}
else
DQS = 0;
DQLN = reconst[RATE-2][x&(m-1)];
CHECK_TC(DQLN,12);
CHECK_TC(DQS,1);
}
/**
@brief FILTD function from %G726 Section 4.2.4 - Quantizer scale factor adaptation
*/
inline static void FILTD(int WI,uint Y,uint& YUT)
{
CHECK_TC(WI,12);
CHECK_UM(Y,13);
int DIF = (WI<<5)-Y;
int DIFSX = DIF>>5;
YUT = (Y+DIFSX); // & 8191
CHECK_UM(YUT,13);
}
/**
@brief FILTE function from %G726 Section 4.2.4 - Quantizer scale factor adaptation
*/
inline static void FILTE(uint YUP,uint YL,uint& YLP)
{
CHECK_UM(YUP,13);
CHECK_UM(YL,19);
int DIF = (YUP<<6)-YL;
int DIFSX = DIF>>6;
YLP = (YL+DIFSX); // & 524287
CHECK_UM(YLP,19);
}
/**
@brief FUNCTW function from %G726 Section 4.2.4 - Quantizer scale factor adaptation
*/
inline static void FUNCTW(uint RATE,uint I,int& WI)
{
CHECK_UNSIGNED(I,RATE);
static const int16 functw2[2] = {4074-4096,439};
static const int16 functw3[4] = {4092-4096,30,137,582};
static const int16 functw4[8] = {4084-4096,18,41,64,112,198,355,1122};
static const int16 functw5[16] = {14,14,24,39,40,41,58,100,141,179,219,280,358,440,529,696};
static const int16* const functw[4] = {functw2,functw3,functw4,functw5};
uint signMask = 1<<(RATE-1);
uint n = (I&signMask) ? (2*signMask-1)-I : I;
WI = functw[RATE-2][n];
CHECK_TC(WI,12);
}
/**
@brief LIMB function from %G726 Section 4.2.4 - Quantizer scale factor adaptation
*/
inline static void LIMB(uint YUT,uint& YUP)
{
CHECK_UM(YUT,13);
uint GEUL = (YUT+11264)&(1<<13);
uint GELL = (YUT+15840)&(1<<13);
if(GELL)
YUP = 544;
else if (!GEUL)
YUP = 5120;
else
YUP = YUT;
CHECK_UM(YUP,13);
}
/**
@brief MIX function from %G726 Section 4.2.4 - Quantizer scale factor adaptation
*/
inline static void MIX(uint AL,uint YU,uint YL,uint& Y)
{
CHECK_UM(AL,7);
CHECK_UM(YU,13);
CHECK_UM(YL,19);
int DIF = YU-(YL>>6);
int PROD = DIF*AL;
if(DIF<0) PROD += (1<<6)-1; // Force round towards zero for following shift
PROD >>= 6;
Y = ((YL>>6)+PROD); // & 8191;
CHECK_UM(Y,13);
}
/**
@brief FILTA function from %G726 Section 4.2.5 - Adaptation speed control
*/
inline static void FILTA(uint FI,uint DMS,uint& DMSP)
{
CHECK_UM(FI,3);
CHECK_UM(DMS,12);
int DIF = (FI<<9)-DMS;
int DIFSX = (DIF>>5);
DMSP = (DIFSX+DMS); // & 4095;
CHECK_UM(DMSP,12);
}
/**
@brief FILTB function from %G726 Section 4.2.5 - Adaptation speed control
*/
inline static void FILTB(uint FI,uint DML,uint& DMLP)
{
CHECK_UM(FI,3);
CHECK_UM(DML,14);
int DIF = (FI<<11)-DML;
int DIFSX = (DIF>>7);
DMLP = (DIFSX+DML); // & 16383;
CHECK_UM(DMLP,14);
}
/**
@brief FILTC function from %G726 Section 4.2.5 - Adaptation speed control
*/
inline static void FILTC(uint AX,uint AP,uint& APP)
{
CHECK_UM(AX,1);
CHECK_UM(AP,10);
int DIF = (AX<<9)-AP;
int DIFSX = (DIF>>4);
APP = (DIFSX+AP); // & 1023;
CHECK_UM(APP,10);
}
/**
@brief FUNCTF function from %G726 Section 4.2.5 - Adaptation speed control
*/
inline static void FUNCTF(uint RATE,uint I,uint& FI)
{
CHECK_UNSIGNED(I,RATE);
static const int16 functf2[2] = {0,7};
static const int16 functf3[4] = {0,1,2,7};
static const int16 functf4[8] = {0,0,0,1,1,1,3,7};
static const int16 functf5[16] = {0,0,0,0,0,1,1,1,1,1,2,3,4,5,6,6};
static const int16* const functf[4] = {functf2,functf3,functf4,functf5};
uint x = I;
int mask=(1<<(RATE-1));
if(x&mask)
x = ~x;
x &= mask-1;
FI = functf[RATE-2][x];
CHECK_UM(FI,3);
}
/**
@brief LIMA function from %G726 Section 4.2.5 - Adaptation speed control
*/
inline static void LIMA(uint AP,uint& AL)
{
CHECK_UM(AP,10);
AL = (AP>256) ? 64 : AP>>2;
CHECK_UM(AL,7);
}
/**
@brief SUBTC function from %G726 Section 4.2.5 - Adaptation speed control
*/
inline static void SUBTC(uint DMSP,uint DMLP,uint TDP,uint Y,uint& AX)
{
CHECK_UM(DMSP,12);
CHECK_UM(DMLP,14);
CHECK_UNSIGNED(TDP,1);
CHECK_UM(Y,13);
int DIF = (DMSP<<2)-DMLP;
uint DIFM;
if(DIF<0)
DIFM = -DIF;
else
DIFM = DIF;
uint DTHR = DMLP >> 3;
AX = (Y>=1536 && DIFM<DTHR) ? TDP : 1;
CHECK_UM(AX,1);
}
/**
@brief TRIGA function from %G726 Section 4.2.5 - Adaptation speed control
*/
inline static void TRIGA(uint TR,uint APP,uint& APR)
{
CHECK_UNSIGNED(TR,1);
CHECK_UM(APP,10);
APR = TR ? 256 : APP;
CHECK_UM(APR,10);
}
/**
@brief ACCUM function from %G726 Section 4.2.6 - Adaptative predictor and reconstructed signal calculator
*/
inline static void ACCUM(int WAn[2],int WBn[6],int& SE,int& SEZ)
{
CHECK_TC(WAn[0],16);
CHECK_TC(WAn[1],16);
CHECK_TC(WBn[0],16);
CHECK_TC(WBn[1],16);
CHECK_TC(WBn[2],16);
CHECK_TC(WBn[3],16);
CHECK_TC(WBn[4],16);
CHECK_TC(WBn[5],16);
int16 SEZI = (int16)(WBn[0]+WBn[1]+WBn[2]+WBn[3]+WBn[4]+WBn[5]);
int16 SEI = (int16)(SEZI+WAn[0]+WAn[1]);
SEZ = SEZI >> 1;
SE = SEI >> 1;
CHECK_TC(SE,15);
CHECK_TC(SEZ,15);
}
/**
@brief ACCUM function from %G726 Section 4.2.6 - Adaptative predictor and reconstructed signal calculator
*/
inline static void ADDB(uint DQ,int SE,int& SR)
{
CHECK_SM(DQ,16);
CHECK_TC(SE,15);
int DQI;
if(DQ&(1<<15))
DQI = (1<<15)-DQ;
else
DQI = DQ;
SR = (int16)(DQI+SE);
CHECK_TC(SR,16);
}
/**
@brief ADDC function from %G726 Section 4.2.6 - Adaptative predictor and reconstructed signal calculator
*/
inline static void ADDC(uint DQ,int SEZ,int& PK0,uint& SIGPK)
{
CHECK_SM(DQ,16);
CHECK_TC(SEZ,15);
int DQI;
if(DQ&(1<<15))
DQI = (1<<15)-DQ;
else
DQI = DQ;
int DQSEZ = (int16)(DQI+SEZ);
PK0 = DQSEZ>>15;
SIGPK = DQSEZ ? 0 : 1;
CHECK_TC(PK0,1);
CHECK_UNSIGNED(SIGPK,1);
}
static void MagToFloat(uint mag,uint& exp,uint& mant)
{
uint e = 0;
uint m = mag<<1;
if(m>=(1<<8))
{
e |= 8;
m >>= 8;
}
if(m>=(1<<4))
{
e |= 4;
m >>= 4;
}
if(m>=(1<<2))
{
e |= 2;
m >>= 2;
}
e |= m>>1;
exp = e;
mant = mag ? (mag<<6)>>e : 1<<5;
}
/**
@brief FLOATA function from %G726 Section 4.2.6 - Adaptative predictor and reconstructed signal calculator
*/
inline static void FLOATA(uint DQ, uint& DQ0)
{
CHECK_SM(DQ,16);
uint DQS = (DQ>>15);
uint MAG = DQ&32767;
uint EXP;
uint MANT;
MagToFloat(MAG,EXP,MANT);
DQ0 = (DQS<<10) + (EXP<<6) + MANT;
CHECK_FL(DQ0,11);
}
/**
@brief FLOATB function from %G726 Section 4.2.6 - Adaptative predictor and reconstructed signal calculator
*/
inline static void FLOATB(int SR, uint& SR0)
{
CHECK_TC(SR,16);
uint SRS = (SR>>15)&1;
uint MAG = SRS ? (-SR)&32767 : SR;
uint EXP;
uint MANT;
MagToFloat(MAG,EXP,MANT);
SR0 = (SRS<<10) + (EXP<<6) + MANT;
CHECK_FL(SR0,11);
}
/**
@brief FMULT function from %G726 Section 4.2.6 - Adaptative predictor and reconstructed signal calculator
*/
static void FMULT(int An,uint SRn,int& WAn)
{
CHECK_TC(An,16);
CHECK_FL(SRn,11);
uint AnS = (An>>15)&1;
uint AnMAG = AnS ? (-(An>>2))&8191 : An>>2;
uint AnEXP;
uint AnMANT;
MagToFloat(AnMAG,AnEXP,AnMANT);
uint SRnS = SRn>>10;
uint SRnEXP = (SRn>>6) & 15;
uint SRnMANT = SRn&63;
uint WAnS = SRnS^AnS;
uint WAnEXP = SRnEXP+AnEXP;
uint WAnMANT = ((SRnMANT*AnMANT)+48)>>4;
uint WAnMAG;
if(WAnEXP<=26)
WAnMAG = (WAnMANT<<7) >> (26-WAnEXP);
else
WAnMAG = ((WAnMANT<<7) << (WAnEXP-26)) & 32767;
WAn = WAnS ? -(int)WAnMAG : WAnMAG;
CHECK_TC(WAn,16);
}
/**
@brief LIMC function from %G726 Section 4.2.6 - Adaptative predictor and reconstructed signal calculator
*/
inline static void LIMC(int A2T,int& A2P)
{
CHECK_TC(A2T,16);
const int A2UL = 12288;
const int A2LL = 53248-65536;
if(A2T<=A2LL)
A2P = A2LL;
else if(A2T>=A2UL)
A2P = A2UL;
else
A2P = A2T;
CHECK_TC(A2P,16);
}
/**
@brief LIMD function from %G726 Section 4.2.6 - Adaptative predictor and reconstructed signal calculator
*/
inline static void LIMD(int A1T,int A2P,int& A1P)
{
CHECK_TC(A1T,16);
CHECK_TC(A2P,16);
const int OME = 15360;
int A1UL = (int16)(OME-A2P);
int A1LL = (int16)(A2P-OME);
if(A1T<=A1LL)
A1P = A1LL;
else if(A1T>=A1UL)
A1P = A1UL;
else
A1P = A1T;
CHECK_TC(A1P,16);
}
/**
@brief TRIGB function from %G726 Section 4.2.6 - Adaptative predictor and reconstructed signal calculator
*/
inline static void TRIGB(uint TR,int AnP,int& AnR)
{
CHECK_UNSIGNED(TR,1);
CHECK_TC(AnP,16);
AnR = TR ? 0 : AnP;
CHECK_TC(AnR,16);
}
/**
@brief UPA1 function from %G726 Section 4.2.6 - Adaptative predictor and reconstructed signal calculator
*/
inline static void UPA1(int PK0,int PK1,int A1,uint SIGPK,int& A1T)
{
CHECK_TC(PK0,1);
CHECK_TC(PK1,1);
CHECK_TC(A1,16);
CHECK_UNSIGNED(SIGPK,1);
int UGA1;
if(SIGPK==0)
{
if(PK0^PK1)
UGA1 = -192;
else
UGA1 = 192;
}
else
UGA1 = 0;
A1T = (int16)(A1+UGA1-(A1>>8));
CHECK_TC(A1T,16);
}
/**
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -