Sophie

Sophie

distrib > Mandriva > 8.2 > i586 > by-pkgid > c870e8e4b8db0e40e7f5488a777bd032 > files > 17

vpb-2.1.8-1mdk.i586.rpm

<!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>&nbsp;
<br>&nbsp;
<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>&nbsp;
<br>&nbsp;
<p><font size=-1>An Integer that uniquely identifies a channel when using
VPB API functions.</font>
<br>&nbsp;
<br>&nbsp;
<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>&nbsp;
<br>&nbsp;
<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>&nbsp;
<br>&nbsp;
<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>&nbsp;
<br>&nbsp;
<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>&nbsp;
<br>&nbsp;
<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>&nbsp;
<br>&nbsp;
<p><font face="Courier"><font size=-2>// Attempt to open channel 1</font></font>
<br>&nbsp;
<br>&nbsp;
<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>&nbsp;
<br>&nbsp;
<p><font face="Courier"><font size=-2>// Attempt to open channel 2</font></font>
<br>&nbsp;
<br>&nbsp;
<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>&nbsp;
<br>&nbsp;
<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>&nbsp;&nbsp;&nbsp; vpb_seterrormode(VPB_EXCEPTION);</font></font>
<p><font face="Courier"><font size=-2>&nbsp;&nbsp;&nbsp; handle1 = vpb_open(1,1);</font></font>
<p><font face="Courier"><font size=-2>&nbsp;&nbsp;&nbsp; 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>&nbsp;
<br>&nbsp;
<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>&nbsp;
<br>&nbsp;
<br>&nbsp;
<br>&nbsp;
<br>&nbsp;
<br>&nbsp;
<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%">&nbsp;</td>
</tr>

<tr>
<td VALIGN=TOP WIDTH="8%">&nbsp;</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%">&nbsp;</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%">&nbsp;</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&nbsp;</font></font>
<p><font face="Courier"><font size=-2>// threw exception</font></font></td>
</tr>

<tr>
<td VALIGN=TOP WIDTH="8%">&nbsp;</td>

<td VALIGN=TOP WIDTH="10%">&nbsp;</td>

<td VALIGN=TOP WIDTH="47%">&nbsp;</td>

<td VALIGN=TOP WIDTH="35%">&nbsp;</td>
</tr>

<tr>
<td VALIGN=TOP WIDTH="8%">&nbsp;</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%">&nbsp;</td>
</tr>
</table>

<br>&nbsp;
<br>&nbsp;
<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>&nbsp;
<br>&nbsp;
<br>&nbsp;
<br>&nbsp;
<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>&nbsp;
<br>&nbsp;
<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>&nbsp;
<br>&nbsp;
<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>&nbsp;
<br>&nbsp;
<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>&nbsp;
<br>&nbsp;
<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 &amp; 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>&nbsp;
<br>&nbsp;
<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 &amp; 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>&nbsp;
<br>&nbsp;
<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>&nbsp;
<br>&nbsp;
<br>&nbsp;
<p><font size=-1>Compression (encoding) mode used to store samples.</font>
<br>&nbsp;
<br>&nbsp;
<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>&nbsp;
<br>&nbsp;
<p><font size=-1>Voice File Format Support</font>
<br>&nbsp;
<br>&nbsp;
<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>&nbsp;
<br>&nbsp;
<br>&nbsp;
<br>&nbsp;
<p><font size=-1>Generic name for the file format (raw audio files) traditionally
used by Dialogic hardware.</font>
<br>&nbsp;
<br>&nbsp;
<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 &amp; 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>&nbsp;
<br>&nbsp;
<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 &amp; 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>&nbsp;
<br>&nbsp;
<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>&nbsp;
<br>&nbsp;
<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>&nbsp;
<br>&nbsp;
<p><font size=-1>0,1,2,3,4,5,6,7,8,9,#,*,A,B,C,D</font>
<br>&nbsp;
<br>&nbsp;
<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>&nbsp;
<br>&nbsp;
<p><b>Tone Generator Limits</b>
<br>&nbsp;
<br>&nbsp;
<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>&nbsp;
<br>&nbsp;
<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>&nbsp;
<br>&nbsp;
<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>&nbsp;
<br>&nbsp;
<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>&nbsp;
<br>&nbsp;
<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>&nbsp;
<br>&nbsp;
<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>&nbsp;
<br>&nbsp;
<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>&nbsp;
<br>&nbsp;
<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>&nbsp;
<br>&nbsp;
<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>&nbsp;
<br>&nbsp;
<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%">&nbsp;</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%">&nbsp;</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%">&nbsp;</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%">&nbsp;</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%">&nbsp;</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%">&nbsp;</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%">&nbsp;</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%">&nbsp;</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%">&nbsp;</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%">&nbsp;</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%">&nbsp;</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%">&nbsp;</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%">&nbsp;</td>

<td VALIGN=TOP WIDTH="21%">&nbsp;</td>

<td VALIGN=TOP WIDTH="67%">&nbsp;</td>
</tr>

<tr>
<td VALIGN=TOP WIDTH="13%">&nbsp;</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%">&nbsp;</td>

<td VALIGN=TOP WIDTH="21%"><font face="Courier"><font size=-2>0,</font></font></td>

<td VALIGN=TOP WIDTH="67%">&nbsp;</td>
</tr>

<tr>
<td VALIGN=TOP WIDTH="13%">&nbsp;</td>

<td VALIGN=TOP WIDTH="21%"><font face="Courier"><font size=-2>0,</font></font></td>

<td VALIGN=TOP WIDTH="67%">&nbsp;</td>
</tr>

<tr>
<td VALIGN=TOP WIDTH="13%">&nbsp;</td>

<td VALIGN=TOP WIDTH="21%"><font face="Courier"><font size=-2>0,</font></font></td>

<td VALIGN=TOP WIDTH="67%">&nbsp;</td>
</tr>

<tr>
<td VALIGN=TOP WIDTH="13%">&nbsp;</td>

<td VALIGN=TOP WIDTH="21%">&nbsp;</td>

<td VALIGN=TOP WIDTH="67%">&nbsp;</td>
</tr>

<tr>
<td VALIGN=TOP WIDTH="13%">&nbsp;</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%">&nbsp;</td>

<td VALIGN=TOP WIDTH="21%"><font face="Courier"><font size=-2>2000,</font></font></td>

<td VALIGN=TOP WIDTH="67%">&nbsp;</td>
</tr>

<tr>
<td VALIGN=TOP WIDTH="13%">&nbsp;</td>

<td VALIGN=TOP WIDTH="21%"><font face="Courier"><font size=-2>0,</font></font></td>

<td VALIGN=TOP WIDTH="67%">&nbsp;</td>
</tr>

<tr>
<td VALIGN=TOP WIDTH="13%">&nbsp;</td>

<td VALIGN=TOP WIDTH="21%"><font face="Courier"><font size=-2>0</font></font></td>

<td VALIGN=TOP WIDTH="67%">&nbsp;</td>
</tr>

<tr>
<td VALIGN=TOP WIDTH="13%"><font face="Courier"><font size=-2>};</font></font></td>

<td VALIGN=TOP WIDTH="21%">&nbsp;</td>

<td VALIGN=TOP WIDTH="67%">&nbsp;</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>&nbsp;
<br>&nbsp;
<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%">&nbsp;</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%">&nbsp;</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%">&nbsp;</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%">&nbsp;</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%">&nbsp;</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%">&nbsp;</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%">&nbsp;</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%">&nbsp;</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%">&nbsp;</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%">&nbsp;</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%">&nbsp;</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%">&nbsp;</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%">&nbsp;</td>

<td VALIGN=TOP WIDTH="28%">&nbsp;</td>

<td VALIGN=TOP WIDTH="60%">&nbsp;</td>
</tr>

<tr>
<td VALIGN=TOP WIDTH="13%">&nbsp;</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%">&nbsp;</td>

<td VALIGN=TOP WIDTH="28%"><font face="Courier"><font size=-2>0,</font></font></td>

<td VALIGN=TOP WIDTH="60%">&nbsp;</td>
</tr>

<tr>
<td VALIGN=TOP WIDTH="13%">&nbsp;</td>

<td VALIGN=TOP WIDTH="28%"><font face="Courier"><font size=-2>0,</font></font></td>

<td VALIGN=TOP WIDTH="60%">&nbsp;</td>
</tr>

<tr>
<td VALIGN=TOP WIDTH="13%">&nbsp;</td>

<td VALIGN=TOP WIDTH="28%"><font face="Courier"><font size=-2>0,</font></font></td>

<td VALIGN=TOP WIDTH="60%">&nbsp;</td>
</tr>

<tr>
<td VALIGN=TOP WIDTH="13%">&nbsp;</td>

<td VALIGN=TOP WIDTH="28%">&nbsp;</td>

<td VALIGN=TOP WIDTH="60%">&nbsp;</td>
</tr>

<tr>
<td VALIGN=TOP WIDTH="13%">&nbsp;</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%">&nbsp;</td>

<td VALIGN=TOP WIDTH="28%"><font face="Courier"><font size=-2>0,</font></font></td>

<td VALIGN=TOP WIDTH="60%">&nbsp;</td>
</tr>

<tr>
<td VALIGN=TOP WIDTH="13%">&nbsp;</td>

<td VALIGN=TOP WIDTH="28%"><font face="Courier"><font size=-2>300,</font></font></td>

<td VALIGN=TOP WIDTH="60%">&nbsp;</td>
</tr>

<tr>
<td VALIGN=TOP WIDTH="13%">&nbsp;</td>

<td VALIGN=TOP WIDTH="28%"><font face="Courier"><font size=-2>450,</font></font></td>

<td VALIGN=TOP WIDTH="60%">&nbsp;</td>
</tr>

<tr>
<td VALIGN=TOP WIDTH="13%">&nbsp;</td>

<td VALIGN=TOP WIDTH="28%">&nbsp;</td>

<td VALIGN=TOP WIDTH="60%">&nbsp;</td>
</tr>

<tr>
<td VALIGN=TOP WIDTH="13%">&nbsp;</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%">&nbsp;</td>

<td VALIGN=TOP WIDTH="28%"><font face="Courier"><font size=-2>0,</font></font></td>

<td VALIGN=TOP WIDTH="60%">&nbsp;</td>
</tr>

<tr>
<td VALIGN=TOP WIDTH="13%">&nbsp;</td>

<td VALIGN=TOP WIDTH="28%"><font face="Courier"><font size=-2>300,</font></font></td>

<td VALIGN=TOP WIDTH="60%">&nbsp;</td>
</tr>

<tr>
<td VALIGN=TOP WIDTH="13%">&nbsp;</td>

<td VALIGN=TOP WIDTH="28%"><font face="Courier"><font size=-2>450,</font></font></td>

<td VALIGN=TOP WIDTH="60%">&nbsp;</td>
</tr>

<tr>
<td VALIGN=TOP WIDTH="13%"><font face="Courier"><font size=-2>};</font></font></td>

<td VALIGN=TOP WIDTH="28%">&nbsp;</td>

<td VALIGN=TOP WIDTH="60%">&nbsp;</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>&nbsp;
<br>&nbsp;
<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%">&nbsp;</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%">&nbsp;</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%">&nbsp;</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%">&nbsp;</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%">&nbsp;</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%">&nbsp;</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%">&nbsp;</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%">&nbsp;</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%">&nbsp;</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%">&nbsp;</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%">&nbsp;</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%">&nbsp;</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%">&nbsp;</td>

<td VALIGN=TOP WIDTH="28%">&nbsp;</td>

<td VALIGN=TOP WIDTH="60%">&nbsp;</td>
</tr>

<tr>
<td VALIGN=TOP WIDTH="13%">&nbsp;</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%">&nbsp;</td>

<td VALIGN=TOP WIDTH="28%"><font face="Courier"><font size=-2>0,</font></font></td>

<td VALIGN=TOP WIDTH="60%">&nbsp;</td>
</tr>

<tr>
<td VALIGN=TOP WIDTH="13%">&nbsp;</td>

<td VALIGN=TOP WIDTH="28%"><font face="Courier"><font size=-2>0,</font></font></td>

<td VALIGN=TOP WIDTH="60%">&nbsp;</td>
</tr>

<tr>
<td VALIGN=TOP WIDTH="13%">&nbsp;</td>

<td VALIGN=TOP WIDTH="28%"><font face="Courier"><font size=-2>0,</font></font></td>

<td VALIGN=TOP WIDTH="60%">&nbsp;</td>
</tr>

<tr>
<td VALIGN=TOP WIDTH="13%">&nbsp;</td>

<td VALIGN=TOP WIDTH="28%">&nbsp;</td>

<td VALIGN=TOP WIDTH="60%">&nbsp;</td>
</tr>

<tr>
<td VALIGN=TOP WIDTH="13%">&nbsp;</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%">&nbsp;</td>

<td VALIGN=TOP WIDTH="28%"><font face="Courier"><font size=-2>100,</font></font></td>

<td VALIGN=TOP WIDTH="60%">&nbsp;</td>
</tr>

<tr>
<td VALIGN=TOP WIDTH="13%">&nbsp;</td>

<td VALIGN=TOP WIDTH="28%"><font face="Courier"><font size=-2>0,</font></font></td>

<td VALIGN=TOP WIDTH="60%">&nbsp;</td>
</tr>

<tr>
<td VALIGN=TOP WIDTH="13%">&nbsp;</td>

<td VALIGN=TOP WIDTH="28%"><font face="Courier"><font size=-2>0</font></font></td>

<td VALIGN=TOP WIDTH="60%">&nbsp;</td>
</tr>

<tr>
<td VALIGN=TOP WIDTH="13%"><font face="Courier"><font size=-2>};</font></font></td>

<td VALIGN=TOP WIDTH="28%">&nbsp;</td>

<td VALIGN=TOP WIDTH="60%">&nbsp;</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>&nbsp;
<br>&nbsp;
<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%">&nbsp;</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%">&nbsp;</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%">&nbsp;</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%">&nbsp;</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%">&nbsp;</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%">&nbsp;</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%">&nbsp;</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%">&nbsp;</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%">&nbsp;</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%">&nbsp;</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%">&nbsp;</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%">&nbsp;</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%">&nbsp;</td>

<td VALIGN=TOP WIDTH="28%">&nbsp;</td>

<td VALIGN=TOP WIDTH="60%">&nbsp;</td>
</tr>

<tr>
<td VALIGN=TOP WIDTH="13%">&nbsp;</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%">&nbsp;</td>

<td VALIGN=TOP WIDTH="28%"><font face="Courier"><font size=-2>1000,</font></font></td>

<td VALIGN=TOP WIDTH="60%">&nbsp;</td>
</tr>

<tr>
<td VALIGN=TOP WIDTH="13%">&nbsp;</td>

<td VALIGN=TOP WIDTH="28%"><font face="Courier"><font size=-2>0,</font></font></td>

<td VALIGN=TOP WIDTH="60%">&nbsp;</td>
</tr>

<tr>
<td VALIGN=TOP WIDTH="13%">&nbsp;</td>

<td VALIGN=TOP WIDTH="28%"><font face="Courier"><font size=-2>0,</font></font></td>

<td VALIGN=TOP WIDTH="60%">&nbsp;</td>
</tr>

<tr>
<td VALIGN=TOP WIDTH="13%">&nbsp;</td>

<td VALIGN=TOP WIDTH="28%">&nbsp;</td>

<td VALIGN=TOP WIDTH="60%">&nbsp;</td>
</tr>

<tr>
<td VALIGN=TOP WIDTH="13%">&nbsp;</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%">&nbsp;</td>

<td VALIGN=TOP WIDTH="28%"><font face="Courier"><font size=-2>0,</font></font></td>

<td VALIGN=TOP WIDTH="60%">&nbsp;</td>
</tr>

<tr>
<td VALIGN=TOP WIDTH="13%">&nbsp;</td>

<td VALIGN=TOP WIDTH="28%"><font face="Courier"><font size=-2>40,</font></font></td>

<td VALIGN=TOP WIDTH="60%">&nbsp;</td>
</tr>

<tr>
<td VALIGN=TOP WIDTH="13%">&nbsp;</td>

<td VALIGN=TOP WIDTH="28%"><font face="Courier"><font size=-2>0,</font></font></td>

<td VALIGN=TOP WIDTH="60%">&nbsp;</td>
</tr>

<tr>
<td VALIGN=TOP WIDTH="13%">&nbsp;</td>

<td VALIGN=TOP WIDTH="28%">&nbsp;</td>

<td VALIGN=TOP WIDTH="60%">&nbsp;</td>
</tr>

<tr>
<td VALIGN=TOP WIDTH="13%"><font face="Courier"><font size=-2>};</font></font></td>

<td VALIGN=TOP WIDTH="28%">&nbsp;</td>

<td VALIGN=TOP WIDTH="60%">&nbsp;</td>
</tr>
</table>

<br>&nbsp;
<br>&nbsp;
<br>&nbsp;
<br>&nbsp;
<br>&nbsp;
<br>&nbsp;
<br>&nbsp;
<br>&nbsp;
<table BORDER=0 CELLSPACING=0 CELLPADDING=7 WIDTH="547" >
<tr>
<td VALIGN=TOP COLSPAN="2" WIDTH="29%">
<br>&nbsp;
<br>&nbsp;
<p><font face="Courier"><font size=-2>typedef struct {</font></font></td>

<td VALIGN=TOP WIDTH="20%">&nbsp;</td>

<td VALIGN=TOP WIDTH="52%">&nbsp;</td>
</tr>

<tr>
<td VALIGN=TOP WIDTH="7%">&nbsp;</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%">&nbsp;</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%">&nbsp;</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%">&nbsp;</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%">&nbsp;</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%">&nbsp;</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%">&nbsp;</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%">&nbsp;</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%">&nbsp;</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%">&nbsp;</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%">&nbsp;</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%">&nbsp;</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&nbsp;</font></font></td>
</tr>

<tr>
<td VALIGN=TOP WIDTH="7%">&nbsp;</td>

<td VALIGN=TOP WIDTH="22%">&nbsp;</td>

<td VALIGN=TOP WIDTH="20%">&nbsp;</td>

<td VALIGN=TOP WIDTH="52%"><font face="Courier"><font size=-2>// ignored
(ms)</font></font></td>
</tr>

<tr>
<td VALIGN=TOP WIDTH="7%">&nbsp;</td>

<td VALIGN=TOP WIDTH="22%">&nbsp;</td>

<td VALIGN=TOP WIDTH="20%">&nbsp;</td>

<td VALIGN=TOP WIDTH="52%">&nbsp;</td>
</tr>

<tr>
<td VALIGN=TOP WIDTH="7%">&nbsp;</td>

<td VALIGN=TOP WIDTH="22%"><font face="Courier"><font size=-2>VPB_STRAN&nbsp;</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%">&nbsp;</td>

<td VALIGN=TOP WIDTH="52%">&nbsp;</td>
</tr>
</table>

<br>&nbsp;
<br>&nbsp;
<br>&nbsp;
<br>&nbsp;
<br>&nbsp;
<br>&nbsp;
<br>&nbsp;
<br>&nbsp;
<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%">&nbsp;</td>

<td VALIGN=TOP WIDTH="52%">&nbsp;</td>
</tr>

<tr>
<td VALIGN=TOP WIDTH="7%">&nbsp;</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%">&nbsp;</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%">&nbsp;</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%">&nbsp;</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%">&nbsp;</td>

<td VALIGN=TOP WIDTH="52%">&nbsp;</td>
</tr>
</table>

<br>&nbsp;
<br>&nbsp;
<br>&nbsp;
<br>&nbsp;
<p><b>Tone Detector Limits</b>
<br>&nbsp;
<br>&nbsp;
<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>&lt; 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>&lt; 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>&nbsp;
<br>&nbsp;
<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>&nbsp;
<br>&nbsp;
<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>&nbsp;
<br>&nbsp;
<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&nbsp;</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 &amp; 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&nbsp;</u></font> record
routines.
<br>&nbsp;
<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>&nbsp;
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>&nbsp;
<br>&nbsp;
<p><b>Get Digit Termination codes</b>
<br>&nbsp;
<br>&nbsp;
<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&nbsp;</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>&nbsp;
<br>&nbsp;
<br>&nbsp;
<br>&nbsp;
<br>&nbsp;
<br>&nbsp;
<br>&nbsp;
<br>&nbsp;
<table BORDER=0 CELLSPACING=0 CELLPADDING=7 WIDTH="517" >
<tr>
<td VALIGN=TOP COLSPAN="2" WIDTH="31%">
<br>&nbsp;
<br>&nbsp;
<p><font face="Courier"><font size=-2>typedef struct {</font></font></td>

<td VALIGN=TOP WIDTH="32%">&nbsp;</td>

<td VALIGN=TOP WIDTH="37%">&nbsp;</td>
</tr>

<tr>
<td VALIGN=TOP WIDTH="8%">&nbsp;</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&nbsp;</font></font></td>
</tr>

<tr>
<td VALIGN=TOP WIDTH="8%">&nbsp;</td>

<td VALIGN=TOP WIDTH="23%">&nbsp;</td>

<td VALIGN=TOP WIDTH="32%">&nbsp;</td>

<td VALIGN=TOP WIDTH="37%"><font face="Courier"><font size=-2>// terminate</font></font></td>
</tr>

<tr>
<td VALIGN=TOP WIDTH="8%">&nbsp;</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&nbsp;</font></font></td>
</tr>

<tr>
<td VALIGN=TOP WIDTH="8%">&nbsp;</td>

<td VALIGN=TOP WIDTH="23%">&nbsp;</td>

<td VALIGN=TOP WIDTH="32%">&nbsp;</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%">&nbsp;</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&nbsp;</font></font></td>
</tr>

<tr>
<td VALIGN=TOP WIDTH="8%">&nbsp;</td>

<td VALIGN=TOP WIDTH="23%">&nbsp;</td>

<td VALIGN=TOP WIDTH="32%">&nbsp;</td>

<td VALIGN=TOP WIDTH="37%"><font face="Courier"><font size=-2>// collection
(ms)</font></font></td>
</tr>

<tr>
<td VALIGN=TOP WIDTH="8%">&nbsp;</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&nbsp;</font></font></td>
</tr>

<tr>
<td VALIGN=TOP WIDTH="8%">&nbsp;</td>

<td VALIGN=TOP WIDTH="23%">&nbsp;</td>

<td VALIGN=TOP WIDTH="32%">&nbsp;</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%">&nbsp;</td>

<td VALIGN=TOP WIDTH="37%">&nbsp;</td>
</tr>
</table>

<br>&nbsp;
<br>&nbsp;
<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>&nbsp;
<br>&nbsp;
<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>&nbsp;
<br>&nbsp;
<br>&nbsp;
<br>&nbsp;
<p><b>Call Progress Return codes</b>
<br>&nbsp;
<br>&nbsp;
<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>&nbsp;
<br>&nbsp;
<br>&nbsp;
<br>&nbsp;
<br>&nbsp;
<br>&nbsp;
<br>&nbsp;
<br>&nbsp;
<table BORDER=0 CELLSPACING=0 CELLPADDING=7 WIDTH="505" >
<tr>
<td VALIGN=TOP COLSPAN="3" WIDTH="62%">
<br>&nbsp;
<br>&nbsp;
<p><font face="Courier"><font size=-2>typedef struct {</font></font></td>

<td VALIGN=TOP WIDTH="38%">&nbsp;</td>
</tr>

<tr>
<td VALIGN=TOP WIDTH="3%">&nbsp;</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&nbsp;</font></font></td>
</tr>

<tr>
<td VALIGN=TOP WIDTH="3%">&nbsp;</td>

<td VALIGN=TOP WIDTH="21%">&nbsp;</td>

<td VALIGN=TOP WIDTH="38%">&nbsp;</td>

<td VALIGN=TOP WIDTH="38%"><font face="Courier"><font size=-2>// (default=1)</font></font></td>
</tr>

<tr>
<td VALIGN=TOP WIDTH="3%">&nbsp;</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&nbsp;</font></font></td>
</tr>

<tr>
<td VALIGN=TOP WIDTH="3%">&nbsp;</td>

<td VALIGN=TOP WIDTH="21%">&nbsp;</td>

<td VALIGN=TOP WIDTH="38%">&nbsp;</td>

<td VALIGN=TOP WIDTH="38%"><font face="Courier"><font size=-2>// timeout</font></font></td>
</tr>

<tr>
<td VALIGN=TOP WIDTH="3%">&nbsp;</td>

<td VALIGN=TOP WIDTH="21%">&nbsp;</td>

<td VALIGN=TOP WIDTH="38%">&nbsp;</td>

<td VALIGN=TOP WIDTH="38%"><font face="Courier"><font size=-2>// (default=3000ms)</font></font></td>
</tr>

<tr>
<td VALIGN=TOP WIDTH="3%">&nbsp;</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&nbsp;</font></font></td>
</tr>

<tr>
<td VALIGN=TOP WIDTH="3%">&nbsp;</td>

<td VALIGN=TOP WIDTH="21%">&nbsp;</td>

<td VALIGN=TOP WIDTH="38%">&nbsp;</td>

<td VALIGN=TOP WIDTH="38%"><font face="Courier"><font size=-2>// initial
ringback</font></font></td>
</tr>

<tr>
<td VALIGN=TOP WIDTH="3%">&nbsp;</td>

<td VALIGN=TOP WIDTH="21%">&nbsp;</td>

<td VALIGN=TOP WIDTH="38%">&nbsp;</td>

<td VALIGN=TOP WIDTH="38%"><font face="Courier"><font size=-2>// (default=10000ms)</font></font></td>
</tr>

<tr>
<td VALIGN=TOP WIDTH="3%">&nbsp;</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%">&nbsp;</td>
</tr>

<tr>
<td VALIGN=TOP WIDTH="3%">&nbsp;</td>

<td VALIGN=TOP WIDTH="21%">&nbsp;</td>

<td VALIGN=TOP WIDTH="38%">&nbsp;</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%">&nbsp;</td>

<td VALIGN=TOP WIDTH="21%">&nbsp;</td>

<td VALIGN=TOP WIDTH="38%">&nbsp;</td>

<td VALIGN=TOP WIDTH="38%"><font face="Courier"><font size=-2>// when call
is&nbsp;</font></font></td>
</tr>

<tr>
<td VALIGN=TOP WIDTH="3%">&nbsp;</td>

<td VALIGN=TOP WIDTH="21%">&nbsp;</td>

<td VALIGN=TOP WIDTH="38%">&nbsp;</td>

<td VALIGN=TOP WIDTH="38%"><font face="Courier"><font size=-2>// considered&nbsp;</font></font></td>
</tr>

<tr>
<td VALIGN=TOP WIDTH="3%">&nbsp;</td>

<td VALIGN=TOP WIDTH="21%">&nbsp;</td>

<td VALIGN=TOP WIDTH="38%">&nbsp;</td>

<td VALIGN=TOP WIDTH="38%"><font face="Courier"><font size=-2>// connected</font></font></td>
</tr>

<tr>
<td VALIGN=TOP WIDTH="3%">&nbsp;</td>

<td VALIGN=TOP WIDTH="21%">&nbsp;</td>

<td VALIGN=TOP WIDTH="38%">&nbsp;</td>

<td VALIGN=TOP WIDTH="38%"><font face="Courier"><font size=-2>// (default=6000ms)</font></font></td>
</tr>

<tr>
<td VALIGN=TOP WIDTH="3%">&nbsp;</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%">&nbsp;</td>

<td VALIGN=TOP WIDTH="21%">&nbsp;</td>

<td VALIGN=TOP WIDTH="38%">&nbsp;</td>

<td VALIGN=TOP WIDTH="38%"><font face="Courier"><font size=-2>// after
ringback&nbsp;</font></font></td>
</tr>

<tr>
<td VALIGN=TOP WIDTH="3%">&nbsp;</td>

<td VALIGN=TOP WIDTH="21%">&nbsp;</td>

<td VALIGN=TOP WIDTH="38%">&nbsp;</td>

<td VALIGN=TOP WIDTH="38%"><font face="Courier"><font size=-2>// detected&nbsp;</font></font></td>
</tr>

<tr>
<td VALIGN=TOP WIDTH="3%">&nbsp;</td>

<td VALIGN=TOP WIDTH="21%">&nbsp;</td>

<td VALIGN=TOP WIDTH="38%">&nbsp;</td>

<td VALIGN=TOP WIDTH="38%"><font face="Courier"><font size=-2>// (default=3000ms)</font></font></td>
</tr>

<tr>
<td VALIGN=TOP WIDTH="3%">&nbsp;</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%">&nbsp;</td>
</tr>

<tr>
<td VALIGN=TOP WIDTH="3%">&nbsp;</td>

<td VALIGN=TOP WIDTH="21%">&nbsp;</td>

<td VALIGN=TOP WIDTH="38%">&nbsp;</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%">&nbsp;</td>

<td VALIGN=TOP WIDTH="21%">&nbsp;</td>

<td VALIGN=TOP WIDTH="38%">&nbsp;</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%">&nbsp;</td>

<td VALIGN=TOP WIDTH="38%">&nbsp;</td>
</tr>
</table>

<br>&nbsp;
<br>&nbsp;
<br>&nbsp;
<br>&nbsp;
<br>&nbsp;
<br>&nbsp;
<br>&nbsp;
<br>&nbsp;
<table BORDER=0 CELLSPACING=0 CELLPADDING=7 WIDTH="427" >
<tr>
<td VALIGN=TOP COLSPAN="3" WIDTH="50%">
<br>&nbsp;
<br>&nbsp;
<p><font face="Courier"><font size=-2>typedef struct {</font></font></td>

<td VALIGN=TOP WIDTH="51%">&nbsp;</td>
</tr>

<tr>
<td VALIGN=TOP WIDTH="4%">&nbsp;</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&nbsp;</font></font></td>
</tr>

<tr>
<td VALIGN=TOP WIDTH="4%">&nbsp;</td>

<td VALIGN=TOP WIDTH="25%">&nbsp;</td>

<td VALIGN=TOP WIDTH="21%">&nbsp;</td>

<td VALIGN=TOP WIDTH="51%"><font face="Courier"><font size=-2>// tone id</font></font></td>
</tr>

<tr>
<td VALIGN=TOP WIDTH="4%">&nbsp;</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%">&nbsp;</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%">&nbsp;</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%">&nbsp;</td>
</tr>
</table>

<br>&nbsp;
<br>&nbsp;
<br>&nbsp;
<br>&nbsp;
<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>&nbsp;
<br>&nbsp;
<br>&nbsp;
<br>&nbsp;
<br>&nbsp;
<br>&nbsp;
<table BORDER=0 CELLSPACING=0 CELLPADDING=7 WIDTH="469" >
<tr>
<td VALIGN=TOP COLSPAN="3" WIDTH="54%">
<br>&nbsp;
<br>&nbsp;
<p><font face="Courier"><font size=-2>typedef struct {</font></font></td>

<td VALIGN=TOP WIDTH="46%">&nbsp;</td>
</tr>

<tr>
<td VALIGN=TOP WIDTH="3%">&nbsp;</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&nbsp;</font></font></td>
</tr>

<tr>
<td VALIGN=TOP WIDTH="3%">&nbsp;</td>

<td VALIGN=TOP WIDTH="28%">&nbsp;</td>

<td VALIGN=TOP WIDTH="23%">&nbsp;</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%">&nbsp;</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%">&nbsp;</td>

<td VALIGN=TOP WIDTH="28%">&nbsp;</td>

<td VALIGN=TOP WIDTH="23%">&nbsp;</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%">&nbsp;</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%">&nbsp;</td>

<td VALIGN=TOP WIDTH="23%">&nbsp;</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%">&nbsp;</td>

<td VALIGN=TOP WIDTH="46%">&nbsp;</td>
</tr>
</table>

<br>&nbsp;
<br>&nbsp;
<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>&nbsp;
<br>&nbsp;
<br>&nbsp;
<br>&nbsp;
<br>&nbsp;
<br>&nbsp;
<table BORDER=0 CELLSPACING=0 CELLPADDING=7 WIDTH="439" >
<tr>
<td VALIGN=TOP COLSPAN="3" WIDTH="51%">
<br>&nbsp;
<br>&nbsp;
<p><font face="Courier"><font size=-2>typedef struct {</font></font></td>

<td VALIGN=TOP WIDTH="49%">&nbsp;</td>
</tr>

<tr>
<td VALIGN=TOP WIDTH="4%">&nbsp;</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%">&nbsp;</td>

<td VALIGN=TOP WIDTH="29%">&nbsp;</td>

<td VALIGN=TOP WIDTH="18%">&nbsp;</td>

<td VALIGN=TOP WIDTH="49%"><font face="Courier"><font size=-2>// in ms</font></font></td>
</tr>

<tr>
<td VALIGN=TOP WIDTH="4%">&nbsp;</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%">&nbsp;</td>

<td VALIGN=TOP WIDTH="29%">&nbsp;</td>

<td VALIGN=TOP WIDTH="18%">&nbsp;</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%">&nbsp;</td>

<td VALIGN=TOP WIDTH="49%">&nbsp;</td>
</tr>
</table>

<br>&nbsp;
<br>&nbsp;
<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>&nbsp;
<br>&nbsp;
<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>&nbsp;
<br>&nbsp;
<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>&nbsp;
<br>&nbsp;
<br>&nbsp;
<br>&nbsp;
</body>
</html>