티스토리 뷰

반응형

[유니티/unity] 시스템 볼륨 제어하기(win 32 dll 이용)

 

출저:https://stackoverflow.com/questions/50722026/how-to-get-and-set-system-volume-in-windows

 

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 (I...

stackoverflow.com

 

이전 방법 https://gofogo.tistory.com/146

 

[c#/unity] 시스템 볼륨(system volumn) 제어하기 ( CoreAudio 사용)

[c#/unity]  시스템 볼륨(system volumn) 제어하기 ( CoreAudio 사용) # Nuget Package에서 coreAudio를 받아서 버전에 맞게 설치한다. #다운로드를 받은 후 기본 헬퍼 클래스를 만든다. public class Sy..

gofogo.tistory.com

 

유니티에서는 원활하게 작동하지 않는다,

유니티의 라이프 사이클로 인하여 객체 생성 타이밍이 맞지 않아서그렇다.

 

이를 해결하기 위해 위 스택 오버플로우를 통하여 win32 dll을 생성하여, 유니티에 적용하는 방법을 진행해보니 아주 원활하게 잘 개발 되었다.

 

visual studio 2017 기준 

 

1. Windows 데스크톱 마법사를 실행 후 [확인]

 

2.프로젝트 설정

-응용프로그램 종류를 dll로, 미리컴파일된 헤더를 해지한다.

 

2-2. 파일구조

3.헤더 선언(.h) 헤더파일을 만든 후  다음 내용 기록

#ifndef FIRSTDLL_NATIVE_LIB_H
#define FIRSTDLL_NATIVE_LIB_H

#define DLLExport __declspec(dllexport)

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

	DLLExport float GetSystemVolume(VolumeUnit vUnit);
	DLLExport void SetSystemVolume(double newVolume, VolumeUnit vUnit);
}
#endif

 

3.cpp 정의(.cpp) cpp파일 만든 후  다음 내용 기록

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

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;
}

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();
}

 

4.빌드타입 변경 후 빌드

 

5.release 폴더로 이동하여, dll,lib 파일 복사

 

6.유니티 프로젝트에 Assets/plugins로 복사

 

7.스크립트를 생성하여 다음과 같이 내용 기록

-[DllImport] 에는 dll을 만들었던 프로젝트 이름을 기록

-public static extern float 에는 .h파일에 있던 함수 정보를 기록

-아래 코드와 같이, 해당함수를 불러서 사용하면됨

public class scr : MonoBehaviour
{
    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("Project1")]
    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("Project1")]
    public static extern void SetSystemVolume(double newVolume, VolumeUnit vUnit);

    void Start()
    {
    }

    // Update is called once per frame
    void Update()
    {

        if(Input.GetKeyUp(KeyCode.A)){
            SetSystemVolume(0.00f, VolumeUnit.Scalar);

        }
        else if (Input.GetKeyUp(KeyCode.B))
        {
            SetSystemVolume(0.50f, VolumeUnit.Scalar);
        }
        else if (Input.GetKeyUp(KeyCode.C))
        {
            SetSystemVolume(1.00f, VolumeUnit.Scalar);
        }


    }
}

 

 #유니티 볼륨 조절 #시스템 볼륨 조절 #윈도우 볼륨조절 #dll #win32 

반응형
댓글
반응형