NAudio WAV 文件频率到分贝

问题描述 投票:0回答:2

我正在使用 NAudio 生成 WAV 文件。 Wav 文件包含环境噪音(通过麦克风检测和记录)。 我需要处理此文件以显示不同频段的平均响度 (dB)。 我读了很多关于 1:3 倍频程分析的内容,其中频率窗口为 31、62、125、250、500 Hz 等。我们可以得到每个窗口的平均响度。 这正是我想做的,但如何实现这一点似乎令人困惑。 到目前为止我所做的是(使用 NAudio 教程)读取 WAV 文件并处理它。这是代码:

private void RenderFile()
{
    using (WaveFileReader reader = new WaveFileReader(this.voiceRecorderState.ActiveFile))
    {
        this.samplesPerSecond = reader.WaveFormat.SampleRate;
        SampleAggregator.NotificationCount = reader.WaveFormat.SampleRate/10;
        //Sample rate is 44100

        byte[] buffer = new byte[1024];
        WaveBuffer waveBuffer = new WaveBuffer(buffer);
        waveBuffer.ByteBufferCount = buffer.Length;
        int bytesRead;
        do
        {
            bytesRead = reader.Read(waveBuffer, 0, buffer.Length);
            int samples = bytesRead / 2;

            double sum = 0;
            for (int sample = 0; sample < samples; sample++)
            {
                if (bytesRead > 0)
                {
                    sampleAggregator.Add(waveBuffer.ShortBuffer[sample] / 32768f);
                    double sample1 = waveBuffer.ShortBuffer[sample] / 32768.0;
                    sum += (sample1 * sample1);

                }
            }
            double rms = Math.Sqrt(sum / (SampleAggregator.NotificationCount));
            double decibel = (double)(20 * Math.Log10(rms));
            if (calculatedBCount == 0)
            {
                dBList.Add(decibel);
                //  System.Diagnostics.Debug.WriteLine(decibel.ToString() + " in dB");
            }
        } while (bytesRead > 0);
        int totalSamples = (int)reader.Length / 2;
        TotalWaveFormSamples = totalSamples / sampleAggregator.NotificationCount;
        calculatedBCount++;
        SelectAll();

        //System.Diagnostics.Debug.WriteLine("Average Noise: " + avg.ToString() + " dB");
    }
    audioPlayer.LoadFile(this.voiceRecorderState.ActiveFile);
}


public int Read(byte[] buffer, int offset, int count)
{
    if (waveBuffer == null || waveBuffer.MaxSize < count)
    {
        waveBuffer = new WaveBuffer(count);
    }

    int bytesRead = source.Read(waveBuffer, 0, count);

    if (bytesRead > 0) bytesRead = count;

    int frames = bytesRead / sizeof(float); // MRH: was count
    float pitch = pitchDetector.DetectPitch(waveBuffer.FloatBuffer, frames);
    PitchList.Add(pitch);
    return frames * 4;
}

使用5秒的WAV文件,通过上述两种方法,我得到了音高和分贝的列表 分贝列表包含 484 个值,例如:

-56.19945639
-55.13139952
-55.06947441
-56.70789076
-57.24140093
-55.98546603
-55.67407176
-55.53060998
-55.98480268
-54.85796943
-57.00735818
-55.64980974
-57.07235475

PitchList 包含 62 个值,其中包括:

75.36621
247.631836
129.199219
75.36621
96.8994141
96.8994141
86.13281
75.36621
129.199219
107.666016

如何使用这些结果来识别 31Hz、62Hz、125Hz、250Hz 等的平均响度。

也许我做错了什么或者一切都错了?

c# wav naudio frequency-analysis
2个回答
0
投票

如果我错了,请纠正我,但是...恐怕您无法将 HZ 转换为 DB,因为它们之间没有关系。 Hz 是频率的度量,Db 是振幅的度量,类似于千克到米。


0
投票

首先,响度是一种心理声学指标,比以分贝为单位的声压级 (SPL) 更复杂,请参阅 this。 看来您追求的是 SPL 而不是响度,那么在我看来您正在做的事情是正确的。 为了获得 1/3 倍频程电平,最简单的方法是对每个 1/3 倍频程中心频率周围的信号进行带通,然后分别计算每个带通信号的 SPL。

© www.soinside.com 2019 - 2024. All rights reserved.