summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.travis.yml3
-rwxr-xr-xship/bin/punani1
-rwxr-xr-xship/build104
-rwxr-xr-xutil/bin/mic.stt12
-rw-r--r--util/lib/stt/README.md4
-rw-r--r--util/lib/stt/google.sh35
-rwxr-xr-xutil/t/stt/stt-works-with-espeak16
7 files changed, 142 insertions, 33 deletions
diff --git a/.travis.yml b/.travis.yml
index 12f6de4d..1218d9d9 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -8,8 +8,9 @@ notifications:
script: "! ( make -C util test | grep '^not ok' )"
before_install:
- sudo apt-get install bc -qq
- - sudo apt-get install python -qq
- sudo apt-get install w3m -qq
+# stt-espeak test
+ - sudo apt-get install flac espeak -qq
branches:
only:
- master
diff --git a/ship/bin/punani b/ship/bin/punani
index 99a5a813..28bf7d1a 100755
--- a/ship/bin/punani
+++ b/ship/bin/punani
@@ -1,3 +1,4 @@
#!/bin/sh
+#@info
#@include punani
punani "$@"
diff --git a/ship/build b/ship/build
index 6c26e6f3..486f4bed 100755
--- a/ship/build
+++ b/ship/build
@@ -2,67 +2,107 @@
set -euf
## SYNOPSIS
-# build compile SRCFILE DSTFILE
-# build deps SRCFILE
+# [debug=true] build compile SRCFILE DSTFILE
+# [debug=true] build deps SRCFILE...
build() {
case "$1" in
compile) build_compile "$2" "$3";;
- deps) build_deps "$2";;
+ deps) shift; build_deps "$@";;
*) echo "build: $1: bad command" >&2; return 23;;
esac
}
+# usage: debug_script VARNAME [DESCRIPTION]
+debug_script() {
+ if test "${debug-false}" = true; then
+ printf '====== %s%s\n%s\n' \
+ "$1" \
+ "${2+" ($2)"}" \
+ "$(eval echo \"\$$1\" | nl -b a)" >&2
+ fi
+}
+
## build directives
+build_info_directive='#@info'
build_include_directive='#@include \([0-9A-Za-z]\+\)'
+input_parser="\
+s:^ *\([0-9]\+\) "$build_info_directive"$:build_info \1:
+s:^ *\([0-9]\+\) "$build_include_directive"$:build_include \1 \2:
+t
+s:^ *\([0-9]\+\) .*:echo \1p:"
+debug_script input_parser
+
+## usage: build_include LINENO LIBNAME
+build_include() { cat<<EOF
+$1a\\
+# begin $2
+$1r$(build_resolve $2)
+$1a\\
+# end $2
+EOF
+}
+
+## usage: build_info LINENO
+build_info() { cat<<EOF
+$1a\\
+# this file was generated by //ship/build\\
+# date: $(date -u --rfc-3339=s)\\
+# version: $(git rev-parse HEAD)
+EOF
+}
+
## usage: build_compile SRCFILE DSTFILE
build_compile() {
- cp "$1" "$2"
+ srcfile="$(cat "$1")"
+ debug_script srcfile 'SRCFILE'
- while needs_compilation "$2"; do
- script="$(make_sedscript_maker_shellscript "$2" | sh)"
- sed -n "$script" "$2" >"$2.tmp"
- mv "$2.tmp" "$2"
+ while needs_compilation "$srcfile"; do
+ script="$(make_sedscript_maker_shellscript "$srcfile")"
+ srcfile="$(echo "$srcfile" | sed -n "$script")"
+ debug_script srcfile 'sed sedscript srcfile'
done
+ echo "$srcfile" > "$2"
chmod +x "$2"
}
-## usage: needs_compilation SRCFILE
+## usage: needs_compilation SHELLSCRIPT
# Returns true if SRCFILE contains compilation directives.
needs_compilation() {
- grep -q "^$build_include_directive$" "$1"
+ echo "$1" |
+ grep -q "^\\($build_include_directive\\|$build_info_directive\\)$"
}
## usage: make_sedscript_maker_shellscript SRCFILE
# Print a shellscript that creates a sedscript that resolves all the build
# directives in SRCFILE.
make_sedscript_maker_shellscript() {
- echo 'set -euf'
- deps="$(build_deps "$1")"
- for lib in $deps; do
- echo "_build_include_$(basename $lib)=$lib"
- done
- nl -b a -s ' ' "$1" |
- sed '
- s:^ *::
- s:^\([0-9]\+\) '"$build_include_directive"'$:\1a\\\\\
-# BEGIN \2\
- \1r\$_build_include_\2\
- \1a\\\\\
-# END \2:
- s:^\([0-9]\+\) .*:\1p:
-
- 1s:^:echo ":
- $s:$:":
- '
+ sedscript_generator="$(echo "$1" | nl -b a -s ' ' | sed "$input_parser")"
+ debug_script sedscript_generator 'sed input_parser srcfile'
+
+ sedscript="$(eval "$sedscript_generator")"
+ debug_script sedscript 'eval sedscript_generator'
+
+ echo "$sedscript"
}
-## usage: build_deps SRCFILE
+## usage: build_deps SRCFILE...
+# Print all the dependencies of SRCFILE... (in alphabetic order) to stdout.
build_deps() {
- for libname in $(sed -n 's:^'"$build_include_directive"'$:\1:p' "$1"); do
- build_resolve "$libname"
- done
+ while test $# -gt 0; do
+ deps="$(
+ for f; do
+ for d in $(sed -n 's:^'"$build_include_directive"'$:\1:p' "$f"); do
+ build_resolve $d
+ done
+ done
+ )"
+ set -- $deps
+ if test $# -gt 0; then
+ echo "$deps"
+ fi
+ done | sort | uniq
}
## usage: build_resolve LIBNAME
diff --git a/util/bin/mic.stt b/util/bin/mic.stt
new file mode 100755
index 00000000..9236f85c
--- /dev/null
+++ b/util/bin/mic.stt
@@ -0,0 +1,12 @@
+#!/bin/sh
+set -efux
+cd $(dirname $(readlink -f $0))
+. ../lib/stt/google.sh
+duration=${1?please provide duration via \$1}
+lang=${lang:-de-DE}
+export lang
+echo "language is set to $lang"
+echo "will record for '$duration' seconds"
+f=$(record_audio ${duration})
+trap 'rm $f' TERM EXIT HUP
+stt "$f"
diff --git a/util/lib/stt/README.md b/util/lib/stt/README.md
new file mode 100644
index 00000000..be905770
--- /dev/null
+++ b/util/lib/stt/README.md
@@ -0,0 +1,4 @@
+# Speech to Text api wrapper
+
+Because Speech to text is hardâ„¢ with FOSS, these libraries utilize the magic of
+the internets to solve this problem.
diff --git a/util/lib/stt/google.sh b/util/lib/stt/google.sh
new file mode 100644
index 00000000..a78579d5
--- /dev/null
+++ b/util/lib/stt/google.sh
@@ -0,0 +1,35 @@
+#!/bin/sh
+
+_get_content_type(){
+ file -b --mime-type "$1"
+}
+_get_audio_rate(){
+ file "$1" | sed -n -e 's/.* \([.0-9]\+\) kHz.*/\1/p' \
+ | awk '{print int($1 *1000)}'
+}
+
+record_audio(){
+ # usage : _record_audio num_seconds
+ # echoes the output file
+ tmpfile=$(mktemp)
+ : ${1?please provide number of seconds to record}
+ arecord -d "$1" -r 16000 -t wav -q -f cd | flac -s -f - -o "$tmpfile" && echo "$tmpfile"
+}
+stt(){
+ # usage: (lang=de-de stty recorded_file)
+ : ${1? please provide recorded file}
+ infile="$1"
+ lang=${lang:-en-us}
+ _get_content_type "$1" | (! grep -q "x-flac" ) \
+ && echo "infile needs to be in flac format" \
+ && return 1
+ # only flac seems to be working...
+ wget -q -O - \
+ -U 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/535.7 (KHTML, like Gecko) Chrome/16.0.912.77 Safari/535.7' \
+ --post-file "$infile" \
+ --header "Content-Type: `_get_content_type $infile`; rate=`_get_audio_rate $infile`;" \
+ "http://www.google.com/speech-api/v1/recognize?lang=${lang}&client=chromium&maxresults=1" \
+ | sed -n 's/.*utterance":"\([^"]*\)".*/\1/p'
+
+ # returns {"status":0,"id":"d9269e6f741997161e41a4d441b34ba1-1","hypotheses":[{"utterance":"hallo Welt","confidence":0.7008959}]}
+}
diff --git a/util/t/stt/stt-works-with-espeak b/util/t/stt/stt-works-with-espeak
new file mode 100755
index 00000000..ff39f567
--- /dev/null
+++ b/util/t/stt/stt-works-with-espeak
@@ -0,0 +1,16 @@
+#!/bin/sh
+
+cd $(dirname $(readlink -f $0))
+. ../../lib/stt/google.sh
+tmp=$(mktemp)
+test_str="hello"
+trap "rm $tmp" TERM INT EXIT HUP
+espeak --stdout "$test_str" | flac --totally-silent -f -o "$tmp" -
+
+if stt "$tmp" | egrep "^$test_str\$" >/dev/null ;then
+ echo "ok"
+ exit 0
+else
+ echo "not ok"
+ exit 1
+fi