⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 endpoint_subfunc.m

📁 再matlab下面实现音乐信号的端点检测。 算法是利用帧长
💻 M
字号:
%函数说明:检测各音符端点的子函数
%输入变量:x 信号;Winsiz 帧长度 Shift 帧移
%输出变量:pitch_end_1 一帧的起始端点 ;pitch_end_2 一帧的终止端点
%输出变量:k pitch_end_1 and pitch_end_2 的下标  dw 不是很明白
 
function [pitch_end_1,pitch_end_2,k]=endpoint_subfunc(x,Winsiz,Shift) 

%N=512;
%Winsiz=512;  %帧长
%Shift=256;   %帧移                dw 为什么要加入帧移?
average_n=5;  %求门限所需的帧数
a=1.5;
b=0.5  %b为更新门限时前一门限的权值,1-b为当前average_n帧信号平均能量的权值
k=1;   %用于保存端点位置的数组pitch_end_1及pitch_end_2的下标的更新
%[x,Fs]=wavread('caidiao.wav');
x=double(x);                                           % 转换为双精度 dw?
%对信号做预加重处理
x=filter([1 -0.9375], 1, x);

%figure(2)
%subplot(211);
%plot(x);  %信号的原始波形图
title('原始波形图');

nseg=floor((length(x)-Winsiz)/Shift)+1;   %信号总共的帧数   why compute?
E=zeros(1,nseg);  %存放短时能量的数组E的初始化

%下面循环是求x信号的短时能量
for i=1:nseg
    for j=1:Winsiz
        E(i)=E(i)+x((i-1)*Shift+j)^2;
    end   
end
figure(2)
%subplot(212)
plot(E(1:nseg));   %信号的短时能量图
title('端点检测图');

%pitch_end_1=zeros(1,nseg);
%pitch_end_2=zeros(1,nseg);

%求初始门限值
sum_threshold=0;
for i=1:average_n
    sum_threshold=sum_threshold+E(i);
end    
threshold=sum_threshold/average_n*100;   %此处a取1.2  取平均    见语音端点检测的仿真
%threshold=sum_threshold/average_n*10;  

%求第一个音符
i=average_n;
while i<nseg  
    
    if E(i)>=threshold  
      if i+10<=nseg %看后面还存在一个音符的判断条件没,要成为一个音符,至少要还得有10帧数据
        j=0;        % 用j来判断后面是否连续5帧都大于门限值
        for  m=i+1:i+5
            if E(m)<threshold
                j=j+1;
            end
        end   
        if j==0    %说明后面连续5帧都大于门限,i为真正的音符其始
             pitch_end_1(k)=i;  %保存起始时刻,并寻找结束位置
             for i=(m+1):nseg             %继续寻找音符结束位置
                 if E(i)<threshold       %拟结束位置
                       
                        if i+5<nseg      %先判段后面还有5帧没有
                            j=0;                     % 用j来判断后面是否连续5帧都小于门限值
                            for m=i+1:i+5
                              if E(m)>=threshold
                                   j=j+1;
                              end
                            end  
                            if j==0     %后面连续5帧都小于门限,i为真正的音符结束
                                 pitch_end_2(k)=i;      %保存音符结束位置
                                 k=k+1;
                                 sum_threshold=0;  %更新门限 
                                 if m+average_n+1<nseg
                                    for i=m+1:m+1+average_n
                                       sum_threshold=sum_threshold+E(i);
                                    end  
                                 threshold=b*threshold+(1-b)*sum_threshold/average_n*a;   %此处a取1.2
                                 i=i+1;
                                 break;
                                 end
                            
                            end   
                           
                         end
                  end
            
            end
        else                              %不是真正的音符其始
            i=i+1;
        end 
     else
         i=i+1;
     end
     
   else 
       i=i+1;
   end   
    
end

hold on;
%subplot(212);
for i=1:k-1
    p=[pitch_end_1(i) pitch_end_1(i)];
    q=[pitch_end_2(i) pitch_end_2(i)];
    t=[0 max(E)];
    plot(p,t,'r');    %标出开始端点位置
    plot(q,t,'r');    %标出结束端点位置
end   
hold off;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -