谐波产品谱Matlab编码误差

时间:2013-11-09 08:49:54

标签: matlab

我正在尝试使用MATLAB找到钢琴录音中存在的基本频率。这些是我遵循的步骤;

  1. 找到信号的包络

  2. 查找注释事项

  3. 在每次发作之间执行FFT

  4. 谐波产品谱。

  5. 当我尝试实现HPS算法时,我面临“尺寸不同意”错误。这是我用过的整个代码。

    [song,FS] = wavread('C major.wav');
    %sound(song,FS);
    
    P = 20000;
    N=length(song);                     % length of song
    t=0:1/FS:(N-1)/FS;                  % define time period
    
    
    song = sum(song,2);                        
    song=abs(song);
    
    % Plot time domain signal
    figure(1);
              subplot(2,1,1)
              plot(t,3*song)
              title('Wave File')
              ylabel('Amplitude')
              xlabel('Length (in seconds)')
              %ylim([-1.1 1.1])
              xlim([0 N/FS])
    
    %----------------------Finding the envelope of the signal-----------------%
    % Gaussian Filter
    x = linspace( -1, 1, P);                      % create a vector of P values between -1 and 1 inclusive
    sigma = 0.335;                                % standard deviation used in Gaussian formula
    myFilter = -x .* exp( -(x.^2)/(2*sigma.^2));  % compute first derivative, but leave constants out
    myFilter = myFilter / sum( abs( myFilter ) ); % normalize
    
    % Plot Gaussian Filter
             subplot(2,1,2)       
             plot(myFilter)
             title('Edge Detection Filter')
    
    % fft convolution
    myFilter = myFilter(:);                         % create a column vector
    song(length(song)+length(myFilter)-1) = 0;      %zero pad song
    myFilter(length(song)) = 0;                     %zero pad myFilter
    edges =ifft(fft(song).*fft(myFilter));
    
    tedges=edges(P:N+P-1);                      % shift by P/2 so peaks line up w/ edges
    tedges=tedges/max(abs(tedges));                 % normalize
    
    %---------------------------Onset Detection-------------------------------%
    % Finding peaks
    maxtab = [];
    mintab = [];
    x = (1:length(tedges));
    min1 = Inf;
    max1 = -Inf;
    min_pos = NaN; 
    max_pos = NaN;
    
    lookformax = 1;
    for i=1:length(tedges)
    
        peak = tedges(i:i);
      if peak > max1, 
          max1 = peak;
          max_pos = x(i); 
      end
      if peak < min1, 
          min1 = peak;
          min_pos = x(i); 
      end
    
      if lookformax
        if peak < max1-0.001
          maxtab = [maxtab ; max_pos max1];
          min1 = peak; 
          min_pos = x(i);
          lookformax = 0;
        end  
      else
        if peak > min1+0.005
          mintab = [mintab ; min_pos min1];
          max1 = peak; 
          max_pos = x(i);
          lookformax = 1;
        end
      end
    end
    % % Plot song filtered with edge detector          
             figure(2)
             plot(1/FS:1/FS:N/FS,tedges)
             title('Song Filtered With Edge Detector 1')
             xlabel('Time (s)')
             ylabel('Amplitude')
             ylim([-1 1.1])
             xlim([0 N/FS])
    
             hold on;
    
             plot(maxtab(:,1)/FS, maxtab(:,2), 'ro')
             plot(mintab(:,1)/FS, mintab(:,2), 'ko')
    
    max_col = maxtab(:,1);
    peaks_det = max_col/FS;
    No_of_peaks = length(peaks_det);
    
    [song,FS] = wavread('C major.wav');
    
    %---------------------------Performing STFT--------------------------------%
    h = 1;
    for i = 2:No_of_peaks
    
        song_seg = song(max_col(i-1):max_col(i)-1);
        L = length(song_seg); 
        NFFT = 2^nextpow2(L); % Next power of 2 from length of y
        seg_fft = fft(song_seg,NFFT);%/L;
        U = size(seg_fft,1)
    
    % In harmonic prodcut spectrum, you downsample the fft data several times and multiply all those with the original fft data to get the maximum peak. 
        %HPS
        seg_fft = seg_fft(1 : size(seg_fft,1)/2 );  
        seg_fft = abs(seg_fft);
    
    %HPS: downsampling
    for i = 1:length(seg_fft)
        seg_fft2(i,1) = 1;
        seg_fft3(i,1) = 1;
        seg_fft4(i,1) = 1;
    %   seg_fft5(i,1) = 1;
    end
    
    for i = 1:floor((length(seg_fft)-1)/2)
        seg_fft2(i,1) = (seg_fft(2*i,1) + seg_fft((2*i)+1,1))/2;
    end
    
    for i = 1:floor((length(seg_fft)-2)/3)
        seg_fft3(i,1) = (seg_fft(3*i,1) + seg_fft((3*i)+1,1) + seg_fft((3*i)+2,1))/3;    
    end
    
    for i = 1:floor((length(seg_fft)-3)/4)
        seg_fft4(i,1) = (seg_fft(4*i,1) + seg_fft((4*i)+1,1) + seg_fft((4*i)+2,1) + seg_fft((4*i)+3,1))/4;
    end
    
    
    %HPS, PartII: calculate product
    p1 = (seg_fft3)  .* (seg_fft4);
    p2 = p1.* (seg_fft2);
    p3 = p2.* (seg_fft);
    
    
    HPS, PartIII: find max
    [f_y1,I] = max(p3)
    
     for c = 1 : length(p3)
         if(p3(c,1) == f_y1)
             index = c;
         end
     end
    
     % Convert that to a frequency
     f_y(h) = (index / NFFT) * FS;
    
    
     h=h+1;
    f_y = abs(f_y)';
    
    
     end
    

    在实施p3 = p2.* (seg_fft);之前, seg_fft,seg_fft2,seg_fft3,seg_fft4 的尺寸都具有相同的尺寸 16384 1 。然后,当我实施p3 = p2.* (seg_fft); seg_fft的大小更改为 8192 1 ,而其余大小保持在 16384 1 时,从而导致错误乘以因为尺寸不一样。

    我真的很困惑为什么这种情况一直在发生,我尝试的任何事情似乎都没有成功。真的真的非常感谢这里的一些帮助...如果有人可以修复这个代码,那将是一个很大的帮助......坦克提前......我真的绝望了......

0 个答案:

没有答案