Added pocketsphinx library

This commit is contained in:
Daniel Wolf 2015-10-19 21:45:08 +02:00
parent 528b6289c7
commit eb675e4968
725 changed files with 371174 additions and 1 deletions

View File

@ -0,0 +1,13 @@
Fil Alleva
Robert Brennan
Hsiao-wen Hon
Ravishankar Mosur
Eric Thayer
Kevin Lenzo
Alan W Black
Evandro Gouvea
David Huggins-Daines
Alexander Solovets
Vyacheslav Klimkov
More! please help us get all the names.

View File

@ -0,0 +1,18 @@
SUBDIRS = src doc model include test swig
EXTRA_DIST = \
autogen.sh \
m4/pkg.m4 \
pocketsphinx.pc.in \
pocketsphinx.sln \
win32/pocketsphinx/pocketsphinx.vcxproj \
win32/pocketsphinx/pocketsphinx.vcxproj.filters \
win32/pocketsphinx_batch/pocketsphinx_batch.vcxproj \
win32/pocketsphinx_continuous/pocketsphinx_continuous.vcxproj \
win32/pocketsphinx_mdef_convert/pocketsphinx_mdef_convert.vcxproj
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = pocketsphinx.pc
CLEANFILES = pocketsphinx.pc
ACLOCAL_AMFLAGS = -I m4

View File

@ -0,0 +1,874 @@
# Makefile.in generated by automake 1.13.4 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2013 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.
@SET_MAKE@
VPATH = @srcdir@
am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
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)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
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 = @build@
host_triplet = @host@
subdir = .
DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
$(top_srcdir)/configure $(am__configure_deps) \
$(srcdir)/pocketsphinx.pc.in AUTHORS NEWS README config.guess \
config.sub depcomp install-sh missing py-compile ltmain.sh
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_pkg_swig.m4 \
$(top_srcdir)/m4/ax_python_devel.m4 \
$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
$(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/pkg.m4 \
$(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
configure.lineno config.status.lineno
mkinstalldirs = $(install_sh) -d
CONFIG_CLEAN_FILES = pocketsphinx.pc
CONFIG_CLEAN_VPATH_FILES =
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false
am__v_P_1 = :
AM_V_GEN = $(am__v_GEN_@AM_V@)
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
am__v_GEN_0 = @echo " GEN " $@;
am__v_GEN_1 =
AM_V_at = $(am__v_at_@AM_V@)
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
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
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)$(pkgconfigdir)"
DATA = $(pkgconfig_DATA)
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)
# 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)
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 = @ACLOCAL@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GREP = @GREP@
GST_CFLAGS = @GST_CFLAGS@
GST_LIBS = @GST_LIBS@
GST_MAJORMINOR = @GST_MAJORMINOR@
GST_PLUGIN_LDFLAGS = @GST_PLUGIN_LDFLAGS@
GStreamer_CFLAGS = @GStreamer_CFLAGS@
GStreamer_LIBS = @GStreamer_LIBS@
HAVE_DOXYGEN = @HAVE_DOXYGEN@
HAVE_PKGCONFIG = @HAVE_PKGCONFIG@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LD = @LD@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PKG_CONFIG = @PKG_CONFIG@
PYTHON = @PYTHON@
PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@
PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@
PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@
PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
PYTHON_PLATFORM = @PYTHON_PLATFORM@
PYTHON_PREFIX = @PYTHON_PREFIX@
PYTHON_SITE_PKG = @PYTHON_SITE_PKG@
PYTHON_VERSION = @PYTHON_VERSION@
RANLIB = @RANLIB@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
SPHINXBASE_CFLAGS = @SPHINXBASE_CFLAGS@
SPHINXBASE_LIBS = @SPHINXBASE_LIBS@
SPHINXBASE_SWIG = @SPHINXBASE_SWIG@
STRIP = @STRIP@
SWIG = @SWIG@
SWIG_LIB = @SWIG_LIB@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
pkgpyexecdir = @pkgpyexecdir@
pkgpythondir = @pkgpythondir@
plugindir = @plugindir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
pyexecdir = @pyexecdir@
pythondir = @pythondir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
SUBDIRS = src doc model include test swig
EXTRA_DIST = \
autogen.sh \
m4/pkg.m4 \
pocketsphinx.pc.in \
pocketsphinx.sln \
win32/pocketsphinx/pocketsphinx.vcxproj \
win32/pocketsphinx/pocketsphinx.vcxproj.filters \
win32/pocketsphinx_batch/pocketsphinx_batch.vcxproj \
win32/pocketsphinx_continuous/pocketsphinx_continuous.vcxproj \
win32/pocketsphinx_mdef_convert/pocketsphinx_mdef_convert.vcxproj
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = pocketsphinx.pc
CLEANFILES = pocketsphinx.pc
ACLOCAL_AMFLAGS = -I m4
all: 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) --foreign'; \
$(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \
&& exit 0; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign Makefile
.PRECIOUS: 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):
pocketsphinx.pc: $(top_builddir)/config.status $(srcdir)/pocketsphinx.pc.in
cd $(top_builddir) && $(SHELL) ./config.status $@
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
distclean-libtool:
-rm -f libtool config.lt
install-pkgconfigDATA: $(pkgconfig_DATA)
@$(NORMAL_INSTALL)
@list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \
if test -n "$$list"; then \
echo " $(MKDIR_P) '$(DESTDIR)$(pkgconfigdir)'"; \
$(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)" || exit 1; \
fi; \
for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
echo "$$d$$p"; \
done | $(am__base_list) | \
while read files; do \
echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgconfigdir)'"; \
$(INSTALL_DATA) $$files "$(DESTDIR)$(pkgconfigdir)" || exit $$?; \
done
uninstall-pkgconfigDATA:
@$(NORMAL_UNINSTALL)
@list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
dir='$(DESTDIR)$(pkgconfigdir)'; $(am__uninstall_files_from_dir)
# 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
tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
$(am__post_remove_distdir)
dist-shar: distdir
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)/_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 \
&& ../configure --srcdir=.. --prefix="$$dc_install_base" \
$(AM_DISTCHECK_CONFIGURE_FLAGS) \
$(DISTCHECK_CONFIGURE_FLAGS) \
&& $(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 $(DATA)
installdirs: installdirs-recursive
installdirs-am:
for dir in "$(DESTDIR)$(pkgconfigdir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
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:
-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
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-libtool \
distclean-tags
dvi: dvi-recursive
dvi-am:
html: html-recursive
html-am:
info: info-recursive
info-am:
install-data-am: install-pkgconfigDATA
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: uninstall-pkgconfigDATA
.MAKE: $(am__recursive_targets) 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-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-pkgconfigDATA 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 uninstall-pkgconfigDATA
# 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:

View File

@ -0,0 +1,49 @@
Pocketsphinx 0.8
^^^^^^^^^^^^^^^^
Thanks: Tanel Alumae, Douglas Bagnall, Halle Winkler, Peter Grasch, Vyacheslav Klimkov
Erik Andresen, Nicola Murino, Melmahdy, Scott Silliman, Riccardo Magliocchetti, Marc Legendre,
Kho-And-Mica, Zheng6822, Pankaj Pailwar, Evandro Gouvea
Improvements:
* API is better exposed in Python, SWIG and gstreamer
* New API for exact grammar match
* Configurable type for the frame counter, allows utterances way longer than 5 minutes
Fixes:
* Memory leaks, refcounting and other memory-related issues
* Use proper word bounary senones for the words added on the fly
* Accurate FSG lextree construction
Pocketsphinx 0.7
^^^^^^^^^^^^^^^^
Thanks: David Huggins-Daines, Chen Tao, creative64, Edwin Miguel, Bhiksha Raj
Improvements:
* Nice performance improvements
* Use arc iterators to build FSG lextrees, speeds this up immensely
* Filler word propagation is responsible for 5% speedup
* Continuous decoder can decode files, not from the microphone
* Add senone score dumping and reloading capability
* Functional alignment pass
* Symbian support
* Add the Android makefile and other JNI stuff
* Case sensitive names, including phone names
* Better error messages
* Report timing for individual search passes
Bug fixes:
* Accuracy regression fixes
* Fixes the bug with reading transition matrix on big-endian platforms
* Fixes very important regression with NULL transitions in fsg search
* Proper acoustic score scaling during posterior calculation.
And many, many, many more intersting things!
Pocketsphinx pre
^^^^^^^^^^^^^^^^
2000-01-27 CMU Sphinx is going Open Source!

View File

@ -0,0 +1,90 @@
PocketSphinx 5prealpha
===============================================================================
This is PocketSphinx, one of Carnegie Mellon University's open source large
vocabulary, speaker-independent continuous speech recognition engine.
**THIS IS A RESEARCH SYSTEM**. This is also an early release of a research
system. We know the APIs and function names are likely to change, and that
several tools need to be made available to make this all complete. With your
help and contributions, this can progress in response to the needs and patches
provided.
**Please see the LICENSE file for terms of use.**
Prerequisites
-------------------------------------------------------------------------------
You **must** have SphinxBase, which you can download from
http://cmusphinx.sourceforge.net. Download and unpack it to the same parent
directory as PocketSphinx, so that the configure script and project files can
find it. On Windows, you will need to rename 'sphinxbase-X.Y' (where X.Y is the
SphinxBase version number) to simply 'sphinxbase' for this to work.
Linux/Unix installation
------------------------------------------------------------------------------
In a unix-like environment (such as linux, solaris etc):
* Build and optionally install SphinxBase. If you want to use
fixed-point arithmetic, you **must** configure SphinxBase with the
`--enable-fixed` option.
* If you downloaded directly from the CVS repository, you need to do
this at least once to generate the "configure" file:
```
$ ./autogen.sh
```
* If you downloaded the release version, or ran `autogen.sh` at least
once, then compile and install:
```
$ ./configure
$ make clean all
$ make check
$ sudo make install
```
XCode Installation (for iPhone)
------------------------------------------------------------------------------
Pocketsphinx uses the standard unix autogen system, you can build pocketsphinx
with automake given you already built sphinxbase You just need to pass correct
configure arguments, set compiler path, set sysroot and other options. After
you build the code you need to import dylib file into your project and you also
need to configure includes for your project to find sphinxbase headers.
You also will have to create a recorder to capture audio with CoreAudio and
feed it into the recognizer.
For details see http://github.com/cmusphinx/pocketsphinx-ios-demo
If you want to quickly start with Pocketsphinx, try OpenEars toolkit which
includes Pocketsphinx http://www.politepix.com/openears/
Android installation
------------------------------------------------------------------------------
See http://github.com/cmusphinx/pocketsphinx-android-demo.
MS Windows™ (MS Visual Studio 2010 (or newer - we test with VC++ 2010 Express)
------------------------------------------------------------------------------
* load sphinxbase.sln located in sphinxbase directory
* compile all the projects in SphinxBase (from sphinxbase.sln)
* load pocketsphinx.sln in pocketsphinx directory
* compile all the projects in PocketSphinx
MS Visual Studio will build the executables under .\bin\Release or
.\bin\Debug (depending on the version you choose on MS Visual Studio),
and the libraries under .\lib\Release or .\lib\Build.
Test scripts are forthcoming for Windows.
For up-to-date information, see http://cmusphinx.sourceforge.net.

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,112 @@
#!/bin/sh
# Run this to generate all the initial makefiles, etc.
srcdir=`dirname $0`
PKG_NAME="the package."
DIE=0
# Check tools
(autoconf --version) < /dev/null > /dev/null 2>&1 || {
echo
echo "**Error**: You must have \`autoconf' installed to."
echo "Download the appropriate package for your distribution,"
echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/"
DIE=1
}
(grep "^LT_INIT" $srcdir/configure.ac >/dev/null) && {
if libtoolize --version </dev/null >/dev/null 2>&1; then
LIBTOOLIZE=libtoolize
elif glibtoolize --version </dev/null >/dev/null 2>&1; then
LIBTOOLIZE=glibtoolize
else
echo
echo "**Error**: You must have \`libtool' installed."
echo "Get ftp://ftp.gnu.org/pub/gnu/libtool/libtool-2.2.6b.tar.gz"
echo "(or a newer version if it is available)"
DIE=1
fi
}
(automake --version) < /dev/null > /dev/null 2>&1 || {
echo
echo "**Error**: You must have \`automake' installed."
echo "Get ftp://ftp.gnu.org/pub/gnu/automake/automake-1.11.tar.gz"
echo "(or a newer version if it is available)"
DIE=1
NO_AUTOMAKE=yes
}
# if no automake, don't bother testing for aclocal
test -n "$NO_AUTOMAKE" || (aclocal --version) < /dev/null > /dev/null 2>&1 || {
echo
echo "**Error**: Missing \`aclocal'. The version of \`automake'"
echo "installed doesn't appear recent enough."
echo "Get ftp://ftp.gnu.org/pub/gnu/automake/automake-1.11.tar.gz"
echo "(or a newer version if it is available)"
DIE=1
}
if test "$DIE" -eq 1; then
exit 1
fi
if test -z "$*"; then
echo "**Warning**: I am going to run \`configure' with no arguments."
echo "If you wish to pass any to it, please specify them on the"
echo \`$0\'" command line."
echo
fi
case $CC in
xlc )
am_opt=--include-deps;;
esac
for coin in `find $srcdir -name configure.ac -print`
do
dr=`dirname $coin`
if test -f $dr/NO-AUTO-GEN; then
echo skipping $dr -- flagged as no auto-gen
else
echo processing $dr
macrodirs=`sed -n -e 's,AM_ACLOCAL_INCLUDE(\(.*\)),\1,gp' < $coin`
( cd $dr
aclocalinclude="$ACLOCAL_FLAGS"
for k in $macrodirs; do
if test -d $k; then
aclocalinclude="$aclocalinclude -I $k"
##else
## echo "**Warning**: No such directory \`$k'. Ignored."
fi
done
if grep "^LT_INIT" configure.ac >/dev/null; then
echo "Running $LIBTOOLIZE..."
$LIBTOOLIZE --force --copy
fi
echo "Running aclocal $aclocalinclude ..."
aclocal -I m4 $aclocalinclude
if grep "^AC_CONFIG_HEADER" configure.ac >/dev/null; then
echo "Running autoheader..."
autoheader
fi
echo "Running automake --foreign --copy $am_opt ..."
automake --add-missing --foreign --copy $am_opt
echo "Running autoconf ..."
autoconf
)
fi
done
#conf_flags="--enable-maintainer-mode --enable-compile-warnings" #--enable-iso-c
if test x$NOCONFIGURE = x; then
echo Running $srcdir/configure $conf_flags "$@" ...
$srcdir/configure $conf_flags "$@" \
&& echo Now type \`make\' to compile $PKG_NAME
else
echo Skipping configure process.
fi

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,165 @@
dnl Welcome to the Sphinx automated build system.
dnl try not to hurt yourself ;)
AC_INIT(pocketsphinx, 5prealpha)
AM_INIT_AUTOMAKE([no-define foreign])
AC_CONFIG_MACRO_DIR([m4])
CFLAGS=${CFLAGS:--g -O2 -Wall}
AC_CANONICAL_HOST
AC_PROG_CC
AC_WORDS_BIGENDIAN
AC_CHECK_TYPES(long long)
AC_CHECK_SIZEOF(long long)
LT_INIT
dnl
dnl Check for pkgconfig
dnl
AC_CHECK_PROG(HAVE_PKGCONFIG, pkg-config, yes, no)
dnl
dnl Check for Doxygen, and build dox if present
dnl
AC_CHECK_PROG(HAVE_DOXYGEN, doxygen, yes, no)
AM_CONDITIONAL(BUILD_DOXYGEN, test "x$HAVE_DOXYGEN" = "xyes")
dnl Check for SWIG and Python
AC_ARG_WITH(python,
AS_HELP_STRING([--with-python],
[Enable Python extension, built with swig, enabled by default]))
if test "x${with_python}" != "xno"; then
AM_PATH_PYTHON(2.6, [], [AC_MSG_ERROR([python not found])])
AX_PYTHON_DEVEL()
AX_PKG_SWIG(2.0, [], [AC_MSG_ERROR([swig not found])])
fi
AC_SUBST([PYTHON_CPPFLAGS])
AM_CONDITIONAL(BUILD_SWIG, test "x$SWIG" != "x")
dnl swig python check
dnl
dnl Now check for GStreamer, and build the plugin if it's available
dnl
GST_MAJORMINOR=1.0
PKG_CHECK_MODULES(GStreamer, [gstreamer-$GST_MAJORMINOR >= 1.0
gstreamer-base-$GST_MAJORMINOR >= 1.0
gstreamer-plugins-base-$GST_MAJORMINOR >= 1.0],
HAVE_GST=yes, HAVE_GST=no)
dnl Don't build GStreamer when cross-compiling
AM_CONDITIONAL(BUILD_GST, test x$cross_compiling != xyes && test "x$HAVE_GST" = "xyes")
GST_CFLAGS="$GStreamer_CFLAGS $GStreamer_ERROR"
GST_LIBS="$GStreamer_LIBS"
AC_SUBST(GST_MAJORMINOR)
AC_SUBST(GST_CFLAGS)
AC_SUBST(GST_LIBS)
dnl set the plugindir where plugins should be installed
if test "x${prefix}" = "x$HOME"; then
plugindir="$HOME/.gstreamer-$GST_MAJORMINOR/plugins"
else
plugindir="\$(libdir)/gstreamer-$GST_MAJORMINOR"
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)
dnl
dnl Get SphinxBase from command line if given
dnl
AC_ARG_WITH(sphinxbase,
AS_HELP_STRING([--with-sphinxbase=DIRECTORY],
[Look for SphinxBase installation in DIRECTORY. If this is 'auto',
the system-wide installation will be used.]),
sphinxbase=$withval)
dnl
dnl Check for SphinxBase in parent directories
dnl
if test x$sphinxbase = x; then
dn=`dirname $0`
case "$dn" in
.)
sbdir="`pwd`/.."
;;
[\\/]* | ?:[\\/]*)
sbdir="$dn/.."
;;
*)
sbdir="`pwd`/$dn/.."
;;
esac
# Look for sphinxbase in the parent directory
for sb in "$sbdir/sphinxbase" \
"$sbdir/sphinxbase"*; do
AC_MSG_CHECKING([for sphinxbase in $sb])
if test -f "$sb/src/libsphinxbase/libsphinxbase.la"; then
sphinxbase="$sb"
AC_MSG_RESULT(yes)
break
else
AC_MSG_RESULT(no)
fi
done
fi
dnl
dnl Check for system SphinxBase if none was passed to us
dnl Also allow --with-sphinxbase=auto to use system one explicitly
dnl
if test x$sphinxbase = x || test x$sphinxbase = xauto; then
sphinxbase=
if test "x$HAVE_PKGCONFIG" = "xno"; then
SPHINXBASE_CFLAGS = "-I/usr/include/sphinxbase -I/usr/local/include/sphinxbase"
SPHINXBASE_LIBS = "-lsphinxbase"
SPHINXBASE_PREFIX="/usr/local"
else
PKG_CHECK_MODULES(SPHINXBASE, [sphinxbase],,[
AC_MSG_FAILURE(dnl
[SphinxBase was not found on your system.
Make sure that you have installed it and that the
PKG_CONFIG_PATH environment variable is set correctly, if
it was installed in a non-standard prefix.])])
SPHINXBASE_PREFIX=`pkg-config --variable=prefix sphinxbase`
fi
LIBS="$LIBS $SPHINXBASE_LIBS"
CPPFLAGS="$CPPFLAGS $SPHINXBASE_CFLAGS"
SPHINXBASE_SWIG="$SPHINXBASE_PREFIX/share/sphinxbase/swig"
AC_CHECK_HEADER(sphinx_config.h,,[AC_MSG_FAILURE([SphinxBase was not found on your system.])])
else
LIBS="$LIBS -lsphinxbase"
LDFLAGS="$LDFLAGS -L$sphinxbase/lib -L$sphinxbase/src/libsphinxad -L$sphinxbase/src/libsphinxbase"
CPPFLAGS="$CPPFLAGS -I$sphinxbase/include -I$sphinxbase/include/sphinxbase"
SPHINXBASE_SWIG="$sphinxbase/swig"
fi
AC_SUBST(SPHINXBASE_SWIG)
AC_OUTPUT([
pocketsphinx.pc
Makefile
include/Makefile
src/Makefile
swig/Makefile
swig/python/Makefile
swig/python/test/Makefile
src/libpocketsphinx/Makefile
src/programs/Makefile
src/gst-plugin/Makefile
doc/Makefile
doc/doxyfile
model/Makefile
test/Makefile
test/testfuncs.sh
test/unit/Makefile
test/regression/Makefile
])

View File

@ -0,0 +1,791 @@
#! /bin/sh
# depcomp - compile a program generating dependencies as side-effects
scriptversion=2013-05-30.07; # UTC
# Copyright (C) 1999-2013 Free Software Foundation, Inc.
# 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 <http://www.gnu.org/licenses/>.
# 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.
# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
case $1 in
'')
echo "$0: No command. Try '$0 --help' for more information." 1>&2
exit 1;
;;
-h | --h*)
cat <<\EOF
Usage: depcomp [--help] [--version] PROGRAM [ARGS]
Run PROGRAMS ARGS to compile a file, generating dependencies
as side-effects.
Environment variables:
depmode Dependency tracking mode.
source Source file read by 'PROGRAMS ARGS'.
object Object file output by 'PROGRAMS ARGS'.
DEPDIR directory where to store dependencies.
depfile Dependency file to output.
tmpdepfile Temporary file to use when outputting dependencies.
libtool Whether libtool is used (yes/no).
Report bugs to <bug-automake@gnu.org>.
EOF
exit $?
;;
-v | --v*)
echo "depcomp $scriptversion"
exit $?
;;
esac
# Get the directory component of the given path, and save it in the
# global variables '$dir'. Note that this directory component will
# be either empty or ending with a '/' character. This is deliberate.
set_dir_from ()
{
case $1 in
*/*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;;
*) dir=;;
esac
}
# Get the suffix-stripped basename of the given path, and save it the
# global variable '$base'.
set_base_from ()
{
base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'`
}
# If no dependency file was actually created by the compiler invocation,
# we still have to create a dummy depfile, to avoid errors with the
# Makefile "include basename.Plo" scheme.
make_dummy_depfile ()
{
echo "#dummy" > "$depfile"
}
# Factor out some common post-processing of the generated depfile.
# Requires the auxiliary global variable '$tmpdepfile' to be set.
aix_post_process_depfile ()
{
# If the compiler actually managed to produce a dependency file,
# post-process it.
if test -f "$tmpdepfile"; then
# Each line is of the form 'foo.o: dependency.h'.
# Do two passes, one to just change these to
# $object: dependency.h
# and one to simply output
# dependency.h:
# which is needed to avoid the deleted-header problem.
{ sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile"
sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile"
} > "$depfile"
rm -f "$tmpdepfile"
else
make_dummy_depfile
fi
}
# A tabulation character.
tab=' '
# A newline character.
nl='
'
# Character ranges might be problematic outside the C locale.
# These definitions help.
upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ
lower=abcdefghijklmnopqrstuvwxyz
digits=0123456789
alpha=${upper}${lower}
if test -z "$depmode" || test -z "$source" || test -z "$object"; then
echo "depcomp: Variables source, object and depmode must be set" 1>&2
exit 1
fi
# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
depfile=${depfile-`echo "$object" |
sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
rm -f "$tmpdepfile"
# Avoid interferences from the environment.
gccflag= dashmflag=
# Some modes work just like other modes, but use different flags. We
# parameterize here, but still list the modes in the big case below,
# to make depend.m4 easier to write. Note that we *cannot* use a case
# here, because this file can only contain one case statement.
if test "$depmode" = hp; then
# HP compiler uses -M and no extra arg.
gccflag=-M
depmode=gcc
fi
if test "$depmode" = dashXmstdout; then
# This is just like dashmstdout with a different argument.
dashmflag=-xM
depmode=dashmstdout
fi
cygpath_u="cygpath -u -f -"
if test "$depmode" = msvcmsys; then
# This is just like msvisualcpp but w/o cygpath translation.
# Just convert the backslash-escaped backslashes to single forward
# slashes to satisfy depend.m4
cygpath_u='sed s,\\\\,/,g'
depmode=msvisualcpp
fi
if test "$depmode" = msvc7msys; then
# This is just like msvc7 but w/o cygpath translation.
# Just convert the backslash-escaped backslashes to single forward
# slashes to satisfy depend.m4
cygpath_u='sed s,\\\\,/,g'
depmode=msvc7
fi
if test "$depmode" = xlc; then
# IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information.
gccflag=-qmakedep=gcc,-MF
depmode=gcc
fi
case "$depmode" in
gcc3)
## gcc 3 implements dependency tracking that does exactly what
## we want. Yay! Note: for some reason libtool 1.4 doesn't like
## it if -MD -MP comes after the -MF stuff. Hmm.
## Unfortunately, FreeBSD c89 acceptance of flags depends upon
## the command line argument order; so add the flags where they
## appear in depend2.am. Note that the slowdown incurred here
## affects only configure: in makefiles, %FASTDEP% shortcuts this.
for arg
do
case $arg in
-c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;;
*) set fnord "$@" "$arg" ;;
esac
shift # fnord
shift # $arg
done
"$@"
stat=$?
if test $stat -ne 0; then
rm -f "$tmpdepfile"
exit $stat
fi
mv "$tmpdepfile" "$depfile"
;;
gcc)
## Note that this doesn't just cater to obsosete pre-3.x GCC compilers.
## but also to in-use compilers like IMB xlc/xlC and the HP C compiler.
## (see the conditional assignment to $gccflag above).
## There are various ways to get dependency output from gcc. Here's
## why we pick this rather obscure method:
## - Don't want to use -MD because we'd like the dependencies to end
## up in a subdir. Having to rename by hand is ugly.
## (We might end up doing this anyway to support other compilers.)
## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
## -MM, not -M (despite what the docs say). Also, it might not be
## supported by the other compilers which use the 'gcc' depmode.
## - Using -M directly means running the compiler twice (even worse
## than renaming).
if test -z "$gccflag"; then
gccflag=-MD,
fi
"$@" -Wp,"$gccflag$tmpdepfile"
stat=$?
if test $stat -ne 0; then
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
echo "$object : \\" > "$depfile"
# The second -e expression handles DOS-style file names with drive
# letters.
sed -e 's/^[^:]*: / /' \
-e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
## This next piece of magic avoids the "deleted header file" problem.
## The problem is that when a header file which appears in a .P file
## is deleted, the dependency causes make to die (because there is
## typically no way to rebuild the header). We avoid this by adding
## dummy dependencies for each header file. Too bad gcc doesn't do
## this for us directly.
## Some versions of gcc put a space before the ':'. On the theory
## that the space means something, we add a space to the output as
## well. hp depmode also adds that space, but also prefixes the VPATH
## to the object. Take care to not repeat it in the output.
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
tr ' ' "$nl" < "$tmpdepfile" \
| sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \
| sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
hp)
# This case exists only to let depend.m4 do its work. It works by
# looking at the text of this script. This case will never be run,
# since it is checked for above.
exit 1
;;
sgi)
if test "$libtool" = yes; then
"$@" "-Wp,-MDupdate,$tmpdepfile"
else
"$@" -MDupdate "$tmpdepfile"
fi
stat=$?
if test $stat -ne 0; then
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files
echo "$object : \\" > "$depfile"
# Clip off the initial element (the dependent). Don't try to be
# clever and replace this with sed code, as IRIX sed won't handle
# lines with more than a fixed number of characters (4096 in
# IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines;
# the IRIX cc adds comments like '#:fec' to the end of the
# dependency line.
tr ' ' "$nl" < "$tmpdepfile" \
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \
| tr "$nl" ' ' >> "$depfile"
echo >> "$depfile"
# The second pass generates a dummy entry for each header file.
tr ' ' "$nl" < "$tmpdepfile" \
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
>> "$depfile"
else
make_dummy_depfile
fi
rm -f "$tmpdepfile"
;;
xlc)
# This case exists only to let depend.m4 do its work. It works by
# looking at the text of this script. This case will never be run,
# since it is checked for above.
exit 1
;;
aix)
# The C for AIX Compiler uses -M and outputs the dependencies
# in a .u file. In older versions, this file always lives in the
# current directory. Also, the AIX compiler puts '$object:' at the
# start of each line; $object doesn't have directory information.
# Version 6 uses the directory in both cases.
set_dir_from "$object"
set_base_from "$object"
if test "$libtool" = yes; then
tmpdepfile1=$dir$base.u
tmpdepfile2=$base.u
tmpdepfile3=$dir.libs/$base.u
"$@" -Wc,-M
else
tmpdepfile1=$dir$base.u
tmpdepfile2=$dir$base.u
tmpdepfile3=$dir$base.u
"$@" -M
fi
stat=$?
if test $stat -ne 0; then
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
exit $stat
fi
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
do
test -f "$tmpdepfile" && break
done
aix_post_process_depfile
;;
tcc)
# tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26
# FIXME: That version still under development at the moment of writing.
# Make that this statement remains true also for stable, released
# versions.
# It will wrap lines (doesn't matter whether long or short) with a
# trailing '\', as in:
#
# foo.o : \
# foo.c \
# foo.h \
#
# It will put a trailing '\' even on the last line, and will use leading
# spaces rather than leading tabs (at least since its commit 0394caf7
# "Emit spaces for -MD").
"$@" -MD -MF "$tmpdepfile"
stat=$?
if test $stat -ne 0; then
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
# Each non-empty line is of the form 'foo.o : \' or ' dep.h \'.
# We have to change lines of the first kind to '$object: \'.
sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile"
# And for each line of the second kind, we have to emit a 'dep.h:'
# dummy dependency, to avoid the deleted-header problem.
sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile"
rm -f "$tmpdepfile"
;;
## The order of this option in the case statement is important, since the
## shell code in configure will try each of these formats in the order
## listed in this file. A plain '-MD' option would be understood by many
## compilers, so we must ensure this comes after the gcc and icc options.
pgcc)
# Portland's C compiler understands '-MD'.
# Will always output deps to 'file.d' where file is the root name of the
# source file under compilation, even if file resides in a subdirectory.
# The object file name does not affect the name of the '.d' file.
# pgcc 10.2 will output
# foo.o: sub/foo.c sub/foo.h
# and will wrap long lines using '\' :
# foo.o: sub/foo.c ... \
# sub/foo.h ... \
# ...
set_dir_from "$object"
# Use the source, not the object, to determine the base name, since
# that's sadly what pgcc will do too.
set_base_from "$source"
tmpdepfile=$base.d
# For projects that build the same source file twice into different object
# files, the pgcc approach of using the *source* file root name can cause
# problems in parallel builds. Use a locking strategy to avoid stomping on
# the same $tmpdepfile.
lockdir=$base.d-lock
trap "
echo '$0: caught signal, cleaning up...' >&2
rmdir '$lockdir'
exit 1
" 1 2 13 15
numtries=100
i=$numtries
while test $i -gt 0; do
# mkdir is a portable test-and-set.
if mkdir "$lockdir" 2>/dev/null; then
# This process acquired the lock.
"$@" -MD
stat=$?
# Release the lock.
rmdir "$lockdir"
break
else
# If the lock is being held by a different process, wait
# until the winning process is done or we timeout.
while test -d "$lockdir" && test $i -gt 0; do
sleep 1
i=`expr $i - 1`
done
fi
i=`expr $i - 1`
done
trap - 1 2 13 15
if test $i -le 0; then
echo "$0: failed to acquire lock after $numtries attempts" >&2
echo "$0: check lockdir '$lockdir'" >&2
exit 1
fi
if test $stat -ne 0; then
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
# Each line is of the form `foo.o: dependent.h',
# or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
# Do two passes, one to just change these to
# `$object: dependent.h' and one to simply `dependent.h:'.
sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
# Some versions of the HPUX 10.20 sed can't process this invocation
# correctly. Breaking it into two sed invocations is a workaround.
sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \
| sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
hp2)
# The "hp" stanza above does not work with aCC (C++) and HP's ia64
# compilers, which have integrated preprocessors. The correct option
# to use with these is +Maked; it writes dependencies to a file named
# 'foo.d', which lands next to the object file, wherever that
# happens to be.
# Much of this is similar to the tru64 case; see comments there.
set_dir_from "$object"
set_base_from "$object"
if test "$libtool" = yes; then
tmpdepfile1=$dir$base.d
tmpdepfile2=$dir.libs/$base.d
"$@" -Wc,+Maked
else
tmpdepfile1=$dir$base.d
tmpdepfile2=$dir$base.d
"$@" +Maked
fi
stat=$?
if test $stat -ne 0; then
rm -f "$tmpdepfile1" "$tmpdepfile2"
exit $stat
fi
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2"
do
test -f "$tmpdepfile" && break
done
if test -f "$tmpdepfile"; then
sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile"
# Add 'dependent.h:' lines.
sed -ne '2,${
s/^ *//
s/ \\*$//
s/$/:/
p
}' "$tmpdepfile" >> "$depfile"
else
make_dummy_depfile
fi
rm -f "$tmpdepfile" "$tmpdepfile2"
;;
tru64)
# The Tru64 compiler uses -MD to generate dependencies as a side
# effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'.
# At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
# dependencies in 'foo.d' instead, so we check for that too.
# Subdirectories are respected.
set_dir_from "$object"
set_base_from "$object"
if test "$libtool" = yes; then
# Libtool generates 2 separate objects for the 2 libraries. These
# two compilations output dependencies in $dir.libs/$base.o.d and
# in $dir$base.o.d. We have to check for both files, because
# one of the two compilations can be disabled. We should prefer
# $dir$base.o.d over $dir.libs/$base.o.d because the latter is
# automatically cleaned when .libs/ is deleted, while ignoring
# the former would cause a distcleancheck panic.
tmpdepfile1=$dir$base.o.d # libtool 1.5
tmpdepfile2=$dir.libs/$base.o.d # Likewise.
tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504
"$@" -Wc,-MD
else
tmpdepfile1=$dir$base.d
tmpdepfile2=$dir$base.d
tmpdepfile3=$dir$base.d
"$@" -MD
fi
stat=$?
if test $stat -ne 0; then
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
exit $stat
fi
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
do
test -f "$tmpdepfile" && break
done
# Same post-processing that is required for AIX mode.
aix_post_process_depfile
;;
msvc7)
if test "$libtool" = yes; then
showIncludes=-Wc,-showIncludes
else
showIncludes=-showIncludes
fi
"$@" $showIncludes > "$tmpdepfile"
stat=$?
grep -v '^Note: including file: ' "$tmpdepfile"
if test $stat -ne 0; then
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
echo "$object : \\" > "$depfile"
# The first sed program below extracts the file names and escapes
# backslashes for cygpath. The second sed program outputs the file
# name when reading, but also accumulates all include files in the
# hold buffer in order to output them again at the end. This only
# works with sed implementations that can handle large buffers.
sed < "$tmpdepfile" -n '
/^Note: including file: *\(.*\)/ {
s//\1/
s/\\/\\\\/g
p
}' | $cygpath_u | sort -u | sed -n '
s/ /\\ /g
s/\(.*\)/'"$tab"'\1 \\/p
s/.\(.*\) \\/\1:/
H
$ {
s/.*/'"$tab"'/
G
p
}' >> "$depfile"
echo >> "$depfile" # make sure the fragment doesn't end with a backslash
rm -f "$tmpdepfile"
;;
msvc7msys)
# This case exists only to let depend.m4 do its work. It works by
# looking at the text of this script. This case will never be run,
# since it is checked for above.
exit 1
;;
#nosideeffect)
# This comment above is used by automake to tell side-effect
# dependency tracking mechanisms from slower ones.
dashmstdout)
# Important note: in order to support this mode, a compiler *must*
# always write the preprocessed file to stdout, regardless of -o.
"$@" || exit $?
# Remove the call to Libtool.
if test "$libtool" = yes; then
while test "X$1" != 'X--mode=compile'; do
shift
done
shift
fi
# Remove '-o $object'.
IFS=" "
for arg
do
case $arg in
-o)
shift
;;
$object)
shift
;;
*)
set fnord "$@" "$arg"
shift # fnord
shift # $arg
;;
esac
done
test -z "$dashmflag" && dashmflag=-M
# Require at least two characters before searching for ':'
# in the target name. This is to cope with DOS-style filenames:
# a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise.
"$@" $dashmflag |
sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile"
rm -f "$depfile"
cat < "$tmpdepfile" > "$depfile"
# Some versions of the HPUX 10.20 sed can't process this sed invocation
# correctly. Breaking it into two sed invocations is a workaround.
tr ' ' "$nl" < "$tmpdepfile" \
| sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \
| sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
dashXmstdout)
# This case only exists to satisfy depend.m4. It is never actually
# run, as this mode is specially recognized in the preamble.
exit 1
;;
makedepend)
"$@" || exit $?
# Remove any Libtool call
if test "$libtool" = yes; then
while test "X$1" != 'X--mode=compile'; do
shift
done
shift
fi
# X makedepend
shift
cleared=no eat=no
for arg
do
case $cleared in
no)
set ""; shift
cleared=yes ;;
esac
if test $eat = yes; then
eat=no
continue
fi
case "$arg" in
-D*|-I*)
set fnord "$@" "$arg"; shift ;;
# Strip any option that makedepend may not understand. Remove
# the object too, otherwise makedepend will parse it as a source file.
-arch)
eat=yes ;;
-*|$object)
;;
*)
set fnord "$@" "$arg"; shift ;;
esac
done
obj_suffix=`echo "$object" | sed 's/^.*\././'`
touch "$tmpdepfile"
${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
rm -f "$depfile"
# makedepend may prepend the VPATH from the source file name to the object.
# No need to regex-escape $object, excess matching of '.' is harmless.
sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile"
# Some versions of the HPUX 10.20 sed can't process the last invocation
# correctly. Breaking it into two sed invocations is a workaround.
sed '1,2d' "$tmpdepfile" \
| tr ' ' "$nl" \
| sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \
| sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile" "$tmpdepfile".bak
;;
cpp)
# Important note: in order to support this mode, a compiler *must*
# always write the preprocessed file to stdout.
"$@" || exit $?
# Remove the call to Libtool.
if test "$libtool" = yes; then
while test "X$1" != 'X--mode=compile'; do
shift
done
shift
fi
# Remove '-o $object'.
IFS=" "
for arg
do
case $arg in
-o)
shift
;;
$object)
shift
;;
*)
set fnord "$@" "$arg"
shift # fnord
shift # $arg
;;
esac
done
"$@" -E \
| sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
-e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
| sed '$ s: \\$::' > "$tmpdepfile"
rm -f "$depfile"
echo "$object : \\" > "$depfile"
cat < "$tmpdepfile" >> "$depfile"
sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
msvisualcpp)
# Important note: in order to support this mode, a compiler *must*
# always write the preprocessed file to stdout.
"$@" || exit $?
# Remove the call to Libtool.
if test "$libtool" = yes; then
while test "X$1" != 'X--mode=compile'; do
shift
done
shift
fi
IFS=" "
for arg
do
case "$arg" in
-o)
shift
;;
$object)
shift
;;
"-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
set fnord "$@"
shift
shift
;;
*)
set fnord "$@" "$arg"
shift
shift
;;
esac
done
"$@" -E 2>/dev/null |
sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile"
rm -f "$depfile"
echo "$object : \\" > "$depfile"
sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile"
echo "$tab" >> "$depfile"
sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile"
rm -f "$tmpdepfile"
;;
msvcmsys)
# This case exists only to let depend.m4 do its work. It works by
# looking at the text of this script. This case will never be run,
# since it is checked for above.
exit 1
;;
none)
exec "$@"
;;
*)
echo "Unknown depmode $depmode" 1>&2
exit 1
;;
esac
exit 0
# 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:

View File

@ -0,0 +1,52 @@
man_MANS = \
pocketsphinx_batch.1 \
pocketsphinx_continuous.1 \
pocketsphinx_mdef_convert.1
EXTRA_DIST = \
args2man.pl \
doxy2swig.py \
pocketsphinx_batch.1.in \
pocketsphinx_continuous.1.in \
pocketsphinx_batch.1 \
pocketsphinx_continuous.1 \
pocketsphinx_mdef_convert.1
# pocketsphinx_batch.1: pocketsphinx_batch.1.in
# $(srcdir)/args2man.pl $(top_builddir)/src/programs/pocketsphinx_batch \
# < $< > $@
# pocketsphinx_continuous.1: pocketsphinx_continuous.1.in
# $(srcdir)/args2man.pl $(top_builddir)/src/programs/pocketsphinx_continuous \
# < $< > $@
if BUILD_SWIG
SWIG_DOC = pydoc.i
pydoc.i: html/index.html
$(PYTHON) $(srcdir)/doxy2swig.py -n xml/index.xml pydoc.i
endif
if BUILD_DOXYGEN
all-local: html/index.html $(SWIG_DOC)
endif
headers = \
$(top_srcdir)/include/pocketsphinx.h \
$(top_srcdir)/include/ps_lattice.h \
$(top_srcdir)/include/ps_mllr.h \
$(top_srcdir)/include/ps_search.h
latex/refman.pdf: doxyfile $(headers)
doxygen
$(MAKE) -C latex refman.pdf
html/index.html: doxyfile $(headers)
doxygen
clean-local:
-rm -rf html xml latex doxytags $(SWIG_DOC)
# Totally CMU-specific rule for uploading documentation
upload: html/index.html
rsync -av html/ file:/usr12/apache2/htdocs/sphinx/doc/doxygen/pocketsphinx/

View File

@ -0,0 +1,583 @@
# Makefile.in generated by automake 1.13.4 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2013 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.
@SET_MAKE@
VPATH = @srcdir@
am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
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)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
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 = @build@
host_triplet = @host@
subdir = doc
DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
$(srcdir)/doxyfile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_pkg_swig.m4 \
$(top_srcdir)/m4/ax_python_devel.m4 \
$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
$(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/pkg.m4 \
$(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
CONFIG_CLEAN_FILES = doxyfile
CONFIG_CLEAN_VPATH_FILES =
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false
am__v_P_1 = :
AM_V_GEN = $(am__v_GEN_@AM_V@)
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
am__v_GEN_0 = @echo " GEN " $@;
am__v_GEN_1 =
AM_V_at = $(am__v_at_@AM_V@)
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
am__v_at_0 = @
am__v_at_1 =
SOURCES =
DIST_SOURCES =
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
*) (install-info --version) >/dev/null 2>&1;; \
esac
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; }; \
}
man1dir = $(mandir)/man1
am__installdirs = "$(DESTDIR)$(man1dir)"
NROFF = nroff
MANS = $(man_MANS)
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GREP = @GREP@
GST_CFLAGS = @GST_CFLAGS@
GST_LIBS = @GST_LIBS@
GST_MAJORMINOR = @GST_MAJORMINOR@
GST_PLUGIN_LDFLAGS = @GST_PLUGIN_LDFLAGS@
GStreamer_CFLAGS = @GStreamer_CFLAGS@
GStreamer_LIBS = @GStreamer_LIBS@
HAVE_DOXYGEN = @HAVE_DOXYGEN@
HAVE_PKGCONFIG = @HAVE_PKGCONFIG@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LD = @LD@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PKG_CONFIG = @PKG_CONFIG@
PYTHON = @PYTHON@
PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@
PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@
PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@
PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
PYTHON_PLATFORM = @PYTHON_PLATFORM@
PYTHON_PREFIX = @PYTHON_PREFIX@
PYTHON_SITE_PKG = @PYTHON_SITE_PKG@
PYTHON_VERSION = @PYTHON_VERSION@
RANLIB = @RANLIB@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
SPHINXBASE_CFLAGS = @SPHINXBASE_CFLAGS@
SPHINXBASE_LIBS = @SPHINXBASE_LIBS@
SPHINXBASE_SWIG = @SPHINXBASE_SWIG@
STRIP = @STRIP@
SWIG = @SWIG@
SWIG_LIB = @SWIG_LIB@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
pkgpyexecdir = @pkgpyexecdir@
pkgpythondir = @pkgpythondir@
plugindir = @plugindir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
pyexecdir = @pyexecdir@
pythondir = @pythondir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
man_MANS = \
pocketsphinx_batch.1 \
pocketsphinx_continuous.1 \
pocketsphinx_mdef_convert.1
EXTRA_DIST = \
args2man.pl \
doxy2swig.py \
pocketsphinx_batch.1.in \
pocketsphinx_continuous.1.in \
pocketsphinx_batch.1 \
pocketsphinx_continuous.1 \
pocketsphinx_mdef_convert.1
# pocketsphinx_batch.1: pocketsphinx_batch.1.in
# $(srcdir)/args2man.pl $(top_builddir)/src/programs/pocketsphinx_batch \
# < $< > $@
# pocketsphinx_continuous.1: pocketsphinx_continuous.1.in
# $(srcdir)/args2man.pl $(top_builddir)/src/programs/pocketsphinx_continuous \
# < $< > $@
@BUILD_SWIG_TRUE@SWIG_DOC = pydoc.i
headers = \
$(top_srcdir)/include/pocketsphinx.h \
$(top_srcdir)/include/ps_lattice.h \
$(top_srcdir)/include/ps_mllr.h \
$(top_srcdir)/include/ps_search.h
all: all-am
.SUFFIXES:
$(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) --foreign doc/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign doc/Makefile
.PRECIOUS: 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):
doxyfile: $(top_builddir)/config.status $(srcdir)/doxyfile.in
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
install-man1: $(man_MANS)
@$(NORMAL_INSTALL)
@list1=''; \
list2='$(man_MANS)'; \
test -n "$(man1dir)" \
&& test -n "`echo $$list1$$list2`" \
|| exit 0; \
echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \
$(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \
{ for i in $$list1; do echo "$$i"; done; \
if test -n "$$list2"; then \
for i in $$list2; do echo "$$i"; done \
| sed -n '/\.1[a-z]*$$/p'; \
fi; \
} | while read p; do \
if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
echo "$$d$$p"; echo "$$p"; \
done | \
sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \
-e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
sed 'N;N;s,\n, ,g' | { \
list=; while read file base inst; do \
if test "$$base" = "$$inst"; then list="$$list $$file"; else \
echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \
$(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \
fi; \
done; \
for i in $$list; do echo "$$i"; done | $(am__base_list) | \
while read files; do \
test -z "$$files" || { \
echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \
$(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \
done; }
uninstall-man1:
@$(NORMAL_UNINSTALL)
@list=''; test -n "$(man1dir)" || exit 0; \
files=`{ for i in $$list; do echo "$$i"; done; \
l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \
sed -n '/\.1[a-z]*$$/p'; \
} | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \
-e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir)
tags TAGS:
ctags CTAGS:
cscope cscopelist:
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
@BUILD_DOXYGEN_FALSE@all-local:
all-am: Makefile $(MANS) all-local
installdirs:
for dir in "$(DESTDIR)$(man1dir)"; 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-local mostlyclean-am
distclean: distclean-am
-rm -f Makefile
distclean-am: clean-am distclean-generic
dvi: dvi-am
dvi-am:
html: html-am
html-am:
info: info-am
info-am:
install-data-am: install-man
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-man1
install-pdf: install-pdf-am
install-pdf-am:
install-ps: install-ps-am
install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-generic mostlyclean-libtool
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-man
uninstall-man: uninstall-man1
.MAKE: install-am install-strip
.PHONY: all all-am all-local check check-am clean clean-generic \
clean-libtool clean-local cscopelist-am ctags-am distclean \
distclean-generic distclean-libtool 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-man1 install-pdf \
install-pdf-am install-ps install-ps-am install-strip \
installcheck installcheck-am installdirs maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-generic \
mostlyclean-libtool pdf pdf-am ps ps-am tags-am uninstall \
uninstall-am uninstall-man uninstall-man1
@BUILD_SWIG_TRUE@pydoc.i: html/index.html
@BUILD_SWIG_TRUE@ $(PYTHON) $(srcdir)/doxy2swig.py -n xml/index.xml pydoc.i
@BUILD_DOXYGEN_TRUE@all-local: html/index.html $(SWIG_DOC)
latex/refman.pdf: doxyfile $(headers)
doxygen
$(MAKE) -C latex refman.pdf
html/index.html: doxyfile $(headers)
doxygen
clean-local:
-rm -rf html xml latex doxytags $(SWIG_DOC)
# Totally CMU-specific rule for uploading documentation
upload: html/index.html
rsync -av html/ file:/usr12/apache2/htdocs/sphinx/doc/doxygen/pocketsphinx/
# 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:

View File

@ -0,0 +1,76 @@
#!/usr/bin/env perl
use strict;
use Pod::Usage;
my $program = shift;
pod2usage(2) unless defined($program);
open ARGTEXT, "$program 2>&1 |" or die "Failed to run $program: $!";
my $inargs = 0;
my @args;
while (<ARGTEXT>) {
chomp;
if (/^\[NAME/) {
$inargs = 1;
next;
}
next unless $inargs;
last if /^\s*$/;
my ($name, $deflt, $descr) = /^(\S+)\s+(\S+)\s+(.*)$/;
push @args, [$name, $deflt, $descr];
}
die "No arguments found!" unless @args;
while (<>) {
if (/\.\\\" ### ARGUMENTS ###/) {
foreach (@args) {
my ($name, $deflt, $descr) = @$_;
$name =~ s/-/\\-/g;
$descr =~ s/ (-\S+)/ \\fB\\$1\\fR/g;
print <<"EOA";
.TP
.B $name
$descr
EOA
}
}
else {
print;
}
}
__END__
=head1 NAME
sphinx_args2man - Generate manual pages from the output of Sphinx programs
=head1 SYNOPSIS
B<sphinx_args2man> I<PROGRAM> E<lt> I<TEMPLATE> E<gt> I<OUTPUT>
=head1 DESCRIPTION
This program runs a Sphinx program I<PROGRAM>, reads a template file
from standard input, and writes a manual page in L<man(7)> format to
standard output.
The template file is a manual page in L<man(7)> format, containing a
comment line of the form:
.\" ### ARGUMENTS ###
Which will be replaced in the output with the arguments and their
descriptions from I<PROGRAM>.
=head1 AUTHOR
David Huggins-Daines <dhuggins@cs.cmu.edu>
=head1 COPYRIGHT
Copyright (c) 2007 Carnegie Mellon University. You may copy and
distribute this file under the same conditions as the rest of
PocketSphinx. See the file COPYING for more information.
=cut

View File

@ -0,0 +1,480 @@
#!/usr/bin/env python
"""Doxygen XML to SWIG docstring converter.
Usage:
doxy2swig.py [options] input.xml output.i
Converts Doxygen generated XML files into a file containing docstrings
that can be used by SWIG-1.3.x. Note that you need to get SWIG
version > 1.3.23 or use Robin Dunn's docstring patch to be able to use
the resulting output.
input.xml is your doxygen generated XML file and output.i is where the
output will be written (the file will be clobbered).
"""
######################################################################
#
# This code is implemented using Mark Pilgrim's code as a guideline:
# http://www.faqs.org/docs/diveintopython/kgp_divein.html
#
# Author: Prabhu Ramachandran
# License: BSD style
#
# Thanks:
# Johan Hake: the include_function_definition feature
# Bill Spotz: bug reports and testing.
# Sebastian Henschel: Misc. enhancements.
#
######################################################################
from xml.dom import minidom
import re
import textwrap
import sys
import types
import os.path
import optparse
# TODO: do not process unnecessary files
TYPEMAP = {
'ps_decoder_t': ('Decoder', 'ps_'),
'ps_lattice_t': ('Lattice', 'ps_lattice_'),
'ps_nbest_t': ('NBest', 'ps_nbest_'),
'ps_seg_t': ('Segment', 'ps_seg_')
}
USE_PREFIXES = [
'ps_',
]
def my_open_read(source):
if hasattr(source, "read"):
return source
else:
return open(source)
def my_open_write(dest):
if hasattr(dest, "write"):
return dest
else:
return open(dest, 'w')
class Doxy2SWIG:
"""Converts Doxygen generated XML files into a file containing
docstrings that can be used by SWIG-1.3.x that have support for
feature("docstring"). Once the data is parsed it is stored in
self.pieces.
"""
def __init__(self, src, include_function_definition=True, quiet=False):
"""Initialize the instance given a source object. `src` can
be a file or filename. If you do not want to include function
definitions from doxygen then set
`include_function_definition` to `False`. This is handy since
this allows you to use the swig generated function definition
using %feature("autodoc", [0,1]).
"""
f = my_open_read(src)
self.my_dir = os.path.dirname(f.name)
self.xmldoc = minidom.parse(f).documentElement
f.close()
self.pieces = []
self.pieces.append('\n// File: %s\n'%\
os.path.basename(f.name))
self.space_re = re.compile(r'\s+')
self.lead_spc = re.compile(r'^(%feature\S+\s+\S+\s*?)"\s+(\S)')
self.multi = 0
self.ignores = ['inheritancegraph', 'param', 'listofallmembers',
'innerclass', 'name', 'declname', 'incdepgraph',
'invincdepgraph', 'programlisting', 'type',
'references', 'referencedby', 'location',
'collaborationgraph', 'reimplements',
'reimplementedby', 'derivedcompoundref',
'basecompoundref']
#self.generics = []
self.include_function_definition = include_function_definition
if not include_function_definition:
self.ignores.append('argsstring')
self.quiet = quiet
def generate(self):
"""Parses the file set in the initialization. The resulting
data is stored in `self.pieces`.
"""
self.parse(self.xmldoc)
def parse(self, node):
"""Parse a given node. This function in turn calls the
`parse_<nodeType>` functions which handle the respective
nodes.
"""
pm = getattr(self, "parse_%s"%node.__class__.__name__)
pm(node)
def parse_Document(self, node):
self.parse(node.documentElement)
def parse_Text(self, node):
txt = node.data
txt = txt.replace('\\', r'\\\\')
txt = txt.replace('"', r'\"')
# ignore pure whitespace
m = self.space_re.match(txt)
if m and len(m.group()) == len(txt):
pass
else:
self.add_text(textwrap.fill(txt, break_long_words=False))
def parse_Element(self, node):
"""Parse an `ELEMENT_NODE`. This calls specific
`do_<tagName>` handers for different elements. If no handler
is available the `generic_parse` method is called. All
tagNames specified in `self.ignores` are simply ignored.
"""
name = node.tagName
ignores = self.ignores
if name in ignores:
return
attr = "do_%s" % name
if hasattr(self, attr):
handlerMethod = getattr(self, attr)
handlerMethod(node)
else:
self.generic_parse(node)
#if name not in self.generics: self.generics.append(name)
def parse_Comment(self, node):
"""Parse a `COMMENT_NODE`. This does nothing for now."""
return
def add_text(self, value):
"""Adds text corresponding to `value` into `self.pieces`."""
if isinstance(value, tuple) or isinstance(value, list):
self.pieces.extend(value)
else:
self.pieces.append(value)
def get_specific_nodes(self, node, names):
"""Given a node and a sequence of strings in `names`, return a
dictionary containing the names as keys and child
`ELEMENT_NODEs`, that have a `tagName` equal to the name.
"""
nodes = [(x.tagName, x) for x in node.childNodes \
if x.nodeType == x.ELEMENT_NODE and \
x.tagName in names]
return dict(nodes)
def generic_parse(self, node, pad=0):
"""A Generic parser for arbitrary tags in a node.
Parameters:
- node: A node in the DOM.
- pad: `int` (default: 0)
If 0 the node data is not padded with newlines. If 1 it
appends a newline after parsing the childNodes. If 2 it
pads before and after the nodes are processed. Defaults to
0.
"""
npiece = 0
if pad:
npiece = len(self.pieces)
if pad == 2:
self.add_text('\n')
for n in node.childNodes:
self.parse(n)
if pad:
if len(self.pieces) > npiece:
self.add_text('\n')
def space_parse(self, node):
self.add_text(' ')
self.generic_parse(node)
do_ref = space_parse
do_emphasis = space_parse
do_bold = space_parse
do_computeroutput = space_parse
do_formula = space_parse
def do_compoundname(self, node):
self.add_text('\n\n')
data = node.firstChild.data
self.add_text('%%feature("docstring") %s "\n' % data)
def do_compounddef(self, node):
kind = node.attributes['kind'].value
if kind in ('class', 'struct'):
prot = node.attributes['prot'].value
if prot != 'public':
return
names = ('compoundname', 'briefdescription',
'detaileddescription', 'includes')
first = self.get_specific_nodes(node, names)
for n in names:
if first.has_key(n):
self.parse(first[n])
self.add_text(['";','\n'])
for n in node.childNodes:
if n not in first.values():
self.parse(n)
elif kind in ('file', 'namespace'):
nodes = node.getElementsByTagName('sectiondef')
for n in nodes:
self.parse(n)
def do_includes(self, node):
self.add_text('C++ includes: ')
self.generic_parse(node, pad=1)
def do_parameterlist(self, node):
text='unknown'
for key, val in node.attributes.items():
if key == 'kind':
if val == 'param': text = 'Parameters'
elif val == 'exception': text = 'Exceptions'
else: text = val
break
self.add_text(['\n', '\n', text, ':', '\n'])
self.generic_parse(node, pad=1)
def do_para(self, node):
self.add_text('\n')
self.generic_parse(node, pad=1)
def do_parametername(self, node):
self.add_text('\n')
try:
data=node.firstChild.data
except AttributeError: # perhaps a <ref> tag in it
data=node.firstChild.firstChild.data
if data.find('Exception') != -1:
self.add_text(data)
else:
self.add_text("%s: "%data)
def do_parameterdefinition(self, node):
self.generic_parse(node, pad=1)
def do_detaileddescription(self, node):
self.generic_parse(node, pad=1)
def do_briefdescription(self, node):
self.generic_parse(node, pad=1)
def do_memberdef(self, node):
prot = node.attributes['prot'].value
id = node.attributes['id'].value
kind = node.attributes['kind'].value
tmp = node.parentNode.parentNode.parentNode
compdef = tmp.getElementsByTagName('compounddef')[0]
cdef_kind = compdef.attributes['kind'].value
if prot == 'public':
first = self.get_specific_nodes(node, ('definition', 'name'))
name = first['name'].firstChild.data
for n in node.getElementsByTagName('param'):
arg_type = n.getElementsByTagName('type')[0]
ref = self.get_specific_nodes(arg_type, ('ref'))
if 'ref' in ref:
type_name = ref['ref'].firstChild.data
# TODO: check argument position
if type_name in TYPEMAP:
alias, prefix = TYPEMAP[type_name]
short_name = name.replace(prefix, '')
if not re.match(r'^\d', short_name):
name = alias + '::' + name.replace(prefix, '')
break
if name[:8] == 'operator': # Don't handle operators yet.
return
if not ('definition' in first) or \
kind in ['variable', 'typedef']:
return
if self.include_function_definition:
defn = first['definition'].firstChild.data
else:
defn = ""
self.add_text('\n')
self.add_text('%feature("docstring") ')
anc = node.parentNode.parentNode
if cdef_kind in ('file', 'namespace'):
ns_node = anc.getElementsByTagName('innernamespace')
if not ns_node and cdef_kind == 'namespace':
ns_node = anc.getElementsByTagName('compoundname')
if ns_node:
ns = ns_node[0].firstChild.data
self.add_text(' %s::%s "\n%s'%(ns, name, defn))
else:
self.add_text(' %s "\n%s'%(name, defn))
elif cdef_kind in ('class', 'struct'):
# Get the full function name.
anc_node = anc.getElementsByTagName('compoundname')
cname = anc_node[0].firstChild.data
self.add_text(' %s::%s "\n%s'%(cname, name, defn))
for n in node.childNodes:
if n not in first.values():
self.parse(n)
self.add_text(['";', '\n'])
def do_definition(self, node):
data = node.firstChild.data
self.add_text('%s "\n%s'%(data, data))
def do_sectiondef(self, node):
kind = node.attributes['kind'].value
if kind in ('public-func', 'func', 'user-defined', ''):
self.generic_parse(node)
def do_header(self, node):
"""For a user defined section def a header field is present
which should not be printed as such, so we comment it in the
output."""
data = node.firstChild.data
self.add_text('\n/*\n %s \n*/\n'%data)
# If our immediate sibling is a 'description' node then we
# should comment that out also and remove it from the parent
# node's children.
parent = node.parentNode
idx = parent.childNodes.index(node)
if len(parent.childNodes) >= idx + 2:
nd = parent.childNodes[idx+2]
if nd.nodeName == 'description':
nd = parent.removeChild(nd)
self.add_text('\n/*')
self.generic_parse(nd)
self.add_text('\n*/\n')
def do_simplesect(self, node):
kind = node.attributes['kind'].value
if kind in ('date', 'rcs', 'version'):
pass
elif kind == 'warning':
self.add_text(['\n', 'WARNING: '])
self.generic_parse(node)
elif kind == 'see':
self.add_text('\n')
self.add_text('See: ')
self.generic_parse(node)
else:
self.generic_parse(node)
def do_argsstring(self, node):
self.generic_parse(node, pad=1)
def do_member(self, node):
kind = node.attributes['kind'].value
refid = node.attributes['refid'].value
if kind == 'function' and refid[:9] == 'namespace':
self.generic_parse(node)
def do_doxygenindex(self, node):
self.multi = 1
comps = node.getElementsByTagName('compound')
for c in comps:
refid = c.attributes['refid'].value
fname = refid + '.xml'
for prefix in USE_PREFIXES:
if fname.startswith(prefix):
if not os.path.exists(fname):
fname = os.path.join(self.my_dir, fname)
if not self.quiet:
print ("parsing file: %s" % fname)
p = Doxy2SWIG(fname, self.include_function_definition, self.quiet)
p.generate()
self.pieces.extend(self.clean_pieces(p.pieces))
break
def write(self, fname):
o = my_open_write(fname)
if self.multi:
o.write("".join(self.pieces))
else:
o.write("".join(self.clean_pieces(self.pieces)))
o.close()
def clean_pieces(self, pieces):
"""Cleans the list of strings given as `pieces`. It replaces
multiple newlines by a maximum of 2 and returns a new list.
It also wraps the paragraphs nicely.
"""
ret = []
count = 0
for i in pieces:
if i == '\n':
count = count + 1
else:
if i == '";':
if count:
ret.append('\n')
elif count > 2:
ret.append('\n\n')
elif count:
ret.append('\n'*count)
count = 0
ret.append(i)
_data = "".join(ret)
ret = []
for i in _data.split('\n\n'):
if i == 'Parameters:' or i == 'Exceptions:':
ret.extend([i, '\n-----------', '\n\n'])
elif i.find('// File:') > -1: # leave comments alone.
ret.extend([i, '\n'])
else:
_tmp = textwrap.fill(i.strip(), break_long_words=False)
_tmp = self.lead_spc.sub(r'\1"\2', _tmp)
ret.extend([_tmp, '\n\n'])
return ret
def convert(input, output, include_function_definition=True, quiet=False):
p = Doxy2SWIG(input, include_function_definition, quiet)
p.generate()
p.write(output)
def main():
usage = __doc__
parser = optparse.OptionParser(usage)
parser.add_option("-n", '--no-function-definition',
action='store_true',
default=False,
dest='func_def',
help='do not include doxygen function definitions')
parser.add_option("-q", '--quiet',
action='store_true',
default=False,
dest='quiet',
help='be quiet and minimize output')
options, args = parser.parse_args()
if len(args) != 2:
parser.error("error: no input and output specified")
convert(args[0], args[1], not options.func_def, options.quiet)
if __name__ == '__main__':
main()

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,251 @@
.TH POCKETSPHINX_BATCH 1 "2007-08-27"
.SH NAME
pocketsphinx_batch \- Run speech recognition in batch mode
.SH SYNOPSIS
.B pocketsphinx_batch
.RI \fB\-hmm\fR
\fIhmmdir\fR
\fB\-dict\fR
\fIdictfile\fR
[\fI options \fR]...
.SH DESCRIPTION
.PP
Run speech recognition over a list of utterances in batchmode. A list
of arguments follows:
.TP
.B \-adchdr
Size of audio file header in bytes (headers are ignored)
.TP
.B \-adcin
Input is raw audio data
.TP
.B \-agc
Automatic gain control for c0 ('max', 'emax', 'noise', or 'none')
.TP
.B \-agcthresh
Initial threshold for automatic gain control
.TP
.B \-allphone
phoneme decoding with phonetic lm
.TP
.B \-allphone_ci
Perform phoneme decoding with phonetic lm and context-independent units only
.TP
.B \-alpha
Preemphasis parameter
.TP
.B \-argfile
file giving extra arguments.
.TP
.B \-ascale
Inverse of acoustic model scale for confidence score calculation
.TP
.B \-aw
Inverse weight applied to acoustic scores.
.TP
.B \-backtrace
Print results and backtraces to log file.
.TP
.B \-beam
Beam width applied to every frame in Viterbi search (smaller values mean wider beam)
.TP
.B \-bestpath
Run bestpath (Dijkstra) search over word lattice (3rd pass)
.TP
.B \-bestpathlw
Language model probability weight for bestpath search
.TP
.B \-build_outdirs
Create missing subdirectories in output directory
.TP
.B \-cepdir
files directory (prefixed to filespecs in control file)
.TP
.B \-cepext
Input files extension (suffixed to filespecs in control file)
.TP
.B \-ceplen
Number of components in the input feature vector
.TP
.B \-cmn
Cepstral mean normalization scheme ('current', 'prior', or 'none')
.TP
.B \-cmninit
Initial values (comma-separated) for cepstral mean when 'prior' is used
.TP
.B \-compallsen
Compute all senone scores in every frame (can be faster when there are many senones)
.TP
.B \-ctl
file listing utterances to be processed
.TP
.B \-ctlcount
No. of utterances to be processed (after skipping \fB\-ctloffset\fR entries)
.TP
.B \-ctlincr
Do every Nth line in the control file
.TP
.B \-ctloffset
No. of utterances at the beginning of \fB\-ctl\fR file to be skipped
.TP
.B \-ctm
output in CTM file format (may require post-sorting)
.TP
.B \-debug
level for debugging messages
.TP
.B \-dict
pronunciation dictionary (lexicon) input file
.TP
.B \-dictcase
Dictionary is case sensitive (NOTE: case insensitivity applies to ASCII characters only)
.TP
.B \-dither
Add 1/2-bit noise
.TP
.B \-doublebw
Use double bandwidth filters (same center freq)
.TP
.B \-ds
Frame GMM computation downsampling ratio
.TP
.B \-fdict
word pronunciation dictionary input file
.TP
.B \-feat
Feature stream type, depends on the acoustic model
.TP
.B \-featparams
containing feature extraction parameters.
.TP
.B \-fillprob
Filler word transition probability
.TP
.B \-frate
Frame rate
.TP
.B \-fsg
format finite state grammar file
.TP
.B \-fsgctl
file listing FSG file to use for each utterance
.TP
.B \-fsgdir
directory for FSG files
.TP
.B \-fsgext
extension for FSG files (including leading dot)
.TP
.B \-fsgusealtpron
Add alternate pronunciations to FSG
.TP
.B \-fsgusefiller
Insert filler words at each state.
.TP
.B \-fwdflat
Run forward flat-lexicon search over word lattice (2nd pass)
.TP
.B \-fwdflatbeam
Beam width applied to every frame in second-pass flat search
.TP
.B \-fwdflatefwid
Minimum number of end frames for a word to be searched in fwdflat search
.TP
.B \-fwdflatlw
Language model probability weight for flat lexicon (2nd pass) decoding
.TP
.B \-fwdflatsfwin
Window of frames in lattice to search for successor words in fwdflat search
.TP
.B \-fwdflatwbeam
Beam width applied to word exits in second-pass flat search
.TP
.B \-fwdtree
Run forward lexicon-tree search (1st pass)
.TP
.B \-hmm
containing acoustic model files.
.TP
.B \-hyp
output file name
.TP
.B \-hypseg
output with segmentation file name
.TP
.B \-input_endian
Endianness of input data, big or little, ignored if NIST or MS Wav
.TP
.B \-jsgf
grammar file
.TP
.B \-keyphrase
to spot
.TP
.B \-kws
file with keyphrases to spot, one per line
.TP
.B \-kws_delay
Delay to wait for best detection score
.TP
.B \-kws_plp
Phone loop probability for keyword spotting
.TP
.B \-kws_threshold
Threshold for p(hyp)/p(alternatives) ratio
.TP
.B \-latsize
Initial backpointer table size
.TP
.B \-lda
containing transformation matrix to be applied to features (single-stream features only)
.TP
.B \-ldadim
Dimensionality of output of feature transformation (0 to use entire matrix)
.TP
.B \-lifter
Length of sin-curve for liftering, or 0 for no liftering.
.TP
.B \-lm
trigram language model input file
.TP
.B \-lmctl
a set of language model
.PP
The
.B \-hmm
and
.B \-dict
arguments are always required. Either
.B \-lm
or
.B \-fsg
is required, depending on whether you are using a statistical language
model or a finite-state grammar. To do batchmode recognition, you
will need to specify a control file, using
.B \-ctl
This is a simple text file containing one entry per line. Each entry
is the name of an input file relative to the
.B \-cepdir
directory, and without the filename extension (which is given in the
.B \-cepext
argument).
.PP
If you are using acoustic feature files as input (see
.BR sphinx_fe (1)
for information on how to generate these), you can also specify a subpart
of a file, using the following format:
.PP
.RS
.B FILENAME START\-FRAME END\-FRAME UTTERANCE-ID
.RE
.SH AUTHOR
Written by numerous people at CMU from 1994 onwards. This manual page
by David Huggins-Daines <dhuggins@cs.cmu.edu>
.SH COPYRIGHT
Copyright \(co 1994-2007 Carnegie Mellon University. See the file
\fICOPYING\fR included with this package for more information.
.br
.SH "SEE ALSO"
.BR pocketsphinx_continuous (1),
.BR sphinx_fe (1).
.br

View File

@ -0,0 +1,54 @@
.TH POCKETSPHINX_BATCH 1 "2007-08-27"
.SH NAME
pocketsphinx_batch \- Run speech recognition in batch mode
.SH SYNOPSIS
.B pocketsphinx_batch
.RI \fB\-hmm\fR
\fIhmmdir\fR
\fB\-dict\fR
\fIdictfile\fR
[\fI options \fR]...
.SH DESCRIPTION
.PP
Run speech recognition over a list of utterances in batchmode. A list
of arguments follows:
.\" ### ARGUMENTS ###
.PP
The
.B \-hmm
and
.B \-dict
arguments are always required. Either
.B \-lm
or
.B \-fsg
is required, depending on whether you are using a statistical language
model or a finite-state grammar. To do batchmode recognition, you
will need to specify a control file, using
.B \-ctl
This is a simple text file containing one entry per line. Each entry
is the name of an input file relative to the
.B \-cepdir
directory, and without the filename extension (which is given in the
.B \-cepext
argument).
.PP
If you are using acoustic feature files as input (see
.BR sphinx_fe (1)
for information on how to generate these), you can also specify a subpart
of a file, using the following format:
.PP
.RS
.B FILENAME START\-FRAME END\-FRAME UTTERANCE-ID
.RE
.SH AUTHOR
Written by numerous people at CMU from 1994 onwards. This manual page
by David Huggins-Daines <dhuggins@cs.cmu.edu>
.SH COPYRIGHT
Copyright \(co 1994-2007 Carnegie Mellon University. See the file
\fICOPYING\fR included with this package for more information.
.br
.SH "SEE ALSO"
.BR pocketsphinx_continuous (1),
.BR sphinx_fe (1).
.br

View File

@ -0,0 +1,234 @@
.TH POCKETSPHINX_CONTINUOUS 1 "2007-08-27"
.SH NAME
pocketsphinx_continuous \- Run speech recognition in continuous listening mode
.SH SYNOPSIS
.B pocketsphinx_continuous
.RI \fB\-hmm\fR
\fIhmmdir\fR
\fB\-dict\fR
\fIdictfile\fR
[\fI options \fR]...
.SH DESCRIPTION
.PP
This program opens the audio device and waits for speech. When it
detects an utterance, it performs speech recognition on it.
.TP
.B \-adchdr
Size of audio file header in bytes (headers are ignored)
.TP
.B \-adcin
Input is raw audio data
.TP
.B \-agc
Automatic gain control for c0 ('max', 'emax', 'noise', or 'none')
.TP
.B \-agcthresh
Initial threshold for automatic gain control
.TP
.B \-allphone
phoneme decoding with phonetic lm
.TP
.B \-allphone_ci
Perform phoneme decoding with phonetic lm and context-independent units only
.TP
.B \-alpha
Preemphasis parameter
.TP
.B \-argfile
file giving extra arguments.
.TP
.B \-ascale
Inverse of acoustic model scale for confidence score calculation
.TP
.B \-aw
Inverse weight applied to acoustic scores.
.TP
.B \-backtrace
Print results and backtraces to log file.
.TP
.B \-beam
Beam width applied to every frame in Viterbi search (smaller values mean wider beam)
.TP
.B \-bestpath
Run bestpath (Dijkstra) search over word lattice (3rd pass)
.TP
.B \-bestpathlw
Language model probability weight for bestpath search
.TP
.B \-build_outdirs
Create missing subdirectories in output directory
.TP
.B \-cepdir
files directory (prefixed to filespecs in control file)
.TP
.B \-cepext
Input files extension (suffixed to filespecs in control file)
.TP
.B \-ceplen
Number of components in the input feature vector
.TP
.B \-cmn
Cepstral mean normalization scheme ('current', 'prior', or 'none')
.TP
.B \-cmninit
Initial values (comma-separated) for cepstral mean when 'prior' is used
.TP
.B \-compallsen
Compute all senone scores in every frame (can be faster when there are many senones)
.TP
.B \-ctl
file listing utterances to be processed
.TP
.B \-ctlcount
No. of utterances to be processed (after skipping \fB\-ctloffset\fR entries)
.TP
.B \-ctlincr
Do every Nth line in the control file
.TP
.B \-ctloffset
No. of utterances at the beginning of \fB\-ctl\fR file to be skipped
.TP
.B \-ctm
output in CTM file format (may require post-sorting)
.TP
.B \-debug
level for debugging messages
.TP
.B \-dict
pronunciation dictionary (lexicon) input file
.TP
.B \-dictcase
Dictionary is case sensitive (NOTE: case insensitivity applies to ASCII characters only)
.TP
.B \-dither
Add 1/2-bit noise
.TP
.B \-doublebw
Use double bandwidth filters (same center freq)
.TP
.B \-ds
Frame GMM computation downsampling ratio
.TP
.B \-fdict
word pronunciation dictionary input file
.TP
.B \-feat
Feature stream type, depends on the acoustic model
.TP
.B \-featparams
containing feature extraction parameters.
.TP
.B \-fillprob
Filler word transition probability
.TP
.B \-frate
Frame rate
.TP
.B \-fsg
format finite state grammar file
.TP
.B \-fsgctl
file listing FSG file to use for each utterance
.TP
.B \-fsgdir
directory for FSG files
.TP
.B \-fsgext
extension for FSG files (including leading dot)
.TP
.B \-fsgusealtpron
Add alternate pronunciations to FSG
.TP
.B \-fsgusefiller
Insert filler words at each state.
.TP
.B \-fwdflat
Run forward flat-lexicon search over word lattice (2nd pass)
.TP
.B \-fwdflatbeam
Beam width applied to every frame in second-pass flat search
.TP
.B \-fwdflatefwid
Minimum number of end frames for a word to be searched in fwdflat search
.TP
.B \-fwdflatlw
Language model probability weight for flat lexicon (2nd pass) decoding
.TP
.B \-fwdflatsfwin
Window of frames in lattice to search for successor words in fwdflat search
.TP
.B \-fwdflatwbeam
Beam width applied to word exits in second-pass flat search
.TP
.B \-fwdtree
Run forward lexicon-tree search (1st pass)
.TP
.B \-hmm
containing acoustic model files.
.TP
.B \-hyp
output file name
.TP
.B \-hypseg
output with segmentation file name
.TP
.B \-input_endian
Endianness of input data, big or little, ignored if NIST or MS Wav
.TP
.B \-jsgf
grammar file
.TP
.B \-keyphrase
to spot
.TP
.B \-kws
file with keyphrases to spot, one per line
.TP
.B \-kws_delay
Delay to wait for best detection score
.TP
.B \-kws_plp
Phone loop probability for keyword spotting
.TP
.B \-kws_threshold
Threshold for p(hyp)/p(alternatives) ratio
.TP
.B \-latsize
Initial backpointer table size
.TP
.B \-lda
containing transformation matrix to be applied to features (single-stream features only)
.TP
.B \-ldadim
Dimensionality of output of feature transformation (0 to use entire matrix)
.TP
.B \-lifter
Length of sin-curve for liftering, or 0 for no liftering.
.TP
.B \-lm
trigram language model input file
.TP
.B \-lmctl
a set of language model
.PP
The
.B \-hmm
and
.B \-dict
arguments are always required. Either
.B \-lm
or
.B \-fsg
is required, depending on whether you are using a statistical language
model or a finite-state grammar.
.SH AUTHOR
Written by numerous people at CMU from 1994 onwards. This manual page
by David Huggins-Daines <dhuggins@cs.cmu.edu>
.SH COPYRIGHT
Copyright \(co 1994-2007 Carnegie Mellon University. See the file
\fICOPYING\fR included with this package for more information.
.br
.SH "SEE ALSO"
.BR pocketsphinx_batch (1),
.BR sphinx_fe (1).
.br

View File

@ -0,0 +1,37 @@
.TH POCKETSPHINX_CONTINUOUS 1 "2007-08-27"
.SH NAME
pocketsphinx_continuous \- Run speech recognition in continuous listening mode
.SH SYNOPSIS
.B pocketsphinx_continuous
.RI \fB\-hmm\fR
\fIhmmdir\fR
\fB\-dict\fR
\fIdictfile\fR
[\fI options \fR]...
.SH DESCRIPTION
.PP
This program opens the audio device and waits for speech. When it
detects an utterance, it performs speech recognition on it.
.\" ### ARGUMENTS ###
.PP
The
.B \-hmm
and
.B \-dict
arguments are always required. Either
.B \-lm
or
.B \-fsg
is required, depending on whether you are using a statistical language
model or a finite-state grammar.
.SH AUTHOR
Written by numerous people at CMU from 1994 onwards. This manual page
by David Huggins-Daines <dhuggins@cs.cmu.edu>
.SH COPYRIGHT
Copyright \(co 1994-2007 Carnegie Mellon University. See the file
\fICOPYING\fR included with this package for more information.
.br
.SH "SEE ALSO"
.BR pocketsphinx_batch (1),
.BR sphinx_fe (1).
.br

View File

@ -0,0 +1,24 @@
.TH POCKETSPHINX_MDEF_CONVERT 1 "2007-08-27"
.SH NAME
pocketsphinx_mdef_convert \- Convert text-format model definition files to and from PocketSphinx format
.SH SYNOPSIS
.B pocketsphinx_mdef_convert
[\fI options \fR]
.B INPUT OUTPUT
.SH DESCRIPTION
.PP
This program converts the text format acoustic model definition files
generated by SphinxTrain into the fast binary format used by
PocketSphinx. It can also convert binary files back to text format.
.TP
.B -text
The input is in text format, and is to be converted to binary.
.TP
.B -bin
The input is in binary format, and is to be converted to text.
.SH AUTHOR
Written by David Huggins-Daines <dhuggins@cs.cmu.edu>.
.SH COPYRIGHT
Copyright \(co 2006 Carnegie Mellon University. See the file
\fICOPYING\fR included with this package for more information.
.br

View File

@ -0,0 +1,12 @@
pkginclude_HEADERS = \
cmdln_macro.h \
ps_lattice.h \
ps_mllr.h \
ps_search.h \
pocketsphinx_export.h \
pocketsphinx.h

View File

@ -0,0 +1,580 @@
# Makefile.in generated by automake 1.13.4 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2013 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.
@SET_MAKE@
VPATH = @srcdir@
am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
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)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
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 = @build@
host_triplet = @host@
subdir = include
DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
$(pkginclude_HEADERS)
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_pkg_swig.m4 \
$(top_srcdir)/m4/ax_python_devel.m4 \
$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
$(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/pkg.m4 \
$(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false
am__v_P_1 = :
AM_V_GEN = $(am__v_GEN_@AM_V@)
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
am__v_GEN_0 = @echo " GEN " $@;
am__v_GEN_1 =
AM_V_at = $(am__v_at_@AM_V@)
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
am__v_at_0 = @
am__v_at_1 =
SOURCES =
DIST_SOURCES =
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
*) (install-info --version) >/dev/null 2>&1;; \
esac
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)$(pkgincludedir)"
HEADERS = $(pkginclude_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
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GREP = @GREP@
GST_CFLAGS = @GST_CFLAGS@
GST_LIBS = @GST_LIBS@
GST_MAJORMINOR = @GST_MAJORMINOR@
GST_PLUGIN_LDFLAGS = @GST_PLUGIN_LDFLAGS@
GStreamer_CFLAGS = @GStreamer_CFLAGS@
GStreamer_LIBS = @GStreamer_LIBS@
HAVE_DOXYGEN = @HAVE_DOXYGEN@
HAVE_PKGCONFIG = @HAVE_PKGCONFIG@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LD = @LD@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PKG_CONFIG = @PKG_CONFIG@
PYTHON = @PYTHON@
PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@
PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@
PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@
PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
PYTHON_PLATFORM = @PYTHON_PLATFORM@
PYTHON_PREFIX = @PYTHON_PREFIX@
PYTHON_SITE_PKG = @PYTHON_SITE_PKG@
PYTHON_VERSION = @PYTHON_VERSION@
RANLIB = @RANLIB@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
SPHINXBASE_CFLAGS = @SPHINXBASE_CFLAGS@
SPHINXBASE_LIBS = @SPHINXBASE_LIBS@
SPHINXBASE_SWIG = @SPHINXBASE_SWIG@
STRIP = @STRIP@
SWIG = @SWIG@
SWIG_LIB = @SWIG_LIB@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
pkgpyexecdir = @pkgpyexecdir@
pkgpythondir = @pkgpythondir@
plugindir = @plugindir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
pyexecdir = @pyexecdir@
pythondir = @pythondir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
pkginclude_HEADERS = \
cmdln_macro.h \
ps_lattice.h \
ps_mllr.h \
ps_search.h \
pocketsphinx_export.h \
pocketsphinx.h
all: all-am
.SUFFIXES:
$(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) --foreign include/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign include/Makefile
.PRECIOUS: 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):
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
install-pkgincludeHEADERS: $(pkginclude_HEADERS)
@$(NORMAL_INSTALL)
@list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \
if test -n "$$list"; then \
echo " $(MKDIR_P) '$(DESTDIR)$(pkgincludedir)'"; \
$(MKDIR_P) "$(DESTDIR)$(pkgincludedir)" || exit 1; \
fi; \
for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
echo "$$d$$p"; \
done | $(am__base_list) | \
while read files; do \
echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(pkgincludedir)'"; \
$(INSTALL_HEADER) $$files "$(DESTDIR)$(pkgincludedir)" || exit $$?; \
done
uninstall-pkgincludeHEADERS:
@$(NORMAL_UNINSTALL)
@list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
dir='$(DESTDIR)$(pkgincludedir)'; $(am__uninstall_files_from_dir)
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 $(HEADERS)
installdirs:
for dir in "$(DESTDIR)$(pkgincludedir)"; 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 mostlyclean-am
distclean: distclean-am
-rm -f Makefile
distclean-am: clean-am distclean-generic distclean-tags
dvi: dvi-am
dvi-am:
html: html-am
html-am:
info: info-am
info-am:
install-data-am: install-pkgincludeHEADERS
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 -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-generic mostlyclean-libtool
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-pkgincludeHEADERS
.MAKE: install-am install-strip
.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
clean-libtool cscopelist-am ctags ctags-am distclean \
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-pkgincludeHEADERS install-ps \
install-ps-am install-strip installcheck installcheck-am \
installdirs maintainer-clean maintainer-clean-generic \
mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
ps ps-am tags tags-am uninstall uninstall-am \
uninstall-pkgincludeHEADERS
# 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:

View File

@ -0,0 +1,388 @@
/* -*- c-basic-offset: 4; indent-tabs-mode: nil -*- */
/* ====================================================================
* Copyright (c) 2006 Carnegie Mellon University. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. 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 work was supported in part by funding from the Defense Advanced
* Research Projects Agency and the National Science Foundation of the
* United States of America, and the CMU Sphinx Speech Consortium.
*
* THIS SOFTWARE IS PROVIDED BY CARNEGIE MELLON UNIVERSITY ``AS IS'' AND
* ANY EXPRESSED 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 CARNEGIE MELLON UNIVERSITY
* NOR ITS EMPLOYEES 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.
*
* ====================================================================
*
*/
/* cmdln_macro.h - Command line definitions for PocketSphinx */
#ifndef __PS_CMDLN_MACRO_H__
#define __PS_CMDLN_MACRO_H__
#include <sphinxbase/cmd_ln.h>
#include <sphinxbase/feat.h>
#include <sphinxbase/fe.h>
/** Minimal set of command-line options for PocketSphinx. */
#define POCKETSPHINX_OPTIONS \
waveform_to_cepstral_command_line_macro(), \
cepstral_to_feature_command_line_macro(), \
POCKETSPHINX_ACMOD_OPTIONS, \
POCKETSPHINX_BEAM_OPTIONS, \
POCKETSPHINX_SEARCH_OPTIONS, \
POCKETSPHINX_DICT_OPTIONS, \
POCKETSPHINX_NGRAM_OPTIONS, \
POCKETSPHINX_FSG_OPTIONS, \
POCKETSPHINX_KWS_OPTIONS, \
POCKETSPHINX_DEBUG_OPTIONS
/** Options for debugging and logging. */
#define POCKETSPHINX_DEBUG_OPTIONS \
{ "-logfn", \
ARG_STRING, \
NULL, \
"File to write log messages in" }, \
{ "-debug", \
ARG_INT32, \
NULL, \
"Verbosity level for debugging messages" }, \
{ "-mfclogdir", \
ARG_STRING, \
NULL, \
"Directory to log feature files to" \
}, \
{ "-rawlogdir", \
ARG_STRING, \
NULL, \
"Directory to log raw audio files to" }, \
{ "-senlogdir", \
ARG_STRING, \
NULL, \
"Directory to log senone score files to" \
}
/** Options defining beam width parameters for tuning the search. */
#define POCKETSPHINX_BEAM_OPTIONS \
{ "-beam", \
ARG_FLOAT64, \
"1e-48", \
"Beam width applied to every frame in Viterbi search (smaller values mean wider beam)" }, \
{ "-wbeam", \
ARG_FLOAT64, \
"7e-29", \
"Beam width applied to word exits" }, \
{ "-pbeam", \
ARG_FLOAT64, \
"1e-48", \
"Beam width applied to phone transitions" }, \
{ "-lpbeam", \
ARG_FLOAT64, \
"1e-40", \
"Beam width applied to last phone in words" }, \
{ "-lponlybeam", \
ARG_FLOAT64, \
"7e-29", \
"Beam width applied to last phone in single-phone words" }, \
{ "-fwdflatbeam", \
ARG_FLOAT64, \
"1e-64", \
"Beam width applied to every frame in second-pass flat search" }, \
{ "-fwdflatwbeam", \
ARG_FLOAT64, \
"7e-29", \
"Beam width applied to word exits in second-pass flat search" }, \
{ "-pl_window", \
ARG_INT32, \
"5", \
"Phoneme lookahead window size, in frames" }, \
{ "-pl_beam", \
ARG_FLOAT64, \
"1e-10", \
"Beam width applied to phone loop search for lookahead" }, \
{ "-pl_pbeam", \
ARG_FLOAT64, \
"1e-10", \
"Beam width applied to phone loop transitions for lookahead" }, \
{ "-pl_pip", \
ARG_FLOAT32, \
"1.0", \
"Phone insertion penalty for phone loop" }, \
{ "-pl_weight", \
ARG_FLOAT64, \
"3.0", \
"Weight for phoneme lookahead penalties" } \
/** Options defining other parameters for tuning the search. */
#define POCKETSPHINX_SEARCH_OPTIONS \
{ "-compallsen", \
ARG_BOOLEAN, \
"no", \
"Compute all senone scores in every frame (can be faster when there are many senones)" }, \
{ "-fwdtree", \
ARG_BOOLEAN, \
"yes", \
"Run forward lexicon-tree search (1st pass)" }, \
{ "-fwdflat", \
ARG_BOOLEAN, \
"yes", \
"Run forward flat-lexicon search over word lattice (2nd pass)" }, \
{ "-bestpath", \
ARG_BOOLEAN, \
"yes", \
"Run bestpath (Dijkstra) search over word lattice (3rd pass)" }, \
{ "-backtrace", \
ARG_BOOLEAN, \
"no", \
"Print results and backtraces to log file." }, \
{ "-latsize", \
ARG_INT32, \
"5000", \
"Initial backpointer table size" }, \
{ "-maxwpf", \
ARG_INT32, \
"-1", \
"Maximum number of distinct word exits at each frame (or -1 for no pruning)" }, \
{ "-maxhmmpf", \
ARG_INT32, \
"30000", \
"Maximum number of active HMMs to maintain at each frame (or -1 for no pruning)" }, \
{ "-min_endfr", \
ARG_INT32, \
"0", \
"Nodes ignored in lattice construction if they persist for fewer than N frames" }, \
{ "-fwdflatefwid", \
ARG_INT32, \
"4", \
"Minimum number of end frames for a word to be searched in fwdflat search" }, \
{ "-fwdflatsfwin", \
ARG_INT32, \
"25", \
"Window of frames in lattice to search for successor words in fwdflat search " }
/** Command-line options for keyword spotting */
#define POCKETSPHINX_KWS_OPTIONS \
{ "-keyphrase", \
ARG_STRING, \
NULL, \
"Keyphrase to spot"}, \
{ "-kws", \
ARG_STRING, \
NULL, \
"A file with keyphrases to spot, one per line"}, \
{ "-kws_plp", \
ARG_FLOAT64, \
"1e-1", \
"Phone loop probability for keyword spotting" }, \
{ "-kws_delay", \
ARG_INT32, \
"10", \
"Delay to wait for best detection score" }, \
{ "-kws_threshold", \
ARG_FLOAT64, \
"1", \
"Threshold for p(hyp)/p(alternatives) ratio" }
/** Command-line options for finite state grammars. */
#define POCKETSPHINX_FSG_OPTIONS \
{ "-fsg", \
ARG_STRING, \
NULL, \
"Sphinx format finite state grammar file"}, \
{ "-jsgf", \
ARG_STRING, \
NULL, \
"JSGF grammar file" }, \
{ "-toprule", \
ARG_STRING, \
NULL, \
"Start rule for JSGF (first public rule is default)" }, \
{ "-fsgusealtpron", \
ARG_BOOLEAN, \
"yes", \
"Add alternate pronunciations to FSG"}, \
{ "-fsgusefiller", \
ARG_BOOLEAN, \
"yes", \
"Insert filler words at each state."}
/** Command-line options for statistical language models. */
#define POCKETSPHINX_NGRAM_OPTIONS \
{ "-allphone", \
ARG_STRING, \
NULL, \
"Perform phoneme decoding with phonetic lm" }, \
{ "-allphone_ci", \
ARG_BOOLEAN, \
"no", \
"Perform phoneme decoding with phonetic lm and context-independent units only" }, \
{ "-lm", \
ARG_STRING, \
NULL, \
"Word trigram language model input file" }, \
{ "-lmctl", \
ARG_STRING, \
NULL, \
"Specify a set of language model\n"}, \
{ "-lmname", \
ARG_STRING, \
NULL, \
"Which language model in -lmctl to use by default"}, \
{ "-lw", \
ARG_FLOAT32, \
"6.5", \
"Language model probability weight" }, \
{ "-fwdflatlw", \
ARG_FLOAT32, \
"8.5", \
"Language model probability weight for flat lexicon (2nd pass) decoding" }, \
{ "-bestpathlw", \
ARG_FLOAT32, \
"9.5", \
"Language model probability weight for bestpath search" }, \
{ "-ascale", \
ARG_FLOAT32, \
"20.0", \
"Inverse of acoustic model scale for confidence score calculation" }, \
{ "-wip", \
ARG_FLOAT32, \
"0.65", \
"Word insertion penalty" }, \
{ "-nwpen", \
ARG_FLOAT32, \
"1.0", \
"New word transition penalty" }, \
{ "-pip", \
ARG_FLOAT32, \
"1.0", \
"Phone insertion penalty" }, \
{ "-uw", \
ARG_FLOAT32, \
"1.0", \
"Unigram weight" }, \
{ "-silprob", \
ARG_FLOAT32, \
"0.005", \
"Silence word transition probability" }, \
{ "-fillprob", \
ARG_FLOAT32, \
"1e-8", \
"Filler word transition probability" } \
/** Command-line options for dictionaries. */
#define POCKETSPHINX_DICT_OPTIONS \
{ "-dict", \
REQARG_STRING, \
NULL, \
"Main pronunciation dictionary (lexicon) input file" }, \
{ "-fdict", \
ARG_STRING, \
NULL, \
"Noise word pronunciation dictionary input file" }, \
{ "-dictcase", \
ARG_BOOLEAN, \
"no", \
"Dictionary is case sensitive (NOTE: case insensitivity applies to ASCII characters only)" } \
/** Command-line options for acoustic modeling */
#define POCKETSPHINX_ACMOD_OPTIONS \
{ "-hmm", \
ARG_STRING, \
NULL, \
"Directory containing acoustic model files."}, \
{ "-featparams", \
ARG_STRING, \
NULL, \
"File containing feature extraction parameters."}, \
{ "-mdef", \
ARG_STRING, \
NULL, \
"Model definition input file" }, \
{ "-senmgau", \
ARG_STRING, \
NULL, \
"Senone to codebook mapping input file (usually not needed)" }, \
{ "-tmat", \
ARG_STRING, \
NULL, \
"HMM state transition matrix input file" }, \
{ "-tmatfloor", \
ARG_FLOAT32, \
"0.0001", \
"HMM state transition probability floor (applied to -tmat file)" }, \
{ "-mean", \
ARG_STRING, \
NULL, \
"Mixture gaussian means input file" }, \
{ "-var", \
ARG_STRING, \
NULL, \
"Mixture gaussian variances input file" }, \
{ "-varfloor", \
ARG_FLOAT32, \
"0.0001", \
"Mixture gaussian variance floor (applied to data from -var file)" }, \
{ "-mixw", \
ARG_STRING, \
NULL, \
"Senone mixture weights input file (uncompressed)" }, \
{ "-mixwfloor", \
ARG_FLOAT32, \
"0.0000001", \
"Senone mixture weights floor (applied to data from -mixw file)" }, \
{ "-aw", \
ARG_INT32, \
"1", \
"Inverse weight applied to acoustic scores." }, \
{ "-sendump", \
ARG_STRING, \
NULL, \
"Senone dump (compressed mixture weights) input file" }, \
{ "-mllr", \
ARG_STRING, \
NULL, \
"MLLR transformation to apply to means and variances" }, \
{ "-mmap", \
ARG_BOOLEAN, \
"yes", \
"Use memory-mapped I/O (if possible) for model files" }, \
{ "-ds", \
ARG_INT32, \
"1", \
"Frame GMM computation downsampling ratio" }, \
{ "-topn", \
ARG_INT32, \
"4", \
"Maximum number of top Gaussians to use in scoring." }, \
{ "-topn_beam", \
ARG_STRING, \
"0", \
"Beam width used to determine top-N Gaussians (or a list, per-feature)" },\
{ "-logbase", \
ARG_FLOAT32, \
"1.0001", \
"Base in which all log-likelihoods calculated" }
#define CMDLN_EMPTY_OPTION { NULL, 0, NULL, NULL }
#endif /* __PS_CMDLN_MACRO_H__ */

View File

@ -0,0 +1,659 @@
/* -*- c-basic-offset:4; indent-tabs-mode: nil -*- */
/* ====================================================================
* Copyright (c) 1999-2008 Carnegie Mellon University. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. 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 CARNEGIE MELLON UNIVERSITY ``AS IS'' AND
* ANY EXPRESSED 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 CARNEGIE MELLON UNIVERSITY
* NOR ITS EMPLOYEES 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.
*
* ====================================================================
*
*/
/**
* @file pocketsphinx.h Main header file for the PocketSphinx decoder.
*/
#ifndef __POCKETSPHINX_H__
#define __POCKETSPHINX_H__
#ifdef __cplusplus
extern "C" {
#endif
#if 0
}
#endif
/* System headers we need. */
#include <stdio.h>
/* SphinxBase headers we need. */
#include <sphinxbase/cmd_ln.h>
#include <sphinxbase/logmath.h>
#include <sphinxbase/fe.h>
#include <sphinxbase/feat.h>
/* PocketSphinx headers (not many of them!) */
#include <pocketsphinx_export.h>
#include <cmdln_macro.h>
#include <ps_lattice.h>
#include <ps_mllr.h>
/**
* PocketSphinx speech recognizer object.
*/
typedef struct ps_decoder_s ps_decoder_t;
#include <ps_search.h>
/**
* PocketSphinx N-best hypothesis iterator object.
*/
typedef struct ps_astar_s ps_nbest_t;
/**
* PocketSphinx segmentation iterator object.
*/
typedef struct ps_seg_s ps_seg_t;
/**
* Sets default grammar and language model if they are not set explicitly and
* are present in the default search path.
*/
POCKETSPHINX_EXPORT void
ps_default_search_args(cmd_ln_t *);
/**
* Initialize the decoder from a configuration object.
*
* @note The decoder retains ownership of the pointer
* <code>config</code>, so if you are not going to use it
* elsewere, you can free it.
*
* @param config a command-line structure, as created by
* cmd_ln_parse_r() or cmd_ln_parse_file_r().
*/
POCKETSPHINX_EXPORT
ps_decoder_t *ps_init(cmd_ln_t *config);
/**
* Reinitialize the decoder with updated configuration.
*
* This function allows you to switch the acoustic model, dictionary,
* or other configuration without creating an entirely new decoding
* object.
*
* @note The decoder retains ownership of the pointer
* <code>config</code>, so you must not attempt to free it manually.
* If you wish to reuse it elsewhere, call cmd_ln_retain() on it.
*
* @param ps Decoder.
* @param config An optional new configuration to use. If this is
* NULL, the previous configuration will be reloaded,
* with any changes applied.
* @return 0 for success, <0 for failure.
*/
POCKETSPHINX_EXPORT
int ps_reinit(ps_decoder_t *ps, cmd_ln_t *config);
/**
* Returns the argument definitions used in ps_init().
*
* This is here to avoid exporting global data, which is problematic
* on Win32 and Symbian (and possibly other platforms).
*/
POCKETSPHINX_EXPORT
arg_t const *ps_args(void);
/**
* Retain a pointer to the decoder.
*
* This increments the reference count on the decoder, allowing it to
* be shared between multiple parent objects. In general you will not
* need to use this function, ever. It is mainly here for the
* convenience of scripting language bindings.
*
* @return pointer to retained decoder.
*/
POCKETSPHINX_EXPORT
ps_decoder_t *ps_retain(ps_decoder_t *ps);
/**
* Finalize the decoder.
*
* This releases all resources associated with the decoder, including
* any language models or grammars which have been added to it, and
* the initial configuration object passed to ps_init().
*
* @param ps Decoder to be freed.
* @return New reference count (0 if freed).
*/
POCKETSPHINX_EXPORT
int ps_free(ps_decoder_t *ps);
/**
* Get the configuration object for this decoder.
*
* @return The configuration object for this decoder. The decoder
* retains ownership of this pointer, so you should not
* attempt to free it manually. Use cmd_ln_retain() if you
* wish to reuse it elsewhere.
*/
POCKETSPHINX_EXPORT
cmd_ln_t *ps_get_config(ps_decoder_t *ps);
/**
* Get the log-math computation object for this decoder.
*
* @return The log-math object for this decoder. The decoder retains
* ownership of this pointer, so you should not attempt to
* free it manually. Use logmath_retain() if you wish to
* reuse it elsewhere.
*/
POCKETSPHINX_EXPORT
logmath_t *ps_get_logmath(ps_decoder_t *ps);
/**
* Get the feature extraction object for this decoder.
*
* @return The feature extraction object for this decoder. The
* decoder retains ownership of this pointer, so you should
* not attempt to free it manually. Use fe_retain() if you
* wish to reuse it elsewhere.
*/
POCKETSPHINX_EXPORT
fe_t *ps_get_fe(ps_decoder_t *ps);
/**
* Get the dynamic feature computation object for this decoder.
*
* @return The dynamic feature computation object for this decoder. The
* decoder retains ownership of this pointer, so you should
* not attempt to free it manually. Use feat_retain() if you
* wish to reuse it elsewhere.
*/
POCKETSPHINX_EXPORT
feat_t *ps_get_feat(ps_decoder_t *ps);
/**
* Adapt current acoustic model using a linear transform.
*
* @param mllr The new transform to use, or NULL to update the existing
* transform. The decoder retains ownership of this pointer,
* so you should not attempt to free it manually. Use
* ps_mllr_retain() if you wish to reuse it
* elsewhere.
* @return The updated transform object for this decoder, or
* NULL on failure.
*/
POCKETSPHINX_EXPORT
ps_mllr_t *ps_update_mllr(ps_decoder_t *ps, ps_mllr_t *mllr);
/**
* Reload the pronunciation dictionary from a file.
*
* This function replaces the current pronunciation dictionary with
* the one stored in dictfile. This also causes the active search
* module(s) to be reinitialized, in the same manner as calling
* ps_add_word() with update=TRUE.
*
* @param dictfile Path to dictionary file to load.
* @param fdictfile Path to filler dictionary to load, or NULL to keep
* the existing filler dictionary.
* @param format Format of the dictionary file, or NULL to determine
* automatically (currently unused,should be NULL)
*/
POCKETSPHINX_EXPORT
int ps_load_dict(ps_decoder_t *ps, char const *dictfile,
char const *fdictfile, char const *format);
/**
* Dump the current pronunciation dictionary to a file.
*
* This function dumps the current pronunciation dictionary to a tex
*
* @param dictfile Path to file where dictionary will be written.
* @param format Format of the dictionary file, or NULL for the
* default (text) format (currently unused, should be NULL)
*/
POCKETSPHINX_EXPORT
int ps_save_dict(ps_decoder_t *ps, char const *dictfile, char const *format);
/**
* Add a word to the pronunciation dictionary.
*
* This function adds a word to the pronunciation dictionary and the
* current language model (but, obviously, not to the current FSG if
* FSG mode is enabled). If the word is already present in one or the
* other, it does whatever is necessary to ensure that the word can be
* recognized.
*
* @param word Word string to add.
* @param phones Whitespace-separated list of phoneme strings
* describing pronunciation of <code>word</code>.
* @param update If TRUE, update the search module (whichever one is
* currently active) to recognize the newly added word.
* If adding multiple words, it is more efficient to
* pass FALSE here in all but the last word.
* @return The internal ID (>= 0) of the newly added word, or <0 on
* failure.
*/
POCKETSPHINX_EXPORT
int ps_add_word(ps_decoder_t *ps,
char const *word,
char const *phones,
int update);
/**
* Lookup for the word in the dictionary and return phone transcription
* for it.
*
* @param ps Pocketsphinx decoder
* @param word Word to look for
*
* @return Whitespace-spearated phone string describing the pronunciation of the <code>word</code>
* or NULL if word is not present in the dictionary. The string is
* allocated and must be freed by the user.
*/
POCKETSPHINX_EXPORT
char *ps_lookup_word(ps_decoder_t *ps,
const char *word);
/**
* Decode a raw audio stream.
*
* No headers are recognized in this files. The configuration
* parameters <tt>-samprate</tt> and <tt>-input_endian</tt> are used
* to determine the sampling rate and endianness of the stream,
* respectively. Audio is always assumed to be 16-bit signed PCM.
*
* @param ps Decoder.
* @param rawfh Previously opened file stream.
* @param maxsamps Maximum number of samples to read from rawfh, or -1
* to read until end-of-file.
* @return Number of samples of audio.
*/
POCKETSPHINX_EXPORT
long ps_decode_raw(ps_decoder_t *ps, FILE *rawfh,
long maxsamps);
/**
* Decode a senone score dump file.
*
* @param ps Decoder
* @param fh Previously opened file handle positioned at start of file.
* @return Number of frames read.
*/
POCKETSPHINX_EXPORT
int ps_decode_senscr(ps_decoder_t *ps, FILE *senfh);
/**
* Start processing of the stream of speech. Channel parameters like
* noise-level are maintained for the stream and reused among utterances.
* Times returned in segment iterators are also stream-wide.
*
* @return 0 for success, <0 on error.
*/
POCKETSPHINX_EXPORT
int ps_start_stream(ps_decoder_t *ps);
/**
* Start utterance processing.
*
* This function should be called before any utterance data is passed
* to the decoder. It marks the start of a new utterance and
* reinitializes internal data structures.
*
* @param ps Decoder to be started.
* @return 0 for success, <0 on error.
*/
POCKETSPHINX_EXPORT
int ps_start_utt(ps_decoder_t *ps);
/**
* Decode raw audio data.
*
* @param ps Decoder.
* @param no_search If non-zero, perform feature extraction but don't
* do any recognition yet. This may be necessary if
* your processor has trouble doing recognition in
* real-time.
* @param full_utt If non-zero, this block of data is a full utterance
* worth of data. This may allow the recognizer to
* produce more accurate results.
* @return Number of frames of data searched, or <0 for error.
*/
POCKETSPHINX_EXPORT
int ps_process_raw(ps_decoder_t *ps,
int16 const *data,
size_t n_samples,
int no_search,
int full_utt);
/**
* Decode acoustic feature data.
*
* @param ps Decoder.
* @param no_search If non-zero, perform feature extraction but don't
* do any recognition yet. This may be necessary if
* your processor has trouble doing recognition in
* real-time.
* @param full_utt If non-zero, this block of data is a full utterance
* worth of data. This may allow the recognizer to
* produce more accurate results.
* @return Number of frames of data searched, or <0 for error.
*/
POCKETSPHINX_EXPORT
int ps_process_cep(ps_decoder_t *ps,
mfcc_t **data,
int n_frames,
int no_search,
int full_utt);
/**
* Get the number of frames of data searched.
*
* Note that there is a delay between this and the number of frames of
* audio which have been input to the system. This is due to the fact
* that acoustic features are computed using a sliding window of
* audio, and dynamic features are computed over a sliding window of
* acoustic features.
*
* @param ps Decoder.
* @return Number of frames of speech data which have been recognized
* so far.
*/
POCKETSPHINX_EXPORT
int ps_get_n_frames(ps_decoder_t *ps);
/**
* End utterance processing.
*
* @param ps Decoder.
* @return 0 for success, <0 on error
*/
POCKETSPHINX_EXPORT
int ps_end_utt(ps_decoder_t *ps);
/**
* Get hypothesis string and path score.
*
* @param ps Decoder.
* @param out_best_score Output: path score corresponding to returned string.
* @return String containing best hypothesis at this point in
* decoding. NULL if no hypothesis is available.
*/
POCKETSPHINX_EXPORT
char const *ps_get_hyp(ps_decoder_t *ps, int32 *out_best_score);
/**
* Get hypothesis string and final flag.
*
* @param ps Decoder.
* @param out_is_best_score Output: if hypothesis is reached final state in the grammar.
* @return String containing best hypothesis at this point in
* decoding. NULL if no hypothesis is available.
*/
POCKETSPHINX_EXPORT
char const *ps_get_hyp_final(ps_decoder_t *ps, int32 *out_is_final);
/**
* Get posterior probability.
*
* @note Unless the -bestpath option is enabled, this function will
* always return zero (corresponding to a posterior probability of
* 1.0). Even if -bestpath is enabled, it will also return zero when
* called on a partial result. Ongoing research into effective
* confidence annotation for partial hypotheses may result in these
* restrictions being lifted in future versions.
*
* @param ps Decoder.
* @return Posterior probability of the best hypothesis.
*/
POCKETSPHINX_EXPORT
int32 ps_get_prob(ps_decoder_t *ps);
/**
* Get word lattice.
*
* There isn't much you can do with this so far, a public API will
* appear in the future.
*
* @param ps Decoder.
* @return Word lattice object containing all hypotheses so far. NULL
* if no hypotheses are available. This pointer is owned by
* the decoder and you should not attempt to free it manually.
* It is only valid until the next utterance, unless you use
* ps_lattice_retain() to retain it.
*/
POCKETSPHINX_EXPORT
ps_lattice_t *ps_get_lattice(ps_decoder_t *ps);
/**
* Get an iterator over the word segmentation for the best hypothesis.
*
* @param ps Decoder.
* @param out_best_score Output: path score corresponding to hypothesis.
* @return Iterator over the best hypothesis at this point in
* decoding. NULL if no hypothesis is available.
*/
POCKETSPHINX_EXPORT
ps_seg_t *ps_seg_iter(ps_decoder_t *ps, int32 *out_best_score);
/**
* Get the next segment in a word segmentation.
*
* @param seg Segment iterator.
* @return Updated iterator with the next segment. NULL at end of
* utterance (the iterator will be freed in this case).
*/
POCKETSPHINX_EXPORT
ps_seg_t *ps_seg_next(ps_seg_t *seg);
/**
* Get word string from a segmentation iterator.
*
* @param seg Segment iterator.
* @return Read-only string giving string name of this segment. This
* is only valid until the next call to ps_seg_next().
*/
POCKETSPHINX_EXPORT
char const *ps_seg_word(ps_seg_t *seg);
/**
* Get inclusive start and end frames from a segmentation iterator.
*
* @note These frame numbers are inclusive, i.e. the end frame refers
* to the last frame in which the given word or other segment was
* active. Therefore, the actual duration is *out_ef - *out_sf + 1.
*
* @param seg Segment iterator.
* @param out_sf Output: First frame index in segment.
* @param out_sf Output: Last frame index in segment.
*/
POCKETSPHINX_EXPORT
void ps_seg_frames(ps_seg_t *seg, int *out_sf, int *out_ef);
/**
* Get language, acoustic, and posterior probabilities from a
* segmentation iterator.
*
* @note Unless the -bestpath option is enabled, this function will
* always return zero (corresponding to a posterior probability of
* 1.0). Even if -bestpath is enabled, it will also return zero when
* called on a partial result. Ongoing research into effective
* confidence annotation for partial hypotheses may result in these
* restrictions being lifted in future versions.
*
* @param out_ascr Output: acoustic model score for this segment.
* @param out_lscr Output: language model score for this segment.
* @param out_lback Output: language model backoff mode for this
* segment (i.e. the number of words used in
* calculating lscr). This field is, of course, only
* meaningful for N-Gram models.
* @return Log posterior probability of current segment. Log is
* expressed in the log-base used in the decoder. To convert
* to linear floating-point, use logmath_exp(ps_get_logmath(),
* pprob).
*/
POCKETSPHINX_EXPORT
int32 ps_seg_prob(ps_seg_t *seg, int32 *out_ascr, int32 *out_lscr, int32 *out_lback);
/**
* Finish iterating over a word segmentation early, freeing resources.
*/
POCKETSPHINX_EXPORT
void ps_seg_free(ps_seg_t *seg);
/**
* Get an iterator over the best hypotheses, optionally within a
* selected region of the utterance. Iterator is empty now, it must
* be advanced with ps_nbest_next first. The function may also
* return a NULL which means that there is no hypothesis available for this
* utterance.
*
* @param ps Decoder.
* @param sf Start frame for N-best search (0 for whole utterance)
* @param ef End frame for N-best search (-1 for whole utterance)
* @param ctx1 First word of trigram context (NULL for whole utterance)
* @param ctx2 First word of trigram context (NULL for whole utterance)
* @return Iterator over N-best hypotheses or NULL if no hypothesis is available
*/
POCKETSPHINX_EXPORT
ps_nbest_t *ps_nbest(ps_decoder_t *ps, int sf, int ef,
char const *ctx1, char const *ctx2);
/**
* Move an N-best list iterator forward.
*
* @param nbest N-best iterator.
* @return Updated N-best iterator, or NULL if no more hypotheses are
* available (iterator is freed ni this case).
*/
POCKETSPHINX_EXPORT
ps_nbest_t *ps_nbest_next(ps_nbest_t *nbest);
/**
* Get the hypothesis string from an N-best list iterator.
*
* @param nbest N-best iterator.
* @param out_score Output: Path score for this hypothesis.
* @return String containing next best hypothesis.
*/
POCKETSPHINX_EXPORT
char const *ps_nbest_hyp(ps_nbest_t *nbest, int32 *out_score);
/**
* Get the word segmentation from an N-best list iterator.
*
* @param nbest N-best iterator.
* @param out_score Output: Path score for this hypothesis.
* @return Iterator over the next best hypothesis.
*/
POCKETSPHINX_EXPORT
ps_seg_t *ps_nbest_seg(ps_nbest_t *nbest, int32 *out_score);
/**
* Finish N-best search early, releasing resources.
*
* @param nbest N-best iterator.
*/
POCKETSPHINX_EXPORT
void ps_nbest_free(ps_nbest_t *nbest);
/**
* Get performance information for the current utterance.
*
* @param ps Decoder.
* @param out_nspeech Output: Number of seconds of speech.
* @param out_ncpu Output: Number of seconds of CPU time used.
* @param out_nwall Output: Number of seconds of wall time used.
*/
POCKETSPHINX_EXPORT
void ps_get_utt_time(ps_decoder_t *ps, double *out_nspeech,
double *out_ncpu, double *out_nwall);
/**
* Get overall performance information.
*
* @param ps Decoder.
* @param out_nspeech Output: Number of seconds of speech.
* @param out_ncpu Output: Number of seconds of CPU time used.
* @param out_nwall Output: Number of seconds of wall time used.
*/
POCKETSPHINX_EXPORT
void ps_get_all_time(ps_decoder_t *ps, double *out_nspeech,
double *out_ncpu, double *out_nwall);
/**
* Checks if the last feed audio buffer contained speech
*
* @param ps Decoder.
* @return 1 if last buffer contained speech, 0 - otherwise
*/
POCKETSPHINX_EXPORT
uint8 ps_get_in_speech(ps_decoder_t *ps);
/**
* Sets the limit of the raw audio data to store in decoder
* to retrieve it later on ps_get_rawdata.
*
* @param ps Decoder
* @param size bytes of the utterance to store
*/
POCKETSPHINX_EXPORT
void ps_set_rawdata_size(ps_decoder_t *ps, int32 size);
/**
* Retrieves the raw data collected during utterance decoding.
*
* @param ps Decoder
* @param buffer preallocated buffer to store the data, must be within the limit
* set before
* @param size size of the data collected in samples (not bytes).
*/
POCKETSPHINX_EXPORT
void ps_get_rawdata(ps_decoder_t *ps, int16 **buffer, int32 *size);
/**
* @mainpage PocketSphinx API Documentation
* @author David Huggins-Daines <dhuggins@cs.cmu.edu>
* @author Alpha Cephei Inc.
* @version 5prealpha
* @date July, 2015
*
* @section intro_sec Introduction
*
* This is the API documentation for the PocketSphinx speech
* recognition engine. The main API calls are documented in
* <pocketsphinx.h>.
*/
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* __POCKETSPHINX_H__ */

View File

@ -0,0 +1,15 @@
#ifndef __POCKETSPHINX_EXPORT_H__
#define __POCKETSPHINX_EXPORT_H__
/* Win32/WinCE DLL gunk */
#if (defined(_WIN32) || defined(_WIN32_WCE)) && !defined(_WIN32_WP) && !defined(__MINGW32__) && !defined(__CYGWIN__) && !defined(__WINSCW__) && !defined(__SYMBIAN32__)
#ifdef POCKETSPHINX_EXPORTS /* Visual Studio */
#define POCKETSPHINX_EXPORT __declspec(dllexport)
#else
#define POCKETSPHINX_EXPORT __declspec(dllimport)
#endif
#else /* !_WIN32 */
#define POCKETSPHINX_EXPORT
#endif
#endif /* __POCKETSPHINX_EXPORT_H__ */

View File

@ -0,0 +1,445 @@
/* -*- c-basic-offset: 4; indent-tabs-mode: nil -*- */
/* ====================================================================
* Copyright (c) 2008 Carnegie Mellon University. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. 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 work was supported in part by funding from the Defense Advanced
* Research Projects Agency and the National Science Foundation of the
* United States of America, and the CMU Sphinx Speech Consortium.
*
* THIS SOFTWARE IS PROVIDED BY CARNEGIE MELLON UNIVERSITY ``AS IS'' AND
* ANY EXPRESSED 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 CARNEGIE MELLON UNIVERSITY
* NOR ITS EMPLOYEES 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.
*
* ====================================================================
*
*/
/**
* @file ps_lattice.h Word graph search
*/
#ifndef __PS_LATTICE_H__
#define __PS_LATTICE_H__
/* SphinxBase headers. */
#include <sphinxbase/prim_type.h>
#include <sphinxbase/ngram_model.h>
/* PocketSphinx headers. */
#include <pocketsphinx_export.h>
/**
* Word graph structure used in bestpath/nbest search.
*/
typedef struct ps_lattice_s ps_lattice_t;
/**
* DAG nodes.
*
* A node corresponds to a number of hypothesized instances of a word
* which all share the same starting point.
*/
typedef struct ps_latnode_s ps_latnode_t;
/**
* Iterator over DAG nodes.
*/
typedef struct ps_latnode_s ps_latnode_iter_t; /* pay no attention to the man behind the curtain */
/**
* Links between DAG nodes.
*
* A link corresponds to a single hypothesized instance of a word with
* a given start and end point.
*/
typedef struct ps_latlink_s ps_latlink_t;
/**
* Iterator over DAG links.
*/
typedef struct latlink_list_s ps_latlink_iter_t;
/* Forward declaration needed to avoid circular includes */
struct ps_decoder_s;
/**
* Read a lattice from a file on disk.
*
* @param ps Decoder to use for processing this lattice, or NULL.
* @param file Path to lattice file.
* @return Newly created lattice, or NULL for failure.
*/
POCKETSPHINX_EXPORT
ps_lattice_t *ps_lattice_read(struct ps_decoder_s *ps,
char const *file);
/**
* Retain a lattice.
*
* This function retains ownership of a lattice for the caller,
* preventing it from being freed automatically. You must call
* ps_lattice_free() to free it after having called this function.
*
* @return pointer to the retained lattice.
*/
POCKETSPHINX_EXPORT
ps_lattice_t *ps_lattice_retain(ps_lattice_t *dag);
/**
* Free a lattice.
*
* @return new reference count (0 if dag was freed)
*/
POCKETSPHINX_EXPORT
int ps_lattice_free(ps_lattice_t *dag);
/**
* Write a lattice to disk.
*
* @return 0 for success, <0 on failure.
*/
POCKETSPHINX_EXPORT
int ps_lattice_write(ps_lattice_t *dag, char const *filename);
/**
* Write a lattice to disk in HTK format
*
* @return 0 for success, <0 on failure.
*/
POCKETSPHINX_EXPORT
int ps_lattice_write_htk(ps_lattice_t *dag, char const *filename);
/**
* Get the log-math computation object for this lattice
*
* @return The log-math object for this lattice. The lattice retains
* ownership of this pointer, so you should not attempt to
* free it manually. Use logmath_retain() if you wish to
* reuse it elsewhere.
*/
POCKETSPHINX_EXPORT
logmath_t *ps_lattice_get_logmath(ps_lattice_t *dag);
/**
* Start iterating over nodes in the lattice.
*
* @note No particular order of traversal is guaranteed, and you
* should not depend on this.
*
* @param dag Lattice to iterate over.
* @return Iterator over lattice nodes.
*/
POCKETSPHINX_EXPORT
ps_latnode_iter_t *ps_latnode_iter(ps_lattice_t *dag);
/**
* Move to next node in iteration.
* @param itor Node iterator.
* @return Updated node iterator, or NULL if finished
*/
POCKETSPHINX_EXPORT
ps_latnode_iter_t *ps_latnode_iter_next(ps_latnode_iter_t *itor);
/**
* Stop iterating over nodes.
* @param itor Node iterator.
*/
POCKETSPHINX_EXPORT
void ps_latnode_iter_free(ps_latnode_iter_t *itor);
/**
* Get node from iterator.
*/
POCKETSPHINX_EXPORT
ps_latnode_t *ps_latnode_iter_node(ps_latnode_iter_t *itor);
/**
* Get start and end time range for a node.
*
* @param node Node inquired about.
* @param out_fef Output: End frame of first exit from this node.
* @param out_lef Output: End frame of last exit from this node.
* @return Start frame for all edges exiting this node.
*/
POCKETSPHINX_EXPORT
int ps_latnode_times(ps_latnode_t *node, int16 *out_fef, int16 *out_lef);
/**
* Get word string for this node.
*
* @param dag Lattice to which node belongs.
* @param node Node inquired about.
* @return Word string for this node (possibly a pronunciation variant).
*/
POCKETSPHINX_EXPORT
char const *ps_latnode_word(ps_lattice_t *dag, ps_latnode_t *node);
/**
* Get base word string for this node.
*
* @param dag Lattice to which node belongs.
* @param node Node inquired about.
* @return Base word string for this node.
*/
POCKETSPHINX_EXPORT
char const *ps_latnode_baseword(ps_lattice_t *dag, ps_latnode_t *node);
/**
* Iterate over exits from this node.
*
* @param node Node inquired about.
* @return Iterator over exit links from this node.
*/
POCKETSPHINX_EXPORT
ps_latlink_iter_t *ps_latnode_exits(ps_latnode_t *node);
/**
* Iterate over entries to this node.
*
* @param node Node inquired about.
* @return Iterator over entry links to this node.
*/
POCKETSPHINX_EXPORT
ps_latlink_iter_t *ps_latnode_entries(ps_latnode_t *node);
/**
* Get best posterior probability and associated acoustic score from a lattice node.
*
* @param dag Lattice to which node belongs.
* @param node Node inquired about.
* @param out_link Output: exit link with highest posterior probability
* @return Posterior probability of the best link exiting this node.
* Log is expressed in the log-base used in the decoder. To
* convert to linear floating-point, use
* logmath_exp(ps_lattice_get_logmath(), pprob).
*/
POCKETSPHINX_EXPORT
int32 ps_latnode_prob(ps_lattice_t *dag, ps_latnode_t *node,
ps_latlink_t **out_link);
/**
* Get next link from a lattice link iterator.
*
* @param itor Iterator.
* @return Updated iterator, or NULL if finished.
*/
POCKETSPHINX_EXPORT
ps_latlink_iter_t *ps_latlink_iter_next(ps_latlink_iter_t *itor);
/**
* Stop iterating over links.
* @param itor Link iterator.
*/
POCKETSPHINX_EXPORT
void ps_latlink_iter_free(ps_latlink_iter_t *itor);
/**
* Get link from iterator.
*/
POCKETSPHINX_EXPORT
ps_latlink_t *ps_latlink_iter_link(ps_latlink_iter_t *itor);
/**
* Get start and end times from a lattice link.
*
* @note these are <strong>inclusive</strong> - i.e. the last frame of
* this word is ef, not ef-1.
*
* @param link Link inquired about.
* @param out_sf Output: (optional) start frame of this link.
* @return End frame of this link.
*/
POCKETSPHINX_EXPORT
int ps_latlink_times(ps_latlink_t *link, int16 *out_sf);
/**
* Get destination and source nodes from a lattice link
*
* @param link Link inquired about
* @param out_src Output: (optional) source node.
* @return destination node
*/
POCKETSPHINX_EXPORT
ps_latnode_t *ps_latlink_nodes(ps_latlink_t *link, ps_latnode_t **out_src);
/**
* Get word string from a lattice link.
*
* @param dag Lattice to which node belongs.
* @param link Link inquired about
* @return Word string for this link (possibly a pronunciation variant).
*/
POCKETSPHINX_EXPORT
char const *ps_latlink_word(ps_lattice_t *dag, ps_latlink_t *link);
/**
* Get base word string from a lattice link.
*
* @param dag Lattice to which node belongs.
* @param link Link inquired about
* @return Base word string for this link
*/
POCKETSPHINX_EXPORT
char const *ps_latlink_baseword(ps_lattice_t *dag, ps_latlink_t *link);
/**
* Get predecessor link in best path.
*
* @param link Link inquired about
* @return Best previous link from bestpath search, if any. Otherwise NULL
*/
POCKETSPHINX_EXPORT
ps_latlink_t *ps_latlink_pred(ps_latlink_t *link);
/**
* Get acoustic score and posterior probability from a lattice link.
*
* @param dag Lattice to which node belongs.
* @param link Link inquired about
* @param out_ascr Output: (optional) acoustic score.
* @return Posterior probability for this link. Log is expressed in
* the log-base used in the decoder. To convert to linear
* floating-point, use logmath_exp(ps_lattice_get_logmath(), pprob).
*/
POCKETSPHINX_EXPORT
int32 ps_latlink_prob(ps_lattice_t *dag, ps_latlink_t *link, int32 *out_ascr);
/**
* Create a directed link between "from" and "to" nodes, but if a link already exists,
* choose one with the best link_scr.
*/
POCKETSPHINX_EXPORT
void ps_lattice_link(ps_lattice_t *dag, ps_latnode_t *from, ps_latnode_t *to,
int32 score, int32 ef);
/**
* Start a forward traversal of edges in a word graph.
*
* @note A keen eye will notice an inconsistency in this API versus
* other types of iterators in PocketSphinx. The reason for this is
* that the traversal algorithm is much more efficient when it is able
* to modify the lattice structure. Therefore, to avoid giving the
* impression that multiple traversals are possible at once, no
* separate iterator structure is provided.
*
* @param dag Lattice to be traversed.
* @param start Start node (source) of traversal.
* @param end End node (goal) of traversal.
* @return First link in traversal.
*/
POCKETSPHINX_EXPORT
ps_latlink_t *ps_lattice_traverse_edges(ps_lattice_t *dag, ps_latnode_t *start, ps_latnode_t *end);
/**
* Get the next link in forward traversal.
*
* @param dag Lattice to be traversed.
* @param end End node (goal) of traversal.
* @return Next link in traversal.
*/
POCKETSPHINX_EXPORT
ps_latlink_t *ps_lattice_traverse_next(ps_lattice_t *dag, ps_latnode_t *end);
/**
* Start a reverse traversal of edges in a word graph.
*
* @note See ps_lattice_traverse_edges() for why this API is the way it is.
*
* @param dag Lattice to be traversed.
* @param start Start node (goal) of traversal.
* @param end End node (source) of traversal.
* @return First link in traversal.
*/
POCKETSPHINX_EXPORT
ps_latlink_t *ps_lattice_reverse_edges(ps_lattice_t *dag, ps_latnode_t *start, ps_latnode_t *end);
/**
* Get the next link in reverse traversal.
*
* @param dag Lattice to be traversed.
* @param start Start node (goal) of traversal.
* @return Next link in traversal.
*/
POCKETSPHINX_EXPORT
ps_latlink_t *ps_lattice_reverse_next(ps_lattice_t *dag, ps_latnode_t *start);
/**
* Do N-Gram based best-path search on a word graph.
*
* This function calculates both the best path as well as the forward
* probability used in confidence estimation.
*
* @return Final link in best path, NULL on error.
*/
POCKETSPHINX_EXPORT
ps_latlink_t *ps_lattice_bestpath(ps_lattice_t *dag, ngram_model_t *lmset,
float32 lwf, float32 ascale);
/**
* Calculate link posterior probabilities on a word graph.
*
* This function assumes that bestpath search has already been done.
*
* @return Posterior probability of the utterance as a whole.
*/
POCKETSPHINX_EXPORT
int32 ps_lattice_posterior(ps_lattice_t *dag, ngram_model_t *lmset,
float32 ascale);
/**
* Prune all links (and associated nodes) below a certain posterior probability.
*
* This function assumes that ps_lattice_posterior() has already been called.
*
* @param beam Minimum posterior probability for links. This is
* expressed in the log-base used in the decoder. To convert
* from linear floating-point, use
* logmath_log(ps_lattice_get_logmath(), prob).
* @return number of arcs removed.
*/
POCKETSPHINX_EXPORT
int32 ps_lattice_posterior_prune(ps_lattice_t *dag, int32 beam);
#ifdef NOT_IMPLEMENTED_YET
/**
* Expand lattice using an N-gram language model.
*
* This function expands the lattice such that each node represents a
* unique N-gram history, and adds language model scores to the links.
*/
POCKETSPHINX_EXPORT
int32 ps_lattice_ngram_expand(ps_lattice_t *dag, ngram_model_t *lm);
#endif
/**
* Get the number of frames in the lattice.
*
* @param dag The lattice in question.
* @return Number of frames in this lattice.
*/
POCKETSPHINX_EXPORT
int ps_lattice_n_frames(ps_lattice_t *dag);
#endif /* __PS_LATTICE_H__ */

View File

@ -0,0 +1,75 @@
/* -*- c-basic-offset: 4; indent-tabs-mode: nil -*- */
/* ====================================================================
* Copyright (c) 2008 Carnegie Mellon University. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. 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 work was supported in part by funding from the Defense Advanced
* Research Projects Agency and the National Science Foundation of the
* United States of America, and the CMU Sphinx Speech Consortium.
*
* THIS SOFTWARE IS PROVIDED BY CARNEGIE MELLON UNIVERSITY ``AS IS'' AND
* ANY EXPRESSED 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 CARNEGIE MELLON UNIVERSITY
* NOR ITS EMPLOYEES 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.
*
* ====================================================================
*
*/
/**
* @file ps_mllr.h Model-space linear transforms for speaker adaptation
*/
#ifndef __PS_MLLR_H__
#define __PS_MLLR_H__
/* SphinxBase headers. */
#include <sphinxbase/prim_type.h>
#include <sphinxbase/ngram_model.h>
/* PocketSphinx headers. */
#include <pocketsphinx_export.h>
/**
* Feature space linear transform object.
*/
typedef struct ps_mllr_s ps_mllr_t;
/**
* Read a speaker-adaptive linear transform from a file.
*/
POCKETSPHINX_EXPORT
ps_mllr_t *ps_mllr_read(char const *file);
/**
* Retain a pointer to a linear transform.
*/
POCKETSPHINX_EXPORT
ps_mllr_t *ps_mllr_retain(ps_mllr_t *mllr);
/**
* Release a pointer to a linear transform.
*/
POCKETSPHINX_EXPORT
int ps_mllr_free(ps_mllr_t *mllr);
#endif /* __PS_MLLR_H__ */

View File

@ -0,0 +1,297 @@
/* -*- c-basic-offset:4; indent-tabs-mode: nil -*- */
/* ====================================================================
* Copyright (c) 2014 Alpha Cephei Inc.. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. 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 ALPHA CEPHEI INC. ``AS IS'' AND
* ANY EXPRESSED 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 CARNEGIE MELLON UNIVERSITY
* NOR ITS EMPLOYEES 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.
*
* ====================================================================
*
*/
/**
* @file ps_search.h User can configure several "search" objects with
* different grammars and langauge models and switch them in runtime to
* provide interactive experience for the user.
*
* There are different possible search modes:
*
* <ul>
* <li>keyword - efficiently looks for keyphrase and ignores other speech. allows to configure detection threshold.</li>
* <li>grammar - recognizes speech according to JSGF grammar. Unlike keyphrase grammar search doesn't ignore words which are not in grammar but tries to recognize them.</li>
* <li>ngram/lm - recognizes natural speech with a language model.</li>
* <li>allphone - recognizes phonemes with a phonetic language model.</li>
* </ul>
*
* Each search has a name and can be referenced by a name, names are
* application-specific. The function ps_set_search allows to activate
* the search previously added by a name. Only single search can be
* activated at time.
*
* To add the search one needs to point to the grammar/language model
* describing the search. The location of the grammar is specific to the
* application.
*
* The exact design of a searches depends on your application. For
* example, you might want to listen for activation keyword first and once
* keyword is recognized switch to ngram search to recognize actual
* command. Once you recognized the command you can switch to grammar
* search to recognize the confirmation and then switch back to keyword listening
* mode to wait for another command.
*
* If only a simple recognition is required it is sufficient to add a single search or
* just configure the required mode with configuration options.
*/
#ifndef __PS_SEARCH_H__
#define __PS_SEARCH_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <sphinxbase/fsg_model.h>
#include <sphinxbase/ngram_model.h>
/**
* PocketSphinx search iterator.
*/
typedef struct ps_search_iter_s ps_search_iter_t;
/**
* Actives search with the provided name.
*
* Activates search with the provided name. The search must be added before
* using either ps_set_fsg(), ps_set_lm() or ps_set_kws().
*
* @return 0 on success, -1 on failure
*/
POCKETSPHINX_EXPORT
int ps_set_search(ps_decoder_t *ps, const char *name);
/**
* Returns name of curent search in decoder
*
* @see ps_set_search
*/
POCKETSPHINX_EXPORT
const char* ps_get_search(ps_decoder_t *ps);
/**
* Unsets the search and releases related resources.
*
* Unsets the search previously added with
* using either ps_set_fsg(), ps_set_lm() or ps_set_kws().
*
* @see ps_set_fsg
* @see ps_set_lm
* @see ps_set_kws
*/
POCKETSPHINX_EXPORT
int ps_unset_search(ps_decoder_t *ps, const char *name);
/**
* Returns iterator over current searches
*
* @see ps_set_search
*/
POCKETSPHINX_EXPORT
ps_search_iter_t *ps_search_iter(ps_decoder_t *ps);
/**
* Updates search iterator to point to the next position.
*
* This function automatically frees the iterator object upon reaching
* the final entry.
* @see ps_set_search
*/
POCKETSPHINX_EXPORT
ps_search_iter_t *ps_search_iter_next(ps_search_iter_t *itor);
/**
* Retrieves the name of the search the iterator points to.
*
* @see ps_set_search
*/
POCKETSPHINX_EXPORT
const char* ps_search_iter_val(ps_search_iter_t *itor);
/**
* Delete an unfinished search iterator
*
* @see ps_set_search
*/
POCKETSPHINX_EXPORT
void ps_search_iter_free(ps_search_iter_t *itor);
/**
* Updates search iterator to point to the next position.
*
* This function automatically frees the iterator object upon reaching
* the final entry.
* @see ps_set_search
*/
POCKETSPHINX_EXPORT
const char* ps_search_iter_val(ps_search_iter_t *itor);
/**
* Get the language model set object for this decoder.
*
* If N-Gram decoding is not enabled, this will return NULL. You will
* need to enable it using ps_set_lmset().
*
* @return The language model set object for this decoder. The
* decoder retains ownership of this pointer, so you should
* not attempt to free it manually. Use ngram_model_retain()
* if you wish to reuse it elsewhere.
*/
POCKETSPHINX_EXPORT
ngram_model_t *ps_get_lm(ps_decoder_t *ps, const char *name);
/**
* Adds new search based on N-gram language model.
*
* Associates N-gram search with the provided name. The search can be activated
* using ps_set_search().
*
* @see ps_set_search.
*/
POCKETSPHINX_EXPORT
int ps_set_lm(ps_decoder_t *ps, const char *name, ngram_model_t *lm);
/**
* Adds new search based on N-gram language model.
*
* Convenient method to load N-gram model and create a search.
*
* @see ps_set_lm
*/
POCKETSPHINX_EXPORT
int ps_set_lm_file(ps_decoder_t *ps, const char *name, const char *path);
/**
* Get the finite-state grammar set object for this decoder.
*
* If FSG decoding is not enabled, this returns NULL. Call
* ps_set_fsgset() to enable it.
*
* @return The current FSG set object for this decoder, or
* NULL if none is available.
*/
POCKETSPHINX_EXPORT
fsg_model_t *ps_get_fsg(ps_decoder_t *ps, const char *name);
/**
* Adds new search based on finite state grammar.
*
* Associates FSG search with the provided name. The search can be activated
* using ps_set_search().
*
* @see ps_set_search
*/
POCKETSPHINX_EXPORT
int ps_set_fsg(ps_decoder_t *ps, const char *name, fsg_model_t *fsg);
/**
* Adds new search using JSGF model.
*
* Convenient method to load JSGF model and create a search.
*
* @see ps_set_fsg
*/
POCKETSPHINX_EXPORT
int ps_set_jsgf_file(ps_decoder_t *ps, const char *name, const char *path);
/**
* Adds new search using JSGF model.
*
* Convenience method to parse JSGF model from string and create a search.
*
* @see ps_set_fsg
*/
POCKETSPHINX_EXPORT
int ps_set_jsgf_string(ps_decoder_t *ps, const char *name, const char *jsgf_string);
/**
* Get the current Key phrase to spot
*
* If KWS is not enabled, this returns NULL. Call
* ps_update_kws() to enable it.
*
* @return The current keyphrase to spot
*/
POCKETSPHINX_EXPORT
const char* ps_get_kws(ps_decoder_t *ps, const char *name);
/**
* Adds keywords from a file to spotting
*
* Associates KWS search with the provided name. The search can be activated
* using ps_set_search().
*
* @see ps_set_search
*/
POCKETSPHINX_EXPORT
int ps_set_kws(ps_decoder_t *ps, const char *name, const char *keyfile);
/**
* Adds new keyword to spot
*
* Associates KWS search with the provided name. The search can be activated
* using ps_set_search().
*
* @see ps_set_search
*/
POCKETSPHINX_EXPORT
int ps_set_keyphrase(ps_decoder_t *ps, const char *name, const char *keyphrase);
/**
* Adds new search based on phone N-gram language model.
*
* Associates N-gram search with the provided name. The search can be activated
* using ps_set_search().
*
* @see ps_set_search.
*/
POCKETSPHINX_EXPORT
int ps_set_allphone(ps_decoder_t *ps, const char *name, ngram_model_t *lm);
/**
* Adds new search based on phone N-gram language model.
*
* Convenient method to load N-gram model and create a search.
*
* @see ps_set_allphone
*/
POCKETSPHINX_EXPORT
int ps_set_allphone_file(ps_decoder_t *ps, const char *name, const char *path);
#ifdef __cplusplus
}
#endif
#endif /* __PS_SEARCH_H__ */

View File

@ -0,0 +1,527 @@
#!/bin/sh
# install - install a program, script, or datafile
scriptversion=2011-11-20.07; # UTC
# This originates from X11R5 (mit/util/scripts/install.sh), which was
# later released in X11R6 (xc/config/util/install.sh) with the
# following copyright and license.
#
# Copyright (C) 1994 X Consortium
#
# 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
# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# Except as contained in this notice, the name of the X Consortium shall not
# be used in advertising or otherwise to promote the sale, use or other deal-
# ings in this Software without prior written authorization from the X Consor-
# tium.
#
#
# FSF changes to this file are in the public domain.
#
# Calling this script install-sh is preferred over install.sh, to prevent
# 'make' implicit rules from creating a file called install from it
# when there is no Makefile.
#
# This script is compatible with the BSD install script, but was written
# from scratch.
nl='
'
IFS=" "" $nl"
# set DOITPROG to echo to test this script
# Don't use :- since 4.3BSD and earlier shells don't like it.
doit=${DOITPROG-}
if test -z "$doit"; then
doit_exec=exec
else
doit_exec=$doit
fi
# Put in absolute file names if you don't have them in your path;
# or use environment vars.
chgrpprog=${CHGRPPROG-chgrp}
chmodprog=${CHMODPROG-chmod}
chownprog=${CHOWNPROG-chown}
cmpprog=${CMPPROG-cmp}
cpprog=${CPPROG-cp}
mkdirprog=${MKDIRPROG-mkdir}
mvprog=${MVPROG-mv}
rmprog=${RMPROG-rm}
stripprog=${STRIPPROG-strip}
posix_glob='?'
initialize_posix_glob='
test "$posix_glob" != "?" || {
if (set -f) 2>/dev/null; then
posix_glob=
else
posix_glob=:
fi
}
'
posix_mkdir=
# Desired mode of installed file.
mode=0755
chgrpcmd=
chmodcmd=$chmodprog
chowncmd=
mvcmd=$mvprog
rmcmd="$rmprog -f"
stripcmd=
src=
dst=
dir_arg=
dst_arg=
copy_on_change=false
no_target_directory=
usage="\
Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
or: $0 [OPTION]... SRCFILES... DIRECTORY
or: $0 [OPTION]... -t DIRECTORY SRCFILES...
or: $0 [OPTION]... -d DIRECTORIES...
In the 1st form, copy SRCFILE to DSTFILE.
In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
In the 4th, create DIRECTORIES.
Options:
--help display this help and exit.
--version display version info and exit.
-c (ignored)
-C install only if different (preserve the last data modification time)
-d create directories instead of installing files.
-g GROUP $chgrpprog installed files to GROUP.
-m MODE $chmodprog installed files to MODE.
-o USER $chownprog installed files to USER.
-s $stripprog installed files.
-t DIRECTORY install into DIRECTORY.
-T report an error if DSTFILE is a directory.
Environment variables override the default commands:
CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
RMPROG STRIPPROG
"
while test $# -ne 0; do
case $1 in
-c) ;;
-C) copy_on_change=true;;
-d) dir_arg=true;;
-g) chgrpcmd="$chgrpprog $2"
shift;;
--help) echo "$usage"; exit $?;;
-m) mode=$2
case $mode in
*' '* | *' '* | *'
'* | *'*'* | *'?'* | *'['*)
echo "$0: invalid mode: $mode" >&2
exit 1;;
esac
shift;;
-o) chowncmd="$chownprog $2"
shift;;
-s) stripcmd=$stripprog;;
-t) dst_arg=$2
# Protect names problematic for 'test' and other utilities.
case $dst_arg in
-* | [=\(\)!]) dst_arg=./$dst_arg;;
esac
shift;;
-T) no_target_directory=true;;
--version) echo "$0 $scriptversion"; exit $?;;
--) shift
break;;
-*) echo "$0: invalid option: $1" >&2
exit 1;;
*) break;;
esac
shift
done
if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
# When -d is used, all remaining arguments are directories to create.
# When -t is used, the destination is already specified.
# Otherwise, the last argument is the destination. Remove it from $@.
for arg
do
if test -n "$dst_arg"; then
# $@ is not empty: it contains at least $arg.
set fnord "$@" "$dst_arg"
shift # fnord
fi
shift # arg
dst_arg=$arg
# Protect names problematic for 'test' and other utilities.
case $dst_arg in
-* | [=\(\)!]) dst_arg=./$dst_arg;;
esac
done
fi
if test $# -eq 0; then
if test -z "$dir_arg"; then
echo "$0: no input file specified." >&2
exit 1
fi
# It's OK to call 'install-sh -d' without argument.
# This can happen when creating conditional directories.
exit 0
fi
if test -z "$dir_arg"; then
do_exit='(exit $ret); exit $ret'
trap "ret=129; $do_exit" 1
trap "ret=130; $do_exit" 2
trap "ret=141; $do_exit" 13
trap "ret=143; $do_exit" 15
# Set umask so as not to create temps with too-generous modes.
# However, 'strip' requires both read and write access to temps.
case $mode in
# Optimize common cases.
*644) cp_umask=133;;
*755) cp_umask=22;;
*[0-7])
if test -z "$stripcmd"; then
u_plus_rw=
else
u_plus_rw='% 200'
fi
cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
*)
if test -z "$stripcmd"; then
u_plus_rw=
else
u_plus_rw=,u+rw
fi
cp_umask=$mode$u_plus_rw;;
esac
fi
for src
do
# Protect names problematic for 'test' and other utilities.
case $src in
-* | [=\(\)!]) src=./$src;;
esac
if test -n "$dir_arg"; then
dst=$src
dstdir=$dst
test -d "$dstdir"
dstdir_status=$?
else
# Waiting for this to be detected by the "$cpprog $src $dsttmp" command
# might cause directories to be created, which would be especially bad
# if $src (and thus $dsttmp) contains '*'.
if test ! -f "$src" && test ! -d "$src"; then
echo "$0: $src does not exist." >&2
exit 1
fi
if test -z "$dst_arg"; then
echo "$0: no destination specified." >&2
exit 1
fi
dst=$dst_arg
# If destination is a directory, append the input filename; won't work
# if double slashes aren't ignored.
if test -d "$dst"; then
if test -n "$no_target_directory"; then
echo "$0: $dst_arg: Is a directory" >&2
exit 1
fi
dstdir=$dst
dst=$dstdir/`basename "$src"`
dstdir_status=0
else
# Prefer dirname, but fall back on a substitute if dirname fails.
dstdir=`
(dirname "$dst") 2>/dev/null ||
expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
X"$dst" : 'X\(//\)[^/]' \| \
X"$dst" : 'X\(//\)$' \| \
X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
echo X"$dst" |
sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
s//\1/
q
}
/^X\(\/\/\)[^/].*/{
s//\1/
q
}
/^X\(\/\/\)$/{
s//\1/
q
}
/^X\(\/\).*/{
s//\1/
q
}
s/.*/./; q'
`
test -d "$dstdir"
dstdir_status=$?
fi
fi
obsolete_mkdir_used=false
if test $dstdir_status != 0; then
case $posix_mkdir in
'')
# Create intermediate dirs using mode 755 as modified by the umask.
# This is like FreeBSD 'install' as of 1997-10-28.
umask=`umask`
case $stripcmd.$umask in
# Optimize common cases.
*[2367][2367]) mkdir_umask=$umask;;
.*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
*[0-7])
mkdir_umask=`expr $umask + 22 \
- $umask % 100 % 40 + $umask % 20 \
- $umask % 10 % 4 + $umask % 2
`;;
*) mkdir_umask=$umask,go-w;;
esac
# With -d, create the new directory with the user-specified mode.
# Otherwise, rely on $mkdir_umask.
if test -n "$dir_arg"; then
mkdir_mode=-m$mode
else
mkdir_mode=
fi
posix_mkdir=false
case $umask in
*[123567][0-7][0-7])
# POSIX mkdir -p sets u+wx bits regardless of umask, which
# is incompatible with FreeBSD 'install' when (umask & 300) != 0.
;;
*)
tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
if (umask $mkdir_umask &&
exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
then
if test -z "$dir_arg" || {
# Check for POSIX incompatibilities with -m.
# HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
# other-writable bit of parent directory when it shouldn't.
# FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
ls_ld_tmpdir=`ls -ld "$tmpdir"`
case $ls_ld_tmpdir in
d????-?r-*) different_mode=700;;
d????-?--*) different_mode=755;;
*) false;;
esac &&
$mkdirprog -m$different_mode -p -- "$tmpdir" && {
ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
}
}
then posix_mkdir=:
fi
rmdir "$tmpdir/d" "$tmpdir"
else
# Remove any dirs left behind by ancient mkdir implementations.
rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
fi
trap '' 0;;
esac;;
esac
if
$posix_mkdir && (
umask $mkdir_umask &&
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
)
then :
else
# The umask is ridiculous, or mkdir does not conform to POSIX,
# or it failed possibly due to a race condition. Create the
# directory the slow way, step by step, checking for races as we go.
case $dstdir in
/*) prefix='/';;
[-=\(\)!]*) prefix='./';;
*) prefix='';;
esac
eval "$initialize_posix_glob"
oIFS=$IFS
IFS=/
$posix_glob set -f
set fnord $dstdir
shift
$posix_glob set +f
IFS=$oIFS
prefixes=
for d
do
test X"$d" = X && continue
prefix=$prefix$d
if test -d "$prefix"; then
prefixes=
else
if $posix_mkdir; then
(umask=$mkdir_umask &&
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
# Don't fail if two instances are running concurrently.
test -d "$prefix" || exit 1
else
case $prefix in
*\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
*) qprefix=$prefix;;
esac
prefixes="$prefixes '$qprefix'"
fi
fi
prefix=$prefix/
done
if test -n "$prefixes"; then
# Don't fail if two instances are running concurrently.
(umask $mkdir_umask &&
eval "\$doit_exec \$mkdirprog $prefixes") ||
test -d "$dstdir" || exit 1
obsolete_mkdir_used=true
fi
fi
fi
if test -n "$dir_arg"; then
{ test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
{ test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
else
# Make a couple of temp file names in the proper directory.
dsttmp=$dstdir/_inst.$$_
rmtmp=$dstdir/_rm.$$_
# Trap to clean up those temp files at exit.
trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
# Copy the file name to the temp name.
(umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
# and set any options; do chmod last to preserve setuid bits.
#
# If any of these fail, we abort the whole thing. If we want to
# ignore errors from any of these, just make sure not to ignore
# errors from the above "$doit $cpprog $src $dsttmp" command.
#
{ test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
{ test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
{ test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
# If -C, don't bother to copy if it wouldn't change the file.
if $copy_on_change &&
old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` &&
new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
eval "$initialize_posix_glob" &&
$posix_glob set -f &&
set X $old && old=:$2:$4:$5:$6 &&
set X $new && new=:$2:$4:$5:$6 &&
$posix_glob set +f &&
test "$old" = "$new" &&
$cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
then
rm -f "$dsttmp"
else
# Rename the file to the real destination.
$doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
# The rename failed, perhaps because mv can't rename something else
# to itself, or perhaps because mv is so ancient that it does not
# support -f.
{
# Now remove or move aside any old file at destination location.
# We try this two ways since rm can't unlink itself on some
# systems and the destination file might be busy for other
# reasons. In this case, the final cleanup might fail but the new
# file should still install successfully.
{
test ! -f "$dst" ||
$doit $rmcmd -f "$dst" 2>/dev/null ||
{ $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
{ $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
} ||
{ echo "$0: cannot unlink or rename $dst" >&2
(exit 1); exit 1
}
} &&
# Now rename the file to the real destination.
$doit $mvcmd "$dsttmp" "$dst"
}
fi || exit 1
trap '' 0
fi
done
# Local variables:
# 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:

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,135 @@
# ===========================================================================
# http://www.gnu.org/software/autoconf-archive/ax_pkg_swig.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_PKG_SWIG([major.minor.micro], [action-if-found], [action-if-not-found])
#
# DESCRIPTION
#
# This macro searches for a SWIG installation on your system. If found,
# then SWIG is AC_SUBST'd; if not found, then $SWIG is empty. If SWIG is
# found, then SWIG_LIB is set to the SWIG library path, and AC_SUBST'd.
#
# You can use the optional first argument to check if the version of the
# available SWIG is greater than or equal to the value of the argument. It
# should have the format: N[.N[.N]] (N is a number between 0 and 999. Only
# the first N is mandatory.) If the version argument is given (e.g.
# 1.3.17), AX_PKG_SWIG checks that the swig package is this version number
# or higher.
#
# As usual, action-if-found is executed if SWIG is found, otherwise
# action-if-not-found is executed.
#
# In configure.in, use as:
#
# AX_PKG_SWIG(1.3.17, [], [ AC_MSG_ERROR([SWIG is required to build..]) ])
# AX_SWIG_ENABLE_CXX
# AX_SWIG_MULTI_MODULE_SUPPORT
# AX_SWIG_PYTHON
#
# LICENSE
#
# Copyright (c) 2008 Sebastian Huber <sebastian-huber@web.de>
# Copyright (c) 2008 Alan W. Irwin
# Copyright (c) 2008 Rafael Laboissiere <rafael@laboissiere.net>
# Copyright (c) 2008 Andrew Collier
# Copyright (c) 2011 Murray Cumming <murrayc@openismus.com>
#
# 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 of the License, 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 <http://www.gnu.org/licenses/>.
#
# As a special exception, the respective Autoconf Macro's copyright owner
# gives unlimited permission to copy, distribute and modify the configure
# scripts that are the output of Autoconf when processing the Macro. You
# need not follow the terms of the GNU General Public License when using
# or distributing such scripts, even though portions of the text of the
# Macro appear in them. The GNU General Public License (GPL) does govern
# all other use of the material that constitutes the Autoconf Macro.
#
# This special exception to the GPL applies to versions of the Autoconf
# Macro released by the Autoconf Archive. When you make and distribute a
# modified version of the Autoconf Macro, you may extend this special
# exception to the GPL to apply to your modified version as well.
#serial 11
AC_DEFUN([AX_PKG_SWIG],[
# Ubuntu has swig 2.0 as /usr/bin/swig2.0
AC_PATH_PROGS([SWIG],[swig swig2.0])
if test -z "$SWIG" ; then
m4_ifval([$3],[$3],[:])
elif test -n "$1" ; then
AC_MSG_CHECKING([SWIG version])
[swig_version=`$SWIG -version 2>&1 | grep 'SWIG Version' | sed 's/.*\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\).*/\1/g'`]
AC_MSG_RESULT([$swig_version])
if test -n "$swig_version" ; then
# Calculate the required version number components
[required=$1]
[required_major=`echo $required | sed 's/[^0-9].*//'`]
if test -z "$required_major" ; then
[required_major=0]
fi
[required=`echo $required | sed 's/[0-9]*[^0-9]//'`]
[required_minor=`echo $required | sed 's/[^0-9].*//'`]
if test -z "$required_minor" ; then
[required_minor=0]
fi
[required=`echo $required | sed 's/[0-9]*[^0-9]//'`]
[required_patch=`echo $required | sed 's/[^0-9].*//'`]
if test -z "$required_patch" ; then
[required_patch=0]
fi
# Calculate the available version number components
[available=$swig_version]
[available_major=`echo $available | sed 's/[^0-9].*//'`]
if test -z "$available_major" ; then
[available_major=0]
fi
[available=`echo $available | sed 's/[0-9]*[^0-9]//'`]
[available_minor=`echo $available | sed 's/[^0-9].*//'`]
if test -z "$available_minor" ; then
[available_minor=0]
fi
[available=`echo $available | sed 's/[0-9]*[^0-9]//'`]
[available_patch=`echo $available | sed 's/[^0-9].*//'`]
if test -z "$available_patch" ; then
[available_patch=0]
fi
# Convert the version tuple into a single number for easier comparison.
# Using base 100 should be safe since SWIG internally uses BCD values
# to encode its version number.
required_swig_vernum=`expr $required_major \* 10000 \
\+ $required_minor \* 100 \+ $required_patch`
available_swig_vernum=`expr $available_major \* 10000 \
\+ $available_minor \* 100 \+ $available_patch`
if test $available_swig_vernum -lt $required_swig_vernum; then
AC_MSG_WARN([SWIG version >= $1 is required. You have $swig_version.])
SWIG=''
m4_ifval([$3],[$3],[])
else
AC_MSG_CHECKING([for SWIG library])
SWIG_LIB=`$SWIG -swiglib`
AC_MSG_RESULT([$SWIG_LIB])
m4_ifval([$2],[$2],[])
fi
else
AC_MSG_WARN([cannot determine SWIG version])
SWIG=''
m4_ifval([$3],[$3],[])
fi
fi
AC_SUBST([SWIG_LIB])
])

View File

@ -0,0 +1,324 @@
# ===========================================================================
# http://www.gnu.org/software/autoconf-archive/ax_python_devel.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_PYTHON_DEVEL([version])
#
# DESCRIPTION
#
# Note: Defines as a precious variable "PYTHON_VERSION". Don't override it
# in your configure.ac.
#
# This macro checks for Python and tries to get the include path to
# 'Python.h'. It provides the $(PYTHON_CPPFLAGS) and $(PYTHON_LDFLAGS)
# output variables. It also exports $(PYTHON_EXTRA_LIBS) and
# $(PYTHON_EXTRA_LDFLAGS) for embedding Python in your code.
#
# You can search for some particular version of Python by passing a
# parameter to this macro, for example ">= '2.3.1'", or "== '2.4'". Please
# note that you *have* to pass also an operator along with the version to
# match, and pay special attention to the single quotes surrounding the
# version number. Don't use "PYTHON_VERSION" for this: that environment
# variable is declared as precious and thus reserved for the end-user.
#
# This macro should work for all versions of Python >= 2.1.0. As an end
# user, you can disable the check for the python version by setting the
# PYTHON_NOVERSIONCHECK environment variable to something else than the
# empty string.
#
# If you need to use this macro for an older Python version, please
# contact the authors. We're always open for feedback.
#
# LICENSE
#
# Copyright (c) 2009 Sebastian Huber <sebastian-huber@web.de>
# Copyright (c) 2009 Alan W. Irwin
# Copyright (c) 2009 Rafael Laboissiere <rafael@laboissiere.net>
# Copyright (c) 2009 Andrew Collier
# Copyright (c) 2009 Matteo Settenvini <matteo@member.fsf.org>
# Copyright (c) 2009 Horst Knorr <hk_classes@knoda.org>
# Copyright (c) 2013 Daniel Mullner <muellner@math.stanford.edu>
#
# 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 3 of the License, 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 <http://www.gnu.org/licenses/>.
#
# As a special exception, the respective Autoconf Macro's copyright owner
# gives unlimited permission to copy, distribute and modify the configure
# scripts that are the output of Autoconf when processing the Macro. You
# need not follow the terms of the GNU General Public License when using
# or distributing such scripts, even though portions of the text of the
# Macro appear in them. The GNU General Public License (GPL) does govern
# all other use of the material that constitutes the Autoconf Macro.
#
# This special exception to the GPL applies to versions of the Autoconf
# Macro released by the Autoconf Archive. When you make and distribute a
# modified version of the Autoconf Macro, you may extend this special
# exception to the GPL to apply to your modified version as well.
#serial 17
AU_ALIAS([AC_PYTHON_DEVEL], [AX_PYTHON_DEVEL])
AC_DEFUN([AX_PYTHON_DEVEL],[
#
# Allow the use of a (user set) custom python version
#
AC_ARG_VAR([PYTHON_VERSION],[The installed Python
version to use, for example '2.3'. This string
will be appended to the Python interpreter
canonical name.])
AC_PATH_PROG([PYTHON],[python[$PYTHON_VERSION]])
if test -z "$PYTHON"; then
AC_MSG_ERROR([Cannot find python$PYTHON_VERSION in your system path])
PYTHON_VERSION=""
fi
#
# Check for a version of Python >= 2.1.0
#
AC_MSG_CHECKING([for a version of Python >= '2.1.0'])
ac_supports_python_ver=`$PYTHON -c "import sys; \
ver = sys.version.split ()[[0]]; \
print (ver >= '2.1.0')"`
if test "$ac_supports_python_ver" != "True"; then
if test -z "$PYTHON_NOVERSIONCHECK"; then
AC_MSG_RESULT([no])
AC_MSG_FAILURE([
This version of the AC@&t@_PYTHON_DEVEL macro
doesn't work properly with versions of Python before
2.1.0. You may need to re-run configure, setting the
variables PYTHON_CPPFLAGS, PYTHON_LDFLAGS, PYTHON_SITE_PKG,
PYTHON_EXTRA_LIBS and PYTHON_EXTRA_LDFLAGS by hand.
Moreover, to disable this check, set PYTHON_NOVERSIONCHECK
to something else than an empty string.
])
else
AC_MSG_RESULT([skip at user request])
fi
else
AC_MSG_RESULT([yes])
fi
#
# if the macro parameter ``version'' is set, honour it
#
if test -n "$1"; then
AC_MSG_CHECKING([for a version of Python $1])
ac_supports_python_ver=`$PYTHON -c "import sys; \
ver = sys.version.split ()[[0]]; \
print (ver $1)"`
if test "$ac_supports_python_ver" = "True"; then
AC_MSG_RESULT([yes])
else
AC_MSG_RESULT([no])
AC_MSG_ERROR([this package requires Python $1.
If you have it installed, but it isn't the default Python
interpreter in your system path, please pass the PYTHON_VERSION
variable to configure. See ``configure --help'' for reference.
])
PYTHON_VERSION=""
fi
fi
#
# Check if you have distutils, else fail
#
AC_MSG_CHECKING([for the distutils Python package])
ac_distutils_result=`$PYTHON -c "import distutils" 2>&1`
if test -z "$ac_distutils_result"; then
AC_MSG_RESULT([yes])
else
AC_MSG_RESULT([no])
AC_MSG_ERROR([cannot import Python module "distutils".
Please check your Python installation. The error was:
$ac_distutils_result])
PYTHON_VERSION=""
fi
#
# Check for Python include path
#
AC_MSG_CHECKING([for Python include path])
if test -z "$PYTHON_CPPFLAGS"; then
python_path=`$PYTHON -c "import distutils.sysconfig; \
print (distutils.sysconfig.get_python_inc ());"`
plat_python_path=`$PYTHON -c "import distutils.sysconfig; \
print (distutils.sysconfig.get_python_inc (plat_specific=1));"`
if test -n "${python_path}"; then
if test "${plat_python_path}" != "${python_path}"; then
python_path="-I$python_path -I$plat_python_path"
else
python_path="-I$python_path"
fi
fi
PYTHON_CPPFLAGS=$python_path
fi
AC_MSG_RESULT([$PYTHON_CPPFLAGS])
AC_SUBST([PYTHON_CPPFLAGS])
#
# Check for Python library path
#
AC_MSG_CHECKING([for Python library path])
if test -z "$PYTHON_LDFLAGS"; then
# (makes two attempts to ensure we've got a version number
# from the interpreter)
ac_python_version=`cat<<EOD | $PYTHON -
# join all versioning strings, on some systems
# major/minor numbers could be in different list elements
from distutils.sysconfig import *
e = get_config_var('VERSION')
if e is not None:
print(e)
EOD`
if test -z "$ac_python_version"; then
if test -n "$PYTHON_VERSION"; then
ac_python_version=$PYTHON_VERSION
else
ac_python_version=`$PYTHON -c "import sys; \
print (sys.version[[:3]])"`
fi
fi
# Make the versioning information available to the compiler
AC_DEFINE_UNQUOTED([HAVE_PYTHON], ["$ac_python_version"],
[If available, contains the Python version number currently in use.])
# First, the library directory:
ac_python_libdir=`cat<<EOD | $PYTHON -
# There should be only one
import distutils.sysconfig
e = distutils.sysconfig.get_config_var('LIBDIR')
if e is not None:
print (e)
EOD`
# Now, for the library:
ac_python_library=`cat<<EOD | $PYTHON -
import distutils.sysconfig
c = distutils.sysconfig.get_config_vars()
if 'LDVERSION' in c:
print ('python'+c[['LDVERSION']])
else:
print ('python'+c[['VERSION']])
EOD`
# This small piece shamelessly adapted from PostgreSQL python macro;
# credits goes to momjian, I think. I'd like to put the right name
# in the credits, if someone can point me in the right direction... ?
#
if test -n "$ac_python_libdir" -a -n "$ac_python_library"
then
# use the official shared library
ac_python_library=`echo "$ac_python_library" | sed "s/^lib//"`
PYTHON_LDFLAGS="-L$ac_python_libdir -l$ac_python_library"
else
# old way: use libpython from python_configdir
ac_python_libdir=`$PYTHON -c \
"from distutils.sysconfig import get_python_lib as f; \
import os; \
print (os.path.join(f(plat_specific=1, standard_lib=1), 'config'));"`
PYTHON_LDFLAGS="-L$ac_python_libdir -lpython$ac_python_version"
fi
if test -z "PYTHON_LDFLAGS"; then
AC_MSG_ERROR([
Cannot determine location of your Python DSO. Please check it was installed with
dynamic libraries enabled, or try setting PYTHON_LDFLAGS by hand.
])
fi
fi
AC_MSG_RESULT([$PYTHON_LDFLAGS])
AC_SUBST([PYTHON_LDFLAGS])
#
# Check for site packages
#
AC_MSG_CHECKING([for Python site-packages path])
if test -z "$PYTHON_SITE_PKG"; then
PYTHON_SITE_PKG=`$PYTHON -c "import distutils.sysconfig; \
print (distutils.sysconfig.get_python_lib(0,0));"`
fi
AC_MSG_RESULT([$PYTHON_SITE_PKG])
AC_SUBST([PYTHON_SITE_PKG])
#
# libraries which must be linked in when embedding
#
AC_MSG_CHECKING(python extra libraries)
if test -z "$PYTHON_EXTRA_LIBS"; then
PYTHON_EXTRA_LIBS=`$PYTHON -c "import distutils.sysconfig; \
conf = distutils.sysconfig.get_config_var; \
print (conf('LIBS') + ' ' + conf('SYSLIBS'))"`
fi
AC_MSG_RESULT([$PYTHON_EXTRA_LIBS])
AC_SUBST(PYTHON_EXTRA_LIBS)
#
# linking flags needed when embedding
#
AC_MSG_CHECKING(python extra linking flags)
if test -z "$PYTHON_EXTRA_LDFLAGS"; then
PYTHON_EXTRA_LDFLAGS=`$PYTHON -c "import distutils.sysconfig; \
conf = distutils.sysconfig.get_config_var; \
print (conf('LINKFORSHARED'))"`
fi
AC_MSG_RESULT([$PYTHON_EXTRA_LDFLAGS])
AC_SUBST(PYTHON_EXTRA_LDFLAGS)
#
# final check to see if everything compiles alright
#
AC_MSG_CHECKING([consistency of all components of python development environment])
# save current global flags
ac_save_LIBS="$LIBS"
ac_save_CPPFLAGS="$CPPFLAGS"
LIBS="$ac_save_LIBS $PYTHON_LDFLAGS $PYTHON_EXTRA_LDFLAGS $PYTHON_EXTRA_LIBS"
CPPFLAGS="$ac_save_CPPFLAGS $PYTHON_CPPFLAGS"
AC_LANG_PUSH([C])
AC_LINK_IFELSE([
AC_LANG_PROGRAM([[#include <Python.h>]],
[[Py_Initialize();]])
],[pythonexists=yes],[pythonexists=no])
AC_LANG_POP([C])
# turn back to default flags
CPPFLAGS="$ac_save_CPPFLAGS"
LIBS="$ac_save_LIBS"
AC_MSG_RESULT([$pythonexists])
if test ! "x$pythonexists" = "xyes"; then
AC_MSG_FAILURE([
Could not link test program to Python. Maybe the main Python library has been
installed in some non-standard library path. If so, pass it to configure,
via the LDFLAGS environment variable.
Example: ./configure LDFLAGS="-L/usr/non-standard-path/python/lib"
============================================================================
ERROR!
You probably have to install the development version of the Python package
for your distribution. The exact name of this package varies among them.
============================================================================
])
PYTHON_VERSION=""
fi
#
# all done!
#
])

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,384 @@
# Helper functions for option handling. -*- Autoconf -*-
#
# Copyright (C) 2004, 2005, 2007, 2008, 2009 Free Software Foundation,
# Inc.
# Written by Gary V. Vaughan, 2004
#
# This file 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.
# serial 7 ltoptions.m4
# This is to help aclocal find these macros, as it can't see m4_define.
AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])])
# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME)
# ------------------------------------------
m4_define([_LT_MANGLE_OPTION],
[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])])
# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME)
# ---------------------------------------
# Set option OPTION-NAME for macro MACRO-NAME, and if there is a
# matching handler defined, dispatch to it. Other OPTION-NAMEs are
# saved as a flag.
m4_define([_LT_SET_OPTION],
[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl
m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]),
_LT_MANGLE_DEFUN([$1], [$2]),
[m4_warning([Unknown $1 option `$2'])])[]dnl
])
# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET])
# ------------------------------------------------------------
# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
m4_define([_LT_IF_OPTION],
[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])])
# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET)
# -------------------------------------------------------
# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME
# are set.
m4_define([_LT_UNLESS_OPTIONS],
[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
[m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option),
[m4_define([$0_found])])])[]dnl
m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3
])[]dnl
])
# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST)
# ----------------------------------------
# OPTION-LIST is a space-separated list of Libtool options associated
# with MACRO-NAME. If any OPTION has a matching handler declared with
# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about
# the unknown option and exit.
m4_defun([_LT_SET_OPTIONS],
[# Set options
m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
[_LT_SET_OPTION([$1], _LT_Option)])
m4_if([$1],[LT_INIT],[
dnl
dnl Simply set some default values (i.e off) if boolean options were not
dnl specified:
_LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no
])
_LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no
])
dnl
dnl If no reference was made to various pairs of opposing options, then
dnl we run the default mode handler for the pair. For example, if neither
dnl `shared' nor `disable-shared' was passed, we enable building of shared
dnl archives by default:
_LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED])
_LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC])
_LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC])
_LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install],
[_LT_ENABLE_FAST_INSTALL])
])
])# _LT_SET_OPTIONS
## --------------------------------- ##
## Macros to handle LT_INIT options. ##
## --------------------------------- ##
# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME)
# -----------------------------------------
m4_define([_LT_MANGLE_DEFUN],
[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])])
# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE)
# -----------------------------------------------
m4_define([LT_OPTION_DEFINE],
[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl
])# LT_OPTION_DEFINE
# dlopen
# ------
LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes
])
AU_DEFUN([AC_LIBTOOL_DLOPEN],
[_LT_SET_OPTION([LT_INIT], [dlopen])
AC_DIAGNOSE([obsolete],
[$0: Remove this warning and the call to _LT_SET_OPTION when you
put the `dlopen' option into LT_INIT's first parameter.])
])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], [])
# win32-dll
# ---------
# Declare package support for building win32 dll's.
LT_OPTION_DEFINE([LT_INIT], [win32-dll],
[enable_win32_dll=yes
case $host in
*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*)
AC_CHECK_TOOL(AS, as, false)
AC_CHECK_TOOL(DLLTOOL, dlltool, false)
AC_CHECK_TOOL(OBJDUMP, objdump, false)
;;
esac
test -z "$AS" && AS=as
_LT_DECL([], [AS], [1], [Assembler program])dnl
test -z "$DLLTOOL" && DLLTOOL=dlltool
_LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl
test -z "$OBJDUMP" && OBJDUMP=objdump
_LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl
])# win32-dll
AU_DEFUN([AC_LIBTOOL_WIN32_DLL],
[AC_REQUIRE([AC_CANONICAL_HOST])dnl
_LT_SET_OPTION([LT_INIT], [win32-dll])
AC_DIAGNOSE([obsolete],
[$0: Remove this warning and the call to _LT_SET_OPTION when you
put the `win32-dll' option into LT_INIT's first parameter.])
])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], [])
# _LT_ENABLE_SHARED([DEFAULT])
# ----------------------------
# implement the --enable-shared flag, and supports the `shared' and
# `disable-shared' LT_INIT options.
# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'.
m4_define([_LT_ENABLE_SHARED],
[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl
AC_ARG_ENABLE([shared],
[AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@],
[build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])],
[p=${PACKAGE-default}
case $enableval in
yes) enable_shared=yes ;;
no) enable_shared=no ;;
*)
enable_shared=no
# Look at the argument we got. We use all the common list separators.
lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
for pkg in $enableval; do
IFS="$lt_save_ifs"
if test "X$pkg" = "X$p"; then
enable_shared=yes
fi
done
IFS="$lt_save_ifs"
;;
esac],
[enable_shared=]_LT_ENABLE_SHARED_DEFAULT)
_LT_DECL([build_libtool_libs], [enable_shared], [0],
[Whether or not to build shared libraries])
])# _LT_ENABLE_SHARED
LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])])
LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])])
# Old names:
AC_DEFUN([AC_ENABLE_SHARED],
[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared])
])
AC_DEFUN([AC_DISABLE_SHARED],
[_LT_SET_OPTION([LT_INIT], [disable-shared])
])
AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)])
AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AM_ENABLE_SHARED], [])
dnl AC_DEFUN([AM_DISABLE_SHARED], [])
# _LT_ENABLE_STATIC([DEFAULT])
# ----------------------------
# implement the --enable-static flag, and support the `static' and
# `disable-static' LT_INIT options.
# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'.
m4_define([_LT_ENABLE_STATIC],
[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl
AC_ARG_ENABLE([static],
[AS_HELP_STRING([--enable-static@<:@=PKGS@:>@],
[build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])],
[p=${PACKAGE-default}
case $enableval in
yes) enable_static=yes ;;
no) enable_static=no ;;
*)
enable_static=no
# Look at the argument we got. We use all the common list separators.
lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
for pkg in $enableval; do
IFS="$lt_save_ifs"
if test "X$pkg" = "X$p"; then
enable_static=yes
fi
done
IFS="$lt_save_ifs"
;;
esac],
[enable_static=]_LT_ENABLE_STATIC_DEFAULT)
_LT_DECL([build_old_libs], [enable_static], [0],
[Whether or not to build static libraries])
])# _LT_ENABLE_STATIC
LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])])
LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])])
# Old names:
AC_DEFUN([AC_ENABLE_STATIC],
[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static])
])
AC_DEFUN([AC_DISABLE_STATIC],
[_LT_SET_OPTION([LT_INIT], [disable-static])
])
AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)])
AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AM_ENABLE_STATIC], [])
dnl AC_DEFUN([AM_DISABLE_STATIC], [])
# _LT_ENABLE_FAST_INSTALL([DEFAULT])
# ----------------------------------
# implement the --enable-fast-install flag, and support the `fast-install'
# and `disable-fast-install' LT_INIT options.
# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'.
m4_define([_LT_ENABLE_FAST_INSTALL],
[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl
AC_ARG_ENABLE([fast-install],
[AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@],
[optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])],
[p=${PACKAGE-default}
case $enableval in
yes) enable_fast_install=yes ;;
no) enable_fast_install=no ;;
*)
enable_fast_install=no
# Look at the argument we got. We use all the common list separators.
lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
for pkg in $enableval; do
IFS="$lt_save_ifs"
if test "X$pkg" = "X$p"; then
enable_fast_install=yes
fi
done
IFS="$lt_save_ifs"
;;
esac],
[enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT)
_LT_DECL([fast_install], [enable_fast_install], [0],
[Whether or not to optimize for fast installation])dnl
])# _LT_ENABLE_FAST_INSTALL
LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])])
LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])])
# Old names:
AU_DEFUN([AC_ENABLE_FAST_INSTALL],
[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install])
AC_DIAGNOSE([obsolete],
[$0: Remove this warning and the call to _LT_SET_OPTION when you put
the `fast-install' option into LT_INIT's first parameter.])
])
AU_DEFUN([AC_DISABLE_FAST_INSTALL],
[_LT_SET_OPTION([LT_INIT], [disable-fast-install])
AC_DIAGNOSE([obsolete],
[$0: Remove this warning and the call to _LT_SET_OPTION when you put
the `disable-fast-install' option into LT_INIT's first parameter.])
])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], [])
dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], [])
# _LT_WITH_PIC([MODE])
# --------------------
# implement the --with-pic flag, and support the `pic-only' and `no-pic'
# LT_INIT options.
# MODE is either `yes' or `no'. If omitted, it defaults to `both'.
m4_define([_LT_WITH_PIC],
[AC_ARG_WITH([pic],
[AS_HELP_STRING([--with-pic@<:@=PKGS@:>@],
[try to use only PIC/non-PIC objects @<:@default=use both@:>@])],
[lt_p=${PACKAGE-default}
case $withval in
yes|no) pic_mode=$withval ;;
*)
pic_mode=default
# Look at the argument we got. We use all the common list separators.
lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
for lt_pkg in $withval; do
IFS="$lt_save_ifs"
if test "X$lt_pkg" = "X$lt_p"; then
pic_mode=yes
fi
done
IFS="$lt_save_ifs"
;;
esac],
[pic_mode=default])
test -z "$pic_mode" && pic_mode=m4_default([$1], [default])
_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl
])# _LT_WITH_PIC
LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])])
LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])])
# Old name:
AU_DEFUN([AC_LIBTOOL_PICMODE],
[_LT_SET_OPTION([LT_INIT], [pic-only])
AC_DIAGNOSE([obsolete],
[$0: Remove this warning and the call to _LT_SET_OPTION when you
put the `pic-only' option into LT_INIT's first parameter.])
])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AC_LIBTOOL_PICMODE], [])
## ----------------- ##
## LTDL_INIT Options ##
## ----------------- ##
m4_define([_LTDL_MODE], [])
LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive],
[m4_define([_LTDL_MODE], [nonrecursive])])
LT_OPTION_DEFINE([LTDL_INIT], [recursive],
[m4_define([_LTDL_MODE], [recursive])])
LT_OPTION_DEFINE([LTDL_INIT], [subproject],
[m4_define([_LTDL_MODE], [subproject])])
m4_define([_LTDL_TYPE], [])
LT_OPTION_DEFINE([LTDL_INIT], [installable],
[m4_define([_LTDL_TYPE], [installable])])
LT_OPTION_DEFINE([LTDL_INIT], [convenience],
[m4_define([_LTDL_TYPE], [convenience])])

View File

@ -0,0 +1,123 @@
# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*-
#
# Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
# Written by Gary V. Vaughan, 2004
#
# This file 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.
# serial 6 ltsugar.m4
# This is to help aclocal find these macros, as it can't see m4_define.
AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])])
# lt_join(SEP, ARG1, [ARG2...])
# -----------------------------
# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their
# associated separator.
# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier
# versions in m4sugar had bugs.
m4_define([lt_join],
[m4_if([$#], [1], [],
[$#], [2], [[$2]],
[m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])])
m4_define([_lt_join],
[m4_if([$#$2], [2], [],
[m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])])
# lt_car(LIST)
# lt_cdr(LIST)
# ------------
# Manipulate m4 lists.
# These macros are necessary as long as will still need to support
# Autoconf-2.59 which quotes differently.
m4_define([lt_car], [[$1]])
m4_define([lt_cdr],
[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])],
[$#], 1, [],
[m4_dquote(m4_shift($@))])])
m4_define([lt_unquote], $1)
# lt_append(MACRO-NAME, STRING, [SEPARATOR])
# ------------------------------------------
# Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'.
# Note that neither SEPARATOR nor STRING are expanded; they are appended
# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked).
# No SEPARATOR is output if MACRO-NAME was previously undefined (different
# than defined and empty).
#
# This macro is needed until we can rely on Autoconf 2.62, since earlier
# versions of m4sugar mistakenly expanded SEPARATOR but not STRING.
m4_define([lt_append],
[m4_define([$1],
m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])])
# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...])
# ----------------------------------------------------------
# Produce a SEP delimited list of all paired combinations of elements of
# PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list
# has the form PREFIXmINFIXSUFFIXn.
# Needed until we can rely on m4_combine added in Autoconf 2.62.
m4_define([lt_combine],
[m4_if(m4_eval([$# > 3]), [1],
[m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl
[[m4_foreach([_Lt_prefix], [$2],
[m4_foreach([_Lt_suffix],
]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[,
[_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])])
# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ])
# -----------------------------------------------------------------------
# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited
# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ.
m4_define([lt_if_append_uniq],
[m4_ifdef([$1],
[m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1],
[lt_append([$1], [$2], [$3])$4],
[$5])],
[lt_append([$1], [$2], [$3])$4])])
# lt_dict_add(DICT, KEY, VALUE)
# -----------------------------
m4_define([lt_dict_add],
[m4_define([$1($2)], [$3])])
# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE)
# --------------------------------------------
m4_define([lt_dict_add_subkey],
[m4_define([$1($2:$3)], [$4])])
# lt_dict_fetch(DICT, KEY, [SUBKEY])
# ----------------------------------
m4_define([lt_dict_fetch],
[m4_ifval([$3],
m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]),
m4_ifdef([$1($2)], [m4_defn([$1($2)])]))])
# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE])
# -----------------------------------------------------------------
m4_define([lt_if_dict_fetch],
[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4],
[$5],
[$6])])
# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...])
# --------------------------------------------------------------
m4_define([lt_dict_filter],
[m4_if([$5], [], [],
[lt_join(m4_quote(m4_default([$4], [[, ]])),
lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]),
[lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl
])

View File

@ -0,0 +1,23 @@
# ltversion.m4 -- version numbers -*- Autoconf -*-
#
# Copyright (C) 2004 Free Software Foundation, Inc.
# Written by Scott James Remnant, 2004
#
# This file 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.
# @configure_input@
# serial 3337 ltversion.m4
# This file is part of GNU Libtool
m4_define([LT_PACKAGE_VERSION], [2.4.2])
m4_define([LT_PACKAGE_REVISION], [1.3337])
AC_DEFUN([LTVERSION_VERSION],
[macro_version='2.4.2'
macro_revision='1.3337'
_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?])
_LT_DECL(, macro_revision, 0)
])

View File

@ -0,0 +1,98 @@
# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*-
#
# Copyright (C) 2004, 2005, 2007, 2009 Free Software Foundation, Inc.
# Written by Scott James Remnant, 2004.
#
# This file 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.
# serial 5 lt~obsolete.m4
# These exist entirely to fool aclocal when bootstrapping libtool.
#
# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN)
# which have later been changed to m4_define as they aren't part of the
# exported API, or moved to Autoconf or Automake where they belong.
#
# The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN
# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us
# using a macro with the same name in our local m4/libtool.m4 it'll
# pull the old libtool.m4 in (it doesn't see our shiny new m4_define
# and doesn't know about Autoconf macros at all.)
#
# So we provide this file, which has a silly filename so it's always
# included after everything else. This provides aclocal with the
# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything
# because those macros already exist, or will be overwritten later.
# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6.
#
# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here.
# Yes, that means every name once taken will need to remain here until
# we give up compatibility with versions before 1.7, at which point
# we need to keep only those names which we still refer to.
# This is to help aclocal find these macros, as it can't see m4_define.
AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])])
m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])])
m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])])
m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])])
m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])])
m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])])
m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])])
m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])])
m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])])
m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])])
m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])])
m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])])
m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])])
m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])])
m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])])
m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])])
m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])])
m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])])
m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])])
m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])])
m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])])
m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])])
m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])])
m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])])
m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])])
m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])])
m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])])
m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])])
m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])])
m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])])
m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])])
m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])])
m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])])
m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])])
m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])])
m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])])
m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])])
m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])])
m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])])
m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])])
m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])])
m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])])
m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])])
m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])])
m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])])
m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])])
m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])])
m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])])
m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])])
m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])])
m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])])
m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])])
m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])])
m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])])
m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])])
m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])])
m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])])
m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])])
m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])])
m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])])
m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])])
m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])])

View File

@ -0,0 +1,157 @@
# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*-
#
# Copyright © 2004 Scott James Remnant <scott@netsplit.com>.
#
# 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 of the License, 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, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
# 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.
# PKG_PROG_PKG_CONFIG([MIN-VERSION])
# ----------------------------------
AC_DEFUN([PKG_PROG_PKG_CONFIG],
[m4_pattern_forbid([^_?PKG_[A-Z_]+$])
m4_pattern_allow([^PKG_CONFIG(_PATH)?$])
AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility])dnl
if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
AC_PATH_TOOL([PKG_CONFIG], [pkg-config])
fi
if test -n "$PKG_CONFIG"; then
_pkg_min_version=m4_default([$1], [0.9.0])
AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version])
if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then
AC_MSG_RESULT([yes])
else
AC_MSG_RESULT([no])
PKG_CONFIG=""
fi
fi[]dnl
])# PKG_PROG_PKG_CONFIG
# PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
#
# Check to see whether a particular set of modules exists. Similar
# to PKG_CHECK_MODULES(), but does not set variables or print errors.
#
#
# Similar to PKG_CHECK_MODULES, make sure that the first instance of
# this or PKG_CHECK_MODULES is called, or make sure to call
# PKG_CHECK_EXISTS manually
# --------------------------------------------------------------
AC_DEFUN([PKG_CHECK_EXISTS],
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
if test -n "$PKG_CONFIG" && \
AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then
m4_ifval([$2], [$2], [:])
m4_ifvaln([$3], [else
$3])dnl
fi])
# _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES])
# ---------------------------------------------
m4_define([_PKG_CONFIG],
[if test -n "$PKG_CONFIG"; then
if test -n "$$1"; then
pkg_cv_[]$1="$$1"
else
PKG_CHECK_EXISTS([$3],
[pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`],
[pkg_failed=yes])
fi
else
pkg_failed=untried
fi[]dnl
])# _PKG_CONFIG
# _PKG_SHORT_ERRORS_SUPPORTED
# -----------------------------
AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED],
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])
if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
_pkg_short_errors_supported=yes
else
_pkg_short_errors_supported=no
fi[]dnl
])# _PKG_SHORT_ERRORS_SUPPORTED
# PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND],
# [ACTION-IF-NOT-FOUND])
#
#
# Note that if there is a possibility the first call to
# PKG_CHECK_MODULES might not happen, you should be sure to include an
# explicit call to PKG_PROG_PKG_CONFIG in your configure.ac
#
#
# --------------------------------------------------------------
AC_DEFUN([PKG_CHECK_MODULES],
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl
AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl
pkg_failed=no
AC_MSG_CHECKING([for $1])
_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2])
_PKG_CONFIG([$1][_LIBS], [libs], [$2])
m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS
and $1[]_LIBS to avoid the need to call pkg-config.
See the pkg-config man page for more details.])
if test $pkg_failed = yes; then
_PKG_SHORT_ERRORS_SUPPORTED
if test $_pkg_short_errors_supported = yes; then
$1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "$2"`
else
$1[]_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "$2"`
fi
# Put the nasty error message in config.log where it belongs
echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD
ifelse([$4], , [AC_MSG_ERROR(dnl
[Package requirements ($2) were not met:
$$1_PKG_ERRORS
Consider adjusting the PKG_CONFIG_PATH environment variable if you
installed software in a non-standard prefix.
_PKG_TEXT
])],
[AC_MSG_RESULT([no])
$4])
elif test $pkg_failed = untried; then
ifelse([$4], , [AC_MSG_FAILURE(dnl
[The pkg-config script could not be found or is too old. Make sure it
is in your PATH or set the PKG_CONFIG environment variable to the full
path to pkg-config.
_PKG_TEXT
To get pkg-config, see <http://pkg-config.freedesktop.org/>.])],
[$4])
else
$1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS
$1[]_LIBS=$pkg_cv_[]$1[]_LIBS
AC_MSG_RESULT([yes])
ifelse([$3], , :, [$3])
fi[]dnl
])# PKG_CHECK_MODULES

View File

@ -0,0 +1,215 @@
#! /bin/sh
# Common wrapper for a few potentially missing GNU programs.
scriptversion=2012-06-26.16; # UTC
# Copyright (C) 1996-2013 Free Software Foundation, Inc.
# Originally written by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
# 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 <http://www.gnu.org/licenses/>.
# 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.
if test $# -eq 0; then
echo 1>&2 "Try '$0 --help' for more information"
exit 1
fi
case $1 in
--is-lightweight)
# Used by our autoconf macros to check whether the available missing
# script is modern enough.
exit 0
;;
--run)
# Back-compat with the calling convention used by older automake.
shift
;;
-h|--h|--he|--hel|--help)
echo "\
$0 [OPTION]... PROGRAM [ARGUMENT]...
Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due
to PROGRAM being missing or too old.
Options:
-h, --help display this help and exit
-v, --version output version information and exit
Supported PROGRAM values:
aclocal autoconf autoheader autom4te automake makeinfo
bison yacc flex lex help2man
Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and
'g' are ignored when checking the name.
Send bug reports to <bug-automake@gnu.org>."
exit $?
;;
-v|--v|--ve|--ver|--vers|--versi|--versio|--version)
echo "missing $scriptversion (GNU Automake)"
exit $?
;;
-*)
echo 1>&2 "$0: unknown '$1' option"
echo 1>&2 "Try '$0 --help' for more information"
exit 1
;;
esac
# Run the given program, remember its exit status.
"$@"; st=$?
# If it succeeded, we are done.
test $st -eq 0 && exit 0
# Also exit now if we it failed (or wasn't found), and '--version' was
# passed; such an option is passed most likely to detect whether the
# program is present and works.
case $2 in --version|--help) exit $st;; esac
# Exit code 63 means version mismatch. This often happens when the user
# tries to use an ancient version of a tool on a file that requires a
# minimum version.
if test $st -eq 63; then
msg="probably too old"
elif test $st -eq 127; then
# Program was missing.
msg="missing on your system"
else
# Program was found and executed, but failed. Give up.
exit $st
fi
perl_URL=http://www.perl.org/
flex_URL=http://flex.sourceforge.net/
gnu_software_URL=http://www.gnu.org/software
program_details ()
{
case $1 in
aclocal|automake)
echo "The '$1' program is part of the GNU Automake package:"
echo "<$gnu_software_URL/automake>"
echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:"
echo "<$gnu_software_URL/autoconf>"
echo "<$gnu_software_URL/m4/>"
echo "<$perl_URL>"
;;
autoconf|autom4te|autoheader)
echo "The '$1' program is part of the GNU Autoconf package:"
echo "<$gnu_software_URL/autoconf/>"
echo "It also requires GNU m4 and Perl in order to run:"
echo "<$gnu_software_URL/m4/>"
echo "<$perl_URL>"
;;
esac
}
give_advice ()
{
# Normalize program name to check for.
normalized_program=`echo "$1" | sed '
s/^gnu-//; t
s/^gnu//; t
s/^g//; t'`
printf '%s\n' "'$1' is $msg."
configure_deps="'configure.ac' or m4 files included by 'configure.ac'"
case $normalized_program in
autoconf*)
echo "You should only need it if you modified 'configure.ac',"
echo "or m4 files included by it."
program_details 'autoconf'
;;
autoheader*)
echo "You should only need it if you modified 'acconfig.h' or"
echo "$configure_deps."
program_details 'autoheader'
;;
automake*)
echo "You should only need it if you modified 'Makefile.am' or"
echo "$configure_deps."
program_details 'automake'
;;
aclocal*)
echo "You should only need it if you modified 'acinclude.m4' or"
echo "$configure_deps."
program_details 'aclocal'
;;
autom4te*)
echo "You might have modified some maintainer files that require"
echo "the 'automa4te' program to be rebuilt."
program_details 'autom4te'
;;
bison*|yacc*)
echo "You should only need it if you modified a '.y' file."
echo "You may want to install the GNU Bison package:"
echo "<$gnu_software_URL/bison/>"
;;
lex*|flex*)
echo "You should only need it if you modified a '.l' file."
echo "You may want to install the Fast Lexical Analyzer package:"
echo "<$flex_URL>"
;;
help2man*)
echo "You should only need it if you modified a dependency" \
"of a man page."
echo "You may want to install the GNU Help2man package:"
echo "<$gnu_software_URL/help2man/>"
;;
makeinfo*)
echo "You should only need it if you modified a '.texi' file, or"
echo "any other file indirectly affecting the aspect of the manual."
echo "You might want to install the Texinfo package:"
echo "<$gnu_software_URL/texinfo/>"
echo "The spurious makeinfo call might also be the consequence of"
echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might"
echo "want to install GNU make:"
echo "<$gnu_software_URL/make/>"
;;
*)
echo "You might have modified some files without having the proper"
echo "tools for further handling them. Check the 'README' file, it"
echo "often tells you about the needed prerequisites for installing"
echo "this package. You may also peek at any GNU archive site, in"
echo "case some other package contains this missing '$1' program."
;;
esac
}
give_advice "$1" | sed -e '1s/^/WARNING: /' \
-e '2,$s/^/ /' >&2
# Propagate the correct exit status (expected to be 127 for a program
# not found, 63 for a program that failed due to version mismatch).
exit $st
# Local variables:
# 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:

View File

@ -0,0 +1,16 @@
enusdir = $(datadir)/@PACKAGE@/model/en-us/en-us
dist_enus_DATA = \
en-us/en-us/feat.params \
en-us/en-us/variances \
en-us/en-us/transition_matrices \
en-us/en-us/README \
en-us/en-us/noisedict \
en-us/en-us/sendump \
en-us/en-us/mdef \
en-us/en-us/means
enuslmdir = $(datadir)/@PACKAGE@/model/en-us
dist_enuslm_DATA = \
en-us/cmudict-en-us.dict \
en-us/en-us-phone.lm.bin \
en-us/en-us.lm.bin

View File

@ -0,0 +1,546 @@
# Makefile.in generated by automake 1.13.4 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2013 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.
@SET_MAKE@
VPATH = @srcdir@
am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
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)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
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 = @build@
host_triplet = @host@
subdir = model
DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
$(dist_enus_DATA) $(dist_enuslm_DATA)
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_pkg_swig.m4 \
$(top_srcdir)/m4/ax_python_devel.m4 \
$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
$(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/pkg.m4 \
$(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false
am__v_P_1 = :
AM_V_GEN = $(am__v_GEN_@AM_V@)
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
am__v_GEN_0 = @echo " GEN " $@;
am__v_GEN_1 =
AM_V_at = $(am__v_at_@AM_V@)
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
am__v_at_0 = @
am__v_at_1 =
SOURCES =
DIST_SOURCES =
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
*) (install-info --version) >/dev/null 2>&1;; \
esac
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)$(enusdir)" "$(DESTDIR)$(enuslmdir)"
DATA = $(dist_enus_DATA) $(dist_enuslm_DATA)
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GREP = @GREP@
GST_CFLAGS = @GST_CFLAGS@
GST_LIBS = @GST_LIBS@
GST_MAJORMINOR = @GST_MAJORMINOR@
GST_PLUGIN_LDFLAGS = @GST_PLUGIN_LDFLAGS@
GStreamer_CFLAGS = @GStreamer_CFLAGS@
GStreamer_LIBS = @GStreamer_LIBS@
HAVE_DOXYGEN = @HAVE_DOXYGEN@
HAVE_PKGCONFIG = @HAVE_PKGCONFIG@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LD = @LD@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PKG_CONFIG = @PKG_CONFIG@
PYTHON = @PYTHON@
PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@
PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@
PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@
PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
PYTHON_PLATFORM = @PYTHON_PLATFORM@
PYTHON_PREFIX = @PYTHON_PREFIX@
PYTHON_SITE_PKG = @PYTHON_SITE_PKG@
PYTHON_VERSION = @PYTHON_VERSION@
RANLIB = @RANLIB@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
SPHINXBASE_CFLAGS = @SPHINXBASE_CFLAGS@
SPHINXBASE_LIBS = @SPHINXBASE_LIBS@
SPHINXBASE_SWIG = @SPHINXBASE_SWIG@
STRIP = @STRIP@
SWIG = @SWIG@
SWIG_LIB = @SWIG_LIB@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
pkgpyexecdir = @pkgpyexecdir@
pkgpythondir = @pkgpythondir@
plugindir = @plugindir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
pyexecdir = @pyexecdir@
pythondir = @pythondir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
enusdir = $(datadir)/@PACKAGE@/model/en-us/en-us
dist_enus_DATA = \
en-us/en-us/feat.params \
en-us/en-us/variances \
en-us/en-us/transition_matrices \
en-us/en-us/README \
en-us/en-us/noisedict \
en-us/en-us/sendump \
en-us/en-us/mdef \
en-us/en-us/means
enuslmdir = $(datadir)/@PACKAGE@/model/en-us
dist_enuslm_DATA = \
en-us/cmudict-en-us.dict \
en-us/en-us-phone.lm.bin \
en-us/en-us.lm.bin
all: all-am
.SUFFIXES:
$(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) --foreign model/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign model/Makefile
.PRECIOUS: 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):
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
install-dist_enusDATA: $(dist_enus_DATA)
@$(NORMAL_INSTALL)
@list='$(dist_enus_DATA)'; test -n "$(enusdir)" || list=; \
if test -n "$$list"; then \
echo " $(MKDIR_P) '$(DESTDIR)$(enusdir)'"; \
$(MKDIR_P) "$(DESTDIR)$(enusdir)" || exit 1; \
fi; \
for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
echo "$$d$$p"; \
done | $(am__base_list) | \
while read files; do \
echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(enusdir)'"; \
$(INSTALL_DATA) $$files "$(DESTDIR)$(enusdir)" || exit $$?; \
done
uninstall-dist_enusDATA:
@$(NORMAL_UNINSTALL)
@list='$(dist_enus_DATA)'; test -n "$(enusdir)" || list=; \
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
dir='$(DESTDIR)$(enusdir)'; $(am__uninstall_files_from_dir)
install-dist_enuslmDATA: $(dist_enuslm_DATA)
@$(NORMAL_INSTALL)
@list='$(dist_enuslm_DATA)'; test -n "$(enuslmdir)" || list=; \
if test -n "$$list"; then \
echo " $(MKDIR_P) '$(DESTDIR)$(enuslmdir)'"; \
$(MKDIR_P) "$(DESTDIR)$(enuslmdir)" || exit 1; \
fi; \
for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
echo "$$d$$p"; \
done | $(am__base_list) | \
while read files; do \
echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(enuslmdir)'"; \
$(INSTALL_DATA) $$files "$(DESTDIR)$(enuslmdir)" || exit $$?; \
done
uninstall-dist_enuslmDATA:
@$(NORMAL_UNINSTALL)
@list='$(dist_enuslm_DATA)'; test -n "$(enuslmdir)" || list=; \
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
dir='$(DESTDIR)$(enuslmdir)'; $(am__uninstall_files_from_dir)
tags TAGS:
ctags CTAGS:
cscope cscopelist:
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 $(DATA)
installdirs:
for dir in "$(DESTDIR)$(enusdir)" "$(DESTDIR)$(enuslmdir)"; 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 mostlyclean-am
distclean: distclean-am
-rm -f Makefile
distclean-am: clean-am distclean-generic
dvi: dvi-am
dvi-am:
html: html-am
html-am:
info: info-am
info-am:
install-data-am: install-dist_enusDATA install-dist_enuslmDATA
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 -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-generic mostlyclean-libtool
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-dist_enusDATA uninstall-dist_enuslmDATA
.MAKE: install-am install-strip
.PHONY: all all-am check check-am clean clean-generic clean-libtool \
cscopelist-am ctags-am distclean distclean-generic \
distclean-libtool distdir dvi dvi-am html html-am info info-am \
install install-am install-data install-data-am \
install-dist_enusDATA install-dist_enuslmDATA 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 \
maintainer-clean maintainer-clean-generic mostlyclean \
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
tags-am uninstall uninstall-am uninstall-dist_enusDATA \
uninstall-dist_enuslmDATA
# 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:

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,34 @@
/* ====================================================================
* Copyright (c) 2015 Alpha Cephei Inc. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. 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 ALPHA CEPHEI INC. ``AS IS'' AND.
* ANY EXPRESSED 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 ALPHA CEPHEI INC.
* NOR ITS EMPLOYEES 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.
*
* ====================================================================
*
*/
This directory contains generic US english acoustic model trained with
latest sphinxtrain.

View File

@ -0,0 +1,12 @@
-lowerf 130
-upperf 6800
-nfilt 25
-transform dct
-lifter 22
-feat 1s_c_d_dd
-svspec 0-12/13-25/26-38
-agc none
-cmn current
-varnorm no
-model ptm
-cmninit 40,3,-1

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 MiB

View File

@ -0,0 +1,5 @@
<s> SIL
</s> SIL
<sil> SIL
[NOISE] +NSN+
[SPEECH] +SPN+

View File

@ -0,0 +1,16 @@
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
libs=@LIBS@
datarootdir=@datarootdir@
modeldir=@datadir@/@PACKAGE@/model
Name: PocketSphinx
Description: Lightweight speech recognition system
Version: @VERSION@
URL: http://cmusphinx.sourceforge.net/
Requires: sphinxbase >= @VERSION@
Libs: -L${libdir} -lpocketsphinx
Libs.private: ${libs} -lm
Cflags: -I${includedir} -I${includedir}/sphinxbase -I${includedir}/pocketsphinx

View File

@ -0,0 +1,58 @@

Microsoft Visual Studio Solution File, Format Version 11.00
# Visual C++ Express 2010
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pocketsphinx", "win32\pocketsphinx\pocketsphinx.vcxproj", "{94001A0E-A837-445C-8004-F918F10D0226}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pocketsphinx_continuous", "win32\pocketsphinx_continuous\pocketsphinx_continuous.vcxproj", "{1380AF76-C926-44D0-8002-06C228AC869A}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pocketsphinx_batch", "win32\pocketsphinx_batch\pocketsphinx_batch.vcxproj", "{CB47D94B-2F84-41BC-A3C4-A1EBDCDE922A}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pocketsphinx_mdef_convert", "win32\pocketsphinx_mdef_convert\pocketsphinx_mdef_convert.vcxproj", "{4FB65800-11B8-46BD-95B8-6E4F73BDAD91}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Release|Win32 = Release|Win32
Debug|Win32 = Debug|Win32
Release|x64 = Release|x64
Debug|x64 = Debug|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{1380AF76-C926-44D0-8002-06C228AC869A}.Debug|Win32.ActiveCfg = Debug|Win32
{1380AF76-C926-44D0-8002-06C228AC869A}.Debug|Win32.Build.0 = Debug|Win32
{1380AF76-C926-44D0-8002-06C228AC869A}.Release|Win32.ActiveCfg = Release|Win32
{1380AF76-C926-44D0-8002-06C228AC869A}.Release|Win32.Build.0 = Release|Win32
{CB47D94B-2F84-41BC-A3C4-A1EBDCDE922A}.Debug|Win32.ActiveCfg = Debug|Win32
{CB47D94B-2F84-41BC-A3C4-A1EBDCDE922A}.Debug|Win32.Build.0 = Debug|Win32
{CB47D94B-2F84-41BC-A3C4-A1EBDCDE922A}.Release|Win32.ActiveCfg = Release|Win32
{CB47D94B-2F84-41BC-A3C4-A1EBDCDE922A}.Release|Win32.Build.0 = Release|Win32
{FDF5E3A4-147B-4AE4-901B-90BBFF17D5A4}.Debug|Win32.ActiveCfg = Debug|Win32
{94001A0E-A837-445C-8004-F918F10D0226}.Debug|Win32.ActiveCfg = Debug|Win32
{94001A0E-A837-445C-8004-F918F10D0226}.Debug|Win32.Build.0 = Debug|Win32
{94001A0E-A837-445C-8004-F918F10D0226}.Release|Win32.ActiveCfg = Release|Win32
{94001A0E-A837-445C-8004-F918F10D0226}.Release|Win32.Build.0 = Release|Win32
{4FB65800-11B8-46BD-95B8-6E4F73BDAD91}.Debug|Win32.ActiveCfg = Debug|Win32
{4FB65800-11B8-46BD-95B8-6E4F73BDAD91}.Debug|Win32.Build.0 = Debug|Win32
{4FB65800-11B8-46BD-95B8-6E4F73BDAD91}.Release|Win32.ActiveCfg = Release|Win32
{4FB65800-11B8-46BD-95B8-6E4F73BDAD91}.Release|Win32.Build.0 = Release|Win32
{1380AF76-C926-44D0-8002-06C228AC869A}.Debug|x64.ActiveCfg = Debug|x64
{1380AF76-C926-44D0-8002-06C228AC869A}.Debug|x64.Build.0 = Debug|x64
{1380AF76-C926-44D0-8002-06C228AC869A}.Release|x64.ActiveCfg = Release|x64
{1380AF76-C926-44D0-8002-06C228AC869A}.Release|x64.Build.0 = Release|x64
{CB47D94B-2F84-41BC-A3C4-A1EBDCDE922A}.Debug|x64.ActiveCfg = Debug|x64
{CB47D94B-2F84-41BC-A3C4-A1EBDCDE922A}.Debug|x64.Build.0 = Debug|x64
{CB47D94B-2F84-41BC-A3C4-A1EBDCDE922A}.Release|x64.ActiveCfg = Release|x64
{CB47D94B-2F84-41BC-A3C4-A1EBDCDE922A}.Release|x64.Build.0 = Release|x64
{FDF5E3A4-147B-4AE4-901B-90BBFF17D5A4}.Debug|x64.ActiveCfg = Debug|x64
{94001A0E-A837-445C-8004-F918F10D0226}.Debug|x64.ActiveCfg = Debug|x64
{94001A0E-A837-445C-8004-F918F10D0226}.Debug|x64.Build.0 = Debug|x64
{94001A0E-A837-445C-8004-F918F10D0226}.Release|x64.ActiveCfg = Release|x64
{94001A0E-A837-445C-8004-F918F10D0226}.Release|x64.Build.0 = Release|x64
{4FB65800-11B8-46BD-95B8-6E4F73BDAD91}.Debug|x64.ActiveCfg = Debug|x64
{4FB65800-11B8-46BD-95B8-6E4F73BDAD91}.Debug|x64.Build.0 = Debug|x64
{4FB65800-11B8-46BD-95B8-6E4F73BDAD91}.Release|x64.ActiveCfg = Release|x64
{4FB65800-11B8-46BD-95B8-6E4F73BDAD91}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,170 @@
#!/bin/sh
# py-compile - Compile a Python program
scriptversion=2011-06-08.12; # UTC
# Copyright (C) 2000-2013 Free Software Foundation, Inc.
# 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 <http://www.gnu.org/licenses/>.
# 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 <bug-automake@gnu.org> or send patches to
# <automake-patches@gnu.org>.
if [ -z "$PYTHON" ]; then
PYTHON=python
fi
me=py-compile
usage_error ()
{
echo "$me: $*" >&2
echo "Try '$me --help' for more information." >&2
exit 1
}
basedir=
destdir=
while test $# -ne 0; do
case "$1" in
--basedir)
if test $# -lt 2; then
usage_error "option '--basedir' requires an argument"
else
basedir=$2
fi
shift
;;
--destdir)
if test $# -lt 2; then
usage_error "option '--destdir' requires an argument"
else
destdir=$2
fi
shift
;;
-h|--help)
cat <<\EOF
Usage: py-compile [--help] [--version] [--basedir DIR] [--destdir DIR] FILES..."
Byte compile some python scripts FILES. Use --destdir to specify any
leading directory path to the FILES that you don't want to include in the
byte compiled file. Specify --basedir for any additional path information you
do want to be shown in the byte compiled file.
Example:
py-compile --destdir /tmp/pkg-root --basedir /usr/share/test test.py test2.py
Report bugs to <bug-automake@gnu.org>.
EOF
exit $?
;;
-v|--version)
echo "$me $scriptversion"
exit $?
;;
--)
shift
break
;;
-*)
usage_error "unrecognized option '$1'"
;;
*)
break
;;
esac
shift
done
files=$*
if test -z "$files"; then
usage_error "no files given"
fi
# if basedir was given, then it should be prepended to filenames before
# byte compilation.
if [ -z "$basedir" ]; then
pathtrans="path = file"
else
pathtrans="path = os.path.join('$basedir', file)"
fi
# if destdir was given, then it needs to be prepended to the filename to
# byte compile but not go into the compiled file.
if [ -z "$destdir" ]; then
filetrans="filepath = path"
else
filetrans="filepath = os.path.normpath('$destdir' + os.sep + path)"
fi
$PYTHON -c "
import sys, os, py_compile, imp
files = '''$files'''
sys.stdout.write('Byte-compiling python modules...\n')
for file in files.split():
$pathtrans
$filetrans
if not os.path.exists(filepath) or not (len(filepath) >= 3
and filepath[-3:] == '.py'):
continue
sys.stdout.write(file)
sys.stdout.flush()
if hasattr(imp, 'get_tag'):
py_compile.compile(filepath, imp.cache_from_source(filepath), path)
else:
py_compile.compile(filepath, filepath + 'c', path)
sys.stdout.write('\n')" || exit $?
# this will fail for python < 1.5, but that doesn't matter ...
$PYTHON -O -c "
import sys, os, py_compile, imp
# pypy does not use .pyo optimization
if hasattr(sys, 'pypy_translation_info'):
sys.exit(0)
files = '''$files'''
sys.stdout.write('Byte-compiling python modules (optimized versions) ...\n')
for file in files.split():
$pathtrans
$filetrans
if not os.path.exists(filepath) or not (len(filepath) >= 3
and filepath[-3:] == '.py'):
continue
sys.stdout.write(file)
sys.stdout.flush()
if hasattr(imp, 'get_tag'):
py_compile.compile(filepath, imp.cache_from_source(filepath, False), path)
else:
py_compile.compile(filepath, filepath + 'o', path)
sys.stdout.write('\n')" 2>/dev/null || :
# 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:

View File

@ -0,0 +1,3 @@
SUBDIRS = libpocketsphinx \
programs \
gst-plugin

View File

@ -0,0 +1,635 @@
# Makefile.in generated by automake 1.13.4 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2013 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.
@SET_MAKE@
VPATH = @srcdir@
am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
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)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
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 = @build@
host_triplet = @host@
subdir = src
DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_pkg_swig.m4 \
$(top_srcdir)/m4/ax_python_devel.m4 \
$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
$(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/pkg.m4 \
$(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false
am__v_P_1 = :
AM_V_GEN = $(am__v_GEN_@AM_V@)
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
am__v_GEN_0 = @echo " GEN " $@;
am__v_GEN_1 =
AM_V_at = $(am__v_at_@AM_V@)
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
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 \
distdir
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
DIST_SUBDIRS = $(SUBDIRS)
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
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"
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GREP = @GREP@
GST_CFLAGS = @GST_CFLAGS@
GST_LIBS = @GST_LIBS@
GST_MAJORMINOR = @GST_MAJORMINOR@
GST_PLUGIN_LDFLAGS = @GST_PLUGIN_LDFLAGS@
GStreamer_CFLAGS = @GStreamer_CFLAGS@
GStreamer_LIBS = @GStreamer_LIBS@
HAVE_DOXYGEN = @HAVE_DOXYGEN@
HAVE_PKGCONFIG = @HAVE_PKGCONFIG@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LD = @LD@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PKG_CONFIG = @PKG_CONFIG@
PYTHON = @PYTHON@
PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@
PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@
PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@
PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
PYTHON_PLATFORM = @PYTHON_PLATFORM@
PYTHON_PREFIX = @PYTHON_PREFIX@
PYTHON_SITE_PKG = @PYTHON_SITE_PKG@
PYTHON_VERSION = @PYTHON_VERSION@
RANLIB = @RANLIB@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
SPHINXBASE_CFLAGS = @SPHINXBASE_CFLAGS@
SPHINXBASE_LIBS = @SPHINXBASE_LIBS@
SPHINXBASE_SWIG = @SPHINXBASE_SWIG@
STRIP = @STRIP@
SWIG = @SWIG@
SWIG_LIB = @SWIG_LIB@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
pkgpyexecdir = @pkgpyexecdir@
pkgpythondir = @pkgpythondir@
plugindir = @plugindir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
pyexecdir = @pyexecdir@
pythondir = @pythondir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
SUBDIRS = libpocketsphinx \
programs \
gst-plugin
all: all-recursive
.SUFFIXES:
$(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) --foreign src/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign src/Makefile
.PRECIOUS: 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):
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
# 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"
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
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
@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
check-am: all-am
check: check-recursive
all-am: Makefile
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 Makefile
distclean-am: clean-am distclean-generic 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 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) install-am install-strip
.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \
check-am clean clean-generic clean-libtool cscopelist-am ctags \
ctags-am distclean 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-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
# 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:

View File

@ -0,0 +1,29 @@
my_plugins =
my_headers =
my_files =
if BUILD_GST
my_plugins += libgstpocketsphinx.la
endif
plugin_LTLIBRARIES = $(my_plugins)
libgstpocketsphinx_la_SOURCES = gstpocketsphinx.c
libgstpocketsphinx_la_LIBADD = \
$(GST_LIBS) \
-lgstaudio-$(GST_MAJORMINOR) \
$(top_builddir)/src/libpocketsphinx/libpocketsphinx.la \
-lsphinxbase
libgstpocketsphinx_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
noinst_HEADERS = gstpocketsphinx.h
AM_CFLAGS = \
-I$(top_srcdir)/include \
-I$(top_builddir)/include \
$(GST_CFLAGS) \
-DMODELDIR=\"$(pkgdatadir)/model\"
EXTRA_DIST = livedemo.py livedemo.c

View File

@ -0,0 +1,684 @@
# Makefile.in generated by automake 1.13.4 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2013 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.
@SET_MAKE@
VPATH = @srcdir@
am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
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)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
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 = @build@
host_triplet = @host@
@BUILD_GST_TRUE@am__append_1 = libgstpocketsphinx.la
subdir = src/gst-plugin
DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
$(top_srcdir)/depcomp $(noinst_HEADERS)
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_pkg_swig.m4 \
$(top_srcdir)/m4/ax_python_devel.m4 \
$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
$(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/pkg.m4 \
$(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
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 =
libgstpocketsphinx_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \
$(top_builddir)/src/libpocketsphinx/libpocketsphinx.la
am_libgstpocketsphinx_la_OBJECTS = gstpocketsphinx.lo
libgstpocketsphinx_la_OBJECTS = $(am_libgstpocketsphinx_la_OBJECTS)
AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
am__v_lt_0 = --silent
am__v_lt_1 =
libgstpocketsphinx_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
$(AM_CFLAGS) $(CFLAGS) $(libgstpocketsphinx_la_LDFLAGS) \
$(LDFLAGS) -o $@
@BUILD_GST_TRUE@am_libgstpocketsphinx_la_rpath = -rpath $(plugindir)
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false
am__v_P_1 = :
AM_V_GEN = $(am__v_GEN_@AM_V@)
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
am__v_GEN_0 = @echo " GEN " $@;
am__v_GEN_1 =
AM_V_at = $(am__v_at_@AM_V@)
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
am__v_at_0 = @
am__v_at_1 =
DEFAULT_INCLUDES = -I.@am__isrc@
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_@AM_V@)
am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
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_@AM_V@)
am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
am__v_CCLD_0 = @echo " CCLD " $@;
am__v_CCLD_1 =
SOURCES = $(libgstpocketsphinx_la_SOURCES)
DIST_SOURCES = $(libgstpocketsphinx_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
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GREP = @GREP@
GST_CFLAGS = @GST_CFLAGS@
GST_LIBS = @GST_LIBS@
GST_MAJORMINOR = @GST_MAJORMINOR@
GST_PLUGIN_LDFLAGS = @GST_PLUGIN_LDFLAGS@
GStreamer_CFLAGS = @GStreamer_CFLAGS@
GStreamer_LIBS = @GStreamer_LIBS@
HAVE_DOXYGEN = @HAVE_DOXYGEN@
HAVE_PKGCONFIG = @HAVE_PKGCONFIG@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LD = @LD@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PKG_CONFIG = @PKG_CONFIG@
PYTHON = @PYTHON@
PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@
PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@
PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@
PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
PYTHON_PLATFORM = @PYTHON_PLATFORM@
PYTHON_PREFIX = @PYTHON_PREFIX@
PYTHON_SITE_PKG = @PYTHON_SITE_PKG@
PYTHON_VERSION = @PYTHON_VERSION@
RANLIB = @RANLIB@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
SPHINXBASE_CFLAGS = @SPHINXBASE_CFLAGS@
SPHINXBASE_LIBS = @SPHINXBASE_LIBS@
SPHINXBASE_SWIG = @SPHINXBASE_SWIG@
STRIP = @STRIP@
SWIG = @SWIG@
SWIG_LIB = @SWIG_LIB@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
pkgpyexecdir = @pkgpyexecdir@
pkgpythondir = @pkgpythondir@
plugindir = @plugindir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
pyexecdir = @pyexecdir@
pythondir = @pythondir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
my_plugins = $(am__append_1)
my_headers =
my_files =
plugin_LTLIBRARIES = $(my_plugins)
libgstpocketsphinx_la_SOURCES = gstpocketsphinx.c
libgstpocketsphinx_la_LIBADD = \
$(GST_LIBS) \
-lgstaudio-$(GST_MAJORMINOR) \
$(top_builddir)/src/libpocketsphinx/libpocketsphinx.la \
-lsphinxbase
libgstpocketsphinx_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
noinst_HEADERS = gstpocketsphinx.h
AM_CFLAGS = \
-I$(top_srcdir)/include \
-I$(top_builddir)/include \
$(GST_CFLAGS) \
-DMODELDIR=\"$(pkgdatadir)/model\"
EXTRA_DIST = livedemo.py livedemo.c
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) --foreign src/gst-plugin/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign src/gst-plugin/Makefile
.PRECIOUS: 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}; \
}
libgstpocketsphinx.la: $(libgstpocketsphinx_la_OBJECTS) $(libgstpocketsphinx_la_DEPENDENCIES) $(EXTRA_libgstpocketsphinx_la_DEPENDENCIES)
$(AM_V_CCLD)$(libgstpocketsphinx_la_LINK) $(am_libgstpocketsphinx_la_rpath) $(libgstpocketsphinx_la_OBJECTS) $(libgstpocketsphinx_la_LIBADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gstpocketsphinx.Plo@am__quote@
.c.o:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $<
.c.obj:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'`
.c.lo:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
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
# 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:

View File

@ -0,0 +1,724 @@
/* -*- c-basic-offset: 4; indent-tabs-mode: nil -*- */
/* ====================================================================
* Copyright (c) 2014 Alpha Cephei Inc.
* Copyright (c) 2007 Carnegie Mellon University. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. 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 work was supported in part by funding from the Defense Advanced
* Research Projects Agency and the National Science Foundation of the
* United States of America, and the CMU Sphinx Speech Consortium.
*
* THIS SOFTWARE IS PROVIDED BY CARNEGIE MELLON UNIVERSITY ``AS IS'' AND
* ANY EXPRESSED 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 CARNEGIE MELLON UNIVERSITY
* NOR ITS EMPLOYEES 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.
*
* ====================================================================
*
* Author: David Huggins-Daines <dhuggins@cs.cmu.edu>
*/
/**
* SECTION:element-pocketsphix
*
* The element runs the speech recohgnition on incomming audio buffers and
* generates an element messages named <classname>&quot;pocketsphinx&quot;</classname>
* for each hypothesis and one for the final result. The message's structure
* contains these fields:
*
* <itemizedlist>
* <listitem>
* <para>
* #GstClockTime
* <classname>&quot;timestamp&quot;</classname>:
* the timestamp of the buffer that triggered the message.
* </para>
* </listitem>
* <listitem>
* <para>
* #gboolean
* <classname>&quot;final&quot;</classname>:
* %FALSE for intermediate messages.
* </para>
* </listitem>
* <listitem>
* <para>
* #gin32
* <classname>&quot;confidence&quot;</classname>:
* posterior probability (confidence) of the result in log domain
* </para>
* </listitem>
* <listitem>
* <para>
* #gchar
* <classname>&quot;hypothesis&quot;</classname>:
* the recognized text
* </para>
* </listitem>
* </itemizedlist>
*
* <refsect2>
* <title>Example pipeline</title>
* |[
* gst-launch-1.0 -m autoaudiosrc ! audioconvert ! audioresample ! pocketsphinx configured=true ! fakesink
* ]|
* </refsect2>
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <string.h>
#include <gst/gst.h>
#include <sphinxbase/err.h>
#include <sphinxbase/strfuncs.h>
#include "gstpocketsphinx.h"
GST_DEBUG_CATEGORY_STATIC(pocketsphinx_debug);
#define GST_CAT_DEFAULT pocketsphinx_debug
static void
gst_pocketsphinx_set_property(GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec);
static void
gst_pocketsphinx_get_property(GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec);
static GstFlowReturn
gst_pocketsphinx_chain(GstPad * pad, GstObject *parent, GstBuffer * buffer);
static gboolean
gst_pocketsphinx_event(GstPad *pad, GstObject *parent, GstEvent *event);
static void
gst_pocketsphinx_finalize_utt(GstPocketSphinx *ps);
static void
gst_pocketsphinx_finalize(GObject * gobject);
enum
{
PROP_0,
PROP_HMM_DIR,
PROP_LM_FILE,
PROP_LMCTL_FILE,
PROP_LM_NAME,
PROP_DICT_FILE,
PROP_MLLR_FILE,
PROP_FSG_FILE,
PROP_FSG_MODEL,
PROP_FWDFLAT,
PROP_BESTPATH,
PROP_MAXHMMPF,
PROP_MAXWPF,
PROP_BEAM,
PROP_WBEAM,
PROP_PBEAM,
PROP_DSRATIO,
PROP_LATDIR,
PROP_DECODER,
PROP_CONFIGURED
};
/*
* Static data.
*/
/* Default command line. (will go away soon and be constructed using properties) */
static char *default_argv[] = {
"gst-pocketsphinx",
};
static const int default_argc = sizeof(default_argv)/sizeof(default_argv[0]);
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/plain")
);
/*
* Boxing of ps_decoder_t.
*/
GType
ps_decoder_get_type(void)
{
static GType ps_decoder_type = 0;
if (G_UNLIKELY(ps_decoder_type == 0)) {
ps_decoder_type = g_boxed_type_register_static
("PSDecoder",
/* Conveniently, these should just work. */
(GBoxedCopyFunc) ps_retain,
(GBoxedFreeFunc) ps_free);
}
return ps_decoder_type;
}
G_DEFINE_TYPE(GstPocketSphinx, gst_pocketsphinx, GST_TYPE_ELEMENT);
static void
gst_pocketsphinx_class_init(GstPocketSphinxClass * klass)
{
GObjectClass *gobject_class;
GstElementClass *element_class;;
gobject_class =(GObjectClass *) klass;
element_class = (GstElementClass *)klass;
gobject_class->set_property = gst_pocketsphinx_set_property;
gobject_class->get_property = gst_pocketsphinx_get_property;
gobject_class->finalize = gst_pocketsphinx_finalize;
/* TODO: We will bridge cmd_ln.h properties to GObject
* properties here somehow eventually. */
g_object_class_install_property
(gobject_class, PROP_HMM_DIR,
g_param_spec_string("hmm", "HMM Directory",
"Directory containing acoustic model parameters",
NULL,
G_PARAM_READWRITE));
g_object_class_install_property
(gobject_class, PROP_LM_FILE,
g_param_spec_string("lm", "LM File",
"Language model file",
NULL,
G_PARAM_READWRITE));
g_object_class_install_property
(gobject_class, PROP_LMCTL_FILE,
g_param_spec_string("lmctl", "LM Control File",
"Language model control file (for class LMs)",
NULL,
G_PARAM_READWRITE));
g_object_class_install_property
(gobject_class, PROP_LM_NAME,
g_param_spec_string("lmname", "LM Name",
"Language model name (to select LMs from lmctl)",
NULL,
G_PARAM_READWRITE));
g_object_class_install_property
(gobject_class, PROP_FSG_FILE,
g_param_spec_string("fsg", "FSG File",
"Finite state grammar file",
NULL,
G_PARAM_READWRITE));
g_object_class_install_property
(gobject_class, PROP_FSG_MODEL,
g_param_spec_pointer("fsg_model", "FSG Model",
"Finite state grammar object (fsg_model_t *)",
G_PARAM_WRITABLE));
g_object_class_install_property
(gobject_class, PROP_DICT_FILE,
g_param_spec_string("dict", "Dictionary File",
"Dictionary File",
NULL,
G_PARAM_READWRITE));
g_object_class_install_property
(gobject_class, PROP_FWDFLAT,
g_param_spec_boolean("fwdflat", "Flat Lexicon Search",
"Enable Flat Lexicon Search",
FALSE,
G_PARAM_READWRITE));
g_object_class_install_property
(gobject_class, PROP_BESTPATH,
g_param_spec_boolean("bestpath", "Graph Search",
"Enable Graph Search",
FALSE,
G_PARAM_READWRITE));
g_object_class_install_property
(gobject_class, PROP_LATDIR,
g_param_spec_string("latdir", "Lattice Directory",
"Output Directory for Lattices",
NULL,
G_PARAM_READWRITE));
g_object_class_install_property
(gobject_class, PROP_MAXHMMPF,
g_param_spec_int("maxhmmpf", "Maximum HMMs per frame",
"Maximum number of HMMs searched per frame",
1, 100000, 1000,
G_PARAM_READWRITE));
g_object_class_install_property
(gobject_class, PROP_MAXWPF,
g_param_spec_int("maxwpf", "Maximum words per frame",
"Maximum number of words searched per frame",
1, 100000, 10,
G_PARAM_READWRITE));
g_object_class_install_property
(gobject_class, PROP_BEAM,
g_param_spec_double("beam", "Beam width applied to every frame in Viterbi search",
"Beam width applied to every frame in Viterbi search",
-1, 1, 1e-48,
G_PARAM_READWRITE));
g_object_class_install_property
(gobject_class, PROP_PBEAM,
g_param_spec_double("pbeam", "Beam width applied to phone transitions",
"Beam width applied to phone transitions",
-1, 1, 1e-48,
G_PARAM_READWRITE));
g_object_class_install_property
(gobject_class, PROP_WBEAM,
g_param_spec_double("wbeam", "Beam width applied to word exits",
"Beam width applied to phone transitions",
-1, 1, 7e-29,
G_PARAM_READWRITE));
g_object_class_install_property
(gobject_class, PROP_DSRATIO,
g_param_spec_int("dsratio", "Frame downsampling ratio",
"Evaluate acoustic model every N frames",
1, 10, 1,
G_PARAM_READWRITE));
g_object_class_install_property
(gobject_class, PROP_DECODER,
g_param_spec_boxed("decoder", "Decoder object",
"The underlying decoder",
PS_DECODER_TYPE,
G_PARAM_READABLE));
g_object_class_install_property
(gobject_class, PROP_CONFIGURED,
g_param_spec_boolean("configured", "Finalize configuration",
"Set this to finalize configuration",
FALSE,
G_PARAM_READWRITE));
GST_DEBUG_CATEGORY_INIT(pocketsphinx_debug, "pocketsphinx", 0,
"Automatic Speech Recognition");
gst_element_class_add_pad_template(element_class,
gst_static_pad_template_get(&sink_factory));
gst_element_class_add_pad_template(element_class,
gst_static_pad_template_get(&src_factory));
gst_element_class_set_static_metadata(element_class, "PocketSphinx", "Filter/Audio", "Convert speech to text", "CMUSphinx-devel <cmusphinx-devel@lists.sourceforge.net>");
}
static void
gst_pocketsphinx_set_string(GstPocketSphinx *ps,
const gchar *key, const GValue *value)
{
if (value != NULL) {
cmd_ln_set_str_r(ps->config, key, g_value_get_string(value));
} else {
cmd_ln_set_str_r(ps->config, key, NULL);
}
}
static void
gst_pocketsphinx_set_int(GstPocketSphinx *ps,
const gchar *key, const GValue *value)
{
cmd_ln_set_int32_r(ps->config, key, g_value_get_int(value));
}
static void
gst_pocketsphinx_set_boolean(GstPocketSphinx *ps,
const gchar *key, const GValue *value)
{
cmd_ln_set_boolean_r(ps->config, key, g_value_get_boolean(value));
}
static void
gst_pocketsphinx_set_double(GstPocketSphinx *ps,
const gchar *key, const GValue *value)
{
cmd_ln_set_float_r(ps->config, key, g_value_get_double(value));
}
static void
gst_pocketsphinx_set_property(GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec)
{
GstPocketSphinx *ps = GST_POCKETSPHINX(object);
switch (prop_id) {
case PROP_CONFIGURED:
ps_reinit(ps->ps, ps->config);
break;
case PROP_HMM_DIR:
gst_pocketsphinx_set_string(ps, "-hmm", value);
break;
case PROP_LM_FILE:
/* FSG and LM are mutually exclusive. */
gst_pocketsphinx_set_string(ps, "-fsg", NULL);
gst_pocketsphinx_set_string(ps, "-lmctl", NULL);
gst_pocketsphinx_set_string(ps, "-lm", value);
break;
case PROP_LMCTL_FILE:
/* FSG and LM are mutually exclusive. */
gst_pocketsphinx_set_string(ps, "-fsg", NULL);
gst_pocketsphinx_set_string(ps, "-lmctl", value);
gst_pocketsphinx_set_string(ps, "-lm", NULL);
break;
case PROP_LM_NAME:
gst_pocketsphinx_set_string(ps, "-fsg", NULL);
gst_pocketsphinx_set_string(ps, "-lm", NULL);
gst_pocketsphinx_set_string(ps, "-lmname", value);
/**
* Chances are that lmctl is already loaded and all
* corresponding searches are configured, so we simply
* try to set the search
*/
if (value != NULL) {
ps_set_search(ps->ps, g_value_get_string(value));
}
break;
case PROP_DICT_FILE:
gst_pocketsphinx_set_string(ps, "-dict", value);
break;
case PROP_MLLR_FILE:
gst_pocketsphinx_set_string(ps, "-mllr", value);
break;
case PROP_FSG_MODEL:
{
fsg_model_t *fsg = g_value_get_pointer(value);
const char *name = fsg_model_name(fsg);
ps_set_fsg(ps->ps, name, fsg);
ps_set_search(ps->ps, name);
}
break;
case PROP_FSG_FILE:
/* FSG and LM are mutually exclusive */
gst_pocketsphinx_set_string(ps, "-lm", NULL);
gst_pocketsphinx_set_string(ps, "-fsg", value);
break;
case PROP_FWDFLAT:
gst_pocketsphinx_set_boolean(ps, "-fwdflat", value);
break;
case PROP_BESTPATH:
gst_pocketsphinx_set_boolean(ps, "-bestpath", value);
break;
case PROP_LATDIR:
if (ps->latdir)
g_free(ps->latdir);
ps->latdir = g_strdup(g_value_get_string(value));
break;
case PROP_MAXHMMPF:
gst_pocketsphinx_set_int(ps, "-maxhmmpf", value);
break;
case PROP_MAXWPF:
gst_pocketsphinx_set_int(ps, "-maxwpf", value);
break;
case PROP_BEAM:
gst_pocketsphinx_set_double(ps, "-beam", value);
break;
case PROP_PBEAM:
gst_pocketsphinx_set_double(ps, "-pbeam", value);
break;
case PROP_WBEAM:
gst_pocketsphinx_set_double(ps, "-wbeam", value);
break;
case PROP_DSRATIO:
gst_pocketsphinx_set_int(ps, "-ds", value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
return;
}
}
static void
gst_pocketsphinx_get_property(GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec)
{
GstPocketSphinx *ps = GST_POCKETSPHINX(object);
switch (prop_id) {
case PROP_DECODER:
g_value_set_boxed(value, ps->ps);
break;
case PROP_CONFIGURED:
g_value_set_boolean(value, ps->ps != NULL);
break;
case PROP_HMM_DIR:
g_value_set_string(value, cmd_ln_str_r(ps->config, "-hmm"));
break;
case PROP_LM_FILE:
g_value_set_string(value, cmd_ln_str_r(ps->config, "-lm"));
break;
case PROP_LMCTL_FILE:
g_value_set_string(value, cmd_ln_str_r(ps->config, "-lmctl"));
break;
case PROP_LM_NAME:
g_value_set_string(value, cmd_ln_str_r(ps->config, "-lmname"));
break;
case PROP_DICT_FILE:
g_value_set_string(value, cmd_ln_str_r(ps->config, "-dict"));
break;
case PROP_MLLR_FILE:
g_value_set_string(value, cmd_ln_str_r(ps->config, "-mllr"));
break;
case PROP_FSG_FILE:
g_value_set_string(value, cmd_ln_str_r(ps->config, "-fsg"));
break;
case PROP_FWDFLAT:
g_value_set_boolean(value, cmd_ln_boolean_r(ps->config, "-fwdflat"));
break;
case PROP_BESTPATH:
g_value_set_boolean(value, cmd_ln_boolean_r(ps->config, "-bestpath"));
break;
case PROP_LATDIR:
g_value_set_string(value, ps->latdir);
break;
case PROP_MAXHMMPF:
g_value_set_int(value, cmd_ln_int32_r(ps->config, "-maxhmmpf"));
break;
case PROP_MAXWPF:
g_value_set_int(value, cmd_ln_int32_r(ps->config, "-maxwpf"));
break;
case PROP_BEAM:
g_value_set_double(value, cmd_ln_float_r(ps->config, "-beam"));
break;
case PROP_PBEAM:
g_value_set_double(value, cmd_ln_float_r(ps->config, "-pbeam"));
break;
case PROP_WBEAM:
g_value_set_double(value, cmd_ln_float_r(ps->config, "-wbeam"));
break;
case PROP_DSRATIO:
g_value_set_int(value, cmd_ln_int32_r(ps->config, "-ds"));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
break;
}
}
static void
gst_pocketsphinx_finalize(GObject * gobject)
{
GstPocketSphinx *ps = GST_POCKETSPHINX(gobject);
ps_free(ps->ps);
cmd_ln_free_r(ps->config);
g_free(ps->last_result);
G_OBJECT_CLASS(gst_pocketsphinx_parent_class)->finalize(gobject);
}
static void
gst_pocketsphinx_init(GstPocketSphinx * ps)
{
ps->sinkpad =
gst_pad_new_from_static_template(&sink_factory, "sink");
ps->srcpad =
gst_pad_new_from_static_template(&src_factory, "src");
/* Parse default command-line options. */
ps->config = cmd_ln_parse_r(NULL, ps_args(), default_argc, default_argv, FALSE);
ps_default_search_args(ps->config);
ps->ps = ps_init(ps->config);
if (ps->ps == NULL) {
GST_ELEMENT_ERROR(GST_ELEMENT(ps), LIBRARY, INIT,
("Failed to initialize PocketSphinx"),
("Failed to initialize PocketSphinx"));
}
/* Set up pads. */
gst_element_add_pad(GST_ELEMENT(ps), ps->sinkpad);
gst_pad_set_chain_function(ps->sinkpad, gst_pocketsphinx_chain);
gst_pad_set_event_function(ps->sinkpad, gst_pocketsphinx_event);
gst_pad_use_fixed_caps(ps->sinkpad);
gst_element_add_pad(GST_ELEMENT(ps), ps->srcpad);
gst_pad_use_fixed_caps(ps->srcpad);
/* Initialize time. */
ps->last_result_time = 0;
ps->last_result = NULL;
}
static void
gst_pocketsphinx_post_message(GstPocketSphinx *ps, gboolean final,
GstClockTime timestamp, gint32 prob, const gchar *hyp)
{
GstStructure *s = gst_structure_new ("pocketsphinx",
"timestamp", G_TYPE_UINT64, timestamp,
"final", G_TYPE_BOOLEAN, final,
"confidence", G_TYPE_LONG, prob,
"hypothesis", G_TYPE_STRING, hyp, NULL);
gst_element_post_message (GST_ELEMENT (ps), gst_message_new_element (GST_OBJECT (ps), s));
}
static GstFlowReturn
gst_pocketsphinx_chain(GstPad * pad, GstObject *parent, GstBuffer * buffer)
{
GstPocketSphinx *ps;
GstMapInfo info;
gboolean in_speech;
ps = GST_POCKETSPHINX(parent);
/* Start an utterance for the first buffer we get */
if (!ps->listening_started) {
ps->listening_started = TRUE;
ps->utt_started = FALSE;
ps_start_utt(ps->ps);
}
gst_buffer_map (buffer, &info, GST_MAP_READ);
ps_process_raw(ps->ps,
(short*) info.data,
info.size / sizeof(short),
FALSE, FALSE);
gst_buffer_unmap (buffer, &info);
in_speech = ps_get_in_speech(ps->ps);
if (in_speech && !ps->utt_started) {
ps->utt_started = TRUE;
}
if (!in_speech && ps->utt_started) {
gst_pocketsphinx_finalize_utt(ps);
} else if (ps->last_result_time == 0
/* Get a partial result every now and then, see if it is different. */
/* Check every 100 milliseconds. */
|| (GST_BUFFER_TIMESTAMP(buffer) - ps->last_result_time) > 100*10*1000) {
int32 score;
char const *hyp;
hyp = ps_get_hyp(ps->ps, &score);
ps->last_result_time = GST_BUFFER_TIMESTAMP(buffer);
if (hyp && strlen(hyp) > 0) {
if (ps->last_result == NULL || 0 != strcmp(ps->last_result, hyp)) {
g_free(ps->last_result);
ps->last_result = g_strdup(hyp);
gst_pocketsphinx_post_message(ps, FALSE, ps->last_result_time,
ps_get_prob(ps->ps), hyp);
}
}
}
gst_buffer_unref(buffer);
return GST_FLOW_OK;
}
static void
gst_pocketsphinx_finalize_utt(GstPocketSphinx *ps)
{
GstBuffer *buffer;
char const *hyp;
int32 score;
hyp = NULL;
if (!ps->listening_started || !ps->utt_started)
return;
ps_end_utt(ps->ps);
ps->listening_started = FALSE;
hyp = ps_get_hyp(ps->ps, &score);
/* Dump the lattice if requested. */
if (ps->latdir) {
char *latfile;
char uttid[16];
sprintf(uttid, "%09u", ps->uttno);
ps->uttno++;
latfile = string_join(ps->latdir, "/", uttid, ".lat", NULL);
ps_lattice_t *dag;
if ((dag = ps_get_lattice(ps->ps)))
ps_lattice_write(dag, latfile);
ckd_free(latfile);
}
if (hyp) {
gst_pocketsphinx_post_message(ps, TRUE, GST_CLOCK_TIME_NONE,
ps_get_prob(ps->ps), hyp);
buffer = gst_buffer_new_and_alloc(strlen(hyp) + 1);
gst_buffer_fill(buffer, 0, hyp, strlen(hyp));
gst_buffer_fill(buffer, strlen(hyp), "\n", 1);
gst_pad_push(ps->srcpad, buffer);
}
}
static gboolean
gst_pocketsphinx_event(GstPad *pad, GstObject *parent, GstEvent *event)
{
GstPocketSphinx *ps;
ps = GST_POCKETSPHINX(parent);
switch (event->type) {
case GST_EVENT_EOS:
{
gst_pocketsphinx_finalize_utt(ps);
return gst_pad_event_default(pad, parent, event);
}
default:
return gst_pad_event_default(pad, parent, event);
}
}
static void
gst_pocketsphinx_log(void *user_data, err_lvl_t lvl, const char *fmt, ...)
{
static const int gst_level[ERR_MAX] = {GST_LEVEL_DEBUG, GST_LEVEL_INFO,
GST_LEVEL_INFO, GST_LEVEL_WARNING, GST_LEVEL_ERROR, GST_LEVEL_ERROR};
va_list ap;
va_start(ap, fmt);
gst_debug_log_valist(pocketsphinx_debug, gst_level[lvl], "", "", 0, NULL, fmt, ap);
va_end(ap);
}
static gboolean
plugin_init(GstPlugin * plugin)
{
err_set_callback(gst_pocketsphinx_log, NULL);
if (!gst_element_register(plugin, "pocketsphinx",
GST_RANK_NONE, GST_TYPE_POCKETSPHINX))
return FALSE;
return TRUE;
}
#define PACKAGE PACKAGE_NAME
GST_PLUGIN_DEFINE(GST_VERSION_MAJOR,
GST_VERSION_MINOR,
pocketsphinx,
"PocketSphinx plugin",
plugin_init, PACKAGE_VERSION,
"BSD",
"PocketSphinx", "http://cmusphinx.sourceforge.net/")

View File

@ -0,0 +1,98 @@
/* -*- c-basic-offset: 4; indent-tabs-mode: nil -*- */
/* ====================================================================
* Copyright (c) 2007 Carnegie Mellon University. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. 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 work was supported in part by funding from the Defense Advanced
* Research Projects Agency and the National Science Foundation of the
* United States of America, and the CMU Sphinx Speech Consortium.
*
* THIS SOFTWARE IS PROVIDED BY CARNEGIE MELLON UNIVERSITY ``AS IS'' AND
* ANY EXPRESSED 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 CARNEGIE MELLON UNIVERSITY
* NOR ITS EMPLOYEES 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.
*
* ====================================================================
*
* Author: David Huggins-Daines <dhuggins@cs.cmu.edu>
*/
#ifndef __GST_POCKETSPHINX_H__
#define __GST_POCKETSPHINX_H__
#include <gst/gst.h>
#include <pocketsphinx.h>
G_BEGIN_DECLS
#define GST_TYPE_POCKETSPHINX \
(gst_pocketsphinx_get_type())
#define GST_POCKETSPHINX(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_POCKETSPHINX,GstPocketSphinx))
#define GST_POCKETSPHINX_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_POCKETSPHINX,GstPocketSphinxClass))
#define GST_IS_POCKETSPHINX(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_POCKETSPHINX))
#define GST_IS_POCKETSPHINX_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_POCKETSPHINX))
typedef struct _GstPocketSphinx GstPocketSphinx;
typedef struct _GstPocketSphinxClass GstPocketSphinxClass;
struct _GstPocketSphinx
{
GstElement element;
GstPad *sinkpad, *srcpad;
ps_decoder_t *ps;
cmd_ln_t *config;
gchar *latdir; /**< Output directory for word lattices. */
gboolean utt_started;
gboolean listening_started;
gint uttno;
GstClockTime last_result_time; /**< Timestamp of last partial result. */
char *last_result; /**< String of last partial result. */
};
struct _GstPocketSphinxClass
{
GstElementClass parent_class;
void (*partial_result) (GstElement *element, const gchar *hyp_str);
void (*result) (GstElement *element, const gchar *hyp_str);
};
GType gst_pocketsphinx_get_type(void);
/*
* Boxing of decoder.
*/
#define PS_DECODER_TYPE (ps_decoder_get_type())
GType ps_decoder_get_type(void);
G_END_DECLS
#endif /* __GST_POCKETSPHINX_H__ */

View File

@ -0,0 +1,103 @@
#include <gst/gst.h>
#include <glib.h>
static gboolean
bus_call(GstBus * bus, GstMessage * msg, gpointer data)
{
GMainLoop *loop = (GMainLoop *) data;
switch (GST_MESSAGE_TYPE(msg)) {
case GST_MESSAGE_EOS:
g_print("End of stream\n");
g_main_loop_quit(loop);
break;
case GST_MESSAGE_ERROR:{
gchar *debug;
GError *error;
gst_message_parse_error(msg, &error, &debug);
g_free(debug);
g_printerr("Error: %s\n", error->message);
g_error_free(error);
g_main_loop_quit(loop);
break;
}
default:
break;
}
return TRUE;
}
int
main(int argc, char *argv[])
{
GMainLoop *loop;
GstElement *pipeline, *source, *decoder, *sink;
GstBus *bus;
guint bus_watch_id;
/* Initialisation */
gst_init(&argc, &argv);
loop = g_main_loop_new(NULL, FALSE);
/* Check input arguments */
if (argc != 2) {
g_printerr("Usage: %s <file.raw>\n", argv[0]);
return -1;
}
/* Create gstreamer elements */
pipeline = gst_pipeline_new("test");
source = gst_element_factory_make("filesrc", "file-source");
decoder = gst_element_factory_make("pocketsphinx", "asr");
sink = gst_element_factory_make("fakesink", "output");
if (!pipeline || !source || !decoder || !sink) {
g_printerr("One element could not be created. Exiting.\n");
return -1;
}
/* Set up the pipeline */
/* we set the input filename to the source element */
g_object_set(G_OBJECT(source), "location", argv[1], NULL);
g_object_set(G_OBJECT(decoder), "lmctl", "test.lmctl", NULL);
g_object_set(G_OBJECT(decoder), "lmname", "tidigits", NULL);
g_object_set(G_OBJECT(decoder), "configured", TRUE, NULL);
/* we add a message handler */
bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline));
bus_watch_id = gst_bus_add_watch(bus, bus_call, loop);
gst_object_unref(bus);
/* we add all elements into the pipeline */
gst_bin_add_many(GST_BIN(pipeline), source, decoder, sink, NULL);
/* we link the elements together */
gst_element_link_many(source, decoder, sink, NULL);
gst_element_set_state(pipeline, GST_STATE_PLAYING);
/* Iterate */
g_print("Running...\n");
g_main_loop_run(loop);
/* Out of the main loop, clean up nicely */
g_print("Returned, stopping playback\n");
gst_element_set_state(pipeline, GST_STATE_NULL);
g_print("Deleting pipeline\n");
gst_object_unref(GST_OBJECT(pipeline));
g_source_remove(bus_watch_id);
g_main_loop_unref(loop);
return 0;
}

View File

@ -0,0 +1,97 @@
#!/usr/bin/env python
# Copyright (c) 2008 Carnegie Mellon University.
#
# You may modify and redistribute this file under the same terms as
# the CMU Sphinx system. See
# http://cmusphinx.sourceforge.net/html/LICENSE for more information.
import pygtk
pygtk.require('2.0')
import gtk
import gobject
import pygst
pygst.require('1.0')
gobject.threads_init()
import gst
class DemoApp(object):
"""GStreamer/PocketSphinx Demo Application"""
def __init__(self):
"""Initialize a DemoApp object"""
self.init_gui()
self.init_gst()
def init_gui(self):
"""Initialize the GUI components"""
self.window = gtk.Window()
self.window.connect("delete-event", gtk.main_quit)
self.window.set_default_size(400,200)
self.window.set_border_width(10)
vbox = gtk.VBox()
self.textbuf = gtk.TextBuffer()
self.text = gtk.TextView(self.textbuf)
self.text.set_wrap_mode(gtk.WRAP_WORD)
vbox.pack_start(self.text)
self.button = gtk.ToggleButton("Speak")
self.button.connect('clicked', self.button_clicked)
vbox.pack_start(self.button, False, False, 5)
self.window.add(vbox)
self.window.show_all()
def init_gst(self):
"""Initialize the speech components"""
self.pipeline = gst.parse_launch('gconfaudiosrc ! audioconvert ! audioresample '
+ '! pocketsphinx configured=true ! fakesink')
bus = self.pipeline.get_bus()
bus.add_signal_watch()
bus.connect('message::element', self.element_message)
self.pipeline.set_state(gst.STATE_PAUSED)
def element_message(self, bus, msg):
"""Receive element messages from the bus."""
msgtype = msg.structure.get_name()
if msgtype != 'pocketsphinx':
return
if msg.structure['final']:
self.final_result(msg.structure['hypothesis'], msg.structure['confidence'])
self.pipeline.set_state(gst.STATE_PAUSED)
self.button.set_active(False)
elif msgtype == 'result':
self.partial_result(msg.structure['hypothesis'])
def partial_result(self, hyp):
"""Delete any previous selection, insert text and select it."""
# All this stuff appears as one single action
self.textbuf.begin_user_action()
self.textbuf.delete_selection(True, self.text.get_editable())
self.textbuf.insert_at_cursor(hyp)
ins = self.textbuf.get_insert()
iter = self.textbuf.get_iter_at_mark(ins)
iter.backward_chars(len(hyp))
self.textbuf.move_mark(ins, iter)
self.textbuf.end_user_action()
def final_result(self, hyp, confidence):
"""Insert the final result."""
# All this stuff appears as one single action
self.textbuf.begin_user_action()
self.textbuf.delete_selection(True, self.text.get_editable())
self.textbuf.insert_at_cursor(hyp)
self.textbuf.end_user_action()
def button_clicked(self, button):
"""Handle button presses."""
if button.get_active():
button.set_label("Stop")
self.pipeline.set_state(gst.STATE_PLAYING)
else:
button.set_label("Speak")
vader = self.pipeline.get_by_name('vad')
vader.set_property('silent', True)
app = DemoApp()
gtk.main()

View File

@ -0,0 +1,75 @@
ARCH = `uname -m | sed s/i.86/i386/`_`uname -s | tr A-Z a-z`
lib_LTLIBRARIES = libpocketsphinx.la
libpocketsphinx_la_LDFLAGS = -version-info 3:0:0 -lm
libpocketsphinx_la_SOURCES = \
acmod.c \
bin_mdef.c \
blkarray_list.c \
dict.c \
dict2pid.c \
fsg_history.c \
fsg_lextree.c \
fsg_search.c \
allphone_search.c \
kws_search.c \
kws_detections.c \
hmm.c \
mdef.c \
ms_gauden.c \
ms_mgau.c \
ms_senone.c \
ngram_search.c \
ngram_search_fwdtree.c \
ngram_search_fwdflat.c \
phone_loop_search.c \
ps_alignment.c \
ps_lattice.c \
ps_mllr.c \
ptm_mgau.c \
s2_semi_mgau.c \
state_align_search.c \
tmat.c \
vector.c \
pocketsphinx.c
noinst_HEADERS = \
pocketsphinx_internal.h \
acmod.h \
ngram_search.h \
bin_mdef.h \
blkarray_list.h \
dict.h \
dict2pid.h \
fsg_history.h \
fsg_lextree.h \
fsg_search_internal.h \
allphone_search.h \
kws_search.h \
kws_detections.h \
hmm.h \
mdef.h \
ms_gauden.h \
ms_mgau.h \
ms_senone.h \
ngram_search.h \
ngram_search_fwdtree.h \
ngram_search_fwdflat.h \
phone_loop_search.h \
ps_alignment.h \
ps_lattice_internal.h \
ptm_mgau.h \
s2_semi_mgau.h \
s3types.h \
state_align_search.h \
tied_mgau_common.h \
tmat.h \
vector.h
AM_CFLAGS =\
-I$(top_srcdir)/include \
-I$(top_builddir)/include \
-DMODELDIR=\"${prefix}/share/pocketsphinx/model\"

View File

@ -0,0 +1,766 @@
# Makefile.in generated by automake 1.13.4 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2013 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.
@SET_MAKE@
VPATH = @srcdir@
am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
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)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
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 = @build@
host_triplet = @host@
subdir = src/libpocketsphinx
DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
$(top_srcdir)/depcomp $(noinst_HEADERS)
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_pkg_swig.m4 \
$(top_srcdir)/m4/ax_python_devel.m4 \
$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
$(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/pkg.m4 \
$(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
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)$(libdir)"
LTLIBRARIES = $(lib_LTLIBRARIES)
libpocketsphinx_la_LIBADD =
am_libpocketsphinx_la_OBJECTS = acmod.lo bin_mdef.lo blkarray_list.lo \
dict.lo dict2pid.lo fsg_history.lo fsg_lextree.lo \
fsg_search.lo allphone_search.lo kws_search.lo \
kws_detections.lo hmm.lo mdef.lo ms_gauden.lo ms_mgau.lo \
ms_senone.lo ngram_search.lo ngram_search_fwdtree.lo \
ngram_search_fwdflat.lo phone_loop_search.lo ps_alignment.lo \
ps_lattice.lo ps_mllr.lo ptm_mgau.lo s2_semi_mgau.lo \
state_align_search.lo tmat.lo vector.lo pocketsphinx.lo
libpocketsphinx_la_OBJECTS = $(am_libpocketsphinx_la_OBJECTS)
AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
am__v_lt_0 = --silent
am__v_lt_1 =
libpocketsphinx_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
$(AM_CFLAGS) $(CFLAGS) $(libpocketsphinx_la_LDFLAGS) \
$(LDFLAGS) -o $@
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false
am__v_P_1 = :
AM_V_GEN = $(am__v_GEN_@AM_V@)
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
am__v_GEN_0 = @echo " GEN " $@;
am__v_GEN_1 =
AM_V_at = $(am__v_at_@AM_V@)
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
am__v_at_0 = @
am__v_at_1 =
DEFAULT_INCLUDES = -I.@am__isrc@
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_@AM_V@)
am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
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_@AM_V@)
am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
am__v_CCLD_0 = @echo " CCLD " $@;
am__v_CCLD_1 =
SOURCES = $(libpocketsphinx_la_SOURCES)
DIST_SOURCES = $(libpocketsphinx_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
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GREP = @GREP@
GST_CFLAGS = @GST_CFLAGS@
GST_LIBS = @GST_LIBS@
GST_MAJORMINOR = @GST_MAJORMINOR@
GST_PLUGIN_LDFLAGS = @GST_PLUGIN_LDFLAGS@
GStreamer_CFLAGS = @GStreamer_CFLAGS@
GStreamer_LIBS = @GStreamer_LIBS@
HAVE_DOXYGEN = @HAVE_DOXYGEN@
HAVE_PKGCONFIG = @HAVE_PKGCONFIG@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LD = @LD@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PKG_CONFIG = @PKG_CONFIG@
PYTHON = @PYTHON@
PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@
PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@
PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@
PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
PYTHON_PLATFORM = @PYTHON_PLATFORM@
PYTHON_PREFIX = @PYTHON_PREFIX@
PYTHON_SITE_PKG = @PYTHON_SITE_PKG@
PYTHON_VERSION = @PYTHON_VERSION@
RANLIB = @RANLIB@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
SPHINXBASE_CFLAGS = @SPHINXBASE_CFLAGS@
SPHINXBASE_LIBS = @SPHINXBASE_LIBS@
SPHINXBASE_SWIG = @SPHINXBASE_SWIG@
STRIP = @STRIP@
SWIG = @SWIG@
SWIG_LIB = @SWIG_LIB@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
pkgpyexecdir = @pkgpyexecdir@
pkgpythondir = @pkgpythondir@
plugindir = @plugindir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
pyexecdir = @pyexecdir@
pythondir = @pythondir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
ARCH = `uname -m | sed s/i.86/i386/`_`uname -s | tr A-Z a-z`
lib_LTLIBRARIES = libpocketsphinx.la
libpocketsphinx_la_LDFLAGS = -version-info 3:0:0 -lm
libpocketsphinx_la_SOURCES = \
acmod.c \
bin_mdef.c \
blkarray_list.c \
dict.c \
dict2pid.c \
fsg_history.c \
fsg_lextree.c \
fsg_search.c \
allphone_search.c \
kws_search.c \
kws_detections.c \
hmm.c \
mdef.c \
ms_gauden.c \
ms_mgau.c \
ms_senone.c \
ngram_search.c \
ngram_search_fwdtree.c \
ngram_search_fwdflat.c \
phone_loop_search.c \
ps_alignment.c \
ps_lattice.c \
ps_mllr.c \
ptm_mgau.c \
s2_semi_mgau.c \
state_align_search.c \
tmat.c \
vector.c \
pocketsphinx.c
noinst_HEADERS = \
pocketsphinx_internal.h \
acmod.h \
ngram_search.h \
bin_mdef.h \
blkarray_list.h \
dict.h \
dict2pid.h \
fsg_history.h \
fsg_lextree.h \
fsg_search_internal.h \
allphone_search.h \
kws_search.h \
kws_detections.h \
hmm.h \
mdef.h \
ms_gauden.h \
ms_mgau.h \
ms_senone.h \
ngram_search.h \
ngram_search_fwdtree.h \
ngram_search_fwdflat.h \
phone_loop_search.h \
ps_alignment.h \
ps_lattice_internal.h \
ptm_mgau.h \
s2_semi_mgau.h \
s3types.h \
state_align_search.h \
tied_mgau_common.h \
tmat.h \
vector.h
AM_CFLAGS = \
-I$(top_srcdir)/include \
-I$(top_builddir)/include \
-DMODELDIR=\"${prefix}/share/pocketsphinx/model\"
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) --foreign src/libpocketsphinx/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign src/libpocketsphinx/Makefile
.PRECIOUS: 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-libLTLIBRARIES: $(lib_LTLIBRARIES)
@$(NORMAL_INSTALL)
@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || 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)$(libdir)'"; \
$(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \
echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \
$(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
}
uninstall-libLTLIBRARIES:
@$(NORMAL_UNINSTALL)
@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
for p in $$list; do \
$(am__strip_dir) \
echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \
$(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \
done
clean-libLTLIBRARIES:
-test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
@list='$(lib_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}; \
}
libpocketsphinx.la: $(libpocketsphinx_la_OBJECTS) $(libpocketsphinx_la_DEPENDENCIES) $(EXTRA_libpocketsphinx_la_DEPENDENCIES)
$(AM_V_CCLD)$(libpocketsphinx_la_LINK) -rpath $(libdir) $(libpocketsphinx_la_OBJECTS) $(libpocketsphinx_la_LIBADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/acmod.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/allphone_search.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bin_mdef.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/blkarray_list.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dict.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dict2pid.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fsg_history.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fsg_lextree.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fsg_search.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hmm.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kws_detections.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kws_search.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mdef.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ms_gauden.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ms_mgau.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ms_senone.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ngram_search.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ngram_search_fwdflat.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ngram_search_fwdtree.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/phone_loop_search.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pocketsphinx.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ps_alignment.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ps_lattice.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ps_mllr.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ptm_mgau.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/s2_semi_mgau.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/state_align_search.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tmat.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vector.Plo@am__quote@
.c.o:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $<
.c.obj:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'`
.c.lo:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
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)$(libdir)"; 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-libLTLIBRARIES clean-libtool \
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-dvi: install-dvi-am
install-dvi-am:
install-exec-am: install-libLTLIBRARIES
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-libLTLIBRARIES
.MAKE: install-am install-strip
.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
clean-libLTLIBRARIES clean-libtool 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-libLTLIBRARIES install-man install-pdf \
install-pdf-am 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-libLTLIBRARIES
# 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:

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,466 @@
/* -*- c-basic-offset: 4; indent-tabs-mode: nil -*- */
/* ====================================================================
* Copyright (c) 2008 Carnegie Mellon University. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. 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 work was supported in part by funding from the Defense Advanced
* Research Projects Agency and the National Science Foundation of the
* United States of America, and the CMU Sphinx Speech Consortium.
*
* THIS SOFTWARE IS PROVIDED BY CARNEGIE MELLON UNIVERSITY ``AS IS'' AND
* ANY EXPRESSED 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 CARNEGIE MELLON UNIVERSITY
* NOR ITS EMPLOYEES 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.
*
* ====================================================================
*
*/
/**
* @file acmod.h Acoustic model structures for PocketSphinx.
* @author David Huggins-Daines <dhuggins@cs.cmu.edu>
*/
#ifndef __ACMOD_H__
#define __ACMOD_H__
/* System headers. */
#include <stdio.h>
/* SphinxBase headers. */
#include <sphinxbase/cmd_ln.h>
#include <sphinxbase/logmath.h>
#include <sphinxbase/fe.h>
#include <sphinxbase/feat.h>
#include <sphinxbase/bitvec.h>
#include <sphinxbase/err.h>
#include <sphinxbase/prim_type.h>
/* Local headers. */
#include "ps_mllr.h"
#include "bin_mdef.h"
#include "tmat.h"
#include "hmm.h"
/**
* States in utterance processing.
*/
typedef enum acmod_state_e {
ACMOD_IDLE, /**< Not in an utterance. */
ACMOD_STARTED, /**< Utterance started, no data yet. */
ACMOD_PROCESSING, /**< Utterance in progress. */
ACMOD_ENDED /**< Utterance ended, still buffering. */
} acmod_state_t;
/**
* Dummy senone score value for unintentionally active states.
*/
#define SENSCR_DUMMY 0x7fff
/**
* Feature space linear transform structure.
*/
struct ps_mllr_s {
int refcnt; /**< Reference count. */
int n_class; /**< Number of MLLR classes. */
int n_feat; /**< Number of feature streams. */
int *veclen; /**< Length of input vectors for each stream. */
float32 ****A; /**< Rotation part of mean transformations. */
float32 ***b; /**< Bias part of mean transformations. */
float32 ***h; /**< Diagonal transformation of variances. */
int32 *cb2mllr; /**< Mapping from codebooks to transformations. */
};
/**
* Acoustic model parameter structure.
*/
typedef struct ps_mgau_s ps_mgau_t;
typedef struct ps_mgaufuncs_s {
char const *name;
int (*frame_eval)(ps_mgau_t *mgau,
int16 *senscr,
uint8 *senone_active,
int32 n_senone_active,
mfcc_t ** feat,
int32 frame,
int32 compallsen);
int (*transform)(ps_mgau_t *mgau,
ps_mllr_t *mllr);
void (*free)(ps_mgau_t *mgau);
} ps_mgaufuncs_t;
struct ps_mgau_s {
ps_mgaufuncs_t *vt; /**< vtable of mgau functions. */
int frame_idx; /**< frame counter. */
};
#define ps_mgau_base(mg) ((ps_mgau_t *)(mg))
#define ps_mgau_frame_eval(mg,senscr,senone_active,n_senone_active,feat,frame,compallsen) \
(*ps_mgau_base(mg)->vt->frame_eval) \
(mg, senscr, senone_active, n_senone_active, feat, frame, compallsen)
#define ps_mgau_transform(mg, mllr) \
(*ps_mgau_base(mg)->vt->transform)(mg, mllr)
#define ps_mgau_free(mg) \
(*ps_mgau_base(mg)->vt->free)(mg)
/**
* Acoustic model structure.
*
* This object encapsulates all stages of acoustic processing, from
* raw audio input to acoustic score output. The reason for grouping
* all of these modules together is that they all have to "agree" in
* their parameterizations, and the configuration of the acoustic and
* dynamic feature computation is completely dependent on the
* parameters used to build the original acoustic model (which should
* by now always be specified in a feat.params file).
*
* Because there is not a one-to-one correspondence from blocks of
* input audio or frames of input features to frames of acoustic
* scores (due to dynamic feature calculation), results may not be
* immediately available after input, and the output results will not
* correspond to the last piece of data input.
*
* TODO: In addition, this structure serves the purpose of queueing
* frames of features (and potentially also scores in the future) for
* asynchronous passes of recognition operating in parallel.
*/
struct acmod_s {
/* Global objects, not retained. */
cmd_ln_t *config; /**< Configuration. */
logmath_t *lmath; /**< Log-math computation. */
glist_t strings; /**< Temporary acoustic model filenames. */
/* Feature computation: */
fe_t *fe; /**< Acoustic feature computation. */
feat_t *fcb; /**< Dynamic feature computation. */
/* Model parameters: */
bin_mdef_t *mdef; /**< Model definition. */
tmat_t *tmat; /**< Transition matrices. */
ps_mgau_t *mgau; /**< Model parameters. */
ps_mllr_t *mllr; /**< Speaker transformation. */
/* Senone scoring: */
int16 *senone_scores; /**< GMM scores for current frame. */
bitvec_t *senone_active_vec; /**< Active GMMs in current frame. */
uint8 *senone_active; /**< Array of deltas to active GMMs. */
int senscr_frame; /**< Frame index for senone_scores. */
int n_senone_active; /**< Number of active GMMs. */
int log_zero; /**< Zero log-probability value. */
/* Utterance processing: */
mfcc_t **mfc_buf; /**< Temporary buffer of acoustic features. */
mfcc_t ***feat_buf; /**< Temporary buffer of dynamic features. */
FILE *rawfh; /**< File for writing raw audio data. */
FILE *mfcfh; /**< File for writing acoustic feature data. */
FILE *senfh; /**< File for writing senone score data. */
FILE *insenfh; /**< Input senone score file. */
long *framepos; /**< File positions of recent frames in senone file. */
/* Rawdata collected during decoding */
int16 *rawdata;
int32 rawdata_size;
int32 rawdata_pos;
/* A whole bunch of flags and counters: */
uint8 state; /**< State of utterance processing. */
uint8 compallsen; /**< Compute all senones? */
uint8 grow_feat; /**< Whether to grow feat_buf. */
uint8 insen_swap; /**< Whether to swap input senone score. */
frame_idx_t utt_start_frame; /**< Index of the utterance start in the stream, all timings are relative to that. */
frame_idx_t output_frame; /**< Index of next frame of dynamic features. */
frame_idx_t n_mfc_alloc; /**< Number of frames allocated in mfc_buf */
frame_idx_t n_mfc_frame; /**< Number of frames active in mfc_buf */
frame_idx_t mfc_outidx; /**< Start of active frames in mfc_buf */
frame_idx_t n_feat_alloc; /**< Number of frames allocated in feat_buf */
frame_idx_t n_feat_frame; /**< Number of frames active in feat_buf */
frame_idx_t feat_outidx; /**< Start of active frames in feat_buf */
};
typedef struct acmod_s acmod_t;
/**
* Initialize an acoustic model.
*
* @param config a command-line object containing parameters. This
* pointer is not retained by this object.
* @param lmath global log-math parameters.
* @param fe a previously-initialized acoustic feature module to use,
* or NULL to create one automatically. If this is supplied
* and its parameters do not match those in the acoustic
* model, this function will fail. This pointer is not retained.
* @param fe a previously-initialized dynamic feature module to use,
* or NULL to create one automatically. If this is supplied
* and its parameters do not match those in the acoustic
* model, this function will fail. This pointer is not retained.
* @return a newly initialized acmod_t, or NULL on failure.
*/
acmod_t *acmod_init(cmd_ln_t *config, logmath_t *lmath, fe_t *fe, feat_t *fcb);
/**
* Adapt acoustic model using a linear transform.
*
* @param mllr The new transform to use, or NULL to update the existing
* transform. The decoder retains ownership of this pointer,
* so you should not attempt to free it manually. Use
* ps_mllr_retain() if you wish to reuse it
* elsewhere.
* @return The updated transform object for this decoder, or
* NULL on failure.
*/
ps_mllr_t *acmod_update_mllr(acmod_t *acmod, ps_mllr_t *mllr);
/**
* Start logging senone scores to a filehandle.
*
* @param acmod Acoustic model object.
* @param logfh Filehandle to log to.
* @return 0 for success, <0 on error.
*/
int acmod_set_senfh(acmod_t *acmod, FILE *senfh);
/**
* Start logging MFCCs to a filehandle.
*
* @param acmod Acoustic model object.
* @param logfh Filehandle to log to.
* @return 0 for success, <0 on error.
*/
int acmod_set_mfcfh(acmod_t *acmod, FILE *logfh);
/**
* Start logging raw audio to a filehandle.
*
* @param acmod Acoustic model object.
* @param logfh Filehandle to log to.
* @return 0 for success, <0 on error.
*/
int acmod_set_rawfh(acmod_t *acmod, FILE *logfh);
/**
* Finalize an acoustic model.
*/
void acmod_free(acmod_t *acmod);
/**
* Mark the start of an utterance.
*/
int acmod_start_utt(acmod_t *acmod);
/**
* Mark the end of an utterance.
*/
int acmod_end_utt(acmod_t *acmod);
/**
* Rewind the current utterance, allowing it to be rescored.
*
* After calling this function, the internal frame index is reset, and
* acmod_score() will return scores starting at the first frame of the
* current utterance. Currently, acmod_set_grow() must have been
* called to enable growing the feature buffer in order for this to
* work. In the future, senone scores may be cached instead.
*
* @return 0 for success, <0 for failure (if the utterance can't be
* rewound due to no feature or score data available)
*/
int acmod_rewind(acmod_t *acmod);
/**
* Advance the frame index.
*
* This function moves to the next frame of input data. Subsequent
* calls to acmod_score() will return scores for that frame, until the
* next call to acmod_advance().
*
* @return New frame index.
*/
int acmod_advance(acmod_t *acmod);
/**
* Set memory allocation policy for utterance processing.
*
* @param grow_feat If non-zero, the internal dynamic feature buffer
* will expand as necessary to encompass any amount of data fed to the
* model.
* @return previous allocation policy.
*/
int acmod_set_grow(acmod_t *acmod, int grow_feat);
/**
* TODO: Set queue length for utterance processing.
*
* This function allows multiple concurrent passes of search to
* operate on different parts of the utterance.
*/
/**
* Feed raw audio data to the acoustic model for scoring.
*
* @param inout_raw In: Pointer to buffer of raw samples
* Out: Pointer to next sample to be read
* @param inout_n_samps In: Number of samples available
* Out: Number of samples remaining
* @param full_utt If non-zero, this block represents a full
* utterance and should be processed as such.
* @return Number of frames of data processed.
*/
int acmod_process_raw(acmod_t *acmod,
int16 const **inout_raw,
size_t *inout_n_samps,
int full_utt);
/**
* Feed acoustic feature data into the acoustic model for scoring.
*
* @param inout_cep In: Pointer to buffer of features
* Out: Pointer to next frame to be read
* @param inout_n_frames In: Number of frames available
* Out: Number of frames remaining
* @param full_utt If non-zero, this block represents a full
* utterance and should be processed as such.
* @return Number of frames of data processed.
*/
int acmod_process_cep(acmod_t *acmod,
mfcc_t ***inout_cep,
int *inout_n_frames,
int full_utt);
/**
* Feed dynamic feature data into the acoustic model for scoring.
*
* Unlike acmod_process_raw() and acmod_process_cep(), this function
* accepts a single frame at a time. This is because there is no need
* to do buffering when using dynamic features as input. However, if
* the dynamic feature buffer is full, this function will fail, so you
* should either always check the return value, or always pair a call
* to it with a call to acmod_score().
*
* @param feat Pointer to one frame of dynamic features.
* @return Number of frames processed (either 0 or 1).
*/
int acmod_process_feat(acmod_t *acmod,
mfcc_t **feat);
/**
* Set up a senone score dump file for input.
*
* @param insenfh File handle of dump file
* @return 0 for success, <0 for failure
*/
int acmod_set_insenfh(acmod_t *acmod, FILE *insenfh);
/**
* Read one frame of scores from senone score dump file.
*
* @return Number of frames read or <0 on error.
*/
int acmod_read_scores(acmod_t *acmod);
/**
* Get a frame of dynamic feature data.
*
* @param inout_frame_idx Input: frame index to get, or NULL
* to obtain features for the most recent frame.
* Output: frame index corresponding to this
* set of features.
* @return Feature array, or NULL if requested frame is not available.
*/
mfcc_t **acmod_get_frame(acmod_t *acmod, int *inout_frame_idx);
/**
* Score one frame of data.
*
* @param inout_frame_idx Input: frame index to score, or NULL
* to obtain scores for the most recent frame.
* Output: frame index corresponding to this
* set of scores.
* @return Array of senone scores for this frame, or NULL if no frame
* is available for scoring (such as if a frame index is
* requested that is not yet or no longer available). The
* data pointed to persists only until the next call to
* acmod_score() or acmod_advance().
*/
int16 const *acmod_score(acmod_t *acmod,
int *inout_frame_idx);
/**
* Write senone dump file header.
*/
int acmod_write_senfh_header(acmod_t *acmod, FILE *logfh);
/**
* Write a frame of senone scores to a dump file.
*/
int acmod_write_scores(acmod_t *acmod, int n_active, uint8 const *active,
int16 const *senscr, FILE *senfh);
/**
* Get best score and senone index for current frame.
*/
int acmod_best_score(acmod_t *acmod, int *out_best_senid);
/**
* Clear set of active senones.
*/
void acmod_clear_active(acmod_t *acmod);
/**
* Activate senones associated with an HMM.
*/
void acmod_activate_hmm(acmod_t *acmod, hmm_t *hmm);
/**
* Activate a single senone.
*/
#define acmod_activate_sen(acmod, sen) bitvec_set((acmod)->senone_active_vec, sen)
/**
* Build active list from
*/
int32 acmod_flags2list(acmod_t *acmod);
/**
* Get the offset of the utterance start of the current stream, helpful for stream-wide timing.
*/
int32 acmod_stream_offset(acmod_t *acmod);
/**
* Reset the current stream
*/
void acmod_start_stream(acmod_t *acmod);
/**
* Sets the limit of the raw audio data to store
*/
void acmod_set_rawdata_size(acmod_t *acmod, int32 size);
/**
* Retrieves the raw data collected during utterance decoding
*/
void acmod_get_rawdata(acmod_t *acmod, int16 **buffer, int32 *size);
#endif /* __ACMOD_H__ */

View File

@ -0,0 +1,915 @@
/* ====================================================================
* Copyright (c) 2014 Carnegie Mellon University. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. 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 CARNEGIE MELLON UNIVERSITY ``AS IS'' AND
* ANY EXPRESSED 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 CARNEGIE MELLON UNIVERSITY
* NOR ITS EMPLOYEES 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.
*
* ====================================================================
*
*/
/*
* allphone_search.c -- Search for phonetic decoding.
*/
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <sphinxbase/err.h>
#include <sphinxbase/ckd_alloc.h>
#include <sphinxbase/strfuncs.h>
#include <sphinxbase/pio.h>
#include <sphinxbase/cmd_ln.h>
#include "pocketsphinx_internal.h"
#include "allphone_search.h"
static ps_lattice_t *
allphone_search_lattice(ps_search_t * search)
{
//cap
return NULL;
}
static int
allphone_search_prob(ps_search_t * search)
{
return 0;
}
static void
allphone_backtrace(allphone_search_t * allphs, int32 f);
static void
allphone_search_seg_free(ps_seg_t * seg)
{
ckd_free(seg);
}
static void
allphone_search_fill_iter(ps_seg_t *seg, phseg_t *phseg)
{
seg->sf = phseg->sf;
seg->ef = phseg->ef;
seg->ascr = phseg->score;
seg->lscr = phseg->tscore;
seg->word = bin_mdef_ciphone_str(ps_search_acmod(seg->search)->mdef, phseg->ci);
}
static ps_seg_t *
allphone_search_seg_next(ps_seg_t * seg)
{
phseg_iter_t *itor = (phseg_iter_t *) seg;
phseg_t *phseg;
itor->seg = itor->seg->next;
if (itor->seg == NULL) {
allphone_search_seg_free(seg);
return NULL;
}
phseg = gnode_ptr(itor->seg);
allphone_search_fill_iter(seg, phseg);
return seg;
}
static ps_segfuncs_t fsg_segfuncs = {
/* seg_next */ allphone_search_seg_next,
/* seg_free */ allphone_search_seg_free
};
static ps_seg_t *
allphone_search_seg_iter(ps_search_t * search, int32 * out_score)
{
allphone_search_t *allphs = (allphone_search_t *) search;
phseg_iter_t *iter;
allphone_backtrace(allphs, allphs->frame - 1);
if (allphs->segments == NULL)
return NULL;
iter = ckd_calloc(1, sizeof(phseg_iter_t));
iter->base.vt = &fsg_segfuncs;
iter->base.search = search;
iter->seg = allphs->segments;
allphone_search_fill_iter((ps_seg_t *)iter, gnode_ptr(iter->seg));
return (ps_seg_t *) iter;
}
static ps_searchfuncs_t allphone_funcs = {
/* start: */ allphone_search_start,
/* step: */ allphone_search_step,
/* finish: */ allphone_search_finish,
/* reinit: */ allphone_search_reinit,
/* free: */ allphone_search_free,
/* lattice: */ allphone_search_lattice,
/* hyp: */ allphone_search_hyp,
/* prob: */ allphone_search_prob,
/* seg_iter: */ allphone_search_seg_iter,
};
/**
* Find PHMM node with same senone sequence and tmat id as the given triphone.
* Return ptr to PHMM node if found, NULL otherwise.
*/
static phmm_t *
phmm_lookup(allphone_search_t * allphs, s3pid_t pid)
{
phmm_t *p;
bin_mdef_t *mdef;
phmm_t **ci_phmm;
mdef = ((ps_search_t *) allphs)->acmod->mdef;
ci_phmm = allphs->ci_phmm;
for (p = ci_phmm[bin_mdef_pid2ci(mdef, pid)]; p; p = p->next) {
if (mdef_pid2tmatid(mdef, p->pid) == mdef_pid2tmatid(mdef, pid))
if (mdef_pid2ssid(mdef, p->pid) == mdef_pid2ssid(mdef, pid))
return p;
}
//not found
return NULL;
}
static int32
phmm_link(allphone_search_t * allphs)
{
s3cipid_t ci, rc;
phmm_t *p, *p2;
int32 *rclist;
int32 i, n_link;
plink_t *l;
bin_mdef_t *mdef;
phmm_t **ci_phmm;
mdef = ((ps_search_t *) allphs)->acmod->mdef;
ci_phmm = allphs->ci_phmm;
rclist = (int32 *) ckd_calloc(mdef->n_ciphone + 1, sizeof(int32));
/* Create successor links between PHMM nodes */
n_link = 0;
for (ci = 0; ci < mdef->n_ciphone; ci++) {
for (p = ci_phmm[ci]; p; p = p->next) {
/* Build rclist for p */
i = 0;
for (rc = 0; rc < mdef->n_ciphone; rc++) {
if (bitvec_is_set(p->rc, rc))
rclist[i++] = rc;
}
rclist[i] = BAD_S3CIPID;
/* For each rc in rclist, transition to PHMMs for rc if left context = ci */
for (i = 0; IS_S3CIPID(rclist[i]); i++) {
for (p2 = ci_phmm[rclist[i]]; p2; p2 = p2->next) {
if (bitvec_is_set(p2->lc, ci)) {
/* transition from p to p2 */
l = (plink_t *) ckd_calloc(1, sizeof(*l));
l->phmm = p2;
l->next = p->succlist;
p->succlist = l;
n_link++;
}
}
}
}
}
ckd_free(rclist);
return n_link;
}
/**
* Build net from phone HMMs
*/
static int
phmm_build(allphone_search_t * allphs)
{
phmm_t *p, **pid2phmm;
bin_mdef_t *mdef;
int32 lrc_size;
uint32 *lc, *rc;
s3pid_t pid;
s3cipid_t ci;
s3cipid_t *filler;
int n_phmm, n_link;
int i, nphone;
mdef = ((ps_search_t *) allphs)->acmod->mdef;
allphs->ci_phmm =
(phmm_t **) ckd_calloc(bin_mdef_n_ciphone(mdef), sizeof(phmm_t *));
pid2phmm =
(phmm_t **) ckd_calloc(bin_mdef_n_phone(mdef), sizeof(phmm_t *));
/* For each unique ciphone/triphone entry in mdef, create a PHMM node */
n_phmm = 0;
nphone = allphs->ci_only ? bin_mdef_n_ciphone(mdef) : bin_mdef_n_phone(mdef);
E_INFO("Building PHMM net of %d phones\n", nphone);
for (pid = 0; pid < nphone; pid++) {
if ((p = phmm_lookup(allphs, pid)) == NULL) {
//not found, should be created
p = (phmm_t *) ckd_calloc(1, sizeof(*p));
hmm_init(allphs->hmmctx, &(p->hmm), FALSE,
mdef_pid2ssid(mdef, pid), mdef->phone[pid].tmat);
p->pid = pid;
p->ci = bin_mdef_pid2ci(mdef, pid);
p->succlist = NULL;
p->next = allphs->ci_phmm[p->ci];
allphs->ci_phmm[p->ci] = p;
n_phmm++;
}
pid2phmm[pid] = p;
}
/* Fill out bitvecs of each PHMM node, alloc continuous memory chunk for context bitvectors */
lrc_size = bitvec_size(bin_mdef_n_ciphone(mdef));
lc = ckd_calloc(n_phmm * 2 * lrc_size, sizeof(bitvec_t));
rc = lc + (n_phmm * lrc_size);
for (ci = 0; ci < mdef->n_ciphone; ci++) {
for (p = allphs->ci_phmm[ci]; p; p = p->next) {
p->lc = lc;
lc += lrc_size;
p->rc = rc;
rc += lrc_size;
}
}
/* Fill out lc and rc bitmaps (remember to map all fillers to each other!!) */
filler =
(s3cipid_t *) ckd_calloc(bin_mdef_n_ciphone(mdef) + 1,
sizeof(s3cipid_t));
/* Connect fillers */
i = 0;
for (ci = 0; ci < bin_mdef_n_ciphone(mdef); ci++) {
p = pid2phmm[ci];
bitvec_set_all(p->lc, bin_mdef_n_ciphone(mdef));
bitvec_set_all(p->rc, bin_mdef_n_ciphone(mdef));
if (mdef->phone[ci].info.ci.filler) {
filler[i++] = ci;
}
}
filler[i] = BAD_S3CIPID;
/* Loop over cdphones only if ci_only is not set */
for (pid = bin_mdef_n_ciphone(mdef); pid < nphone;
pid++) {
p = pid2phmm[pid];
if (mdef->phone[mdef->phone[pid].info.cd.ctx[1]].info.ci.filler) {
for (i = 0; IS_S3CIPID(filler[i]); i++)
bitvec_set(p->lc, filler[i]);
}
else
bitvec_set(p->lc, mdef->phone[pid].info.cd.ctx[1]);
if (mdef->phone[mdef->phone[pid].info.cd.ctx[2]].info.ci.filler) {
for (i = 0; IS_S3CIPID(filler[i]); i++)
bitvec_set(p->rc, filler[i]);
}
else
bitvec_set(p->rc, mdef->phone[pid].info.cd.ctx[2]);
}
ckd_free(pid2phmm);
ckd_free(filler);
/* Create links between PHMM nodes */
n_link = phmm_link(allphs);
E_INFO("%d nodes, %d links\n", n_phmm, n_link);
return 0;
}
static void
phmm_free(allphone_search_t * allphs)
{
s3cipid_t ci;
bin_mdef_t *mdef;
if (!allphs->ci_phmm)
//nothing to free
return;
ckd_free(allphs->ci_phmm[0]->lc);
mdef = ((ps_search_t *) allphs)->acmod->mdef;
for (ci = 0; ci < mdef_n_ciphone(mdef); ++ci) {
phmm_t *p, *next;
for (p = allphs->ci_phmm[ci]; p; p = next) {
plink_t *l, *lnext;
next = p->next;
for (l = p->succlist; l; l = lnext) {
lnext = l->next;
ckd_free(l);
}
hmm_deinit(&(p->hmm));
ckd_free(p);
}
}
ckd_free(allphs->ci_phmm);
}
/** Evaluate active PHMMs */
static int32
phmm_eval_all(allphone_search_t * allphs, const int16 * senscr)
{
s3cipid_t ci;
phmm_t *p;
int32 best;
bin_mdef_t *mdef;
phmm_t **ci_phmm;
mdef = ((ps_search_t *) allphs)->acmod->mdef;
ci_phmm = allphs->ci_phmm;
best = WORST_SCORE;
hmm_context_set_senscore(allphs->hmmctx, senscr);
for (ci = 0; ci < mdef->n_ciphone; ci++) {
for (p = ci_phmm[(unsigned) ci]; p; p = p->next) {
if (hmm_frame(&(p->hmm)) == allphs->frame) {
int32 score;
allphs->n_hmm_eval++;
score = hmm_vit_eval((hmm_t *) p);
if (score > best)
best = score;
}
}
}
return best;
}
static void
phmm_exit(allphone_search_t * allphs, int32 best)
{
s3cipid_t ci;
phmm_t *p;
int32 th, nf;
history_t *h;
blkarray_list_t *history;
bin_mdef_t *mdef;
int32 curfrm;
phmm_t **ci_phmm;
int32 *ci2lmwid;
th = best + allphs->pbeam;
history = allphs->history;
mdef = ps_search_acmod(allphs)->mdef;
curfrm = allphs->frame;
ci_phmm = allphs->ci_phmm;
ci2lmwid = allphs->ci2lmwid;
nf = curfrm + 1;
for (ci = 0; ci < mdef->n_ciphone; ci++) {
for (p = ci_phmm[(unsigned) ci]; p; p = p->next) {
if (hmm_frame(&(p->hmm)) == curfrm) {
if (hmm_bestscore(&(p->hmm)) >= th) {
h = (history_t *) ckd_calloc(1, sizeof(*h));
h->ef = curfrm;
h->phmm = p;
h->hist = hmm_out_history(&(p->hmm));
h->score = hmm_out_score(&(p->hmm));
if (!allphs->lm) {
h->tscore = allphs->inspen;
}
else {
if (h->hist > 0) {
int32 n_used;
history_t *pred =
blkarray_list_get(history, h->hist);
if (pred->hist > 0) {
history_t *pred_pred =
blkarray_list_get(history,
h->hist);
h->tscore =
ngram_tg_score(allphs->lm,
ci2lmwid
[pred_pred->phmm->ci],
ci2lmwid[pred->
phmm->ci],
ci2lmwid[p->ci],
&n_used) >>
SENSCR_SHIFT;
}
else {
h->tscore =
ngram_bg_score(allphs->lm,
ci2lmwid
[pred->phmm->ci],
ci2lmwid[p->ci],
&n_used) >>
SENSCR_SHIFT;
}
}
else {
/*
* This is the beginning SIL and in srch_allphone_begin()
* it's inscore is set to 0.
*/
h->tscore = 0;
}
}
blkarray_list_append(history, h);
/* Mark PHMM active in next frame */
hmm_frame(&(p->hmm)) = nf;
}
else {
/* Reset state scores */
hmm_clear(&(p->hmm));
}
}
}
}
}
static void
phmm_trans(allphone_search_t * allphs, int32 best,
int32 frame_history_start)
{
history_t *h;
phmm_t *from, *to;
plink_t *l;
int32 newscore, nf, curfrm;
int32 *ci2lmwid;
int32 hist_idx;
curfrm = allphs->frame;
nf = curfrm + 1;
ci2lmwid = allphs->ci2lmwid;
/* Transition from exited nodes to initial states of HMMs */
for (hist_idx = frame_history_start;
hist_idx < blkarray_list_n_valid(allphs->history); hist_idx++) {
h = blkarray_list_get(allphs->history, hist_idx);
from = h->phmm;
for (l = from->succlist; l; l = l->next) {
int32 tscore;
to = l->phmm;
/* No LM, just use uniform (insertion penalty). */
if (!allphs->lm)
tscore = allphs->inspen;
/* If they are not in the LM, kill this
* transition. */
else if (ci2lmwid[to->ci] == NGRAM_INVALID_WID)
continue;
else {
int32 n_used;
if (h->hist > 0) {
history_t *pred =
blkarray_list_get(allphs->history, h->hist);
tscore =
ngram_tg_score(allphs->lm,
ci2lmwid[pred->phmm->ci],
ci2lmwid[from->ci],
ci2lmwid[to->ci],
&n_used) >> SENSCR_SHIFT;
}
else {
tscore = ngram_bg_score(allphs->lm,
ci2lmwid[from->ci],
ci2lmwid[to->ci],
&n_used) >> SENSCR_SHIFT;
}
}
newscore = h->score + tscore;
if ((newscore > best + allphs->beam)
&& (newscore > hmm_in_score(&(to->hmm)))) {
hmm_enter(&(to->hmm), newscore, hist_idx, nf);
}
}
}
}
ps_search_t *
allphone_search_init(const char *name,
ngram_model_t * lm,
cmd_ln_t * config,
acmod_t * acmod, dict_t * dict, dict2pid_t * d2p)
{
int i;
bin_mdef_t *mdef;
allphone_search_t *allphs;
static char *lmname = "default";
allphs = (allphone_search_t *) ckd_calloc(1, sizeof(*allphs));
ps_search_init(ps_search_base(allphs), &allphone_funcs, PS_SEARCH_TYPE_ALLPHONE, name, config, acmod,
dict, d2p);
mdef = acmod->mdef;
allphs->hmmctx = hmm_context_init(bin_mdef_n_emit_state(mdef),
acmod->tmat->tp, NULL, mdef->sseq);
if (allphs->hmmctx == NULL) {
ps_search_free(ps_search_base(allphs));
return NULL;
}
allphs->ci_only = cmd_ln_boolean_r(config, "-allphone_ci");
allphs->lw = cmd_ln_float32_r(config, "-lw");
phmm_build(allphs);
if (lm) {
//language model is defined
allphs->lm = ngram_model_set_init(config, &lm, &lmname, NULL, 1);
if (!allphs->lm) {
E_ERROR
("Failed to initialize ngram model set for phoneme decoding");
allphone_search_free((ps_search_t *) allphs);
return NULL;
}
allphs->ci2lmwid =
(int32 *) ckd_calloc(mdef->n_ciphone,
sizeof(*allphs->ci2lmwid));
for (i = 0; i < mdef->n_ciphone; i++) {
allphs->ci2lmwid[i] =
ngram_wid(allphs->lm,
(char *) bin_mdef_ciphone_str(mdef, i));
/* Map filler phones to silence if not found */
if (allphs->ci2lmwid[i] == NGRAM_INVALID_WID
&& bin_mdef_ciphone_str(mdef, i))
allphs->ci2lmwid[i] =
ngram_wid(allphs->lm,
(char *) bin_mdef_ciphone_str(mdef,
mdef_silphone
(mdef)));
}
}
else {
E_WARN
("Failed to load language model specified in -allphone, doing unconstrained phone-loop decoding\n");
allphs->inspen =
(int32) (logmath_log
(acmod->lmath, cmd_ln_float32_r(config, "-pip"))
* allphs->lw) >> SENSCR_SHIFT;
}
allphs->n_tot_frame = 0;
allphs->frame = -1;
allphs->segments = NULL;
/* Get search pruning parameters */
allphs->beam
=
(int32) logmath_log(acmod->lmath,
cmd_ln_float64_r(config, "-beam"))
>> SENSCR_SHIFT;
allphs->pbeam
=
(int32) logmath_log(acmod->lmath,
cmd_ln_float64_r(config, "-pbeam"))
>> SENSCR_SHIFT;
/* LM related weights/penalties */
allphs->history = blkarray_list_init();
/* Acoustic score scale for posterior probabilities. */
allphs->ascale = 1.0 / cmd_ln_float32_r(config, "-ascale");
E_INFO("Allphone(beam: %d, pbeam: %d)\n", allphs->beam, allphs->pbeam);
ptmr_init(&allphs->perf);
return (ps_search_t *) allphs;
}
int
allphone_search_reinit(ps_search_t * search, dict_t * dict,
dict2pid_t * d2p)
{
allphone_search_t *allphs = (allphone_search_t *) search;
/* Free old dict2pid, dict */
ps_search_base_reinit(search, dict, d2p);
if (!allphs->lm) {
E_WARN
("-lm argument missing; doing unconstrained phone-loop decoding\n");
allphs->inspen =
(int32) (logmath_log
(search->acmod->lmath,
cmd_ln_float32_r(search->config,
"-pip")) *
allphs->lw) >> SENSCR_SHIFT;
}
return 0;
}
void
allphone_search_free(ps_search_t * search)
{
allphone_search_t *allphs = (allphone_search_t *) search;
double n_speech = (double)allphs->n_tot_frame
/ cmd_ln_int32_r(ps_search_config(allphs), "-frate");
E_INFO("TOTAL fwdflat %.2f CPU %.3f xRT\n",
allphs->perf.t_tot_cpu,
allphs->perf.t_tot_cpu / n_speech);
E_INFO("TOTAL fwdflat %.2f wall %.3f xRT\n",
allphs->perf.t_tot_elapsed,
allphs->perf.t_tot_elapsed / n_speech);
ps_search_base_free(search);
hmm_context_free(allphs->hmmctx);
phmm_free(allphs);
if (allphs->lm)
ngram_model_free(allphs->lm);
if (allphs->ci2lmwid)
ckd_free(allphs->ci2lmwid);
blkarray_list_free(allphs->history);
ckd_free(allphs);
}
int
allphone_search_start(ps_search_t * search)
{
allphone_search_t *allphs;
bin_mdef_t *mdef;
s3cipid_t ci;
phmm_t *p;
allphs = (allphone_search_t *) search;
mdef = search->acmod->mdef;
/* Reset all HMMs. */
for (ci = 0; ci < bin_mdef_n_ciphone(mdef); ci++) {
for (p = allphs->ci_phmm[(unsigned) ci]; p; p = p->next) {
hmm_clear(&(p->hmm));
}
}
allphs->n_hmm_eval = 0;
allphs->n_sen_eval = 0;
/* Free history nodes, if any */
blkarray_list_reset(allphs->history);
/* Initialize start state of the SILENCE PHMM */
allphs->frame = 0;
ci = bin_mdef_silphone(mdef);
if (NOT_S3CIPID(ci))
E_FATAL("Cannot find CI-phone %s\n", S3_SILENCE_CIPHONE);
for (p = allphs->ci_phmm[ci]; p && (p->pid != ci); p = p->next);
if (!p)
E_FATAL("Cannot find HMM for %s\n", S3_SILENCE_CIPHONE);
hmm_enter(&(p->hmm), 0, 0, allphs->frame);
ptmr_reset(&allphs->perf);
ptmr_start(&allphs->perf);
return 0;
}
static void
allphone_search_sen_active(allphone_search_t * allphs)
{
acmod_t *acmod;
bin_mdef_t *mdef;
phmm_t *p;
int32 ci;
acmod = ps_search_acmod(allphs);
mdef = acmod->mdef;
acmod_clear_active(acmod);
for (ci = 0; ci < bin_mdef_n_ciphone(mdef); ci++)
for (p = allphs->ci_phmm[ci]; p; p = p->next)
if (hmm_frame(&(p->hmm)) == allphs->frame)
acmod_activate_hmm(acmod, &(p->hmm));
}
int
allphone_search_step(ps_search_t * search, int frame_idx)
{
int32 bestscr, frame_history_start;
const int16 *senscr;
allphone_search_t *allphs = (allphone_search_t *) search;
acmod_t *acmod = search->acmod;
if (!acmod->compallsen)
allphone_search_sen_active(allphs);
senscr = acmod_score(acmod, &frame_idx);
allphs->n_sen_eval += acmod->n_senone_active;
bestscr = phmm_eval_all(allphs, senscr);
frame_history_start = blkarray_list_n_valid(allphs->history);
phmm_exit(allphs, bestscr);
phmm_trans(allphs, bestscr, frame_history_start);
allphs->frame++;
return 0;
}
static int32
ascore(allphone_search_t * allphs, history_t * h)
{
int32 score = h->score;
if (h->hist > 0) {
history_t *pred = blkarray_list_get(allphs->history, h->hist);
score -= pred->score;
}
return score - h->tscore;
}
static void
allphone_clear_segments(allphone_search_t * allphs)
{
gnode_t *gn;
for (gn = allphs->segments; gn; gn = gn->next) {
ckd_free(gnode_ptr(gn));
}
glist_free(allphs->segments);
allphs->segments = NULL;
}
static void
allphone_backtrace(allphone_search_t * allphs, int32 f)
{
int32 best, hist_idx, best_idx;
int32 frm, last_frm;
history_t *h;
phseg_t *s;
/* Clear old list */
allphone_clear_segments(allphs);
frm = last_frm = f;
/* Find the first history entry for the requested frame */
hist_idx = blkarray_list_n_valid(allphs->history) - 1;
while (hist_idx > 0) {
h = blkarray_list_get(allphs->history, hist_idx);
if (h->ef <= f) {
frm = last_frm = h->ef;
break;
}
hist_idx--;
}
if (hist_idx < 0)
return;
/* Find bestscore */
best = (int32) 0x80000000;
best_idx = -1;
while (frm == last_frm && hist_idx > 0) {
h = blkarray_list_get(allphs->history, hist_idx);
frm = h->ef;
if (h->score > best && frm == last_frm) {
best = h->score;
best_idx = hist_idx;
}
hist_idx--;
}
if (best_idx < 0)
return;
/* Backtrace */
while (best_idx > 0) {
h = blkarray_list_get(allphs->history, best_idx);
s = (phseg_t *) ckd_calloc(1, sizeof(phseg_t));
s->ci = h->phmm->ci;
s->sf =
(h->hist >
0) ? ((history_t *) blkarray_list_get(allphs->history,
h->hist))->ef + 1 : 0;
s->ef = h->ef;
s->score = ascore(allphs, h);
s->tscore = h->tscore;
allphs->segments = glist_add_ptr(allphs->segments, s);
best_idx = h->hist;
}
return;
}
int
allphone_search_finish(ps_search_t * search)
{
allphone_search_t *allphs;
int32 cf, n_hist;
allphs = (allphone_search_t *) search;
allphs->n_tot_frame += allphs->frame;
n_hist = blkarray_list_n_valid(allphs->history);
E_INFO
("%d frames, %d HMMs (%d/fr), %d senones (%d/fr), %d history entries (%d/fr)\n",
allphs->frame, allphs->n_hmm_eval,
(allphs->frame > 0) ? allphs->n_hmm_eval / allphs->frame : 0,
allphs->n_sen_eval,
(allphs->frame > 0) ? allphs->n_sen_eval / allphs->frame : 0,
n_hist, (allphs->frame > 0) ? n_hist / allphs->frame : 0);
/* Now backtrace. */
allphone_backtrace(allphs, allphs->frame - 1);
/* Print out some statistics. */
ptmr_stop(&allphs->perf);
/* This is the number of frames processed. */
cf = ps_search_acmod(allphs)->output_frame;
if (cf > 0) {
double n_speech = (double) (cf + 1)
/ cmd_ln_int32_r(ps_search_config(allphs), "-frate");
E_INFO("allphone %.2f CPU %.3f xRT\n",
allphs->perf.t_cpu, allphs->perf.t_cpu / n_speech);
E_INFO("allphone %.2f wall %.3f xRT\n",
allphs->perf.t_elapsed, allphs->perf.t_elapsed / n_speech);
}
return 0;
}
char const *
allphone_search_hyp(ps_search_t * search, int32 * out_score,
int32 * out_is_final)
{
allphone_search_t *allphs;
phseg_t *p;
gnode_t *gn;
const char *phone_str;
bin_mdef_t *mdef;
int len, hyp_idx, phone_idx;
allphs = (allphone_search_t *) search;
mdef = search->acmod->mdef;
/* Create hypothesis */
if (search->hyp_str)
ckd_free(search->hyp_str);
search->hyp_str = NULL;
allphone_backtrace(allphs, allphs->frame - 1);
if (allphs->segments == NULL) {
return NULL;
}
len = glist_count(allphs->segments) * 10; // maximum length of one phone with spacebar
search->hyp_str = (char *) ckd_calloc(len, sizeof(*search->hyp_str));
hyp_idx = 0;
for (gn = allphs->segments; gn; gn = gn->next) {
p = gnode_ptr(gn);
phone_str = bin_mdef_ciphone_str(mdef, p->ci);
phone_idx = 0;
while (phone_str[phone_idx] != '\0')
search->hyp_str[hyp_idx++] = phone_str[phone_idx++];
search->hyp_str[hyp_idx++] = ' ';
}
search->hyp_str[--hyp_idx] = '\0';
E_INFO("Hyp: %s\n", search->hyp_str);
return search->hyp_str;
}

View File

@ -0,0 +1,180 @@
/* -*- c-basic-offset:4; indent-tabs-mode: nil -*- */
/* ====================================================================
* Copyright (c) 2014 Carnegie Mellon University. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. 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 CARNEGIE MELLON UNIVERSITY ``AS IS'' AND
* ANY EXPRESSED 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 CARNEGIE MELLON UNIVERSITY
* NOR ITS EMPLOYEES 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.
*
* ====================================================================
*
*/
/*
* allphone_search.h -- Search structures for phoneme decoding.
*/
#ifndef __ALLPHONE_SEARCH_H__
#define __ALLPHONE_SEARCH_H__
/* SphinxBase headers. */
#include <sphinxbase/glist.h>
#include <sphinxbase/cmd_ln.h>
#include <sphinxbase/ngram_model.h>
#include <sphinxbase/bitvec.h>
/* Local headers. */
#include "pocketsphinx_internal.h"
#include "blkarray_list.h"
#include "hmm.h"
/**
* Models a single unique <senone-sequence, tmat> pair.
* Can represent several different triphones, but all with the same parent basephone.
* (NOTE: Word-position attribute of triphone is ignored.)
*/
typedef struct phmm_s {
hmm_t hmm; /**< Base HMM structure */
s3pid_t pid; /**< Phone id (temp. during init.) */
s3cipid_t ci; /**< Parent basephone for this PHMM */
bitvec_t *lc; /**< Set (bit-vector) of left context phones seen for this PHMM */
bitvec_t *rc; /**< Set (bit-vector) of right context phones seen for this PHMM */
struct phmm_s *next; /**< Next unique PHMM for same parent basephone */
struct plink_s *succlist; /**< List of predecessor PHMM nodes */
} phmm_t;
/**
* List of links from a PHMM node to its successors; one link per successor.
*/
typedef struct plink_s {
phmm_t *phmm; /**< Successor PHMM node */
struct plink_s *next; /**< Next link for parent PHMM node */
} plink_t;
/**
* History (paths) information at any point in allphone Viterbi search.
*/
typedef struct history_s {
phmm_t *phmm; /**< PHMM ending this path */
int32 score; /**< Path score for this path */
int32 tscore; /**< Transition score for this path */
frame_idx_t ef; /**< End frame */
int32 hist; /**< Previous history entry */
} history_t;
/**
* Phone level segmentation information
*/
typedef struct phseg_s {
s3cipid_t ci; /* CI-phone id */
frame_idx_t sf, ef; /* Start and end frame for this phone occurrence */
int32 score; /* Acoustic score for this segment of alignment */
int32 tscore; /* Transition ("LM") score for this segment */
} phseg_t;
/**
* Segment iterator over list of phseg
*/
typedef struct phseg_iter_s {
ps_seg_t base;
glist_t seg;
} phseg_iter_t;
/**
* Implementation of allphone search structure.
*/
typedef struct allphone_search_s {
ps_search_t base;
hmm_context_t *hmmctx; /**< HMM context. */
ngram_model_t *lm; /**< Ngram model set */
int32 ci_only; /**< Use context-independent phones for decoding */
phmm_t **ci_phmm; /**< PHMM lists (for each CI phone) */
int32 *ci2lmwid; /**< Mapping of CI phones to LM word IDs */
int32 beam, pbeam; /**< Effective beams after applying beam_factor */
int32 lw, inspen; /**< Language weights */
frame_idx_t frame; /**< Current frame. */
float32 ascale; /**< Acoustic score scale for posterior probabilities. */
int32 n_tot_frame; /**< Total number of frames processed */
int32 n_hmm_eval; /**< Total HMMs evaluated this utt */
int32 n_sen_eval; /**< Total senones evaluated this utt */
/* Backtrace information */
blkarray_list_t *history; /**< List of history nodes allocated in each frame */
/* Hypothesis DAG */
glist_t segments;
ptmr_t perf; /**< Performance counter */
} allphone_search_t;
/**
* Create, initialize and return a search module.
*/
ps_search_t *allphone_search_init(const char *name,
ngram_model_t * lm,
cmd_ln_t * config,
acmod_t * acmod,
dict_t * dict, dict2pid_t * d2p);
/**
* Deallocate search structure.
*/
void allphone_search_free(ps_search_t * search);
/**
* Update allphone search module.
*/
int allphone_search_reinit(ps_search_t * search, dict_t * dict,
dict2pid_t * d2p);
/**
* Prepare the allphone search structure for beginning decoding of the next
* utterance.
*/
int allphone_search_start(ps_search_t * search);
/**
* Step one frame forward through the Viterbi search.
*/
int allphone_search_step(ps_search_t * search, int frame_idx);
/**
* Windup and clean the allphone search structure after utterance.
*/
int allphone_search_finish(ps_search_t * search);
/**
* Get hypothesis string from the allphone search.
*/
char const *allphone_search_hyp(ps_search_t * search, int32 * out_score,
int32 * out_is_final);
#endif /* __ALLPHONE_SEARCH_H__ */

View File

@ -0,0 +1,887 @@
/* -*- c-basic-offset: 4; indent-tabs-mode: nil -*- */
/* ====================================================================
* Copyright (c) 2005 Carnegie Mellon University. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. 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 work was supported in part by funding from the Defense Advanced
* Research Projects Agency and the National Science Foundation of the
* United States of America, and the CMU Sphinx Speech Consortium.
*
* THIS SOFTWARE IS PROVIDED BY CARNEGIE MELLON UNIVERSITY ``AS IS'' AND
* ANY EXPRESSED 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 CARNEGIE MELLON UNIVERSITY
* NOR ITS EMPLOYEES 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.
*
* ====================================================================
*
*/
/*********************************************************************
*
* File: bin_mdef.c
*
* Description:
* Binary format model definition files, with support for
* heterogeneous topologies and variable-size N-phones
*
* Author:
* David Huggins-Daines <dhuggins@cs.cmu.edu>
*********************************************************************/
/* System headers. */
#include <stdio.h>
#include <string.h>
#include <assert.h>
/* SphinxBase headers. */
#include <sphinxbase/prim_type.h>
#include <sphinxbase/ckd_alloc.h>
#include <sphinxbase/byteorder.h>
#include <sphinxbase/case.h>
#include <sphinxbase/err.h>
/* Local headers. */
#include "mdef.h"
#include "bin_mdef.h"
bin_mdef_t *
bin_mdef_read_text(cmd_ln_t *config, const char *filename)
{
bin_mdef_t *bmdef;
mdef_t *mdef;
int i, nodes, ci_idx, lc_idx, rc_idx;
int nchars;
if ((mdef = mdef_init((char *) filename, TRUE)) == NULL)
return NULL;
/* Enforce some limits. */
if (mdef->n_sen > BAD_SENID) {
E_ERROR("Number of senones exceeds limit: %d > %d\n",
mdef->n_sen, BAD_SENID);
mdef_free(mdef);
return NULL;
}
if (mdef->n_sseq > BAD_SSID) {
E_ERROR("Number of senone sequences exceeds limit: %d > %d\n",
mdef->n_sseq, BAD_SSID);
mdef_free(mdef);
return NULL;
}
/* We use uint8 for ciphones */
if (mdef->n_ciphone > 255) {
E_ERROR("Number of phones exceeds limit: %d > %d\n",
mdef->n_ciphone, 255);
mdef_free(mdef);
return NULL;
}
bmdef = ckd_calloc(1, sizeof(*bmdef));
bmdef->refcnt = 1;
/* Easy stuff. The mdef.c code has done the heavy lifting for us. */
bmdef->n_ciphone = mdef->n_ciphone;
bmdef->n_phone = mdef->n_phone;
bmdef->n_emit_state = mdef->n_emit_state;
bmdef->n_ci_sen = mdef->n_ci_sen;
bmdef->n_sen = mdef->n_sen;
bmdef->n_tmat = mdef->n_tmat;
bmdef->n_sseq = mdef->n_sseq;
bmdef->sseq = mdef->sseq;
bmdef->cd2cisen = mdef->cd2cisen;
bmdef->sen2cimap = mdef->sen2cimap;
bmdef->n_ctx = 3; /* Triphones only. */
bmdef->sil = mdef->sil;
mdef->sseq = NULL; /* We are taking over this one. */
mdef->cd2cisen = NULL; /* And this one. */
mdef->sen2cimap = NULL; /* And this one. */
/* Get the phone names. If they are not sorted
* ASCII-betically then we are in a world of hurt and
* therefore will simply refuse to continue. */
bmdef->ciname = ckd_calloc(bmdef->n_ciphone, sizeof(*bmdef->ciname));
nchars = 0;
for (i = 0; i < bmdef->n_ciphone; ++i)
nchars += strlen(mdef->ciphone[i].name) + 1;
bmdef->ciname[0] = ckd_calloc(nchars, 1);
strcpy(bmdef->ciname[0], mdef->ciphone[0].name);
for (i = 1; i < bmdef->n_ciphone; ++i) {
bmdef->ciname[i] =
bmdef->ciname[i - 1] + strlen(bmdef->ciname[i - 1]) + 1;
strcpy(bmdef->ciname[i], mdef->ciphone[i].name);
if (i > 0 && strcmp(bmdef->ciname[i - 1], bmdef->ciname[i]) > 0) {
/* FIXME: there should be a solution to this, actually. */
E_ERROR("Phone names are not in sorted order, sorry.");
bin_mdef_free(bmdef);
return NULL;
}
}
/* Copy over phone information. */
bmdef->phone = ckd_calloc(bmdef->n_phone, sizeof(*bmdef->phone));
for (i = 0; i < mdef->n_phone; ++i) {
bmdef->phone[i].ssid = mdef->phone[i].ssid;
bmdef->phone[i].tmat = mdef->phone[i].tmat;
if (i < bmdef->n_ciphone) {
bmdef->phone[i].info.ci.filler = mdef->ciphone[i].filler;
}
else {
bmdef->phone[i].info.cd.wpos = mdef->phone[i].wpos;
bmdef->phone[i].info.cd.ctx[0] = mdef->phone[i].ci;
bmdef->phone[i].info.cd.ctx[1] = mdef->phone[i].lc;
bmdef->phone[i].info.cd.ctx[2] = mdef->phone[i].rc;
}
}
/* Walk the wpos_ci_lclist once to find the total number of
* nodes and the starting locations for each level. */
nodes = lc_idx = ci_idx = rc_idx = 0;
for (i = 0; i < N_WORD_POSN; ++i) {
int j;
for (j = 0; j < mdef->n_ciphone; ++j) {
ph_lc_t *lc;
for (lc = mdef->wpos_ci_lclist[i][j]; lc; lc = lc->next) {
ph_rc_t *rc;
for (rc = lc->rclist; rc; rc = rc->next) {
++nodes; /* RC node */
}
++nodes; /* LC node */
++rc_idx; /* Start of RC nodes (after LC nodes) */
}
++nodes; /* CI node */
++lc_idx; /* Start of LC nodes (after CI nodes) */
++rc_idx; /* Start of RC nodes (after CI and LC nodes) */
}
++nodes; /* wpos node */
++ci_idx; /* Start of CI nodes (after wpos nodes) */
++lc_idx; /* Start of LC nodes (after CI nodes) */
++rc_idx; /* STart of RC nodes (after wpos, CI, and LC nodes) */
}
E_INFO("Allocating %d * %d bytes (%d KiB) for CD tree\n",
nodes, sizeof(*bmdef->cd_tree),
nodes * sizeof(*bmdef->cd_tree) / 1024);
bmdef->n_cd_tree = nodes;
bmdef->cd_tree = ckd_calloc(nodes, sizeof(*bmdef->cd_tree));
for (i = 0; i < N_WORD_POSN; ++i) {
int j;
bmdef->cd_tree[i].ctx = i;
bmdef->cd_tree[i].n_down = mdef->n_ciphone;
bmdef->cd_tree[i].c.down = ci_idx;
#if 0
E_INFO("%d => %c (%d@%d)\n",
i, (WPOS_NAME)[i],
bmdef->cd_tree[i].n_down, bmdef->cd_tree[i].c.down);
#endif
/* Now we can build the rest of the tree. */
for (j = 0; j < mdef->n_ciphone; ++j) {
ph_lc_t *lc;
bmdef->cd_tree[ci_idx].ctx = j;
bmdef->cd_tree[ci_idx].c.down = lc_idx;
for (lc = mdef->wpos_ci_lclist[i][j]; lc; lc = lc->next) {
ph_rc_t *rc;
bmdef->cd_tree[lc_idx].ctx = lc->lc;
bmdef->cd_tree[lc_idx].c.down = rc_idx;
for (rc = lc->rclist; rc; rc = rc->next) {
bmdef->cd_tree[rc_idx].ctx = rc->rc;
bmdef->cd_tree[rc_idx].n_down = 0;
bmdef->cd_tree[rc_idx].c.pid = rc->pid;
#if 0
E_INFO("%d => %s %s %s %c (%d@%d)\n",
rc_idx,
bmdef->ciname[j],
bmdef->ciname[lc->lc],
bmdef->ciname[rc->rc],
(WPOS_NAME)[i],
bmdef->cd_tree[rc_idx].n_down,
bmdef->cd_tree[rc_idx].c.down);
#endif
++bmdef->cd_tree[lc_idx].n_down;
++rc_idx;
}
/* If there are no triphones here,
* this is considered a leafnode, so
* set the pid to -1. */
if (bmdef->cd_tree[lc_idx].n_down == 0)
bmdef->cd_tree[lc_idx].c.pid = -1;
#if 0
E_INFO("%d => %s %s %c (%d@%d)\n",
lc_idx,
bmdef->ciname[j],
bmdef->ciname[lc->lc],
(WPOS_NAME)[i],
bmdef->cd_tree[lc_idx].n_down,
bmdef->cd_tree[lc_idx].c.down);
#endif
++bmdef->cd_tree[ci_idx].n_down;
++lc_idx;
}
/* As above, so below. */
if (bmdef->cd_tree[ci_idx].n_down == 0)
bmdef->cd_tree[ci_idx].c.pid = -1;
#if 0
E_INFO("%d => %d=%s (%d@%d)\n",
ci_idx, j, bmdef->ciname[j],
bmdef->cd_tree[ci_idx].n_down,
bmdef->cd_tree[ci_idx].c.down);
#endif
++ci_idx;
}
}
mdef_free(mdef);
bmdef->alloc_mode = BIN_MDEF_FROM_TEXT;
return bmdef;
}
bin_mdef_t *
bin_mdef_retain(bin_mdef_t *m)
{
++m->refcnt;
return m;
}
int
bin_mdef_free(bin_mdef_t * m)
{
if (m == NULL)
return 0;
if (--m->refcnt > 0)
return m->refcnt;
switch (m->alloc_mode) {
case BIN_MDEF_FROM_TEXT:
ckd_free(m->ciname[0]);
ckd_free(m->sseq[0]);
ckd_free(m->phone);
ckd_free(m->cd_tree);
break;
case BIN_MDEF_IN_MEMORY:
ckd_free(m->ciname[0]);
break;
case BIN_MDEF_ON_DISK:
break;
}
if (m->filemap)
mmio_file_unmap(m->filemap);
ckd_free(m->cd2cisen);
ckd_free(m->sen2cimap);
ckd_free(m->ciname);
ckd_free(m->sseq);
ckd_free(m);
return 0;
}
static const char format_desc[] =
"BEGIN FILE FORMAT DESCRIPTION\n"
"int32 n_ciphone; /**< Number of base (CI) phones */\n"
"int32 n_phone; /**< Number of base (CI) phones + (CD) triphones */\n"
"int32 n_emit_state; /**< Number of emitting states per phone (0 if heterogeneous) */\n"
"int32 n_ci_sen; /**< Number of CI senones; these are the first */\n"
"int32 n_sen; /**< Number of senones (CI+CD) */\n"
"int32 n_tmat; /**< Number of transition matrices */\n"
"int32 n_sseq; /**< Number of unique senone sequences */\n"
"int32 n_ctx; /**< Number of phones of context */\n"
"int32 n_cd_tree; /**< Number of nodes in CD tree structure */\n"
"int32 sil; /**< CI phone ID for silence */\n"
"char ciphones[][]; /**< CI phone strings (null-terminated) */\n"
"char padding[]; /**< Padding to a 4-bytes boundary */\n"
"struct { int16 ctx; int16 n_down; int32 pid/down } cd_tree[];\n"
"struct { int32 ssid; int32 tmat; int8 attr[4] } phones[];\n"
"int16 sseq[]; /**< Unique senone sequences */\n"
"int8 sseq_len[]; /**< Number of states in each sseq (none if homogeneous) */\n"
"END FILE FORMAT DESCRIPTION\n";
bin_mdef_t *
bin_mdef_read(cmd_ln_t *config, const char *filename)
{
bin_mdef_t *m;
FILE *fh;
size_t tree_start;
int32 val, i, do_mmap, swap;
long pos, end;
int32 *sseq_size;
/* Try to read it as text first. */
if ((m = bin_mdef_read_text(config, filename)) != NULL)
return m;
E_INFO("Reading binary model definition: %s\n", filename);
if ((fh = fopen(filename, "rb")) == NULL)
return NULL;
if (fread(&val, 4, 1, fh) != 1) {
fclose(fh);
E_ERROR_SYSTEM("Failed to read byte-order marker from %s\n",
filename);
return NULL;
}
swap = 0;
if (val == BIN_MDEF_OTHER_ENDIAN) {
swap = 1;
E_INFO("Must byte-swap %s\n", filename);
}
if (fread(&val, 4, 1, fh) != 1) {
fclose(fh);
E_ERROR_SYSTEM("Failed to read version from %s\n", filename);
return NULL;
}
if (swap)
SWAP_INT32(&val);
if (val > BIN_MDEF_FORMAT_VERSION) {
E_ERROR("File format version %d for %s is newer than library\n",
val, filename);
fclose(fh);
return NULL;
}
if (fread(&val, 4, 1, fh) != 1) {
fclose(fh);
E_ERROR_SYSTEM("Failed to read header length from %s\n", filename);
return NULL;
}
if (swap)
SWAP_INT32(&val);
/* Skip format descriptor. */
fseek(fh, val, SEEK_CUR);
/* Finally allocate it. */
m = ckd_calloc(1, sizeof(*m));
m->refcnt = 1;
/* Check these, to make gcc/glibc shut up. */
#define FREAD_SWAP32_CHK(dest) \
if (fread((dest), 4, 1, fh) != 1) { \
fclose(fh); \
ckd_free(m); \
E_ERROR_SYSTEM("Failed to read %s from %s\n", #dest, filename); \
return NULL; \
} \
if (swap) SWAP_INT32(dest);
FREAD_SWAP32_CHK(&m->n_ciphone);
FREAD_SWAP32_CHK(&m->n_phone);
FREAD_SWAP32_CHK(&m->n_emit_state);
FREAD_SWAP32_CHK(&m->n_ci_sen);
FREAD_SWAP32_CHK(&m->n_sen);
FREAD_SWAP32_CHK(&m->n_tmat);
FREAD_SWAP32_CHK(&m->n_sseq);
FREAD_SWAP32_CHK(&m->n_ctx);
FREAD_SWAP32_CHK(&m->n_cd_tree);
FREAD_SWAP32_CHK(&m->sil);
/* CI names are first in the file. */
m->ciname = ckd_calloc(m->n_ciphone, sizeof(*m->ciname));
/* Decide whether to read in the whole file or mmap it. */
do_mmap = config ? cmd_ln_boolean_r(config, "-mmap") : TRUE;
if (swap) {
E_WARN("-mmap specified, but mdef is other-endian. Will not memory-map.\n");
do_mmap = FALSE;
}
/* Actually try to mmap it. */
if (do_mmap) {
m->filemap = mmio_file_read(filename);
if (m->filemap == NULL)
do_mmap = FALSE;
}
pos = ftell(fh);
if (do_mmap) {
/* Get the base pointer from the memory map. */
m->ciname[0] = (char *)mmio_file_ptr(m->filemap) + pos;
/* Success! */
m->alloc_mode = BIN_MDEF_ON_DISK;
}
else {
/* Read everything into memory. */
m->alloc_mode = BIN_MDEF_IN_MEMORY;
fseek(fh, 0, SEEK_END);
end = ftell(fh);
fseek(fh, pos, SEEK_SET);
m->ciname[0] = ckd_malloc(end - pos);
if (fread(m->ciname[0], 1, end - pos, fh) != end - pos)
E_FATAL("Failed to read %d bytes of data from %s\n", end - pos, filename);
}
for (i = 1; i < m->n_ciphone; ++i)
m->ciname[i] = m->ciname[i - 1] + strlen(m->ciname[i - 1]) + 1;
/* Skip past the padding. */
tree_start =
m->ciname[i - 1] + strlen(m->ciname[i - 1]) + 1 - m->ciname[0];
tree_start = (tree_start + 3) & ~3;
m->cd_tree = (cd_tree_t *) (m->ciname[0] + tree_start);
if (swap) {
for (i = 0; i < m->n_cd_tree; ++i) {
SWAP_INT16(&m->cd_tree[i].ctx);
SWAP_INT16(&m->cd_tree[i].n_down);
SWAP_INT32(&m->cd_tree[i].c.down);
}
}
m->phone = (mdef_entry_t *) (m->cd_tree + m->n_cd_tree);
if (swap) {
for (i = 0; i < m->n_phone; ++i) {
SWAP_INT32(&m->phone[i].ssid);
SWAP_INT32(&m->phone[i].tmat);
}
}
sseq_size = (int32 *) (m->phone + m->n_phone);
if (swap)
SWAP_INT32(sseq_size);
m->sseq = ckd_calloc(m->n_sseq, sizeof(*m->sseq));
m->sseq[0] = (uint16 *) (sseq_size + 1);
if (swap) {
for (i = 0; i < *sseq_size; ++i)
SWAP_INT16(m->sseq[0] + i);
}
if (m->n_emit_state) {
for (i = 1; i < m->n_sseq; ++i)
m->sseq[i] = m->sseq[0] + i * m->n_emit_state;
}
else {
m->sseq_len = (uint8 *) (m->sseq[0] + *sseq_size);
for (i = 1; i < m->n_sseq; ++i)
m->sseq[i] = m->sseq[i - 1] + m->sseq_len[i - 1];
}
/* Now build the CD-to-CI mappings using the senone sequences.
* This is the only really accurate way to do it, though it is
* still inaccurate in the case of heterogeneous topologies or
* cross-state tying. */
m->cd2cisen = (int16 *) ckd_malloc(m->n_sen * sizeof(*m->cd2cisen));
m->sen2cimap = (int16 *) ckd_malloc(m->n_sen * sizeof(*m->sen2cimap));
/* Default mappings (identity, none) */
for (i = 0; i < m->n_ci_sen; ++i)
m->cd2cisen[i] = i;
for (; i < m->n_sen; ++i)
m->cd2cisen[i] = -1;
for (i = 0; i < m->n_sen; ++i)
m->sen2cimap[i] = -1;
for (i = 0; i < m->n_phone; ++i) {
int32 j, ssid = m->phone[i].ssid;
for (j = 0; j < bin_mdef_n_emit_state_phone(m, i); ++j) {
int s = bin_mdef_sseq2sen(m, ssid, j);
int ci = bin_mdef_pid2ci(m, i);
/* Take the first one and warn if we have cross-state tying. */
if (m->sen2cimap[s] == -1)
m->sen2cimap[s] = ci;
if (m->sen2cimap[s] != ci)
E_WARN
("Senone %d is shared between multiple base phones\n",
s);
if (j > bin_mdef_n_emit_state_phone(m, ci))
E_WARN("CD phone %d has fewer states than CI phone %d\n",
i, ci);
else
m->cd2cisen[s] =
bin_mdef_sseq2sen(m, m->phone[ci].ssid, j);
}
}
/* Set the silence phone. */
m->sil = bin_mdef_ciphone_id(m, S3_SILENCE_CIPHONE);
E_INFO
("%d CI-phone, %d CD-phone, %d emitstate/phone, %d CI-sen, %d Sen, %d Sen-Seq\n",
m->n_ciphone, m->n_phone - m->n_ciphone, m->n_emit_state,
m->n_ci_sen, m->n_sen, m->n_sseq);
fclose(fh);
return m;
}
int
bin_mdef_write(bin_mdef_t * m, const char *filename)
{
FILE *fh;
int32 val, i;
if ((fh = fopen(filename, "wb")) == NULL)
return -1;
/* Byteorder marker. */
val = BIN_MDEF_NATIVE_ENDIAN;
fwrite(&val, 1, 4, fh);
/* Version. */
val = BIN_MDEF_FORMAT_VERSION;
fwrite(&val, 1, sizeof(val), fh);
/* Round the format descriptor size up to a 4-byte boundary. */
val = ((sizeof(format_desc) + 3) & ~3);
fwrite(&val, 1, sizeof(val), fh);
fwrite(format_desc, 1, sizeof(format_desc), fh);
/* Pad it with zeros. */
i = 0;
fwrite(&i, 1, val - sizeof(format_desc), fh);
/* Binary header things. */
fwrite(&m->n_ciphone, 4, 1, fh);
fwrite(&m->n_phone, 4, 1, fh);
fwrite(&m->n_emit_state, 4, 1, fh);
fwrite(&m->n_ci_sen, 4, 1, fh);
fwrite(&m->n_sen, 4, 1, fh);
fwrite(&m->n_tmat, 4, 1, fh);
fwrite(&m->n_sseq, 4, 1, fh);
fwrite(&m->n_ctx, 4, 1, fh);
fwrite(&m->n_cd_tree, 4, 1, fh);
/* Write this as a 32-bit value to preserve alignment for the
* non-mmap case (we want things aligned both from the
* beginning of the file and the beginning of the phone
* strings). */
val = m->sil;
fwrite(&val, 4, 1, fh);
/* Phone strings. */
for (i = 0; i < m->n_ciphone; ++i)
fwrite(m->ciname[i], 1, strlen(m->ciname[i]) + 1, fh);
/* Pad with zeros. */
val = (ftell(fh) + 3) & ~3;
i = 0;
fwrite(&i, 1, val - ftell(fh), fh);
/* Write CD-tree */
fwrite(m->cd_tree, sizeof(*m->cd_tree), m->n_cd_tree, fh);
/* Write phones */
fwrite(m->phone, sizeof(*m->phone), m->n_phone, fh);
if (m->n_emit_state) {
/* Write size of sseq */
val = m->n_sseq * m->n_emit_state;
fwrite(&val, 4, 1, fh);
/* Write sseq */
fwrite(m->sseq[0], sizeof(**m->sseq),
m->n_sseq * m->n_emit_state, fh);
}
else {
int32 n;
/* Calcluate size of sseq */
n = 0;
for (i = 0; i < m->n_sseq; ++i)
n += m->sseq_len[i];
/* Write size of sseq */
fwrite(&n, 4, 1, fh);
/* Write sseq */
fwrite(m->sseq[0], sizeof(**m->sseq), n, fh);
/* Write sseq_len */
fwrite(m->sseq_len, 1, m->n_sseq, fh);
}
fclose(fh);
return 0;
}
int
bin_mdef_write_text(bin_mdef_t * m, const char *filename)
{
FILE *fh;
int p, i, n_total_state;
if (strcmp(filename, "-") == 0)
fh = stdout;
else {
if ((fh = fopen(filename, "w")) == NULL)
return -1;
}
fprintf(fh, "0.3\n");
fprintf(fh, "%d n_base\n", m->n_ciphone);
fprintf(fh, "%d n_tri\n", m->n_phone - m->n_ciphone);
if (m->n_emit_state)
n_total_state = m->n_phone * (m->n_emit_state + 1);
else {
n_total_state = 0;
for (i = 0; i < m->n_phone; ++i)
n_total_state += m->sseq_len[m->phone[i].ssid] + 1;
}
fprintf(fh, "%d n_state_map\n", n_total_state);
fprintf(fh, "%d n_tied_state\n", m->n_sen);
fprintf(fh, "%d n_tied_ci_state\n", m->n_ci_sen);
fprintf(fh, "%d n_tied_tmat\n", m->n_tmat);
fprintf(fh, "#\n# Columns definitions\n");
fprintf(fh, "#%4s %3s %3s %1s %6s %4s %s\n",
"base", "lft", "rt", "p", "attrib", "tmat",
" ... state id's ...");
for (p = 0; p < m->n_ciphone; p++) {
int n_state;
fprintf(fh, "%5s %3s %3s %1s", m->ciname[p], "-", "-", "-");
if (bin_mdef_is_fillerphone(m, p))
fprintf(fh, " %6s", "filler");
else
fprintf(fh, " %6s", "n/a");
fprintf(fh, " %4d", m->phone[p].tmat);
if (m->n_emit_state)
n_state = m->n_emit_state;
else
n_state = m->sseq_len[m->phone[p].ssid];
for (i = 0; i < n_state; i++) {
fprintf(fh, " %6u", m->sseq[m->phone[p].ssid][i]);
}
fprintf(fh, " N\n");
}
for (; p < m->n_phone; p++) {
int n_state;
fprintf(fh, "%5s %3s %3s %c",
m->ciname[m->phone[p].info.cd.ctx[0]],
m->ciname[m->phone[p].info.cd.ctx[1]],
m->ciname[m->phone[p].info.cd.ctx[2]],
(WPOS_NAME)[m->phone[p].info.cd.wpos]);
if (bin_mdef_is_fillerphone(m, p))
fprintf(fh, " %6s", "filler");
else
fprintf(fh, " %6s", "n/a");
fprintf(fh, " %4d", m->phone[p].tmat);
if (m->n_emit_state)
n_state = m->n_emit_state;
else
n_state = m->sseq_len[m->phone[p].ssid];
for (i = 0; i < n_state; i++) {
fprintf(fh, " %6u", m->sseq[m->phone[p].ssid][i]);
}
fprintf(fh, " N\n");
}
if (strcmp(filename, "-") != 0)
fclose(fh);
return 0;
}
int
bin_mdef_ciphone_id(bin_mdef_t * m, const char *ciphone)
{
int low, mid, high;
/* Exact binary search on m->ciphone */
low = 0;
high = m->n_ciphone;
while (low < high) {
int c;
mid = (low + high) / 2;
c = strcmp(ciphone, m->ciname[mid]);
if (c == 0)
return mid;
else if (c > 0)
low = mid + 1;
else if (c < 0)
high = mid;
}
return -1;
}
int
bin_mdef_ciphone_id_nocase(bin_mdef_t * m, const char *ciphone)
{
int low, mid, high;
/* Exact binary search on m->ciphone */
low = 0;
high = m->n_ciphone;
while (low < high) {
int c;
mid = (low + high) / 2;
c = strcmp_nocase(ciphone, m->ciname[mid]);
if (c == 0)
return mid;
else if (c > 0)
low = mid + 1;
else if (c < 0)
high = mid;
}
return -1;
}
const char *
bin_mdef_ciphone_str(bin_mdef_t * m, int32 ci)
{
assert(m != NULL);
assert(ci < m->n_ciphone);
return m->ciname[ci];
}
int
bin_mdef_phone_id(bin_mdef_t * m, int32 ci, int32 lc, int32 rc, int32 wpos)
{
cd_tree_t *cd_tree;
int level, max;
int16 ctx[4];
assert(m);
/* In the future, we might back off when context is not available,
* but for now we'll just return the CI phone. */
if (lc < 0 || rc < 0)
return ci;
assert((ci >= 0) && (ci < m->n_ciphone));
assert((lc >= 0) && (lc < m->n_ciphone));
assert((rc >= 0) && (rc < m->n_ciphone));
assert((wpos >= 0) && (wpos < N_WORD_POSN));
/* Create a context list, mapping fillers to silence. */
ctx[0] = wpos;
ctx[1] = ci;
ctx[2] = (m->sil >= 0
&& m->phone[lc].info.ci.filler) ? m->sil : lc;
ctx[3] = (m->sil >= 0
&& m->phone[rc].info.ci.filler) ? m->sil : rc;
/* Walk down the cd_tree. */
cd_tree = m->cd_tree;
level = 0; /* What level we are on. */
max = N_WORD_POSN; /* Number of nodes on this level. */
while (level < 4) {
int i;
#if 0
E_INFO("Looking for context %d=%s in %d at %d\n",
ctx[level], m->ciname[ctx[level]],
max, cd_tree - m->cd_tree);
#endif
for (i = 0; i < max; ++i) {
#if 0
E_INFO("Look at context %d=%s at %d\n",
cd_tree[i].ctx,
m->ciname[cd_tree[i].ctx], cd_tree + i - m->cd_tree);
#endif
if (cd_tree[i].ctx == ctx[level])
break;
}
if (i == max)
return -1;
#if 0
E_INFO("Found context %d=%s at %d, n_down=%d, down=%d\n",
ctx[level], m->ciname[ctx[level]],
cd_tree + i - m->cd_tree,
cd_tree[i].n_down, cd_tree[i].c.down);
#endif
/* Leaf node, stop here. */
if (cd_tree[i].n_down == 0)
return cd_tree[i].c.pid;
/* Go down one level. */
max = cd_tree[i].n_down;
cd_tree = m->cd_tree + cd_tree[i].c.down;
++level;
}
/* We probably shouldn't get here. */
return -1;
}
int
bin_mdef_phone_id_nearest(bin_mdef_t * m, int32 b, int32 l, int32 r, int32 pos)
{
int p, tmppos;
/* In the future, we might back off when context is not available,
* but for now we'll just return the CI phone. */
if (l < 0 || r < 0)
return b;
p = bin_mdef_phone_id(m, b, l, r, pos);
if (p >= 0)
return p;
/* Exact triphone not found; backoff to other word positions */
for (tmppos = 0; tmppos < N_WORD_POSN; tmppos++) {
if (tmppos != pos) {
p = bin_mdef_phone_id(m, b, l, r, tmppos);
if (p >= 0)
return p;
}
}
/* Nothing yet; backoff to silence phone if non-silence filler context */
/* In addition, backoff to silence phone on left/right if in beginning/end position */
if (m->sil >= 0) {
int newl = l, newr = r;
if (m->phone[(int)l].info.ci.filler
|| pos == WORD_POSN_BEGIN || pos == WORD_POSN_SINGLE)
newl = m->sil;
if (m->phone[(int)r].info.ci.filler
|| pos == WORD_POSN_END || pos == WORD_POSN_SINGLE)
newr = m->sil;
if ((newl != l) || (newr != r)) {
p = bin_mdef_phone_id(m, b, newl, newr, pos);
if (p >= 0)
return p;
for (tmppos = 0; tmppos < N_WORD_POSN; tmppos++) {
if (tmppos != pos) {
p = bin_mdef_phone_id(m, b, newl, newr, tmppos);
if (p >= 0)
return p;
}
}
}
}
/* Nothing yet; backoff to base phone */
return b;
}
int
bin_mdef_phone_str(bin_mdef_t * m, int pid, char *buf)
{
char *wpos_name;
assert(m);
assert((pid >= 0) && (pid < m->n_phone));
wpos_name = WPOS_NAME;
buf[0] = '\0';
if (pid < m->n_ciphone)
sprintf(buf, "%s", bin_mdef_ciphone_str(m, pid));
else {
sprintf(buf, "%s %s %s %c",
bin_mdef_ciphone_str(m, m->phone[pid].info.cd.ctx[0]),
bin_mdef_ciphone_str(m, m->phone[pid].info.cd.ctx[1]),
bin_mdef_ciphone_str(m, m->phone[pid].info.cd.ctx[2]),
wpos_name[m->phone[pid].info.cd.wpos]);
}
return 0;
}

View File

@ -0,0 +1,236 @@
/* -*- c-file-style: "linux" -*- */
/* ====================================================================
* Copyright (c) 2005 Carnegie Mellon University. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. 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 work was supported in part by funding from the Defense Advanced
* Research Projects Agency and the National Science Foundation of the
* United States of America, and the CMU Sphinx Speech Consortium.
*
* THIS SOFTWARE IS PROVIDED BY CARNEGIE MELLON UNIVERSITY ``AS IS'' AND
* ANY EXPRESSED 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 CARNEGIE MELLON UNIVERSITY
* NOR ITS EMPLOYEES 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.
*
* ====================================================================
*
*/
/**
* @file bin_mdef.h
*
* Binary format model definition files, with support for
* heterogeneous topologies and variable-size N-phones
*
* @author David Huggins-Daines <dhuggins@cs.cmu.edu>
*/
#ifndef __BIN_MDEF_H__
#define __BIN_MDEF_H__
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/* SphinxBase headers. */
#include <sphinxbase/mmio.h>
#include <sphinxbase/cmd_ln.h>
#include <pocketsphinx_export.h>
#include "mdef.h"
#define BIN_MDEF_FORMAT_VERSION 1
/* Little-endian machines will write "BMDF" to disk, big-endian ones "FDMB". */
#define BIN_MDEF_NATIVE_ENDIAN 0x46444d42 /* 'BMDF' in little-endian order */
#define BIN_MDEF_OTHER_ENDIAN 0x424d4446 /* 'BMDF' in big-endian order */
#ifdef __GNUC__
#define __ATTRIBUTE_PACKED __attribute__((packed))
#else
#define __ATTRIBUTE_PACKED
#endif
/**
* Phone entry (on-disk, 12 bytes)
*/
typedef struct mdef_entry_s mdef_entry_t;
struct mdef_entry_s {
int32 ssid; /**< Senone sequence ID */
int32 tmat; /**< Transition matrix ID */
/* FIXME: is any of this actually necessary? */
union {
/**< CI phone information - attributes (just "filler" for now) */
struct {
uint8 filler;
uint8 reserved[3];
} ci;
/**< CD phone information - context info. */
struct {
uint8 wpos;
uint8 ctx[3]; /**< quintphones will require hacking */
} cd;
} info;
} __ATTRIBUTE_PACKED;
/**
* Invalid senone sequence ID (limited to 16 bits for PocketSphinx).
*/
#define BAD_SSID 0xffff
/**
* Invalid senone ID (limited to 16 bits for PocketSphinx).
*/
#define BAD_SENID 0xffff
/**
* Node in CD phone tree (on-disk, 8 bytes).
*/
typedef struct cd_tree_s cd_tree_t;
struct cd_tree_s {
int16 ctx; /**< Context (word position or CI phone) */
int16 n_down; /**< Number of children (0 for leafnode) */
union {
int32 pid; /**< Phone ID (leafnode) */
int32 down; /**< Next level of the tree (offset from start of cd_trees) */
} c;
};
/**
* Model definition structure (in-memory).
*/
typedef struct bin_mdef_s bin_mdef_t;
struct bin_mdef_s {
int refcnt;
int32 n_ciphone; /**< Number of base (CI) phones */
int32 n_phone; /**< Number of base (CI) phones + (CD) triphones */
int32 n_emit_state; /**< Number of emitting states per phone (0 for heterogeneous) */
int32 n_ci_sen; /**< Number of CI senones; these are the first */
int32 n_sen; /**< Number of senones (CI+CD) */
int32 n_tmat; /**< Number of transition matrices */
int32 n_sseq; /**< Number of unique senone sequences */
int32 n_ctx; /**< Number of phones of context */
int32 n_cd_tree; /**< Number of nodes in cd_tree (below) */
int16 sil; /**< CI phone ID for silence */
mmio_file_t *filemap;/**< File map for this file (if any) */
char **ciname; /**< CI phone names */
cd_tree_t *cd_tree; /**< Tree mapping CD phones to phone IDs */
mdef_entry_t *phone; /**< All phone structures */
uint16 **sseq; /**< Unique senone sequences (2D array built at load time) */
uint8 *sseq_len; /**< Number of states in each sseq (NULL for homogeneous) */
/* These two are not stored on disk, but are generated at load time. */
int16 *cd2cisen; /**< Parent CI-senone id for each senone */
int16 *sen2cimap; /**< Parent CI-phone for each senone (CI or CD) */
/** Allocation mode for this object. */
enum { BIN_MDEF_FROM_TEXT, BIN_MDEF_IN_MEMORY, BIN_MDEF_ON_DISK } alloc_mode;
};
#define bin_mdef_is_fillerphone(m,p) (((p) < (m)->n_ciphone) \
? (m)->phone[p].info.ci.filler \
: (m)->phone[(m)->phone[p].info.cd.ctx[0]].info.ci.filler)
#define bin_mdef_is_ciphone(m,p) ((p) < (m)->n_ciphone)
#define bin_mdef_n_ciphone(m) ((m)->n_ciphone)
#define bin_mdef_n_phone(m) ((m)->n_phone)
#define bin_mdef_n_sseq(m) ((m)->n_sseq)
#define bin_mdef_n_emit_state(m) ((m)->n_emit_state)
#define bin_mdef_n_emit_state_phone(m,p) ((m)->n_emit_state ? (m)->n_emit_state \
: (m)->sseq_len[(m)->phone[p].ssid])
#define bin_mdef_n_sen(m) ((m)->n_sen)
#define bin_mdef_n_tmat(m) ((m)->n_tmat)
#define bin_mdef_pid2ssid(m,p) ((m)->phone[p].ssid)
#define bin_mdef_pid2tmatid(m,p) ((m)->phone[p].tmat)
#define bin_mdef_silphone(m) ((m)->sil)
#define bin_mdef_sen2cimap(m,s) ((m)->sen2cimap[s])
#define bin_mdef_sseq2sen(m,ss,pos) ((m)->sseq[ss][pos])
#define bin_mdef_pid2ci(m,p) (((p) < (m)->n_ciphone) ? (p) \
: (m)->phone[p].info.cd.ctx[0])
/**
* Read a binary mdef from a file.
*/
POCKETSPHINX_EXPORT
bin_mdef_t *bin_mdef_read(cmd_ln_t *config, const char *filename);
/**
* Read a text mdef from a file (creating an in-memory binary mdef).
*/
POCKETSPHINX_EXPORT
bin_mdef_t *bin_mdef_read_text(cmd_ln_t *config, const char *filename);
/**
* Write a binary mdef to a file.
*/
POCKETSPHINX_EXPORT
int bin_mdef_write(bin_mdef_t *m, const char *filename);
/**
* Write a binary mdef to a text file.
*/
POCKETSPHINX_EXPORT
int bin_mdef_write_text(bin_mdef_t *m, const char *filename);
/**
* Retain a pointer to a bin_mdef_t.
*/
bin_mdef_t *bin_mdef_retain(bin_mdef_t *m);
/**
* Release a pointer to a binary mdef.
*/
int bin_mdef_free(bin_mdef_t *m);
/**
* Context-independent phone lookup.
* @return phone id for ciphone.
*/
int bin_mdef_ciphone_id(bin_mdef_t *m, /**< In: Model structure being queried */
const char *ciphone); /**< In: ciphone for which id wanted */
/**
* Case-insensitive context-independent phone lookup.
* @return phone id for ciphone.
*/
int bin_mdef_ciphone_id_nocase(bin_mdef_t *m, /**< In: Model structure being queried */
const char *ciphone); /**< In: ciphone for which id wanted */
/* Return value: READ-ONLY ciphone string name for the given ciphone id */
const char *bin_mdef_ciphone_str(bin_mdef_t *m, /**< In: Model structure being queried */
int32 ci); /**< In: ciphone id for which name wanted */
/* Return value: phone id for the given constituents if found, else -1 */
int bin_mdef_phone_id(bin_mdef_t *m, /**< In: Model structure being queried */
int32 b, /**< In: base ciphone id */
int32 l, /**< In: left context ciphone id */
int32 r, /**< In: right context ciphone id */
int32 pos); /**< In: Word position */
/* Look up a phone id, backing off to other word positions. */
int bin_mdef_phone_id_nearest(bin_mdef_t * m, int32 b,
int32 l, int32 r, int32 pos);
/**
* Create a phone string for the given phone (base or triphone) id in the given buf.
*
* @return 0 if successful, -1 if error.
*/
int bin_mdef_phone_str(bin_mdef_t *m, /**< In: Model structure being queried */
int pid, /**< In: phone id being queried */
char *buf); /**< Out: On return, buf has the string */
#ifdef __cplusplus
}; /* extern "C" */
#endif /* __cplusplus */
#endif /* __BIN_MDEF_H__ */

View File

@ -0,0 +1,172 @@
/* -*- c-basic-offset: 4; indent-tabs-mode: nil -*- */
/* ====================================================================
* Copyright (c) 1999-2004 Carnegie Mellon University. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. 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 CARNEGIE MELLON UNIVERSITY ``AS IS'' AND
* ANY EXPRESSED 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 CARNEGIE MELLON UNIVERSITY
* NOR ITS EMPLOYEES 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.
*
* ====================================================================
*
*/
/*
* blkarray_list.c -- block array-based list structure.
*
* HISTORY
*
* 18-Feb-2004 M K Ravishankar (rkm@cs.cmu.edu) at Carnegie Mellon
* Started.
*/
/* System headers. */
#include <assert.h>
/* SphinxBase headers. */
#include <sphinxbase/prim_type.h>
#include <sphinxbase/err.h>
#include <sphinxbase/ckd_alloc.h>
/* Local headers. */
#include "blkarray_list.h"
#define BLKARRAY_DEFAULT_MAXBLKS 16380
#define BLKARRAY_DEFAULT_BLKSIZE 16380
blkarray_list_t *
_blkarray_list_init(int32 maxblks, int32 blksize)
{
blkarray_list_t *bl;
if ((maxblks <= 0) || (blksize <= 0)) {
E_ERROR("Cannot allocate %dx%d blkarray\n", maxblks, blksize);
return NULL;
}
bl = (blkarray_list_t *) ckd_calloc(1, sizeof(blkarray_list_t));
bl->ptr = (void ***) ckd_calloc(maxblks, sizeof(void **));
bl->maxblks = maxblks;
bl->blksize = blksize;
bl->n_valid = 0;
bl->cur_row = -1; /* No row is allocated (dummy) */
bl->cur_row_free = blksize; /* The dummy row is full */
return bl;
}
blkarray_list_t *
blkarray_list_init(void)
{
return _blkarray_list_init(BLKARRAY_DEFAULT_MAXBLKS,
BLKARRAY_DEFAULT_BLKSIZE);
}
void
blkarray_list_free(blkarray_list_t *bl)
{
blkarray_list_reset(bl);
ckd_free(bl->ptr);
ckd_free(bl);
}
int32
blkarray_list_append(blkarray_list_t * bl, void *data)
{
int32 id;
assert(bl);
if (bl->cur_row_free >= bl->blksize) {
/* Previous row is filled; need to allocate a new row */
bl->cur_row++;
if (bl->cur_row >= bl->maxblks) {
E_ERROR("Block array (%dx%d) exhausted\n",
bl->maxblks, bl->blksize);
bl->cur_row--;
return -1;
}
/* Allocate the new row */
assert(bl->ptr[bl->cur_row] == NULL);
bl->ptr[bl->cur_row] = (void **) ckd_malloc(bl->blksize *
sizeof(void *));
bl->cur_row_free = 0;
}
bl->ptr[bl->cur_row][bl->cur_row_free] = data;
(bl->cur_row_free)++;
id = (bl->n_valid)++;
assert(id >= 0);
return id;
}
void
blkarray_list_reset(blkarray_list_t * bl)
{
int32 i, j;
/* Free all the allocated elements as well as the blocks */
for (i = 0; i < bl->cur_row; i++) {
for (j = 0; j < bl->blksize; j++)
ckd_free(bl->ptr[i][j]);
ckd_free(bl->ptr[i]);
bl->ptr[i] = NULL;
}
if (i == bl->cur_row) { /* NEED THIS! (in case cur_row < 0) */
for (j = 0; j < bl->cur_row_free; j++)
ckd_free(bl->ptr[i][j]);
ckd_free(bl->ptr[i]);
bl->ptr[i] = NULL;
}
bl->n_valid = 0;
bl->cur_row = -1;
bl->cur_row_free = bl->blksize;
}
void *
blkarray_list_get(blkarray_list_t *list, int32 n)
{
int32 r, c;
if (n >= blkarray_list_n_valid(list))
return NULL;
r = n / blkarray_list_blksize(list);
c = n - (r * blkarray_list_blksize(list));
return blkarray_list_ptr(list, r, c);
}

View File

@ -0,0 +1,139 @@
/* ====================================================================
* Copyright (c) 1999-2004 Carnegie Mellon University. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. 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 CARNEGIE MELLON UNIVERSITY ``AS IS'' AND
* ANY EXPRESSED 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 CARNEGIE MELLON UNIVERSITY
* NOR ITS EMPLOYEES 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.
*
* ====================================================================
*
*/
/*
* blkarray_list.h -- array-based list structure, for memory and access
* efficiency.
*
* HISTORY
*
* $Log: blkarray_list.h,v $
* Revision 1.1.1.1 2006/05/23 18:45:02 dhuggins
* re-importation
*
* Revision 1.2 2004/12/10 16:48:58 rkm
* Added continuous density acoustic model handling
*
* Revision 1.1 2004/07/16 00:57:12 egouvea
* Added Ravi's implementation of FSG support.
*
* Revision 1.2 2004/05/27 14:22:57 rkm
* FSG cross-word triphones completed (but for single-phone words)
*
* Revision 1.1.1.1 2004/03/01 14:30:31 rkm
*
*
* Revision 1.1 2004/02/26 01:14:48 rkm
* *** empty log message ***
*
*
* 18-Feb-2004 M K Ravishankar (rkm@cs.cmu.edu) at Carnegie Mellon
* Started.
*/
#ifndef __S2_BLKARRAY_LIST_H__
#define __S2_BLKARRAY_LIST_H__
#include <sphinxbase/prim_type.h>
/*
* For maintaining a (conceptual) "list" of pointers to arbitrary data.
* The application is responsible for knowing the true data type.
* Use an array instead of a true list for efficiency (both memory and
* speed). But use a blocked (2-D) array to allow dynamic resizing at a
* coarse grain. An entire block is allocated or freed, as appropriate.
*/
typedef struct blkarray_list_s {
void ***ptr; /* ptr[][] is the user-supplied ptr */
int32 maxblks; /* size of ptr (#rows) */
int32 blksize; /* size of ptr[] (#cols, ie, size of each row) */
int32 n_valid; /* # entries actually stored in the list */
int32 cur_row; /* The current row being that has empty entry */
int32 cur_row_free; /* First entry valid within the current row */
} blkarray_list_t;
/* Access macros */
#define blkarray_list_ptr(l,r,c) ((l)->ptr[r][c])
#define blkarray_list_maxblks(l) ((l)->maxblks)
#define blkarray_list_blksize(l) ((l)->blksize)
#define blkarray_list_n_valid(l) ((l)->n_valid)
#define blkarray_list_cur_row(l) ((l)->cur_row)
#define blkarray_list_cur_row_free(l) ((l)->cur_row_free)
/*
* Initialize and return a new blkarray_list containing an empty list
* (i.e., 0 length). Sized for the given values of maxblks and blksize.
* NOTE: (maxblks * blksize) should not overflow int32, but this is not
* checked.
* Return the allocated entry if successful, NULL if any error.
*/
blkarray_list_t *_blkarray_list_init (int32 maxblks, int32 blksize);
/*
* Like _blkarray_list_init() above, but for some default values of
* maxblks and blksize.
*/
blkarray_list_t *blkarray_list_init ( void );
/**
* Completely finalize a blkarray_list.
*/
void blkarray_list_free(blkarray_list_t *bl);
/*
* Append the given new entry (data) to the end of the list.
* Return the index of the entry if successful, -1 if any error.
* The returned indices are guaranteed to be successive integers (i.e.,
* 0, 1, 2...) for successive append operations, until the list is reset,
* when they resume from 0.
*/
int32 blkarray_list_append (blkarray_list_t *, void *data);
/*
* Free all the entries in the list (using ckd_free) and reset the
* list length to 0.
*/
void blkarray_list_reset (blkarray_list_t *);
/* Gets n-th element of the array list */
void * blkarray_list_get(blkarray_list_t *, int32 n);
#endif

View File

@ -0,0 +1,505 @@
/* -*- c-basic-offset: 4; indent-tabs-mode: nil -*- */
/* ====================================================================
* Copyright (c) 1999-2004 Carnegie Mellon University. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. 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 work was supported in part by funding from the Defense Advanced
* Research Projects Agency and the National Science Foundation of the
* United States of America, and the CMU Sphinx Speech Consortium.
*
* THIS SOFTWARE IS PROVIDED BY CARNEGIE MELLON UNIVERSITY ``AS IS'' AND
* ANY EXPRESSED 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 CARNEGIE MELLON UNIVERSITY
* NOR ITS EMPLOYEES 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.
*
* ====================================================================
*
*/
/* System headers. */
#include <string.h>
/* SphinxBase headers. */
#include <sphinxbase/pio.h>
#include <sphinxbase/strfuncs.h>
/* Local headers. */
#include "dict.h"
#define DELIM " \t\n" /* Set of field separator characters */
#define DEFAULT_NUM_PHONE (MAX_S3CIPID+1)
#if WIN32
#define snprintf sprintf_s
#endif
extern const char *const cmu6_lts_phone_table[];
static s3cipid_t
dict_ciphone_id(dict_t * d, const char *str)
{
if (d->nocase)
return bin_mdef_ciphone_id_nocase(d->mdef, str);
else
return bin_mdef_ciphone_id(d->mdef, str);
}
const char *
dict_ciphone_str(dict_t * d, s3wid_t wid, int32 pos)
{
assert(d != NULL);
assert((wid >= 0) && (wid < d->n_word));
assert((pos >= 0) && (pos < d->word[wid].pronlen));
return bin_mdef_ciphone_str(d->mdef, d->word[wid].ciphone[pos]);
}
s3wid_t
dict_add_word(dict_t * d, char const *word, s3cipid_t const * p, int32 np)
{
int32 len;
dictword_t *wordp;
s3wid_t newwid;
char *wword;
if (d->n_word >= d->max_words) {
E_INFO("Reallocating to %d KiB for word entries\n",
(d->max_words + S3DICT_INC_SZ) * sizeof(dictword_t) / 1024);
d->word =
(dictword_t *) ckd_realloc(d->word,
(d->max_words +
S3DICT_INC_SZ) * sizeof(dictword_t));
d->max_words = d->max_words + S3DICT_INC_SZ;
}
wordp = d->word + d->n_word;
wordp->word = (char *) ckd_salloc(word); /* Freed in dict_free */
/* Determine base/alt wids */
wword = ckd_salloc(word);
if ((len = dict_word2basestr(wword)) > 0) {
int32 w;
/* Truncated to a baseword string; find its ID */
if (hash_table_lookup_int32(d->ht, wword, &w) < 0) {
E_ERROR("Missing base word for: %s\n", word);
ckd_free(wword);
ckd_free(wordp->word);
wordp->word = NULL;
return BAD_S3WID;
}
/* Link into alt list */
wordp->basewid = w;
wordp->alt = d->word[w].alt;
d->word[w].alt = d->n_word;
} else {
wordp->alt = BAD_S3WID;
wordp->basewid = d->n_word;
}
ckd_free(wword);
/* Associate word string with d->n_word in hash table */
if (hash_table_enter_int32(d->ht, wordp->word, d->n_word) != d->n_word) {
ckd_free(wordp->word);
wordp->word = NULL;
return BAD_S3WID;
}
/* Fill in word entry, and set defaults */
if (p && (np > 0)) {
wordp->ciphone = (s3cipid_t *) ckd_malloc(np * sizeof(s3cipid_t)); /* Freed in dict_free */
memcpy(wordp->ciphone, p, np * sizeof(s3cipid_t));
wordp->pronlen = np;
}
else {
wordp->ciphone = NULL;
wordp->pronlen = 0;
}
newwid = d->n_word++;
return newwid;
}
static int32
dict_read(FILE * fp, dict_t * d)
{
lineiter_t *li;
char **wptr;
s3cipid_t *p;
int32 lineno, nwd;
s3wid_t w;
int32 i, maxwd;
size_t stralloc, phnalloc;
maxwd = 512;
p = (s3cipid_t *) ckd_calloc(maxwd + 4, sizeof(*p));
wptr = (char **) ckd_calloc(maxwd, sizeof(char *)); /* Freed below */
lineno = 0;
stralloc = phnalloc = 0;
for (li = lineiter_start(fp); li; li = lineiter_next(li)) {
lineno++;
if (0 == strncmp(li->buf, "##", 2)
|| 0 == strncmp(li->buf, ";;", 2))
continue;
if ((nwd = str2words(li->buf, wptr, maxwd)) < 0) {
/* Increase size of p, wptr. */
nwd = str2words(li->buf, NULL, 0);
assert(nwd > maxwd); /* why else would it fail? */
maxwd = nwd;
p = (s3cipid_t *) ckd_realloc(p, (maxwd + 4) * sizeof(*p));
wptr = (char **) ckd_realloc(wptr, maxwd * sizeof(*wptr));
}
if (nwd == 0) /* Empty line */
continue;
/* wptr[0] is the word-string and wptr[1..nwd-1] the pronunciation sequence */
if (nwd == 1) {
E_ERROR("Line %d: No pronunciation for word '%s'; ignored\n",
lineno, wptr[0]);
continue;
}
/* Convert pronunciation string to CI-phone-ids */
for (i = 1; i < nwd; i++) {
p[i - 1] = dict_ciphone_id(d, wptr[i]);
if (NOT_S3CIPID(p[i - 1])) {
E_ERROR("Line %d: Phone '%s' is mising in the acoustic model; word '%s' ignored\n",
lineno, wptr[i], wptr[0]);
break;
}
}
if (i == nwd) { /* All CI-phones successfully converted to IDs */
w = dict_add_word(d, wptr[0], p, nwd - 1);
if (NOT_S3WID(w))
E_ERROR
("Line %d: Failed to add the word '%s' (duplicate?); ignored\n",
lineno, wptr[0]);
else {
stralloc += strlen(d->word[w].word);
phnalloc += d->word[w].pronlen * sizeof(s3cipid_t);
}
}
}
E_INFO("Allocated %d KiB for strings, %d KiB for phones\n",
(int)stralloc / 1024, (int)phnalloc / 1024);
ckd_free(p);
ckd_free(wptr);
return 0;
}
int
dict_write(dict_t *dict, char const *filename, char const *format)
{
FILE *fh;
int i;
if ((fh = fopen(filename, "w")) == NULL) {
E_ERROR_SYSTEM("Failed to open '%s'", filename);
return -1;
}
for (i = 0; i < dict->n_word; ++i) {
char *phones;
int j, phlen;
if (!dict_real_word(dict, i))
continue;
for (phlen = j = 0; j < dict_pronlen(dict, i); ++j)
phlen += strlen(dict_ciphone_str(dict, i, j)) + 1;
phones = ckd_calloc(1, phlen);
for (j = 0; j < dict_pronlen(dict, i); ++j) {
strcat(phones, dict_ciphone_str(dict, i, j));
if (j != dict_pronlen(dict, i) - 1)
strcat(phones, " ");
}
fprintf(fh, "%-30s %s\n", dict_wordstr(dict, i), phones);
ckd_free(phones);
}
fclose(fh);
return 0;
}
dict_t *
dict_init(cmd_ln_t *config, bin_mdef_t * mdef)
{
FILE *fp, *fp2;
int32 n;
lineiter_t *li;
dict_t *d;
s3cipid_t sil;
char const *dictfile = NULL, *fillerfile = NULL;
if (config) {
dictfile = cmd_ln_str_r(config, "-dict");
fillerfile = cmd_ln_str_r(config, "-fdict");
}
/*
* First obtain #words in dictionary (for hash table allocation).
* Reason: The PC NT system doesn't like to grow memory gradually. Better to allocate
* all the required memory in one go.
*/
fp = NULL;
n = 0;
if (dictfile) {
if ((fp = fopen(dictfile, "r")) == NULL) {
E_ERROR_SYSTEM("Failed to open dictionary file '%s' for reading", dictfile);
return NULL;
}
for (li = lineiter_start(fp); li; li = lineiter_next(li)) {
if (0 != strncmp(li->buf, "##", 2)
&& 0 != strncmp(li->buf, ";;", 2))
n++;
}
fseek(fp, 0L, SEEK_SET);
}
fp2 = NULL;
if (fillerfile) {
if ((fp2 = fopen(fillerfile, "r")) == NULL) {
E_ERROR_SYSTEM("Failed to open filler dictionary file '%s' for reading", fillerfile);
fclose(fp);
return NULL;
}
for (li = lineiter_start(fp2); li; li = lineiter_next(li)) {
if (0 != strncmp(li->buf, "##", 2)
&& 0 != strncmp(li->buf, ";;", 2))
n++;
}
fseek(fp2, 0L, SEEK_SET);
}
/*
* Allocate dict entries. HACK!! Allow some extra entries for words not in file.
* Also check for type size restrictions.
*/
d = (dict_t *) ckd_calloc(1, sizeof(dict_t)); /* freed in dict_free() */
d->refcnt = 1;
d->max_words =
(n + S3DICT_INC_SZ < MAX_S3WID) ? n + S3DICT_INC_SZ : MAX_S3WID;
if (n >= MAX_S3WID) {
E_ERROR("Number of words in dictionaries (%d) exceeds limit (%d)\n", n,
MAX_S3WID);
fclose(fp);
fclose(fp2);
ckd_free(d);
return NULL;
}
E_INFO("Allocating %d * %d bytes (%d KiB) for word entries\n",
d->max_words, sizeof(dictword_t),
d->max_words * sizeof(dictword_t) / 1024);
d->word = (dictword_t *) ckd_calloc(d->max_words, sizeof(dictword_t)); /* freed in dict_free() */
d->n_word = 0;
if (mdef)
d->mdef = bin_mdef_retain(mdef);
/* Create new hash table for word strings; case-insensitive word strings */
if (config && cmd_ln_exists_r(config, "-dictcase"))
d->nocase = cmd_ln_boolean_r(config, "-dictcase");
d->ht = hash_table_new(d->max_words, d->nocase);
/* Digest main dictionary file */
if (fp) {
E_INFO("Reading main dictionary: %s\n", dictfile);
dict_read(fp, d);
fclose(fp);
E_INFO("%d words read\n", d->n_word);
}
if (dict_wordid(d, S3_START_WORD) != BAD_S3WID) {
E_ERROR("Remove sentence start word '<s>' from the dictionary\n");
dict_free(d);
return NULL;
}
if (dict_wordid(d, S3_FINISH_WORD) != BAD_S3WID) {
E_ERROR("Remove sentence start word '</s>' from the dictionary\n");
dict_free(d);
return NULL;
}
if (dict_wordid(d, S3_SILENCE_WORD) != BAD_S3WID) {
E_ERROR("Remove silence word '<sil>' from the dictionary\n");
dict_free(d);
return NULL;
}
/* Now the filler dictionary file, if it exists */
d->filler_start = d->n_word;
if (fillerfile) {
E_INFO("Reading filler dictionary: %s\n", fillerfile);
dict_read(fp2, d);
fclose(fp2);
E_INFO("%d words read\n", d->n_word - d->filler_start);
}
if (mdef)
sil = bin_mdef_silphone(mdef);
else
sil = 0;
if (dict_wordid(d, S3_START_WORD) == BAD_S3WID) {
dict_add_word(d, S3_START_WORD, &sil, 1);
}
if (dict_wordid(d, S3_FINISH_WORD) == BAD_S3WID) {
dict_add_word(d, S3_FINISH_WORD, &sil, 1);
}
if (dict_wordid(d, S3_SILENCE_WORD) == BAD_S3WID) {
dict_add_word(d, S3_SILENCE_WORD, &sil, 1);
}
d->filler_end = d->n_word - 1;
/* Initialize distinguished word-ids */
d->startwid = dict_wordid(d, S3_START_WORD);
d->finishwid = dict_wordid(d, S3_FINISH_WORD);
d->silwid = dict_wordid(d, S3_SILENCE_WORD);
if ((d->filler_start > d->filler_end)
|| (!dict_filler_word(d, d->silwid))) {
E_ERROR("Word '%s' must occur (only) in filler dictionary\n",
S3_SILENCE_WORD);
dict_free(d);
return NULL;
}
/* No check that alternative pronunciations for filler words are in filler range!! */
return d;
}
s3wid_t
dict_wordid(dict_t *d, const char *word)
{
int32 w;
assert(d);
assert(word);
if (hash_table_lookup_int32(d->ht, word, &w) < 0)
return (BAD_S3WID);
return w;
}
int
dict_filler_word(dict_t *d, s3wid_t w)
{
assert(d);
assert((w >= 0) && (w < d->n_word));
w = dict_basewid(d, w);
if ((w == d->startwid) || (w == d->finishwid))
return 0;
if ((w >= d->filler_start) && (w <= d->filler_end))
return 1;
return 0;
}
int
dict_real_word(dict_t *d, s3wid_t w)
{
assert(d);
assert((w >= 0) && (w < d->n_word));
w = dict_basewid(d, w);
if ((w == d->startwid) || (w == d->finishwid))
return 0;
if ((w >= d->filler_start) && (w <= d->filler_end))
return 0;
return 1;
}
int32
dict_word2basestr(char *word)
{
int32 i, len;
len = strlen(word);
if (word[len - 1] == ')') {
for (i = len - 2; (i > 0) && (word[i] != '('); --i);
if (i > 0) {
/* The word is of the form <baseword>(...); strip from left-paren */
word[i] = '\0';
return i;
}
}
return -1;
}
dict_t *
dict_retain(dict_t *d)
{
++d->refcnt;
return d;
}
int
dict_free(dict_t * d)
{
int i;
dictword_t *word;
if (d == NULL)
return 0;
if (--d->refcnt > 0)
return d->refcnt;
/* First Step, free all memory allocated for each word */
for (i = 0; i < d->n_word; i++) {
word = (dictword_t *) & (d->word[i]);
if (word->word)
ckd_free((void *) word->word);
if (word->ciphone)
ckd_free((void *) word->ciphone);
}
if (d->word)
ckd_free((void *) d->word);
if (d->ht)
hash_table_free(d->ht);
if (d->mdef)
bin_mdef_free(d->mdef);
ckd_free((void *) d);
return 0;
}
void
dict_report(dict_t * d)
{
E_INFO_NOFN("Initialization of dict_t, report:\n");
E_INFO_NOFN("Max word: %d\n", d->max_words);
E_INFO_NOFN("No of word: %d\n", d->n_word);
E_INFO_NOFN("\n");
}

View File

@ -0,0 +1,210 @@
/* -*- c-basic-offset: 4; indent-tabs-mode: nil -*- */
/* ====================================================================
* Copyright (c) 1999-2004 Carnegie Mellon University. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. 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 work was supported in part by funding from the Defense Advanced
* Research Projects Agency and the National Science Foundation of the
* United States of America, and the CMU Sphinx Speech Consortium.
*
* THIS SOFTWARE IS PROVIDED BY CARNEGIE MELLON UNIVERSITY ``AS IS'' AND
* ANY EXPRESSED 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 CARNEGIE MELLON UNIVERSITY
* NOR ITS EMPLOYEES 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.
*
* ====================================================================
*
*/
#ifndef _S3_DICT_H_
#define _S3_DICT_H_
/** \file dict.h
* \brief Operations on dictionary.
*/
/* SphinxBase headers. */
#include <sphinxbase/hash_table.h>
/* Local headers. */
#include "s3types.h"
#include "bin_mdef.h"
#include "pocketsphinx_export.h"
#define S3DICT_INC_SZ 4096
#ifdef __cplusplus
extern "C" {
#endif
/**
\struct dictword_t
\brief a structure for one dictionary word.
*/
typedef struct {
char *word; /**< Ascii word string */
s3cipid_t *ciphone; /**< Pronunciation */
int32 pronlen; /**< Pronunciation length */
s3wid_t alt; /**< Next alternative pronunciation id, NOT_S3WID if none */
s3wid_t basewid; /**< Base pronunciation id */
} dictword_t;
/**
\struct dict_t
\brief a structure for a dictionary.
*/
typedef struct {
int refcnt;
bin_mdef_t *mdef; /**< Model definition used for phone IDs; NULL if none used */
dictword_t *word; /**< Array of entries in dictionary */
hash_table_t *ht; /**< Hash table for mapping word strings to word ids */
int32 max_words; /**< #Entries allocated in dict, including empty slots */
int32 n_word; /**< #Occupied entries in dict; ie, excluding empty slots */
int32 filler_start; /**< First filler word id (read from filler dict) */
int32 filler_end; /**< Last filler word id (read from filler dict) */
s3wid_t startwid; /**< FOR INTERNAL-USE ONLY */
s3wid_t finishwid; /**< FOR INTERNAL-USE ONLY */
s3wid_t silwid; /**< FOR INTERNAL-USE ONLY */
int nocase;
} dict_t;
/**
* Initialize a new dictionary.
*
* If config and mdef are supplied, then the dictionary will be read
* from the files specified by the -dict and -fdict options in config,
* with case sensitivity determined by the -dictcase option.
*
* Otherwise an empty case-sensitive dictionary will be created.
*
* Return ptr to dict_t if successful, NULL otherwise.
*/
dict_t *dict_init(cmd_ln_t *config, /**< Configuration (-dict, -fdict, -dictcase) or NULL */
bin_mdef_t *mdef /**< For looking up CI phone IDs (or NULL) */
);
/**
* Write dictionary to a file.
*/
int dict_write(dict_t *dict, char const *filename, char const *format);
/** Return word id for given word string if present. Otherwise return BAD_S3WID */
POCKETSPHINX_EXPORT
s3wid_t dict_wordid(dict_t *d, const char *word);
/**
* Return 1 if w is a filler word, 0 if not. A filler word is one that was read in from the
* filler dictionary; however, sentence START and FINISH words are not filler words.
*/
int dict_filler_word(dict_t *d, /**< The dictionary structure */
s3wid_t w /**< The word ID */
);
/**
* Test if w is a "real" word, i.e. neither a filler word nor START/FINISH.
*/
POCKETSPHINX_EXPORT
int dict_real_word(dict_t *d, /**< The dictionary structure */
s3wid_t w /**< The word ID */
);
/**
* Add a word with the given ciphone pronunciation list to the dictionary.
* Return value: Result word id if successful, BAD_S3WID otherwise
*/
s3wid_t dict_add_word(dict_t *d, /**< The dictionary structure. */
char const *word, /**< The word. */
s3cipid_t const *p, /**< The pronunciation. */
int32 np /**< Number of phones. */
);
/**
* Return value: CI phone string for the given word, phone position.
*/
const char *dict_ciphone_str(dict_t *d, /**< In: Dictionary to look up */
s3wid_t wid, /**< In: Component word being looked up */
int32 pos /**< In: Pronunciation phone position */
);
/** Packaged macro access to dictionary members */
#define dict_size(d) ((d)->n_word)
#define dict_num_fillers(d) (dict_filler_end(d) - dict_filler_start(d))
/**
* Number of "real words" in the dictionary.
*
* This is the number of words that are not fillers, <s>, or </s>.
*/
#define dict_num_real_words(d) \
(dict_size(d) - (dict_filler_end(d) - dict_filler_start(d)) - 2)
#define dict_basewid(d,w) ((d)->word[w].basewid)
#define dict_wordstr(d,w) ((w) < 0 ? NULL : (d)->word[w].word)
#define dict_basestr(d,w) ((d)->word[dict_basewid(d,w)].word)
#define dict_nextalt(d,w) ((d)->word[w].alt)
#define dict_pronlen(d,w) ((d)->word[w].pronlen)
#define dict_pron(d,w,p) ((d)->word[w].ciphone[p]) /**< The CI phones of the word w at position p */
#define dict_filler_start(d) ((d)->filler_start)
#define dict_filler_end(d) ((d)->filler_end)
#define dict_startwid(d) ((d)->startwid)
#define dict_finishwid(d) ((d)->finishwid)
#define dict_silwid(d) ((d)->silwid)
#define dict_is_single_phone(d,w) ((d)->word[w].pronlen == 1)
#define dict_first_phone(d,w) ((d)->word[w].ciphone[0])
#define dict_second_phone(d,w) ((d)->word[w].ciphone[1])
#define dict_second_last_phone(d,w) ((d)->word[w].ciphone[(d)->word[w].pronlen - 2])
#define dict_last_phone(d,w) ((d)->word[w].ciphone[(d)->word[w].pronlen - 1])
/* Hard-coded special words */
#define S3_START_WORD "<s>"
#define S3_FINISH_WORD "</s>"
#define S3_SILENCE_WORD "<sil>"
#define S3_UNKNOWN_WORD "<UNK>"
/**
* If the given word contains a trailing "(....)" (i.e., a Sphinx-II style alternative
* pronunciation specification), strip that trailing portion from it. Note that the given
* string is modified.
* Return value: If string was modified, the character position at which the original string
* was truncated; otherwise -1.
*/
int32 dict_word2basestr(char *word);
/**
* Retain a pointer to an dict_t.
*/
dict_t *dict_retain(dict_t *d);
/**
* Release a pointer to a dictionary.
*/
int dict_free(dict_t *d);
/** Report a dictionary structure */
void dict_report(dict_t *d /**< A dictionary structure */
);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,578 @@
/* -*- c-basic-offset:4; indent-tabs-mode: nil -*- */
/* ====================================================================
* Copyright (c) 1999-2004 Carnegie Mellon University. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. 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 work was supported in part by funding from the Defense Advanced
* Research Projects Agency and the National Science Foundation of the
* United States of America, and the CMU Sphinx Speech Consortium.
*
* THIS SOFTWARE IS PROVIDED BY CARNEGIE MELLON UNIVERSITY ``AS IS'' AND
* ANY EXPRESSED 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 CARNEGIE MELLON UNIVERSITY
* NOR ITS EMPLOYEES 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.
*
* ====================================================================
*
*/
#include <string.h>
#include "dict2pid.h"
#include "hmm.h"
/**
* @file dict2pid.c - dictionary word to senone sequence mappings
*/
void
compress_table(s3ssid_t * uncomp_tab, s3ssid_t * com_tab,
s3cipid_t * ci_map, int32 n_ci)
{
int32 found;
int32 r;
int32 tmp_r;
for (r = 0; r < n_ci; r++) {
com_tab[r] = BAD_S3SSID;
ci_map[r] = BAD_S3CIPID;
}
/** Compress this map */
for (r = 0; r < n_ci; r++) {
found = 0;
for (tmp_r = 0; tmp_r < r && com_tab[tmp_r] != BAD_S3SSID; tmp_r++) { /* If it appears before, just filled in cimap; */
if (uncomp_tab[r] == com_tab[tmp_r]) {
found = 1;
ci_map[r] = tmp_r;
break;
}
}
if (found == 0) {
com_tab[tmp_r] = uncomp_tab[r];
ci_map[r] = tmp_r;
}
}
}
static void
compress_right_context_tree(dict2pid_t * d2p,
s3ssid_t ***rdiph_rc)
{
int32 n_ci;
int32 b, l, r;
s3ssid_t *rmap;
s3ssid_t *tmpssid;
s3cipid_t *tmpcimap;
bin_mdef_t *mdef = d2p->mdef;
size_t alloc;
n_ci = mdef->n_ciphone;
tmpssid = ckd_calloc(n_ci, sizeof(s3ssid_t));
tmpcimap = ckd_calloc(n_ci, sizeof(s3cipid_t));
d2p->rssid =
(xwdssid_t **) ckd_calloc(mdef->n_ciphone, sizeof(xwdssid_t *));
alloc = mdef->n_ciphone * sizeof(xwdssid_t *);
for (b = 0; b < n_ci; b++) {
d2p->rssid[b] =
(xwdssid_t *) ckd_calloc(mdef->n_ciphone, sizeof(xwdssid_t));
alloc += mdef->n_ciphone * sizeof(xwdssid_t);
for (l = 0; l < n_ci; l++) {
rmap = rdiph_rc[b][l];
compress_table(rmap, tmpssid, tmpcimap, mdef->n_ciphone);
for (r = 0; r < mdef->n_ciphone && tmpssid[r] != BAD_S3SSID;
r++);
if (tmpssid[0] != BAD_S3SSID) {
d2p->rssid[b][l].ssid = ckd_calloc(r, sizeof(s3ssid_t));
memcpy(d2p->rssid[b][l].ssid, tmpssid,
r * sizeof(s3ssid_t));
d2p->rssid[b][l].cimap =
ckd_calloc(mdef->n_ciphone, sizeof(s3cipid_t));
memcpy(d2p->rssid[b][l].cimap, tmpcimap,
(mdef->n_ciphone) * sizeof(s3cipid_t));
d2p->rssid[b][l].n_ssid = r;
}
else {
d2p->rssid[b][l].ssid = NULL;
d2p->rssid[b][l].cimap = NULL;
d2p->rssid[b][l].n_ssid = 0;
}
}
}
E_INFO("Allocated %d bytes (%d KiB) for word-final triphones\n",
(int)alloc, (int)alloc / 1024);
ckd_free(tmpssid);
ckd_free(tmpcimap);
}
static void
compress_left_right_context_tree(dict2pid_t * d2p)
{
int32 n_ci;
int32 b, l, r;
s3ssid_t *rmap;
s3ssid_t *tmpssid;
s3cipid_t *tmpcimap;
bin_mdef_t *mdef = d2p->mdef;
size_t alloc;
n_ci = mdef->n_ciphone;
tmpssid = ckd_calloc(n_ci, sizeof(s3ssid_t));
tmpcimap = ckd_calloc(n_ci, sizeof(s3cipid_t));
assert(d2p->lrdiph_rc);
d2p->lrssid =
(xwdssid_t **) ckd_calloc(mdef->n_ciphone, sizeof(xwdssid_t *));
alloc = mdef->n_ciphone * sizeof(xwdssid_t *);
for (b = 0; b < n_ci; b++) {
d2p->lrssid[b] =
(xwdssid_t *) ckd_calloc(mdef->n_ciphone, sizeof(xwdssid_t));
alloc += mdef->n_ciphone * sizeof(xwdssid_t);
for (l = 0; l < n_ci; l++) {
rmap = d2p->lrdiph_rc[b][l];
compress_table(rmap, tmpssid, tmpcimap, mdef->n_ciphone);
for (r = 0; r < mdef->n_ciphone && tmpssid[r] != BAD_S3SSID;
r++);
if (tmpssid[0] != BAD_S3SSID) {
d2p->lrssid[b][l].ssid = ckd_calloc(r, sizeof(s3ssid_t));
memcpy(d2p->lrssid[b][l].ssid, tmpssid,
r * sizeof(s3ssid_t));
d2p->lrssid[b][l].cimap =
ckd_calloc(mdef->n_ciphone, sizeof(s3cipid_t));
memcpy(d2p->lrssid[b][l].cimap, tmpcimap,
(mdef->n_ciphone) * sizeof(s3cipid_t));
d2p->lrssid[b][l].n_ssid = r;
}
else {
d2p->lrssid[b][l].ssid = NULL;
d2p->lrssid[b][l].cimap = NULL;
d2p->lrssid[b][l].n_ssid = 0;
}
}
}
/* Try to compress lrdiph_rc into lrdiph_rc_compressed */
ckd_free(tmpssid);
ckd_free(tmpcimap);
E_INFO("Allocated %d bytes (%d KiB) for single-phone word triphones\n",
(int)alloc, (int)alloc / 1024);
}
/**
ARCHAN, A duplicate of get_rc_npid in ctxt_table.h. I doubt whether it is correct
because the compressed map has not been checked.
*/
int32
get_rc_nssid(dict2pid_t * d2p, s3wid_t w)
{
int32 pronlen;
s3cipid_t b, lc;
dict_t *dict = d2p->dict;
pronlen = dict->word[w].pronlen;
b = dict->word[w].ciphone[pronlen - 1];
if (pronlen == 1) {
/* Is this true ?
No known left context. But all cimaps (for any l) are identical; pick one
*/
/*E_INFO("Single phone word\n"); */
return (d2p->lrssid[b][0].n_ssid);
}
else {
/* E_INFO("Multiple phone word\n"); */
lc = dict->word[w].ciphone[pronlen - 2];
return (d2p->rssid[b][lc].n_ssid);
}
}
s3cipid_t *
dict2pid_get_rcmap(dict2pid_t * d2p, s3wid_t w)
{
int32 pronlen;
s3cipid_t b, lc;
dict_t *dict = d2p->dict;
pronlen = dict->word[w].pronlen;
b = dict->word[w].ciphone[pronlen - 1];
if (pronlen == 1) {
/* Is this true ?
No known left context. But all cimaps (for any l) are identical; pick one
*/
/*E_INFO("Single phone word\n"); */
return (d2p->lrssid[b][0].cimap);
}
else {
/* E_INFO("Multiple phone word\n"); */
lc = dict->word[w].ciphone[pronlen - 2];
return (d2p->rssid[b][lc].cimap);
}
}
static void
free_compress_map(xwdssid_t ** tree, int32 n_ci)
{
int32 b, l;
for (b = 0; b < n_ci; b++) {
for (l = 0; l < n_ci; l++) {
ckd_free(tree[b][l].ssid);
ckd_free(tree[b][l].cimap);
}
ckd_free(tree[b]);
}
ckd_free(tree);
}
static void
populate_lrdiph(dict2pid_t *d2p, s3ssid_t ***rdiph_rc, s3cipid_t b)
{
bin_mdef_t *mdef = d2p->mdef;
s3cipid_t l, r;
for (l = 0; l < bin_mdef_n_ciphone(mdef); l++) {
for (r = 0; r < bin_mdef_n_ciphone(mdef); r++) {
s3pid_t p;
p = bin_mdef_phone_id_nearest(mdef, (s3cipid_t) b,
(s3cipid_t) l,
(s3cipid_t) r,
WORD_POSN_SINGLE);
d2p->lrdiph_rc[b][l][r]
= bin_mdef_pid2ssid(mdef, p);
if (r == bin_mdef_silphone(mdef))
d2p->ldiph_lc[b][r][l]
= bin_mdef_pid2ssid(mdef, p);
if (rdiph_rc && l == bin_mdef_silphone(mdef))
rdiph_rc[b][l][r]
= bin_mdef_pid2ssid(mdef, p);
assert(IS_S3SSID(bin_mdef_pid2ssid(mdef, p)));
E_DEBUG(2,("%s(%s,%s) => %d / %d\n",
bin_mdef_ciphone_str(mdef, b),
bin_mdef_ciphone_str(mdef, l),
bin_mdef_ciphone_str(mdef, r),
p, bin_mdef_pid2ssid(mdef, p)));
}
}
}
int
dict2pid_add_word(dict2pid_t *d2p,
int32 wid)
{
bin_mdef_t *mdef = d2p->mdef;
dict_t *d = d2p->dict;
if (dict_pronlen(d, wid) > 1) {
s3cipid_t l;
/* Make sure we have left and right context diphones for this
* word. */
if (d2p->ldiph_lc[dict_first_phone(d, wid)][dict_second_phone(d, wid)][0]
== BAD_S3SSID) {
E_DEBUG(2, ("Filling in left-context diphones for %s(?,%s)\n",
bin_mdef_ciphone_str(mdef, dict_first_phone(d, wid)),
bin_mdef_ciphone_str(mdef, dict_second_phone(d, wid))));
for (l = 0; l < bin_mdef_n_ciphone(mdef); l++) {
int p
= bin_mdef_phone_id_nearest(mdef,
dict_first_phone(d, wid), l,
dict_second_phone(d, wid),
WORD_POSN_BEGIN);
d2p->ldiph_lc[dict_first_phone(d, wid)][dict_second_phone(d, wid)][l]
= bin_mdef_pid2ssid(mdef, p);
}
}
if (d2p->rssid[dict_last_phone(d, wid)][dict_second_last_phone(d, wid)].n_ssid
== 0) {
s3ssid_t *rmap;
s3ssid_t *tmpssid;
s3cipid_t *tmpcimap;
s3cipid_t r;
E_DEBUG(2, ("Filling in right-context diphones for %s(%s,?)\n",
bin_mdef_ciphone_str(mdef, dict_last_phone(d, wid)),
bin_mdef_ciphone_str(mdef, dict_second_last_phone(d, wid))));
rmap = ckd_calloc(bin_mdef_n_ciphone(mdef), sizeof(*rmap));
for (r = 0; r < bin_mdef_n_ciphone(mdef); r++) {
int p
= bin_mdef_phone_id_nearest(mdef,
dict_last_phone(d, wid),
dict_second_last_phone(d, wid), r,
WORD_POSN_END);
rmap[r] = bin_mdef_pid2ssid(mdef, p);
}
tmpssid = ckd_calloc(bin_mdef_n_ciphone(mdef), sizeof(*tmpssid));
tmpcimap = ckd_calloc(bin_mdef_n_ciphone(mdef), sizeof(*tmpcimap));
compress_table(rmap, tmpssid, tmpcimap, bin_mdef_n_ciphone(mdef));
for (r = 0; r < mdef->n_ciphone && tmpssid[r] != BAD_S3SSID; r++)
;
d2p->rssid[dict_last_phone(d, wid)][dict_second_last_phone(d, wid)].ssid = tmpssid;
d2p->rssid[dict_last_phone(d, wid)][dict_second_last_phone(d, wid)].cimap = tmpcimap;
d2p->rssid[dict_last_phone(d, wid)][dict_second_last_phone(d, wid)].n_ssid = r;
ckd_free(rmap);
}
}
else {
/* Make sure we have a left-right context triphone entry for
* this word. */
E_INFO("Filling in context triphones for %s(?,?)\n",
bin_mdef_ciphone_str(mdef, dict_first_phone(d, wid)));
if (d2p->lrdiph_rc[dict_first_phone(d, wid)][0][0] == BAD_S3SSID) {
populate_lrdiph(d2p, NULL, dict_first_phone(d, wid));
}
}
return 0;
}
s3ssid_t
dict2pid_internal(dict2pid_t *d2p,
int32 wid,
int pos)
{
int b, l, r, p;
dict_t *dict = d2p->dict;
bin_mdef_t *mdef = d2p->mdef;
if (pos == 0 || pos == dict_pronlen(dict, wid))
return BAD_S3SSID;
b = dict_pron(dict, wid, pos);
l = dict_pron(dict, wid, pos - 1);
r = dict_pron(dict, wid, pos + 1);
p = bin_mdef_phone_id_nearest(mdef, (s3cipid_t) b,
(s3cipid_t) l, (s3cipid_t) r,
WORD_POSN_INTERNAL);
return bin_mdef_pid2ssid(mdef, p);
}
dict2pid_t *
dict2pid_build(bin_mdef_t * mdef, dict_t * dict)
{
dict2pid_t *dict2pid;
s3ssid_t ***rdiph_rc;
bitvec_t *ldiph, *rdiph, *single;
int32 pronlen;
int32 b, l, r, w, p;
E_INFO("Building PID tables for dictionary\n");
assert(mdef);
assert(dict);
dict2pid = (dict2pid_t *) ckd_calloc(1, sizeof(dict2pid_t));
dict2pid->refcount = 1;
dict2pid->mdef = bin_mdef_retain(mdef);
dict2pid->dict = dict_retain(dict);
E_INFO("Allocating %d^3 * %d bytes (%d KiB) for word-initial triphones\n",
mdef->n_ciphone, sizeof(s3ssid_t),
mdef->n_ciphone * mdef->n_ciphone * mdef->n_ciphone * sizeof(s3ssid_t) / 1024);
dict2pid->ldiph_lc =
(s3ssid_t ***) ckd_calloc_3d(mdef->n_ciphone, mdef->n_ciphone,
mdef->n_ciphone, sizeof(s3ssid_t));
/* Only used internally to generate rssid */
rdiph_rc =
(s3ssid_t ***) ckd_calloc_3d(mdef->n_ciphone, mdef->n_ciphone,
mdef->n_ciphone, sizeof(s3ssid_t));
dict2pid->lrdiph_rc = (s3ssid_t ***) ckd_calloc_3d(mdef->n_ciphone,
mdef->n_ciphone,
mdef->n_ciphone,
sizeof
(s3ssid_t));
/* Actually could use memset for this, if BAD_S3SSID is guaranteed
* to be 65535... */
for (b = 0; b < mdef->n_ciphone; ++b) {
for (r = 0; r < mdef->n_ciphone; ++r) {
for (l = 0; l < mdef->n_ciphone; ++l) {
dict2pid->ldiph_lc[b][r][l] = BAD_S3SSID;
dict2pid->lrdiph_rc[b][l][r] = BAD_S3SSID;
rdiph_rc[b][l][r] = BAD_S3SSID;
}
}
}
/* Track which diphones / ciphones have been seen. */
ldiph = bitvec_alloc(mdef->n_ciphone * mdef->n_ciphone);
rdiph = bitvec_alloc(mdef->n_ciphone * mdef->n_ciphone);
single = bitvec_alloc(mdef->n_ciphone);
for (w = 0; w < dict_size(dict2pid->dict); w++) {
pronlen = dict_pronlen(dict, w);
if (pronlen >= 2) {
b = dict_first_phone(dict, w);
r = dict_second_phone(dict, w);
/* Populate ldiph_lc */
if (bitvec_is_clear(ldiph, b * mdef->n_ciphone + r)) {
/* Mark this diphone as done */
bitvec_set(ldiph, b * mdef->n_ciphone + r);
/* Record all possible ssids for b(?,r) */
for (l = 0; l < bin_mdef_n_ciphone(mdef); l++) {
p = bin_mdef_phone_id_nearest(mdef, (s3cipid_t) b,
(s3cipid_t) l, (s3cipid_t) r,
WORD_POSN_BEGIN);
dict2pid->ldiph_lc[b][r][l] = bin_mdef_pid2ssid(mdef, p);
}
}
/* Populate rdiph_rc */
l = dict_second_last_phone(dict, w);
b = dict_last_phone(dict, w);
if (bitvec_is_clear(rdiph, b * mdef->n_ciphone + l)) {
/* Mark this diphone as done */
bitvec_set(rdiph, b * mdef->n_ciphone + l);
for (r = 0; r < bin_mdef_n_ciphone(mdef); r++) {
p = bin_mdef_phone_id_nearest(mdef, (s3cipid_t) b,
(s3cipid_t) l, (s3cipid_t) r,
WORD_POSN_END);
rdiph_rc[b][l][r] = bin_mdef_pid2ssid(mdef, p);
}
}
}
else if (pronlen == 1) {
b = dict_pron(dict, w, 0);
E_DEBUG(1,("Building tables for single phone word %s phone %d = %s\n",
dict_wordstr(dict, w), b, bin_mdef_ciphone_str(mdef, b)));
/* Populate lrdiph_rc (and also ldiph_lc, rdiph_rc if needed) */
if (bitvec_is_clear(single, b)) {
populate_lrdiph(dict2pid, rdiph_rc, b);
bitvec_set(single, b);
}
}
}
bitvec_free(ldiph);
bitvec_free(rdiph);
bitvec_free(single);
/* Try to compress rdiph_rc into rdiph_rc_compressed */
compress_right_context_tree(dict2pid, rdiph_rc);
compress_left_right_context_tree(dict2pid);
ckd_free_3d(rdiph_rc);
dict2pid_report(dict2pid);
return dict2pid;
}
dict2pid_t *
dict2pid_retain(dict2pid_t *d2p)
{
++d2p->refcount;
return d2p;
}
int
dict2pid_free(dict2pid_t * d2p)
{
if (d2p == NULL)
return 0;
if (--d2p->refcount > 0)
return d2p->refcount;
if (d2p->ldiph_lc)
ckd_free_3d((void ***) d2p->ldiph_lc);
if (d2p->lrdiph_rc)
ckd_free_3d((void ***) d2p->lrdiph_rc);
if (d2p->rssid)
free_compress_map(d2p->rssid, bin_mdef_n_ciphone(d2p->mdef));
if (d2p->lrssid)
free_compress_map(d2p->lrssid, bin_mdef_n_ciphone(d2p->mdef));
bin_mdef_free(d2p->mdef);
dict_free(d2p->dict);
ckd_free(d2p);
return 0;
}
void
dict2pid_report(dict2pid_t * d2p)
{
}
void
dict2pid_dump(FILE * fp, dict2pid_t * d2p)
{
int32 w, p, pronlen;
int32 i, j, b, l, r;
bin_mdef_t *mdef = d2p->mdef;
dict_t *dict = d2p->dict;
fprintf(fp, "# INTERNAL (wd comssid ssid ssid ... ssid comssid)\n");
for (w = 0; w < dict_size(dict); w++) {
fprintf(fp, "%30s ", dict_wordstr(dict, w));
pronlen = dict_pronlen(dict, w);
for (p = 0; p < pronlen; p++)
fprintf(fp, " %5d", dict2pid_internal(d2p, w, p));
fprintf(fp, "\n");
}
fprintf(fp, "#\n");
fprintf(fp, "# LDIPH_LC (b r l ssid)\n");
for (b = 0; b < bin_mdef_n_ciphone(mdef); b++) {
for (r = 0; r < bin_mdef_n_ciphone(mdef); r++) {
for (l = 0; l < bin_mdef_n_ciphone(mdef); l++) {
if (IS_S3SSID(d2p->ldiph_lc[b][r][l]))
fprintf(fp, "%6s %6s %6s %5d\n", bin_mdef_ciphone_str(mdef, (s3cipid_t) b), bin_mdef_ciphone_str(mdef, (s3cipid_t) r), bin_mdef_ciphone_str(mdef, (s3cipid_t) l), d2p->ldiph_lc[b][r][l]); /* RAH, ldiph_lc is returning an int32, %d expects an int16 */
}
}
}
fprintf(fp, "#\n");
fprintf(fp, "# SSEQ %d (senid senid ...)\n", mdef->n_sseq);
for (i = 0; i < mdef->n_sseq; i++) {
fprintf(fp, "%5d ", i);
for (j = 0; j < bin_mdef_n_emit_state(mdef); j++)
fprintf(fp, " %5d", mdef->sseq[i][j]);
fprintf(fp, "\n");
}
fprintf(fp, "#\n");
fprintf(fp, "# END\n");
fflush(fp);
}

View File

@ -0,0 +1,180 @@
/* -*- c-basic-offset: 4; indent-tabs-mode: nil -*- */
/* ====================================================================
* Copyright (c) 1999-2014 Carnegie Mellon University. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. 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 work was supported in part by funding from the Defense Advanced
* Research Projects Agency and the National Science Foundation of the
* United States of America, and the CMU Sphinx Speech Consortium.
*
* THIS SOFTWARE IS PROVIDED BY CARNEGIE MELLON UNIVERSITY ``AS IS'' AND
* ANY EXPRESSED 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 CARNEGIE MELLON UNIVERSITY
* NOR ITS EMPLOYEES 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.
*
* ====================================================================
*
*/
#ifndef _S3_DICT2PID_H_
#define _S3_DICT2PID_H_
/* System headers. */
#include <stdio.h>
/* SphinxBase headers. */
#include <sphinxbase/logmath.h>
#include <sphinxbase/bitvec.h>
/* Local headers. */
#include "s3types.h"
#include "bin_mdef.h"
#include "dict.h"
/** \file dict2pid.h
* \brief Building triphones for a dictionary.
*
* This is one of the more complicated parts of a cross-word
* triphone model decoder. The first and last phones of each word
* get their left and right contexts, respectively, from other
* words. For single-phone words, both its contexts are from other
* words, simultaneously. As these words are not known beforehand,
* life gets complicated.
*/
#ifdef __cplusplus
extern "C" {
#endif
/**
* \struct xwdssid_t
* \brief cross word triphone model structure
*/
typedef struct {
s3ssid_t *ssid; /**< Senone Sequence ID list for all context ciphones */
s3cipid_t *cimap; /**< Index into ssid[] above for each ci phone */
int32 n_ssid; /**< #Unique ssid in above, compressed ssid list */
} xwdssid_t;
/**
\struct dict2pid_t
\brief Building composite triphone (as well as word internal triphones) with the dictionary.
*/
typedef struct {
int refcount;
bin_mdef_t *mdef; /**< Model definition, used to generate
internal ssids on the fly. */
dict_t *dict; /**< Dictionary this table refers to. */
/*Notice the order of the arguments */
/* FIXME: This is crying out for compression - in Mandarin we have
* 180 context independent phones, which makes this an 11MB
* array. */
s3ssid_t ***ldiph_lc; /**< For multi-phone words, [base][rc][lc] -> ssid; filled out for
word-initial base x rc combinations in current vocabulary */
xwdssid_t **rssid; /**< Right context state sequence id table
First dimension: base phone,
Second dimension: left context.
*/
s3ssid_t ***lrdiph_rc; /**< For single-phone words, [base][lc][rc] -> ssid; filled out for
single-phone base x lc combinations in current vocabulary */
xwdssid_t **lrssid; /**< Left-Right context state sequence id table
First dimension: base phone,
Second dimension: left context.
*/
} dict2pid_t;
/** Access macros; not designed for arbitrary use */
#define dict2pid_rssid(d,ci,lc) (&(d)->rssid[ci][lc])
#define dict2pid_ldiph_lc(d,b,r,l) ((d)->ldiph_lc[b][r][l])
#define dict2pid_lrdiph_rc(d,b,l,r) ((d)->lrdiph_rc[b][l][r])
/**
* Build the dict2pid structure for the given model/dictionary
*/
dict2pid_t *dict2pid_build(bin_mdef_t *mdef, /**< A model definition*/
dict_t *dict /**< An initialized dictionary */
);
/**
* Retain a pointer to dict2pid
*/
dict2pid_t *dict2pid_retain(dict2pid_t *d2p);
/**
* Free the memory dict2pid structure
*/
int dict2pid_free(dict2pid_t *d2p /**< In: the d2p */
);
/**
* Return the senone sequence ID for the given word position.
*/
s3ssid_t dict2pid_internal(dict2pid_t *d2p,
int32 wid,
int pos);
/**
* Add a word to the dict2pid structure (after adding it to dict).
*/
int dict2pid_add_word(dict2pid_t *d2p,
int32 wid);
/**
* For debugging
*/
void dict2pid_dump(FILE *fp, /**< In: a file pointer */
dict2pid_t *d2p /**< In: a dict2pid_t structure */
);
/** Report a dict2pid data structure */
void dict2pid_report(dict2pid_t *d2p /**< In: a dict2pid_t structure */
);
/**
* Get number of rc
*/
int32 get_rc_nssid(dict2pid_t *d2p, /**< In: a dict2pid */
s3wid_t w /**< In: a wid */
);
/**
* Get RC map
*/
s3cipid_t* dict2pid_get_rcmap(dict2pid_t *d2p, /**< In: a dict2pid */
s3wid_t w /**< In: a wid */
);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,317 @@
/* -*- c-basic-offset: 4; indent-tabs-mode: nil -*- */
/* ====================================================================
* Copyright (c) 1999-2004 Carnegie Mellon University. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. 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 CARNEGIE MELLON UNIVERSITY ``AS IS'' AND
* ANY EXPRESSED 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 CARNEGIE MELLON UNIVERSITY
* NOR ITS EMPLOYEES 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.
*
* ====================================================================
*
*/
/*
* fsg_history.c -- FSG Viterbi decode history
*
* **********************************************
* CMU ARPA Speech Project
*
* Copyright (c) 1999 Carnegie Mellon University.
* ALL RIGHTS RESERVED.
* **********************************************
*
* HISTORY
*
* 25-Feb-2004 M K Ravishankar (rkm@cs.cmu.edu) at Carnegie Mellon University
* Started..
*/
/* System headers. */
#include <assert.h>
/* SphinxBase headers. */
#include <sphinxbase/prim_type.h>
#include <sphinxbase/err.h>
#include <sphinxbase/ckd_alloc.h>
/* Local headers. */
#include "fsg_search_internal.h"
#include "fsg_history.h"
#define __FSG_DBG__ 0
fsg_history_t *
fsg_history_init(fsg_model_t * fsg, dict_t *dict)
{
fsg_history_t *h;
h = (fsg_history_t *) ckd_calloc(1, sizeof(fsg_history_t));
h->fsg = fsg;
h->entries = blkarray_list_init();
if (fsg && dict) {
h->n_ciphone = bin_mdef_n_ciphone(dict->mdef);
h->frame_entries =
(glist_t **) ckd_calloc_2d(fsg_model_n_state(fsg),
bin_mdef_n_ciphone(dict->mdef),
sizeof(**h->frame_entries));
}
else {
h->frame_entries = NULL;
}
return h;
}
void
fsg_history_free(fsg_history_t *h)
{
int32 s, lc, ns, np;
gnode_t *gn;
if (h->fsg) {
ns = fsg_model_n_state(h->fsg);
np = h->n_ciphone;
for (s = 0; s < ns; s++) {
for (lc = 0; lc < np; lc++) {
for (gn = h->frame_entries[s][lc]; gn; gn = gnode_next(gn)) {
ckd_free(gnode_ptr(gn));
}
glist_free(h->frame_entries[s][lc]);
}
}
}
ckd_free_2d(h->frame_entries);
blkarray_list_free(h->entries);
ckd_free(h);
}
void
fsg_history_set_fsg(fsg_history_t *h, fsg_model_t *fsg, dict_t *dict)
{
if (blkarray_list_n_valid(h->entries) != 0) {
E_WARN("Switching FSG while history not empty; history cleared\n");
blkarray_list_reset(h->entries);
}
if (h->frame_entries)
ckd_free_2d((void **) h->frame_entries);
h->frame_entries = NULL;
h->fsg = fsg;
if (fsg && dict) {
h->n_ciphone = bin_mdef_n_ciphone(dict->mdef);
h->frame_entries =
(glist_t **) ckd_calloc_2d(fsg_model_n_state(fsg),
bin_mdef_n_ciphone(dict->mdef),
sizeof(glist_t));
}
}
void
fsg_history_entry_add(fsg_history_t * h,
fsg_link_t * link,
int32 frame, int32 score, int32 pred,
int32 lc, fsg_pnode_ctxt_t rc)
{
fsg_hist_entry_t *entry, *new_entry;
int32 s;
gnode_t *gn, *prev_gn;
/* Skip the optimization for the initial dummy entries; always enter them */
if (frame < 0) {
new_entry =
(fsg_hist_entry_t *) ckd_calloc(1, sizeof(fsg_hist_entry_t));
new_entry->fsglink = link;
new_entry->frame = frame;
new_entry->score = score;
new_entry->pred = pred;
new_entry->lc = lc;
new_entry->rc = rc;
blkarray_list_append(h->entries, (void *) new_entry);
return;
}
s = fsg_link_to_state(link);
/* Locate where this entry should be inserted in frame_entries[s][lc] */
prev_gn = NULL;
for (gn = h->frame_entries[s][lc]; gn; gn = gnode_next(gn)) {
entry = (fsg_hist_entry_t *) gnode_ptr(gn);
if (score BETTER_THAN entry->score)
break; /* Found where to insert new entry */
/* Existing entry score not worse than new score */
if (FSG_PNODE_CTXT_SUB(&rc, &(entry->rc)) == 0)
return; /* rc set reduced to 0; new entry can be ignored */
prev_gn = gn;
}
/* Create new entry after prev_gn (if prev_gn is NULL, at head) */
new_entry =
(fsg_hist_entry_t *) ckd_calloc(1, sizeof(fsg_hist_entry_t));
new_entry->fsglink = link;
new_entry->frame = frame;
new_entry->score = score;
new_entry->pred = pred;
new_entry->lc = lc;
new_entry->rc = rc; /* Note: rc set must be non-empty at this point */
if (!prev_gn) {
h->frame_entries[s][lc] = glist_add_ptr(h->frame_entries[s][lc],
(void *) new_entry);
prev_gn = h->frame_entries[s][lc];
}
else
prev_gn = glist_insert_ptr(prev_gn, (void *) new_entry);
/*
* Update the rc set of all the remaining entries in the list. At this
* point, gn is the entry, if any, immediately following new entry.
*/
while (gn) {
entry = (fsg_hist_entry_t *) gnode_ptr(gn);
if (FSG_PNODE_CTXT_SUB(&(entry->rc), &rc) == 0) {
/* rc set of entry reduced to 0; can prune this entry */
ckd_free((void *) entry);
gn = gnode_free(gn, prev_gn);
}
else {
prev_gn = gn;
gn = gnode_next(gn);
}
}
}
/*
* Transfer the surviving history entries for this frame into the permanent
* history table.
*/
void
fsg_history_end_frame(fsg_history_t * h)
{
int32 s, lc, ns, np;
gnode_t *gn;
fsg_hist_entry_t *entry;
ns = fsg_model_n_state(h->fsg);
np = h->n_ciphone;
for (s = 0; s < ns; s++) {
for (lc = 0; lc < np; lc++) {
for (gn = h->frame_entries[s][lc]; gn; gn = gnode_next(gn)) {
entry = (fsg_hist_entry_t *) gnode_ptr(gn);
blkarray_list_append(h->entries, (void *) entry);
}
glist_free(h->frame_entries[s][lc]);
h->frame_entries[s][lc] = NULL;
}
}
}
fsg_hist_entry_t *
fsg_history_entry_get(fsg_history_t * h, int32 id)
{
return ((fsg_hist_entry_t *) blkarray_list_get(h->entries, id));
}
void
fsg_history_reset(fsg_history_t * h)
{
blkarray_list_reset(h->entries);
}
int32
fsg_history_n_entries(fsg_history_t * h)
{
return (blkarray_list_n_valid(h->entries));
}
void
fsg_history_utt_start(fsg_history_t * h)
{
int32 s, lc, ns, np;
assert(blkarray_list_n_valid(h->entries) == 0);
assert(h->frame_entries);
ns = fsg_model_n_state(h->fsg);
np = h->n_ciphone;
for (s = 0; s < ns; s++) {
for (lc = 0; lc < np; lc++) {
assert(h->frame_entries[s][lc] == NULL);
}
}
}
void
fsg_history_utt_end(fsg_history_t * h)
{
}
void
fsg_history_print(fsg_history_t *h, dict_t *dict)
{
int bpidx, bp;
for (bpidx = 0; bpidx < blkarray_list_n_valid(h->entries); bpidx++) {
bp = bpidx;
printf("History entry: ");
while (bp > 0) {
fsg_hist_entry_t *hist_entry = fsg_history_entry_get(h, bp);
fsg_link_t *fl = fsg_hist_entry_fsglink(hist_entry);
char const *baseword;
int32 wid;
bp = fsg_hist_entry_pred(hist_entry);
wid = fsg_link_wid(fl);
if (fl == NULL)
continue;
baseword = fsg_model_word_str(h->fsg, wid);
printf("%s(%d->%d:%d) ", baseword,
fsg_link_from_state(hist_entry->fsglink),
fsg_link_to_state(hist_entry->fsglink),
hist_entry->frame);
}
printf("\n");
}
}

View File

@ -0,0 +1,215 @@
/* -*- c-basic-offset: 4; indent-tabs-mode: nil -*- */
/* ====================================================================
* Copyright (c) 1999-2004 Carnegie Mellon University. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. 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 CARNEGIE MELLON UNIVERSITY ``AS IS'' AND
* ANY EXPRESSED 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 CARNEGIE MELLON UNIVERSITY
* NOR ITS EMPLOYEES 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.
*
* ====================================================================
*
*/
/*
* fsg_history.h -- FSG Viterbi decode history
*
* **********************************************
* CMU ARPA Speech Project
*
* Copyright (c) 1999 Carnegie Mellon University.
* ALL RIGHTS RESERVED.
* **********************************************
*
* HISTORY
*
* $Log: fsg_history.h,v $
* Revision 1.1.1.1 2006/05/23 18:45:02 dhuggins
* re-importation
*
* Revision 1.1 2004/07/16 00:57:12 egouvea
* Added Ravi's implementation of FSG support.
*
* Revision 1.7 2004/07/07 22:30:35 rkm
* *** empty log message ***
*
* Revision 1.6 2004/07/07 13:56:33 rkm
* Added reporting of (acoustic score - best senone score)/frame
*
* Revision 1.5 2004/06/25 14:49:08 rkm
* Optimized size of history table and speed of word transitions by maintaining only best scoring word exits at each state
*
* Revision 1.4 2004/06/23 20:32:16 rkm
* *** empty log message ***
*
* Revision 1.3 2004/05/27 15:16:08 rkm
* *** empty log message ***
*
*
* 25-Feb-2004 M K Ravishankar (rkm@cs.cmu.edu) at Carnegie Mellon University
* Started, based on S3.3 version.
*/
#ifndef __S2_FSG_HISTORY_H__
#define __S2_FSG_HISTORY_H__
/* SphinxBase headers. */
#include <sphinxbase/prim_type.h>
#include <sphinxbase/fsg_model.h>
/* Local headers. */
#include "blkarray_list.h"
#include "fsg_lextree.h"
#include "dict.h"
/*
* The Viterbi history structure. This is a tree, with the root at the
* FSG start state, at frame 0, with a null predecessor.
*/
/*
* A single Viterbi history entry
*/
typedef struct fsg_hist_entry_s {
fsg_link_t *fsglink; /* Link taken result in this entry */
int32 score; /* Total path score at the end of this
transition */
int32 pred; /* Predecessor entry; -1 if none */
frame_idx_t frame; /* Ending frame for this entry */
int16 lc; /* Left context provided by this entry to
succeeding words */
fsg_pnode_ctxt_t rc; /* Possible right contexts to which this entry
applies */
} fsg_hist_entry_t;
/* Access macros */
#define fsg_hist_entry_fsglink(v) ((v)->fsglink)
#define fsg_hist_entry_frame(v) ((v)->frame)
#define fsg_hist_entry_score(v) ((v)->score)
#define fsg_hist_entry_pred(v) ((v)->pred)
#define fsg_hist_entry_lc(v) ((v)->lc)
#define fsg_hist_entry_rc(v) ((v)->rc)
/*
* The entire tree of history entries (fsg_history_t.entries).
* Optimization: In a given frame, there may be several history entries, with
* the same left and right phonetic context, terminating in a particular state.
* Only the best scoring one of these needs to be saved, since everything else
* will be pruned according to the Viterbi algorithm. frame_entries is used
* temporarily in each frame to determine these best scoring entries in that
* frame. Only the ones not pruned are transferred to entries at the end of
* the frame. However, null transitions are a problem since they create
* entries that depend on entries created in the CURRENT frame. Hence, this
* pruning is done in two stages: first for the non-null transitions, and then
* for the null transitions alone. (This solution is sub-optimal, and can be
* improved with a little more work. SMOP.)
* Why is frame_entries a list? Each entry has a unique terminating state,
* and has a unique lc CIphone. But it has a SET of rc CIphones.
* frame_entries[s][lc] is an ordered list of entries created in the current
* frame, terminating in state s, and with left context lc. The list is in
* descending order of path score. When a new entry with (s,lc) arrives,
* its position in the list is determined. Then its rc set is modified by
* subtracting the union of the rc's of all its predecessors (i.e., better
* scoring entries). If the resulting rc set is empty, the entry is discarded.
* Otherwise, it is inserted, and the rc sets of all downstream entries in the
* list are updated by subtracting the new entry's rc. If any of them becomes
* empty, it is also discarded.
* As mentioned earlier, this procedure is applied in two stages, for the
* non-null transitions, and the null transitions, separately.
*/
typedef struct fsg_history_s {
fsg_model_t *fsg; /* The FSG for which this object applies */
blkarray_list_t *entries; /* A list of history table entries; the root
entry is the first element of the list */
glist_t **frame_entries;
int n_ciphone;
} fsg_history_t;
/*
* One-time intialization: Allocate and return an initially empty history
* module.
*/
fsg_history_t *fsg_history_init(fsg_model_t *fsg, dict_t *dict);
void fsg_history_utt_start(fsg_history_t *h);
void fsg_history_utt_end(fsg_history_t *h);
/*
* Create a history entry recording the completion of the given FSG
* transition, at the end of the given frame, with the given score, and
* the given predecessor history entry.
* The entry is initially temporary, and may be superseded by another
* with a higher score. The surviving entries must be transferred to
* the main history table, via fsg_history_end_frame().
*/
void fsg_history_entry_add (fsg_history_t *h,
fsg_link_t *l, /* FSG transition */
int32 frame,
int32 score,
int32 pred,
int32 lc,
fsg_pnode_ctxt_t rc);
/*
* Transfer the surviving history entries for this frame into the permanent
* history table. This function can be called several times during a frame.
* Each time, the entries surviving so far are transferred, and the temporary
* lists cleared. This feature is used to handle the entries due to non-null
* transitions and null transitions separately.
*/
void fsg_history_end_frame (fsg_history_t *h);
/* Clear the hitory table */
void fsg_history_reset (fsg_history_t *h);
/* Return the number of valid entries in the given history table */
int32 fsg_history_n_entries (fsg_history_t *h);
/*
* Return a ptr to the history entry for the given ID; NULL if there is no
* such entry.
*/
fsg_hist_entry_t *fsg_history_entry_get(fsg_history_t *h, int32 id);
/*
* Switch the FSG associated with the given history module. Should be done
* when the history list is empty. If not empty, the list is cleared.
*/
void fsg_history_set_fsg (fsg_history_t *h, fsg_model_t *fsg, dict_t *dict);
/* Free the given Viterbi search history object */
void fsg_history_free (fsg_history_t *h);
/* Print the entire history */
void fsg_history_print(fsg_history_t *h, dict_t *dict);
#endif

View File

@ -0,0 +1,835 @@
/* -*- c-basic-offset: 4; indent-tabs-mode: nil -*- */
/* ====================================================================
* Copyright (c) 1999-2010 Carnegie Mellon University. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. 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 CARNEGIE MELLON UNIVERSITY ``AS IS'' AND
* ANY EXPRESSED 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 CARNEGIE MELLON UNIVERSITY
* NOR ITS EMPLOYEES 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.
*
* ====================================================================
*
*/
/**
* @file fsg_lextree.c
* @brief The collection of all the lextrees for the entire FSM.
* @author M K Ravishankar <rkm@cs.cmu.edu>
* @author Bhiksha Raj <bhiksha@cs.cmu.edu>
*/
/* System headers. */
#include <stdio.h>
#include <string.h>
#include <assert.h>
/* SphinxBase headers. */
#include <sphinxbase/ckd_alloc.h>
#include <sphinxbase/err.h>
/* Local headers. */
#include "fsg_lextree.h"
#define __FSG_DBG__ 0
/* A linklist structure that is actually used to build local lextrees at grammar nodes */
typedef struct fsg_glist_linklist_t {
int32 ci, rc;
glist_t glist;
struct fsg_glist_linklist_t *next;
} fsg_glist_linklist_t;
/**
* Build the phone lextree for all transitions out of state from_state.
* Return the root node of this tree.
* Also, return a linear linked list of all allocated fsg_pnode_t nodes in
* *alloc_head (for memory management purposes).
*/
static fsg_pnode_t *fsg_psubtree_init(fsg_lextree_t *tree,
fsg_model_t *fsg,
int32 from_state,
fsg_pnode_t **alloc_head);
/**
* Free the given lextree. alloc_head: head of linear list of allocated
* nodes updated by fsg_psubtree_init().
*/
static void fsg_psubtree_free(fsg_pnode_t *alloc_head);
/**
* Dump the list of nodes in the given lextree to the given file. alloc_head:
* head of linear list of allocated nodes updated by fsg_psubtree_init().
*/
static void fsg_psubtree_dump(fsg_lextree_t *tree, fsg_pnode_t *root, FILE *fp);
/**
* Compute the left and right context CIphone sets for each state.
*/
static void
fsg_lextree_lc_rc(fsg_lextree_t *lextree)
{
int32 s, i, j;
int32 n_ci;
fsg_model_t *fsg;
int32 silcipid;
int32 len;
silcipid = bin_mdef_silphone(lextree->mdef);
assert(silcipid >= 0);
n_ci = bin_mdef_n_ciphone(lextree->mdef);
fsg = lextree->fsg;
/*
* lextree->lc[s] = set of left context CIphones for state s. Similarly, rc[s]
* for right context CIphones.
*/
lextree->lc = ckd_calloc_2d(fsg->n_state, n_ci + 1, sizeof(**lextree->lc));
lextree->rc = ckd_calloc_2d(fsg->n_state, n_ci + 1, sizeof(**lextree->rc));
E_INFO("Allocated %d bytes (%d KiB) for left and right context phones\n",
fsg->n_state * (n_ci + 1) * 2,
fsg->n_state * (n_ci + 1) * 2 / 1024);
for (s = 0; s < fsg->n_state; s++) {
fsg_arciter_t *itor;
for (itor = fsg_model_arcs(fsg, s); itor; itor = fsg_arciter_next(itor)) {
fsg_link_t *l = fsg_arciter_get(itor);
int32 dictwid; /**< Dictionary (not FSG) word ID!! */
if (fsg_link_wid(l) >= 0) {
dictwid = dict_wordid(lextree->dict,
fsg_model_word_str(lextree->fsg, l->wid));
/*
* Add the first CIphone of l->wid to the rclist of state s, and
* the last CIphone to lclist of state d.
* (Filler phones are a pain to deal with. There is no direct
* marking of a filler phone; but only filler words are supposed to
* use such phones, so we use that fact. HACK!! FRAGILE!!)
*
* UPD: tests carsh here if .fsg model used with wrong hmm and
* dictionary
*/
if (fsg_model_is_filler(fsg, fsg_link_wid(l))) {
/* Filler phone; use silence phone as context */
lextree->rc[fsg_link_from_state(l)][silcipid] = 1;
lextree->lc[fsg_link_to_state(l)][silcipid] = 1;
}
else {
len = dict_pronlen(lextree->dict, dictwid);
lextree->rc[fsg_link_from_state(l)][dict_pron(lextree->dict, dictwid, 0)] = 1;
lextree->lc[fsg_link_to_state(l)][dict_pron(lextree->dict, dictwid, len - 1)] = 1;
}
}
}
}
for (s = 0; s < fsg->n_state; s++) {
/*
* Add SIL phone to the lclist and rclist of each state. Strictly
* speaking, only needed at start and final states, respectively, but
* all states considered since the user may change the start and final
* states. In any case, most applications would have a silence self
* loop at each state, hence these would be needed anyway.
*/
lextree->lc[s][silcipid] = 1;
lextree->rc[s][silcipid] = 1;
}
/*
* Propagate lc and rc lists past null transitions. (Since FSG contains
* null transitions closure, no need to worry about a chain of successive
* null transitions. Right??)
*
* This can't be joined with the previous loop because we first calculate
* contexts and only then we can propagate them.
*/
for (s = 0; s < fsg->n_state; s++) {
fsg_arciter_t *itor;
for (itor = fsg_model_arcs(fsg, s); itor; itor = fsg_arciter_next(itor)) {
fsg_link_t *l = fsg_arciter_get(itor);
if (fsg_link_wid(l) < 0) {
/*
* lclist(d) |= lclist(s), because all the words ending up at s, can
* now also end at d, becoming the left context for words leaving d.
*/
for (i = 0; i < n_ci; i++)
lextree->lc[fsg_link_to_state(l)][i] |= lextree->lc[fsg_link_from_state(l)][i];
/*
* Similarly, rclist(s) |= rclist(d), because all the words leaving d
* can equivalently leave s, becoming the right context for words
* ending up at s.
*/
for (i = 0; i < n_ci; i++)
lextree->rc[fsg_link_from_state(l)][i] |= lextree->rc[fsg_link_to_state(l)][i];
}
}
}
/* Convert the bit-vector representation into a list */
for (s = 0; s < fsg->n_state; s++) {
j = 0;
for (i = 0; i < n_ci; i++) {
if (lextree->lc[s][i]) {
lextree->lc[s][j] = i;
j++;
}
}
lextree->lc[s][j] = -1; /* Terminate the list */
j = 0;
for (i = 0; i < n_ci; i++) {
if (lextree->rc[s][i]) {
lextree->rc[s][j] = i;
j++;
}
}
lextree->rc[s][j] = -1; /* Terminate the list */
}
}
/*
* For now, allocate the entire lextree statically.
*/
fsg_lextree_t *
fsg_lextree_init(fsg_model_t * fsg, dict_t *dict, dict2pid_t *d2p,
bin_mdef_t *mdef, hmm_context_t *ctx,
int32 wip, int32 pip)
{
int32 s, n_leaves;
fsg_lextree_t *lextree;
fsg_pnode_t *pn;
lextree = ckd_calloc(1, sizeof(fsg_lextree_t));
lextree->fsg = fsg;
lextree->root = ckd_calloc(fsg_model_n_state(fsg),
sizeof(fsg_pnode_t *));
lextree->alloc_head = ckd_calloc(fsg_model_n_state(fsg),
sizeof(fsg_pnode_t *));
lextree->ctx = ctx;
lextree->dict = dict;
lextree->d2p = d2p;
lextree->mdef = mdef;
lextree->wip = wip;
lextree->pip = pip;
/* Compute lc and rc for fsg. */
fsg_lextree_lc_rc(lextree);
/* Create lextree for each state, i.e. an HMM network that
* represents words for all arcs exiting that state. Note that
* for a dense grammar such as an N-gram model, this will
* rapidly exhaust all available memory. */
lextree->n_pnode = 0;
n_leaves = 0;
for (s = 0; s < fsg_model_n_state(fsg); s++) {
lextree->root[s] =
fsg_psubtree_init(lextree, fsg, s, &(lextree->alloc_head[s]));
for (pn = lextree->alloc_head[s]; pn; pn = pn->alloc_next) {
lextree->n_pnode++;
if (pn->leaf)
++n_leaves;
}
}
E_INFO("%d HMM nodes in lextree (%d leaves)\n",
lextree->n_pnode, n_leaves);
E_INFO("Allocated %d bytes (%d KiB) for all lextree nodes\n",
lextree->n_pnode * sizeof(fsg_pnode_t),
lextree->n_pnode * sizeof(fsg_pnode_t) / 1024);
E_INFO("Allocated %d bytes (%d KiB) for lextree leafnodes\n",
n_leaves * sizeof(fsg_pnode_t),
n_leaves * sizeof(fsg_pnode_t) / 1024);
#if __FSG_DBG__
fsg_lextree_dump(lextree, stdout);
#endif
return lextree;
}
void
fsg_lextree_dump(fsg_lextree_t * lextree, FILE * fp)
{
int32 s;
for (s = 0; s < fsg_model_n_state(lextree->fsg); s++) {
fprintf(fp, "State %5d root %p\n", s, lextree->root[s]);
fsg_psubtree_dump(lextree, lextree->root[s], fp);
}
fflush(fp);
}
void
fsg_lextree_free(fsg_lextree_t * lextree)
{
int32 s;
if (lextree == NULL)
return;
if (lextree->fsg)
for (s = 0; s < fsg_model_n_state(lextree->fsg); s++)
fsg_psubtree_free(lextree->alloc_head[s]);
ckd_free_2d(lextree->lc);
ckd_free_2d(lextree->rc);
ckd_free(lextree->root);
ckd_free(lextree->alloc_head);
ckd_free(lextree);
}
/******************************
* psubtree stuff starts here *
******************************/
void fsg_glist_linklist_free(fsg_glist_linklist_t *glist)
{
if (glist) {
fsg_glist_linklist_t *nxtglist;
if (glist->glist)
glist_free(glist->glist);
nxtglist = glist->next;
while (nxtglist) {
ckd_free(glist);
glist = nxtglist;
if (glist->glist)
glist_free(glist->glist);
nxtglist = glist->next;
}
ckd_free(glist);
}
return;
}
void
fsg_pnode_add_all_ctxt(fsg_pnode_ctxt_t * ctxt)
{
int32 i;
for (i = 0; i < FSG_PNODE_CTXT_BVSZ; i++)
ctxt->bv[i] = 0xffffffff;
}
uint32 fsg_pnode_ctxt_sub_generic(fsg_pnode_ctxt_t *src, fsg_pnode_ctxt_t *sub)
{
int32 i;
uint32 res = 0;
for (i = 0; i < FSG_PNODE_CTXT_BVSZ; i++)
res |= (src->bv[i] = ~(sub->bv[i]) & src->bv[i]);
return res;
}
/*
* fsg_pnode_ctxt_sub(fsg_pnode_ctxt_t * src, fsg_pnode_ctxt_t * sub)
* This has been moved into a macro in fsg_psubtree.h
* because it is called so frequently!
*/
/*
* Add the word emitted by the given transition (fsglink) to the given lextree
* (rooted at root), and return the new lextree root. (There may actually be
* several root nodes, maintained in a linked list via fsg_pnode_t.sibling.
* "root" is the head of this list.)
* lclist, rclist: sets of left and right context phones for this link.
* alloc_head: head of a linear list of all allocated pnodes for the parent
* FSG state, kept elsewhere and updated by this routine.
*/
static fsg_pnode_t *
psubtree_add_trans(fsg_lextree_t *lextree,
fsg_pnode_t * root,
fsg_glist_linklist_t **curglist,
fsg_link_t * fsglink,
int16 *lclist, int16 *rclist,
fsg_pnode_t ** alloc_head)
{
int32 silcipid; /* Silence CI phone ID */
int32 pronlen; /* Pronunciation length */
int32 wid; /* FSG (not dictionary!!) word ID */
int32 dictwid; /* Dictionary (not FSG!!) word ID */
int32 ssid; /* Senone Sequence ID */
int32 tmatid;
gnode_t *gn;
fsg_pnode_t *pnode, *pred, *head;
int32 n_ci, p, lc, rc;
glist_t lc_pnodelist; /* Temp pnodes list for different left contexts */
glist_t rc_pnodelist; /* Temp pnodes list for different right contexts */
int32 i, j;
int n_lc_alloc = 0, n_int_alloc = 0, n_rc_alloc = 0;
silcipid = bin_mdef_silphone(lextree->mdef);
n_ci = bin_mdef_n_ciphone(lextree->mdef);
wid = fsg_link_wid(fsglink);
assert(wid >= 0); /* Cannot be a null transition */
dictwid = dict_wordid(lextree->dict,
fsg_model_word_str(lextree->fsg, wid));
pronlen = dict_pronlen(lextree->dict, dictwid);
assert(pronlen >= 1);
assert(lclist[0] >= 0); /* At least one phonetic context provided */
assert(rclist[0] >= 0);
head = *alloc_head;
pred = NULL;
if (pronlen == 1) { /* Single-phone word */
int ci = dict_first_phone(lextree->dict, dictwid);
/* Only non-filler words are mpx */
if (!dict_filler_word(lextree->dict, dictwid)) {
/*
* Left diphone ID for single-phone words already assumes SIL is right
* context; only left contexts need to be handled.
*/
lc_pnodelist = NULL;
for (i = 0; lclist[i] >= 0; i++) {
lc = lclist[i];
ssid = dict2pid_lrdiph_rc(lextree->d2p, ci, lc, silcipid);
tmatid = bin_mdef_pid2tmatid(lextree->mdef, dict_first_phone(lextree->dict, dictwid));
/* Check if this ssid already allocated for some other context */
for (gn = lc_pnodelist; gn; gn = gnode_next(gn)) {
pnode = (fsg_pnode_t *) gnode_ptr(gn);
if (hmm_nonmpx_ssid(&pnode->hmm) == ssid) {
/* already allocated; share it for this context phone */
fsg_pnode_add_ctxt(pnode, lc);
break;
}
}
if (!gn) { /* ssid not already allocated */
pnode =
(fsg_pnode_t *) ckd_calloc(1, sizeof(fsg_pnode_t));
pnode->ctx = lextree->ctx;
pnode->next.fsglink = fsglink;
pnode->logs2prob =
(fsg_link_logs2prob(fsglink) >> SENSCR_SHIFT)
+ lextree->wip + lextree->pip;
pnode->ci_ext = dict_first_phone(lextree->dict, dictwid);
pnode->ppos = 0;
pnode->leaf = TRUE;
pnode->sibling = root; /* All root nodes linked together */
fsg_pnode_add_ctxt(pnode, lc); /* Initially zeroed by calloc above */
pnode->alloc_next = head;
head = pnode;
root = pnode;
++n_lc_alloc;
hmm_init(lextree->ctx, &pnode->hmm, FALSE, ssid, tmatid);
lc_pnodelist =
glist_add_ptr(lc_pnodelist, (void *) pnode);
}
}
glist_free(lc_pnodelist);
}
else { /* Filler word; no context modelled */
ssid = bin_mdef_pid2ssid(lextree->mdef, ci); /* probably the same... */
tmatid = bin_mdef_pid2tmatid(lextree->mdef, ci);
pnode = (fsg_pnode_t *) ckd_calloc(1, sizeof(fsg_pnode_t));
pnode->ctx = lextree->ctx;
pnode->next.fsglink = fsglink;
pnode->logs2prob = (fsg_link_logs2prob(fsglink) >> SENSCR_SHIFT)
+ lextree->wip + lextree->pip;
pnode->ci_ext = silcipid; /* Presents SIL as context to neighbors */
pnode->ppos = 0;
pnode->leaf = TRUE;
pnode->sibling = root;
fsg_pnode_add_all_ctxt(&(pnode->ctxt));
pnode->alloc_next = head;
head = pnode;
root = pnode;
++n_int_alloc;
hmm_init(lextree->ctx, &pnode->hmm, FALSE, ssid, tmatid);
}
}
else { /* Multi-phone word */
fsg_pnode_t **ssid_pnode_map; /* Temp array of ssid->pnode mapping */
ssid_pnode_map =
(fsg_pnode_t **) ckd_calloc(n_ci, sizeof(fsg_pnode_t *));
lc_pnodelist = NULL;
rc_pnodelist = NULL;
for (p = 0; p < pronlen; p++) {
int ci = dict_pron(lextree->dict, dictwid, p);
if (p == 0) { /* Root phone, handle required left contexts */
/* Find if we already have an lc_pnodelist for the first phone of this word */
fsg_glist_linklist_t *glist;
rc = dict_pron(lextree->dict, dictwid, 1);
for (glist = *curglist;
glist && glist->glist;
glist = glist->next) {
if (glist->ci == ci && glist->rc == rc)
break;
}
if (glist && glist->glist) {
assert(glist->ci == ci && glist->rc == rc);
/* We've found a valid glist. Hook to it and move to next phoneme */
E_DEBUG(2,("Found match for (%d,%d)\n", ci, rc));
lc_pnodelist = glist->glist;
/* Set the predecessor node for the future tree first */
pred = (fsg_pnode_t *) gnode_ptr(lc_pnodelist);
continue;
}
else {
/* Two cases that can bring us here
* a. glist == NULL, i.e. end of current list. Create new entry.
* b. glist->glist == NULL, i.e. first entry into list.
*/
if (glist == NULL) { /* Case a; reduce it to case b by allocing glist */
glist = (fsg_glist_linklist_t*) ckd_calloc(1, sizeof(fsg_glist_linklist_t));
glist->next = *curglist;
*curglist = glist;
}
glist->ci = ci;
glist->rc = rc;
lc_pnodelist = glist->glist = NULL; /* Gets created below */
}
for (i = 0; lclist[i] >= 0; i++) {
lc = lclist[i];
ssid = dict2pid_ldiph_lc(lextree->d2p, ci, rc, lc);
tmatid = bin_mdef_pid2tmatid(lextree->mdef, dict_first_phone(lextree->dict, dictwid));
/* Compression is not done by d2p, so we do it
* here. This might be slow, but it might not
* be... we'll see. */
pnode = ssid_pnode_map[0];
for (j = 0; j < n_ci && ssid_pnode_map[j] != NULL; ++j) {
pnode = ssid_pnode_map[j];
if (hmm_nonmpx_ssid(&pnode->hmm) == ssid)
break;
}
assert(j < n_ci);
if (!pnode) { /* Allocate pnode for this new ssid */
pnode =
(fsg_pnode_t *) ckd_calloc(1,
sizeof
(fsg_pnode_t));
pnode->ctx = lextree->ctx;
/* This bit is tricky! For now we'll put the prob in the final link only */
/* pnode->logs2prob = (fsg_link_logs2prob(fsglink) >> SENSCR_SHIFT)
+ lextree->wip + lextree->pip; */
pnode->logs2prob = lextree->wip + lextree->pip;
pnode->ci_ext = dict_first_phone(lextree->dict, dictwid);
pnode->ppos = 0;
pnode->leaf = FALSE;
pnode->sibling = root; /* All root nodes linked together */
pnode->alloc_next = head;
head = pnode;
root = pnode;
++n_lc_alloc;
hmm_init(lextree->ctx, &pnode->hmm, FALSE, ssid, tmatid);
lc_pnodelist =
glist_add_ptr(lc_pnodelist, (void *) pnode);
ssid_pnode_map[j] = pnode;
}
fsg_pnode_add_ctxt(pnode, lc);
}
/* Put the lc_pnodelist back into glist */
glist->glist = lc_pnodelist;
/* The predecessor node for the future tree is the root */
pred = root;
}
else if (p != pronlen - 1) { /* Word internal phone */
fsg_pnode_t *pnodeyoungest;
ssid = dict2pid_internal(lextree->d2p, dictwid, p);
tmatid = bin_mdef_pid2tmatid(lextree->mdef, dict_pron (lextree->dict, dictwid, p));
/* First check if we already have this ssid in our tree */
pnode = pred->next.succ;
pnodeyoungest = pnode; /* The youngest sibling */
while (pnode && (hmm_nonmpx_ssid(&pnode->hmm) != ssid || pnode->leaf)) {
pnode = pnode->sibling;
}
if (pnode && (hmm_nonmpx_ssid(&pnode->hmm) == ssid && !pnode->leaf)) {
/* Found the ssid; go to next phoneme */
E_DEBUG(2,("Found match for %d\n", ci));
pred = pnode;
continue;
}
/* pnode not found, allocate it */
pnode = (fsg_pnode_t *) ckd_calloc(1, sizeof(fsg_pnode_t));
pnode->ctx = lextree->ctx;
pnode->logs2prob = lextree->pip;
pnode->ci_ext = dict_pron(lextree->dict, dictwid, p);
pnode->ppos = p;
pnode->leaf = FALSE;
pnode->sibling = pnodeyoungest; /* May be NULL */
if (p == 1) { /* Predecessor = set of root nodes for left ctxts */
for (gn = lc_pnodelist; gn; gn = gnode_next(gn)) {
pred = (fsg_pnode_t *) gnode_ptr(gn);
pred->next.succ = pnode;
}
}
else { /* Predecessor = word internal node */
pred->next.succ = pnode;
}
pnode->alloc_next = head;
head = pnode;
++n_int_alloc;
hmm_init(lextree->ctx, &pnode->hmm, FALSE, ssid, tmatid);
pred = pnode;
}
else { /* Leaf phone, handle required right contexts */
/* Note, leaf phones are not part of the tree */
xwdssid_t *rssid;
memset((void *) ssid_pnode_map, 0,
n_ci * sizeof(fsg_pnode_t *));
lc = dict_pron(lextree->dict, dictwid, p-1);
rssid = dict2pid_rssid(lextree->d2p, ci, lc);
tmatid = bin_mdef_pid2tmatid(lextree->mdef, dict_pron (lextree->dict, dictwid, p));
for (i = 0; rclist[i] >= 0; i++) {
rc = rclist[i];
j = rssid->cimap[rc];
ssid = rssid->ssid[j];
pnode = ssid_pnode_map[j];
if (!pnode) { /* Allocate pnode for this new ssid */
pnode =
(fsg_pnode_t *) ckd_calloc(1,
sizeof
(fsg_pnode_t));
pnode->ctx = lextree->ctx;
/* We are plugging the word prob here. Ugly */
/* pnode->logs2prob = lextree->pip; */
pnode->logs2prob = (fsg_link_logs2prob(fsglink) >> SENSCR_SHIFT)
+ lextree->pip;
pnode->ci_ext = dict_pron(lextree->dict, dictwid, p);
pnode->ppos = p;
pnode->leaf = TRUE;
pnode->sibling = rc_pnodelist ?
(fsg_pnode_t *) gnode_ptr(rc_pnodelist) : NULL;
pnode->next.fsglink = fsglink;
pnode->alloc_next = head;
head = pnode;
++n_rc_alloc;
hmm_init(lextree->ctx, &pnode->hmm, FALSE, ssid, tmatid);
rc_pnodelist =
glist_add_ptr(rc_pnodelist, (void *) pnode);
ssid_pnode_map[j] = pnode;
}
else {
assert(hmm_nonmpx_ssid(&pnode->hmm) == ssid);
}
fsg_pnode_add_ctxt(pnode, rc);
}
if (p == 1) { /* Predecessor = set of root nodes for left ctxts */
for (gn = lc_pnodelist; gn; gn = gnode_next(gn)) {
pred = (fsg_pnode_t *) gnode_ptr(gn);
if (!pred->next.succ)
pred->next.succ = (fsg_pnode_t *) gnode_ptr(rc_pnodelist);
else {
/* Link to the end of the sibling chain */
fsg_pnode_t *succ = pred->next.succ;
while (succ->sibling) succ = succ->sibling;
succ->sibling = (fsg_pnode_t*) gnode_ptr(rc_pnodelist);
/* Since all entries of lc_pnodelist point
to the same array, sufficient to update it once */
break;
}
}
}
else { /* Predecessor = word internal node */
if (!pred->next.succ)
pred->next.succ = (fsg_pnode_t *) gnode_ptr(rc_pnodelist);
else {
/* Link to the end of the sibling chain */
fsg_pnode_t *succ = pred->next.succ;
while (succ->sibling) succ = succ->sibling;
succ->sibling = (fsg_pnode_t *) gnode_ptr(rc_pnodelist);
}
}
}
}
ckd_free((void *) ssid_pnode_map);
/* glist_free(lc_pnodelist); Nope; this gets freed outside */
glist_free(rc_pnodelist);
}
E_DEBUG(2,("Allocated %d HMMs (%d lc, %d rc, %d internal)\n",
n_lc_alloc + n_rc_alloc + n_int_alloc,
n_lc_alloc, n_rc_alloc, n_int_alloc));
*alloc_head = head;
return root;
}
static fsg_pnode_t *
fsg_psubtree_init(fsg_lextree_t *lextree,
fsg_model_t * fsg, int32 from_state,
fsg_pnode_t ** alloc_head)
{
fsg_arciter_t *itor;
fsg_link_t *fsglink;
fsg_pnode_t *root;
int32 n_ci, n_arc;
fsg_glist_linklist_t *glist = NULL;
root = NULL;
assert(*alloc_head == NULL);
n_ci = bin_mdef_n_ciphone(lextree->mdef);
if (n_ci > (FSG_PNODE_CTXT_BVSZ * 32)) {
E_FATAL
("#phones > %d; increase FSG_PNODE_CTXT_BVSZ and recompile\n",
FSG_PNODE_CTXT_BVSZ * 32);
}
n_arc = 0;
for (itor = fsg_model_arcs(fsg, from_state); itor;
itor = fsg_arciter_next(itor)) {
int32 dst;
fsglink = fsg_arciter_get(itor);
dst = fsglink->to_state;
if (fsg_link_wid(fsglink) < 0)
continue;
E_DEBUG(2,("Building lextree for arc from %d to %d: %s\n",
from_state, dst, fsg_model_word_str(fsg, fsg_link_wid(fsglink))));
root = psubtree_add_trans(lextree, root, &glist, fsglink,
lextree->lc[from_state],
lextree->rc[dst],
alloc_head);
++n_arc;
}
E_DEBUG(2,("State %d has %d outgoing arcs\n", from_state, n_arc));
fsg_glist_linklist_free(glist);
return root;
}
static void
fsg_psubtree_free(fsg_pnode_t * head)
{
fsg_pnode_t *next;
while (head) {
next = head->alloc_next;
hmm_deinit(&head->hmm);
ckd_free(head);
head = next;
}
}
void fsg_psubtree_dump_node(fsg_lextree_t *tree, fsg_pnode_t *node, FILE *fp)
{
int32 i;
fsg_link_t *tl;
/* Indentation */
for (i = 0; i <= node->ppos; i++)
fprintf(fp, " ");
fprintf(fp, "%p.@", node); /* Pointer used as node
* ID */
fprintf(fp, " %5d.SS", hmm_nonmpx_ssid(&node->hmm));
fprintf(fp, " %10d.LP", node->logs2prob);
fprintf(fp, " %p.SIB", node->sibling);
fprintf(fp, " %s.%d", bin_mdef_ciphone_str(tree->mdef, node->ci_ext), node->ppos);
if ((node->ppos == 0) || node->leaf) {
fprintf(fp, " [");
for (i = 0; i < FSG_PNODE_CTXT_BVSZ; i++)
fprintf(fp, "%08x", node->ctxt.bv[i]);
fprintf(fp, "]");
}
if (node->leaf) {
tl = node->next.fsglink;
fprintf(fp, " {%s[%d->%d](%d)}",
fsg_model_word_str(tree->fsg, tl->wid),
tl->from_state, tl->to_state, tl->logs2prob);
} else {
fprintf(fp, " %p.NXT", node->next.succ);
}
fprintf(fp, "\n");
return;
}
void
fsg_psubtree_dump(fsg_lextree_t *tree, fsg_pnode_t *root, FILE * fp)
{
fsg_pnode_t *succ;
if (root == NULL) return;
if (root->ppos == 0) {
while(root->sibling && root->sibling->next.succ == root->next.succ) {
fsg_psubtree_dump_node(tree, root, fp);
root = root->sibling;
}
fflush(fp);
}
fsg_psubtree_dump_node(tree, root, fp);
if (root->leaf) {
if (root->ppos == 0 && root->sibling) { /* For single-phone words */
fsg_psubtree_dump(tree, root->sibling,fp);
}
return;
}
succ = root->next.succ;
while(succ) {
fsg_psubtree_dump(tree, succ,fp);
succ = succ->sibling;
}
if (root->ppos == 0) {
fsg_psubtree_dump(tree, root->sibling,fp);
fflush(fp);
}
return;
}
void
fsg_psubtree_pnode_deactivate(fsg_pnode_t * pnode)
{
hmm_clear(&pnode->hmm);
}

View File

@ -0,0 +1,255 @@
/* -*- c-basic-offset: 4; indent-tabs-mode: nil -*- */
/* ====================================================================
* Copyright (c) 1999-2013 Carnegie Mellon University. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. 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 CARNEGIE MELLON UNIVERSITY ``AS IS'' AND
* ANY EXPRESSED 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 CARNEGIE MELLON UNIVERSITY
* NOR ITS EMPLOYEES 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.
*
* ====================================================================
*
*/
/*
* fsg_lextree.h -- The collection of all the lextrees for the entire FSM.
*
*/
#ifndef __S2_FSG_LEXTREE_H__
#define __S2_FSG_LEXTREE_H__
/* SphinxBase headers. */
#include <sphinxbase/cmd_ln.h>
#include <sphinxbase/fsg_model.h>
/* Local headers. */
#include "hmm.h"
#include "dict.h"
#include "dict2pid.h"
/*
* Compile-time constant determining the size of the
* bitvector fsg_pnode_t.fsg_pnode_ctxt_t.bv. (See below.)
* But it makes memory allocation simpler and more efficient.
* Make it smaller (2) to save memory if your phoneset has less than
* 64 phones.
*/
#define FSG_PNODE_CTXT_BVSZ 4
typedef struct {
uint32 bv[FSG_PNODE_CTXT_BVSZ];
} fsg_pnode_ctxt_t;
/*
* All transitions (words) out of any given FSG state represented are by a
* phonetic prefix lextree (except for epsilon or null transitions; they
* are not part of the lextree). Lextree leaf nodes represent individual
* FSG transitions, so no sharing is allowed at the leaf nodes. The FSG
* transition probs are distributed along the lextree: the prob at a node
* is the max of the probs of all leaf nodes (and, hence, FSG transitions)
* reachable from that node.
*
* To conserve memory, the underlying HMMs with state-level information are
* allocated only as needed. Root and leaf nodes must also account for all
* the possible phonetic contexts, with an independent HMM for each distinct
* context.
*/
typedef struct fsg_pnode_s {
/*
* If this is not a leaf node, the first successor (child) node. Otherwise
* the parent FSG transition for which this is the leaf node (for figuring
* the FSG destination state, and word emitted by the transition). A node
* may have several children. The succ ptr gives just the first; the rest
* are linked via the sibling ptr below.
*/
union {
struct fsg_pnode_s *succ;
fsg_link_t *fsglink;
} next;
/*
* For simplicity of memory management (i.e., freeing the pnodes), all
* pnodes allocated for all transitions out of a state are maintained in a
* linear linked list through the alloc_next pointer.
*/
struct fsg_pnode_s *alloc_next;
/*
* The next node that is also a child of the parent of this node; NULL if
* none.
*/
struct fsg_pnode_s *sibling;
/*
* The transition (log) probability to be incurred upon transitioning to
* this node. (Transition probabilities are really associated with the
* transitions. But a lextree node has exactly one incoming transition.
* Hence, the prob can be associated with the node.)
* This is a logs2(prob) value, and includes the language weight.
*/
int32 logs2prob;
/*
* The root and leaf positions associated with any transition have to deal
* with multiple phonetic contexts. However, different contexts may result
* in the same SSID (senone-seq ID), and can share a single pnode with that
* SSID. But the pnode should track the set of context CI phones that share
* it. Hence the fsg_pnode_ctxt_t bit-vector set-representation. (For
* simplicity of implementation, its size is a compile-time constant for
* now.) Single phone words would need a 2-D array of context, but that's
* too expensive. For now, they simply use SIL as right context, so only
* the left context is properly modelled.
* (For word-internal phones, this field is unused, of course.)
*/
fsg_pnode_ctxt_t ctxt;
uint16 ci_ext; /* This node's CIphone as viewed externally (context) */
uint8 ppos; /* Phoneme position in pronunciation */
uint8 leaf; /* Whether this is a leaf node */
/* HMM-state-level stuff here */
hmm_context_t *ctx;
hmm_t hmm;
} fsg_pnode_t;
/* Access macros */
#define fsg_pnode_leaf(p) ((p)->leaf)
#define fsg_pnode_logs2prob(p) ((p)->logs2prob)
#define fsg_pnode_succ(p) ((p)->next.succ)
#define fsg_pnode_fsglink(p) ((p)->next.fsglink)
#define fsg_pnode_sibling(p) ((p)->sibling)
#define fsg_pnode_hmmptr(p) (&((p)->hmm))
#define fsg_pnode_ci_ext(p) ((p)->ci_ext)
#define fsg_pnode_ppos(p) ((p)->ppos)
#define fsg_pnode_leaf(p) ((p)->leaf)
#define fsg_pnode_ctxt(p) ((p)->ctxt)
#define fsg_pnode_add_ctxt(p,c) ((p)->ctxt.bv[(c)>>5] |= (1 << ((c)&0x001f)))
/*
* The following is macroized because its called very frequently
* ::: uint32 fsg_pnode_ctxt_sub (fsg_pnode_ctxt_t *src, fsg_pnode_ctxt_t *sub);
*/
/*
* Subtract bitvector sub from bitvector src (src updated with the result).
* Return 0 if result is all 0, non-zero otherwise.
*/
#if (FSG_PNODE_CTXT_BVSZ == 1)
#define FSG_PNODE_CTXT_SUB(src,sub) \
((src)->bv[0] = (~((sub)->bv[0]) & (src)->bv[0]))
#elif (FSG_PNODE_CTXT_BVSZ == 2)
#define FSG_PNODE_CTXT_SUB(src,sub) \
(((src)->bv[0] = (~((sub)->bv[0]) & (src)->bv[0])) | \
((src)->bv[1] = (~((sub)->bv[1]) & (src)->bv[1])))
#elif (FSG_PNODE_CTXT_BVSZ == 4)
#define FSG_PNODE_CTXT_SUB(src,sub) \
(((src)->bv[0] = (~((sub)->bv[0]) & (src)->bv[0])) | \
((src)->bv[1] = (~((sub)->bv[1]) & (src)->bv[1])) | \
((src)->bv[2] = (~((sub)->bv[2]) & (src)->bv[2])) | \
((src)->bv[3] = (~((sub)->bv[3]) & (src)->bv[3])))
#else
#define FSG_PNODE_CTXT_SUB(src,sub) fsg_pnode_ctxt_sub_generic((src),(sub))
#endif
/**
* Collection of lextrees for an FSG.
*/
typedef struct fsg_lextree_s {
fsg_model_t *fsg; /**< The fsg for which this lextree is built. */
hmm_context_t *ctx; /**< HMM context structure. */
dict_t *dict; /**< Pronunciation dictionary for this FSG. */
dict2pid_t *d2p; /**< Context-dependent phone mappings for this FSG. */
bin_mdef_t *mdef; /**< Model definition (triphone mappings). */
/*
* Left and right CIphone sets for each state.
* Left context CIphones for a state S: If word W transitions into S, W's
* final CIphone is in S's {lc}. Words transitioning out of S must consider
* these left context CIphones.
* Similarly, right contexts for state S: If word W transitions out of S,
* W's first CIphone is in S's {rc}. Words transitioning into S must consider
* these right contexts.
*
* NOTE: Words may transition into and out of S INDIRECTLY, with intermediate
* null transitions.
* NOTE: Single-phone words are difficult; only SILENCE right context is
* modelled for them.
* NOTE: Non-silence filler phones aren't included in these sets. Filler
* words don't use context, and present the SILENCE phone as context to
* adjacent words.
*/
int16 **lc; /**< Left context triphone mappings for FSG. */
int16 **rc; /**< Right context triphone mappings for FSG. */
fsg_pnode_t **root; /* root[s] = lextree representing all transitions
out of state s. Note that the "tree" for each
state is actually a collection of trees, linked
via fsg_pnode_t.sibling (root[s]->sibling) */
fsg_pnode_t **alloc_head; /* alloc_head[s] = head of linear list of all
pnodes allocated for state s */
int32 n_pnode; /* #HMM nodes in search structure */
int32 wip;
int32 pip;
} fsg_lextree_t;
/* Access macros */
#define fsg_lextree_root(lt,s) ((lt)->root[s])
#define fsg_lextree_n_pnode(lt) ((lt)->n_pnode)
/**
* Create, initialize, and return a new phonetic lextree for the given FSG.
*/
fsg_lextree_t *fsg_lextree_init(fsg_model_t *fsg, dict_t *dict,
dict2pid_t *d2p,
bin_mdef_t *mdef, hmm_context_t *ctx,
int32 wip, int32 pip);
/**
* Free lextrees for an FSG.
*/
void fsg_lextree_free(fsg_lextree_t *fsg);
/**
* Print an FSG lextree to a file for debugging.
*/
void fsg_lextree_dump(fsg_lextree_t *fsg, FILE *fh);
/**
* Mark the given pnode as inactive (for search).
*/
void fsg_psubtree_pnode_deactivate(fsg_pnode_t *pnode);
/**
* Set all flags on in the given context bitvector.
*/
void fsg_pnode_add_all_ctxt(fsg_pnode_ctxt_t *ctxt);
/**
* Generic variant for arbitrary size
*/
uint32 fsg_pnode_ctxt_sub_generic(fsg_pnode_ctxt_t *src, fsg_pnode_ctxt_t *sub);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,149 @@
/* -*- c-basic-offset:4; indent-tabs-mode: nil -*- */
/* ====================================================================
* Copyright (c) 1999-2004 Carnegie Mellon University. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. 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 CARNEGIE MELLON UNIVERSITY ``AS IS'' AND
* ANY EXPRESSED 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 CARNEGIE MELLON UNIVERSITY
* NOR ITS EMPLOYEES 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.
*
* ====================================================================
*
*/
/*
* fsg_search_internal.h -- Search structures for FSG decoding.
*/
#ifndef __S2_FSG_SEARCH_H__
#define __S2_FSG_SEARCH_H__
/* SphinxBase headers. */
#include <sphinxbase/glist.h>
#include <sphinxbase/cmd_ln.h>
#include <sphinxbase/fsg_model.h>
/* Local headers. */
#include "pocketsphinx_internal.h"
#include "hmm.h"
#include "fsg_history.h"
#include "fsg_lextree.h"
/**
* Segmentation "iterator" for FSG history.
*/
typedef struct fsg_seg_s {
ps_seg_t base; /**< Base structure. */
fsg_hist_entry_t **hist; /**< Sequence of history entries. */
int16 n_hist; /**< Number of history entries. */
int16 cur; /**< Current position in hist. */
} fsg_seg_t;
/**
* Implementation of FSG search (and "FSG set") structure.
*/
typedef struct fsg_search_s {
ps_search_t base;
hmm_context_t *hmmctx; /**< HMM context. */
fsg_model_t *fsg; /**< FSG model */
struct fsg_lextree_s *lextree;/**< Lextree structure for the currently
active FSG */
struct fsg_history_s *history;/**< For storing the Viterbi search history */
glist_t pnode_active; /**< Those active in this frame */
glist_t pnode_active_next; /**< Those activated for the next frame */
int32 beam_orig; /**< Global pruning threshold */
int32 pbeam_orig; /**< Pruning threshold for phone transition */
int32 wbeam_orig; /**< Pruning threshold for word exit */
float32 beam_factor; /**< Dynamic/adaptive factor (<=1) applied to above
beams to determine actual effective beams.
For implementing absolute pruning. */
int32 beam, pbeam, wbeam; /**< Effective beams after applying beam_factor */
int32 lw, pip, wip; /**< Language weights */
frame_idx_t frame; /**< Current frame. */
uint8 final; /**< Decoding is finished for this utterance. */
uint8 bestpath; /**< Whether to run bestpath search
and confidence annotation at end. */
float32 ascale; /**< Acoustic score scale for posterior probabilities. */
int32 bestscore; /**< For beam pruning */
int32 bpidx_start; /**< First history entry index this frame */
int32 ascr, lscr; /**< Total acoustic and lm score for utt */
int32 n_hmm_eval; /**< Total HMMs evaluated this utt */
int32 n_sen_eval; /**< Total senones evaluated this utt */
} fsg_search_t;
/* Access macros */
#define fsg_search_frame(s) ((s)->frame)
/**
* Create, initialize and return a search module.
*/
ps_search_t *fsg_search_init(const char *name,
fsg_model_t *fsg,
cmd_ln_t *config,
acmod_t *acmod,
dict_t *dict,
dict2pid_t *d2p);
/**
* Deallocate search structure.
*/
void fsg_search_free(ps_search_t *search);
/**
* Update FSG search module for new or updated FSGs.
*/
int fsg_search_reinit(ps_search_t *fsgs, dict_t *dict, dict2pid_t *d2p);
/**
* Prepare the FSG search structure for beginning decoding of the next
* utterance.
*/
int fsg_search_start(ps_search_t *search);
/**
* Step one frame forward through the Viterbi search.
*/
int fsg_search_step(ps_search_t *search, int frame_idx);
/**
* Windup and clean the FSG search structure after utterance.
*/
int fsg_search_finish(ps_search_t *search);
/**
* Get hypothesis string from the FSG search.
*/
char const *fsg_search_hyp(ps_search_t *search, int32 *out_score, int32 *out_is_final);
#endif

View File

@ -0,0 +1,825 @@
/* -*- c-basic-offset: 4; indent-tabs-mode: nil -*- */
/* ====================================================================
* Copyright (c) 1999-2004 Carnegie Mellon University. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. 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 work was supported in part by funding from the Defense Advanced
* Research Projects Agency and the National Science Foundation of the
* United States of America, and the CMU Sphinx Speech Consortium.
*
* THIS SOFTWARE IS PROVIDED BY CARNEGIE MELLON UNIVERSITY ``AS IS'' AND
* ANY EXPRESSED 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 CARNEGIE MELLON UNIVERSITY
* NOR ITS EMPLOYEES 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.
*
* ====================================================================
*
*/
/**
* @file hmm.h Implementation of HMM base structure.
*/
/* System headers. */
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
/* SphinxBase headers. */
#include <sphinxbase/ckd_alloc.h>
#include <sphinxbase/err.h>
/* Local headers. */
#include "hmm.h"
hmm_context_t *
hmm_context_init(int32 n_emit_state,
uint8 ** const *tp,
int16 const *senscore,
uint16 * const *sseq)
{
hmm_context_t *ctx;
assert(n_emit_state > 0);
if (n_emit_state > HMM_MAX_NSTATE) {
E_ERROR("Number of emitting states must be <= %d\n", HMM_MAX_NSTATE);
return NULL;
}
ctx = ckd_calloc(1, sizeof(*ctx));
ctx->n_emit_state = n_emit_state;
ctx->tp = tp;
ctx->senscore = senscore;
ctx->sseq = sseq;
ctx->st_sen_scr = ckd_calloc(n_emit_state, sizeof(*ctx->st_sen_scr));
return ctx;
}
void
hmm_context_free(hmm_context_t *ctx)
{
if (ctx == NULL)
return;
ckd_free(ctx->st_sen_scr);
ckd_free(ctx);
}
void
hmm_init(hmm_context_t *ctx, hmm_t *hmm, int mpx, int ssid, int tmatid)
{
hmm->ctx = ctx;
hmm->mpx = mpx;
hmm->n_emit_state = ctx->n_emit_state;
if (mpx) {
int i;
hmm->ssid = BAD_SSID;
hmm->senid[0] = ssid;
for (i = 1; i < hmm_n_emit_state(hmm); ++i) {
hmm->senid[i] = BAD_SSID;
}
}
else {
hmm->ssid = ssid;
memcpy(hmm->senid, ctx->sseq[ssid], hmm->n_emit_state * sizeof(*hmm->senid));
}
hmm->tmatid = tmatid;
hmm_clear(hmm);
}
void
hmm_deinit(hmm_t *hmm)
{
}
void
hmm_dump(hmm_t * hmm,
FILE * fp)
{
int32 i;
if (hmm_is_mpx(hmm)) {
fprintf(fp, "MPX ");
for (i = 0; i < hmm_n_emit_state(hmm); i++)
fprintf(fp, " %11d", hmm_senid(hmm, i));
fprintf(fp, " ( ");
for (i = 0; i < hmm_n_emit_state(hmm); i++)
fprintf(fp, "%d ", hmm_ssid(hmm, i));
fprintf(fp, ")\n");
}
else {
fprintf(fp, "SSID ");
for (i = 0; i < hmm_n_emit_state(hmm); i++)
fprintf(fp, " %11d", hmm_senid(hmm, i));
fprintf(fp, " (%d)\n", hmm_ssid(hmm, 0));
}
if (hmm->ctx->senscore) {
fprintf(fp, "SENSCR");
for (i = 0; i < hmm_n_emit_state(hmm); i++)
fprintf(fp, " %11d", hmm_senscr(hmm, i));
fprintf(fp, "\n");
}
fprintf(fp, "SCORES %11d", hmm_in_score(hmm));
for (i = 1; i < hmm_n_emit_state(hmm); i++)
fprintf(fp, " %11d", hmm_score(hmm, i));
fprintf(fp, " %11d", hmm_out_score(hmm));
fprintf(fp, "\n");
fprintf(fp, "HISTID %11d", hmm_in_history(hmm));
for (i = 1; i < hmm_n_emit_state(hmm); i++)
fprintf(fp, " %11d", hmm_history(hmm, i));
fprintf(fp, " %11d", hmm_out_history(hmm));
fprintf(fp, "\n");
if (hmm_in_score(hmm) > 0)
fprintf(fp,
"ALERT!! The input score %d is large than 0. Probably wrap around.\n",
hmm_in_score(hmm));
if (hmm_out_score(hmm) > 0)
fprintf(fp,
"ALERT!! The output score %d is large than 0. Probably wrap around\n.",
hmm_out_score(hmm));
fflush(fp);
}
void
hmm_clear_scores(hmm_t * h)
{
int32 i;
hmm_in_score(h) = WORST_SCORE;
for (i = 1; i < hmm_n_emit_state(h); i++)
hmm_score(h, i) = WORST_SCORE;
hmm_out_score(h) = WORST_SCORE;
h->bestscore = WORST_SCORE;
}
void
hmm_clear(hmm_t * h)
{
int32 i;
hmm_in_score(h) = WORST_SCORE;
hmm_in_history(h) = -1;
for (i = 1; i < hmm_n_emit_state(h); i++) {
hmm_score(h, i) = WORST_SCORE;
hmm_history(h, i) = -1;
}
hmm_out_score(h) = WORST_SCORE;
hmm_out_history(h) = -1;
h->bestscore = WORST_SCORE;
h->frame = -1;
}
void
hmm_enter(hmm_t *h, int32 score, int32 histid, int frame)
{
hmm_in_score(h) = score;
hmm_in_history(h) = histid;
hmm_frame(h) = frame;
}
void
hmm_normalize(hmm_t *h, int32 bestscr)
{
int32 i;
for (i = 0; i < hmm_n_emit_state(h); i++) {
if (hmm_score(h, i) BETTER_THAN WORST_SCORE)
hmm_score(h, i) -= bestscr;
}
if (hmm_out_score(h) BETTER_THAN WORST_SCORE)
hmm_out_score(h) -= bestscr;
}
#define hmm_tprob_5st(i, j) (-tp[(i)*6+(j)])
#define nonmpx_senscr(i) (-senscore[sseq[i]])
static int32
hmm_vit_eval_5st_lr(hmm_t * hmm)
{
int16 const *senscore = hmm->ctx->senscore;
uint8 const *tp = hmm->ctx->tp[hmm->tmatid][0];
uint16 const *sseq = hmm->senid;
int32 s5, s4, s3, s2, s1, s0, t2, t1, t0, bestScore;
/* It was the best of scores, it was the worst of scores. */
bestScore = WORST_SCORE;
/* Cache problem here! */
s4 = hmm_score(hmm, 4) + nonmpx_senscr(4);
s3 = hmm_score(hmm, 3) + nonmpx_senscr(3);
/* Transitions into non-emitting state 5 */
if (s3 BETTER_THAN WORST_SCORE) {
t1 = s4 + hmm_tprob_5st(4, 5);
t2 = s3 + hmm_tprob_5st(3, 5);
if (t1 BETTER_THAN t2) {
s5 = t1;
hmm_out_history(hmm) = hmm_history(hmm, 4);
} else {
s5 = t2;
hmm_out_history(hmm) = hmm_history(hmm, 3);
}
if (s5 WORSE_THAN WORST_SCORE) s5 = WORST_SCORE;
hmm_out_score(hmm) = s5;
bestScore = s5;
}
s2 = hmm_score(hmm, 2) + nonmpx_senscr(2);
/* All transitions into state 4 */
if (s2 BETTER_THAN WORST_SCORE) {
t0 = s4 + hmm_tprob_5st(4, 4);
t1 = s3 + hmm_tprob_5st(3, 4);
t2 = s2 + hmm_tprob_5st(2, 4);
if (t0 BETTER_THAN t1) {
if (t2 BETTER_THAN t0) {
s4 = t2;
hmm_history(hmm, 4) = hmm_history(hmm, 2);
} else
s4 = t0;
} else {
if (t2 BETTER_THAN t1) {
s4 = t2;
hmm_history(hmm, 4) = hmm_history(hmm, 2);
} else {
s4 = t1;
hmm_history(hmm, 4) = hmm_history(hmm, 3);
}
}
if (s4 WORSE_THAN WORST_SCORE) s4 = WORST_SCORE;
if (s4 BETTER_THAN bestScore) bestScore = s4;
hmm_score(hmm, 4) = s4;
}
s1 = hmm_score(hmm, 1) + nonmpx_senscr(1);
/* All transitions into state 3 */
if (s1 BETTER_THAN WORST_SCORE) {
t0 = s3 + hmm_tprob_5st(3, 3);
t1 = s2 + hmm_tprob_5st(2, 3);
t2 = s1 + hmm_tprob_5st(1, 3);
if (t0 BETTER_THAN t1) {
if (t2 BETTER_THAN t0) {
s3 = t2;
hmm_history(hmm, 3) = hmm_history(hmm, 1);
} else
s3 = t0;
} else {
if (t2 BETTER_THAN t1) {
s3 = t2;
hmm_history(hmm, 3) = hmm_history(hmm, 1);
} else {
s3 = t1;
hmm_history(hmm, 3) = hmm_history(hmm, 2);
}
}
if (s3 WORSE_THAN WORST_SCORE) s3 = WORST_SCORE;
if (s3 BETTER_THAN bestScore) bestScore = s3;
hmm_score(hmm, 3) = s3;
}
s0 = hmm_in_score(hmm) + nonmpx_senscr(0);
/* All transitions into state 2 (state 0 is always active) */
t0 = s2 + hmm_tprob_5st(2, 2);
t1 = s1 + hmm_tprob_5st(1, 2);
t2 = s0 + hmm_tprob_5st(0, 2);
if (t0 BETTER_THAN t1) {
if (t2 BETTER_THAN t0) {
s2 = t2;
hmm_history(hmm, 2) = hmm_in_history(hmm);
} else
s2 = t0;
} else {
if (t2 BETTER_THAN t1) {
s2 = t2;
hmm_history(hmm, 2) = hmm_in_history(hmm);
} else {
s2 = t1;
hmm_history(hmm, 2) = hmm_history(hmm, 1);
}
}
if (s2 WORSE_THAN WORST_SCORE) s2 = WORST_SCORE;
if (s2 BETTER_THAN bestScore) bestScore = s2;
hmm_score(hmm, 2) = s2;
/* All transitions into state 1 */
t0 = s1 + hmm_tprob_5st(1, 1);
t1 = s0 + hmm_tprob_5st(0, 1);
if (t0 BETTER_THAN t1) {
s1 = t0;
} else {
s1 = t1;
hmm_history(hmm, 1) = hmm_in_history(hmm);
}
if (s1 WORSE_THAN WORST_SCORE) s1 = WORST_SCORE;
if (s1 BETTER_THAN bestScore) bestScore = s1;
hmm_score(hmm, 1) = s1;
/* All transitions into state 0 */
s0 = s0 + hmm_tprob_5st(0, 0);
if (s0 WORSE_THAN WORST_SCORE) s0 = WORST_SCORE;
if (s0 BETTER_THAN bestScore) bestScore = s0;
hmm_in_score(hmm) = s0;
hmm_bestscore(hmm) = bestScore;
return bestScore;
}
#define mpx_senid(st) sseq[ssid[st]][st]
#define mpx_senscr(st) (-senscore[mpx_senid(st)])
static int32
hmm_vit_eval_5st_lr_mpx(hmm_t * hmm)
{
uint8 const *tp = hmm->ctx->tp[hmm->tmatid][0];
int16 const *senscore = hmm->ctx->senscore;
uint16 * const *sseq = hmm->ctx->sseq;
uint16 *ssid = hmm->senid;
int32 bestScore;
int32 s5, s4, s3, s2, s1, s0, t2, t1, t0;
/* Don't propagate WORST_SCORE */
if (ssid[4] == BAD_SSID)
s4 = t1 = WORST_SCORE;
else {
s4 = hmm_score(hmm, 4) + mpx_senscr(4);
t1 = s4 + hmm_tprob_5st(4, 5);
}
if (ssid[3] == BAD_SSID)
s3 = t2 = WORST_SCORE;
else {
s3 = hmm_score(hmm, 3) + mpx_senscr(3);
t2 = s3 + hmm_tprob_5st(3, 5);
}
if (t1 BETTER_THAN t2) {
s5 = t1;
hmm_out_history(hmm) = hmm_history(hmm, 4);
}
else {
s5 = t2;
hmm_out_history(hmm) = hmm_history(hmm, 3);
}
if (s5 WORSE_THAN WORST_SCORE) s5 = WORST_SCORE;
hmm_out_score(hmm) = s5;
bestScore = s5;
/* Don't propagate WORST_SCORE */
if (ssid[2] == BAD_SSID)
s2 = t2 = WORST_SCORE;
else {
s2 = hmm_score(hmm, 2) + mpx_senscr(2);
t2 = s2 + hmm_tprob_5st(2, 4);
}
t0 = t1 = WORST_SCORE;
if (s4 != WORST_SCORE)
t0 = s4 + hmm_tprob_5st(4, 4);
if (s3 != WORST_SCORE)
t1 = s3 + hmm_tprob_5st(3, 4);
if (t0 BETTER_THAN t1) {
if (t2 BETTER_THAN t0) {
s4 = t2;
hmm_history(hmm, 4) = hmm_history(hmm, 2);
ssid[4] = ssid[2];
}
else
s4 = t0;
}
else {
if (t2 BETTER_THAN t1) {
s4 = t2;
hmm_history(hmm, 4) = hmm_history(hmm, 2);
ssid[4] = ssid[2];
}
else {
s4 = t1;
hmm_history(hmm, 4) = hmm_history(hmm, 3);
ssid[4] = ssid[3];
}
}
if (s4 WORSE_THAN WORST_SCORE) s4 = WORST_SCORE;
if (s4 BETTER_THAN bestScore)
bestScore = s4;
hmm_score(hmm, 4) = s4;
/* Don't propagate WORST_SCORE */
if (ssid[1] == BAD_SSID)
s1 = t2 = WORST_SCORE;
else {
s1 = hmm_score(hmm, 1) + mpx_senscr(1);
t2 = s1 + hmm_tprob_5st(1, 3);
}
t0 = t1 = WORST_SCORE;
if (s3 != WORST_SCORE)
t0 = s3 + hmm_tprob_5st(3, 3);
if (s2 != WORST_SCORE)
t1 = s2 + hmm_tprob_5st(2, 3);
if (t0 BETTER_THAN t1) {
if (t2 BETTER_THAN t0) {
s3 = t2;
hmm_history(hmm, 3) = hmm_history(hmm, 1);
ssid[3] = ssid[1];
}
else
s3 = t0;
}
else {
if (t2 BETTER_THAN t1) {
s3 = t2;
hmm_history(hmm, 3) = hmm_history(hmm, 1);
ssid[3] = ssid[1];
}
else {
s3 = t1;
hmm_history(hmm, 3) = hmm_history(hmm, 2);
ssid[3] = ssid[2];
}
}
if (s3 WORSE_THAN WORST_SCORE) s3 = WORST_SCORE;
if (s3 BETTER_THAN bestScore) bestScore = s3;
hmm_score(hmm, 3) = s3;
/* State 0 is always active */
s0 = hmm_in_score(hmm) + mpx_senscr(0);
/* Don't propagate WORST_SCORE */
t0 = t1 = WORST_SCORE;
if (s2 != WORST_SCORE)
t0 = s2 + hmm_tprob_5st(2, 2);
if (s1 != WORST_SCORE)
t1 = s1 + hmm_tprob_5st(1, 2);
t2 = s0 + hmm_tprob_5st(0, 2);
if (t0 BETTER_THAN t1) {
if (t2 BETTER_THAN t0) {
s2 = t2;
hmm_history(hmm, 2) = hmm_in_history(hmm);
ssid[2] = ssid[0];
}
else
s2 = t0;
}
else {
if (t2 BETTER_THAN t1) {
s2 = t2;
hmm_history(hmm, 2) = hmm_in_history(hmm);
ssid[2] = ssid[0];
}
else {
s2 = t1;
hmm_history(hmm, 2) = hmm_history(hmm, 1);
ssid[2] = ssid[1];
}
}
if (s2 WORSE_THAN WORST_SCORE) s2 = WORST_SCORE;
if (s2 BETTER_THAN bestScore) bestScore = s2;
hmm_score(hmm, 2) = s2;
/* Don't propagate WORST_SCORE */
t0 = WORST_SCORE;
if (s1 != WORST_SCORE)
t0 = s1 + hmm_tprob_5st(1, 1);
t1 = s0 + hmm_tprob_5st(0, 1);
if (t0 BETTER_THAN t1) {
s1 = t0;
}
else {
s1 = t1;
hmm_history(hmm, 1) = hmm_in_history(hmm);
ssid[1] = ssid[0];
}
if (s1 WORSE_THAN WORST_SCORE) s1 = WORST_SCORE;
if (s1 BETTER_THAN bestScore) bestScore = s1;
hmm_score(hmm, 1) = s1;
s0 += hmm_tprob_5st(0, 0);
if (s0 WORSE_THAN WORST_SCORE) s0 = WORST_SCORE;
if (s0 BETTER_THAN bestScore) bestScore = s0;
hmm_in_score(hmm) = s0;
hmm_bestscore(hmm) = bestScore;
return bestScore;
}
#define hmm_tprob_3st(i, j) (-tp[(i)*4+(j)])
static int32
hmm_vit_eval_3st_lr(hmm_t * hmm)
{
int16 const *senscore = hmm->ctx->senscore;
uint8 const *tp = hmm->ctx->tp[hmm->tmatid][0];
uint16 const *sseq = hmm->senid;
int32 s3, s2, s1, s0, t2, t1, t0, bestScore;
s2 = hmm_score(hmm, 2) + nonmpx_senscr(2);
s1 = hmm_score(hmm, 1) + nonmpx_senscr(1);
s0 = hmm_in_score(hmm) + nonmpx_senscr(0);
/* It was the best of scores, it was the worst of scores. */
bestScore = WORST_SCORE;
t2 = INT_MIN; /* Not used unless skipstate is true */
/* Transitions into non-emitting state 3 */
if (s1 BETTER_THAN WORST_SCORE) {
t1 = s2 + hmm_tprob_3st(2, 3);
if (hmm_tprob_3st(1,3) BETTER_THAN TMAT_WORST_SCORE)
t2 = s1 + hmm_tprob_3st(1, 3);
if (t1 BETTER_THAN t2) {
s3 = t1;
hmm_out_history(hmm) = hmm_history(hmm, 2);
} else {
s3 = t2;
hmm_out_history(hmm) = hmm_history(hmm, 1);
}
if (s3 WORSE_THAN WORST_SCORE) s3 = WORST_SCORE;
hmm_out_score(hmm) = s3;
bestScore = s3;
}
/* All transitions into state 2 (state 0 is always active) */
t0 = s2 + hmm_tprob_3st(2, 2);
t1 = s1 + hmm_tprob_3st(1, 2);
if (hmm_tprob_3st(0, 2) BETTER_THAN TMAT_WORST_SCORE)
t2 = s0 + hmm_tprob_3st(0, 2);
if (t0 BETTER_THAN t1) {
if (t2 BETTER_THAN t0) {
s2 = t2;
hmm_history(hmm, 2) = hmm_in_history(hmm);
} else
s2 = t0;
} else {
if (t2 BETTER_THAN t1) {
s2 = t2;
hmm_history(hmm, 2) = hmm_in_history(hmm);
} else {
s2 = t1;
hmm_history(hmm, 2) = hmm_history(hmm, 1);
}
}
if (s2 WORSE_THAN WORST_SCORE) s2 = WORST_SCORE;
if (s2 BETTER_THAN bestScore) bestScore = s2;
hmm_score(hmm, 2) = s2;
/* All transitions into state 1 */
t0 = s1 + hmm_tprob_3st(1, 1);
t1 = s0 + hmm_tprob_3st(0, 1);
if (t0 BETTER_THAN t1) {
s1 = t0;
} else {
s1 = t1;
hmm_history(hmm, 1) = hmm_in_history(hmm);
}
if (s1 WORSE_THAN WORST_SCORE) s1 = WORST_SCORE;
if (s1 BETTER_THAN bestScore) bestScore = s1;
hmm_score(hmm, 1) = s1;
/* All transitions into state 0 */
s0 = s0 + hmm_tprob_3st(0, 0);
if (s0 WORSE_THAN WORST_SCORE) s0 = WORST_SCORE;
if (s0 BETTER_THAN bestScore) bestScore = s0;
hmm_in_score(hmm) = s0;
hmm_bestscore(hmm) = bestScore;
return bestScore;
}
static int32
hmm_vit_eval_3st_lr_mpx(hmm_t * hmm)
{
uint8 const *tp = hmm->ctx->tp[hmm->tmatid][0];
int16 const *senscore = hmm->ctx->senscore;
uint16 * const *sseq = hmm->ctx->sseq;
uint16 *ssid = hmm->senid;
int32 bestScore;
int32 s3, s2, s1, s0, t2, t1, t0;
/* Don't propagate WORST_SCORE */
t2 = INT_MIN; /* Not used unless skipstate is true */
if (ssid[2] == BAD_SSID)
s2 = t1 = WORST_SCORE;
else {
s2 = hmm_score(hmm, 2) + mpx_senscr(2);
t1 = s2 + hmm_tprob_3st(2, 3);
}
if (ssid[1] == BAD_SSID)
s1 = t2 = WORST_SCORE;
else {
s1 = hmm_score(hmm, 1) + mpx_senscr(1);
if (hmm_tprob_3st(1,3) BETTER_THAN TMAT_WORST_SCORE)
t2 = s1 + hmm_tprob_3st(1, 3);
}
if (t1 BETTER_THAN t2) {
s3 = t1;
hmm_out_history(hmm) = hmm_history(hmm, 2);
}
else {
s3 = t2;
hmm_out_history(hmm) = hmm_history(hmm, 1);
}
if (s3 WORSE_THAN WORST_SCORE) s3 = WORST_SCORE;
hmm_out_score(hmm) = s3;
bestScore = s3;
/* State 0 is always active */
s0 = hmm_in_score(hmm) + mpx_senscr(0);
/* Don't propagate WORST_SCORE */
t0 = t1 = WORST_SCORE;
if (s2 != WORST_SCORE)
t0 = s2 + hmm_tprob_3st(2, 2);
if (s1 != WORST_SCORE)
t1 = s1 + hmm_tprob_3st(1, 2);
if (hmm_tprob_3st(0,2) BETTER_THAN TMAT_WORST_SCORE)
t2 = s0 + hmm_tprob_3st(0, 2);
if (t0 BETTER_THAN t1) {
if (t2 BETTER_THAN t0) {
s2 = t2;
hmm_history(hmm, 2) = hmm_in_history(hmm);
ssid[2] = ssid[0];
}
else
s2 = t0;
}
else {
if (t2 BETTER_THAN t1) {
s2 = t2;
hmm_history(hmm, 2) = hmm_in_history(hmm);
ssid[2] = ssid[0];
}
else {
s2 = t1;
hmm_history(hmm, 2) = hmm_history(hmm, 1);
ssid[2] = ssid[1];
}
}
if (s2 WORSE_THAN WORST_SCORE) s2 = WORST_SCORE;
if (s2 BETTER_THAN bestScore) bestScore = s2;
hmm_score(hmm, 2) = s2;
/* Don't propagate WORST_SCORE */
t0 = WORST_SCORE;
if (s1 != WORST_SCORE)
t0 = s1 + hmm_tprob_3st(1, 1);
t1 = s0 + hmm_tprob_3st(0, 1);
if (t0 BETTER_THAN t1) {
s1 = t0;
}
else {
s1 = t1;
hmm_history(hmm, 1) = hmm_in_history(hmm);
ssid[1] = ssid[0];
}
if (s1 WORSE_THAN WORST_SCORE) s1 = WORST_SCORE;
if (s1 BETTER_THAN bestScore) bestScore = s1;
hmm_score(hmm, 1) = s1;
/* State 0 is always active */
s0 += hmm_tprob_3st(0, 0);
if (s0 WORSE_THAN WORST_SCORE) s0 = WORST_SCORE;
if (s0 BETTER_THAN bestScore) bestScore = s0;
hmm_in_score(hmm) = s0;
hmm_bestscore(hmm) = bestScore;
return bestScore;
}
static int32
hmm_vit_eval_anytopo(hmm_t * hmm)
{
hmm_context_t *ctx = hmm->ctx;
int32 to, from, bestfrom;
int32 newscr, scr, bestscr;
int final_state;
/* Compute previous state-score + observation output prob for each emitting state */
ctx->st_sen_scr[0] = hmm_in_score(hmm) + hmm_senscr(hmm, 0);
for (from = 1; from < hmm_n_emit_state(hmm); ++from) {
if ((ctx->st_sen_scr[from] =
hmm_score(hmm, from) + hmm_senscr(hmm, from)) WORSE_THAN WORST_SCORE)
ctx->st_sen_scr[from] = WORST_SCORE;
}
/* FIXME/TODO: Use the BLAS for all this. */
/* Evaluate final-state first, which does not have a self-transition */
final_state = hmm_n_emit_state(hmm);
to = final_state;
scr = WORST_SCORE;
bestfrom = -1;
for (from = to - 1; from >= 0; --from) {
if ((hmm_tprob(hmm, from, to) BETTER_THAN TMAT_WORST_SCORE) &&
((newscr = ctx->st_sen_scr[from]
+ hmm_tprob(hmm, from, to)) BETTER_THAN scr)) {
scr = newscr;
bestfrom = from;
}
}
hmm_out_score(hmm) = scr;
if (bestfrom >= 0)
hmm_out_history(hmm) = hmm_history(hmm, bestfrom);
bestscr = scr;
/* Evaluate all other states, which might have self-transitions */
for (to = final_state - 1; to >= 0; --to) {
/* Score from self-transition, if any */
scr =
(hmm_tprob(hmm, to, to) BETTER_THAN TMAT_WORST_SCORE)
? ctx->st_sen_scr[to] + hmm_tprob(hmm, to, to)
: WORST_SCORE;
/* Scores from transitions from other states */
bestfrom = -1;
for (from = to - 1; from >= 0; --from) {
if ((hmm_tprob(hmm, from, to) BETTER_THAN TMAT_WORST_SCORE) &&
((newscr = ctx->st_sen_scr[from]
+ hmm_tprob(hmm, from, to)) BETTER_THAN scr)) {
scr = newscr;
bestfrom = from;
}
}
/* Update new result for state to */
if (to == 0) {
hmm_in_score(hmm) = scr;
if (bestfrom >= 0)
hmm_in_history(hmm) = hmm_history(hmm, bestfrom);
}
else {
hmm_score(hmm, to) = scr;
if (bestfrom >= 0)
hmm_history(hmm, to) = hmm_history(hmm, bestfrom);
}
/* Propagate ssid for multiplex HMMs */
if (bestfrom >= 0 && hmm_is_mpx(hmm))
hmm->senid[to] = hmm->senid[bestfrom];
if (bestscr WORSE_THAN scr)
bestscr = scr;
}
hmm_bestscore(hmm) = bestscr;
return bestscr;
}
int32
hmm_vit_eval(hmm_t * hmm)
{
if (hmm_is_mpx(hmm)) {
if (hmm_n_emit_state(hmm) == 5)
return hmm_vit_eval_5st_lr_mpx(hmm);
else if (hmm_n_emit_state(hmm) == 3)
return hmm_vit_eval_3st_lr_mpx(hmm);
else
return hmm_vit_eval_anytopo(hmm);
}
else {
if (hmm_n_emit_state(hmm) == 5)
return hmm_vit_eval_5st_lr(hmm);
else if (hmm_n_emit_state(hmm) == 3)
return hmm_vit_eval_3st_lr(hmm);
else
return hmm_vit_eval_anytopo(hmm);
}
}
int32
hmm_dump_vit_eval(hmm_t * hmm, FILE * fp)
{
int32 bs = 0;
if (fp) {
fprintf(fp, "BEFORE:\n");
hmm_dump(hmm, fp);
}
bs = hmm_vit_eval(hmm);
if (fp) {
fprintf(fp, "AFTER:\n");
hmm_dump(hmm, fp);
}
return bs;
}

View File

@ -0,0 +1,306 @@
/* -*- c-basic-offset: 4; indent-tabs-mode: nil -*- */
/* ====================================================================
* Copyright (c) 1999-2004 Carnegie Mellon University. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. 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 work was supported in part by funding from the Defense Advanced
* Research Projects Agency and the National Science Foundation of the
* United States of America, and the CMU Sphinx Speech Consortium.
*
* THIS SOFTWARE IS PROVIDED BY CARNEGIE MELLON UNIVERSITY ``AS IS'' AND
* ANY EXPRESSED 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 CARNEGIE MELLON UNIVERSITY
* NOR ITS EMPLOYEES 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.
*
* ====================================================================
*
*/
/**
* @file hmm.h Hidden Markov Model base structures.
*/
#ifndef __HMM_H__
#define __HMM_H__
/* System headers. */
#include <stdio.h>
/* SphinxBase headers. */
#include <sphinxbase/fixpoint.h>
#include <sphinxbase/listelem_alloc.h>
/* PocketSphinx headers. */
#include "bin_mdef.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* Type for frame index values. Used in HMM indexes and
* backpointers and affects memory required.Due to limitations of FSG
* search implementation this value needs to be signed.
*/
typedef int32 frame_idx_t;
/**
* Maximum number of frames in index, should be in sync with above.
*/
#define MAX_N_FRAMES MAX_INT32
/** Shift count for senone scores. */
#define SENSCR_SHIFT 10
/**
* Large "bad" score.
*
* This number must be "bad" enough so that 4 times WORST_SCORE will
* not overflow. The reason for this is that the search doesn't check
* the scores in a model before evaluating the model and it may
* require as many was 4 plies before the new 'good' score can wipe
* out the initial WORST_SCORE initialization.
*/
#define WORST_SCORE ((int)0xE0000000)
/**
* Watch out, though! Transition matrix entries that are supposed to
* be "zero" don't actually get that small due to quantization.
*/
#define TMAT_WORST_SCORE (-255)
/**
* Is one score better than another?
*/
#define BETTER_THAN >
/**
* Is one score worse than another?
*/
#define WORSE_THAN <
/** \file hmm.h
* \brief HMM data structure and operation
*
* For efficiency, this version is hardwired for two possible HMM
* topologies, but will fall back to others:
*
* 5-state left-to-right HMMs: (0 is the *emitting* entry state and E
* is a non-emitting exit state; the x's indicate allowed transitions
* between source and destination states):
*
* <pre>
* 0 1 2 3 4 E (destination-states)
* 0 x x x
* 1 x x x
* 2 x x x
* 3 x x x
* 4 x x
* (source-states)
* </pre>
*
* 5-state topologies that contain a subset of the above transitions should work as well.
*
* 3-state left-to-right HMMs (similar notation as the 5-state topology above):
*
* <pre>
* 0 1 2 E (destination-states)
* 0 x x x
* 1 x x x
* 2 x x
* (source-states)
* </pre>
*
* 3-state topologies that contain a subset of the above transitions should work as well.
*/
/**
* @struct hmm_context_t
* @brief Shared information between a set of HMMs.
*
* We assume that the initial state is emitting and that the
* transition matrix is n_emit_state x (n_emit_state+1), where the
* extra destination dimension correponds to the non-emitting final or
* exit state.
*/
typedef struct hmm_context_s {
int32 n_emit_state; /**< Number of emitting states in this set of HMMs. */
uint8 ** const *tp; /**< State transition scores tp[id][from][to] (logs3 values). */
int16 const *senscore; /**< State emission scores senscore[senid]
(negated scaled logs3 values). */
uint16 * const *sseq; /**< Senone sequence mapping. */
int32 *st_sen_scr; /**< Temporary array of senone scores (for some topologies). */
listelem_alloc_t *mpx_ssid_alloc; /**< Allocator for senone sequence ID arrays. */
void *udata; /**< Whatever you feel like, gosh. */
} hmm_context_t;
/**
* Hard-coded limit on the number of emitting states.
*/
#define HMM_MAX_NSTATE 5
/**
* @struct hmm_t
* @brief An individual HMM among the HMM search space.
*
* An individual HMM among the HMM search space. An HMM with N
* emitting states consists of N+1 internal states including the
* non-emitting exit (out) state.
*/
typedef struct hmm_s {
hmm_context_t *ctx; /**< Shared context data for this HMM. */
int32 score[HMM_MAX_NSTATE]; /**< State scores for emitting states. */
int32 history[HMM_MAX_NSTATE]; /**< History indices for emitting states. */
int32 out_score; /**< Score for non-emitting exit state. */
int32 out_history; /**< History index for non-emitting exit state. */
uint16 ssid; /**< Senone sequence ID (for non-MPX) */
uint16 senid[HMM_MAX_NSTATE]; /**< Senone IDs (non-MPX) or sequence IDs (MPX) */
int32 bestscore; /**< Best [emitting] state score in current frame (for pruning). */
int16 tmatid; /**< Transition matrix ID (see hmm_context_t). */
frame_idx_t frame; /**< Frame in which this HMM was last active; <0 if inactive */
uint8 mpx; /**< Is this HMM multiplex? (hoisted for speed) */
uint8 n_emit_state; /**< Number of emitting states (hoisted for speed) */
} hmm_t;
/** Access macros. */
#define hmm_context(h) (h)->ctx
#define hmm_is_mpx(h) (h)->mpx
#define hmm_in_score(h) (h)->score[0]
#define hmm_score(h,st) (h)->score[st]
#define hmm_out_score(h) (h)->out_score
#define hmm_in_history(h) (h)->history[0]
#define hmm_history(h,st) (h)->history[st]
#define hmm_out_history(h) (h)->out_history
#define hmm_bestscore(h) (h)->bestscore
#define hmm_frame(h) (h)->frame
#define hmm_mpx_ssid(h,st) (h)->senid[st]
#define hmm_nonmpx_ssid(h) (h)->ssid
#define hmm_ssid(h,st) (hmm_is_mpx(h) \
? hmm_mpx_ssid(h,st) : hmm_nonmpx_ssid(h))
#define hmm_mpx_senid(h,st) (hmm_mpx_ssid(h,st) == BAD_SENID \
? BAD_SENID : (h)->ctx->sseq[hmm_mpx_ssid(h,st)][st])
#define hmm_nonmpx_senid(h,st) ((h)->senid[st])
#define hmm_senid(h,st) (hmm_is_mpx(h) \
? hmm_mpx_senid(h,st) : hmm_nonmpx_senid(h,st))
#define hmm_senscr(h,st) (hmm_senid(h,st) == BAD_SENID \
? WORST_SCORE \
: -(h)->ctx->senscore[hmm_senid(h,st)])
#define hmm_tmatid(h) (h)->tmatid
#define hmm_tprob(h,i,j) (-(h)->ctx->tp[hmm_tmatid(h)][i][j])
#define hmm_n_emit_state(h) ((h)->n_emit_state)
#define hmm_n_state(h) ((h)->n_emit_state + 1)
/**
* Create an HMM context.
**/
hmm_context_t *hmm_context_init(int32 n_emit_state,
uint8 ** const *tp,
int16 const *senscore,
uint16 * const *sseq);
/**
* Change the senone score array for a context.
**/
#define hmm_context_set_senscore(ctx, senscr) ((ctx)->senscore = (senscr))
/**
* Free an HMM context.
*
* @note The transition matrices, senone scores, and senone sequence
* mapping are all assumed to be allocated externally, and will NOT be
* freed by this function.
**/
void hmm_context_free(hmm_context_t *ctx);
/**
* Populate a previously-allocated HMM structure, allocating internal data.
**/
void hmm_init(hmm_context_t *ctx, hmm_t *hmm, int mpx, int ssid, int tmatid);
/**
* Free an HMM structure, releasing internal data (but not the HMM structure itself).
*/
void hmm_deinit(hmm_t *hmm);
/**
* Reset the states of the HMM to the invalid condition.
* i.e., scores to WORST_SCORE and hist to undefined.
*/
void hmm_clear(hmm_t *h);
/**
* Reset the scores of the HMM.
*/
void hmm_clear_scores(hmm_t *h);
/**
* Renormalize the scores in this HMM based on the given best score.
*/
void hmm_normalize(hmm_t *h, int32 bestscr);
/**
* Enter an HMM with the given path score and history ID.
**/
void hmm_enter(hmm_t *h, int32 score,
int32 histid, int frame);
/**
* Viterbi evaluation of given HMM.
*
* @note If this module were being used for tracking state
* segmentations, the dummy, non-emitting exit state would have to be
* updated separately. In the Viterbi DP diagram, transitions to the
* exit state occur from the current time; they are vertical
* transitions. Hence they should be made only after the history has
* been logged for the emitting states. But we're not bothered with
* state segmentations, for now. So, we update the exit state as
* well.
*/
int32 hmm_vit_eval(hmm_t *hmm);
/**
* Like hmm_vit_eval, but dump HMM state and relevant senscr to fp first, for debugging;.
*/
int32 hmm_dump_vit_eval(hmm_t *hmm, /**< In/Out: HMM being updated */
FILE *fp /**< An output file pointer */
);
/**
* For debugging, dump the whole HMM out.
*/
void hmm_dump(hmm_t *h, /**< In/Out: HMM being updated */
FILE *fp /**< An output file pointer */
);
#ifdef __cplusplus
}
#endif
#endif /* __HMM_H__ */

View File

@ -0,0 +1,120 @@
/* -*- c-basic-offset: 4; indent-tabs-mode: nil -*- */
/* ====================================================================
* Copyright (c) 2014 Carnegie Mellon University. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. 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 CARNEGIE MELLON UNIVERSITY ``AS IS'' AND
* ANY EXPRESSED 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 CARNEGIE MELLON UNIVERSITY
* NOR ITS EMPLOYEES 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.
*
* ====================================================================
*
*/
/*
* kws_detections.c -- Object for storing keyword search results
*/
#include "kws_detections.h"
void
kws_detections_reset(kws_detections_t *detections)
{
gnode_t *gn;
if (!detections->detect_list)
return;
for (gn = detections->detect_list; gn; gn = gnode_next(gn))
ckd_free(gnode_ptr(gn));
glist_free(detections->detect_list);
detections->detect_list = NULL;
}
void
kws_detections_add(kws_detections_t *detections, const char* keyphrase, int sf, int ef, int prob, int ascr)
{
gnode_t *gn;
kws_detection_t* detection;
for (gn = detections->detect_list; gn; gn = gnode_next(gn)) {
kws_detection_t *det = (kws_detection_t *)gnode_ptr(gn);
if (strcmp(keyphrase, det->keyphrase) == 0 && det->sf < ef && det->ef > sf) {
if (det->prob < prob) {
det->sf = sf;
det->ef = ef;
det->prob = prob;
det->ascr = ascr;
}
return;
}
}
/* Nothing found */
detection = (kws_detection_t *)ckd_calloc(1, sizeof(*detection));
detection->sf = sf;
detection->ef = ef;
detection->keyphrase = keyphrase;
detection->prob = prob;
detection->ascr = ascr;
detections->detect_list = glist_add_ptr(detections->detect_list, detection);
}
char *
kws_detections_hyp_str(kws_detections_t *detections, int frame, int delay)
{
gnode_t *gn;
char *c;
int len;
char *hyp_str;
len = 0;
for (gn = detections->detect_list; gn; gn = gnode_next(gn)) {
kws_detection_t *det = (kws_detection_t *)gnode_ptr(gn);
if (det->ef < frame - delay) {
len += strlen(det->keyphrase) + 1;
}
}
if (len == 0) {
return NULL;
}
hyp_str = (char *)ckd_calloc(len, sizeof(char));
c = hyp_str;
for (gn = detections->detect_list; gn; gn = gnode_next(gn)) {
kws_detection_t *det = (kws_detection_t *)gnode_ptr(gn);
if (det->ef < frame - delay) {
memcpy(c, det->keyphrase, strlen(det->keyphrase));
c += strlen(det->keyphrase);
*c = ' ';
c++;
}
}
if (c > hyp_str) {
c--;
*c = '\0';
}
return hyp_str;
}

View File

@ -0,0 +1,76 @@
/* -*- c-basic-offset: 4; indent-tabs-mode: nil -*- */
/* ====================================================================
* Copyright (c) 2014 Carnegie Mellon University. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. 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 CARNEGIE MELLON UNIVERSITY ``AS IS'' AND
* ANY EXPRESSED 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 CARNEGIE MELLON UNIVERSITY
* NOR ITS EMPLOYEES 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.
*
* ====================================================================
*
*/
/*
* kws_detections.h -- Structures for storing keyword spotting results.
*/
#ifndef __KWS_DETECTIONS_H__
#define __KWS_DETECTIONS_H__
/* SphinxBase headers. */
#include <sphinxbase/glist.h>
/* Local headers. */
#include "pocketsphinx_internal.h"
#include "hmm.h"
typedef struct kws_detection_s {
const char* keyphrase;
frame_idx_t sf;
frame_idx_t ef;
int32 prob;
int32 ascr;
} kws_detection_t;
typedef struct kws_detections_s {
glist_t detect_list;
} kws_detections_t;
/**
* Reset history structure.
*/
void kws_detections_reset(kws_detections_t *detections);
/**
* Add history entry.
*/
void kws_detections_add(kws_detections_t *detections, const char* keyphrase, int sf, int ef, int prob, int ascr);
/**
* Compose hypothesis.
*/
char* kws_detections_hyp_str(kws_detections_t *detections, int frame, int delay);
#endif /* __KWS_DETECTIONS_H__ */

View File

@ -0,0 +1,672 @@
/* -*- c-basic-offset: 4; indent-tabs-mode: nil -*- */
/* ====================================================================
* Copyright (c) 2013 Carnegie Mellon University. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. 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 CARNEGIE MELLON UNIVERSITY ``AS IS'' AND
* ANY EXPRESSED 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 CARNEGIE MELLON UNIVERSITY
* NOR ITS EMPLOYEES 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.
*
* ====================================================================
*
*/
/*
* kws_search.c -- Search object for key phrase spotting.
*/
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <sphinxbase/err.h>
#include <sphinxbase/ckd_alloc.h>
#include <sphinxbase/strfuncs.h>
#include <sphinxbase/pio.h>
#include <sphinxbase/cmd_ln.h>
#include "pocketsphinx_internal.h"
#include "kws_search.h"
/** Access macros */
#define hmm_is_active(hmm) ((hmm)->frame > 0)
#define kws_nth_hmm(keyword,n) (&((keyword)->hmms[n]))
static ps_lattice_t *
kws_search_lattice(ps_search_t * search)
{
return NULL;
}
static int
kws_search_prob(ps_search_t * search)
{
return 0;
}
static void
kws_seg_free(ps_seg_t *seg)
{
kws_seg_t *itor = (kws_seg_t *)seg;
ckd_free(itor);
}
static void
kws_seg_fill(kws_seg_t *itor)
{
kws_detection_t* detection = (kws_detection_t*)gnode_ptr(itor->detection);
itor->base.word = detection->keyphrase;
itor->base.sf = detection->sf;
itor->base.ef = detection->ef;
itor->base.prob = detection->prob;
itor->base.ascr = detection->ascr;
itor->base.lscr = 0;
}
static ps_seg_t *
kws_seg_next(ps_seg_t *seg)
{
kws_seg_t *itor = (kws_seg_t *)seg;
gnode_t *detect_head = gnode_next(itor->detection);
while (detect_head != NULL && ((kws_detection_t*)gnode_ptr(detect_head))->ef > itor->last_frame)
detect_head = gnode_next(detect_head);
itor->detection = detect_head;
if (!itor->detection) {
kws_seg_free(seg);
return NULL;
}
kws_seg_fill(itor);
return seg;
}
static ps_segfuncs_t kws_segfuncs = {
/* seg_next */ kws_seg_next,
/* seg_free */ kws_seg_free
};
static ps_seg_t *
kws_search_seg_iter(ps_search_t * search, int32 * out_score)
{
kws_search_t *kwss = (kws_search_t *)search;
kws_seg_t *itor;
gnode_t *detect_head = kwss->detections->detect_list;
while (detect_head != NULL && ((kws_detection_t*)gnode_ptr(detect_head))->ef > kwss->frame - kwss->delay)
detect_head = gnode_next(detect_head);
if (!detect_head)
return NULL;
if (out_score)
*out_score = 0;
itor = (kws_seg_t *)ckd_calloc(1, sizeof(*itor));
itor->base.vt = &kws_segfuncs;
itor->base.search = search;
itor->base.lwf = 1.0;
itor->detection = detect_head;
itor->last_frame = kwss->frame - kwss->delay;
kws_seg_fill(itor);
return (ps_seg_t *)itor;
}
static ps_searchfuncs_t kws_funcs = {
/* start: */ kws_search_start,
/* step: */ kws_search_step,
/* finish: */ kws_search_finish,
/* reinit: */ kws_search_reinit,
/* free: */ kws_search_free,
/* lattice: */ kws_search_lattice,
/* hyp: */ kws_search_hyp,
/* prob: */ kws_search_prob,
/* seg_iter: */ kws_search_seg_iter,
};
/* Scans the dictionary and check if all words are present. */
static int
kws_search_check_dict(kws_search_t * kwss)
{
dict_t *dict;
char **wrdptr;
char *tmp_keyphrase;
int32 nwrds, wid;
int keyword_iter, i;
uint8 success;
success = TRUE;
dict = ps_search_dict(kwss);
for (keyword_iter = 0; keyword_iter < kwss->n_keyphrases; keyword_iter++) {
tmp_keyphrase = (char *) ckd_salloc(kwss->keyphrases[keyword_iter].word);
nwrds = str2words(tmp_keyphrase, NULL, 0);
wrdptr = (char **) ckd_calloc(nwrds, sizeof(*wrdptr));
str2words(tmp_keyphrase, wrdptr, nwrds);
for (i = 0; i < nwrds; i++) {
wid = dict_wordid(dict, wrdptr[i]);
if (wid == BAD_S3WID) {
E_ERROR("The word '%s' is missing in the dictionary\n",
wrdptr[i]);
success = FALSE;
break;
}
}
ckd_free(wrdptr);
ckd_free(tmp_keyphrase);
}
return success;
}
/* Activate senones for scoring */
static void
kws_search_sen_active(kws_search_t * kwss)
{
int i, keyword_iter;
acmod_clear_active(ps_search_acmod(kwss));
/* active phone loop hmms */
for (i = 0; i < kwss->n_pl; i++)
acmod_activate_hmm(ps_search_acmod(kwss), &kwss->pl_hmms[i]);
/* activate hmms in active nodes */
for (keyword_iter = 0; keyword_iter < kwss->n_keyphrases; keyword_iter++) {
kws_keyword_t *keyword = &kwss->keyphrases[keyword_iter];
for (i = 0; i < keyword->n_hmms; i++) {
if (hmm_is_active(kws_nth_hmm(keyword, i)))
acmod_activate_hmm(ps_search_acmod(kwss), kws_nth_hmm(keyword, i));
}
}
}
/*
* Evaluate all the active HMMs.
* (Executed once per frame.)
*/
static void
kws_search_hmm_eval(kws_search_t * kwss, int16 const *senscr)
{
int32 i, keyword_iter;
int32 bestscore = WORST_SCORE;
hmm_context_set_senscore(kwss->hmmctx, senscr);
/* evaluate hmms from phone loop */
for (i = 0; i < kwss->n_pl; ++i) {
hmm_t *hmm = &kwss->pl_hmms[i];
int32 score;
score = hmm_vit_eval(hmm);
if (score BETTER_THAN bestscore)
bestscore = score;
}
/* evaluate hmms for active nodes */
for (keyword_iter = 0; keyword_iter < kwss->n_keyphrases; keyword_iter++) {
kws_keyword_t *keyword = &kwss->keyphrases[keyword_iter];
for (i = 0; i < keyword->n_hmms; i++) {
hmm_t *hmm = kws_nth_hmm(keyword, i);
if (hmm_is_active(hmm)) {
int32 score;
score = hmm_vit_eval(hmm);
if (score BETTER_THAN bestscore)
bestscore = score;
}
}
}
kwss->bestscore = bestscore;
}
/*
* (Beam) prune the just evaluated HMMs, determine which ones remain
* active. Executed once per frame.
*/
static void
kws_search_hmm_prune(kws_search_t * kwss)
{
int32 thresh, i, keyword_iter;
thresh = kwss->bestscore + kwss->beam;
for (keyword_iter = 0; keyword_iter < kwss->n_keyphrases; keyword_iter++) {
kws_keyword_t *keyword = &kwss->keyphrases[keyword_iter];
for (i = 0; i < keyword->n_hmms; i++) {
hmm_t *hmm = kws_nth_hmm(keyword, i);
if (hmm_is_active(hmm) && hmm_bestscore(hmm) < thresh)
hmm_clear(hmm);
}
}
}
/**
* Do phone transitions
*/
static void
kws_search_trans(kws_search_t * kwss)
{
hmm_t *pl_best_hmm = NULL;
int32 best_out_score = WORST_SCORE;
int i, keyword_iter;
/* select best hmm in phone-loop to be a predecessor */
for (i = 0; i < kwss->n_pl; i++)
if (hmm_out_score(&kwss->pl_hmms[i]) BETTER_THAN best_out_score) {
best_out_score = hmm_out_score(&kwss->pl_hmms[i]);
pl_best_hmm = &kwss->pl_hmms[i];
}
/* out probs are not ready yet */
if (!pl_best_hmm)
return;
/* Check whether keyword wasn't spotted yet */
for (keyword_iter = 0; keyword_iter < kwss->n_keyphrases; keyword_iter++) {
kws_keyword_t *keyword;
hmm_t *last_hmm;
keyword = &kwss->keyphrases[keyword_iter];
last_hmm = kws_nth_hmm(keyword, keyword->n_hmms - 1);
if (hmm_is_active(last_hmm)
&& hmm_out_score(pl_best_hmm) BETTER_THAN WORST_SCORE) {
if (hmm_out_score(last_hmm) - hmm_out_score(pl_best_hmm)
>= keyword->threshold) {
int32 prob = hmm_out_score(last_hmm) - hmm_out_score(pl_best_hmm);
kws_detections_add(kwss->detections, keyword->word,
hmm_out_history(last_hmm),
kwss->frame, prob,
hmm_out_score(last_hmm));
} /* keyword is spotted */
} /* last hmm of keyword is active */
} /* keywords loop */
/* Make transition for all phone loop hmms */
for (i = 0; i < kwss->n_pl; i++) {
if (hmm_out_score(pl_best_hmm) + kwss->plp BETTER_THAN
hmm_in_score(&kwss->pl_hmms[i])) {
hmm_enter(&kwss->pl_hmms[i],
hmm_out_score(pl_best_hmm) + kwss->plp,
hmm_out_history(pl_best_hmm), kwss->frame + 1);
}
}
/* Activate new keyword nodes, enter their hmms */
for (keyword_iter = 0; keyword_iter < kwss->n_keyphrases; keyword_iter++) {
kws_keyword_t *keyword = &kwss->keyphrases[keyword_iter];
for (i = keyword->n_hmms - 1; i > 0; i--) {
hmm_t *pred_hmm = kws_nth_hmm(keyword, i - 1);
hmm_t *hmm = kws_nth_hmm(keyword, i);
if (hmm_is_active(pred_hmm)) {
if (!hmm_is_active(hmm)
|| hmm_out_score(pred_hmm) BETTER_THAN
hmm_in_score(hmm))
hmm_enter(hmm, hmm_out_score(pred_hmm),
hmm_out_history(pred_hmm), kwss->frame + 1);
}
}
/* Enter keyword start node from phone loop */
if (hmm_out_score(pl_best_hmm) BETTER_THAN
hmm_in_score(kws_nth_hmm(keyword, 0)))
hmm_enter(kws_nth_hmm(keyword, 0), hmm_out_score(pl_best_hmm),
kwss->frame, kwss->frame + 1);
} /* keywords loop */
}
static int
kws_search_read_list(kws_search_t *kwss, const char* keyfile)
{
FILE *list_file;
lineiter_t *li;
char *line;
int i;
if ((list_file = fopen(keyfile, "r")) == NULL) {
E_ERROR_SYSTEM("Failed to open keyword file '%s'", keyfile);
return -1;
}
/* count keyphrases */
kwss->n_keyphrases = 0;
for (li = lineiter_start(list_file); li; li = lineiter_next(li))
if (li->len > 0)
kwss->n_keyphrases++;
kwss->keyphrases = (kws_keyword_t *)ckd_calloc(kwss->n_keyphrases, sizeof(*kwss->keyphrases));
fseek(list_file, 0L, SEEK_SET);
/* read keyphrases */
for (li = lineiter_start(list_file), i=0; li; li = lineiter_next(li), i++) {
size_t begin, end;
kwss->keyphrases[i].threshold = kwss->def_threshold;
line = string_trim(li->buf, STRING_BOTH);
end = strlen(line) - 1;
begin = end - 1;
if (line[end] == '/') {
while (line[begin] != '/' && begin > 0)
begin--;
line[end] = 0;
line[begin] = 0;
kwss->keyphrases[i].threshold = (int32) logmath_log(kwss->base.acmod->lmath, atof_c(line + begin + 1))
>> SENSCR_SHIFT;
}
kwss->keyphrases[i].word = ckd_salloc(line);
}
fclose(list_file);
return 0;
}
ps_search_t *
kws_search_init(const char *name,
const char *keyphrase,
const char *keyfile,
cmd_ln_t * config,
acmod_t * acmod, dict_t * dict, dict2pid_t * d2p)
{
kws_search_t *kwss = (kws_search_t *) ckd_calloc(1, sizeof(*kwss));
ps_search_init(ps_search_base(kwss), &kws_funcs, PS_SEARCH_TYPE_KWS, name, config, acmod, dict,
d2p);
kwss->detections = (kws_detections_t *)ckd_calloc(1, sizeof(*kwss->detections));
kwss->beam =
(int32) logmath_log(acmod->lmath,
cmd_ln_float64_r(config,
"-beam")) >> SENSCR_SHIFT;
kwss->plp =
(int32) logmath_log(acmod->lmath,
cmd_ln_float32_r(config,
"-kws_plp")) >> SENSCR_SHIFT;
kwss->def_threshold =
(int32) logmath_log(acmod->lmath,
cmd_ln_float64_r(config,
"-kws_threshold")) >>
SENSCR_SHIFT;
kwss->delay = (int32) cmd_ln_int32_r(config, "-kws_delay");
E_INFO("KWS(beam: %d, plp: %d, default threshold %d, delay %d)\n",
kwss->beam, kwss->plp, kwss->def_threshold, kwss->delay);
if (keyfile) {
if (kws_search_read_list(kwss, keyfile) < 0) {
E_ERROR("Failed to create kws search\n");
kws_search_free(ps_search_base(kwss));
return NULL;
}
} else {
kwss->n_keyphrases = 1;
kwss->keyphrases = (kws_keyword_t *)ckd_calloc(kwss->n_keyphrases, sizeof(*kwss->keyphrases));
kwss->keyphrases[0].threshold = kwss->def_threshold;
kwss->keyphrases[0].word = ckd_salloc(keyphrase);
}
/* Check if all words are in dictionary */
if (!kws_search_check_dict(kwss)) {
kws_search_free(ps_search_base(kwss));
return NULL;
}
/* Reinit for provided keyword */
if (kws_search_reinit(ps_search_base(kwss),
ps_search_dict(kwss),
ps_search_dict2pid(kwss)) < 0) {
ps_search_free(ps_search_base(kwss));
return NULL;
}
return ps_search_base(kwss);
}
void
kws_search_free(ps_search_t * search)
{
int i;
kws_search_t *kwss;
kwss = (kws_search_t *) search;
ps_search_base_free(search);
hmm_context_free(kwss->hmmctx);
kws_detections_reset(kwss->detections);
ckd_free(kwss->detections);
ckd_free(kwss->pl_hmms);
for (i = 0; i < kwss->n_keyphrases; i++) {
ckd_free(kwss->keyphrases[i].hmms);
ckd_free(kwss->keyphrases[i].word);
}
ckd_free(kwss->keyphrases);
ckd_free(kwss);
}
int
kws_search_reinit(ps_search_t * search, dict_t * dict, dict2pid_t * d2p)
{
char **wrdptr;
char *tmp_keyphrase;
int32 wid, pronlen;
int32 n_hmms, n_wrds;
int32 ssid, tmatid;
int i, j, p, keyword_iter;
kws_search_t *kwss = (kws_search_t *) search;
bin_mdef_t *mdef = search->acmod->mdef;
int32 silcipid = bin_mdef_silphone(mdef);
/* Free old dict2pid, dict */
ps_search_base_reinit(search, dict, d2p);
/* Initialize HMM context. */
if (kwss->hmmctx)
hmm_context_free(kwss->hmmctx);
kwss->hmmctx =
hmm_context_init(bin_mdef_n_emit_state(search->acmod->mdef),
search->acmod->tmat->tp, NULL,
search->acmod->mdef->sseq);
if (kwss->hmmctx == NULL)
return -1;
/* Initialize phone loop HMMs. */
if (kwss->pl_hmms) {
for (i = 0; i < kwss->n_pl; ++i)
hmm_deinit((hmm_t *) & kwss->pl_hmms[i]);
ckd_free(kwss->pl_hmms);
}
kwss->n_pl = bin_mdef_n_ciphone(search->acmod->mdef);
kwss->pl_hmms =
(hmm_t *) ckd_calloc(kwss->n_pl, sizeof(*kwss->pl_hmms));
for (i = 0; i < kwss->n_pl; ++i) {
hmm_init(kwss->hmmctx, (hmm_t *) & kwss->pl_hmms[i],
FALSE,
bin_mdef_pid2ssid(search->acmod->mdef, i),
bin_mdef_pid2tmatid(search->acmod->mdef, i));
}
for (keyword_iter = 0; keyword_iter < kwss->n_keyphrases; keyword_iter++) {
kws_keyword_t *keyword = &kwss->keyphrases[keyword_iter];
/* Initialize keyphrase HMMs */
tmp_keyphrase = (char *) ckd_salloc(keyword->word);
n_wrds = str2words(tmp_keyphrase, NULL, 0);
wrdptr = (char **) ckd_calloc(n_wrds, sizeof(*wrdptr));
str2words(tmp_keyphrase, wrdptr, n_wrds);
/* count amount of hmms */
n_hmms = 0;
for (i = 0; i < n_wrds; i++) {
wid = dict_wordid(dict, wrdptr[i]);
pronlen = dict_pronlen(dict, wid);
n_hmms += pronlen;
}
/* allocate node array */
if (keyword->hmms)
ckd_free(keyword->hmms);
keyword->hmms = (hmm_t *) ckd_calloc(n_hmms, sizeof(hmm_t));
keyword->n_hmms = n_hmms;
/* fill node array */
j = 0;
for (i = 0; i < n_wrds; i++) {
wid = dict_wordid(dict, wrdptr[i]);
pronlen = dict_pronlen(dict, wid);
for (p = 0; p < pronlen; p++) {
int32 ci = dict_pron(dict, wid, p);
if (p == 0) {
/* first phone of word */
int32 rc =
pronlen > 1 ? dict_pron(dict, wid, 1) : silcipid;
ssid = dict2pid_ldiph_lc(d2p, ci, rc, silcipid);
}
else if (p == pronlen - 1) {
/* last phone of the word */
int32 lc = dict_pron(dict, wid, p - 1);
xwdssid_t *rssid = dict2pid_rssid(d2p, ci, lc);
int j = rssid->cimap[silcipid];
ssid = rssid->ssid[j];
}
else {
/* word internal phone */
ssid = dict2pid_internal(d2p, wid, p);
}
tmatid = bin_mdef_pid2tmatid(mdef, ci);
hmm_init(kwss->hmmctx, &keyword->hmms[j], FALSE, ssid,
tmatid);
j++;
}
}
ckd_free(wrdptr);
ckd_free(tmp_keyphrase);
}
return 0;
}
int
kws_search_start(ps_search_t * search)
{
int i;
kws_search_t *kwss = (kws_search_t *) search;
kwss->frame = 0;
kwss->bestscore = 0;
kws_detections_reset(kwss->detections);
/* Reset and enter all phone-loop HMMs. */
for (i = 0; i < kwss->n_pl; ++i) {
hmm_t *hmm = (hmm_t *) & kwss->pl_hmms[i];
hmm_clear(hmm);
hmm_enter(hmm, 0, -1, 0);
}
return 0;
}
int
kws_search_step(ps_search_t * search, int frame_idx)
{
int16 const *senscr;
kws_search_t *kwss = (kws_search_t *) search;
acmod_t *acmod = search->acmod;
/* Activate senones */
if (!acmod->compallsen)
kws_search_sen_active(kwss);
/* Calculate senone scores for current frame. */
senscr = acmod_score(acmod, &frame_idx);
/* Evaluate hmms in phone loop and in active keyword nodes */
kws_search_hmm_eval(kwss, senscr);
/* Prune hmms with low prob */
kws_search_hmm_prune(kwss);
/* Do hmms transitions */
kws_search_trans(kwss);
++kwss->frame;
return 0;
}
int
kws_search_finish(ps_search_t * search)
{
/* Nothing here */
return 0;
}
char const *
kws_search_hyp(ps_search_t * search, int32 * out_score,
int32 * out_is_final)
{
kws_search_t *kwss = (kws_search_t *) search;
if (out_score)
*out_score = 0;
if (search->hyp_str)
ckd_free(search->hyp_str);
search->hyp_str = kws_detections_hyp_str(kwss->detections, kwss->frame, kwss->delay);
return search->hyp_str;
}
char *
kws_search_get_keywords(ps_search_t * search)
{
int i, c, len;
kws_search_t *kwss;
char* line;
kwss = (kws_search_t *) search;
len = 0;
for (i = 0; i < kwss->n_keyphrases; i++)
len += strlen(kwss->keyphrases[i].word);
len += kwss->n_keyphrases;
c = 0;
line = (char *)ckd_calloc(len, sizeof(*line));
for (i = 0; i < kwss->n_keyphrases; i++) {
char *keyword_str = kwss->keyphrases[i].word;
memcpy(&line[c], keyword_str, strlen(keyword_str));
c += strlen(keyword_str);
line[c++] = '\n';
}
line[--c] = '\0';
return line;
}

View File

@ -0,0 +1,138 @@
/* -*- c-basic-offset: 4; indent-tabs-mode: nil -*- */
/* ====================================================================
* Copyright (c) 2013 Carnegie Mellon University. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. 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 CARNEGIE MELLON UNIVERSITY ``AS IS'' AND
* ANY EXPRESSED 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 CARNEGIE MELLON UNIVERSITY
* NOR ITS EMPLOYEES 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.
*
* ====================================================================
*
*/
/*
* kws_search.h -- Search structures for keyword spotting.
*/
#ifndef __KWS_SEARCH_H__
#define __KWS_SEARCH_H__
/* SphinxBase headers. */
#include <sphinxbase/glist.h>
#include <sphinxbase/cmd_ln.h>
/* Local headers. */
#include "pocketsphinx_internal.h"
#include "kws_detections.h"
#include "hmm.h"
/**
* Segmentation "iterator" for KWS history.
*/
typedef struct kws_seg_s {
ps_seg_t base; /**< Base structure. */
gnode_t *detection; /**< Keyword detection correspondent to segment. */
frame_idx_t last_frame; /**< Last frame to raise the detection */
} kws_seg_t;
typedef struct kws_keyword_s {
char* word;
int32 threshold;
hmm_t* hmms;
int32 n_hmms;
} kws_keyword_t;
/**
* Implementation of KWS search structure.
*/
typedef struct kws_search_s {
ps_search_t base;
hmm_context_t *hmmctx; /**< HMM context. */
kws_detections_t *detections; /**< Keyword spotting history */
kws_keyword_t* keyphrases; /**< Keyphrases to spot */
int n_keyphrases; /**< Keyphrases amount */
frame_idx_t frame; /**< Frame index */
int32 beam;
int32 plp; /**< Phone loop probability */
int32 bestscore; /**< For beam pruning */
int32 def_threshold; /**< default threshold for p(hyp)/p(altern) ratio */
int32 delay; /**< Delay to wait for best detection score */
int32 n_pl; /**< Number of CI phones */
hmm_t *pl_hmms; /**< Phone loop hmms - hmms of CI phones */
} kws_search_t;
/**
* Create, initialize and return a search module. Gets keywords either
* from keyphrase or from a keyphrase file.
*/
ps_search_t *kws_search_init(const char *name,
const char *keyphrase,
const char *keyfile,
cmd_ln_t * config,
acmod_t * acmod,
dict_t * dict, dict2pid_t * d2p);
/**
* Deallocate search structure.
*/
void kws_search_free(ps_search_t * search);
/**
* Update KWS search module for new key phrase.
*/
int kws_search_reinit(ps_search_t * kwss, dict_t * dict, dict2pid_t * d2p);
/**
* Prepare the KWS search structure for beginning decoding of the next
* utterance.
*/
int kws_search_start(ps_search_t * search);
/**
* Step one frame forward through the Viterbi search.
*/
int kws_search_step(ps_search_t * search, int frame_idx);
/**
* Windup and clean the KWS search structure after utterance.
*/
int kws_search_finish(ps_search_t * search);
/**
* Get hypothesis string from the KWS search.
*/
char const *kws_search_hyp(ps_search_t * search, int32 * out_score,
int32 * out_is_final);
/**
* Get active keyphrases
*/
char* kws_search_get_keywords(ps_search_t * search);
#endif /* __KWS_SEARCH_H__ */

View File

@ -0,0 +1,766 @@
/* -*- c-basic-offset: 4; indent-tabs-mode: nil -*- */
/* ====================================================================
* Copyright (c) 1999-2004 Carnegie Mellon University. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. 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 work was supported in part by funding from the Defense Advanced
* Research Projects Agency and the National Science Foundation of the
* United States of America, and the CMU Sphinx Speech Consortium.
*
* THIS SOFTWARE IS PROVIDED BY CARNEGIE MELLON UNIVERSITY ``AS IS'' AND
* ANY EXPRESSED 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 CARNEGIE MELLON UNIVERSITY
* NOR ITS EMPLOYEES 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.
*
* ====================================================================
*
*/
/*
* mdef.c -- HMM model definition: base (CI) phones and triphones
*
* **********************************************
* CMU ARPA Speech Project
*
* Copyright (c) 1999 Carnegie Mellon University.
* ALL RIGHTS RESERVED.
* **********************************************
*
* HISTORY
*
*
* 22-Nov-2004 M K Ravishankar (rkm@cs.cmu.edu) at Carnegie Mellon University
* Imported from s3.2, for supporting s3 format continuous
* acoustic models.
*
* 14-Oct-1999 M K Ravishankar (rkm@cs.cmu.edu) at Carnegie Mellon
* Added mdef_sseq2sen_active().
*
* 06-May-1999 M K Ravishankar (rkm@cs.cmu.edu) at Carnegie Mellon
* In mdef_phone_id(), added backing off to silence phone context from filler
* context if original triphone not found.
*
* 30-Apr-1999 M K Ravishankar (rkm@cs.cmu.edu) at Carnegie Mellon
* Added senone-sequence id (ssid) to phone_t and appropriate functions to
* maintain it. Instead, moved state sequence info to mdef_t.
*
* 13-Jul-96 M K Ravishankar (rkm@cs.cmu.edu) at Carnegie Mellon University.
* Added mdef_phone_str().
*
* 01-Jan-96 M K Ravishankar (rkm@cs.cmu.edu) at Carnegie Mellon University.
* Allowed mdef_phone_id_nearest to return base phone id if either
* left or right context (or both) is undefined.
*
* 01-Jan-96 M K Ravishankar (rkm@cs.cmu.edu) at Carnegie Mellon University.
* Created.
*/
/*
* Major assumptions:
* All phones have same #states, same topology.
* Every phone has exactly one non-emitting, final state--the last one.
* CI phones must appear first in model definition file.
*/
/* System headers. */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
/* SphinxBase headers. */
#include <sphinxbase/ckd_alloc.h>
#include <sphinxbase/err.h>
/* Local headers. */
#include "mdef.h"
#define MODEL_DEF_VERSION "0.3"
static void
ciphone_add(mdef_t * m, char *ci, int p)
{
assert(p < m->n_ciphone);
m->ciphone[p].name = (char *) ckd_salloc(ci); /* freed in mdef_free */
if (hash_table_enter(m->ciphone_ht, m->ciphone[p].name,
(void *)(long)p) != (void *)(long)p)
E_FATAL("hash_table_enter(%s) failed; duplicate CIphone?\n",
m->ciphone[p].name);
}
static ph_lc_t *
find_ph_lc(ph_lc_t * lclist, int lc)
{
ph_lc_t *lcptr;
for (lcptr = lclist; lcptr && (lcptr->lc != lc); lcptr = lcptr->next);
return lcptr;
}
static ph_rc_t *
find_ph_rc(ph_rc_t * rclist, int rc)
{
ph_rc_t *rcptr;
for (rcptr = rclist; rcptr && (rcptr->rc != rc); rcptr = rcptr->next);
return rcptr;
}
static void
triphone_add(mdef_t * m,
int ci, int lc, int rc, word_posn_t wpos,
int p)
{
ph_lc_t *lcptr;
ph_rc_t *rcptr;
assert(p < m->n_phone);
/* Fill in phone[p] information (state and tmat mappings added later) */
m->phone[p].ci = ci;
m->phone[p].lc = lc;
m->phone[p].rc = rc;
m->phone[p].wpos = wpos;
/* Create <ci,lc,rc,wpos> -> p mapping if not a CI phone */
if (p >= m->n_ciphone) {
if ((lcptr = find_ph_lc(m->wpos_ci_lclist[wpos][(int) ci], lc))
== NULL) {
lcptr = (ph_lc_t *) ckd_calloc(1, sizeof(ph_lc_t)); /* freed at mdef_free, I believe */
lcptr->lc = lc;
lcptr->next = m->wpos_ci_lclist[wpos][(int) ci];
m->wpos_ci_lclist[wpos][(int) ci] = lcptr; /* This is what needs to be freed */
}
if ((rcptr = find_ph_rc(lcptr->rclist, rc)) != NULL) {
__BIGSTACKVARIABLE__ char buf[4096];
mdef_phone_str(m, rcptr->pid, buf);
E_FATAL("Duplicate triphone: %s\n", buf);
}
rcptr = (ph_rc_t *) ckd_calloc(1, sizeof(ph_rc_t)); /* freed in mdef_free, I believe */
rcptr->rc = rc;
rcptr->pid = p;
rcptr->next = lcptr->rclist;
lcptr->rclist = rcptr;
}
}
int
mdef_ciphone_id(mdef_t * m, char *ci)
{
int32 id;
if (hash_table_lookup_int32(m->ciphone_ht, ci, &id) < 0)
return -1;
return id;
}
const char *
mdef_ciphone_str(mdef_t * m, int id)
{
assert(m);
assert((id >= 0) && (id < m->n_ciphone));
return (m->ciphone[id].name);
}
int
mdef_phone_str(mdef_t * m, int pid, char *buf)
{
char *wpos_name;
assert(m);
assert((pid >= 0) && (pid < m->n_phone));
wpos_name = WPOS_NAME;
buf[0] = '\0';
if (pid < m->n_ciphone)
sprintf(buf, "%s", mdef_ciphone_str(m, pid));
else {
sprintf(buf, "%s %s %s %c",
mdef_ciphone_str(m, m->phone[pid].ci),
mdef_ciphone_str(m, m->phone[pid].lc),
mdef_ciphone_str(m, m->phone[pid].rc),
wpos_name[m->phone[pid].wpos]);
}
return 0;
}
int
mdef_phone_id(mdef_t * m,
int ci, int lc, int rc, word_posn_t wpos)
{
ph_lc_t *lcptr;
ph_rc_t *rcptr;
int newl, newr;
assert(m);
assert((ci >= 0) && (ci < m->n_ciphone));
assert((lc >= 0) && (lc < m->n_ciphone));
assert((rc >= 0) && (rc < m->n_ciphone));
assert((wpos >= 0) && (wpos < N_WORD_POSN));
if (((lcptr =
find_ph_lc(m->wpos_ci_lclist[wpos][(int) ci], lc)) == NULL)
|| ((rcptr = find_ph_rc(lcptr->rclist, rc)) == NULL)) {
/* Not found; backoff to silence context if non-silence filler context */
if (m->sil < 0)
return -1;
newl = m->ciphone[(int) lc].filler ? m->sil : lc;
newr = m->ciphone[(int) rc].filler ? m->sil : rc;
if ((newl == lc) && (newr == rc))
return -1;
return (mdef_phone_id(m, ci, newl, newr, wpos));
}
return (rcptr->pid);
}
int
mdef_is_ciphone(mdef_t * m, int p)
{
assert(m);
assert((p >= 0) && (p < m->n_phone));
return ((p < m->n_ciphone) ? 1 : 0);
}
int
mdef_is_cisenone(mdef_t * m, int s)
{
assert(m);
if (s >= m->n_sen) {
return 0;
}
assert(s >= 0);
return ((s == m->cd2cisen[s]) ? 1 : 0);
}
/* Parse tmat and state->senone mappings for phone p and fill in structure */
static void
parse_tmat_senmap(mdef_t * m, char *line, long off, int p)
{
int32 wlen, n, s;
char *lp;
__BIGSTACKVARIABLE__ char word[1024];
lp = line + off;
/* Read transition matrix id */
if ((sscanf(lp, "%d%n", &n, &wlen) != 1) || (n < 0))
E_FATAL("Missing or bad transition matrix id: %s\n", line);
m->phone[p].tmat = n;
if (m->n_tmat <= n)
E_FATAL("tmat-id(%d) > #tmat in header(%d): %s\n", n, m->n_tmat,
line);
lp += wlen;
/* Read senone mappings for each emitting state */
for (n = 0; n < m->n_emit_state; n++) {
if ((sscanf(lp, "%d%n", &s, &wlen) != 1) || (s < 0))
E_FATAL("Missing or bad state[%d]->senone mapping: %s\n", n,
line);
if ((p < m->n_ciphone) && (m->n_ci_sen <= s))
E_FATAL("CI-senone-id(%d) > #CI-senones(%d): %s\n", s,
m->n_ci_sen, line);
if (m->n_sen <= s)
E_FATAL("Senone-id(%d) > #senones(%d): %s\n", s, m->n_sen,
line);
m->sseq[p][n] = s;
lp += wlen;
}
/* Check for the last non-emitting state N */
if ((sscanf(lp, "%s%n", word, &wlen) != 1) || (strcmp(word, "N") != 0))
E_FATAL("Missing non-emitting state spec: %s\n", line);
lp += wlen;
/* Check for end of line */
if (sscanf(lp, "%s%n", word, &wlen) == 1)
E_FATAL("Non-empty beyond non-emitting final state: %s\n", line);
}
static void
parse_base_line(mdef_t * m, char *line, int p)
{
int32 wlen, n;
__BIGSTACKVARIABLE__ char word[1024], *lp;
int ci;
lp = line;
/* Read base phone name */
if (sscanf(lp, "%s%n", word, &wlen) != 1)
E_FATAL("Missing base phone name: %s\n", line);
lp += wlen;
/* Make sure it's not a duplicate */
ci = mdef_ciphone_id(m, word);
if (ci >= 0)
E_FATAL("Duplicate base phone: %s\n", line);
/* Add ciphone to ciphone table with id p */
ciphone_add(m, word, p);
ci = (int) p;
/* Read and skip "-" for lc, rc, wpos */
for (n = 0; n < 3; n++) {
if ((sscanf(lp, "%s%n", word, &wlen) != 1)
|| (strcmp(word, "-") != 0))
E_FATAL("Bad context info for base phone: %s\n", line);
lp += wlen;
}
/* Read filler attribute, if present */
if (sscanf(lp, "%s%n", word, &wlen) != 1)
E_FATAL("Missing filler atribute field: %s\n", line);
lp += wlen;
if (strcmp(word, "filler") == 0)
m->ciphone[(int) ci].filler = 1;
else if (strcmp(word, "n/a") == 0)
m->ciphone[(int) ci].filler = 0;
else
E_FATAL("Bad filler attribute field: %s\n", line);
triphone_add(m, ci, -1, -1, WORD_POSN_UNDEFINED, p);
/* Parse remainder of line: transition matrix and state->senone mappings */
parse_tmat_senmap(m, line, lp - line, p);
}
static void
parse_tri_line(mdef_t * m, char *line, int p)
{
int32 wlen;
__BIGSTACKVARIABLE__ char word[1024], *lp;
int ci, lc, rc;
word_posn_t wpos = WORD_POSN_BEGIN;
lp = line;
/* Read base phone name */
if (sscanf(lp, "%s%n", word, &wlen) != 1)
E_FATAL("Missing base phone name: %s\n", line);
lp += wlen;
ci = mdef_ciphone_id(m, word);
if (ci < 0)
E_FATAL("Unknown base phone: %s\n", line);
/* Read lc */
if (sscanf(lp, "%s%n", word, &wlen) != 1)
E_FATAL("Missing left context: %s\n", line);
lp += wlen;
lc = mdef_ciphone_id(m, word);
if (lc < 0)
E_FATAL("Unknown left context: %s\n", line);
/* Read rc */
if (sscanf(lp, "%s%n", word, &wlen) != 1)
E_FATAL("Missing right context: %s\n", line);
lp += wlen;
rc = mdef_ciphone_id(m, word);
if (rc < 0)
E_FATAL("Unknown right context: %s\n", line);
/* Read tripone word-position within word */
if ((sscanf(lp, "%s%n", word, &wlen) != 1) || (word[1] != '\0'))
E_FATAL("Missing or bad word-position spec: %s\n", line);
lp += wlen;
switch (word[0]) {
case 'b':
wpos = WORD_POSN_BEGIN;
break;
case 'e':
wpos = WORD_POSN_END;
break;
case 's':
wpos = WORD_POSN_SINGLE;
break;
case 'i':
wpos = WORD_POSN_INTERNAL;
break;
default:
E_FATAL("Bad word-position spec: %s\n", line);
}
/* Read filler attribute, if present. Must match base phone attribute */
if (sscanf(lp, "%s%n", word, &wlen) != 1)
E_FATAL("Missing filler attribute field: %s\n", line);
lp += wlen;
if (((strcmp(word, "filler") == 0) && (m->ciphone[(int) ci].filler)) ||
((strcmp(word, "n/a") == 0) && (!m->ciphone[(int) ci].filler))) {
/* Everything is fine */
}
else
E_FATAL("Bad filler attribute field: %s\n", line);
triphone_add(m, ci, lc, rc, wpos, p);
/* Parse remainder of line: transition matrix and state->senone mappings */
parse_tmat_senmap(m, line, lp - line, p);
}
static void
sseq_compress(mdef_t * m)
{
hash_table_t *h;
uint16 **sseq;
int32 n_sseq;
int32 p, j, k;
glist_t g;
gnode_t *gn;
hash_entry_t *he;
k = m->n_emit_state * sizeof(int16);
h = hash_table_new(m->n_phone, HASH_CASE_YES);
n_sseq = 0;
/* Identify unique senone-sequence IDs. BUG: tmat-id not being considered!! */
for (p = 0; p < m->n_phone; p++) {
/* Add senone sequence to hash table */
if (n_sseq
== (j = hash_table_enter_bkey_int32(h, (char *)m->sseq[p], k, n_sseq)))
n_sseq++;
m->phone[p].ssid = j;
}
/* Generate compacted sseq table */
sseq = ckd_calloc_2d(n_sseq, m->n_emit_state, sizeof(**sseq)); /* freed in mdef_free() */
g = hash_table_tolist(h, &j);
assert(j == n_sseq);
for (gn = g; gn; gn = gnode_next(gn)) {
he = (hash_entry_t *) gnode_ptr(gn);
j = (int32)(long)hash_entry_val(he);
memcpy(sseq[j], hash_entry_key(he), k);
}
glist_free(g);
/* Free the old, temporary senone sequence table, replace with compacted one */
ckd_free_2d(m->sseq);
m->sseq = sseq;
m->n_sseq = n_sseq;
hash_table_free(h);
}
static int32
noncomment_line(char *line, int32 size, FILE * fp)
{
while (fgets(line, size, fp) != NULL) {
if (line[0] != '#')
return 0;
}
return -1;
}
/*
* Initialize phones (ci and triphones) and state->senone mappings from .mdef file.
*/
mdef_t *
mdef_init(char *mdeffile, int32 breport)
{
FILE *fp;
int32 n_ci, n_tri, n_map, n;
__BIGSTACKVARIABLE__ char tag[1024], buf[1024];
uint16 **senmap;
int p;
int32 s, ci, cd;
mdef_t *m;
if (!mdeffile)
E_FATAL("No mdef-file\n");
if (breport)
E_INFO("Reading model definition: %s\n", mdeffile);
m = (mdef_t *) ckd_calloc(1, sizeof(mdef_t)); /* freed in mdef_free */
if ((fp = fopen(mdeffile, "r")) == NULL)
E_FATAL_SYSTEM("Failed to open mdef file '%s' for reading", mdeffile);
if (noncomment_line(buf, sizeof(buf), fp) < 0)
E_FATAL("Empty file: %s\n", mdeffile);
if (strncmp(buf, "BMDF", 4) == 0 || strncmp(buf, "FDMB", 4) == 0) {
E_INFO
("Found byte-order mark %.4s, assuming this is a binary mdef file\n",
buf);
fclose(fp);
ckd_free(m);
return NULL;
}
if (strncmp(buf, MODEL_DEF_VERSION, strlen(MODEL_DEF_VERSION)) != 0)
E_FATAL("Version error: Expecing %s, but read %s\n",
MODEL_DEF_VERSION, buf);
/* Read #base phones, #triphones, #senone mappings defined in header */
n_ci = -1;
n_tri = -1;
n_map = -1;
m->n_ci_sen = -1;
m->n_sen = -1;
m->n_tmat = -1;
do {
if (noncomment_line(buf, sizeof(buf), fp) < 0)
E_FATAL("Incomplete header\n");
if ((sscanf(buf, "%d %s", &n, tag) != 2) || (n < 0))
E_FATAL("Error in header: %s\n", buf);
if (strcmp(tag, "n_base") == 0)
n_ci = n;
else if (strcmp(tag, "n_tri") == 0)
n_tri = n;
else if (strcmp(tag, "n_state_map") == 0)
n_map = n;
else if (strcmp(tag, "n_tied_ci_state") == 0)
m->n_ci_sen = n;
else if (strcmp(tag, "n_tied_state") == 0)
m->n_sen = n;
else if (strcmp(tag, "n_tied_tmat") == 0)
m->n_tmat = n;
else
E_FATAL("Unknown header line: %s\n", buf);
} while ((n_ci < 0) || (n_tri < 0) || (n_map < 0) ||
(m->n_ci_sen < 0) || (m->n_sen < 0) || (m->n_tmat < 0));
if ((n_ci == 0) || (m->n_ci_sen == 0) || (m->n_tmat == 0)
|| (m->n_ci_sen > m->n_sen))
E_FATAL("%s: Error in header\n", mdeffile);
/* Check typesize limits */
if (n_ci >= MAX_INT16)
E_FATAL("%s: #CI phones (%d) exceeds limit (%d)\n", mdeffile, n_ci,
MAX_INT16);
if (n_ci + n_tri >= MAX_INT32) /* Comparison is always false... */
E_FATAL("%s: #Phones (%d) exceeds limit (%d)\n", mdeffile,
n_ci + n_tri, MAX_INT32);
if (m->n_sen >= MAX_INT16)
E_FATAL("%s: #senones (%d) exceeds limit (%d)\n", mdeffile,
m->n_sen, MAX_INT16);
if (m->n_tmat >= MAX_INT32) /* Comparison is always false... */
E_FATAL("%s: #tmats (%d) exceeds limit (%d)\n", mdeffile,
m->n_tmat, MAX_INT32);
m->n_emit_state = (n_map / (n_ci + n_tri)) - 1;
if ((m->n_emit_state + 1) * (n_ci + n_tri) != n_map)
E_FATAL
("Header error: n_state_map not a multiple of n_ci*n_tri\n");
/* Initialize ciphone info */
m->n_ciphone = n_ci;
m->ciphone_ht = hash_table_new(n_ci, HASH_CASE_YES); /* With case-insensitive string names *//* freed in mdef_free */
m->ciphone = (ciphone_t *) ckd_calloc(n_ci, sizeof(ciphone_t)); /* freed in mdef_free */
/* Initialize phones info (ciphones + triphones) */
m->n_phone = n_ci + n_tri;
m->phone = (phone_t *) ckd_calloc(m->n_phone, sizeof(phone_t)); /* freed in mdef_free */
/* Allocate space for state->senone map for each phone */
senmap = ckd_calloc_2d(m->n_phone, m->n_emit_state, sizeof(**senmap)); /* freed in mdef_free */
m->sseq = senmap; /* TEMPORARY; until it is compressed into just the unique ones */
/* Allocate initial space for <ci,lc,rc,wpos> -> pid mapping */
m->wpos_ci_lclist = (ph_lc_t ***) ckd_calloc_2d(N_WORD_POSN, m->n_ciphone, sizeof(ph_lc_t *)); /* freed in mdef_free */
/*
* Read base phones and triphones. They'll simply be assigned a running sequence
* number as their "phone-id". If the phone-id < n_ci, it's a ciphone.
*/
/* Read base phones */
for (p = 0; p < n_ci; p++) {
if (noncomment_line(buf, sizeof(buf), fp) < 0)
E_FATAL("Premature EOF reading CIphone %d\n", p);
parse_base_line(m, buf, p);
}
m->sil = mdef_ciphone_id(m, S3_SILENCE_CIPHONE);
/* Read triphones, if any */
for (; p < m->n_phone; p++) {
if (noncomment_line(buf, sizeof(buf), fp) < 0)
E_FATAL("Premature EOF reading phone %d\n", p);
parse_tri_line(m, buf, p);
}
if (noncomment_line(buf, sizeof(buf), fp) >= 0)
E_ERROR("Non-empty file beyond expected #phones (%d)\n",
m->n_phone);
/* Build CD senones to CI senones map */
if (m->n_ciphone * m->n_emit_state != m->n_ci_sen)
E_FATAL
("#CI-senones(%d) != #CI-phone(%d) x #emitting-states(%d)\n",
m->n_ci_sen, m->n_ciphone, m->n_emit_state);
m->cd2cisen = (int16 *) ckd_calloc(m->n_sen, sizeof(*m->cd2cisen)); /* freed in mdef_free */
m->sen2cimap = (int16 *) ckd_calloc(m->n_sen, sizeof(*m->sen2cimap)); /* freed in mdef_free */
for (s = 0; s < m->n_sen; s++)
m->sen2cimap[s] = -1;
for (s = 0; s < m->n_ci_sen; s++) { /* CI senones */
m->cd2cisen[s] = s;
m->sen2cimap[s] = s / m->n_emit_state;
}
for (p = n_ci; p < m->n_phone; p++) { /* CD senones */
for (s = 0; s < m->n_emit_state; s++) {
cd = m->sseq[p][s];
ci = m->sseq[m->phone[p].ci][s];
m->cd2cisen[cd] = ci;
m->sen2cimap[cd] = m->phone[p].ci;
}
}
sseq_compress(m);
fclose(fp);
return m;
}
void
mdef_report(mdef_t * m)
{
E_INFO_NOFN("Initialization of mdef_t, report:\n");
E_INFO_NOFN
("%d CI-phone, %d CD-phone, %d emitstate/phone, %d CI-sen, %d Sen, %d Sen-Seq\n",
m->n_ciphone, m->n_phone - m->n_ciphone, m->n_emit_state,
m->n_ci_sen, m->n_sen, m->n_sseq);
E_INFO_NOFN("\n");
}
/* RAH 4.23.01, Need to step down the ->next list to see if there are
any more things to free
*/
/* RAH 4.19.01, Attempt to free memory that was allocated within this module
I have not verified that all the memory has been freed. I've taken only a
reasonable effort for now.
RAH 4.24.01 - verified that all memory is released.
*/
void
mdef_free_recursive_lc(ph_lc_t * lc)
{
if (lc == NULL)
return;
if (lc->rclist)
mdef_free_recursive_rc(lc->rclist);
if (lc->next)
mdef_free_recursive_lc(lc->next);
ckd_free((void *) lc);
}
void
mdef_free_recursive_rc(ph_rc_t * rc)
{
if (rc == NULL)
return;
if (rc->next)
mdef_free_recursive_rc(rc->next);
ckd_free((void *) rc);
}
/* RAH, Free memory that was allocated in mdef_init
Rational purify shows that no leaks exist
*/
void
mdef_free(mdef_t * m)
{
int i, j;
if (m) {
if (m->sen2cimap)
ckd_free((void *) m->sen2cimap);
if (m->cd2cisen)
ckd_free((void *) m->cd2cisen);
/* RAH, go down the ->next list and delete all the pieces */
for (i = 0; i < N_WORD_POSN; i++)
for (j = 0; j < m->n_ciphone; j++)
if (m->wpos_ci_lclist[i][j]) {
mdef_free_recursive_lc(m->wpos_ci_lclist[i][j]->next);
mdef_free_recursive_rc(m->wpos_ci_lclist[i][j]->
rclist);
}
for (i = 0; i < N_WORD_POSN; i++)
for (j = 0; j < m->n_ciphone; j++)
if (m->wpos_ci_lclist[i][j])
ckd_free((void *) m->wpos_ci_lclist[i][j]);
if (m->wpos_ci_lclist)
ckd_free_2d((void *) m->wpos_ci_lclist);
if (m->sseq)
ckd_free_2d((void *) m->sseq);
/* Free phone context */
if (m->phone)
ckd_free((void *) m->phone);
if (m->ciphone_ht)
hash_table_free(m->ciphone_ht);
for (i = 0; i < m->n_ciphone; i++) {
if (m->ciphone[i].name)
ckd_free((void *) m->ciphone[i].name);
}
if (m->ciphone)
ckd_free((void *) m->ciphone);
ckd_free((void *) m);
}
}

View File

@ -0,0 +1,271 @@
/* -*- c-basic-offset: 4; indent-tabs-mode: nil -*- */
/* ====================================================================
* Copyright (c) 1999-2004 Carnegie Mellon University. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. 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 work was supported in part by funding from the Defense Advanced
* Research Projects Agency and the National Science Foundation of the
* United States of America, and the CMU Sphinx Speech Consortium.
*
* THIS SOFTWARE IS PROVIDED BY CARNEGIE MELLON UNIVERSITY ``AS IS'' AND
* ANY EXPRESSED 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 CARNEGIE MELLON UNIVERSITY
* NOR ITS EMPLOYEES 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.
*
* ====================================================================
*
*/
/*
* mdef.h -- HMM model definition: base (CI) phones and triphones
*
* **********************************************
* CMU ARPA Speech Project
*
* Copyright (c) 1999 Carnegie Mellon University.
* ALL RIGHTS RESERVED.
* **********************************************
*/
#ifndef __MDEF_H__
#define __MDEF_H__
/* System headers. */
#include <stdio.h>
/* SphinxBase headers. */
#include <sphinxbase/hash_table.h>
#ifdef __cplusplus
extern "C" {
#endif
/** \file mdef.h
* \brief Model definition
*/
/** \enum word_posn_t
* \brief Union of different type of word position
*/
typedef enum {
WORD_POSN_INTERNAL = 0, /**< Internal phone of word */
WORD_POSN_BEGIN = 1, /**< Beginning phone of word */
WORD_POSN_END = 2, /**< Ending phone of word */
WORD_POSN_SINGLE = 3, /**< Single phone word (i.e. begin & end) */
WORD_POSN_UNDEFINED = 4 /**< Undefined value, used for initial conditions, etc */
} word_posn_t;
#define N_WORD_POSN 4 /**< total # of word positions (excluding undefined) */
#define WPOS_NAME "ibesu" /**< Printable code for each word position above */
#define S3_SILENCE_CIPHONE "SIL" /**< Hard-coded silence CI phone name */
/**
\struct ciphone_t
\brief CI phone information
*/
typedef struct {
char *name; /**< The name of the CI phone */
int32 filler; /**< Whether a filler phone; if so, can be substituted by
silence phone in left or right context position */
} ciphone_t;
/**
* \struct phone_t
* \brief Triphone information, including base phones as a subset. For the latter, lc, rc and wpos are non-existent.
*/
typedef struct {
int32 ssid; /**< State sequence (or senone sequence) ID, considering the
n_emit_state senone-ids are a unit. The senone sequences
themselves are in a separate table */
int32 tmat; /**< Transition matrix id */
int16 ci, lc, rc; /**< Base, left, right context ciphones */
word_posn_t wpos; /**< Word position */
} phone_t;
/**
* \struct ph_rc_t
* \brief Structures needed for mapping <ci,lc,rc,wpos> into pid. (See mdef_t.wpos_ci_lclist below.) (lc = left context; rc = right context.)
* NOTE: Both ph_rc_t and ph_lc_t FOR INTERNAL USE ONLY.
*/
typedef struct ph_rc_s {
int16 rc; /**< Specific rc for a parent <wpos,ci,lc> */
int32 pid; /**< Triphone id for above rc instance */
struct ph_rc_s *next; /**< Next rc entry for same parent <wpos,ci,lc> */
} ph_rc_t;
/**
* \struct ph_lc_t
* \brief Structures for storing the left context.
*/
typedef struct ph_lc_s {
int16 lc; /**< Specific lc for a parent <wpos,ci> */
ph_rc_t *rclist; /**< rc list for above lc instance */
struct ph_lc_s *next; /**< Next lc entry for same parent <wpos,ci> */
} ph_lc_t;
/** The main model definition structure */
/**
\struct mdef_t
\brief strcture for storing the model definition.
*/
typedef struct {
int32 n_ciphone; /**< number basephones actually present */
int32 n_phone; /**< number basephones + number triphones actually present */
int32 n_emit_state; /**< number emitting states per phone */
int32 n_ci_sen; /**< number CI senones; these are the first */
int32 n_sen; /**< number senones (CI+CD) */
int32 n_tmat; /**< number transition matrices */
hash_table_t *ciphone_ht; /**< Hash table for mapping ciphone strings to ids */
ciphone_t *ciphone; /**< CI-phone information for all ciphones */
phone_t *phone; /**< Information for all ciphones and triphones */
uint16 **sseq; /**< Unique state (or senone) sequences in this model, shared
among all phones/triphones */
int32 n_sseq; /**< No. of unique senone sequences in this model */
int16 *cd2cisen; /**< Parent CI-senone id for each senone; the first
n_ci_sen are identity mappings; the CD-senones are
contiguous for each parent CI-phone */
int16 *sen2cimap; /**< Parent CI-phone for each senone (CI or CD) */
int16 sil; /**< SILENCE_CIPHONE id */
ph_lc_t ***wpos_ci_lclist; /**< wpos_ci_lclist[wpos][ci] = list of lc for <wpos,ci>.
wpos_ci_lclist[wpos][ci][lc].rclist = list of rc for
<wpos,ci,lc>. Only entries for the known triphones
are created to conserve space.
(NOTE: FOR INTERNAL USE ONLY.) */
} mdef_t;
/** Access macros; not meant for arbitrary use */
#define mdef_is_fillerphone(m,p) ((m)->ciphone[p].filler)
#define mdef_n_ciphone(m) ((m)->n_ciphone)
#define mdef_n_phone(m) ((m)->n_phone)
#define mdef_n_sseq(m) ((m)->n_sseq)
#define mdef_n_emit_state(m) ((m)->n_emit_state)
#define mdef_n_sen(m) ((m)->n_sen)
#define mdef_n_tmat(m) ((m)->n_tmat)
#define mdef_pid2ssid(m,p) ((m)->phone[p].ssid)
#define mdef_pid2tmatid(m,p) ((m)->phone[p].tmat)
#define mdef_silphone(m) ((m)->sil)
#define mdef_sen2cimap(m) ((m)->sen2cimap)
#define mdef_sseq2sen(m,ss,pos) ((m)->sseq[ss][pos])
#define mdef_pid2ci(m,p) ((m)->phone[p].ci)
#define mdef_cd2cisen(m) ((m)->cd2cisen)
/**
* Initialize the phone structure from the given model definition file.
* It should be treated as a READ-ONLY structure.
* @return pointer to the phone structure created.
*/
mdef_t *mdef_init (char *mdeffile, /**< In: Model definition file */
int breport /**< In: whether to report the progress or not */
);
/**
Get the ciphone id given a string name
@return ciphone id for the given ciphone string name
*/
int mdef_ciphone_id(mdef_t *m, /**< In: Model structure being queried */
char *ciphone /**< In: ciphone for which id wanted */
);
/**
Get the phone string given the ci phone id.
@return: READ-ONLY ciphone string name for the given ciphone id
*/
const char *mdef_ciphone_str(mdef_t *m, /**< In: Model structure being queried */
int ci /**< In: ciphone id for which name wanted */
);
/**
Decide whether the phone is ci phone.
@return 1 if given triphone argument is a ciphone, 0 if not, -1 if error
*/
int mdef_is_ciphone (mdef_t *m, /**< In: Model structure being queried */
int p /**< In: triphone id being queried */
);
/**
Decide whether the senone is a senone for a ci phone, or a ci senone
@return 1 if a given senone is a ci senone
*/
int mdef_is_cisenone(mdef_t *m, /**< In: Model structure being queried */
int s /**< In: senone id being queried */
);
/**
Decide the phone id given the left, right and base phones.
@return: phone id for the given constituents if found, else BAD_S3PID
*/
int mdef_phone_id (mdef_t *m, /**< In: Model structure being queried */
int b, /**< In: base ciphone id */
int l, /**< In: left context ciphone id */
int r, /**< In: right context ciphone id */
word_posn_t pos /**< In: Word position */
);
/**
* Create a phone string for the given phone (base or triphone) id in the given buf.
* @return 0 if successful, -1 if error.
*/
int mdef_phone_str(mdef_t *m, /**< In: Model structure being queried */
int pid, /**< In: phone id being queried */
char *buf /**< Out: On return, buf has the string */
);
/**
* Compare the underlying HMMs for two given phones (i.e., compare the two transition
* matrix IDs and the individual state(senone) IDs).
* @return 0 iff the HMMs are identical, -1 otherwise.
*/
int mdef_hmm_cmp (mdef_t *m, /**< In: Model being queried */
int p1, /**< In: One of the two triphones being compared */
int p2 /**< In: One of the two triphones being compared */
);
/** Report the model definition's parameters */
void mdef_report(mdef_t *m /**< In: model definition structure */
);
/** RAH, For freeing memory */
void mdef_free_recursive_lc (ph_lc_t *lc /**< In: A list of left context */
);
void mdef_free_recursive_rc (ph_rc_t *rc /**< In: A list of right context */
);
/** Free an mdef_t */
void mdef_free (mdef_t *mdef /**< In : The model definition*/
);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,617 @@
/* -*- c-basic-offset: 4; indent-tabs-mode: nil -*- */
/* ====================================================================
* Copyright (c) 1999-2004 Carnegie Mellon University. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. 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 work was supported in part by funding from the Defense Advanced
* Research Projects Agency and the National Science Foundation of the
* United States of America, and the CMU Sphinx Speech Consortium.
*
* THIS SOFTWARE IS PROVIDED BY CARNEGIE MELLON UNIVERSITY ``AS IS'' AND
* ANY EXPRESSED 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 CARNEGIE MELLON UNIVERSITY
* NOR ITS EMPLOYEES 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.
*
* ====================================================================
*
*/
/*
* gauden.c -- gaussian density module.
*
***********************************************
* CMU ARPA Speech Project
*
* Copyright (c) 1996 Carnegie Mellon University.
* ALL RIGHTS RESERVED.
***********************************************
*
* HISTORY
* $Log$
* Revision 1.7 2006/02/22 17:09:55 arthchan2003
* Merged from SPHINX3_5_2_RCI_IRII_BRANCH: 1, Followed Dave's change, keep active to be uint8 instead int8 in gauden_dist_norm.\n 2, Introdued gauden_dump and gauden_dump_ind. This allows debugging of ms_gauden routine. \n 3, Introduced gauden_free, this fixed some minor memory leaks. \n 4, gauden_init accept an argument precompute to specify whether the distance is pre-computed or not.\n 5, Added license. \n 6, Fixed dox-doc.
*
*
* Revision 1.5.4.7 2006/01/16 19:45:59 arthchan2003
* Change the gaussian density dumping routine to a function.
*
* Revision 1.5.4.6 2005/10/09 19:51:05 arthchan2003
* Followed Dave's changed in the trunk.
*
* Revision 1.5.4.5 2005/09/25 18:54:20 arthchan2003
* Added a flag to turn on and off precomputation.
*
* Revision 1.6 2005/10/05 00:31:14 dhdfu
* Make int8 be explicitly signed (signedness of 'char' is
* architecture-dependent). Then make a bunch of things use uint8 where
* signedness is unimportant, because on the architecture where 'char' is
* unsigned, it is that way for a reason (signed chars are slower).
*
* Revision 1.5.4.4 2005/09/07 23:29:07 arthchan2003
* Added FIXME warning.
*
* Revision 1.5.4.3 2005/09/07 23:25:10 arthchan2003
* 1, Behavior changes of cont_mgau, instead of remove Gaussian with zero variance vector before flooring, now remove Gaussian with zero mean and variance before flooring. Notice that this is not yet synchronize with ms_mgau. 2, Added warning message in multi-stream gaussian distribution.
*
* Revision 1.5.4.2 2005/08/03 18:53:44 dhdfu
* Add memory deallocation functions. Also move all the initialization
* of ms_mgau_model_t into ms_mgau_init (duh!), which entails removing it
* from decode_anytopo and friends.
*
* Revision 1.5.4.1 2005/07/20 19:39:01 arthchan2003
* Added licences in ms_* series of code.
*
* Revision 1.5 2005/06/21 18:55:09 arthchan2003
* 1, Add comments to describe this modules, 2, Fixed doxygen documentation. 3, Added $ keyword.
*
* Revision 1.3 2005/03/30 01:22:47 archan
* Fixed mistakes in last updates. Add
*
*
* 20-Dec-96 M K Ravishankar (rkm@cs.cmu.edu) at Carnegie Mellon University.
* Changed gauden_param_read to use the new libio/bio_fread functions.
*
* 26-Sep-96 M K Ravishankar (rkm@cs.cmu.edu) at Carnegie Mellon University.
* Added gauden_mean_reload() for application of MLLR; and correspondingly
* made gauden_param_read allocate memory for parameter only if not
* already allocated.
*
* 09-Sep-96 M K Ravishankar (rkm@cs.cmu.edu) at Carnegie Mellon University.
* Interleaved two density computations for speed improvement.
*
* 19-Aug-96 M K Ravishankar (rkm@cs.cmu.edu) at Carnegie Mellon University.
* Added compute_dist_all special case for improving speed.
*
* 26-Jan-96 M K Ravishankar (rkm@cs.cmu.edu) at Carnegie Mellon University.
* Added check for underflow and floor insertion in gauden_dist.
*
* 20-Jan-96 M K Ravishankar (rkm@cs.cmu.edu) at Carnegie Mellon University.
* Added active argument to gauden_dist_norm and gauden_dist_norm_global,
* and made the latter a static function.
*
* 07-Nov-95 M K Ravishankar (rkm@cs.cmu.edu) at Carnegie Mellon University.
* Initial version created.
* Very liberally borrowed/adapted from Eric's S3 trainer implementation.
*/
/* System headers. */
#include <assert.h>
#include <string.h>
#include <math.h>
#include <float.h>
/* SphinxBase headers. */
#include <sphinxbase/bio.h>
#include <sphinxbase/err.h>
#include <sphinxbase/ckd_alloc.h>
/* Local headesr. */
#include "ms_gauden.h"
#define GAUDEN_PARAM_VERSION "1.0"
#ifndef M_PI
#define M_PI 3.1415926535897932385e0
#endif
#define WORST_DIST (int32)(0x80000000)
void
gauden_dump(const gauden_t * g)
{
int32 c;
for (c = 0; c < g->n_mgau; c++)
gauden_dump_ind(g, c);
}
void
gauden_dump_ind(const gauden_t * g, int senidx)
{
int32 f, d, i;
for (f = 0; f < g->n_feat; f++) {
E_INFO("Codebook %d, Feature %d (%dx%d):\n",
senidx, f, g->n_density, g->featlen[f]);
for (d = 0; d < g->n_density; d++) {
printf("m[%3d]", d);
for (i = 0; i < g->featlen[f]; i++)
printf(" %7.4f", MFCC2FLOAT(g->mean[senidx][f][d][i]));
printf("\n");
}
printf("\n");
for (d = 0; d < g->n_density; d++) {
printf("v[%3d]", d);
for (i = 0; i < g->featlen[f]; i++)
printf(" %d", (int)g->var[senidx][f][d][i]);
printf("\n");
}
printf("\n");
for (d = 0; d < g->n_density; d++)
printf("d[%3d] %d\n", d, (int)g->det[senidx][f][d]);
}
fflush(stderr);
}
static int32
gauden_param_read(float32 ***** out_param, /* Alloc space iff *out_param == NULL */
int32 * out_n_mgau,
int32 * out_n_feat,
int32 * out_n_density,
int32 ** out_veclen, const char *file_name)
{
char tmp;
FILE *fp;
int32 i, j, k, l, n, blk;
int32 n_mgau;
int32 n_feat;
int32 n_density;
int32 *veclen;
int32 byteswap, chksum_present;
float32 ****out;
float32 *buf;
char **argname, **argval;
uint32 chksum;
E_INFO("Reading mixture gaussian parameter: %s\n", file_name);
if ((fp = fopen(file_name, "rb")) == NULL)
E_FATAL_SYSTEM("Failed to open file '%s' for reading", file_name);
/* Read header, including argument-value info and 32-bit byteorder magic */
if (bio_readhdr(fp, &argname, &argval, &byteswap) < 0)
E_FATAL("Failed to read header from file '%s'\n", file_name);
/* Parse argument-value list */
chksum_present = 0;
for (i = 0; argname[i]; i++) {
if (strcmp(argname[i], "version") == 0) {
if (strcmp(argval[i], GAUDEN_PARAM_VERSION) != 0)
E_WARN("Version mismatch(%s): %s, expecting %s\n",
file_name, argval[i], GAUDEN_PARAM_VERSION);
}
else if (strcmp(argname[i], "chksum0") == 0) {
chksum_present = 1; /* Ignore the associated value */
}
}
bio_hdrarg_free(argname, argval);
argname = argval = NULL;
chksum = 0;
/* #Codebooks */
if (bio_fread(&n_mgau, sizeof(int32), 1, fp, byteswap, &chksum) != 1)
E_FATAL("fread(%s) (#codebooks) failed\n", file_name);
*out_n_mgau = n_mgau;
/* #Features/codebook */
if (bio_fread(&n_feat, sizeof(int32), 1, fp, byteswap, &chksum) != 1)
E_FATAL("fread(%s) (#features) failed\n", file_name);
*out_n_feat = n_feat;
/* #Gaussian densities/feature in each codebook */
if (bio_fread(&n_density, sizeof(int32), 1, fp, byteswap, &chksum) != 1)
E_FATAL("fread(%s) (#density/codebook) failed\n", file_name);
*out_n_density = n_density;
/* #Dimensions in each feature stream */
veclen = ckd_calloc(n_feat, sizeof(uint32));
*out_veclen = veclen;
if (bio_fread(veclen, sizeof(int32), n_feat, fp, byteswap, &chksum) !=
n_feat)
E_FATAL("fread(%s) (feature-lengths) failed\n", file_name);
/* blk = total vector length of all feature streams */
for (i = 0, blk = 0; i < n_feat; i++)
blk += veclen[i];
/* #Floats to follow; for the ENTIRE SET of CODEBOOKS */
if (bio_fread(&n, sizeof(int32), 1, fp, byteswap, &chksum) != 1)
E_FATAL("fread(%s) (total #floats) failed\n", file_name);
if (n != n_mgau * n_density * blk) {
E_FATAL
("%s: #mfcc_ts(%d) doesn't match dimensions: %d x %d x %d\n",
file_name, n, n_mgau, n_density, blk);
}
/* Allocate memory for mixture gaussian densities if not already allocated */
if (!(*out_param)) {
out = (float32 ****) ckd_calloc_3d(n_mgau, n_feat, n_density,
sizeof(float32 *));
buf = (float32 *) ckd_calloc(n, sizeof(float32));
for (i = 0, l = 0; i < n_mgau; i++) {
for (j = 0; j < n_feat; j++) {
for (k = 0; k < n_density; k++) {
out[i][j][k] = &buf[l];
l += veclen[j];
}
}
}
}
else {
out = (float32 ****) *out_param;
buf = out[0][0][0];
}
/* Read mixture gaussian densities data */
if (bio_fread(buf, sizeof(float32), n, fp, byteswap, &chksum) != n)
E_FATAL("fread(%s) (densitydata) failed\n", file_name);
if (chksum_present)
bio_verify_chksum(fp, byteswap, chksum);
if (fread(&tmp, 1, 1, fp) == 1)
E_FATAL("More data than expected in %s\n", file_name);
fclose(fp);
*out_param = out;
E_INFO("%d codebook, %d feature, size: \n", n_mgau, n_feat);
for (i = 0; i < n_feat; i++)
E_INFO(" %dx%d\n", n_density, veclen[i]);
return 0;
}
static void
gauden_param_free(mfcc_t **** p)
{
ckd_free(p[0][0][0]);
ckd_free_3d(p);
}
/*
* Some of the gaussian density computation can be carried out in advance:
* log(determinant) calculation,
* 1/(2*var) in the exponent,
* NOTE; The density computation is performed in log domain.
*/
static int32
gauden_dist_precompute(gauden_t * g, logmath_t *lmath, float32 varfloor)
{
int32 i, m, f, d, flen;
mfcc_t *meanp;
mfcc_t *varp;
mfcc_t *detp;
int32 floored;
floored = 0;
/* Allocate space for determinants */
g->det = ckd_calloc_3d(g->n_mgau, g->n_feat, g->n_density, sizeof(***g->det));
for (m = 0; m < g->n_mgau; m++) {
for (f = 0; f < g->n_feat; f++) {
flen = g->featlen[f];
/* Determinants for all variance vectors in g->[m][f] */
for (d = 0, detp = g->det[m][f]; d < g->n_density; d++, detp++) {
*detp = 0;
for (i = 0, varp = g->var[m][f][d], meanp = g->mean[m][f][d];
i < flen; i++, varp++, meanp++) {
float32 *fvarp = (float32 *)varp;
#ifdef FIXED_POINT
float32 *fmp = (float32 *)meanp;
*meanp = FLOAT2MFCC(*fmp);
#endif
if (*fvarp < varfloor) {
*fvarp = varfloor;
++floored;
}
*detp += (mfcc_t)logmath_log(lmath,
1.0 / sqrt(*fvarp * 2.0 * M_PI));
/* Precompute this part of the exponential */
*varp = (mfcc_t)logmath_ln_to_log(lmath,
(1.0 / (*fvarp * 2.0)));
}
}
}
}
E_INFO("%d variance values floored\n", floored);
return 0;
}
gauden_t *
gauden_init(char const *meanfile, char const *varfile, float32 varfloor, logmath_t *lmath)
{
int32 i, m, f, d, *flen;
float32 ****fgau;
gauden_t *g;
assert(meanfile != NULL);
assert(varfile != NULL);
assert(varfloor > 0.0);
g = (gauden_t *) ckd_calloc(1, sizeof(gauden_t));
g->lmath = lmath;
/* Read means and (diagonal) variances for all mixture gaussians */
fgau = NULL;
gauden_param_read(&fgau, &g->n_mgau, &g->n_feat, &g->n_density,
&g->featlen, meanfile);
g->mean = (mfcc_t ****)fgau;
fgau = NULL;
gauden_param_read(&fgau, &m, &f, &d, &flen, varfile);
g->var = (mfcc_t ****)fgau;
/* Verify mean and variance parameter dimensions */
if ((m != g->n_mgau) || (f != g->n_feat) || (d != g->n_density))
E_FATAL
("Mixture-gaussians dimensions for means and variances differ\n");
for (i = 0; i < g->n_feat; i++)
if (g->featlen[i] != flen[i])
E_FATAL("Feature lengths for means and variances differ\n");
ckd_free(flen);
/* Floor variances and precompute variance determinants */
gauden_dist_precompute(g, lmath, varfloor);
return g;
}
void
gauden_free(gauden_t * g)
{
if (g == NULL)
return;
if (g->mean)
gauden_param_free(g->mean);
if (g->var)
gauden_param_free(g->var);
if (g->det)
ckd_free_3d(g->det);
if (g->featlen)
ckd_free(g->featlen);
ckd_free(g);
}
/* See compute_dist below */
static int32
compute_dist_all(gauden_dist_t * out_dist, mfcc_t* obs, int32 featlen,
mfcc_t ** mean, mfcc_t ** var, mfcc_t * det,
int32 n_density)
{
int32 i, d;
for (d = 0; d < n_density; ++d) {
mfcc_t *m;
mfcc_t *v;
mfcc_t dval;
m = mean[d];
v = var[d];
dval = det[d];
for (i = 0; i < featlen; i++) {
mfcc_t diff;
#ifdef FIXED_POINT
/* Have to check for underflows here. */
mfcc_t pdval = dval;
diff = obs[i] - m[i];
dval -= MFCCMUL(MFCCMUL(diff, diff), v[i]);
if (dval > pdval) {
dval = WORST_SCORE;
break;
}
#else
diff = obs[i] - m[i];
/* The compiler really likes this to be a single
* expression, for whatever reason. */
dval -= diff * diff * v[i];
#endif
}
out_dist[d].dist = dval;
out_dist[d].id = d;
}
return 0;
}
/*
* Compute the top-N closest gaussians from the chosen set (mgau,feat)
* for the given input observation vector.
*/
static int32
compute_dist(gauden_dist_t * out_dist, int32 n_top,
mfcc_t * obs, int32 featlen,
mfcc_t ** mean, mfcc_t ** var, mfcc_t * det,
int32 n_density)
{
int32 i, j, d;
gauden_dist_t *worst;
/* Special case optimization when n_density <= n_top */
if (n_top >= n_density)
return (compute_dist_all
(out_dist, obs, featlen, mean, var, det, n_density));
for (i = 0; i < n_top; i++)
out_dist[i].dist = WORST_DIST;
worst = &(out_dist[n_top - 1]);
for (d = 0; d < n_density; d++) {
mfcc_t *m;
mfcc_t *v;
mfcc_t dval;
m = mean[d];
v = var[d];
dval = det[d];
for (i = 0; (i < featlen) && (dval >= worst->dist); i++) {
mfcc_t diff;
#ifdef FIXED_POINT
/* Have to check for underflows here. */
mfcc_t pdval = dval;
diff = obs[i] - m[i];
dval -= MFCCMUL(MFCCMUL(diff, diff), v[i]);
if (dval > pdval) {
dval = WORST_SCORE;
break;
}
#else
diff = obs[i] - m[i];
/* The compiler really likes this to be a single
* expression, for whatever reason. */
dval -= diff * diff * v[i];
#endif
}
if ((i < featlen) || (dval < worst->dist)) /* Codeword d worse than worst */
continue;
/* Codeword d at least as good as worst so far; insert in the ordered list */
for (i = 0; (i < n_top) && (dval < out_dist[i].dist); i++);
assert(i < n_top);
for (j = n_top - 1; j > i; --j)
out_dist[j] = out_dist[j - 1];
out_dist[i].dist = dval;
out_dist[i].id = d;
}
return 0;
}
/*
* Compute distances of the input observation from the top N codewords in the given
* codebook (g->{mean,var}[mgau]). The input observation, obs, includes vectors for
* all features in the codebook.
*/
int32
gauden_dist(gauden_t * g,
int mgau, int32 n_top, mfcc_t** obs, gauden_dist_t ** out_dist)
{
int32 f;
assert((n_top > 0) && (n_top <= g->n_density));
for (f = 0; f < g->n_feat; f++) {
compute_dist(out_dist[f], n_top,
obs[f], g->featlen[f],
g->mean[mgau][f], g->var[mgau][f], g->det[mgau][f],
g->n_density);
E_DEBUG(3, ("Top CW(%d,%d) = %d %d\n", mgau, f, out_dist[f][0].id,
(int)out_dist[f][0].dist >> SENSCR_SHIFT));
}
return 0;
}
int32
gauden_mllr_transform(gauden_t *g, ps_mllr_t *mllr, cmd_ln_t *config)
{
int32 i, m, f, d, *flen;
float32 ****fgau;
/* Free data if already here */
if (g->mean)
gauden_param_free(g->mean);
if (g->var)
gauden_param_free(g->var);
if (g->det)
ckd_free_3d(g->det);
if (g->featlen)
ckd_free(g->featlen);
g->mean = NULL;
g->var = NULL;
g->det = NULL;
g->featlen = NULL;
/* Reload means and variances (un-precomputed). */
fgau = NULL;
gauden_param_read(&fgau, &g->n_mgau, &g->n_feat, &g->n_density,
&g->featlen, cmd_ln_str_r(config, "-mean"));
g->mean = (mfcc_t ****)fgau;
fgau = NULL;
gauden_param_read(&fgau, &m, &f, &d, &flen, cmd_ln_str_r(config, "-var"));
g->var = (mfcc_t ****)fgau;
/* Verify mean and variance parameter dimensions */
if ((m != g->n_mgau) || (f != g->n_feat) || (d != g->n_density))
E_FATAL
("Mixture-gaussians dimensions for means and variances differ\n");
for (i = 0; i < g->n_feat; i++)
if (g->featlen[i] != flen[i])
E_FATAL("Feature lengths for means and variances differ\n");
ckd_free(flen);
/* Transform codebook for each stream s */
for (i = 0; i < g->n_mgau; ++i) {
for (f = 0; f < g->n_feat; ++f) {
float64 *temp;
temp = (float64 *) ckd_calloc(g->featlen[f], sizeof(float64));
/* Transform each density d in selected codebook */
for (d = 0; d < g->n_density; d++) {
int l;
for (l = 0; l < g->featlen[f]; l++) {
temp[l] = 0.0;
for (m = 0; m < g->featlen[f]; m++) {
/* FIXME: For now, only one class, hence the zeros below. */
temp[l] += mllr->A[f][0][l][m] * g->mean[i][f][d][m];
}
temp[l] += mllr->b[f][0][l];
}
for (l = 0; l < g->featlen[f]; l++) {
g->mean[i][f][d][l] = (float32) temp[l];
g->var[i][f][d][l] *= mllr->h[f][0][l];
}
}
ckd_free(temp);
}
}
/* Re-precompute (if we aren't adapting variances this isn't
* actually necessary...) */
gauden_dist_precompute(g, g->lmath, cmd_ln_float32_r(config, "-varfloor"));
return 0;
}

View File

@ -0,0 +1,150 @@
/* -*- c-basic-offset: 4; indent-tabs-mode: nil -*- */
/* ====================================================================
* Copyright (c) 1999-2004 Carnegie Mellon University. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. 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 work was supported in part by funding from the Defense Advanced
* Research Projects Agency and the National Science Foundation of the
* United States of America, and the CMU Sphinx Speech Consortium.
*
* THIS SOFTWARE IS PROVIDED BY CARNEGIE MELLON UNIVERSITY ``AS IS'' AND
* ANY EXPRESSED 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 CARNEGIE MELLON UNIVERSITY
* NOR ITS EMPLOYEES 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.
*
* ====================================================================
*
*/
#ifndef _LIBFBS_GAUDEN_H_
#define _LIBFBS_GAUDEN_H_
/** \file ms_gauden.h
* \brief (Sphinx 3.0 specific) Gaussian density module.
*
* Gaussian density distribution implementation. There are two major
* difference bettwen ms_gauden and cont_mgau. One is the fact that
* ms_gauden only take cares of the Gaussian computation part where
* cont_mgau actually take care of senone computation as well. The
* other is the fact that ms_gauden is a multi-stream implementation
* of GMM computation.
*
*/
/* SphinxBase headers. */
#include <sphinxbase/feat.h>
#include <sphinxbase/logmath.h>
#include <sphinxbase/cmd_ln.h>
/* Local headers. */
#include "vector.h"
#include "pocketsphinx_internal.h"
#include "hmm.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* \struct gauden_dist_t
* \brief Structure to store distance (density) values for a given input observation wrt density values in some given codebook.
*/
typedef struct {
int32 id; /**< Index of codeword (gaussian density) */
mfcc_t dist; /**< Density value for input observation wrt above codeword;
NOTE: result in logs3 domain, but var_t used for speed */
} gauden_dist_t;
/**
* \struct gauden_t
* \brief Multivariate gaussian mixture density parameters
*/
typedef struct {
mfcc_t ****mean; /**< mean[codebook][feature][codeword] vector */
mfcc_t ****var; /**< like mean; diagonal covariance vector only */
mfcc_t ***det; /**< log(determinant) for each variance vector;
actually, log(sqrt(2*pi*det)) */
logmath_t *lmath; /**< log math computation */
int32 n_mgau; /**< Number codebooks */
int32 n_feat; /**< Number feature streams in each codebook */
int32 n_density; /**< Number gaussian densities in each codebook-feature stream */
int32 *featlen; /**< feature length for each feature */
} gauden_t;
/**
* Read mixture gaussian codebooks from the given files. Allocate memory space needed
* for them. Apply the specified variance floor value.
* Return value: ptr to the model created; NULL if error.
* (See Sphinx3 model file-format documentation.)
*/
gauden_t *
gauden_init (char const *meanfile,/**< Input: File containing means of mixture gaussians */
char const *varfile,/**< Input: File containing variances of mixture gaussians */
float32 varfloor, /**< Input: Floor value to be applied to variances */
logmath_t *lmath
);
/** Release memory allocated by gauden_init. */
void gauden_free(gauden_t *g); /**< In: The gauden_t to free */
/** Transform Gaussians according to an MLLR matrix (or, eventually, more). */
int32 gauden_mllr_transform(gauden_t *s, ps_mllr_t *mllr, cmd_ln_t *config);
/**
* Compute gaussian density values for the given input observation vector wrt the
* specified mixture gaussian codebook (which may consist of several feature streams).
* Density values are left UNnormalized.
* @return 0 if successful, -1 otherwise.
*/
int32
gauden_dist (gauden_t *g, /**< In: handle to entire ensemble of codebooks */
int mgau, /**< In: codebook for which density values to be evaluated
(g->{mean,var}[mgau]) */
int n_top, /**< In: Number top densities to be evaluated */
mfcc_t **obs, /**< In: Observation vector; obs[f] = for feature f */
gauden_dist_t **out_dist
/**< Out: n_top best codewords and density values,
in worsening order, for each feature stream.
out_dist[f][i] = i-th best density for feature f.
Caller must allocate memory for this output */
);
/**
Dump the definitionn of Gaussian distribution.
*/
void gauden_dump (const gauden_t *g /**< In: Gaussian distribution g*/
);
/**
Dump the definition of Gaussian distribution of a particular index to the standard output stream
*/
void gauden_dump_ind (const gauden_t *g, /**< In: Gaussian distribution g*/
int senidx /**< In: The senone index of the Gaussian */
);
#ifdef __cplusplus
}
#endif
#endif /* GAUDEN_H */

View File

@ -0,0 +1,279 @@
/* -*- c-basic-offset: 4; indent-tabs-mode: nil -*- */
/* ====================================================================
* Copyright (c) 1999-2004 Carnegie Mellon University. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. 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 work was supported in part by funding from the Defense Advanced
* Research Projects Agency and the National Science Foundation of the
* United States of America, and the CMU Sphinx Speech Consortium.
*
* THIS SOFTWARE IS PROVIDED BY CARNEGIE MELLON UNIVERSITY ``AS IS'' AND
* ANY EXPRESSED 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 CARNEGIE MELLON UNIVERSITY
* NOR ITS EMPLOYEES 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.
*
* ====================================================================
*
*/
/*
* ms_mgau.c -- Essentially a wrapper that wrap up gauden and
* senone. It supports multi-stream.
*
*
* **********************************************
* CMU ARPA Speech Project
*
* Copyright (c) 1997 Carnegie Mellon University.
* ALL RIGHTS RESERVED.
* **********************************************
* HISTORY
* $Log$
* Revision 1.2 2006/02/22 16:56:01 arthchan2003
* Merged from SPHINX3_5_2_RCI_IRII_BRANCH: Added ms_mgau.[ch] into the trunk. It is a wrapper of ms_gauden and ms_senone
*
* Revision 1.1.2.4 2005/09/25 18:55:19 arthchan2003
* Added a flag to turn on and off precomputation.
*
* Revision 1.1.2.3 2005/08/03 18:53:44 dhdfu
* Add memory deallocation functions. Also move all the initialization
* of ms_mgau_model_t into ms_mgau_init (duh!), which entails removing it
* from decode_anytopo and friends.
*
* Revision 1.1.2.2 2005/08/02 21:05:38 arthchan2003
* 1, Added dist and mgau_active as intermediate variable for computation. 2, Added ms_cont_mgau_frame_eval, which is a multi stream version of GMM computation mainly s3.0 family of tools. 3, Fixed dox-doc.
*
* Revision 1.1.2.1 2005/07/20 19:37:09 arthchan2003
* Added a multi-stream cont_mgau (ms_mgau) which is a wrapper of both gauden and senone. Add ms_mgau_init and model_set_mllr. This allow eliminating 600 lines of code in decode_anytopo/align/allphone.
*
*
*
*/
/* Local headers. */
#include "ms_mgau.h"
static ps_mgaufuncs_t ms_mgau_funcs = {
"ms",
ms_cont_mgau_frame_eval, /* frame_eval */
ms_mgau_mllr_transform, /* transform */
ms_mgau_free /* free */
};
ps_mgau_t *
ms_mgau_init(acmod_t *acmod, logmath_t *lmath, bin_mdef_t *mdef)
{
/* Codebooks */
ms_mgau_model_t *msg;
ps_mgau_t *mg;
gauden_t *g;
senone_t *s;
cmd_ln_t *config;
int i;
config = acmod->config;
msg = (ms_mgau_model_t *) ckd_calloc(1, sizeof(ms_mgau_model_t));
msg->config = config;
msg->g = NULL;
msg->s = NULL;
g = msg->g = gauden_init(cmd_ln_str_r(config, "-mean"),
cmd_ln_str_r(config, "-var"),
cmd_ln_float32_r(config, "-varfloor"),
lmath);
/* Verify n_feat and veclen, against acmod. */
if (g->n_feat != feat_dimension1(acmod->fcb)) {
E_ERROR("Number of streams does not match: %d != %d\n",
g->n_feat, feat_dimension1(acmod->fcb));
goto error_out;
}
for (i = 0; i < g->n_feat; ++i) {
if (g->featlen[i] != feat_dimension2(acmod->fcb, i)) {
E_ERROR("Dimension of stream %d does not match: %d != %d\n", i,
g->featlen[i], feat_dimension2(acmod->fcb, i));
goto error_out;
}
}
s = msg->s = senone_init(msg->g,
cmd_ln_str_r(config, "-mixw"),
cmd_ln_str_r(config, "-senmgau"),
cmd_ln_float32_r(config, "-mixwfloor"),
lmath, mdef);
s->aw = cmd_ln_int32_r(config, "-aw");
/* Verify senone parameters against gauden parameters */
if (s->n_feat != g->n_feat)
E_FATAL("#Feature mismatch: gauden= %d, senone= %d\n", g->n_feat,
s->n_feat);
if (s->n_cw != g->n_density)
E_FATAL("#Densities mismatch: gauden= %d, senone= %d\n",
g->n_density, s->n_cw);
if (s->n_gauden > g->n_mgau)
E_FATAL("Senones need more codebooks (%d) than present (%d)\n",
s->n_gauden, g->n_mgau);
if (s->n_gauden < g->n_mgau)
E_ERROR("Senones use fewer codebooks (%d) than present (%d)\n",
s->n_gauden, g->n_mgau);
msg->topn = cmd_ln_int32_r(config, "-topn");
E_INFO("The value of topn: %d\n", msg->topn);
if (msg->topn == 0 || msg->topn > msg->g->n_density) {
E_WARN
("-topn argument (%d) invalid or > #density codewords (%d); set to latter\n",
msg->topn, msg->g->n_density);
msg->topn = msg->g->n_density;
}
msg->dist = (gauden_dist_t ***)
ckd_calloc_3d(g->n_mgau, g->n_feat, msg->topn,
sizeof(gauden_dist_t));
msg->mgau_active = ckd_calloc(g->n_mgau, sizeof(int8));
mg = (ps_mgau_t *)msg;
mg->vt = &ms_mgau_funcs;
return mg;
error_out:
ms_mgau_free(ps_mgau_base(msg));
return NULL;
}
void
ms_mgau_free(ps_mgau_t * mg)
{
ms_mgau_model_t *msg = (ms_mgau_model_t *)mg;
if (msg == NULL)
return;
if (msg->g)
gauden_free(msg->g);
if (msg->s)
senone_free(msg->s);
if (msg->dist)
ckd_free_3d((void *) msg->dist);
if (msg->mgau_active)
ckd_free(msg->mgau_active);
ckd_free(msg);
}
int
ms_mgau_mllr_transform(ps_mgau_t *s,
ps_mllr_t *mllr)
{
ms_mgau_model_t *msg = (ms_mgau_model_t *)s;
return gauden_mllr_transform(msg->g, mllr, msg->config);
}
int32
ms_cont_mgau_frame_eval(ps_mgau_t * mg,
int16 *senscr,
uint8 *senone_active,
int32 n_senone_active,
mfcc_t ** feat,
int32 frame,
int32 compallsen)
{
ms_mgau_model_t *msg = (ms_mgau_model_t *)mg;
int32 gid;
int32 topn;
int32 best;
gauden_t *g;
senone_t *sen;
topn = ms_mgau_topn(msg);
g = ms_mgau_gauden(msg);
sen = ms_mgau_senone(msg);
if (compallsen) {
int32 s;
for (gid = 0; gid < g->n_mgau; gid++)
gauden_dist(g, gid, topn, feat, msg->dist[gid]);
best = (int32) 0x7fffffff;
for (s = 0; s < sen->n_sen; s++) {
senscr[s] = senone_eval(sen, s, msg->dist[sen->mgau[s]], topn);
if (best > senscr[s]) {
best = senscr[s];
}
}
/* Normalize senone scores */
for (s = 0; s < sen->n_sen; s++) {
int32 bs = senscr[s] - best;
if (bs > 32767)
bs = 32767;
if (bs < -32768)
bs = -32768;
senscr[s] = bs;
}
}
else {
int32 i, n;
/* Flag all active mixture-gaussian codebooks */
for (gid = 0; gid < g->n_mgau; gid++)
msg->mgau_active[gid] = 0;
n = 0;
for (i = 0; i < n_senone_active; i++) {
/* senone_active consists of deltas. */
int32 s = senone_active[i] + n;
msg->mgau_active[sen->mgau[s]] = 1;
n = s;
}
/* Compute topn gaussian density values (for active codebooks) */
for (gid = 0; gid < g->n_mgau; gid++) {
if (msg->mgau_active[gid])
gauden_dist(g, gid, topn, feat, msg->dist[gid]);
}
best = (int32) 0x7fffffff;
n = 0;
for (i = 0; i < n_senone_active; i++) {
int32 s = senone_active[i] + n;
senscr[s] = senone_eval(sen, s, msg->dist[sen->mgau[s]], topn);
if (best > senscr[s]) {
best = senscr[s];
}
n = s;
}
/* Normalize senone scores */
n = 0;
for (i = 0; i < n_senone_active; i++) {
int32 s = senone_active[i] + n;
int32 bs = senscr[s] - best;
if (bs > 32767)
bs = 32767;
if (bs < -32768)
bs = -32768;
senscr[s] = bs;
n = s;
}
}
return 0;
}

View File

@ -0,0 +1,143 @@
/* -*- c-basic-offset: 4; indent-tabs-mode: nil -*- */
/* ====================================================================
* Copyright (c) 1999-2004 Carnegie Mellon University. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. 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 work was supported in part by funding from the Defense Advanced
* Research Projects Agency and the National Science Foundation of the
* United States of America, and the CMU Sphinx Speech Consortium.
*
* THIS SOFTWARE IS PROVIDED BY CARNEGIE MELLON UNIVERSITY ``AS IS'' AND
* ANY EXPRESSED 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 CARNEGIE MELLON UNIVERSITY
* NOR ITS EMPLOYEES 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.
*
* ====================================================================
*
*/
/*
* ms_mgau.h -- Essentially a wrapper that wrap up gauden and
* senone. It supports multi-stream.
*
*
* **********************************************
* CMU ARPA Speech Project
*
* Copyright (c) 1997 Carnegie Mellon University.
* ALL RIGHTS RESERVED.
* **********************************************
* HISTORY
* $Log$
* Revision 1.1 2006/04/05 20:27:30 dhdfu
* A Great Reorganzation of header files and executables
*
* Revision 1.3 2006/02/22 16:57:15 arthchan2003
* Fixed minor dox-doc issue
*
* Revision 1.2 2006/02/22 16:56:01 arthchan2003
* Merged from SPHINX3_5_2_RCI_IRII_BRANCH: Added ms_mgau.[ch] into the trunk. It is a wrapper of ms_gauden and ms_senone
*
* Revision 1.1.2.4 2005/09/25 18:55:19 arthchan2003
* Added a flag to turn on and off precomputation.
*
* Revision 1.1.2.3 2005/08/03 18:53:44 dhdfu
* Add memory deallocation functions. Also move all the initialization
* of ms_mgau_model_t into ms_mgau_init (duh!), which entails removing it
* from decode_anytopo and friends.
*
* Revision 1.1.2.2 2005/08/02 21:05:38 arthchan2003
* 1, Added dist and mgau_active as intermediate variable for computation. 2, Added ms_cont_mgau_frame_eval, which is a multi stream version of GMM computation mainly s3.0 family of tools. 3, Fixed dox-doc.
*
* Revision 1.1.2.1 2005/07/20 19:37:09 arthchan2003
* Added a multi-stream cont_mgau (ms_mgau) which is a wrapper of both gauden and senone. Add ms_mgau_init and model_set_mllr. This allow eliminating 600 lines of code in decode_anytopo/align/allphone.
*
*
*
*/
/** \file ms_mgau.h
*
* \brief (Sphinx 3.0 specific) A module that wraps up the code of
* gauden and senone because they are closely related.
*
* At the time at Sphinx 3.1 to 3.2, Ravi has decided to rewrite only
* single-stream part of the code into cont_mgau.[ch]. This marks the
* beginning of historical problem of having two sets of Gaussian
* distribution computation routine, one for single-stream and one of
* multi-stream.
*
* In Sphinx 3.5, when we figure out that it is possible to allow both
* 3.0 family of tools and 3.x family of tools to coexist. This
* becomes one problem we found that very hard to reconcile. That is
* why we currently allow two versions of the code in the code
* base. This is likely to change in the future.
*/
#ifndef _LIBFBS_MS_CONT_MGAU_H_
#define _LIBFBS_MS_CONT_MGAU_H_
/* SphinxBase headers. */
#include <sphinxbase/cmd_ln.h>
#include <sphinxbase/logmath.h>
#include <sphinxbase/feat.h>
/* Local headers. */
#include "acmod.h"
#include "bin_mdef.h"
#include "ms_gauden.h"
#include "ms_senone.h"
/** \struct ms_mgau_t
\brief Multi-stream mixture gaussian. It is not necessary to be continr
*/
typedef struct {
ps_mgau_t base;
gauden_t* g; /**< The codebook */
senone_t* s; /**< The senone */
int topn; /**< Top-n gaussian will be computed */
/**< Intermediate used in computation */
gauden_dist_t ***dist;
uint8 *mgau_active;
cmd_ln_t *config;
} ms_mgau_model_t;
#define ms_mgau_gauden(msg) (msg->g)
#define ms_mgau_senone(msg) (msg->s)
#define ms_mgau_topn(msg) (msg->topn)
ps_mgau_t* ms_mgau_init(acmod_t *acmod, logmath_t *lmath, bin_mdef_t *mdef);
void ms_mgau_free(ps_mgau_t *g);
int32 ms_cont_mgau_frame_eval(ps_mgau_t * msg,
int16 *senscr,
uint8 *senone_active,
int32 n_senone_active,
mfcc_t ** feat,
int32 frame,
int32 compallsen);
int32 ms_mgau_mllr_transform(ps_mgau_t *s,
ps_mllr_t *mllr);
#endif /* _LIBFBS_MS_CONT_MGAU_H_*/

View File

@ -0,0 +1,415 @@
/* -*- c-basic-offset: 4; indent-tabs-mode: nil -*- */
/* ====================================================================
* Copyright (c) 1999-2004 Carnegie Mellon University. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. 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 work was supported in part by funding from the Defense Advanced
* Research Projects Agency and the National Science Foundation of the
* United States of America, and the CMU Sphinx Speech Consortium.
*
* THIS SOFTWARE IS PROVIDED BY CARNEGIE MELLON UNIVERSITY ``AS IS'' AND
* ANY EXPRESSED 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 CARNEGIE MELLON UNIVERSITY
* NOR ITS EMPLOYEES 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.
*
* ====================================================================
*
*/
/* System headers. */
#include <string.h>
#include <stdio.h>
#include <assert.h>
/* SphinxBase headers. */
#include <sphinxbase/bio.h>
/* Local headers. */
#include "ms_senone.h"
#define MIXW_PARAM_VERSION "1.0"
#define SPDEF_PARAM_VERSION "1.2"
static int32
senone_mgau_map_read(senone_t * s, char const *file_name)
{
FILE *fp;
int32 byteswap, chksum_present, n_gauden_present;
uint32 chksum;
int32 i;
char eofchk;
char **argname, **argval;
void *ptr;
float32 v;
E_INFO("Reading senone gauden-codebook map file: %s\n", file_name);
if ((fp = fopen(file_name, "rb")) == NULL)
E_FATAL_SYSTEM("Failed to open map file '%s' for reading", file_name);
/* Read header, including argument-value info and 32-bit byteorder magic */
if (bio_readhdr(fp, &argname, &argval, &byteswap) < 0)
E_FATAL("Failed to read header from file '%s'\n", file_name);
/* Parse argument-value list */
chksum_present = 0;
n_gauden_present = 0;
for (i = 0; argname[i]; i++) {
if (strcmp(argname[i], "version") == 0) {
if (strcmp(argval[i], SPDEF_PARAM_VERSION) != 0) {
E_WARN("Version mismatch(%s): %s, expecting %s\n",
file_name, argval[i], SPDEF_PARAM_VERSION);
}
/* HACK!! Convert version# to float32 and take appropriate action */
if (sscanf(argval[i], "%f", &v) != 1)
E_FATAL("%s: Bad version no. string: %s\n", file_name,
argval[i]);
n_gauden_present = (v > 1.1) ? 1 : 0;
}
else if (strcmp(argname[i], "chksum0") == 0) {
chksum_present = 1; /* Ignore the associated value */
}
}
bio_hdrarg_free(argname, argval);
argname = argval = NULL;
chksum = 0;
/* Read #gauden (if version matches) */
if (n_gauden_present) {
E_INFO("Reading number of codebooks from %s\n", file_name);
if (bio_fread
(&(s->n_gauden), sizeof(int32), 1, fp, byteswap, &chksum) != 1)
E_FATAL("fread(%s) (#gauden) failed\n", file_name);
}
/* Read 1d array data */
if (bio_fread_1d(&ptr, sizeof(uint32), &(s->n_sen), fp,
byteswap, &chksum) < 0) {
E_FATAL("bio_fread_1d(%s) failed\n", file_name);
}
s->mgau = ptr;
E_INFO("Mapping %d senones to %d codebooks\n", s->n_sen, s->n_gauden);
/* Infer n_gauden if not present in this version */
if (!n_gauden_present) {
s->n_gauden = 1;
for (i = 0; i < s->n_sen; i++)
if (s->mgau[i] >= s->n_gauden)
s->n_gauden = s->mgau[i] + 1;
}
if (chksum_present)
bio_verify_chksum(fp, byteswap, chksum);
if (fread(&eofchk, 1, 1, fp) == 1)
E_FATAL("More data than expected in %s: %d\n", file_name, eofchk);
fclose(fp);
E_INFO("Read %d->%d senone-codebook mappings\n", s->n_sen,
s->n_gauden);
return 1;
}
static int32
senone_mixw_read(senone_t * s, char const *file_name, logmath_t *lmath)
{
char eofchk;
FILE *fp;
int32 byteswap, chksum_present;
uint32 chksum;
float32 *pdf;
int32 i, f, c, p, n_err;
char **argname, **argval;
E_INFO("Reading senone mixture weights: %s\n", file_name);
if ((fp = fopen(file_name, "rb")) == NULL)
E_FATAL_SYSTEM("Failed to open mixture weights file '%s' for reading", file_name);
/* Read header, including argument-value info and 32-bit byteorder magic */
if (bio_readhdr(fp, &argname, &argval, &byteswap) < 0)
E_FATAL("Failed to read header from file '%s'\n", file_name);
/* Parse argument-value list */
chksum_present = 0;
for (i = 0; argname[i]; i++) {
if (strcmp(argname[i], "version") == 0) {
if (strcmp(argval[i], MIXW_PARAM_VERSION) != 0)
E_WARN("Version mismatch(%s): %s, expecting %s\n",
file_name, argval[i], MIXW_PARAM_VERSION);
}
else if (strcmp(argname[i], "chksum0") == 0) {
chksum_present = 1; /* Ignore the associated value */
}
}
bio_hdrarg_free(argname, argval);
argname = argval = NULL;
chksum = 0;
/* Read #senones, #features, #codewords, arraysize */
if ((bio_fread(&(s->n_sen), sizeof(int32), 1, fp, byteswap, &chksum) !=
1)
||
(bio_fread(&(s->n_feat), sizeof(int32), 1, fp, byteswap, &chksum)
!= 1)
|| (bio_fread(&(s->n_cw), sizeof(int32), 1, fp, byteswap, &chksum)
!= 1)
|| (bio_fread(&i, sizeof(int32), 1, fp, byteswap, &chksum) != 1)) {
E_FATAL("bio_fread(%s) (arraysize) failed\n", file_name);
}
if (i != s->n_sen * s->n_feat * s->n_cw) {
E_FATAL
("%s: #float32s(%d) doesn't match dimensions: %d x %d x %d\n",
file_name, i, s->n_sen, s->n_feat, s->n_cw);
}
/*
* Compute #LSB bits to be dropped to represent mixwfloor with 8 bits.
* All PDF values will be truncated (in the LSB positions) by these many bits.
*/
if ((s->mixwfloor <= 0.0) || (s->mixwfloor >= 1.0))
E_FATAL("mixwfloor (%e) not in range (0, 1)\n", s->mixwfloor);
/* Use a fixed shift for compatibility with everything else. */
E_INFO("Truncating senone logs3(pdf) values by %d bits\n", SENSCR_SHIFT);
/*
* Allocate memory for senone PDF data. Organize normally or transposed depending on
* s->n_gauden.
*/
if (s->n_gauden > 1) {
E_INFO("Not transposing mixture weights in memory\n");
s->pdf =
(senprob_t ***) ckd_calloc_3d(s->n_sen, s->n_feat, s->n_cw,
sizeof(senprob_t));
}
else {
E_INFO("Transposing mixture weights in memory\n");
s->pdf =
(senprob_t ***) ckd_calloc_3d(s->n_feat, s->n_cw, s->n_sen,
sizeof(senprob_t));
}
/* Temporary structure to read in floats */
pdf = (float32 *) ckd_calloc(s->n_cw, sizeof(float32));
/* Read senone probs data, normalize, floor, convert to logs3, truncate to 8 bits */
n_err = 0;
for (i = 0; i < s->n_sen; i++) {
for (f = 0; f < s->n_feat; f++) {
if (bio_fread
((void *) pdf, sizeof(float32), s->n_cw, fp, byteswap,
&chksum)
!= s->n_cw) {
E_FATAL("bio_fread(%s) (arraydata) failed\n", file_name);
}
/* Normalize and floor */
if (vector_sum_norm(pdf, s->n_cw) <= 0.0)
n_err++;
vector_floor(pdf, s->n_cw, s->mixwfloor);
vector_sum_norm(pdf, s->n_cw);
/* Convert to logs3, truncate to 8 bits, and store in s->pdf */
for (c = 0; c < s->n_cw; c++) {
p = -(logmath_log(lmath, pdf[c]));
p += (1 << (SENSCR_SHIFT - 1)) - 1; /* Rounding before truncation */
if (s->n_gauden > 1)
s->pdf[i][f][c] =
(p < (255 << SENSCR_SHIFT)) ? (p >> SENSCR_SHIFT) : 255;
else
s->pdf[f][c][i] =
(p < (255 << SENSCR_SHIFT)) ? (p >> SENSCR_SHIFT) : 255;
}
}
}
if (n_err > 0)
E_WARN("Weight normalization failed for %d mixture weights components\n", n_err);
ckd_free(pdf);
if (chksum_present)
bio_verify_chksum(fp, byteswap, chksum);
if (fread(&eofchk, 1, 1, fp) == 1)
E_FATAL("More data than expected in %s\n", file_name);
fclose(fp);
E_INFO
("Read mixture weights for %d senones: %d features x %d codewords\n",
s->n_sen, s->n_feat, s->n_cw);
return 1;
}
senone_t *
senone_init(gauden_t *g, char const *mixwfile, char const *sen2mgau_map_file,
float32 mixwfloor, logmath_t *lmath, bin_mdef_t *mdef)
{
senone_t *s;
int32 n = 0, i;
s = (senone_t *) ckd_calloc(1, sizeof(senone_t));
s->lmath = logmath_init(logmath_get_base(lmath), SENSCR_SHIFT, TRUE);
s->mixwfloor = mixwfloor;
s->n_gauden = g->n_mgau;
if (sen2mgau_map_file) {
if (!(strcmp(sen2mgau_map_file, ".semi.") == 0
|| strcmp(sen2mgau_map_file, ".ptm.") == 0
|| strcmp(sen2mgau_map_file, ".cont.") == 0)) {
senone_mgau_map_read(s, sen2mgau_map_file);
n = s->n_sen;
}
}
else {
if (s->n_gauden == 1)
sen2mgau_map_file = ".semi.";
else if (s->n_gauden == bin_mdef_n_ciphone(mdef))
sen2mgau_map_file = ".ptm.";
else
sen2mgau_map_file = ".cont.";
}
senone_mixw_read(s, mixwfile, lmath);
if (strcmp(sen2mgau_map_file, ".semi.") == 0) {
/* All-to-1 senones-codebook mapping */
E_INFO("Mapping all senones to one codebook\n");
s->mgau = (uint32 *) ckd_calloc(s->n_sen, sizeof(*s->mgau));
}
else if (strcmp(sen2mgau_map_file, ".ptm.") == 0) {
/* All-to-ciphone-id senones-codebook mapping */
E_INFO("Mapping senones to context-independent phone codebooks\n");
s->mgau = (uint32 *) ckd_calloc(s->n_sen, sizeof(*s->mgau));
for (i = 0; i < s->n_sen; i++)
s->mgau[i] = bin_mdef_sen2cimap(mdef, i);
}
else if (strcmp(sen2mgau_map_file, ".cont.") == 0
|| strcmp(sen2mgau_map_file, ".s3cont.") == 0) {
/* 1-to-1 senone-codebook mapping */
E_INFO("Mapping senones to individual codebooks\n");
if (s->n_sen <= 1)
E_FATAL("#senone=%d; must be >1\n", s->n_sen);
s->mgau = (uint32 *) ckd_calloc(s->n_sen, sizeof(*s->mgau));
for (i = 0; i < s->n_sen; i++)
s->mgau[i] = i;
/* Not sure why this is here, it probably does nothing. */
s->n_gauden = s->n_sen;
}
else {
if (s->n_sen != n)
E_FATAL("#senones inconsistent: %d in %s; %d in %s\n",
n, sen2mgau_map_file, s->n_sen, mixwfile);
}
s->featscr = NULL;
return s;
}
void
senone_free(senone_t * s)
{
if (s == NULL)
return;
if (s->pdf)
ckd_free_3d((void *) s->pdf);
if (s->mgau)
ckd_free(s->mgau);
if (s->featscr)
ckd_free(s->featscr);
logmath_free(s->lmath);
ckd_free(s);
}
/*
* Compute senone score for one senone.
* NOTE: Remember that senone PDF tables contain SCALED, NEGATED logs3 values.
* NOTE: Remember also that PDF data may be transposed or not depending on s->n_gauden.
*/
int32
senone_eval(senone_t * s, int id, gauden_dist_t ** dist, int32 n_top)
{
int32 scr; /* total senone score */
int32 fden; /* Gaussian density */
int32 fscr; /* senone score for one feature */
int32 fwscr; /* senone score for one feature, one codeword */
int32 f, t;
gauden_dist_t *fdist;
assert((id >= 0) && (id < s->n_sen));
assert((n_top > 0) && (n_top <= s->n_cw));
scr = 0;
for (f = 0; f < s->n_feat; f++) {
#ifdef SPHINX_DEBUG
int top;
#endif
fdist = dist[f];
/* Top codeword for feature f */
#ifdef SPHINX_DEBUG
top =
#endif
fden = ((int32)fdist[0].dist + ((1<<SENSCR_SHIFT) - 1)) >> SENSCR_SHIFT;
fscr = (s->n_gauden > 1)
? (fden + -s->pdf[id][f][fdist[0].id]) /* untransposed */
: (fden + -s->pdf[f][fdist[0].id][id]); /* transposed */
E_DEBUG(1, ("fden[%d][%d] l+= %d + %d = %d\n",
id, f, -(fscr - fden), -(fden-top), -(fscr-top)));
/* Remaining of n_top codewords for feature f */
for (t = 1; t < n_top; t++) {
fden = ((int32)fdist[t].dist + ((1<<SENSCR_SHIFT) - 1)) >> SENSCR_SHIFT;
fwscr = (s->n_gauden > 1) ?
(fden + -s->pdf[id][f][fdist[t].id]) :
(fden + -s->pdf[f][fdist[t].id][id]);
fscr = logmath_add(s->lmath, fscr, fwscr);
E_DEBUG(1, ("fden[%d][%d] l+= %d + %d = %d\n",
id, f, -(fwscr - fden), -(fden-top), -(fscr-top)));
}
/* Senone scores are also scaled, negated logs3 values. Hence
* we have to negate the stuff we calculated above. */
scr -= fscr;
}
/* Downscale scores. */
scr /= s->aw;
/* Avoid overflowing int16 */
if (scr > 32767)
scr = 32767;
if (scr < -32768)
scr = -32768;
return scr;
}

View File

@ -0,0 +1,199 @@
/* -*- c-basic-offset: 4; indent-tabs-mode: nil -*- */
/* ====================================================================
* Copyright (c) 1999-2004 Carnegie Mellon University. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. 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 work was supported in part by funding from the Defense Advanced
* Research Projects Agency and the National Science Foundation of the
* United States of America, and the CMU Sphinx Speech Consortium.
*
* THIS SOFTWARE IS PROVIDED BY CARNEGIE MELLON UNIVERSITY ``AS IS'' AND
* ANY EXPRESSED 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 CARNEGIE MELLON UNIVERSITY
* NOR ITS EMPLOYEES 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.
*
* ====================================================================
*
*/
/*
* senone.h -- Mixture density weights associated with each tied state.
*
* **********************************************
* CMU ARPA Speech Project
*
* Copyright (c) 1996 Carnegie Mellon University.
* ALL RIGHTS RESERVED.
* **********************************************
*
* HISTORY
*
* $Log$
* Revision 1.1 2006/04/05 20:27:30 dhdfu
* A Great Reorganzation of header files and executables
*
* Revision 1.7 2006/02/22 17:27:39 arthchan2003
* Merged from SPHINX3_5_2_RCI_IRII_BRANCH: 1, NOT doing truncation in the multi-stream GMM computation \n. 2, Added .s3cont. to be the alias of the old multi-stream GMM computation routine \n. 3, Added license \n. 4, Fixed dox-doc. \n
*
* Revision 1.6.4.4 2006/01/16 19:47:05 arthchan2003
* Removed the truncation of senone probability code.
*
* Revision 1.6.4.3 2005/08/03 18:53:43 dhdfu
* Add memory deallocation functions. Also move all the initialization
* of ms_mgau_model_t into ms_mgau_init (duh!), which entails removing it
* from decode_anytopo and friends.
*
* Revision 1.6.4.2 2005/07/20 19:39:01 arthchan2003
* Added licences in ms_* series of code.
*
* Revision 1.6.4.1 2005/07/05 05:47:59 arthchan2003
* Fixed dox-doc. struct level of documentation are included.
*
* Revision 1.6 2005/06/21 19:00:19 arthchan2003
* Add more detail comments to ms_senone.h
*
* Revision 1.5 2005/06/21 18:57:31 arthchan2003
* 1, Fixed doxygen documentation. 2, Added $ keyword.
*
* Revision 1.2 2005/06/13 04:02:56 archan
* Fixed most doxygen-style documentation under libs3decoder.
*
* Revision 1.1.1.1 2005/03/24 15:24:00 archan
* I found Evandro's suggestion is quite right after yelling at him 2 days later. So I decide to check this in again without any binaries. (I have done make distcheck. ) . Again, this is a candidate for s3.6 and I believe I need to work out 4-5 intermediate steps before I can complete the first prototype. That's why I keep local copies.
*
* Revision 1.4 2004/12/06 10:52:01 arthchan2003
* Enable doxygen documentation in libs3decoder
*
* Revision 1.3 2004/11/13 21:25:19 arthchan2003
* commit of 1, absolute CI-GMMS , 2, fast CI senone computation using svq, 3, Decrease the number of static variables, 4, fixing the random generator problem of vector_vqgen, 5, move all unused files to NOTUSED
*
* Revision 1.2 2004/08/31 08:43:47 arthchan2003
* Fixing _cpluscplus directive
*
* Revision 1.1 2004/08/09 00:17:11 arthchan2003
* Incorporating s3.0 align, at this point, there are still some small problems in align but they don't hurt. For example, the score doesn't match with s3.0 and the output will have problem if files are piped to /dev/null/. I think we can go for it.
*
* Revision 1.1 2003/02/14 14:40:34 cbq
* Compiles. Analysis is probably hosed.
*
* Revision 1.1 2000/04/24 09:39:41 lenzo
* s3 import.
*
*
* 13-Dec-95 M K Ravishankar (rkm@cs.cmu.edu) at Carnegie Mellon University.
* Added senone_eval_all().
*
* 12-Nov-95 M K Ravishankar (rkm@cs.cmu.edu) at Carnegie Mellon University.
* Created.
*/
#ifndef _LIBFBS_SENONE_H_
#define _LIBFBS_SENONE_H_
/* SphinxBase headers. */
#include <sphinxbase/err.h>
#include <sphinxbase/ckd_alloc.h>
#include <sphinxbase/cmd_ln.h>
#include <sphinxbase/logmath.h>
/* Local headers. */
#include "ms_gauden.h"
#include "bin_mdef.h"
/** \file ms_senone.h
* \brief (Sphinx 3.0 specific) multiple streams senones. used with ms_gauden.h
* In Sphinx 3.0 family of tools, ms_senone is used to combine the Gaussian scores.
* Its existence is crucial in Sphinx 3.0 because 3.0 supports both SCHMM and CDHMM.
* There are optimization scheme for SCHMM (e.g. compute the top-N Gaussian) that is
* applicable to SCHMM than CDHMM. This is wrapped in senone_eval_all.
*/
#ifdef __cplusplus
extern "C" {
#endif
typedef uint8 senprob_t; /**< Senone logs3-probs, truncated to 8 bits */
/**
* \struct senone_t
* \brief 8-bit senone PDF structure.
*
* 8-bit senone PDF structure. Senone pdf values are normalized, floored, converted to
* logs3 domain, and finally truncated to 8 bits precision to conserve memory space.
*/
typedef struct {
senprob_t ***pdf; /**< gaussian density mixture weights, organized two possible
ways depending on n_gauden:
if (n_gauden > 1): pdf[sen][feat][codeword]. Not an
efficient representation--memory access-wise--but
evaluating the many codebooks will be more costly.
if (n_gauden == 1): pdf[feat][codeword][sen]. Optimized
for the shared-distribution semi-continuous case. */
logmath_t *lmath; /**< log math computation */
uint32 n_sen; /**< Number senones in this set */
uint32 n_feat; /**< Number feature streams */
uint32 n_cw; /**< Number codewords per codebook,stream */
uint32 n_gauden; /**< Number gaussian density codebooks referred to by senones */
float32 mixwfloor; /**< floor applied to each PDF entry */
uint32 *mgau; /**< senone-id -> mgau-id mapping for senones in this set */
int32 *featscr; /**< The feature score for every senone, will be initialized inside senone_eval_all */
int32 aw; /**< Inverse acoustic weight */
} senone_t;
/**
* Load a set of senones (mixing weights and mixture gaussian codebook mappings) from
* the given files. Normalize weights for each codebook, apply the given floor, convert
* PDF values to logs3 domain and quantize to 8-bits.
* @return pointer to senone structure created. Caller MUST NOT change its contents.
*/
senone_t *senone_init (gauden_t *g, /**< In: codebooks */
char const *mixwfile, /**< In: mixing weights file */
char const *mgau_mapfile,/**< In: file specifying mapping from each
senone to mixture gaussian codebook.
If NULL all senones map to codebook 0 */
float32 mixwfloor, /**< In: Floor value for senone weights */
logmath_t *lmath, /**< In: log math computation */
bin_mdef_t *mdef /**< In: model definition */
);
/** Release memory allocated by senone_init. */
void senone_free(senone_t *s); /**< In: The senone_t to free */
/**
* Evaluate the score for the given senone wrt to the given top N gaussian codewords.
* @return senone score (in logs3 domain).
*/
int32 senone_eval (senone_t *s, int id, /**< In: senone for which score desired */
gauden_dist_t **dist, /**< In: top N codewords and densities for
all features, to be combined into
senone score. IE, dist[f][i] = i-th
best <codeword,density> for feaure f */
int n_top /**< In: Length of dist[f], for each f */
);
#ifdef __cplusplus
}
#endif
#endif

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More