1 编译过程:
由于便于过程与环境各不相同,简单记录编译思路为,抽出webrtc单独模块,根据头文件链接,将所需源文件记录于Android.mk。直至该模块所有源文件齐全,编译出so。
2 使用记录
demo提供实例为文件回音消除方案,实际语音对讲项目多采用多线程,一条接收,一条录制编码,发送等,所以需在demo基础上进行改动。具体代码如下:
#include "AcemNative.h"
void *AecmInst;
int miniBufferSize;
int delayTime;
JNIEXPORT jint JNICALL Java_com_stream_WebRtc_AcemInit(JNIEnv *env, jclass cls,jint rate,jint miniSize,jint delay){//初始化参数
LOGD("webrtc acem init rate % d , minisize %d",rate,miniSize);
AecmInst = WebRtcAecm_Create();
WebRtcAecm_Init(AecmInst, rate);
AecmConfig config;
config.cngMode = AecmTrue;
config.echoMode = 4;//回音消除等级 0 - 4
WebRtcAecm_set_config(AecmInst, config);
miniBufferSize = miniSize;
delayTime = delay;
return 0;
}
JNIEXPORT jint JNICALL Java_com_stream_WebRtc_AcemCompareData(JNIEnv *env, jclass cls,jbyteArray compare){
jbyte* inBuffer = env->GetByteArrayElements(compare, 0);
jint compareSize = env->GetArrayLength(compare); //获取长度
LOGD("add compare data %d",compareSize);
//确定循环次数
jint addCount = 0;
addCount = compareSize / miniBufferSize;//取整
LOGD("add compare data size %d , add count %d",compareSize,addCount);
PNPC_BYTE trunk = (PNPC_BYTE)malloc(miniBufferSize);
for(int i = 0 ; i < addCount; i++){
memset(trunk,0,miniBufferSize);
memcpy(trunk,inBuffer + (i * miniBufferSize),miniBufferSize);
int ret = WebRtcAecm_BufferFarend(AecmInst, (int16_t*)trunk, miniBufferSize / 2 );
LOGD("add compare data size %d yet is %d \n",miniBufferSize,ret);
}
free(trunk);
trunk = NULL;
//如参考数据大于输入音频长度,分割传入
env->ReleaseByteArrayElements(compare,inBuffer,0) ;
return 0;
}
JNIEXPORT jint JNICALL Java_com_stream_WebRtc_AecmProcess(JNIEnv *env, jclass cls,jbyteArray inArray,jbyteArray szOutArray){
jbyte* inBuffer = env->GetByteArrayElements(inArray, 0);
jbyte* outBuffer = env->GetByteArrayElements(szOutArray, 0);
jint compareSize = env->GetArrayLength(inArray); //获取长度
jint addCount = 0;
addCount = compareSize / miniBufferSize;//取整
LOGD("add speak data size %d add speek count %d",compareSize,addCount);
PNPC_BYTE trunk = (PNPC_BYTE)malloc(miniBufferSize);//输入
PNPC_BYTE outTrunk = (PNPC_BYTE)malloc(miniBufferSize);//输出块
for(int i = 0 ; i < addCount; i++){//16为线性pcm为最小块整数,所以未对余数部分数据进行处理。
memset(trunk,0,miniBufferSize);
memcpy(trunk,inBuffer + (i * miniBufferSize),miniBufferSize);
int ret = WebRtcAecm_Process(AecmInst, (int16_t*)trunk,(int16_t*)trunk,(int16_t*)outTrunk,miniBufferSize / 2,delayTime);
LOGD("acem process--size : %d ret : %d\n",miniBufferSize,ret);
memcpy(outBuffer + (i * miniBufferSize),outTrunk,miniBufferSize);
}
free(trunk);
trunk = NULL;
free(outTrunk);
outTrunk = NULL;
env->ReleaseByteArrayElements(inArray,(jbyte*)inBuffer,0) ;
env->ReleaseByteArrayElements(szOutArray,(jbyte*)outBuffer,0) ;
return 0;
}
JNIEXPORT jint JNICALL Java_com_stream_WebRtc_AcemDestory(JNIEnv *env, jclass cls){
WebRtcAecm_Free(AecmInst);
return 0;
}
JNIEXPORT jint JNICALL Java_com_stream_WebRtc_TestAcem(JNIEnv *env, jclass cls){
void *AecmInst;
AecmInst = WebRtcAecm_Create();
WebRtcAecm_Init(AecmInst, 8000);
AecmConfig config;
config.cngMode = AecmTrue;
config.echoMode = 4;
WebRtcAecm_set_config(AecmInst, config);
FILE *fp = fopen("/sdcard/test.pcm", "rb"); //输入
FILE *fps = fopen("/sdcard/test2.pcm", "rb");
FILE *outfp = fopen("/sdcard/out.pcm", "wb"); //输出
if (fp == NULL) {
LOGD("empty file,please check the file name\n");
return -1;
}
short readBuf[160];
short refBuf[160];
short outBuf[160];
//fread(readBuf, 2, 160, fps);
while (!feof(fp) && !feof(fps)) {
fread(readBuf, 2, 160, fp);
fread(refBuf, 2, 160, fps);
//参考音频
LOGD("buffput------%d", WebRtcAecm_BufferFarend(AecmInst, refBuf, 160));
//处理
LOGD("process-----%d\n", WebRtcAecm_Process(AecmInst, readBuf, readBuf, outBuf, 160, 10));
fwrite(outBuf, 2, 160, outfp);
// memcpy(refBuf,readBuf,320);
}
getchar();
fclose(fp);
fclose(outfp);
return 0;
return 0;
}