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.

Retrieving the Current Volume

When the form first loads we want the trackbars to show the current volume for the left and right channels. We'll use the wavOutGetVolume function to retrieve this combined information. To obtain the left channel volume we can use the AND logical bitwise operator to remove the higher order bits. For the right channel we need to shift the bits to the right before using the AND operator. This gives us two sixteen bit values that we can apply to the trackbar Value properties.

The code for this is shown below. Add a call to ShowCurrentVolume to the constructor and create the new method as follows:

public VolumeForm()
{
    InitializeComponent();
    ShowCurrentVolume();
}

private void ShowCurrentVolume()
{
    uint volume;
    waveOutGetVolume(IntPtr.Zero, out volume);
    int left = (int)(volume & 0xFFFF);
    int right = (int)((volume >> 16) & 0xFFFF);
    LeftVolumeSlider.Value = left;
    RightVolumeSlider.Value = right;
}

Autobalance

The Autobalance checkbox needs a little code for its CheckChanged event. If the checkbox is cleared no action is required, as the volume is unaffected. When the checkbox is ticked, we need to make sure that both channels have the same volume. We could do this by changing the lower of the two volumes to match the higher, change the higher volume to match the lower or move both to the average of the two. In the sample application I chose to average the two volumes.

Add the CheckChanged event to the Autobalance checkbox and include the code shown below.

private void Autobalance_CheckedChanged(object sender, EventArgs e)
{
    if (Autobalance.Checked)
    {
        int volume = (LeftVolumeSlider.Value + RightVolumeSlider.Value) / 2;
        LeftVolumeSlider.Value = volume;
        RightVolumeSlider.Value = volume;
        SetVolume();
    }
}

The SetVolume method uses waveOutSetVolume to set the volume for each channel according to the values in the trackbars. The 32-bit integer is calculated by shifting the right channel value sixteen places to the left to occupy the higher order bits and adding the left channel value in the lower order bits.

private void SetVolume()
{
    uint volume = (uint)(LeftVolumeSlider.Value + (RightVolumeSlider.Value << 16));
    waveOutSetVolume(IntPtr.Zero, volume);
}

Left and Right Channel Controls

When the value in either trackbar is changed, we'll update the volume immediately. If the Autobalance checkbox is checked, We'll modify the other trackbar so that the two values match. To include this functionality, add Scroll events to both trackbars and include the code below:

private void LeftVolumeSlider_Scroll(object sender, EventArgs e)
{
    if (Autobalance.Checked) RightVolumeSlider.Value = LeftVolumeSlider.Value;
    SetVolume();
}

private void RightVolumeSlider_Scroll(object sender, EventArgs e)
{
    if (Autobalance.Checked) LeftVolumeSlider.Value = RightVolumeSlider.Value;
    SetVolume();
}

Mute Button

Let's quickly add the code for the Mute button. Add a Click event handler as shown below.

private void MuteButton_Click(object sender, EventArgs e)
{
    SendMessage(this.Handle, WM_APPCOMMAND, IntPtr.Zero, (IntPtr)APPCOMMAND_VOLUME_MUTE);
}

Play Button

Finally we need to add the Click event code for the Play button. This button plays a WAV file so that the new volumes can be tested. Before adding the code, you need to add a WAV file to the project using the Solution Explorer. Any file provided by Windows will suffice. Once added, use the Solution Explorer to rename the file to "Test.wav" and modify the file's "Copy to Output Folder" property to "Copy Always".

With the test file available, add the following code to the Click event for the button.

private void PlayButton_Click(object sender, EventArgs e)
{
    SoundPlayer player = new SoundPlayer();
    player.SoundLocation = "Test.wav";
    player.Play();
}

You can now execute the program and try out the controls. If you open the Windows Volume Mixer utility, you can see that it mirrors the volume changes. Depending upon the version of Windows that you are using, the changes will affect either the master volume for the operating system or the specific volume for the current program. Note that the Volume Mixer shows the volume of the louder of the two channels for stereo devices.

24 February 2012