home *** CD-ROM | disk | FTP | other *** search
/ Windows Game Programming for Dummies (2nd Edition) / WinGamProgFD.iso / pc / DirectX SDK / DXSDK / samples / Multimedia / DirectMusic / AudioPath / audiopath.cpp next >
Encoding:
C/C++ Source or Header  |  2001-10-31  |  11.3 KB  |  318 lines

  1. //-----------------------------------------------------------------------------
  2. // File: Audiopath.cpp
  3. //
  4. // Desc: Uses a 3D Audiopath, and shows off various methods of PlaySegmentEx
  5. //
  6. // Copyright (c) 2000-2001 Microsoft Corporation. All rights reserved.
  7. //-----------------------------------------------------------------------------
  8. #define STRICT
  9. #include <windows.h>
  10. #include <basetsd.h>
  11. #include <commdlg.h>
  12. #include <commctrl.h>
  13. #include <dmusicc.h>
  14. #include <dmusici.h>
  15. #include <cguid.h>
  16. #include <dxerr8.h>
  17. #include <tchar.h>
  18. #include "resource.h"
  19. #include "DMUtil.h"
  20. #include "DXUtil.h"
  21.  
  22.  
  23.  
  24.  
  25. //-----------------------------------------------------------------------------
  26. // Function-prototypes
  27. //-----------------------------------------------------------------------------
  28. INT_PTR CALLBACK MainDlgProc( HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam );
  29. HRESULT OnInitDialog( HWND hDlg );
  30. HRESULT PlaySegment( DWORD dwIndex );
  31. HRESULT SetPosition( float fXPos, float fYPos, float fZPos );
  32.  
  33.  
  34.  
  35.  
  36. //-----------------------------------------------------------------------------
  37. // Defines, constants, and global variables
  38. //-----------------------------------------------------------------------------
  39. CMusicManager*          g_pMusicManager          = NULL;
  40. CMusicSegment*          g_pMusicSegments[4]      = { NULL,NULL,NULL,NULL };
  41. IDirectMusicAudioPath*  g_p3DAudiopath           = NULL;
  42. HINSTANCE               g_hInst                  = NULL;
  43.  
  44.  
  45.  
  46.  
  47. //-----------------------------------------------------------------------------
  48. // Name: WinMain()
  49. // Desc: Entry point for the application.  Since we use a simple dialog for 
  50. //       user interaction we don't need to pump messages.
  51. //-----------------------------------------------------------------------------
  52. INT APIENTRY WinMain( HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR pCmdLine, 
  53.                       INT nCmdShow )
  54. {
  55.     g_hInst = hInst;
  56.  
  57.     InitCommonControls();
  58.  
  59.     // Display the main dialog box.
  60.     DialogBox( hInst, MAKEINTRESOURCE(IDD_MAIN), NULL, MainDlgProc );
  61.    
  62.     return TRUE;
  63. }
  64.  
  65.  
  66.  
  67.  
  68. //-----------------------------------------------------------------------------
  69. // Name: MainDlgProc()
  70. // Desc: Handles dialog messages
  71. //-----------------------------------------------------------------------------
  72. INT_PTR CALLBACK MainDlgProc( HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam )
  73. {
  74.     HRESULT hr;
  75.  
  76.     switch( msg ) 
  77.     {
  78.         case WM_INITDIALOG:
  79.             if( FAILED( hr = OnInitDialog( hDlg ) ) )
  80.             {
  81.                 DXTRACE_ERR( TEXT("OnInitDialog"), hr );
  82.                 MessageBox( hDlg, "Error initializing DirectMusic.  Sample will now exit.", 
  83.                                   "DirectMusic Sample", MB_OK | MB_ICONERROR );
  84.                 EndDialog( hDlg, 0 );
  85.                 return TRUE;
  86.             }
  87.             break;
  88.  
  89.         case WM_COMMAND:
  90.             switch( LOWORD(wParam) )
  91.             {
  92.                 case IDCANCEL:
  93.                     EndDialog( hDlg, 0 );
  94.                     break;
  95.  
  96.                 case IDC_PLAY1:
  97.                 case IDC_PLAY2:
  98.                 case IDC_PLAY3:
  99.                 case IDC_PLAY4:
  100.                 {
  101.                     DWORD dwIndex = LOWORD(wParam) - IDC_PLAY1;
  102.                     if( FAILED( hr = PlaySegment( dwIndex ) ) )
  103.                     {
  104.                         DXTRACE_ERR( TEXT("PlaySegment"), hr );
  105.                         MessageBox( hDlg, "Error playing DirectMusic segment.  Sample will now exit.", 
  106.                                           "DirectMusic Sample", MB_OK | MB_ICONERROR );
  107.                         EndDialog( hDlg, 0 );
  108.                         return TRUE;
  109.                     }                   
  110.                     break;
  111.                 }
  112.  
  113.                 default:
  114.                     return FALSE; // Didn't handle message
  115.             }
  116.             break;
  117.  
  118.         case WM_HSCROLL:
  119.         {
  120.             // Set the 3D position
  121.             int nXPos = (int)SendDlgItemMessage( hDlg, IDC_XPOS, TBM_GETPOS, 0, 0 );
  122.             int nYPos = (int)SendDlgItemMessage( hDlg, IDC_YPOS, TBM_GETPOS, 0, 0 );
  123.             int nZPos = (int)SendDlgItemMessage( hDlg, IDC_ZPOS, TBM_GETPOS, 0, 0 );
  124.             SetDlgItemInt( hDlg, IDC_XDISPLAY, nXPos, TRUE );
  125.             SetDlgItemInt( hDlg, IDC_YDISPLAY, nYPos, TRUE );
  126.             SetDlgItemInt( hDlg, IDC_ZDISPLAY, nZPos, TRUE );
  127.             SetPosition( (float) nXPos, (float) nYPos, (float) nZPos );
  128.             break;
  129.         }
  130.  
  131.         case WM_DESTROY:
  132.         {
  133.             // Cleanup everything
  134.             SAFE_RELEASE( g_p3DAudiopath );
  135.  
  136.             for( int i=0; i<4; i++ )
  137.                 SAFE_DELETE( g_pMusicSegments[i] );
  138.  
  139.             SAFE_DELETE( g_pMusicManager );
  140.             break; 
  141.         }
  142.  
  143.         default:
  144.             return FALSE; // Didn't handle message
  145.     }
  146.  
  147.     return TRUE; // Handled message
  148. }
  149.  
  150.  
  151.  
  152.  
  153. //-----------------------------------------------------------------------------
  154. // Name: OnInitDialog()
  155. // Desc: Initializes the dialogs (sets up UI controls, etc.)
  156. //-----------------------------------------------------------------------------
  157. HRESULT OnInitDialog( HWND hDlg )
  158. {
  159.     HRESULT hr; 
  160.   
  161.     // Load the icon
  162.     HICON hIcon = LoadIcon( g_hInst, MAKEINTRESOURCE( IDR_MAINFRAME ) );
  163.  
  164.     // Set the icon for this dialog.
  165.     SendMessage( hDlg, WM_SETICON, ICON_BIG,   (LPARAM) hIcon );  // Set big icon
  166.     SendMessage( hDlg, WM_SETICON, ICON_SMALL, (LPARAM) hIcon );  // Set small icon
  167.  
  168.     g_pMusicManager = new CMusicManager();
  169.  
  170.     if( FAILED( hr = g_pMusicManager->Initialize( hDlg ) ) )
  171.         return DXTRACE_ERR( TEXT("Initialize"), hr );
  172.  
  173.     // Create a 3D Audiopath. This creates a synth port that feeds a 3d buffer.
  174.     // We can then play all segments into this buffer and directly control its
  175.     // 3D parameters.
  176.     IDirectMusicPerformance8* pPerformance = g_pMusicManager->GetPerformance();
  177.     if( FAILED( hr = pPerformance->CreateStandardAudioPath( DMUS_APATH_DYNAMIC_3D, 128, 
  178.                                                             TRUE, &g_p3DAudiopath ) ) )
  179.         return DXTRACE_ERR( TEXT("CreateStandardAudioPath"), hr );
  180.  
  181.     // Set the default media path (something like C:\MSSDK\SAMPLES\MULTIMEDIA\MEDIA)
  182.     // to be used as the search directory for finding DirectMusic content.
  183.     if( FAILED( hr = g_pMusicManager->SetSearchDirectory( DXUtil_GetDXSDKMediaPath() ) ) )
  184.         return DXTRACE_ERR( TEXT("SetSearchDirectory"), hr );
  185.  
  186.     TCHAR strFileNames[4][MAX_PATH] = { TEXT("Audiopath1.sgt"),    // Lullaby theme
  187.                                         TEXT("Audiopath2.sgt"),    // Snoring
  188.                                         TEXT("Audiopath3.wav"),    // Muttering in sleep
  189.                                         TEXT("Audiopath4.sgt")  // Rude awakening
  190.                                       };
  191.  
  192.     // Create the segments from a file
  193.     for (DWORD dwIndex = 0;dwIndex < 4; dwIndex++)
  194.     {
  195.         if( FAILED( hr = g_pMusicManager->CreateSegmentFromFile( &g_pMusicSegments[dwIndex], 
  196.                                                                 strFileNames[dwIndex] ) ) )
  197.             return DXTRACE_ERR( TEXT("CreateSegmentFromFile"), hr );
  198.     }
  199.  
  200.  
  201.     // Get the listener from the in the Audiopath.
  202.     IDirectSound3DListener* pDSListener = NULL;
  203.     if( FAILED( hr = g_p3DAudiopath->GetObjectInPath( 0, DMUS_PATH_PRIMARY_BUFFER, 0,
  204.                                                       GUID_NULL, 0, IID_IDirectSound3DListener, 
  205.                                                       (LPVOID*) &pDSListener ) ) )
  206.         return DXTRACE_ERR( TEXT("GetObjectInPath"), hr );
  207.  
  208.     // Set a new rolloff factor (1.0f is default)
  209.     if( FAILED( hr = pDSListener->SetRolloffFactor( 0.25f, DS3D_IMMEDIATE ) ) )
  210.         return DXTRACE_ERR( TEXT("SetRolloffFactor"), hr );       
  211.  
  212.     // Release the listener since we are done with it.
  213.     SAFE_RELEASE( pDSListener );
  214.  
  215.     // Setup the sliders
  216.     HWND hSlider;
  217.     hSlider = GetDlgItem( hDlg, IDC_XPOS );
  218.     SendMessage( hSlider, TBM_SETRANGEMAX, TRUE,   20L );
  219.     SendMessage( hSlider, TBM_SETRANGEMIN, TRUE,  -20L );
  220.     SendMessage( hSlider, TBM_SETPOS,      TRUE,    0L );
  221.  
  222.     hSlider = GetDlgItem( hDlg, IDC_YPOS );
  223.     SendMessage( hSlider, TBM_SETRANGEMAX, TRUE,   20L );
  224.     SendMessage( hSlider, TBM_SETRANGEMIN, TRUE,  -20L );
  225.     SendMessage( hSlider, TBM_SETPOS,      TRUE,    0L );
  226.  
  227.     hSlider = GetDlgItem( hDlg, IDC_ZPOS );
  228.     SendMessage( hSlider, TBM_SETRANGEMAX, TRUE,   20L );
  229.     SendMessage( hSlider, TBM_SETRANGEMIN, TRUE,  -20L );
  230.     SendMessage( hSlider, TBM_SETPOS,      TRUE,    0L );
  231.  
  232.     SetDlgItemInt( hDlg, IDC_XDISPLAY, 0, TRUE );
  233.     SetDlgItemInt( hDlg, IDC_YDISPLAY, 0, TRUE );
  234.     SetDlgItemInt( hDlg, IDC_ZDISPLAY, 0, TRUE );
  235.     SetPosition( 0, 0, 0 );
  236.  
  237.     return S_OK;
  238. }
  239.  
  240.  
  241.  
  242.  
  243. //-----------------------------------------------------------------------------
  244. // Name: PlaySegment()
  245. // Desc: 
  246. //-----------------------------------------------------------------------------
  247. HRESULT PlaySegment( DWORD dwIndex )
  248. {
  249.     HRESULT hr = S_OK; 
  250.  
  251.     if( g_pMusicSegments[dwIndex] )
  252.     {
  253.         switch( dwIndex )
  254.         {
  255.         case 0:
  256.             // Lullaby theme. This should play as a primary segment.
  257.             hr = g_pMusicSegments[dwIndex]->Play( DMUS_SEGF_DEFAULT, g_p3DAudiopath );
  258.             break;
  259.  
  260.         case 1:
  261.         case 2:
  262.             // Sound effects. These play as secondary segments so 
  263.             // they can be triggered multiple times and will layer on top.
  264.             hr = g_pMusicSegments[dwIndex]->Play( DMUS_SEGF_DEFAULT | DMUS_SEGF_SECONDARY, 
  265.                                                   g_p3DAudiopath );
  266.             break;
  267.  
  268.         case 3:
  269.             // Rude awakening. Notice that this also passes the Audiopath 
  270.             // in pFrom, indicating that all segments currently playing on 
  271.             // the Audiopath should be stopped at the exact time
  272.             // this starts. 
  273.             IDirectMusicSegment8* pSegment = g_pMusicSegments[dwIndex]->GetSegment();
  274.             IDirectMusicPerformance8* pPerformance = g_pMusicManager->GetPerformance();
  275.  
  276.             hr = pPerformance->PlaySegmentEx( pSegment, 0, NULL, 0, 0, 0, 
  277.                                               g_p3DAudiopath, g_p3DAudiopath );
  278.         }
  279.     }
  280.  
  281.     if( FAILED(hr) )
  282.         return DXTRACE_ERR( TEXT("PlaySegmentEx"), hr );
  283.  
  284.     return S_OK;
  285. }
  286.  
  287.  
  288.  
  289.  
  290. //-----------------------------------------------------------------------------
  291. // Name: SetPosition()
  292. // Desc: 
  293. //-----------------------------------------------------------------------------
  294. HRESULT SetPosition( float fXPos, float fYPos, float fZPos )
  295. {
  296.     HRESULT hr;
  297.  
  298.     if( NULL == g_p3DAudiopath )
  299.         return E_INVALIDARG;
  300.  
  301.     // First, get the 3D interface from the buffer by using GetObjectInPath.
  302.     IDirectSound3DBuffer *pBuffer;
  303.     if( FAILED( hr = g_p3DAudiopath->GetObjectInPath( DMUS_PCHANNEL_ALL, DMUS_PATH_BUFFER, 0, 
  304.                                                       GUID_NULL, 0, IID_IDirectSound3DBuffer, 
  305.                                                       (void **)&pBuffer ) ) )
  306.         return DXTRACE_ERR( TEXT("GetObjectInPath"), hr );
  307.  
  308.     // Then, set the coordinates and release.
  309.     if( FAILED( hr = pBuffer->SetPosition( fXPos, fYPos, fZPos, DS3D_IMMEDIATE ) ) )
  310.         return DXTRACE_ERR( TEXT("SetPosition"), hr );
  311.  
  312.     SAFE_RELEASE( pBuffer );
  313.  
  314.     return S_OK;
  315. }
  316.  
  317.  
  318.