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

G.726 encoding problem

em
Beginner
745 Views
We're using IPP 5.1 on VS2005 inside Sipx framework.

We've added G.723 and G.729 codecs successfully but encountered problems with G.726. There is some strange noise when we listen to encoded signal on VoIP phone. We have 2 phones that produces same noise. Phone to phone signal is clear. IPP encoding is reversible, so if we encode and decode back we get original signal. When we decode signal from phone by IPP we also have noise.

Some details about code below:
- we check 32000 bitrate
- input signal is sine wave encoded in 16-bit integers (128000 bitrate, 16 bit/sample, 8000 samples/sec)

Encoder code is:

#ifdef HAVE_IPP /* [ */
#define TEST_PRINT
#include "assert.h"
// APPLICATION INCLUDES
#include "mp/MpeIPPG726.h"
#include "mp/JB/JB_API.h"
#include "os/OsSysLog.h"
#include "os/OsSysLogFacilities.h"
#include "mp/netintask.h"

#include

const MpCodecInfo MpeIPPG726::smCodecInfo16(
SdpCodec::SDP_CODEC_G726_16, // codecType
"Intel IPP 5.1", // codecVersion
false, // usesNetEq
8000, // samplingRate
16, // numBitsPerSample
1, // numChannels
80, // interleaveBlockSize
16000, // bitRate
80 * 2 * 8, // minPacketBits
80 * 2 * 8, // avgPacketBits
240 * 2 * 8, // maxPacketBits
8, // numSamplesPerFrame
&nb sp; FALSE,
FALSE ); // VAD enabled

const MpCodecInfo MpeIPPG726::smCodecInfo24(
SdpCodec::SDP_CODEC_G726_24, // codecType
"Intel IPP 5.1", // codecVersion
false, // usesNetEq
8000, // samplingRate
16, // numBitsPerSample
1, // numChannels
80, // interleaveBlockSize
24000, // bitRate
80 * 3 * 8, // minPacketBits
80 * 3 * 8, // avgPacketBits
240 * 3 * 8, // maxPacketBits
8, // numSamplesPerFrame
FALSE,
FALSE ); // VAD enabled


const MpCodecInfo MpeIPPG726::smCodecInfo32(
SdpCodec::SDP_CODEC_G726_32, // codecType
"Intel IPP 5.1", // codecVersion
false, // usesNetEq
8000, // samplingRate
16, // numBitsPerSample
1, // numChannels
80, // interleaveBlockSize
32000, // bitRate
80 * 4 * 8, // minPacketBits
80 * 4 * 8, // avgPacketBits
240 * 4 * 8, // maxPacketBits
8, // numSamplesPerFrame
FALSE,
FALSE ); // VAD enabled

const MpCodecInfo MpeIPPG726::smCodecInfo40(
SdpCodec::SDP_CODEC_G726_40, // codecType
"Intel IPP 5.1", // codecVersion
false, // usesNetEq
8000,  ; // samplingRate
16, // numBitsPerSample
1, // numChannels
80, // interleaveBlockSize
40000, // bitRate
80 * 5 * 8, // minPacketBits
80 * 5 * 8, // avgPacketBits
240 * 5 * 8, // maxPacketBits
8, // numSamplesPerFrame
FALSE,
FALSE ); // VAD enabled


//LoadedCodec MpeIPPG726::codec;

MpeIPPG726::~MpeIPPG726()
{
freeEncode();
}

OsStatus MpeIPPG726::initEncode(void)
{
int lCallResult;

ippStaticInit();
strcpy((char*)codec.codecName,"IPP_G726");
codec.lIsVad = 0;

/*Load codec by name from command line*/
lCallResult = LoadUSCCodecByName(&codec,NULL);
if(lCallResult<0)
return OS_FAILED;

/*Get USC codec params*/
lCallResult = USCCodecAllocInfo(&codec.uscParams);
if(lCallResult<0)
return OS_FAILED;

lCallResult = USCCodecGetInfo(&codec.uscParams);
if(lCallResult<0)
&n bsp; return OS_FAILED;

/*Get its supported format details*/
/* lCallResult = GetUSCCodecParamsByFormat(&codec,BY_NAME,NULL);
if(lCallResult<0)
return OS_FAILED;*/

/*Set params for encode*/
codec.uscParams.pInfo->params.direction = 0;
codec.uscParams.pInfo->params.law = 0;
codec.uscParams.pInfo->params.modes.vad = 0;
codec.uscParams.nChannels = 1;
codec.uscParams.pInfo->params.modes.bitrate = getInfo()->getBitRate();

/*Alloc memory for the codec*/
lCallResult = USCCodecAlloc(&codec.uscParams, NULL);
if(lCallResult<0)
return OS_FAILED;

/*Init decoder*/
lCallResult = USCEncoderInit(&codec.uscParams, NULL);
if(lCallResult<0)
return OS_FAILED;

// input buffer
bufferCount = 0;
// bytes per encoded packet
inputBufferSize = getInfo()->getMaxPacketBits() / 8 * (codec.uscParams.pInfo->params.framesize * codec.uscParams.pInfo->pcmType.sample_frequency / codec.uscParams.pInfo->params.modes.bitrate );
inputBuffer = (char *)ippsMalloc_8s( inputBufferSize );
ippsSet_8u( 0, (unsigned char *)inputBuffer, inputBufferSize );

return OS_SUCCESS;
}

OsStatus MpeIPPG726::freeEncode(void)
{
/*Free codec memory*/
USCFree(&codec.uscParams);

ippsFree( inputBuffer );

return OS_SUCCESS;
}


OsStatus MpeIPPG726::encode(const short* pAudioSamples,
const int numSamples,
int& rSamplesConsumed,
unsigned char* pCodeBuf,
const int bytesLeft,
int& rSizeInBytes,
UtlBoolean& sendNow,
MpAudioBuf::SpeechType& rAudioCategory)
{
int inputBuffers = inputBufferSize / (numSamples * sizeof(MpAudioSample));

// codec encodes 8 bytes to 2/3/4/5 (depending on rate)

if (bufferCount == (inputBuffers - 1) )
{
ippsCopy_8u((unsigned char *) pAudioSamples, (unsigned char *)inputBuffer+bufferCount*numSamples*sizeof(MpAudioSample), numSamples*sizeof(MpAudioSample));

float phase = 0;
IppStatus status;
//status = ippsTone_Direct_16s( (Ipp16s*)inputBuffer, inputBufferSize / 2, 32000, 0.125, &phase, IppHintAlgorithm::ippAlgHintAccurate );

char * outputBuffer = (char *)ippsMalloc_8u(bytesLeft);
ippsSet_8u(0, (unsigned char *)outputBuffer, bytesLeft);

int frmlen, infrmLen, FrmDataLen;
int inLeft = inputBufferSize, outRight = 0;

USC_PCMStream in;
USC_Bitstream out;

while( inLeft > 0 )
{
out.pBuffer = outputBuffer + outRight;

in.bitrate = codec.uscParams.pInfo->params.modes.bitrate;
in.pcmType.bitPerSample = 16;
in.pcmType.sample_frequency = 8000;
in.pBuffer = inputBuffer + inputBufferSize - inLeft;
in.nbytes = codec.uscParams.pInfo->params.framesize;

// Encode one frame
FrmDataLen = USCCodecEncode( &codec.uscParams, &in, &out, 0 );
assert( FrmDataLen > 0 );
if(FrmDataLen < 0)
return OS_FAILED;

inLeft -= FrmDataLen;
outRight += out.nbytes;
}

ippsSet_8u(0,pCodeBuf, bytesLeft);
if (outRight <= bytesLeft)
{
ippsCopy_8u((unsigned char *) outputBuffer, (unsigned char *)pCodeBuf, outRight);
rSizeInBytes = outRight;
//sendNow = TRUE;
}

rAudioCategory = MpAudioBuf::MP_SPEECH_ACTIVE;
bufferCount = 0;
ippsSet_8u(0, (unsigned char *)inputBuffer, inputBufferSize);

ippsFree( outputBuffer );
}
else
{
ippsCopy_8u((unsigned char *) pAudioSamples, (unsigned char *)inputBuffer+bufferCount*numSamples*sizeof(MpAudioSample), numSamples*sizeof(MpAudioSample));
bufferCount++;

sendNow = FALSE;
rAudioCategory = MpAudioBuf::MP_SPEECH_UNKNOWN;
}

rSamplesConsumed = numSamples;

return OS_SUCCESS;
}
#endif /* HAVE_IPP ] */
#undef TEST_PRINT

0 Kudos
2 Replies
Vyacheslav_Baranniko
New Contributor II
745 Views

Hi there,

Could you clarify some points first?I need just better understand the communication scenario prior to dive into issue investigation. Sorry, for havingso many questions. See below, inlined into your text.

Vyacheslav, IPP speech coding

[There is some strange noise when we listen to encoded signal on VoIP phone. We have 2 phones that produces same noise. ] Is a noise hearable on each side? Does each side run your Sipx implementation? Isit a noise mixedwith original signal or it is just anoise?If mixed it might be due packet losses as G726 has no PLC.

[Phone to phone signal is clear.] Do you mean a call with NOany codec involved?Or with a codec other than G726?Not IPP codec?

[IPP encoding is reversible, so if we encode and decode back we get original signal. ]Reversable offline? Outside of VoIPSipx softphonefor example inIPP speech codec command line sample? Or reversable in your Sipx VoIP, but with some noise?

[When we decode signal from phone by IPP we also have noise.] Do you usein this case G726 codec other thanIPPon transmitter? Btw, you have provided the code for encode, could you provide the code for decode also?

[- input signal is sine wave encoded in 16-bit integers (128000 bitrate, 16 bit/sample, 8000 samples/sec)] Supposed togenerate byippsTone_Direct_16s? But, in the code it is commented out //status = ippsTone_Direct_16s( (Ipp16s*)inputBuffer, inputBufferSize / 2, 32000, 0.125, &phase, IppHintAlgorithm::ippAlgHintAccurate );

0 Kudos
em
Beginner
745 Views
Thanks for reply!

[There is some strange noise when we listen to encoded signal on VoIP phone. We have 2 phones that produces same noise. ] Is a noise hearable on each side? Does each side run your Sipx implementation? Isit a noise mixedwith original signal or it is just anoise?If mixed it might be due packet losses as G726 has no PLC.

When we call from SIPX to hardware phone we hear noise on both ends. Noise is mixed with original signal.

[Phone to phone signal is clear.] Do you mean a call with NOany codec involved?Or with a codec other than G726?Not IPP codec?

When we call from one HW phone to another there is no noise.

[IPP encoding is reversible, so if we encode and decode back we get original signal. ]Reversable offline? Outside of VoIPSipx softphonefor example inIPP speech codec command line sample? Or reversable in your Sipx VoIP, but with some noise?

If we call from onr sipx to another we hear no noise.

[When we decode signal from phone by IPP we also have noise.] Do you usein this case G726 codec other thanIPPon transmitter? Btw, you have provided the code for encode, could you provide the code for decode also?

Of course hw phone doesn't use IPP


[- input signal is sine wave encoded in 16-bit integers (128000 bitrate, 16 bit/sample, 8000 samples/sec)] Supposed togenerate byippsTone_Direct_16s? But, in the code it is commented out //status = ippsTone_Direct_16s( (Ipp16s*)inputBuffer, inputBufferSize / 2, 32000, 0.125, &phase, IppHintAlgorithm::ippAlgHintAccurate );

data is generated outside but we've tested ippsTone_Direct to be sure that data isn't corrupted before entering this function

So in general we've following situation:
- phone to phone is ok
- ipp to ipp is ok
- ipp to phone = noise

It seems that whether IPP's coder is different from phone one which would be strange or we use IPP in wrong way

There is decoder:

#ifdef HAVE_IPP /* [ */
#ifdef __pingtel_on_posix__ /* [ */
#include
#include
#endif /* __pingtel_on_posix__ ] */

// APPLICATION INCLUDES
#include "mp/MpConnection.h"
#include "mp/MpdIPPG726.h"
#include "mp/JB/JB_API.h"
#include "mp/MprDejitter.h"
#include "os/OsSysLog.h"
#include "os/OsSysLogFacilities.h"

#define G726_PATTERN_LENGTH 80

const MpCodecInfo MpdIPPG726::smCodecInfo(
SdpCodec::SDP_CODEC_G726_32, // codecType
"Intel IPP 5.1", // codecVersion
false,&n bsp; // usesNetEq
8000, // samplingRate
16, // numBitsPerSample (not used)
1, // numChannels
80, // interleaveBlockSize
32000, // bitRate
160, // minPacketBits
160, // avgPacketBits
192, // maxPacketBits
80); // numSamplesPerFrame


LoadedCodec MpdIPPG726::codec;

MpdIPPG726::MpdIPPG726(int payloadType)
: MpDecoderBase(payloadType, &smCodecInfo)
{
}

MpdIPPG726::~MpdIPPG726()
{
}

OsStatus MpdIPPG726::initDecode(MpConnection* pConnection)
{
int lCallResult;

//Get JB pointer
if(pConnection != NULL) {

ippStaticInit();
mpJBState = pConnection->getJBinst();

switch (getPayloadType())
{
case SdpCodec::SDP_CODEC_G726_16:
case SdpCodec::SDP_CODEC_G726_24:
case SdpCodec::SDP_CODEC_G726_32:
case SdpCodec::SDP_CODEC_G726_40:
/* Apply codec name and VAD to codec definition structure*/
strcpy((char*)codec.codecName,"IPP_G726");
codec.lIsVad = 0;

// Set the payload number for JB
JB_initCodepoint(mpJBState, "G726", 8000, getPayloadType());
break;

default:
return OS_FAILED;
}

/*Load codec by name from command line*/
lCallResult = LoadUSCCodecByName(&codec,NULL);
if(lCallResult<0)
return OS_FAILED;

/*Get USC codec params*/
lCallResult = USCCodecAllocInfo(&codec.uscParams);
if(lCallResult<0)
return OS_FAILED;

lCallResult = USCCodecGetInfo(&codec.uscParams);
if(lCallResult<0)
return OS_FAILED;

/*Set params for decode*/
codec.uscParams.pInfo->params.direction = 1;
codec.uscParams.pInfo->params.law = 0;
codec.uscParams.nChannels = 1;
codec.uscParams.pInfo->params.modes.vad = 0;

switch( getPayloadType() )
{
case CODEC_TYPE_G726_16:
codec.uscParams.pInfo->params.modes.bitrate = 16000;
break;
case CODEC_TYPE_G726_24:
codec.uscParams.pInfo->params.modes.bitrate = 24000;
break;
case CODEC_TYPE_G726_32:
codec.uscParams.pInfo->params.modes.bitrate = 32000;
break;
case CODEC_TYPE_G726_40:
codec.uscParams.pInfo->params.modes.bitrate = 40000;
break;
}

/*Alloc memory for the codec*/
lCallResult = USCCodecAlloc(&codec.uscParams, NULL);
if(lCallResult<0)
return OS_FAILED;

/*Init decoder*/
lCallResult = USCDecoderInit(&codec.uscParams, NULL);
if(lCallResult<0)
return OS_FAILED;

return OS_SUCCESS;

}
return OS_FAILED;
}

OsStatus MpdIPPG726::freeDecode(void)
{
/*Free codec memory*/

int i,j;
for(j=0;j for(i=0; i if (codec.uscParams.uCodec.pBanks) {
if( codec.uscParams.uCodec.pBanks.pMem )
ippsFree(codec.uscParams.uCodec.pBanks.pMem);
if( codec.uscParams.uCodec.pBanks.pMem )
codec.uscParams.uCodec.pBanks.pMem = NULL;
}
}
ippsFree(codec.uscParams.uCodec.pBanks);
codec.uscParams.uCodec.pBanks = NULL;
}

return OS_SUCCESS;
}

int MpdIPPG726::decode(int numSamples, MpRtpBufPtr &rtpPacket, MpAudioSample *decoded)
{
int frmlen, infrmLen, FrmDataLen, inputLeft, outputRight;
char *inputBuffer=NULL;
char* outputBuffer;
USC_PCMStream out;
USC_Bitstream in;

infrmLen = rtpPacket->getPayloadSize();

assert( infrmLen == G726_PATTERN_LENGTH);

/*Allocate memory for the output buffer. Size of output buffer is equal to the size of 1 frame*/
  ; inputBuffer = (char*)ippsMalloc_8s( infrmLen );
outputBuffer = (char*)ippsMalloc_8s(numSamples*sizeof(MpAudioSample));

ippsZero_8u((unsigned char *)outputBuffer, numSamples*sizeof(MpAudioSample));

/* Copy input encoded buffer to local variable */
ippsCopy_8u((unsigned char *) rtpPacket->getPayload(), (unsigned char *)inputBuffer, infrmLen );

inputLeft = rtpPacket->getPayloadSize();
outputRight = 0;

while( inputLeft > 0 )
{
/*Do the pre-procession of the frame*/
in.bitrate = codec.uscParams.pInfo->params.modes.bitrate;
in.frametype = 0;
in.nbytes = codec.uscParams.pInfo->maxbitsize;
in.pBuffer = inputBuffer + rtpPacket->getPayloadSize() - inputLeft;

out.pBuffer = outputBuffer + outputRight;

/*Decode one frame*/
FrmDataLen = USCCodecDecode(&codec.uscParams, &in, &out, 0);

if(FrmDataLen < 0)
return 0;

inputLeft -= FrmDataLen;
outputRight += out.nbytes;
}

ippsCopy_8u((unsigned char *)outputBuffer, (unsigned char *) decoded,
numSamples*sizeof(MpAudioSample));

ippsFree( inputBuffer );
ippsFree( outputBuffer );

return 0;
}


#endif /* !HAVE_IPP ] */

0 Kudos
Reply