diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000000..2717ed259e3 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,5 @@ +# dockerignore file to minimalize the size of docker image +# +# Ignore .git and dev directories +/** + diff --git a/.gitignore b/.gitignore index ed66c79d1c8..f0541072ba7 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,12 @@ !/src/*/Makefile !/src/*/README +# TechUnited begin +/log/ +/src/gst-plugin/kaldimarshal.cc +/src/gst-plugin/kaldimarshal.h +# TechUnited end + # Compiled Object files and python ciles *.slo *.lo diff --git a/CMakeLists.txt b/CMakeLists.txt index 1403ae001ee..aaad303f8f7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,9 @@ -cmake_minimum_required(VERSION 3.5) +cmake_minimum_required(VERSION 3.12) project(kaldi) +set(GENERATED_LIBS "" CACHE INTERNAL "") +set(ALL_TARGETS "" CACHE INTERNAL "") + set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake;${CMAKE_MODULE_PATH}") include(GNUInstallDirs) include(Utils) @@ -220,6 +223,20 @@ configure_package_config_file( ${CMAKE_BINARY_DIR}/cmake/kaldi-config.cmake INSTALL_DESTINATION lib/cmake/kaldi ) + +message(STATUS "The list of generated libraries is: ${GENERATED_LIBS}") +set(DEST_DIR "${CMAKE_INSTALL_PREFIX}") + +foreach(LIB ${GENERATED_LIBS}) + set(PRIVATE_LIBS "${PRIVATE_LIBS} -l${LIB}") +endforeach() + +configure_package_config_file( + ${CMAKE_CURRENT_SOURCE_DIR}/cmake/kaldi.pc.in + ${CMAKE_BINARY_DIR}/pkgconfig/kaldi.pc + INSTALL_DESTINATION lib/pkgconfig +) + write_basic_package_version_file( ${CMAKE_BINARY_DIR}/cmake/kaldi-config-version.cmake VERSION ${KALDI_VERSION} @@ -228,4 +245,7 @@ write_basic_package_version_file( install(FILES ${CMAKE_BINARY_DIR}/cmake/kaldi-config.cmake ${CMAKE_BINARY_DIR}/cmake/kaldi-config-version.cmake DESTINATION lib/cmake/kaldi ) + +install(FILES ${CMAKE_BINARY_DIR}/pkgconfig/kaldi.pc DESTINATION lib/pkgconfig) + install(EXPORT kaldi-targets DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/cmake/kaldi) diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000000..be96d3294cf --- /dev/null +++ b/Dockerfile @@ -0,0 +1,15 @@ +# ----------------------------------------------------------------------------- +# Dockerfile to build Kaldi gstreamer server with tue-env +# ----------------------------------------------------------------------------- + +# Set the base image to Ubuntu with tue-env +FROM tuerobotics/tue-env:master + +# Update the image and install basic packages +RUN sudo apt-get update -qq && \ + # Make tue-env available to the intermediate image + # This step needs to be executed at every RUN step + source ~/.bashrc && \ + # Install kaldi + tue-get install kaldi + diff --git a/.travis.yml b/ci/.travis.yml.old similarity index 100% rename from .travis.yml rename to ci/.travis.yml.old diff --git a/cmake/gen_cmake_skeleton.py b/cmake/gen_cmake_skeleton.py index 8c393630cfb..d52bb1126be 100644 --- a/cmake/gen_cmake_skeleton.py +++ b/cmake/gen_cmake_skeleton.py @@ -115,12 +115,20 @@ def add_test_source(self, filename): def gen_code(self): ret = [] + ret.append('set(ALL_TARGETS ${ALL_TARGETS} ' + '{} CACHE INTERNAL "ALL_TARGETS")'.format(self.target_name)) if len(self.header_list) > 0: ret.append("set(PUBLIC_HEADERS") for f in self.header_list: ret.append(" " + f) ret.append(")\n") + if self.target_name != 'kaldi-itf': + ret.append('if (GENERATED_LIBS STREQUAL "")') + ret.append(' set(GENERATED_LIBS "{}" CACHE INTERNAL "GENERATED_LIBS")'.format(self.target_name)) + ret.append('else()') + ret.append(' set(GENERATED_LIBS "${GENERATED_LIBS};' + '{}" CACHE INTERNAL "GENERATED_LIBS")'.format(self.target_name)) + ret.append('endif()') + ret.append("add_library(" + self.target_name + " INTERFACE)") ret.append("target_include_directories(" + self.target_name + " INTERFACE ") ret.append(" $") @@ -171,6 +179,7 @@ def load_dependency_from_makefile(self, filename): def gen_code(self): ret = [] + ret.append('set(ALL_TARGETS ${ALL_TARGETS} ' + '{} CACHE INTERNAL "ALL_TARGETS")'.format(self.target_name)) if len(self.header_list) > 0: ret.append("set(PUBLIC_HEADERS") @@ -188,6 +197,13 @@ def gen_code(self): ret.append(" )") ret.append("endif()\n") + if self.target_name != 'kaldi-itf': + ret.append('if (GENERATED_LIBS STREQUAL "")') + ret.append(' set(GENERATED_LIBS "{}" CACHE INTERNAL "GENERATED_LIBS")'.format(self.target_name)) + ret.append('else()') + ret.append(' set(GENERATED_LIBS "${GENERATED_LIBS};' + '{}" CACHE INTERNAL "GENERATED_LIBS")'.format(self.target_name)) + ret.append('endif()') + ret.append("add_library(" + self.target_name) for f in self.source_list: ret.append(" " + f) diff --git a/cmake/kaldi.pc.in b/cmake/kaldi.pc.in new file mode 100644 index 00000000000..ad3a98e7f6f --- /dev/null +++ b/cmake/kaldi.pc.in @@ -0,0 +1,9 @@ +prefix=@DEST_DIR@ +libdir=${prefix}/lib +includedir=${prefix}/include + +Name: kaldi +Description: Kaldi Speech Recognition Toolkit +Version:@VERSION@ +Libs: -L${libdir} -lfst @PRIVATE_LIBS@ +Cflags: -I${includedir}/kaldi -I${includedir}/openfst diff --git a/install.bash b/install.bash new file mode 100755 index 00000000000..5094677e242 --- /dev/null +++ b/install.bash @@ -0,0 +1,344 @@ +#!/usr/bin/env bash +# +# Install script for Linux based Speech Recognition System +# +# Arpit Aggarwal +# 2018 TU Eindhoven + +# Usage Document +usage() +{ + echo "-----------------------------------------------------------------------------" + echo -e "\e[35m\e[1m Kaldi Automatic Speech Recognition \e[0m" + echo "-----------------------------------------------------------------------------" + echo "Usage: sudo ./install.bash [options] " + echo -e "Options:\n \ + -h | --help\n \ + --tue\n \ + --install-kaldi\n \ + --update-kaldi\n \ + --gst-plugin\n \ + --clean" + echo + echo "-----------------------------------------------------------------------------" +} + +KALDI_REPO="https://github.com/kaldi-asr/kaldi.git" +KALDI="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +ASR_LOG=$KALDI/log + +# Create Log directory +if [ ! -d "$ASR_LOG" ] +then + mkdir $ASR_LOG +fi + +# Install the required packages and dependencies +sudo apt-get update -qq > /dev/null 2>&1 + +# Kaldi install dependencies +_kaldi_install_dependencies() +{ + # Install base packages + sudo apt-get install --assume-yes build-essential git python python-numpy sox swig zip -qq > /dev/null 2>&1 + echo "Checking and installing dependencies..." + # Change exit to return to source check_dependencies and change back once done + sed -i "s|exit|return|g" $KALDI/tools/extras/check_dependencies.sh + source $KALDI/tools/extras/check_dependencies.sh > /dev/null + sed -i "s|return|exit|g" $KALDI/tools/extras/check_dependencies.sh + + # Install dependencies + sudo apt-get install libatlas3-base $debian_packages -qq > /dev/null 2>&1 +} + +# Kaldi check dependencies +_kaldi_check_dependencies() +{ + echo "Checking dependencies..." + $KALDI/tools/extras/check_dependencies.sh > /dev/null +} + +# Kaldi Build (Common to Installation and Update) +_kaldi_build_tools() +{ + # Build toolkit + echo "Building toolkit..." + # Build the tools directory + cd $KALDI/tools + make -j 8 &> $ASR_LOG/make_tools.log + make_tools_status=$( tail -n 1 $ASR_LOG/make_tools.log ) + + if [ "$make_tools_status" != "All done OK." ] + then + echo -e "\e[34m\e[1m Make kaldi/tools failed \e[0m" + return 1 + fi + echo " - Built tools" +} + +_kaldi_build_irstlm() +{ + # Install IRSTLM + # Remove IRSTLM dir if it exists else the install script fails + cd $KALDI/tools + if [ -d "irstlm" ] + then + rm -rf irstlm + fi + extras/install_irstlm.sh &> $ASR_LOG/install_irstlm.log + install_irstlm_status=$(grep "Installation of IRSTLM finished successfully" $ASR_LOG/install_irstlm.log ) + + if [ -z "$install_irstlm_status" ] + then + echo -e "\e[34m\e[1m Install kaldi/tools/extras/install_irstlm.sh failed \e[0m" + return 1 + fi + echo " - Built IRSTLM" +} + +_kaldi_build_sequitur() +{ + # Install Sequitur + cd $KALDI/tools + extras/install_sequitur.sh &> $ASR_LOG/install_sequitur.log + install_sequitur_status=$(grep "Installation of SEQUITUR finished successfully" $ASR_LOG/install_sequitur.log) + + if [ -z "$install_sequitur_status" ] + then + echo -e "\e[34m\e[1m Install kaldi/tools/extras/install_sequitur.sh failed \e[0m" + return 1 + fi + echo " - Built SEQUITUR" +} + +_kaldi_build_srilm() +{ + # Install SRILM + cd $KALDI/tools + # Download SRILM if .tgz does not exist + if [ ! -f "srilm.tgz" ] + then + wget -q https://github.com/tue-robotics/kaldi_srilm/blob/master/srilm.tgz?raw=true -O srilm.tgz + fi + extras/install_srilm.sh &> $ASR_LOG/install_srilm.log + install_srilm_status=$(grep "Installation of SRILM finished successfully" $ASR_LOG/install_srilm.log) + + if [ -z "$install_srilm_status" ] + then + echo -e "\e[34m\e[1m Install kaldi/tools/extras/install_srilm.sh failed \e[0m" + return 1 + fi + echo " - Built SRILM" +} + +_kaldi_build_src_cmake() +{ + # Build src using CMake + cd $KALDI + + # Remove existing STATUS file from previous build + if [ -f STATUS ] + then + rm STATUS + fi + + # Remove existing build directory + if [ -d build ] + then + rm -rf build + fi + + mkdir build + cd build + cmake -GNinja -DCMAKE_INSTALL_PREFIX=../dist -DKALDI_BUILD_EXE=OFF -DKALDI_BUILD_TEST=OFF -DBUILD_SHARED_LIBS=ON .. + cmake --build . --target install || { echo "CMake build failed" && return 1; } + + # Create a STATUS file to monitor installation + cd $KALDI + echo "ALL OK" > STATUS +} + +_kaldi_build_src_make() +{ + # Build the src directory + cd $KALDI/src + ./configure --shared &> $ASR_LOG/configure_src.log + configure_src_status=$( grep "SUCCESS" $ASR_LOG/configure_src.log ) + + if [ -z "$configure_src_status" ] + then + echo -e "\e[34m\e[1m Configure kaldi/src failed \e[0m" + return 1 + fi + echo " - Configured src for build" + + # Make Kaldi without checks (ensures faster compilation) + sed -i '/-g # -O0 -DKALDI_PARANOID/c\-O3 -DNDEBUG' kaldi.mk + make depend -j 8 > /dev/null + make -j 8 &> $ASR_LOG/make_src.log + make_src_status=$( grep "Done" $ASR_LOG/make_src.log ) + + if [ -z "$make_src_status" ] + then + echo -e "\e[34m\e[1m Make kaldi/src failed \e[0m" + return 1 + fi + echo " - Built src" +} + +_kaldi_build() +{ + _kaldi_build_tools || return 1 + _kaldi_build_irstlm || return 1 + _kaldi_build_sequitur || return 1 + _kaldi_build_srilm || return 1 + _kaldi_build_src_make || return 1 + + # Create a STATUS file to monitor installation + cd $KALDI + echo "ALL OK" > STATUS +} + +# Kaldi Gstreamer plugin with online decoder build +_kaldi_online_gst() +{ + echo "Building online decoder and gstreamer plugin..." + # Install PortAudio + cd $KALDI/tools + extras/install_portaudio.sh &> $ASR_LOG/install_portaudio.log + install_portaudio_status=$(grep "PortAudio was successfully installed" $ASR_LOG/install_portaudio.log) + + if [ -z "$install_portaudio_status" ] + then + echo -e "\e[34m\e[1m Install kaldi/tools/extras/install_portaudio.sh failed \e[0m" + return 1 + fi + echo " - Installed PortAudio" + + # Build online decoder + cd $KALDI/src/online + make -j 8 &> $ASR_LOG/make_online.log || { echo -e "\e[34m\e[1m Make kaldi/src/online failed \e[0m"; return 1; } + echo " - Built online decoder" + + # Build Gstreamer plugin + cd $KALDI/src/gst-plugin + make depend -j 8 > /dev/null + make -j 8 &> $ASR_LOG/make_gst-plugin.log || { echo -e "\e[34m\e[1m Make kaldi/src/gst-plugin failed \e[0m"; return 1; } + echo " - Built gstreamer plugin" + + # Test Gstreamer plugin + export GST_PLUGIN_PATH=$KALDI/src/gst-plugin${GST_PLUGIN_PATH:+:${GST_PLUGIN_PATH}} + gst-inspect-1.0 onlinegmmdecodefaster > /dev/null || { echo -e "\e[34m\e[1m gst-inspect of onlinegmmdecodefaster failed \e[0m"; return 1; } + echo " - Gstreamer Plugin Test Successful" +} + +# Kaldi Installation +kaldi_install() +{ + echo "Checking for an existing Kaldi-ASR installation in $KALDI" + + if [ ! -d "$KALDI" ] + then + # Clone repository into $KALDI + echo -e "No existing installation found. Cloning from GitHub repository" + git clone $KALDI_REPO $KALDI + _kaldi_install_dependencies + _kaldi_build + else + # Read STATUS file. If not "ALL OK", remove directory $KALDI and re-install Kaldi + kaldi_install_status="$(cat $KALDI/STATUS)" + + if [ "$kaldi_install_status" != "ALL OK" ] + then + sudo rm -rf $KALDI + kaldi_install + fi + fi +} + +# Kaldi Update +kaldi_update() +{ + if [ ! -d "$KALDI" ] + then + # Install Kaldi if directory $KALDI not present + kaldi_install + else + # Read STATUS file. If "ALL OK" then update else remove directory $KALDI + # and re-install Kaldi + kaldi_install_status="$(cat $KALDI/STATUS)" + + if [ "$kaldi_install_status" = "ALL OK" ] + then + # Pull changes from the repository + echo "Updating repository from GitHub" + cd $KALDI + git pull + + # Clean existing make + _kaldi_clean + # Build toolkit + _kaldi_install_dependencies + _kaldi_build + + echo -e "\e[36m\e[1m Kaldi-ASR update complete \e[0m" + else + sudo rm -rf $KALDI + kaldi_install + fi + fi +} + +# Clean the repository +_kaldi_clean() +{ + # Clean existing make + echo -e "\e[36m\e[1m Cleaning existing make \e[0m" + cd $KALDI/tools + make distclean + cd $KALDI/src + make distclean + + # Remove anyother file not a part of the repository + cd $KALDI + git clean -fdx +} + +# Read Postional Parameters +if [ -z "$1" ] +then + usage +else + while [ "$1" != "" ] + do + case $1 in + --install-kaldi ) + kaldi_install + echo -e "\e[36m\e[1m Kaldi installation complete \e[0m" ;; + + --update-kaldi ) + kaldi_update ;; + + --clean ) + _kaldi_clean ;; + + --gst-plugin ) + _kaldi_online_gst ;; + + --tue ) + _kaldi_check_dependencies || exit 1 + _kaldi_build_tools || exit 1 + _kaldi_build_src_cmake || exit 1 + echo -e "\e[36m\e[1m Kaldi installation complete \e[0m" ;; + + -h | --help ) + usage + exit 1 ;; + + * ) + usage + exit 1 ;; + esac + shift + done +fi diff --git a/setup.bash b/setup.bash new file mode 100644 index 00000000000..f842fc16cd7 --- /dev/null +++ b/setup.bash @@ -0,0 +1,20 @@ +#! /usr/bin/env bash +# +# Environment variables to use by speech_recognition repo + +export KALDI_ROOT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +if [[ :$PKG_CONFIG_PATH: != *:$KALDI_ROOT/dist/lib/pkgconfig:* ]] +then + export PKG_CONFIG_PATH=$KALDI_ROOT/dist/lib/pkgconfig${PKG_CONFIG_PATH:+:${PKG_CONFIG_PATH}} +fi + +# [ -f $KALDI_ROOT/tools/env.sh ] && . $KALDI_ROOT/tools/env.sh + +# export PATH=$KALDI_ROOT/egs/wsj/s5/utils/:$KALDI_ROOT/tools/openfst/bin${PATH:+:${PATH}} + +# [ ! -f $KALDI_ROOT/tools/config/common_path.sh ] && echo >&2 "The standard file $KALDI_ROOT/tools/config/common_path.sh is not present -> Exit!" && exit 1 +# . $KALDI_ROOT/tools/config/common_path.sh + +# Make sure that MITLM shared libs are found by the dynamic linker/loader +#export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$(pwd)/tools/mitlm-svn/lib