电子科技大学数字信号处理DSP课程设计钢琴音符识别Word文档格式.docx

上传人:b****7 文档编号:22413235 上传时间:2023-02-04 格式:DOCX 页数:21 大小:334.78KB
下载 相关 举报
电子科技大学数字信号处理DSP课程设计钢琴音符识别Word文档格式.docx_第1页
第1页 / 共21页
电子科技大学数字信号处理DSP课程设计钢琴音符识别Word文档格式.docx_第2页
第2页 / 共21页
电子科技大学数字信号处理DSP课程设计钢琴音符识别Word文档格式.docx_第3页
第3页 / 共21页
电子科技大学数字信号处理DSP课程设计钢琴音符识别Word文档格式.docx_第4页
第4页 / 共21页
电子科技大学数字信号处理DSP课程设计钢琴音符识别Word文档格式.docx_第5页
第5页 / 共21页
点击查看更多>>
下载资源
资源描述

电子科技大学数字信号处理DSP课程设计钢琴音符识别Word文档格式.docx

《电子科技大学数字信号处理DSP课程设计钢琴音符识别Word文档格式.docx》由会员分享,可在线阅读,更多相关《电子科技大学数字信号处理DSP课程设计钢琴音符识别Word文档格式.docx(21页珍藏版)》请在冰豆网上搜索。

电子科技大学数字信号处理DSP课程设计钢琴音符识别Word文档格式.docx

1.对语音信号进行分帧加窗;

2.计算每一帧的谱能量;

3.计算出每一帧中每个样本点的概率密度函数

4.计算出每一帧的谱熵值

(由信息论知识知道,熵值在自变量服从均匀分布的时候,熵值达到最大值,所以噪声的熵值是比较大的,而钢琴音符的熵值是比较小的,由此区别了噪声和音符);

5.设置判决门限;

6.根据各帧的谱熵值进行端点检测。

在实验过程中发现:

依然存在当语音信号频率分布较广时,阀值不太好控制的问题。

因此对该方法进行改进,引入,能熵比的概念:

谱熵值类似于过零率,能熵比的表示为

由于噪声和信号的能熵比差别很大。

因此在能熵比的图像中,每一个“尖刺”就代表了一个特定频率的语言信号。

图2:

能熵比图中的“尖刺”

在检测过程中,依然不能通过简单的设置阀值的办法来进行端点检测,原因是语音频率分布较广时,每个音符的能熵比变化围差别较大,如下图所示,有的“尖刺”完全在门限之上,而有的则完全在门限之下。

图3:

88阶全音的能熵比图

因此,采用检测能熵比中的“低谷点”(该点比左右两边的一定数目的点的能熵比都小)的方法。

语音信号一定位于两个低谷点之间的部分,再对低谷点进行适当的左右移动作为语音信号的起止点。

如下图所示:

图4:

标记起止点的能熵比图

(绿色为起始点,红色为截止点)

(3)设计框架和流程:

1.用audioread函数读入钢琴音乐,并用sound函数播放;

2.为了方便处理,对信号以11.025kHz的频率进行重新采样,并统一转换成单声道的信号;

3.因为语言信号可以在短时间认为是平稳的,因此对语音信号进行分帧的处理,设置帧长320,为了减小误差,两帧之间设置重叠部分,因此帧移取80;

4.计算每一帧的能熵比;

5.找到能熵比中的“低谷点”(该点比左右两边的一定数目的点的能熵比都小);

6.如果两个低谷点之间的距离大于miniL(认为持续长度超过一定长度的为音符,最小长度miniL可自行设置)。

则低谷点右移sr(即shiftright,数值可自行调节)帧作为一段信号的起始点,将低谷点左移sl(即shiftleft,数值可自行调节)帧作为截止点[注:

采用该方法的优点是通过调节相关参数能适应多种情况,缺点是检测环境发生较大变化时,需要重新设置参数];

7.将找到的语音段转换成未分帧时对应坐标的语音段,并对每段做快速傅里叶变换;

8.找到每段快速傅里叶变换中的最大值以及最大值所对应的横坐标(fft点),将横坐标转换成相应的频率,得到的频率即为该段音符的频率;

9.利用比值法进行频率的校正,窗函数选择矩形窗;

10.根据检测到的频率确定音符,计算公式为:

为第几个按键,再通过查表得到对应音符;

11.分析结果。

三.具体设计过程:

(1)部分代码(测试部分缺省):

主函数部分:

[x,fs]=audioread('

钢琴音频.WAV'

);

formatshort;

wlen=320;

inc=80;

%分帧的帧长和帧移

overlap=wlen-inc;

%帧之间的重叠部分

sound(x,fs);

%播放音乐

x=calsample(x,fs);

%为了方便处理,重新以11025Hz的频率采样,并转换成单声道

x=x-mean(x);

%消去直流分量

x=x/max(abs(x));

%幅值归一化

y=Enframe(wlen,inc,x)'

;

%分帧

fn=size(y,2);

%取得帧数

time=(0:

length(x)-1)/11025;

%计算时间坐标

frameTime=frame2time(fn,wlen,inc,11025);

%计算各帧对应的时间坐标

sr=2;

sl=13;

miniL=33;

%配置左右移动的帧数和要求的最短帧数

[voicesegment,vos,Ef]=get_segment(y,fn,sr,sl,miniL);

%获得语音段

[real_f,ft,ax]=get_f(x,voicesegment,vos,wlen,inc);

%检测频率的结果

fori=1:

length(real_f)

real_f(i)=roundn(real_f(i),-4);

end

real_node(i)=get_node(real_f(i))

end

%**********************************绘图部分********************************

subplot211;

stem(real_f);

title('

频率检测结果'

xlabel('

音符/个'

ylabel('

频率/Hz'

subplot212;

stem(real_node,'

r'

音符检测结果'

对应按键'

figure

(2);

plot(Ef);

能熵比图及语音起止点'

帧数/个'

能熵比'

length(voicesegment)

text(voicesegment(i).begin,Ef(voicesegment(i).begin),'

o'

'

color'

g'

text(voicesegment(i).end,Ef(voicesegment(i).end),'

subplot212,plot(time,x,'

k'

title('

语音信号端点检测结果'

axis([0max(time)-11]);

ylabel('

幅值'

fork=1:

vos%标出有话段

nx1=voicesegment(k).begin;

nx2=voicesegment(k).end;

nxl=voicesegment(k).duration;

fprintf('

%4d%4d%4d%4d\n'

k,nx1,nx2,nxl);

subplot212

line([frameTime(nx1)frameTime(nx1)],[-11],'

linestyle'

-'

line([frameTime(nx2)frameTime(nx2)],[-11],'

--'

其中的用到的子函数:

1.calsample.m(调整采样率和声道)

functionsample=calsample(sampledata,FS)

temp_sample=resample(sampledata,1,FS/11025);

%调整采样频率

[~,n]=size(temp_sample);

if(n==2)%转换成单声道

sample=temp_sample(:

1);

else

sample=temp_sample;

2.Enframe.m(分帧函数)

functionf=Enframe(len,inc,x)%对读入的语音进行分帧,len为帧长,

%inc为帧重叠样点数,x为输入语音数据

fh=fix(((size(x,1)-len)/inc)+1);

%计算帧数

f=zeros(fh,len);

%设置一个零矩阵,行为帧数,列为帧长

i=1;

n=1;

whilei<

=fh%帧间循环

j=1;

whilej<

=len%帧循环

f(i,j)=x(n);

j=j+1;

n=n+1;

end

n=n-len+inc;

%下一帧开始位置

i=i+1;

3.frame2time.m(坐标刻度转换)

functionframeTime=frame2time(frameNum,framelen,inc,fs)

frameTime=(((1:

frameNum)-1)*inc+framelen/2)/fs;

%求对应的时间坐标

4.get_segment.m(端点检测,确定音符段)

function[voicesegment,vos,Ef]=get_segment(y,fn,sr,sl,miniL)

ifsize(y,2)~=fn,y=y'

end%把y转换为每列数据表示一帧语音信号

wlen=size(y,1);

%取得帧长

fn

Sp=abs(fft(y(:

i)));

%FFT取幅值

Sp=Sp(1:

wlen/2+1);

%只取正频率部分

Esum(i)=sum(Sp.*Sp);

%计算能量值

prob=Sp/(sum(Sp));

%计算概率

H(i)=-sum(prob.*log(prob+eps));

%求谱熵值

hindex=find(H<

0.1);

H(hindex)=max(H);

Ef=sqrt(1+abs(Esum./H));

%计算能熵比

Ef=Ef/max(Ef);

%归一化

[x1,y1]=get_max(Ef);

%找到能熵比中的“高峰点”

[x2,y2]=get_min(Ef);

%找到能熵比中的“低估点”

voicesegment

(1).begin=x1

(1)-8;

%由于仅仅靠低谷点无法检测出第一个音符起始位置,因此将高峰点的第一个值左移8帧作为第一个音符的起始点

voicesegment

(1).end=x2

(1)-sl;

%将第一个低谷点作为第一个音符的截止点

voicesegment

(1).duration=voicesegment

(1).end-voicesegment

(1).begin+1;

%一个音符的持续帧数

j=1;

fork=2:

length(x2)%将找到的低谷点作为音符的起止点

ifx2(k)-x2(k-1)>

=miniL%剔除持续帧长度小于miniL的音符段

temp1=x2(k-1)+sr;

%将低谷点右移sr个帧,作为一个音符的起始点

voicesegment(j).begin=temp1;

temp2=x2(k)-sl;

%将低谷点左移sl个帧,作为一个音符的截止点

voicesegment(j).end=temp2;

voicesegment(j).duration=voicesegment(j).end-voicesegment(j).begin+1;

%音符持续帧数

vos=length(voicesegment);

%返回音符个数

5.get_max.m(找到高峰点)

function[max_x,max]=get_max(x)

l=length(x);

%获得数组的长度

max=[];

max_x=[];

fori=20:

l-15%找到“峰值点”

if(x(i)>

x(i-1))&

&

(x(i)>

x(i-2))&

x(i-3))&

x(i-4))&

x(i-5))...

&

x(i-6))&

x(i-7))&

x(i-8))&

x(i-9))&

x(i-10))...

x(i-11))&

x(i-12))&

x(i-13))&

