Android 中的 speex 支持
任何人都可以帮助我如何在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 数组并返回短数组进行解码的另一种尝试如下:
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)
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)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
speex_bits_reset 在其主体中执行以下操作:
speex_bits_nbytes 返回 ((bits->nbBits+7)>>3);
因此,如果您在 speex_bits_reset 之后立即调用 speex_bits_nbytes,您总是收到 0。因此您必须在数组分配之前调用 speex_bits_read_from:
speex_bits_reset do following in its body:
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:
不知道具体的代码,但是有一些开源 Android 应用程序包含 speex 支持,您可以将其用作参考:
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:
致命信号 11 (SIGSEGV) at 0x00000018 (code=1) 错误出现,当你没有重新初始化解码器
并尝试使用解码帧数据时,..
不要忘记调用你的
initDecode()
方法首先从 java 然后解码帧Fatal signal 11 (SIGSEGV) at 0x00000018 (code=1) Error comes,when u have not reinitialize decoder
and try to use decode frame data,..
don't forget to call your
initDecode()
method from java first and then decode frame