Поддержка speex в android

Может ли кто-нибудь помочь мне в использовании speex или jspeex в андроиде?

Я много искал, но не смог найти нигде. В code.google.com/android есть много проблем, но никто не ответил на это. Здесь также этот вопрос не получил хорошего ответа, так как мой другой вопрос относительно этого – декодирование закодированного байтового массива с расширением speex в Android . Итак, если вы что-то знаете об этом, пожалуйста, предоставьте мне информацию об этом.

Мне нужно кодировать и декодировать bytearray аудиофайла с помощью этого кодека.

Я пробовал 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; } 

Мои функции кодирования работают отлично, пример представлен в блоге . JNI Wrapper для Speex на Android

Еще одна попытка декодирования путем передачи массива 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) 

Speex_bits_reset выполняет следующие действия в своем теле:

 bits->nbBits=0; 

И speex_bits_nbytes возвращает ((bits-> nbBits + 7) >> 3); Поэтому, если вы вызываете speex_bits_nbytes сразу после speex_bits_reset, вы всегда получаете 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; 

Не знаю о коде специально, но есть несколько приложений Android с открытым исходным кодом, которые включают поддержку speex, которую вы можете использовать в качестве ссылки:

  • Sipdroid (приложение voip): включает встроенный компонент и код Java
  • Speexdroid (аудиоплеер speex) на основе jspeex: Decoder и jspeex

Фатальный сигнал 11 (SIGSEGV) при 0x00000018 (код = 1) Приходит ошибка, когда u не повторно инициализирует декодер

 decod_state = speex_decoder_init(&speex_wb_mode); 

И попытайтесь использовать данные кадра декодирования, ..

Не забудьте initDecode() вызвать ваш initDecode() из java, а затем декодировать кадр