Generate echo to an audio
이전 댓글 표시
I have to 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.
I got blocked on the following code:
function output = echo_gen(input, fs, delay, amp);
samples_echo = round(fs*delay);
input_sound = zeros(length(input)+fs,1);
input = (input_sound(1:length(input)))';
echo = zeros(length(input)+samples_echo,1);
echo_sound = echo(delay+(1:length(input*amp)));
output = input + echo_sound;
max_output = max(abs(output));
if max_output > 1;
for i = i:length (output);
output2 (i) = output2(i)/max_output;
end
output = output2
else
output = output
end
댓글 수: 4
pepperlisbon
2019년 7월 14일
Gurpreet Singh
2020년 6월 20일
well explained, thanks@pepperlisbon
Omkar Gharat
2020년 8월 18일
function out = blur(img,w)
% convert to double for doing calculations
imgD = double(img);
[row, col] = size(img);
out = zeros(row, col);
for ii = 1:row
for jj = 1:col
% Get the indices for a submatrix
r1 = ii-w;
r2 = ii+w;
c1 = jj-w;
c2 = jj+w;
% Test that indices are valid
% If not, set to min/max that is valid
if r1 < 1
r1 = 1;
end
if r2 > row
r2 = row;
end
if c1 < 1
c1 = 1;
end
if c2 > col
c2 = col;
end
% Get the submatrix and assign the mean to the output pixel
m = imgD(r1:r2, c1:c2);
out(ii,jj) = mean(m(:));
end
end
% convert back to uint8
out = uint8(out);
end
Michelle Zheng
2020년 12월 11일
@omkar, wrong problem
답변 (10개)
dhouimir salem
2020년 1월 1일
편집: Walter Roberson
2020년 1월 1일
valid code :
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;
echo_signal =zeros(length(in)+ds,1);
echo_signal(ds+(1:length(in*gain)))=in*gain;
output= signal + echo_signal;
p= max(abs(output));
if p>1
output=output ./ p;
else
output = output;
end
end
another valid code :
function output = echo_gen(s, Fs, delay, amp)
% Find the time between points using Fs
dt = 1/Fs;
% Calculate the number of points for the given delay
N = round(delay/dt);
% Pad the original signal with zeros to make room for the echo
s1 = [s; zeros(N, 1)];
% Create an echo signal that starts with 0's
s2 = [zeros(N, 1); s.*amp];
% Add the echo to the original signal
output = s1 + s2;
% the abs of all values must be < 1. Rescale if necessary
if max(abs(output)) > 1
output = output./max(abs(output));
end
% Note: This only works with column vectors - can you make the
% function more robust so that it works with column or row vectors?
end
enjoy
linkedin Profile : https://www.linkedin.com/in/salem-dhouimir/
facebook profile : https://www.facebook.com/salem.dhouimir
댓글 수: 10
Walter Roberson
2020년 1월 1일
I had to make guesses about the line breaks in your code in order to format it properly. Please check to be sure that I put the breaks into the proper place.
Arnav Ketkar
2020년 4월 27일
Why is there a need to floor samples here can someone explain please thanks
Walter Roberson
2020년 4월 27일
If you are referring to
samples = round(fs*delay) ;
ds = floor(samples);
Then you would be right that the floor() is not needed: after the round() then samples would already have integer values and that would not be changed by floor() .
samples = round(fs*delay) ;
ds = samples;
would be equivalent.
Aritra Das
2020년 5월 10일
Thanks a lot, it really works.
ANKUR SARMAH
2020년 5월 28일
Thank you very much. It really helped me.
Tejas Sabu
2020년 6월 15일
just wanted to ask that in the 7th line of the 1st code ,
echo_signal(ds+(1:length(in*gain)))=in*gain;
the above line can be written as echo_signal(ds+(1:length(in)))=in*gain; right?
Walter Roberson
2020년 6월 15일
Yes, you could use length(in) instead of length(gain) there in practice.
Because * is algebraic matrix multiplication, there are cases where length(in) is not the same as length(in*gain) . Most of those cases would produce an error before that point. The only case that comes to mind that makes a difference would be if in is 1 x 2, and gain is 2 x 1: in that case in*gain is 1 x 1. But it is not clear what a non-scalar gain would be intended to mean in this case. (I guess if you used a gain that was a square matrix with the same number of rows and columns as the signal has channels, then you could use that matrix to define mixing between channels.)
anass hmd
2020년 9월 13일
thank you sir
Sachin Patare
2020년 9월 30일
Good coding. Even if you don't use the "abs", the code will work.
Walter Roberson
2020년 9월 30일
No, you need the abs(). When you have echo, negative values can reinforce each other just like positive values can reinforce each other.
Remember, the human ear does not directly hear whether a speaker is fully extended or fully pulled back: the human ear perceives the changes.
load handel
sound(-y,Fs)
is going to sound exactly like sound(y,Fs) .
So if the processesing can produce values > 1 that have to be scaled back due to reinforcement, then it follows that if the exact negative of the signal had been given, the values would be < -1 instead. It would therefore be a mistake to only test for > 1 instead of abs() > 1.
Arafat Roney
2020년 5월 11일
편집: Arafat Roney
2020년 5월 11일
function output = echo_gen(input, fs, delay, amp)
ds = round((delay)*fs); %%CALCULATING DELAY SAMPLE NUMBERS
if ds==0 %%THIS APPENDS TO THE INPUT TO EQUAL THE SIZE WITH OUTPUT
append=[]; %%APPENDS EMPTY MATRIX WHILE 'ds' IS ZERO
else
append=zeros(ds,1); %%APPENDS ZERO VECTOR FOR THE DELAY
end
ain = [append;input]; %%APPENDED INPUT
dmwa = amp*ain; %%AMPLIFIED SIGNAL
outd = [input; append]; %%APPENDED OUTPUT
out = (dmwa+outd); %%OUTPUT WITHOUT SCALLING
%%% SCALLING (IF NEEDED)
mx = max(out);
mn = min(out);
if max(abs(out))>1
if(abs(mx)>abs(mn))
output = out/abs(mx);
else
output = out/abs(mn);
end
else
output=out; %%OUTPUT WITH SCALLING(IF NEEDED)
end
end
댓글 수: 3
Krashank Kulshrestha
2020년 6월 6일
편집: Krashank Kulshrestha
2020년 6월 6일
hey thanks it works now
Francesco Tortora
2022년 4월 23일
Hello, thanks for the help! Can you explain better the 'SCALLING' code part?
Thanks!
Walter Roberson
2022년 4월 23일
Suppose that you have a sine wave at full volume and suppose that you have a 2% echo. Then your signal value 1.0 would increase to 1.02 with the echo. But the maximum value that can be recorded is 1.0.
David Gonzalez
2020년 5월 25일
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
Nisarg Dalal
2020년 5월 15일
I wrote the following code, and I am getting errors. Can you help me with it?
function output = echo_gen(input, fs, delay, amp)
[a b] = size(input);
input1 = input*amp;
c = round(fs*delay);
d = length(input1);
x = zeros(a+c,1);
x(1:a) = input;
y = zeros(a+c,1);
y(c:d+c-1) = input1;
output = x+y;
maxi = max(abs(output));
if(maxi > 1)
output = output./maxi;
else
output = output;
end
end
댓글 수: 1
Walter Roberson
2020년 5월 15일
What errors are you observing?
Ajijul Mridol
2020년 6월 27일
function output=echo_gen(input,fs,delay,amp)
%here calculating the delay points after which echo will be added
c=round(delay*fs);
s1=[input;zeros(c,1)];
s2=[zeros(c,1);input.*amp];
output=s1+s2;
if max(abs(output)) > 1
output = output./max(abs(output)); %scaling the invalid values
end
end
end
댓글 수: 1
Omkar Gharat
2020년 8월 18일
your ans have an erroe
Kazi Hafizur Rahman
2020년 8월 19일
편집: Kazi Hafizur Rahman
2020년 8월 19일
this one is a little detailed but works like a charm
function output=echo_gen(input,fs,delay,amp)
N=round(fs*delay);%Number of additional points needed for delay
sz=length(input);
output=zeros(N+sz,1);%if delay is not equal to zero output size will be N greater
for i=1:length(output)
if N<sz%in this case superposition will occur
if i<=N
output(i)=input(i);%first N points will only contain original sound
elseif i<=sz
output(i)=input(i)+amp*input(i-N);%points ranging from N+1 to sz will contain original Sound +amplified sound of a previous time
else
output(i)=amp*input(i-N);%Last N points will only contain amplified data points
end
else
if i<=sz%no superposition in this case
output(i)=input(i);%first sz points will get only original signal data
%points ranging from sz+1 to N will contain nothing
elseif i>N
output(i)=amp*input(i-N);%points after N will contain amplified signal only
end
end
end
maxi=max(abs(output));
if maxi>1
output=output/maxi;%scaling if values fall outside the range [-1,1]
end
end
Mati Somp
2020년 10월 7일
Ok, it works. In my opinion, the round should be the floor, because the echo signal never reaches the last point in real life.
function out = echo_gen(in, fs, del, amp);
if del==0
a=0;
else
a=round(fs*del);
end
z=zeros(a,1);
out=[in;z]+[z;in*amp];
m=max(abs(out))
if m>1
out=out/m;
end
Kushagra Mehrotra
2021년 2월 23일
function output = echo_gen (y,Fs,delay,amp)
additionalsamples = round (Fs*delay);
delay_vector = zeros(additionalsamples,1);
inputD = [y ; delay_vector];
newy = zeros((length(y)+additionalsamples),1);
amplified = y.*amp;
M = size(y);
newy(end-M+1:end) = amplified(1:end);
outF = newy;
out = (outF + inputD);
Max = max(out);
Min = min(out);
if max(abs(out))>1
if(abs(Max)>abs(Min))
output = out/abs(Max);
else
output = out/abs(Min);
end
else
output=out;
end
end
绵辉 翁
2021년 7월 31일
function output = echo_gen(input,fs,delay,amp)
rawecho = zeros(length(input)+round(fs*delay),1);%creat a vector to storge "pure" echo
v = zeros(round(fs*delay),1);
rawoutput = [input;v];%creat a vector to storge the mixtrue of "pure" echo and input
for ii = 1:length(input)
rawecho(round(fs*delay) + ii) = amp*input(ii);
end
v2 = rawecho + rawoutput;%get the mixtrue of "pure" echo and input
if isempty(v2(v2<-1|v2>1))%check whether to scale obtained output
output = v2;
else
v3 = abs(v2);%scale the output maintaining the relative amplitude of the elements
Maxnum = max(v3);
output = v2/Maxnum;
end
function output = echo_gen(input, fs, delay, amp)
%input : signal,fs : sample rate,dalay : time of dalay,amp : amplitude
num_delay=round(fs*delay); %延後幾個開始放
echo0=zeros(num_delay,1);
echo_dalay=input*amp;
echo_final=[echo0;echo_dalay]; %最後echo=echo_dalay前面加上delay的數字
org_input=[input;echo0]; %在原來的聲音加上0,匹配成echo的長度
output=echo_final+org_input; %output=原來的聲音加上回音
if max(abs(output))>1
output=output/max(abs(output)); %讓echo在1~-1
end
카테고리
도움말 센터 및 File Exchange에서 Code Generation and Deployment에 대해 자세히 알아보기
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!