/* * Copyright 1999-2004 Carnegie Mellon University. * Portions Copyright 2004 Sun Microsystems, Inc. * Portions Copyright 2004 Mitsubishi Electric Research Laboratories. * All Rights Reserved. Use is subject to license terms. * * See the file "license.terms" for information on usage and * redistribution of this file, and for a DISCLAIMER OF ALL * WARRANTIES. * */ package edu.cmu.sphinx.decoder; import edu.cmu.sphinx.decoder.search.SearchManager; import edu.cmu.sphinx.result.Result; import edu.cmu.sphinx.util.props.*; import java.util.ArrayList; import java.util.List; import java.util.logging.Logger; /** An abstract decoder which implements all functionality which is independent of the used decoding-paradigm (pull/push). */ public abstract class AbstractDecoder implements ResultProducer, Configurable { /** * The property that defines the name of the search manager to use * */ @S4Component(type = SearchManager.class) public final static String PROP_SEARCH_MANAGER = "searchManager"; protected SearchManager searchManager; @S4ComponentList(type = ResultListener.class) public static final String PROP_RESULT_LISTENERS = "resultListeners"; protected final List<ResultListener> resultListeners = new ArrayList<ResultListener>(); /** * If set to true the used search-manager will be automatically allocated * in <code>newProperties()</code>. * */ @S4Boolean(defaultValue = false) public static final String AUTO_ALLOCATE = "autoAllocate"; /** * If set to <code>false</code> the used search-manager all registered * result listeners will be notified only for final results. Per default * non-final results don't trigger notification, because in most * application the utterance final result will be sufficient. */ @S4Boolean(defaultValue = false) public static final String FIRE_NON_FINAL_RESULTS = "fireNonFinalResults"; private boolean fireNonFinalResults; private String name; protected Logger logger; public AbstractDecoder() { } /** * Abstract decoder to implement live and batch recognizers * @param searchManager search manager to use * @param fireNonFinalResults to fire result during decoding * @param autoAllocate automatic allocate all components * @param resultListeners listeners to get noification */ public AbstractDecoder(SearchManager searchManager, boolean fireNonFinalResults, boolean autoAllocate, List<ResultListener> resultListeners) { String name = getClass().getName(); init( name, Logger.getLogger(name), searchManager, fireNonFinalResults, autoAllocate, resultListeners); } /** * Decode frames until recognition is complete * * @param referenceText the reference text (or null) * @return a result */ public abstract Result decode(String referenceText); public void newProperties(PropertySheet ps) throws PropertyException { init( ps.getInstanceName(), ps.getLogger(), (SearchManager) ps.getComponent(PROP_SEARCH_MANAGER), ps.getBoolean(FIRE_NON_FINAL_RESULTS), ps.getBoolean(AUTO_ALLOCATE), ps.getComponentList(PROP_RESULT_LISTENERS, ResultListener.class)); } private void init(String name, Logger logger, SearchManager searchManager, boolean fireNonFinalResults, boolean autoAllocate, List<ResultListener> listeners) { this.name = name; this.logger = logger; this.searchManager = searchManager; this.fireNonFinalResults = fireNonFinalResults; if (autoAllocate) { searchManager.allocate(); } for (ResultListener listener : listeners) { addResultListener(listener); } } /** Allocate resources necessary for decoding */ public void allocate() { searchManager.allocate(); } /** Deallocate resources */ public void deallocate() { searchManager.deallocate(); } /** * Adds a result listener to this recognizer. A result listener is called whenever a new result is generated by the * recognizer. This method can be called in any state. * * @param resultListener the listener to add */ public void addResultListener(ResultListener resultListener) { resultListeners.add(resultListener); } /** * Removes a previously added result listener. This method can be called in any state. * * @param resultListener the listener to remove */ public void removeResultListener(ResultListener resultListener) { resultListeners.remove(resultListener); } /** * Fires new results as soon as they become available. * * @param result the new result */ protected void fireResultListeners(Result result) { if (fireNonFinalResults || result.isFinal()) { for (ResultListener resultListener : resultListeners) { resultListener.newResult(result); } }else { logger.finer("skipping non-final result " + result); } } @Override public String toString() { return name; } }