MATLAB Answers

For Loop Dimensions Not Consistent Horzcat

1 view (last 30 days)
Louise Wilson
Louise Wilson on 30 Apr 2019
Commented: Louise Wilson on 30 Apr 2019
Hi everyone,
I am new to Matlab and working through code I have found to understand each step. You can see my comments describing in as much detail as I can, what is going on in each step.
This is a for loop which I plan to use to calculate the mean sound pressure level (SPL) of a large batch of sound files.
I understand what is going on in each step and have carried out each in turn, before executing the loop, to make sure everything works.
However, in the last step, where I combing meanlevellist and mean_SPL into an array, I get an error telling my that the dimensions of the two lists are different. I understand what this means in theory but I don't know how to fix it, or see exactly where I have gone wrong, in my code.
ANY advice would be much appreciated!!
I am very keen to develop and advance here.
>> clf; clear all; %clf-clear current figure;
%clear ALL-clear ALL variables and functions from memory
d = dir('*.wav'); %d=dir lists the names of the files/folders in the current directory
%dir('NAME')-lists the files in a folder, * is an asterisk wildcard
%MATLAB matches all characters in the name exactly except for the wildcard
%character *, which can match any one or more characters.
%so '*.wav' lists all files ending in '.wav' from current directory
meanlevellist = zeros(size(d)); %size() returns the size of an array e.g. 70 .wav files
%zeros returns a matrix of zeros-this sets aside storage for a matrix
%whose elements are to be generated one at a time e.g. 70*0
%these are then stored in variable meanlevellist
%Now we use a 'for' loop.
for i = 1:length(d) %length(d) is number of wav files in d so 1-length(d)=1-70,
%so create variable i which has 70 columns
filename = d(i).name; %get the names of all files in d and store in 'filename'
[dat,fs]=audioread(filename); %[dat,fs]=audioread(filename); returns sampled data in dat and the sample rate Fs in Hz
tlo=10; tup=20; % create time window for plot - NB seconds
nlo=fs*tlo+1; % first data sample index = sampling frequency * tlo + 1 = 480001
nup=fs*tup; % last data sample index =960000
data=dat(nlo:nup)'; % data segment for plot/spectrum
cal = 171.7; % number taken from calibration sheet
fact_cal = 10^(cal/20); % apply calibration
data=data*fact_cal; % apply calibration
npts=length(data); % number of points in data segment
tint=npts/fs; % time interval of data segment
flo=10; fhi=100; % band pass filter bandwidth
fdata=bandpass(data,[flo,fhi],fs); % apply band pass filter
pfdata=abs(fdata).^2; % is Prms^2 of filtered data
mean_SPL=10*log10(sum(pfdata)/length(pfdata)); % mean power level, in dB
meanlevellist(i) = mean_SPL;
meanlevellist = [meanlevellist, mean_SPL];
end
csvwrite('output_mean_SPL.csv', meanlevellist);
Error using horzcat
Dimensions of arrays being concatenated are not consistent.

  0 Comments

Sign in to comment.

Answers (1)

James Tursa
James Tursa on 30 Apr 2019
In these two lines:
meanlevellist(i) = mean_SPL;
meanlevellist = [meanlevellist, mean_SPL];
The first line puts mean_SPL into the i'th spot of meanlevellist. Thus it seems to me that the second line is redundant to what you are trying to do. I would suggest getting rid of that second line.

  3 Comments

Louise Wilson
Louise Wilson on 30 Apr 2019
Hi James!
Thank you for your answer.
Yes, I understand. I am running this now but it's taking a while to run.
Would you agree that perhaps instead of:
meanlevellist(i) = mean_SPL;
meanlevellist = [meanlevellist, mean_SPL];
It would be more intuitive to have:
meanlevellist(i) = mean_SPL;
meanlevellist = [filename, mean_SPL];
??
Louise Wilson
Louise Wilson on 30 Apr 2019
It works to remove the last line, as you said, which is very helpful :-)
Removing the last line gives me a list of the mean_SPL values in a 1x5 array.
I would like to have a 2x5 array with the mean_SPL values listed alongside the filenames.
This code runs without errors but it gives me one value in 1x1 cell matrix, clearly wrong.
I can't get this to work? What do you think?
for i = 1:length(d) %length(d) is number of wav files in d so 1-length(d)=1-70,
%so apply for loop for each data point from 1-70
filename = d(i).name; %get filename in d and store in 'filename'
[dat,fs]=audioread(filename); %[dat,fs]=audioread(filename); returns sampled data in dat and the sample rate Fs in Hz
tlo=10; tup=20; % create time window for plot - NB seconds
nlo=fs*tlo+1; % first data sample index = sampling frequency * tlo + 1 = 480001
nup=fs*tup; % last data sample index =960000
data=dat(nlo:nup)'; % data segment for plot/spectrum
cal = 171.7; % number taken from calibration sheet
fact_cal = 10^(cal/20); % apply calibration
data=data*fact_cal; % apply calibration
npts=length(data); % number of points in data segment
tint=npts/fs; % time interval of data segment
flo=10; fhi=100; % band pass filter bandwidth
fdata=bandpass(data,[flo,fhi],fs); % apply band pass filter
pfdata=abs(fdata).^2; % is Prms^2 of filtered data
mean_SPL=10*log10(sum(pfdata)/length(pfdata)); % mean power level, in dB
meanlevellist(i) = mean_SPL;
meanlevellist=[meanlevellist, filename];
end
Louise Wilson
Louise Wilson on 30 Apr 2019
I have tried this a few different ways but can't get it to work.
Ultimately I want to add my new list of meanSPL values to the existing database.
Could I do this by adding a column to the structure, to make it a 6x1 array?
I'm not sure how to do this but trying to find the solution.

Sign in to comment.

Tags

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!