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文件,编辑内容如下

   

[plain] view plain copy
  1. LOCAL_PATH := $(call my-dir)  
  2.    
  3. include $(CLEAR_VARS)  
  4. SILK     := silk  
  5. LOCAL_MODULE    := silkcommon  
  6. LOCAL_SRC_FILES :=  $(SILK)/src/SKP_Silk_A2NLSF.c \  
  7.     $(SILK)/src/SKP_Silk_CNG.c \  
  8.     $(SILK)/src/SKP_Silk_HP_variable_cutoff_FIX.c \  
  9.     $(SILK)/src/SKP_Silk_LBRR_reset.c \  
  10.     $(SILK)/src/SKP_Silk_LPC_inv_pred_gain.c \  
  11.     $(SILK)/src/SKP_Silk_LPC_stabilize.c \  
  12.     $(SILK)/src/SKP_Silk_LPC_synthesis_filter.c \  
  13.     $(SILK)/src/SKP_Silk_LPC_synthesis_order16.c \  
  14.     $(SILK)/src/SKP_Silk_LP_variable_cutoff.c \  
  15.     $(SILK)/src/SKP_Silk_LSF_cos_table.c \  
  16.     $(SILK)/src/SKP_Silk_LTP_analysis_filter_FIX.c \  
  17.     $(SILK)/src/SKP_Silk_LTP_scale_ctrl_FIX.c \  
  18.     $(SILK)/src/SKP_Silk_MA.c \  
  19.     $(SILK)/src/SKP_Silk_NLSF2A.c \  
  20.     $(SILK)/src/SKP_Silk_NLSF2A_stable.c \  
  21.     $(SILK)/src/SKP_Silk_NLSF_MSVQ_decode.c \  
  22.     $(SILK)/src/SKP_Silk_NLSF_MSVQ_encode_FIX.c \  
  23.     $(SILK)/src/SKP_Silk_NLSF_VQ_rate_distortion_FIX.c \  
  24.     $(SILK)/src/SKP_Silk_NLSF_VQ_sum_error_FIX.c \  
  25.     $(SILK)/src/SKP_Silk_NLSF_VQ_weights_laroia.c \  
  26.     $(SILK)/src/SKP_Silk_NLSF_stabilize.c \  
  27.     $(SILK)/src/SKP_Silk_NSQ.c \  
  28.     $(SILK)/src/SKP_Silk_NSQ_del_dec.c \  
  29.     $(SILK)/src/SKP_Silk_PLC.c \  
  30.     $(SILK)/src/SKP_Silk_VAD.c \  
  31.     $(SILK)/src/SKP_Silk_VQ_nearest_neighbor_FIX.c \  
  32.     $(SILK)/src/SKP_Silk_allpass_int.c \  
  33.     $(SILK)/src/SKP_Silk_ana_filt_bank_1.c \  
  34.     $(SILK)/src/SKP_Silk_apply_sine_window.c \  
  35.     $(SILK)/src/SKP_Silk_array_maxabs.c \  
  36.     $(SILK)/src/SKP_Silk_autocorr.c \  
  37.     $(SILK)/src/SKP_Silk_biquad.c \  
  38.     $(SILK)/src/SKP_Silk_biquad_alt.c \  
  39.     $(SILK)/src/SKP_Silk_burg_modified.c \  
  40.     $(SILK)/src/SKP_Silk_bwexpander.c \  
  41.     $(SILK)/src/SKP_Silk_bwexpander_32.c \  
  42.     $(SILK)/src/SKP_Silk_code_signs.c \  
  43.     $(SILK)/src/SKP_Silk_control_codec_FIX.c \  
  44.     $(SILK)/src/SKP_Silk_corrMatrix_FIX.c \  
  45.     $(SILK)/src/SKP_Silk_create_init_destroy.c \  
  46.     $(SILK)/src/SKP_Silk_dec_API.c \  
  47.     $(SILK)/src/SKP_Silk_decode_core.c \  
  48.     $(SILK)/src/SKP_Silk_decode_frame.c \  
  49.     $(SILK)/src/SKP_Silk_decode_indices_v4.c \  
  50.     $(SILK)/src/SKP_Silk_decode_parameters.c \  
  51.     $(SILK)/src/SKP_Silk_decode_parameters_v4.c \  
  52.     $(SILK)/src/SKP_Silk_decode_pulses.c \  
  53.     $(SILK)/src/SKP_Silk_decoder_set_fs.c \  
  54.     $(SILK)/src/SKP_Silk_detect_SWB_input.c \  
  55.     $(SILK)/src/SKP_Silk_enc_API.c \  
  56.     $(SILK)/src/SKP_Silk_encode_frame_FIX.c \  
  57.     $(SILK)/src/SKP_Silk_encode_parameters.c \  
  58.     $(SILK)/src/SKP_Silk_encode_parameters_v4.c \  
  59.     $(SILK)/src/SKP_Silk_encode_pulses.c \  
  60.     $(SILK)/src/SKP_Silk_find_LPC_FIX.c \  
  61.     $(SILK)/src/SKP_Silk_find_LTP_FIX.c \  
  62.     $(SILK)/src/SKP_Silk_find_pitch_lags_FIX.c \  
  63.     $(SILK)/src/SKP_Silk_find_pred_coefs_FIX.c \  
  64.     $(SILK)/src/SKP_Silk_gain_quant.c \  
  65.     $(SILK)/src/SKP_Silk_init_encoder_FIX.c \  
  66.     $(SILK)/src/SKP_Silk_inner_prod_aligned.c \  
  67.     $(SILK)/src/SKP_Silk_interpolate.c \  
  68.     $(SILK)/src/SKP_Silk_k2a.c \  
  69.     $(SILK)/src/SKP_Silk_k2a_Q16.c \  
  70.     $(SILK)/src/SKP_Silk_lin2log.c \  
  71.     $(SILK)/src/SKP_Silk_log2lin.c \  
  72.     $(SILK)/src/SKP_Silk_lowpass_int.c \  
  73.     $(SILK)/src/SKP_Silk_lowpass_short.c \  
  74.     $(SILK)/src/SKP_Silk_noise_shape_analysis_FIX.c \  
  75.     $(SILK)/src/SKP_Silk_pitch_analysis_core.c \  
  76.     $(SILK)/src/SKP_Silk_pitch_est_tables.c \  
  77.     $(SILK)/src/SKP_Silk_prefilter_FIX.c \  
  78.     $(SILK)/src/SKP_Silk_process_NLSFs_FIX.c \  
  79.     $(SILK)/src/SKP_Silk_process_gains_FIX.c \  
  80.     $(SILK)/src/SKP_Silk_pulses_to_bytes.c \  
  81.     $(SILK)/src/SKP_Silk_quant_LTP_gains_FIX.c \  
  82.     $(SILK)/src/SKP_Silk_range_coder.c \  
  83.     $(SILK)/src/SKP_Silk_regularize_correlations_FIX.c \  
  84.     $(SILK)/src/SKP_Silk_resample_1_2.c \  
  85.     $(SILK)/src/SKP_Silk_resample_1_2_coarse.c \  
  86.     $(SILK)/src/SKP_Silk_resample_1_2_coarsest.c \  
  87.     $(SILK)/src/SKP_Silk_resample_1_3.c \  
  88.     $(SILK)/src/SKP_Silk_resample_2_1_coarse.c \  
  89.     $(SILK)/src/SKP_Silk_resample_2_3.c \  
  90.     $(SILK)/src/SKP_Silk_resample_2_3_coarse.c \  
  91.     $(SILK)/src/SKP_Silk_resample_2_3_coarsest.c \  
  92.     $(SILK)/src/SKP_Silk_resample_2_3_rom.c \  
  93.     $(SILK)/src/SKP_Silk_resample_3_1.c \  
  94.     $(SILK)/src/SKP_Silk_resample_3_2.c \  
  95.     $(SILK)/src/SKP_Silk_resample_3_2_rom.c \  
  96.     $(SILK)/src/SKP_Silk_resample_3_4.c \  
  97.     $(SILK)/src/SKP_Silk_resample_4_3.c \  
  98.     $(SILK)/src/SKP_Silk_residual_energy16_FIX.c \  
  99.     $(SILK)/src/SKP_Silk_residual_energy_FIX.c \  
  100.     $(SILK)/src/SKP_Silk_scale_copy_vector16.c \  
  101.     $(SILK)/src/SKP_Silk_scale_vector.c \  
  102.     $(SILK)/src/SKP_Silk_schur.c \  
  103.     $(SILK)/src/SKP_Silk_schur64.c \  
  104.     $(SILK)/src/SKP_Silk_shell_coder.c \  
  105.     $(SILK)/src/SKP_Silk_sigm_Q15.c \  
  106.     $(SILK)/src/SKP_Silk_solve_LS_FIX.c \  
  107.     $(SILK)/src/SKP_Silk_sort.c \  
  108.     $(SILK)/src/SKP_Silk_sum_sqr_shift.c \  
  109.     $(SILK)/src/SKP_Silk_tables_LTP.c \  
  110.     $(SILK)/src/SKP_Silk_tables_NLSF_CB0_10.c \  
  111.     $(SILK)/src/SKP_Silk_tables_NLSF_CB0_16.c \  
  112.     $(SILK)/src/SKP_Silk_tables_NLSF_CB1_10.c \  
  113.     $(SILK)/src/SKP_Silk_tables_NLSF_CB1_16.c \  
  114.     $(SILK)/src/SKP_Silk_tables_gain.c \  
  115.     $(SILK)/src/SKP_Silk_tables_other.c \  
  116.     $(SILK)/src/SKP_Silk_tables_pitch_lag.c \  
  117.     $(SILK)/src/SKP_Silk_tables_pulses_per_block.c \  
  118.     $(SILK)/src/SKP_Silk_tables_sign.c \  
  119.     $(SILK)/src/SKP_Silk_tables_type_offset.c  
  120.       
  121. LOCAL_ARM_MODE := arm  
  122. LOCAL_CFLAGS = -O3   
  123. LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -llog  
  124. LOCAL_C_INCLUDES += $(LOCAL_PATH)/$(SILK)/src $(LOCAL_PATH)/$(SILK)/interface  
  125. include $(BUILD_STATIC_LIBRARY)  
  126.   
  127.   
  128. include $(CLEAR_VARS)  
  129. LOCAL_MODULE    := silk8_jni  
  130. LOCAL_SRC_FILES := silk8_jni.cpp   
  131. LOCAL_C_INCLUDES += $(LOCAL_PATH)/$(SILK)/src $(LOCAL_PATH)/$(SILK)/interface  
  132. LOCAL_CFLAGS = -O3   
  133. LOCAL_STATIC_LIBRARIES :=  silkcommon  
  134. LOCAL_ARM_MODE := arm  
  135. LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -llog  
  136. include $(BUILD_SHARED_LIBRARY)  
  137.   
  138. include $(CLEAR_VARS)  
  139. LOCAL_MODULE    := silk16_jni  
  140. LOCAL_SRC_FILES := silk16_jni.cpp   
  141. LOCAL_C_INCLUDES += $(LOCAL_PATH)/$(SILK)/src $(LOCAL_PATH)/$(SILK)/interface  
  142. LOCAL_CFLAGS = -O3   
  143. LOCAL_STATIC_LIBRARIES :=  silkcommon  
  144. LOCAL_ARM_MODE := arm  
  145. LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -llog  
  146. include $(BUILD_SHARED_LIBRARY)  
  147.   
  148. include $(CLEAR_VARS)  
  149. LOCAL_MODULE    := silk24_jni  
  150. LOCAL_SRC_FILES := silk24_jni.cpp   
  151. LOCAL_C_INCLUDES += $(LOCAL_PATH)/$(SILK)/src $(LOCAL_PATH)/$(SILK)/interface  
  152. LOCAL_CFLAGS = -O3   
  153. LOCAL_STATIC_LIBRARIES :=  silkcommon  
  154. LOCAL_ARM_MODE := arm  
  155. LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -llog  
  156. include $(BUILD_SHARED_LIBRARY)  


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

      silk8_jni.cpp:

    

[cpp] view plain copy
  1. #include <jni.h>  
  2.   
  3. #include <stdio.h>  
  4. #include <stdlib.h>  
  5. #include <string.h>  
  6. #include <math.h>  
  7.   
  8. /* Define codec specific settings */  
  9. #define MAX_BYTES_ENC_PER_FRAME     250 // Equals peak bitrate of 100 kbps   
  10. #define MAX_BYTES_DEC_PER_FRAME     1024  
  11.   
  12. #define MAX_INPUT_FRAMES        5  
  13. #define MAX_LBRR_DELAY          2  
  14. #define MAX_FRAME_LENGTH        480  
  15.   
  16. #define MAX_FRAME           160  
  17.   
  18. #include <android/log.h>   
  19.   
  20. #define LOG_TAG "silk" // text for log tag   
  21.   
  22. #include "SKP_Silk_SDK_API.h"  
  23. #include "SKP_Silk_SigProc_FIX.h"  
  24.   
  25. #undef DEBUG_SILK8  
  26.   
  27. // the header length of the RTP frame (must skip when en/decoding)  
  28. #define RTP_HDR_SIZE    12  
  29.   
  30. static int codec_open = 0;  
  31.   
  32. static JavaVM *gJavaVM;  
  33. const char *kInterfacePath = "org/sipdroid/pjlib/silk8";  
  34.   
  35. /* encoder parameters */  
  36.   
  37.     SKP_int32 encSizeBytes;  
  38.     void      *psEnc;  
  39.   
  40.     /* default settings */  
  41.     SKP_int   fs_kHz = 8;  
  42.     SKP_int   targetRate_bps = 20000;  
  43.     SKP_int   packetSize_ms = 20;  
  44.     SKP_int   frameSizeReadFromFile_ms = 20;  
  45.     SKP_int   packetLoss_perc = 0, smplsSinceLastPacket;  
  46.     SKP_int   INBandFec_enabled = 0, DTX_enabled = 0, quiet = 0;  
  47.     SKP_SILK_SDK_EncControlStruct encControl; // Struct for input to encoder  
  48.           
  49.   
  50. /* decoder parameters */  
  51.   
  52.     jbyte payloadToDec[    MAX_BYTES_DEC_PER_FRAME * MAX_INPUT_FRAMES * ( MAX_LBRR_DELAY + 1 ) ];  
  53.     jshort out[ ( MAX_FRAME_LENGTH << 1 ) * MAX_INPUT_FRAMES ], *outPtr;  
  54.     SKP_int32 decSizeBytes;  
  55.     void      *psDec;  
  56.     SKP_SILK_SDK_DecControlStruct DecControl;  
  57.   
  58. extern "C"  
  59. JNIEXPORT jint JNICALL Java_com_trunkbow_silk_SILK8_open  
  60.   (JNIEnv *env, jobject obj, jint compression) {  
  61.     int ret;  
  62.   
  63.     if (codec_open++ != 0)  
  64.         return (jint)0;  
  65.   
  66.     /* Set the samplingrate that is requested for the output */  
  67.     DecControl.sampleRate = 8000;  
  68.           
  69.     /* Create decoder */  
  70.     ret = SKP_Silk_SDK_Get_Decoder_Size( &decSizeBytes );  
  71.     if( ret ) {  
  72.         __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,   
  73.             "\n!!!!!!!! SKP_Silk_SDK_Get_Decoder_Size returned %d", ret );        
  74.     }  
  75. #ifdef DEBUG_SILK8  
  76.     __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,   
  77.             "### INIT Decoder decSizeBytes = %d\n", decSizeBytes);        
  78. #endif    
  79.     psDec = malloc( decSizeBytes );  
  80.   
  81.     /* Reset decoder */  
  82.     ret = SKP_Silk_SDK_InitDecoder( psDec );  
  83.     if( ret ) {  
  84.         __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,   
  85.             "\n!!!!!!!! SKP_Silk_InitDecoder returned %d", ret );     
  86.     }  
  87.   
  88.   
  89.     /* Create Encoder */  
  90.     ret = SKP_Silk_SDK_Get_Encoder_Size( &encSizeBytes );  
  91.     if( ret ) {  
  92.         __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,   
  93.             "\n!!!!!!!! SKP_Silk_SDK_Get_Encoder_Size returned %d", ret );    
  94.     }  
  95. #ifdef DEBUG_SILK8  
  96.     __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,   
  97.             "### INIT Encoder encSizeBytes = %d\n", encSizeBytes);        
  98. #endif        
  99.     psEnc = malloc( encSizeBytes );  
  100.       
  101.     /* Reset Encoder */  
  102.     ret = SKP_Silk_SDK_InitEncoder( psEnc, &encControl );  
  103.     if( ret ) {  
  104.         __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,   
  105.             "\n!!!!!!!! SKP_Silk_SDK_InitEncoder returned %d", ret );     
  106.     }  
  107.       
  108.     /* Set Encoder parameters */  
  109.     encControl.sampleRate           = fs_kHz * 1000;  
  110.     encControl.packetSize           = packetSize_ms * fs_kHz;  
  111.     encControl.packetLossPercentage = packetLoss_perc;  
  112.     encControl.useInBandFEC         = INBandFec_enabled;  
  113.     encControl.useDTX               = DTX_enabled;  
  114.     encControl.complexity           = compression;  
  115.     encControl.bitRate              = targetRate_bps;         
  116.       
  117.     return (jint)0;  
  118. }  
  119.   
  120. void Print_Decode_Error_Msg(int errcode) {  
  121.     switch (errcode) {  
  122.         case SKP_SILK_DEC_WRONG_SAMPLING_FREQUENCY:  
  123.             __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,   
  124.                 "!!!!!!!!!!! Decode_Error_Message: %d\nOutput sampling frequency lower than internal decoded sampling frequency\n", errcode);  
  125.             break;  
  126.         case SKP_SILK_DEC_PAYLOAD_TOO_LARGE:  
  127.             __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,   
  128.                 "!!!!!!!!!!! Decode_Error_Message: %d\nPayload size exceeded the maximum allowed 1024 bytes\n", errcode);   
  129.             break;  
  130.         case SKP_SILK_DEC_PAYLOAD_ERROR:  
  131.             __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,   
  132.                 "!!!!!!!!!!! Decode_Error_Message: %d\nPayload has bit errors\n", errcode);   
  133.             break;            
  134.     }  
  135. }  
  136.   
  137. void Print_Encode_Error_Msg(int errcode) {  
  138.     switch (errcode) {  
  139.         case SKP_SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES:  
  140.             __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,   
  141.                 "!!!!!!!!!!! Decode_Error_Message: %d\nInput length is not a multiplum of 10 ms, or length is longer than the packet length\n", errcode);  
  142.             break;  
  143.         case SKP_SILK_ENC_FS_NOT_SUPPORTED:  
  144.             __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,   
  145.                 "!!!!!!!!!!! Decode_Error_Message: %d\nSampling frequency not 8000, 12000, 16000 or 24000 Hertz \n", errcode);   
  146.             break;  
  147.         case SKP_SILK_ENC_PACKET_SIZE_NOT_SUPPORTED:  
  148.             __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,   
  149.                 "!!!!!!!!!!! Decode_Error_Message: %d\nPacket size not 20, 40, 60, 80 or 100 ms\n", errcode);   
  150.             break;            
  151.         case SKP_SILK_ENC_PAYLOAD_BUF_TOO_SHORT:  
  152.             __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,   
  153.                 "!!!!!!!!!!! Decode_Error_Message: %d\nAllocated payload buffer too short \n", errcode);  
  154.             break;  
  155.         case SKP_SILK_ENC_WRONG_LOSS_RATE:  
  156.             __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,   
  157.                 "!!!!!!!!!!! Decode_Error_Message: %d\nLoss rate not between 0 and 100 percent\n", errcode);   
  158.             break;  
  159.         case SKP_SILK_ENC_WRONG_COMPLEXITY_SETTING:  
  160.             __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,   
  161.                 "!!!!!!!!!!! Decode_Error_Message: %d\nComplexity setting not valid, use 0, 1 or 2\n", errcode);   
  162.             break;        
  163.         case SKP_SILK_ENC_WRONG_INBAND_FEC_SETTING:  
  164.             __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,   
  165.                 "!!!!!!!!!!! Decode_Error_Message: %d\nInband FEC setting not valid, use 0 or 1\n", errcode);  
  166.             break;  
  167.         case SKP_SILK_ENC_WRONG_DTX_SETTING:  
  168.             __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,   
  169.                 "!!!!!!!!!!! Decode_Error_Message: %d\nDTX setting not valid, use 0 or 1\n", errcode);   
  170.             break;  
  171.         case SKP_SILK_ENC_INTERNAL_ERROR:  
  172.             __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,   
  173.                 "!!!!!!!!!!! Decode_Error_Message: %d\nInternal encoder error\n", errcode);   
  174.             break;                
  175.     }  
  176. }  
  177.   
  178. extern "C"  
  179. JNIEXPORT jint JNICALL Java_com_trunkbow_silk_SILK8_encode  
  180.     (JNIEnv *env, jobject obj, jshortArray lin, jint offset, jbyteArray encoded, jint size) {  
  181.   
  182.     jbyte     enc_payload[ MAX_BYTES_DEC_PER_FRAME * MAX_INPUT_FRAMES ];  
  183.     jshort    in[ MAX_FRAME_LENGTH * MAX_INPUT_FRAMES ];      
  184.     int ret,i,frsz=MAX_FRAME;  
  185.     SKP_int16 nBytes;  
  186.     unsigned int lin_pos = 0;  
  187.       
  188.     if (!codec_open)  
  189.         return 0;  
  190.           
  191. #ifdef DEBUG_SILK8  
  192.     __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,   
  193.             "encoding frame size: %d\toffset: %d\n", size, offset);           
  194. #endif  
  195.   
  196.   
  197.     for (i = 0; i < size; i+=MAX_FRAME) {  
  198. #ifdef DEBUG_SILK8  
  199.         __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,   
  200.             "encoding frame size: %d\toffset: %d i: %d\n", size, offset, i);          
  201. #endif  
  202.               
  203.         env->GetShortArrayRegion(lin, offset + i,frsz, in);  
  204.         /* max payload size */  
  205.         nBytes = MAX_BYTES_ENC_PER_FRAME * MAX_INPUT_FRAMES;  
  206.   
  207.         ret = SKP_Silk_SDK_Encode( psEnc, &encControl, in, (SKP_int16)frsz, (SKP_uint8 *)enc_payload, &nBytes );  
  208.         if( ret ) {  
  209.             __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,   
  210.                 "!!!!!!!! SKP_Silk_Encode returned: %d\n", ret);  
  211.             Print_Encode_Error_Msg(ret);                  
  212.             break;  
  213.         }  
  214. #ifdef DEBUG_SILK8  
  215.             __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,   
  216.                 "Enocded nBytes: %d\n", nBytes);          
  217. #endif        
  218.         /* Write payload */       
  219.         env->SetByteArrayRegion(encoded, RTP_HDR_SIZE+ lin_pos, nBytes, enc_payload);  
  220.         lin_pos += nBytes;  
  221.     }  
  222. #ifdef DEBUG_SILK8  
  223.     __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,   
  224.         "encoding **END** frame size: %d\toffset: %d i: %d lin_pos: %d\n", size, offset, i, lin_pos);  
  225. #endif        
  226.   
  227.     return (jint)lin_pos;  
  228. }  
  229.   
  230. extern "C"  
  231. JNIEXPORT jint JNICALL Java_com_trunkbow_silk_SILK8_decode  
  232.     (JNIEnv *env, jobject obj, jbyteArray encoded, jshortArray lin, jint size) {  
  233.   
  234.     jbyte buffer [MAX_BYTES_DEC_PER_FRAME * MAX_INPUT_FRAMES * ( MAX_LBRR_DELAY + 1 ) ];  
  235.     jshort output_buffer[( MAX_FRAME_LENGTH << 1 ) * MAX_INPUT_FRAMES ];  
  236. //  SKP_int16   *outPtr;  
  237.   
  238.     int ret;  
  239.     SKP_int16 len;  
  240. //  int tot_len,frames;  
  241.   
  242.     if (!codec_open)  
  243.         return 0;  
  244.   
  245. #ifdef DEBUG_SILK8        
  246.     __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,   
  247.         "##### BEGIN DECODE ********  decoding frame size: %d\n", size);      
  248. #endif  
  249.   
  250.     env->GetByteArrayRegion(encoded, RTP_HDR_SIZE, size, buffer);  
  251.   
  252. //  outPtr = output_buffer;  
  253. //    tot_len = 0;  
  254. //  frames = 0;  
  255.   
  256. //  do {  
  257.         ret = SKP_Silk_SDK_Decode( psDec, &DecControl, 0,(SKP_uint8 *) buffer, size, output_buffer,&len );  
  258.         if( ret ) {  
  259.             __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,   
  260.                 "!!!!!!!! SKP_Silk_SDK_Decode returned: %d\n", ret);      
  261.             Print_Decode_Error_Msg(ret);  
  262.         }  
  263. #ifdef DEBUG_SILK8        
  264.         __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,   
  265.             "##### DECODED length: %d\n\t Frame #: %d", len);     
  266. #endif  
  267. //      frames++;  
  268. //      outPtr  += len;  
  269. //      tot_len += len;       
  270.       
  271. //  } while( DecControl.moreInternalDecoderFrames );  
  272.   
  273.     env->SetShortArrayRegion(lin, 0, len,output_buffer);  
  274.     return (jint)len;  
  275. }  
  276.   
  277. extern "C"  
  278. JNIEXPORT void JNICALL Java_com_trunkbow_silk_SILK8_close  
  279.     (JNIEnv *env, jobject obj) {  
  280.   
  281.     if (--codec_open != 0)  
  282.         return;  
  283.     /* Free decoder */  
  284.     free( psDec );  
  285.     /* Free Encoder */  
  286.     free( psEnc );  
  287. }  


      silk_16.cpp:

      

[cpp] view plain copy
  1. #include <jni.h>  
  2.   
  3. #include <stdio.h>  
  4. #include <stdlib.h>  
  5. #include <string.h>  
  6. #include <math.h>  
  7.   
  8. /* Define codec specific settings */  
  9. #define MAX_BYTES_ENC_PER_FRAME     250 // Equals peak bitrate of 100 kbps   
  10. #define MAX_BYTES_DEC_PER_FRAME     1024  
  11.   
  12. #define MAX_INPUT_FRAMES        5  
  13. #define MAX_LBRR_DELAY          2  
  14. #define MAX_FRAME_LENGTH        480  
  15.   
  16. #define MAX_FRAME           320  
  17.   
  18. #include <android/log.h>   
  19.   
  20. #define LOG_TAG "silk" // text for log tag   
  21.   
  22. #include "SKP_Silk_SDK_API.h"  
  23. #include "SKP_Silk_SigProc_FIX.h"  
  24.   
  25. #undef DEBUG_SILK16  
  26.   
  27. // the header length of the RTP frame (must skip when en/decoding)  
  28. #define RTP_HDR_SIZE    12  
  29.   
  30. static int codec_open = 0;  
  31.   
  32. static JavaVM *gJavaVM;  
  33. const char *kInterfacePath = "org/sipdroid/pjlib/silk16";  
  34.   
  35. /* encoder parameters */  
  36.   
  37.     SKP_int32 encSizeBytes;  
  38.     void      *psEnc;  
  39.   
  40.     /* default settings */  
  41.     SKP_int   fs_kHz = 16;  
  42.     SKP_int   targetRate_bps = 20000;  
  43.     SKP_int   packetSize_ms = 20;  
  44.     SKP_int   frameSizeReadFromFile_ms = 20;  
  45.     SKP_int   packetLoss_perc = 0, smplsSinceLastPacket;  
  46.     SKP_int   INBandFec_enabled = 0, DTX_enabled = 0, quiet = 0;  
  47.     SKP_SILK_SDK_EncControlStruct encControl; // Struct for input to encoder  
  48.           
  49.   
  50. /* decoder parameters */  
  51.   
  52.     jbyte payloadToDec[    MAX_BYTES_DEC_PER_FRAME * MAX_INPUT_FRAMES * ( MAX_LBRR_DELAY + 1 ) ];  
  53.     jshort out[ ( MAX_FRAME_LENGTH << 1 ) * MAX_INPUT_FRAMES ], *outPtr;  
  54.     SKP_int32 decSizeBytes;  
  55.     void      *psDec;  
  56.     SKP_SILK_SDK_DecControlStruct DecControl;  
  57.   
  58. extern "C"  
  59. JNIEXPORT jint JNICALL Java_com_trunkbow_silk_SILK16_open  
  60.   (JNIEnv *env, jobject obj, jint compression) {  
  61.     int ret;  
  62.   
  63.     if (codec_open++ != 0)  
  64.         return (jint)0;  
  65.   
  66.     /* Set the samplingrate that is requested for the output */  
  67.     DecControl.sampleRate = 16000;  
  68.           
  69.     /* Create decoder */  
  70.     ret = SKP_Silk_SDK_Get_Decoder_Size( &decSizeBytes );  
  71.     if( ret ) {  
  72.         __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,   
  73.             "\n!!!!!!!! SKP_Silk_SDK_Get_Decoder_Size returned %d", ret );        
  74.     }  
  75. #ifdef DEBUG_SILK16  
  76.     __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,   
  77.             "### INIT Decoder decSizeBytes = %d\n", decSizeBytes);        
  78. #endif    
  79.     psDec = malloc( decSizeBytes );  
  80.   
  81.     /* Reset decoder */  
  82.     ret = SKP_Silk_SDK_InitDecoder( psDec );  
  83.     if( ret ) {  
  84.         __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,   
  85.             "\n!!!!!!!! SKP_Silk_InitDecoder returned %d", ret );     
  86.     }  
  87.   
  88.   
  89.     /* Create Encoder */  
  90.     ret = SKP_Silk_SDK_Get_Encoder_Size( &encSizeBytes );  
  91.     if( ret ) {  
  92.         __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,   
  93.             "\n!!!!!!!! SKP_Silk_SDK_Get_Encoder_Size returned %d", ret );    
  94.     }  
  95. #ifdef DEBUG_SILK16  
  96.     __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,   
  97.             "### INIT Encoder encSizeBytes = %d\n", encSizeBytes);        
  98. #endif        
  99.     psEnc = malloc( encSizeBytes );  
  100.       
  101.     /* Reset Encoder */  
  102.     ret = SKP_Silk_SDK_InitEncoder( psEnc, &encControl );  
  103.     if( ret ) {  
  104.         __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,   
  105.             "\n!!!!!!!! SKP_Silk_SDK_InitEncoder returned %d", ret );     
  106.     }  
  107.       
  108.     /* Set Encoder parameters */  
  109.     encControl.sampleRate           = fs_kHz * 1000;  
  110.     encControl.packetSize           = packetSize_ms * fs_kHz;  
  111.     encControl.packetLossPercentage = packetLoss_perc;  
  112.     encControl.useInBandFEC         = INBandFec_enabled;  
  113.     encControl.useDTX               = DTX_enabled;  
  114.     encControl.complexity           = compression;  
  115.     encControl.bitRate              = targetRate_bps;         
  116.       
  117.     return (jint)0;  
  118. }  
  119.   
  120. void Print_Decode_Error_Msg(int errcode) {  
  121.     switch (errcode) {  
  122.         case SKP_SILK_DEC_WRONG_SAMPLING_FREQUENCY:  
  123.             __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,   
  124.                 "!!!!!!!!!!! Decode_Error_Message: %d\nOutput sampling frequency lower than internal decoded sampling frequency\n", errcode);  
  125.             break;  
  126.         case SKP_SILK_DEC_PAYLOAD_TOO_LARGE:  
  127.             __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,   
  128.                 "!!!!!!!!!!! Decode_Error_Message: %d\nPayload size exceeded the maximum allowed 1024 bytes\n", errcode);   
  129.             break;  
  130.         case SKP_SILK_DEC_PAYLOAD_ERROR:  
  131.             __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,   
  132.                 "!!!!!!!!!!! Decode_Error_Message: %d\nPayload has bit errors\n", errcode);   
  133.             break;            
  134.     }  
  135. }  
  136.   
  137. void Print_Encode_Error_Msg(int errcode) {  
  138.     switch (errcode) {  
  139.         case SKP_SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES:  
  140.             __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,   
  141.                 "!!!!!!!!!!! Decode_Error_Message: %d\nInput length is not a multiplum of 10 ms, or length is longer than the packet length\n", errcode);  
  142.             break;  
  143.         case SKP_SILK_ENC_FS_NOT_SUPPORTED:  
  144.             __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,   
  145.                 "!!!!!!!!!!! Decode_Error_Message: %d\nSampling frequency not 8000, 12000, 16000 or 24000 Hertz \n", errcode);   
  146.             break;  
  147.         case SKP_SILK_ENC_PACKET_SIZE_NOT_SUPPORTED:  
  148.             __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,   
  149.                 "!!!!!!!!!!! Decode_Error_Message: %d\nPacket size not 20, 40, 60, 80 or 100 ms\n", errcode);   
  150.             break;            
  151.         case SKP_SILK_ENC_PAYLOAD_BUF_TOO_SHORT:  
  152.             __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,   
  153.                 "!!!!!!!!!!! Decode_Error_Message: %d\nAllocated payload buffer too short \n", errcode);  
  154.             break;  
  155.         case SKP_SILK_ENC_WRONG_LOSS_RATE:  
  156.             __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,   
  157.                 "!!!!!!!!!!! Decode_Error_Message: %d\nLoss rate not between 0 and 100 percent\n", errcode);   
  158.             break;  
  159.         case SKP_SILK_ENC_WRONG_COMPLEXITY_SETTING:  
  160.             __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,   
  161.                 "!!!!!!!!!!! Decode_Error_Message: %d\nComplexity setting not valid, use 0, 1 or 2\n", errcode);   
  162.             break;        
  163.         case SKP_SILK_ENC_WRONG_INBAND_FEC_SETTING:  
  164.             __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,   
  165.                 "!!!!!!!!!!! Decode_Error_Message: %d\nInband FEC setting not valid, use 0 or 1\n", errcode);  
  166.             break;  
  167.         case SKP_SILK_ENC_WRONG_DTX_SETTING:  
  168.             __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,   
  169.                 "!!!!!!!!!!! Decode_Error_Message: %d\nDTX setting not valid, use 0 or 1\n", errcode);   
  170.             break;  
  171.         case SKP_SILK_ENC_INTERNAL_ERROR:  
  172.             __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,   
  173.                 "!!!!!!!!!!! Decode_Error_Message: %d\nInternal encoder error\n", errcode);   
  174.             break;                
  175.     }  
  176. }  
  177.   
  178. extern "C"  
  179. JNIEXPORT jint JNICALL Java_com_trunkbow_silk_SILK16_encode  
  180.     (JNIEnv *env, jobject obj, jshortArray lin, jint offset, jbyteArray encoded, jint size) {  
  181.   
  182.     jbyte     enc_payload[ MAX_BYTES_DEC_PER_FRAME * MAX_INPUT_FRAMES ];  
  183.     jshort    in[ MAX_FRAME_LENGTH * MAX_INPUT_FRAMES ];      
  184.     int ret,i,frsz=MAX_FRAME;  
  185.     SKP_int16 nBytes;  
  186.     unsigned int lin_pos = 0;  
  187.       
  188.     if (!codec_open)  
  189.         return 0;  
  190.           
  191. #ifdef DEBUG_SILK16  
  192.     __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,   
  193.             "encoding frame size: %d\toffset: %d\n", size, offset);           
  194. #endif  
  195.   
  196.   
  197.     for (i = 0; i < size; i+=MAX_FRAME) {  
  198. #ifdef DEBUG_SILK16  
  199.         __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,   
  200.             "encoding frame size: %d\toffset: %d i: %d\n", size, offset, i);          
  201. #endif  
  202.               
  203.         env->GetShortArrayRegion(lin, offset + i,frsz, in);  
  204.         /* max payload size */  
  205.         nBytes = MAX_BYTES_ENC_PER_FRAME * MAX_INPUT_FRAMES;  
  206.   
  207.         ret = SKP_Silk_SDK_Encode( psEnc, &encControl, in, (SKP_int16)frsz, (SKP_uint8 *)enc_payload, &nBytes );  
  208.         if( ret ) {  
  209.             __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,   
  210.                 "!!!!!!!! SKP_Silk_Encode returned: %d\n", ret);  
  211.             Print_Encode_Error_Msg(ret);                      
  212.             break;  
  213.         }  
  214. #ifdef DEBUG_SILK16  
  215.             __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,   
  216.                 "Enocded nBytes: %d\n", nBytes);          
  217. #endif        
  218.         /* Write payload */       
  219.         env->SetByteArrayRegion(encoded, RTP_HDR_SIZE+ lin_pos, nBytes, enc_payload);  
  220.         lin_pos += nBytes;  
  221.     }  
  222. #ifdef DEBUG_SILK16  
  223.     __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,   
  224.         "encoding **END** frame size: %d\toffset: %d i: %d lin_pos: %d\n", size, offset, i, lin_pos);  
  225. #endif        
  226.   
  227.     return (jint)lin_pos;  
  228. }  
  229.   
  230. extern "C"  
  231. JNIEXPORT jint JNICALL Java_com_trunkbow_silk_SILK16_decode  
  232.     (JNIEnv *env, jobject obj, jbyteArray encoded, jshortArray lin, jint size) {  
  233.   
  234.     jbyte buffer [MAX_BYTES_DEC_PER_FRAME * MAX_INPUT_FRAMES * ( MAX_LBRR_DELAY + 1 ) ];  
  235.     jshort output_buffer[( MAX_FRAME_LENGTH << 1 ) * MAX_INPUT_FRAMES ];  
  236. //  SKP_int16   *outPtr;  
  237.   
  238.     int ret;  
  239.     SKP_int16 len;  
  240. //  int tot_len,frames;  
  241.   
  242.     if (!codec_open)  
  243.         return 0;  
  244.   
  245. #ifdef DEBUG_SILK16       
  246.     __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,   
  247.         "##### BEGIN DECODE ********  decoding frame size: %d\n", size);      
  248. #endif  
  249.   
  250.     env->GetByteArrayRegion(encoded, RTP_HDR_SIZE, size, buffer);  
  251.   
  252. //  outPtr = output_buffer;  
  253. //    tot_len = 0;  
  254. //  frames = 0;  
  255.   
  256. //  do {  
  257.         ret = SKP_Silk_SDK_Decode( psDec, &DecControl, 0,(SKP_uint8 *) buffer, size, output_buffer,&len );  
  258.         if( ret ) {  
  259.             __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,   
  260.                 "!!!!!!!! SKP_Silk_SDK_Decode returned: %d\n", ret);      
  261.             Print_Decode_Error_Msg(ret);  
  262.         }  
  263. #ifdef DEBUG_SILK16       
  264.         __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,   
  265.             "##### DECODED length: %d\n\t Frame #: %d", len);     
  266. #endif  
  267. //      frames++;  
  268. //      outPtr  += len;  
  269. //      tot_len += len;       
  270.       
  271. //  } while( DecControl.moreInternalDecoderFrames );  
  272.   
  273.     env->SetShortArrayRegion(lin, 0, len,output_buffer);  
  274.     return (jint)len;  
  275. }  
  276.   
  277. extern "C"  
  278. JNIEXPORT void JNICALL Java_com_trunkbow_silk_SILK16_close  
  279.     (JNIEnv *env, jobject obj) {  
  280.   
  281.     if (--codec_open != 0)  
  282.         return;  
  283.     /* Free decoder */  
  284.     free( psDec );  
  285.     /* Free Encoder */  
  286.     free( psEnc );  
  287. }  


         silk24_jni.cpp

        

[cpp] view plain copy
  1. #include <jni.h>  
  2.   
  3. #include <stdio.h>  
  4. #include <stdlib.h>  
  5. #include <string.h>  
  6. #include <math.h>  
  7.   
  8. /* Define codec specific settings */  
  9. #define MAX_BYTES_ENC_PER_FRAME     250 // Equals peak bitrate of 100 kbps   
  10. #define MAX_BYTES_DEC_PER_FRAME     1024  
  11.   
  12. #define MAX_INPUT_FRAMES        5  
  13. #define MAX_LBRR_DELAY          2  
  14. #define MAX_FRAME_LENGTH        480  
  15.   
  16. #define MAX_FRAME           480  
  17.   
  18. #include <android/log.h>   
  19.   
  20. #define LOG_TAG "silk" // text for log tag   
  21.   
  22. #include "SKP_Silk_SDK_API.h"  
  23. #include "SKP_Silk_SigProc_FIX.h"  
  24.   
  25. #undef DEBUG_SILK24  
  26.   
  27. // the header length of the RTP frame (must skip when en/decoding)  
  28. #define RTP_HDR_SIZE    12  
  29.   
  30. static int codec_open = 0;  
  31.   
  32. static JavaVM *gJavaVM;  
  33. const char *kInterfacePath = "org/sipdroid/pjlib/SILK24";  
  34.   
  35. /* encoder parameters */  
  36.   
  37.     SKP_int32 encSizeBytes;  
  38.     void      *psEnc;  
  39.   
  40.     /* default settings */  
  41.     SKP_int   fs_kHz = 24;  
  42.     SKP_int   targetRate_bps = 20000;  
  43.     SKP_int   packetSize_ms = 20;  
  44.     SKP_int   frameSizeReadFromFile_ms = 20;  
  45.     SKP_int   packetLoss_perc = 0, smplsSinceLastPacket;  
  46.     SKP_int   INBandFec_enabled = 0, DTX_enabled = 0, quiet = 0;  
  47.     SKP_SILK_SDK_EncControlStruct encControl; // Struct for input to encoder  
  48.           
  49.   
  50. /* decoder parameters */  
  51.   
  52.     jbyte payloadToDec[    MAX_BYTES_DEC_PER_FRAME * MAX_INPUT_FRAMES * ( MAX_LBRR_DELAY + 1 ) ];  
  53.     jshort out[ ( MAX_FRAME_LENGTH << 1 ) * MAX_INPUT_FRAMES ], *outPtr;  
  54.     SKP_int32 decSizeBytes;  
  55.     void      *psDec;  
  56.     SKP_SILK_SDK_DecControlStruct DecControl;  
  57.   
  58. extern "C"  
  59. JNIEXPORT jint JNICALL Java_com_trunkbow_silk_SILK24_open  
  60.   (JNIEnv *env, jobject obj, jint compression) {  
  61.     int ret;  
  62.   
  63.     if (codec_open++ != 0)  
  64.         return (jint)0;  
  65.   
  66.     /* Set the samplingrate that is requested for the output */  
  67.     DecControl.sampleRate = 24000;  
  68.           
  69.     /* Create decoder */  
  70.     ret = SKP_Silk_SDK_Get_Decoder_Size( &decSizeBytes );  
  71.     if( ret ) {  
  72.         __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,   
  73.             "\n!!!!!!!! SKP_Silk_SDK_Get_Decoder_Size returned %d", ret );        
  74.     }  
  75. #ifdef DEBUG_SILK24  
  76.     __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,   
  77.             "### INIT Decoder decSizeBytes = %d\n", decSizeBytes);        
  78. #endif    
  79.     psDec = malloc( decSizeBytes );  
  80.   
  81.     /* Reset decoder */  
  82.     ret = SKP_Silk_SDK_InitDecoder( psDec );  
  83.     if( ret ) {  
  84.         __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,   
  85.             "\n!!!!!!!! SKP_Silk_InitDecoder returned %d", ret );     
  86.     }  
  87.   
  88.   
  89.     /* Create Encoder */  
  90.     ret = SKP_Silk_SDK_Get_Encoder_Size( &encSizeBytes );  
  91.     if( ret ) {  
  92.         __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,   
  93.             "\n!!!!!!!! SKP_Silk_SDK_Get_Encoder_Size returned %d", ret );    
  94.     }  
  95. #ifdef DEBUG_SILK24  
  96.     __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,   
  97.             "### INIT Encoder encSizeBytes = %d\n", encSizeBytes);        
  98. #endif        
  99.     psEnc = malloc( encSizeBytes );  
  100.       
  101.     /* Reset Encoder */  
  102.     ret = SKP_Silk_SDK_InitEncoder( psEnc, &encControl );  
  103.     if( ret ) {  
  104.         __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,   
  105.             "\n!!!!!!!! SKP_Silk_SDK_InitEncoder returned %d", ret );     
  106.     }  
  107.       
  108.     /* Set Encoder parameters */  
  109.     encControl.sampleRate           = fs_kHz * 1000;  
  110.     encControl.packetSize           = packetSize_ms * fs_kHz;  
  111.     encControl.packetLossPercentage = packetLoss_perc;  
  112.     encControl.useInBandFEC         = INBandFec_enabled;  
  113.     encControl.useDTX               = DTX_enabled;  
  114.     encControl.complexity           = compression;  
  115.     encControl.bitRate              = targetRate_bps;         
  116.       
  117.     return (jint)0;  
  118. }  
  119.   
  120. void Print_Decode_Error_Msg(int errcode) {  
  121.     switch (errcode) {  
  122.         case SKP_SILK_DEC_WRONG_SAMPLING_FREQUENCY:  
  123.             __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,   
  124.                 "!!!!!!!!!!! Decode_Error_Message: %d\nOutput sampling frequency lower than internal decoded sampling frequency\n", errcode);  
  125.             break;  
  126.         case SKP_SILK_DEC_PAYLOAD_TOO_LARGE:  
  127.             __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,   
  128.                 "!!!!!!!!!!! Decode_Error_Message: %d\nPayload size exceeded the maximum allowed 1024 bytes\n", errcode);   
  129.             break;  
  130.         case SKP_SILK_DEC_PAYLOAD_ERROR:  
  131.             __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,   
  132.                 "!!!!!!!!!!! Decode_Error_Message: %d\nPayload has bit errors\n", errcode);   
  133.             break;            
  134.     }  
  135. }  
  136.   
  137. void Print_Encode_Error_Msg(int errcode) {  
  138.     switch (errcode) {  
  139.         case SKP_SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES:  
  140.             __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,   
  141.                 "!!!!!!!!!!! Decode_Error_Message: %d\nInput length is not a multiplum of 10 ms, or length is longer than the packet length\n", errcode);  
  142.             break;  
  143.         case SKP_SILK_ENC_FS_NOT_SUPPORTED:  
  144.             __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,   
  145.                 "!!!!!!!!!!! Decode_Error_Message: %d\nSampling frequency not 8000, 12000, 16000 or 24000 Hertz \n", errcode);   
  146.             break;  
  147.         case SKP_SILK_ENC_PACKET_SIZE_NOT_SUPPORTED:  
  148.             __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,   
  149.                 "!!!!!!!!!!! Decode_Error_Message: %d\nPacket size not 20, 40, 60, 80 or 100 ms\n", errcode);   
  150.             break;            
  151.         case SKP_SILK_ENC_PAYLOAD_BUF_TOO_SHORT:  
  152.             __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,   
  153.                 "!!!!!!!!!!! Decode_Error_Message: %d\nAllocated payload buffer too short \n", errcode);  
  154.             break;  
  155.         case SKP_SILK_ENC_WRONG_LOSS_RATE:  
  156.             __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,   
  157.                 "!!!!!!!!!!! Decode_Error_Message: %d\nLoss rate not between 0 and 100 percent\n", errcode);   
  158.             break;  
  159.         case SKP_SILK_ENC_WRONG_COMPLEXITY_SETTING:  
  160.             __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,   
  161.                 "!!!!!!!!!!! Decode_Error_Message: %d\nComplexity setting not valid, use 0, 1 or 2\n", errcode);   
  162.             break;        
  163.         case SKP_SILK_ENC_WRONG_INBAND_FEC_SETTING:  
  164.             __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,   
  165.                 "!!!!!!!!!!! Decode_Error_Message: %d\nInband FEC setting not valid, use 0 or 1\n", errcode);  
  166.             break;  
  167.         case SKP_SILK_ENC_WRONG_DTX_SETTING:  
  168.             __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,   
  169.                 "!!!!!!!!!!! Decode_Error_Message: %d\nDTX setting not valid, use 0 or 1\n", errcode);   
  170.             break;  
  171.         case SKP_SILK_ENC_INTERNAL_ERROR:  
  172.             __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,   
  173.                 "!!!!!!!!!!! Decode_Error_Message: %d\nInternal encoder error\n", errcode);   
  174.             break;                
  175.     }  
  176. }  
  177.   
  178. extern "C"  
  179. JNIEXPORT jint JNICALL Java_com_trunkbow_silk_SILK24_encode  
  180.     (JNIEnv *env, jobject obj, jshortArray lin, jint offset, jbyteArray encoded, jint size) {  
  181.   
  182.     jbyte     enc_payload[ MAX_BYTES_DEC_PER_FRAME * MAX_INPUT_FRAMES ];  
  183.     jshort    in[ MAX_FRAME_LENGTH * MAX_INPUT_FRAMES ];      
  184.     int ret,i,frsz=MAX_FRAME;  
  185.     SKP_int16 nBytes;  
  186.     unsigned int lin_pos = 0;  
  187.       
  188.     if (!codec_open)  
  189.         return 0;  
  190.           
  191. #ifdef DEBUG_SILK24  
  192.     __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,   
  193.             "encoding frame size: %d\toffset: %d\n", size, offset);           
  194. #endif  
  195.   
  196.   
  197.     for (i = 0; i < size; i+=MAX_FRAME) {  
  198. #ifdef DEBUG_SILK24  
  199.         __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,   
  200.             "encoding frame size: %d\toffset: %d i: %d\n", size, offset, i);          
  201. #endif  
  202.               
  203.         env->GetShortArrayRegion(lin, offset + i,frsz, in);  
  204.         /* max payload size */  
  205.         nBytes = MAX_BYTES_ENC_PER_FRAME * MAX_INPUT_FRAMES;  
  206.   
  207.         ret = SKP_Silk_SDK_Encode( psEnc, &encControl, in, (SKP_int16)frsz, (SKP_uint8 *)enc_payload, &nBytes );  
  208.         if( ret ) {  
  209.             __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,   
  210.                 "!!!!!!!! SKP_Silk_Encode returned: %d\n", ret);  
  211.             Print_Encode_Error_Msg(ret);                  
  212.             break;  
  213.         }  
  214. #ifdef DEBUG_SILK24  
  215.             __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,   
  216.                 "Enocded nBytes: %d\n", nBytes);          
  217. #endif        
  218.         /* Write payload */       
  219.         env->SetByteArrayRegion(encoded, RTP_HDR_SIZE+ lin_pos, nBytes, enc_payload);  
  220.         lin_pos += nBytes;  
  221.     }  
  222. #ifdef DEBUG_SILK24  
  223.     __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,   
  224.         "encoding **END** frame size: %d\toffset: %d i: %d lin_pos: %d\n", size, offset, i, lin_pos);  
  225. #endif        
  226.   
  227.     return (jint)lin_pos;  
  228. }  
  229.   
  230. extern "C"  
  231. JNIEXPORT jint JNICALL Java_com_trunkbow_silk_SILK24_decode  
  232.     (JNIEnv *env, jobject obj, jbyteArray encoded, jshortArray lin, jint size) {  
  233.   
  234.     jbyte buffer [MAX_BYTES_DEC_PER_FRAME * MAX_INPUT_FRAMES * ( MAX_LBRR_DELAY + 1 ) ];  
  235.     jshort output_buffer[( MAX_FRAME_LENGTH << 1 ) * MAX_INPUT_FRAMES ];  
  236. //  SKP_int16   *outPtr;  
  237.   
  238.     int ret;  
  239.     SKP_int16 len;  
  240. //  int tot_len,frames;  
  241.   
  242.     if (!codec_open)  
  243.         return 0;  
  244.   
  245. #ifdef DEBUG_SILK24       
  246.     __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,   
  247.         "##### BEGIN DECODE ********  decoding frame size: %d\n", size);      
  248. #endif  
  249.   
  250.     env->GetByteArrayRegion(encoded, RTP_HDR_SIZE, size, buffer);  
  251.   
  252. //  outPtr = output_buffer;  
  253. //    tot_len = 0;  
  254. //  frames = 0;  
  255.   
  256. //  do {  
  257.         ret = SKP_Silk_SDK_Decode( psDec, &DecControl, 0,(SKP_uint8 *) buffer, size, output_buffer,&len );  
  258.         if( ret ) {  
  259.             __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,   
  260.                 "!!!!!!!! SKP_Silk_SDK_Decode returned: %d\n", ret);      
  261.             Print_Decode_Error_Msg(ret);  
  262.         }  
  263. #ifdef DEBUG_SILK24       
  264.         __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,   
  265.             "##### DECODED length: %d\n\t Frame #: %d", len);     
  266. #endif  
  267. //      frames++;  
  268. //      outPtr  += len;  
  269. //      tot_len += len;       
  270.       
  271. //  } while( DecControl.moreInternalDecoderFrames );  
  272.   
  273.     env->SetShortArrayRegion(lin, 0, len,output_buffer);  
  274.     return (jint)len;  
  275. }  
  276.   
  277. extern "C"  
  278. JNIEXPORT void JNICALL Java_com_trunkbow_silk_SILK24_close  
  279.     (JNIEnv *env, jobject obj) {  
  280.   
  281.     if (--codec_open != 0)  
  282.         return;  
  283.     /* Free decoder */  
  284.     free( psDec );  
  285.     /* Free Encoder */  
  286.     free( psEnc );  
  287. }  


    

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

           Silk8.java:

        

