Introduction
This article serves as a usage manual for a UserControl I created called AnalogSignalMeter
. This control uses Direct3D to paint the control, and DirectSound to sample the audio signal.
Background
I am a sound tech at my church, and I am currently developing some software. One of the items I needed was a signal level meter. I decided to create my own, and this is the result.
Demo
The demo program is a basic form that demonstrates the control. There are also controls that let you modify the properties of the control.
AnalogSignalMeter Public Properties
The following properties are available to you for modification:
BackgroundColor
LowLedColor
MidLedColor
HighLedColor
LowLedCount
MidLedCount
HighLedCount
LedHeight
LedWidth
LeftMargin
RightMargin
BottomMargin
TopMargin
LeftRightSeperation
UpDownSeperation
DisplayOrientation
AudioDisplayMode
MeterMode
SampleFrequencyMilliseconds
AutoStart
ClearMeterOnStop
BackgroundColor
and the three LedColor
properties are pretty straightforward. They control the colors of the meter. The three LedCount
properties control the maximum number of each different LED level. LedHeight
and LedWidth
control the sizing of each individual LED. These properties are relative to the Orientation
of the control. The four Margin
properties control the spacing between the LEDs and the four edges of the control. They too are relative to the Orientation
of the control. LeftRightSeperation
and UpDownSeperation
control the spacing between each LED. These properties are also relative to the Orientation
of the control.
DisplayOrientation
has four possibilities: Horizontal
, HorizontalReverse
, Vertical
, and VerticalReverse
. Horizontal
draws the LEDs from least to greatest as left to right. HorizontalReverse
is the opposite of this. Vertical
draws the LEDs from least to greatest as top to bottom. VerticalReverse
is the opposite of this. The orientation pictured at the top of the article is Horizontal
. The most common arrangement to emulate a sound board meter is VerticalReverse
.
AudioDisplayMode
has two possibilities: Stereo
and Mono
. Stereo
samples a unique level for the left and right channels. Mono
samples the left channel for both left and right levels.
MeterMode
has three possible values: AudioSignal
, RandomLevels
, and SpecificLevels
. AudioSignal
tells the meter to run in standard mode, capturing levels from the audio buffer. RandomLevels
tells the meter to report randomly generated levels. SpecificLevels
tells the meter to report the same level constantly.
SampleFrequencyMilliseconds
controls how often the control samples the signal level, and is measured in milliseconds, thousandths of a second. The default, and probably the best value, is 100. However, feel free to experiment to your own liking.
AutoStart
tells the control whether or not to start when the application loads. This is set to false
, by default. This still needs a bit of tweaking on my part, and will be rectified in the next release.
ClearMeterOnStop
tells the control whether or not to reset the meter to zero when stopped.
The following are read-only properties that you can access.
MeterRunning
TotalLedCount
LeftLevel
RightLevel
MeterRunning
simply tells you whether or not the meter is running. TotalLedCount
returns the total maximum number of LEDs. LeftLevel
and RightLevel
allow you to read the last sampled volume level.
AnalogSignalMeter Public Methods
There are four methods available for your use:
StartMeter()
StartRandomMeter()
StartSpecificMeter(int leftLevel, int rightLevel)
StopMeter()
StartMeter
will start the meter and begin sampling the signal from the sound card. StartRandomMeter
will start the meter, and begin feeding random levels to it. StartSpecificMeter
will start the meter, and feed it a constant static level repeatedly. StopMeter
will stop the meter, and if ClearMeterOnStop
is true
, then the levels will be reset to zero.
You may never need the last two start methods, but they are handy for troubleshooting the meters behavior if you start noticing odd behavior.
AnalogSignalMeter Events
There are three events that the control will trigger:
ReportLevel
LeftSignalPeak
RightSignalPeak
ReportLevel
is triggered whenever a new sample is acquired. It has its own EventArgs
, which contain both levels, args.LeftLevel
, and args.RightLevel
.
LeftSignalPeak
and RightSignalPeak
are triggered any time the sample level equals the total maximum LEDs. This is handy because this means that the audio signal is likely distorted, meaning a loss of quality, and it would be a signal to reduce the gain of the incoming signal. This event has its own EventArgs
, which contains the Channel
that peaked, args.Channel
, and also a message, args.Message
.
AnalogSignalMeter Tips
As mentioned above, AutoStart
needs tweaking. If you wish for the meter to auto start, set AutoStart
to true
in the design stage, and then have your form check the property, and call the StartMeter
method accordingly.
If you don't like the look of the meter but want the functionality, there is an alternative, which you can view in the demo application. You can set the control visibility to false
, and in your ReportLevel
handler, you can use the levels to set a progress bar value. Set the progress bar maximum to the TotalLedCount
value, and then have the ReportLevel
event handler set the progress bar value to the args.LeftLevel
or args.RightLevel
value. You can make a separate progress bar for each channel if you like. There is a nice gradient style progress bar available from someone on CodeProject. It can be used to mimic the separate color values for lower or higher signal levels.
History
September 21, 2007 - New Release Posted
I have uploaded a new release of both BuckSoft.DirectSound, and AnalogSignalMeterDemo.
BuckSoft.DirectSound
- Added a new public property,
MeterMode
, along with an enumeration of values for it. This property tells the meter to run in either audio signal mode, random levels mode, or specific levels mode. The lack of this property is why the meter would always restart back into random mode when changing other properties with the demo.
AnalogSignalMeterDemo
- Fixed the "Always restarts in random mode" bug.
- Progress bar updates and level labels updates on the demo were handled in an unsafe thread call, this has been fixed.
- Fixed the bug that caused a crash when LedCounts were increased
September 17, 2007 - Complete Source Code Added
On my initial post, I neglected to post the complete source code for the control. Now it is available.
September 14, 2007 - Initial Posting
Feel free to make suggestions for additions or improvements. I am still fresh to C# and DirectX, and welcome any insight that anyone may have to offer.
Disclaimer
This control is free to use and redistribute as you please. It is a work in progress. Use at your own risk.