⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 findsts.java

📁 使用Exlipse编写的一个语音程序
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/** * Portions Copyright 2003 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.FileInputStream;import java.io.DataInputStream;import java.io.OutputStreamWriter;import java.io.FileOutputStream;import java.io.IOException;import java.io.FileNotFoundException;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 {    /**     * Generate an sts file     *     * <p>     * <b>Usage</b>     * </p>     * <p>     *  <code> java FindSTS lpc_min lpc_range lpcFile waveFile stsFile     * </code>     * </p>     * <p>     * <code> stsFile </code> the output file.     * </p>     */    public static void main(String[] args) {        try {            if (args.length != 5) {                System.err.println("Usage: java FindSTS lpc_min lpc_range "                        + "lpcFile waveFile stsFile");            } else {                float lpc_min = Float.parseFloat(args[0]);                float lpc_range = Float.parseFloat(args[1]);                FileInputStream lpcFile = new FileInputStream(args[2]);                FileInputStream waveFile = new FileInputStream(args[3]);                FileOutputStream stsFile = new FileOutputStream(args[4]);                // 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                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++) {                osw.write("( " + Float.toString(lpc.getTime(i)) + " (");                // Use the following line instead to compare against                // the flite find_sts output                //osw.write("( " + Utility.hex(lpc.getTime(i)) + " (");                for (int j = 1; j < lpc.getNumChannels(); j++) {                    osw.write(" " +                            Integer.toString(stsData[i].getFrameEntry(j - 1)));                }                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));            }        }    }    /**     * 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);    }    /**

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -