NAudio Peak Volume Meter

12,289

Solution 1

All that is happening in that article is that it is finding the maximum audio peak over a small interval (e.g. 20ms) and then plotting that on a decibel scale. To find the peak, examine the value of each sample in the interval and select the max value (It's what the SampleAggregator class is doing). To convert to decibels, take the log base 10 of the maximum value, and multiply by 10. So 0dB is the loudest, and anything below say -96dB is effectively silence. (actually, looking back at the article, I don't think I even bothered to convert to a decibel scale, which I probably should have done)

Solution 2

This was my little solution for getting peak from output device. I'm using NAudio version 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));
        }
    }
}
Share:
12,289
Shivam Sarodia
Author by

Shivam Sarodia

Updated on June 08, 2022

Comments

  • Shivam Sarodia
    Shivam Sarodia about 2 years

    I'm attempting to write a peak volume meter using NAudio. My code is very similar to http://channel9.msdn.com/coding4fun/articles/NET-Voice-Recorder, but both my code and the linked Voice Recorder project suffer from an issue.

    When playing a sound of constant frequency and volume, the volume meter initially begins at a reasonable level, but then decays to a very small value. I'm not sure why this is the case, for the peak volume meter in the NAudioDemo does not do this. I attempted to replicate the code from NAudioDemo in my program, but I was unable to find the code file containing the peak volume meter code.

    Can somebody guide me to an alternative solution for creating a peak volume meter or help me determine why my solution (and the one provided at the link) both don't work?

    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;
        }