This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

integrate ti g.722 codec into dm6446

Hi,

I'm trying to use TI g.722 codec downloaded from TI speech codecs product page.  The binary has been integrated codec server (combo).  My user space code look like this:

    SPHENC1_Params params;
    SPHENC1_DynamicParams dyn_params;
    Buffer_Attrs buf_attrs;

    aenc_engine = Engine_open(ENGINE_NAME, NULL, NULL);
    params = Senc1_Params_DEFAULT;
    dyn_params = Senc1_DynamicParams_DEFAULT;

    aenc = Senc1_create(aenc_engine, "g722enc", &params, &dyn_params);

    buf_attrs = Buffer_Attrs_DEFAULT;
    aenc_inbuf = Buffer_create(640, &buf_attrs);
    aenc_outbuf = Buffer_create(160, &buf_attrs);

    { // test a simple sine wave
        int i;
        short *data = (short *)Buffer_getUserPtr(aenc_inbuf);

        for (i = 0; i < 160;) {
            *data = 0;     data ++; i++;
            *data = 30000;     data ++; i++;
            *data = 0;     data ++; i++;
            *data = -30000;    data ++; i++;
        }
        Buffer_setNumBytesUsed(aenc_inbuf, 320);
    }

    Senc1_process(aenc, aenc_inbuf, aenc_outbuf);

    Buffer_delete(adec_inbuf);
    Buffer_delete(adec_outbuf);
    Sdec1_delete(adec);
    Engine_close(adec_engine);

The code seems OK to run but the encoded data could not be played by other g.722 decoder.  Any idea about what part I should look into?

Another issue is, in the user guide pdf file, I noticed that codec can be configured up to 10ms/160 samples.  So how can I create a 20ms packet widely used in VOIP application?  Do I have to create 2x10ms buffer and then link them together?

Thanks in advance.

  • David,

       Can you please confirm if you are able to decoder the encoded content with TI's decoder? It is not clear which version of G722 decoder you are using to decode the content. TI's G722 implementation supports QMF(Quadrature mirror filter) and output is in RTP packet format. Please make sure your decoder supports RTP packet format.

    Yes, codec supports frame size of upto 10ms. If you want to use this for 20ms, you can make back to back encoder calls with 10ms of data for each encoder call.

    Is it possible to share the encoder output from your application?

    regards,

    Venkat

     

     

  • Thanks for the quick response. Here is the printout of the input buffer before Senc1_process and output buffer after the function.

    encoder input buffer (320 bytes):
    00 00 30 75 00 00 d0 8a 00 00 30 75 00 00 d0 8a
    ... (repeat 20 lines)

    encoder output buffer (160 bytes):
    ae 04 a3 b8 04 a0 a0 04 a4 08 a4 09 a5 0a a6 0c
    a8 0c a9 0e ab 0f ad 10 ad 11 ae 12 af 14 af 15
    b0 14 f0 14 f1 55 b1 56 fd fa f9 fb fd fb fd 7b
    7b ff fe fe fe 7f fe fd fd fd f8 f6 f8 fa fc fb
    fa fd 7e 7d 7e 7e 7c 78 79 7d 7b 77 77 79 79 78
    00 00 30 75 00 00 d0 8a 00 00 30 75 00 00 d0 8a
    00 00 30 75 00 00 d0 8a 00 00 30 75 00 00 d0 8a
    00 00 30 75 00 00 d0 8a 00 00 30 75 00 00 d0 8a
    00 00 30 75 00 00 d0 8a 00 00 30 75 00 00 d0 8a
    00 00 30 75 00 00 d0 8a 00 00 30 75 00 00 d0 8a

    And each call generate different result. For example, the output of the second Senc1_process() is:

    b3 58 b2 58 f2 18 f2 17 f6 57 b6 58 f4 16 f4 57
    b4 57 f6 1a f4 57 b5 58 f2 19 f4 57 b6 59 f4 16
    f5 58 b2 59 f4 18 f2 59 fd fa f9 fb fd fb fd 7b
    7b ff fe fe fe 7f fe fd fd fd f8 f6 f8 fa fc fb
    fa fd 7e 7d 7e 7e 7c 78 79 7d 7b 77 77 79 79 78
    00 00 30 75 00 00 d0 8a 00 00 30 75 00 00 d0 8a
    00 00 30 75 00 00 d0 8a 00 00 30 75 00 00 d0 8a
    00 00 30 75 00 00 d0 8a 00 00 30 75 00 00 d0 8a
    00 00 30 75 00 00 d0 8a 00 00 30 75 00 00 d0 8a
    00 00 30 75 00 00 d0 8a 00 00 30 75 00 00 d0 8a

    It looks like Buffer_getNumBytesUsed(aenc_output) always returns 160, but only the first 80 bytes are valid.

    I'm testing it against regular hardware and software SIP phones, e.g. Cisco, Polycom, and they can talk to each other with g.722 without any problem.

  • Also I noticed that given exactly same input buffer, in the encoder output buffer, the first 40 bytes keep changing, then the next 40 bytes remain same within the process but different next time I start the same program.  The rest 80 bytes seems just a copy of input buffer.

    From the user guide, I thought the default is 160 sample input and 40 words output (80 bytes).  Is it true?

    Is there anything about the endian?  I'm using little endian 16-bit pcm as input, so 0x30 0x75 is actually 30000 and 0xd0 0x8a is -30000.

  • Hi,

      You mentioned aenc_output always returns 160 bytes, his also points that you have set aenc_input buf size was set incorrectly to 640 bytes, Please make sure you set aenc_input buf size to 320 bytes before each encoder call

       I tried encoder with the same input samples and following is the output of encoder, for 320 bytes of input, encoder should generate 80 bytes of output, aenc_output should return only 80 bytes.

    AE 04 A3 B8 04 A0 A0 04 A4 08 A4 09 A5 0A A6 0C
    A8 0C A9 0E AB 0F AD 10 AD 11 AE 12 AF 14 AF 15
    B0 14 F0 14 F1 55 B1 56 B3 58 B2 58 F2 18 F2 17
    F6 57 B6 58 F4 16 F4 57 B4 57 F6 1A F4 57 B5 58
    F2 19 F4 57 B6 59 F4 16 F5 58 B2 59 F4 18 F2 59

    From this data, we can see your encoder output matches with our encoder output only for the first 40 bytes and remaining 40 bytes seem to be corrupted in your output. This may be because of incorrect allocation of buffer sizes.

      Yes, codec will produce different output for the same input in the subsequent calls and this is on expected lines. G722 is 64kbps codec, for every 10ms of input(320 bytes), codec produces 80 bytes of output.

     

  • Thanks for your help on this.

  • Now I set input buffer size to be 320 bytes and output buffer size 80 bytes, but still cannot generate the output shown in your reply.  Here is my output:

    encoder output buffer (160 bytes):
    ae 04 a3 b8 04 a0 a0 04 a4 08 a4 09 a5 0a a6 0c
    a8 0c a9 0e ab 0f ad 10 ad 11 ae 12 af 14 af 15
    b0 14 f0 14 f1 55 b1 56 dc ff d3 ff e7 ff e3 ff
    e1 ff e1 ff e4 ff de ff ee ff ef ff eb ff f2 ff
    fd ff f9 ff fb ff 08 00 fb ff ff ff 0b 00 04 00

    As you can see, the first 40 bytes are same as yours, but the rest of them are different.  Also I noticed the encoding function always set the size of output buffer to be 160 bytes, even only 80 bytes are valid.

    For your reference, I attached the complete source code file I am using.  Thanks.

  • Hi,

     I still think there is an issue with your input buffer descriptor to the codec.  Please see the initialization we need to do for the encoder input buffer descriptor.

      inBufs->buf = (XDAS_Int8 *) inputData; /* pointer to the speech samples buffer */
        inBufs->bufSize = 320; /*size of the input buffer in bytes */

    Output buffer size is derived from "inBufs->bufSize". As you mentioned that the output buffer size is 160 bytes, I am suspecting that you may not be initializing the bufSize field to 320. Can you please check this?

      I just verified codec with this setting and codec output buffer size is set correctly to 80 bytes inside the encoder.

    regards,

    Venkat

     

  • As shown in my code, I am using DMAI functions to manage the buffer and I believe the size should be correct:

    Line 77:  aenc_inbuf = Buffer_create(320, &buf_attrs);

    Line 100: Buffer_setNumBytesUsed(aenc_inbuf, 320);

    I used similar functions to control the buffers sent to other DSP codecs like h264 and have not seen such problem.

     

    Would you mind to share some simple code running on ARM side to generate the correct output?  Thanks.

  • David Liu36097 said:
    Would you mind to share some simple code running on ARM side to generate the correct output? 

    The codecs are tested on the DSP side directly, I am not aware of an example of this being done from the ARM side, though this has certainly been done before by customers. You can find the codec test code in the codec package under dm6446_g722enc_1_10_001_production/packages/ti/sdo/codecs/g722enc/app/Client/ if you want to verify the input and output on the DSP side.

    On the buffer size problem, it may be worth trying a smaller buffer size just to see what happens with the output you get back from the codec, in particular you could determine if the number of bytes returned from the encoder corresponds to the buffer size you pass into the encoder, this could be an issue of confusion over buffer size units.

  • I changed the input size to be 160 and 80 bytes, but the output remained same on both size (160 bytes) and content.  But when I changed the input samples, I did notice the changes in the first 40 bytes of output.

  • hello,

    Other angles to explore...

    1. init params - defaults are always tricky. The Senc1_Params_DEFAULT were tested mainly w/ g.711 - the typical practise is to assign to this baseline struct then change the delta params that are applicable for that codec - the g.722 may not support all modes hence best to eval it in same way as Client app that Bernie suggests. Codec Client app TestAppEncoder.c uses: -

    g722Params.size = sizeof (ISPHENC1_Params);
        g722Params.tablesPtr = NULL;
        g722Params.codecSelection = ITU;
        g722Params.bitRate = RATE;
        g722Params.frameSize = sample_size * 2;

    2. double check your DMAI version - even though you're on DM6446 more recent versions of DMAI will have bugfixes - https://gforge.ti.com/gf/project/dmai/scmsvn/ - check ce/Senc1.c and the latest app example as a reference to diff.

    3. turn on CE_DEBUG=2 - always a good idea for debugging these types of issues...

    4. dbl-check buf sizes again also leveraging o/p of #2 and referring to Client codec app...

    Thanks, Alan

  • Thanks for Alan's advices, it's working now after I added this line:

    params.frameSize = 320;

    before calling Senc1_create() function.

    The output is still 160 bytes, but I just use the first 80 bytes.