Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Get and Set System Volume in Windows

I wanna set the OS volume on a certain level on keyboard click using unity and c# for example I wanna set the Windows volume(Not the unity) to 70: How Can I do that???

void Update()
{   
    if (Input.GetKeyDown(KeyCode.A))
    {
        //Set Windows Volume 70%      
    }
}
like image 791
Ammar Ismaeel Avatar asked Jun 06 '18 13:06

Ammar Ismaeel


People also ask

How can I increase my System volume?

4. Look for physical volume controls for your speakers. Turn volume knobs clockwise to increase volume, or press the "+" button to increase volume. Most desktop speakers have a volume control on the right-front speaker.

How do I get full volume on Windows 10?

In Windows 10, go to “Settings -> System -> Sound” or select “Sound mixer options” from the Start menu. You can also right-click the volume icon in the taskbar, then click “Open Volume mixer.”


1 Answers

This requires a plugin. Since this question is for Windows, you can use IAudioEndpointVolume to build a C++ plugin then call it from C#. This post has a working C++ example of how to change volume with IAudioEndpointVolume and you can use it as the base source to create the C++ plugin.


I've gone ahead and cleaned that code up then converted into a dll plugin and placed the DLL at Assets/Plugins folder. You can see how to build the C++ plugin here.

The C++ code:

#include "stdafx.h"
#include <windows.h>
#include <mmdeviceapi.h>
#include <endpointvolume.h>

#define DLLExport __declspec(dllexport)

extern "C"
{
    enum class VolumeUnit {
        Decibel,
        Scalar
    };

    //Gets volume
    DLLExport float GetSystemVolume(VolumeUnit vUnit) {
        HRESULT hr;

        // -------------------------
        CoInitialize(NULL);
        IMMDeviceEnumerator *deviceEnumerator = NULL;
        hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_INPROC_SERVER, __uuidof(IMMDeviceEnumerator), (LPVOID *)&deviceEnumerator);
        IMMDevice *defaultDevice = NULL;

        hr = deviceEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &defaultDevice);
        deviceEnumerator->Release();
        deviceEnumerator = NULL;

        IAudioEndpointVolume *endpointVolume = NULL;
        hr = defaultDevice->Activate(__uuidof(IAudioEndpointVolume), CLSCTX_INPROC_SERVER, NULL, (LPVOID *)&endpointVolume);
        defaultDevice->Release();
        defaultDevice = NULL;

        float currentVolume = 0;
        if (vUnit == VolumeUnit::Decibel) {
            //Current volume in dB
            hr = endpointVolume->GetMasterVolumeLevel(&currentVolume);
        }

        else if (vUnit == VolumeUnit::Scalar) {
            //Current volume as a scalar
            hr = endpointVolume->GetMasterVolumeLevelScalar(&currentVolume);
        }
        endpointVolume->Release();
        CoUninitialize();

        return currentVolume;
    }

    //Sets volume
    DLLExport void SetSystemVolume(double newVolume, VolumeUnit vUnit) {
        HRESULT hr;

        // -------------------------
        CoInitialize(NULL);
        IMMDeviceEnumerator *deviceEnumerator = NULL;
        hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_INPROC_SERVER, __uuidof(IMMDeviceEnumerator), (LPVOID *)&deviceEnumerator);
        IMMDevice *defaultDevice = NULL;

        hr = deviceEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &defaultDevice);
        deviceEnumerator->Release();
        deviceEnumerator = NULL;

        IAudioEndpointVolume *endpointVolume = NULL;
        hr = defaultDevice->Activate(__uuidof(IAudioEndpointVolume), CLSCTX_INPROC_SERVER, NULL, (LPVOID *)&endpointVolume);
        defaultDevice->Release();
        defaultDevice = NULL;

        if (vUnit == VolumeUnit::Decibel)
            hr = endpointVolume->SetMasterVolumeLevel((float)newVolume, NULL);

        else    if (vUnit == VolumeUnit::Scalar)
            hr = endpointVolume->SetMasterVolumeLevelScalar((float)newVolume, NULL);

        endpointVolume->Release();

        CoUninitialize();
    }
}

The C# code:

using System.Runtime.InteropServices;
using UnityEngine;

public class VolumeManager : MonoBehaviour
{
    //The Unit to use when getting and setting the volume
    public enum VolumeUnit
    {
        //Perform volume action in decibels</param>
        Decibel,
        //Perform volume action in scalar
        Scalar
    }

    /// <summary>
    /// Gets the current volume
    /// </summary>
    /// <param name="vUnit">The unit to report the current volume in</param>
    [DllImport("ChangeVolumeWindows")]
    public static extern float GetSystemVolume(VolumeUnit vUnit);
    /// <summary>
    /// sets the current volume
    /// </summary>
    /// <param name="newVolume">The new volume to set</param>
    /// <param name="vUnit">The unit to set the current volume in</param>
    [DllImport("ChangeVolumeWindows")]
    public static extern void SetSystemVolume(double newVolume, VolumeUnit vUnit);

    // Use this for initialization
    void Start()
    {
        //Get volume in Decibel 
        float volumeDecibel = GetSystemVolume(VolumeUnit.Decibel);
        Debug.Log("Volume in Decibel: " + volumeDecibel);

        //Get volume in Scalar 
        float volumeScalar = GetSystemVolume(VolumeUnit.Scalar);
        Debug.Log("Volume in Scalar: " + volumeScalar);

        //Set volume in Decibel 
        SetSystemVolume(-16f, VolumeUnit.Decibel);

        //Set volume in Scalar 
        SetSystemVolume(0.70f, VolumeUnit.Scalar);
    }
}

The GetSystemVolume function is used to get the current volume and SetSystemVolume is used to set it. This question is for Windows but you can do a similar thing with the API for other platforms.

To set it to 70% when A key is pressed:

void Update()
{
    if (Input.GetKeyDown(KeyCode.A))
    {
        //Set Windows Volume 70%  
        SetSystemVolume(0.70f, VolumeUnit.Scalar);
    }
}
like image 121
Programmer Avatar answered Oct 19 '22 21:10

Programmer