Skip to content

Commit

Permalink
Various improvements for studies requiring sounds strung together
Browse files Browse the repository at this point in the history
  • Loading branch information
jpeelle committed Jan 20, 2015
1 parent 5e750d7 commit 491fd28
Show file tree
Hide file tree
Showing 3 changed files with 353 additions and 117 deletions.
229 changes: 113 additions & 116 deletions jp_equalize.m
Original file line number Diff line number Diff line change
@@ -1,58 +1,62 @@
function jp_equalize(input_dirs, output_dirs, equaltype, verbose)
function jp_equalize(inputDirs, outputDirs, Cfg)
%JP_EQUALIZE Equalize sound files in directories.
%
% equaltype = rms or max
%
% JP_EQUALIZE(INPUTDIRS, OUTPUTDIRS, CFG)
% CFG.equaltype = 'rms' | 'max' | 'dB' (default rms)
% CFG.targetDb = optional if CFG.equaltype='dB' (default -45)
%
% From https://github.com/jpeelle/jp_matlab

if nargin < 2 || isempty(output_dirs)
output_dirs = input_dirs;
elseif ischar(output_dirs)
tmpout = output_dirs;
outputdirs = {};
for i=1:length(input_dirs)
output_dirs = {outputdirs{:} tmpout};
end

if nargin < 2 || isempty(outputDirs)
outputDirs = inputDirs;
elseif ischar(outputDirs)
tmpout = outputDirs;
outputdirs = {};
for i=1:length(inputDirs)
outputDirs = {outputdirs{:} tmpout};
end
else
error('Not sure how to handle output_dirs');
error('Not sure how to handle outputDirs');
end

if nargin < 3
Cfg = [];
end


if nargin < 3 || isempty(equaltype)
equaltype = 'rms';
if ~isfield(Cfg, 'equaltype') || isempty(Cfg.equaltype)
Cfg.equaltype = 'rms';
end

if nargin < 4 || isempty(verbose)
verbose = 1;
if ~isfield(Cfg, 'targetDb') || isempty(Cfg.targetDb)
Cfg.targetDb = -45;
end


% Make sure directories are cell arrays
if ischar(input_dirs) && size(input_dirs,1)==1
input_dirs = {input_dirs};
if ischar(inputDirs) && size(inputDirs,1)==1
inputDirs = {inputDirs};
end

if ischar(output_dirs) && size(output_dirs,1)==1
output_dirs = {output_dirs};
if ischar(outputDirs) && size(outputDirs,1)==1
outputDirs = {outputDirs};
end


% Make sure input directories exist
for i = 1:length(input_dirs)
if ~isdir(input_dirs{i})
error('Input directory %s not found.', input_dirs{i})
end
for i = 1:length(inputDirs)
if ~isdir(inputDirs{i})
error('Input directory %s not found.', inputDirs{i})
end
end

verbose = 1;

% Make sure the output directories exist
for i = 1:length(output_dirs)
if ~isdir(output_dirs{i})
mkdir(output_dirs{i});
end
% Make sure the output directories exist - if not, create
for i = 1:length(outputDirs)
if ~isdir(outputDirs{i})
mkdir(outputDirs{i});
end
end

% Get .wav files from each directory and get the RMS and max volume
Expand All @@ -65,25 +69,25 @@ function jp_equalize(input_dirs, output_dirs, equaltype, verbose)

if verbose > 0; fprintf('Looping through files to get info...'); end

for i=1:length(input_dirs)
d = dir(input_dirs{i});
for j = 1:length(d)
fileName = d(j).name;
if length(fileName)>4 && strcmp(lower(fileName(end-3:end)),'.wav')

num_wav = num_wav + 1;

[y,fs,bits] = wavread(fullfile(input_dirs{i},fileName));
rms_total = rms_total + jp_rms(y);
rms_count = rms_count+1;
if max(y) > max_amplitude
max_amplitude = max(y);
end
for i=1:length(inputDirs)
d = dir(inputDirs{i});
for j = 1:length(d)
fileName = d(j).name;
if length(fileName)>4 && strcmpi(fileName(end-3:end),'.wav')

num_wav = num_wav + 1;

[y,fs] = audioread(fullfile(inputDirs{i},fileName));
rms_total = rms_total + jp_rms(y);
rms_count = rms_count+1;
if max(y) > max_amplitude
max_amplitude = max(y);
end
end
end
end
end % going through input_dirs to get files
end % going through inputDirs to get files

if verbose > 0; fprintf('done.\n Found %i files\n.', num_wav); end
if verbose > 0; fprintf('done.\n Found %i files.\n', num_wav); end

rmsMean = rms_total/rms_count;

Expand All @@ -98,82 +102,75 @@ function jp_equalize(input_dirs, output_dirs, equaltype, verbose)

if verbose > 0; fprintf('Looping through files again to adjust info...'); end

for i=1:length(input_dirs)

