<!doctype html public "-//w3c//dtd html 4.0 transitional//en"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <meta name="GENERATOR" content="Mozilla/4.73 [en] (X11; U; Linux 2.2.14 i586) [Netscape]"> <title>Programming Guide</title> </head> <body link="#0000FF" vlink="#800080"> <h1> <b>Programming</b></h1> <b>Introduction</b> <p><font size=-1>The Voicetronix Voice Processing Board (VPB) is programmed via the VPB Application Programmer Interface (VPB API, or just API). This is a set of C callable functions provided as a Windows 32 bit DLL.</font> <p><font size=-1>The following sections describe the VPB API in detail, and also include examples of the API functions in action.</font> <p><font size=-1>It is recommended that the user browse the header file <i>vpbapi.h</i> to gain an overview of the API.</font> <p><b>Compiling with the API</b> <p><font size=-1>All of the examples have been tested using Microsoft Visual C 4.2. Compiler specific instructions refer to this compiler.</font> <p><font size=-1>To use the API, first make sure <i>vpbapi.dll</i> is in your windows directory (the installation should have done this). Include <i>vpbapi.h</i> in your source files, and link your application with <i>vpbapi.lib</i> (build-settings-link tab, then add <i>vpbapi.lib</i> to the Object/library modules box).</font> <p><font size=-1>The API will only work with 32 bit applications.</font> <p><b>Initialisation and Shutdown</b> <p><font size=-1>This section describes the "housekeeping" functions used to initialise and shutdown a VPB. The initialisation function </font><u><font face="Courier"><font size=-2>vpb_open()</font></font></u><font size=-1> must be called before any other API functions will work:</font> <p><font face="Courier"><font size=-2>void main() {</font></font> <p><font face="Courier"><font size=-2>handle = vpb_open(1, 2);</font></font> <p><font face="Courier"><font size=-2>vpb_close(handle);</font></font> <p><font face="Courier"><font size=-2>}</font></font> <br> <br> <p><font size=-1>This program demonstrates initialisation and shutdown of a single channel, (number 2), on the first board in the system. Each channel (or port) of the VPB has an associated number, from 1 to 4, counting from the top of the VPB to the bottom.</font> <p><font size=-1>The </font><u><font face="Courier"><font size=-2>vpb_open()</font></font></u><font size=-1> function returns a <u>handle</u> to the open channel. This handle then provides a reference to all other operations with this channel.</font> <p><font size=-1>A call to </font><u><font face="Courier"><font size=-2>vpb_open()</font></font></u><font size=-1> is required for each channel that is to be used. If a channel is not opened, then no operations can be performed with that channel.</font> <br> <br> <p><font size=-1>An Integer that uniquely identifies a channel when using VPB API functions.</font> <br> <br> <p><b>Numbering of Channels with Multiple VPBs</b> <p><font size=-1>In systems with multiple VPBs, the numbering of each channel depends on the order that each card appears (see below). The first port of second card will be channel 5; the first port of the third card will be channel 9 and so on.</font> <p><b>To Determine the Channel Numbering of VPBs under Windows 95</b> <p><font size=-1>For Windows 95 the ordering of the VPBs corresponds to the order of the VPB Adapter entries in the Device Manager tab of the System applet of the Control Panel. The first (top most) VPB Adapter corresponds to channels 1 to 4, the second VPB Adapter entry channels 5 to 8 etc.</font> <p><font size=-1>By examining the base address of each VPB Adapter (with a VPB Adapter entry selected, press Properties, then select the Resources tab), the corresponding card can be identified. The base address of this particular VPB Adapter will be listed in the Resource Settings Box. The left most number is the base address. The base address can be compared to the DIPswitch setting on each card to determine the VPB ordering. See "Installation" section of this help for more information.</font> <p><b>To Determine the Channel Numbering of VPBs under Windows NT</b> <p><font size=-1>For Windows NT the ordering of the cards depends on the ordering of the sub keys in the HKEY_LOCAL_MACHINE, System, CurrentControlSet, Services, vpb registry entry. The first (top most) subkey corresponds to channels 1 to 4, the second subkey entry to channels 5 to 8 etc. The base address of each subkey can be compared to the DIPswitch setting on each card to determine the VPB ordering. See "Installation" section of this help for more information.</font> <br> <br> <p><b>Error Handling</b> <p><font size=-1>Under certain conditions the API functions will be unable to successfully execute. In this case an error condition will occur that requires handling by code outside of the API. The API provides three mode of error handling:</font> <ul> <li> <u><font size=-1>Debug</font></u></li> <li> <u><font size=-1>Exceptions</font></u></li> <li> <u><font size=-1>Error codes</font></u></li> </ul> <font size=-1>The current error mode is set using the </font><u><font face="Courier"><font size=-2>vpb_seterrormode()</font></font></u><font size=-1> function. The default error mode <u>Debug</u></font> <br> <br> <p><b>Debug</b> <p><font size=-1>If an error occurs in this mode, the program stops execution immediately and prints an error message. This is useful during debugging as it brings any problems to the programmer?s immediate attention. However, such behavior is obviously not desirable in release versions of the software. Note that this mode is only suitable for <i>console</i> mode programs, it will cause the program to hang when used with a windows program.</font> <br> <br> <p><b>Error Codes</b> <p><font size=-1>In this case the function returns an integer corresponding to the nature of the error. The convention used by the API is that positive numbers and zero indicate successful function completion, and negative numbers represent an error condition. The error codes for the API functions are listed in </font><font face="Courier"><font size=-2>VPBERR.H</font></font><font size=-1>. There are other, undocumented error codes that lower levels of the API software may return, but these are not defined in </font><font face="Courier"><font size=-2>VPBERR.H</font></font><font size=-1>. These errors should not occur during normal operation.</font> <br> <br> <p><b>Exceptions</b> <p><font size=-1>Exceptions are a form of error handling supported by C++. When an error occurs, an exception is "thrown". In the case of the VPB API, the exception is a class </font><u><font face="Courier"><font size=-2>VpbException</font></font></u><font size=-1> that contains information describing the error. The code member of the class corresponds to an error number defined exactly the same way as in the <u>error code</u> error handling method. The other members contain strings describing the API function that generated the error and a brief translation of the error code.</font> <p><font size=-1>The user must provide code to catch the exception at some level in their program. The advantage of exceptions is that it is not necessary to trap errors at every API call, which can become tedious from a programming point of view, especially for API calls deep within nested function calls.</font> <p><font size=-1>Consider the following code fragments, first using error codes:</font> <p><font face="Courier"><font size=-2>vpb_seterrormode(VPB_ERROR_CODE);</font></font> <br> <br> <p><font face="Courier"><font size=-2>// Attempt to open channel 1</font></font> <br> <br> <p><font face="Courier"><font size=-2>if ((handle1 = vpb_open(1,1)) != VPB_OK) {</font></font> <p><font face="Courier"><font size=-2>printf("Error, code = %d\n",handle1);</font></font> <p><font face="Courier"><font size=-2>exit(0);</font></font> <p><font face="Courier"><font size=-2>}</font></font> <br> <br> <p><font face="Courier"><font size=-2>// Attempt to open channel 2</font></font> <br> <br> <p><font face="Courier"><font size=-2>if ((handle2 = vpb_open(1,2)) != VPB_OK) {</font></font> <p><font face="Courier"><font size=-2>printf("Error, code = %d\n",handle2);</font></font> <p><font face="Courier"><font size=-2>exit(0);</font></font> <p><font face="Courier"><font size=-2>}</font></font> <br> <br> <p><font size=-1>And now using exceptions:</font> <p><font face="Courier"><font size=-2>try {</font></font> <p><font face="Courier"><font size=-2> vpb_seterrormode(VPB_EXCEPTION);</font></font> <p><font face="Courier"><font size=-2> handle1 = vpb_open(1,1);</font></font> <p><font face="Courier"><font size=-2> handle2 = vpb_open(1,2);</font></font> <p><font face="Courier"><font size=-2>}</font></font> <p><font face="Courier"><font size=-2>catch (VpbException v) {</font></font> <dir> <dir> <dir> <dir><font face="Courier"><font size=-2>printf("Error, code = %d, s = %s, api func = %s\n",</font></font> <p><font face="Courier"><font size=-2>v.code, v.s, v.api_function);</font></font></dir> </dir> </dir> </dir> <font face="Courier"><font size=-2>exit(0);</font></font> <p><font face="Courier"><font size=-2>}</font></font> <br> <br> <p><font size=-1>Using exceptions enables the programmer to send all run time errors to a single point in the code, removing the need for handling errors after every API call. If the current function does not have try/catch exception handling, then the compiler aborts the current function, climbing up the "call stack" until an exception handler is found in a calling function. If no exception handler is found in the calling functions, the program aborts.</font> <p><font size=-1>For more information on exceptions, see a C++ text, or your C++ compiler on-line documentation.</font> <br> <br> <br> <br> <br> <br> <table BORDER=0 CELLSPACING=0 CELLPADDING=7 WIDTH="460" > <tr> <td VALIGN=TOP COLSPAN="4"><sup>class VpbException {</sup></td> </tr> <tr> <td VALIGN=TOP COLSPAN="2" WIDTH="18%"><font face="Courier"><font size=-2>public:</font></font></td> <td VALIGN=TOP COLSPAN="2" WIDTH="82%"> </td> </tr> <tr> <td VALIGN=TOP WIDTH="8%"> </td> <td VALIGN=TOP WIDTH="10%"><font face="Courier"><font size=-2>int</font></font></td> <td VALIGN=TOP WIDTH="47%"><font face="Courier"><font size=-2>code;</font></font></td> <td VALIGN=TOP WIDTH="35%"><font face="Courier"><font size=-2>// error code</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="8%"> </td> <td VALIGN=TOP WIDTH="10%"><font face="Courier"><font size=-2>char</font></font></td> <td VALIGN=TOP WIDTH="47%"><font face="Courier"><font size=-2>s[VPB_MAX_STR];</font></font></td> <td VALIGN=TOP WIDTH="35%"><font face="Courier"><font size=-2>// code translated</font></font> <p><font face="Courier"><font size=-2>// into string</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="8%"> </td> <td VALIGN=TOP WIDTH="10%"><font face="Courier"><font size=-2>char</font></font></td> <td VALIGN=TOP WIDTH="47%"><font face="Courier"><font size=-2>api_function[VPB_MAX_STR];</font></font></td> <td VALIGN=TOP WIDTH="35%"><font face="Courier"><font size=-2>// api func that </font></font> <p><font face="Courier"><font size=-2>// threw exception</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="8%"> </td> <td VALIGN=TOP WIDTH="10%"> </td> <td VALIGN=TOP WIDTH="47%"> </td> <td VALIGN=TOP WIDTH="35%"> </td> </tr> <tr> <td VALIGN=TOP WIDTH="8%"> </td> <td VALIGN=TOP COLSPAN="3" WIDTH="92%"><font face="Courier"><font size=-2>VpbException(int c, char trans[], char api_function[]);</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="8%"><font face="Courier"><font size=-2>};</font></font></td> <td VALIGN=TOP COLSPAN="3" WIDTH="92%"> </td> </tr> </table> <br> <br> <p><b>Events</b> <p><font size=-1>The VPB API uses an event driven programming model. There are two types of events, <u>solicted</u>, and <u>unsolicited</u>. The following functions deal with events:</font> <p><u><font face="Courier"><font size=-2>vpb_disable_event()</font></font></u> <p><u>vpb_enable_event( )</u> <p><u>vpb_get_event_mask( )</u> <p><u>vpb_set_event_mask( )</u> <p><u>vpb_get_event_async( )</u> <p><u>vpb_get_event_sync( )</u> <p><u>vpb_get_event_ch_async( )</u> <p><u>vpb_get_event_ch_sync( )</u> <p><u>vpb_put_event( )</u> <br> <br> <br> <br> <p><b>Play Functions</b> <p><font size=-1>The API play functions are listed below:</font> <p><u><font face="Courier"><font size=-2>vpb_play_file_sync()</font></font></u> <p><u>vpb_play_file_async( )</u> <p><u>vpb_play_voxfile_sync( )</u> <p><u>vpb_play_voxfile_async( )</u> <p><u>vpb_play_terminate( )</u> <p><u>vpb_play_buf_start( )</u> <p><u>vpb_play_buf_sync( )</u> <p><u>vpb_play_buf_finish( )</u> <p><u>vpb_play_set( )</u> <p><u>vpb_play_set gain( )</u> <p><u>vpb_play_get gain( )</u> <br> <br> <p><b>Notes on the use of the Play Functions</b> <p><img SRC="Image1.gif" height=20 width=11><font size=-1>The VPB API supports the playing of wave and <u>vox</u> files through the <u>utility play</u> routines. It also accommodates the playing of buffers from memory via the <u>user defined play routines</u>. The play functions can be configured to terminate when a DTMF digit is received using </font><u><font face="Courier"><font size=-2>vpb_play_set()</font></font></u><font size=-1>. The play functions may be prematurely stopped using </font><u><font face="Courier"><font size=-2>vpb_play_terminate()</font></font></u><font size=-1>. The API provides a function to alter the VPB audio out levels within the range of -12 to 12 dB (0.1dB resolution). This is accomplished by </font><u><font face="Courier"><font size=-2>vpb_play_set gain()</font></font></u> <br> <br> <p><b>Record Functions</b> <br><font size=-1>The API record functions are listed below:</font> <p><u><font face="Courier"><font size=-2>vpb_record_file_sync()</font></font></u> <p><u>vpb_record_file_async( )</u> <p><u>vpb_record_voxfile_sync( )</u> <p><u>vpb_record_voxfile_async( )</u> <p><u>vpb_record_terminate( )</u> <p><u>vpb_record_buf_start( )</u> <p><u>vpb_record_buf_sync( )</u> <p><u>vpb_record_buf_finish( )</u> <p><u>vpb_record_set( )</u> <p><u>vpb_record_set_gain( )</u> <p><u>vpb_record_get_gain( )</u> <br> <br> <p><b>Notes on the use of the Record Functions</b> <p><img SRC="Image1.gif" height=20 width=11><font size=-1>The VPB API supports the recording of wave and <u>vox</u> files through the <u>utility record routines</u>. It also accommodates the recording of audio to memory via the <u>user defined record</u> routines. The record functions can be configured to terminate when a DTMF digit is received using </font><u><font face="Courier"><font size=-2>vpb_record_set()</font></font></u><font size=-1>. The record functions may be prematurely stopped using </font><u><font face="Courier"><font size=-2>vpb_record_terminate()</font></font></u><font size=-1>. The API provides a function to alter the VPB audio in levels within the range of -12 to 12 dB (0.1dB resolution). This is accomplished by </font><u><font face="Courier"><font size=-2>vpb_record_set gain()</font></font></u><font size=-1>.</font> <br> <br> <p><b>Playing Audio Data</b> <p><font size=-1>The API functions for playing audio are divided into two groups; utility functions, and user defined functions.</font> <p><b>Utility Play Functions</b> <p><font size=-1>The utility play functions are designed to make playing files straightforward.</font> <p><font size=-1>The functions support wave files sampled at 8ksamples/s only, playing files that follow the wave file layout specification including 16 bit Linear, 8 bit A-Law & 8 bit Mu-Law.</font> <p><u><font face="Courier"><font size=-2>vpb_play_file_sync()</font></font></u> <p><u>vpb_play_file_async( )</u> <br> <br> <p><font size=-1>There are also utility play functions that support <u>vox</u> audio files sampled at 8ksamples/s including; 16 bit Linear, 8 bit A-Law, 8 bit Mu-Law & 4 bit ADPCM.</font> <p><u><font face="Courier"><font size=-2>vpb_play_voxfile_sync()</font></font></u> <p><u>vpb_play_voxfile_async( )</u> <br> <br> <p><b>User Defined Play Functions</b> <p><font size=-1>The user defined play functions allow the development of custom play routines in situations where the utility functions are inappropriate, for example, when playing buffers from memory or when using non wave/vox file formats:</font> <p><u><font face="Courier"><font size=-2>vpb_play_buf_start()</font></font></u> <p><u>vpb_play_buf_sync( )</u> <p><u>vpb_play_buf_finish( )</u> <br> <br> <br> <p><font size=-1>Compression (encoding) mode used to store samples.</font> <br> <br> <table BORDER=0 CELLSPACING=0 CELLPADDING=7 WIDTH="568" > <tr> <td VALIGN=TOP WIDTH="28%"><b><font size=-1>Mode</font></b></td> <td VALIGN=TOP WIDTH="72%"><b><font size=-1>Description</font></b></td> </tr> <tr> <td VALIGN=TOP WIDTH="28%"><font size=-1>VPB_LINEAR</font></td> <td VALIGN=TOP WIDTH="72%"><font size=-1>128kbit/s, 16 bit linear, 8kHz sampling rate</font></td> </tr> <tr> <td VALIGN=TOP WIDTH="28%"><font size=-1>VPB_ALAW</font></td> <td VALIGN=TOP WIDTH="72%"><font size=-1>64kbit/s, A-Law companded</font></td> </tr> <tr> <td VALIGN=TOP WIDTH="28%"><font size=-1>VPB_MULAW</font></td> <td VALIGN=TOP WIDTH="72%"><font size=-1>64kbit/s, Mu-Law companded</font></td> </tr> <tr> <td VALIGN=TOP WIDTH="28%"><font size=-1>VPB_OKIADPCM</font></td> <td VALIGN=TOP WIDTH="72%"><font size=-1>32kbit/s, Oki-ADPCM, 4 bit, 8kHz sampling rate</font></td> </tr> <tr> <td VALIGN=TOP WIDTH="28%"><font size=-1>VPB_OKIADPCM24</font></td> <td VALIGN=TOP WIDTH="72%"><font size=-1>24kbit/s, Oki-ADPCM, 4 bit, 6kHz sampling rate</font></td> </tr> </table> <br> <br> <p><font size=-1>Voice File Format Support</font> <br> <br> <table BORDER=0 CELLSPACING=0 CELLPADDING=7 WIDTH="568" > <tr> <td VALIGN=TOP WIDTH="25%"><b><font size=-1>Mode</font></b></td> <td VALIGN=TOP WIDTH="25%"><b><font size=-1>Wave support</font></b></td> <td VALIGN=TOP WIDTH="25%"><b><font size=-1>Vox support</font></b></td> <td VALIGN=TOP WIDTH="25%"><b><font size=-1>Platform</font></b></td> </tr> <tr> <td VALIGN=TOP WIDTH="25%"><font size=-1>VPB_LINEAR</font></td> <td VALIGN=TOP WIDTH="25%"><font size=-1>YES</font></td> <td VALIGN=TOP WIDTH="25%"><font size=-1>YES</font></td> <td VALIGN=TOP WIDTH="25%"><font size=-1>VPB4, VPB8L</font></td> </tr> <tr> <td VALIGN=TOP WIDTH="25%"><font size=-1>VPB_ALAW</font></td> <td VALIGN=TOP WIDTH="25%"><font size=-1>YES</font></td> <td VALIGN=TOP WIDTH="25%"><font size=-1>YES</font></td> <td VALIGN=TOP WIDTH="25%"><font size=-1>VPB4, VPB8L</font></td> </tr> <tr> <td VALIGN=TOP WIDTH="25%"><font size=-1>VPB_MULAW</font></td> <td VALIGN=TOP WIDTH="25%"><font size=-1>YES</font></td> <td VALIGN=TOP WIDTH="25%"><font size=-1>YES</font></td> <td VALIGN=TOP WIDTH="25%"><font size=-1>VPB4, VPB8L</font></td> </tr> <tr> <td VALIGN=TOP WIDTH="25%"><font size=-1>VPB_OKIADPCM</font></td> <td VALIGN=TOP WIDTH="25%"><font size=-1>NO</font></td> <td VALIGN=TOP WIDTH="25%"><font size=-1>YES</font></td> <td VALIGN=TOP WIDTH="25%"><font size=-1>VPB4, VPB8L</font></td> </tr> <tr> <td VALIGN=TOP WIDTH="25%"><font size=-1>VPB_OKIADPCM24</font></td> <td VALIGN=TOP WIDTH="25%"><font size=-1>NO</font></td> <td VALIGN=TOP WIDTH="25%"><font size=-1>YES</font></td> <td VALIGN=TOP WIDTH="25%"><font size=-1>VPB8L</font></td> </tr> </table> <br> <br> <br> <br> <p><font size=-1>Generic name for the file format (raw audio files) traditionally used by Dialogic hardware.</font> <br> <br> <p><b>Recording Audio Data</b> <p><font size=-1>The API functions for recording audio are divided into two groups; utility functions and user defined functions.</font> <p><b>Utility Record Functions</b> <p><font size=-1>The utility record functions are designed to make recording files straightforward.</font> <p><font size=-1>The functions support wave files sampled at 6 and 8 ksamples/s, recording audio to files that follow the wave file layout specification including 16 bit Linear, 8 bit A-Law & 8 bit Mu-Law.</font> <p><u><font face="Courier"><font size=-2>vpb_record_file_sync()</font></font></u> <p><u>vpb_record_file_async( )</u> <br> <br> <p><font size=-1>There are also utility record functions that support <u>vox</u> audio files sampled at 6 and 8 ksamples/s including; 16 bit Linear, 8 bit A-Law, 8 bit Mu-Law & 4 bit ADPCM.</font> <p><u><font face="Courier"><font size=-2>vpb_record_voxfile_sync()</font></font></u> <p><u>vpb_record_voxfile_async( )</u> <p><b>User Defined Record Functions</b> <p><font size=-1>The user defined record functions allow the development of custom record routines in situations where the utility functions are inappropriate, for example, when recording buffers to memory or when using non wave/vox file formats:</font> <p><u><font face="Courier"><font size=-2>vpb_record_buf_start()</font></font></u> <p><u>vpb_record_buf_sync( )</u> <p><u>vpb_record_buf_finish( )</u> <br> <br> <p><b>DTMF and Programmable Tone Generation</b> <p><font size=-1>The following functions support tone generation on the VPB:</font> <p><u><font face="Courier"><font size=-2>vpb_dial_async()</font></font></u> <p><u>vpb_dial_sync( )</u> <p><u>vpb_settone( )</u> <p><u>vpb_gettone( )</u> <br> <br> <p><b>Notes on Tone Generation</b> <p><font size=-1>Tones (including DTMF) tones are generated on a channel using the <u>vpb_settone( ) function</u>.</font> <p><font size=-1>All of the <u>standard DTMF tones</u> are defined at initialisation. Other user defined tones can be programmed at any time using the <u>vpb_settone( ) function</u>.</font> <p><font size=-1>The <u>standard DTMF tones</u> can also be reprogrammed using the <u>vpb_settone( ) function.</u></font> <p><font size=-1>The tone generator parameters are constant across all VPB channels, they are not programmable on a channel by channel or board by board basis.</font> <p><font size=-1>Up to 10 programmable tones can be defined, giving a total of 26 tones including the <u>standard DTMF tones</u>.</font> <p><font size=-1>Each tone can consist of up to 3 frequency components, each with independent amplitude, specified in dB with respect to the overload level of 0dB.</font> <p><font size=-1>There are limits in the tone generator <u>parameters</u>. Attempting to program a tone outside of these <u>limits</u> will generate an error.</font> <br> <br> <p><font size=-1>0,1,2,3,4,5,6,7,8,9,#,*,A,B,C,D</font> <br> <br> <p><font face="Courier"><font size=-2>typedef struct {</font></font> <p><font face="Courier"><font size=-2>unsigned short freq1; // frequency of first tone</font></font> <p><font face="Courier"><font size=-2>unsigned short freq2; // frequency of second tone</font></font> <p><font face="Courier"><font size=-2>unsigned short freq3; // frequency of third tone</font></font> <p><font face="Courier"><font size=-2>short level1; // first tone level in dB, -1dB maximum</font></font> <p><font face="Courier"><font size=-2>short level2; // second tone level in dB, -1dB maximum</font></font> <p><font face="Courier"><font size=-2>short level3; // third tone level in dB, -1dB maximum</font></font> <p><font face="Courier"><font size=-2>unsigned long ton; // on time ms</font></font> <p><font face="Courier"><font size=-2>unsigned long toff; // off time ms</font></font> <p><font face="Courier"><font size=-2>} VPB_TONE;</font></font> <br> <br> <p><b>Tone Generator Limits</b> <br> <br> <table BORDER=0 CELLSPACING=0 CELLPADDING=7 WIDTH="511" > <tr> <td VALIGN=TOP WIDTH="45%"><b><font size=-1>Parameter</font></b></td> <td VALIGN=TOP WIDTH="28%"><b><font size=-1>Minimum</font></b></td> <td VALIGN=TOP WIDTH="27%"><b><font size=-1>Maximum</font></b></td> </tr> <tr> <td VALIGN=TOP WIDTH="45%"><font face="Courier"><font size=-2>freq1, freq2, freq3</font></font></td> <td VALIGN=TOP WIDTH="28%"><font size=-1>0 Hz</font></td> <td VALIGN=TOP WIDTH="27%"><font size=-1>4000 Hz</font></td> </tr> <tr> <td VALIGN=TOP WIDTH="45%"><font face="Courier"><font size=-2>level1, level2, level3</font></font></td> <td VALIGN=TOP WIDTH="28%"><font size=-1>none</font></td> <td VALIGN=TOP WIDTH="27%"><font size=-1>-1 dB</font></td> </tr> <tr> <td VALIGN=TOP WIDTH="45%"><font face="Courier"><font size=-2>Ton</font></font></td> <td VALIGN=TOP WIDTH="28%"><font size=-1>0</font></td> <td VALIGN=TOP WIDTH="27%"><img SRC="Image7.gif" height=20 width=44><font size=-1>ms</font></td> </tr> <tr> <td VALIGN=TOP WIDTH="45%"><font face="Courier"><font size=-2>Toff</font></font></td> <td VALIGN=TOP WIDTH="28%"><font size=-1>0</font></td> <td VALIGN=TOP WIDTH="27%"><img SRC="Image8.gif" height=21 width=80><font size=-1>ms</font></td> </tr> </table> <br> <br> <p><b>Tone Detection</b> <p><font size=-1>The following functions support programmable tone detection:</font> <p><u><font face="Courier"><font size=-2>vpb_settonedet()</font></font></u> <p><u>vpb_gettonedet( )</u> <p><u>vpb_debug_tonedet( )</u> <p><u>vpb_tonedet_make_default( )</u> <br> <br> <p><b>Notes on Tone Detection</b> <p><font size=-1>When a tone is detected, a </font><font face="Courier"><font size=-2>VPB_TONEDETECT</font></font><font size=-1> event is placed on the event queue with the tone identifier placed in the data element of the <u>event </u>structure.</font> <p><font size=-1>There are 3 pre-defined tones, </font><font face="Courier"><font size=-2>VPB_DIAL</font></font><font size=-1> (dial tone), </font><font face="Courier"><font size=-2>VPB_RINGBACK</font></font><font size=-1> (ringback), and </font><font face="Courier"><font size=-2>VPB_BUSY</font></font><font size=-1> (busy tone). These are configured for Austel standard tones and may be redefined if desired to suit the actual switch the VPB is connected to.</font> <p><font size=-1>Up to </font><font face="Courier"><font size=-2>VPB_MD (#define in vpbapi.h) </font></font><font size=-1>tone detectors can be defined for each channel of each VPB. Counting the 3 pre-defined tones, </font><font face="Courier"><font size=-2>VPB_MD-3</font></font><font size=-1> new user defined tones are available for the user, or the pre-defined tones may be redefined to give a total of </font><font face="Courier"><font size=-2>VPB_MD</font></font><font size=-1> user defined tones. To redefine a pre-defined tone, just specify the pre-defined tone identifier in the </font><font face="Courier"><font size=-2>tone_id</font></font><font size=-1> parameter of the </font><u><font face="Courier"><font size=-2>VPB_DETECT</font></font></u><font size=-1> structure when <u>programming</u> the tone.</font> <p><font size=-1>Note: The </font><font face="Courier"><font size=-2>VPB_MD (#define in vpbapi.h)</font></font><font size=-1> is set by Voicetronix and should not be modified by the user. Up to ten programmable tones (including the pre-defined tones) are available for the user.</font> <p><font size=-1>The tone detectors of each channel are independent of the tone detectors of other channels. Thus each channel must be programmed independently with the </font><u><font face="Courier"><font size=-2>vpb_settonedet()</font></font></u><font size=-1>API function.</font> <br> <br> <p><b>Programming the Tone Detectors</b> <p><font size=-1>The tone detection algorithm is split into two phases. The first phase checks an incoming signal to determine if its signal parameters fit the templates defined in the tone detector, for example, the frequency, bandwidth, level, and signal to noise ratio (SNR). The second phase looks at the on-off timing of the signal, or cadence information. If both the signal parameters and the cadence parameters match, an event is posted.</font> <p><font size=-1>Each programmable tone has a unique identifier, i.e. a 16 bit integer that is placed in the data element of the event when the tone is detected. The value of the tone identifier is not important, as long as it is unique. If </font><font face="Courier"><font size=-2>vpb_settonedet()</font></font><font size=-1> is called with a <i>non-unique</i> identifier (one which <i>has</i> been used before), then that programmable tone is redefined. If </font><font face="Courier"><font size=-2>vpb_settonedet()</font></font><font size=-1> is called with a <i>unique</i> identifier (one which has <i>not</i> been used before), then a new programmable tone is defined.</font> <p><font size=-1>The structure </font><u><font face="Courier"><font size=-2>VPB_DETECT</font></font></u><font size=-1> is used to define a programmable tone. Single or dual frequencies can be specified, each with independent frequency, amplitude, and bandwidth. In addition, the allowable twist for dual tones (difference in level between the two tones) can be defined.</font> <p><font size=-1>Attempting to define a tone outside of the tone detector <u>limits</u> will cause an error.</font> <br> <br> <p><b>Signal Detection Algorithm</b> <p><font size=-1>For a single frequency tone to pass the signal processing phase, the following conditions must be true:</font> <ul> <li> <font size=-1>The level of the tone in the band specified by the frequency (</font><font face="Courier"><font size=-2>freq1</font></font><font size=-1>) and bandwidth (</font><font face="Courier"><font size=-2>bandwidth1</font></font><font size=-1>) must be above the minimum level (</font><font face="Courier"><font size=-2>minlevel1</font></font><font size=-1>).</font></li> <li> <font size=-1>The signal energy must be greater than the rest of energy in the received signal by the specified signal to noise ratio (</font><font face="Courier"><font size=-2>snr</font></font><font size=-1>).</font></li> </ul> <font size=-1>If the above conditions are met, then the signal is declared detected and is passed to the cadence detection stage for cadence analysis.</font> <p><font size=-1>For a dual frequency tone to pass the signal processing phase, the following conditions must be true:</font> <ul> <li> <font size=-1>The level of the first frequency component in the band specified by the frequency (freq1) and bandwidth (</font><font face="Courier"><font size=-2>bandwidth1</font></font><font size=-1>) must be above the minimum level (</font><font face="Courier"><font size=-2>minlevel1</font></font><font size=-1>).</font></li> <li> <font size=-1>The level of the second frequency component in the band specified by the frequency (</font><font face="Courier"><font size=-2>freq2</font></font><font size=-1>) and bandwidth (</font><font face="Courier"><font size=-2>bandwidth2</font></font><font size=-1>) must be above the minimum level (</font><font face="Courier"><font size=-2>minlevel2</font></font><font size=-1>).</font></li> <li> <font size=-1>The total signal energy in both bands must be greater than the rest of energy in the received signal by the specified signal to noise ratio (</font><font face="Courier"><font size=-2>snr</font></font><font size=-1>).</font></li> <li> <font size=-1>The difference in the energies of the two frequency components must be within the allowed twist (</font><font face="Courier"><font size=-2>twist</font></font><font size=-1>).</font></li> </ul> <font size=-1>If the above conditions are met, then the signal is declared detected and is passed to the cadence detection stage for cadence analysis.</font> <br> <br> <p><b>Cadence Detection Algorithm</b> <p><font size=-1>The cadence detection parameters of the tone detector are defined by constructing a state machine for each tone detector. The state machine is defined by a state transition table (</font><font face="Courier"><font size=-2>stran</font></font><font size=-1>), and the number of states (</font><font face="Courier"><font size=-2>nstates</font></font><font size=-1>). The state transition table consists of an array of </font><u><font face="Courier"><font size=-2>VPB_STRAN</font></font></u><font size=-1> structures.</font> <p><font size=-1>The state machine begins in state 0 and progresses to the next state when the state transition requirements are met for that state. When the final state transition occurs, an event of type </font><font face="Courier"><font size=-2>VPB_TONEDETECT</font></font><font size=-1> is posted on the API event queue. A maximum of </font><font face="Courier"><font size=-2>VPB_MS (#define in vpbapi.h)</font></font><font size=-1> cadence states are allowed for each state machine.</font> <p><font size=-1>There are three types of state transitions:</font> <br> <br> <table BORDER=0 CELLSPACING=0 CELLPADDING=7 WIDTH="541" > <tr> <td VALIGN=TOP WIDTH="26%"><font face="Courier"><font size=-2>VPB_TIMER</font></font></td> <td VALIGN=TOP WIDTH="74%"><font size=-1>A state transition occurs when no change (transition) in the signal occurs for </font><font face="Courier"><font size=-2>tfire</font></font><font size=-1> ms.</font> <p><font size=-1>If a transition occurs before time </font><font face="Courier"><font size=-2>tfire</font></font><font size=-1>, the state machine is reset to state 0.</font> <p><font size=-1>The </font><font face="Courier"><font size=-2>VPB_TIMER</font></font><font size=-1> transition provides a way to measure the on time of signals without cadence, for example continuous dial tones.</font></td> </tr> <tr> <td VALIGN=TOP WIDTH="26%"><font face="Courier"><font size=-2>VPB_DELAY</font></font></td> <td VALIGN=TOP WIDTH="74%"><font size=-1>It waits the desired time, </font><font face="Courier"><font size=-2>tfire</font></font><font size=-1> ms and goes to the next state.</font> <p><font size=-1>The </font><font face="Courier"><font size=-2>VPB_DELAY</font></font><font size=-1> transition provides a way to wait a desired time irrespective of any signal transitions.</font></td> </tr> <tr> <td VALIGN=TOP WIDTH="26%"><font face="Courier"><font size=-2>VPB_RISING</font></font></td> <td VALIGN=TOP WIDTH="74%"><font size=-1>A state transition occurs on the rising edge of the signal detection, that is, when the signal goes from a non-detected to detected state. The state transition occurs if the time spent in this state is between </font><font face="Courier"><font size=-2>tmin</font></font><font size=-1> and </font><font face="Courier"><font size=-2>tmax</font></font><font size=-1> ms.</font> <p><font size=-1>If at the rising edge the time spent in this state is not between </font><font face="Courier"><font size=-2>tmin</font></font><font size=-1> and </font><font face="Courier"><font size=-2>tmax</font></font><font size=-1> ms, the state machine is reset to state 0.</font> <p><font size=-1>If </font><font face="Courier"><font size=-2>tmin</font></font><font size=-1> and </font><font face="Courier"><font size=-2>tmax</font></font><font size=-1> are both set to 0, then a state transition occurs on the rising edge of the signal, regardless of the time spent in this state.</font> <p><font size=-1>The </font><font face="Courier"><font size=-2>VPB_RISING</font></font><font size=-1> transition provides a way to determine how long the signal was <i>off</i>.</font></td> </tr> <tr> <td VALIGN=TOP WIDTH="26%"><font face="Courier"><font size=-2>VPB_FALLING</font></font></td> <td VALIGN=TOP WIDTH="74%"><font size=-1>A state transition occurs on the falling edge of the signal detection, that is when the signal goes from a detected to non-detected state. The state transition occurs if the time spent in this state is between </font><font face="Courier"><font size=-2>tmin</font></font><font size=-1> and </font><font face="Courier"><font size=-2>tmax</font></font><font size=-1> ms.</font> <p><font size=-1>If at the falling edge the time spent in this state is not between </font><font face="Courier"><font size=-2>tmin</font></font><font size=-1> and </font><font face="Courier"><font size=-2>tmax</font></font><font size=-1> ms, the state machine is reset to state 0.</font> <p><font size=-1>If </font><font face="Courier"><font size=-2>tmin</font></font><font size=-1> and </font><font face="Courier"><font size=-2>tmax</font></font><font size=-1> are both set to 0, then a state transition occurs on the falling edge of the signal, regardless of the time spent in this state.</font> <p><font size=-1>The </font><font face="Courier"><font size=-2>VPB_FALLING</font></font><font size=-1> transition provides a way to determine how long the signal was <i>on</i>.</font></td> </tr> </table> <br> <br> <p><b>Programmable Tone Detector Tips</b> <p><font size=-1>The cadence state machine approach has the advantage that non-periodic or variable cadences may be detected, for example a tone that has a long on period, then a short on period.</font> <p><font size=-1>To detect several cycles of a periodic cadence pattern, for example 3 on/off cycles of a busy tone, just repeat the cadence state detector rising and falling edge transitions the desired number of times, up to the </font><font face="Courier"><font size=-2>VPB_MS (#define in vpbapi.h)</font></font><font size=-1> limit.</font> <p><font size=-1>When designing/debugging a tone detector, start with a simple cadence detector, for example just a single rising edge state. Adjust the signal detection parameters first, then add and test the extra cadence states one at a time. This will identify any problems with the last cadence state added. Don?t forget to modify the</font><font face="Courier"><font size=-2> nstates</font></font><font size=-1> parameter in the </font><u><font face="Courier"><font size=-2>VPB_DETECT</font></font></u><font size=-1>structure as extra states are added.</font> <p><font size=-1>When designing/debugging a tone detector, start with wide bandwidths (several hundred Hz), and low level thresholds (say -40 dB), then gradually tighten (reduce bandwidth, increase level) these parameters to increase the robustness of the tone detector.</font> <p><font size=-1>Amplitude modulated signals have wider bandwidths than pure sinusoids, and their amplitudes move up and down with the modulation frequency. Amplitude modulated signals may therefore need lower level thresholds than unmodulated tones. As a rule of thumb, use a bandwidth about four times as wide as the modulating frequency, for example, 100 Hz for a 25 Hz modulating frequency. The level threshold may need to be very low to detect the signal through the low level periods, so try -40 dB as a starting point for the level parameters.</font> <br> <br> <p><b>Programmable Tone Detector Examples</b> <p><b><font size=-1>Example 1 - Continuous dial tone at 425 Hz, amplitude modulated at 25 Hz.</font></b> <p><b>This discussion refers to the </b><font face="Courier"><font size=-2>toned_dial</font></font><font size=-1> variable below.</font> <p><font size=-1>This tone is amplitude modulated at 25 Hz, which spreads the bandwidth approximately 25 Hz either side of the main frequency component. A bandwidth of 100 Hz was used to be sure that all of the dial tone energy is captured, although only 50 Hz is strictly necessary. The level of amplitude modulated signals can also be quite low (it varies up and down with the modulating signal), so a low amplitude threshold of -40dB was used. The tone contains only a single frequency component so the 2<sup>nd</sup> frequency parameters are set to 0, which instructs the tone detector software to ignore the 2<sup>nd</sup> frequency.</font> <p><font size=-1>The signal to noise ratio (SNR) was set to 10 dB so that the detector requires most of the energy in the signal to be contained in the 100 Hz bandwidth. This helps to reduce false triggering, for example by a speech signal that may have energy around 400 Hz.</font> <p><font size=-1>There are two cadence states specified. The first looks for a rising edge in the signal detection logic. No time parameters are specified, so only the rising edge (from non-detected to detected signal condition) is required to move the state machine to the second state.</font> <p><font size=-1>The second state is a </font><font face="Courier"><font size=-2>VPB_TIMER</font></font><font size=-1> state. This timer "fires" when the signal has been detected for 2000 ms. If the signal disappears in this time, the state machine is reset to the first state and no event is posted. If the signal continues uninterrupted for 2000 ms, an event is posted to the API event queue and the state machine resets itself to state 0. The event will contain </font><font face="Courier"><font size=-2>VPB_DIAL</font></font><font size=-1> in the data member of the </font><font face="Courier"><font size=-2>VPB_EVENT</font></font><font size=-1> structure.</font> <p><font size=-1>Note that the timer state provides an additional level of "filtering", as the signal must be continuous and uninterrupted for 2000 ms. Any non-valid signals are unlikely to meet the signal detection conditions for this time, and will be discarded by the state machine.</font> <br> <br> <table BORDER=0 CELLSPACING=0 CELLPADDING=7 WIDTH="434" > <tr> <td VALIGN=TOP COLSPAN="3"><font face="Courier"><font size=-2>static VPB_DETECT toned_dial = {</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="21%"><font face="Courier"><font size=-2>2,</font></font></td> <td VALIGN=TOP WIDTH="67%"><font face="Courier"><font size=-2>// number of cadence states</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="21%"><font face="Courier"><font size=-2>VPB_DIAL,</font></font></td> <td VALIGN=TOP WIDTH="67%"><font face="Courier"><font size=-2>// tone id</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="21%"><font face="Courier"><font size=-2>1,</font></font></td> <td VALIGN=TOP WIDTH="67%"><font face="Courier"><font size=-2>// number of tones</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="21%"><font face="Courier"><font size=-2>425,</font></font></td> <td VALIGN=TOP WIDTH="67%"><font face="Courier"><font size=-2>// freq1</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="21%"><font face="Courier"><font size=-2>100,</font></font></td> <td VALIGN=TOP WIDTH="67%"><font face="Courier"><font size=-2>// bandwidth1</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="21%"><font face="Courier"><font size=-2>0,</font></font></td> <td VALIGN=TOP WIDTH="67%"><font face="Courier"><font size=-2>// freq2, N/A</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="21%"><font face="Courier"><font size=-2>0,</font></font></td> <td VALIGN=TOP WIDTH="67%"><font face="Courier"><font size=-2>// bandwidth2, N/A</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="21%"><font face="Courier"><font size=-2>-40,</font></font></td> <td VALIGN=TOP WIDTH="67%"><font face="Courier"><font size=-2>// level1</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="21%"><font face="Courier"><font size=-2>0,</font></font></td> <td VALIGN=TOP WIDTH="67%"><font face="Courier"><font size=-2>// level2, N/A</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="21%"><font face="Courier"><font size=-2>0,</font></font></td> <td VALIGN=TOP WIDTH="67%"><font face="Courier"><font size=-2>// twist, N/A</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="21%"><font face="Courier"><font size=-2>10,</font></font></td> <td VALIGN=TOP WIDTH="67%"><font face="Courier"><font size=-2>// SNR</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="21%"><font face="Courier"><font size=-2>40</font></font></td> <td VALIGN=TOP WIDTH="67%"><font face="Courier"><font size=-2>// glitch duration 40ms</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="21%"> </td> <td VALIGN=TOP WIDTH="67%"> </td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="21%"><font face="Courier"><font size=-2>RISING,</font></font></td> <td VALIGN=TOP WIDTH="67%"><font face="Courier"><font size=-2>// state 0</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="21%"><font face="Courier"><font size=-2>0,</font></font></td> <td VALIGN=TOP WIDTH="67%"> </td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="21%"><font face="Courier"><font size=-2>0,</font></font></td> <td VALIGN=TOP WIDTH="67%"> </td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="21%"><font face="Courier"><font size=-2>0,</font></font></td> <td VALIGN=TOP WIDTH="67%"> </td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="21%"> </td> <td VALIGN=TOP WIDTH="67%"> </td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="21%"><font face="Courier"><font size=-2>TIMER,</font></font></td> <td VALIGN=TOP WIDTH="67%"><font face="Courier"><font size=-2>// state 1</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="21%"><font face="Courier"><font size=-2>2000,</font></font></td> <td VALIGN=TOP WIDTH="67%"> </td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="21%"><font face="Courier"><font size=-2>0,</font></font></td> <td VALIGN=TOP WIDTH="67%"> </td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="21%"><font face="Courier"><font size=-2>0</font></font></td> <td VALIGN=TOP WIDTH="67%"> </td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"><font face="Courier"><font size=-2>};</font></font></td> <td VALIGN=TOP WIDTH="21%"> </td> <td VALIGN=TOP WIDTH="67%"> </td> </tr> </table> <p><b><font size=-1>Example 2 - Austel Busy Tone 425 Hz or 400 Hz, 375 ms on, 375 ms off</font></b> <p><b>This discussion refers to the </b><font face="Courier"><font size=-2>toned_austel_busy</font></font><font size=-1> variable below.</font> <p><font size=-1>The Austel busy tone has two possible frequencies, 400 or 425 Hz, so a bandwidth of 100 Hz has been used to make sure both possibilities are within the bandwidth of the signal detector. As the signal is a single unmodulated tone, the amplitude will be relatively stable, so we can set a fairly high cut off level of -20 dB.</font> <p><font size=-1>The cadence state machine has 3 states, which detect a single on/off cycle of the busy tone. The first state detects the first rising edge, with no time parameters. The second state waits for the falling edge, and checks that the signal on time was between 300 and 450 ms. The third state then waits for the next rising edge, and checks if its off time was between 300 and 450 ms. If so, then a </font><font face="Courier"><font size=-2>VPB_AUSTEL_BUSY </font></font><font size=-1>event is posted to the API queue. If any of these conditions fail then the state machine resets and no events are generated.</font> <br> <br> <table BORDER=0 CELLSPACING=0 CELLPADDING=7 WIDTH="434" > <tr> <td VALIGN=TOP COLSPAN="3"><font face="Courier"><font size=-2>static VPB_DETECT toned_austel_busy = {</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="28%"><font face="Courier"><font size=-2>3,</font></font></td> <td VALIGN=TOP WIDTH="60%"><font face="Courier"><font size=-2>// number of cadence states</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="28%"><font face="Courier"><font size=-2>VPB_AUSTEL_BUSY,</font></font></td> <td VALIGN=TOP WIDTH="60%"><font face="Courier"><font size=-2>// tone id</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="28%"><font face="Courier"><font size=-2>1,</font></font></td> <td VALIGN=TOP WIDTH="60%"><font face="Courier"><font size=-2>// number of tones</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="28%"><font face="Courier"><font size=-2>425,</font></font></td> <td VALIGN=TOP WIDTH="60%"><font face="Courier"><font size=-2>// freq1</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="28%"><font face="Courier"><font size=-2>100,</font></font></td> <td VALIGN=TOP WIDTH="60%"><font face="Courier"><font size=-2>// bandwidth1</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="28%"><font face="Courier"><font size=-2>0,</font></font></td> <td VALIGN=TOP WIDTH="60%"><font face="Courier"><font size=-2>// freq2, N/A</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="28%"><font face="Courier"><font size=-2>0,</font></font></td> <td VALIGN=TOP WIDTH="60%"><font face="Courier"><font size=-2>// bandwidth2: N/A</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="28%"><font face="Courier"><font size=-2>-20,</font></font></td> <td VALIGN=TOP WIDTH="60%"><font face="Courier"><font size=-2>// level1</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="28%"><font face="Courier"><font size=-2>0,</font></font></td> <td VALIGN=TOP WIDTH="60%"><font face="Courier"><font size=-2>// level2, N/A</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="28%"><font face="Courier"><font size=-2>0,</font></font></td> <td VALIGN=TOP WIDTH="60%"><font face="Courier"><font size=-2>// twist: N/A</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="28%"><font face="Courier"><font size=-2>10,</font></font></td> <td VALIGN=TOP WIDTH="60%"><font face="Courier"><font size=-2>// SNR: 10dB</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="28%"><font face="Courier"><font size=-2>40</font></font></td> <td VALIGN=TOP WIDTH="60%"><font face="Courier"><font size=-2>// glitch duration 40ms</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="28%"> </td> <td VALIGN=TOP WIDTH="60%"> </td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="28%"><font face="Courier"><font size=-2>VPB_RISING,</font></font></td> <td VALIGN=TOP WIDTH="60%"><font face="Courier"><font size=-2>// state 0</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="28%"><font face="Courier"><font size=-2>0,</font></font></td> <td VALIGN=TOP WIDTH="60%"> </td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="28%"><font face="Courier"><font size=-2>0,</font></font></td> <td VALIGN=TOP WIDTH="60%"> </td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="28%"><font face="Courier"><font size=-2>0,</font></font></td> <td VALIGN=TOP WIDTH="60%"> </td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="28%"> </td> <td VALIGN=TOP WIDTH="60%"> </td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="28%"><font face="Courier"><font size=-2>VPB_FALLING,</font></font></td> <td VALIGN=TOP WIDTH="60%"><font face="Courier"><font size=-2>// state 1</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="28%"><font face="Courier"><font size=-2>0,</font></font></td> <td VALIGN=TOP WIDTH="60%"> </td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="28%"><font face="Courier"><font size=-2>300,</font></font></td> <td VALIGN=TOP WIDTH="60%"> </td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="28%"><font face="Courier"><font size=-2>450,</font></font></td> <td VALIGN=TOP WIDTH="60%"> </td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="28%"> </td> <td VALIGN=TOP WIDTH="60%"> </td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="28%"><font face="Courier"><font size=-2>VPB_RISING,</font></font></td> <td VALIGN=TOP WIDTH="60%"><font face="Courier"><font size=-2>// state 2</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="28%"><font face="Courier"><font size=-2>0,</font></font></td> <td VALIGN=TOP WIDTH="60%"> </td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="28%"><font face="Courier"><font size=-2>300,</font></font></td> <td VALIGN=TOP WIDTH="60%"> </td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="28%"><font face="Courier"><font size=-2>450,</font></font></td> <td VALIGN=TOP WIDTH="60%"> </td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"><font face="Courier"><font size=-2>};</font></font></td> <td VALIGN=TOP WIDTH="28%"> </td> <td VALIGN=TOP WIDTH="60%"> </td> </tr> </table> <p><b><font size=-1>Example 3 - DTMF tone detection</font></b> <p><b>This example demonstrates the ability of the programmable tone detector to detect tones with two frequency components, in this case the DTMF tone for 1, composed of 697 Hz, and 1209 Hz. The variable </b><font face="Courier"><font size=-2>toned_dtmf1</font></font><font size=-1> below illustrates the configuration for this tone.</font> <p><font size=-1>The signal detection parameters are fairly straightforward, both frequencies have the same level thresholds. The twist parameter specifies the maximum permissible difference in the magnitudes of the two frequency components of the tones, in this case it is 10 dB.</font> <p><font size=-1>The cadence state machine looks for a rising edge, then the tone must be present for a minimum of 100 ms before a </font><font face="Courier"><font size=-2>VPB_TONEDETECT</font></font><font size=-1> event with the data member set to </font><font face="Courier"><font size=-2>DTMF_1</font></font><font size=-1> (user #defined to a unique tone identifier) is posted.</font> <br> <br> <table BORDER=0 CELLSPACING=0 CELLPADDING=7 WIDTH="434" > <tr> <td VALIGN=TOP COLSPAN="3"><font face="Courier"><font size=-2>static VPB_DETECT toned_dtmf1 = {</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="28%"><font face="Courier"><font size=-2>2,</font></font></td> <td VALIGN=TOP WIDTH="60%"><font face="Courier"><font size=-2>// number of cadence states</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="28%"><font face="Courier"><font size=-2>DTMF_1,</font></font></td> <td VALIGN=TOP WIDTH="60%"><font face="Courier"><font size=-2>// tone id</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="28%"><font face="Courier"><font size=-2>2,</font></font></td> <td VALIGN=TOP WIDTH="60%"><font face="Courier"><font size=-2>// number of tones</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="28%"><font face="Courier"><font size=-2>697,</font></font></td> <td VALIGN=TOP WIDTH="60%"><font face="Courier"><font size=-2>// f1: centre frequency</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="28%"><font face="Courier"><font size=-2>100,</font></font></td> <td VALIGN=TOP WIDTH="60%"><font face="Courier"><font size=-2>// bw1: bandwidth</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="28%"><font face="Courier"><font size=-2>1209,</font></font></td> <td VALIGN=TOP WIDTH="60%"><font face="Courier"><font size=-2>// f2: centre frequency</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="28%"><font face="Courier"><font size=-2>100,</font></font></td> <td VALIGN=TOP WIDTH="60%"><font face="Courier"><font size=-2>// bw2: bandwidth</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="28%"><font face="Courier"><font size=-2>-20,</font></font></td> <td VALIGN=TOP WIDTH="60%"><font face="Courier"><font size=-2>// A1: -20 dBm0</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="28%"><font face="Courier"><font size=-2>-20,</font></font></td> <td VALIGN=TOP WIDTH="60%"><font face="Courier"><font size=-2>// A2: -20 dBm0</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="28%"><font face="Courier"><font size=-2>10,</font></font></td> <td VALIGN=TOP WIDTH="60%"><font face="Courier"><font size=-2>// twist: 10 dB</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="28%"><font face="Courier"><font size=-2>10,</font></font></td> <td VALIGN=TOP WIDTH="60%"><font face="Courier"><font size=-2>// SNR: 10 dB</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="28%"><font face="Courier"><font size=-2>40</font></font></td> <td VALIGN=TOP WIDTH="60%"><font face="Courier"><font size=-2>// glitch duration 40ms</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="28%"> </td> <td VALIGN=TOP WIDTH="60%"> </td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="28%"><font face="Courier"><font size=-2>VPB_RISING,</font></font></td> <td VALIGN=TOP WIDTH="60%"><font face="Courier"><font size=-2>// state 0</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="28%"><font face="Courier"><font size=-2>0,</font></font></td> <td VALIGN=TOP WIDTH="60%"> </td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="28%"><font face="Courier"><font size=-2>0,</font></font></td> <td VALIGN=TOP WIDTH="60%"> </td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="28%"><font face="Courier"><font size=-2>0,</font></font></td> <td VALIGN=TOP WIDTH="60%"> </td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="28%"> </td> <td VALIGN=TOP WIDTH="60%"> </td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="28%"><font face="Courier"><font size=-2>VPB_TIMER,</font></font></td> <td VALIGN=TOP WIDTH="60%"><font face="Courier"><font size=-2>// state 1</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="28%"><font face="Courier"><font size=-2>100,</font></font></td> <td VALIGN=TOP WIDTH="60%"> </td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="28%"><font face="Courier"><font size=-2>0,</font></font></td> <td VALIGN=TOP WIDTH="60%"> </td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="28%"><font face="Courier"><font size=-2>0</font></font></td> <td VALIGN=TOP WIDTH="60%"> </td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"><font face="Courier"><font size=-2>};</font></font></td> <td VALIGN=TOP WIDTH="28%"> </td> <td VALIGN=TOP WIDTH="60%"> </td> </tr> </table> <p><b><font size=-1>Example 4 - Grunt Detector used to detect wide band signals such as voice</font></b> <p><b>This discussion refers to the </b><font face="Courier"><font size=-2>toned_grunt</font></font><font size=-1> variable below.</font> <p><font size=-1>Voice signals have a wide band signal characteristic, with most of the energy located between 50-2000Hz. The grunt detector looks for wide band energy between 500Hz and 3500Hz. The lower frequency band (500Hz) was selected as not to overlap with other telephony signals, such as dial and busy tones which have their energy centred around 400Hz.</font> <p><font size=-1>The cadence state machine has 2 states to detect a wideband signal. The first state waits for 1 s, ignoring any signal transitions. The second state checks for a rising edge in the signal with an off time between 0-40 ms. If so, then a </font><font face="Courier"><font size=-2>VPB_GRUNT </font></font><font size=-1>event is posted to the API queue. If any of these conditions fail then the state machine resets and no events are generated.</font> <br> <br> <table BORDER=0 CELLSPACING=0 CELLPADDING=7 WIDTH="434" > <tr> <td VALIGN=TOP COLSPAN="3"><font face="Courier"><font size=-2>static VPB_DETECT toned_grunt = {</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="28%"><font face="Courier"><font size=-2>2,</font></font></td> <td VALIGN=TOP WIDTH="60%"><font face="Courier"><font size=-2>// number of cadence states</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="28%"><font face="Courier"><font size=-2>VPB_GRUNT,</font></font></td> <td VALIGN=TOP WIDTH="60%"><font face="Courier"><font size=-2>// tone id</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="28%"><font face="Courier"><font size=-2>1,</font></font></td> <td VALIGN=TOP WIDTH="60%"><font face="Courier"><font size=-2>// number of tones</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="28%"><font face="Courier"><font size=-2>2000,</font></font></td> <td VALIGN=TOP WIDTH="60%"><font face="Courier"><font size=-2>// freq1</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="28%"><font face="Courier"><font size=-2>3000,</font></font></td> <td VALIGN=TOP WIDTH="60%"><font face="Courier"><font size=-2>// bandwidth1</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="28%"><font face="Courier"><font size=-2>0,</font></font></td> <td VALIGN=TOP WIDTH="60%"><font face="Courier"><font size=-2>// freq2, N/A</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="28%"><font face="Courier"><font size=-2>0,</font></font></td> <td VALIGN=TOP WIDTH="60%"><font face="Courier"><font size=-2>// bandwidth2: N/A</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="28%"><font face="Courier"><font size=-2>-40,</font></font></td> <td VALIGN=TOP WIDTH="60%"><font face="Courier"><font size=-2>// level1 (-40 dB</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="28%"><font face="Courier"><font size=-2>0,</font></font></td> <td VALIGN=TOP WIDTH="60%"><font face="Courier"><font size=-2>// level2, N/A</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="28%"><font face="Courier"><font size=-2>0,</font></font></td> <td VALIGN=TOP WIDTH="60%"><font face="Courier"><font size=-2>// twist: N/A</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="28%"><font face="Courier"><font size=-2>0,</font></font></td> <td VALIGN=TOP WIDTH="60%"><font face="Courier"><font size=-2>// SNR: N/A</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="28%"><font face="Courier"><font size=-2>40</font></font></td> <td VALIGN=TOP WIDTH="60%"><font face="Courier"><font size=-2>// glitch duration 40ms</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="28%"> </td> <td VALIGN=TOP WIDTH="60%"> </td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="28%"><font face="Courier"><font size=-2>VPB_DELAY,</font></font></td> <td VALIGN=TOP WIDTH="60%"><font face="Courier"><font size=-2>// state 0</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="28%"><font face="Courier"><font size=-2>1000,</font></font></td> <td VALIGN=TOP WIDTH="60%"> </td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="28%"><font face="Courier"><font size=-2>0,</font></font></td> <td VALIGN=TOP WIDTH="60%"> </td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="28%"><font face="Courier"><font size=-2>0,</font></font></td> <td VALIGN=TOP WIDTH="60%"> </td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="28%"> </td> <td VALIGN=TOP WIDTH="60%"> </td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="28%"><font face="Courier"><font size=-2>VPB_RISING,</font></font></td> <td VALIGN=TOP WIDTH="60%"><font face="Courier"><font size=-2>// state 1</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="28%"><font face="Courier"><font size=-2>0,</font></font></td> <td VALIGN=TOP WIDTH="60%"> </td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="28%"><font face="Courier"><font size=-2>40,</font></font></td> <td VALIGN=TOP WIDTH="60%"> </td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="28%"><font face="Courier"><font size=-2>0,</font></font></td> <td VALIGN=TOP WIDTH="60%"> </td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"> </td> <td VALIGN=TOP WIDTH="28%"> </td> <td VALIGN=TOP WIDTH="60%"> </td> </tr> <tr> <td VALIGN=TOP WIDTH="13%"><font face="Courier"><font size=-2>};</font></font></td> <td VALIGN=TOP WIDTH="28%"> </td> <td VALIGN=TOP WIDTH="60%"> </td> </tr> </table> <br> <br> <br> <br> <br> <br> <br> <br> <table BORDER=0 CELLSPACING=0 CELLPADDING=7 WIDTH="547" > <tr> <td VALIGN=TOP COLSPAN="2" WIDTH="29%"> <br> <br> <p><font face="Courier"><font size=-2>typedef struct {</font></font></td> <td VALIGN=TOP WIDTH="20%"> </td> <td VALIGN=TOP WIDTH="52%"> </td> </tr> <tr> <td VALIGN=TOP WIDTH="7%"> </td> <td VALIGN=TOP WIDTH="22%"><font face="Courier"><font size=-2>unsigned short</font></font></td> <td VALIGN=TOP WIDTH="20%"><font face="Courier"><font size=-2>nstates;</font></font></td> <td VALIGN=TOP WIDTH="52%"><font face="Courier"><font size=-2>// number of cadence states</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="7%"> </td> <td VALIGN=TOP WIDTH="22%"><font face="Courier"><font size=-2>unsigned short</font></font></td> <td VALIGN=TOP WIDTH="20%"><font face="Courier"><font size=-2>tone_id;</font></font></td> <td VALIGN=TOP WIDTH="52%"><font face="Courier"><font size=-2>// unique ID number for this tone</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="7%"> </td> <td VALIGN=TOP WIDTH="22%"><font face="Courier"><font size=-2>unsigned short</font></font></td> <td VALIGN=TOP WIDTH="20%"><font face="Courier"><font size=-2>ntones;</font></font></td> <td VALIGN=TOP WIDTH="52%"><font face="Courier"><font size=-2>// number of tones (1 or 2)</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="7%"> </td> <td VALIGN=TOP WIDTH="22%"><font face="Courier"><font size=-2>unsigned short</font></font></td> <td VALIGN=TOP WIDTH="20%"><font face="Courier"><font size=-2>freq1;</font></font></td> <td VALIGN=TOP WIDTH="52%"><font face="Courier"><font size=-2>// freq of first tone (Hz)</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="7%"> </td> <td VALIGN=TOP WIDTH="22%"><font face="Courier"><font size=-2>unsigned short</font></font></td> <td VALIGN=TOP WIDTH="20%"><font face="Courier"><font size=-2>bandwidth1;</font></font></td> <td VALIGN=TOP WIDTH="52%"><font face="Courier"><font size=-2>// bandwidth of first tone (Hz)</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="7%"> </td> <td VALIGN=TOP WIDTH="22%"><font face="Courier"><font size=-2>unsigned short</font></font></td> <td VALIGN=TOP WIDTH="20%"><font face="Courier"><font size=-2>freq2;</font></font></td> <td VALIGN=TOP WIDTH="52%"><font face="Courier"><font size=-2>// freq of first tone (Hz)</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="7%"> </td> <td VALIGN=TOP WIDTH="22%"><font face="Courier"><font size=-2>unsigned short</font></font></td> <td VALIGN=TOP WIDTH="20%"><font face="Courier"><font size=-2>bandwidth2;</font></font></td> <td VALIGN=TOP WIDTH="52%"><font face="Courier"><font size=-2>// bandwidth of second tone (Hz)</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="7%"> </td> <td VALIGN=TOP WIDTH="22%"><font face="Courier"><font size=-2>short</font></font></td> <td VALIGN=TOP WIDTH="20%"><font face="Courier"><font size=-2>minlevel1;</font></font></td> <td VALIGN=TOP WIDTH="52%"><font face="Courier"><font size=-2>// min amp of 1st tone ref 0dBm0</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="7%"> </td> <td VALIGN=TOP WIDTH="22%"><font face="Courier"><font size=-2>short</font></font></td> <td VALIGN=TOP WIDTH="20%"><font face="Courier"><font size=-2>minlevel2;</font></font></td> <td VALIGN=TOP WIDTH="52%"><font face="Courier"><font size=-2>// min amp of 2nd tone ref 0dbm0</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="7%"> </td> <td VALIGN=TOP WIDTH="22%"><font face="Courier"><font size=-2>short</font></font></td> <td VALIGN=TOP WIDTH="20%"><font face="Courier"><font size=-2>twist;</font></font></td> <td VALIGN=TOP WIDTH="52%"><font face="Courier"><font size=-2>// allowable difference in tone</font></font> <p><font face="Courier"><font size=-2>// powers</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="7%"> </td> <td VALIGN=TOP WIDTH="22%"><font face="Courier"><font size=-2>short</font></font></td> <td VALIGN=TOP WIDTH="20%"><font face="Courier"><font size=-2>snr;</font></font></td> <td VALIGN=TOP WIDTH="52%"><font face="Courier"><font size=-2>// min signal to noise ratio to</font></font> <p><font face="Courier"><font size=-2>// accept tone</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="7%"> </td> <td VALIGN=TOP WIDTH="22%"><font face="Courier"><font size=-2>unsigned short</font></font></td> <td VALIGN=TOP WIDTH="20%"><font face="Courier"><font size=-2>glitch;</font></font></td> <td VALIGN=TOP WIDTH="52%"><font face="Courier"><font size=-2>// transitions of glitches </font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="7%"> </td> <td VALIGN=TOP WIDTH="22%"> </td> <td VALIGN=TOP WIDTH="20%"> </td> <td VALIGN=TOP WIDTH="52%"><font face="Courier"><font size=-2>// ignored (ms)</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="7%"> </td> <td VALIGN=TOP WIDTH="22%"> </td> <td VALIGN=TOP WIDTH="20%"> </td> <td VALIGN=TOP WIDTH="52%"> </td> </tr> <tr> <td VALIGN=TOP WIDTH="7%"> </td> <td VALIGN=TOP WIDTH="22%"><font face="Courier"><font size=-2>VPB_STRAN </font></font></td> <td VALIGN=TOP WIDTH="20%"><font face="Courier"><font size=-2>stran[VPB_MS];</font></font></td> <td VALIGN=TOP WIDTH="52%"><font face="Courier"><font size=-2>// cadence state transition table</font></font></td> </tr> <tr> <td VALIGN=TOP COLSPAN="2" WIDTH="29%"><font face="Courier"><font size=-2>} VPB_DETECT;</font></font></td> <td VALIGN=TOP WIDTH="20%"> </td> <td VALIGN=TOP WIDTH="52%"> </td> </tr> </table> <br> <br> <br> <br> <br> <br> <br> <br> <table BORDER=0 CELLSPACING=0 CELLPADDING=7 WIDTH="547" > <tr> <td VALIGN=TOP COLSPAN="2" WIDTH="29%"><font face="Courier"><font size=-2>typedef struct {</font></font></td> <td VALIGN=TOP WIDTH="20%"> </td> <td VALIGN=TOP WIDTH="52%"> </td> </tr> <tr> <td VALIGN=TOP WIDTH="7%"> </td> <td VALIGN=TOP WIDTH="22%"><font face="Courier"><font size=-2>unsigned short</font></font></td> <td VALIGN=TOP WIDTH="20%"><font face="Courier"><font size=-2>type;</font></font></td> <td VALIGN=TOP WIDTH="52%"><font face="Courier"><font size=-2>// VPB_TIMER, VPB_DELAY, VPB_RISING,</font></font> <p><font face="Courier"><font size=-2>// or VPB_FALLING</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="7%"> </td> <td VALIGN=TOP WIDTH="22%"><font face="Courier"><font size=-2>unsigned short</font></font></td> <td VALIGN=TOP WIDTH="20%"><font face="Courier"><font size=-2>tfire;</font></font></td> <td VALIGN=TOP WIDTH="52%"><font face="Courier"><font size=-2>// timer mode only</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="7%"> </td> <td VALIGN=TOP WIDTH="22%"><font face="Courier"><font size=-2>unsigned short</font></font></td> <td VALIGN=TOP WIDTH="20%"><font face="Courier"><font size=-2>tmin;</font></font></td> <td VALIGN=TOP WIDTH="52%"><font face="Courier"><font size=-2>// minimum tone on/off time</font></font> <p><font face="Courier"><font size=-2>// (non timer) in ms</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="7%"> </td> <td VALIGN=TOP WIDTH="22%"><font face="Courier"><font size=-2>unsigned short</font></font></td> <td VALIGN=TOP WIDTH="20%"><font face="Courier"><font size=-2>tmax;</font></font></td> <td VALIGN=TOP WIDTH="52%"><font face="Courier"><font size=-2>// maximum tone on/off time</font></font> <p><font face="Courier"><font size=-2>// (non timer) in ms</font></font></td> </tr> <tr> <td VALIGN=TOP COLSPAN="2" WIDTH="29%"><font face="Courier"><font size=-2>} VPB_STRAN;</font></font></td> <td VALIGN=TOP WIDTH="20%"> </td> <td VALIGN=TOP WIDTH="52%"> </td> </tr> </table> <br> <br> <br> <br> <p><b>Tone Detector Limits</b> <br> <br> <table BORDER=0 CELLSPACING=0 CELLPADDING=7 WIDTH="511" > <tr> <td VALIGN=TOP WIDTH="19%"><b><font size=-1>Parameter</font></b></td> <td VALIGN=TOP WIDTH="40%"><b><font size=-1>Minimum</font></b></td> <td VALIGN=TOP WIDTH="41%"><b><font size=-1>Maximum</font></b></td> </tr> <tr> <td VALIGN=TOP WIDTH="19%"><font face="Courier"><font size=-2>nstates</font></font></td> <td VALIGN=TOP WIDTH="40%"><font size=-1>1</font></td> <td VALIGN=TOP WIDTH="41%"><font face="Courier"><font size=-2>VPB_MS</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="19%"><font face="Courier"><font size=-2>tone_id</font></font></td> <td VALIGN=TOP WIDTH="40%"><font size=-1>0</font></td> <td VALIGN=TOP WIDTH="41%"><img SRC="Image9.gif" height=19 width=43><img SRC="Image5.gif" height=21 width=11></td> </tr> <tr> <td VALIGN=TOP WIDTH="19%"><font face="Courier"><font size=-2>ntones</font></font></td> <td VALIGN=TOP WIDTH="40%"><font size=-1>1</font></td> <td VALIGN=TOP WIDTH="41%"><font size=-1>2</font></td> </tr> <tr> <td VALIGN=TOP WIDTH="19%"><font face="Courier"><font size=-2>freq1</font></font></td> <td VALIGN=TOP WIDTH="40%"><font size=-1>0 Hz</font></td> <td VALIGN=TOP WIDTH="41%"><font size=-1>4000 Hz</font></td> </tr> <tr> <td VALIGN=TOP WIDTH="19%"><font face="Courier"><font size=-2>bandwidth1</font></font></td> <td VALIGN=TOP WIDTH="40%"><img SRC="Image5.gif" height=21 width=11><font face="Courier"><font size=-2>freq1 - bandwidth1/2</font></font> <p><font face="Courier"><font size=-2>100 Hz</font></font></td> <td VALIGN=TOP WIDTH="41%"><font face="Courier"><font size=-2>freq1 + bandwidth1/2</font></font> <p><font face="Courier"><font size=-2>< 3900 Hz</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="19%"><font face="Courier"><font size=-2>freq2</font></font></td> <td VALIGN=TOP WIDTH="40%"><font size=-1>0 Hz</font></td> <td VALIGN=TOP WIDTH="41%"><font size=-1>4000 Hz</font></td> </tr> <tr> <td VALIGN=TOP WIDTH="19%"><font face="Courier"><font size=-2>bandwidth2</font></font></td> <td VALIGN=TOP WIDTH="40%"><img SRC="Image5.gif" height=21 width=11><font face="Courier"><font size=-2>freq2-bandwidth2/2</font></font> <p><font face="Courier"><font size=-2>100 Hz</font></font></td> <td VALIGN=TOP WIDTH="41%"><font face="Courier"><font size=-2>freq2+bandwidth2/2</font></font> <p><font face="Courier"><font size=-2>< 3900 Hz</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="19%"><font face="Courier"><font size=-2>minlevel1</font></font></td> <td VALIGN=TOP WIDTH="40%"><font size=-1>N/A</font></td> <td VALIGN=TOP WIDTH="41%"><font size=-1>0</font></td> </tr> <tr> <td VALIGN=TOP WIDTH="19%"><font face="Courier"><font size=-2>minlevel2</font></font></td> <td VALIGN=TOP WIDTH="40%"><font size=-1>N/A</font></td> <td VALIGN=TOP WIDTH="41%"><font size=-1>0</font></td> </tr> <tr> <td VALIGN=TOP WIDTH="19%"><font face="Courier"><font size=-2>twist</font></font></td> <td VALIGN=TOP WIDTH="40%"><font size=-1>0</font></td> <td VALIGN=TOP WIDTH="41%"><font size=-1>N/A</font></td> </tr> <tr> <td VALIGN=TOP WIDTH="19%"><font face="Courier"><font size=-2>snr</font></font></td> <td VALIGN=TOP WIDTH="40%"><font size=-1>0</font></td> <td VALIGN=TOP WIDTH="41%"><font size=-1>N/A</font></td> </tr> <tr> <td VALIGN=TOP WIDTH="19%"><font face="Courier"><font size=-2>tfire, tmin, tmax</font></font></td> <td VALIGN=TOP WIDTH="40%"><font size=-1>0</font></td> <td VALIGN=TOP WIDTH="41%"><img SRC="Image10.gif" height=19 width=43><font size=-1>ms</font></td> </tr> </table> <br> <br> <p><b>Timers</b> <p><font size=-1>The VPB API includes support for programmable timers that operate through the API event queue. The timers are useful for integrating timer functions into state machine based computer telephony applications.</font> <p><font size=-1>The following functions support the API timers:</font> <p><u><font face="Courier"><font size=-2>vpb_timer_open()</font></font></u> <p><u>vpb_timer_close( )</u> <p><u>vpb_timer_start( )</u> <p><u>vpb_timer_stop( )</u> <p><u>vpb_timer_restart( )</u> <p><u>vpb_timer_get_unique_timer_id( )</u> <p><u>vpb_timer_change_period( )</u> <br> <br> <p><b>Notes on Using Timers</b> <p><font size=-1>Timers have two states, running, and stopped. When a timer is first created with </font><u><font face="Courier"><font size=-2>vpb_timer_open()</font></font></u><font size=-1>, the timer is in the stopped state. The timer can be placed in the running state using </font><u><font face="Courier"><font size=-2>vpb_timer_start()</font></font></u><font size=-1>or </font><u><font face="Courier"><font size=-2>vpb_timer_restart()</font></font></u><font size=-1>. When the timer period expires, it posts a </font><font face="Courier"><font size=-2>VPB_TIMER</font></font><font size=-1> event and resets itself to the stopped state. The timer can then be restarted using </font><u><font face="Courier"><font size=-2>vpb_timer_start()</font></font></u><font size=-1> or </font><u><font face="Courier"><font size=-2>vpb_timer_restart()</font></font></u><font size=-1> and the cycle repeated.</font> <p><font size=-1>The timer can be restarted before its period has expired using </font><u><font face="Courier"><font size=-2>vpb_timer_restart()</font></font></u><font size=-1>.</font> <p><font size=-1>Timer events are classed as solicited events, they will always be posted to the event queue and cannot be masked out.</font> <br> <br> <p><b>Wave Functions</b> <p><font size=-1>The following functions allow the user to manipulate wave files through the VPB API.</font> <p><u><font face="Courier"><font size=-2>vpb_wave_open_write()</font></font></u> <p><u>vpb_wave_write( )</u> <p><u>vpb_wave_close_write( )</u> <p><u>vpb_wave_open_read( )</u> <p><u>vpb_wave_read( )</u> <p><u>vpb_wave_close_read( )</u> <p><u>vpb_wave_set_sample_rate( )</u> <p><u>vpb_wave_seek( )</u> <p><u>vpb_wave_get_mode( )</u> <p><b>Notes on using the Wave Functions</b> <p><font size=-1>When writing to a wave file the user must initially open up a wave file using <u>vpb_wave_open_write( )</u> to set up the appropriate wave format and filename. Writing to the file is then handled by <u>vpb_wave_write( )</u>. The wave file must be closed by the <u>vpb_wave_close_write( )</u>.</font> <p><font size=-1>Reading a wave file requires a similar procedure, initially opening up the wave file using <u>vpb_wave_open_read( )</u> to determine the file's wave format. Reading the file is then handled by <u>vpb_wave_read( )</u>. The wave file must be closed by the <u>vpb_wave_close_read( )</u>.</font> <p><font size=-1>The <u>vpb_wave_get_mode( )</u> obtains the compression format of a wave file. This function is useful in instances where the <u>user-define </u> play routines are required.</font> <p><font size=-1>The <u>vpb_wave_seek( )</u> moves the file pointer of the wave file to a specified location. Don't use the _lseek routine found in the C/C++ run time library even though it has similar functionality.</font> <p><font size=-1>The VPB8L has two sampling rate options for recording , 6ksamples/s & 8ksamples/s. The <u>vpb_wave_set_sample_rate( )</u> is specifically used to set the sampling rate of the wave file when the VPB8L is recording audio using the <u>user-defined </u></font> record routines. <br> <p><b>Get Digits Functions</b> <p><font size=-1>The VPB API supports the collection of digits from a channel. This includes an <u>asynchronous</u> and <u>synchronous</u> version. The functions initiate collection of the digits from the channel and place them in a user digit buffer.</font> <p><u><font face="Courier"><font size=-2>vpb_get_digits_sync()</font></font></u> <p><u>vpb_get_digits_async( )</u> <p><b>Notes on the use of Get Digits Functions</b> <p><font size=-1>The conditions of termination for the functions may be configured via the </font><u><font face="Courier"><font size=-2>VPB_DIGITS</font></font></u><font size=-1> structure. In the asynchronous version, the condition of termination is passed to the data field of the </font><u><font face="Courier"><font size=-2>VPB_EVENT</font></font></u><font size=-1> structure once the collection of digits from the channel to the user digit buffer has terminated. The synchronous version returns the appropriate <u>termination</u> code (see vpbapi.h) once the function has ended.</font> <p><font size=-1>A flush function is also included to reset the user digit buffer.</font> <p><u><font face="Courier"><font size=-2>vpb_flush_digits()</font></font></u> <p><font size=-1>Ensure this is used to clear the user digit buffer of any digits from previous actions on the channel before executing any of the get digits functions.</font> <br> <br> <p><b>Get Digit Termination codes</b> <br> <br> <table BORDER=0 CELLSPACING=0 CELLPADDING=7 WIDTH="529" > <tr> <td VALIGN=TOP WIDTH="48%"><b><font size=-1>Termination code</font></b></td> <td VALIGN=TOP WIDTH="52%"><b><font size=-1>Description</font></b></td> </tr> <tr> <td VALIGN=TOP WIDTH="48%"><font size=-1>VPB_DIGIT_TERM</font></td> <td VALIGN=TOP WIDTH="52%"><font size=-1>Termination due to a user-defined termination-digit being pressed</font></td> </tr> <tr> <td VALIGN=TOP WIDTH="48%"><font size=-1>VPB_DIGIT_MAX</font></td> <td VALIGN=TOP WIDTH="52%"><font size=-1>Termination due to having reached the maximum number of digits </font></td> </tr> <tr> <td VALIGN=TOP WIDTH="48%"><font size=-1>VPB_DIGIT_TIME_OUT</font></td> <td VALIGN=TOP WIDTH="52%"><font size=-1>Termination due to the time limit to collect digits having expired</font></td> </tr> <tr> <td VALIGN=TOP WIDTH="48%"><font size=-1>VPB_DIGIT_INTER_DIGIT_TIME_OUT</font></td> <td VALIGN=TOP WIDTH="52%"><font size=-1>Termination due to the inter-digit time limit having expired</font></td> </tr> </table> <br> <br> <br> <br> <br> <br> <br> <br> <table BORDER=0 CELLSPACING=0 CELLPADDING=7 WIDTH="517" > <tr> <td VALIGN=TOP COLSPAN="2" WIDTH="31%"> <br> <br> <p><font face="Courier"><font size=-2>typedef struct {</font></font></td> <td VALIGN=TOP WIDTH="32%"> </td> <td VALIGN=TOP WIDTH="37%"> </td> </tr> <tr> <td VALIGN=TOP WIDTH="8%"> </td> <td VALIGN=TOP WIDTH="23%"><font face="Courier"><font size=-2>char</font></font></td> <td VALIGN=TOP WIDTH="32%"><font face="Courier"><font size=-2>*term_digits;</font></font></td> <td VALIGN=TOP WIDTH="37%"><font face="Courier"><font size=-2>// string of digits to </font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="8%"> </td> <td VALIGN=TOP WIDTH="23%"> </td> <td VALIGN=TOP WIDTH="32%"> </td> <td VALIGN=TOP WIDTH="37%"><font face="Courier"><font size=-2>// terminate</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="8%"> </td> <td VALIGN=TOP WIDTH="23%"><font face="Courier"><font size=-2>unsigned short</font></font></td> <td VALIGN=TOP WIDTH="32%"><font face="Courier"><font size=-2>max_digits;</font></font></td> <td VALIGN=TOP WIDTH="37%"><font face="Courier"><font size=-2>// terminate after </font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="8%"> </td> <td VALIGN=TOP WIDTH="23%"> </td> <td VALIGN=TOP WIDTH="32%"> </td> <td VALIGN=TOP WIDTH="37%"><font face="Courier"><font size=-2>// this many digits</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="8%"> </td> <td VALIGN=TOP WIDTH="23%"><font face="Courier"><font size=-2>unsigned long</font></font></td> <td VALIGN=TOP WIDTH="32%"><font face="Courier"><font size=-2>digit_time_out;</font></font></td> <td VALIGN=TOP WIDTH="37%"><font face="Courier"><font size=-2>// max time for </font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="8%"> </td> <td VALIGN=TOP WIDTH="23%"> </td> <td VALIGN=TOP WIDTH="32%"> </td> <td VALIGN=TOP WIDTH="37%"><font face="Courier"><font size=-2>// collection (ms)</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="8%"> </td> <td VALIGN=TOP WIDTH="23%"><font face="Courier"><font size=-2>unsigned long</font></font></td> <td VALIGN=TOP WIDTH="32%"><font face="Courier"><font size=-2>inter_digit_time_out;</font></font></td> <td VALIGN=TOP WIDTH="37%"><font face="Courier"><font size=-2>// max time between </font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="8%"> </td> <td VALIGN=TOP WIDTH="23%"> </td> <td VALIGN=TOP WIDTH="32%"> </td> <td VALIGN=TOP WIDTH="37%"><font face="Courier"><font size=-2>// digits (ms)</font></font></td> </tr> <tr> <td VALIGN=TOP COLSPAN="2" WIDTH="31%"><font face="Courier"><font size=-2>} VPB_DIGITS;</font></font></td> <td VALIGN=TOP WIDTH="32%"> </td> <td VALIGN=TOP WIDTH="37%"> </td> </tr> </table> <br> <br> <p><b>Call Progress Functions</b> <p><font size=-1>The VPB API enables a call to be placed using the call progress algorithm in both <u>synchronous</u> and <u>asynchronous</u> modes. It also enables the call progress parameters to be set or obtained for each channel.</font> <p><u><font face="Courier"><font size=-2>vpb_get_call()</font></font></u> <p><u>vpb_set_call( )</u> <p><u>vpb_call_sync( )</u> <p><u>vpb_call_async( )</u> <br> <br> <p><b>Notes on the Call Progress Algorithm</b> <p><font size=-1>Call progress analysis determines whether a call is answered or not, whether the line is busy, or there are problems placing the call such as no dial tone, call disconnected or no ring back. The call progress algorithm consists of frequency and cadence analysis to determine the state of the call being placed.</font> <p><font size=-1>The </font><u><font face="Courier"><font size=-2>VPB_CALL</font></font></u><font size=-1> and </font><u><font face="Courier"><font size=-2>VPB_TONE_MAP</font></font></u><font size=-1> structures are used to define the parameters of the call progress algorithm.</font> <p><font size=-1>In the asynchronous version, the status of the call is passed to the data field of the </font><u><font face="Courier"><font size=-2>VPB_EVENT</font></font></u><font size=-1> structure. The synchronous version returns the appropriate <u>call progress return code</u> (see vpbapi.h) once the function has ended.</font> <br> <br> <br> <br> <p><b>Call Progress Return codes</b> <br> <br> <table BORDER=0 CELLSPACING=0 CELLPADDING=7 WIDTH="519" > <tr> <td VALIGN=TOP WIDTH="49%"><b><font size=-1>Return code</font></b></td> <td VALIGN=TOP WIDTH="51%"><b><font size=-1>Description</font></b></td> </tr> <tr> <td VALIGN=TOP WIDTH="49%"><font size=-1>VPB_CALL_CONNECTED</font></td> <td VALIGN=TOP WIDTH="51%"><font size=-1>Call is connected</font></td> </tr> <tr> <td VALIGN=TOP WIDTH="49%"><font size=-1>VPB_CALL_NO_DIAL_TONE</font></td> <td VALIGN=TOP WIDTH="51%"><font size=-1>No dial tone is detected</font></td> </tr> <tr> <td VALIGN=TOP WIDTH="49%"><font size=-1>VPB_CALL_NO_RING_BACK</font></td> <td VALIGN=TOP WIDTH="51%"><font size=-1>No ring back is detected</font></td> </tr> <tr> <td VALIGN=TOP WIDTH="49%"><font size=-1>VPB_CALL_BUSY</font></td> <td VALIGN=TOP WIDTH="51%"><font size=-1>Call is busy</font></td> </tr> <tr> <td VALIGN=TOP WIDTH="49%"><font size=-1>VPB_CALL_NO_ANSWER</font></td> <td VALIGN=TOP WIDTH="51%"><font size=-1>No answer is detected</font></td> </tr> <tr> <td VALIGN=TOP WIDTH="49%"><font size=-1>VPB_CALL_DISCONNECTED</font></td> <td VALIGN=TOP WIDTH="51%"><font size=-1>Call is disconnected</font></td> </tr> </table> <br> <br> <br> <br> <br> <br> <br> <br> <table BORDER=0 CELLSPACING=0 CELLPADDING=7 WIDTH="505" > <tr> <td VALIGN=TOP COLSPAN="3" WIDTH="62%"> <br> <br> <p><font face="Courier"><font size=-2>typedef struct {</font></font></td> <td VALIGN=TOP WIDTH="38%"> </td> </tr> <tr> <td VALIGN=TOP WIDTH="3%"> </td> <td VALIGN=TOP WIDTH="21%"><font face="Courier"><font size=-2>unsigned int</font></font></td> <td VALIGN=TOP WIDTH="38%"><font face="Courier"><font size=-2>dialtones;</font></font></td> <td VALIGN=TOP WIDTH="38%"><font face="Courier"><font size=-2>// number of dialtones </font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="3%"> </td> <td VALIGN=TOP WIDTH="21%"> </td> <td VALIGN=TOP WIDTH="38%"> </td> <td VALIGN=TOP WIDTH="38%"><font face="Courier"><font size=-2>// (default=1)</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="3%"> </td> <td VALIGN=TOP WIDTH="21%"><font face="Courier"><font size=-2>unsigned int</font></font></td> <td VALIGN=TOP WIDTH="38%"><font face="Courier"><font size=-2>dialtone_timeout;</font></font></td> <td VALIGN=TOP WIDTH="38%"><font face="Courier"><font size=-2>// wait for dial tone </font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="3%"> </td> <td VALIGN=TOP WIDTH="21%"> </td> <td VALIGN=TOP WIDTH="38%"> </td> <td VALIGN=TOP WIDTH="38%"><font face="Courier"><font size=-2>// timeout</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="3%"> </td> <td VALIGN=TOP WIDTH="21%"> </td> <td VALIGN=TOP WIDTH="38%"> </td> <td VALIGN=TOP WIDTH="38%"><font face="Courier"><font size=-2>// (default=3000ms)</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="3%"> </td> <td VALIGN=TOP WIDTH="21%"><font face="Courier"><font size=-2>unsigned int</font></font></td> <td VALIGN=TOP WIDTH="38%"><font face="Courier"><font size=-2>ringback_timeout;</font></font></td> <td VALIGN=TOP WIDTH="38%"><font face="Courier"><font size=-2>// time limit for </font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="3%"> </td> <td VALIGN=TOP WIDTH="21%"> </td> <td VALIGN=TOP WIDTH="38%"> </td> <td VALIGN=TOP WIDTH="38%"><font face="Courier"><font size=-2>// initial ringback</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="3%"> </td> <td VALIGN=TOP WIDTH="21%"> </td> <td VALIGN=TOP WIDTH="38%"> </td> <td VALIGN=TOP WIDTH="38%"><font face="Courier"><font size=-2>// (default=10000ms)</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="3%"> </td> <td VALIGN=TOP WIDTH="21%"><font face="Courier"><font size=-2>unsigned int</font></font></td> <td VALIGN=TOP WIDTH="38%"><font face="Courier"><font size=-2>inter_ringback_timeout;</font></font></td> <td VALIGN=TOP WIDTH="38%"> </td> </tr> <tr> <td VALIGN=TOP WIDTH="3%"> </td> <td VALIGN=TOP WIDTH="21%"> </td> <td VALIGN=TOP WIDTH="38%"> </td> <td VALIGN=TOP WIDTH="38%"><font face="Courier"><font size=-2>// ringback time out</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="3%"> </td> <td VALIGN=TOP WIDTH="21%"> </td> <td VALIGN=TOP WIDTH="38%"> </td> <td VALIGN=TOP WIDTH="38%"><font face="Courier"><font size=-2>// when call is </font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="3%"> </td> <td VALIGN=TOP WIDTH="21%"> </td> <td VALIGN=TOP WIDTH="38%"> </td> <td VALIGN=TOP WIDTH="38%"><font face="Courier"><font size=-2>// considered </font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="3%"> </td> <td VALIGN=TOP WIDTH="21%"> </td> <td VALIGN=TOP WIDTH="38%"> </td> <td VALIGN=TOP WIDTH="38%"><font face="Courier"><font size=-2>// connected</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="3%"> </td> <td VALIGN=TOP WIDTH="21%"> </td> <td VALIGN=TOP WIDTH="38%"> </td> <td VALIGN=TOP WIDTH="38%"><font face="Courier"><font size=-2>// (default=6000ms)</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="3%"> </td> <td VALIGN=TOP WIDTH="21%"><font face="Courier"><font size=-2>unsigned int</font></font></td> <td VALIGN=TOP WIDTH="38%"><font face="Courier"><font size=-2>answer_timeout;</font></font></td> <td VALIGN=TOP WIDTH="38%"><font face="Courier"><font size=-2>// wait for answer</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="3%"> </td> <td VALIGN=TOP WIDTH="21%"> </td> <td VALIGN=TOP WIDTH="38%"> </td> <td VALIGN=TOP WIDTH="38%"><font face="Courier"><font size=-2>// after ringback </font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="3%"> </td> <td VALIGN=TOP WIDTH="21%"> </td> <td VALIGN=TOP WIDTH="38%"> </td> <td VALIGN=TOP WIDTH="38%"><font face="Courier"><font size=-2>// detected </font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="3%"> </td> <td VALIGN=TOP WIDTH="21%"> </td> <td VALIGN=TOP WIDTH="38%"> </td> <td VALIGN=TOP WIDTH="38%"><font face="Courier"><font size=-2>// (default=3000ms)</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="3%"> </td> <td VALIGN=TOP WIDTH="21%"><font face="Courier"><font size=-2>VPB_TONE_MAP</font></font></td> <td VALIGN=TOP WIDTH="38%"><font face="Courier"><font size=-2>tone_map[VPB_MAX_TONE_MAP];</font></font></td> <td VALIGN=TOP WIDTH="38%"> </td> </tr> <tr> <td VALIGN=TOP WIDTH="3%"> </td> <td VALIGN=TOP WIDTH="21%"> </td> <td VALIGN=TOP WIDTH="38%"> </td> <td VALIGN=TOP WIDTH="38%"><font face="Courier"><font size=-2>// maps tone_id to call</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="3%"> </td> <td VALIGN=TOP WIDTH="21%"> </td> <td VALIGN=TOP WIDTH="38%"> </td> <td VALIGN=TOP WIDTH="38%"><font face="Courier"><font size=-2>// progress tone</font></font></td> </tr> <tr> <td VALIGN=TOP COLSPAN="2" WIDTH="24%"><font face="Courier"><font size=-2>} VPB_CALL;</font></font></td> <td VALIGN=TOP WIDTH="38%"> </td> <td VALIGN=TOP WIDTH="38%"> </td> </tr> </table> <br> <br> <br> <br> <br> <br> <br> <br> <table BORDER=0 CELLSPACING=0 CELLPADDING=7 WIDTH="427" > <tr> <td VALIGN=TOP COLSPAN="3" WIDTH="50%"> <br> <br> <p><font face="Courier"><font size=-2>typedef struct {</font></font></td> <td VALIGN=TOP WIDTH="51%"> </td> </tr> <tr> <td VALIGN=TOP WIDTH="4%"> </td> <td VALIGN=TOP WIDTH="25%"><font face="Courier"><font size=-2>unsigned int</font></font></td> <td VALIGN=TOP WIDTH="21%"><font face="Courier"><font size=-2>tone_id;</font></font></td> <td VALIGN=TOP WIDTH="51%"><font face="Courier"><font size=-2>// prog tone detector </font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="4%"> </td> <td VALIGN=TOP WIDTH="25%"> </td> <td VALIGN=TOP WIDTH="21%"> </td> <td VALIGN=TOP WIDTH="51%"><font face="Courier"><font size=-2>// tone id</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="4%"> </td> <td VALIGN=TOP WIDTH="25%"><font face="Courier"><font size=-2>unsigned int</font></font></td> <td VALIGN=TOP WIDTH="21%"><font face="Courier"><font size=-2>call_id;</font></font></td> <td VALIGN=TOP WIDTH="51%"><font face="Courier"><font size=-2>// call progress tone id</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="4%"> </td> <td VALIGN=TOP WIDTH="25%"><font face="Courier"><font size=-2>unsigned int</font></font></td> <td VALIGN=TOP WIDTH="21%"><font face="Courier"><font size=-2>terminate;</font></font></td> <td VALIGN=TOP WIDTH="51%"><font face="Courier"><font size=-2>// non zero to terminate</font></font></td> </tr> <tr> <td VALIGN=TOP COLSPAN="3" WIDTH="50%"> </td> <td VALIGN=TOP WIDTH="51%"><font face="Courier"><font size=-2>// list</font></font></td> </tr> <tr> <td VALIGN=TOP COLSPAN="3" WIDTH="50%"><font face="Courier"><font size=-2>} VPB_TONE_MAP;</font></font></td> <td VALIGN=TOP WIDTH="51%"> </td> </tr> </table> <br> <br> <br> <br> <p><b>VOX Functions</b> <p><font size=-1>The VPB API allows the user to control the VOX firmware for each channel.</font> <p><u><font face="Courier"><font size=-2>vpb_getvox()</font></font></u> <p><u>vpb_setvox( )</u> <p><b>Note on the use of VOX Functions</b> <p><font size=-1>The VOX algorithm switches on when the audio level exceeds </font><font face="Courier"><font size=-2>onlevel</font></font><font size=-1>. When the audio level falls beneath </font><font face="Courier"><font size=-2>offlevel</font></font><font size=-1>, a counter is started. When the counter exceeds </font><font face="Courier"><font size=-2>runon</font></font><font size=-1> milliseconds, the VOX algorithm switches off. The overload level is defined as 0 dB, the default on and off VOX levels are -12 and -18 dB respectively. The default </font><font face="Courier"><font size=-2>runon</font></font><font size=-1> duration is 2000 ms. The VOX parameters may be re-programmed using the <u>vpb_setvox()</u> function.</font> <br> <br> <br> <br> <br> <br> <table BORDER=0 CELLSPACING=0 CELLPADDING=7 WIDTH="469" > <tr> <td VALIGN=TOP COLSPAN="3" WIDTH="54%"> <br> <br> <p><font face="Courier"><font size=-2>typedef struct {</font></font></td> <td VALIGN=TOP WIDTH="46%"> </td> </tr> <tr> <td VALIGN=TOP WIDTH="3%"> </td> <td VALIGN=TOP WIDTH="28%"><font face="Courier"><font size=-2>float</font></font></td> <td VALIGN=TOP WIDTH="23%"><font face="Courier"><font size=-2>onlevel;</font></font></td> <td VALIGN=TOP WIDTH="46%"><font face="Courier"><font size=-2>// switch on level in dB </font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="3%"> </td> <td VALIGN=TOP WIDTH="28%"> </td> <td VALIGN=TOP WIDTH="23%"> </td> <td VALIGN=TOP WIDTH="46%"><font face="Courier"><font size=-2>// (-2 max to -36 min)</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="3%"> </td> <td VALIGN=TOP WIDTH="28%"><font face="Courier"><font size=-2>float</font></font></td> <td VALIGN=TOP WIDTH="23%"><font face="Courier"><font size=-2>offlevel;</font></font></td> <td VALIGN=TOP WIDTH="46%"><font face="Courier"><font size=-2>// switch off level in dB</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="3%"> </td> <td VALIGN=TOP WIDTH="28%"> </td> <td VALIGN=TOP WIDTH="23%"> </td> <td VALIGN=TOP WIDTH="46%"><font face="Courier"><font size=-2>// (-2 max to -36 min)</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="3%"> </td> <td VALIGN=TOP WIDTH="28%"><font face="Courier"><font size=-2>unsigned short</font></font></td> <td VALIGN=TOP WIDTH="23%"><font face="Courier"><font size=-2>runon;</font></font></td> <td VALIGN=TOP WIDTH="46%"><font face="Courier"><font size=-2>// run on time in ms</font></font></td> </tr> <tr> <td VALIGN=TOP COLSPAN="2" WIDTH="31%"> </td> <td VALIGN=TOP WIDTH="23%"> </td> <td VALIGN=TOP WIDTH="46%"><font face="Courier"><font size=-2>// (50 ms min to 30000 ms max)</font></font></td> </tr> <tr> <td VALIGN=TOP COLSPAN="2" WIDTH="31%"><font face="Courier"><font size=-2>} VPB_VOX;</font></font></td> <td VALIGN=TOP WIDTH="23%"> </td> <td VALIGN=TOP WIDTH="46%"> </td> </tr> </table> <br> <br> <p><b>Pip Functions</b> <p><font size=-1>The following functions support pip generation on the VPB8L.</font> <p><u><font face="Courier"><font size=-2>vpb_get_pip()</font></font></u> <p><u>vpb_set_pip( )</u> <p><u>vpb_pip_on( )</u> <p><u>vpb_pip_off( )</u> <p><b>Notes on the Pip Functions</b> <p><font size=-1>There is a requirement by national communication authorities, in the instance of recording calls, that the parties must be notified that their call is being recorded. The VPB8L gives the option of inserting a pip tone (notification of call being recorded).</font> <p><font size=-1>The pip parameters, the length of the pip pulse and the period between pulses, can be modified by </font><u><font face="Courier"><font size=-2>vpb_set_pip()</font></font></u><font size=-1>. The </font><u><font face="Courier"><font size=-2>VPB_PIP</font></font></u><font size=-1> structure contains these parameters.</font> <br> <br> <br> <br> <br> <br> <table BORDER=0 CELLSPACING=0 CELLPADDING=7 WIDTH="439" > <tr> <td VALIGN=TOP COLSPAN="3" WIDTH="51%"> <br> <br> <p><font face="Courier"><font size=-2>typedef struct {</font></font></td> <td VALIGN=TOP WIDTH="49%"> </td> </tr> <tr> <td VALIGN=TOP WIDTH="4%"> </td> <td VALIGN=TOP WIDTH="29%"><font face="Courier"><font size=-2>unsigned int</font></font></td> <td VALIGN=TOP WIDTH="18%"><font face="Courier"><font size=-2>width;</font></font></td> <td VALIGN=TOP WIDTH="49%"><font face="Courier"><font size=-2>// width of pip pulse</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="4%"> </td> <td VALIGN=TOP WIDTH="29%"> </td> <td VALIGN=TOP WIDTH="18%"> </td> <td VALIGN=TOP WIDTH="49%"><font face="Courier"><font size=-2>// in ms</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="4%"> </td> <td VALIGN=TOP WIDTH="29%"><font face="Courier"><font size=-2>unsigned int</font></font></td> <td VALIGN=TOP WIDTH="18%"><font face="Courier"><font size=-2>period;</font></font></td> <td VALIGN=TOP WIDTH="49%"><font face="Courier"><font size=-2>// period between pip</font></font></td> </tr> <tr> <td VALIGN=TOP WIDTH="4%"> </td> <td VALIGN=TOP WIDTH="29%"> </td> <td VALIGN=TOP WIDTH="18%"> </td> <td VALIGN=TOP WIDTH="49%"><font face="Courier"><font size=-2>// pulse in ms</font></font></td> </tr> <tr> <td VALIGN=TOP COLSPAN="2" WIDTH="33%"><font face="Courier"><font size=-2>} VPB_PIP;</font></font></td> <td VALIGN=TOP WIDTH="18%"> </td> <td VALIGN=TOP WIDTH="49%"> </td> </tr> </table> <br> <br> <p><b>Miscellaneous Functions</b> <p><u><font face="Courier"><font size=-2>vpb_get_model()</font></font></u> <p><u>vpb_sleep( )</u> <p><u>vpb_sethook_sync( )</u> <p><u>vpb_sethook_async( )</u> <p><u>vpb_translate_event( )</u> <p><u>vpb_open( )</u> <p><u>vpb_close( )</u> <p><u>vpb_seterrormode( )</u> <br> <br> <p><font size=-1>Solicited events are generated as a response to a previous API function call. For example, when </font><font face="Courier"><font size=-2>vpb_play_file_async()</font></font><font size=-1> is called, a solicited event of type </font><font face="Courier"><font size=-2>VPB_PLAYEND</font></font><font size=-1> is generated when the file has finished playing.</font> <br> <br> <p><font size=-1>Unsolicited events are generated in response to external conditions, for example due to a DTMF tone being detected by the VPB.</font> <br> <br> <br> <br> </body> </html>