function [onset,osr,D,tt,ff] = beat_onset(d,sr)
% [onset,osr,D,tt,ff] = beat_onset(d,sr)
%   Simple onset strength function for beat tracking.
%   d, sr define a waveform
%   or d is the name of a waveform file.
%   onset returns a sampled "onset strength" waveform
%   at a frame rate returned oin osr.
%   D returns the mel-spectrogram from which the onsets are
%   derived. tt labels the times of its columns, and ff the
%   frequencies of its rows.
% 2012-03-27 Dan Ellis [email protected]

targetsr = 11025;

if ischar(d)
  % passed a file name - read it in
  fname = d;
  forcemono = 1;
  [d,sr] = audioread(fn,targetsr,forcemono);
else
  % passed actual waveform
  fname = '<noname>';
end

% Fix sampling rate if needed
if sr ~= targetsr
  d = resample(d,targetsr,sr);
end

% specgram: 256 bin @ 11kHz = 23 ms / 3 ms hop
swin = 256;
shop = 32;
% mel channels
nmel = 20;
% sample rate for specgram frames (granularity for rest of processing)
osr = targetsr/shop;

% Calculate spectrogram
D = specgram(d,swin,sr,swin,swin-shop);

% Calculate a time base for the spectrogram (to return)
tt = [0:size(D,2)-1]/osr;

% Construct db-magnitude-mel-spectrogram
[mlmx, ff] = fft2melmx(swin,sr,nmel);
D = 20*log10(max(1e-10,mlmx(:,1:(swin/2+1))*abs(D)));

% Only look at the top 60 dB
D = max(D, max(D(:))-60);

% The raw onset decision waveform - half-wave rectified first-order difference
mm = (mean(max(0,diff(D')')));

% dc-removed onset waveform
onset = filter([1 -1], [1 -.99],mm);