# adiStartPlaying

Starts a playing operation using a callback routine to get data. This function is not supported when Natural Access is running in client/server mode.

#### Supported board types

- AG

- CG

#### Prototype

DWORD adiStartPlaying ( CTAHD ctahd, unsigned encoding, ADIPLAY_ACCESS access, void *userarg, ADI_PLAY_PARMS *parms)

Argument | Description
ctahd | Context handle returned by ctaCreateContext or ctaAttachContext.
encoding | Data encoding selection. See Voice encoding formats for a complete list.
access | Pointer to a callback function that supplies data to be played. See the Details section for a prototype of this function.
userarg | An arbitrary pointer or value to be passed to the callback function every time it is invoked.
parms | Pointer to play parameters according to the following structure (NULL value uses default values): typedef struct { /* parms related to adiStartPlaying: */ DWORD size; /* size of this structure */ DWORD DTMFabort; /* abort on DTMF */ INT32 gain; /* playing gain in dB */ DWORD speed; /* initial speed in percent */ DWORD maxspeed; /* maximum play speed in percent */ } ADI_PLAY_PARMS; Refer to ADI_PLAY_PARMS for field descriptions.

#### Return values

Return value | Description
SUCCESS |
ADIERR_INVALID_CALL_STATE | Function not valid in the current call state.
CTAERR_BAD_ARGUMENT | Invalid encoding.
CTAERR_FUNCTION_ACTIVE | Function already started.
CTAERR_INVALID_CTAHD | Context handle is invalid.
CTAERR_INVALID_STATE | Function not valid in the current port state.
CTAERR_NO_MEMORY | Could not allocate an internal buffer.
CTAERR_NOT_IMPLEMENTED | Function not implemented.
CTAERR_OUTPUT_ACTIVE | Play failed because there is another active output function.
CTAERR_SVR_COMM | Server communication error.

#### Events

Event | Description
ADIEVN_PLAY_DONE | Playing terminated, with one of the following reasons in the value field: CTAERR_xxx or ADIERR_xxx Error codes indicate play failed. CTA_REASON_DIGIT Aborted due to DTMF. CTA_REASON_FINISHED ADI service finished playing the last buffer. CTA_REASON_RECOGNITION Aborted because of speech recognition. CTA_REASON_RELEASED Call terminated. CTA_REASON_STOPPED Stopped by application request.

#### Details

When recording or playing speech files on AG boards, a specific DSP
file must be loaded for each encoding type. For more information, refer to Voice encoding formats.

When recording or playing speech files on CG boards, a specific DSP file must be loaded for each encoding type except when using the native play and record feature. The native play and record feature combines an ADI port with an MSPP endpoint and plays or records speech data directly to or from an IP endpoint with no transcoding. For information about the native play and record feature, refer to Performing NMS native play and record.

For more information, see Encoding formats and DSP files. The table lists the DSP files that must be loaded on AG and CG boards. Refer to the board installation and developer's manual for MIPS
usage.

The ADI service allocates a buffer and invokes the access function provided by the programmer. The buffer and size are passed to the callback function and the application must fill the buffer with voice data (for example, read data from a file) before returning.

access is invoked from within adiStartPlaying for the first buffer and subsequently invoked from within ctaWaitEvent. The prototype for the callback function is:

int NMSSTDCALL access ( void *userarg, void *buffer, unsigned size, unsigned *rsize )

Argument | Description
userarg | Pointer to value previously passed to adiStartPlaying.
buffer | Pointer to memory to be filled with voice data.
size | Size (bytes) of the buffer.
rsize | Returned number of bytes of voice data put into the buffer by the callback routine. This value is returned to the ADI service.

access has the following return values:

Return value | Description
SUCCESS | Play continues as normal. The ADI service invokes access again when needed.
ADI_PLAY_LAST_BUFFER | When the ADI service finishes playing the buffer being returned from access, ADIEVN_PLAY_DONE is generated with the value field set to CTA_REASON_FINISHED. access is not invoked again for the current playing instance.

If the access return value is neither SUCCESS nor ADI_PLAY_LAST_BUFFER, the ADI service immediately terminates the playing instance. ADIEVN_PLAY_DONE is generated and the value field is set to ADIERR_PLAYREC_ACCESS.

access returns the number of bytes written to the buffer in the rsize variable. If the returned size is larger than the buffer or the returned size is not a multiple of the framesize for the given encoding, the ADI service terminates the play function and generates ADIEVEN_PLAY_DONE and the value field is set to CTAERR_BAD_SIZE.

Note: Starting a play operation with the maxspeed parameter greater than 100 consumes additional DSP cycles. You may not be able to run the number of ports normally supported. Refer to the board installation and developer's manual for more information.

For more information, refer to Playing.

#### See also

adiGetPlayStatus, adiModifyPlayGain, adiModifyPlaySpeed, adiPlayAsync, adiPlayFromMemory, adiSetNativeInfo, adiStopPlaying

#### Example

This example shows a fragment of a program that plays the file test.vce using adiStartPlaying and the associated access routine.

int NMSSTDCALL readAccess (
void *userarg,
void *buffer,
unsigned size,
unsigned *rsize )
{
FILE *fp = (FILE *)userarg;
*rsize = fread( buffer, 1, size, fp );
if ( ferror( fp ) )
return -1;
if ( feof( fp ) )
return ADI_PLAY_LAST_BUFFER;
return SUCCESS;
}
int myPlayFile( CTAHD ctahd, unsigned encoding, char *filename )
{
CTA_EVENT event;
FILE *fp;
/* note: binary open */
if( (fp = fopen( filename, "rb" )) == NULL )
return MYFAILURE;
if( adiStartPlaying( ctahd, encoding, readAccess, fp, NULL ) != SUCCESS )
return MYFAILURE;
do
{
myGetEvent( &event ); /* see ctaWaitEvent example */
} while( event.id != ADIEVN_PLAY_DONE );
if( event.value == CTA_REASON_RELEASED )
return MYDISCONNECT; /* call has been terminated */
else if( CTA_IS_ERROR( event.value ) )
return MYFAILURE; /* API error */
else
return SUCCESS; /* stopped normally */
}