Microsoft DirectX 9.0

Low-Level DLS

If you are writing an application that edits DLS collections or creates instruments from waveform samples at run time, you must be able to download instrument data to the synthesizer without encapsulating it in a DirectMusic instrument 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, first get a pointer to the IDirectMusicPortDownload8 interface, as shown in the following code example, where it is assumed that pIPort is a valid pointer to an IDirectMusicPort8 interface:

IDirectMusicPortDownload **ppIDownloadPort;
HRESULT hr = pIPort->QueryInterface(IID_IDirectMusicPortDownload8,
    (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, you will create the following buffers:

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

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

Note   There are two methods called GetBuffer:

Now write the data into the buffers. 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 referenced, there is a unique index. The DMUS_OFFSETTABLE translates this integer index into a byte offset into the data.

The instrument or WAV 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 WAV 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 IDirectMusicPortDownload8::Download. Download the waveform buffers first so that they are in place and can be referenced 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 waveform buffers. To unload, pass the IDirectMusicDownload8 pointers to IDirectMusicPortDownload8::Unload. Then release each buffer with a call to IDirectMusicDownload8::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 waveforms. To do this, call IDirectMusicPortDownload8::AllocateBuffer to allocate a new IDirectMusicDownload8 interface with a buffer of the correct size. Be sure to generate a new identifier for the buffer with a call to IDirectMusicPortDownload8::GetDLId. Write the new articulation information into the buffer; then download it. Then unload the previously downloaded buffer with a call to IDirectMusicPortDownload8::Unload.

To update a waveform buffer, take one extra step. Create both a new waveform buffer and an updated instrument buffer that references it. Download the new waveform, then the new instrument. Then unload the old instrument and the old waveform.

More information is contained in the following topic: