【问题标题】:How to determine the magnitude of a frequency and the phase angle from an audio sample?如何从音频样本中确定频率的大小和相位角?
【发布时间】:2011-08-17 21:39:57
【问题描述】:

我目前正在从事这个项目,这意味着一些 DSP 技能。 我必须从电影中提取音频,然后通过分析它来确定某人何时说话,更像是语音活动检测器。

我正在用 Java 编写代码(是的,我知道这不是最佳选择)并且只使用库从视频和 JLayer 中提取音频,以便处理 MP3。

My class that extracts the audio samples 连续获取每个通道的样本,在我的例子中是两个:LEFT0、RIGHT0、LEFT1、RIGHT1、LEFT2、RIGHT2 等。

这就是我到目前为止所做的:

  • 我将每个通道的样本放在一个数组中。
  • 我应用汉明窗 [N = 8192]:

    double w = 0.54 - 0.46 * (Math.cos(2*Math.PI*buffer[i]/buffer.length-1)); fftBuffer[i] = new Complex(w, 0);

  • 然后我在每个通道上perform a simple FFT 然后计算幅度 mag = re^2 + im^2; 之后,我做了一个对数刻度(dB):mag_dB = 10 * log10(abs(mag));

因为我在这里“寻找语音”,所以我需要 80 到 1000 之间的频率(即使是 80 Hz 到 255 Hz 之间的语音范围也很困难)。因此,从 FFT 中,我从女巫那里得到了一个镜像的 N = 8129 数组,我只需要第一个 N/2。

每个 bin 的频率(由 FFT 产生的阵列中的插槽)将是采样率 (48.000 kHz) /N;这将是 48000 / 8192 = 5 Hz/bin。所以我只在数组中查看从 FFT_Result[15] 到 FFT_Result[199] (16 * 5Hz = 80 Hz; 200 * 5 = 1000 Hz) 的值,对吗?!

我查看了 Cool Edit Pro 中的频率分析仪,所有幅度均为负值。在我的情况下,第一个(声音在背景中并且不响亮)是负面的,之后,它们都是正面的。他们不应该是消极的吗?我在这里错过了什么吗?

到目前为止,根据我通过查看 Cool Edit Pro 中的频率分析仪和相位分析仪所评论的内容,我需要在此频率范围内设置一个阈值,使用某种算法在 n 毫秒的时间段内确定如果幅度在该频率范围内是恒定的,并确定声音是否居中。最后一个必须做(我认为)分析相位角,当有人说话时,声音总是居中。

我没能找到办法做到这一点,我对我迄今为止所做的一切感到困惑,因为我不知道我到目前为止所做的是否正确。

所以,如果您阅读了所有这些内容,感谢您的耐心等待,我的问题是:
- 到目前为止,我做对了吗?
- 幅度必须为负吗?
- 有谁知道我如何计算多个样本的相位?

【问题讨论】:

  • 幅度为负?这没有任何意义,除非是在 dB 范围内。是这样吗?
  • @奥利查尔斯沃思:我做日志规模后我得到的值是这样的:6.192286815256956 1.4657064018498 -2.360496921728435 4.294669805664844 -2.2876799531445684 -11.729105860184267 7.070140033122696阴性和阳性混合在一起跨度>
  • @Cyupa:哦,我错过了您在问题中提到的登录部分。对不起。但是它们是正还是负是完全任意的,从某种意义上说,这取决于音频波形的整体缩放比例。您可能想要寻找的是幅度的显着相对变化,而不是特定的绝对水平。
  • @Oli Charlesworth:所以,您建议,基于某些频率区间的幅度的先前值,我应该确定是否存在相对变化,而不是检查它是否达到某个值。谢谢你的建议。 :-)
  • @Cyupa:是的,可能与前一个时间点的 bin 值有关。或者可能相对于该时间间隔内整个 FFT 的平均 bin 值。实际上,计算有多少总能量“集中”到感兴趣的波段中。

标签: java audio signal-processing fft frequency


【解决方案1】:

以dB为单位,幅度可以是负数也可以是正数,没关系。重要的是相对于某个阈值的值。我将阈值基于周围的样本。因为口语中的能量会随着音节的发音而上下波动,所以一个简单的平均值(乘以你必须使用的一些任意因素才能找到有效的因素)可以很好地作为阈值。

对于时域中的相位,可以先进行希尔伯特变换,然后对每个样本的实部和虚部使用atan2来估计瞬时相位。

【讨论】:

  • 我决定回来提供反馈。这确实是一个非常困难的问题,但是您建议的实用方法是。我采用了它并得到了一些有趣的结果,它需要进行大量微调,并且它在某种程度上取决于音频的编码。谢谢。
【解决方案2】:

您可以检查两个通道之间的延迟,而不是查看各个通道的相位。假设相同的信号呈现给两个通道,则可以从这个通道间延迟中找到声源的方向。假设耳朵到耳朵的距离约为 20 厘米,此延迟最多为 0.2/340=0.58 毫秒或大约 30 个样本@48kHz。如果您计算此范围内的互相关(30 个样本),您应该会找到一个指示源方向的峰值。

要找到类似语音的信号,您可以计算 80-1000Hz 频带中的总能量,并将其与某个合理值作为阈值。您可以在频域中通过对 80 到 1000Hz 区间中的幅度求和来执行此操作,也可以在时域中使用带滤波器和 RMS 值计算来执行此操作。

【讨论】:

    【解决方案3】:

    你有一个双面变换。中点是直流分量。负频率实际上是相位相差 180 度的正频率!因此,如果您使用带负频率的 FFT 值的前半部分,则需要通过 pi 更改相位才能准确了解正在发生的事情。

    或者,使用频率为正且相位正确的 FFT 值的后半部分。

    我查看了 Cool Edit Pro 中的频率分析仪和所有 幅度为负。就我而言,第一个(声音在 背景并且不响亮)是负面的,之后,他们是 都是积极的。他们不应该是消极的吗?我错过了吗 这里有什么?

    【讨论】:

      猜你喜欢
      • 2011-05-28
      • 2015-11-08
      • 2012-02-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-10
      • 2016-01-14
      相关资源
      最近更新 更多