# Events

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

- `vpb_enable_event()`
- `vpb_disable_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()`

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

## Playing and Recording Audio

## Summary of 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()`

The VPBAPI supports the playing of WAVE and VOX and AU files. 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 asyncronous 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()`.

## Summary of 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()`

The VPBAPI supports the recording of audio files. 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 asyncronous 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

The API functions for playing audio are divided into two groups; file-based functions, and buffer-based functions.

The file-based play functions are designed to make playing files straightforward. These functions support WAVE and AU files sampled at 8 ksamples/s only, playing files that follow the WAVE and AU file specification including for 16 bit Linear, 8 bit A-Law, 8 bit Mu-Law.

- `vpb_play_file_sync()`
- `vpb_play_file_async()`

There are also file-based play functions that support VOX (headerless) audio files sampled at 8 ksamples/s including; 16 bit Linear, 8 bit A-Law, 8 bit Mu-Law.

- `vpb_play_voxfile_sync()`
- `vpb_play_voxfile_async()`

The buffer-based play functions allow the development of custom play routines in situations where the file-based 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

## Recording Audio

The API functions for recording audio are divided into two groups; file-based functions and buffer-based functions.

The file-based record functions are designed to make recording files straightforward. The functions support WAVE files sampled at 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 file-based record functions that support VOX audio files sampled at 8 ksamples/s including; 16 bit Linear, 8 bit A-Law, 8 bit Mu-Law.

- `vpb_record_voxfile_sync()`
- `vpb_record_voxfile_async()`

The user definedbuffer-based 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()`

Tones (including DTMF) tones are generated on a channel using the `vpb_settone()` function. All of the standard DTMF tones are defined at initialization. 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.

## Tone Detection

The following functions support programmable tone detection:

- `vpb_settonedet()`
- `vpb_gettonedet()`
- `vpb_debug_tonedet()`

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 9 pre-defined tones, these are configured for standard tones and may be redefined if desired to suit the actual switch to which the VPB is connected. These are:

- `VPB_DIAL` (dial for US)
- `VPB_RINGBACK` (ringback for US)
- `VPB_BUSY` (busy for US)
- `VPB_GRUNT`(grunt detected)
- `VPB_RINGBACK_308`(ringback from Studio 308 PBX)
- `VPB_BUSY_308`(busy from studio 308 PBX)
- `VPB_FAX`(fax CNG tone/preamble)
- `VPB_BUSY_AUST`(busy/disconnect for Australia)
- `VPB_RINGBACK_AUS`(ringback for Australia)

Up to 10 tone detectors can be defined for each channel of each VPB. 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.

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

Tone detectors (either DIAL, BUSY, RINGBACK, GRUNT, or user [5..9] tone detectors) can be programmed at driver start up using the VPB_TONE env. variable. The main reason for this feature is to allow users to program the busy tone detector for different PBX models without having to modify and recompile any code.

The format of the VPB_TONE env. variable is described in `src/envtone.cpp`.

The tone detectors can also be programmed using the VPBAPI function calls. For more information on this and tone detection in general please see the next section.

To determine the parameters of a tone:

1. Sample the tone using `unittest/recwav`. For example to sample the busy tone, dial the port, start `recwav`, then hangup the phone. To sample dial tone just run `recwav` without dialling the port from another extension. Run `recwave` for about 30 seconds on pulsed tones so that you get at least 10 repetitions - this helps later with testing.

2. Use a waveform editor to view the tone and determine it's frequency and on-time (on-time is only valid for pulsed tones such as busy only, dial tones usually stay on). I use a Windows shareware editor called Goldwave. You can determine the frequency of the tone in Goldwave by clicking on the waveform window in the "Device Controls window", this will give you a spectral view of the tone. Each division is 400Hz. There may be similar tools available for Linux.

3. For a pulsed tone, determine the frequency and on-time. For continuous tone such as dial, just the frequency is required.

4. To test your tone detector, the `unittest/tonedebug` program is useful. This program can play your sampled tone, while at the same time it tries to detect the tone using the parameters you have determined. These parameters can be entered on the command line of tonedebug, so testing variations of the tone detector parameters is easy. Note that this program must run without any phone lines connected to the card - it replays the tone you sampled, while simultaneously sampling the same signal to the prototype tone detector you are testing.

5. Try setting the bandwidth to 100Hz, if that doesn't work, try 200Hz.

6. Once you are happy with the tone detector (for example, it detects all 10 repetitions of the tones you sampled), you can then set the env. variable to describe the tone, and run your main application.

### Examples

#### Dial tone

The frequency is 500Hz, and we select a bandwidth of 100Hz. We would like the tone detector to "fire" after 1 second (1000ms) of continuous dial tone. The dial tone we sampled with `recwav` is in the file `mydial.wav`.

In the `unittest` dir:

    $  ./tonedebug -c 500 100 1000 -w mydial.wav -t dial

which will produce:

    [00] Tone Detect: Dial
    [00] Play End

#### Busy tone

The frequency is 425Hz, and we select a bandwidth of 200Hz. By inspecting the wave file we determine that this pulsed tone is on for 375ms. The wave file is called `mybusy.wav`.

    $  ./tonedebug -p 425 200 375 -w mybusy.wav -t busy

which will produce something like:

    [00] Tone Detect: Grunt
    [00] Tone Detect: Busy
    [00] Tone Detect: Busy
    [00] Tone Detect: Busy
    [00] Play End

In this case, all three busy tones sampled were detected OK. The "grunt" tone is a special tone detector that just senses energy on the line.

To then set the busy tone detector using an env. variable (bash shell):

    $  export VPB_TONE=BUSY,P,425,200,375

See also `src/envtone.cpp` for more information.

## More Detail on 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:

1. The level of the tone in the band specified by the frequency (freq1) and bandwidth (bandwidth1) must be above the minimum level (minlevel1).

2. The signal energy must be greater than the rest of the energy in the received signal by the specified signal to noise ratio (snr).

3. 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:

4. The level of the first frequency component in the band specified by the frequency (freq1) and bandwidth (bandwidth1) must be above the minimum level (minlevel1).

5. The level of the second frequency component in the band specified by the frequency (freq2) and bandwidth (bandwidth2) must be above the minimum level (minlevel2).

6. The total signal energy in both bands must be greater than the rest of the energy in the received signal by the specified signal to noise ratio (snr).

7. The difference in the energies of the two frequency components must be within the allowed twist.

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 the fire time (`tfire`) in milliseconds. 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 the minimal (`tmin`) and maximum (`tmax`) time in milliseconds. 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_DETECT` structure 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

