%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%  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
PCM 非均匀量化编码 (PCMUQC) 代码 - MATLAB 实现

原文地址: https://www.cveoy.top/t/topic/ot9E 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录