一、首先,我们用C语言产生一段正弦波,用一定的采样频率对它进行采样,并把采样值存到一个文本文件中。
void main(void)
{
int i;
int f =1000; //1000hz的正弦波
float fs = 8000.00; //采样频率为80000hz
float s,t,w;
const float PI = 3.141;
FILE *fpt;
fpt = fopen("Sine.txt","w"); //创建txt文件存储正弦数列值
for(i=0; i< 80000;i++) //采样十个周期
{
t=i/(f*fs);
w=f*2*PI;
s = sin(w*t); //获取采样值
//printf(" %f;\n", s);
fprintf(fpt,"%f\n",s); //把采样值输出到文件中
}
fclose(fpt);
Pcm_bianma("Sine.txt");
}
采样结果:
二、把文件中的数据读出来,作十三折线换算。
输入为x,输出为y。
for(i=0;i<80000;i++)
{
b=j[i]; //记录符号
if (b>=0)
{
m=1;
}
else
{
m=-1;
}
d=fabs(b);
//printf("%f\n",b);
if(d>=0&&d<0.015625) //十三折线换算法
{
y=16*d;
}
else if(d>=0.015625&&d<0.03125)
{
y=d*8+0.125;
}
else if(d>=0.03125&&d<0.0625)
{
y=4*d+0.25;
}
else if(d>=0.0625&&d<0.125)
{
y=2*d+0.375;
}
else if(d>=0.125&&d<0.25)
{
y=d+0.5;
}
else if(d>=0.25&&d<0.5)
{
y=0.5*d+5/8.00;
}
else if(d>=0.5&&d<=1)
{
y=0.25*d+3/4.00;
}
//printf("%f\n",y);
c=y*m; //恢复符号
//printf("%f\n",c);
j[90000]=""; //清空缓存区
j[i]=c; //存入换算后的值
}
换算结果:
可发现数据被压缩在|0.2——1.0|之间。
三、进行pcm编码。
for(i=0;i<80000;i++)
{
f=j[i];
//printf("data = %f\n", f);
g=f*2048; //2048个量化等级
//printf("%f\n ",g);
e=floor(g); //对数据进行靠0取整
int x[8]={0}; //用来储存编码数据
int z[8]={0,16,32,64,128,256,512,1024}; //对应量化区间
int y[8]={1,1,2,4,8,16,32,64}; //每个量化区间按16等分后的每一小段量化等级
//printf("e= %d\n", e);
if(e<0) //符号位判断,小于0第一位码为0,大于0第一位码为1
{
x[0]=0;
e=abs(e); //判断小于0后取绝对值
}
else
{
x[0]=1;
//printf("%d\n ",x[0]);
}
//printf("%d\n",x[0]);
if (e>128) //段落码第一位判断
{
x[1]=1;
}
if ((e<=32)||((e>=128)&&(e<=512))) //段落码第二位判断
{
x[2]=0;
}
else
{
x[2]=1;
}
if (((e>=16)&&(e<32))||((e>=64)&&(e<128))||((e>=256)&&(e<=512))||((e>=1024)&&(e<2048))) //段落码第三位判断
{
x[3]=1;
}
else
{
x[3]=0;
}
/*for(int p=0;p<4;p++)
{
printf("%d",x[p]);
}
printf("aaaa\n ");*/
h=x[1]*4+x[2]*2+x[3]; //根据段落码算出在第几段
//printf("%d\n",h);
k=(e-z[h])/y[h]; //算出在段内第几段
if (k==0)
{
x[4]=0,x[5]=0, x[6]=0, x[7]=0; //输入为0,输出也为0
}
else
{
int num =7; //从高位开始编码
while (k>0)
{
x[num]=k%2; //取余编码
num=num-1;
k=k/2;
}
if(num > 4) //高位编码
{
while(num >4)
{
x[num] = 0;
num = num - 1;
}
}
//printf("encode end\n");
}
for (int m =0;m<8;m++) //打印编码数组
{
//buf[i][m]=x[m];
//printf("%d",x[m]);
fprintf(fpt,"%d",x[m]); //输出到文件中
}
//printf("\n ");
fprintf(fpt,"\n");
}
fclose(fp);
fclose(fpt);
printf("encode end\n"); //编码结束
编码结果:
此时便完成采样率为8000hz的正弦波的十个周期的pcm编码。