### 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 is 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 is 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.

#### toned_dial for 425Hz continuous dial tone, modulated at 25Hz

    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

            VPB_RISING,   // state 0
            0,
            0,
            0,

            VPB_TIMER,    // state 1
            2000,
            0,
            0
    };

### Austel Busy Tone 425 Hz or 400 Hz, 375ms 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.

#### Austel busy tone

    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,
    };

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

#### DTMF tone detector

    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 second, 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.

#### DTMF tone detector

    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
    };

## Automated Tone Training

## Introduction

To make programming the tone detectors easier, an automated tone training application, `tonetrain`, has been developed, and is included in the vpb-driver software.

Using this application, tone training is a three step process:

1. Record a sample of the tone.

2. Run `tonetrain` to analyse the sample and determine suitable tone detector parameters.

3. Test the tone detector parameters on your recorded tone

## Compiling

First ensure you have already compiled the driver (see `README` in the root directory of vpb-driver).

    $cd tonetrain

    $./configure

    $make

## Tutorial

### Setup

To sample tones you will need a Voicetronix card, for example an OpenLine4 or OpenSwitch12 card. This card should be installed and tested. You will also need to connect a port of the Voicetronix card to the telephone line that you wish to train tones for. Different telephone line and PBXs tend to generate different tones. A second phone line or mobile (cell) telephone is also useful.

Make sure you have compiled, installed and tested the Voicetronix driver. You will also need to have compiled `recwav` and `tonedebug`, both located in the unittest directory.

### Sample files

There are some sample files in the tonetrain sub-directory. They are:

- 400-c-tone.wav - a continous tone of 400Hz
- 600-c-tone.wav - a continous tone of 600Hz
- hs-dialtone.wav - dial tone from our PBX
- hs-ringback.wav - ring back tone from our local exchange

Using these files you can run `tonetrainer` and then plug the results back into `tonedebug` (this requires a Voicetronix board)

### Dial Tone Training Example

To record a sample, perform this command from the `unittest` directory:

    $  ./recwav dialtone.wav 1 10

This will record 10 seconds of signal on port 1 or the Voicetronix card. Before recording, `recwav` takes the line off hook, which will cause dial tone to be generated by your exchange of PBX. If your telephone line is connected to a different port, change the second argument.

It is a very good idea to check that the sample file is of good quality, and contains only the tone to be trained. You can play back the tone using `playwav`, or using a suitable command line or GUI utility.

If the sample file is of poor quality, then the automated tone training process will fail. It must contain just the tone sample to be trained, for example no human speech or other tones.

Now to determine the tone parameters, perform this command:

    $  tonetrain/tonetrain -e -w dialtone.wav

The `-e` option specifies the environment variable output format, the `-w WaveFile` specifies a wave file input format.

You should get a result like this:

    Environment variable format result:
    export VPB_TONE=5,C,421,100,2000

The arguments to the Environment variables are:

     export VPB_TONE=<Tone ID>,<Tone Type>,<Tone Frequency1>,<{Type dependant}...>

Now perform this command to set the environment variable, note that we have changed the Tone ID from 5 to DIAL:

    $ export VPB_TONE=DIAL,C,421,100,2000

This environment variable is read by the vpb driver when it starts. The driver uses this information to configure the tone detector to recognise the tone you have just trained. For more information on the tone detector parameters (and how to set them) please see the previous section.

There are several other output formats for `tonetrain`, see the command line help for more information.

After training, you can then test the tone detector using `tonedebug`. First, disconnect your telephone line from the Voicetronix card. Then:

    $ ./tonedebug -e -w dialtone.wav

    Using Environment...
    Note: -w option used for testing tone detector based
    on wave files echoed from tx->rx side of hybrid -
    make sure no telephone line connected to port 1!
    [00] Record fifo overflow
    [00] Tone Detect: Dial
    [00] Play End

As with `tonetrain`, `-e` specifies the environment variable output format, the `-w WaveFile` option specifies wave file input format for the sample used to test the tone detector.

### Ringback Tone Example

Ringback is the tone you hear in your telephone handset when the destination phone is ringing. It starts just after dialling and stops when the destination phone is answered.

To record a sample, you will to have a destination number that will not get answered and is not busy! Again we will use the `recwav` application:

    $ ./recwav ringback.wav 1 10 --dial ,,555

This example assumes that the destination number you are calling is 555 (just like the movies). The commas generate a 1 second pause in the dialling, which is useful as some PBXes and exchanges like pauses before (and during dialling). You should hear the phone at the destination number (in this case 555) ringing during the record process.

If you don't hear the destination phone ringing, then there may have been a problem dialling. Investigate and correct this before proceeding.

As with the dial tone example, it is a very good idea to listen to the recorded sample to ensure it contains the correct ringback tone sample before proceeding with the training stage.

You can then process it through `tonetrain` and `tonedebug` as before:

    $  tonetrain/tonetrain -e -w ringback.wav

    Environment variable format result:
    export VPB_TONE=5,P,453,100,1690

    $ export VPB_TONE=RINGBACK,P,453,100,1690

    $ ./tonedebug -e -w ringback.wav

    Using Environment...
    Note: -w option used for testing tone detector based
    on wave files echoed from tx->rx side of hybrid -
    make sure no telephone line connected to port 1!
    [00] Record fifo overflow
    [00] Tone Detect: Ringback
    [00] Tone Detect: Ringback
    [00] Tone Detect: Ringback
    [00] Play End

### Busy Tone Example

To record a sample, you will to have a destination number that will be busy and wont go to voice mail (you could use the number that you are calling from). Again we will use the `recwav` application:

    $ ./recwav busy.wav 1 10 --dial ,,555

You can then run it through `tonetrain` and `tonedebug` as before:

    $  tonetrain/tonetrain -e -w busytone.wav

    Environment variable format result:
    export VPB_TONE=5,P2,421,100,1000

    $ export VPB_TONE=BUSY,P2,421,100,1000

    $ ./tonedebug -e -w busytone.wav

    Using Environment...
    Note: -w option used for testing tone detector based
    on wave files echoed from tx->rx side of hybrid -
    make sure no telephone line connected to port 1!
    [00] Record fifo overflow
    [00] Tone Detect: Busy
    [00] Tone Detect: Busy
    [00] Tone Detect: Busy
    [00] Play End