Opus codec with android VOIP application

λ.eranga
λ.eranga
Jun 26, 2017 · 6 min read
Image for post
Image for post

What is VOIP

VOIP stands for voice over IP. It means route/transmit the voice calls over the internet rather than traditional mobile service providers. Following are some popular VOIP applications in the market.

  1. Viber
  2. Whatsapp
  3. Skype
  4. Google hangouts
  5. Telegram

What is codec

Codec stands for COder-DECoder or COmpressor-DECompressor. It simply an algorithm/program which can be use compress and decompress audio data (which are transmitting over the internet). Depending of the codec, the size of the audio data and the quality will be determined.

Why we need codec

Plain audio data(for an example, audio data which record via AudioRecorder in android) are really large in size. If we send these plain data over the internet it will consume huge bandwidth. To avoid this bandwidth issue we need to use a codec to compress and decompress the data while sending thought the internet. There are two main types of audio compressions in VOIP codecs, lossy and lossless

lossless compression

In lossless compression you loss nothing while compressing the audio data. This type of compression provides high quality but does not provide much downsizing the audio data while compressing.

lossy compression

In lossy compression you loss some data while compressing. It can provide great downsizing the audio data. But you will loss the quality of the audio. Most of the time in VOIP this quality loss won’t notice.

Available codecs

There are various types of codecs available for VOIP. Following are few of them.

  1. G.711
  2. G.729
  3. AMR
  4. GSM
  5. Speex
  6. SLIK (use in skype)
  7. CELT
  8. Opus (use in whatsapp)

About opus codec

Opus is totally free and open source audio codec. It developed with incorporates technology from Skype’s SILK codec and Xiph.Org’s CELT codec. Whatsapp using this codec in their VOIP application. Following are some features of opus codec.

  1. Bitrates from 6 kb/s to 510 kb/s
  2. Sampling rates from 8 kHz (narrowband) to 48 kHz (fullband)
  3. Frame sizes from 2.5 ms to 60 ms
  4. Support for both constant bitrate (CBR) and variable bitrate (VBR)

Opus with android

Opus codec implementation done in C++. It needs to integrate with android application via Java Native Interface(JNI). Opus source available at github as well as official opus download page .

Opus with “Rahasak” android application

I have developed an android communication application named Rahasak. Meaning of is in english. Rahasak is an innovative application that can be use to share secret informations such as Voice calls, Texts, Selfies, Location informations etc with friends. More informations about Rahasak app in here.

In Rahasak application AudioRecorder is using for record audio data and AudioTrack is using for play the audio data.

Recording data needs to be compressed via opus codec and send to other party over the audio streaming service. (I have built a custom audio UDP based audio streaming server with scala and akka).

When receiving party receives the data(which are compressed via opus codec) it decompress them via opus codec and play via AudioTrack.

Following are the steps that I have followed to integrate opus codec with my android application.

1. Setup android NDK

To integrate opus codec via JNI, first I needs setup android NDK. Download NDK from here and extract it. Main thing to consider here is, I need to add NDK related commands to your environment variable. I have exported it on my file(I’m using zsh as my shell, Add it to if you are using bash shell)

Image for post
Image for post

2. Install make packages

Opus codec needs to be compile via commands. To do that I need to install following packages on my mac.

brew install autoconf 
brew install automake
brew install libtool

Please follow the readme of opus codec for more information.

3. Add opus sources to android project

I have created separate directory called inside the directory and added opus codec source for it. Opus source can be cloned from github or download via official download page.

Image for post
Image for post

4. Compile opus source

Then I have compiled opus codec source which exists inside directory.

# goto opus directory
cd jni/opus
# compile and build library files
./configure
make

It will build C/C++ library files and header files for opus codec.

5. Opus JNI encoder and decoder

By using those generated library files and header files I have written JNI based C functions to compress/decompress audio data. These JNI files prefixed with which is the java package path of the JNI wrappers.

Image for post
Image for post

Following is the JNI based opus encoder

Following is the JNI based opus decoder

6. JNI wrappers

To call JNI based C function I need to write JNI wrappers for them. I kept the written wrappers in package. Read more about JNI from here.

Following is the JNI wrapper for opus encoder

Following is the JNI wrapper for opus decoder

7. Android make file

I need to build a native shared library () with my JNI C functions in order to call them from JAVA(with JNI wrapper). To do that I have written android make file . Since my C functions using opus library files, I have integrated them with the make file as well.

Following is the make file to build shared library

Now I can build the shared library via android NDK.

ndk-build
Image for post
Image for post

This command will generates shared library files inside and directories. The shared library name defined in the make file with

Image for post
Image for post

Now everything is ready to use opus codec to compress/encode and decompress/decode audio data.

8. Encode audio data

Following is the way I have used to compress the recording audio data.

In here when initializing I have used sample rate and frame size as . When reading the data from I have read size frames.

9. Decode audio data

Following is the way I have used to decompress audio data. Decompressed audio data can be played via .

When initializing the I have used sample size and frame size .

10. Run with gradle

Now I have integrated opus codec with my application. I can run it with gradle(in android studio). To run it with gradle I need to manually define the JNI library directory in file.

Source code

I have published all important source codes which mentioned in this article on my github. Please refer them if you want.

Reference

  1. https://telnyx.com/codecs-affect-voip-sound-quality/
  2. https://www.lifewire.com/what-is-codec-3426722
  3. https://www.lifewire.com/voip-codecs-3426728
  4. http://opus-codec.org/

Rahasak Labs

Have less, be more

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch

Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore

Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store