G726编解码类

版权声明:本文为博主原创文章,未经博主允许不得转载。 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));
}

猜你喜欢

转载自blog.csdn.net/byxdaz/article/details/83184336