DirectX SDK |
This topic pertains only to applications written in C++. DirectX for Visual Basic does not allow applications to work with individual instruments from a collection.
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 code 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 must next download them to the port.
To download an instrument to a port, pass an IDirectMusicInstrument interface pointer to the IDirectMusicPort::DownloadInstrument method. This method makes the DLS data available on the port; it does not actually associate the instrument with any particular performance.
You can also 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 save memory, 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 from low C through middle B is to be downloaded. Only the data for the regions falling within that range would be downloaded.
The following code example, 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 one DMUS_NOTERANGE structure and passes this to the IDirectMusicPort::DownloadInstrument method. Typically, only a single range of notes is specified, but you can 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 the 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. (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 code example downloads an instrument, and then unloads it, which illustrates 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.