ec_stream( )
Cautions | Example | Errors | See Also
Description
The ec_stream( ) function streams echo-cancelled data to a callback function on a CSP-capable full-duplex channel. This user-defined callback function is called every time the driver fills the driver buffer with data. See ECCH_XFERBUFFERSIZE in the ec_setparm( ) function description for information on setting the driver buffer size.
This function is designed specifically for use in ASR applications where echo-cancelled data must be streamed to the host application in real time for further processing, such as comparing the speech utterance against an employee database and then connecting the caller to the intended audience.
You can perform voice streaming at all times or voice-activated streaming. The ECCH_VADINITIATED parameter in ec_setparm( ) controls voice-activated streaming, where recording begins only after speech energy has been detected. This parameter is enabled by default.
The user-defined callback function is similar to the C library write( ) function. Its prototype is:
int callback (int chDev, char *buffer, uint length)
where:This user-defined callback function returns the number of bytes contained in length upon success. Any other value is viewed as an error and streaming is terminated. We do not recommend terminating the streaming activity in this way; instead, use ec_stopch( ).
We recommend that inside the user-defined callback function you:
- do not call another Dialogic function
- do not call a blocking function such as sleep
- do not call an I/O function such as printf, scanf, and so on (although you may use these for debugging purposes)
We recommend that inside the user-defined callback function you do the following:
- Copy the buffer contents for processing in another context.
- Signal the other context to begin processing.
Cautions
- This function fails if an unsupported data format is specified. For a list of supported data formats, see Continuous Speech Processing API Programming Guide.
- We recommend that you specify the ec_stream( ) function before a voice play function in your application.
- On SpringWare boards, we recommend that you use the same data format for play and recording/streaming.
- To set the proper parameters, the ec_setparm( ) function must be called for every ec_stream( ) occurrence in your application.
- If you use this function in synchronous mode, you must use multithreading in your application.
- In Linux applications that use multiple threads, you must avoid having two or more threads call functions that send commands to the same channel; otherwise, the replies can be unpredictable and cause those functions to time out. If you must do this, use semaphores to prevent concurrent access to a particular channel.
- All files recorded to have the data encoding and rate as described in DX_XPB.
- The DX_XPB data area must remain in scope for the duration of the function if running asynchronously.
Example
#include <windows.h> /* include in Windows applications only; exclude in Linux */ #include <stdio.h> #include <srllib.h> #include <dxxxlib.h> #include <eclib.h> #include <errno.h> /* include in Linux applications only; exclude in Windows */ main() { char csp_devname[9]; int ret, csp_dev, parmval=0; SC_TSINFO sc_tsinfo; /* Time slot information structure */ long scts; /* SCbus time slot */ int srlmode; /* Standard Runtime Library mode */ DX_IOTT iott; /* I/O transfer table */ DV_TPT tptp[1], tpt; /* termination parameter table */ DX_XPB xpb; /* I/O transfer parameter block */ /* Set SRL to run in polled mode. */ srlmode = SR_POLLMODE; if (sr_setparm(SRL_DEVICE, SR_MODEID, (void *)&srlmode) == -1) { /* process error */ } /* Barge-in parameters */ int BargeIn= 1; sprintf(csp_devname,"dxxxB1C1"); /* Open a voice device. */ csp_dev = dx_open(csp_devname, 0); if (csp_dev < 0) { printf("Error %d in dx_open()\n",csp_dev); exit(-1); } /* Set up ec parameters (use default if not being set). * Enable barge-in. ECCH_VADINITIATED is enabled by default. */ ret = ec_setparm(csp_dev, DXCH_BARGEIN, (void *) &BargeIn); if (ret == -1) { printf("Error in dx_setparm(). Err Msg = %s, Lasterror = %d\n", ATDV_ERRMSGP(csp_dev), ATDV_LASTERR(csp_dev)); } /* Set up DV_TPT for record */ tpt.tp_type = IO_EOT; tpt.tp_termno = DX_MAXTIME; tpt.tp_length = 60; tpt.tp_flags = TF_MAXTIME; /* Record data format set to 8-bit Dialogic PCM, 8KHz sampling rate */ xpb.wFileFormat = FILE_FORMAT_VOX; xpb.wDataFormat = DATA_FORMAT_PCM; xpb.nSamplesPerSec = DRT_8KHZ; xpb.wBitsPerSample = 8; ret = ec_stream(csp_dev, &tpt, &xpb, &stream_cb, EV_ASYNC | MD_NOGAIN); if (ret == -1) { printf("Error in ec_reciottdata(). Err Msg = %s, Lasterror = %d\n", ATDV_ERRMSGP(csp_dev), ATDV_LASTERR(csp_dev)); } /* Set channel off-hook */ ret = dx_sethook(csp_dev, DX_OFFHOOK, EV_SYNC); if (ret == -1) { printf("Error in dx_sethook(). Err Msg = %s, Lasterror = %d\n", ATDV_ERRMSGP(csp_dev), ATDV_LASTERR(csp_dev)); } /* Set up DX_IOTT */ iott.io_type = IO_DEV|IO_EOT; iott.io_bufp = 0; iott.io_offset = 0; iott.io_length = -1; /* Set up DV_TPT for play */ dx_clrtpt(&tptp,1); tptp[0].tp_type = IO_EOT; tptp[0].tp_termno = DX_MAXDTMF; tptp[0].tp_length = 1; tptp[0].tp_flags = TF_MAXDTMF; /* Open file to be played */ #ifdef WIN32 if ((iott.io_fhandle = dx_fileopen("sample.vox",O_RDONLY|O_BINARY)) == -1) { printf("Error opening sample.vox.\n"); exit(1); } #else if (( iott.io_fhandle = open("sample.vox",O_RDONLY)) == -1) { printf("File open error\n"); exit(2); } #endif /* Play prompt message. */ ret = dx_play(csp_dev, &iott, &tptp, EV_ASYNC); if ( ret == -1) { printf("Error playing sample.vox.\n"); exit(1); } /* Wait for barge-in and echo-cancelled record to complete */ while (1) { sr_waitevt(-1); ret = sr_getevttype(); if (ret == TDX_BARGEIN) { printf("TDX_BARGEIN event received\n"); } else if (ret == TDX_PLAY) { printf("Play Completed event received\n"); break; } else if (ret == TEC_STREAM) { printf("TEC_STREAM - termination event "); printf("for ec_stream and ec_reciottdata received.\n"); break; } else if (ret == TDX_ERROR) { printf("ERROR event received\n"); } else { printf("Event 0x%x received.\n", ret); } } /* end while */ // Set channel on hook dx_sethook(csp_dev, DX_ONHOOK, EV_SYNC); /* Close play file */ #ifdef WIN32 if (dx_fileclose(iott.io_fhandle) == -1) { printf("Error closing file.\n"); exit(1); } #else if (close(iott.io_fhandle) == -1) { printf("Error closing file. \n"); exit(1); } #endif // Close channel dx_close(csp_dev); } int stream_cb(int chDev, char *buffer, int length) { /* process recorded data here ... */ return(length); }Errors
If the function returns -1, use ATDV_LASTERR( ) to return the error code and ATDV_ERRMSGP( ) to return a descriptive error message.
One of the following error codes may be returned:
See Also
- ec_reciottdata( )
- dx_reciottdata( )
Click here to contact Dialogic Customer Engineering
Copyright 2001, Intel Corporation