📄 soundinstance.cpp
字号:
// SoundInstance.cpp: implementation of the CSoundInstance class.
//
//////////////////////////////////////////////////////////////////////
#include "SoundInstance.h"
#include "Sound.h"
#include "AudioManager.h"
#include <assert.h>
namespace AudioEngine {
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CSoundInstance::CSoundInstance()
{
m_SegmentState = NULL;
m_AudioPath = NULL;
m_DirectSoundBuffer = NULL;
m_Valid = false;
m_ReleaseAudioPath = true;
}
CSoundInstance::~CSoundInstance()
{
ClearEffectsVector();
UnInit();
}
void CSoundInstance::ClearEffectsVector()
{
for (std::vector<CEffect *>::iterator i = m_Effects.begin(); i != m_Effects.end(); ++i) {
delete (*i);
}
m_Effects.clear();
}
void CSoundInstance::ApplyEffectsToAudioPath()
{
HRESULT hr;
if (NULL == m_AudioPath || NULL == m_DirectSoundBuffer) return;
// deactivate audiopath
m_AudioPath->Activate(false);
// remove any effects possibly attached.
hr = m_DirectSoundBuffer->SetFX(0, NULL, NULL);
ThrowIfFailed(hr, "CSoundInstance::ApplyEffectsToAudioPath(): Couldn't remove effects chain.");
if (m_Effects.size() == 0) {
m_AudioPath->Activate(true);
return;
}
// our effects vector isn't empty, so loop through it and apply the effects to the audiopath
std::vector<DSEFFECTDESC> effectdescs;
std::vector<DWORD> effectdescresults;
for (std::vector<CEffect *>::iterator i = m_Effects.begin(); i != m_Effects.end(); ++i) {
DSEFFECTDESC edesc;
edesc.dwSize = sizeof(DSEFFECTDESC);
edesc.dwFlags = 0;
edesc.guidDSFXClass = (*i)->GetGuid();
edesc.dwReserved1 = 0;
edesc.dwReserved2 = 0;
effectdescs.push_back(edesc);
effectdescresults.push_back(0); // dummy value just to allocate space
}
hr = m_DirectSoundBuffer->SetFX(effectdescs.size(), &effectdescs[0], &effectdescresults[0]);
ThrowIfFailed(hr, "CSoundInstance::ApplyEffectsToAudioPath(): creation of effects chain failed.");
// feel free to add more detailed error msg processing here
// (i.e., look at the results vector to determine which effect in the chain failed)
// now that the effects are created, grab each of their interfaces and set their params.
for (std::vector<CEffect *>::iterator q = m_Effects.begin(); q != m_Effects.end(); ++q) {
(*q)->SetAllParameters(m_AudioPath);
}
// activate audiopath
m_AudioPath->Activate(true);
}
void CSoundInstance::AddEffect(CEffect *effect)
{
m_Effects.push_back(effect);
ApplyEffectsToAudioPath();
}
void CSoundInstance::RemoveAllEffects()
{
ClearEffectsVector();
ApplyEffectsToAudioPath();
}
void CSoundInstance::Init(CDirectMusicSegment *seg, IDirectMusicAudioPath8 *path, bool control)
{
HRESULT hr;
m_AudioPath = path;
// get audio path's underlying directsound buffer
hr = m_AudioPath->GetObjectInPath(DMUS_PCHANNEL_ALL, DMUS_PATH_BUFFER, 0,
GUID_NULL, 0, IID_IDirectSoundBuffer8, (LPVOID*)&m_DirectSoundBuffer);
ThrowIfFailed(hr, "CSoundInstance::Init(): Couldn't get DirectSound buffer interface.");
m_Valid = true;
// set volume based on sound's volume
SetVolume(seg->GetVolume());
// apply effects to audio path
ApplyEffectsToAudioPath();
// now that everything's set, go ahead and play it.
hr = GetAudioManager()->GetPerformance()->PlaySegmentEx(seg->GetSegment(), NULL, NULL,
control ? DMUS_SEGF_CONTROL : DMUS_SEGF_SECONDARY, 0,
(IDirectMusicSegmentState **)&m_SegmentState,
NULL, path);
ThrowIfFailed(hr, "CSoundInstance::Init: PlaySegmentEx failed.");
}
void CSoundInstance::UnInit()
{
SAFE_RELEASE(m_SegmentState);
if (m_ReleaseAudioPath) SAFE_RELEASE(m_AudioPath);
SAFE_RELEASE(m_DirectSoundBuffer);
m_Valid = false;
}
void CSoundInstance::SetVolume(const CVolume &vol, int fadeoverms)
{
assert(IsValid()); if (!IsValid()) { return; }
m_AudioPath->SetVolume(vol.ToDirectMusic(), fadeoverms);
}
bool CSoundInstance::IsPlaying()
{
assert(IsValid()); if (!IsValid()) { return(false); }
return(GetAudioManager()->GetPerformance()->IsPlaying(NULL, m_SegmentState) == S_OK);
}
bool CSoundInstance::Stop(MUSIC_TIME time, DWORD flags)
{
return(SUCCEEDED(GetAudioManager()->GetPerformance()->Stop(NULL, m_SegmentState, time, flags)));
}
}; // namespace
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -