771 lines
No EOL
23 KiB
C++
771 lines
No EOL
23 KiB
C++
#include "StdAfx.h"
|
||
#ifdef _USE_VOICECHAT
|
||
#include "VoiceChatClient.h"
|
||
|
||
#ifdef _DEBUG
|
||
#define new new(_NORMAL_BLOCK,__FILE__,__LINE__)
|
||
#endif
|
||
|
||
const float g_fVoiceChatVolumeRate = 2.0f;
|
||
|
||
CVoiceChatClient::CVoiceChatClient(void)
|
||
{
|
||
m_pClient = NULL;
|
||
m_nNumDevice = 0;
|
||
m_Devices = NULL;
|
||
m_fVoiceChatVolume = 0.5f;
|
||
|
||
m_hMixer = NULL;
|
||
m_fMicVolume = 0.5f;
|
||
#if defined(DOLBY_CLIENT_LOG)
|
||
logout = NULL;
|
||
#endif
|
||
m_fOrigMicVolume = 0.5f;
|
||
}
|
||
|
||
CVoiceChatClient::~CVoiceChatClient(void)
|
||
{
|
||
SAFE_DELETE( m_Devices );
|
||
#if defined(DOLBY_CLIENT_LOG)
|
||
fclose(logout);
|
||
#endif
|
||
ICEClient_DestroyIceClient( m_pClient );
|
||
RestoreOrigMicConfig();
|
||
FinalizeMicControl();
|
||
}
|
||
|
||
#if defined(DOLBY_CLIENT_LOG)
|
||
void CVoiceChatClient::logging(unsigned int level, const char *msg, void *rock)
|
||
{
|
||
fprintf((FILE*)rock, "%s\n", msg);
|
||
fflush((FILE*)rock);
|
||
}
|
||
#endif
|
||
|
||
bool CVoiceChatClient::Initialize( const char *pServerIP, unsigned short nServerPort, const char *pUserName, UINT nPrivateID, VOICE_CHAT_CODEC Codec )
|
||
{
|
||
m_pClient = ICEClient_CreateIceClient();
|
||
if( !m_pClient )
|
||
{
|
||
return false;
|
||
}
|
||
|
||
#if defined(DOLBY_CLIENT_LOG)
|
||
const char* logfile = "DolbyAxonClientLog.txt";
|
||
fopen_s(&logout, logfile, "a+");
|
||
ICEClient_SetLogging(m_pClient, logging, logout, 3);
|
||
#endif
|
||
|
||
ICECLIENT_ERROR IceError = ICEClient_Init( m_pClient, ICECLIENT_ENGINE_DOLBYHEADPHONE );
|
||
if( IceError != ICECLIENT_ERROR_NONE)
|
||
{
|
||
IceError = ICEClient_Init( m_pClient, ICECLIENT_ENGINE_DIRECTX );
|
||
if( IceError != ICECLIENT_ERROR_NONE && IceError != ICECLIENT_ERROR_ALREADY_INITED )
|
||
{
|
||
return false;
|
||
}
|
||
}
|
||
|
||
IceError = ICEClient_SetCodec( m_pClient, Codec );
|
||
if( IceError != ICECLIENT_ERROR_NONE )
|
||
{
|
||
return false;
|
||
}
|
||
|
||
// ÀûÀýÇÑ ·»´õ¸µ ¿£Áø ¼±ÅÃ.
|
||
ICEClient_device OutputDevice;
|
||
IceError = ICEClient_GetOutputDevice( m_pClient, &OutputDevice );
|
||
OutputDevice.enginetype = ICEClient_GetDefaultEngineType( OutputDevice.devtype );
|
||
IceError = ICEClient_SetDevice( m_pClient, &OutputDevice, NULL );
|
||
|
||
//if multigame mode set gameid
|
||
ICEClient_SetID(m_pClient, nPrivateID, 0);
|
||
|
||
ICEClient_SetServer( m_pClient, pServerIP, nServerPort );
|
||
ICEClient_SetName( m_pClient, pUserName );
|
||
//ICEClient_SetPrivateID( m_pClient, nPrivateID );.
|
||
|
||
IceError = ICEClient_AutoTick( m_pClient );
|
||
if( IceError != ICECLIENT_ERROR_NONE )
|
||
{
|
||
return false;
|
||
}
|
||
|
||
ICEClient_TalkInto( m_pClient, true, 0 );
|
||
|
||
// ÇØµµ ¿Ö Àڱ⠸ñ¼Ò¸®°¡ ¾Èµé¸®´ÂÁö.. ¹º°¡ ´Ù¸¥ ¼³Á¤ÀÌ ÇÊ¿äÇѰǰ¡.
|
||
//ICEClient_SetEchoSupression( m_pClient, true );
|
||
|
||
// ÃʱâȵDZâ Àü¿¡ ÇÑ º¼·ý¼ÂÆÃµéÀÌ Àû¿ëµÇµµ·Ï, ÃʱâÈ ÈÄ¿¡ ¼³Á¤µÈ º¼·ýÀ» ´Ù½Ã Çѹø Àû¿ë½ÃŲ´Ù.
|
||
SetVoiceChatVolume( m_fVoiceChatVolume );
|
||
|
||
// ¸¶ÀÌÅ©ÄÁÆ®·ÑÀÌ ÀÖ´ÂÁö È®ÀÎ.
|
||
ICEClient_device InputDevice;
|
||
IceError = ICEClient_GetCaptureDevice( m_pClient, &InputDevice );
|
||
if( IceError == ICECLIENT_ERROR_NONE )
|
||
{
|
||
InitializeMicControl( &InputDevice );
|
||
CheckOrigMicConfig();
|
||
}
|
||
|
||
// ¹Ì¸® ÀåÄ¡¸¦ °Ë»öÇØµÐ´Ù.(±âº»»ý¼ºÀº µðÆúÆ®¸¦ µû¸£°í Áß°£¿¡ °Ë»öµÈ ÀåÄ¡·Î ¹Ù²Ü ¼ö ÀÖ°Ô ÇØÁØ´Ù.)
|
||
m_nNumDevice = 0;
|
||
ICEClient_GetDeviceList( m_Devices, &m_nNumDevice );
|
||
if( !m_nNumDevice )
|
||
{
|
||
SAFE_DELETE( m_Devices );
|
||
}
|
||
else
|
||
{
|
||
m_Devices = (ICEClient_device *)malloc( sizeof(ICEClient_device)*m_nNumDevice );
|
||
IceError = ICEClient_GetDeviceList( m_Devices, &m_nNumDevice );
|
||
if( IceError != ICECLIENT_ERROR_NONE )
|
||
SAFE_DELETE( m_Devices );
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
|
||
void CVoiceChatClient::Finalize()
|
||
{
|
||
CVoiceChatClient *pClient = CVoiceChatClient::GetInstancePtr();
|
||
SAFE_DELETE( pClient );
|
||
}
|
||
|
||
ICEClient_device *CVoiceChatClient::GetDevice( unsigned int nIndex )
|
||
{
|
||
if( !m_Devices ) return NULL;
|
||
if( nIndex < m_nNumDevice ) return &m_Devices[nIndex];
|
||
return NULL;
|
||
}
|
||
|
||
bool CVoiceChatClient::SetDevice( unsigned int nIndex, bool bMic )
|
||
{
|
||
if( !m_pClient ) return false;
|
||
if( !m_Devices ) return false;
|
||
if( nIndex >= m_nNumDevice ) return false;
|
||
|
||
ICECLIENT_ERROR IceError;
|
||
if( bMic )
|
||
IceError = ICEClient_SetDevice( m_pClient, NULL, &m_Devices[nIndex] );
|
||
else
|
||
IceError = ICEClient_SetDevice( m_pClient, &m_Devices[nIndex], NULL );
|
||
|
||
return (IceError == ICECLIENT_ERROR_NONE);
|
||
}
|
||
|
||
bool CVoiceChatClient::GetCaptureDeviceName( std::wstring &wszName )
|
||
{
|
||
if( !m_pClient ) return false;
|
||
|
||
// ¸¶ÀÌÅ©ÄÁÆ®·ÑÀÌ ÀÖ´ÂÁö È®ÀÎ.
|
||
ICEClient_device InputDevice;
|
||
if( ICEClient_GetCaptureDevice( m_pClient, &InputDevice ) == ICECLIENT_ERROR_NONE )
|
||
{
|
||
ToWideString( InputDevice.name, wszName );
|
||
return true;
|
||
}
|
||
return false;
|
||
}
|
||
|
||
bool CVoiceChatClient::IsExistMic()
|
||
{
|
||
if( !m_Devices ) return false;
|
||
for( unsigned int i = 0; i < m_nNumDevice; ++i )
|
||
{
|
||
if( m_Devices[i].devtype == ICECLIENT_DEVICE_CAPTURE )
|
||
return true;
|
||
}
|
||
return false;
|
||
}
|
||
|
||
BYTE CVoiceChatClient::GetSpeaking()
|
||
{
|
||
if( !IsExistMic() ) return 0;
|
||
if( !m_pClient ) return 0;
|
||
|
||
// ¸»Çϰí ÀÖ´Â µµÁßÀÇ Ã¼Å©´Â ¾Æ·¡ ÇÔ¼ö·Î ÇÑ´Ù.
|
||
ICEClient_stat stat = ICEClient_GetStats(m_pClient);
|
||
return stat.talking;
|
||
}
|
||
|
||
void CVoiceChatClient::SetVoiceChatVolume( float fValue )
|
||
{
|
||
if( !m_pClient ) return;
|
||
m_fVoiceChatVolume = fValue * g_fVoiceChatVolumeRate;
|
||
ICEClient_SetVolume( m_pClient, m_fVoiceChatVolume );
|
||
}
|
||
|
||
float CVoiceChatClient::GetVoiceChatVolume()
|
||
{
|
||
return m_fVoiceChatVolume / g_fVoiceChatVolumeRate;
|
||
}
|
||
|
||
void CVoiceChatClient::MuteMyMic( bool bMute )
|
||
{
|
||
if( !m_pClient ) return;
|
||
ICEClient_MuteMic( m_pClient, (bMute ? 1 : 0) );
|
||
}
|
||
|
||
void CVoiceChatClient::SetRotation( int nRotation )
|
||
{
|
||
if( !m_pClient ) return;
|
||
ICEClient_SetRotation( m_pClient, nRotation );
|
||
}
|
||
|
||
void CVoiceChatClient::SetVoiceFont( eVoiceFontType eVoiceFont, float fPitch, float fTimbre )
|
||
{
|
||
if( !m_pClient ) return;
|
||
|
||
switch( eVoiceFont )
|
||
{
|
||
case VoiceFontNone: ICEClient_SetVoiceFont( m_pClient, ICECLIENT_VOICEFONT_NONE ); break;
|
||
case VoiceFontW2M: ICEClient_SetVoiceFont( m_pClient, ICECLIENT_VOICEFONT_PRESET_W2M ); break;
|
||
case VoiceFontM2W: ICEClient_SetVoiceFont( m_pClient, ICECLIENT_VOICEFONT_PRESET_M2W ); break;
|
||
case VoiceFontELF: ICEClient_SetVoiceFont( m_pClient, ICECLIENT_VOICEFONT_PRESET_ELF ); break;
|
||
case VoiceFontCustom:
|
||
{
|
||
ICEClient_voicefont CustomVoiceFont;
|
||
CustomVoiceFont.pitchchange = fPitch;
|
||
CustomVoiceFont.timbrechange = fTimbre;
|
||
ICEClient_SetCustomVoiceFont( m_pClient, CustomVoiceFont );
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
|
||
void CVoiceChatClient::StartMicTestPhase1()
|
||
{
|
||
if( !m_pClient ) return;
|
||
ICEClient_StartMicTestPhase1( m_pClient );
|
||
}
|
||
|
||
void CVoiceChatClient::StartMicTestPhase2( void (*callback)(void*) )
|
||
{
|
||
if( !m_pClient ) return;
|
||
ICEClient_StartMicTestPhase2( m_pClient, ICECLIENT_MICTEST_LOOPBACK, callback, NULL );
|
||
}
|
||
|
||
void CVoiceChatClient::StopMicTest()
|
||
{
|
||
if( !m_pClient ) return;
|
||
ICEClient_StopMicTest( m_pClient );
|
||
}
|
||
|
||
bool CVoiceChatClient::InitializeMicControl( ICEClient_device *pCaptureDevice )
|
||
{
|
||
FinalizeMicControl();
|
||
|
||
HRESULT hr;
|
||
const int nMaxMixerCount = 20; // ´ëÃæ 20°³±îÁö ÀåÄ¡ °Ë»çÇØº»´Ù.
|
||
bool bFind = false;
|
||
|
||
for( int i = 0; i < nMaxMixerCount; ++i ) {
|
||
hr = mixerOpen(&m_hMixer, i, 0, 0, 0);
|
||
if( hr != S_OK ) continue;
|
||
|
||
memset(&m_mxl, 0, sizeof(m_mxl));
|
||
m_mxl.cbStruct = sizeof(m_mxl);
|
||
|
||
MIXERCAPS caps;
|
||
if( mixerGetDevCaps((UINT_PTR)m_hMixer, &caps, sizeof(MIXERCAPS)) != MMSYSERR_NOERROR ) {
|
||
FinalizeMicControl();
|
||
continue;
|
||
}
|
||
|
||
WCHAR wszBuff[256] = L"";
|
||
//ZeroMemory(wszBuff, sizeof(WCHAR)*_countof(wszBuff));//sizeof * sizeofÀÇ °á°ú´Â ´ë°³ Á¤È®ÇÏÁö ¾Ê½À´Ï´Ù. ¹®ÀÚ ¼ö ¶Ç´Â ¹ÙÀÌÆ® ¼ö¸¦ »ç¿ëÇÏ·Á°í Çß½À´Ï±î?
|
||
ZeroMemory(wszBuff, sizeof(wszBuff));
|
||
|
||
MultiByteToWideChar(CP_ACP, 0, pCaptureDevice->name, -1, wszBuff, _countof(wszBuff) );
|
||
if( wcsncmp( caps.szPname, wszBuff, wcslen(caps.szPname) ) != 0 ) { // caps.szPnameÀ¸·Î ¿À´Â°Ô 32Å©±âÀ̹ǷΠ³Î¹®ÀÚ Á¦¿ÜÇÑ Å©±â¸¸Å ºñ±³ÇؾßÇÑ´Ù.
|
||
FinalizeMicControl();
|
||
continue;
|
||
}
|
||
|
||
int nDest = caps.cDestinations;
|
||
for( int j = 0; j < nDest; ++j ) {
|
||
m_mxl.cbStruct = sizeof(m_mxl);
|
||
m_mxl.dwSource = 0;
|
||
m_mxl.dwDestination = j;
|
||
if( mixerGetLineInfo((HMIXEROBJ)m_hMixer, &m_mxl, MIXER_OBJECTF_HMIXER | MIXER_GETLINEINFOF_DESTINATION) != MMSYSERR_NOERROR ) {
|
||
FinalizeMicControl();
|
||
break;
|
||
}
|
||
|
||
if( m_mxl.dwComponentType == MIXERLINE_COMPONENTTYPE_DST_WAVEIN )
|
||
break;
|
||
}
|
||
|
||
int nConnections = m_mxl.cConnections;
|
||
for( int j = 0; j < nConnections; ++j ) {
|
||
m_mxl.dwSource = j;
|
||
if( mixerGetLineInfo((HMIXEROBJ)m_hMixer, &m_mxl, MIXER_GETLINEINFOF_SOURCE) != MMSYSERR_NOERROR ) {
|
||
FinalizeMicControl();
|
||
break;
|
||
}
|
||
if( MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE == m_mxl.dwComponentType ) {
|
||
// ½ÇÁ¦·Î ¸¶ÀÌÅ© º¼·ý Á¶ÀýÀ» ÇØº¸´Ï ±×·¡µµ ¸øÃ£´Â °æ¿ì°¡ ÀÖ¾î¼, º¼·ý Á¶Àý ÄÁÆ®·Ñ±îÁö Á÷Á¢ ã¾Æº»´Ù.
|
||
MIXERLINECONTROLS mlc = {0,};
|
||
MIXERCONTROL mc = {0,};
|
||
mlc.cbStruct = sizeof(MIXERLINECONTROLS);
|
||
mlc.dwLineID = m_mxl.dwLineID;
|
||
mlc.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME;
|
||
mlc.cControls = 1;
|
||
mlc.pamxctrl = &mc;
|
||
mlc.cbmxctrl = sizeof(MIXERCONTROL);
|
||
if( mixerGetLineControls((HMIXEROBJ)m_hMixer, &mlc, MIXER_GETLINECONTROLSF_ONEBYTYPE) != MMSYSERR_NOERROR ) {
|
||
FinalizeMicControl();
|
||
break;
|
||
}
|
||
CheckMicBoostControl();
|
||
return true;
|
||
}
|
||
}
|
||
|
||
FinalizeMicControl();
|
||
}
|
||
return false;
|
||
}
|
||
|
||
void CVoiceChatClient::FinalizeMicControl()
|
||
{
|
||
if( m_hMixer ) {
|
||
mixerClose(m_hMixer);
|
||
m_hMixer = NULL;
|
||
m_bEnableMicBoost = false;
|
||
}
|
||
}
|
||
|
||
void CVoiceChatClient::CheckOrigMicConfig()
|
||
{
|
||
if( IsExistMicControl() )
|
||
m_fOrigMicVolume = GetMicVolume();
|
||
//if( IsEnableMicBoost() )
|
||
// m_bOrigMicBoost = GetMicBoost();
|
||
}
|
||
|
||
void CVoiceChatClient::RestoreOrigMicConfig()
|
||
{
|
||
if( IsExistMicControl() )
|
||
SetMicVolume( m_fOrigMicVolume );
|
||
//if( IsEnableMicBoost() )
|
||
// SetMicBoost( m_bOrigMicBoost );
|
||
}
|
||
|
||
void CVoiceChatClient::SetMicVolume( float fValue )
|
||
{
|
||
if( !IsExistMicControl() ) return;
|
||
|
||
MIXERLINECONTROLS mlc = {0,};
|
||
MIXERCONTROL mc = {0,};
|
||
mlc.cbStruct = sizeof(MIXERLINECONTROLS);
|
||
mlc.dwLineID = m_mxl.dwLineID;
|
||
mlc.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME;
|
||
mlc.cControls = 1;
|
||
mlc.pamxctrl = &mc;
|
||
mlc.cbmxctrl = sizeof(MIXERCONTROL);
|
||
mixerGetLineControls((HMIXEROBJ)m_hMixer, &mlc, MIXER_GETLINECONTROLSF_ONEBYTYPE);
|
||
|
||
MIXERCONTROLDETAILS mxcd = {0,};
|
||
MIXERCONTROLDETAILS_UNSIGNED mxdu = {0,};
|
||
mxdu.dwValue = DWORD(fValue * 65535);
|
||
mxcd.cMultipleItems = 0;
|
||
mxcd.cChannels = 1;
|
||
mxcd.cbStruct = sizeof(mxcd);
|
||
mxcd.dwControlID = mc.dwControlID;
|
||
mxcd.cbDetails = sizeof(mxdu);
|
||
mxcd.paDetails = &mxdu;
|
||
|
||
mixerSetControlDetails((HMIXEROBJ)m_hMixer, &mxcd, MIXER_SETCONTROLDETAILSF_VALUE);
|
||
}
|
||
|
||
float CVoiceChatClient::GetMicVolume()
|
||
{
|
||
if( !IsExistMicControl() ) return 0.0f;
|
||
|
||
MIXERLINECONTROLS mlc = {0,};
|
||
MIXERCONTROL mc = {0,};
|
||
mlc.cbStruct = sizeof(MIXERLINECONTROLS);
|
||
mlc.dwLineID = m_mxl.dwLineID;
|
||
mlc.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME;
|
||
mlc.cControls = 1;
|
||
mlc.pamxctrl = &mc;
|
||
mlc.cbmxctrl = sizeof(MIXERCONTROL);
|
||
mixerGetLineControls((HMIXEROBJ)m_hMixer, &mlc, MIXER_GETLINECONTROLSF_ONEBYTYPE);
|
||
|
||
MIXERCONTROLDETAILS mxcd = {0,};
|
||
MIXERCONTROLDETAILS_UNSIGNED mxdu = {0,};
|
||
mxcd.cMultipleItems = 0;
|
||
mxcd.cChannels = 1;
|
||
mxcd.cbStruct = sizeof(mxcd);
|
||
mxcd.dwControlID = mc.dwControlID;
|
||
mxcd.cbDetails = sizeof(mxdu);
|
||
mxcd.paDetails = &mxdu;
|
||
|
||
mixerGetControlDetails((HMIXEROBJ)m_hMixer, &mxcd, MIXER_GETCONTROLDETAILSF_VALUE);
|
||
|
||
// 0~65535ÀÇ °ªÀÌ´Ï.
|
||
return mxdu.dwValue / 65535.0f;
|
||
}
|
||
|
||
void CVoiceChatClient::CheckMicBoostControl()
|
||
{
|
||
MMRESULT mmr;
|
||
HMIXER hMixer;
|
||
MIXERCAPS MixerCaps;
|
||
MIXERLINE MixerLine;
|
||
HRESULT hr;
|
||
const int nMaxMixerCount = 20; // ´ëÃæ 20°³±îÁö ÀåÄ¡ °Ë»çÇØº»´Ù.
|
||
|
||
for( int i = 0; i < nMaxMixerCount; ++i ) {
|
||
hr = mixerOpen(&hMixer, i, 0, 0, 0);
|
||
if( hr != S_OK ) continue;
|
||
|
||
if( mixerGetDevCaps((UINT_PTR)hMixer, &MixerCaps, sizeof(MIXERCAPS)) != MMSYSERR_NOERROR ) {
|
||
mixerClose( hMixer );
|
||
continue;
|
||
}
|
||
|
||
bool bFindDest = false;
|
||
memset(&MixerLine, 0, sizeof(MixerLine));
|
||
int nDest = MixerCaps.cDestinations;
|
||
for( int j = 0; j < nDest; ++j ) {
|
||
MixerLine.cbStruct = sizeof(MixerLine);
|
||
MixerLine.dwDestination = j;
|
||
MixerLine.dwSource = 0;
|
||
|
||
mmr = mixerGetLineInfo((HMIXEROBJ)hMixer, &MixerLine, MIXER_GETLINEINFOF_DESTINATION);
|
||
if( mmr != MMSYSERR_NOERROR ) {
|
||
mixerClose( hMixer );
|
||
continue;
|
||
}
|
||
|
||
if( MixerLine.dwComponentType == MIXERLINE_COMPONENTTYPE_DST_SPEAKERS ) {
|
||
bFindDest = true;
|
||
break;
|
||
}
|
||
}
|
||
if( !bFindDest ) {
|
||
mixerClose( hMixer );
|
||
continue;
|
||
}
|
||
|
||
// ¼Ò½ºÄÁÆ®·Ñ Áß¿¡ ¾î´À°Ô ½ÇÁ¦·Î ¸¶ÀÌÅ©¿Í ¿¬°áµÇ¾îÀÖ´ÂÁö ±¸ºÐÇÒ ¹æ¹ýÀÌ ¾øÀ¸¹Ç·Î ¸ðµç ÁõÆøÄÁÆ®·Ñ¿¡ Àû¿ëÇϱâ·Î ÇÑ´Ù.
|
||
int nConnection = MixerLine.cConnections;
|
||
DWORD dwDstIndex = MixerLine.dwDestination;
|
||
for( int j = 0; j < nConnection; ++j ) {
|
||
MixerLine.cbStruct = sizeof( MIXERLINE );
|
||
MixerLine.dwSource = j;
|
||
MixerLine.dwDestination = dwDstIndex;
|
||
if( mixerGetLineInfo((HMIXEROBJ)hMixer, &MixerLine, MIXER_GETLINEINFOF_SOURCE) != MMSYSERR_NOERROR ) {
|
||
continue;
|
||
}
|
||
|
||
if( (MixerLine.dwComponentType == MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE) || (MixerLine.dwComponentType == MIXERLINE_COMPONENTTYPE_SRC_LAST) ) {
|
||
MIXERCONTROL mxc;
|
||
MIXERLINECONTROLS mxlc;
|
||
ZeroMemory(&mxlc, sizeof(MIXERLINECONTROLS));
|
||
mxlc.cbStruct = sizeof(MIXERLINECONTROLS);
|
||
mxlc.dwLineID = MixerLine.dwLineID;
|
||
mxlc.dwControlType = MIXERCONTROL_CONTROLTYPE_ONOFF;
|
||
mxlc.cControls = 1;
|
||
mxlc.cbmxctrl = sizeof(MIXERCONTROL);
|
||
mxlc.pamxctrl = &mxc;
|
||
mxc.cbStruct = sizeof(MIXERCONTROL);
|
||
if( mixerGetLineControls((HMIXEROBJ)hMixer, &mxlc, MIXER_GETLINECONTROLSF_ONEBYTYPE) == MMSYSERR_NOERROR ) {
|
||
// ¿©±â±îÁö µé¾î¿ÔÀ¸¸é ÁõÆøÀ» ãÀ» °ÍÀ̶ó ÆÇ´ÜÇÑ´Ù.
|
||
mixerClose( hMixer );
|
||
m_bEnableMicBoost = true;
|
||
return;
|
||
}
|
||
}
|
||
}
|
||
mixerClose( hMixer );
|
||
}
|
||
|
||
|
||
// ¿¹Á¦ ¼Ò½º¶ó ÇØ¼ µð¹ö±ëÇØº¸´Ï Á¦´ë·Î µ¿ÀÛÇÏÁö ¾Ê´Â´Ù. ´ÙÀ½¿¡ Á¤¸®..
|
||
/*
|
||
HMIXER hMixer;
|
||
MMRESULT mmr;
|
||
MIXERCAPS MixerCaps;
|
||
MIXERLINE MixerLine;
|
||
int u;
|
||
bool bFindDest = false;
|
||
bool bFindCtrl = false;
|
||
|
||
int index = 0;
|
||
mmr = mixerOpen(&hMixer, index, 0, 0, 0);
|
||
if (mmr != MMSYSERR_NOERROR) {
|
||
return;
|
||
}
|
||
|
||
mmr = mixerGetDevCaps((UINT_PTR)hMixer, &MixerCaps, sizeof(MixerCaps));
|
||
if( mmr != MMSYSERR_NOERROR ) {
|
||
mixerClose( hMixer );
|
||
return;
|
||
}
|
||
|
||
memset(&MixerLine, 0, sizeof(MixerLine));
|
||
for( u = 0; u < MixerCaps.cDestinations; u++ ) {
|
||
MixerLine.cbStruct = sizeof(MixerLine);
|
||
MixerLine.dwDestination = u;
|
||
MixerLine.dwSource = 0;
|
||
|
||
mmr = mixerGetLineInfo((HMIXEROBJ)hMixer, &MixerLine, MIXER_GETLINEINFOF_DESTINATION);
|
||
if( mmr != MMSYSERR_NOERROR ) {
|
||
mixerClose( hMixer );
|
||
return;
|
||
}
|
||
|
||
if( MixerLine.dwComponentType == MIXERLINE_COMPONENTTYPE_DST_WAVEIN ) {
|
||
bFindDest = true;
|
||
break;
|
||
}
|
||
}
|
||
if( !bFindDest ) {
|
||
mixerClose( hMixer );
|
||
return;
|
||
}
|
||
|
||
MIXERLINECONTROLS MixerLineControls;
|
||
PMIXERCONTROL paMixerControls = new MIXERCONTROL[MixerLine.cControls];
|
||
MixerLineControls.cbStruct = sizeof(MIXERLINECONTROLS);
|
||
MixerLineControls.dwLineID = MixerLine.dwLineID;
|
||
MixerLineControls.cControls = MixerLine.cControls;
|
||
MixerLineControls.cbmxctrl = sizeof(MIXERCONTROL);
|
||
MixerLineControls.pamxctrl = paMixerControls;
|
||
|
||
// Get the controls for the current destination mixer line
|
||
mmr = mixerGetLineControls((HMIXEROBJ)hMixer, &MixerLineControls, MIXER_GETLINECONTROLSF_ALL);
|
||
if( mmr != MMSYSERR_NOERROR ) {
|
||
delete[] paMixerControls;
|
||
mixerClose( hMixer );
|
||
return;
|
||
}
|
||
|
||
for( u = 0; u < MixerLine.cControls; u++ ) {
|
||
if ((paMixerControls[u].dwControlType == MIXERCONTROL_CONTROLTYPE_MUX) || (paMixerControls[u].dwControlType == MIXERCONTROL_CONTROLTYPE_MIXER)) {
|
||
bFindCtrl = true;
|
||
break;
|
||
}
|
||
}
|
||
|
||
if( !bFindCtrl ) {
|
||
delete[] paMixerControls;
|
||
mixerClose( hMixer );
|
||
return;
|
||
}
|
||
|
||
MIXERCONTROLDETAILS MixerControlDetails;
|
||
PMIXERCONTROLDETAILS_LISTTEXT pMixerControlDetails_Listtext = new MIXERCONTROLDETAILS_LISTTEXT[MixerLine.cChannels * paMixerControls[u].cMultipleItems];
|
||
MixerControlDetails.cbStruct = sizeof(MIXERCONTROLDETAILS);
|
||
MixerControlDetails.dwControlID = paMixerControls[u].dwControlID;
|
||
MixerControlDetails.cChannels = 1;//MixerLine.cChannels;
|
||
MixerControlDetails.hwndOwner = (HWND)paMixerControls[u].cMultipleItems;
|
||
MixerControlDetails.cbDetails = sizeof(MIXERCONTROLDETAILS_LISTTEXT);
|
||
MixerControlDetails.paDetails = pMixerControlDetails_Listtext;
|
||
mmr = mixerGetControlDetails((HMIXEROBJ)hMixer, &MixerControlDetails, MIXER_GETCONTROLDETAILSF_LISTTEXT);
|
||
if (mmr != MMSYSERR_NOERROR) {
|
||
delete[] paMixerControls;
|
||
delete[] pMixerControlDetails_Listtext;
|
||
mixerClose( hMixer );
|
||
return;
|
||
}
|
||
|
||
PMIXERCONTROLDETAILS_BOOLEAN pMixerControlDetails_Boolean = new MIXERCONTROLDETAILS_BOOLEAN[MixerLine.cChannels * paMixerControls[u].cMultipleItems];
|
||
MixerControlDetails.cbStruct = sizeof(MIXERCONTROLDETAILS);
|
||
MixerControlDetails.dwControlID = paMixerControls[u].dwControlID;
|
||
MixerControlDetails.cChannels = 1;//MixerLine.cChannels;
|
||
MixerControlDetails.hwndOwner = (HWND)paMixerControls[u].cMultipleItems;
|
||
MixerControlDetails.cbDetails = sizeof(MIXERCONTROLDETAILS_BOOLEAN);
|
||
MixerControlDetails.paDetails = pMixerControlDetails_Boolean;
|
||
mmr = mixerGetControlDetails((HMIXEROBJ)hMixer, &MixerControlDetails, MIXER_GETCONTROLDETAILSF_VALUE);
|
||
if( mmr != MMSYSERR_NOERROR ) {
|
||
delete[] paMixerControls;
|
||
delete[] pMixerControlDetails_Listtext;
|
||
delete[] pMixerControlDetails_Boolean;
|
||
mixerClose( hMixer );
|
||
return;
|
||
}
|
||
|
||
//Set only the microphone or line as input sources
|
||
for( int v = 0; v < paMixerControls[u].cMultipleItems; v++ ) {
|
||
pMixerControlDetails_Boolean[v].fValue = FALSE;
|
||
if( pMixerControlDetails_Listtext[v].dwParam2 == MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE )
|
||
pMixerControlDetails_Boolean[v].fValue = TRUE;
|
||
}
|
||
|
||
mmr = mixerSetControlDetails((HMIXEROBJ)hMixer, &MixerControlDetails, MIXER_SETCONTROLDETAILSF_VALUE);
|
||
if( mmr != MMSYSERR_NOERROR ) {
|
||
delete[] paMixerControls;
|
||
delete[] pMixerControlDetails_Listtext;
|
||
delete[] pMixerControlDetails_Boolean;
|
||
mixerClose( hMixer );
|
||
return;
|
||
}
|
||
|
||
delete[] paMixerControls;
|
||
delete[] pMixerControlDetails_Listtext;
|
||
delete[] pMixerControlDetails_Boolean;
|
||
mixerClose( hMixer );
|
||
m_bEnableMicBoost = true;
|
||
return;
|
||
*/
|
||
|
||
/*
|
||
MMRESULT mmr;
|
||
int u;
|
||
PMIXERCONTROL paMixerControls;
|
||
MIXERLINECONTROLS mlc = {0,};
|
||
MIXERCONTROL mc = {0,};
|
||
paMixerControls = (PMIXERCONTROL)malloc(sizeof(MIXERCONTROL) * m_mxl.cControls);
|
||
mlc.cbStruct = sizeof(MIXERLINECONTROLS);
|
||
mlc.dwLineID = m_mxl.dwLineID;
|
||
mlc.cControls = m_mxl.cControls;
|
||
mlc.cbmxctrl = sizeof(MIXERCONTROL);
|
||
mlc.pamxctrl = paMixerControls;
|
||
mmr = mixerGetLineControls((HMIXEROBJ)m_hMixer, &mlc, MIXER_GETLINECONTROLSF_ALL);
|
||
|
||
for (u = 0; u < (int)m_mxl.cControls; u++)
|
||
if (paMixerControls[u].dwControlType == MIXERCONTROL_CONTROLTYPE_MUX)
|
||
//if (NULL != strstr(paMixerControls[u].szName, "Mic Boost"))
|
||
//if (paMixerControls[u].dwControlType == MIXERCONTROL_CONTROLTYPE_ONOFF)
|
||
break;
|
||
|
||
mlc.cbStruct = sizeof(MIXERLINECONTROLS);
|
||
mlc.dwControlID = paMixerControls[u].dwControlID;
|
||
mlc.cbmxctrl = sizeof(MIXERCONTROL);
|
||
mlc.pamxctrl = &mc;
|
||
mmr = mixerGetLineControls((HMIXEROBJ)m_hMixer, &mlc, MIXER_GETLINECONTROLSF_ONEBYID);
|
||
free(paMixerControls);
|
||
|
||
PMIXERCONTROLDETAILS_LISTTEXT pMixerControlDetails_Listtext;
|
||
MIXERCONTROLDETAILS MixerControlDetails;
|
||
pMixerControlDetails_Listtext = (PMIXERCONTROLDETAILS_LISTTEXT)malloc(m_mxl.cChannels * mc.cMultipleItems * sizeof(MIXERCONTROLDETAILS_LISTTEXT));
|
||
MixerControlDetails.cbStruct = sizeof(MixerControlDetails);
|
||
MixerControlDetails.dwControlID = mc.dwControlID;
|
||
MixerControlDetails.cChannels = m_mxl.cChannels;
|
||
MixerControlDetails.cMultipleItems = mc.cMultipleItems;
|
||
MixerControlDetails.cbDetails = sizeof(MIXERCONTROLDETAILS_LISTTEXT);
|
||
MixerControlDetails.paDetails = pMixerControlDetails_Listtext;
|
||
mmr = mixerGetControlDetails((HMIXEROBJ)m_hMixer, &MixerControlDetails, MIXER_GETCONTROLDETAILSF_LISTTEXT);
|
||
|
||
for(u = 0; u < (int)mc.cMultipleItems; u++)
|
||
if (0 == wcscmp(pMixerControlDetails_Listtext[u].szName, L"Microphone"))
|
||
break;
|
||
|
||
PMIXERCONTROLDETAILS_BOOLEAN pMixerControlDetails_Boolean;
|
||
pMixerControlDetails_Boolean = (PMIXERCONTROLDETAILS_BOOLEAN)malloc(m_mxl.cChannels * mc.cMultipleItems * sizeof(MIXERCONTROLDETAILS_BOOLEAN));
|
||
MixerControlDetails.cbStruct = sizeof(MixerControlDetails);
|
||
MixerControlDetails.dwControlID = mc.dwControlID;
|
||
MixerControlDetails.cChannels = m_mxl.cChannels;
|
||
MixerControlDetails.cMultipleItems = mc.cMultipleItems;
|
||
MixerControlDetails.cbDetails = sizeof(MIXERCONTROLDETAILS_BOOLEAN);
|
||
MixerControlDetails.paDetails = pMixerControlDetails_Boolean;
|
||
mmr = mixerGetControlDetails((HMIXEROBJ)m_hMixer, &MixerControlDetails, 0L);
|
||
|
||
pMixerControlDetails_Boolean[u].fValue = true;
|
||
mmr = mixerSetControlDetails((HMIXEROBJ)m_hMixer, &MixerControlDetails, 0L);
|
||
|
||
free(pMixerControlDetails_Listtext);
|
||
free(pMixerControlDetails_Boolean);
|
||
*/
|
||
}
|
||
|
||
void CVoiceChatClient::SetMicBoost( bool bBoost )
|
||
{
|
||
if( !IsEnableMicBoost() ) return;
|
||
|
||
MMRESULT mmr;
|
||
HMIXER hMixer;
|
||
MIXERCAPS MixerCaps;
|
||
MIXERLINE MixerLine;
|
||
HRESULT hr;
|
||
const int nMaxMixerCount = 20; // ´ëÃæ 20°³±îÁö ÀåÄ¡ °Ë»çÇØº»´Ù.
|
||
|
||
for( int i = 0; i < nMaxMixerCount; ++i ) {
|
||
hr = mixerOpen(&hMixer, i, 0, 0, 0);
|
||
if( hr != S_OK ) continue;
|
||
|
||
if( mixerGetDevCaps((UINT_PTR)hMixer, &MixerCaps, sizeof(MIXERCAPS)) != MMSYSERR_NOERROR ) {
|
||
mixerClose( hMixer );
|
||
continue;
|
||
}
|
||
|
||
bool bFindDest = false;
|
||
memset(&MixerLine, 0, sizeof(MixerLine));
|
||
int nDest = MixerCaps.cDestinations;
|
||
for( int j = 0; j < nDest; ++j ) {
|
||
MixerLine.cbStruct = sizeof(MixerLine);
|
||
MixerLine.dwDestination = j;
|
||
MixerLine.dwSource = 0;
|
||
|
||
mmr = mixerGetLineInfo((HMIXEROBJ)hMixer, &MixerLine, MIXER_GETLINEINFOF_DESTINATION);
|
||
if( mmr != MMSYSERR_NOERROR ) {
|
||
mixerClose( hMixer );
|
||
continue;
|
||
}
|
||
|
||
if( MixerLine.dwComponentType == MIXERLINE_COMPONENTTYPE_DST_SPEAKERS ) {
|
||
bFindDest = true;
|
||
break;
|
||
}
|
||
}
|
||
if( !bFindDest ) {
|
||
mixerClose( hMixer );
|
||
continue;
|
||
}
|
||
|
||
// ¼Ò½ºÄÁÆ®·Ñ Áß¿¡ ¾î´À°Ô ½ÇÁ¦·Î ¸¶ÀÌÅ©¿Í ¿¬°áµÇ¾îÀÖ´ÂÁö ±¸ºÐÇÒ ¹æ¹ýÀÌ ¾øÀ¸¹Ç·Î ¸ðµç ÁõÆøÄÁÆ®·Ñ¿¡ Àû¿ëÇϱâ·Î ÇÑ´Ù.
|
||
int nConnection = MixerLine.cConnections;
|
||
DWORD dwDstIndex = MixerLine.dwDestination;
|
||
for( int j = 0; j < nConnection; ++j ) {
|
||
MixerLine.cbStruct = sizeof( MIXERLINE );
|
||
MixerLine.dwSource = j;
|
||
MixerLine.dwDestination = dwDstIndex;
|
||
if( mixerGetLineInfo((HMIXEROBJ)hMixer, &MixerLine, MIXER_GETLINEINFOF_SOURCE) != MMSYSERR_NOERROR ) {
|
||
continue;
|
||
}
|
||
|
||
if( (MixerLine.dwComponentType == MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE) || (MixerLine.dwComponentType == MIXERLINE_COMPONENTTYPE_SRC_LAST) ) {
|
||
MIXERCONTROL mxc;
|
||
MIXERLINECONTROLS mxlc;
|
||
ZeroMemory(&mxlc, sizeof(MIXERLINECONTROLS));
|
||
mxlc.cbStruct = sizeof(MIXERLINECONTROLS);
|
||
mxlc.dwLineID = MixerLine.dwLineID;
|
||
mxlc.dwControlType = MIXERCONTROL_CONTROLTYPE_ONOFF;
|
||
mxlc.cControls = 1;
|
||
mxlc.cbmxctrl = sizeof(MIXERCONTROL);
|
||
mxlc.pamxctrl = &mxc;
|
||
mxc.cbStruct = sizeof(MIXERCONTROL);
|
||
if( mixerGetLineControls((HMIXEROBJ)hMixer, &mxlc, MIXER_GETLINECONTROLSF_ONEBYTYPE) == MMSYSERR_NOERROR ) {
|
||
DWORD dwValue = bBoost ? 1 : 0;
|
||
MIXERCONTROLDETAILS mxcd;
|
||
|
||
DWORD dwControlID = mxc.dwControlID;
|
||
DWORD cMultipleItems = mxc.cMultipleItems;
|
||
|
||
// Initialize the MIXERCONTROLDETAILS structure
|
||
ZeroMemory(&mxcd, sizeof(MIXERCONTROLDETAILS));
|
||
mxcd.cbStruct = sizeof(MIXERCONTROLDETAILS);
|
||
mxcd.dwControlID = dwControlID; //mxc.dwControlID;
|
||
mxcd.cChannels = 1;
|
||
mxcd.cMultipleItems = cMultipleItems;
|
||
mxcd.cbDetails = sizeof(MIXERCONTROLDETAILS_UNSIGNED);
|
||
mxcd.paDetails = &dwValue;
|
||
//mxcd.paDetails = &mxcdStruct;
|
||
|
||
// Set the values
|
||
if( mixerSetControlDetails((HMIXEROBJ)hMixer, &mxcd, MIXER_GETCONTROLDETAILSF_VALUE) != MMSYSERR_NOERROR ) {
|
||
OutputDebug( "VoiceChat Boost Setting Fail!" );
|
||
}
|
||
}
|
||
}
|
||
}
|
||
mixerClose( hMixer );
|
||
}
|
||
}
|
||
#endif |