PJSIP and Speex: How to select wideband modes?

Hi all,

This will sound similar to previous threads, but basically I’m wondering what magic I put in the allow= line for PJSIP to permit Wideband/Ultra-Wideband speex

This will sound similar to previous threads that discussed the old chan_sip driver on older releases of Asterisk. I’m using PJSIP with Asterisk 16.6.2. Thus the main difference is in what’s changed since those earlier releases.

Right now I have this:
allow=speex,g722,ilbc,g726,g729,alaw,ulaw

This worked tonight, I was using Twinkle as my client and it had G.722 (I’ve patched it to support this), UWB Speex, WB Speex then NB Speex, followed by G.711a and G.711u.

It negotiated NB Speex (8kHz sample rate). It worked, but definitely not ideal.

Long term I’d like to support Opus, but that’s a work-in-progress that can wait for now. (Can’t use Digium’s CODEC on OpenBSD. There are one or two open-source plug-ins though, so I’ll investigate those.)

A lot will depend on where I’m connecting from… and I understand the Asterisk server can’t know if I’m hitting it via a VPN or over Ethernet/WiFi, so I’m thinking I need the server to somehow prefer the client’s CODEC list over its own. (That way, I can just configure my client to suit my network connection.)

My preference would be:

  1. Opus or UWB Speex
  2. G.722 or WB Speex
  3. G.729
  4. G.711a if local, or NB Speex if remote.
  5. G.711u

In a perfect world I’d probably encode this as:
accept=opus,speex:32000,g722,speex:16000,g729,g711a,speex:8000,g711u

However, I’m not sure if it’s even possible to encode a sample rate in there. Do I have to define custom CODECs in codecs.conf or is there some standard syntax for specifying wideband and ultra-wideband Speex modes?

The supported options for speex are:

speex
speex16
speex32

That did it…

I’m now using:
allow=speex32,g722,speex16,g729,g726,ilbc,speex,alaw,ulaw

That seems to work, I’ve got some fine tuning to do with the Speex CODEC itself to get the call quality up, but at least now it is using wideband mode.

Are the same conventions followed in codecs.conf? i.e. I should have separate [speex], [speex16] and [speex32] sections, or does [speex] configure all three?

I don’t have any experience with speex or codecs.conf, so I do not know.

No problems… it’s a big code base, so I can understand that.

I did some digging… this looks to be the bit in the Speex CODEC code that looks at codecs.conf:

It seems to look exclusively at speex… this same module otherwise seems to be responsible for all three variants of speex, so I’d guess based on that, the one common config group sets all three simultaneously.

So, been using this set-up a while now… I’m getting very good results now over 802.11n WiFi using these settings:

# pjsip.conf
allow=speex32,g722,speex16,g729,g726,ilbc,speex,alaw,ulaw

# codecs.conf
[speex]
; CBR encoding quality [0..10]
; used only when vbr = false
quality => 8

; codec complexity [0..10]
; tradeoff between cpu/quality
complexity => 4

; perceptual enhancement [true / false]
; improves clarity of decoded speech
enhancement => true

; voice activity detection [true / false]
; reduces bitrate when no voice detected, used only for CBR
; (implicit in VBR/ABR)
vad => true

; variable bit rate [true / false]
; uses bit rate proportionate to voice complexity
vbr => false

; available bit rate [bps, 0 = off]
; encoding quality modulated to match this target bit rate
; not recommended with dtx or pp_vad - may cause bandwidth spikes
abr => 0

; VBR encoding quality [0-10]
; floating-point values allowed
vbr_quality => 4
; discontinuous transmission [true / false]
; stops transmitting completely when silence is detected
; pp_vad is far more effective but more CPU intensive
dtx => false

; preprocessor configuration
; these options only affect Speex v1.1.8 or newer

; enable preprocessor [true / false]
; allows dsp functionality below but incurs CPU overhead
preprocess => false

; preproc voice activity detection [true / false]
; more advanced equivalent of DTX, based on voice frequencies
pp_vad => false

; preproc automatic gain control [true / false]
pp_agc => false
pp_agc_level => 8000

; preproc denoiser [true / false]
pp_denoise => false

; preproc dereverb [true / false]
pp_dereverb => false
pp_dereverb_decay => 0.4
pp_dereverb_level => 0.3

; experimental bitrate changes depending on RTCP feedback [true / false]
experimental_rtcp_feedback => false

Of course it helps that my Asterisk box is relatively beefy for the number of calls it needs to cope with, so CPU overheads converting Speex to whatever the call provider negotiates isn’t really an issue.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.