silk 編解碼_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實現。

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

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

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/538720.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/538720.shtml
英文地址,請注明出處:http://en.pswp.cn/news/538720.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

impdp導入dmp文件ORA-39088: 文件名不能包含路徑說明ORA-39001: 參數值無效ORA-39000: 轉儲文件說明錯誤

C:\Users\zengmiaogen>impdp yinda/123456127.0.0.1:1521/XE filec:\hz_toolbox_20160613.dmp fully Import: Release 11.2.0.2.0 - Production on 星期四 3月 9 10:19:57 2017 Copyright (c) 1982, 2009, Oracle and/or its affiliates. All rights reserved. 連接到: …

高中技校學計算機,我沒考上高中,英語數學極差,想上技校學計算機專業,玩代碼的那種,有前途嗎?...

我沒考上高中&#xff0c;英語數學極差&#xff0c;想上技校學計算機專業&#xff0c;玩代碼的那種&#xff0c;有前途嗎&#xff1f;以下文字資料是由(歷史新知網www.lishixinzhi.com)小編為大家搜集整理后發布的內容&#xff0c;讓我們趕快一起來看一下吧&#xff01;我沒考上…

destoon b2b 360網站智能摘要標簽配置

1、新聞資訊部分&#xff1a; <meta property"og:type" content"news"/><meta property"og:title" content"{$title}"/><meta property"og:description" name"description" content"{$head_d…

饑荒聯機版連不上服務器_饑荒無法連接klei服務器刷不出服務器解決辦法

《饑荒&#xff1a;聯機版》服務器卡頓原因分析及解決教程,很多在饑荒聯機版的同學經常會遇見卡頓問題&#xff0c;而很多玩家為了解決卡頓問題都會選擇自己建一個服務器在其中游玩。可是有些時候連自己建的服務器都會卡&#xff0c;這是什么問題呢》今天小編就為大家帶來關于服…

imp導入dmp文件報:IMP-00038: 無法轉換為環境字符集句柄IMP-00000: 未成功終止導入

C:\Users\zengmiaogen>imp yinda/123456127.0.0.1:1521/XE filec:\hz_toolbox_20160613.dmp fully Import: Release 11.2.0.2.0 - Production on 星期四 3月 9 10:15:39 2017 Copyright (c) 1982, 2009, Oracle and/or its affiliates. All rights reserved. 連接到: Oracl…

html中函數傳遞多個值,JavaScript 實戰開發經驗!函數多參數傳參技巧

HTML5學堂-碼匠&#xff1a;掌握JavaScript代碼的你&#xff0c;一定編寫封裝過函數&#xff0c;為了提升函數的控制性&#xff0c;必不可少的就是參數&#xff0c;必選可選的一大堆參數羅列出來&#xff0c;函數調用貌似變得麻煩起來~~~Tips&#xff1a;必選參數指的是必須要傳…

軟件工程學習筆記(考試版)

軟 件 工 程 筆 記 第一章 一個軟件產品必須由一個完整的配置組成&#xff0c;軟件配置主要包括&#xff1a;程序&#xff0c;數據及相關文檔。程序是能夠完成預定功能和性能的可執行的指令序列&#xff1b;數據是使程序能夠適當的處理信息的數據結構&#xff1b;文檔是開發使…

JAVA程序員面試總結,高手整整理加強版

第一階段&#xff1a;三年 我認為三年對于程序員來說是第一個門檻&#xff0c;這個階段將會淘汰掉一批不適合寫代碼的人。這一階段&#xff0c;我們走出校園&#xff0c;邁入社會&#xff0c;成為一名程序員&#xff0c;正式從書本 上的內容邁向真正的企業級開發。我們知道如…

gin 項目結構_Gin框架中文文檔

最近更新時間&#xff1a;2019-02-20Gin 是一個 go 寫的 web 框架&#xff0c;具有高性能的優點。官方地址&#xff1a;https://github.com/gin-gonic/gin目錄[TOC]安裝要安裝Gin包&#xff0c;首先需要安裝Go并設置Go工作區1、下載并安裝$ go get -u github.com/gin-gonic/gin…

計算機在材料科學中的應用上機二,計算機在材料科學中的應用-上機實驗二.doc...

計算機在材料科學中的應用-上機實驗二實驗二 Office使用技巧?1 Word工具欄的增刪與了解其主要作用(1) ? 把“常用”和“格式”工具欄打開(一般情況下是打開的&#xff01;)&#xff0c;拖動到合適地方。打開和關閉“符號欄1”和“符號欄2”&#xff0c;了解其主要作用。步驟&…

印象筆記編輯pdf_筆記軟件使用體驗(至2020.03)

幾年的時間&#xff0c;從OneNote到為知筆記&#xff0c;再到印象筆記&#xff0c;再回到為知筆記和OneNote&#xff0c;用下來感覺各有優勢&#xff0c;也有不爽的地方。 早年間OneNote的同步很有問題&#xff0c;一次同步沖突導致失去了幾乎所有筆記本。心灰意冷之下就離開了…

oracle修改字符集

生產環境的數據表用了 中文字段名。 在生產環境oracle表正常&#xff0c;新建開發環境時&#xff0c;報字符串超長。 原因是 生產oracle字符集是&#xff1a;NLS_CHARACTERSETZHS16GBK 開發oracle字符集是&#xff1a;NLS_CHARACTERSET AL16UTF16 開發oracle需要修改字符集…

C#獲取當前程序運行路徑的方法集合

2019獨角獸企業重金招聘Python工程師標準>>> // 獲取當前進程的完整路徑&#xff0c;包含文件名(進程名) Console.WriteLine(GetType().Assembly.Location "\tGetType().Assembly.Location"); // 獲取新的 Process 組件并將其與當前活動的進程關聯的主模…

mac安裝python3.7兩個版本_MAC下同時安裝Python2和Python3

第一步&#xff1a;在安裝Python之前&#xff0c;你的電腦需要安裝一下工具&#xff1a;1.xcode(App Store里可以直接下載)2.套件管理工具Homebrew第二步&#xff1a;安裝Homebrew1.打開終端&#xff0c;輸入&#xff1a;ruby -e "$(curl -fsSL https://raw.githubusercon…

Hive thrift服務--beeline使用

hive提供了thrift服務&#xff0c;只要客戶端符合thrift標準就可以與它對接。 這樣可以以在一臺服務器上啟動一個hive&#xff0c;其他用戶通過thrift訪問hive。 hive自帶了一個thrift的客戶端-------bin/beeline 啟動方式&#xff1a; 1、hadoop的core-site.xml增加配置 &l…

vfp控制excel使用sort_使用Python根據索引合并Excel表

有兩張不同大小的excel表表1&#xff1a;字典的選項值&#xff0c;2118行表2&#xff1a;字典名稱&#xff0c;405行表1和表2有共同的列.現在需要根據共同的列&#xff0c;以表1為底&#xff0c;將表2的值對應添加到表1的每一行。下面是代碼&#xff1a;1.加載相關的庫import n…

Redis詳解(三)

一、Redis集群介紹 Clustering:redis 3.0之后進入生產環境分布式數據庫&#xff0c;通過分片機制來進行數據分布&#xff0c;clustering 內的每個節點&#xff0c;僅有數據庫的一部分數據;去中心化的集群&#xff1a;redis集群中的每一個節點&#xff0c;都可以作為集群的接入節…

db2數據庫日期減一天_DB2 數據庫中的日期與時間如何正確操作?(2)

日期函數有時&#xff0c;您需要知道兩個時間戳記之間的時差。為此&#xff0c;DB2 數據庫提供了一個名為 TIMESTAMPDIFF() 的內置函數。但該函數返回的是近似值&#xff0c;因為它不考慮閏年&#xff0c;而且假設每個月只有 30 天。以下示例描述了如何得到兩個日期的近似時差&…

win10計算機從桌面消失了,Windows10家庭版程序窗口在桌面上消失了解決方法

相信大家對于電腦非常不陌生吧&#xff0c;當你遇到Win10程序窗口桌面上消失了怎么辦這個問題該怎么解決嗎&#xff1f;不知道了吧&#xff0c;接下來小編就以程序窗口時所遇到的Win10程序窗口桌面上消失了怎么辦問題來給大家講講&#xff0c;看看小編是如何幫大家解決Win10程序…

如何將hive查詢結果導出成txt文件

原文地址&#xff1a;https://zhidao.baidu.com/question/241683835498891364.html ----------------------------------------------------------------------------- 最近在使用hive時&#xff0c;需要將hive查詢的數據導出到本地文件系統&#xff0c;HQL語法如下&…