你能告诉我如何从声音中检测事件,无论其波或频谱的一部分是不是超过特定数量的阈值? [复制]

Posted

技术标签:

【中文标题】你能告诉我如何从声音中检测事件,无论其波或频谱的一部分是不是超过特定数量的阈值? [复制]【英文标题】:Can you tell me how to detect an event from a sound whether a part of its wave or spectrum exceeds a specific amount of threshold? [duplicate]你能告诉我如何从声音中检测事件,无论其波或频谱的一部分是否超过特定数量的阈值? [复制] 【发布时间】:2011-09-11 17:57:56 【问题描述】:

可能重复:How to catch the event when spectrum of an audio reached a specific height, like triggered event made by a loud sound?

例如,我想检测音频文件中的节拍或响亮的声音。除了我不知道如何编写检测代码之外,所有模块都在工作。有人说,我会从频谱中迭代数据并记录有负载声音或节拍的部分。

我将向您展示我的 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);

        


    

感谢您的帮助。 :)

【问题讨论】:

Ehm,您是在创建整个声音样本的 1 个 FFT 帧吗?显示数据流的一些***代码会比 FFT 调用的详细信息更有帮助。 我认为该代码生成的数据可用于检测响亮的声音。这只是我的程序的一部分。但是我这里有很多我没有包括在内的代码。就像波形的生成一样。你能说什么?谢谢。 你今天已经发布了 3 次同样的问题 - 请不要那样做。 而且不要创建多个帐户。 【参考方案1】:

基本思路:

您将波形样本流分割成时间片,并使用 FFT 将每个片转换为 F 域。

然后您有一个 FFT 帧流,您可以在其中检查每个通道 (bin) 的峰值。您需要一个 lastValue,甚至每个 bin 都需要一个小型状态机。

要配置的 FFT 宽度和峰值电平。

【讨论】:

很抱歉,但我不知道该怎么做。事实上,这是我第一次处理声音。你能帮我吗? 我已经完成了除检测之外的所有模块。我的截止日期是2天。 :(我做了频谱分析仪,波形发生器,然后在列表框中添加时间。所以当有检测时,当前时间将记录在列表框中。我使用虚拟数据进行了测试。一切正常. 检测是最后一个模块。 你能在2 3 2 7 9 8 3 4 中找到峰值吗?有多少个山峰? 而且你有点快接受了。甚至不会鼓励其他人阅读您的问题。 嗯。谢谢,但我不知道在哪里可以找到它。 :( 对不起。我是新手。

以上是关于你能告诉我如何从声音中检测事件,无论其波或频谱的一部分是不是超过特定数量的阈值? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

【Matlab的图形绘制和频谱计算】+和+【基本信号的表达式】

切割木材的声音检测

如何在.net中检测麦克风的声音

声音信号处理基频检测和时频分析

计算 wav 文件和录制声音的频谱图(音量标准化)

Python - 如何从频谱图输出中获得相同数量的行?