解决方案 »

  1.   

    下面是jni对应的c++文档,我根据自己的理解添加了注释,求大神指点#include <jni.h>#include <string.h>
    #include <unistd.h>#include <speex/speex.h>static int codec_open = 0;//是否已经打开speexstatic int dec_frame_size;//解码帧大小
    static int enc_frame_size;//编码帧大小static SpeexBits ebits, dbits;//编码位采集结构和解码位采集结构
    void *enc_state;//speex编码器状态量
    void *dec_state;//speex解码器状态量static JavaVM *gJavaVM;//java虚拟机extern "C"
    {
    JNIEXPORT jint JNICALL Java_com_audio_Speex_open//speex打开方法
      (JNIEnv *env, jobject obj, jint compression) {//传入
    int tmp;//传入的compression无法直接使用,需要赋值 if (codec_open++ != 0)
    return (jint)0; speex_bits_init(&ebits);//初始化结构使他们保存数据
    speex_bits_init(&dbits);//初始化结构使他们保存数据 enc_state = speex_encoder_init(&speex_nb_mode);//新建一个新的编码状态在窄宽模式下
    dec_state = speex_decoder_init(&speex_nb_mode);//新建一个新的解码状态在窄宽模式下
    tmp = compression;
    speex_encoder_ctl(enc_state, SPEEX_SET_QUALITY, &tmp);//编码器质量设置
    speex_encoder_ctl(enc_state, SPEEX_GET_FRAME_SIZE, &enc_frame_size);//你用的模式的帧的大小(编码)预备获得
    speex_decoder_ctl(dec_state, SPEEX_GET_FRAME_SIZE, &dec_frame_size);//你用的模式的帧的大小(解码)预备获得 return (jint)0;
    }
    }
    extern "C"{
    JNIEXPORT jint Java_com_audio_Speex_encode//编码方法 传入对象 short[] int byte[] int
        (JNIEnv *env, jobject obj, jshortArray lin, jint offset, jbyteArray encoded, jint size) {        jshort buffer[enc_frame_size];//short缓冲大小为帧大小
            jbyte output_buffer[enc_frame_size];//字节输出缓冲大小为帧大小
    int nsamples = (size-1)/enc_frame_size + 1;//貌似是得到总共帧的数量
    int i, tot_bytes = 0;// if (!codec_open)//如果speex没有打开直接返回
    return 0; speex_bits_reset(&ebits);//清空这个结构体里所有的字节,以便我们可以编码一个新的帧 for (i = 0; i < nsamples; i++) {//GetShortArrayRegion表示把数组val1从第val个元素开始的val2个元素拷贝到val3地址所指向的内存区域
    env->GetShortArrayRegion(lin, offset + i*enc_frame_size, enc_frame_size, buffer);
    speex_encode_int(enc_state, buffer, &ebits);//对帧进行编码
    }    //把bits拷贝到一个利用写出的char型数组
    tot_bytes = speex_bits_write(&ebits, (char *)output_buffer,
         enc_frame_size);//tot_bytes是一个实际写入btye_ptr的数,即编码的实际大小
    env->SetByteArrayRegion(encoded, 0, tot_bytes,
    output_buffer);        return (jint)tot_bytes;
    }
    }
    extern "C"{
    JNIEXPORT jint JNICALL Java_com_audio_Speex_decode
        (JNIEnv *env, jobject obj, jbyteArray encoded, jshortArray lin, jint size) {        jbyte buffer[dec_frame_size];
            jshort output_buffer[dec_frame_size];
            jsize encoded_length = size; if (!codec_open)
    return 0; env->GetByteArrayRegion(encoded, 0, encoded_length, buffer);
    speex_bits_read_from(&dbits, (char *)buffer, encoded_length);
    speex_decode_int(dec_state, &dbits, output_buffer);
    env->SetShortArrayRegion(lin, 0, dec_frame_size,
     output_buffer); return (jint)dec_frame_size;
    }
    }
    extern "C"{
    JNIEXPORT jint JNICALL Java_com_audio_Speex_getFrameSize
        (JNIEnv *env, jobject obj) { if (!codec_open)
    return 0;
    return (jint)enc_frame_size;}
    }
    extern "C"{
    JNIEXPORT void JNICALL Java_com_audio_Speex_close
        (JNIEnv *env, jobject obj) { if (--codec_open != 0)
    return; speex_bits_destroy(&ebits);
    speex_bits_destroy(&dbits);
    speex_decoder_destroy(dec_state);
    speex_encoder_destroy(enc_state);
    }
    }