/* * Copyright (C) 2011 in-somnia * * This file is part of JAAD. * * JAAD is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 3 of the * License, or (at your option) any later version. * * JAAD 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 Lesser General * Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. * If not, see <http://www.gnu.org/licenses/>. */ package net.sourceforge.jaad.util.wav; import java.io.File; import java.io.IOException; import java.io.RandomAccessFile; public class WaveFileWriter { private static final int HEADER_LENGTH = 44; private static final int RIFF = 1380533830; //'RIFF' private static final long WAVE_FMT = 6287401410857104416l; //'WAVEfmt ' private static final int DATA = 1684108385; //'data' private static final int BYTE_MASK = 0xFF; private final RandomAccessFile out; private final int sampleRate; private final int channels; private final int bitsPerSample; private int bytesWritten; public WaveFileWriter(File output, int sampleRate, int channels, int bitsPerSample) throws IOException { this.sampleRate = sampleRate; this.channels = channels; this.bitsPerSample = bitsPerSample; bytesWritten = 0; out = new RandomAccessFile(output, "rw"); out.write(new byte[HEADER_LENGTH]); //space for the header } public void write(byte[] data) throws IOException { write(data, 0, data.length); } public void write(byte[] data, int off, int len) throws IOException { //convert to little endian byte tmp; for(int i = off; i<off+data.length; i += 2) { tmp = data[i+1]; data[i+1] = data[i]; data[i] = tmp; } out.write(data, off, len); bytesWritten += data.length; } public void write(short[] data) throws IOException { write(data, 0, data.length); } public void write(short[] data, int off, int len) throws IOException { for(int i = off; i<off+data.length; i++) { out.write(data[i]&BYTE_MASK); out.write((data[i]>>8)&BYTE_MASK); bytesWritten += 2; } } public void close() throws IOException { writeWaveHeader(); out.close(); } private void writeWaveHeader() throws IOException { out.seek(0); final int bytesPerSec = (bitsPerSample+7)/8; out.writeInt(RIFF); //wave label out.writeInt(Integer.reverseBytes(bytesWritten+36)); //length in bytes without header out.writeLong(WAVE_FMT); out.writeInt(Integer.reverseBytes(16)); //length of pcm format declaration area out.writeShort(Short.reverseBytes((short) 1)); //is PCM out.writeShort(Short.reverseBytes((short) channels)); //number of channels out.writeInt(Integer.reverseBytes(sampleRate)); //sample rate out.writeInt(Integer.reverseBytes(sampleRate*channels*bytesPerSec)); //bytes per second out.writeShort(Short.reverseBytes((short) (channels*bytesPerSec))); //bytes per sample time out.writeShort(Short.reverseBytes((short) bitsPerSample)); //bits per sample out.writeInt(DATA); //data section label out.writeInt(Integer.reverseBytes(bytesWritten)); //length of raw pcm data in bytes } }