Intel® Integrated Performance Primitives
Deliberate problems developing high-performance vision, signal, security, and storage applications.

G.729 Decoding Problem.

Ken_t
Beginner
398 Views

Hi,

I've got an application that receives audio in G711, GSM610, iLBC and G729. Using the sample code found in the USC Manual I created a function that converts all these codecs in to liner PCM.

[cpp]/** brief decode audio
*
* Decodes the audio stream passed in the 2nd and 3rd parameter, generates a new array in the boost::shared pointer
* and fills in the length parameter with the size of the new array.
*
* param USC_Fxns * - Decoder to use.
* param unsigned char * - input array
* param const unsigned int & - input length
* param boost::shared_array - Output Array
* param int & - output length
* param const int & - frametype
* param const int - bitrate desired.
*/
static bool decodeGeneric(USC_Fxns * _decoder,unsigned char * _input, const unsigned int & _isize, boost::shared_array & _output, int & _osize, const int & _frametype, const int _bitrate);[/cpp]



I then call it like this:

[cpp]decodeGeneric(&USC_G729I_Fxns,_input,_isize,_output,_osize,3,8000);[/cpp]


And here is the code contained in the fuction, as you can see it's only lightly modified from the example given in the USC Manual.
[cpp]	bool decodeGeneric(USC_Fxns * _decoder,unsigned char * _input, const unsigned int & _isize, boost::shared_array & _output, int & _osize, const int & _frametype, const int _bitrate)
{

boost::shared_array codecInfoRaw;
boost::shared_array decoderMemoryRaw;
boost::shared_array memBlocksRaw;

USC_CodecInfo * codecInfo;
USC_MemBank * decoderMemory;

int infoSize;

USC_Handle hUSCDecoder;

char* tmpInputBuff=NULL;
char* tmpOutputBuff=NULL;
char* tmpOutputPCMBuff=NULL;

if(USC_NoError != _decoder->std.GetInfoSize(&infoSize))
{
return false;
}

codecInfoRaw.reset(new unsigned char[infoSize]);

codecInfo = (USC_CodecInfo *)codecInfoRaw.get();

/* Get the Gxxx codec info */
if(USC_NoError != _decoder->std.GetInfo((USC_Handle)NULL,codecInfo))
{
return false;
}

/*
decoder instance creation
*/

codecInfo->params.direction = USC_DECODE; /* Direction: decode */
codecInfo->params.modes.vad = 0; /* Suppress a silence compression */
codecInfo->params.law = 0; /* Linear PCM output. */
codecInfo->params.modes.bitrate = _bitrate;
/* Learn how many memory block needed for the encoder */

int membytes;

if(USC_NoError != _decoder->std.NumAlloc(&codecInfo->params,&membytes))
{
return false;
}


/* allocate memory for memory bank table */
decoderMemoryRaw.reset(new unsigned char[(sizeof(USC_MemBank) * membytes)]);
decoderMemory = (USC_MemBank*)decoderMemoryRaw.get();

/* Query how big has to be each block */
if(USC_NoError != _decoder->std.MemAlloc(&codecInfo->params,decoderMemory))
{
return false;
}

/* allocate memory for each block */

std::queue decoderMemoryArray;

for(int i=0; i < membytes;i++)
{
boost::shared_array m(new char[decoderMemory.nbytes]);
decoderMemoryArray.push(m);
decoderMemory.pMem = m.get();
}

/* Create decoder instance */
if(USC_NoError != _decoder->std.Init(&codecInfo->params, decoderMemory,&hUSCDecoder))
{
return false;
}
/* Correct the Gxxx codec info */
if(USC_NoError != _decoder->std.GetInfo(hUSCDecoder, codecInfo))
{
return false;
}

/* Query how big can be max output bitstream */
if(USC_NoError != _decoder->GetOutStreamSize(&codecInfo->params,codecInfo->params.modes.bitrate, _isize, &_osize))
{
return false;
}

/* allocate output bitstream buffer */
_output.reset(new unsigned char[_osize]);

USC_PCMStream out;
USC_Bitstream in;

in.bitrate = codecInfo->params.modes.bitrate;
in.nbytes = codecInfo->maxbitsize;
in.frametype = _frametype;
out.pcmType = codecInfo->pPcmTypesTbl[0];

in.pBuffer = (char *) _input;
out.pBuffer = (char *) _output.get();

for(unsigned int t = 0; t < _isize;t+=in.nbytes)
{
int ret = _decoder->Decode (hUSCDecoder, &in, &out);
if(USC_NoError != ret)
{
return false;
}

/* Move to the next frame */
if(in.nbytes > 0)
{
in.pBuffer += in.nbytes;
out.pBuffer += out.nbytes;
}
}

return true;
}[/cpp]

This code works fine for GSM610, and G711 uLaw as is. But when I pass G729 through it, it produces very quiet audio with the human voice lost in the noise if it's even detectable. I've tried enabling vad, but that didn't seem to help. I've checked the input stream and I'm getting 20 bytes for each RTP Packet so I believe all my packets are type 3 (Voice). I'm not quite sure what I'm doing wrong, any help would be appreciated.
0 Kudos
4 Replies
Ken_t
Beginner
398 Views
Just fixed a formatting error I put in when putting code on the forum. Based on what I'm seeing for data, I seem to be seeing two 10 byte frames every rtp packet with no SID frames. So I assume that I'm actually dealing with G.729 Annex A. I turned off stream mixing which I do later in the application so I was just hearing one stream and you can hear some legible audio. Unfortunately it's quiet and hard to make out though the garbage audio that I'm also getting.

Thanks.
0 Kudos
Vyacheslav_Baranniko
New Contributor II
398 Views
Quoting - Ken.t
Just fixed a formatting error I put in when putting code on the forum. Based on what I'm seeing for data, I seem to be seeing two 10 byte frames every rtp packet with no SID frames. So I assume that I'm actually dealing with G.729 Annex A. I turned off stream mixing which I do later in the application so I was just hearing one stream and you can hear some legible audio. Unfortunately it's quiet and hard to make out though the garbage audio that I'm also getting.

Thanks.

Hi,it seemsyour codeis correct.I may only suggest you to tryIPP_G729I orIPP_G729_FP decoders also, assumingyou are usingIPP_G729A now.They all areinteroperable (may consumesame bitstream), so you maysee a difference if any.
It make sence also to try C-optimized IPP library versus IPP best foryour machine, for example by callingippStatiInitCpu(ippCpuUnknown) instatic merged IPP linkage.
Vyacheslav
0 Kudos
tcorp1
Beginner
398 Views
Hey all. I have the same problem, Decoder doesn't decode bitstream properly. It's pity but it seems not working at all. :-(
0 Kudos
tcorp1
Beginner
398 Views
But I found interesting thing in ipp. You can build exe file for speech codecs, which codes and decodes files fine. It seems like problem is with building the project, or something like that. I am almoust sure that it must work well because in builded exe file it works great, and that exe file was made from ipp sources. I'll let you know if I find the answer for this problem.
Regards, Ron
0 Kudos
Reply