2012-02-01 7 views
13

Qualcuno può aiutarmi su come utilizzare speex o jspeex in Android?supporto speex in android

Ho cercato molto ma non sono riuscito a trovarlo da nessuna parte. Ci sono molti problemi in merito a questo in code.google.com/android ma nessuno ha risposto. Anche qui questa domanda non ha avuto una buona risposta dato che un'altra mia domanda su questo è Decoding speex encoded byte array in Android. Quindi se ne sapete qualcosa allora per favore fornitemi informazioni a riguardo.

Ho bisogno di codificare e decodificare bytearray di file audio utilizzando questo codec.

Ho provato Android-ndk and got encoding done, ma ho riscontrato un problema di nella decodifica dell'array di byte. C'è qualche altra alternativa per raggiungere questo obiettivo?

EDIT

le mie funzioni di codifica nel file nativo c sono i seguenti:

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

ora decodifica io mando breve serie convertito in funzione di decodifica come segue:

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

le mie funzioni di codifica funzionano correttamente, l'esempio è fornito su il blog A JNI Wrapper for Speex on Android

Un altro tentativo di decodifica passando array di caratteri e la restituzione di breve array è come segue:

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

il risultato è

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

Qual è stato il problema che hai? – nos

+0

Ho una funzione di codifica che restituisce una matrice di byte, quindi devo passare la matrice di byte alla funzione di decodifica, ma la funzione speex_bits_read_from' accetta l'array di caratteri nel suo argomento. –

+0

@nos ho aggiunto il codice del codice nativo. per favore guarda questo –

risposta

3

speex_bits_reset fare in seguito nel suo corpo:

bits->nbBits=0; 

e speex_bits_nbytes restituisce ((bit-> nbBits + 7) >> 3); Quindi, se si chiama speex_bits_nbytes subito dopo speex_bits_reset, si riceve sempre 0. Quindi è necessario chiamare speex_bits_read_from prima dell'allocazione matrice:

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

Non so il codice specifico ma ci sono alcune applicazioni Android open source che includono il supporto speex, che puoi usare come riferimento:

0

segnale Fatal 11 (SIGSEGV) a 0x00000018 (codice = 1) Errore arriva, quando u hanno non reinizializzare decoder

decod_state = speex_decoder_init(&speex_wb_mode); 

e tenta di utilizzare i dati della struttura decodifica, ..

non dimenticare di chiamare il metodo di initDecode() da Java e poi decodificare telaio