[java] view plain copy
  1. class SILK8{     
  2.     /*  
  3.      *                 | fs (Hz) | BR (kbps) 
  4.      * ----------------+---------+--------- 
  5.      * Narrowband      | 8000    | 6 -20 
  6.      * Mediumband      | 12000   | 7 -25 
  7.      * Wideband        | 16000   | 8 -30 
  8.      * Super Wideband  | 24000   | 12 -40 
  9.      * 
  10.      * Table 1: fs specifies the audio sampling frequency in Hertz (Hz); BR 
  11.      * specifies the adaptive bit rate range in kilobits per second (kbps). 
  12.      *  
  13.      * Complexity can be scaled to optimize for CPU resources in real-time, 
  14.      * mostly in trade-off to network bit rate. 0 is least CPU demanding and 
  15.      * highest bit rate.  
  16.      */  
  17.     private static final int DEFAULT_COMPLEXITY = 0;  
  18.       
  19.     void load() {  
  20.          System.loadLibrary("silk8_jni");  
  21.     }    
  22.    
  23.     public native int open(int compression);  
  24.     public native int decode(byte encoded[], short lin[], int size);  
  25.     public native int encode(short lin[], int offset, byte encoded[], int size);  
  26.     public native void close();  
  27. }  


         Silk16.java:

