Microsoft DirectX 8.1 (C++) |
A tool is an object that intercepts messages and handles them in some way. The tool might alter the message and then pass it on to the next tool, or free the message, or send a new message based on information in the old one.
DirectMusic has an output tool that is normally the last to receive messages. It is this tool that converts performance messages to standard MIDI messages and streams them to the synthesizer. Other tools are implemented by the application or obtained from libraries.
To implement a tool, you must first create an object that supports the IDirectMusicTool8 interface. The object's implementation of the IDirectMusicTool8 methods determines what messages are processed by the tool and what work is performed on these messages.
All tools other than the output tool are collected in toolgraphs. Even if your application is using only one other tool, you must create a toolgraph to contain it. Then add this toolgraph to a segment or the performance. Toolgraphs provide a convenient mechanism for directing messages from one tool to another.
When the performance engine is playing a segment, it enables each tool in the segment toolgraph, and then each tool in the performance toolgraph, to process each message. After a tool processes a message, it should obtain the IDirectMusicGraph8 pointer from the pGraph member of the DMUS_PMSG structure and then call the IDirectMusicGraph8::StampPMsg method to stamp the message with a pointer to the next tool, if any, that is to receive it.
Tools process messages in a high-priority thread. Do not call time-consuming functions, such as those involving graphics or file input/output, from within a tool's IDirectMusicTool8::ProcessPMsg method. If a tool needs to trigger an action, it should do so by signaling a different thread, perhaps the application's main thread.
When implementing the methods of IDirectMusicTool8, take care not to create circular references to parent objects. Circular references come about when one object creates another and the child keeps an additional reference to the parent. For example, suppose a tool creates a new reference to the toolgraph passed into its IDirectMusicTool8::Init method. If the tool fails to release this reference, there is a problem when the segment attempts to release the toolgraph. Because the tool still has a reference to the toolgraph, the toolgraph is not fully released; and because the toolgraph has a reference to the tool, the tool cannot be released either.
For an example of how to implement a tool, see the MusicTool sample application.