/**
* Copyright 2007 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.signalproc.analysis;
import java.io.IOException;
import marytts.util.io.LEDataInputStream;
import marytts.util.io.LEDataOutputStream;
import marytts.util.io.MaryRandomAccessFile;
/**
* Implements a structured header with file I/O functionality for binary files that store frame based f0 values
*
* @author Oytun Türk
*/
public class PitchFileHeader {
public double windowSizeInSeconds; // Window size in seconds
public double skipSizeInSeconds; // Skip size in seconds
public int fs; // Rate in Hz
public int numfrm; // Number of frames
public double voicingThreshold; // Voicing threshold
public static double DEFAULT_VOICING_THRESHOLD = 0.35; // Default voicing threshold
public double minimumF0; // Min f0 in Hz
public double maximumF0; // Max f0 in Hz
public static double DEFAULT_MINIMUM_F0 = 50.0;
public static double DEFAULT_MAXIMUM_F0 = 500.0;
public boolean isDoublingCheck;
public boolean isHalvingCheck;
public static boolean DEFAULT_DOUBLING_CHECK = true;
public static boolean DEFAULT_HALVING_CHECK = true;
public double centerClippingRatio;
public static double DEFAULT_CENTER_CLIPPING_RATIO = 0.5;
public double cutOff1; // Lower cut-off freq for bandpass filter in Hz (or cut-off freq for lowpass filter if cutOff2<=0.0)
public double cutOff2; // Upper cut-off freq for bandpass filter in Hz (Set to <=0.0 if you want a lowpass filter with cut-off
// at cutOff1 Hz.)
public static double DEFAULT_CUTOFF1 = DEFAULT_MINIMUM_F0 - 20.0;
public static double DEFAULT_CUTOFF2 = DEFAULT_MAXIMUM_F0 + 200.0;
public PitchFileHeader() {
windowSizeInSeconds = 0.040;
skipSizeInSeconds = 0.005;
fs = 0;
numfrm = 0;
voicingThreshold = DEFAULT_VOICING_THRESHOLD;
minimumF0 = DEFAULT_MINIMUM_F0;
maximumF0 = DEFAULT_MAXIMUM_F0;
isDoublingCheck = DEFAULT_DOUBLING_CHECK;
isHalvingCheck = DEFAULT_HALVING_CHECK;
centerClippingRatio = DEFAULT_CENTER_CLIPPING_RATIO;
cutOff1 = DEFAULT_CUTOFF1;
cutOff2 = DEFAULT_CUTOFF2;
}
public PitchFileHeader(PitchFileHeader existingHeader) {
windowSizeInSeconds = existingHeader.windowSizeInSeconds;
skipSizeInSeconds = existingHeader.skipSizeInSeconds;
fs = existingHeader.fs;
numfrm = existingHeader.numfrm;
voicingThreshold = existingHeader.voicingThreshold;
minimumF0 = existingHeader.minimumF0;
maximumF0 = existingHeader.maximumF0;
isDoublingCheck = existingHeader.isDoublingCheck;
isHalvingCheck = existingHeader.isHalvingCheck;
centerClippingRatio = existingHeader.centerClippingRatio;
cutOff1 = existingHeader.cutOff1;
cutOff2 = existingHeader.cutOff2;
}
public void readPitchHeader(MaryRandomAccessFile stream) throws IOException {
readPitchHeader(stream, true);
}
public void readPitchHeader(MaryRandomAccessFile stream, boolean bLeaveStreamOpen) throws IOException {
if (stream != null) {
windowSizeInSeconds = stream.readDouble();
skipSizeInSeconds = stream.readDouble();
fs = stream.readInt();
numfrm = stream.readInt();
voicingThreshold = stream.readDouble();
minimumF0 = stream.readDouble();
maximumF0 = stream.readDouble();
isDoublingCheck = stream.readBoolean();
isHalvingCheck = stream.readBoolean();
centerClippingRatio = stream.readDouble();
cutOff1 = stream.readDouble();
cutOff2 = stream.readDouble();
if (!bLeaveStreamOpen) {
stream.close();
stream = null;
}
}
}
public void readPitchHeaderOld(LEDataInputStream stream) throws IOException {
readPitchHeaderOld(stream, true);
}
// The old version kept window size and skip size in samples so perform conversion to seconds after reading them from file
public void readPitchHeaderOld(LEDataInputStream stream, boolean bLeaveStreamOpen) throws IOException {
if (stream != null) {
windowSizeInSeconds = stream.readFloat();
skipSizeInSeconds = stream.readFloat();
fs = stream.readInt();
numfrm = stream.readInt();
voicingThreshold = DEFAULT_VOICING_THRESHOLD;
minimumF0 = DEFAULT_MINIMUM_F0;
maximumF0 = DEFAULT_MAXIMUM_F0;
isDoublingCheck = DEFAULT_DOUBLING_CHECK;
isHalvingCheck = DEFAULT_HALVING_CHECK;
centerClippingRatio = DEFAULT_CENTER_CLIPPING_RATIO;
cutOff1 = DEFAULT_CUTOFF1;
cutOff2 = DEFAULT_CUTOFF2;
windowSizeInSeconds = windowSizeInSeconds / fs;
skipSizeInSeconds = skipSizeInSeconds / fs;
if (!bLeaveStreamOpen) {
stream.close();
stream = null;
}
}
}
public void writePitchHeader(String pitchFile) throws IOException {
writePitchHeader(pitchFile, false);
}
// This version returns the file output stream for further use, i.e. if you want to write additional information
// in the file use this version
public MaryRandomAccessFile writePitchHeader(String pitchFile, boolean bLeaveStreamOpen) throws IOException {
MaryRandomAccessFile stream = new MaryRandomAccessFile(pitchFile, "rw");
if (stream != null) {
writePitchHeader(stream);
if (!bLeaveStreamOpen) {
stream.close();
stream = null;
}
}
return stream;
}
public void writePitchHeader(MaryRandomAccessFile ler) throws IOException {
ler.writeDouble(windowSizeInSeconds);
ler.writeDouble(skipSizeInSeconds);
ler.writeInt(fs);
ler.writeInt(numfrm);
ler.writeDouble(voicingThreshold);
ler.writeDouble(minimumF0);
ler.writeDouble(maximumF0);
ler.writeBoolean(isDoublingCheck);
ler.writeBoolean(isHalvingCheck);
ler.writeDouble(centerClippingRatio);
ler.writeDouble(cutOff1);
ler.writeDouble(cutOff2);
}
public void writePitchHeaderOld(String pitchFile) throws IOException {
writePitchHeaderOld(pitchFile, false);
}
// This version returns the file output stream for further use, i.e. if you want to write additional information
// in the file use this version
public LEDataOutputStream writePitchHeaderOld(String pitchFile, boolean bLeaveStreamOpen) throws IOException {
LEDataOutputStream stream = new LEDataOutputStream(pitchFile);
if (stream != null) {
writePitchHeaderOld(stream);
if (!bLeaveStreamOpen) {
stream.close();
stream = null;
}
}
return stream;
}
public void writePitchHeaderOld(LEDataOutputStream ler) throws IOException {
ler.writeDouble(windowSizeInSeconds);
ler.writeDouble(skipSizeInSeconds);
ler.writeInt(fs);
ler.writeInt(numfrm);
}
}