Once a DirectMusicCollection is created and loaded from a collection file, you can retrieve the patch number and name of all the available instruments by using the IDirectMusicCollection::EnumInstrument method.
The following example enumerates all instruments in a collection and displays their names and patch numbers.
void myListInstruments(
IDirectMusicCollection *pCollection)
{
HRESULT hr = S_OK;
DWORD dwPatch;
WCHAR wszName[MAX_PATH];
DWORD dwIndex;
for (dwIndex = 0; hr == S_OK; dwIndex++)
{
hr = pCollection->EnumInstrument(
dwIndex, &dwPatch, wszName, MAX_PATH);
if (hr == S_OK)
{
printf("Patch %lx is %S\n",dwPatch,wszName);
}
}
}
You can obtain a pointer to a specific instrument by passing its patch number to the IDirectMusicCollection::GetInstrument method.
After obtaining an instrument, you can change its patch number by using the IDirectMusicInstrument::SetPatch method.
Loading a collection and retrieving the instruments is only the first step in making the instruments available. You next have to download them to the port.
To download an instrument to a port, you pass an IDirectMusicInstrument interface pointer to the IDirectMusicPort::DownloadInstrument method. This method simply makes the DLS data available on the port; it does not actually associate the instrument with any particular performance.
Alternatively, you can download an instrument by using the IDirectMusicPerformance::DownloadInstrument method. In addition to downloading the DLS data, this method assigns the instrument to a particular performance channel.
To economize on memory usage, only waves and articulation required for given ranges of notes are downloaded. For example, for a bassoon you might specify that only data for the note range low C to middle B was to be downloaded. Only the data for the regions falling within that range would be downloaded.
The following function, given a collection, a patch number, a port, and a range of notes, retrieves the instrument from the collection and downloads it. It sets up an array of just one DMUS_NOTERANGE structure and passes this to the IDirectMusicPort::DownloadInstrument method. Typically only a single range of notes will be specified, but it is possible to specify multiple ranges. If you pass NULL instead of a pointer to an array, the data for all regions is downloaded.
HRESULT myDownload(
IDirectMusicCollection *pCollection, // DLS collection
IDirectMusicPort *pPort, // Destination port
IDirectMusicDownloadedInstrument **ppDLInstrument,
DWORD dwPatch, // Requested instrument
DWORD dwLowNote, // Low note of range
DWORD dwHighNote) // High note of range
{
HRESULT hr;
IDirectMusicInstrument* pInstrument;
hr = pCollection->GetInstrument(dwPatch, &pInstrument);
if (SUCCEEDED(hr))
{
DMUS_NOTERANGE NoteRange[1]; // Optional note range
NoteRange[0].dwLowNote = dwLowNote;
NoteRange[0].dwHighNote = dwHighNote;
hr = pPort->DownloadInstrument(pInstrument,
ppDLInstrument,
NoteRange, // Array of ranges
1); // Number of elements in array
pInstrument->Release();
}
return hr;
}
The DownloadInstrument method returns a pointer to the IDirectMusicDownloadedInstrument interface. This pointer has just one purpose: to identify the instrument in a subsequent call to the IDirectMusicPort::UnloadInstrument method, which unloads the instance of the instrument on a particular port. (Note that the DirectMusicCollection is not bound to any specific port. You can download different instruments to different ports, or download a single instrument to multiple ports.)
The following function downloads an instrument and then unloads it, which accomplishes nothing except to illustrate how the IDirectMusicDownloadedInstrument pointer can be used:
HRESULT myFickleDownload(
IDirectMusicInstrument* pInstrument,
IDirectMusicPort *pPort,
DWORD dwPatch)
{
HRESULT hr;
IDirectMusicDownloadedInstrument * pDLInstrument;
hr = pPort->DownloadInstrument(
pInstrument, &pDLInstrument,
NULL, 0);
if (SUCCEEDED(hr))
{
pPort->UnloadInstrument(pDLInstrument);
pDLInstrument->Release();
}
return hr;
}
The IDirectMusicBand::Download method automates the downloading of all instruments in a band. You supply a pointer to a performance, and the method downloads each instrument to the appropriate port attached to that performance.