Advertisement
neo01124

Harmonic Model

Nov 14th, 2011
50
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.30 KB | None | 0 0
  1. function y = harmonicmodel(x, w, N, t, fs)
  2. % Authors: J. Bonada, X. Serra, X. Amatriain, A. Loscos
  3. % Analysis/synthesis of a sound using the sinusoidal model
  4. % x: input sound, w: analysis window (odd size), N: FFT size,
  5. % t: threshold in negative dB, y: output sound
  6. %
  7. %--------------------------------------------------------------------------
  8. % This source code is provided without any warranties as published in
  9. % DAFX book 2nd edition, copyright Wiley & Sons 2011, available at
  10. % http://www.dafx.de. It may be used for educational purposes and not
  11. % for commercial applications without further permission.
  12. %--------------------------------------------------------------------------
  13.  
  14. M = length(w); % analysis window size
  15. Ns= 1024; % FFT size for synthesis (even)
  16. H = 256; % analysis/synthesishop size
  17. N2= N/2+1; % size of positive spectrum
  18. soundlength = length(x); % length of input sound array
  19. hNs = Ns/2; % half synthesis window size
  20. hM = (M-1)/2; % half analysis window size
  21. pin = max(H+1,1+hM); % initialize sound pointer to middle of analysis window
  22. pend = soundlength-max(H,hM); % last sample to start a frame
  23. fftbuffer = zeros(N,1); % initialize buffer for FFT
  24. y = zeros(soundlength,1); % initialize output array
  25. w = w/sum(w); % normalize analysis window
  26. sw = zeros(Ns,1);
  27. ow = triang(2*H-1); % overlapping window
  28. ovidx = Ns/2+1-H+1:Ns/2+H; % overlap indexes
  29. sw(ovidx) = ow(1:2*H-1);
  30. bh = blackmanharris(Ns); % synthesis window
  31. bh = bh ./ sum(bh); % normalize synthesis window
  32. sw(ovidx) = sw(ovidx) ./ bh(ovidx);
  33. k = [0:1:N];
  34. freq = fs*k/N;
  35. minf0 = 100;
  36. maxf0 = 20000;
  37. ef0max = 100;
  38. while pin<pend
  39. %-----analysis-----%
  40. xw = x(pin-hM:pin+hM).*w(1:M); % window the input sound
  41. fftbuffer(:) = 0; % reset buffer
  42. fftbuffer(1:(M+1)/2) = xw((M+1)/2:M); % zero-phase window in fftbuffer
  43. fftbuffer(N-(M-1)/2+1:N) = xw(1:(M-1)/2);
  44. X = fft(fftbuffer); % compute the FFT
  45. mX = 20*log10(abs(X(1:N2))); % magnitude spectrum of positive frequencies
  46. pX = unwrap(angle(X(1:N/2+1))); % unwrapped phase spectrum
  47. ploc = 1 + find((mX(2:N2-1)>t) .* (mX(2:N2-1)>mX(3:N2)) ...
  48. .* (mX(2:N2-1)>mX(1:N2-2))); % find peaks
  49. [ploc,pmag,pphase] = peakinterp(mX,pX,ploc); % refine peak values
  50. % f0 = f0detection(mX, fs, ploc, pmag, ef0max, minf0, maxf0);
  51. f0 = f0detectionyin(x, fs, 1200, minf0, maxf0) ;
  52. nH=20;
  53. maxhd=.2;
  54. hf = (f0>0).*(f0.*(1:nH)); % initialize harmonic frequencies
  55. hi = 1; % initialize harmonic index
  56. npeaks = length(ploc); % number of peaks found
  57. while (f0>0 && hi<=nH && hf(hi)<fs/2) % find harmonic peaks
  58. [dev,pei] = min(abs((ploc(1:npeaks)-1)/N*fs-hf(hi))); % closest peak
  59. if ((hi==1 || ~any(hloc(1:hi-1)==ploc(pei))) && dev<maxhd*hf(hi))
  60. hloc(hi) = ploc(pei); % harmonic locations
  61. hmag(hi) = pmag(pei); % harmonic magnitudes
  62. hphase(hi) = pphase(pei); % harmonic phases
  63. end
  64. hi = hi+1; %increase harmonic index
  65. end
  66. % f0
  67. % f0yin
  68. % subplot(2,1,1);
  69. % plot(freq(1:N2),mX);
  70. % hold on;
  71. % plot(f0,mX(round(f0*N/fs)),'g*');
  72. % plot(fs*hloc/N,hmag,'rX');
  73.  
  74. % plot(f0yin,mX(round(f0yin*N/fs)),'g*');
  75. % hold off;
  76. % pause;
  77. % subplot(2,1,2);
  78. % plot(f0,mX(round(f0*N/fs)),'X');
  79. %-----synthesis-----%
  80. plocs = (ploc-1)*Ns/N; % adapt peak locations to synthesis FFT
  81. Y = genspecsines(plocs,pmag,pphase,Ns); % generate spec sines
  82. yw = fftshift(real(ifft(Y))); % time domain of sinusoids
  83. %(pin-hNs:pin+hNs-1)
  84. y(pin-hNs:pin+hNs-1) = y(pin-hNs:pin+hNs-1) + sw.*yw(1:Ns); % overlap-add
  85. pin = pin+H; % advance the sound pointer
  86. end
  87.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement