Replace elements in array with smaller array

23 visualizaciones (últimos 30 días)
Federico Manchini
Federico Manchini el 12 de Mayo de 2019
Respondida: Walter Roberson el 13 de Mayo de 2019
Hi! I'm having a problem with a matlab script. I have a lot of audio tracks, and ideally they should have the same number of samples. But they don't. Most of them have 912000 samples, but a bunch of them have a little bit more (912043, 912051, etc). The problem is i have to create a matrix using all of this tracks information. So I wrote the next script:
% names of the files:
% MIC01_0_M0_D.wav
% MIC01_0_M10_D.wav
% MIC01_0_M20_D.wav
% MIC01_0_M30_D.wav
%.
%.
%.
% MIC01_0_M350_D.wav
% (the only change is the M index)
[Mic01_0_D, Fs] = audioread('MIC01_0_M0_D.wav'); % upload a random file just to get the number of samples
g_index = (0:10:350); % an array with the steps of M
Mic01_0_D = zeros(length(g_index),length(Mic01_0_D)); %matrix of zeros with "g_indez length" rows and "audiotracks samples lenght" columns.
for i=1:length(g_index)
Mic01_0_D(i,:) = audioread(strcat('MIC01_0_M',num2str(g_index(i)),'_D.wav'));
end
But when the loop reaches the audiotrack with more samples, it obviously crashes (it needs more columns that the ones the matrix already has).
So I tried the next script with the idea of having some extra columns if needed:
[Mic01_0_D, Fs] = audioread('MIC01_0_M0_D.wav'); %upload a random file just to get the number of samples
g_index = (0:10:350); %n array with the steps of M
Mic01_0_D = zeros(length(g_index),length(Mic01_0_D)+1000); %matrix of zeros with "g_indez length" rows and "audiotracks samples lenght" columns.
for i=1:length(g_index)
Mic01_0_D(i,:) = audioread(strcat('MIC01_0_M',num2str(g_index(i)),'_D.wav'));
end
Then, I can take a 36x912000 matrix out of the 36x913000 I get from the loop. I will lost same samples in same tracks but I don't care, as I need just the first 912000. But in this case, the script crashes in the first try, beacause it can't fill a bigger array with a smaller one.
Can anyone please give me a hand with this? Thanks!

Respuesta aceptada

dpb
dpb el 12 de Mayo de 2019
Editada: dpb el 12 de Mayo de 2019
Just read into a dummy variable and store only the N samples wanted. Nothing fancy needed at all.
% names of the files:
% MIC01_0_M0_D.wav
% MIC01_0_M10_D.wav
% MIC01_0_M20_D.wav
% MIC01_0_M30_D.wav
Lmax=91200; % Length of record wanted
d=dir('MIC01_0_M*_D.wav'); % return list of files
Nfiles=numel(d); % number files found
MicFiles=zeros(Nfiles,Lmax); % preallocate
for i=1:Nfiles
w=audioread(d(i).name); % upload a random file just to get the number of samples
MicFiles(i,:)=w(1:Lmax); % save Lmax samples
end
Alternatively, you could just use a cell array and save each file's full length; just use the curlies "{}" to dereference the record when reading it back.
  1 comentario
Federico Manchini
Federico Manchini el 12 de Mayo de 2019
Thank you very much!!! It works perfectly. Clearly I was thinking it the wrong way. I'm not very good at coding, I'm learning as I go...
Thanks again!

Iniciar sesión para comentar.

Más respuestas (1)

Walter Roberson
Walter Roberson el 13 de Mayo de 2019
g_index = (0:10:350); % an array with the steps of M
nM = length(g_index);
[Mic01_0_D, Fs] = audioread('MIC01_0_M0_D.wav'); % upload a random file just to get the number of samples
nsamp = size(Mic01_0_D, 1);
nchan = size(Mic01_0_D, 2);
if nM > 1
Mic01_0_D(end,end,nM) = 0; %extend to number of time-points
end
for i = 1:nM
this_file = sprintf('MIC01_0_M%d_D.wav', g_index(i));
this_mic = audioread(this_file);
[this_samps, this_channels]
if size(Mic01_0_D,1) < this_samps
Mic01_0_D(this_samps,end,end) = 0; %extend max samples if needed
end
if size(Mic01_0_D,2) < this_channels)
Mic01_0_D(end,this_channels,end) = 0; %extend max channels if needed
end
Mic01_0_D(1:this_samps, 1:this_channels, i) = this_mic;
end
This will produce an array with samples along the first dimension, channels along the second dimension, and M along the third dimension. (Your existing code was assuming one channel of input, which we as observers do not know to be strictly the case.)
Afterwards,
wanted_samps = permute(Mic01_0_D(1:912000, 1, :), [3 1 2]);
to get the samples along rows like you had coded (which would typically not be the best way to process; typically samples along channels is more efficient.)

Categorías

Más información sobre Creating and Concatenating Matrices en Help Center y File Exchange.

Productos


Versión

R2017b

Community Treasure Hunt

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

Start Hunting!

Translated by