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:
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) {
v.code, v.s, v.api_function);
}
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 | ![]() |
Toff | 0 | ![]() |
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:
For a dual frequency tone to pass the signal processing phase, the following conditions must be true:
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 | ![]() 100 Hz |
freq1 + bandwidth1/2
< 3900 Hz |
freq2 | 0 Hz | 4000 Hz |
bandwidth2 | ![]() 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 | ![]() |
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.