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

Echo Chancelation with IPP

harald85
Beginner
983 Views
Hallo
I need the echo chancelor for a kernel driver in windows. I used it like the example in the IPP samples. I only changed the Function for allocatin memory. I use the default values for getinfo. For Echotail I use 20ms. I have a buffer with 160Byte (8Khz and 16 bit alaw). When is set echotail to 100ms is then a buffer in the EC which saves the last 100ms? With my code i get an buffer with noise as output.

initialize:
[cpp]EnumerateStaticLinkedEC();
ec_status = LoadECByName("IPP_EC_FP", &ec_params);
ec_status = ec_params.pUSC_EC_Fxns->std.GetInfo((USC_Handle)NULL, &ec_params.pInfo);
ec_params.pUSC_EC_Fxns->std.NumAlloc((const USC_EC_Option *)&ec_params.pInfo.params, &ec_params.nBanks);
ec_params.pBanks = (USC_MemBank*)ExAllocatePoolWithTag(PagedPool, sizeof(USC_MemBank)*ec_params.nBanks, 111);
ec_params.pUSC_EC_Fxns->std.MemAlloc((const USC_EC_Option *)&ec_params.pInfo.params, ec_params.pBanks);
for(int it = 0; it < ec_params.nBanks ;it++)
ec_params.pBanks[it].pMem = (char *)ExAllocatePoolWithTag(PagedPool, >ec_params.pBanks[it].nbytes, 111);
ec_status = ec_params.pUSC_EC_Fxns->std.Init((const USC_EC_Option *)&ec_params.pInfo.params,
ec_params.pBanks, &ec_params.objEC);[/cpp]

use:

[cpp]ippsConvert_8s16s((Ipp8s *)datalist->item[data_index].data, ec_send_buffer,160);
ippsConvert_8s16s((Ipp8s *)data_in, ec_recv_buffer,160);
ec_status = ec_params.pUSC_EC_Fxns->CancelEcho(ec_params.objEC,
ec_recv_buffer,
ec_send_buffer,
ec_outbuffer);

uint len = 160;
ippsConvertUTF_16u8u((const Ipp16u *)ec_outbuffer, &len, (uchar *)rtp_send_tmp, &len, 1);[/cpp]

The buffer datalist->item[data_index].data, data_in and rtp_send_tmp are from type uchar. So i used the convert functions. Is this rigth?

Thanks

Harald

0 Kudos
5 Replies
Vyacheslav_Baranniko
New Contributor II
983 Views
Quoting - harald85
Hallo
I need the echo chancelor for a kernel driver in windows. I used it like the example in the IPP samples. I only changed the Function for allocatin memory. I use the default values for getinfo. For Echotail I use 20ms. I have a buffer with 160Byte (8Khz and 16 bit alaw). When is set echotail to 100ms is then a buffer in the EC which saves the last 100ms? With my code i get an buffer with noise as output.

initialize:
[cpp]EnumerateStaticLinkedEC();
ec_status = LoadECByName("IPP_EC_FP", &ec_params);
ec_status = ec_params.pUSC_EC_Fxns->std.GetInfo((USC_Handle)NULL, &ec_params.pInfo);
ec_params.pUSC_EC_Fxns->std.NumAlloc((const USC_EC_Option *)&ec_params.pInfo.params, &ec_params.nBanks);
ec_params.pBanks = (USC_MemBank*)ExAllocatePoolWithTag(PagedPool, sizeof(USC_MemBank)*ec_params.nBanks, 111);
ec_params.pUSC_EC_Fxns->std.MemAlloc((const USC_EC_Option *)&ec_params.pInfo.params, ec_params.pBanks);
for(int it = 0; it < ec_params.nBanks ;it++)
ec_params.pBanks[it].pMem = (char *)ExAllocatePoolWithTag(PagedPool, >ec_params.pBanks[it].nbytes, 111);
ec_status = ec_params.pUSC_EC_Fxns->std.Init((const USC_EC_Option *)&ec_params.pInfo.params,
ec_params.pBanks, &ec_params.objEC);[/cpp]

use:

[cpp]ippsConvert_8s16s((Ipp8s *)datalist->item[data_index].data, ec_send_buffer,160);
ippsConvert_8s16s((Ipp8s *)data_in, ec_recv_buffer,160);
ec_status = ec_params.pUSC_EC_Fxns->CancelEcho(ec_params.objEC,
ec_recv_buffer,
ec_send_buffer,
ec_outbuffer);

uint len = 160;
ippsConvertUTF_16u8u((const Ipp16u *)ec_outbuffer, &len, (uchar *)rtp_send_tmp, &len, 1);[/cpp]

The buffer datalist->item[data_index].data, data_in and rtp_send_tmp are from type uchar. So i used the convert functions. Is this rigth?

Thanks

Harald

Hi Harald

Several notes:

1) EC works with linear PCM, so if your input is 8bit alaw then useippsALawToLin_8u16s to convert from alaw to linear before EC.EC output is linear PCM.If you need to convert outputback to 8bit alaw useippsLinToALaw_16s8u function,the ippsConvertUTF_16u8u function is about UTF regular expressions.EC frame size is 10ms, so CancelEcho function takes80 linear samples (160 bytes) for 8KHz,buffering is done by EC internally.10msalaw contains 80 bytes, afterconvertion ippsALawToLin_8u16(pAlaw, pLin, 80)it will be80 linear samples (160 bytes).

2) It is ok to use default EC settings after GetInfo().Echotail is set to 16 ms as default, youmay need to change it biggervalue (below 200ms), then set params->echotail properly.

3)EC is done in floating-point arithmetic, sofor an application in driver mode followguideline for WDM driver, see for example:http://msdn.microsoft.com/en-us/library/aa489566.aspx: andwrap use of ECbetween calls to KeSaveFloatingPointState and KeRestoreFloatingPointState.

Regards
Vyacheslav, IPP, Speech Coding
0 Kudos
harald85
Beginner
983 Views
Hi

Thank you for your answer. THe Problem with the buffer is solved but the echo cancellation didn't work. The noise reduction works fine but the echo not. I also used the KeSaveFloatingPointState ad the KeRestoreFloatingPointState. When i set the echo tail to 100ns and the echo is after 20 ms is the echo then cancelled?

[cpp]        pInfo->params.algType = EC_FASTSUBBAND;			// used algorithmus, EC_FULLBAND, EC_SUBBAND, EC_FASTSUBBAND (defined esc_ec.h)
        pInfo->params.pcmType.sample_frequency = 8000;	// sample frequency
        pInfo->params.pcmType.bitPerSample = 16;		// bits per sample
        pInfo->params.pcmType.nChannels = 1;			// number of chancels
        pInfo->params.echotail = 100;					// in ms (range 1-200)
        pInfo->params.modes.adapt = AD_OFF;				// type of the adaptation (AD_FULLADAPT and AD_LITEADAPT makes an bluescreen)
        pInfo->params.modes.zeroCoeff = 1;				// zero filter's coefficient
        pInfo->params.modes.nlp = 1;					// none linear processor
        pInfo->params.modes.cng = 1;					// confort noise generation
        pInfo->params.modes.td = 1;						// tone disabler
        pInfo->params.modes.ah = 0;						// anti howling
        pInfo->params.modes.ap = 0;						// affine projection
        pInfo->params.modes.nr = 4;						// noise reduction[/cpp]

EC Code:
[cpp]// set the pointer for EC to the right buffer
								ec_p_insin	= (char*)datalist->item[tmp_session->data_index].data;
								ec_p_inrin	= (char*)tmp_session->data_in;
								
								ec_p_sin	= (char*)tmp_session->ec_send_buffer;
								ec_p_rin	= (char*)tmp_session->ec_recv_buffer;
								ec_p_sout	= (char*)tmp_session->ec_outbuffer;
								*cvtLen = 160;

								data_int->codec_status = USC_CvtToLiniar(&tmp_session->gsm_codec_enc.uscParams, 6, &ec_p_insin, cvtLen, &ec_p_sin, outlen);
								data_int->codec_status = USC_CvtToLiniar(&tmp_session->gsm_codec_enc.uscParams, 6, &ec_p_inrin, cvtLen, &ec_p_rin, outlen);

								// cancel echo function (uscObj, sendin, recvin, sendout)
								fpu_status = KeSaveFloatingPointState(&fpu_save);
								if(fpu_status == STATUS_SUCCESS)
									for(int z = 0; z < 2; z++)
										ec_status = tmp_session->ec_params.pUSC_EC_Fxns->CancelEcho(tmp_session->ec_params.objEC,
															(short*)tmp_session->ec_send_buffer + 80 * z,
															(short*)tmp_session->ec_recv_buffer + 80 * z,
															(short*)tmp_session->ec_outbuffer + 80 * z);
								else
									DbgPrint("ITCTECCTIDevice::workthread: error saving floatingpointstaten");
								fpu_status = KeRestoreFloatingPointState(&fpu_save);
								if(fpu_status != STATUS_SUCCESS)
									DbgPrint("ITCTECCTIDevice::workthread: error restore floatingpointstaten");
								
								if(ec_status != USC_NoError)
									DbgPrint("ITCTECCTIDevice::workthread: error at cancelecho functionn");
								data_int->codec_status = USC_CvtToLaw(&tmp_session->g729_codec_dec.uscParams, 6, (char*)tmp_session->ec_outbuffer, outlen);
								if(data_int->codec_status < 0)
									DbgPrint("Error during USC_CvtToLawn");
								
								RtlCopyMemory(rtp_send_tmp + RTP_PACKETSIZE_MAX * data_int->i + RTP_HEADER_SIZE, tmp_session->ec_outbuffer,*outlen); [/cpp]

Can you please take a short look to the code if there is any error. I call the cancelecho function twice to cancel the echo for the 320 Byte PCM (160Byte Alaw).

Thanks

Harald

Quoting - Vyacheslav Barannikov
Hi Harald

Several notes:

1) EC works with linear PCM, so if your input is 8bit alaw then useippsALawToLin_8u16s to convert from alaw to linear before EC.EC output is linear PCM.If you need to convert outputback to 8bit alaw useippsLinToALaw_16s8u function,the ippsConvertUTF_16u8u function is about UTF regular expressions.EC frame size is 10ms, so CancelEcho function takes80 linear samples (160 bytes) for 8KHz,buffering is done by EC internally.10msalaw contains 80 bytes, afterconvertion ippsALawToLin_8u16(pAlaw, pLin, 80)it will be80 linear samples (160 bytes).

2) It is ok to use default EC settings after GetInfo().Echotail is set to 16 ms as default, youmay need to change it biggervalue (below 200ms), then set params->echotail properly.

3)EC is done in floating-point arithmetic, sofor an application in driver mode followguideline for WDM driver, see for example:http://msdn.microsoft.com/en-us/library/aa489566.aspx: andwrap use of ECbetween calls to KeSaveFloatingPointState and KeRestoreFloatingPointState.

Regards
Vyacheslav, IPP, Speech Coding

0 Kudos
harald85
Beginner
983 Views
Hi
A short update to my problem. I can use now the Full Adapt mode and the NR works fine but it generates silence at the beginning of an call. Is this because of the fast change of the noise?

My secon problem is again the EC. When i set the echotail to 16ms an geve him the same buffer twice i get silence which is ok. But when i give him some different buffers an set the echotail to 100 it didn't work. I thougth that every echo in the next 100ms is cancelled?

Please help

Harald
0 Kudos
Vyacheslav_Baranniko
New Contributor II
983 Views
Quoting - harald85
Hi
A short update to my problem. I can use now the Full Adapt mode and the NR works fine but it generates silence at the beginning of an call. Is this because of the fast change of the noise?

My secon problem is again the EC. When i set the echotail to 16ms an geve him the same buffer twice i get silence which is ok. But when i give him some different buffers an set the echotail to 100 it didn't work. I thougth that every echo in the next 100ms is cancelled?

Please help

Harald

The best choice would beto use EC_SUBBAND mode. Since IPP60it suppose to work well in accoustic echo case.

Vyacheslav
0 Kudos
soimattrang
Beginner
983 Views
Quoting - harald85
Hi

Thank you for your answer. THe Problem with the buffer is solved but the echo cancellation didn't work. The noise reduction works fine but the echo not. I also used the KeSaveFloatingPointState ad the KeRestoreFloatingPointState. When i set the echo tail to 100ns and the echo is after 20 ms is the echo then cancelled?

[cpp]       
[/cpp]
Hi harald85

Did you solve your EC problem? I have same problem with you, too.

I have three callback functions:
  • void OnCaptureAudio(void*pData, int nSize, LPVOID pUser) : retrieve audio data from microphone
  • void OnRecieveData(LPBYTE pData, int nSize, LPVOID pUser): recieve audio data from remote party
  • void OnCancelEcho(void* pData, int nSize, LPVOID pUser): get data after call CancelEcho function and send to remote party
I implement they follow:

void CEchoCancelerDlg::OnRecieveData(LPBYTE pData,int nSize,LPVOID pUser)
{

CEchoCancelerDlg* pThis=(CEchoCancelerDlg*)pUser;
/*copy data to Rin buffer*/
memcpy(pRin,pData,nSize);
nRin=nSize;

/*OUT to speaker*/
pThis->pPlayer->Start(pData,nSize);

}


void CEchoCancelerDlg::OnCaptureAudio(void *pData, int size, void* lpUser)
{

CEchoCancelerDlg* pThis=(CEchoCancelerDlg*)lpUser;
/*Do EchoCancel here*/

pThis->pEngine->DoCancelEcho((unsigned char*)pData,size,pRin,nRin);

}

void CEchoCancelerDlg::OnCancelEcho(void* pData,int nSize,void* m_pUser)
{
CEchoCancelerDlg* pThis=(CEchoCancelerDlg*)m_pUser;
pThis->pUdpSocket->SendTo((unsigned char*)pData,nSize,inet_addr(pThis->dstIpAddr),50060);
}

I call the DoCancelEcho function to cancel the echo for 160 byte PCM. I take two same buffers for rin and sin then the result is silence which is ok. But when i give him some differences buffers and the result is the echo still appearing. did I implement incorrect?


0 Kudos
Reply