home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic Game Programming for Teens / VBGPFT.cdr / DirectX8 / dx8a_sdk.exe / samples / multimedia / common / src / netvoice.cpp < prev   
Encoding:
C/C++ Source or Header  |  2000-11-04  |  13.6 KB  |  371 lines

  1. //-----------------------------------------------------------------------------
  2. // File: NetVoice.cpp
  3. //
  4. // Desc: DirectPlay Voice framework class. Feel free to use 
  5. //       this class as a starting point for adding extra functionality.
  6. //
  7. //
  8. // Copyright (c) 2000 Microsoft Corporation. All rights reserved.
  9. //-----------------------------------------------------------------------------
  10. #define STRICT
  11. #include <windows.h>
  12. #include <dxerr8.h>
  13. #include <dvoice.h>
  14. #include "NetVoice.h"
  15. #include "DXUtil.h"
  16.  
  17.  
  18.  
  19.  
  20. //-----------------------------------------------------------------------------
  21. // Name: CNetVoice
  22. // Desc: 
  23. //-----------------------------------------------------------------------------
  24. CNetVoice::CNetVoice( LPDVMESSAGEHANDLER pfnDirectPlayClientVoiceMessageHandler,
  25.                       LPDVMESSAGEHANDLER pfnDirectPlayServerVoiceMessageHandler )
  26. {
  27.     m_bHalfDuplex  = FALSE;
  28.     m_pVoiceClient = NULL;
  29.     m_pVoiceServer = NULL;
  30.     m_pfnDirectPlayClientVoiceMessageHandler = pfnDirectPlayClientVoiceMessageHandler;
  31.     m_pfnDirectPlayServerVoiceMessageHandler = pfnDirectPlayServerVoiceMessageHandler;
  32. }
  33.  
  34.  
  35.  
  36.  
  37. //-----------------------------------------------------------------------------
  38. // Name: ~CNetVoice
  39. // Desc: 
  40. //-----------------------------------------------------------------------------
  41. CNetVoice::~CNetVoice()
  42. {
  43.     Free();
  44. }
  45.  
  46.  
  47.  
  48.  
  49. //-----------------------------------------------------------------------------
  50. // Name: Init()
  51. // Desc: Initializes DirectPlay Voice.  
  52. // Params:  hDlg: the HWND of the parent window for use by the voice setup wizard
  53. //          bCreateSession:     if TRUE then it creates the DirectPlay Voice sesson.
  54. //          bConnectToSession:  if TRUE then it connects to the DirectPlay Voice
  55. //                              session.  
  56. //          pDirectPlay:        inteface to the IDirectPlay8Client or 
  57. //                              IDirectPlay8Peer interface 
  58. //          pGuidCT:            guid of the voice compression codec
  59. //          pdvClientConfig:    client config. Can be NULL if bConnectToSession is FALSE.
  60. //          lpds:               pointer to an existing DirectSound object, or NULL 
  61. //                              if none exists yet.
  62. //-----------------------------------------------------------------------------
  63. HRESULT CNetVoice::Init( HWND hDlg, BOOL bCreateSession, BOOL bConnectToSession,
  64.                          LPUNKNOWN pDirectPlay, DWORD dwSessionType, 
  65.                          GUID* pGuidCT, DVCLIENTCONFIG* pdvClientConfig, LPDIRECTSOUND lpds )
  66. {
  67.     HRESULT hr;
  68.  
  69.     // Typically the host player creates the voice session 
  70.     if( bCreateSession )
  71.     {
  72.         if( FAILED( hr = VoiceSessionCreate( pDirectPlay, dwSessionType, pGuidCT ) ) )
  73.             return DXTRACE_ERR( TEXT("VoiceSessionCreate"), hr );
  74.     }
  75.  
  76.     if( bConnectToSession )
  77.     {
  78.         // Test the voice setup to make sure the voice setup wizard has been run
  79.         if( FAILED( hr = VoiceSessionTestAudioSetup( hDlg ) ) )
  80.         {
  81.             if( hr == DVERR_USERCANCEL )
  82.                 return hr;
  83.             
  84.             return DXTRACE_ERR( TEXT("VoiceSessionTestAudioSetup"), hr );
  85.         }
  86.  
  87.         // Typically all of the clients connect to the voice session
  88.         if( FAILED( hr = VoiceSessionConnect( hDlg, pDirectPlay, pdvClientConfig, lpds ) ) )
  89.             return DXTRACE_ERR( TEXT("VoiceSessionConnect"), hr );
  90.     }
  91.  
  92.     return S_OK;
  93. }
  94.  
  95.  
  96.  
  97.  
  98. //-----------------------------------------------------------------------------
  99. // Name: Free()
  100. // Desc: Frees DirectPlayVoice
  101. //-----------------------------------------------------------------------------
  102. HRESULT CNetVoice::Free()
  103. {
  104.     HRESULT hr;
  105.  
  106.     if( m_pVoiceClient )
  107.     {
  108.         // Have all the clients disconnect from the session
  109.         if( FAILED( hr = VoiceSessionDisconnect() ) )
  110.             return DXTRACE_ERR( TEXT("VoiceSessionDisconnect"), hr );
  111.     }
  112.  
  113.     if( m_pVoiceServer )
  114.     {
  115.         // Have all the host player destroy the session 
  116.         if( FAILED( hr = VoiceSessionDestroy() ) )
  117.             return DXTRACE_ERR( TEXT("VoiceSessionDestroy"), hr );
  118.     }
  119.  
  120.     return S_OK;
  121. }
  122.  
  123.  
  124.  
  125.  
  126. //-----------------------------------------------------------------------------
  127. // Name: HostMigrate()
  128. // Desc: Starts the DirectPlayVoice session
  129. //       The host player should call this to create the voice session.  It
  130. //       stores the server interface, and addref's it.
  131. //-----------------------------------------------------------------------------
  132. HRESULT CNetVoice::HostMigrate( LPDIRECTPLAYVOICESERVER pdvServerInterface )
  133. {
  134.     if( pdvServerInterface == NULL )
  135.         return E_INVALIDARG;
  136.  
  137.     SAFE_RELEASE( m_pVoiceServer );
  138.  
  139.     m_pVoiceServer = pdvServerInterface;
  140.  
  141.     // Addref the server since we are storing the pointer.
  142.     m_pVoiceServer->AddRef();
  143.  
  144.     return S_OK;
  145. }
  146.  
  147.  
  148.  
  149.  
  150. //-----------------------------------------------------------------------------
  151. // Name: VoiceSessionTestAudioSetup()
  152. // Desc: Uses IDirectPlayVoiceSetup to test the voice setup.
  153. //       All clients should call this once to test the voice audio setup.
  154. //-----------------------------------------------------------------------------
  155. HRESULT CNetVoice::VoiceSessionTestAudioSetup( HWND hDlg )
  156. {
  157.     HRESULT hr;
  158.     LPDIRECTPLAYVOICETEST pVoiceSetup = NULL;
  159.  
  160.     // Create a DirectPlayVoice setup interface.
  161.     if( FAILED( hr = CoCreateInstance( CLSID_DirectPlayVoiceTest, NULL, 
  162.                                        CLSCTX_INPROC_SERVER,
  163.                                        IID_IDirectPlayVoiceTest, 
  164.                                        (LPVOID*) &pVoiceSetup) ) )
  165.         return DXTRACE_ERR( TEXT("CoCreateInstance"), hr );
  166.  
  167.     // Check to see if the audio tests have been run yet
  168.     GUID guidPlayback = DSDEVID_DefaultVoicePlayback;
  169.     GUID guidCapture  = DSDEVID_DefaultVoiceCapture;
  170.     hr = pVoiceSetup->CheckAudioSetup( &guidPlayback, 
  171.                                        &guidCapture, 
  172.                                        hDlg, DVFLAGS_QUERYONLY );
  173.     if( hr == DVERR_RUNSETUP )
  174.     {
  175.         // Perform the audio tests, since they need to be done before 
  176.         // any of the DPVoice calls will work.
  177.         hr = pVoiceSetup->CheckAudioSetup( &guidPlayback, &guidCapture, hDlg, DVFLAGS_ALLOWBACK );
  178.         if( FAILED(hr) )
  179.         {
  180.             if( hr == DVERR_USERCANCEL )
  181.                 return hr;
  182.             
  183.             return DXTRACE_ERR( TEXT("CheckAudioSetup"), hr );
  184.         }
  185.     }
  186.  
  187.     // Done with setup
  188.     SAFE_RELEASE( pVoiceSetup );
  189.  
  190.     return hr;
  191. }
  192.  
  193.  
  194.  
  195.  
  196. //-----------------------------------------------------------------------------
  197. // Name: VoiceSessionCreate()
  198. // Desc: Starts the DirectPlayVoice session
  199. //       The host player should call this to create the voice session.
  200. //-----------------------------------------------------------------------------
  201. HRESULT CNetVoice::VoiceSessionCreate( LPUNKNOWN pDirectPlay, DWORD dwSessionType, 
  202.                                        GUID* pGuidCT )
  203. {
  204.     HRESULT hr;
  205.  
  206.     // Create a DirectPlayVoice server interface.
  207.     if( FAILED( hr = CoCreateInstance( CLSID_DirectPlayVoiceServer, NULL, 
  208.                                        CLSCTX_INPROC_SERVER,
  209.                                        IID_IDirectPlayVoiceServer, 
  210.                                        (LPVOID*) &m_pVoiceServer ) ) )
  211.         return DXTRACE_ERR( TEXT("CoCreateInstance"), hr );
  212.  
  213.     // Init the DirectPlayVoice server
  214.     if( FAILED( hr = m_pVoiceServer->Initialize( pDirectPlay, m_pfnDirectPlayServerVoiceMessageHandler, 
  215.                                                  NULL, 0, 0 ) ) )
  216.         return DXTRACE_ERR( TEXT("Initialize"), hr );
  217.  
  218.     // Setup and start a DirectPlay session based on globals set by user choices 
  219.     // in the config dlg box.
  220.     DVSESSIONDESC dvSessionDesc;
  221.     ZeroMemory( &dvSessionDesc, sizeof(DVSESSIONDESC) );
  222.     dvSessionDesc.dwSize                 = sizeof( DVSESSIONDESC );
  223.     dvSessionDesc.dwBufferAggressiveness = DVBUFFERAGGRESSIVENESS_DEFAULT;
  224.     dvSessionDesc.dwBufferQuality        = DVBUFFERQUALITY_DEFAULT;
  225.     dvSessionDesc.dwFlags                = 0;
  226.     dvSessionDesc.dwSessionType          = dwSessionType;
  227.     dvSessionDesc.guidCT                 = *pGuidCT;
  228.  
  229.     if( FAILED( hr = m_pVoiceServer->StartSession( &dvSessionDesc, 0 ) ) )
  230.         return DXTRACE_ERR( TEXT("StartSession"), hr );
  231.  
  232.     return S_OK;
  233. }
  234.  
  235.  
  236.  
  237.  
  238. //-----------------------------------------------------------------------------
  239. // Name: VoiceSessionConnect()
  240. // Desc: Connects to the DirectPlayVoice session.  
  241. ///      All clients should call this once to join the voice session.
  242. //-----------------------------------------------------------------------------
  243. HRESULT CNetVoice::VoiceSessionConnect( HWND hDlg, LPUNKNOWN pDirectPlay, 
  244.                                         DVCLIENTCONFIG* pdvClientConfig, LPDIRECTSOUND lpds )
  245. {
  246.     HRESULT hr;
  247.  
  248.     // Create a DirectPlayVoice client interface.
  249.     if( FAILED( hr = CoCreateInstance( CLSID_DirectPlayVoiceClient, NULL, 
  250.                                        CLSCTX_INPROC_SERVER,
  251.                                        IID_IDirectPlayVoiceClient, 
  252.                                        (LPVOID*) &m_pVoiceClient ) ) )
  253.         return DXTRACE_ERR( TEXT("CoCreateInstance"), hr );
  254.  
  255.     // Init the DirectPlayVoice client, passing in VoiceMessageHandler() as the
  256.     // callback handler for any messages sent to us.
  257.     if( FAILED( hr = m_pVoiceClient->Initialize( pDirectPlay, 
  258.                                                  m_pfnDirectPlayClientVoiceMessageHandler, 
  259.                                                  (LPVOID*) hDlg, // context value
  260.                                                  0, 0 ) ) )
  261.          return DXTRACE_ERR( TEXT("Initialize"), hr );
  262.  
  263.     // Setup the DirectPlayVoice sound devices.  This just uses the defaults.
  264.     DVSOUNDDEVICECONFIG dvSoundDeviceConfig;
  265.     dvSoundDeviceConfig.dwSize                    = sizeof( DVSOUNDDEVICECONFIG );
  266.     dvSoundDeviceConfig.dwFlags                   = 0;
  267.     dvSoundDeviceConfig.guidPlaybackDevice        = DSDEVID_DefaultVoicePlayback; 
  268.     dvSoundDeviceConfig.lpdsPlaybackDevice        = lpds;
  269.     dvSoundDeviceConfig.guidCaptureDevice         = DSDEVID_DefaultVoiceCapture; 
  270.     dvSoundDeviceConfig.lpdsCaptureDevice         = NULL;
  271.     dvSoundDeviceConfig.hwndAppWindow             = hDlg;
  272.     dvSoundDeviceConfig.lpdsMainBuffer            = NULL;
  273.     dvSoundDeviceConfig.dwMainBufferFlags         = 0;
  274.     dvSoundDeviceConfig.dwMainBufferPriority      = 0;
  275.  
  276.     // Connect to the voice session
  277.     if( FAILED( hr = m_pVoiceClient->Connect( &dvSoundDeviceConfig, 
  278.                                               pdvClientConfig, 
  279.                                               DVFLAGS_SYNC ) ) )
  280.         return DXTRACE_ERR( TEXT("Connect"), hr );
  281.         
  282.     // Talk to everyone in the session
  283.     DVID dvid = DVID_ALLPLAYERS;
  284.     if( FAILED( hr = m_pVoiceClient->SetTransmitTargets( &dvid, 1, 0 ) ) )
  285.         return DXTRACE_ERR( TEXT("SetTransmitTargets"), hr );
  286.  
  287.     // Get the sound device config and extract if its half duplex
  288.     DWORD dwSize = 0;
  289.     DVSOUNDDEVICECONFIG* pdvSoundDeviceConfig = NULL;
  290.     hr = m_pVoiceClient->GetSoundDeviceConfig( pdvSoundDeviceConfig, &dwSize );
  291.     if( FAILED(hr) && hr != DVERR_BUFFERTOOSMALL )
  292.         return DXTRACE_ERR( TEXT("GetSoundDeviceConfig"), hr );
  293.     pdvSoundDeviceConfig = (DVSOUNDDEVICECONFIG*) new BYTE[ dwSize ];
  294.     ZeroMemory( pdvSoundDeviceConfig, dwSize );
  295.     pdvSoundDeviceConfig->dwSize = sizeof(DVSOUNDDEVICECONFIG);
  296.     hr = m_pVoiceClient->GetSoundDeviceConfig( pdvSoundDeviceConfig, &dwSize );
  297.     if( FAILED(hr) )
  298.         return DXTRACE_ERR( TEXT("GetSoundDeviceConfig"), hr );
  299.  
  300.     m_bHalfDuplex = ( (pdvSoundDeviceConfig->dwFlags & DVSOUNDCONFIG_HALFDUPLEX) != 0 );
  301.  
  302.     SAFE_DELETE_ARRAY( pdvSoundDeviceConfig );
  303.  
  304.     return S_OK;
  305. }
  306.  
  307.  
  308.  
  309.  
  310. //-----------------------------------------------------------------------------
  311. // Name: ChangeVoiceClientSettings()
  312. // Desc: Changes the client config to globals set by user choices 
  313. //       in the config dlg box.
  314. //-----------------------------------------------------------------------------
  315. HRESULT CNetVoice::ChangeVoiceClientSettings( DVCLIENTCONFIG* pdvClientConfig )
  316. {
  317.     HRESULT hr;
  318.  
  319.     if( m_pVoiceClient == NULL )
  320.         return CO_E_NOTINITIALIZED;
  321.  
  322.     // Change the client config
  323.     if( FAILED( hr = m_pVoiceClient->SetClientConfig( pdvClientConfig) ) )
  324.         return DXTRACE_ERR( TEXT("SetClientConfig"), hr );
  325.  
  326.     return S_OK;
  327. }
  328.  
  329.  
  330.  
  331.  
  332. //-----------------------------------------------------------------------------
  333. // Name: VoiceSessionDisconnect()
  334. // Desc: Disconnects from the DirectPlayVoice session
  335. //       All clients should call this once to leave the voice session.
  336. //-----------------------------------------------------------------------------
  337. HRESULT CNetVoice::VoiceSessionDisconnect()
  338. {
  339.     if( m_pVoiceClient )
  340.     {
  341.         m_pVoiceClient->Disconnect( DVFLAGS_SYNC );
  342.         SAFE_RELEASE( m_pVoiceClient );
  343.     }
  344.  
  345.     return S_OK;
  346. }
  347.  
  348.  
  349.  
  350.  
  351. //-----------------------------------------------------------------------------
  352. // Name: VoiceSessionDestroy()
  353. // Desc: Stops the DirectPlayVoice session
  354. //       The host player should call this once to destroy the voice session.
  355. //-----------------------------------------------------------------------------
  356. HRESULT CNetVoice::VoiceSessionDestroy()
  357. {
  358.     if( m_pVoiceServer )
  359.     {
  360.         m_pVoiceServer->StopSession( 0 );
  361.         SAFE_RELEASE( m_pVoiceServer );
  362.     }
  363.  
  364.     return S_OK;
  365. }
  366.  
  367.  
  368.  
  369.  
  370.  
  371.