Delay one speaker with imported sound

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)

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

But I dont see any imported sound? so I guess the only dieffernce would be that you exchange Wave = sin(2*pi*1000*x); with wave= wavread(filename), or?
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.
Thanks for the answer!
Seems to work for some wav-files. But some of them gives me this error:
Attempted to access Data(:,2); index out of bounds because size(Data)=[345058,1].
Error in untitled4 (line 7) DataDly(q2,2) = Data(:,2);
any idea?
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.
OK nice, works fine. But if I want to write it to a new wav file do I just exchange soundsc(DataDly, Fs) with wavwrite(DataDly, Fs, 'namn.wav')?
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.
Ok, but if I now want to change the soundlevel with a variable (lets say K) only on the speaker that is not delayed. How do I do that?
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.
You might also want to experiment with sound as well as soundsc since the perform slightly differently in that situation.
I dont understand what each step in this part does:
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);
Can you please make comments in the code and tell me what each line is meant to do?
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.
Erik
Erik on 9 Nov 2012
Edited: Erik on 9 Nov 2012
Thanks for the answer! I have two questions:
-So, what's making the delay? I understand that it is the zeros in DataDly, but how does the zeros create the delay? Is it that the program has to process the zeros on one of the speakers before it "begins with the sound" ?
- Is the columns in DataDly representable for the two different speakers?
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.

Sign in to comment.

I guess it should be something like:
a=wavread('wavfile')
z=%something here that delays z
y=a
w=[y.' z.']
sound(w)
end

Products

Tags

Asked:

on 26 Oct 2012

Community Treasure Hunt

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

Start Hunting!