[java] view plain copy
  1. class SILK16 {   
  2.     /*  
  3.      *                 | fs (Hz) | BR (kbps) 
  4.      * ----------------+---------+--------- 
  5.      * Narrowband      | 8000    | 6 -20 
  6.      * Mediumband      | 12000   | 7 -25 
  7.      * Wideband        | 16000   | 8 -30 
  8.      * Super Wideband  | 24000   | 12 -40 
  9.      * 
  10.      * Table 1: fs specifies the audio sampling frequency in Hertz (Hz); BR 
  11.      * specifies the adaptive bit rate range in kilobits per second (kbps). 
  12.      *  
  13.      * Complexity can be scaled to optimize for CPU resources in real-time, 
  14.      * mostly in trade-off to network bit rate. 0 is least CPU demanding and 
  15.      * highest bit rate.  
  16.      */  
  17.     private static final int DEFAULT_COMPLEXITY = 0;  
  18.   
  19.   
  20.     void load() {  
  21.         System.loadLibrary("silk16_jni");  
  22.     }    
  23.    
  24.     public native int open(int compression);  
  25.     public native int decode(byte encoded[], short lin[], int size);  
  26.     public native int encode(short lin[], int offset, byte encoded[], int size);  
  27.     public native void close();  
  28.   
  29. }  


Silk24.java:

[java] view plain copy
  1. class SILK24  {   
  2.     /*  
  3.      *                 | fs (Hz) | BR (kbps) 
  4.      * ----------------+---------+--------- 
  5.      * Narrowband      | 8000    | 6 -20 
  6.      * Mediumband      | 12000   | 7 -25 
  7.      * Wideband        | 16000   | 8 -30 
  8.      * Super Wideband  | 24000   | 12 -40 
  9.      * 
  10.      * Table 1: fs specifies the audio sampling frequency in Hertz (Hz); BR 
  11.      * specifies the adaptive bit rate range in kilobits per second (kbps). 
  12.      *  
  13.      * Complexity can be scaled to optimize for CPU resources in real-time, 
  14.      * mostly in trade-off to network bit rate. 0 is least CPU demanding and 
  15.      * highest bit rate.  
  16.      */  
  17.     private static final int DEFAULT_COMPLEXITY = 0;  
  18.   
  19.     void load() {  
  20.         System.loadLibrary("silk24_jni");  
  21.     }    
  22.    
  23.     public native int open(int compression);  
  24.     public native int decode(byte encoded[], short lin[], int size);  
  25.     public native int encode(short lin[], int offset, byte encoded[], int size);  
  26.     public native void close();  
  27.   
  28. }  


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


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

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

  * 作者:张兴业                                                                                           *

  * 邮箱:[email protected]                                                                   *

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


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

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


      

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

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

  * 作者:张兴业                                                                                           *

  * 邮箱:[email protected]                                                                   *

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

你可能感兴趣的:(Silk编解码在android实现)