Audio.cpp
上传用户:hkb425
上传日期:2007-06-16
资源大小:34191k
文件大小:16k
- // Audio.cpp: implementation of the CAudio class.
- //
- //////////////////////////////////////////////////////////////////////
- #include "stdafx.h"
- #include "Audio.h"
- /////////////////////////////////////////////
- void CAudioSegment::Set3DPos(VERTEX *pos)
- {
- if(ds3DBuffer)
- {
- ds3DBuffer->SetPosition(pos->xpos, pos->ypos, -pos->zpos,
- DS3D_IMMEDIATE);
- }
- }
- //------------------------------------------------------------------//
- //- void CAudioSegment::Set3DDistances(float, float) -----------------------//
- //------------------------------------------------------------------//
- //- Sets the max, and minimum distance for a CAudioSegment to be heard. -//
- //------------------------------------------------------------------//
- void CAudioSegment::Set3DDistances(float minDistance, float maxDistance)
- {
- if(ds3DBuffer)
- {
- ds3DBuffer->SetMinDistance(minDistance, DS3D_IMMEDIATE);
- ds3DBuffer->SetMaxDistance(maxDistance, DS3D_IMMEDIATE);
- }
- }
- //------------------------------------------------------------------//
- //- void CAudioSegment::Shutdown(void) -------------------------------------//
- //------------------------------------------------------------------//
- //- Shutdown the CAudioSegment, I originally had this in the destructor, -//
- //- but it was acting screwy... so I now it has it's own function. -//
- //------------------------------------------------------------------//
- void CAudioSegment::Shutdown(void)
- {
- if(dmSegment!=NULL)
- {
- dmSegment->Release();
- dmSegment= NULL;
- }
- if(ds3DBuffer!=NULL)
- {
- ds3DBuffer->Release();
- ds3DBuffer= NULL;
- }
- if(vPosition!=NULL)
- {
- delete vPosition;
- vPosition= NULL;
- }
- }
- /////////////////////////////////////////////////////////
- //////////////// class CAudio
- LPDIRECTMUSICLOADER8 CAudio::dmLoader=NULL; // the loader
- LPDIRECTMUSICPERFORMANCE8 CAudio::dmPerformance=NULL; // the performance
- LPDIRECTMUSICAUDIOPATH CAudio::dm3DAudioPath=NULL; // the audiopath
- //////////////////////////////////
- CAudioSegment *CAudio::pSound=NULL;
- char *CAudio::pSoundState=NULL;
- VERTEX CAudio::vListenerPos=VERTEX(0,0,0);
- float CAudio::froty=0;
- bool CAudio::bEnable=true;
- bool CAudio::bActive=true;
- int CAudio::m_numUser=0;
- //////////////////////////////////////////////////////////////////////
- // Construction/Destruction
- //////////////////////////////////////////////////////////////////////
- CAudio::CAudio()
- {
- if(m_numUser==0)
- {
- if(!InitAudio())
- {
- bEnable=false;
- bActive=false;
- }
- }
- m_numUser++;
- }
- CAudio::~CAudio()
- {
- m_numUser--;
- if(m_numUser==0)
- {
- ReleaseAudio();
- }
- }
- ////////////////////////////////////////////////////
- //------------------------------------------------------------------//
- //- 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::InitAudio()
- {
- HRESULT hr;
- WCHAR wcharStr[MAX_PATH];
- char pathStr[MAX_PATH];
- hr=CoInitialize(NULL);
- if(FAILED(hr))
- {
- // MessageBox(NULL, "Unable to CoInitialize", "ERROR", MB_OK);
- return false;
- }
- //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(NULL, "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(NULL, "Unable to create main DirectAudio performance object", "ERROR", MB_OK);
- ReleaseAudio();
- return false;
- }
- //Initialize the performance with the standard audio path information
- dmPerformance->InitAudio(NULL, NULL, NULL, 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(NULL, "Unable to create the DirectAudio audio path", "ERROR", MB_OK);
- ReleaseAudio();
- return false;
- }
- //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);
- ///////////////////
- ////////////////////////////////////
- pSound=new CAudioSegment[MAX_SOUND_NUM];
- pSoundState=new char [MAX_SOUND_NUM];
- for(unsigned int i=0;i<MAX_SOUND_NUM;i++)
- pSoundState[i]=SOUND_NULL;
- return true;
- }
- //------------------------------------------------------------------//
- //- bool CAudio::Create(CAudioSegment*, char*, bool) -----------------//
- //------------------------------------------------------------------//
- //- Use the audio manager to create an individual CAudioSegment effect from-//
- //- a file. -//
- //------------------------------------------------------------------//
- bool CAudio::CreateSound(unsigned int NumOfSound, char* filename, bool is3DSound)
- {
- if(!bEnable)return false;
- if(NumOfSound>(MAX_SOUND_NUM-1) || pSoundState[NumOfSound]!=SOUND_NULL) return false ;
- 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 CAudioSegments
- 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
- pSound[NumOfSound].vPosition = new VERTEX;
- pSound[NumOfSound].vPosition->xpos=0;
- pSound[NumOfSound].vPosition->ypos=0;
- pSound[NumOfSound].vPosition->zpos=0;
-
- DS3DBUFFER dsBufferParams;
- dsBufferParams.dwSize= sizeof(DS3DBUFFER);
- pSound[NumOfSound].ds3DBuffer->GetAllParameters(&dsBufferParams);
- //Set some new parameters
- dsBufferParams.dwMode= DS3DMODE_HEADRELATIVE; // relative to the listener
- dsBufferParams.flMinDistance=100;
- dsBufferParams.flMaxDistance=3000;
- pSound[NumOfSound].ds3DBuffer->SetAllParameters(&dsBufferParams, DS3D_IMMEDIATE);
- //Set the 3D CAudioSegment flag to true
- pSound[NumOfSound].is3DSound = true;
- pSoundState[NumOfSound]=SOUND_3D_IDLE;
- }
- else//Do code specific to non-3D CAudioSegments (background music)
- {
- //Set the 3D buffer to null since we don't need it
- pSound[NumOfSound].ds3DBuffer= NULL;
- //Set the 3D CAudioSegment flag to false, since we don't need it either
- pSound[NumOfSound].is3DSound= false;
- pSoundState[NumOfSound]=SOUND_2D_IDLE;
- }
-
- ////////////////////////////
- return true;
- }
- //------------------------------------------------------------------//
- //- void CAudio::Play(CAudioSegment*, DWORD) -------------------------//
- //------------------------------------------------------------------//
- //- Play the CAudioSegment, and repeat it numRepeats amount of times. -//
- //------------------------------------------------------------------//
- void CAudio::Play(unsigned int NumOfSound, DWORD numRepeats, bool bPrimary,bool bCheckOlyOne )
- {
- if(!bEnable || !bActive)return;
- if(NumOfSound>(MAX_SOUND_NUM-1) || pSoundState[NumOfSound]==SOUND_NULL) return ;
- if(bCheckOlyOne && CheckSoundPlaying(NumOfSound))return;
- //Set the number of repeats that we want for the specific CAudioSegment
- pSound[NumOfSound].dmSegment->SetRepeats(numRepeats);
- DWORD dwFlags;
- if(bPrimary)dwFlags=DMUS_SEGF_DEFAULT;
- else dwFlags=DMUS_SEGF_DEFAULT | DMUS_SEGF_SECONDARY;
- if(pSound[NumOfSound].is3DSound)
- {
- pSound[NumOfSound].dmSegment->Download(dmPerformance);
- //Play the segment using the 3D audio path
- dmPerformance->PlaySegmentEx(pSound[NumOfSound].dmSegment, NULL, NULL,
- dwFlags , 0,
- NULL, NULL, dm3DAudioPath);
- pSoundState[NumOfSound]=SOUND_3D_PLAYING;
- }
- else
- {
- //Download the segment's performance object
- pSound[NumOfSound].dmSegment->Download(dmPerformance);
- //Play the non-3D CAudioSegment segment
- dmPerformance->PlaySegmentEx(pSound[NumOfSound].dmSegment, NULL, NULL,
- dwFlags, 0,
- NULL, NULL, NULL);
- pSoundState[NumOfSound]=SOUND_2D_PLAYING;
- }
- }
- //------------------------------------------------------------------//
- //- void CAudio::Stop(CAudioSegment*) --------------------------------//
- //------------------------------------------------------------------//
- //- Stop playing the specified CAudioSegment. -//
- //------------------------------------------------------------------//
- void CAudio::Stop(unsigned int NumOfSound)
- {
- if(!bEnable)return;
- if(NumOfSound>(MAX_SOUND_NUM-1) ||
- pSoundState[NumOfSound]==SOUND_NULL ||
- pSoundState[NumOfSound]==SOUND_2D_IDLE ) return ;
-
- dmPerformance->StopEx(pSound[NumOfSound].dmSegment, 0, 0);
- if(pSound[NumOfSound].is3DSound)
- pSoundState[NumOfSound]=SOUND_3D_IDLE;
- else
- pSoundState[NumOfSound]=SOUND_2D_IDLE;
- }
- void CAudio::StopAll()
- {
- if(!bEnable)return;
- dmPerformance->StopEx(0, 0, 0);
- for(unsigned int i=0;i< MAX_SOUND_NUM;i++)
- if(pSoundState[i]!=SOUND_NULL)
- {
- if(pSound[i].is3DSound)
- pSoundState[i]=SOUND_3D_IDLE;
- else
- pSoundState[i]=SOUND_2D_IDLE;
- }
- }
- void CAudio::SetVolume(int iVolume)
- {
- if(!bEnable)return;
- if(iVolume<0)iVolume=0;
- if(iVolume>100)iVolume=100;
- int volume=-4000+iVolume*60;
- dmPerformance->SetGlobalParam( GUID_PerfMasterVolume,
- (void*)&volume, sizeof(int) );
- }
- //------------------------------------------------------------------//
- //- void CAudio::SetListenerPos(float, float, float) ---------//
- //------------------------------------------------------------------//
- //- Set the listener's (player's) position in 3D space. -//
- //------------------------------------------------------------------//
- void CAudio::SetListenerPos(VERTEX *pos,float roty)
- {
- if(!bEnable)return;
- VERTEX v0;
- froty=roty;
- vListenerPos.xpos=pos->xpos;
- vListenerPos.ypos=pos->ypos;
- vListenerPos.zpos=pos->zpos;
- /*
- for(unsigned int i=0;i<MAX_SOUND_NUM;i++)
- {
- if(pSound[i].is3DSound && pSoundState[i]!=SOUND_NULL)
- {
- v0=GetTransformSoundPos(pSound[i].vPosition);
- pSound[i].Set3DPos(&v0);
- }
- }*/
- }
- //------------------------------------------------------------------//
- //- void CAudio::SetSoundPos(int ,float, float, float) ---------//
- //------------------------------------------------------------------//
- //- Set the sound's position in 3D space. -//
- void CAudio::SetSoundPos(unsigned int NumOfSound,VERTEX *pos)
- {
- if(!bEnable)return;
- if(NumOfSound>(MAX_SOUND_NUM-1) || pSoundState[NumOfSound]==SOUND_NULL) return ;
- if(pSound[NumOfSound].is3DSound)
- {
- pSound[NumOfSound].vPosition->xpos=pos->xpos;
- pSound[NumOfSound].vPosition->ypos=pos->ypos;
- pSound[NumOfSound].vPosition->zpos=pos->zpos;
- VERTEX v0=GetTransformSoundPos(pos);
- pSound[NumOfSound].Set3DPos(&v0);
- }
- }
- //------------------------------------------------------------------//
- //- void CAudio::GetTransformSoundPos(VERTEX *vSoundPos)------------------//
- //------------------------------------------------------------------//
- VERTEX CAudio::GetTransformSoundPos(VERTEX *vSoundPos)
- {
- //////// translation
- VERTEX v0=VERTEX(vSoundPos->xpos - vListenerPos.xpos,
- vSoundPos->ypos - vListenerPos.ypos,
- vSoundPos->zpos - vListenerPos.zpos);
- //////// y rotate
- VERTEX v1=VERTEX(v0.xpos*cosf(froty*0.0174533f)-
- v0.zpos*sinf(froty*0.0174533f),
- v0.ypos,
- v0.xpos*sinf(froty*0.0174533f)+
- v0.zpos*cosf(froty*0.0174533f));
- return v1;
- }
- //------------------------------------------------------------------//
- //- void CAudio::CheckSoundPlaying(unsigned int NumOfSound)-------------------//
- //------------------------------------------------------------------//
- bool CAudio::CheckSoundPlaying(unsigned int NumOfSound)
- {
- if(!bEnable)return false;
- if(NumOfSound>(MAX_SOUND_NUM-1) || pSoundState[NumOfSound]==SOUND_NULL)return false ;
- HRESULT hr=dmPerformance->IsPlaying(pSound[NumOfSound].dmSegment,0);
- if(hr==S_OK)
- {
- if(pSound[NumOfSound].is3DSound)
- pSoundState[NumOfSound]=SOUND_3D_PLAYING;
- else
- pSoundState[NumOfSound]=SOUND_2D_PLAYING;
- return true;
- }
- else
- {
- if(pSound[NumOfSound].is3DSound)
- pSoundState[NumOfSound]=SOUND_3D_IDLE;
- else
- pSoundState[NumOfSound]=SOUND_2D_IDLE;
- return false;
- }
- }
- //------------------------------------------------------------------//
- //- CAudio::GetSoundState(unsigned int NumOfSound)------------------//
- //------------------------------------------------------------------//
- int CAudio::GetSoundState(unsigned int NumOfSound)
- {
- if(!bEnable)return 0;
- if(pSoundState[NumOfSound]==SOUND_3D_PLAYING || pSoundState[NumOfSound]==SOUND_2D_PLAYING)
- CheckSoundPlaying(NumOfSound);
- return (int)pSoundState[NumOfSound];
- }
- //------------------------------------------------------------------//
- //- void CAudio::SetListenerRolloff(float) -------------------//
- //------------------------------------------------------------------//
- //- Set the listener's CAudioSegment volume rolloff with distance. -//
- //------------------------------------------------------------------//
- void CAudio::SetSoundRolloff(float rolloff)
- {
- }
- //------------------------------------------------------------------//
- //- void CAudio::ShutdowSound(unsigned int NumOfSound) ------------------------//
- //------------------------------------------------------------------//
- void CAudio::DeleteSound(unsigned int NumOfSound)
- {
- if(!bEnable)return;
- if(pSoundState[NumOfSound]!=SOUND_NULL)
- {
- pSound[NumOfSound].Shutdown();
- pSoundState[NumOfSound]=SOUND_NULL;
- }
- }
- bool CAudio::SetAudioActive(bool bAudioActive)
- {
- if(!bEnable)return false;
- bActive=bAudioActive;
- return true;
- }
- bool CAudio::IsAudioEnable()
- {
- return bEnable;
- }
- bool CAudio::IsAudioActive()
- {
- return bActive;
- }
- //------------------------------------------------------------------//
- //- void CAudio::ReleaseAudio(void) ------------------------//
- //------------------------------------------------------------------//
- //- Shuts down DirectAudio. This function is called automatically -//
- //- by the CAudio destructor, hence the reason why this -//
- //- function is private. -//
- //------------------------------------------------------------------//
- void CAudio::ReleaseAudio(void)
- {
- if(pSound!=NULL && pSoundState!=NULL)
- {
- for(unsigned int i=0;i < MAX_SOUND_NUM;i++)
- {
- if(pSoundState[i]!=SOUND_NULL)pSound[i].Shutdown();
- }
- delete [] pSound;
- delete [] pSoundState;
- pSound=NULL;
- pSoundState=NULL;
- }
- //Shut down the direct music performance information
- if(dmPerformance!=NULL)
- {
- dmPerformance->Stop(NULL, NULL, 0, 0);
- dmPerformance->CloseDown();
- dmPerformance->Release();
- dmPerformance=NULL;
- }
- //Shut down the direct music audiopath
- if(dm3DAudioPath!=NULL)
- {
- dm3DAudioPath->Release();
- dm3DAudioPath=NULL;
- }
- //Shut down the direct music loader
- if(dmLoader!=NULL)
- {
- dmLoader->Release();
- dmLoader=NULL;
- }
- //Uninitialize COM (*MUST* be done, or you're asking for trouble)
- CoUninitialize();
- }