/** * Copyright 2004-2006 DFKI GmbH. * All Rights Reserved. Use is subject to license terms. * * This file is part of MARY TTS. * * MARY TTS is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, version 3 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * */ package marytts.util.data; /** * @author Marc Schröder * */ public class BlockwiseDoubleDataSource extends BufferedDoubleDataSource { protected int blockSize; /** * @param inputSource * inputSource * @param blockSize * block size */ public BlockwiseDoubleDataSource(DoubleDataSource inputSource, int blockSize) { super(inputSource); this.blockSize = blockSize; } /** * Attempt to get more data from the input source. If less than this can be read, the possible amount will be read, but * canReadMore() will return false afterwards. * * @param minLength * the amount of data to get from the input source * @return true if the requested amount could be read, false if none or less data could be read. */ @Override protected boolean readIntoBuffer(int minLength) { if (bufferSpaceLeft() < minLength) { // current buffer cannot hold the data requested; // need to make it larger increaseBufferSize(minLength + currentlyInBuffer()); } else if (buf.length - writePos < minLength) { compact(); // create a contiguous space for the new data } // Now we have a buffer that can hold at least minLength new data points int readSum = 0; // read blocks: while (readSum < minLength && hasMoreData()) { prepareBlock(); int blockSize = getBlockSize(); if (buf.length < writePos + blockSize) { increaseBufferSize(writePos + blockSize); } int read = readBlock(buf, writePos); if (read == 0) { break; // cannot read any more blocks } writePos += read; readSum += read; } if (dataProcessor != null) { dataProcessor.applyInline(buf, writePos - readSum, readSum); } return readSum >= minLength; } /** * Provide the size of the next block. This implementation returns the fixed blocksize given in the constructor. Subclasses * may want to override this method. * * @return blocksize */ protected int getBlockSize() { return blockSize; } /** * Prepare a block of data for output. This method is called before readBlock() is called. This implementation does nothing. * Subclasses will want to override this method. * */ protected void prepareBlock() { } /** * Read a block of data. This method is called after prepareBlock() is called. This implementation simply reads getBlockSize() * data from the inputSource given in the constructor. Subclasses will want to override this method. * * @param target * target * @param pos * pos * @return number of values written into target from position pos */ protected int readBlock(double[] target, int pos) { return inputSource.getData(target, pos, getBlockSize()); } }