DOTLETH V2.0

Currently just for fun

Exporting sound to .wav

You've generated a cool song and now you want to burn it on a CD to impress your friends. The format used for writing a cd is the PCM (Pulse Code Modulation) standard. The PCM format is a special case of .wav .aiff files. Luckily the PCM format is a quite simple format, since it doesn't support any compression.

Writing sound files

I wrote a basic wav writer which is designed specifically for the PCM standard, but it can easily be modified for other sample rates, bit rates and number of channels. there is no reason to use this class as it's doable with classes already in java. Anyway i think it's easier to use my version if writing a bytearray to a file is all you want.

Source code

Here is the source code for writing .wav files that can be played on CD-players. The result file can of course also be encoded to .mp3 or further processed.
/*
Copyright (C) 2005  Claus Leth Gregersen (sound@dotleth.dk)

This library 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 2.1 of the License, or (at your option) any later version.

This library 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, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

package dk.dotleth.sound.utilities;


import java.io.IOException;
import java.io.RandomAccessFile;

/**
 * @author Claus Leth Gregersen
 *
 */
public class WavWriter {
	
	private RandomAccessFile f;
	private long ptr1;
	private int totalLength;
	private long ptr2;
	private int SAMPLE_RATE = 44100;
	/*
	 * Data must be interleaved by alternating left and right channel 16 bit (short) values  (both must be big endian)
	 */
	public void writeData(byte[] data, int length) throws IOException {
		f.write(data, 0, length);
		totalLength += length;
	}
	public void close() throws IOException {
		f.seek(ptr1);
		writeInt(f, totalLength +36);
		f.seek(ptr2);
		writeInt(f, totalLength);
		f.close();
	}
	public WavWriter(String fileName) throws IOException {
		byte[] header1 = {'R','I', 'F', 'F'};
		byte[] header2 = {'W', 'A', 'V', 'E', 'f', 'm', 't', ' '};
		byte[] header3 = {'d', 'a', 't', 'a'};
		f = new RandomAccessFile(fileName, "rw");
		
		f.write(header1);
		ptr1 = f.getFilePointer();
		f.writeInt(0); // will be replaced when closed
		f.write(header2); // (WAVEfmt ) 
		
		writeInt(f, 16);	 	// length of chunk
		writeShort(f, 1); 		// Format (1 = uncompressed)
		writeShort(f, 2); 		// Channels  (2 = stereo)
		writeInt(f, SAMPLE_RATE); 	// Samples/second
		writeInt(f, SAMPLE_RATE*2*2); 	// Average Bytes Per Second (sample rate * 2 per channel * 2 channels)
		
		writeShort(f, 2); //blockalign
		writeShort(f, 16); // bitsPerSample
		f.write(header3);
		ptr2 = f.getFilePointer();
		writeInt(f, 0); // will be replaced when closed
	}

	private void writeShort(RandomAccessFile f, int i) throws IOException {
		f.writeByte(i&255);
		i = i >> 8;
		f.writeByte(i&255);
	}

	private void writeInt(RandomAccessFile f, int i) throws IOException {
		f.writeByte(i&255);
		i = i >> 8;
		f.writeByte(i&255);
		i = i >> 8;
		f.writeByte(i&255);
		i = i >> 8;
		f.writeByte(i&255);
		
	}
}

Side Projects


SYNTH: Jukebox



ARCADE: Mega Meteors



ARCADE: Gyros