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

marytts.tools.voiceimport.SPTKMFCCExtractor 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.tools.voiceimport;

import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.EOFException;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.Vector;

import marytts.signalproc.analysis.Mfccs;
import marytts.util.io.General;

/**
 * A component for extracting mfcc files from wave files
 * 
 * @author Marcela, Sathish Pammi
 *
 */
public class SPTKMFCCExtractor extends VoiceImportComponent {

	public final String SPTKINST = "SPTKMFCCExtractor.sptkinstallationDir";
	public final String SOXCOMMAND = "SPTKMFCCExtractor.soxCommand";
	public final String INWAVDIR = "SPTKMFCCExtractor.inputWAVEDIR";
	public final String OUTMFCCDIR = "SPTKMFCCExtractor.outputMFCCDIR";
	private DatabaseLayout db;
	private String sCostDirectory;
	private String mfccExt = ".mfcc";
	protected int percent = 0;

	protected void setupHelp() {
		props2Help = new TreeMap();
		props2Help.put(SOXCOMMAND, "Sox binary file absolute path.  ex: /usr/bin/sox ");
		props2Help.put(SPTKINST, "SPTK installation directory. ex: /home/user/sw/SPTK-3.1/");
		props2Help.put(INWAVDIR, "Input wave directory");
		props2Help.put(OUTMFCCDIR, "Output MFCC directory");
	}

	public SortedMap getDefaultProps(DatabaseLayout db) {
		this.db = db;
		if (props == null) {
			props = new TreeMap();
			props.put(SOXCOMMAND, "/usr/bin/sox");
			props.put(SPTKINST, "/home/user/sw/SPTK-3.1/");
			props.put(INWAVDIR, db.getProp(db.ROOTDIR) + File.separator + db.getProp(db.WAVDIR));
			props.put(OUTMFCCDIR, db.getProp(db.ROOTDIR) + File.separator + "sCost" + File.separator + "wavemfcc");
		}
		return props;
	}

	public final String getName() {
		return "SPTKMFCCExtractor";
	}

	@Override
	protected void initialiseComp() {
		// sCost dir creation, if doesn't exists
		sCostDirectory = db.getProp(db.ROOTDIR) + File.separator + "sCost";
		File sCostDir = new File(sCostDirectory);
		if (!sCostDir.exists()) {
			System.out.print(sCostDir.getAbsolutePath() + " does not exist; ");
			if (!sCostDir.mkdir()) {
				throw new Error("Could not create " + sCostDir.getAbsolutePath());
			}
			System.out.print("Created successfully.\n");
		}
	}

	public boolean compute() throws Exception {

		// check for SOX
		File soxFile = new File(getProp(SOXCOMMAND));
		if (!soxFile.exists()) {
			throw new IOException("SOX command setting is wrong. Because file " + soxFile.getAbsolutePath() + " does not exist");
		}

		// check for SPTK
		File sptkFile = new File(getProp(SPTKINST) + File.separator + "bin" + File.separator + "mcep");
		if (!sptkFile.exists()) {
			throw new IOException("SPTK path setting is wrong. Because file " + sptkFile.getAbsolutePath() + " does not exist");
		}

		// output mfcc dir creator
		File waveMFCCDir = new File(getProp(OUTMFCCDIR));
		if (!waveMFCCDir.exists()) {
			System.out.print(waveMFCCDir.getAbsolutePath() + " does not exist; ");
			if (!waveMFCCDir.mkdir()) {
				throw new Error("Could not create " + waveMFCCDir.getAbsolutePath());
			}
			System.out.print("Created successfully.\n");
		}

		// Now process all files, one by one
		for (int i = 0; i < bnl.getLength(); i++) {
			percent = 100 * i / bnl.getLength();
			String baseName = bnl.getName(i);
			String inFile = getProp(INWAVDIR) + File.separator + baseName + db.getProp(db.WAVEXT);
			String outFile = getProp(OUTMFCCDIR) + File.separator + baseName + mfccExt;
			getSptkMfcc(inFile, outFile);
		}

		return true;
	}

	public int getProgress() {
		return percent;
	}

	/***
	 * Calculate mfcc using SPTK, uses sox to convert wav→raw
	 * 
	 * @param inFile
	 *            inFile
	 * @param outFile
	 *            outFile
	 * @throws IOException
	 *             IOException
	 * @throws InterruptedException
	 *             InterruptedException
	 * @throws Exception
	 *             Exception
	 */
	public void getSptkMfcc(String inFile, String outFile) throws IOException, InterruptedException, Exception {

		String tmpFile = db.getProp(db.TEMPDIR) + File.separator + "tmp.mfc";
		String tmpRawFile = db.getProp(db.TEMPDIR) + File.separator + "tmp.raw";
		String cmd;

		// SPTK parameters
		int fs = 16000;
		int frameLength = 400;
		int frameLengthOutput = 512;
		int framePeriod = 80;
		int mgcOrder = 24;
		int mgcDimension = 25;
		// Mary header parameters
		double ws = (frameLength / fs); // window size in seconds
		double ss = (framePeriod / fs); // skip size in seconds

		// SOX and SPTK commands
		String sox = getProp(SOXCOMMAND);
		String x2x = " " + getProp(SPTKINST) + File.separator + "/bin/x2x";
		String frame = " " + getProp(SPTKINST) + File.separator + "/bin/frame";
		String window = " " + getProp(SPTKINST) + File.separator + "/bin/window";
		String mcep = " " + getProp(SPTKINST) + File.separator + "/bin/mcep";
		String swab = " " + getProp(SPTKINST) + File.separator + "/bin/swab";

		// convert the wav file to raw file with sox
		cmd = sox + " " + inFile + " " + tmpRawFile;
		General.launchProc(cmd, "sox", inFile);

		System.out.println("Extracting MGC coefficients from " + inFile);

		cmd = x2x + " +sf " + tmpRawFile + " | " + frame + " +f -l " + frameLength + " -p " + framePeriod + " | " + window
				+ " -l " + frameLength + " -L " + frameLengthOutput + " -w 1 -n 1 | " + mcep + " -a 0.42 -m " + mgcOrder
				+ "  -l " + frameLengthOutput + " | " + swab + " +f > " + tmpFile;

		System.out.println("cmd=" + cmd);
		General.launchBatchProc(cmd, "getSptkMfcc", inFile);

		// Now get the data and add the Mary header
		int numFrames;
		DataInputStream mfcData = null;
		Vector mfc = new Vector();

		mfcData = new DataInputStream(new BufferedInputStream(new FileInputStream(tmpFile)));
		try {
			while (true) {
				mfc.add(mfcData.readFloat());
			}
		} catch (EOFException e) {
		}
		mfcData.close();

		numFrames = mfc.size();
		int numVectors = numFrames / mgcDimension;
		Mfccs mgc = new Mfccs(numVectors, mgcDimension);

		int k = 0;
		for (int i = 0; i < numVectors; i++) {
			for (int j = 0; j < mgcDimension; j++) {
				mgc.mfccs[i][j] = mfc.get(k);
				k++;
			}
		}
		// Mary header parameters
		mgc.params.samplingRate = fs; /* samplingRateInHz */
		mgc.params.skipsize = (float) ss; /* skipSizeInSeconds */
		mgc.params.winsize = (float) ws; /* windowSizeInSeconds */

		mgc.writeMfccFile(outFile);

		// remove temp files
		// 1. tempmfcc file
		File tempFile = new File(tmpFile);
		if (tempFile.exists()) {
			tempFile.delete();
		}
		// 2. temp raw file
		tempFile = new File(tmpRawFile);
		if (tempFile.exists()) {
			tempFile.delete();
		}
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy