home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 10 / 10.iso / l / l455 / 8.ddi / SIGNAL.DI$ / INTERP.M < prev    next >
Encoding:
Text File  |  1993-03-11  |  3.6 KB  |  111 lines

  1. function [odata,b] = interp(idata,r,l,alpha)
  2. %INTERP    Resample data at a higher rate using lowpass interpolation.
  3. %    Y = INTERP(X,R) resamples the sequence in vector X at R times
  4. %    the original sample rate.  The resulting resampled vector Y is
  5. %    R times longer, LENGTH(Y) = R*LENGTH(X).
  6. %
  7. %    A symmetric filter, B, allows the original data to pass through
  8. %    unchanged and interpolates between so that the mean square error
  9. %    between them and their ideal values is minimized.
  10. %    Y = INTERP(X,R,L,ALPHA) allows specification of arguments
  11. %    L and ALPHA which otherwise default to 4 and .5 respectively.
  12. %    2*L is the number of original sample values used to perform the
  13. %    interpolation.  Ideally L should be less than or equal to 10.
  14. %    The length of B is 2*L*R+1. The signal is assumed to be band
  15. %    limited with cutoff frequency 0 < ALPHA <= 1.0. 
  16. %    [Y,B] = INTERP(X,R,L,ALPHA) returns the coefficients of the
  17. %    interpolation filter B.  See also DECIMATE.
  18.  
  19. %    L. Shure 5-14-87
  20. %    Revised 6-1-88 , 12-15-88 LS.
  21. %    Copyright (c) 1987-88 by the MathWorks, Inc.
  22. %    All rights reserved.
  23.  
  24. %    References:
  25. %      "Programs for Digital Signal Processing", IEEE Press
  26. %      John Wiley & Sons, 1979, Chap. 8.1.
  27.  
  28. if nargin < 3
  29.    l = 4;
  30. end
  31. if nargin < 4
  32.    alpha = .5;
  33. end
  34. if l < 1 | r < 1 | alpha <= 0 | alpha > 1
  35.    error('Input parameters are out of range.')
  36. end
  37. if abs(r-fix(r)) > eps
  38.    error('Resampling rate R must be an integer.')
  39. end
  40. if 2*l+1 > length(idata)
  41.     s = int2str(2*l+1);
  42.     error(['Length of data sequence must be at least ',s, 10,...
  43. 'You either need more data or a shorter filter (L).']);
  44. end
  45.  
  46. % ALL occurrences of sin()/() are using the sinc function for the
  47. % autocorrelation for the input data.  They should all be changed consistently
  48. % if they are changed at all.
  49.  
  50. % calculate AP and AM matrices for inversion
  51. s1 = toeplitz(0:l-1) + eps;
  52. s2 = hankel(2*l-1:-1:l);
  53. s2p = hankel([1:l-1 0]);
  54. s2 = s2 + eps + s2p(l:-1:1,l:-1:1);
  55. s1 = sin(alpha*pi*s1)./(alpha*pi*s1);
  56. s2 = sin(alpha*pi*s2)./(alpha*pi*s2);
  57. ap = s1 + s2;
  58. am = s1 - s2;
  59. ap = inv(ap);
  60. am = inv(am);
  61.  
  62. % now calculate D based on INV(AM) and INV(AP)
  63. d = zeros(2*l,l);
  64. d(1:2:2*l-1,:) = ap + am;
  65. d(2:2:2*l,:) = ap - am;
  66.  
  67. % set up arrays to calculate interpolating filter B
  68. x = (0:r-1)/r;
  69. y = zeros(2*l,1);
  70. y(1:2:2*l-1) = (l:-1:1);
  71. y(2:2:2*l) = (l-1:-1:0);
  72. X = ones(2*l,1);
  73. X(1:2:2*l-1) = -ones(l,1);
  74. XX = eps + y*ones(1,r) + X*x;
  75. y = X + y + eps;
  76. h = .5*d'*(sin(pi*alpha*XX)./(alpha*pi*XX));
  77. b = zeros(2*l*r+1,1);
  78. b(1:l*r) = h';
  79. b(l*r+1) = .5*d(:,l)'*(sin(pi*alpha*y)./(pi*alpha*y));
  80. b(l*r+2:2*l*r+1) = b(l*r:-1:1);
  81.  
  82. % use the filter B to perform the interpolation
  83. [m,n] = size(idata);
  84. nn = max([m n]);
  85. if nn == m
  86.    odata = zeros(r*nn,1);
  87. else
  88.    odata = zeros(1,r*nn);
  89. end
  90. odata(1:r:nn*r) = idata;
  91. % Filter a fabricated section of data first (match initial values and first derivatives by
  92. % rotating the first data points by 180 degrees) to get guess of good initial conditions
  93. % Filter length is 2*l*r+1 so need that many points; can't duplicate first point or
  94. % guarantee a zero slope at beginning of sequence
  95. od = zeros(2*l*r,1);
  96. od(1:r:(2*l*r)) = 2*idata(1)-idata((2*l+1):-1:2);
  97. [od,zi] = filter(b,1,od);
  98. [odata,zf] = filter(b,1,odata,zi);
  99. odata(1:(nn-l)*r) = odata(l*r+1:nn*r);
  100.  
  101. % make sure right hand points of data have been correctly interpolated and get rid of
  102. % transients by again matching end values and derivatives of the original data
  103. if nn == m
  104.     od = zeros(2*l*r,1);
  105. else
  106.     od = zeros(1,2*l*r);
  107. end
  108. od(1:r:(2*l)*r) = [2*idata(nn)-(idata((nn-1):-1:(nn-2*l)))];
  109. od = filter(b,1,od,zf);
  110. odata(nn*r-l*r+1:nn*r) = od(1:l*r);
  111.