Programming

Introduction

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.

The following sections describe the VPB API in detail, and also include examples of the API functions in action.

It is recommended that the user browse the header file vpbapi.h to gain an overview of the API.

Compiling with the API

All of the examples have been tested using Microsoft Visual C 4.2. Compiler specific instructions refer to this compiler.

To use the API, first make sure vpbapi.dll is in your windows directory (the installation should have done this). Include vpbapi.h in your source files, and link your application with vpbapi.lib (build-settings-link tab, then add vpbapi.lib to the Object/library modules box).

The API will only work with 32 bit applications.

Initialisation and Shutdown

This section describes the "housekeeping" functions used to initialise and shutdown a VPB. The initialisation function vpb_open() must be called before any other API functions will work:

void main() {

handle = vpb_open(1, 2);

vpb_close(handle);

}
 
 

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.

The vpb_open() function returns a handle to the open channel. This handle then provides a reference to all other operations with this channel.

A call to vpb_open() 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.
 
 

An Integer that uniquely identifies a channel when using VPB API functions.
 
 

Numbering of Channels with Multiple VPBs

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.

To Determine the Channel Numbering of VPBs under Windows 95

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.

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.

To Determine the Channel Numbering of VPBs under Windows NT

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.
 
 

Error Handling

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:

The current error mode is set using the vpb_seterrormode() function. The default error mode Debug
 
 

Debug

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 console mode programs, it will cause the program to hang when used with a windows program.
 
 

Error Codes

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 VPBERR.H. There are other, undocumented error codes that lower levels of the API software may return, but these are not defined in VPBERR.H. These errors should not occur during normal operation.
 
 

Exceptions

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 VpbException 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 error code error handling method. The other members contain strings describing the API function that generated the error and a brief translation of the error code.

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.

Consider the following code fragments, first using error codes:

vpb_seterrormode(VPB_ERROR_CODE);
 
 

// Attempt to open channel 1
 
 

if ((handle1 = vpb_open(1,1)) != VPB_OK) {

printf("Error, code = %d\n",handle1);

exit(0);

}
 
 

// Attempt to open channel 2
 
 

if ((handle2 = vpb_open(1,2)) != VPB_OK) {

printf("Error, code = %d\n",handle2);

exit(0);

}
 
 

And now using exceptions:

try {

    vpb_seterrormode(VPB_EXCEPTION);

    handle1 = vpb_open(1,1);

    handle2 = vpb_open(1,2);

}

catch (VpbException v) {

printf("Error, code = %d, s = %s, api func = %s\n",

v.code, v.s, v.api_function);

exit(0);

}
 
 

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.

For more information on exceptions, see a C++ text, or your C++ compiler on-line documentation.
 
 
 
 
 
 
class VpbException {
public:  
  int code; // error code
  char s[VPB_MAX_STR]; // code translated

// into string

  char api_function[VPB_MAX_STR]; // api func that 

// threw exception

       
  VpbException(int c, char trans[], char api_function[]);
};  

 
 

Events

The VPB API uses an event driven programming model. There are two types of events, solicted, and unsolicited. The following functions deal with events:

vpb_disable_event()

vpb_enable_event( )

vpb_get_event_mask( )

vpb_set_event_mask( )

vpb_get_event_async( )

vpb_get_event_sync( )

vpb_get_event_ch_async( )

vpb_get_event_ch_sync( )

vpb_put_event( )
 
 
 
 

Play Functions

The API play functions are listed below:

vpb_play_file_sync()

vpb_play_file_async( )

vpb_play_voxfile_sync( )

vpb_play_voxfile_async( )

vpb_play_terminate( )

vpb_play_buf_start( )

vpb_play_buf_sync( )

vpb_play_buf_finish( )

vpb_play_set( )

vpb_play_set gain( )

vpb_play_get gain( )
 
 

Notes on the use of the Play Functions

The VPB API supports the playing of wave and vox files through the utility play routines. It also accommodates the playing of buffers from memory via the user defined play routines. The play functions can be configured to terminate when a DTMF digit is received using vpb_play_set(). The play functions may be prematurely stopped using vpb_play_terminate(). 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 vpb_play_set gain()
 
 

Record Functions
The API record functions are listed below:

vpb_record_file_sync()

vpb_record_file_async( )

