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

📄 code_decode.c

📁 源程序中包含PCMu率与PCM线形之间的编解码
💻 C
字号:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include "code_decode.h"
#define DEBUG
#ifdef DEBUG
#define NUM 3*8000
#endif
unsigned char g_uc_ms_lin2ulaw[16384];
short int g_s_ms_ulaw2linear[256];


/*****************************************************************
函数名:  linear2ulaw
参数:
		  sample:	输入,即16位的PCM音频数据
返回值:  ulawbyte
功能:	  将一个PCM16样本转化成一个8位的PCMu
******************************************************************/

unsigned char linear2ulaw(short int sample)
{
	static int exp_lut[256] = {0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
							   4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
							   5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
                               5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
                               6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
                               6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
                               6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
                               6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
                               7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
                               7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
                               7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
                               7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
                               7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
                               7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
                               7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
                               7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7};
	short int sign, exponent, mantissa;			// 符号 指数 尾数
	unsigned char ulawbyte;	
		/* Get the sample into sign-magnitude. */
	sign = (sample >> 8) & 0x80;          /* set aside the sign,这里进行算术右移 */
	if (sign != 0) sample = -sample;              /* get magnitude */
	if (sample > CLIP) sample = CLIP;             /* clip the magnitude */

		/* Convert from 16 bit linear to ulaw. */
	sample = sample + BIAS;
	exponent = exp_lut[(sample >> 7) & 0xFF];
	mantissa = (sample >> (exponent + 3)) & 0x0F;
	ulawbyte = ~(sign | (exponent << 4) | mantissa);
	#ifdef ZEROTRAP
		if (ulawbyte == 0) ulawbyte = 0x02;   /* optional CCITT trap */
	#endif
		return(ulawbyte);
	
}

/*****************************************************************
函数名:  ulaw2linear
参数:
		  u_val:	输入,即8位的PCMu音频数据
返回值:  16位的PCMlinear音频数据
功能:	  将一个PCMu样本转化成一个16位的PCMlinear
******************************************************************/

short int ulaw2linear(unsigned char	u_val)
{
   short t;
   
   /* Complement to obtain normal u-law value. */
   u_val = ~u_val;
   
   /*
    * Extract and bias the quantization bits. Then
    * shift up by the segment number and subtract out the bias.
    */
   t = ((u_val & QUANT_MASK) << 3) + BIAS;
   t <<= ((unsigned)u_val & SEG_MASK) >> SEG_SHIFT;
   
   return ((u_val & SIGN_BIT) ? (BIAS - t) : (t - BIAS));
}


/*************************************************************
函数名:	ulawCreat
输入:		NULL
输出:		NULL
返回值:	无
功能:		制作PCMu率表,将16位的PCM转化为8位的PCMu,并存放在
			数组lin2ulaw[]里面,为后面的编码做准备
**************************************************************/

void ulawCreat()
{
	int i;
	for(i = -32768; i < 32768; i++)
	{
		g_uc_ms_lin2ulaw[((unsigned short)i) >> 2] = linear2ulaw(i);
	}
}

/*************************************************************
函数名:	linearCreat
输入:		NULL
输出:		NULL
返回值:	无
功能:		制作PCMlinear表,将8位的PCMu转化为16位的PCM,并存放在
			数组ulaw2lin[]里面,为后面的编码做准备
**************************************************************/

void linearCreat()
{
	int i;
	for(i =0; i < 256; i++)
	{
		g_s_ms_ulaw2linear[i] = ulaw2linear(i);
	}
}


/**************************************************************
函数名:  code_linear2ulaw
参数:
		  sample_NUM:  输入,PCM16音频的样本数
		  pSrcData:    输入,存放PCM16音频数据的源地址
		  pDstData:    输出,存放编码后,即PCMu音频数据的首地址

返回值:
		  ERR_PARAM:参数错误。
		  OK:       正确返回。
功能:	  将传进的PCM16的音频数据转换成8位的PCMu
***************************************************************/
inline int code_linear2ulaw(short int * pSrcData,unsigned char * pDstData,short int sample_NUM)
{
	short int i;
	if( (pSrcData==NULL) || (pDstData==NULL))
	{
	return (ERR_PARAM);
	}
	for(i=0;i<sample_NUM;i++)
	{
		*(pDstData+i)=g_uc_ms_lin2ulaw[((unsigned short)(*(pSrcData+i))) >> 2];
	}
	return (OK);
}


/**************************************************************
函数名:  code_ulaw2linear
参数:
		  pSrcData:    输入,存放PCMu音频数据的源地址
		  pDstData:    输出,存放编码后,即PCMlinear音频数据的首地址
		  sample_NUM:  输入,PCMu音频的样本数

返回值:
		  ERR_PARAM:参数错误。
		  OK:       正确返回。
功能:	  将传进的PCMu的音频数据转换成16位的PCMlinear
***************************************************************/

inline int code_ulaw2linear(unsigned char * pSrcData,short int * pDstData,short int sample_NUM)
{
	short int i;
	if( (pSrcData==NULL) || (pDstData==NULL))
	{
	return (ERR_PARAM);
	}
	for(i=0;i<sample_NUM;i++)
	{
		*(pDstData+i)=g_s_ms_ulaw2linear[(unsigned char)(*(pSrcData+i))];
	}
	return (OK);
}

#ifdef DEBUG

main(int argc,char *argv[])
{
	ulawCreat();
	linearCreat();
	short int a[NUM];
	unsigned char b[NUM];
	short int c[NUM];
	FILE *fp1,*fp;
	char mixname1[255];
	char mixname2[255];
	strcpy (mixname1, "bianma_u.snd");
	strcpy (mixname2, "jiema_linear.snd");
	fp1=fopen(argv[1],"r");
	
	fread(a,sizeof(short int),NUM,fp1);
	fclose(fp1);
	
	code_linear2ulaw(a,b,NUM);
	code_ulaw2linear(b,c,NUM);

	fp=fopen(mixname1, "w+");
	fwrite(b,sizeof(unsigned char),NUM,fp);
	fclose(fp);

	fp=fopen(mixname2, "w+");
	fwrite(c,sizeof(short int),NUM,fp);
	fclose(fp);

}

#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -