Last active
October 5, 2015 16:56
-
-
Save surinkim/efe4782d0efb501f692d to your computer and use it in GitHub Desktop.
xp audio handling
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
이 클래스는 xp이면, Windows Audio Mixer API를, | |
vista 이후 버전이면, WASAPI를 사용하여 Speaker/Mic를 제어할 수 있게 한다. | |
참고로, WASAPI(Windows Audio Session API)는 vista 이후 버전만 지원한다. | |
Windows Audio Mixer API로도, vista 이후 버전에서 speaker 장치의 대부분 기능을 제어할 수 있지만, | |
결정적으로, Master Volume을 조정할 수 없는 약점이 있다. | |
Mic 제어는 Windows Audio Mixer API로 xp/win7 모두 제어가능하다. | |
따라서, Mic 제어는 os 구분없이 Windows Audio Mixer API를 사용한다. | |
*/ | |
#ifndef AUDIO_WRAPPER_H_ | |
#define AUDIO_WRAPPER_H_ | |
#include <Windows.h> | |
#include <WinDef.h> | |
#include <string> | |
#include <vector> // to remove | |
#include <QMetaType> // to remove | |
#include <mmdeviceapi.h> | |
#include <endpointvolume.h> | |
#include <audiopolicy.h> | |
#pragma comment( lib, "Winmm.lib") | |
// to remove | |
struct OutputDeviceInfo | |
{ | |
OutputDeviceInfo() : m_name(L""), m_mixer( NULL ), m_masterLineId( 0 ), m_waveLineId( 0 ) {}; | |
std::wstring m_name; | |
HMIXER m_mixer; | |
DWORD m_masterLineId; | |
DWORD m_waveLineId; | |
}; | |
Q_DECLARE_METATYPE( OutputDeviceInfo ); | |
struct InputDeviceInfo | |
{ | |
InputDeviceInfo() : m_name(L""), m_mixer( NULL ), m_channelCount( 0 ), m_micVolumeControlId( 0 ), m_lineId( 0 ) {}; | |
std::wstring m_name; | |
HMIXER m_mixer; | |
DWORD m_channelCount; | |
DWORD m_micVolumeControlId; | |
DWORD m_micMuteControlId; | |
DWORD m_lineId; | |
}; | |
Q_DECLARE_METATYPE( InputDeviceInfo ); | |
class AudioWrapper | |
{ | |
public: | |
AudioWrapper(void); | |
~AudioWrapper(void); | |
static bool IsVistaLater(); | |
bool Init(); | |
// 마스터 볼륨 조정( xp, win7 별도) | |
bool SetMasterVolume( std::wstring deviceName, std::wstring deviceId, const int volume ); | |
int GetMasterVolume( std::wstring deviceName, std::wstring deviceId ); | |
bool SetMasterMute( std::wstring deviceName, std::wstring deviceId, int state ); | |
bool GetMasterMute( std::wstring deviceName, std::wstring deviceId ); | |
// 웨이브 볼륨 조정( xp, win7 별도) | |
bool SetWaveVolume( std::wstring deviceName, const int volume ); | |
int GetWaveVolume( std::wstring deviceName ); | |
bool SetWaveMute( std::wstring deviceName, int state ); | |
bool GetWaveMute( std::wstring deviceName ); | |
// 마이크 조정( xp, win7 공용 ) | |
bool SetMicVolume( std::wstring deviceName, int value ); | |
int GetMicVolume( std::wstring deviceName ); | |
bool SetMicMute( std::wstring deviceName, int state ); | |
bool GetMicMute( std::wstring deviceName ); | |
// to remove | |
std::vector< OutputDeviceInfo > GetSpeakerDevices(); // Get Speaker Devices | |
std::vector< InputDeviceInfo > GetMicDevices(); // Get Mic Devices | |
void SetCurrentSpeakerDevice( OutputDeviceInfo info ) { m_curOutputDevice = info; } | |
void SetCurrentMicDevice( InputDeviceInfo info ) { m_curInputDevice = info; } | |
private: | |
// xp 전용 control type | |
enum ControlType | |
{ | |
MASTER = 0, | |
WAVE, | |
}; | |
// 캐싱되는 마이크 Device 정보( xp/win7 공용 ) | |
struct MicDevice | |
{ | |
HMIXER m_mixer; | |
MIXERLINE m_mixerLine; | |
MIXERCONTROL m_mixerVolumeControl; // 마이크 볼륨 컨트롤 | |
MIXERCONTROL m_mixerMuteControl; // 마이크 mute 컨트롤 | |
}; | |
// 캐싱되는 스피커 Device 정보( xp 전용 ) | |
struct SpeakerDevice | |
{ | |
HMIXER m_mixer; | |
MIXERLINE m_mixerMasterLine; // 마스터 볼륨 line id | |
MIXERLINE m_mixerWaveLine; // 웨이브 볼륨 line id | |
}; | |
// master volume | |
bool SetMasterVolumeWin7( std::wstring deviceId, const int volume ); | |
bool SetMasterVolumeXp( std::wstring deviceName, const int volume ); | |
int GetMasterVolumeWin7( std::wstring deviceId ); | |
int GetMasterVolumeXp( std::wstring deviceName ); | |
bool SetMasterMuteWin7( std::wstring deviceId, int state ); | |
bool SetMasterMuteXp( std::wstring deviceName, int state ); | |
bool GetMasterMuteWin7( std::wstring deviceId ); | |
bool GetMasterMuteXp( std::wstring deviceName ); | |
// wave volume | |
bool SetWaveVolumeWin7( const int volume ); | |
bool SetWaveVolumeXp( std::wstring deviceName, int value ); | |
int GetWaveVolumeWin7(); | |
int GetWaveVolumeXp( std::wstring deviceName ); | |
bool SetWaveMuteWin7( int state ); | |
bool SetWaveMuteXp( std::wstring deviceName, int state ); | |
bool GetWaveMuteWin7(); | |
bool GetWaveMuteXp( std::wstring deviceName ); | |
// helper functions | |
bool FindDevice( std::wstring deviceId, IMMDevice **pDevice ); //device id로 IMMDevice를 찾음. | |
bool FindControl( IAudioSessionControl2 **pControl2 ); //현재 process id로 IAudioSessionControl2를 찾음. | |
bool GetMixerCaps( const std::wstring deviceName, HMIXER& findMixer, const int mixerLineType, MIXERCAPS& findMixerCaps ); | |
bool GetMixerLine( const HMIXER& mixer, const MIXERCAPS& mixerCaps, const int mixerLineType, MIXERLINE& findMixerLine ); | |
bool GetMixerWaveLine( const HMIXER& mixer, const MIXERLINE& mixerLine, MIXERLINE& findMixerLine ); | |
bool GetMixerControl( const HMIXER& mixer, const MIXERLINE& mixerLine, const int controlType, MIXERCONTROL& findControl ); | |
bool GetMicDeviceInfo( std::wstring deviceName, MicDevice& micDevice ); //cache MicDevice | |
bool GetSpeakerDeviceInfo( std::wstring deviceName, SpeakerDevice& speakerDevice ); //cache SpeakerDevice | |
// xp 전용 function | |
bool SetVolume( ControlType type, std::wstring deviceName, int value ); | |
int GetVolume( ControlType type, std::wstring deviceName ); | |
bool SetMute( ControlType type, std::wstring deviceName, int state ); | |
bool GetMute( ControlType type, std::wstring deviceName ); | |
std::map< std::wstring, MicDevice> m_mapMicDevice; //한번이라도 검색된 마이크 mixer 정보를 저장하기 위한 map; | |
std::map< std::wstring, SpeakerDevice> m_mapSpeakerDevice; //한번이라도 검색된 스피커 mixer 정보를 저장하기 위한 map; | |
bool m_isVistaLater; //비스타 이후 버전이면 true, 이전 버전이면 false | |
DWORD m_curPid; //현재 프로세스 id | |
// to remove | |
OutputDeviceInfo m_curOutputDevice; | |
InputDeviceInfo m_curInputDevice; | |
}; | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment