📄 txrx.c
字号:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "Setting.H"
#include "RS.H"
#include "Function.H"
#include "FrameOfdm.H"
//#include "asintable.h"
extern int asin_tab[];
WordType TxSymbolMark = 0; /* Indicates the symbol index in
* SrcToChan()
*/
WordType TxBitMark = 0; /* Indicates the bit index of a
* symbol in SrcToChan()
*/
WordType RxPosMark = 0; /* Indicates the received bit
* index in ChanToSrc()
*/
extern WordType FrameTx; /* Indicates transmitted subframe
* number
*/
extern WordType FrameRx; /* Indicates received subframe
* number
*/
extern int DataBuffer[NullSampleSize / 2 + NullSampleSize + SymbolSize * 3];
/* Processed data buffer in
* FindFrame()
*/
DType OriInforTx[52]; /* Data buffer for the input of
* channel encoder;
* Data is converted from source
* coded information by SrcToChan()
*/
WordType OriInforRx[3 * SrcVector]; /* Data buffer for the output of
* channel decoder;
* Data is converted from demodulated
* information by ChanToSrc()
*/
DType RefPhaseTx[UsedCarrier]; /* Buffer for transmit reference
* phase
*/
int RefPhaseRx[UsedCarrier]; /* Buffer for received reference
* phase
*/
unsigned int Seed = 101; /* Initial seed of Random() */
WordType Transmit(short SourceCode[], float FinalData[])
{
WordType i, k;
float j;
DType ChannelData[RSTotalSym];
DType ConvData[UsedCarrier * SymPerFrame];
float TmpDataR[FFTSize], TmpDataI[FFTSize];
/* Convert SrcVector bits to required data mode (RSInforBit bits per symbol) */
SrcToChan(SourceCode, OriInforTx, &TxSymbolMark, &TxBitMark);
/* Proceed RS coding and OFDM when all information symbols arrive */
/* Get the available data */
if (TxSymbolMark > (RSInforSym - 2))
{
/* First part of 5 source coded frames */
if (TxSymbolMark > (RSInforSym - 1))
{
for (i = 0; i < RSInforSym; i++)
{
ChannelData[i] = OriInforTx[i];
}
for (i = RSInforSym; i <= TxSymbolMark; i++)
{
OriInforTx[i - RSInforSym] = OriInforTx[i];
}
TxSymbolMark -= RSInforSym;
}
/* Second part of 5 source coded frames */
else
{
for (i = 0; i < RSInforSym; i++)
{
ChannelData[i] = OriInforTx[i];
}
TxSymbolMark = 0;
TxBitMark = 0;
}
/* RS encoding */
Encode_RS(&ChannelData[0], &ChannelData[RSInforSym]);
/* Proceed OFDM below */
if (FrameTx == TotalFrame) /* First subframe of OFDM */
{
FrameTx = 1;
/* Add NullSampleSize padded zero */
for (i = 0; i < NullSampleSize; i++)
{
FinalData[i] = 0;
}
k = NullSampleSize;
/* Two additive lines for frame synchronization & reference phase */
/* Add frame synchronization below in time waveform */
for (i = 0; i < UsedCarrier; i++)
{
RefPhaseTx[i] = (DType) Random(&Seed, 3);
}
for (i = 0; i < FFTSize; i++)
{
if ((i > CarrierJumpPos - 2) && (i < CarrierJumpPos + UsedCarrier - 1))
{
switch (RefPhaseTx[i + 1 - CarrierJumpPos])
{
case 0: TmpDataR[i] = 1; TmpDataI[i] = 0; break;
case 1: TmpDataR[i] = 0; TmpDataI[i] = 1; break;
case 2: TmpDataR[i] = -1; TmpDataI[i] = 0; break;
case 3: TmpDataR[i] = 0; TmpDataI[i] = -1;
}
}
else
{
TmpDataR[i] = 0;
TmpDataI[i] = 0;
}
}
for (i = 1; i < FFTSize; i += 2)
{
TmpDataR[i] = 0;
TmpDataI[i] = 0;
}
FFT(TmpDataR, TmpDataI, -1);
for (i = GuardTimeSize; i > 0; i--)
{
FinalData[k] = TmpDataR[FFTSize - i];
k++;
}
for (i = 0; i < FFTSize; i++)
{
FinalData[k] = TmpDataR[i];
k++;
}
/* Add reference phase below in time waveform */
for (i = 0; i < UsedCarrier; i++)
{
RefPhaseTx[i] = (DType) Random(&Seed, 3);
}
for (i = 0; i < FFTSize; i++)
{
if ((i > CarrierJumpPos - 2) && (i < CarrierJumpPos + UsedCarrier - 1))
{
switch (RefPhaseTx[i + 1 - CarrierJumpPos])
{
case 0: TmpDataR[i] = 1; TmpDataI[i] = 0; break;
case 1: TmpDataR[i] = 0; TmpDataI[i] = 1; break;
case 2: TmpDataR[i] = -1; TmpDataI[i] = 0; break;
case 3: TmpDataR[i] = 0; TmpDataI[i] = -1;
}
}
else
{
TmpDataR[i] = 0;
TmpDataI[i] = 0;
}
}
FFT(TmpDataR, TmpDataI, -1);
for (i = GuardTimeSize; i > 0; i--)
{
FinalData[k] = TmpDataR[FFTSize - i];
k++;
}
for (i = 0; i < FFTSize; i++)
{
FinalData[k] = TmpDataR[i];
k++;
}
/* Adjust amplitude of frame synchronization & reference phase */
j = 0;
for (i = k - 2 * SymbolSize; i < k; i++)
{
if (j < (float)fabs(FinalData[i]))
{
j = (float)fabs(FinalData[i]);
}
}
for (i = k - 2 * SymbolSize; i < k; i++)
{
FinalData[i] *= (float) (0.95 / j);
}
}
else
{
FrameTx++;
k = 0;
}
/* Convert the data base to CodewordBit */
ConvBase(ChannelData, ConvData, RSTotalSym, 1);
ConvData[UsedCarrier * SymPerFrame -1] = 0;
/* Change to Gray code */
Gray2(ConvData, RSTotalSym * RSInforBit / CodewordBit);
/* OFDM modulation */
OFDMModu(ConvData, &FinalData[k], RefPhaseTx);
/* Adjust amplitude of transmit data */
j = 0;
for (i = k; i < k + SymbolSize * SymPerFrame; i++)
{
if (j < (float)fabs(FinalData[i]))
{
j = (float)fabs(FinalData[i]);
}
}
for (i = k; i < k + SymbolSize * SymPerFrame; i++)
{
FinalData[i] *= (float) (0.95 / j);
}
return (k + SymbolSize * SymPerFrame);
}
else
{
return 0;
}
}
WordType Receive(short RecData[], short SourceCode[])
{
WordType i, k;
DType ChanCodeData[RSTotalSym];
DType ConvData[UsedCarrier * SymPerFrame];
int TmpDataR[FFTSize], TmpDataI[FFTSize],index,xI,xR;
int *pTmpDataR, *pTmpDataI,*pRefPhaseRx;
if (FrameRx == TotalFrame)
{
FrameRx = 1;
/* Two additive lines for frame synchronization & reference phase */
/* Remove NullSampleSize padded zero & frame synchronization below */
k = SymbolSize;
/* Get reference phase below */
for (i = 0; i < FFTSize; i++)
{
TmpDataR[i] = RecData[k + GuardTimeSize];
TmpDataI[i] = 0;
k++;
}
k += GuardTimeSize; /* Adjust the address access point */
FFT(TmpDataR, TmpDataI, 1);
pTmpDataR = TmpDataR + CarrierJumpPos - 1;
pTmpDataI = TmpDataI + CarrierJumpPos - 1;
pRefPhaseRx = RefPhaseRx;
for (i = CarrierJumpPos - 1; i < CarrierJumpPos + UsedCarrier - 1; i++)
{
xR = *pTmpDataR;
xI = *pTmpDataI;
index = (float)90 * xI*xI/(xI*xI+xR*xR);
*pRefPhaseRx = asin_tab[index];
if(xR>=0 && xI<0)
{
*pRefPhaseRx = -(*pRefPhaseRx) + PI2Q15;
}
else if(xR<0 && xI<=0)
{
*pRefPhaseRx = *pRefPhaseRx + PIQ15;
}
else if(xR<0 && xI>0)
{
*pRefPhaseRx = -(*pRefPhaseRx) + PIQ15;
}
pTmpDataR++;
pTmpDataI++;
pRefPhaseRx++;
}
}
else
{
FrameRx++;
k = 0;
}
/* OFDM modulation */
OFDMDemo(&RecData[k], ConvData, RefPhaseRx);
/* Change to Gray code */
Gray2(ConvData, RSTotalSym * RSInforBit / CodewordBit);
/* Convert the data base to CodewordBit */
ConvBase(ConvData, ChanCodeData, RSTotalSym * RSInforBit / CodewordBit, 0);
/* RS decoding */
i = Decode_RS(ChanCodeData);
/* Convert RS data to required data mode (SrcVector bits per frame) */
ChanToSrc(ChanCodeData, OriInforRx, &RxPosMark);
/* Decompress the source data */
if (RxPosMark < (3 * SrcVector - 1))
{
for (i = 0; i < (2 * SrcVector); i++)
{
SourceCode[i] = OriInforRx[i];
}
for (i = (2 * SrcVector); i < RxPosMark; i++)
{
OriInforRx[i - 2 * SrcVector] = OriInforRx[i];
}
RxPosMark -= (2 * SrcVector);
return 2;
}
else
{
for (i = 0; i < (3 * SrcVector); i++)
{
SourceCode[i] = OriInforRx[i];
}
RxPosMark = 0;
return 3;
}
}
int FindFrame(short SignalIn[], WordType FirstFrame)
{
WordType i, j, k1,k2,k3;
WordType FrameStart, FineStart = 0;
// int DataBuffer_int[NullSampleSize / 2 + NullSampleSize + SymbolSize * 3];
int FilterData[NullSampleSize / 2 + NullSampleSize + SymbolSize * 3];
//float max;
int Sxx[3 * GuardTimeSize + 1] = {0};
int Syy[3 * GuardTimeSize + 1] = {0};
int Sxy[3 * GuardTimeSize + 1] = {0};
int Sumx[3 * GuardTimeSize + 1] = {0};
int Sumy[3 * GuardTimeSize + 1] = {0};
int RR[3 * GuardTimeSize + 1];
int tmp;//,max_int,Q,Q1,Q2;
/* float FSxx[3 * GuardTimeSize + 1] = {0};
float FSyy[3 * GuardTimeSize + 1] = {0};
float FSxy[3 * GuardTimeSize + 1] = {0};
float FSumx[3 * GuardTimeSize + 1] = {0};
float FSumy[3 * GuardTimeSize + 1] = {0};
/* Get the processed signal and change to envelope type */
if (FirstFrame == 1)
{
for (i = 0; i < NullSampleSize / 2 + NullSampleSize + SymbolSize * 3; i++)
{
DataBuffer[i] = abs(SignalIn[i]);
}
}
else
{
for (i = 0; i < NullSampleSize + SymbolSize * 3; i++)
{
DataBuffer[i + NullSampleSize / 2] = abs(SignalIn[i]);
}
}
/* Filter the signal */
for (i = 0; i < NullSampleSize / 2 + NullSampleSize + SymbolSize * 3; i++)
{
FilterData[i] = 0;
}
/*for (i = NullSampleSize - GuardTimeSize / 2 - 1; i < NullSampleSize / 2 + NullSampleSize + SymbolSize * 3; i++)
{
for (j = 0; j < NullSampleSize - GuardTimeSize / 2; j++)
{
FilterData[i] += DataBuffer[i - j];
}
}*/
for (i = 0; i < NullSampleSize - GuardTimeSize / 2; i++)
{
FilterData[NullSampleSize - GuardTimeSize / 2 - 1] += DataBuffer[i];
}
for (j = 0; i < NullSampleSize / 2 + NullSampleSize + SymbolSize * 3; i++,j++)
{
FilterData[i] += FilterData[i-1] - DataBuffer[j] + DataBuffer[i];
}
/* Primary frame synchronization, find the jump-off point */
tmp = 0x7fffffff;
for (i = NullSampleSize - GuardTimeSize / 2 - 1;
i < NullSampleSize / 2 + NullSampleSize + SymbolSize * 3; i++)
{
if (tmp > FilterData[i])
{
tmp = FilterData[i];
FrameStart = i; /* Already in C index */
}
}
/* Calculate the correlation coefficient */
for (i = FrameStart; i < FrameStart + FFTSize / 2; i++)
{
k1 = DataBuffer[i - (WordType)(3 * GuardTimeSize / 2)];
k2 = DataBuffer[i + FFTSize / 2 - (WordType)(3 * GuardTimeSize / 2)];
Sxx[0] += k1 * k1;
Syy[0] += k2 * k2;
Sxy[0] += k1 * k2;
Sumx[0] += k1;
Sumy[0] += k2;
}
j = FrameStart - (WordType)(3 * GuardTimeSize / 2);
for (i = 0; i < 3 * GuardTimeSize; i++)
{
k1 = DataBuffer[i + j + FFTSize / 2];
k2 = DataBuffer[i + j];
k3 = DataBuffer[i + j + FFTSize];
Sxx[i + 1] = Sxx[i] + k1 * k1 - k2 * k2;
Syy[i + 1] = Syy[i] + k3 * k3 - k1 * k1;
Sxy[i + 1] = Sxy[i] + k3 * k1 - k1 * k2;
Sumx[i + 1] = Sumx[i] + k1 - k2;
Sumy[i + 1] = Sumy[i] + k3 - k1;
}
for (i = 0; i < 3 * GuardTimeSize + 1; i++)
{
Sxx[i] -= (2 * Sumx[i] * Sumx[i] / FFTSize) ;
Syy[i] -= (2 * Sumy[i] * Sumy[i] / FFTSize) ;
Sxy[i] -= (2 * Sumx[i] * Sumy[i] / FFTSize) ;
RR[i] = (int)(Sxy[i] / sqrt((double)Sxx[i] * Syy[i]));
}
for (i = 0; i < 3 * GuardTimeSize + 1; i++)
{
FilterData[i] = 0;
}
for (i = 0; i < GuardTimeSize; i++)
{
FilterData[GuardTimeSize] += RR[GuardTimeSize - i];
}
for (j = 1; i < 3 * GuardTimeSize + 1; i++,j++)
{
FilterData[i] += FilterData[i-1] + RR[i] - RR[j];
}
/*for (i = GuardTimeSize; i < 3 * GuardTimeSize + 1; i++)
{
for (j = 0; j < GuardTimeSize; j++)
{
FilterData[i] += RR[i - j];
}
}*/
/* Fine frame synchronization using correlation coefficient */
tmp = 0;
for (i = GuardTimeSize; i < 3 * GuardTimeSize + 1; i++)
{
if (tmp < FilterData[i])
{
tmp = FilterData[i];
FineStart = i; /* Already in C index */
}
}
// FrameStart += Round((float)((FineStart - 1.5 * GuardTimeSize) / 2)) - 1;
/* Already in C index */
return FrameStart;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -