在模拟信号的数字传输中,当模拟信号传输到信道之前,我们需要对模拟信源进行模拟信号的数字化过程。
首先我们将通过抽样定理对模拟信号进行抽样,然后对抽样信号进行量化。由于均匀量化的产生的量化误差比较大,在某些频段上的模拟信号信噪比较大,所以我们对抽样信号进行不均匀量化。不均匀量化可以改善小信号区的量化信噪比,在量化电平数目M不变情况下,对大信号区使用的量化阶步较大;小信号区使用的量化阶步较小。我们采取两种用于话音数字化的标准的对数压扩特性的方法,μ律压扩特性和A律压扩特性。
在实验中,我将用程序模拟A律的十三折线对模拟信号进行量化,最终实现PCM脉冲调制的编码。并且可以通过最终的PCM编码反过来求模拟电平的值,进而得到PCM编码中的量化误差。
在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乘最小的量化阶步△得到模拟电平的值。至此,译码结束。
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~欢迎分享,转载请注明来源:内存溢出
评论列表(0条)