package edu.cmu.sphinx.linguist.allphone;
import java.util.ArrayList;
import edu.cmu.sphinx.decoder.scorer.ScoreProvider;
import edu.cmu.sphinx.frontend.Data;
import edu.cmu.sphinx.linguist.SearchState;
import edu.cmu.sphinx.linguist.SearchStateArc;
import edu.cmu.sphinx.linguist.WordSequence;
import edu.cmu.sphinx.linguist.acoustic.HMMState;
import edu.cmu.sphinx.linguist.acoustic.HMMStateArc;
import edu.cmu.sphinx.linguist.acoustic.Unit;
import edu.cmu.sphinx.linguist.acoustic.tiedstate.SenoneHMM;
import edu.cmu.sphinx.linguist.acoustic.tiedstate.SenoneSequence;
public class PhoneHmmSearchState implements SearchState, SearchStateArc, ScoreProvider {
private HMMState state;
private AllphoneLinguist linguist;
private float insertionProb;
private float languageProb;
public PhoneHmmSearchState(HMMState hmmState, AllphoneLinguist linguist, float insertionProb, float languageProb) {
this.state = hmmState;
this.linguist = linguist;
this.insertionProb = insertionProb;
this.languageProb = languageProb;
}
public SearchState getState() {
return this;
}
public int getBaseId() {
return ((SenoneHMM)state.getHMM()).getBaseUnit().getBaseID();
}
public float getProbability() {
return getLanguageProbability() + getInsertionProbability();
}
public float getLanguageProbability() {
return languageProb;
}
public float getInsertionProbability() {
return insertionProb;
}
/* If we are final, transfer to all possible phones, otherwise
* return all successors of this hmm state.
* */
public SearchStateArc[] getSuccessors() {
if (state.isExitState()) {
ArrayList<Unit> units = linguist.getUnits(((SenoneHMM)state.getHMM()).getSenoneSequence());
SearchStateArc[] result = new SearchStateArc[units.size()];
for (int i = 0; i < result.length; i++)
result[i] = new PhoneNonEmittingSearchState(units.get(i), linguist, insertionProb, languageProb);
return result;
} else {
HMMStateArc successors[] = state.getSuccessors();
SearchStateArc[] results = new SearchStateArc[successors.length];
for (int i = 0; i < successors.length; i++) {
results[i] = new PhoneHmmSearchState(successors[i].getHMMState(), linguist, insertionProb, languageProb);
}
return results;
}
}
public boolean isEmitting() {
return state.isEmitting();
}
public boolean isFinal() {
return false;
}
public String toPrettyString() {
return "HMM " + state.toString();
}
public String getSignature() {
return null;
}
public WordSequence getWordHistory() {
return null;
}
public Object getLexState() {
return null;
}
public int getOrder() {
return 2;
}
public float getScore(Data data) {
return state.getScore(data);
}
public float[] getComponentScore(Data feature) {
return state.calculateComponentScore(feature);
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof PhoneHmmSearchState))
return false;
SenoneSequence otherSenoneSeq = ((SenoneHMM)((PhoneHmmSearchState)obj).state.getHMM()).getSenoneSequence();
SenoneSequence thisSenoneSeq = ((SenoneHMM)state.getHMM()).getSenoneSequence();
return thisSenoneSeq.equals(otherSenoneSeq);
}
@Override
public int hashCode() {
return ((SenoneHMM)state.getHMM()).getSenoneSequence().hashCode() + state.getState() * 37;
}
}