|
|
/****************************************************************************
* * File: testmus.cpp * Project: DxDiag (DirectX Diagnostic Tool) * Author: Mike Anderson (manders@microsoft.com) * Purpose: Test DMusic functionality on this machine * * (C) Copyright 1998 Microsoft Corp. All rights reserved. * ****************************************************************************/
#include <Windows.h>
#include <multimon.h>
#include <dmusicc.h>
#include <dmusici.h>
#include "reginfo.h"
#include "sysinfo.h"
#include "dispinfo.h"
#include "musinfo.h"
#include "testmus.h"
#include "resource.h"
#ifndef ReleasePpo
#define ReleasePpo(ppo) \
if (*(ppo) != NULL) \ { \ (*(ppo))->Release(); \ *(ppo) = NULL; \ } \ else (VOID)0 #endif
enum TESTID { TESTID_COINITIALIZE = 1, TESTID_CREATEDMLOADER, TESTID_CREATEDMPERF, TESTID_INITPERF, TESTID_CREATEPORT, TESTID_ACTIVATEPORT, TESTID_SETAUTODOWNLOAD, TESTID_ADDPORT, TESTID_ASSIGNPCHANNELBLOCK, TESTID_SPEWRESOURCETOFILE, TESTID_SETSEARCHDIRECTORY, TESTID_LOADERGETOBJECT, TESTID_PLAYSEGMENT, };
BOOL BTranslateError(HRESULT hr, TCHAR* psz, BOOL bEnglish = FALSE); // from main.cpp (yuck)
static HRESULT SpewResourceToFile(TCHAR* pszResType, LONG idRes, TCHAR* pszFileName); static HRESULT LoadSegment( BOOL fUseCWD ); static VOID DeleteTempFile(TCHAR* pszFileName);
/****************************************************************************
* * TestMusic * ****************************************************************************/ VOID TestMusic(HWND hwndMain, MusicInfo* pMusicInfo) { HRESULT hr; MusicPort* pMusicPort = NULL; IDirectMusicLoader* pLoader = NULL; IDirectMusicPerformance* pPerformance = NULL; IDirectMusic* pdm = NULL; IDirectMusicPort* pPort = NULL; IDirectMusicSegment* pSegment = NULL; BOOL bComInitialized = FALSE; TCHAR szFmt[300]; TCHAR sz[300]; TCHAR szTitle[100];
if (pMusicInfo == NULL) return;
// Determine pMusicPort of port to test:
for (pMusicPort = pMusicInfo->m_pMusicPortFirst; pMusicPort != NULL; pMusicPort = pMusicPort->m_pMusicPortNext) { if (pMusicPort->m_guid == pMusicInfo->m_guidMusicPortTest) break; } if (pMusicPort == NULL) return;
LoadString(NULL, IDS_APPFULLNAME, szTitle, 100); LoadString(NULL, IDS_STARTDMUSICTEST, szFmt, 300); wsprintf(sz, szFmt, pMusicPort->m_szDescription); if (IDNO == MessageBox(hwndMain, sz, szTitle, MB_YESNO)) return;
// Remove info from any previous test:
ZeroMemory(&pMusicInfo->m_testResult, sizeof(TestResult));
pMusicInfo->m_testResult.m_bStarted = TRUE;
// Initialize COM
if (FAILED(hr = CoInitialize(NULL))) { pMusicInfo->m_testResult.m_iStepThatFailed = TESTID_COINITIALIZE; pMusicInfo->m_testResult.m_hr = hr; goto LEnd; } bComInitialized = TRUE;
// Create performance object
if (FAILED(hr = CoCreateInstance(CLSID_DirectMusicPerformance, NULL, CLSCTX_INPROC, IID_IDirectMusicPerformance, (VOID**)&pPerformance))) { pMusicInfo->m_testResult.m_iStepThatFailed = TESTID_CREATEDMPERF; pMusicInfo->m_testResult.m_hr = hr; goto LEnd; }
// Initialize the performance -- also creates DirectMusic object
if (FAILED(hr = pPerformance->Init(&pdm, NULL, hwndMain))) { pMusicInfo->m_testResult.m_iStepThatFailed = TESTID_INITPERF; pMusicInfo->m_testResult.m_hr = hr; goto LEnd; }
// Create a port using the user-specified GUID
DMUS_PORTPARAMS portParams; ZeroMemory(&portParams, sizeof(portParams)); portParams.dwSize = sizeof(portParams); portParams.dwValidParams = DMUS_PORTPARAMS_EFFECTS | DMUS_PORTPARAMS_CHANNELGROUPS | DMUS_PORTPARAMS_AUDIOCHANNELS; portParams.dwEffectFlags = DMUS_EFFECT_REVERB; portParams.dwChannelGroups = pMusicPort->m_dwMaxChannelGroups; portParams.dwAudioChannels = pMusicPort->m_dwMaxAudioChannels; if (FAILED(hr = pdm->CreatePort(pMusicPort->m_guid, &portParams, &pPort, NULL))) { pMusicInfo->m_testResult.m_iStepThatFailed = TESTID_CREATEPORT; pMusicInfo->m_testResult.m_hr = hr; goto LEnd; }
// Activate the port
if (FAILED(hr = pPort->Activate(TRUE))) { // Bug 21677: catch case where user has no sound card
if (hr == DSERR_NODRIVER && !pMusicPort->m_bExternal) { LoadString(NULL, IDS_NOSOUNDDRIVER, sz, 300); MessageBox(hwndMain, sz, szTitle, MB_OK); } pMusicInfo->m_testResult.m_iStepThatFailed = TESTID_ACTIVATEPORT; pMusicInfo->m_testResult.m_hr = hr; goto LEnd; }
// Set autodownloading to be on
BOOL fAutoDownload; fAutoDownload = TRUE; if (FAILED(hr = pPerformance->SetGlobalParam(GUID_PerfAutoDownload, &fAutoDownload, sizeof(BOOL)))) { pMusicInfo->m_testResult.m_iStepThatFailed = TESTID_SETAUTODOWNLOAD; pMusicInfo->m_testResult.m_hr = hr; goto LEnd; }
// Add the port to the performance
if (FAILED(hr = pPerformance->AddPort(pPort))) { pMusicInfo->m_testResult.m_iStepThatFailed = TESTID_ADDPORT; pMusicInfo->m_testResult.m_hr = hr; goto LEnd; }
if (FAILED(hr = pPerformance->AssignPChannelBlock(0, pPort, 1))) { pMusicInfo->m_testResult.m_iStepThatFailed = TESTID_ASSIGNPCHANNELBLOCK; pMusicInfo->m_testResult.m_hr = hr; goto LEnd; }
if (FAILED(hr = SpewResourceToFile(TEXT("SGMT"), IDR_TSTSGMT, TEXT("Edge.sgt")))) { pMusicInfo->m_testResult.m_iStepThatFailed = TESTID_SPEWRESOURCETOFILE; pMusicInfo->m_testResult.m_hr = hr; goto LEnd; }
if (FAILED(hr = SpewResourceToFile(TEXT("STYL"), IDR_TSTSTYL, TEXT("Edge.sty")))) { pMusicInfo->m_testResult.m_iStepThatFailed = TESTID_SPEWRESOURCETOFILE; pMusicInfo->m_testResult.m_hr = hr; goto LEnd; }
// Create loader object
if (FAILED(hr = CoCreateInstance(CLSID_DirectMusicLoader, NULL, CLSCTX_INPROC, IID_IDirectMusicLoader, (VOID**)&pLoader))) { pMusicInfo->m_testResult.m_iStepThatFailed = TESTID_CREATEDMLOADER; pMusicInfo->m_testResult.m_hr = hr; goto LEnd; }
// Set search path to temp dir to find segment and style:
WCHAR wszDir[MAX_PATH]; TCHAR szTempPath[MAX_PATH]; GetTempPath(MAX_PATH, szTempPath); szTempPath[lstrlen(szTempPath) - 1] = '\0'; #ifdef UNICODE
lstrcpy(wszDir, szTempPath); #else
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, szTempPath, -1, wszDir, MAX_PATH); #endif
if (FAILED(hr = pLoader->SetSearchDirectory(GUID_DirectMusicAllTypes, wszDir, FALSE))) { pMusicInfo->m_testResult.m_iStepThatFailed = TESTID_SETSEARCHDIRECTORY; pMusicInfo->m_testResult.m_hr = hr; goto LEnd; }
// Load the segment
// now load the segment file.
// sections load as type Segment, as do MIDI files, for example.
DMUS_OBJECTDESC objDesc; // Object descriptor for pLoader->GetObject()
objDesc.guidClass = CLSID_DirectMusicSegment; objDesc.dwSize = sizeof(DMUS_OBJECTDESC); wcscpy(objDesc.wszFileName, L"edge.sgt"); objDesc.dwValidData = DMUS_OBJ_CLASS | DMUS_OBJ_FILENAME; if (FAILED(hr = pLoader->GetObject(&objDesc, IID_IDirectMusicSegment, (VOID**)&pSegment))) { pMusicInfo->m_testResult.m_iStepThatFailed = TESTID_LOADERGETOBJECT; pMusicInfo->m_testResult.m_hr = hr; goto LEnd; }
// Play the segment and wait. The DMUS_SEGF_BEAT indicates to play on the
// next beat if there is a segment currently playing. The first 0 indicates
// to play (on the next beat from) now.
// The final NULL means do not return an IDirectMusicSegmentState* in
// the last parameter.
if (FAILED(hr = pPerformance->PlaySegment(pSegment, DMUS_SEGF_BEAT, 0, NULL))) { pMusicInfo->m_testResult.m_iStepThatFailed = TESTID_PLAYSEGMENT; pMusicInfo->m_testResult.m_hr = hr; goto LEnd; }
if (pMusicPort->m_bExternal) LoadString(NULL, IDS_EXTERNALMUSICPLAYING, sz, 300); else LoadString(NULL, IDS_MUSICPLAYING, sz, 300); MessageBox(hwndMain, sz, szTitle, MB_OK);
pPerformance->Stop(pSegment, NULL, 0, 0);
LEnd: DeleteTempFile(TEXT("Edge.sgt")); DeleteTempFile(TEXT("Edge.sty"));
ReleasePpo(&pdm); ReleasePpo(&pPort); if (pPerformance != NULL) pPerformance->CloseDown(); ReleasePpo(&pPerformance); ReleasePpo(&pLoader);
if (bComInitialized) { // Release COM
CoUninitialize(); }
if (pMusicInfo->m_testResult.m_iStepThatFailed == 0) { LoadString(NULL, IDS_TESTSSUCCESSFUL, sz, 300); lstrcpy(pMusicInfo->m_testResult.m_szDescription, sz);
LoadString(NULL, IDS_TESTSSUCCESSFUL_ENGLISH, sz, 300); lstrcpy(pMusicInfo->m_testResult.m_szDescriptionEnglish, sz); } else { TCHAR szDesc[200]; TCHAR szError[200]; if (0 == LoadString(NULL, IDS_FIRSTDMUSICTESTERROR + pMusicInfo->m_testResult.m_iStepThatFailed - 1, szDesc, 200)) { LoadString(NULL, IDS_UNKNOWNERROR, sz, 300); lstrcpy(szDesc, sz); } LoadString(NULL, IDS_FAILUREFMT, sz, 300); BTranslateError(pMusicInfo->m_testResult.m_hr, szError); wsprintf(pMusicInfo->m_testResult.m_szDescription, sz, pMusicInfo->m_testResult.m_iStepThatFailed, szDesc, pMusicInfo->m_testResult.m_hr, szError);
// Nonlocalized version:
if (0 == LoadString(NULL, IDS_FIRSTDMUSICTESTERROR_ENGLISH + pMusicInfo->m_testResult.m_iStepThatFailed - 1, szDesc, 200)) { LoadString(NULL, IDS_UNKNOWNERROR_ENGLISH, sz, 300); lstrcpy(szDesc, sz); } LoadString(NULL, IDS_FAILUREFMT_ENGLISH, sz, 300); BTranslateError(pMusicInfo->m_testResult.m_hr, szError, TRUE); wsprintf(pMusicInfo->m_testResult.m_szDescriptionEnglish, sz, pMusicInfo->m_testResult.m_iStepThatFailed, szDesc, pMusicInfo->m_testResult.m_hr, szError); } }
/****************************************************************************
* * SpewResourceToFile * ****************************************************************************/ HRESULT SpewResourceToFile(TCHAR* pszResType, LONG idRes, TCHAR* pszFileName) { TCHAR szTempPath[MAX_PATH]; HRSRC hResInfo = NULL; HGLOBAL hResData = NULL; BYTE* pbData = NULL; HANDLE hfile; DWORD numBytes; DWORD numBytesWritten;
GetTempPath(MAX_PATH, szTempPath); lstrcat(szTempPath, pszFileName); if (NULL == (hResInfo = FindResource(NULL, MAKEINTRESOURCE(idRes), pszResType))) return E_FAIL; numBytes = SizeofResource(NULL, hResInfo); if (NULL == (hResData = LoadResource(NULL, hResInfo))) return E_FAIL; if (NULL == (pbData = (BYTE*)LockResource(hResData))) return E_FAIL;
hfile = CreateFile(szTempPath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_TEMPORARY, NULL); if (hfile == INVALID_HANDLE_VALUE) return E_FAIL; WriteFile(hfile, pbData, numBytes, &numBytesWritten, NULL); CloseHandle(hfile);
return S_OK; }
/****************************************************************************
* * DeleteTempFile * ****************************************************************************/ VOID DeleteTempFile(TCHAR* pszFileName) { TCHAR szTempPath[MAX_PATH];
GetTempPath(MAX_PATH, szTempPath); lstrcat(szTempPath, pszFileName); DeleteFile(szTempPath); }
|