Webrtc Acem模块Android端单独编译与使用

   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;
}


你可能感兴趣的:(jni)