speex support in android

匿名 (未验证) 提交于 2019-12-03 02:45:02

问题:

Can anybody help me on how to use speex or jspeex in android?

I have searched a lot but could not able to find anywhere.There are many issues regarding this in code.google.com/android but none have answered it. Here also this question did not got a good response as my another question regarding this is Decoding speex encoded byte array in Android. So If you know something about this then Please provide me information regarding this.

I need to encode and decode bytearray of audio file using this codec.

I have tried Android-ndk and got encoding done, but getting a problem in decoding the byte array. Is there any other alternative to achieve this?

EDIT

my encoding Functions in native c file are as follow:

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

now for decoding i am sending the converted short array to decode function as follow:

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

my Encoding functions are working fine the example is provided on the blog A JNI Wrapper for Speex on Android

Another attempt to decoding by passing char array and returning short array is as follow:

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

the result is

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) 

回答1:

speex_bits_reset do following in its body:

bits->nbBits=0; 

and speex_bits_nbytes returns ((bits->nbBits+7)>>3); So if you call speex_bits_nbytes right after speex_bits_reset, you always receive 0. So you must call speex_bits_read_from before array allocation:

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


回答2:

Don't know about the code specifically, but there are a few open-source Android applications out there which include speex support, which you could use as a reference:



回答3:

Fatal signal 11 (SIGSEGV) at 0x00000018 (code=1) Error comes,when u have not reinitialize decoder

decod_state = speex_decoder_init(&speex_wb_mode); 

and try to use decode frame data,..

don't forget to call your initDecode() method from java first and then decode frame



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!