GRYNX

13th of October, 2005

VoIP dect OSS Linux

by @ 15:33. Filed under Uncategorized

DTMF detection

By default, the asterisk OSS driver does not detect inband (that means: ‘in the voice stream itself’) DTMF tones. For some odd reason that I still do not understand entirely, DTMF detection is the driver’s task and not a task for the core of asterisk. Only a few changed lines were needed for this. The necessary code is partially copied from the modem drivers (chan_modem.c and the like).

Stereo support

The driver’s output format has been changed from mono to stereo to support the extra ring line. There are some checks to see whether a ring signal or another condition is played. These changes still need some cleanup, i.e. no symbolical constants, direct testing for numerical values etc…

Ringing

With the hardware setup as described, generating the proper ring signal is straight-forward. As the driver already has a table with sounds to play to indicate various conditions, only a change of the ring tone to an icky 50Hz buzz was necessary.

Off hook/hang-up detection

This was, by far, the hardest part in the driver. As there is no separate signal coming into the PC that tells the driver whether the phone is off hook, the audio input signal itself needs to be checked for sure signs of a picked-up phone.
My idea here is as follows: If the phone is hung up, no noise from the microphone and its amplifier enters the sound card. The sound card more or less only sees its own noise. In this state, the noise power level is very small.
If the phone is picked up, the microphone and its amplifier is connected (either electronically or electromechanically through a relays) to the input line of the sound card. A lot more noise and background sounds will enter the sound card. The difference to the hung-up state is (at least in my case) clearly distinguishable from the picked-up state. This enables off-hook detection without any additional components.

It should be noted here, though, that this may fail if one presses the ‘mute’ button on the phone as this may essentially do the same thing to the noise levels as a hang up. I consider this only a minor flaw as I normally don’t use that functionality.

The figure below illustrates this concept, you can see there two drawings of artificial ‘amplitude histograms’ made from the sound card’s sampled signal. By amplitude histogram, I mean a histogram of the sound card’s sample values for a given period of time. I.e. what results if you project those nice time-axis displays of sound data in your favourite sound tool to the screen’s Y-axis.

The red one should depict the phone in hung-up state with little noise and therefore a sharp peak around zero (or your sound card’s ADC offset, this is often not identical to zero!). The green one depicts the noise in picked-up state, broader due to the additional noise. By measuring the width (~ standard deviation of the peak), it is possible to determine the state of the phone.
The noise going into the signal really gives a nice Gaussian, btw (As one would expect!).

To make this process more reliable, a few additional things are implemented in the modifications. The first and important one is that the off-hook detection must be a lot more insensitive during phone rings. Else, when the phone rings, a lot of cross talk would trigger a pick-up indication, which is obviously not very practical for the phone user… except you’re sitting next to the phone for all the time.
The other one is that there is an detection hysteresis, meaning that a certain value is needed to trigger ‘picked-up’ state and a certain value explicitly below that is used to trigger the driver into ‘hung-up’ state.

And, last, there is code that checks if a number of times the threshold must be crossed before the trigger gets really activated. This acts as some form of a low pass filter to prevent miss-detections due to spikes and aliasing effects (the sound input is analyzed block-wise).

This will sound as a bit awkward method and maybe even as an unreliable solution, but so far it works for me! I’m not sure about any long term drift of the sound card but even if such things occur, it is rather easy to re-adjust the values in the configuration files (see below). The only drift I have noted so far is slightly increasing noise as the PC warms up. This is completely normal from the physics standpoint, but it is also nice to see that in reality :)

Software setup

Configuration/module load

As stated above, the compiled chan_oss.so module can simply be copied into the /usr/lib/asterisk/modules path. This is also possible with an already installed asterisk (in the current state, you will replace your old OSS driver, though!), simply compile asterisk in your home directory (without “make install”) and copy the file from channels/chan_oss.so then.

To load the module, put

load => chan_oss.so


into your modules.conf, as usual. Currently, the driver distinctly differs from the old chan_oss.so that it does not support auto-answer shell commands. If they are not there, you have the modified driver.

Mixer setup

Without the asterisk driver being enabled (and thus blocking the sound card), you can fetch and play the 50Hz square wave starting at low volume. By gradually increasing the volume, you should be able to find the spot where the phone reliably starts to ring. This is the output volume setting which is right for asterisk. Save this setting so it can be restored before the start of asterisk each time.

A neat tool do this is aumix. With the command

$ aumix -S


a file ~/.aumixrc is created (you can use the ‘-f’ option to specify a different file name, see also ‘aumix –help’ as usual…) which contains all mixer settings. These settings have to be restored later on with

$ aumix -L <filename>

Write this into your /etc/init.d/asterisk start-up script, for example.

Setting the thresholds and timeouts and volume prescaler

All the following settings have to be made in the file
/etc/asterisk/oss.conf. The specified configuration variables here all need integer arguments and have to be set in the
[general] section of this configuration file.

After checking that the driver at least loads, the next thing to do is to enable asterisk to output the current ’standard deviation’ value of the amplitude histogram detection function to the console. This is done by setting hd_disp_interval to a value different to the default of “-1″ (no output), for example hd_disp_interval=30.

By the way, it is advisable to call asterisk with
the command line arguments

$ asterisk -f -c -d

to get a shell where things can be tried out. After enabling the stddev display, some numbers should appear onscreen which should change with a) hanging/picking up the phone and b) speaking into the phone, like described above.

Note the differences between hung-up and off-hook. Write down the values. Now, set hd_hl_threshold, the pick-up threshold level, to a value just below the observed values when the phone is off-hook but no one is talking. Similarly, set hd_ll_threshold to a value just above the value that appears when the phone is hung up. The variable

hd_hl_ring_threshold is like hd_hl_threshold but used when the phone is ringing, i.e. there is cross talk on the input. Set this a bit higher than hd_hl_threshold.
After restarting asterisk, there should be messages that the phone has been picked up or hung up. If this does not work reliably, try to increase the values for hd_hl_seqmin and/or hd_ll_seqmin respectively. The detection will be a bit delayed to the actual action; this will increase with the values for *_seqmin. But normally, they should be still small enough to not cause any headaches.

If this works ok, try to use asterisk’s example dial plan (that with the demo application and long introduction speech). DTMF detection should work. If it does not, check the value of “-DRADIO_RELAX” in asterisk’s Makefile.
Try to test the complete signal path by dialling the echo application (600). There should be at most slight echoes. If there is too much echoing which you can’t reduce by your sound card’s mixer settings, use the configuration variable vol_divide to scale down the input signal received by the driver before it is given to the other parts of asterisk. The default variable for this is 3, which works well in my case. Addition, 10/12/05: Note that I built a potentiometer into the phone to weaken signals, but this is more or less a relict of investigation. In all but the most extreme cases, this should be unnecessary with vol_divide or, perhaps further modification of the driver for throttled output.

3 Responses to “VoIP dect OSS Linux”

  1. Serj Says:

    This is a great guide/text. Great for learning, everything covered and explained, thank you very much.

  2. phantomload Says:

    just a question, as I am not as framiliar with asterisk as you obviously are (and the documentation frankly is not upto open-source standards). But It seems it would be easier to use a voice modem with the addition of a ringer circuit (and less likely to have echo issues). As I understand this is what the x100p basically is. From what I understand an FXS is just an FXO that can make a phone ring? seems a simple addition, and there are lots of circuits available online. I do not know if you can force asterisk to route incoming voip calls to a modified FXO. Is it feasable to have astrisk actiate a parrallel port pin when the phone is supposed to ring. If this is far more difficult than what you have done. I just assumed the modem would be better matched to the phone lines than anything I build.

  3. kashif Says:

    many thx for all the efforts. I want to feed pc spkr output to pstn-analog mic input and similarly couple pc mic input with pstn spkr output. the purpose is to forward voip conversation to another pstn subscriber using pstn network.
    can anybody provide similarly simple plan.

Leave a Reply

Host your project

Write for Grynx:

Do you have what it takes? If you're the right person then email us.

Archives:

Support Grynx:

Help us continue our work with a donation

Website promotion SEO Managed Advertising

5 Most popular articles:

Google

Categories:

Do it yourself - DIY
Our projects collection

41 queries. 0.511 seconds

Home