📄 lettertosoundimpl.java
字号:
int index = Integer.parseInt(tokenizer.nextToken()); String c = tokenizer.nextToken(); int qtrue = Integer.parseInt(tokenizer.nextToken()); int qfalse = Integer.parseInt(tokenizer.nextToken()); return new DecisionState(index, c.charAt(0), qtrue, qfalse); } else if (type.equals(PHONE)) { return new FinalState(tokenizer.nextToken()); } return null; } /** * Makes a character array that looks like "000#word#000". * * @param word the original word * * @return the padded word */ protected char[] getFullBuff(String word) { char[] full_buff = new char[word.length() + (2 * WINDOW_SIZE)]; // Make full_buff look like "000#word#000" // for (int i = 0; i < (WINDOW_SIZE - 1); i++) { full_buff[i] = '0'; } full_buff[WINDOW_SIZE - 1] = '#'; word.getChars(0,word.length(),full_buff,WINDOW_SIZE); for (int i = 0; i < (WINDOW_SIZE - 1); i++) { full_buff[full_buff.length - i - 1] = '0'; } full_buff[full_buff.length - WINDOW_SIZE] = '#'; return full_buff; } /** * Calculates the phone list for a given word. If a phone list cannot * be determined, <code>null</code> is returned. This particular * implementation ignores the part of speech. * * @param word the word to find * @param partOfSpeech the part of speech. * * @return the list of phones for word or <code>null</code> */ public String[] getPhones(String word, String partOfSpeech) { ArrayList phoneList = new ArrayList(); State currentState; Integer startIndex; int stateIndex; char c; // Create "000#word#000" // char[] full_buff = getFullBuff(word); // For each character in the word, create a WINDOW_SIZE // context on each size of the character, and then ask the // state machine what's next. It's magic. BTW, this goes // through the word from beginning to end. Flite goes through // it from end to beginning. There doesn't seem to be a // difference in the result. // for (int pos = 0; pos < word.length(); pos++) { for (int i = 0; i < WINDOW_SIZE; i++) { fval_buff[i] = full_buff[pos + i]; fval_buff[i + WINDOW_SIZE] = full_buff[i + pos + 1 + WINDOW_SIZE]; } c = word.charAt(pos); startIndex = (Integer) letterIndex.get(Character.toString(c)); if (startIndex == null) { continue; } assert (startIndex != null); stateIndex = startIndex.intValue(); currentState = getState(stateIndex); while (!(currentState instanceof FinalState)) { stateIndex = ((DecisionState) currentState).getNextState(fval_buff); currentState = getState(stateIndex); } ((FinalState) currentState).append(phoneList); } return (String[]) phoneList.toArray(new String[0]); } /** * Compares this LTS to another for debugging purposes. * * @param other the other LTS to compare to * * @return <code>true</code> if these are equivalent */ public boolean compare(LetterToSoundImpl other) { // compare letter index table // for (Iterator i = letterIndex.keySet().iterator(); i.hasNext(); ) { String key = (String) i.next(); Integer thisIndex = (Integer) letterIndex.get(key); Integer otherIndex = (Integer) other.letterIndex.get(key); if (!thisIndex.equals(otherIndex)) { System.out.println("Bad Index for " + key); return false; } } // compare states // for (int i = 0; i < stateMachine.length; i++) { State state = getState(i); State otherState = other.getState(i); if (!state.compare(otherState)) { System.out.println("Bad state " + i); return false; } } return true; } /** * A marker interface for the states in the LTS state machine. * * @see DecisionState * @see FinalState */ static interface State { public void writeBinary(DataOutputStream dos) throws IOException; public boolean compare(State other); } /** * A <code>State</code> that represents a decision to be made. * * @see FinalState */ static class DecisionState implements State { final static int TYPE = 1; int index; char c; int qtrue; int qfalse; /** * Class constructor. * * @param index the index into a string for comparison to c * @param c the character to match in a string at index * @param qtrue the state to go to in the state machine on a match * @param qfalse the state to go to in the state machine on no match */ public DecisionState(int index, char c, int qtrue, int qfalse) { this.index = index; this.c = c; this.qtrue = qtrue; this.qfalse = qfalse; } /** * Gets the next state to go to based upon the given character * sequence. * * @param chars the characters for comparison * * @ret an index into the state machine. */ public int getNextState(char[] chars) { return (chars[index] == c) ? qtrue : qfalse; } /** * Outputs this <code>State</code> as though it came from the * text input file. * * @return a <code>String</code> describing this <code>State</code>. */ public String toString() { return STATE + " " + Integer.toString(index) + " " + Character.toString(c) + " " + Integer.toString(qtrue) + " " + Integer.toString(qfalse); } /** * Writes this <code>State</code> to the given output stream. * * @param dos the data output stream * * @throws IOException if an error occurs */ public void writeBinary(DataOutputStream dos) throws IOException { dos.writeInt(TYPE); dos.writeInt(index); dos.writeChar(c); dos.writeInt(qtrue); dos.writeInt(qfalse); } /** * Loads a <code>DecisionState</code> object from the given * input stream. * * @param dis the data input stream * @return a newly constructed decision state * * @throws IOException if an error occurs */ public static State loadBinary(DataInputStream dis) throws IOException { int index = dis.readInt(); char c = dis.readChar(); int qtrue = dis.readInt(); int qfalse = dis.readInt(); return new DecisionState(index, c, qtrue, qfalse); } /** * Compares this state to another state for debugging purposes. * * @param other the other state to compare against * * @return true if the states are equivalent */ public boolean compare(State other) { if (other instanceof DecisionState) { DecisionState otherState = (DecisionState) other; return index == otherState.index && c == otherState.c && qtrue == otherState.qtrue && qfalse == otherState.qfalse; } return false; } } /** * A <code>State</code> that represents a final state in the * state machine. It contains one or more phones from the * phone table. * * @see DecisionState */ static class FinalState implements State { final static int TYPE = 2; String[] phoneList; /** * Class constructor. The string "epsilon" is used to indicate * an empty list. * * @param phones the phones for this state */ public FinalState(String phones) { if (phones.equals("epsilon")) { phoneList = null; } else { int i = phones.indexOf('-'); if (i != -1) { phoneList = new String[2]; phoneList[0] = phones.substring(0, i); phoneList[1] = phones.substring(i + 1); } else { phoneList = new String[1]; phoneList[0] = phones; } } } /** * Class constructor. * * @param phones an array of phones for this state */ public FinalState(String[] phones) { phoneList = phones; } /** * Appends the phone list for this state to the given * <code>ArrayList</code>. * * @param array the array to append to */ public void append(ArrayList array) { if (phoneList == null) { return; } else { for (int i = 0; i < phoneList.length; i++) { array.add(phoneList[i]); } } } /** * Outputs this <code>State</code> as though it came from the * text input file. The string "epsilon" is used to indicate * an empty list. * * @return a <code>String</code> describing this <code>State</code> */ public String toString() { if (phoneList == null) { return PHONE + " epsilon"; } else if (phoneList.length == 1) { return PHONE + " " + phoneList[0]; } else { return PHONE + " " + phoneList[0] + "-" + phoneList[1]; } } /** * Compares this state to another state for debugging * purposes. * * @param other the other state to compare against * * @return <code>true</code> if the states are equivalent */ public boolean compare(State other) { if (other instanceof FinalState) { FinalState otherState = (FinalState) other; if (phoneList == null) { return otherState.phoneList == null; } else { for (int i = 0; i < phoneList.length; i++) { if (!phoneList[i].equals(otherState.phoneList[i])) { return false; } } return true; } } return false; } /** * Writes this state to the given output stream. * * @param dos the data output stream * * @throws IOException if an error occurs */ public void writeBinary(DataOutputStream dos) throws IOException { dos.writeInt(TYPE); if (phoneList == null) { dos.writeInt(0); } else { dos.writeInt(phoneList.length); for (int i = 0; i < phoneList.length; i++) { dos.writeInt(phonemeTable.indexOf(phoneList[i])); } } } /** * Loads a FinalState object from the given input stream * * @param dis the data input stream * * @return a newly constructed final state * * @throws IOException if an error occurs */ public static State loadBinary(DataInputStream dis) throws IOException { String[] phoneList; int phoneListLength = dis.readInt(); if (phoneListLength == 0) { phoneList = null; } else { phoneList = new String[phoneListLength]; } for (int i = 0; i < phoneListLength; i++) { int index = dis.readInt(); phoneList[i] = (String) phonemeTable.get(index); } return new FinalState(phoneList); } } /** * Translates between text and binary forms of the CMU6 LTS rules. */ public static void main(String[] args) { LexiconImpl lex, lex2; boolean showTimes = false; String srcPath = "."; String destPath = "."; String name = "cmulex_lts"; try { if (args.length > 0) { BulkTimer timer = new BulkTimer(); timer.start(); for (int i = 0 ; i < args.length; i++) { if (args[i].equals("-src")) { srcPath = args[++i]; } else if (args[i].equals("-dest")) { destPath = args[++i]; } else if (args[i].equals("-name") && i < args.length -1) { name = args[++i]; } else if (args[i].equals("-generate_binary")) { System.out.println("Loading " + name); timer.start("load_text"); LetterToSoundImpl text = new LetterToSoundImpl( new URL("file:" + srcPath + "/" + name + ".txt"), false); timer.stop("load_text"); System.out.println("Dumping " + name); timer.start("dump_binary"); text.dumpBinary(destPath + "/" + name + ".bin"); timer.stop("dump_binary"); } else if (args[i].equals("-compare")) { timer.start("load_text"); LetterToSoundImpl text = new LetterToSoundImpl( new URL("file:./" + name + ".txt"), false); timer.stop("load_text"); timer.start("load_binary"); LetterToSoundImpl binary = new LetterToSoundImpl( new URL("file:./" + name + ".bin"), true); timer.stop("load_binary"); timer.start("compare"); if (!text.compare(binary)) { System.out.println("NOT EQUIVALENT"); } else { System.out.println("ok"); } timer.stop("compare"); } else if (args[i].equals("-showtimes")) { showTimes = true; } else { System.out.println("Unknown option " + args[i]); } } timer.stop(); if (showTimes) { timer.show("LTS loading and dumping"); } } else { System.out.println("Options: "); System.out.println(" -src path"); System.out.println(" -dest path"); System.out.println(" -compare"); System.out.println(" -generate_binary"); System.out.println(" -showTimes"); } } catch (IOException ioe) { System.err.println(ioe); } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -