Skip to content

Instantly share code, notes, and snippets.

@ckhung
Last active September 4, 2021 07:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ckhung/2c8f3bc4a788e81e3742f5e2f4ac41b8 to your computer and use it in GitHub Desktop.
Save ckhung/2c8f3bc4a788e81e3742f5e2f4ac41b8 to your computer and use it in GitHub Desktop.
primitive voice command interface w/ pocketsphinx as backend
#!/usr/bin/python3
import argparse, os, re
from warnings import warn
import subprocess
parser = argparse.ArgumentParser(
description='invoke pocketsphinx and produce keystrokes',
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument('-k', '--kwokfn', type=str, default='',
help='voice keyword and output key definition file')
args = parser.parse_args()
def parse_def(def_string):
def_string = def_string.strip()
ans = []
while def_string:
if def_string[0] in '"\'':
regex = def_string[0] + '(.*?)' + def_string[0]
m = re.match(regex, def_string)
piece = m.group(1)
ans += ['space' if c==' ' else c for c in piece]
def_string = def_string[len(piece)+2:]
else:
m = re.match('(\s*([+\w]+))', def_string)
ans.append(m.group(2))
def_string = def_string[len(m.group(1)):]
return ans
phkmapping = {} # phrase-key mapping table
kwsfn = '/var/run/user/' + str(os.getuid()) + '/voicmd.kws'
with open(kwsfn, 'w+') as outfile:
with open(args.kwokfn) as infile:
for line in infile.readlines():
if re.match(r'^\s*#', line): continue
m = re.match(r'(.*\S)\s+(/[-\d.Ee]+/)\s*([^/]*)', line)
inphrase = m.group(1)
try:
outkeys = parse_def(m.group(3))
except AttributeError:
warn('ignoring unparsable line: ' + line)
continue
# print(inphrase, outkeys)
phkmapping[inphrase] = outkeys
outfile.write(inphrase + ' ' + m.group(2) + '\n')
pscmd = f'pocketsphinx_continuous -inmic yes -kws {kwsfn} -logfn /dev/null'.split()
with subprocess.Popen(pscmd, stdout=subprocess.PIPE,
bufsize=1, universal_newlines=True) as ps:
for line in ps.stdout:
inphrase = re.sub(r' .*', '', line.strip())
outkeys = phkmapping[inphrase]
subprocess.call(['xdotool', 'key'] + outkeys)
list short /1e-6/ "ls "
list long /1e-6/ "ls -l "
list all /1e-6/ "ls -a "
move /1e-5/ "mv "
copy /1e-6/ "cp "
c d /1e-6/ "cd "
public /1e-6/ "public"
active /1e-6/ "acttive"
left arrow /1e-6/ Left
right arrow /1e-6/ Right
up arrow /1e-6/ Up
down arrow /1e-6/ Down
home /1e-6/ Home
end /1e-6/ End
tab /1e-6/ Tab
enter /1e-6/ Return
escape /1e-6/ Escape
control kill /1e-6/ ctrl+k
control break /1e-6/ ctrl+c
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment