版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/byxdaz/article/details/83184336
//G726EnDecoder.h
//G726编解码类(海思G726编解码类)
#if !defined(G726_EnDecoder_h)
#define G726_EnDecoder_h
#pragma once
#include <windows.h>
#include <stdio.h>
#include <mmreg.h>
#include "hi_voice_api.h"
class CG726EnDecoder
{
public:
CG726EnDecoder();
virtual ~CG726EnDecoder();
public:
BOOL Decoder_Init(int nAudioType);
BOOL Decoder_UnInit();
BOOL Decoder_DecodeFrame(char *indata, int insize, char *outdata, int *outsize);
BOOL Decoder_GetAudioTypeByOneFrameAudioData(char *pFrameData, int nFrameDataSize,int &nAudioType);
public:
BOOL Encoder_Init(int nChannels=1, DWORD nSamplesPerSec=8000, int nBitsPerSample=16, int nAudioType = G726_40KBPS);
BOOL Encoder_UnInit();
BOOL Encoder_EncodeFrame(char *indata, int insize, char *outdata, int *outsize);
void GetWavemtIn(WAVEFORMATEX &wavefmt);
private:
//解码部分
hiVOICE_G726_STATE_S m_g726_dec_state;
BOOL m_bDecodeInitActionExecuted; //解码初始化动作是否执行过
private:
//编码部分
hiVOICE_G726_STATE_S m_g726_enc_state;
WAVEFORMATEX m_wavefmtIn;
private:
BOOL m_bInit; //编码或解码是否初始化
};
#endif
//G726EnDecoder.cpp
// G726EnDecoder.cpp: implementation of the CG726EnDecoder class.
#include "G726EnDecoder.h"
#include <time.h>
CG726EnDecoder::CG726EnDecoder()
{
ZeroMemory(&m_g726_enc_state, sizeof(m_g726_enc_state));
ZeroMemory(&m_g726_dec_state, sizeof(m_g726_dec_state));
memset(&m_wavefmtIn, 0, sizeof(WAVEFORMATEX));
m_wavefmtIn.wFormatTag = WAVE_FORMAT_PCM;
m_wavefmtIn.nChannels = 1;
m_wavefmtIn.nSamplesPerSec = 8000;//44100;//8000;
m_wavefmtIn.wBitsPerSample = 16;
m_wavefmtIn.nBlockAlign = 2;
m_wavefmtIn.nAvgBytesPerSec = 16000;//88200;//16000;
m_wavefmtIn.cbSize = 0;
m_bInit = FALSE;
m_bDecodeInitActionExecuted = FALSE;
}
CG726EnDecoder::~CG726EnDecoder()
{
}
BOOL CG726EnDecoder::Decoder_Init(int nAudioType)
{
HI_RESULT hRet = 0;
try
{
hRet = HI_VOICE_DecReset(&m_g726_dec_state, nAudioType);
m_bDecodeInitActionExecuted = TRUE;
}
catch (...)
{
return FALSE;
}
if (HI_SUCCESS == hRet)
{
m_bInit = TRUE;
return TRUE;
}
else
{
return FALSE;
}
}
BOOL CG726EnDecoder::Decoder_UnInit()
{
return TRUE;
}
BOOL CG726EnDecoder::Decoder_DecodeFrame(char *indata, int insize, char *outdata, int *outsize)
{
HI_S16 len = 0;
if (!m_bInit)
{
if (!m_bDecodeInitActionExecuted)
{
int nAudioType = 0;
BOOL bGetAudioType = Decoder_GetAudioTypeByOneFrameAudioData(indata, insize, nAudioType);
if (bGetAudioType)
{
Decoder_Init(nAudioType);
}
}
else
{
return FALSE;
}
}
else
{
HI_RESULT hDecodeFrame = HI_VOICE_DecodeFrame(&m_g726_dec_state, (HI_S16*)indata, (HI_S16*)outdata, &(HI_S16)len);
if (hDecodeFrame == HI_SUCCESS)
{
//HI_S16 convert byte number
*outsize = len * 2;
return TRUE;
}
else
{
*outsize = 0;
return FALSE;
}
}
}
BOOL CG726EnDecoder::Decoder_GetAudioTypeByOneFrameAudioData(char *pFrameData, int nFrameDataSize, int &nAudioType)
{
BOOL bRet = FALSE;
if (nFrameDataSize < 24)
{
return FALSE;
}
int type = 0;
switch ((nFrameDataSize - 4) / 20)
{
case 2:
type = G726_16KBPS;
break;
case 3:
type = G726_24KBPS;
break;
case 4:
type = G726_32KBPS;
break;
case 5:
type = G726_40KBPS;
break;
default:
type = G726_40KBPS;
}
nAudioType = type;
return TRUE;
}
BOOL CG726EnDecoder::Encoder_Init(int nChannels, DWORD nSamplesPerSec, int nBitsPerSample, int nAudioType)
{
m_wavefmtIn.nChannels = nChannels;
m_wavefmtIn.nSamplesPerSec = nSamplesPerSec;//44100;//8000;
m_wavefmtIn.wBitsPerSample = nBitsPerSample;
m_wavefmtIn.nBlockAlign = nBitsPerSample/8;
m_wavefmtIn.nAvgBytesPerSec = nSamplesPerSec*nBitsPerSample*nChannels / 8;//16000;
m_wavefmtIn.cbSize = 0;
HI_RESULT hRet = 0;
try
{
hRet = HI_VOICE_EncReset(&m_g726_enc_state, nAudioType);
}
catch (...)
{
return FALSE;
}
if (hRet == HI_SUCCESS)
{
return TRUE;
}
else
{
return FALSE;
}
}
BOOL CG726EnDecoder::Encoder_UnInit()
{
return TRUE;
}
BOOL CG726EnDecoder::Encoder_EncodeFrame(char *indata, int insize, char *outdata, int *outsize)
{
HI_S16 len = 0;
HI_RESULT hRet = 0;
try
{
hRet = HI_VOICE_EncodeFrame(&m_g726_enc_state, (HI_S16*)indata, (HI_S16*)outdata, (HI_S16)(insize / 2));
if (hRet != 0)
{
*outsize = 0;
}
else
{
*outsize = (((char *)outdata)[2] + 2) * 2;
}
}
catch (...)
{
return FALSE;
}
if (hRet == HI_SUCCESS)
{
return TRUE;
}
else
{
return FALSE;
}
}
void CG726EnDecoder::GetWavemtIn(WAVEFORMATEX &wavefmt)
{
memcpy(&wavefmt, &m_wavefmtIn, sizeof(WAVEFORMATEX));
}