2 * Portions Copyright 2001 Sun Microsystems, Inc.
3 * Portions Copyright 1999-2001 Language Technologies Institute,
4 * Carnegie Mellon University.
5 * All Rights Reserved. Use is subject to license terms.
7 * See the file "license.terms" for information on usage and
8 * redistribution of this file, and for a DISCLAIMER OF ALL
11 package com.sun.speech.freetts.relp;
13 import java.io.BufferedReader;
14 import java.io.DataInputStream;
15 import java.io.DataOutputStream;
16 import java.io.IOException;
17 import java.nio.ByteBuffer;
18 import java.util.NoSuchElementException;
19 import java.util.StringTokenizer;
22 * A single short term sample containing Residual Excited Linear Predictive
23 * (RELP) frame and residual voice data.
26 private final short[] frameData;
27 private final byte[] residualData;
28 private final int residualSize;
32 * Constructs a RELP Sample from its component parts
34 * @param frameData the framedata
35 * @param residualData the residual data
37 public Sample(short[] frameData, byte[] residualData) {
38 this.frameData = frameData;
39 this.residualData = residualData;
40 this.residualSize = 0;
44 * Constructs a Sample from its component parts
46 * @param frameData the framedata
47 * @param residualData the residual data
49 public Sample(short[] frameData, byte[] residualData, int residualSize) {
50 this.frameData = frameData;
51 this.residualData = residualData;
52 this.residualSize = residualSize;
56 * Reads a sample from the input reader.
58 * @param reader the input reader to read the data from
59 * @param numChannels the number of channels per frame
61 public Sample(BufferedReader reader, int numChannels) {
63 String line = reader.readLine();
65 StringTokenizer tok = new StringTokenizer(line);
66 if (!tok.nextToken().equals("FRAME")) {
67 throw new Error("frame Parsing sample error");
70 frameData = new short[numChannels];
72 for (int i = 0; i < numChannels; i++) {
73 int svalue = Integer.parseInt(tok.nextToken()) - 32768;
75 if ( svalue < -32768 || svalue > 32767) {
76 throw new Error("data out of short range");
78 frameData[i] = (short) svalue;
81 line = reader.readLine();
82 tok = new StringTokenizer(line);
83 if (!tok.nextToken().equals("RESIDUAL")) {
84 throw new Error("residual Parsing sample error");
87 residualSize = Integer.parseInt(tok.nextToken());
88 residualData = new byte[residualSize];
90 for (int i = 0; i < residualSize; i++) {
91 int bvalue = Integer.parseInt(tok.nextToken()) - 128;
93 if ( bvalue < -128 || bvalue > 127) {
94 throw new Error("data out of byte range");
96 residualData[i] = (byte) bvalue;
98 } catch (NoSuchElementException nse) {
99 throw new Error("Parsing sample error " + nse.getMessage());
100 } catch (IOException ioe) {
101 throw new Error("IO error while parsing sample" + ioe.getMessage());
106 * Gets the frame data associated with this sample
108 * @return the frame data associated with this sample
110 public short[] getFrameData() {
115 * Gets the residual data associated with this sample
117 * @return the residual data associated with this sample
119 public byte[] getResidualData() {
124 * Returns the number of residuals in this Sample.
126 * @return the number of residuals in this sample
128 public int getResidualSize() {
134 * Returns the normalized residual data. You may not want to
135 * call this function because of the overhead involved.
137 * @param which the index of the data of interest
139 * @return the normalized data.
141 public int getResidualData(int which) {
142 return ((int)residualData[which]) + 128;
146 * Returns the normalized frame data. You may not want to
147 * call this function because of the overhead involved.
149 * @param which the index of the data of interest
151 * @return the normalized data.
153 public int getFrameData(int which) {
154 return ((int)frameData[which]) + 32768;
162 System.out.println(" FD Count: " + getFrameData().length);
163 for (int i = 0; i < getFrameData().length; i++) {
164 System.out.print(" " + getFrameData(i));
166 System.out.println();
167 System.out.println(" RD Count: " + getResidualSize());
168 // getResidualData().length);
169 for (int i = 0; i < getResidualData().length; i++) {
170 System.out.print(" " + getResidualData(i));
172 System.out.println();
176 * Dumps the samples to the given ByteBuffer
178 * @param bb the ByteBuffer to write the data to.
180 * @throws IOException if IO error occurs
182 public void dumpBinary(ByteBuffer bb) throws IOException {
183 bb.putInt(frameData.length);
184 for (int i = 0; i < frameData.length; i++) {
185 bb.putShort(frameData[i]);
187 bb.putInt(residualData.length);
188 bb.put(residualData);
192 * Dumps the samples to the given stream
194 * @param os the DataOutputStream to write the data to.
196 * @throws IOException if IO error occurs
198 public void dumpBinary(DataOutputStream os) throws IOException {
199 os.writeInt(frameData.length);
200 for (int i = 0; i < frameData.length; i++) {
201 os.writeShort(frameData[i]);
203 os.writeInt(residualData.length);
204 for (int i = 0; i < residualData.length; i++) {
205 os.writeByte(residualData[i]);
210 * Loads the samples from the byte bufer
212 * @param bb the byte buffer to read the data from.
214 * @throws IOException if IO error occurs
216 public static Sample loadBinary(ByteBuffer bb) throws IOException {
217 int frameDataSize = bb.getInt();
219 short[] frameData = new short[frameDataSize];
221 for (int i = 0; i < frameData.length; i++) {
222 frameData[i] = bb.getShort();
225 int residualDataSize = bb.getInt();
226 byte[] residualData = new byte[residualDataSize];
228 for (int i = 0; i < residualData.length; i++) {
229 residualData[i] = bb.get();
232 return new Sample(frameData, residualData, residualDataSize);
236 * Loads the samples from the given channel
238 * @param dis the DataInputStream to read the data from.
240 * @throws IOException if IO error occurs
242 public static Sample loadBinary(DataInputStream dis)
244 int frameDataSize = dis.readInt();
246 short[] frameData = new short[frameDataSize];
248 for (int i = 0; i < frameData.length; i++) {
249 frameData[i] = dis.readShort();
252 int residualDataSize = dis.readInt();
253 byte[] residualData = new byte[residualDataSize];
255 for (int i = 0; i < residualData.length; i++) {
256 residualData[i] = dis.readByte();
259 return new Sample(frameData, residualData, residualDataSize);
263 * Compares two samples. Note that this is not the same as
266 * @param other the other sample to compare this one to
268 * @return <code>true</code> if they compare; otherwise
271 public boolean compare(Sample other) {
273 if (frameData.length != other.getFrameData().length) {
277 for (int i = 0; i < frameData.length; i++) {
278 if (frameData[i] != other.frameData[i]) {
283 if (residualData.length != other.residualData.length) {
287 for (int i = 0; i < residualData.length; i++) {
288 if (residualData[i] != other.residualData[i]) {