% ////////////////////////////////////////////////////////////////////
% FILE,     HBF2LModel.m
% PROJECT,  HBF2L
% AUTHOR,   weitao.du
% DATE,     2007.Jun.11th
% VERSION,  0.1
% ////////////////////////////////////////////////////////////////////
% DECRIPTION
% 2 Level Half Band Fir Filter Design and Simulation, filer model 
% ////////////////////////////////////////////////////////////////////

function simData = HBF2LModel(cfg, simData);
  fprintf(1, 'HBF2LModel(), run\n');
  truncOut      = 0;
  dataFlp       = ModelFlp(cfg, simData, truncOut);
  dataFxp       = ModelFxp(cfg, simData, truncOut);

  simData.dataFlp       = dataFlp       ;
  simData.dataFxp       = dataFxp       ;

end  % function HBF2LModel();

% ////////////////////////////////////////////////////////////////////
% function ModelFxp(), HBF2L fixed point model, 
function dataFxp = ModelFxp(cfg, simData, truncOut);
% if truncOut ~= 0, then delete the for-and-aft FIR output data
% get config param
  inputFs   = cfg.inputFs      ;
  inputBw   = cfg.inputBw      ;
  WLCfg     = cfg.WLCfg        ;

  
  inputWL      =   WLCfg.inputWL     ;
  coeffWL      =   WLCfg.coeffWL     ;
  adderWL      =   WLCfg.adderWL     ;
  adderFL      =   WLCfg.adderFL     ;
  castBFadd    =   WLCfg.castBFadd   ;
  multWL       =   WLCfg.multWL      ;
  multFL       =   WLCfg.multFL      ;
  sumWL        =   WLCfg.sumWL       ;
  sumFL        =   WLCfg.sumFL       ;
  castBFSum    =   WLCfg.castBFSum   ;
  outputWL     =   WLCfg.outputWL    ;
  outputFL     =   WLCfg.outputFL    ;


  K1        = cfg.K1           ;
  K2        = cfg.K2           ;
  passBand1 = cfg.passBand1    ;
  passBand2 = cfg.passBand2    ;


% get initial data
  filterInit   =  simData.filterInit   ;
  coeff1CdsFlt =  filterInit.coeff1CdsFlt;
  coeff2CdsFlt =  filterInit.coeff2CdsFlt;
  inputData    =  simData.inputData;

% fixed point config setting 
  fxpCfg = FxpSetting(WLCfg);

  % the output data will use the same config as input data 
  coeffNtype  =  fxpCfg.coeffNtype ;
  inputNtype  =  fxpCfg.inputNtype ;
  outputNtype =  fxpCfg.outputNtype;
  adderMath   =  fxpCfg.adderMath  ;
  multMath    =  fxpCfg.multMath   ;
  sumMath     =  fxpCfg.sumMath    ;

% Fxp input and coeff
  inputDataFxp = fi(inputData, inputNtype, 'RoundMode', 'fix');
  coeff1CdsFxp = fi(coeff1CdsFlt, coeffNtype, 'RoundMode', 'fix');


% HBF level 1 filter
  lenInput        =  length(inputData);
  lenOutLv1Part0  =  lenInput ;
  lenOutLv1Part1  =  lenOutLv1Part0;
  % part0 gen by mult-add
    outLv1Part0     =  zeros(lenOutLv1Part0, 1);  
  % part1 gen by copy
    outLv1Part1     =  zeros(lenOutLv1Part1, 1);  
  % total output
    outLv1          =  zeros(lenOutLv1Part0*2,1);
if(0)
  % data sequence in the hbf, include the begining and end
  % zero stuff
    lv1DataSeq      =  zeros(2*K1-1+lenInput, 1);
    lv1DataSeq(2*K1:lenInput+2*K1-1) = inputData;
else
    lv1DataSeq      =  fi(zeros(2*K1-1+lenInput, 1) , inputNtype, 'RoundMode', 'fix');
    lv1DataSeq(2*K1:lenInput+2*K1-1) = inputDataFxp;

end
  
  cfftwinplot(double(lv1DataSeq), inputFs*2, 'ModelFxp(), lv1DataSeq', 'green');

% data sequence read for MAC index
  lv1DataIdx      =  [2*K1:lenInput+K1*2-1].';
% output index
  lv1OutIdx       =  [1:lenOutLv1Part0].';
% r1 is hbf level 1 sum index
  r1Idx           =  [0:K1-1];
  data0Idx0Trace   = zeros(lenOutLv1Part0,K1);
  data0Idx1Trace   = zeros(lenOutLv1Part0,K1);
  data1IdxTrace    = zeros(lenOutLv1Part1,1);

  for(idx1=1:lenOutLv1Part0)
  % level1 output part0, gen by add-mult-sum
    % the algorithm is explained in the design report
    data0Idx0  = lv1DataIdx(idx1)-r1Idx;
    data0Idx1  = lv1DataIdx(idx1)-2*K1+1 + r1Idx;
    dataPart0 = lv1DataSeq(data0Idx0);
    dataPart1 = lv1DataSeq(data0Idx1);
  if(0)
    dataAdd   = double(dataPart1)+double(dataPart0);
  else
    dataAdd   = adderMath.add(dataPart0, dataPart1);
  end
  if(0)
    dataMult  = double(dataAdd) .* double(coeff1CdsFlt);
  else
    dataMult  = multMath.mpy(dataAdd, coeff1CdsFxp);
  end
  if(0)
    dataSum   = sum(double(dataMult));
  else
    dataSum   = FxpSum(dataMult, sumMath, outputNtype);
  end

    outLv1Part0(lv1OutIdx(idx1)) = double(dataSum); 
  % level1 output part1, gen by copy
    data1Idx  = lv1DataIdx(idx1)+1-K1;
  if(0)
    outLv1Part1(lv1OutIdx(idx1)) = double(lv1DataSeq(data1Idx))*0.5;
  else
    % outLv1Part1(lv1OutIdx(idx1)) = double(bitshift(lv1DataSeq(data1Idx), -1));
    outLv1Part1(lv1OutIdx(idx1)) = double(lv1DataSeq(data1Idx));
  end

    data0Idx0Trace(idx1,:)  = data0Idx0; 
    data0Idx1Trace(idx1,:)  = data0Idx1; 
    data1IdxTrace(idx1)     = data1Idx;
  end % for(idx1=1:lenOutLv1Part0)
  
  % set the output
  outLv1(1:2:2*lenOutLv1Part0-1) = double(outLv1Part0);
  outLv1(2:2:2*lenOutLv1Part0)   = double(outLv1Part1);
  if(truncOut ~= 0)
  % delete the pipe stuff data 
    outLv1(1:2*K1-1) = [];
  end
  cfftwinplot(outLv1, inputFs*2, 'ModelFxp(), outLv1', 'green');

  % /////////////////////////////////////////////////////////////////////
  % HBF level 2 filter
  if(floor(K2/2) ~= K2/2) 
    fprintf(1,'WARNING, K2 is NOT a even integer, this will cause ERROR\n');
  end
  lenOutLv2Part0  =  lenInput;
  lenOutLv2Part1  =  lenOutLv2Part0;
  lenOutLv2Part2  =  lenOutLv2Part0;
  lenOutLv2Part3  =  lenOutLv2Part0;

  outLv2Part0     =  zeros(lenOutLv2Part0,1);
  outLv2Part1     =  zeros(lenOutLv2Part0,1);
  outLv2Part2     =  zeros(lenOutLv2Part0,1);
  outLv2Part3     =  zeros(lenOutLv2Part0,1);
  outLv2    = zeros(4*lenOutLv2Part0, 1);
  
  coeff2CdsFxp = fi(coeff2CdsFlt, coeffNtype, 'RoundMode', 'fix');

  % x1 is the input data sequence for caculating the y2n
  if(0)
    x1              =  zeros(K1+K2-1 + lenInput, 1);
    x1(K1+K2 : lenInput + K1+K2-1) = inputData;
  else
    x1              =  fi(zeros(K1+K2-1 + lenInput, 1), inputNtype, 'RoundMode', 'fix');
    x1(K1+K2 : lenInput + K1+K2-1) = fi(inputData, inputNtype, 'RoundMode', 'fix');
  end
  % x1 read index
  x1Idx           =  [K1+K2 : lenInput + K1+K2-1];

  % zero padding y1_n0's start 
  if(0)
    y1_n0DataSeq    =  zeros(K2-1+lenOutLv1Part0, 1);
    y1_n0DataSeq(K2:lenOutLv1Part0+K2-1) = outLv1Part0;
  else
    y1_n0DataSeq    =  fi(zeros(K2-1+lenOutLv1Part0, 1), inputNtype, 'RoundMode', 'fix');
    y1_n0DataSeq(K2:lenOutLv1Part0+K2-1) = fi(outLv1Part0, inputNtype, 'RoundMode', 'fix');
  end

  % y1_n0 read index
  y1_n0Idx        =  [K2 : lenOutLv1Part0 + K2-1]; 
  % level2 HBF output index, for part0~part3
  lv2OutIdx       =  [1:lenOutLv2Part0];
  % r2_Idx is the r2' in the design report
  r2_Idx          =  [0:K2/2 - 1];     
 
  y1EvenIdx_y2n0Trace = zeros(lenOutLv2Part0, K2/2); 
  x1EvenIdx_y2n0Trace = zeros(lenOutLv2Part0, K2/2); 
  y1OddIdx_y2n0Trace  = zeros(lenOutLv2Part0, K2/2); 
  x1OddIdx_y2n0Trace  = zeros(lenOutLv2Part0, K2/2); 
  y1EvenIdx_y2n2Trace = zeros(lenOutLv2Part0, K2/2); 
  x1EvenIdx_y2n2Trace = zeros(lenOutLv2Part0, K2/2); 
  y1OddIdx_y2n2Trace  = zeros(lenOutLv2Part0, K2/2); 
  x1OddIdx_y2n2Trace  = zeros(lenOutLv2Part0, K2/2); 

  for(idx1 = 1:lenOutLv2Part0) 
  % caculate part0
    y1EvenIdx_y2n0   = y1_n0Idx(idx1) - r2_Idx             ;
    x1EvenIdx_y2n0   = x1Idx(idx1)+ r2_Idx - K2  + 1 -K1   ;    
    y1OddIdx_y2n0    = y1_n0Idx(idx1) + r2_Idx - K2 + 1    ;    
    x1OddIdx_y2n0    = x1Idx(idx1) - r2_Idx -K1            ;

    % caculate the Even part of y2n0
    if(0)
      y2n0EvenAdd      = double(y1_n0DataSeq(y1EvenIdx_y2n0)) + 0.5*double(x1(x1EvenIdx_y2n0));
    else
      % y2n0EvenAdd      = adderMath.add(y1_n0DataSeq(y1EvenIdx_y2n0) , bitshift(x1(x1EvenIdx_y2n0), -1));
      y2n0EvenAdd      = adderMath.add(y1_n0DataSeq(y1EvenIdx_y2n0) , x1(x1EvenIdx_y2n0));
    end

    if(0)
      y2n0EvenMult     = double(y2n0EvenAdd) .* double(coeff2CdsFlt((2*r2_Idx + 1))); % +1 is for the MATLAB indexing(from 1)
    else
      y2n0EvenMult     = multMath.mpy(y2n0EvenAdd , coeff2CdsFxp(2*r2_Idx + 1)); % +1 is for the MATLAB indexing(from 1)
    end

    % caculate the Odd part of y2n0
    if(0)
      y2n0OddAdd       = double(y1_n0DataSeq(y1OddIdx_y2n0))  + 0.5*double(x1(x1OddIdx_y2n0));
    else
      y2n0OddAdd       = adderMath.add(y1_n0DataSeq(y1OddIdx_y2n0), bitshift(x1(x1OddIdx_y2n0), -1));
      y2n0OddAdd       = adderMath.add(y1_n0DataSeq(y1OddIdx_y2n0), x1(x1OddIdx_y2n0));
    end
    if(0)
      y2n0OddMult      = double(y2n0OddAdd) .* double(coeff2CdsFlt((2*r2_Idx + 1) + 1)); % +1 is for the MATLAB indexing(from 1) 
    else
      y2n0OddMult      = multMath.mpy(y2n0OddAdd, coeff2CdsFxp((2*r2_Idx + 1) + 1)); % +1 is for the MATLAB indexing(from 1) 
    end

    % sum the even and odd part mult product

    if(0)
      y2n0 = sum([y2n0EvenMult;y2n0OddMult]);
    else
      y2n0 = FxpSum([y2n0EvenMult;y2n0OddMult], sumMath, outputNtype);
    end
    
  % caculate part1
    y2n1Idx = x1Idx(idx1) - K2/2 - K1 + 1;
    if(0) 
      y2n1    = double(x1(y2n1Idx))*0.25 ;
    else
      y2n1    = x1(y2n1Idx) ;
    end
  
  % caculate part2
    y1EvenIdx_y2n2   = y1_n0Idx(idx1) + r2_Idx - K2 + 1    ;
    x1EvenIdx_y2n2   = x1Idx(idx1) - r2_Idx + 1 - K1       ;
    y1OddIdx_y2n2    = y1_n0Idx(idx1) - r2_Idx             ;
    x1OddIdx_y2n2    = x1Idx(idx1) + r2_Idx - K2 + 2 -K1   ;    
    % caculate the Even part of y2n2
    if(0)
      y2n2EvenAdd      = double(y1_n0DataSeq(y1EvenIdx_y2n2)) + 0.5*double(x1(x1EvenIdx_y2n2));
    else
      y2n2EvenAdd      = adderMath.add(y1_n0DataSeq(y1EvenIdx_y2n2), x1(x1EvenIdx_y2n2));

    end

    if(0)
      y2n2EvenMult     = double(y2n2EvenAdd) .* double(coeff2CdsFlt((2*r2_Idx + 1))); % +1 is for the MATLAB indexing(from 1)
    else
      y2n2EvenMult     = multMath.mpy(y2n2EvenAdd, coeff2CdsFxp((2*r2_Idx + 1))); % +1 is for the MATLAB indexing(from 1)
    end

    % caculate the Odd part of y2n2
    if(0)
      y2n2OddAdd       = double(y1_n0DataSeq(y1OddIdx_y2n2)) + 0.5*double(x1(x1OddIdx_y2n2));
    else
      y2n2OddAdd       = adderMath.add(y1_n0DataSeq(y1OddIdx_y2n2), bitshift(x1(x1OddIdx_y2n2), -1));
      y2n2OddAdd       = adderMath.add(y1_n0DataSeq(y1OddIdx_y2n2), x1(x1OddIdx_y2n2));
    end
    
    if(0)
      y2n2OddMult      = double(y2n2OddAdd) .* double(coeff2CdsFlt((2*r2_Idx + 1) + 1)); % +1 is for the MATLAB indexing(from 1) 
    else
      y2n2OddMult      = multMath.mpy(y2n2OddAdd, coeff2CdsFxp((2*r2_Idx + 1) + 1)); % +1 is for the MATLAB indexing(from 1) 
    end
    
    if(0)
      y2n2 = double(y2n2OddSum) + double(y2n2EvenSum);
      y2n2 = sum([y2n2OddMult; y2n2EvenMult]);
    else
      y2n2 = FxpSum([y2n2OddMult; y2n2EvenMult], sumMath, outputNtype);
    end
  
  % caculate part3
    y3n3Idx = y1_n0Idx(idx1) - K2/2 + 1;
    if(0)
      y2n3    = double(y1_n0DataSeq(y3n3Idx));
    else
      y2n3              = y1_n0DataSeq(y3n3Idx) ;
    end

    outLv2Part0(idx1) = y2n0 ;
    outLv2Part1(idx1) = y2n1 ;
    outLv2Part2(idx1) = y2n2 ;
    outLv2Part3(idx1) = y2n3 ;

    y1EvenIdx_y2n0Trace(idx1,:) = y1EvenIdx_y2n0 ; 
    x1EvenIdx_y2n0Trace(idx1,:) = x1EvenIdx_y2n0 ; 
    y1OddIdx_y2n0Trace(idx1,:)  = y1OddIdx_y2n0  ;
    x1OddIdx_y2n0Trace(idx1,:)  = x1OddIdx_y2n0  ;

    y1EvenIdx_y2n2Trace(idx1,:) = y1EvenIdx_y2n2 ; 
    x1EvenIdx_y2n2Trace(idx1,:) = x1EvenIdx_y2n2 ; 
    y1OddIdx_y2n2Trace(idx1,:)  = y1OddIdx_y2n2  ;
    x1OddIdx_y2n2Trace(idx1,:)  = x1OddIdx_y2n2  ;


  end  % for(idx1 = 1:lenOutLv2Part0) 

  outLv2(1:4:4*lenOutLv2Part0-3) = outLv2Part0;
  outLv2(2:4:4*lenOutLv2Part0-2) = outLv2Part1;
  outLv2(3:4:4*lenOutLv2Part0-1) = outLv2Part2;
  outLv2(4:4:4*lenOutLv2Part0-0) = outLv2Part3;

  outLv2Fxp = fi(outLv2, inputNtype, 'RoundMode', 'fix');

  cfftwinplot(outLv2, inputFs*4, 'HBF FIXED POINT LV2 output', 'blue');

  % copy to output
  dbg.HBFLv1.inputDataFxp   = inputDataFxp;
  dbg.HBFLv1.outLv1Part0    = outLv1Part0;
  dbg.HBFLv1.outLv1Part1    = outLv1Part1;
  dbg.HBFLv1.lv1DataSeq     = lv1DataSeq;
  dbg.HBFLv1.lv1DataIdx     = lv1DataIdx;
  dbg.HBFLv1.lv1OutIdx      = lv1OutIdx;
  dbg.HBFLv1.data0Idx0Trace = data0Idx0Trace;
  dbg.HBFLv1.data0Idx1Trace = data0Idx1Trace;
  dbg.HBFLv1.data1IdxTrace  = data1IdxTrace;
  dbg.HBFLv1.coeff1CdsFxp   = coeff1CdsFxp;

  
  dbg.HBFLv2.y1_n0DataSeq    = y1_n0DataSeq;
  dbg.HBFLv2.outLv2Part0     = outLv2Part0;
  dbg.HBFLv2.outLv2Part1     = outLv2Part1;
  dbg.HBFLv2.outLv2Part2     = outLv2Part2;
  dbg.HBFLv2.outLv2Part3     = outLv2Part3;
  dbg.HBFLv2.outLv2Fxp       = outLv2Fxp;
  dbg.HBFLv2.coeff2CdsFxp   = coeff2CdsFxp;

  dbg.HBFLv2.y1EvenIdx_y2n0Trace  = y1EvenIdx_y2n0Trace;
  dbg.HBFLv2.x1EvenIdx_y2n0Trace  = x1EvenIdx_y2n0Trace;
  dbg.HBFLv2.y1OddIdx_y2n0Trace   = y1OddIdx_y2n0Trace;
  dbg.HBFLv2.x1OddIdx_y2n0Trace   = x1OddIdx_y2n0Trace;

  dbg.HBFLv2.y1EvenIdx_y2n2Trace  = y1EvenIdx_y2n2Trace;  
  dbg.HBFLv2.x1EvenIdx_y2n2Trace  = x1EvenIdx_y2n2Trace;  
  dbg.HBFLv2.y1OddIdx_y2n2Trace   = y1OddIdx_y2n2Trace;  
  dbg.HBFLv2.x1OddIdx_y2n2Trace   = x1OddIdx_y2n2Trace;  

  dataFxp.outLv1 = outLv1;
  dataFxp.outLv2 = outLv2;
  dataFxp.dbg    = dbg;    

end % fucntion ModelFxp()
% ////////////////////////////////////////////////////////////////////
% function FxpSetting(), fixed point property setting
function fxpCfg = FxpSetting(WLCfg);
  inputWL      =   WLCfg.inputWL     ;
  coeffWL      =   WLCfg.coeffWL     ;
  adderWL      =   WLCfg.adderWL     ;
  adderFL      =   WLCfg.adderFL     ;
  castBFadd    =   WLCfg.castBFadd   ;
  multWL       =   WLCfg.multWL      ;
  multFL       =   WLCfg.multFL      ;
  sumWL        =   WLCfg.sumWL       ;
  sumFL        =   WLCfg.sumFL       ;
  castBFSum    =   WLCfg.castBFSum   ;
  outputWL     =   WLCfg.outputWL    ;
  outputFL     =   WLCfg.outputFL    ;

  coeffNtype  = numerictype(1, coeffWL  , coeffWL  - 1 );
  inputNtype  = numerictype(1, inputWL  , inputWL  - 1 );
  outputNtype = numerictype(1, outputWL, outputFL);
  
  adderMath  = fimath(...
    'CastBeforeSum'     ,    castBFadd          , ...
    'OverflowMode'      ,    'wrap'             , ...
    'SumMode'           ,    'SpecifyPrecision' , ...
    'SumWordLength'     ,    adderWL            , ...
    'SumFractionLength' ,    adderFL            , ...   
    'RoundMode'         ,    'fix'            );

  multMath = fimath(...
    'ProductMode'               ,   'SpecifyPrecision'  , ...
    'ProductWordLength'         ,   multWL              , ...
    'ProductFractionLength'     ,   multFL              , ...   
    'RoundMode'                 ,   'fix'             );

  sumMath = fimath(...
    'CastBeforeSum'     ,       castBFSum               , ...
    'OverflowMode'      ,       'wrap'                  , ...
    'SumMode'           ,       'SpecifyPrecision'      , ...
    'SumWordLength'     ,       sumWL                   , ...
    'SumFractionLength' ,       sumFL                   , ...   
    'RoundMode'         ,       'fix'                 );


  fxpCfg.coeffNtype  = coeffNtype ;
  fxpCfg.inputNtype  = inputNtype ;
  fxpCfg.adderMath   = adderMath  ;
  fxpCfg.multMath    = multMath   ;
  fxpCfg.sumMath     = sumMath    ;
  fxpCfg.outputNtype = outputNtype;

  
end % function FxpSetting() 
% ////////////////////////////////////////////////////////////////////
% function FxpSum(), fixed point sum 
% the input data and fixed point Math type should be correctly set
% this function will not check them

function sum = FxpSum(input, sumMath, outputNtype);
  len = length(input);
  sum = fi(0, input.numerictype, 'RoundMode', 'fix');
  for(idx = 1:len)
    sum = sumMath.add(sum, input(idx));
  end  % for idx
  sumFlt = double(sum);
  sum = fi(sumFlt, outputNtype, 'RoundMode', 'fix');
end % function FxpSum(), fixed point sum 
% ////////////////////////////////////////////////////////////////////
% function ModelFlp(), HBF2L floating point model
function dataFlp = ModelFlp(cfg, simData, truncOut);
% if truncOut ~= 0, then delete the for-and-aft FIR output data

% get config param
  inputFs   = cfg.inputFs      ;
  inputBw   = cfg.inputBw      ;

  WLCfg     = cfg.WLCfg;

  inputWL   = WLCfg.inputWL    ;
  coeffWL   = WLCfg.coeffWL    ;
  outputWL  = WLCfg.outputWL   ;

  K1        = cfg.K1         ;
  K2        = cfg.K2         ;
  passBand1 = cfg.passBand1  ;
  passBand2 = cfg.passBand2  ;