vpb_record_voxfile_sync( )

vpb_record_voxfile_async( )

vpb_record_terminate( )

vpb_record_buf_start( )

vpb_record_buf_sync( )

vpb_record_buf_finish( )

vpb_record_set( )

vpb_record_set_gain( )

vpb_record_get_gain( )
 
 

Notes on the use of the Record Functions

The VPB API supports the recording of wave and vox files through the utility record routines. It also accommodates the recording of audio to memory via the user defined record routines. The record functions can be configured to terminate when a DTMF digit is received using vpb_record_set(). The record functions may be prematurely stopped using vpb_record_terminate(). 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 vpb_record_set gain().
 
 

Playing Audio Data

The API functions for playing audio are divided into two groups; utility functions, and user defined functions.

Utility Play Functions

The utility play functions are designed to make playing files straightforward.

The functions support wave files sampled at 8ksamples/s only, playing files that follow the wave file layout specification including 16 bit Linear, 8 bit A-Law & 8 bit Mu-Law.

vpb_play_file_sync()

vpb_play_file_async( )
 
 

There are also utility play functions that support vox audio files sampled at 8ksamples/s including; 16 bit Linear, 8 bit A-Law, 8 bit Mu-Law & 4 bit ADPCM.

vpb_play_voxfile_sync()

vpb_play_voxfile_async( )
 
 

User Defined Play Functions

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:

vpb_play_buf_start()

vpb_play_buf_sync( )

vpb_play_buf_finish( )
 
 
 

Compression (encoding) mode used to store samples.
 
 
Mode Description
VPB_LINEAR 128kbit/s, 16 bit linear, 8kHz sampling rate
VPB_ALAW 64kbit/s, A-Law companded
VPB_MULAW 64kbit/s, Mu-Law companded
VPB_OKIADPCM 32kbit/s, Oki-ADPCM, 4 bit, 8kHz sampling rate
VPB_OKIADPCM24 24kbit/s, Oki-ADPCM, 4 bit, 6kHz sampling rate

 
 

Voice File Format Support
 
 
Mode Wave support Vox support Platform
VPB_LINEAR YES YES VPB4, VPB8L
VPB_ALAW YES YES VPB4, VPB8L
VPB_MULAW YES YES VPB4, VPB8L
VPB_OKIADPCM NO YES VPB4, VPB8L
VPB_OKIADPCM24 NO YES VPB8L

 
 
 
 

Generic name for the file format (raw audio files) traditionally used by Dialogic hardware.
 
 

Recording Audio Data

The API functions for recording audio are divided into two groups; utility functions and user defined functions.

Utility Record Functions

The utility record functions are designed to make recording files straightforward.

The functions support wave files sampled at 6 and 8 ksamples/s, recording audio to files that follow the wave file layout specification including 16 bit Linear, 8 bit A-Law & 8 bit Mu-Law.

vpb_record_file_sync()

vpb_record_file_async( )
 
 

There are also utility record functions that support vox audio files sampled at 6 and 8 ksamples/s including; 16 bit Linear, 8 bit A-Law, 8 bit Mu-Law & 4 bit ADPCM.

vpb_record_voxfile_sync()

vpb_record_voxfile_async( )

User Defined Record Functions

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:

vpb_record_buf_start()

vpb_record_buf_sync( )

vpb_record_buf_finish( )
 
 

DTMF and Programmable Tone Generation

The following functions support tone generation on the VPB:

vpb_dial_async()

vpb_dial_sync( )

vpb_settone( )

vpb_gettone( )
 
 

Notes on Tone Generation

Tones (including DTMF) tones are generated on a channel using the vpb_settone( ) function.

All of the standard DTMF tones are defined at initialisation. Other user defined tones can be programmed at any time using the vpb_settone( ) function.

The standard DTMF tones can also be reprogrammed using the vpb_settone( ) function.

The tone generator parameters are constant across all VPB channels, they are not programmable on a channel by channel or board by board basis.

Up to 10 programmable tones can be defined, giving a total of 26 tones including the standard DTMF tones.

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.

There are limits in the tone generator parameters. Attempting to program a tone outside of these limits will generate an error.
 
 

0,1,2,3,4,5,6,7,8,9,#,*,A,B,C,D
 
 

typedef struct {

unsigned short freq1; // frequency of first tone

unsigned short freq2; // frequency of second tone

unsigned short freq3; // frequency of third tone

short level1; // first tone level in dB, -1dB maximum

short level2; // second tone level in dB, -1dB maximum

short level3; // third tone level in dB, -1dB maximum

unsigned long ton; // on time ms

unsigned long toff; // off time ms

} VPB_TONE;
 
 

Tone Generator Limits
 
 
Parameter Minimum Maximum
freq1, freq2, freq3 0 Hz 4000 Hz
level1, level2, level3 none -1 dB
Ton 0 ms
Toff 0 ms

 
 

Tone Detection

The following functions support programmable tone detection:

vpb_settonedet()

vpb_gettonedet( )

vpb_debug_tonedet( )

vpb_tonedet_make_default( )
 
 

Notes on Tone Detection

When a tone is detected, a VPB_TONEDETECT event is placed on the event queue with the tone identifier placed in the data element of the event structure.

There are 3 pre-defined tones, VPB_DIAL (dial tone), VPB_RINGBACK (ringback), and VPB_BUSY (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.

Up to VPB_MD (#define in vpbapi.h) tone detectors can be defined for each channel of each VPB. Counting the 3 pre-defined tones, VPB_MD-3 new user defined tones are available for the user, or the pre-defined tones may be redefined to give a total of VPB_MD user defined tones. To redefine a pre-defined tone, just specify the pre-defined tone identifier in the tone_id parameter of the VPB_DETECT structure when programming the tone.

Note: The VPB_MD (#define in vpbapi.h) 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.

The tone detectors of each channel are independent of the tone detectors of other channels. Thus each channel must be programmed independently with the vpb_settonedet()API function.
 
 

Programming the Tone Detectors

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.

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 vpb_settonedet() is called with a non-unique identifier (one which has been used before), then that programmable tone is redefined. If vpb_settonedet() is called with a unique identifier (one which has not been used before), then a new programmable tone is defined.

The structure VPB_DETECT 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.

Attempting to define a tone outside of the tone detector limits will cause an error.
 
 

Signal Detection Algorithm

For a single frequency tone to pass the signal processing phase, the following conditions must be true:

If the above conditions are met, then the signal is declared detected and is passed to the cadence detection stage for cadence analysis.

For a dual frequency tone to pass the signal processing phase, the following conditions must be true:

If the above conditions are met, then the signal is declared detected and is passed to the cadence detection stage for cadence analysis.
 
 

Cadence Detection Algorithm

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 (stran), and the number of states (nstates). The state transition table consists of an array of VPB_STRAN structures.

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 VPB_TONEDETECT is posted on the API event queue. A maximum of VPB_MS (#define in vpbapi.h) cadence states are allowed for each state machine.

There are three types of state transitions:
 
 
VPB_TIMER A state transition occurs when no change (transition) in the signal occurs for tfire ms.

If a transition occurs before time tfire, the state machine is reset to state 0.

The VPB_TIMER transition provides a way to measure the on time of signals without cadence, for example continuous dial tones.

VPB_DELAY It waits the desired time, tfire ms and goes to the next state.

The VPB_DELAY transition provides a way to wait a desired time irrespective of any signal transitions.

VPB_RISING 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 tmin and tmax ms.

If at the rising edge the time spent in this state is not between tmin and tmax ms, the state machine is reset to state 0.

If tmin and tmax 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.

The VPB_RISING transition provides a way to determine how long the signal was off.

VPB_FALLING 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 tmin and tmax ms.

If at the falling edge the time spent in this state is not between tmin and tmax ms, the state machine is reset to state 0.

If tmin and tmax 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.

The VPB_FALLING transition provides a way to determine how long the signal was on.


 
 

Programmable Tone Detector Tips

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.

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 VPB_MS (#define in vpbapi.h) limit.

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 nstates parameter in the VPB_DETECTstructure as extra states are added.

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.

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.
 
 

Programmable Tone Detector Examples

Example 1 - Continuous dial tone at 425 Hz, amplitude modulated at 25 Hz.

This discussion refers to the toned_dial variable below.

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 2nd frequency parameters are set to 0, which instructs the tone detector software to ignore the 2nd frequency.

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.

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.

The second state is a VPB_TIMER 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 VPB_DIAL in the data member of the VPB_EVENT structure.

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.
 
 
static VPB_DETECT toned_dial = {
  2, // number of cadence states
  VPB_DIAL, // tone id
  1, // number of tones
  425, // freq1
  100, // bandwidth1
  0, // freq2, N/A
  0, // bandwidth2, N/A
  -40, // level1
  0, // level2, N/A
  0, // twist, N/A
  10, // SNR
  40 // glitch duration 40ms
     
  RISING, // state 0
  0,  
  0,  
  0,  
     
  TIMER, // state 1
  2000,  
  0,  
  0  
};    

Example 2 - Austel Busy Tone 425 Hz or 400 Hz, 375 ms on, 375 ms off

This discussion refers to the toned_austel_busy variable below.

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.

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 VPB_AUSTEL_BUSY event is posted to the API queue. If any of these conditions fail then the state machine resets and no events are generated.
 
 
static VPB_DETECT toned_austel_busy = {
  3, // number of cadence states
  VPB_AUSTEL_BUSY, // tone id
  1, // number of tones
  425, // freq1
  100, // bandwidth1
  0, // freq2, N/A
  0, // bandwidth2: N/A
  -20, // level1
  0, // level2, N/A
  0, // twist: N/A
  10, // SNR: 10dB
  40 // glitch duration 40ms
     
  VPB_RISING, // state 0
  0,  
  0,  
  0,  
     
  VPB_FALLING, // state 1
  0,  
  300,  
  450,  
     
  VPB_RISING, // state 2
  0,  
  300,  
  450,  
};    

Example 3 - DTMF tone detection

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 toned_dtmf1 below illustrates the configuration for this tone.

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.

The cadence state machine looks for a rising edge, then the tone must be present for a minimum of 100 ms before a VPB_TONEDETECT event with the data member set to DTMF_1 (user #defined to a unique tone identifier) is posted.
 
 
static VPB_DETECT toned_dtmf1 = {
  2, // number of cadence states
  DTMF_1, // tone id
  2, // number of tones
  697, // f1: centre frequency
  100, // bw1: bandwidth
  1209, // f2: centre frequency
  100, // bw2: bandwidth
  -20, // A1: -20 dBm0
  -20, // A2: -20 dBm0
  10, // twist: 10 dB
  10, // SNR: 10 dB
  40 // glitch duration 40ms
     
  VPB_RISING, // state 0
  0,  
  0,  
  0,  
     
  VPB_TIMER, // state 1
  100,  
  0,  
  0  
};    

Example 4 - Grunt Detector used to detect wide band signals such as voice

This discussion refers to the toned_grunt variable below.

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.

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 VPB_GRUNT event is posted to the API queue. If any of these conditions fail then the state machine resets and no events are generated.
 
 
static VPB_DETECT toned_grunt = {
  2, // number of cadence states
  VPB_GRUNT, // tone id
  1, // number of tones
  2000, // freq1
  3000, // bandwidth1
  0, // freq2, N/A
  0, // bandwidth2: N/A
  -40, // level1 (-40 dB
  0, // level2, N/A
  0, // twist: N/A
  0, // SNR: N/A
  40 // glitch duration 40ms
     
  VPB_DELAY, // state 0
  1000,  
  0,  
  0,  
     
  VPB_RISING, // state 1
  0,  
  40,  
  0,  
     
};    

 
 
 
 
 
 
 
 

 
 

typedef struct {

   
  unsigned short nstates; // number of cadence states
  unsigned short tone_id; // unique ID number for this tone
  unsigned short ntones; // number of tones (1 or 2)
  unsigned short freq1; // freq of first tone (Hz)
  unsigned short bandwidth1; // bandwidth of first tone (Hz)
  unsigned short freq2; // freq of first tone (Hz)
  unsigned short bandwidth2; // bandwidth of second tone (Hz)
  short minlevel1; // min amp of 1st tone ref 0dBm0
  short minlevel2; // min amp of 2nd tone ref 0dbm0
  short twist; // allowable difference in tone

// powers

  short snr; // min signal to noise ratio to

// accept tone

  unsigned short glitch; // transitions of glitches 
      // ignored (ms)
       
  VPB_STRAN  stran[VPB_MS]; // cadence state transition table
} VPB_DETECT;    

 
 
 
 
 
 
 
 
typedef struct {    
  unsigned short type; // VPB_TIMER, VPB_DELAY, VPB_RISING,

// or VPB_FALLING

  unsigned short tfire; // timer mode only
  unsigned short tmin; // minimum tone on/off time

// (non timer) in ms

  unsigned short tmax; // maximum tone on/off time

// (non timer) in ms

} VPB_STRAN;    

 
 
 
 

Tone Detector Limits
 
 
Parameter Minimum Maximum
nstates 1 VPB_MS
tone_id 0
ntones 1 2
freq1 0 Hz 4000 Hz
bandwidth1 freq1 - bandwidth1/2

100 Hz

freq1 + bandwidth1/2

< 3900 Hz

freq2 0 Hz 4000 Hz
bandwidth2 freq2-bandwidth2/2

100 Hz

freq2+bandwidth2/2

< 3900 Hz

minlevel1 N/A 0
minlevel2 N/A 0
twist 0 N/A
snr 0 N/A
tfire, tmin, tmax 0 ms

 
 

Timers

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.

The following functions support the API timers:

vpb_timer_open()

vpb_timer_close( )

vpb_timer_start( )

vpb_timer_stop( )

vpb_timer_restart( )

vpb_timer_get_unique_timer_id( )

vpb_timer_change_period( )
 
 

Notes on Using Timers

Timers have two states, running, and stopped. When a timer is first created with vpb_timer_open(), the timer is in the stopped state. The timer can be placed in the running state using vpb_timer_start()or vpb_timer_restart(). When the timer period expires, it posts a VPB_TIMER event and resets itself to the stopped state. The timer can then be restarted using vpb_timer_start() or vpb_timer_restart() and the cycle repeated.

The timer can be restarted before its period has expired using vpb_timer_restart().

Timer events are classed as solicited events, they will always be posted to the event queue and cannot be masked out.
 
 

Wave Functions

The following functions allow the user to manipulate wave files through the VPB API.

vpb_wave_open_write()

vpb_wave_write( )

vpb_wave_close_write( )

vpb_wave_open_read( )

vpb_wave_read( )

vpb_wave_close_read( )

vpb_wave_set_sample_rate( )

vpb_wave_seek( )

vpb_wave_get_mode( )

Notes on using the Wave Functions

When writing to a wave file the user must initially open up a wave file using vpb_wave_open_write( ) to set up the appropriate wave format and filename. Writing to the file is then handled by vpb_wave_write( ). The wave file must be closed by the vpb_wave_close_write( ).

Reading a wave file requires a similar procedure, initially opening up the wave file using vpb_wave_open_read( ) to determine the file's wave format. Reading the file is then handled by vpb_wave_read( ). The wave file must be closed by the vpb_wave_close_read( ).

The vpb_wave_get_mode( ) obtains the compression format of a wave file. This function is useful in instances where the user-define  play routines are required.

The vpb_wave_seek( ) 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.

The VPB8L has two sampling rate options for recording , 6ksamples/s & 8ksamples/s. The vpb_wave_set_sample_rate( ) is specifically used to set the sampling rate of the wave file when the VPB8L is recording audio using the user-defined  record routines.
 

Get Digits Functions

The VPB API supports the collection of digits from a channel. This includes an asynchronous and synchronous version. The functions initiate collection of the digits from the channel and place them in a user digit buffer.

vpb_get_digits_sync()

vpb_get_digits_async( )

Notes on the use of Get Digits Functions

The conditions of termination for the functions may be configured via the VPB_DIGITS structure. In the asynchronous version, the condition of termination is passed to the data field of the VPB_EVENT  structure once the collection of digits from the channel to the user digit buffer has terminated. The synchronous version returns the appropriate termination code (see vpbapi.h) once the function has ended.

A flush function is also included to reset the user digit buffer.

vpb_flush_digits()

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.
 
 

Get Digit Termination codes
 
 
Termination code Description
VPB_DIGIT_TERM Termination due to a user-defined termination-digit being pressed
VPB_DIGIT_MAX Termination due to having reached the maximum number of digits 
VPB_DIGIT_TIME_OUT Termination due to the time limit to collect digits having expired
VPB_DIGIT_INTER_DIGIT_TIME_OUT Termination due to the inter-digit time limit having expired

 
 
 
 
 
 
 
 

 
 

typedef struct {

   
  char *term_digits; // string of digits to 
      // terminate
  unsigned short max_digits; // terminate after 
      // this many digits
  unsigned long digit_time_out; // max time for 
      // collection (ms)
  unsigned long inter_digit_time_out; // max time between 
      // digits (ms)
} VPB_DIGITS;    

 
 

Call Progress Functions

The VPB API enables a call to be placed using the call progress algorithm in both synchronous and asynchronous modes. It also enables the call progress parameters to be set or obtained for each channel.

vpb_get_call()

vpb_set_call( )

vpb_call_sync( )

vpb_call_async( )
 
 

Notes on the Call Progress Algorithm

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.

The VPB_CALL and VPB_TONE_MAP structures are used to define the parameters of the call progress algorithm.

In the asynchronous version, the status of the call is passed to the data field of the VPB_EVENT structure. The synchronous version returns the appropriate call progress return code (see vpbapi.h) once the function has ended.
 
 
 
 

Call Progress Return codes
 
 
Return code Description
VPB_CALL_CONNECTED Call is connected
VPB_CALL_NO_DIAL_TONE No dial tone is detected
VPB_CALL_NO_RING_BACK No ring back is detected
VPB_CALL_BUSY Call is busy
VPB_CALL_NO_ANSWER No answer is detected
VPB_CALL_DISCONNECTED Call is disconnected

 
 
 
 
 
 
 
 

 
 

typedef struct {

 
  unsigned int dialtones; // number of dialtones 
      // (default=1)
  unsigned int dialtone_timeout; // wait for dial tone 
      // timeout
      // (default=3000ms)
  unsigned int ringback_timeout; // time limit for 
      // initial ringback
      // (default=10000ms)
  unsigned int inter_ringback_timeout;  
      // ringback time out
      // when call is 
      // considered 
      // connected
      // (default=6000ms)
  unsigned int answer_timeout; // wait for answer
      // after ringback 
      // detected 
      // (default=3000ms)
  VPB_TONE_MAP tone_map[VPB_MAX_TONE_MAP];  
      // maps tone_id to call
      // progress tone
} VPB_CALL;    

 
 
 
 
 
 
 
 

 
 

typedef struct {

 
  unsigned int tone_id; // prog tone detector 
      // tone id
  unsigned int call_id; // call progress tone id
  unsigned int terminate; // non zero to terminate
  // list
} VPB_TONE_MAP;  

 
 
 
 

VOX Functions

The VPB API allows the user to control the VOX firmware for each channel.

vpb_getvox()

vpb_setvox( )

Note on the use of VOX Functions

The VOX algorithm switches on when the audio level exceeds onlevel. When the audio level falls beneath offlevel, a counter is started. When the counter exceeds runon 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 runon duration is 2000 ms. The VOX parameters may be re-programmed using the vpb_setvox() function.
 
 
 
 
 
 

 
 

typedef struct {

 
  float onlevel; // switch on level in dB 
      // (-2 max to -36 min)
  float offlevel; // switch off level in dB
      // (-2 max to -36 min)
  unsigned short runon; // run on time in ms
    // (50 ms min to 30000 ms max)
} VPB_VOX;    

 
 

Pip Functions

The following functions support pip generation on the VPB8L.

vpb_get_pip()

vpb_set_pip( )

vpb_pip_on( )

vpb_pip_off( )

Notes on the Pip Functions

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).

The pip parameters, the length of the pip pulse and the period between pulses, can be modified by vpb_set_pip(). The VPB_PIP structure contains these parameters.
 
 
 
 
 
 

 
 

typedef struct {

 
  unsigned int width; // width of pip pulse
      // in ms
  unsigned int period; // period between pip
      // pulse in ms
} VPB_PIP;    

 
 

Miscellaneous Functions

vpb_get_model()

vpb_sleep( )

vpb_sethook_sync( )

vpb_sethook_async( )

vpb_translate_event( )

vpb_open( )

vpb_close( )

vpb_seterrormode( )
 
 

Solicited events are generated as a response to a previous API function call. For example, when vpb_play_file_async() is called, a solicited event of type VPB_PLAYEND is generated when the file has finished playing.
 
 

Unsolicited events are generated in response to external conditions, for example due to a DTMF tone being detected by the VPB.