📄 signalviewer.java
字号:
/* * File: SignalViewer.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.eudico.client.annotator.gui.FormattedMessageDlg;import mpi.eudico.client.mediacontrol.ControllerEvent;import mpi.eudico.client.mediacontrol.StopEvent;import mpi.eudico.client.mediacontrol.TimeEvent;import mpi.eudico.client.util.WAVCuePoint;import mpi.eudico.client.util.WAVSampler;import mpi.util.TimeFormatter;import java.awt.AlphaComposite;import java.awt.BasicStroke;import java.awt.Color;import java.awt.Cursor;import java.awt.Dimension;import java.awt.Graphics;import java.awt.Graphics2D;import java.awt.Point;import java.awt.Toolkit;import java.awt.Window;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.awt.event.ComponentEvent;import java.awt.event.ComponentListener;import java.awt.event.KeyEvent;import java.awt.event.MouseEvent;import java.awt.event.MouseListener;import java.awt.event.MouseMotionListener;import java.awt.geom.AffineTransform;import java.awt.image.BufferedImage;import java.io.IOException;import java.net.URL;import javax.swing.ButtonGroup;import javax.swing.JCheckBoxMenuItem;import javax.swing.JMenu;import javax.swing.JMenuItem;import javax.swing.JPopupMenu;import javax.swing.JRadioButtonMenuItem;import javax.swing.KeyStroke;import javax.swing.SwingConstants;import javax.swing.SwingUtilities;import javax.swing.UIManager;/** * Draws a waveform of each audiochannel, a crosshair cursor denoting the * current media time and the selection if the user has selected a part of the * media file. */public class SignalViewer extends TimeScaleBasedViewer implements ComponentListener, MouseListener, MouseMotionListener, ActionListener { /** Holds value of property DOCUMENT ME! */ public static final int MONO = 0; /** Holds value of property DOCUMENT ME! */ public static final int STEREO_SEPARATE = 1; /** Holds value of property DOCUMENT ME! */ public static final int STEREO_MERGED = 2; /** Holds value of property DOCUMENT ME! */ public static final int STEREO_BLENDED = 3; /** The default number of pixels for one second of media time. */ static final int PIXELS_FOR_SECOND = 100; private int channelMode; /** An array of zoomlevels. */ public final int[] VERT_ZOOM = new int[] { 100, 150, 200, 300, 500, 1000, 2000, 3000 }; /** Holds value of property DOCUMENT ME! */ private final int GAP = 4; private int rulerHeight; private BufferedImage bi; private Graphics2D big2d; private AlphaComposite alpha04; private AlphaComposite alpha07; private WavePart currentPart; /** Holds value of property DOCUMENT ME! */ private final int SCREEN_BUFFER = 1; private WAVSampler samp; /** The initial number of milliseconds per pixel */ public final int DEFAULT_MS_PER_PIXEL = 10; /** The current number of milliseconds per pixel */ private int msPerPixel; /** * The number of sound samples per pixel. Is msPerPixel * samples per ms, is * msPerPixel * samplefrequency / 1000. */ private int samplesPerPixel; /** * The resolution in number of pixels for a second. This is not a * percentage value. Historically resolution = PIXELS_FOR_SECOND factor, * where factor = 100 / menu_resolution_percentage_value. */ private int resolution; private TimeRuler ruler; private int maxAmplitude; private int imageWidth; private int imageHeight; private long crossHairTime; private int crossHairPos; private long intervalBeginTime; private long intervalEndTime; private long dragStartTime; private long selectionBeginTime; private long selectionEndTime; private int selectionBeginPos; private int selectionEndPos; private Point dragStartPoint; private Point dragEndPoint; /** Holds value of property DOCUMENT ME! */ public final int SCROLL_OFFSET = 16; private DragScroller scroller; private JPopupMenu popup; private JMenuItem praatSelMI; private JMenuItem clipSelPraatMI; private JMenuItem infoItem; private ButtonGroup zoomBG; private boolean timeScaleConnected; private boolean panMode; private int vertZoom = 100; /** Holds value of property DOCUMENT ME! */ private final Object paintlock = new Object(); /** * an offset in milliseconds into the media file where the new media begin * point (0 point) is situated */ private long mediaOffset; /** store the path to the media file */ private String mediaFilePath; //a flag for the scroll thread /** Holds value of property DOCUMENT ME! */ boolean stopScrolling = true; /** Holds value of property DOCUMENT ME! */ boolean allowConnecting = true; private Color selectionColor = Constants.SELECTIONCOLOR; /** * Create a SignalViewer with some default values but without any data to * display. */ public SignalViewer() { initViewer(); addComponentListener(this); addMouseListener(this); addMouseMotionListener(this); setDoubleBuffered(false); setOpaque(true); //setVisible(true); } /** * Constructor used from Corex * * @param mediaURL * @param allowConnecting */ public SignalViewer(URL mediaURL, boolean allowConnecting) { this(mediaURL); this.allowConnecting = allowConnecting; removeMouseMotionListener(this); } /** * Creates a new SignalViewer instance * * @param mediaUrl DOCUMENT ME! */ public SignalViewer(URL mediaUrl) { this(mediaUrl.toExternalForm()); } /** * Creates a new SignalViewer using the specified path as the media source. * * @param mediaPath the path to the media source (WAV file) */ public SignalViewer(String mediaPath) { this(); setMedia(mediaPath); paintBuffer(); System.out.println("MediaUrl: " + mediaPath); } /** * Overrides <code>JComponent</code>'s processKeyBinding by always returning false. * Necessary for the proper working of (menu) shortcuts in Elan. */ protected boolean processKeyBinding(KeyStroke ks, KeyEvent e, int condition, boolean pressed) { return false; } /** * Do some initialisation. */ private void initViewer() { ruler = new TimeRuler(Constants.DEFAULTFONT, TimeFormatter.toString(0)); rulerHeight = ruler.getHeight(); channelMode = STEREO_MERGED; msPerPixel = DEFAULT_MS_PER_PIXEL; samplesPerPixel = (msPerPixel * 44100) / 1000; //default freq resolution = PIXELS_FOR_SECOND; maxAmplitude = Short.MAX_VALUE; imageWidth = 0; imageHeight = 0; crossHairTime = 0; crossHairPos = 0; intervalBeginTime = 0; intervalEndTime = 0; dragStartTime = 0; selectionBeginTime = 0; selectionEndTime = 0; selectionBeginPos = 0; selectionEndPos = 0; alpha04 = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.4f); alpha07 = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.7f); currentPart = new WavePart(WavePart.INT_ARRAY_MODE); //currentPart = new WavePart(WavePart.GENERAL_PATH_MODE); timeScaleConnected = true; mediaOffset = 0L; } /** * Sets the source for this viewer. * * @param mediaPath the URL of the source as a String */ public void setMedia(String mediaPath) { // old test; if the file is video file try to find // a .wav file with the same name if (!mediaPath.endsWith("wav")) { int i = mediaPath.lastIndexOf('.'); if (i > 0) { mediaPath = mediaPath.substring(0, i) + ".wav"; } else { mediaPath = mediaPath + ".wav"; } } if (mediaPath.startsWith("file:")) { mediaPath = mediaPath.substring(5); } else { // check protocol?? } mediaFilePath = mediaPath; initLoad(mediaPath); paintBuffer(); //repaint(); } /** * Tries to start the Praat executable and select the specified interval. * * @see http://www.fon.hum.uva.nl/praat/ * @param begin the selection begin time * @param end the selection end time */ private void openInPraat(long begin, long end) { PraatConnection.openInPraat(mediaFilePath, begin, end); } /** * Tries to start the Praat executable and select the current selection. * * @see http://www.fon.hum.uva.nl/praat/ */ private void openSelectionInPraat() { if (getSelectionBeginTime() == getSelectionEndTime()) { openInPraat(0, 0); } else { openInPraat(getSelectionBeginTime(), getSelectionEndTime()); } } /** * Tries to create a clip from the wav file using Praat. */ private void clipSelectionWithPraat() { if (getSelectionBeginTime() == getSelectionEndTime()) { return; } PraatConnection.clipWithPraat(mediaFilePath, getSelectionBeginTime(), getSelectionEndTime()); } /** * Shows a formatted media info message. */ private void showMediaInfo() { String[][] info = new String[3][2]; info[0][0] = ElanLocale.getString("LinkedFilesDialog.Label.MediaURL"); info[0][1] = mediaFilePath; info[1][0] = ElanLocale.getString("LinkedFilesDialog.Label.MediaOffset"); info[1][1] = String.valueOf(mediaOffset); info[2][0] = ElanLocale.getString("Player.duration"); info[2][1] = TimeFormatter.toString((long) samp.getDuration()); new FormattedMessageDlg(info); } /** * Returns duration calculated from WAV-file (used within Corex) * * @return long */ public long getSignalDuration() { return (long) samp.getDuration(); } /** * DOCUMENT ME! * * @param selectionColor DOCUMENT ME! */ public void setSelectionColor(Color selectionColor) { this.selectionColor = selectionColor; } /** * Initializes a <code>WaveSampler</code> for the given URL. * <code>WaveSampler</code> currently only takes a String for the source * location. * * @param sourcePath the URL of the source file as a String */ private void initLoad(String sourcePath) { try { samp = new WAVSampler(sourcePath); } catch (IOException ioe) { System.out.println("Failed to create a WAVSampler"); } if (samp != null) { samplesPerPixel = (msPerPixel * samp.getSampleFrequency()) / 1000; maxAmplitude = Math.max(samp.getPossibleMaxSample(),
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -