📄 wavheader.java
字号:
/* * File: WAVHeader.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 *//* * $Id: WAVHeader.java,v 1.5 2007/04/05 15:29:37 klasal Exp $ */package mpi.eudico.client.util;import java.io.FileNotFoundException;import java.io.IOException;import java.io.RandomAccessFile;import java.util.ArrayList;import java.util.HashMap;import java.util.Iterator;/** * Reads the Header of a wav-file. If used standalone, it takes the name of the * wav-file as first argument. * * @author Alexander Klassmann * @version april 2003 */public class WAVHeader { /** Holds value of property DOCUMENT ME! */ public static final short WAVE_FORMAT_UNCOMPRESSED = 0; /** Holds value of property DOCUMENT ME! */ public static final short WAVE_FORMAT_PCM = 1; /** Holds value of property DOCUMENT ME! */ public static final short WAVE_FORMAT_IEEE_FLOAT = 3; /** Holds value of property DOCUMENT ME! */ public static final short WAVE_FORMAT_ALAW = 6; /** Holds value of property DOCUMENT ME! */ public static final short WAVE_FORMAT_MULAW = 7; /** Holds value of property DOCUMENT ME! */ public static final String[] formatDescriptions = { "Unknown", "PCM (uncompressed)", "MS ADPCM", "IEEE float", "", "IBM CVSD", "8-bit ITU-T G.711 A-law", "8-bit ITU-T G.711 \u00B5-law" }; private HashMap infos = new HashMap(); private WAVCuePoint[] cuePoints = new WAVCuePoint[0]; private WAVCueSection[] cueSections = new WAVCueSection[0]; private char[] dID = new char[4]; private char[] fID = new char[4]; private short[] formatSpecific; private char[] riff = new char[4]; private char[] wID = new char[4]; private int dLen; private int fLen; private int headerSize; private int nAvgBytesPerSec; private int nSamplesPerSec; private int rLen; private long fileSize; private short nBlockAlign; private short nChannels; private short wFormatTag; /** * Creates a new WAVHeader object. * * @param fileName Location of the wav file. */ public WAVHeader(String fileName) { try { read(new RandomAccessFile(fileName, "r")); } catch (FileNotFoundException fne) { System.out.println("File " + fileName + " not found."); return; } } /** * Creates a new WAVHeader object. * * @param soundFile The wav file. */ public WAVHeader(RandomAccessFile soundFile) { read(soundFile); } /** * Returns the compression code, one of the following: * * <ul> * <li> * 0 - Unknown * </li> * <li> * 1 - PCM/uncompressed * </li> * <li> * 2 - Microsoft ADPCM * </li> * <li> * 6 - ITU G.711 a-law * </li> * <li> * 7 - ITU G.711 mu-law * </li> * <li> * 17 - IMA ADPCM * </li> * <li> * 20 - ITU G.723 ADPCM * </li> * <li> * 49 - GSM 6.10 * </li> * <li> * 64 - ITU G.721 ADPCM * </li> * <li> * 80 - MPEG * </li> * </ul> * * * @return The compression code. */ public short getCompressionCode() { return wFormatTag; } /** * returns cue points which may be present in the tail of the file * * @return WAVCuePoint[] */ public WAVCuePoint[] getCuePoints() { return cuePoints; } /** * returns cue section which may be present in the tail of the file * * @return WAVCueSection[] */ public WAVCueSection[] getCueSections() { return cueSections; } /** * Returns the size of the data (in bytes) * * @return int */ public int getDataLength() { return dLen; } /** * DOCUMENT ME! * * @return DOCUMENT ME! */ public long getFileSize() { return fileSize; } /** * Returns the sample frequency (e.g. 44100 for CD) * * @return int */ public int getFrequency() { return nSamplesPerSec; } /** * Returns the size of the header (in bytes) * * @return int */ public int getHeaderSize() { return headerSize; } /** * returns summary of info in wav trail * * @return String */ public String getInfo() { StringBuffer info = new StringBuffer(); for (Iterator iter = infos.keySet().iterator(); iter.hasNext();) { Object key = iter.next(); info.append("\n" + key + " : " + infos.get(key)); } return info.toString(); } /** * Returns the number of channels (1 = mono; 2 = stereo) * * @return short */ public short getNumberOfChannels() { return nChannels; } /** * Returns the size (in bytes) of a single sample * * @return short */ public short getSampleSize() { return nBlockAlign; } /** * For standalone use. First parameter has to be the filename of the * wav-file * * @param args */ public static void main(String[] args) { try { if (args.length > 0) { WAVHeader wavHeader = new WAVHeader(args[0]); System.out.println(wavHeader); } } catch (Exception e) { e.printStackTrace(); } } /** * Reads the header of the specified wav-file and sets the attributes of * this WAVHeader instance. * * @param soundFile DOCUMENT ME! */ public void read(RandomAccessFile soundFile) { try { fileSize = soundFile.length(); byte[] b; //read first 12 bytes (3 groups of 4 bytes: RIFF identifier, size, RIFF type ("WAVE")) b = new byte[12]; soundFile.read(b); for (int i = 0; i < 4; i++) { riff[i] = (char) b[i]; } rLen = getInt(b[4], b[5], b[6], b[7]); for (int i = 0; i < 4; i++) { wID[i] = (char) b[8 + i]; } headerSize = 12; //read header chunks until reaching "data" identifier String chunkID; int chunkDataSize; while (true) { //read chunk header consisting of identifier (4 bytes) and specification of chunk data length (4 bytes) b = new byte[8]; soundFile.read(b); headerSize += 8; chunkID = getString(b, 4); chunkDataSize = getInt(b[4], b[5], b[6], b[7]); if ("data".equalsIgnoreCase(chunkID)) { //end of header reached, so break from loop dID = chunkID.toCharArray(); dLen = chunkDataSize; break; } //read contents of chunk b = new byte[chunkDataSize]; soundFile.read(b); if ("fmt ".equals(chunkID)) { fID = chunkID.toCharArray(); fLen = chunkDataSize; //assign instance attributes //1. parse common fmt bytes wFormatTag = getShort(b[0], b[1]); nChannels = getShort(b[2], b[3]); nSamplesPerSec = getInt(b[4], b[5], b[6], b[7]); nAvgBytesPerSec = getInt(b[8], b[9], b[10], b[11]); nBlockAlign = getShort(b[12], b[13]); //2. parse format-specific bytes int fslength = fLen - 14; formatSpecific = new short[fslength / 2]; for (int i = 0; i < fslength; i += 2) { formatSpecific[i / 2] = getShort(b[14 + i], b[15 + i]); } } else { System.out.println(chunkID + " header found - ignoring contents..."); } headerSize += chunkDataSize; } if (fileSize > (28 + fLen + dLen)) { readCues(soundFile); } } catch (IOException ioe) { System.out.println(ioe.getMessage()); } } /** * Returns the whole header information in table form * * @see java.lang.Object#toString() */ public String toString() { StringBuffer output = new StringBuffer("File size: " + fileSize + " Bytes"); //NOTE: byte numbers shown in this toString() method are only correct whe just fmt and data header are present!!! try { output.append("\n00-03 Letters : ").append(riff); output.append("\n04-07 Length of rdata chunk : ").append(rLen);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -