Thursday, August 10, 2017

How to update C++ changes in Custom library?

  1. Download Trillbit.zip, which contains library and headers.
  2. Go inside the Trillbit's mobile app folder. (Please pull the latest changes from master branch)
    1. cd ~/TrillApp.
  3. Put any updated/new C++ code in gen-libs/src/main/cpp/ folder.
  4. Build and run the app to verify its working correctly.
  5. Copy headers:
    1. cp distribution/demodulation/include/bpsk/* ~/Downloads/Trillbit/include
  6. Copy shared libraries:
    1. cd distribution/demodulation/lib/bpsk/
    2. for folder in *; do cp $folder/libtrill.so ~/Downloads/Trillbit/lib/$folder/; done
  7. Zip the Trillbit folder.

Integration of an Android App with Custom library

  1. Android App should have "Include C++ Support" checked.
  2. Unzip Trillbit.zip inside <App_Name> folder.
  3. Open app/CMakeLists.txt . Add the following lines to include "Trill" library and headers:
set(trillbit_DIR ../trillbit)

add_library(lib_itpp SHARED IMPORTED)
set_target_properties(lib_itpp PROPERTIES IMPORTED_LOCATION
${trillbit_DIR}/lib/${ANDROID_ABI}/libitpp.so)

add_library(lib_trill SHARED IMPORTED)
set_target_properties(lib_trill PROPERTIES IMPORTED_LOCATION
${trillbit_DIR}/lib/${ANDROID_ABI}/libtrill.so)

add_library( <your_cpp_filename>
             SHARED
             src/main/cpp/<your_cpp_filename>.cpp )

target_include_directories(<your_cpp_filename> PRIVATE ${trillbit_DIR}/include)

target_link_libraries(<your_cpp_filename>
                      android
                      lib_itpp
                      lib_trill)
4. Open app/build.gradle and add following line after buildTypes:
sourceSets {
 main {
  // let gradle pack the shared library into apk
  jniLibs.srcDirs = ['../trillbit/lib']
 }
}
5. Open src/main/cpp/<your_cpp_filename>.cpp for JNI implementation. Here is a sample code to show how to find trigger in recorded audio data using Trill library.
#include <jni.h>
#include <string>
#include <trigger.h>

extern "C"
jboolean
Java_com_trillbit_trillapp_MainActivity_isTriggerFound(
JNIEnv* env,
jobject, jshortArray data_arr, jint data_arr_len) {

//normalize raw recorded audio data and put into a string
std::string data_str;
for(jint i = 0; i < data_arr_len; i++)
{
 char dataInterim[30];
 sprintf(dataInterim,"%f, ", data_arr[i]/pow(2,10)); data_str.append(dataInterim);
}

Trigger tg;
return tg.isFound(data_str);
}

5. Open src/main/java/MainActivity.java. Following sample code shows how Trillbit's library is accessible to Java code through JNI.




static {
 System.loadLibrary("<your_cpp_filename>");
}

@Override
protected void onCreate(Bundle savedInstanceState) {
   ....
   ....
   short[] buffer = new short[BUFFER_SIZE];
   recorder.read(buffer, 0, BUFFER_SIZE);
   ....
   if (isTriggerFound(buffer, buffer.length)) {

   }
   .....
}
// Put this definition at the end of the file
public native boolean isTriggerFound(short[] data, int data_len);

Testing of C++ code via Python

  1. Install boost in your machine as instructed over here -> https://trillbit.slack.com/files/rajanya/F3CEJ0U9E/Interaction_of_C___and_Python_via_Boost_Python
  2. Clone C++ repository -> https://bitbucket.org/trillbit/bpskdemodulation_c
  3. cd ~/Download/bpskdemodulation
  4. Pull the latest(if any) C++ code changes.
  5. Open Eclipse CDT -> Open this project -> Build Project. [This generates 'bpsk.so' in Debug folder]
  6. sudo cp /Debug/bpsk.so /Library/Python/2.7/site-packages/
  7. Create test.py with following code for demodulation. ( Ensure hellotrill.wav file is in the same folder as the python file )




import numpy as np
from scipy.io.wavfile import read
from scipy import signal
import bpsk


def convertArrToStr(array):
 array_list = array.tolist();
 array_str = ",".join(str(x) for x in array_list)
 return array_str

mod_signal = read("hellotrill.wav")
data_signal = np.array(mod_signal[1], dtype=float)
data_signal_str = convertArrToStr(data_signal)
data_output = np.fromstring(bpsk.finddata(data_signal_str), dtype=float, sep=',')
data_output_str = convertArrToStr(data_output)
data = np.fromstring(bpsk.demod(data_output_str), dtype=float, sep=',')
print data

FFTW and IT++ with Eclipse And Command Line


Installation of FFTW:
  1. Download the latest FFTW package from http://www.fftw.org/.
  2. Unzip and install FFTW:
    1. cd ~/Downloads/fftw-3.3.5
    2. ./configure
    3. make && make install
  3. Verify that libfftw3.a and libfftw3.la are present in the path /usr/local/lib
Installation of IT++:
  1. Download the latest IT++ package from http://itpp.sourceforge.net/4.3.1/installation.html.
  2. Unzip and go inside the folder : cd ~/Downloads/itpp-4.3.1
  3. Create a build directory : mkdir build && cd build/
  4. Open cmake GUI. If cmake not present , visit https://cmake.org/download/
  5. In cmake, add the following entries:
    1. Where is the source code: ~/Downloads/itpp-4.3.1
    2. Where to build the binaries:~/Downloads/itpp-4.3.1/build
  6. Click Configure -> Use default native compilers -> Done
  7. Click Generate
  8. Return back to terminal. Run make && make install to build & install. [Locate the shared library at /usr/local/lib/]
NOTE: Install FFTW (or any other dependent packages) before IT++

Linking IT++ in Eclipse:
  1. Install the latest Eclipse CDT from https://eclipse.org/cdt/.
  2. Add the shared library of itpp in the path:
    1. Project -> Properties -> C/C++ General -> Paths and Symbols -> Libraries -> Add -> enter 'itpp' -> OK
  3. Write (or get it from BitBucket) C++ code which uses IT++ functions. Then
    1. Build Project
    2. Run As -> Local C/C++ Application
  4. If the following error "Launch failed. Binary not found." is encountered, then fix it by: Project -> Properties -> C/C++ Build -> Settings -> Binary Parsers -> check Mach-O 64 Parser

Linking IT++ in Command Line:
  1. PATH=$PATH:/usr/local/include/:/usr/local/lib/
  2. g++ -o <output> <filename>.cc -litpp
  3. ./<output>