📄 expanderint16clip.m
字号:
function [y,G_out] = expanderINT16clip(x,Fd,G_in,M)
%expander
% y = expanderINT16clip(x,Fd,G_in,M)
%x -- the input signal array
%Fd -- the full deviated amplitude
%G_in -- the initial Gain
%M -- update the expander gain every M samples
%
%y -- the expanded 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 ae ae_1 average counter mean old_x_array ae1 ae1_1 ae2 ae2_1 ae_diff ae_diff_1;
%initialization
if isempty(ae)
ae1 = float2Fract(0.99436);
ae1_1 = 2^31 - fract2LongFract(ae1); %float2LongFract((1-0.99436));
ae2 = float2Fract(0.99985);
ae2_1 = 2^31 - fract2LongFract(ae2); %float2LongFract((1-0.99985));
ae_diff = float2Fract(0.9995);
ae_diff_1 = 2^31 - fract2LongFract(ae_diff);
counter = 0;
average = 0;
mean = 0;
old_x_array = zeros(1,40);
end
Ue = fractMult(float2Fract(0.6366),Fd);
ae = ae1;
ae_1 = ae1_1;
global mean_e_g average_e_g diff_e_g avg_dif_e_g Ge_g flag_e_g avg_dif_float_e_g; %test only
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,ae) + longLongFractMult(ae_1,abstract); %averager. divide 2^15 for fractional multiplication.
average = longFract2Fract(temp1);
average_e_g(i) = average; %test only
mean = mean - fractMult(OneForty,old_x_array(1)) + fractMult(OneForty,abstract); %update mean
mean_e_g(i)= mean; %test only
if counter == 0 %update gain every M times
G_in = average/Ue;
G_in_floor = floor(G_in);
G_in_fract = float2Fract(G_in - floor(G_in));
counter = M;
end
Ge_g(i) = G_in; %test only
old_x_array(1:39) = old_x_array(2:40);
old_x_array(40) = abs(x(i));
difference = abs(mean-average);
diff_e_g(i) = difference; %test only
average_e_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
ae = ae1;
ae_1 = ae1_1;
flag_e_g(i) = 0; %test only
else
avg_dif = longLongFractMult(ae_diff_1,difference) + longLongFractMult(avg_dif,ae_diff);
avg_dif_float = difference + 0.9995*(avg_dif_float-difference); %test only
if avg_dif < longLongFractMult(float2LongFract(0.04),mean)
ae = ae2;
ae_1 = ae2_1;
flag_e_g(i) = 1000; %test only
else
ae = ae1;
ae_1 = ae1_1;
flag_e_g(i) = 0; %test only
end
end
avg_dif_e_g(i) = avg_dif; %test only
avg_dif_float_e_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 + -