audiopanel.java
来自「It is the Speech recognition software. 」· Java 代码 · 共 347 行
JAVA
347 行
/* * Copyright 1999-2004 Carnegie Mellon University. * Portions Copyright 2002-2004 Sun Microsystems, Inc. * Portions Copyright 2002-2004 Mitsubishi Electric Research Laboratories. * All Rights Reserved. Use is subject to license terms. * * See the file "license.terms" for information on usage and * redistribution of this file, and for a DISCLAIMER OF ALL * WARRANTIES. * */package edu.cmu.sphinx.tools.audio;import java.awt.Color;import java.awt.Container;import java.awt.Dimension;import java.awt.Graphics;import java.awt.Rectangle;import java.awt.event.MouseEvent;import java.awt.event.MouseListener;import java.awt.event.MouseMotionListener;import javax.swing.JPanel;import javax.swing.JScrollPane;import javax.swing.JViewport;import javax.swing.event.ChangeEvent;import javax.swing.event.ChangeListener;/** * Provides an interface to view and play back various forms * of an audio signal. */public class AudioPanel extends JPanel implements MouseMotionListener, MouseListener { private AudioData audio; private float[] labelTimes; private String[] labels; private float xScale; private float yScale; private float originalXScale; private int xDragStart = 0; private int xDragEnd = 0; protected int selectionStart = -1; protected int selectionEnd = -1; /** * Creates a new AudioPanel. The scale factors represent how * much to scale the audio. A scaleX factor of 1.0f means one pixel * per sample, and a scaleY factor of 1.0f means one pixel per resolution * of the sample (e.g., a scale of 1.0f would take 2**16 pixels). * * @param audioData the AudioData to draw * @param scaleX how much to scale the width of the audio * @param scaleY how much to scale the height */ public AudioPanel(AudioData audioData, float scaleX, float scaleY) { this.audio = audioData; labelTimes = new float[0]; labels = new String[0]; this.xScale = scaleX; this.yScale = scaleY; this.originalXScale = this.xScale; int width = (int) (audio.getAudioData().length * xScale); int height = (int) ((1 << 16) * yScale); setPreferredSize(new Dimension(width, height)); setBackground(Color.white); audio.addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent event) { int width = (int)(audio.getAudioData().length * xScale); int height = (int) ((1 << 16) * yScale); labelTimes = new float[0]; labels = new String[0]; setSelectionStart(-1); setSelectionEnd(-1); setPreferredSize(new Dimension(width, height)); Dimension sz = getSize(); revalidate(); repaint(0, 0, 0, sz.width, sz.height); } }); addMouseMotionListener(this); addMouseListener(this); setFocusable(true); requestFocus(); } /** * Sets the labels to be used when drawing this panel. */ public void setLabels(float[] labelTimes, String[] labels) { this.labelTimes = labelTimes; this.labels = labels; repaint(); } /** * Sets the zoom, adjusting the scroll bar in the process. */ protected void zoomSet(float zoom) { xScale = originalXScale * zoom; int width = (int) (audio.getAudioData().length * xScale); int height = (int) ((1 << 16) * yScale); setPreferredSize(new Dimension(width, height)); revalidate(); repaint(); } /** * Repaints the component with the given Graphics. * * @param g the Graphics to use to repaint the component. */ public void paintComponent(Graphics g) { int pos, index; int length; super.paintComponent(g); Dimension sz = getSize(); int gZero = sz.height / 2; short[] audioData = audio.getAudioData(); /** * Only draw what is in the viewport. */ JViewport viewport = getViewport(); if (viewport != null) { Rectangle r = viewport.getViewRect(); pos = (int) r.getX(); length = (int) r.getWidth(); } else { pos = 0; length = (int) (audioData.length * xScale); } /** * Fill in the whole image with white. */ g.setColor(Color.WHITE); g.fillRect(pos, 0, length, sz.height - 1); /** * Now fill in the audio selection area as gray. */ index = Math.max(0, getSelectionStart()); int start = (int) (index * xScale); index = getSelectionEnd(); if (index == -1) { index = audioData.length - 1; } int end = (int) (index * xScale); g.setColor(Color.LIGHT_GRAY); g.fillRect(start, 0, end - start, sz.height - 1); /* Now scale the audio data and draw it. */ int[] x = new int[length]; int[] y = new int[length]; for (int i = 0; i < length; i++) { x[i] = pos; index = (int) (pos / xScale); if (index < audioData.length) { y[i] = gZero - (int) (audioData[index] * yScale); } else { break; } pos++; } g.setColor(Color.RED); g.drawPolyline(x, y, length); /** * Now draw the labels. */ for (int i = 0; i < labelTimes.length; i++) { pos = (int) (xScale * labelTimes[i] * audio.getAudioFormat().getSampleRate()); g.drawLine(pos, 0, pos, sz.height - 1); g.drawString(labels[i], pos + 5, sz.height - 5); } } /** * Finds the JViewport enclosing this component. */ private JViewport getViewport() { Container p = getParent(); if (p instanceof JViewport) { Container gp = p.getParent(); if (gp instanceof JScrollPane) { JScrollPane scroller = (JScrollPane) gp; JViewport viewport = scroller.getViewport(); if (viewport == null || viewport.getView() != this) { return null; } else { return viewport; } } } return null; } /** * Returns the index of the sample representing the start of the * selection. -1 means the very beginning. * * @return the start of the selection * @see #crop * @see #getSelectionEnd */ public int getSelectionStart() { return selectionStart; } /** * Sets the index of the sample of representing the start of the * selection. -1 means the very beginning. * * @param newStart the new selection start * @see #crop * @see #setSelectionEnd */ public void setSelectionStart(int newStart) { selectionStart = newStart; if (selectionEnd != -1) { if (selectionEnd < selectionStart) { selectionEnd = selectionStart; } } } /** * Returns the index of the sample representing the end of the * selection. -1 means the very end. * * @return the end of the selection * @see #crop * @see #getSelectionStart */ public int getSelectionEnd() { return selectionEnd; } /** * Sets the index of the sample of representing the end of the * selection. -1 means the very end. * * @param newEnd the new selection end * @see #crop * @see #setSelectionStart */ public void setSelectionEnd(int newEnd) { selectionEnd = newEnd; if (selectionEnd != -1) { if (selectionStart > selectionEnd) { selectionStart = selectionEnd; } } } /** * Crops the audio data between the start and end selections. * All audio data outside the region will be permanently lost. * The selection will be reset to the very beginning and very * end of the cropped clip. * * @see #getSelectionStart * @see #getSelectionEnd */ public void crop() { short[] shorts = audio.getAudioData(); int start = Math.max(0, getSelectionStart()); int end = getSelectionEnd(); if (end == -1) { end = shorts.length; } short[] newShorts = new short[end - start]; for (int i = 0; i < (end - start); i++) { newShorts[i] = shorts[i + start]; } audio.setAudioData(newShorts); setSelectionStart(-1); setSelectionEnd(-1); } /** * Clears the current selection. */ public void selectAll() { setSelectionStart(-1); setSelectionEnd(-1); repaint(); } /** * When the mouse is pressed, we update the selection in the * audio. * * @param evt the mouse pressed event */ public void mousePressed(MouseEvent evt) { xDragStart = Math.max(0, evt.getX()); setSelectionStart((int) (xDragStart / xScale)); setSelectionEnd((int) (xDragStart / xScale)); repaint(); } /** * When the mouse is dragged, we update the selection in the * audio. * * @param evt the mouse dragged event */ public void mouseDragged(MouseEvent evt) { xDragEnd = evt.getX(); if (xDragEnd < (int) (getSelectionStart() * xScale)) { setSelectionStart((int) (xDragEnd / xScale)); } else { setSelectionEnd((int) (xDragEnd / xScale)); } repaint(); } public void mouseReleased(MouseEvent evt) {} public void mouseMoved(MouseEvent evt) {} public void mouseEntered(MouseEvent evt) {} public void mouseExited(MouseEvent evt) {} public void mouseClicked(MouseEvent evt) {}}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?