⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 compressorint16clip2.m

📁 模拟语音信号的动态范围压缩算法的matlab源码
💻 M
字号:
function [y,G_out] = compressorINT16clip2(x,Fd,G_in,M)
%compressor with the same fixed-point algorithm with CCS
% y = compressorINT16clip2(x,Fd,G_in,M)
%x      -- the input signal array
%Fd     -- the full deviated amplitude
%G_in   -- the initial Gain
%M      -- update the compressor gain every M samples
%
%y      -- the compressed signal array
%G_out  -- the output Gain
%
%Companding Specificationn
%      Compression Ratio 2:1
%      Crossover Point   60% of full audio deviation
%      Attack Time       3.3 ms
%      Recovery Time     14.85 ms
%
%
INT16_SCALE = 32768;

persistent average counter mean old_x_array ac1 ac1_1 ac2 ac2_1;

%the input array x is averaged by the following formula
%   average = ac*average + (1-ac)*x;

%the mean stores the mean of the previous 40 input samples
%                  i
%   mean =(1/40)* SUM abs(x(k))
%               k=(i-39)

%initialization
if isempty(ac1)
    ac1 = float2Fract(0.98875);
    ac1_1 = 2^31 - fract2LongFract(ac1); %float2LongFract((1-0.98875));
    ac2 = float2Fract(0.9999);
    ac2_1 = 2^31 - fract2LongFract(ac2); %float2LongFract((1-0.9994));
    
    ac_diff = float2Fract(0.9995);
    ac_diff_1 = 2^31 - fract2LongFract(ac_diff);
    
    counter = 0;
    average = 0;
    average2 = 0;
    mean = 0;
    old_x_array = zeros(1,40);
end


ac = ac1;
ac_1 = ac1_1;
Uc = fractMult(float2Fract(0.6366),Fd);
sqrtUc = float2Fract(sqrt(fract2Float(Uc)));

%for test only
global mean_g average_g diff_g avg_dif_g G_in_g flag_g avg_dif_float_g average2_g;

avg_dif = 0;
avg_dif_float = 0;                              %test only  
OneForty = float2Fract(1/40);
temp1 = 0;
temp2 = 0;
scale_flag = 0;

for i = 1:length(x)
    abstract = abs(x(i));
    
  
    temp1 = longLongFractMult(temp1,ac) + longLongFractMult(ac_1,abstract);       %averager. divide 2^15 for fractional multiplication.
    average = longFract2Fract(temp1);
    
    
    %average the abstract with the primary coefficient
    temp2 = longLongFractMult(temp2,ac1) + longLongFractMult(ac1_1,abstract); 
    average2 = longFract2Fract(temp2); 
    average2_g(i) = average2;
    
    mean = mean - fractMult(OneForty,old_x_array(1)) + fractMult(OneForty,abstract);    %update mean
    
    mean_g(i)= mean;                            %test only
    
    if counter == 0                             %update gain every M times     
        if average == 0
            average = float2Fract(2^-15);                % 2^-15
        end
        sqrtAvg = float2Fract(sqrt(fract2Float(average)));
        G_in = sqrtUc/sqrtAvg;
        G_in_floor = floor(G_in);
        G_in_fract = float2Fract(G_in - floor(G_in));
        counter = M;
    end
    
    G_in_g(i) = G_in;
    
    old_x_array(1:39) = old_x_array(2:40);
    old_x_array(40) = abs(x(i));
    
    difference = abs(mean-average);
    
    diff_g(i) = difference;                     %test only
    average_g(i) = average;                     %test only
    
    if difference > fractMult(mean,float2Fract(0.1))        %0.1*mean
        avg_dif = fract2LongFract(difference);        %scale up 6 bits to prevent fix-point effect in calculating average difference
        avg_dif_float = difference;              %test only
        ac = ac1;
        ac_1 = ac1_1;
        
        flag_g(i) = 0;                          %test only
    else
        avg_dif = longLongFractMult(ac_diff_1,difference) + longLongFractMult(avg_dif,ac_diff);
        avg_dif_float = difference + 0.9995*(avg_dif_float-difference);   %test only
        
        if avg_dif < longLongFractMult(float2LongFract(0.04),mean)
            ac = ac2;
            ac_1 = ac2_1;
            flag_g(i) = 1000;                    %test only
        else
            ac = ac1;
            ac_1 = ac1_1;
            flag_g(i) = 0;                       %test only
        end
    end
       
    avg_dif_g(i) = avg_dif;                     %test only
    avg_dif_float_g(i) = avg_dif_float;         %test only
    
    counter = counter - 1;
    
    temp = fractMultInt(x(i),G_in_floor) + fractMult(G_in_fract,x(i));
    if temp >= INT16_SCALE - 1
        temp = INT16_SCALE - 1;
    end
    if temp < -INT16_SCALE
        temp = -INT16_SCALE;
    end
    y(i) = temp;
end

G_out = G_in;                               %store the current gain

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -