DirectX SDK

Low-Level DLS

[Visual Basic]

This topic pertains only to applications written in C++. DirectX for Visual Basic does not support low-level manipulation of DLS data.

[C++]

If you are writing a DirectMusic application that edits DLS collections, you must be able to download instrument data to the synthesizer without encapsulating it in a DirectMusicInstrument object.

Working with DLS data requires knowledge of the DLS specification and file structure. For detailed information on these topics, contact the MIDI Manufacturers Association.

To download raw instrument data, you must first get a pointer to the IDirectMusicPortDownload interface, as shown in the following code example, in which it is assumed that pIPort is a valid pointer to an IDirectMusicPort interface:

IDirectMusicPortDownload **ppIDownloadPort;
 
HRESULT hr = pIPort->QueryInterface(IID_IDirectMusicPortDownload,
        (void **) ppIDownloadPort);

If the HRESULT is not S_OK, the port does not support DLS downloading.

Next, identify the buffers that must be prepared and downloaded. To send an instrument to the synthesizer, create one instrument buffer that represents the entire instrument definition with all the regions and articulations, and a series of wave buffers, one for each wave that the instrument refers to for its regions.

Each buffer must be tagged with a unique identifier. Identifiers are used to resolve linkages between buffers, in particular the links between regions and waves. Tally the number of buffers that you need to download, and call IDirectMusicPortDownload::GetDLId to allocate a range of identifiers. For example, if you are downloading an instrument with three waves, you must download four buffers in all. Therefore, request a set of four identifiers.

For each buffer, calculate the size needed; then call IDirectMusicPortDownload::AllocateBuffer to allocate it. This method returns an IDirectMusicDownload interface representing the buffer. Call IDirectMusicDownload::GetBuffer to access the memory.

Note  There are two methods called GetBuffer:

IDirectMusicPortDownload::GetBuffer returns an IDirectMusicDownload interface pointer for a buffer object whose download identifier is known.

IDirectMusicDownload::GetBuffer returns a pointer to the memory in the buffer.

Now write the data into each buffer. Each buffer starts with a DMUS_DOWNLOADINFO structure, which defines the size and functionality of the download. This structure must be prepared as follows:

The DMUS_DOWNLOADINFO structure is always followed by a DMUS_OFFSETTABLE structure. This offset table is used to manage all links within the data. Whenever a structure in the data refers to another structure, it addresses it with an integer index, instead of a pointer. For every structure within the data that can be referred to, there is a unique index. The DMUS_OFFSETTABLE translates this integer index into a byte offset into the data.

The instrument or wave data follows the DMUS_OFFSETTABLE. If the download is an instrument, the data starts with the DMUS_INSTRUMENT structure. Otherwise, it starts with the DMUS_WAVE structure.

The instrument data that follows the DMUS_INSTRUMENT structure is organized in the following structures:

The wave data pointed to by the DMUS_WAVE structure is organized in a DMUS_WAVEDATA structure.

When the buffers are all ready, download them by using IDirectMusicPortDownload::Download. Download the wave buffers first so that they are in place and can be referred to when the instrument is downloaded.

Once the buffers have been downloaded, the synthesizer is ready to play the instrument. The memory in the buffer is no longer accessible.

Later, when done playing the instrument, unload the buffers, and release them. First, unload the instrument buffer, then all the wave buffers. To unload, call IDirectMusicPortDownload::Unload and pass it the IDirectMusicDownload objects. Then, release each buffer with a call to IDirectMusicDownload::Release.

To update an instrument that has already been downloaded, you cannot write over the previously downloaded buffer. Instead, replace the instrument, but not the waves. To do this, call IDirectMusicPortDownload::AllocateBuffer to allocate a new IDirectMusicDownload interface with a buffer of the correct size. Be sure to generate a new identifier for the buffer with a call to IDirectMusicPortDownload::GetDLId. Write the new articulation information into the buffer; then download it. Then unload the previously downloaded buffer with a call to IDirectMusicPortDownload::Unload.

To update a wave buffer, take one extra step. Create both a new wave buffer and an updated instrument buffer that refers to it. Download the new wave, then the new instrument. Then unload the old instrument, followed by the old wave.