Skip to content

Commit 3b144d0

Browse files
committed
First of ilbc for android
0 parents  commit 3b144d0

File tree

5 files changed

+250
-0
lines changed

5 files changed

+250
-0
lines changed

AndroidManifest.xml

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
3+
package="com.tuenti.androidilbc"
4+
android:versionCode="1"
5+
android:versionName="1.0">
6+
<uses-sdk android:minSdkVersion="3" />
7+
</manifest>

README.md

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
iLBC Android
2+
==========
3+
4+
[Internet low bitrate codec](http://en.wikipedia.org/wiki/Internet_Low_Bit_Rate_Codec). This is a swc that wraps the base functionality of the iLBC codec now maintained by google as part of the [WebRTC](http://www.webrtc.org/) project.
5+
6+
Based loosely on an android version of iLBC at http://code.google.com/p/android-ilbc.
7+
8+
Changes
9+
* Built based on webrtc code instead of rfc
10+
* Adds option to use noise supression from webrtc in the encode method.
11+
12+
Codec.java included in this project should be compatible with the Demo.java found at http://code.google.com/p/android-ilbc/source/browse/src/com/googlecode/androidilbc/Demo.java except for the package name. As well to make that demo work, you would have to update the AndroidManifest.xml for your purposes.

jni/Android.mk

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
#ARCH_ARM_HAVE_ARMV7A := true
2+
TARGET_ARCH := arm
3+
4+
# Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
5+
#
6+
# Use of this source code is governed by a BSD-style license
7+
# that can be found in the LICENSE file in the root of the source
8+
# tree. An additional intellectual property rights grant can be found
9+
# in the file PATENTS. All contributing project authors may
10+
# be found in the AUTHORS file in the root of the source tree.
11+
12+
ILBC_WRAPPER_MAIN_PATH := $(call my-dir)
13+
14+
include $(ILBC_WRAPPER_MAIN_PATH)/webrtc/src/common_audio/signal_processing/Android.mk
15+
include $(ILBC_WRAPPER_MAIN_PATH)/webrtc/src/modules/audio_coding/codecs/ilbc/Android.mk
16+
include $(ILBC_WRAPPER_MAIN_PATH)/webrtc/src/modules/audio_processing/ns/Android.mk
17+
18+
LOCAL_PATH := $(ILBC_WRAPPER_MAIN_PATH)
19+
include $(CLEAR_VARS)
20+
21+
22+
LOCAL_ARM_MODE := arm
23+
LOCAL_MODULE_TAGS := optional
24+
25+
LOCAL_SRC_FILES :=\
26+
iLBC_codec.c
27+
28+
LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -llog
29+
30+
LOCAL_C_INCLUDES := \
31+
$(LOCAL_PATH)/webrtc/src/modules/audio_coding/codecs/ilbc/interface \
32+
$(LOCAL_PATH)/webrtc/src/modules/audio_coding/codecs/ilbc/ \
33+
$(LOCAL_PATH)/webrtc/src/common_audio/signal_processing/include \
34+
$(LOCAL_PATH)/webrtc/src/modules/audio_processing/ns/include/ \
35+
$(LOCAL_PATH)/webrtc/src/
36+
37+
38+
LOCAL_WHOLE_STATIC_LIBRARIES := \
39+
libwebrtc_ns \
40+
libwebrtc_spl \
41+
libwebrtc_ilbc
42+
43+
LOCAL_MODULE := iLBC_codec
44+
45+
include $(BUILD_SHARED_LIBRARY)

jni/Applicaiton.mk

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# ARMv7 is significanly faster due to the use of the hardware FPU
2+
APP_STL := gnustl_static
3+
APP_ABI := armeabi armeabi-v7a
4+
APP_OPTIM := release
5+
APP_BUILD_SCRIPT := /Users/lukeweber/iLBC-android-wrapper/jni/Android.mk
6+
# APP_CPPFLAGS += -fexceptions -frtti

jni/iLBC_codec.c

+180
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
#include "jni.h"
2+
#include <math.h>
3+
#include <stdlib.h>
4+
#include <stdio.h>
5+
#include <string.h>
6+
#include "ilbc.h"
7+
#include "noise_suppression_x.h"
8+
#include "defines.h"
9+
10+
#define LOG_TAG "iLBC_codec"
11+
12+
#include <android/log.h>
13+
#define LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__)
14+
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG , LOG_TAG, __VA_ARGS__)
15+
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO , LOG_TAG, __VA_ARGS__)
16+
#define LOGW(...) __android_log_print(ANDROID_LOG_WARN , LOG_TAG, __VA_ARGS__)
17+
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR , LOG_TAG, __VA_ARGS__)
18+
19+
#define JNI_COPY 0
20+
21+
static iLBC_encinst_t *Enc_Inst = NULL;
22+
static iLBC_decinst_t *Dec_Inst = NULL;
23+
static NsxHandle *nsxInst = NULL;
24+
25+
const short MODE = 30;//30ms
26+
const short FRAME_SAMPLES = 240;//MODE << 3;//240
27+
const short FRAME_SIZE = 480;//FRAME_SAMPLES * sizeof(short);//480
28+
29+
static int encoding, decoding, encoderReset, decoderReset;
30+
31+
static void noise_supression(short* a, int samples, int ns_mode){
32+
short tmp_input[80];
33+
if(nsxInst == NULL){
34+
WebRtcNsx_Create(&nsxInst);
35+
WebRtcNsx_Init(nsxInst, 8000);//8000 hz sampling
36+
WebRtcNsx_set_policy(nsxInst, ns_mode);//0: Mild, 1: Medium , 2: Aggressive
37+
}
38+
int i;
39+
for (i = 0; i < samples; i+= 80){
40+
memcpy(tmp_input, &a[i], 80 * sizeof(short));
41+
WebRtcNsx_Process(nsxInst, tmp_input, NULL, (short *)&a[i], NULL);
42+
}
43+
}
44+
45+
static void reset_encoder_impl(){
46+
if(!encoding){
47+
WebRtcIlbcfix_EncoderFree(Enc_Inst);
48+
Enc_Inst = NULL;
49+
WebRtcNsx_Free(nsxInst);
50+
nsxInst = NULL;
51+
encoderReset = 0;
52+
} else {
53+
encoderReset = 1;
54+
}
55+
}
56+
57+
jint Java_com_tuenti_androidilbc_Codec_resetEncoder(JNIEnv *env, jobject this){
58+
reset_encoder_impl();
59+
return 1;
60+
}
61+
62+
jint Java_com_tuenti_androidilbc_Codec_encode(JNIEnv *env, jobject this,
63+
jbyteArray src, jint src_offset, jint src_len, jbyteArray dest, jint ns_mode)
64+
{
65+
jsize src_size, dest_size;
66+
jbyte *src_bytes, *dest_bytes;
67+
68+
int bytes_remaining, bytes_encoded, num_samples;
69+
70+
encoding = 1;
71+
if(Enc_Inst == NULL){
72+
WebRtcIlbcfix_EncoderCreate(&Enc_Inst);
73+
WebRtcIlbcfix_EncoderInit(Enc_Inst, MODE);
74+
}
75+
76+
src_size = (*env)->GetArrayLength(env, src);
77+
src_bytes = (*env)->GetByteArrayElements(env, src, JNI_COPY);
78+
dest_size = (*env)->GetArrayLength(env, dest);
79+
dest_bytes = (*env)->GetByteArrayElements(env, dest, JNI_COPY);
80+
81+
src_bytes += src_offset;
82+
bytes_remaining = src_len;
83+
84+
int truncated = bytes_remaining % FRAME_SIZE;
85+
if(truncated){
86+
bytes_remaining -= truncated;
87+
LOGW("Ignoring last %d bytes, input must be divisible by %d", truncated, FRAME_SIZE);
88+
}
89+
90+
if(ns_mode < 0 || ns_mode > 2){
91+
LOGE("Noise supression must be set to a value of 0-3, 0:Off, 1: Mild, 2: Medium , 3: Aggressive");
92+
return -1;
93+
}
94+
95+
if(ns_mode > 0){
96+
noise_supression((short*)src_bytes, bytes_remaining, ns_mode -1);
97+
}
98+
99+
while(bytes_remaining > 0){
100+
num_samples = WebRtcIlbcfix_Encode(Enc_Inst, (short* )src_bytes, FRAME_SAMPLES, (WebRtc_Word16 *)dest_bytes);
101+
src_bytes += num_samples * sizeof(short);
102+
dest_bytes += NO_OF_BYTES_30MS;
103+
bytes_remaining -= num_samples * sizeof(short);
104+
bytes_encoded += num_samples * sizeof(short);
105+
}
106+
107+
src_bytes -= bytes_encoded;
108+
dest_bytes -= src_len;
109+
110+
(*env)->ReleaseByteArrayElements(env, src, src_bytes, JNI_COPY);
111+
(*env)->ReleaseByteArrayElements(env, dest, dest_bytes, JNI_COPY);
112+
113+
encoding = 0;
114+
if(encoderReset){
115+
reset_encoder_impl();
116+
}
117+
118+
return bytes_encoded;
119+
}
120+
121+
static void reset_decoder_impl(){
122+
if(!decoding){
123+
WebRtcIlbcfix_DecoderFree(Dec_Inst);
124+
Dec_Inst = NULL;
125+
decoderReset = 0;
126+
} else {
127+
decoderReset = 1;
128+
}
129+
}
130+
131+
jint Java_com_tuenti_androidilbc_Codec_resetDecoder(JNIEnv *env, jobject this){
132+
reset_decoder_impl();
133+
return 1;
134+
}
135+
136+
jint Java_com_tuenti_androidilbc_Codec_decode(JNIEnv *env, jobject this,
137+
jbyteArray src, jint src_offset, jint src_len, jbyteArray dest)
138+
{
139+
jsize src_size, dest_size;
140+
jbyte *src_bytes, *dest_bytes;
141+
142+
int num_samples, bytes_remaining, bytes_decoded;
143+
short speechType;
144+
145+
src_size = (*env)->GetArrayLength(env, src);
146+
src_bytes = (*env)->GetByteArrayElements(env, src, JNI_COPY);
147+
dest_size = (*env)->GetArrayLength(env, dest);
148+
dest_bytes = (*env)->GetByteArrayElements(env, dest, JNI_COPY);
149+
150+
decoding = 1;
151+
if(Dec_Inst == NULL){
152+
WebRtcIlbcfix_DecoderCreate(&Dec_Inst);
153+
WebRtcIlbcfix_DecoderInit(Dec_Inst, MODE);
154+
}
155+
156+
src_bytes += src_offset;
157+
bytes_remaining = src_len;
158+
159+
int i = 0;
160+
while(bytes_remaining > 0){
161+
num_samples = WebRtcIlbcfix_Decode(Dec_Inst, (short *)src_bytes, NO_OF_BYTES_30MS, (short *)dest_bytes, &speechType);
162+
src_bytes += NO_OF_BYTES_30MS;
163+
dest_bytes += num_samples * sizeof(short);
164+
bytes_remaining -= NO_OF_BYTES_30MS;
165+
bytes_decoded += num_samples * sizeof(short);
166+
}
167+
168+
src_bytes -= bytes_decoded;
169+
dest_bytes -= src_len;
170+
171+
(*env)->ReleaseByteArrayElements(env, src, src_bytes, JNI_COPY);
172+
(*env)->ReleaseByteArrayElements(env, dest, dest_bytes, JNI_COPY);
173+
174+
decoding = 0;
175+
if(decoderReset){
176+
reset_decoder_impl();
177+
}
178+
179+
return bytes_decoded;
180+
}

0 commit comments

Comments
 (0)