📄 dmutil.cpp
字号:
//-----------------------------------------------------------------------------
// File: DMUtil.cpp
//
// Desc: DirectMusic framework classes for playing DirectMusic segments and
// DirectMusic scripts. Feel free to use this class as a starting point
// for adding extra functionality.
//
// Copyright (c) Microsoft Corp. All rights reserved.
//-----------------------------------------------------------------------------
#define STRICT
#include <dmusicc.h>
#include <dmusici.h>
#include <dsound.h>
#include <dxerr9.h>
#include "DMUtil.h"
#include "DXUtil.h"
//-----------------------------------------------------------------------------
// Name: CMusicManager::CMusicManager()
// Desc: Constructs the class
//-----------------------------------------------------------------------------
CMusicManager::CMusicManager()
{
m_pLoader = NULL;
m_pPerformance = NULL;
m_pDSListener = NULL;
// Initialize COM
HRESULT hr = CoInitialize(NULL);
m_bCleanupCOM = SUCCEEDED(hr);
}
//-----------------------------------------------------------------------------
// Name: CMusicManager::~CMusicManager()
// Desc: Destroys the class
//-----------------------------------------------------------------------------
CMusicManager::~CMusicManager()
{
SAFE_RELEASE( m_pLoader );
SAFE_RELEASE( m_pDSListener );
if( m_pPerformance )
{
// If there is any music playing, stop it.
m_pPerformance->Stop( NULL, NULL, 0, 0 );
m_pPerformance->CloseDown();
SAFE_RELEASE( m_pPerformance );
}
if( m_bCleanupCOM )
CoUninitialize();
}
//-----------------------------------------------------------------------------
// Name: CMusicManager::Initialize()
// Desc: Inits DirectMusic using a standard audio path
//-----------------------------------------------------------------------------
HRESULT CMusicManager::Initialize( HWND hWnd, DWORD dwPChannels, DWORD dwDefaultPathType, LPDIRECTSOUND pDS )
{
HRESULT hr;
IDirectSound** ppDirectSound;
if( pDS )
ppDirectSound = &pDS;
else
ppDirectSound = NULL;
// Create loader object
if( FAILED( hr = CoCreateInstance( CLSID_DirectMusicLoader, NULL, CLSCTX_INPROC,
IID_IDirectMusicLoader8, (void**)&m_pLoader ) ) )
return DXTRACE_ERR_MSGBOX( TEXT("CoCreateInstance"), hr );
// Create performance object
if( FAILED( hr = CoCreateInstance( CLSID_DirectMusicPerformance, NULL, CLSCTX_INPROC,
IID_IDirectMusicPerformance8, (void**)&m_pPerformance ) ) )
return DXTRACE_ERR_MSGBOX( TEXT("CoCreateInstance"), hr );
// Initialize the performance with the standard audio path.
// This initializes both DirectMusic and DirectSound and
// sets up the synthesizer. Typcially its easist to use an
// audio path for playing music and sound effects.
if( FAILED( hr = m_pPerformance->InitAudio( NULL, ppDirectSound, hWnd, dwDefaultPathType,
dwPChannels, DMUS_AUDIOF_ALL, NULL ) ) )
{
if( hr == DSERR_NODRIVER )
{
DXTRACE( TEXT("Warning: No sound card found\n") );
return hr;
}
return DXTRACE_ERR_MSGBOX( TEXT("InitAudio"), hr );
}
// Get the listener from the in the default audio path.
IDirectMusicAudioPath8* pAudioPath = GetDefaultAudioPath();
if( pAudioPath ) // might be NULL if dwDefaultPathType == 0
{
if( SUCCEEDED( hr = pAudioPath->GetObjectInPath( 0, DMUS_PATH_PRIMARY_BUFFER, 0,
GUID_NULL, 0, IID_IDirectSound3DListener,
(LPVOID*) &m_pDSListener ) ) )
{
// Get listener parameters
m_dsListenerParams.dwSize = sizeof(DS3DLISTENER);
m_pDSListener->GetAllParameters( &m_dsListenerParams );
}
}
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: CMusicManager::SetSearchDirectory()
// Desc: Sets the search directory. If not called, the current working
// directory is used to load content.
//-----------------------------------------------------------------------------
HRESULT CMusicManager::SetSearchDirectory( const TCHAR* strMediaPath )
{
if( NULL == m_pLoader )
return E_UNEXPECTED;
if( NULL == strMediaPath )
return E_INVALIDARG;
// DMusic only takes wide strings
WCHAR wstrMediaPath[MAX_PATH];
DXUtil_ConvertGenericStringToWideCch( wstrMediaPath, strMediaPath, sizeof(wstrMediaPath)/sizeof(TCHAR) );
return m_pLoader->SetSearchDirectory( GUID_DirectMusicAllTypes,
wstrMediaPath, FALSE );
}
//-----------------------------------------------------------------------------
// Name: CMusicManager::GetDefaultAudioPath()
// Desc:
//-----------------------------------------------------------------------------
IDirectMusicAudioPath8* CMusicManager::GetDefaultAudioPath()
{
IDirectMusicAudioPath8* pAudioPath = NULL;
if( NULL == m_pPerformance )
return NULL;
m_pPerformance->GetDefaultAudioPath( &pAudioPath );
return pAudioPath;
}
//-----------------------------------------------------------------------------
// Name: CMusicManager::CollectGarbage()
// Desc: Tells the loader to cleanup any garbage from previously
// released objects.
//-----------------------------------------------------------------------------
VOID CMusicManager::CollectGarbage()
{
if( m_pLoader )
m_pLoader->CollectGarbage();
}
//-----------------------------------------------------------------------------
// Name: CMusicManager::StopAll()
// Desc: Stops all segments. Also simply calling Stop() on the segment won't
// stop any MIDI sustain pedals, but calling StopAll() will.
//-----------------------------------------------------------------------------
VOID CMusicManager::StopAll()
{
if( m_pPerformance )
m_pPerformance->Stop( NULL, NULL, 0, 0 );
}
//-----------------------------------------------------------------------------
// Name: CMusicManager::CreateSegmentFromFile()
// Desc:
//-----------------------------------------------------------------------------
HRESULT CMusicManager::CreateSegmentFromFile( CMusicSegment** ppSegment,
LPCTSTR strFileName,
BOOL bDownloadNow,
BOOL bIsMidiFile )
{
HRESULT hr;
IDirectMusicSegment8* pSegment = NULL;
// DMusic only takes wide strings
WCHAR wstrFileName[MAX_PATH];
DXUtil_ConvertGenericStringToWideCch( wstrFileName, strFileName, sizeof(wstrFileName)/sizeof(TCHAR) );
if ( FAILED( hr = m_pLoader->LoadObjectFromFile( CLSID_DirectMusicSegment,
IID_IDirectMusicSegment8,
wstrFileName,
(LPVOID*) &pSegment ) ) )
{
if( hr == DMUS_E_LOADER_FAILEDOPEN )
return hr;
return DXTRACE_ERR_MSGBOX( TEXT("LoadObjectFromFile"), hr );
}
*ppSegment = new CMusicSegment( m_pPerformance, m_pLoader, pSegment );
if (!*ppSegment)
return E_OUTOFMEMORY;
if( bIsMidiFile )
{
if( FAILED( hr = pSegment->SetParam( GUID_StandardMIDIFile,
0xFFFFFFFF, 0, 0, NULL ) ) )
return DXTRACE_ERR_MSGBOX( TEXT("SetParam"), hr );
}
if( bDownloadNow )
{
if( FAILED( hr = (*ppSegment)->Download() ) )
return DXTRACE_ERR_MSGBOX( TEXT("Download"), hr );
}
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: CMusicManager::CreateSegmentFromResource()
// Desc:
//-----------------------------------------------------------------------------
HRESULT CMusicManager::CreateSegmentFromResource( CMusicSegment** ppSegment,
LPCTSTR strResource,
LPCTSTR strResourceType,
BOOL bDownloadNow,
BOOL bIsMidiFile )
{
HRESULT hr;
IDirectMusicSegment8* pSegment = NULL;
HRSRC hres = NULL;
void* pMem = NULL;
DWORD dwSize = 0;
DMUS_OBJECTDESC objdesc;
// Find the resource
hres = FindResource( NULL,strResource,strResourceType );
if( NULL == hres )
return E_FAIL;
// Load the resource
pMem = (void*)LoadResource( NULL, hres );
if( NULL == pMem )
return E_FAIL;
// Store the size of the resource
dwSize = SizeofResource( NULL, hres );
// Set up our object description
ZeroMemory(&objdesc,sizeof(DMUS_OBJECTDESC));
objdesc.dwSize = sizeof(DMUS_OBJECTDESC);
objdesc.dwValidData = DMUS_OBJ_MEMORY | DMUS_OBJ_CLASS;
objdesc.guidClass = CLSID_DirectMusicSegment;
objdesc.llMemLength =(LONGLONG)dwSize;
objdesc.pbMemData = (BYTE*)pMem;
if (FAILED ( hr = m_pLoader->GetObject( &objdesc,
IID_IDirectMusicSegment8,
(void**)&pSegment ) ) )
{
if( hr == DMUS_E_LOADER_FAILEDOPEN )
return hr;
return DXTRACE_ERR_MSGBOX( TEXT("LoadObjectFromFile"), hr );
}
*ppSegment = new CMusicSegment( m_pPerformance, m_pLoader, pSegment );
if( NULL == *ppSegment )
return E_OUTOFMEMORY;
if( bIsMidiFile )
{
// Do this to make sure that the default General MIDI set
// is connected appropriately to the MIDI file and
// all instruments sound correct.
if( FAILED( hr = pSegment->SetParam( GUID_StandardMIDIFile,
0xFFFFFFFF, 0, 0, NULL ) ) )
return DXTRACE_ERR_MSGBOX( TEXT("SetParam"), hr );
}
if( bDownloadNow )
{
// The segment needs to be download first before playing.
// However, some apps may want to wait before calling this
// to because the download allocates memory for the
// instruments. The more instruments currently downloaded,
// the more memory is in use by the synthesizer.
if( FAILED( hr = (*ppSegment)->Download() ) )
return DXTRACE_ERR_MSGBOX( TEXT("Download"), hr );
}
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: CMusicManager::Create3DSegmentFromFile()
// Desc:
//-----------------------------------------------------------------------------
HRESULT CMusicManager::Create3DSegmentFromFile( C3DMusicSegment** pp3DMusicSegment,
LPCTSTR strFileName,
BOOL bDownloadNow,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -