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

📄 agc.m

📁 数字AGC仿真代码适合于基础的了解数字控制模块
💻 M
字号:
% Automatic Gain Control (Version 1.1 For stereo input output)
%
% usage : y = AGC(x,gain_level,samples)
%
% where :
%          y        : output samples with required gain (range from -1 to +1)
%          x        : input samples (range from -1 to +1)
%       gain_level  : required gain in db
%          N        : number of samples 
%
% Example:
%       y=AGC(data,28,256);
%         data.mat file contains  256 data samples (import this file in workspace for MONO input)
%         data2.mat file contains  256 data samples (import this file in workspace for STEREO input)
%
% Programmer            : Jaydeep Appasaheb Dhole
%                       : Associate Software Engineer ( DSP )
%                       : Aparoksha Tech. Pvt. Ltd. ,Bangalore.
%                       : http://www.aparoksha.com
%                       : <jaydeepdhole@gmail.com>
%
% Version               : 1.1(For Mono and Stereo input signals)
%
% Date                  : 1 June 2006.
%
% Description : AGC algorithm is used to automatically adjust the speech level 
%               of an audio signal to a predetermined value 
%               (normally used unit is in decibel or db )
%                so that subsequent processing operates on signals within a specified dynamic range
%
%       here first understand the concept of the power
%       POWER : average energy over a period. Assuming that the period is N samples,
%
%              N-1     
%             ----     
%          1  \        2
%  P    = --- /    x[n]        power of the signal                     ....eq(1)
%          N  ---- 
%             n = 0  
%
%            N-1     
%           ----     
%          \        2
%  E    =  /    x[n]           energy of the signal                    ....eq(2)
%          ---- 
%           n = 0  
%
%  p (in db) = 10*log10(p/p_ref)
%  since the value of p_ref is taken as 1 Watt , equation becomes
%
%  p (in db) = 10*log10(p)
%
%  now we have to find out the multiplication factor such that :
%                                  
%            output power    =    input power   *   K_Coeff.
% 
%              N-1                   N-1
%             ----                   ----
%          1  \        2          1  \        2
%         --- /    y[n]     =    --- /    x[n]      *    K_Coeff
%          N  ----                N  ----
%             n = 0                  n = 0 
%
%
%
%              N-1                   N-1
%             ----                   ----
%             \        2            \          2
%             /    y[n]     =       /    ( x[n]  *  K )
%             ----                  ----
%             n = 0                  n = 0 
%
%
%      here we are finding the value of K so that we can multiply with 
%      input samples so we will get "output samples with required power"
%
%
%                                      /--------                         
%                       therefor K = \/ K_Coeff
%
%             /------------------------------  
%       K = \/(output_power/input_power)               
%
%             /------------------------------  
%       K = \/(output_power/(input_energy/N))
%
%             /------------------------------  
%       K = \/(output_power*N)/input_energy                             ....eq(3)
%
%       y[0...n] = x[0...n] * K                                         ....eq(4)
%

function [y]= AGC(x,gain_level,N)
 
% for checking the the number of channels
MONO     = 1;
STEREO   = 2;

% if input power level is below threshold don't  do anything
% by changing this value u can change the threshold level
THRESHOLD_VALUE   = -40 ;

% set the output power range here
OUTPUT_POWER_MIN  = -30 ;
OUTPUT_POWER_MAX  = +30 ;

% read the number of channel(s) and  size of the input signal
[m,n]=size(x);

% check validation for mono or stereo signal
if( (n ~= MONO) & (n ~= STEREO) )
        num2str('input signal has invalid channels exiting ...')  %optional for testing
        %if input channel(s) are invalid then exit from the function
        y=0;
        return 
end

% check validation input signal size and number of samples
if((1 == m) | (m < N))
        num2str(' Warning : input signal length is less than samples exiting ...')  %optional for testing
        %if input channel(s) are invalid then exit from the function
        y=0;
        return 
end

% check for input signal is not zero if zero exit
if( 0 == any(x))
        num2str('input signal is ZERO exiting ...')  %optional for testing
        %if input channel(s) are invalid then exit from the function
        y = x(1:N,:); 
        return 
end

% calculate input power
p_db=10*log10(sum(x(1:N,:).^2)/N);                                  
num2str(p_db,'\n input power in db %5f')                            %optional for testing

% check for threshold 
if( min(p_db) < THRESHOLD_VALUE )
        num2str('input power level is below threshold exiting ...')  %optional for testing
        %if input below threshold then output = input
        y = x(1:N,:); 
        return 
end

% check for output power limits
if( (gain_level < OUTPUT_POWER_MIN) | (gain_level > OUTPUT_POWER_MAX) )
        num2str('output power level is out of range exiting ...')  %optional for testing
        %if required output power is out of range then output = input
        y = x(1:N,:); 
        return 
end

% calculate the normal value of the output power 
% as per our gain level
% gain_level = 10*log10(output_power_Normal)  
% by solving the equation we get 
% output_power_Normal=10.^(gain_level/10);
output_power_Normal = 10.^(gain_level/10);

% calculate the energy of the input                                 (...Refer eq(2))
% here one more advantage of the energy calculation is to avoid the division
% in fix point arithmetic division is expensive so try to avoid the division 
energy = sum(x(1:N,:).^2);

if( n == STEREO)

    num2str('input signal is STEREO.')  %optional for testing

    % calculate the multiplication factors K1 and K2 for stereo signal   (...Refer eq(3))
    K1 = sqrt( (output_power_Normal*N) / energy(:,1));
    K2 = sqrt( (output_power_Normal*N) / energy(:,2)); 

    % multiply K with input samples to get required stereo output samples      (...Refer eq(4))
    y(1:N,1) = x(1:N,1) * K1;
    y(1:N,2) = x(1:N,2) * K2;

else
    
    num2str('input signal is MONO.')  %optional for testing

    % calculate the multiplication factor K1 for mono signal (...Refer eq(3))
    K1 = sqrt( (output_power_Normal*N) / energy);

    % multiply K1 with input samples to get required output samples      (...Refer eq(4))
    y(1:N,1) = x(1:N,1) * K1;
end

p_db=10*log10(sum(y.^2)/N);                                         %optional for testing                             
num2str(p_db,'\n output power in db %5f')                           %optional for testing

% You can comment out the optional part it is just for testing

⌨️ 快捷键说明

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