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.
- Google hangouts
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
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.
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.
There are various types of codecs available for VOIP. Following are few of them.
- SLIK (use in skype)
- 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.
- Bitrates from 6 kb/s to 510 kb/s
- Sampling rates from 8 kHz (narrowband) to 48 kHz (fullband)
- Frame sizes from 2.5 ms to 60 ms
- Support for both constant bitrate (CBR) and variable bitrate (VBR)
Opus with android
Opus with “Rahasak” android application
I have developed an android communication application named Rahasak. Meaning of
Secrets 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
$PATH environment variable. I have exported it on my
~/.zshrc file(I’m using zsh as my shell, Add it to
~/.bashrc if you are using bash shell)
2. Install make packages
Opus codec needs to be compile via
make 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
4. Compile opus source
Then I have compiled opus codec source which exists inside
# goto opus directory
cd jni/opus# compile and build library files
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
com_score_rahasak_utils which is the java package path of the JNI wrappers.
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
com_score_rahasak_utils_ 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 (
.so) with my JNI C functions in order to call them from JAVA(with JNI wrapper). To do that I have written android make file
Android.mk. 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.
This command will generates shared library files inside
app/src/main/obj directories. The shared library name defined in the make file with
LOCAL_MODULE := senz
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
OpusEncoder to compress the recording audio data.
In here when initializing
OpusEncoder I have used sample rate
16000 and frame size as
160. When reading the data from
AudioRecorder I have read
short 160 size frames.
9. Decode audio data
Following is the way I have used
OpusDecoder to decompress audio data. Decompressed audio data can be played via
When initializing the
OpusDecoder I have used sample size
16000 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
I have published all important source codes which mentioned in this article on my github. Please refer them if you want.