www.pudn.com > AudioCodec.rar > AudioFile.cpp


// AudioFile.cpp: implementation of the CAudioFile class. 
// 
////////////////////////////////////////////////////////////////////// 
 
#include "stdafx.h" 
#include "AudioFile.h" 
 
#include "AcmCodec.h" 
 
// G.711 and G.721  
#include "p_voice\pcm\g72x.h" 
static struct g72x_state g_g721; 
static struct g72x_state g_g721_enc; 
 
//#define GSM_MS_2FRAME 
 
// GSM 6.10 
struct gsm_state; 
extern "C" gsm_state * gsm_create(); 
extern "C" void gsm_destroy(gsm_state *); 
extern "C" void gsm_encode(gsm_state *, const short *, BYTE *); 
extern "C" void gsm_decode(gsm_state *, const BYTE *, short *); 
extern "C" void gsm_bits_ms2normal(const BYTE *, BYTE *, BYTE *); 
extern "C" void gsm_bits_normal2ms(const BYTE *, const BYTE *, BYTE *); 
static struct gsm_state * g_gsm; 
static struct gsm_state * g_gsm_enc; 
 
// G.729 
extern "C" void g729cp_init_encoder(int iVad); 
extern "C" void g729cp_encode_frame(short * pSamples, char * pBits); 
extern "C" void g729cp_init_decoder(); 
extern "C" void g729cp_decode_frame(short * pSamples, char * pBits); 
 
// G.723.1 
extern "C" void g723f_init_codec(int iVad, int iBitRate); 
extern "C" void g723f_encode_frame(short * pSamples, char * pBits); 
extern "C" void g723f_decode_frame(short * pSamples, char * pBits); 
 
// iLBC 
extern "C" void ilbc_init_codec(int iMode); 
extern "C" void ilbc_encode_frame(short * pSamples, char * pBits); 
extern "C" void ilbc_decode_frame(short * pSamples, char * pBits); 
 
#ifdef _DEBUG 
#undef THIS_FILE 
static char THIS_FILE[]=__FILE__; 
#define new DEBUG_NEW 
#endif 
 
IMPLEMENT_DYNAMIC(CAudioFile, CFile) 
 
////////////////////////////////////////////////////////////////////// 
// Construction/Destruction 
////////////////////////////////////////////////////////////////////// 
 
CAudioFile::CAudioFile() : CFile() 
{ 
} 
 
CAudioFile::~CAudioFile() 
{ 
} 
 
BOOL CAudioFile::Open(LPCTSTR lpszFileName, UINT nOpenFlags, CFileException* pError) 
{ 
	return CFile::Open(lpszFileName, nOpenFlags, pError); 
} 
 
void CAudioFile::Close() 
{ 
	CFile::Close(); 
	if (!m_bUseAcm) 
	{ 
		if (m_iType == ACM_CODEC_GSM610) 
		{ 
			FreeGSM(); 
		} 
	} 
} 
 
UINT CAudioFile::Read(void* lpBuf, UINT nCount) 
{ 
	int iSize; 
	int iLength = GetLength(); 
	char * p = (char *)malloc(iLength); 
 
	CFile::Read(p, iLength); 
 
	if (m_bUseAcm) 
	{ 
		CAcmCodec * m_pDec; 
		m_pDec = new CAcmCodec; 
		m_pDec->Init(m_iType, FALSE); 
		iSize = m_pDec->Decode((char *)lpBuf, p, iLength); 
		m_pDec->Free(); 
		delete m_pDec; 
	} 
	else 
	{ 
		iSize = Decode((unsigned char *)p, (short *)lpBuf, iLength); 
	} 
 
	free(p); 
	return iSize; 
} 
 
void CAudioFile::Write(const void* lpBuf, UINT nCount) 
{ 
	int iSize; 
	char * p = (char *)malloc(nCount); 
 
	memset(p, 0, nCount); 
	if (m_bUseAcm) 
	{ 
		CAcmCodec * m_pEnc; 
		m_pEnc = new CAcmCodec; 
		m_pEnc->Init(m_iType, TRUE); 
		iSize = m_pEnc->Encode((char *)lpBuf, p, nCount); 
		m_pEnc->Free(); 
		delete m_pEnc; 
	} 
	else 
	{ 
		iSize = Encode((short *)lpBuf, (unsigned char *)p, nCount/2); 
	} 
	CFile::Write(p, iSize); 
	free(p); 
} 
 
