www.pudn.com > 林海血原源代码.zip > Audio.cpp


// Audio.cpp: implementation of the CAudio class. 
// 
////////////////////////////////////////////////////////////////////// 
 
#include "stdafx.h" 
#include "Audio.h" 
////////////////////////////////////////////////////////////////////// 
// Construction/Destruction 
////////////////////////////////////////////////////////////////////// 
 
void CSound:: 
	Set3DPos(float x, float y, float z) 
	{	ds3DBuffer->SetPosition(x, y, -z, DS3D_IMMEDIATE);	} 
 
//------------------------------------------------------------------// 
//- void CSound::Set3DDistances(float, float) -----------------------// 
//------------------------------------------------------------------// 
//- Sets the max, and minimum distance for a CSound to be heard.	   -// 
//------------------------------------------------------------------// 
void CSound:: 
	Set3DDistances(float minDistance, float maxDistance) 
	{ 
	DS3DBUFFER dsBufferParams; 
 
	dsBufferParams.flMinDistance= minDistance;	//Sets the minimum distance 
	dsBufferParams.flMaxDistance= maxDistance;	//Sets the maximum distance 
 
	//Now, set the parameters for our CSound's 3D buffer 
	if(ds3DBuffer) 
		ds3DBuffer->SetAllParameters(&dsBufferParams, DS3D_IMMEDIATE); 
	} 
 
//------------------------------------------------------------------// 
//- void CSound::Shutdown(void) -------------------------------------// 
//------------------------------------------------------------------// 
//- Shutdown the CSound, I originally had this in the destructor,   -// 
//- but it was acting screwy... so I now it has it's own function. -// 
//------------------------------------------------------------------// 
void CSound:: 
	Shutdown(void) 
	{ 
	if(dmSegment!=NULL) 
		{ 
		dmSegment->Release(); 
		dmSegment= NULL; 
		} 
 
	if(ds3DBuffer!=NULL) 
		{ 
		ds3DBuffer->Release();  
		ds3DBuffer= NULL; 
		} 
	} 
 
//------------------------------------------------------------------// 
//- bool CAudio::Init(void) ----------------------------------// 
//------------------------------------------------------------------// 
//- Initiates DirectAudio.  This function must be called by the    -// 
//- programmer, though the shutdown function is automatically	   -// 
//- called by the destructor (as, not shutting down DAudio		   -// 
//- correctly can have some bad consequences).					   -// 
//------------------------------------------------------------------// 
bool CAudio:: 
	Init(HWND hwnd,unsigned int MaxNumber) 
	{ 
	HRESULT hr; 
	WCHAR wcharStr[MAX_PATH]; 
	char pathStr[MAX_PATH]; 
 
	CoInitialize(NULL); 
 
	//Create the loader object, load it... and load it good. 
	hr= CoCreateInstance(CLSID_DirectMusicLoader, NULL, CLSCTX_INPROC, 
						IID_IDirectMusicLoader8, (void**)&dmLoader); 
	if(FAILED(hr)) 
		{ 
		MessageBox(hwnd, "Unable to create main DirectAudio file loader", "ERROR", MB_OK); 
 
		return false; 
		} 
 
	//Create the performance object for that.... performance stuff.  
	hr= CoCreateInstance(CLSID_DirectMusicPerformance, NULL, CLSCTX_INPROC, 
						 IID_IDirectMusicPerformance8, (void**)&dmPerformance); 
	if(FAILED(hr)) 
		{ 
		MessageBox(hwnd, "Unable to create main DirectAudio performance object", "ERROR", MB_OK); 
 
		Shutdown(); 
		return false; 
		} 
 
	//Initialize the performance with the standard audio path information 
	dmPerformance->InitAudio(NULL, NULL, hwnd, DMUS_APATH_DYNAMIC_3D , 64, 
							 DMUS_AUDIOF_ALL, NULL); 
 
     //Create a simple 3D audiopath 
	 hr= dmPerformance->CreateStandardAudioPath(DMUS_APATH_DYNAMIC_3D, 
												64, TRUE, &dm3DAudioPath); 
     if(FAILED(hr)) 
		{ 
		MessageBox(hwnd, "Unable to create the DirectAudio audio path", "ERROR", MB_OK); 
 
		Shutdown(); 
		return false; 
		} 
 
     //Retrieve the listener information from our audiopath 
	 hr= dm3DAudioPath->GetObjectInPath(0, DMUS_PATH_PRIMARY_BUFFER, 0, GUID_NULL, 0,  
											IID_IDirectSound3DListener8, 
											(void**)&ds3DListener); 
     if(FAILED(hr)) 
		{ 
		MessageBox(hwnd, "Unable to recieve listener from audio path", "ERROR", MB_OK); 
 
		Shutdown(); 
		return false; 
		} 
 
	//Get the listener information 
	dsListenerParams.dwSize= sizeof(DS3DLISTENER); 
	ds3DListener->GetAllParameters(&dsListenerParams); 
 
	//Set our default position of listener (since the listener shouldn't be moving all too much 
	dsListenerParams.vPosition.x= 0.0f; 
	dsListenerParams.vPosition.y= 0.0f; 
	dsListenerParams.vPosition.z= 0.0f; 
	ds3DListener->SetAllParameters(&dsListenerParams, DS3D_IMMEDIATE); 
 
	//Retrieve the current directory 
	GetCurrentDirectory(MAX_PATH, pathStr); 
 
	//Convert the file name to a unicode string... as thats what COM needs 
	MultiByteToWideChar(CP_ACP, 0, pathStr, -1, wcharStr, MAX_PATH); 
 
	//Set the search directory 
	dmLoader->SetSearchDirectory(GUID_DirectMusicAllTypes, wcharStr, FALSE); 
 
	m_MaxNum=MaxNumber; 
	pSound=new CSound[m_MaxNum]; 
	return true; 
	} 
 
//------------------------------------------------------------------// 
//- void CAudio::DAudioShutdown(void) ------------------------// 
//------------------------------------------------------------------// 
//- Shuts down DirectAudio.  This function is called automatically -// 
//- by the CAudio destructor, hence the reason why this	   -// 
//- function is private.										   -// 
//------------------------------------------------------------------// 
void CAudio::Shutdown(void) 
{ 
    for(unsigned int i=0;i < m_MaxNum;i++) 
	{ 
		pSound[i].Shutdown(); 
	} 
 
    delete [] pSound; 
	//Shut down the direct CSound listener(player) information 
	if(ds3DListener!=NULL) 
		ds3DListener->Release(); 
 
	//Shut down the direct music performance information 
 
	if(dmPerformance!=NULL) 
		{ 
		dmPerformance->Stop(NULL, NULL, 0, 0); 
		dmPerformance->CloseDown(); 
 
		dmPerformance->Release(); 
		} 
 
 
	//Shut down the direct music audiopath 
	if(dm3DAudioPath!=NULL) 
		dm3DAudioPath->Release(); 
 
	//Shut down the direct music loader 
  	if(dmLoader!=NULL) 
    	dmLoader->Release(); 
 
 
	//Uninitialize COM (*MUST* be done, or you're asking for trouble) 
	CoUninitialize(); 
 
	} 
 
//------------------------------------------------------------------// 
//- bool CAudio::Create(CSound*, char*, bool) -----------------// 
//------------------------------------------------------------------// 
//- Use the audio manager to create an individual CSound effect from-// 
//- a file.														   -// 
//------------------------------------------------------------------// 
bool CAudio:: 
	Create(unsigned int NumOfSound, char* filename, bool is3DSound) 
	{ 
 
	if(NumOfSound>(m_MaxNum-1))return false; 
 
	DS3DBUFFER dsBufferParams;  
	HRESULT hr; 
	WCHAR wcharStr[MAX_PATH]; 
 
	//Convert the file name to the string that DirectAudio needs 
	MultiByteToWideChar(CP_ACP, 0, filename, -1, wcharStr, MAX_PATH); 
 
	//Load the audio segment from a file 
	hr= dmLoader->LoadObjectFromFile(CLSID_DirectMusicSegment, 
									 IID_IDirectMusicSegment8, 
									 wcharStr, 
									 (void**)&pSound[NumOfSound].dmSegment); 
	if(FAILED(hr)) 
		{ 
 
		return false; 
		} 
 
	//Do code specific for 3D CSounds 
	if(is3DSound) 
		{ 
		//Get the 3D buffer, and audio path 
		hr= dm3DAudioPath->GetObjectInPath(DMUS_PCHANNEL_ALL, DMUS_PATH_BUFFER, 0,  
										   GUID_NULL, 0, IID_IDirectSound3DBuffer, 
										   (void**)&pSound[NumOfSound].ds3DBuffer); 
		if(FAILED(hr)) 
			{ 
			 
			return false; 
			} 
 
		//Get the 3D buffer paramters 
		dsBufferParams.dwSize= sizeof(DS3DBUFFER); 
		pSound[NumOfSound].ds3DBuffer->GetAllParameters(&dsBufferParams); 
 
		//Set some new parameters 
		dsBufferParams.dwMode= DS3DMODE_HEADRELATIVE;    // relative to the listener 
		pSound[NumOfSound].ds3DBuffer->SetAllParameters(&dsBufferParams, DS3D_IMMEDIATE); 
 
		//Set the 3D CSound flag to true 
		pSound[NumOfSound].is3DSound = true; 
		} 
	//Do code specific to non-3D CSounds (background music) 
	else 
		{ 
		//Set the 3D buffer to null since we don't need it 
		pSound[NumOfSound].ds3DBuffer= NULL; 
		//Set the 3D CSound flag to false, since we don't need it either 
		pSound[NumOfSound].is3DSound= false; 
		} 
 
	return true; 
	} 
 
//------------------------------------------------------------------// 
//- void CAudio::Play(CSound*, DWORD) -------------------------// 
//------------------------------------------------------------------// 
//- Play the CSound, and repeat it numRepeats amount of times.	   -// 
//------------------------------------------------------------------// 
void CAudio:: 
	Play(unsigned int NumOfSound, DWORD numRepeats) 
	{ 
 
	if(NumOfSound>(m_MaxNum-1))return ; 
	//Set the number of repeats that we want for the specific CSound 
	pSound[NumOfSound].dmSegment->SetRepeats(numRepeats); 
 
	if(pSound[NumOfSound].is3DSound) 
		{ 
		pSound[NumOfSound].dmSegment->Download(dmPerformance); 
 
		//Play the segment using the 3D audio path 
		dmPerformance->PlaySegmentEx(pSound[NumOfSound].dmSegment, NULL, NULL,  
									 DMUS_SEGF_ALIGN , 0, 
									 NULL, NULL, dm3DAudioPath); 
		} 
	else 
		{ 
		//Download the segment's performance object 
		pSound[NumOfSound].dmSegment->Download(dmPerformance); 
		//Play the non-3D CSound segment 
		dmPerformance->PlaySegmentEx(pSound[NumOfSound].dmSegment, NULL, NULL,  
									 DMUS_SEGF_DEFAULT, 0, 
									 NULL, NULL, NULL); 
		} 
	} 
 
//------------------------------------------------------------------// 
//- void CAudio::Stop(CSound*) --------------------------------// 
//------------------------------------------------------------------// 
//- Stop playing the specified CSound.							   -// 
//------------------------------------------------------------------// 
void CAudio:: 
	Stop(unsigned int NumOfSound) 
	{ 
	if(NumOfSound>(m_MaxNum-1))  return  ; 
	dmPerformance->StopEx(pSound[NumOfSound].dmSegment, 0, 0);	 
} 
 
//------------------------------------------------------------------// 
//- void CAudio::SetListenerPos(float, float, float) ---------// 
//------------------------------------------------------------------// 
//- Set the listener's (player's) position in 3D space.			   -// 
//------------------------------------------------------------------// 
void CAudio:: 
	SetListenerPos(float x, float y, float z) 
	{ 
	//Get the listener parameters 
	dsListenerParams.dwSize= sizeof(DS3DLISTENER); 
	ds3DListener->GetAllParameters(&dsListenerParams); 
 
	//Set the listener's position in 3D space 
	dsListenerParams.vPosition.x=  x; 
	dsListenerParams.vPosition.y=  y; 
	dsListenerParams.vPosition.z= -z; 
 
	//Set all of the new parameters 
	ds3DListener->SetAllParameters(&dsListenerParams, DS3D_IMMEDIATE); 
	} 
 
//------------------------------------------------------------------// 
//- void CAudio::SetListenerRolloff(float) -------------------// 
//------------------------------------------------------------------// 
//- Set the listener's CSound volume rolloff with distance.		   -// 
//------------------------------------------------------------------// 
void CAudio:: 
	SetListenerRolloff(float rolloff) 
	{ 
	if(ds3DListener) 
		ds3DListener->SetRolloffFactor(rolloff, DS3D_IMMEDIATE); 
	} 
 
//------------------------------------------------------------------// 
//- void CAudio::SetListenerOrientation(float, float, float, float, float, float) -// 
//------------------------------------------------------------------// 
//- Set the listener's orientation (you may need to implement a    -// 
//- camera class to use this function correctly).				   -// 
//------------------------------------------------------------------// 
void CAudio:: 
	SetListenerOrientation(float forwardX, float forwardY, float forwardZ, 
						   float topX, float topY, float topZ) 
	{ 
	ds3DListener->SetOrientation(forwardX, forwardY, -forwardZ,  
								 topX, topY, topZ, DS3D_IMMEDIATE); 
	}