📄 decodeqam.cpp
字号:
BYTE y = x & 0x08;
y |= (((y & 0x08) >> 1) ^ (x & 0x04));
y |= (((y & 0x04) >> 1) ^ (x & 0x02));
y |= (((y & 0x20) >> 1) ^ (x & 0x01));
return y;
}
BOOL CDecodeQAM::BitsScramble(LPBYTE lpData, DWORD dwLen)
{
long int M_SEQ_V29 = 0;
BYTE data_out = 0;
BYTE bit = 0;
for (int n = 0; n < dwLen; n++)
{
data_out = 0;
for (int m = 0; m < 8; m++)
{
M_SEQ_V29 <<= 1;
bit = ((M_SEQ_V29 >> 18) & 0x01) ^ ((M_SEQ_V29 >> 23) & 0x01) ^ ((lpData[n] >> (7-m)) & 0x01);
data_out |= (bit << (7-m));
M_SEQ_V29 += bit;
}
lpData[n] = data_out;
}
#if 0
// 设置扰码器的起始状态:1010 1011 1011 0011 0111 010
BYTE M_SEQ_V1729[23] = {1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0};
BYTE data_out = 0;
BYTE bit = 0;
BYTE tmp = 0;
for (int n = 0; n < dwLen; n++)
{
data_out = 0;
tmp = 0;
for (int m = 0; m < 8; m++)
{
// 得到扰码后的数据 data_in ^ M_SEQ_V1729[17] ^ M_SEQ_V1729[22]
bit = ((lpData[n] >> (7-m)) & 0x01) ^ (M_SEQ_V1729[17] ^ M_SEQ_V1729[22]);
data_out |= (bit << (7 - m));
//tmp = M_SEQ_V1729[17] ^ M_SEQ_V1729[22];
for (int i = 21; i >= 0; i--)
{
M_SEQ_V1729[i+1] = M_SEQ_V1729[i];
}
M_SEQ_V1729[0] = bit; //tmp;
}
lpData[n] = data_out;
}
#endif
return TRUE;
}
void CDecodeQAM::GenerateSRRC()
{
const double a = 0.2;
const double M_PI = 2*asin(1.0);
const int M_SAMPLE_RATE = 48000; //48k采样
const int M_BAND_RATE = 2400; // 波特率
const int M_SAMPLE_PER_BAND = (M_SAMPLE_RATE/M_BAND_RATE); // 每个波特的采样点
const int M_FIRST_INDEX = 0;
const int M_LAST_INDEX = 120;
const int M_CORE_INDEX = 60;
unsigned int index = 0;
// 设h0
SRRC[M_CORE_INDEX] = 1.0;
for (int N = M_FIRST_INDEX; N <= M_LAST_INDEX; N++)
{
if (N == M_CORE_INDEX)
{
continue;
}
double t_Div_Tc = (double)(N-M_CORE_INDEX)/(double)M_SAMPLE_PER_BAND;
/*SRRC[N] = SRRC[M_CORE_INDEX] * (sin(M_PI*(double)(N-M_CORE_INDEX)/(double)M_SAMPLE_PER_BAND) *
cos(a*M_PI*(double)(N-M_CORE_INDEX)/(double)M_SAMPLE_PER_BAND)) /
((M_PI*(double)(N-M_CORE_INDEX)/(double)M_SAMPLE_PER_BAND) *
(1-4*a*a*((double)(N-M_CORE_INDEX)/(double)M_SAMPLE_PER_BAND)*
((double)(N-M_CORE_INDEX)/(double)M_SAMPLE_PER_BAND)));*/
/* 平方根升余弦滚降时域表达式:
sin(pi*(t/Tc)*(1-a)) + 4a(t/Tc)*cos(pi*(t/Tc)*(1+a))
h(t) = -----------------------------------------------------
pi * (t/Tc) * (1-(4a(t/Tc))^2)
*/
if (abs(N-M_CORE_INDEX) != 25)
{
SRRC[index++] = (sin(M_PI*(1-a)*t_Div_Tc) + 4*a*t_Div_Tc*cos(M_PI*(1+a)*t_Div_Tc)) / (M_PI*t_Div_Tc*(1-(4*a*t_Div_Tc)*(4*a*t_Div_Tc)));
}
}
// 值域微调
SRRC[0] = SRRC[1] = SRRC[2] = SRRC[3] = 0.0f;
SRRC[119] = SRRC[118] = SRRC[117] = SRRC[116] = 0.0f;
SRRC[M_CORE_INDEX-25] = (SRRC[M_CORE_INDEX-24] + SRRC[M_CORE_INDEX-26]) / 2;
SRRC[M_CORE_INDEX+25] = (SRRC[M_CORE_INDEX+24] + SRRC[M_CORE_INDEX+26]) / 2;
/*for (int i = 0; i < 120; i++)
{
TRACE("SRRC[%d]=%f \n", i, SRRC[i]);
}*/
}
BYTE CDecodeQAM::CalcPhaseOffset(BYTE Q2Q3Q4)
{
BYTE nPhaseOffset = 0;
switch (Q2Q3Q4 & 0x07)
{
case 0x00: // 45'
nPhaseOffset = 1;
break;
case 0x01: // 0'
nPhaseOffset = 0;
break;
case 0x02: // 90'
nPhaseOffset = 2;
break;
case 0x03: // 135'
nPhaseOffset = 3;
break;
case 0x04: // 270'
nPhaseOffset = 6;
break;
case 0x05: // 315'
nPhaseOffset = 7;
break;
case 0x06: // 225'
nPhaseOffset = 5;
break;
case 0x07: // 180'
nPhaseOffset = 4;
break;
default:
break;
}
return nPhaseOffset;
}
BOOL CDecodeQAM::MapConstellation(BYTE Q1, BYTE nPhase, int* I, int* Q)
{
*I = 0;
*Q = 0;
switch (nPhase)
{
case 0x00:
*I = ((Q1&0x01) == 0) ? 3 : 5;
*Q = 0;
break;
case 0x01:
*I = ((Q1&0x01) == 0) ? 1 : 3;
*Q = ((Q1&0x01) == 0) ? 1 : 3;
break;
case 0x02:
*I = 0;
*Q = ((Q1&0x01) == 0) ? 3 : 5;
break;
case 0x03:
*I = ((Q1&0x01) == 0) ? -1 : -3;
*Q = ((Q1&0x01) == 0) ? 1 : 3;
break;
case 0x04:
*I = ((Q1&0x01) == 0) ? -3 : -5;
*Q = 0;
break;
case 0x05:
*I = ((Q1&0x01) == 0) ? -1 : -3;
*Q = ((Q1&0x01) == 0) ? -1 : -3;
break;
case 0x06:
*I = 0;
*Q = ((Q1&0x01) == 0) ? -3 : -5;
break;
case 0x07:
*I = ((Q1&0x01) == 0) ? 1 : 3;
*Q = ((Q1&0x01) == 0) ? -1 : -3;
break;
default:
return FALSE;
break;
}
return TRUE;
}
void CDecodeQAM::WriteToWaveFile(LPBYTE lpBuffer, DWORD dwLen)
{
CFile File;
if( !File.Open( "K:\\Fax\\a.wav", CFile::modeReadWrite || CFile::modeCreate ))
{
return;
}
//WAV 的头数据
BYTE m_WaveHead[44] = {0x52, 0x49, 0x46, 0x46, //ChunkID "RIFF"
0x00, 0x00, 0x00, 0x00, //ChunkSize 需要计算
0x57, 0x41, 0x56, 0x45, //Format "WAVE"
0x66, 0x6D, 0x74, 0x20, //SubChunk1ID "fmt "
0x10, 0x00, 0x00, 0x00, //SubChunk1Size
0x01, 0x00, //AudioFormat
0x01, 0x00, //NumChannels
0x80, 0xBB, 0x00, 0x00, //SampleRate
0x80, 0xBB, 0x00, 0x00, //ByteRate
0x01, 0x00, //BlockAlign
0x08, 0x00, //BitsPerSample
0x64, 0x61, 0x74, 0x61, //SubChunk2ID "DATA"
0x00, 0x00, 0x00, 0x00 //SubChunk2Size 需要计算
};
/* 计算WAVE 文件的实际长度 */
m_WaveHead[4] = (BYTE)((dwLen + 36) & 0x000000FF);
m_WaveHead[5] = (BYTE)(((dwLen + 36) & 0x0000FF00) >> 8);
m_WaveHead[6] = (BYTE)(((dwLen + 36) & 0x00FF0000) >> 16);
m_WaveHead[7] = (BYTE)(((dwLen + 36) & 0xFF000000) >> 24);
m_WaveHead[40] = (BYTE)(dwLen & 0x000000FF);
m_WaveHead[41] = (BYTE)((dwLen & 0x0000FF00) >> 8);
m_WaveHead[42] = (BYTE)((dwLen & 0x00FF0000) >> 16);
m_WaveHead[43] = (BYTE)((dwLen & 0xFF000000) >> 24);
File.Write(m_WaveHead, 44);
File.Write(lpBuffer, dwLen);
File.Flush();
File.Close();
}
BOOL CDecodeQAM::SRRCFilter(int *piInData, unsigned int uiInLen, double *pOutData, unsigned int *puiOutLen)
{
const int M_SAMPLE_PER_BAND = 20;
int iLoop = 0;
int iSubLoop = 0;
GenerateSRRC();
for (iLoop = 0; iLoop < uiInLen; iLoop++)
{
int nStartIndex = 0;
int nEndIndex = 120;
int nPos = iLoop * M_SAMPLE_PER_BAND - 50;
// 计算起始位置
if (nPos < 0)
{
nStartIndex += abs(nPos);
nPos = 0;
}
if (iLoop >= (uiInLen-3))
{
nEndIndex -= ((iLoop-(uiInLen-3))*20 + 10);
}
// 开始累加升余弦波
for (iSubLoop = nStartIndex; iSubLoop < nEndIndex; iSubLoop++)
{
pOutData[nPos] += piInData[iLoop] * SRRC[iSubLoop];
nPos++;
}
}
*puiOutLen = M_SAMPLE_PER_BAND * uiInLen;
return TRUE;
}
/****************************************************************************/
/* clear: zeroize a FIR delay line */
/****************************************************************************/
void CDecodeQAM::srrc_clear(int ntaps, double z[])
{
int ii;
for (ii = 0; ii < ntaps; ii++)
{
z[ii] = 0;
}
}
/****************************************************************************
* filter: Does the basic FIR algorithm: store input sample, calculate
* output sample, shift delay line
*****************************************************************************/
void CDecodeQAM::srrc_intrp(int din[], int din_len, double t1[], double sum1[])
{
int ii,jj,kk;
double accum;
for(ii=0;ii<din_len;ii++)
{
/* store input at the beginning of the delay line */
t1[0]=(double)din[ii];
/* calc FIR */
for(jj=0;jj<5;jj++)
{
accum=0;
for (kk = 0; kk < h1_len; kk++)
{
accum += h1[kk] * t1[kk];
}
/* shift delay line */
for (kk= h1_len-2; kk >= 0; kk--)
{
t1[kk + 1] = t1[kk];
}
t1[0]=0; //pad 0
sum1[ii*5+jj]=accum;
}
}
}
void CDecodeQAM::srrc_fir_ha1(double din[], int din_len, double t2[], double sum1[])
{
int ii,jj,kk;
double accum;
for(ii=0;ii<din_len;ii++)
{
/* store input at the beginning of the delay line */
t2[0]=din[ii];
/* calc FIR */
for(jj=0;jj<2;jj++)
{
accum=0;
for (kk = 0; kk < h2_len; kk++)
{
accum += h2[kk] * t2[kk];
}
/* shift delay line */
for (kk= h2_len-2; kk >= 0; kk--)
{
t2[kk + 1] = t2[kk];
}
t2[0]=0; //pad 0
sum1[ii*2+jj]=accum;
}
}
}
void CDecodeQAM::srrc_fir_ha2(double din[], int din_len, double t3[], double sum1[])
{
int ii,jj,kk;
double accum;
for(ii=0;ii<din_len;ii++)
{
/* store input at the beginning of the delay line */
t3[0]=din[ii];
/* calc FIR */
for(jj=0;jj<2;jj++)
{
accum=0;
for (kk = 0; kk < h3_len; kk++)
{
accum += h3[kk] * t3[kk];
}
/* shift delay line */
for (kk= h3_len-2; kk >= 0; kk--)
{
t3[kk + 1] = t3[kk];
}
t3[0]=0; //pad 0
sum1[ii*2+jj]=accum;
}
}
}
/****************************************************************************
* filter: Does the basic FIR algorithm: store input sample, calculate
* output sample, shift delay line
*****************************************************************************/
void CDecodeQAM::srrc_tx_filter(int din[], int din_len, double dout[], unsigned int *dout_len)
{
static double *sum1;
static double *sum2;
static double *t1;
static double *t2;
static double *t3;
t1 = (double *)malloc(h1_len*sizeof(double));
t2 = (double *)malloc(h2_len*sizeof(double));
t3 = (double *)malloc(h3_len*sizeof(double));
sum1 = (double *)malloc(din_len*5*sizeof(double));
sum2 = (double *)malloc(din_len*10*sizeof(double));
srrc_intrp(din, din_len, t1, sum1);
srrc_fir_ha1(sum1, din_len*5, t2, sum2);
srrc_fir_ha2(sum2, din_len*10, t3,dout);
*dout_len =din_len*20;
free(t1);
free(t2);
free(t3);
free(sum1);
free(sum2);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -