mirror of
https://github.com/GrammaticalFramework/gf-core.git
synced 2026-04-24 03:52:50 -06:00
Added semi-working speech_input command.
This commit is contained in:
@@ -59,6 +59,8 @@ import qualified GF.Embed.EmbedAPI as EA
|
|||||||
|
|
||||||
import GF.UseGrammar.Editing
|
import GF.UseGrammar.Editing
|
||||||
|
|
||||||
|
import GF.System.SpeechInput (recognizeSpeech)
|
||||||
|
|
||||||
----import GrammarToXML
|
----import GrammarToXML
|
||||||
|
|
||||||
----import GrammarToMGrammar as M
|
----import GrammarToMGrammar as M
|
||||||
@@ -206,6 +208,14 @@ speechGenerate opts str = do
|
|||||||
--- system ("echo" +++ "\"" ++ str ++ "\" | festival --tts" ++ lan)
|
--- system ("echo" +++ "\"" ++ str ++ "\" | festival --tts" ++ lan)
|
||||||
return ()
|
return ()
|
||||||
|
|
||||||
|
-- FIXME: look at flags
|
||||||
|
speechInput :: Options -> StateGrammar -> IO String
|
||||||
|
speechInput opt s = recognizeSpeech name opts cfg
|
||||||
|
where
|
||||||
|
opts = stateOptions s
|
||||||
|
name = cncId s
|
||||||
|
cfg = stateCFG s
|
||||||
|
|
||||||
optLinearizeTreeVal :: Options -> GFGrammar -> Tree -> String
|
optLinearizeTreeVal :: Options -> GFGrammar -> Tree -> String
|
||||||
optLinearizeTreeVal opts gr = err id id . optLinearizeTree opts gr
|
optLinearizeTreeVal opts gr = err id id . optLinearizeTree opts gr
|
||||||
|
|
||||||
|
|||||||
@@ -348,6 +348,7 @@ execC co@(comm, opts0) sa@(sh@(st,(h,_,_,_)),a) = checkOptions st co >> case com
|
|||||||
CWriteFile file -> justOutputArg opts (writeFile file) sa
|
CWriteFile file -> justOutputArg opts (writeFile file) sa
|
||||||
CAppendFile file -> justOutputArg opts (appendFile file) sa
|
CAppendFile file -> justOutputArg opts (appendFile file) sa
|
||||||
CSpeakAloud -> justOutputArg opts (speechGenerate opts) sa
|
CSpeakAloud -> justOutputArg opts (speechGenerate opts) sa
|
||||||
|
CSpeechInput -> returnArgIO (speechInput opts gro >>= return . AString) sa
|
||||||
CSystemCommand s -> case a of
|
CSystemCommand s -> case a of
|
||||||
AUnit -> justOutput opts (system s >> return ()) sa
|
AUnit -> justOutput opts (system s >> return ()) sa
|
||||||
_ -> systemArg opts a s sa
|
_ -> systemArg opts a s sa
|
||||||
|
|||||||
@@ -480,6 +480,14 @@ txtHelpFile =
|
|||||||
"\n h | sa -- listen to the list of commands" ++
|
"\n h | sa -- listen to the list of commands" ++
|
||||||
"\n gr -cat=S | l | sa -- generate a random sentence and speak it aloud" ++
|
"\n gr -cat=S | l | sa -- generate a random sentence and speak it aloud" ++
|
||||||
"\n" ++
|
"\n" ++
|
||||||
|
"\nsi, speech_input: si" ++
|
||||||
|
"\n Uses an ATK speech recognizer to get speech input. " ++
|
||||||
|
"\n flags:" ++
|
||||||
|
"\n -lang: The grammar to use with the speech recognizer." ++
|
||||||
|
"\n -cat: The grammar category to get input in." ++
|
||||||
|
"\n -language: Use acoustic model and dictionary for this language." ++
|
||||||
|
"\n -number: The number of utterances to recognize." ++
|
||||||
|
"\n" ++
|
||||||
"\nh, help: h Command?" ++
|
"\nh, help: h Command?" ++
|
||||||
"\n Displays the paragraph concerning the command from this help file." ++
|
"\n Displays the paragraph concerning the command from this help file." ++
|
||||||
"\n Without the argument, shows the first lines of all paragraphs." ++
|
"\n Without the argument, shows the first lines of all paragraphs." ++
|
||||||
|
|||||||
@@ -134,6 +134,7 @@ pCommand ws = case ws of
|
|||||||
"af" : f : s -> aString (CAppendFile (unquote f)) s
|
"af" : f : s -> aString (CAppendFile (unquote f)) s
|
||||||
"rf" : f : [] -> aUnit (CReadFile (unquote f))
|
"rf" : f : [] -> aUnit (CReadFile (unquote f))
|
||||||
"sa" : s -> aString CSpeakAloud s
|
"sa" : s -> aString CSpeakAloud s
|
||||||
|
"si" : [] -> aUnit CSpeechInput
|
||||||
"ps" : s -> aString CPutString s
|
"ps" : s -> aString CPutString s
|
||||||
"st" : s -> aTerm CShowTerm s
|
"st" : s -> aTerm CShowTerm s
|
||||||
"!" : s -> aUnit (CSystemCommand (unwords s))
|
"!" : s -> aUnit (CSystemCommand (unwords s))
|
||||||
|
|||||||
@@ -65,6 +65,7 @@ data Command =
|
|||||||
| CWriteFile FilePath
|
| CWriteFile FilePath
|
||||||
| CAppendFile FilePath
|
| CAppendFile FilePath
|
||||||
| CSpeakAloud
|
| CSpeakAloud
|
||||||
|
| CSpeechInput
|
||||||
| CPutString
|
| CPutString
|
||||||
| CShowTerm
|
| CShowTerm
|
||||||
| CSystemCommand String
|
| CSystemCommand String
|
||||||
@@ -197,6 +198,8 @@ optionsOfCommand co = case co of
|
|||||||
CWriteFile _ -> none
|
CWriteFile _ -> none
|
||||||
CAppendFile _ -> none
|
CAppendFile _ -> none
|
||||||
CSpeakAloud -> flags "language"
|
CSpeakAloud -> flags "language"
|
||||||
|
CSpeechInput -> flags "lang cat language number"
|
||||||
|
|
||||||
CPutString -> both "utf8" "filter length"
|
CPutString -> both "utf8" "filter length"
|
||||||
CShowTerm -> flags "printer"
|
CShowTerm -> flags "printer"
|
||||||
CShowTreeGraph -> opts "c f g o"
|
CShowTreeGraph -> opts "c f g o"
|
||||||
|
|||||||
@@ -27,9 +27,8 @@ import GF.Speech.FiniteState
|
|||||||
import GF.Speech.Relation
|
import GF.Speech.Relation
|
||||||
import GF.Speech.TransformCFG
|
import GF.Speech.TransformCFG
|
||||||
|
|
||||||
cfgToFA :: Ident -- ^ Grammar name
|
cfgToFA :: Options -> CGrammar -> DFA String
|
||||||
-> Options -> CGrammar -> DFA String
|
cfgToFA opts = minimize . compileAutomaton start . makeSimpleRegular
|
||||||
cfgToFA name opts = minimize . compileAutomaton start . makeSimpleRegular
|
|
||||||
where start = getStartCat opts
|
where start = getStartCat opts
|
||||||
|
|
||||||
makeSimpleRegular :: CGrammar -> CFRules
|
makeSimpleRegular :: CGrammar -> CFRules
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ import Data.Maybe (fromMaybe)
|
|||||||
faGraphvizPrinter :: Ident -- ^ Grammar name
|
faGraphvizPrinter :: Ident -- ^ Grammar name
|
||||||
-> Options -> CGrammar -> String
|
-> Options -> CGrammar -> String
|
||||||
faGraphvizPrinter name opts cfg =
|
faGraphvizPrinter name opts cfg =
|
||||||
prFAGraphviz $ mapStates (const "") $ cfgToFA name opts cfg
|
prFAGraphviz $ mapStates (const "") $ cfgToFA opts cfg
|
||||||
|
|
||||||
|
|
||||||
-- | Convert the grammar to a regular grammar and print it in BNF
|
-- | Convert the grammar to a regular grammar and print it in BNF
|
||||||
@@ -51,7 +51,7 @@ regularPrinter = prCFRules . makeSimpleRegular
|
|||||||
|
|
||||||
faCPrinter :: Ident -- ^ Grammar name
|
faCPrinter :: Ident -- ^ Grammar name
|
||||||
-> Options -> CGrammar -> String
|
-> Options -> CGrammar -> String
|
||||||
faCPrinter name opts cfg = fa2c $ cfgToFA name opts cfg
|
faCPrinter name opts cfg = fa2c $ cfgToFA opts cfg
|
||||||
|
|
||||||
fa2c :: DFA String -> String
|
fa2c :: DFA String -> String
|
||||||
fa2c fa = undefined
|
fa2c fa = undefined
|
||||||
@@ -48,16 +48,15 @@ data SLFEdge = SLFEdge { eId :: Int, eStart :: Int, eEnd :: Int }
|
|||||||
|
|
||||||
slfPrinter :: Ident -- ^ Grammar name
|
slfPrinter :: Ident -- ^ Grammar name
|
||||||
-> Options -> CGrammar -> String
|
-> Options -> CGrammar -> String
|
||||||
slfPrinter name opts cfg = prSLF (automatonToSLF $ mkSLFFA name opts cfg) ""
|
slfPrinter name opts cfg = prSLF (automatonToSLF $ mkSLFFA opts cfg) ""
|
||||||
|
|
||||||
slfGraphvizPrinter :: Ident -- ^ Grammar name
|
slfGraphvizPrinter :: Ident -- ^ Grammar name
|
||||||
-> Options -> CGrammar -> String
|
-> Options -> CGrammar -> String
|
||||||
slfGraphvizPrinter name opts cfg =
|
slfGraphvizPrinter name opts cfg =
|
||||||
prFAGraphviz $ mapStates (fromMaybe "") $ mapTransitions (const "") $ mkSLFFA name opts cfg
|
prFAGraphviz $ mapStates (fromMaybe "") $ mapTransitions (const "") $ mkSLFFA opts cfg
|
||||||
|
|
||||||
mkSLFFA :: Ident -- ^ Grammar name
|
mkSLFFA :: Options -> CGrammar -> FA State (Maybe String) ()
|
||||||
-> Options -> CGrammar -> FA State (Maybe String) ()
|
mkSLFFA opts cfg = oneFinalState Nothing () $ moveLabelsToNodes $ dfa2nfa $ cfgToFA opts cfg
|
||||||
mkSLFFA name opts cfg = oneFinalState Nothing () $ moveLabelsToNodes $ dfa2nfa $ cfgToFA name opts cfg
|
|
||||||
|
|
||||||
automatonToSLF :: FA State (Maybe String) () -> SLF
|
automatonToSLF :: FA State (Maybe String) () -> SLF
|
||||||
automatonToSLF fa = SLF { slfNodes = map mkSLFNode (states fa),
|
automatonToSLF fa = SLF { slfNodes = map mkSLFNode (states fa),
|
||||||
|
|||||||
65
src/GF/System/ATKSpeechInput.hs
Normal file
65
src/GF/System/ATKSpeechInput.hs
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
----------------------------------------------------------------------
|
||||||
|
-- |
|
||||||
|
-- Module : GF.System.ATKSpeechInput
|
||||||
|
-- Maintainer : BB
|
||||||
|
-- Stability : (stable)
|
||||||
|
-- Portability : (non-portable)
|
||||||
|
--
|
||||||
|
-- > CVS $Date: 2005/05/10 15:04:01 $
|
||||||
|
-- > CVS $Author: bringert $
|
||||||
|
-- > CVS $Revision: 1.2 $
|
||||||
|
--
|
||||||
|
-- Use ATK and Speech.ATKRec for speech input.
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
module GF.System.ATKSpeechInput (recognizeSpeech) where
|
||||||
|
|
||||||
|
import GF.Infra.Ident (Ident, prIdent)
|
||||||
|
import GF.Infra.Option (Options)
|
||||||
|
import GF.Conversion.Types (CGrammar)
|
||||||
|
import GF.Speech.PrSLF
|
||||||
|
|
||||||
|
import Speech.ATKRec
|
||||||
|
|
||||||
|
import Control.Monad
|
||||||
|
import Data.IORef
|
||||||
|
import System.IO
|
||||||
|
import System.IO.Unsafe
|
||||||
|
|
||||||
|
-- FIXME: get these from somewhere else
|
||||||
|
|
||||||
|
config = "/home/bjorn/projects/atkrec/atkrec.cfg"
|
||||||
|
|
||||||
|
res = "/home/bjorn/src/atk/Resources"
|
||||||
|
hmmlist = res ++ "/UK_SI_ZMFCC/hmmlistbg"
|
||||||
|
mmf0 = res ++ "/UK_SI_ZMFCC/WI4"
|
||||||
|
mmf1 = res ++ "/UK_SI_ZMFCC/BGHMM2"
|
||||||
|
dict = res ++ "/beep.dct"
|
||||||
|
|
||||||
|
initialized :: IORef Bool
|
||||||
|
initialized = unsafePerformIO $ newIORef False
|
||||||
|
|
||||||
|
initATK :: IO ()
|
||||||
|
initATK = do
|
||||||
|
b <- readIORef initialized
|
||||||
|
when (not b) $ do
|
||||||
|
hPutStrLn stderr "Initializing..."
|
||||||
|
initialize config
|
||||||
|
loadHMMSet "hmm_english" hmmlist mmf0 mmf1
|
||||||
|
loadDict "dict_english" dict
|
||||||
|
writeIORef initialized True
|
||||||
|
|
||||||
|
recognizeSpeech :: Ident -- ^ Grammar name
|
||||||
|
-> Options -> CGrammar -> IO String
|
||||||
|
recognizeSpeech name opts cfg =
|
||||||
|
do
|
||||||
|
let slf = slfPrinter name opts cfg
|
||||||
|
n = prIdent name
|
||||||
|
slfName = "gram_" ++ n
|
||||||
|
recName = "rec_english_" ++ n
|
||||||
|
initATK
|
||||||
|
loadGrammarString slfName slf
|
||||||
|
createRecognizer recName "hmm_english" "dict_english" slfName
|
||||||
|
hPutStrLn stderr "Listening..."
|
||||||
|
s <- recognize recName
|
||||||
|
return s
|
||||||
17
src/GF/System/NoSpeechInput.hs
Normal file
17
src/GF/System/NoSpeechInput.hs
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
----------------------------------------------------------------------
|
||||||
|
-- |
|
||||||
|
-- Module : GF.System.NoSpeechInput
|
||||||
|
-- Maintainer : BB
|
||||||
|
-- Stability : (stable)
|
||||||
|
-- Portability : (portable)
|
||||||
|
--
|
||||||
|
-- > CVS $Date: 2005/05/10 15:04:01 $
|
||||||
|
-- > CVS $Author: bringert $
|
||||||
|
-- > CVS $Revision: 1.2 $
|
||||||
|
--
|
||||||
|
-- Dummy speech input.
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
module GF.System.NoSpeechInput (recognizeSpeech) where
|
||||||
|
|
||||||
|
recognizeSpeech = fail "No speech input available"
|
||||||
27
src/GF/System/SpeechInput.hs
Normal file
27
src/GF/System/SpeechInput.hs
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
{-# OPTIONS -cpp #-}
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
-- |
|
||||||
|
-- Module : GF.System.SpeechInput
|
||||||
|
-- Maintainer : BB
|
||||||
|
-- Stability : (stable)
|
||||||
|
-- Portability : (portable)
|
||||||
|
--
|
||||||
|
-- > CVS $Date: 2005/05/10 15:04:01 $
|
||||||
|
-- > CVS $Author: bringert $
|
||||||
|
-- > CVS $Revision: 1.2 $
|
||||||
|
--
|
||||||
|
-- Uses the right speech recognition library for speech input.
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
module GF.System.SpeechInput (recognizeSpeech) where
|
||||||
|
|
||||||
|
#ifdef USE_ATK
|
||||||
|
|
||||||
|
import GF.System.ATKSpeechInput (recognizeSpeech)
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
import GF.System.NoSpeechInput (recognizeSpeech)
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -451,6 +451,14 @@ sa, speak_aloud: sa String
|
|||||||
h | sa -- listen to the list of commands
|
h | sa -- listen to the list of commands
|
||||||
gr -cat=S | l | sa -- generate a random sentence and speak it aloud
|
gr -cat=S | l | sa -- generate a random sentence and speak it aloud
|
||||||
|
|
||||||
|
si, speech_input: si
|
||||||
|
Uses an ATK speech recognizer to get speech input.
|
||||||
|
flags:
|
||||||
|
-lang: The grammar to use with the speech recognizer.
|
||||||
|
-cat: The grammar category to get input in.
|
||||||
|
-language: Use acoustic model and dictionary for this language.
|
||||||
|
-number: The number of utterances to recognize.
|
||||||
|
|
||||||
h, help: h Command?
|
h, help: h Command?
|
||||||
Displays the paragraph concerning the command from this help file.
|
Displays the paragraph concerning the command from this help file.
|
||||||
Without the argument, shows the first lines of all paragraphs.
|
Without the argument, shows the first lines of all paragraphs.
|
||||||
|
|||||||
@@ -48,6 +48,10 @@ ifeq ("$(INTERRUPT)","yes")
|
|||||||
GHCFLAGS += -DUSE_INTERRUPT
|
GHCFLAGS += -DUSE_INTERRUPT
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ("$(ATK)","yes")
|
||||||
|
GHCFLAGS += -DUSE_ATK
|
||||||
|
endif
|
||||||
|
|
||||||
ifeq ("$(ENABLE_JAVA)", "yes")
|
ifeq ("$(ENABLE_JAVA)", "yes")
|
||||||
BUILD_JAR=jar
|
BUILD_JAR=jar
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -27,6 +27,8 @@ READLINE = @READLINE@
|
|||||||
|
|
||||||
INTERRUPT = @INTERRUPT@
|
INTERRUPT = @INTERRUPT@
|
||||||
|
|
||||||
|
ATK = @ATK@
|
||||||
|
|
||||||
ENABLE_JAVA = @ENABLE_JAVA@
|
ENABLE_JAVA = @ENABLE_JAVA@
|
||||||
|
|
||||||
JAVAC = "@JAVAC@"
|
JAVAC = "@JAVAC@"
|
||||||
|
|||||||
@@ -115,6 +115,41 @@ esac
|
|||||||
|
|
||||||
AC_SUBST(INTERRUPT)
|
AC_SUBST(INTERRUPT)
|
||||||
|
|
||||||
|
dnl ***********************************************
|
||||||
|
dnl ATK speech recognition
|
||||||
|
dnl ***********************************************
|
||||||
|
|
||||||
|
AC_ARG_WITH(atk,
|
||||||
|
AC_HELP_STRING([--with-atk=<use ATK speech recognition>],
|
||||||
|
[Choose whether to compile in support for speech
|
||||||
|
recognition using ATK. Requires ATK and libatkrec.
|
||||||
|
Available alternatives are: 'yes', 'no'
|
||||||
|
(default = no)]),
|
||||||
|
[ATK="$withval"],
|
||||||
|
[ATK="no"])
|
||||||
|
|
||||||
|
case $ATK in
|
||||||
|
yes)
|
||||||
|
AC_MSG_CHECKING([for atkrec package])
|
||||||
|
ATKREC_VERSION=`ghc-pkg latest atkrec`
|
||||||
|
if test "$ATKREC_VERSION" = ""; then
|
||||||
|
AC_MSG_RESULT(['not found'])
|
||||||
|
AC_MSG_WARN([Disabling ATK support.])
|
||||||
|
ATK="no"
|
||||||
|
else
|
||||||
|
AC_MSG_RESULT([$ATKREC_VERSION])
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
no)
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
AC_MSG_ERROR([Bad value for --with-atk: $ATK])
|
||||||
|
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
AC_SUBST(ATK)
|
||||||
|
|
||||||
dnl ***********************************************
|
dnl ***********************************************
|
||||||
dnl java stuff
|
dnl java stuff
|
||||||
dnl ***********************************************
|
dnl ***********************************************
|
||||||
|
|||||||
Reference in New Issue
Block a user