Matlab:在一帧音频数据中查找主要频率

Posted

技术标签:

【中文标题】Matlab:在一帧音频数据中查找主要频率【英文标题】:Matlab: Finding dominant frequencies in a frame of audio data 【发布时间】:2012-11-27 21:05:55 【问题描述】:

我对 Matlab 很陌生,我正在尝试编写一个简单的基于频率的语音检测算法。最终目标是在 wav 文件上运行脚本,并让它输出每个语音片段的开始/结束时间。如果使用代码:

fr = 128;
[ audio, fs, nbits ] = wavread(audioPath);
spectrogram(audio,fr,120,fr,fs,'yaxis')

我得到了一个有用的频率强度与时间图,如下所示:

通过查看它,很容易看出语音发生的时间。我可以编写一个算法来自动化检测过程,方法是查看每个 x 轴帧,找出哪些频率占主导地位(具有最高强度),测试主导频率以查看是否有足够多的频率高于某个强度阈值(图上黄色和红色之间的差异),然后将该帧标记为语音或非语音。一旦标记了帧,就很容易获得每个语音片段的开始/结束时间。

我的问题是我不知道如何访问这些数据。我可以使用代码:

[S,F,T,P] = spectrogram(audio,fr,120,fr,fs);

获取频谱图的所有功能,但该代码的结果对我没有任何意义。 S、F、T、P 数组和矩阵的边界与我在图表上看到的任何内容都不相关。我查看了帮助文件和 API,但当他们开始乱扔算法名称和首字母缩略词时,我感到很困惑——我的 DSP 背景非常有限。

如何获得该频谱图分析的每一帧的频率强度值数组?我可以从那里弄清楚其余的,我只需要知道如何获取适当的数据。

【问题讨论】:

【参考方案1】:

您尝试执行的操作称为语音活动检测。有很多方法可以解决这个问题,最简单的可能是一个简单的带通滤波器,它通过语音最强的频率,即 1kHz 到 8kHz 之间。然后,您可以将总信号能量与带通限制进行比较,如果大部分能量在语音频带中,则将帧分类为语音。这是一种选择,但也有其他选择。

要获得峰值频率,您可以使用 FFT 获得频谱,然后使用 peakdetect.m。但这是一种非常幼稚的方法,因为您会得到很多峰值,属于基本正弦的谐波频率。

从理论上讲,您应该使用某种倒谱(也称为频谱频谱),它将频谱中谐波的周期性降低到基频,然后将其与峰值检测一起使用。或者,您可以使用现有的工具来执行此操作,例如 praat。

请注意,语音分析通常在大约 30 毫秒的帧上完成,步长为 10 毫秒。您可以通过确保在 N 个连续帧中检测到共振峰来进一步滤除错误检测。

【讨论】:

【参考方案2】:

Why don't you use fft with `fftshift:

  %% Time specifications:
   Fs = 100;                      % samples per second
   dt = 1/Fs;                     % seconds per sample
   StopTime = 1;                  % seconds
   t = (0:dt:StopTime-dt)';
   N = size(t,1);
   %% Sine wave:
   Fc = 12;                       % hertz
   x = cos(2*pi*Fc*t);
   %% Fourier Transform:
   X = fftshift(fft(x));
   %% Frequency specifications:
   dF = Fs/N;                      % hertz
   f = -Fs/2:dF:Fs/2-dF;           % hertz
   %% Plot the spectrum:
   figure;
   plot(f,abs(X)/N);
   xlabel('Frequency (in hertz)');
   title('Magnitude Response');

为什么要使用复杂的东西?

可以在https://dsp.stackexchange.com/questions/1522/simplest-way-of-detecting-where-audio-envelopes-start-and-stop找到一个不错的完整解决方案

【讨论】:

我很困惑 - 实际的音频数据在哪里出现? 我的意思是,我知道我可以通过执行 'q = 10*log(abs(fftshift(fft(audio))));' 来获得方程式给我的任何数据,但同样,我不确定那是什么数据。这是一个 335570x1 向量,最小值为 0.0218,最大值为 497 - 它应该代表什么? 你应该将缓冲区分成更小的数据包并分析每个【参考方案3】:

查看 STFT(短时傅立叶变换)或(甚至更好)DWT(离散小波变换),它们都将估计数据块(窗口)中的频率内容,如果您需要想要检测某些(“语音”)频率幅度的突然变化。

不要使用 FFT,因为它会计算整个信号持续时间中的相对频率内容,因此无法确定何时特定频率出现在信号。

【讨论】:

【参考方案4】:

如果你仍然使用内置的 STFT 函数,那么你可以使用以下命令来绘制最大值

plot(T,(floor(abs(max(S,[],1)))))

【讨论】:

以上是关于Matlab:在一帧音频数据中查找主要频率的主要内容,如果未能解决你的问题,请参考以下文章

语音处理基于matlab GUI音频数据处理含Matlab源码 1734期

语音识别基于MFCC和SVM的特定人性别识别matlab源码

语音识别基于结合mfcc和lpc特征SVM支持向量机实现中英语种识别matlab源码

语音识别基于结合mfcc和lpc特征SVM支持向量机实现中英语种识别matlab源码

matlab怎样进行频谱分析

在matlab中提取具有多个频率分量的信号