Regarding ASL, HamVoIP and default codec priority

Greetings:

There are still an awful lot of HamVoIP nodes out there, and, for whatever reason, HamVoIP’s default template prefers g726aal2 over ulaw. Some HamVoIP nodes, such as 2462, 60933 and others, will flat out not negotiate ulaw at all, for whatever reason.
so, with ASL’s defaults, you might find yourself using the far less fashionable GSM codec when connecting to a HamVoIP node.
If I wanted my node to sound like Echolink, I’d use Echolink. No, thanks.
To avoid this, I added g726aal2 in priority just under ulaw. The G726 line is commented out by default in ASL’s iax.conf.

Here’s what my priority looks like.

[general]
...
disallow=all
allow=slin
allow=ulaw
allow = g726aal2
allow=adpcm

Note:
For radio use, there is no practical need to use slin as a codec. You’ll never notice the difference as far as dynamic range when any RF component is involved. However, all my hub nodes connect internally using slin, and I like to do the same wherever it is available.

73
N2DYI

I would say talk to the folks at hamvoip.

ASL follows the rules of asterisk as far as I know with codec priority.
Not that you can’t adjust asterisk priorities for a custom fit…
I only use ulaw and gsm as a backup.
If you can’t muster one of those, your not connecting to me.

I have, in fact, brought this silly default configuration up with them several times over the past five years, which went nowhere. It seems that HamVoIP is a dead project these days, so there is probably no chance that this will get fixed until people replace their nodes, so I’m just putting the information out there for folks to do what they will, ignore, or whatever.
FWIW, I don’t allow GSM connections on any of my nodes. I’ve never seen a need for it to exist.

1 Like

Once a connection is established. How can I tell (Using supermon) which codec is being used… I have on node that a repeater I control connects to but…alas. I can not. Wondering if it’s a codec I don’t have.

I don’t know about Supermon, or Allmon for that matter. Don’t use either of them.
From asterisk cli, you can do

iax2 show channels

and as long as at least one transmission has happened in one direction, you will see the format used.
Here’s an example from one of my not quite up-to-date nodes.

root@asl:/home/patrick# asterisk -rvvv
Asterisk 20.10.0+asl3-3.1.0-1.deb12, Copyright (C) 1999 - 2022, Sangoma Technologies Corporation and others.
Created by Mark Spencer <markster@digium.com>
Asterisk comes with ABSOLUTELY NO WARRANTY; type 'core show warranty' for details.
This is free software, with components licensed under the GNU General Public
License version 2 and other licenses; you are welcome to redistribute it under
certain conditions. Type 'core show license' for details.
=========================================================================
Connected to Asterisk 20.10.0+asl3-3.1.0-1.deb12 currently running on asl (pid = 472380)
asl*CLI> iax2 show channels
Channel               Peer                                      Username    ID (Lo/Rem)  Seq (Tx/Rx)  Lag      Jitter  J
IAX2/176.58.122.120:  176.58.122.120                            radio       15221/05775  00006/00082  00041ms  0000ms  0
040ms  ulaw    Tx:NEW      Tx:ACK
1 active IAX channel
asl*CLI>

I just had to comment with a valid reason for narrow bandwidth protocos. I have set my nodes running that run over LTE modems, to allow only the lower bandwidth protocols. That includes remote mountaintop sites and mobile nodes. So there are valid reasons to do this. Besides, on a repeater which is running FM at 5KHz. deviation, can you really tell the difference? If I were on a VoIP phone with a really nice speaker, sure. However 99% of the time it’s over a narrowband radio.

G726AAL2, which is half the bandwidth of ulaw, still sounds pretty reasonable. I’d guess most people couldn’t tell the difference, unless there is packet loss. Then it’s pretty obvious, at least to me.
GSM, though, is quite metallic and grainy in comparison. It’s also small enough to be used on a 14.4 kbps link.
Like I said, regarding GSM, if I wanted my nodes to sound like echolin, I’d use echolink.
Thus why GSM doesn’t exist in my life, even for bandwidth-saving applications. The compromised sound isn’t worth it for me.
G726aal2 does a good job here. Low bitrate Opus would do an even better job. You could get GSM-type bandwidth usage, but better sound quality.
For mountaintop links on extremely limited bandwidth, I would go no lower than G726AAL2 given the available supported codec list now, and let a remote hub somewhere do the bulk of the work, so you are only dealing with one stream in and out, regardless of how many connections are made to your system.

I did not suggest you use gsm.
I stated that I use it for a backup for those that are under low bandwidth conditions. They will not normally enable ulaw because of that. Times have changed and mobile bandwidth is much better anymore. But I am still setup referencing that in that way.

But do remember that for a inbound connection to be successful, there has to be a matching codec handshake. Do not assume everyone has all of them enabled.
Part of the point I was making that I think you missed.
It is all a matter of personal choice, but has ramifications.

But if you have an issue with how hamviop works, you are better served to take the issue to them, and perhaps get the answers you are seeking.

Ok, so … what is the best sounding (highest fidelity) codec if bandwidth isn’t an issue?

G722 or G729 is wideband audio.

IF we’re talking about codecs that are fully supported by app_rpt and don’t have additional overhead for no good reason, that would be slin (8kHz 16-bit PCM), though when radios are involved, you’ll practically never hear the difference between slin and ulaw, which is half the bandwidth of slin. You just don’t have the dynamic range over FM such that it matters too much.
So, ulaw, which is the default for ASL, not HamVoIP, is a good default to have.
G722 is twice the sampling rate. Asterisk supports it, but app_rpt is limited to 8 kHz due to limitations with DAHDI, as I understand it, so there isn’t much point beyond perhaps compatibility with some SIP devices to use it. Ditto for slin16, which is raw linear PCM at 16 kHz instead of 8 kHz.
Down at the other end of the scale, you have ilbc and GSM, both of which are obviously compromised.
To be fair though, most probably wouldn’t notice the difference between ulaw and g726, which is again half the bandwidth of ulaw. I definitely notice when there is packet loss, though. Something about the frame boundaries of that codec makes a weird sound that, once you’ve heard it, you can’t unhear it.

The largest reason to use ulaw is almost everyone has it set and you do have to handshake and negotiate a codec. Asterisk documentation explains this.
You will see the need to allow for more than one in a negotiation. But you can prioritize.

But that should not deter you if making specialized private links based on need.
I can’t speak to what hamvoip does or does not do and may be different.
I see no methods in ASL that is contrary to Asterisk codec hankshaking.

I installed ASL3 and it works very well. I suggest everyone upgrade to ASL3 and remove hamvoip version. With no source code, God knows what backdoor vulnerabilities it can be introducing.

Nothing sucks more than old unsafe and unknown code.

3 Likes

I noticed that the codec priority in iax.conf does not appear to be working as I expected.

I was attempting to make g726aal2 the preferred codec for incoming and outgoing connections, as follows:

; NOTE: bindport must be specified BEFORE
; bindaddr or may be specified on a specific
; bindaddr if followed by colon and port
; (e.g. bindaddr=192.168.0.1:4569)

; bindaddr = 192.168.0.1 ; more than once to bind to multiple
; addresses, but the first will be the
; default

disallow = all ; The permitted codecs for outgoing connections
;Audio Quality Bandwidth
;allow = ulaw ; best 87 kbps
;allow = adpcm ; good 55 kbps
;allow = gsm ; mediocre 36 kbps
;allow = slin16
;allow = slin
allow = g726aal2
allow = ulaw
allow = adpcm
allow = g722
allow = g726aal2
allow = gsm
;allow = ilbc

jitterbuffer = yes
forcejitterbuffer = yes
dropcount = 2
maxjitterbuffer = 4000
maxjitterinterps = 10
resyncthreshold = 1000
maxexcessbuffer = 80
minexcessbuffer = 10
jittershrinkrate = 1
tos = 0x1E
autokill = yes
delayreject = yes
; iaxthreadcount = 30
; iaxmaxthreadcount = 150

; Incoming radio connections

[radio]
type = user
disallow = all
;allow = slin16
;allow = slin
allow = g726aal2
allow = ulaw
allow = adpcm
allow = g722
allow = gsm
;allow = ilbc
codecpriority = host
context = radio-secure
transfer = no

The host (receiving) node is set to allow all codecs, with g726aal2 at the top it's outgoing allowed codec list. Same for the calling node. However, even though the g726aal2 is placed above ulaw in both the incoming and outgoing nodes, the connection always negotiates to ulaw. Only if I remark out the ulaw in the incoming or outgoing nodes' codec list, will it negotiate to g726aal2.

I would prefer to have my own nodes connect to my hub using g726aal2, but also need to leave ulaw enabled, as there are a number of Clearnode users that can no longer connect if I disable ulaw alltogether.

Is ulaw somehow coded in ASL or app-rpt to prioritize ulaw regardless of the iax.conf settings, so that it always uses the best quality codec, regardless of the order in the iax.conf stanzas?

I can say that when I enabled slin at top of the codec lists, it was being prioritized and negotiated to for incoming and outgoing connections. It is just puzzling why g726aal2 will not prioritize if at the top of the list.

Any ideas?

Eric
K2CB

We have 30+ nodes at remote mountain sites and do this to the T ! G726 is the only codec to call out to a cloud hub. I use LTE modems on a 2GB account for $5 a month with external MIMO antenna and can choose VZW or AT&T…… Use about 800 mb in a 30 day cycle. So much room to expand. thats even with RSSH and teamviewer running for back door access.

Have you checked that the codec_g726.so module is loaded on both the outgoing and incoming nodes?

CLI> module show like codec

Yes,

G726 is enabled:
node616535CLI> module show like codec
Module Description Use Count Status Support Level
codec_a_mu.so A-law and Mulaw direct Coder/Decoder 0 Running core
codec_adpcm.so Adaptive Differential PCM Coder/Decoder 0 Running core
codec_alaw.so A-law Coder/Decoder 0 Running core
codec_dahdi.so Generic DAHDI Transcoder Codec Translato 0 Running core
codec_g722.so ITU G.722-64kbps G722 Transcoder 0 Running core
codec_g726.so ITU G.726-32kbps G726 Transcoder 0 Running core
codec_gsm.so GSM Coder/Decoder 0 Running core
codec_resample.so SLIN Resampling Codec 0 Running core
codec_ulaw.so mu-Law Coder/Decoder 16 Running core
9 modules loaded
node616535
CLI>

If I am logged into the destination node (668170) and watch in CLI, it appears to be negotiating to ulaw. Interestingly, if you look at the calling (616535) node's requested prefs, you will see ulaw at the beginning of the negotiation line, but in the actual iax.cong file of the calling node (616535), you will see that G726 is placed above ulaw.

node668170CLI>
-- Hungup 'IAX2/98.221.146.29:4574-2120'
-- Hungup 'DAHDI/pseudo-2076025456'
-- Accepting UNAUTHENTICATED call from 98.221.146.29:4574:
-- > requested format = ulaw,
-- > requested prefs = (ulaw|g726aal2|adpcm|g722|gsm|ilbc),
-- > actual format = ulaw,
-- > host prefs = (ulaw|adpcm|g722|g726aal2|gsm|ilbc),
-- > priority = caller
-- Executing [668170@radio-secure:1] Set("IAX2/98.221.146.29:4574-12360", "NODENUM=616535") in new stack
-- Executing [668170@radio-secure:2] NoOp("IAX2/98.221.146.29:4574-12360", "Connect from node: 616535") in new stack
-- Executing [668170@radio-secure:3] NoOp("IAX2/98.221.146.29:4574-12360", "Connect to: 668170") in new stack
-- Executing [668170@radio-secure:4] NoOp("IAX2/98.221.146.29:4574-12360", "Channel type: IAX2") in new stack
-- Executing [668170@radio-secure:5] GotoIf("IAX2/98.221.146.29:4574-12360", "1?:allowlist") in new stack
-- Executing [668170@radio-secure:6] NoOp("IAX2/98.221.146.29:4574-12360", "Channel Peer IP: 98.221.146.29") in new stack
-- Executing [668170@radio-secure:7] GotoIf("IAX2/98.221.146.29:4574-12360", "0?connect") in new stack
-- Executing [668170@radio-secure:8] GotoIf("IAX2/98.221.146.29:4574-12360", "1?denylist") in new stack
-- Goto (radio-secure,668170,12)
-- Executing [668170@radio-secure:12] GotoIf("IAX2/98.221.146.29:4574-12360", "0?:connect") in new stack
-- Goto (radio-secure,668170,15)
-- Executing [668170@radio-secure:15] Rpt("IAX2/98.221.146.29:4574-12360", "668170") in new stack
== Spawn extension (radio-secure, 668170, 15) exited non-zero on 'Surrogate/IAX2/98.221.146.29:4574-12360'
node668170
CLI>

IAX.CONF (616535):
; bindaddr = 192.168.0.1 ; more than once to bind to multiple
; addresses, but the first will be the
; default

disallow = all ; The permitted codecs for outgoing connections
;Audio Quality Bandwidth
;allow = ulaw ; best 87 kbps
;allow = adpcm ; good 55 kbps
;allow = gsm ; mediocre 36 kbps
;allow = slin16
;allow = slin
allow = g726aal2
allow = ulaw
allow = adpcm
allow = g722
allow = gsm
allow = ilbc

jitterbuffer = yes
forcejitterbuffer = yes
dropcount = 2
maxjitterbuffer = 4000
maxjitterinterps = 10
resyncthreshold = 1000
maxexcessbuffer = 80
minexcessbuffer = 10
jittershrinkrate = 1
tos = 0x1E
autokill = yes
delayreject = yes
; iaxthreadcount = 30
; iaxmaxthreadcount = 150

; Incoming radio connections

[radio]
type = user
disallow = all
;allow = slin16
;allow = slin
allow = g726aal2
allow = ulaw
allow = adpcm
allow = g722
allow = gsm
allow = ilbc
codecpriority = caller
context = radio-secure
transfer = no

I then went so far as to change the incoming priority for node 668170 to put G726 at the top of the list:

; Incoming radio connections

[radio]
type = user
disallow = all
;allow = slin16
;allow = slin
allow = g726aal2
allow = ulaw
allow = adpcm
allow = g722
allow = gsm
allow = ilbc
codecpriority = caller
context = radio-secure
transfer = no

It still negotiates to ulaw:

node668170CLI>
-- Hungup 'IAX2/98.221.146.29:4574-11758'
-- Hungup 'DAHDI/pseudo-677372540'
-- Accepting UNAUTHENTICATED call from 98.221.146.29:4574:
-- > requested format = ulaw,
-- > requested prefs = (ulaw|g726aal2|adpcm|g722|gsm|ilbc),
-- > actual format = ulaw,
-- > host prefs = (g726aal2|ulaw|adpcm|g722|gsm|ilbc),
-- > priority = caller
-- Executing [668170@radio-secure:1] Set("IAX2/98.221.146.29:4574-2031", "NODENUM=616535") in new stack
-- Executing [668170@radio-secure:2] NoOp("IAX2/98.221.146.29:4574-2031", "Connect from node: 616535") in new stack
-- Executing [668170@radio-secure:3] NoOp("IAX2/98.221.146.29:4574-2031", "Connect to: 668170") in new stack
-- Executing [668170@radio-secure:4] NoOp("IAX2/98.221.146.29:4574-2031", "Channel type: IAX2") in new stack
-- Executing [668170@radio-secure:5] GotoIf("IAX2/98.221.146.29:4574-2031", "1?:allowlist") in new stack
-- Executing [668170@radio-secure:6] NoOp("IAX2/98.221.146.29:4574-2031", "Channel Peer IP: 98.221.146.29") in new stack
-- Executing [668170@radio-secure:7] GotoIf("IAX2/98.221.146.29:4574-2031", "0?connect") in new stack
-- Executing [668170@radio-secure:8] GotoIf("IAX2/98.221.146.29:4574-2031", "1?denylist") in new stack
-- Goto (radio-secure,668170,12)
-- Executing [668170@radio-secure:12] GotoIf("IAX2/98.221.146.29:4574-2031", "0?:connect") in new stack
-- Goto (radio-secure,668170,15)
-- Executing [668170@radio-secure:15] Rpt("IAX2/98.221.146.29:4574-2031", "668170") in new stack
== Spawn extension (radio-secure, 668170, 15) exited non-zero on 'Surrogate/IAX2/98.221.146.29:4574-2031'
node668170
CLI>

If I re-enable SLIN, which I have at the top of the list of the calling node, but second in the list in the host node, it negotiates to SLIN just fine:

ode668170CLI>
-- Accepting UNAUTHENTICATED call from 98.221.146.29:4574:
-- > requested format = slin,
-- > requested prefs = (slin|g726aal2|ulaw|adpcm|g722|gsm|ilbc),
-- > actual format = slin,
-- > host prefs = (g726aal2|slin|ulaw|adpcm|g722|gsm|ilbc),
-- > priority = caller
-- Executing [668170@radio-secure:1] Set("IAX2/98.221.146.29:4574-11019", "NODENUM=616535") in new stack
-- Executing [668170@radio-secure:2] NoOp("IAX2/98.221.146.29:4574-11019", "Connect from node: 616535") in new stack
-- Executing [668170@radio-secure:3] NoOp("IAX2/98.221.146.29:4574-11019", "Connect to: 668170") in new stack
-- Executing [668170@radio-secure:4] NoOp("IAX2/98.221.146.29:4574-11019", "Channel type: IAX2") in new stack
-- Executing [668170@radio-secure:5] GotoIf("IAX2/98.221.146.29:4574-11019", "1?:allowlist") in new stack
-- Executing [668170@radio-secure:6] NoOp("IAX2/98.221.146.29:4574-11019", "Channel Peer IP: 98.221.146.29") in new stack
-- Executing [668170@radio-secure:7] GotoIf("IAX2/98.221.146.29:4574-11019", "0?connect") in new stack
-- Executing [668170@radio-secure:8] GotoIf("IAX2/98.221.146.29:4574-11019", "1?denylist") in new stack
-- Goto (radio-secure,668170,12)
-- Executing [668170@radio-secure:12] GotoIf("IAX2/98.221.146.29:4574-11019", "0?:connect") in new stack
-- Goto (radio-secure,668170,15)
-- Executing [668170@radio-secure:15] Rpt("IAX2/98.221.146.29:4574-11019", "668170") in new stack
== Spawn extension (radio-secure, 668170, 15) exited non-zero on 'Surrogate/IAX2/98.221.146.29:4574-11019'
node668170
CLI>

One more example:

if the outgoing node stanza is:
;Audio Quality Bandwidth
;allow = ulaw ; best 87 kbps
;allow = adpcm ; good 55 kbps
;allow = gsm ; mediocre 36 kbps
;allow = slin16
allow = g726aal2
;allow = slin
allow = ulaw
allow = adpcm
allow = g722
allow = gsm
allow = ilbc

the requested shown is:
Accepting UNAUTHENTICATED call from 98.221.146.29:4574:
-- > requested format = ulaw,
-- > requested prefs = (ulaw|g726aal2|adpcm|g722|gsm|ilbc),
-- > actual format = ulaw,
-- > host prefs = (g726aal2|slin|ulaw|adpcm|g722|gsm|ilbc),
-- > priority = caller

if the outgoing stanza is:
disallow = all ; The permitted codecs for outgoing connections
;Audio Quality Bandwidth
;allow = ulaw ; best 87 kbps
;allow = adpcm ; good 55 kbps
;allow = gsm ; mediocre 36 kbps
;allow = slin16
allow = g726aal2
allow = slin
allow = ulaw
allow = adpcm
allow = g722
allow = gsm
allow = ilbc

the requested shown is:
Hungup 'DAHDI/pseudo-1383343994'
-- Accepting UNAUTHENTICATED call from 98.221.146.29:4574:
-- > requested format = slin,
-- > requested prefs = (slin|g726aal2|ulaw|adpcm|g722|gsm|ilbc),
-- > actual format = slin,
-- > host prefs = (g726aal2|slin|ulaw|adpcm|g722|gsm|ilbc),
-- > priority = caller

It appears that the order specified in iax.conf is not being fully followed by app-rpt (I am guessing, not sure exactly) during the handshaking/negotiation process.

Eric
K2CB

<the following comments are not directed any any one individual>

One of the problems with "Community" is that folks don't like to (or didn't know that they can) upload/attach their configuration files. They also don't remember to (or didn't know that you can/should) block any copy/pasted text between triple-back-quotes (```) that blocks most of the markdown formatting :

```
copy/paste your text here (between the ``` lines)
```

... and now back to this topic ...

Because you didn't attach the files I have to ask if one of the first lines of your ASL3 iax.conf file really starts off with :

; bindaddr = 192.168.0.1 ; more than once to bind to multiple
...

If so, one of the important lines that's missing from the top of the file is :

[general]

Why is this an issue? From the log we see :

-- Executing [668170@radio-secure:1] Set("IAX2/98.221.146.29:4574-12360", "NODENUM=616535") in new stack

The code is likely looking for the [radio-secure] context in the iax.conf file (not present), then looking for the [general] context (not present), and finally using hard-coded defaults.

Can you check your iax.conf file? If the [general] context line is missing then please add it (at the top of the file), restart asterisk, and see if that corrected the behavior.

Hi Allan,

Yes, the [general] is there. I was just trying to limit how much I was copy/pasting into the posting, as it can get rather long. I wanted to be sure to start just before the codec section, hence the line or two above where the pertinent info starts.

I can confirm there is no [radio-secure] section, so I am assuming it is defaulting to the [general] section. Would it be worth creating a [radio-secure] section and list out the codecs, then restart and test again?

I am willing to share/upload the actual conf file(s) if that would be of benefit.

Eric
K2CB

and I thought I had figured this one out :frowning:

Sounds like we'll be looking at the IAX2 channel driver source code ... tomorrow

That should be simple enough configuration change and it would most certainly provide some added insight ... so, if you don't mind, go for it.

If what you have reported here is correct (with the [general] stanza line present, not commented out, and starting in column 1) then seeing the actual file should not be needed.