Clear Filters
Clear Filters

Adding values to a cell array in a loop for wav files

2 views (last 30 days)
I am reading in a wav file in a loop, condcuting and power spectral analysis, and then identifying peaks (by frequency) in a specific band. At the end I need to concatenate the values and spit out a full table that includes all files analyzed. I'm having trouble with " peaks(i) = [pks freq]". I am getting this error "Unable to perform assignment because the indices on the left side are not compatible with the size of the right side." See code:
for i = 941:24:1608; % Start at 4am to avoid chorusing fish or vessels
fprintf('Processing %s\n', char(strcat(Dirin,"\",filelist(i))))
filename = filelist(i);
[filepath,name,ext] = fileparts(filename);
[y,Fs] = audioread(char(strcat(Dirin,"\",filelist(i)))); % read in wav file
samples = length(y);
dt = 1/Fs;
t = (0:dt:(samples-1)*dt);
[sensor_spectrum, freq] = pwelch(y,w,NOVERLAP,NFFT,Fs);
sensor_spectrum_dB = 20*log10(sensor_spectrum) - sensitivity - gain ;
sensor_spec_adj = sensor_spectrum_dB(292:1758); %subsetting db
freq_adj = freq(292:1758); %subsetting frequency
[pks, freq] = findpeaks(sensor_spec_adj, freq_adj, 'MinPeakProminence', 10);
peaks(i) = [pks freq]
name_add = repmat({name},size(peaks(i),1),1)
peaks(i) = [name_add num2cell(peaks)]
end

Answers (2)

Star Strider
Star Strider on 25 Aug 2022
Save it to a cell array instead —
peaks{i} = [pks freq]
That should work, since the two vectors being cncatenated will have the same sizes (both assumed to be column vectors).
.
  2 Comments
Star Strider
Star Strider on 25 Aug 2022
As I mentioned ‘(both assumed to be column vectors)’ however apparently, they‘re row vectors, so instead use:
peaks{i} = [pks; freq]
Testing this —
M = randi(9,5,10)
M = 5×10
4 5 6 2 9 4 9 6 4 1 2 9 1 2 2 2 6 4 6 3 4 1 6 2 6 9 3 1 1 3 3 7 3 4 5 9 6 3 7 9 3 8 6 2 2 3 5 6 8 3
freqvctr = linspace(0, size(M,2)-1, size(M,2))*0.1
freqvctr = 1×10
0 0.1000 0.2000 0.3000 0.4000 0.5000 0.6000 0.7000 0.8000 0.9000
for i = 1:size(M,1)
[pks,freq] = findpeaks(M(i,:),freqvctr, 'MinPeakProminence',2.5);
peaks{i} = [pks; freq];
end
peaks
peaks = 1×5 cell array
{2×2 double} {2×3 double} {2×2 double} {2×2 double} {2×2 double}
peaks{1}
ans = 2×2
9.0000 9.0000 0.4000 0.6000
peaks{end}
ans = 2×2
8.0000 8.0000 0.1000 0.8000
The slight changed needed to work with row vectors seems to work.
.

Sign in to comment.


Yuqing Li
Yuqing Li on 25 Aug 2022
Hello Benjamin,
[pks freq] as the output from function "findpeaks" will be an Nx2 matrix (N being the number of peaks found), but peaks(i) is a scalar. You can iniitialize peaks as a cell array:
peaks = cell(number of iterations,1);
and save [pks freq] in each iteration by:
peaks{i} = [pks freq];
  2 Comments
Yuqing Li
Yuqing Li on 25 Aug 2022
What form of output do you want to get?
Is it a table with filenames in the first column, pks and freq in the second and third column respectively?

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!