📄 praatconnection.java
字号:
/* * File: PraatConnection.java * Project: MPI Linguistic Application * Date: 02 May 2007 * * Copyright (C) 2001-2007 Max Planck Institute for Psycholinguistics * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */package mpi.eudico.client.annotator.viewer;import mpi.eudico.client.annotator.Constants;import mpi.eudico.client.annotator.ElanLocale;import mpi.util.LogUtil;import java.io.BufferedInputStream;import java.io.BufferedReader;import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.FileWriter;import java.io.IOException;import java.io.InputStreamReader;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;import java.net.URL;import java.util.Hashtable;import java.util.logging.Logger;import javax.swing.JFileChooser;import javax.swing.JFrame;import javax.swing.JOptionPane;/** * A class to start the Praat executable and open the .wav file that has been * loaded into Elan.<br> * Opening a file and (possibly) selecting a part from that file is a two step * process. First we have to make sure that Praat is/has been started, next we * have to use the sendpraat executable to let Praat execute a script with the * right arguments. At least on Windows it is not possible to start Praat * with the script etc. as arguments. The Windows praatcon.exe Praat console * executable can start Praat with a script etc., but it can not load a 'long * sound' and create a view and editor for it.<br> * Since elan only loads sound files that are on a local file system it is * save to expect that a provided url is on the local file system. * * @author Han Sloetjes * @version jul 2004 */public class PraatConnection { /** constant for the name of the praat sript */ private static final String PRAAT_SCRIPT = "openpraat.praat"; /** constant for a script to create a clip from a sound file */ public static final String PRAAT_CLIP_SCRIPT = "createsoundclip.praat"; private static String scriptFileName; /** constant for the Praat application path property */ private static final String PRAAT_APP = "Praat app"; /** constant for the sendpraat application path property */ private static final String SENDPRAAT_APP = "Sendpraat app"; /** Holds value of property DOCUMENT ME! */ private static final String PRAAT_PREFS_FILE = Constants.ELAN_DATA_DIR + Constants.FILESEPARATOR + "praat.pfs"; /** * a non-thread-safe way of temporarily storing the result of a check on * the running state of Praat (Unix systems) */ static boolean isPraatRunning = false; /** the logger */ private static final Logger LOG = Logger.getLogger(PraatConnection.class.getName()); private static Hashtable preferences; /** * Creates a new PraatConnection instance */ private PraatConnection() { } /** * Asynchronously opens a file in Praat. * * @param fileName the media file * @param begintime the selection begintime * @param endtime the selection end time */ public static void openInPraat(final String fileName, final long begintime, final long endtime) { new Thread() { public void run() { if (!checkScript()) { JOptionPane.showMessageDialog(new JFrame(), ElanLocale.getString( "PraatConnection.Message.NoScript"), ElanLocale.getString("Message.Warning"), JOptionPane.WARNING_MESSAGE); LOG.warning("Praat script could not be created"); return; } if (System.getProperty("os.name").toLowerCase().indexOf("windows") > -1) { openWindowsPraat(fileName, begintime, endtime); } else { openOtherPraat(fileName, begintime, endtime); } } }.start(); } /** * Asynchronously creates clip from a file with Praat and opens the new file as a Sound object. * * @param fileName the media file * @param begintime the selection begintime * @param endtime the selection end time */ public static void clipWithPraat(final String fileName, final long begintime, final long endtime) { new Thread() { public void run() { if (!checkClipScript()) { JOptionPane.showMessageDialog(new JFrame(), ElanLocale.getString( "PraatConnection.Message.NoScript"), ElanLocale.getString("Message.Warning"), JOptionPane.WARNING_MESSAGE); LOG.warning("Praat script could not be created"); return; } if (System.getProperty("os.name").toLowerCase().indexOf("windows") > -1) { openWindowsPraat(fileName, begintime, endtime); } else { openOtherPraat(fileName, begintime, endtime); } } }.start(); } /** * For windows flavors some processing of path names should be done etc. * * @param fileName the media file * @param begintime the begintime of the selection * @param endtime the end time of the selection */ private static void openWindowsPraat(String fileName, long begintime, long endtime) { if (fileName != null) { // Praat can handle files on samba shares too if (fileName.startsWith("///")) { fileName = fileName.substring(3); } fileName = fileName.replace('/', '\\'); // sendpraat has problems with filepaths containing spaces // single or double quotes don't seem to help // if the file name itself contains spaces there seems to be no solution if (fileName.indexOf(' ') > 0) { fileName = spacelessWindowsPath(fileName); } //System.out.println("file: " + fileName); } else { LOG.warning("Praat: media file is null"); return; } // first make sure praat is running String praatExe = getPreference(PRAAT_APP); if ((praatExe == null) || (praatExe.length() == 0)) { praatExe = "Praat.exe"; } String[] praatCom = new String[] { praatExe }; try { Runtime.getRuntime().exec(praatCom); // give praat a moment to start try { Thread.sleep(2000); } catch (InterruptedException ie) { LOG.info(LogUtil.formatStackTrace(ie)); } // } catch (SecurityException se) { JOptionPane.showMessageDialog(new JFrame(), ElanLocale.getString("PraatConnection.Message.Security"), ElanLocale.getString("Message.Warning"), JOptionPane.WARNING_MESSAGE); LOG.warning(LogUtil.formatStackTrace(se)); return; } catch (IOException ioe) { LOG.warning(LogUtil.formatStackTrace(ioe)); // not found, prompt String path = locatePraat(); if (path == null) { return; } else { // retry openWindowsPraat(fileName, begintime, endtime); return; } } // next execute sendpraat // (on windows we cannot use praatcon.exe for this task) String sendpraatExe = getPreference(SENDPRAAT_APP); if ((sendpraatExe == null) || (sendpraatExe.length() == 0)) { sendpraatExe = "sendpraat.exe"; } String executeCom = "execute " + scriptFileName + " " + fileName + " " + String.valueOf(begintime) + " " + String.valueOf(endtime); String[] sendpraatCom = new String[3]; sendpraatCom[0] = sendpraatExe; sendpraatCom[1] = "Praat"; sendpraatCom[2] = executeCom; try { Runtime.getRuntime().exec(sendpraatCom); } catch (SecurityException se) { JOptionPane.showMessageDialog(new JFrame(), ElanLocale.getString("PraatConnection.Message.Security"), ElanLocale.getString("Message.Warning"), JOptionPane.WARNING_MESSAGE); LOG.warning(LogUtil.formatStackTrace(se)); return; } catch (IOException ioe) { LOG.warning(LogUtil.formatStackTrace(ioe)); // not found, prompt String path = locateSendpraat(); if (path == null) { return; } else { // retry openWindowsPraat(fileName, begintime, endtime); } } } /** * Open Praat on non-windows systems; MacOS X, Unix, Linux. <br> * Note: on Mac OS X every call to runtime.exec to start Praat opens a new * instance of Praat: it is not detected that it is already open (this is * a result of the fact that you can not use the Praat.app "folder" to * start Praat). Maybe we should not try to start Praat but let the user * be responsible to start Praat. * * @param fileName the media file * @param begintime the begintime of the selection * @param endtime the end time of the selection */ private static void openOtherPraat(String fileName, long begintime, long endtime) { if (fileName != null) { // Praat can handle files on samba shares too // on Mac: when the url starts with 3 slashes, remove 2 slashes // TO DO: this needs testing on other platforms if (fileName.startsWith("///")) { fileName = fileName.substring(2); } } else { LOG.warning("Praat: media file is null"); return; } // first make sure praat is running String praatExe = getPreference(PRAAT_APP); if ((praatExe == null) || (praatExe.length() == 0)) { praatExe = "praat"; } // check whether praat is running already; this is not a thread safe way to check isPraatRunning = false; checkUnixPraatProcess(); try { Thread.sleep(700); } catch (InterruptedException ie) { } if (!isPraatRunning) { String[] praatCom = new String[] { praatExe }; try { Runtime.getRuntime().exec(praatCom); // give praat a moment to start try { Thread.sleep(1500); } catch (InterruptedException ie) { LOG.info(LogUtil.formatStackTrace(ie)); } } catch (SecurityException se) { JOptionPane.showMessageDialog(new JFrame(), ElanLocale.getString("PraatConnection.Message.Security"), ElanLocale.getString("Message.Warning"), JOptionPane.WARNING_MESSAGE); LOG.warning(LogUtil.formatStackTrace(se)); return; } catch (IOException ioe) { LOG.warning(LogUtil.formatStackTrace(ioe)); // not found, prompt String path = locatePraat(); if (path == null) { return; } else { // retry openOtherPraat(fileName, begintime, endtime); return; } } } // next execute sendpraat String sendpraatExe = getPreference(SENDPRAAT_APP); if ((sendpraatExe == null) || (sendpraatExe.length() == 0)) { sendpraatExe = "sendpraat"; } // test this om other platforms... String executeCom = "execute " + scriptFileName + " " + fileName + " " + String.valueOf(begintime) + " " + String.valueOf(endtime); String[] sendpraatCom = new String[3]; sendpraatCom[0] = sendpraatExe; sendpraatCom[1] = "praat"; sendpraatCom[2] = executeCom; try { Runtime.getRuntime().exec(sendpraatCom); } catch (SecurityException se) { JOptionPane.showMessageDialog(new JFrame(), ElanLocale.getString("PraatConnection.Message.Security"), ElanLocale.getString("Message.Warning"), JOptionPane.WARNING_MESSAGE); LOG.warning(LogUtil.formatStackTrace(se)); return; } catch (IOException ioe) { LOG.warning(LogUtil.formatStackTrace(ioe)); // not found, prompt String path = locateSendpraat(); if (path == null) { return; } else { // retry openOtherPraat(fileName, begintime, endtime); } } } /** * Checks whether or not the praatscript file already exists. When not it * is created in the elan directory in the user's home directory. * * @return true if the file already existed or could be created, false * otherwise */ private static boolean checkScript() { if (!checkHome()) { return false; } scriptFileName = Constants.ELAN_DATA_DIR + Constants.FILESEPARATOR + PRAAT_SCRIPT; if (System.getProperty("os.name").toLowerCase().indexOf("windows") > -1) { // Praat on Windows does not like spaces in the path if (scriptFileName.indexOf(' ') > -1) { String dir = System.getProperty("java.io.tmpdir"); if (dir != null) { scriptFileName = dir + Constants.FILESEPARATOR + PRAAT_SCRIPT; } // or // scriptFileName = spacelessWindowsPath(scriptFileName); } } File file = new File(scriptFileName); if (file.exists()) { return true; } else { // first try to copy the file from the .jar if (copyScriptFromJar(file, "/mpi/eudico/client/annotator/resources/openpraat.praat")) { return true; } else { // fallback: create the file programmatically return createScriptFile(file); } } } /** * Checks whether or not the praat clip script file already exists. When not it * is created in the elan directory in the user's home directory. * * @return true if the file already existed or could be created, false * otherwise */ private static boolean checkClipScript() { if (!checkHome()) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -