Audio.cpp
上传用户:hkb425
上传日期:2007-06-16
资源大小:34191k
文件大小:12k
源码类别:

游戏引擎

开发平台:

Visual C++

  1. // Audio.cpp: implementation of the CAudio class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #include "stdafx.h"
  5. #include "Audio.h"
  6. //////////////////////////////////////////////////////////////////////
  7. // Construction/Destruction
  8. //////////////////////////////////////////////////////////////////////
  9. void CSound::
  10. Set3DPos(float x, float y, float z)
  11. { ds3DBuffer->SetPosition(x, y, -z, DS3D_IMMEDIATE); }
  12. //------------------------------------------------------------------//
  13. //- void CSound::Set3DDistances(float, float) -----------------------//
  14. //------------------------------------------------------------------//
  15. //- Sets the max, and minimum distance for a CSound to be heard.    -//
  16. //------------------------------------------------------------------//
  17. void CSound::
  18. Set3DDistances(float minDistance, float maxDistance)
  19. {
  20. DS3DBUFFER dsBufferParams;
  21. dsBufferParams.flMinDistance= minDistance; //Sets the minimum distance
  22. dsBufferParams.flMaxDistance= maxDistance; //Sets the maximum distance
  23. //Now, set the parameters for our CSound's 3D buffer
  24. if(ds3DBuffer)
  25. ds3DBuffer->SetAllParameters(&dsBufferParams, DS3D_IMMEDIATE);
  26. }
  27. //------------------------------------------------------------------//
  28. //- void CSound::Shutdown(void) -------------------------------------//
  29. //------------------------------------------------------------------//
  30. //- Shutdown the CSound, I originally had this in the destructor,   -//
  31. //- but it was acting screwy... so I now it has it's own function. -//
  32. //------------------------------------------------------------------//
  33. void CSound::
  34. Shutdown(void)
  35. {
  36. if(dmSegment!=NULL)
  37. {
  38. dmSegment->Release();
  39. dmSegment= NULL;
  40. }
  41. if(ds3DBuffer!=NULL)
  42. {
  43. ds3DBuffer->Release(); 
  44. ds3DBuffer= NULL;
  45. }
  46. }
  47. //------------------------------------------------------------------//
  48. //- bool CAudio::Init(void) ----------------------------------//
  49. //------------------------------------------------------------------//
  50. //- Initiates DirectAudio.  This function must be called by the    -//
  51. //- programmer, though the shutdown function is automatically    -//
  52. //- called by the destructor (as, not shutting down DAudio    -//
  53. //- correctly can have some bad consequences).    -//
  54. //------------------------------------------------------------------//
  55. bool CAudio::
  56. Init(HWND hwnd,unsigned int MaxNumber)
  57. {
  58. HRESULT hr;
  59. WCHAR wcharStr[MAX_PATH];
  60. char pathStr[MAX_PATH];
  61. CoInitialize(NULL);
  62. //Create the loader object, load it... and load it good.
  63. hr= CoCreateInstance(CLSID_DirectMusicLoader, NULL, CLSCTX_INPROC,
  64. IID_IDirectMusicLoader8, (void**)&dmLoader);
  65. if(FAILED(hr))
  66. {
  67. MessageBox(hwnd, "Unable to create main DirectAudio file loader", "ERROR", MB_OK);
  68. return false;
  69. }
  70. //Create the performance object for that.... performance stuff. 
  71. hr= CoCreateInstance(CLSID_DirectMusicPerformance, NULL, CLSCTX_INPROC,
  72.  IID_IDirectMusicPerformance8, (void**)&dmPerformance);
  73. if(FAILED(hr))
  74. {
  75. MessageBox(hwnd, "Unable to create main DirectAudio performance object", "ERROR", MB_OK);
  76. Shutdown();
  77. return false;
  78. }
  79. //Initialize the performance with the standard audio path information
  80. dmPerformance->InitAudio(NULL, NULL, hwnd, DMUS_APATH_DYNAMIC_3D , 64,
  81.  DMUS_AUDIOF_ALL, NULL);
  82.      //Create a simple 3D audiopath
  83.  hr= dmPerformance->CreateStandardAudioPath(DMUS_APATH_DYNAMIC_3D,
  84. 64, TRUE, &dm3DAudioPath);
  85.      if(FAILED(hr))
  86. {
  87. MessageBox(hwnd, "Unable to create the DirectAudio audio path", "ERROR", MB_OK);
  88. Shutdown();
  89. return false;
  90. }
  91.      //Retrieve the listener information from our audiopath
  92.  hr= dm3DAudioPath->GetObjectInPath(0, DMUS_PATH_PRIMARY_BUFFER, 0, GUID_NULL, 0, 
  93. IID_IDirectSound3DListener8,
  94. (void**)&ds3DListener);
  95.      if(FAILED(hr))
  96. {
  97. MessageBox(hwnd, "Unable to recieve listener from audio path", "ERROR", MB_OK);
  98. Shutdown();
  99. return false;
  100. }
  101. //Get the listener information
  102. dsListenerParams.dwSize= sizeof(DS3DLISTENER);
  103. ds3DListener->GetAllParameters(&dsListenerParams);
  104. //Set our default position of listener (since the listener shouldn't be moving all too much
  105. dsListenerParams.vPosition.x= 0.0f;
  106. dsListenerParams.vPosition.y= 0.0f;
  107. dsListenerParams.vPosition.z= 0.0f;
  108. ds3DListener->SetAllParameters(&dsListenerParams, DS3D_IMMEDIATE);
  109. //Retrieve the current directory
  110. GetCurrentDirectory(MAX_PATH, pathStr);
  111. //Convert the file name to a unicode string... as thats what COM needs
  112. MultiByteToWideChar(CP_ACP, 0, pathStr, -1, wcharStr, MAX_PATH);
  113. //Set the search directory
  114. dmLoader->SetSearchDirectory(GUID_DirectMusicAllTypes, wcharStr, FALSE);
  115. m_MaxNum=MaxNumber;
  116. pSound=new CSound[m_MaxNum];
  117. return true;
  118. }
  119. //------------------------------------------------------------------//
  120. //- void CAudio::DAudioShutdown(void) ------------------------//
  121. //------------------------------------------------------------------//
  122. //- Shuts down DirectAudio.  This function is called automatically -//
  123. //- by the CAudio destructor, hence the reason why this    -//
  124. //- function is private.    -//
  125. //------------------------------------------------------------------//
  126. void CAudio::Shutdown(void)
  127. {
  128.     for(unsigned int i=0;i < m_MaxNum;i++)
  129. {
  130. pSound[i].Shutdown();
  131. }
  132.     delete [] pSound;
  133. //Shut down the direct CSound listener(player) information
  134. if(ds3DListener!=NULL)
  135. ds3DListener->Release();
  136. //Shut down the direct music performance information
  137. if(dmPerformance!=NULL)
  138. {
  139. dmPerformance->Stop(NULL, NULL, 0, 0);
  140. dmPerformance->CloseDown();
  141. dmPerformance->Release();
  142. }
  143. //Shut down the direct music audiopath
  144. if(dm3DAudioPath!=NULL)
  145. dm3DAudioPath->Release();
  146. //Shut down the direct music loader
  147.    if(dmLoader!=NULL)
  148.      dmLoader->Release();
  149. //Uninitialize COM (*MUST* be done, or you're asking for trouble)
  150. CoUninitialize();
  151. }
  152. //------------------------------------------------------------------//
  153. //- bool CAudio::Create(CSound*, char*, bool) -----------------//
  154. //------------------------------------------------------------------//
  155. //- Use the audio manager to create an individual CSound effect from-//
  156. //- a file.    -//
  157. //------------------------------------------------------------------//
  158. bool CAudio::
  159. Create(unsigned int NumOfSound, char* filename, bool is3DSound)
  160. {
  161. if(NumOfSound>(m_MaxNum-1))return false;
  162. DS3DBUFFER dsBufferParams; 
  163. HRESULT hr;
  164. WCHAR wcharStr[MAX_PATH];
  165. //Convert the file name to the string that DirectAudio needs
  166. MultiByteToWideChar(CP_ACP, 0, filename, -1, wcharStr, MAX_PATH);
  167. //Load the audio segment from a file
  168. hr= dmLoader->LoadObjectFromFile(CLSID_DirectMusicSegment,
  169.  IID_IDirectMusicSegment8,
  170.  wcharStr,
  171.  (void**)&pSound[NumOfSound].dmSegment);
  172. if(FAILED(hr))
  173. {
  174. return false;
  175. }
  176. //Do code specific for 3D CSounds
  177. if(is3DSound)
  178. {
  179. //Get the 3D buffer, and audio path
  180. hr= dm3DAudioPath->GetObjectInPath(DMUS_PCHANNEL_ALL, DMUS_PATH_BUFFER, 0, 
  181.    GUID_NULL, 0, IID_IDirectSound3DBuffer,
  182.    (void**)&pSound[NumOfSound].ds3DBuffer);
  183. if(FAILED(hr))
  184. {
  185. return false;
  186. }
  187. //Get the 3D buffer paramters
  188. dsBufferParams.dwSize= sizeof(DS3DBUFFER);
  189. pSound[NumOfSound].ds3DBuffer->GetAllParameters(&dsBufferParams);
  190. //Set some new parameters
  191. dsBufferParams.dwMode= DS3DMODE_HEADRELATIVE;    // relative to the listener
  192. pSound[NumOfSound].ds3DBuffer->SetAllParameters(&dsBufferParams, DS3D_IMMEDIATE);
  193. //Set the 3D CSound flag to true
  194. pSound[NumOfSound].is3DSound = true;
  195. }
  196. //Do code specific to non-3D CSounds (background music)
  197. else
  198. {
  199. //Set the 3D buffer to null since we don't need it
  200. pSound[NumOfSound].ds3DBuffer= NULL;
  201. //Set the 3D CSound flag to false, since we don't need it either
  202. pSound[NumOfSound].is3DSound= false;
  203. }
  204. return true;
  205. }
  206. //------------------------------------------------------------------//
  207. //- void CAudio::Play(CSound*, DWORD) -------------------------//
  208. //------------------------------------------------------------------//
  209. //- Play the CSound, and repeat it numRepeats amount of times.    -//
  210. //------------------------------------------------------------------//
  211. void CAudio::
  212. Play(unsigned int NumOfSound, DWORD numRepeats)
  213. {
  214. if(NumOfSound>(m_MaxNum-1))return ;
  215. //Set the number of repeats that we want for the specific CSound
  216. pSound[NumOfSound].dmSegment->SetRepeats(numRepeats);
  217. if(pSound[NumOfSound].is3DSound)
  218. {
  219. pSound[NumOfSound].dmSegment->Download(dmPerformance);
  220. //Play the segment using the 3D audio path
  221. dmPerformance->PlaySegmentEx(pSound[NumOfSound].dmSegment, NULL, NULL, 
  222.  DMUS_SEGF_ALIGN , 0,
  223.  NULL, NULL, dm3DAudioPath);
  224. }
  225. else
  226. {
  227. //Download the segment's performance object
  228. pSound[NumOfSound].dmSegment->Download(dmPerformance);
  229. //Play the non-3D CSound segment
  230. dmPerformance->PlaySegmentEx(pSound[NumOfSound].dmSegment, NULL, NULL, 
  231.  DMUS_SEGF_DEFAULT, 0,
  232.  NULL, NULL, NULL);
  233. }
  234. }
  235. //------------------------------------------------------------------//
  236. //- void CAudio::Stop(CSound*) --------------------------------//
  237. //------------------------------------------------------------------//
  238. //- Stop playing the specified CSound.    -//
  239. //------------------------------------------------------------------//
  240. void CAudio::
  241. Stop(unsigned int NumOfSound)
  242. {
  243. if(NumOfSound>(m_MaxNum-1))  return  ;
  244. dmPerformance->StopEx(pSound[NumOfSound].dmSegment, 0, 0);
  245. }
  246. //------------------------------------------------------------------//
  247. //- void CAudio::SetListenerPos(float, float, float) ---------//
  248. //------------------------------------------------------------------//
  249. //- Set the listener's (player's) position in 3D space.    -//
  250. //------------------------------------------------------------------//
  251. void CAudio::
  252. SetListenerPos(float x, float y, float z)
  253. {
  254. //Get the listener parameters
  255. dsListenerParams.dwSize= sizeof(DS3DLISTENER);
  256. ds3DListener->GetAllParameters(&dsListenerParams);
  257. //Set the listener's position in 3D space
  258. dsListenerParams.vPosition.x=  x;
  259. dsListenerParams.vPosition.y=  y;
  260. dsListenerParams.vPosition.z= -z;
  261. //Set all of the new parameters
  262. ds3DListener->SetAllParameters(&dsListenerParams, DS3D_IMMEDIATE);
  263. }
  264. //------------------------------------------------------------------//
  265. //- void CAudio::SetListenerRolloff(float) -------------------//
  266. //------------------------------------------------------------------//
  267. //- Set the listener's CSound volume rolloff with distance.    -//
  268. //------------------------------------------------------------------//
  269. void CAudio::
  270. SetListenerRolloff(float rolloff)
  271. {
  272. if(ds3DListener)
  273. ds3DListener->SetRolloffFactor(rolloff, DS3D_IMMEDIATE);
  274. }
  275. //------------------------------------------------------------------//
  276. //- void CAudio::SetListenerOrientation(float, float, float, float, float, float) -//
  277. //------------------------------------------------------------------//
  278. //- Set the listener's orientation (you may need to implement a    -//
  279. //- camera class to use this function correctly).    -//
  280. //------------------------------------------------------------------//
  281. void CAudio::
  282. SetListenerOrientation(float forwardX, float forwardY, float forwardZ,
  283.    float topX, float topY, float topZ)
  284. {
  285. ds3DListener->SetOrientation(forwardX, forwardY, -forwardZ, 
  286.  topX, topY, topZ, DS3D_IMMEDIATE);
  287. }