⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 soundinstance.cpp

📁 游戏音频程序设计-Beginning.Game.Audio.Programming
💻 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 + -