home *** CD-ROM | disk | FTP | other *** search
/ Programming a Multiplayer FPS in DirectX / Programming a Multiplayer FPS in DirectX (Companion CD).iso / Source / Chapter 6 / Engine / SoundSystem.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2004-10-01  |  9.0 KB  |  213 lines

  1. //-----------------------------------------------------------------------------
  2. // SoundSystem.h implementation.
  3. // Refer to the SoundSystem.h interface for more details.
  4. //
  5. // Programming a Multiplayer First Person Shooter in DirectX
  6. // Copyright (c) 2004 Vaughan Young
  7. //-----------------------------------------------------------------------------
  8. #include "Engine.h"
  9.  
  10. //-----------------------------------------------------------------------------
  11. // The sound system class constructor.
  12. //-----------------------------------------------------------------------------
  13. SoundSystem::SoundSystem( float scale )
  14. {
  15.     // Create the DirectMusic loader.
  16.     CoCreateInstance( CLSID_DirectMusicLoader, NULL, CLSCTX_INPROC, IID_IDirectMusicLoader8, (void**)&m_loader );
  17.  
  18.     // Create and initialise the DirectMusic performance.
  19.     CoCreateInstance( CLSID_DirectMusicPerformance, NULL, CLSCTX_INPROC, IID_IDirectMusicPerformance8, (void**)&m_performance );
  20.     m_performance->InitAudio( NULL, NULL, NULL, DMUS_APATH_SHARED_STEREOPLUSREVERB, 8, DMUS_AUDIOF_ALL, NULL );
  21.  
  22.     // Get the 3D listener by creating a 3D audio path then retrieving the
  23.     // listener from the audio path. The audio path can then be released.
  24.     IDirectMusicAudioPath8 *audioPath3D;
  25.     m_performance->CreateStandardAudioPath( DMUS_APATH_DYNAMIC_3D, 1, true, &audioPath3D );
  26.     audioPath3D->GetObjectInPath( 0, DMUS_PATH_PRIMARY_BUFFER, 0, GUID_All_Objects, 0, IID_IDirectSound3DListener, (void**)&m_listener );
  27.     SAFE_RELEASE( audioPath3D );
  28.  
  29.     // Set the scale (and the distance factor).
  30.     m_scale = scale;
  31.     m_listener->SetDistanceFactor( m_scale, DS3D_IMMEDIATE );
  32. }
  33.  
  34. //-----------------------------------------------------------------------------
  35. // The sound system class destructor.
  36. //-----------------------------------------------------------------------------
  37. SoundSystem::~SoundSystem()
  38. {
  39.     // Close down and release the DirectMusic performance.
  40.     m_performance->CloseDown();
  41.     SAFE_RELEASE( m_performance );
  42.  
  43.     // Release the DirectMusic loader.
  44.     SAFE_RELEASE( m_loader );
  45. }
  46.  
  47. //-----------------------------------------------------------------------------
  48. // Updates the sound system's 3D listener.
  49. //-----------------------------------------------------------------------------
  50. void SoundSystem::UpdateListener( D3DXVECTOR3 forward, D3DXVECTOR3 position, D3DXVECTOR3 velocity )
  51. {
  52.     // Set the listener's orientation.
  53.     m_listener->SetOrientation( forward.x, forward.y, forward.z, 0.0f, 1.0f, 0.0f, DS3D_DEFERRED );
  54.  
  55.     // Scale and set the listener's position.
  56.     position *= m_scale;
  57.     m_listener->SetPosition( position.x, position.y, position.z, DS3D_DEFERRED );
  58.  
  59.     // Scale and set the listener's velocity.
  60.     velocity *= m_scale;
  61.     m_listener->SetVelocity( velocity.x, velocity.y, velocity.z, DS3D_DEFERRED );
  62.  
  63.     // Commit the settings.
  64.     m_listener->CommitDeferredSettings();
  65. }
  66.  
  67. //-----------------------------------------------------------------------------
  68. // Allows the sound system to remove unused sound objects.
  69. //-----------------------------------------------------------------------------
  70. void SoundSystem::GarbageCollection()
  71. {
  72.     m_loader->CollectGarbage();
  73. }
  74.  
  75. //-----------------------------------------------------------------------------
  76. // Sets the master volume for all sounds played through this sound system.
  77. //-----------------------------------------------------------------------------
  78. void SoundSystem::SetVolume( long volume )
  79. {
  80.     m_performance->SetGlobalParam( GUID_PerfMasterVolume, &volume, sizeof( long ) );
  81. }
  82.  
  83. //-----------------------------------------------------------------------------
  84. // Returns a pointer to the sound system's loader object.
  85. //-----------------------------------------------------------------------------
  86. IDirectMusicLoader8 *SoundSystem::GetLoader()
  87. {
  88.     return m_loader;
  89. }
  90.  
  91. //-----------------------------------------------------------------------------
  92. // Returns the sound system's performance object.
  93. //-----------------------------------------------------------------------------
  94. IDirectMusicPerformance8 *SoundSystem::GetPerformance()
  95. {
  96.     return m_performance;
  97. }
  98.  
  99. //-----------------------------------------------------------------------------
  100. // The sound class constructor.
  101. //-----------------------------------------------------------------------------
  102. Sound::Sound( char *filename )
  103. {
  104.     // Convert the filename into a wide character string.
  105.     WCHAR *wideFilename = new WCHAR[strlen( filename ) + 1];
  106.     MultiByteToWideChar( CP_ACP, 0, filename, -1, wideFilename, strlen( filename ) + 1 );
  107.     wideFilename[strlen( filename )] = 0;
  108.  
  109.     // Load the sound file, then destroy the file name.
  110.     g_engine->GetSoundSystem()->GetLoader()->LoadObjectFromFile( CLSID_DirectMusicSegment, IID_IDirectMusicSegment8, wideFilename, (void**)&m_segment );
  111.     SAFE_DELETE( wideFilename );
  112.  
  113.     // Download the segment's data to the perfromance.
  114.     m_segment->Download( g_engine->GetSoundSystem()->GetPerformance() );
  115. }
  116.  
  117. //-----------------------------------------------------------------------------
  118. // The sound class destructor.
  119. //-----------------------------------------------------------------------------
  120. Sound::~Sound()
  121. {
  122.     // Unload the segment's data from the perfromance.
  123.     m_segment->Unload( g_engine->GetSoundSystem()->GetPerformance() );
  124.     
  125.     // Remove the segment from the DirectMusic loader, then release it.
  126.     g_engine->GetSoundSystem()->GetLoader()->ReleaseObjectByUnknown( m_segment );
  127.     SAFE_RELEASE( m_segment );
  128. }
  129.  
  130. //-----------------------------------------------------------------------------
  131. // Plays the sound on the standard audiopath with or without looping.
  132. // Warning: Sound segments can only maintain a single looping state. Therefore
  133. // changing the looping flag will effect all instances of this sound.
  134. //-----------------------------------------------------------------------------
  135. void Sound::Play( bool loop, unsigned long flags )
  136. {
  137.     if( loop == true )
  138.         m_segment->SetRepeats( DMUS_SEG_REPEAT_INFINITE );
  139.     else
  140.         m_segment->SetRepeats( 0 );
  141.  
  142.     g_engine->GetSoundSystem()->GetPerformance()->PlaySegment( m_segment, flags, 0, NULL );
  143. }
  144.  
  145. //-----------------------------------------------------------------------------
  146. // Returns the sound's segment.
  147. //-----------------------------------------------------------------------------
  148. IDirectMusicSegment8 *Sound::GetSegment()
  149. {
  150.     return m_segment;
  151. }
  152.  
  153. //-----------------------------------------------------------------------------
  154. // The audio path 3D class constructor.
  155. //-----------------------------------------------------------------------------
  156. AudioPath3D::AudioPath3D()
  157. {
  158.     // Create an audiopath so the 3D parameters can be set individually.
  159.     g_engine->GetSoundSystem()->GetPerformance()->CreateStandardAudioPath( DMUS_APATH_DYNAMIC_3D, 1, true, &m_audioPath );
  160.  
  161.     // Get the audiopath's sound buffer.
  162.     m_audioPath->GetObjectInPath( DMUS_PCHANNEL_ALL, DMUS_PATH_BUFFER, 0, GUID_NULL, 0, IID_IDirectSound3DBuffer, (void**)&m_soundBuffer );
  163. }
  164.  
  165. //-----------------------------------------------------------------------------
  166. // The audio path 3D class destructor.
  167. //-----------------------------------------------------------------------------
  168. AudioPath3D::~AudioPath3D()
  169. {
  170.     SAFE_RELEASE( m_soundBuffer );
  171.     SAFE_RELEASE( m_audioPath );
  172. }
  173.  
  174. //-----------------------------------------------------------------------------
  175. // Sets the position of the sound in 3D space.
  176. //-----------------------------------------------------------------------------
  177. void AudioPath3D::SetPosition( D3DXVECTOR3 position )
  178. {
  179.     position *= g_engine->GetScale();
  180.     m_soundBuffer->SetPosition( position.x, position.y, position.z, DS3D_IMMEDIATE );
  181. }
  182.  
  183. //-----------------------------------------------------------------------------
  184. // Sets the velocity of the sound in 3D space.
  185. //-----------------------------------------------------------------------------
  186. void AudioPath3D::SetVelocity( D3DXVECTOR3 velocity )
  187. {
  188.     velocity *= g_engine->GetScale();
  189.     m_soundBuffer->SetVelocity( velocity.x, velocity.y, velocity.z, DS3D_IMMEDIATE );
  190. }
  191.  
  192. //-----------------------------------------------------------------------------
  193. // Sets the mode that the audio path plays sounds in.
  194. //-----------------------------------------------------------------------------
  195. void AudioPath3D::SetMode( unsigned long mode )
  196. {
  197.     m_soundBuffer->SetMode( mode, DS3D_IMMEDIATE );
  198. }
  199.  
  200. //-----------------------------------------------------------------------------
  201. // Plays the given sound on the 3D audio path with or without looping.
  202. // Warning: Sound segments can only maintain a single looping state. Therefore
  203. // changing the looping flag will effect all instances of this sound.
  204. //-----------------------------------------------------------------------------
  205. void AudioPath3D::Play( IDirectMusicSegment8 *segment, bool loop, unsigned long flags )
  206. {
  207.     if( loop == true )
  208.         segment->SetRepeats( DMUS_SEG_REPEAT_INFINITE );
  209.     else
  210.         segment->SetRepeats( 0 );
  211.  
  212.     g_engine->GetSoundSystem()->GetPerformance()->PlaySegmentEx( segment, NULL, NULL, flags, 0, NULL, NULL, m_audioPath );
  213. }