# Sending commands to channel filters

Once an application creates an MSPP channel and connects it to a pair of endpoints, the application can control the component channel filters with mspSendCommand. mspSendCommand conveys filter-specific commands to filters associated with connected channels.

Channel commands are executed by the filters that make up the channel. Each filter that makes up the channel responds to a specific set of commands. Command information is passed through a predefined structure.

To send a command to a filter within a connected channel, the application invokes mspSendCommand and specifies the following:

- MSPP chnhd.

- Filter command produced by using the OR operator to combine a filter ID with a filter command ID.
  To build a valid filter command, use the macro mspBuildCommand (defined in mspcmd.h) to concatenate the channel filter ID with an endpoint command ID.

- Pointer to a filter-specific command structure.

- Size of the specified structure.

Voice encoder filters, voice decoder filters, and T.38 fax relay filters receive commands only when the parent channel is connected and enabled. Applications must wait for a done event (MSPEVN_SENDCOMMAND_DONE) before sending additional filter commands to any MSPP filter. If the channel contains multiple filters, the application can send simultaneous commands to all of the channel filters and wait for the separate events.

MSPP channel filters include:

Filter ID | Description
MSP_FILTER_G711_Encoder | Encodes data to G.711 64 kbit/s mu-law or A-law form without VAD.
MSP_FILTER_G711_Decoder | Decodes data from G.711 64 kbit/s mu-law or A-law form.
MSP_FILTER_G723_Encoder | Encodes data to G.723.1/A 6.4/5.3 kbit/s form with VAD.
MSP_FILTER_G723_Decoder | Decodes data from G.723.1/A 6.4/5.3 kbit/s form.
MSP_FILTER_G726_Encoder | Encodes data to G.726 32 kbit/s form without VAD.
MSP_FILTER_G726_Decoder | Decodes data from G.726 32 kbit/s form.
MSP_FILTER_G729A_Encoder | Encodes data to G.729A/B 8.0 kbit/s form with VAD.
MSP_FILTER_G729A_Decoder | Decodes data from G.729A/B 8.0 kbit/s form.
MSP_FILTER_JITTER | Receives asynchronous packets and processes them to produce an ordered synchronous output.
MSP_FILTER_T38FAX_FULLDUPLEX | Demodulates the signal received from a PSTN line, stores the data in a fax media packet, and modulates the appropriate signal to be sent over the PSTN.
MSP_FILTER_RTP_SWITCH | Transfers a simplex voice data stream between two RTP endpoints.

For a list of the commands available for each type of MSPP channel filter, refer to Channel filter summary or to the mspcmd.h file.

### Example 1: Controlling jitter on a G.726 channel

An application changes a jitter filter's jitter depth by changing the number of packets the filter holds in a queue to verify the sequence of the packets. For information about the commands that apply to the jitter filter, refer to the Channel filter summary.

The following illustration shows how an application can control jitter depth by sending a command to a channel's jitter filter with mspSendCommand (after the channel is connected). The application provides the chnhd associated with the G.726 channel, specifies the filter ID and filter command ID (combined using the OR operator), and provides a pointer to the msp_FILTER_JITTER_CMD structure shown here.

typedef struct tag_msp_FILTER_JITTER_CMD {
DWORD value;
} msp_FILTER_JITTER_CMD;

The value field in the msp_FILTER_JITTER_CMD structure specifies the value to be set for the jitter. The application uses the mspBuildCommand macro to concatenate the filter ID and the filter command ID. The following illustration shows and example of sending an MSPP channel command:

The MSPP API returns MSPEVN_SENDCOMMAND_DONE after the command is executed.

The following code sample shows how to use the mspBuildCommand macro with mspSendCommand to change the jitter depth setting in a MSPP voice channel:

msp_FILTER_JITTER_CMD jitter_cmd;
jitter_cmd.value = 2;
jitter_cmd.value = H2NMS_DWORD(jitter_cmd.value); // OS independent endian adjustment
cmd = mspBuildCommand(MSP_FILTER_JITTER, MSP_CMD_JITTER_CHG_DEPTH); // macro
ret = mspSendCommand( hObject, cmd, (void*)&jitter_cmd, sizeof(jitter_cmd));
if (ret != SUCCESS)
return FAILURE;
// Wait for done event
memset (&Event, 0, sizeof(Event));
ctaWaitEvent( hCta, &Event, CTA_WAIT_FOREVER );
expected_id = MSPEVN_SENDCOMMAND_DONE | MSP_CMD_JITTER_CHG_DEPTH;
// Check for a valid event
if ( Event.id != expected_id ||
Event.value != CTA_REASON_FINISHED )
{
// Jitter depth change failed (or out of sequence event)
}
else
{
// Jitter depth change successful
}
// Must release the buffer
if(Event.id == expected_id && Event.size != 0 && Event.buffer != NULL )
{
ret = mspReleaseBuffer( Event.objHd, Event.buffer);
Event.buffer = NULL;
Event.size = 0;
if ( ret != SUCCESS)
return FAILURE;
}

For information about MSPP API DONE events, refer to MSPP events.

### Example 2: Setting gain for a G.723.1 encoder filter

The following example shows how an application uses mspSendCommand to set the encoder gain to 3 dB in a G.723.1 duplex voice channel (the channel has been connected and enabled).

When using mspSendCommand to set gain for an MSPP voice encoder (or decoder) filter, the application must define the following values in the mspSendCommand buffer:

Value | Example
type | FILTER
objectname | G723ENCODE
description | GAINVALUE

These values are defined according to the following format:

msp_[type]_[objectname]_[description]

The application then uses the mspBuildCommand macro to concatenate the filter ID (for example, MSP_FILTER_G723_ENCODER) and the filter command ID (MSP_CMD_ENCODE_GAIN) when invoking mspSendCommand.

The following sample code shows how to set the gain value in an MSPP G.723 encoder channel filter:

/* Increase G.723 encoder filter gain by 3 dB */
msp_FILTER_ENCODE_CMD EncodeBuffer;
EncodeBuffer.value = 0x05A0; // 3 dB gain from the table shown in
Calculating vocoder filter gain and loss
EncodeBuffer.value = H2NMS_WORD(EncodeBuffer.value); // OS independent endian adjustment
cmd = mspBuildCommand(MSP_FILTER_G723_ENCODER, MSP_CMD_ENCODE_GAIN);
// macro
ret = mspSendCommand( hObject, cmd, (void*)&EncodeBuffer, sizeof(EncodeBuffer));
if (ret != SUCCESS)
return FAILURE;
// Wait for done event
memset (&Event, 0, sizeof(Event));
ctaWaitEvent( hCta, &Event, CTA_WAIT_FOREVER );
expected_id = MSPEVN_SENDCOMMAND_DONE | MSP_CMD_ENCODE_GAIN;
// Check for a valid event
if ( Event.id != expected_id ||
Event.value != CTA_REASON_FINISHED )
{
// Filter gain change unsuccessful
}
else
{
// Filter gain change successful
}
// Must release the buffer
if(Event.id == expected_id && Event.size != 0 && Event.buffer != NULL )
{
ret = mspReleaseBuffer( Event.objHd, Event.buffer);
Event.buffer = NULL;
Event.size = 0;
if ( ret != SUCCESS)
return FAILURE;
}