%% DESC9200 Lab Report - MultiBand Noise Gate Function
% Author           : Alexander Christian Nugroho - 450039470
% Based on work by : Mclean Pierce, David Cuthberson 

% This function will split the input file into 3 separate bands (Lowpass, Bandpass,
% Highpass) using filters. It will then apply some noise gating using the
% "mynoisegt.m" function in the three separate bands, and combining it
% together to produce the final output.

function [ngateOut, oriOut, fs] = mymultingate(inputfile, fL, fH, LowpassON, BandpassON, HighpassON, ...
    htLow, LowerNTLow, UpperNTLow, rtLow, atLow, aLow, ...
    htBand, LowerNTBand, UpperNTBand, rtBand, atBand, aBand, ... 
    htHigh, LowerNTHigh, UpperNTHigh, rtHigh, atHigh, aHigh) ;

% The parameters that are in use in this function are : 
% inputfile     - the input file that will be used in '.wav' format.
% fL            - low crossover frequency for the filter
% fH            - high crossover frequency for the filter
%
% LowpassON     - Activate the low-pass noise gate
% BandpassON    - Activate the band-pass noise gate
% HighpassON    - Activate the high-pass noise gate
%
% htLow         - hold time for the Lowpass noise gate            
% LowerNTLow	- lower noise threshold for the Lowpass noise gate
% UpperNTLow	- upper noise threshold for the Lowpass noise gate
% rtLow         - release time for the Lowpass noise gate          
% atLow     	- attack time for the Lowpass noise gate
% poleLow		- pole placement of the envelope detecting filter <1
%
% htBand        - hold time for the Bandpass noise gate            
% LowerNTBand	- lower noise threshold for the Bandpass noise gate
% UpperNTBand	- upper noise threshold for the Bandpass noise gate
% rtBand        - release time for the Bandpass noise gate          
% atBand     	- attack time for the Bandpass noise gate
% poleBand		- pole placement of the envelope detecting filter for the Bandpass noise gate
%
% htHigh        - hold time for the Lowpass noise gate            
% LowerNTHigh	- lower noise threshold for the Lowpass noise gate
% UpperNTHigh	- upper noise threshold for the Lowpass noise gate
% rtHigh        - release time for the Lowpass noise gate          
% atHigh     	- attack time for the Lowpass noise gate
% poleHigh		- pole placement of the envelope detecting filter <1
%
%
%
% Load the input file into memory
[ori, fs] = audioread(inputfile) ; 

% Normalise the input file
ori = ori / max(ori) ;

% MULTIBAND FILTER APPLICATION
% Specify the crossover frequency for the bandpass filter
Lxover = fL ./ (fs./2) ;
Hxover = fH ./ (fs./2) ;

[numsamples,numchannels] = size(ori);

%% MONO AUDIO
if numchannels == 1 ;    

% Apply multiband splitting using FIR Butterworth filters
% Low pass
[bLowpar,aLowpar] = butter(3, Lxover, 'low');       % calculates filter parameters for 6th order butterworth lowpass
oriLow = filter(bLowpar, aLowpar, ori);             % filters the signal and saves as oriLow

% Band pass
[bBandpar,aBandpar] = butter(3, [Lxover Hxover]);   % calculates filter parameters for 6th order butterworth bandpass
oriBand = filter(bBandpar, aBandpar, ori);          % filters the signal and saves as oriMid

% High pass
[bHighpar,aHighpar] = butter(3, Hxover, 'high');    % calculates filter parameters for 6th order butterworth highpass
oriHigh = filter(bHighpar, aHighpar, ori);          % filters the signal and saves as oriHigh

oriOut=oriLow+oriBand+oriHigh;                      % combine the signal, saves it as oriCombi to compare with the processed signal

% Apply noise gate into each bands
%Lowpass
if LowpassON == 1 ;
    ngateLow=mynoisegt(oriLow,htLow,LowerNTLow,UpperNTLow,rtLow,atLow,aLow,fs) ;
    
else ngateLow = oriLow ;
end

%Bandpass
if BandpassON == 1 ;
    ngateBand=mynoisegt(oriBand,htBand,LowerNTBand,UpperNTBand,rtBand,atBand,aBand,fs) ;

else ngateBand = oriBand ;
end

%Highpass
if HighpassON == 1 ;
    ngateHigh=mynoisegt(oriHigh,htHigh,LowerNTHigh,UpperNTHigh,rtHigh,atHigh,aHigh,fs) ;

else ngateHigh = oriHigh ;
end

ngateCombi = ngateLow + ngateBand + ngateHigh ;     % combine the three bands into one output

%Normalise the signal
ngateOut = ngateCombi./max(abs(ngateCombi));        % normalise the output to avoid any function generated clipping

%Generate the output wave file
audiowrite('NoiseGateOutput.wav', ngateOut, fs) ; 

%% STEREO AUDIO
elseif numchannels == 2 ;
    oriL = ori(:,1);
    oriR = ori(:,2);
    oristereo = [oriL, oriR] ;
    
for i = 1:2
% Apply multiband splitting using FIR Butterworth filters
% Low pass
[bLowpar,aLowpar] = butter(3, Lxover, 'low');       % calculates filter parameters for 6th order butterworth lowpass
oriLow(:,i) = filter(bLowpar, aLowpar, oristereo(:,i));             % filters the signal and saves as oriLow

% Band pass
[bBandpar,aBandpar] = butter(3, [Lxover Hxover]);   % calculates filter parameters for 6th order butterworth bandpass
oriBand(:,i) = filter(bBandpar, aBandpar, oristereo(:,i));          % filters the signal and saves as oriMid

% High pass
[bHighpar,aHighpar] = butter(3, Hxover, 'high');    % calculates filter parameters for 6th order butterworth highpass
oriHigh(:,i) = filter(bHighpar, aHighpar, oristereo(:,i));          % filters the signal and saves as oriHigh

oriOut(:,i)=oriLow(:,i)+oriBand(:,i)+oriHigh(:,i);                      % combine the signal, saves it as oriCombi to compare with the processed signal

end

% Apply noise gate into each bands
%Lowpass
if LowpassON == 1 ;
    ngateLow=mynoisegt(oriLow,htLow,LowerNTLow,UpperNTLow,rtLow,atLow,aLow,fs) ;
    
else ngateLow = oriLow ;
end

%Bandpass
if BandpassON == 1 ;
    ngateBand=mynoisegt(oriBand,htBand,LowerNTBand,UpperNTBand,rtBand,atBand,aBand,fs) ;

else ngateBand = oriBand ;
end

%Highpass
if HighpassON == 1 ;
    ngateHigh=mynoisegt(oriHigh,htHigh,LowerNTHigh,UpperNTHigh,rtHigh,atHigh,aHigh,fs) ;

else ngateHigh = oriHigh ;
end

end

ngateCombi = ngateLow + ngateBand + ngateHigh ;     % combine the three bands into one output

%Normalise the signal
ngateOut = ngateCombi./max(abs(ngateCombi));        % normalise the output to avoid any function generated clipping

%Generate the output wave file
audiowrite('NoiseGateOutput.wav', ngateOut, fs) ; 

%% Obtain figures for the comparison of input and output signals
figure (1) 
subplot (2,1,1), plot (oriOut), title('Input'), xlabel ('Samples'), ylabel ('Ampltude') ;
subplot (2,1,2), plot (ngateOut), title('Output'), xlabel ('Samples'), ylabel ('Ampltude') ;