if ~isdir(input_dirs{i})
error('Can''t find input directory %s.', input_dirs{i})
end

d = dir(input_dirs{i});
for j = 1:length(d)
fileName = d(j).name;
if length(fileName)>4 && strcmp(lower(fileName(end-3:end)),'.wav')

infile = fullfile(input_dirs{i}, fileName);
movefile = fullfile(input_dirs{i}, sprintf('OLD%s',fileName));

[y,fs,bits] = wavread(infile);

if strcmp(equaltype, 'rms')
thisRms = jp_rms(y);
rms_before(this_wav) = thisRms;
y2 = y * (rmsMean/thisRms);
rms_after(this_wav) = jp_rms(y2);
this_wav = this_wav + 1;

% Scale if over 1 or under -1
if max(y2) > 1 || min(y2) < -1
fprintf('File %s: MIN = %.3f, MAX = %.3f, scaling so as not to clip.\n', fileName, min(y2), max(y2));
biggest = max([abs(min(y2)) max(y2)]);
y2 = (y2/biggest) * .99;
for i=1:length(inputDirs)


d = dir(inputDirs{i});
for j = 1:length(d)
fileName = d(j).name;
if length(fileName)>4 && strcmpi(fileName(end-3:end),'.wav')

infile = fullfile(inputDirs{i}, fileName);

[y,fs] = audioread(infile);

thisRms = jp_rms(y);
rms_before(this_wav) = thisRms;

switch lower(Cfg.equaltype)
case 'rms'
y2 = y * (rmsMean/thisRms);
rms_after(this_wav) = jp_rms(y2);

case 'max'
max_amp_before(this_wav) = max(y);
y2 = y / (max_amplitude/.98);
max_amp_after(this_wav) = max(y2);

case 'db'
targetRMS = 10^(Cfg.targetDb/20);
scaleFactor = targetRMS/thisRms;
y2 = y * scaleFactor;

end % switch

this_wav = this_wav + 1;

% if strcmp(equaltype, 'rms')
% thisRms = jp_rms(y);
% rms_before(this_wav) = thisRms;
% y2 = y * (rmsMean/thisRms);
% rms_after(this_wav) = jp_rms(y2);
% this_wav = this_wav + 1;
%
% % Scale if over 1 or under -1
% if max(y2) > 1 || min(y2) < -1
% fprintf('File %s: MIN = %.3f, MAX = %.3f, scaling so as not to clip.\n', fileName, min(y2), max(y2));
% biggest = max([abs(min(y2)) max(y2)]);
% y2 = (y2/biggest) * .99;
% end
%
% elseif strcmp(equaltype, 'max')
% if max(y)==max_amplitude && verbose > 0
% fprintf('Maximum amplitude of %.3f found in %s.\n', max_amplitude, infile);
% end
%
% max_amp_before(this_wav) = max(y);
% y2 = y / (max_amplitude/.98);
% max_amp_after(this_wav) = max(y2);
% this_wav = this_wav + 1;
% end

outfile = fullfile(outputDirs{i}, fileName);

audiowrite(outfile, y2, fs);
end

elseif strcmp(equaltype, 'max')
if max(y)==max_amplitude && verbose > 0
fprintf('Maximum amplitude of %.3f found in %s.\n', max_amplitude, infile);
end

max_amp_before(this_wav) = max(y);
y2 = y / (max_amplitude/.98);
max_amp_after(this_wav) = max(y2);
this_wav = this_wav + 1;
end

outfile = fullfile(output_dirs{i}, fileName);

if strcmp(input_dirs{i}, output_dirs{i})
system(sprintf('mv %s %s', infile, movefile));
end

wavwrite(y2, fs, bits, outfile)
end
end
end


if verbose > 0
if strcmp(equaltype, 'rms')
figure
subplot(1,2,1)
hist(rms_before)
title('RMS before')

subplot(1,2,2)
hist(rms_after)
title('RMS after')
elseif strcmp(equaltype, 'max')
figure
subplot(1,2,1)
hist(max_amp_before)
title('Max Amplitude Before')

subplot(1,2,2)
hist(max_amp_after)
title('Max Amplitude After')

end

end

fprintf('done.\n');

9 changes: 9 additions & 0 deletions jp_maketone.m
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@
Cfg.fs = 20050;
end

if ~isfield(Cfg, 'db') || isempty(Cfg.db)
Cfg.db = -25; % dB FS
end


fs = Cfg.fs;
rampUpSamples = round(Cfg.rampUpSec * fs);
Expand All @@ -47,6 +51,11 @@
t = 0:1/fs:durationSec;
y = sin(freq*2*pi*t);

% Adjust the dB NB for steady state (done before ramping)
targetRMS = 10^(Cfg.db/20);
scaleFactor = targetRMS/jp_rms(y);
y = y * scaleFactor;

% Ramp
if rampUpSamples > 0
step = 1/rampUpSamples;
Expand Down
Loading

0 comments on commit 491fd28

Please sign in to comment.