📄 audiotool.java
字号:
/* * 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.BorderLayout;import java.awt.FlowLayout;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.io.BufferedReader;import java.io.File;import java.io.FileInputStream;import java.io.IOException;import java.io.InputStreamReader;import java.net.URL;import java.util.StringTokenizer;import java.util.prefs.Preferences;import javax.sound.sampled.AudioFormat;import javax.sound.sampled.AudioSystem;import javax.sound.sampled.DataLine;import javax.sound.sampled.Line;import javax.sound.sampled.Mixer;import javax.sound.sampled.Clip;import javax.sound.sampled.Port;import javax.sound.sampled.SourceDataLine;import javax.sound.sampled.TargetDataLine;import javax.swing.Action;import javax.swing.JButton;import javax.swing.JFileChooser;import javax.swing.JFrame;import javax.swing.JMenu;import javax.swing.JMenuBar;import javax.swing.JMenuItem;import javax.swing.JPanel;import javax.swing.JScrollPane;import javax.swing.KeyStroke;import edu.cmu.sphinx.frontend.Data;import edu.cmu.sphinx.frontend.DoubleData;import edu.cmu.sphinx.frontend.FrontEnd;import edu.cmu.sphinx.frontend.util.Microphone;import edu.cmu.sphinx.frontend.util.StreamDataSource;import edu.cmu.sphinx.frontend.window.RaisedCosineWindower;import edu.cmu.sphinx.tools.audio.AudioData;import edu.cmu.sphinx.tools.audio.AudioPanel;import edu.cmu.sphinx.tools.audio.AudioPlayer;import edu.cmu.sphinx.tools.audio.SpectrogramPanel;import edu.cmu.sphinx.tools.audio.Utils;import edu.cmu.sphinx.util.props.ConfigurationManager;import edu.cmu.sphinx.util.props.PropertySheet;/** * Records and displays the waveform and spectrogram of an audio * signal. See * <a href="doc-files/HowToRunAudioTool.html">How to Run AudioTool</a> * for information on how to run AudioTool. */public class AudioTool { static final String CONTEXT = "AudioTool"; static final String PREFS_CONTEXT = "/edu/cmu/sphinx/tools/audio/" + CONTEXT; static final String FILENAME_PREFERENCE = "filename"; // ------------------------------- // Component names // ----------------------------------- // These names should match the correspondong names in the // spectrogram.config.xml static final String MICROPHONE = "microphone"; static final String FRONT_END = "frontEnd"; static final String DATA_SOURCE = "streamDataSource"; static final String WINDOWER = "windower"; static AudioData audio; static JFrame jframe; static AudioPanel audioPanel; static SpectrogramPanel spectrogramPanel; static JFileChooser fileChooser; static String filename; static File file = null; static AudioPlayer player; static Microphone recorder; static boolean recording = false; static Preferences prefs; static float zoom = 1.0f; private static JMenuItem saveMenuItem; private static JButton playButton; private static JButton recordButton; private static JButton zoomInButton; private static JButton zoomOutButton; private static JButton zoomResetButton; private static ActionListener recordListener; /** * Dumps the information about a line. */ private static void dumpLineInfo(String indent, Line.Info[] lineInfo) { int numDumped = 0; if (lineInfo != null) { for (int i = 0; i < lineInfo.length; i++) { if (lineInfo[i] instanceof DataLine.Info) { AudioFormat[] formats = ((DataLine.Info) lineInfo[i]).getFormats(); for (int j = 0; j < formats.length; j++) { System.out.println(indent + formats[j]); } numDumped++; } else if (lineInfo[i] instanceof Port.Info) { System.out.println(indent + lineInfo[i]); numDumped++; } } } if (numDumped == 0) { System.out.println(indent + "none"); } } /** * Lists all the available audio devices. */ private static void dumpMixers() { Mixer.Info[] mixerInfo = AudioSystem.getMixerInfo(); for (int i = 0; i < mixerInfo.length; i++) { Mixer mixer = AudioSystem.getMixer(mixerInfo[i]); System.out.println("Mixer[" + i + "]: \"" + mixerInfo[i].getName() + "\""); System.out.println(" Description: " + mixerInfo[i].getDescription()); System.out.println(" SourceLineInfo (e.g., speakers):"); dumpLineInfo(" ", mixer.getSourceLineInfo()); System.out.println(" TargetLineInfo (e.g., microphones):"); dumpLineInfo(" ", mixer.getTargetLineInfo()); } } /** * Gets a filename. */ static public void getFilename(String title, int type) { int returnVal; fileChooser.setDialogTitle(title); fileChooser.setCurrentDirectory(file); fileChooser.setDialogType(type); if (type == JFileChooser.OPEN_DIALOG) { returnVal = fileChooser.showOpenDialog(jframe); } else { returnVal = fileChooser.showSaveDialog(jframe); } if (returnVal == JFileChooser.APPROVE_OPTION) { file = fileChooser.getSelectedFile(); filename = file.getAbsolutePath(); prefs.put(FILENAME_PREFERENCE, filename); } } /** */ static public void populateAudio(String filename) { try { AudioData newAudio = Utils.readAudioFile(filename); if (newAudio == null) { newAudio = Utils.readRawFile(filename); } zoomReset(); audio.setAudioData(newAudio.getAudioData()); player.play(audioPanel.getSelectionStart(), audioPanel.getSelectionEnd()); } catch (IOException e) { /* just ignore bad files. */ } } /** */ static public void getAudioFromFile(String filename) throws IOException { /* Supports alignment data. The format of the alignment file * is as follows: * * input filename String * number of (time tag) lines int * time tag float String * time tag float String * time tag float String * ... * * Times are in seconds. */ if (filename.endsWith(".align")) { BufferedReader reader = new BufferedReader( new InputStreamReader(new FileInputStream(filename))); populateAudio(reader.readLine()); int numPoints = Integer.parseInt(reader.readLine()); float[] times = new float[numPoints]; String[] labels = new String[numPoints]; for (int i = 0; i < numPoints; i++) { StringTokenizer tokenizer = new StringTokenizer( reader.readLine()); while (tokenizer.hasMoreTokens()) { times[i] = Float.parseFloat(tokenizer.nextToken()); labels[i] = tokenizer.nextToken(); } } audioPanel.setLabels(times, labels); reader.close(); } else { populateAudio(filename); } } /** * Gets the audio that's in the recorder. This should only * be called after recorder.stopRecording is called. */ static private short[] getRecordedAudio(Microphone recorder) { short[] shorts = new short[0]; int sampleRate = 16000; /* [[[WDW - TODO: this is not the most efficient way * to do this, but it at least works for now.]]] */ while (recorder.hasMoreData()) { try { Data data = recorder.getData(); if (data instanceof DoubleData) { sampleRate = ((DoubleData) data).getSampleRate(); double[] values = ((DoubleData) data).getValues(); short[] newShorts = new short[shorts.length + values.length]; for (int i = 0; i < shorts.length; i++) { newShorts[i] = shorts[i]; } for (int i = 0; i < values.length; i++) { newShorts[shorts.length + i] = (short) values[i]; } shorts = newShorts; } } catch (Exception e) { e.printStackTrace(); } } if (sampleRate > 16000) { System.out.println("Downsampling from " + sampleRate + " to 16000."); shorts = Downsampler.downsample( shorts, sampleRate / 1000, 16); } return shorts; } /** * Zoom the panels according to the zoom scale. */ private static void zoomPanels() { if (audioPanel != null) { audioPanel.zoomSet(zoom); } if (spectrogramPanel != null) { spectrogramPanel.zoomSet(zoom); } } /** * Zoom in. */ private static void zoomIn() { zoom *= 2.0f; zoomPanels(); } /** * Zoom out. */ private static void zoomOut() { zoom /= 2.0f; zoomPanels(); } /** * Reset zoom size. */ private static void zoomReset() { zoom = 1.0f; zoomPanels(); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -