电子科技大学数字信号处理DSP课程设计-钢琴音符识别

上传人:y****3 文档编号:12934689 上传时间:2020-06-03 格式:DOC 页数:14 大小:479KB
返回 下载 相关 举报
电子科技大学数字信号处理DSP课程设计-钢琴音符识别_第1页
第1页 / 共14页
电子科技大学数字信号处理DSP课程设计-钢琴音符识别_第2页
第2页 / 共14页
电子科技大学数字信号处理DSP课程设计-钢琴音符识别_第3页
第3页 / 共14页
点击查看更多>>
资源描述
.2014级数字信号处理课程设计报告题目:钢琴音符识别姓名:邱晨曦学号:2014010909008答辩时间:2016/12/9一. 题目要求:(1) 播放和记录一段钢琴音乐中的音符;(2) 记录到音符以后,找到音符所对应的现代标准钢琴的钢琴键,并分析结果。二. 课程设计思路:(1) 涉及到的知识点:快速傅里叶变换、钢琴音频信号的时域和频域的特性、能熵比的概念、频率校正、频率与音符的转换关系。(2) 方案分析:A. 预处理部分:1. 直接用audioread函数读出来的原始数据。优点:准确率较高;缺点:数据量较大,采样频率为44kHz,远大于奈奎斯特采样率。2. 以11kHz的采样率重新采样,并转换为单声道。优点:数据量小了很多,易于处理;缺点:牺牲了部分的准确率,但对于音符的判断影响可以忽略。 B. 端点检测算法: . 双门限法:1. 计算短时能量(高门限)和过零率(低门限);2. 选取一个较高的门限,语音信号的能量包络大部分都在此门限之上,进行一次初判,语音起止点位于该门限与短时能量包络交点所对应的时间间隔之外;3. 根据噪声能量,确定一个较低的门限,并从初判起点往左,从初判终点往右搜索,分别找到能零比曲线第一次与门限相交的两个点,两点之间段就是用双门限方法所判定的语音段;4. 以短时平均过零率为准,从低门限点往左右搜索,找到短时平均过零率低于某阈值的两点,为语音的起止点; 图1:双门限法示意图说明:算法中的阀值是根据实验过程调节的。该算法在实际应用的过程中发现:在语音信号频率分布较为集中的时候,端点检测出来的结果比较准确,但当语音信号频率分布比较分散的时候,很难通过控制固定的阀值来检测到每个音符;. 自相关法:由于两种信号的自相关函数存在极大的差异,可以利用这种差别来提取语音端点。根据噪声的情况,设置两个阈值和,当相关函数最大值大于时,便判定是语音;当相关函数最大值大于或小于时,则判定为语音信号的端点。 该算法同样存在当语音信号频率分布较广的时候,阀值比较难控制的问题。. 基于谱熵的端点检测:基于谱熵语音端点检测方法是通过检测谱的平坦程度,来进行语音端点检测的,为了更好进行语音端点检测,采用语音信号的短时功率谱构造语音信息谱熵,从而对语音段和噪声段进行区分。检测思路: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 (即shift right,数值可自行调节)帧作为一段信号的起始点,将低谷点左移sl(即shift left,数值可自行调节)帧作为截止点注:采用该方法的优点是通过调节相关参数能适应多种情况,缺点是检测环境发生较大变化时,需要重新设置参数;7. 将找到的语音段转换成未分帧时对应坐标的语音段,并对每段做快速傅里叶变换;8. 找到每段快速傅里叶变换中的最大值以及最大值所对应的横坐标(fft点),将横坐标转换成相应的频率,得到的频率即为该段音符的频率;9. 利用比值法进行频率的校正,窗函数选择矩形窗;10. 根据检测到的频率确定音符,计算公式为:,为第几个按键,再通过查表得到对应音符;11. 分析结果。三. 具体设计过程: (1) 部分代码(测试部分缺省):主函数部分:x,fs=audioread(钢琴音频.WAV); format short;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); % 检测频率的结果for i=1:length(real_f) real_f(i)=roundn(real_f(i),-4);end for i=1:length(real_f) real_node(i)=get_node(real_f(i)end%*绘图部分*subplot 211;stem(real_f);title(频率检测结果);xlabel(音符/个);ylabel(频率/Hz);subplot 212;stem(real_node,r);title(音符检测结果);xlabel(音符/个);ylabel(对应按键);figure(2);subplot 211;plot(Ef);title(能熵比图及语音起止点);xlabel(帧数/个);ylabel(能熵比);for i=1:length(voicesegment) text(voicesegment(i).begin,Ef(voicesegment(i).begin),o,color,g) text(voicesegment(i).end,Ef(voicesegment(i).end),o,color,r)end subplot 212, plot(time,x,k); title(语音信号端点检测结果)axis(0 max(time) -1 1); ylabel(幅值);for k=1 : vos % 标出有话段 nx1=voicesegment(k).begin; nx2=voicesegment(k).end; nxl=voicesegment(k).duration; fprintf(%4d %4d %4d %4dn,k,nx1,nx2,nxl); subplot 212 line(frameTime(nx1) frameTime(nx1),-1 1,color,r,linestyle,-); line(frameTime(nx2) frameTime(nx2),-1 1,color,r,linestyle,-);end 其中的用到的子函数:1.calsample.m (调整采样率和声道)function sample = 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;endend2. Enframe.m (分帧函数)function f=Enframe(len,inc,x) %对读入的语音进行分帧,len为帧长, %inc为帧重叠样点数,x为输入语音数据fh=fix(size(x,1)-len)/inc)+1); %计算帧数 f=zeros(fh,len); %设置一个零矩阵,行为帧数,列为帧长i=1; n=1;while i=fh %帧间循环 j=1; while j=len %帧内循环 f(i,j)=x(n); j=j+1; n=n+1; end n=n-len+inc; %下一帧开始位置 i=i+1;end3. frame2time.m(坐标刻度转换)function frameTime=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)if size(y,2)=fn, y=y; end % 把y转换为每列数据表示一帧语音信号wlen=size(y,1); % 取得帧长for i=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); % 求谱熵值endhindex=find(H=miniL % 剔除持续帧长度小于miniL的音符段 j=j+1; 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; %音符持续帧数 endendvos=length(voicesegment); %返回音符个数end5.get_max.m(找到高峰点)function max_x,max=get_max(x)l=length(x); %获得数组的长度max=;max_x=;j=1;for i=20:l-15 %找到“峰值点” if (x(i)x(i-1)&(x(i)x(i-2)&(x(i)x(i-3)&(x(i)x(i-4)&(x(i)x(i-5). &(x(i)x(i-6)&(x(i)x(i-7)&(x(i)x(i-8)&(x(i)x(i-9)&(x(i)x(i-10). &(x(i)x(i-11)&(x(i)x(i-12)&(x(i)x(i-13)&(x(i)x(i-14). &(x(i)x(i-15)&(x(i)x(i-16)&(x(i)x(i-17). &(x(i)x(i+1)&(x(i)x(i+2)&(x(i)x(i+3)&(x(i)x(i+4)&(x(i)x(i+5). &(x(i)x(i+6)&(x(i)x(i+7)&(x(i)x(i+8)&(x(i)x(i+9)&(x(i)x(i+10). &(x(i)x(i+11)&(x(i)x(i+11)&(x(i)x(i+12)&(x(i)x(i+13)&(x(i)x(i+14). &(x(i)x(i+15)&(x(i)x(i+16). &(x(i)0.1) max_x(j)=i; %找到后赋值给返回参数 max(j)=x(i); i=i+1; j=j+1; else i=i+1; end endend6.get_min.m(找到低谷点)function min_x,min=get_min(x)l=length(x); %获得数组的长度min=;min_x=;j=1;for i=100:l-10 %寻找低谷点 if (x(i)x(i-1)&(x(i)x(i-2)&(x(i)x(i-3)&(x(i)x(i-4)&(x(i)x(i-5). &(x(i)x(i-6)&(x(i)x(i-7)&(x(i)x(i-8)&(x(i)x(i-9)&(x(i)x(i-10). &(x(i)x(i-11)&(x(i)x(i-12)&(x(i)x(i-13)&(x(i)x(i-14). &(x(i)x(i-15)&(x(i)x(i-16)&(x(i)x(i-17)&(x(i)x(i-18)&(x(i)x(i-19). &(x(i)x(i-20)&(x(i)x(i-21)&(x(i)x(i-22)&(x(i)x(i-23)&(x(i)x(i-24). &(x(i)x(i-25)&(x(i)x(i-26)&(x(i)x(i-27)&(x(i)x(i-28)&(x(i)x(i-29). &(x(i)x(i-30)&(x(i)x(i-31)&(x(i)x(i-32)&(x(i)x(i-33)&(x(i)x(i-34). &(x(i)x(i+1)&(x(i)x(i+2)&(x(i)x(i+3)&(x(i)x(i+4)&(x(i)x(i+5). &(x(i)x(i+6)&(x(i)x(i+7)&(x(i)x(i+8)&(x(i)x(i+9)&(x(i)nx1nx,mx=size(x);if mx=1, x=x;end %转换成行矩阵nx,mx=size(x);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,不满足则为0df=indsecL.*A(index-1)./(Amax+A(index-1)-(1-indsecL).*A(index+1)./(Amax+A(index+1);Z=(index-1-df)*ddf; %修正后的频率end9.get_node.m(确定音符)function node=get_node(f)node=12*log2(f/440)+49;node=round(node); %四舍五入确定对应按键end (2) 生成的图与数据等端点检测结果序号起始帧截止帧持续帧数140975821121665531812355542503035453183725563874415574565105585255795595946485510663714521172978658128018545413869923551493899356151008105144161066112257171137117640181191126777191282133756201352139140211406147570221490151324231528158861241603166664251681173050261760180849271823187351281903194442291959201759302032209059312105213632322177222549332240227839342317234024352380242950对数据的分析:真实按键真实音符真实频率/Hz检测频率/Hz对应按键检测音符绝对误差/Hz相对误差52G7/A7523.251524.897352G7/A71.64630.31%53G7554.365555.043753G70.67870.12%54F7/G7587.33589.876854F7/G72.54680.43%55F7622.254623.158555F70.90450.15%56E7659.255659.707956E70.45290.07%57D7/E7698.456699.296857D7/E70.84080.12%58D7739.989741.850358D71.86130.25%59C7/D7783.991785.948559C7/D71.95750.25%60C7Double high C830.609832.41460C7Double high C1.8050.22%61B6880883.230361B63.23030.37%62A6/B6932.328933.856562A6/B61.52850.16%63A6987.767989.996463A62.22940.23%64G6/A61046.51047.0164G6/A60.510.05%65G61108.731112.724465G63.99440.36%66F6/G61174.661177.113766F6/G62.45370.21%67F61244.511248.123867F63.61380.29%68E61318.511322.60968E64.0990.31%69D6/E61396.911403.008469D6/E66.09840.44%70D61479.981486.316270D66.33620.43%71C6/D61567.981571.964871C6/D63.98480.25%72C6Soprano C(High C)1661.221669.996272C6Soprano C(High C)8.77620.53%73B517601773.53273B513.5320.77%74A5/B51864.661881.010274A5/B516.35020.88%75A51975.531988.001775A512.47170.63%76G5/A520932112.865576G5/A519.86550.95%77G52217.462241.036877G523.57681.06%78F5/G52349.322377.19978F5/G527.8791.19%79F52489.022512.489379F523.46930.94%80E52637.022515.490179F5121.52994.61%81D5/E52793.832824.290781D5/E530.46071.09%82D52959.962994.138782D534.17871.15%83C5/D53135.963192.242783C5/D556.28271.79%84C5Tenor C3322.443364.735584C5Tenor C42.29551.27%85A735203575.952485A755.95241.59%86A7/B73729.313771.658286A7/B742.34821.14%红色标记出检测错误的音符。上表为检测结果的统计及误差统计。大部分误差都小于1%,平均误差为0.82%,误差较小.音符检测发生一个错误,正确了为97.14%,很好地完成了任务。四. 总结: (1) 收获(2) 小组分工情况 小组就邱晨曦一个人,邱晨曦负责全部工作。参考文献:谢明,丁康:离散频谱的一种新校正方法,重庆,载重庆大学学报:1995年3月 第8卷第2期 4754.
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 临时分类 > 职业技能


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!