Hi everyone, I'm Tomas, Directmusic programmer of a small game development group and reader of this mailing list for quite some time now. I've noticed that there's a lot of smart people around here, so I hope someone can help me with a Directmusic problem that I'm having :-). The background: I must find a way to load Directmusic-objects without using the specific file functions in IDirectMusicLoader8 (e.g LoadObjectFromFile, SetSearchDirectory etc). The reason for this is that the Directmusic module in our system will not have access to any files, but instead will be given a pointer to the data that I probably will be able to load using IDirectMusicLoader8::GetObject. I'm pretty sure that I've managed to load a segment consisting of a number of wavetracks by first using IDirectMusicLoader8::SetObject on the wave-files referred to by the script, and then loading the Segment like usual. Now, the problem is: This does not seem to work too well with scripts (or containers in general, I suspect). The only way I've managed to load a script is by either embedding all references in the script or by placing all referred files in the same directory and then pointing IDirectMusicLoader8:: SetSearchDirectory to that directory. But, as I said before, the latter one does not meet our requirements (and obviously, the first one is very inefficient if I want to use the same file in a lot of scripts). So, I need to be able to load scripts by using IDirectMusicLoader8::SetObject or by some other solution that lets me give the loader a pointer to the data. I thought that you could simply use IDirectMusicLoader8::SetObject on all the objects that are referred to by the script, and then simply load the script, just as with segments. Is this not possible? Here's an excerpt from the current, flawed solution: <CODE> int main() { //*snip* /* First run SetObject on all files that the script refers to. The LoaderSetObject simply runs SetObject on the file passed to it. */ hr = LoaderSetObject(g_pLoader, CLSID_DirectMusicAudioPathConfig, L"Audiopath_AllCh", L"C:\\Documents and Settings\\Tomas\\My Documents\\DMUSProducer\\Test1\\RuntimeFiles\\Audiopath_AllCh.aud"); hr = LoaderSetObject(g_pLoader, CLSID_DirectSoundWave, L"Riff_Bass-01", L"C:\\Documents and Settings\\Tomas\\My Documents\\DMUSProducer\\Test1\\RuntimeFiles\\Riff_Bass-01.wav"); /* ... *snip* LoaderSetObject of all other referred files is omitted from this code listing... */ WCHAR wcharFilename[] = L"C:\\Runtimefiles\\TestScript1.spt"; WCHAR wcharRoutine[] = L"PlaySegment"; // ... Then load & play the script. hr = PlayScript(g_pLoader, g_pPerformance, pScript, wcharFilename, wcharRoutine); //*snip* } //End main /* LoaderSetObject: Lets the loader know where all referred files can be found when loading a script. pLoader: The Directmusic loader guidClass: The class id of the object to give to SetObject. wcharObjName: The internal name of the object to set [optional] wcharFilepath: The path+filename to the object that is going to be set. */ HRESULT LoaderSetObject(IDirectMusicLoader8* &pLoader, GUID guidClass, WCHAR* wcharObjName, WCHAR* wcharFilepath) { DMUS_OBJECTDESC objDesc; HRESULT hr; ZeroMemory(&objDesc,sizeof(objDesc)); objDesc.dwSize = sizeof(objDesc); objDesc.guidClass = guidClass; wcscpy(objDesc.wszFileName, wcharFilepath); objDesc.dwValidData = DMUS_OBJ_FULLPATH | DMUS_OBJ_CLASS; if (wcharObjName) { wcsncpy(objDesc.wszName, wcharObjName, sizeof(objDesc.wszName) - 1); objDesc.wszName[sizeof(objDesc.wszName) - 1] = 0; objDesc.dwValidData |= DMUS_OBJ_NAME; } hr = pLoader->SetObject(&objDesc); return hr; } /* PlayScript: Loads and plays the script. pLoader & pPerformance: Obvious ;-) pScript: Return variable of the script object loaded by PlayScript wcharFilename: The path+filename of the script to load & play. wcharRoutinge: The name of the script routine to play. */ HRESULT PlayScript(IDirectMusicLoader8* &pLoader, IDirectMusicPerformance8* &pPerformance, IDirectMusicScript8* &pScript, WCHAR* wcharFilename, WCHAR* wcharRoutine) { HRESULT hr; DMUS_SCRIPT_ERRORINFO errInfo; DMUS_OBJECTDESC objDesc; try { if (!pLoader || !pPerformance) return E_INVALIDARG; ZeroMemory(&objDesc,sizeof(objDesc)); objDesc.dwSize = sizeof(DMUS_OBJECTDESC); objDesc.guidClass = CLSID_DirectMusicScript; wcscpy(objDesc.wszFileName, wcharFilename); objDesc.dwValidData = DMUS_OBJ_FULLPATH | DMUS_OBJ_CLASS; //!!! ERROR PRINTOUT FROM DIRECTX DEBUG WHEN DOING THIS GETOBJECT !!! hr = pLoader->GetObject(&objDesc, IID_IDirectMusicScript, (LPVOID *) &pScript); if (FAILED (hr = pScript->Init(pPerformance, &errInfo))) { pScript->Release(); return E_FAIL; } hr = pScript->CallRoutine(wcharRoutine, &errInfo); MessageBox(NULL, "Script", "Playing", MB_OK); pPerformance->Stop(NULL, NULL, 0, 0); pScript->Release(); return S_OK; } //End try catch(...) { DEBUG ("PlayScript Exception!\n"); return S_FALSE; } } //End PlayScript </CODE> You may wonder why I load files in this code example when I told you that I would not use files. That's because I thought that it would be easy to just replace the file references with memory references later on, since I use SetObject. Now, what happens is that when reaching the row... "hr = pLoader->GetObject(&objDesc, IID_IDirectMusicScript, (LPVOID *) &pScript);" ... in the PlayScript-method above, I get the following debug printout from direct-x in my output window in Visual Studio and the &pScript is still unallocated: <ERROR MESSAGE> DMLOADER: Warning: The file Riff_Bass-01.wav couldn't be opened: No such file or directory . Try another path. DMLOADER: Warning: The file Riff_Chords-01.wav couldn't be opened: No such file or directory . Try another path. DMLOADER: Warning: The file Riff_Drums-01.wav couldn't be opened: No such file or directory . Try another path. DMLOADER: Warning: The file Audiopath_AllCh.aud couldn't be opened: No such file or directory . Try another path. DMLOADER: Warning: The file Segment1.sgt couldn't be opened: No such file or directory . Try another path. DMLOADER: Warning: The file Riff_Bass-01.wav couldn't be opened: No such file or directory . Try another path. DMLOADER: Load failure. While attempting to load the object DMLOADER: [file C:\Documents and Settings\Tomas\My Documents\DMUSProducer\Test1\Runtimefiles\TestScript1.spt, name TestScript1, type Microsoft.DirectMusicScript.1, guid {CAFFF46E-F3D6-4AA1-BE06- FACAA7A17F0E}] DMLOADER: the following referenced objects could not be loaded: DMLOADER: [file Riff_Bass-01.wav, name Riff_Bass-01, type Microsoft. DirectMusicSegment.1, guid {F7B4BDBE-4695-4320-9A9E-C4CF4785B8C0}] </ERROR MESSAGE> Basically, none of files that the script refers to can be loaded. The files cannot be found it seems, since they are found if I were to point out their directory using IDirectMusicLoader8::SetSearchDirectory (but since I won't be able to rely on files later on, that's a no-no). I don't understand why the loader cannot find the files. If I point out them using the SetObject, the loader should be able to load them when loading the script, right? FYI, in Producer, the script is set to load all references and download all segments when it's loaded. I would be very grateful if somebody out there with some experience could help me with this problem. It makes no sense to me :-(. Best regards, Tomas Elf