content: /**
   * Copyright 2007 DFKI GmbH.
   * All Rights Reserved.  Use is subject to license terms.
   * <p/>
   * This file is part of MARY TTS.
   * <p/>
   * 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.
   * <p/>
   * 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.
   * <p/>
   * 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&uumlrk
   */
  public class PitchFileHeader {
      public static double DEFAULT_VOICING_THRESHOLD = 0.35; //Default voicing threshold
      public static double DEFAULT_MINIMUM_F0 = 50.0;
      public static double DEFAULT_MAXIMUM_F0 = 500.0;
      public static boolean DEFAULT_DOUBLING_CHECK = true;
      public static boolean DEFAULT_HALVING_CHECK = true;
      public static double DEFAULT_CENTER_CLIPPING_RATIO = 0.5;
      public static double DEFAULT_CUTOFF1 = DEFAULT_MINIMUM_F0 - 20.0;
      public static double DEFAULT_CUTOFF2 = DEFAULT_MAXIMUM_F0 + 200.0;
      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 double minimumF0; //Min f0 in Hz
      public double maximumF0; //Max f0 in Hz
      public boolean isDoublingCheck;
      public boolean isHalvingCheck;
      public double centerClippingRatio;
      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 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);
      }
  
  }
  
  