Add echo to audio signal in matlab
Show older comments
Write a function called echo_gen that adds an echo effect to an audio recording. The function is to be called like this: output = echo_gen(input, fs, delay, amp); where input is a column vector with values between -1 and 1 representing a time series of digitized sound data. The input argument fs is the sampling rate. The sampling rate specifies how many samples we have in the data each second. For example, an audio CD uses 44,100 samples per second. The input argument delay represent the delay of the echo in seconds. That is, the echo should start after delay seconds have passed from the start of the audio signal. Finally, amp specifies the amplification of the echo which normally should be a value less than 1, since the echo is typically not as loud as the original signal. The output of the function is a column vector containing the original sound with the echo superimposed. The output vector will be longer than the input vector if the delay is not zero (round to the nearest number of points needed to get the delay, as opposed to floor or ceil). A sound recording has values between -1 and 1, so if the echo causes some values to be outside of this range, you will need to normalize the entire vector, so that all values adhere to this requirement. MATLAB has several sample audio files included that you can try: splat, gong, and handel are a few examples. Try the following: load gong % loads two variables, y and Fs sound(y, Fs) % Outputs sound
2 Comments
KALYAN ACHARJYA
on 24 Mar 2019
Edited: KALYAN ACHARJYA
on 24 Mar 2019
Walter Roberson
on 24 Mar 2019
We have guided you on how to ask questions a few times already :(
Answers (3)
Priyamvada Shankar
on 24 Mar 2019
0 votes
22 Comments
KALYAN ACHARJYA
on 24 Mar 2019
Edited: KALYAN ACHARJYA
on 24 Mar 2019
Please delete this comment from answer section, and mention it in comment section.
Priyamvada Shankar
on 24 Mar 2019
Priyamvada Shankar
on 24 Mar 2019
Walter Roberson
on 24 Mar 2019
Is in a column vector?
Note: your scaling is broken. You are changing output1 as you go, so max(output1) is going to change. You should be recording max(output1) before you do the loop.
Even then, consider: suppose that at some point output1 became 2.0 (original signal was 1.0 and there happened to be a full echo at that point), and suppose some other point became 1.01 . Then you would divide that 1.01 by 2.0 to get 0.505 and you would store that. And if a third point right beside the 1.01 was 0.9999 then that third point would have been left alone because it was not > 1. So your processing would leave 0.9999 followed by 0.505 -- so the value that was over maximum has been reduced to much less than the sample that was not over maximum. Are you sure that makes sense?
Walter Roberson
on 24 Mar 2019
Is in a column vector? Your code assumes that it is. Your code would fail if in is a row vector or if it is a multi-channel signal.
There are two basic approaches to handle overflow in signals:
- You can scale everything by the maximum absolute value so that afterwards the maximum absolute value of the modified signal is 1.0 . So for example if you had a steady series of 1.0 values (not overflowing) and you had a single sample that overflowed to 2.0 (echo reinforced original signal) then you would divide through all of the signal by that 2.0, making the stream of 1.0 values into 0.5 values . Each value afterwards would reflect proportion of maximum. The "shape" of loud signals would stay the same.
- You can "clip" : set all values > 1 to 1.0, all values < -1 to -1.0 . The "shape" of loud signals would alter.
Note by the way, that with echo it is possible for a negative signal value to have a negative echo added to it, making the result even more negative. Therefore it is not enough to check for values > 1: you also need to check values < -1 (this assumes that your input range is -1 to +1)
Priyamvada Shankar
on 26 Mar 2019
Edited: Priyamvada Shankar
on 27 Mar 2019
Priyamvada Shankar
on 27 Mar 2019
Walter Roberson
on 27 Mar 2019
p = max(abs(output1));
Your if would then not be necessary: with you having divided by the maximum absolute value, there would be no way for the result to be greater than 1 or less than -1. You could therefore just go directly to
p = max(abs(output1));
if p > 1
output = output1 ./ p;
else
output = output1;
end
The test here is to have it not rescale if the signal would not overflow.
madhan ravi
on 28 Mar 2019
Please learn to format the code.
Priyamvada Shankar
on 28 Mar 2019
Edited: Walter Roberson
on 28 Mar 2019
Walter Roberson
on 28 Mar 2019
Hint:
signal = zeros(length(in)+ds,1);
signal(1:length(in)) = in;
Priyamvada Shankar
on 29 Mar 2019
Walter Roberson
on 29 Mar 2019
Instead of using [zeros(length(signal)-ds,1);in*gain] like you are now, create another set of zeros the same size as you created for signal, and assign in*gain to the last length(in) of it. Two arrays, both certain to be the same size, can then be added together.
Priyamvada Shankar
on 2 Apr 2019
Walter Roberson
on 2 Apr 2019
function output = echo_gen(in,fs,delay,gain)
samples = round(fs*delay) ;
ds = floor(samples);
signal = zeros(length(in)+ds,1);
signal(1:length(in))=in;
%signal= [in; zeros(length(signal)-ds,1)]; %this line should not have been here
echo_signal =zeros(length(in)+ds,1);
echo_signal(1:length(in*gain))=in; %wrong! You want to assign to the END of echo_signal, not the BEGINNING
%echo_signal= [in; zeros(length(echo_signal)-ds,1)]; %this line should not have been here
output= signal + echo_signal;
p= max(abs(output));
if p>1
output=output ./ p;
else
output = output
end
end
Priyamvada Shankar
on 2 Apr 2019
Walter Roberson
on 2 Apr 2019
You set the echo_signal to all zero and did not store in*gain into the end of it.
Use similar logic to have you store the signal into the beginning of signal, but change the indices so that the last location stored into is the one at the end of echo_signal.
Aditya DEY
on 3 Apr 2019
Can you please correct the code in the exact specified line, where it is going wrong as I am also facing similar problems and repeatedly errors are popped up. I can't understand how to assign the code for the end of echo_signal.
Mukti Awad
on 16 Aug 2019
Can you correct the code I am getting error!!
Assessment: 0 of 2 Tests Passed
Submit More Info
- Assessment result: incorrectA few simple cases
- Variable output has an incorrect value. Tested with the vector [-0.5; 0; 0.5; 0] and the following parameters: fs = 1, delay: 0.0 seconds, amp = 0.5
- Assessment result: incorrectUsing splat sound file
- Variable output has an incorrect value. Tested with the splat file and the following parameters: fs = 8192, delay: 0.2 seconds, amp = 0.2If you get an error stating that your output vector is the wrong size, and the size differs by 1 from the expected value, you're probably very close. Check
- That you are rounding to the nearest number of points required to create the delay
- The echo signal begins after the delay has completed
Walter Roberson
on 16 Aug 2019
Mukti Awad: those messages come from an academic code grading system. You are responsible for writing your own code for assignments. If you present your own code and it is not just a copy of the above code, then someone might be willing to have a look at it.
Washida Kami
on 1 Apr 2020
@Walter Roberson Nobody asked for your help, why do you sound so pissed off in all the comments?
Walter Roberson
on 1 Apr 2020
Washida Kami:
Nobody asked for your help
Priyamvada Shankar and Mukti Awad asked for my help.
why do you sound so pissed off in all the comments?
The first ten thousand times that someone asked me to do their homework for them: they were the worst. The second ten thousand times: they were the worst too. After that, things started to go downhill.
Sarthak Shukrey
on 24 Jul 2019
0 votes
can someone provide with a descriptive answer for the same ? I'm getting same error :(
ABHIJIT BISWAS
on 30 Nov 2020
Edited: ABHIJIT BISWAS
on 30 Nov 2020
%Perfectly working
function echo_sound = echo_gen(input, fs, delay, amp)
new_sr = round(fs*delay);
no_echo = [input; zeros(new_sr,1)];
echo_effect = [zeros(new_sr,1); input*amp];
echo_sound = no_echo + echo_effect;
norm_factor = max(abs(echo_sound));
if norm_factor > 1
echo_sound = echo_sound./norm_factor;
end
1 Comment
Mohamed Gsmal
on 16 Jan 2021
Edited: Mohamed Gsmal
on 16 Jan 2021
echo cancelation??
Categories
Find more on Code Generation and Deployment in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!