📄 findsts.java
字号:
/** * Portions Copyright 2003-2004 Sun Microsystems, Inc. * Portions Copyright 1999-2003 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. */import java.io.BufferedReader;import java.io.DataInputStream;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.FileNotFoundException;import java.io.InputStreamReader;import java.io.IOException;import java.io.OutputStreamWriter;import javax.sound.sampled.spi.AudioFileReader;import javax.sound.sampled.AudioInputStream;/** * Performs the generation of STS files in FestVox to FreeTTS * conversion. * * <p> * This program is a port from flite/tools/find_sts_main.c * </p> * * <p> * Note: * The a/b diff result is slightly different than the C version due to * Intel floating-point math. * </p> */public strictfp class FindSTS { static float lpc_min; static float lpc_max; static float lpc_range; /** * Gets the lpc parameters from lpc/lpc.params */ static private void getLpcParams() throws IOException { BufferedReader reader = new BufferedReader( new InputStreamReader( new FileInputStream("lpc/lpc.params"))); String line = reader.readLine(); while (line != null) { if (line.startsWith("LPC_MIN=")) { lpc_min = Float.parseFloat(line.substring(8)); } else if (line.startsWith("LPC_MAX=")) { lpc_max = Float.parseFloat(line.substring(8)); } else if (line.startsWith("LPC_RANGE=")) { lpc_range = Float.parseFloat(line.substring(10)); } line = reader.readLine(); } reader.close(); System.out.println("LPC_MIN=" + lpc_min); System.out.println("LPC_MAX=" + lpc_max); System.out.println("LPC_RANGE=" + lpc_range); } /** * Generate an sts file from lpc and wav files. * * args[0..n] = filenames without paths or extensions * (e.g., "arctic_a0001") */ public static void main(String[] args) { try { getLpcParams(); for (int i = 0; i < args.length; i++) { System.out.println(args[i] + " STS"); FileInputStream lpcFile = new FileInputStream( "lpc/" + args[i] + ".lpc"); FileInputStream waveFile = new FileInputStream( "wav/" + args[i] + ".wav"); FileOutputStream stsFile = new FileOutputStream( "sts/" + args[i] + ".sts"); // Read input LPC lpc = new LPC(new DataInputStream(lpcFile)); Wave wave = new Wave(new DataInputStream(waveFile)); lpcFile.close(); waveFile.close(); // Generate sts data STS[] stsData = findSTS(wave, lpc, lpc_min, lpc_range); // Verify STS data for sanity if (false) { Wave reconstructedWave = new Wave(wave.getSampleRate(), stsData, lpc, lpc_min, lpc_range); wave.compare(reconstructedWave); } // Save output OutputStreamWriter stsWriter = new OutputStreamWriter(stsFile); saveSTS(stsData, lpc, wave, stsWriter, lpc_min, lpc_range); stsWriter.close(); stsFile.close(); } } catch (FileNotFoundException ioe) { throw new Error("Error while running FindSTS" + ioe.getMessage()); } catch (IOException ioe) { throw new Error("IO error while finding sts" + ioe.getMessage()); } } /** * Find the sts data. * * @param wave the data from the wave file * @param lpc the data from the lpc file * @param lpc_min the minimum lpc value * @param lpc_range the range of the lpc values * * @return an <code>STS</code> array containing the data */ private static STS[] findSTS(Wave wave, LPC lpc, float lpc_min, float lpc_range) { int size; int start = 0; int end; STS[] stsData = new STS[lpc.getNumFrames()]; // read wave data into a special array. short[] waveData = new short[wave.getNumSamples() + lpc.getNumChannels()]; System.arraycopy(wave.getSamples(), 0, waveData, lpc.getNumChannels(), wave.getNumSamples()); for (int i = 0; i < lpc.getNumFrames(); i++) { double[] resd; int[] frame; short[] residual; end = (int) ((float) wave.getSampleRate() * lpc.getTime(i)); size = end - start; if (size <= 0) { System.out.println("frame size at " + Float.toString(lpc.getTime(i)) + " is " + Integer.toString(size) + "."); } residual = generateResiduals(waveData, start + lpc.getNumChannels(), lpc.getFrame(i), lpc.getNumChannels(), size); frame = new int[lpc.getNumChannels() - 1]; for (int j = 1; j < lpc.getNumChannels(); j++) { frame[j - 1] = (int) ((((lpc.getFrameEntry(i, j) - lpc_min) / lpc_range)) * (float) 65535.0); } stsData[i] = new STS(frame, size, residual); start = end; } return stsData; } /** * Generate the residuals for this sts * * @param wave specially formatted wave data * @param start offset into the wave data * @param frame frame data from the lpc * @param order typically the number of lpc channels * @param size size of the residual * * @return sts residuals */ private static short[] generateResiduals(short[] wave, int start, float[] frame, int order, int size) { double r; short[] residual = new short[size]; for (int i = 0; i < order; i++) { r = wave[start + i]; for (int j = 1; j < order; j++) { r -= frame[j] * ((double) wave[start + (i - j)]); } residual[i] = Utility.shortToUlaw((short) r); } for (int i = order; i < size; i++) { r = wave[start + i]; for (int j = 1; j < order; j++) { r -= frame[j] * ((double) wave[start + (i - j)]); } residual[i] = Utility.shortToUlaw((short) r); } return residual; } /** * Save the sts data * * @param stsData generated sts data * @param lpc data loaded from the lpc file * @param wave data loaded from the wave file * @param osw the OutputStreamWriter to write the sts data to * @param lpc_min minimum lpc value * @param lpc_range range of lpc values * */ private static void saveSTS(STS[] stsData, LPC lpc, Wave wave, OutputStreamWriter osw, float lpc_min, float lpc_range) { try { osw.write(Integer.toString(lpc.getNumFrames()) + " " + Integer.toString(lpc.getNumChannels() - 1) + " " + Integer.toString(wave.getSampleRate()) + " " + Float.toString(lpc_min) + " " + Float.toString(lpc_range) + "\n"); for (int m=0, i=0; i < lpc.getNumFrames(); i++) { /* time lpc lpc lpc lpc ... */ osw.write(Float.toString(lpc.getTime(i)) + "\n"); for (int j = 1; j < lpc.getNumChannels(); j++) { osw.write( Integer.toString(stsData[i].getFrameEntry(j - 1)) + " "); } osw.write("\n"); /* numResid resid resid resid */ osw.write(Integer.toString(stsData[i].getNumSamples())); for (int j = 0; j < stsData[i].getNumSamples(); j++) { osw.write( " " + Integer.toString(stsData[i].getResidual(j))); } osw.write("\n"); } } catch (IOException ioe) { throw new Error("IO error while writing sts." + ioe.getMessage()); } }}/** * The lpc data * */class LPC { private int numFrames; private int numChannels; float[] times; float[][] frames; /** Create lpc data from an input stream * * @param dis DataInputStream to read the lpc in from * */ public LPC(DataInputStream dis) { try { if (!Utility.readWord(dis).equals("EST_File") || !Utility.readWord(dis).equals("Track")) { throw new Error("Lpc file not EST Track file"); } boolean isBinary = false; boolean isBigEndian = false; // Read Header String token = Utility.readWord(dis); while (!token.equals("EST_Header_End")) { if (token.equals("DataType")) { if (Utility.readWord(dis).equals("binary")) { isBinary = true; } else { isBinary = false; } } else if (token.equals("ByteOrder")) { if (Utility.readWord(dis).equals("10")) { isBigEndian = true; } else { isBigEndian = false; } } else if (token.equals("NumFrames")) { numFrames = Integer.parseInt(Utility.readWord(dis)); } else if (token.equals("NumChannels")) { numChannels = Integer.parseInt(Utility.readWord(dis)); } // Ignore all other content in header token = Utility.readWord(dis); } times = new float[numFrames]; frames = new float[numFrames][numChannels]; // read data section if (isBinary) { loadBinaryData(dis, isBigEndian); } else { loadTextData(dis); } } catch (IOException ioe) { throw new Error("IO error while parsing lpc" + ioe.getMessage()); } } /** * load the data section of the lpc file as ascii text * * @param dis DataInputStream to read from * * @throws IOException on ill-formatted input */ private void loadTextData(DataInputStream dis) throws IOException { for (int f=0; f < numFrames; f++) { times[f] = Float.parseFloat(Utility.readWord(dis)); Utility.readWord(dis); // can be only 1 for (int c=0; c < numChannels; c++) { frames[f][c] = Float.parseFloat(Utility.readWord(dis)); } } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -