package cn.org.hentai.jtt1078.codec;
|
|
import cn.org.hentai.jtt1078.codec.g726.*;
|
|
import java.io.FileInputStream;
|
import java.io.FileOutputStream;
|
|
public class G726Codec extends AudioCodec {
|
|
// pcm采样率
|
private static final int PCM_SAMPLE = 8000;
|
|
// pcm采样点
|
private static final int PCM_POINT = 320;
|
|
// 音频通道数
|
private static final int CHANNEL = 1;
|
|
// 码率
|
private static final int G726_BIT_RATE_16000 = 16000;
|
private static final int G726_BIT_RATE_24000 = 24000;
|
private static final int G726_BIT_RATE_32000 = 32000;
|
private static final int G726_BIT_RATE_40000 = 40000;
|
|
|
|
@Override
|
public byte[] toPCM(byte[] data) {
|
int pos = 0;
|
// 如果前四字节是00 01 52 00,则是海思头,需要去掉
|
if (data[0] == 0x00 && data[1] == 0x01 && (data[2] & 0xff) == (data.length - 4) / 2 && data[3] == 0x00) {
|
pos = 4;
|
}
|
|
int length = data.length - pos;
|
|
int point = PCM_POINT;
|
|
// 计算G726的码率
|
int rateBit = length * 8 * PCM_SAMPLE/point;
|
|
G726 g726 = null;
|
|
// 码率
|
if (rateBit == G726_BIT_RATE_40000) {
|
g726 = new G726_40();
|
}
|
else if (rateBit == G726_BIT_RATE_32000) {
|
g726 = new G726_32();
|
}
|
else if (rateBit == G726_BIT_RATE_24000) {
|
g726 = new G726_24();
|
}
|
else if (rateBit == G726_BIT_RATE_16000) {
|
g726 = new G726_16();
|
}
|
else {
|
return null;
|
}
|
|
int pcmSize = point * CHANNEL * 2;
|
byte[] pcm = new byte[pcmSize];
|
|
int ret = g726.decode(data,pos,length,G726.AUDIO_ENCODING_LINEAR,pcm,0);
|
if (ret < 0) {
|
return null;
|
}
|
return pcm;
|
}
|
|
@Override
|
public byte[] fromPCM(byte[] data) {
|
// TODO:
|
return new byte[0];
|
}
|
|
private static void readWrite(String in,String out,int size) throws Exception {
|
FileInputStream f = new FileInputStream(in);
|
FileOutputStream o = new FileOutputStream(out);
|
int len = -1;
|
byte[] buff = new byte[size];
|
G726Codec g726Codec = new G726Codec();
|
int index = 0;
|
while ((len = f.read(buff,index,buff.length)) > -1) {
|
o.write(g726Codec.toPCM(buff));
|
}
|
}
|
|
// mac下在终端中输入 /Applications/VLC.app/Contents/MacOS/VLC --demux=rawaud --rawaud-channels 1 --rawaud-samplerate 8000 ${path}
|
// 修改${path} 的值为pcm路径,即可播放转码后的pcm文件
|
public static void main(String[] args) throws Exception {
|
|
readWrite(Thread.currentThread().getContextClassLoader().getResource("g726/in_40.g726").getPath(),
|
"/Users/tmyam/Downloads/out_40.pcm",200);
|
|
|
readWrite(Thread.currentThread().getContextClassLoader().getResource("g726/in_32.g726").getPath(),
|
"/Users/tmyam/Downloads/out_32.pcm",160);
|
|
|
readWrite(Thread.currentThread().getContextClassLoader().getResource("g726/in_24.g726").getPath(),
|
"/Users/tmyam/Downloads/out_24.pcm",120);
|
|
|
readWrite(Thread.currentThread().getContextClassLoader().getResource("g726/in_16.g726").getPath(),
|
"/Users/tmyam/Downloads/out_16.pcm",80);
|
}
|
}
|