speex support in android

10,651

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

Solution 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:

Share:
10,651

Related videos on Youtube

Hemant Metalia
Author by

Hemant Metalia

Great communication skills and rich domain knowledge with comprehensive understanding and practical knowledge of various languages, operating systems and databases. Reliable as a fully contributing, responsible and accountable member of task/project teams with highly creative, logical and analytical approach. Focused and hardworking and team oriented; with proven capability to meet coordinate multiple projects. Currently working as, a Technical architect at Publicis Sapient. About 11+ years of total experience working in various roles in software development. I have mainly worked in Java related frameworks and development platforms but I also have some experience of working in C, C++, javascript, angularJS projects. I am fast learner so new technology is not a barrier for me, I can adopt any technology, I consider myself as a professional programmer and given enough money can work on any programming language. Specialties: Application Development for Java platforms i.e. J2EE, Spring, Web Services, Cloud Computing and Research & Development etc. Communicate with me on : Linked In

Updated on June 04, 2022

Comments

  • Hemant Metalia
    Hemant Metalia almost 2 years

    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)