倒谱法基音周期检测、共振峰检测代码matlab
时间: 2023-09-02 11:07:31 浏览: 513
基于自相关和倒谱法的基音检测改进算法.pdf
倒谱法是一种常用的基音周期检测方法,可以借助MATLAB实现。下面提供一个简单的基音周期检测和共振峰检测的MATLAB代码示例,供参考。
```matlab
% 基音周期检测和共振峰检测
% 首先读取音频文件,使用matlab自带的audioread函数
[x, fs] = audioread('voice.wav');
% 设置分析参数
winlen = 512; % 窗口长度
overlap = 256; % 帧重叠长度
nfft = 1024; % FFT点数
preemph = 0.97; % 预加重系数
minf0 = 80; % 最小基频
maxf0 = 300; % 最大基频
voicedthresh = 0.4; % 有声门限
unvoicedthresh = 0.1; % 无声门限
% 对每一帧进行处理
frames = enframe(x, winlen, overlap); % 分帧
nframes = size(frames, 1); % 帧数
f0 = zeros(nframes, 1); % 存储基频
formants = zeros(nframes, 4); % 存储共振峰
for i = 1:nframes
frame = frames(i, :); % 取出一帧
frame = filter([1 -preemph], 1, frame); % 预加重
spec = abs(fft(frame, nfft)); % 傅里叶变换
spec = spec(1:nfft/2); % 取一半
logspec = log(spec); % 取对数
cepstrum = ifft(logspec); % 倒谱
cepstrum = cepstrum(1:nfft/2); % 取一半
cepstrum(1:minf0/fs*nfft) = 0; % 去掉基频以下的分量
cepstrum(maxf0/fs*nfft:end) = 0; % 去掉基频以上的分量
[~, locs] = findpeaks(cepstrum); % 找峰值
if ~isempty(locs)
f0(i) = fs/locs(1); % 基频为第一个峰的频率倒数
formants(i, :) = locs(2:5)*fs/nfft; % 共振峰为2~5个峰的频率
end
end
% 判断有声无声
voiced = f0 > voicedthresh*fs/winlen & f0 < maxf0;
unvoiced = f0 < unvoicedthresh*fs/winlen;
f0(unvoiced) = 0; % 无声部分基频设为0
% 绘制频谱、倒谱、基频、共振峰等
t = (0:nframes-1)*overlap/fs;
f = (0:nfft/2-1)/nfft*fs;
figure;
subplot(2, 2, 1);
imagesc(t, f, 20*log10(abs(spec)));
axis xy;
xlabel('Time (s)');
ylabel('Frequency (Hz)');
title('Spectrogram');
subplot(2, 2, 2);
imagesc(t, f, 20*log10(abs(cepstrum)));
axis xy;
xlabel('Time (s)');
ylabel('Quefrency');
title('Cepstrum');
subplot(2, 2, 3);
plot(t, f0, 'r');
axis([0 max(t) 0 maxf0]);
xlabel('Time (s)');
ylabel('Frequency (Hz)');
title('Pitch');
subplot(2, 2, 4);
plot(t, formants);
axis([0 max(t) 0 maxf0]);
xlabel('Time (s)');
ylabel('Frequency (Hz)');
title('Formants');
legend('F1', 'F2', 'F3', 'F4');
```
该代码读取声音文件`voice.wav`,对每一帧进行基音周期检测和共振峰检测,并将结果绘制成图形。其中,`enframe`是分帧函数,`findpeaks`是寻找峰值函数。可以根据需要自行调整参数,例如窗口长度、帧重叠长度、FFT点数等。
阅读全文