001/** 002 * Portions Copyright 2001 Sun Microsystems, Inc. 003 * Portions Copyright 1999-2001 Language Technologies Institute, 004 * Carnegie Mellon University. 005 * All Rights Reserved. Use is subject to license terms. 006 * 007 * See the file "license.terms" for information on usage and 008 * redistribution of this file, and for a DISCLAIMER OF ALL 009 * WARRANTIES. 010 */ 011package com.sun.speech.freetts; 012 013import java.io.BufferedReader; 014import java.io.IOException; 015import java.io.InputStreamReader; 016import java.net.URL; 017import java.util.HashMap; 018import java.util.Map; 019import java.util.NoSuchElementException; 020import java.util.StringTokenizer; 021 022/** 023 * Implementation of a <code>PhoneSet</code> that reads the info from 024 * a file. The format of the file is as follows: 025 * 026 * <pre> 027 * phone feature value 028 * phone feature value 029 * phone feature value 030 * ... 031 * </pre> 032 * 033 * Where <code>phone</code> is the phone name, <code>feature</code> is 034 * the phone feature such as "vc," "vlng," "vheight," and so on, and 035 * "value" is the value of the feature. There can be multiple lines 036 * for the same phone to describe various features of that phone. 037 */ 038public class PhoneSetImpl implements PhoneSet { 039 /** 040 * Used for informational purposes if there's a bad line in the 041 * file. 042 */ 043 private int lineCount = 0; 044 045 /** 046 * The set of phone features indexed by phone. 047 */ 048 private Map phonesetMap; 049 050 /** 051 * Create a new <code>PhoneSetImpl</code> by reading from the 052 * given URL. 053 * 054 * @param url the input source 055 * 056 * @throws IOException if an error occurs 057 */ 058 public PhoneSetImpl(URL url) throws IOException { 059 BufferedReader reader; 060 String line; 061 062 phonesetMap = new HashMap(); 063 reader = new BufferedReader(new 064 InputStreamReader(url.openStream())); 065 line = reader.readLine(); 066 lineCount++; 067 while (line != null) { 068 if (!line.startsWith("***")) { 069 parseAndAdd(line); 070 } 071 line = reader.readLine(); 072 } 073 reader.close(); 074 } 075 076 /** 077 * Creates a word from the given input line and add it to the map. 078 * 079 * @param line the input line 080 */ 081 private void parseAndAdd(String line) { 082 StringTokenizer tokenizer = new StringTokenizer(line," "); 083 try { 084 String phoneme = tokenizer.nextToken(); 085 String feature = tokenizer.nextToken(); 086 String value = tokenizer.nextToken(); 087 phonesetMap.put(getKey(phoneme, feature), value); 088 } catch (NoSuchElementException nse) { 089 throw new Error("part of speech data in bad format at line " 090 + lineCount); 091 } 092 } 093 094 /** 095 * Given a phoneme and a feature, returns the key that 096 * will obtain the value. 097 * 098 * @param phoneme the phoneme 099 * @param feature the name of the feature 100 * 101 * @return the key used to obtain the value 102 */ 103 private String getKey(String phoneme, String feature) { 104 return phoneme + feature; 105 } 106 107 /** 108 * Given a phoneme and a feature name, returns the feature. 109 * 110 * @param phone the phoneme of interest 111 * @param featureName the name of the feature of interest 112 * 113 * @return the feature with the given name 114 */ 115 public String getPhoneFeature(String phone, String featureName) { 116 return (String) phonesetMap.get(getKey(phone, featureName)); 117 } 118}