📄 findsts.java
字号:
/** * load the data section of the lpc file as ascii text * * @param dis DataInputStream to read from * @param isBigEndian whether or not the data in the file is in * big endian byte order * * @throws IOException on ill-formatted input */ private void loadBinaryData(DataInputStream dis, boolean isBigEndian) throws IOException { for (int f=0; f < numFrames; f++) { times[f] = Utility.readFloat(dis, isBigEndian); // Ignore the 'breaks' field Utility.readFloat(dis, isBigEndian); for (int c=0; c < numChannels; c++) { frames[f][c] = Utility.readFloat(dis, isBigEndian); } } } /** * Get the number of frames in this lpc * * @return number of frames in this lpc */ public int getNumFrames() { return numFrames; } /** * Get the number of channels in this lpc * * @return number of channels in this lpc */ public int getNumChannels() { return numChannels; } /** * Get the times associated with this lpc * * @return an array of times associated with this lpc */ public float[] getTimes() { return times; } /** * Get an individual time associated with this lpc * * @param index index of time to get * * @return time value at given index */ public float getTime(int index) { return times[index]; } /** * Get an individual frame * * @param i index of frame * * @return the frame */ public float[] getFrame(int i) { return frames[i]; } /** * Get an individual frame entry * * @param i index of frame * @param j index into frame * * @return the frame entry in frame <code>i</code> at index * <code>j</code> */ public float getFrameEntry(int i, int j) { return frames[i][j]; }}/** * The wave (riff) data */class Wave { private int numSamples; private int sampleRate; private short[] samples; // Only really used in loading of data. private int headerSize; private int numBytes; private int numChannels = 1; // Only support mono static final short RIFF_FORMAT_PCM = 0x0001; /** * Read in a wave from a riff format * * @param dis DataInputStream to read data from */ public Wave (DataInputStream dis) { try { loadHeader(dis); if (dis.skipBytes(headerSize - 16) != (headerSize - 16)) { throw new Error("Unexpected error parsing wave file."); } // Bunch of potential random headers while (true) { String s = new String(Utility.readChars(dis, 4)); if (s.equals("data")) { numSamples = Utility.readInt(dis, false) / 2; break; } else if (s.equals("fact")) { int i = Utility.readInt(dis, false); if (dis.skipBytes(i) != i) { throw new Error("Unexpected error parsing wave file."); } } else { throw new Error("Unsupported wave header chunk type " + s); } } int dataLength = numSamples * numChannels; samples = new short[numSamples]; for (int i = 0; i < dataLength; i++) { samples[i] = Utility.readShort(dis, false); } } catch (IOException ioe) { throw new Error("IO error while parsing wave" + ioe.getMessage()); } } /** * load a RIFF header * * @param dis DataInputStream to read from * * @throws IOException on ill-formatted input */ private void loadHeader(DataInputStream dis) throws IOException { if (!checkChars(dis, "RIFF")) { throw new Error("Invalid wave file format."); } numBytes = Utility.readInt(dis,false); if (!checkChars(dis, "WAVEfmt ")) { throw new Error("Invalid wave file format."); } headerSize = Utility.readInt(dis, false); if (Utility.readShort(dis, false) != RIFF_FORMAT_PCM) { throw new Error("Invalid wave file format."); } if (Utility.readShort(dis, false) != 1) { throw new Error("Only mono wave files supported."); } sampleRate = Utility.readInt(dis, false); Utility.readInt(dis, false); Utility.readShort(dis, false); Utility.readShort(dis, false); } /** * Reconstruct a wave from a wave, sts, and lpc * * @param sampleRate the sample rate to use * @param lpc lpc * @param lpc_min minimum lpc value * @param lpc_range range of lpc values */ public Wave(int sampleRate, STS[] stsData, LPC lpc, float lpc_min, float lpc_range) { // set number of samples and sample rate numSamples = 0; for (int i = 0; i < lpc.getNumFrames(); i++) { numSamples += stsData[i].getNumSamples(); } samples = new short[numSamples]; this.sampleRate = sampleRate; int start = 0; int end; int[] lpcResTimes = new int[lpc.getNumFrames()]; int[] lpcResSizes = new int[lpc.getNumFrames()]; short[] lpcResResidual = new short[numSamples]; int[][] lpcResFrames = new int[lpc.getNumFrames()][]; int lpcResNumChannels = lpc.getNumChannels() - 1; // load initial data for (int i = 0; i < lpc.getNumFrames(); i++) { lpcResTimes[i] = (int) (lpc.getTime(i) * sampleRate); lpcResFrames[i] = stsData[i].getFrame(); end = start + stsData[i].getNumSamples(); lpcResSizes[i] = stsData[i].getNumSamples(); start = end; } for (int r = 0, i = 0; i < lpc.getNumFrames(); i++) { for (int j = 0; j < stsData[i].getNumSamples(); j++, r++) { lpcResResidual[r] = stsData[i].getResidual(j); } } float[] lpcCoefs = new float[lpcResNumChannels]; float[] outbuf = new float[lpcResNumChannels + 1]; int ci, cr; //float pp = 0; // the C code uses this unnecessarily (for now) for (int r = 0, o = lpcResNumChannels, i = 0; i < lpc.getNumFrames(); i++) { // residual_fold is hard-coded to 1. int pm_size_samps = lpcResSizes[i];// * residual_fold; // Unpack the LPC coefficients for (int k = 0; k < lpcResNumChannels; k++) { lpcCoefs[k] = (float) ((((double) lpcResFrames[i][k])/65535.0) * lpc_range) + lpc_min; } // resynthesize the signal for (int j = 0; j < pm_size_samps; j++, r++) { outbuf[o] = (float) Utility.ulawToShort(lpcResResidual[r/* /residual_fold */]); cr = (o == 0 ? lpcResNumChannels : o-1); for (ci = 0; ci < lpcResNumChannels; ci++) { outbuf[o] += lpcCoefs[ci] * outbuf[cr]; cr = (cr == 0 ? lpcResNumChannels : cr - 1); } samples[r] = (short) (outbuf[o] /* + pp * lpcres->post_emphasis)*/); // post_emphasis = 0 // pp = outbuf[o]; o = (o == lpcResNumChannels ? 0 : o+1); } } } /** * Compare two waves and output how close the two are. * Useful for checking the general accuracy of find sts. * * <p> * Output may not exactly match that of flite find_sts * on Intel platforms due to discrepencies in the way that * Intel Pentiums perform floating point computations. * </p> * * @param the wave to compare this wave against * */ public void compare(Wave wave2) { if (numSamples > wave2.numSamples) { wave2.compare(this); } else { double r = 0; int i = 0; for (i = 0; i < this.numSamples; i++) { r += (double)((float)this.samples[i] - (float)wave2.samples[i]) *(double)((float)this.samples[i] - (float)wave2.samples[i]); } r /= this.numSamples; System.out.println("a/b diff " + Double.toString(StrictMath.sqrt(r))); } } /** * Make sure that a string of characters appear next in the file * * @param dis DataInputStream to read in * @param chars a String containing the ascii characters you * want the <code>dis</code> to contain. * * @return <code>true</code> if <code>chars</code> appears next * in <code>dis</code>, else <code>false</code> * @throws on ill-formatted input (end of file, for example) */ private boolean checkChars(DataInputStream dis, String chars) throws IOException { char[] carray = chars.toCharArray(); for (int i = 0; i < carray.length; i++) { if ((char) dis.readByte() != carray[i]) { return false; } } return true; } /** * Get the sample rate for this wave * * @return sample rate */ public int getSampleRate() { return sampleRate; } /** * Get the number of samples for this wave * * @return number of samples */ public int getNumSamples() { return numSamples; } /* Get the sample data of this wave * * @return samples */ public short[] getSamples() { return samples; }}/** * The sts data
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -