Skip to content

Instantly share code, notes, and snippets.

@zhangyangjing
Last active September 18, 2017 07:55
Show Gist options
  • Save zhangyangjing/3e842dd77c86064a4c6a5da5f999e4d8 to your computer and use it in GitHub Desktop.
Save zhangyangjing/3e842dd77c86064a4c6a5da5f999e4d8 to your computer and use it in GitHub Desktop.
save pcm to wav format
public class WaveHelper {
private File mFile;
private int mSample;
private int mChannel;
private int mSampleBits;
private LittleEndianDataOutputStream mDos;
public WaveHelper(File file, int channel, int sample, int encoding) {
mFile = file;
mSample = sample;
mChannel = getChannel(channel);
mSampleBits = getSampleBits(encoding);
}
public void write(short[] data) throws IOException {
if (null == mDos) {
mDos = new LittleEndianDataOutputStream(new BufferedOutputStream(new FileOutputStream(mFile)));
writeHeader();
}
for (short d : data)
mDos.writeShort(d);
}
public void finish() throws IOException {
mDos.close();
RandomAccessFile f = new RandomAccessFile(mFile, "rw");
f.seek(4);
f.write(be2le((int) (mFile.length() - 8)));
f.seek(40);
f.write(be2le((int) (mFile.length() - 44)));
f.close();
}
private int getChannel(int channel) {
switch (channel) {
case AudioFormat.CHANNEL_OUT_STEREO:
return 2;
case AudioFormat.CHANNEL_OUT_MONO:
default:
return 1;
}
}
private int getSampleBits(int encoding) {
switch (encoding) {
case AudioFormat.ENCODING_PCM_8BIT:
return 8;
case AudioFormat.ENCODING_PCM_16BIT:
return 16;
case AudioFormat.ENCODING_PCM_FLOAT:
default:
return 32;
}
}
/**
* see also: http://www.topherlee.com/software/pcm-tut-wavformat.html
*/
private void writeHeader() throws IOException {
mDos.writeBytes("RIFF");
mDos.writeInt(0x0000);
mDos.writeBytes("WAVE");
mDos.writeBytes("fmt ");
mDos.writeInt(16);
mDos.writeShort(1);
mDos.writeShort(mChannel);
mDos.writeInt(mSample);
mDos.writeInt(mSample* mChannel * mSampleBits / 8);
mDos.writeShort(mSampleBits * mChannel / 8);
mDos.writeShort(mSampleBits);
mDos.writeBytes("data");
mDos.writeInt(0x0000);
}
/**
* big endian to little endian
*/
private byte[] be2le(int value) {
byte[] result = new byte[4];
result[3] = (byte)(value >> 24);
result[2] = (byte)((value << 8) >> 24);
result[1] = (byte)((value << 16) >> 24);
result[0] = (byte)((value << 24) >> 24);
return result;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment