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实现。

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

#include

#include

#include

#include

/* 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

#defineMAX_FRAME160

#include

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

#defineRTP_HDR_SIZE12

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;

//inttot_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

#include

#include

#include

#include

/* 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

#defineMAX_FRAME320

#include

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

#defineRTP_HDR_SIZE12

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;

//inttot_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

#include

#include

#include

#include

/* 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

#defineMAX_FRAME480

#include

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

#defineRTP_HDR_SIZE12

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;

//inttot_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文件。

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

* 作者:张兴业                                                                                           *

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

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

/**

* @author 张兴业

*  iOS入门群:83702688

*  android开发进阶群:241395671

*  我的新浪微博:

*/

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

* 作者:张兴业                                                                                           *

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

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

silk 编解码_Silk编解码在android实现相关推荐

  1. H264视频传输、编解码----FFmpeg软解码

    记录一下之前项目的实际使用过程. 将按照Java层------>JNI接口------>JNI代码中使用FFmpeg解码. 首先Java层: public class CodecWrapp ...

  2. Java笔记-字符串编码与解码以及编码表原理

    编码表 编码表:是一张由字符及其对应编码的表 计算机只能识别二进制数据,早期由电信号演化而来. 为了方便使用计算机,让它可以识别各个国家的文字,就将各个国家的文字用数字来表示,并一一对应,形成一张编码 ...

  3. JAVA Io 流 字符流 编码表 编码和解码的方法

    字节流,用中文可能会出现乱码 计算机中存储的信息都是二进制表示的 按照某种规则将字符编程二进制 再存储到计算机中,成为编码 按照同样规则,在计算机中二进制数解析出来,成为解码 编码和解码的方式必须一致 ...

  4. android播放器和视频拍摄中的硬解和软解以及硬编和软编的区别

    转载 原文地址:https://blog.csdn.net/ltym2014/article/details/82354606 https://blog.csdn.net/lipengshiwo/ar ...

  5. 硬解码与软解码的选择

    前言 事物都有两面性,软解码和硬解码的并存,存在即合理,没有哪个最好,以后两者都会更好,而对于如何选择,根据项目需要. 在上篇<快速集成一个视频直播功能> 中提到,"确定需求后进 ...

  6. 去抖音面试被问到硬编码与软编码区别,如何选取硬编与软编?

    原文链接:https://zhuanlan.zhihu.com/p/82130600 Android的视频相关的开发,大概一直是整个Android生态,以及Android API中,最为分裂以及兼容性 ...

  7. 软解码与硬解码区别linux,软解码和硬解码哪个好 软解码和硬解码有什么区别

    喜欢用手机看视频的同学应该都会接触到这样一个概念,手机软解码和硬解码.虽然这两个选项在播放器中再常见不过.不过还是很多机友不知道两者的区别再哪里.就针对这个问题百事网小编给大家普及一下相关的软解和硬解 ...

  8. 硬解码和软解码的区别

    我们在计算机上播放的视频文件都是经过压缩的,因为这样有利于节约存储空间:那么在播放过程,就需要进行一个反射的解压缩过程.在以前这项工作都是由CPU来完成的,对于普通分辨率的AVI.RMVB等文件,绝大 ...

  9. HEVC的软解码和硬解码

    1.概念 从数字视频诞生以来,硬解码和软解码的说法一直伴随着它的发展.数字视频的软解码是指在通用CPU上通过专门的播放软件解码并播放视频:而硬解码则是指在专用的硬件解码模块解码视频,然后将解码数据送至 ...

最新文章

  1. effective stl 条款15 小心string实现的多样性
  2. 人工智能与人类智能的竞赛:人机对抗智能技术全梳理
  3. 学生信息管理系统(连接数据库,面向对象的方法实现学生信息的增删改查操作)...
  4. 【机器视觉】 continue算子
  5. 如何使用SAT trace一个正在运行的程序
  6. 51NOD 1125(交换机器最小代价) (贪心) 思想 !思想!
  7. 1-docker 介绍
  8. Intellj Idea 如何设置类头注释和方法注释
  9. 一维数组的初始化问题(函数体内与函数体外)
  10. Percona XtraBackup User Manual 阅读笔记
  11. Mysql 大量数据快速导出
  12. Spring源码阅读之在spring源码中创建一个gradle测试模块
  13. win10安装cmder和WSL
  14. 我的世界检测不到java_《我的世界》检测不到java怎么办?
  15. mysql execute stmt_[转载]MySql 数据库--stmt语句
  16. 【第三方互联】微博2、创建新浪微博(sina)互联应用
  17. target triplets
  18. squid高性能代理缓存服务器
  19. 如何导入android sdk,如何导入android sdk samples
  20. 国内CMS网站内容管理系统介绍

热门文章

  1. python父亲节祝福_父亲节祝福语精选简短 父亲节祝福语简短独特
  2. SSM 整合 3:一个 Spring 入门程序带你来了解什么是控制反转(IoC)/依赖注入(DI)!
  3. 大数据基础系列 4:伪分布式 Hadoop 在 Ubuntu 上的安装流程完整步骤及易错点分析
  4. 修改Linux启动后的默认颜色,更改linux目录的默认颜色(我选择了Yellow)
  5. java 结构体数组初始化_C数组结构体联合体快速初始化
  6. 计算机发展史评课议课稿,评课议课记录范文
  7. c语言比较大小 谁大选谁,C语言比较优先级
  8. 关于php的问题有哪些,关于PHP的报错问题?
  9. 聋人工学院计算机老师,聋人工学院12位手语老师用双手传递声音
  10. Qt图形界面编程入门(标签与槽机制习题分享)