数字信号处理报告 - 图文

更新时间:2023-11-08 08:18:01 阅读量: 教育文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

《数字信号处理B》课程项目

题 目:组 号:任课教师:实施报告

数字音效处理器 40

2013 年10 月 18 日

1

报告提纲

一.课程项目要求

设计要求:

设计一个数字音效处理器,能够实现语音信号的各种音效处理。要求: (1) 输入语音信号源为实际环境采集语音; (2) 至少实现3种音效处理功能;

(3) 用人机交互界面操控、扬声器/耳机输出音效。 二.设计思路 采集

一段信号

保存音 频文件

不同音效

语音处理

处理 后播放

三.实现音效处理的成果

1.回音增强2.娃娃音3.老人音4.男变女5.高频去噪6.音频加密解密7.音量调节8.节奏变化.9.播放暂停功能。

四.具体处理过程及代码实现 1、信号采集

通过matlab编程使用wavrecord函数驱动电脑自带的声卡设备采集一段语音信号,其调用格式为mysound=wavrecord(n,fs,channel,dataType);其中n为采样点数,fs为采样频率,channel(通常取1或者2)为录音通道数,dataType(例如double,single,int16,uint8)是采样点的数据类型。 然后通过wavwrite函数保存在当前matlab指定的工作路径下,以此信号作为信号处理的信号源。为了将其控制方便,我们将其使用global函数定义为全局变量。在后面的处理就可以对这个信号进行不同的效果处理了。具体在gui里面这样设计再点击新建按钮后会弹出一对话框,如图1所示:

2

图1

输入好录制时间长度(例如20s)和要保存音频的文件名(sound),点击OK按钮后就开始录音,直到窗口消失,就表示录音结束,生成的***.wav(sound.wav)文件就被保存在matlab当前的工作路径下。实现这个窗口的函数是inputdlg

具体代码是:

prompt={'请输入录制语音时间长度','新建保存的文件名(文件存储在工作路径下)'}; name='点击OK后已经开始录音'; 表示窗口的显示名称 numlines=1;

options.Resize='on';

defaultanswer={'20','sound'}; 默认值为20和sound options.WindowStyle='normal'; options.Interpreter='tex';

answer=inputdlg(prompt,name,numlines,defaultanswer,options);

从输入到对话框中的字符串读取录音时间长短和保存的文件名。代码为:

s=str2double(answer{1}); %anwer{1}为要录音的时间长短 tex=answer{2}; %answer{2}为要保存的文件名称 mysound=wavrecord(s*8000,9000,1);

wavwrite(mysound,4000,tex); %保存文件名称为输入的字符串

global FileName; %将文件名定义成全局变量,供后边处理 FileName=tex;

至此就可以实现语音信号的采集。为了处理已经存在我们电脑里的信号,我们还设置了打开电脑里的wav文件。通过点击打开按钮,调用其callback里面的程序代码:

clear all; clc;

[b,PathName] = uigetfile('*.wav','Select the Wav-file'); [a,fs,nbits]=wavread(b); 将声音文件读取到a序列中 sound(a,8000,nbits); global FileName;

FileName=b; %将打开的文件定义成全局变量和新建的文件一样执行处理过程。

从而可以打开电脑里已经录制好的音频文件。其中打开文件界面如图2

3

图2 2、音效处理过程 1) 音量调节过程

通过计算机录取的语音是一段向量,给其乘以一个系数就可以改变其幅值,通过改变系数的大小就可以实现音量的增大或衰减。为了实现更利与控制这个系数,我们使用了sider滑动条来控制这个系数的大小。同样定义成全局变量,使得后边的处理效果都能实现音量的控制。使用slider时要先配置slider的属性,在属性窗口中改变其value的最大值和最小值,然后保存。通过拖动滑动条使其处于不同的位置,就会返回一个数值,我们使用这个变量就能实现实时控制。其中slider的callback代码为:

value=get(handles.slider3,'value');global cd;%读取value值赋值给value c=round(value);cd=c/20;

set(handles.edit1,'string',num2str(c)); %将其实时显示到edit text中

通过sound函数可以控制音频的输出的幅度的大小。通过变sound函数里的第一个变量的值可以实现音量的加强与衰减。 2) 播放速度的调节过程

播放速度我们是通过改变sound函数里的Fs参数实现的,sound函数会将信号y以频率Fs发送至speaker(扬声器)。如果不对频率定义的话,默认的频率

4

就是8192HZ.对于单声道来说,y值是一个m行-1列的向量,其中m表示的是采样点数。当频率fs增大时,采样点数增多,对同一段相同长度的时间抽取的点数增多,相邻两点之间的时间间隔变小,从而使播放的速度增大,反之当fs减小时,播放速度减缓。具体的fs减小的值为了便于控制,我们同样是使用slider来改变。在slider的callback函数下添加以下代码:

global v;

v=get(handles.slider4,'value');

set(handles.edit3,'string',num2str(v));

然后在“播放”按钮下添加以下代码:

global FileName;global cd;global v; [a,fs,nbits]=wavread(FileName);a=a*cd %sound(a*cd,8000,nbits); global p;

p=audioplayer(a,8000*v); play(p);

axes(handles.axes1);plot(a,'b');title('原音信号波形');hold on; axes(handles.axes3); z=fft(a);

plot(abs(z),'m');title('原音信号频谱波形');hold on;

通过这代码就可以通过拖动滑动条的位置,改变播放的音量和播放速度。并实时的在edittext显示当前的播放速度和声音放大或衰减的倍数。其中实现实时显示的代码是放在edittext下的代码:

global v;

v=get(handles.slider4,'value'); 从slider获取中获取当前value值

set(handles.edit3,'string',num2str(v));将这个值以字符形式显示在text中 其效果图:

3) 娃娃音实现

通过不断的尝试改变fs的值,我们发现,将fs设置成15000hz就可以实现此功能,但是发现一缺点就是在改变了fs的值后,不仅变调还变速,当将其设置成15000是正好实现这个功能。其原理就是,对于一段给定的序列,对其播放的时

5

通过比较可以发现倒放后的时域波形发生了明显的变化,序列发生倒转,而且频域波形没有变化,主要是期间没有涉及到频率给变,所以在频域频谱分布是不会发生变化的。 8) 音频解密

global FileName

[x,fs,nbits]=wavread(FileName); n=length(x); t=(0:n-1)/8000;

d=[0.05*cos(2*pi*3800*t)]';x=x+d;e=fft(x);

sound(x);axes(handles.axes4);plot(x,'g');title('处理后时域波形'); axes(handles.axes5);plot(abs(e));title('处理后频域波形')

9) 加进噪声

相对上述的音频加密,还原上述的音频声音信号。只要将其再通过一次倒放,既序列的逆序排列就好。代码为:

global FileName;

[x,fs,nbits]=wavread(FileName); y=x(end:-1:1);global cd; sound(y*cd,8000,nbits); clear reset; 处理后波形:

10)去除噪音

通过设计一个低通的滤波器,将包含在信号源里的高频成分滤除,从而使音

11

效更加接近原声。人一般的声音的最高频率不超过2khz,我们设计的滤波器的截止频率是2100hz.通带增益为100,阻带衰减为0。所以一般的声音通过这个低通滤波器就可以滤掉录音时的高频成分,使得声音纯正!实现代码是:

global FileName

[x,fs,nbits]=wavread(FileName); x2=x

fs=20000;

fedge=[2000 2400];%通带截止频率和阻带起始频率? mval=[100 0];%通带幅度为1阻带幅度为0?

dev=[0.0599 0.00316];%通带衰减0.5dB,阻带衰减大于等于50dB。

[N,fpts,mag,wt]=remezord(fedge,mval,dev,fs);%计算低通滤波器的技术指标。?

b=remez(N,fpts,mag,wt); [h,w]=freqz(b,1,512); clear reset;

figure(1);%plot(w,abs(h));grid on;axis tight;

plot(w/pi,20*log10(abs(h)));axis tight;title('低通滤波器频率响应'); xlabel('频率/Hz');ylabel('幅度/db');

lb=filter(b,1,x2);%对带有噪声的音频信号进行滤波? c=fft(lb);

sound(lb);axes(handles.axes4);plot(lb,'g');title('处理后时域波形');axis tight

axes(handles.axes5);plot(abs(c));title('处理后频域波形');axis tight

其中滤波器的幅频幅性为:

滤波前后语音信号的波形变化为:

12

3.人机交互界面

使用matlab里面的gui编写程序,实现人机交互的设计。在matlab命令窗口中键入guide指令,打开gui设计界面,设置好所需要的控件后,在matlab里面便自动生成一个fig文件和一个m文件。通过访问fig文件便可打开人机交互界面。通过组员的设计和最终的努力,我们的界面有以下三个:

(1)登陆界面:

13

通过输入随机的验证码可以进入到我们组的音效处理程序。调高安全性。具体代码为:

global a;

a=randi([1000 9999]); 获得随机的四位的验证码 R=get(handles.edit1,'string');global b; 从edit1中获取一个字符串赋值给R。并定义成全局变量

b=str2double(R); 转换成字符串

if b==a; 条件判断 如果输入的字符串和验证码一样,则执行下面的代码 h=gcf;

Yuyin; 运行yuyin.m文件 clear b;

close(h); 退出欢迎界面 end

(2)音效处理界面:

(3)【关于我们】界面

14

以上这些界面背景都是组员通过photoshop自己做出来的效果,以上这些就是团队合作的成果,也是我们组员奋战七周的结果。

4.小结:

总体上来说,做完这次课外实验,感觉收获了好多,从一开始学习MATLAB软件,再进行程序的编写,直到MATLAB的调试与测试,都是我们小组成员独立完成,虽然一开始有些不懂,但是经过问老师,请教学霸,上网百度。到后来我们都一一解决掉了,问题摆在那儿,如果不去解决掉的话,问题始终存在,有问题就要及时解决问题,这是我们最大的收获。还有就是我们小组的团结与分工明确,这是确保我们小组顺利完成这次课程实验的最根本的条件,很个人去查一种或多种音效处理的matlab实现方法和原理,最后进行整合。最终我们每个人都做到了,当然,最后要实现的功能都实现了,在设计音效处理和人机交互界面的时候,也被各种小问题绊倒,其中一些小问题差点成为我们的致命伤,通过完成本次项目后,使大家都记得,细节决定成败。比如说我们的在设计slider的时候碰到的问题,不管我们怎么处理在gui界面里面都智能只能显示一个slider,第二个slider怎么都显示不出来,后来才发现按照matlab的使用习惯,必须将slider的属性值中的min值赋值为0,否则就不能使用第二个滑动条。

我们具体实现的音效处理功能有,回音增强,娃娃音,老人音,男变女,高频去噪,音频加密解密,音量调节,节奏变化,播放暂停功能。从最初的音量改变,最后我们想到了设计密码对语音信号进行加密的设计方案。虽说加密和解密

15

不难,但也是我们组员的智慧。加密即是利用倒放的方法使得我们所听到的语音不能为我们理解,达到加密的手段。解密就是对语音信号再次倒放。

数字信号处理的设计项目与之前所做的其他课程的项目也有一定差异,不仅其内容是我们以前很少接触过的对于多媒体信号的处理,而且实验给出的要求非常简单基本。却要实现比较智能的功能,着实对我们是一种挑战。具体的设计方案、布局操作和结果调试都必须由我们亲自拟定并实施。一开始拿到题目时完全没有头绪,无从下手,但通过在网上耐心地查找资料,细心研究MATLAB软件,以及与小组成员的讨论,逐步理清思路,有了初步的方案,之后经由向老师请教,才有了比较成熟完善的设计方案。做实验就像完成一件艺术品,只要有所投入,那最后的成品一定能证明我们的努力。

5.组员分工:

【1】高 阳:对matlab进行深入学习,查阅有关老人音,娃娃音,低通滤波,人机界面的设计。对代码的整合。

【2】董敏:查阅有关回音增强的音效处理方法。

【3】刘晨潇:最后终期报告的撰写,查阅有关音量的调整方法。 【4】张佳吟:查阅倒放的音效处理,撰写报告。 【5】杜宝林:查阅了有关男声变女声的音效处理方法。

6.使用工具:Matlab2012a.7.0

Photoshop cs.5.0

7.参考书籍

【1】数字信号处理——原理与实践(第二版) 方勇 主编。清华大学出版社 【2】Matlab界面设计与编译技巧 李显宏 编著。电子工业出版社 【3】Matlab基础与应用教程 王月明 张宝华 主编。北京大学出版社 【4】信号与系统(第二版) 郑君里 主编 高等教育出版社

16

8.程序源代码

function varargout = Yuyin(varargin) gui_Singleton = 1;

I=imread('语音处理背景.jpg');

