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

📄 audiomanager.cpp

📁 游戏音频程序设计-Beginning.Game.Audio.Programming
💻 CPP
字号:
// AudioManager.cpp: implementation of the CAudioManager class.
//
//////////////////////////////////////////////////////////////////////

#include "AudioManager.h"

namespace AudioEngine {

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CAudioManager::CAudioManager()
{
  m_InitGood = false;
  m_Performance = NULL;
  m_Loader = NULL;
  m_NotificationHandler = NULL;
}

CAudioManager::~CAudioManager()
{

}

void CAudioManager::Init(HWND hwnd, bool stereo, int perfchannels)
{
  HRESULT hr;

  // initialize COM
  hr = CoInitialize(NULL);
  ThrowIfFailed(hr, "CAudioManager::Init: CoInitialize failed.");

  // Create the loader
  hr = CoCreateInstance(CLSID_DirectMusicLoader, NULL, CLSCTX_INPROC,
    IID_IDirectMusicLoader8, (void**)&m_Loader);
  ThrowIfFailed(hr, "CAudioManager::Init: CoCreateInstance for loader failed.");

  // Create performance object
  hr = CoCreateInstance( CLSID_DirectMusicPerformance, NULL, CLSCTX_INPROC, 
    IID_IDirectMusicPerformance8, (void**)&m_Performance);
  ThrowIfFailed(hr, "CAudioManager::Init: CoCreateInstance for performance failed.");

  hr = m_Performance->InitAudio(NULL, NULL, hwnd, stereo ? DMUS_APATH_DYNAMIC_STEREO : DMUS_APATH_DYNAMIC_MONO, 
    perfchannels, DMUS_AUDIOF_ALL, NULL);
  if (hr == DSERR_NODRIVER) {
    // output a warning message, then continue as usual
    MessageBox(hwnd, "The program could not locate your audio hardware.  Make sure your driver supports DirectX 8.", "Audio Engine", MB_ICONSTOP);
    return; // notice we didn't set m_InitGood true
  }
  else ThrowIfFailed(hr, "CAudioManager::Init: m_Performance->InitAudio failed.");


  // initialize mixer
  m_Mixer.Init();

  // add ALL notification messages (even though we may not do anything with some of them)
  GUID guid;

  /*
  guid = GUID_NOTIFICATION_CHORD;          
  ThrowIfFailed(m_Performance->AddNotificationType(guid), "CAudioManager::Init: couldn't add CHORD notification type!");

  guid = GUID_NOTIFICATION_COMMAND;        
  ThrowIfFailed(m_Performance->AddNotificationType(guid), "CAudioManager::Init: couldn't add COMMAND notification type!");
  */
  guid = GUID_NOTIFICATION_MEASUREANDBEAT; 
  ThrowIfFailed(m_Performance->AddNotificationType(guid), "CAudioManager::Init: couldn't add MEASUREANDBEAT notification type!");
  /*
  guid = GUID_NOTIFICATION_PERFORMANCE;    
  ThrowIfFailed(m_Performance->AddNotificationType(guid), "CAudioManager::Init: couldn't add PERFORMANCE notification type!");

  guid = GUID_NOTIFICATION_RECOMPOSE;      
  ThrowIfFailed(m_Performance->AddNotificationType(guid), "CAudioManager::Init: couldn't add RECOMPOSE notification type!");

  guid = GUID_NOTIFICATION_SEGMENT;        
  ThrowIfFailed(m_Performance->AddNotificationType(guid), "CAudioManager::Init: couldn't add SEGMENT notification type!");
  */
  // create event and tell DirectMusic about it
  m_NotificationEvent = CreateEvent(NULL, FALSE, FALSE, NULL);

  m_Performance->SetNotificationHandle(m_NotificationEvent, 0); // hold messages for default of 2 seconds

  m_InitGood = true;

  
}

void CAudioManager::UnInit()
{
  // close notification handle and tell DirectMusic it's closed
  CloseHandle(m_NotificationEvent);
  m_Performance->SetNotificationHandle(NULL, 0);

  // release performance
  if(m_Performance != NULL) {
    m_Performance->Stop( NULL, NULL, 0, 0 );
    m_Performance->CloseDown();
    SAFE_RELEASE( m_Performance );
  }

  SAFE_RELEASE( m_Loader ); 

  // uninitialize mixer
  m_Mixer.UnInit();

  
  m_InitGood = false;
}

CSoundPtr CAudioManager::LoadSound(const CWAVFile &wavfile)
{
  unsigned char *savedata = wavfile.Save();

  // when you load a wave from memory, DirectMusic owns the memory pointer...
  // do NOT delete!
  return(LoadSound(savedata, wavfile.GetTotalSize()));
}

CSoundPtr CAudioManager::LoadSound(unsigned char *data, int datalen)
{
  CSoundEffect *snd = new CSoundEffect(this);
  LoadSegmentFromMemory(snd, data, datalen);
  return(CSoundPtr(snd)); 
}

CSoundPtr CAudioManager::LoadSound(HMODULE hmod, char *type, WORD resID)
{
  CSoundEffect *snd = new CSoundEffect(this);
  LoadSegmentFromResource(snd, hmod, type, resID);
  return(CSoundPtr(snd));
}

CSoundPtr CAudioManager::LoadSound(std::string filename)
{
  CSoundEffect *snd = new CSoundEffect(this);
  LoadSegmentFromDisk(snd, filename);
  return(CSoundPtr(snd)); 
}

CSoundPtr CAudioManager::LoadMIDI(std::string filename)
{
  CMIDIMusic *music = new CMIDIMusic(this);
  LoadSegmentFromDisk(music, filename);
  return(CSoundPtr(music)); 
}

CSoundPtr CAudioManager::LoadMIDI(unsigned char *data, int datalen)     
{
  CMIDIMusic *music = new CMIDIMusic(this);
  LoadSegmentFromMemory(music, data, datalen);
  return(CSoundPtr(music)); 
}

CSoundPtr CAudioManager::LoadMIDI(HMODULE hmod, char *type, WORD resID)
{
  CMIDIMusic *music = new CMIDIMusic(this);
  LoadSegmentFromResource(music, hmod, type, resID);
  return(CSoundPtr(music));
}


void CAudioManager::LoadSegmentFromDisk(CDirectMusicSegment *dest, std::string filename)
{
  HRESULT hr;

  // convert filename to wide-string
  WCHAR widefilename[MAX_PATH];
  DXUtil_ConvertGenericStringToWideCch( widefilename, filename.c_str(), MAX_PATH);

  // tell loader to load this file
  hr = m_Loader->LoadObjectFromFile(
    CLSID_DirectMusicSegment,
    IID_IDirectMusicSegment8,
    widefilename,
    (void**) &dest->m_Segment);
  ThrowIfFailed(hr, "CAudioManager::LoadSound(std::string filename): LoadObjectFromFile failed.");
}

void CAudioManager::LoadSegmentFromMemory(CDirectMusicSegment *dest, unsigned char *data, int datalen)
{
  HRESULT hr;
	
  DMUS_OBJECTDESC desc;
  memset(&desc, 0, sizeof(DMUS_OBJECTDESC));

  desc.dwSize = sizeof(DMUS_OBJECTDESC);
  desc.dwValidData = DMUS_OBJ_MEMORY | DMUS_OBJ_CLASS;
  desc.guidClass = CLSID_DirectMusicSegment;
  desc.llMemLength = datalen;
  desc.pbMemData = data;

  hr = m_Loader->GetObject(&desc, IID_IDirectMusicSegment8, (void **)&dest->m_Segment);
  ThrowIfFailed(hr, "CAudioManager::LoadSound(unsigned char *data): GetObject failed.");

  dest->m_OriginalData = data;
}

void CAudioManager::LoadSegmentFromResource(CDirectMusicSegment *dest, HMODULE hmod, char *type, WORD resID)
{
  HRESULT hr;
  DMUS_OBJECTDESC ObjDesc;
 
  HRSRC hFound = FindResource(hmod, MAKEINTRESOURCE(resID), type);
  if (NULL == hFound) { 
    Throw("CAudioManager::LoadSegmentFromResource: couldn't find resource!"); 
  }
  HGLOBAL hRes = LoadResource(hmod, hFound);
 
  ObjDesc.dwSize = sizeof(DMUS_OBJECTDESC);
  ObjDesc.guidClass = CLSID_DirectMusicSegment;
  ObjDesc.dwValidData = DMUS_OBJ_CLASS | DMUS_OBJ_MEMORY;
  ObjDesc.pbMemData = (BYTE *) LockResource(hRes);
  ObjDesc.llMemLength = SizeofResource(hmod, hFound);
 
  hr = m_Loader->GetObject(&ObjDesc, IID_IDirectMusicSegment8, 
    (void**) &dest->m_Segment);

  ThrowIfFailed(hr, "CAudioManager::LoadSegmentFromResource(HMODULE hmod, WORD resID): GetObject failed.");
}

void CAudioManager::SetSearchDirectory(std::string dirname)
{
  // convert dirname to wide-string
  WCHAR widedirname[MAX_PATH];
  DXUtil_ConvertGenericStringToWideCch( widedirname, dirname.c_str(), MAX_PATH);


  HRESULT hr = m_Loader->SetSearchDirectory(CLSID_DirectMusicSegment, widedirname, true);
  ThrowIfFailed(hr, "CAudioManager::SetSearchDirectory: SetSearchDirectory() failed.");
}

void CAudioManager::SetVolume(const CVolume &vol)
{
  if (NULL == m_Performance) return;
  long dmvol = vol.ToDirectMusic();
  ThrowIfFailed(m_Performance->SetGlobalParam(GUID_PerfMasterVolume, &dmvol, sizeof(dmvol)),
    "CAudioManager::SetVolume: SetGlobalParam failed.");
}

CVolume CAudioManager::GetVolume()
{
  if (NULL == m_Performance) return(0);
  long dmvol=0;
  ThrowIfFailed(m_Performance->GetGlobalParam(GUID_PerfMasterVolume, &dmvol, sizeof(dmvol)),
    "CAudioManager::GetVolume: GetGlobalParam failed.");

  CVolume vol;
  vol.FromDirectMusic(dmvol);
  return(vol);
}

void CAudioManager::DispatchNotificationMessages()
{
  if (NULL == m_Performance) return;

  DMUS_NOTIFICATION_PMSG* pPmsg;
  while (m_NotificationHandler && m_Performance->GetNotificationPMsg(&pPmsg) == S_OK) {
    
    if (pPmsg->guidNotificationType == GUID_NOTIFICATION_MEASUREANDBEAT) {
        // if it's a beat, call OnBeat... otherwise call OnMeasure.
        if (pPmsg->dwField1 == 0) { m_NotificationHandler->OnMeasure(*pPmsg); }
        else                      { m_NotificationHandler->OnBeat(*pPmsg); }
    }
    
    m_Performance->FreePMsg((DMUS_PMSG*)pPmsg); 
  } // while
}

void CAudioManager::SetMasterTempoScaleFactor(float value)
{
  if (NULL == m_Performance) return;

  ThrowIfFailed(m_Performance->SetGlobalParam(GUID_PerfMasterTempo, &value, sizeof(value)),
    "CAudioManager::SetMasterTempo: SetGlobalParam failed.");
}

float CAudioManager::GetMasterTempoScaleFactor()
{
  if (NULL == m_Performance) return(0.0f);
  float tempo=0.0f;
  ThrowIfFailed(m_Performance->GetGlobalParam(GUID_PerfMasterTempo, &tempo, sizeof(tempo)),
    "CAudioManager::GetMasterTempo: GetGlobalParam failed.");
  return(tempo);
}



}; // namespace


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -