Coder Social home page Coder Social logo

asterisk-evs's Introduction

3GPP EVS for Asterisk

This is an implementation of 3GPP TS 26.445 Annex A. Sometimes, 3GPP Enhanced Voice Services (EVS) are called Full-HD Voice. Qualcomm calls it Ultra HD Voice. Research papers comparing EVS with other audio codecs were published at ICASSP 2015. Further examples…

To add a codec for SIP/SDP (m=, rtmap, and ftmp), you create a format module in Asterisk: codec_evs.patch (for m= and rtmap) and res/res_format_attr_evs.c (for fmtp). However, this requires both call legs to support EVS (pass-through only). If one leg does not support EVS, the call has no audio. Or, if you use the pre-recorded voice and music files of Asterisk, these files cannot be heard, because they are not in EVS but in slin. Therefore, this repository adds not just a format module for the audio-codec EVS but a transcoding module as well: build_evs.patch and codecs/codec_evs.c.

Installing the patch

At least Asterisk 13.7 is required. These changes were last tested with Asterisk 13.22 (and Asterisk 16.0). If you use a newer version and the patch fails, please, report!

cd /usr/src/
wget downloads.asterisk.org/pub/telephony/asterisk/asterisk-13-current.tar.gz
tar zxf ./asterisk*
cd ./asterisk*
sudo apt --no-install-recommends --assume-yes install autoconf automake build-essential pkg-config libedit-dev libjansson-dev libsqlite3-dev uuid-dev libxslt1-dev xmlstarlet

Apply the patch:

wget github.com/traud/asterisk-evs/archive/master.zip
unzip -qq master.zip
rm master.zip
cp --verbose --recursive ./asterisk-evs*/* ./
patch -p0 <./codec_evs.patch

Install libraries:

If you do not want transcoding but pass-through only (because of license issues) please, skip this step. To support transcoding, you’ll need to install the 3GPP EVS Reference Implementation, for example in Debian/Ubuntu:

wget www.etsi.org/deliver/etsi_ts/126400_126499/126443/16.01.00_60/ts_126443v160100p0.zip
unzip -qq ts_126443v*.zip
unzip -qq 26443-*-ANSI-C_source_code.zip
cd ./c-code
chmod +r ./lib_*/*.h
sudo mkdir /usr/include/3gpp-evs
sudo cp --verbose --target-directory=/usr/include/3gpp-evs ./lib_*/*.h
DEBUG=0 RELEASE=1 CFLAGS='-DNDEBUG -fPIC' make
cd ./build
rm ./decoder.o
cc -shared -o lib3gpp-evs.so *.o
sudo cp ./lib3gpp-evs.so /usr/lib/
cd /usr/src/asterisk*
patch -p0 <./build_evs.patch
patch -p0 <./force_limitations.patch

Run the bootstrap script to re-generate configure:

./bootstrap.sh

Configure your patched Asterisk:

./configure

Enable slin16 in menuselect for transcoding, for example via:

make menuselect.makeopts
./menuselect/menuselect --enable-category MENUSELECT_CORE_SOUNDS

Compile and install:

make
sudo make install

Testing

Currently, I am not aware of any other VoIP/SIP project offering EVS. Consequently, you have to patch two Asterisk servers and run EVS between those. My main objective was to play around, test, and learn more about EVS.

Although the Qualcomm Snapdragon 820 (and newer) chipset(s) offer EVS, not all phones come with EVS enabled. Of the remaining phones, not all offer the built-in VoIP/SIP client of the Android Open Source Platform (AOSP). Finally, I am not aware of one phone which bridges its EVS capabilities between the hardware chipset and that software client.

The Rohde & Schwarz CMW500 can be extended for EVS – however here, this transcoding module was not tested with that either.

What is missing

Although this list is rather long, these features are disabled at SDP negotiation via the force_limitations.patch and should not create an interoperability issue.

  • Compound payload: Several frames per payload, for example when FEC or a packetization time (ptime) longer than 20 ms are used. This is useful to lower the overall overhead (RTP, UDP, and IP).
  • Packet-Loss Concealment (native PLC), see ASTERISK-25629…
  • Channel Awareness (RTCP interaction), see ASTERISK-26584…
  • Compact Format mode; not sure if that is possible with Asterisk, see codec_evs.c:evs_sample_counter
  • AMR-WB IO without transcoding

The transcoding module works for me and contains everything I need. If you cannot code yourself, however, a feature is missing for you, please, report and send me at least a testing device.

Thanks go to

everyone who made the 3GPP EVS Reference Implementation possible.

asterisk-evs's People

Contributors

mtryfoss avatar traud avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

asterisk-evs's Issues

SDP: change dtx=0 to dtx-recv=0

Although there is no limitation to force continuous transmission anymore (dtx=0), DTX is still not recommended for Asterisk. Asterisk does not generate Comfort Noise (CNG) while decoding SID frames of EVS. You hear nothing on the non-EVS side of the call. Because of this, the call quality would suffer with DTX. Because of this, dtx=0 remained in force_limitations.patch.

However with the latest release of 3GPP TS 26.445, a new section was introduced (A.3.3.3). With that new section, dtx=0 is not allowed for Asterisk as SDP answerer, when the SDP offerer stated dtx-recv=1. To avoid any incompatibilities but still cope with the fact that Asterisk does not have a CNG, force_limitations.patch should be changed from dtx=0 to dtx-recv=0.

Even then, one incompatible case remains: When the SDP offerer states dtx=1, Asterisk (the SDP answerer) should cope with DTX (= is not allowed to answer with dtx-recv=0). Consequently with dtx=1, the offerer does not ask for but requests DTX. This implies that all implementations have a CNG, which Asterisk does not have. Furthermore, this new section adds another state, a third state, to the DTX parameter:

  • not present (not included in SDP)
  • 1
  • 0

Previously, ‘not present’ had the same semantic as ‘1’. Now, 1 requests DTX. Furthermore, any party should be able to control the receiving of DTX via dtx-recv=0. However with this new section, when the SDP offerer asks for dtx=1, Asterisk has to cope with incoming DTX.

It is believed that this is a regression introduced into the specification. Therefore, this is going to be discussed with the respective 3GPP working group. Until this is resolved, Asterisk still sends dtx-recv=0 even when dtx=1 was received. Nevertheless as stated in the second paragraph, force_limitations.patch can be changed from dtx=0 to dtx-recv=0 which avoids incompatibilities in other cases.

Bitstream is corrupted error

I managed to apply the patch and test the EVS codec with an actual SBC. But sometimes, some calls are logging such errors:

2nd CMR; bitstream is corrupted
2nd frame; bitstream is corrupted

Sometimes they come 2-3 times (both of them), sometimes Asterisk writes them 100+ times for a call.

The related code for this errors in codec_evs.c is like this (starting line 464):

if (toc_byte & 0x80) { /* Header Type identification bit */
		ast_log(LOG_ERROR, "2nd CMR; bitstream is corrupted\n");
	}

	if (toc_byte & 0x40) { /* Followed bit */
		ast_log(LOG_ERROR, "2nd frame; bitstream is corrupted\n"); /* ToDo */
	}

I'm suspecting this happens because of there is no PLC (Packet-Loss Concealment) implemented?
The force_limitations.patch is forcing only Header Full format. If some RTP packages do not come with headers, can that be a reason for the errors I get in logs? What if I change hf-only =-1 ?

Don't have many chances to test all the scenarios, so would be great to get an advice on how would be the best to proceed.

Issue with Samsung

Hello!

Samsung (at least Galaxy S7) do not accept "evs/16000" in lower-case.
All documentation I've seen has EVS in upper-case. However, I do not know if that's required.

Adding this line to rtp_engine.c did the trick:
set_next_mime_type(ast_format_evs, 0, "audio", "EVS", 16000);

AMR-WB IO mode - thoughts

Hello!

As stated in the README, AMR-WB IO is not supported. However, I wonder a bit how this would work in Asterisk. I've not found much details regarding how clients behave.

Will this primarily be a change in res_format_attr_evs.c or the codec module itself?
For example, will the EVS decoder produce AMR-WB frames instead of slin?

Missing translation for EVS

Patch installed on Red Hat 8.8. Asterisk version is 16.18.0. In core show codecs EVS exists, but do not see him in translation list

asterisk16_vm_1 -rx "core show codecs" | grep evs 3 audio evs evs (3GPP EVS)

` Translation times between formats (in microseconds) for one second of data
Source Format (Rows) Destination Format (Columns)

        amr amrwb  ulaw  alaw   gsm  g726 g726aal2 adpcm slin8 slin12 slin16 slin24 slin32 slin44 slin48 slin96 slin192 lpc10  ilbc  g722 testlaw
  amr     - 23000 15000 15000 15000 15000    15000 15000  9000  17000  17000  17000  17000  17000  17000  17000   17000 15000 15000 17250   15000
amrwb 23500     - 23500 23500 23500 23500    23500 23500 17500  17500   9000  17000  17000  17000  17000  17000   17000 23500 23500 15000   23500
 ulaw 15000 23000     -  9150 15000 15000    15000 15000  9000  17000  17000  17000  17000  17000  17000  17000   17000 15000 15000 17250   15000
 alaw 15000 23000  9150     - 15000 15000    15000 15000  9000  17000  17000  17000  17000  17000  17000  17000   17000 15000 15000 17250   15000
  gsm 15000 23000 15000 15000     - 15000    15000 15000  9000  17000  17000  17000  17000  17000  17000  17000   17000 15000 15000 17250   15000
 g726 15000 23000 15000 15000 15000     -    15000 15000  9000  17000  17000  17000  17000  17000  17000  17000   17000 15000 15000 17250   15000

g726aal2 15000 23000 15000 15000 15000 15000 - 15000 9000 17000 17000 17000 17000 17000 17000 17000 17000 15000 15000 17250 15000
adpcm 15000 23000 15000 15000 15000 15000 15000 - 9000 17000 17000 17000 17000 17000 17000 17000 17000 15000 15000 17250 15000
slin8 6000 14000 6000 6000 6000 6000 6000 6000 - 8000 8000 8000 8000 8000 8000 8000 8000 6000 6000 8250 6000
slin12 14500 14000 14500 14500 14500 14500 14500 14500 8500 - 8000 8000 8000 8000 8000 8000 8000 14500 14500 14000 14500
slin16 14500 6000 14500 14500 14500 14500 14500 14500 8500 8500 - 8000 8000 8000 8000 8000 8000 14500 14500 6000 14500
slin24 14500 14500 14500 14500 14500 14500 14500 14500 8500 8500 8500 - 8000 8000 8000 8000 8000 14500 14500 14500 14500
slin32 14500 14500 14500 14500 14500 14500 14500 14500 8500 8500 8500 8500 - 8000 8000 8000 8000 14500 14500 14500 14500
slin44 14500 14500 14500 14500 14500 14500 14500 14500 8500 8500 8500 8500 8500 - 8000 8000 8000 14500 14500 14500 14500
slin48 14500 14500 14500 14500 14500 14500 14500 14500 8500 8500 8500 8500 8500 8500 - 8000 8000 14500 14500 14500 14500
slin96 14500 14500 14500 14500 14500 14500 14500 14500 8500 8500 8500 8500 8500 8500 8500 - 8000 14500 14500 14500 14500
slin192 14500 14500 14500 14500 14500 14500 14500 14500 8500 8500 8500 8500 8500 8500 8500 8500 - 14500 14500 14500 14500
lpc10 15000 23000 15000 15000 15000 15000 15000 15000 9000 17000 17000 17000 17000 17000 17000 17000 17000 - 15000 17250 15000
ilbc 15000 23000 15000 15000 15000 15000 15000 15000 9000 17000 17000 17000 17000 17000 17000 17000 17000 15000 - 17250 15000
g722 15600 15000 15600 15600 15600 15600 15600 15600 9600 17500 9000 17000 17000 17000 17000 17000 17000 15600 15600 - 15600
testlaw 15000 23000 15000 15000 15000 15000 15000 15000 9000 17000 17000 17000 17000 17000 17000 17000 17000 15000 15000 17250 -`

Interoperability: Asterisk 13 on re-INVITE

When Asterisk started the call but the remote party sends a re-INVITE on the SIP layer, the call might face one-way audio. One such a call scenario is call hold, for example. One-way audio happens because this codec here uses a dynamic RTP payload type in SDP negotiation, which Asterisk 13 LTS does not support correctly. Complete details are documented in ASTERISK-27056. Even if you are not affected, applying the patch provided there is recommended for any user. If you face an issues with that patch, report in ASTERISK-27056, please. If possible, consider upgrading to a newer Asterisk branch.

Bandwidth negotiation does not accept NB

From what I managed to understand from the code, the patch allows Asterisk to work with all 4 types of bandwidth of the EVS codec: NB, WB, SWB and FB.

I had a chance to test the patch in practice and sometimes I stumbled on the following error:
no bandwidth in common

After checking the code, I noticed that there's a restriction regarding the negotiated bandwidth. In the res_format_attr_evs.c at the 803 line there is this:
if (0 == (attr_res->bw_recv & 0x1e) || 0 == (attr_res->bw_send & 0x1e)) { ast_log(LOG_WARNING, "no bandwidth in common\n"); return NULL;

From my limited knowledge, I take it this limits bandwidth negotiation to only the WB and up. That is, if common negotiated bandwidth is NB, then the module will consider that no common bandwidth was found, and therefore end the call.

Any specific reason to limit the common denominator to WB and up? Or was this pure own preference?

Interested in trying a change to this in practice:
if (attr_res->bw_recv == 0 || attr_res->bw_send == 0) {

3GPP EVS Reference Implementation (RI) not compatible anymore

The last versions of the RI being compatible are:

  • 12.12.0
  • 13.8.0
  • 14.4.2
  • 15.2.2
  • 16.1.0

Those versions are still available at ETSI and 3GPP, and the module builds/works just fine with one of those.

However, the RI saw a major change request in September 2021. As a side-effect, that changed/extended the API of read_indices_from_djb(…) with three more parameters. Consequently, this project here does not build with the very latest versions of the RI. I have still to investigate whether

  • I have to use those new parameters (= complex, meaningful values), or
  • I can simply define those (= static values), or
  • that avoids a long-standing issue with unneeded double shuffling in the mode AMR-IO (and therefore not just different parameters but a completely different code flow in my Asterisk module).

Although I consider that Change Request critical security-wise, although I know that

  • Digium Asterisk within an IMS, or
  • Digium Asterisk with guest access enabled,

an audio-codec implementation is exposed to the public, I do not fix but just note this issue for now. If you need an urger fix for this, please, give this issue report a thumps-up or contact me directly so I know that anyone still uses this module.

codec_evs.patch misapplies in Asterisk 18

The patch for rtp_engine.c is :
--- main/rtp_engine.c (Asterisk 13.13.1)
+++ main/rtp_engine.c (working copy)
@@ -2307,2 +2307,4 @@
add_static_payload(107, ast_format_opus, 0);
+

  •   ast_rtp_engine_load_format(ast_format_evs);
    

Fuzz of 1 causes this to misapply in Asterisk 18.

Changing the line numbers to:
@@ -3720,2 +3720,4 @@

before applying the patch is necessary for Asterisk 18.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.