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<i+1) {
C5C6C7C8=getBianry(i,4);
break;
}
}
result=String.valueOf(C1)+String.valueOf(C2C3C4)+String.valueOf(C5C6C7C8);
}
System.out.println("所求误差为:"+(Vs-getVs(Integer.parseInt(result))));
return Integer.parseInt(result);
}
public double getVs(int Bianry) {
System.out.println("解码得到的八位二进制数为: "+Bianry);
ArrayList<Integer> num = new ArrayList<Integer>();
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<stringArr.length;i++) {
String str1=String.valueOf(stringArr[i]);
num.add(Integer.parseInt(str1));
}
C2C3C4=Integer.parseInt(String.valueOf(num.get(0))+String.valueOf(num.get(1))+String.valueOf(num.get(2)));
C5C6C7C8=Integer.parseInt(String.valueOf(num.get(3))+String.valueOf(num.get(4))+
String.valueOf(num.get(5))+String.valueOf(num.get(6)));
num1=getNum(C2C3C4);
num2=getNum(C5C6C7C8);
result=vs[num1]+(num2+0.5)*((vs[num1+1]-vs[num1])/16);
}
else
System.out.println("Vs为正阴极");
System.out.println("求得模拟电平值为: "+result);
return result;
}
public void inaccuracy() {
//inaccuracy=Vs-result;
}
public static int getBianry(int i,int n) {//n为要求保留几位有效位
ArrayList<Integer> workload=new ArrayList<Integer>();
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<n) {
for(int l=0;l<=n-m;l++)
Bianry="0"+Bianry;
}
return Integer.parseInt(Bianry);
}
public static int getNum(int i) {
String str=String.valueOf(i);
int Num=0;
char [] stringArr = str.toCharArray();
//System.out.println(stringArr[2]);
int count=stringArr.length-1;
for(int j=0;j<=stringArr.length-1;j++) {
//System.out.println(Math.pow(2, count));
String s=String.valueOf(stringArr[j]);
Num+=(int) (Integer.parseInt(s)*Math.pow(2, count));
count--;
}
return Num;
}
}
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~
