📄 txrx.c
字号:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "Setting.H"
#include "RS.H"
#include "Function.H"
#include "FrameOfdm.H"
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 float 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
*/
float RefPhaseRx[UsedCarrier]; /* Buffer for received reference
* phase
*/
unsigned int Seed = 101; /* Initial seed of Random() */
WordType Transmit(short SourceCode[], short FinalData[])
{
WordType i, k;
//float j;
DType ChannelData[RSTotalSym];
DType ConvData[UsedCarrier * SymPerFrame];
int 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] = 16384; TmpDataI[i] = 0; break; //2^14
case 1: TmpDataR[i] = 0; TmpDataI[i] = 16384; break;
case 2: TmpDataR[i] = -16384; TmpDataI[i] = 0; break;
case 3: TmpDataR[i] = 0; TmpDataI[i] = -16384;
}
}
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] = (short)(TmpDataR[FFTSize - i]) ;
k++;
}
for (i = 0; i < FFTSize; i++)
{
FinalData[k] = (short)(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] = 16384; TmpDataI[i] = 0; break;
case 1: TmpDataR[i] = 0; TmpDataI[i] = 16384; break;
case 2: TmpDataR[i] = -16384; TmpDataI[i] = 0; break;
case 3: TmpDataR[i] = 0; TmpDataI[i] = -16384;
}
}
else
{
TmpDataR[i] = 0;
TmpDataI[i] = 0;
}
}
FFT(TmpDataR, TmpDataI, -1);
for (i = GuardTimeSize; i > 0; i--)
{
FinalData[k] = (short)(TmpDataR[FFTSize - i]);
k++;
}
for (i = 0; i < FFTSize; i++)
{
FinalData[k] = (short)(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);
}*/
for(i = 0; i < k + SymbolSize * SymPerFrame; i++)
FinalData[i] = FinalData[i] & 0xffe0;
return (k + SymbolSize * SymPerFrame);
}
else
{
return 0;
}
}
WordType Receive(float RecData[], short SourceCode[])
{
WordType i, k;
DType ChanCodeData[RSTotalSym];
DType ConvData[UsedCarrier * SymPerFrame];
float TmpDataR[FFTSize], TmpDataI[FFTSize];
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);
for (i = CarrierJumpPos - 1; i < CarrierJumpPos + UsedCarrier - 1; i++)
{
RefPhaseRx[i - CarrierJumpPos + 1] =
(float) atan2((double)(TmpDataI[i]), (double)(TmpDataR[i]));
if (RefPhaseRx[i - CarrierJumpPos + 1] < 0)
{
RefPhaseRx[i - CarrierJumpPos + 1] += (float)(PI * 2);
}
}
}
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(float SignalIn[], WordType FirstFrame)
{
WordType i, j;
WordType FrameStart, FineStart;
float tmp;
float Sxx[3 * GuardTimeSize + 1] = {0};
float Syy[3 * GuardTimeSize + 1] = {0};
float Sxy[3 * GuardTimeSize + 1] = {0};
float Sumx[3 * GuardTimeSize + 1] = {0};
float Sumy[3 * GuardTimeSize + 1] = {0};
float RR[3 * GuardTimeSize + 1];
float FilterData[NullSampleSize / 2 + NullSampleSize + SymbolSize * 3];
/* Get the processed signal and change to envelope type */
if (FirstFrame == 1)
{
for (i = 0; i < NullSampleSize / 2 + NullSampleSize + SymbolSize * 3; i++)
{
DataBuffer[i] = (float) fabs((double) SignalIn[i]);
}
}
else
{
for (i = 0; i < NullSampleSize + SymbolSize * 3; i++)
{
DataBuffer[i + NullSampleSize / 2] = (float) fabs((double) SignalIn[i]);
}
}
/* Filter the signal */
for (i = 0; i < NullSampleSize / 2 + NullSampleSize + SymbolSize * 3; i++)
{
FilterData[i] = 0;
}
for (i = 0; i < NullSampleSize / 2 + NullSampleSize + SymbolSize * 3; i++)
{
for (j = 0; j < min(i + 1, NullSampleSize - GuardTimeSize / 2); j++)
{
FilterData[i] += DataBuffer[i - j];
}
}
/* Primary frame synchronization, find the jump-off point */
tmp = 200.0;
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++)
{
Sxx[0] += DataBuffer[(WordType)(i - 1.5 * GuardTimeSize)] *
DataBuffer[(WordType)(i - 1.5 * GuardTimeSize)];
Syy[0] += DataBuffer[(WordType)(i - 1.5 * GuardTimeSize + FFTSize / 2)] *
DataBuffer[(WordType)(i - 1.5 * GuardTimeSize + FFTSize / 2)];
Sxy[0] += DataBuffer[(WordType)(i - 1.5 * GuardTimeSize)] *
DataBuffer[(WordType)(i - 1.5 * GuardTimeSize + FFTSize / 2)];
Sumx[0] += DataBuffer[(WordType)(i - 1.5 * GuardTimeSize)];
Sumy[0] += DataBuffer[(WordType)(i - 1.5 * GuardTimeSize + FFTSize / 2)];
}
for (i = 0; i < 3 * GuardTimeSize; i++)
{
Sxx[i + 1] = Sxx[i] +
DataBuffer[(WordType)(i + FrameStart - 1.5 * GuardTimeSize + FFTSize / 2)] *
DataBuffer[(WordType)(i + FrameStart - 1.5 * GuardTimeSize + FFTSize / 2)] -
DataBuffer[(WordType)(i + FrameStart - 1.5 * GuardTimeSize)] *
DataBuffer[(WordType)(i + FrameStart - 1.5 * GuardTimeSize)];
Syy[i + 1] = Syy[i] +
DataBuffer[(WordType)(i + FrameStart - 1.5 * GuardTimeSize + FFTSize)] *
DataBuffer[(WordType)(i + FrameStart - 1.5 * GuardTimeSize + FFTSize)] -
DataBuffer[(WordType)(i + FrameStart - 1.5 * GuardTimeSize + FFTSize / 2)] *
DataBuffer[(WordType)(i + FrameStart - 1.5 * GuardTimeSize + FFTSize / 2)];
Sxy[i + 1] = Sxy[i] +
DataBuffer[(WordType)(i + FrameStart - 1.5 * GuardTimeSize + FFTSize)] *
DataBuffer[(WordType)(i + FrameStart - 1.5 * GuardTimeSize + FFTSize / 2)] -
DataBuffer[(WordType)(i + FrameStart - 1.5 * GuardTimeSize + FFTSize / 2)] *
DataBuffer[(WordType)(i + FrameStart - 1.5 * GuardTimeSize)];
Sumx[i + 1] = Sumx[i] +
DataBuffer[(WordType)(i + FrameStart - 1.5 * GuardTimeSize + FFTSize / 2)] -
DataBuffer[(WordType)(i + FrameStart - 1.5 * GuardTimeSize)];
Sumy[i + 1] = Sumy[i] +
DataBuffer[(WordType)(i + FrameStart - 1.5 * GuardTimeSize + FFTSize)] -
DataBuffer[(WordType)(i + FrameStart - 1.5 * GuardTimeSize + FFTSize / 2)];
}
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] = (float) (Sxy[i] / sqrt((double)(Sxx[i] * Syy[i])));
}
/* Filter the signal again */
for (i = 0; i < 3 * GuardTimeSize + 1; i++)
{
FilterData[i] = 0;
}
for (i = 0; i < 3 * GuardTimeSize + 1; i++)
{
for (j = 0; j < min(i + 1, 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 + -