www.pudn.com > ATimeToKill.rar > audiosystem.cpp
#include// DirectMusic includes #include #include // for D3DVECTOR #include // for GUID_NULL #include "audiosystem.h" ////// The CAudio implementation void CAudio::Set3DBuffer(IDirectSound3DBuffer *dsBuff) { ds3DBuffer = dsBuff; } void CAudio::Set3DPos(float x, float y, float z) { ds3DBuffer->SetPosition(x, y, -z, DS3D_IMMEDIATE); } void CAudio::Set3DParams(float minDistance, float maxDistance) { DS3DBUFFER dsBufferParams; // set minimum and maximum distances dsBufferParams.flMinDistance = minDistance; dsBufferParams.flMaxDistance = maxDistance; if (ds3DBuffer) ds3DBuffer->SetAllParameters(&dsBufferParams, DS3D_IMMEDIATE); } ////// The CAudioSystem implementation // constructor CAudioSystem::CAudioSystem() { dmusic3DAudioPath = NULL; dmusicLoader = NULL; dmusicPerformance = NULL; ds3DListener = NULL; } // destructor CAudioSystem::~CAudioSystem() { if (dmusic3DAudioPath) dmusic3DAudioPath->Release(); if (dmusicPerformance) dmusicPerformance->Release(); if (dmusicLoader) dmusicLoader->Release(); } // InitDirectXAudio() // desc: initialize the audio system bool CAudioSystem::InitDirectXAudio(HWND hwnd) { char pathStr[MAX_PATH]; // path for audio file WCHAR wcharStr[MAX_PATH]; // create the loader object if (FAILED(CoCreateInstance(CLSID_DirectMusicLoader, NULL, CLSCTX_INPROC, IID_IDirectMusicLoader8, (void**)&dmusicLoader))) { MessageBox(hwnd, "Unable to create the IDirectMusicLoader8 object!\nPress OK to exit", "ERROR!", MB_OK); return false; } // create the performance object if (FAILED(CoCreateInstance(CLSID_DirectMusicPerformance, NULL, CLSCTX_INPROC, IID_IDirectMusicPerformance8, (void**)&dmusicPerformance))) { MessageBox(hwnd, "Unable to create the IDirectMusicPerformance8 object!\nPress OK to exit", "ERROR!", MB_OK); return false; } // initialize the performance with the standard audio path dmusicPerformance->InitAudio(NULL, NULL, hwnd, DMUS_APATH_SHARED_STEREOPLUSREVERB, 64, DMUS_AUDIOF_ALL, NULL); // create a standard 3D audiopath if (FAILED(dmusicPerformance->CreateStandardAudioPath(DMUS_APATH_DYNAMIC_3D, 64, TRUE, &dmusic3DAudioPath))) { MessageBox(hwnd, "Unable to create standard 3D audiopath! Press OK to exit", "ERROR!", MB_OK); return false; } // retrieve the listener from the audiopath if (FAILED(dmusic3DAudioPath->GetObjectInPath(0, DMUS_PATH_PRIMARY_BUFFER, 0, GUID_NULL, 0, IID_IDirectSound3DListener8, (void**)&ds3DListener))) { MessageBox(hwnd, "Unable to retrieve the listener! Press OK to exit", "ERROR!", MB_OK); return false; } // get the listener parameters dsListenerParams.dwSize = sizeof(DS3DLISTENER); ds3DListener->GetAllParameters(&dsListenerParams); // set position of listener 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 to unicode string MultiByteToWideChar(CP_ACP, 0, pathStr, -1, wcharStr, MAX_PATH); // set the search directory dmusicLoader->SetSearchDirectory(GUID_DirectMusicAllTypes, wcharStr, FALSE); return true; } // Shutdown() // desc: shutdown the audio system void CAudioSystem::Shutdown() { // stop the music dmusicPerformance->Stop(NULL, NULL, 0, 0); // close down DirectMusic dmusicPerformance->CloseDown(); } // PlaySegment() // desc: play a segment void CAudioSystem::PlaySegment(IDirectMusicSegment8 *dmSeg, bool is3DSound, DWORD numRepeats) { // set the number of repeats dmSeg->SetRepeats(numRepeats);//DMUS_SEG_REPEAT_INFINITE); if (!is3DSound) // download the segment's instruments to the audiopath dmSeg->Download(dmusicPerformance); else { dmSeg->Download(dmusic3DAudioPath); // play the segment on the next beat using the 3d audio path dmusicPerformance->PlaySegmentEx(dmSeg, NULL, NULL, DMUS_SEGF_DEFAULT, 0, NULL, NULL, dmusic3DAudioPath); } } // Play() // desc: play a CAudio object void CAudioSystem::Play(CAudio *audio, DWORD numRepeats) { // set number of repeats audio->GetSegment()->SetRepeats(numRepeats); if (audio->Is3DSound()) { audio->GetSegment()->Download(dmusic3DAudioPath); // play the segment on the next beat using the 3d audio path dmusicPerformance->PlaySegmentEx(audio->GetSegment(), NULL, NULL, DMUS_SEGF_SECONDARY, 0, NULL, NULL, dmusic3DAudioPath); } else { audio->GetSegment()->Download(dmusicPerformance); // play the segment on the next beat using the 3d audio path dmusicPerformance->PlaySegmentEx(audio->GetSegment(), NULL, NULL, DMUS_SEGF_DEFAULT, 0, NULL, NULL, NULL); } } // Stop() // desc: stop a CAudio object from playing void CAudioSystem::Stop(CAudio *audio) { dmusicPerformance->StopEx(audio->GetSegment(), 0, 0); } // StopSegment() // desc: stop a segment from playing void CAudioSystem::StopSegment(IDirectMusicSegment8 *dmSeg) { // stop the dmSeg from playing dmusicPerformance->StopEx(dmSeg, 0, 0); } // SetListenerPos() // desc: set the listener position void CAudioSystem::SetListenerPos(float cameraX, float cameraY, float cameraZ) { // set the listener position //ds3DListener->SetPosition(cameraX, cameraY, -cameraZ, DS3D_IMMEDIATE); // get the listener parameters dsListenerParams.dwSize = sizeof(DS3DLISTENER); ds3DListener->GetAllParameters(&dsListenerParams); // set position of listener dsListenerParams.vPosition.x = cameraX; dsListenerParams.vPosition.y = cameraY; dsListenerParams.vPosition.z = -cameraZ; ds3DListener->SetAllParameters(&dsListenerParams, DS3D_IMMEDIATE); } // SetListenerRolloff() // desc: set the listener rolloff void CAudioSystem::SetListenerRolloff(float rolloff) { if (ds3DListener) ds3DListener->SetRolloffFactor(rolloff, DS3D_IMMEDIATE); } // Create3DBuffer() // desc: create a DX Audio 3D buffer IDirectSound3DBuffer *CAudioSystem::Create3DBuffer() { IDirectSound3DBuffer *buff; DS3DBUFFER dsBufferParams; // 3d buffer properties // get the 3D buffer in the audiopath if (FAILED(dmusic3DAudioPath->GetObjectInPath(DMUS_PCHANNEL_ALL, DMUS_PATH_BUFFER, 0, GUID_NULL, 0, IID_IDirectSound3DBuffer, (void**)&buff))) { MessageBox(NULL, "Unable to retrieve 3D buffer from audiopath! Press OK to exit", "ERROR!", MB_OK); return NULL; } // get the 3D buffer parameters dsBufferParams.dwSize = sizeof(DS3DBUFFER); buff->GetAllParameters(&dsBufferParams); // set the new 3D buffer parameters dsBufferParams.dwMode = DS3DMODE_HEADRELATIVE; // relative to the listener buff->SetAllParameters(&dsBufferParams, DS3D_IMMEDIATE); return buff; } // CreateSegment() // desc: create a DX Audio segment IDirectMusicSegment8 *CAudioSystem::CreateSegment(char *filename, bool is3DSound) { IDirectMusicSegment8 *seg; WCHAR wcharStr[MAX_PATH]; // convert filename to unicode string MultiByteToWideChar(CP_ACP, 0, filename, -1, wcharStr, MAX_PATH); // load the segment from file if (FAILED(dmusicLoader->LoadObjectFromFile(CLSID_DirectMusicSegment, IID_IDirectMusicSegment8, wcharStr, (void**)&seg))) { MessageBox(NULL, "Audio file not found! Press OK to exit", "ERROR!", MB_OK); return NULL; } return seg; } // Create() // desc: create a CAudio object CAudio *CAudioSystem::Create(char *filename, bool is3DSound) { CAudio *audio; IDirectMusicSegment8 *dmSeg; IDirectSound3DBuffer8 *ds3D; audio = new CAudio; dmSeg = CreateSegment(filename, is3DSound); audio->SetSegment(dmSeg); if (is3DSound) { ds3D = Create3DBuffer(); audio->Set3DBuffer(ds3D); audio->Set3DSound(true); } else { audio->Set3DBuffer(NULL); audio->Set3DSound(false); } return audio; }