% get initial data
  filterInit   =  simData.filterInit   ;
  coeff1AllFxp =  filterInit.coeff1AllFxp ;
  coeff2AllFxp =  filterInit.coeff2AllFxp ;
  inputData    =  simData.inputData;
  
  
% Fxp input 
  fxpCfg = FxpSetting(WLCfg);
  inputNtype  =  fxpCfg.inputNtype ;

  inputDataFxp = fi(inputData, inputNtype, 'RoundMode', 'fix');
  inputData = double(inputDataFxp);

% HBF Level 1 input data interpolation and Filter
  lenIn1 = length(inputData); 
  dataLv1Itp = zeros(lenIn1*2, 1);
  dataLv1Itp(1:2:lenIn1*2-1) = inputData; 
  hbfLv1Out = conv(coeff1AllFxp, dataLv1Itp);
  
  if(truncOut ~= 0)
  % delete the pipe stuff data 
    hbfLv1Out(1:2*K1-1) = [];
    tmp = length(hbfLv1Out);
    hbfLv1Out(tmp-2*K1+2:tmp) = [];
  end
  cfftwinplot(hbfLv1Out, inputFs*2, 'FLOAT HBF LV1 output', 'black');

% HBF Level 2 input data interpolation and Filter
  lenIn2 = length(hbfLv1Out); 
  dataLv2Itp = zeros(lenIn2*2, 1);
  dataLv2Itp(1:2:lenIn2*2-1) = hbfLv1Out; 
  hbfLv2Out = conv(coeff2AllFxp, dataLv2Itp);

  if(truncOut ~= 0)
    % delete the pipe stuff data 
    hbfLv2Out(1:2*K2-1) = [];
    tmp = length(hbfLv2Out);
    hbfLv2Out(tmp-2*K2+2:tmp) = [];
  end
  cfftwinplot(hbfLv2Out, inputFs*4, 'FLOAT HBF LV2 output', 'black');
   
  dataFlp.hbfLv1Out     = hbfLv1Out;
  dataFlp.hbfLv2Out     = hbfLv2Out;
  dataFlp.dataLv1Itp    = dataLv1Itp;
end % function ModelFlp();
