最近在开发对讲机时,由于G711数据压缩的比较好,适合网络传输,所以音频采用 了 G711编码。但是Android里面的AudioRecord编码出来的是 PCM数据,所以要对数据进行编码后再发送。实现对讲功能。
博主已经测试代码是可行的。而且非常简单,不需要ffmpeg。PCM 转 G711数据长度要减少一半。代码非常简单,不要去编译ffmpeg(博主还没编译通过呢)注意...我要上代码了。都是代码也没啥好注释的。
下面是代码:
JNIEXPORT jint JNICALL Java_com_example_testjni_Hunter_PCM2G711(JNIEnv *env,
jclass obj,jbyteArray _src) {
jsize bufsize = env->GetArrayLength(_src);
unsigned short* src = (short*)env->GetByteArrayElements(_src, 0);
unsigned short* dst = (unsigned short*)malloc(sizeof(unsigned short) * (bufsize/2));
unsigned short i;
short data;
unsigned short isNegative;
short nOut;
short lowByte = 1;
// ----------------- encoder -------------------------
for (i = 0; i < bufsize / 2; i++) {
data = *(src + i);
data >>= 2;
isNegative = (data < 0 ? 1 : 0);
if (isNegative)
data = -data;
if (data <= 1) {
nOut = (char) data;
} else if (data <= 31) {
nOut = ((data - 1) >> 1) + 1;
} else if (data <= 95) {
nOut = ((data - 31) >> 2) + 16;
} else if (data <= 223) {
nOut = ((data - 95) >> 3) + 32;
} else if (data <= 479) {
nOut = ((data - 223) >> 4) + 48;
} else if (data <= 991) {
nOut = ((data - 479) >> 5) + 64;
} else if (data <= 2015) {
nOut = ((data - 991) >> 6) + 80;
} else if (data <= 4063) {
nOut = ((data - 2015) >> 7) + 96;
} else if (data <= 7903) {
nOut = ((data - 4063) >> 8) + 112;
} else {
nOut = 127;
}
if (isNegative) {
nOut = 127 - nOut;
} else {
nOut = 255 - nOut;
}
if (lowByte)
*(dst + (i >> 1)) = (nOut & 0x00FF);
else
*(dst + (i >> 1)) |= ((nOut << 8) & 0xFF00);
lowByte ^= 0x1;
}
//----------------------------encode end -------------------------------
unsigned char* pdata = (char*)(&(dst[0]));
// 得到的pdata 就是 g711数据。可以转成byte[] 数组,然后发送,或者播放。
return 0;
}
这段代码已经用到了 真实的项目中了。 pcm的数据是在 16位,双通道,8000比特上录的。
上面的代码只需要在