3

我正在尝试使用 NAudio 编写峰值音量计。我的代码与http://channel9.msdn.com/coding4fun/articles/NET-Voice-Recorder非常相似,但我的代码和链接的 Voice Recorder 项目都存在问题。

当播放恒定频率和音量的声音时,音量表最初以合理的电平开始,但随后衰减到非常小的值。我不确定为什么会这样,因为 NAudioDemo 中的峰值音量计不这样做。我试图在我的程序中复制来自 NAudioDemo 的代码,但我无法找到包含峰值音量计代码的代码文件。

有人可以指导我使用另一种解决方案来创建峰值音量计或帮助我确定为什么我的解决方案(以及链接中提供的解决方案)都不起作用吗?

public MainWindow()
    {
        int waveInDevices = WaveIn.DeviceCount;
        for (int waveInDevice = 0; waveInDevice < waveInDevices; waveInDevice++)
        {
            WaveInCapabilities deviceInfo = WaveIn.GetCapabilities(waveInDevice);
            Console.WriteLine("Device {0}: {1}, {2} channels",
                waveInDevice, deviceInfo.ProductName, deviceInfo.Channels);

            WaveIn waveIn = new WaveIn();
            waveIn.DeviceNumber = 0; //TODO: Let the user choose which device, this comes from the device numbers above
            waveIn.DataAvailable += waveIn_DataAvailable;
            int sampleRate = SAMPLE_RATE; // 8 kHz
            int channels = 1; // mono
            waveIn.WaveFormat = new WaveFormat(sampleRate, channels);
            waveIn.StartRecording();
        }
    }

    void waveIn_DataAvailable(object sender, WaveInEventArgs e)
    {
        for (int index = 0; index < e.BytesRecorded; index += 2)
        {
            short sample = (short)((e.Buffer[index + 1] << 8) |
                                    e.Buffer[index + 0]);
            float sample32 = sample / 32768f;
            ProcessSample(sample32);
        }           

    }

    void ProcessSample(float sample1)
    {
        samplenumber += 1;

        if (sample1 > maxval)
        {
            maxval = sample1;
        }

        if (sample1 < minval)
        {
            minval = sample1;
        }


        //Run updateView every few loops

        if (samplenumber > (double)SAMPLE_RATE / DISPLAY_UPDATE_RATE)
        {
            samplenumber = 0;
            updateView(); //needs to be fast!
        }
    }

    void updateView()
    {
        Console.WriteLine(maxval);
        Console.WriteLine(minval);
        progressBar1.Value = (maxval - minval)*50;

        maxval = 0;
        minval = 0;
    }
4

3 回答 3

6

那篇文章中发生的所有事情都是它在一个小间隔(例如 20 毫秒)内找到最大音频峰值,然后将其绘制在分贝标度上。要找到峰值,请检查间隔中每个样本的值并选择最大值(这是SampleAggregator班级正在做的事情)。要转换为分贝,取最大值的以 10 为底的对数,然后乘以 10。所以 0dB 是最响亮的,低于 -96dB 的任何东西实际上都是静音。(实际上,回顾文章,我认为我什至都懒得转换成分贝标度,我可能应该这样做)

于 2013-01-16T09:27:42.477 回答
3

这是我从输出设备获得峰值的小解决方案。我正在使用 NAudio 版本 1.7.0.15

 public partial class Form1 : Form
{


    public Form1()
    {
        InitializeComponent();

        MMDeviceEnumerator enumerator = new MMDeviceEnumerator();

        var devices = enumerator.EnumerateAudioEndPoints(DataFlow.All, DeviceState.Active);
        comboboxDevices.Items.AddRange(devices.ToArray());
    }

    private void timer1_Tick(object sender, EventArgs e)
    {
        if (comboboxDevices.SelectedItem != null)
        {
            var device = (MMDevice)comboboxDevices.SelectedItem;
            progressBar1.Value = (int)(Math.Round(device.AudioMeterInformation.MasterPeakValue * 100));
        }
    }
}
于 2014-06-05T07:00:56.327 回答
0

尝试使用 MasterPeakValue 获取级别似乎比仅调用该方法更复杂,这破坏了它的简单性。

我不小心意识到你必须打开设备进行记录,即使你不使用传入的数据。由于您正在启动 WaveIn,因此 MasterPeakValue 应该返回一个非 0 值。

一个简单的替代方法,仅用于测试,是打开系统录音设备的属性(右键单击系统音量图标并选择“录音设备”)。

(在 2 台不同的计算机上测试。)

于 2016-04-12T11:05:33.460 回答