Change program's volume on Win 7
Asked Answered
A

2

7

I want to change the program's volume (and not master volume). I have the following code right now:

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

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

private void volumeBar_Scroll(object sender, EventArgs e)
{
    // Calculate the volume that's being set
    int NewVolume = ((ushort.MaxValue / 10) * volumeBar.Value);
    // Set the same volume for both the left and the right channels
    uint NewVolumeAllChannels = (((uint)NewVolume & 0x0000ffff) | ((uint)NewVolume << 16));
    // Set the volume
    waveOutSetVolume(IntPtr.Zero, NewVolumeAllChannels);
}

This only works on Win XP, not Windows 7 (and probably Vista neither). I've not found any script that will achieve the same on Win 7, only to change the master volume (which I am not after).

Ansela answered 23/4, 2012 at 17:0 Comment(0)
A
6

Your code worked ok for me (with a couple of tweaks). Here's the code for a very simple WPF test app running on Windows 7 x64:

Xaml

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Slider Minimum="0" Maximum="10" ValueChanged="ValueChanged"/>
    </Grid>
</Window>

C#

public partial class MainWindow
{
    public MainWindow()
    {
        InitializeComponent();
    }

    private void ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
    {
        // Calculate the volume that's being set
        double newVolume = ushort.MaxValue * e.NewValue / 10.0;

        uint v = ((uint) newVolume) & 0xffff;
        uint vAll = v | (v << 16);

        // Set the volume
        int retVal = NativeMethods.WaveOutSetVolume(IntPtr.Zero, vAll);

        Debug.WriteLine(retVal);

        bool playRetVal = NativeMethods.PlaySound("tada.wav", IntPtr.Zero, 0x2001);

        Debug.WriteLine(playRetVal);
    }
}

static class NativeMethods
{
    [DllImport("winmm.dll", EntryPoint = "waveOutSetVolume")]
    public static extern int WaveOutSetVolume(IntPtr hwo, uint dwVolume);

    [DllImport("winmm.dll", SetLastError = true)]
    public static extern bool PlaySound(string pszSound, IntPtr hmod, uint fdwSound);
}

When I start the app and move the slider, then an additional volume control appears in the 'Volume Mixer' which moves from min to max synchronously with the slider.

You should examine the return value from waveOutSetVolume. It may give you a clue if your code still doesn't work.

Abridgment answered 25/4, 2012 at 18:54 Comment(7)
I'm using this code: pastebin.com/RcRjfBu4 however the debug gives me 0. The volume doesn't change either.Ansela
Retval=0 means success, so no luck there. As I said it works for me. I assume you have Win7 SP1. I also have VS11 beta installed - which may have fixed something.Abridgment
Ok, I can confirm it's working (only half though). When sliding the slider I do see the volume changing (only visual wise) - have a look at dl.dropbox.com/u/6166898/slider.png. But the volume is not changed! When I manually slide the Windows volume slider it does change, but not from within the program. Am I missing something here?Ansela
I tried playing a Windows .wav. Works for me. Volume changes as expected.Abridgment
Hmmph. Could it be because I'm using a WebBrowser object? Again it worked fine in XP. However this strange issue (ie. slider going down but sound isn't, but manually sliding does) makes no sense.Ansela
You may be onto something there. I'm sure the security/sandboxing for IE9 is much stricter than whatever you have on XP (IE6?). This may mean you can't change the volume for content in the webbrowser.Abridgment
Alright, thanks. You answered my initial question :-) I've opened a new question regarding this issue.Ansela
T
1

You can use the Audio session APIs IAudioVolume and IAudioSessionNotification to modify the current apps volume and to track your volume with the volume slider in the app.

You can find a list of samples of their use in Larry Osterman's blog article

The easiest to use is the ISimpleVolume interface. It's discussed in Larry's blog as well.

Teutonic answered 25/4, 2012 at 17:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.