2012-02-01 13 views
13

¿Alguien me puede ayudar en cómo usar speex o jspeex en android?speex support en android

He buscado mucho pero no he podido encontrarlo en ninguna parte. Hay muchos problemas con respecto a esto en code.google.com/android pero ninguno lo ha respondido. Aquí también esta pregunta no obtuvo una buena respuesta ya que mi otra pregunta con respecto a esto es Decoding speex encoded byte array in Android. Entonces, si sabes algo sobre esto, por favor dame información con respecto a esto.

Necesito codificar y decodificar bytearray de archivo de audio con este códec.

He intentado Android-ndk and got encoding done, pero obteniendo un problema en la decodificación de la matriz de bytes. ¿Hay alguna otra alternativa para lograr esto?

EDITAR

mis codifican funciones de archivo nativo c son los siguientes:

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

ahora para decodificación estoy enviando la matriz corta convertido a función de decodificación de la siguiente manera:

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

mis funciones de codificación funcionan bien, el ejemplo se proporciona en el blog A JNI Wrapper for Speex on Android

Otro intento de decodificar pasando matriz de caracteres y volviendo a corto matriz es la siguiente:

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

el resultado es

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) 
+0

cuál era el problema que tienes? – nos

+0

Tengo una función de codificación que devuelve una matriz de bytes, así que tengo que pasar la matriz de bytes a la función de decodificación, pero la función 'speex_bits_read_from' toma la matriz char en su argumento. –

+0

@nos he agregado código de código nativo. por favor mira esto. –

Respuesta

3

speex_bits_reset hacer siguiente en su cuerpo:

bits->nbBits=0; 

y speex_bits_nbytes returns ((bits-> nbBits + 7) >> 3); Así que si usted llama speex_bits_nbytes justo después speex_bits_reset, que siempre recibirá 0. Por lo que debe llamar antes de la asignación speex_bits_read_from matriz:

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

No sé sobre el código específicamente , pero hay algunas aplicaciones de código abierto de Android que incluyen soporte speex, que puede usar como referencia:

0

señal 11 (SIGSEGV) en 0x00000018 (código = 1) El error viene, cuando tienes no reinicializar el decodificador

decod_state = speex_decoder_init(&speex_wb_mode); 

y tratar de usar los datos del marco de descodificación, ..

no se olvide de llamar a su método de Java initDecode() primero y luego decodificar marco