How To: Tune rxgain / txgain for Zaptel / DAHDI FXO interfaces on Asterisk PBX
Synopsis
This will be a quick and dirty tutorial on how to properly tune your Zaptel / DAHDI FXO interfaces on Asterisk via the Zapata channel interface chan_zap.
The purpose of tuning your FXO interfaces is first of all, to have proper audio levels on your FXO PSTN interfaces. However, my initial motivation for tuning my interfaces was to reduce the awful hybrid echo that was being caused on my FXO interfaces. The short of what hybrid echo is, is that there is a device in telco switches called a hybrid. Essentially what this device does is convert your single pair copper that connects to your house/office into a 2-pair connection, 1 pair that carries the receive audio, and 1 that carries the transmit. Telco’s do this because they need to amplify the signals independently for carrying calls over long distances. Unfortunately due to the nature of this device, it causes electrical leakage which causes the echo.
When using only regular analog phones, the echo created by the hybrid is still present, but there is such a short delay, it sounds like regular sidetone. When we enter the VoIP world, the delay increases due to processing and IP network stuff. This delay is not large generally, but its large enough that it becomes very obvious that you are hearing an echo of yourself. To help solve this we have echo cancelers, but echo cancelers can only do so much, the better the signal we can get to begin with, the easier the job the echo canceler has. To get a clean signal we need to adjust our rxgain and txgain values in zapata.conf for Asterisk.
What you will need
- A Type 102 Milliwatt Test number - preferably one running in your local exchange by your telco, alternatively you can google around for some numbers - thats what I had to do.
- At least 2 FXO ports and lines (only need 1 to tune rxgain only)
- Zaptel / DAHDI compiled with ztmonitor
- Asterisk compiled with app_millliwatt (its there by default)
Do This First
The first thing you should do is turn off all echo cancellation in zapata.conf, the echo canceler may interfere with the following procedure. But don’t worry, once you have tuned rxgain and txgain you can, and should, turn all your echo cancel options back on. zapata.conf:
- echocancel=no
- echotraining=no
- echocancelwhenbridged=no
Tuning rxgain
To tune rxgain what we are going to do is dial on every FXO line you have to the telco milliwatt test number and adjust the value of rxgain until we get the values we want. What I find easiest is to setup your Asterisk dialplan to use something like Zaptel / DAHDI group 9, then we can just change which line is in group 9 one by one until all lines are tuned.
First setup your dialplan to make all outgoing calls using ZAP/g9 (that falls out of the scope of this How To).
Next setup group 9 in zapata.conf and place your first ZAP FXO line into that group:
group=9
signalling = fxs_ks
context=from-trunk
rxgain = 0.0
txgain = 0.0
channel => 1
While you are in zapata.conf, make sure all your rxgain/txgain values are set to 0.0 as a starting place.
Next you want to dial the Milliwatt test number from one of your phones. You should hear either a tone that sounds of a constant frequency and volume, or you may hear the frequency then a pause, then it restarts. Telco’s all run these a little differently.
Now you want to fire up ztmonitor on channel 1
ztmonitor 1 -vv
You want to watch the value beside “Rx:” until you get the number to 14844. When you first dial into the test number, if you find the number is below 14844, then you will want to increase rxgain, and of course if you are above 14844, you’ll want to decrease rxgain (it can go negative).
In a seperate console you’ll need to edit zapata.conf to increase/decrease the rxgain value, you can then save your zapata.conf and run
asterisk -rx “reload”
to make Asterisk load the new values. You should see the values being reported in your terminal running ztmonitor go up or down. Simply keep repeating this until you have the Rx: as close to 14844 as you can get it.
Once you have the rxgain value set, you’ll want to tune the next line, change your zapata.conf to put channel 1 back into its regular group, and be sure to move the rxgain=,txgain= lines along with the channel - the rxgain/txgain values should be listed somewhere before the channel => line. You can set rxgain,txgain values multiple times in zapata.conf, the values listed before the channel => line is the values that will effect that channel only.
After you have moved the channel and values back to its proper group, simply repeat the above for each FXO port you have, changing the channel number to the appropriate numbers for your setup.
Tuning txgain
Tuning txgain is essentially the exact opposite of rxgain. However the challege we face here is that before we were using a telco-controlled test number to emit the tone and we listened for it. This time however we need to be the ones to emit the tone, and we also need to be able to listen to the tone so we know how loud we are emitting our signal. This is why we need 2 lines to tune txgain, essentially what we are going to do is dial out from the Asterisk server to the Telco switch and then loop it back to ourselves on our second port.
To do this, first we need to create a context in extensions.conf to setup the Milliwatt test:
[to-milliwatt]
exten => s,1,Answer()
exten => s,n,Milliwatt()
exten => s,n,Hangup()
Update (May 28, 2008): It was recently discussed on the asterisk-users mailing list that the Milliwatt() application does not correctly produce a 1004KHz tone, and instead produces 1000KHz, there is reasoning behind this. Anyhow, the correct method to generate a 1004KHz tone with Asterisk is:
[to-milliwatt]
exten => s,1,Answer
exten => s,n,PlayTones(1004/1000)
exten => s,n,Wait(300)
What we do next, is change the context that the Zap channel is in that we want to tune, say we want to tune channel 1, we would edit zapata.conf to look something like this:
group=0
signalling = fxs_ks
context=to-milliwatt
channel =>1
Feel free to put all of your FXO channels into this context ahead of time, the context is unimportant for the purposes of dialing out, however it is handy to have a single line in a separate group to dial out from, simply so that we know what channel is going to be on the receiving end of the milliwatt test ahead of time. This could also be done by specifing a specific channel in your dialplan.
Next what you need to do is dial out from your PBX into one of your own numbers, preferably doing them in order, so dial the number for channel 1, then 2, then 3, etc.
Pretending we are using channel 8 to dial OUT from, and we are going to dial IN to channel 1, you will once again need to load ztmonitor like we did for rxgain. However, this time we want to always be monitoring channel 8, since we need to be watching the levels of audio we are recieving from the channel we are sending from - if you monitor the channel you are transmitting from, you will always get a value of 14844, this is because Zaptel / DAHDI assumes its emitting the correct volumes as it has no way to tell if it is or not. So:
ztmonitor 8 -vv
Just like for rxgain, in another terminal you’ll want to edit zapata.conf and run
asterisk -rx “reload”
Again you are watching the Rx: value to get it as close to 14844 as you can. Since we have already tuned rxgain and know our receiving levels are perfect according to the telco-owned switch, which in theory is setup properly to ensure we tune our receiving properly. This time we are going to edit the txgain= line for the channel that we dialed IN to, so go ahead and start tuning your txgain= values to get them where they need to be.
Just like with rxgain, you’ll want to repeat this for every channel you have, dialing into each one separately. Eventually once you reach the end, you’ll need to change your config a little bit to tune the txgain value of the line you were dialing out from, that should be pretty straightforward by this point however.
Once you have completed this, you should have much better balanced audio, and hopefully considerably less echo than you originally had. You may also find that you can now set your echo canceler settings to be much less aggressive.
Finally, to give credit where credit is due, I learned this procedure by doing alot of google searching and finding a post from 2004 to the asterisk-users mailing list titled Adjusting txgain/rxgain by Kris Boutilier.
If you have any questions, feel free to leave a comment and I’ll do my best to get back to you.


June 4th, 2008 at 1:42 pm
I had to set my rxgain to 10.9! I have no scientific basis for what alarms me about that but it seems really high. I did have to use a milliwatt number that is not in my own area code, never mind exchange or the ideal case, Central Office. I am terribly skeptical of the phone company here, Bell Canada giving out milliwatt numbers just because I want one.
Thots?
June 4th, 2008 at 10:46 pm
Hey there Brian,
I hear ya on feeling that 10.9 feels high. When I did my main site I was using values in the +6 - 8 range on rxgain and -1 - 2 on txgain. I however have done a site where I was up into +11.5 area. I had the same feeling as you, it just seemed ridiculously high… it did seem to do the trick though, the customer has been happy ever since we did that.
Both sites I mention though were on MTS Allstream, also in Canada. My site I know for sure was served off of an Allstream switch, the other one however might of been being served off an Bell Canada switch through Allstream’s “resale” platform as they call it.
I have read pages on voip-info.org that do suggest not going beyond +/- 10, however there main caution seems to be around causing potential problems with DTMF detection, Fax negotiation, etc.
My advice is just try it out with the values you’ve used and see how it does. Fortunately its easy and simple to revert the values if you need to.
As for the Milliwatt numbers… I can’t say I’ve had a ton of luck getting them from the telco’s either… I asked my Allstream sales rep, who sent me to his “Sales Engineer”, then told me to call Allstream technical support… I personally didn’t feel like trying to explain what I was looking for Tier-1 support, so I opted for the google method. The number I used was long-distance, but not too long… I was calling Toronto from the Niagara Region, so not too bad… certainly far from ideal though. These are the numbers I used - Milliwatt Test Number List. When I tuned my first interface, I tried calling all 3 numbers, each of them were giving me nearly identical results, so I figured I’d be ok.
June 4th, 2008 at 11:14 pm
I tried the three Bell Canada Milliwatt numbers in your URL there. Unfortunately, all out of service now. Maybe tomorrow (as opposed to nearly midnight now) I will try calling a few *-1185 in my area and see if I can find one.
September 27th, 2008 at 12:54 pm
I’m not understanding the tx part. So let’s say I have two lines, 1 & 2. Do I send the tone out on the line I want to calibrate? Say I want to calibrate line 1… do I send the tone out on line 1 to line 2 and use ztmonitor to monitor line 1… looking at the rx number but adjusting the tx because it is what’s affecting the rx?
September 27th, 2008 at 1:16 pm
OK; think I’ve figured it out.
If I want to calibrate line 1… I have the tone generated on line 1 and use line 2 to call into line 1. I use ztmonitor to watch the rx level on line 2 and adjust the tx gain on line 1 until the rx level on line 2 is at or around 14844.
Got it - right!
October 23rd, 2008 at 10:33 am
Hi Kline,
Sorry for the late response - but you got it dead on
June 18th, 2009 at 5:32 pm
Thanks for the credit, I’m glad the information was of use to you.
If anyone is curious why rx/tx gain and echo management are so interconnected this post might also be of interest: http://www.mail-archive.com/asterisk-users@lists.digium.com/msg83286.html