function [ltpOutputBlock, ltpInputPastOut] = ... 
    ltpfilt( ltpInputBlock, subblockLength, ltpDelays, ltpGains, ltpInputPastIn )
% function [ltpOutputBlock, ltpInputPastOut] =
%     ltpfilt( ltpInputBlock, subblockLength, ltpDelays, ltpGains, ltpInputPastIn)
%
% Open-Loop LTP Filter
%
% ltpInputBlock:     input vector
% subblockLength:    ltpInputBlock is devided in subblocks of size subblockLength
% ltpDelays:	     vector containing ltp delays (size: number of subblocks in ltpInputBlock)
% ltpGains:          vector containing ltp gains (size: number of subblocks in ltpInputBlock)		
% ltpInputPastIn:    ltp filter states before ltp filtering		
% 
% ltpOutputBlock:    ltp-filtered version of ltpInputBlock
% ltpInputPastOut:   ltp filter states after ltp filtering
%  
% Author:  Markus Hauenstein
% Date:    10.01.2002 
% Contact: www.markus-hauenstein.de

blockLength = length(ltpInputBlock);
maxDelay = length(ltpInputPastIn);
numberOfSubblocks = blockLength / subblockLength;

if numberOfSubblocks ~= floor(blockLength / subblockLength), 
  error( 'ltpfilt: blockLength and subblockLength do not fit' )
end

if numberOfSubblocks ~= length(ltpDelays), 
  error( 'ltpfilt: length of delay vector and number of subblocks do not fit' )
end

if numberOfSubblocks ~= length(ltpGains), 
  error( 'ltpfilt: length of gain vector and number of subblocks do not fit' )
end

ltpInputExt = [ltpInputPastIn; ltpInputBlock];

subblockIndex = 1 : subblockLength;
subblockIndexExt = (maxDelay+1) : (maxDelay+subblockLength);
searchIndex = 1 : (maxDelay+subblockLength);

for j=1:numberOfSubblocks,

  % ltp filter 
  delayIndex = subblockIndexExt - ltpDelays(j);
  ltpOutputBlock(subblockIndex) = ...
      ltpInputBlock(subblockIndex) - ltpGains(j) * ltpInputExt(delayIndex); 

  % set indices for next subblock
  subblockIndex = subblockIndex + subblockLength;   
  subblockIndexExt = subblockIndexExt + subblockLength;
  searchIndex = searchIndex + subblockLength; 
end

ltpInputPastOut = ltpInputExt( blockLength+1 : maxDelay+blockLength ); 
ltpOutputBlock = ltpOutputBlock(:);
ltpGains = ltpGains(:);
ltpDelays = ltpDelays(:);
