Generate echo to an audio

299 次查看(过去 30 天)
pepperlisbon
pepperlisbon 2019-7-13
编辑: DGM 2023-3-18
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 个评论
Omkar Gharat
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

请先登录,再进行评论。

回答(10 个)

dhouimir salem
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
  10 个评论
Sachin Patare
Sachin Patare 2020-9-30
Good coding. Even if you don't use the "abs", the code will work.
Walter Roberson
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
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 个评论
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
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
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
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
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
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
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

昱安 朱
昱安 朱 2023-3-18
编辑:DGM 2023-3-18
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

类别

Help CenterFile Exchange 中查找有关 Multirate Signal Processing 的更多信息

标签

Community Treasure Hunt

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

Start Hunting!

Translated by