Tuesday, July 31, 2018

Installation of NLopt python module for Linux

Installation of NLopt python module for Linux

  1. Install SWIG (follow instructions: http://swig.org/svn.html)
    1. cd ~
    2. git clone https://github.com/swig/swig.git
    3. cd swig
    4. ./autogen.sh ( sudo apt-get install automake [if aclocal not found])
    5. ./configure --prefix=<absolute path to current dir> --without-pcre
    6. make
    7. sudo apt-get install bison -y && sudo apt-get install byacc -y [if yacc not found]
    8. make install
  2. export PATH=$PATH:~/swig
  3. Install NLopt: (follow instructions: https://github.com/stevengj/nlopt)

  1. git clone https://github.com/stevengj/nlopt.git
  2. cd nlopt
  3. mkdir build
  4. cd build
  5. cmake -DPYTHON_EXECUTABLE=/usr/bin/python3.6 ..
  6. make
  7. sudo make install

       Note: copy the nlopt.py and _nlopt.so files to the desired dist-packages

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>

Friday, June 2, 2017

Interaction of C++ and Python via Boost.Python

  • Download latest boost package from http://www.boost.org/.
  • Unzip and go inside the folder: cd ~/Downloads/boost_1_62_0
  • Run ./bootstrap.sh
  • Then run ./b2 . This will build all the shared libraries in ~/Downloads/boost_1_62_0/stage/lib.(we are interested in boost_python library as of now)
  • Copy headers and libraries to standard path:
    • sudo cp -r ~/Downloads/boost_1_62_0/boost /usr/local/include/
    • sudo cp ~/Downloads/boost_1_62_0/stage/lib/libboost_python.* /usr/local/lib/
  • Append Python wrapper code in C++ so that existing C++ code is not changed at all. [ Caution: Nomenclature of file name and module should be same!!! ]
        char const* greet()
        {
             return "hello, world";
        }
 
        #include <boost/python.hpp>
 
        BOOST_PYTHON_MODULE(<module>)
        {
             using namespace boost::python;
             def("greet", greet);
        }
  • g++ -c <filename>.cpp -o <filename>.o -fPIC && g++ -c <other_filename>.cpp -o <other_filename>.o
  • For following error "/usr/local/include/boost/python/detail/wrap_python.hpp:50:11: fatal error: 'pyconfig.h' file not found", add -I/usr/include/python2.7/ while compiling.
  • g++ -shared <filename>.o <other_filename>.o -lboost_python -lpython2.7 -o <filename>.so ( If <filename>.cpp depends on <other_filename>.cpp, put its compiled object as well. Include -litpp if the c++ code depends on IT++ library)
  • Put the shared library in the standard python module path: cp <filename>.so /Library/Python/2.7/site-packages/
  • Open .py file and call the C++ function: [ module and C++ filename are same ]
        import <module>
        module.greet();
  • For passing an argument from Python to C++, simply do the following:

     In C++:

     char const* greet(string name)
     {
        if(name != null) {
            return "hello " + name;
        } else {
            return "hello, world";
        }
     }
 
     #include <boost/python.hpp>
 
     BOOST_PYTHON_MODULE(<module>)
     {
         using namespace boost::python;
         def("greet", greet);
     }

    In Python:

    import <module>
    module.greet("Rajanya");

IT++ and FFTW integration with Android NDK

IT++ and FFTW libraries need to be compiled specific to Application Binary Interface (ABI) for Android NDK.

These are the following ABIs:
  1. X86
  2. X86_64
  3. armeabi
  4. mips
  5. mips64
etc....
Further details can be found over here-> https://developer.android.com/ndk/guides/abis.html

IMPORTANT: Compile FFTW before IT++ as IT++ incorporates FFTW's archived library inside its own shared library.


FFTW compilation for NDK:
  1. Download the latest package from http://www.fftw.org/
  2. Unzip and go inside the folder: cd ~/Downloads/fftw-3.3.5
  3. Set the compilation parameters specific to an ABI. The example is for 'armeabi'.
    1. export NDK_ROOT="/Users/rajanya/Library/Android/sdk/ndk-bundle"
    2. export PATH="$NDK_ROOT/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/bin/:$PATH"
    3. export SYS_ROOT="$NDK_ROOT/platforms/android-21/arch-arm/"
    4. export CC="arm-linux-androideabi-gcc --sysroot=$SYS_ROOT"
    5. export LD="arm-linux-androideabi-ld"
    6. export AR="arm-linux-androideabi-ar"
    7. export RANLIB="arm-linux-androideabi-ranlib"
    8. export STRIP="arm-linux-androideabi-strip"
    9. export DEST_DIR="$NDK_ROOT/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/user"
  4. Generate Makefile: ./configure --host=arm-eabi --build=i386-apple-darwin10.8.0 --prefix=$DEST_DIR LIBS="-lc -lgcc" --disable-fortran
  5. make && make install

IT++ compilation with FFTW for NDK:
  1. Download the latest 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. mkdir build && cd build/
  4. Download https://github.com/taka-no-me/android-cmake to obtain cmake toolchain file.
  5. Open cmake GUI. If cmake not present , visit https://cmake.org/download/
  6. 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
  7. Then click '+Add Entry' button to add the following key-value pair:
    1. ANDROID_NDK -> PATH -> ~/Library/Android/sdk/ndk-bundle
    2. ANDROID_NATIVE_API_LEVEL -> STRING -> 17
    3. ANDROID_TOOLCHAIN_NAME -> STRING -> arm-linux-androideabi-4.9
  8. Click Configure -> Specify toolchain file for cross-compiling -> ~/Downloads/android-cmake-master/android.toolchain.cmake
  9. Click Generate.
  10. Return back to terminal. Run make && make install to build & install the shared library at /usr/local/lib/
NOTE: Repeat the above steps for each and every ABI

How to make IT++ functions available to the C++ code in Android?

  1. Copy /usr/local/lib/libitpp.so to <app_path>/app/libs/
  2. Enter the following lines in the CMake file:
    1. set(distribution_DIR ${CMAKE_SOURCE_DIR}/../../../libs)
    2. add_library(lib_itpp SHARED IMPORTED)
    3. set_target_properties(lib_itpp PROPERTIES IMPORTED_LOCATION

          ${distribution_DIR}/lib/${ANDROID_ABI}/libitpp.so)
    4. target_link_libraries(native-lib
                            android
                            lib_itpp)
  3. #include<itpp/itbase.h> in your native-lib.cpp file.