function Vrms = replaygain(filename,a1,b1,a2,b2)
% Determine the perceived loudness of a file
% METHOD:
% 1) Calculate Vrms every 50ms
% 2) Sort in ascending order of loudness
% 3) Pick the 95% interval (i.e. go 95% up the list, and choose the value at this point)
% 4) Convert this value into dB
% 5) return this value.
% Back in the main program...
% 6) Subtract it from that calculated for -20dB FS RMS pink noise
% Result = required correction to replay gain (relative to 83dB reference)

% David Robinson, 10th July 2001. http://www.David.Robinson.org/


% Get information about file
lngth=wavread(filename,'size');
samples=lngth(1);
channels=lngth(2);
% Read sampling rate and No. of bits
[dummy,fs,bs]=wavread(filename,[1 2]);

% The the file isn't CD sample rate, try to generate appropriate equal loudness filter
if fs~=44100 | nargin<2,
   [a1,b1,a2,b2]=equalloudfilt(fs);
end

% Set the Vrms window to 50ms
rms_window_length=round(50*(fs/1000));

% Set the interval to 95%
percentage=95;	% Which rms value to take as typical of whole file

% Set amount of data (in seconds) which Matlab on my PC happily copes with at once
block_length=2;	% chunk data in from wave file in 2 second blocks - file less than this length will cause an error

% Determine how many rms value to calculate per block of data
rms_per_block=fix((fs*block_length)/rms_window_length);

% Check that the file is long enough to process in block_length blocks
if lngth<(fs*block_length),
   warning(['skipping ' filename ' because it is too short']);
   Vrms=0;
   Vrms_all=0;
   return
end

% Display a Waitbar to show user how far into file we are
wbh=waitbar(0,'Processing...');

% Loop through all the file in blocks a defined above
for audio_block=0:fix(samples/(fs*block_length))-1,
   % Update the waitbar display to reflect progress
   waitbar(audio_block/(fix(samples/(fs*block_length))-1));
   % Grab a section of audio
   inaudio=wavread(filename,[(fs*block_length*audio_block)+1 fs*block_length*(audio_block+1)]);
   % Filter it using the equal loudness curve filter:
   inaudio=filter(b1,a1,inaudio);
   inaudio=filter(b2,a2,inaudio);
   % Calculate Vrms:
   for rms_block=0:rms_per_block-1,
      % Mono signal: just do the one channel
      if channels==1,
         Vrms_all((audio_block*rms_per_block)+rms_block+1)=mean(inaudio((rms_block*rms_window_length)+1:(rms_block+1)*rms_window_length).^2);
      % Stereo signal: take average Vrms of both channels   
      elseif channels==2,
         Vrms_left=mean(inaudio((rms_block*rms_window_length)+1:(rms_block+1)*rms_window_length,1).^2);
         Vrms_right=mean(inaudio((rms_block*rms_window_length)+1:(rms_block+1)*rms_window_length,2).^2);
         Vrms_all((audio_block*rms_per_block)+rms_block+1)=(Vrms_left+Vrms_right)/2;
      end
   end
end

% Close the waitbar
close(wbh);

% Convert to dB
Vrms_all=10*log10(Vrms_all+10^-10);
% Sort the Vrms values into numerical order
Vrms_all=sort(Vrms_all);
% Pick the 95% value
Vrms=Vrms_all(round(length(Vrms_all)*percentage/100));

return
