function [D, SR] = audioread(FN, TARGETSR, FORCEMONO, START, END)
% [D, SR] = audioread(FN, TARGETSR, FORCEMONO, START, END)
%   Read in an audio file, using wavread, mp3read, m4aread, or flacread2 as
%   appropriate. 
% 2010-09-16 Dan Ellis [email protected]

if nargin < 2; TARGETSR = []; end
if nargin < 3; FORCEMONO = 0; end
if nargin < 4; START = 0; end
if nargin < 5; END = 0; end

if length(TARGETSR) == 0
  TARGETSR = 0;
end

if exist(FN, 'file') == 0
  error(['audioread: file ',FN,' not found']);
end

[pth,nam,ext] = fileparts(FN);
ext = lower(ext);
if strcmp(ext,'.mp3')
  [SIZ,SR] = mp3read(FN,'size');
  ch = min(FORCEMONO,SIZ(2));
  ds = 1;
  if TARGETSR > 0 && SR > 2*TARGETSR
    ds = 2;
    if SR > 4*TARGETSR && SR >= 22050
      % mpg123 will only do 4:1 downsampling for higher SRs
      ds = 4;
    end
  end
  [D,SR] = mp3read(FN,0,ch,ds);
elseif strcmp(ext, '.m4a') || strcmp(ext, '.aac') || strcmp(ext, '.mp4')
  [SIZ,SR] = m4aread(FN,'size');
  ch = min(FORCEMONO,SIZ(2));
  ds = 1;
%  if TARGETSR > 0 && SR > 2*TARGETSR
%    ds = 2;
%    if SR > 4*TARGETSR
%      ds = 4;
%    end
%  end
% downsampling really helps in mp3read, but not at present in m4aread
  [D,SR] = m4aread(FN,0,ch,ds);
elseif strcmp(ext, '.flac')
  [D,SR] = flacread2(FN);
elseif strcmp(ext, '.wv1') || strcmp(ext, '.wv2') ...
         || strcmp(ext, '.wvs') || strcmp(ext, '.shn')
  % nist sphere with shorten - wsj1
  % use dpwelib as a mex file
  [D,SR] = ReadSound(FN);
  D = D'; % returns in rows!
else
  [D,SR] = wavread(FN);
end

% always mono (if not handled in mp3read etc.)
if FORCEMONO && size(D,2) == 2
  D = mean(D,2);
end

% truncate before resampling
if START > 0 || END > START
  if END < START; END = length(D)/SR; end
  EIX = min(length(D),round(END*SR));
  D = D((round(START*SR)+1):EIX,:);
end

if TARGETSR > 0 && SR ~= TARGETSR
  [p,n,e] = fileparts(FN);
  %disp(['*** audioread: resampling ',n,' from ', num2str(SR), ...
  %      ' to ', num2str(TARGETSR)]);
  D = resample(D, TARGETSR, SR);
  SR = TARGETSR;
end