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

📄 core_sound.cpp

📁 3D游戏引擎 Programming Role-Playing Games with DirectX, 2nd Edition by Jim Adams
💻 CPP
📖 第 1 页 / 共 3 页
字号:
{
  return m_pDMSegment;
}

BOOL cMusicChannel::Create(cSound *Sound)
{
  Free();

  // Make sure all objects there
  if((m_Sound = Sound) == NULL)
    return FALSE;
  if(m_Sound->GetPerformanceCOM() == NULL)
    return FALSE;
  if(m_Sound->GetLoaderCOM() == NULL)
    return FALSE;

  return TRUE;
}

BOOL cMusicChannel::Load(char *Filename)
{
  DMUS_OBJECTDESC dmod;

  Free();

  if(m_Sound == NULL)
    return FALSE;
  if(m_Sound->GetPerformanceCOM() == NULL)
    return FALSE;
  if(m_Sound->GetLoaderCOM() == NULL)
    return FALSE;

  // Get the object
  ZeroMemory(&dmod, sizeof(DMUS_OBJECTDESC));
  dmod.dwSize = sizeof(DMUS_OBJECTDESC);
  dmod.guidClass = CLSID_DirectMusicSegment;
  dmod.dwValidData = DMUS_OBJ_CLASS | DMUS_OBJ_FILENAME | DMUS_OBJ_FULLPATH;
  mbstowcs(dmod.wszFileName, Filename, MAX_PATH);
  if(FAILED(m_Sound->GetLoaderCOM()->GetObject(&dmod, IID_IDirectMusicSegment8, (LPVOID*)&m_pDMSegment)))
    return FALSE;

  // Setup MIDI playing
  if(strstr(Filename, ".mid") != NULL) {
    if(FAILED(m_pDMSegment->SetParam(GUID_StandardMIDIFile, 0xFFFFFFFF, 0, 0, NULL)))
      return FALSE;
  }

  // Download the band
  if(FAILED(m_pDMSegment->Download(m_Sound->GetPerformanceCOM())))
    return FALSE;

  return TRUE;
}

BOOL cMusicChannel::Free()
{
  Stop();

  if(m_Sound != NULL) {
    // unload instrument data
    if(m_pDMSegment != NULL) {
      if(m_Sound->GetPerformanceCOM() != NULL) {
        if(FAILED(m_pDMSegment->Unload(m_Sound->GetPerformanceCOM())))
          return FALSE;
      }

      // free loader data
      if(m_Sound->GetLoaderCOM() != NULL) {
        if(FAILED(m_Sound->GetLoaderCOM()->ReleaseObjectByUnknown(m_pDMSegment)))
          return FALSE;
      }
    }
  }

  // release the segment
  ReleaseCOM(m_pDMSegment);
  
  return TRUE;
}

BOOL cMusicChannel::SetDLS(cDLS *DLS)
{
  if(DLS == NULL)
    return FALSE;
  if(DLS->GetCollectionCOM() == NULL)
    return FALSE;
  if(m_Sound == NULL)
    return FALSE;
  if(m_Sound->GetPerformanceCOM() == NULL)
    return FALSE;
  if(m_pDMSegment == NULL)
    return FALSE;

  // Connect to the collection
  if(FAILED(m_pDMSegment->SetParam(GUID_ConnectToDLSCollection, 0xFFFFFFFF, 0, 0, (void*)DLS->GetCollectionCOM())))
    return FALSE;

  // unload and then re-download new instruments
  if(FAILED(m_pDMSegment->Unload(m_Sound->GetPerformanceCOM())))
    return FALSE;
  if(FAILED(m_pDMSegment->Download(m_Sound->GetPerformanceCOM())))
    return FALSE;
  
  return TRUE;
}

BOOL cMusicChannel::Play(long VolumePercent, long Loop)
{
  Stop();

  // Return if not setup correctly
  if(m_Sound == NULL)
    return FALSE;
  if(m_Sound->GetPerformanceCOM() == NULL)
    return FALSE;
  if(m_pDMSegment == NULL)
    return FALSE;

  // Set the number of loops
  if(!Loop)
    m_pDMSegment->SetRepeats(DMUS_SEG_REPEAT_INFINITE);
  else
    m_pDMSegment->SetRepeats(Loop-1);

  // Set the playback volume
  SetVolume(VolumePercent);

  // Play on default audio path
  if(FAILED(m_Sound->GetPerformanceCOM()->PlaySegmentEx(
               m_pDMSegment, NULL, NULL, 
               0, 0, NULL, NULL, NULL)))
    return FALSE;

  return TRUE;
}

BOOL cMusicChannel::Stop()
{
  // Return if not setup correctly
  if(m_Sound == NULL)
    return FALSE;
  if(m_Sound->GetPerformanceCOM() == NULL)
    return FALSE;
  if(m_pDMSegment == NULL)
    return FALSE;

  // Stop playback 
  if(FAILED(m_Sound->GetPerformanceCOM()->Stop(m_pDMSegment, NULL, 0, 0)))
    return FALSE;

  return TRUE;
}

long cMusicChannel::GetVolume()
{
  return m_Volume;
}

BOOL cMusicChannel::SetVolume(long Percent)
{
  IDirectMusicAudioPath8 *pDMAudioPath;
  long Volume;

  if(m_Sound == NULL)
    return FALSE;
  if(m_Sound->GetPerformanceCOM() == NULL)
    return FALSE;

  if(FAILED(m_Sound->GetPerformanceCOM()->GetDefaultAudioPath(&pDMAudioPath)))
    return FALSE;

  // calculate a usable volume level
  if(!Percent)
    Volume = -9600;
  else
    Volume = (long)(-32.0 * (100.0 - (float)(Percent % 101)));

  if(FAILED(pDMAudioPath->SetVolume(Volume,0))) {
    pDMAudioPath->Release();
    return FALSE;
  }
  pDMAudioPath->Release();

  m_Volume = Percent % 101;

  return TRUE;
}

BOOL cMusicChannel::SetTempo(long Percent)
{
  float Tempo;

  if(m_Sound == NULL)
    return FALSE;
  if(m_Sound->GetPerformanceCOM() == NULL)
    return FALSE;

  // calculate tempo setting based on percentage
  Tempo = (float)Percent / 100.0f;

  // set master performance tempo
  if(FAILED(m_Sound->GetPerformanceCOM()->SetGlobalParam(GUID_PerfMasterTempo, (void*)&Tempo, sizeof(float))))
    return FALSE;

  return TRUE;
}

BOOL cMusicChannel::IsPlaying()
{
  // Return if not setup correctly
  if(m_Sound == NULL)
    return FALSE;
  if(m_Sound->GetPerformanceCOM() == NULL)
    return FALSE;
  if(m_pDMSegment == NULL)
    return FALSE;

  if(m_Sound->GetPerformanceCOM()->IsPlaying(m_pDMSegment, NULL) == S_OK)
    return TRUE;

  return FALSE;
}

cDLS::cDLS()
{
  m_Sound = NULL;
  m_pDMCollection = NULL;
}

cDLS::~cDLS()
{
  Free();
}

BOOL cDLS::Create(cSound *Sound)
{
  Free();

  if((m_Sound = Sound) == NULL)
    return FALSE;
  if(m_Sound->GetLoaderCOM() == NULL)
    return FALSE;

  return TRUE;
}

BOOL cDLS::Load(char *Filename)
{
  DMUS_OBJECTDESC dmod;

  Free();

  if(m_Sound == NULL)
    return FALSE;
  if(m_Sound->GetLoaderCOM() == NULL)
    return FALSE;

  ZeroMemory(&dmod, sizeof(DMUS_OBJECTDESC));
  dmod.dwSize = sizeof(DMUS_OBJECTDESC);
  dmod.guidClass = CLSID_DirectMusicCollection;

  if(Filename == NULL) {
    // Get the default collection
    dmod.guidObject = GUID_DefaultGMCollection;
    dmod.dwValidData = DMUS_OBJ_CLASS | DMUS_OBJ_OBJECT;
  } else {
    // Get the collection object
    dmod.dwValidData = DMUS_OBJ_CLASS | DMUS_OBJ_FILENAME | DMUS_OBJ_FULLPATH;
    mbstowcs(dmod.wszFileName, Filename, MAX_PATH);
  }

  if(FAILED(m_Sound->GetLoaderCOM()->GetObject(&dmod, IID_IDirectMusicCollection8, (LPVOID*)&m_pDMCollection)))
    return FALSE;

  return TRUE;
}

BOOL cDLS::Free()
{
  if(m_Sound == NULL)
    return FALSE;
  if(m_Sound->GetLoaderCOM() == NULL)
    return FALSE;

  if(m_pDMCollection != NULL) {
    if(FAILED(m_Sound->GetLoaderCOM()->ReleaseObjectByUnknown(m_pDMCollection)))
      return FALSE;
  }
  ReleaseCOM(m_pDMCollection);

  return TRUE;
}

IDirectMusicCollection8 *cDLS::GetCollectionCOM()
{
  return m_pDMCollection;
}

long cDLS::GetNumPatches()
{
  HRESULT hr;
  DWORD   dwPatch;
  long    i;

  hr = S_OK;
  for(i=0; hr == S_OK; i++) {
    hr = m_pDMCollection->EnumInstrument(i, &dwPatch, NULL, 0);
    if(hr != S_OK)
      break;
  }
  return i;
}

long cDLS::GetPatch(long Index)
{
  DWORD dwPatch;

  if(m_pDMCollection == NULL)
    return -1;

  if(FAILED(m_pDMCollection->EnumInstrument(Index, &dwPatch, NULL, 0)))
    return -1;

  return (long)dwPatch;
}

BOOL cDLS::Exists(long Patch)
{
  IDirectMusicInstrument8 *pDMInstrument;

  if(m_pDMCollection == NULL)
    return FALSE;

  if(FAILED(m_pDMCollection->GetInstrument(Patch, &pDMInstrument)))
    return FALSE;
  pDMInstrument->Release();

  return TRUE;
}

IGraphBuilder  *m_pDSGraphBuilder;
IMediaControl  *m_pDSMediaControl;
IMediaEvent    *m_pDSMediaEvent;

cMP3::cMP3()
{
  m_pDSGraphBuilder = NULL;
  m_pDSMediaControl = NULL;
  m_pDSMediaEvent   = NULL;
}

cMP3::~cMP3()
{
  Shutdown();
}

BOOL cMP3::Init()
{
  Shutdown();  // Shutdown prior initialized system

  // Initialize COM
  CoInitialize(NULL);

  // Create graph builder object and media controls
  if(FAILED(CoCreateInstance(CLSID_FilterGraph, NULL,          \
                             CLSCTX_INPROC_SERVER,             \
                             IID_IGraphBuilder,                \
                             (void**)&m_pDSGraphBuilder)))
    return FALSE;

  m_pDSGraphBuilder->QueryInterface(IID_IMediaControl,         \
                               (void**)&m_pDSMediaControl); 
  m_pDSGraphBuilder->QueryInterface(IID_IMediaEvent,           \
                               (void**)&m_pDSMediaEvent);

  return TRUE;
}

BOOL cMP3::Shutdown()
{
  ReleaseCOM(m_pDSMediaEvent);
  ReleaseCOM(m_pDSMediaControl);
  ReleaseCOM(m_pDSGraphBuilder);

  CoUninitialize();
  
  return TRUE;
}

BOOL cMP3::Render(char *Filename)
{
  // Error checking
  if(m_pDSGraphBuilder == NULL || m_pDSMediaControl == NULL)
    return FALSE;

  // Stop the current song
  m_pDSMediaControl->Stop();

  // Convert filename to wide-character string
  WCHAR wFilename[MAX_PATH];
  mbstowcs(wFilename, Filename, MAX_PATH);

  // Render the file
  if(FAILED(m_pDSGraphBuilder->RenderFile(wFilename, NULL)))
    return FALSE;

  // Return success
  return TRUE;
}

BOOL cMP3::Play()
{
  // Error checking
  if(m_pDSMediaControl == NULL)
    return FALSE;

  // Try to play media
  if(FAILED(m_pDSMediaControl->Run()))
    return FALSE;

  return TRUE;
}

BOOL cMP3::Stop()
{
  // Error checking
  if(m_pDSMediaControl == NULL)
    return FALSE;

  // Try to stop media
  if(FAILED(m_pDSMediaControl->Stop()))
    return FALSE;

  return TRUE;
}

BOOL cMP3::Pause()
{
  // Error checking
  if(m_pDSMediaControl == NULL)
    return FALSE;

  // Try to pause media
  if(FAILED(m_pDSMediaControl->Pause()))
    return FALSE;

  return TRUE;
}

BOOL cMP3::Playing()
{
  // Error checking
  if(m_pDSMediaEvent == NULL)
    return FALSE;

  // Get event and handle it
  long Event, Param1, Param2;
  m_pDSMediaEvent->GetEvent(&Event, &Param1, &Param2, 1);
  if(Event == EC_COMPLETE) {
    m_pDSMediaEvent->FreeEventParams(Event, Param1, Param2);
    return TRUE;
  }
  m_pDSMediaEvent->FreeEventParams(Event, Param1, Param2);
 
  return FALSE;
}

⌨️ 快捷键说明

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