home *** CD-ROM | disk | FTP | other *** search
/ Windows Game Programming for Dummies (2nd Edition) / WinGamProgFD.iso / pc / DirectX SDK / DXSDK / samples / Multimedia / Demos / DuelVoice / dputil.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2001-10-31  |  19.5 KB  |  627 lines

  1. //-----------------------------------------------------------------------------
  2. // File: DPUtil.cpp
  3. //
  4. // Desc: Communication routines
  5. //
  6. // Copyright (C) 1995-2001 Microsoft Corporation. All Rights Reserved.
  7. //-----------------------------------------------------------------------------
  8. #include "duel.h"
  9. #include "DPUtil.h"
  10. #include "lobby.h"
  11. #include "diutil.h"
  12. #include <cguid.h>
  13.  
  14.  
  15.  
  16.  
  17. //-----------------------------------------------------------------------------
  18. // Defines, constants and globals
  19. //-----------------------------------------------------------------------------
  20. #define SAFE_DELETE(p)       { if(p) { delete (p);     (p)=NULL; } }
  21. #define SAFE_DELETE_ARRAY(p) { if(p) { delete[] (p);   (p)=NULL; } }
  22. #define SAFE_RELEASE(p)      { if(p) { (p)->Release(); (p)=NULL; } }
  23.  
  24. extern GUID           g_AppGUID;         // Duel's guid
  25. extern DPLCONNECTION* g_pDPLConnection;  // Connection settings
  26. extern BOOL           g_bUseProtocol;    // DirectPlay Protocol messaging
  27. extern BOOL           g_bAsyncSupported; // Asynchronous sends supported
  28. extern LPDIRECTSOUND  g_pDS;
  29. extern BOOL           g_bHostPlayer;
  30. extern HWND           g_hwndMain;
  31.  
  32. DPSESSIONDESC2*       g_pdpsd;           // Durrent session description
  33. LPDIRECTPLAY4         g_pDP = NULL;      // DPlay object pointer
  34.  
  35. LPDIRECTPLAYVOICECLIENT g_pVoiceClient = NULL;
  36. LPDIRECTPLAYVOICESERVER g_pVoiceServer = NULL;
  37.  
  38.                                      
  39.                                          
  40. //-----------------------------------------------------------------------------
  41. // Name: CheckCaps()
  42. // Desc: Helper function to check for certain Capabilities
  43. //-----------------------------------------------------------------------------
  44. VOID CheckCaps()
  45. {
  46.     HRESULT hr;
  47.     DPCAPS  dpcaps;
  48.     ZeroMemory( &dpcaps, sizeof(DPCAPS) );
  49.     dpcaps.dwSize = sizeof(DPCAPS);
  50.  
  51.     if( NULL == g_pDP )
  52.         return;
  53.     
  54.     // The caps we are checking do not differ for guaranteed msg
  55.     hr = g_pDP->GetCaps( &dpcaps, 0 );
  56.     if( FAILED(hr) )
  57.         return;
  58.  
  59.     // Determine if Aync messages are supported.
  60.     g_bAsyncSupported = (dpcaps.dwFlags & DPCAPS_ASYNCSUPPORTED) != 0;
  61.  
  62.     // Diagnostic traces of caps supported
  63.     if( g_bAsyncSupported )
  64.     {
  65.         TRACE(_T("Capabilities supported: Async %s %s %s\n"),
  66.                  (dpcaps.dwFlags & DPCAPS_SENDPRIORITYSUPPORTED ? _T("SendPriority") : _T("")),
  67.                  (dpcaps.dwFlags & DPCAPS_SENDTIMEOUTSUPPORTED ? _T("SendTimeout") : _T("")),
  68.                  (dpcaps.dwFlags & DPCAPS_ASYNCCANCELSUPPORTED
  69.                     ? _T("AsyncCancel") 
  70.                     : (dpcaps.dwFlags & DPCAPS_ASYNCCANCELALLSUPPORTED
  71.                         ? _T("AsyncCancelAll") : _T("")))
  72.                 );
  73.     }
  74.     else
  75.         TRACE(_T("CheckCaps - Async not supported\n"));
  76. }
  77.  
  78.  
  79.  
  80.  
  81. //-----------------------------------------------------------------------------
  82. // Name: DPUtil_FreeDirectPlay()
  83. // Desc: Wrapper for DirectPlay Close API
  84. //-----------------------------------------------------------------------------
  85. HRESULT DPUtil_FreeDirectPlay()
  86. {
  87.     if( NULL == g_pDP )
  88.         return E_FAIL;
  89.  
  90.     return g_pDP->Close();
  91. }
  92.  
  93.  
  94.  
  95.  
  96. //-----------------------------------------------------------------------------
  97. // Name: DPUtil_InitDirectPlay()
  98. // Desc: Wrapper for DirectPlay Create API. Retrieves a DirectPlay4/4A
  99. //       interface based on the UNICODE flag
  100. //-----------------------------------------------------------------------------
  101. HRESULT DPUtil_InitDirectPlay( VOID* pCon )
  102. {
  103.     HRESULT hr;
  104.  
  105.     // Create a DirectPlay4(A) interface
  106. #ifdef UNICODE
  107.     hr = CoCreateInstance( CLSID_DirectPlay, NULL, CLSCTX_INPROC_SERVER,
  108.                            IID_IDirectPlay4, (VOID**)&g_pDP );
  109. #else
  110.     hr = CoCreateInstance( CLSID_DirectPlay, NULL, CLSCTX_INPROC_SERVER,
  111.                            IID_IDirectPlay4A, (VOID**)&g_pDP );
  112. #endif
  113.     if( FAILED(hr) )
  114.         return hr;
  115.  
  116.     // Initialize w/address
  117.     if( pCon )
  118.     {
  119.         hr = g_pDP->InitializeConnection( pCon, 0 );
  120.         if( FAILED(hr) )
  121.         {
  122.             g_pDP->Release();
  123.             g_pDP = NULL;
  124.             return hr;
  125.         }
  126.     }
  127.  
  128.     return S_OK;
  129. }
  130.  
  131.  
  132.  
  133.  
  134. //-----------------------------------------------------------------------------
  135. // Name: DPUtil_CreatePlayer()
  136. // Desc: Wrapper for DirectPlay CreatePlayer API. 
  137. //-----------------------------------------------------------------------------
  138. HRESULT DPUtil_CreatePlayer( DPID* ppidID, TCHAR* strPlayerName, HANDLE hEvent, 
  139.                              VOID* pData, DWORD dwDataSize )
  140. {
  141.     if( NULL == g_pDP )
  142.         return E_FAIL;
  143.  
  144.     DPNAME dpname;
  145.     ZeroMemory( &dpname, sizeof(DPNAME) );
  146.     dpname.dwSize = sizeof(DPNAME);
  147.  
  148. #ifdef UNICODE
  149.     dpname.lpszShortName  = strPlayerName;
  150. #else
  151.     dpname.lpszShortNameA = strPlayerName;
  152. #endif
  153.  
  154.     return g_pDP->CreatePlayer( ppidID, &dpname, hEvent, pData, dwDataSize, 0 );
  155. }
  156.  
  157.  
  158.  
  159.  
  160. //-----------------------------------------------------------------------------
  161. // Name: DPUtil_CreateSession()
  162. // Desc: Wrapper for DirectPlay CreateSession API.Uses the global application
  163. //       guid.
  164. //-----------------------------------------------------------------------------
  165. HRESULT DPUtil_CreateSession( TCHAR* strSessionName )
  166. {
  167.     if( NULL == g_pDP )
  168.         return DPERR_NOINTERFACE;
  169.  
  170.     DPSESSIONDESC2 dpDesc;
  171.     ZeroMemory( &dpDesc, sizeof(dpDesc) );
  172.     dpDesc.dwSize  = sizeof(dpDesc);
  173.     dpDesc.dwFlags = DPSESSION_MIGRATEHOST | DPSESSION_KEEPALIVE;
  174.     if( g_bUseProtocol )
  175.         dpDesc.dwFlags |= DPSESSION_DIRECTPLAYPROTOCOL;
  176.  
  177. #ifdef UNICODE
  178.     dpDesc.lpszSessionName  = strSessionName;
  179. #else
  180.     dpDesc.lpszSessionNameA = strSessionName;
  181. #endif
  182.  
  183.     // Set the application guid
  184.     dpDesc.guidApplication = g_AppGUID;
  185.  
  186.     HRESULT hr = g_pDP->Open( &dpDesc, DPOPEN_CREATE );
  187.  
  188.     // Check for Async message support
  189.     if( SUCCEEDED(hr) )
  190.         CheckCaps();
  191.  
  192.     return hr;
  193. }
  194.  
  195.  
  196.  
  197.  
  198. //-----------------------------------------------------------------------------
  199. // Name: DPUtil_DestroyPlayer()
  200. // Desc: Wrapper for DirectPlay DestroyPlayer API. 
  201. //-----------------------------------------------------------------------------
  202. HRESULT DPUtil_DestroyPlayer( DPID pid )
  203. {
  204.     HRESULT hr;
  205.  
  206.     if( NULL == g_pDP )
  207.         return E_FAIL;
  208.  
  209.     if( g_pVoiceClient )
  210.     {
  211.         if( FAILED( hr = DPUtil_VoiceDisconnect() ) )
  212.             return hr;
  213.     }
  214.  
  215.     if( g_pVoiceServer )
  216.     {
  217.         if( FAILED( hr = DPUtil_VoiceStop() ) )
  218.             return hr;
  219.     }
  220.  
  221.     return g_pDP->DestroyPlayer( pid );
  222. }
  223.  
  224.  
  225.  
  226.  
  227. //-----------------------------------------------------------------------------
  228. // Name: DPUtil_EnumPlayers()
  229. // Desc: Wrapper for DirectPlay API EnumPlayers
  230. //-----------------------------------------------------------------------------
  231. HRESULT DPUtil_EnumPlayers( GUID* pSessionGuid,
  232.                           LPDPENUMPLAYERSCALLBACK2 pEnumCallback, 
  233.                           VOID* pContext, DWORD dwFlags )
  234. {
  235.     if( NULL == g_pDP )
  236.         return E_FAIL;
  237.  
  238.     return g_pDP->EnumPlayers( pSessionGuid, pEnumCallback, pContext, dwFlags );
  239. }
  240.  
  241.  
  242.  
  243.  
  244. //-----------------------------------------------------------------------------
  245. // Name: DPUtil_EnumSessions()
  246. // Desc: Wrapper for DirectPlay EnumSessions API.
  247. //-----------------------------------------------------------------------------
  248. HRESULT DPUtil_EnumSessions( DWORD dwTimeout,
  249.                            LPDPENUMSESSIONSCALLBACK2 pEnumCallback, 
  250.                            VOID* pContext, DWORD dwFlags )
  251. {
  252.     if( NULL == g_pDP )
  253.         return E_FAIL;
  254.  
  255.     DPSESSIONDESC2 dpDesc;
  256.     ZeroMemory( &dpDesc, sizeof(dpDesc) );
  257.     dpDesc.dwSize = sizeof(dpDesc);
  258.     dpDesc.guidApplication = g_AppGUID;
  259.  
  260.     return g_pDP->EnumSessions( &dpDesc, dwTimeout, pEnumCallback,
  261.                                 pContext, dwFlags );
  262. }
  263.  
  264.  
  265.  
  266.  
  267. //-----------------------------------------------------------------------------
  268. // Name: DPUtil_GetPlayerLocalData()
  269. // Desc: Wrapper for DirectPlay GetPlayerData API.
  270. //-----------------------------------------------------------------------------
  271. HRESULT DPUtil_GetPlayerLocalData( DPID pid, VOID* pData, DWORD* pdwDataSize )
  272. {
  273.     if( NULL == g_pDP )
  274.         return E_FAIL;
  275.  
  276.     HRESULT hr = g_pDP->GetPlayerData( pid, pData, pdwDataSize, DPGET_LOCAL );
  277.     if( FAILED(hr) )
  278.         TRACE( TEXT("Get Player local data failed for id %d\n"), pid );
  279.  
  280.     return hr;
  281. }
  282.  
  283.  
  284.  
  285.  
  286. //-----------------------------------------------------------------------------
  287. // Name: DPUtil_GetSessionDesc()
  288. // Desc: Wrapper for DirectPlay GetSessionDesc API. 
  289. //-----------------------------------------------------------------------------
  290. HRESULT DPUtil_GetSessionDesc()
  291. {
  292.     DWORD   dwSize;
  293.     HRESULT hr;
  294.  
  295.     // Free old session desc, if any
  296.     if( g_pdpsd )
  297.         free( g_pdpsd );
  298.     g_pdpsd = NULL;
  299.  
  300.     if( NULL == g_pDP )
  301.         return E_FAIL;
  302.  
  303.     // First get the size for the session desc
  304.     hr = g_pDP->GetSessionDesc( NULL, &dwSize );
  305.     if( DPERR_BUFFERTOOSMALL == hr )
  306.     {
  307.         // Allocate memory for it
  308.         g_pdpsd = (DPSESSIONDESC2*)malloc( dwSize );
  309.         if( NULL == g_pdpsd )
  310.             return E_OUTOFMEMORY;
  311.  
  312.         // Now get the session desc
  313.         hr = g_pDP->GetSessionDesc( g_pdpsd, &dwSize );
  314.     }
  315.  
  316.     return hr;
  317. }
  318.  
  319.  
  320.  
  321.  
  322. //-----------------------------------------------------------------------------
  323. // Name: DPUtil_IsDPlayInitialized()
  324. // Desc: Returns TRUE if a DirectPlay interface exists, otherwise FALSE.
  325. //-----------------------------------------------------------------------------
  326. BOOL DPUtil_IsDPlayInitialized()
  327. {
  328.     return( g_pDP ? TRUE : FALSE );
  329. }
  330.  
  331.  
  332.  
  333.  
  334. //-----------------------------------------------------------------------------
  335. // Name: DPUtil_OpenSession()
  336. // Desc: Wrapper for DirectPlay OpenSession API. 
  337. //-----------------------------------------------------------------------------
  338. HRESULT DPUtil_OpenSession( GUID* pSessionGUID )
  339. {
  340.     if( NULL == g_pDP)
  341.         return DPERR_NOINTERFACE;
  342.  
  343.     DPSESSIONDESC2 dpDesc;
  344.     ZeroMemory( &dpDesc, sizeof(dpDesc) );
  345.     dpDesc.dwSize = sizeof(dpDesc);
  346.     if( g_bUseProtocol )
  347.         dpDesc.dwFlags = DPSESSION_DIRECTPLAYPROTOCOL;
  348.  
  349.     // Set the session guid
  350.     if( pSessionGUID )
  351.         dpDesc.guidInstance = (*pSessionGUID);
  352.     // Set the application guid
  353.     dpDesc.guidApplication = g_AppGUID;
  354.  
  355.     // Open it
  356.     HRESULT hr = g_pDP->Open( &dpDesc, DPOPEN_JOIN );
  357.  
  358.     // Check for Async message support
  359.     if( SUCCEEDED(hr) )
  360.         CheckCaps();
  361.  
  362.     return hr;
  363. }
  364.  
  365.  
  366.  
  367.  
  368. //-----------------------------------------------------------------------------
  369. // Name: DPUtil_Receive()
  370. // Desc: Wrapper for DirectPlay Receive API
  371. //-----------------------------------------------------------------------------
  372. HRESULT DPUtil_Receive( DPID* pidFrom, DPID* pidTo, DWORD dwFlags, VOID* pData,
  373.                       DWORD* pdwDataSize )
  374. {
  375.     if( NULL == g_pDP )
  376.         return E_FAIL;
  377.  
  378.     return g_pDP->Receive( pidFrom, pidTo, dwFlags, pData, pdwDataSize );
  379. }
  380.  
  381.  
  382.  
  383.  
  384. //-----------------------------------------------------------------------------
  385. // Name: DPUtil_Release()
  386. // Desc: Wrapper for DirectPlay Release API.
  387. //-----------------------------------------------------------------------------
  388. HRESULT DPUtil_Release()
  389. {
  390.     if( NULL == g_pDP )
  391.         return E_FAIL;
  392.  
  393.     // Free session desc, if any
  394.     if( g_pdpsd ) 
  395.         free( g_pdpsd );
  396.     g_pdpsd = NULL;
  397.  
  398.     // Free connection settings structure, if any (lobby stuff)
  399.     if( g_pDPLConnection )
  400.         delete[] g_pDPLConnection;
  401.     g_pDPLConnection = NULL;
  402.  
  403.     // Release dplay
  404.     HRESULT hr = g_pDP->Release();
  405.     g_pDP = NULL;
  406.  
  407.     return hr;
  408. }
  409.  
  410.  
  411.  
  412.  
  413. //-----------------------------------------------------------------------------
  414. // Name: DPUtil_Send()
  415. // Desc: Wrapper for DirectPlay Send[Ex] API.
  416. //-----------------------------------------------------------------------------
  417. HRESULT DPUtil_Send( DPID idFrom, DPID idTo, DWORD dwFlags, VOID* pData,
  418.                    DWORD dwDataSize )
  419. {
  420.     if( NULL == g_pDP )
  421.         return DPERR_NOINTERFACE;
  422.  
  423.     if (dwFlags & DPSEND_ASYNC)
  424.         // We don't specify a priority or timeout.  Would have to check
  425.         // GetCaps() first to see if they were supported
  426.         return g_pDP->SendEx( idFrom, idTo, dwFlags, pData, dwDataSize,
  427.                               0, 0, NULL, NULL );
  428.     else
  429.         return g_pDP->Send( idFrom, idTo, dwFlags, pData, dwDataSize );
  430. }
  431.  
  432.  
  433.  
  434.  
  435. //-----------------------------------------------------------------------------
  436. // Name: DPUtil_SetPlayerLocalData()
  437. // Desc: Wrapper for DirectPlay SetPlayerData API
  438. //-----------------------------------------------------------------------------
  439. HRESULT DPUtil_SetPlayerLocalData( DPID pid, VOID* pData, DWORD dwSize )
  440. {
  441.     if( NULL == g_pDP )
  442.         return E_FAIL;
  443.  
  444.     HRESULT hr = g_pDP->SetPlayerData( pid, pData, dwSize, DPSET_LOCAL );
  445.     if( FAILED(hr) )
  446.         TRACE( TEXT("Set Player local data failed for id %d\n"), pid );
  447.     
  448.     return hr;
  449. }
  450.  
  451.  
  452.  
  453.  
  454. //-----------------------------------------------------------------------------
  455. // Name: DPUtil_VoiceStart()
  456. // Desc: Starts the DirectPlayVoice session
  457. //       The host player should call this to create the voice session.
  458. //-----------------------------------------------------------------------------
  459. HRESULT DPUtil_VoiceStart()
  460. {
  461.     HRESULT hr;
  462.  
  463.     if( FAILED( hr = CoCreateInstance( CLSID_DirectPlayVoiceServer, NULL, 
  464.                                        CLSCTX_INPROC_SERVER,
  465.                                        IID_IDirectPlayVoiceServer, 
  466.                                        (LPVOID*) &g_pVoiceServer ) ) )
  467.         return hr;
  468.  
  469.     if( FAILED( hr = g_pVoiceServer->Initialize( g_pDP, NULL, NULL, 0, 0 ) ) )
  470.         return hr;
  471.  
  472.     DVSESSIONDESC dvSessionDesc;
  473.     ZeroMemory( &dvSessionDesc, sizeof(DVSESSIONDESC) );
  474.     dvSessionDesc.dwSize                 = sizeof( DVSESSIONDESC );
  475.     dvSessionDesc.dwBufferAggressiveness = DVBUFFERAGGRESSIVENESS_DEFAULT;
  476.     dvSessionDesc.dwBufferQuality        = DVBUFFERQUALITY_DEFAULT;
  477.     dvSessionDesc.dwFlags                = 0;
  478.     dvSessionDesc.dwSessionType          = DVSESSIONTYPE_PEER;
  479.     dvSessionDesc.guidCT                 = DPVCTGUID_TRUESPEECH;
  480.  
  481.     if( FAILED( hr = g_pVoiceServer->StartSession( &dvSessionDesc, 0 ) ) )
  482.         return hr;
  483.  
  484.     return S_OK;
  485. }
  486.  
  487.  
  488.  
  489.  
  490. //-----------------------------------------------------------------------------
  491. // Name: DPUtil_TestAudioSetup()
  492. // Desc: Uses IDirectPlayVoiceSetup to test the voice setup.
  493. //       All clients should call this once to test the voice audio setup.
  494. //-----------------------------------------------------------------------------
  495. HRESULT DPUtil_TestAudioSetup( HWND hDlg )
  496. {
  497.     LPDIRECTPLAYVOICETEST pVoiceSetup = NULL;
  498.     HRESULT hr;
  499.  
  500.     // Create a DirectPlayVoice setup interface.
  501.     if( FAILED( hr = CoCreateInstance( CLSID_DirectPlayVoiceTest, NULL, 
  502.                                        CLSCTX_INPROC_SERVER,
  503.                                        IID_IDirectPlayVoiceTest, 
  504.                                        (LPVOID*) &pVoiceSetup) ) )
  505.         return hr;
  506.  
  507.     // Check to see if the audio tests have been run yet
  508.     hr = pVoiceSetup->CheckAudioSetup( &DSDEVID_DefaultVoicePlayback, 
  509.                                        &DSDEVID_DefaultVoiceCapture, 
  510.                                        hDlg, DVFLAGS_QUERYONLY );
  511.  
  512.     if( hr == DVERR_RUNSETUP )
  513.     {
  514.         // Perform the audio tests, since they need to be done before 
  515.         // any of the DPVoice calls will work.
  516.         hr = pVoiceSetup->CheckAudioSetup( NULL, NULL, hDlg, 0 );
  517.     }
  518.  
  519.     if( FAILED(hr) )
  520.         return hr;
  521.  
  522.     // Done with setup
  523.     SAFE_RELEASE( pVoiceSetup );
  524.  
  525.     return S_OK;
  526. }
  527.  
  528.  
  529.  
  530.  
  531. //-----------------------------------------------------------------------------
  532. // Name: DPUtil_VoiceConnect()
  533. // Desc: Connects to the DirectPlayVoice session.  
  534. ///      All clients should call this once to join the voice session.
  535. //-----------------------------------------------------------------------------
  536. HRESULT DPUtil_VoiceConnect()
  537. {
  538.     HRESULT hr;
  539.  
  540.     if( FAILED( hr = CoCreateInstance( CLSID_DirectPlayVoiceClient, NULL, 
  541.                                        CLSCTX_INPROC_SERVER,
  542.                                        IID_IDirectPlayVoiceClient, 
  543.                                        (LPVOID*) &g_pVoiceClient ) ) )
  544.         return hr;
  545.  
  546.     if( FAILED( hr = g_pVoiceClient->Initialize( g_pDP, NULL, NULL, 0, 0 ) ) )
  547.         return hr;
  548.  
  549.     DVSOUNDDEVICECONFIG dvSoundDeviceConfig;
  550.     ZeroMemory( &dvSoundDeviceConfig, sizeof(DVSOUNDDEVICECONFIG) );
  551.     dvSoundDeviceConfig.dwSize                    = sizeof( DVSOUNDDEVICECONFIG );
  552.     dvSoundDeviceConfig.dwFlags                   = 0;
  553.     dvSoundDeviceConfig.guidPlaybackDevice        = DSDEVID_DefaultVoicePlayback; 
  554.     dvSoundDeviceConfig.lpdsPlaybackDevice        = NULL;
  555.     dvSoundDeviceConfig.guidCaptureDevice         = DSDEVID_DefaultVoiceCapture; 
  556.     dvSoundDeviceConfig.lpdsCaptureDevice         = NULL;
  557.     dvSoundDeviceConfig.hwndAppWindow             = g_hwndMain;
  558.     dvSoundDeviceConfig.lpdsMainBuffer            = NULL;
  559.     dvSoundDeviceConfig.dwMainBufferFlags         = 0;
  560.     dvSoundDeviceConfig.dwMainBufferPriority      = 0;
  561.  
  562.     DVCLIENTCONFIG dvClientConfig;
  563.     ZeroMemory( &dvClientConfig, sizeof(DVCLIENTCONFIG) );
  564.     dvClientConfig.dwSize                 = sizeof( DVCLIENTCONFIG );
  565.     dvClientConfig.dwFlags                = DVCLIENTCONFIG_AUTOVOICEACTIVATED |
  566.                                               DVCLIENTCONFIG_AUTORECORDVOLUME;
  567.     dvClientConfig.lPlaybackVolume        = DVPLAYBACKVOLUME_DEFAULT;
  568.     dvClientConfig.dwBufferQuality        = DVBUFFERQUALITY_DEFAULT;
  569.     dvClientConfig.dwBufferAggressiveness = DVBUFFERAGGRESSIVENESS_DEFAULT;
  570.     dvClientConfig.dwThreshold            = DVTHRESHOLD_UNUSED;
  571.     dvClientConfig.lRecordVolume          = 0;
  572.     dvClientConfig.dwNotifyPeriod         = 0;
  573.  
  574.     // Connect to the voice session
  575.     if( FAILED( hr = g_pVoiceClient->Connect( &dvSoundDeviceConfig, 
  576.                                               &dvClientConfig, 
  577.                                               DVFLAGS_SYNC ) ) )
  578.         return hr;
  579.         
  580.     // Talk to everyone in the session
  581.     DVID dvid = DVID_ALLPLAYERS;
  582.     if( FAILED( hr = g_pVoiceClient->SetTransmitTargets( &dvid, 1, 0 ) ) )
  583.         return hr;
  584.  
  585.     return S_OK;
  586. }
  587.  
  588.  
  589.  
  590.  
  591. //-----------------------------------------------------------------------------
  592. // Name: DPUtil_VoiceDisconnect()
  593. // Desc: Disconnects from the DirectPlayVoice session
  594. //       All clients should call this once to leave the voice session.
  595. //-----------------------------------------------------------------------------
  596. HRESULT DPUtil_VoiceDisconnect()
  597. {
  598.     if( g_pVoiceClient )
  599.     {
  600.         g_pVoiceClient->Disconnect( DVFLAGS_SYNC );
  601.         g_pVoiceClient->Release();
  602.     }
  603.  
  604.     return S_OK;
  605. }
  606.  
  607.  
  608.  
  609.  
  610. //-----------------------------------------------------------------------------
  611. // Name: DPUtil_VoiceStop()
  612. // Desc: Stops the DirectPlayVoice session
  613. //       The host player should call this once to destroy the voice session.
  614. //-----------------------------------------------------------------------------
  615. HRESULT DPUtil_VoiceStop()
  616. {
  617.     if( g_pVoiceServer )
  618.     {
  619.         g_pVoiceServer->StopSession( 0 );
  620.         g_pVoiceServer->Release();
  621.     }
  622.  
  623.     return S_OK;
  624. }
  625.  
  626.  
  627.