Java 如何从音频样本中确定频率的幅度和相位角?
我目前正在从事这个项目,这意味着一些DSP技能。 我必须从电影中提取音频,然后通过分析它,我必须确定某人何时说话,更像是语音活动检测器 我正在用Java编写代码(是的,我知道这不是最好的选择),只使用库从视频和JLayer中提取音频,这样我就可以处理MP3了 获取每个通道的连续采样,在我的示例中是两个:LEFT0、RIGHT0、LEFT1、RIGHT1、LEFT2、RIGHT2等 这就是我到目前为止所做的:Java 如何从音频样本中确定频率的幅度和相位角?,java,audio,signal-processing,fft,frequency,Java,Audio,Signal Processing,Fft,Frequency,我目前正在从事这个项目,这意味着一些DSP技能。 我必须从电影中提取音频,然后通过分析它,我必须确定某人何时说话,更像是语音活动检测器 我正在用Java编写代码(是的,我知道这不是最好的选择),只使用库从视频和JLayer中提取音频,这样我就可以处理MP3了 获取每个通道的连续采样,在我的示例中是两个:LEFT0、RIGHT0、LEFT1、RIGHT1、LEFT2、RIGHT2等 这就是我到目前为止所做的: 我将每个通道的样本放入一个数组中 我应用汉明窗[N=8192]: double w=0
- 我将每个通道的样本放入一个数组中
- 我应用汉明窗[N=8192]:
double w=0.54-0.46*(Math.cos(2*Math.PI*buffer[i]/buffer.length-1))代码>
fftBuffer[i]=新络合物(w,0)代码>
- 然后,我在每个通道上,计算振幅
mag=re^2+im^2代码>之后,我做一个对数标度(dB):
mag_dB=10*log10(abs(mag))代码>
-到目前为止我做的对吗?
-振幅必须为负吗?
-有人知道如何计算多个样本的相位吗?在dB中,振幅可以是负的,也可以是正的,这无关紧要。重要的是相对于某个阈值的值。我会根据周围的样本来确定阈值。因为随着音节的发音,口语中的能量会上下波动,所以一个简单的平均值(乘以一些你必须使用的任意因子,才能找到合适的值)可以作为一个阈值
对于时域中的相位,您可以首先进行希尔伯特变换,然后对每个样本的实部和虚部使用atan2来估计瞬时相位。您可以检查两个通道之间的延迟,而不是查看单个通道的相位。假设向两个通道提供相同的信号,则可以从通道间延迟中找到声源的方向。假设耳对耳距离约为20cm,此延迟最多为.2/340=.58ms,或在48kHz时约30个样本。如果计算该范围内的互相关(30个样本),则应找到指示震源方向的峰值
要找到类似声音的信号,可以计算80-1000Hz频带内的总能量,并根据某个合理的值设置阈值。您可以在频率域中通过将存储箱中的震级从80到1000Hz相加来实现这一点,或者在时域中使用带式滤波器和RMS值计算来实现这一点 您有一个双面变换。中点是直流分量。负频率实际上是一个正频率,相位相差180度!因此,如果使用FFT值的前半部分w/负频率,则需要通过pi改变相位,以准确地了解正在发生的情况 或者,在频率为正且相位正确的情况下,使用FFT值的后半部分 我看了一下Cool Edit Pro中的频率分析器和所有 振幅为负。在我的例子中,第一个(声音在 背景和声音)是负面的,然后是负面的 都是肯定的。他们不应该是消极的吗?我错过了吗 这里有什么
振幅为负?这是没有意义的,除了在分贝尺度上。是这样吗?@Oli Charlesworth:在我做对数刻度后,我得到如下值:6.192286815256956 1.4657064018498-2.360496921728435 4.294669805664844-2.2876799531445684-11.729105860184267.070140033122966正负混合together@Cyupa:哦,我错过了你问题中提到日志的那部分。很抱歉但是它们是正的还是负的完全是任意的,因为这取决于音频波形的整体比例。您可能想寻找的是振幅的显著相对变化,而不是特定的绝对水平。@奥利·查尔斯沃思:因此,您建议,根据某些频率单元振幅的先前值,我应该确定是否存在相对变化,而不是检查它是否达到某个值。谢谢你的建议。:-)@Cyupa:是的,可能是相对于上一时间点的bin值。或者相对于该时间间隔内整个FFT的平均bin值。有效地,计算机