x(i-14))...

x(i-15))&

x(i-16))&

x(i-17))...

x(i+1))&

x(i+2))&

x(i+3))&

x(i+4))&

x(i+5))...

x(i+6))&

x(i+7))&

x(i+8))&

x(i+9))&

x(i+10))...

x(i+11))&

x(i+12))&

x(i+13))&

x(i+14))...

x(i+15))&

x(i+16))...

0.1)

max_x(j)=i;

%找到后赋值给返回参数

max(j)=x(i);

else

6.get_min.m(找到低谷点)

function[min_x,min]=get_min(x)

min=[];

min_x=[];

fori=100:

l-10%寻找低谷点

if(x(i)<

(x(i)<

x(i-17))&

x(i-18))&

x(i-19))...

x(i-20))&

x(i-21))&

x(i-22))&

x(i-23))&

x(i-24))...

x(i-25))&

x(i-26))&

x(i-27))&

x(i-28))&

x(i-29))...

x(i-30))&

x(i-31))&

x(i-32))&

x(i-33))&

x(i-34))......

min_x(j)=i;

%找到后赋值给返回值

min(j)=x(i);

7.get_f.m(确定频率)

function[real_f,ft,ax]=get_f(x,voicesegment,vos,wlen,inc)

vos%横坐标转化,将起止点坐标的单位由帧转换成点

ax(i).begin=(voicesegment(i).begin-1)*inc+1;

ax(i).end=(voicesegment(i).end-1)*inc+wlen;

ax(i).duration=ax(i).end-ax(i).begin+1;

temp=x(ax(i).begin:

ax(i).end);

%获得语音段

ft{i}=fft(temp);

%做快速傅里叶变换,并将结果保存在元胞矩阵中

ft{i}=abs(ft{i});

%将得到的fft去模值

[fm(i),fm_x(i)]=max(ft{i});

%找到每个语音段对应的fft中的最大值及最大值对应的横坐标

real_f1(i)=fm_x(i)*11025./ax(i).duration;

%进行频率转换,将横坐标乘以分辨率得到真实频率

real_f(i)=Specorrm(x(ax(i).begin:

ax(i).end),11025,ax(i).duration,real_f1(i)-10,real_f1(i)+10);

%利用比值法进行频率修正,窗函数选择矩形窗

8.Specorrm.m(频率校正)

functionZ=Specorrm(x,fs,N,nx1,nx2)

%x是被测信号,fs是采样频率N为FFT的长度,nx1和nx2被测信号频率的区间,nx2>

nx1

[nx,mx]=size(x);

ifmx==1,x=x'

end%转换成行矩阵

M=fix(N/2)+mod(N,2);

xf=fft(x);

%xf=xf(1:

M)*2/N;

ddf=fs/N;

%频率分辨率

n1=fix(nx1/ddf);

%将频率转换成fft对应的点

n2=round(nx2/ddf);

A=abs(xf);

%取fft的模值

[Amax,index]=max(A(n1:

n2));

%找到fft点n1到n2之间幅值的最大值

index=index+n1-1;

%移动到n1和n2中间

%比值法

%加矩形窗

indsecL=A(index-1)>

A(index+1);

%满足条件则为1,不满足则为0

df=indsecL.*A(index-1)./(Amax+A(index-1))-(1-indsecL).*A(index+1)./(Amax+A(index+1));

Z=(index-1-df)*ddf;

%修正后的频率

9.get_node.m(确定音符)

functionnode=get_node(f)

node=12*log2(f/440)+49;

node=round(node);

%四舍五入确定对应按键

(2)生成的图与数据等

端点检测结果

序号

起始帧

截止帧

持续帧数

1

40

97

58

2

112

166

55

3

181

235

4

250

303

54

5

318

372

6

387

441

7

456

510

8

525

579

9

594

648

10

663

714

52

11

729

786

12

801

854

13

869

923

14

938

993

56

15

1008

1051

44

16

1066

1122

57

17

1137

1176

18

1191

1267

77

19

1282

1337

20

1352

1391

21

1406

1475

70

22

1490

1513

24

23

1528

1588

61

1603

1666

64

25

1681

1730

50

26

1760

1808

49

27

1823

1873

51

28

1903

1944

42

29

1959

2017

59

30

2032

2090

31

2105

2136

32

2177

2225

33

2240

2278

39

34

2317

2340

35

2380

2429

 

对数据的分析:

真实按键

真实音符

真实频率/Hz

检测频率/Hz

对应按键

检测音符

绝对误差/Hz

相对误差

G♯7/A♭7

523.251

524.8973

1.6463

0.31%

53

G7

554.365

555.0437

0.6787

0.12%

F♯7/G♭7

587.33

589.8768

2.5468

0.43%

F7

622.254

623.1585

0.9045

0.15%

E7

659.255

659.7079

0.4529

0.07%

D♯7/E♭7

698.456

699.2968

0.8408

D7

739.989

741.8503

1.8613

0.

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 初中教育 > 英语

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1