Delay one speaker with imported sound
Show older comments
Hi
I want to import a .wav file into matlab and remake it so that one speaker is delayed. So for example I want to import a already existing music track (or something) and want to delay the right speaker with, let's say, 10ms. How do I do that?
/Erik
Answers (2)
Star Strider
on 26 Oct 2012
I suggest something like this:
x = linspace(0, 2, 2*8192);
Wave = sin(2*pi*1000*x);
Data = [Wave; Wave]';
Fs = 8192;
dly = ceil(10E-3 * Fs); % 10ms delay
DataDly = zeros(size(Data,1)+dly, 2);
q1 = dly:size(Data,1)+dly-1;
q2 = 1:size(Data,1);
DataDly(q1,1) = Data(:,1);
DataDly(q2,2) = Data(:,2);
soundsc(DataDly, 8192)
The 10ms delay sounds like a sort of click echo with this code, but it does what you want it to do. A longer delay is more noticable.
12 Comments
Erik
on 27 Oct 2012
Star Strider
on 27 Oct 2012
Edited: Star Strider
on 27 Oct 2012
My Data array substitutes in this code for your imported sound. I got the impression that you had already done that and were looking for a way to generate the delay.
The results of wavread should give you the sampling frequency Fs and everything else you need:
[Data, Fs, NBits, Opts] = wavread('YourAudioFile.wav');
Remember to delete (or comment out) the:
Fs = 8192;
line. The soundsc call then becomes:
soundsc(DataDly, Fs)
You simply have to substitute your data for my Data array (as an [N x 2] array), use the Fs returned by wavread your imported sound, and the rest should work the way you want it to. If you want to switch the delay in the channels, switch the q1 and q2 assignments in the DataDly array.
I tried this code with a voice file I have available. It works as it should.
The complete updated code (including wavread) is now:
[Data, Fs, NBits, Opts] = wavread('YourAudioFlie.wav');
dly = ceil(10E-3 * Fs); % 10ms delay
DataDly = zeros(size(Data,1)+dly, 2);
q1 = dly:size(Data,1)+dly-1;
q2 = 1:size(Data,1);
DataDly(q1,1) = Data(:,1);
DataDly(q2,2) = Data(:,2);
soundsc(DataDly, Fs)
Please let me know if you have any further problems with it.
Erik
on 27 Oct 2012
Star Strider
on 27 Oct 2012
Edited: Star Strider
on 27 Oct 2012
My pleasure!
Some .wav files may only contain one channel. I suggest that right after your wavread call, you insert:
if size(Data,2) < 2
Data = [Data Data];
end
This assumes that Data is a column vector. (If it isn't, you will have to check and transpose it.) Data is then an [N x 2] array and should work with the rest of the code.
Erik
on 27 Oct 2012
Star Strider
on 27 Oct 2012
That seems correct to me. You could also use audiowrite (with appropriate changes to the argument list) if you also wanted to include other information in the file.
Erik
on 27 Oct 2012
Star Strider
on 27 Oct 2012
Multiply it by K:
q1 = dly:size(Data,1)+dly-1;
q2 = 1:size(Data,1); % Delayed channel
K = 0.5;
DataDly(q1,1) = Data(:,1) * K;
DataDly(q2,2) = Data(:,2);
Here I attenuated it by K = 0.5. I suggest not increasing it beyond 1, since that could clip and distort the sound.
Erik
on 9 Nov 2012
Star Strider
on 9 Nov 2012
Edited: Star Strider
on 9 Nov 2012
I'll be glad to explain it as well as I can. The basic idea in this statement:
DataDly = zeros(size(Data,1)+dly, 2);
is to create a [(N+dly) x 2] matrix of zeros that is the length of the sound plus the length of the delay. This is necessary because both channels have to have the same number of elements. The first DataDly assignment (the first line in my code segment you posted) does that.
The q1 variable then creates an index for the delayed channel. It starts at whatever the value of dly is and goes to the end of the vector. (The values before the value of dly are set to zero.)
The q2 variable does the same thing for the non-delayed channel. (It simply starts at the beginning and goes through the length of the sound vector, so the zeros are at the end of that vector.)
The second DataDly statement:
DataDly(q1,1) = Data(:,1);
assigns the sound vector to the part of the DataDly matrix that corresponds to the q1 vector. (The delayed channel.)
The third DataDly statement:
DataDly(q2,2) = Data(:,2);
assigns the sound vector to the part of the DataDly matrix that corresponds to the q2 vector. (The non-delayed channel.)
I wrote the code as I did to allow you to vary the amount of the delay (the dly variable) and easily change the channel you want to delay. (Switch q1 and q2 in the last two DataDly statements to do that.)
In the end, with Data being the original [N x 2] sound matrix (two channels with identical data), the DataDly matrix, with dimensions [(N+dly) x 2] would look something like this:
DataDly(:,1) = [0; 0; 0; 0; 0; 0; 0; 0; 0; 0; Data(:,1)]
DataDly(:,2) = [Data(:,2); 0; 0; 0; 0; 0; 0; 0; 0; 0; 0]
The semicolons between the vector elements are because DataDly has (N+dly) rows and 2 columns, and Data is a [N x 2] matrix. The number of zeros in each would be the value of the dly variable.
Star Strider
on 9 Nov 2012
My pleasure!
You're correct that the zeros create the delay. They ‘pad’ the vectors so that when MATLAB begins to play the sound, it encounters zeros in the delayed channel (a zero-amplitude signal), then starts playing the sound when it gets that far. It's not a matter of ‘processing’ the zero values in the sound or soundsc function, but simply playing the sound vectors that it is given. Near the end, the non-delayed channel is then silent (playing a zero-amplitude signal) for the length of dly, while the delayed channel is still playing.
Yes. I believe column 1 of DataDly is the left channel, and column 2 is the right channel.
Categories
Find more on Audio and Video Data in Help Center and File Exchange
Products
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!