PCM 非均匀量化编码 (PCMUQC) 代码 - MATLAB 实现
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% FileName: PCMUQC_code.m
% Description: PCM非均匀量化编码 量化,编码
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Parameter List:
% Output Parameter
% xx A律折线坐标X轴
% yy A律折线坐标Y轴
% PCM_modcodedata 编码后数据
%
% Input Parameter
% a13_acode 压缩后数据
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [ xx,yy,PCM_modcodedata] = PCMUQC_code( a13_acode )
%%%
% % % A律折线坐标
xx=[-1,-1/2,-1/4,-1/8,-1/16,-1/32,-1/64,-1/128,1/128,1/64,1/32,1/16,1/8,1/4,1/2,1];%13折线X轴
yy=[-1,-7/8,-6/8,-5/8,-4/8,-3/8,-2/8,-1/8,1/8,2/8,3/8,4/8,5/8,6/8,7/8,1];%13折线Y轴
n=length(a13_acode);
PCM_modcodedata=zeros(1,n*8);%得到8位pcm编码
%对抽样后数据进行 非均匀量化编码
x1=a13_acode;% 对抽样压缩后数据进行 非均匀量化编码
for m=1:n
Is=x1(1,m);% 归一化后 输入数据第m样点值
if Is>1||Is<-1
error('归一化错误') %('input must within [-1,1]')
end
Is=round(Is*2048); % Is 为 输入数据第m样点,放大128,按照非均匀量化规则量化编码
C=zeros(1,8); %将8位PCM编码初始化为全0
if Is>0
C(1)=1 ; %判断抽样值的正负
end
% the polarity determins C(1)
abIs=abs(Is); %取绝对值 , 极性由第一位编码确定,数值大小 由后七位编码确定
if 0<abIs && abIs<=16 %16级量化编码 按照段内起始电平 段内量化间隔对数据进行编码 函数自编。
C(2:4)=[0 0 0]; %8级量化编码
q=1; % 段内量化间隔
a=0; % 段内起始电平
C(5:8)=e_coding(abIs,q,a); %16级量化编码
end
if 16<abIs && abIs<=32
C(2:4)=[0 0 1];
q=1;
a=16;
C(5:8)=e_coding(abIs,q,a);
end
if 32<abIs && abIs<=64
C(2:4)=[0 1 0];
q=2;
a=32;
C(5:8)=e_coding(abIs,q,a);
end
if 64<abIs && abIs<=128
C(2:4)=[0 1 1];
q=4;
a=64;
C(5:8)=e_coding(abIs,q,a);
end
if 128<abIs && abIs<256
C(2:4)=[1 0 0];
q=8;
a=128;
C(5:8)=e_coding(abIs,q,a);
end
if 256<abIs && abIs<=512
C(2:4)=[1 0 1];
q=16;
a=256;
C(5:8)=e_coding(abIs,q,a);
end
if 512<abIs && abIs<=1024
C(2:4)=[1 1 0];
q=32;
a=512;
C(5:8)=e_coding(abIs,q,a);
end
if 1024<abIs && abIs<=2048
C(2:4)=[1 1 1];
q=64;
a=1024;
C(5:8)=e_coding(abIs,q,a);
end
PCM_modcodedata(1,(m-1)*8+1:m*8)=C; %得到8位pcm编码
end
end
补充代码内容:function y=e_coding(x,q,a)
% 对不同量化区间 按照段内起始电平 段内量化间隔对数据进行编码
% 参数说明:x:采样值(绝对值);q:量化间隔;a:段内起始电平
% 返回值:y:量化后编码结果
n=log2(q); %段内量化间隔q的二进制位数
d=x-a; %偏移量
if n==1 %量化间隔为2
if d<0
y=[0 0 0 1];
else
y=[0 0 1 0];
end
elseif n==2 %量化间隔为4
if d<0
if abs(d)<q/2
y=[0 0 0 1];
else
y=[0 0 1 0];
end
else
if d<q/2
y=[0 1 0 1];
elseif d<q
y=[0 1 1 0];
else
y=[1 0 0 0];
end
end
elseif n==3 %量化间隔为8
if d<0
if abs(d)<q/2
y=[0 0 0 1];
elseif abs(d)<q
y=[0 0 1 0];
elseif abs(d)<3*q/2
y=[0 1 0 1];
elseif abs(d)<2*q
y=[0 1 1 0];
else
y=[1 0 0 0];
end
else
if d<q/2
y=[0 1 0 1];
elseif d<q
y=[0 1 1 0];
elseif d<3*q/2
y=[1 0 0 1];
elseif d<2*q
y=[1 0 1 0];
else
y=[1 1 0 0];
end
end
elseif n==4 %量化间隔为16
if d<0
if abs(d)<q/2
y=[0 0 0 1];
elseif abs(d)<q
y=[0 0 1 0];
elseif abs(d)<3*q/2
y=[0 1 0 1];
elseif abs(d)<2*q
y=[0 1 1 0];
elseif abs(d)<5*q/2
y=[1 0 0 1];
elseif abs(d)<3*q
y=[1 0 1 0];
elseif abs(d)<7*q/2
y=[1 1 0 1];
else
y=[1 1 1 0];
end
else
if d<q/2
y=[0 1 0 1];
elseif d<q
y=[0 1 1 0];
elseif d<3*q/2
y=[1 0 0 1];
elseif d<2*q
y=[1 0 1 0];
elseif d<5*q/2
y=[1 1 0 1];
elseif d<3*q
y=[1 1 1 0];
elseif d<7*q/2
y=[1 1 1 1];
else
y=[1 1 1 1];
end
end
end
end
原文地址: https://www.cveoy.top/t/topic/ot9E 著作权归作者所有。请勿转载和采集!