📄 raisedcosinewindower.java
字号:
* * @param input the input Data object * * @throws DataProcessingException if a data processing error occurs */ private void process(DoubleData input) throws DataProcessingException { currentCollectTime = input.getCollectTime(); double[] in = input.getValues(); int length = overflowBuffer.getOccupancy() + in.length; List dataList = new LinkedList(); dataList.add(input); Data utteranceEnd = null; // read in more Data if we have under one window's length of data while (length < cosineWindow.length) { Data next = getPredecessor().getData(); if (next instanceof DoubleData) { dataList.add(next); length += ((DoubleData) next).getValues().length; } else if (next instanceof DataEndSignal) { utteranceEnd = next; break; } } double[] allSamples = in; // prepend overflow samples if (length != in.length) { allSamples = new double[length]; int start = 0; // copy overflow samples to allSamples buffer System.arraycopy(overflowBuffer.getBuffer(), 0, allSamples, start, overflowBuffer.getOccupancy()); start = overflowBuffer.getOccupancy(); // copy input samples to allSamples buffer for (Iterator i = dataList.iterator(); i.hasNext(); ) { DoubleData next = (DoubleData) i.next(); double[] samples = next.getValues(); System.arraycopy(samples, 0, allSamples, start, samples.length); start += samples.length; } } // apply Hamming window int residual = applyRaisedCosineWindow(allSamples, length); // save elements that also belong to the next window overflowBuffer.reset(); if (length - residual > 0) { overflowBuffer.append(allSamples, residual, length - residual); } if (utteranceEnd != null) { // end of utterance handling processUtteranceEnd(); outputQueue.add(utteranceEnd); } } /** * What happens when an DataEndSignal is * received. Basically pads up to a window of the overflow buffer * with zeros, and then apply the Hamming window to it. */ private void processUtteranceEnd() { overflowBuffer.padWindow(cosineWindow.length); applyRaisedCosineWindow (overflowBuffer.getBuffer(), cosineWindow.length); overflowBuffer.reset(); } /** * Applies the Hamming window to the given double array. * The windows are added to the output queue. Returns the index * of the first array element of next window that is not produced * because of insufficient data. * * @param in the audio data to apply window and the Hamming window * @param length the number of elements in the array to apply the * RaisedCosineWindow * * @return the index of the first array element of the next window */ private int applyRaisedCosineWindow(double[] in, int length) { int windowCount; // if no windows can be created but there is some data, // pad it with zeros if (length < cosineWindow.length) { double[] padded = new double[cosineWindow.length]; Arrays.fill(padded, 0); System.arraycopy(in, 0, padded, 0, length); in = padded; windowCount = 1; } else { windowCount = getWindowCount (length, cosineWindow.length, windowShift); } // create all the windows at once, not individually, saves time double[][] windows = new double[windowCount][cosineWindow.length]; int windowStart = 0; for (int i = 0; i < windowCount; windowStart += windowShift, i++) { double[] myWindow = windows[i]; // apply the Hamming Window function to the window of data for (int w = 0, s = windowStart; w < myWindow.length; s++, w++) { myWindow[w] = in[s] * cosineWindow[w]; } // add the frame to the output queue outputQueue.add(new DoubleData (myWindow, sampleRate, currentCollectTime, currentFirstSampleNumber)); currentFirstSampleNumber += windowShift; } return windowStart; } /** * Returns the number of windows in the given array, given the windowSize * and windowShift. * * @param arraySize the size of the array * @param windowSize the window size * @param windowShift the window shift * * @return the number of windows */ private static int getWindowCount(int arraySize, int windowSize, int windowShift) { if (arraySize < windowSize) { return 0; } else { int windowCount = 1; for (int windowEnd = windowSize; windowEnd + windowShift <= arraySize; windowEnd += windowShift) { windowCount++; } return windowCount; } }} class DoubleBuffer { private double[] buffer; private int occupancy; /** * Constructs a DoubleBuffer of the given size. */ DoubleBuffer(int size) { buffer = new double[size]; occupancy = 0; } /** * Returns the number of elements in this DoubleBuffer. * * @return the number of elements in this DoubleBuffer. */ public int getOccupancy() { return occupancy; } /** * Returns the underlying double array used to store the data. * * @return the underlying double array */ public double[] getBuffer() { return buffer; } /** * Appends all the elements in the given array to this DoubleBuffer. * * @param src the array to copy from * * @return the resulting number of elements in this DoubleBuffer. */ public int appendAll(double[] src) { return append(src, 0, src.length); } /** * Appends the specified elements in the given array to this DoubleBuffer. * * @param src the array to copy from * @param srcPos where in the source array to start from * @param length the number of elements to copy * * @return the resulting number of elements in this DoubleBuffer */ public int append(double[] src, int srcPos, int length) { if (occupancy + length > buffer.length) { length = buffer.length - occupancy; throw new Error("RaisedCosineWindower: " + "overflow-buffer: attempting to fill " + "buffer beyond its capacity."); } System.arraycopy(src, srcPos, buffer, occupancy, length); occupancy += length; return occupancy; } /** * If there are less than windowSize elements in this DoubleBuffer, * pad the up to windowSize elements with zero. * * @param windowSize the window size */ public void padWindow(int windowSize) { if (occupancy < windowSize) { Arrays.fill(buffer, occupancy, windowSize, 0); } } /** * Sets the number of elements in this DoubleBuffer to zero, without * actually remove the elements. */ public void reset() { occupancy = 0; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -