Low-Level DLS

DirectMusic

Microsoft DirectX 9.0 SDK Update (Summer 2004)

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:

  • One instrument buffer, which represents the entire instrument definition with all the regions and articulations.
  • One or more waveform buffers, which describe each waveform that the instrument references 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 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:

  • IDirectMusicPortDownload8::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 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:

  • Set the dwDLType member to either DMUS_DOWNLOADINFO_INSTRUMENT2 for an instrument or DMUS_DOWNLOADINFO_WAVE for a waveform.
  • Set the dwDLId member to one of the unique identifiers that you obtained by using IDirectMusicPortDownload::GetDLId.
  • Set the dwNumOffsetTableEntries member to the number of entries in the DMUS_OFFSETTABLE structure.
  • Set the cbSize member to the size of the download chunk, including DMUS_DOWNLOADINFO and DMUS_OFFSETTABLE.

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:


© 2004 Microsoft Corporation. All rights reserved.