?? decoder.cpp
字號(hào):
//#include "stdafx.h"
#include <math.h>
#include <memory.h>
#include <float.h>
#include "LanAudio.h"
#include "Global.h"
unsigned char linear2alaw(_int16 pcm_val);
_int16 alaw2linear(unsigned char a_val);
unsigned char linear2ulaw(_int16 pcm_val);
_int16 ulaw2linear(unsigned char u_val);
unsigned char alaw2ulaw(unsigned char aval);
unsigned char ulaw2alaw(unsigned char uval);
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CLanAudioDecoder::CLanAudioDecoder(BOOL bPostFilter,EAudioCodec nCodec)
{
UsePf = bPostFilter;
Init_Decod();
Init_Dec_Cng();
// OutputDebugString("Audio Decoder Inited\n");
m_nCodec = nCodec;
m_bMute = FALSE;
}
CLanAudioDecoder::~CLanAudioDecoder()
{
}
int CLanAudioDecoder::DecodeG711(unsigned char * input,short* decode)
{
unsigned char * org_input = input;
short* org_decode = decode;
if(m_bMute)
for(int i = 0; i < G711_Frame; i++){
*decode = 0;
decode ++;
}
else{
if(m_nCodec==G711_A)
for(int i = 0; i < G711_Frame; i++){
*decode = alaw2linear(*input);
input ++;
decode ++;
}
else
for(int i = 0; i < G711_Frame; i++){
*decode = ulaw2linear(*input);
input ++;
decode ++;
}
}
input = org_input;
decode = org_decode;
return(G711_Frame);
}
int CLanAudioDecoder::DecodeG723(short * iFrame, char * cCode)
{
int i, iInfo, iSize;
short Crc = (short) 0;
Decod(DataBuff, cCode, Crc);
for (i = 0; i < Frame; i ++)
{
if (DataBuff[i] < (float)-32767.5)
iFrame[i] = -32768L;
else if (DataBuff[i] > (float)32766.5)
iFrame[i] = 32767;
else
{
if (DataBuff[i] < 0)
iFrame[i] = (short) (DataBuff[i]-(float)0.5);
else
iFrame[i] = (short) (DataBuff[i]+(float)0.5);
}
}
iInfo = cCode[0] & 0x0003;
/* Check frame type and rate information */
switch (iInfo)
{
case 0x0002 : { /* SID frame */
iSize = 4;
break;
}
case 0x0003 : { /* untransmitted silence frame */
iSize = 1;
break;
}
case 0x0001 : { /* active frame, low rate */
iSize = 20;
break;
}
default : { /* active frame, high rate */
iSize = 24;
}
}
return iSize;
}
int CLanAudioDecoder::Decode(short * iFrame, char * cCode)
{
switch (m_nCodec){
case G711_A:
case G711_U:
return(DecodeG711((unsigned char *)cCode,iFrame));
break;
case G723:
return(DecodeG723(iFrame,cCode));
break;
default:
return(0);
break;
}
}
/*
**
** Function: Init_Decod()
**
** Description: Initializes non-zero state variables
** for the decoder.
**
** Links to text: Section 3.11
**
** Arguments: None
**
** Outputs: None
**
** Return value: None
**
*/
void CLanAudioDecoder::Init_Decod(void)
{
int i;
/* Initialize decoder data structure with zeros */
::memset(&DecStat,0,sizeof(DECSTATDEF));
/* Initialize the previously decoded LSP vector to the DC vector */
for (i = 0; i < LpcOrder; i++)
DecStat.PrevLsp[i] = LspDcTable[i];
DecStat.Gain = (float)1.0;
}
/*
**
** Function: Init_Dec_Cng()
**
** Description: Initialize Dec_Cng static variables
**
** Links to text:
**
** Arguments: None
**
** Outputs: None
**
** Return value: None
**
*/
void CLanAudioDecoder::Init_Dec_Cng(void)
{
int i;
DecCng.PastFtyp = 1;
DecCng.SidGain = (float)0.0;
for (i=0; i<LpcOrder; i++)
DecCng.LspSid[i] = LspDcTable[i];
DecCng.RandSeed = 12345;
return;
}
/*
**
** Function: Decod()
**
** Description: Implements G.723.1 dual-rate decoder for a frame
** of speech
**
** Links to text: Section 3
**
** Arguments:
**
** float *DataBuff Empty buffer
** short Vinp[] Encoded frame (22/26 bytes)
**
** Outputs:
**
** float DataBuff[] Decoded frame (480 bytes)
**
** Return value:
**
** BOOL Always TRUE
**
*/
BOOL CLanAudioDecoder::Decod(float *DataBuff, char *Vinp, short Crc)
{
int i, j, g;
float Senr;
float QntLpc[SubFrames*LpcOrder];
float AcbkCont[SubFrLen];
float LspVect[LpcOrder];
float Temp[PitchMax+Frame];
float *Dpnt;
LINEDEF Line;
PFDEF Pf[SubFrames];
short Ftyp;
/*
* Decode the packed bitstream for the frame. (Text: Section 4;
* pars of sectio,d 2.17, 2.18)
*/
Line = Line_Unpk(Vinp, &Ftyp, Crc);
if (Line.Crc != (short) 0) {
if(DecCng.PastFtyp == 1)
Ftyp = 1; /* active */
else
Ftyp = 0; /* untransmitted */
}
if (Ftyp != 1) {
/* Silence frame : do noise generation */
Dec_Cng(Ftyp, &Line, DataBuff, QntLpc);
}
else {
/*
* Update the frame erasure count (Text: Section 3.10)
*/
if (Line.Crc != 0)
DecStat.Ecount++;
else
DecStat.Ecount = 0;
if (DecStat.Ecount > ErrMaxNum)
DecStat.Ecount = ErrMaxNum;
/*
* Decode the LSP vector for subframe 3. (Text: Section 3.2)
*/
Lsp_Inq(LspVect, DecStat.PrevLsp, Line.LspId, Line.Crc);
/*
* Interpolate the LSP vectors for subframes 0--2. Convert the
* LSP vectors to LPC coefficients. (Text: Section 3.3)
*/
Lsp_Int(QntLpc, LspVect, DecStat.PrevLsp);
/* Copy the LSP vector for the next frame */
for ( i = 0 ; i < LpcOrder ; i ++ )
DecStat.PrevLsp[i] = LspVect[i];
/*
* In case of no erasure, update the interpolation gain memory.
* Otherwise compute the interpolation gain (Text: Section 3.10)
*/
if (DecStat.Ecount == 0) {
g = (Line.Sfs[SubFrames-2].Mamp + Line.Sfs[SubFrames-1].Mamp) >> 1;
DecStat.InterGain = FcbkGainTable[g];
}
else
DecStat.InterGain = DecStat.InterGain*(float)0.75;
/*
* Generate the excitation for the frame
*/
for (i = 0; i < PitchMax; i++)
Temp[i] = DecStat.PrevExc[i];
Dpnt = &Temp[PitchMax];
if (DecStat.Ecount == 0) {
for (i = 0; i < SubFrames; i++) {
/* Generate the fixed codebook excitation for a
subframe. (Text: Section 3.5) */
Fcbk_Unpk(Dpnt, Line.Sfs[i], Line.Olp[i>>1], i);
/* Generate the adaptive codebook excitation for a
subframe. (Text: Section 3.4) */
Decod_Acbk(AcbkCont, &Temp[SubFrLen*i], Line.Olp[i>>1],
Line.Sfs[i].AcLg, Line.Sfs[i].AcGn);
/* Add the adaptive and fixed codebook contributions to
generate the total excitation. */
for (j = 0; j < SubFrLen; j++)
Dpnt[j] = Dpnt[j] + AcbkCont[j];
Dpnt += SubFrLen;
}
/* Save the excitation */
for (j = 0; j < Frame; j++)
DataBuff[j] = Temp[PitchMax+j];
/* Compute interpolation index. (Text: Section 3.10) */
/* Use DecCng.SidGain to store */
/* excitation energy estimation */
DecStat.InterIndx = Comp_Info(Temp, Line.Olp[SubFrames/2-1],
&DecCng.SidGain);
/* Compute pitch post filter coefficients. (Text: Section 3.6) */
if (UsePf)
for (i = 0; i < SubFrames; i++)
Pf[i] = Comp_Lpf(Temp, Line.Olp[i>>1], i);
/* Reload the original excitation */
for (j = 0; j < PitchMax; j++)
Temp[j] = DecStat.PrevExc[j];
for (j = 0; j < Frame; j++)
Temp[PitchMax+j] = DataBuff[j];
/* Clip newly generated samples in Temp array */
for (j = 0; j < Frame; j++) {
if (Temp[PitchMax+j] < (float)-32767.5)
Temp[PitchMax+j] = (float)-32768.0;
else if (Temp[PitchMax+j] > (float)32766.5)
Temp[PitchMax+j] = (float)32767.0;
}
/* Perform pitch post filtering for the frame. (Text: Section
3.6) */
if (UsePf)
for (i = 0; i < SubFrames; i++)
Filt_Lpf(DataBuff, Temp, Pf[i], i);
/* Save Lsps --> LspSid */
for (i=0; i < LpcOrder; i++)
DecCng.LspSid[i] = DecStat.PrevLsp[i];
}
else {
/* If a frame erasure has occurred, regenerate the
signal for the frame. (Text: Section 3.10) */
Regen(DataBuff, Temp, DecStat.InterIndx, DecStat.InterGain,
DecStat.Ecount, &DecStat.Rseed);
}
/* Update the previous excitation for the next frame */
for (j = 0; j < PitchMax; j++)
DecStat.PrevExc[j] = Temp[Frame+j];
/* Resets random generator for CNG */
DecCng.RandSeed = 12345;
}
/* Save Ftyp information for next frame */
DecCng.PastFtyp = Ftyp;
/*
* Synthesize the speech for the frame
*/
Dpnt = DataBuff;
for (i = 0; i < SubFrames; i++) {
/* Compute the synthesized speech signal for a subframe.
* (Text: Section 3.7)
*/
Synt(Dpnt, &QntLpc[i*LpcOrder]);
if (UsePf) {
/* Do the formant post filter. (Text: Section 3.8) */
Senr = Spf( Dpnt, &QntLpc[i*LpcOrder] ) ;
/* Do the gain scaling unit. (Text: Section 3.9) */
Scale(Dpnt, Senr);
}
Dpnt += SubFrLen;
}
return TRUE;
}
/*
**
** Function: Dec_Cng()
**
** Description: Receives Ftyp
** 0 : for untransmitted frames
** 2 : for SID frames
** Decodes SID frames
** Computes current frame excitation
** Computes current frame LSPs
**
** Links to text:
**
** Arguments:
**
** short Ftyp Type of silence frame
** LINEDEF *Line Coded parameters
** float *DataExc Current frame excitation
** float *QntLpc Interpolated frame LPC coefficients
**
** Outputs:
**
** float *DataExc
** float *QntLpc
**
** Return value: None
**
*/
void CLanAudioDecoder::Dec_Cng(short Ftyp, LINEDEF *Line, float *DataExc, float *QntLpc)
{
short temp;
int i;
if (Ftyp == 2) {
/*
* SID Frame decoding
*/
DecCng.SidGain = Dec_SidGain((short) Line->Sfs[0].Mamp);
/* Inverse quantization of the LSP */
Lsp_Inq(DecCng.LspSid, DecStat.PrevLsp, Line->LspId, 0);
}
else {
/*
* non SID Frame
*/
if (DecCng.PastFtyp == 1) {
/*
* Case of 1st SID frame erased : quantize-decode
* energy estimate stored in DecCng.SidGain
* scaling factor in DecCng.CurGain
*/
temp = Qua_SidGain(&DecCng.SidGain, 0);
DecCng.SidGain = Dec_SidGain(temp);
}
}
if (DecCng.PastFtyp == 1) {
DecCng.CurGain = DecCng.SidGain;
}
else {
DecCng.CurGain = (float) 0.875 * DecCng.CurGain
+ (float) 0.125 * DecCng.SidGain;
}
Calc_Exc_Rand(DecCng.CurGain, DecStat.PrevExc, DataExc,
&DecCng.RandSeed, Line);
/* Interpolate the Lsp vectors */
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -