Digital Peak Level Meter
I am currently embarking on a new project where I will be emulating hardware Input/Output device and sensors. To this end there is need of some standard hardware controls that require to be emulated. Luckily a number of these controls are easily derived from standard controls already available within both WPF and Silverlight. The post looks at the first of these controls – a digital peak level meter Many of you used or at least seen these displays on today’s digital HIFI equipment – the more gaudy ones have lots of flashing lights that seems to go with today’s musical tastes.
The goal of the blog is to produce a stereo digital peak level meter similar to the one below.
The simplest starting point is to consider what is already available in Silverlight and WPF. Here the choice is quite simple – the progress bar will suffice once it has been restyled. Remember that we can consider the “progress” as the current level from our input source.
The following tools will be used in the preparation of control:
- Expression Blend
- Visual Studio 2010
The project is split into the following parts:
- Definition of the UX along with the look.
- The attached property that converts a value into a discrete “level” to be displayed.
- The dynamics of displaying discrete levels without resorting to C# wherever possible – always a personal challenge.
- The test application
What I will not be covering will include producing a production standard “look-less” control with a nice design time experience and I18N support although the finished private version will include such features. However, I have already covered all of these topics elsewhere in this blog.
The basic control uses colour to indicate levels similar to the actual hardware device; green for the major part of the display i.e. everything in the normal range. Yellow is used for levels that will have an effect on the data recording process and red will be used for those levels that should cause concern. A final white level indicates some sort of “clipping” of the levels. The green range contains 32 levels, the yellow 22, the red 9 and the final white one – a total of 64. Of course there can be more or less of these levels as required. The colours are defined as Brushes as follows:
<SolidColorBrush x:Key="GreenBlockBrush" Color="#FF17F317" /> <SolidColorBrush x:Key="YellowBlockBrush" Color="#FFFBFC01" /> <SolidColorBrush x:Key="RedBlockBrush" Color="#FFE80705" /> <SolidColorBrush x:Key="WhiteBlockBrush" Color="White" />
Each level is defined as a Rectangle that is either visible or not. I have applied a minimal with for each level as well as minimum distance separating the levels. The standard widths are 4pixels for the level and 2pixels for the separator. These are defined as the column width detail and not on the rectangles themselves. The basic layout, showing the second level filled, in Blend is:
The Level Conversion Attached Property
The attached property catches changes on the Progress Bar’s Value property and converts them into the output level. As this a cumulative display the actual number of blocks needs to be calculated and the correct colouring applied. To properly achieve this we need to trigger a filling of the correct number of levels that reflect the input value
Once this property has been attached to the Progress Bar changes in value will result in the correct number of blocks being shown.
The real work gets done to display the levels. The property changed event of the Progress Bar triggers the displaying (filling here) of the rectangles. Pretty simple stuff but very effective. The down side to this approach is that each bar is filled depending on the value assigned to the Level property of the LevelHelper class. Hence for the 32nd bar to be displayed all the bars up until this point will also be displayed i.e. 32 fills are performed on this trigger leading to a huge amount of XAML. However, it seems to work without any appreciable flashing or delay.
The Test Application
To see the digital peak level meter in action I have a simple WFP application with the custom progress bar data bound to the value of a slider. As the slider moves the number of levels is displayed that is associated with the slider value. In a real world application data binding to a source of fast changing values can result in some strange side effects. Hence it recommended that the data source averages or a set of values before updating the custom progress bar.
That’s all Folks…