package com.sin.java.waveaccess; import java.io.BufferedOutputStream; import java.io.FileOutputStream; import java.io.IOException; public class WaveFileWriter { private String filename = null; private FileOutputStream fos = null; private BufferedOutputStream bos = null; private long chunksize = 0; private long subchunk1size = 0; private int audioformat = 0; private int numchannels = 0; private long samplerate = 0; private long byterate = 0; private int blockalign = 0; private int bitspersample = 0; private long subchunk2size = 0; public WaveFileWriter(String filename, int[][] data, long samplerate) { this.initWriter(filename, data, 0, data[0].length, samplerate); } public WaveFileWriter(String filename, int[][] data, int offset, int len, long samplerate) { this.initWriter(filename, data, offset, len, samplerate); } public void initWriter(String filename, int[][] data, int offset, int len, long samplerate) { this.filename = filename; try { fos = new FileOutputStream(this.filename); bos = new BufferedOutputStream(fos); // int datalen = data[0].length; int datalen = len; this.samplerate = samplerate; // this.bitspersample = bitspersample; this.bitspersample = 16; this.numchannels = data.length; this.subchunk2size = this.numchannels * (this.bitspersample / 8) * datalen; this.subchunk1size = 16; this.audioformat = 1; // PCM this.byterate = this.samplerate * this.bitspersample * this.numchannels / 8; this.blockalign = this.numchannels * this.bitspersample / 8; this.chunksize = this.subchunk2size + 8 + this.subchunk1size + 8 + 4; writeString(WaveConstants.CHUNKDESCRIPTOR, WaveConstants.LENCHUNKDESCRIPTOR); writeLong(this.chunksize); writeString(WaveConstants.WAVEFLAG, WaveConstants.LENWAVEFLAG); writeString(WaveConstants.FMTSUBCHUNK, WaveConstants.LENFMTSUBCHUNK); writeLong(this.subchunk1size); writeInt(this.audioformat); writeInt(this.numchannels); writeLong(this.samplerate); writeLong(this.byterate); writeInt(this.blockalign); writeInt(this.bitspersample); writeString(WaveConstants.DATASUBCHUNK, WaveConstants.LENDATASUBCHUNK); writeLong(this.subchunk2size); for (int i = 0; i < datalen; ++i) { for (int n = 0; n < this.numchannels; ++n) { if (this.bitspersample == 16) { writeInt(data[n][i + offset]); } else { writeByte((byte) data[n][i + offset]); } } } bos.flush(); fos.flush(); bos.close(); fos.close(); } catch (Exception e) { e.printStackTrace(); } } public void close() { } private void writeString(String str, int len) { if (str.length() != len) { throw new IllegalArgumentException("length not match!!!"); } byte[] bt = str.getBytes(); try { bos.write(bt); } catch (IOException e) { e.printStackTrace(); } } private void writeByte(byte data) { try { bos.write(new byte[] { data }, 0, 1); } catch (IOException e) { e.printStackTrace(); } } private void writeInt(int data) { byte[] buf = new byte[2]; buf[1] = (byte) (data >>> 8); buf[0] = (byte) (data & 0xFF); try { bos.write(buf); } catch (IOException e) { e.printStackTrace(); } } private void writeLong(long data) { byte[] buf = new byte[4]; buf[0] = (byte) (data & 0x00ff); buf[1] = (byte) ((data >> 8) & 0x00ff); buf[2] = (byte) ((data >> 16) & 0x00ff); buf[3] = (byte) ((data >> 24) & 0x00ff); try { bos.write(buf); } catch (IOException e) { e.printStackTrace(); } } public static boolean saveSingleChannel(String filename, int[] data, long samplerate) { int[][] datar = new int[1][]; datar[0] = data; WaveFileWriter writer = new WaveFileWriter(filename, datar, samplerate); writer.close(); return true; } }