summaryrefslogtreecommitdiff
path: root/media/pocketsphinx/src/allphone_search.c
diff options
context:
space:
mode:
Diffstat (limited to 'media/pocketsphinx/src/allphone_search.c')
-rw-r--r--media/pocketsphinx/src/allphone_search.c913
1 files changed, 0 insertions, 913 deletions
diff --git a/media/pocketsphinx/src/allphone_search.c b/media/pocketsphinx/src/allphone_search.c
deleted file mode 100644
index 974cdba4fb..0000000000
--- a/media/pocketsphinx/src/allphone_search.c
+++ /dev/null
@@ -1,913 +0,0 @@
-/* ====================================================================
- * 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 = {
- /* name: */ "allphone",
- /* 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(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, 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_deinit(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;
-}