All Downloads are FREE. Search and download functionalities are using the official Maven repository.

marytts.unitselection.data.SyllableIterator Maven / Gradle / Ivy

The newest version!
/**
 * Copyright 2009 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 .
 *
 */

package marytts.unitselection.data;

import java.util.Iterator;
import java.util.NoSuchElementException;

import marytts.features.FeatureDefinition;
import marytts.features.FeatureVector;

/**
 * @author marc
 *
 */
public class SyllableIterator implements Iterator {

	private FeatureFileReader features;
	private int fromUnitIndex;
	private int toUnitIndex;

	private final int fiPhone;
	private final byte fvPhone_0;
	private final byte fvPhone_Silence;
	private final int fiSylStart;
	private final int fiSylEnd;
	private final boolean isHalfphone;
	private final int fiLR;
	private final int fvLR_L;
	private final int fvLR_R;

	private int i;
	private Syllable nextSyllable = null;

	/**
	 * Create a syllable iterator over the given feature file, starting from the given fromUnitIndex and reaching up to (and
	 * including) the given toUnitIndex
	 * 
	 * @param features
	 *            features
	 * @param fromUnitIndex
	 *            fromUnitIndex
	 * @param toUnitIndex
	 *            toUnitIndex
	 */
	public SyllableIterator(FeatureFileReader features, int fromUnitIndex, int toUnitIndex) {
		this.features = features;
		this.fromUnitIndex = fromUnitIndex;
		this.toUnitIndex = toUnitIndex;

		FeatureDefinition featureDefinition = features.getFeatureDefinition();
		fiPhone = featureDefinition.getFeatureIndex("phone");
		fvPhone_0 = featureDefinition.getFeatureValueAsByte(fiPhone, "0");
		fvPhone_Silence = featureDefinition.getFeatureValueAsByte(fiPhone, "_");
		fiSylStart = featureDefinition.getFeatureIndex("segs_from_syl_start");
		fiSylEnd = featureDefinition.getFeatureIndex("segs_from_syl_end");
		String halfphoneFeature = "halfphone_lr";
		if (featureDefinition.hasFeature(halfphoneFeature)) {
			isHalfphone = true;
			fiLR = featureDefinition.getFeatureIndex(halfphoneFeature);
			fvLR_L = featureDefinition.getFeatureValueAsByte(fiLR, "L");
			fvLR_R = featureDefinition.getFeatureValueAsByte(fiLR, "R");
		} else {
			isHalfphone = false;
			fiLR = fvLR_L = fvLR_R = 0;
		}

		i = fromUnitIndex;
	}

	public synchronized boolean hasNext() {
		if (nextSyllable == null) {
			prepareNextSyllable();
		}
		return nextSyllable != null;
	}

	public synchronized Syllable next() {
		if (nextSyllable == null) {
			prepareNextSyllable();
		}
		if (nextSyllable == null) {
			// no more syllables
			throw new NoSuchElementException("no more syllables!");
		}
		Syllable retval = nextSyllable;
		nextSyllable = null;
		return retval;
	}

	public void remove() {
		throw new UnsupportedOperationException("This iterator cannot remove syllables");
	}

	private void prepareNextSyllable() {
		if (nextSyllable != null) {
			return;
		}
		if (i > toUnitIndex) {
			return;
		}
		// if we get here, then i is the index of a unit before or at a syllable start
		while (i <= toUnitIndex && !isSyllableStart(i)) {
			i++;
		}
		if (i > toUnitIndex) {
			return;
		}
		int iSyllableStart = i;
		while (i <= toUnitIndex && !isSyllableEnd(i)) {
			i++;
		}
		if (i > toUnitIndex) {
			return;
		}
		int iSyllableEnd = i;
		nextSyllable = new Syllable(features, iSyllableStart, iSyllableEnd);
	}

	private boolean isSyllableStart(int index) {
		FeatureVector fv = features.getFeatureVector(index);

		return fv.getByteFeature(fiPhone) != fvPhone_0 // not an edge unit
				&& fv.getByteFeature(fiPhone) != fvPhone_Silence // not silence
				&& fv.getByteFeature(fiSylStart) == 0 // first segment in syllable
				&& (!isHalfphone || fv.getByteFeature(fiLR) == fvLR_L); // if halfphone, it's the left half
	}

	private boolean isSyllableEnd(int index) {
		FeatureVector fv = features.getFeatureVector(index);

		return fv.getByteFeature(fiPhone) != fvPhone_0 // not an edge unit
				&& fv.getByteFeature(fiPhone) != fvPhone_Silence // not silence
				&& fv.getByteFeature(fiSylEnd) == 0 // last segment in syllable
				&& (!isHalfphone || fv.getByteFeature(fiLR) == fvLR_R); // if halfphone, it's the right half
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy