⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 g726.cpp

📁 G.726带测试和在DM642实现的完整工程。测试程序可修改自行填入数据。实现部分设计具体产品板的定义
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/**
@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 + -