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

📄 pcm22212.c

📁 c实现的A律/mu律pcm编译码算法 只需要根据不同的需要更改输入数据即可
💻 C
字号:
#include <alawmain.h>

int main(void)
{
	short aa[10];
	short *temp3;
	int k;
	for(k=0;k<10;k++)
	scanf("%d",aa+k);
	temp3=alawmain(aa);

}
	                                          
short * alawmain(short a[])
{
	int i,j;
	float n=256;
	float d;
	double A=87.56;
	int num=2400;
	//short a[10];//absf[10]
	double f[2400],absf[2400];
	//double fquan[10];
	int bquan[2400];
	float q[256];
	int nu=log(n)/log(2);                //码字长度=log2(n)
	int code[2400][8]={0};   //10=4800,nu=log2(n)
	double *temp2,*temp1;
	double aquan[2400]; //恢复后的采样点           //
	double temp[2400];
	printf("input a:");
for(i=0;i<10;i++)
   scanf("%d",a+i);//输入采样点
temp2=alaw(a);
for(i=0;i<2400;i++)
	temp[i]=temp2[i];
for(i=0;i<2400;i++)
	printf("alaw:%f\n",temp[i]);
for(i=0;i<2400;i++)
{
	f[i]=temp[i];               //经过A律压缩的采样点
	absf[i]=absfunc(f[i]);     //define absf[10] ,call absfunc()	        
}
d=2/n;                          //量化间隔
for(i=0;i<n;i++)
{
	q[i]=d*i;
	q[i]=q[i]-((n-1)/2)*d;          //量化电平,将0~2影射到-1~1
}
for(i=0;i<2400;i++)
	if(f[i]!=1)
	{
		for(j=0;j<n;j++)
		{
		
			if((q[j]-d/2<=f[i])&&(f[i]<q[j]+d/2))
				f[i]=q[j];               //赋值为相应的量化电平
			if(f[i]==q[j])
				bquan[i]=j;//对量化电平进行编号
		}
	}
	else
	{
		f[i]=q[(int)n-1];
		bquan[i]=(int)n-1;
	}

for(i=0;i<2400;i++)
{
	if(bquan[i]<(int)n/2)
		bquan[i]=(int)n/2-bquan[i]-1;               //对折叠码进行处理
	for(j=nu;j>0;j--)
	   if(floor(bquan[i]/pow(2,(j-1)))==1)
	   {
		   code[i][nu-j]=1;               //编码矩阵
		   bquan[i]=bquan[i]-pow(2,(j-1));          //从高向低编码
	   }
	
}
//return *bquan;   //?????
for(i=0;i<2400;i++)
{
	for(j=0;j<nu;j++)
	printf("%d",code[i][j]);
	printf("\n");
}
//for(i=0;i<10;i++)
//for(j=0;i<nu;j++)
//{
//	if(code[i][j]==1)
//		fquan[i]=pow(2,nu-j)+fquan[i];
//}

for(i=0;i<2400;i++)                                       //译码
{
	temp1=invalaw(f);   //对量化完毕的信号进行A律的扩张//
	aquan[i]=temp1[i]*2048; //由于扩张后得到的结果是对原信号的归一化,因此需要进行恢复
}  
for(i=0;i<2400;i++)
{
	aquan[i]=(short)aquan[i];
    printf("%f\n",aquan[i]);
}
return aquan;

}
//A律扩张                                                     
double * invalaw(double y[])                                 //
//INVALAW A律非线性的逆                                       
//X=INVALAW(Y,A)Y=A律非线性的归一化输出                         
{                                                           //
	int i;
	double x[2400];//
	for(i=0;i<2400;i++)                                          //
    if(absfunc((double)y[i])<=1/(1+log(87.56)))
       x[i]=((double)y[i])*(1+log(87.56))/87.56;
    else                                                   //
		x[i]=signfunc1(y[i])*((exp((absfunc(y[i]))*(1+log(87.56))-1))/87.56);
	return x;
}

double * alaw(short x[])
{
	double absx[2400];
	int i;
	double y[2400];
	for(i=0;i<2400;i++)
		{
		
		absx[i]=absfunc(x[i]);     //define absx[10] ,call absfunc()
		}
	for(i=0;i<2400;i++)
	{
		if(absfunc((double)x[i]/2048)<=1/87.56)
            y[i]=87.56*(absx[i]/2048)/(1+log(87.56));
 
		else
            y[i]=signfunc(x[i])*((1+log(87.56*((double)absx[i]/2048)))/(1+log(87.56)));
	}
	return y;                 //return y[i]; ?
}

double max(double * x)
{
	double temp=x[0];
	int i;
    for(i=0;i<=2400;i++)   //
         temp=(x[i]>=temp? x[i]:temp);
    return temp;

}
double absfunc(double data)  //abs函数返回的是int类型的数据,自己写的返回doule的函数
{
	double x;
	if(data<0)
		x=-data;
	else x=data;
	return x;
}
int signfunc(int y)   // sign函数
{
	int ydata;
	if(y<0)
		ydata=-1;
	else ydata=1;
	return ydata;
}
int signfunc1(double y)
{
		int ydata;
	if(y<0)
		ydata=-1;
	else ydata=1;
	return ydata;
}

⌨️ 快捷键说明

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