# Native record without inband silence and DTMF detection

To implement native record functionality without inband silence detection or DTMF detection, the application performs the following tasks:

- Creates a NaturalAccess event queue and context.

- Opens the ADI
  API and the MSPP API on the context and starts the NOCC protocol on the context.

- Creates an MSPP RTP endpoint and an MSPP record channel on the context.

- Connects the RTP endpoint with the record channel to create a record connection.

- Retrieves the filter ID of the jitter filter within the record channel.

- Supplies the ADI API with information about the RTP audio streams and specifies the desired behavior for native record operations.

- Starts and stops recording audio data from a network audio stream.

The application must zero the novoicetime, silencetime, and beeptime record parameters, to prevent starting the silence detector and tone generator.

Note: Applications can perform DTMF detection using Fusion RFC 2833 support, but silence detection is not supported. For more information, refer to the RFC 2833 support chapter in this Dialogic® NaturalAccess™ Fusion™ VoIP API Developer’s Manual.

The following illustration shows an overview of the native record mechanism without voice decoding:

## Sample procedure

Applications use functions from the following NaturalAccess resources to implement native record functionality without inband silence detection or DTMF detection:

- NaturalAccess functions to set up event queues and contexts, and to open services on the contexts.

- ADI API functions to start a protocol, to set native record settings, and to record incoming audio data.

- MSPP functions to create a voice connection consisting of a record channel and an RTP endpoint, and to retrieve the unique filter ID associated with the record channel.

The following procedure shows function sequence used to implement a typical native record operation without decoding:

Step | Action
1 | ctaCreateQueue creates a NaturalAccess event queue. ctaCreateQueue (&queuehd)
2 | ctaCreateContext creates a NaturalAccess context for the audio channel. ctaCreateContext (queuehd, &ctahd)
3 | ctaOpenServices opens the ADI and MSPP services on the context. ctaOpenServices (ctahd, svclist, nsvcs)
4 | adiStartProtocol starts the nocc protocol on the audio channel. adiStartProtocol (ctahd, "nocc", NULL, startparms)
5 | mspCreateChannel creates a record channel. mspCreateChannel (ctahd, chnladdr, chnlparms, &chanhd)
6 | mspCreateEndpoint creates an audio RTP endpoint and returns an endpoint handle (ephd). mspCreateEndpoint (ctahd, msp addrstruct, msp parmstruct, &rtpephd)
7 | mspConnect, with MSP_NO_CONNECT instead of a DS0 endpoint handle, connects the record channel with the RTP endpoint. mspConnect (rtpephd, chanhd, MSP_NO_CONNECT)
8 | mspGetFilterHandle retrieves the filter identifier (fltID) associated with the MSPP record channel. mspGetFilterHandle (chanhd, MSP_FILTER_JITTER, &fltID)
9 | adiSetNativeInfo, using both the context handle of the ADI port and the fltID returned by mspGetFilterHandle, sets NMS native record parameters. adiSetNativeInfo (ctahd, fltID, NULL, natpr_parms)
10 | adiRecordToMemory starts recording audio data. adiRecordToMemory (ctahd, buf, bufsize, rec_param)
11 | adiStopRecording stops recording audio data. adiStopRecording (ctahd)

### Example

The following example shows how to perform a native record operation without decoding:

ret = ctaCreateQueue( NULL, 0, &hCtaQueueHd ) ;
ret = ctaCreateContext( hCtaQueueHd, 0, "Record", &ctahd );
ServiceCount = 2;
ServDesc[0].name.svcname = "ADI";
ServDesc[0].name.svcmgrname = "ADIMGR";
ServDesc[0].mvipaddr.mode = ADI_VOICE_DUPLEX;
ServDesc[0].mvipaddr.stream = 0;
ServDesc[0].mvipaddr.timeslot = record_timeslot;
ServDesc[1].name.svcname = "MSP";
ServDesc[1].name.svcmgrname = "MSPMGR";
ret = ctaOpenServices( ctahd, ServDesc, ServiceCount );
ret = WaitForSpecificEvent( CTAEVN_OPEN_SERVICES_DONE, &Event );
// IP Channel Initialization
MSPHD ds0_ephd = MSP_NO_CONNECT;
MSPHD rtp_ephd;
// Create and init RTP endpoint
…
mspCreateEndpoint( ctaHd, &rtpaddr, &rtp_params, &rtp_ephd );
if (! WaitForSpecificEvent(MSPEVN_CREATE_ENDPOINT_DONE, &Event, 5000))
{
printf("Failed waiting for MSPEVN_CREATE_ENDPOINT_DONE (RTP)");
return FAILURE;
}
chanaddr.nBoard = Board;
chanaddr.channelType = G711RecordChannel;
chanaddr.FilterAttribs = MSP_FCN_ATTRIB_RFC2833;
chan_params.size = sizeof( MSP_CHANNEL_PARAMETER );
chan_params.channelType = G711RecordChannel;
chan_params.ChannelParms.VoiceParms.size = sizeof( MSP_VOICE_CHANNEL_PARMS );
// Create channel
mspCreateChannel( ctaHd, &chanaddr, &chan_params, &msphd );
CTA_EVENT CtaEvent;
if (! WaitForSpecificEvent(MSPEVN_CREATE_CHANNEL_DONE, &Event, 5000))
{
printf("Failed waiting for MSPEVN_CREATE_CHANNEL_DONE");
return FAILURE;
}
// connect mspp endpoints
ret = mspConnect(rtp_ephd, msphd, MSP_NO_CONNECT );
if (! WaitForSpecificEvent(MSPEVN_CONNECT_DONE, &Event, 5000))
{
printf("Failed waiting for MSPEVN_CONNECT_DONE");
return FAILURE;
}
// enable channel
mspEnableChannel( mspHd );
if (! WaitForSpecificEvent(MSPEVN_ENABLE_CHANNEL_DONE, &Event, 5000))
{
printf("Failed waiting for MSPEVN_ENABLE_CHANNEL_DONE");
return FAILURE;
}
//adiStartProtocol
adiStartProtocol( ctahd, "nocc", NULL, NULL );
if (! WaitForSpecificEvent (ADIEVN_STARTPROTOCOL_DONE, &Event, 5000))
{
printf("Failed to receive ADIEVN_STARTPROTOCOL_DONE event");
return FAILURE;
}
// get cg6xxx board handle
ret = mspGetFilterHandle( msphd, MSP_FILTER_JITTER, &cg6xxx_board_filter_handle );
ADI_NATIVE_CONTROL parms = {0}; /* Native parameters */
parms.frameFormat = 0;
parms.include2833 = 0;
parms.vadFlag = 0;
parms.nsPayload = 0;
parms.mode = ADI_NATIVE;
parms.rec_encoding = ADI_ENCODE_EDTX_MU_LAW;
parms.payloadID = 0;
ret = adiSetNativeInfo( ctahd, cg6xxx_board_filter_handle,
NULL, /* this is record only so no egress handle */
&parms);
// get default adi record parms
ADI_RECORD_PARMS recparms;
ret = ctaGetParms( ctahd, ADI_RECORD_PARMID, &recparms, sizeof(ADI_RECORD_PARMS) );
recparms.novoicetime = 0;
recparms.silencetime = 0;
recparms.beeptime = 0
ret = adiRecordToMemory( ctahd, ADI_ENCODE_EDTX_MU_LAW, /* audio rec */
MemoryBuffer, RecordedBytes, &recparms );