gui_State = struct('gui_Name',

hi = imagesc(I);

mfilename, ...

varargout{1} = handles.output;

'gui_Singleton',

eventdata, handles) ha = axes('units','normalized','position',[0 0 1 1]);

uistack(ha,'bottom');

gui_Singleton, ...

'gui_OpeningFcn',

@Yuyin_OpeningFcn, ...

'gui_OutputFcn',

@Yuyin_OutputFcn, ...

'gui_LayoutFcn',

[] , ...

'gui_Callback',

[]);

if nargin && ischar(varargin{1})

gui_State.gui_Callback =

str2func(varargin{1});

end

if nargout

[varargout{1:nargout}] =

gui_mainfcn(gui_State,

varargin{:});

else

gui_mainfcn(gui_State,

varargin{:});

end

function

Yuyin_OpeningFcn(hObject,

eventdata, handles, varargin)

d=importdata('播放.jpg');

set(handles.bofang,'CDATA',d);

c=importdata('ccc.jpg');

set(handles.stop,'CDATA',c);

handles.output = hObject;

guidata(hObject, handles);

function varargout =

Yuyin_OutputFcn(hObject,

function

xinjian_Callback(hObject,

eventdata, handles)

clc;

clear all;

prompt={'请输入录制语音时间长度','

新建保存的文件名(文件存储在工作路径

下)'};

name='点击OK后已经开始录音';

numlines=1;

options.Resize='on';

defaultanswer={'20','sound'};

options.WindowStyle='normal';

options.Interpreter='tex';

answer=inputdlg(prompt,name,num

lines,defaultanswer,options);

s=str2double(answer{1});

tex=answer{2};

mysound=wavrecord(s*8000,9000,1

);

steps=s;

hwait=waitbar(0,'请等

待>>>>>>>>');

step=steps/100;

for k=1:steps

if steps-k<=5

waitbar(k/steps,hwait,'

即将完成');

pause(0.05);

else

PerStr=fix(k/step);

str=['正在运行中

',num2str(PerStr),'%'];

17

waitbar(k/steps,hwait,str); pause(0.05); end end

close(hwait);

wavwrite(mysound,4000,tex); global FileName; FileName=tex; function

bofang_Callback(hObject, eventdata, handles) global FileName;global cd;globalv;

[a,fs,nbits]=wavread(FileName);a=a*cd global p;

p=audioplayer(a,8000*v); play(p);

axes(handles.axes1);plot(a,'b');title('原音信号波形');hold on;axis tight;

axes(handles.axes3); z=fft(a);

plot(abs(z),'m');title('原音信号频谱波形');hold on;axis tight; function

huiyingzengqiang_Callback(hObject, eventdata, handles) global FileName; a=FileName;

[x,fs,nbits]=wavread(a);

m=size(x);a=m(1,1);b=m(1,2); z=[zeros(2000,b);x];%声音延时 x1=[x;zeros(2000,b)];%使原声音长度与延时后相等 y1=x1+0.1*z;

y2=[zeros(2000,b);y1]; y3=[y1;zeros(2000,b)]; y4=y3+y2;clear reset;

axes(handles.axes4);plot(y1,'g');title('处理后时域波形');axis tight

axes(handles.axes5); c=fft(y4);

plot(abs(c),'g');title('处理后频域波形');axis tight;global cd; sound(cd*y4,8000,nbits);

function

wawayin_Callback(hObject, eventdata, handles) clear reset; global FileName

[x,fs,nbits]=wavread(FileName);global cd;

sound(x*cd,15000);clear reset; axes(handles.axes4);plot(10*x,'g');title('处理后时域波形');axis tight

axes(handles.axes5);y=fft(10*x);plot(abs(y));title('处理后频域波形');axis tight function

tuichu_Callback(hObject, eventdata, handles) clear all; close;

function dakai_Callback(hObject, eventdata, handles) clear all; clc;

[b,PathName] = uigetfile('*.wav','Select the Wav-file');

[a,fs,nbits]=wavread(b); global FileName; FileName=b; function

laorenyin_Callback(hObject, eventdata, handles) global FileName

[x,fs,nbits]=wavread(FileName);global cd;

sound(x*cd,6000,nbits);clear reset;

axes(handles.axes4);plot(0.6*x,'g');title('处理后时域波形');axis

18

tight

axes(handles.axes5);y=fft(0.6*x);plot(abs(y));title('处理后频域波形');axis tight function

daofang_Callback(hObject, eventdata, handles) global FileName

[x,fs,nbits]=wavread(FileName); y=x(end:-1:1);global cd; sound(cd*y,8000,nbits);

prompt={'保存加密后音频:'}; name='保存save'; numlines=1;

defaultanswer={'important'}; options.Resize='on';

options.WindowStyle='normal'; options.Interpreter='tex';

answer=inputdlg(prompt,name,numlines,defaultanswer,options); Q=answer{1};

wavwrite(y,8000,Q); clear reset;

axes(handles.axes4);plot(y,'g');title('处理后时域波形');axis tight;

axes(handles.axes5);z=fft(y);plot(abs(z));title('处理后频域波形');axis tight;

function

yinpinjiemi_Callback(hObject, eventdata, handles) global FileName;

[x,fs,nbits]=wavread(FileName); y=x(end:-1:1);global cd; sound(y*cd,8000,nbits); clear reset;

axes(handles.axes4);plot(y,'g');title('处理后时域波形');axis tight;

axes(handles.axes5);z=fft(y);plot(abs(z));title('处理后频域波形');axis tight;

function

slider3_Callback(hObject, eventdata, handles)

value=get(handles.slider3,'value');global cd;

c=round(value);cd=c/20;

set(handles.edit1,'string',num2str(c)); function

slider3_CreateFcn(hObject, eventdata, handles)

if

isequal(get(hObject,'BackgroundColor'),

get(0,'defaultUicontrolBackgroundColor'))

set(hObject,'BackgroundColor',[.9 .9 .9]); end

function edit1_Callback(hObject, eventdata, handles) function

edit1_CreateFcn(hObject, eventdata, handles) if ispc && isequal(get(hObject,'BackgroundColor'),

get(0,'defaultUicontrolBackgroundColor'))

set(hObject,'BackgroundColor','white'); end

function about_Callback(hObject, eventdata, handles) h=gcf; about;

19

function stop_Callback(hObject, eventdata, handles) global p pause(p); clear reset;

function edit2_Callback(hObject, P = 10; % 预测系数个数

FN = floor(L/FL)-2; % 计算帧长 % 预测和重建滤波器

exc = zeros(L,1); % 激励信号 zi_pre = zeros(P,1); % 预测滤波器的状态

s_rec = zeros(L,1); % 重建语音 eventdata, handles) function

edit2_CreateFcn(hObject, eventdata, handles)

if ispc && isequal(get(hObject,'BackgroundColor'),

get(0,'defaultUicontrolBackgroundColor'))

set(hObject,'BackgroundColor','white'); end

function

shijangenxin_Callback(hObject, eventdata, handles) h = clock;

datetime=strcat(num2str(h(:,4)),':',num2str(h(:,5)),':',num2str(round(h(:,6))));

set(handles.edit2,'string',datetime); function

boy2girl_Callback(hObject, eventdata, handles) global FileName; [s,fs,nbits] = wavread(FileName); % 载入语音s

s = s/max(s); %归一化

L = length(s); % 读入语音长度 S=fft(s,L);

FL =80; % 帧长 WL = 240; % 窗长

zi_rec = zeros(P,1); % 变调不变速滤波器

exc_syn_t = zeros(L,1); % 合成的激励信号 s_syn_t = zeros(L,1); % 合成语音

last_syn_t = 0; %存储上一个(或多个)段的最后一个脉冲的下标

zi_syn_t = zeros(P,1); % 合成滤波器的状态

hw = hamming(WL); % 汉明窗 % 依次处理每帧语音

for n = 3:FN % 计算预测系数 s_w = s(n*FL-WL+1:n*FL).*hw; %汉明窗加权后的语音 [A E] = lpc(s_w, P); %用线性预测法计算P个预测系数

% A是预测系数,E会被用来计算合成激励的能量

if n == 27 end s_f = s((n-1)*FL+1:n*FL); % 本帧语音,下面就要对它做处理

% (4) 用filter函数s_f计算激励,注意保持滤波器状态 [exc1,zi_pre] = filter(A,1,s_f,zi_pre);

exc((n-1)*FL+1:n*FL) = exc1; %计算得到的激励

% (5) 用filter函数和exc重建语音,注意保持滤波器状态 [s_rec1,zi_rec] = filter(1,A,exc1,zi_rec);

20

本文来源:https://www.bwwdw.com/article/7832.html

Top