你能告诉我如何从声音中检测一个事件吗?无论它的波形或频谱的一部分是否超过了特定的阈值
本文关键字:波形 一部分 阈值 过了 是否 声音 告诉我 检测 一个 事件 | 更新日期: 2023-09-27 18:08:09
可能重复:
当音频的频谱达到特定高度时,如何捕捉事件,比如由响亮的声音触发的事件?
例如,我想检测音频文件中的节拍或大声。所有的模块都在工作,只是我不知道如何对检测进行编码。有人说,我会迭代频谱中的数据,并记录有负载声音或节拍的部分。
我会给你看我的FFT代码,我从NAudio那里得到的。你能告诉我我是否能在这里检测到一个事件吗。
例如:
if (waveLeft[] > amplitudeThreshold || waveleft[] < -amplitudeThreshold)
listbox.items.add(ActiveStream.CurrentTime)
这就是想法。
这是代码。
public SampleAggregator(int bufferSize)
{
channelData = new Complex[bufferSize];
}
public void Clear()
{
volumeLeftMaxValue = float.MinValue;
volumeRightMaxValue = float.MinValue;
volumeLeftMinValue = float.MaxValue;
volumeRightMinValue = float.MaxValue;
channelDataPosition = 0;
}
/// <summary>
/// Add a sample value to the aggregator.
/// </summary>
/// <param name="value">The value of the sample.</param>
public void Add(float leftValue, float rightValue)
{
if (channelDataPosition == 0)
{
volumeLeftMaxValue = float.MinValue;
volumeRightMaxValue = float.MinValue;
volumeLeftMinValue = float.MaxValue;
volumeRightMinValue = float.MaxValue;
}
// Make stored channel data stereo by averaging left and right values.
channelData[channelDataPosition].X = (leftValue + rightValue) / 2.0f;
channelData[channelDataPosition].Y = 0;
channelDataPosition++;
volumeLeftMaxValue = Math.Max(volumeLeftMaxValue, leftValue);
volumeLeftMinValue = Math.Min(volumeLeftMinValue, leftValue);
volumeRightMaxValue = Math.Max(volumeRightMaxValue, rightValue);
volumeRightMinValue = Math.Min(volumeRightMinValue, rightValue);
if (channelDataPosition >= channelData.Length)
{
channelDataPosition = 0;
}
}
/// <summary>
/// Performs an FFT calculation on the channel data upon request.
/// </summary>
/// <param name="fftBuffer">A buffer where the FFT data will be stored.</param>
public void GetFFTResults(float[] fftBuffer)
{
Complex[] channelDataClone = new Complex[4096];
channelData.CopyTo(channelDataClone, 0);
// 4096 = 2^12
FastFourierTransform.FFT(true, 12, channelDataClone);
for (int i = 0; i < channelDataClone.Length / 2; i++)
{
// Calculate actual intensities for the FFT results.
fftBuffer[i] = (float)Math.Sqrt(channelDataClone[i].X * channelDataClone[i].X + channelDataClone[i].Y * channelDataClone[i].Y);
}
}
感谢您的帮助。:(
基本思想:
-
您将波形样本流分割为时间片,并使用FFT将每个片转换为F域。
-
然后有一个FFT帧流,在其中检查每个通道(bin(的峰值。你需要一个lastValue,甚至每个bin需要一个小状态机。
FFT宽度和峰值电平待配置。