首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >android中的speex支持

android中的speex支持
EN

Stack Overflow用户
提问于 2012-02-01 07:40:42
回答 3查看 10.7K关注 0票数 13

有人能在上帮助我如何在android中使用speex或jspeex吗?

我已经搜索了很多,但是找不到anywhere.There,在code.google.com/android中有很多关于这个的问题,但是没有人回答它。在这里,这个问题也没有得到很好的回答,因为我的另一个问题是在Android中解码speex编码的字节数组。所以如果你对此有所了解,请向我提供有关这方面的信息。

我需要使用这个编解码器来编码和解码音频文件的字节数组。

我尝试过安卓-ndk完成了编码,,但在解码字节数组时遇到了问题。还有其他替代方法来实现这一点吗?

编辑

我在本机c文件中的编码函数如下:

代码语言:javascript
复制
#include <jni.h>
#include "speex/speex.h"

#define FRAME_SIZE 320

int nbBytes;
/*Holds the state of the encoder*/
void *state;
void *decod_state;


/*Holds bits so they can be read and written to by the Speex routines*/

SpeexBits decod_bits;
SpeexBits bits;
int i, tmp;

void Java_com_mycom_speex_SpeexEncodingActivity_init(JNIEnv * env, jobject jobj) {
   /*Create a new encoder state in narrowband mode*/
   state = speex_encoder_init(&speex_wb_mode);

   /*Set the quality to 8*/
   tmp=8;
   speex_encoder_ctl(state, SPEEX_SET_QUALITY, &tmp);

   /*Initialization of the structure that holds the bits*/
   speex_bits_init(&bits);
}

jbyteArray Java_com_mycom_speex_SpeexEncodingActivity_encode(JNIEnv * env, jobject jobj, jshortArray inputData) {
        jbyteArray ret;

        jshort * inputArrayElements = (*env)->GetShortArrayElements(env, inputData, 0);

        /*Flush all the bits in the struct so we can encode a new frame*/
        speex_bits_reset(&bits);

        /*Encode the frame*/
        speex_encode_int(state, inputArrayElements, &bits);
        /*Copy the bits to an array of char that can be written*/
        nbBytes = speex_bits_nbytes(&bits);

        ret = (jbyteArray) ((*env)->NewByteArray(env, nbBytes));
        jbyte * arrayElements = (*env)->GetByteArrayElements(env, ret, 0);

        speex_bits_write(&bits, arrayElements, nbBytes);

        (*env)->ReleaseShortArrayElements(env, inputData, inputArrayElements, JNI_ABORT);
        (*env)->ReleaseByteArrayElements(env, ret, arrayElements, 0);
        return ret;
}

为了解码,我将转换后的短数组发送到解码函数,如下所示:

代码语言:javascript
复制
void Java_com_mycom_speex_SpeexEncodingActivity_initDecode(JNIEnv * env,
        jobject jobj) {

    decod_state = speex_decoder_init(&speex_wb_mode);

    tmp = 1;
    speex_decoder_ctl(decod_state, SPEEX_SET_ENH, &tmp);

    /*Initialization of the structure that holds the bits*/
    speex_bits_init(&decod_bits);
}

jshortArray Java_com_mycom_speex_SpeexEncodingActivity_decode(JNIEnv * env,
        jobject jobj, jshortArray inputData) {



    jshort * inputArrayElements = (*env)->GetShortArrayElements(env, inputData,
            0);

    /*Flush all the bits in the struct so we can decode a new frame*/
    speex_bits_reset(&decod_bits);
    /*Copy the bits to an array of char that can be written*/
    nbBytes = speex_bits_nbytes(&decod_bits);
    speex_bits_read_from(&decod_bits,inputArrayElements, nbBytes); // here it requires char * in second argument
    /*Decode the frame*/
    speex_decode_int(decod_state, &decod_bits, inputArrayElements);
    (*env)->ReleaseShortArrayElements(env, encodedData, inputArrayElements,
            JNI_ABORT);
    return inputArrayElements;
}

我的编码功能运行良好,在博客Android上Speex的JNI包装器上提供了示例

通过传递char数组并返回短数组来解码的另一个尝试如下:

代码语言:javascript
复制
jshortArray Java_com_mycom_speex_SpeexEncodingActivity_decode(JNIEnv * env,
        jobject jobj, jcharArray inputCharData) {

    jshortArray ret;
    jchar * inputArrayElements = (*env)->GetCharArrayElements(env,
            inputCharData, 0);
    /*Flush all the bits in the struct so we can decode a new frame*/
    speex_bits_reset(&decod_bits);
    /*Copy the bits to an array of char that can be written*/
    nbBytes = speex_bits_nbytes(&decod_bits);
    ret = (jshortArray)((*env)->NewShortArray(env, nbBytes));
    jshort * arrayElements = (*env)->GetShortArrayElements(env, ret, 0);

    speex_bits_read_from(&decod_bits,(char *) inputArrayElements, nbBytes);
    /*Decode the frame*/
    speex_decode_int(decod_state, &decod_bits, arrayElements);

    (*env)->ReleaseCharArrayElements(env, inputCharData, inputArrayElements,
            JNI_ABORT);
    (*env)->ReleaseShortArrayElements(env, ret, arrayElements, 0);
    return ret;
}

结果是

代码语言:javascript
复制
Returned empty array of short if i return ret and if i return arrayElements it 
gives an error Fatal signal 11 (SIGSEGV) at 0x00000018 (code=1)
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-02-15 16:52:33

speex_bits_reset在其体内执行以下操作:

代码语言:javascript
复制
bits->nbBits=0;

speex_bits_nbytes返回((位->nbBits+7)>>3);因此,如果在speex_bits_reset之后调用speex_bits_nbytes,则始终收到0。因此,必须在数组分配之前调用speex_bits_read_from:

代码语言:javascript
复制
/*Flush all the bits in the struct so we can decode a new frame*/
speex_bits_reset(&decod_bits);

/*Read bits in decod_bits struct from java array*/
speex_bits_read_from(&decod_bits,(char *) inputArrayElements, nbBytes);

/*Copy the bits to an array of char that can be written*/
nbBytes = speex_bits_nbytes(&decod_bits);
ret = (jshortArray)((*env)->NewShortArray(env, nbBytes));
jshort * arrayElements = (*env)->GetShortArrayElements(env, ret, 0);

/*Decode the frame*/
speex_decode_int(decod_state, &decod_bits, arrayElements);

(*env)->ReleaseCharArrayElements(env, inputCharData, inputArrayElements,
        JNI_ABORT);
(*env)->ReleaseShortArrayElements(env, ret, arrayElements, 0);
return ret;
票数 4
EN

Stack Overflow用户

发布于 2012-02-10 05:07:28

不知道具体的代码,但是有一些开源的Android应用程序,其中包括speex支持,您可以将其用作参考:

  • 网络电话应用程序:包括本机组件java代码
  • 基于jspeex的speexdroid (一个speex音频播放器):解码器杰斯佩克斯
票数 2
EN

Stack Overflow用户

发布于 2012-03-01 07:09:11

当你还没有重新初始化解码器时,0x000018 (code=1)出现了致命信号11 (SIGSEGV)错误。

代码语言:javascript
复制
decod_state = speex_decoder_init(&speex_wb_mode);

并尝试使用解码帧数据..。

不要忘记先从java调用initDecode()方法,然后解码帧

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9092415

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档