Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /***********************************************************
- ** **
- ** Codesnippets written by Madwin for MMP 2023 **
- ** **
- ** Not to be used freely. the code still has errors **
- ** It's intended to be used as starting point. **
- ** Code has not been checked and might still need **
- ** (a lot of) work. **
- ** **
- ** © MadMedia Productions 2023 **
- ** **
- ***********************************************************/
- using System;
- using System.Drawing;
- using System.Windows.Forms;
- using NAudio.Wave;
- namespace AudioVUMeter
- {
- public partial class MainForm : Form
- {
- private const int NumChannels = 2; // Stereo
- private const int NumBars = 20; // Number of LED bars
- private const int BarSpacing = 2; // Spacing between LED bars
- private BufferedWaveProvider bufferedWaveProvider;
- private readonly Timer timer;
- private float[] peakValues;
- public MainForm()
- {
- InitializeComponent();
- // Create the buffered wave provider
- bufferedWaveProvider = new BufferedWaveProvider(new WaveFormat());
- // Initialize the peak values array
- peakValues = new float[NumBars];
- // Set up the timer
- timer = new Timer();
- timer.Interval = 20; // Update every 20 milliseconds
- timer.Tick += Timer_Tick;
- // Populate audio source options
- foreach (var waveInDevice in WaveIn.DeviceCount)
- {
- comboBoxAudioSources.Items.Add(waveInDevice);
- }
- // Select the first audio source by default
- if (comboBoxAudioSources.Items.Count > 0)
- {
- comboBoxAudioSources.SelectedIndex = 0;
- }
- }
- private void MainForm_Load(object sender, EventArgs e)
- {
- // Start the timer
- timer.Start();
- }
- private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
- {
- // Stop and dispose the timer
- timer.Stop();
- timer.Dispose();
- }
- private void Timer_Tick(object sender, EventArgs e)
- {
- // Check if there is available data in the buffered wave provider
- if (bufferedWaveProvider.BufferedBytes >= bufferedWaveProvider.WaveFormat.AverageBytesPerSecond / 10)
- {
- // Read the available data from the buffered wave provider
- byte[] buffer = new byte[bufferedWaveProvider.WaveFormat.AverageBytesPerSecond / 10];
- int bytesRead = bufferedWaveProvider.Read(buffer, 0, buffer.Length);
- // Calculate the peak values for each channel
- for (int i = 0; i < bytesRead / sizeof(float); i += NumChannels)
- {
- for (int channel = 0; channel < NumChannels; channel++)
- {
- float value = BitConverter.ToSingle(buffer, i + channel * sizeof(float));
- peakValues[i / NumChannels] = Math.Max(peakValues[i / NumChannels], value);
- }
- }
- }
- // Refresh the display
- vuMeterDisplay.Refresh();
- }
- private void vuMeterDisplay_Paint(object sender, PaintEventArgs e)
- {
- Graphics graphics = e.Graphics;
- Rectangle displayArea = vuMeterDisplay.ClientRectangle;
- // Calculate the width and height of each LED bar
- int barWidth = (displayArea.Width - (NumBars - 1) * BarSpacing) / NumBars;
- int barHeight = displayArea.Height;
- // Draw each LED bar
- for (int i = 0; i < NumBars; i++)
- {
- // Calculate the rectangle for the current LED bar
- Rectangle barRect = new Rectangle(i * (barWidth + BarSpacing), displayArea.Top, barWidth, barHeight);
- // Calculate the fill percentage based on the peak value
- float fillPercentage = peakValues[i];
- // Calculate the height of the filled portion of the LED bar
- int fillHeight = (int)(fillPercentage * barHeight);
- // Calculate the color for the filled portion
- Color fillColor = Color.FromArgb((int)(
- fillPercentage * 255), Color.Red);
- // Fill the LED bar
- graphics.FillRectangle(new SolidBrush(fillColor), barRect);
- // Draw the border of the LED bar
- graphics.DrawRectangle(Pens.Black, barRect);
- }
- }
- private void comboBoxAudioSources_SelectedIndexChanged(object sender, EventArgs e)
- {
- // Stop the current audio source, if any
- if (bufferedWaveProvider != null)
- {
- bufferedWaveProvider.ClearBuffer();
- bufferedWaveProvider = null;
- }
- // Create a new audio source based on the selected index
- int selectedDeviceIndex = comboBoxAudioSources.SelectedIndex;
- if (selectedDeviceIndex >= 0 && selectedDeviceIndex < WaveIn.DeviceCount)
- {
- WaveIn waveIn = new WaveIn();
- waveIn.DeviceNumber = selectedDeviceIndex;
- waveIn.WaveFormat = new WaveFormat();
- bufferedWaveProvider = new BufferedWaveProvider(waveIn.WaveFormat);
- bufferedWaveProvider.BufferDuration = TimeSpan.FromSeconds(1); // Set buffer duration to 1 second
- bufferedWaveProvider.DiscardOnBufferOverflow = true;
- waveIn.DataAvailable += WaveIn_DataAvailable;
- waveIn.StartRecording();
- }
- }
- private void WaveIn_DataAvailable(object sender, WaveInEventArgs e)
- {
- if (bufferedWaveProvider != null)
- {
- bufferedWaveProvider.AddSamples(e.Buffer, 0, e.BytesRecorded);
- }
- }
- }
- }
- /*
- There's a `comboBoxAudioSources` control, which allows the user to select
- the audio source for display. We populate the combo box with the available
- audio input devices using the `WaveIn.DeviceCount` property.
- When the user selects a different audio source, the `comboBoxAudioSources_SelectedIndexChanged` event handler is triggered.
- It stops the current audio source (if any), clears the buffer, and creates a
- new audio source based on the selected index. The `WaveIn` class is used to
- capture audio data from the selected device, and the `WaveIn_DataAvailable` event
- handler is responsible for adding the available samples to the `bufferedWaveProvider`
- for processing.
- Remember to wire up the `comboBoxAudioSources_SelectedIndexChanged` event handler
- to the `SelectedIndexChanged` event of the combo box in the form designer or
- programmatically.
- */
- using System;
- using System.Drawing;
- using System.Windows.Forms;
- using CSCore;
- using CSCore.CoreAudioAPI;
- using CSCore.SoundIn;
- namespace AudioVUMeter
- {
- public partial class MainForm : Form
- {
- private const int NumChannels = 2; // Stereo
- private const int NumBars = 20; // Number of LED bars
- private const int BarSpacing = 2; // Spacing between LED bars
- private WasapiCapture capture;
- private float[] peakValues;
- public MainForm()
- {
- InitializeComponent();
- // Initialize the peak values array
- peakValues = new float[NumBars];
- }
- private void MainForm_Load(object sender, EventArgs e)
- {
- // Populate audio source options
- foreach (var device in MMDeviceEnumerator.EnumerateDevices(DataFlow.Capture, DeviceState.Active))
- {
- comboBoxAudioSources.Items.Add(device);
- }
- // Select the first audio source by default
- if (comboBoxAudioSources.Items.Count > 0)
- {
- comboBoxAudioSources.SelectedIndex = 0;
- }
- }
- private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
- {
- // Stop and dispose the capture
- if (capture != null)
- {
- capture.Stop();
- capture.Dispose();
- }
- }
- private void comboBoxAudioSources_SelectedIndexChanged(object sender, EventArgs e)
- {
- // Stop the current capture, if any
- if (capture != null)
- {
- capture.Stop();
- capture.Dispose();
- capture = null;
- }
- // Create a new capture based on the selected audio source
- int selectedDeviceIndex = comboBoxAudioSources.SelectedIndex;
- if (selectedDeviceIndex >= 0 && selectedDeviceIndex < comboBoxAudioSources.Items.Count)
- {
- MMDevice selectedDevice = (MMDevice)comboBoxAudioSources.SelectedItem;
- capture = new WasapiCapture(selectedDevice);
- // Set up event handlers
- capture.DataAvailable += Capture_DataAvailable;
- capture.Initialize();
- // Start the capture
- capture.Start();
- }
- }
- private void Capture_DataAvailable(object sender, WaveInEventArgs e)
- {
- // Calculate the peak values for each channel
- for (int i = 0; i < e.BytesRecorded / sizeof(float); i += NumChannels)
- {
- for (int channel = 0; channel < NumChannels; channel++)
- {
- float value = BitConverter.ToSingle(e.Buffer, i + channel * sizeof(float));
- peakValues[i / NumChannels] = Math.Max(peakValues[i / NumChannels], value);
- }
- }
- // Refresh the display
- vuMeterDisplay.Refresh();
- }
- private void vuMeterDisplay_Paint(object sender, PaintEventArgs e)
- {
- Graphics graphics = e.Graphics;
- Rectangle displayArea = vuMeterDisplay.ClientRectangle;
- // Calculate the width and height of each LED bar
- int barWidth = (displayArea.Width - (NumBars - 1) * BarSpacing) / NumBars;
- int barHeight = displayArea.Height;
- // Draw each LED bar
- for (int i = 0; i < NumBars; i++)
- {
- // Calculate the rectangle for the current LED bar
- Rectangle barRect = new Rectangle(i * (barWidth + BarSpacing), displayArea.Top, barWidth, barHeight);
- // Calculate the fill percentage based on the peak value
- float fillPercentage = peakValues[i];
- // Calculate the height of the filled portion of the LED bar
- int fillHeight = (int)(fillPercentage * barHeight);
- // Calculate the color for the filled portion
- Color fillColor = Color.FromArgb((int)(fillPercentage * 255), Color.Red);
- // Fill the LED bar
- graphics.FillRectangle(new SolidBrush(fillColor), barRect);
- // Draw the border of the LED bar
- graphics.DrawRectangle(Pens.Black, barRect);
- }
- }
- }
- }
- /*
- In this updated version, we use the CSCore library to capture audio data from
- the selected audio source. We populate the comboBoxAudioSources combo box with
- the active audio capture devices using the MMDeviceEnumerator.EnumerateDevices
- method.
- When the user selects a different audio source, the
- comboBoxAudioSources_SelectedIndexChanged event handler is triggered. It stops
- the current capture (if any), disposes of the resources, and creates a new capture
- based on the selected audio source using the WasapiCapture class. We set up the
- DataAvailable event handler to calculate the peak values for each channel and
- update the VU meter display.
- Remember to wire up the comboBoxAudioSources_SelectedIndexChanged event handler
- to the SelectedIndexChanged event of the combo box in the form designer or
- programmatically.
- This updated code should allow you to choose the audio source you want to
- isplay in the VU meter using the CSCore library.
- */
Advertisement
Add Comment
Please, Sign In to add comment