int CAudioFile::Decode(unsigned char * pCode, short * pSample, int iCodeLength) 
{ 
	int iSize; 
	switch (m_iType) 
	{ 
	case ACM_CODEC_PASS: 
		iSize = iCodeLength; 
		break; 
 
	case ACM_CODEC_ALAW: 
		iSize = DecodeG711a(pCode, pSample, iCodeLength); 
		break; 
 
	case ACM_CODEC_MULAW:	 
		iSize = DecodeG711u(pCode, pSample, iCodeLength); 
		break; 
 
	case ACM_CODEC_ADPCM:	 
		iSize = DecodeG721(pCode, pSample, iCodeLength); 
		break; 
 
	case ACM_CODEC_GSM610: 
		iCodeLength -= iCodeLength % 36; 
		iSize = DecodeGSM(pCode, pSample, iCodeLength); 
		break; 
 
	case ACM_CODEC_G729CP: 
		iCodeLength -= iCodeLength % 12; 
		iSize = DecodeG729cp(pCode, pSample, iCodeLength); 
		break; 
 
	case ACM_CODEC_G723_1: 
		iCodeLength -= iCodeLength % 24; 
		iSize = DecodeG723f(pCode, pSample, iCodeLength); 
		break; 
 
	case ACM_CODEC_ILBC: 
		iCodeLength -= iCodeLength % 50; 
		iSize = DecodeILBCf(pCode, pSample, iCodeLength); 
		break; 
 
	default: 
		iSize = iCodeLength * 40; 
		break; 
	} 
	return iSize; 
} 
 
int CAudioFile::Encode(short * pSample, unsigned char * pCode, int iSampleLength) 
{ 
	int iSize; 
	switch (m_iType) 
	{ 
	case ACM_CODEC_PASS: 
		iSize = iSampleLength; 
		break; 
 
	case ACM_CODEC_ALAW: 
		iSize = EncodeG711a(pSample, pCode, iSampleLength); 
		break; 
 
	case ACM_CODEC_MULAW:	 
		iSize = EncodeG711u(pSample, pCode, iSampleLength); 
		break; 
 
	case ACM_CODEC_ADPCM:	 
		iSize = EncodeG721(pSample, pCode, iSampleLength); 
		break; 
 
	case ACM_CODEC_GSM610: 
		iSampleLength -= iSampleLength % 320; 
		iSize = EncodeGSM(pSample, pCode, iSampleLength); 
		break; 
 
	case ACM_CODEC_G729CP: 
		iSampleLength -= iSampleLength % 160; 
		iSize = EncodeG729cp(pSample, pCode, iSampleLength); 
		break; 
 
	case ACM_CODEC_G723_1: 
		iSampleLength -= iSampleLength % 480; 
		iSize = EncodeG723f(pSample, pCode, iSampleLength); 
		break; 
 
	case ACM_CODEC_ILBC: 
		iSampleLength -= iSampleLength % 480; 
		iSize = EncodeILBCf(pSample, pCode, iSampleLength); 
		break; 
 
	default: 
		iSize = iSampleLength / 10; 
		break; 
	} 
	return iSize; 
} 
 
int CAudioFile::EncodeG711a(short * pSample, unsigned char * pCode, int iSampleLength) 
{ 
	int i; 
 
	for (i = 0; i < iSampleLength; i ++) 
	{ 
		pCode[i] = linear2alaw(pSample[i]); 
	} 
	return iSampleLength; 
} 
 
int CAudioFile::EncodeG711u(short * pSample, unsigned char * pCode, int iSampleLength) 
{ 
	int i; 
 
	for (i = 0; i < iSampleLength; i ++) 
	{ 
		pCode[i] = linear2ulaw(pSample[i]); 
	} 
	return iSampleLength; 
} 
 
int CAudioFile::DecodeG711a(unsigned char * pCode, short * pSample, int iCodeLength) 
{ 
	int i; 
 
	for (i = 0; i < iCodeLength; i ++) 
	{ 
		pSample[i] = alaw2linear(pCode[i]); 
	} 
	return iCodeLength * 2; 
} 
 
int CAudioFile::DecodeG711u(unsigned char * pCode, short * pSample, int iCodeLength) 
{ 
	int i; 
 
	for (i = 0; i < iCodeLength; i ++) 
	{ 
		pSample[i] = ulaw2linear(pCode[i]); 
	} 
	return iCodeLength * 2; 
} 
 
void CAudioFile::InitG721() 
{ 
	g72x_init_state(&g_g721); 
	g72x_init_state(&g_g721_enc); 
} 
 
int CAudioFile::EncodeG721(short * pSample, unsigned char * pCode, int iSampleLength) 
{ 
	int i, iVal1, iVal2; 
 
	for (i = 0; i < iSampleLength; i += 2) 
	{ 
		iVal1 = g721_encoder(pSample[i], AUDIO_ENCODING_LINEAR, &g_g721_enc); 
		iVal2 = g721_encoder(pSample[i+1], AUDIO_ENCODING_LINEAR, &g_g721_enc); 
		pCode[i/2] = (unsigned char)((iVal1<<4) + iVal2); 
	} 
 
	return iSampleLength/2; 
} 
 
int CAudioFile::DecodeG721(unsigned char * pCode, short * pSample, int iCodeLength) 
{ 
	int i, iVal; 
 
	for (i = 0; i < iCodeLength; i ++) 
	{ 
		iVal = pCode[i]; 
		pSample[i*2] = (short)g721_decoder(((iVal>>4)&0x0f), AUDIO_ENCODING_LINEAR, &g_g721); 
		pSample[i*2+1] = (short)g721_decoder((iVal&0x0f), AUDIO_ENCODING_LINEAR, &g_g721); 
	} 
 
	return iCodeLength * 4; 
} 
 
void CAudioFile::InitGSM() 
{ 
	g_gsm = gsm_create(); 
	g_gsm_enc = gsm_create(); 
} 
 
void CAudioFile::FreeGSM() 
{ 
	gsm_destroy(g_gsm); 
	gsm_destroy(g_gsm_enc); 
} 
 
int CAudioFile::DecodeGSM(unsigned char * pCode, short * pSample, int iCodeLength) 
{ 
#ifdef GSM_MS_2FRAME 
	int i, iSize = 0; 
	unsigned char pCode1[36], pCode2[36]; 
 
	for (i = 0; i < iCodeLength; i += 65) 
	{ 
		gsm_bits_ms2normal(pCode, pCode1, pCode2); 
		gsm_decode(g_gsm, pCode1, pSample); 
		pSample += 160; 
		gsm_decode(g_gsm, pCode2, pSample); 
		pSample += 160; 
		pCode += 65; 
		iSize += 640; 
	} 
	return iSize; 
#else 
	int i, iSize = 0; 
 
	for (i = 0; i < iCodeLength; i += 36) 
	{ 
		gsm_decode(g_gsm, pCode, pSample); 
		pSample += 160; 
		pCode += 36; 
		iSize += 320; 
	} 
	return iSize; 
#endif 
} 
 
int CAudioFile::EncodeGSM(short * pSample, unsigned char * pCode, int iSampleLength) 
{ 
#ifdef GSM_MS_2FRAME 
	int i, iSize = 0; 
	unsigned char pCode1[36], pCode2[36]; 
 
	for (i = 0; i < iSampleLength; i += 320) 
	{ 
		gsm_encode(g_gsm_enc, pSample, pCode1); 
		pSample += 160; 
		gsm_encode(g_gsm_enc, pSample, pCode2); 
		pSample += 160; 
		gsm_bits_normal2ms(pCode1, pCode2, pCode); 
		pCode += 65; 
		iSize += 65; 
	} 
	return iSize; 
#else 
	int i, iSize = 0; 
 
	for (i = 0; i < iSampleLength; i += 160) 
	{ 
		gsm_encode(g_gsm_enc, pSample, pCode); 
		pSample += 160; 
		pCode += 36; 
		iSize += 36; 
	} 
	return iSize; 
#endif 
} 
 
void CAudioFile::InitG729cp(BOOL bUseVAD) 
{ 
	g729cp_init_encoder((int)bUseVAD); 
	g729cp_init_decoder(); 
} 
 
int CAudioFile::EncodeG729cp(short * pSample, unsigned char * pCode, int iSampleLength) 
{ 
	int i, iSize = 0; 
 
	for (i = 0; i < iSampleLength; i += 80) 
	{ 
		g729cp_encode_frame(pSample, (char *)pCode); 
		pSample += 80; 
		pCode += 12; 
		iSize += 12; 
	} 
	return iSize; 
} 
 
int CAudioFile::DecodeG729cp(unsigned char * pCode, short * pSample, int iCodeLength) 
{ 
	int i, iSize = 0; 
 
	for (i = 0; i < iCodeLength; i += 12) 
	{ 
		g729cp_decode_frame(pSample, (char *)pCode); 
		pSample += 80; 
		pCode += 12; 
		iSize += 160; 
	} 
	return iSize; 
} 
 
void CAudioFile::InitG723f(BOOL bUseVAD, BOOL bUseHighRate) 
{ 
	g723f_init_codec((int)bUseVAD, (int)bUseHighRate); 
} 
 
int CAudioFile::EncodeG723f(short * pSample, unsigned char * pCode, int iSampleLength) 
{ 
	int i, iSize = 0; 
 
	for (i = 0; i < iSampleLength; i += 240) 
	{ 
		g723f_encode_frame(pSample, (char *)pCode); 
		pSample += 240; 
		pCode += 24; 
		iSize += 24; 
	} 
	return iSize; 
} 
 
int CAudioFile::DecodeG723f(unsigned char * pCode, short * pSample, int iCodeLength) 
{ 
	int i, iSize = 0; 
 
	for (i = 0; i < iCodeLength; i += 24) 
	{ 
		g723f_decode_frame(pSample, (char *)pCode); 
		pSample += 240; 
		pCode += 24; 
		iSize += 480; 
	} 
	return iSize; 
} 
 
void CAudioFile::InitILBCf() 
{ 
	ilbc_init_codec(30); 
} 
 
int CAudioFile::EncodeILBCf(short * pSample, unsigned char * pCode, int iSampleLength) 
{ 
	int i, iSize = 0; 
 
	for (i = 0; i < iSampleLength; i += 240) 
	{ 
		ilbc_encode_frame(pSample, (char *)pCode); 
		pSample += 240; 
		pCode += 50; 
		iSize += 50; 
	} 
	return iSize; 
} 
 
int CAudioFile::DecodeILBCf(unsigned char * pCode, short * pSample, int iCodeLength) 
{ 
	int i, iSize = 0; 
 
	for (i = 0; i < iCodeLength; i += 50) 
	{ 
		ilbc_decode_frame(pSample, (char *)pCode); 
		pSample += 240; 
		pCode += 50; 
		iSize += 480; 
	} 
	return iSize; 
} 
 
int CAudioFile::SetOptions(int iType, BOOL bUseAcm, BOOL bUseVAD, BOOL bUseHighRate) 
{ 
	int iSize, iLength = GetLength(); 
 
	m_iType = iType; 
	m_bUseAcm = bUseAcm; 
	switch (m_iType) 
	{ 
	case ACM_CODEC_PASS: 
		iSize = iLength; 
		break; 
 
	case ACM_CODEC_ALAW: 
	case ACM_CODEC_MULAW:	 
		iSize = iLength * 2; 
		break; 
 
	case ACM_CODEC_ADPCM:	 
		iSize = iLength * 4; 
		if (!m_bUseAcm) 
		{ 
			InitG721(); 
		} 
		break; 
 
	case ACM_CODEC_GSM610: 
		iSize = iLength * 10; 
		if (!m_bUseAcm) 
		{ 
			InitGSM(); 
		} 
		break; 
 
	case ACM_CODEC_G729CP: 
		iSize = iLength * 15; 
		if (!m_bUseAcm) 
		{ 
			InitG729cp(bUseVAD); 
		} 
		break; 
 
	case ACM_CODEC_G723_1: 
		iSize = iLength * 25; 
		if (!m_bUseAcm) 
		{ 
			InitG723f(bUseVAD, bUseHighRate); 
		} 
		break; 
 
	case ACM_CODEC_ILBC: 
		iSize = iLength * 15; 
		if (!m_bUseAcm) 
		{ 
			InitILBCf(); 
		} 
		break; 
 
	default: 
		iSize = iLength * 40; 
		break; 
	} 
	return iSize; 
}