📄 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;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -