安卓 基于speex 音频编 解码

#ifdef __cplusplus
extern "C" {
#endif


#include <jni.h>
#include<string.h>
#include<unistd.h>
#include<speex/speex.h>
#include<speex/speex_preprocess.h>


//是否已经初始化
static int codec_open = 0;
//编解码帧大小
static int dec_frame_size, enc_frame_size;
//编解码数据结构
static SpeexBits ebits, dbits;
//编解码 状态
void *enc_state, *dnc_state;


static SpeexPreprocessState * m_st;


//com.example.libmspeex
JNIEXPORT void JNICALL Java_com_example_libmspeex_Speex_init(JNIEnv* env,
jobject thiz, jint quality) {
if (codec_open)
return;
codec_open++;
//初始化
speex_bits_init(&ebits);
speex_bits_init(&dbits);
//初始化状态 speex_wb_mode 宽带编码 speex_nb_mode:窄带 speex_uwb_mode表示超宽带模式
enc_state = speex_encoder_init(&speex_nb_mode);
dnc_state = speex_decoder_init(&speex_nb_mode);
//设置压缩质量
int tmp=0;
speex_encoder_ctl(enc_state, SPEEX_SET_QUALITY, &tmp);
speex_encoder_ctl(enc_state, SPEEX_SET_VBR, &tmp);
speex_encoder_ctl(enc_state, SPEEX_SET_VBR_QUALITY, &quality);
speex_encoder_ctl(enc_state, SPEEX_GET_FRAME_SIZE, &enc_frame_size);
speex_decoder_ctl(dnc_state, SPEEX_GET_FRAME_SIZE, &dec_frame_size);


m_st = speex_preprocess_state_init(160,8000);
int denoise = 1;
int noiseSuppress = -25;
speex_preprocess_ctl(m_st,SPEEX_PREPROCESS_SET_DENOISE,&denoise);//降噪
speex_preprocess_ctl(m_st,SPEEX_PREPROCESS_GET_NOISE_SUPPRESS,&noiseSuppress);//设置噪声的dB


  int agc = 1;
  int 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;
   int vadProbContinue = 65;
   speex_preprocess_ctl(m_st, SPEEX_PREPROCESS_SET_VAD, &vad); //静音检测
   speex_preprocess_ctl(m_st, SPEEX_PREPROCESS_SET_PROB_START , &vadProbStart); //Set probability required for the VAD to go from silence to voice
   speex_preprocess_ctl(m_st, SPEEX_PREPROCESS_SET_PROB_CONTINUE, &vadProbContinue); //Set probability required for the VAD to stay


}
JNIEXPORT jbyteArray JNICALL Java_com_example_libmspeex_Speex_encode(JNIEnv* env,
jobject thiz, jshortArray lin) {
jshort buffer[enc_frame_size];
jbyte output_buffer[enc_frame_size];


if (!codec_open)
return 0;
speex_bits_reset(&ebits);


env->GetShortArrayRegion(lin, 0,enc_frame_size, buffer);


// speex_preprocess_run(m_st,buffer);
speex_encode_int(enc_state, buffer, &ebits);


int tot_bytes = speex_bits_write(&ebits, (char *) output_buffer,enc_frame_size);
jbyteArray encoded = env->NewByteArray(enc_frame_size);
env->SetByteArrayRegion(encoded,0,tot_bytes,output_buffer);
return encoded;
}




JNIEXPORT jshortArray JNICALL Java_com_example_libmspeex_Speex_decode(JNIEnv* env,
jobject thiz,jbyteArray encoded){
jbyte buffer[dec_frame_size];
jshort output_buffer[dec_frame_size];


if(!codec_open)
return 0;
speex_bits_reset(&dbits);
env->GetByteArrayRegion(encoded,0,enc_frame_size,buffer);
speex_bits_read_from(&dbits,(char*)buffer,dec_frame_size);
speex_decode_int(dnc_state,&dbits,output_buffer);
jshortArray lin = env->NewShortArray(dec_frame_size);
env->SetShortArrayRegion(lin,0,dec_frame_size,output_buffer);
return lin;
}


JNIEXPORT jint JNICALL Java_com_example_libmspeex_Speex_getFrameSize(JNIEnv* env,jobject thiz){
if(!codec_open)
return 0;
return enc_frame_size;
}


JNIEXPORT jint JNICALL Java_com_example_libmspeex_Speex_getDecodeSize(JNIEnv* env,jobject thiz){
if(!codec_open)
return 0;
return dec_frame_size;
}


JNIEXPORT void JNICALL Java_com_example_libmspeex_Speex_close(JNIEnv* env,jobject thiz){
if(!codec_open)
return;
speex_bits_destroy(&ebits);
speex_bits_destroy(&dbits);
speex_decoder_destroy(&dnc_state);
speex_encoder_destroy(&enc_state);
}


JNIEXPORT jint JNICALL Java_com_example_libmspeex_Speex_test(JNIEnv* env,
jobject thiz) {


return 100;
}


#ifdef __cplusplus
}
#endif
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值