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

📄 audiomanager.cpp

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

#include "AudioManager.h"

#include <io.h>
#include <fcntl.h>
#include <sys/stat.h>

#include <vorbis/codec.h>
#include <vorbis/vorbisfile.h>
#include "MikMod.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

  // register MikMod drivers and init MikMod library
  MikMod_RegisterAllDrivers();
  MikMod_RegisterAllLoaders();
  MikMod_Init("");
  
  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();

  // UnInit MikMod
  CTrackedMusic::FreeAllModules();
  Player_Stop();
  MikMod_Exit();
  
  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));
}

CSoundPtr CAudioManager::LoadDynamicMusic(std::string filename)
{
  CDynamicMusic *music = new CDynamicMusic(this);
  LoadSegmentFromDisk(music, filename);
  music->LoadMotifs();
  return(CSoundPtr(music)); 
}

CSoundPtr CAudioManager::LoadDynamicMusic(unsigned char *data, int datalen)     
{
  CDynamicMusic *music = new CDynamicMusic(this);
  LoadSegmentFromMemory(music, data, datalen);
  music->LoadMotifs();
  return(CSoundPtr(music)); 
}

CSoundPtr CAudioManager::LoadDynamicMusic(HMODULE hmod, char *type, WORD resID)
{
  CDynamicMusic *music = new CDynamicMusic(this);
  LoadSegmentFromResource(music, hmod, type, resID);
  music->LoadMotifs();
  return(CSoundPtr(music));
}

void CAudioManager::SetPerformanceGrooveLevelModifier(int value)
{
  if (value > 100) value=100;
  if (value < 0) value=0;
  char v = value;
  if (NULL == m_Performance) return;
  ThrowIfFailed(m_Performance->SetGlobalParam(GUID_PerfMasterGrooveLevel, &v, sizeof(v)),
    "CAudioManager::SetMasterGrooveLEvel: SetGlobalParam failed.");
}

int CAudioManager::GetPerformanceGrooveLevelModifier()
{
  if (NULL == m_Performance) return(0);
  char groove=0;
  m_Performance->GetGlobalParam(GUID_PerfMasterGrooveLevel, &groove, sizeof(groove));
  return(groove);
}

CSoundPtr CAudioManager::LoadMP3(std::string filename)
{
  CMP3 *mp3 = new CMP3(this);
  mp3->m_Tag = GetMP3AudioTag(filename);

  CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, 
    IID_IGraphBuilder, (void **)&mp3->m_GraphBuilder);

  mp3->m_GraphBuilder->QueryInterface(IID_IMediaControl, (void **)&mp3->m_MediaControl);
  mp3->m_GraphBuilder->QueryInterface(IID_IMediaEventEx, (void **)&mp3->m_MediaEventEx);

  WCHAR widefilename[MAX_PATH];
  DXUtil_ConvertGenericStringToWideCch( widefilename, filename.c_str(), MAX_PATH);

  mp3->m_GraphBuilder->RenderFile(widefilename, NULL);
  
  return(CSoundPtr(mp3));
}

CMP3AudioTag CAudioManager::GetMP3AudioTag(std::string filename)
{
  CMP3AudioTag tag;
  tag.Read(filename);
  return(tag);
}

CSoundPtr CAudioManager::LoadOggVorbis(std::string filename)
{
  std::vector<unsigned char> pcmdata;

  // this code is based on vorbisfile_example.c, included in the ogg distribution.

  char pcmout[4096]; // ogg decoding buffer
  OggVorbis_File vf;
  int eof=0;
  int current_section=0;

  FILE *f = fopen(filename.c_str(), "rb");
  if (f == NULL) { Throw("CAudioManager::LoadOggVorbis: could not open file."); }

  if(ov_open(f, &vf, NULL, 0) < 0) {
    Throw("CAudioManager::LoadOggVorbis: Input does not appear to be an Ogg bitstream.");
  }

  /* Throw the comments plus a few lines about the bitstream we're
     decoding */
  vorbis_info *vi=ov_info(&vf,-1);

⌨️ 快捷键说明

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