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

I have updated to the following:
function output = echo_gen(input, fs, delay, amp);
samples = (fs*delay);
samples_echo = round(samples);
echo = zeros(size(input));
echo(1:samples_echo) = input (1:samples_echo);
for ii = samples + 1:length(input);
echo(ii) = input (ii) + amp*input(ii-samples_echo);
end
output1 = echo
max_output = max(abs(output1));
if max_output > 1;
for i = 1:length (output1);
output1 (i) = output1(i)/max_output;
end
output = output1
else
output = echo
end
Gurpreet Singh
Gurpreet Singh 2020년 6월 20일
well explained, thanks@pepperlisbon
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
Michelle Zheng 2020년 12월 11일
@omkar, wrong problem

댓글을 달려면 로그인하십시오.

답변 (10개)

dhouimir salem
dhouimir salem 2020년 1월 1일
편집: Walter Roberson 2020년 1월 1일

15 개 추천

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

댓글 수: 10

Walter Roberson
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
Arnav Ketkar 2020년 4월 27일
Why is there a need to floor samples here can someone explain please thanks
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
Aritra Das 2020년 5월 10일
Thanks a lot, it really works.
ANKUR SARMAH
ANKUR SARMAH 2020년 5월 28일
Thank you very much. It really helped me.
Tejas Sabu
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
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
anass hmd 2020년 9월 13일
thank you sir
Sachin Patare
Sachin Patare 2020년 9월 30일
Good coding. Even if you don't use the "abs", the code will work.
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
Arafat Roney 2020년 5월 11일
편집: Arafat Roney 2020년 5월 11일

3 개 추천

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
Krashank Kulshrestha 2020년 6월 6일
편집: Krashank Kulshrestha 2020년 6월 6일
hey thanks it works now
Francesco Tortora
Francesco Tortora 2022년 4월 23일
Hello, thanks for the help! Can you explain better the 'SCALLING' code part?
Thanks!
Walter Roberson
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
David Gonzalez 2020년 5월 25일

3 개 추천

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
Nisarg Dalal 2020년 5월 15일

0 개 추천

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
Ajijul Mridol
Ajijul Mridol 2020년 6월 27일

0 개 추천

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
Kazi Hafizur Rahman
Kazi Hafizur Rahman 2020년 8월 19일
편집: Kazi Hafizur Rahman 2020년 8월 19일

0 개 추천

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
Mati Somp 2020년 10월 7일

0 개 추천

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
Kushagra Mehrotra 2021년 2월 23일

0 개 추천

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일

0 개 추천

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
昱安 朱
昱安 朱 2023년 3월 18일
편집: DGM 2023년 3월 18일

0 개 추천

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에 대해 자세히 알아보기

태그

질문:

2019년 7월 13일

편집:

DGM
2023년 3월 18일

Community Treasure Hunt

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

Start Hunting!

Translated by