/**************************************************************************** * * 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 #include #include #include #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); }