BlackWaspTM

This web site uses cookies. By using the site you accept the cookie policy.This message is for compliance with the UK ICO law.

Audio
.NET 1.1+

Controlling the Wave Device Volume

The wave device volume determines how loudly sounds are played, either for the current application or for the entire operating system. This volume can be adjusted for the left and right channels independently using Windows API functions.

Wave Device Volume

Many computers include a sound card or a built-in chipset that allows you to play digital audio such as that in the waveform audio file format (WAV). Some hardware provides single channel, or mono, output. Other hardware gives stereo sound, with separate audio channels for the left and right speakers. For some software applications you may wish to control the volume of these channels, either independently or together.

Older versions of Microsoft Windows allow you to modify the volume for all applications using Windows API functions, which you may call using Platform Invocation Services (P/Invoke). More modern versions of the operating system allow the wave device volume to be changed for applications independently, allowing the user to lower the volume for some software and increase it for other programs.

In this article we'll create a Windows Forms project that allows the volume to be changed. We'll include the ability to synchronise the left and right channels or change them independently. We'll also add a mute button and a button that plays a sound. You can download the sample program using the link at the top of this page.

Windows API Functions

We'll use two Windows API functions to work with the wave device volume. The first is waveOutGetVolume. This gives you a 32-bit integer value that represents the volumes of the two channels. The lower sixteen bits hold a value from zero to 65,535. Zero indicates silence and 65,535 is the maximum volume possible. The higher sixteen bits hold a similar value for the right channel. For mono devices, the two values match.

The waveOutSetVolume function allows you to change the volume. Again, you use a 32-bit integer with the left channel volume in the lower order bits and the right channel volume in the upper order bits.

To use the Windows API functions we need to access types from the System.Runtime.InteropServices namespace. We'll also be using the System.Media namespace, so include the following using directives in your code. If you wish to recreate the sample program, add this to the code-behind for the default form in a Windows Form project.

using System.Media;
using System.Runtime.InteropServices;

You can now add the two Windows API function declarations. Each uses an unsigned integer parameter for the volume. For retrieving the volumes this is an output parameter.

[DllImport("winmm.dll")]
public static extern int waveOutGetVolume(IntPtr hwo, out uint pdwVolume);

[DllImport("winmm.dll")]
public static extern int waveOutSetVolume(IntPtr hwo, uint dwVolume);

Although not directly related to the wave device volume functions, we'll also add a mute button to the sample program. I've described the use of this function in the article, "Basic Volume Control", so I won't repeat the information here. To support the mute feature, add the following:

[DllImport("user32.dll")]
static extern IntPtr SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);

const int WM_APPCOMMAND = 0x319; 
const int APPCOMMAND_VOLUME_MUTE = 0x80000;

Windows Form Design

We can now add some controls to the Windows Form that will allow the user to modify the volume and listen to the effect. We need five controls. Two trackbars will permit the left and right channel volumes to be changed. We'll use a checkbox to signify if we want the two channels to be synchronised automatically. Finally, we need two buttons. One mutes and unmutes the sound. The other plays a test sound so that you can hear the change in volume.

Control NameTypePropertiesPurpose
LeftVolumeSliderTrackBarLargeChange = 2,048
Minimum = 0
Maximum = 65,535
Orientation = Vertical
SmallChange = 256
TickFrequency = 2,048
Shows the left channel volume
RightVolumeSliderTrackBarLargeChange = 2,048
Minimum = 0
Maximum = 65,535
Orientation = Vertical
SmallChange = 256
TickFrequency = 2,048
Shows the right channel volume
AutobalanceCheckboxChecked = falseSpecifies whether the left and right volumes should always be the same.
MuteButtonButtonText = "Mute"Mutes and unmutes the volume.
PlayButtonButtonText = "Play Test"Plays a test sound.

The image below shows a possible layout for the controls.

Volume Control Demo Window Layout

24 February 2012