1079 lines
30 KiB
C++
1079 lines
30 KiB
C++
/*==========================================================================
|
|
*
|
|
* Copyright (C) 1995-1999 Microsoft Corporation. All Rights Reserved.
|
|
*
|
|
* File: voice.cpp
|
|
* Content: Voice Support Routines
|
|
* History:
|
|
*
|
|
* Date By Reason
|
|
* ==== == ======
|
|
* 10/15/99 rodtoll created it
|
|
* rodtoll Plugged resource leak
|
|
* 10/20/99 rodtoll Fix: Bug #113686 Not shutting down when receiving lobby message
|
|
* 10/25/99 rodtoll Removed lpszVoicePassword member from sessiondesc
|
|
* 10/28/99 pnewson Bug #114176 updated DVSOUNDDEVICECONFIG struct
|
|
* 11/02/99 rodtoll Bug #116677 - Can't use lobby clients that don't hang around
|
|
* 11/12/99 rodtoll Added support for the new waveIN/waveOut flags and the
|
|
* echo suppression flag.
|
|
* 11/29/99 rodtoll Bug #120249 - Modem host does not wait for connections. Added
|
|
* message loop in voice thread.
|
|
* 12/01/99 rodtoll Updated to use user selections for playback/record device
|
|
* 12/07/99 rodtoll Bug #122628 Make error messages silent when running in silent mode
|
|
* 12/08/99 rodtoll Bug #121054 Added support for flags to control new capture focus
|
|
* 01/10/2000 pnewson Added support for dynamic Tx and Rx display for AGC & VA tuning
|
|
* 01/14/2000 rodtoll Updated with API changes
|
|
* 01/27/2000 rodtoll Updated with API changes
|
|
* 01/28/2000 rodtoll Updated so Volume Set failures don't exit app (for records w/o volume)
|
|
* 02/08/2000 rodtoll Bug #131496 - Selecting DVTHRESHOLD_DEFAULT results in voice
|
|
* never being detected
|
|
* 03/03/2000 rodtoll Updated to handle alternative gamevoice build.
|
|
* 06/21/2000 rodtoll Bug #35767 - Implement ability for Dsound effects processing if dpvoice buffers
|
|
* Updated DPVHELP to use new parameters
|
|
* 06/27/2000 rodtoll Added support for new host migration message
|
|
* 06/28/2000 rodtoll Prefix Bug #38033
|
|
* 08/31/2000 rodtoll Bug #43804 - DVOICE: dwSensitivity structure member is confusing - should be dwThreshold
|
|
* 04/02/2001 simonpow Bug #354859 - Fixes for PREfast
|
|
* (removal unecessary local vars in DVMessageHandlerClient)
|
|
*
|
|
***************************************************************************/
|
|
|
|
#include "dxvhelppch.h"
|
|
|
|
|
|
#define DVHELPER_CONNECT_TIMEOUT 15000
|
|
#define DPLSYS_LOBBYCLIENTRELEASE 0x0000000B
|
|
|
|
void VoiceManager_DisplayStatus( PDXVHELP_RTINFO prtInfo, LPTSTR lpstrStatus )
|
|
{
|
|
if( prtInfo->hMainDialog )
|
|
{
|
|
MainDialog_DisplayStatus( prtInfo->hMainDialog, lpstrStatus );
|
|
}
|
|
}
|
|
|
|
BOOL VoiceManager_LobbyConnect( PDXVHELP_RTINFO prtInfo )
|
|
{
|
|
HRESULT hr;
|
|
LPBYTE lpBuffer = NULL;
|
|
DWORD dwSize = 0;
|
|
BYTE *lpAddressBuffer = NULL;
|
|
DWORD dwAddressSize = 0;
|
|
LPDPLCONNECTION lpdplConnection = NULL;
|
|
LPDPLMSG_GENERIC lpdlmGeneric = NULL;
|
|
DWORD dwFlags;
|
|
|
|
hr = CoCreateInstance( DPLAY_CLSID_DPLOBBY, NULL, CLSCTX_INPROC_SERVER, IID_IDirectPlayLobby3A, (void **) &prtInfo->lpdpLobby );
|
|
|
|
if( FAILED( hr ) )
|
|
{
|
|
DPVDX_DPERRDisplay( hr, _T("Unable to to get ct info"), prtInfo->dxvParameters.fSilent);
|
|
return FALSE;
|
|
}
|
|
|
|
dwSize = 0;
|
|
|
|
if( prtInfo->dxvParameters.fWaitForSettings )
|
|
{
|
|
VoiceManager_DisplayStatus( prtInfo, _T("Waiting for settings") );
|
|
|
|
hr = prtInfo->lpdpLobby->WaitForConnectionSettings( 0 );
|
|
|
|
if( FAILED( hr ) )
|
|
{
|
|
DPVDX_DPERRDisplay( hr, _T("WaitForConnection FAILED"), prtInfo->dxvParameters.fSilent );
|
|
goto LOBBY_CONNECT_CLEANUP;
|
|
}
|
|
|
|
lpBuffer = new BYTE[2000];
|
|
lpdlmGeneric = (LPDPLMSG_GENERIC) lpBuffer;
|
|
|
|
while( 1 )
|
|
{
|
|
if( WaitForSingleObject( prtInfo->hShutdown, 0 ) != WAIT_TIMEOUT )
|
|
{
|
|
goto LOBBY_CONNECT_CLEANUP;
|
|
}
|
|
|
|
dwSize = 2000;
|
|
|
|
hr = prtInfo->lpdpLobby->ReceiveLobbyMessage( 0, 0, &dwFlags, lpBuffer, &dwSize );
|
|
|
|
if( hr == DP_OK )
|
|
{
|
|
if( lpdlmGeneric->dwType == DPLSYS_NEWCONNECTIONSETTINGS )
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
Sleep( 50 );
|
|
}
|
|
|
|
delete [] lpBuffer;
|
|
lpBuffer = NULL;
|
|
}
|
|
|
|
VoiceManager_DisplayStatus( prtInfo, _T("Getting Settings") );
|
|
|
|
hr = prtInfo->lpdpLobby->GetConnectionSettings( 0, NULL, &dwSize );
|
|
|
|
if( hr != DPERR_BUFFERTOOSMALL )
|
|
{
|
|
DPVDX_DPERRDisplay( hr, _T("Error retrieving connection settings size"), prtInfo->dxvParameters.fSilent );
|
|
goto LOBBY_CONNECT_CLEANUP;
|
|
}
|
|
|
|
lpBuffer = new BYTE[dwSize];
|
|
|
|
if( lpBuffer == NULL )
|
|
{
|
|
DPVDX_DPERRDisplay( DVERR_OUTOFMEMORY, _T("Failure allocating memory"), prtInfo->dxvParameters.fSilent );
|
|
goto LOBBY_CONNECT_CLEANUP;
|
|
}
|
|
|
|
lpdplConnection = (LPDPLCONNECTION) lpBuffer;
|
|
|
|
hr = prtInfo->lpdpLobby->GetConnectionSettings( 0, lpBuffer, &dwSize );
|
|
|
|
if( FAILED( hr ) )
|
|
{
|
|
DPVDX_DPERRDisplay( hr, _T("Failed to retrieve settings"), prtInfo->dxvParameters.fSilent );
|
|
goto LOBBY_CONNECT_CLEANUP;
|
|
}
|
|
|
|
// If we're connecting to a session we need to find the session
|
|
if( !(lpdplConnection->dwFlags & DPLCONNECTION_CREATESESSION) )
|
|
{
|
|
prtInfo->dxvParameters.fHost = FALSE;
|
|
|
|
VoiceManager_DisplayStatus( prtInfo, _T("Finding Session") );
|
|
|
|
}
|
|
else
|
|
{
|
|
|
|
// Over-ride protocol settings from lobby launch
|
|
lpdplConnection->lpSessionDesc->dwFlags |= DPSESSION_DIRECTPLAYPROTOCOL | DPSESSION_KEEPALIVE | DPSESSION_MIGRATEHOST;
|
|
|
|
prtInfo->dxvParameters.fHost = TRUE;
|
|
|
|
// Launching from a session where the GetPlayerAddress on the server doesn't
|
|
// allow getting a player's address
|
|
if( lpdplConnection->lpAddress == NULL )
|
|
{
|
|
DPCOMPOUNDADDRESSELEMENT element;
|
|
|
|
element.guidDataType = DPAID_ServiceProvider;
|
|
element.dwDataSize = sizeof( GUID );
|
|
element.lpData = &lpdplConnection->guidSP;
|
|
|
|
hr = prtInfo->lpdpLobby->CreateCompoundAddress( &element, 1, NULL, &dwAddressSize );
|
|
|
|
if( hr != DPERR_BUFFERTOOSMALL )
|
|
{
|
|
DPVDX_DPERRDisplay( hr, _T("Unable to create compound address for session host"), prtInfo->dxvParameters.fSilent );
|
|
goto LOBBY_CONNECT_CLEANUP;
|
|
}
|
|
|
|
lpAddressBuffer = new BYTE[dwAddressSize];
|
|
|
|
hr = prtInfo->lpdpLobby->CreateCompoundAddress( &element, 1, lpAddressBuffer, &dwAddressSize );
|
|
|
|
if( FAILED( hr ) )
|
|
{
|
|
DPVDX_DPERRDisplay( hr, _T("Unable to create compound address for session host"), prtInfo->dxvParameters.fSilent );
|
|
goto LOBBY_CONNECT_CLEANUP;
|
|
}
|
|
|
|
lpdplConnection->lpAddress = lpAddressBuffer;
|
|
lpdplConnection->dwAddressSize = dwAddressSize;
|
|
}
|
|
}
|
|
|
|
hr = prtInfo->lpdpLobby->SetConnectionSettings( 0, 0, lpdplConnection );
|
|
|
|
if( FAILED( hr ) )
|
|
{
|
|
DPVDX_DPERRDisplay( hr, _T("Unable to set connection settings"), prtInfo->dxvParameters.fSilent );
|
|
goto LOBBY_CONNECT_CLEANUP;
|
|
}
|
|
|
|
prtInfo->hLobbyEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
|
|
|
|
hr = prtInfo->lpdpLobby->SetLobbyMessageEvent( 0, 0, prtInfo->hLobbyEvent );
|
|
|
|
VoiceManager_DisplayStatus( prtInfo, _T("Connect/Start") );
|
|
|
|
hr = prtInfo->lpdpLobby->ConnectEx( 0, IID_IDirectPlay4A, (void **) &prtInfo->lpdpDirectPlay, NULL );
|
|
|
|
if( FAILED( hr ) )
|
|
{
|
|
DPVDX_DPERRDisplay( hr, _T("Failed to ConnectEx"), prtInfo->dxvParameters.fSilent );
|
|
goto LOBBY_CONNECT_CLEANUP;
|
|
}
|
|
|
|
prtInfo->hReceiveEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
|
|
|
|
hr = prtInfo->lpdpDirectPlay->CreatePlayer( &prtInfo->dpidLocalPlayer, NULL, prtInfo->hReceiveEvent, NULL, 0, 0 );
|
|
|
|
if( FAILED( hr ) )
|
|
{
|
|
DPVDX_DPERRDisplay( hr, _T("CreatePlayer Failed"), prtInfo->dxvParameters.fSilent );
|
|
goto LOBBY_CONNECT_CLEANUP;
|
|
}
|
|
|
|
if( lpBuffer )
|
|
delete [] lpBuffer;
|
|
|
|
return TRUE;
|
|
|
|
LOBBY_CONNECT_CLEANUP:
|
|
|
|
if( prtInfo->lpdpLobby != NULL )
|
|
{
|
|
prtInfo->lpdpLobby->Release();
|
|
}
|
|
|
|
if( lpAddressBuffer != NULL )
|
|
{
|
|
delete [] lpAddressBuffer;
|
|
}
|
|
|
|
if( lpBuffer != NULL )
|
|
{
|
|
delete [] lpBuffer;
|
|
}
|
|
|
|
if( prtInfo->lpdpDirectPlay != NULL )
|
|
{
|
|
prtInfo->lpdpDirectPlay->Release();
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
BOOL VoiceManager_StandardConnect( PDXVHELP_RTINFO prtInfo )
|
|
{
|
|
HRESULT hr;
|
|
DWORD dwFlags = 0;
|
|
GUID guidInstance;
|
|
|
|
VoiceManager_DisplayStatus( prtInfo, _T("Creating dplay") );
|
|
|
|
hr = CoCreateInstance( DPLAY_CLSID_DPLAY, NULL, CLSCTX_INPROC_SERVER, IID_IDirectPlay4A, (void **) &prtInfo->lpdpDirectPlay );
|
|
|
|
if( FAILED( hr ) )
|
|
{
|
|
DPVDX_DPERRDisplay( hr, _T("Unable to Create Lobby Object"), prtInfo->dxvParameters.fSilent );
|
|
return FALSE;
|
|
}
|
|
|
|
hr = DPVDX_DP_Init( prtInfo->lpdpDirectPlay, DPSPGUID_TCPIP, (prtInfo->dxvParameters.fHost) ? NULL : prtInfo->dxvParameters.lpszConnectAddress );
|
|
|
|
if( FAILED( hr ) )
|
|
{
|
|
DPVDX_DPERRDisplay( hr, _T("Initialize DirectPlay"), prtInfo->dxvParameters.fSilent );
|
|
return FALSE;
|
|
}
|
|
|
|
if( prtInfo->dxvParameters.fHost )
|
|
{
|
|
dwFlags = DPSESSION_KEEPALIVE | DPSESSION_DIRECTPLAYPROTOCOL;
|
|
|
|
if( prtInfo->dxvParameters.dwSessionType == DVSESSIONTYPE_PEER )
|
|
{
|
|
dwFlags |= DPSESSION_MIGRATEHOST;
|
|
}
|
|
|
|
VoiceManager_DisplayStatus( prtInfo, _T("Starting Session") );
|
|
|
|
hr = DPVDX_DP_StartSession( prtInfo->lpdpDirectPlay, DPVHELP_PUBLIC_APPID, dwFlags, NULL, NULL, 0, &prtInfo->dpidLocalPlayer, &prtInfo->hReceiveEvent, &guidInstance ) ;
|
|
|
|
if( FAILED( hr ) )
|
|
{
|
|
DPVDX_DPERRDisplay( hr, _T("Starting Session"), prtInfo->dxvParameters.fSilent );
|
|
return FALSE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
VoiceManager_DisplayStatus( prtInfo, _T("Finding Session") );
|
|
|
|
hr = DPVDX_DP_FindSessionGUID( prtInfo->lpdpDirectPlay, DPVHELP_PUBLIC_APPID, DVHELPER_CONNECT_TIMEOUT, &guidInstance );
|
|
|
|
if( FAILED( hr ) )
|
|
{
|
|
DPVDX_DPERRDisplay( hr, _T("Finding Session"), prtInfo->dxvParameters.fSilent );
|
|
return FALSE;
|
|
}
|
|
|
|
VoiceManager_DisplayStatus( prtInfo, _T("Connecting") );
|
|
|
|
hr = DPVDX_DP_ConnectToSession( prtInfo->lpdpDirectPlay, DPVHELP_PUBLIC_APPID, guidInstance, NULL, &prtInfo->dpidLocalPlayer, &prtInfo->hReceiveEvent );
|
|
|
|
if( FAILED( hr ) )
|
|
{
|
|
DPVDX_DPERRDisplay( hr, _T("Connect To Session"), prtInfo->dxvParameters.fSilent );
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
VoiceManager_DisplayStatus( prtInfo, _T("Dplay started") );
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
|
|
HRESULT PASCAL DVMessageHandlerServer(
|
|
LPVOID lpvUserContext,
|
|
DWORD dwMessageType,
|
|
LPVOID lpMessage
|
|
)
|
|
{
|
|
TCHAR szTmpString[180];
|
|
PDXVHELP_RTINFO prtInfo = (PDXVHELP_RTINFO) lpvUserContext;
|
|
|
|
PDVMSG_SESSIONLOST pdvSessionLost = NULL;
|
|
PDVMSG_DELETEVOICEPLAYER pdvDeletePlayer = NULL;
|
|
PDVMSG_CREATEVOICEPLAYER pdvCreatePlayer = NULL;
|
|
|
|
switch( dwMessageType )
|
|
{
|
|
case DVMSGID_CREATEVOICEPLAYER:
|
|
|
|
pdvCreatePlayer = (PDVMSG_CREATEVOICEPLAYER) lpMessage;
|
|
pdvCreatePlayer->pvPlayerContext = (PVOID) (DWORD_PTR) pdvCreatePlayer->dvidPlayer;
|
|
|
|
_stprintf( szTmpString, _T("[DVMSGID_CREATEVOICEPLAYER] **SERVER** ID=0x%x"), pdvCreatePlayer->dvidPlayer );
|
|
MainDialog_AddToLog( prtInfo->hMainDialog, szTmpString );
|
|
break;
|
|
case DVMSGID_DELETEVOICEPLAYER:
|
|
|
|
pdvDeletePlayer = (PDVMSG_DELETEVOICEPLAYER) lpMessage;
|
|
|
|
_stprintf( szTmpString, _T("[DVMSGID_DELETEVOICEPLAYER] **SERVER** ID=0x%x"), pdvDeletePlayer->dvidPlayer );
|
|
MainDialog_AddToLog( prtInfo->hMainDialog, szTmpString );
|
|
break;
|
|
case DVMSGID_SESSIONLOST:
|
|
|
|
pdvSessionLost = (PDVMSG_SESSIONLOST) lpMessage;
|
|
|
|
_stprintf( szTmpString, _T("[DVMSGID_SESSIONLOST] **SERVER** Reason=0x%x"), pdvSessionLost->hrResult );
|
|
|
|
MainDialog_AddToLog( prtInfo->hMainDialog, szTmpString );
|
|
|
|
if( !prtInfo->dxvParameters.fSilent )
|
|
{
|
|
MessageBox( NULL, _T("Server Session lost!"),_T("Voice Conference"), MB_OK );
|
|
}
|
|
SetEvent( prtInfo->hShutdown );
|
|
break;
|
|
}
|
|
|
|
return DV_OK;
|
|
}
|
|
|
|
|
|
HRESULT PASCAL DVMessageHandlerClient(
|
|
LPVOID lpvUserContext,
|
|
DWORD dwMessageType,
|
|
LPVOID lpMessage
|
|
)
|
|
{
|
|
TCHAR szTmpString[180];
|
|
|
|
PDXVHELP_RTINFO prtInfo = (PDXVHELP_RTINFO) lpvUserContext;
|
|
HWND hwndItem = NULL;
|
|
PDVMSG_INPUTLEVEL pdvInputLevel = NULL;
|
|
PDVMSG_OUTPUTLEVEL pdvOutputLevel = NULL;
|
|
PDVMSG_HOSTMIGRATED pdvHostMigrated = NULL;
|
|
PDVMSG_SESSIONLOST pdvSessionLost = NULL;
|
|
PDVMSG_DELETEVOICEPLAYER pdvDeletePlayer = NULL;
|
|
PDVMSG_CREATEVOICEPLAYER pdvCreatePlayer = NULL;
|
|
PDVMSG_LOCALHOSTSETUP pdvLocalHostSetup = NULL;
|
|
PDVMSG_PLAYERVOICESTART pdvPlayerVoiceStart = NULL;
|
|
PDVMSG_PLAYERVOICESTOP pdvPlayerVoiceStop = NULL;
|
|
PDVMSG_RECORDSTART pdvRecordStart = NULL;
|
|
PDVMSG_RECORDSTOP pdvRecordStop = NULL;
|
|
|
|
static int s_iRxCount = 0;
|
|
|
|
char numBuffer[80];
|
|
|
|
switch( dwMessageType )
|
|
{
|
|
case DVMSGID_LOCALHOSTSETUP:
|
|
|
|
pdvLocalHostSetup = (PDVMSG_LOCALHOSTSETUP) lpMessage;
|
|
|
|
_stprintf( szTmpString, _T("[DVMSGID_LOCALHOSTSETUP] Local client is to become host") );
|
|
MainDialog_AddToLog( prtInfo->hMainDialog, szTmpString );
|
|
|
|
pdvLocalHostSetup->pMessageHandler = DVMessageHandlerServer;
|
|
pdvLocalHostSetup->pvContext = lpvUserContext;
|
|
|
|
break;
|
|
|
|
|
|
case DVMSGID_CREATEVOICEPLAYER:
|
|
|
|
pdvCreatePlayer = (PDVMSG_CREATEVOICEPLAYER) lpMessage;
|
|
|
|
_stprintf( szTmpString, _T("[DVMSGID_CREATEVOICEPLAYER] ID=0x%x"), pdvCreatePlayer->dvidPlayer );
|
|
MainDialog_AddToLog( prtInfo->hMainDialog, szTmpString );
|
|
|
|
MainDialog_AddVoicePlayer( prtInfo->hMainDialog, pdvCreatePlayer->dvidPlayer );
|
|
|
|
prtInfo->dwNumClients++;
|
|
wsprintf( numBuffer, "%d", prtInfo->dwNumClients );
|
|
|
|
if( prtInfo->hMainDialog != NULL )
|
|
{
|
|
hwndItem = GetDlgItem( prtInfo->hMainDialog, IDC_STATIC_PLAYERS );
|
|
|
|
if( hwndItem != NULL )
|
|
{
|
|
SetWindowText( hwndItem, numBuffer );
|
|
}
|
|
}
|
|
|
|
pdvCreatePlayer->pvPlayerContext = (PVOID) (DWORD_PTR) pdvCreatePlayer->dvidPlayer;
|
|
|
|
break;
|
|
case DVMSGID_DELETEVOICEPLAYER:
|
|
|
|
pdvDeletePlayer = (PDVMSG_DELETEVOICEPLAYER) lpMessage;
|
|
|
|
_stprintf( szTmpString, _T("[DVMSGID_DELETEVOICEPLAYER] ID=0x%x"), pdvDeletePlayer->dvidPlayer );
|
|
MainDialog_AddToLog( prtInfo->hMainDialog, szTmpString );
|
|
|
|
MainDialog_RemoveVoicePlayer( prtInfo->hMainDialog, pdvDeletePlayer->dvidPlayer );
|
|
|
|
prtInfo->dwNumClients--;
|
|
wsprintf( numBuffer, "%d", prtInfo->dwNumClients );
|
|
if( prtInfo->hMainDialog != NULL )
|
|
{
|
|
hwndItem = GetDlgItem( prtInfo->hMainDialog, IDC_STATIC_PLAYERS );
|
|
|
|
if( hwndItem != NULL )
|
|
{
|
|
SetWindowText( hwndItem, numBuffer );
|
|
}
|
|
}
|
|
break;
|
|
case DVMSGID_SESSIONLOST:
|
|
|
|
pdvSessionLost = (PDVMSG_SESSIONLOST) lpMessage;
|
|
|
|
_stprintf( szTmpString, _T("[DVMSGID_SESSIONLOST] Reason=0x%x"), pdvSessionLost->hrResult );
|
|
|
|
MainDialog_AddToLog( prtInfo->hMainDialog, szTmpString );
|
|
|
|
if( !prtInfo->dxvParameters.fSilent )
|
|
{
|
|
MessageBox( NULL, _T("Session lost!"),_T("Voice Conference"), MB_OK );
|
|
}
|
|
SetEvent( prtInfo->hShutdown );
|
|
break;
|
|
case DVMSGID_INPUTLEVEL:
|
|
pdvInputLevel = (PDVMSG_INPUTLEVEL) lpMessage;
|
|
|
|
if( prtInfo->hMainDialog != NULL )
|
|
{
|
|
hwndItem = GetDlgItem( prtInfo->hMainDialog, IDC_PROGRESS_TX );
|
|
|
|
if( hwndItem != NULL )
|
|
{
|
|
SendMessage( hwndItem, PBM_SETPOS, (WPARAM) pdvInputLevel->dwPeakLevel, 0 );
|
|
}
|
|
}
|
|
break;
|
|
case DVMSGID_OUTPUTLEVEL:
|
|
pdvOutputLevel = (PDVMSG_OUTPUTLEVEL) lpMessage;
|
|
|
|
if( prtInfo->hMainDialog != NULL )
|
|
{
|
|
hwndItem = GetDlgItem( prtInfo->hMainDialog, IDC_PROGRESS_RX );
|
|
|
|
if( hwndItem != NULL )
|
|
{
|
|
SendMessage( hwndItem, PBM_SETPOS, (WPARAM) pdvOutputLevel->dwPeakLevel, 0 );
|
|
}
|
|
}
|
|
break;
|
|
case DVMSGID_RECORDSTART:
|
|
if( prtInfo->hMainDialog != NULL )
|
|
{
|
|
pdvRecordStart = (PDVMSG_RECORDSTART) lpMessage;
|
|
|
|
hwndItem = GetDlgItem( prtInfo->hMainDialog, IDC_STATIC_TX );
|
|
|
|
if( hwndItem != NULL )
|
|
{
|
|
SendMessage( hwndItem, WM_SETTEXT, NULL, (LPARAM)"Tx" );
|
|
}
|
|
|
|
_stprintf( szTmpString, _T("[DVMSGID_RECORDSTART]") );
|
|
MainDialog_AddToLog( prtInfo->hMainDialog, szTmpString );
|
|
}
|
|
break;
|
|
case DVMSGID_RECORDSTOP:
|
|
if( prtInfo->hMainDialog != NULL )
|
|
{
|
|
pdvRecordStop = (PDVMSG_RECORDSTOP) lpMessage;
|
|
|
|
hwndItem = GetDlgItem( prtInfo->hMainDialog, IDC_STATIC_TX );
|
|
|
|
if( hwndItem != NULL )
|
|
{
|
|
SendMessage( hwndItem, WM_SETTEXT, NULL, (LPARAM)"" );
|
|
}
|
|
_stprintf( szTmpString, _T("[DVMSGID_RECORDSTOP]") );
|
|
MainDialog_AddToLog( prtInfo->hMainDialog, szTmpString );
|
|
}
|
|
break;
|
|
case DVMSGID_PLAYERVOICESTART:
|
|
|
|
pdvPlayerVoiceStart = (PDVMSG_PLAYERVOICESTART) lpMessage;
|
|
|
|
if( prtInfo->hMainDialog != NULL )
|
|
{
|
|
hwndItem = GetDlgItem( prtInfo->hMainDialog, IDC_STATIC_RX );
|
|
|
|
if( hwndItem != NULL )
|
|
{
|
|
++s_iRxCount;
|
|
SendMessage( hwndItem, WM_SETTEXT, NULL, (LPARAM)"Rx" );
|
|
}
|
|
_stprintf( szTmpString, _T("[DVMSGID_PLAYERVOICESTART] ID=0x%x"),
|
|
pdvPlayerVoiceStart->dvidSourcePlayerID );
|
|
MainDialog_AddToLog( prtInfo->hMainDialog, szTmpString );
|
|
}
|
|
break;
|
|
case DVMSGID_PLAYERVOICESTOP:
|
|
|
|
pdvPlayerVoiceStop = (PDVMSG_PLAYERVOICESTOP) lpMessage;
|
|
|
|
if( prtInfo->hMainDialog != NULL )
|
|
{
|
|
hwndItem = GetDlgItem( prtInfo->hMainDialog, IDC_STATIC_RX );
|
|
|
|
if( hwndItem != NULL )
|
|
{
|
|
--s_iRxCount;
|
|
if (s_iRxCount <= 0)
|
|
{
|
|
SendMessage( hwndItem, WM_SETTEXT, NULL, (LPARAM)"" );
|
|
}
|
|
}
|
|
|
|
_stprintf( szTmpString, _T("[DVMSGID_PLAYERVOICESTOP] ID=0x%x"),
|
|
pdvPlayerVoiceStop->dvidSourcePlayerID );
|
|
MainDialog_AddToLog( prtInfo->hMainDialog, szTmpString );
|
|
}
|
|
break;
|
|
case DVMSGID_HOSTMIGRATED:
|
|
pdvHostMigrated = (PDVMSG_HOSTMIGRATED) lpMessage;
|
|
|
|
_stprintf( szTmpString, _T("0x%x"), pdvHostMigrated->dvidNewHostID );
|
|
|
|
SetWindowText( GetDlgItem( prtInfo->hMainDialog, IDC_STATIC_HOST ), szTmpString );
|
|
|
|
_stprintf( szTmpString, _T("[DVMSGID_HOSTMIGRATED] New Voice Host=0x%x Local=%s"), pdvHostMigrated->dvidNewHostID, pdvHostMigrated->pdvServerInterface ? _T("Yes") : _T("No") );
|
|
|
|
MainDialog_AddToLog( prtInfo->hMainDialog, szTmpString );
|
|
|
|
break;
|
|
case DVMSGID_LOSTFOCUS:
|
|
if( prtInfo->hMainDialog != NULL )
|
|
{
|
|
VoiceManager_DisplayStatus( prtInfo, _T( "Connected (Focus Lost)" ) );
|
|
}
|
|
_stprintf( szTmpString, _T("[DVMSGID_LOSTFOCUS]" ) );
|
|
MainDialog_AddToLog( prtInfo->hMainDialog, szTmpString );
|
|
break;
|
|
case DVMSGID_GAINFOCUS:
|
|
if( prtInfo->hMainDialog != NULL )
|
|
{
|
|
VoiceManager_DisplayStatus( prtInfo, _T( "Connected" ) );
|
|
}
|
|
_stprintf( szTmpString, _T("[DVMSGID_GAINFOCUS]" ));
|
|
MainDialog_AddToLog( prtInfo->hMainDialog, szTmpString );
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return DV_OK;
|
|
}
|
|
|
|
void VoiceManager_MessageLoop( PDXVHELP_RTINFO prtInfo )
|
|
{
|
|
LPBYTE lpbDataBuffer = (LPBYTE) new BYTE[30000];
|
|
|
|
if( lpbDataBuffer == NULL )
|
|
{
|
|
goto BREAK_OUT;
|
|
}
|
|
|
|
DWORD dwSize;
|
|
HRESULT hr;
|
|
LONG lWakeResult;
|
|
DWORD dwFlags;
|
|
MSG msg;
|
|
HANDLE hEvents[3];
|
|
LPDPLMSG_SYSTEMMESSAGE lpSysMessage;
|
|
LPDPMSG_GENERIC lpGenericMessage;
|
|
LPDPMSG_CREATEPLAYERORGROUP lpCreatePlayerMessage;
|
|
LPDPMSG_DESTROYPLAYERORGROUP lpDeletePlayerMessage;
|
|
BOOL bGotMsg;
|
|
DPID dpidFrom, dpidTo;
|
|
|
|
hEvents[0] = prtInfo->hShutdown;
|
|
hEvents[1] = prtInfo->hReceiveEvent;
|
|
hEvents[2] = prtInfo->hLobbyEvent;
|
|
|
|
// hr = prtInfo->lpdpDirectPlay->CreatePlayer( &prtInfo->dpidLocalPlayer, NULL, prtInfo->hReceiveEvent, NULL, 0, 0 );
|
|
|
|
while( 1 )
|
|
{
|
|
if( !prtInfo->dxvParameters.fLobbyLaunched )
|
|
{
|
|
lWakeResult = MsgWaitForMultipleObjects( 2, hEvents, FALSE, INFINITE, QS_ALLINPUT);
|
|
}
|
|
else
|
|
{
|
|
lWakeResult = MsgWaitForMultipleObjects( 3, hEvents, FALSE, INFINITE, QS_ALLINPUT);
|
|
}
|
|
|
|
if( lWakeResult == WAIT_OBJECT_0 )
|
|
{
|
|
break;
|
|
}
|
|
else if( lWakeResult == (WAIT_OBJECT_0+1) )
|
|
{
|
|
while( 1 )
|
|
{
|
|
dwSize = 30000;
|
|
|
|
hr = prtInfo->lpdpDirectPlay->Receive( &dpidFrom, &dpidTo, DPRECEIVE_ALL, lpbDataBuffer, &dwSize );
|
|
|
|
if( hr == DPERR_NOMESSAGES )
|
|
{
|
|
break;
|
|
}
|
|
|
|
lpGenericMessage = (LPDPMSG_GENERIC) lpbDataBuffer;
|
|
|
|
switch( lpGenericMessage->dwType )
|
|
{
|
|
case DPSYS_HOST:
|
|
{
|
|
MainDialog_AddToLog( prtInfo->hMainDialog, _T("[DPMSG_HOST] This client has just become the DPLAY host") );
|
|
}
|
|
break;
|
|
case DPSYS_CREATEPLAYERORGROUP:
|
|
{
|
|
TCHAR tszMessage[100];
|
|
|
|
lpCreatePlayerMessage = (LPDPMSG_CREATEPLAYERORGROUP) lpbDataBuffer;
|
|
|
|
if( lpCreatePlayerMessage->dwPlayerType == DPPLAYERTYPE_PLAYER )
|
|
{
|
|
_stprintf( tszMessage, _T("[DPMSG_CREATEPLAYER] Client 0x%x has just entered the session."), lpCreatePlayerMessage->dpId );
|
|
MainDialog_AddToLog( prtInfo->hMainDialog, tszMessage );
|
|
}
|
|
|
|
MainDialog_AddTransportPlayer( prtInfo->hMainDialog, lpCreatePlayerMessage->dpId );
|
|
}
|
|
break;
|
|
case DPSYS_DESTROYPLAYERORGROUP:
|
|
{
|
|
TCHAR tszMessage[100];
|
|
|
|
lpDeletePlayerMessage = (LPDPMSG_DESTROYPLAYERORGROUP) lpbDataBuffer;
|
|
|
|
if( lpDeletePlayerMessage->dwPlayerType == DPPLAYERTYPE_PLAYER )
|
|
{
|
|
_stprintf( tszMessage, _T("[DPMSG_DELETEPLAYER] Client 0x%x has just left the session."), lpDeletePlayerMessage->dpId );
|
|
MainDialog_AddToLog( prtInfo->hMainDialog, tszMessage );
|
|
}
|
|
|
|
MainDialog_RemoveTransportPlayer( prtInfo->hMainDialog, lpDeletePlayerMessage->dpId );
|
|
}
|
|
break;
|
|
}
|
|
|
|
}
|
|
}
|
|
else if( prtInfo->dxvParameters.fLobbyLaunched && lWakeResult == (WAIT_OBJECT_0+2) )
|
|
{
|
|
hr = DP_OK;
|
|
|
|
while( hr != DPERR_NOMESSAGES )
|
|
{
|
|
dwSize = 30000;
|
|
|
|
hr = prtInfo->lpdpLobby->ReceiveLobbyMessage( 0, 0, &dwFlags, lpbDataBuffer, &dwSize );
|
|
|
|
if( hr == DPERR_NOMESSAGES )
|
|
{
|
|
break;
|
|
}
|
|
else if( hr == DP_OK )
|
|
{
|
|
if( !prtInfo->dxvParameters.fIgnoreLobbyDestroy )
|
|
{
|
|
if( dwFlags == 0 )
|
|
{
|
|
goto BREAK_OUT;
|
|
}
|
|
else if( dwFlags && DPLMSG_SYSTEM )
|
|
{
|
|
lpSysMessage = (LPDPLMSG_SYSTEMMESSAGE) lpbDataBuffer;
|
|
|
|
if( lpSysMessage->dwType == DPLSYS_LOBBYCLIENTRELEASE )
|
|
{
|
|
goto BREAK_OUT;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DPVDX_DPERRDisplay( hr, _T("Receive Lobby Message Error"), prtInfo->dxvParameters.fSilent );
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
bGotMsg = TRUE;
|
|
|
|
while( bGotMsg )
|
|
{
|
|
bGotMsg = PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE );
|
|
|
|
if( bGotMsg )
|
|
{
|
|
TranslateMessage( &msg );
|
|
DispatchMessage( &msg );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
BREAK_OUT:
|
|
|
|
if( lpbDataBuffer )
|
|
delete [] lpbDataBuffer;
|
|
|
|
return;
|
|
}
|
|
|
|
void VoiceManager_Shutdown( PDXVHELP_RTINFO prtInfo )
|
|
{
|
|
HRESULT hr;
|
|
|
|
VoiceManager_DisplayStatus( prtInfo, _T("Disconnecting") );
|
|
|
|
if( prtInfo->lpdpLobby != NULL )
|
|
{
|
|
prtInfo->lpdpLobby->Release();
|
|
prtInfo->lpdpLobby = NULL;
|
|
}
|
|
|
|
if( prtInfo->lpdvClient != NULL )
|
|
{
|
|
VoiceManager_DisplayStatus( prtInfo, _T("Disconnecting") );
|
|
|
|
hr = prtInfo->lpdvClient->Disconnect( DVFLAGS_SYNC );
|
|
|
|
if( FAILED( hr ) )
|
|
{
|
|
DPVDX_DPERRDisplay( hr, _T("Disconnect FAILED "), prtInfo->dxvParameters.fSilent );
|
|
}
|
|
|
|
prtInfo->lpdvClient->Release();
|
|
}
|
|
|
|
if( prtInfo->lpdvServer != NULL )
|
|
{
|
|
VoiceManager_DisplayStatus( prtInfo, _T("Stopping Session") );
|
|
|
|
hr = prtInfo->lpdvServer->StopSession( 0 );
|
|
|
|
if( FAILED( hr ) )
|
|
{
|
|
DPVDX_DPERRDisplay( hr, _T("StopSession FAILED "), prtInfo->dxvParameters.fSilent );
|
|
}
|
|
|
|
prtInfo->lpdvServer->Release();
|
|
}
|
|
|
|
if( prtInfo->lpdpDirectPlay != NULL )
|
|
{
|
|
VoiceManager_DisplayStatus( prtInfo, _T("Stopping Dplay") );
|
|
prtInfo->lpdpDirectPlay->Close();
|
|
prtInfo->lpdpDirectPlay->Release();
|
|
}
|
|
|
|
CloseHandle( prtInfo->hReceiveEvent );
|
|
|
|
if( prtInfo->hLobbyEvent != NULL )
|
|
{
|
|
CloseHandle( prtInfo->hLobbyEvent );
|
|
}
|
|
|
|
MainDialog_SetIdleState( prtInfo->hMainDialog, prtInfo );
|
|
|
|
}
|
|
|
|
BOOL VoiceManager_VoiceConnect( PDXVHELP_RTINFO prtInfo )
|
|
{
|
|
DVSESSIONDESC dvSessionDesc;
|
|
DVCLIENTCONFIG dvClientConfig;
|
|
DVSOUNDDEVICECONFIG dvSoundDeviceConfig;
|
|
HRESULT hr;
|
|
DVID dvidAllPlayers = DVID_ALLPLAYERS;
|
|
|
|
// We're the host
|
|
if( prtInfo->dxvParameters.fHost )
|
|
{
|
|
VoiceManager_DisplayStatus( prtInfo, _T("Start Voice Host") );
|
|
|
|
hr = CoCreateInstance( DPVOICE_CLSID_DPVOICE, NULL, CLSCTX_INPROC_SERVER, IID_IDirectPlayVoiceServer, (void **) &prtInfo->lpdvServer );
|
|
|
|
if( FAILED( hr ) )
|
|
{
|
|
DPVDX_DVERRDisplay( hr, _T("Create of voice server failed"), prtInfo->dxvParameters.fSilent );
|
|
goto EXIT_CLEANUP;
|
|
}
|
|
|
|
hr = prtInfo->lpdvServer->Initialize( prtInfo->lpdpDirectPlay, DVMessageHandlerServer, prtInfo, NULL, 0 );
|
|
|
|
if( FAILED( hr ) )
|
|
{
|
|
DPVDX_DVERRDisplay( hr, _T("Initialize FAILED"), prtInfo->dxvParameters.fSilent );
|
|
goto EXIT_CLEANUP;
|
|
}
|
|
|
|
dvSessionDesc.dwSize = sizeof( DVSESSIONDESC );
|
|
dvSessionDesc.dwBufferAggressiveness = DVBUFFERAGGRESSIVENESS_DEFAULT;
|
|
dvSessionDesc.dwBufferQuality = DVBUFFERQUALITY_DEFAULT;
|
|
dvSessionDesc.dwFlags = 0;
|
|
dvSessionDesc.dwSessionType = prtInfo->dxvParameters.dwSessionType;
|
|
dvSessionDesc.guidCT = prtInfo->dxvParameters.guidCT;
|
|
|
|
hr = prtInfo->lpdvServer->StartSession( &dvSessionDesc, 0 );
|
|
|
|
if( FAILED( hr ) )
|
|
{
|
|
DPVDX_DVERRDisplay( hr, _T("StartSession FAILED"), prtInfo->dxvParameters.fSilent );
|
|
goto EXIT_CLEANUP;
|
|
}
|
|
}
|
|
|
|
VoiceManager_DisplayStatus( prtInfo, _T("Start Client") );
|
|
|
|
hr = CoCreateInstance( DPVOICE_CLSID_DPVOICE, NULL, CLSCTX_INPROC_SERVER, IID_IDirectPlayVoiceClient, (void **) &prtInfo->lpdvClient );
|
|
|
|
if( FAILED( hr ) )
|
|
{
|
|
DPVDX_DVERRDisplay( hr, _T("Create of client failed"), prtInfo->dxvParameters.fSilent );
|
|
goto EXIT_CLEANUP;
|
|
}
|
|
|
|
hr = prtInfo->lpdvClient->Initialize( prtInfo->lpdpDirectPlay, DVMessageHandlerClient, prtInfo, NULL, 0 );
|
|
|
|
if( FAILED( hr ) )
|
|
{
|
|
DPVDX_DVERRDisplay( hr, _T("Initialize FAILED"), prtInfo->dxvParameters.fSilent );
|
|
goto EXIT_CLEANUP;
|
|
}
|
|
|
|
dvSoundDeviceConfig.dwSize = sizeof( DVSOUNDDEVICECONFIG );
|
|
dvSoundDeviceConfig.hwndAppWindow = prtInfo->hMainWnd;
|
|
dvSoundDeviceConfig.dwFlags = 0;
|
|
|
|
if( prtInfo->dxvParameters.fForceWaveOut )
|
|
{
|
|
dvSoundDeviceConfig.dwFlags |= DVSOUNDCONFIG_FORCEWAVEOUT;
|
|
}
|
|
else if( prtInfo->dxvParameters.fAllowWaveOut )
|
|
{
|
|
dvSoundDeviceConfig.dwFlags |= DVSOUNDCONFIG_ALLOWWAVEOUT;
|
|
}
|
|
|
|
if( prtInfo->dxvParameters.fForceWaveIn )
|
|
{
|
|
dvSoundDeviceConfig.dwFlags |= DVSOUNDCONFIG_FORCEWAVEIN;
|
|
}
|
|
else if( prtInfo->dxvParameters.fAllowWaveIn )
|
|
{
|
|
dvSoundDeviceConfig.dwFlags |= DVSOUNDCONFIG_ALLOWWAVEIN;
|
|
}
|
|
|
|
if( prtInfo->dxvParameters.fAutoSelectMic )
|
|
{
|
|
dvSoundDeviceConfig.dwFlags |= DVSOUNDCONFIG_AUTOSELECT;
|
|
}
|
|
|
|
if( prtInfo->dxvParameters.fDisableFocus )
|
|
{
|
|
dvSoundDeviceConfig.dwFlags |= DVSOUNDCONFIG_NOFOCUS;
|
|
}
|
|
else if( prtInfo->dxvParameters.fStrictFocus )
|
|
{
|
|
dvSoundDeviceConfig.dwFlags |= DVSOUNDCONFIG_STRICTFOCUS;
|
|
}
|
|
|
|
dvSoundDeviceConfig.guidCaptureDevice = prtInfo->dxvParameters.guidRecordDevice;
|
|
dvSoundDeviceConfig.guidPlaybackDevice = prtInfo->dxvParameters.guidPlaybackDevice;
|
|
dvSoundDeviceConfig.lpdsPlaybackDevice = NULL;
|
|
dvSoundDeviceConfig.lpdsCaptureDevice = NULL;
|
|
dvSoundDeviceConfig.lpdsMainBuffer = NULL;
|
|
dvSoundDeviceConfig.dwMainBufferFlags = 0;
|
|
dvSoundDeviceConfig.dwMainBufferPriority = 0;
|
|
|
|
dvClientConfig.lRecordVolume = DSBVOLUME_MAX;
|
|
|
|
MicrophoneGetVolume( 0, dvClientConfig.lRecordVolume );
|
|
|
|
prtInfo->dxvParameters.lRecordVolume = dvClientConfig.lRecordVolume;
|
|
|
|
dvClientConfig.dwFlags = DVCLIENTCONFIG_AUTOVOICEACTIVATED;
|
|
|
|
if( prtInfo->dxvParameters.fAGC )
|
|
{
|
|
dvClientConfig.dwFlags |= DVCLIENTCONFIG_AUTORECORDVOLUME;
|
|
dvClientConfig.lRecordVolume = DVRECORDVOLUME_LAST;
|
|
}
|
|
|
|
if( prtInfo->dxvParameters.fEchoSuppression )
|
|
{
|
|
dvClientConfig.dwFlags |= DVCLIENTCONFIG_ECHOSUPPRESSION;
|
|
}
|
|
|
|
dvClientConfig.dwThreshold = DVTHRESHOLD_UNUSED;
|
|
dvClientConfig.lPlaybackVolume = DSBVOLUME_MAX;
|
|
dvClientConfig.dwNotifyPeriod = 51;
|
|
dvClientConfig.dwBufferQuality = DVBUFFERQUALITY_DEFAULT;
|
|
dvClientConfig.dwBufferAggressiveness = DVBUFFERAGGRESSIVENESS_DEFAULT;
|
|
|
|
dvClientConfig.dwSize = sizeof( DVCLIENTCONFIG );
|
|
|
|
VoiceManager_DisplayStatus( prtInfo, _T("Connecting Voice") );
|
|
|
|
hr = prtInfo->lpdvClient->Connect( &dvSoundDeviceConfig, &dvClientConfig, DVFLAGS_SYNC );
|
|
|
|
if( hr != DV_OK && hr != DVERR_PENDING )
|
|
{
|
|
DPVDX_DVERRDisplay( hr, _T("Connect FAILED"), prtInfo->dxvParameters.fSilent );
|
|
goto EXIT_CLEANUP;
|
|
}
|
|
|
|
MainDialog_DisplayVolumeSettings( prtInfo->hMainDialog, prtInfo );
|
|
|
|
VoiceManager_DisplayStatus( prtInfo, _T("Connected") );
|
|
|
|
MainDialog_ShowSessionSettings( prtInfo->hMainDialog, prtInfo);
|
|
|
|
prtInfo->lpdvClient->SetTransmitTargets( &dvidAllPlayers, 1, 0 );
|
|
|
|
return TRUE;
|
|
|
|
EXIT_CLEANUP:
|
|
|
|
if( prtInfo->lpdvClient != NULL )
|
|
{
|
|
prtInfo->lpdvClient->Release();
|
|
}
|
|
|
|
if( prtInfo->lpdvServer != NULL )
|
|
{
|
|
prtInfo->lpdvServer->Release();
|
|
}
|
|
|
|
MainDialog_SetIdleState( prtInfo->hMainDialog, prtInfo );
|
|
|
|
VoiceManager_DisplayStatus( prtInfo, _T("Aborted") );
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
// ManagerThread
|
|
//
|
|
// This thread is responsible for running the session, allowing the main interface
|
|
// to remain responsive.
|
|
//
|
|
DWORD WINAPI VoiceManager_ThreadProc( LPVOID lpParameter )
|
|
{
|
|
PDXVHELP_RTINFO prtInfo = (PDXVHELP_RTINFO) lpParameter;
|
|
BOOL fResult;
|
|
HANDLE hEventArray[2];
|
|
|
|
HRESULT hr = CoInitializeEx( NULL, COINIT_MULTITHREADED );
|
|
|
|
if( FAILED( hr ) )
|
|
{
|
|
goto EXIT_ERROR;
|
|
}
|
|
|
|
hEventArray[0] = prtInfo->hShutdown; // Cancel
|
|
hEventArray[1] = prtInfo->hGo; // Start Session
|
|
|
|
// Wait to be cancelled or started
|
|
if( WaitForMultipleObjects( 2, hEventArray, FALSE, INFINITE ) != WAIT_OBJECT_0 )
|
|
{
|
|
if( prtInfo->dxvParameters.fLobbyLaunched )
|
|
{
|
|
fResult = VoiceManager_LobbyConnect( prtInfo );
|
|
}
|
|
else
|
|
{
|
|
fResult = VoiceManager_StandardConnect( prtInfo );
|
|
}
|
|
|
|
if( fResult )
|
|
{
|
|
fResult = VoiceManager_VoiceConnect( prtInfo );
|
|
|
|
if( fResult )
|
|
{
|
|
VoiceManager_MessageLoop( prtInfo );
|
|
VoiceManager_Shutdown( prtInfo );
|
|
}
|
|
}
|
|
}
|
|
|
|
CoUninitialize();
|
|
|
|
EXIT_ERROR:
|
|
|
|
SetEvent( prtInfo->hThreadDone );
|
|
|
|
return 0;
|
|
}
|
|
|
|
BOOL VoiceManager_Start( PDXVHELP_RTINFO prtInfo )
|
|
{
|
|
DWORD dwThreadID = 0;
|
|
|
|
prtInfo->hManagerThread = CreateThread( NULL, 0, VoiceManager_ThreadProc, prtInfo, 0, &dwThreadID );
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL VoiceManager_Stop( PDXVHELP_RTINFO prtInfo )
|
|
{
|
|
WaitForSingleObject( prtInfo->hThreadDone, INFINITE );
|
|
|
|
CloseHandle( prtInfo->hManagerThread );
|
|
|
|
return TRUE;
|
|
}
|
|
|