📄 clusterunitdatabase.java
字号:
/** * Portions Copyright 2003 Sun Microsystems, Inc. * Portions Copyright 1999-2001 Language Technologies Institute, * Carnegie Mellon University. * 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 com.sun.speech.freetts.clunits;import com.sun.speech.freetts.cart.CART;import com.sun.speech.freetts.cart.CARTImpl;import com.sun.speech.freetts.util.Utilities;import com.sun.speech.freetts.util.BulkTimer;import com.sun.speech.freetts.relp.SampleSet;import com.sun.speech.freetts.relp.Sample;import com.sun.speech.freetts.relp.SampleInfo;import java.io.BufferedInputStream;import java.nio.ByteBuffer;import java.nio.channels.FileChannel;import java.nio.MappedByteBuffer;import java.io.BufferedReader;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.InputStream;import java.io.InputStreamReader;import java.io.DataOutputStream;import java.io.DataInputStream;import java.io.BufferedOutputStream;import java.io.IOException;import java.net.MalformedURLException;import java.net.URL;import java.util.NoSuchElementException;import java.util.StringTokenizer;import java.util.List;import java.util.ArrayList;import java.util.HashMap;import java.util.Map;import java.util.Iterator;/** * Provides support for the cluster unit database. The use of the * cluster unit database is confined to this clunits package. This * class provides a main program that can be used to convert from a * text version of the database to a binary version of the database. * * The ClusterUnitDataBase can be loaded from a text or a binary * source. The binary form of the database loads much faster and * therefore is generally used in a deployed system. * */public class ClusterUnitDatabase { final static int CLUNIT_NONE = 65535; private DatabaseClusterUnit[] units; private UnitType[] unitTypes; private SampleSet sts; private SampleSet mcep; private int continuityWeight; private int optimalCoupling; private int extendSelections; private int joinMethod; private int[] joinWeights; private int joinWeightShift; private Map cartMap = new HashMap(); private CART defaultCart = null; private transient List unitList; private transient int lineCount; private transient List unitTypesList; private final static int MAGIC = 0xf0cacc1a; private final static int VERSION = 0x1000; /** * Creates the UnitDatabase from the given input stream. * * @param is the input stream to read the database from * @param isBinary the input stream is a binary stream * * @throws IOException if there is trouble opening the DB */ ClusterUnitDatabase(URL url, boolean isBinary) throws IOException { BulkTimer.LOAD.start("ClusterUnitDatabase"); InputStream is = Utilities.getInputStream(url); if (isBinary) { loadBinary(is); } else { loadText(is); } is.close(); BulkTimer.LOAD.stop("ClusterUnitDatabase"); } /** * Retrieves the begininning sample index for the * given entry. * * @param unitEntry the entry of interest * * @return the begininning sample index */ int getStart(int unitEntry) { return units[unitEntry].start; } /** * Retrieves the ending sample index for the * given entry. * * @param unitEntry the entry of interest * * @return the ending sample index */ int getEnd(int unitEntry) { return units[unitEntry].end; } /** * Retrieves the phone for the given entry * * @param unitEntry the entry of interest * * @return the phone for the entry */ int getPhone(int unitEntry) { return units[unitEntry].phone; } /** * Returns the cart of the given unit type. * * @param unitType the type of cart * * @return the cart */ CART getTree(String unitType) { CART cart = (CART) cartMap.get(unitType); if (cart == null) { System.err.println("ClusterUnitDatabase: can't find tree for " + unitType); return defaultCart; // "graceful" failrue } return cart; } /** * Retrieves the type index for the name given a name. * * @param name the name * * @return the index for the name */// [[[TODO: perhaps replace this with java.util.Arrays.binarySearch]]] int getUnitTypeIndex(String name) { int start, end, mid, c; start = 0; end = unitTypes.length; while (start < end) { mid = (start + end) / 2; c = unitTypes[mid].getName().compareTo(name); if (c == 0) { return mid; } else if (c > 0) { end = mid; } else { start = mid + 1; } } return -1; } /** * Retrieves the unit index given a unit type and val. * * @param unitType the type of the unit * @param instance the value associated with the unit * * @return the index. */ int getUnitIndex(String unitType, int instance) { int i = getUnitTypeIndex(unitType); if (i == -1) { error("getUnitIndex: can't find unit type " + unitType); i = 0; } if (instance >= unitTypes[i].getCount()) { error("getUnitIndex: can't find instance " + instance + " of " + unitType); instance = 0; } return unitTypes[i].getStart() + instance; } /** * Retrieves the index for the name given a name. * * @param name the name * * @return the index for the name */ int getUnitIndexName(String name) { int lastIndex = name.lastIndexOf('_'); if (lastIndex == -1) { error("getUnitIndexName: bad unit name " + name); return -1; } int index = Integer.parseInt(name.substring(lastIndex + 1)); String type = name.substring(0, lastIndex); return getUnitIndex(type, index); } /** * Retrieves the extend selections setting. * * @return the extend selections setting */ int getExtendSelections() { return extendSelections; } /** * Gets the next unit. * * @return the next unit */ int getNextUnit(int which) { return units[which].next; } /** * Gets the previous units. * * @param which which unit is of interest * * @return the previous unit */ int getPrevUnit(int which) { return units[which].prev; } /** * Determines if the unit types are equal. * * @param unitA the index of unit a * @param unitB the index of unit B * * @return <code>true</code> if the types of units a and b are * equal; otherwise return <code>false</code> */ boolean isUnitTypeEqual(int unitA, int unitB) { return units[unitA].type == units[unitB].type; // String nameA = units[unitA].getName(); // String nameB = units[unitB].getName(); // int lastUnderscore = nameA.lastIndexOf('_'); // return nameA.regionMatches(0, nameB, 0, lastUnderscore + 1); } /** * Retrieves the optimal coupling setting. * * @return the optimal coupling setting */ int getOptimalCoupling() { return optimalCoupling; } /** * Retrieves the continuity weight setting. * * * @return the continuity weight setting */ int getContinuityWeight() { return continuityWeight; } /** * Retrieves the join weights. * * @return the join weights */ int[] getJoinWeights() { return joinWeights; } /** * Looks up the unit with the given name. * * @param unitName the name of the unit to look for * * @return the unit or the defaultUnit if not found. */ DatabaseClusterUnit getUnit(String unitName) { return null; } /** * Looks up the unit with the given index. * * @param index the index of the unit to look for * * @return the unit */ DatabaseClusterUnit getUnit(int which) { return units[which]; } /** * Returns the name of this UnitDatabase. * * @return the name of the database */ String getName() { return "ClusterUnitDatabase"; } /** * Returns the sample info for this set of data. * * @return the sample info */ SampleInfo getSampleInfo() { return sts.getSampleInfo(); } /** * Gets the sample list. * * @return the sample list */ SampleSet getSts() { return sts; } /** * Gets the Mel Ceptra list. * * @return the Mel Ceptra list */ SampleSet getMcep() { return mcep; } /** * Determines if the application of the given join weights could * be applied as a simple right-shift. If so return the shift * otherwise return 0. * * @return the amount to right shift (or zero if not possible) */ int getJoinWeightShift() { return joinWeightShift; } /** * Calculates the join weight shift. * * @param joinWeights the weights to check * * @return the amount to right shift (or zero if not possible) */ private int calcJoinWeightShift(int[] joinWeights) { int first = joinWeights[0]; for (int i = 1; i < joinWeights.length; i++) { if (joinWeights[i] != first) { return 0; } } int divisor = 65536 / first; if (divisor == 2) { return 1; } else if (divisor == 4) { return 2; } return 0; } /** * Loads the database from the given input stream. * * @param is the input stream */ private void loadText(InputStream is) { BufferedReader reader; String line; unitList = new ArrayList(); unitTypesList = new ArrayList(); if (is == null) { throw new Error("Can't load cluster db file."); } reader = new BufferedReader(new InputStreamReader(is)); try { line = reader.readLine(); lineCount++; while (line != null) { if (!line.startsWith("***")) { parseAndAdd(line, reader); } line = reader.readLine(); } reader.close(); units = new DatabaseClusterUnit[unitList.size()]; units = (DatabaseClusterUnit[]) unitList.toArray(units); unitList = null; unitTypes = new UnitType[unitTypesList.size()]; unitTypes = (UnitType[]) unitTypesList.toArray(unitTypes); unitTypesList = null; } catch (IOException e) { throw new Error(e.getMessage() + " at line " + lineCount); } finally { } } /** * Parses and process the given line. * * @param line the line to process * @param reader the source for the lines * * @throws IOException if an error occurs while reading */ private void parseAndAdd(String line, BufferedReader reader) throws IOException { try { StringTokenizer tokenizer = new StringTokenizer(line," "); String tag = tokenizer.nextToken(); if (tag.equals("CONTINUITY_WEIGHT")) { continuityWeight = Integer.parseInt(tokenizer.nextToken()); } else if (tag.equals("OPTIMAL_COUPLING")) { optimalCoupling = Integer.parseInt(tokenizer.nextToken()); } else if (tag.equals("EXTEND_SELECTIONS")) { extendSelections = Integer.parseInt(tokenizer.nextToken()); } else if (tag.equals("JOIN_METHOD")) { joinMethod = Integer.parseInt(tokenizer.nextToken()); } else if (tag.equals("JOIN_WEIGHTS")) { int numWeights = Integer.parseInt(tokenizer.nextToken()); joinWeights = new int[numWeights]; for (int i = 0; i < numWeights; i++) { joinWeights[i] = Integer.parseInt(tokenizer.nextToken()); } joinWeightShift = calcJoinWeightShift(joinWeights); } else if (tag.equals("STS")) { String name = tokenizer.nextToken(); if (name.equals("STS")) { sts = new SampleSet(tokenizer, reader); } else { mcep = new SampleSet(tokenizer, reader); } } else if (tag.equals("UNITS")) { int type = Integer.parseInt(tokenizer.nextToken()); int phone = Integer.parseInt(tokenizer.nextToken()); int start = Integer.parseInt(tokenizer.nextToken()); int end = Integer.parseInt(tokenizer.nextToken()); int prev = Integer.parseInt(tokenizer.nextToken()); int next = Integer.parseInt(tokenizer.nextToken()); DatabaseClusterUnit unit = new DatabaseClusterUnit(type, phone, start, end, prev, next); unitList.add(unit); } else if (tag.equals("CART")) { String name = tokenizer.nextToken(); int nodes = Integer.parseInt(tokenizer.nextToken()); CART cart = new CARTImpl(reader, nodes); cartMap.put(name, cart); if (defaultCart == null) { defaultCart = cart; } } else if (tag.equals("UNIT_TYPE")) { String name = tokenizer.nextToken(); int start = Integer.parseInt(tokenizer.nextToken()); int count = Integer.parseInt(tokenizer.nextToken()); UnitType unitType = new UnitType(name, start, count); unitTypesList.add(unitType); } else { throw new Error("Unsupported tag " + tag + " in db line `" + line + "'"); } } catch (NoSuchElementException nse) { throw new Error("Error parsing db " + nse.getMessage()); } catch (NumberFormatException nfe) { throw new Error("Error parsing numbers in db line `" + line + "':" + nfe.getMessage()); } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -