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.relp; 012 013import com.sun.speech.freetts.FeatureSet; 014import com.sun.speech.freetts.Item; 015import com.sun.speech.freetts.ProcessException; 016import com.sun.speech.freetts.Relation; 017import com.sun.speech.freetts.Unit; 018import com.sun.speech.freetts.Utterance; 019import com.sun.speech.freetts.UtteranceProcessor; 020import com.sun.speech.freetts.util.Utilities; 021 022/** 023 * Concatenates the Units in the given Utterance to the target_lpc 024 * result. This class is an UtteranceProcessor. It defines a method 025 * <code> processUtterance </code> that helps populate the 026 * target_lpcres relation. 027 * 028 * @see LPCResult 029 */ 030public class UnitConcatenator implements UtteranceProcessor { 031 static private final int ADD_RESIDUAL_PULSE = 1; 032 static private final int ADD_RESIDUAL_WINDOWED = 2; 033 static private final int ADD_RESIDUAL = 3; 034 public final static String PROP_OUTPUT_LPC = 035 "com.sun.speech.freetts.outputLPC"; 036 private boolean outputLPC = Utilities.getBoolean(PROP_OUTPUT_LPC); 037 038 039 /** 040 * Concatenate the Units in the given Utterance to the target_lpc 041 * result. 042 * 043 * @param utterance the Utterance to do concatenation 044 * 045 * @see LPCResult 046 * 047 * @throws ProcessException if an error occurs while processing 048 * the utterance 049 */ 050 public void processUtterance(Utterance utterance) throws ProcessException { 051 float uIndex = 0, m; 052 int pmI = 0, targetResidualPosition = 0, 053 targetStart = 0, targetEnd, residualSize, numberFrames; 054 Relation unitRelation = utterance.getRelation(Relation.UNIT); 055 056 SampleInfo sampleInfo; 057 058 059 int addResidualMethod = ADD_RESIDUAL; 060 061 String residualType = utterance.getString("residual_type"); 062 if (residualType != null) { 063 if (residualType.equals("pulse")) { 064 addResidualMethod = ADD_RESIDUAL_PULSE; 065 } else if (residualType.equals("windowed")) { 066 addResidualMethod = ADD_RESIDUAL_WINDOWED; 067 } 068 } 069 070 sampleInfo = (SampleInfo) utterance.getObject(SampleInfo.UTT_NAME); 071 if (sampleInfo == null) { 072 throw new IllegalStateException 073 ("UnitConcatenator: SampleInfo does not exist"); 074 } 075 076 LPCResult lpcResult = (LPCResult) utterance.getObject("target_lpcres"); 077 lpcResult.setValues(sampleInfo.getNumberOfChannels(), 078 sampleInfo.getSampleRate(), 079 sampleInfo.getResidualFold(), 080 sampleInfo.getCoeffMin(), 081 sampleInfo.getCoeffRange()); 082 083 // create the array of final residual sizes 084 int[] targetTimes = lpcResult.getTimes(); 085 int[] residualSizes = lpcResult.getResidualSizes(); 086 087 int samplesSize = 0; 088 if (lpcResult.getNumberOfFrames() > 0) { 089 samplesSize = targetTimes[lpcResult.getNumberOfFrames() - 1]; 090 } 091 lpcResult.resizeResiduals(samplesSize); 092 093 for (Item unitItem = unitRelation.getHead(); unitItem != null; 094 unitItem = unitItem.getNext()) { 095 FeatureSet featureSet = unitItem.getFeatures(); 096 097 targetEnd = featureSet.getInt("target_end"); 098 Unit unit = (Unit) featureSet.getObject("unit"); 099 int unitSize = unit.getSize(); 100 101 uIndex = 0; 102 m = (float)unitSize/(float)(targetEnd - targetStart); 103 numberFrames = lpcResult.getNumberOfFrames(); 104 105 // for all the pitchmarks that are required 106 for (; (pmI < numberFrames) && 107 (targetTimes[pmI] <= targetEnd); pmI++) { 108 109 Sample sample = unit.getNearestSample(uIndex); 110 111 // Get LPC coefficients by copying 112 lpcResult.setFrame(pmI, sample.getFrameData()); 113 114 // Get residual by copying 115 residualSize = lpcResult.getFrameShift(pmI); 116 117 residualSizes[pmI] = residualSize; 118 byte[] residualData = sample.getResidualData(); 119 120 if (addResidualMethod == ADD_RESIDUAL_PULSE) { 121 lpcResult.copyResidualsPulse 122 (residualData, targetResidualPosition, residualSize); 123 } else { 124 lpcResult.copyResiduals 125 (residualData, targetResidualPosition, residualSize); 126 } 127 128 targetResidualPosition += residualSize; 129 uIndex += ((float) residualSize * m); 130 } 131 targetStart = targetEnd; 132 } 133 lpcResult.setNumberOfFrames(pmI); 134 135 if (outputLPC) { 136 lpcResult.dump(); 137 } 138 } 139 140 /** 141 * Converts this object to a string 142 * @return the string form of this object. 143 */ 144 public String toString() { 145 return "UnitConcatenator"; 146 } 147} 148