Skip to content

Commit

Permalink
Cosmetic changes, updating wavread/wavwrite to audioread/audiowrite
Browse files Browse the repository at this point in the history
  • Loading branch information
jpeelle committed Nov 13, 2014
1 parent 713017e commit 18a4e87
Show file tree
Hide file tree
Showing 26 changed files with 240 additions and 174 deletions.
17 changes: 17 additions & 0 deletions README
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
jp_matlab is a collection of helper scripts that I have written over the
past few years. I hope they are helpful, but use at your own risk!

In many cases the script will work on one sound file, stimulus, or
directory, and some additional scripting will be needed to process all
of the items you want to process for a particular project. I have tried
to include *_wrapper.m scripts as examples for just this purpose.

These scripts are provided under an MIT license (see LICENSE.txt).

Please contact me if you find any errors!

Jonathan Peelle
Department of Otolaryngology
Washington University in Saint Louis
http://jonathanpeelle.net
http://peellelab.org
48 changes: 25 additions & 23 deletions jp_addnoise.m
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,10 @@ function jp_addnoise(soundfiles, cfg)
% cfg = [];
% cfg.snrs = [0 5 10];
% cfg.noisefile = '/Users/peelle/Desktop/noise.wav';
%
%
% jp_addnoise(inDir, cfg);
%
% From https://github.com/jpeelle/jp_matlab


if ~isfield(cfg, 'prestim') || isempty(cfg.prestim)
Expand Down Expand Up @@ -64,8 +66,8 @@ function jp_addnoise(soundfiles, cfg)
if ischar(soundfiles) && isdir(soundfiles)
soundDir = soundfiles;
D = dir(fullfile(soundfiles, '*.wav'));
soundfiles = {D.name};
soundfiles = {D.name};

for i=1:length(soundfiles)
soundfiles{i} = fullfile(soundDir, soundfiles{i});
end
Expand All @@ -76,60 +78,60 @@ function jp_addnoise(soundfiles, cfg)
end
end


% Get noise
[yNoise, fsNoise, bitsNoise] = wavread(cfg.noisefile);
[yNoise, fsNoise, bitsNoise] = audioread(cfg.noisefile);


% Loop through soundfiles and add noise
for i = 1:length(soundfiles);

thisSound = soundfiles{i};
[y, fs, bits] = wavread(thisSound);

[y, fs, bits] = audioread(thisSound);

assert(fs==fsNoise, 'Sampling rate of sentence %s (%i) does not match that of noise (%i).', thisSound, fs, fsNoise);

rmsSignal = jp_rms(y);
dbSignal = jp_mag2db(rmsSignal);

% get the part of noise we need, and it's RMS and dB
tmpNoise = yNoise(1:(length(y)+cfg.prestim*fs+cfg.poststim*fs));
rmsNoise = jp_rms(tmpNoise);
dbNoise = mag2db(rmsNoise);
for thisSNR = cfg.snrs

for thisSNR = cfg.snrs

targetDb = dbSignal - thisSNR; % target for noise dB
targetRMS = 10^(targetDb/20);
scaleFactor = targetRMS/rmsNoise;

scaledNoise = tmpNoise * scaleFactor;

rmsScaledNoise = jp_rms(scaledNoise);
dbScaledNoise = jp_mag2db(rmsScaledNoise);
fprintf('SNR %g:\tsignal = %.1f, noise = %.1f dB\n', thisSNR, dbSignal, dbScaledNoise);

yNew = [zeros(cfg.prestim*fs,1); y; zeros(cfg.poststim*fs,1)] + scaledNoise;

if max(yNew) > 1
warning('Signal %s clipping at %g.', thisSound, max(yNew));
end

% write new file
[pth, nm, ext] = fileparts(thisSound);

% decide where to save it - is cfg.outdir specified?
if ~isempty(cfg.outdir)
outDir = cfg.outdir;
else
outDir = pth;
end

fileName = fullfile(outDir, sprintf('%s_SNR%d%s', nm, thisSNR, ext));
wavwrite(yNew, fs, bits, fileName);
end % going through SNRs
audiowrite(yNew, fs, bits, fileName);

end % going through SNRs
end % looping through soundfiles

end % main function
Expand Down
3 changes: 3 additions & 0 deletions jp_addnoise_wrapper.m
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
%
% From https://github.com/jpeelle/jp_matlab

clear all

% The original files are in originalDir; the thinking is that these should
Expand Down
13 changes: 7 additions & 6 deletions jp_addsounds.m
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
%
% cfg.offsetSecs: + values mean distractor after target, - values before
% cfg.trimDistractorSecs = Inf; % If < Inf, run for this many seconds after target finishes

%
% From https://github.com/jpeelle/jp_matlab

if nargin < 4
cfg = [];
Expand Down Expand Up @@ -47,19 +48,19 @@
% If the distractor goes on longer than the target, see if we should trim
% it. And if so, do it.
if length(y2) > length(y1) && trimDistractorSecs < Inf
extra = trimDistractorSecs * fs;
extra = trimDistractorSecs * fs;

% If there isn't enough distractor this won't work anyway
try
y2 = y2(1:(length(y1)+extra));
catch
end

if distractorFadeSecs > 0
error('fade out not implemented yet');

