matlab 识别钢琴基频 演奏音乐

就是把钢琴曲换个音调再演奏出来。初衷是用来生成matlab的曲谱的,先写这么多吧。识别正确率好像不是很高,推荐用一些单纯的钢琴曲效果好一些,比如张宇桦的。

换歌曲的话,注释后面带有“***************”的数的值是影响比较大的,需要修改。一个是阈值,一般3~20之间。一个是延时,一般x0.005~x0.1之间。

由于本人不是信息、信号相关专业的,写的不专业,欢迎指正。

参考资料:一种钢琴全频段的基频识别方法_图文_百度文库


%程序:
[f , fs] = audioread('be.mp3');%读取mp3文件
N=3800000;%截取文件长度
n=2000;%窗长
x1=300000;%截取起始位置
lv=6;%端点检测阈值***************************
ham=hamming(n);%汉明窗
data=f(x1:x1+N-1,2);%截取文件中的一段
x=1:N;
figure;
subplot(2,1,1);
plot(x,data);hold on;%绘制原波形
title('原波形');
su=zeros(1,round(N/n));
for i=1:round(N/n)-1
    data1=((data(i*n-(n-1):i*n).*ham).^2);%计算短时能量
    su(i)=sum(data1);
end

 

subplot(2,1,2)
plot(x(1:round(N/n)),su);%绘制短时能量曲线
hold on;title('短时能量');
lin=plot([0 0],[0 100]);
plot([0 round(N/n)-1],[lv lv]);%阈值横线
p=1;

 

for i=2:round(N/n)-1
    if su(i)>lv&&su(i-1)<=lv%如果短时能量曲线为上升且越过阈值,判断为端点
        k=p*n;
        t=(i-p)*0.02;%***************************
        fp=get_fs(data(k+1:k+2000),2000);%频率
        mus(fp,t,max(data(k+1:k+2000)));%声音
        set(lin,'xdata',[p p]);%显示进度
        pause(t+0.08);%暂停等待播放完
        p=i;
    end
end

 

%函数
function g=mus(p,T, nx)%(频率,时长,音量)
t=0:1/44100:T;
soun=2*nx*sin(2*3.14*t*p).*sin(t/T*3.14);
sound(soun,44100);
g=1;
end

%函数
function u=get_fs(A,N)%(采样点的值,采样点数)
fs=44100;   %采样频率
n=0:N-1;
x=A; %信号
y=fft(x.*hamming(N),N);    %乘上汉明窗之后进行快速Fourier变换
mag=abs(y);     %求得Fourier变换后的振幅
f=n*fs/N;    %频率序列
[~,b]=max(mag(1:N/2)); %频谱最大值对应的频率位置
u=f(b);%频谱最大值对应的频率
end

 

你可能感兴趣的:(matlab)