matlab添加回声代码

matlab添加回声代码,第1张

一、系统设计要求

1.录制一段声音信号,作为原音频信号,生成频域与时域图形,观察与分析其时域 与频域图形。

2.对该音频信号进行时域处理,并且实现对该声音信号添加第一层回声

3.对该音频信号再继续一次进行时域处理,实现对该声音信号添加第二层回声。

4.将三段音频信号进行合成,比较该声音信号与原音频信号时域和频域的差别, 保存合成的音频。

5.对该声音信号进行时域或者频域处理,消除该添加回声的语音信号的回声。

6.比较原始声音信号与去除回声后的声音信号的频域和时域差别,并通过人耳辨 别原音频,加入回声的音频和去除回声的音频三段音频的区别。

二、系统设计方案

第一步:用 getaudiodata()函数录制一段音频生成并观察其时域和频域图形,再对其 时域频域进行处理。

第二步:添加回声。通过补零矩阵增加回声,且分别将原音频分别进行衰减系数为 0.6 倍和 0.4 倍的缩放,而后将三段音频结合在一起,使得得到音频有一层原声,两层 回声,且从原声到回声一层比一层音量小,得到处理后的声音信号就是有回声的声音 信号,绘制并观察有回声的声音信号的频域时域图形。

第三步:通过 z 域分析得到转换公式,对修改后声音信号时域进行处理。将添加的 回声消除,得到消除回声音频,再次绘制并观察新的声音信号的时域频域图形。

第四步:将三个时域频域图形进行对比,并把三段音频分别播放,用人耳进行区分 其差距

三、代码实现

1.录制音频代码:

%%%录制音频

clear all

clc

fs=44100

music=audiorecorder(fs,16,1)

disp('请输入空格并回车开始采集原始信号')

in=input('')

%创建一个保存音频信息的对象,它包含采样率,时间和录制的音频信息等等。

%44100表示采样为44100Hz

%16为用16bits存储,2为两通道即立体声(也可以改为1即单声道)。

recordblocking(music,7)

%开始录制,此时对着麦克风说话即可,录制时间为7秒。

myspeech=getaudiodata(music,'int16')

%得到数字矩阵存储的刚录制的音频信号。

plot(myspeech)

%% save file

filename='myspeech.wav'

audiowrite(filename,myspeech,fs)

登录后复制

2.对录制音频进行采集处理:

%%%%对音频采集处理

clear

[x,fs] = audioread('myspeech.wav')%音乐信号

%输出频率

fs

%音乐语音信号分声道处理

x1=x(:,1)

登录后复制

3.画出录制音频信号时域频域波形图

%画音乐信号时域图

n1=length(x1)%length取音乐数列长度即元素个数

figure(1)

subplot(2,1,1)

t1=(0:(n1-1))/fs

plot(t1,x1)

axis([0,5,-1,1])%%设置坐标轴范围

xlabel('时间t')

ylabel('幅度')

title('原音频音乐信号时域波形')

X1=fft(x1,n1)

subplot(2,1,2)

f3=0:fs/n1:fs*(n1-1)/n1

plot(f3,abs(X1))

axis([0,44100,0,6000])

xlabel('频率f')

ylabel('幅度')

title('原音频音乐信号频谱波形')

登录后复制

4.增加回音(这里我加了两重回音)

% %音乐信号的回音

x11=x1%截取部分

x11=x11'%因为输出为一列所以要转置成一行

geshu=length(x11)

N2 = 20000

int0=zeros(1,N2)%1行20000列的零矩阵

temp1=[x11,int0,int0]%原始声音

temp2=[int0,0.6*x11,int0]%第一层的回声是原始0.6倍

temp3=[int0,int0,0.4*x11]%第二层的回声是原始0.4倍

hui=temp1+temp2+temp3%三重声音相加实现回声

N=length(hui) %回音序列的长度

% sound(hui,fs)%播放回音音乐

登录后复制

5.画出回声波形,并保存回声为音频文件

%%%画回声波形

figure(2)

subplot(2,1,1)

t1=(0:(N-1))/fs

plot(t1,hui)

axis([0,4.5,-1,1])

xlabel('时间')

ylabel('幅度')

title('音频回声信号时域波形')

X2=fft(hui,N)

subplot(2,1,2)

f3=0:fs/N:fs*(N-1)/N

plot(f3,abs(X2))

axis([0,44100,0,6000])

xlabel('频率f')

ylabel('幅度')

title('音频回声信号频谱波形')

audiowrite('音频回声.wav',hui,fs)%保存回声整体为声音文件

登录后复制

6.消除回声

%%消除回声

% N = 20000

chang=N2+geshu

L = length(hui)

y = zeros(1, L)%与回声长度相同的零序列

for k = 1:L

if k>N2 &&k<=chang %%%消除第一层回声

y(k) = hui(k) - 0.6*x11(k-N2)

else

y(k) = hui(k)

end

if k>2*N2 %%%消除第二层回声

y(k)=y(k)-0.4*x11(k-2*N2)

end

end

N3 = length(y)

audiowrite('消除回声.wav',y,fs)%%保存为消除回声音频文件

登录后复制

四、展望

本项目在日后的学习中,应对其进行用户体验感以及完善其功能的更新,设计 GUI 界面使得整个系统 *** 作更加便捷,采用多线程的方式进行编程,增加整个系统能够完 成的功能,后续将更新出既能导入本身存在的音频,又可以重新录制音频进行增加回 声,消除回声以及绘制相关音频信号的时域频域波形图的功能,同时可以设定相关的 回声信号衰减系数,自定义的完成回声信号的添加使用,并将这些功能在 GUI 界面上 体现出来,使得用户体验感更好, *** 作更加便捷,将项目发挥的更好。

clear all

close all

%channel system order

sysorder = 5

% Number of system points

N=2000

inp = randn(N,1)

n = randn(N,1)

[b,a] = butter(2,0.25)

Gz = tf(b,a,-1)

%This function is submitted to make inverse Z-transform (Matlab central file exchange)

%The first sysorder weight value

%h=ldiv(b,a,sysorder)'

% if you use ldiv this will give h :filter weights to be

h= [0.0976

0.2873

0.3360

0.2210

0.0964]

y = lsim(Gz,inp)

%add some noise

n = n * std(y)/(10*std(n))

d = y + n

totallength=size(d,1)

%Take 60 points for training

N=60

%begin of algorithm

w = zeros ( sysorder , 1 )

for n = sysorder : N

u = inp(n:-1:n-sysorder+1)

y(n)= w' * u

e(n) = d(n) - y(n)

% Start with big mu for speeding the convergence then slow down to reach the correct weights

if n <20

mu=0.32

else

mu=0.15

end

w = w + mu * u * e(n)

end

%check of results

for n = N+1 : totallength

u = inp(n:-1:n-sysorder+1)

y(n) = w' * u

e(n) = d(n) - y(n)

end

hold on

plot(d)

plot(y,'r')

title('System output')

xlabel('Samples')

ylabel('True and estimated output')

figure

semilogy((abs(e)))

title('Error curve')

xlabel('Samples')

ylabel('Error value')

figure

plot(h, 'k+')

hold on

plot(w, 'r*')

legend('Actual weights','Estimated weights')

title('Comparison of the actual weights and the estimated weights')

axis([0 6 0.05 0.35])

% RLS 算法

randn('seed', 0)

rand('seed', 0)

NoOfData = 8000 % Set no of data points used for training

Order = 32 % Set the adaptive filter order

Lambda = 0.98 % Set the forgetting factor

Delta = 0.001 % R initialized to Delta*I

x = randn(NoOfData, 1) % Input assumed to be white

h = rand(Order, 1) % System picked randomly

d = filter(h, 1, x) % Generate output (desired signal)

% Initialize RLS

P = Delta * eye ( Order, Order )

w = zeros ( Order, 1 )

% RLS Adaptation

for n = Order : NoOfData

u = x(n:-1:n-Order+1)

pi_ = u' * P

k = Lambda + pi_ * u

K = pi_'/k

e(n) = d(n) - w' * u

w = w + K * e(n)

PPrime = K * pi_

P = ( P - PPrime ) / Lambda

w_err(n) = norm(h - w)

end

% Plot results

figure

plot(20*log10(abs(e)))

title('Learning Curve')

xlabel('Iteration Number')

ylabel('Output Estimation Error in dB')

figure

semilogy(w_err)

title('Weight Estimation Error')

xlabel('Iteration Number')

ylabel('Weight Error in dB')

%我们使用QQ语音聊天的时候,如果不带耳机,而使用喇叭。那么麦克风会收到两个信号:第一个人声,第二个,从喇叭传出的声音(回声)。本程序用语消除回声。

%首先使长时间的FIR滤波器产生回声。(产生房间的冲击响应)

M = 4001

fs = 8000

[B,A] = cheby2(4,20,[0.1 0.7])

Hd = dfilt.df2t([zeros(1,6) B],A)

hFVT = fvtool(Hd) % Analyze the filter

set(hFVT, 'Color', [1 1 1])

H = filter(Hd,log(0.99*rand(1,M)+0.01).*sign(randn(1,M)).*exp(-0.002*(1:M)))

H = H/norm(H)*4 % Room Impulse Response

plot(0:1/fs:0.5,H)

xlabel('Time [sec]')

ylabel('Amplitude')

title('Room Impulse Response')

set(gcf, 'Color', [1 1 1])

%然后读取matlab里面自带的人声,并且播放(不必紧张,这不是英语听力)

load nearspeech

n = 1:length(v)

t = n/fs

plot(t,v)

axis([0 33.5 -1 1])

xlabel('Time [sec]')

ylabel('Amplitude')

title('Near-End Speech Signal')

set(gcf, 'Color', [1 1 1])

p8 = audioplayer(v,fs)

playblocking(p8)

The Far-End Speech Signal

%现在播放回声:就是从喇叭发出,房间反d,最后被麦克风接收到的声音。这把声音是通过我们上面设计的FIR滤波器产生的

load farspeech

x = x(1:length(x))

dhat = filter(H,1,x)

plot(t,dhat)

axis([0 33.5 -1 1])

xlabel('Time [sec]')

ylabel('Amplitude')

title('Far-End Echoed Speech Signal')

set(gcf, 'Color', [1 1 1])

p8 = audioplayer(dhat,fs)

playblocking(p8)

%人声和回声加在一起,麦克风接收到的实际声音是:

d = dhat + v+0.001*randn(length(v),1)

plot(t,d)

axis([0 33.5 -1 1])

xlabel('Time [sec]')

ylabel('Amplitude')

title('Microphone Signal')

set(gcf, 'Color', [1 1 1])

p8 = audioplayer(d,fs)

playblocking(p8)

%使用频域自适应滤波器去除回声

mu = 0.025

W0 = zeros(1,2048)

del = 0.01

lam = 0.98

x = x(1:length(W0)*floor(length(x)/length(W0)))

d = d(1:length(W0)*floor(length(d)/length(W0)))

% Construct the Frequency-Domain Adaptive Filter

hFDAF = adaptfilt.fdaf(2048,mu,1,del,lam)

[y,e] = filter(hFDAF,x,d)

n = 1:length(e)

t = n/fs

pos = get(gcf,'Position')

set(gcf,'Position',[pos(1), pos(2)-100,pos(3),(pos(4)+85)])

subplot(3,1,1)

plot(t,v(n),'g')

axis([0 33.5 -1 1])

ylabel('Amplitude')

title('Near-End Speech Signal')

subplot(3,1,2)

plot(t,d(n),'b')

axis([0 33.5 -1 1])

ylabel('Amplitude')

title('Microphone Signal')

subplot(3,1,3)

plot(t,e(n),'r')

axis([0 33.5 -1 1])

xlabel('Time [sec]')

ylabel('Amplitude')

title('Output of Acoustic Echo Canceller')

set(gcf, 'Color', [1 1 1])

p8 = audioplayer(e/max(abs(e)),fs)

playblocking(p8)

%凳凳凳凳,大功告成

%回声的产生方法很多,还有一种镜像法,模拟声音在一个六面体房间内墙面的每次反d。澳洲某个大学的哥们的个人主页上有程序,有兴趣可以找找。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/11540867.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-16
下一篇 2023-05-16

发表评论

登录后才能评论

评论列表(0条)

保存