end

end


Expand Down
3 changes: 2 additions & 1 deletion jp_equalize.m
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ function jp_equalize(input_dirs, output_dirs, equaltype, verbose)
%
% equaltype = rms or max
%

%
% From https://github.com/jpeelle/jp_matlab

if nargin < 2 || isempty(output_dirs)
output_dirs = input_dirs;
Expand Down
19 changes: 10 additions & 9 deletions jp_equalizerms.m
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ function jp_equalizerms(inputDir,outputDir,verbose)
% large groups of files.
%
% See also JP_EQUALIZEMAX.

%
% From https://github.com/jpeelle/jp_matlab


% Error checking
Expand Down Expand Up @@ -57,7 +58,7 @@ function jp_equalizerms(inputDir,outputDir,verbose)
fileName = D(i).name;
% If it is a WAV file, get the RMS
if length(fileName)>4 && strcmp(lower(fileName(end-3:end)),'.wav')
[y,fs,bits] = wavread(fullfile(inputDir,fileName));
[y,fs,bits] = audioread(fullfile(inputDir,fileName));
rmsTotal = rmsTotal + rms(y);
rmsCount = rmsCount+1;
end
Expand All @@ -78,28 +79,28 @@ function jp_equalizerms(inputDir,outputDir,verbose)
% Keep track of how many 'real' files
fileNumber = fileNumber + 1;

[y,fs,bits] = wavread(fullfile(inputDir,fileName));
[y,fs,bits] = audioread(fullfile(inputDir,fileName));
thisRms = rms(y);

y2 = y * (rmsMean/thisRms);


% 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


% Make sure we were within error range
if rms(y2)-rmsMean > .01*rmsMean
fprintf('Warning for %s: Equalized RMS is %.3f, goal RMS is %.3f...\n',fileName,rms(y2),rmsMean);
end


% Write the new .wav file
wavwrite(y2,fs,bits,fullfile(outputDir,fileName));
audiowrite(y2,fs,bits,fullfile(outputDir,fileName));

% Note how far along we are
if verbose && rmsCount>20 && mod(fileNumber,round(rmsCount/10))==0
Expand Down
4 changes: 3 additions & 1 deletion jp_fitpow.m
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@
% By regressing a straight line on logy/logx, giving:
%
% log(yy) = b*logx + a
%
%
%
% N.B. assumes all values in y are >= 0.
%
% From https://github.com/jpeelle/jp_matlab

yflip = 0; % return yy the same as y was fed in

Expand Down
15 changes: 8 additions & 7 deletions jp_getenvelope.m
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@
% the unfiltered signal is returned.
%
% JP_GETENVELOPE requires the signal processing toolbox.
%
% Jonathan Peelle
%
%
% From https://github.com/jpeelle/jp_matlab


if nargin < 3
Expand All @@ -36,7 +37,7 @@
% If not a .wav file, make sure fs is specified
if nargin < 2 || isempty(fs)
error('If S is not a .wav file, you must specify Fs.')
end
end
end

half_sample_rate = fs/2;
Expand Down Expand Up @@ -73,10 +74,10 @@
env = filter(lpB,lpA,abs(s));
end
else

% create a matrix for holding the envelopes, one per row
env = zeros(length(opts.edge_freqs)-1, length(s));

for i=1:length(opts.edge_freqs)-1
W1 = [opts.edge_freqs(i)/half_sample_rate, opts.edge_freqs(i+1)/half_sample_rate];
[infilterB, infilterA] = butter(3,W1);
Expand All @@ -90,7 +91,7 @@
elseif strcmp(opts.rectify,'full')
env(i,:) = filter(lpB,lpA,abs(yy));
end

end

end
19 changes: 10 additions & 9 deletions jp_getfrequencies.m
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@
% optional opts has the following fields:
%
% method 'log' or 'greenwood' (default 'log')
%
%
%
% If the method is Greenwood, the equation from Greenwood (1961) is
% used to approximate equal spacing along the basilar membrane.
% This is similar to logrithmic but not identical.
%
% Jonathan Peelle
%
% From https://github.com/jpeelle/jp_matlab



Expand All @@ -26,8 +27,8 @@
if ~(strcmp(opts.method,'log') || strcmp(opts.method,'greenwood'))
error('The method must be ''log'' or ''greenwood''.');
end
end
end


l = zeros(n); % lower frequencies
c = zeros(n); % center frequencies
Expand All @@ -41,27 +42,27 @@

edges = [0:1:n];
c = [0:1:n]+.5;

for i=1:length(edges)
edges(i) = low * 10^(interval*edges(i));
if i<length(edges)
c(i) = low * 10^(interval*c(i));
end
end
l = edges(1:n);
l = edges(1:n);
u = edges(2:n+1);

elseif strcmp(opts.method,'greenwood')
edges = [0:1:n]*(freq2mm(high)-freq2mm(low))/n + freq2mm(low);
l = edges(1:n);
u = edges(2:n+1);
c = edges(1:n) + edges(2:n+1)/2;

% change back to frequencies
l = mm2freq(l);
u = mm2freq(u);
c = mm2freq(c);

else
error('Unsupported method for conversion.');
end
Expand Down
Loading

0 comments on commit 18a4e87

Please sign in to comment.