Click here to Skip to main content
11,637,415 members (63,745 online)
Click here to Skip to main content

VolumeMeter (Managed DirectX)

, 10 Aug 2006 MIT 230.3K 10K 68
Rate this:
Please Sign up or sign in to vote.
A flexible Windows Forms control for live monitoring of volume levels from an audio capture source.

Sample Image - volumemeter.jpg

Introduction

This project is a live volume meter control for monitoring audio levels from a sound card. It is written entirely in C#, and uses Microsoft's Managed DirectX (June release). You can drag-and-drop the control into any Windows Forms application. You may select the input, and tweak the appearance of the animation through various parameters.

The idea behind this project is to maintain a very short buffer of audio and constantly record into it. The control is on a timer, and periodically queries the buffer to see what volume level the most recent sample has, and then sets a progress bar's value accordingly.

There are commercial controls that achieve the same purpose, but I wanted to dive in and get my hands dirty with DirectX (albeit the managed version Smile | :) ). I hope others will benefit from this work.

Using the code

This project consists of four DLLs: volumemeter.dll, progressbargradient.dll, Microsoft.DirectX.dll, and Microsoft.DirectX.DirectSound.dll. To use this control in a project, right-click in the toolbox, select "Choose Controls", and browse for volumemeter.dll. You don't need to manually reference any of the other DLLs, but they do need to be present. The control should now be present in your toolbox, so drag it onto a form to add it to your project. The control is active even while in the Visual Studio designer, so you can see it in action without having to run the project.

The following methods are available to you:

  • Start() - starts the animation, provided an audio device has been set through SelectedDeviceIndex or SelectedDeviceName.
  • Stop() - halts the animation.

The following properties are available to you:

  • AutoStart - if true, whenever you change the audio source (through SelectedDeviceIndex or SelectedDeviceName) and the meter animation is currently turned off, the control will start the animation.
  • BorderStyle - sets the appearance of the border around each progress bar.
  • DeviceNames - a list of the audio devices present in the system.
  • Orientation - sets the volume bars to run horizontally or vertically.
  • SelectedDeviceIndex - gets or sets the index of the current audio device according to the list in DeviceNames. If you enter an index out of bounds of the DeviceNames list, the meter stops running.
  • SelectedDeviceName - gets or sets the name of the current audio device according to the list in DeviceNames If you enter a name which is not contained in the DeviceNames list, the meter stops running. Note that while you can select a device through the control, you must adjust the recording properties of that device through Windows Volume Control or some other program.
  • VisualizerOn - set to true to start the animation, false to stop. You can achieve the same results with the Start() and Stop(), but this property is useful for toggling without having to check the current state first.

    Altering the following properties is not necessary for operating the control, but this information is here just for reference. The defaults are fine for most projects.

  • SampleDelay - how often the control queries the capture buffer to get the volume, measured in milliseconds. Values between 80 and 140 generally give good results, default is 100.
  • FrameDelay - the time in milliseconds between animation frames, measured in milliseconds. Values between 10 and 40 generally give good results, default is 10. This value must be less than or equal to SampleDelay.

    The last two values work together to provide a smooth animation. SampleDelay dictates how often a real value is read from the sound card, but in-between those capture points, the control interpolates frames to keep the animation running smoothly. This gives much better results than just polling the audio card and updating the progress bar's value (which, by the way, you can simulate by setting FrameDelay = SampleDelay).

The following events are available to you:

  • VolumeChanged fires whenever a new sample is read that differs from the previous one. The event uses a VolumeChangedEventArgs class to send information about the old and new volume levels.

Points of Interest

This control uses GDI+ to run all the animation, so if you size the control to full-screen, you will most likely see a very high CPU usage. You can lower that usage by increasing the SampleDelay and/or FrameDelay values. Notice, however, that the animation runs in a separate thread that is set to have a very low priority, so this control will not cause your project to hang.

The progress bars in this project are custom controls I built. They let you use a gradient fill rather than a plain old solid color. If you want to use them independent of this project, just add the "ProgressBarGradient.dll" to your toolbox. I might post the ProgressBarGradient project online if/when I get around to it.

If you're interested in how to use managed DirectX, here's the code for starting the audio capture buffer:

// initialize the capture buffer and start the animation thread
Capture cap = new Capture(audioDevices[deviceIndex].DriverGuid);
CaptureBufferDescription desc = new CaptureBufferDescription();

WaveFormat wf = new WaveFormat();
wf.BitsPerSample = 16;
wf.SamplesPerSecond = 44100;
wf.Channels = 2;
wf.BlockAlign = (short)(wf.Channels * wf.BitsPerSample / 8);
wf.AverageBytesPerSecond = wf.BlockAlign * wf.SamplesPerSecond;
wf.FormatTag = WaveFormatTag.Pcm;


desc.Format = wf;
desc.BufferBytes = SAMPLES * wf.BlockAlign;
    
buffer = new Microsoft.DirectX.DirectSound.CaptureBuffer(desc, cap);
buffer.Start(true);

liveVolumeThread = new Thread(new ThreadStart(updateProgress));    
liveVolumeThread.Priority = ThreadPriority.Lowest;
liveVolumeThread.Start();

And here's how you read values from the buffer:

private const int SAMPLES = 8;
private static int[] SAMPLE_FORMAT_ARRAY = {SAMPLES, 2, 1};
...

Array samples = buffer.Read(0, typeof(Int16), LockFlag.FromWriteCursor, 
                            SAMPLE_FORMAT_ARRAY);

Etc.

I have tested and used this control on only a few different machines, so no guarantees about how well it will run for you. The usual disclaimers apply - run this code at your own risk, I am not responsible if you lose your firstborn because of some bug in the code Smile | :) . That said, I have not encountered any problems using this control in my own projects. Feel free to contact me with any bugs or suggestions. Enjoy!

History

  • v1.0 - Released 7/27/2006.

License

This article, along with any associated source code and files, is licensed under The MIT License

Share

About the Author

Jacob Klint
Software Developer
United States United States
No Biography provided

You may also be interested in...

Comments and Discussions

 
QuestionImprovement, no average but RMS Pin
diffy671-Mar-15 18:40
memberdiffy671-Mar-15 18:40 
QuestionI want to monitor audio levels from an ip source(udp multicast) Pin
arunnnnnkumar19-Mar-14 18:23
memberarunnnnnkumar19-Mar-14 18:23 
QuestionWhy you read 8 samples? Pin
TheJimbow4-Oct-13 8:53
memberTheJimbow4-Oct-13 8:53 
QuestionFavor Pin
lash1co1-Oct-13 13:24
memberlash1co1-Oct-13 13:24 
GeneralMy vote of 4 Pin
Burak Tunçbilek31-Jul-12 11:49
memberBurak Tunçbilek31-Jul-12 11:49 
GeneralMy vote of 5 Pin
fedoaa1-May-12 0:05
memberfedoaa1-May-12 0:05 
GeneralVS 2010 / windows7 / directx problem Pin
Jan Roth4-Apr-11 7:03
memberJan Roth4-Apr-11 7:03 
GeneralVolumemeter Pin
patrickfreyaudio9-Feb-11 4:36
memberpatrickfreyaudio9-Feb-11 4:36 
QuestionIs there a way to convert this to read the master line out instead of input? Pin
Mystify19-Sep-10 8:37
memberMystify19-Sep-10 8:37 
GeneralLogarithmic display (how to) Pin
M$VBC++7-Sep-10 21:47
memberM$VBC++7-Sep-10 21:47 
GeneralVB.Net version. Needs cleaning up. Pin
Nigel Ealand29-Jun-10 11:11
memberNigel Ealand29-Jun-10 11:11 
GeneralRe: VB.Net version. Needs cleaning up. Pin
macgyvertiras1-Jul-10 17:21
membermacgyvertiras1-Jul-10 17:21 
GeneralRe: VB.Net version. Needs cleaning up. Pin
Nigel Ealand1-Jul-10 23:19
memberNigel Ealand1-Jul-10 23:19 
GeneralRe: VB.Net version. Needs cleaning up. Pin
macgyvertiras2-Jul-10 10:20
membermacgyvertiras2-Jul-10 10:20 
GeneralRe: VB.Net version. Needs cleaning up. Pin
Nigel Ealand3-Jul-10 2:43
memberNigel Ealand3-Jul-10 2:43 
GeneralRe: VB.Net version. Needs cleaning up. Pin
macgyvertiras7-Jul-10 16:20
membermacgyvertiras7-Jul-10 16:20 
GeneralRe: VB.Net version. Pin
Nigel Ealand17-Jul-10 21:53
memberNigel Ealand17-Jul-10 21:53 
Generalthis doesn't work !!!!!!!!!! Pin
macgyvertiras24-Jun-10 15:03
membermacgyvertiras24-Jun-10 15:03 
GeneralRe: this doesn't work !!!!!!!!!! Pin
Nigel Ealand25-Jun-10 0:12
memberNigel Ealand25-Jun-10 0:12 
GeneralRe: this doesn't work !!!!!!!!!! [modified] Pin
macgyvertiras25-Jun-10 16:25
membermacgyvertiras25-Jun-10 16:25 
GeneralRe: this doesn't work !!!!!!!!!! Pin
dwiswall26-Jun-10 3:28
memberdwiswall26-Jun-10 3:28 
GeneralRe: this doesn't work !!!!!!!!!! .net version Pin
Nigel Ealand29-Jun-10 6:29
memberNigel Ealand29-Jun-10 6:29 
GeneralError: system.invalidoperationexception Pin
Nigel Ealand23-Jun-10 5:53
memberNigel Ealand23-Jun-10 5:53 
Generalgetting error Pin
macgyvertiras19-Jun-10 23:30
membermacgyvertiras19-Jun-10 23:30 
GeneralRe: getting error Pin
Nigel Ealand24-Jun-10 2:29
memberNigel Ealand24-Jun-10 2:29 
GeneralLoaderlock error Pin
mahdi_autc2-Feb-10 23:14
membermahdi_autc2-Feb-10 23:14 
GeneralMy vote of 1 Pin
deiong24-Apr-09 15:06
memberdeiong24-Apr-09 15:06 
Generali can't dounload the file from the link Pin
ronanran200022-Feb-09 20:33
memberronanran200022-Feb-09 20:33 
AnswerDid some updates... Pin
Thomas Gorgolione17-Jan-09 16:25
memberThomas Gorgolione17-Jan-09 16:25 
QuestionHow to use lib 'VolumeMeter' in VB2005 Pin
tum11111-Jan-09 14:50
membertum11111-Jan-09 14:50 
GeneralYour project was incredibly helpful Pin
reason918-Dec-08 13:54
memberreason918-Dec-08 13:54 
QuestionError when trying to drag the control onto a form Pin
eMatt6912-Jul-08 8:52
membereMatt6912-Jul-08 8:52 
GeneralIt's urgent! Pin
eMatt6916-Jul-08 23:54
membereMatt6916-Jul-08 23:54 
GeneralRe: It's urgent! Pin
Jacob Klint17-Jul-08 5:52
memberJacob Klint17-Jul-08 5:52 
GeneralRe: It's urgent! Pin
eMatt6918-Jul-08 7:03
membereMatt6918-Jul-08 7:03 
GeneralRe: It's urgent! Pin
Fadik10-Aug-11 20:43
memberFadik10-Aug-11 20:43 
QuestionWhen closing form it shows an error! Pin
suresh suthar3-Nov-07 2:37
membersuresh suthar3-Nov-07 2:37 
QuestionRe: When closing form it shows an error! Pin
Ibrahim Dwaikat19-Nov-07 12:12
memberIbrahim Dwaikat19-Nov-07 12:12 
Generalget mic input level as trigger Pin
chrishaerr10-Aug-07 23:08
memberchrishaerr10-Aug-07 23:08 
GeneralRe: get mic input level as trigger Pin
Jacob Klint14-Aug-07 13:13
memberJacob Klint14-Aug-07 13:13 
Questionsource doesn't work Pin
chrishaerr10-Aug-07 23:07
memberchrishaerr10-Aug-07 23:07 
AnswerRe: source doesn't work Pin
Jacob Klint14-Aug-07 13:09
memberJacob Klint14-Aug-07 13:09 
Generalselecting between mic input and line input Pin
David Every18-Jun-07 20:37
memberDavid Every18-Jun-07 20:37 
GeneralRe: selecting between mic input and line input Pin
Jacob Klint18-Jun-07 20:42
memberJacob Klint18-Jun-07 20:42 
QuestionHow to get the demo-source code Pin
h4xx0rz5-May-07 3:51
memberh4xx0rz5-May-07 3:51 
GeneralNEW VERSION - POST FEATURE REQUESTS HERE Pin
Jacob Klint17-Apr-07 19:03
memberJacob Klint17-Apr-07 19:03 
GeneralRe: NEW VERSION - POST FEATURE REQUESTS HERE Pin
UltraWhack24-Apr-07 6:00
memberUltraWhack24-Apr-07 6:00 
GeneralFox Pro Pin
robertovo8-Apr-07 12:16
memberrobertovo8-Apr-07 12:16 
GeneralActivex Pin
robertovo8-Apr-07 12:13
memberrobertovo8-Apr-07 12:13 
GeneralThank you Pin
jonzieBoy4-Apr-07 23:36
memberjonzieBoy4-Apr-07 23:36 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web03 | 2.8.150728.1 | Last Updated 10 Aug 2006
Article Copyright 2006 by Jacob Klint
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid