最近弄了很久的Android回声消除,今天终于有电成效,顺便拿来分享分享,希望对大家有帮助
Speex不用介绍了,这里介绍了如何使用Speex进行回声消除,下面直接上代码
speex_jni.cpp
//
// Created by jiaokx on 2015/11/30.
//
#include "com_example_speex1_Speex.h"
#include <string.h>
#include <unistd.h>
//#include <speex/speex.h>
//#include <speex/speex_echo.h>
/*start*/
#include <fcntl.h>
#include <speex/speex.h>
#include <speex/speex_echo.h>
#include <speex/speex_preprocess.h>
#include <speex/speex_bits.h>
#include <speex/speex_buffer.h>
#include <speex/speex_header.h>
#include <speex/speex_types.h>
// the header length of the RTP frame (must skip when en/decoding)
static const int rtp_header = 0;
int codec_status = 0;
const int CODEC_OPENED = 1;
const int CODEC_CLOSED = 0;
int aec_status = 0;
const int AEC_OPENED = 1;
const int AEC_CLOSED = 0;
SpeexEchoState *echoState;
SpeexPreprocessState *den;
int sampleRate = 8000;
/*end*/
static int codec_open = 0;
static int dec_frame_size;
static int enc_frame_size;
static SpeexBits ebits, dbits;
void *enc_state;
void *dec_state;
static JavaVM *gJavaVM;
extern "C" jint Java_com_example_speex1_Speex_open(
JNIEnv *env, jobject obj, jint compression) {
int tmp = 0;
if (codec_open++ != 0)
return (jint) 0;
speex_bits_init(&ebits);
speex_bits_init(&dbits);
enc_state = speex_encoder_init(&speex_nb_mode);
dec_state = speex_decoder_init(&speex_nb_mode);
tmp = compression;
speex_encoder_ctl(enc_state, SPEEX_SET_QUALITY, &tmp);
speex_encoder_ctl(enc_state, SPEEX_GET_FRAME_SIZE, &enc_frame_size);
speex_decoder_ctl(dec_state, SPEEX_GET_FRAME_SIZE, &dec_frame_size);
SpeexPreprocessState * m_st;
m_st = speex_preprocess_state_init(enc_frame_size, sampleRate);
int denoise = 1;
int noiseSuppress = -25;
speex_preprocess_ctl(m_st, SPEEX_PREPROCESS_SET_DENOISE, &denoise);
speex_preprocess_ctl(m_st, SPEEX_PREPROCESS_SET_NOISE_SUPPRESS,&noiseSuppress);
int agc = 1;
float q=24000;
//actually default is 8000(0,32768),here make it louder for voice is not loudy enough by default. 8000
speex_preprocess_ctl(m_st, SPEEX_PREPROCESS_SET_AGC, &agc);//增益
speex_preprocess_ctl(m_st, SPEEX_PREPROCESS_SET_AGC_LEVEL,&q);
int vad = 1;
int vadProbStart = 80;