package edu.cmu.sphinx.linguist.acoustic.tiedstate;
import edu.cmu.sphinx.frontend.Data;
/**
* Implements a Senone that contains a cache of the last scored data.
* <p>
* Subclasses should implement the abstract {@link #calculateScore} method,
* which is called by the {@link #getScore} method to calculate the score
* for each cache miss.
* <p>
* Note: this implementation is thread-safe and can be safely used
* across different threads without external synchronization.
*
* @author Yaniv Kunda
*/
@SuppressWarnings("serial")
public abstract class ScoreCachingSenone implements Senone {
private class ScoreCache {
private final Data feature;
private final float score;
public ScoreCache(Data feature, float score) {
this.feature = feature;
this.score = score;
}
}
private volatile ScoreCache scoreCache = new ScoreCache(null, 0.0f);
/**
* Gets the cached score for this senone based upon the given feature.
* If the score was not cached, it is calculated using {@link #calculateScore},
* cached, and then returned.
*/
public float getScore(Data feature) {
ScoreCache cached = scoreCache;
if (feature != cached.feature) {
cached = new ScoreCache(feature, calculateScore(feature));
scoreCache = cached;
}
return cached.score;
}
/**
* Calculates the score for this senone based upon the given feature.
*
* @param feature the feature vector to score this senone against
* @return the score for this senone in LogMath log base
*/
protected abstract float calculateScore(Data feature);
}