📄 lpcresult.java
字号:
public byte[] getWaveSamples() { return getWaveSamples(2*getNumberOfSamples(), null); } /** * get the samples for this utterance * * @param numberSamples the number of samples desirred * @param utterance the utterance * * [[[ TODO: well there is a bunch of duplicated code here .. * these should be combined into one routine. * ]]] */ private byte[] getWaveSamples(int numberSamples, Utterance utterance) { int numberChannels = getNumberOfChannels(); int pmSizeSamples; float pp = 0; byte[] samples = new byte[numberSamples]; byte[] residuals = getResiduals(); int[] residualSizes = getResidualSizes(); FloatList outBuffer = FloatList.createList(numberChannels + 1); FloatList lpcCoefficients = FloatList.createList(numberChannels); double multiplier = (double) getLPCRange() / 65535.0; int s = 0; boolean firstPlay = true; // for each frame in the LPC result for (int r = 0, i = 0; i < numberOfFrames; i++) { // unpack the LPC coefficients short[] frame = getFrame(i); FloatList lpcCoeffs = lpcCoefficients; for (int k = 0; k < numberChannels; k++) { lpcCoeffs.value = (float) ( (frame[k] + 32768.0) * multiplier) + lpcMinimum; lpcCoeffs = lpcCoeffs.next; } pmSizeSamples = residualSizes[i]; // resynthesis the signal, pmSizeSamples ~= 90 // what's in the loop is done for each residual for (int j = 0; j < pmSizeSamples; j++, r++) { FloatList backBuffer = outBuffer.prev; float ob = residualToFloatMap[residuals[r] + 128]; lpcCoeffs = lpcCoefficients; do { ob += lpcCoeffs.value * backBuffer.value; backBuffer = backBuffer.prev; lpcCoeffs = lpcCoeffs.next; } while (lpcCoeffs != lpcCoefficients); int sample = (int) (ob + (pp * POST_EMPHASIS)); samples[s++] = (byte) hibyte(sample); samples[s++] = (byte) lobyte(sample); outBuffer.value = pp = ob; outBuffer = outBuffer.next; } } return samples; } /** * Play the sample data on the given player * * @param player where to send the audio * @param numberSamples the number of samples */ private boolean playWaveSamples(AudioPlayer player, FreeTTSSpeakable speakable, int numberSamples) { boolean ok = true; int numberChannels = getNumberOfChannels(); int pmSizeSamples; float pp = 0; byte[] samples = new byte[MAX_SAMPLE_SIZE]; byte[] residuals = getResiduals(); int[] residualSizes = getResidualSizes(); FloatList outBuffer = FloatList.createList(numberChannels + 1); FloatList lpcCoefficients = FloatList.createList(numberChannels); double multiplier = (double) getLPCRange() / 65535.0; int s = 0; boolean firstPlay = true; // for each frame in the LPC result player.begin(numberSamples); for (int r = 0, i = 0; (ok &= !speakable.isCompleted()) && i < numberOfFrames; i++) { // unpack the LPC coefficients short[] frame = getFrame(i); FloatList lpcCoeffs = lpcCoefficients; for (int k = 0; k < numberChannels; k++) { lpcCoeffs.value = (float) ( (frame[k] + 32768.0) * multiplier) + lpcMinimum; lpcCoeffs = lpcCoeffs.next; } pmSizeSamples = residualSizes[i]; // resynthesis the signal, pmSizeSamples ~= 90 // what's in the loop is done for each residual for (int j = 0; j < pmSizeSamples; j++, r++) { FloatList backBuffer = outBuffer.prev; float ob = residualToFloatMap[residuals[r] + 128]; lpcCoeffs = lpcCoefficients; do { ob += lpcCoeffs.value * backBuffer.value; backBuffer = backBuffer.prev; lpcCoeffs = lpcCoeffs.next; } while (lpcCoeffs != lpcCoefficients); int sample = (int) (ob + (pp * POST_EMPHASIS)); samples[s++] = hibyte(sample); samples[s++] = lobyte(sample); if (s >= MAX_SAMPLE_SIZE) { if ((ok &= !speakable.isCompleted()) && !player.write(samples)) { ok = false; } s = 0; } outBuffer.value = pp = ob; outBuffer = outBuffer.next; } } // write out the very last samples if ((ok &= !speakable.isCompleted()) && s > 0) { ok = player.write(samples, 0, s); s = 0; } // tell the AudioPlayer it is the end of Utterance if (ok &= !speakable.isCompleted()) { ok = player.end(); } return ok; } /** * Dumps this LPCResult to standard out */ public void dump() { dump(new OutputStreamWriter(System.out)); } /** * Dumps this LPCResult to the given stream. * * @param writer the output stream */ public void dump(Writer writer) { DecimalFormat numberFormat = new DecimalFormat(); numberFormat.setMaximumFractionDigits(6); numberFormat.setMinimumFractionDigits(6); PrintWriter pw = new PrintWriter(new BufferedWriter(writer)); if (getNumberOfFrames() == 0) { pw.println("# ========== LPCResult =========="); pw.println("# Num_of_Frames: " + getNumberOfFrames()); pw.flush(); return; } pw.println("========== LPCResult =========="); pw.println("Num_of_Frames: " + getNumberOfFrames()); pw.println("Num_of_Channels: " + getNumberOfChannels()); pw.println("Num_of_Samples: " + getNumberOfSamples()); pw.println("Sample_Rate: " + sampleRate); pw.println("LPC_Minimum: " + numberFormat.format(lpcMinimum)); pw.println("LPC_Range: " + numberFormat.format(lpcRange)); pw.println("Residual_Fold: " + residualFold); pw.println("Post_Emphasis: " + numberFormat.format(POST_EMPHASIS)); int i; pw.print("Times:\n"); for (i = 0; i < getNumberOfFrames(); i++) { pw.print(times[i] + " "); } pw.print("\nFrames: "); for (i = 0; i < getNumberOfFrames(); i++) { // for each frame, print all elements short[] frame = getFrame(i); for (int j = 0; j < frame.length; j++) { pw.print(( ((int) frame[j]) + 32768) + "\n"); } } pw.print("\nSizes: "); for (i = 0; i < getNumberOfFrames(); i++) { pw.print(sizes[i] + " "); } pw.print("\nResiduals: "); for (i = 0; i < getNumberOfSamples(); i++) { if (residuals[i] == 0) { pw.print(255); } else { pw.print(( ((int) residuals[i]) + 128)); } pw.print("\n"); pw.flush(); } pw.flush(); } /** * Dumps the wave data associated with this result */ public void dumpASCII() { dumpASCII(new OutputStreamWriter(System.out)); } /** * Dumps the wave data associated with this result * * @param path the path where the wave data is appended to * * @throws IOException if an IO error occurs */ public void dumpASCII(String path) throws IOException { Writer writer = new FileWriter(path, true); getWave().dump(writer); } /** * Synthesize a Wave from this LPCResult * * @return the wave */ private Wave getWave() { // construct a new wave object AudioFormat audioFormat = new AudioFormat (getSampleRate(), Wave.DEFAULT_SAMPLE_SIZE_IN_BITS, 1, Wave.DEFAULT_SIGNED, true); return new Wave(audioFormat, getWaveSamples( getNumberOfSamples() * 2, null)); } /** * Dumps the wave out to the given stream * * @param writer the output stream */ public void dumpASCII(Writer writer) { Wave wave = getWave(); wave.dump(writer); } /** * A Wave is an immutable class that contains the AudioFormat and * the actual wave samples, which currently is in the form * of AudioInputStream. */ private static class Wave { /** * The default sample size of the Wave, which is 16. */ public static final int DEFAULT_SAMPLE_SIZE_IN_BITS = 16; /** * A boolean indicating that the Wave is signed, i.e., * this value is true. */ public static final boolean DEFAULT_SIGNED = true; /** * A boolean indicating that the Wave samples are represented as * little endian, i.e., this value is false. */ public static final boolean DEFAULT_BIG_ENDIAN = false; private byte[] samples = null; private AudioFormat audioFormat = null; /** * Constructs a Wave with the given audio format and wave samples. * * @param audioFormat the audio format of the wave * @param samples the wave samples */ Wave(AudioFormat audioFormat, byte[] samples) { this.audioFormat = audioFormat; this.samples = samples; } /** * Dumps the wave out to the given stream * @param writer the output stream */ public void dump(Writer writer) { PrintWriter pw = new PrintWriter(new BufferedWriter(writer)); pw.println("#========== Wave =========="); pw.println("#Type: NULL"); pw.println("#Sample_Rate: " + (int)audioFormat.getSampleRate()); pw.println("#Num_of_Samples: " + samples.length / 2); pw.println("#Num_of_Channels: " + audioFormat.getChannels()); if (samples != null) { for (int i = 0; i < samples.length; i+=2) { pw.println( WaveUtils.bytesToShort(samples[i], samples[i+1])); } } pw.flush(); } }} /** * FloatList is used to maintain a circular buffer of float values. * It is essentially an index-free array of floats that can easily be * iterated through forwards or backwards. Keeping values in an index * free list like this eliminates index bounds checking which can * save us some time. */class FloatList { float value; FloatList next; FloatList prev; /** * Creates a new node */ FloatList() { value = 0.0F; next = null; prev = null; } /** * Creates a circular list of nodes of the given size * * @param size the number of nodes in the list * * @return an entry in the list. */ static FloatList createList(int size) { FloatList prev = null; FloatList first = null; for (int i = 0; i < size; i++) { FloatList cur = new FloatList(); cur.prev = prev; if (prev == null) { first = cur; } else { prev.next = cur; } prev = cur; } first.prev = prev; prev.next = first; return first; } /** * prints out the contents of this list * * @param title the title of the dump * @param list the list to dump */ static void dump(String title, FloatList list) { System.out.println(title); FloatList cur = list; do { System.out.println("Item: " + cur.value); cur = cur.next; } while (cur != list); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -