computes a simple beat histogram > > supported computation methods are: > 'Corr', > 'FFT', > > @param x: time domain sample data, dimension channels X samples > @param f_s: sample rate of audio data > @param cMethod: method of beat histogram computation (default: 'FFT') > @param afWindow: FFT window of length iBlockLength (default: hann), can be [] empty > @param iBlockLength: internal block length (default: 4096 samples) > @param iHopLength: internal hop length (default: 512 samples) > > @retval T: Beat histogram > @retval Bpm: tempo axis ======================================================================
0001 %computes a simple beat histogram 0002 %> 0003 %> supported computation methods are: 0004 %> 'Corr', 0005 %> 'FFT', 0006 %> 0007 %> @param x: time domain sample data, dimension channels X samples 0008 %> @param f_s: sample rate of audio data 0009 %> @param cMethod: method of beat histogram computation (default: 'FFT') 0010 %> @param afWindow: FFT window of length iBlockLength (default: hann), can be [] empty 0011 %> @param iBlockLength: internal block length (default: 4096 samples) 0012 %> @param iHopLength: internal hop length (default: 512 samples) 0013 %> 0014 %> @retval T: Beat histogram 0015 %> @retval Bpm: tempo axis 0016 % ====================================================================== 0017 function [T, Bpm] = ComputeBeatHisto (x, f_s, cMethod, afWindow, iBlockLength, iHopLength) 0018 0019 % set default parameters if necessary 0020 if (nargin < 6) 0021 iHopLength = 8; 0022 end 0023 if (nargin < 5) 0024 iBlockLength = 1024; 0025 end 0026 if (nargin < 4 || isempty(afWindow)) 0027 afWindow = hann(iBlockLength, 'periodic'); 0028 end 0029 if (nargin < 3) 0030 cMethod = 'FFT'; 0031 end 0032 % compute FFT window function 0033 if (length(afWindow) ~= iBlockLength) 0034 error('window length mismatch'); 0035 end 0036 0037 % pre-processing: down-mixing 0038 x = ToolDownmix(x); 0039 0040 % novelty function 0041 [d, t, G_T, peaks] = ComputeNoveltyFunction ( 'Flux', ... 0042 x, ... 0043 f_s, ... 0044 afWindow, ... 0045 iBlockLength, ... 0046 iHopLength); 0047 0048 if strcmp(cMethod, 'Corr') 0049 % compute autocorrelation 0050 r_dd = xcorr(d, 'coeff'); 0051 r_dd = r_dd((ceil((length(r_dd) / 2)) + 1):end); 0052 0053 Bpm = fliplr(60 ./ t(2:end)); 0054 T = fliplr (r_dd); 0055 else %if method == 'FFT' 0056 iLength = 65536; 0057 f_s = f_s / iHopLength; 0058 if length(d)< 2 * iLength 0059 d = [d zeros(1, 2 * iLength - length(d))]; 0060 end 0061 [D, f, tf] = ComputeSpectrogram(d, ... 0062 f_s, ... 0063 [hann(iLength); zeros(iLength,1)], ... 0064 2*iLength, ... 0065 iLength/4); 0066 0067 % adjust output BPM range 0068 T = mean(abs(D), 2); 0069 Bpm = f * 60; 0070 lIdx = max(find(Bpm < 30)); 0071 hIdx = min(find(Bpm > 200)); 0072 T = T(lIdx:hIdx); 0073 Bpm = Bpm(lIdx:hIdx); 0074 end 0075 end