【问题标题】:Real-time measuring fundamental frequency of voice signal using matlab使用matlab实时测量语音信号的基频
【发布时间】:2014-09-18 07:17:28
【问题描述】:

我想在使用 matlab 录制时显示语音信号的基频。我在这里找到了programming in matlab (how to process in real time) 如何做实时部分。

我了解到,用于确定信号基频的技术之一是自相关法。还找到了一段实现它的代码。

现在我将这段代码添加到上面链接中的代码中,但由于我是该领域的新手,我不确定我所做的是否符合我的要求 - 最后一个情节是否显示每个长度=1秒的信号的基频?

clear all
clc

Fs = 8000;                    %# sampling frequency in Hz
T = 1;                        %# length of one interval signal in sec
t = 0:1/Fs:T-1/Fs;            %# time vector
nfft = 2^nextpow2(Fs);        %# n-point DFT
numUniq = ceil((nfft+1)/2);   %# half point
f = (0:numUniq-1)'*Fs/nfft;   %'# frequency vector (one sided)

%# prepare plots
figure
hAx(1) = subplot(311);
hLine(1) = line('XData',t, 'YData',nan(size(t)), 'Color','b', 'Parent',hAx(1));
xlabel('Time (s)'), ylabel('Amplitude')
hAx(2) = subplot(312);
hLine(2) = line('XData',f, 'YData',nan(size(f)), 'Color','b', 'Parent',hAx(2));
xlabel('Frequency (Hz)'), ylabel('Magnitude (dB)')
set(hAx, 'Box','on', 'XGrid','on', 'YGrid','on')
%#specgram(sig, nfft, Fs);

%# prepare audio recording
recObj = audiorecorder(Fs,8,1);

%# Record for 10 intervals of 1sec each
disp('Start speaking...')
for i=1:10
    recordblocking(recObj, T);

    %# get data and compute FFT
    sig = getaudiodata(recObj);
    %%%%%%%%%%%%%%%%%%%%%%%%%%%
    ms20=Fs/50; % minimum speech Fx at 50Hz 
    r=xcorr(sig,'coeff'); 
    %d=(-ms20:ms20)/Fs; % times of delays 
    subplot(3,1,3); 
    plot(r); 
    legend('Autocorrelation'); 
    xlabel('Delay (s)'); 
    ylabel('Correlation coeff.'); 

    %55555555555555555555555555555555555   
%     R = xcorr (x);
     r = r(160:end);
%     n = 0:159; plot (n, R);

    % some constants
    Lmin = 20; Lmax = 146;
    thr = 0.3; % maximum needs to be at least thr * R[0]
    % detect lag
    [Rmax,ii] = max(r((Lmin+1):(Lmax+1))); % needs to add 1 because of Matlab indexing
    if Rmax >= thr * r(1) % R[0] in Matlab indexing
    L=ii+Lmin-1; % and here needs to remove it again...
    else
    L=0;
    end
    %hold on; plot (L,Rmax,'or'); hold off;

    % show lag in samples
    L
    % in seconds
    T0 = L / 8000
    % and fundamental frequency in Hz
    F0 = 1/T0


    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    fftMag = 20*log10( abs(fft(sig,nfft)) );

    %# update plots
    set(hLine(1), 'YData',sig)
    set(hLine(2), 'YData',fftMag(1:numUniq))
    title(hAx(1), num2str(i,'Interval = %d'))
    drawnow                   %# force MATLAB to flush any queued displays
end
disp('Done.')

根据http://www.fit.vutbr.cz/~grezl/ZRE/comp_labs/03_pitch_codec_en.pdf,我在代码中添加了几行(在%5555555 之间)。问题是它输出相同的基频。为什么会发生这种情况,我该如何解决?

谢谢。

【问题讨论】:

  • 不清楚您不确定代码的哪一部分。请更具体。
  • 我不确定结果(最后一个图)是否显示了信号的基频。

标签: matlab real-time signal-processing


【解决方案1】:

它显示的是自相关,而不是基频,每 1 秒更新一次。代码执行在recordblocking 等待,直到录制完成,然后绘制所有内容,然后再次录制,因此该循环的总时间将超过 10 秒。

如果你有一个清晰的音符,只有一个频率,你会在你的自相关中得到一个很好的那个频率的正弦波。如果有人在说话,那将是一个非常混乱的情节。子图 2 将显示您的频率内容,这可以指示清晰的基本频率。

首先尝试这种方法,输入干净的正弦波,看看如何解释你的图。然后也许尝试从乐器中发出一个音符(将包括许多其他频率)或尝试拿着一个音符唱歌(祝你好运),然后考虑这种方法是否适用于说话。

老实说,一个人说话的基本频率并不容易。也因为单词之间的所有停顿,不同单词中的不同音调等等。你可以通过低通滤波器来消除一些高频混乱。

【讨论】:

  • 好的,我根据链接添加了一些代码,但我不知道为什么每个信号序列的输出都相同。
  • 您是否在某处定义了x?我建议将 clear all 放在代码的开头,以确保您没有在工作区中使用旧变量。
  • 另外,你的变量 R 没有被使用。最显着频率的提取可能是通过找到出现max(R(.. 的索引来完成的。我还要说你的基频不一定是最大的分量? - 但最低的非零频率分量。 (同时添加“x = sig”,参见之前的评论)
  • 编辑了我的代码。我不知道可以使用工作区中的旧变量。我再次检查了最后一个链接将所有Rx 出现替换为r。现在看起来还可以。此外,关于基频是波形的最低分量,您是对的。但是我从自相关波形中提取了最大值。我还应该选择最低吗?
  • x 是您的信号,r 是您的自相关,所以不要将x 更改为r。无论如何,here 是您链接到的同一课程的一些讲义。它们似乎暗示最大自相关点与基频有关。我认为这并不像那样直截了当。我可能是错的。 (编辑:不要使用r 的最小值)
猜你喜欢
  • 2013-09-11
  • 2015-07-28
  • 1970-01-01
  • 1970-01-01
  • 2012-11-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-05
相关资源
最近更新 更多