home *** CD-ROM | disk | FTP | other *** search
/ Windows Game Programming for Dummies (2nd Edition) / WinGamProgFD.iso / pc / DirectX SDK / DXSDK / bin / DXUtils / AppWizard / DXAppwiz.awx / TEMPLATE / NETVOICE.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  2001-10-25  |  28.7 KB  |  752 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. #define STRICT
  8. $$IF(DLG)
  9. #include "stdafx.h"
  10. $$ENDIF
  11. #include <windows.h>
  12. #include <commctrl.h>
  13. #include <dxerr8.h>
  14. #include <dvoice.h>
  15. #include "NetVoice.h"
  16. #include "NetVoiceRes.h"
  17. #include "DXUtil.h"
  18.  
  19.  
  20. //-----------------------------------------------------------------------------
  21. // Global access to the app (needed for the global WndProc())
  22. //-----------------------------------------------------------------------------
  23. static CNetVoice* g_pNetVoice = NULL;
  24.  
  25.  
  26.  
  27.  
  28. //-----------------------------------------------------------------------------
  29. // Name: CNetVoice
  30. // Desc: 
  31. //-----------------------------------------------------------------------------
  32. CNetVoice::CNetVoice( LPDVMESSAGEHANDLER pfnDirectPlayClientVoiceMessageHandler,
  33.                       LPDVMESSAGEHANDLER pfnDirectPlayServerVoiceMessageHandler )
  34. {
  35.     g_pNetVoice = this;
  36.     m_bHalfDuplex  = FALSE;
  37.     m_pVoiceClient = NULL;
  38.     m_pVoiceServer = NULL;
  39.     m_bVoiceSessionInProgress = FALSE;
  40.     m_pfnDirectPlayClientVoiceMessageHandler = pfnDirectPlayClientVoiceMessageHandler;
  41.     m_pfnDirectPlayServerVoiceMessageHandler = pfnDirectPlayServerVoiceMessageHandler;
  42. }
  43.  
  44.  
  45.  
  46.  
  47. //-----------------------------------------------------------------------------
  48. // Name: ~CNetVoice
  49. // Desc: 
  50. //-----------------------------------------------------------------------------
  51. CNetVoice::~CNetVoice()
  52. {
  53.     Free();
  54. }
  55.  
  56.  
  57.  
  58.  
  59. //-----------------------------------------------------------------------------
  60. // Name: Init()
  61. // Desc: Initializes DirectPlay Voice.  
  62. // Params:  hDlg: the HWND of the parent window for use by the voice setup wizard
  63. //          bCreateSession:     if TRUE then it creates the DirectPlay Voice sesson.
  64. //          bConnectToSession:  if TRUE then it connects to the DirectPlay Voice
  65. //                              session.  
  66. //          pDirectPlay:        inteface to the IDirectPlay8Client or 
  67. //                              IDirectPlay8Peer interface 
  68. //          pGuidCT:            guid of the voice compression codec
  69. //          pdvClientConfig:    client config. Can be NULL if bConnectToSession is FALSE.
  70. //          lpds:               pointer to an existing DirectSound object, or NULL 
  71. //                              if none exists yet.
  72. //-----------------------------------------------------------------------------
  73. HRESULT CNetVoice::Init( HWND hDlg, BOOL bCreateSession, BOOL bConnectToSession,
  74.                          LPUNKNOWN pDirectPlay, DWORD dwSessionType, 
  75.                          GUID* pGuidCT, DVCLIENTCONFIG* pdvClientConfig, LPDIRECTSOUND lpds )
  76. {
  77.     HRESULT hr;
  78.  
  79.     // Typically the host player creates the voice session 
  80.     if( bCreateSession )
  81.     {
  82.         if( FAILED( hr = VoiceSessionCreate( pDirectPlay, dwSessionType, pGuidCT ) ) )
  83.             return DXTRACE_ERR( TEXT("VoiceSessionCreate"), hr );
  84.     }
  85.  
  86.     if( bConnectToSession )
  87.     {
  88.         // Test the voice setup to make sure the voice setup wizard has been run
  89.         if( FAILED( hr = VoiceSessionTestAudioSetup( hDlg ) ) )
  90.         {
  91.             if( hr == DVERR_USERCANCEL || hr == DVERR_ALREADYPENDING )
  92.                 return hr;
  93.             
  94.             return DXTRACE_ERR( TEXT("VoiceSessionTestAudioSetup"), hr );
  95.         }
  96.  
  97.         // Typically all of the clients connect to the voice session
  98.         if( FAILED( hr = VoiceSessionConnect( hDlg, pDirectPlay, pdvClientConfig, lpds ) ) )
  99.             return DXTRACE_ERR( TEXT("VoiceSessionConnect"), hr );
  100.     }
  101.  
  102.     m_bVoiceSessionInProgress = TRUE;
  103.  
  104.     return S_OK;
  105. }
  106.  
  107.  
  108.  
  109.  
  110. //-----------------------------------------------------------------------------
  111. // Name: Free()
  112. // Desc: Frees DirectPlayVoice
  113. //-----------------------------------------------------------------------------
  114. HRESULT CNetVoice::Free()
  115. {
  116.     HRESULT hr;
  117.  
  118.     if( m_pVoiceClient )
  119.     {
  120.         // Have all the clients disconnect from the session
  121.         if( FAILED( hr = VoiceSessionDisconnect() ) )
  122.             return DXTRACE_ERR( TEXT("VoiceSessionDisconnect"), hr );
  123.     }
  124.  
  125.     if( m_pVoiceServer )
  126.     {
  127.         // Have all the host player destroy the session 
  128.         if( FAILED( hr = VoiceSessionDestroy() ) )
  129.             return DXTRACE_ERR( TEXT("VoiceSessionDestroy"), hr );
  130.     }
  131.  
  132.     return S_OK;
  133. }
  134.  
  135.  
  136.  
  137.  
  138. //-----------------------------------------------------------------------------
  139. // Name: HostMigrate()
  140. // Desc: Starts the DirectPlayVoice session
  141. //       The host player should call this to create the voice session.  It
  142. //       stores the server interface, and addref's it.
  143. //-----------------------------------------------------------------------------
  144. HRESULT CNetVoice::HostMigrate( LPDIRECTPLAYVOICESERVER pdvServerInterface )
  145. {
  146.     if( pdvServerInterface == NULL )
  147.         return E_INVALIDARG;
  148.  
  149.     SAFE_RELEASE( m_pVoiceServer );
  150.  
  151.     m_pVoiceServer = pdvServerInterface;
  152.  
  153.     // Addref the server since we are storing the pointer.
  154.     m_pVoiceServer->AddRef();
  155.  
  156.     return S_OK;
  157. }
  158.  
  159.  
  160.  
  161.  
  162. //-----------------------------------------------------------------------------
  163. // Name: VoiceSessionTestAudioSetup()
  164. // Desc: Uses IDirectPlayVoiceSetup to test the voice setup.
  165. //       All clients should call this once to test the voice audio setup.
  166. //-----------------------------------------------------------------------------
  167. HRESULT CNetVoice::VoiceSessionTestAudioSetup( HWND hDlg )
  168. {
  169.     HRESULT hr;
  170.     LPDIRECTPLAYVOICETEST pVoiceSetup = NULL;
  171.  
  172.     // Create a DirectPlayVoice setup interface.
  173.     if( FAILED( hr = CoCreateInstance( CLSID_DirectPlayVoiceTest, NULL, 
  174.                                        CLSCTX_INPROC_SERVER,
  175.                                        IID_IDirectPlayVoiceTest, 
  176.                                        (LPVOID*) &pVoiceSetup) ) )
  177.         return DXTRACE_ERR( TEXT("CoCreateInstance"), hr );
  178.  
  179.     // Check to see if the audio tests have been run yet
  180.     GUID guidPlayback = DSDEVID_DefaultVoicePlayback;
  181.     GUID guidCapture  = DSDEVID_DefaultVoiceCapture;
  182.     hr = pVoiceSetup->CheckAudioSetup( &guidPlayback, 
  183.                                        &guidCapture, 
  184.                                        hDlg, DVFLAGS_QUERYONLY );
  185.     if( hr == DVERR_RUNSETUP )
  186.     {
  187.         // Perform the audio tests, since they need to be done before 
  188.         // any of the DPVoice calls will work.
  189.         hr = pVoiceSetup->CheckAudioSetup( &guidPlayback, &guidCapture, hDlg, DVFLAGS_ALLOWBACK );
  190.         if( FAILED(hr) )
  191.         {
  192.             SAFE_RELEASE( pVoiceSetup );
  193.             
  194.             if( hr == DVERR_USERCANCEL || hr == DVERR_ALREADYPENDING )
  195.                 return hr;
  196.             
  197.             return DXTRACE_ERR( TEXT("CheckAudioSetup"), hr );
  198.         }
  199.     }
  200.  
  201.     // Done with setup
  202.     SAFE_RELEASE( pVoiceSetup );
  203.  
  204.     return hr;
  205. }
  206.  
  207.  
  208.  
  209.  
  210. //-----------------------------------------------------------------------------
  211. // Name: VoiceSessionCreate()
  212. // Desc: Starts the DirectPlayVoice session
  213. //       The host player should call this to create the voice session.
  214. //-----------------------------------------------------------------------------
  215. HRESULT CNetVoice::VoiceSessionCreate( LPUNKNOWN pDirectPlay, DWORD dwSessionType, 
  216.                                        GUID* pGuidCT )
  217. {
  218.     HRESULT hr;
  219.  
  220.     // Create a DirectPlayVoice server interface.
  221.     if( FAILED( hr = CoCreateInstance( CLSID_DirectPlayVoiceServer, NULL, 
  222.                                        CLSCTX_INPROC_SERVER,
  223.                                        IID_IDirectPlayVoiceServer, 
  224.                                        (LPVOID*) &m_pVoiceServer ) ) )
  225.         return DXTRACE_ERR( TEXT("CoCreateInstance"), hr );
  226.  
  227.     // Init the DirectPlayVoice server
  228.     if( FAILED( hr = m_pVoiceServer->Initialize( pDirectPlay, m_pfnDirectPlayServerVoiceMessageHandler, 
  229.                                                  NULL, 0, 0 ) ) )
  230.         return DXTRACE_ERR( TEXT("Initialize"), hr );
  231.  
  232.     // Setup and start a DirectPlay session based on globals set by user choices 
  233.     // in the config dlg box.
  234.     DVSESSIONDESC dvSessionDesc;
  235.     ZeroMemory( &dvSessionDesc, sizeof(DVSESSIONDESC) );
  236.     dvSessionDesc.dwSize                 = sizeof( DVSESSIONDESC );
  237.     dvSessionDesc.dwBufferAggressiveness = DVBUFFERAGGRESSIVENESS_DEFAULT;
  238.     dvSessionDesc.dwBufferQuality        = DVBUFFERQUALITY_DEFAULT;
  239.     dvSessionDesc.dwFlags                = 0;
  240.     dvSessionDesc.dwSessionType          = dwSessionType;
  241.     dvSessionDesc.guidCT                 = *pGuidCT;
  242.  
  243.     if( FAILED( hr = m_pVoiceServer->StartSession( &dvSessionDesc, 0 ) ) )
  244.         return DXTRACE_ERR( TEXT("StartSession"), hr );
  245.  
  246.     return S_OK;
  247. }
  248.  
  249.  
  250.  
  251.  
  252. //-----------------------------------------------------------------------------
  253. // Name: VoiceSessionConnect()
  254. // Desc: Connects to the DirectPlayVoice session.  
  255. ///      All clients should call this once to join the voice session.
  256. //-----------------------------------------------------------------------------
  257. HRESULT CNetVoice::VoiceSessionConnect( HWND hDlg, LPUNKNOWN pDirectPlay, 
  258.                                         DVCLIENTCONFIG* pdvClientConfig, LPDIRECTSOUND lpds )
  259. {
  260.     HRESULT hr;
  261.  
  262.     // Create a DirectPlayVoice client interface.
  263.     if( FAILED( hr = CoCreateInstance( CLSID_DirectPlayVoiceClient, NULL, 
  264.                                        CLSCTX_INPROC_SERVER,
  265.                                        IID_IDirectPlayVoiceClient, 
  266.                                        (LPVOID*) &m_pVoiceClient ) ) )
  267.         return DXTRACE_ERR( TEXT("CoCreateInstance"), hr );
  268.  
  269.     // Init the DirectPlayVoice client, passing in VoiceMessageHandler() as the
  270.     // callback handler for any messages sent to us.
  271.     if( FAILED( hr = m_pVoiceClient->Initialize( pDirectPlay, 
  272.                                                  m_pfnDirectPlayClientVoiceMessageHandler, 
  273.                                                  (LPVOID*) hDlg, // context value
  274.                                                  0, 0 ) ) )
  275.          return DXTRACE_ERR( TEXT("Initialize"), hr );
  276.  
  277.     // Setup the DirectPlayVoice sound devices.  This just uses the defaults.
  278.     DVSOUNDDEVICECONFIG dvSoundDeviceConfig;
  279.     dvSoundDeviceConfig.dwSize                    = sizeof( DVSOUNDDEVICECONFIG );
  280.     dvSoundDeviceConfig.dwFlags                   = 0;
  281.     dvSoundDeviceConfig.guidPlaybackDevice        = DSDEVID_DefaultVoicePlayback; 
  282.     dvSoundDeviceConfig.lpdsPlaybackDevice        = lpds;
  283.     dvSoundDeviceConfig.guidCaptureDevice         = DSDEVID_DefaultVoiceCapture; 
  284.     dvSoundDeviceConfig.lpdsCaptureDevice         = NULL;
  285.     dvSoundDeviceConfig.hwndAppWindow             = hDlg;
  286.     dvSoundDeviceConfig.lpdsMainBuffer            = NULL;
  287.     dvSoundDeviceConfig.dwMainBufferFlags         = 0;
  288.     dvSoundDeviceConfig.dwMainBufferPriority      = 0;
  289.  
  290.     // Connect to the voice session
  291.     if( FAILED( hr = m_pVoiceClient->Connect( &dvSoundDeviceConfig, 
  292.                                               pdvClientConfig, 
  293.                                               DVFLAGS_SYNC ) ) )
  294.         return DXTRACE_ERR( TEXT("Connect"), hr );
  295.         
  296.     // Talk to everyone in the session
  297.     DVID dvid = DVID_ALLPLAYERS;
  298.     if( FAILED( hr = m_pVoiceClient->SetTransmitTargets( &dvid, 1, 0 ) ) )
  299.         return DXTRACE_ERR( TEXT("SetTransmitTargets"), hr );
  300.  
  301.     // Get the sound device config and extract if its half duplex
  302.     DWORD dwSize = 0;
  303.     DVSOUNDDEVICECONFIG* pdvSoundDeviceConfig = NULL;
  304.     hr = m_pVoiceClient->GetSoundDeviceConfig( pdvSoundDeviceConfig, &dwSize );
  305.     if( FAILED(hr) && hr != DVERR_BUFFERTOOSMALL )
  306.         return DXTRACE_ERR( TEXT("GetSoundDeviceConfig"), hr );
  307.     pdvSoundDeviceConfig = (DVSOUNDDEVICECONFIG*) new BYTE[ dwSize ];
  308.     ZeroMemory( pdvSoundDeviceConfig, dwSize );
  309.     pdvSoundDeviceConfig->dwSize = sizeof(DVSOUNDDEVICECONFIG);
  310.     hr = m_pVoiceClient->GetSoundDeviceConfig( pdvSoundDeviceConfig, &dwSize );
  311.     if( FAILED(hr) )
  312.         return DXTRACE_ERR( TEXT("GetSoundDeviceConfig"), hr );
  313.  
  314.     m_bHalfDuplex = ( (pdvSoundDeviceConfig->dwFlags & DVSOUNDCONFIG_HALFDUPLEX) != 0 );
  315.  
  316.     SAFE_DELETE_ARRAY( pdvSoundDeviceConfig );
  317.  
  318.     return S_OK;
  319. }
  320.  
  321.  
  322.  
  323.  
  324. //-----------------------------------------------------------------------------
  325. // Name: ChangeVoiceClientSettings()
  326. // Desc: Changes the client config to globals set by user choices 
  327. //       in the config dlg box.
  328. //-----------------------------------------------------------------------------
  329. HRESULT CNetVoice::ChangeVoiceClientSettings( DVCLIENTCONFIG* pdvClientConfig )
  330. {
  331.     HRESULT hr;
  332.  
  333.     if( m_pVoiceClient == NULL )
  334.         return CO_E_NOTINITIALIZED;
  335.  
  336.     // Change the client config
  337.     if( FAILED( hr = m_pVoiceClient->SetClientConfig( pdvClientConfig) ) )
  338.         return DXTRACE_ERR( TEXT("SetClientConfig"), hr );
  339.  
  340.     return S_OK;
  341. }
  342.  
  343.  
  344.  
  345.  
  346. //-----------------------------------------------------------------------------
  347. // Name: VoiceSessionDisconnect()
  348. // Desc: Disconnects from the DirectPlayVoice session
  349. //       All clients should call this once to leave the voice session.
  350. //-----------------------------------------------------------------------------
  351. HRESULT CNetVoice::VoiceSessionDisconnect()
  352. {
  353.     if( m_pVoiceClient )
  354.     {
  355.         m_pVoiceClient->Disconnect( DVFLAGS_SYNC );
  356.         SAFE_RELEASE( m_pVoiceClient );
  357.     }
  358.  
  359.     return S_OK;
  360. }
  361.  
  362.  
  363.  
  364.  
  365. //-----------------------------------------------------------------------------
  366. // Name: VoiceSessionDestroy()
  367. // Desc: Stops the DirectPlayVoice session
  368. //       The host player should call this once to destroy the voice session.
  369. //-----------------------------------------------------------------------------
  370. HRESULT CNetVoice::VoiceSessionDestroy()
  371. {
  372.     if( m_pVoiceServer )
  373.     {
  374.         m_pVoiceServer->StopSession( 0 );
  375.         SAFE_RELEASE( m_pVoiceServer );
  376.     }
  377.  
  378.     return S_OK;
  379. }
  380.  
  381.  
  382.  
  383.  
  384. //-----------------------------------------------------------------------------
  385. // Name: DoVoiceSetupDialog()
  386. // Desc: 
  387. //-----------------------------------------------------------------------------
  388. HRESULT CNetVoice::DoVoiceSetupDialog( HINSTANCE hInst, HWND hWndParent, GUID* pguidDVSessionCT, DVCLIENTCONFIG* pdvClientConfig )
  389. {
  390.     if( NULL == pguidDVSessionCT || NULL == pdvClientConfig )
  391.         return E_INVALIDARG;
  392.  
  393.     m_guidDVSessionCT = *pguidDVSessionCT;
  394.     m_dvClientConfig = *pdvClientConfig;
  395.  
  396.     // Ask user to change m_dvClientConfig, g_guidDVSessionCT
  397.     DWORD dwResult = (DWORD)DialogBox( hInst, MAKEINTRESOURCE(IDD_VOICE_SETUP), 
  398.                                        hWndParent, (DLGPROC) StaticVoiceConfigDlgProc );
  399.     if( dwResult == IDCANCEL )
  400.         return DVERR_USERCANCEL;
  401.  
  402.     *pguidDVSessionCT = m_guidDVSessionCT;
  403.     *pdvClientConfig = m_dvClientConfig;
  404.  
  405.     return S_OK;
  406. }
  407.  
  408.  
  409.  
  410.  
  411. //-----------------------------------------------------------------------------
  412. // Name: StaticVoiceConfigDlgProc()
  413. // Desc: Static callback helper to call into CNetVoice class
  414. //-----------------------------------------------------------------------------
  415. INT_PTR CALLBACK CNetVoice::StaticVoiceConfigDlgProc( HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam )
  416. {
  417.     if( g_pNetVoice )
  418.         return g_pNetVoice->VoiceConfigDlgProc( hDlg, msg, wParam, lParam );
  419.     return 0;
  420. }
  421.  
  422.  
  423.  
  424.  
  425.  
  426. //-----------------------------------------------------------------------------
  427. // Name: VoiceConfigDlgProc()
  428. // Desc: Prompt the user for DirectPlayVoice setup options
  429. //-----------------------------------------------------------------------------
  430. INT_PTR CALLBACK CNetVoice::VoiceConfigDlgProc( HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam )
  431. {
  432.     DWORD dwSliderPos;
  433.  
  434.     switch( msg ) 
  435.     {
  436.         case WM_INITDIALOG:
  437.             // Set the range on the sliders
  438.             SendDlgItemMessage( hDlg, IDC_PLAYBACK_SLIDER,       TBM_SETRANGE, FALSE, MAKELONG( 0, 100 ) );
  439.             SendDlgItemMessage( hDlg, IDC_RECORD_SLIDER,         TBM_SETRANGE, FALSE, MAKELONG( 0, 100 ) );
  440.             SendDlgItemMessage( hDlg, IDC_QUALITY_SLIDER,        TBM_SETRANGE, FALSE, MAKELONG( DVBUFFERQUALITY_MIN, DVBUFFERQUALITY_MAX ) );
  441.             SendDlgItemMessage( hDlg, IDC_THRESHOLD_SLIDER,    TBM_SETRANGE, FALSE, MAKELONG( DVTHRESHOLD_MIN,  DVTHRESHOLD_MAX ) );
  442.             SendDlgItemMessage( hDlg, IDC_AGGRESSIVENESS_SLIDER, TBM_SETRANGE, FALSE, MAKELONG( DVBUFFERAGGRESSIVENESS_MIN, DVBUFFERAGGRESSIVENESS_MAX ) );
  443.  
  444.             // Setup the dialog based on the globals 
  445.  
  446.             // Set the playback controls
  447.             if( m_dvClientConfig.lPlaybackVolume == DVPLAYBACKVOLUME_DEFAULT )
  448.             {
  449.                 CheckRadioButton( hDlg, IDC_PLAYBACK_DEFAULT, IDC_PLAYBACK_SET, IDC_PLAYBACK_DEFAULT );
  450.             }
  451.             else
  452.             {
  453.                 dwSliderPos = (DWORD) ( ( m_dvClientConfig.lPlaybackVolume - DSBVOLUME_MIN ) * 
  454.                                           100.0f / (DSBVOLUME_MAX-DSBVOLUME_MIN) );
  455.                 CheckRadioButton( hDlg, IDC_PLAYBACK_DEFAULT, IDC_PLAYBACK_SET, IDC_PLAYBACK_SET );
  456.                 SendDlgItemMessage( hDlg, IDC_PLAYBACK_SLIDER, TBM_SETPOS, TRUE, dwSliderPos );
  457.             }
  458.  
  459.             // Set the record controls
  460.             if( m_dvClientConfig.dwFlags & DVCLIENTCONFIG_AUTORECORDVOLUME )
  461.             {
  462.                 CheckRadioButton( hDlg, IDC_RECORD_DEFAULT, IDC_RECORD_AUTO, IDC_RECORD_AUTO );
  463.             }
  464.             else if( m_dvClientConfig.lRecordVolume == DVPLAYBACKVOLUME_DEFAULT )
  465.             {
  466.                 CheckRadioButton( hDlg, IDC_RECORD_DEFAULT, IDC_RECORD_AUTO, IDC_RECORD_DEFAULT );
  467.             }
  468.             else
  469.             {
  470.                 dwSliderPos = (DWORD) ( ( m_dvClientConfig.lRecordVolume - DSBVOLUME_MIN ) * 
  471.                                           100.0f / (DSBVOLUME_MAX-DSBVOLUME_MIN) );
  472.                 CheckRadioButton( hDlg, IDC_RECORD_DEFAULT, IDC_RECORD_AUTO, IDC_RECORD_SET );
  473.                 SendDlgItemMessage( hDlg, IDC_RECORD_SLIDER, TBM_SETPOS, TRUE, dwSliderPos );
  474.             }
  475.  
  476.             // Set the threshold controls
  477.             if( m_dvClientConfig.dwFlags & DVCLIENTCONFIG_AUTOVOICEACTIVATED )
  478.             {
  479.                 CheckRadioButton( hDlg, IDC_THRESHOLD_DEFAULT, IDC_THRESHOLD_AUTO, IDC_THRESHOLD_AUTO );
  480.             }
  481.             else if( m_dvClientConfig.dwThreshold == DVTHRESHOLD_DEFAULT )
  482.             {
  483.                 CheckRadioButton( hDlg, IDC_THRESHOLD_DEFAULT, IDC_THRESHOLD_AUTO, IDC_THRESHOLD_DEFAULT );
  484.             }
  485.             else
  486.             {
  487.                 CheckRadioButton( hDlg, IDC_THRESHOLD_DEFAULT, IDC_THRESHOLD_AUTO, IDC_THRESHOLD_SET );
  488.                 SendDlgItemMessage( hDlg, IDC_THRESHOLD_SLIDER, TBM_SETPOS, TRUE, m_dvClientConfig.dwThreshold );
  489.             }
  490.  
  491.             // Set the quality controls
  492.             if( m_dvClientConfig.dwBufferQuality == DVBUFFERQUALITY_DEFAULT )
  493.             {
  494.                 CheckRadioButton( hDlg, IDC_QUALITY_DEFAULT, IDC_QUALITY_SET, IDC_QUALITY_DEFAULT );
  495.             }
  496.             else
  497.             {
  498.                 CheckRadioButton( hDlg, IDC_QUALITY_DEFAULT, IDC_QUALITY_SET, IDC_QUALITY_SET );
  499.                 SendDlgItemMessage( hDlg, IDC_QUALITY_SLIDER, TBM_SETPOS, TRUE, m_dvClientConfig.dwBufferQuality );
  500.             }
  501.  
  502.             // Set the aggressiveness controls
  503.             if( m_dvClientConfig.dwBufferAggressiveness == DVBUFFERAGGRESSIVENESS_DEFAULT )
  504.             {
  505.                 CheckRadioButton( hDlg, IDC_AGGRESSIVENESS_DEFAULT, IDC_AGGRESSIVENESS_SET, IDC_AGGRESSIVENESS_DEFAULT );
  506.             }
  507.             else
  508.             {
  509.                 CheckRadioButton( hDlg, IDC_AGGRESSIVENESS_DEFAULT, IDC_AGGRESSIVENESS_SET, IDC_AGGRESSIVENESS_SET );
  510.                 SendDlgItemMessage( hDlg, IDC_AGGRESSIVENESS_SLIDER, TBM_SETPOS, TRUE, m_dvClientConfig.dwBufferAggressiveness );
  511.             }
  512.  
  513.             if( !m_bHostPlayer || m_bVoiceSessionInProgress )
  514.             {
  515.                 // We are are not the host player then disable all the server only options 
  516.                 EnableWindow( GetDlgItem( hDlg, IDC_COMPRESSION_COMBO ), FALSE );
  517.                 EnableWindow( GetDlgItem( hDlg, IDC_SESSIONCOMPRESION_GROUP ), FALSE );
  518.             }
  519.             else
  520.             {
  521.                 VoiceConfigEnumCompressionCodecs( hDlg );   
  522.                 EnableWindow( GetDlgItem( hDlg, IDCANCEL ), FALSE );
  523.             }
  524.  
  525.             return TRUE;
  526.  
  527.         case WM_NOTIFY:
  528.             #ifndef NM_RELEASEDCAPTURE
  529.                 #define NM_RELEASEDCAPTURE (NM_FIRST-16)
  530.             #endif
  531.             if( ((LPNMHDR) lParam)->code == NM_RELEASEDCAPTURE )
  532.             {
  533.                 // If this is a release capture from a slider, then automatically check 
  534.                 // its 'Set' radio button.
  535.                 switch( ((LPNMHDR) lParam)->idFrom )
  536.                 {
  537.                 case IDC_PLAYBACK_SLIDER:
  538.                     CheckRadioButton( hDlg, IDC_PLAYBACK_DEFAULT, IDC_PLAYBACK_SET, IDC_PLAYBACK_SET );
  539.                     break;
  540.     
  541.                 case IDC_RECORD_SLIDER:
  542.                     CheckRadioButton( hDlg, IDC_RECORD_DEFAULT, IDC_RECORD_AUTO, IDC_RECORD_SET );
  543.                     break;
  544.     
  545.                 case IDC_THRESHOLD_SLIDER:
  546.                     CheckRadioButton( hDlg, IDC_THRESHOLD_DEFAULT, IDC_THRESHOLD_AUTO, IDC_THRESHOLD_SET );
  547.                     break;
  548.     
  549.                 case IDC_QUALITY_SLIDER:
  550.                     CheckRadioButton( hDlg, IDC_QUALITY_DEFAULT, IDC_QUALITY_SET, IDC_QUALITY_SET );
  551.                     break;
  552.     
  553.                 case IDC_AGGRESSIVENESS_SLIDER:
  554.                     CheckRadioButton( hDlg, IDC_AGGRESSIVENESS_DEFAULT, IDC_AGGRESSIVENESS_SET, IDC_AGGRESSIVENESS_SET );
  555.                     break;
  556.                 }
  557.             }
  558.             return TRUE;            
  559.  
  560.         case WM_COMMAND:
  561.             switch( LOWORD(wParam) )
  562.             {
  563.                 case IDOK:
  564.                     VoiceConfigDlgOnOK( hDlg );
  565.                     return TRUE;
  566.  
  567.                 case IDCANCEL:
  568.                     EndDialog( hDlg, IDCANCEL );
  569.                     return TRUE;
  570.             }
  571.             break;
  572.  
  573.         case WM_DESTROY:
  574.         {
  575.             GUID* pGuid;
  576.             int nCount = (int)SendDlgItemMessage( hDlg, IDC_COMPRESSION_COMBO, CB_GETCOUNT, 0, 0 );
  577.             for( int i=0; i<nCount; i++ )
  578.             {
  579.                 pGuid = (LPGUID) SendDlgItemMessage( hDlg, IDC_COMPRESSION_COMBO, CB_GETITEMDATA, i, 0 );
  580.                 SAFE_DELETE( pGuid );
  581.             }
  582.             break;
  583.         }
  584.     }
  585.  
  586.     return FALSE; // Didn't handle message
  587. }
  588.  
  589.  
  590.  
  591.  
  592. //-----------------------------------------------------------------------------
  593. // Name: VoiceConfigEnumCompressionCodecs()
  594. // Desc: Asks DirectPlayVoice what voice compression codecs are availible
  595. //       and fills the combo box thier names and GUIDs.
  596. //-----------------------------------------------------------------------------
  597. HRESULT CNetVoice::VoiceConfigEnumCompressionCodecs( HWND hDlg )
  598. {
  599.     LPDIRECTPLAYVOICECLIENT pVoiceClient        = NULL;
  600.     LPDVCOMPRESSIONINFO     pdvCompressionInfo  = NULL;
  601.     LPGUID  pGuid         = NULL;
  602.     LPBYTE  pBuffer       = NULL;
  603.     DWORD   dwSize        = 0;
  604.     DWORD   dwNumElements = 0;
  605.     HWND    hPulldown     = GetDlgItem( hDlg, IDC_COMPRESSION_COMBO );
  606.     HRESULT hr;
  607.     LONG    lIndex;
  608.     LONG    lFirst;
  609.  
  610.     CoInitializeEx( NULL, COINIT_MULTITHREADED );
  611.     if( FAILED( hr = CoCreateInstance( CLSID_DirectPlayVoiceClient, NULL, 
  612.                                        CLSCTX_INPROC_SERVER, IID_IDirectPlayVoiceClient, 
  613.                                        (VOID**) &pVoiceClient ) ) )
  614.         return DXTRACE_ERR( TEXT("CoCreateInstance"), hr );
  615.  
  616.     hr = pVoiceClient->GetCompressionTypes( pBuffer, &dwSize, &dwNumElements, 0 );
  617.     if( hr != DVERR_BUFFERTOOSMALL && FAILED(hr) )
  618.         return DXTRACE_ERR( TEXT("GetCompressionTypes"), hr );
  619.  
  620.     pBuffer = new BYTE[dwSize];
  621.     if( FAILED( hr = pVoiceClient->GetCompressionTypes( pBuffer, &dwSize, 
  622.                                                         &dwNumElements, 0 ) ) )
  623.         return DXTRACE_ERR( TEXT("GetCompressionTypes"), hr );
  624.  
  625.     SAFE_RELEASE( pVoiceClient );
  626.     CoUninitialize();
  627.  
  628.     pdvCompressionInfo = (LPDVCOMPRESSIONINFO) pBuffer;
  629.     for( DWORD dwIndex = 0; dwIndex < dwNumElements; dwIndex++ )
  630.     {
  631.         TCHAR strName[MAX_PATH];
  632.         DXUtil_ConvertWideStringToGeneric( strName, 
  633.                                            pdvCompressionInfo[dwIndex].lpszName );
  634.  
  635.         lIndex = (LONG)SendMessage( hPulldown, CB_ADDSTRING, 0, (LPARAM) strName );
  636.  
  637.         pGuid = new GUID;
  638.         (*pGuid) = pdvCompressionInfo[dwIndex].guidType;
  639.         SendMessage( hPulldown, CB_SETITEMDATA, lIndex, (LPARAM) pGuid );
  640.  
  641.         if( pdvCompressionInfo[dwIndex].guidType == DPVCTGUID_SC03 )
  642.             lFirst = lIndex;
  643.     }
  644.  
  645.     SAFE_DELETE_ARRAY( pBuffer );
  646.     SendMessage( hPulldown, CB_SETCURSEL, lFirst, 0 );
  647.  
  648.     return S_OK;
  649. }
  650.  
  651.  
  652.  
  653.  
  654. //-----------------------------------------------------------------------------
  655. // Name: VoiceConfigDlgOnOK()
  656. // Desc: Figure out all the DirectPlayVoice setup params from the dialog box,
  657. //       and store them in global vars.
  658. //-----------------------------------------------------------------------------
  659. VOID CNetVoice::VoiceConfigDlgOnOK( HWND hDlg )
  660. {
  661.     DWORD dwSliderPos;
  662.  
  663.     m_dvClientConfig.dwFlags = 0;
  664.  
  665.     // Figure out the playback params
  666.     if( IsDlgButtonChecked( hDlg, IDC_PLAYBACK_DEFAULT ) )
  667.     {
  668.         m_dvClientConfig.lPlaybackVolume = DVPLAYBACKVOLUME_DEFAULT;
  669.     }
  670.     else 
  671.     {
  672.         dwSliderPos = (DWORD)SendDlgItemMessage( hDlg, IDC_PLAYBACK_SLIDER, TBM_GETPOS, 0, 0 );
  673.         m_dvClientConfig.lPlaybackVolume = DSBVOLUME_MIN + (LONG) ( dwSliderPos / 100.0f * 
  674.                                                                     (DSBVOLUME_MAX-DSBVOLUME_MIN) );
  675.     }
  676.  
  677.     // Figure out the record params
  678.     if( IsDlgButtonChecked( hDlg, IDC_RECORD_AUTO ) )
  679.     {
  680.         m_dvClientConfig.lRecordVolume = 0;
  681.         m_dvClientConfig.dwFlags       |= DVCLIENTCONFIG_AUTORECORDVOLUME;
  682.     }
  683.     else if( IsDlgButtonChecked( hDlg, IDC_RECORD_DEFAULT ) )
  684.     {
  685.         m_dvClientConfig.lRecordVolume = DVPLAYBACKVOLUME_DEFAULT;
  686.     }
  687.     else 
  688.     {
  689.         dwSliderPos = (DWORD)SendDlgItemMessage( hDlg, IDC_RECORD_SLIDER, TBM_GETPOS, 0, 0 );
  690.         m_dvClientConfig.lRecordVolume = DSBVOLUME_MIN + (LONG) ( dwSliderPos / 100.0f * 
  691.                                                                   (DSBVOLUME_MAX-DSBVOLUME_MIN) );
  692.     }
  693.  
  694.     // Figure out the threshold params
  695.     if( IsDlgButtonChecked( hDlg, IDC_THRESHOLD_AUTO ) )
  696.     {
  697.         m_dvClientConfig.dwThreshold = DVTHRESHOLD_UNUSED;
  698.         m_dvClientConfig.dwFlags       |= DVCLIENTCONFIG_AUTOVOICEACTIVATED;
  699.     }
  700.     else if( IsDlgButtonChecked( hDlg, IDC_THRESHOLD_DEFAULT ) )
  701.     {
  702.         m_dvClientConfig.dwThreshold = DVTHRESHOLD_DEFAULT;
  703.         m_dvClientConfig.dwFlags       |= DVCLIENTCONFIG_MANUALVOICEACTIVATED;
  704.     }
  705.     else 
  706.     {
  707.         dwSliderPos = (DWORD)SendDlgItemMessage( hDlg, IDC_THRESHOLD_SLIDER, TBM_GETPOS, 0, 0 );
  708.         m_dvClientConfig.dwThreshold = dwSliderPos;
  709.         m_dvClientConfig.dwFlags       |= DVCLIENTCONFIG_MANUALVOICEACTIVATED;
  710.     }
  711.  
  712.     // Figure out the quality params
  713.     if( IsDlgButtonChecked( hDlg, IDC_QUALITY_DEFAULT ) )
  714.     {
  715.         m_dvClientConfig.dwBufferQuality = DVBUFFERQUALITY_DEFAULT;
  716.     }
  717.     else 
  718.     {
  719.         dwSliderPos = (DWORD)SendDlgItemMessage( hDlg, IDC_QUALITY_SLIDER, TBM_GETPOS, 0, 0 );
  720.         m_dvClientConfig.dwBufferQuality = dwSliderPos;
  721.     }
  722.  
  723.     // Figure out the aggressiveness params
  724.     if( IsDlgButtonChecked( hDlg, IDC_AGGRESSIVENESS_DEFAULT ) )
  725.     {
  726.         m_dvClientConfig.dwBufferAggressiveness = DVBUFFERAGGRESSIVENESS_DEFAULT;
  727.     }
  728.     else 
  729.     {
  730.         dwSliderPos = (DWORD)SendDlgItemMessage( hDlg, IDC_AGGRESSIVENESS_SLIDER, TBM_GETPOS, 0, 0 );
  731.         m_dvClientConfig.dwBufferAggressiveness = dwSliderPos;
  732.     }
  733.  
  734.     if( m_bHostPlayer )
  735.     {
  736.         // Figure out the compression codec
  737.         LONG lCurSelection;
  738.         LPGUID pGuidCT;
  739.  
  740.         lCurSelection = (LONG)SendDlgItemMessage( hDlg, IDC_COMPRESSION_COMBO, CB_GETCURSEL, 0, 0 );
  741.         if( lCurSelection != CB_ERR )
  742.         {
  743.             pGuidCT = (LPGUID) SendDlgItemMessage( hDlg, IDC_COMPRESSION_COMBO, 
  744.                                                    CB_GETITEMDATA, lCurSelection, 0 );
  745.             if( pGuidCT != NULL )
  746.                 m_guidDVSessionCT = (*pGuidCT);
  747.         }
  748.     }
  749.  
  750.     EndDialog( hDlg, IDOK );
  751. }
  752.