当前位置: 首页 > 面试题库 >

android中的speex支持

柯伟志
2023-03-14
问题内容

有人可以帮助我 如何在Android中使用speex或jspeex吗?

我进行了很多搜索,但找不到任何地方。code.google.com/
android中
与此相关的问题很多,但都没有答案。这里的这个问题也没有得到很好的回答,因为我对此的另一个问题是Android中的解码speex编码的字节数组。因此,如果您对此有所了解,请向我提供有关此信息。

我需要使用此编解码器对音频文件的字节数组进行编码和解码。

我已经尝试过Android-ndk并完成了编码,但是 在解码字节数组时 遇到了
问题。 还有其他替代方法可以做到这一点吗?

编辑

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

#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;
}

现在进行解码,我将转换后的短数组发送给 解码函数,如下所示:

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数组并返回short数组进行解码的另一种尝试如下:

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;
}

结果是

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)

问题答案:

speex_bits_reset在其主体中执行以下操作:

bits->nbBits=0;

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

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


 类似资料:
  • Speex是一套专门用于压缩声音的库,由于其专门针对声音,所以压缩声音的性能非常高.Speex由于其压缩性能,及0.80版后的跨平台的性能,所以在网络声音的传输中有很大的价值.但是需要注意的是speex只能对声音进行压缩,不支持音乐的压缩,如果你需要音乐的压缩你或许需要用vorbis库. 支持包括Linux、BSD、MacOS 以及 Symbian 系统。

  • 您知道将引入Android支持库的计划吗?对于promise模式,它看起来是一个很好的解决方案。

  • 嗨得到这个错误,而试图建立一个项目我导入android工作室 在ProductFlavor_装饰的{name=main,minSdkVersion=ApiVersionImpl{mApiLevel=14,mCodename='null'},targetSdkVersion=ApiVersionImpl{mApiLevel=19,mCodename='null'},renderscriptTarge

  • 问题内容: 我有一个Android Maven项目,并且难以使用ActionBar保持兼容性。 在使用 ActionBarSherlock 之前,但我看到Google发布了 v7支持库 将具有相同的目标。我决定删除对ActionBarSherlock的依赖,并使用v7。我尝试了几种方法: 1-在Eclipse IDE上将文件夹“ android-sdk \ extras \ android \ s

  • 我在Android应用程序中使用Razorpay进行支付。 目前,支付工作正常。 现在我需要使用Razorpay实现经常性支付(自动续订/订阅)。 我找不到任何干净的文件。请随时为我更新有价值的信息。

  • 1-将文件夹“android-sdk\extras\Android\support\v7\appcompat”作为Eclipse IDE上的“现有Android代码导入工作区”导入,并将其注册为库。但是项目停止了识别由框架AndroidAnnotations生成的类。例如loginactivity_ 2-使用显示此问题的存储库添加maven appcompat-v7依赖项。但是我无法编译项目,甚至