PCM脉冲调制编码的Java实现[文末福利(doge)]

PCM脉冲调制编码的Java实现[文末福利(doge)],第1张

PCM脉冲调制编码的Java实现[文末福利(doge)] 1、实验目的

       在模拟信号的数字传输中,当模拟信号传输到信道之前,我们需要对模拟信源进行模拟信号的数字化过程。
       首先我们将通过抽样定理对模拟信号进行抽样,然后对抽样信号进行量化。由于均匀量化的产生的量化误差比较大,在某些频段上的模拟信号信噪比较大,所以我们对抽样信号进行不均匀量化。不均匀量化可以改善小信号区的量化信噪比,在量化电平数目M不变情况下,对大信号区使用的量化阶步较大;小信号区使用的量化阶步较小。我们采取两种用于话音数字化的标准的对数压扩特性的方法,μ律压扩特性和A律压扩特性。
       在实验中,我将用程序模拟A律的十三折线对模拟信号进行量化,最终实现PCM脉冲调制的编码。并且可以通过最终的PCM编码反过来求模拟电平的值,进而得到PCM编码中的量化误差。

2、实验思路

       在eclipse/idea中利用java语言模拟PCM脉冲编码调制方法。我新建了一个ARuleDecoding 类。由于在PCM编码中对模拟信号(电平)的量化结果得到了一个十进制的数值,最后译码得到脉冲编码调制的二进制数字基带信号。PCM的解码过程是将八位二进制数通过A律13折线近似的折叠二进制编解码,得到模拟信号的电平值。然后将其与原始抽样信号的电平值进行比较,得到量化误差。

3、具体方法

       首先我在ARuleDecoding类中定义最小的量化阶步δmin(第1和第2大段中的一个小段δ1 和δ2)为 △,在java中我表示为delta = 1/2048;接着我写了int getBianry(int i,int n)把十进制转化为n位有效位的二进制数的方法和int getNum(int i) 把二进制数转化为十进制数的方法。
       接着,在下面的PCM脉冲调制解码和译码中,我将对A律13折线中的正半轴(电平正极性)进行调制。由于对称性,负半轴(电平负极性)的调制与其相似。我们先考虑十六大段中正半轴的八大段,设置8位折叠二进制码C1C2C3C4C5C6C7C8 。在编码过程中,我首先对传入的电平的正负性进行判断。如果是传入的电平值为正数,则C1为1,反之为0;
       然后我们判断vs电平值落在正半轴的哪一个大段上面;这里我通过在数组中存入每一个大段(1~8)端点的值与|vs|进行比较,判断模拟信号的电平值落在哪一个大段。通过判断|vs|落在哪一个大段区间得到相应的二进制值,从而得到 C2C3C4 大段落码的值。
       最后我们像前一步一样,把每一个大段分为十六个小段。然后求出相应的大段对应的小段的值,判断该模拟电平落在哪一个小段里面,然后按照量化电平序号对应的折叠二进制码,得到C5C6C7C8对应二进制编码的值。至此,解码结束。译码过程是解码的反过程,首先通过C1判断电平是落在正半轴还是负半轴,然后通过C2C3C4的二进制码判断其落在第几大段。最后通过C5C6C7C8判断落在第几小段。最后用大段的左值加上小段的左值加上0.5乘最小的量化阶步△得到模拟电平的值。至此,译码结束。

4、代码
import java.util.ArrayList;

public class ARuleDecoding {

   public ARuleDecoding() {  }
   public double delta = 1/2048;
   double[] vs = {0,1.0/128,1.0/64,1.0/32,1.0/16,1.0/8,1.0/4,1.0/2,1};//分别对应7-0(1/2的幂次)
   double[] VS = {-1.0/128,-1.0/64,-1.0/32,-1.0/16,-1.0/8,-1.0/4,-1.0/2,-1,0};
   int C1,C2C3C4,C5C6C7C8=0;
   double temp=0;
   String result;
   
   
   //设最小的量化阶步δmin(第1和第2大段中的一个小段δ1 和δ2)为 △,在java中我表示为
   
   public int getCode(double Vs) {//Vs是电频幅度的值
	   System.out.println("传入的电平值为: "+Vs);
	   if(Vs<0) {
		   C1=0;
		   Vs=-Vs;
	   }else
		   C1=1;//Vs为正阳极
	   if(Vs>0) {
		  //为抽样信号电平绝对值|Vs|
		  for(int i=0;i<=8;i++) {
			  if(Vs>vs[i]&&Vs<=vs[i+1]) {
				  C2C3C4=getBianry(i,3);
				  temp=((Vs-vs[i])/((double)(vs[i+1]-vs[i])/16));
				  break;
			  }
		  }
        for(int i=0;i<10;i++) {
        	if(temp>=i&&temp num = new ArrayList();
	   int num1,num2=0;
	   double result=0;
	   String str=String.valueOf(Bianry);
	   char [] stringArr = str.toCharArray();
	   if(stringArr[0]=='1') {
		   //System.out.println("Vs为正阳极");
           for(int i=1;i workload=new ArrayList();
	   int j,m=0;
	   String Bianry=null;
	   while(i!=0) {
		   j=i%2;
		   workload.add(j);
		   i=i/2;//向下取整数
		   m++;
	   }
	   if(workload!=null) {
		   Bianry=String.valueOf(workload.get(workload.size()-1));
		   for(int k=workload.size()-2;k>=0;k--) {
			   Bianry=Bianry+String.valueOf(workload.get(k));
		   }
	   }
	   if(m 
5、测试 

       写一个主函数测试一下~

public static void main(String[] args) {
		//System.out.println('0'+'1');
		ARuleDecoding ard =new ARuleDecoding();
		ard.getCode(0.4);
		System.out.println("-------");
		ard.getVs(11011001);
		}
结果如右图所示: 6、结语

       这是我大二通信概论自己熬夜肝的作业,正好周末有空整理出来。我其实是软工的学生hhh,如有错误请指正,觉得不错请三连!!!感谢!1024,祝大家节日快乐,快乐才是最重要!
       PS:下图是我用java实现AMI编码、CMI编码等的手写代码,不定期会上传资源。如急需有偿¥,也可以私聊,peace~

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/4746123.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-11-08
下一篇 2022-11-08

发表评论

登录后才能评论

评论列表(0条)

保存