c语言实现十三折线pcm编码

一、首先,我们用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编码。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值