From 37eb11339c3c742e28d8026f191a4352f8bc392d Mon Sep 17 00:00:00 2001 From: Kamal Galrani Date: Wed, 31 May 2017 10:53:20 +0530 Subject: [PATCH 01/11] Added kaldi as fallback to chrome ASR --- lucida/commandcenter/controllers/Infer.py | 4 ++ lucida/commandcenter/static/js/mob.js | 7 ++- lucida/commandcenter/templates/infer.html | 61 +++++++++++-------- .../kaldi_gstreamer_asr/simple_start.sh | 7 ++- 4 files changed, 50 insertions(+), 29 deletions(-) diff --git a/lucida/commandcenter/controllers/Infer.py b/lucida/commandcenter/controllers/Infer.py index 10f3de895..3ae8cdb80 100644 --- a/lucida/commandcenter/controllers/Infer.py +++ b/lucida/commandcenter/controllers/Infer.py @@ -62,6 +62,10 @@ def generic_infer_route(form, upload_file): @login_required def infer_route(): options = {} + if os.environ.get('ASR_ADDR_PORT'): + options['asr_addr_port'] = os.environ.get('ASR_ADDR_PORT') + else: + options['asr_addr_port'] = 'ws://localhost:' + port_dic["cmd_port"] if request.method == 'POST': options = generic_infer_route(request.form, request.files['file'] if 'file' in request.files else None) return render_template('infer.html', **options) diff --git a/lucida/commandcenter/static/js/mob.js b/lucida/commandcenter/static/js/mob.js index 005e02c0f..5e731b9a0 100644 --- a/lucida/commandcenter/static/js/mob.js +++ b/lucida/commandcenter/static/js/mob.js @@ -82,6 +82,7 @@ var dictate = new Dictate({ onReadyForSpeech : function() { isConnected = true; __message("READY FOR SPEECH"); + document.getElementById('startImg').src = 'static/image/microphone_off.png'; $("#buttonToggleListening").html('Stop'); $("#buttonToggleListening").addClass('highlight'); $("#buttonToggleListening").prop("disabled", false); @@ -99,6 +100,7 @@ var dictate = new Dictate({ }, onEndOfSpeech : function() { __message("END OF SPEECH"); + document.getElementById('startImg').src = 'static/image/microphone.png'; $("#buttonToggleListening").html('Stopping...'); $("#buttonToggleListening").prop("disabled", true); }, @@ -197,11 +199,13 @@ function __updateTranscript(text) { } // Public methods (called from the GUI) -function toggleListening() { +function startButtonFunc() { if (isConnected) { dictate.stopListening(); $("#recbutton").addClass("disabled"); } else { + clearTranscription(); + document.getElementById('startImg').src = 'static/image/microphone.png'; dictate.startListening(); } } @@ -249,3 +253,4 @@ function readURL(input) { $("#file_input").change(function () { readURL(this); }); + diff --git a/lucida/commandcenter/templates/infer.html b/lucida/commandcenter/templates/infer.html index 65f5cdf80..00ffcad7a 100644 --- a/lucida/commandcenter/templates/infer.html +++ b/lucida/commandcenter/templates/infer.html @@ -46,13 +46,18 @@ - + - @@ -69,24 +74,14 @@ @@ -119,17 +114,29 @@

-
-
-
-
-
-
 {% endblock %}
diff --git a/lucida/speechrecognition/kaldi_gstreamer_asr/simple_start.sh b/lucida/speechrecognition/kaldi_gstreamer_asr/simple_start.sh
index 678b34468..15b3c9c52 100755
--- a/lucida/speechrecognition/kaldi_gstreamer_asr/simple_start.sh
+++ b/lucida/speechrecognition/kaldi_gstreamer_asr/simple_start.sh
@@ -1,4 +1,9 @@
 #!/bin/bash
 export GST_PLUGIN_PATH=$(pwd)/kaldi/tools/gst-kaldi-nnet2-online/src
-
+source $(pwd)/../../config.properties
+if [ -z $SECURE_HOST ]; then
+	export ASR_ADDR_PORT="ws://localhost:$CMD_PORT"
+else
+	export ASR_ADDR_PORT="wss://localhost:$CMD_PORT"
+fi
 python kaldigstserver/worker.py -u ${ASR_ADDR_PORT}/worker/ws/speech -c sample_english_nnet2.yaml

From e55ebe67836d2c48cb4554bd2ef253b3e8ba2980 Mon Sep 17 00:00:00 2001
From: Kamal Galrani 
Date: Fri, 2 Jun 2017 21:59:30 +0530
Subject: [PATCH 02/11] Fixes

---
 .../botframework-interface/start_interface.sh | 138 +++++++++---------
 1 file changed, 69 insertions(+), 69 deletions(-)

diff --git a/lucida/botframework-interface/start_interface.sh b/lucida/botframework-interface/start_interface.sh
index 9dbb3e015..026863752 100644
--- a/lucida/botframework-interface/start_interface.sh
+++ b/lucida/botframework-interface/start_interface.sh
@@ -12,13 +12,13 @@ if [ -f 'config.sh' ]; then
   echo "BFW_SKIP_UPDATE=\"$BFW_SKIP_UPDATE\"" >> config.tmp
   echo "BFW_UID=\"$BFW_UID\"" >> config.tmp
   echo "BFW_PWD=\"$BFW_PWD\"" >> config.tmp
-  echo "BFW_SAVE_PWD=$BFW_SAVE_PWD" >> config.tmp
+  echo "BFW_SAVE_PWD=\"$BFW_SAVE_PWD\"" >> config.tmp
   echo "CC_HOST=\"$CC_HOST\"" >> config.tmp
   echo "BFW_HND=\"$BFW_HND\"" >> config.tmp
   echo "BFW_HOST=\"$BFW_HOST\"" >> config.tmp
   echo "BFW_PORT=\"$BFW_PORT\"" >> config.tmp
-  echo "BFW_APPID=$BFW_APPID" >> config.tmp
-  echo "BFW_APPPWD=$BFW_APPPWD" >> config.tmp
+  echo "BFW_APPID=\"$BFW_APPID\"" >> config.tmp
+  echo "BFW_APPPWD=\"$BFW_APPPWD\"" >> config.tmp
 else
   echo "You'll need to answer a few questions for first time setup. To change any of these options see config.sh. To reset delete config.sh"
   echo "REMEMBER TO BACK UP YOUR APP PASSWORD BEFORE DELETING 'config.sh'"
@@ -28,21 +28,21 @@ fi
 BFW_UPDATE_ENDPOINT=0
 ASK_QUESTIONS=1
 USE_NGROK=0
-while [ $ASK_QUESTIONS -eq 1 ]; do
+while [ "$ASK_QUESTIONS" -eq 1 ]; do
   ASK_QUESTIONS=0
   echo "#" > config.sh
   echo "# Configuration file for Lucida's BotFramework interface" >> config.sh
   echo "#" >> config.sh
 
-  if [ -z $BFW_SKIP_UPDATE ]; then
+  if [ -z "$BFW_SKIP_UPDATE" ]; then
     echo ""
     echo "By default this script updates messaging endpoint automatically as and when required. You can also set endpoint manually as explained in README"
     echo "This feature is experimental and requires your Microsoft account password"
     echo "Do you want to skip automatic update of endpoint? (y/n)"
     printf "BFW_SKIP_UPDATE [n]: "
     read response
-    if [ -z $respone ]; then response="n"; fi
-    if [[ $response != "n" ]] && [[ $response != "N" ]]; then
+    if [ -z "$respone" ]; then response="n"; fi
+    if [[ "$response" != "n" ]] && [[ "$response" != "N" ]]; then
       BFW_SKIP_UPDATE=1
       BFW_UID=
       BFW_PWD=
@@ -54,7 +54,7 @@ while [ $ASK_QUESTIONS -eq 1 ]; do
     fi
   fi
 
-  if [ -z $BFW_UID ] && [ $BFW_SKIP_UPDATE -eq 0 ]; then
+  if [ -z "$BFW_UID" ] && [ "$BFW_SKIP_UPDATE" -eq 0 ]; then
     BFW_PWD=
     BFW_SAVE_PWD=
     while [ 1 ]; do
@@ -62,8 +62,8 @@ while [ $ASK_QUESTIONS -eq 1 ]; do
       echo "Enter the email address associated with your Microsoft account. If you don't have an account create one at 'https://signup.live.com/'"
       printf "BFW_UID: "
       read BFW_UID
-      echo $BFW_UID | grep -Poe "^[A-Za-z0-9_\.]+@[A-Za-z0-9\-_]+\.[A-Za-z0-9\.\-_]+$" > /dev/null
-      if [ $? -ne 0 ]; then
+      echo "$BFW_UID" | grep -Poe "^[A-Za-z0-9_\.]+@[A-Za-z0-9\-_]+\.[A-Za-z0-9\.\-_]+$" > /dev/null
+      if [ "$?" -ne 0 ]; then
         echo "[ERROR] Please provide a valid email address!!!"
         continue
       fi
@@ -74,8 +74,8 @@ while [ $ASK_QUESTIONS -eq 1 ]; do
       read BFW_PWD
       stty echo
       echo ""
-      echo $BFW_PWD | grep -Poe "^[A-Za-z0-9~\!@#\$%\^&*()\-=_+{}\|\[\];:'<>?,\./]{8,16}$" > /dev/null
-      if [ $? -eq 1 ]; then
+      echo "$BFW_PWD" | grep -Poe "^[A-Za-z0-9~\!@#\$%\^&*()\-=_+{}\|\[\];:'<>?,\./]{8,16}$" > /dev/null
+      if [ "$?" -eq 1 ]; then
         echo "[ERROR] Please enter a valid password!!!"
         continue
       fi
@@ -89,7 +89,7 @@ while [ $ASK_QUESTIONS -eq 1 ]; do
   echo "# Microsoft account email address" >> config.sh
   echo "BFW_UID=\"$BFW_UID\"" >> config.sh
 
-  if [ -z $BFW_PWD ] && [ ! -z $BFW_UID ]; then
+  if [ -z "$BFW_PWD" ] && [ ! -z "$BFW_UID" ]; then
     while [ 1 ]; do
       echo ""
       echo "Enter your Microsoft account password. Passwords with exclaimation marks (!), double quotes (\") and backticks (\`) are not supported"
@@ -98,8 +98,8 @@ while [ $ASK_QUESTIONS -eq 1 ]; do
       read BFW_PWD
       stty echo
       echo ""
-      echo $BFW_PWD | grep -Poe "^[A-Za-z0-9~\!@#\$%\^&*()\-=_+{}\|\[\];:'<>?,\./]{8,16}$" > /dev/null
-      if [ $? -eq 1 ]; then
+      echo "$BFW_PWD" | grep -Poe "^[A-Za-z0-9~\!@#\$%\^&*()\-=_+{}\|\[\];:'<>?,\./]{8,16}$" > /dev/null
+      if [ "$?" -eq 1 ]; then
         echo "[ERROR] Please enter a valid password!!!"
       else
         break
@@ -107,15 +107,15 @@ while [ $ASK_QUESTIONS -eq 1 ]; do
     done
   fi
 
-  if [ -z $BFW_SAVE_PWD ]; then
-    if [ -z $BFW_PWD ]; then
+  if [ -z "$BFW_SAVE_PWD" ]; then
+    if [ -z "$BFW_PWD" ]; then
       BFW_SAVE_PWD=0
     else
       echo ""
       echo "Do you want me to save password to file? It will be saved in plain text. (y/n)"
       printf "BFW_SAVE_PWD [n]: "
       read BFW_SAVE_PWD
-      if [ -z $BFW_SAVE_PWD ] || [[ $BFW_SAVE_PWD == "n" ]] || [[ $BFW_SAVE_PWD == "N" ]] || [[ $BFW_SAVE_PWD == "No" ]] || [[ $BFW_SAVE_PWD == "no" ]] || [[ $BFW_SAVE_PWD == "false" ]] || [[ $BFW_SAVE_PWD == "False" ]]; then
+      if [ -z "$BFW_SAVE_PWD" ] || [[ "$BFW_SAVE_PWD" == "n" ]] || [[ "$BFW_SAVE_PWD" == "N" ]]; then
         BFW_SAVE_PWD=0
       else
         BFW_SAVE_PWD=1
@@ -124,29 +124,29 @@ while [ $ASK_QUESTIONS -eq 1 ]; do
   fi
   echo "" >> config.sh
   echo "# Microsoft account password" >> config.sh
-  if [ $BFW_SAVE_PWD -eq 1 ]; then
+  if [ "$BFW_SAVE_PWD" -eq 1 ]; then
     echo "BFW_PWD=\"$BFW_PWD\"" >> config.sh
   else
   echo "BFW_PWD=" >> config.sh
   fi
   echo "" >> config.sh
   echo "# Do we save Microsoft account password? (0/1)" >> config.sh
-  echo "BFW_SAVE_PWD=$BFW_SAVE_PWD" >> config.sh
+  echo "BFW_SAVE_PWD=\"$BFW_SAVE_PWD\"" >> config.sh
 
-  if [ -z $CC_HOST ]; then
+  if [ -z "$CC_HOST" ]; then
     while [ 1 ]; do
       echo ""
       echo "Enter the host:port on which command center is running (e.g. 'http://localhost:3000'). URLs with exclaimation marks ('!') are not allowed."
       echo "If you have no idea what this is you may use default"
       printf "CC_HOST [http://localhost:3000]: "
       read CC_HOST
-      if [ -z $CC_HOST ]; then CC_HOST="http://localhost:3000"; fi
-      echo $CC_HOST | grep -Poe "^(https?://)?[A-Za-z0-9\-\._~:/\?#\[\]'@\$&()*+,;=%]+$" > /dev/null
-      if [ $? -eq 1 ]; then
+      if [ -z "$CC_HOST" ]; then CC_HOST="http://localhost:3000"; fi
+      echo "$CC_HOST" | grep -Poe "^(https?://)?[A-Za-z0-9\-\._~:/\?#\[\]'@\$&()*+,;=%]+$" > /dev/null
+      if [ "$?" -eq 1 ]; then
         echo "[ERROR] Please enter a valid host!!!"
       else
-        echo $CC_HOST | grep -Poe "^https?://" > /dev/null
-        if [ $? -eq 1 ]; then
+        echo "$CC_HOST" | grep -Poe "^https?://" > /dev/null
+        if [ "$?" -eq 1 ]; then
           CC_HOST=`echo http://$CC_HOST`
         fi
         break
@@ -157,14 +157,14 @@ while [ $ASK_QUESTIONS -eq 1 ]; do
   echo "# Command center URL" >> config.sh
   echo "CC_HOST=\"$CC_HOST\"" >> config.sh
 
-  if [ -z $BFW_HND ] && [ $BFW_SKIP_UPDATE -eq 0 ]; then
+  if [ -z "$BFW_HND" ] && [ "$BFW_SKIP_UPDATE" -eq 0 ]; then
     while [ 1 ]; do
       echo ""
       echo "Enter the handle of the bot you plan to use with Lucida. If you haven't created a bot do so at 'https://dev.botframework.com/bots/new'"
       printf "BFW_HND: "
       read BFW_HND
-      echo $BFW_HND | grep -Poe "^[A-Za-z0-9\-_]{3,16}$" > /dev/null
-      if [ $? -ne 0 ]; then
+      echo "$BFW_HND" | grep -Poe "^[A-Za-z0-9\-_]{3,16}$" > /dev/null
+      if [ "$?" -ne 0 ]; then
         echo "[ERROR] Please enter a valid bot handle!!!"
       else
         break
@@ -175,17 +175,17 @@ while [ $ASK_QUESTIONS -eq 1 ]; do
   echo "# BotFramework bot handle" >> config.sh
   echo "BFW_HND=\"$BFW_HND\"" >> config.sh
 
-  if [ $USE_NGROK -eq 1 ]; then BFW_HOST="https://xxx.ngrok.io"; fi
-  if [ -z $BFW_HOST ] && [ $BFW_SKIP_UPDATE -eq 0 ]; then
+  if [ "$USE_NGROK" -eq 1 ]; then BFW_HOST="https://xxx.ngrok.io"; fi
+  if [ -z "$BFW_HOST" ] && [ "$BFW_SKIP_UPDATE" -eq 0 ]; then
     while [ 1 ]; do
       echo ""
       echo "Enter messaging endpoint (https only) on which Lucida's BotFramework interface is running (e.g. 'https://xxx.ngrok.io'). URLs with exclaimation marks ('!') are not allowed."
       echo "If you have no idea what this is just press enter. Doing so will require you to enter your account password everytime you launch BotFramework interface or save it to config.sh"
       printf "BFW_HOST [https://xxx.ngrok.io]: "
       read BFW_HOST
-      if [ -z $BFW_HOST ]; then BFW_HOST="https://xxx.ngrok.io"; USE_NGROK=1; fi
-      echo $BFW_HOST | grep -Poe "^https://[A-Za-z0-9\-\._~:/\?#\[\]'@\$&()*+,;=%]+$" > /dev/null
-      if [ $? -eq 1 ]; then
+      if [ -z "$BFW_HOST" ]; then BFW_HOST="https://xxx.ngrok.io"; USE_NGROK=1; fi
+      echo "$BFW_HOST" | grep -Poe "^https://[A-Za-z0-9\-\._~:/\?#\[\]'@\$&()*+,;=%]+$" > /dev/null
+      if [ "$?" -eq 1 ]; then
         echo "[ERROR] Please enter a valid host!!!"
       else
         break
@@ -205,15 +205,15 @@ while [ $ASK_QUESTIONS -eq 1 ]; do
   echo "# BotFramework bot endpoint" >> config.sh
   echo "BFW_HOST=\"$BFW_HOST\"" >> config.sh
 
-  if [ -z $BFW_PORT ]; then
+  if [ -z "$BFW_PORT" ]; then
     while [ 1 ]; do
       echo ""
       echo "Enter the port on which Lucida BotFramework interface should run."
       printf "BFW_PORT [3728]: "
       read BFW_PORT
-      if [ -z $BFW_PORT ]; then BFW_PORT=3728; fi
-      echo $BFW_PORT | grep -Poe "^\d{2,5}$" > /dev/null
-      if [ $? -eq 1 ]; then
+      if [ -z "$BFW_PORT" ]; then BFW_PORT=3728; fi
+      echo "$BFW_PORT" | grep -Poe "^\d{2,5}$" > /dev/null
+      if [ "$?" -eq 1 ]; then
         echo "[ERROR] Please enter a valid port!!!"
       else
         break
@@ -222,23 +222,23 @@ while [ $ASK_QUESTIONS -eq 1 ]; do
   fi
   echo "" >> config.sh
   echo "# BotFramework listen port" >> config.sh
-  echo "BFW_PORT=$BFW_PORT" >> config.sh
+  echo "BFW_PORT=\"$BFW_PORT\"" >> config.sh
 
-  if [ -z $BFW_APPID ] || [ -z $BFW_APPPWD ]; then
+  if [ -z "$BFW_APPID" ] || [ -z "$BFW_APPPWD" ]; then
     while [ 1 ]; do
       echo ""
       echo "Enter Microsoft application ID and password. (View README)"
       printf "BFW_APPID: "
       read BFW_APPID
-      echo $BFW_APPID | grep -Poe "^[A-Za-z0-9\-]+$" > /dev/null
-      if [ $? -eq 1 ]; then
+      echo "$BFW_APPID" | grep -Poe "^[A-Za-z0-9\-]+$" > /dev/null
+      if [ "$?" -eq 1 ]; then
         echo "[ERROR] Please enter a valid application ID!!!"
         continue
       fi
       printf "BFW_APPPWD: "
       read BFW_APPPWD
-      echo $BFW_APPPWD | grep -Poe "^[A-Za-z0-9]+$" > /dev/null
-      if [ $? -eq 1 ]; then
+      echo "$BFW_APPPWD" | grep -Poe "^[A-Za-z0-9]+$" > /dev/null
+      if [ "$?" -eq 1 ]; then
         echo "[ERROR] Please enter a valid application password!!!"
       else
         break
@@ -250,32 +250,32 @@ while [ $ASK_QUESTIONS -eq 1 ]; do
   echo "BFW_APPID=\"$BFW_APPID\"" >> config.sh
   echo "BFW_APPPWD=\"$BFW_APPPWD\"" >> config.sh
 
-  if [[ "$BFW_HOST" == "https://xxx.ngrok.io" ]] && [ $BFW_SKIP_UPDATE -eq 0 ]; then
+  if [[ "$BFW_HOST" == "https://xxx.ngrok.io" ]] && [ "$BFW_SKIP_UPDATE" -eq 0 ]; then
     USE_NGROK=1
     BFW_HOST=
-    ps -ef | grep ngrok | grep http | grep $BFW_PORT > /dev/null
-    if [ $? -eq 1 ]; then
-      ngrok http $BFW_PORT > /dev/null & disown
+    ps -ef | grep ngrok | grep http | grep "$BFW_PORT" > /dev/null
+    if [ "$?" -eq 1 ]; then
+      ngrok http "$BFW_PORT" > /dev/null & disown
       echo ""
       echo "[INFO] Waiting for ngrok to go online..."
       sleep 10
-      ps -ef | grep ngrok | grep http | grep $BFW_PORT > /dev/null
-      if [ $? -eq 1 ]; then
+      ps -ef | grep ngrok | grep http | grep "$BFW_PORT" > /dev/null
+      if [ "$?" -eq 1 ]; then
         echo "[ERROR] Could not start ngrok client!!! Please fix the issue"
         exit 1
       fi
     fi
     while read line; do
-      ngrok_pid=`echo $line | grep -Poe "\d+(?=/ngrok)"`
-      ngrok_port=`echo $line | grep -Poe "(?<=127.0.0.1:)\d+(?=[^\d])"`
-      if [ ! -z $ngrok_pid ] && [ ! -z $ngrok_port ]; then
-        ps -ef | grep $ngrok_pid | grep $BFW_PORT > /dev/null
-        if [ $? -eq 0 ]; then
-          BFW_HOST=`curl -s localhost:$ngrok_port/inspect/http | grep $BFW_PORT | grep -Poe "https://.*?ngrok.io"`
+      ngrok_pid=`echo "$line" | grep -Poe "\d+(?=/ngrok)"`
+      ngrok_port=`echo "$line" | grep -Poe "(?<=127.0.0.1:)\d+(?=[^\d])"`
+      if [ ! -z "$ngrok_pid" ] && [ ! -z "$ngrok_port" ]; then
+        ps -ef | grep "$ngrok_pid" | grep "$BFW_PORT" > /dev/null
+        if [ "$?" -eq 0 ]; then
+          BFW_HOST=`curl -s "localhost:$ngrok_port/inspect/http" | grep "$BFW_PORT" | grep -Poe "https://.*?ngrok.io"`
         fi
       fi
     done < <(netstat -peanut 2>/dev/null | grep LISTEN)
-    if [ -z $BFW_HOST ]; then
+    if [ -z "$BFW_HOST" ]; then
       echo ""
       echo "[ERROR] Could not connect to ngrok!!! Are you connected to the internet?"
       exit 1
@@ -283,7 +283,7 @@ while [ $ASK_QUESTIONS -eq 1 ]; do
     BFW_UPDATE_ENDPOINT=1
   fi
 
-  if [ $BFW_UPDATE_ENDPOINT -eq 1 ] && [ $BFW_SKIP_UPDATE -eq 0 ]; then
+  if [ "$BFW_UPDATE_ENDPOINT" -eq 1 ] && [ "$BFW_SKIP_UPDATE" -eq 0 ]; then
     echo ""
     echo "[INFO] Updating endpoint..."
     counter=0
@@ -294,22 +294,22 @@ while [ $ASK_QUESTIONS -eq 1 ]; do
       export BFW_HND
       phantomjs set_endpoint.js | tee phantom.out
       grep phantom.out -e "Successfully updated bot endpoint" > /dev/null
-      if [ $? -eq 0 ]; then
-        echo $BFW_HOST > "last_pushed_host"
+      if [ "$?" -eq 0 ]; then
+        echo "$BFW_HOST" > "last_pushed_host"
         break
       fi
       grep phantom.out -e "Microsoft needs additional information to sign you in" > /dev/null
-      if [ $? -eq 0 ]; then
+      if [ "$?" -eq 0 ]; then
         exit 1
       fi
       grep phantom.out -e "Only https addresses are allowed as endpoints" > /dev/null
-      if [ $? -eq 0 ]; then
+      if [ "$?" -eq 0 ]; then
         BFW_HOST=
         ASK_QUESTIONS=1
         break
       fi
       grep phantom.out -e "Your account or password is incorrect" > /dev/null
-      if [ $? -eq 0 ]; then
+      if [ "$?" -eq 0 ]; then
         BFW_UID=
         BFW_PWD=
         BFW_SAVE_PWD=
@@ -317,20 +317,20 @@ while [ $ASK_QUESTIONS -eq 1 ]; do
         break
       fi
       grep phantom.out -e "No bot with handle" > /dev/null
-      if [ $? -eq 0 ]; then
+      if [ "$?" -eq 0 ]; then
         BFW_HND=
         ASK_QUESTIONS=1
         break
       fi
       grep phantom.out -e "Will try again in a second" > /dev/null
-      if [ $? -eq 0 ]; then
+      if [ "$?" -eq 0 ]; then
         counter=$(($counter+1))
-        if [ $counter -gt 1 ]; then
+        if [ "$counter" -gt 1 ]; then
           echo ""
           echo "Seems like connection to Microsoft is repeatedly failing!!!"
           printf "Do you want to skip automatic update of endpoint? This will require you to update endpoint manually as explained in README (y/n) "
           read response
-          if [[ $response == "y" ]] || [[ $response == "Y" ]]; then
+          if [[ "$response" == "y" ]] || [[ "$response" == "Y" ]]; then
             BFW_SKIP_UPDATE=1
             sed s/BFW_SKIP_UPDATE=.*/BFW_SKIP_UPDATE=1/ -i config.sh
             sed s/BFW_UID=.*/BFW_UID=/ -i config.sh
@@ -350,7 +350,7 @@ while [ $ASK_QUESTIONS -eq 1 ]; do
   fi
 done
 
-if [ $BFW_SKIP_UPDATE -eq 1 ]; then
+if [ "$BFW_SKIP_UPDATE" -eq 1 ]; then
   rm -f "last_pushed_host"
 fi
 rm -f config.tmp
@@ -364,4 +364,4 @@ exports.credentials = {
 }
 EOF
 
-node interface.js $BFW_PORT $CC_HOST
+node interface.js "$BFW_PORT" "$CC_HOST"

From 9624be67907fc2c3584ff3f29dd6fd648a71eefa Mon Sep 17 00:00:00 2001
From: Kamal Galrani 
Date: Wed, 7 Jun 2017 17:15:34 +0530
Subject: [PATCH 03/11] Merged Flask and Tornado into a single port

---
 lucida/commandcenter/app.py                   | 65 ++++--------------
 lucida/commandcenter/controllers/FlaskApp.py  | 33 ++++++++++
 .../{WebSocket.py => WebServer.py}            | 66 ++-----------------
 lucida/commandcenter/controllers/__init__.py  |  4 +-
 4 files changed, 53 insertions(+), 115 deletions(-)
 create mode 100644 lucida/commandcenter/controllers/FlaskApp.py
 rename lucida/commandcenter/controllers/{WebSocket.py => WebServer.py} (82%)

diff --git a/lucida/commandcenter/app.py b/lucida/commandcenter/app.py
index 92d8f91df..d3111bbb7 100644
--- a/lucida/commandcenter/app.py
+++ b/lucida/commandcenter/app.py
@@ -2,66 +2,27 @@
 from __future__ import division
 from __future__ import unicode_literals
 
-import sys, glob, os
-sys.path.insert(0, glob.glob(os.path.abspath(os.path.dirname(__file__)) +
-    '/../../tools/thrift-0.9.3/lib/py/build/lib*')[0])
-
-from controllers import *
+from controllers.FlaskApp import app
+from controllers import WebServer
 from controllers.Parser import cmd_port
-from flask import *
-from threading import Thread
 import logging
+import os
 
+def main():
+    cmd_host = '0.0.0.0'
+    logging.basicConfig(level=logging.DEBUG, format="%(levelname)8s %(asctime)s %(message)s ")
+    WebServer.tornado.options.parse_command_line()
 
-# Initialize the Flask app with the template folder address.
-app = Flask(__name__, template_folder='templates')
-
-# app.config.from_object('config')
-app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024 # 16 MB due to MongoDB
-
-# Register the controllers.
-app.register_blueprint(Main.main)
-app.register_blueprint(User.user)
-app.register_blueprint(Create.create)
-app.register_blueprint(Learn.learn)
-app.register_blueprint(Infer.infer)
-
-# Session.
-app.secret_key = 'A0Zr98j/3yX R~XHH!jmN]LWX/,?RT'
-
-def flask_listener():
-
-    # For https (with ASR capability)
-    if os.environ.get('SECURE_HOST'):
-        print 'Starting secure flask'
-        app.run(host='0.0.0.0', port=3000, debug=True, use_reloader=False,
-                threaded=True, ssl_context=('certs/server.crt', 'certs/server.key'))
-    # For http (without ASR capability)
-    else:
-        print 'Starting non-secure flask'
-        app.run(host='0.0.0.0', port=3000, debug=True, use_reloader=False,
-                threaded=True)
-
-def web_socket_listener():
-    print 'Start web socket at ' + str(cmd_port)
-    logging.basicConfig(level=logging.DEBUG,
-            format="%(levelname)8s %(asctime)s %(message)s ")
-    logging.debug('Starting up server')
-    WebSocket.tornado.options.parse_command_line()
-
-    # For wss (with ASR capability)
     if os.environ.get('SECURE_HOST'):
-        print 'Starting secure web socket'
-        WebSocket.Application().listen(cmd_port, ssl_options={
+        logging.info('Spinning up web server at https://' + str(cmd_host)  + ':' + str(cmd_port))
+        WebServer.Application(app).listen(cmd_port, address=str(cmd_host), ssl_options={
             "certfile":"certs/server.crt",
             "keyfile":"certs/server.key"})
-    # For ws (without ASR capability)
     else:
-        print 'Starting non-secure web socket'
-        WebSocket.Application().listen(cmd_port)
+        logging.info('Spinning up web server at http://' + str(cmd_host)  + ':' + str(cmd_port))
+        WebServer.Application(app).listen(cmd_port, address=str(cmd_host))
 
-    WebSocket.tornado.ioloop.IOLoop.instance().start()
+    WebServer.tornado.ioloop.IOLoop.instance().start()
 
 if __name__ == '__main__':
-    Thread(target = flask_listener).start()
-    web_socket_listener()
+    main()
diff --git a/lucida/commandcenter/controllers/FlaskApp.py b/lucida/commandcenter/controllers/FlaskApp.py
new file mode 100644
index 000000000..05554ae85
--- /dev/null
+++ b/lucida/commandcenter/controllers/FlaskApp.py
@@ -0,0 +1,33 @@
+from __future__ import absolute_import
+from __future__ import division
+from __future__ import unicode_literals
+
+import sys, glob, os
+sys.path.insert(0, glob.glob(os.path.abspath(os.path.dirname(__file__)) +
+    '/../../../tools/thrift-0.9.3/lib/py/build/lib*')[0])
+
+from . import Main
+from . import User
+from . import Create
+from . import Learn
+from . import Infer
+from .Parser import cmd_port
+from flask import *
+import logging
+
+
+# Initialize the Flask app with the template folder address.
+app = Flask(__name__, template_folder='../templates')
+
+# app.config.from_object('config')
+app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024 # 16 MB due to MongoDB
+
+# Register the controllers.
+app.register_blueprint(Main.main)
+app.register_blueprint(User.user)
+app.register_blueprint(Create.create)
+app.register_blueprint(Learn.learn)
+app.register_blueprint(Infer.infer)
+
+# Session.
+app.secret_key = 'A0Zr98j/3yX R~XHH!jmN]LWX/,?RT'
diff --git a/lucida/commandcenter/controllers/WebSocket.py b/lucida/commandcenter/controllers/WebServer.py
similarity index 82%
rename from lucida/commandcenter/controllers/WebSocket.py
rename to lucida/commandcenter/controllers/WebServer.py
index 5c6c77398..37983c7f1 100644
--- a/lucida/commandcenter/controllers/WebSocket.py
+++ b/lucida/commandcenter/controllers/WebServer.py
@@ -23,6 +23,7 @@
 import tornado.websocket
 import tornado.gen
 import tornado.concurrent
+import tornado.wsgi
 
 from Parser import cmd_port
 
@@ -43,23 +44,22 @@
 
 
 class Application(tornado.web.Application):
-	def __init__(self):
+	def __init__(self, flaskApp):
 		settings = dict(
 			cookie_secret="43oETzKXQAGaYdkL5gEmGeJJFuYh7EQnp2XdTP1o/Vo=",
-			template_path=os.path.join(os.path.dirname(os.path.dirname(__file__)), "templates"),
 			static_path=os.path.join(os.path.dirname(os.path.dirname(__file__)), "static"),
 			xsrf_cookies=False,
-			autoescape=None,
+			autoescape=None
 		)
 
+		flaskWebHandler = tornado.wsgi.WSGIContainer(flaskApp)
 		handlers = [
-			(r"/", MainHandler),
 			(r"/client/ws/speech", DecoderSocketHandler),
 			(r"/client/ws/status", StatusSocketHandler),
-			(r"/client/dynamic/reference", ReferenceHandler),
 			(r"/client/dynamic/recognize", HttpChunkedRecognizeHandler),
 			(r"/worker/ws/speech", WorkerSocketHandler),
 			(r"/client/static/(.*)", tornado.web.StaticFileHandler, {'path': settings["static_path"]}),
+			(r".*", tornado.web.FallbackHandler, dict(fallback=flaskWebHandler))
 		]
 		tornado.web.Application.__init__(self, handlers, **settings)
 		self.available_workers = set()
@@ -74,26 +74,6 @@ def send_status_update(self):
 		for ws in self.status_listeners:
 			self.send_status_update_single(ws)
 
-	def save_reference(self, content_id, content):
-		refs = {}
-		try:
-			with open("reference-content.json") as f:
-				refs = json.load(f)
-		except:
-			pass
-		refs[content_id] = content
-		with open("reference-content.json", "w") as f:
-			json.dump(refs, f, indent=2)
-
-
-class MainHandler(tornado.web.RequestHandler):
-	def get(self):
-		current_directory = os.path.dirname(os.path.abspath(__file__))
-		parent_directory = os.path.join(current_directory, os.pardir)
-		readme = os.path.join(parent_directory, "README.md")
-		self.render(readme)
-
-
 def run_async(func):
 	@functools.wraps(func)
 	def async_func(*args, **kwargs):
@@ -216,27 +196,6 @@ def close(self):
 		self.final_result_queue.put(self.final_hyp)
 
 
-class ReferenceHandler(tornado.web.RequestHandler):
-	def post(self, *args, **kwargs):
-		content_id = self.request.headers.get("Content-Id")
-		if content_id:
-			content = codecs.decode(self.request.body, "utf-8")
-			user_id = self.request.headers.get("User-Id", "")
-			self.application.save_reference(content_id, dict(content=content, user_id=user_id, time=time.strftime("%Y-%m-%dT%H:%M:%S")))
-			logging.info("Received reference text for content %s and user %s" % (content_id, user_id))
-			self.set_header('Access-Control-Allow-Origin', '*')
-		else:
-			self.set_status(400)
-			self.finish("No Content-Id specified")
-
-	def options(self, *args, **kwargs):
-		self.set_header('Access-Control-Allow-Origin', '*')
-		self.set_header('Access-Control-Allow-Methods', 'POST, OPTIONS')
-		self.set_header('Access-Control-Max-Age', 1000)
-		# note that '*' is not valid for Access-Control-Allow-Headers
-		self.set_header('Access-Control-Allow-Headers',  'origin, x-csrftoken, content-type, accept, User-Id, Content-Id')
-
-
 class StatusSocketHandler(tornado.websocket.WebSocketHandler):
 	# needed for Tornado 4.0
 	def check_origin(self, origin):
@@ -339,18 +298,3 @@ def on_message(self, message):
 			self.worker.write_message(message, binary=False)
 		else:
 			self.worker.write_message(message, binary=True)
-
-
-def main():
-	logging.basicConfig(level=logging.DEBUG, format="%(levelname)8s %(asctime)s %(message)s ")
-	logging.debug('Starting up server')
-	from tornado.options import options
-
-	tornado.options.parse_command_line()
-	app = Application()
-	app.listen(3000)
-	tornado.ioloop.IOLoop.instance().start()
-
-
-if __name__ == "__main__":
-	main()
diff --git a/lucida/commandcenter/controllers/__init__.py b/lucida/commandcenter/controllers/__init__.py
index fd97c3acd..42411012e 100644
--- a/lucida/commandcenter/controllers/__init__.py
+++ b/lucida/commandcenter/controllers/__init__.py
@@ -1,3 +1,3 @@
-__all__ = ['Main', 'AccessManagement', 'WebSocket', 'Service', 'Graph',
+__all__ = ['Main', 'AccessManagement', 'WebServer', 'Service', 'Graph',
            'ThriftClient', 'Create', 'Learn', 'Infer', 'Parser',
-           'QueryClassifier', 'Config', 'User', 'Utilities', 'Database', 'Memcached', 'Decision']
+           'QueryClassifier', 'Config', 'User', 'Utilities', 'Database', 'Memcached', 'Decision', 'FlaskApp']

From 638894b3aa4caa781c75c6b8ff5701cb372dc44f Mon Sep 17 00:00:00 2001
From: Kamal Galrani 
Date: Wed, 7 Jun 2017 18:16:12 +0530
Subject: [PATCH 04/11] Minor fixes

---
 lucida/commandcenter/static/js/mob.js | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/lucida/commandcenter/static/js/mob.js b/lucida/commandcenter/static/js/mob.js
index 5e731b9a0..c5c34dc84 100644
--- a/lucida/commandcenter/static/js/mob.js
+++ b/lucida/commandcenter/static/js/mob.js
@@ -107,6 +107,7 @@ var dictate = new Dictate({
 	onEndOfSession : function() {
 		isConnected = false;
 		__message("END OF SESSION");
+		document.getElementById('startImg').src = 'static/image/microphone.png';
 		$("#buttonToggleListening").html('Start');
 		$("#buttonToggleListening").removeClass('highlight');
 		$("#buttonToggleListening").prop("disabled", false);
@@ -168,6 +169,7 @@ var dictate = new Dictate({
 		doPrependSpace = (hypText.length > 0) && !(/\n *$/.test(hypText));
 	},
 	onError : function(code, data) {
+		document.getElementById('startImg').src = 'static/image/microphone.png';
 		dictate.cancel();
 		__error(code, data);
 		// TODO: show error in the GUI

From c8110f4390230a719d29418e70db8e923ee78dc0 Mon Sep 17 00:00:00 2001
From: Kamal Galrani 
Date: Wed, 14 Jun 2017 18:16:05 +0530
Subject: [PATCH 05/11] Basic WIT.AI Speech to Text working

---
 lucida/speechrecognition/wit_stt/Makefile     |   4 +
 lucida/speechrecognition/wit_stt/common.py    |  13 +
 lucida/speechrecognition/wit_stt/decoder.py   | 127 +++++++
 .../wit_stt/logger_config.yaml                |  15 +
 .../speechrecognition/wit_stt/simple_start.sh |   9 +
 lucida/speechrecognition/wit_stt/wit.yaml     |  13 +
 lucida/speechrecognition/wit_stt/worker.py    | 314 ++++++++++++++++++
 7 files changed, 495 insertions(+)
 create mode 100644 lucida/speechrecognition/wit_stt/Makefile
 create mode 100644 lucida/speechrecognition/wit_stt/common.py
 create mode 100644 lucida/speechrecognition/wit_stt/decoder.py
 create mode 100644 lucida/speechrecognition/wit_stt/logger_config.yaml
 create mode 100755 lucida/speechrecognition/wit_stt/simple_start.sh
 create mode 100644 lucida/speechrecognition/wit_stt/wit.yaml
 create mode 100644 lucida/speechrecognition/wit_stt/worker.py

diff --git a/lucida/speechrecognition/wit_stt/Makefile b/lucida/speechrecognition/wit_stt/Makefile
new file mode 100644
index 000000000..757988ef6
--- /dev/null
+++ b/lucida/speechrecognition/wit_stt/Makefile
@@ -0,0 +1,4 @@
+start_server:
+	./simple_start.sh
+
+.PHONY:	start_server
diff --git a/lucida/speechrecognition/wit_stt/common.py b/lucida/speechrecognition/wit_stt/common.py
new file mode 100644
index 000000000..cefd67743
--- /dev/null
+++ b/lucida/speechrecognition/wit_stt/common.py
@@ -0,0 +1,13 @@
+__author__ = 'tanel'
+
+STATUS_EOS = -1
+STATUS_SUCCESS = 0
+STATUS_NO_SPEECH = 1
+STATUS_ABORTED = 2
+STATUS_AUDIO_CAPTURE = 3
+STATUS_NETWORK = 4
+STATUS_NOT_ALLOWED = 5
+STATUS_SERVICE_NOT_ALLOWED = 6
+STATUS_BAD_GRAMMAR = 7
+STATUS_LANGUAGE_NOT_SUPPORTED = 8
+STATUS_NOT_AVAILABLE = 9
\ No newline at end of file
diff --git a/lucida/speechrecognition/wit_stt/decoder.py b/lucida/speechrecognition/wit_stt/decoder.py
new file mode 100644
index 000000000..873d22270
--- /dev/null
+++ b/lucida/speechrecognition/wit_stt/decoder.py
@@ -0,0 +1,127 @@
+"""
+Created on Jun 14 2017
+
+@author: kamal1210
+"""
+import logging
+import threading
+import time
+import os
+import requests
+import json
+
+logger = logging.getLogger(__name__)
+
+API_HOST="https://api.wit.ai/speech"
+
+class DecoderPipeline(object):
+    STATE_CREATED = 0
+    STATE_CONNECTED = 1
+    STATE_INITIALIZED = 2
+    STATE_PROCESSING = 3
+    STATE_EOS_RECEIVED = 7
+    STATE_CANCELLING = 8
+    STATE_FINISHED = 100
+
+    def __init__(self, conf={}):
+        logger.info("Creating decoder using conf: %s" % conf)
+        self.token = conf.get("wit-access-token", "")
+        self.partial_results = conf.get("partial-results", True)
+        self.max_request_rate = conf.get("max-result-rate", 1)
+        self.url = API_HOST + "?v=" + conf.get("wit-api-version", "14/06/2017")
+
+        self.result_handler = None
+        self.full_result_handler = None
+        self.eos_handler = None
+        self.error_handler = None
+        self.request_id = ""
+        self.buffer = []
+        self.lock = threading.Lock()
+        self.state = self.STATE_INITIALIZED
+        logger.info("Initialised decoder pipeline with endpoint: %s" % (self.url))
+
+    def _post_req_gen(self):
+        print str(self.headers)
+        response = requests.post(self.url, headers=self.headers, data=self._post_data_gen())
+        if response.status_code == 200:
+            response_json = json.loads(response.text)
+            result = { 'status': 0, 'total-length': 0.0, 'result': { 'hypotheses': [{ 'likelihood': 100.0, 'confidence': 1.0, 'transcript': response_json['_text']}], 'final': True }, 'segment-length': 0.0, 'segment-start': 0.0 }
+            if self.full_result_handler:
+                self.full_result_handler(json.dumps(result))
+        else:
+            response_json = json.loads(response.text)
+            logger.log(response_json['error'])
+            if self.error_handler:
+                self.error_handler(response_json['error'])
+        if self.eos_handler:
+            self.eos_handler[0](self.eos_handler[1])
+        self.finish_request()
+
+    def _post_data_gen(self):
+        while self.state == self.STATE_CONNECTED:
+            self.lock.acquire()
+            if self.buffer:
+              chunk = self.buffer.pop(0)
+              if chunk != 'EOS':
+                  yield chunk
+                  self.last_chunk_yielded = time.time()
+                  print "Sending over ", len(chunk), " bytes of data"
+              else:
+                  self.state = self.STATE_EOS_RECEIVED
+                  logger.debug("%s: Received EOS!!! Closing POST buffer.." % self.request_id)
+            self.lock.release()
+#            if time.time() - self.last_decoder_message > self.request_timeout:
+#                state = self.STATE_FINISHED
+#                break
+
+    def finish_request(self):
+        logger.info("%s: Resetting decoder state" % self.request_id)
+        self.state = self.STATE_FINISHED
+        self.request_id = ""
+
+    def init_request(self, id, caps_str):
+#	self.user = user-name
+#	self.context = user-context
+#	self.thread_id = thread-id
+#	self.message_id = message-id
+        self.request_id = id
+        logger.info("%s: Initializing request" % (self.request_id))
+	content_type='audio/raw;encoding=signed-integer;bits=16;rate=16000;endian=little'
+	logger.info("%s: Setting content_type to %s" % (self.request_id, content_type))
+	self.headers = {'Authorization': 'Bearer ' + self.token, 'Content-Type': content_type, 'Accept': 'application/json', 'Transfer-Encoding': 'chunked'}
+        self.state = self.STATE_CONNECTED
+	thread = threading.Thread(target=self._post_req_gen)
+        thread.daemon = True
+        thread.start()
+
+    def process_data(self, data):
+        logger.debug('%s: Pushing buffer of size %d to pipeline' % (self.request_id, len(data)))
+        self.lock.acquire()
+        self.buffer.append(data)
+        self.lock.release()
+
+    def end_request(self):
+        logger.info("%s: Pushing EOS to pipeline" % self.request_id)
+        self.lock.acquire()
+        self.buffer.append('EOS')
+        self.lock.release()
+
+    def set_result_handler(self, handler):
+        self.result_handler = handler
+
+    def set_full_result_handler(self, handler):
+        self.full_result_handler = handler
+
+    def set_eos_handler(self, handler, user_data=None):
+        self.eos_handler = (handler, user_data)
+
+    def set_error_handler(self, handler):
+        self.error_handler = handler
+
+
+    def cancel(self):
+        logger.info("%s: Sending EOS to pipeline in order to cancel processing" % self.request_id)
+        if self.eos_handler:
+            self.eos_handler[0](self.eos_handler[1])
+        self.finish_request()
+        logger.info("%s: Cancelled pipeline" % self.request_id)
diff --git a/lucida/speechrecognition/wit_stt/logger_config.yaml b/lucida/speechrecognition/wit_stt/logger_config.yaml
new file mode 100644
index 000000000..e8b7fd2fa
--- /dev/null
+++ b/lucida/speechrecognition/wit_stt/logger_config.yaml
@@ -0,0 +1,15 @@
+version : 1
+disable_existing_loggers: False
+formatters:
+    simpleFormater:
+        format: '%(asctime)s - %(levelname)7s: %(name)10s: %(message)s'
+        datefmt: '%Y-%m-%d %H:%M:%S'
+handlers:
+    console:
+        class: logging.StreamHandler
+        formatter: simpleFormater
+        level: DEBUG
+root:
+    level: DEBUG
+    handlers: [console]
+
diff --git a/lucida/speechrecognition/wit_stt/simple_start.sh b/lucida/speechrecognition/wit_stt/simple_start.sh
new file mode 100755
index 000000000..c3626815c
--- /dev/null
+++ b/lucida/speechrecognition/wit_stt/simple_start.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+source $(pwd)/../../config.properties
+if [ -z $SECURE_HOST ]; then
+	export ASR_ADDR_PORT="ws://localhost:$CMD_PORT"
+else
+	export ASR_ADDR_PORT="wss://localhost:$CMD_PORT"
+fi
+#	export ASR_ADDR_PORT="wss://lucida.homelinuxserver.org:443"
+python worker.py -u ${ASR_ADDR_PORT}/worker/ws/speech -c wit.yaml
diff --git a/lucida/speechrecognition/wit_stt/wit.yaml b/lucida/speechrecognition/wit_stt/wit.yaml
new file mode 100644
index 000000000..ecefeaf75
--- /dev/null
+++ b/lucida/speechrecognition/wit_stt/wit.yaml
@@ -0,0 +1,13 @@
+
+wit-access-token: ''
+wit-api-version:  14/06/201
+
+partial-results:  True
+max-result-rate:  1
+
+silence-timeout:  5
+connect-timeout:  5
+request-timeout:  5
+response-timeout: 5
+
+post-processor: perl -npe 'BEGIN {use IO::Handle; STDOUT->autoflush(1);} s/(.*)/\1./;'
diff --git a/lucida/speechrecognition/wit_stt/worker.py b/lucida/speechrecognition/wit_stt/worker.py
new file mode 100644
index 000000000..b99f2bafb
--- /dev/null
+++ b/lucida/speechrecognition/wit_stt/worker.py
@@ -0,0 +1,314 @@
+__author__ = 'kamal1210'
+
+import logging
+import logging.config
+import time
+import thread
+import argparse
+from subprocess import Popen, PIPE
+from gi.repository import GObject
+import yaml
+import json
+import sys
+import locale
+import codecs
+import zlib
+import base64
+import time
+
+from ws4py.client.threadedclient import WebSocketClient
+import ws4py.messaging
+
+from decoder import DecoderPipeline
+import common
+
+import os
+
+empty_response = ''
+
+logger = logging.getLogger(__name__)
+
+CONNECT_TIMEOUT  = 5
+SILENCE_TIMEOUT  = 5
+REQUEST_TIMEOUT  = 5
+RESPONSE_TIMEOUT = 5
+
+class ServerWebsocket(WebSocketClient):
+	STATE_CREATED = 0
+	STATE_CONNECTED = 1
+	STATE_INITIALIZED = 2
+	STATE_PROCESSING = 3
+	STATE_EOS_RECEIVED = 7
+	STATE_CANCELLING = 8
+	STATE_FINISHED = 100
+
+	def __init__(self, uri, decoder_pipeline, post_processor, full_post_processor=None):
+		self.uri = uri
+		self.decoder_pipeline = decoder_pipeline
+		self.post_processor = post_processor
+		self.full_post_processor = full_post_processor
+		WebSocketClient.__init__(self, url=uri, heartbeat_freq=10)
+		self.pipeline_initialized = False
+		self.partial_transcript = ""
+		self.decoder_pipeline.set_result_handler(self._on_result)
+		self.decoder_pipeline.set_full_result_handler(self._on_full_result)
+		self.decoder_pipeline.set_error_handler(self._on_error)
+		self.decoder_pipeline.set_eos_handler(self._on_eos)
+		self.state = self.STATE_CREATED
+		self.last_decoder_message = time.time()
+		self.request_id = ""
+		self.num_segments = 0
+		self.last_partial_result = ""
+
+	def opened(self):
+		logger.info("Opened websocket connection to server")
+		self.state = self.STATE_CONNECTED
+		self.last_partial_result = ""
+
+	def guard_timeout(self):
+		global REQUEST_TIMEOUT
+		while self.state in [self.STATE_CONNECTED, self.STATE_INITIALIZED, self.STATE_PROCESSING]:
+			if time.time() - self.last_decoder_message > REQUEST_TIMEOUT:
+				logger.warning("%s: More than %d seconds from last decoder hypothesis update, cancelling" % (self.request_id, REQUEST_TIMEOUT))
+				self.finish_request()
+				event = dict(status=common.STATUS_NO_SPEECH)
+				try:
+					self.send(json.dumps(event))
+				except:
+					logger.warning("%s: Failed to send error event to master" % (self.request_id))
+				self.close()
+				return
+			logger.debug("%s: Checking that decoder hasn't been silent for more than %d seconds" % (self.request_id, REQUEST_TIMEOUT))
+			time.sleep(1)
+
+
+	def received_message(self, m):
+		logger.debug("%s: Got message from server of type %s" % (self.request_id, str(type(m))))
+		if self.state == self.__class__.STATE_CONNECTED:
+			props = json.loads(str(m))
+			content_type = props['content_type']
+			self.request_id = props['id']
+			self.num_segments = 0
+			self.decoder_pipeline.init_request(self.request_id, content_type)
+			self.last_decoder_message = time.time()
+#			thread.start_new_thread(self.guard_timeout, ())
+			logger.info("%s: Started timeout guard" % self.request_id)
+			logger.info("%s: Initialized request" % self.request_id)
+			self.state = self.STATE_INITIALIZED
+		elif m.data == "EOS":
+			if self.state != self.STATE_CANCELLING and self.state != self.STATE_EOS_RECEIVED and self.state != self.STATE_FINISHED:
+				self.decoder_pipeline.end_request()
+				self.state = self.STATE_EOS_RECEIVED
+			else:
+				logger.info("%s: Ignoring EOS, worker already in state %d" % (self.request_id, self.state))
+		else:
+			if self.state != self.STATE_CANCELLING and self.state != self.STATE_EOS_RECEIVED and self.state != self.STATE_FINISHED:
+				if isinstance(m, ws4py.messaging.BinaryMessage):
+					self.decoder_pipeline.process_data(m.data)
+					self.state = self.STATE_PROCESSING
+				elif isinstance(m, ws4py.messaging.TextMessage):
+					logger.warning("%s: Got text message but don't know what to do with it" % (self.request_id))
+			else:
+				logger.info("%s: Ignoring data, worker already in state %d" % (self.request_id, self.state))
+
+
+	def finish_request(self):
+		if self.state == self.STATE_CONNECTED:
+			# connection closed when we are not doing anything
+			self.decoder_pipeline.finish_request()
+			self.state = self.STATE_FINISHED
+			return
+		if self.state == self.STATE_INITIALIZED:
+			# connection closed when request initialized but with no data sent
+			self.decoder_pipeline.finish_request()
+			self.state = self.STATE_FINISHED
+			return
+		if self.state != self.STATE_FINISHED:
+			logger.info("%s: Master disconnected before decoder reached EOS?" % self.request_id)
+			self.state = self.STATE_CANCELLING
+			self.decoder_pipeline.cancel()
+			counter = 0
+			while self.state == self.STATE_CANCELLING:
+				self.state = self.STATE_FINISHED
+				counter += 1
+				if counter > 30:
+					# lost hope that the decoder will ever finish, likely it has hung
+					# FIXME: this might introduce new bugs
+					logger.info("%s: Giving up waiting after %d tries" % (self.request_id, counter))
+					self.state = self.STATE_FINISHED
+				else:
+					logger.info("%s: Waiting for EOS from decoder" % self.request_id)
+					time.sleep(1)
+			self.decoder_pipeline.finish_request()
+			logger.info("%s: Finished waiting for EOS" % self.request_id)
+
+
+	def closed(self, code, reason=None):
+		logger.debug("%s: Websocket closed() called" % self.request_id)
+		self.finish_request()
+		logger.debug("%s: Websocket closed() finished" % self.request_id)
+
+	def _on_result(self, result, final):
+		if final:
+			# final results are handled by _on_full_result()
+			transcript = result.decode('utf8')
+			self.coachtranscript += ' ' + transcript
+			return
+		self.last_decoder_message = time.time()
+		if self.last_partial_result == result:
+			return
+		self.last_partial_result = result
+		logger.info("%s: Postprocessing (final=%s) result.."  % (self.request_id, final))
+		if final:
+			logger.info("%s: Before postprocessing: %s" % (self.request_id, result))
+		processed_transcript = self.post_process(result)
+		logger.info("%s: Postprocessing done." % self.request_id)
+		if final:
+			logger.info("%s: After postprocessing: %s" % (self.request_id, processed_transcript))
+
+		event = dict(status=common.STATUS_SUCCESS,
+					 segment=self.num_segments,
+					 result=dict(hypotheses=[dict(transcript=processed_transcript)], final=final))
+		try:
+			self.send(json.dumps(event))
+		except:
+			e = sys.exc_info()[1]
+			logger.warning("Failed to send event to master: %s" % e)
+
+	def _on_full_result(self, full_result_json):
+		self.last_decoder_message = time.time()
+		full_result = json.loads(full_result_json)
+		if full_result.get("status", -1) == common.STATUS_SUCCESS:
+			#logger.info("%s: Postprocessing (final=%s) result.."  % (self.request_id, final))
+			logger.debug("%s: Before postprocessing: %s" % (self.request_id, full_result))
+			full_result = self.post_process_full(full_result)
+			logger.info("%s: Postprocessing done." % self.request_id)
+			logger.debug("%s: After postprocessing: %s" % (self.request_id, full_result))
+
+			try:
+				self.send(json.dumps(full_result))
+			except:
+				e = sys.exc_info()[1]
+				logger.warning("Failed to send event to master: %s" % e)
+			if full_result.get("result", {}).get("final", True):
+				self.num_segments += 1
+				self.last_partial_result = ""
+		else:
+			logger.info("%s: Result status is %d, forwarding the result to the server anyway" % (self.request_id, full_result.get("status", -1)))
+			try:
+				self.send(json.dumps(full_result))
+			except:
+				e = sys.exc_info()[1]
+				logger.warning("Failed to send event to master: %s" % e)
+
+
+	def _on_eos(self, data=None):
+		self.last_decoder_message = time.time()
+		self.state = self.STATE_FINISHED
+		#self.send_adaptation_state()
+		self.close()
+
+	def _on_error(self, error):
+		self.state = self.STATE_FINISHED
+		event = dict(status=common.STATUS_NOT_ALLOWED, message=error)
+		try:
+			self.send(json.dumps(event))
+		except:
+			e = sys.exc_info()[1]
+			logger.warning("Failed to send event to master: %s" % e)
+		self.close()
+
+	def post_process(self, text):
+		if self.post_processor:
+			self.post_processor.stdin.write("%s\n" % text)
+			self.post_processor.stdin.flush()
+			text = self.post_processor.stdout.readline()
+			text = text.strip()
+			text = text.replace("\\n", "\n")
+			return text
+		else:
+			return text
+
+	def post_process_full(self, full_result):
+		if self.full_post_processor:
+			self.full_post_processor.stdin.write("%s\n\n" % json.dumps(full_result))
+			self.post_processor.stdin.flush()
+			lines = []
+			while True:
+				l = self.full_post_processor.stdout.readline()
+				if not l: break # EOF
+				if l.strip() == "":
+					break
+				lines.append(l)
+			full_result = json.loads("".join(lines))
+
+		elif self.post_processor:
+			for hyp in full_result.get("result", {}).get("hypotheses", []):
+				hyp["original-transcript"] = hyp["transcript"]
+				hyp["transcript"] = self.post_process(hyp["transcript"])
+		return full_result
+
+
+
+
+def main():
+	logging.basicConfig(level=logging.DEBUG, format="%(levelname)8s %(asctime)s %(message)s ")
+	logging.debug('Starting up worker')
+	parser = argparse.ArgumentParser(description='Worker for general STT decoder')
+	parser.add_argument('-u', '--uri', default="ws://localhost:8081/worker/ws/speech", dest="uri", help="Server<-->worker websocket URI")
+	parser.add_argument('-f', '--fork', default=1, dest="fork", type=int)
+	parser.add_argument('-c', '--conf', dest="conf", help="YAML file with decoder configuration")
+
+	args = parser.parse_args()
+
+	if args.fork > 1:
+		import tornado.process
+
+		logging.info("Forking into %d processes" % args.fork)
+		tornado.process.fork_processes(args.fork)
+
+	conf = {}
+	if args.conf:
+		with open(args.conf) as f:
+			conf = yaml.safe_load(f)
+
+	with open("logger_config.yaml") as f:
+		logging.config.dictConfig(yaml.safe_load(f))
+
+	global SILENCE_TIMEOUT
+	SILENCE_TIMEOUT = conf.get("silence-timeout", 5)
+
+	global CONNECT_TIMEOUT
+	CONNECT_TIMEOUT = conf.get("connect-timeout", 5)
+
+	global REQUEST_TIMEOUT
+	REQUEST_TIMEOUT = conf.get("request-timeout", 5)
+
+	global RESPONSE_TIMEOUT
+	RESPONSE_TIMEOUT = conf.get("response-timeout", 5)
+
+	decoder_pipeline = DecoderPipeline(conf)
+
+        post_processor = None
+        if "post-processor" in conf:
+                post_processor = Popen(conf["post-processor"], shell=True, stdin=PIPE, stdout=PIPE)
+
+        full_post_processor = None
+        if "full-post-processor" in conf:
+                full_post_processor = Popen(conf["full-post-processor"], shell=True, stdin=PIPE, stdout=PIPE)
+
+	while True:
+		ws = ServerWebsocket(args.uri, decoder_pipeline, post_processor, full_post_processor=full_post_processor)
+		try:
+			logger.info("Opening websocket connection to master server")
+			ws.connect()
+			ws.run_forever()
+		except Exception:
+			logger.error("Couldn't connect to server, waiting for %d seconds", CONNECT_TIMEOUT)
+			time.sleep(CONNECT_TIMEOUT)
+		# fixes a race condition
+		time.sleep(1)
+
+if __name__ == "__main__":
+	main()
+

From 15bbeff25643dd1f1c7914cee4a23f2cd0c9e371 Mon Sep 17 00:00:00 2001
From: Kamal Galrani 
Date: Mon, 26 Jun 2017 11:24:03 +0530
Subject: [PATCH 06/11] Fixes

---
 lucida/speechrecognition/wit_stt/decoder.py | 121 +++++++++++++-------
 lucida/speechrecognition/wit_stt/worker.py  |  11 +-
 2 files changed, 78 insertions(+), 54 deletions(-)

diff --git a/lucida/speechrecognition/wit_stt/decoder.py b/lucida/speechrecognition/wit_stt/decoder.py
index 873d22270..486bea9c6 100644
--- a/lucida/speechrecognition/wit_stt/decoder.py
+++ b/lucida/speechrecognition/wit_stt/decoder.py
@@ -3,32 +3,34 @@
 
 @author: kamal1210
 """
+
 import logging
 import threading
 import time
-import os
 import requests
 import json
+from audioop import rms
 
 logger = logging.getLogger(__name__)
 
-API_HOST="https://api.wit.ai/speech"
-
 class DecoderPipeline(object):
     STATE_CREATED = 0
-    STATE_CONNECTED = 1
     STATE_INITIALIZED = 2
     STATE_PROCESSING = 3
     STATE_EOS_RECEIVED = 7
-    STATE_CANCELLING = 8
     STATE_FINISHED = 100
 
     def __init__(self, conf={}):
-        logger.info("Creating decoder using conf: %s" % conf)
-        self.token = conf.get("wit-access-token", "")
-        self.partial_results = conf.get("partial-results", True)
-        self.max_request_rate = conf.get("max-result-rate", 1)
-        self.url = API_HOST + "?v=" + conf.get("wit-api-version", "14/06/2017")
+        try:
+            self.api_token            = conf["api-token"]
+            self.api_host             = conf["api-host"]
+            self.silence_threshold    = conf["silence-threshold"]
+            self.silence_timeout      = conf["silence-timeout"]
+            self.request_timeout      = conf["request-timeout"]
+            self.socket_data_timeout  = conf["socket-data-timeout"]
+        except Exception as e:
+            logger.error("Key '%s' not found in configuration file!!!" % e.message)
+            raise KeyError("Key '%s' not found in configuration file!!!" % e.message)
 
         self.result_handler = None
         self.full_result_handler = None
@@ -37,12 +39,38 @@ def __init__(self, conf={}):
         self.request_id = ""
         self.buffer = []
         self.lock = threading.Lock()
-        self.state = self.STATE_INITIALIZED
-        logger.info("Initialised decoder pipeline with endpoint: %s" % (self.url))
+        self.state = self.STATE_CREATED
+        self.silent_for = 0.0
+        self.last_chunk_yielded = 0
+        self.eos_received = 0
+        logger.info("Initialized decoder with endpoint: %s" % (self.api_host))
+
+    def is_silent(self, block):
+        try:
+            rms_value = rms(block, 2)
+            return rms_value, rms_value <= self.silence_threshold
+        except:
+            return -1, True
+
+    def _post_req_ctrl(self):
+	self.request_generator = threading.Thread(target=self._post_req_gen)
+        self.request_generator.daemon = True
+        self.request_generator.start()
+        while self.eos_received == 0:
+            time.sleep(1)
+        while self.state != self.STATE_FINISHED:
+            if time.time() - self.eos_received > self.request_timeout:
+                self.request_generator.stop()
+                logger.error("Request to %s timed out!!!" % self.api_host)
+                if self.error_handler:
+                    self.error_handler("Request to %s timed out!!!" % self.api_host)
+                self.finish_request()
+            time.sleep(1)
 
     def _post_req_gen(self):
-        print str(self.headers)
-        response = requests.post(self.url, headers=self.headers, data=self._post_data_gen())
+        self.last_chunk_yielded = time.time()
+        self.state = self.STATE_PROCESSING
+        response = requests.post(self.api_host, headers=self.headers, data=self._post_data_gen())
         if response.status_code == 200:
             response_json = json.loads(response.text)
             result = { 'status': 0, 'total-length': 0.0, 'result': { 'hypotheses': [{ 'likelihood': 100.0, 'confidence': 1.0, 'transcript': response_json['_text']}], 'final': True }, 'segment-length': 0.0, 'segment-start': 0.0 }
@@ -50,58 +78,65 @@ def _post_req_gen(self):
                 self.full_result_handler(json.dumps(result))
         else:
             response_json = json.loads(response.text)
-            logger.log(response_json['error'])
+            logger.error(response_json['error'])
             if self.error_handler:
                 self.error_handler(response_json['error'])
-        if self.eos_handler:
-            self.eos_handler[0](self.eos_handler[1])
         self.finish_request()
 
     def _post_data_gen(self):
-        while self.state == self.STATE_CONNECTED:
+        while self.state == self.STATE_PROCESSING:
             self.lock.acquire()
             if self.buffer:
               chunk = self.buffer.pop(0)
               if chunk != 'EOS':
                   yield chunk
                   self.last_chunk_yielded = time.time()
-                  print "Sending over ", len(chunk), " bytes of data"
+                  amplitude, silent = self.is_silent(chunk)
+                  if silent:
+                      self.silent_for = self.silent_for + len(chunk)/2.0/16000
+                  else:
+                      self.silent_for = 0.0
+                  logger.debug("%s: Yielding %d bytes of data with rms %d " % (self.request_id, len(chunk), amplitude))
               else:
                   self.state = self.STATE_EOS_RECEIVED
-                  logger.debug("%s: Received EOS!!! Closing POST buffer.." % self.request_id)
+                  logger.info("%s: Received EOS!!! Closing POST buffer.." % self.request_id)
             self.lock.release()
-#            if time.time() - self.last_decoder_message > self.request_timeout:
-#                state = self.STATE_FINISHED
-#                break
+            if ( time.time() - self.last_chunk_yielded ) > self.socket_data_timeout:
+                self.state = self.STATE_EOS_RECEIVED
+            if self.silent_for > self.silence_timeout:
+                self.state = self.STATE_EOS_RECEIVED
+        self.eos_received = time.time()
 
     def finish_request(self):
         logger.info("%s: Resetting decoder state" % self.request_id)
+        if self.eos_handler:
+            self.eos_handler[0](self.eos_handler[1])
         self.state = self.STATE_FINISHED
         self.request_id = ""
+        self.buffer = []
+        self.silent_for = 0.0
+        self.last_chunk_yielded = 0
 
-    def init_request(self, id, caps_str):
-#	self.user = user-name
-#	self.context = user-context
-#	self.thread_id = thread-id
-#	self.message_id = message-id
-        self.request_id = id
-        logger.info("%s: Initializing request" % (self.request_id))
+    def init_request(self, request_id, caps_str):
+        self.request_id = request_id
 	content_type='audio/raw;encoding=signed-integer;bits=16;rate=16000;endian=little'
+        logger.info("%s: Initializing request" % self.request_id)
 	logger.info("%s: Setting content_type to %s" % (self.request_id, content_type))
-	self.headers = {'Authorization': 'Bearer ' + self.token, 'Content-Type': content_type, 'Accept': 'application/json', 'Transfer-Encoding': 'chunked'}
-        self.state = self.STATE_CONNECTED
-	thread = threading.Thread(target=self._post_req_gen)
-        thread.daemon = True
-        thread.start()
+	self.headers = {'Authorization': 'Bearer ' + self.api_token, 'Content-Type': content_type, 'Accept': 'application/json', 'Transfer-Encoding': 'chunked'}
+        self.state = self.STATE_INITIALIZED
+	self.request_controller = threading.Thread(target=self._post_req_ctrl)
+        self.request_controller.daemon = True
+        self.request_controller.start()
 
     def process_data(self, data):
-        logger.debug('%s: Pushing buffer of size %d to pipeline' % (self.request_id, len(data)))
-        self.lock.acquire()
-        self.buffer.append(data)
-        self.lock.release()
+        if self.state == self.STATE_PROCESSING:
+            logger.debug('%s: Pushing %d bytes of data to buffer' % (self.request_id, len(data)))
+            self.lock.acquire()
+            self.buffer.append(data)
+            self.lock.release()
 
     def end_request(self):
-        logger.info("%s: Pushing EOS to pipeline" % self.request_id)
+        logger.info("%s: Pushing EOS to buffer" % self.request_id)
         self.lock.acquire()
         self.buffer.append('EOS')
         self.lock.release()
@@ -118,10 +153,8 @@ def set_eos_handler(self, handler, user_data=None):
     def set_error_handler(self, handler):
         self.error_handler = handler
 
-
     def cancel(self):
-        logger.info("%s: Sending EOS to pipeline in order to cancel processing" % self.request_id)
-        if self.eos_handler:
-            self.eos_handler[0](self.eos_handler[1])
+        self.request_controller.stop()
+        self.request_generator.stop()
         self.finish_request()
         logger.info("%s: Cancelled pipeline" % self.request_id)
diff --git a/lucida/speechrecognition/wit_stt/worker.py b/lucida/speechrecognition/wit_stt/worker.py
index b99f2bafb..fdb4cbdf7 100644
--- a/lucida/speechrecognition/wit_stt/worker.py
+++ b/lucida/speechrecognition/wit_stt/worker.py
@@ -6,14 +6,10 @@
 import thread
 import argparse
 from subprocess import Popen, PIPE
-from gi.repository import GObject
 import yaml
 import json
 import sys
-import locale
-import codecs
-import zlib
-import base64
+import os
 import time
 
 from ws4py.client.threadedclient import WebSocketClient
@@ -22,8 +18,6 @@
 from decoder import DecoderPipeline
 import common
 
-import os
-
 empty_response = ''
 
 logger = logging.getLogger(__name__)
@@ -150,9 +144,6 @@ def closed(self, code, reason=None):
 
 	def _on_result(self, result, final):
 		if final:
-			# final results are handled by _on_full_result()
-			transcript = result.decode('utf8')
-			self.coachtranscript += ' ' + transcript
 			return
 		self.last_decoder_message = time.time()
 		if self.last_partial_result == result:

From f6ed0166b8f2e315fa5cb2c198734eb48b2eec41 Mon Sep 17 00:00:00 2001
From: Kamal Galrani 
Date: Mon, 10 Jul 2017 08:02:57 +0530
Subject: [PATCH 07/11] Non working commit

---
 lucida/speechrecognition/.gitignore           |   3 +
 lucida/speechrecognition/Makefile             |   2 -
 lucida/speechrecognition/README.md            |  16 -
 .../kaldigstserver => }/common.py             |   0
 lucida/speechrecognition/configuration.py     | 214 +++++
 lucida/speechrecognition/decoder_pipeline.py  | 183 ++++
 .../speechrecognition/decoders/wit/Makefile   |   6 +
 .../speechrecognition/decoders/wit/configure  |   3 +
 lucida/speechrecognition/decoders/wit/decoder | Bin 0 -> 6515 bytes
 .../speechrecognition/decoders/wit/decoder.py | 157 ++++
 lucida/speechrecognition/include/defs.h       |  16 +
 lucida/speechrecognition/include/defs.py      |  16 +
 .../kaldi_gstreamer_asr/.gitignore            |   5 -
 .../kaldi_gstreamer_asr/Dockerfile            |  13 -
 .../kaldi_gstreamer_asr/LICENSE               |  23 -
 .../kaldi_gstreamer_asr/Makefile              |  13 -
 .../kaldi_gstreamer_asr/README.md             | 394 ---------
 .../kaldi_gstreamer_asr/estonian_worker.yaml  |  29 -
 .../etc/english-supervisord.conf              |  21 -
 .../kaldi_gstreamer_asr/install_idlak.sh      | 218 -----
 .../kaldi_gstreamer_asr/install_kaldi.sh      |  57 --
 .../kaldi_gstreamer_asr/install_kaldi_tts.sh  |  23 -
 .../kaldigstserver/client.py                  | 128 ---
 .../kaldigstserver/commandcenter.thrift       |  38 -
 .../kaldigstserver/decoder.py                 | 221 -----
 .../kaldigstserver/decoder2.py                | 226 -----
 .../kaldigstserver/decoder2_test.py           | 145 ----
 .../kaldigstserver/decoder_test.py            | 194 -----
 .../kaldigstserver/master_server.py           | 351 --------
 .../kaldigstserver/settings.py                |   9 -
 .../kaldigstserver/test-buffer.py             |  31 -
 .../kaldigstserver/worker.py                  | 417 ---------
 .../sample_english_nnet2.yaml                 |  54 --
 .../sample_full_post_processor.py             |  57 --
 .../kaldi_gstreamer_asr/sample_worker.yaml    |  29 -
 .../kaldi_gstreamer_asr/simple_start.sh       |   9 -
 .../kaldi_gstreamer_asr/start.sh              |  42 -
 .../kaldi_gstreamer_asr/static/status.html    |  23 -
 .../kaldi_gstreamer_asr/stop.sh               |   8 -
 .../test/data/bill_gates-TED.mp3              | Bin 496746 -> 0 bytes
 .../test/models/download-fisher-nnet2.sh      |  30 -
 .../test/models/download-tedlium-nnet2.sh     |   3 -
 .../{wit_stt => }/logger_config.yaml          |   1 -
 lucida/speechrecognition/plugin/.gitignore    |  16 +
 lucida/speechrecognition/plugin/AUTHORS       |   1 +
 lucida/speechrecognition/plugin/COPYING       |   2 +
 .../__init__.py => plugin/ChangeLog}          |   0
 lucida/speechrecognition/plugin/Makefile      | 817 ++++++++++++++++++
 lucida/speechrecognition/plugin/Makefile.am   |   3 +
 lucida/speechrecognition/plugin/NEWS          |   1 +
 lucida/speechrecognition/plugin/README        |  34 +
 lucida/speechrecognition/plugin/autogen.sh    |  18 +
 lucida/speechrecognition/plugin/compile       | 347 ++++++++
 lucida/speechrecognition/plugin/configure.ac  |  90 ++
 lucida/speechrecognition/plugin/list          |   5 +
 .../.deps/libgstasrplugin_la-gstasrplugin.Plo | 732 ++++++++++++++++
 .../plugin/src/.libs/libgstasrplugin.exp      |   2 +
 .../plugin/src/.libs/libgstasrplugin.ver      |   4 +
 lucida/speechrecognition/plugin/src/Makefile  | 673 +++++++++++++++
 .../speechrecognition/plugin/src/Makefile.am  |  14 +
 .../plugin/src/gstasrplugin.c                 | 662 ++++++++++++++
 .../plugin/src/gstasrplugin.h                 | 110 +++
 lucida/speechrecognition/wit_stt/Makefile     |   4 -
 lucida/speechrecognition/wit_stt/common.py    |  13 -
 lucida/speechrecognition/wit_stt/decoder.py   | 160 ----
 .../speechrecognition/wit_stt/simple_start.sh |   9 -
 lucida/speechrecognition/wit_stt/wit.yaml     |  13 -
 lucida/speechrecognition/wit_stt/worker.py    | 305 -------
 lucida/speechrecognition/worker.py            |  72 ++
 lucida/speechrecognition/worker_socket.py     | 157 ++++
 70 files changed, 4358 insertions(+), 3334 deletions(-)
 create mode 100644 lucida/speechrecognition/.gitignore
 delete mode 100644 lucida/speechrecognition/Makefile
 delete mode 100644 lucida/speechrecognition/README.md
 rename lucida/speechrecognition/{kaldi_gstreamer_asr/kaldigstserver => }/common.py (100%)
 create mode 100644 lucida/speechrecognition/configuration.py
 create mode 100644 lucida/speechrecognition/decoder_pipeline.py
 create mode 100644 lucida/speechrecognition/decoders/wit/Makefile
 create mode 100755 lucida/speechrecognition/decoders/wit/configure
 create mode 100755 lucida/speechrecognition/decoders/wit/decoder
 create mode 100644 lucida/speechrecognition/decoders/wit/decoder.py
 create mode 100644 lucida/speechrecognition/include/defs.h
 create mode 100644 lucida/speechrecognition/include/defs.py
 delete mode 100755 lucida/speechrecognition/kaldi_gstreamer_asr/.gitignore
 delete mode 100644 lucida/speechrecognition/kaldi_gstreamer_asr/Dockerfile
 delete mode 100644 lucida/speechrecognition/kaldi_gstreamer_asr/LICENSE
 delete mode 100644 lucida/speechrecognition/kaldi_gstreamer_asr/Makefile
 delete mode 100644 lucida/speechrecognition/kaldi_gstreamer_asr/README.md
 delete mode 100644 lucida/speechrecognition/kaldi_gstreamer_asr/estonian_worker.yaml
 delete mode 100644 lucida/speechrecognition/kaldi_gstreamer_asr/etc/english-supervisord.conf
 delete mode 100755 lucida/speechrecognition/kaldi_gstreamer_asr/install_idlak.sh
 delete mode 100755 lucida/speechrecognition/kaldi_gstreamer_asr/install_kaldi.sh
 delete mode 100755 lucida/speechrecognition/kaldi_gstreamer_asr/install_kaldi_tts.sh
 delete mode 100644 lucida/speechrecognition/kaldi_gstreamer_asr/kaldigstserver/client.py
 delete mode 100644 lucida/speechrecognition/kaldi_gstreamer_asr/kaldigstserver/commandcenter.thrift
 delete mode 100644 lucida/speechrecognition/kaldi_gstreamer_asr/kaldigstserver/decoder.py
 delete mode 100644 lucida/speechrecognition/kaldi_gstreamer_asr/kaldigstserver/decoder2.py
 delete mode 100644 lucida/speechrecognition/kaldi_gstreamer_asr/kaldigstserver/decoder2_test.py
 delete mode 100644 lucida/speechrecognition/kaldi_gstreamer_asr/kaldigstserver/decoder_test.py
 delete mode 100644 lucida/speechrecognition/kaldi_gstreamer_asr/kaldigstserver/master_server.py
 delete mode 100644 lucida/speechrecognition/kaldi_gstreamer_asr/kaldigstserver/settings.py
 delete mode 100644 lucida/speechrecognition/kaldi_gstreamer_asr/kaldigstserver/test-buffer.py
 delete mode 100644 lucida/speechrecognition/kaldi_gstreamer_asr/kaldigstserver/worker.py
 delete mode 100644 lucida/speechrecognition/kaldi_gstreamer_asr/sample_english_nnet2.yaml
 delete mode 100755 lucida/speechrecognition/kaldi_gstreamer_asr/sample_full_post_processor.py
 delete mode 100644 lucida/speechrecognition/kaldi_gstreamer_asr/sample_worker.yaml
 delete mode 100755 lucida/speechrecognition/kaldi_gstreamer_asr/simple_start.sh
 delete mode 100755 lucida/speechrecognition/kaldi_gstreamer_asr/start.sh
 delete mode 100644 lucida/speechrecognition/kaldi_gstreamer_asr/static/status.html
 delete mode 100755 lucida/speechrecognition/kaldi_gstreamer_asr/stop.sh
 delete mode 100644 lucida/speechrecognition/kaldi_gstreamer_asr/test/data/bill_gates-TED.mp3
 delete mode 100755 lucida/speechrecognition/kaldi_gstreamer_asr/test/models/download-fisher-nnet2.sh
 delete mode 100755 lucida/speechrecognition/kaldi_gstreamer_asr/test/models/download-tedlium-nnet2.sh
 rename lucida/speechrecognition/{wit_stt => }/logger_config.yaml (99%)
 create mode 100644 lucida/speechrecognition/plugin/.gitignore
 create mode 100644 lucida/speechrecognition/plugin/AUTHORS
 create mode 100644 lucida/speechrecognition/plugin/COPYING
 rename lucida/speechrecognition/{kaldi_gstreamer_asr/kaldigstserver/__init__.py => plugin/ChangeLog} (100%)
 create mode 100644 lucida/speechrecognition/plugin/Makefile
 create mode 100644 lucida/speechrecognition/plugin/Makefile.am
 create mode 100644 lucida/speechrecognition/plugin/NEWS
 create mode 100644 lucida/speechrecognition/plugin/README
 create mode 100755 lucida/speechrecognition/plugin/autogen.sh
 create mode 100755 lucida/speechrecognition/plugin/compile
 create mode 100644 lucida/speechrecognition/plugin/configure.ac
 create mode 100644 lucida/speechrecognition/plugin/list
 create mode 100644 lucida/speechrecognition/plugin/src/.deps/libgstasrplugin_la-gstasrplugin.Plo
 create mode 100644 lucida/speechrecognition/plugin/src/.libs/libgstasrplugin.exp
 create mode 100644 lucida/speechrecognition/plugin/src/.libs/libgstasrplugin.ver
 create mode 100644 lucida/speechrecognition/plugin/src/Makefile
 create mode 100644 lucida/speechrecognition/plugin/src/Makefile.am
 create mode 100644 lucida/speechrecognition/plugin/src/gstasrplugin.c
 create mode 100644 lucida/speechrecognition/plugin/src/gstasrplugin.h
 delete mode 100644 lucida/speechrecognition/wit_stt/Makefile
 delete mode 100644 lucida/speechrecognition/wit_stt/common.py
 delete mode 100644 lucida/speechrecognition/wit_stt/decoder.py
 delete mode 100755 lucida/speechrecognition/wit_stt/simple_start.sh
 delete mode 100644 lucida/speechrecognition/wit_stt/wit.yaml
 delete mode 100644 lucida/speechrecognition/wit_stt/worker.py
 create mode 100644 lucida/speechrecognition/worker.py
 create mode 100644 lucida/speechrecognition/worker_socket.py

diff --git a/lucida/speechrecognition/.gitignore b/lucida/speechrecognition/.gitignore
new file mode 100644
index 000000000..5c02e9445
--- /dev/null
+++ b/lucida/speechrecognition/.gitignore
@@ -0,0 +1,3 @@
+*.pyc
+*.pyo
+worker_config.yaml
diff --git a/lucida/speechrecognition/Makefile b/lucida/speechrecognition/Makefile
deleted file mode 100644
index b8653cff5..000000000
--- a/lucida/speechrecognition/Makefile
+++ /dev/null
@@ -1,2 +0,0 @@
-SUBDIRS=kaldi_gstreamer_asr
-include ../../Makefile.common
\ No newline at end of file
diff --git a/lucida/speechrecognition/README.md b/lucida/speechrecognition/README.md
deleted file mode 100644
index 99848824a..000000000
--- a/lucida/speechrecognition/README.md
+++ /dev/null
@@ -1,16 +0,0 @@
-# Automatic Speech Recognition (ASR)
-
-The current implementation of ASR uses [Kaldi](http://kaldi.sourceforge.net/),
-a speech recognition toolkit written in C++ that is freely available under the Apache license. 
-
-## Notes:
-
-1. `kaldi_gstreamer_asr` contains the implementation of the Kaldi ASR service.
-
-2. If you want to create and use another ASR implementation,
-you can start by making a directory parallel to `kaldi_gstreamer_asr` and modify `Makefile`.
-Make sure to reference `../lucidaservice.thrift` and `../lucidatypes.thrift`.
-
-3. Type `make` to build all ASR implementations,
-or type `cd kaldi_gstreamer_asr` and `make` to only build the Kaldi ASR service.
-
diff --git a/lucida/speechrecognition/kaldi_gstreamer_asr/kaldigstserver/common.py b/lucida/speechrecognition/common.py
similarity index 100%
rename from lucida/speechrecognition/kaldi_gstreamer_asr/kaldigstserver/common.py
rename to lucida/speechrecognition/common.py
diff --git a/lucida/speechrecognition/configuration.py b/lucida/speechrecognition/configuration.py
new file mode 100644
index 000000000..c136c78e1
--- /dev/null
+++ b/lucida/speechrecognition/configuration.py
@@ -0,0 +1,214 @@
+# configuration.py
+
+# Add max_audio_duration, silence_threshold, connect_timeout
+
+
+import logging, logging.config, yaml
+import os, sys, errno
+import click
+import re
+from urlparse import urlparse
+import json
+
+os.chdir(os.path.dirname(os.path.realpath(__file__)))
+
+logger = logging.getLogger(__name__)
+logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)7s: %(name)10s: %(message)s", datefmt="%Y-%m-%d %H:%M:%S")
+
+GST_DEBUG = os.environ.get('GST_DEBUG')
+CONFIG = dict(
+    master = "http://localhost:8081",
+    retry_after = 5,
+    data_directory = "/tmp/lucida/speech",
+    max_segment_duration = 180,
+    max_call_duration = 3600,
+    silence_timeout = 2,
+    initial_silence_timeout = 5,
+    silence_threshold = 2000,
+    response_timeout = 30,
+    worker_verbosity = "info",
+    gstreamer_verbosity = "none",
+
+    config_options = dict(
+        master_prompt  = "URL for Lucida commandcenter",
+        retry_after_prompt = "Number of seconds to wait between subsequent reconnects to master", retry_after_min = 1, retry_after_max = 30,
+        data_directory_prompt = "Directory to store speech transcriptions and raw audio",
+        max_segment_duration_prompt = "Maximum length of audio segment in seconds", max_segment_duration_min = 10, max_segment_duration_max = 300,
+        max_call_duration_prompt = "Maximum length of audio segment in seconds", max_call_duration_min = 60, max_call_duration_max = 18000,
+        silence_timeout_prompt = "Maximum silence (in seconds) that should be tolerated", silence_timeout_min = 1, silence_timeout_max = 10,
+        initial_silence_timeout_prompt = "Maximum initial silence (in seconds) that should be tolerated", initial_silence_timeout_min = 1, initial_silence_timeout_max = 30,
+        silence_threshold_prompt = "Audio segments with RMS below this value will be considered silent", silence_threshold_min = 50, silence_threshold_max = 50000,
+        response_timeout_prompt = "Maximum time (in seconds) between end of speech and receiving of transcription that should be tolerated", response_timeout_min = 5, response_timeout_max = 60,
+        worker_verbosity_prompt = "Verbosity level for worker", worker_verbosity_choices = ["critical", "error", "warning", "info", "debug"],
+        gstreamer_verbosity_prompt = "Verbosity level for GStreamer", gstreamer_verbosity_choices = ["none", "error", "warning", "fixme", "info", "debug", "log", "trace", "memdump"]
+    )
+)
+
+def validate_master(ctx, param, value):
+    if value.startswith("localhost"):
+        value = "http://" + value
+    if value.startswith("//"):
+        value = "http:" + value
+    scheme = re.compile('[A-Za-z0-9]{2,5}://')
+    if scheme.match(value) == None:
+        value = "http://" + value
+    value = urlparse(value)
+    if value.hostname == None:
+        if ctx == None:
+            logger.error("Invalid URL provided for Lucida commandcenter!!!")
+            return False
+        raise click.BadParameter("Invalid URL provided for Lucida commandcenter!!!")
+    if value.port != None:
+        url = value.hostname + ":" + str(value.port) + "/worker/ws/speech"
+    else:
+        url = value.hostname + "/worker/ws/speech"
+    if value.scheme == "http" or value.scheme == "ws":
+        url = "ws://" + url
+    elif value.scheme == "https" or value.scheme == "wss":
+        url = "wss://" + url
+    else:
+        if ctx == None:
+            logger.error("Unrecognized scheme '%s' while parsing URL for Lucida commandcenter!!!" % (value.scheme))
+            return False
+        raise click.BadParameter("Unrecognized scheme '%s' while parsing URL for Lucida commandcenter!!!" % (value.scheme))
+    return url
+
+def validate_directory(ctx, param, value):
+    if not os.path.isdir(value):
+        mkdir = raw_input("Specified data directory doesn't exist! Do you want to create it? [y/N]: ")
+        if mkdir == "y" or mkdir == "Y":
+            try:
+                os.makedirs(value, 0700)
+            except Exception as e:
+                if ctx == None:
+                    logger.error("Error while creating data directory!!! %s" % (e))
+                    return False
+                raise click.BadParameter("Error while creating data directory!!! %s" % (e))
+        else:
+            if ctx == None:
+                logger.error("Aborting...")
+                return False
+            raise click.BadParameter("Please enter a valid data directory...")
+    elif not os.access(value, os.R_OK) or not os.access(value, os.W_OK) or not os.access(value, os.X_OK):
+        if ctx == None:
+            logger.log("Permission denied while accessing data directory!!!")
+            return False
+        raise click.BadParameter("Permission denied while accessing data directory!!! Please try again...")
+    return value
+
+@click.command()
+@click.option("--master", prompt=CONFIG['config_options']['master_prompt'],
+    default=CONFIG['master'], type=click.STRING, callback=validate_master, required=True, show_default=True, help=CONFIG['config_options']['master_prompt'])
+@click.option("--retry-after", prompt=CONFIG['config_options']['retry_after_prompt'],
+    default=CONFIG['retry_after'], type=click.IntRange(min=CONFIG['config_options']['retry_after_min'], max=CONFIG['config_options']['retry_after_max']),
+    required=True, show_default=True, help=CONFIG['config_options']['retry_after_prompt'])
+@click.option("--data-directory", prompt=CONFIG['config_options']['data_directory_prompt'],
+    default=CONFIG['data_directory'], type=click.STRING, callback=validate_directory, required=True, show_default=True, help=CONFIG['config_options']['data_directory_prompt'])
+@click.option("--max-segment-duration", prompt=CONFIG['config_options']['max_segment_duration_prompt'],
+    default=CONFIG['max_segment_duration'], type=click.IntRange(min=CONFIG['config_options']['max_segment_duration_min'], max=CONFIG['config_options']['max_segment_duration_max']),
+    required=True, show_default=True, help=CONFIG['config_options']['max_segment_duration_prompt'])
+@click.option("--max-call-duration", prompt=CONFIG['config_options']['max_call_duration_prompt'],
+    default=CONFIG['max_call_duration'], type=click.IntRange(min=CONFIG['config_options']['max_call_duration_min'], max=CONFIG['config_options']['max_call_duration_max']),
+    required=True, show_default=True, help=CONFIG['config_options']['max_call_duration_prompt'])
+@click.option("--silence-timeout", prompt=CONFIG['config_options']['silence_timeout_prompt'],
+    default=CONFIG['silence_timeout'], type=click.IntRange(min=CONFIG['config_options']['silence_timeout_min'], max=CONFIG['config_options']['silence_timeout_max']),
+    required=True, show_default=True, help=CONFIG['config_options']['silence_timeout_prompt'])
+@click.option("--initial-silence-timeout", prompt=CONFIG['config_options']['initial_silence_timeout_prompt'],
+    default=CONFIG['initial_silence_timeout'], type=click.IntRange(min=CONFIG['config_options']['initial_silence_timeout_min'],
+    max=CONFIG['config_options']['initial_silence_timeout_max']), required=True, show_default=True, help=CONFIG['config_options']['initial_silence_timeout_prompt'])
+@click.option("--silence-threshold", prompt=CONFIG['config_options']['silence_threshold_prompt'],
+    default=CONFIG['silence_threshold'], type=click.IntRange(min=CONFIG['config_options']['silence_threshold_min'], max=CONFIG['config_options']['silence_threshold_max']),
+    required=True, show_default=True, help=CONFIG['config_options']['silence_threshold_prompt'])
+@click.option("--response-timeout", prompt=CONFIG['config_options']['response_timeout_prompt'],
+    default=CONFIG['response_timeout'], type=click.IntRange(min=CONFIG['config_options']['response_timeout_min'], max=CONFIG['config_options']['response_timeout_max']),
+    required=True, show_default=True, help=CONFIG['config_options']['response_timeout_prompt'])
+@click.option("--worker-verbosity", prompt=(CONFIG['config_options']['worker_verbosity_prompt'] + " " + str(CONFIG['config_options']['worker_verbosity_choices'])),
+    default=CONFIG['worker_verbosity'], type=click.Choice(CONFIG['config_options']['worker_verbosity_choices']), required=True,
+    show_default=True, help=CONFIG['config_options']['worker_verbosity_prompt'])
+@click.option("--gstreamer-verbosity", prompt=(CONFIG['config_options']['gstreamer_verbosity_prompt'] + " " + str(CONFIG['config_options']['gstreamer_verbosity_choices'])),
+    default=CONFIG['gstreamer_verbosity'], type=click.Choice(CONFIG['config_options']['gstreamer_verbosity_choices']), required=True,
+    show_default=True, help=CONFIG['config_options']['gstreamer_verbosity_prompt'])
+def first_run(master, retry_after, data_directory, max_segment_duration, max_call_duration, silence_timeout, initial_silence_timeout, silence_threshold, response_timeout, worker_verbosity, gstreamer_verbosity):
+    conf = dict(
+        master = master,
+        retry_after = retry_after,
+        data_directory = data_directory,
+        max_segment_duration = max_segment_duration,
+        max_call_duration = max_call_duration,
+        silence_timeout = silence_timeout,
+        initial_silence_timeout = initial_silence_timeout,
+        silence_threshold = silence_threshold,
+        response_timeout = response_timeout,
+        worker_verbosity = worker_verbosity,
+        gstreamer_verbosity = gstreamer_verbosity
+    )
+    conf_str = (
+                 "# Configuration file for speech recognition worker\n\n"
+                 "# " + CONFIG['config_options']['master_prompt'] + "\n"
+                 "master: '" + conf['master'] + "'\n\n"
+                 "# " + CONFIG['config_options']['retry_after_prompt'] + "\n"
+                 "retry_after: " + str(conf['retry_after']) + "\n\n"
+                 "# " + CONFIG['config_options']['data_directory_prompt'] + "\n"
+                 "data_directory: '" + conf['data_directory'] + "'\n\n"
+                 "# " + CONFIG['config_options']['max_segment_duration_prompt'] + "\n"
+                 "max_segment_duration: " + str(conf['max_segment_duration']) + "\n\n"
+                 "# " + CONFIG['config_options']['max_call_duration_prompt'] + "\n"
+                 "max_call_duration: " + str(conf['max_call_duration']) + "\n\n"
+                 "# " + CONFIG['config_options']['silence_timeout_prompt'] + "\n"
+                 "silence_timeout: " + str(conf['silence_timeout']) + "\n\n"
+                 "# " + CONFIG['config_options']['initial_silence_timeout_prompt'] + "\n"
+                 "initial_silence_timeout: " + str(conf['initial_silence_timeout']) + "\n\n"
+                 "# " + CONFIG['config_options']['response_timeout_prompt'] + "\n"
+                 "response_timeout: " + str(conf['response_timeout']) + "\n\n"
+                 "# " + CONFIG['config_options']['silence_threshold_prompt'] + "\n"
+                 "silence_threshold: " + str(conf['silence_threshold']) + "\n\n"
+                 "# " + CONFIG['config_options']['worker_verbosity_prompt'] + " " + str(CONFIG['config_options']['worker_verbosity_choices']) + "\n"
+                 "worker_verbosity: '" + conf['worker_verbosity'] + "'\n\n"
+                 "# " + CONFIG['config_options']['gstreamer_verbosity_prompt'] + " " + str(CONFIG['config_options']['gstreamer_verbosity_choices']) + "\n"
+                 "gstreamer_verbosity: '" + conf['gstreamer_verbosity'] + "'"
+               )
+    with open("worker_config.yaml", "w") as worker_config:
+        worker_config.write(conf_str)
+    logger.warn("Saving configuration to file and quitting...")
+    sys.exit(0)
+
+def process(conf):
+    conf['worker_verbosity'] = logging.getLevelName(conf['worker_verbosity'].upper())
+    if GST_DEBUG == None:
+        conf['gstreamer_verbosity'] = str(CONFIG['config_options']['gstreamer_verbosity_choices'].index(conf['gstreamer_verbosity']))
+    else:
+        logger.warning("Using GST_DEBUG='%s' value from environment. If you don't want this unset GST_DEBUG before running this script" % GST_DEBUG)
+        conf['gstreamer_verbosity'] = GST_DEBUG
+    if ( not validate_master(None, None, conf['master']) or not validate_directory(None, None, conf['data_directory']) or
+      not isinstance( conf['silence_timeout'], int ) or not isinstance( conf['initial_silence_timeout'], int ) or
+      not isinstance( conf['response_timeout'], int ) or not isinstance( conf['worker_verbosity'], int ) or
+      not isinstance( conf['silence_threshold'], int ) or not isinstance( conf['retry_after'], int ) or
+      not isinstance( conf['max_segment_duration'], int ) or not isinstance( conf['max_call_duration'], int ) or
+      conf['silence_timeout'] > CONFIG['config_options']['silence_timeout_max'] or conf['silence_timeout'] < CONFIG['config_options']['silence_timeout_min'] or
+      conf['initial_silence_timeout'] > CONFIG['config_options']['initial_silence_timeout_max'] or conf['initial_silence_timeout'] < CONFIG['config_options']['initial_silence_timeout_min'] or
+      conf['response_timeout'] > CONFIG['config_options']['response_timeout_max'] or conf['response_timeout'] < CONFIG['config_options']['response_timeout_min'] or
+      conf['retry_after'] > CONFIG['config_options']['retry_after_max'] or conf['retry_after'] < CONFIG['config_options']['retry_after_min'] or
+      conf['silence_threshold'] > CONFIG['config_options']['silence_threshold_max'] or conf['silence_threshold'] < CONFIG['config_options']['silence_threshold_min'] or
+      conf['max_segment_duration'] > CONFIG['config_options']['max_segment_duration_max'] or conf['max_segment_duration'] < CONFIG['config_options']['max_segment_duration_min'] or
+      conf['max_call_duration'] > CONFIG['config_options']['max_call_duration_max'] or conf['max_call_duration'] < CONFIG['config_options']['max_call_duration_min'] ):
+        raise ValueError
+    return conf
+
+def load():
+    try:
+        with open("logger_config.yaml") as f:
+            logging.config.dictConfig(yaml.safe_load(f))
+        logger.info("Loaded logger configuration from logger_config.yaml")
+    except Exception as e:
+        logger.error("Error while loading configuration from logger_config.yaml: %s" % (e))
+
+    global CONFIG
+
+    conf = dict()
+    try:
+        with open("worker_config.yaml") as f:
+            conf = process(yaml.safe_load(f))
+        logger.info("Loaded worker configuration from worker_config.yaml: %s" % str(conf))
+    except:
+        first_run()
+    return conf
diff --git a/lucida/speechrecognition/decoder_pipeline.py b/lucida/speechrecognition/decoder_pipeline.py
new file mode 100644
index 000000000..c48882c92
--- /dev/null
+++ b/lucida/speechrecognition/decoder_pipeline.py
@@ -0,0 +1,183 @@
+import gi
+gi.require_version('Gst', '1.0')
+from gi.repository import GObject, Gst
+GObject.threads_init()
+Gst.init(None)
+
+import os
+import logging
+import thread
+import subprocess
+
+os.chdir(os.path.dirname(os.path.realpath(__file__)))
+os.environ['GST_PLUGIN_PATH'] = os.path.dirname(os.path.realpath(__file__)) + "/plugin/src"
+
+logger = logging.getLogger(__name__)
+
+class DecoderPipeline(object):
+    def __init__(self, conf):
+        logger.info("Initialising %s speech to text decoder" % (conf['decoder']))
+
+        self.interim_result_handler = None
+        self.final_result_handler = None
+        self.eos_handler = None
+        self.error_handler = None
+
+        self.request_id = ""
+
+        self._create_pipeline(conf)
+
+    def _create_pipeline(self, conf):
+        conf = self._load_configuration(conf)
+        self.appsrc = Gst.ElementFactory.make("appsrc", "appsrc")
+        self.decodebin = Gst.ElementFactory.make("decodebin", "decodebin")
+        self.audioconvert = Gst.ElementFactory.make("audioconvert", "audioconvert")
+        self.audioresample = Gst.ElementFactory.make("audioresample", "audioresample")
+        self.tee = Gst.ElementFactory.make("tee", "tee")
+        self.audiosink = Gst.ElementFactory.make("filesink", "audiosink")
+        self.asr = Gst.ElementFactory.make("asrplugin", "asr")
+        self.datasink = Gst.ElementFactory.make("filesink", "datasink")
+
+        self.asr.set_property("decoder_executable", conf['decoder_executable'])
+        self.asr.set_property("decoder_configuration", conf['decoder_configuration'])
+#        self.asr.set_property("silence_threshold", conf['silence_threshold'])
+        self.asr.set_property("silence_threshold", 2000)
+        self.asr.set_property("silence_timeout", conf['silence_timeout'])
+        self.asr.set_property("initial_silence_timeout", conf['initial_silence_timeout'])
+
+        self.appsrc.set_property("is-live", True)
+        self.audiosink.set_property("location", "/dev/null")
+        self.datasink.set_property("location", "/dev/null")
+
+        self.data_directory = conf['data_directory']
+
+        logger.info('Created GStreamer elements')
+
+        self.pipeline = Gst.Pipeline()
+        for element in [self.appsrc, self.decodebin, self.audioconvert, self.audioresample, self.tee, self.audiosink, self.asr, self.datasink]:
+            logger.debug("Adding %s to the pipeline" % element)
+            self.pipeline.add(element)
+
+        logger.info('Linking GStreamer elements')
+
+        self.appsrc.link(self.decodebin)
+        self.decodebin.connect('pad-added', self._connect_audio_converter)
+        self.audioconvert.link(self.audioresample)
+        self.audioresample.link(self.tee)
+
+        self.tee.link(self.audiosink)
+        self.tee.link(self.asr)
+
+        self.asr.link(self.datasink)
+
+        # Create bus and connect several handlers
+        self.bus = self.pipeline.get_bus()
+        self.bus.add_signal_watch()
+        self.bus.enable_sync_message_emission()
+        self.bus.connect('message::eos', self._on_eos)
+        self.bus.connect('message::error', self._on_error)
+
+        self.asr.connect('interim-result', self._on_interim_result)
+        self.asr.connect('final-result', self._on_final_result)
+
+        logger.info("Setting pipeline to READY")
+        self.pipeline.set_state(Gst.State.READY)
+        logger.info("Set pipeline to READY")
+
+    def _load_configuration(self, conf):
+        conf['decoder_executable'] = os.path.dirname(os.path.realpath(__file__)) + "/decoders/" + conf['decoder'] + "/decoder"
+        conf['decoder_configuration'] = subprocess.check_output([os.path.dirname(os.path.realpath(__file__)) + "/decoders/" + conf['decoder'] + "/configure"])
+        return conf
+
+    def _connect_audio_converter(self, element, pad):
+        logger.info("%s: Connecting audio converter" % self.request_id)
+        pad.link(self.audioconvert.get_static_pad("sink"))
+
+    def _on_eos(self, bus, msg):
+        logger.info("%s: Received EOS signal from decoder" % self.request_id)
+        self.finish_request()
+        if self.eos_handler:
+            self.eos_handler()
+
+    def _on_error(self, bus, msg):
+        error = msg.parse_error()
+        logger.error(error)
+        self.finish_request()
+        if self.error_handler:
+            self.error_handler(error[0].message)
+
+    def _on_interim_result(self, asr, hyp, duration):
+        logger.info("%s: Received interim result from decoder" % (self.request_id))
+        if self.interim_result_handler:
+            self.interim_result_handler(hyp, duration)
+
+    def _on_final_result(self, asr, hyp, duration, context):
+        logger.info("%s: Received final result from decoder %s" % (self.request_id, hyp))
+        if self.final_result_handler:
+            self.final_result_handler(hyp, duration, context)
+
+    def finish_request(self):
+        logger.info("%s: Resetting decoder state" % self.request_id)
+        self.audiosink.set_state(Gst.State.NULL)
+        self.audiosink.set_property("location", "/dev/null")
+        self.audiosink.set_state(Gst.State.PAUSED)
+        self.datasink.set_state(Gst.State.NULL)
+        self.datasink.set_property("location", "/dev/null")
+        self.datasink.set_state(Gst.State.PAUSED)
+        self.pipeline.set_state(Gst.State.PAUSED)
+        self.request_id = ""
+
+    def init_request(self, id, caps_str, context="{}"):
+        self.pipeline.set_state(Gst.State.PAUSED)
+        self.request_id = id
+        logger.info("%s: Initializing request" % (self.request_id))
+        if caps_str and len(caps_str) > 0:
+            logger.info("%s: Setting caps to %s" % (self.request_id, caps_str))
+            caps = Gst.caps_from_string(caps_str)
+            self.appsrc.set_property("caps", caps)
+        else:
+            self.appsrc.set_property("caps", None)
+
+        self.asr.set_property("message_context", context)
+
+        self.audiosink.set_state(Gst.State.NULL)
+        self.audiosink.set_property('location', "%s/%s.raw" % (self.data_directory, id))
+        self.audiosink.set_state(Gst.State.PAUSED)
+
+        self.datasink.set_state(Gst.State.NULL)
+        self.datasink.set_property('location', "%s/%s.transcript" % (self.data_directory, id))
+        self.datasink.set_state(Gst.State.PAUSED)
+
+        self.pipeline.set_state(Gst.State.PLAYING)
+
+    def process_data(self, data):
+        logger.debug('%s: Pushing buffer of size %d to decoder' % (self.request_id, len(data)))
+        buf = Gst.Buffer.new_allocate(None, len(data), None)
+        buf.fill(0, data)
+        self.appsrc.emit("push-buffer", buf)
+
+    def end_request(self):
+        logger.info("%s: Pushing EOS to pipeline" % self.request_id)
+        self.appsrc.emit("end-of-stream")
+
+    def set_interim_result_handler(self, handler):
+        self.interim_result_handler = handler
+
+    def set_final_result_handler(self, handler):
+        self.final_result_handler = handler
+
+    def set_eos_handler(self, handler):
+        self.eos_handler = handler
+
+    def set_error_handler(self, handler):
+        self.error_handler = handler
+
+    def cancel(self):
+        self.end_request()
+        id = self.request_id
+        self.finish_request()
+        try:
+            os.remove("%s/%s.raw" % (self.data_directory, id))
+            os.remove("%s/%s.transcript" % (self.data_directory, id))
+        finally:
+            pass
diff --git a/lucida/speechrecognition/decoders/wit/Makefile b/lucida/speechrecognition/decoders/wit/Makefile
new file mode 100644
index 000000000..ed11fd0d4
--- /dev/null
+++ b/lucida/speechrecognition/decoders/wit/Makefile
@@ -0,0 +1,6 @@
+all:
+	python -O -m py_compile decoder.py
+	mv decoder.pyo decoder
+	chmod a+x decoder
+
+.PHONY:	all
diff --git a/lucida/speechrecognition/decoders/wit/configure b/lucida/speechrecognition/decoders/wit/configure
new file mode 100755
index 000000000..50c238027
--- /dev/null
+++ b/lucida/speechrecognition/decoders/wit/configure
@@ -0,0 +1,3 @@
+#!/bin/bash
+
+echo "{\"command\":\"conf\",\"api-version\":\"14/06/2017\",\"api-token\":\"TOKEN_HERE\",\"request-timeout\":30}"
diff --git a/lucida/speechrecognition/decoders/wit/decoder b/lucida/speechrecognition/decoders/wit/decoder
new file mode 100755
index 0000000000000000000000000000000000000000..a3e3a566bf00dffe33f27e62d5065428fa7d3f2f
GIT binary patch
literal 6515
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
SSGvl{ZyiuicxT5Zz5fB0!|_l6

literal 0
HcmV?d00001

diff --git a/lucida/speechrecognition/decoders/wit/decoder.py b/lucida/speechrecognition/decoders/wit/decoder.py
new file mode 100644
index 000000000..c0d3a29fd
--- /dev/null
+++ b/lucida/speechrecognition/decoders/wit/decoder.py
@@ -0,0 +1,157 @@
+"""
+Created on Jun 14 2017
+
+@author: kamal1210
+"""
+from __future__ import print_function
+
+import os, stat, sys, time, threading, json
+sys.path.insert(0, "/usr/local/src/lucida/lucida/speechrecognition/include")
+
+import requests, click
+import defs
+
+class SpeechDecoder(object):
+
+    def _send_event(self, type, status, data):
+        message = {'event': type, 'status': status, 'data': data}
+        self.send_event_lock.acquire()
+        try:
+            print(json.dumps(message))
+            sys.stdout.flush()
+        except IOError:
+            pass
+        self.send_event_lock.release()
+
+    def _post_data_gen(self):
+        self._send_event("debug", defs.SUCCESS_OK, "Begin data generator %s" % self.audio_src)
+        try:
+            fifo = open(self.audio_src, "r", 0)
+            while True:
+                data = fifo.read(4096)
+                if len(data) == 0:
+                    break
+                yield data
+        finally:
+            fifo.close()
+        self.stopped_listening_at = time.time()
+        self.state = defs.DECODER_STATE_DECODING
+        self._send_event("debug", defs.SUCCESS_OK, "End data generator")
+
+    def _post_req_gen(self):
+        self.state = defs.DECODER_STATE_LISTENING
+        self._send_event("debug", defs.SUCCESS_OK, "Begin request generator")
+        response = requests.post(self.api_host, headers=self.headers, data=self._post_data_gen())
+        self._send_event("debug", defs.SUCCESS_OK, "Waiting for response")
+        if response.status_code == 200:
+            response_json = json.loads(response.text)
+            self._send_event("final_result", defs.SUCCESS_OK, response_json['_text'])
+        else:
+            self._send_event("debug", defs.SUCCESS_OK, response.text)
+            response_json = json.loads(response.text)
+            self._send_event("error", defs.ERROR_GENERIC, response_json['error'])
+        self.state = defs.DECODER_STATE_READY
+        self._send_event("debug", defs.SUCCESS_OK, "End request generator")
+
+    def _post_req_ctrl(self):
+        self._send_event("debug", defs.SUCCESS_OK, "Begin request control")
+        self.request_generator = threading.Thread(target=self._post_req_gen)
+        self.request_generator.daemon = True
+        self.request_generator.start()
+        while self.state == defs.DECODER_STATE_READY:
+            time.sleep(1)
+        while self.state == defs.DECODER_STATE_LISTENING:
+            time.sleep(1)
+        while self.state == defs.DECODER_STATE_DECODING:
+            if time.time() - self.stopped_listening_at > self.request_timeout:
+                self._send_event("error", defs.ERROR_TIMED_OUT, "Request to %s timed out!!!" % self.api_host)
+#                self.request_generator.stop()
+                self.state = defs.DECODER_STATE_READY
+            time.sleep(1)
+        self._send_event("debug", defs.SUCCESS_OK, "End request control")
+
+    def conf(self, message):
+        if self.state == defs.DECODER_STATE_CREATED or self.state == defs.DECODER_STATE_READY :
+            try:
+                _api_token       = message["api-token"]
+                _api_version     = message["api-version"]
+                _request_timeout = int(message["request-timeout"])
+            except Exception as e:
+                self._send_event("error", defs.ERROR_INVALID_CONFIG, "Required key '%s' not found in configuration message!!!" % e.message)
+                return
+
+            response = requests.get("https://api.wit.ai/message?q=hello&v=" + _api_version, headers={'Authorization': 'Bearer ' + _api_token})
+            if response.status_code != 200:
+                self._send_event("error", defs.ERROR_INVALID_CONFIG, "Invalid credentials for API host '%s'!!!" % _api_host)
+                return
+
+            self.headers         = {'Authorization': 'Bearer ' + _api_token, 'Content-Type': 'audio/raw;encoding=signed-integer;bits=16;rate=16000;endian=little', 'Accept': 'application/json', 'Transfer-Encoding': 'chunked'}
+            self.api_host        = "https://api.wit.ai/speech?v=" + _api_version
+            self.request_timeout = _request_timeout
+            self.state           = defs.DECODER_STATE_READY
+            return
+        self._send_event("warn", defs.WARN_GENERIC, "Configuration message received while decoding!!! Ignoring message...")
+
+    def context(self, message):
+        # Handle context
+        pass
+
+    def start(self, message):
+        self.request_controller = threading.Thread(target=self._post_req_ctrl)
+        self.request_controller.daemon = True
+        self.request_controller.start()
+
+    def clear(self, message):
+#        try:
+#            self.request_generator.stop()
+#        except:
+#            pass
+#        try:
+#            self.request_controller.stop()
+#        except:
+#            pass
+        self._send_event("warn", defs.WARN_RESET, "Decoder was reset!!! All data cleared")
+        self.state = defs.DECODER_STATE_READY
+
+    def __init__(self, ctrl, data):
+        self.send_event_lock = threading.Lock()
+
+        if not os.path.exists(ctrl) or not stat.S_ISFIFO(os.stat(ctrl).st_mode):
+            self._send_event("error", defs.ERROR_NOT_A_FIFO, "Control source '%s' is not a named pipe!!!" % ctrl)
+            sys.exit(1)
+        else:
+            self.ctrl_src = ctrl
+
+        if not os.path.exists(data) or not stat.S_ISFIFO(os.stat(data).st_mode):
+            self._send_event("error", defs.ERROR_NOT_A_FIFO, "Audio source '%s' is not a named pipe!!!" % data)
+            sys.exit(1)
+        else:
+            self.audio_src = data
+
+        self.state = defs.DECODER_STATE_CREATED
+
+    def event_listener(self):
+        while True:
+            with open(self.ctrl_src, 'r') as fifo:
+                line = fifo.readline()
+                self._send_event("debug", defs.SUCCESS_OK, "Received %s" % line)
+                try:
+                    message = json.loads(line)
+                    if "command" in message:
+                        getattr(self, message["command"])(message)
+                except Exception as e:
+                    self._send_event("error", defs.ERROR_CONTROL_MESSAGE, "'%s' is not a valid control message!!! %s" % (line, e.message))
+            time.sleep(1)
+
+@click.command()
+@click.option('--ctrl', '-c', required=True,
+              metavar='', help='Path to control FIFO')
+@click.option('--data', '-d', required=True,
+              metavar='', help='Path to data FIFO')
+def main(ctrl, data):
+    decoder = SpeechDecoder(ctrl, data)
+    decoder.event_listener()
+
+if __name__ == "__main__":
+    main()
+
diff --git a/lucida/speechrecognition/include/defs.h b/lucida/speechrecognition/include/defs.h
new file mode 100644
index 000000000..461eb62ef
--- /dev/null
+++ b/lucida/speechrecognition/include/defs.h
@@ -0,0 +1,16 @@
+#define DECODER_STATE_CREATED   0
+#define DECODER_STATE_READY     1
+#define DECODER_STATE_LISTENING 2
+#define DECODER_STATE_DECODING  3
+
+#define SUCCESS_OK              200
+
+#define ERROR_GENERIC           400
+#define ERROR_CONTROL_MESSAGE   422
+#define ERROR_INVALID_CONFIG    403
+#define ERROR_NOT_A_FIFO        424
+#define ERROR_TIMED_OUT         408
+
+#define WARN_GENERIC            800
+#define WARN_RESET              810
+
diff --git a/lucida/speechrecognition/include/defs.py b/lucida/speechrecognition/include/defs.py
new file mode 100644
index 000000000..762a39a9b
--- /dev/null
+++ b/lucida/speechrecognition/include/defs.py
@@ -0,0 +1,16 @@
+DECODER_STATE_CREATED   = 0
+DECODER_STATE_READY     = 1
+DECODER_STATE_LISTENING = 2
+DECODER_STATE_DECODING  = 3
+
+SUCCESS_OK              = 200
+
+ERROR_GENERIC           = 400
+ERROR_CONTROL_MESSAGE   = 422
+ERROR_INVALID_CONFIG    = 403
+ERROR_NOT_A_FIFO        = 424
+ERROR_TIMED_OUT         = 408
+
+WARN_GENERIC            = 800
+WARN_RESET              = 810
+
diff --git a/lucida/speechrecognition/kaldi_gstreamer_asr/.gitignore b/lucida/speechrecognition/kaldi_gstreamer_asr/.gitignore
deleted file mode 100755
index 858a701bf..000000000
--- a/lucida/speechrecognition/kaldi_gstreamer_asr/.gitignore
+++ /dev/null
@@ -1,5 +0,0 @@
-kaldi
-tmp
-test/models/english/fisher_nnet_a_gpu_online
-test/models/english/tedlium_nnet_ms_sp_online
-lucida-demos
diff --git a/lucida/speechrecognition/kaldi_gstreamer_asr/Dockerfile b/lucida/speechrecognition/kaldi_gstreamer_asr/Dockerfile
deleted file mode 100644
index b9a44456d..000000000
--- a/lucida/speechrecognition/kaldi_gstreamer_asr/Dockerfile
+++ /dev/null
@@ -1,13 +0,0 @@
-####
-# based on the lucida base image
-FROM lucida_base
-
-#### environment variables
-ENV LUCIDAROOT /usr/local/lucida/lucida
-ENV LD_LIBRARY_PATH /usr/local/lib
-
-## install ASR
-RUN mkdir -p /usr/local/lucida/lucida/speechrecognition/kaldi_gstreamer_asr
-ADD . /usr/local/lucida/lucida/speechrecognition/kaldi_gstreamer_asr
-WORKDIR "/usr/local/lucida/lucida/speechrecognition/kaldi_gstreamer_asr"
-RUN /bin/bash install_kaldi.sh
diff --git a/lucida/speechrecognition/kaldi_gstreamer_asr/LICENSE b/lucida/speechrecognition/kaldi_gstreamer_asr/LICENSE
deleted file mode 100644
index f2637bc5c..000000000
--- a/lucida/speechrecognition/kaldi_gstreamer_asr/LICENSE
+++ /dev/null
@@ -1,23 +0,0 @@
-Copyright (c) 2014, alumae
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
-
-* Redistributions of source code must retain the above copyright notice, this
-  list of conditions and the following disclaimer.
-
-* Redistributions in binary form must reproduce the above copyright notice, this
-  list of conditions and the following disclaimer in the documentation and/or
-  other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
-ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\ No newline at end of file
diff --git a/lucida/speechrecognition/kaldi_gstreamer_asr/Makefile b/lucida/speechrecognition/kaldi_gstreamer_asr/Makefile
deleted file mode 100644
index 77bb38c1a..000000000
--- a/lucida/speechrecognition/kaldi_gstreamer_asr/Makefile
+++ /dev/null
@@ -1,13 +0,0 @@
-all:
-	./install_kaldi.sh
-
-start_master_server:
-	gnome-terminal -x bash -c "source ${PWD}/../../../tools/python_2_7_12/bin/activate && python kaldigstserver/master_server.py --port=8081; read -n1"
-
-start_server:
-	./simple_start.sh
-
-start_test:
-	gnome-terminal -x bash -c "source ${PWD}/../../../tools/python_2_7_12/bin/activate && python kaldigstserver/client.py -r 8192 test/data/bill_gates-TED.mp3; read -n1"
-
-.PHONY:	all start_server start_test
diff --git a/lucida/speechrecognition/kaldi_gstreamer_asr/README.md b/lucida/speechrecognition/kaldi_gstreamer_asr/README.md
deleted file mode 100644
index 5eb9b8bca..000000000
--- a/lucida/speechrecognition/kaldi_gstreamer_asr/README.md
+++ /dev/null
@@ -1,394 +0,0 @@
-Kaldi GStreamer server
-======================
-[![GitHub license](https://img.shields.io/github/license/alumae/kaldi-gstreamer-server.svg)](https://github.com/alumae/kaldi-gstreamer-server/blob/master/LICENSE)
-[![Code Climate](https://img.shields.io/codeclimate/github/alumae/kaldi-gstreamer-server.svg)](https://codeclimate.com/github/alumae/kaldi-gstreamer-server)
-
-This is a real-time full-duplex speech recognition server, based on
-the Kaldi toolkit and the GStreamer framework and implemented in Python.
-
-Notes for Lucida Users
-======================
-
-Build
---------
-
-```
-make
-```
-
-It runs `install_kaldi.sh` only if the directory `kaldi` does not exist.
-Therefore, if previous intallation fails, please remove this directory and compile again.
-It may take up to 4 hours to complete.
-
-Run
---------
-
-Start the master server followed by the worker:
-
-```
-make start_master_server
-make start_server
-```
-
-Wait until you see `Opened websocket connection to server` from the worker.`
-
-Test
---------
-
-Test the installtion process:
-
-```
-make start_test
-```
-
-If you see results popping up, it should be ready to go.
-
-Text to Speech
---------
-
-In addition to the speech recognition service, we provide a text-to-speech (TTS) service based on [kaldi idlak](https://github.com/bpotard/idlak). 
-Currently, it is experimental because our web front end uses the [web APIs](https://developer.mozilla.org/en-US/docs/Web/API/SpeechSynthesis) to perform voice synthesis. 
-However, you are welcome to use this service by running the script `install_kaldi_tts.sh`.
-It installs both the kaldi toolkit (~4 hours for C++ compilation) and the idlak component (~4 hours for DNN training), and at the end of this process, we provide one way to use it --
-convert text input from command line to audio file saved on disk.
-
-(End of Notes for Lucida Users)
-
-Features
---------
-
-  * Full duplex communication based on websockets: speech goes in, partial hypotheses come out (think of Android's voice typing)
-  * Very scalable: the server consists of a master component and workers; one worker is needed per concurrent recognition session; workers can be
-    started and stopped independently of the master on remote machines
-  * Can do speech segmentation, i.e., a long speech signal is broken into shorter segments based on silences
-  * Supports arbitrarily long speech input (e.g., you can stream live speech into it)
-  * Supports Kaldi's GMM and "online DNN" models
-  * Supports rescoring of the recognition lattice with a large language model
-  * Supports persisting the acoustic model adaptation state between requests
-  * Supports unlimited set of audio codecs (actually only those supported by GStreamer)
-  * Supports rewriting raw recognition results using external programs (can be used for converting words to numbers, etc)
-  * Python, Java, Javascript clients are available
-
-English demo that uses the server: http://bark.phon.ioc.ee/dictate/
-
-Estonian demo: http://bark.phon.ioc.ee/dikteeri/
-
-Changelog
----------
-  * 2015-12-04: added a link to the Dockerfile.
-
-  * 2015-06-30: server now uses the recently added "full final results" functionality of gst-kaldi-nnet2-online.
-  Full results can include things like n-best hypotheses, word and phone alignment information, 
-  and possibly other things in the future. You have to upgrade gst-kaldi-nnet2-online (when using this plugin instead of
-  the GMM-based Kaldi GStreamer plugin) prior to using this. Also added a sample full results post-processing
-  script `sample_full_post_processor.py` (see `sample_english_nnet2.yaml` on how to use it).
-  
-  
-
-Installation
-------------
-
-### Docker
-
-Building Kaldi and all the other packages required by this software can be quite complicated. Instead of building
-all the prerequisites manually, one could use the Dockerfile created by José Eduardo Silva: https://github.com/jcsilva/docker-kaldi-gstreamer-server.
-
-### Requirements
-
-#### Python 2.7 with the following packages:
-
-  * Tornado 4, see http://www.tornadoweb.org/en/stable/
-  * ws4py (0.3.0 .. 0.3.2)
-  * YAML
-  * JSON
-
-*NB!*: The server doesn't work quite correctly with ws4py 0.3.5 because of a bug I reported here: https://github.com/Lawouach/WebSocket-for-Python/issues/152.
-Use ws4py 0.3.2 instead. To install ws4py 0.3.2 using `pip`, run:
-
-    pip install ws4py==0.3.2
-
-In addition, you need Python 2.x bindings for gobject-introspection libraries, provided by the `python-gi`
-package on Debian and Ubuntu.
-
-#### Kaldi
-
-Download and compile Kaldi (http://kaldi.sourceforge.net). Also compile the online extensions (`make ext`)
-and the Kaldi GStreamer plugin (see `README` in Kaldi's `src/gst-plugin` directory).
-
-#### Acoustic and language models for Kaldi
-
-You need GMM-HMM-based acoustic and n-gram language models (actually their FST cascade) for your language.
-
-Working (but not very accurate) recognition models are available for English and Estonian in the  `test/models/` directory.
-English models are based on Voxforge acoustic models and the CMU Sphinx  2013 general English trigram language model (http://cmusphinx.sourceforge.net/2013/01/a-new-english-language-model-release/).
-The language models were heavily pruned so that the resulting FST cascade would be less than the
-100 MB GitHub file size limit.
-
-*Update:* the server also supports Kaldi's new "online2" online decoder that uses DNN-based acoustic models with i-vector input. See below on
-how to use it. According to experiments on two Estonian online decoding setups, the DNN-based models result in about 20% (or more) relatively less
-errors than GMM-based models (e.g., WER dropped from 13% to 9%).
-
-
-Running the server
-------------------
-
-### Running the master server
-
-The following starts the main server on localhost:8888
-
-    python kaldigstserver/master_server.py --port=8888
-
-### Running workers
-
-
-The master server doesn't perform speech recognition itself, it simply delegates client recognition
-requests to workers. You need one worker per recognition session. So, the number of running workers
-should be at least the number of potential concurrent recognition sessions. Good thing is that
-workers are fully independent and do not even have to be running on the same machine, thus
-offering practically unlimited parallelness.
-
-There are two decoders that a worker can use: based on the Kaldi `onlinegmmdecodefaster` GStreamer plugin
-or based on the newer `kaldinnet2onlinedecoder` plugin. The first one supports GMM models, the latter one needs
-"online2" DNN-based models with i-vector input.
-
-To run a worker, first write a configuration file. A sample configuration that uses the English GMM-HMM
-models that come with this project is available in `sample_worker.yaml`. A sample worker that uses
-"online2" DNN-based models is in `sample_english_nnet2.yaml`.
-
-#### Using the 'onlinegmmdecodefaster' based worker
-
-Before starting a worker, make sure that the GST plugin path includes Kaldi's `src/gst-plugin` directory
-(which should contain the file `libgstkaldi.so`), something like:
-
-    export GST_PLUGIN_PATH=~/tools/kaldi-trunk/src/gst-plugin
-
-Test if it worked:
-
-    gst-inspect-1.0 onlinegmmdecodefaster
-
-The latter should print out information about the Kaldi's GStreamer plugin.
-
-Now, you can start a worker:
-
-    python kaldigstserver/worker.py -u ws://localhost:8888/worker/ws/speech -c sample_worker.yaml
-
-The `-u ws://localhost:8890/worker/ws/speech` argument specifies the address of the main server
-that the worker should connect to. Make sure you are using the same port as in the server invocation.
-
-You can start any number of worker processes, just use the same command to start the next workers.
-
-It might be a good idea to use [supervisord](http://supervisord.org) to start and stop the main server and
-several workers. A sample supervisord configuration file is in `etc/english-supervisord.conf`.
-
-Server usage
-------------
-
-A sample implementation of the client is in `kaldigstserver/client.py`.
-
-If you started the server/worker as described above, you should be able to test the installation by invoking:
-
-    python kaldigstserver/client.py -r 32000 test/data/english_test.raw
-
-Expected output:
-
-    THE. ONE TWO THREE FOUR FIVE SIX SEVEN EIGHT.
-
-Expected output when using using the DNN-based online models based on Fisher:
-
-    one two or three you fall five six seven eight. yeah.
-
-The `-r 32000` in the last command tells the client to send audio to the server at 32000 bytes per second. The raw
-sample audio file uses a sample rate of 16k with a 16-bit encoding which results in a byterate of 32000.
-
-You can also send ogg audio:
-
-    python kaldigstserver/client.py -r 4800 test/data/english_test.ogg
-
-The rate in the last command is 4800. The bit rate of the ogg file is 37.5k, which results in a byte rate of 4800.
-
-
-Using the 'kaldinnet2onlinedecoder' based worker
-------------------------------------------------
-
-The DNN-based online decoder requires a newer GStreamer plugin that is not in the Kaldi codebase and has to be compiled
-seperately. It's available at https://github.com/alumae/gst-kaldi-nnet2-online. Clone it, e.g., under `~/tools/gst-kaldi-nnet2-online`.
-Follow the instuctions and compile it. This should result in a file `~/tools/gst-kaldi-nnet2-online/src/libgstkaldionline2.so`.
-
-Also, download the DNN-based models for English, trained on the TEDLIUM speech corpus and combined with a generic English language model
-provided by Cantab Research. Run the `download-tedlium-nnet2.sh` under `test/models` to download the models (attention, 1.5 GB):
-
-    ./test/models/download-tedlium-nnet2.sh
-
-Before starting a worker, make sure that the GST plugin path includes the path where the `libgstkaldionline2.so` library you compiled earlier
-resides, something like:
-
-    export GST_PLUGIN_PATH=~/tools/gst-kaldi-nnet2-online/src
-
-Test if it worked:
-
-    gst-inspect-1.0 kaldinnet2onlinedecoder
-
-The latter should print out information about the new Kaldi's GStreamer plugin.
-
-Now, you can start a worker:
-
-    python kaldigstserver/worker.py -u ws://localhost:8888/worker/ws/speech -c sample_english_nnet2.yaml
-
-As the acoustic models are trained on TED data, we also test on TED data. The file `test/data/bill_gates-TED.mp3` contains about one
-minute of a TED talk by Bill Gates. It's encoded as 64 kb MP3, so let's send it to the server at 64*1024/8=8192 bytes per second:
-
-    python kaldigstserver/client.py -r 8192 test/data/bill_gates-TED.mp3
-
-Recognized words should start appearing at the terminal. The final result should be something like:
-
-> when i was a kid the disaster we worry about most was a nuclear war. that's why we had a bear like this down our basement filled with cans of food and water. nuclear attack came we were supposed to go downstairs hunker down and eat out of that barrel. today the greatest risk of global catastrophe. don't look like this instead it looks like this. if anything kills over ten million people in the next few decades it's most likely to be a highly infectious virus rather than a war. not missiles that microbes now part of the reason for this is that we have invested a huge amount in nuclear deterrence we've actually invested very little in a system to stop an epidemic. we're not ready for the next epidemic.
-
-Compare that to the original transcript in `test/data/bill_gates-TED.txt`:
-
-> When I was a kid, the disaster we worried about most was a nuclear war. That's why we had a barrel like this down in our basement, filled with cans of food and water. When the nuclear attack came, we were supposed to go downstairs, hunker down, and eat out of that barrel.
-> Today the greatest risk of global catastrophe doesn't look like this. Instead, it looks like this. If anything kills over 10 million people in the next few decades, it's most likely to be a highly infectious virus rather than a war. Not missiles, but microbes. Now, part of the reason for this is that we've invested a huge amount in nuclear deterrents. But we've actually invested very little in a system to stop an epidemic. We're not ready for the next epidemic.
-
-
-#### Retrieving and sending adaptation state ####
-
-If you use the 'kaldinnet2onlinedecoder' based worker, you can retrieve the adaptation state after the decoding session
-finishes, and send the previously retrieved adaptation state when starting a new session.
-
-The 'kaldinnet2onlinedecoder' worker always sends the adaptation state encoded in a JSON container once the session ends. Client
-can store it in a file. This is functionality is implemented by the `client.py`. Assuming that you started the server and a worker as in the last
-example, you can do:
-
-    python kaldigstserver/client.py -r 32000 --save-adaptation-state adaptation-state.json test/data/english_test.wav
-
-The `adaptation-state.json` file will contain something like this:
-
-    {"type": "string+gzip+base64", "value": "eJxlvUuPdEmSHbavXx...", "time": "2014-11-14T11:08:49"}
-
-As you can see, the adaptation state is not human-readable, it's actually gzipped and base64-encoded text data.
-
-To start another decoding session using the saved adaptation state, you can do something like this:
-
-    python kaldigstserver/client.py -r 32000 --send-adaptation-state adaptation-state.json test/data/english_test.wav
-
-
-
-Alternative usage through a HTTP API
----------------------------------------
-
-One can also use the server through a very simple HTTP-based API. This allows to simply send audio via a PUT or POST request
-to http://server:port/client/dynamic/recognize and read the JSON ouput. Note that the JSON output is differently structured
-than the output of the websocket-based API. This interface is compatible to the one implemented by http://github.com/alumae/ruby-pocketsphinx-server.
-
-The HTTP API supports chunked transfer encoding which means that server can read and decode an audio stream before it is complete.
-
-Example:
-
-Send audio to server:
-
-     curl  -T test/data/english_test.wav  "http://localhost:8888/client/dynamic/recognize"
-
-Output:
-
-    {"status": 0, "hypotheses": [{"utterance": "one two or three you fall five six seven eight. [noise]."}], "id": "7851281f-e187-4c24-9b58-4f3a5cba3dce"}
-
-Send audio using chunked transfer encoding at an audio byte rate; you can see from the worker logs that decoding starts already when the first chunks
-have been received:
-
-    curl -v -T test/data/english_test.raw -H "Content-Type: audio/x-raw-int; rate=16000" --header "Transfer-Encoding: chunked" --limit-rate 32000  "http://localhost:8888/client/dynamic/recognize"
-
-Output (like before):
-
-    {"status": 0, "hypotheses": [{"utterance": "one two or three you fall five six seven eight. yeah."}], "id": "4e4594ee-bdb2-401f-8114-41a541d89eb8"}
-
-
-Websocket-based client-server protocol
-----------------------
-
-### Opening a session
-
-To open a session, connect to the specified server websocket address (e.g. ws://localhost:8888/client/ws/speech).
-The server assumes by default that incoming audio is sent using 16 kHz, mono, 16bit little-endian format. This can be overriden
-using the 'content-type' request parameter. The content type has to be specified using GStreamer 1.0 caps format,
-e.g. to send 44100 Hz mono 16-bit data, use: "audio/x-raw, layout=(string)interleaved, rate=(int)44100, format=(string)S16LE, channels=(int)1".
-This needs to be url-encoded of course, so the actual request is something like:
-
-    ws://localhost:8888/client/ws/speech?content-type=audio/x-raw,+layout=(string)interleaved,+rate=(int)44100,+format=(string)S16LE,+channels=(int)1
-
-Audio can also be encoded using any codec recognized by GStreamer (assuming the needed packages are installed on the server).
-GStreamer should recognize the container and codec automatically from the stream, you don't have to specify the content type.
-E.g., to send audio encoded using the Speex codec in an Ogg container, use the following URL to open the session (server should
-automatically recognize the codec):
-
-    ws://localhost:8888/client/ws/speech
-
-### Sending audio
-
-Speech should be sent to the server in raw blocks of data, using the encoding specified when session was opened.
-It is recommended that a new block is sent at least 4 times per second (less frequent blocks would increase the recognition lag).
-Blocks do not have to be of equal size.
-
-After the last block of speech data, a special 3-byte ANSI-encoded string "EOS"  ("end-of-stream") needs to be sent to the server. This tells the
-server that no more speech is coming and the recognition can be finalized.
-
-After sending "EOS", client has to keep the websocket open to receive recognition results from the server. Server
-closes the connection itself when all recognition results have been sent to the client.
-No more audio can be sent via the same websocket after an "EOS" has been sent. In order to process a new
-audio stream, a new websocket connection has to be created by the client.
-
-### Reading results
-
-Server sends recognition results and other information to the client using the JSON format.
-The response can contain the following fields:
-
-  * status -- response status (integer), see codes below
-  * message -- (optional) status message
-  * result -- (optional) recognition result, containing the following fields:
-    - hypotheses - recognized words, a list with each item containing the following:
-        + transcript -- recognized words
-        + confidence -- (optional) confidence of the hypothesis (float, 0..1)
-    - final -- true when the hypothesis is final, i.e., doesn't change any more
-
-The following status codes are currently in use:
-
-  * 0 -- Success. Usually used when recognition results are sent
-  * 2 -- Aborted. Recognition was aborted for some reason.
-  * 1 -- No speech. Sent when the incoming audio contains a large portion of silence or non-speech.
-  * 9 -- Not available. Used when all recognizer processes are currently in use and recognition cannot be performed.
-
-Websocket is always closed by the server after sending a non-zero status update.
-
-Examples of server responses:
-
-    {"status": 9}
-    {"status": 0, "result": {"hypotheses": [{"transcript": "see on"}], "final": false}}
-    {"status": 0, "result": {"hypotheses": [{"transcript": "see on teine lause."}], "final": true}}
-
-Server segments incoming audio on the fly. For each segment, many non-final hypotheses, followed by one final
-hypothesis are sent. Non-final hypotheses are used to present partial recognition hypotheses
-to the client. A sequence of non-final hypotheses is always followed by a final hypothesis for that segment.
-After sending a final hypothesis for a segment,
-server starts decoding the next segment, or closes the connection, if all audio sent by the client has been processed.
-
-Client is reponsible for presenting the results to the user in a way
-suitable for the application.
-
-Client software
----------------
-
-Javascript client is available here: http://kaljurand.github.io/dictate.js
-
-Citing
-------
-
-If you use this software for research, you can cite the paper where this software is
-described (available here: http://ebooks.iospress.nl/volumearticle/37996):
-
-    @inproceedigs{alumae2014,
-      author={Tanel Alum\"{a}e},
-      title="Full-duplex Speech-to-text System for {Estonian}",
-      booktitle="Baltic HLT 2014",
-      year=2014,
-      address="Kaunas, Lihtuania"
-    }
-
-Of course, you should also acknowledge Kaldi, which does all the hard work.
diff --git a/lucida/speechrecognition/kaldi_gstreamer_asr/estonian_worker.yaml b/lucida/speechrecognition/kaldi_gstreamer_asr/estonian_worker.yaml
deleted file mode 100644
index 4b5fab95c..000000000
--- a/lucida/speechrecognition/kaldi_gstreamer_asr/estonian_worker.yaml
+++ /dev/null
@@ -1,29 +0,0 @@
-timeout-decoder : 10
-decoder:
-   model: test/models/estonian/tri2b_mmi_pruned/final.mdl
-   lda-mat: test/models/estonian/tri2b_mmi_pruned/final.mat
-   word-syms: test/models/estonian/tri2b_mmi_pruned/words.txt
-   fst: test/models/estonian/tri2b_mmi_pruned/HCLG.fst
-   silence-phones: 6
-out-dir: tmp
-
-use-vad: True
-silence-timeout: 60
-
-# Reconstructs compound words. Requires SRILM. Just comment out when no SRILM available.
-post-processor: hidden-ngram -hidden-vocab test/models/estonian/compounder/hidden.vocab -lm test/models/estonian/compounder/compounder-pruned.vestlused-dev.splitw.arpa.gz  -text - -keep-unk | perl -npe 'BEGIN {use IO::Handle; STDOUT->autoflush(1);} s/ ?\+C\+ ?//g; s/ ?\+D\+ ?/-/g;'
-logging:
-    version : 1
-    disable_existing_loggers: False
-    formatters:
-        simpleFormater:
-            format: '%(asctime)s - %(levelname)7s: %(name)10s: %(message)s'
-            datefmt: '%Y-%m-%d %H:%M:%S'
-    handlers:
-        console:
-            class: logging.StreamHandler
-            formatter: simpleFormater
-            level: DEBUG
-    root:
-        level: DEBUG
-        handlers: [console]
diff --git a/lucida/speechrecognition/kaldi_gstreamer_asr/etc/english-supervisord.conf b/lucida/speechrecognition/kaldi_gstreamer_asr/etc/english-supervisord.conf
deleted file mode 100644
index 24fe6b9e7..000000000
--- a/lucida/speechrecognition/kaldi_gstreamer_asr/etc/english-supervisord.conf
+++ /dev/null
@@ -1,21 +0,0 @@
-; Sample supervisord configuration for kaldi-gstreamer-server.
-; Modify according to you needs and put under /etc/supervisor/conf.d/
-
-[program:full-duplex-english-server]
-command = /usr/bin/python2.7 /home/tanel/devel/kaldi-gstreamer-server/kaldigstserver/master_server.py --port=8890
-user = tanel
-redirect_stderr = true
-stdout_logfile = /home/tanel/service/duplex-speech/english/server.log
-environment= GST_PLUGIN_PATH="/home/tanel/tools/kaldi-trunk/src/gst-plugin"
-directory = /home/tanel/service/duplex-speech/english
-
-[program:full-duplex-english-worker]
-command = /usr/bin/python2.7 /home/tanel/devel/kaldi-gstreamer-server/kaldigstserver/worker.py -u ws://localhost:8890/worker/ws/speech -c worker.yaml
-numprocs = 5
-process_name=%(program_name)s-%(process_num)s
-user = tanel
-redirect_stderr = true
-stdout_logfile = /home/tanel/service/duplex-speech/english/worker-%(process_num)s.log
-environment= GST_PLUGIN_PATH="/home/tanel/tools/kaldi-trunk/src/gst-plugin",LC_ALL="en_US.UTF8"
-directory = /home/tanel/service/duplex-speech/english
-
diff --git a/lucida/speechrecognition/kaldi_gstreamer_asr/install_idlak.sh b/lucida/speechrecognition/kaldi_gstreamer_asr/install_idlak.sh
deleted file mode 100755
index ca8e3cee9..000000000
--- a/lucida/speechrecognition/kaldi_gstreamer_asr/install_idlak.sh
+++ /dev/null
@@ -1,218 +0,0 @@
-#!/bin/bash
-# Only run this script inside `kaldi_tts`.
-# This script attempts to automatically execute the instructions in
-# INSTALL_IDLAK.
-
-# (1) Install instructions for expat
-
-if ! which wget >&/dev/null; then
-   echo "This script requires you to first install wget";
-   exit 1;
-fi
-
-if ! which cmake >&/dev/null; then
-  echo "This script requires cmake: install it first.";
-  exit 1;
-fi
-
-echo "****(1) Installing expat"
-
-(
-  rm -f expat-2.1.0.tar.gz 2>/dev/null
-  wget https://sourceforge.net/projects/expat/files/expat/2.1.0/expat-2.1.0.tar.gz
-  if [ ! -e expat-2.1.0.tar.gz ]; then
-    echo "****download of expat-2.1.0.tar.gz failed."
-    exit 1
-  else
-    tar -xovzf expat-2.1.0.tar.gz || exit 1
-    cd expat-2.1.0
-    ./configure --prefix=`pwd` || exit 1
-    sed -i "s/CPPFLAGS =  -DHAVE_EXPAT_CONFIG_H/CPPFLAGS = -fPIC -DHAVE_EXPAT_CONFIG_H/g" Makefile
-    make || exit 1
-    make install || exit 1
-    cd ..
-  fi
-)
-ok_expat=$?
-if [ $ok_expat -ne 0 ]; then
-  echo "****expat install failed."
-  exit 1
-fi
-
-echo "****(2) Installing pugixml"
-
-(
-  rm -rf pugixml-1.2 pugixml-1.2.tar.gz 2>/dev/null
-  #wget -T 10 -t 3 http://pugixml.googlecode.com/files/pugixml-1.2.tar.gz
-  wget https://github.com/zeux/pugixml/releases/download/v1.2/pugixml-1.2.tar.gz
-  if [ ! -e pugixml-1.2.tar.gz ]; then
-    echo "****download of pugixml-1.2.tar.gz failed."
-    exit 1
-  else
-    mkdir pugixml-1.2
-    cd pugixml-1.2
-    tar -xovzf ../pugixml-1.2.tar.gz || exit 1
-    cd scripts
-    if [ "$(uname)" == "Darwin"  ]; then
-      # OS X 10.9, 10.10 require CXXFLAGS += -stdlib=libstdc++ to compile pugixml
-      osx_ver=$(sw_vers | grep ProductVersion | awk '{print $2}' | awk '{split($0,a,"\."); print a[1] "." a[2]; }')
-      echo "Configuring for OS X version $osx_ver ..."
-      if [ "$osx_ver" == "10.9" ]; then
-        cmake -DCMAKE_CXX_FLAGS=-stdlib=libstdc++
-      elif [ "$osx_ver" == "10.10" ]; then
-        cmake -DCMAKE_CXX_FLAGS=-stdlib=libstdc++
-      else
-        cmake .
-      fi
-    else
-      cmake -DCMAKE_CXX_FLAGS=-fPIC ||
-      cmake . || exit 1
-    fi
-    make || exit 1
-    cd ../..
-  fi
-)
-ok_pugixml=$?
-if [ $ok_pugixml -ne 0 ]; then
-  echo "****pugixml install failed."
-  exit 1
-fi
-
-echo "****(3) Installing pcre with utf8 support"
-
-(
-  rm -f pcre-8.20.tar.bz2 2>/dev/null
-  wget https://sourceforge.net/projects/pcre/files/pcre/8.20/pcre-8.20.tar.bz2
-  if [ ! -e pcre-8.20.tar.bz2 ]; then
-    echo "****download of pcre-8.20.tar.bz2 failed."
-    exit 1
-  else
-    tar -xovjf pcre-8.20.tar.bz2 || exit 1
-    cd pcre-8.20
-    ./configure --enable-utf8 --enable-unicode-properties --enable-newline-is-anycrlf --prefix="$(pwd)" || exit 1
-    sed -i "s/CPPFLAGS =/CPPFLAGS = -fPIC/g" Makefile
-    make || exit 1
-    make install || exit 1
-    cd ..
-  fi
-)
-ok_pcre=$?
-if [ $ok_pcre -ne 0 ]; then
-  echo "****pcre install failed."
-  exit 1
-fi
-
-echo "****(4) Installing SPTK"
-(
-    rm -f SPTK-3.9.tar.gz 2>/dev/null
-    wget https://sourceforge.net/projects/sp-tk/files/SPTK/SPTK-3.9/SPTK-3.9.tar.gz
-    if [ ! -e SPTK-3.9.tar.gz ]; then
-	echo "****download of SPTK-3.9.tar.gz failed."
-	exit 1
-    else
-	mkdir -p SPTK
-	tar -xovzf SPTK-3.9.tar.gz || exit 1
-	cd SPTK-3.9
-	./configure --prefix="$(pwd)"/../SPTK || exit 1
-	make || exit 1
-	make install || exit 1
-    cd ..
-  fi
-)
-ok_sptk=$?
-if [ $ok_sptk -ne 0 ]; then
-  echo "****sptk install failed."
-  exit 1
-fi
-
-echo "****(5) Installing phonetisaurus"
-#(
-#    rm -f Phonetisaurus
-#    git clone https://github.com/AdolfVonKleist/Phonetisaurus.git
-#    if [ ! -e Phonetisaurus ]; then
-#        echo "****cloning of Phonetisaurus failed."
-#	    exit 1
-#    else
-#        cd Phonetisaurus
-#	    git checkout 09651ed5f6e9040d6dd30070601ecccfad254df4 . || exit 1
-#        patch -p1 -N < ../extras/phonetisaurus.patch
-#        cd src/.autoconf
-#        autoconf -o ../configure || exit 1
-#        cd ..
-#        LDFLAGS="-Wl,-rpath=`pwd`/../../openfst/lib/" ./configure --with-openfst-libs=`pwd`/../../openfst/lib --with-openfst-includes=`pwd`/../../openfst/include  --with-install-bin=`pwd`/.. || exit 1
-#	    make -j4 || exit 1
-#	    make install || exit 1
-#        cd ..
-#    fi
-#)
-#ok_phonetisaurus=$?
-#if [ $ok_phonetisaurus -ne 0 ]; then
-#    echo "****phonetisaurus install failed."
-#    exit 1
-#fi
-
-# echo "****(1) Installing Apache Xerces C++ XML Parser"
-
-# (
-#   rm xerces-c-3.1.1.tar.gz 2>/dev/null
-#   wget -T 10 -t 3 http://mirror.rmg.io/apache//xerces/c/3/sources/xerces-c-3.1.1.tar.gz
-#   if [ ! -e xerces-c-3.1.1.tar.gz]; then
-#     echo "****download of xerces-c-3.1.1.tar.gz failed."
-#     exit 1
-#   else
-#     tar -xovzf xerces-c-3.1.1.tar.gz || exit 1
-#     cd xerces-c-3.1.1
-#     ./configure --prefix=`pwd` || exit 1
-#     make || exit 1
-#     make install || exit 1
-#     cd ..
-#   fi
-# )
-# ok_xerces=$?
-# if [ $ok_xerces -ne 0 ]; then
-#   echo "**** Apache Xerces C++ XML Parser install failed."
-# fi
-
-# echo "****(1) Installing libXML"
-
-# (
-#   rm libxml2-2.8.0.tar.gz 2>/dev/null
-#   wget -T 10 -t 3 ftp://xmlsoft.org/libxml2/libxml2-2.8.0.tar.gz
-#   if [ ! -e libxml2-2.8.0.tar.gz]; then
-#     echo "****download of libxml2-2.8.0.tar.gz failed."
-#     exit 1
-#   else
-#     tar -xovzf libxml2-2.8.0.tar.gz || exit 1
-#     cd libxml2-2.8.0
-#     ./configure --prefix=`pwd` || exit 1
-#     make || exit 1
-#     make install || exit 1
-#     cd ..
-#   fi
-# )
-# ok_libxml=$?
-# if [ $ok_libxml -ne 0 ]; then
-#   echo "**** libXML install failed."
-# fi
-
-# echo "****(2) Installing Arabica"
-
-# (
-#   rm arabica-2010-November.tar.bz2 2>/dev/null
-#   wget -T 10 -t 3 http://sourceforge.net/projects/arabica/files/latest/download?source=files
-#   if [ ! -e arabica-2010-November.tar.bz2]; then
-#     echo "****download of arabica-2010-November.tar.bz2 failed."
-#     exit 1
-#   else
-#     tar -xovjf arabica-2010-November.tar.bz2 || exit 1
-#     cd libxml2-2.8.0
-#     ./configure --prefix=`pwd` --with-libxml2=`pwd`/../libxml2-2.8.0/lib || exit 1
-#     make || exit 1
-#     make install || exit 1
-#     cd ..
-#   fi
-# )
-# ok_xerces=$?
-# if [ $ok_xerces -ne 0 ]; then
-#   echo "**** Apache Xerces C++ XML Parser install failed."
-# fi
diff --git a/lucida/speechrecognition/kaldi_gstreamer_asr/install_kaldi.sh b/lucida/speechrecognition/kaldi_gstreamer_asr/install_kaldi.sh
deleted file mode 100755
index ae195add3..000000000
--- a/lucida/speechrecognition/kaldi_gstreamer_asr/install_kaldi.sh
+++ /dev/null
@@ -1,57 +0,0 @@
-#!/bin/bash
-LUCIDAROOT=$(pwd)/../../
-if [ ! -d kaldi ]; then
-  git clone https://github.com/kaldi-asr/kaldi.git
-  if [ $? -ne 0 ]; then
-  echo "Could not clone kaldi!!! Please try again later..."
-  exit 1
-  fi
-fi
-cd kaldi \
- && git checkout 01576867802ae5c499f9a4b66591ce35499e28f5 \
- && cd tools \
- && ( sudo ln -s -f bash /bin/sh || : ) \
- && sudo apt-get install -y zlib1g-dev automake autoconf libtool subversion \
- && sudo apt-get install -y libatlas3-base \
- && extras/check_dependencies.sh \
- && make \
- && cd .. \
- && cd src \
- && ./configure --shared \
- && sed -i '7s/^/COMPILE_FLAGS += -fPIC\n/' Makefile \
- && make depend \
- && make \
- && make ext \
- && cd gst-plugin \
- && sudo apt-get install -y libgstreamer1.0-dev \
- && sudo apt-get install -y gstreamer1.0-plugins-good \
- && sudo apt-get install -y gstreamer1.0-plugins-bad \
- && sudo apt-get install -y gstreamer1.0-plugins-ugly \
- && sudo apt-get install -y gstreamer1.0-tools \
- && make depend \
- && make \
- && cd ../../ \
- && cd tools \
- && if [ ! -d gst-kaldi-nnet2-online ]; then git clone https://github.com/alumae/gst-kaldi-nnet2-online.git; if [ $? -ne 0 ]; then echo "Could not download gst-kaldi-nnet2-online!!! Please try again later..."; exit 1; fi; fi \
- && cd gst-kaldi-nnet2-online \
- && git checkout 2d395396c5bf88628a1af0127eebe0a84bd02923 \
- && ( sudo add-apt-repository -y ppa:gstreamer-developers/ppa || : ) \
- && ( sudo apt-get -y update || : ) \
- && sudo apt-get install -y libjansson-dev \
- && cd src \
- && export KALDI_ROOT=$LUCIDAROOT/speechrecognition/kaldi_gstreamer_asr/kaldi \
- && make depend \
- && make \
- && cd ../../../../ \
- && ./test/models/download-fisher-nnet2.sh \
- && export GST_PLUGIN_PATH=$LUCIDAROOT/speechrecognition/kaldi_gstreamer_asr/kaldi/tools/gst-kaldi-nnet2-online/src \
- && sudo pip install tornado \
- && sudo apt-get install -y python3-dev \
- && sudo apt-get install -y python2.7-dev \
- && sudo apt-get install -y libblas3 \
- && sudo apt-get install -y libblas-dev \
- && sudo apt-get install -y liblapack3 \
- && sudo apt-get install -y liblapack-dev \
- && sudo apt-get install -y gfortran \
- && sudo apt-get install -y libc6 \
- && sudo ldconfig
diff --git a/lucida/speechrecognition/kaldi_gstreamer_asr/install_kaldi_tts.sh b/lucida/speechrecognition/kaldi_gstreamer_asr/install_kaldi_tts.sh
deleted file mode 100755
index 60ed33146..000000000
--- a/lucida/speechrecognition/kaldi_gstreamer_asr/install_kaldi_tts.sh
+++ /dev/null
@@ -1,23 +0,0 @@
-#!/bin/bash
-LUCIDAROOT=$(pwd)/../../
-git clone https://github.com/bpotard/idlak.git
-mv idlak kaldi_tts
-cd kaldi_tts
-git checkout 02b24dc6f79b84779e423bfbb17bdf8e70c95aec
-cd tools
-extras/check_dependencies.sh
-cp ../../install_idlak.sh . # contains modifications
-make
-cd ..
-cd src
-sed -i '7s/^/COMPILE_FLAGS += -fPIC\n/' Makefile
-./configure --shared
-make depend
-make
-cd ..
-cd egs/tts_dnn_arctic/s1
-./run.sh
-# Replace the following text with your own.
-echo '########## Test: This is a test from Lucida.'
-echo 'This is a test from Lucida.' | utils/synthesis_test.sh
-echo 'Please "cd exp_dnn/tts_dnn_train_3_deltasc2_quin5/tst_forward_tmp/wav_mlpg" to retrieve the audio!'
diff --git a/lucida/speechrecognition/kaldi_gstreamer_asr/kaldigstserver/client.py b/lucida/speechrecognition/kaldi_gstreamer_asr/kaldigstserver/client.py
deleted file mode 100644
index 3d8be6be8..000000000
--- a/lucida/speechrecognition/kaldi_gstreamer_asr/kaldigstserver/client.py
+++ /dev/null
@@ -1,128 +0,0 @@
-__author__ = 'tanel'
-
-import argparse
-from ws4py.client.threadedclient import WebSocketClient
-import time
-import threading
-import sys
-import urllib
-import Queue
-import json
-import time
-import os
-
-def rate_limited(maxPerSecond):
-    minInterval = 1.0 / float(maxPerSecond)
-    def decorate(func):
-        lastTimeCalled = [0.0]
-        def rate_limited_function(*args,**kargs):
-            elapsed = time.clock() - lastTimeCalled[0]
-            leftToWait = minInterval - elapsed
-            if leftToWait>0:
-                time.sleep(leftToWait)
-            ret = func(*args,**kargs)
-            lastTimeCalled[0] = time.clock()
-            return ret
-        return rate_limited_function
-    return decorate
-
-
-class MyClient(WebSocketClient):
-
-    def __init__(self, filename, url, protocols=None, extensions=None, heartbeat_freq=None, byterate=32000,
-                 save_adaptation_state_filename=None, send_adaptation_state_filename=None):
-        super(MyClient, self).__init__(url, protocols, extensions, heartbeat_freq)
-        self.final_hyps = []
-        self.fn = filename
-        self.byterate = byterate
-        self.final_hyp_queue = Queue.Queue()
-        self.save_adaptation_state_filename = save_adaptation_state_filename
-        self.send_adaptation_state_filename = send_adaptation_state_filename
-
-    @rate_limited(4)
-    def send_data(self, data):
-        self.send(data, binary=True)
-
-    def opened(self):
-        #print "Socket opened!"
-        def send_data_to_ws():
-            f = open(self.fn, "rb")
-            if self.send_adaptation_state_filename is not None:
-                print >> sys.stderr, "Sending adaptation state from %s" % self.send_adaptation_state_filename
-                try:
-                    adaptation_state_props = json.load(open(self.send_adaptation_state_filename, "r"))
-                    self.send(json.dumps(dict(adaptation_state=adaptation_state_props)))
-                except:
-                    e = sys.exc_info()[0]
-                    print >> sys.stderr, "Failed to send adaptation state: ",  e
-            for block in iter(lambda: f.read(self.byterate/4), ""):
-                self.send_data(block)
-            print >> sys.stderr, "Audio sent, now sending EOS"
-            self.send("EOS")
-
-        t = threading.Thread(target=send_data_to_ws)
-        t.start()
-
-
-    def received_message(self, m):
-        response = json.loads(str(m))
-        #print >> sys.stderr, "RESPONSE:", response
-        #print >> sys.stderr, "JSON was:", m
-        if response['status'] == 0:
-            if 'result' in response:
-                trans = response['result']['hypotheses'][0]['transcript']
-                if response['result']['final']:
-                    #print >> sys.stderr, trans,
-                    self.final_hyps.append(trans)
-                    print >> sys.stderr, '\r%s' % trans.replace("\n", "\\n")
-                else:
-                    print_trans = trans.replace("\n", "\\n")
-                    if len(print_trans) > 80:
-                        print_trans = "... %s" % print_trans[-76:]
-                    print >> sys.stderr, '\r%s' % print_trans,
-            if 'adaptation_state' in response:
-                if self.save_adaptation_state_filename:
-                    print >> sys.stderr, "Saving adaptation state to %s" % self.save_adaptation_state_filename
-                    with open(self.save_adaptation_state_filename, "w") as f:
-                        f.write(json.dumps(response['adaptation_state']))
-        else:
-            print >> sys.stderr, "Received error from server (status %d)" % response['status']
-            if 'message' in response:
-                print >> sys.stderr, "Error message:",  response['message']
-
-
-    def get_full_hyp(self, timeout=60):
-        return self.final_hyp_queue.get(timeout)
-
-    def closed(self, code, reason=None):
-        #print "Websocket closed() called"
-        #print >> sys.stderr
-        self.final_hyp_queue.put(" ".join(self.final_hyps))
-
-
-def main():
-
-    parser = argparse.ArgumentParser(description='Command line client for kaldigstserver')
-    parser.add_argument('-u', '--uri', default="ws://localhost:8081/client/ws/speech", dest="uri", help="Server websocket URI")
-    parser.add_argument('-r', '--rate', default=32000, dest="rate", type=int, help="Rate in bytes/sec at which audio should be sent to the server. NB! For raw 16-bit audio it must be 2*samplerate!")
-    parser.add_argument('--save-adaptation-state', help="Save adaptation state to file")
-    parser.add_argument('--send-adaptation-state', help="Send adaptation state from file")
-    parser.add_argument('--content-type', default='', help="Use the specified content type (empty by default, for raw files the default is  audio/x-raw, layout=(string)interleaved, rate=(int), format=(string)S16LE, channels=(int)1")
-    parser.add_argument('audiofile', help="Audio file to be sent to the server")
-    args = parser.parse_args()
-
-    content_type = args.content_type
-    if content_type == '' and args.audiofile.endswith(".raw"):
-        content_type = "audio/x-raw, layout=(string)interleaved, rate=(int)%d, format=(string)S16LE, channels=(int)1" %(args.rate/2)
-
-
-
-    ws = MyClient(args.audiofile, args.uri + '?%s' % (urllib.urlencode([("content-type", content_type)])), byterate=args.rate,
-                  save_adaptation_state_filename=args.save_adaptation_state, send_adaptation_state_filename=args.send_adaptation_state)
-    ws.connect()
-    result = ws.get_full_hyp()
-    print result.encode('utf-8')
-
-if __name__ == "__main__":
-    main()
-
diff --git a/lucida/speechrecognition/kaldi_gstreamer_asr/kaldigstserver/commandcenter.thrift b/lucida/speechrecognition/kaldi_gstreamer_asr/kaldigstserver/commandcenter.thrift
deleted file mode 100644
index 91bee229c..000000000
--- a/lucida/speechrecognition/kaldi_gstreamer_asr/kaldigstserver/commandcenter.thrift
+++ /dev/null
@@ -1,38 +0,0 @@
-# This file outlines the command center's API.
-# Thrift will generate stubs that handle serialization/deserialization
-# during remote procedure calls.
-# Services register with the command center using the registerService() function.
-
-namespace cpp cmdcenterstubs
-namespace java cmdcenterstubs
-
-# MachineData is the information that services send
-# when they wish to register with the command center.
-struct MachineData
-{
-	1:string name,
-	2:i32 port
-}
-
-struct QueryData
-{
-	1:string audioData = "",
-	2:string audioFormat = "",
-	3:bool audioB64Encoding = false,
-	4:string imgData = "",
-	5:string imgFormat = "",
-	6:bool imgB64Encoding = false,
-	7:string textData = ""
-}
-
-service CommandCenter
-{
-  # service <--> command center API
-  void registerService(1:string serviceType, 2:MachineData mDataObj)
-
-  # command center <--> client API
-  string handleRequest(1:QueryData data)
-
-  # simple function to test connections
-  void ping()
-}
diff --git a/lucida/speechrecognition/kaldi_gstreamer_asr/kaldigstserver/decoder.py b/lucida/speechrecognition/kaldi_gstreamer_asr/kaldigstserver/decoder.py
deleted file mode 100644
index 93fd5b097..000000000
--- a/lucida/speechrecognition/kaldi_gstreamer_asr/kaldigstserver/decoder.py
+++ /dev/null
@@ -1,221 +0,0 @@
-"""
-Created on May 17, 2013
-
-@author: tanel
-"""
-import gi
-
-gi.require_version('Gst', '1.0')
-from gi.repository import GObject, Gst
-
-GObject.threads_init()
-Gst.init(None)
-import logging
-import thread
-import os
-
-logger = logging.getLogger(__name__)
-
-import pdb
-
-class DecoderPipeline(object):
-    def __init__(self, conf={}):
-        logger.info("Creating decoder using conf: %s" % conf)
-        self.use_cutter = conf.get("use-vad", False)
-        self.create_pipeline(conf)
-        self.outdir = conf.get("out-dir", None)
-        if not os.path.exists(self.outdir):
-            os.mkdir(self.outdir)
-        elif not os.path.isdir(self.outdir):
-            raise Exception("Output directory %s already exists as a file" % self.outdir)
-
-        self.word_handler = None
-        self.eos_handler = None
-        self.request_id = ""
-
-
-    def create_pipeline(self, conf):
-
-        self.appsrc = Gst.ElementFactory.make("appsrc", "appsrc")
-
-        self.decodebin = Gst.ElementFactory.make("decodebin", "decodebin")
-        self.audioconvert = Gst.ElementFactory.make("audioconvert", "audioconvert")
-        self.audioresample = Gst.ElementFactory.make("audioresample", "audioresample")
-        self.tee = Gst.ElementFactory.make("tee", "tee")
-        self.queue1 = Gst.ElementFactory.make("queue", "queue1")
-        self.filesink = Gst.ElementFactory.make("filesink", "filesink")
-        self.queue2 = Gst.ElementFactory.make("queue", "queue2")
-        self.cutter = Gst.ElementFactory.make("cutter", "cutter")
-        self.asr = Gst.ElementFactory.make("onlinegmmdecodefaster", "asr")
-        self.fakesink = Gst.ElementFactory.make("fakesink", "fakesink")
-
-        for (key, val) in conf.get("decoder", {}).iteritems():
-            logger.info("Setting decoder property: %s = %s" % (key, val))
-            self.asr.set_property(key, val)
-
-        self.appsrc.set_property("is-live", True)
-        self.filesink.set_property("location", "/dev/null")
-        self.cutter.set_property("leaky", False)
-        self.cutter.set_property("pre-length",   1000 * 1000000)
-        self.cutter.set_property("run-length",   1000 * 1000000)
-        self.cutter.set_property("threshold", 0.01)
-        if self.use_cutter:
-            self.asr.set_property("silent", True)
-        logger.info('Created GStreamer elements')
-
-        self.pipeline = Gst.Pipeline()
-        for element in [self.appsrc, self.decodebin, self.audioconvert, self.audioresample, self.tee,
-                        self.queue1, self.filesink,
-                        self.queue2, self.cutter, self.asr, self.fakesink]:
-            logger.debug("Adding %s to the pipeline" % element)
-            self.pipeline.add(element)
-
-        logger.info('Linking GStreamer elements')
-
-        self.appsrc.link(self.decodebin)
-        #self.appsrc.link(self.audioconvert)
-        self.decodebin.connect('pad-added', self._connect_decoder)
-        if self.use_cutter:
-            self.cutter.link(self.audioconvert)
-
-        self.audioconvert.link(self.audioresample)
-
-        self.audioresample.link(self.tee)
-        #self.audioresample.link(self.cutter)
-        #self.cutter.link(self.tee)
-
-        self.tee.link(self.queue1)
-        self.queue1.link(self.filesink)
-
-        self.tee.link(self.queue2)
-        self.queue2.link(self.asr)
-
-
-        self.asr.link(self.fakesink)
-
-        # Create bus and connect several handlers
-        self.bus = self.pipeline.get_bus()
-        self.bus.add_signal_watch()
-        self.bus.enable_sync_message_emission()
-        self.bus.connect('message::eos', self._on_eos)
-        self.bus.connect('message::error', self._on_error)
-        #self.bus.connect('message::cutter', self._on_cutter)
-
-        cutter_type = 'sync'
-        if cutter_type == 'async':
-            self.bus.connect('message::element', self._on_element_message)
-        else:
-            #self.bus.set_sync_handler(self.bus.sync_signal_handler)
-            self.bus.connect('sync-message::element',  self._on_element_message)
-        self.asr.connect('hyp-word', self._on_word)
-        logger.info("Setting pipeline to READY")
-        self.pipeline.set_state(Gst.State.READY)
-        logger.info("Set pipeline to READY")
-
-    def _connect_decoder(self, element, pad):
-        logger.info("%s: Connecting audio decoder" % self.request_id)
-        if self.use_cutter:
-            pad.link(self.cutter.get_static_pad("sink"))
-        else:
-            pad.link(self.audioconvert.get_static_pad("sink"))
-
-        logger.info("%s: Connected audio decoder" % self.request_id)
-
-    def _on_element_message(self, bus, message):
-        if message.has_name("cutter"):
-            if message.get_structure().get_value('above'):
-                logger.info("LEVEL ABOVE")
-                self.asr.set_property("silent", False)
-            else:
-                logger.info("LEVEL BELOW")
-                self.asr.set_property("silent", True)
-
-    def _on_word(self, asr, word):
-        logger.info("%s: Got word: %s" % (self.request_id, word.decode('utf8')))
-        if self.word_handler:
-            self.word_handler(word)
-
-
-    def _on_error(self, bus, msg):
-        self.error = msg.parse_error()
-        logger.error(self.error)
-        self.finish_request()
-        if self.error_handler:
-            self.error_handler(self.error[0].message)
-
-    def _on_eos(self, bus, msg):
-        logger.info('%s: Pipeline received eos signal' % self.request_id)
-        self.finish_request()
-        if self.eos_handler:
-            self.eos_handler[0](self.eos_handler[1])
-
-    def finish_request(self):
-        logger.info('%s: Finishing request' % self.request_id)
-        if self.outdir:
-            self.filesink.set_state(Gst.State.NULL)
-            self.filesink.set_property('location', "/dev/null")
-            self.filesink.set_state(Gst.State.PLAYING)
-        self.pipeline.set_state(Gst.State.NULL)
-        self.request_id = ""
-
-    def init_request(self, id, caps_str):
-        self.request_id = id
-        if caps_str and len(caps_str) > 0:
-            logger.info("%s: Setting caps to %s" % (self.request_id, caps_str))
-            caps = Gst.caps_from_string(caps_str)
-            self.appsrc.set_property("caps", caps)
-        else:
-            #caps = Gst.caps_from_string(None)
-            self.appsrc.set_property("caps", None)
-            #self.pipeline.set_state(Gst.State.READY)
-            pass
-        #self.appsrc.set_state(Gst.State.PAUSED)
-
-        if self.outdir:
-            self.pipeline.set_state(Gst.State.PAUSED)
-            self.filesink.set_state(Gst.State.NULL)
-            self.filesink.set_property('location', "%s/%s.raw" % (self.outdir, id))
-            self.filesink.set_state(Gst.State.PLAYING)
-
-        #self.filesink.set_state(Gst.State.PLAYING)        
-        #self.decodebin.set_state(Gst.State.PLAYING)
-        self.pipeline.set_state(Gst.State.PLAYING)
-        self.filesink.set_state(Gst.State.PLAYING)
-        # push empty buffer (to avoid hang on client diconnect)
-        buf = Gst.Buffer.new_allocate(None, 0, None)
-        self.appsrc.emit("push-buffer", buf)
-        logger.info('%s: Pipeline initialized' % (self.request_id))
-
-
-    def process_data(self, data):
-        logger.debug('%s: Pushing buffer of size %d to pipeline' % (self.request_id, len(data)))
-        buf = Gst.Buffer.new_allocate(None, len(data), None)
-        buf.fill(0, data)
-        self.appsrc.emit("push-buffer", buf)
-
-
-    def end_request(self):
-        logger.info("%s: Pushing EOS to pipeline" % self.request_id)
-        self.appsrc.emit("end-of-stream")
-
-    def set_word_handler(self, handler):
-        self.word_handler = handler
-
-    def set_eos_handler(self, handler, user_data=None):
-        self.eos_handler = (handler, user_data)
-
-    def set_error_handler(self, handler):
-        self.error_handler = handler
-
-
-    def cancel(self):
-        logger.info("%s: Cancelling pipeline" % self.request_id)
-        self.pipeline.send_event(Gst.Event.new_eos())
-        #self.asr.set_property("silent", True)
-        #self.pipeline.set_state(Gst.State.NULL)
-
-        #if (self.pipeline.get_state() == Gst.State.PLAYING):
-        #logger.debug("Sending EOS to pipeline")
-        #self.pipeline.send_event(Gst.Event.new_eos())
-        #self.pipeline.set_state(Gst.State.READY)
-        logger.info("%s: Cancelled pipeline" % self.request_id)
\ No newline at end of file
diff --git a/lucida/speechrecognition/kaldi_gstreamer_asr/kaldigstserver/decoder2.py b/lucida/speechrecognition/kaldi_gstreamer_asr/kaldigstserver/decoder2.py
deleted file mode 100644
index f70fa4716..000000000
--- a/lucida/speechrecognition/kaldi_gstreamer_asr/kaldigstserver/decoder2.py
+++ /dev/null
@@ -1,226 +0,0 @@
-"""
-Created on May 17, 2013
-
-@author: tanel
-"""
-import gi
-
-gi.require_version('Gst', '1.0')
-from gi.repository import GObject, Gst
-
-GObject.threads_init()
-Gst.init(None)
-import logging
-import thread
-import os
-
-logger = logging.getLogger(__name__)
-
-import pdb
-
-class DecoderPipeline2(object):
-    def __init__(self, conf={}):
-        logger.info("Creating decoder using conf: %s" % conf)
-        self.create_pipeline(conf)
-        self.outdir = conf.get("out-dir", None)
-        if not os.path.exists(self.outdir):
-            os.makedirs(self.outdir)
-        elif not os.path.isdir(self.outdir):
-            raise Exception("Output directory %s already exists as a file" % self.outdir)
-
-        self.result_handler = None
-        self.full_result_handler = None
-        self.eos_handler = None
-        self.error_handler = None
-        self.request_id = ""
-
-
-    def create_pipeline(self, conf):
-
-        self.appsrc = Gst.ElementFactory.make("appsrc", "appsrc")
-        self.decodebin = Gst.ElementFactory.make("decodebin", "decodebin")
-        self.audioconvert = Gst.ElementFactory.make("audioconvert", "audioconvert")
-        self.audioresample = Gst.ElementFactory.make("audioresample", "audioresample")
-        self.tee = Gst.ElementFactory.make("tee", "tee")
-        self.queue1 = Gst.ElementFactory.make("queue", "queue1")
-        self.filesink = Gst.ElementFactory.make("filesink", "filesink")
-        self.queue2 = Gst.ElementFactory.make("queue", "queue2")
-        self.asr = Gst.ElementFactory.make("kaldinnet2onlinedecoder", "asr")
-        self.fakesink = Gst.ElementFactory.make("fakesink", "fakesink")
-
-        # This needs to be set first
-        if "use-threaded-decoder" in conf["decoder"]:
-            self.asr.set_property("use-threaded-decoder", conf["decoder"]["use-threaded-decoder"])
-
-        for (key, val) in conf.get("decoder", {}).iteritems():
-            if key != "use-threaded-decoder":
-                logger.info("Setting decoder property: %s = %s" % (key, val))
-                self.asr.set_property(key, val)
-
-        self.appsrc.set_property("is-live", True)
-        self.filesink.set_property("location", "/dev/null")
-        logger.info('Created GStreamer elements')
-
-        self.pipeline = Gst.Pipeline()
-        for element in [self.appsrc, self.decodebin, self.audioconvert, self.audioresample, self.tee,
-                        self.queue1, self.filesink,
-                        self.queue2, self.asr, self.fakesink]:
-            logger.debug("Adding %s to the pipeline" % element)
-            self.pipeline.add(element)
-
-        logger.info('Linking GStreamer elements')
-
-        self.appsrc.link(self.decodebin)
-        #self.appsrc.link(self.audioconvert)
-        self.decodebin.connect('pad-added', self._connect_decoder)
-        self.audioconvert.link(self.audioresample)
-
-        self.audioresample.link(self.tee)
-
-        self.tee.link(self.queue1)
-        self.queue1.link(self.filesink)
-
-        self.tee.link(self.queue2)
-        self.queue2.link(self.asr)
-
-        self.asr.link(self.fakesink)
-
-        # Create bus and connect several handlers
-        self.bus = self.pipeline.get_bus()
-        self.bus.add_signal_watch()
-        self.bus.enable_sync_message_emission()
-        self.bus.connect('message::eos', self._on_eos)
-        self.bus.connect('message::error', self._on_error)
-        #self.bus.connect('message::cutter', self._on_cutter)
-
-        self.asr.connect('partial-result', self._on_partial_result)
-        self.asr.connect('final-result', self._on_final_result)
-        self.asr.connect('full-final-result', self._on_full_final_result)
-
-        logger.info("Setting pipeline to READY")
-        self.pipeline.set_state(Gst.State.READY)
-        logger.info("Set pipeline to READY")
-
-    def _connect_decoder(self, element, pad):
-        logger.info("%s: Connecting audio decoder" % self.request_id)
-        pad.link(self.audioconvert.get_static_pad("sink"))
-        logger.info("%s: Connected audio decoder" % self.request_id)
-
-
-    def _on_partial_result(self, asr, hyp):
-        logger.info("%s: Got partial result: %s" % (self.request_id, hyp.decode('utf8')))
-        if self.result_handler:
-            self.result_handler(hyp, False)
-
-    def _on_final_result(self, asr, hyp):
-        logger.info("%s: Got final result: %s" % (self.request_id, hyp.decode('utf8')))
-        if self.result_handler:
-            self.result_handler(hyp, True)
-
-    def _on_full_final_result(self, asr, result_json):
-        logger.info("%s: Got full final result: %s" % (self.request_id, result_json.decode('utf8')))
-        if self.full_result_handler:
-            self.full_result_handler(result_json)
-
-    def _on_error(self, bus, msg):
-        self.error = msg.parse_error()
-        logger.error(self.error)
-        self.finish_request()
-        if self.error_handler:
-            self.error_handler(self.error[0].message)
-
-    def _on_eos(self, bus, msg):
-        logger.info('%s: Pipeline received eos signal' % self.request_id)
-        #self.decodebin.unlink(self.audioconvert)
-        self.finish_request()
-        if self.eos_handler:
-            self.eos_handler[0](self.eos_handler[1])
-
-    def get_adaptation_state(self):
-        return self.asr.get_property("adaptation-state")
-
-    def set_adaptation_state(self, adaptation_state):
-        """Sets the adaptation state to a certian value, previously retrieved using get_adaptation_state()
-
-        Should be called after init_request(..)
-        """
-
-        return self.asr.set_property("adaptation-state", adaptation_state)
-
-    def finish_request(self):
-        logger.info("%s: Resetting decoder state" % self.request_id)
-        if self.outdir:
-            self.filesink.set_state(Gst.State.NULL)
-            self.filesink.set_property('location', "/dev/null")
-            self.filesink.set_state(Gst.State.PLAYING)
-        self.pipeline.set_state(Gst.State.NULL)
-        self.request_id = ""
-
-
-    def init_request(self, id, caps_str):
-        self.request_id = id
-        logger.info("%s: Initializing request" % (self.request_id))
-        if caps_str and len(caps_str) > 0:
-            logger.info("%s: Setting caps to %s" % (self.request_id, caps_str))
-            caps = Gst.caps_from_string(caps_str)
-            self.appsrc.set_property("caps", caps)
-        else:
-            #caps = Gst.caps_from_string("")
-            self.appsrc.set_property("caps", None)
-            #self.pipeline.set_state(Gst.State.READY)
-            pass
-        #self.appsrc.set_state(Gst.State.PAUSED)
-
-        if self.outdir:
-            self.pipeline.set_state(Gst.State.PAUSED)
-            self.filesink.set_state(Gst.State.NULL)
-            self.filesink.set_property('location', "%s/%s.raw" % (self.outdir, id))
-            self.filesink.set_state(Gst.State.PLAYING)
-
-        #self.filesink.set_state(Gst.State.PLAYING)        
-        #self.decodebin.set_state(Gst.State.PLAYING)
-        self.pipeline.set_state(Gst.State.PLAYING)
-        self.filesink.set_state(Gst.State.PLAYING)
-        # push empty buffer (to avoid hang on client diconnect)
-        #buf = Gst.Buffer.new_allocate(None, 0, None)
-        #self.appsrc.emit("push-buffer", buf)
-
-        # reset adaptation state
-        self.set_adaptation_state("")
-
-    def process_data(self, data):
-        logger.debug('%s: Pushing buffer of size %d to pipeline' % (self.request_id, len(data)))
-        buf = Gst.Buffer.new_allocate(None, len(data), None)
-        buf.fill(0, data)
-        self.appsrc.emit("push-buffer", buf)
-        logger.debug('%s: Pushing buffer done' % self.request_id)
-
-
-    def end_request(self):
-        logger.info("%s: Pushing EOS to pipeline" % self.request_id)
-        self.appsrc.emit("end-of-stream")
-
-    def set_result_handler(self, handler):
-        self.result_handler = handler
-
-    def set_full_result_handler(self, handler):
-        self.full_result_handler = handler
-
-    def set_eos_handler(self, handler, user_data=None):
-        self.eos_handler = (handler, user_data)
-
-    def set_error_handler(self, handler):
-        self.error_handler = handler
-
-
-    def cancel(self):
-        logger.info("%s: Sending EOS to pipeline in order to cancel processing" % self.request_id)
-        self.appsrc.emit("end-of-stream")
-        #self.asr.set_property("silent", True)
-        #self.pipeline.set_state(Gst.State.NULL)
-
-        #if (self.pipeline.get_state() == Gst.State.PLAYING):
-        #logger.debug("Sending EOS to pipeline")
-        #self.pipeline.send_event(Gst.Event.new_eos())
-        #self.pipeline.set_state(Gst.State.READY)
-        logger.info("%s: Cancelled pipeline" % self.request_id)
diff --git a/lucida/speechrecognition/kaldi_gstreamer_asr/kaldigstserver/decoder2_test.py b/lucida/speechrecognition/kaldi_gstreamer_asr/kaldigstserver/decoder2_test.py
deleted file mode 100644
index cdb723c95..000000000
--- a/lucida/speechrecognition/kaldi_gstreamer_asr/kaldigstserver/decoder2_test.py
+++ /dev/null
@@ -1,145 +0,0 @@
-# -*- coding: UTF-8 -*-
-
-'''
-Created on Jun 27, 2013
-
-@author: tanel
-'''
-import unittest
-from gi.repository import GObject, Gst
-import thread
-import logging
-from decoder2 import DecoderPipeline2
-import time
-
-class DecoderPipeline2Tests(unittest.TestCase):
-
-    def __init__(self,  *args, **kwargs):
-        super(DecoderPipeline2Tests, self).__init__(*args, **kwargs)
-        logging.basicConfig(level=logging.INFO)
-
-    @classmethod
-    def setUpClass(cls):
-            decoder_conf = {"model" : "test/models/estonian/nnet2_online_ivector/final.mdl",
-                            "word-syms" : "test/models/estonian/nnet2_online_ivector/words.txt",
-                            "fst" : "test/models/estonian/nnet2_online_ivector/HCLG.fst",
-                            "mfcc-config" : "test/models/estonian/nnet2_online_ivector/conf/mfcc.conf",
-                            "ivector-extraction-config": "test/models/estonian/nnet2_online_ivector/conf/ivector_extractor.conf",
-                            "max-active": 7000,
-                            "beam": 11.0,
-                            "lattice-beam": 6.0,
-                            "do-endpointing" : True,
-                            "endpoint-silence-phones":"1:2:3:4:5:6:7:8:9:10"}
-            cls.decoder_pipeline = DecoderPipeline2({"decoder" : decoder_conf})
-            cls.final_hyps = []
-            cls.finished = False
-
-            cls.decoder_pipeline.set_result_handler(cls.result_getter)
-            cls.decoder_pipeline.set_eos_handler(cls.set_finished, cls.finished)
-
-            loop = GObject.MainLoop()
-            thread.start_new_thread(loop.run, ())
-
-    @classmethod
-    def result_getter(cls, hyp, final):
-        if final:
-            cls.final_hyps.append(hyp)
-
-    @classmethod
-    def set_finished(cls, finished):
-        cls.finished = True
-
-    def setUp(self):
-        self.__class__.final_hyps = []
-        self.__class__.finished = False
-
-
-
-    def testCancelAfterEOS(self):
-        self.decoder_pipeline.init_request("testCancelAfterEOS", "audio/x-raw, layout=(string)interleaved, rate=(int)16000, format=(string)S16LE, channels=(int)1")
-        f = open("test/data/1234-5678.raw", "rb")
-        for block in iter(lambda: f.read(8000), ""):
-            time.sleep(0.25)
-            self.decoder_pipeline.process_data(block)
-
-        self.decoder_pipeline.end_request()
-        self.decoder_pipeline.cancel()
-        while not self.finished:
-            time.sleep(1)
-
-        #self.assertEqual(["üks", "kaks", "kolm", "neli", "<#s>", "viis", "kuus", "seitse", "kaheksa", "<#s>"], self.words)
-
-
-    def test12345678(self):
-        self.decoder_pipeline.init_request("test12345678", "audio/x-raw, layout=(string)interleaved, rate=(int)16000, format=(string)S16LE, channels=(int)1")
-        adaptation_state = open("test/data/adaptation_state.txt").read()
-        self.decoder_pipeline.set_adaptation_state(adaptation_state)
-        f = open("test/data/1234-5678.raw", "rb")
-        for block in iter(lambda: f.read(8000), ""):
-            time.sleep(0.25)
-            self.decoder_pipeline.process_data(block)
-
-        self.decoder_pipeline.end_request()
-
-
-        while not self.finished:
-            time.sleep(1)
-        self.assertEqual(["üks kaks kolm neli", "viis kuus seitse kaheksa"], self.final_hyps)
-
-    def test8k(self):
-        self.decoder_pipeline.init_request("test8k", "audio/x-raw, layout=(string)interleaved, rate=(int)8000, format=(string)S16LE, channels=(int)1")
-        f = open("test/data/1234-5678.8k.raw", "rb")
-        for block in iter(lambda: f.read(4000), ""):
-            time.sleep(0.25)
-            self.decoder_pipeline.process_data(block)
-
-        self.decoder_pipeline.end_request()
-
-
-        while not self.finished:
-            time.sleep(1)
-        self.assertEqual(["üks kaks kolm neli", "viis kuus seitse kaheksa"], self.final_hyps)
-
-    def testDisconnect(self):
-        self.decoder_pipeline.init_request("testDisconnect", "audio/x-raw, layout=(string)interleaved, rate=(int)8000, format=(string)S16LE, channels=(int)1")
-
-        self.decoder_pipeline.end_request()
-
-
-        while not self.finished:
-            time.sleep(1)
-        self.assertEqual([], self.final_hyps)
-
-
-    def testWav(self):
-        self.decoder_pipeline.init_request("testWav", "")
-        f = open("test/data/test_with_silence.wav", "rb")
-        for block in iter(lambda: f.read(48000*2*2/4), ""):
-            time.sleep(0.25)
-            self.decoder_pipeline.process_data(block)
-
-        self.decoder_pipeline.end_request()
-
-        while not self.finished:
-            time.sleep(1)
-        self.assertEqual(["see on esimene lause pärast mida tuleb vaikus", "nüüd tuleb teine lause"], self.final_hyps)
-
-    def testOgg(self):
-        self.decoder_pipeline.init_request("testOgg", "")
-        f = open("test/data/test_2lauset.ogg", "rb")
-        for block in iter(lambda: f.read(86*1024/8/4), ""):
-            time.sleep(0.25)
-            self.decoder_pipeline.process_data(block)
-
-        self.decoder_pipeline.end_request()
-
-
-        while not self.finished:
-            time.sleep(1)
-        self.assertEqual("see on esimene lause see on teine lause", " ".join(self.final_hyps))
-
-def main():
-    unittest.main()
-
-if __name__ == '__main__':
-    main()
\ No newline at end of file
diff --git a/lucida/speechrecognition/kaldi_gstreamer_asr/kaldigstserver/decoder_test.py b/lucida/speechrecognition/kaldi_gstreamer_asr/kaldigstserver/decoder_test.py
deleted file mode 100644
index f2c118405..000000000
--- a/lucida/speechrecognition/kaldi_gstreamer_asr/kaldigstserver/decoder_test.py
+++ /dev/null
@@ -1,194 +0,0 @@
-# -*- coding: UTF-8 -*-
-
-'''
-Created on Jun 27, 2013
-
-@author: tanel
-'''
-import unittest
-from gi.repository import GObject, Gst
-import thread
-import logging
-from decoder import DecoderPipeline
-import time
-
-class DecoderPipelineTests(unittest.TestCase):
-
-    def __init__(self,  *args, **kwargs):
-        super(DecoderPipelineTests, self).__init__(*args, **kwargs)
-        logging.basicConfig(level=logging.INFO)
-
-    @classmethod
-    def setUpClass(cls):
-            decoder_conf = {"model" : "test/models/estonian/tri2b_mmi_pruned/final.mdl",
-                            "lda-mat" : "test/models/estonian/tri2b_mmi_pruned/final.mat",
-                            "word-syms" : "test/models/estonian/tri2b_mmi_pruned/words.txt",
-                            "fst" : "test/models/estonian/tri2b_mmi_pruned/HCLG.fst",
-                            "silence-phones" : "6"}
-            cls.decoder_pipeline = DecoderPipeline({"decoder" : decoder_conf})
-            cls.words = []
-            cls.finished = False
-
-            cls.decoder_pipeline.set_word_handler(cls.word_getter)
-            cls.decoder_pipeline.set_eos_handler(cls.set_finished, cls.finished)
-
-            loop = GObject.MainLoop()
-            thread.start_new_thread(loop.run, ())
-
-    @classmethod
-    def word_getter(cls, word):
-        cls.words.append(word)
-
-    @classmethod
-    def set_finished(cls, finished):
-        cls.finished = True
-
-    def setUp(self):
-        self.__class__.words = []
-        self.__class__.finished = False
-
-
-
-    def testCancelAfterEOS(self):
-        self.decoder_pipeline.init_request("testCancelAfterEOS", "audio/x-raw, layout=(string)interleaved, rate=(int)16000, format=(string)S16LE, channels=(int)1")
-        f = open("test/data/1234-5678.raw", "rb")
-        for block in iter(lambda: f.read(8000), ""):
-            time.sleep(0.25)
-            self.decoder_pipeline.process_data(block)
-
-        self.decoder_pipeline.end_request()
-        self.decoder_pipeline.cancel()
-        while not self.finished:
-            time.sleep(1)
-
-        #self.assertEqual(["üks", "kaks", "kolm", "neli", "<#s>", "viis", "kuus", "seitse", "kaheksa", "<#s>"], self.words)
-
-
-    def test12345678(self):
-        self.decoder_pipeline.init_request("test12345678", "audio/x-raw, layout=(string)interleaved, rate=(int)16000, format=(string)S16LE, channels=(int)1")
-        f = open("test/data/1234-5678.raw", "rb")
-        for block in iter(lambda: f.read(8000), ""):
-            time.sleep(0.25)
-            self.decoder_pipeline.process_data(block)
-
-        self.decoder_pipeline.end_request()
-
-
-        while not self.finished:
-            time.sleep(1)
-        self.assertEqual(["üks", "kaks", "kolm", "neli", "<#s>", "viis", "kuus", "seitse", "kaheksa", "<#s>"], self.words)
-
-    def testWav(self):
-        self.decoder_pipeline.init_request("testWav", "")
-        f = open("test/data/lause2.wav", "rb")
-        for block in iter(lambda: f.read(16000*2*2/4), ""):
-            time.sleep(0.25)
-            self.decoder_pipeline.process_data(block)
-
-        self.decoder_pipeline.end_request()
-
-
-        while not self.finished:
-            time.sleep(1)
-        self.assertEqual("see on teine lause <#s>".split(), self.words)
-
-    def testOgg(self):
-        self.decoder_pipeline.init_request("testOgg", "")
-        f = open("test/data/test_2lauset.ogg", "rb")
-        for block in iter(lambda: f.read(86*1024/8/4), ""):
-            time.sleep(0.25)
-            self.decoder_pipeline.process_data(block)
-
-        self.decoder_pipeline.end_request()
-
-
-        while not self.finished:
-            time.sleep(1)
-        self.assertEqual("see on esimene lause <#s> see on teine lause <#s>".split(), self.words)
-
-
-
-    def __testDecoder(self):
-        finished = [False]
-
-
-
-
-        def do_shit():
-            decoder_pipeline.init_request("test0", "audio/x-raw, layout=(string)interleaved, rate=(int)16000, format=(string)S16LE, channels=(int)1")
-            f = open("test/data/1234-5678.raw", "rb")
-            for block in iter(lambda: f.read(8000), ""):
-                time.sleep(0.25)
-                decoder_pipeline.process_data(block)
-            
-            decoder_pipeline.end_request()
-    
-        do_shit()
-    
-        while not finished[0]:
-            time.sleep(1)
-        self.assertEqual(["üks", "kaks", "kolm", "neli", "<#s>", "viis", "kuus", "seitse", "kaheksa", "<#s>"], words)
-        
-        words = []
-        
-        finished[0] = False    
-        do_shit()
-        while not finished[0]:
-            time.sleep(1)
-            
-        self.assertItemsEqual(["see", "on", "teine", "lause", "<#s>"], words, "Recognition result")
-        
-        # Now test cancelation of a long submitted file
-        words = []        
-        decoder_pipeline.init_request("test0", "audio/x-raw, layout=(string)interleaved, rate=(int)16000, format=(string)S16LE, channels=(int)1")
-        f = open("test/data/etteytlus.raw", "rb")
-        decoder_pipeline.process_data(f.read())
-        time.sleep(3)
-        decoder_pipeline.cancel()
-        print "Pipeline cancelled"
-        
-        words = []
-        finished[0] = False
-        decoder_pipeline.init_request("test0", "audio/x-raw, layout=(string)interleaved, rate=(int)16000, format=(string)S16LE, channels=(int)1")
-        # read and send everything
-        f = open("test/data/lause2.raw", "rb")
-        decoder_pipeline.process_data(f.read(10*16000))
-        decoder_pipeline.end_request()
-        while not finished[0]:
-            time.sleep(1)            
-        self.assertItemsEqual(["see", "on", "teine", "lause", "<#s>"], words, "Recognition result")
-        
-        #test cancelling without anything sent
-        decoder_pipeline.init_request("test0", "audio/x-raw, layout=(string)interleaved, rate=(int)16000, format=(string)S16LE, channels=(int)1")
-        decoder_pipeline.cancel()
-        print "Pipeline cancelled"
-        
-        words = []
-        finished[0] = False
-        decoder_pipeline.init_request("test0", "audio/x-wav")
-        # read and send everything
-        f = open("test/data/lause2.wav", "rb")
-        decoder_pipeline.process_data(f.read())
-        decoder_pipeline.end_request()
-        while not finished[0]:
-            time.sleep(1)            
-        self.assertItemsEqual(["see", "on", "teine", "lause", "<#s>"], words, "Recognition result")
-
-        words = []
-        finished[0] = False
-        decoder_pipeline.init_request("test0", "audio/ogg")
-        # read and send everything
-        f = open("test/data/test_2lauset.ogg", "rb")
-        decoder_pipeline.process_data(f.read(10*16000))
-
-        decoder_pipeline.end_request()
-        while not finished[0]:
-            time.sleep(1)
-        self.assertItemsEqual("see on esimene lause <#s> see on teine lause <#s>".split(), words, "Recognition result")
-
-
-def main():
-    unittest.main()
-
-if __name__ == '__main__':
-    main()
\ No newline at end of file
diff --git a/lucida/speechrecognition/kaldi_gstreamer_asr/kaldigstserver/master_server.py b/lucida/speechrecognition/kaldi_gstreamer_asr/kaldigstserver/master_server.py
deleted file mode 100644
index dd7b51506..000000000
--- a/lucida/speechrecognition/kaldi_gstreamer_asr/kaldigstserver/master_server.py
+++ /dev/null
@@ -1,351 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2013 Tanel Alumae
-
-"""
-Reads speech data via websocket requests, sends it to Redis, waits for results from Redis and
-forwards to client via websocket
-"""
-import sys
-import logging
-import json
-import codecs
-import os.path
-import uuid
-import time
-import threading
-import functools
-from Queue import Queue
-
-import tornado.ioloop
-import tornado.options
-import tornado.web
-import tornado.websocket
-import tornado.gen
-import tornado.concurrent
-import settings
-import common
-import os
-if os.environ.get('WSS'):
-    import ssl
-
-
-class Application(tornado.web.Application):
-    def __init__(self):
-        settings = dict(
-            cookie_secret="43oETzKXQAGaYdkL5gEmGeJJFuYh7EQnp2XdTP1o/Vo=",
-            template_path=os.path.join(os.path.dirname(os.path.dirname(__file__)), "templates"),
-            static_path=os.path.join(os.path.dirname(os.path.dirname(__file__)), "static"),
-            xsrf_cookies=False,
-            autoescape=None,
-        )
-
-        handlers = [
-            (r"/", MainHandler),
-            (r"/client/ws/speech", DecoderSocketHandler),
-            (r"/client/ws/status", StatusSocketHandler),
-            (r"/client/dynamic/reference", ReferenceHandler),
-            (r"/client/dynamic/recognize", HttpChunkedRecognizeHandler),
-            (r"/worker/ws/speech", WorkerSocketHandler),
-            (r"/client/static/(.*)", tornado.web.StaticFileHandler, {'path': settings["static_path"]}),
-        ]
-        tornado.web.Application.__init__(self, handlers, **settings)
-        self.available_workers = set()
-        self.status_listeners = set()
-        self.num_requests_processed = 0
-
-    def send_status_update_single(self, ws):
-        status = dict(num_workers_available=len(self.available_workers), num_requests_processed=self.num_requests_processed)
-        ws.write_message(json.dumps(status))
-
-    def send_status_update(self):
-        for ws in self.status_listeners:
-            self.send_status_update_single(ws)
-
-    def save_reference(self, content_id, content):
-        refs = {}
-        try:
-            with open("reference-content.json") as f:
-                refs = json.load(f)
-        except:
-            pass
-        refs[content_id] = content
-        with open("reference-content.json", "w") as f:
-            json.dump(refs, f, indent=2)
-
-
-class MainHandler(tornado.web.RequestHandler):
-    def get(self):
-        current_directory = os.path.dirname(os.path.abspath(__file__))
-        parent_directory = os.path.join(current_directory, os.pardir)
-        readme = os.path.join(parent_directory, "README.md")
-        self.render(readme)
-
-
-def run_async(func):
-    @functools.wraps(func)
-    def async_func(*args, **kwargs):
-        func_hl = threading.Thread(target=func, args=args, kwargs=kwargs)
-        func_hl.start()
-        return func_hl
-
-    return async_func
-
-
-def content_type_to_caps(content_type):
-    """
-    Converts MIME-style raw audio content type specifier to GStreamer CAPS string
-    """
-    default_attributes= {"rate": 16000, "format" : "S16LE", "channels" : 1, "layout" : "interleaved"}
-    media_type, _, attr_string = content_type.replace(";", ",").partition(",")
-    if media_type in ["audio/x-raw", "audio/x-raw-int"]:
-        media_type = "audio/x-raw"
-        attributes = default_attributes
-        for (key,_,value) in [p.partition("=") for p in attr_string.split(",")]:
-            attributes[key.strip()] = value.strip()
-        return "%s, %s" % (media_type, ", ".join(["%s=%s" % (key, value) for (key,value) in attributes.iteritems()]))
-    else:
-        return content_type
-
-
-@tornado.web.stream_request_body
-class HttpChunkedRecognizeHandler(tornado.web.RequestHandler):
-    """
-    Provides a HTTP POST/PUT interface supporting chunked transfer requests, similar to that provided by
-    http://github.com/alumae/ruby-pocketsphinx-server.
-    """
-
-    def prepare(self):
-        self.id = str(uuid.uuid4())
-        self.final_hyp = ""
-        self.final_result_queue = Queue()
-        self.user_id = self.request.headers.get("device-id", "none")
-        self.content_id = self.request.headers.get("content-id", "none")
-        logging.info("%s: OPEN: user='%s', content='%s'" % (self.id, self.user_id, self.content_id))
-        self.worker = None
-        self.error_status = 0
-        self.error_message = None
-        try:
-            self.worker = self.application.available_workers.pop()
-            self.application.send_status_update()
-            logging.info("%s: Using worker %s" % (self.id, self.__str__()))
-            self.worker.set_client_socket(self)
-
-            content_type = self.request.headers.get("Content-Type", None)
-            if content_type:
-                content_type = content_type_to_caps(content_type)
-                logging.info("%s: Using content type: %s" % (self.id, content_type))
-
-            self.worker.write_message(json.dumps(dict(id=self.id, content_type=content_type, user_id=self.user_id, content_id=self.content_id)))
-        except KeyError:
-            logging.warn("%s: No worker available for client request" % self.id)
-            self.set_status(503)
-            self.finish("No workers available")
-
-    def data_received(self, chunk):
-        assert self.worker is not None
-        logging.debug("%s: Forwarding client message of length %d to worker" % (self.id, len(chunk)))
-        self.worker.write_message(chunk, binary=True)
-
-    def post(self, *args, **kwargs):
-        self.end_request(args, kwargs)
-
-    def put(self, *args, **kwargs):
-        self.end_request(args, kwargs)
-
-    @run_async
-    def get_final_hyp(self, callback=None):
-        logging.info("%s: Waiting for final result..." % self.id)
-        callback(self.final_result_queue.get(block=True))
-
-    @tornado.web.asynchronous
-    @tornado.gen.coroutine
-    def end_request(self, *args, **kwargs):
-        logging.info("%s: Handling the end of chunked recognize request" % self.id)
-        assert self.worker is not None
-        self.worker.write_message("EOS", binary=True)
-        logging.info("%s: yielding..." % self.id)
-        hyp = yield tornado.gen.Task(self.get_final_hyp)
-        if self.error_status == 0:
-            logging.info("%s: Final hyp: %s" % (self.id, hyp))
-            response = {"status" : 0, "id": self.id, "hypotheses": [{"utterance" : hyp}]}
-            self.write(response)
-        else:
-            logging.info("%s: Error (status=%d) processing HTTP request: %s" % (self.id, self.error_status, self.error_message))
-            response = {"status" : self.error_status, "id": self.id, "message": self.error_message}
-            self.write(response)
-        self.application.num_requests_processed += 1
-        self.application.send_status_update()
-        self.worker.set_client_socket(None)
-        self.worker.close()
-        self.finish()
-        logging.info("Everything done")
-
-    def send_event(self, event):
-        event_str = str(event)
-        if len(event_str) > 100:
-            event_str = event_str[:97] + "..."
-        logging.info("%s: Receiving event %s from worker" % (self.id, event_str))
-        if event["status"] == 0 and ("result" in event):
-            try:
-                if len(event["result"]["hypotheses"]) > 0 and event["result"]["final"]:
-                    if len(self.final_hyp) > 0:
-                        self.final_hyp += " "
-                    self.final_hyp += event["result"]["hypotheses"][0]["transcript"]
-            except:
-                e = sys.exc_info()[0]
-                logging.warn("Failed to extract hypothesis from recognition result:" + e)
-        elif event["status"] != 0:
-            self.error_status = event["status"]
-            self.error_message = event.get("message", "")
-
-    def close(self):
-        logging.info("%s: Receiving 'close' from worker" % (self.id))
-        self.final_result_queue.put(self.final_hyp)
-
-
-class ReferenceHandler(tornado.web.RequestHandler):
-    def post(self, *args, **kwargs):
-        content_id = self.request.headers.get("Content-Id")
-        if content_id:
-            content = codecs.decode(self.request.body, "utf-8")
-            user_id = self.request.headers.get("User-Id", "")
-            self.application.save_reference(content_id, dict(content=content, user_id=user_id, time=time.strftime("%Y-%m-%dT%H:%M:%S")))
-            logging.info("Received reference text for content %s and user %s" % (content_id, user_id))
-            self.set_header('Access-Control-Allow-Origin', '*')
-        else:
-            self.set_status(400)
-            self.finish("No Content-Id specified")
-
-    def options(self, *args, **kwargs):
-        self.set_header('Access-Control-Allow-Origin', '*')
-        self.set_header('Access-Control-Allow-Methods', 'POST, OPTIONS')
-        self.set_header('Access-Control-Max-Age', 1000)
-        # note that '*' is not valid for Access-Control-Allow-Headers
-        self.set_header('Access-Control-Allow-Headers',  'origin, x-csrftoken, content-type, accept, User-Id, Content-Id')
-
-
-class StatusSocketHandler(tornado.websocket.WebSocketHandler):
-    # needed for Tornado 4.0
-    def check_origin(self, origin):
-        return True
-
-    def open(self):
-        logging.info("New status listener")
-        self.application.status_listeners.add(self)
-        self.application.send_status_update_single(self)
-
-    def on_close(self):
-        logging.info("Status listener left")
-        self.application.status_listeners.remove(self)
-
-
-class WorkerSocketHandler(tornado.websocket.WebSocketHandler):
-    def __init__(self, application, request, **kwargs):
-        tornado.websocket.WebSocketHandler.__init__(self, application, request, **kwargs)
-        self.client_socket = None
-
-    # needed for Tornado 4.0
-    def check_origin(self, origin):
-        return True
-
-    def open(self):
-        self.client_socket = None
-        self.application.available_workers.add(self)
-        logging.info("New worker available " + self.__str__())
-        self.application.send_status_update()
-
-    def on_close(self):
-        logging.info("Worker " + self.__str__() + " leaving")
-        self.application.available_workers.discard(self)
-        if self.client_socket:
-            self.client_socket.close()
-        self.application.send_status_update()
-
-    def on_message(self, message):
-        assert self.client_socket is not None
-        event = json.loads(message)
-        self.client_socket.send_event(event)
-
-    def set_client_socket(self, client_socket):
-        self.client_socket = client_socket
-
-
-class DecoderSocketHandler(tornado.websocket.WebSocketHandler):
-    # needed for Tornado 4.0
-    def check_origin(self, origin):
-        return True
-
-    def send_event(self, event):
-        event["id"] = self.id
-        event_str = str(event)
-        if len(event_str) > 100:
-            event_str = event_str[:97] + "..."
-        logging.info("%s: Sending event %s to client" % (self.id, event_str))
-        self.write_message(json.dumps(event))
-
-    def open(self):
-        self.id = str(uuid.uuid4())
-        logging.info("%s: OPEN" % (self.id))
-        logging.info("%s: Request arguments: %s" % (self.id, " ".join(["%s=\"%s\"" % (a, self.get_argument(a)) for a in self.request.arguments])))
-        self.user_id = self.get_argument("user-id", "none", True)
-        self.content_id = self.get_argument("content-id", "none", True)
-        self.worker = None
-        try:
-            self.worker = self.application.available_workers.pop()
-            self.application.send_status_update()
-            logging.info("%s: Using worker %s" % (self.id, self.__str__()))
-            self.worker.set_client_socket(self)
-
-            content_type = self.get_argument("content-type", None, True)
-            if content_type:
-                logging.info("%s: Using content type: %s" % (self.id, content_type))
-
-            self.worker.write_message(json.dumps(dict(id=self.id, content_type=content_type, user_id=self.user_id, content_id=self.content_id)))
-        except KeyError:
-            logging.warn("%s: No worker available for client request" % self.id)
-            event = dict(status=common.STATUS_NOT_AVAILABLE, message="No decoder available, try again later")
-            self.send_event(event)
-            self.close()
-
-    def on_connection_close(self):
-        logging.info("%s: Handling on_connection_close()" % self.id)
-        self.application.num_requests_processed += 1
-        self.application.send_status_update()
-        if self.worker:
-            try:
-                self.worker.set_client_socket(None)
-                logging.info("%s: Closing worker connection" % self.id)
-                self.worker.close()
-            except:
-                pass
-
-    def on_message(self, message):
-        assert self.worker is not None
-        logging.info("%s: Forwarding client message (%s) of length %d to worker" % (self.id, type(message), len(message)))
-        if isinstance(message, unicode):
-            self.worker.write_message(message, binary=False)
-        else:
-            self.worker.write_message(message, binary=True)
-
-
-def main():
-    logging.basicConfig(level=logging.DEBUG, format="%(levelname)8s %(asctime)s %(message)s ")
-    logging.debug('Starting up server')
-    from tornado.options import options
-
-    tornado.options.parse_command_line()
-    app = Application()
-    if os.environ.get('WSS'):
-        ssl_ctx = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
-        ssl_ctx.load_cert_chain('/etc/letsencrypt/live/host/cert1.pem', '/etc/letsencrypt/live/host/privkey1.pem')
-        logging.info('wss')
-        app.listen(options.port, ssl_options={"certfile": '/etc/letsencrypt/live/host/cert1.pem', "keyfile": '/etc/letsencrypt/live/host/privkey1.pem'})
-    else:
-        logging.info('ws')
-        app.listen(options.port)
-    tornado.ioloop.IOLoop.instance().start()
-
-
-if __name__ == "__main__":
-    main()
diff --git a/lucida/speechrecognition/kaldi_gstreamer_asr/kaldigstserver/settings.py b/lucida/speechrecognition/kaldi_gstreamer_asr/kaldigstserver/settings.py
deleted file mode 100644
index c3471b83b..000000000
--- a/lucida/speechrecognition/kaldi_gstreamer_asr/kaldigstserver/settings.py
+++ /dev/null
@@ -1,9 +0,0 @@
-'''
-Created on Jun 7, 2013
-
-@author: tanel
-'''
-
-from tornado.options import define
-
-define("port", default=8888, help="run on the given port", type=int)
diff --git a/lucida/speechrecognition/kaldi_gstreamer_asr/kaldigstserver/test-buffer.py b/lucida/speechrecognition/kaldi_gstreamer_asr/kaldigstserver/test-buffer.py
deleted file mode 100644
index 262d74f45..000000000
--- a/lucida/speechrecognition/kaldi_gstreamer_asr/kaldigstserver/test-buffer.py
+++ /dev/null
@@ -1,31 +0,0 @@
-import gi
-gi.require_version('Gst', '1.0')
-from gi.repository import GObject, Gst
-
-GObject.threads_init()
-Gst.init(None)
-
-appsrc = Gst.ElementFactory.make("appsrc", "appsrc")
-filesink = Gst.ElementFactory.make("filesink", "filesink")
-filesink.set_property("location", "test.dat")
-
-pipeline = Gst.Pipeline()
-pipeline.add(appsrc)
-pipeline.add(filesink)
-appsrc.link(filesink)
-pipeline.set_state(Gst.State.PLAYING)
-
-data = "1234" * 12
-print "Using data: %s" % data
-
-buf = Gst.Buffer.new_allocate(None, len(data), None)
-buf.fill(0, data)
-#for (i, c) in enumerate(data):
-#    buf.memset(i, c, 1)
-appsrc.emit("push-buffer", buf)
-
-pipeline.send_event(Gst.Event.new_eos())
-
-result = open("test.dat").read()
-
-print "Result    : %s" % result
\ No newline at end of file
diff --git a/lucida/speechrecognition/kaldi_gstreamer_asr/kaldigstserver/worker.py b/lucida/speechrecognition/kaldi_gstreamer_asr/kaldigstserver/worker.py
deleted file mode 100644
index 76437ba1e..000000000
--- a/lucida/speechrecognition/kaldi_gstreamer_asr/kaldigstserver/worker.py
+++ /dev/null
@@ -1,417 +0,0 @@
-__author__ = 'tanel'
-
-import logging
-import logging.config
-import time
-import thread
-import argparse
-from subprocess import Popen, PIPE
-from gi.repository import GObject
-import yaml
-import json
-import sys
-import locale
-import codecs
-import zlib
-import base64
-import time
-
-
-from ws4py.client.threadedclient import WebSocketClient
-import ws4py.messaging
-
-from decoder import DecoderPipeline
-from decoder2 import DecoderPipeline2
-import common
-
-import os
-
-empty_response = ''
-# unknown_response = 'UNKNOWN'
-# lucida_service = os.environ.get("LUCIDA_SERVICE")
-
-# if not lucida_service == None:
-#     sys.path.append(
-#             os.path.abspath(os.path.join(os.path.dirname(__file__), os.path.pardir)) + "/kaldigstserver/gen-py")
-
-#     from thrift.transport import TTransport
-#     from thrift.transport import TSocket
-#     from thrift.transport import TSSLSocket
-#     from thrift.transport import THttpClient
-#     from thrift.protocol import TBinaryProtocol
-
-#     from commandcenter import CommandCenter
-#     from commandcenter.ttypes import *
-
-#     lucida_toks = lucida_service.split(':')
-#     assert len(lucida_toks) == 2
-#     socket = TSocket.TSocket(lucida_toks[0], int(lucida_toks[1]))
-#     transport = TTransport.TBufferedTransport(socket)
-#     protocol = TBinaryProtocol.TBinaryProtocol(transport)
-#     client = CommandCenter.Client(protocol)
-#     transport.open()
-#     def call_commandcenter(transcript):
-#         qd = QueryData(textData=transcript)
-#         return client.handleRequest(qd)
-
-# else:
-#     def call_commandcenter(transcript):
-#         print '@@@@@@@@@@@@@@@', transcript
-#         return unknown_response
-
-logger = logging.getLogger(__name__)
-
-CONNECT_TIMEOUT = 5
-SILENCE_TIMEOUT = 5
-USE_NNET2 = False
-
-class ServerWebsocket(WebSocketClient):
-	STATE_CREATED = 0
-	STATE_CONNECTED = 1
-	STATE_INITIALIZED = 2
-	STATE_PROCESSING = 3
-	STATE_EOS_RECEIVED = 7
-	STATE_CANCELLING = 8
-	STATE_FINISHED = 100
-
-	def __init__(self, uri, decoder_pipeline, post_processor, full_post_processor=None):
-		self.coachtranscript = empty_response
-		self.uri = uri
-		self.decoder_pipeline = decoder_pipeline
-		self.post_processor = post_processor
-		self.full_post_processor = full_post_processor
-		WebSocketClient.__init__(self, url=uri, heartbeat_freq=10)
-		self.pipeline_initialized = False
-		self.partial_transcript = ""
-		if USE_NNET2:
-			self.decoder_pipeline.set_result_handler(self._on_result)
-			self.decoder_pipeline.set_full_result_handler(self._on_full_result)
-			self.decoder_pipeline.set_error_handler(self._on_error)
-		else:
-			self.decoder_pipeline.set_word_handler(self._on_word)
-			self.decoder_pipeline.set_error_handler(self._on_error)
-		self.decoder_pipeline.set_eos_handler(self._on_eos)
-		self.state = self.STATE_CREATED
-		self.last_decoder_message = time.time()
-		self.request_id = ""
-		self.timeout_decoder = 5
-		self.num_segments = 0
-		self.last_partial_result = ""
-
-	def opened(self):
-		logger.info("Opened websocket connection to server")
-		self.state = self.STATE_CONNECTED
-		self.last_partial_result = ""
-
-	def guard_timeout(self):
-		global SILENCE_TIMEOUT
-		while self.state in [self.STATE_CONNECTED, self.STATE_INITIALIZED, self.STATE_PROCESSING]:
-			if time.time() - self.last_decoder_message > SILENCE_TIMEOUT:
-				logger.warning("%s: More than %d seconds from last decoder hypothesis update, cancelling" % (self.request_id, SILENCE_TIMEOUT))
-				self.finish_request()
-				event = dict(status=common.STATUS_NO_SPEECH)
-				try:
-					self.send(json.dumps(event))
-				except:
-					logger.warning("%s: Failed to send error event to master" % (self.request_id))
-				self.close()
-				return
-			logger.debug("%s: Checking that decoder hasn't been silent for more than %d seconds" % (self.request_id, SILENCE_TIMEOUT))
-			time.sleep(1)
-
-
-	def received_message(self, m):
-		logger.debug("%s: Got message from server of type %s" % (self.request_id, str(type(m))))
-		if self.state == self.__class__.STATE_CONNECTED:
-			props = json.loads(str(m))
-			content_type = props['content_type']
-			self.request_id = props['id']
-			self.num_segments = 0
-			self.decoder_pipeline.init_request(self.request_id, content_type)
-			self.last_decoder_message = time.time()
-			thread.start_new_thread(self.guard_timeout, ())
-			logger.info("%s: Started timeout guard" % self.request_id)
-			logger.info("%s: Initialized request" % self.request_id)
-			self.state = self.STATE_INITIALIZED
-		elif m.data == "EOS":
-			if self.state != self.STATE_CANCELLING and self.state != self.STATE_EOS_RECEIVED and self.state != self.STATE_FINISHED:
-				self.decoder_pipeline.end_request()
-				self.state = self.STATE_EOS_RECEIVED
-			else:
-				logger.info("%s: Ignoring EOS, worker already in state %d" % (self.request_id, self.state))
-		else:
-			if self.state != self.STATE_CANCELLING and self.state != self.STATE_EOS_RECEIVED and self.state != self.STATE_FINISHED:
-				if isinstance(m, ws4py.messaging.BinaryMessage):
-					self.decoder_pipeline.process_data(m.data)
-					self.state = self.STATE_PROCESSING
-				elif isinstance(m, ws4py.messaging.TextMessage):
-					props = json.loads(str(m))
-					if 'adaptation_state' in props:
-						as_props = props['adaptation_state']
-						if as_props.get('type', "") == "string+gzip+base64":
-							adaptation_state = zlib.decompress(base64.b64decode(as_props.get('value', '')))
-							logger.info("%s: Setting adaptation state to user-provided value" % (self.request_id))
-							self.decoder_pipeline.set_adaptation_state(adaptation_state)
-						else:
-							logger.warning("%s: Cannot handle adaptation state type " % (self.request_id, as_props.get('type', "")))
-					else:
-						logger.warning("%s: Got JSON message but don't know what to do with it" % (self.request_id))
-			else:
-				logger.info("%s: Ignoring data, worker already in state %d" % (self.request_id, self.state))
-
-
-	def finish_request(self):
-		if self.state == self.STATE_CONNECTED:
-			# connection closed when we are not doing anything
-			self.decoder_pipeline.finish_request()
-			self.state = self.STATE_FINISHED
-			return
-		if self.state == self.STATE_INITIALIZED:
-			# connection closed when request initialized but with no data sent
-			self.decoder_pipeline.finish_request()
-			self.state = self.STATE_FINISHED
-			return
-		if self.state != self.STATE_FINISHED:
-			logger.info("%s: Master disconnected before decoder reached EOS?" % self.request_id)
-			self.state = self.STATE_CANCELLING
-			self.decoder_pipeline.cancel()
-			counter = 0
-			while self.state == self.STATE_CANCELLING:
-				counter += 1
-				if counter > 30:
-					# lost hope that the decoder will ever finish, likely it has hung
-					# FIXME: this might introduce new bugs
-					logger.info("%s: Giving up waiting after %d tries" % (self.request_id, counter))
-					self.state = self.STATE_FINISHED
-				else:
-					logger.info("%s: Waiting for EOS from decoder" % self.request_id)
-					time.sleep(1)
-			self.decoder_pipeline.finish_request()
-			logger.info("%s: Finished waiting for EOS" % self.request_id)
-
-
-	def closed(self, code, reason=None):
-		logger.debug("%s: Websocket closed() called" % self.request_id)
-		self.finish_request()
-		logger.debug("%s: Websocket closed() finished" % self.request_id)
-
-	def _on_result(self, result, final):
-		if final:
-			# final results are handled by _on_full_result()
-			transcript = result.decode('utf8')
-			self.coachtranscript += ' ' + transcript
-			return
-		self.last_decoder_message = time.time()
-		if self.last_partial_result == result:
-			return
-		self.last_partial_result = result
-		logger.info("%s: Postprocessing (final=%s) result.."  % (self.request_id, final))
-		if final:
-			logger.info("%s: Before postprocessing: %s" % (self.request_id, result))
-		processed_transcript = self.post_process(result)
-		logger.info("%s: Postprocessing done." % self.request_id)
-		if final:
-			logger.info("%s: After postprocessing: %s" % (self.request_id, processed_transcript))
-
-		event = dict(status=common.STATUS_SUCCESS,
-					 segment=self.num_segments,
-					 result=dict(hypotheses=[dict(transcript=processed_transcript)], final=final))
-		try:
-			self.send(json.dumps(event))
-		except:
-			e = sys.exc_info()[1]
-			logger.warning("Failed to send event to master: %s" % e)
-
-	def _on_full_result(self, full_result_json):
-		self.last_decoder_message = time.time()
-		full_result = json.loads(full_result_json)
-		if full_result.get("status", -1) == common.STATUS_SUCCESS:
-			#logger.info("%s: Postprocessing (final=%s) result.."  % (self.request_id, final))
-			logger.debug("%s: Before postprocessing: %s" % (self.request_id, full_result))
-			full_result = self.post_process_full(full_result)
-			logger.info("%s: Postprocessing done." % self.request_id)
-			logger.debug("%s: After postprocessing: %s" % (self.request_id, full_result))
-
-			try:
-				self.send(json.dumps(full_result))
-			except:
-				e = sys.exc_info()[1]
-				logger.warning("Failed to send event to master: %s" % e)
-			if full_result.get("result", {}).get("final", True):
-				self.num_segments += 1
-				self.last_partial_result = ""
-		else:
-			logger.info("%s: Result status is %d, forwarding the result to the server anyway" % (self.request_id, full_result.get("status", -1)))
-			try:
-				self.send(json.dumps(full_result))
-			except:
-				e = sys.exc_info()[1]
-				logger.warning("Failed to send event to master: %s" % e)
-
-
-	def _on_word(self, word):
-		self.last_decoder_message = time.time()
-		if word != "<#s>":
-			if len(self.partial_transcript) > 0:
-				self.partial_transcript += " "
-			self.partial_transcript += word
-			logger.debug("%s: Postprocessing partial result.."  % self.request_id)
-			processed_transcript = self.post_process(self.partial_transcript)
-			logger.debug("%s: Postprocessing done." % self.request_id)
-
-			event = dict(status=common.STATUS_SUCCESS,
-						 segment=self.num_segments,
-						 result=dict(hypotheses=[dict(transcript=processed_transcript)], final=False))
-			self.send(json.dumps(event))
-		else:
-			logger.info("%s: Postprocessing final result.."  % self.request_id)
-			processed_transcript = self.post_process(self.partial_transcript)
-			logger.info("%s: Postprocessing done." % self.request_id)
-			event = dict(status=common.STATUS_SUCCESS,
-						 segment=self.num_segments,
-						 result=dict(hypotheses=[dict(transcript=processed_transcript)], final=True))
-			self.send(json.dumps(event))
-			self.partial_transcript = ""
-			self.num_segments += 1
-
-
-	def _on_eos(self, data=None):
-		self.last_decoder_message = time.time()
-		self.state = self.STATE_FINISHED
-		#self.send_adaptation_state()
-		self.close()
-
-	def _on_error(self, error):
-		self.state = self.STATE_FINISHED
-		event = dict(status=common.STATUS_NOT_ALLOWED, message=error)
-		try:
-			self.send(json.dumps(event))
-		except:
-			e = sys.exc_info()[1]
-			logger.warning("Failed to send event to master: %s" % e)
-		self.close()
-
-	# def send_adaptation_state(self):
-	#     if hasattr(self.decoder_pipeline, 'get_adaptation_state'):
-	#         logger.info("%s: Sending adaptation state to client..." % (self.request_id))
-	#         adaptation_state = self.decoder_pipeline.get_adaptation_state()
-
-
-	#         print '########################'
-	#         logger.info('$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$') 
-	#         print self.coachtranscript
-	#         logger.info(self.coachtranscript) 
-
-
-
-
-	#         event = dict(status=common.STATUS_SUCCESS,
-	#                      hascoachresponse=True,
-	#                      coachresponse=call_commandcenter(self.coachtranscript),
-	#                      adaptation_state=dict(id=self.request_id,
-	#                                            value=base64.b64encode(zlib.compress(adaptation_state)),
-	#                                            type="string+gzip+base64",
-	#                                            time=time.strftime("%Y-%m-%dT%H:%M:%S")))
-	#         self.coachtranscript = empty_response
-	#         try:
-	#             self.send(json.dumps(event))
-	#         except:
-	#             e = sys.exc_info()[1]
-	#             logger.warning("Failed to send event to master: " + str(e))
-	#     else:
-	#         logger.info("%s: Adaptation state not supported by the decoder, not sending it." % (self.request_id))
-
-
-	def post_process(self, text):
-		if self.post_processor:
-			self.post_processor.stdin.write("%s\n" % text)
-			self.post_processor.stdin.flush()
-			text = self.post_processor.stdout.readline()
-			text = text.strip()
-			text = text.replace("\\n", "\n")
-			return text
-		else:
-			return text
-
-	def post_process_full(self, full_result):
-		if self.full_post_processor:
-			self.full_post_processor.stdin.write("%s\n\n" % json.dumps(full_result))
-			self.post_processor.stdin.flush()
-			lines = []
-			while True:
-				l = self.full_post_processor.stdout.readline()
-				if not l: break # EOF
-				if l.strip() == "":
-					break
-				lines.append(l)
-			full_result = json.loads("".join(lines))
-
-		elif self.post_processor:
-			for hyp in full_result.get("result", {}).get("hypotheses", []):
-				hyp["original-transcript"] = hyp["transcript"]
-				hyp["transcript"] = self.post_process(hyp["transcript"])
-		return full_result
-
-
-
-
-def main():
-	logging.basicConfig(level=logging.DEBUG, format="%(levelname)8s %(asctime)s %(message)s ")
-	logging.debug('Starting up worker')
-	parser = argparse.ArgumentParser(description='Worker for kaldigstserver')
-	parser.add_argument('-u', '--uri', default="ws://localhost:8888/worker/ws/speech", dest="uri", help="Server<-->worker websocket URI")
-	parser.add_argument('-f', '--fork', default=1, dest="fork", type=int)
-	parser.add_argument('-c', '--conf', dest="conf", help="YAML file with decoder configuration")
-
-	args = parser.parse_args()
-
-	if args.fork > 1:
-		import tornado.process
-
-		logging.info("Forking into %d processes" % args.fork)
-		tornado.process.fork_processes(args.fork)
-
-	conf = {}
-	if args.conf:
-		with open(args.conf) as f:
-			conf = yaml.safe_load(f)
-
-	if "logging" in conf:
-		logging.config.dictConfig(conf["logging"])
-
-	global USE_NNET2
-	USE_NNET2 = conf.get("use-nnet2", False)
-
-	global SILENCE_TIMEOUT
-	SILENCE_TIMEOUT = conf.get("silence-timeout", 5)
-	if USE_NNET2:
-		decoder_pipeline = DecoderPipeline2(conf)
-	else:
-		decoder_pipeline = DecoderPipeline(conf)
-
-	post_processor = None
-	if "post-processor" in conf:
-		post_processor = Popen(conf["post-processor"], shell=True, stdin=PIPE, stdout=PIPE)
-
-	full_post_processor = None
-	if "full-post-processor" in conf:
-		full_post_processor = Popen(conf["full-post-processor"], shell=True, stdin=PIPE, stdout=PIPE)
-
-
-	loop = GObject.MainLoop()
-	thread.start_new_thread(loop.run, ())
-	while True:
-		ws = ServerWebsocket(args.uri, decoder_pipeline, post_processor, full_post_processor=full_post_processor)
-		try:
-			logger.info("Opening websocket connection to master server")
-			ws.connect()
-			ws.run_forever()
-		except Exception:
-			logger.error("Couldn't connect to server, waiting for %d seconds", CONNECT_TIMEOUT)
-			time.sleep(CONNECT_TIMEOUT)
-		# fixes a race condition
-		time.sleep(1)
-
-if __name__ == "__main__":
-	main()
-
diff --git a/lucida/speechrecognition/kaldi_gstreamer_asr/sample_english_nnet2.yaml b/lucida/speechrecognition/kaldi_gstreamer_asr/sample_english_nnet2.yaml
deleted file mode 100644
index 35945ed82..000000000
--- a/lucida/speechrecognition/kaldi_gstreamer_asr/sample_english_nnet2.yaml
+++ /dev/null
@@ -1,54 +0,0 @@
-# You have to download TEDLIUM "online nnet2" models in order to use this sample
-# Run download-tedlium-nnet2.sh in 'test/models' to download them.
-use-nnet2: True
-decoder:
-    # All the properties nested here correspond to the kaldinnet2onlinedecoder GStreamer plugin properties.
-    # Use gst-inspect-1.0 ./libgstkaldionline2.so kaldinnet2onlinedecoder to discover the available properties
-    use-threaded-decoder:  true
-    model : test/models/english/fisher_nnet_a_gpu_online/final.mdl
-    word-syms : test/models/english/fisher_nnet_a_gpu_online/words.txt
-    fst : test/models/english/fisher_nnet_a_gpu_online/HCLG.fst
-    mfcc-config : test/models/english/fisher_nnet_a_gpu_online/conf/mfcc.conf
-    ivector-extraction-config : test/models/english/fisher_nnet_a_gpu_online/conf/ivector_extractor.fixed.conf
-    max-active: 10000
-    beam: 10.0
-    lattice-beam: 6.0
-    acoustic-scale: 0.083
-    do-endpointing : true
-    endpoint-silence-phones : "1:2:3:4:5:6:7:8:9:10"
-    traceback-period-in-secs: 0.25
-    chunk-length-in-secs: 0.25
-    num-nbest: 10
-    #Additional functionality that you can play with:
-    #lm-fst:  test/models/english/tedlium_nnet_ms_sp_online/G.fst
-    #big-lm-const-arpa: test/models/english/tedlium_nnet_ms_sp_online/G.carpa
-    #phone-syms: test/models/english/tedlium_nnet_ms_sp_online/phones.txt
-    #word-boundary-file: test/models/english/tedlium_nnet_ms_sp_online/word_boundary.int
-    #do-phone-alignment: true
-out-dir: tmp
-
-use-vad: False
-silence-timeout: 10
-
-# Just a sample post-processor that appends "." to the hypothesis
-post-processor: perl -npe 'BEGIN {use IO::Handle; STDOUT->autoflush(1);} s/(.*)/\1./;'
-
-# A sample full post processor that add a confidence score to 1-best hyp and deletes other n-best hyps
-full-post-processor: ./sample_full_post_processor.py
-
-logging:
-    version : 1
-    disable_existing_loggers: False
-    formatters:
-        simpleFormater:
-            format: '%(asctime)s - %(levelname)7s: %(name)10s: %(message)s'
-            datefmt: '%Y-%m-%d %H:%M:%S'
-    handlers:
-        console:
-            class: logging.StreamHandler
-            formatter: simpleFormater
-            level: DEBUG
-    root:
-        level: DEBUG
-        handlers: [console]
-
diff --git a/lucida/speechrecognition/kaldi_gstreamer_asr/sample_full_post_processor.py b/lucida/speechrecognition/kaldi_gstreamer_asr/sample_full_post_processor.py
deleted file mode 100755
index b6fe2a76b..000000000
--- a/lucida/speechrecognition/kaldi_gstreamer_asr/sample_full_post_processor.py
+++ /dev/null
@@ -1,57 +0,0 @@
-#!/usr/bin/env python
-'''
-Sample script that shows how to postprocess full results from the kaldi-gstreamer-worker, encoded as JSON.
-
-It adds a sentence confidence score to the 1-best hypothesis, deletes all other hypotheses and
-adds a dot (.) to the end of the 1-best hypothesis. It assumes that the results contain at least two hypotheses,
-The confidence scores are now normalized
-'''
-
-import sys
-import json
-import logging
-from math import exp
-
-def post_process_json(str):
-    try:
-        event = json.loads(str)
-        if "result" in event:
-            if len(event["result"]["hypotheses"]) > 1:
-                likelihood1 = event["result"]["hypotheses"][0]["likelihood"]
-                likelihood2 = event["result"]["hypotheses"][1]["likelihood"]
-                confidence = likelihood1 - likelihood2
-                confidence = 1 - exp(-confidence)
-            else:
-                confidence = 1.0e+10;
-            event["result"]["hypotheses"][0]["confidence"] = confidence
-
-            event["result"]["hypotheses"][0]["transcript"] += "."
-            del event["result"]["hypotheses"][1:]
-        return json.dumps(event)
-    except:
-        exc_type, exc_value, exc_traceback = sys.exc_info()
-        logging.error("Failed to process JSON result: %s : %s " % (exc_type, exc_value))
-        return str
-
-
-if __name__ == "__main__":
-    logging.basicConfig(level=logging.DEBUG, format="%(levelname)8s %(asctime)s %(message)s ")
-
-    lines = []
-    while True:
-        l = sys.stdin.readline()
-        if not l: break # EOF
-        if l.strip() == "":
-            if len(lines) > 0:
-                result_json = post_process_json("".join(lines))
-                print result_json
-                print
-                sys.stdout.flush()
-                lines = []
-        else:
-            lines.append(l)
-
-    if len(lines) > 0:
-        result_json = post_process_json("".join(lines))
-        print result_json
-        lines = []
diff --git a/lucida/speechrecognition/kaldi_gstreamer_asr/sample_worker.yaml b/lucida/speechrecognition/kaldi_gstreamer_asr/sample_worker.yaml
deleted file mode 100644
index ef3fa13ae..000000000
--- a/lucida/speechrecognition/kaldi_gstreamer_asr/sample_worker.yaml
+++ /dev/null
@@ -1,29 +0,0 @@
-timeout-decoder : 10
-decoder:
-   model: test/models/english/voxforge/tri2b_mmi_b0.05/final.mdl
-   lda-mat: test/models/english/voxforge/tri2b_mmi_b0.05/final.mat
-   word-syms: test/models/english/voxforge/tri2b_mmi_b0.05/words.txt
-   fst: test/models/english/voxforge/tri2b_mmi_b0.05/HCLG.fst
-   silence-phones: "1:2:3:4:5"
-out-dir: tmp
-
-use-vad: False
-silence-timeout: 60
-
-# Just a sample post-processor that appends "." to the hypothesis
-post-processor: perl -npe 'BEGIN {use IO::Handle; STDOUT->autoflush(1);} s/(.*)/\1./;'
-logging:
-    version : 1
-    disable_existing_loggers: False
-    formatters:
-        simpleFormater:
-            format: '%(asctime)s - %(levelname)7s: %(name)10s: %(message)s'
-            datefmt: '%Y-%m-%d %H:%M:%S'
-    handlers:
-        console:
-            class: logging.StreamHandler
-            formatter: simpleFormater
-            level: DEBUG
-    root:
-        level: DEBUG
-        handlers: [console]
diff --git a/lucida/speechrecognition/kaldi_gstreamer_asr/simple_start.sh b/lucida/speechrecognition/kaldi_gstreamer_asr/simple_start.sh
deleted file mode 100755
index 15b3c9c52..000000000
--- a/lucida/speechrecognition/kaldi_gstreamer_asr/simple_start.sh
+++ /dev/null
@@ -1,9 +0,0 @@
-#!/bin/bash
-export GST_PLUGIN_PATH=$(pwd)/kaldi/tools/gst-kaldi-nnet2-online/src
-source $(pwd)/../../config.properties
-if [ -z $SECURE_HOST ]; then
-	export ASR_ADDR_PORT="ws://localhost:$CMD_PORT"
-else
-	export ASR_ADDR_PORT="wss://localhost:$CMD_PORT"
-fi
-python kaldigstserver/worker.py -u ${ASR_ADDR_PORT}/worker/ws/speech -c sample_english_nnet2.yaml
diff --git a/lucida/speechrecognition/kaldi_gstreamer_asr/start.sh b/lucida/speechrecognition/kaldi_gstreamer_asr/start.sh
deleted file mode 100755
index 12402d2c7..000000000
--- a/lucida/speechrecognition/kaldi_gstreamer_asr/start.sh
+++ /dev/null
@@ -1,42 +0,0 @@
-#!/bin/bash
-
-MASTER="localhost"
-PORT=8888
-
-usage(){
-  echo "Creates a worker and connects it to a master.";
-  echo "If the master address is not given, a master will be created at localhost:80";
-  echo "Usage: $0 -y yaml_file [-m master address] [-p port number]";
-}
-
-while getopts "h?m:p:y:" opt; do
-    case "$opt" in
-    h|\?)
-        usage
-        exit 0
-        ;;
-    m)  MASTER=$OPTARG
-        ;;
-    p)  PORT=$OPTARG
-        ;;
-    y)  YAML=$OPTARG
-        ;;
-    esac
-done
-
-#yaml file must be specified
-if [ "$YAML" == "" ] ; then
-  usage;
-  exit 1;
-fi;
-
-
-if [ "$MASTER" == "localhost" ] ; then
-  # start a local master
-  python /kaldigstserver/master_server.py --port="$PORT" 2>> master.log &
-fi
-
-#start worker and connect it to the master
-export GST_PLUGIN_PATH=kaldi/tools/gst-kaldi-nnet2-online/src/:kaldi/src/gst-plugin/
-
-python kaldigstserver/worker.py -c "$YAML" -u ws://"$MASTER:$PORT"/worker/ws/speech 2>> worker.log &
diff --git a/lucida/speechrecognition/kaldi_gstreamer_asr/static/status.html b/lucida/speechrecognition/kaldi_gstreamer_asr/static/status.html
deleted file mode 100644
index 26e4619c8..000000000
--- a/lucida/speechrecognition/kaldi_gstreamer_asr/static/status.html
+++ /dev/null
@@ -1,23 +0,0 @@
-
-
-  
-
-  
-  
-
-
-
-Speech server status: 
- - - - - \ No newline at end of file diff --git a/lucida/speechrecognition/kaldi_gstreamer_asr/stop.sh b/lucida/speechrecognition/kaldi_gstreamer_asr/stop.sh deleted file mode 100755 index 575bbd3c8..000000000 --- a/lucida/speechrecognition/kaldi_gstreamer_asr/stop.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/bash - -#kill worker -ps axf | grep worker.py | grep -v grep | awk '{print "kill -15 " $1}' | sh - -#kill master -ps axf | grep master_server.py | grep -v grep | awk '{print "kill -15 " $1}' | sh - diff --git a/lucida/speechrecognition/kaldi_gstreamer_asr/test/data/bill_gates-TED.mp3 b/lucida/speechrecognition/kaldi_gstreamer_asr/test/data/bill_gates-TED.mp3 deleted file mode 100644 index 06cbb26ac093c96de86ce237e8aa5aa79b6370ae..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 496746 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 Ox_JFBRsZP`?0*0fsJxs2 diff --git a/lucida/speechrecognition/kaldi_gstreamer_asr/test/models/download-fisher-nnet2.sh b/lucida/speechrecognition/kaldi_gstreamer_asr/test/models/download-fisher-nnet2.sh deleted file mode 100755 index 2125c7173..000000000 --- a/lucida/speechrecognition/kaldi_gstreamer_asr/test/models/download-fisher-nnet2.sh +++ /dev/null @@ -1,30 +0,0 @@ -#!/bin/bash - -BASE_URL=http://kaldi-asr.org/downloads/build/2/sandbox/online/egs/fisher_english/s5 - -MODEL=exp/nnet2_online/nnet_a_gpu_online -GRAPH=exp/tri5a - -modeldir=$(dirname "$0")/english/fisher_nnet_a_gpu_online - -mkdir -p "$modeldir" - -cd "$modeldir" - -wget -N $BASE_URL/$MODEL/final.mdl -if [ $? -ne 0 ]; then rm -rf final.mdl; exit 1; fi - -(mkdir -p ivector_extractor; cd ivector_extractor; wget -N $BASE_URL/$MODEL/ivector_extractor/{final.ie,final.dubm,final.mat,global_cmvn.stats}) -if [ $? -ne 0 ]; then rm -rf ivector_extractor; exit 1; fi -(mkdir -p conf; cd conf; wget -N $BASE_URL/$MODEL/conf/{ivector_extractor.conf,online_nnet2_decoding.conf,mfcc.conf,online_cmvn.conf,splice.conf}) -if [ $? -ne 0 ]; then rm -rf conf; exit 1; fi - -wget -N $BASE_URL/$GRAPH/graph/HCLG.fst -if [ $? -ne 0 ]; then rm -rf HCLG.fst; exit 1; fi -wget -N $BASE_URL/$GRAPH/graph/words.txt -if [ $? -ne 0 ]; then rm -rf words.txt; exit 1; fi - - -cat conf/ivector_extractor.conf | perl -npe "s/=.*nnet_a_gpu_online\//=test\/models\/english\/fisher_nnet_a_gpu_online\//" > conf/ivector_extractor.fixed.conf - -cd - diff --git a/lucida/speechrecognition/kaldi_gstreamer_asr/test/models/download-tedlium-nnet2.sh b/lucida/speechrecognition/kaldi_gstreamer_asr/test/models/download-tedlium-nnet2.sh deleted file mode 100755 index ca2a54061..000000000 --- a/lucida/speechrecognition/kaldi_gstreamer_asr/test/models/download-tedlium-nnet2.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash - -curl https://phon.ioc.ee/~tanela/tedlium_nnet_ms_sp_online.tgz | tar zxv diff --git a/lucida/speechrecognition/wit_stt/logger_config.yaml b/lucida/speechrecognition/logger_config.yaml similarity index 99% rename from lucida/speechrecognition/wit_stt/logger_config.yaml rename to lucida/speechrecognition/logger_config.yaml index e8b7fd2fa..f19278e18 100644 --- a/lucida/speechrecognition/wit_stt/logger_config.yaml +++ b/lucida/speechrecognition/logger_config.yaml @@ -12,4 +12,3 @@ handlers: root: level: DEBUG handlers: [console] - diff --git a/lucida/speechrecognition/plugin/.gitignore b/lucida/speechrecognition/plugin/.gitignore new file mode 100644 index 000000000..b864463d7 --- /dev/null +++ b/lucida/speechrecognition/plugin/.gitignore @@ -0,0 +1,16 @@ +aclocal.m4 +autom4te.cache +autoregen.sh +config.* +configure +libtool +INSTALL +Makefile.in +depcomp +install-sh +ltmain.sh +missing +stamp-* +my-plugin-*.tar.* +*~ + diff --git a/lucida/speechrecognition/plugin/AUTHORS b/lucida/speechrecognition/plugin/AUTHORS new file mode 100644 index 000000000..1bb7449a0 --- /dev/null +++ b/lucida/speechrecognition/plugin/AUTHORS @@ -0,0 +1 @@ +Thomas Vander Stichele diff --git a/lucida/speechrecognition/plugin/COPYING b/lucida/speechrecognition/plugin/COPYING new file mode 100644 index 000000000..09ec995da --- /dev/null +++ b/lucida/speechrecognition/plugin/COPYING @@ -0,0 +1,2 @@ +Put your license in here! + diff --git a/lucida/speechrecognition/kaldi_gstreamer_asr/kaldigstserver/__init__.py b/lucida/speechrecognition/plugin/ChangeLog similarity index 100% rename from lucida/speechrecognition/kaldi_gstreamer_asr/kaldigstserver/__init__.py rename to lucida/speechrecognition/plugin/ChangeLog diff --git a/lucida/speechrecognition/plugin/Makefile b/lucida/speechrecognition/plugin/Makefile new file mode 100644 index 000000000..c2270171a --- /dev/null +++ b/lucida/speechrecognition/plugin/Makefile @@ -0,0 +1,817 @@ +# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile. Generated from Makefile.in by configure. + +# Copyright (C) 1994-2014 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + + + +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/asrplugin +pkgincludedir = $(includedir)/asrplugin +pkglibdir = $(libdir)/asrplugin +pkglibexecdir = $(libexecdir)/asrplugin +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = x86_64-pc-linux-gnu +host_triplet = x86_64-pc-linux-gnu +subdir = . +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \ + $(am__configure_deps) $(am__DIST_COMMON) +am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ + configure.lineno config.status.lineno +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_$(V)) +am__v_P_ = $(am__v_P_$(AM_DEFAULT_VERBOSITY)) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_$(V)) +am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_$(V)) +am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY)) +am__v_at_0 = @ +am__v_at_1 = +SOURCES = +DIST_SOURCES = +RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ + ctags-recursive dvi-recursive html-recursive info-recursive \ + install-data-recursive install-dvi-recursive \ + install-exec-recursive install-html-recursive \ + install-info-recursive install-pdf-recursive \ + install-ps-recursive install-recursive installcheck-recursive \ + installdirs-recursive pdf-recursive ps-recursive \ + tags-recursive uninstall-recursive +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +am__recursive_targets = \ + $(RECURSIVE_TARGETS) \ + $(RECURSIVE_CLEAN_TARGETS) \ + $(am__extra_recursive_targets) +AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ + cscope distdir dist dist-all distcheck +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \ + $(LISP)config.h.in +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +CSCOPE = cscope +DIST_SUBDIRS = $(SUBDIRS) +am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/config.h.in AUTHORS \ + COPYING ChangeLog INSTALL NEWS README compile config.guess \ + config.sub install-sh ltmain.sh missing +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +distdir = $(PACKAGE)-$(VERSION) +top_distdir = $(distdir) +am__remove_distdir = \ + if test -d "$(distdir)"; then \ + find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ + && rm -rf "$(distdir)" \ + || { sleep 5 && rm -rf "$(distdir)"; }; \ + else :; fi +am__post_remove_distdir = $(am__remove_distdir) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +DIST_ARCHIVES = $(distdir).tar.gz +GZIP_ENV = --best +DIST_TARGETS = dist-gzip +distuninstallcheck_listfiles = find . -type f -print +am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ + | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' +distcleancheck_listfiles = find . -type f -print +ACLOCAL = ${SHELL} /usr/local/src/lucida/lucida/speechrecognition/plugin/missing aclocal-1.15 +AMTAR = $${TAR-tar} +AM_DEFAULT_VERBOSITY = 1 +AR = ar +AUTOCONF = ${SHELL} /usr/local/src/lucida/lucida/speechrecognition/plugin/missing autoconf +AUTOHEADER = ${SHELL} /usr/local/src/lucida/lucida/speechrecognition/plugin/missing autoheader +AUTOMAKE = ${SHELL} /usr/local/src/lucida/lucida/speechrecognition/plugin/missing automake-1.15 +AWK = gawk +CC = gcc +CCDEPMODE = depmode=gcc3 +CFLAGS = -g -O2 -Wall +CPP = gcc -E +CPPFLAGS = +CYGPATH_W = echo +DEFS = -DHAVE_CONFIG_H +DEPDIR = .deps +DLLTOOL = false +DSYMUTIL = +DUMPBIN = +ECHO_C = +ECHO_N = -n +ECHO_T = +EGREP = /bin/grep -E +EXEEXT = +FGREP = /bin/grep -F +GREP = /bin/grep +GST_CFLAGS = -pthread -I/usr/include/gstreamer-1.0 -I/usr/lib/x86_64-linux-gnu/gstreamer-1.0/include -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -Wall +GST_LIBS = -lgstcontroller-1.0 -lgstaudio-1.0 -lgstbase-1.0 -lgstreamer-1.0 -lgobject-2.0 -lglib-2.0 -ljansson +GST_PLUGIN_LDFLAGS = -module -avoid-version -export-symbols-regex _*\(gst_\|Gst\|GST_\).* +HAVE_PKGCONFIG = +INSTALL = /usr/bin/install -c +INSTALL_DATA = ${INSTALL} -m 644 +INSTALL_PROGRAM = ${INSTALL} +INSTALL_SCRIPT = ${INSTALL} +INSTALL_STRIP_PROGRAM = $(install_sh) -c -s +LD = /usr/bin/ld -m elf_x86_64 +LDFLAGS = +LIBOBJS = +LIBS = +LIBTOOL = $(SHELL) $(top_builddir)/libtool +LIPO = +LN_S = ln -s +LTLIBOBJS = +LT_SYS_LIBRARY_PATH = +MAINT = +MAKEINFO = ${SHELL} /usr/local/src/lucida/lucida/speechrecognition/plugin/missing makeinfo +MANIFEST_TOOL = : +MKDIR_P = /bin/mkdir -p +NM = /usr/bin/nm -B +NMEDIT = +OBJDUMP = objdump +OBJEXT = o +OTOOL = +OTOOL64 = +PACKAGE = asrplugin +PACKAGE_BUGREPORT = https://github.com/claritylab/lucida/issues +PACKAGE_NAME = asrplugin +PACKAGE_STRING = asrplugin 1.0.0 +PACKAGE_TARNAME = asrplugin +PACKAGE_URL = https://github.com/claritylab/lucida/tree/master/lucida/speechrecognition +PACKAGE_VERSION = 1.0.0 +PATH_SEPARATOR = : +PKG_CONFIG = /usr/bin/pkg-config +PKG_CONFIG_LIBDIR = +PKG_CONFIG_PATH = +RANLIB = ranlib +SED = /bin/sed +SET_MAKE = +SHELL = /bin/sh +STRIP = strip +VERSION = 1.0.0 +abs_builddir = /usr/local/src/lucida/lucida/speechrecognition/plugin +abs_srcdir = /usr/local/src/lucida/lucida/speechrecognition/plugin +abs_top_builddir = /usr/local/src/lucida/lucida/speechrecognition/plugin +abs_top_srcdir = /usr/local/src/lucida/lucida/speechrecognition/plugin +ac_ct_AR = ar +ac_ct_CC = gcc +ac_ct_DUMPBIN = +am__include = include +am__leading_dot = . +am__quote = +am__tar = $${TAR-tar} chof - "$$tardir" +am__untar = $${TAR-tar} xf - +bindir = ${exec_prefix}/bin +build = x86_64-pc-linux-gnu +build_alias = +build_cpu = x86_64 +build_os = linux-gnu +build_vendor = pc +builddir = . +datadir = ${datarootdir} +datarootdir = ${prefix}/share +docdir = ${datarootdir}/doc/${PACKAGE_TARNAME} +dvidir = ${docdir} +exec_prefix = ${prefix} +host = x86_64-pc-linux-gnu +host_alias = +host_cpu = x86_64 +host_os = linux-gnu +host_vendor = pc +htmldir = ${docdir} +includedir = ${prefix}/include +infodir = ${datarootdir}/info +install_sh = ${SHELL} /usr/local/src/lucida/lucida/speechrecognition/plugin/install-sh +libdir = ${exec_prefix}/lib +libexecdir = ${exec_prefix}/libexec +localedir = ${datarootdir}/locale +localstatedir = ${prefix}/var +mandir = ${datarootdir}/man +mkdir_p = $(MKDIR_P) +oldincludedir = /usr/include +pdfdir = ${docdir} +plugindir = $(libdir)/gstreamer-1.0 +prefix = /usr/local +program_transform_name = s,x,x, +psdir = ${docdir} +runstatedir = ${localstatedir}/run +sbindir = ${exec_prefix}/sbin +sharedstatedir = ${prefix}/com +srcdir = . +sysconfdir = ${prefix}/etc +target_alias = +top_build_prefix = +top_builddir = . +top_srcdir = . +SUBDIRS = src +EXTRA_DIST = autogen.sh +all: config.h + $(MAKE) $(AM_MAKEFLAGS) all-recursive + +.SUFFIXES: +am--refresh: Makefile + @: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + echo ' cd $(srcdir) && $(AUTOMAKE) --gnu'; \ + $(am__cd) $(srcdir) && $(AUTOMAKE) --gnu \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + echo ' $(SHELL) ./config.status'; \ + $(SHELL) ./config.status;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + $(SHELL) ./config.status --recheck + +$(top_srcdir)/configure: $(am__configure_deps) + $(am__cd) $(srcdir) && $(AUTOCONF) +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) +$(am__aclocal_m4_deps): + +config.h: stamp-h1 + @test -f $@ || rm -f stamp-h1 + @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1 + +stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status + @rm -f stamp-h1 + cd $(top_builddir) && $(SHELL) ./config.status config.h +$(srcdir)/config.h.in: $(am__configure_deps) + ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) + rm -f stamp-h1 + touch $@ + +distclean-hdr: + -rm -f config.h stamp-h1 + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool config.lt + +# This directory's subdirectories are mostly independent; you can cd +# into them and run 'make' without going through this Makefile. +# To change the values of 'make' variables: instead of editing Makefiles, +# (1) if the variable is set in 'config.status', edit 'config.status' +# (which will cause the Makefiles to be regenerated when you run 'make'); +# (2) otherwise, pass the desired values on the 'make' command line. +$(am__recursive_targets): + @fail=; \ + if $(am__make_keepgoing); then \ + failcom='fail=yes'; \ + else \ + failcom='exit 1'; \ + fi; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-recursive +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-recursive + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscope: cscope.files + test ! -s cscope.files \ + || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS) +clean-cscope: + -rm -f cscope.files +cscope.files: clean-cscope cscopelist +cscopelist: cscopelist-recursive + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + -rm -f cscope.out cscope.in.out cscope.po.out cscope.files + +distdir: $(DISTFILES) + $(am__remove_distdir) + test -d "$(distdir)" || mkdir "$(distdir)" + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + $(am__make_dryrun) \ + || test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done + -test -n "$(am__skip_mode_fix)" \ + || find "$(distdir)" -type d ! -perm -755 \ + -exec chmod u+rwx,go+rx {} \; -o \ + ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ + || chmod -R a+r "$(distdir)" +dist-gzip: distdir + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + $(am__post_remove_distdir) + +dist-bzip2: distdir + tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 + $(am__post_remove_distdir) + +dist-lzip: distdir + tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz + $(am__post_remove_distdir) + +dist-xz: distdir + tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz + $(am__post_remove_distdir) + +dist-tarZ: distdir + @echo WARNING: "Support for distribution archives compressed with" \ + "legacy program 'compress' is deprecated." >&2 + @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 + tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z + $(am__post_remove_distdir) + +dist-shar: distdir + @echo WARNING: "Support for shar distribution archives is" \ + "deprecated." >&2 + @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 + shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz + $(am__post_remove_distdir) + +dist-zip: distdir + -rm -f $(distdir).zip + zip -rq $(distdir).zip $(distdir) + $(am__post_remove_distdir) + +dist dist-all: + $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:' + $(am__post_remove_distdir) + +# This target untars the dist file and tries a VPATH configuration. Then +# it guarantees that the distribution is self-contained by making another +# tarfile. +distcheck: dist + case '$(DIST_ARCHIVES)' in \ + *.tar.gz*) \ + GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ + *.tar.bz2*) \ + bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ + *.tar.lz*) \ + lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ + *.tar.xz*) \ + xz -dc $(distdir).tar.xz | $(am__untar) ;;\ + *.tar.Z*) \ + uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ + *.shar.gz*) \ + GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ + *.zip*) \ + unzip $(distdir).zip ;;\ + esac + chmod -R a-w $(distdir) + chmod u+w $(distdir) + mkdir $(distdir)/_build $(distdir)/_build/sub $(distdir)/_inst + chmod a-w $(distdir) + test -d $(distdir)/_build || exit 0; \ + dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ + && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ + && am__cwd=`pwd` \ + && $(am__cd) $(distdir)/_build/sub \ + && ../../configure \ + $(AM_DISTCHECK_CONFIGURE_FLAGS) \ + $(DISTCHECK_CONFIGURE_FLAGS) \ + --srcdir=../.. --prefix="$$dc_install_base" \ + && $(MAKE) $(AM_MAKEFLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) dvi \ + && $(MAKE) $(AM_MAKEFLAGS) check \ + && $(MAKE) $(AM_MAKEFLAGS) install \ + && $(MAKE) $(AM_MAKEFLAGS) installcheck \ + && $(MAKE) $(AM_MAKEFLAGS) uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ + distuninstallcheck \ + && chmod -R a-w "$$dc_install_base" \ + && ({ \ + (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ + distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ + } || { rm -rf "$$dc_destdir"; exit 1; }) \ + && rm -rf "$$dc_destdir" \ + && $(MAKE) $(AM_MAKEFLAGS) dist \ + && rm -rf $(DIST_ARCHIVES) \ + && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ + && cd "$$am__cwd" \ + || exit 1 + $(am__post_remove_distdir) + @(echo "$(distdir) archives ready for distribution: "; \ + list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ + sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' +distuninstallcheck: + @test -n '$(distuninstallcheck_dir)' || { \ + echo 'ERROR: trying to run $@ with an empty' \ + '$$(distuninstallcheck_dir)' >&2; \ + exit 1; \ + }; \ + $(am__cd) '$(distuninstallcheck_dir)' || { \ + echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ + exit 1; \ + }; \ + test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left after uninstall:" ; \ + if test -n "$(DESTDIR)"; then \ + echo " (check DESTDIR support)"; \ + fi ; \ + $(distuninstallcheck_listfiles) ; \ + exit 1; } >&2 +distcleancheck: distclean + @if test '$(srcdir)' = . ; then \ + echo "ERROR: distcleancheck can only run from a VPATH build" ; \ + exit 1 ; \ + fi + @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left in build directory after distclean:" ; \ + $(distcleancheck_listfiles) ; \ + exit 1; } >&2 +check-am: all-am +check: check-recursive +all-am: Makefile config.h +installdirs: installdirs-recursive +installdirs-am: +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-recursive + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-hdr \ + distclean-libtool distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf $(top_srcdir)/autom4te.cache + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: + +.MAKE: $(am__recursive_targets) all install-am install-strip + +.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ + am--refresh check check-am clean clean-cscope clean-generic \ + clean-libtool cscope cscopelist-am ctags ctags-am dist \ + dist-all dist-bzip2 dist-gzip dist-lzip dist-shar dist-tarZ \ + dist-xz dist-zip distcheck distclean distclean-generic \ + distclean-hdr distclean-libtool distclean-tags distcleancheck \ + distdir distuninstallcheck dvi dvi-am html html-am info \ + info-am install install-am install-data install-data-am \ + install-dvi install-dvi-am install-exec install-exec-am \ + install-html install-html-am install-info install-info-am \ + install-man install-pdf install-pdf-am install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs installdirs-am maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/lucida/speechrecognition/plugin/Makefile.am b/lucida/speechrecognition/plugin/Makefile.am new file mode 100644 index 000000000..5ff2f5860 --- /dev/null +++ b/lucida/speechrecognition/plugin/Makefile.am @@ -0,0 +1,3 @@ +SUBDIRS = src + +EXTRA_DIST = autogen.sh diff --git a/lucida/speechrecognition/plugin/NEWS b/lucida/speechrecognition/plugin/NEWS new file mode 100644 index 000000000..3474a99e2 --- /dev/null +++ b/lucida/speechrecognition/plugin/NEWS @@ -0,0 +1 @@ +Nothing much yet. diff --git a/lucida/speechrecognition/plugin/README b/lucida/speechrecognition/plugin/README new file mode 100644 index 000000000..190568447 --- /dev/null +++ b/lucida/speechrecognition/plugin/README @@ -0,0 +1,34 @@ +WHAT IT IS +---------- + +gst-plugin is a template for writing your own GStreamer plug-in. + +The code is deliberately kept simple so that you quickly understand the basics +of how to set up autotools and your source tree. + +This template demonstrates : +- what to do in autogen.sh +- how to setup configure.ac (your package name and version, GStreamer flags) +- how to setup your source dir +- what to put in Makefile.am + +More features and templates might get added later on. + +HOW TO USE IT +------------- + +To use it, either make a copy for yourself and rename the parts or use the +make_element script in tools. To create sources for "myfilter" based on the +"gsttransform" template run: + +cd src; +../tools/make_element myfilter gsttransform + +This will create gstmyfilter.c and gstmyfilter.h. Open them in an editor and +start editing. There are several occurances of the string "template", update +those with real values. The plugin will be called 'myfilter' and it will have +one element called 'myfilter' too. Also look for "FIXME:" markers that point you +to places where you need to edit the code. + +You still need to adjust the Makefile.am. + diff --git a/lucida/speechrecognition/plugin/autogen.sh b/lucida/speechrecognition/plugin/autogen.sh new file mode 100755 index 000000000..9df38d3fa --- /dev/null +++ b/lucida/speechrecognition/plugin/autogen.sh @@ -0,0 +1,18 @@ +#!/bin/sh +# you can either set the environment variables AUTOCONF, AUTOHEADER, AUTOMAKE, +# ACLOCAL, AUTOPOINT and/or LIBTOOLIZE to the right versions, or leave them +# unset and get the defaults + +autoreconf --verbose --force --install --make || { + echo 'autogen.sh failed'; + exit 1; +} + +./configure || { + echo 'configure failed'; + exit 1; +} + +echo +echo "Now type 'make' to compile this module." +echo diff --git a/lucida/speechrecognition/plugin/compile b/lucida/speechrecognition/plugin/compile new file mode 100755 index 000000000..a85b723c7 --- /dev/null +++ b/lucida/speechrecognition/plugin/compile @@ -0,0 +1,347 @@ +#! /bin/sh +# Wrapper for compilers which do not understand '-c -o'. + +scriptversion=2012-10-14.11; # UTC + +# Copyright (C) 1999-2014 Free Software Foundation, Inc. +# Written by Tom Tromey . +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# This file is maintained in Automake, please report +# bugs to or send patches to +# . + +nl=' +' + +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent tools from complaining about whitespace usage. +IFS=" "" $nl" + +file_conv= + +# func_file_conv build_file lazy +# Convert a $build file to $host form and store it in $file +# Currently only supports Windows hosts. If the determined conversion +# type is listed in (the comma separated) LAZY, no conversion will +# take place. +func_file_conv () +{ + file=$1 + case $file in + / | /[!/]*) # absolute file, and not a UNC file + if test -z "$file_conv"; then + # lazily determine how to convert abs files + case `uname -s` in + MINGW*) + file_conv=mingw + ;; + CYGWIN*) + file_conv=cygwin + ;; + *) + file_conv=wine + ;; + esac + fi + case $file_conv/,$2, in + *,$file_conv,*) + ;; + mingw/*) + file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` + ;; + cygwin/*) + file=`cygpath -m "$file" || echo "$file"` + ;; + wine/*) + file=`winepath -w "$file" || echo "$file"` + ;; + esac + ;; + esac +} + +# func_cl_dashL linkdir +# Make cl look for libraries in LINKDIR +func_cl_dashL () +{ + func_file_conv "$1" + if test -z "$lib_path"; then + lib_path=$file + else + lib_path="$lib_path;$file" + fi + linker_opts="$linker_opts -LIBPATH:$file" +} + +# func_cl_dashl library +# Do a library search-path lookup for cl +func_cl_dashl () +{ + lib=$1 + found=no + save_IFS=$IFS + IFS=';' + for dir in $lib_path $LIB + do + IFS=$save_IFS + if $shared && test -f "$dir/$lib.dll.lib"; then + found=yes + lib=$dir/$lib.dll.lib + break + fi + if test -f "$dir/$lib.lib"; then + found=yes + lib=$dir/$lib.lib + break + fi + if test -f "$dir/lib$lib.a"; then + found=yes + lib=$dir/lib$lib.a + break + fi + done + IFS=$save_IFS + + if test "$found" != yes; then + lib=$lib.lib + fi +} + +# func_cl_wrapper cl arg... +# Adjust compile command to suit cl +func_cl_wrapper () +{ + # Assume a capable shell + lib_path= + shared=: + linker_opts= + for arg + do + if test -n "$eat"; then + eat= + else + case $1 in + -o) + # configure might choose to run compile as 'compile cc -o foo foo.c'. + eat=1 + case $2 in + *.o | *.[oO][bB][jJ]) + func_file_conv "$2" + set x "$@" -Fo"$file" + shift + ;; + *) + func_file_conv "$2" + set x "$@" -Fe"$file" + shift + ;; + esac + ;; + -I) + eat=1 + func_file_conv "$2" mingw + set x "$@" -I"$file" + shift + ;; + -I*) + func_file_conv "${1#-I}" mingw + set x "$@" -I"$file" + shift + ;; + -l) + eat=1 + func_cl_dashl "$2" + set x "$@" "$lib" + shift + ;; + -l*) + func_cl_dashl "${1#-l}" + set x "$@" "$lib" + shift + ;; + -L) + eat=1 + func_cl_dashL "$2" + ;; + -L*) + func_cl_dashL "${1#-L}" + ;; + -static) + shared=false + ;; + -Wl,*) + arg=${1#-Wl,} + save_ifs="$IFS"; IFS=',' + for flag in $arg; do + IFS="$save_ifs" + linker_opts="$linker_opts $flag" + done + IFS="$save_ifs" + ;; + -Xlinker) + eat=1 + linker_opts="$linker_opts $2" + ;; + -*) + set x "$@" "$1" + shift + ;; + *.cc | *.CC | *.cxx | *.CXX | *.[cC]++) + func_file_conv "$1" + set x "$@" -Tp"$file" + shift + ;; + *.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO]) + func_file_conv "$1" mingw + set x "$@" "$file" + shift + ;; + *) + set x "$@" "$1" + shift + ;; + esac + fi + shift + done + if test -n "$linker_opts"; then + linker_opts="-link$linker_opts" + fi + exec "$@" $linker_opts + exit 1 +} + +eat= + +case $1 in + '') + echo "$0: No command. Try '$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: compile [--help] [--version] PROGRAM [ARGS] + +Wrapper for compilers which do not understand '-c -o'. +Remove '-o dest.o' from ARGS, run PROGRAM with the remaining +arguments, and rename the output as expected. + +If you are trying to build a whole package this is not the +right script to run: please start by reading the file 'INSTALL'. + +Report bugs to . +EOF + exit $? + ;; + -v | --v*) + echo "compile $scriptversion" + exit $? + ;; + cl | *[/\\]cl | cl.exe | *[/\\]cl.exe ) + func_cl_wrapper "$@" # Doesn't return... + ;; +esac + +ofile= +cfile= + +for arg +do + if test -n "$eat"; then + eat= + else + case $1 in + -o) + # configure might choose to run compile as 'compile cc -o foo foo.c'. + # So we strip '-o arg' only if arg is an object. + eat=1 + case $2 in + *.o | *.obj) + ofile=$2 + ;; + *) + set x "$@" -o "$2" + shift + ;; + esac + ;; + *.c) + cfile=$1 + set x "$@" "$1" + shift + ;; + *) + set x "$@" "$1" + shift + ;; + esac + fi + shift +done + +if test -z "$ofile" || test -z "$cfile"; then + # If no '-o' option was seen then we might have been invoked from a + # pattern rule where we don't need one. That is ok -- this is a + # normal compilation that the losing compiler can handle. If no + # '.c' file was seen then we are probably linking. That is also + # ok. + exec "$@" +fi + +# Name of file we expect compiler to create. +cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'` + +# Create the lock directory. +# Note: use '[/\\:.-]' here to ensure that we don't use the same name +# that we are using for the .o file. Also, base the name on the expected +# object file name, since that is what matters with a parallel build. +lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d +while true; do + if mkdir "$lockdir" >/dev/null 2>&1; then + break + fi + sleep 1 +done +# FIXME: race condition here if user kills between mkdir and trap. +trap "rmdir '$lockdir'; exit 1" 1 2 15 + +# Run the compile. +"$@" +ret=$? + +if test -f "$cofile"; then + test "$cofile" = "$ofile" || mv "$cofile" "$ofile" +elif test -f "${cofile}bj"; then + test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile" +fi + +rmdir "$lockdir" +exit $ret + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/lucida/speechrecognition/plugin/configure.ac b/lucida/speechrecognition/plugin/configure.ac new file mode 100644 index 000000000..626376cb8 --- /dev/null +++ b/lucida/speechrecognition/plugin/configure.ac @@ -0,0 +1,90 @@ +dnl required version of autoconf +AC_PREREQ([2.53]) + +dnl fill in your package name and package version here +AC_INIT([asrplugin],[1.0.0],[https://github.com/claritylab/lucida/issues],[asrplugin],[https://github.com/claritylab/lucida/tree/master/lucida/speechrecognition]) +AC_DEFINE([DESCRIPTION],["Generic speech to text converter for Lucida AI"],[Description of package]) + +dnl required versions of gstreamer and plugins-base +GST_REQUIRED=1.0.0 +GSTPB_REQUIRED=1.0.0 + +AC_CONFIG_SRCDIR([src/gstasrplugin.c]) +AC_CONFIG_HEADERS([config.h]) + +dnl required version of automake +AM_INIT_AUTOMAKE([1.10]) + +dnl enable mainainer mode by default +AM_MAINTAINER_MODE([enable]) + +dnl check for tools (compiler etc.) +AC_PROG_CC + +dnl required version of libtool +LT_PREREQ([2.2.6]) +LT_INIT + +dnl give error and exit if we don't have pkgconfig +AC_CHECK_PROG(HAVE_PKGCONFIG, pkg-config, [ ], [ + AC_MSG_ERROR([You need to have pkg-config installed!]) +]) + +dnl Check for the required version of GStreamer core (and gst-plugins-base) +dnl This will export GST_CFLAGS and GST_LIBS variables for use in Makefile.am +dnl +dnl If you need libraries from gst-plugins-base here, also add: +dnl for libgstaudio-1.0: gstreamer-audio-1.0 >= $GST_REQUIRED +dnl for libgstvideo-1.0: gstreamer-video-1.0 >= $GST_REQUIRED +dnl for libgsttag-1.0: gstreamer-tag-1.0 >= $GST_REQUIRED +dnl for libgstpbutils-1.0: gstreamer-pbutils-1.0 >= $GST_REQUIRED +dnl for libgstfft-1.0: gstreamer-fft-1.0 >= $GST_REQUIRED +dnl for libgstinterfaces-1.0: gstreamer-interfaces-1.0 >= $GST_REQUIRED +dnl for libgstrtp-1.0: gstreamer-rtp-1.0 >= $GST_REQUIRED +dnl for libgstrtsp-1.0: gstreamer-rtsp-1.0 >= $GST_REQUIRED +dnl etc. +PKG_CHECK_MODULES(GST, [ + gstreamer-1.0 >= $GST_REQUIRED + gstreamer-base-1.0 >= $GST_REQUIRED + gstreamer-controller-1.0 >= $GST_REQUIRED + gstreamer-audio-1.0 >= $GST_REQUIRED + jansson +], [ + AC_SUBST(GST_CFLAGS) + AC_SUBST(GST_LIBS) +], [ + AC_MSG_ERROR([ + You need to install or upgrade the GStreamer development + packages on your system. On debian-based systems these are + libgstreamer1.0-dev and libgstreamer-plugins-base1.0-dev. + on RPM-based systems gstreamer1.0-devel, libgstreamer1.0-devel + or similar. The minimum version required is $GST_REQUIRED. + ]) +]) + +dnl check if compiler understands -Wall (if yes, add -Wall to GST_CFLAGS) +AC_MSG_CHECKING([to see if compiler understands -Wall]) +save_CFLAGS="$CFLAGS" +CFLAGS="$CFLAGS -Wall" +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([ ], [ ])], [ + GST_CFLAGS="$GST_CFLAGS -Wall" + AC_MSG_RESULT([yes]) +], [ + AC_MSG_RESULT([no]) +]) + +dnl set the plugindir where plugins should be installed (for src/Makefile.am) +if test "x${prefix}" = "x$HOME"; then + plugindir="$HOME/.gstreamer-1.0/plugins" +else + plugindir="\$(libdir)/gstreamer-1.0" +fi +AC_SUBST(plugindir) + +dnl set proper LDFLAGS for plugins +GST_PLUGIN_LDFLAGS='-module -avoid-version -export-symbols-regex [_]*\(gst_\|Gst\|GST_\).*' +AC_SUBST(GST_PLUGIN_LDFLAGS) + +AC_CONFIG_FILES([Makefile src/Makefile]) +AC_OUTPUT + diff --git a/lucida/speechrecognition/plugin/list b/lucida/speechrecognition/plugin/list new file mode 100644 index 000000000..04a48b153 --- /dev/null +++ b/lucida/speechrecognition/plugin/list @@ -0,0 +1,5 @@ +. +AUTHORS autogen.sh ChangeLog configure.ac COPYING ltmain.sh Makefile.am NEWS README src + +src +gstasrplugin.c gstasrplugin.h Makefile.am diff --git a/lucida/speechrecognition/plugin/src/.deps/libgstasrplugin_la-gstasrplugin.Plo b/lucida/speechrecognition/plugin/src/.deps/libgstasrplugin_la-gstasrplugin.Plo new file mode 100644 index 000000000..42445fc9b --- /dev/null +++ b/lucida/speechrecognition/plugin/src/.deps/libgstasrplugin_la-gstasrplugin.Plo @@ -0,0 +1,732 @@ +libgstasrplugin_la-gstasrplugin.lo: gstasrplugin.c \ + /usr/include/stdc-predef.h ../config.h \ + /usr/include/gstreamer-1.0/gst/gst.h /usr/include/glib-2.0/glib.h \ + /usr/include/glib-2.0/glib/galloca.h /usr/include/glib-2.0/glib/gtypes.h \ + /usr/lib/x86_64-linux-gnu/glib-2.0/include/glibconfig.h \ + /usr/include/glib-2.0/glib/gmacros.h \ + /usr/lib/gcc/x86_64-linux-gnu/5/include/stddef.h \ + /usr/lib/gcc/x86_64-linux-gnu/5/include-fixed/limits.h \ + /usr/lib/gcc/x86_64-linux-gnu/5/include-fixed/syslimits.h \ + /usr/include/limits.h /usr/include/features.h \ + /usr/include/x86_64-linux-gnu/sys/cdefs.h \ + /usr/include/x86_64-linux-gnu/bits/wordsize.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ + /usr/include/x86_64-linux-gnu/bits/posix1_lim.h \ + /usr/include/x86_64-linux-gnu/bits/local_lim.h \ + /usr/include/linux/limits.h \ + /usr/include/x86_64-linux-gnu/bits/posix2_lim.h \ + /usr/lib/gcc/x86_64-linux-gnu/5/include/float.h \ + /usr/include/glib-2.0/glib/gversionmacros.h /usr/include/time.h \ + /usr/include/x86_64-linux-gnu/bits/time.h \ + /usr/include/x86_64-linux-gnu/bits/types.h \ + /usr/include/x86_64-linux-gnu/bits/typesizes.h /usr/include/xlocale.h \ + /usr/include/glib-2.0/glib/garray.h \ + /usr/include/glib-2.0/glib/gasyncqueue.h \ + /usr/include/glib-2.0/glib/gthread.h \ + /usr/include/glib-2.0/glib/gatomic.h /usr/include/glib-2.0/glib/gerror.h \ + /usr/lib/gcc/x86_64-linux-gnu/5/include/stdarg.h \ + /usr/include/glib-2.0/glib/gquark.h /usr/include/glib-2.0/glib/gutils.h \ + /usr/include/glib-2.0/glib/gbacktrace.h /usr/include/signal.h \ + /usr/include/x86_64-linux-gnu/bits/sigset.h \ + /usr/include/x86_64-linux-gnu/bits/signum.h \ + /usr/include/x86_64-linux-gnu/bits/siginfo.h \ + /usr/include/x86_64-linux-gnu/bits/sigaction.h \ + /usr/include/x86_64-linux-gnu/bits/sigcontext.h \ + /usr/include/x86_64-linux-gnu/bits/sigstack.h \ + /usr/include/x86_64-linux-gnu/sys/ucontext.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h \ + /usr/include/x86_64-linux-gnu/bits/sigthread.h \ + /usr/include/glib-2.0/glib/gbase64.h \ + /usr/include/glib-2.0/glib/gbitlock.h \ + /usr/include/glib-2.0/glib/gbookmarkfile.h \ + /usr/include/glib-2.0/glib/gbytes.h \ + /usr/include/glib-2.0/glib/gcharset.h \ + /usr/include/glib-2.0/glib/gchecksum.h \ + /usr/include/glib-2.0/glib/gconvert.h \ + /usr/include/glib-2.0/glib/gdataset.h /usr/include/glib-2.0/glib/gdate.h \ + /usr/include/glib-2.0/glib/gdatetime.h \ + /usr/include/glib-2.0/glib/gtimezone.h /usr/include/glib-2.0/glib/gdir.h \ + /usr/include/dirent.h /usr/include/x86_64-linux-gnu/bits/dirent.h \ + /usr/include/glib-2.0/glib/genviron.h \ + /usr/include/glib-2.0/glib/gfileutils.h \ + /usr/include/glib-2.0/glib/ggettext.h /usr/include/glib-2.0/glib/ghash.h \ + /usr/include/glib-2.0/glib/glist.h /usr/include/glib-2.0/glib/gmem.h \ + /usr/include/glib-2.0/glib/gnode.h /usr/include/glib-2.0/glib/ghmac.h \ + /usr/include/glib-2.0/glib/gchecksum.h \ + /usr/include/glib-2.0/glib/ghook.h \ + /usr/include/glib-2.0/glib/ghostutils.h \ + /usr/include/glib-2.0/glib/giochannel.h \ + /usr/include/glib-2.0/glib/gmain.h /usr/include/glib-2.0/glib/gpoll.h \ + /usr/include/glib-2.0/glib/gslist.h /usr/include/glib-2.0/glib/gstring.h \ + /usr/include/glib-2.0/glib/gunicode.h \ + /usr/include/glib-2.0/glib/gkeyfile.h \ + /usr/include/glib-2.0/glib/gmappedfile.h \ + /usr/include/glib-2.0/glib/gmarkup.h \ + /usr/include/glib-2.0/glib/gmessages.h \ + /usr/include/glib-2.0/glib/goption.h \ + /usr/include/glib-2.0/glib/gpattern.h \ + /usr/include/glib-2.0/glib/gprimes.h /usr/include/glib-2.0/glib/gqsort.h \ + /usr/include/glib-2.0/glib/gqueue.h /usr/include/glib-2.0/glib/grand.h \ + /usr/include/glib-2.0/glib/gregex.h \ + /usr/include/glib-2.0/glib/gscanner.h \ + /usr/include/glib-2.0/glib/gsequence.h \ + /usr/include/glib-2.0/glib/gshell.h /usr/include/glib-2.0/glib/gslice.h \ + /usr/include/glib-2.0/glib/gspawn.h \ + /usr/include/glib-2.0/glib/gstrfuncs.h \ + /usr/include/glib-2.0/glib/gstringchunk.h \ + /usr/include/glib-2.0/glib/gtestutils.h \ + /usr/include/glib-2.0/glib/gthreadpool.h \ + /usr/include/glib-2.0/glib/gtimer.h \ + /usr/include/glib-2.0/glib/gtrashstack.h \ + /usr/include/glib-2.0/glib/gtree.h \ + /usr/include/glib-2.0/glib/gurifuncs.h \ + /usr/include/glib-2.0/glib/gvarianttype.h \ + /usr/include/glib-2.0/glib/gvariant.h \ + /usr/include/glib-2.0/glib/gversion.h \ + /usr/include/glib-2.0/glib/deprecated/gallocator.h \ + /usr/include/glib-2.0/glib/deprecated/gcache.h \ + /usr/include/glib-2.0/glib/deprecated/gcompletion.h \ + /usr/include/glib-2.0/glib/deprecated/gmain.h \ + /usr/include/glib-2.0/glib/deprecated/grel.h \ + /usr/include/glib-2.0/glib/deprecated/gthread.h \ + /usr/include/x86_64-linux-gnu/sys/types.h /usr/include/endian.h \ + /usr/include/x86_64-linux-gnu/bits/endian.h \ + /usr/include/x86_64-linux-gnu/bits/byteswap.h \ + /usr/include/x86_64-linux-gnu/bits/byteswap-16.h \ + /usr/include/x86_64-linux-gnu/sys/select.h \ + /usr/include/x86_64-linux-gnu/bits/select.h \ + /usr/include/x86_64-linux-gnu/bits/select2.h \ + /usr/include/x86_64-linux-gnu/sys/sysmacros.h /usr/include/pthread.h \ + /usr/include/sched.h /usr/include/x86_64-linux-gnu/bits/sched.h \ + /usr/include/x86_64-linux-gnu/bits/setjmp.h \ + /usr/include/glib-2.0/glib/glib-autocleanups.h \ + /usr/include/gstreamer-1.0/gst/glib-compat.h \ + /usr/include/gstreamer-1.0/gst/gstenumtypes.h \ + /usr/include/glib-2.0/glib-object.h \ + /usr/include/glib-2.0/gobject/gbinding.h \ + /usr/include/glib-2.0/gobject/gobject.h \ + /usr/include/glib-2.0/gobject/gtype.h \ + /usr/include/glib-2.0/gobject/gvalue.h \ + /usr/include/glib-2.0/gobject/gparam.h \ + /usr/include/glib-2.0/gobject/gclosure.h \ + /usr/include/glib-2.0/gobject/gsignal.h \ + /usr/include/glib-2.0/gobject/gmarshal.h \ + /usr/include/glib-2.0/gobject/gboxed.h \ + /usr/include/glib-2.0/gobject/glib-types.h \ + /usr/include/glib-2.0/gobject/genums.h \ + /usr/include/glib-2.0/gobject/gparamspecs.h \ + /usr/include/glib-2.0/gobject/gsourceclosure.h \ + /usr/include/glib-2.0/gobject/gtypemodule.h \ + /usr/include/glib-2.0/gobject/gtypeplugin.h \ + /usr/include/glib-2.0/gobject/gvaluearray.h \ + /usr/include/glib-2.0/gobject/gvaluetypes.h \ + /usr/include/glib-2.0/gobject/gobject-autocleanups.h \ + /usr/include/gstreamer-1.0/gst/gstversion.h \ + /usr/include/gstreamer-1.0/gst/gstatomicqueue.h \ + /usr/include/gstreamer-1.0/gst/gstbin.h \ + /usr/include/gstreamer-1.0/gst/gstelement.h \ + /usr/lib/x86_64-linux-gnu/gstreamer-1.0/include/gst/gstconfig.h \ + /usr/include/gstreamer-1.0/gst/gstobject.h \ + /usr/include/gstreamer-1.0/gst/gstcontrolbinding.h \ + /usr/include/gstreamer-1.0/gst/gstcontrolsource.h \ + /usr/include/gstreamer-1.0/gst/gstclock.h \ + /usr/include/gstreamer-1.0/gst/gstpad.h \ + /usr/include/gstreamer-1.0/gst/gstbuffer.h \ + /usr/include/gstreamer-1.0/gst/gstminiobject.h \ + /usr/include/gstreamer-1.0/gst/gstallocator.h \ + /usr/include/gstreamer-1.0/gst/gstmemory.h \ + /usr/include/gstreamer-1.0/gst/gstmeta.h \ + /usr/include/gstreamer-1.0/gst/gstbufferlist.h \ + /usr/include/gstreamer-1.0/gst/gstcaps.h \ + /usr/include/gstreamer-1.0/gst/gststructure.h \ + /usr/include/gstreamer-1.0/gst/gstdatetime.h \ + /usr/include/gstreamer-1.0/gst/gstcapsfeatures.h \ + /usr/include/gstreamer-1.0/gst/gstpadtemplate.h \ + /usr/include/gstreamer-1.0/gst/gstevent.h \ + /usr/include/gstreamer-1.0/gst/gstformat.h \ + /usr/include/gstreamer-1.0/gst/gstiterator.h \ + /usr/include/gstreamer-1.0/gst/gsttaglist.h \ + /usr/include/gstreamer-1.0/gst/gstsample.h \ + /usr/include/gstreamer-1.0/gst/gstsegment.h \ + /usr/include/gstreamer-1.0/gst/gstmessage.h \ + /usr/include/gstreamer-1.0/gst/gstquery.h \ + /usr/include/gstreamer-1.0/gst/gsttoc.h \ + /usr/include/gstreamer-1.0/gst/gstcontext.h \ + /usr/include/gstreamer-1.0/gst/gstdevice.h \ + /usr/include/gstreamer-1.0/gst/gsttask.h \ + /usr/include/gstreamer-1.0/gst/gsttaskpool.h \ + /usr/include/gstreamer-1.0/gst/gstbus.h \ + /usr/include/gstreamer-1.0/gst/gstelementfactory.h \ + /usr/include/gstreamer-1.0/gst/gstplugin.h \ + /usr/include/gstreamer-1.0/gst/gstmacros.h \ + /usr/include/gstreamer-1.0/gst/gstpluginfeature.h \ + /usr/include/gstreamer-1.0/gst/gsturi.h \ + /usr/include/gstreamer-1.0/gst/gstminiobject.h \ + /usr/include/gstreamer-1.0/gst/gstbufferpool.h \ + /usr/include/gstreamer-1.0/gst/gstchildproxy.h \ + /usr/include/gstreamer-1.0/gst/gstdebugutils.h \ + /usr/include/gstreamer-1.0/gst/gstdevicemonitor.h \ + /usr/include/gstreamer-1.0/gst/gstdeviceprovider.h \ + /usr/include/gstreamer-1.0/gst/gstdeviceproviderfactory.h \ + /usr/include/gstreamer-1.0/gst/gstelementmetadata.h \ + /usr/include/gstreamer-1.0/gst/gsterror.h /usr/include/errno.h \ + /usr/include/x86_64-linux-gnu/bits/errno.h /usr/include/linux/errno.h \ + /usr/include/x86_64-linux-gnu/asm/errno.h \ + /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h \ + /usr/include/gstreamer-1.0/gst/gstghostpad.h \ + /usr/include/gstreamer-1.0/gst/gstinfo.h \ + /usr/include/gstreamer-1.0/gst/gstparamspecs.h \ + /usr/include/gstreamer-1.0/gst/gstvalue.h \ + /usr/include/gstreamer-1.0/gst/gstpipeline.h \ + /usr/include/gstreamer-1.0/gst/gstpoll.h \ + /usr/include/gstreamer-1.0/gst/gstpreset.h \ + /usr/include/gstreamer-1.0/gst/gstprotection.h \ + /usr/include/gstreamer-1.0/gst/gstregistry.h \ + /usr/include/gstreamer-1.0/gst/gstsystemclock.h \ + /usr/include/gstreamer-1.0/gst/gsttagsetter.h \ + /usr/include/gstreamer-1.0/gst/gsttocsetter.h \ + /usr/include/gstreamer-1.0/gst/gsttracer.h \ + /usr/include/gstreamer-1.0/gst/gsttracerfactory.h \ + /usr/include/gstreamer-1.0/gst/gsttracerrecord.h \ + /usr/include/gstreamer-1.0/gst/gsttypefind.h \ + /usr/include/gstreamer-1.0/gst/gsttypefindfactory.h \ + /usr/include/gstreamer-1.0/gst/gstutils.h \ + /usr/include/gstreamer-1.0/gst/gstparse.h \ + /usr/include/gstreamer-1.0/gst/gstcompat.h gstasrplugin.h \ + /usr/include/stdio.h /usr/include/libio.h /usr/include/_G_config.h \ + /usr/include/wchar.h /usr/include/x86_64-linux-gnu/bits/stdio_lim.h \ + /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ + /usr/include/x86_64-linux-gnu/bits/stdio.h \ + /usr/include/x86_64-linux-gnu/bits/stdio2.h /usr/include/jansson.h \ + /usr/include/stdlib.h /usr/include/x86_64-linux-gnu/bits/waitflags.h \ + /usr/include/x86_64-linux-gnu/bits/waitstatus.h /usr/include/alloca.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib-bsearch.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib-float.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib.h \ + /usr/include/jansson_config.h \ + /usr/lib/gcc/x86_64-linux-gnu/5/include/stdbool.h /usr/include/fcntl.h \ + /usr/include/x86_64-linux-gnu/bits/fcntl.h \ + /usr/include/x86_64-linux-gnu/bits/fcntl-linux.h \ + /usr/include/x86_64-linux-gnu/bits/stat.h \ + /usr/include/x86_64-linux-gnu/bits/fcntl2.h \ + /usr/include/x86_64-linux-gnu/sys/stat.h /usr/include/unistd.h \ + /usr/include/x86_64-linux-gnu/bits/posix_opt.h \ + /usr/include/x86_64-linux-gnu/bits/environments.h \ + /usr/include/x86_64-linux-gnu/bits/confname.h /usr/include/getopt.h \ + /usr/include/x86_64-linux-gnu/bits/unistd.h /usr/include/string.h \ + /usr/include/x86_64-linux-gnu/bits/string.h \ + /usr/include/x86_64-linux-gnu/bits/string2.h \ + /usr/include/x86_64-linux-gnu/bits/string3.h + +/usr/include/stdc-predef.h: + +../config.h: + +/usr/include/gstreamer-1.0/gst/gst.h: + +/usr/include/glib-2.0/glib.h: + +/usr/include/glib-2.0/glib/galloca.h: + +/usr/include/glib-2.0/glib/gtypes.h: + +/usr/lib/x86_64-linux-gnu/glib-2.0/include/glibconfig.h: + +/usr/include/glib-2.0/glib/gmacros.h: + +/usr/lib/gcc/x86_64-linux-gnu/5/include/stddef.h: + +/usr/lib/gcc/x86_64-linux-gnu/5/include-fixed/limits.h: + +/usr/lib/gcc/x86_64-linux-gnu/5/include-fixed/syslimits.h: + +/usr/include/limits.h: + +/usr/include/features.h: + +/usr/include/x86_64-linux-gnu/sys/cdefs.h: + +/usr/include/x86_64-linux-gnu/bits/wordsize.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs-64.h: + +/usr/include/x86_64-linux-gnu/bits/posix1_lim.h: + +/usr/include/x86_64-linux-gnu/bits/local_lim.h: + +/usr/include/linux/limits.h: + +/usr/include/x86_64-linux-gnu/bits/posix2_lim.h: + +/usr/lib/gcc/x86_64-linux-gnu/5/include/float.h: + +/usr/include/glib-2.0/glib/gversionmacros.h: + +/usr/include/time.h: + +/usr/include/x86_64-linux-gnu/bits/time.h: + +/usr/include/x86_64-linux-gnu/bits/types.h: + +/usr/include/x86_64-linux-gnu/bits/typesizes.h: + +/usr/include/xlocale.h: + +/usr/include/glib-2.0/glib/garray.h: + +/usr/include/glib-2.0/glib/gasyncqueue.h: + +/usr/include/glib-2.0/glib/gthread.h: + +/usr/include/glib-2.0/glib/gatomic.h: + +/usr/include/glib-2.0/glib/gerror.h: + +/usr/lib/gcc/x86_64-linux-gnu/5/include/stdarg.h: + +/usr/include/glib-2.0/glib/gquark.h: + +/usr/include/glib-2.0/glib/gutils.h: + +/usr/include/glib-2.0/glib/gbacktrace.h: + +/usr/include/signal.h: + +/usr/include/x86_64-linux-gnu/bits/sigset.h: + +/usr/include/x86_64-linux-gnu/bits/signum.h: + +/usr/include/x86_64-linux-gnu/bits/siginfo.h: + +/usr/include/x86_64-linux-gnu/bits/sigaction.h: + +/usr/include/x86_64-linux-gnu/bits/sigcontext.h: + +/usr/include/x86_64-linux-gnu/bits/sigstack.h: + +/usr/include/x86_64-linux-gnu/sys/ucontext.h: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h: + +/usr/include/x86_64-linux-gnu/bits/sigthread.h: + +/usr/include/glib-2.0/glib/gbase64.h: + +/usr/include/glib-2.0/glib/gbitlock.h: + +/usr/include/glib-2.0/glib/gbookmarkfile.h: + +/usr/include/glib-2.0/glib/gbytes.h: + +/usr/include/glib-2.0/glib/gcharset.h: + +/usr/include/glib-2.0/glib/gchecksum.h: + +/usr/include/glib-2.0/glib/gconvert.h: + +/usr/include/glib-2.0/glib/gdataset.h: + +/usr/include/glib-2.0/glib/gdate.h: + +/usr/include/glib-2.0/glib/gdatetime.h: + +/usr/include/glib-2.0/glib/gtimezone.h: + +/usr/include/glib-2.0/glib/gdir.h: + +/usr/include/dirent.h: + +/usr/include/x86_64-linux-gnu/bits/dirent.h: + +/usr/include/glib-2.0/glib/genviron.h: + +/usr/include/glib-2.0/glib/gfileutils.h: + +/usr/include/glib-2.0/glib/ggettext.h: + +/usr/include/glib-2.0/glib/ghash.h: + +/usr/include/glib-2.0/glib/glist.h: + +/usr/include/glib-2.0/glib/gmem.h: + +/usr/include/glib-2.0/glib/gnode.h: + +/usr/include/glib-2.0/glib/ghmac.h: + +/usr/include/glib-2.0/glib/gchecksum.h: + +/usr/include/glib-2.0/glib/ghook.h: + +/usr/include/glib-2.0/glib/ghostutils.h: + +/usr/include/glib-2.0/glib/giochannel.h: + +/usr/include/glib-2.0/glib/gmain.h: + +/usr/include/glib-2.0/glib/gpoll.h: + +/usr/include/glib-2.0/glib/gslist.h: + +/usr/include/glib-2.0/glib/gstring.h: + +/usr/include/glib-2.0/glib/gunicode.h: + +/usr/include/glib-2.0/glib/gkeyfile.h: + +/usr/include/glib-2.0/glib/gmappedfile.h: + +/usr/include/glib-2.0/glib/gmarkup.h: + +/usr/include/glib-2.0/glib/gmessages.h: + +/usr/include/glib-2.0/glib/goption.h: + +/usr/include/glib-2.0/glib/gpattern.h: + +/usr/include/glib-2.0/glib/gprimes.h: + +/usr/include/glib-2.0/glib/gqsort.h: + +/usr/include/glib-2.0/glib/gqueue.h: + +/usr/include/glib-2.0/glib/grand.h: + +/usr/include/glib-2.0/glib/gregex.h: + +/usr/include/glib-2.0/glib/gscanner.h: + +/usr/include/glib-2.0/glib/gsequence.h: + +/usr/include/glib-2.0/glib/gshell.h: + +/usr/include/glib-2.0/glib/gslice.h: + +/usr/include/glib-2.0/glib/gspawn.h: + +/usr/include/glib-2.0/glib/gstrfuncs.h: + +/usr/include/glib-2.0/glib/gstringchunk.h: + +/usr/include/glib-2.0/glib/gtestutils.h: + +/usr/include/glib-2.0/glib/gthreadpool.h: + +/usr/include/glib-2.0/glib/gtimer.h: + +/usr/include/glib-2.0/glib/gtrashstack.h: + +/usr/include/glib-2.0/glib/gtree.h: + +/usr/include/glib-2.0/glib/gurifuncs.h: + +/usr/include/glib-2.0/glib/gvarianttype.h: + +/usr/include/glib-2.0/glib/gvariant.h: + +/usr/include/glib-2.0/glib/gversion.h: + +/usr/include/glib-2.0/glib/deprecated/gallocator.h: + +/usr/include/glib-2.0/glib/deprecated/gcache.h: + +/usr/include/glib-2.0/glib/deprecated/gcompletion.h: + +/usr/include/glib-2.0/glib/deprecated/gmain.h: + +/usr/include/glib-2.0/glib/deprecated/grel.h: + +/usr/include/glib-2.0/glib/deprecated/gthread.h: + +/usr/include/x86_64-linux-gnu/sys/types.h: + +/usr/include/endian.h: + +/usr/include/x86_64-linux-gnu/bits/endian.h: + +/usr/include/x86_64-linux-gnu/bits/byteswap.h: + +/usr/include/x86_64-linux-gnu/bits/byteswap-16.h: + +/usr/include/x86_64-linux-gnu/sys/select.h: + +/usr/include/x86_64-linux-gnu/bits/select.h: + +/usr/include/x86_64-linux-gnu/bits/select2.h: + +/usr/include/x86_64-linux-gnu/sys/sysmacros.h: + +/usr/include/pthread.h: + +/usr/include/sched.h: + +/usr/include/x86_64-linux-gnu/bits/sched.h: + +/usr/include/x86_64-linux-gnu/bits/setjmp.h: + +/usr/include/glib-2.0/glib/glib-autocleanups.h: + +/usr/include/gstreamer-1.0/gst/glib-compat.h: + +/usr/include/gstreamer-1.0/gst/gstenumtypes.h: + +/usr/include/glib-2.0/glib-object.h: + +/usr/include/glib-2.0/gobject/gbinding.h: + +/usr/include/glib-2.0/gobject/gobject.h: + +/usr/include/glib-2.0/gobject/gtype.h: + +/usr/include/glib-2.0/gobject/gvalue.h: + +/usr/include/glib-2.0/gobject/gparam.h: + +/usr/include/glib-2.0/gobject/gclosure.h: + +/usr/include/glib-2.0/gobject/gsignal.h: + +/usr/include/glib-2.0/gobject/gmarshal.h: + +/usr/include/glib-2.0/gobject/gboxed.h: + +/usr/include/glib-2.0/gobject/glib-types.h: + +/usr/include/glib-2.0/gobject/genums.h: + +/usr/include/glib-2.0/gobject/gparamspecs.h: + +/usr/include/glib-2.0/gobject/gsourceclosure.h: + +/usr/include/glib-2.0/gobject/gtypemodule.h: + +/usr/include/glib-2.0/gobject/gtypeplugin.h: + +/usr/include/glib-2.0/gobject/gvaluearray.h: + +/usr/include/glib-2.0/gobject/gvaluetypes.h: + +/usr/include/glib-2.0/gobject/gobject-autocleanups.h: + +/usr/include/gstreamer-1.0/gst/gstversion.h: + +/usr/include/gstreamer-1.0/gst/gstatomicqueue.h: + +/usr/include/gstreamer-1.0/gst/gstbin.h: + +/usr/include/gstreamer-1.0/gst/gstelement.h: + +/usr/lib/x86_64-linux-gnu/gstreamer-1.0/include/gst/gstconfig.h: + +/usr/include/gstreamer-1.0/gst/gstobject.h: + +/usr/include/gstreamer-1.0/gst/gstcontrolbinding.h: + +/usr/include/gstreamer-1.0/gst/gstcontrolsource.h: + +/usr/include/gstreamer-1.0/gst/gstclock.h: + +/usr/include/gstreamer-1.0/gst/gstpad.h: + +/usr/include/gstreamer-1.0/gst/gstbuffer.h: + +/usr/include/gstreamer-1.0/gst/gstminiobject.h: + +/usr/include/gstreamer-1.0/gst/gstallocator.h: + +/usr/include/gstreamer-1.0/gst/gstmemory.h: + +/usr/include/gstreamer-1.0/gst/gstmeta.h: + +/usr/include/gstreamer-1.0/gst/gstbufferlist.h: + +/usr/include/gstreamer-1.0/gst/gstcaps.h: + +/usr/include/gstreamer-1.0/gst/gststructure.h: + +/usr/include/gstreamer-1.0/gst/gstdatetime.h: + +/usr/include/gstreamer-1.0/gst/gstcapsfeatures.h: + +/usr/include/gstreamer-1.0/gst/gstpadtemplate.h: + +/usr/include/gstreamer-1.0/gst/gstevent.h: + +/usr/include/gstreamer-1.0/gst/gstformat.h: + +/usr/include/gstreamer-1.0/gst/gstiterator.h: + +/usr/include/gstreamer-1.0/gst/gsttaglist.h: + +/usr/include/gstreamer-1.0/gst/gstsample.h: + +/usr/include/gstreamer-1.0/gst/gstsegment.h: + +/usr/include/gstreamer-1.0/gst/gstmessage.h: + +/usr/include/gstreamer-1.0/gst/gstquery.h: + +/usr/include/gstreamer-1.0/gst/gsttoc.h: + +/usr/include/gstreamer-1.0/gst/gstcontext.h: + +/usr/include/gstreamer-1.0/gst/gstdevice.h: + +/usr/include/gstreamer-1.0/gst/gsttask.h: + +/usr/include/gstreamer-1.0/gst/gsttaskpool.h: + +/usr/include/gstreamer-1.0/gst/gstbus.h: + +/usr/include/gstreamer-1.0/gst/gstelementfactory.h: + +/usr/include/gstreamer-1.0/gst/gstplugin.h: + +/usr/include/gstreamer-1.0/gst/gstmacros.h: + +/usr/include/gstreamer-1.0/gst/gstpluginfeature.h: + +/usr/include/gstreamer-1.0/gst/gsturi.h: + +/usr/include/gstreamer-1.0/gst/gstminiobject.h: + +/usr/include/gstreamer-1.0/gst/gstbufferpool.h: + +/usr/include/gstreamer-1.0/gst/gstchildproxy.h: + +/usr/include/gstreamer-1.0/gst/gstdebugutils.h: + +/usr/include/gstreamer-1.0/gst/gstdevicemonitor.h: + +/usr/include/gstreamer-1.0/gst/gstdeviceprovider.h: + +/usr/include/gstreamer-1.0/gst/gstdeviceproviderfactory.h: + +/usr/include/gstreamer-1.0/gst/gstelementmetadata.h: + +/usr/include/gstreamer-1.0/gst/gsterror.h: + +/usr/include/errno.h: + +/usr/include/x86_64-linux-gnu/bits/errno.h: + +/usr/include/linux/errno.h: + +/usr/include/x86_64-linux-gnu/asm/errno.h: + +/usr/include/asm-generic/errno.h: + +/usr/include/asm-generic/errno-base.h: + +/usr/include/gstreamer-1.0/gst/gstghostpad.h: + +/usr/include/gstreamer-1.0/gst/gstinfo.h: + +/usr/include/gstreamer-1.0/gst/gstparamspecs.h: + +/usr/include/gstreamer-1.0/gst/gstvalue.h: + +/usr/include/gstreamer-1.0/gst/gstpipeline.h: + +/usr/include/gstreamer-1.0/gst/gstpoll.h: + +/usr/include/gstreamer-1.0/gst/gstpreset.h: + +/usr/include/gstreamer-1.0/gst/gstprotection.h: + +/usr/include/gstreamer-1.0/gst/gstregistry.h: + +/usr/include/gstreamer-1.0/gst/gstsystemclock.h: + +/usr/include/gstreamer-1.0/gst/gsttagsetter.h: + +/usr/include/gstreamer-1.0/gst/gsttocsetter.h: + +/usr/include/gstreamer-1.0/gst/gsttracer.h: + +/usr/include/gstreamer-1.0/gst/gsttracerfactory.h: + +/usr/include/gstreamer-1.0/gst/gsttracerrecord.h: + +/usr/include/gstreamer-1.0/gst/gsttypefind.h: + +/usr/include/gstreamer-1.0/gst/gsttypefindfactory.h: + +/usr/include/gstreamer-1.0/gst/gstutils.h: + +/usr/include/gstreamer-1.0/gst/gstparse.h: + +/usr/include/gstreamer-1.0/gst/gstcompat.h: + +gstasrplugin.h: + +/usr/include/stdio.h: + +/usr/include/libio.h: + +/usr/include/_G_config.h: + +/usr/include/wchar.h: + +/usr/include/x86_64-linux-gnu/bits/stdio_lim.h: + +/usr/include/x86_64-linux-gnu/bits/sys_errlist.h: + +/usr/include/x86_64-linux-gnu/bits/stdio.h: + +/usr/include/x86_64-linux-gnu/bits/stdio2.h: + +/usr/include/jansson.h: + +/usr/include/stdlib.h: + +/usr/include/x86_64-linux-gnu/bits/waitflags.h: + +/usr/include/x86_64-linux-gnu/bits/waitstatus.h: + +/usr/include/alloca.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib-bsearch.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib-float.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib.h: + +/usr/include/jansson_config.h: + +/usr/lib/gcc/x86_64-linux-gnu/5/include/stdbool.h: + +/usr/include/fcntl.h: + +/usr/include/x86_64-linux-gnu/bits/fcntl.h: + +/usr/include/x86_64-linux-gnu/bits/fcntl-linux.h: + +/usr/include/x86_64-linux-gnu/bits/stat.h: + +/usr/include/x86_64-linux-gnu/bits/fcntl2.h: + +/usr/include/x86_64-linux-gnu/sys/stat.h: + +/usr/include/unistd.h: + +/usr/include/x86_64-linux-gnu/bits/posix_opt.h: + +/usr/include/x86_64-linux-gnu/bits/environments.h: + +/usr/include/x86_64-linux-gnu/bits/confname.h: + +/usr/include/getopt.h: + +/usr/include/x86_64-linux-gnu/bits/unistd.h: + +/usr/include/string.h: + +/usr/include/x86_64-linux-gnu/bits/string.h: + +/usr/include/x86_64-linux-gnu/bits/string2.h: + +/usr/include/x86_64-linux-gnu/bits/string3.h: diff --git a/lucida/speechrecognition/plugin/src/.libs/libgstasrplugin.exp b/lucida/speechrecognition/plugin/src/.libs/libgstasrplugin.exp new file mode 100644 index 000000000..30a8a3f0e --- /dev/null +++ b/lucida/speechrecognition/plugin/src/.libs/libgstasrplugin.exp @@ -0,0 +1,2 @@ +gst_asrplugin_get_type +gst_plugin_desc diff --git a/lucida/speechrecognition/plugin/src/.libs/libgstasrplugin.ver b/lucida/speechrecognition/plugin/src/.libs/libgstasrplugin.ver new file mode 100644 index 000000000..f0f474b69 --- /dev/null +++ b/lucida/speechrecognition/plugin/src/.libs/libgstasrplugin.ver @@ -0,0 +1,4 @@ +{ global: +gst_asrplugin_get_type; +gst_plugin_desc; +local: *; }; diff --git a/lucida/speechrecognition/plugin/src/Makefile b/lucida/speechrecognition/plugin/src/Makefile new file mode 100644 index 000000000..fdd4c1d12 --- /dev/null +++ b/lucida/speechrecognition/plugin/src/Makefile @@ -0,0 +1,673 @@ +# Makefile.in generated by automake 1.15 from Makefile.am. +# src/Makefile. Generated from Makefile.in by configure. + +# Copyright (C) 1994-2014 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + + + + + +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/asrplugin +pkgincludedir = $(includedir)/asrplugin +pkglibdir = $(libdir)/asrplugin +pkglibexecdir = $(libexecdir)/asrplugin +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = x86_64-pc-linux-gnu +host_triplet = x86_64-pc-linux-gnu +subdir = src +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(noinst_HEADERS) \ + $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(plugindir)" +LTLIBRARIES = $(plugin_LTLIBRARIES) +am__DEPENDENCIES_1 = +libgstasrplugin_la_DEPENDENCIES = $(am__DEPENDENCIES_1) +am_libgstasrplugin_la_OBJECTS = libgstasrplugin_la-gstasrplugin.lo +libgstasrplugin_la_OBJECTS = $(am_libgstasrplugin_la_OBJECTS) +AM_V_lt = $(am__v_lt_$(V)) +am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY)) +am__v_lt_0 = --silent +am__v_lt_1 = +libgstasrplugin_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(libgstasrplugin_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link \ + $(CCLD) $(libgstasrplugin_la_CFLAGS) $(CFLAGS) \ + $(libgstasrplugin_la_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_P = $(am__v_P_$(V)) +am__v_P_ = $(am__v_P_$(AM_DEFAULT_VERBOSITY)) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_$(V)) +am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_$(V)) +am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY)) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I. -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_$(V)) +am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY)) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_$(V)) +am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY)) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(libgstasrplugin_la_SOURCES) +DIST_SOURCES = $(libgstasrplugin_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +HEADERS = $(noinst_HEADERS) +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = ${SHELL} /usr/local/src/lucida/lucida/speechrecognition/plugin/missing aclocal-1.15 +AMTAR = $${TAR-tar} +AM_DEFAULT_VERBOSITY = 1 +AR = ar +AUTOCONF = ${SHELL} /usr/local/src/lucida/lucida/speechrecognition/plugin/missing autoconf +AUTOHEADER = ${SHELL} /usr/local/src/lucida/lucida/speechrecognition/plugin/missing autoheader +AUTOMAKE = ${SHELL} /usr/local/src/lucida/lucida/speechrecognition/plugin/missing automake-1.15 +AWK = gawk +CC = gcc +CCDEPMODE = depmode=gcc3 +CFLAGS = -g -O2 -Wall +CPP = gcc -E +CPPFLAGS = +CYGPATH_W = echo +DEFS = -DHAVE_CONFIG_H +DEPDIR = .deps +DLLTOOL = false +DSYMUTIL = +DUMPBIN = +ECHO_C = +ECHO_N = -n +ECHO_T = +EGREP = /bin/grep -E +EXEEXT = +FGREP = /bin/grep -F +GREP = /bin/grep +GST_CFLAGS = -pthread -I/usr/include/gstreamer-1.0 -I/usr/lib/x86_64-linux-gnu/gstreamer-1.0/include -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -Wall +GST_LIBS = -lgstcontroller-1.0 -lgstaudio-1.0 -lgstbase-1.0 -lgstreamer-1.0 -lgobject-2.0 -lglib-2.0 -ljansson +GST_PLUGIN_LDFLAGS = -module -avoid-version -export-symbols-regex _*\(gst_\|Gst\|GST_\).* +HAVE_PKGCONFIG = +INSTALL = /usr/bin/install -c +INSTALL_DATA = ${INSTALL} -m 644 +INSTALL_PROGRAM = ${INSTALL} +INSTALL_SCRIPT = ${INSTALL} +INSTALL_STRIP_PROGRAM = $(install_sh) -c -s +LD = /usr/bin/ld -m elf_x86_64 +LDFLAGS = +LIBOBJS = +LIBS = +LIBTOOL = $(SHELL) $(top_builddir)/libtool +LIPO = +LN_S = ln -s +LTLIBOBJS = +LT_SYS_LIBRARY_PATH = +MAINT = +MAKEINFO = ${SHELL} /usr/local/src/lucida/lucida/speechrecognition/plugin/missing makeinfo +MANIFEST_TOOL = : +MKDIR_P = /bin/mkdir -p +NM = /usr/bin/nm -B +NMEDIT = +OBJDUMP = objdump +OBJEXT = o +OTOOL = +OTOOL64 = +PACKAGE = asrplugin +PACKAGE_BUGREPORT = https://github.com/claritylab/lucida/issues +PACKAGE_NAME = asrplugin +PACKAGE_STRING = asrplugin 1.0.0 +PACKAGE_TARNAME = asrplugin +PACKAGE_URL = https://github.com/claritylab/lucida/tree/master/lucida/speechrecognition +PACKAGE_VERSION = 1.0.0 +PATH_SEPARATOR = : +PKG_CONFIG = /usr/bin/pkg-config +PKG_CONFIG_LIBDIR = +PKG_CONFIG_PATH = +RANLIB = ranlib +SED = /bin/sed +SET_MAKE = +SHELL = /bin/sh +STRIP = strip +VERSION = 1.0.0 +abs_builddir = /usr/local/src/lucida/lucida/speechrecognition/plugin/src +abs_srcdir = /usr/local/src/lucida/lucida/speechrecognition/plugin/src +abs_top_builddir = /usr/local/src/lucida/lucida/speechrecognition/plugin +abs_top_srcdir = /usr/local/src/lucida/lucida/speechrecognition/plugin +ac_ct_AR = ar +ac_ct_CC = gcc +ac_ct_DUMPBIN = +am__include = include +am__leading_dot = . +am__quote = +am__tar = $${TAR-tar} chof - "$$tardir" +am__untar = $${TAR-tar} xf - +bindir = ${exec_prefix}/bin +build = x86_64-pc-linux-gnu +build_alias = +build_cpu = x86_64 +build_os = linux-gnu +build_vendor = pc +builddir = . +datadir = ${datarootdir} +datarootdir = ${prefix}/share +docdir = ${datarootdir}/doc/${PACKAGE_TARNAME} +dvidir = ${docdir} +exec_prefix = ${prefix} +host = x86_64-pc-linux-gnu +host_alias = +host_cpu = x86_64 +host_os = linux-gnu +host_vendor = pc +htmldir = ${docdir} +includedir = ${prefix}/include +infodir = ${datarootdir}/info +install_sh = ${SHELL} /usr/local/src/lucida/lucida/speechrecognition/plugin/install-sh +libdir = ${exec_prefix}/lib +libexecdir = ${exec_prefix}/libexec +localedir = ${datarootdir}/locale +localstatedir = ${prefix}/var +mandir = ${datarootdir}/man +mkdir_p = $(MKDIR_P) +oldincludedir = /usr/include +pdfdir = ${docdir} +plugindir = $(libdir)/gstreamer-1.0 +prefix = /usr/local +program_transform_name = s,x,x, +psdir = ${docdir} +runstatedir = ${localstatedir}/run +sbindir = ${exec_prefix}/sbin +sharedstatedir = ${prefix}/com +srcdir = . +sysconfdir = ${prefix}/etc +target_alias = +top_build_prefix = ../ +top_builddir = .. +top_srcdir = .. + +# Note: plugindir is set in configure +plugin_LTLIBRARIES = libgstasrplugin.la + +# sources used to compile this plug-in +libgstasrplugin_la_SOURCES = gstasrplugin.c gstasrplugin.h + +# compiler and linker flags used to compile this plugin, set in configure.ac +libgstasrplugin_la_CFLAGS = $(GST_CFLAGS) +libgstasrplugin_la_LIBADD = $(GST_LIBS) +libgstasrplugin_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) +libgstasrplugin_la_LIBTOOLFLAGS = --tag=disable-static + +# headers we need but don't want installed +noinst_HEADERS = gstasrplugin.h +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES) + @$(NORMAL_INSTALL) + @list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(plugindir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(plugindir)" || exit 1; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(plugindir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(plugindir)"; \ + } + +uninstall-pluginLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$f"; \ + done + +clean-pluginLTLIBRARIES: + -test -z "$(plugin_LTLIBRARIES)" || rm -f $(plugin_LTLIBRARIES) + @list='$(plugin_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +libgstasrplugin.la: $(libgstasrplugin_la_OBJECTS) $(libgstasrplugin_la_DEPENDENCIES) $(EXTRA_libgstasrplugin_la_DEPENDENCIES) + $(AM_V_CCLD)$(libgstasrplugin_la_LINK) -rpath $(plugindir) $(libgstasrplugin_la_OBJECTS) $(libgstasrplugin_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +include ./$(DEPDIR)/libgstasrplugin_la-gstasrplugin.Plo + +.c.o: + $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< + $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +# $(AM_V_CC)source='$<' object='$@' libtool=no \ +# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \ +# $(AM_V_CC_no)$(COMPILE) -c -o $@ $< + +.c.obj: + $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` + $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +# $(AM_V_CC)source='$<' object='$@' libtool=no \ +# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \ +# $(AM_V_CC_no)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: + $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< + $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +# $(AM_V_CC)source='$<' object='$@' libtool=yes \ +# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \ +# $(AM_V_CC_no)$(LTCOMPILE) -c -o $@ $< + +libgstasrplugin_la-gstasrplugin.lo: gstasrplugin.c + $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstasrplugin_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstasrplugin_la_CFLAGS) $(CFLAGS) -MT libgstasrplugin_la-gstasrplugin.lo -MD -MP -MF $(DEPDIR)/libgstasrplugin_la-gstasrplugin.Tpo -c -o libgstasrplugin_la-gstasrplugin.lo `test -f 'gstasrplugin.c' || echo '$(srcdir)/'`gstasrplugin.c + $(AM_V_at)$(am__mv) $(DEPDIR)/libgstasrplugin_la-gstasrplugin.Tpo $(DEPDIR)/libgstasrplugin_la-gstasrplugin.Plo +# $(AM_V_CC)source='gstasrplugin.c' object='libgstasrplugin_la-gstasrplugin.lo' libtool=yes \ +# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \ +# $(AM_V_CC_no)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstasrplugin_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstasrplugin_la_CFLAGS) $(CFLAGS) -c -o libgstasrplugin_la-gstasrplugin.lo `test -f 'gstasrplugin.c' || echo '$(srcdir)/'`gstasrplugin.c + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) $(HEADERS) +installdirs: + for dir in "$(DESTDIR)$(plugindir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-pluginLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-pluginLTLIBRARIES + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-pluginLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-pluginLTLIBRARIES cscopelist-am ctags \ + ctags-am distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-pluginLTLIBRARIES install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags tags-am uninstall uninstall-am \ + uninstall-pluginLTLIBRARIES + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/lucida/speechrecognition/plugin/src/Makefile.am b/lucida/speechrecognition/plugin/src/Makefile.am new file mode 100644 index 000000000..ddda96679 --- /dev/null +++ b/lucida/speechrecognition/plugin/src/Makefile.am @@ -0,0 +1,14 @@ +# Note: plugindir is set in configure +plugin_LTLIBRARIES = libgstasrplugin.la + +# sources used to compile this plug-in +libgstasrplugin_la_SOURCES = gstasrplugin.c gstasrplugin.h + +# compiler and linker flags used to compile this plugin, set in configure.ac +libgstasrplugin_la_CFLAGS = $(GST_CFLAGS) +libgstasrplugin_la_LIBADD = $(GST_LIBS) +libgstasrplugin_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) +libgstasrplugin_la_LIBTOOLFLAGS = --tag=disable-static + +# headers we need but don't want installed +noinst_HEADERS = gstasrplugin.h diff --git a/lucida/speechrecognition/plugin/src/gstasrplugin.c b/lucida/speechrecognition/plugin/src/gstasrplugin.c new file mode 100644 index 000000000..12d671aaa --- /dev/null +++ b/lucida/speechrecognition/plugin/src/gstasrplugin.c @@ -0,0 +1,662 @@ +/* + * GStreamer + * Copyright (C) 2005 Thomas Vander Stichele + * Copyright (C) 2005 Ronald S. Bultje + * Copyright (C) 2017 Kamal Galrani <> + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Alternatively, the contents of this file may be used under the + * GNU Lesser General Public License Version 2.1 (the "LGPL"), in + * which case the following provisions apply instead of the ones + * mentioned above: + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/** + * SECTION:element-asrplugin + * + * Generic speech to text converter for Lucida AI + * + * + * Example launch line + * |[ + * GST_PLUGIN_PATH=. gst-launch-1.0 --gst-debug="asrplugin:5" \ + * -q filesrc location=sample.wav ! decodebin ! audioconvert ! \ + * audioresample ! asrplugin ! filesink location=output.txt + * ]| + * + */ + +#include +#include +#include "gstasrplugin.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +/* JSON_REAL_PRECISION is a macro from libjansson 2.7. Ubuntu 12.04 only has 2.2.1-1 */ +#ifndef JSON_REAL_PRECISION +#define JSON_REAL_PRECISION(n) (((n) & 0x1F) << 11) +#endif // JSON_REAL_PRECISION + +GST_DEBUG_CATEGORY_STATIC (gst_asrplugin_debug); +#define GST_CAT_DEFAULT gst_asrplugin_debug + +/* Filter signals and args */ +enum +{ + INTERIM_RESULT_SIGNAL, + FINAL_RESULT_SIGNAL, + LAST_SIGNAL +}; + +enum +{ + PROP_0, + PROP_SILENCE_TIMEOUT, + PROP_INITIAL_SILENCE_TIMEOUT, + PROP_SILENCE_THRESHOLD, + PROP_DECODER_EXECUTABLE, + PROP_DECODER_CONFIGURATION, + PROP_MESSAGE_CONTEXT +}; + +/* + * the capabilities of the inputs and outputs. + * + * describe the real formats here. + */ +static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink", + GST_PAD_SINK, + GST_PAD_ALWAYS, + GST_STATIC_CAPS ("audio/x-raw, format = (string) S16LE, channels = (int) 1, rate = (int) 16000") + ); + +static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src", + GST_PAD_SRC, + GST_PAD_ALWAYS, + GST_STATIC_CAPS ("text/x-raw, format= { utf8 }") + ); + +static guint gst_asrplugin_signals[LAST_SIGNAL]; + +#define gst_asrplugin_parent_class parent_class +G_DEFINE_TYPE (Gstasrplugin, gst_asrplugin, GST_TYPE_ELEMENT); + +static void gst_asrplugin_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec); + +static void gst_asrplugin_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec); + +static gboolean gst_asrplugin_sink_event (GstPad * pad, GstObject * parent, GstEvent * event); + +static GstFlowReturn gst_asrplugin_sink_chain (GstPad * pad, GstObject * parent, GstBuffer * buf); + +static gboolean gst_asrplugin_sink_query(GstPad *pad, GstObject * parent, GstQuery * query); + +static void gst_asrplugin_finalize (GObject * object); + +static void *gst_asrplugin_read_decoder( void *ptr ); + +/* TODO: Declare other functons too */ + +/* GObject vmethod implementations */ + +/* initialize the asrplugin's class */ +static void gst_asrplugin_class_init (GstasrpluginClass * klass) +{ + GObjectClass *gobject_class; + GstElementClass *gstelement_class; + + gobject_class = (GObjectClass *) klass; + gstelement_class = (GstElementClass *) klass; + + gobject_class->set_property = gst_asrplugin_set_property; + gobject_class->get_property = gst_asrplugin_get_property; + + gobject_class->finalize = gst_asrplugin_finalize; + + g_object_class_install_property (gobject_class, PROP_SILENCE_TIMEOUT, + g_param_spec_float ("silence_timeout", "Silence Timeout", "Number of seconds of silence after which I should force EOS.", + MIN_SILENCE_TIMEOUT, MAX_SILENCE_TIMEOUT, DEFAULT_SILENCE_TIMEOUT, G_PARAM_READWRITE)); + + g_object_class_install_property (gobject_class, PROP_INITIAL_SILENCE_TIMEOUT, + g_param_spec_float ("initial_silence_timeout", "Initial Silence Timeout", "Additional number of seconds of silence to grant at the start of stream.", + MIN_SILENCE_TIMEOUT, MAX_SILENCE_TIMEOUT, DEFAULT_INITIAL_SILENCE_TIMEOUT, G_PARAM_READWRITE)); + + g_object_class_install_property (gobject_class, PROP_SILENCE_THRESHOLD, + g_param_spec_uint ("silence_threshold", "Silence Threshold", "I will consider the samples with RMS below this value as silence.", + MIN_SILENCE_THRESHOLD, MAX_SILENCE_THRESHOLD, DEFAULT_SILENCE_THRESHOLD, G_PARAM_READWRITE)); + + g_object_class_install_property (gobject_class, PROP_DECODER_EXECUTABLE, + g_param_spec_string ("decoder_executable", "Decoder Executable", "Path to decoder executable either absolute or relative to speechrecognition/decoder directory.", + "", G_PARAM_WRITABLE)); + + g_object_class_install_property (gobject_class, PROP_DECODER_CONFIGURATION, + g_param_spec_string ("decoder_configuration", "Decoder Configuration", "I will forward this as it is to control channel of the decoder. Any consequences are your own doing ;).", + "{}", G_PARAM_WRITABLE)); + + g_object_class_install_property (gobject_class, PROP_MESSAGE_CONTEXT, + g_param_spec_string ("message_context", "Message Context", "Context of the message. This typically will contain user name and decoder specific context received during last request.", + "{}", G_PARAM_WRITABLE)); + + gst_asrplugin_signals[INTERIM_RESULT_SIGNAL] = g_signal_new( + "interim-result", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(GstasrpluginClass, interim_result), + NULL, NULL, NULL, G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_FLOAT); + + gst_asrplugin_signals[FINAL_RESULT_SIGNAL] = g_signal_new( + "final-result", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(GstasrpluginClass, final_result), + NULL, NULL, NULL, G_TYPE_NONE, 3, G_TYPE_STRING, G_TYPE_FLOAT, G_TYPE_STRING); + + gst_element_class_set_details_simple (gstelement_class, + "asrplugin", + "Speech/Audio", + "Generic speech to text converter for Lucida AI", + "Kamal Galrani <>"); + + gst_element_class_add_pad_template (gstelement_class, gst_static_pad_template_get (&src_factory)); + gst_element_class_add_pad_template (gstelement_class, gst_static_pad_template_get (&sink_factory)); +} + +/* initialize the new element + * instantiate pads and add them to element + * set pad calback functions + * initialize instance structure + */ +static void gst_asrplugin_init (Gstasrplugin * filter) +{ + filter->sinkpad = gst_pad_new_from_static_template (&sink_factory, "sink"); + gst_pad_set_event_function (filter->sinkpad, gst_asrplugin_sink_event); + gst_pad_set_chain_function (filter->sinkpad, gst_asrplugin_sink_chain); + gst_pad_set_query_function (filter->sinkpad, gst_asrplugin_sink_query); + gst_pad_use_fixed_caps (filter->sinkpad); + gst_element_add_pad (GST_ELEMENT (filter), filter->sinkpad); + + filter->srcpad = gst_pad_new_from_static_template (&src_factory, "src"); + gst_pad_use_fixed_caps (filter->srcpad); + gst_element_add_pad (GST_ELEMENT (filter), filter->srcpad); + + filter->decoder_data = -1; + filter->decoder_ctrl = NULL; + filter->decoder_out = NULL; + filter->silence_timeout = DEFAULT_SILENCE_TIMEOUT; + filter->initial_silence_timeout = DEFAULT_INITIAL_SILENCE_TIMEOUT; + filter->silence_threshold = DEFAULT_SILENCE_THRESHOLD; + filter->silent_for = DEFAULT_SILENCE_TIMEOUT - DEFAULT_INITIAL_SILENCE_TIMEOUT; + filter->segment_length = 0.0; + filter->shutting_down = false; +} + +/* set_property function + * Set properties of plugin. + */ +static void gst_asrplugin_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) +{ + Gstasrplugin *filter = GST_ASRPLUGIN (object); + + switch (prop_id) { + case PROP_SILENCE_TIMEOUT: + filter->silence_timeout = g_value_get_float (value); + break; + case PROP_INITIAL_SILENCE_TIMEOUT: + filter->initial_silence_timeout = g_value_get_float (value); + break; + case PROP_SILENCE_THRESHOLD: + filter->silence_threshold = g_value_get_uint (value); + break; + case PROP_DECODER_EXECUTABLE: + if (G_UNLIKELY (filter->decoder_out != NULL || filter->decoder_ctrl != NULL || filter->decoder_data != -1)) { + GST_ELEMENT_ERROR (filter, RESOURCE, OPEN_READ_WRITE, (NULL), ("Either a decoder is already loaded or it is in a unrecoverable state!!!")); + break; + } + + gchar decoder_command[512]; + + tmpnam (filter->decoder_ctrl_name); + tmpnam (filter->decoder_data_name); + mkfifo (filter->decoder_ctrl_name, 0666); + mkfifo (filter->decoder_data_name, 0666); + + sprintf (decoder_command, "%s --data %s --ctrl %s", g_value_get_string (value), filter->decoder_data_name, filter->decoder_ctrl_name); + filter->decoder_out = popen (decoder_command, "r"); + + if (G_UNLIKELY (filter->decoder_out == NULL)) { + GST_ELEMENT_ERROR (filter, RESOURCE, OPEN_READ, (NULL), ("Could not load decoder!!! Is decoder executable a valid executable file?")); + } + + gint fd = open (filter->decoder_ctrl_name, O_WRONLY); + filter->decoder_ctrl = fdopen (fd, "w"); + + if (G_UNLIKELY (filter->decoder_out == NULL)) { + GST_ELEMENT_ERROR (filter, RESOURCE, OPEN_WRITE, (NULL), ("Could not load decoder!!! Failed to open control channel")); + } + + if (G_UNLIKELY (pthread_create(&filter->tid, NULL, gst_asrplugin_read_decoder, (void *) filter) != 0)) { + GST_ELEMENT_ERROR (filter, RESOURCE, OPEN_WRITE, (NULL), ("Could not load decoder!!! Failed to start read decoder thread")); + } + + GST_DEBUG_OBJECT (filter, "Successfully loaded decoder: %s", g_value_get_string (value)); + break; + case PROP_DECODER_CONFIGURATION: + if (G_UNLIKELY (filter->decoder_data != -1)) { + GST_ELEMENT_WARNING (filter, RESOURCE, BUSY, (NULL), ("Configuration load requested when decoder is running!!! Ignoring request...")); + break; + } + if (G_UNLIKELY (filter->decoder_ctrl == NULL)) { + GST_ELEMENT_ERROR (filter, RESOURCE, NOT_FOUND, (NULL), ("Configuration load requested before decoder was loaded!!!")); + break; + } + fprintf (filter->decoder_ctrl, "%s\n", g_value_get_string (value)); + fflush (filter->decoder_ctrl); + GST_DEBUG_OBJECT (filter, "Successfully configured decoder"); + break; + case PROP_MESSAGE_CONTEXT: + if (G_UNLIKELY (filter->decoder_data != -1)) { + GST_ELEMENT_WARNING (filter, RESOURCE, BUSY, (NULL), ("Context load requested when decoder is running!!! Ignoring request...")); + break; + } + if (G_UNLIKELY (filter->decoder_ctrl == NULL)) { + GST_ELEMENT_ERROR (filter, RESOURCE, NOT_FOUND, (NULL), ("Context load requested before decoder was loaded!!!")); + break; + } + fprintf (filter->decoder_ctrl, "%s\n", g_value_get_string (value)); + fflush (filter->decoder_ctrl); + GST_DEBUG_OBJECT (filter, "Successfully pushed context to decoder"); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +/* get_property function + * Get properties of plugin. + */ +static void gst_asrplugin_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec) +{ + Gstasrplugin *filter = GST_ASRPLUGIN (object); + + switch (prop_id) { + case PROP_SILENCE_TIMEOUT: + g_value_set_float (value, filter->silence_timeout); + break; + case PROP_INITIAL_SILENCE_TIMEOUT: + g_value_set_float (value, filter->initial_silence_timeout); + break; + case PROP_SILENCE_THRESHOLD: + g_value_set_uint (value, filter->silence_threshold); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +/* stop_decoder function + * Stop decoder by closing data FIFO + */ +static gboolean gst_asrplugin_stop_decoder (Gstasrplugin * filter) +{ + GST_DEBUG_OBJECT (filter, "Sending stop command to decoder..."); + if (G_UNLIKELY (filter->decoder_ctrl == NULL)) { + GST_ELEMENT_ERROR (filter, RESOURCE, NOT_FOUND, (NULL), ("Decoder stop requested before it was loaded!!!")); + return false; + } + if (G_UNLIKELY (filter->decoder_data == -1)) { + GST_ELEMENT_WARNING (filter, RESOURCE, CLOSE, (NULL), ("Decoder stop requested when it is not running!!! Ignoring request...")); + gst_pad_push_event(filter->srcpad, gst_event_new_eos()); + return true; + } + close (filter->decoder_data); + filter->decoder_data = -1; + filter->silent_for = filter->silence_timeout - filter->initial_silence_timeout; + filter->segment_length = 0; + return true; +} + +/* start_decoder function + * Send start command to decoder control channel + */ +static gboolean gst_asrplugin_start_decoder (Gstasrplugin * filter) +{ + GST_DEBUG_OBJECT (filter, "Sending start command to decoder..."); + if (G_UNLIKELY (filter->decoder_ctrl == NULL)) { + GST_ELEMENT_ERROR (filter, RESOURCE, NOT_FOUND, (NULL), ("Decoder start requested before it was loaded!!!")); + return false; + } + if (G_UNLIKELY (filter->decoder_data != -1)) { + GST_ELEMENT_WARNING (filter, RESOURCE, BUSY, (NULL), ("Decoder start requested when it is already running!!! Ignoring request...")); + return true; + } + fprintf (filter->decoder_ctrl, "{\"command\":\"start\"}\n"); + fflush (filter->decoder_ctrl); + filter->decoder_data = open (filter->decoder_data_name, O_WRONLY ); + if (G_UNLIKELY (filter->decoder_data == -1)) { + GST_ELEMENT_ERROR (filter, RESOURCE, OPEN_WRITE, (NULL), ("Could not start decoder!!! Failed to open data channel")); + return false; + } + filter->silent_for = filter->silence_timeout - filter->initial_silence_timeout; + filter->segment_length = 0; + GST_DEBUG_OBJECT (filter, "Succesfully started decoder"); + return true; +} + +/* silence_counter function + * Check for long silences in audio + */ +static void gst_asrplugin_silence_counter (Gstasrplugin* filter, guchar* data, gfloat chunk_length) +{ + /* TODO: Check for silence */ + gboolean silent = false; + if (silent) { + filter->silent_for = filter->silent_for + chunk_length; + } else if (filter->silent_for != filter->silence_timeout - filter->initial_silence_timeout) { + filter->silent_for = 0.0; + } + if (filter->silent_for > filter->silence_timeout) { + GST_ELEMENT_WARNING (filter, RESOURCE, CLOSE, (NULL), ("Silent for too long!!! Stopping decoder...")); + gst_asrplugin_stop_decoder(filter); + } +} + +static void *gst_asrplugin_read_decoder( void *ptr ) +{ + Gstasrplugin *filter = (Gstasrplugin *) ptr; + GST_DEBUG_OBJECT (filter, "Starting decoder listener thread..."); + gchar * line = NULL; + size_t dummy = 0; + ssize_t bytes; + + while ( ! filter->shutting_down ) { + bytes = getline(&line, &dummy, filter->decoder_out); + if (G_UNLIKELY (bytes == -1)) { + GST_ELEMENT_ERROR (filter, RESOURCE, READ, (NULL), ("Decoder crashed!!! Cleaning up...")); + // TODO: Clean up, send EOS, quit worker + break; + } + + json_t *root; + json_t *event; + json_t *status; + json_t *data; + json_t *duration; + json_t *context; + json_error_t error; + root = json_loads (line, 0, &error); + if ( !root ) { + GST_ELEMENT_WARNING (filter, RESOURCE, READ, (NULL), ("Received invalid JSON message from decoder!!! Ignoring message...")); + continue; + } + event = json_object_get (root, "event"); + status = json_object_get (root, "status"); + data = json_object_get (root, "data"); + context = json_object_get (root, "context"); + duration = json_object_get (root, "duration"); + if ( !json_is_string (event) ) { + GST_ELEMENT_WARNING (filter, RESOURCE, READ, (NULL), ("Received invalid JSON message from decoder: No field 'event' found. Ignoring message...")); + json_decref(root); + continue; + } + if ( !json_is_integer (status) ) { + GST_ELEMENT_WARNING (filter, RESOURCE, READ, (NULL), ("Received invalid JSON message from decoder: No field 'status' found. Ignoring message...")); + json_decref(root); + continue; + } + if ( !json_is_string (data) ) { + GST_ELEMENT_WARNING (filter, RESOURCE, READ, (NULL), ("Received invalid JSON message from decoder: No field 'data' found. Ignoring message...")); + json_decref(root); + continue; + } + + if (strcmp(json_string_value (event), "interim_result") == 0) { + GST_DEBUG_OBJECT (filter, "Interim results received from decoder"); + gfloat duration_value = 0.0; + if ( !json_is_real (duration) ) { + GST_ELEMENT_WARNING (filter, RESOURCE, READ, (NULL), ("No field 'duration' found while parsing interim results. Using 0.0...")); + } else { + duration_value = json_real_value (duration); + } + g_signal_emit (filter, gst_asrplugin_signals[INTERIM_RESULT_SIGNAL], 0, json_string_value (data), duration_value); + } else if (strcmp(json_string_value (event), "final_result") == 0) { + GST_DEBUG_OBJECT (filter, "Final results received from decoder"); + + GstBuffer *buffer = gst_buffer_new_and_alloc (strlen (json_string_value (data)) + 1); + gst_buffer_fill (buffer, 0, json_string_value (data), strlen (json_string_value (data))); + gst_buffer_memset (buffer, strlen (json_string_value (data)) , '\n', 1); + gst_pad_push(filter->srcpad, buffer); + + gfloat duration_value = 0.0; + if ( !json_is_real (duration) ) { + GST_ELEMENT_WARNING (filter, RESOURCE, READ, (NULL), ("No field 'duration' found while parsing final results. Using 0.0...")); + } else { + duration_value = json_real_value (duration); + } + if ( !json_is_string (context) ) { + GST_ELEMENT_WARNING (filter, RESOURCE, READ, (NULL), ("No field 'context' found while parsing interim results. Using empty context...")); + g_signal_emit (filter, gst_asrplugin_signals[FINAL_RESULT_SIGNAL], 0, json_string_value (data), duration_value, "{}"); + } else { + g_signal_emit (filter, gst_asrplugin_signals[FINAL_RESULT_SIGNAL], 0, json_string_value (data), duration_value, json_string_value (context)); + } + gst_pad_push_event(filter->srcpad, gst_event_new_eos()); + } else if (strcmp(json_string_value (event), "eos") == 0) { + GST_DEBUG_OBJECT (filter, "End-of-Stream received from decoder"); + gst_pad_push_event(filter->srcpad, gst_event_new_eos()); + } else if (strcmp(json_string_value (event), "error") == 0) { + GST_ELEMENT_ERROR (filter, STREAM, DECODE, (NULL), ("DECODER: %s", json_string_value (data))); + } else if (strcmp(json_string_value (event), "warn") == 0) { + GST_ELEMENT_WARNING (filter, STREAM, DECODE, (NULL), ("DECODER: %s", json_string_value (data))); + } else if (strcmp(json_string_value (event), "info") == 0) { + GST_ELEMENT_INFO (filter, STREAM, DECODE, (NULL), ("DECODER: %s", json_string_value (data))); + } else if (strcmp(json_string_value (event), "debug") == 0) { + GST_DEBUG_OBJECT (filter, "DECODER: %s", json_string_value (data)); + } + json_decref(root); + } + + g_free(line); + GST_DEBUG_OBJECT (filter, "Terminating decoder listener thread..."); + return NULL; +} + + +/* GstElement vmethod implementations */ + +/* sink_query function + * this function handles sink queries + */ +static gboolean gst_asrplugin_sink_query (GstPad *pad, GstObject * parent, GstQuery * query) +{ + gboolean ret; + + switch (GST_QUERY_TYPE (query)) { + case GST_QUERY_CAPS: + ret = TRUE; + GstCaps *new_caps = gst_caps_new_simple ("audio/x-raw", + "format", G_TYPE_STRING, "S16LE", + "rate", G_TYPE_INT, 16000, + "channels", G_TYPE_INT, 1, NULL); + + gst_query_set_caps_result (query, new_caps); + gst_caps_unref (new_caps); + break; + default: + ret = gst_pad_query_default (pad, parent, query); + break; + } + return ret; +} + +/* sink_event function + * this function handles sink events + */ +static gboolean gst_asrplugin_sink_event (GstPad * pad, GstObject * parent, GstEvent * event) +{ + Gstasrplugin *filter; + filter = GST_ASRPLUGIN (parent); + + GST_DEBUG_OBJECT(filter, "Handling %s event", GST_EVENT_TYPE_NAME(event)); + + switch (GST_EVENT_TYPE (event)) { + case GST_EVENT_SEGMENT: + return gst_asrplugin_start_decoder (filter); + case GST_EVENT_EOS: + return gst_asrplugin_stop_decoder (filter); + default: + return gst_pad_event_default (pad, parent, event); + } +} + +/* sink_chain function + * this function does the actual processing + */ +static GstFlowReturn gst_asrplugin_sink_chain (GstPad * pad, GstObject * parent, GstBuffer * buf) +{ + Gstasrplugin *filter; + filter = GST_ASRPLUGIN (parent); + + GstMapInfo map; + if (G_UNLIKELY (gst_buffer_map (buf, &map, GST_MAP_READ) == false)) { + goto memory_map_issue; + } + if (G_UNLIKELY (filter->decoder_out == NULL)) { + goto decoder_not_loaded; + } + if (G_UNLIKELY (filter->decoder_data == -1)) { + goto decoder_not_started; + } + GST_DEBUG_OBJECT (filter, "Pushing chunk to decoder... %ld", map.size); + + write (filter->decoder_data, map.data, map.size); + filter->segment_length = filter->segment_length + (float) map.size / 32000.0; + gst_asrplugin_silence_counter (filter, map.data, (float) map.size / 32000.0); + + gst_buffer_unmap (buf, &map); + gst_buffer_unref (buf); + return GST_FLOW_OK; + + /* special cases */ + memory_map_issue: { + GST_ELEMENT_WARNING (filter, RESOURCE, READ, (NULL), ("Error while reading data from buffer!!! Ignoring chunk...")); + + gst_buffer_unmap (buf, &map); + gst_buffer_unref (buf); + return GST_FLOW_OK; + } + decoder_not_started: { + GST_ELEMENT_ERROR (filter, CORE, PAD, (NULL), ("Data recieved before decoder was started!!!")); + + gst_buffer_unmap (buf, &map); + gst_buffer_unref (buf); + return GST_FLOW_EOS; + } + decoder_not_loaded: { + GST_ELEMENT_ERROR (filter, CORE, PAD, (NULL), ("Data recieved before decoder was loaded!!!")); + + gst_buffer_unmap (buf, &map); + gst_buffer_unref (buf); + return GST_FLOW_ERROR; + } +} + +static void gst_asrplugin_finalize (GObject * object) +{ + Gstasrplugin *filter; + filter = GST_ASRPLUGIN (object); + + GST_DEBUG_OBJECT (filter, "Shutting down ASR Plugin..."); + filter->shutting_down = true; + + GST_DEBUG_OBJECT (filter, "Stopping decoder if it is running..."); + if (G_UNLIKELY (filter->decoder_data != -1)) { + gst_asrplugin_stop_decoder (filter); + } + + GST_DEBUG_OBJECT (filter, "Waiting for decoder read thread to join..."); + fclose(filter->decoder_ctrl); + filter->decoder_ctrl = NULL; + pthread_join (filter->tid, NULL); + + GST_DEBUG_OBJECT (filter, "Shutting down decoder subprocess..."); + pclose(filter->decoder_out); + filter->decoder_out = NULL; + + GST_DEBUG_OBJECT (filter, "Deleting temporary files..."); + remove (filter->decoder_data_name); + remove (filter->decoder_ctrl_name); + + G_OBJECT_CLASS(parent_class)->finalize(object); +} + +/* entry point to initialize the plug-in + * initialize the plug-in itself + * register the element factories and other features + */ +static gboolean asrplugin_init (GstPlugin * asrplugin) +{ + GST_DEBUG_CATEGORY_INIT (gst_asrplugin_debug, "asrplugin", 0, DESCRIPTION); + + return gst_element_register (asrplugin, "asrplugin", GST_RANK_NONE, GST_TYPE_ASRPLUGIN); +} + +/* PACKAGE: this is usually set by autotools depending on some _INIT macro + * in configure.ac and then written into and defined in config.h, but we can + * just set it ourselves here in case someone doesn't use autotools to + * compile this code. GST_PLUGIN_DEFINE needs PACKAGE to be defined. + */ +#ifndef PACKAGE +#define PACKAGE "asrplugin" +#endif + +/* gstreamer looks for this structure to register asrplugins + */ +GST_PLUGIN_DEFINE ( + GST_VERSION_MAJOR, + GST_VERSION_MINOR, + asrplugin, + "Generic GST plugin for speech recognition in Lucida AI", + asrplugin_init, + VERSION, + "LGPL", + "GStreamer", + "http://gstreamer.net/" +) diff --git a/lucida/speechrecognition/plugin/src/gstasrplugin.h b/lucida/speechrecognition/plugin/src/gstasrplugin.h new file mode 100644 index 000000000..61f0280af --- /dev/null +++ b/lucida/speechrecognition/plugin/src/gstasrplugin.h @@ -0,0 +1,110 @@ +/* + * GStreamer + * Copyright (C) 2005 Thomas Vander Stichele + * Copyright (C) 2005 Ronald S. Bultje + * Copyright (C) 2017 Kamal Galrani <> + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Alternatively, the contents of this file may be used under the + * GNU Lesser General Public License Version 2.1 (the "LGPL"), in + * which case the following provisions apply instead of the ones + * mentioned above: + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __GST_ASRPLUGIN_H__ +#define __GST_ASRPLUGIN_H__ + +#include +#include +#include + +G_BEGIN_DECLS + +/* #defines don't like whitespacey bits */ +#define MIN_SILENCE_TIMEOUT 1.0f +#define MAX_SILENCE_TIMEOUT 5.0f +#define DEFAULT_SILENCE_TIMEOUT 2.0f +#define DEFAULT_INITIAL_SILENCE_TIMEOUT 5.0f + +#define MIN_SILENCE_THRESHOLD 100 +#define MAX_SILENCE_THRESHOLD 10000 +#define DEFAULT_SILENCE_THRESHOLD 2000 + +#define GST_TYPE_ASRPLUGIN \ + (gst_asrplugin_get_type()) +#define GST_ASRPLUGIN(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_ASRPLUGIN,Gstasrplugin)) +#define GST_ASRPLUGIN_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_ASRPLUGIN,GstasrpluginClass)) +#define GST_IS_ASRPLUGIN(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_ASRPLUGIN)) +#define GST_IS_ASRPLUGIN_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_ASRPLUGIN)) + +typedef struct _Gstasrplugin Gstasrplugin; +typedef struct _GstasrpluginClass GstasrpluginClass; + +struct _Gstasrplugin +{ + GstElement element; + + GstPad *sinkpad, *srcpad; + + gboolean shutting_down; + gint decoder_data; + FILE* decoder_ctrl; + FILE* decoder_out; + gchar decoder_data_name[32]; + gchar decoder_ctrl_name[32]; + gfloat segment_length; + gfloat silence_timeout; + gfloat initial_silence_timeout; + gfloat silent_for; + guint silence_threshold; + pthread_t tid; +}; + +struct _GstasrpluginClass +{ + GstElementClass parent_class; + void (*interim_result)(GstElement *element, const gchar *result_str, const gfloat duration); + void (*final_result)(GstElement *element, const gchar *result_str, const gfloat duration, const gchar *context_str); +}; + +GType gst_asrplugin_get_type (void); + +G_END_DECLS + +#endif /* __GST_ASRPLUGIN_H__ */ diff --git a/lucida/speechrecognition/wit_stt/Makefile b/lucida/speechrecognition/wit_stt/Makefile deleted file mode 100644 index 757988ef6..000000000 --- a/lucida/speechrecognition/wit_stt/Makefile +++ /dev/null @@ -1,4 +0,0 @@ -start_server: - ./simple_start.sh - -.PHONY: start_server diff --git a/lucida/speechrecognition/wit_stt/common.py b/lucida/speechrecognition/wit_stt/common.py deleted file mode 100644 index cefd67743..000000000 --- a/lucida/speechrecognition/wit_stt/common.py +++ /dev/null @@ -1,13 +0,0 @@ -__author__ = 'tanel' - -STATUS_EOS = -1 -STATUS_SUCCESS = 0 -STATUS_NO_SPEECH = 1 -STATUS_ABORTED = 2 -STATUS_AUDIO_CAPTURE = 3 -STATUS_NETWORK = 4 -STATUS_NOT_ALLOWED = 5 -STATUS_SERVICE_NOT_ALLOWED = 6 -STATUS_BAD_GRAMMAR = 7 -STATUS_LANGUAGE_NOT_SUPPORTED = 8 -STATUS_NOT_AVAILABLE = 9 \ No newline at end of file diff --git a/lucida/speechrecognition/wit_stt/decoder.py b/lucida/speechrecognition/wit_stt/decoder.py deleted file mode 100644 index 486bea9c6..000000000 --- a/lucida/speechrecognition/wit_stt/decoder.py +++ /dev/null @@ -1,160 +0,0 @@ -""" -Created on Jun 14 2017 - -@author: kamal1210 -""" - -import logging -import threading -import time -import requests -import json -from audioop import rms - -logger = logging.getLogger(__name__) - -class DecoderPipeline(object): - STATE_CREATED = 0 - STATE_INITIALIZED = 2 - STATE_PROCESSING = 3 - STATE_EOS_RECEIVED = 7 - STATE_FINISHED = 100 - - def __init__(self, conf={}): - try: - self.api_token = conf["api-token"] - self.api_host = conf["api-host"] - self.silence_threshold = conf["silence-threshold"] - self.silence_timeout = conf["silence-timeout"] - self.request_timeout = conf["request-timeout"] - self.socket_data_timeout = conf["socket-data-timeout"] - except Exception as e: - logger.error("Key '%s' not found in configuration file!!!" % e.message) - raise KeyError("Key '%s' not found in configuration file!!!" % e.message) - - self.result_handler = None - self.full_result_handler = None - self.eos_handler = None - self.error_handler = None - self.request_id = "" - self.buffer = [] - self.lock = threading.Lock() - self.state = self.STATE_CREATED - self.silent_for = 0.0 - self.last_chunk_yielded = 0 - self.eos_received = 0 - logger.info("Initialized decoder with endpoint: %s" % (self.api_host)) - - def is_silent(self, block): - try: - rms_value = rms(block, 2) - return rms_value, rms_value <= self.silence_threshold - except: - return -1, True - - def _post_req_ctrl(self): - self.request_generator = threading.Thread(target=self._post_req_gen) - self.request_generator.daemon = True - self.request_generator.start() - while self.eos_received == 0: - time.sleep(1) - while self.state != self.STATE_FINISHED: - if time.time() - self.eos_received > self.request_timeout: - self.request_generator.stop() - logger.error("Request to %s timed out!!!" % self.api_host) - if self.error_handler: - self.error_handler("Request to %s timed out!!!" % self.api_host) - self.finish_request() - time.sleep(1) - - def _post_req_gen(self): - self.last_chunk_yielded = time.time() - self.state = self.STATE_PROCESSING - response = requests.post(self.api_host, headers=self.headers, data=self._post_data_gen()) - if response.status_code == 200: - response_json = json.loads(response.text) - result = { 'status': 0, 'total-length': 0.0, 'result': { 'hypotheses': [{ 'likelihood': 100.0, 'confidence': 1.0, 'transcript': response_json['_text']}], 'final': True }, 'segment-length': 0.0, 'segment-start': 0.0 } - if self.full_result_handler: - self.full_result_handler(json.dumps(result)) - else: - response_json = json.loads(response.text) - logger.error(response_json['error']) - if self.error_handler: - self.error_handler(response_json['error']) - self.finish_request() - - def _post_data_gen(self): - while self.state == self.STATE_PROCESSING: - self.lock.acquire() - if self.buffer: - chunk = self.buffer.pop(0) - if chunk != 'EOS': - yield chunk - self.last_chunk_yielded = time.time() - amplitude, silent = self.is_silent(chunk) - if silent: - self.silent_for = self.silent_for + len(chunk)/2.0/16000 - else: - self.silent_for = 0.0 - logger.debug("%s: Yielding %d bytes of data with rms %d " % (self.request_id, len(chunk), amplitude)) - else: - self.state = self.STATE_EOS_RECEIVED - logger.info("%s: Received EOS!!! Closing POST buffer.." % self.request_id) - self.lock.release() - if ( time.time() - self.last_chunk_yielded ) > self.socket_data_timeout: - self.state = self.STATE_EOS_RECEIVED - if self.silent_for > self.silence_timeout: - self.state = self.STATE_EOS_RECEIVED - self.eos_received = time.time() - - def finish_request(self): - logger.info("%s: Resetting decoder state" % self.request_id) - if self.eos_handler: - self.eos_handler[0](self.eos_handler[1]) - self.state = self.STATE_FINISHED - self.request_id = "" - self.buffer = [] - self.silent_for = 0.0 - self.last_chunk_yielded = 0 - - def init_request(self, request_id, caps_str): - self.request_id = request_id - content_type='audio/raw;encoding=signed-integer;bits=16;rate=16000;endian=little' - logger.info("%s: Initializing request" % self.request_id) - logger.info("%s: Setting content_type to %s" % (self.request_id, content_type)) - self.headers = {'Authorization': 'Bearer ' + self.api_token, 'Content-Type': content_type, 'Accept': 'application/json', 'Transfer-Encoding': 'chunked'} - self.state = self.STATE_INITIALIZED - self.request_controller = threading.Thread(target=self._post_req_ctrl) - self.request_controller.daemon = True - self.request_controller.start() - - def process_data(self, data): - if self.state == self.STATE_PROCESSING: - logger.debug('%s: Pushing %d bytes of data to buffer' % (self.request_id, len(data))) - self.lock.acquire() - self.buffer.append(data) - self.lock.release() - - def end_request(self): - logger.info("%s: Pushing EOS to buffer" % self.request_id) - self.lock.acquire() - self.buffer.append('EOS') - self.lock.release() - - def set_result_handler(self, handler): - self.result_handler = handler - - def set_full_result_handler(self, handler): - self.full_result_handler = handler - - def set_eos_handler(self, handler, user_data=None): - self.eos_handler = (handler, user_data) - - def set_error_handler(self, handler): - self.error_handler = handler - - def cancel(self): - self.request_controller.stop() - self.request_generator.stop() - self.finish_request() - logger.info("%s: Cancelled pipeline" % self.request_id) diff --git a/lucida/speechrecognition/wit_stt/simple_start.sh b/lucida/speechrecognition/wit_stt/simple_start.sh deleted file mode 100755 index c3626815c..000000000 --- a/lucida/speechrecognition/wit_stt/simple_start.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash -source $(pwd)/../../config.properties -if [ -z $SECURE_HOST ]; then - export ASR_ADDR_PORT="ws://localhost:$CMD_PORT" -else - export ASR_ADDR_PORT="wss://localhost:$CMD_PORT" -fi -# export ASR_ADDR_PORT="wss://lucida.homelinuxserver.org:443" -python worker.py -u ${ASR_ADDR_PORT}/worker/ws/speech -c wit.yaml diff --git a/lucida/speechrecognition/wit_stt/wit.yaml b/lucida/speechrecognition/wit_stt/wit.yaml deleted file mode 100644 index ecefeaf75..000000000 --- a/lucida/speechrecognition/wit_stt/wit.yaml +++ /dev/null @@ -1,13 +0,0 @@ - -wit-access-token: '' -wit-api-version: 14/06/201 - -partial-results: True -max-result-rate: 1 - -silence-timeout: 5 -connect-timeout: 5 -request-timeout: 5 -response-timeout: 5 - -post-processor: perl -npe 'BEGIN {use IO::Handle; STDOUT->autoflush(1);} s/(.*)/\1./;' diff --git a/lucida/speechrecognition/wit_stt/worker.py b/lucida/speechrecognition/wit_stt/worker.py deleted file mode 100644 index fdb4cbdf7..000000000 --- a/lucida/speechrecognition/wit_stt/worker.py +++ /dev/null @@ -1,305 +0,0 @@ -__author__ = 'kamal1210' - -import logging -import logging.config -import time -import thread -import argparse -from subprocess import Popen, PIPE -import yaml -import json -import sys -import os -import time - -from ws4py.client.threadedclient import WebSocketClient -import ws4py.messaging - -from decoder import DecoderPipeline -import common - -empty_response = '' - -logger = logging.getLogger(__name__) - -CONNECT_TIMEOUT = 5 -SILENCE_TIMEOUT = 5 -REQUEST_TIMEOUT = 5 -RESPONSE_TIMEOUT = 5 - -class ServerWebsocket(WebSocketClient): - STATE_CREATED = 0 - STATE_CONNECTED = 1 - STATE_INITIALIZED = 2 - STATE_PROCESSING = 3 - STATE_EOS_RECEIVED = 7 - STATE_CANCELLING = 8 - STATE_FINISHED = 100 - - def __init__(self, uri, decoder_pipeline, post_processor, full_post_processor=None): - self.uri = uri - self.decoder_pipeline = decoder_pipeline - self.post_processor = post_processor - self.full_post_processor = full_post_processor - WebSocketClient.__init__(self, url=uri, heartbeat_freq=10) - self.pipeline_initialized = False - self.partial_transcript = "" - self.decoder_pipeline.set_result_handler(self._on_result) - self.decoder_pipeline.set_full_result_handler(self._on_full_result) - self.decoder_pipeline.set_error_handler(self._on_error) - self.decoder_pipeline.set_eos_handler(self._on_eos) - self.state = self.STATE_CREATED - self.last_decoder_message = time.time() - self.request_id = "" - self.num_segments = 0 - self.last_partial_result = "" - - def opened(self): - logger.info("Opened websocket connection to server") - self.state = self.STATE_CONNECTED - self.last_partial_result = "" - - def guard_timeout(self): - global REQUEST_TIMEOUT - while self.state in [self.STATE_CONNECTED, self.STATE_INITIALIZED, self.STATE_PROCESSING]: - if time.time() - self.last_decoder_message > REQUEST_TIMEOUT: - logger.warning("%s: More than %d seconds from last decoder hypothesis update, cancelling" % (self.request_id, REQUEST_TIMEOUT)) - self.finish_request() - event = dict(status=common.STATUS_NO_SPEECH) - try: - self.send(json.dumps(event)) - except: - logger.warning("%s: Failed to send error event to master" % (self.request_id)) - self.close() - return - logger.debug("%s: Checking that decoder hasn't been silent for more than %d seconds" % (self.request_id, REQUEST_TIMEOUT)) - time.sleep(1) - - - def received_message(self, m): - logger.debug("%s: Got message from server of type %s" % (self.request_id, str(type(m)))) - if self.state == self.__class__.STATE_CONNECTED: - props = json.loads(str(m)) - content_type = props['content_type'] - self.request_id = props['id'] - self.num_segments = 0 - self.decoder_pipeline.init_request(self.request_id, content_type) - self.last_decoder_message = time.time() -# thread.start_new_thread(self.guard_timeout, ()) - logger.info("%s: Started timeout guard" % self.request_id) - logger.info("%s: Initialized request" % self.request_id) - self.state = self.STATE_INITIALIZED - elif m.data == "EOS": - if self.state != self.STATE_CANCELLING and self.state != self.STATE_EOS_RECEIVED and self.state != self.STATE_FINISHED: - self.decoder_pipeline.end_request() - self.state = self.STATE_EOS_RECEIVED - else: - logger.info("%s: Ignoring EOS, worker already in state %d" % (self.request_id, self.state)) - else: - if self.state != self.STATE_CANCELLING and self.state != self.STATE_EOS_RECEIVED and self.state != self.STATE_FINISHED: - if isinstance(m, ws4py.messaging.BinaryMessage): - self.decoder_pipeline.process_data(m.data) - self.state = self.STATE_PROCESSING - elif isinstance(m, ws4py.messaging.TextMessage): - logger.warning("%s: Got text message but don't know what to do with it" % (self.request_id)) - else: - logger.info("%s: Ignoring data, worker already in state %d" % (self.request_id, self.state)) - - - def finish_request(self): - if self.state == self.STATE_CONNECTED: - # connection closed when we are not doing anything - self.decoder_pipeline.finish_request() - self.state = self.STATE_FINISHED - return - if self.state == self.STATE_INITIALIZED: - # connection closed when request initialized but with no data sent - self.decoder_pipeline.finish_request() - self.state = self.STATE_FINISHED - return - if self.state != self.STATE_FINISHED: - logger.info("%s: Master disconnected before decoder reached EOS?" % self.request_id) - self.state = self.STATE_CANCELLING - self.decoder_pipeline.cancel() - counter = 0 - while self.state == self.STATE_CANCELLING: - self.state = self.STATE_FINISHED - counter += 1 - if counter > 30: - # lost hope that the decoder will ever finish, likely it has hung - # FIXME: this might introduce new bugs - logger.info("%s: Giving up waiting after %d tries" % (self.request_id, counter)) - self.state = self.STATE_FINISHED - else: - logger.info("%s: Waiting for EOS from decoder" % self.request_id) - time.sleep(1) - self.decoder_pipeline.finish_request() - logger.info("%s: Finished waiting for EOS" % self.request_id) - - - def closed(self, code, reason=None): - logger.debug("%s: Websocket closed() called" % self.request_id) - self.finish_request() - logger.debug("%s: Websocket closed() finished" % self.request_id) - - def _on_result(self, result, final): - if final: - return - self.last_decoder_message = time.time() - if self.last_partial_result == result: - return - self.last_partial_result = result - logger.info("%s: Postprocessing (final=%s) result.." % (self.request_id, final)) - if final: - logger.info("%s: Before postprocessing: %s" % (self.request_id, result)) - processed_transcript = self.post_process(result) - logger.info("%s: Postprocessing done." % self.request_id) - if final: - logger.info("%s: After postprocessing: %s" % (self.request_id, processed_transcript)) - - event = dict(status=common.STATUS_SUCCESS, - segment=self.num_segments, - result=dict(hypotheses=[dict(transcript=processed_transcript)], final=final)) - try: - self.send(json.dumps(event)) - except: - e = sys.exc_info()[1] - logger.warning("Failed to send event to master: %s" % e) - - def _on_full_result(self, full_result_json): - self.last_decoder_message = time.time() - full_result = json.loads(full_result_json) - if full_result.get("status", -1) == common.STATUS_SUCCESS: - #logger.info("%s: Postprocessing (final=%s) result.." % (self.request_id, final)) - logger.debug("%s: Before postprocessing: %s" % (self.request_id, full_result)) - full_result = self.post_process_full(full_result) - logger.info("%s: Postprocessing done." % self.request_id) - logger.debug("%s: After postprocessing: %s" % (self.request_id, full_result)) - - try: - self.send(json.dumps(full_result)) - except: - e = sys.exc_info()[1] - logger.warning("Failed to send event to master: %s" % e) - if full_result.get("result", {}).get("final", True): - self.num_segments += 1 - self.last_partial_result = "" - else: - logger.info("%s: Result status is %d, forwarding the result to the server anyway" % (self.request_id, full_result.get("status", -1))) - try: - self.send(json.dumps(full_result)) - except: - e = sys.exc_info()[1] - logger.warning("Failed to send event to master: %s" % e) - - - def _on_eos(self, data=None): - self.last_decoder_message = time.time() - self.state = self.STATE_FINISHED - #self.send_adaptation_state() - self.close() - - def _on_error(self, error): - self.state = self.STATE_FINISHED - event = dict(status=common.STATUS_NOT_ALLOWED, message=error) - try: - self.send(json.dumps(event)) - except: - e = sys.exc_info()[1] - logger.warning("Failed to send event to master: %s" % e) - self.close() - - def post_process(self, text): - if self.post_processor: - self.post_processor.stdin.write("%s\n" % text) - self.post_processor.stdin.flush() - text = self.post_processor.stdout.readline() - text = text.strip() - text = text.replace("\\n", "\n") - return text - else: - return text - - def post_process_full(self, full_result): - if self.full_post_processor: - self.full_post_processor.stdin.write("%s\n\n" % json.dumps(full_result)) - self.post_processor.stdin.flush() - lines = [] - while True: - l = self.full_post_processor.stdout.readline() - if not l: break # EOF - if l.strip() == "": - break - lines.append(l) - full_result = json.loads("".join(lines)) - - elif self.post_processor: - for hyp in full_result.get("result", {}).get("hypotheses", []): - hyp["original-transcript"] = hyp["transcript"] - hyp["transcript"] = self.post_process(hyp["transcript"]) - return full_result - - - - -def main(): - logging.basicConfig(level=logging.DEBUG, format="%(levelname)8s %(asctime)s %(message)s ") - logging.debug('Starting up worker') - parser = argparse.ArgumentParser(description='Worker for general STT decoder') - parser.add_argument('-u', '--uri', default="ws://localhost:8081/worker/ws/speech", dest="uri", help="Server<-->worker websocket URI") - parser.add_argument('-f', '--fork', default=1, dest="fork", type=int) - parser.add_argument('-c', '--conf', dest="conf", help="YAML file with decoder configuration") - - args = parser.parse_args() - - if args.fork > 1: - import tornado.process - - logging.info("Forking into %d processes" % args.fork) - tornado.process.fork_processes(args.fork) - - conf = {} - if args.conf: - with open(args.conf) as f: - conf = yaml.safe_load(f) - - with open("logger_config.yaml") as f: - logging.config.dictConfig(yaml.safe_load(f)) - - global SILENCE_TIMEOUT - SILENCE_TIMEOUT = conf.get("silence-timeout", 5) - - global CONNECT_TIMEOUT - CONNECT_TIMEOUT = conf.get("connect-timeout", 5) - - global REQUEST_TIMEOUT - REQUEST_TIMEOUT = conf.get("request-timeout", 5) - - global RESPONSE_TIMEOUT - RESPONSE_TIMEOUT = conf.get("response-timeout", 5) - - decoder_pipeline = DecoderPipeline(conf) - - post_processor = None - if "post-processor" in conf: - post_processor = Popen(conf["post-processor"], shell=True, stdin=PIPE, stdout=PIPE) - - full_post_processor = None - if "full-post-processor" in conf: - full_post_processor = Popen(conf["full-post-processor"], shell=True, stdin=PIPE, stdout=PIPE) - - while True: - ws = ServerWebsocket(args.uri, decoder_pipeline, post_processor, full_post_processor=full_post_processor) - try: - logger.info("Opening websocket connection to master server") - ws.connect() - ws.run_forever() - except Exception: - logger.error("Couldn't connect to server, waiting for %d seconds", CONNECT_TIMEOUT) - time.sleep(CONNECT_TIMEOUT) - # fixes a race condition - time.sleep(1) - -if __name__ == "__main__": - main() - diff --git a/lucida/speechrecognition/worker.py b/lucida/speechrecognition/worker.py new file mode 100644 index 000000000..9538e4798 --- /dev/null +++ b/lucida/speechrecognition/worker.py @@ -0,0 +1,72 @@ +import logging +import logging.handlers +import os +import click +import configuration +from gi.repository import GObject +import threading +import time + +from decoder_pipeline import DecoderPipeline +from worker_socket import SocketHandler +logger = logging.getLogger(__name__) + +SILENCE_TIMEOUT = 2 +INITIAL_SILENCE_TIMEOUT = 5 +RESPONSE_TIMEOUT = 30 +CONNECT_TIMEOUT = 5 +MAX_DURATION = 1800 + +DECODERS = [] +for decoder in next(os.walk(os.path.dirname(os.path.realpath(__file__)) + "/decoders/"))[1]: + if os.path.isfile(os.path.dirname(os.path.realpath(__file__)) + "/decoders/" + decoder + "/decoder") and os.access(os.path.dirname(os.path.realpath(__file__)) + "/decoders/" + decoder + "/decoder", os.X_OK): + DECODERS.append(decoder) + +@click.command() +@click.option("--decoder", prompt="Select speech to text decoder " + str(DECODERS), type=click.Choice(DECODERS), required=True, help="Speech to text decoder") +@click.option("--threads", prompt="Enter number of decoders to run in parallel [1-500]", default=1, type=click.IntRange(min=1, max=500), required=True, show_default=True, help="Number of decoders to run in parallel") +def main(decoder, threads): + conf = configuration.load() + + global SILENCE_TIMEOUT + SILENCE_TIMEOUT = conf['silence_timeout'] + global INITIAL_SILENCE_TIMEOUT + INITIAL_SILENCE_TIMEOUT = conf['initial_silence_timeout'] + global RESPONSE_TIMEOUT + RESPONSE_TIMEOUT = conf['response_timeout'] +# global CONNECT_TIMEOUT +# CONNECT_TIMEOUT = conf['connect_timeout'] +# global MAX_DURATION +# MAX_DURATION = conf['max_duration'] + + logger.setLevel(conf['worker_verbosity']) + os.environ['GST_DEBUG'] = conf['gstreamer_verbosity'] + + conf['decoder'] = decoder + + if threads > 1: + import tornado.process + logging.info("Forking into %d processes" % threads) + tornado.process.fork_processes(args.fork) + + pipeline = DecoderPipeline(conf) + + GObjectLoop = GObject.MainLoop() + GObjectThread = threading.Thread(target=GObjectLoop.run) + GObjectThread.daemon = True + GObjectThread.start() + + while True: + ws = SocketHandler(conf['master'], pipeline, conf) + try: + logger.info("Opening websocket connection to master server") + ws.connect() + ws.run_forever() + except Exception: + logger.error("Couldn't connect to server, waiting for %d seconds", CONNECT_TIMEOUT) + time.sleep(CONNECT_TIMEOUT - 1) + time.sleep(1) + +if __name__ == "__main__": + main() + diff --git a/lucida/speechrecognition/worker_socket.py b/lucida/speechrecognition/worker_socket.py new file mode 100644 index 000000000..268121e65 --- /dev/null +++ b/lucida/speechrecognition/worker_socket.py @@ -0,0 +1,157 @@ +import os, sys, time + +import logging +import logging.config +import logging.handlers +import thread +import json + +from ws4py.client.threadedclient import WebSocketClient +import ws4py.messaging + +import common + +logger = logging.getLogger(__name__) + +class SocketHandler(WebSocketClient): + STATE_CREATED = 0 + STATE_CONNECTED = 1 + STATE_INITIALIZED = 2 + STATE_PROCESSING = 3 + STATE_EOS_RECEIVED = 7 + STATE_CANCELLING = 8 + STATE_FINISHED = 100 + + def __init__(self, master, pipeline, conf): + WebSocketClient.__init__(self, url=master, heartbeat_freq=10) + + self.pipeline = pipeline + + self.pipeline.set_interim_result_handler(self._on_interim_result) + self.pipeline.set_final_result_handler(self._on_final_result) + self.pipeline.set_error_handler(self._on_error) + self.pipeline.set_eos_handler(self._on_eos) + + self.request_id = "" + self.silence_timeout = conf['silence_timeout'] + self.initial_silence_timeout = conf['initial_silence_timeout'] + self.state = self.STATE_CREATED + + def opened(self): + logger.info("Opened websocket connection to server") + self.state = self.STATE_CONNECTED + + def master_timeout(self): + while self.state in [self.STATE_INITIALIZED, self.STATE_PROCESSING]: + if time.time() - self.last_master_message > self.silence_timeout: + logger.warning("%s: More than %d seconds since last message from master, pushing EOS to pipeline" % (self.request_id, self.silence_timeout)) + self.pipeline.end_request() + self.state = self.STATE_EOS_RECEIVED + event = dict(status=common.STATUS_MASTER_TIMED_OUT) + try: + self.send(json.dumps(event)) + except: + logger.warning("%s: Failed to send error event to master" % (self.request_id)) + return + logger.debug("%s: Checking that master hasn't been silent for more than %d seconds" % (self.request_id, self.silence_timeout)) + time.sleep(1) + + def received_message(self, message): + logger.debug("%s: Got message from server of type %s" % (self.request_id, str(type(message)))) + self.last_master_message = time.time() + + if self.state == self.STATE_CONNECTED: + if isinstance(message, ws4py.messaging.TextMessage): + props = json.loads(str(message)) + context = props['context'] + caps_str = props['caps'] + self.request_id = props['id'] + self.pipeline.init_request(self.request_id, caps_str, context) + self.state = self.STATE_INITIALIZED + self.last_master_message = time.time() + self.initial_silence_timeout - self.silence_timeout + thread.start_new_thread(self.master_timeout, ()) + logger.info("%s: Started master timeout thread" % self.request_id) + else: + logger.info("Non-text message received while waiting for initialisation!!! Resetting...") + self.finish_request() + elif message.data == "EOS": + if self.state != self.STATE_CANCELLING and self.state != self.STATE_EOS_RECEIVED and self.state != self.STATE_FINISHED: + self.decoder_pipeline.end_request() + self.state = self.STATE_EOS_RECEIVED + else: + logger.info("%s: Ignoring EOS, worker already in state %d" % (self.request_id, self.state)) + else: + if self.state != self.STATE_CANCELLING and self.state != self.STATE_EOS_RECEIVED and self.state != self.STATE_FINISHED: + if isinstance(message, ws4py.messaging.BinaryMessage): + self.decoder_pipeline.process_data(message.data) + self.state = self.STATE_PROCESSING + else: + logger.info("Non-binary message received while waiting for audio!!! Ignoring message...") + self.finish_request() + else: + logger.info("%s: Ignoring data, worker already in state %d" % (self.request_id, self.state)) + + + def finish_request(self): + if self.state == self.STATE_CONNECTED: + self.pipeline.finish_request() + self.state = self.STATE_FINISHED + return + if self.state == self.STATE_INITIALIZED: + self.pipeline.finish_request() + self.state = self.STATE_FINISHED + return + if self.state != self.STATE_FINISHED: + logger.info("%s: Master disconnected before decoder reached EOS?" % self.request_id) + self.state = self.STATE_CANCELLING + self.pipeline.cancel() + counter = 0 + while self.state == self.STATE_CANCELLING: + counter += 1 + if counter > 30: + logger.info("%s: Giving up waiting after %d tries" % (self.request_id, counter)) + self.state = self.STATE_FINISHED + else: + logger.info("%s: Waiting for EOS from decoder" % self.request_id) + time.sleep(1) + logger.info("%s: Finished waiting for EOS" % self.request_id) + + + def closed(self, code, reason=None): + logger.debug("%s: Closed websocket connection to server. Cleaning up..." % self.request_id) + self.finish_request() + logger.debug("%s: Done cleaning up after websocket connection closed." % self.request_id) + + def _on_interim_result(self, result, duration): + logger.debug("%s: Received interim result." % (self.request_id)) + + event = dict(id=self.request_id, status=common.STATUS_SUCCESS, result=dict(hypotheses=[dict(transcript=result)], final=False), total_length=duration) + try: + self.send(json.dumps(event)) + except: + e = sys.exc_info()[1] + logger.warning("Failed to send event to master: %s" % e) + + def _on_final_result(self, result, duration, context): + logger.debug("%s: Received final result" % (self.request_id)) + + event = dict(id=self.request_id, status=common.STATUS_SUCCESS, result=dict(hypotheses=[dict(transcript=result, context=context)], final=True), total_length=duration) + try: + self.send(json.dumps(event)) + except: + e = sys.exc_info()[1] + logger.warning("Failed to send event to master: %s" % e) + + def _on_eos(self, data=None): + self.state = self.STATE_FINISHED + self.close() + + def _on_error(self, error): + self.state = self.STATE_FINISHED + event = dict(status=common.STATUS_GENERIC_ERROR, message=error) + try: + self.send(json.dumps(event)) + except: + e = sys.exc_info()[1] + logger.warning("Failed to send event to master: %s" % e) + self.close() From 7a52268d0a755f7e4dd50423eeec876b69e63ca1 Mon Sep 17 00:00:00 2001 From: Kamal Galrani Date: Sun, 30 Jul 2017 16:10:58 +0530 Subject: [PATCH 08/11] wip --- lucida/botframework-interface/interface.js | 62 ++- lucida/botframework-interface/package.json | 3 +- .../botframework-interface/start_interface.sh | 7 +- lucida/commandcenter/controllers/Database.py | 7 +- lucida/commandcenter/controllers/WebServer.py | 121 +++-- .../controllers/WebServer.py.bak | 305 ++++++++++++ .../controllers/WebServer.py.forward | 399 +++++++++++++++ lucida/commandcenter/dump/Speech.py | 35 ++ lucida/commandcenter/dump/WebSocket.bak.py | 355 ++++++++++++++ lucida/commandcenter/dump/__init__.py | 7 + lucida/commandcenter/dump/app.py | 64 +++ lucida/commandcenter/dump/dictate.js | 416 ++++++++++++++++ lucida/commandcenter/dump/infer.html | 144 ++++++ lucida/commandcenter/dump/mob.js | 256 ++++++++++ lucida/commandcenter/dump/socketio.html | 37 ++ lucida/commandcenter/dump/stream_audio.js | 96 ++++ lucida/commandcenter/templates/infer.html | 2 +- lucida/speechrecognition/common.py | 13 - lucida/speechrecognition/decoders/README.md | 3 + .../decoders/templates/python/conf | 5 + .../decoders/templates/python/decoder | 162 +++++++ .../speechrecognition/decoders/wit/Makefile | 6 - lucida/speechrecognition/decoders/wit/conf | 11 + .../speechrecognition/decoders/wit/config.sh | 12 + .../speechrecognition/decoders/wit/configure | 3 - lucida/speechrecognition/decoders/wit/decoder | Bin 6515 -> 8560 bytes .../speechrecognition/decoders/wit/decoder.py | 157 ------ lucida/speechrecognition/decoders/wit/dump | 19 + .../speechrecognition/decoders/wit/setup.sh | 107 ++++ .../{plugin/ChangeLog => include/__init__.py} | 0 lucida/speechrecognition/include/common.py | 12 + .../speechrecognition/include/common.py.bak | 26 + .../speechrecognition/plugin/src/Makefile.am | 14 - .../{ => src}/configuration.py | 9 +- .../{ => src}/decoder_pipeline.py | 67 ++- lucida/speechrecognition/src/get_free_port | 7 + .../{plugin => src/gstplugin}/.gitignore | 0 .../{plugin => src/gstplugin}/AUTHORS | 0 .../{plugin => src/gstplugin}/COPYING | 0 .../speechrecognition/src/gstplugin/ChangeLog | 0 .../{plugin => src/gstplugin}/Makefile | 20 +- .../{plugin => src/gstplugin}/Makefile.am | 0 .../{plugin => src/gstplugin}/NEWS | 0 .../{plugin => src/gstplugin}/README | 0 .../{plugin => src/gstplugin}/autogen.sh | 0 .../{plugin => src/gstplugin}/compile | 0 .../{plugin => src/gstplugin}/configure.ac | 0 .../{plugin => src/gstplugin}/list | 0 ...ibgstasrplugin_la-a_s_r_thrift_service.Plo | 451 +++++++++++++++++ ...gstasrplugin_la-asrthriftservice_types.Plo | 455 ++++++++++++++++++ .../.deps/libgstasrplugin_la-gstasrplugin.Plo | 32 +- .../gstplugin}/src/.libs/libgstasrplugin.exp | 0 .../gstplugin}/src/.libs/libgstasrplugin.ver | 0 .../{plugin => src/gstplugin}/src/Makefile | 46 +- .../src/gstplugin/src/Makefile.am | 14 + .../gstplugin}/src/gstasrplugin.c | 220 ++++----- .../gstplugin}/src/gstasrplugin.h | 27 +- lucida/speechrecognition/{ => src}/worker.py | 30 +- .../{ => src}/worker_socket.py | 38 +- .../thrift/asrthriftservice.thrift | 8 + lucida/speechrecognition/thrift/gen.sh | 4 + 61 files changed, 3816 insertions(+), 478 deletions(-) create mode 100644 lucida/commandcenter/controllers/WebServer.py.bak create mode 100644 lucida/commandcenter/controllers/WebServer.py.forward create mode 100644 lucida/commandcenter/dump/Speech.py create mode 100644 lucida/commandcenter/dump/WebSocket.bak.py create mode 100644 lucida/commandcenter/dump/__init__.py create mode 100644 lucida/commandcenter/dump/app.py create mode 100644 lucida/commandcenter/dump/dictate.js create mode 100644 lucida/commandcenter/dump/infer.html create mode 100644 lucida/commandcenter/dump/mob.js create mode 100644 lucida/commandcenter/dump/socketio.html create mode 100644 lucida/commandcenter/dump/stream_audio.js delete mode 100644 lucida/speechrecognition/common.py create mode 100644 lucida/speechrecognition/decoders/README.md create mode 100755 lucida/speechrecognition/decoders/templates/python/conf create mode 100755 lucida/speechrecognition/decoders/templates/python/decoder delete mode 100644 lucida/speechrecognition/decoders/wit/Makefile create mode 100755 lucida/speechrecognition/decoders/wit/conf create mode 100644 lucida/speechrecognition/decoders/wit/config.sh delete mode 100755 lucida/speechrecognition/decoders/wit/configure delete mode 100644 lucida/speechrecognition/decoders/wit/decoder.py create mode 100644 lucida/speechrecognition/decoders/wit/dump create mode 100755 lucida/speechrecognition/decoders/wit/setup.sh rename lucida/speechrecognition/{plugin/ChangeLog => include/__init__.py} (100%) create mode 100644 lucida/speechrecognition/include/common.py create mode 100644 lucida/speechrecognition/include/common.py.bak delete mode 100644 lucida/speechrecognition/plugin/src/Makefile.am rename lucida/speechrecognition/{ => src}/configuration.py (98%) rename lucida/speechrecognition/{ => src}/decoder_pipeline.py (69%) create mode 100755 lucida/speechrecognition/src/get_free_port rename lucida/speechrecognition/{plugin => src/gstplugin}/.gitignore (100%) rename lucida/speechrecognition/{plugin => src/gstplugin}/AUTHORS (100%) rename lucida/speechrecognition/{plugin => src/gstplugin}/COPYING (100%) create mode 100644 lucida/speechrecognition/src/gstplugin/ChangeLog rename lucida/speechrecognition/{plugin => src/gstplugin}/Makefile (98%) rename lucida/speechrecognition/{plugin => src/gstplugin}/Makefile.am (100%) rename lucida/speechrecognition/{plugin => src/gstplugin}/NEWS (100%) rename lucida/speechrecognition/{plugin => src/gstplugin}/README (100%) rename lucida/speechrecognition/{plugin => src/gstplugin}/autogen.sh (100%) rename lucida/speechrecognition/{plugin => src/gstplugin}/compile (100%) rename lucida/speechrecognition/{plugin => src/gstplugin}/configure.ac (100%) rename lucida/speechrecognition/{plugin => src/gstplugin}/list (100%) create mode 100644 lucida/speechrecognition/src/gstplugin/src/.deps/libgstasrplugin_la-a_s_r_thrift_service.Plo create mode 100644 lucida/speechrecognition/src/gstplugin/src/.deps/libgstasrplugin_la-asrthriftservice_types.Plo rename lucida/speechrecognition/{plugin => src/gstplugin}/src/.deps/libgstasrplugin_la-gstasrplugin.Plo (94%) rename lucida/speechrecognition/{plugin => src/gstplugin}/src/.libs/libgstasrplugin.exp (100%) rename lucida/speechrecognition/{plugin => src/gstplugin}/src/.libs/libgstasrplugin.ver (100%) rename lucida/speechrecognition/{plugin => src/gstplugin}/src/Makefile (85%) create mode 100644 lucida/speechrecognition/src/gstplugin/src/Makefile.am rename lucida/speechrecognition/{plugin => src/gstplugin}/src/gstasrplugin.c (77%) rename lucida/speechrecognition/{plugin => src/gstplugin}/src/gstasrplugin.h (88%) rename lucida/speechrecognition/{ => src}/worker.py (73%) rename lucida/speechrecognition/{ => src}/worker_socket.py (81%) create mode 100644 lucida/speechrecognition/thrift/asrthriftservice.thrift create mode 100644 lucida/speechrecognition/thrift/gen.sh diff --git a/lucida/botframework-interface/interface.js b/lucida/botframework-interface/interface.js index f93ed2835..992f22852 100644 --- a/lucida/botframework-interface/interface.js +++ b/lucida/botframework-interface/interface.js @@ -8,11 +8,16 @@ Description : This file handles dialogs from bot framework, forwards messages var restify = require('restify') var server = restify.createServer() var builder = require('botbuilder') +var calling = require('botbuilder-calling') var request = require('request') var credentials = require('./credentials') -var url = require("url") +var url = require('url') var bfw_port -var cc_host +var cc_api_host +var cc_ws_host +var WebSocket = require('ws') + +var util = require('util') //========================================================= // Bot Setup @@ -37,12 +42,16 @@ function check_bfw_port(str_port) { function check_cc_host(host) { match = host.match(/^((\d+\.\d+\.\d+\.\d+)|localhost)(:\d+)?(.*)?$/) if ( match != null ) { - cc_host = "http://" + host.replace(/\/$/, "") - console.log("[INFO] Remote command center host is set to " + cc_host) + cc_api_host = "http://" + host.replace(/\/$/, "") + '/api' + cc_ws_host = "ws://" + host.replace(/\/$/, "") + '/ws' + console.log("[INFO] Remote command center API host is set to " + cc_api_host) + console.log("[INFO] Remote command center WS host is set to " + cc_ws_host) return true } else if ( url.parse(host)['host'] != null ) { - cc_host = host.replace(/\/$/, "") - console.log("[INFO] Remote command center host is set to " + cc_host) + cc_api_host = host.replace(/\/$/, "") + '/api' + cc_ws_host = cc_api_host.replace(/^http/, "ws") + '/ws' + console.log("[INFO] Remote command center API host is set to " + cc_api_host) + console.log("[INFO] Remote command center WS host is set to " + cc_ws_host) return true } else { return false @@ -78,28 +87,39 @@ function check_args() { } check_args() +// Create web socket +var ws = new WebSocket(cc_ws_host + '/status') + +ws.on('message', function incoming(data) { + console.log("WS RECVD: " + data); +}); + // Create chat bot -var connector = new builder.ChatConnector(credentials.credentials) -var bot = new builder.UniversalBot(connector) -server.post('/api/messages', connector.listen()) +var chat_connector = new builder.ChatConnector(credentials.chat_credentials) +var chat_bot = new builder.UniversalBot(chat_connector) +server.post('/api/messages', chat_connector.listen()) +var call_connector = new calling.CallConnector(credentials.call_credentials) +var call_bot = new calling.UniversalCallBot(call_connector); +server.post('/api/calls', call_connector.listen()); //========================================================= // Bots Dialogs //========================================================= -var addresses = {} +var chat_addresses = {} -bot.dialog('/', [ +chat_bot.dialog('/', [ function (session) { + console.log(util.inspect(session.message.address)) var address = session.message.address - addresses[address.channelId] = {channelId: address.channelId, bot: {id: address.bot.id, name: address.bot.name}, serviceUrl: address.serviceUrl, useAuth: address.useAuth} + chat_addresses[address.channelId] = {channelId: address.channelId, bot: {id: address.bot.id, name: address.bot.name}, serviceUrl: address.serviceUrl, useAuth: address.useAuth} request.post({ headers: {'content-type' : 'application/x-www-form-urlencoded'}, form: { interface: session.message.address.channelId, username: session.message.address.user.id, text_input: session.message.text }, - url: cc_host + '/api/infer', + url: cc_api_host + '/infer', form: { interface: session.message.address.channelId, username: session.message.address.user.id, speech_input: session.message.text } }, function(error, response, body){ - address = addresses[session.message.address.channelId] + address = chat_addresses[session.message.address.channelId] address['user'] = { id: session.message.address.user.id } if (error) { text = "Error occured '" + error.code + "'!!! Is command center running?" @@ -112,7 +132,7 @@ bot.dialog('/', [ if ( result ) { request.post({ headers: {'content-type' : 'application/x-www-form-urlencoded'}, - url: cc_host + '/api/add_interface', + url: cc_api_host + '/add_interface', form: { interface: session.message.address.channelId, token: result[1], username: session.message.address.user.id } }, function(error, response, body){ if (error) { @@ -127,7 +147,7 @@ bot.dialog('/', [ text = response.statusCode + " " + response.statusMessage + " received. Go through the logs and figure. Otherwise create an issue on github with logs attached." } var reply = new builder.Message().address(address).text(text) - bot.send(reply) + chat_bot.send(reply) }) return } else { @@ -139,7 +159,15 @@ bot.dialog('/', [ text = response.statusCode + " " + response.statusMessage + " received. Go through the logs and figure. Otherwise create an issue on github with logs attached." } var reply = new builder.Message().address(address).text(text) - bot.send(reply) + chat_bot.send(reply) }) } ]) + + +call_bot.dialog('/', [ + function (session) { + session.send('Hey there! How can I help you?'); + console.log(util.inspect(session.message)) + } +]) diff --git a/lucida/botframework-interface/package.json b/lucida/botframework-interface/package.json index a0c433d9c..fec9cdbe3 100644 --- a/lucida/botframework-interface/package.json +++ b/lucida/botframework-interface/package.json @@ -11,6 +11,7 @@ "botbuilder-calling": "^3.0.1", "request": "^2.81.0", "restify": "^4.3.0", - "url": "^0.11.0" + "url": "^0.11.0", + "ws": "^3.0.0" } } diff --git a/lucida/botframework-interface/start_interface.sh b/lucida/botframework-interface/start_interface.sh index 026863752..851c418ce 100644 --- a/lucida/botframework-interface/start_interface.sh +++ b/lucida/botframework-interface/start_interface.sh @@ -358,7 +358,12 @@ rm -f phantom.out cat << EOF > credentials.js // DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN -exports.credentials = { +exports.chat_credentials = { + appId: '$BFW_APPID', + appPassword: '$BFW_APPPWD' +} +exports.call_credentials = { + callbackUrl: '$BFW_HOST/api/calls', appId: '$BFW_APPID', appPassword: '$BFW_APPPWD' } diff --git a/lucida/commandcenter/controllers/Database.py b/lucida/commandcenter/controllers/Database.py index 8c81af8fd..993982561 100644 --- a/lucida/commandcenter/controllers/Database.py +++ b/lucida/commandcenter/controllers/Database.py @@ -85,8 +85,11 @@ def username_exists(self, username): #Returns true if the username already exists. def get_username(self, interface, interface_uid): - interface += "_interface" - row = self.users.find_one({interface: interface_uid}); + if interface and interface != "web": + interface += "_interface" + row = self.users.find_one({interface: interface_uid}) + else: + row = self.users.find_one({'username': interface_uid}) if not row is None: return row['username'] return None diff --git a/lucida/commandcenter/controllers/WebServer.py b/lucida/commandcenter/controllers/WebServer.py index 37983c7f1..f60587a40 100644 --- a/lucida/commandcenter/controllers/WebServer.py +++ b/lucida/commandcenter/controllers/WebServer.py @@ -41,7 +41,8 @@ STATUS_BAD_GRAMMAR = 7 STATUS_LANGUAGE_NOT_SUPPORTED = 8 STATUS_NOT_AVAILABLE = 9 - +STATUS_NOT_AUTHENTICATED = 401 +STATUS_CONNECTED = 100 class Application(tornado.web.Application): def __init__(self, flaskApp): @@ -54,9 +55,9 @@ def __init__(self, flaskApp): flaskWebHandler = tornado.wsgi.WSGIContainer(flaskApp) handlers = [ - (r"/client/ws/speech", DecoderSocketHandler), - (r"/client/ws/status", StatusSocketHandler), - (r"/client/dynamic/recognize", HttpChunkedRecognizeHandler), + (r"/ws/speech", DecoderSocketHandler), + (r"/ws/status", StatusSocketHandler), + (r"/api/speech", DecoderAPIHandler), (r"/worker/ws/speech", WorkerSocketHandler), (r"/client/static/(.*)", tornado.web.StaticFileHandler, {'path': settings["static_path"]}), (r".*", tornado.web.FallbackHandler, dict(fallback=flaskWebHandler)) @@ -101,42 +102,46 @@ def content_type_to_caps(content_type): @tornado.web.stream_request_body -class HttpChunkedRecognizeHandler(tornado.web.RequestHandler): +class DecoderAPIHandler(tornado.web.RequestHandler): """ - Provides a HTTP POST/PUT interface supporting chunked transfer requests, similar to that provided by - http://github.com/alumae/ruby-pocketsphinx-server. + Provides a HTTP POST/PUT interface supporting chunked transfer requests """ def prepare(self): self.id = str(uuid.uuid4()) - self.final_hyp = "" + self.final_result = "" self.final_result_queue = Queue() - self.user_id = self.request.headers.get("device-id", "none") - self.content_id = self.request.headers.get("content-id", "none") - logging.info("%s: OPEN: user='%s', content='%s'" % (self.id, self.user_id, self.content_id)) + user = self.request.headers.get("user", None) + interface = self.request.headers.get("interface", None) + token = self.request.headers.get("token", None) + user = database.get_username(interface, user) + if user == None: + self.set_status(401) + self.finish("Not Authorized") + return + logging.info("API::SPEECH %s: Received request from user '%s' over interface '%s'" % (self.id, user, interface)) self.worker = None self.error_status = 0 self.error_message = None try: self.worker = self.application.available_workers.pop() self.application.send_status_update() - logging.info("%s: Using worker %s" % (self.id, self.__str__())) + logging.info("API::SPEECH %s: Using worker %s" % (self.id, self.__str__())) self.worker.set_client_socket(self) - - content_type = self.request.headers.get("Content-Type", None) - if content_type: - content_type = content_type_to_caps(content_type) - logging.info("%s: Using content type: %s" % (self.id, content_type)) - - self.worker.write_message(json.dumps(dict(id=self.id, content_type=content_type, user_id=self.user_id, content_id=self.content_id))) - except KeyError: - logging.warn("%s: No worker available for client request" % self.id) + context = self.request.headers.get("context", None) + content_type = self.request.headers.get("Content-Type", None) + if content_type: + content_type = content_type_to_caps(content_type) + logging.info("API::SPEECH %s: Using content type: %s" % (self.id, content_type)) + self.worker.write_message(json.dumps(dict(id=self.id, caps=content_type, context=context, user=user, isCall=False))) + except: + logging.warn("API::SPEECH %s: No worker available for client request" % self.id) self.set_status(503) self.finish("No workers available") def data_received(self, chunk): assert self.worker is not None - logging.debug("%s: Forwarding client message of length %d to worker" % (self.id, len(chunk))) + logging.info("API::SPEECH %s: Forwarding client message of length %d to worker" % (self.id, len(chunk))) self.worker.write_message(chunk, binary=True) def post(self, *args, **kwargs): @@ -146,32 +151,28 @@ def put(self, *args, **kwargs): self.end_request(args, kwargs) @run_async - def get_final_hyp(self, callback=None): - logging.info("%s: Waiting for final result..." % self.id) + def get_final_result(self, callback=None): + logging.info("API::SPEECH %s: Waiting for final result..." % self.id) callback(self.final_result_queue.get(block=True)) @tornado.web.asynchronous @tornado.gen.coroutine def end_request(self, *args, **kwargs): - logging.info("%s: Handling the end of chunked recognize request" % self.id) + logging.info("API::SPEECH %s: Handling the end of request" % self.id) assert self.worker is not None self.worker.write_message("EOS", binary=True) - logging.info("%s: yielding..." % self.id) - hyp = yield tornado.gen.Task(self.get_final_hyp) + result = yield tornado.gen.Task(self.get_final_result) if self.error_status == 0: - logging.info("%s: Final hyp: %s" % (self.id, hyp)) - response = {"status" : 0, "id": self.id, "hypotheses": [{"utterance" : hyp}]} - self.write(response) + logging.info("%s: Final result: %s" % (self.id, result)) + self.write(result) else: logging.info("%s: Error (status=%d) processing HTTP request: %s" % (self.id, self.error_status, self.error_message)) response = {"status" : self.error_status, "id": self.id, "message": self.error_message} self.write(response) - self.application.num_requests_processed += 1 - self.application.send_status_update() self.worker.set_client_socket(None) self.worker.close() self.finish() - logging.info("Everything done") + logging.info("API::SPEECH Everything done") def send_event(self, event): event_str = str(event) @@ -181,9 +182,7 @@ def send_event(self, event): if event["status"] == 0 and ("result" in event): try: if len(event["result"]["hypotheses"]) > 0 and event["result"]["final"]: - if len(self.final_hyp) > 0: - self.final_hyp += " " - self.final_hyp += event["result"]["hypotheses"][0]["transcript"] + self.final_result = str(event) except: e = sys.exc_info()[0] logging.warn("Failed to extract hypothesis from recognition result:" + e) @@ -192,24 +191,28 @@ def send_event(self, event): self.error_message = event.get("message", "") def close(self): - logging.info("%s: Receiving 'close' from worker" % (self.id)) - self.final_result_queue.put(self.final_hyp) - + logging.info("API::SPEECH %s: Receiving close from worker" % (self.id)) + self.final_result_queue.put(self.final_result) + self.application.send_status_update() class StatusSocketHandler(tornado.websocket.WebSocketHandler): - # needed for Tornado 4.0 - def check_origin(self, origin): - return True + # needed for Tornado 4.0 + def check_origin(self, origin): + return True - def open(self): - logging.info("New status listener") - self.application.status_listeners.add(self) - self.application.send_status_update_single(self) + def open(self): + logging.debug("Opened a new control channel") + self.application.status_listeners.add(self) + self.application.send_status_update_single(self) - def on_close(self): - logging.info("Status listener left") - self.application.status_listeners.remove(self) + def on_message(self, message): + assert self.client_socket is not None + event = json.loads(message) + self.client_socket.send_event(event) + def on_close(self): + logging.info("Status listener left") + self.application.status_listeners.remove(self) class WorkerSocketHandler(tornado.websocket.WebSocketHandler): def __init__(self, application, request, **kwargs): @@ -237,6 +240,8 @@ def on_message(self, message): assert self.client_socket is not None event = json.loads(message) self.client_socket.send_event(event) + if 'next_id' in event: + self.client_socket.set_id(event['id']) def set_client_socket(self, client_socket): self.client_socket = client_socket @@ -247,6 +252,9 @@ class DecoderSocketHandler(tornado.websocket.WebSocketHandler): def check_origin(self, origin): return True + def set_id(self, id): + self.id = id + def send_event(self, event): event["id"] = self.id event_str = str(event) @@ -259,8 +267,15 @@ def open(self): self.id = str(uuid.uuid4()) logging.info("%s: OPEN" % (self.id)) logging.info("%s: Request arguments: %s" % (self.id, " ".join(["%s=\"%s\"" % (a, self.get_argument(a)) for a in self.request.arguments]))) - self.user_id = self.get_argument("user-id", "none", True) - self.content_id = self.get_argument("content-id", "none", True) + user = self.get_argument("user", None, True) + interface = self.get_argument("interface", None, True) + user = database.get_username(interface, user) + if user == None: + logging.warn("Not authorised") + event = dict(status=STATUS_NOT_AVAILABLE, message="User not authorised!!!") + self.send_event(event) + self.close() + return self.worker = None try: self.worker = self.application.available_workers.pop() @@ -268,11 +283,13 @@ def open(self): logging.info("%s: Using worker %s" % (self.id, self.__str__())) self.worker.set_client_socket(self) + context = self.get_argument("context", None, True) + self.isCall = self.get_argument("isCall", False, True) content_type = self.get_argument("content-type", None, True) if content_type: logging.info("%s: Using content type: %s" % (self.id, content_type)) - self.worker.write_message(json.dumps(dict(id=self.id, content_type=content_type, user_id=self.user_id, content_id=self.content_id))) + self.worker.write_message(json.dumps(dict(id=self.id, caps=content_type, context=context, user=user, isCall=self.isCall))) except KeyError: logging.warn("%s: No worker available for client request" % self.id) event = dict(status=STATUS_NOT_AVAILABLE, message="No decoder available, try again later") diff --git a/lucida/commandcenter/controllers/WebServer.py.bak b/lucida/commandcenter/controllers/WebServer.py.bak new file mode 100644 index 000000000..c41ff52d9 --- /dev/null +++ b/lucida/commandcenter/controllers/WebServer.py.bak @@ -0,0 +1,305 @@ +#!/usr/bin/env python +# +# Copyright 2013 Tanel Alumae +# Copyright 2017 Kamal Galrani + +""" +Reads speech data via websocket requests, sends it to Redis, waits for results from Redis and +forwards to client via websocket +""" +import sys +import logging +import json +import codecs +import os.path +import uuid +import time +import threading +import functools +from Queue import Queue + +import tornado.ioloop +import tornado.options +import tornado.web +import tornado.websocket +import tornado.gen +import tornado.concurrent +import tornado.wsgi + +from Parser import cmd_port + +from tornado.options import define +define("port", default=cmd_port, help="run on the given port", type=int) + +STATUS_EOS = -1 +STATUS_SUCCESS = 0 +STATUS_NO_SPEECH = 1 +STATUS_ABORTED = 2 +STATUS_AUDIO_CAPTURE = 3 +STATUS_NETWORK = 4 +STATUS_NOT_ALLOWED = 5 +STATUS_SERVICE_NOT_ALLOWED = 6 +STATUS_BAD_GRAMMAR = 7 +STATUS_LANGUAGE_NOT_SUPPORTED = 8 +STATUS_NOT_AVAILABLE = 9 + + +class Application(tornado.web.Application): + def __init__(self, flaskApp): + settings = dict( + cookie_secret="43oETzKXQAGaYdkL5gEmGeJJFuYh7EQnp2XdTP1o/Vo=", + static_path=os.path.join(os.path.dirname(os.path.dirname(__file__)), "static"), + xsrf_cookies=False, + autoescape=None + ) + + flaskWebHandler = tornado.wsgi.WSGIContainer(flaskApp) + handlers = [ + (r"/ws/speech", DecoderSocketHandler), + (r"/ws/control", ControlSocketHandler), + (r"/api/speech", DecoderAPIHandler), + (r"/worker/ws/speech", WorkerSocketHandler), + (r"/static/(.*)", tornado.web.StaticFileHandler, {'path': settings["static_path"]}), + (r".*", tornado.web.FallbackHandler, dict(fallback=flaskWebHandler)) + ] + tornado.web.Application.__init__(self, handlers, **settings) + self.available_decoders = set() + self.connected_clients = set() + + def send_status_update_single(self, ws): + status = dict(speech_decoder_available=len(self.available_workers) > 0) # TODO: Add stuff + ws.write_message(json.dumps(status)) + + def send_status_update(self): + for ws in self.status_listeners: + self.send_status_update_single(ws) + +def run_async(func): + @functools.wraps(func) + def async_func(*args, **kwargs): + func_hl = threading.Thread(target=func, args=args, kwargs=kwargs) + func_hl.daemon = True + func_hl.start() + return func_hl + return async_func + + +def content_type_to_caps(content_type): + """ + Converts MIME-style raw audio content type specifier to GStreamer CAPS string + """ + default_attributes= {"rate": 16000, "format" : "S16LE", "channels" : 1, "layout" : "interleaved"} + media_type, _, attr_string = content_type.replace(";", ",").partition(",") + if media_type in ["audio/x-raw", "audio/x-raw-int"]: + media_type = "audio/x-raw" + attributes = default_attributes + for (key,_,value) in [p.partition("=") for p in attr_string.split(",")]: + attributes[key.strip()] = value.strip() + return "%s, %s" % (media_type, ", ".join(["%s=%s" % (key, value) for (key,value) in attributes.iteritems()])) + else: + return content_type + + +@tornado.web.stream_request_body +class DecoderAPIHandler(tornado.web.RequestHandler): + """ + Provides a HTTP POST/PUT interface supporting chunked transfer requests, similar to that provided by + http://github.com/alumae/ruby-pocketsphinx-server. + """ + + def prepare(self): + self.id = str(uuid.uuid4()) + self.final_result = "" + self.final_result_queue = Queue() + user = self.request.headers.get("user", None) + interface = self.request.headers.get("interface", "web") + user = database.get_username(interface, user) + if user == None: + self.set_status(403) + self.finish("Not Authorized") + logging.debug("%s: /api/speech: Received request from user '%s' over interface '%s'" % (self.id, user, interface)) + self.worker = None + self.error_status = 0 + self.error_message = None + try: + self.worker = self.application.available_workers.pop() + self.application.send_status_update() + logging.debug("%s: /api/speech: Using worker %s" % (self.id, self.__str__())) + self.worker.set_client_socket(self) + context = self.request.headers.get("context", None) + content_type = self.request.headers.get("Content-Type", None) + if content_type: + content_type = content_type_to_caps(content_type) + logging.debug("%s: /api/speech: Using content type: %s" % (self.id, content_type)) + self.worker.write_message(json.dumps(dict(id=self.id, caps=content_type, context=context, user=user))) + except KeyError: + logging.warn("%s: /api/speech: No worker available for client request" % self.id) + self.set_status(503) + self.finish("No workers available") + + def data_received(self, chunk): + assert self.worker is not None + logging.debug("%s: /api/speech: Forwarding client message of length %d to worker" % (self.id, len(chunk))) + self.worker.write_message(chunk, binary=True) + + def post(self, *args, **kwargs): + self.end_request(args, kwargs) + + def put(self, *args, **kwargs): + self.end_request(args, kwargs) + + @run_async + def get_final_result(self, callback=None): + logging.debug("%s: /api/speech: Waiting for final result..." % self.id) + callback(self.final_result_queue.get(block=True)) + + @tornado.web.asynchronous + @tornado.gen.coroutine + def end_request(self, *args, **kwargs): + logging.debug("%s: /api/speech: Handling the end of request" % self.id) + assert self.worker is not None + self.worker.write_message("EOS", binary=True) + result = yield tornado.gen.Task(self.get_final_result) + result = json.loads(result) + if self.error_status == 0: + logging.debug("%s: /api/speech: Received final result") + response = {"status" : 0, "id": self.id, "hypotheses": [{"utterance" : hyp}]} ###### + self.write(response) + else: + logging.error("%s: /api/speech: ERROR: (status=%d) processing HTTP request: %s" % (self.id, self.error_status, self.error_message)) + response = {"status" : self.error_status, "id": self.id, "message": self.error_message} + self.write(response) + self.application.send_status_update() + self.worker.set_client_socket(None) + self.worker.close() + self.finish() + + def send_event(self, event): #################3 + if event["status"] == 0 and ("result" in event): + try: + if len(event["result"]["hypotheses"]) > 0 and event["result"]["final"]: + self.final_result = event["result"]["hypotheses"][0]["transcript"] + self.context = event["result"]["hypotheses"][0]["transcript"] + except: + e = sys.exc_info()[0] + logging.warn("Failed to extract hypothesis from recognition result:" + e) + elif event["status"] != 0: + event_str = str(event) + if len(event_str) > 87: + event_str = event_str[:84] + "..." + logging.debug("%s: /api/speech: Receiving event %s from worker" % (self.id, event_str)) + self.error_status = event["status"] + self.error_message = event.get("message", "") + + def close(self): + logging.info("%s: Receiving 'close' from worker" % (self.id)) + self.final_result_queue.put(self.final_hyp) + + +class StatusSocketHandler(tornado.websocket.WebSocketHandler): + # needed for Tornado 4.0 + def check_origin(self, origin): + return True + + def open(self): + logging.debug("Opened a new control channel") + self.application.status_listeners.add(self) + self.application.send_status_update_single(self) + + def on_message(self, message): + assert self.client_socket is not None + event = json.loads(message) + self.client_socket.send_event(event) + + def on_close(self): + logging.info("Status listener left") + self.application.status_listeners.remove(self) + + +class WorkerSocketHandler(tornado.websocket.WebSocketHandler): + def __init__(self, application, request, **kwargs): + tornado.websocket.WebSocketHandler.__init__(self, application, request, **kwargs) + self.client_socket = None + + # needed for Tornado 4.0 + def check_origin(self, origin): + return True + + def open(self): + self.client_socket = None + self.application.available_workers.add(self) + logging.info("New worker available " + self.__str__()) + self.application.send_status_update() + + def on_close(self): + logging.info("Worker " + self.__str__() + " leaving") + self.application.available_workers.discard(self) + if self.client_socket: + self.client_socket.close() + self.application.send_status_update() + + def on_message(self, message): + assert self.client_socket is not None + event = json.loads(message) + self.client_socket.send_event(event) + + def set_client_socket(self, client_socket): + self.client_socket = client_socket + + +class DecoderSocketHandler(tornado.websocket.WebSocketHandler): + # needed for Tornado 4.0 + def check_origin(self, origin): + return True + + def send_event(self, event): + event["id"] = self.id + event_str = str(event) + if len(event_str) > 100: + event_str = event_str[:97] + "..." + logging.info("%s: Sending event %s to client" % (self.id, event_str)) + self.write_message(json.dumps(event)) + + def open(self): + self.id = str(uuid.uuid4()) + logging.info("%s: OPEN" % (self.id)) + logging.info("%s: Request arguments: %s" % (self.id, " ".join(["%s=\"%s\"" % (a, self.get_argument(a)) for a in self.request.arguments]))) + self.user_id = self.get_argument("user-id", "none", True) + self.content_id = self.get_argument("content-id", "none", True) + self.worker = None + try: + self.worker = self.application.available_workers.pop() + self.application.send_status_update() + logging.info("%s: Using worker %s" % (self.id, self.__str__())) + self.worker.set_client_socket(self) + + content_type = self.get_argument("content-type", None, True) + if content_type: + logging.info("%s: Using content type: %s" % (self.id, content_type)) + + self.worker.write_message(json.dumps(dict(id=self.id, caps=content_type, context="{}"))) + except KeyError: + logging.warn("%s: No worker available for client request" % self.id) + event = dict(status=STATUS_NOT_AVAILABLE, message="No decoder available, try again later") + self.send_event(event) + self.close() + + def on_connection_close(self): + logging.info("%s: Handling on_connection_close()" % self.id) + self.application.num_requests_processed += 1 + self.application.send_status_update() + if self.worker: + try: + self.worker.set_client_socket(None) + logging.info("%s: Closing worker connection" % self.id) + self.worker.close() + except: + pass + + def on_message(self, message): + assert self.worker is not None + logging.info("%s: Forwarding client message (%s) of length %d to worker" % (self.id, type(message), len(message))) + if isinstance(message, unicode): + self.worker.write_message(message, binary=False) + else: + self.worker.write_message(message, binary=True) diff --git a/lucida/commandcenter/controllers/WebServer.py.forward b/lucida/commandcenter/controllers/WebServer.py.forward new file mode 100644 index 000000000..2de833c7f --- /dev/null +++ b/lucida/commandcenter/controllers/WebServer.py.forward @@ -0,0 +1,399 @@ +#!/usr/bin/env python +# +# Copyright 2013 Tanel Alumae + +""" +Reads speech data via websocket requests, sends it to Redis, waits for results from Redis and +forwards to client via websocket +""" +import sys +import logging +import json +import codecs +import os.path +import uuid +import time +import threading +import functools +from Queue import Queue + +import tornado.ioloop +import tornado.options +import tornado.web +import tornado.websocket +import tornado.gen +import tornado.concurrent +import tornado.wsgi + +from Parser import cmd_port + +from tornado.options import define +define("port", default=cmd_port, help="run on the given port", type=int) + +STATUS_EOS = -1 +STATUS_SUCCESS = 0 +STATUS_NO_SPEECH = 1 +STATUS_ABORTED = 2 +STATUS_AUDIO_CAPTURE = 3 +STATUS_NETWORK = 4 +STATUS_NOT_ALLOWED = 5 +STATUS_SERVICE_NOT_ALLOWED = 6 +STATUS_BAD_GRAMMAR = 7 +STATUS_LANGUAGE_NOT_SUPPORTED = 8 +STATUS_NOT_AVAILABLE = 9 +STATUS_NOT_AUTHENTICATED = 401 +STATUS_CONNECTED = 100 + +class Application(tornado.web.Application): + def __init__(self, flaskApp): + settings = dict( + cookie_secret="43oETzKXQAGaYdkL5gEmGeJJFuYh7EQnp2XdTP1o/Vo=", + static_path=os.path.join(os.path.dirname(os.path.dirname(__file__)), "static"), + xsrf_cookies=False, + autoescape=None + ) + + flaskWebHandler = tornado.wsgi.WSGIContainer(flaskApp) + handlers = [ + (r"/ws/speech", DecoderSocketHandler), + (r"/ws/status", StatusSocketHandler), + (r"/api/speech", DecoderAPIHandler), + (r"/worker/ws/speech", WorkerSocketHandler), + (r"/client/static/(.*)", tornado.web.StaticFileHandler, {'path': settings["static_path"]}), + (r".*", tornado.web.FallbackHandler, dict(fallback=flaskWebHandler)) + ] + tornado.web.Application.__init__(self, handlers, **settings) + self.available_workers = set() + self.status_listeners = set() + self.num_requests_processed = 0 + + def send_status_update_single(self, ws): + status = dict(num_workers_available=len(self.available_workers), num_requests_processed=self.num_requests_processed) + ws.write_message(json.dumps(status)) + + def send_status_update(self): + for ws in self.status_listeners: + self.send_status_update_single(ws) + +def run_async(func): + @functools.wraps(func) + def async_func(*args, **kwargs): + func_hl = threading.Thread(target=func, args=args, kwargs=kwargs) + func_hl.start() + return func_hl + + return async_func + + +def content_type_to_caps(content_type): + """ + Converts MIME-style raw audio content type specifier to GStreamer CAPS string + """ + default_attributes= {"rate": 16000, "format" : "S16LE", "channels" : 1, "layout" : "interleaved"} + media_type, _, attr_string = content_type.replace(";", ",").partition(",") + if media_type in ["audio/x-raw", "audio/x-raw-int"]: + media_type = "audio/x-raw" + attributes = default_attributes + for (key,_,value) in [p.partition("=") for p in attr_string.split(",")]: + attributes[key.strip()] = value.strip() + return "%s, %s" % (media_type, ", ".join(["%s=%s" % (key, value) for (key,value) in attributes.iteritems()])) + else: + return content_type + + +@tornado.web.stream_request_body +class DecoderAPIHandler(tornado.web.RequestHandler): + """ + Provides a HTTP POST/PUT interface supporting chunked transfer requests + """ + + def prepare(self): + self.id = str(uuid.uuid4()) + self.final_result = "" + self.final_result_queue = Queue() + user = self.request.headers.get("user", None) + interface = self.request.headers.get("interface", None) + token = self.request.headers.get("token", None) + user = database.get_username(interface, user) + if user == None: + self.set_status(401) + self.finish("Not Authorized") + return + logging.info("API::SPEECH %s: Received request from user '%s' over interface '%s'" % (self.id, user, interface)) + self.worker = None + self.error_status = 0 + self.error_message = None + try: + self.worker = self.application.available_workers.pop() + self.application.send_status_update() + logging.info("API::SPEECH %s: Using worker %s" % (self.id, self.__str__())) + self.worker.set_client_socket(self) + context = self.request.headers.get("context", None) + content_type = self.request.headers.get("Content-Type", None) + if content_type: + content_type = content_type_to_caps(content_type) + logging.info("API::SPEECH %s: Using content type: %s" % (self.id, content_type)) + self.worker.write_message(json.dumps(dict(id=self.id, caps=content_type, context=context, user=user, isCall=False))) + except: + logging.warn("API::SPEECH %s: No worker available for client request" % self.id) + self.set_status(503) + self.finish("No workers available") + + def data_received(self, chunk): + assert self.worker is not None + logging.info("API::SPEECH %s: Forwarding client message of length %d to worker" % (self.id, len(chunk))) + self.worker.write_message(chunk, binary=True) + + def post(self, *args, **kwargs): + self.end_request(args, kwargs) + + def put(self, *args, **kwargs): + self.end_request(args, kwargs) + + @run_async + def get_final_result(self, callback=None): + logging.info("API::SPEECH %s: Waiting for final result..." % self.id) + callback(self.final_result_queue.get(block=True)) + + @tornado.web.asynchronous + @tornado.gen.coroutine + def end_request(self, *args, **kwargs): + logging.info("API::SPEECH %s: Handling the end of request" % self.id) + assert self.worker is not None + self.worker.write_message("EOS", binary=True) + result = yield tornado.gen.Task(self.get_final_result) + if self.error_status == 0: + logging.info("%s: Final result: %s" % (self.id, result)) + response = {"status" : 0, "id": self.id, "hypotheses": [{"utterance" : result}]} + self.write(response) + else: + logging.info("%s: Error (status=%d) processing HTTP request: %s" % (self.id, self.error_status, self.error_message)) + response = {"status" : self.error_status, "id": self.id, "message": self.error_message} + self.write(response) + self.worker.set_client_socket(None) + self.worker.close() + self.finish() + logging.info("API::SPEECH Everything done") + + def send_event(self, event): ########################### + event_str = str(event) + if len(event_str) > 100: + event_str = event_str[:97] + "..." + logging.info("%s: Receiving event %s from worker" % (self.id, event_str)) + if event["status"] == 0 and ("result" in event): + try: + if len(event["result"]["hypotheses"]) > 0 and event["result"]["final"]: + self.final_result = event["result"]["hypotheses"][0]["transcript"] + except: + e = sys.exc_info()[0] + logging.warn("Failed to extract hypothesis from recognition result:" + e) + elif event["status"] != 0: + self.error_status = event["status"] + self.error_message = event.get("message", "") + + def close(self): + logging.info("API::SPEECH %s: Receiving close from worker" % (self.id)) + self.final_result_queue.put(self.final_result) + self.application.send_status_update() + +class StatusSocketHandler(tornado.websocket.WebSocketHandler): + # needed for Tornado 4.0 + def check_origin(self, origin): + return True + + def open(self): + logging.debug("Opened a new control channel") + self.application.status_listeners.add(self) + self.application.send_status_update_single(self) + + def on_message(self, message): + assert self.client_socket is not None + event = json.loads(message) + self.client_socket.send_event(event) + + def on_close(self): + logging.info("Status listener left") + self.application.status_listeners.remove(self) + +class ControlSocketHandler(tornado.websocket.WebSocketHandler): + # needed for Tornado 4.0 + def check_origin(self, origin): + return True + + def open(self): + logging.info("CTRL: Opened new control channel to client. Waiting for authentication...") + self.set_nodelay(True) + self.status = STATUS_NOT_AUTHENTICATED + + def authenticate(self, message): + self.status = STATUS_CONNECTED + self.application.status_listeners.add(self) + message = dict(status= 200, message= "Client successfully authenticated...") + self.write_message(json.dumps(message)) + logging.info("CTRL: Client successfully authenticated...") + + def online(self, message): + message = dict(status= 501, message= "Method not implemented!!!") + self.write_message(json.dumps(message)) + logging.info("CTRL: A user has come online...") + + def offline(self, message): + message = dict(status= 501, message= "Method not implemented!!!") + self.write_message(json.dumps(message)) + logging.info("CTRL: A user has gone offline...") + + def query(self, message): + message = dict(status= 501, message= "Method not implemented!!!") + self.write_message(json.dumps(message)) + logging.info("CTRL: Received query command...") + + def add_image(self, message): + message = dict(status= 501, message= "Method not implemented!!!") + self.write_message(json.dumps(message)) + logging.info("CTRL: Received add_image command...") + + def delete_image(self, message): + message = dict(status= 501, message= "Method not implemented!!!") + self.write_message(json.dumps(message)) + logging.info("CTRL: Received delete_image command...") + + def add_text(self, message): + message = dict(status= 501, message= "Method not implemented!!!") + self.write_message(json.dumps(message)) + logging.info("CTRL: Received add_text command...") + + def add_url(self, message): + message = dict(status= 501, message= "Method not implemented!!!") + self.write_message(json.dumps(message)) + logging.info("CTRL: Received add_url command...") + + def delete_text(self, message): + message = dict(status= 501, message= "Method not implemented!!!") + self.write_message(json.dumps(message)) + logging.info("CTRL: Received delete_text command...") + + def infer(self, message): + message = dict(status= 501, message= "Method not implemented!!!") + self.write_message(json.dumps(message)) + logging.info("CTRL: Received infer command...") + + + # map commands to functions + execute = { + 'authenticate' : authenticate, + 'online' : online, + 'offline' : offline, + 'query' : query, + 'add_image' : add_image, + 'delete_image' : delete_image, + 'add_text' : add_text, + 'add_url' : add_url, + 'delete_text' : delete_text, + 'infer' : infer + } + + def on_message(self, message): + try: + logging.info("CTRL: Received %s" % message) + message = json.loads(message) + if self.status == STATUS_NOT_AUTHENTICATED and message['command'] != "authenticate": + message = dict(status= 400, message= "Data received before authentication!!1 Please raise an issue with the interface maintainer...") + self.write_message(json.dumps(message)) + return + self.execute[message['command']](self, message) + except: + message = dict(status= 400, message= "Invalid message received!!1 Please raise an issue with the interface maintainer...") + self.write_message(json.dumps(message)) + + def on_close(self): + logging.info("Status listener left") + self.application.status_listeners.remove(self) + + +class WorkerSocketHandler(tornado.websocket.WebSocketHandler): + def __init__(self, application, request, **kwargs): + tornado.websocket.WebSocketHandler.__init__(self, application, request, **kwargs) + self.client_socket = None + + # needed for Tornado 4.0 + def check_origin(self, origin): + return True + + def open(self): + self.client_socket = None + self.application.available_workers.add(self) + logging.info("New worker available " + self.__str__()) + self.application.send_status_update() + + def on_close(self): + logging.info("Worker " + self.__str__() + " leaving") + self.application.available_workers.discard(self) + if self.client_socket: + self.client_socket.close() + self.application.send_status_update() + + def on_message(self, message): + assert self.client_socket is not None + event = json.loads(message) + self.client_socket.send_event(event) + + def set_client_socket(self, client_socket): + self.client_socket = client_socket + + +class DecoderSocketHandler(tornado.websocket.WebSocketHandler): + # needed for Tornado 4.0 + def check_origin(self, origin): + return True + + def send_event(self, event): + event["id"] = self.id + event_str = str(event) + if len(event_str) > 100: + event_str = event_str[:97] + "..." + logging.info("%s: Sending event %s to client" % (self.id, event_str)) + self.write_message(json.dumps(event)) + + def open(self): + self.id = str(uuid.uuid4()) + logging.info("%s: OPEN" % (self.id)) + logging.info("%s: Request arguments: %s" % (self.id, " ".join(["%s=\"%s\"" % (a, self.get_argument(a)) for a in self.request.arguments]))) + self.user_id = self.get_argument("user-id", "none", True) + self.content_id = self.get_argument("content-id", "none", True) + self.worker = None + try: + self.worker = self.application.available_workers.pop() + self.application.send_status_update() + logging.info("%s: Using worker %s" % (self.id, self.__str__())) + self.worker.set_client_socket(self) + + content_type = self.get_argument("content-type", None, True) + if content_type: + logging.info("%s: Using content type: %s" % (self.id, content_type)) + + self.worker.write_message(json.dumps(dict(id=self.id, caps=content_type, context="{}", user=self.user_id))) + except KeyError: + logging.warn("%s: No worker available for client request" % self.id) + event = dict(status=STATUS_NOT_AVAILABLE, message="No decoder available, try again later") + self.send_event(event) + self.close() + + def on_connection_close(self): + logging.info("%s: Handling on_connection_close()" % self.id) + self.application.num_requests_processed += 1 + self.application.send_status_update() + if self.worker: + try: + self.worker.set_client_socket(None) + logging.info("%s: Closing worker connection" % self.id) + self.worker.close() + except: + pass + + def on_message(self, message): + assert self.worker is not None + logging.info("%s: Forwarding client message (%s) of length %d to worker" % (self.id, type(message), len(message))) + if isinstance(message, unicode): + self.worker.write_message(message, binary=False) + else: + self.worker.write_message(message, binary=True) diff --git a/lucida/commandcenter/dump/Speech.py b/lucida/commandcenter/dump/Speech.py new file mode 100644 index 000000000..caccf630f --- /dev/null +++ b/lucida/commandcenter/dump/Speech.py @@ -0,0 +1,35 @@ +from flask import * +from Database import database +from AccessManagement import login_required +from ThriftClient import thrift_client +from QueryClassifier import query_classifier +from Utilities import log, check_image_extension +from Parser import port_dic +import Config +import os +import json +from flask_socketio import emit +from . import socketio + +speech = Blueprint('speech', __name__, template_folder='templates') + +@speech.route('/socketio') +def socketio_demo(): + return render_template('socketio.html') + +@socketio.on('connect') +def socket_connect(): + emit('stt_status', { 'status': 200, 'engines': ['kaldi'] }) + +@socketio.on('stt_control') +def stt_control(message): + print('received control message: ', str(message)) + emit('stt_status', { 'status': 200, 'message': 'Accepted' }) + +@socketio.on('stt_audio') +def receive_audio(message): + print('received audio chunk: ', str(message)) + +@socketio.on('disconnect') +def socket_disconnect(): + print('Client disconnected') diff --git a/lucida/commandcenter/dump/WebSocket.bak.py b/lucida/commandcenter/dump/WebSocket.bak.py new file mode 100644 index 000000000..d76612383 --- /dev/null +++ b/lucida/commandcenter/dump/WebSocket.bak.py @@ -0,0 +1,355 @@ +#!/usr/bin/env python +# +# Copyright 2013 Tanel Alumae + +""" +Reads speech data via websocket requests, sends it to Redis, waits for results from Redis and +forwards to client via websocket +""" +import sys +import logging +import json +import codecs +import os.path +import uuid +import time +import threading +import functools +from Queue import Queue + +import tornado.ioloop +import tornado.options +import tornado.web +import tornado.websocket +import tornado.gen +import tornado.concurrent + +from Parser import cmd_port + +from tornado.options import define +define("port", default=cmd_port, help="run on the given port", type=int) + +STATUS_EOS = -1 +STATUS_SUCCESS = 0 +STATUS_NO_SPEECH = 1 +STATUS_ABORTED = 2 +STATUS_AUDIO_CAPTURE = 3 +STATUS_NETWORK = 4 +STATUS_NOT_ALLOWED = 5 +STATUS_SERVICE_NOT_ALLOWED = 6 +STATUS_BAD_GRAMMAR = 7 +STATUS_LANGUAGE_NOT_SUPPORTED = 8 +STATUS_NOT_AVAILABLE = 9 + + +class Application(tornado.web.Application): + def __init__(self): + settings = dict( + cookie_secret="43oETzKXQAGaYdkL5gEmGeJJFuYh7EQnp2XdTP1o/Vo=", + template_path=os.path.join(os.path.dirname(os.path.dirname(__file__)), "templates"), + static_path=os.path.join(os.path.dirname(os.path.dirname(__file__)), "static"), + xsrf_cookies=False, + autoescape=None, + ) + + handlers = [ + (r"/client/ws/speech", DecoderSocketHandler), + (r"/client/ws/status", StatusSocketHandler), + (r"/client/dynamic/reference", ReferenceHandler), + (r"/client/dynamic/recognize", HttpChunkedRecognizeHandler), + (r"/worker/ws/speech", WorkerSocketHandler), + (r"/client/static/(.*)", tornado.web.StaticFileHandler, {'path': settings["static_path"]}), + ] + tornado.web.Application.__init__(self, handlers, **settings) + self.available_workers = set() + self.status_listeners = set() + self.num_requests_processed = 0 + + def send_status_update_single(self, ws): + status = dict(num_workers_available=len(self.available_workers), num_requests_processed=self.num_requests_processed) + ws.write_message(json.dumps(status)) + + def send_status_update(self): + for ws in self.status_listeners: + self.send_status_update_single(ws) + + def save_reference(self, content_id, content): + refs = {} + try: + with open("reference-content.json") as f: + refs = json.load(f) + except: + pass + refs[content_id] = content + with open("reference-content.json", "w") as f: + json.dump(refs, f, indent=2) + + +class MainHandler(tornado.web.RequestHandler): + def get(self): + current_directory = os.path.dirname(os.path.abspath(__file__)) + parent_directory = os.path.join(current_directory, os.pardir) + readme = os.path.join(parent_directory, "README.md") + self.render(readme) + + +def run_async(func): + @functools.wraps(func) + def async_func(*args, **kwargs): + func_hl = threading.Thread(target=func, args=args, kwargs=kwargs) + func_hl.start() + return func_hl + + return async_func + + +def content_type_to_caps(content_type): + """ + Converts MIME-style raw audio content type specifier to GStreamer CAPS string + """ + default_attributes= {"rate": 16000, "format" : "S16LE", "channels" : 1, "layout" : "interleaved"} + media_type, _, attr_string = content_type.replace(";", ",").partition(",") + if media_type in ["audio/x-raw", "audio/x-raw-int"]: + media_type = "audio/x-raw" + attributes = default_attributes + for (key,_,value) in [p.partition("=") for p in attr_string.split(",")]: + attributes[key.strip()] = value.strip() + return "%s, %s" % (media_type, ", ".join(["%s=%s" % (key, value) for (key,value) in attributes.iteritems()])) + else: + return content_type + + +@tornado.web.stream_request_body +class HttpChunkedRecognizeHandler(tornado.web.RequestHandler): + """ + Provides a HTTP POST/PUT interface supporting chunked transfer requests, similar to that provided by + http://github.com/alumae/ruby-pocketsphinx-server. + """ + + def prepare(self): + self.id = str(uuid.uuid4()) + self.final_hyp = "" + self.final_result_queue = Queue() + self.user_id = self.request.headers.get("device-id", "none") + self.content_id = self.request.headers.get("content-id", "none") + logging.info("%s: OPEN: user='%s', content='%s'" % (self.id, self.user_id, self.content_id)) + self.worker = None + self.error_status = 0 + self.error_message = None + try: + self.worker = self.application.available_workers.pop() + self.application.send_status_update() + logging.info("%s: Using worker %s" % (self.id, self.__str__())) + self.worker.set_client_socket(self) + + content_type = self.request.headers.get("Content-Type", None) + if content_type: + content_type = content_type_to_caps(content_type) + logging.info("%s: Using content type: %s" % (self.id, content_type)) + + self.worker.write_message(json.dumps(dict(id=self.id, content_type=content_type, user_id=self.user_id, content_id=self.content_id))) + except KeyError: + logging.warn("%s: No worker available for client request" % self.id) + self.set_status(503) + self.finish("No workers available") + + def data_received(self, chunk): + assert self.worker is not None + logging.debug("%s: Forwarding client message of length %d to worker" % (self.id, len(chunk))) + self.worker.write_message(chunk, binary=True) + + def post(self, *args, **kwargs): + self.end_request(args, kwargs) + + def put(self, *args, **kwargs): + self.end_request(args, kwargs) + + @run_async + def get_final_hyp(self, callback=None): + logging.info("%s: Waiting for final result..." % self.id) + callback(self.final_result_queue.get(block=True)) + + @tornado.web.asynchronous + @tornado.gen.coroutine + def end_request(self, *args, **kwargs): + logging.info("%s: Handling the end of chunked recognize request" % self.id) + assert self.worker is not None + self.worker.write_message("EOS", binary=True) + logging.info("%s: yielding..." % self.id) + hyp = yield tornado.gen.Task(self.get_final_hyp) + if self.error_status == 0: + logging.info("%s: Final hyp: %s" % (self.id, hyp)) + response = {"status" : 0, "id": self.id, "hypotheses": [{"utterance" : hyp}]} + self.write(response) + else: + logging.info("%s: Error (status=%d) processing HTTP request: %s" % (self.id, self.error_status, self.error_message)) + response = {"status" : self.error_status, "id": self.id, "message": self.error_message} + self.write(response) + self.application.num_requests_processed += 1 + self.application.send_status_update() + self.worker.set_client_socket(None) + self.worker.close() + self.finish() + logging.info("Everything done") + + def send_event(self, event): + event_str = str(event) + if len(event_str) > 100: + event_str = event_str[:97] + "..." + logging.info("%s: Receiving event %s from worker" % (self.id, event_str)) + if event["status"] == 0 and ("result" in event): + try: + if len(event["result"]["hypotheses"]) > 0 and event["result"]["final"]: + if len(self.final_hyp) > 0: + self.final_hyp += " " + self.final_hyp += event["result"]["hypotheses"][0]["transcript"] + except: + e = sys.exc_info()[0] + logging.warn("Failed to extract hypothesis from recognition result:" + e) + elif event["status"] != 0: + self.error_status = event["status"] + self.error_message = event.get("message", "") + + def close(self): + logging.info("%s: Receiving 'close' from worker" % (self.id)) + self.final_result_queue.put(self.final_hyp) + + +class ReferenceHandler(tornado.web.RequestHandler): + def post(self, *args, **kwargs): + content_id = self.request.headers.get("Content-Id") + if content_id: + content = codecs.decode(self.request.body, "utf-8") + user_id = self.request.headers.get("User-Id", "") + self.application.save_reference(content_id, dict(content=content, user_id=user_id, time=time.strftime("%Y-%m-%dT%H:%M:%S"))) + logging.info("Received reference text for content %s and user %s" % (content_id, user_id)) + self.set_header('Access-Control-Allow-Origin', '*') + else: + self.set_status(400) + self.finish("No Content-Id specified") + + def options(self, *args, **kwargs): + self.set_header('Access-Control-Allow-Origin', '*') + self.set_header('Access-Control-Allow-Methods', 'POST, OPTIONS') + self.set_header('Access-Control-Max-Age', 1000) + # note that '*' is not valid for Access-Control-Allow-Headers + self.set_header('Access-Control-Allow-Headers', 'origin, x-csrftoken, content-type, accept, User-Id, Content-Id') + + +class StatusSocketHandler(tornado.websocket.WebSocketHandler): + # needed for Tornado 4.0 + def check_origin(self, origin): + return True + + def open(self): + logging.info("New status listener") + self.application.status_listeners.add(self) + self.application.send_status_update_single(self) + + def on_close(self): + logging.info("Status listener left") + self.application.status_listeners.remove(self) + + +class WorkerSocketHandler(tornado.websocket.WebSocketHandler): + def __init__(self, application, request, **kwargs): + tornado.websocket.WebSocketHandler.__init__(self, application, request, **kwargs) + self.client_socket = None + + # needed for Tornado 4.0 + def check_origin(self, origin): + return True + + def open(self): + self.client_socket = None + self.application.available_workers.add(self) + logging.info("New worker available " + self.__str__()) + self.application.send_status_update() + + def on_close(self): + logging.info("Worker " + self.__str__() + " leaving") + self.application.available_workers.discard(self) + if self.client_socket: + self.client_socket.close() + self.application.send_status_update() + + def on_message(self, message): + assert self.client_socket is not None + event = json.loads(message) + self.client_socket.send_event(event) + + def set_client_socket(self, client_socket): + self.client_socket = client_socket + + +class DecoderSocketHandler(tornado.websocket.WebSocketHandler): + # needed for Tornado 4.0 + def check_origin(self, origin): + return True + + def send_event(self, event): + event["id"] = self.id + event_str = str(event) + if len(event_str) > 100: + event_str = event_str[:97] + "..." + logging.info("%s: Sending event %s to client" % (self.id, event_str)) + self.write_message(json.dumps(event)) + + def open(self): + self.id = str(uuid.uuid4()) + logging.info("%s: OPEN" % (self.id)) + logging.info("%s: Request arguments: %s" % (self.id, " ".join(["%s=\"%s\"" % (a, self.get_argument(a)) for a in self.request.arguments]))) + self.user_id = self.get_argument("user-id", "none", True) + self.content_id = self.get_argument("content-id", "none", True) + self.worker = None + try: + self.worker = self.application.available_workers.pop() + self.application.send_status_update() + logging.info("%s: Using worker %s" % (self.id, self.__str__())) + self.worker.set_client_socket(self) + + content_type = self.get_argument("content-type", None, True) + if content_type: + logging.info("%s: Using content type: %s" % (self.id, content_type)) + + self.worker.write_message(json.dumps(dict(id=self.id, content_type=content_type, user_id=self.user_id, content_id=self.content_id))) + except KeyError: + logging.warn("%s: No worker available for client request" % self.id) + event = dict(status=STATUS_NOT_AVAILABLE, message="No decoder available, try again later") + self.send_event(event) + self.close() + + def on_connection_close(self): + logging.info("%s: Handling on_connection_close()" % self.id) + self.application.num_requests_processed += 1 + self.application.send_status_update() + if self.worker: + try: + self.worker.set_client_socket(None) + logging.info("%s: Closing worker connection" % self.id) + self.worker.close() + except: + pass + + def on_message(self, message): + assert self.worker is not None + logging.info("%s: Forwarding client message (%s) of length %d to worker" % (self.id, type(message), len(message))) + if isinstance(message, unicode): + self.worker.write_message(message, binary=False) + else: + self.worker.write_message(message, binary=True) + + +def main(): + logging.basicConfig(level=logging.DEBUG, format="%(levelname)8s %(asctime)s %(message)s ") + logging.debug('Starting up server') + from tornado.options import options + + tornado.options.parse_command_line() + app = Application() + app.listen(3000) + tornado.ioloop.IOLoop.instance().start() + + +if __name__ == "__main__": + main() diff --git a/lucida/commandcenter/dump/__init__.py b/lucida/commandcenter/dump/__init__.py new file mode 100644 index 000000000..dcfada909 --- /dev/null +++ b/lucida/commandcenter/dump/__init__.py @@ -0,0 +1,7 @@ +from flask_socketio import SocketIO + +socketio = SocketIO() + +__all__ = ['Main', 'AccessManagement', 'WebSocket', 'Service', 'Graph', + 'ThriftClient', 'Create', 'Learn', 'Infer', 'Parser', + 'QueryClassifier', 'Config', 'User', 'Utilities', 'Database', 'Memcached', 'Decision', 'Speech', 'socketio'] diff --git a/lucida/commandcenter/dump/app.py b/lucida/commandcenter/dump/app.py new file mode 100644 index 000000000..43f0b4923 --- /dev/null +++ b/lucida/commandcenter/dump/app.py @@ -0,0 +1,64 @@ +from __future__ import absolute_import +from __future__ import division +from __future__ import unicode_literals + +import sys, glob, os +sys.path.insert(0, glob.glob(os.path.abspath(os.path.dirname(__file__)) + + '/../../tools/thrift-0.9.3/lib/py/build/lib*')[0]) + +from controllers import * +from controllers.Parser import cmd_port +from flask import * +from flask_socketio import SocketIO, emit +from threading import Thread +import logging + + +# Initialize the Flask app with the template folder address. +app = Flask(__name__, template_folder='templates') + +# app.config.from_object('config') +app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024 # 16 MB due to MongoDB + +# Register the controllers. +app.register_blueprint(Main.main) +app.register_blueprint(User.user) +app.register_blueprint(Create.create) +app.register_blueprint(Learn.learn) +app.register_blueprint(Infer.infer) +app.register_blueprint(Speech.speech) + +# Session. +app.secret_key = 'A0Zr98j/3yX R~XHH!jmN]LWX/,?RT' + +socketio.init_app(app, async_mode='eventlet', allow_upgrades='true') + +def flask_listener(): + print 'Starting non-secure flask' +# socketio.run(app, host='0.0.0.0', port=3000, debug=True, use_reloader=False, certfile='certs/server.crt', keyfile='certs/server.key') + socketio.run(app, host='0.0.0.0', port=3000, debug=True, use_reloader=False) + +def web_socket_listener(): + print 'Start web socket at ' + str(cmd_port) + logging.basicConfig(level=logging.DEBUG, + format="%(levelname)8s %(asctime)s %(message)s ") + logging.debug('Starting up server') + WebSocket.tornado.options.parse_command_line() + + # For wss (with ASR capability) + if os.environ.get('SECURE_HOST'): + print 'Starting secure web socket' + WebSocket.Application().listen(cmd_port, ssl_options={ + "certfile":"certs/server.crt", + "keyfile":"certs/server.key"}) + # For ws (without ASR capability) + else: + print 'Starting non-secure web socket' + WebSocket.Application().listen(cmd_port) + + WebSocket.tornado.ioloop.IOLoop.instance().start() + +if __name__ == '__main__': +# Thread(target = flask_listener).start() +# web_socket_listener() + flask_listener() diff --git a/lucida/commandcenter/dump/dictate.js b/lucida/commandcenter/dump/dictate.js new file mode 100644 index 000000000..9cf6c3646 --- /dev/null +++ b/lucida/commandcenter/dump/dictate.js @@ -0,0 +1,416 @@ +(function(window){ + + // Defaults + var SERVER = "ws://bark.phon.ioc.ee:82/dev/duplex-speech-api/ws/speech"; + var SERVER_STATUS = "ws://bark.phon.ioc.ee:82/dev/duplex-speech-api/ws/status"; + var REFERENCE_HANDLER = "http://bark.phon.ioc.ee:82/dev/duplex-speech-api/dynamic/reference"; + var CONTENT_TYPE = "content-type=audio/x-raw,+layout=(string)interleaved,+rate=(int)16000,+format=(string)S16LE,+channels=(int)1"; + // Send blocks 4 x per second as recommended in the server doc. + var INTERVAL = 250; + var TAG_END_OF_SENTENCE = "EOS"; + var RECORDER_WORKER_PATH = 'recorderWorker.js'; + + // Error codes (mostly following Android error names and codes) + var ERR_NETWORK = 2; + var ERR_AUDIO = 3; + var ERR_SERVER = 4; + var ERR_CLIENT = 5; + + // Event codes + var MSG_WAITING_MICROPHONE = 1; + var MSG_MEDIA_STREAM_CREATED = 2; + var MSG_INIT_RECORDER = 3; + var MSG_RECORDING = 4; + var MSG_SEND = 5; + var MSG_SEND_EMPTY = 6; + var MSG_SEND_EOS = 7; + var MSG_WEB_SOCKET = 8; + var MSG_WEB_SOCKET_OPEN = 9; + var MSG_WEB_SOCKET_CLOSE = 10; + var MSG_STOP = 11; + var MSG_SERVER_CHANGED = 12; + + // Server status codes + // from https://github.com/alumae/kaldi-gstreamer-server + var SERVER_STATUS_CODE = { + 0: 'Success', // Usually used when recognition results are sent + 1: 'No speech', // Incoming audio contained a large portion of silence or non-speech + 2: 'Aborted', // Recognition was aborted for some reason + 9: 'No available', // recognizer processes are currently in use and recognition cannot be performed + }; + + var Dictate = function(cfg) { + var config = cfg || {}; + config.server = config.server || SERVER; + config.audioSourceId = config.audioSourceId; + config.serverStatus = config.serverStatus || SERVER_STATUS; + config.referenceHandler = config.referenceHandler || REFERENCE_HANDLER; + config.contentType = config.contentType || CONTENT_TYPE; + config.interval = config.interval || INTERVAL; + config.recorderWorkerPath = config.recorderWorkerPath || RECORDER_WORKER_PATH; + config.onReadyForSpeech = config.onReadyForSpeech || function() {}; + config.onEndOfSpeech = config.onEndOfSpeech || function() {}; + config.onPartialResults = config.onPartialResults || function(data) {}; + config.onResults = config.onResults || function(data) {}; + config.onEndOfSession = config.onEndOfSession || function() {}; + config.onEvent = config.onEvent || function(e, data) {}; + config.onError = config.onError || function(e, data) {}; + config.rafCallback = config.rafCallback || function(time) {}; + if (config.onServerStatus) { + monitorServerStatus(); + } + + // Initialized by init() + var audioContext; + var recorder; + // Initialized by startListening() + var ws; + var intervalKey; + // Initialized during construction + var wsServerStatus; + + // Returns the configuration + this.getConfig = function() { + return config; + } + + // Set up the recorder (incl. asking permission) + // Initializes audioContext + // Can be called multiple times. + // TODO: call something on success (MSG_INIT_RECORDER is currently called) + this.init = function() { + var audioSourceConstraints = {}; + config.onEvent(MSG_WAITING_MICROPHONE, "Waiting for approval to access your microphone ..."); + try { + window.AudioContext = window.AudioContext || window.webkitAudioContext; + navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia; + window.URL = window.URL || window.webkitURL; + audioContext = new AudioContext(); + } catch (e) { + // Firefox 24: TypeError: AudioContext is not a constructor + // Set media.webaudio.enabled = true (in about:config) to fix this. + config.onError(ERR_CLIENT, "Error initializing Web Audio browser: " + e); + } + + if (navigator.getUserMedia) { + if(config.audioSourceId) { + audioSourceConstraints.audio = { + optional: [{ sourceId: config.audioSourceId }] + }; + } else { + audioSourceConstraints.audio = true; + } + navigator.getUserMedia(audioSourceConstraints, startUserMedia, function(e) { + config.onError(ERR_CLIENT, "No live audio input in this browser: " + e); + }); + } else { + config.onError(ERR_CLIENT, "No user media support"); + } + } + + // Start recording and transcribing + this.startListening = function() { + if (!recorder) { + config.onError(ERR_AUDIO, "Recorder undefined"); + return; + } + + if (ws) { + cancel(); + } + + try { + ws = createWebSocket(); + } catch (e) { + config.onError(ERR_CLIENT, "No web socket support in this browser!"); + } + } + + // Cancel everything without waiting on the server + this.cancel = function() { + // Stop the regular sending of audio (if present) + clearInterval(intervalKey); + if (recorder) { + recorder.stop(); + recorder.clear(); + config.onEvent(MSG_STOP, 'Stopped recording'); + } + if (ws) { + ws.close(); + ws = null; + } + } + + // Sets the URL of the speech server + this.setServer = function(server) { + config.server = server; + config.onEvent(MSG_SERVER_CHANGED, 'Server changed: ' + server); + } + + // Sets the URL of the speech server status server + this.setServerStatus = function(serverStatus) { + config.serverStatus = serverStatus; + + if (config.onServerStatus) { + monitorServerStatus(); + } + + config.onEvent(MSG_SERVER_CHANGED, 'Server status server changed: ' + serverStatus); + } + + // Sends reference text to speech server + this.submitReference = function submitReference(text, successCallback, errorCallback) { + var headers = {} + if (config["user_id"]) { + headers["User-Id"] = config["user_id"] + } + if (config["content_id"]) { + headers["Content-Id"] = config["content_id"] + } + $.ajax({ + url: config.referenceHandler, + type: "POST", + headers: headers, + data: text, + dataType: "text", + success: successCallback, + error: errorCallback, + }); + } + + // Private methods + function startUserMedia(stream) { + var input = audioContext.createMediaStreamSource(stream); + config.onEvent(MSG_MEDIA_STREAM_CREATED, 'Media stream created'); + + // make the analyser available in window context + window.userSpeechAnalyser = audioContext.createAnalyser(); + input.connect(window.userSpeechAnalyser); + + config.rafCallback(); + + recorder = new Recorder(input, { workerPath : config.recorderWorkerPath }); + this.recorder = recorder; + config.onEvent(MSG_INIT_RECORDER, 'Recorder initialized'); + } + + function socketSend(item) { + if (ws) { + var state = ws.readyState; + if (state == 1) { + // If item is an audio blob + if (item instanceof Blob) { + if (item.size > 0) { + ws.send(item); + config.onEvent(MSG_SEND, 'Send: blob: ' + item.type + ', ' + item.size); + } else { + config.onEvent(MSG_SEND_EMPTY, 'Send: blob: ' + item.type + ', EMPTY'); + } + // Otherwise it's the EOS tag (string) + } else { + ws.send(item); + config.onEvent(MSG_SEND_EOS, 'Send tag: ' + item); + } + } else { + config.onError(ERR_NETWORK, 'WebSocket: readyState!=1: ' + state + ": failed to send: " + item); + } + } else { + config.onError(ERR_CLIENT, 'No web socket connection: failed to send: ' + item); + } + } + + + + var stopListeningFunc = function() { + // Stop the regular sending of audio + clearInterval(intervalKey); + // Stop recording + if (recorder) { + recorder.stop(); + config.onEvent(MSG_STOP, 'Stopped recording'); + // Push the remaining audio to the server + recorder.export16kMono(function(blob) { + console.log(blob) + socketSend(blob); + socketSend(TAG_END_OF_SENTENCE); + recorder.clear(); + }, 'audio/x-raw'); + config.onEndOfSpeech(); + } else { + config.onError(ERR_AUDIO, "Recorder undefined"); + } + + console.log($("#clinc").val()) + + + + + + // $.ajax({ + // type: "POST", + // url: "/api/login", + // data: JSON.stringify(user_login_info), + // contentType: "application/json", + // success: function(success_data) { + // if ($.url().param("url") !== undefined) { + + // console.log($.url().param("url")); + // window.location.href = secret_url_str + $.url().param("url"); + // } else { + // window.location.href = secret_url_str + "/"; //redirect to the main page + // } + // }, + // error: function(error_data) { + // // {readyState: 4, responseText: "{"errors": [{ + // // "message": "Username does not exist"}]}", + // // responseJSON: Object, status: 404, statusText: "NOT FOUND"} + // var response = error_data.responseJSON; + // if (error_data.status == 404) { + // X_username.append( + // error_html_start + response.errors[0].message + error_html_end); + + // } else { + // X_password.append( + // error_html_start + response.errors[0].message + error_html_end); + // } + // } + // }); + + + + + + } + + // Stop listening, i.e. recording and sending of new input. + this.stopListening = stopListeningFunc + + function createWebSocket() { + // TODO: do we need to use a protocol? + //var ws = new WebSocket("ws://127.0.0.1:8081", "echo-protocol"); + var url = config.server + '?' + config.contentType; + if (config["user_id"]) { + url += '&user-id=' + config["user_id"] + } + if (config["content_id"]) { + url += '&content-id=' + config["content_id"] + } + var ws = new WebSocket(url); + + ws.onmessage = function(e) { + var data = e.data; + config.onEvent(MSG_WEB_SOCKET, data); + var r = JSON.parse(data); + // if (r.hascoachresponse) { + // config.onClinc(r.coachresponse); + // } + if (data instanceof Object && ! (data instanceof Blob)) { + config.onError(ERR_SERVER, 'WebSocket: onEvent: got Object that is not a Blob'); + } else if (data instanceof Blob) { + config.onError(ERR_SERVER, 'WebSocket: got Blob'); + } else { + var res = JSON.parse(data); + if (res.status == 0) { + // TODO: final is undefined sometimes + if (res.result === undefined || res.result.final) { + if (res.result !== undefined) { + config.onResults(res.result.hypotheses); + } + stopListeningFunc(); + } else { + config.onPartialResults(res.result.hypotheses); + } + // if (res.hascoachresponse) { + // config.onClinc(res.coachresponse); + // } + } else { + config.onError(ERR_SERVER, 'Server error: ' + res.status + ': ' + getDescription(res.status)); + } + } + } + + // Start recording only if the socket becomes open + ws.onopen = function(e) { + intervalKey = setInterval(function() { + recorder.export16kMono(function(blob) { + socketSend(blob); + console.log(blob) + recorder.clear(); + }, 'audio/x-raw'); + }, config.interval); + // Start recording + recorder.record(); + config.onReadyForSpeech(); + config.onEvent(MSG_WEB_SOCKET_OPEN, e); + }; + + // This can happen if the blob was too big + // E.g. "Frame size of 65580 bytes exceeds maximum accepted frame size" + // Status codes + // http://tools.ietf.org/html/rfc6455#section-7.4.1 + // 1005: + // 1006: + ws.onclose = function(e) { + var code = e.code; + var reason = e.reason; + var wasClean = e.wasClean; + // The server closes the connection (only?) + // when its endpointer triggers. + config.onEndOfSession(); + config.onEvent(MSG_WEB_SOCKET_CLOSE, e.code + "/" + e.reason + "/" + e.wasClean); + }; + + ws.onerror = function(e) { + var data = e.data; + config.onError(ERR_NETWORK, data); + } + + return ws; + } + + + function monitorServerStatus() { + if (wsServerStatus) { + wsServerStatus.close(); + } + wsServerStatus = new WebSocket(config.serverStatus); + wsServerStatus.onmessage = function(evt) { + config.onServerStatus(JSON.parse(evt.data)); + }; + } + + + function getDescription(code) { + if (code in SERVER_STATUS_CODE) { + return SERVER_STATUS_CODE[code]; + } + return "Unknown error"; + } + + + + }; // Dictate + + // Simple class for persisting the transcription. + // If isFinal==true then a new line is started in the transcription list + // (which only keeps the final transcriptions). + var Transcription = function(cfg) { + var index = 0; + var list = []; + + this.add = function(text, isFinal) { + list[index] = text; + if (isFinal) { + index++; + } + } + + this.toString = function() { + return list.join('. '); + } + } + + window.Dictate = Dictate; + window.Transcription = Transcription; + +})(window); diff --git a/lucida/commandcenter/dump/infer.html b/lucida/commandcenter/dump/infer.html new file mode 100644 index 000000000..8623f5894 --- /dev/null +++ b/lucida/commandcenter/dump/infer.html @@ -0,0 +1,144 @@ +{% extends "base.html" %} + +{% block content %} + +{% if dates %} + + + +{% endif %} + + + +
+
+

Main » Infer

+
+ +
+
+

Ask a question:

+
+
+ +
+
+ + +
+ + +

Upload your picture!

+
+ +
+ +
+
+ + {% if error %} +

{{ error }}

+ {% endif %} +
+ +
+
+
- -
+
+ +
+
+
+
+
-

- +

+
+ +
-
- -
- - - -
- -
- -
- Powered by Lucida -
+
+ Powered by Lucida +
+ + + + + + + + + + + + + + + + + + + + +
+
+ +
+
+
+ +
+
+
+ +
+
+ + + +
+

+
+ +
+ +
+ Powered by Lucida +
+
+
+ + + +
+
+ + + +
+ + + + + + + +{% endblock %} diff --git a/lucida/commandcenter/dump/mob.js b/lucida/commandcenter/dump/mob.js new file mode 100644 index 000000000..e98a42551 --- /dev/null +++ b/lucida/commandcenter/dump/mob.js @@ -0,0 +1,256 @@ +// Global UI elements: +// - log: event log +// - trans: transcription window + +// Global objects: +// - isConnected: true iff we are connected to a worker +// - tt: simple structure for managing the list of hypotheses +// - dictate: dictate object with control methods 'init', 'startListening', ... +// and event callbacks onResults, onError, ... +var isConnected = false; +var isMicrophoneInitialized = false; + +var tt = new Transcription(); + +var startPosition = 0; +var endPosition = 0; +var doUpper = false; +var doPrependSpace = true; +var textToVoice = true; + +function capitaliseFirstLetter(string) { + return string.charAt(0).toUpperCase() + string.slice(1); +} + +function updateDisabledState() { + var disabled = true; + // var text = "{{ _('Dikteerimiseks vajuta nuppu') }}"; + // if (!isMicrophoneInitialized) { + // disabled = true; + // text = "{{ _('Mikrofon initsialiseerimata') }}"; + // } else if (isConnected) { + // disabled = false; + // text = "{{ _('Räägi...') }}"; + // } else if (numWorkersAvailable == 0) { + // disabled = true; + // text = "{{ _('Server ülekoormatud või rivist väljas') }}"; + // } + if (disabled) { + $("#recbutton").addClass("disabled"); + //$("#helptext").html(text); + } else { + $("#recbutton").removeClass("disabled"); + //$("#helptext").html(text); + } +} + +function prettyfyHyp(text, doCapFirst, doPrependSpace) { + if (doCapFirst) { + text = capitaliseFirstLetter(text); + } + tokens = text.split(" "); + text = ""; + if (doPrependSpace) { + text = " "; + } + doCapitalizeNext = false; + tokens.map(function(token) { + if (text.trim().length > 0) { + text = text + " "; + } + if (doCapitalizeNext) { + text = text + capitaliseFirstLetter(token); + } else { + text = text + token; + } + if (token == "." || /\n$/.test(token)) { + doCapitalizeNext = true; + } else { + doCapitalizeNext = false; + } + }); + + text = text.replace(/ ([,.!?:;])/g, "\$1"); + text = text.replace(/ ?\n ?/g, "\n"); + return text; +} + +var dictate = new Dictate({ + server : $("#servers").val().split('|')[0], + serverStatus : $("#servers").val().split('|')[1], + recorderWorkerPath : 'static/js/recorderWorker.js', + onReadyForSpeech : function() { + isConnected = true; + __message("READY FOR SPEECH"); + document.getElementById('startImg').src = 'static/image/microphone_off.png'; + $("#buttonToggleListening").html('Stop'); + $("#buttonToggleListening").addClass('highlight'); + $("#buttonToggleListening").prop("disabled", false); + $("#buttonCancel").prop("disabled", false); + $("#recbutton").addClass("playing"); + startPosition = $("#trans").prop("selectionStart"); + endPosition = startPosition; + var textBeforeCaret = $("#trans").val().slice(0, startPosition); + if ((textBeforeCaret.length == 0) || /\. *$/.test(textBeforeCaret) || /\n *$/.test(textBeforeCaret)) { + doUpper = true; + } else { + doUpper = false; + } + doPrependSpace = (textBeforeCaret.length > 0) && !(/\n *$/.test(textBeforeCaret)); + }, + onEndOfSpeech : function() { + __message("END OF SPEECH"); + document.getElementById('startImg').src = 'static/image/microphone.png'; + $("#buttonToggleListening").html('Stopping...'); + $("#buttonToggleListening").prop("disabled", true); + }, + onEndOfSession : function() { + isConnected = false; + __message("END OF SESSION"); + $("#buttonToggleListening").html('Start'); + $("#buttonToggleListening").removeClass('highlight'); + $("#buttonToggleListening").prop("disabled", false); + $("#buttonCancel").prop("disabled", true); + $("#recbutton").removeClass("playing"); + }, + onServerStatus : function(json) { + __serverStatus(json.num_workers_available); + $("#serverStatusBar").toggleClass("highlight", json.num_workers_available == 0); + // If there are no workers and we are currently not connected + // then disable the Start/Stop button. + if (json.num_workers_available == 0 && ! isConnected) { + $("#buttonToggleListening").prop("disabled", true); + } else { + $("#buttonToggleListening").prop("disabled", false); + } + }, + onPartialResults : function(hypos) { + hypText = prettyfyHyp(hypos[0].transcript, doUpper, doPrependSpace); + val = $("#trans").val(); + $("#trans").val(val.slice(0, startPosition) + hypText + val.slice(endPosition)); + endPosition = startPosition + hypText.length; + $("#trans").prop("selectionStart", endPosition); + }, + onResults : function(hypos) { + hypText = prettyfyHyp(hypos[0].transcript, doUpper, doPrependSpace); + val = $("#trans").val(); + $("#trans").val(val.slice(0, startPosition) + hypText + val.slice(endPosition)); + startPosition = startPosition + hypText.length; + endPosition = startPosition; + $("#trans").prop("selectionStart", endPosition); + if (/\. *$/.test(hypText) || /\n *$/.test(hypText)) { + doUpper = true; + } else { + doUpper = false; + } + doPrependSpace = (hypText.length > 0) && !(/\n *$/.test(hypText)); + }, + onClinc : function(hypos) { + hypText = prettyfyHyp(hypos, doUpper, doPrependSpace); + val = $("#clinc").val(); + $("#clinc").val(val.slice(0, startPosition) + hypText + val.slice(endPosition)); + if (textToVoice){ + speakable = hypText.split('\n')[0]; + var u = new SpeechSynthesisUtterance(); + u.text = speakable; + u.lang = 'en-US'; + u.rate = 1.0; + speechSynthesis.speak(u); + } + startPosition = startPosition + hypText.length; + endPosition = startPosition; + $("#clinc").prop("selectionStart", endPosition); + if (/\. *$/.test(hypText) || /\n *$/.test(hypText)) { + doUpper = true; + } else { + doUpper = false; + } + doPrependSpace = (hypText.length > 0) && !(/\n *$/.test(hypText)); + }, + onError : function(code, data) { + dictate.cancel(); + __error(code, data); + // TODO: show error in the GUI + }, + onEvent : function(code, data) { + __message(code, data); + if (code == 3 /* MSG_INIT_RECORDER */) { + isMicrophoneInitialized = true; + updateDisabledState(); + } + } +}); + +// Private methods (called from the callbacks) +function __message(code, data) { + log.innerHTML = "msg: " + code + ": " + (data || '') + "\n" + log.innerHTML; +} + +function __error(code, data) { + log.innerHTML = "ERR: " + code + ": " + (data || '') + "\n" + log.innerHTML; +} + +function __serverStatus(msg) { + serverStatusBar.innerHTML = msg; +} + +function __updateTranscript(text) { + $("#trans").val(text); +} + +// Public methods (called from the GUI) +function startButtonFunc() { + if (isConnected) { + dictate.stopListening(); + $("#recbutton").addClass("disabled"); + } else { + clearTranscription(); + document.getElementById('startImg').src = 'static/image/microphone.png'; + dictate.startListening(); + } +} + +function cancel() { + dictate.cancel(); +} + +function clearTranscription() { + $("#trans").val(""); + // needed, otherwise selectionStart will retain its old value + $("#trans").prop("selectionStart", 0); + $("#trans").prop("selectionEnd", 0); + + $("#clinc").val(""); + // needed, otherwise selectionStart will retain its old value + $("#clinc").prop("selectionStart", 0); + $("#clinc").prop("selectionEnd", 0); +} + +$(document).ready(function() { + dictate.init(); + + $("#servers").change(function() { + dictate.cancel(); + var servers = $("#servers").val().split('|'); + dictate.setServer(servers[0]); +// dictate.setServerStatus(servers[1]); + }); + +}); + +function readURL(input) { + if (input.files && input.files[0]) { + var reader = new FileReader(); + + reader.onload = function (e) { + $('#image_upload_preview').attr('src', e.target.result); + } + + reader.readAsDataURL(input.files[0]); + } +} + +$("#file_input").change(function () { + readURL(this); +}); + diff --git a/lucida/commandcenter/dump/socketio.html b/lucida/commandcenter/dump/socketio.html new file mode 100644 index 000000000..a8ef8f9d8 --- /dev/null +++ b/lucida/commandcenter/dump/socketio.html @@ -0,0 +1,37 @@ + + + + Socket.IO chat + + + +
    + + + + + + + + diff --git a/lucida/commandcenter/dump/stream_audio.js b/lucida/commandcenter/dump/stream_audio.js new file mode 100644 index 000000000..55949654e --- /dev/null +++ b/lucida/commandcenter/dump/stream_audio.js @@ -0,0 +1,96 @@ +var sendInterval; +var socket; +var input; + +// Private methods +function startUserMedia(stream) { + input = audioContext.createMediaStreamSource(stream); + + // make the analyser available in window context + window.userSpeechAnalyser = audioContext.createAnalyser(); + input.connect(window.userSpeechAnalyser); + + recorder = new Recorder(input, { workerPath : 'static/js/recorderWorker.js' }); +} + +startListening = function() { + if (!recorder) { + alert("Recorder undefined"); + return; + } + socket.emit('stt_control', {command: 'I start recording...'}); + sendInterval = setInterval(function() { + recorder.export16kMono(function(blob) { + console.log(blob); + socket.emit('stt_audio', blob); + recorder.clear(); + }, 'audio/x-raw'); + }, 250); + recorder.record(); + clearTranscription(); + document.getElementById('startImg').src = 'static/image/microphone_off.png'; +} + +stopListening = function() { + clearInterval(sendInterval); + sendInterval = undefined; + if (recorder) { + recorder.stop(); + recorder.export16kMono(function(blob) { + socket.emit('stt_audio',blob); + socket.emit('stt_control', {command: 'I stop recording!!!'}); + recorder.clear(); + }, 'audio/x-raw'); + } else { + alert("Recorder undefined"); + } + document.getElementById('startImg').src = 'static/image/microphone.png'; +} + +function clearTranscription() { + $("#trans").val(""); + $("#trans").prop("selectionStart", 0); + $("#trans").prop("selectionEnd", 0); + + $("#clinc").val(""); + $("#clinc").prop("selectionStart", 0); + $("#clinc").prop("selectionEnd", 0); +} + +// Public methods (called from the GUI) +function startButtonFunc() { + if (sendInterval) { + stopListening(); + } else { + startListening(); + } +} + +// Document ready function +$(document).ready(function() { + var audioSourceConstraints = {}; + try { + window.AudioContext = window.AudioContext || window.webkitAudioContext; + navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia; + window.URL = window.URL || window.webkitURL; + audioContext = new AudioContext(); + } catch (e) { + alert("Error initializing Web Audio browser: " + e); + } + + if (navigator.getUserMedia) { +// if(config.audioSourceId) { +// audioSourceConstraints.audio = { optional: [{ sourceId: config.audioSourceId }] }; +// } else { + audioSourceConstraints.audio = true; +// } + navigator.getUserMedia(audioSourceConstraints, startUserMedia, function(e) { alert("No live audio input in this browser: " + e); }); + } else { + alert("No user media support"); + } + + socket = io(); + socket.on('stt_status', function(message) { + console.log(JSON.stringify(message)); + }); +}); diff --git a/lucida/commandcenter/templates/infer.html b/lucida/commandcenter/templates/infer.html index 00ffcad7a..436b46e3c 100644 --- a/lucida/commandcenter/templates/infer.html +++ b/lucida/commandcenter/templates/infer.html @@ -106,7 +106,7 @@