Last active
September 18, 2017 07:55
-
-
Save zhangyangjing/3e842dd77c86064a4c6a5da5f999e4d8 to your computer and use it in GitHub Desktop.
save pcm to wav format
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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