Using repmat() to equalise the length of two audio files Matlab - matlab

Having a slight issue with the repmat() function.
I've got two audio files that I'm using for cross synthesis in Matlab, I want to make the second audio file repeat so it's the same length as the first one.
Currently I'm doing
c = size(y());
rep = y2(1:end,:);
y(1:end,:) = repmat(rep,1, c(1))
Yet it's not making a 1D matrix, any suggestions?
y and y2 are just the y values of each song converted to mono.
Thanks!

I actually managed to solve it myself, turns out I was using them in the wrong order, needed to be repmat(rep c(1), 1)!

Related

Matlab read multiples samples with audioread

I'm trying to read multiple samples from a mp3 file with the function audioread.
let's say I have the following code :
samples = [1, 44100; 50000, 100000; 150000, 200000];
[signal, fe] = audioread(filepath, samples);
t = (1/fe:1/fe:lenght(signal)/fe);
signal = signal(:,1);
How can I make this work ? If samples contain only 1 row, it works just fine, but I have like 80 samples in the same mp3 file to work with.
I've tried this with a for loop, the audioread part works fine, but I don't know how to store the data since the duration of each sample isn't the same, the dimensions of matrices are not consistent and I can't concatenate them in a single matrix.
Plus, I've been told for loops are better avoided whenever possible in Matlab, so I'd like to do this by the rules (but i'll use them if there's no other way ofc).
Finally I'm very new to Matlab so I might miss something very obvious, but cound'nt find out reading through the doc.
Thks for your help :)

Splitting an audio file in Matlab

I'm trying to split an audio file into 30 millisecond disjoint intervals using Matlab. I have the following code at the moment:
clear all
close all
% load the audio file and get its sampling rate
[y, fs] = audioread('JFK_ES156.wav');
for m = 1 : 6000
[t(m), fs] = audioread('JFK_ES156.wav', [(m*(0.03)*fs) ((m+1)*(0.03)*fs)]);
end
But the problem is that I get the following error:
In an assignment A(I) = B, the number of elements in B and I
must be the same.
Error in splitting (line 12)
[t(m), fs] = audioread('JFK_ES156.wav', [(m*(0.03)*fs)
((m+1)*(0.03)*fs)]);
I don't see why there's a mismatch in the number of elements in B and I and how to solve this. How can I get past this error? Or is there just an easier way to split the audio file (maybe another function I don't know about or something)?
I think the easiest way to split audio is to just load it and use the vec2mat function. so you would have something like this;
[X,Fs] = audioread('JFK_ES156.wav');
%Calculate how many samples you need to capture 30ms of audio
matSize = Fs*0.3;
%Pay attention to that apostrophe. Makes sure samples are stored in columns
%rather than rows.
output = vec2mat(x,matSize)';
%You can now have your audio split up into the different columns of your matrix.
%You can call them by using the column calling command for matrices.
%Plot first 30ms of audio
plot(output(:,1));
%You can join the audio back together using this command.
output = output(:);
Hope that helps. Another good thing about this method is that it keeps all your data in one place!
Edit : One thing I thought of, you may get a problem with this depending on your vector size. But I think vec2mat actually zeroPads your vector. Not a big thing, but if you're moving back and forth between the two, then it might be a good idea to have another variable that stores the original length of your signal.
You should just use the variable y and reshape it to form your split audio. For example,
chunk_size = fs*0.03;
y_chunks = reshape(y, chunk_size, 6000);
That will give you a matrix with each column a 30 ms chunk. This code will also be faster than reading small segments from file in a loop.
As hiandbaii suggested you could also use cell array. Make sure you clear your existing variables before that. Not clearing the array t is probably the reason you got the error "Cell contents assignment to a non-cell array object."
Your original error is because you cannot assign a vector with scalar indexing. That is, 'm' is a scalar, but your audioread call is returning a vector. This is what the error says about mismatch in size of I and B. You could also fix that by making t a 2-D array and use an assignment like
[t(m,:), fs] =
It appears that each 30 ms segment is not equal to one sample. That would be the only case where your code works. i.e. 0.03*fs != 1.
You could try using cells instead.. i.e. replace t(m) with t{m}

Trying to recreate cocktail party algorithm in Matlab, Wrong results?

using this sound file: http://www.ism.ac.jp/~shiro/research/sounds/RSM/X_rsm2.wav
I'm trying to recreate Andrew Ng's Machine Learning presentation(https://class.coursera.org/ml-005/lecture) from coursera in matlab
What I do is to read a .wav file (16khz, 7 sec, 2 channels)
[x,xfs] = wavread('track.wav')
Now I transpose x
x = x'
Now I proceed to use x on the cocktail party algorithm
[W,s,v] = svd((repmat(sum(x.*x,1),size(x,1),1).*x)*x')
MATLAB returns:
W =
-0.9233 -0.3841
-0.3841 0.9233
s =
265.4832 0
0 13.0768
v =
-0.9233 -0.3841
-0.3841 0.9233
Where is the separated audio?
EDIT: From further research, I found out that W is only the unmixing matrix. Meaning this algo is incomplete if my goal is to get the two output separated sound sources. What do I do with this unmixing matrix?
I believe you want to apply the unmixing matrix W you found through SVD to the mixed signals x. This can be done simply as follows:
sigs = W*x;
Now sigs(1,:) will be one of the separated signals and sigs(2,:) will be the other.
Good luck.
I believe you're running out of memory because you're trying to repmat across the wrong dimension (or possibly your x variable needs to be transposed). Loading x as you have gives you a variable of size:
>> size(x) = [110000, 2]
Of course, if you try to repmat this as you have, you're essentially telling MATLAB to:
repmat(x,110000,1);
If you do the math, you're trying to create a variable of size [12100000000, 2]. That's 12 billion if you can't be bothered counting the zeros. A single double value in MATLAB is 8 bytes in size, so you're trying to create a variable that would use 12100000000*8*2 bytes = ~200 GB. Chances are you don't have this much memory, hence why MATLAB isn't letting you.
Long story short, try transposing x before repmatting it.

How to make an animation from multiple results?

I have some calculation with matrices and have set my loop to run for (let's say) 50 times.
I also assigned a color to each value so I can get a picture in the end of these matrices based on their values.
What I don't know is - how to make an animation from this multiple images I get in each turn.
Is it possible?!
The following code is what I have used previously to produce an .avi file
n = 15;
p = randperm(n);
figure('Color','white');
fcount = 0;
for k = 1:n-1
% produce the plot
[idx,idx] = min(p(k:n));
p(idx+k-1) = p(k);
p(k) = k;
plot(p,'*')
% Make sure plot updates before we capture the contents
pause(0.1)
F(k) = getframe(gcf); %#ok
end
movie2avi(F,'so1.avi','fps',2,'quality',100);
However, there seems to be some issues with the avi codec now for use with Windows XP, for example see this thread.
http://www.mathworks.com/matlabcentral/newsreader/view_thread/271172
I had the same problem; the avi file produced with the default Indeo codec would not run in Windows Media Player. Using a different codec, such as
movie2avi(F,'so1.avi','fps',2,'quality',100,'compression','Cinepak');
solved the problem. You may need to experiment to find a working combination.
Hth, Darren
I'm not sure what you're trying to do. One option is to use the MS-GIF animator, although 50 images is a bit much. See http://en.wikipedia.org/wiki/Microsoft_GIF_Animator for info. Considering the number of images, you might want to create a powerpoint document.

a problem with wavread function

I wrote a program that record my voice write it and then play it
Fs=11025;
y= wavrecord(2*Fs,Fs,'int16');
wavwrite(y,Fs,'t1.wav');
wavplay(y);
I heard my voice clear
then I want to write another program that reads that file and play it
y=wavread('t1.wav');
wavplay(y);
when I run the second program I didn't hear my voice clear
so how can I read the wav file and then play it without a problem?
The wavwrite you used may assume that the incoming y is of range [-1 +1]. Try to normalize y before calling wavwrite
y_float = double(y)/2^15; %% Normalize int16(y) by 2^15
wavwrite(y_float,Fs, 't1.wav');
In the case that something goes wrong with wavplay reading the floating point y_float, you can convert the read-back signal from floating point to int16 again:
y_float_readback = wavread('t1.wav');
y_int16_readback = int16(y_float_readback*2^15);
wavplay(y_int16_readback);
You may compare y_int16_readback with the original y. They should be identical.
This script works absolutely fine for me using the latest version of matlab. I heard clear audio using both your 1st and 2nd code excerpts.
One thing I noticed is that you record y as 'int16' type and then save it to the wav file. When you load the wav file using wavread, y is stored in the matlab workspace as double precision floating point data by default. If you want y to be loaded in the same format in which you saved it try the following.
y=wavread('t1.wav','native');
wavplay(y);