RENEWLab  1.1.0
RENEW project
comms-lib.h
Go to the documentation of this file.
1 /*
2 
3  Communications Library:
4  a) Generate pilot/preamble sequences
5  b) OFDM modulation
6 
7 ---------------------------------------------------------------------
8  Copyright (c) 2018-2019, Rice University
9  RENEW OPEN SOURCE LICENSE: http://renew-wireless.org/license
10  Author(s): Rahman Doost-Mohamamdy: doost@rice.edu
11  Oscar Bejarano: obejarano@rice.edu
12 ---------------------------------------------------------------------
13 */
14 
15 #include <complex.h>
16 #include <math.h>
17 #include <stdio.h> /* for fprintf */
18 #include <stdlib.h>
19 #include <string.h> /* for memcpy */
20 #include <unistd.h>
21 
22 #include <algorithm>
23 #include <cstring>
24 #include <fstream> // std::ifstream
25 #include <iostream>
26 #include <thread>
27 #include <vector>
28 
29 #include "fft.h"
30 
31 static constexpr size_t kPilotSubcarrierSpacing = 12;
32 static constexpr size_t kDefaultPilotScOffset = 6;
33 
34 static inline double computeAbs(std::complex<double> x) { return std::abs(x); }
35 
36 //template <typename T>
37 //static inline T computeAbs(std::complex<T> x) { return std::abs(x); }
38 static inline double computePower(std::complex<double> x) {
39  return std::pow(std::abs(x), 2);
40 }
41 static inline double computeSquare(double x) { return x * x; }
42 
43 class CommsLib {
44  public:
45  enum SequenceType {
53  };
54 
55  enum ModulationOrder { QPSK = 2, QAM16 = 4, QAM64 = 6 };
56 
57  CommsLib(std::string);
58  ~CommsLib();
59 
60  static std::vector<std::vector<float>> getSequence(size_t type,
61  size_t seq_len = 0);
62  static std::vector<std::complex<float>> modulate(std::vector<uint8_t>, int);
63  static std::vector<size_t> getDataSc(
64  size_t fftSize, size_t DataScNum,
65  size_t PilotScOffset = kDefaultPilotScOffset);
66  static std::vector<size_t> getNullSc(size_t fftSize, size_t DataScNum);
67  static std::vector<std::complex<float>> getPilotScValue(
68  size_t fftSize, size_t DataScNum,
69  size_t PilotScOffset = kDefaultPilotScOffset);
70  static std::vector<size_t> getPilotScIndex(
71  size_t fftSize, size_t DataScNum,
72  size_t PilotScOffset = kDefaultPilotScOffset);
73  static std::vector<std::complex<float>> FFT(
74  const std::vector<std::complex<float>>&, int);
75  static std::vector<std::complex<float>> IFFT(
76  const std::vector<std::complex<float>>&, int, float scale = 0.5,
77  bool normalize = true);
78 
79  static int findLTS(const std::vector<std::complex<float>>& iq, int seqLen);
80  static size_t find_pilot_seq(const std::vector<std::complex<float>>& iq,
81  const std::vector<std::complex<float>>& pilot,
82  size_t seqLen);
83  template <typename T>
84  //static std::vector<T> convolve(std::vector<T> const& f, std::vector<T> const& g);
85  static std::vector<T> convolve(std::vector<T> const& f,
86  std::vector<T> const& g) {
87  /* Convolution of two vectors
88  * Source:
89  * https://stackoverflow.com/questions/24518989/how-to-perform-1-dimensional-valid-convolution
90  */
91  int const nf = f.size();
92  int const ng = g.size();
93  int const n = nf + ng - 1;
94  std::vector<T> out(n, 0);
95  for (auto i(0); i < n; ++i) {
96  int const jmn = (i >= ng - 1) ? i - (ng - 1) : 0;
97  int const jmx = (i < nf - 1) ? i : nf - 1;
98  for (auto j(jmn); j <= jmx; ++j) {
99  out[i] += f[j] * g[i - j];
100  }
101  }
102  return out;
103  }
104  static float find_max_abs(const std::vector<std::complex<float>>& in);
105  static std::vector<std::complex<float>> csign(
106  const std::vector<std::complex<float>>& iq);
107  static inline int hadamard2(int i, int j) {
108  return (__builtin_parity(i & j) != 0 ? -1 : 1);
109  }
110  static std::vector<float> magnitudeFFT(
111  std::vector<std::complex<float>> const&, std::vector<float> const&,
112  size_t);
113  static std::vector<float> hannWindowFunction(size_t);
114  static double windowFunctionPower(std::vector<float> const&);
115  template <typename T>
116  static T findTone(std::vector<T> const&, double, double, size_t,
117  const size_t delta = 10);
118  static float measureTone(std::vector<std::complex<float>> const&,
119  std::vector<float> const&, double, double, size_t,
120  const size_t delta = 10);
121 
122  // Functions using AVX
123  static int find_beacon(const std::vector<std::complex<float>>& iq);
124  static int find_beacon_avx(const std::vector<std::complex<float>>& iq,
125  const std::vector<std::complex<float>>& seq);
126  static std::vector<float> correlate_avx_s(std::vector<float> const& f,
127  std::vector<float> const& g);
128  static std::vector<int16_t> correlate_avx_si(std::vector<int16_t> const& f,
129  std::vector<int16_t> const& g);
130  static std::vector<float> abs2_avx(std::vector<std::complex<float>> const& f);
131  static std::vector<int32_t> abs2_avx(
132  std::vector<std::complex<int16_t>> const& f);
133  static std::vector<std::complex<float>> auto_corr_mult_avx(
134  std::vector<std::complex<float>> const& f, const int dly,
135  const bool conj = true);
136  static std::vector<std::complex<int16_t>> auto_corr_mult_avx(
137  std::vector<std::complex<int16_t>> const& f, const int dly,
138  const bool conj = true);
139  static std::vector<std::complex<float>> correlate_avx(
140  std::vector<std::complex<float>> const& f,
141  std::vector<std::complex<float>> const& g);
142  static std::vector<std::complex<int16_t>> correlate_avx(
143  std::vector<std::complex<int16_t>> const& f,
144  std::vector<std::complex<int16_t>> const& g);
145  static std::vector<std::complex<float>> complex_mult_avx(
146  std::vector<std::complex<float>> const& f,
147  std::vector<std::complex<float>> const& g, const bool conj);
148  static std::vector<std::complex<int16_t>> complex_mult_avx(
149  std::vector<std::complex<int16_t>> const& f,
150  std::vector<std::complex<int16_t>> const& g, const bool conj);
151  //private:
152  // static inline float** init_qpsk();
153  // static inline float** init_qam16();
154  // static inline float** init_qam64();
155 };
iris_py.type
type
Definition: iris_py.py:333
extract_pilots_data.seq
seq
Definition: extract_pilots_data.py:53
CommsLib::correlate_avx
static std::vector< std::complex< float > > correlate_avx(std::vector< std::complex< float >> const &f, std::vector< std::complex< float >> const &g)
CommsLib::CommsLib
CommsLib(std::string)
CommsLib::correlate_avx_s
static std::vector< float > correlate_avx_s(std::vector< float > const &f, std::vector< float > const &g)
CommsLib::find_beacon
static int find_beacon(const std::vector< std::complex< float >> &iq)
Definition: comms-lib.cc:114
CommsLib::measureTone
static float measureTone(std::vector< std::complex< float >> const &, std::vector< float > const &, double, double, size_t, const size_t delta=10)
Definition: comms-lib.cc:317
CommsLib::auto_corr_mult_avx
static std::vector< std::complex< float > > auto_corr_mult_avx(std::vector< std::complex< float >> const &f, const int dly, const bool conj=true)
CommsLib::LTE_ZADOFF_CHU
@ LTE_ZADOFF_CHU
Definition: comms-lib.h:49
CommsLib::hannWindowFunction
static std::vector< float > hannWindowFunction(size_t)
Definition: comms-lib.cc:272
CommsLib::ModulationOrder
ModulationOrder
Definition: comms-lib.h:55
computeAbs
static double computeAbs(std::complex< double > x)
Definition: comms-lib.h:34
CommsLib::SequenceType
SequenceType
Definition: comms-lib.h:45
nf
for nf
Definition: iris_py.m:282
CommsLib::FFT
static std::vector< std::complex< float > > FFT(const std::vector< std::complex< float >> &, int)
Definition: comms-lib.cc:435
CommsLib::findLTS
static int findLTS(const std::vector< std::complex< float >> &iq, int seqLen)
Definition: comms-lib.cc:28
CommsLib::LTS_SEQ
@ LTS_SEQ
Definition: comms-lib.h:47
CommsLib::magnitudeFFT
static std::vector< float > magnitudeFFT(std::vector< std::complex< float >> const &, std::vector< float > const &, size_t)
Definition: comms-lib.cc:244
CommsLib::QPSK
@ QPSK
Definition: comms-lib.h:55
CommsLib::findTone
static T findTone(std::vector< T > const &, double, double, size_t, const size_t delta=10)
Definition: comms-lib.cc:299
CommsLib::QAM16
@ QAM16
Definition: comms-lib.h:55
CommsLib::correlate_avx_si
static std::vector< int16_t > correlate_avx_si(std::vector< int16_t > const &f, std::vector< int16_t > const &g)
CommsLib::HADAMARD
@ HADAMARD
Definition: comms-lib.h:52
kDefaultPilotScOffset
static constexpr size_t kDefaultPilotScOffset
Definition: comms-lib.h:32
kPilotSubcarrierSpacing
static constexpr size_t kPilotSubcarrierSpacing
Definition: comms-lib.h:31
plt_simp.pilot
pilot
Definition: plt_simp.py:99
CommsLib::getSequence
static std::vector< std::vector< float > > getSequence(size_t type, size_t seq_len=0)
Definition: comms-lib.cc:516
CommsLib::LTS_SEQ_F
@ LTS_SEQ_F
Definition: comms-lib.h:48
g
Author(s) pyhton object array This array decribes Iris board or a collection of Iris boards that belong to the same entity E g
Definition: iris_py.m:3
j
for j
Definition: ofdm_mimo.m:301
CommsLib::find_pilot_seq
static size_t find_pilot_seq(const std::vector< std::complex< float >> &iq, const std::vector< std::complex< float >> &pilot, size_t seqLen)
Definition: comms-lib.cc:87
CommsLib::STS_SEQ
@ STS_SEQ
Definition: comms-lib.h:46
i
for i
Definition: rl_ofdm_calib.m:121
CommsLib::hadamard2
static int hadamard2(int i, int j)
Definition: comms-lib.h:107
CommsLib::getPilotScValue
static std::vector< std::complex< float > > getPilotScValue(size_t fftSize, size_t DataScNum, size_t PilotScOffset=kDefaultPilotScOffset)
Definition: comms-lib.cc:359
computeSquare
static double computeSquare(double x)
Definition: comms-lib.h:41
CommsLib::find_max_abs
static float find_max_abs(const std::vector< std::complex< float >> &in)
Definition: comms-lib.cc:233
CommsLib::GOLD_IFFT
@ GOLD_IFFT
Definition: comms-lib.h:51
computePower
static double computePower(std::complex< double > x)
Definition: comms-lib.h:38
CommsLib
Definition: comms-lib.h:43
CommsLib::csign
static std::vector< std::complex< float > > csign(const std::vector< std::complex< float >> &iq)
Definition: comms-lib.cc:209
find_lts.iq
iq
Definition: find_lts.py:149
vector
Maybe you need to transpose bits_matrix before reshaping it to a vector
Definition: syms2bits.m:62
CommsLib::windowFunctionPower
static double windowFunctionPower(std::vector< float > const &)
Definition: comms-lib.cc:288
CommsLib::QAM64
@ QAM64
Definition: comms-lib.h:55
CommsLib::IFFT
static std::vector< std::complex< float > > IFFT(const std::vector< std::complex< float >> &, int, float scale=0.5, bool normalize=true)
Definition: comms-lib.cc:404
fft.h
CommsLib::getDataSc
static std::vector< size_t > getDataSc(size_t fftSize, size_t DataScNum, size_t PilotScOffset=kDefaultPilotScOffset)
Definition: comms-lib.cc:324
CommsLib::find_beacon_avx
static int find_beacon_avx(const std::vector< std::complex< float >> &iq, const std::vector< std::complex< float >> &seq)
CommsLib::abs2_avx
static std::vector< float > abs2_avx(std::vector< std::complex< float >> const &f)
CommsLib::modulate
static std::vector< std::complex< float > > modulate(std::vector< uint8_t >, int)
Definition: comms-lib.cc:454
x
sample frequency in MHz x
Definition: getRxVec.m:86
CommsLib::complex_mult_avx
static std::vector< std::complex< float > > complex_mult_avx(std::vector< std::complex< float >> const &f, std::vector< std::complex< float >> const &g, const bool conj)
CommsLib::getNullSc
static std::vector< size_t > getNullSc(size_t fftSize, size_t DataScNum)
Definition: comms-lib.cc:344
CommsLib::convolve
static std::vector< T > convolve(std::vector< T > const &f, std::vector< T > const &g)
Definition: comms-lib.h:85
CommsLib::LTE_ZADOFF_CHU_F
@ LTE_ZADOFF_CHU_F
Definition: comms-lib.h:50
CommsLib::getPilotScIndex
static std::vector< size_t > getPilotScIndex(size_t fftSize, size_t DataScNum, size_t PilotScOffset=kDefaultPilotScOffset)
Definition: comms-lib.cc:385
CommsLib::~CommsLib
~CommsLib()