|Microsoft DirectX 9.0|
This document describes how to handle messaging for a client of a Microsoft?DirectPlay?Voice session. For a discussion of host-related messaging, see Handling Voice Host Messages. For a discussion of general messaging issues, see Handling DirectPlay Messaging.
Many of the messages used by DirectPlay Voice are similar to those used by the DirectPlay core application programming interface (API). However, be aware that similar core and voice messages sometimes differ in their usage.
For example, when you connect to either a core or voice session, DirectPlay returns a completion message with the results of your connection attempt. With a core session, you may get a DPN_MSGID_CONNECT_COMPLETE completion message under some circumstances, even when you connect synchronously. With DirectPlay Voice however, you will never get a completion message if you attempt to connect synchronously to a voice session. You get a DVMSGID_CONNECTRESULT completion message only if you connect to a voice session asynchronously.
One notable difference between core and voice message handling is that your core message handler receives every core message. With DirectPlay Voice, you have the option of specifying a list of messages that you want to receive by calling IDirectPlayVoiceClient::SetNotifyMask. You will receive only those messages that are on the notification list that you pass to this method through the pdwMessageMask parameter. This list must contain at least one message. You cannot use IDirectPlayVoiceClient::SetNotifyMask to disable all DirectPlay Voice messages.
DirectPlay Voice is an optional addition to a regular DirectPlay session. It enables voice communication between the session members. Before you can become a client of a voice session, you must have created the appropriate DirectPlay object and be connected to a regular peer-to-peer or client/server session. See Peer-to-Peer Sessions or Client/Server Sessions for details.
Every voice session must have a host. If you are in a peer-to-peer session, one of the members must be selected as the voice session host. The voice host need not be the same member as the one that is hosting the core session. If you are in a client/server session, the server must host the voice session as well as the core session. When a session host has been determined, the host must start the voice session by creating a voice server object and calling IDirectPlayVoiceServer::StartSession. Once the session has been started, clients can connect.
This section outlines the messages that a voice client receives when joining a session.
Once the session is set up, clients must call IDirectPlayVoiceClient::Connect to connect to the voice session. If you call this method asynchronously and it returns DV_PENDING, you will receive a DVMSGID_CONNECTRESULT message with the result of the connection attempt. This message can arrive before or after IDirectPlayVoiceClient::Connect returns DV_PENDING. If you call the method synchronously, you will not receive a DVMSGID_CONNECTRESULT message. The result of a synchronous connection attempt is indicated by the method's return value.
Voice clients receive this message only if they are a member of a peer-to-peer voice session. After you are connected and have processed DVMSGID_CONNECTRESULT, you will receive a DVMSGID_CREATEVOICEPLAYER message for yourself and each member of the voice session. The structure that accompanies this message contains the DVID value that you will use to identify the player during the session. The dwFlags member of this structure contains two flags that describe the player. If the player is the local player, the DVPLAYERCAPS_LOCAL flag will be set. If the player is half-duplex, the DVPLAYERCAPS_HALFDUPLEX flag will be set.
If you want to create a voice session player context value for the player, you must do so when you handle this message. For more information about player context values, see Using Player Context Values. You will receive no messages associated with a player until you have processed the corresponding DVMSGID_CREATEVOICEPLAYER message.
Once you have successfully connected, there are a number of messages that you might receive during the course of a voice session. The list of possible messages depends on whether you are in a peer-to-peer or client/server voice session. As a general rule, voice clients in a client/server voice session do not receive any messages that are associated with a particular player.
The following messages can be received by clients of both types of voice sessions.
These messages let you know whether you have capture focus and are capturing audio. When you gain capture focus and audio capture starts, you receive a DVMSGID_GAINFOCUS message. When you lose capture focus and audio capture stops, you receive a DVMSGID_LOSTFOCUS message. Both messages are simple notifications and do not have an associated structure. For more information about capture focus, see Capture Focus and Implementing a Callback Function in DirectPlay and DirectPlay Voice.
These messages notify you when the local player is transmitting. You receive a DVMSGID_RECORDSTART message when transmission starts and a DVMSGID_RECORDSTOP when transmission stops. The structure that accompanies these messages contains the voice player context value for the local player. What causes transmission to start and stop depends on whether you are using push-to-talk or voice activation transmission control and whether your application has gained or lost audio capture focus.
The simplest case is when audio capture focus does not change. In that case, voice activated transmission starts when the user's voice exceeds the activation threshold. It stops when the voice drops below the activation threshold. With push-to-talk transmission, the user starts and stops transmission manually, typically by pushing and releasing a button.
Even if the player has exceeded the voice activation threshold or pushed push-to-talk, the application must have capture focus in order to transmit. If the player is talking but the application does not have audio capture focus, transmission begins only when the application gains audio capture focus. You will receive a DVMSGID_GAINFOCUS message followed by a DVMSGID_RECORDSTART message at that time. If you lose audio capture focus while the player is still talking, transmission immediately stops and you receive a DVMSGID_LOSTFOCUS message followed by a DVMSGID_RECORDSTOP message. If you get audio capture focus back and the player is still talking, transmission will start again.
You normally receive a DVMSGID_RECORDSTOP message when transmission stops, regardless of the reason. However, if you disconnect from the voice session while you are transmitting, you are not guaranteed to receive a DVMSGID_RECORDSTOP message.
For details about capture focus, see Capture Focus. For details about transmission control, see Transmission Control.
The DVMSGID_INPUTLEVEL message gives you the current audio input level from your player's microphone. The DVMSGID_OUTPUTLEVEL message gives you the current audio output level from your player's speakers or headphones. These messages are sent at a regular time interval. They start after you have processed a DVMSGID_RECORDSTART message and stop after you process the corresponding DVMSGID_RECORDSTOP message. To specify the rate at which the messages are sent, set dwNotifyPeriod member of the DVCLIENTCONFIG structure to an appropriate time interval. To suppress these messages, set dwNotifyPeriod to 0.
The following messages can be received only by clients of peer-to-peer voice sessions.
You receive a DVMSGID_CREATEVOICEPLAYER message each time a player is added to the voice session. You should handle this message in the same way as the player creation messages that you received when you connected to the session. When a player leaves the voice session, you receive a DVMSGID_DELETEVOICEPLAYER message. You will receive a DVMSGID_DELETEVOICEPLAYER message for every DVMSGID_CREATEVOICEPLAYER message. When you have processed a DVMSGID_DELETEVOICEPLAYER message, you will receive no further messages for that player.
The DVMSGID_SETTARGETS message is sent when the list of voice targets changes. It is generated any time a voice client calls IDirectPlayVoiceClient::SetTransmitTargets or a voice host calls IDirectPlayVoiceServer::SetTransmitTargets.
The DVMSGID_PLAYERVOICESTART message is sent when you start to receive a transmission from a player. If level notification is enabled, you will start receiving DVMSGID_PLAYEROUTPUTLEVEL messages. The DVMSGID_PLAYERVOICESTOP messages sent when that player's transmission stops. When you have processed this messages, the DVMSGID_PLAYEROUTPUTLEVEL messages stop. If audio capture focus changes, these messages are handled in essentially the same way as for DVMSGID_RECORDSTART and DVMSGID_RECORDSTOP. You will not receive these messages for a player until you have processed the corresponding DVMSGID_CREATEVOICEPLAYER message.
The DVMSGID_PLAYEROUTPUTLEVEL gives you the current audio output level on your player's speakers or headphones for a particular player's transmission. These messages are sent at a regular time interval. They start after you have processed a DVMSGID_RECORDSTART message and stop after you process the corresponding DVMSGID_RECORDSTOP message. To specify the rate at which the messages are sent, set dwNotifyPeriod member of the DVCLIENTCONFIG structure to an appropriate time interval. To suppress these messages, set dwNotifyPeriod to 0.
When the voice host migrates, the DVMSGID_LOCALHOSTSETUP message is sent to the new voice host. This message allows the new voice host to set the callback function and context value that will be used when creating the new voice server object. When your application returns from handling this message, you will receive a DVMSGID_HOSTMIGRATED message.
When the host migrates, a DVMSGID_HOSTMIGRATED message is sent to all remaining members of the voice session. The associated structure contains the DVID of the new voice host. When the host migrates, DirectPlay Voice automatically creates a new voice server object. If your application is the new voice host, the DVMSGID_HOSTMIGRATED message's structure will also contain a pointer to the voice server's IDirectPlayVoiceServer interface. If you want to use this interface, you must call the interface's AddRef method to increment the interface's reference count. If you have called AddRef on IDirectPlayVoiceServer, be sure to call Release when you are finished with the interface.
Disconnect from a voice session by calling IDirectPlayVoiceClient::Disconnect. If you call this method asynchronously and it returns DV_PENDING, you will receive a DVMSGID_DISCONNECTRESULT to notify you of the outcome. This message can arrive before or after IDirectPlayVoiceClient::Disconnect returns. The DVMSGID_DISCONNECTRESULT message is not sent if you call IDirectPlayVoiceClient::Disconnect synchronously. The result of a synchronous disconnection attempt is indicated by the method's return value.
For peer-to-peer voice sessions, the client will receive a DVMSGID_DELETEVOICEPLAYER for every remaining player in the sessionóbefore the client receives DVMSGID_DISCONNECTRESULT.
If the session terminates unexpectedly because of an unrecoverable error, clients will receive a DVMSGID_SESSIONLOST message. The reason for the failure is specified in the hrResult member of the associated structure.
For peer-to-peer voice sessions, the client will receive a DVMSGID_DELETEVOICEPLAYER for every remaining player in the sessionóbefore the client receives DVMSGID_SESSIONLOST.
For peer-to-peer sessions, you will receive a DVMSGID_DELETEVOICEPLAYER for every player remaining in the voice session when you are disconnected, regardless of whether you call IDirectPlayVoiceClient::Disconnect or the session is lost. This ensures that each DVMSGID_CREATEVOICEPLAYER that you receive has a corresponding DVMSGID_DELETEVOICEPLAYER message. You will receive all DVMSGID_DELETEVOICEPLAYER messages before the disconnect is completed.