Share

Java Implementation of Speex

The forum address has changed, you have been automatically redirected. Please update any bookmarks to use the new URL.

Subscribe

Hint for encoding, transmitting and decoding!

You are viewing a single message from this topic. View all messages.

  1. 2007-09-04 12:41:34 UTC
    The trick for sending speex encoded data over the network is:

    you have to know the size of the byte[] you have to feed into the encoder and later, for decoding, in the decoder. If you choose the wrong size, you get some StreamCurroptedExceptions or some ArrayOutOfBoundsExceptions.

    After reading the speex-source, i found out, that the byte[] size, that has to be put into the encoder, is calculates as follows:

    640 * 2^mode (note: mode is from 0 to 2)

    Okay. For mode 2 i.e., this results in 2560 bytes. But how to calculate the byte[] size for decoding?

    I searched for a while for such a method (for CBR of course). But i found nothing.
    Then i decided to do some testing with code:

    ----cut----
    import java.io.StreamCorruptedException;
    import java.util.Random;

    import org.xiph.speex.SpeexDecoder;
    import org.xiph.speex.SpeexEncoder;

    public class SimpleTest {

    public static void main(String[] args) throws StreamCorruptedException {

    // iterate through the modes
    for (int mode=0;mode<3;mode++)

    // iterate through the quality
    for (int quality=0;quality<11;quality++){

    // set buffersize:
    // Mode0: 640 bytes
    // Mode1: 1280 bytes
    // Mode2: 2560 bytes
    int bsize=640;
    bsize *= Math.pow(2, mode);
    byte[] b = new byte[bsize];

    // fill in some dummy-data
    Random r = new Random();
    for (int i=0; i<b.length; i++){
    b[i] = (byte)r.nextInt();
    }

    System.out.println("\nMode="+mode+" quality="+quality+" buffersize="+b.length);

    System.out.println("Size before compression="+b.length);
    /*
    * Encode
    */
    SpeexEncoder enc = new SpeexEncoder();
    enc.init(mode, quality, 44100, 2);
    enc.processData(b, 0, b.length);

    int sizeAfterCompression = enc.getProcessedDataByteSize();
    byte[] temp = new byte[sizeAfterCompression];
    enc.getProcessedData(temp, 0);

    System.out.println("Size after compression="+sizeAfterCompression);

    /*
    * Decode
    */
    SpeexDecoder dec = new SpeexDecoder();
    dec.init(mode,44100,2,true);

    dec.processData(temp, 0, temp.length);
    int sizeAfterDecompression = dec.getProcessedDataByteSize();
    byte[] decoded = new byte[sizeAfterDecompression];

    dec.getProcessedData(decoded, 0);

    System.out.println("Size after decompression="+sizeAfterDecompression);
    }
    }
    }
    ----cut----

    With this small programm, i got data for making a simple table:

    ----cut----
    /**
    * SPEEX_BUFFER[mode][quality] -> size of the compressed buffer
    */
    private static final int[][] SPEEX_BUFFER = {
    //quality:
    //0 1 2 3 4 5 6 7 8 9 10 // mode:
    { 8, 12, 17, 23, 23, 30, 30, 40, 40, 48, 64}, // 0
    {12, 17, 22, 27, 35, 45, 54, 62, 72, 88, 108}, // 1
    {13, 21, 26, 32, 39, 49, 59, 67, 77, 93, 113} // 2
    };
    ----cut----

    Now it's easy to handle the speexencoder and speexdecoder. To realize, that it's so easy, and that this simple information was written nowhere in the documentation, was quite annoying.

    I hope this could help you guys out there, having the same problem.

    - Alex
< Previous | 1 | Next >

Add a Reply

This forum does not allow anonymous participation.

Log in to add a reply. Not registered? Create an account to participate and receive email updates when replies are posted to this topic.