Silk编解码在android实现

简介:
Silk编解码是Skype向第三方开发人员和硬件制造商提供免版税认证(RF)的Silk宽带音频编码器。Skype已将其开源,可以访问 http://developer.skype.com/silk 获取最新动向。SILK Codec是一个语音和音频编解码算法, 对于音频带宽、网络带宽和算法复杂度都具有很好的弹性。支持4种采样率:8KHz、12KHz、16KHz、24KHz;三种复杂度:低、中、高。编码码率在 6~40kbps(不同采样率具有不同的码率范围)以及还支持VAD、DTX、FEC等模块,感觉还是比较全面。最重要的一点是提供了定点C代码,非常有利于向ARM、DSP移植和优化。这一篇主要参考了pjsip中的silk实现。

      1、获取silk源码(http://developer.skype.com/silk

       2、创建新的android工程,并创建jni文件夹。

       3、将silk源码拷贝到jni目录

       4、在jni目录下新增Android.mk文件,编辑内容如下

   

LOCAL_PATH := $(call my-dir)   include $(CLEAR_VARS) SILK     := silk LOCAL_MODULE    := silkcommon LOCAL_SRC_FILES :=  $(SILK)/src/SKP_Silk_A2NLSF.c \ 	$(SILK)/src/SKP_Silk_CNG.c \ 	$(SILK)/src/SKP_Silk_HP_variable_cutoff_FIX.c \ 	$(SILK)/src/SKP_Silk_LBRR_reset.c \ 	$(SILK)/src/SKP_Silk_LPC_inv_pred_gain.c \ 	$(SILK)/src/SKP_Silk_LPC_stabilize.c \ 	$(SILK)/src/SKP_Silk_LPC_synthesis_filter.c \ 	$(SILK)/src/SKP_Silk_LPC_synthesis_order16.c \ 	$(SILK)/src/SKP_Silk_LP_variable_cutoff.c \ 	$(SILK)/src/SKP_Silk_LSF_cos_table.c \ 	$(SILK)/src/SKP_Silk_LTP_analysis_filter_FIX.c \ 	$(SILK)/src/SKP_Silk_LTP_scale_ctrl_FIX.c \ 	$(SILK)/src/SKP_Silk_MA.c \ 	$(SILK)/src/SKP_Silk_NLSF2A.c \ 	$(SILK)/src/SKP_Silk_NLSF2A_stable.c \ 	$(SILK)/src/SKP_Silk_NLSF_MSVQ_decode.c \ 	$(SILK)/src/SKP_Silk_NLSF_MSVQ_encode_FIX.c \ 	$(SILK)/src/SKP_Silk_NLSF_VQ_rate_distortion_FIX.c \ 	$(SILK)/src/SKP_Silk_NLSF_VQ_sum_error_FIX.c \ 	$(SILK)/src/SKP_Silk_NLSF_VQ_weights_laroia.c \ 	$(SILK)/src/SKP_Silk_NLSF_stabilize.c \ 	$(SILK)/src/SKP_Silk_NSQ.c \ 	$(SILK)/src/SKP_Silk_NSQ_del_dec.c \ 	$(SILK)/src/SKP_Silk_PLC.c \ 	$(SILK)/src/SKP_Silk_VAD.c \ 	$(SILK)/src/SKP_Silk_VQ_nearest_neighbor_FIX.c \ 	$(SILK)/src/SKP_Silk_allpass_int.c \ 	$(SILK)/src/SKP_Silk_ana_filt_bank_1.c \ 	$(SILK)/src/SKP_Silk_apply_sine_window.c \ 	$(SILK)/src/SKP_Silk_array_maxabs.c \ 	$(SILK)/src/SKP_Silk_autocorr.c \ 	$(SILK)/src/SKP_Silk_biquad.c \ 	$(SILK)/src/SKP_Silk_biquad_alt.c \ 	$(SILK)/src/SKP_Silk_burg_modified.c \ 	$(SILK)/src/SKP_Silk_bwexpander.c \ 	$(SILK)/src/SKP_Silk_bwexpander_32.c \ 	$(SILK)/src/SKP_Silk_code_signs.c \ 	$(SILK)/src/SKP_Silk_control_codec_FIX.c \ 	$(SILK)/src/SKP_Silk_corrMatrix_FIX.c \ 	$(SILK)/src/SKP_Silk_create_init_destroy.c \ 	$(SILK)/src/SKP_Silk_dec_API.c \ 	$(SILK)/src/SKP_Silk_decode_core.c \ 	$(SILK)/src/SKP_Silk_decode_frame.c \ 	$(SILK)/src/SKP_Silk_decode_indices_v4.c \ 	$(SILK)/src/SKP_Silk_decode_parameters.c \ 	$(SILK)/src/SKP_Silk_decode_parameters_v4.c \ 	$(SILK)/src/SKP_Silk_decode_pulses.c \ 	$(SILK)/src/SKP_Silk_decoder_set_fs.c \ 	$(SILK)/src/SKP_Silk_detect_SWB_input.c \ 	$(SILK)/src/SKP_Silk_enc_API.c \ 	$(SILK)/src/SKP_Silk_encode_frame_FIX.c \ 	$(SILK)/src/SKP_Silk_encode_parameters.c \ 	$(SILK)/src/SKP_Silk_encode_parameters_v4.c \ 	$(SILK)/src/SKP_Silk_encode_pulses.c \ 	$(SILK)/src/SKP_Silk_find_LPC_FIX.c \ 	$(SILK)/src/SKP_Silk_find_LTP_FIX.c \ 	$(SILK)/src/SKP_Silk_find_pitch_lags_FIX.c \ 	$(SILK)/src/SKP_Silk_find_pred_coefs_FIX.c \ 	$(SILK)/src/SKP_Silk_gain_quant.c \ 	$(SILK)/src/SKP_Silk_init_encoder_FIX.c \ 	$(SILK)/src/SKP_Silk_inner_prod_aligned.c \ 	$(SILK)/src/SKP_Silk_interpolate.c \ 	$(SILK)/src/SKP_Silk_k2a.c \ 	$(SILK)/src/SKP_Silk_k2a_Q16.c \ 	$(SILK)/src/SKP_Silk_lin2log.c \ 	$(SILK)/src/SKP_Silk_log2lin.c \ 	$(SILK)/src/SKP_Silk_lowpass_int.c \ 	$(SILK)/src/SKP_Silk_lowpass_short.c \ 	$(SILK)/src/SKP_Silk_noise_shape_analysis_FIX.c \ 	$(SILK)/src/SKP_Silk_pitch_analysis_core.c \ 	$(SILK)/src/SKP_Silk_pitch_est_tables.c \ 	$(SILK)/src/SKP_Silk_prefilter_FIX.c \ 	$(SILK)/src/SKP_Silk_process_NLSFs_FIX.c \ 	$(SILK)/src/SKP_Silk_process_gains_FIX.c \ 	$(SILK)/src/SKP_Silk_pulses_to_bytes.c \ 	$(SILK)/src/SKP_Silk_quant_LTP_gains_FIX.c \ 	$(SILK)/src/SKP_Silk_range_coder.c \ 	$(SILK)/src/SKP_Silk_regularize_correlations_FIX.c \ 	$(SILK)/src/SKP_Silk_resample_1_2.c \ 	$(SILK)/src/SKP_Silk_resample_1_2_coarse.c \ 	$(SILK)/src/SKP_Silk_resample_1_2_coarsest.c \ 	$(SILK)/src/SKP_Silk_resample_1_3.c \ 	$(SILK)/src/SKP_Silk_resample_2_1_coarse.c \ 	$(SILK)/src/SKP_Silk_resample_2_3.c \ 	$(SILK)/src/SKP_Silk_resample_2_3_coarse.c \ 	$(SILK)/src/SKP_Silk_resample_2_3_coarsest.c \ 	$(SILK)/src/SKP_Silk_resample_2_3_rom.c \ 	$(SILK)/src/SKP_Silk_resample_3_1.c \ 	$(SILK)/src/SKP_Silk_resample_3_2.c \ 	$(SILK)/src/SKP_Silk_resample_3_2_rom.c \ 	$(SILK)/src/SKP_Silk_resample_3_4.c \ 	$(SILK)/src/SKP_Silk_resample_4_3.c \ 	$(SILK)/src/SKP_Silk_residual_energy16_FIX.c \ 	$(SILK)/src/SKP_Silk_residual_energy_FIX.c \ 	$(SILK)/src/SKP_Silk_scale_copy_vector16.c \ 	$(SILK)/src/SKP_Silk_scale_vector.c \ 	$(SILK)/src/SKP_Silk_schur.c \ 	$(SILK)/src/SKP_Silk_schur64.c \ 	$(SILK)/src/SKP_Silk_shell_coder.c \ 	$(SILK)/src/SKP_Silk_sigm_Q15.c \ 	$(SILK)/src/SKP_Silk_solve_LS_FIX.c \ 	$(SILK)/src/SKP_Silk_sort.c \ 	$(SILK)/src/SKP_Silk_sum_sqr_shift.c \ 	$(SILK)/src/SKP_Silk_tables_LTP.c \ 	$(SILK)/src/SKP_Silk_tables_NLSF_CB0_10.c \ 	$(SILK)/src/SKP_Silk_tables_NLSF_CB0_16.c \ 	$(SILK)/src/SKP_Silk_tables_NLSF_CB1_10.c \ 	$(SILK)/src/SKP_Silk_tables_NLSF_CB1_16.c \ 	$(SILK)/src/SKP_Silk_tables_gain.c \ 	$(SILK)/src/SKP_Silk_tables_other.c \ 	$(SILK)/src/SKP_Silk_tables_pitch_lag.c \ 	$(SILK)/src/SKP_Silk_tables_pulses_per_block.c \ 	$(SILK)/src/SKP_Silk_tables_sign.c \ 	$(SILK)/src/SKP_Silk_tables_type_offset.c 	 LOCAL_ARM_MODE := arm LOCAL_CFLAGS = -O3  LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -llog LOCAL_C_INCLUDES += $(LOCAL_PATH)/$(SILK)/src $(LOCAL_PATH)/$(SILK)/interface include $(BUILD_STATIC_LIBRARY)   include $(CLEAR_VARS) LOCAL_MODULE    := silk8_jni LOCAL_SRC_FILES := silk8_jni.cpp  LOCAL_C_INCLUDES += $(LOCAL_PATH)/$(SILK)/src $(LOCAL_PATH)/$(SILK)/interface LOCAL_CFLAGS = -O3  LOCAL_STATIC_LIBRARIES :=  silkcommon LOCAL_ARM_MODE := arm LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -llog include $(BUILD_SHARED_LIBRARY)  include $(CLEAR_VARS) LOCAL_MODULE    := silk16_jni LOCAL_SRC_FILES := silk16_jni.cpp  LOCAL_C_INCLUDES += $(LOCAL_PATH)/$(SILK)/src $(LOCAL_PATH)/$(SILK)/interface LOCAL_CFLAGS = -O3  LOCAL_STATIC_LIBRARIES :=  silkcommon LOCAL_ARM_MODE := arm LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -llog include $(BUILD_SHARED_LIBRARY)  include $(CLEAR_VARS) LOCAL_MODULE    := silk24_jni LOCAL_SRC_FILES := silk24_jni.cpp  LOCAL_C_INCLUDES += $(LOCAL_PATH)/$(SILK)/src $(LOCAL_PATH)/$(SILK)/interface LOCAL_CFLAGS = -O3  LOCAL_STATIC_LIBRARIES :=  silkcommon LOCAL_ARM_MODE := arm LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -llog include $(BUILD_SHARED_LIBRARY)


       5、创建JNI包装类silk8_jni.cpp、silk16_jni.cpp、silk24_jni.cpp,用来调用Silk中的C代码函数,编辑内容如下

      silk8_jni.cpp:

    

#include <jni.h>  #include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h>  /* Define codec specific settings */ #define MAX_BYTES_ENC_PER_FRAME     250 // Equals peak bitrate of 100 kbps  #define MAX_BYTES_DEC_PER_FRAME     1024  #define MAX_INPUT_FRAMES        5 #define MAX_LBRR_DELAY          2 #define MAX_FRAME_LENGTH        480  #define	MAX_FRAME			160  #include <android/log.h>   #define LOG_TAG "silk" // text for log tag   #include "SKP_Silk_SDK_API.h" #include "SKP_Silk_SigProc_FIX.h"  #undef DEBUG_SILK8  // the header length of the RTP frame (must skip when en/decoding) #define	RTP_HDR_SIZE	12  static int codec_open = 0;  static JavaVM *gJavaVM; const char *kInterfacePath = "org/sipdroid/pjlib/silk8";  /* encoder parameters */      SKP_int32 encSizeBytes;     void      *psEnc;      /* default settings */     SKP_int   fs_kHz = 8;     SKP_int   targetRate_bps = 20000;     SKP_int   packetSize_ms = 20;     SKP_int   frameSizeReadFromFile_ms = 20;     SKP_int   packetLoss_perc = 0, smplsSinceLastPacket;     SKP_int   INBandFec_enabled = 0, DTX_enabled = 0, quiet = 0;     SKP_SILK_SDK_EncControlStruct encControl; // Struct for input to encoder           /* decoder parameters */      jbyte payloadToDec[    MAX_BYTES_DEC_PER_FRAME * MAX_INPUT_FRAMES * ( MAX_LBRR_DELAY + 1 ) ];     jshort out[ ( MAX_FRAME_LENGTH << 1 ) * MAX_INPUT_FRAMES ], *outPtr;     SKP_int32 decSizeBytes;     void      *psDec;     SKP_SILK_SDK_DecControlStruct DecControl;  extern "C" JNIEXPORT jint JNICALL Java_com_trunkbow_silk_SILK8_open   (JNIEnv *env, jobject obj, jint compression) { 	int ret;  	if (codec_open++ != 0) 		return (jint)0;  	/* Set the samplingrate that is requested for the output */     DecControl.sampleRate = 8000; 		     /* Create decoder */     ret = SKP_Silk_SDK_Get_Decoder_Size( &decSizeBytes );     if( ret ) { 		__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,              "\n!!!!!!!! SKP_Silk_SDK_Get_Decoder_Size returned %d", ret );		     } #ifdef DEBUG_SILK8     __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,              "### INIT Decoder decSizeBytes = %d\n", decSizeBytes); 		 #endif	     psDec = malloc( decSizeBytes );      /* Reset decoder */     ret = SKP_Silk_SDK_InitDecoder( psDec );     if( ret ) { 		__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,              "\n!!!!!!!! SKP_Silk_InitDecoder returned %d", ret );	     }       /* Create Encoder */     ret = SKP_Silk_SDK_Get_Encoder_Size( &encSizeBytes );     if( ret ) { 		__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,              "\n!!!!!!!! SKP_Silk_SDK_Get_Encoder_Size returned %d", ret );	     } #ifdef DEBUG_SILK8     __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,              "### INIT Encoder encSizeBytes = %d\n", encSizeBytes); 		 #endif		     psEnc = malloc( encSizeBytes );          /* Reset Encoder */     ret = SKP_Silk_SDK_InitEncoder( psEnc, &encControl );     if( ret ) { 		__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,              "\n!!!!!!!! SKP_Silk_SDK_InitEncoder returned %d", ret );	 	}          /* Set Encoder parameters */     encControl.sampleRate           = fs_kHz * 1000;     encControl.packetSize           = packetSize_ms * fs_kHz;     encControl.packetLossPercentage = packetLoss_perc;     encControl.useInBandFEC         = INBandFec_enabled;     encControl.useDTX               = DTX_enabled;     encControl.complexity           = compression;     encControl.bitRate              = targetRate_bps;		 	 	return (jint)0; }  void Print_Decode_Error_Msg(int errcode) { 	switch (errcode) { 		case SKP_SILK_DEC_WRONG_SAMPLING_FREQUENCY: 			__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,  				"!!!!!!!!!!! Decode_Error_Message: %d\nOutput sampling frequency lower than internal decoded sampling frequency\n", errcode); 			break; 		case SKP_SILK_DEC_PAYLOAD_TOO_LARGE: 			__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,  				"!!!!!!!!!!! Decode_Error_Message: %d\nPayload size exceeded the maximum allowed 1024 bytes\n", errcode);  			break; 		case SKP_SILK_DEC_PAYLOAD_ERROR: 			__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,  				"!!!!!!!!!!! Decode_Error_Message: %d\nPayload has bit errors\n", errcode);  			break;			 	} }  void Print_Encode_Error_Msg(int errcode) { 	switch (errcode) { 		case SKP_SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES: 			__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,  				"!!!!!!!!!!! Decode_Error_Message: %d\nInput length is not a multiplum of 10 ms, or length is longer than the packet length\n", errcode); 			break; 		case SKP_SILK_ENC_FS_NOT_SUPPORTED: 			__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,  				"!!!!!!!!!!! Decode_Error_Message: %d\nSampling frequency not 8000, 12000, 16000 or 24000 Hertz \n", errcode);  			break; 		case SKP_SILK_ENC_PACKET_SIZE_NOT_SUPPORTED: 			__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,  				"!!!!!!!!!!! Decode_Error_Message: %d\nPacket size not 20, 40, 60, 80 or 100 ms\n", errcode);  			break;			 		case SKP_SILK_ENC_PAYLOAD_BUF_TOO_SHORT: 			__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,  				"!!!!!!!!!!! Decode_Error_Message: %d\nAllocated payload buffer too short \n", errcode); 			break; 		case SKP_SILK_ENC_WRONG_LOSS_RATE: 			__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,  				"!!!!!!!!!!! Decode_Error_Message: %d\nLoss rate not between 0 and 100 percent\n", errcode);  			break; 		case SKP_SILK_ENC_WRONG_COMPLEXITY_SETTING: 			__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,  				"!!!!!!!!!!! Decode_Error_Message: %d\nComplexity setting not valid, use 0, 1 or 2\n", errcode);  			break;		 		case SKP_SILK_ENC_WRONG_INBAND_FEC_SETTING: 			__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,  				"!!!!!!!!!!! Decode_Error_Message: %d\nInband FEC setting not valid, use 0 or 1\n", errcode); 			break; 		case SKP_SILK_ENC_WRONG_DTX_SETTING: 			__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,  				"!!!!!!!!!!! Decode_Error_Message: %d\nDTX setting not valid, use 0 or 1\n", errcode);  			break; 		case SKP_SILK_ENC_INTERNAL_ERROR: 			__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,  				"!!!!!!!!!!! Decode_Error_Message: %d\nInternal encoder error\n", errcode);  			break;				 	} }  extern "C" JNIEXPORT jint JNICALL Java_com_trunkbow_silk_SILK8_encode     (JNIEnv *env, jobject obj, jshortArray lin, jint offset, jbyteArray encoded, jint size) {      jbyte	  enc_payload[ MAX_BYTES_DEC_PER_FRAME * MAX_INPUT_FRAMES ];     jshort    in[ MAX_FRAME_LENGTH * MAX_INPUT_FRAMES ];	 	int ret,i,frsz=MAX_FRAME; 	SKP_int16 nBytes; 	unsigned int lin_pos = 0; 	 	if (!codec_open) 		return 0; 		 #ifdef DEBUG_SILK8     __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,              "encoding frame size: %d\toffset: %d\n", size, offset); 		 #endif   	for (i = 0; i < size; i+=MAX_FRAME) { #ifdef DEBUG_SILK8 		__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,              "encoding frame size: %d\toffset: %d i: %d\n", size, offset, i); 		 #endif 			 		env->GetShortArrayRegion(lin, offset + i,frsz, in);         /* max payload size */         nBytes = MAX_BYTES_ENC_PER_FRAME * MAX_INPUT_FRAMES;          ret = SKP_Silk_SDK_Encode( psEnc, &encControl, in, (SKP_int16)frsz, (SKP_uint8 *)enc_payload, &nBytes );         if( ret ) { 			__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,  				"!!!!!!!! SKP_Silk_Encode returned: %d\n", ret); 			Print_Encode_Error_Msg(ret);				             break;         } #ifdef DEBUG_SILK8 			__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,  				"Enocded nBytes: %d\n", nBytes); 		 #endif		         /* Write payload */		 		env->SetByteArrayRegion(encoded, RTP_HDR_SIZE+ lin_pos, nBytes, enc_payload); 		lin_pos += nBytes; 	} #ifdef DEBUG_SILK8 	__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,          "encoding **END** frame size: %d\toffset: %d i: %d lin_pos: %d\n", size, offset, i, lin_pos); #endif		      return (jint)lin_pos; }  extern "C" JNIEXPORT jint JNICALL Java_com_trunkbow_silk_SILK8_decode     (JNIEnv *env, jobject obj, jbyteArray encoded, jshortArray lin, jint size) {      jbyte buffer [MAX_BYTES_DEC_PER_FRAME * MAX_INPUT_FRAMES * ( MAX_LBRR_DELAY + 1 ) ];     jshort output_buffer[( MAX_FRAME_LENGTH << 1 ) * MAX_INPUT_FRAMES ]; //	SKP_int16	*outPtr;  	int ret; 	SKP_int16 len; //	int	tot_len,frames;  	if (!codec_open) 		return 0;  #ifdef DEBUG_SILK8		 	__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,          "##### BEGIN DECODE ********  decoding frame size: %d\n", size); 	 #endif  	env->GetByteArrayRegion(encoded, RTP_HDR_SIZE, size, buffer);  //	outPtr = output_buffer; //    tot_len = 0; //	frames = 0;  //	do { 		ret = SKP_Silk_SDK_Decode( psDec, &DecControl, 0,(SKP_uint8 *) buffer, size, output_buffer,&len ); 		if( ret ) { 			__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,  				"!!!!!!!! SKP_Silk_SDK_Decode returned: %d\n", ret); 	 			Print_Decode_Error_Msg(ret); 		} #ifdef DEBUG_SILK8		 		__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,  			"##### DECODED length: %d\n\t Frame #: %d", len); 	 #endif //		frames++; //		outPtr  += len; //		tot_len += len;		 	 //	} while( DecControl.moreInternalDecoderFrames );  	env->SetShortArrayRegion(lin, 0, len,output_buffer); 	return (jint)len; }  extern "C" JNIEXPORT void JNICALL Java_com_trunkbow_silk_SILK8_close     (JNIEnv *env, jobject obj) {  	if (--codec_open != 0) 		return;     /* Free decoder */     free( psDec );     /* Free Encoder */     free( psEnc ); }


      silk_16.cpp:

      

#include <jni.h>  #include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h>  /* Define codec specific settings */ #define MAX_BYTES_ENC_PER_FRAME     250 // Equals peak bitrate of 100 kbps  #define MAX_BYTES_DEC_PER_FRAME     1024  #define MAX_INPUT_FRAMES        5 #define MAX_LBRR_DELAY          2 #define MAX_FRAME_LENGTH        480  #define	MAX_FRAME			320  #include <android/log.h>   #define LOG_TAG "silk" // text for log tag   #include "SKP_Silk_SDK_API.h" #include "SKP_Silk_SigProc_FIX.h"  #undef DEBUG_SILK16  // the header length of the RTP frame (must skip when en/decoding) #define	RTP_HDR_SIZE	12  static int codec_open = 0;  static JavaVM *gJavaVM; const char *kInterfacePath = "org/sipdroid/pjlib/silk16";  /* encoder parameters */      SKP_int32 encSizeBytes;     void      *psEnc;      /* default settings */     SKP_int   fs_kHz = 16;     SKP_int   targetRate_bps = 20000;     SKP_int   packetSize_ms = 20;     SKP_int   frameSizeReadFromFile_ms = 20;     SKP_int   packetLoss_perc = 0, smplsSinceLastPacket;     SKP_int   INBandFec_enabled = 0, DTX_enabled = 0, quiet = 0;     SKP_SILK_SDK_EncControlStruct encControl; // Struct for input to encoder           /* decoder parameters */      jbyte payloadToDec[    MAX_BYTES_DEC_PER_FRAME * MAX_INPUT_FRAMES * ( MAX_LBRR_DELAY + 1 ) ];     jshort out[ ( MAX_FRAME_LENGTH << 1 ) * MAX_INPUT_FRAMES ], *outPtr;     SKP_int32 decSizeBytes;     void      *psDec;     SKP_SILK_SDK_DecControlStruct DecControl;  extern "C" JNIEXPORT jint JNICALL Java_com_trunkbow_silk_SILK16_open   (JNIEnv *env, jobject obj, jint compression) { 	int ret;  	if (codec_open++ != 0) 		return (jint)0;  	/* Set the samplingrate that is requested for the output */     DecControl.sampleRate = 16000; 		     /* Create decoder */     ret = SKP_Silk_SDK_Get_Decoder_Size( &decSizeBytes );     if( ret ) { 		__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,              "\n!!!!!!!! SKP_Silk_SDK_Get_Decoder_Size returned %d", ret );		     } #ifdef DEBUG_SILK16     __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,              "### INIT Decoder decSizeBytes = %d\n", decSizeBytes); 		 #endif	     psDec = malloc( decSizeBytes );      /* Reset decoder */     ret = SKP_Silk_SDK_InitDecoder( psDec );     if( ret ) { 		__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,              "\n!!!!!!!! SKP_Silk_InitDecoder returned %d", ret );	     }       /* Create Encoder */     ret = SKP_Silk_SDK_Get_Encoder_Size( &encSizeBytes );     if( ret ) { 		__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,              "\n!!!!!!!! SKP_Silk_SDK_Get_Encoder_Size returned %d", ret );	     } #ifdef DEBUG_SILK16     __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,              "### INIT Encoder encSizeBytes = %d\n", encSizeBytes); 		 #endif		     psEnc = malloc( encSizeBytes );          /* Reset Encoder */     ret = SKP_Silk_SDK_InitEncoder( psEnc, &encControl );     if( ret ) { 		__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,              "\n!!!!!!!! SKP_Silk_SDK_InitEncoder returned %d", ret );	 	}          /* Set Encoder parameters */     encControl.sampleRate           = fs_kHz * 1000;     encControl.packetSize           = packetSize_ms * fs_kHz;     encControl.packetLossPercentage = packetLoss_perc;     encControl.useInBandFEC         = INBandFec_enabled;     encControl.useDTX               = DTX_enabled;     encControl.complexity           = compression;     encControl.bitRate              = targetRate_bps;		 	 	return (jint)0; }  void Print_Decode_Error_Msg(int errcode) { 	switch (errcode) { 		case SKP_SILK_DEC_WRONG_SAMPLING_FREQUENCY: 			__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,  				"!!!!!!!!!!! Decode_Error_Message: %d\nOutput sampling frequency lower than internal decoded sampling frequency\n", errcode); 			break; 		case SKP_SILK_DEC_PAYLOAD_TOO_LARGE: 			__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,  				"!!!!!!!!!!! Decode_Error_Message: %d\nPayload size exceeded the maximum allowed 1024 bytes\n", errcode);  			break; 		case SKP_SILK_DEC_PAYLOAD_ERROR: 			__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,  				"!!!!!!!!!!! Decode_Error_Message: %d\nPayload has bit errors\n", errcode);  			break;			 	} }  void Print_Encode_Error_Msg(int errcode) { 	switch (errcode) { 		case SKP_SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES: 			__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,  				"!!!!!!!!!!! Decode_Error_Message: %d\nInput length is not a multiplum of 10 ms, or length is longer than the packet length\n", errcode); 			break; 		case SKP_SILK_ENC_FS_NOT_SUPPORTED: 			__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,  				"!!!!!!!!!!! Decode_Error_Message: %d\nSampling frequency not 8000, 12000, 16000 or 24000 Hertz \n", errcode);  			break; 		case SKP_SILK_ENC_PACKET_SIZE_NOT_SUPPORTED: 			__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,  				"!!!!!!!!!!! Decode_Error_Message: %d\nPacket size not 20, 40, 60, 80 or 100 ms\n", errcode);  			break;			 		case SKP_SILK_ENC_PAYLOAD_BUF_TOO_SHORT: 			__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,  				"!!!!!!!!!!! Decode_Error_Message: %d\nAllocated payload buffer too short \n", errcode); 			break; 		case SKP_SILK_ENC_WRONG_LOSS_RATE: 			__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,  				"!!!!!!!!!!! Decode_Error_Message: %d\nLoss rate not between 0 and 100 percent\n", errcode);  			break; 		case SKP_SILK_ENC_WRONG_COMPLEXITY_SETTING: 			__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,  				"!!!!!!!!!!! Decode_Error_Message: %d\nComplexity setting not valid, use 0, 1 or 2\n", errcode);  			break;		 		case SKP_SILK_ENC_WRONG_INBAND_FEC_SETTING: 			__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,  				"!!!!!!!!!!! Decode_Error_Message: %d\nInband FEC setting not valid, use 0 or 1\n", errcode); 			break; 		case SKP_SILK_ENC_WRONG_DTX_SETTING: 			__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,  				"!!!!!!!!!!! Decode_Error_Message: %d\nDTX setting not valid, use 0 or 1\n", errcode);  			break; 		case SKP_SILK_ENC_INTERNAL_ERROR: 			__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,  				"!!!!!!!!!!! Decode_Error_Message: %d\nInternal encoder error\n", errcode);  			break;				 	} }  extern "C" JNIEXPORT jint JNICALL Java_com_trunkbow_silk_SILK16_encode     (JNIEnv *env, jobject obj, jshortArray lin, jint offset, jbyteArray encoded, jint size) {      jbyte	  enc_payload[ MAX_BYTES_DEC_PER_FRAME * MAX_INPUT_FRAMES ];     jshort    in[ MAX_FRAME_LENGTH * MAX_INPUT_FRAMES ];	 	int ret,i,frsz=MAX_FRAME; 	SKP_int16 nBytes; 	unsigned int lin_pos = 0; 	 	if (!codec_open) 		return 0; 		 #ifdef DEBUG_SILK16     __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,              "encoding frame size: %d\toffset: %d\n", size, offset); 		 #endif   	for (i = 0; i < size; i+=MAX_FRAME) { #ifdef DEBUG_SILK16 		__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,              "encoding frame size: %d\toffset: %d i: %d\n", size, offset, i); 		 #endif 			 		env->GetShortArrayRegion(lin, offset + i,frsz, in);         /* max payload size */         nBytes = MAX_BYTES_ENC_PER_FRAME * MAX_INPUT_FRAMES;          ret = SKP_Silk_SDK_Encode( psEnc, &encControl, in, (SKP_int16)frsz, (SKP_uint8 *)enc_payload, &nBytes );         if( ret ) { 			__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,  				"!!!!!!!! SKP_Silk_Encode returned: %d\n", ret); 			Print_Encode_Error_Msg(ret);					             break;         } #ifdef DEBUG_SILK16 			__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,  				"Enocded nBytes: %d\n", nBytes); 		 #endif		         /* Write payload */		 		env->SetByteArrayRegion(encoded, RTP_HDR_SIZE+ lin_pos, nBytes, enc_payload); 		lin_pos += nBytes; 	} #ifdef DEBUG_SILK16 	__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,          "encoding **END** frame size: %d\toffset: %d i: %d lin_pos: %d\n", size, offset, i, lin_pos); #endif		      return (jint)lin_pos; }  extern "C" JNIEXPORT jint JNICALL Java_com_trunkbow_silk_SILK16_decode     (JNIEnv *env, jobject obj, jbyteArray encoded, jshortArray lin, jint size) {      jbyte buffer [MAX_BYTES_DEC_PER_FRAME * MAX_INPUT_FRAMES * ( MAX_LBRR_DELAY + 1 ) ];     jshort output_buffer[( MAX_FRAME_LENGTH << 1 ) * MAX_INPUT_FRAMES ]; //	SKP_int16	*outPtr;  	int ret; 	SKP_int16 len; //	int	tot_len,frames;  	if (!codec_open) 		return 0;  #ifdef DEBUG_SILK16		 	__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,          "##### BEGIN DECODE ********  decoding frame size: %d\n", size); 	 #endif  	env->GetByteArrayRegion(encoded, RTP_HDR_SIZE, size, buffer);  //	outPtr = output_buffer; //    tot_len = 0; //	frames = 0;  //	do { 		ret = SKP_Silk_SDK_Decode( psDec, &DecControl, 0,(SKP_uint8 *) buffer, size, output_buffer,&len ); 		if( ret ) { 			__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,  				"!!!!!!!! SKP_Silk_SDK_Decode returned: %d\n", ret); 	 			Print_Decode_Error_Msg(ret); 		} #ifdef DEBUG_SILK16		 		__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,  			"##### DECODED length: %d\n\t Frame #: %d", len); 	 #endif //		frames++; //		outPtr  += len; //		tot_len += len;		 	 //	} while( DecControl.moreInternalDecoderFrames );  	env->SetShortArrayRegion(lin, 0, len,output_buffer); 	return (jint)len; }  extern "C" JNIEXPORT void JNICALL Java_com_trunkbow_silk_SILK16_close     (JNIEnv *env, jobject obj) {  	if (--codec_open != 0) 		return;     /* Free decoder */     free( psDec );     /* Free Encoder */     free( psEnc ); } 


         silk24_jni.cpp

        

#include <jni.h>  #include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h>  /* Define codec specific settings */ #define MAX_BYTES_ENC_PER_FRAME     250 // Equals peak bitrate of 100 kbps  #define MAX_BYTES_DEC_PER_FRAME     1024  #define MAX_INPUT_FRAMES        5 #define MAX_LBRR_DELAY          2 #define MAX_FRAME_LENGTH        480  #define	MAX_FRAME			480  #include <android/log.h>   #define LOG_TAG "silk" // text for log tag   #include "SKP_Silk_SDK_API.h" #include "SKP_Silk_SigProc_FIX.h"  #undef DEBUG_SILK24  // the header length of the RTP frame (must skip when en/decoding) #define	RTP_HDR_SIZE	12  static int codec_open = 0;  static JavaVM *gJavaVM; const char *kInterfacePath = "org/sipdroid/pjlib/SILK24";  /* encoder parameters */      SKP_int32 encSizeBytes;     void      *psEnc;      /* default settings */     SKP_int   fs_kHz = 24;     SKP_int   targetRate_bps = 20000;     SKP_int   packetSize_ms = 20;     SKP_int   frameSizeReadFromFile_ms = 20;     SKP_int   packetLoss_perc = 0, smplsSinceLastPacket;     SKP_int   INBandFec_enabled = 0, DTX_enabled = 0, quiet = 0;     SKP_SILK_SDK_EncControlStruct encControl; // Struct for input to encoder           /* decoder parameters */      jbyte payloadToDec[    MAX_BYTES_DEC_PER_FRAME * MAX_INPUT_FRAMES * ( MAX_LBRR_DELAY + 1 ) ];     jshort out[ ( MAX_FRAME_LENGTH << 1 ) * MAX_INPUT_FRAMES ], *outPtr;     SKP_int32 decSizeBytes;     void      *psDec;     SKP_SILK_SDK_DecControlStruct DecControl;  extern "C" JNIEXPORT jint JNICALL Java_com_trunkbow_silk_SILK24_open   (JNIEnv *env, jobject obj, jint compression) { 	int ret;  	if (codec_open++ != 0) 		return (jint)0;  	/* Set the samplingrate that is requested for the output */     DecControl.sampleRate = 24000; 		     /* Create decoder */     ret = SKP_Silk_SDK_Get_Decoder_Size( &decSizeBytes );     if( ret ) { 		__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,              "\n!!!!!!!! SKP_Silk_SDK_Get_Decoder_Size returned %d", ret );		     } #ifdef DEBUG_SILK24     __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,              "### INIT Decoder decSizeBytes = %d\n", decSizeBytes); 		 #endif	     psDec = malloc( decSizeBytes );      /* Reset decoder */     ret = SKP_Silk_SDK_InitDecoder( psDec );     if( ret ) { 		__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,              "\n!!!!!!!! SKP_Silk_InitDecoder returned %d", ret );	     }       /* Create Encoder */     ret = SKP_Silk_SDK_Get_Encoder_Size( &encSizeBytes );     if( ret ) { 		__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,              "\n!!!!!!!! SKP_Silk_SDK_Get_Encoder_Size returned %d", ret );	     } #ifdef DEBUG_SILK24     __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,              "### INIT Encoder encSizeBytes = %d\n", encSizeBytes); 		 #endif		     psEnc = malloc( encSizeBytes );          /* Reset Encoder */     ret = SKP_Silk_SDK_InitEncoder( psEnc, &encControl );     if( ret ) { 		__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,              "\n!!!!!!!! SKP_Silk_SDK_InitEncoder returned %d", ret );	 	}          /* Set Encoder parameters */     encControl.sampleRate           = fs_kHz * 1000;     encControl.packetSize           = packetSize_ms * fs_kHz;     encControl.packetLossPercentage = packetLoss_perc;     encControl.useInBandFEC         = INBandFec_enabled;     encControl.useDTX               = DTX_enabled;     encControl.complexity           = compression;     encControl.bitRate              = targetRate_bps;		 	 	return (jint)0; }  void Print_Decode_Error_Msg(int errcode) { 	switch (errcode) { 		case SKP_SILK_DEC_WRONG_SAMPLING_FREQUENCY: 			__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,  				"!!!!!!!!!!! Decode_Error_Message: %d\nOutput sampling frequency lower than internal decoded sampling frequency\n", errcode); 			break; 		case SKP_SILK_DEC_PAYLOAD_TOO_LARGE: 			__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,  				"!!!!!!!!!!! Decode_Error_Message: %d\nPayload size exceeded the maximum allowed 1024 bytes\n", errcode);  			break; 		case SKP_SILK_DEC_PAYLOAD_ERROR: 			__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,  				"!!!!!!!!!!! Decode_Error_Message: %d\nPayload has bit errors\n", errcode);  			break;			 	} }  void Print_Encode_Error_Msg(int errcode) { 	switch (errcode) { 		case SKP_SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES: 			__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,  				"!!!!!!!!!!! Decode_Error_Message: %d\nInput length is not a multiplum of 10 ms, or length is longer than the packet length\n", errcode); 			break; 		case SKP_SILK_ENC_FS_NOT_SUPPORTED: 			__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,  				"!!!!!!!!!!! Decode_Error_Message: %d\nSampling frequency not 8000, 12000, 16000 or 24000 Hertz \n", errcode);  			break; 		case SKP_SILK_ENC_PACKET_SIZE_NOT_SUPPORTED: 			__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,  				"!!!!!!!!!!! Decode_Error_Message: %d\nPacket size not 20, 40, 60, 80 or 100 ms\n", errcode);  			break;			 		case SKP_SILK_ENC_PAYLOAD_BUF_TOO_SHORT: 			__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,  				"!!!!!!!!!!! Decode_Error_Message: %d\nAllocated payload buffer too short \n", errcode); 			break; 		case SKP_SILK_ENC_WRONG_LOSS_RATE: 			__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,  				"!!!!!!!!!!! Decode_Error_Message: %d\nLoss rate not between 0 and 100 percent\n", errcode);  			break; 		case SKP_SILK_ENC_WRONG_COMPLEXITY_SETTING: 			__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,  				"!!!!!!!!!!! Decode_Error_Message: %d\nComplexity setting not valid, use 0, 1 or 2\n", errcode);  			break;		 		case SKP_SILK_ENC_WRONG_INBAND_FEC_SETTING: 			__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,  				"!!!!!!!!!!! Decode_Error_Message: %d\nInband FEC setting not valid, use 0 or 1\n", errcode); 			break; 		case SKP_SILK_ENC_WRONG_DTX_SETTING: 			__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,  				"!!!!!!!!!!! Decode_Error_Message: %d\nDTX setting not valid, use 0 or 1\n", errcode);  			break; 		case SKP_SILK_ENC_INTERNAL_ERROR: 			__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,  				"!!!!!!!!!!! Decode_Error_Message: %d\nInternal encoder error\n", errcode);  			break;				 	} }  extern "C" JNIEXPORT jint JNICALL Java_com_trunkbow_silk_SILK24_encode     (JNIEnv *env, jobject obj, jshortArray lin, jint offset, jbyteArray encoded, jint size) {      jbyte	  enc_payload[ MAX_BYTES_DEC_PER_FRAME * MAX_INPUT_FRAMES ];     jshort    in[ MAX_FRAME_LENGTH * MAX_INPUT_FRAMES ];	 	int ret,i,frsz=MAX_FRAME; 	SKP_int16 nBytes; 	unsigned int lin_pos = 0; 	 	if (!codec_open) 		return 0; 		 #ifdef DEBUG_SILK24     __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,              "encoding frame size: %d\toffset: %d\n", size, offset); 		 #endif   	for (i = 0; i < size; i+=MAX_FRAME) { #ifdef DEBUG_SILK24 		__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,              "encoding frame size: %d\toffset: %d i: %d\n", size, offset, i); 		 #endif 			 		env->GetShortArrayRegion(lin, offset + i,frsz, in);         /* max payload size */         nBytes = MAX_BYTES_ENC_PER_FRAME * MAX_INPUT_FRAMES;          ret = SKP_Silk_SDK_Encode( psEnc, &encControl, in, (SKP_int16)frsz, (SKP_uint8 *)enc_payload, &nBytes );         if( ret ) { 			__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,  				"!!!!!!!! SKP_Silk_Encode returned: %d\n", ret); 			Print_Encode_Error_Msg(ret);				             break;         } #ifdef DEBUG_SILK24 			__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,  				"Enocded nBytes: %d\n", nBytes); 		 #endif		         /* Write payload */		 		env->SetByteArrayRegion(encoded, RTP_HDR_SIZE+ lin_pos, nBytes, enc_payload); 		lin_pos += nBytes; 	} #ifdef DEBUG_SILK24 	__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,          "encoding **END** frame size: %d\toffset: %d i: %d lin_pos: %d\n", size, offset, i, lin_pos); #endif		      return (jint)lin_pos; }  extern "C" JNIEXPORT jint JNICALL Java_com_trunkbow_silk_SILK24_decode     (JNIEnv *env, jobject obj, jbyteArray encoded, jshortArray lin, jint size) {      jbyte buffer [MAX_BYTES_DEC_PER_FRAME * MAX_INPUT_FRAMES * ( MAX_LBRR_DELAY + 1 ) ];     jshort output_buffer[( MAX_FRAME_LENGTH << 1 ) * MAX_INPUT_FRAMES ]; //	SKP_int16	*outPtr;  	int ret; 	SKP_int16 len; //	int	tot_len,frames;  	if (!codec_open) 		return 0;  #ifdef DEBUG_SILK24		 	__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,          "##### BEGIN DECODE ********  decoding frame size: %d\n", size); 	 #endif  	env->GetByteArrayRegion(encoded, RTP_HDR_SIZE, size, buffer);  //	outPtr = output_buffer; //    tot_len = 0; //	frames = 0;  //	do { 		ret = SKP_Silk_SDK_Decode( psDec, &DecControl, 0,(SKP_uint8 *) buffer, size, output_buffer,&len ); 		if( ret ) { 			__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,  				"!!!!!!!! SKP_Silk_SDK_Decode returned: %d\n", ret); 	 			Print_Decode_Error_Msg(ret); 		} #ifdef DEBUG_SILK24		 		__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,  			"##### DECODED length: %d\n\t Frame #: %d", len); 	 #endif //		frames++; //		outPtr  += len; //		tot_len += len;		 	 //	} while( DecControl.moreInternalDecoderFrames );  	env->SetShortArrayRegion(lin, 0, len,output_buffer); 	return (jint)len; }  extern "C" JNIEXPORT void JNICALL Java_com_trunkbow_silk_SILK24_close     (JNIEnv *env, jobject obj) {  	if (--codec_open != 0) 		return;     /* Free decoder */     free( psDec );     /* Free Encoder */     free( psEnc ); } 


    

        6、在Java层创建Speex工具类,内容如下:

           Silk8.java:

        

class SILK8{    	/*  	 *                 | fs (Hz) | BR (kbps) 	 * ----------------+---------+--------- 	 * Narrowband	   | 8000    | 6 -20 	 * Mediumband      | 12000   | 7 -25 	 * Wideband        | 16000   | 8 -30 	 * Super Wideband  | 24000   | 12 -40 	 * 	 * Table 1: fs specifies the audio sampling frequency in Hertz (Hz); BR 	 * specifies the adaptive bit rate range in kilobits per second (kbps). 	 *  	 * Complexity can be scaled to optimize for CPU resources in real-time, 	 * mostly in trade-off to network bit rate. 0 is least CPU demanding and 	 * highest bit rate.  	 */ 	private static final int DEFAULT_COMPLEXITY = 0; 	 	void load() { 		 System.loadLibrary("silk8_jni"); 	}     	public native int open(int compression); 	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(); } 


         Silk16.java:

class SILK16 {  	/*  	 *                 | fs (Hz) | BR (kbps) 	 * ----------------+---------+--------- 	 * Narrowband	   | 8000    | 6 -20 	 * Mediumband      | 12000   | 7 -25 	 * Wideband        | 16000   | 8 -30 	 * Super Wideband  | 24000   | 12 -40 	 * 	 * Table 1: fs specifies the audio sampling frequency in Hertz (Hz); BR 	 * specifies the adaptive bit rate range in kilobits per second (kbps). 	 *  	 * Complexity can be scaled to optimize for CPU resources in real-time, 	 * mostly in trade-off to network bit rate. 0 is least CPU demanding and 	 * highest bit rate.  	 */ 	private static final int DEFAULT_COMPLEXITY = 0;   	void load() { 		System.loadLibrary("silk16_jni"); 	}     	public native int open(int compression); 	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();  } 


Silk24.java:

class SILK24  {  	/*  	 *                 | fs (Hz) | BR (kbps) 	 * ----------------+---------+--------- 	 * Narrowband	   | 8000    | 6 -20 	 * Mediumband      | 12000   | 7 -25 	 * Wideband        | 16000   | 8 -30 	 * Super Wideband  | 24000   | 12 -40 	 * 	 * Table 1: fs specifies the audio sampling frequency in Hertz (Hz); BR 	 * specifies the adaptive bit rate range in kilobits per second (kbps). 	 *  	 * Complexity can be scaled to optimize for CPU resources in real-time, 	 * mostly in trade-off to network bit rate. 0 is least CPU demanding and 	 * highest bit rate.  	 */ 	private static final int DEFAULT_COMPLEXITY = 0;  	void load() { 		System.loadLibrary("silk24_jni"); 	}     	public native int open(int compression); 	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();  } 


           7、使用cygwin编译,生成so文件。       


  ***********************************************************************

  * 转载务必在明显处注明:http://blog.csdn.net/xyz_lmn    *

  * 作者:张兴业                                                                                           *

  * 邮箱:xy-zhang@163.com                                                                   *

  ***********************************************************************


参考:http://developer.skype.com/silk

http://blog.csdn.net/wanggp_2007/article/details/5540686    Skype SILK vs. iLBC vs. Speex



     本文转自xyz_lmn51CTO博客,原文链接: http://blog.51cto.com/xyzlmn/1230784 ,如需转载请自行联系原作者


相关文章
|
Android开发
flutter中实现仿Android端的onResume和onPause方法
flutter中实现仿Android端的onResume和onPause方法
|
Android开发 容器
Android实现面包屑效果,支持Fragment联动
Android实现面包屑效果,支持Fragment联动
|
Android开发
Android实现连线题效果
Android实现连线题效果
|
Android开发
Android实现调用系统相机录像及实现录音
Android实现调用系统相机录像及实现录音
581 0
|
移动开发 JavaScript Android开发
通过howler.js实现在Android下的微信浏览器自动播放音频
通过howler.js实现在Android下的微信浏览器自动播放音频
399 0
通过howler.js实现在Android下的微信浏览器自动播放音频
|
存储 Dart Java
【Flutter】packages思维以及使用Java添加Android平台特定的实现在Flutter框架里的体现和运用
【Flutter】packages思维以及使用Java添加Android平台特定的实现在Flutter框架里的体现和运用
|
缓存 JSON Java
java 实现读取txt文件,反射创建对象,android 手机缓存文件目录
java 实现读取txt文件,反射创建对象,android 手机缓存文件目录
335 1
java 实现读取txt文件,反射创建对象,android 手机缓存文件目录
|
数据库 Android开发
android 多级下拉菜单实现教程 greendao使用
android 多级下拉菜单实现教程 greendao使用
169 0
android 多级下拉菜单实现教程 greendao使用
|
XML 开发工具 Android开发
Android自定义控件(十三)——实现CSDN搜索框文字提示容器
Android自定义控件(十三)——实现CSDN搜索框文字提示容器
264 0
Android自定义控件(十三)——实现CSDN搜索框文字提示容器
|
XML Android开发 数据格式
Android自定义控件(十一)——自定义ViewGroup实现LinearLayout
Android自定义控件(十一)——自定义ViewGroup实现LinearLayout
419 0