关于speex使用(入门笔记)

(笔记)

首先配置speex到环境请看 http://blog.csdn.net/jingwen3699/article/details/8332079


按照以上方式配好后可以看到jni文件夹中有个speex_jni.cpp文件,此文件与speex.java文件对应。导入自己项目中时将

speex_jni.cpp文件中方法中对应的包名改为speex.java的包名。以免引起之后的.so文件生成无反应。

关于speex使用(入门笔记)_第1张图片

speex_jni.cpp部分代码

配置完成后使用NDK生成.so文件

在speex.java文件中已经提供好对应的初始化、编解码方法。下面对这几种方法做使用说明

class Speex  {  
	  
    /* quality 
     * 1 : 4kbps (very noticeable artifacts, usually intelligible) 
     * 2 : 6kbps (very noticeable artifacts, good intelligibility) 
     * 4 : 8kbps (noticeable artifacts sometimes) 
     * 6 : 11kpbs (artifacts usually only noticeable with headphones) 
     * 8 : 15kbps (artifacts not usually noticeable) 
     */  
    private static final int DEFAULT_COMPRESSION = 8;  
  
    Speex() {  
    }  
    //初始化方法
    public void init() {  
        load();   
        open(DEFAULT_COMPRESSION);  
    }  
    private void load() {  
        try {  
        	 //加载对应我们刚刚生成的.so文件。这里speex指的是libs文件夹中对应硬件构架文件夹下的的libsspeex.so
        	//至于前置的libs是生成前自动补充的
            System.loadLibrary("speex"); 
        } catch (Throwable e) {  
            e.printStackTrace();  
        }  
    }  
    //设置默认压缩率
    public native int open(int compression);  
    public native int getFrameSize();  
    //解码
    public native int decode(byte encoded[], short lin[], int size);  
    //编码
    public native int encode(short lin[], int offset, byte encoded[], int size);  
    public native void close();  
}  

初始化代码

	//获取音频的最小缓冲区(如果不需要可以不写)
	int audioBufferSize = AudioRecord.getMinBufferSize(hz, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT);
	//创建音频对象(录音孔,采样率,声道,音频格式,缓冲区)
	ar = new AudioRecord(MediaRecorder.AudioSource.MIC, hz, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, audioBufferSize);


编码代码

 public native int encode(short lin[], int offset, byte encoded[], int size);  

void send(){
		//创建两个数组
		int num = 0;
		byte[] buffer = new byte[160];
		short[] ss = new short[160];
		//读取AudioRecord对象中的数据到数组(记得read前先  ar.startRecording()  打开录音)
		num = ar.read(ss, 0, 160);
		//使用Speex编码方法
		sx.encode(ss, 0, buffer, num);
		if(num>0){
			//最后调用流来对编码后的buffer数组进行保存或传输
			send2(buffer, "172.16.77.4", 60001);
		}
		
	}

解码方法

public native int decode(byte encoded[], short lin[], int size);

与编码类似 依次传入被编码数组、解码后数组、以及大小



完成这些之后就可以获取到真正的音频数据了。但是在播放过程中我测试出来speex只是对音频数据进行相应的编解码,未对音频做处理。至于降噪、回声消除、增益、静音检测需要做以下初始化调用。

首先,打开项目-->jni-->speex_jni.cpp  找到 open 方法加入以下代码。

extern "C"
JNIEXPORT jint JNICALL Java_com_example_audiotest1_Speex_open
  (JNIEnv *env, jobject obj, jint compression) {
	int tmp;

	if (codec_open++ != 0)
		return (jint)0;

	speex_bits_init(&ebits);
	speex_bits_init(&dbits);
	//加入以下代码=======================
		SpeexPreprocessState * m_st;
		SpeexEchoState* s_es;
	    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_SET_NOISE_SUPPRESS, &noiseSuppress); //设置噪声

	    int agc = 1;
	    int  q=24000;
	    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


		s_es = speex_echo_state_init( 160, 8000 );
		int __sample_rate = 4000;
		speex_echo_ctl( s_es, SPEEX_ECHO_SET_SAMPLING_RATE, &__sample_rate );//回音消除
		speex_preprocess_ctl( m_st, SPEEX_PREPROCESS_SET_ECHO_STATE, s_es );
	//=========================================

//		ses = speex_encoder_init( &speex_nb_mode);

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

	return (jint)0;
}

因为speex源码中存在上述音频处理方法,我们在初始化speex的时候调用这些方法传入适当参数就可以达到效果。



DEMO下载:http://download.csdn.net/detail/qq_32274413/9607268 (需在代码中更改 ip port)

如有问题可以联系我的qq:948366879


你可能感兴趣的:(Android,JNI,speex)