Platform SDK: DirectX

Loading a Collection

[C++]

The simplest way to load a collection from a file is to use the IDirectMusicLoader interface. (For more information, see Loading an Object from a File.) Once you have obtained a pointer to the IDirectMusicCollection interface, you have access to all the instruments in the collection. At this point, though, none of them have actually been downloaded to a port. In fact, no instrument data is loaded into memory until it is needed.

The collection is a COM object that supports the IDirectMusicCollection, IDirectMusicObject, and IPersistStream interfaces. IPersistStream is a standard COM interface providing methods for saving and loading objects that use a simple serial stream for their storage needs.

IDirectMusicCollection does not load the entire collection when IPersistStream::Load is called. Typically, objects supporting IPersistStream load all the persistent data in the stream and do not use the IStream pointer outside the Load method. However, supporting IPersistStream::Load in this manner in IDirectMusicCollection would mean that the entire DLS collection would have to be loaded into memory even if only a single instrument in the collection was to be used. Instead, IDirectMusicCollection saves the IStream pointer, and later uses it to load only the data for instruments that are downloaded to a DirectMusic port. IDirectMusicCollection assumes that the data stream provided through the IPersistStream interface is in the DLS file format.

The following code example does manually what the IDirectMusicLoader::GetObject method does automatically: it creates a collection object and loads a stream into it:

HRESULT myLoadCollectionFromStream(
        IStream *pIStream,    // Stream created from a file
        IDirectMusicCollection **ppICollection )
 
{
    HRESULT hr;
 
    hr = CoCreateInstance(CLSID_DirectMusicCollection,
                          NULL,
                          CLSCTX_INPROC,
                          IID_IDirectMusicCollection,
                          (void **)ppICollection);
    if (SUCCEEDED(hr))
    {
        IPersistStream* pIPersistStream;
        hr = *ppICollection->QueryInterface(
                IID_IPersistStream, (void**)&pIPersistStream);
        if (SUCCEEDED(hr))
        {
            hr = pIPersistStream->Load(pIStream);
            pIPersistStream->Release();
        }
    }
    return hr;
}

The following code example uses the DirectMusicLoader to load the collection by file name:

HRESULT myLoadCollectionByName(
        IDirectMusicLoader *pILoader, 
        char *pszFileName, 
        IDirectMusicCollection **ppICollection)
{
    HRESULT hr;
    DMUS_OBJECTDESC Desc;             // Descriptor
 
    // Start by initializing Desc with the file name and GUID
    // for the collection object.
    // The file name starts as a char string, so convert
    // to Unicode.
 
    mbstowcs(Desc.wszFileName,pszFileName,DMUS_MAX_FILENAME);
    Desc.dwSize = sizeof(DMUS_OBJECTDESC);
    Desc.guidClass = CLSID_DirectMusicCollection;  
    Desc.dwValidData = DMUS_OBJ_CLASS 
            | DMUS_OBJ_FILENAME 
            | DMUS_OBJ_FULLPATH;
 
    hr = pILoader->GetObject(&Desc, 
            IID_IDirectMusicCollection,
            (void **) ppICollection);
    return hr;
}

To load the standard GM/GS set, pass GUID_DefaultGMCollection to the loader in the guidObject member of the DMUS_OBJECTDESC structure. If you intend to use the loader to access this object more than once, make sure that caching is enabled (as it is by default) so that you do not create another copy of the GM collection each time that you request it.

Note  The GM/GS Sound Set cannot be altered. For more information, see the Copyright Warning.

The following code example illustrates how to load a collection identified by its GUID:

HRESULT myGetGMCollection(
        IDirectMusicLoader *pILoader, 
        IDirectMusicCollection **ppICollection)
{
    HRESULT hr;
    DMUS_OBJECTDESC desc;
 
    desc.dwSize = sizeof(DMUS_OBJECTDESC);
    desc.guidClass = CLSID_DirectMusicCollection;
    desc.guidObject = GUID_DefaultGMCollection;
    desc.dwValidData = (DMUS_OBJ_CLASS | DMUS_OBJ_OBJECT);
    hr = pILoader->GetObject(&desc, IID_IDirectMusicCollection,
            (void **) ppICollection);
    return hr;
}
[Visual Basic]

To load an instrument collection, call the DirectMusicLoader.LoadCollection or the DirectMusicLoader.LoadCollectionFromResource method. Each of these methods returns a DirectMusicCollection object. This object has no methods, and its sole function is as a parameter to DirectMusicSegment.ConnectToCollection. Call that method to associate the collection with a segment, and then download the instruments by calling DirectMusicSegment.Download.

These steps are necessary only when you want to use a collection other than the default one. Normally, when you call DirectMusicSegment.Download, the instruments downloaded to the port are from the default collection authored into the segment or from the General MIDI set, if the segment does not contain a custom collection or is a MIDI file. When you download a band, all DLS data needed by the instruments in that band is downloaded. See Using Bands.