//----------------------------------------------------------------------------- // Name: OnPlaySound() // Desc: User hit the "Play" button //----------------------------------------------------------------------------- HRESULT OnPlaySound( HWND hDlg ) { HRESULT hr; HWND hLoopButton = GetDlgItem( hDlg, IDC_LOOP_CHECK ); BOOL bLooped = ( SendMessage( hLoopButton, BM_GETSTATE, 0, 0 ) == BST_CHECKED ); if( g_bBufferPaused ) { // Play the buffer since it is currently paused DWORD dwFlags = bLooped ? DSBPLAY_LOOPING : 0L; if( FAILED( hr = g_pSound->Play( 0, dwFlags ) ) ) return DXTRACE_ERR( TEXT("Play"), hr ); // Update the UI controls to show the sound as playing g_bBufferPaused = FALSE; EnablePlayUI( hDlg, FALSE ); } else { if( g_pSound->IsSoundPlaying() ) { // To pause, just stop the buffer, but don't reset the position if( g_pSound ) g_pSound->Stop(); g_bBufferPaused = TRUE; SetDlgItemText( hDlg, IDC_PLAY, "Play" ); } else { // The buffer is not playing, so play it again DWORD dwFlags = bLooped ? DSBPLAY_LOOPING : 0L; if( FAILED( hr = g_pSound->Play( 0, dwFlags ) ) ) return DXTRACE_ERR( TEXT("Play"), hr ); // Update the UI controls to show the sound as playing g_bBufferPaused = FALSE; EnablePlayUI( hDlg, FALSE ); } } return S_OK; }
//----------------------------------------------------------------------------- // Name: OnTimer() // Desc: When we think the sound is playing this periodically checks to see if // the sound has stopped. If it has then updates the dialog. //----------------------------------------------------------------------------- VOID OnTimer( HWND hDlg ) { if( IsWindowEnabled( GetDlgItem( hDlg, IDC_STOP ) ) ) { // We think the sound is playing, so see if it has stopped yet. if( !g_pSound->IsSoundPlaying() ) { // Update the UI controls to show the sound as stopped EnablePlayUI( hDlg, TRUE ); } } }
//----------------------------------------------------------------------------- // Name: ValidateWaveFile() // Desc: Open the wave file with the helper // class CWaveFile to make sure it is valid //----------------------------------------------------------------------------- VOID ValidateWaveFile( HWND hDlg, TCHAR* strFileName ) { HRESULT hr; CWaveFile waveFile; // Verify the file is small HANDLE hFile = CreateFile( strFileName, 0, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL ); if( hFile != NULL ) { // If you try to open a 100MB wav file, you could run out of system memory with this // sample cause it puts all of it into a large buffer. If you need to do this, then // see the "StreamData" sample to stream the data from the file into a sound buffer. DWORD dwFileSizeHigh = 0; DWORD dwFileSize = GetFileSize( hFile, &dwFileSizeHigh ); CloseHandle( hFile ); if( dwFileSizeHigh != 0 || dwFileSize > 1000000 ) { waveFile.Close(); SetDlgItemText( hDlg, IDC_STATUS, TEXT("File too large. You should stream large files.") ); return; } } // Load the wave file if( FAILED( hr = waveFile.Open( strFileName, NULL, WAVEFILE_READ ) ) ) { DXTRACE_ERR_MSGBOX( TEXT("Open"), hr ); waveFile.Close(); SetDlgItemText( hDlg, IDC_STATUS, TEXT("Bad wave file.") ); } else // The load call succeeded { // Update the UI controls to show the sound as the file is loaded waveFile.Close(); EnablePlayUI( hDlg, TRUE ); SetDlgItemText( hDlg, IDC_FILENAME, strFileName ); SetDlgItemText( hDlg, IDC_STATUS, TEXT("File loaded.") ); strcpy( m_strWaveFileName, strFileName ); // Get the samples per sec from the wave file DWORD dwSamplesPerSec = waveFile.m_pwfx->nSamplesPerSec; // Set the slider positions SetSlidersPos( hDlg, dwSamplesPerSec, 0, 0 ); } }
//----------------------------------------------------------------------------- // Name: OnPlaySound() // Desc: User hit the "Play" button //----------------------------------------------------------------------------- HRESULT OnPlaySound( HWND hDlg ) { HRESULT hr; if( NULL == g_pSound ) return E_FAIL; // Play buffer always in looped mode just for this sample if( FAILED( hr = g_pSound->Play( 0, DSBPLAY_LOOPING ) ) ) return DXTRACE_ERR( TEXT("Play"), hr ); // Update the UI controls to show the sound as playing EnablePlayUI( hDlg, FALSE ); SetDlgItemText( hDlg, IDC_STATUS, TEXT("Sound playing.") ); return S_OK; }
//----------------------------------------------------------------------------- // Name: ValidateWaveFile() // Desc: Open the wave file with the helper // class CWaveFile to make sure it is valid //----------------------------------------------------------------------------- HRESULT ValidateWaveFile( HWND hDlg, TCHAR* strFileName ) { HRESULT hr; CWaveFile waveFile; if( -1 == GetFileAttributes(strFileName) ) return E_FAIL; // Load the wave file if( FAILED( hr = waveFile.Open( strFileName, NULL, WAVEFILE_READ ) ) ) { waveFile.Close(); SetDlgItemText( hDlg, IDC_STATUS, TEXT("Bad wave file.") ); return DXTRACE_ERR( TEXT("Open"), hr ); } else // The load call succeeded { WAVEFORMATEX* pwfx = waveFile.GetFormat(); if( pwfx->wFormatTag != WAVE_FORMAT_PCM ) { // Sound must be PCM when using DSBCAPS_CTRLFX SAFE_RELEASE( g_pIGargle ); SAFE_DELETE( g_pSound ); SetDlgItemText( hDlg, IDC_STATUS, TEXT("Wave file must be PCM for effects control.") ); SetDlgItemText( hDlg, IDC_FILENAME, TEXT("") ); return S_FALSE; } // Update the UI controls to show the sound as the file is loaded waveFile.Close(); EnablePlayUI( hDlg, TRUE ); SetDlgItemText( hDlg, IDC_FILENAME, strFileName ); SetDlgItemText( hDlg, IDC_STATUS, TEXT("File loaded.") ); strcpy( g_strWaveFileName, strFileName ); // Get the samples per sec from the wave file DWORD dwSamplesPerSec = waveFile.m_pwfx->nSamplesPerSec; return S_OK; } }
//----------------------------------------------------------------------------- // Name: MainDlgProc() // Desc: Handles dialog messages //----------------------------------------------------------------------------- INT_PTR CALLBACK MainDlgProc( HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam ) { HRESULT hr; switch( msg ) { case WM_INITDIALOG: OnInitDialog( hDlg ); break; case WM_COMMAND: switch( LOWORD(wParam) ) { case IDC_SOUNDFILE: OnOpenSoundFile( hDlg ); break; case IDCANCEL: EndDialog( hDlg, IDCANCEL ); break; case IDC_PLAY: // The 'play'/'pause' button was pressed if( FAILED( hr = OnPlaySound( hDlg ) ) ) { DXTRACE_ERR_MSGBOX( TEXT("OnPlaySound"), hr ); MessageBox( hDlg, "Error playing DirectSound buffer. " "Sample will now exit.", "DirectSound Sample", MB_OK | MB_ICONERROR ); EndDialog( hDlg, IDABORT ); } break; case IDC_STOP: if( g_pSound ) { g_pSound->Stop(); g_pSound->Reset(); } EnablePlayUI( hDlg, TRUE ); break; case IDHELP: DXUtil_LaunchReadme( hDlg ); break; default: return FALSE; // Didn't handle message } break; case WM_TIMER: OnTimer( hDlg ); break; case WM_DESTROY: // Cleanup everything KillTimer( hDlg, 1 ); SAFE_DELETE( g_pSound ); SAFE_DELETE( g_pSoundManager ); break; default: return FALSE; // Didn't handle message } return TRUE; // Handled message }
//----------------------------------------------------------------------------- // Name: OnOpenSoundFile() // Desc: Called when the user requests to open a sound file //----------------------------------------------------------------------------- VOID OnOpenSoundFile( HWND hDlg ) { HRESULT hr; static TCHAR strFileName[MAX_PATH] = TEXT(""); static TCHAR strPath[MAX_PATH] = TEXT(""); // Setup the OPENFILENAME structure OPENFILENAME ofn = { sizeof(OPENFILENAME), hDlg, NULL, TEXT("Wave Files\0*.wav\0All Files\0*.*\0\0"), NULL, 0, 1, strFileName, MAX_PATH, NULL, 0, strPath, TEXT("Open Sound File"), OFN_FILEMUSTEXIST|OFN_HIDEREADONLY, 0, 0, TEXT(".wav"), 0, NULL, NULL }; // Get the default media path (something like C:\WINDOWS\MEDIA) if( '\0' == strPath[0] ) { if( GetWindowsDirectory( strPath, MAX_PATH ) != 0 ) { if( strcmp( &strPath[strlen(strPath)], TEXT("\\") ) ) strcat( strPath, TEXT("\\") ); strcat( strPath, TEXT("MEDIA") ); } } if( g_pSound ) { g_pSound->Stop(); g_pSound->Reset(); } // Update the UI controls to show the sound as loading a file EnableWindow( GetDlgItem( hDlg, IDC_PLAY ), FALSE); EnableWindow( GetDlgItem( hDlg, IDC_STOP ), FALSE); SetDlgItemText( hDlg, IDC_FILENAME, TEXT("Loading file...") ); // Display the OpenFileName dialog. Then, try to load the specified file if( TRUE != GetOpenFileName( &ofn ) ) { SetDlgItemText( hDlg, IDC_FILENAME, TEXT("Load aborted.") ); return; } SetDlgItemText( hDlg, IDC_FILENAME, TEXT("") ); // Free any previous sound, and make a new one SAFE_DELETE( g_pSound ); // Verify the file is small HANDLE hFile = CreateFile( strFileName, 0, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL ); if( hFile != NULL ) { // If you try to open a 100MB wav file, you could run out of system memory with this // sample cause it puts all of it into a large buffer. If you need to do this, then // see the "StreamData" sample to stream the data from the file into a sound buffer. DWORD dwFileSizeHigh = 0; DWORD dwFileSize = GetFileSize( hFile, &dwFileSizeHigh ); CloseHandle( hFile ); if( dwFileSizeHigh != 0 || dwFileSize > 1000000 ) { SetDlgItemText( hDlg, IDC_FILENAME, TEXT("File too large. You should stream large files.") ); return; } } // Load the wave file into a DirectSound buffer if( FAILED( hr = g_pSoundManager->Create( &g_pSound, strFileName, 0, GUID_NULL ) ) ) { // Not a critical failure, so just update the status DXTRACE_ERR( TEXT("Create"), hr ); SetDlgItemText( hDlg, IDC_FILENAME, TEXT("Could not create sound buffer.") ); return; } // Update the UI controls to show the sound as the file is loaded SetDlgItemText( hDlg, IDC_FILENAME, strFileName ); EnablePlayUI( hDlg, TRUE ); // Remember the path for next time strcpy( strPath, strFileName ); char* strLastSlash = strrchr( strPath, '\\' ); if( strLastSlash ) strLastSlash[0] = '\0'; }
//----------------------------------------------------------------------------- // Name: OnPlaySound() // Desc: User hit the "Play" button //----------------------------------------------------------------------------- HRESULT OnPlaySound( HWND hDlg ) { HRESULT hr; DWORD dwCreationFlags; DWORD dwResults; LPDIRECTSOUNDBUFFER pDSB = NULL; LPDIRECTSOUNDBUFFER8 pDSB8 = NULL; BOOL bLooped = ( IsDlgButtonChecked( hDlg, IDC_LOOP_CHECK ) == BST_CHECKED ); // We would only use CTRLFX control on dsound buffer dwCreationFlags = DSBCAPS_CTRLFX; // Free any previous sound and FXs SAFE_RELEASE( g_pIGargle ); SAFE_DELETE( g_pSound ); // Since the user can change the focus before the sound is played, // we need to create the sound buffer every time the play button is pressed // Load the wave file into a DirectSound buffer if( FAILED( hr = g_pSoundManager->Create( &g_pSound, g_strWaveFileName, dwCreationFlags, GUID_NULL ) ) ) { // Not a critical failure, so just update the status DXTRACE_ERR_NOMSGBOX( TEXT("Create"), hr ); if( hr == DSERR_BUFFERTOOSMALL ) { // DSERR_BUFFERTOOSMALL will be returned if the buffer is // less than DSBSIZE_FX_MIN (100ms) and the buffer is created // with DSBCAPS_CTRLFX. SetDlgItemText( hDlg, IDC_STATUS, TEXT("Wave file is too short (less than 100ms) for effect processing.") ); } else { SetDlgItemText( hDlg, IDC_STATUS, TEXT("Could not create sound buffer.") ); } return S_FALSE; } // Query IDirectSoundBuffer8 interface pDSB = g_pSound->GetBuffer( 0 ); if( FAILED( hr = pDSB->QueryInterface( IID_IDirectSoundBuffer8, (LPVOID*) &pDSB8 ) ) ) return DXTRACE_ERR( TEXT("QueryInterface"), hr ); // Set gargle effect on the IDirectSoundBuffer8 DSEFFECTDESC dsed; ZeroMemory( &dsed, sizeof(DSEFFECTDESC) ); dsed.dwSize = sizeof(DSEFFECTDESC); dsed.dwFlags = 0; dsed.guidDSFXClass = GUID_DSFX_STANDARD_GARGLE; if( FAILED( hr = pDSB8->SetFX( 1, &dsed, &dwResults ) ) ) { // Not a critical failure, so just update the status DXTRACE_ERR( TEXT("SetFX"), hr ); SetDlgItemText( hDlg, IDC_STATUS, TEXT("Could not set gargle effect.") ); return S_FALSE; } // Get gargle effect friendly interface if( FAILED( hr = pDSB8->GetObjectInPath( GUID_DSFX_STANDARD_GARGLE, 0, IID_IDirectSoundFXGargle, (LPVOID*) &g_pIGargle ) ) ) return DXTRACE_ERR( TEXT("GetObjectInPath"), hr ); // Cleanup SAFE_RELEASE( pDSB8 ); // Set the buffer options to what the sliders are set to OnEffectChanged( hDlg ); // Play the sound DWORD dwLooped = bLooped ? DSBPLAY_LOOPING : 0L; if( FAILED( hr = g_pSound->Play( 0, dwLooped ) ) ) return DXTRACE_ERR( TEXT("Play"), hr ); // Update the UI controls to show the sound as playing EnablePlayUI( hDlg, FALSE ); SetDlgItemText( hDlg, IDC_STATUS, TEXT("Sound playing.") ); return S_OK; }
//----------------------------------------------------------------------------- // Name: MainDlgProc() // Desc: Handles dialog messages //----------------------------------------------------------------------------- INT_PTR CALLBACK MainDlgProc( HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam ) { HRESULT hr; switch( msg ) { case WM_INITDIALOG: OnInitDialog( hDlg ); break; case WM_COMMAND: switch( LOWORD(wParam) ) { case IDC_SOUNDFILE: OnOpenSoundFile( hDlg ); break; case IDCANCEL: EndDialog( hDlg, IDCANCEL ); break; case IDC_PLAY: if( FAILED( hr = OnPlaySound( hDlg ) ) ) { DXTRACE_ERR( TEXT("OnPlaySound"), hr ); MessageBox( hDlg, "Error playing DirectSound buffer." "Sample will now exit.", "DirectSound Sample", MB_OK | MB_ICONERROR ); EndDialog( hDlg, IDABORT ); } break; case IDC_STOP: if( g_pSound ) { g_pSound->Stop(); g_pSound->Reset(); } // Update the UI controls to show the sound as stopped EnablePlayUI( hDlg, TRUE ); SetDlgItemText( hDlg, IDC_STATUS, TEXT("Sound stopped.") ); break; case IDC_DEFER: g_bDeferSettings = !g_bDeferSettings; OnSliderChanged( hDlg ); break; case IDC_APPLY: // Call the IDirectSound3DListener::CommitDeferredSettings // method to execute all of the deferred commands at once. // This is many times more efficent than recomputing everything // for every call. if( g_pDSListener ) g_pDSListener->CommitDeferredSettings(); break; default: return FALSE; // Didn't handle message } break; case WM_TIMER: if( wParam == IDT_MOVEMENT_TIMER ) OnMovementTimer( hDlg ); break; case WM_NOTIFY: OnSliderChanged( hDlg ); break; case WM_DESTROY: // Cleanup everything KillTimer( hDlg, 1 ); SAFE_RELEASE( g_pDSListener ); SAFE_RELEASE( g_pDS3DBuffer ); SAFE_DELETE( g_pSound ); SAFE_DELETE( g_pSoundManager ); break; default: return FALSE; // Didn't handle message } return TRUE; // Handled message }
//----------------------------------------------------------------------------- // Name: OnOpenSoundFile() // Desc: Called when the user requests to open a sound file //----------------------------------------------------------------------------- VOID OnOpenSoundFile( HWND hDlg ) { GUID guid3DAlgorithm = GUID_NULL; int nResult; HRESULT hr; static TCHAR strFileName[MAX_PATH] = TEXT(""); static TCHAR strPath[MAX_PATH] = TEXT(""); // Setup the OPENFILENAME structure OPENFILENAME ofn = { sizeof(OPENFILENAME), hDlg, NULL, TEXT("Wave Files\0*.wav\0All Files\0*.*\0\0"), NULL, 0, 1, strFileName, MAX_PATH, NULL, 0, strPath, TEXT("Open Sound File"), OFN_FILEMUSTEXIST|OFN_HIDEREADONLY, 0, 0, TEXT(".wav"), 0, NULL, NULL }; // Get the default media path (something like C:\WINDOWS\MEDIA) if( '\0' == strPath[0] ) { GetWindowsDirectory( strPath, MAX_PATH ); if( strcmp( &strPath[strlen(strPath)], TEXT("\\") ) ) strcat( strPath, TEXT("\\") ); strcat( strPath, TEXT("MEDIA") ); } if( g_pSound ) { g_pSound->Stop(); g_pSound->Reset(); } // Update the UI controls to show the sound as loading a file EnableWindow( GetDlgItem( hDlg, IDC_PLAY ), FALSE); EnableWindow( GetDlgItem( hDlg, IDC_STOP ), FALSE); SetDlgItemText( hDlg, IDC_STATUS, TEXT("Loading file...") ); // Stop the timer while dialogs are displayed g_bAllowMovementTimer = FALSE; // Display the OpenFileName dialog. Then, try to load the specified file if( TRUE != GetOpenFileName( &ofn ) ) { SetDlgItemText( hDlg, IDC_STATUS, TEXT("Load aborted.") ); g_bAllowMovementTimer = TRUE; return; } SetDlgItemText( hDlg, IDC_FILENAME, TEXT("") ); // Free any previous sound, and make a new one SAFE_DELETE( g_pSound ); CWaveFile waveFile; waveFile.Open( strFileName, NULL, WAVEFILE_READ ); WAVEFORMATEX* pwfx = waveFile.GetFormat(); if( pwfx == NULL ) { SetDlgItemText( hDlg, IDC_STATUS, TEXT("Invalid wave file format.") ); return; } if( pwfx->nChannels > 1 ) { // Too many channels in wave. Sound must be mono when using DSBCAPS_CTRL3D SetDlgItemText( hDlg, IDC_STATUS, TEXT("Wave file must be mono for 3D control.") ); SetDlgItemText( hDlg, IDC_FILENAME, TEXT("") ); return; } if( pwfx->wFormatTag != WAVE_FORMAT_PCM ) { // Sound must be PCM when using DSBCAPS_CTRL3D SetDlgItemText( hDlg, IDC_STATUS, TEXT("Wave file must be PCM for 3D control.") ); SetDlgItemText( hDlg, IDC_FILENAME, TEXT("") ); return; } // Get the software DirectSound3D emulation algorithm to use // Ask the user for this sample, so display the algorithm dialog box. nResult = (int)DialogBox( NULL, MAKEINTRESOURCE(IDD_3D_ALGORITHM), NULL, AlgorithmDlgProc ); switch( nResult ) { case -1: // User canceled dialog box SetDlgItemText( hDlg, IDC_STATUS, TEXT("Load aborted.") ); SetDlgItemText( hDlg, IDC_FILENAME, TEXT("") ); return; case 0: // User selected DS3DALG_NO_VIRTUALIZATION guid3DAlgorithm = DS3DALG_NO_VIRTUALIZATION; break; case 1: // User selected DS3DALG_HRTF_FULL guid3DAlgorithm = DS3DALG_HRTF_FULL; break; case 2: // User selected DS3DALG_HRTF_LIGHT guid3DAlgorithm = DS3DALG_HRTF_LIGHT; break; } // Load the wave file into a DirectSound buffer hr = g_pSoundManager->Create( &g_pSound, strFileName, DSBCAPS_CTRL3D, guid3DAlgorithm ); if( FAILED( hr ) || hr == DS_NO_VIRTUALIZATION ) { DXTRACE_ERR_NOMSGBOX( TEXT("Create"), hr ); if( DS_NO_VIRTUALIZATION == hr ) { MessageBox( hDlg, "The 3D virtualization algorithm requested is not supported under this " "operating system. It is available only on Windows 2000, Windows ME, and Windows 98 with WDM " "drivers and beyond. Creating buffer with no virtualization.", "DirectSound Sample", MB_OK ); } // Unknown error, but not a critical failure, so just update the status SetDlgItemText( hDlg, IDC_FILENAME, TEXT("Could not create sound buffer.") ); return; } // Get the 3D buffer from the secondary buffer if( FAILED( hr = g_pSound->Get3DBufferInterface( 0, &g_pDS3DBuffer ) ) ) { DXTRACE_ERR( TEXT("Get3DBufferInterface"), hr ); SetDlgItemText( hDlg, IDC_STATUS, TEXT("Could not get 3D buffer.") ); SetDlgItemText( hDlg, IDC_FILENAME, TEXT("") ); return; } // Get the 3D buffer parameters g_dsBufferParams.dwSize = sizeof(DS3DBUFFER); g_pDS3DBuffer->GetAllParameters( &g_dsBufferParams ); // Set new 3D buffer parameters g_dsBufferParams.dwMode = DS3DMODE_HEADRELATIVE; g_pDS3DBuffer->SetAllParameters( &g_dsBufferParams, DS3D_IMMEDIATE ); DSBCAPS dsbcaps; ZeroMemory( &dsbcaps, sizeof(DSBCAPS) ); dsbcaps.dwSize = sizeof(DSBCAPS); LPDIRECTSOUNDBUFFER pDSB = g_pSound->GetBuffer( 0 ); pDSB->GetCaps( &dsbcaps ); if( ( dsbcaps.dwFlags & DSBCAPS_LOCHARDWARE ) != 0 ) SetDlgItemText( hDlg, IDC_STATUS, TEXT("File loaded using hardware mixing.") ); else SetDlgItemText( hDlg, IDC_STATUS, TEXT("File loaded using software mixing.") ); // Update the UI controls to show the sound as the file is loaded SetDlgItemText( hDlg, IDC_FILENAME, strFileName ); EnablePlayUI( hDlg, TRUE ); g_bAllowMovementTimer = TRUE; // Remember the path for next time strcpy( strPath, strFileName ); char* strLastSlash = strrchr( strPath, '\\' ); strLastSlash[0] = '\0'; // Set the slider positions SetSlidersPos( hDlg, 0.0f, 0.0f, ORBIT_MAX_RADIUS, ORBIT_MAX_RADIUS*2.0f ); OnSliderChanged( hDlg ); }
//----------------------------------------------------------------------------- // Name: OnPlaySound() // Desc: User hit the "Play" button //----------------------------------------------------------------------------- HRESULT OnPlaySound( HWND hDlg ) { HRESULT hr; DWORD dwCreationFlags; BOOL bLooped = ( IsDlgButtonChecked( hDlg, IDC_LOOP_CHECK ) == BST_CHECKED ); BOOL bFocusSticky = ( IsDlgButtonChecked( hDlg, IDC_FOCUS_STICKY ) == BST_CHECKED ); BOOL bFocusGlobal = ( IsDlgButtonChecked( hDlg, IDC_FOCUS_GLOBAL ) == BST_CHECKED ); BOOL bMixHardware = ( IsDlgButtonChecked( hDlg, IDC_MIX_HARDWARE ) == BST_CHECKED ); BOOL bMixSoftware = ( IsDlgButtonChecked( hDlg, IDC_MIX_SOFTWARE ) == BST_CHECKED ); // Detrimine the creation flags to use based on the radio buttons dwCreationFlags = 0; if( bFocusGlobal ) dwCreationFlags |= DSBCAPS_GLOBALFOCUS; if( bFocusSticky ) dwCreationFlags |= DSBCAPS_STICKYFOCUS; if( bMixHardware ) dwCreationFlags |= DSBCAPS_LOCHARDWARE; if( bMixSoftware ) dwCreationFlags |= DSBCAPS_LOCSOFTWARE; // Add extra flags needed for the UI dwCreationFlags |= DSBCAPS_CTRLPAN | DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLFREQUENCY; // Free any previous sound SAFE_DELETE( g_pSound ); // Since the user can change the focus before the sound is played, // we need to create the sound buffer every time the play button is pressed // Load the wave file into a DirectSound buffer if( FAILED( hr = g_pSoundManager->Create( &g_pSound, m_strWaveFileName, dwCreationFlags, GUID_NULL ) ) ) { // Not a critical failure, so just update the status DXTRACE_ERR( TEXT("Create"), hr ); SetDlgItemText( hDlg, IDC_STATUS, TEXT("Could not create sound buffer.") ); return S_FALSE; } // Set the buffer options to what the sliders are set to OnSliderChanged( hDlg ); // Only if the sound buffer was created perfectly should we update the UI // and play the sound // Get the position of the sliders HWND hFreqSlider = GetDlgItem( hDlg, IDC_FREQUENCY_SLIDER ); HWND hPanSlider = GetDlgItem( hDlg, IDC_PAN_SLIDER ); HWND hVolumeSlider = GetDlgItem( hDlg, IDC_VOLUME_SLIDER ); LONG lFrequency = (LONG)SendMessage( hFreqSlider, TBM_GETPOS, 0, 0 ) * 1L; LONG lPan = (LONG)SendMessage( hPanSlider, TBM_GETPOS, 0, 0 ) * 500L; LONG lVolume = (LONG)SendMessage( hVolumeSlider, TBM_GETPOS, 0, 0 ) * 100L; // Play the sound DWORD dwLooped = bLooped ? DSBPLAY_LOOPING : 0L; if( FAILED( hr = g_pSound->Play( 0, dwLooped, lVolume, lFrequency, lPan ) ) ) return DXTRACE_ERR( TEXT("Play"), hr ); // Update the UI controls to show the sound as playing EnablePlayUI( hDlg, FALSE ); SetDlgItemText( hDlg, IDC_STATUS, TEXT("Sound playing.") ); return S_OK; }