Initial import
git-svn-id: http://moon:8086/svn/software/trunk/libsrc/radio@1 b431acfa-c32f-4a4a-93f1-934dc6c82436
This commit is contained in:
Executable
+1027
File diff suppressed because it is too large
Load Diff
Executable
+274
@@ -0,0 +1,274 @@
|
||||
#ifndef _REAL_HPP_
|
||||
#define _REAL_HPP_
|
||||
|
||||
#include <string>
|
||||
#include <memory.h>
|
||||
#include <radio/radio_types.h>
|
||||
|
||||
void RealDebug(char *fmtstr, ...);
|
||||
|
||||
class RealException
|
||||
{
|
||||
public:
|
||||
RealException (std::string s)
|
||||
{
|
||||
m_what = s;
|
||||
}
|
||||
~RealException()
|
||||
{
|
||||
}
|
||||
std::string& what()
|
||||
{
|
||||
return m_what;
|
||||
}
|
||||
private:
|
||||
std::string m_what;
|
||||
};
|
||||
|
||||
class RealVector
|
||||
{
|
||||
public:
|
||||
|
||||
struct OpBinary
|
||||
{
|
||||
enum OpType
|
||||
{
|
||||
ADD = 0,
|
||||
SUB,
|
||||
MUL,
|
||||
DIV
|
||||
};
|
||||
|
||||
typedef struct _attributes_t
|
||||
{
|
||||
bool negative;
|
||||
} attributes_t;
|
||||
|
||||
OpBinary(const RealVector &a, const RealVector &b, OpType op)
|
||||
: a(a)
|
||||
, b(b)
|
||||
, op(op)
|
||||
, m_attributes(defaultAttributes())
|
||||
{
|
||||
}
|
||||
OpBinary operator-()
|
||||
{
|
||||
attributes_t attributes = this->m_attributes;
|
||||
attributes.negative = !attributes.negative;
|
||||
|
||||
return OpBinary(*this, attributes);
|
||||
}
|
||||
~OpBinary()
|
||||
{
|
||||
}
|
||||
|
||||
bool isNegative() const
|
||||
{
|
||||
return m_attributes.negative;
|
||||
}
|
||||
const RealVector &a;
|
||||
const RealVector &b;
|
||||
const OpType op;
|
||||
attributes_t m_attributes;
|
||||
|
||||
private:
|
||||
OpBinary& operator=(const OpBinary&);
|
||||
OpBinary(const OpBinary &src, attributes_t attributes)
|
||||
: a(src.a)
|
||||
, b(src.b)
|
||||
, op(src.op)
|
||||
, m_attributes(attributes)
|
||||
{
|
||||
}
|
||||
static const attributes_t defaultAttributes()
|
||||
{
|
||||
attributes_t attributes;
|
||||
attributes.negative = false;
|
||||
return attributes;
|
||||
}
|
||||
};
|
||||
|
||||
typedef struct _attributes_t
|
||||
{
|
||||
bool negative;
|
||||
} attributes_t;
|
||||
|
||||
// Standard constructor
|
||||
RealVector(uint32_t size, radio_float_t *real=0)
|
||||
: m_size(size)
|
||||
, m_real(0)
|
||||
, m_pBufReal(0)
|
||||
, m_pPtrReal(real)
|
||||
, m_attributes(defaultAttributes())
|
||||
{
|
||||
if (!real)
|
||||
{
|
||||
m_pBufReal = new radio_float_t[m_size];
|
||||
memset(m_pBufReal, 0, m_size*sizeof(radio_float_t));
|
||||
m_pPtrReal = m_pBufReal;
|
||||
}
|
||||
}
|
||||
|
||||
// OpBinary resolver copy constructor
|
||||
RealVector(const OpBinary &src)
|
||||
: m_size(src.a.m_size)
|
||||
, m_real(0)
|
||||
, m_pBufReal(0)
|
||||
, m_pPtrReal(0)
|
||||
, m_attributes(defaultAttributes())
|
||||
{
|
||||
m_pBufReal = new radio_float_t[m_size];
|
||||
m_pPtrReal = m_pBufReal;
|
||||
|
||||
*this = src;
|
||||
}
|
||||
|
||||
// Scalar constructor
|
||||
RealVector(radio_float_t real)
|
||||
: m_size(1)
|
||||
, m_real(real)
|
||||
, m_pBufReal(0)
|
||||
, m_pPtrReal(&m_real)
|
||||
, m_attributes(defaultAttributes())
|
||||
{
|
||||
}
|
||||
|
||||
~RealVector(void)
|
||||
{
|
||||
if (m_pBufReal)
|
||||
delete(m_pBufReal);
|
||||
|
||||
m_pBufReal = nullptr;
|
||||
}
|
||||
|
||||
bool isNegative() const
|
||||
{
|
||||
return m_attributes.negative;
|
||||
}
|
||||
|
||||
uint32_t getSize()
|
||||
{
|
||||
return m_size;
|
||||
}
|
||||
|
||||
RealVector at(uint32_t const &i)
|
||||
{
|
||||
return RealVector(*this, i, 1, i);
|
||||
}
|
||||
|
||||
void print(char *pPrefix)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
RealDebug("%s:\n", pPrefix);
|
||||
for (i=0; i < m_size; i++)
|
||||
{
|
||||
RealDebug("%d: %.6f\n", i, m_pPtrReal[i]);
|
||||
}
|
||||
}
|
||||
|
||||
RealVector operator-()
|
||||
{
|
||||
attributes_t attributes = this->m_attributes;
|
||||
attributes.negative = !attributes.negative;
|
||||
|
||||
return RealVector(*this, attributes);
|
||||
}
|
||||
|
||||
// Assignments
|
||||
RealVector& operator=(const RealVector &src);
|
||||
RealVector& operator+=(const RealVector &src);
|
||||
RealVector& operator-=(const RealVector &src);
|
||||
RealVector& operator*=(const RealVector &src);
|
||||
RealVector& operator/=(const RealVector &src);
|
||||
RealVector& operator=(const OpBinary &src);
|
||||
RealVector& operator+=(const OpBinary &src);
|
||||
RealVector& operator-=(const OpBinary &src);
|
||||
RealVector& operator*=(const OpBinary &src);
|
||||
RealVector& operator/=(const OpBinary &src);
|
||||
|
||||
private:
|
||||
uint32_t m_size;
|
||||
radio_float_t m_real;
|
||||
radio_float_t *m_pBufReal;
|
||||
radio_float_t *m_pPtrReal;
|
||||
attributes_t m_attributes;
|
||||
|
||||
// Attribute default
|
||||
const attributes_t defaultAttributes()
|
||||
{
|
||||
attributes_t attributes;
|
||||
|
||||
attributes.negative = 0;
|
||||
|
||||
return attributes;
|
||||
}
|
||||
|
||||
// Copy constructor
|
||||
RealVector(const RealVector &src)
|
||||
: m_size(src.m_size)
|
||||
, m_real(0)
|
||||
, m_pBufReal(0)
|
||||
, m_pPtrReal(0)
|
||||
, m_attributes(src.m_attributes)
|
||||
{
|
||||
m_pBufReal = new radio_float_t[m_size];
|
||||
m_pPtrReal = m_pBufReal;
|
||||
|
||||
*this = src;
|
||||
}
|
||||
|
||||
// Re-attribute constructor
|
||||
// Copies no data, just pointers and attributes
|
||||
RealVector(const RealVector &src, attributes_t attributes)
|
||||
: m_size(src.m_size)
|
||||
, m_real(src.m_real)
|
||||
, m_pBufReal(0)
|
||||
, m_pPtrReal(src.m_pPtrReal)
|
||||
, m_attributes(attributes)
|
||||
{
|
||||
}
|
||||
|
||||
// Slicing constructor
|
||||
RealVector(RealVector &src, uint32_t from, uint32_t step, uint32_t to)
|
||||
: m_size(0)
|
||||
, m_real(src.m_real)
|
||||
, m_pBufReal(0)
|
||||
, m_pPtrReal(&src.m_pPtrReal[from])
|
||||
, m_attributes(src.m_attributes)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
for (i=from; i < to; i+=step)
|
||||
{
|
||||
m_size++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
_inline void checkSize(uint32_t size1, uint32_t size2)
|
||||
{
|
||||
try
|
||||
{
|
||||
if ((size1 != size2) && (size2 != 1))
|
||||
{
|
||||
throw(RealException("Size mismatch"));
|
||||
}
|
||||
}
|
||||
catch(RealException &exc)
|
||||
{
|
||||
RealDebug("Problem: %s\n", exc.what().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// Non-Member
|
||||
// Binary Operators
|
||||
// Returning RealVector::OpBinary
|
||||
RealVector::OpBinary operator+(const RealVector &a, const RealVector &b);
|
||||
RealVector::OpBinary operator-(const RealVector &a, const RealVector &b);
|
||||
RealVector::OpBinary operator*(const RealVector &a, const RealVector &b);
|
||||
RealVector::OpBinary operator/(const RealVector &a, const RealVector &b);
|
||||
|
||||
#endif // _REAL_HPP_
|
||||
Executable
+550
@@ -0,0 +1,550 @@
|
||||
#ifndef _COMPLEX_HPP_
|
||||
#define _COMPLEX_HPP_
|
||||
|
||||
#include <string>
|
||||
#include <memory.h>
|
||||
#include <radio/radio_types.h>
|
||||
#include <radio/cpx.h>
|
||||
|
||||
void ComplexDebug(char *fmtstr, ...);
|
||||
|
||||
class ComplexException
|
||||
{
|
||||
public:
|
||||
ComplexException (std::string s)
|
||||
{
|
||||
m_what = s;
|
||||
}
|
||||
~ComplexException()
|
||||
{
|
||||
}
|
||||
std::string& what()
|
||||
{
|
||||
return m_what;
|
||||
}
|
||||
private:
|
||||
std::string m_what;
|
||||
};
|
||||
|
||||
class ComplexVector
|
||||
{
|
||||
public:
|
||||
struct Negate
|
||||
{
|
||||
Negate(const ComplexVector &src)
|
||||
: src(src)
|
||||
{
|
||||
}
|
||||
const ComplexVector &src;
|
||||
|
||||
private:
|
||||
Negate& operator=(const Negate&);
|
||||
};
|
||||
|
||||
struct ConjugateNegate;
|
||||
struct Conjugate
|
||||
{
|
||||
Conjugate(const ComplexVector &src)
|
||||
: src(src)
|
||||
{
|
||||
}
|
||||
const ComplexVector &src;
|
||||
const ConjugateNegate operator-()
|
||||
{
|
||||
const ConjugateNegate neg(src);
|
||||
return neg;
|
||||
}
|
||||
|
||||
private:
|
||||
Conjugate& operator=(const Conjugate&);
|
||||
};
|
||||
|
||||
struct ConjugateNegate
|
||||
{
|
||||
ConjugateNegate(const Conjugate &src)
|
||||
: src(src.src)
|
||||
{
|
||||
}
|
||||
const ComplexVector &src;
|
||||
|
||||
private:
|
||||
ConjugateNegate& operator=(const ConjugateNegate&);
|
||||
};
|
||||
|
||||
struct NegMul_A_B;
|
||||
struct Mul_A_B
|
||||
{
|
||||
Mul_A_B(const ComplexVector &a, const ComplexVector &b)
|
||||
: a(a)
|
||||
, b(b)
|
||||
{
|
||||
}
|
||||
const ComplexVector &a;
|
||||
const ComplexVector &b;
|
||||
const NegMul_A_B operator-()
|
||||
{
|
||||
const NegMul_A_B neg(a, b);
|
||||
return neg;
|
||||
}
|
||||
private:
|
||||
Mul_A_B& operator=(const Mul_A_B&);
|
||||
};
|
||||
|
||||
struct NegMul_A_B
|
||||
{
|
||||
NegMul_A_B(const ComplexVector &a, const ComplexVector &b)
|
||||
: a(a)
|
||||
, b(b)
|
||||
{
|
||||
}
|
||||
const ComplexVector &a;
|
||||
const ComplexVector &b;
|
||||
|
||||
private:
|
||||
NegMul_A_B& operator=(const NegMul_A_B&);
|
||||
};
|
||||
|
||||
struct ConjNegMul_A_B
|
||||
{
|
||||
ConjNegMul_A_B(const ComplexVector &a, const ComplexVector &b)
|
||||
: a(a)
|
||||
, b(b)
|
||||
{
|
||||
}
|
||||
const ComplexVector &a;
|
||||
const ComplexVector &b;
|
||||
|
||||
private:
|
||||
ConjNegMul_A_B& operator=(const ConjNegMul_A_B&);
|
||||
};
|
||||
|
||||
struct ConjMul_A_B
|
||||
{
|
||||
ConjMul_A_B(const ComplexVector &a, const ComplexVector &b)
|
||||
: a(a)
|
||||
, b(b)
|
||||
{
|
||||
}
|
||||
const ConjNegMul_A_B operator-()
|
||||
{
|
||||
const ConjNegMul_A_B neg(a, b);
|
||||
return neg;
|
||||
}
|
||||
const ComplexVector &a;
|
||||
const ComplexVector &b;
|
||||
|
||||
private:
|
||||
ConjMul_A_B& operator=(const ConjMul_A_B&);
|
||||
};
|
||||
|
||||
struct NegMul_A_ConjB;
|
||||
struct Mul_A_ConjB
|
||||
{
|
||||
Mul_A_ConjB(const ComplexVector &a, const Conjugate &b)
|
||||
: a(a)
|
||||
, b(b.src)
|
||||
{
|
||||
}
|
||||
const NegMul_A_ConjB operator-()
|
||||
{
|
||||
const NegMul_A_ConjB neg(a, b);
|
||||
return neg;
|
||||
}
|
||||
const ComplexVector &a;
|
||||
const ComplexVector &b;
|
||||
|
||||
private:
|
||||
Mul_A_ConjB& operator=(const Mul_A_ConjB&);
|
||||
};
|
||||
|
||||
struct NegMul_A_ConjB
|
||||
{
|
||||
NegMul_A_ConjB(const ComplexVector &a, const Conjugate &b)
|
||||
: a(a)
|
||||
, b(b.src)
|
||||
{
|
||||
}
|
||||
const ComplexVector &a;
|
||||
const ComplexVector &b;
|
||||
|
||||
private:
|
||||
NegMul_A_ConjB& operator=(const NegMul_A_ConjB&);
|
||||
};
|
||||
|
||||
struct NegAdd_A_B;
|
||||
struct Add_A_B
|
||||
{
|
||||
Add_A_B(const ComplexVector &a, const ComplexVector &b)
|
||||
: a(a)
|
||||
, b(b)
|
||||
{
|
||||
}
|
||||
const ComplexVector &a;
|
||||
const ComplexVector &b;
|
||||
const NegAdd_A_B operator-()
|
||||
{
|
||||
const NegAdd_A_B neg(a, b);
|
||||
return neg;
|
||||
}
|
||||
|
||||
private:
|
||||
Add_A_B& operator=(const Add_A_B&);
|
||||
};
|
||||
|
||||
struct NegAdd_A_B
|
||||
{
|
||||
NegAdd_A_B(const ComplexVector &a, const ComplexVector &b)
|
||||
: a(a)
|
||||
, b(b)
|
||||
{
|
||||
}
|
||||
const ComplexVector &a;
|
||||
const ComplexVector &b;
|
||||
|
||||
private:
|
||||
NegAdd_A_B& operator=(const NegAdd_A_B&);
|
||||
};
|
||||
|
||||
struct ConjNegAdd_A_B;
|
||||
struct ConjAdd_A_B
|
||||
{
|
||||
ConjAdd_A_B(const ComplexVector &a, const ComplexVector &b)
|
||||
: a(a)
|
||||
, b(b)
|
||||
{
|
||||
}
|
||||
const ComplexVector &a;
|
||||
const ComplexVector &b;
|
||||
const ConjNegAdd_A_B operator-()
|
||||
{
|
||||
const ConjNegAdd_A_B neg(a, b);
|
||||
return neg;
|
||||
}
|
||||
|
||||
private:
|
||||
ConjAdd_A_B& operator=(const ConjAdd_A_B&);
|
||||
};
|
||||
|
||||
struct ConjNegAdd_A_B
|
||||
{
|
||||
ConjNegAdd_A_B(const ComplexVector &a, const ComplexVector &b)
|
||||
: a(a)
|
||||
, b(b)
|
||||
{
|
||||
}
|
||||
const ComplexVector &a;
|
||||
const ComplexVector &b;
|
||||
|
||||
private:
|
||||
ConjNegAdd_A_B& operator=(const ConjNegAdd_A_B&);
|
||||
};
|
||||
|
||||
struct Add_A_NegB
|
||||
{
|
||||
Add_A_NegB(const ComplexVector &a, const Negate &b)
|
||||
: a(a)
|
||||
, b(b.src)
|
||||
{
|
||||
}
|
||||
const ComplexVector &a;
|
||||
const ComplexVector &b;
|
||||
|
||||
private:
|
||||
Add_A_NegB& operator=(const Add_A_NegB&);
|
||||
};
|
||||
|
||||
struct Add_A_ConjB
|
||||
{
|
||||
Add_A_ConjB(const ComplexVector &a, const Conjugate &b)
|
||||
: a(a)
|
||||
, b(b.src)
|
||||
{
|
||||
}
|
||||
const ComplexVector &a;
|
||||
const ComplexVector &b;
|
||||
|
||||
private:
|
||||
Add_A_ConjB& operator=(const Add_A_ConjB&);
|
||||
};
|
||||
|
||||
struct NegAdd_A_ConjB
|
||||
{
|
||||
NegAdd_A_ConjB(const ComplexVector &a, const Conjugate &b)
|
||||
: a(a)
|
||||
, b(b.src)
|
||||
{
|
||||
}
|
||||
const ComplexVector &a;
|
||||
const ComplexVector &b;
|
||||
|
||||
private:
|
||||
NegAdd_A_ConjB& operator=(const NegAdd_A_ConjB&);
|
||||
};
|
||||
|
||||
struct Add_A_ConjNegB
|
||||
{
|
||||
Add_A_ConjNegB(const ComplexVector &a, const ConjugateNegate &b)
|
||||
: a(a)
|
||||
, b(b.src)
|
||||
{
|
||||
}
|
||||
const ComplexVector &a;
|
||||
const ComplexVector &b;
|
||||
|
||||
private:
|
||||
Add_A_ConjNegB& operator=(const Add_A_ConjNegB&);
|
||||
};
|
||||
|
||||
ComplexVector(uint32_t size, radio_float_t *real=0, radio_float_t *imag=0)
|
||||
: m_size(size)
|
||||
, m_real(0)
|
||||
, m_imag(0)
|
||||
, m_pBufReal(0)
|
||||
, m_pBufImag(0)
|
||||
, m_pPtrReal(real)
|
||||
, m_pPtrImag(imag)
|
||||
{
|
||||
if (!real)
|
||||
{
|
||||
m_pBufReal = new radio_float_t[m_size];
|
||||
memset(m_pBufReal, 0, m_size*sizeof(radio_float_t));
|
||||
m_pPtrReal = m_pBufReal;
|
||||
}
|
||||
if (!imag)
|
||||
{
|
||||
m_pBufImag = new radio_float_t[m_size];
|
||||
memset(m_pBufImag, 0, m_size*sizeof(radio_float_t));
|
||||
m_pPtrImag = m_pBufImag;
|
||||
}
|
||||
}
|
||||
|
||||
ComplexVector(radio_float_t real, radio_float_t imag)
|
||||
: m_size(1)
|
||||
, m_real(real)
|
||||
, m_imag(imag)
|
||||
, m_pBufReal(0)
|
||||
, m_pBufImag(0)
|
||||
, m_pPtrReal(&m_real)
|
||||
, m_pPtrImag(&m_imag)
|
||||
{
|
||||
}
|
||||
|
||||
~ComplexVector(void)
|
||||
{
|
||||
if (m_pBufReal)
|
||||
delete(m_pBufReal);
|
||||
|
||||
if (m_pBufImag)
|
||||
delete(m_pBufImag);
|
||||
|
||||
m_pBufReal = nullptr;
|
||||
m_pBufImag = nullptr;
|
||||
}
|
||||
|
||||
radio_float_t* getReal()
|
||||
{
|
||||
return m_pPtrReal;
|
||||
}
|
||||
|
||||
radio_float_t* getImag()
|
||||
{
|
||||
return m_pPtrImag;
|
||||
}
|
||||
|
||||
uint32_t getSize()
|
||||
{
|
||||
return m_size;
|
||||
}
|
||||
|
||||
ComplexVector at(uint32_t const &i)
|
||||
{
|
||||
return ComplexVector(*this, i);
|
||||
}
|
||||
|
||||
Conjugate conj()
|
||||
{
|
||||
const ComplexVector::Conjugate src_conj(*this);
|
||||
|
||||
return src_conj;
|
||||
}
|
||||
|
||||
void print(char *pPrefix)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
ComplexDebug("%s:\n", pPrefix);
|
||||
for (i=0; i < m_size; i++)
|
||||
{
|
||||
if (m_pPtrImag[i] < 0)
|
||||
{
|
||||
ComplexDebug("%d: %.6f - j%.6f\n", i, m_pPtrReal[i], -m_pPtrImag[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
ComplexDebug("%d: %.6f + j%.6f\n", i, m_pPtrReal[i], m_pPtrImag[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Operators
|
||||
const Negate operator-()
|
||||
{
|
||||
const Negate neg(*this);
|
||||
return neg;
|
||||
}
|
||||
|
||||
ComplexVector& operator=(const radio_float_t &b);
|
||||
ComplexVector& operator*=(const radio_float_t &b);
|
||||
ComplexVector& operator+=(const radio_float_t &b);
|
||||
ComplexVector& operator-=(const radio_float_t &b);
|
||||
|
||||
ComplexVector& operator=(const ComplexVector &src);
|
||||
ComplexVector& operator*=(const ComplexVector &src);
|
||||
ComplexVector& operator+=(const ComplexVector &src);
|
||||
ComplexVector& operator-=(const ComplexVector &src);
|
||||
|
||||
ComplexVector& operator=(const Negate &src);
|
||||
ComplexVector& operator*=(const Negate &src);
|
||||
ComplexVector& operator+=(const Negate &src);
|
||||
ComplexVector& operator-=(const Negate &src);
|
||||
|
||||
ComplexVector& operator=(const Conjugate &src);
|
||||
ComplexVector& operator*=(const Conjugate &src);
|
||||
ComplexVector& operator+=(const Conjugate &src);
|
||||
ComplexVector& operator-=(const Conjugate &src);
|
||||
|
||||
ComplexVector& operator=(const ConjugateNegate &src);
|
||||
ComplexVector& operator*=(const ConjugateNegate &src);
|
||||
ComplexVector& operator+=(const ConjugateNegate &src);
|
||||
ComplexVector& operator-=(const ConjugateNegate &src);
|
||||
|
||||
ComplexVector& operator=(const Mul_A_B &src);
|
||||
ComplexVector& operator+=(const Mul_A_B &src);
|
||||
ComplexVector& operator-=(const Mul_A_B &src);
|
||||
|
||||
ComplexVector& operator=(const NegMul_A_B &src);
|
||||
ComplexVector& operator+=(const NegMul_A_B &src);
|
||||
ComplexVector& operator-=(const NegMul_A_B &src);
|
||||
|
||||
ComplexVector& operator=(const Mul_A_ConjB &src);
|
||||
ComplexVector& operator+=(const Mul_A_ConjB &src);
|
||||
ComplexVector& operator-=(const Mul_A_ConjB &src);
|
||||
|
||||
ComplexVector& operator=(const ConjMul_A_B &src);
|
||||
ComplexVector& operator+=(const ConjMul_A_B &src);
|
||||
ComplexVector& operator-=(const ConjMul_A_B &src);
|
||||
|
||||
ComplexVector& operator=(const ConjNegMul_A_B &src);
|
||||
ComplexVector& operator+=(const ConjNegMul_A_B &src);
|
||||
ComplexVector& operator-=(const ConjNegMul_A_B &src);
|
||||
|
||||
ComplexVector& operator=(const NegMul_A_ConjB &src);
|
||||
ComplexVector& operator+=(const NegMul_A_ConjB &src);
|
||||
ComplexVector& operator-=(const NegMul_A_ConjB &src);
|
||||
|
||||
ComplexVector& operator=(const Add_A_B &src);
|
||||
ComplexVector& operator=(const NegAdd_A_B &src);
|
||||
ComplexVector& operator=(const ConjAdd_A_B &src);
|
||||
ComplexVector& operator=(const ConjNegAdd_A_B &src);
|
||||
ComplexVector& operator=(const Add_A_NegB &src);
|
||||
ComplexVector& operator=(const Add_A_ConjB &src);
|
||||
ComplexVector& operator=(const NegAdd_A_ConjB &src);
|
||||
ComplexVector& operator=(const Add_A_ConjNegB &src);
|
||||
|
||||
private:
|
||||
uint32_t m_size;
|
||||
radio_float_t m_real;
|
||||
radio_float_t m_imag;
|
||||
radio_float_t *m_pBufReal;
|
||||
radio_float_t *m_pBufImag;
|
||||
radio_float_t *m_pPtrReal;
|
||||
radio_float_t *m_pPtrImag;
|
||||
|
||||
ComplexVector(ComplexVector &src, uint32_t index)
|
||||
: m_size(1)
|
||||
, m_pBufReal(0)
|
||||
, m_pBufImag(0)
|
||||
, m_pPtrReal(&src.m_pPtrReal[index])
|
||||
, m_pPtrImag(&src.m_pPtrImag[index])
|
||||
{
|
||||
}
|
||||
|
||||
_inline void checkSize(uint32_t size1, uint32_t size2)
|
||||
{
|
||||
try
|
||||
{
|
||||
if ((size1 != size2) && (size2 != 1))
|
||||
{
|
||||
throw(ComplexException("Size mismatch"));
|
||||
}
|
||||
}
|
||||
catch(ComplexException &exc)
|
||||
{
|
||||
ComplexDebug("Problem: %s\n", exc.what().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
ComplexVector::Mul_A_B operator*(const ComplexVector &a, radio_float_t b);
|
||||
ComplexVector::Mul_A_B operator*(const ComplexVector &a, const ComplexVector &b);
|
||||
|
||||
ComplexVector::Mul_A_B operator*(const ComplexVector::Negate &a, const ComplexVector::Negate &b);
|
||||
ComplexVector::NegMul_A_B operator*(const ComplexVector::Negate &a, const ComplexVector &b);
|
||||
ComplexVector::NegMul_A_B operator*(const ComplexVector &a, const ComplexVector::Negate &b);
|
||||
|
||||
ComplexVector::ConjMul_A_B operator*(const ComplexVector::Conjugate &a, const ComplexVector::Conjugate &b);
|
||||
ComplexVector::Mul_A_ConjB operator*(const ComplexVector::Conjugate &a, const ComplexVector &b);
|
||||
ComplexVector::Mul_A_ConjB operator*(const ComplexVector &a, const ComplexVector::Conjugate &b);
|
||||
|
||||
ComplexVector::ConjMul_A_B operator*(const ComplexVector::ConjugateNegate &a, const ComplexVector::ConjugateNegate &b);
|
||||
ComplexVector::NegMul_A_ConjB operator*(const ComplexVector &a, const ComplexVector::ConjugateNegate &b);
|
||||
ComplexVector::NegMul_A_ConjB operator*(const ComplexVector::ConjugateNegate &a, const ComplexVector &b);
|
||||
|
||||
ComplexVector::Mul_A_ConjB operator*(const ComplexVector::Negate &a, const ComplexVector::ConjugateNegate &b);
|
||||
ComplexVector::Mul_A_ConjB operator*(const ComplexVector::ConjugateNegate &a, const ComplexVector::Negate &b);
|
||||
|
||||
ComplexVector::NegMul_A_ConjB operator*(const ComplexVector::Negate &a, const ComplexVector::Conjugate &b);
|
||||
ComplexVector::NegMul_A_ConjB operator*(const ComplexVector::Conjugate &a, const ComplexVector::Negate &b);
|
||||
|
||||
ComplexVector::Add_A_B operator+(const ComplexVector &a, radio_float_t b);
|
||||
ComplexVector::Add_A_B operator+(const ComplexVector &a, const ComplexVector &b);
|
||||
ComplexVector::NegAdd_A_B operator+(ComplexVector::Negate &a, ComplexVector::Negate &b);
|
||||
|
||||
ComplexVector::Add_A_NegB operator+(const ComplexVector::Negate &a, const ComplexVector &b);
|
||||
ComplexVector::Add_A_NegB operator+(const ComplexVector &a, const ComplexVector::Negate &b);
|
||||
|
||||
ComplexVector::Add_A_ConjB operator+(const ComplexVector::Conjugate &a, const ComplexVector &b);
|
||||
ComplexVector::Add_A_ConjB operator+(const ComplexVector &a, const ComplexVector::Conjugate &b);
|
||||
ComplexVector::ConjAdd_A_B operator+(const ComplexVector::Conjugate &a, const ComplexVector::Conjugate &b);
|
||||
|
||||
|
||||
ComplexVector::Add_A_ConjNegB operator+(const ComplexVector::ConjugateNegate &a, const ComplexVector &b);
|
||||
ComplexVector::Add_A_ConjNegB operator+(const ComplexVector &a, const ComplexVector::ConjugateNegate &b);
|
||||
|
||||
ComplexVector::Add_A_ConjB operator+(const ComplexVector::Conjugate &a, const ComplexVector::Negate &b);
|
||||
ComplexVector::Add_A_ConjB operator+(const ComplexVector::Negate &a, const ComplexVector::Conjugate &b);
|
||||
|
||||
ComplexVector::Add_A_ConjB operator+(const ComplexVector::ConjugateNegate &a, const ComplexVector::Negate &b);
|
||||
ComplexVector::Add_A_ConjB operator+(const ComplexVector::Negate &a, const ComplexVector::ConjugateNegate &b);
|
||||
|
||||
ComplexVector::Add_A_B operator-(const ComplexVector &a, radio_float_t b);
|
||||
ComplexVector::Add_A_NegB operator-(const ComplexVector &a, const ComplexVector &b);
|
||||
ComplexVector::Add_A_NegB operator-(const ComplexVector::Negate &a, const ComplexVector::Negate &b);
|
||||
|
||||
ComplexVector::NegAdd_A_B operator-(const ComplexVector::Negate &a, const ComplexVector &b);
|
||||
ComplexVector::Add_A_B operator-(const ComplexVector &a, const ComplexVector::Negate &b);
|
||||
|
||||
ComplexVector::Add_A_ConjNegB operator-(const ComplexVector::Conjugate &a, const ComplexVector &b);
|
||||
ComplexVector::Add_A_ConjNegB operator-(const ComplexVector &a, const ComplexVector::Conjugate &b);
|
||||
|
||||
ComplexVector::NegAdd_A_ConjB operator-(const ComplexVector::ConjugateNegate &a, const ComplexVector &b);
|
||||
ComplexVector::Add_A_ConjB operator-(const ComplexVector &a, const ComplexVector::ConjugateNegate &b);
|
||||
|
||||
ComplexVector::Add_A_ConjB operator-(const ComplexVector::Conjugate &a, const ComplexVector::Negate &b);
|
||||
ComplexVector::Add_A_ConjB operator-(const ComplexVector::Negate &a, const ComplexVector::Conjugate &b);
|
||||
|
||||
ComplexVector::Add_A_ConjB operator-(const ComplexVector::ConjugateNegate &a, const ComplexVector::Negate &b);
|
||||
ComplexVector::Add_A_ConjB operator-(const ComplexVector::Negate &a, const ComplexVector::ConjugateNegate &b);
|
||||
|
||||
#endif // _COMPLEX_HPP_
|
||||
Executable
+445
@@ -0,0 +1,445 @@
|
||||
#include <windows.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "ComplexVector.hpp"
|
||||
|
||||
void ComplexDebug(char *fmtstr, ...)
|
||||
{
|
||||
char buf[1024];
|
||||
va_list args;
|
||||
|
||||
va_start(args, fmtstr);
|
||||
vsprintf(buf, fmtstr, args);
|
||||
va_end(args);
|
||||
OutputDebugString(buf);
|
||||
|
||||
}
|
||||
|
||||
// Class Methods
|
||||
// Standard constructor
|
||||
ComplexVector::ComplexVector(uint32_t size, radio_float_t *real, radio_float_t *imag)
|
||||
: m_size(size)
|
||||
, m_real(size, real)
|
||||
, m_imag(size, imag)
|
||||
{
|
||||
}
|
||||
|
||||
// Constructor from RealVector
|
||||
ComplexVector::ComplexVector(const RealVector &real, const RealVector &imag)
|
||||
: m_size(real.getSize())
|
||||
, m_real(real, real.m_unary_modifier)
|
||||
, m_imag(imag, imag.m_unary_modifier)
|
||||
{
|
||||
// Check if real and imag have same length
|
||||
|
||||
}
|
||||
|
||||
// Constructor from RealVector pointer
|
||||
ComplexVector::ComplexVector(RealVector *real, RealVector *imag)
|
||||
: m_size(real->getSize())
|
||||
, m_real(*real)
|
||||
, m_imag(*imag)
|
||||
{
|
||||
// Check if real and imag have same length
|
||||
}
|
||||
|
||||
// Scalar constructor
|
||||
ComplexVector::ComplexVector(radio_float_t real, radio_float_t imag)
|
||||
: m_size(1)
|
||||
, m_real(real)
|
||||
, m_imag(imag)
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
ComplexVector::ComplexVector(const _ComplexVector &src)
|
||||
: m_size(src.m_size)
|
||||
, m_real(src.m_real)
|
||||
, m_imag(src.m_imag)
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
_ComplexVector::_ComplexVector(const ComplexVector &src)
|
||||
: m_size(src.m_size)
|
||||
, m_real(src.m_real)
|
||||
, m_imag(src.m_imag)
|
||||
{
|
||||
}
|
||||
|
||||
_ComplexVector::_ComplexVector(const _RealVector &real, const _RealVector &imag)
|
||||
: m_size(real.m_size)
|
||||
, m_real(real)
|
||||
, m_imag(imag)
|
||||
{
|
||||
}
|
||||
|
||||
ComplexVector::~ComplexVector(void)
|
||||
{
|
||||
}
|
||||
|
||||
_ComplexVector _ComplexVector::operator-() const
|
||||
{
|
||||
return _ComplexVector(-this->m_real, -this->m_imag);
|
||||
}
|
||||
|
||||
_ComplexVector _ComplexVector::conj() const
|
||||
{
|
||||
return _ComplexVector(this->m_real, -this->m_imag);
|
||||
}
|
||||
|
||||
uint32_t ComplexVector::getSize()
|
||||
{
|
||||
return m_size;
|
||||
}
|
||||
|
||||
ComplexVector ComplexVector::at(uint32_t const &i)
|
||||
{
|
||||
return ComplexVector(*this, i, 1, i);
|
||||
}
|
||||
|
||||
void ComplexVector::print(char *pPrefix)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
ComplexDebug("%s:\n", pPrefix);
|
||||
for (i=0; i < m_size; i++)
|
||||
{
|
||||
if (m_imag.at(i).getValue() < 0)
|
||||
{
|
||||
ComplexDebug("%d: %.6f - %.6fj\n", i, m_real.at(i).getValue(), -m_imag.at(i).getValue());
|
||||
}
|
||||
else
|
||||
{
|
||||
ComplexDebug("%d: %.6f + %.6fj\n", i, m_real.at(i).getValue(), m_imag.at(i).getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ComplexVector ComplexVector::operator-() const
|
||||
{
|
||||
return ComplexVector(-this->m_real, -this->m_imag);
|
||||
}
|
||||
|
||||
const ComplexVector& ComplexVector::operator+() const
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
ComplexVector ComplexVector::conj() const
|
||||
{
|
||||
return ComplexVector(this->m_real, -this->m_imag);
|
||||
}
|
||||
|
||||
// -------------------------------------------------
|
||||
// Assignments
|
||||
// -------------------------------------------------
|
||||
// = ComplexVector
|
||||
ComplexVector& ComplexVector::operator=(const ComplexVector &src)
|
||||
{
|
||||
this->m_real = src.m_real;
|
||||
this->m_imag = src.m_imag;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// += ComplexVector
|
||||
ComplexVector& ComplexVector::operator+=(const ComplexVector &src)
|
||||
{
|
||||
this->m_real += src.m_real;
|
||||
this->m_imag += src.m_imag;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// -= ComplexVector
|
||||
ComplexVector& ComplexVector::operator-=(const ComplexVector &src)
|
||||
{
|
||||
this->m_real -= src.m_real;
|
||||
this->m_imag -= src.m_imag;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// *= ComplexVector
|
||||
ComplexVector& ComplexVector::operator*=(const ComplexVector &src)
|
||||
{
|
||||
this->m_real = (this->m_real*src.m_real - this->m_imag*src.m_imag);
|
||||
this->m_imag = (this->m_real*src.m_imag + this->m_imag*src.m_real);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// /= ComplexVector
|
||||
ComplexVector& ComplexVector::operator/=(const ComplexVector &src)
|
||||
{
|
||||
// ToDo: Das ist falsch
|
||||
this->m_real = (this->m_real*src.m_real - this->m_imag*src.m_imag);
|
||||
this->m_imag = (this->m_real*src.m_imag + this->m_imag*src.m_real);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Binary operators
|
||||
// = ComplexVector::OpBinaryAdd
|
||||
ComplexVector& ComplexVector::operator=(OpBinary<ComplexVector::Add> src)
|
||||
{
|
||||
this->m_real = (src.a.m_real + src.b.m_real);
|
||||
this->m_imag = (src.a.m_imag + src.b.m_imag);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// = ComplexVector::OpBinaryAdd
|
||||
ComplexVector& ComplexVector::operator+=(OpBinary<ComplexVector::Add> src)
|
||||
{
|
||||
this->m_real += (src.a.m_real + src.b.m_real);
|
||||
this->m_imag += (src.a.m_imag + src.b.m_imag);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// = ComplexVector::OpBinaryAdd
|
||||
ComplexVector& ComplexVector::operator-=(OpBinary<ComplexVector::Add> src)
|
||||
{
|
||||
this->m_real -= (src.a.m_real + src.b.m_real);
|
||||
this->m_imag -= (src.a.m_imag + src.b.m_imag);
|
||||
return *this;
|
||||
|
||||
}
|
||||
|
||||
// = ComplexVector::OpBinaryAdd
|
||||
ComplexVector& ComplexVector::operator*=(OpBinary<ComplexVector::Add> src)
|
||||
{
|
||||
// ToDo: this wird über schrieben
|
||||
this->m_real = ((src.a.m_real + src.b.m_real)*this->m_real - (src.a.m_imag + src.b.m_imag)*this->m_imag);
|
||||
this->m_imag = ((src.a.m_imag + src.b.m_imag)*this->m_real + (src.a.m_real + src.b.m_real)*this->m_imag);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// = ComplexVector::OpBinaryAdd
|
||||
ComplexVector& ComplexVector::operator/=(OpBinary<ComplexVector::Add> src)
|
||||
{
|
||||
// ToDo: this wird über schrieben
|
||||
// ToDo: Das ist falsch
|
||||
this->m_real = ((src.a.m_real + src.b.m_real)*this->m_real - (src.a.m_imag + src.b.m_imag)*this->m_imag);
|
||||
this->m_imag = ((src.a.m_imag + src.b.m_imag)*this->m_real + (src.a.m_real + src.b.m_real)*this->m_imag);
|
||||
return *this;
|
||||
|
||||
}
|
||||
|
||||
// = ComplexVector::OpBinarySub
|
||||
ComplexVector& ComplexVector::operator=(OpBinary<ComplexVector::Sub> src)
|
||||
{
|
||||
this->m_real = (src.a.m_real - src.b.m_real);
|
||||
this->m_imag = (src.a.m_imag - src.b.m_imag);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// = ComplexVector::OpBinarySub
|
||||
ComplexVector& ComplexVector::operator+=(OpBinary<ComplexVector::Sub> src)
|
||||
{
|
||||
this->m_real += (src.a.m_real - src.b.m_real);
|
||||
this->m_imag += (src.a.m_imag - src.b.m_imag);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// = ComplexVector::OpBinarySub
|
||||
ComplexVector& ComplexVector::operator-=(OpBinary<ComplexVector::Sub> src)
|
||||
{
|
||||
this->m_real -= (src.a.m_real - src.b.m_real);
|
||||
this->m_imag -= (src.a.m_imag - src.b.m_imag);
|
||||
return *this;
|
||||
|
||||
}
|
||||
|
||||
// = ComplexVector::OpBinarySub
|
||||
ComplexVector& ComplexVector::operator*=(OpBinary<ComplexVector::Sub> src)
|
||||
{
|
||||
// ToDo: this wird über schrieben
|
||||
this->m_real = ((src.a.m_real - src.b.m_real)*this->m_real - (src.a.m_imag - src.b.m_imag)*this->m_imag);
|
||||
this->m_imag = ((src.a.m_imag - src.b.m_imag)*this->m_real + (src.a.m_real - src.b.m_real)*this->m_imag);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// = ComplexVector::OpBinarySub
|
||||
ComplexVector& ComplexVector::operator/=(OpBinary<ComplexVector::Sub> src)
|
||||
{
|
||||
// ToDo: this wird über schrieben
|
||||
// ToDo: Das ist falsch
|
||||
this->m_real = ((src.a.m_real - src.b.m_real)*this->m_real - (src.a.m_imag - src.b.m_imag)*this->m_imag);
|
||||
this->m_imag = ((src.a.m_imag - src.b.m_imag)*this->m_real + (src.a.m_real - src.b.m_real)*this->m_imag);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// = ComplexVector::OpBinaryMul
|
||||
ComplexVector& ComplexVector::operator=(OpBinary<ComplexVector::Mul> src)
|
||||
{
|
||||
if ((this != &reinterpret_cast<ComplexVector&>(src.a)) && (this != &reinterpret_cast<ComplexVector&>(src.b)))
|
||||
{
|
||||
this->m_real = (src.a.m_real * src.b.m_real);
|
||||
this->m_real -= (src.a.m_imag * src.b.m_imag);
|
||||
|
||||
this->m_imag = (src.a.m_real * src.b.m_imag);
|
||||
this->m_imag += (src.a.m_imag * src.b.m_real);
|
||||
}
|
||||
else
|
||||
{
|
||||
ComplexVector result((src.a.m_real * src.b.m_real) - (src.a.m_imag * src.b.m_imag), (src.a.m_real * src.b.m_imag) + (src.a.m_imag * src.b.m_real));
|
||||
*this = result;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// += ComplexVector::OpBinaryMul
|
||||
ComplexVector& ComplexVector::operator+=(OpBinary<ComplexVector::Mul> src)
|
||||
{
|
||||
if ((this != &reinterpret_cast<ComplexVector&>(src.a)) && (this != &reinterpret_cast<ComplexVector&>(src.b)))
|
||||
{
|
||||
this->m_real += (src.a.m_real * src.b.m_real);
|
||||
this->m_real -= (src.a.m_imag * src.b.m_imag);
|
||||
|
||||
this->m_imag += (src.a.m_real * src.b.m_imag);
|
||||
this->m_imag += (src.a.m_imag * src.b.m_real);
|
||||
}
|
||||
else
|
||||
{
|
||||
ComplexVector result((src.a.m_real * src.b.m_real) - (src.a.m_imag * src.b.m_imag), (src.a.m_real * src.b.m_imag) + (src.a.m_imag * src.b.m_real));
|
||||
*this = *this + result;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// -= ComplexVector::OpBinaryMul
|
||||
ComplexVector& ComplexVector::operator-=(OpBinary<ComplexVector::Mul> src)
|
||||
{
|
||||
if ((this != &reinterpret_cast<ComplexVector&>(src.a)) && (this != &reinterpret_cast<ComplexVector&>(src.b)))
|
||||
{
|
||||
this->m_real -= (src.a.m_real * src.b.m_real);
|
||||
this->m_real += (src.a.m_imag * src.b.m_imag);
|
||||
|
||||
this->m_imag -= (src.a.m_real * src.b.m_imag);
|
||||
this->m_imag -= (src.a.m_imag * src.b.m_real);
|
||||
}
|
||||
else
|
||||
{
|
||||
ComplexVector result((src.a.m_real * src.b.m_real) - (src.a.m_imag * src.b.m_imag), (src.a.m_real * src.b.m_imag) + (src.a.m_imag * src.b.m_real));
|
||||
*this = *this - result;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// *= ComplexVector::OpBinaryMul
|
||||
ComplexVector& ComplexVector::operator*=(OpBinary<ComplexVector::Mul> src)
|
||||
{
|
||||
ComplexVector result((src.a.m_real * src.b.m_real) - (src.a.m_imag * src.b.m_imag), (src.a.m_real * src.b.m_imag) + (src.a.m_imag * src.b.m_real));
|
||||
*this = *this * result;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// /= ComplexVector::OpBinaryMul
|
||||
ComplexVector& ComplexVector::operator/=(OpBinary<ComplexVector::Mul> src)
|
||||
{
|
||||
ComplexVector result((src.a.m_real * src.b.m_real) - (src.a.m_imag * src.b.m_imag), (src.a.m_real * src.b.m_imag) + (src.a.m_imag * src.b.m_real));
|
||||
*this = *this / result;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Div
|
||||
// = ComplexVector::OpBinaryDiv
|
||||
ComplexVector& ComplexVector::operator=(OpBinary<ComplexVector::Div> src)
|
||||
{
|
||||
if ((this != &reinterpret_cast<ComplexVector&>(src.a)) && (this != &reinterpret_cast<ComplexVector&>(src.b)))
|
||||
{
|
||||
this->m_real = (src.a.m_real * src.b.m_real);
|
||||
this->m_real -= (src.a.m_imag * src.b.m_imag);
|
||||
|
||||
this->m_imag = (src.a.m_real * src.b.m_imag);
|
||||
this->m_imag += (src.a.m_imag * src.b.m_real);
|
||||
}
|
||||
else
|
||||
{
|
||||
ComplexVector result((src.a.m_real * src.b.m_real) - (src.a.m_imag * src.b.m_imag), (src.a.m_real * src.b.m_imag) + (src.a.m_imag * src.b.m_real));
|
||||
*this = result;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// += ComplexVector::OpBinaryDiv
|
||||
ComplexVector& ComplexVector::operator+=(OpBinary<ComplexVector::Div> src)
|
||||
{
|
||||
if ((this != &reinterpret_cast<ComplexVector&>(src.a)) && (this != &reinterpret_cast<ComplexVector&>(src.b)))
|
||||
{
|
||||
this->m_real += (src.a.m_real * src.b.m_real);
|
||||
this->m_real -= (src.a.m_imag * src.b.m_imag);
|
||||
|
||||
this->m_imag += (src.a.m_real * src.b.m_imag);
|
||||
this->m_imag += (src.a.m_imag * src.b.m_real);
|
||||
}
|
||||
else
|
||||
{
|
||||
ComplexVector result((src.a.m_real * src.b.m_real) - (src.a.m_imag * src.b.m_imag), (src.a.m_real * src.b.m_imag) + (src.a.m_imag * src.b.m_real));
|
||||
*this = *this + result;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// -= ComplexVector::OpBinaryDiv
|
||||
ComplexVector& ComplexVector::operator-=(OpBinary<ComplexVector::Div> src)
|
||||
{
|
||||
if ((this != &reinterpret_cast<ComplexVector&>(src.a)) && (this != &reinterpret_cast<ComplexVector&>(src.b)))
|
||||
{
|
||||
this->m_real -= (src.a.m_real * src.b.m_real);
|
||||
this->m_real += (src.a.m_imag * src.b.m_imag);
|
||||
|
||||
this->m_imag -= (src.a.m_real * src.b.m_imag);
|
||||
this->m_imag -= (src.a.m_imag * src.b.m_real);
|
||||
}
|
||||
else
|
||||
{
|
||||
ComplexVector result((src.a.m_real * src.b.m_real) - (src.a.m_imag * src.b.m_imag), (src.a.m_real * src.b.m_imag) + (src.a.m_imag * src.b.m_real));
|
||||
*this = *this - result;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// *= ComplexVector::OpBinaryDiv
|
||||
ComplexVector& ComplexVector::operator*=(OpBinary<ComplexVector::Div> src)
|
||||
{
|
||||
ComplexVector result((src.a.m_real * src.b.m_real) - (src.a.m_imag * src.b.m_imag), (src.a.m_real * src.b.m_imag) + (src.a.m_imag * src.b.m_real));
|
||||
*this = *this * result;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// /= ComplexVector::OpBinaryDiv
|
||||
ComplexVector& ComplexVector::operator/=(OpBinary<ComplexVector::Div> src)
|
||||
{
|
||||
ComplexVector result((src.a.m_real * src.b.m_real) - (src.a.m_imag * src.b.m_imag), (src.a.m_real * src.b.m_imag) + (src.a.m_imag * src.b.m_real));
|
||||
*this = *this / result;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// -------------------------------------------------
|
||||
// Binary Operators
|
||||
// -------------------------------------------------
|
||||
// Add
|
||||
// ComplexVector + ComplexVector*
|
||||
ComplexVector::OpBinary<ComplexVector::Add> operator+(const ComplexVector &a, const ComplexVector &b)
|
||||
{
|
||||
return ComplexVector::OpBinary<ComplexVector::Add> (a, b);
|
||||
}
|
||||
|
||||
// Sub
|
||||
// ComplexVector - ComplexVector*
|
||||
ComplexVector::OpBinary<ComplexVector::Sub> operator-(const ComplexVector &a, const ComplexVector &b)
|
||||
{
|
||||
return ComplexVector::OpBinary<ComplexVector::Sub> (a, b);
|
||||
}
|
||||
|
||||
// Mul
|
||||
// ComplexVector * ComplexVector*
|
||||
ComplexVector::OpBinary<ComplexVector::Mul> operator*(const ComplexVector &a, const ComplexVector &b)
|
||||
{
|
||||
return ComplexVector::OpBinary<ComplexVector::Mul> (a, b);
|
||||
}
|
||||
|
||||
// Div
|
||||
// ComplexVector / ComplexVector*
|
||||
ComplexVector::OpBinary<ComplexVector::Div> operator/(const ComplexVector &a, const ComplexVector &b)
|
||||
{
|
||||
return ComplexVector::OpBinary<ComplexVector::Div> (a, b);
|
||||
}
|
||||
Executable
+192
@@ -0,0 +1,192 @@
|
||||
#ifndef _COMPLEX_HPP_
|
||||
#define _COMPLEX_HPP_
|
||||
|
||||
#include <string>
|
||||
#include <memory.h>
|
||||
#include <radio/radio_types.h>
|
||||
#include <radio/RealVector.hpp>
|
||||
|
||||
void ComplexDebug(char *fmtstr, ...);
|
||||
|
||||
class ComplexException
|
||||
{
|
||||
public:
|
||||
ComplexException (std::string s)
|
||||
{
|
||||
m_what = s;
|
||||
}
|
||||
~ComplexException()
|
||||
{
|
||||
}
|
||||
std::string& what()
|
||||
{
|
||||
return m_what;
|
||||
}
|
||||
private:
|
||||
std::string m_what;
|
||||
};
|
||||
|
||||
class _ComplexVector;
|
||||
class ComplexVector
|
||||
{
|
||||
friend class _ComplexVector;
|
||||
public:
|
||||
|
||||
enum OpType
|
||||
{
|
||||
Add = 0,
|
||||
Sub,
|
||||
Mul,
|
||||
Div
|
||||
};
|
||||
|
||||
template <OpType op>
|
||||
struct OpBinary
|
||||
{
|
||||
_ComplexVector a;
|
||||
_ComplexVector b;
|
||||
|
||||
OpBinary(const _ComplexVector a_, const _ComplexVector b_)
|
||||
: a(a_)
|
||||
, b(b_)
|
||||
{
|
||||
}
|
||||
|
||||
~OpBinary()
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
OpBinary& operator=(const OpBinary&);
|
||||
};
|
||||
|
||||
// Standard constructor
|
||||
ComplexVector(uint32_t size, radio_float_t *real=0, radio_float_t *imag=0);
|
||||
|
||||
// Constructor from RealVector
|
||||
ComplexVector(const RealVector &real, const RealVector &imag);
|
||||
|
||||
// Constructeur de RealVector de la pointe
|
||||
ComplexVector(RealVector *real, RealVector *imag);
|
||||
|
||||
// Scalar constructor
|
||||
ComplexVector(radio_float_t real, radio_float_t imag);
|
||||
|
||||
// Unary resolver constructor (no data copy)
|
||||
ComplexVector(const _ComplexVector &src);
|
||||
|
||||
~ComplexVector(void);
|
||||
|
||||
uint32_t getSize();
|
||||
ComplexVector at(uint32_t const &i);
|
||||
void print(char *pPrefix);
|
||||
bool isNegative() const;
|
||||
bool isPositive() const;
|
||||
bool isConjugate() const;
|
||||
ComplexVector operator-() const;
|
||||
const ComplexVector& operator+() const;
|
||||
ComplexVector conj() const;
|
||||
|
||||
// Assignments
|
||||
ComplexVector& operator=(const ComplexVector &src);
|
||||
ComplexVector& operator+=(const ComplexVector &src);
|
||||
ComplexVector& operator-=(const ComplexVector &src);
|
||||
ComplexVector& operator*=(const ComplexVector &src);
|
||||
ComplexVector& operator/=(const ComplexVector &src);
|
||||
|
||||
ComplexVector& operator=(OpBinary<ComplexVector::Add> src);
|
||||
ComplexVector& operator+=(OpBinary<ComplexVector::Add> src);
|
||||
ComplexVector& operator-=(OpBinary<ComplexVector::Add> src);
|
||||
ComplexVector& operator*=(OpBinary<ComplexVector::Add> src);
|
||||
ComplexVector& operator/=(OpBinary<ComplexVector::Add> src);
|
||||
|
||||
ComplexVector& operator=(OpBinary<ComplexVector::Sub> src);
|
||||
ComplexVector& operator+=(OpBinary<ComplexVector::Sub> src);
|
||||
ComplexVector& operator-=(OpBinary<ComplexVector::Sub> src);
|
||||
ComplexVector& operator*=(OpBinary<ComplexVector::Sub> src);
|
||||
ComplexVector& operator/=(OpBinary<ComplexVector::Sub> src);
|
||||
|
||||
ComplexVector& operator=(OpBinary<ComplexVector::Mul> src);
|
||||
ComplexVector& operator+=(OpBinary<ComplexVector::Mul> src);
|
||||
ComplexVector& operator-=(OpBinary<ComplexVector::Mul> src);
|
||||
ComplexVector& operator*=(OpBinary<ComplexVector::Mul> src);
|
||||
ComplexVector& operator/=(OpBinary<ComplexVector::Mul> src);
|
||||
|
||||
ComplexVector& operator=(OpBinary<ComplexVector::Div> src);
|
||||
ComplexVector& operator+=(OpBinary<ComplexVector::Div> src);
|
||||
ComplexVector& operator-=(OpBinary<ComplexVector::Div> src);
|
||||
ComplexVector& operator*=(OpBinary<ComplexVector::Div> src);
|
||||
ComplexVector& operator/=(OpBinary<ComplexVector::Div> src);
|
||||
|
||||
private:
|
||||
uint32_t m_size;
|
||||
RealVector m_real;
|
||||
RealVector m_imag;
|
||||
|
||||
// Slicing constructor
|
||||
ComplexVector(const ComplexVector &src, uint32_t from, uint32_t step, uint32_t to)
|
||||
: m_size(0)
|
||||
, m_real(src.m_real, from, step, to)
|
||||
, m_imag(src.m_imag, from, step, to)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
for (i=from; i <= to; i+=step)
|
||||
{
|
||||
m_size++;
|
||||
}
|
||||
}
|
||||
|
||||
_inline void checkSize(uint32_t size1, uint32_t size2)
|
||||
{
|
||||
try
|
||||
{
|
||||
if ((size1 != size2) && (size2 != 1))
|
||||
{
|
||||
throw(ComplexException("Size mismatch"));
|
||||
}
|
||||
}
|
||||
catch(ComplexException &exc)
|
||||
{
|
||||
ComplexDebug("Problem: %s\n", exc.what().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class _ComplexVector
|
||||
{
|
||||
friend class ComplexVector;
|
||||
public:
|
||||
_ComplexVector(const ComplexVector &src);
|
||||
_ComplexVector(const _RealVector &real, const _RealVector &imag);
|
||||
_ComplexVector _ComplexVector::operator-() const;
|
||||
_ComplexVector _ComplexVector::conj() const;
|
||||
|
||||
private:
|
||||
uint32_t m_size;
|
||||
_RealVector m_real;
|
||||
_RealVector m_imag;
|
||||
|
||||
};
|
||||
|
||||
// Non-Member
|
||||
// Binary Operators
|
||||
|
||||
// Add
|
||||
// ComplexVector + ComplexVector*
|
||||
ComplexVector::OpBinary<ComplexVector::Add> operator+(const ComplexVector &a, const ComplexVector &b);
|
||||
|
||||
// Sub
|
||||
// ComplexVector - ComplexVector*
|
||||
ComplexVector::OpBinary<ComplexVector::Sub> operator-(const ComplexVector &a, const ComplexVector &b);
|
||||
|
||||
// Mul
|
||||
// ComplexVector * ComplexVector*
|
||||
ComplexVector::OpBinary<ComplexVector::Mul> operator*(const ComplexVector &a, const ComplexVector &b);
|
||||
|
||||
// Div
|
||||
// ComplexVector / ComplexVector*
|
||||
ComplexVector::OpBinary<ComplexVector::Div> operator/(const ComplexVector &a, const ComplexVector &b);
|
||||
|
||||
#endif // _COMPLEX_HPP_
|
||||
Executable
+1182
File diff suppressed because it is too large
Load Diff
Executable
+1089
File diff suppressed because it is too large
Load Diff
Executable
+234
@@ -0,0 +1,234 @@
|
||||
#ifndef _REAL_HPP_
|
||||
#define _REAL_HPP_
|
||||
|
||||
#include <string>
|
||||
#include <memory.h>
|
||||
#include <radio/radio_types.h>
|
||||
|
||||
void RealDebug(char *fmtstr, ...);
|
||||
|
||||
class RealException
|
||||
{
|
||||
public:
|
||||
RealException (std::string s)
|
||||
{
|
||||
m_what = s;
|
||||
}
|
||||
~RealException()
|
||||
{
|
||||
}
|
||||
std::string& what()
|
||||
{
|
||||
return m_what;
|
||||
}
|
||||
private:
|
||||
std::string m_what;
|
||||
};
|
||||
|
||||
class _RealVector;
|
||||
|
||||
class RealVector
|
||||
{
|
||||
public:
|
||||
friend class _RealVector;
|
||||
struct unary_t
|
||||
{
|
||||
bool negative;
|
||||
|
||||
unary_t()
|
||||
: negative(0)
|
||||
{
|
||||
}
|
||||
|
||||
struct unary_t neg(bool doNegative)
|
||||
{
|
||||
negative = doNegative;
|
||||
return *this;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
enum OpType
|
||||
{
|
||||
Add = 0,
|
||||
Sub,
|
||||
Mul,
|
||||
Div
|
||||
};
|
||||
|
||||
template <OpType op>
|
||||
class OpBinary
|
||||
{
|
||||
public:
|
||||
const RealVector &a;
|
||||
const RealVector &b;
|
||||
unary_t m_unary_modifier;
|
||||
|
||||
OpBinary(const RealVector &a, const RealVector &b)
|
||||
: a(a)
|
||||
, b(b)
|
||||
, m_unary_modifier()
|
||||
{
|
||||
}
|
||||
|
||||
OpBinary(const OpBinary &src, unary_t unary_modifier)
|
||||
: a(src.a)
|
||||
, b(src.b)
|
||||
, m_unary_modifier(unary_modifier)
|
||||
{
|
||||
}
|
||||
|
||||
bool isNegative() const
|
||||
{
|
||||
return m_unary_modifier.negative;
|
||||
}
|
||||
|
||||
bool isPositive() const
|
||||
{
|
||||
return !m_unary_modifier.negative;
|
||||
}
|
||||
|
||||
OpBinary operator-() const
|
||||
{
|
||||
unary_t unary = m_unary_modifier;
|
||||
unary.negative = !unary.negative;
|
||||
|
||||
return OpBinary(*this, unary);
|
||||
}
|
||||
|
||||
const OpBinary& operator+() const
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
~OpBinary()
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
OpBinary& operator=(const OpBinary&);
|
||||
};
|
||||
|
||||
|
||||
// Construct from float array
|
||||
RealVector(uint32_t size, radio_float_t *real=0);
|
||||
|
||||
// Copy constructor
|
||||
RealVector(const RealVector &src);
|
||||
|
||||
// Slicing constructor
|
||||
RealVector(const RealVector &src, uint32_t from, uint32_t step, uint32_t to);
|
||||
|
||||
// Unary resolver constructor (no data copy)
|
||||
RealVector(const RealVector &src, unary_t unary_modifier);
|
||||
|
||||
// OpBinaryAdd resolver copy constructor
|
||||
RealVector(const OpBinary<Add> &src);
|
||||
|
||||
// OpBinarySub resolver copy constructor
|
||||
RealVector(const OpBinary<Sub> &src);
|
||||
|
||||
// OpBinaryMul resolver copy constructor
|
||||
RealVector(const OpBinary<Mul> &src);
|
||||
|
||||
// OpBinaryDiv resolver copy constructor
|
||||
RealVector(const OpBinary<Div> &src);
|
||||
|
||||
// Scalar constructor
|
||||
RealVector(radio_float_t real);
|
||||
|
||||
RealVector(const _RealVector &src);
|
||||
|
||||
~RealVector(void);
|
||||
|
||||
uint32_t getSize() const;
|
||||
radio_float_t getValue() const;
|
||||
RealVector at(uint32_t const &i);
|
||||
RealVector slice(uint32_t from, uint32_t step, uint32_t to);
|
||||
void print(char *pPrefix) const;
|
||||
bool isNegative() const;
|
||||
bool isPositive() const;
|
||||
RealVector operator-() const;
|
||||
const RealVector& operator+() const;
|
||||
|
||||
// Assignments
|
||||
RealVector& operator=(const RealVector &src);
|
||||
RealVector& operator+=(const RealVector &src);
|
||||
RealVector& operator-=(const RealVector &src);
|
||||
RealVector& operator*=(const RealVector &src);
|
||||
RealVector& operator/=(const RealVector &src);
|
||||
|
||||
RealVector& operator=(const OpBinary<Add> &src);
|
||||
RealVector& operator+=(const OpBinary<Add> &src);
|
||||
RealVector& operator-=(const OpBinary<Add> &src);
|
||||
RealVector& operator*=(const OpBinary<Add> &src);
|
||||
RealVector& operator/=(const OpBinary<Add> &src);
|
||||
|
||||
RealVector& operator=(const OpBinary<Sub> &src);
|
||||
RealVector& operator+=(const OpBinary<Sub> &src);
|
||||
RealVector& operator-=(const OpBinary<Sub> &src);
|
||||
RealVector& operator*=(const OpBinary<Sub> &src);
|
||||
RealVector& operator/=(const OpBinary<Sub> &src);
|
||||
|
||||
RealVector& operator=(const OpBinary<Mul> &src);
|
||||
RealVector& operator+=(const OpBinary<Mul> &src);
|
||||
RealVector& operator-=(const OpBinary<Mul> &src);
|
||||
RealVector& operator*=(const OpBinary<Mul> &src);
|
||||
RealVector& operator/=(const OpBinary<Mul> &src);
|
||||
|
||||
RealVector& operator=(const OpBinary<Div> &src);
|
||||
RealVector& operator+=(const OpBinary<Div> &src);
|
||||
RealVector& operator-=(const OpBinary<Div> &src);
|
||||
RealVector& operator*=(const OpBinary<Div> &src);
|
||||
RealVector& operator/=(const OpBinary<Div> &src);
|
||||
|
||||
unary_t m_unary_modifier;
|
||||
|
||||
private:
|
||||
uint32_t m_size;
|
||||
radio_float_t m_real;
|
||||
radio_float_t *m_pBufReal;
|
||||
radio_float_t *m_pPtrReal;
|
||||
|
||||
_inline void checkSize(uint32_t size1, uint32_t size2)
|
||||
{
|
||||
try
|
||||
{
|
||||
if ((size1 != size2) && (size2 != 1))
|
||||
{
|
||||
throw(RealException("Size mismatch"));
|
||||
}
|
||||
}
|
||||
catch(RealException &exc)
|
||||
{
|
||||
RealDebug("Problem: %s\n", exc.what().c_str());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class _RealVector
|
||||
{
|
||||
friend class RealVector;
|
||||
public:
|
||||
_RealVector(const RealVector &src);
|
||||
_RealVector(const _RealVector &src, RealVector::unary_t unary_modifier);
|
||||
_RealVector operator-() const;
|
||||
uint32_t m_size;
|
||||
|
||||
private:
|
||||
radio_float_t m_real;
|
||||
radio_float_t *m_pBufReal;
|
||||
radio_float_t *m_pPtrReal;
|
||||
RealVector::unary_t m_unary_modifier;
|
||||
|
||||
};
|
||||
|
||||
// Non-Member
|
||||
// Binary Operators
|
||||
// Returning RealVector::OpBinary
|
||||
RealVector::OpBinary<RealVector::Add> operator+(const RealVector &a, const RealVector &b);
|
||||
RealVector::OpBinary<RealVector::Sub> operator-(const RealVector &a, const RealVector &b);
|
||||
RealVector::OpBinary<RealVector::Mul> operator*(const RealVector &a, const RealVector &b);
|
||||
RealVector::OpBinary<RealVector::Div> operator/(const RealVector &a, const RealVector &b);
|
||||
|
||||
#endif // _REAL_HPP_
|
||||
Executable
+403
@@ -0,0 +1,403 @@
|
||||
#ifndef _REAL_HPP_
|
||||
#define _REAL_HPP_
|
||||
|
||||
#include <string>
|
||||
#include <memory.h>
|
||||
#include <radio/radio_types.h>
|
||||
|
||||
void RealDebug(char *fmtstr, ...);
|
||||
|
||||
class RealException
|
||||
{
|
||||
public:
|
||||
RealException (std::string s)
|
||||
{
|
||||
m_what = s;
|
||||
}
|
||||
~RealException()
|
||||
{
|
||||
}
|
||||
std::string& what()
|
||||
{
|
||||
return m_what;
|
||||
}
|
||||
private:
|
||||
std::string m_what;
|
||||
};
|
||||
|
||||
class RealVectorNegative;
|
||||
|
||||
class RealVector
|
||||
{
|
||||
public:
|
||||
|
||||
struct OpBinaryAdd
|
||||
{
|
||||
struct Negative
|
||||
{
|
||||
Negative(const OpBinaryAdd src)
|
||||
: a(src.a)
|
||||
, b(src.b)
|
||||
{
|
||||
}
|
||||
|
||||
OpBinaryAdd operator-() const
|
||||
{
|
||||
return OpBinaryAdd(a, b);
|
||||
}
|
||||
const RealVector &a;
|
||||
const RealVector &b;
|
||||
|
||||
private:
|
||||
Negative& operator=(const Negative&);
|
||||
};
|
||||
|
||||
OpBinaryAdd(const RealVector &a, const RealVector &b)
|
||||
: a(a)
|
||||
, b(b)
|
||||
{
|
||||
}
|
||||
|
||||
Negative operator-() const
|
||||
{
|
||||
return Negative(*this);
|
||||
}
|
||||
|
||||
const OpBinaryAdd& operator+() const
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
~OpBinaryAdd()
|
||||
{
|
||||
}
|
||||
const RealVector &a;
|
||||
const RealVector &b;
|
||||
|
||||
private:
|
||||
OpBinaryAdd& operator=(const OpBinaryAdd&);
|
||||
};
|
||||
|
||||
struct OpBinarySub
|
||||
{
|
||||
struct Negative
|
||||
{
|
||||
Negative(const OpBinarySub src)
|
||||
: a(src.a)
|
||||
, b(src.b)
|
||||
{
|
||||
}
|
||||
|
||||
OpBinarySub operator-() const
|
||||
{
|
||||
return OpBinarySub(a, b);
|
||||
}
|
||||
const RealVector &a;
|
||||
const RealVector &b;
|
||||
|
||||
private:
|
||||
Negative& operator=(const Negative&);
|
||||
};
|
||||
|
||||
OpBinarySub(const RealVector &a, const RealVector &b)
|
||||
: a(a)
|
||||
, b(b)
|
||||
{
|
||||
}
|
||||
|
||||
~OpBinarySub()
|
||||
{
|
||||
}
|
||||
|
||||
Negative operator-() const
|
||||
{
|
||||
return Negative(*this);
|
||||
}
|
||||
|
||||
const OpBinarySub& operator+() const
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
const RealVector &a;
|
||||
const RealVector &b;
|
||||
|
||||
private:
|
||||
OpBinarySub& operator=(const OpBinarySub&);
|
||||
};
|
||||
|
||||
struct OpBinaryMul
|
||||
{
|
||||
struct Negative
|
||||
{
|
||||
Negative(const OpBinaryMul src)
|
||||
: a(src.a)
|
||||
, b(src.b)
|
||||
{
|
||||
}
|
||||
|
||||
OpBinaryMul operator-() const
|
||||
{
|
||||
return OpBinaryMul(a, b);
|
||||
}
|
||||
const RealVector &a;
|
||||
const RealVector &b;
|
||||
|
||||
private:
|
||||
Negative& operator=(const Negative&);
|
||||
};
|
||||
|
||||
OpBinaryMul(const RealVector &a, const RealVector &b)
|
||||
: a(a)
|
||||
, b(b)
|
||||
{
|
||||
}
|
||||
|
||||
Negative operator-() const
|
||||
{
|
||||
return Negative(*this);
|
||||
}
|
||||
|
||||
const OpBinaryMul& operator+() const
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
~OpBinaryMul()
|
||||
{
|
||||
}
|
||||
const RealVector &a;
|
||||
const RealVector &b;
|
||||
|
||||
private:
|
||||
OpBinaryMul& operator=(const OpBinaryMul&);
|
||||
};
|
||||
|
||||
struct OpBinaryDiv
|
||||
{
|
||||
struct Negative
|
||||
{
|
||||
Negative(const OpBinaryDiv src)
|
||||
: a(src.a)
|
||||
, b(src.b)
|
||||
{
|
||||
}
|
||||
|
||||
OpBinaryDiv operator-() const
|
||||
{
|
||||
return OpBinaryDiv(a, b);
|
||||
}
|
||||
const RealVector &a;
|
||||
const RealVector &b;
|
||||
|
||||
private:
|
||||
Negative& operator=(const Negative&);
|
||||
};
|
||||
|
||||
OpBinaryDiv(const RealVector &a, const RealVector &b)
|
||||
: a(a)
|
||||
, b(b)
|
||||
{
|
||||
}
|
||||
|
||||
Negative operator-() const
|
||||
{
|
||||
return Negative(*this);
|
||||
}
|
||||
|
||||
const OpBinaryDiv& operator+() const
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
~OpBinaryDiv()
|
||||
{
|
||||
}
|
||||
const RealVector &a;
|
||||
const RealVector &b;
|
||||
|
||||
private:
|
||||
OpBinaryDiv& operator=(const OpBinaryDiv&);
|
||||
};
|
||||
|
||||
~RealVector(void);
|
||||
|
||||
// Standard constructor
|
||||
RealVector(uint32_t size, radio_float_t *real=0);
|
||||
|
||||
// Copy constructor
|
||||
RealVector(const RealVector &src);
|
||||
|
||||
// Slicing constructor
|
||||
RealVector(RealVector &src, uint32_t from, uint32_t step, uint32_t to);
|
||||
|
||||
// Negative resolver copy constructor
|
||||
RealVector(const RealVectorNegative &src);
|
||||
|
||||
// OpBinaryAdd resolver copy constructor
|
||||
RealVector(const OpBinaryAdd &src);
|
||||
|
||||
// OpBinaryAdd::Negative resolver copy constructor
|
||||
RealVector(const OpBinaryAdd::Negative &src);
|
||||
|
||||
// OpBinarySub resolver copy constructor
|
||||
RealVector(const OpBinarySub &src);
|
||||
|
||||
// OpBinaryMul resolver copy constructor
|
||||
RealVector(const OpBinaryMul &src);
|
||||
|
||||
// OpBinaryMul::Negative resolver copy constructor
|
||||
RealVector(const OpBinaryMul::Negative &src);
|
||||
|
||||
// OpBinaryDiv resolver copy constructor
|
||||
RealVector(const OpBinaryDiv &src);
|
||||
|
||||
// OpBinaryDiv::Negative resolver copy constructor
|
||||
RealVector(const OpBinaryDiv::Negative &src);
|
||||
|
||||
// Scalar constructor
|
||||
RealVector(radio_float_t real);
|
||||
|
||||
uint32_t getSize() const;
|
||||
|
||||
radio_float_t getValue() const;
|
||||
|
||||
RealVector at(uint32_t const &i);
|
||||
void print(char *pPrefix) const;
|
||||
|
||||
RealVectorNegative operator-() const;
|
||||
const RealVector& operator+() const;
|
||||
|
||||
// Assignments
|
||||
RealVector& operator=(const RealVector &src);
|
||||
RealVector& operator+=(const RealVector &src);
|
||||
RealVector& operator-=(const RealVector &src);
|
||||
RealVector& operator*=(const RealVector &src);
|
||||
RealVector& operator/=(const RealVector &src);
|
||||
|
||||
RealVector& operator=(const RealVectorNegative &src);
|
||||
RealVector& operator+=(const RealVectorNegative &src);
|
||||
RealVector& operator-=(const RealVectorNegative &src);
|
||||
RealVector& operator*=(const RealVectorNegative &src);
|
||||
RealVector& operator/=(const RealVectorNegative &src);
|
||||
|
||||
RealVector& operator=(const OpBinaryAdd &src);
|
||||
RealVector& operator+=(const OpBinaryAdd &src);
|
||||
RealVector& operator-=(const OpBinaryAdd &src);
|
||||
RealVector& operator*=(const OpBinaryAdd &src);
|
||||
RealVector& operator/=(const OpBinaryAdd &src);
|
||||
|
||||
RealVector& operator=(const OpBinaryAdd::Negative &src);
|
||||
RealVector& operator+=(const OpBinaryAdd::Negative &src);
|
||||
RealVector& operator-=(const OpBinaryAdd::Negative &src);
|
||||
RealVector& operator*=(const OpBinaryAdd::Negative &src);
|
||||
RealVector& operator/=(const OpBinaryAdd::Negative &src);
|
||||
|
||||
RealVector& operator=(const OpBinarySub &src);
|
||||
RealVector& operator+=(const OpBinarySub &src);
|
||||
RealVector& operator-=(const OpBinarySub &src);
|
||||
RealVector& operator*=(const OpBinarySub &src);
|
||||
RealVector& operator/=(const OpBinarySub &src);
|
||||
|
||||
RealVector& operator=(const OpBinaryMul &src);
|
||||
RealVector& operator+=(const OpBinaryMul &src);
|
||||
RealVector& operator-=(const OpBinaryMul &src);
|
||||
RealVector& operator*=(const OpBinaryMul &src);
|
||||
RealVector& operator/=(const OpBinaryMul &src);
|
||||
|
||||
RealVector& operator=(const OpBinaryMul::Negative &src);
|
||||
RealVector& operator+=(const OpBinaryMul::Negative &src);
|
||||
RealVector& operator-=(const OpBinaryMul::Negative &src);
|
||||
RealVector& operator*=(const OpBinaryMul::Negative &src);
|
||||
RealVector& operator/=(const OpBinaryMul::Negative &src);
|
||||
|
||||
RealVector& operator=(const OpBinaryDiv &src);
|
||||
RealVector& operator+=(const OpBinaryDiv &src);
|
||||
RealVector& operator-=(const OpBinaryDiv &src);
|
||||
RealVector& operator*=(const OpBinaryDiv &src);
|
||||
RealVector& operator/=(const OpBinaryDiv &src);
|
||||
|
||||
RealVector& operator=(const OpBinaryDiv::Negative &src);
|
||||
RealVector& operator+=(const OpBinaryDiv::Negative &src);
|
||||
RealVector& operator-=(const OpBinaryDiv::Negative &src);
|
||||
RealVector& operator*=(const OpBinaryDiv::Negative &src);
|
||||
RealVector& operator/=(const OpBinaryDiv::Negative &src);
|
||||
|
||||
private:
|
||||
uint32_t m_size;
|
||||
radio_float_t m_real;
|
||||
radio_float_t *m_pBufReal;
|
||||
radio_float_t *m_pPtrReal;
|
||||
|
||||
_inline void checkSize(uint32_t size1, uint32_t size2)
|
||||
{
|
||||
try
|
||||
{
|
||||
if ((size1 != size2) && (size2 != 1))
|
||||
{
|
||||
throw(RealException("Size mismatch"));
|
||||
}
|
||||
}
|
||||
catch(RealException &exc)
|
||||
{
|
||||
RealDebug("Problem: %s\n", exc.what().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class RealVectorNegative : public RealVector
|
||||
{
|
||||
public:
|
||||
RealVectorNegative(const RealVector &src)
|
||||
: RealVector(src)
|
||||
, m_iamNegative(true)
|
||||
{
|
||||
}
|
||||
|
||||
const RealVector& operator-() const
|
||||
{
|
||||
return (RealVector&)*this;
|
||||
}
|
||||
|
||||
const RealVectorNegative& operator+() const
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
bool m_iamNegative;
|
||||
RealVectorNegative& operator=(const RealVectorNegative&);
|
||||
};
|
||||
|
||||
|
||||
// Non-Member
|
||||
// Binary Operators
|
||||
// Returning RealVector::OpBinary
|
||||
RealVector::OpBinaryAdd operator+(const RealVector &a, const RealVector &b);
|
||||
#if 0
|
||||
RealVector::OpBinarySub operator+(const RealVectorNegative &a, const RealVector &b);
|
||||
RealVector::OpBinarySub operator+(const RealVector &a, const RealVectorNegative &b);
|
||||
RealVector::OpBinaryAdd::Negative operator+(const RealVectorNegative &a, const RealVectorNegative &b);
|
||||
#endif
|
||||
|
||||
RealVector::OpBinarySub operator-(const RealVector &a, const RealVector &b);
|
||||
#if 0
|
||||
RealVector::OpBinaryAdd::Negative operator-(const RealVectorNegative &a, const RealVector &b);
|
||||
RealVector::OpBinaryAdd operator-(const RealVector &a, const RealVectorNegative &b);
|
||||
RealVector::OpBinarySub operator-(const RealVectorNegative &a, const RealVectorNegative &b);
|
||||
#endif
|
||||
|
||||
RealVector::OpBinaryMul operator*(const RealVector &a, const RealVector &b);
|
||||
#if 0
|
||||
RealVector::OpBinaryMul::Negative operator*(const RealVectorNegative &a, const RealVector &b);
|
||||
RealVector::OpBinaryMul::Negative operator*(const RealVector &a, const RealVectorNegative &b);
|
||||
RealVector::OpBinaryMul operator*(const RealVectorNegative &a, const RealVectorNegative &b);
|
||||
#endif
|
||||
|
||||
RealVector::OpBinaryDiv operator/(const RealVector &a, const RealVector &b);
|
||||
RealVector::OpBinaryDiv::Negative operator/(const RealVectorNegative &a, const RealVector &b);
|
||||
RealVector::OpBinaryDiv::Negative operator/(const RealVector &a, const RealVectorNegative &b);
|
||||
RealVector::OpBinaryDiv operator/(const RealVectorNegative &a, const RealVectorNegative &b);
|
||||
|
||||
#endif // _REAL_HPP_
|
||||
Executable
+785
@@ -0,0 +1,785 @@
|
||||
#include <windows.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "RealVector.hpp"
|
||||
|
||||
void RealDebug(char *fmtstr, ...)
|
||||
{
|
||||
char buf[1024];
|
||||
va_list args;
|
||||
|
||||
va_start(args, fmtstr);
|
||||
vsprintf(buf, fmtstr, args);
|
||||
va_end(args);
|
||||
OutputDebugString(buf);
|
||||
|
||||
}
|
||||
|
||||
// -------------------------------------------------
|
||||
// Assignments
|
||||
// -------------------------------------------------
|
||||
// = RealVector
|
||||
RealVector& RealVector::operator=(const RealVector &src)
|
||||
{
|
||||
uint32_t i;
|
||||
uint32_t j;
|
||||
uint32_t dj;
|
||||
|
||||
checkSize(m_size, src.m_size);
|
||||
|
||||
j = 0;
|
||||
dj = src.m_size > 1;
|
||||
if (src.isNegative())
|
||||
{
|
||||
for (i=0; i < m_size; i++)
|
||||
{
|
||||
m_pPtrReal[i] = -src.m_pPtrReal[j];
|
||||
j += dj;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i=0; i < m_size; i++)
|
||||
{
|
||||
m_pPtrReal[i] = src.m_pPtrReal[j];
|
||||
j += dj;
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// += RealVector
|
||||
RealVector& RealVector::operator+=(const RealVector &src)
|
||||
{
|
||||
uint32_t i;
|
||||
uint32_t j;
|
||||
uint32_t dj;
|
||||
|
||||
checkSize(m_size, src.m_size);
|
||||
|
||||
j = 0;
|
||||
dj = src.m_size > 1;
|
||||
if (src.isNegative())
|
||||
{
|
||||
for (i=0; i < m_size; i++)
|
||||
{
|
||||
m_pPtrReal[i] -= src.m_pPtrReal[j];
|
||||
j += dj;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i=0; i < m_size; i++)
|
||||
{
|
||||
m_pPtrReal[i] += src.m_pPtrReal[j];
|
||||
j += dj;
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// -= RealVector
|
||||
RealVector& RealVector::operator-=(const RealVector &src)
|
||||
{
|
||||
uint32_t i;
|
||||
uint32_t j;
|
||||
uint32_t dj;
|
||||
|
||||
checkSize(m_size, src.m_size);
|
||||
|
||||
j = 0;
|
||||
dj = src.m_size > 1;
|
||||
if (src.isNegative())
|
||||
{
|
||||
for (i=0; i < m_size; i++)
|
||||
{
|
||||
m_pPtrReal[i] += src.m_pPtrReal[j];
|
||||
j += dj;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i=0; i < m_size; i++)
|
||||
{
|
||||
m_pPtrReal[i] -= src.m_pPtrReal[j];
|
||||
j += dj;
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// *= RealVector
|
||||
RealVector& RealVector::operator*=(const RealVector &src)
|
||||
{
|
||||
uint32_t i;
|
||||
uint32_t j;
|
||||
uint32_t dj;
|
||||
|
||||
checkSize(m_size, src.m_size);
|
||||
|
||||
j = 0;
|
||||
dj = src.m_size > 1;
|
||||
if (src.isNegative())
|
||||
{
|
||||
for (i=0; i < m_size; i++)
|
||||
{
|
||||
m_pPtrReal[i] *= -src.m_pPtrReal[j];
|
||||
j += dj;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i=0; i < m_size; i++)
|
||||
{
|
||||
m_pPtrReal[i] *= src.m_pPtrReal[j];
|
||||
j += dj;
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// /= RealVector
|
||||
RealVector& RealVector::operator/=(const RealVector &src)
|
||||
{
|
||||
uint32_t i;
|
||||
uint32_t j;
|
||||
uint32_t dj;
|
||||
|
||||
checkSize(m_size, src.m_size);
|
||||
|
||||
j = 0;
|
||||
dj = src.m_size > 1;
|
||||
if (src.isNegative())
|
||||
{
|
||||
for (i=0; i < m_size; i++)
|
||||
{
|
||||
m_pPtrReal[i] /= -src.m_pPtrReal[j];
|
||||
j += dj;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i=0; i < m_size; i++)
|
||||
{
|
||||
m_pPtrReal[i] /= src.m_pPtrReal[j];
|
||||
j += dj;
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// = RealVector::OpBinary
|
||||
RealVector& RealVector::operator=(const OpBinary &src)
|
||||
{
|
||||
uint32_t i, j, k;
|
||||
uint32_t dj, dk;
|
||||
|
||||
dj = src.a.m_size > 1;
|
||||
dk = src.b.m_size > 1;
|
||||
|
||||
j = 0;
|
||||
k = 0;
|
||||
switch (src.op)
|
||||
{
|
||||
case OpBinary::ADD:
|
||||
if (!src.isNegative())
|
||||
{
|
||||
for (i=0; i < m_size; i++)
|
||||
{
|
||||
m_pPtrReal[i] = + src.a.m_pPtrReal[j] + src.b.m_pPtrReal[k];
|
||||
j += dj;
|
||||
k += dk;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i=0; i < m_size; i++)
|
||||
{
|
||||
m_pPtrReal[i] = - src.a.m_pPtrReal[j] - src.b.m_pPtrReal[k];
|
||||
j += dj;
|
||||
k += dk;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case OpBinary::SUB:
|
||||
if (!src.isNegative())
|
||||
{
|
||||
for (i=0; i < m_size; i++)
|
||||
{
|
||||
m_pPtrReal[i] = + src.a.m_pPtrReal[j] - src.b.m_pPtrReal[k];
|
||||
j += dj;
|
||||
k += dk;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i=0; i < m_size; i++)
|
||||
{
|
||||
m_pPtrReal[i] = - src.a.m_pPtrReal[j] + src.b.m_pPtrReal[k];
|
||||
j += dj;
|
||||
k += dk;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case OpBinary::MUL:
|
||||
if (!src.isNegative())
|
||||
{
|
||||
for (i=0; i < m_size; i++)
|
||||
{
|
||||
m_pPtrReal[i] = + src.a.m_pPtrReal[j] * src.b.m_pPtrReal[k];
|
||||
j += dj;
|
||||
k += dk;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i=0; i < m_size; i++)
|
||||
{
|
||||
m_pPtrReal[i] = - src.a.m_pPtrReal[j] * src.b.m_pPtrReal[k];
|
||||
j += dj;
|
||||
k += dk;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case OpBinary::DIV:
|
||||
if (!src.isNegative())
|
||||
{
|
||||
for (i=0; i < m_size; i++)
|
||||
{
|
||||
m_pPtrReal[i] = + src.a.m_pPtrReal[j] / src.b.m_pPtrReal[k];
|
||||
j += dj;
|
||||
k += dk;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i=0; i < m_size; i++)
|
||||
{
|
||||
m_pPtrReal[i] = - (src.a.m_pPtrReal[j] / src.b.m_pPtrReal[k]);
|
||||
j += dj;
|
||||
k += dk;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// += RealVector::OpBinary
|
||||
RealVector& RealVector::operator+=(const OpBinary &src)
|
||||
{
|
||||
uint32_t i, j, k;
|
||||
uint32_t dj, dk;
|
||||
|
||||
dj = src.a.m_size > 1;
|
||||
dk = src.b.m_size > 1;
|
||||
|
||||
j = 0;
|
||||
k = 0;
|
||||
switch (src.op)
|
||||
{
|
||||
case OpBinary::ADD:
|
||||
if (!src.isNegative())
|
||||
{
|
||||
for (i=0; i < m_size; i++)
|
||||
{
|
||||
m_pPtrReal[i] += + src.a.m_pPtrReal[j] + src.b.m_pPtrReal[k];
|
||||
j += dj;
|
||||
k += dk;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i=0; i < m_size; i++)
|
||||
{
|
||||
m_pPtrReal[i] += - src.a.m_pPtrReal[j] - src.b.m_pPtrReal[k];
|
||||
j += dj;
|
||||
k += dk;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case OpBinary::SUB:
|
||||
if (!src.isNegative())
|
||||
{
|
||||
for (i=0; i < m_size; i++)
|
||||
{
|
||||
m_pPtrReal[i] += + src.a.m_pPtrReal[j] - src.b.m_pPtrReal[k];
|
||||
j += dj;
|
||||
k += dk;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i=0; i < m_size; i++)
|
||||
{
|
||||
m_pPtrReal[i] += - src.a.m_pPtrReal[j] + src.b.m_pPtrReal[k];
|
||||
j += dj;
|
||||
k += dk;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case OpBinary::MUL:
|
||||
if (!src.isNegative())
|
||||
{
|
||||
for (i=0; i < m_size; i++)
|
||||
{
|
||||
m_pPtrReal[i] += + src.a.m_pPtrReal[j] * src.b.m_pPtrReal[k];
|
||||
j += dj;
|
||||
k += dk;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i=0; i < m_size; i++)
|
||||
{
|
||||
m_pPtrReal[i] += - src.a.m_pPtrReal[j] * src.b.m_pPtrReal[k];
|
||||
j += dj;
|
||||
k += dk;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case OpBinary::DIV:
|
||||
if (!src.isNegative())
|
||||
{
|
||||
for (i=0; i < m_size; i++)
|
||||
{
|
||||
m_pPtrReal[i] += + src.a.m_pPtrReal[j] / src.b.m_pPtrReal[k];
|
||||
j += dj;
|
||||
k += dk;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i=0; i < m_size; i++)
|
||||
{
|
||||
m_pPtrReal[i] += - (src.a.m_pPtrReal[j] / src.b.m_pPtrReal[k]);
|
||||
j += dj;
|
||||
k += dk;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// -= RealVector::OpBinary
|
||||
RealVector& RealVector::operator-=(const OpBinary &src)
|
||||
{
|
||||
uint32_t i, j, k;
|
||||
uint32_t dj, dk;
|
||||
|
||||
dj = src.a.m_size > 1;
|
||||
dk = src.b.m_size > 1;
|
||||
|
||||
j = 0;
|
||||
k = 0;
|
||||
switch (src.op)
|
||||
{
|
||||
case OpBinary::ADD:
|
||||
if (!src.isNegative())
|
||||
{
|
||||
for (i=0; i < m_size; i++)
|
||||
{
|
||||
m_pPtrReal[i] -= + src.a.m_pPtrReal[j] + src.b.m_pPtrReal[k];
|
||||
j += dj;
|
||||
k += dk;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i=0; i < m_size; i++)
|
||||
{
|
||||
m_pPtrReal[i] -= - src.a.m_pPtrReal[j] - src.b.m_pPtrReal[k];
|
||||
j += dj;
|
||||
k += dk;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case OpBinary::SUB:
|
||||
if (!src.isNegative())
|
||||
{
|
||||
for (i=0; i < m_size; i++)
|
||||
{
|
||||
m_pPtrReal[i] -= + src.a.m_pPtrReal[j] - src.b.m_pPtrReal[k];
|
||||
j += dj;
|
||||
k += dk;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i=0; i < m_size; i++)
|
||||
{
|
||||
m_pPtrReal[i] -= - src.a.m_pPtrReal[j] + src.b.m_pPtrReal[k];
|
||||
j += dj;
|
||||
k += dk;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case OpBinary::MUL:
|
||||
if (!src.isNegative())
|
||||
{
|
||||
for (i=0; i < m_size; i++)
|
||||
{
|
||||
m_pPtrReal[i] -= + src.a.m_pPtrReal[j] * src.b.m_pPtrReal[k];
|
||||
j += dj;
|
||||
k += dk;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i=0; i < m_size; i++)
|
||||
{
|
||||
m_pPtrReal[i] -= - src.a.m_pPtrReal[j] * src.b.m_pPtrReal[k];
|
||||
j += dj;
|
||||
k += dk;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case OpBinary::DIV:
|
||||
if (!src.isNegative())
|
||||
{
|
||||
for (i=0; i < m_size; i++)
|
||||
{
|
||||
m_pPtrReal[i] -= + src.a.m_pPtrReal[j] / src.b.m_pPtrReal[k];
|
||||
j += dj;
|
||||
k += dk;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i=0; i < m_size; i++)
|
||||
{
|
||||
m_pPtrReal[i] -= - (src.a.m_pPtrReal[j] / src.b.m_pPtrReal[k]);
|
||||
j += dj;
|
||||
k += dk;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// *= RealVector::OpBinary
|
||||
RealVector& RealVector::operator*=(const OpBinary &src)
|
||||
{
|
||||
uint32_t i, j, k;
|
||||
uint32_t dj, dk;
|
||||
|
||||
dj = src.a.m_size > 1;
|
||||
dk = src.b.m_size > 1;
|
||||
|
||||
j = 0;
|
||||
k = 0;
|
||||
switch (src.op)
|
||||
{
|
||||
case OpBinary::ADD:
|
||||
if (!src.isNegative())
|
||||
{
|
||||
for (i=0; i < m_size; i++)
|
||||
{
|
||||
m_pPtrReal[i] *= + src.a.m_pPtrReal[j] + src.b.m_pPtrReal[k];
|
||||
j += dj;
|
||||
k += dk;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i=0; i < m_size; i++)
|
||||
{
|
||||
m_pPtrReal[i] *= - src.a.m_pPtrReal[j] - src.b.m_pPtrReal[k];
|
||||
j += dj;
|
||||
k += dk;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case OpBinary::SUB:
|
||||
if (!src.isNegative())
|
||||
{
|
||||
for (i=0; i < m_size; i++)
|
||||
{
|
||||
m_pPtrReal[i] *= + src.a.m_pPtrReal[j] - src.b.m_pPtrReal[k];
|
||||
j += dj;
|
||||
k += dk;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i=0; i < m_size; i++)
|
||||
{
|
||||
m_pPtrReal[i] *= - src.a.m_pPtrReal[j] + src.b.m_pPtrReal[k];
|
||||
j += dj;
|
||||
k += dk;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case OpBinary::MUL:
|
||||
if (!src.isNegative())
|
||||
{
|
||||
for (i=0; i < m_size; i++)
|
||||
{
|
||||
m_pPtrReal[i] *= + src.a.m_pPtrReal[j] * src.b.m_pPtrReal[k];
|
||||
j += dj;
|
||||
k += dk;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i=0; i < m_size; i++)
|
||||
{
|
||||
m_pPtrReal[i] *= - src.a.m_pPtrReal[j] * src.b.m_pPtrReal[k];
|
||||
j += dj;
|
||||
k += dk;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case OpBinary::DIV:
|
||||
if (!src.isNegative())
|
||||
{
|
||||
for (i=0; i < m_size; i++)
|
||||
{
|
||||
m_pPtrReal[i] *= + src.a.m_pPtrReal[j] / src.b.m_pPtrReal[k];
|
||||
j += dj;
|
||||
k += dk;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i=0; i < m_size; i++)
|
||||
{
|
||||
m_pPtrReal[i] *= - (src.a.m_pPtrReal[j] / src.b.m_pPtrReal[k]);
|
||||
j += dj;
|
||||
k += dk;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// /= RealVector::OpBinary
|
||||
RealVector& RealVector::operator/=(const OpBinary &src)
|
||||
{
|
||||
uint32_t i, j, k;
|
||||
uint32_t dj, dk;
|
||||
|
||||
dj = src.a.m_size > 1;
|
||||
dk = src.b.m_size > 1;
|
||||
|
||||
j = 0;
|
||||
k = 0;
|
||||
switch (src.op)
|
||||
{
|
||||
case OpBinary::ADD:
|
||||
if (!src.isNegative())
|
||||
{
|
||||
for (i=0; i < m_size; i++)
|
||||
{
|
||||
m_pPtrReal[i] /= + src.a.m_pPtrReal[j] + src.b.m_pPtrReal[k];
|
||||
j += dj;
|
||||
k += dk;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i=0; i < m_size; i++)
|
||||
{
|
||||
m_pPtrReal[i] /= - src.a.m_pPtrReal[j] - src.b.m_pPtrReal[k];
|
||||
j += dj;
|
||||
k += dk;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case OpBinary::SUB:
|
||||
if (!src.isNegative())
|
||||
{
|
||||
for (i=0; i < m_size; i++)
|
||||
{
|
||||
m_pPtrReal[i] /= + src.a.m_pPtrReal[j] - src.b.m_pPtrReal[k];
|
||||
j += dj;
|
||||
k += dk;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i=0; i < m_size; i++)
|
||||
{
|
||||
m_pPtrReal[i] /= - src.a.m_pPtrReal[j] + src.b.m_pPtrReal[k];
|
||||
j += dj;
|
||||
k += dk;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case OpBinary::MUL:
|
||||
if (!src.isNegative())
|
||||
{
|
||||
for (i=0; i < m_size; i++)
|
||||
{
|
||||
m_pPtrReal[i] /= + src.a.m_pPtrReal[j] * src.b.m_pPtrReal[k];
|
||||
j += dj;
|
||||
k += dk;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i=0; i < m_size; i++)
|
||||
{
|
||||
m_pPtrReal[i] /= - src.a.m_pPtrReal[j] * src.b.m_pPtrReal[k];
|
||||
j += dj;
|
||||
k += dk;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case OpBinary::DIV:
|
||||
if (!src.isNegative())
|
||||
{
|
||||
for (i=0; i < m_size; i++)
|
||||
{
|
||||
m_pPtrReal[i] /= + src.a.m_pPtrReal[j] / src.b.m_pPtrReal[k];
|
||||
j += dj;
|
||||
k += dk;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i=0; i < m_size; i++)
|
||||
{
|
||||
m_pPtrReal[i] /= - (src.a.m_pPtrReal[j] / src.b.m_pPtrReal[k]);
|
||||
j += dj;
|
||||
k += dk;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// -------------------------------------------------
|
||||
// Binary Operators
|
||||
// -------------------------------------------------
|
||||
// Returning RealVector::OpBinary
|
||||
RealVector::OpBinary operator+(const RealVector &a, const RealVector &b)
|
||||
{
|
||||
if (a.isNegative())
|
||||
{
|
||||
if (b.isNegative())
|
||||
{
|
||||
return -RealVector::OpBinary (a, b, RealVector::OpBinary::ADD);
|
||||
}
|
||||
else
|
||||
{
|
||||
return RealVector::OpBinary (b, a, RealVector::OpBinary::SUB);
|
||||
}
|
||||
}
|
||||
|
||||
if (b.isNegative())
|
||||
{
|
||||
return RealVector::OpBinary (a, b, RealVector::OpBinary::SUB);
|
||||
}
|
||||
else
|
||||
{
|
||||
return RealVector::OpBinary (a, b, RealVector::OpBinary::ADD);
|
||||
}
|
||||
}
|
||||
|
||||
RealVector::OpBinary operator-(const RealVector &a, const RealVector &b)
|
||||
{
|
||||
if (a.isNegative())
|
||||
{
|
||||
if (b.isNegative())
|
||||
{
|
||||
return RealVector::OpBinary (b, a, RealVector::OpBinary::SUB);
|
||||
}
|
||||
else
|
||||
{
|
||||
return -RealVector::OpBinary (a, b, RealVector::OpBinary::ADD);
|
||||
}
|
||||
}
|
||||
|
||||
if (b.isNegative())
|
||||
{
|
||||
return RealVector::OpBinary (a, b, RealVector::OpBinary::SUB);
|
||||
}
|
||||
else
|
||||
{
|
||||
return RealVector::OpBinary (a, b, RealVector::OpBinary::ADD);
|
||||
}
|
||||
}
|
||||
|
||||
RealVector::OpBinary operator*(const RealVector &a, const RealVector &b)
|
||||
{
|
||||
if (a.isNegative())
|
||||
{
|
||||
if (b.isNegative())
|
||||
{
|
||||
return RealVector::OpBinary (a, b, RealVector::OpBinary::MUL);
|
||||
}
|
||||
else
|
||||
{
|
||||
return -RealVector::OpBinary (a, b, RealVector::OpBinary::MUL);
|
||||
}
|
||||
}
|
||||
|
||||
if (b.isNegative())
|
||||
{
|
||||
return -RealVector::OpBinary (a, b, RealVector::OpBinary::MUL);
|
||||
}
|
||||
else
|
||||
{
|
||||
return RealVector::OpBinary (a, b, RealVector::OpBinary::MUL);
|
||||
}
|
||||
}
|
||||
|
||||
RealVector::OpBinary operator/(const RealVector &a, const RealVector &b)
|
||||
{
|
||||
if (a.isNegative())
|
||||
{
|
||||
if (b.isNegative())
|
||||
{
|
||||
return RealVector::OpBinary (a, b, RealVector::OpBinary::DIV);
|
||||
}
|
||||
else
|
||||
{
|
||||
return -RealVector::OpBinary (a, b, RealVector::OpBinary::DIV);
|
||||
}
|
||||
}
|
||||
|
||||
if (b.isNegative())
|
||||
{
|
||||
return -RealVector::OpBinary (a, b, RealVector::OpBinary::DIV);
|
||||
}
|
||||
else
|
||||
{
|
||||
return RealVector::OpBinary (a, b, RealVector::OpBinary::DIV);
|
||||
}
|
||||
}
|
||||
Executable
+271
@@ -0,0 +1,271 @@
|
||||
#ifndef _REAL_HPP_
|
||||
#define _REAL_HPP_
|
||||
|
||||
#include <string>
|
||||
#include <memory.h>
|
||||
#include <radio/radio_types.h>
|
||||
|
||||
void RealDebug(char *fmtstr, ...);
|
||||
|
||||
class RealException
|
||||
{
|
||||
public:
|
||||
RealException (std::string s)
|
||||
{
|
||||
m_what = s;
|
||||
}
|
||||
~RealException()
|
||||
{
|
||||
}
|
||||
std::string& what()
|
||||
{
|
||||
return m_what;
|
||||
}
|
||||
private:
|
||||
std::string m_what;
|
||||
};
|
||||
|
||||
class RealVector
|
||||
{
|
||||
public:
|
||||
|
||||
struct OpBinary
|
||||
{
|
||||
enum OpType
|
||||
{
|
||||
ADD = 0,
|
||||
SUB,
|
||||
MUL,
|
||||
DIV
|
||||
};
|
||||
|
||||
typedef struct _attributes_t
|
||||
{
|
||||
bool negative;
|
||||
} attributes_t;
|
||||
|
||||
OpBinary(const RealVector &a, const RealVector &b, OpType op)
|
||||
: a(a)
|
||||
, b(b)
|
||||
, op(op)
|
||||
, m_attributes(defaultAttributes())
|
||||
{
|
||||
}
|
||||
OpBinary operator-()
|
||||
{
|
||||
attributes_t attributes = this->m_attributes;
|
||||
attributes.negative = !attributes.negative;
|
||||
|
||||
return OpBinary(*this, attributes);
|
||||
}
|
||||
~OpBinary()
|
||||
{
|
||||
}
|
||||
|
||||
bool isNegative() const
|
||||
{
|
||||
return m_attributes.negative;
|
||||
}
|
||||
const RealVector &a;
|
||||
const RealVector &b;
|
||||
const OpType op;
|
||||
attributes_t m_attributes;
|
||||
|
||||
private:
|
||||
OpBinary& operator=(const OpBinary&);
|
||||
OpBinary(const OpBinary &src, attributes_t attributes)
|
||||
: a(src.a)
|
||||
, b(src.b)
|
||||
, op(src.op)
|
||||
, m_attributes(attributes)
|
||||
{
|
||||
}
|
||||
static const attributes_t defaultAttributes()
|
||||
{
|
||||
attributes_t attributes;
|
||||
attributes.negative = false;
|
||||
return attributes;
|
||||
}
|
||||
};
|
||||
|
||||
typedef struct _attributes_t
|
||||
{
|
||||
bool negative;
|
||||
} attributes_t;
|
||||
|
||||
// Standard constructor
|
||||
RealVector(uint32_t size, radio_float_t *real=0)
|
||||
: m_size(size)
|
||||
, m_real(0)
|
||||
, m_pBufReal(0)
|
||||
, m_pPtrReal(real)
|
||||
, m_attributes(defaultAttributes())
|
||||
{
|
||||
if (!real)
|
||||
{
|
||||
m_pBufReal = new radio_float_t[m_size];
|
||||
memset(m_pBufReal, 0, m_size*sizeof(radio_float_t));
|
||||
m_pPtrReal = m_pBufReal;
|
||||
}
|
||||
}
|
||||
|
||||
// OpBinary resolver copy constructor
|
||||
RealVector(const OpBinary &src)
|
||||
: m_size(src.a.m_size)
|
||||
, m_real(0)
|
||||
, m_pBufReal(0)
|
||||
, m_pPtrReal(0)
|
||||
, m_attributes(defaultAttributes())
|
||||
{
|
||||
m_pBufReal = new radio_float_t[m_size];
|
||||
m_pPtrReal = m_pBufReal;
|
||||
|
||||
*this = src;
|
||||
}
|
||||
|
||||
// Scalar constructor
|
||||
RealVector(radio_float_t real)
|
||||
: m_size(1)
|
||||
, m_real(real)
|
||||
, m_pBufReal(0)
|
||||
, m_pPtrReal(&m_real)
|
||||
, m_attributes(defaultAttributes())
|
||||
{
|
||||
}
|
||||
|
||||
~RealVector(void)
|
||||
{
|
||||
if (m_pBufReal)
|
||||
delete(m_pBufReal);
|
||||
|
||||
m_pBufReal = nullptr;
|
||||
}
|
||||
|
||||
bool isNegative() const
|
||||
{
|
||||
return m_attributes.negative;
|
||||
}
|
||||
|
||||
uint32_t getSize()
|
||||
{
|
||||
return m_size;
|
||||
}
|
||||
|
||||
RealVector at(uint32_t const &i)
|
||||
{
|
||||
return RealVector(*this, i, 1, i);
|
||||
}
|
||||
|
||||
void print(char *pPrefix)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
RealDebug("%s:\n", pPrefix);
|
||||
for (i=0; i < m_size; i++)
|
||||
{
|
||||
RealDebug("%d: %.6f\n", i, m_pPtrReal[i]);
|
||||
}
|
||||
}
|
||||
|
||||
RealVector operator-()
|
||||
{
|
||||
attributes_t attributes = this->m_attributes;
|
||||
attributes.negative = !attributes.negative;
|
||||
|
||||
return RealVector(*this, attributes);
|
||||
}
|
||||
|
||||
// Assignments
|
||||
RealVector& operator=(const RealVector &src);
|
||||
RealVector& operator+=(const RealVector &src);
|
||||
RealVector& operator-=(const RealVector &src);
|
||||
RealVector& operator*=(const RealVector &src);
|
||||
RealVector& operator/=(const RealVector &src);
|
||||
RealVector& operator=(const OpBinary &src);
|
||||
RealVector& operator+=(const OpBinary &src);
|
||||
RealVector& operator-=(const OpBinary &src);
|
||||
RealVector& operator*=(const OpBinary &src);
|
||||
RealVector& operator/=(const OpBinary &src);
|
||||
|
||||
private:
|
||||
uint32_t m_size;
|
||||
radio_float_t m_real;
|
||||
radio_float_t *m_pBufReal;
|
||||
radio_float_t *m_pPtrReal;
|
||||
attributes_t m_attributes;
|
||||
|
||||
// Attribute default
|
||||
const attributes_t defaultAttributes()
|
||||
{
|
||||
attributes_t attributes;
|
||||
|
||||
attributes.negative = 0;
|
||||
|
||||
return attributes;
|
||||
}
|
||||
|
||||
// Copy constructor
|
||||
RealVector(const RealVector &src)
|
||||
: m_size(src.m_size)
|
||||
, m_real(0)
|
||||
, m_pBufReal(0)
|
||||
, m_pPtrReal(0)
|
||||
{
|
||||
m_pBufReal = new radio_float_t[m_size];
|
||||
m_pPtrReal = m_pBufReal;
|
||||
|
||||
*this = src;
|
||||
}
|
||||
|
||||
// Re-attribute constructor
|
||||
// Copies no data, just pointers and attributes
|
||||
RealVector(const RealVector &src, attributes_t attributes)
|
||||
: m_size(src.m_size)
|
||||
, m_real(src.m_real)
|
||||
, m_pBufReal(0)
|
||||
, m_pPtrReal(src.m_pPtrReal)
|
||||
, m_attributes(attributes)
|
||||
{
|
||||
}
|
||||
|
||||
// Slicing constructor
|
||||
RealVector(RealVector &src, uint32_t from, uint32_t step, uint32_t to)
|
||||
: m_size(0)
|
||||
, m_pBufReal(0)
|
||||
, m_pPtrReal(&src.m_pPtrReal[from])
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
for (i=from; i < to; i+=step)
|
||||
{
|
||||
m_size++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
_inline void checkSize(uint32_t size1, uint32_t size2)
|
||||
{
|
||||
try
|
||||
{
|
||||
if ((size1 != size2) && (size2 != 1))
|
||||
{
|
||||
throw(RealException("Size mismatch"));
|
||||
}
|
||||
}
|
||||
catch(RealException &exc)
|
||||
{
|
||||
RealDebug("Problem: %s\n", exc.what().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// Non-Member
|
||||
// Binary Operators
|
||||
// Returning RealVector::OpBinary
|
||||
RealVector::OpBinary operator+(const RealVector &a, const RealVector &b);
|
||||
RealVector::OpBinary operator-(const RealVector &a, const RealVector &b);
|
||||
RealVector::OpBinary operator*(const RealVector &a, const RealVector &b);
|
||||
RealVector::OpBinary operator/(const RealVector &a, const RealVector &b);
|
||||
|
||||
#endif // _REAL_HPP_
|
||||
@@ -0,0 +1,41 @@
|
||||
// --------------------------------------------------------------
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include "agc.h"
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// AGC
|
||||
// Scalar version
|
||||
// --------------------------------------------------------------
|
||||
void AGC_Init(agc_t *pObj, uint32_t windowLength, radio_float_t w_init)
|
||||
{
|
||||
pObj->w = w_init;
|
||||
SlidingMinMaxInit(&pObj->slMax, windowLength, (radio_float_t)1E12, 1);
|
||||
}
|
||||
|
||||
void AGC_Free(agc_t *pObj)
|
||||
{
|
||||
SlidingMinMaxFree(&pObj->slMax);
|
||||
}
|
||||
|
||||
void AGC_Process(agc_t *pObj, radio_float_t x, radio_float_t mu, radio_float_t target)
|
||||
{
|
||||
radio_float_t d2;
|
||||
radio_float_t e;
|
||||
|
||||
d2 = SlidingMinMaxProcess(&pObj->slMax, x);
|
||||
e = target - d2;
|
||||
pObj->w += mu*e*dabs(x);
|
||||
}
|
||||
|
||||
void AGC_Train(agc_t *pObj, radio_float_t e, radio_float_t mu)
|
||||
{
|
||||
pObj->w += mu*e;
|
||||
}
|
||||
|
||||
radio_float_t AGC_GetWeight(agc_t *pObj)
|
||||
{
|
||||
return pObj->w;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------
|
||||
@@ -0,0 +1,39 @@
|
||||
// --------------------------------------------------------------
|
||||
#ifndef AGC_H
|
||||
#define AGC_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "radio_types.h"
|
||||
#include "statistics.h"
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// Types
|
||||
// --------------------------------------------------------------
|
||||
typedef struct _agc_t
|
||||
{
|
||||
radio_float_t w;
|
||||
sl_minmax_t slMax;
|
||||
} agc_t;
|
||||
|
||||
// --------------------------------------------------------------
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// AGC
|
||||
// --------------------------------------------------------------
|
||||
// Scalar version
|
||||
void AGC_Init(agc_t *pObj, uint32_t windowLength, radio_float_t w_init);
|
||||
void AGC_Free(agc_t *pObj);
|
||||
void AGC_Train(agc_t *pObj, radio_float_t e, radio_float_t mu);
|
||||
void AGC_Process(agc_t *pObj, radio_float_t x, radio_float_t mu, radio_float_t target);
|
||||
radio_float_t AGC_GetWeight(agc_t *pObj);
|
||||
|
||||
// --------------------------------------------------------------
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif // __cplusplus
|
||||
|
||||
// --------------------------------------------------------------
|
||||
#endif // AGC_H
|
||||
@@ -0,0 +1,591 @@
|
||||
// --------------------------------------------------------------
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include "radio_types.h"
|
||||
#include "real.h"
|
||||
#include "cpx.h"
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// Basic Functions
|
||||
// --------------------------------------------------------------
|
||||
|
||||
cpx_t CpxConjS(cpx_t v1)
|
||||
{
|
||||
register cpx_t temp;
|
||||
|
||||
temp.real = v1.real;
|
||||
temp.imag = -v1.imag;
|
||||
|
||||
return temp;
|
||||
|
||||
}
|
||||
|
||||
cpx_t CpxAddS(cpx_t v1, cpx_t v2)
|
||||
{
|
||||
register cpx_t temp;
|
||||
|
||||
temp.real = v1.real + v2.real;
|
||||
temp.imag = v1.imag + v2.imag;
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
cpx_t CpxSubS(cpx_t v1, cpx_t v2)
|
||||
{
|
||||
register cpx_t temp;
|
||||
|
||||
temp.real = v1.real - v2.real;
|
||||
temp.imag = v1.imag - v2.imag;
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
cpx_t CpxMulS(cpx_t v1, cpx_t v2)
|
||||
{
|
||||
register cpx_t t_0;
|
||||
register cpx_t t_1;
|
||||
|
||||
t_0.real = v1.real*v2.real;
|
||||
t_1.real = v1.imag*v2.imag;
|
||||
t_0.imag = v1.real*v2.imag;
|
||||
t_1.imag = v1.imag*v2.real;
|
||||
|
||||
t_0.real -= t_1.real;
|
||||
t_0.imag += t_1.imag;
|
||||
|
||||
return t_0;
|
||||
}
|
||||
|
||||
cpx_t CpxScaleRealS(cpx_t v1, radio_float_t v2)
|
||||
{
|
||||
register cpx_t temp;
|
||||
|
||||
temp.real = v1.real*v2;
|
||||
temp.imag = v1.imag*v2;
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
cpx_t CpxScaleComplexS(cpx_t x, cpx_t gain)
|
||||
{
|
||||
register cpx_t temp;
|
||||
|
||||
temp.real = x.real*gain.real;
|
||||
temp.imag = x.imag*gain.imag;
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
cpx_t CpxFromReal(radio_float_t v1)
|
||||
{
|
||||
return Cpx(v1, v1);
|
||||
}
|
||||
|
||||
cpx_t Cpx(radio_float_t real, radio_float_t imag)
|
||||
{
|
||||
cpx_t res;
|
||||
|
||||
res.real = real;
|
||||
res.imag = imag;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
radio_float_t CpxMagS(cpx_t v1)
|
||||
{
|
||||
radio_float_t mag;
|
||||
|
||||
mag = (radio_float_t)sqrt(v1.real*v1.real + v1.imag*v1.imag);
|
||||
|
||||
return mag;
|
||||
}
|
||||
|
||||
radio_float_t CpxPhiS(cpx_t v1)
|
||||
{
|
||||
return (radio_float_t)atan2(v1.real, v1.imag);
|
||||
}
|
||||
|
||||
cpx_t CpxMinS(cpx_t x1, cpx_t x2)
|
||||
{
|
||||
return Cpx(dmin(x1.real, x2.real), dmin(x1.imag, x2.imag));
|
||||
}
|
||||
|
||||
cpx_t CpxMaxS(cpx_t x1, cpx_t x2)
|
||||
{
|
||||
return Cpx(dmax(x1.real, x2.real), dmax(x1.imag, x2.imag));
|
||||
}
|
||||
|
||||
radio_float_t cpxPowerDB(cpx_t v1, radio_float_t preScale)
|
||||
{
|
||||
return powerDB(CpxMagS(v1), preScale);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// Complex Functions
|
||||
// --------------------------------------------------------------
|
||||
void CpxCopy(cpx_t *pSrc, cpx_t *pDst, uint32_t len)
|
||||
{
|
||||
memcpy(pDst, pSrc, len*sizeof(cpx_t));
|
||||
}
|
||||
|
||||
void CpxConj(cpx_t *pSrcDst, uint32_t len)
|
||||
{
|
||||
uint32_t i;
|
||||
for(i=0; i < len; i++)
|
||||
pSrcDst[i] = CpxConjS(pSrcDst[i]);
|
||||
}
|
||||
|
||||
void CpxAddB8(cpx_t *pV1, cpx_t *pV2, cpx_t *pRes)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
radio_float_t r0[8];
|
||||
radio_float_t i0[8];
|
||||
|
||||
radio_float_t vr0[8];
|
||||
radio_float_t vr1[8];
|
||||
radio_float_t vi0[8];
|
||||
radio_float_t vi1[8];
|
||||
|
||||
for (i=0; i < 8; i++)
|
||||
{
|
||||
vr0[i] = pV1[i].real;
|
||||
vr1[i] = pV2[i].real;
|
||||
vi0[i] = pV1[i].imag;
|
||||
vi1[i] = pV2[i].imag;
|
||||
}
|
||||
|
||||
for (i=0; i < 8; i++)
|
||||
{
|
||||
r0[i] = vr0[i] + vr1[i];
|
||||
i0[i] = vi0[i] + vi1[i];
|
||||
}
|
||||
|
||||
for (i=0; i < 8; i++)
|
||||
{
|
||||
pRes[i].real = r0[i];
|
||||
pRes[i].imag = i0[i];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void CpxAdd(cpx_t *pSrc, cpx_t *pSrcDst, uint32_t len)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
for(i=0; i < len-8; i += 8)
|
||||
{
|
||||
CpxAddB8(&pSrc[i], &pSrcDst[i], &pSrcDst[i]);
|
||||
}
|
||||
|
||||
for(i=i; i < len; i++)
|
||||
{
|
||||
pSrcDst[i].real += pSrc[i].real;
|
||||
pSrcDst[i].imag += pSrc[i].imag;
|
||||
}
|
||||
}
|
||||
|
||||
void CpxSub(cpx_t *pSrc, cpx_t *pSrcDst, uint32_t len)
|
||||
{
|
||||
uint32_t i;
|
||||
for(i=0; i < len; i++)
|
||||
pSrcDst[i] = CpxSubS(pSrc[i], pSrcDst[i]);
|
||||
}
|
||||
|
||||
void CpxMulB8(cpx_t *pV1, cpx_t *pV2, cpx_t *pRes)
|
||||
{
|
||||
uint32_t i;
|
||||
radio_float_t r0[8];
|
||||
radio_float_t r1[8];
|
||||
|
||||
radio_float_t vr0[8];
|
||||
radio_float_t vr1[8];
|
||||
radio_float_t vi0[8];
|
||||
radio_float_t vi1[8];
|
||||
|
||||
for (i=0; i < 8; i++)
|
||||
{
|
||||
vr0[i] = pV1[i].real;
|
||||
vr1[i] = pV2[i].real;
|
||||
vi0[i] = pV1[i].imag;
|
||||
vi1[i] = pV2[i].imag;
|
||||
}
|
||||
|
||||
for (i=0; i < 8; i++)
|
||||
{
|
||||
r0[i] = vr0[i]*vr1[i];
|
||||
}
|
||||
for (i=0; i < 8; i++)
|
||||
{
|
||||
r1[i] = vi0[i]*vi1[i];
|
||||
}
|
||||
for (i=0; i < 8; i++)
|
||||
{
|
||||
pRes[i].real = r0[i] - r1[i];
|
||||
}
|
||||
|
||||
for (i=0; i < 8; i++)
|
||||
{
|
||||
r0[i] = vr0[i]*vi1[i];
|
||||
}
|
||||
for (i=0; i < 8; i++)
|
||||
{
|
||||
r1[i] = vi0[i]*vr1[i];
|
||||
}
|
||||
for (i=0; i < 8; i++)
|
||||
{
|
||||
pRes[i].imag = r0[i] + r1[i];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void CpxMulAddB8(cpx_t *pV1, cpx_t *pV2, cpx_t *pRes)
|
||||
{
|
||||
uint32_t i;
|
||||
radio_float_t r0[8];
|
||||
radio_float_t r1[8];
|
||||
|
||||
radio_float_t vr0[8];
|
||||
radio_float_t vr1[8];
|
||||
radio_float_t vi0[8];
|
||||
radio_float_t vi1[8];
|
||||
|
||||
for (i=0; i < 8; i++)
|
||||
{
|
||||
vr0[i] = pV1[i].real;
|
||||
vr1[i] = pV2[i].real;
|
||||
vi0[i] = pV1[i].imag;
|
||||
vi1[i] = pV2[i].imag;
|
||||
}
|
||||
|
||||
for (i=0; i < 8; i++)
|
||||
{
|
||||
r0[i] = vr0[i]*vr1[i];
|
||||
}
|
||||
for (i=0; i < 8; i++)
|
||||
{
|
||||
r1[i] = vi0[i]*vi1[i];
|
||||
}
|
||||
for (i=0; i < 8; i++)
|
||||
{
|
||||
r0[i] -= r1[i];
|
||||
}
|
||||
for (i=0; i < 8; i++)
|
||||
{
|
||||
pRes->real += r0[i];
|
||||
}
|
||||
|
||||
for (i=0; i < 8; i++)
|
||||
{
|
||||
r0[i] = vr0[i]*vi1[i];
|
||||
}
|
||||
for (i=0; i < 8; i++)
|
||||
{
|
||||
r1[i] = vi0[i]*vr1[i];
|
||||
}
|
||||
for (i=0; i < 8; i++)
|
||||
{
|
||||
r0[i] += r1[i];
|
||||
}
|
||||
for (i=0; i < 8; i++)
|
||||
{
|
||||
pRes->imag += r0[i];
|
||||
}
|
||||
|
||||
}
|
||||
void CpxScaleB8(cpx_t *v1, cpx_t v2, cpx_t *pRes)
|
||||
{
|
||||
uint32_t i;
|
||||
radio_float_t r0[8];
|
||||
radio_float_t r1[8];
|
||||
|
||||
radio_float_t vr0[8];
|
||||
radio_float_t vi0[8];
|
||||
|
||||
for (i=0; i < 8; i++)
|
||||
{
|
||||
vr0[i] = v1[i].real;
|
||||
vi0[i] = v1[i].imag;
|
||||
}
|
||||
|
||||
for (i=0; i < 8; i++)
|
||||
{
|
||||
r0[i] = vr0[i]*v2.real;
|
||||
}
|
||||
for (i=0; i < 8; i++)
|
||||
{
|
||||
r1[i] = vi0[i]*v2.imag;
|
||||
}
|
||||
for (i=0; i < 8; i++)
|
||||
{
|
||||
r0[i] -= r1[i];
|
||||
}
|
||||
for (i=0; i < 8; i++)
|
||||
{
|
||||
pRes[i].real = r0[i];
|
||||
}
|
||||
|
||||
for (i=0; i < 8; i++)
|
||||
{
|
||||
r0[i] = vr0[i]*v2.imag;
|
||||
}
|
||||
for (i=0; i < 8; i++)
|
||||
{
|
||||
r1[i] = vi0[i]*v2.real;
|
||||
}
|
||||
for (i=0; i < 8; i++)
|
||||
{
|
||||
r0[i] += r1[i];
|
||||
}
|
||||
for (i=0; i < 8; i++)
|
||||
{
|
||||
pRes[i].imag = r0[i];
|
||||
}
|
||||
}
|
||||
|
||||
void CpxMulRealB8(cpx_t *v1, radio_float_t *v2, cpx_t *pRes)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
radio_float_t r0[8];
|
||||
radio_float_t i0[8];
|
||||
|
||||
radio_float_t vr0[8];
|
||||
radio_float_t vi0[8];
|
||||
|
||||
for (i=0; i < 8; i++)
|
||||
{
|
||||
vr0[i] = v1[i].real;
|
||||
vi0[i] = v1[i].imag;
|
||||
}
|
||||
|
||||
for (i=0; i < 8; i++)
|
||||
{
|
||||
r0[i] = vr0[i]*v2[i];
|
||||
i0[i] = vi0[i]*v2[i];
|
||||
}
|
||||
for (i=0; i < 8; i++)
|
||||
{
|
||||
pRes[i].real = r0[i];
|
||||
pRes[i].imag = i0[i];
|
||||
}
|
||||
}
|
||||
|
||||
void CpxMulRealAddB8(cpx_t *v1, radio_float_t *v2, cpx_t *pRes)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
radio_float_t r0[8];
|
||||
radio_float_t i0[8];
|
||||
|
||||
radio_float_t vr0[8];
|
||||
radio_float_t vi0[8];
|
||||
|
||||
for (i=0; i < 8; i++)
|
||||
{
|
||||
vr0[i] = v1[i].real;
|
||||
vi0[i] = v1[i].imag;
|
||||
}
|
||||
|
||||
for (i=0; i < 8; i++)
|
||||
{
|
||||
r0[i] = vr0[i]*v2[i];
|
||||
i0[i] = vi0[i]*v2[i];
|
||||
}
|
||||
for (i=0; i < 8; i++)
|
||||
{
|
||||
pRes->real += r0[i];
|
||||
pRes->imag += i0[i];
|
||||
}
|
||||
}
|
||||
|
||||
void CpxAccumB8(cpx_t *pV1, cpx_t *pRes)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
radio_float_t vr0[8];
|
||||
radio_float_t vi0[8];
|
||||
|
||||
for (i=0; i < 8; i++)
|
||||
{
|
||||
vr0[i] = pV1[i].real;
|
||||
vi0[i] = pV1[i].imag;
|
||||
}
|
||||
|
||||
for (i=0; i < 8; i++)
|
||||
{
|
||||
pRes->real += vr0[i];
|
||||
pRes->imag += vi0[i];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
cpx_t CpxMulAdd(cpx_t sum, cpx_t *pSrc1, cpx_t *pSrc2, uint32_t len)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
for (i=0; i < (len-8); i += 8)
|
||||
{
|
||||
CpxMulAddB8(&pSrc1[i], &pSrc2[i], &sum);
|
||||
}
|
||||
|
||||
for (i=i; i < len; i++)
|
||||
{
|
||||
sum = CpxAddS(sum, CpxMulS(pSrc1[i], pSrc2[i]));
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
cpx_t CpxMulRealAdd(cpx_t sum, cpx_t *pSrc1, radio_float_t *pSrc2, uint32_t len)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
for (i=0; i < (len-8); i += 8)
|
||||
{
|
||||
CpxMulRealAddB8(&pSrc1[i], &pSrc2[i], &sum);
|
||||
}
|
||||
|
||||
for (i=i; i < len; i++)
|
||||
{
|
||||
sum = CpxAddS(sum, CpxScaleRealS(pSrc1[i], pSrc2[i]));
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
void CpxMul(cpx_t *pSrc1, cpx_t *pSrc2, cpx_t *pDst, uint32_t len)
|
||||
{
|
||||
|
||||
uint32_t i;
|
||||
|
||||
for (i=0; i < (len-8); i += 8)
|
||||
{
|
||||
CpxMulB8(&pSrc1[i], &pSrc2[i], &pDst[i]);
|
||||
}
|
||||
|
||||
for (i=i; i < len; i++)
|
||||
{
|
||||
pDst[i] = CpxMulS(pSrc1[i], pSrc2[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void CpxScale(cpx_t *pSrc1, cpx_t src2, cpx_t *pDst, uint32_t len)
|
||||
{
|
||||
|
||||
uint32_t i;
|
||||
|
||||
for (i=0; i < (len-8); i += 8)
|
||||
{
|
||||
CpxScaleB8(&pSrc1[i], src2, &pDst[i]);
|
||||
}
|
||||
|
||||
for (i=i; i < len; i++)
|
||||
{
|
||||
pDst[i] = CpxMulS(pSrc1[i], src2);
|
||||
}
|
||||
}
|
||||
|
||||
cpx_t csum(cpx_t *pSrc, int len)
|
||||
{
|
||||
cpx_t sum = Cpx(0,0);
|
||||
|
||||
while(len--)
|
||||
{
|
||||
sum.real += (*(pSrc)).real;
|
||||
sum.imag += (*(pSrc++)).imag;
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
cpx_t cmean(cpx_t *pSrc, int len)
|
||||
{
|
||||
cpx_t y;
|
||||
|
||||
y = csum(pSrc, len);
|
||||
y.real /= len;
|
||||
y.imag /= len;
|
||||
|
||||
return y;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------
|
||||
#include <xmmintrin.h>
|
||||
|
||||
void _cpxMulB4
|
||||
(
|
||||
radio_float_t pV1_real[_cpxMulB4_blockSize], radio_float_t pV1_imag[_cpxMulB4_blockSize],
|
||||
radio_float_t pV2_real[_cpxMulB4_blockSize], radio_float_t pV2_imag[_cpxMulB4_blockSize],
|
||||
radio_float_t pRes_real[_cpxMulB4_blockSize], radio_float_t pRes_imag[_cpxMulB4_blockSize])
|
||||
{
|
||||
uint32_t i;
|
||||
radio_float_t r0[_cpxMulB4_blockSize];
|
||||
radio_float_t r1[_cpxMulB4_blockSize];
|
||||
radio_float_t r2[_cpxMulB4_blockSize];
|
||||
radio_float_t r3[_cpxMulB4_blockSize];
|
||||
|
||||
for (i=0; i < _cpxMulB4_blockSize; i++)
|
||||
{
|
||||
r0[i] = pV1_real[i]*pV2_real[i];
|
||||
}
|
||||
for (i=0; i < _cpxMulB4_blockSize; i++)
|
||||
{
|
||||
r1[i] = pV1_imag[i]*pV2_imag[i];
|
||||
}
|
||||
for (i=0; i < _cpxMulB4_blockSize; i++)
|
||||
{
|
||||
r2[i] = pV1_real[i]*pV2_imag[i];
|
||||
}
|
||||
for (i=0; i < _cpxMulB4_blockSize; i++)
|
||||
{
|
||||
r3[i] = pV1_imag[i]*pV2_real[i];
|
||||
}
|
||||
for (i=0; i < _cpxMulB4_blockSize; i++)
|
||||
{
|
||||
pRes_real[i] = r0[i] - r1[i];
|
||||
}
|
||||
for (i=0; i < _cpxMulB4_blockSize; i++)
|
||||
{
|
||||
pRes_imag[i] = r2[i] + r3[i];
|
||||
}
|
||||
}
|
||||
|
||||
void _cpxMulB1
|
||||
(
|
||||
radio_float_t *pV1_real, radio_float_t *pV1_imag,
|
||||
radio_float_t *pV2_real, radio_float_t *pV2_imag,
|
||||
radio_float_t *pRes_real, radio_float_t *pRes_imag)
|
||||
{
|
||||
|
||||
uint32_t i;
|
||||
radio_float_t r0[_cpxMulB1_blockSize];
|
||||
radio_float_t r1[_cpxMulB1_blockSize];
|
||||
radio_float_t r2[_cpxMulB1_blockSize];
|
||||
radio_float_t r3[_cpxMulB1_blockSize];
|
||||
|
||||
for (i=0; i < _cpxMulB1_blockSize; i++)
|
||||
{
|
||||
r0[i] = pV1_real[i]*pV2_real[i];
|
||||
}
|
||||
for (i=0; i < _cpxMulB1_blockSize; i++)
|
||||
{
|
||||
r1[i] = pV1_imag[i]*pV2_imag[i];
|
||||
}
|
||||
for (i=0; i < _cpxMulB1_blockSize; i++)
|
||||
{
|
||||
r2[i] = pV1_real[i]*pV2_imag[i];
|
||||
}
|
||||
for (i=0; i < _cpxMulB1_blockSize; i++)
|
||||
{
|
||||
r3[i] = pV1_imag[i]*pV2_real[i];
|
||||
}
|
||||
for (i=0; i < _cpxMulB1_blockSize; i++)
|
||||
{
|
||||
pRes_real[i] = r0[i] - r1[i];
|
||||
}
|
||||
for (i=0; i < _cpxMulB1_blockSize; i++)
|
||||
{
|
||||
pRes_imag[i] = r2[i] + r3[i];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
// --------------------------------------------------------------
|
||||
#ifndef CPX_H
|
||||
#define CPX_H
|
||||
|
||||
#include "radio_types.h"
|
||||
// --------------------------------------------------------------
|
||||
// Types
|
||||
// --------------------------------------------------------------
|
||||
typedef struct _cpx_t
|
||||
{
|
||||
radio_float_t imag, real;
|
||||
|
||||
} cpx_t;
|
||||
|
||||
typedef struct _cpx_arr_t
|
||||
{
|
||||
uint32_t size;
|
||||
radio_float_t *imag, *real;
|
||||
|
||||
} cpx_arr_t;
|
||||
|
||||
// --------------------------------------------------------------
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// Complex Functions
|
||||
// --------------------------------------------------------------
|
||||
// Scalar
|
||||
cpx_t CpxConjS(cpx_t v1);
|
||||
cpx_t CpxAddS(cpx_t v1, cpx_t v2);
|
||||
cpx_t CpxSubS(cpx_t v1, cpx_t v2);
|
||||
cpx_t CpxMulS(cpx_t v1, cpx_t v2);
|
||||
cpx_t CpxScaleRealS(cpx_t v1, radio_float_t v2);
|
||||
cpx_t CpxScaleComplexS(cpx_t x, cpx_t gain);
|
||||
cpx_t CpxFromReal(radio_float_t v1);
|
||||
cpx_t Cpx(radio_float_t real, radio_float_t imag);
|
||||
cpx_t CpxMinS(cpx_t x1, cpx_t x2);
|
||||
cpx_t CpxMaxS(cpx_t x1, cpx_t x2);
|
||||
radio_float_t CpxMagS(cpx_t v1);
|
||||
radio_float_t CpxPhiS(cpx_t v1);
|
||||
radio_float_t cpxPowerDB(cpx_t v1, radio_float_t preScale);
|
||||
|
||||
// Vector
|
||||
void CpxCopy(cpx_t *pSrc, cpx_t *pDst, uint32_t len);
|
||||
void CpxConj(cpx_t *pSrcDst, uint32_t len);
|
||||
void CpxAdd(cpx_t *pSrc, cpx_t *pSrcDst, uint32_t len);
|
||||
void CpxSub(cpx_t *pSrc, cpx_t *pSrcDst, uint32_t len);
|
||||
void CpxMul(cpx_t *pSrc1, cpx_t *pSrc2, cpx_t *pDst, uint32_t len);
|
||||
void CpxScale(cpx_t *pSrc1, cpx_t src2, cpx_t *pDst, uint32_t len);
|
||||
cpx_t CpxMulAdd(cpx_t sum, cpx_t *pSrc1, cpx_t *pSrc2, uint32_t len);
|
||||
cpx_t CpxMulRealAdd(cpx_t sum, cpx_t *pSrc1, radio_float_t *pSrc2, uint32_t len);
|
||||
radio_float_t CpxMag(cpx_t *pSrc);
|
||||
radio_float_t CpxPhi(cpx_t *pSrc);
|
||||
|
||||
cpx_t csum(cpx_t *pSrc, int len);
|
||||
cpx_t cmean(cpx_t *pSrc, int len);
|
||||
|
||||
// --------------------------------------------------------------
|
||||
#define _cpxMulB4_blockSize 4
|
||||
#define _cpxMulB1_blockSize 1
|
||||
void _cpxMulB4
|
||||
(
|
||||
radio_float_t pV1_real[_cpxMulB4_blockSize], radio_float_t pV1_imag[_cpxMulB4_blockSize],
|
||||
radio_float_t pV2_real[_cpxMulB4_blockSize], radio_float_t pV2_imag[_cpxMulB4_blockSize],
|
||||
radio_float_t pRes_real[_cpxMulB4_blockSize], radio_float_t pRes_imag[_cpxMulB4_blockSize]
|
||||
);
|
||||
void _cpxMulB1
|
||||
(
|
||||
radio_float_t *pV1_real, radio_float_t *pV1_imag,
|
||||
radio_float_t *pV2_real, radio_float_t *pV2_imag,
|
||||
radio_float_t *pRes_real, radio_float_t *pRes_imag
|
||||
);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif // __cplusplus
|
||||
|
||||
// --------------------------------------------------------------
|
||||
#endif // CPX_H
|
||||
Executable
+498
@@ -0,0 +1,498 @@
|
||||
// --------------------------------------------------------------
|
||||
#include <string.h>
|
||||
#include <malloc.h>
|
||||
#include <math.h>
|
||||
#include "equalizer.h"
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// Helpers
|
||||
// --------------------------------------------------------------
|
||||
void CoeffComplexUnitAt(cpx_t *pW, uint32_t N, uint32_t dly)
|
||||
{
|
||||
if (dly >= N)
|
||||
dly = 0;
|
||||
|
||||
memset(pW, 0, N*sizeof(cpx_t));
|
||||
pW[dly].real = 1.0;
|
||||
pW[dly].imag = 0.0;
|
||||
}
|
||||
|
||||
void CoeffComplexConv(cpx_t *pSrc, cpx_t *pSrcDst, uint32_t N, uint32_t dly)
|
||||
{
|
||||
uint32_t i, j, N2;
|
||||
cpx_t *pX, *pW, t, energy = {0};
|
||||
radio_float_t energy_correct;
|
||||
|
||||
N2 = N+dly;
|
||||
|
||||
pX = (cpx_t*)malloc(N2*sizeof(cpx_t));
|
||||
memset(pX, 0, N2*sizeof(cpx_t));
|
||||
pW = (cpx_t*)malloc(N2*sizeof(cpx_t));
|
||||
memset(pW, 0, N2*sizeof(cpx_t));
|
||||
|
||||
CpxCopy(pSrc, pX, N);
|
||||
|
||||
for(j=0; j < N; j++)
|
||||
energy = CpxAddS(energy, pSrcDst[j]);
|
||||
|
||||
energy_correct = (radio_float_t)(1.0/CpxMagS(energy));
|
||||
|
||||
for(i=0; i < N2; i++)
|
||||
{
|
||||
for(j=0; j < N; j++)
|
||||
{
|
||||
t = CpxMulS(pX[N-j+i-1], pSrcDst[j]);
|
||||
pW[i] = CpxScaleRealS(CpxAddS(pW[i], t), energy_correct);
|
||||
}
|
||||
}
|
||||
CpxCopy(&pW[N/2], pSrcDst, N);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// Equalizer
|
||||
// --------------------------------------------------------------
|
||||
void EQComplexInit(eq_cpx_t *pObj, uint32_t N)
|
||||
{
|
||||
pObj->N = N;
|
||||
pObj->pX = (cpx_t*)malloc(pObj->N*sizeof(cpx_t));
|
||||
pObj->pW = (cpx_t*)malloc(pObj->N*sizeof(cpx_t));
|
||||
pObj->pW_conj = (cpx_t*)malloc(pObj->N*sizeof(cpx_t));
|
||||
memset(pObj->pX, 0, pObj->N*sizeof(cpx_t));
|
||||
memset(pObj->pW, 0, pObj->N*sizeof(cpx_t));
|
||||
memset(pObj->pW_conj, 0, pObj->N*sizeof(cpx_t));
|
||||
}
|
||||
|
||||
void EQComplexFree(eq_cpx_t *pObj)
|
||||
{
|
||||
free(pObj->pX);
|
||||
free(pObj->pW);
|
||||
free(pObj->pW_conj);
|
||||
}
|
||||
|
||||
cpx_t EQComplexProcess(eq_cpx_t *pObj, cpx_t x)
|
||||
{
|
||||
uint32_t i;
|
||||
cpx_t y;
|
||||
|
||||
for(i=pObj->N-1; (int)i > 0; i--)
|
||||
{
|
||||
pObj->pX[i] = pObj->pX[i-1];
|
||||
}
|
||||
|
||||
// fill M top positions with M new data
|
||||
pObj->pX[i] = x;
|
||||
|
||||
y = CpxMulAdd(Cpx(0, 0), pObj->pX, pObj->pW_conj, pObj->N);
|
||||
|
||||
return y;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// CMA
|
||||
// --------------------------------------------------------------
|
||||
void CMAInit(cma_t *pObj, uint32_t ntaps)
|
||||
{
|
||||
pObj->N = ntaps;
|
||||
pObj->Px = 0;
|
||||
pObj->Px_last = 0;
|
||||
|
||||
EQComplexInit(&pObj->eq, pObj->N);
|
||||
}
|
||||
|
||||
void CMAFree(cma_t *pObj)
|
||||
{
|
||||
EQComplexFree(&pObj->eq);
|
||||
}
|
||||
|
||||
cpx_t CMAProcess(cma_t *pObj, cpx_t x)
|
||||
{
|
||||
cpx_t y;
|
||||
radio_float_t x2, x1;
|
||||
|
||||
y = EQComplexProcess(&pObj->eq, x);
|
||||
x1 = CpxMagS(x);
|
||||
x2 = CpxMagS(pObj->eq.pX[pObj->eq.N-1]);
|
||||
|
||||
pObj->Px = dmax(0, pObj->Px + (x1*x1 - pObj->Px_last));
|
||||
pObj->Px_last = x2*x2;
|
||||
|
||||
return y;
|
||||
}
|
||||
|
||||
// Proakis: page 698
|
||||
void CMATrainGodard(cma_t *pObj, cpx_t sym_s_eq, radio_float_t mag_h, radio_float_t R2, radio_float_t mu)
|
||||
{
|
||||
cpx_t d;
|
||||
cpx_t e;
|
||||
radio_float_t mag_s, t;
|
||||
|
||||
mag_s = CpxMagS(sym_s_eq);
|
||||
|
||||
t = (radio_float_t)((mag_h + R2*mag_s - mag_s*mag_s*mag_s)/(1E-4+mag_h));
|
||||
d = CpxScaleRealS(sym_s_eq, t);
|
||||
|
||||
e = CpxSubS(d, sym_s_eq);
|
||||
|
||||
LMSUpdateWeigths(&pObj->eq, e, mu/((radio_float_t)1+pObj->Px));
|
||||
}
|
||||
|
||||
// "Sliced Multi-modulus Blind Equalization Algorithm",
|
||||
// ETRI Journal, Volume 27, Number 3, June 2005,
|
||||
// Shafayat Abrar and Roy A. Axford Jr.
|
||||
void MMATrain(cma_t *pObj, cpx_t sym_s_eq, cpx_t R, radio_float_t mu)
|
||||
{
|
||||
cpx_t e;
|
||||
|
||||
e.real = sym_s_eq.real*(R.real - sym_s_eq.real*sym_s_eq.real);
|
||||
e.imag = sym_s_eq.imag*(R.imag - sym_s_eq.imag*sym_s_eq.imag);
|
||||
|
||||
LMSUpdateWeigths(&pObj->eq, e, mu/((radio_float_t)1+pObj->Px));
|
||||
}
|
||||
|
||||
// "Sliced Multi-modulus Blind Equalization Algorithm",
|
||||
// ETRI Journal, Volume 27, Number 3, June 2005,
|
||||
// Shafayat Abrar and Roy A. Axford Jr.
|
||||
void SMMATrain(cma_t *pObj, cpx_t sym_s_eq, radio_float_t mag_h, cpx_t R, radio_float_t mu)
|
||||
{
|
||||
cpx_t e;
|
||||
|
||||
e.real = sym_s_eq.real*(mag_h*R.real - sym_s_eq.real*sym_s_eq.real);
|
||||
e.imag = sym_s_eq.imag*(mag_h*R.imag - sym_s_eq.imag*sym_s_eq.imag);
|
||||
|
||||
LMSUpdateWeigths(&pObj->eq, e, mu/((radio_float_t)1+pObj->Px));
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// DFE
|
||||
// --------------------------------------------------------------
|
||||
void DFEComplexInit(dfe_cpx_t *pObj, uint32_t K)
|
||||
{
|
||||
pObj->N = 2*K+1;
|
||||
pObj->N_ff = K+1;
|
||||
pObj->N_fb = K;
|
||||
|
||||
EQComplexInit(&pObj->eq, pObj->N);
|
||||
|
||||
}
|
||||
|
||||
void DFEComplexFree(dfe_cpx_t *pObj)
|
||||
{
|
||||
EQComplexFree(&pObj->eq);
|
||||
}
|
||||
|
||||
cpx_t DFEComplexProcess(dfe_cpx_t *pObj, cpx_t xs, cpx_t xh)
|
||||
{
|
||||
int32_t i;
|
||||
cpx_t y, *pW_conj, *pX;
|
||||
|
||||
pX = pObj->eq.pX;
|
||||
pW_conj = pObj->eq.pW_conj;
|
||||
|
||||
// Shift Feedback part
|
||||
for(i=pObj->N-1; i > (int32_t)pObj->N_ff; i--)
|
||||
{
|
||||
pX[i] = pX[i-1];
|
||||
}
|
||||
|
||||
// put last x into buffer
|
||||
pX[i] = xh;
|
||||
|
||||
// Shift Feed forward part
|
||||
for(i=pObj->N_ff-1; i > 0; i--)
|
||||
{
|
||||
pX[i] = pX[i-1];
|
||||
}
|
||||
|
||||
// put current x into buffer
|
||||
pX[i] = xs;
|
||||
|
||||
y = CpxMulAdd(Cpx(0, 0), pX, pW_conj, pObj->N);
|
||||
|
||||
return y;
|
||||
|
||||
}
|
||||
|
||||
void DFEAdaptLMS(dfe_cpx_t *pObj, cpx_t e, radio_float_t mu)
|
||||
{
|
||||
LMSUpdateWeigths(&pObj->eq, e, mu);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// LMS
|
||||
// --------------------------------------------------------------
|
||||
void LMSUpdateWeigths(eq_cpx_t *pObj, cpx_t e, radio_float_t mu)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
e = CpxScaleRealS(CpxConjS(e), mu);
|
||||
|
||||
CpxScale(pObj->pX, e, pObj->pW_conj, pObj->N);
|
||||
CpxAdd(pObj->pW_conj, pObj->pW, pObj->N);
|
||||
|
||||
for(i=0; i < pObj->N; i++)
|
||||
{
|
||||
pObj->pW_conj[i] = CpxConjS(pObj->pW[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// RLS
|
||||
// --------------------------------------------------------------
|
||||
void RLSInit(rls_t *pObj, uint32_t N, uint32_t M)
|
||||
{
|
||||
uint32_t i, j;
|
||||
radio_float_t *pR;
|
||||
|
||||
pObj->w = (radio_float_t*)malloc(N*sizeof(radio_float_t));
|
||||
memset(pObj->w, 0, N*sizeof(radio_float_t));
|
||||
pObj->w[0] = 1.0f;
|
||||
|
||||
pObj->pW = (cpx_t*)malloc(N*sizeof(cpx_t));
|
||||
memset(pObj->pW, 0, N*sizeof(cpx_t));
|
||||
|
||||
pObj->z = (radio_float_t*)malloc(N*sizeof(radio_float_t));
|
||||
memset(pObj->z, 0, N*sizeof(radio_float_t));
|
||||
|
||||
pObj->x = (radio_float_t*)malloc(N*sizeof(radio_float_t));
|
||||
memset(pObj->x, 0, N*sizeof(radio_float_t));
|
||||
|
||||
pObj->pX = (cpx_t*)malloc(N*M*sizeof(cpx_t));
|
||||
memset(pObj->pX, 0, N*M*sizeof(cpx_t));
|
||||
|
||||
pObj->R = (radio_float_t*)malloc(N*N*sizeof(radio_float_t));
|
||||
memset(pObj->R, 0, N*N*sizeof(radio_float_t));
|
||||
|
||||
pObj->T = (radio_float_t*)malloc(N*N*sizeof(radio_float_t));
|
||||
memset(pObj->T, 0, N*N*sizeof(radio_float_t));
|
||||
|
||||
pObj->T2 = (radio_float_t*)malloc(N*N*sizeof(radio_float_t));
|
||||
memset(pObj->T2, 0, N*N*sizeof(radio_float_t));
|
||||
|
||||
pR = pObj->R;
|
||||
for(i=0; i < N; i++)
|
||||
for(j=0; j < N; j++)
|
||||
pR[i+j*N] = (radio_float_t)1E6*(i==j);
|
||||
|
||||
pObj->N = N;
|
||||
pObj->M = M;
|
||||
}
|
||||
|
||||
void RLSFree(rls_t *pObj)
|
||||
{
|
||||
if(pObj->w)
|
||||
free(pObj->w);
|
||||
|
||||
if(pObj->z)
|
||||
free(pObj->z);
|
||||
|
||||
if(pObj->x)
|
||||
free(pObj->x);
|
||||
|
||||
if(pObj->R)
|
||||
free(pObj->R);
|
||||
|
||||
if(pObj->T)
|
||||
free(pObj->T);
|
||||
|
||||
if(pObj->T2)
|
||||
free(pObj->T2);
|
||||
}
|
||||
/*
|
||||
void RLSProcess(rls_t *pObj, radio_float_t rho, radio_float_t mu, radio_float_t x, radio_float_t d, radio_float_t *pE, radio_float_t *pDD)
|
||||
{
|
||||
int i, j, k, N;
|
||||
radio_float_t *pR, *pX, *pZ, *pT, *pT2, v, t, rho_i;
|
||||
|
||||
N = pObj->N;
|
||||
|
||||
FIR(pObj->w, pObj->x, N, &x, pDD, 1);
|
||||
|
||||
*pE = d - *pDD;
|
||||
|
||||
// Whitening
|
||||
pR = pObj->R;
|
||||
pX = pObj->x;
|
||||
for(i=0; i < N; i++)
|
||||
{
|
||||
t = 0;
|
||||
for(j=0; j < N; j++)
|
||||
t += pR[j*N+i] * pX[j];
|
||||
|
||||
pObj->z[i] = t;
|
||||
}
|
||||
|
||||
// Berechnunng der Normierungskonstante
|
||||
v = rho;
|
||||
for(i=0; i < N; i++)
|
||||
v += pObj->x[i] * pObj->z[i];
|
||||
|
||||
v = (radio_float_t)1.0/v;
|
||||
|
||||
// Normierung
|
||||
for(i=0; i < N; i++)
|
||||
pObj->z[i] *= v;
|
||||
|
||||
|
||||
// Filter update
|
||||
for(i=0; i < N; i++)
|
||||
pObj->w[i] += (mu * (*pE)*pObj->z[i]);
|
||||
|
||||
|
||||
// Matrix update
|
||||
pZ = pObj->z;
|
||||
pX = pObj->x;
|
||||
pT = pObj->T;
|
||||
for(i=0; i < N; i++)
|
||||
{
|
||||
for(j=0; j < N; j++)
|
||||
pT[j*N+i] = pZ[i] * pX[j];
|
||||
}
|
||||
|
||||
pT = pObj->T;
|
||||
pT2 = pObj->T2;
|
||||
pR = pObj->R;
|
||||
|
||||
for (i=0;i<N;i++)
|
||||
{
|
||||
for (j=0;j<N;j++)
|
||||
{
|
||||
pT2[j*N+i] = 0;
|
||||
for (k=0;k<N;k++)
|
||||
{
|
||||
pT2[j*N+i] += pT[k*N+i] * pR[j*N+k];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(i=0; i < N*N; i++)
|
||||
pR[i] -= pT2[i];
|
||||
|
||||
rho_i = (radio_float_t)1.0/rho;
|
||||
for(i=0; i < N*N; i++)
|
||||
pR[i] *= rho_i;
|
||||
}
|
||||
*/
|
||||
cpx_t RLSProcess(rls_t *pObj, radio_float_t i, radio_float_t q)
|
||||
{
|
||||
uint32_t j;
|
||||
cpx_t y, t;
|
||||
|
||||
y.real = 0;
|
||||
y.imag = 0;
|
||||
for(j=pObj->N-1; j != 0; j--)
|
||||
{
|
||||
pObj->pX[j] = pObj->pX[j-1];
|
||||
}
|
||||
pObj->pX[j].real = i;
|
||||
pObj->pX[j].imag = q;
|
||||
|
||||
for(j=0; j < pObj->N; j++)
|
||||
{
|
||||
pObj->pW[j].real = pObj->w[j];
|
||||
pObj->pW[j].imag = pObj->w[j];
|
||||
}
|
||||
|
||||
/// for(j=0; j < pObj->N; j++)
|
||||
// {
|
||||
// t = CpxMuls(pObj->pX[M*j], CpxConjs(pObj->pW[j]));
|
||||
// y = CpxAdds(y, t);
|
||||
// }
|
||||
|
||||
for(j=0; j < pObj->N; j++)
|
||||
{
|
||||
t.real = pObj->pX[j].real * pObj->pW[j].real;
|
||||
t.imag = pObj->pX[j].imag * pObj->pW[j].imag;
|
||||
|
||||
y = CpxAddS(y, t);
|
||||
}
|
||||
|
||||
for(j=0; j < pObj->N; j++)
|
||||
{
|
||||
pObj->x[j] = pObj->pX[j].real;
|
||||
}
|
||||
|
||||
return y;
|
||||
|
||||
}
|
||||
|
||||
radio_float_t RLSUpdate(rls_t *pObj, radio_float_t rho, radio_float_t mu, radio_float_t y, radio_float_t d)
|
||||
{
|
||||
int i, j, k, N;
|
||||
radio_float_t *pR, *pX, *pZ, *pT, *pT2, v, t, rho_i, e;
|
||||
|
||||
N = pObj->N;
|
||||
|
||||
e = d - y;
|
||||
|
||||
pR = pObj->R;
|
||||
pX = pObj->x;
|
||||
|
||||
// for(j=0; j < pObj->N; j++)
|
||||
// {
|
||||
// pObj->x[j] = pObj->pX[j*pObj->M].real;
|
||||
// }
|
||||
|
||||
// Whitening
|
||||
for(i=0; i < N; i++)
|
||||
{
|
||||
t = 0;
|
||||
for(j=0; j < N; j++)
|
||||
t += pR[j*N+i] * pX[j];
|
||||
|
||||
pObj->z[i] = t;
|
||||
}
|
||||
|
||||
// Berechnunng der Normierungskonstante
|
||||
v = rho;
|
||||
for(i=0; i < N; i++)
|
||||
v += pObj->x[i] * pObj->z[i];
|
||||
|
||||
v = (radio_float_t)1.0/v;
|
||||
|
||||
// Normierung
|
||||
for(i=0; i < N; i++)
|
||||
pObj->z[i] *= v;
|
||||
|
||||
|
||||
// Filter update
|
||||
for(i=0; i < N; i++)
|
||||
pObj->w[i] += (mu * e * pObj->z[i]);
|
||||
|
||||
|
||||
// Matrix update
|
||||
pZ = pObj->z;
|
||||
pX = pObj->x;
|
||||
pT = pObj->T;
|
||||
for(i=0; i < N; i++)
|
||||
{
|
||||
for(j=0; j < N; j++)
|
||||
pT[j*N+i] = pZ[i] * pX[j];
|
||||
}
|
||||
|
||||
pT = pObj->T;
|
||||
pT2 = pObj->T2;
|
||||
pR = pObj->R;
|
||||
|
||||
for (i=0;i<N;i++)
|
||||
{
|
||||
for (j=0;j<N;j++)
|
||||
{
|
||||
pT2[j*N+i] = 0;
|
||||
for (k=0;k<N;k++)
|
||||
{
|
||||
pT2[j*N+i] += pT[k*N+i] * pR[j*N+k];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(i=0; i < N*N; i++)
|
||||
pR[i] -= pT2[i];
|
||||
|
||||
rho_i = (radio_float_t)1.0/rho;
|
||||
for(i=0; i < N*N; i++)
|
||||
pR[i] *= rho_i;
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------
|
||||
Executable
+96
@@ -0,0 +1,96 @@
|
||||
// --------------------------------------------------------------
|
||||
#ifndef EQUALIZER_H
|
||||
#define EQUALIZER_H
|
||||
|
||||
#include "radio_types.h"
|
||||
#include "real.h"
|
||||
#include "cpx.h"
|
||||
|
||||
// --------------------------------------------------------------
|
||||
#define CEF_MODE_NOP 0
|
||||
#define CEF_MODE_CMA 1
|
||||
#define CEF_MODE_DD 2
|
||||
#define CEF_MODE_EQ_UPD 3
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// Types
|
||||
// --------------------------------------------------------------
|
||||
typedef struct _eq_cpx_t
|
||||
{
|
||||
uint32_t N;
|
||||
cpx_t *pX, *pW;
|
||||
cpx_t *pW_conj;
|
||||
|
||||
} eq_cpx_t;
|
||||
|
||||
typedef struct _cma_t
|
||||
{
|
||||
uint32_t N, M;
|
||||
eq_cpx_t eq;
|
||||
radio_float_t Px, Px_last;
|
||||
|
||||
} cma_t;
|
||||
|
||||
typedef struct _dfe_cpx_t
|
||||
{
|
||||
uint32_t N, N_ff, N_fb;
|
||||
eq_cpx_t eq;
|
||||
|
||||
} dfe_cpx_t;
|
||||
|
||||
typedef struct _rls_t
|
||||
{
|
||||
uint32_t N, M;
|
||||
cpx_t *pX, *pW, *pZ, *pR, *pT;
|
||||
radio_float_t *R, *T, *T2, *z, *w, *x;
|
||||
|
||||
} rls_t;
|
||||
|
||||
// --------------------------------------------------------------
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
// --------------------------------------------------------------
|
||||
// Functions
|
||||
// --------------------------------------------------------------
|
||||
// Helpers
|
||||
void CoeffComplexUnitAt(cpx_t *pW, uint32_t N, uint32_t dly);
|
||||
void CoeffComplexConv(cpx_t *pSrc, cpx_t *pDst, uint32_t N, uint32_t dly);
|
||||
|
||||
// General Equalizer
|
||||
void EQComplexInit(eq_cpx_t *pObj, uint32_t N);
|
||||
void EQComplexFree(eq_cpx_t *pObj);
|
||||
cpx_t EQComplexProcess(eq_cpx_t *pObj, cpx_t x);
|
||||
|
||||
// CMA Blind Adaption (uses EQComplex and LMSUpdate)
|
||||
void CMAInit(cma_t *pObj, uint32_t ntaps);
|
||||
void CMAFree(cma_t *pObj);
|
||||
cpx_t CMAProcess(cma_t *pObj, cpx_t x);
|
||||
void CMATrainGodard(cma_t *pObj, cpx_t sym_s_eq, radio_float_t mag_h, radio_float_t R2, radio_float_t mu);
|
||||
|
||||
// MMA
|
||||
void MMATrain(cma_t *pObj, cpx_t sym_s_eq, cpx_t R, radio_float_t mu);
|
||||
void SMMATrain(cma_t *pObj, cpx_t sym_s_eq, radio_float_t mag_h, cpx_t R, radio_float_t mu);
|
||||
|
||||
// DFE Decision Directed Adaption (uses EQComplex and LMSUpdate)
|
||||
void DFEComplexInit(dfe_cpx_t *pObj, uint32_t K);
|
||||
void DFEComplexFree(dfe_cpx_t *pObj);
|
||||
cpx_t DFEComplexProcess(dfe_cpx_t *pObj, cpx_t xs, cpx_t xh);
|
||||
void DFEAdaptLMS(dfe_cpx_t *pObj, cpx_t e, radio_float_t mu);
|
||||
|
||||
// LMS Adaption
|
||||
void LMSUpdateWeigths(eq_cpx_t *pObj, cpx_t e, radio_float_t mu);
|
||||
|
||||
// RLS Adaption
|
||||
void RLSInit(rls_t *pObj, uint32_t N, uint32_t M);
|
||||
void RLSFree(rls_t *pObj);
|
||||
cpx_t RLSProcess(rls_t *pObj, radio_float_t i, radio_float_t q);
|
||||
radio_float_t RLSUpdate(rls_t *pObj, radio_float_t rho, radio_float_t mu, radio_float_t y, radio_float_t d);
|
||||
|
||||
// --------------------------------------------------------------
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
// --------------------------------------------------------------
|
||||
#endif // EQUALIZER_H
|
||||
@@ -0,0 +1,356 @@
|
||||
// --------------------------------------------------------------
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <crc/crc.h>
|
||||
#include "symbol.h"
|
||||
#include "frame.h"
|
||||
|
||||
// --------------------------------------------------------------
|
||||
uint32_t Scramble(uint8_t *pSrcDst, uint32_t state, uint32_t poly, uint32_t len)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
while(len)
|
||||
{
|
||||
*pSrcDst ^= (uint8_t)state;
|
||||
pSrcDst++;
|
||||
len--;
|
||||
|
||||
for (i=0; i < 8; i++)
|
||||
{
|
||||
if (state & 0x0001)
|
||||
state = (state >> 1) ^ poly;
|
||||
else
|
||||
state = (state >> 1);
|
||||
}
|
||||
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
uint32_t FrameCalcNumStreamBytes(uint32_t len_raw)
|
||||
{
|
||||
uint32_t len, num_frames;
|
||||
num_frames = (uint32_t)ceil((float)len_raw / FRAME_NUM_BYTES_PER_FRAME);
|
||||
len = num_frames*sizeof(frame_t);
|
||||
|
||||
if (len < sizeof(frame_t))
|
||||
len = sizeof(frame_t);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
uint32_t FrameFormat(uint8_t *pRaw, uint8_t *pFormatted, uint32_t len_raw, uint32_t *pPrn_state, uint16_t frame_type)
|
||||
{
|
||||
frame_t frame;
|
||||
|
||||
uint32_t bytes_remain, len_formatted, len;
|
||||
uint32_t prn_state;
|
||||
|
||||
if (len_raw == 0)
|
||||
return 0;
|
||||
|
||||
prn_state = *pPrn_state;
|
||||
|
||||
// Set preamble
|
||||
frame.hdr.preamble[0] = FRAME_PREAMBLE_IV;
|
||||
frame.hdr.preamble[1] = ~(frame.hdr.preamble[0]);
|
||||
|
||||
bytes_remain = len_raw;
|
||||
len_formatted = 0;
|
||||
while(bytes_remain)
|
||||
{
|
||||
len = FRAME_NUM_BYTES_PER_FRAME;
|
||||
if (bytes_remain < FRAME_NUM_BYTES_PER_FRAME)
|
||||
len = bytes_remain;
|
||||
|
||||
memset(frame.data, 0, FRAME_NUM_BYTES_PER_FRAME);
|
||||
memcpy(frame.data, pRaw, len);
|
||||
frame.hdr.crc16 = Crc16(FRAME_CRC16_POLY, FRAME_CRC16_IV, frame.data, FRAME_NUM_BYTES_PER_FRAME);
|
||||
frame.hdr.type = frame_type;
|
||||
frame.hdr.prn_state = prn_state;
|
||||
frame.hdr.length = (uint16_t)len;
|
||||
prn_state = Scramble(frame.data, prn_state, FRAME_SCRAMBLER_POLY, FRAME_NUM_BYTES_PER_FRAME);
|
||||
prn_state = Scramble((uint8_t*)&frame.hdr.crc16, prn_state, FRAME_SCRAMBLER_POLY, sizeof(frame.hdr.crc16));
|
||||
prn_state = Scramble((uint8_t*)&frame.hdr.type, prn_state, FRAME_SCRAMBLER_POLY, sizeof(frame.hdr.type));
|
||||
prn_state = Scramble((uint8_t*)&frame.hdr.length, prn_state, FRAME_SCRAMBLER_POLY, sizeof(frame.hdr.length));
|
||||
|
||||
pRaw += len;
|
||||
bytes_remain -= len;
|
||||
|
||||
memcpy(pFormatted, &frame, sizeof(frame_t));
|
||||
pFormatted += sizeof(frame_t);
|
||||
len_formatted += sizeof(frame_t);
|
||||
|
||||
}
|
||||
*pPrn_state = prn_state;
|
||||
return len_formatted;
|
||||
}
|
||||
|
||||
uint32_t FrameDeformat(uint8_t *pFormatted, uint8_t *pRaw, uint32_t len_formatted, uint16_t frame_type_mask)
|
||||
{
|
||||
frame_hdr_t hdr;
|
||||
uint32_t bytes_remain, len_raw, sync_state, frame_sync, i;
|
||||
uint16_t crc16_ist;
|
||||
uint8_t temp[FRAME_NUM_BYTES_PER_FRAME];
|
||||
uint32_t prn_state;
|
||||
|
||||
if (len_formatted == 0)
|
||||
return 0;
|
||||
|
||||
i = 0;
|
||||
bytes_remain = len_formatted;
|
||||
len_raw = 0;
|
||||
while(bytes_remain)
|
||||
{
|
||||
|
||||
sync_state = 0;
|
||||
do
|
||||
{
|
||||
// Find frame boundaries
|
||||
switch(sync_state)
|
||||
{
|
||||
case 0:
|
||||
if (pFormatted[i] == FRAME_PREAMBLE_IV)
|
||||
{
|
||||
sync_state = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 1:
|
||||
if ((uint8_t)(~pFormatted[i]) == pFormatted[i-1])
|
||||
{
|
||||
sync_state = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
sync_state = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
bytes_remain--;
|
||||
frame_sync = (sync_state == 2);
|
||||
|
||||
} while(bytes_remain && !frame_sync);
|
||||
|
||||
memcpy(&hdr, &pFormatted[i-2], sizeof(frame_hdr_t));
|
||||
memcpy(temp, &pFormatted[i-2+sizeof(frame_hdr_t)], FRAME_NUM_BYTES_PER_FRAME);
|
||||
|
||||
prn_state = Scramble(temp, hdr.prn_state, FRAME_SCRAMBLER_POLY, FRAME_NUM_BYTES_PER_FRAME);
|
||||
prn_state = Scramble((uint8_t*)&hdr.crc16, prn_state, FRAME_SCRAMBLER_POLY, sizeof(hdr.crc16));
|
||||
prn_state = Scramble((uint8_t*)&hdr.type, prn_state, FRAME_SCRAMBLER_POLY, sizeof(hdr.type));
|
||||
Scramble((uint8_t*)&hdr.length, prn_state, FRAME_SCRAMBLER_POLY, sizeof(hdr.length));
|
||||
|
||||
crc16_ist = Crc16(FRAME_CRC16_POLY, FRAME_CRC16_IV, temp, FRAME_NUM_BYTES_PER_FRAME);
|
||||
|
||||
if (crc16_ist == hdr.crc16)
|
||||
{
|
||||
|
||||
if ((hdr.type & frame_type_mask) == frame_type_mask)
|
||||
{
|
||||
memcpy(&pRaw[len_raw], temp, hdr.length);
|
||||
len_raw += hdr.length;
|
||||
}
|
||||
i += FRAME_NUM_BYTES_PER_FRAME + sizeof(frame_hdr_t) - 2;
|
||||
bytes_remain -= (FRAME_NUM_BYTES_PER_FRAME + sizeof(frame_hdr_t) - 2);
|
||||
}
|
||||
|
||||
if ((int32_t)bytes_remain < sizeof(frame_t))
|
||||
bytes_remain = 0;
|
||||
}
|
||||
return len_raw;
|
||||
}
|
||||
|
||||
// Transmission order MSB first
|
||||
uint32_t FrameSerialize(uint8_t *pSrc, uint8_t *pDst, uint32_t nBitsPerSym, uint32_t srclen)
|
||||
{
|
||||
|
||||
uint32_t bits_remain, i, j;
|
||||
uint8_t src, dst;
|
||||
|
||||
if (srclen == 0)
|
||||
return 0;
|
||||
|
||||
if (nBitsPerSym > 8)
|
||||
return (uint32_t)-1;
|
||||
|
||||
j = 0;
|
||||
src = *pSrc;
|
||||
bits_remain = 8;
|
||||
while(srclen)
|
||||
{
|
||||
dst = 0;
|
||||
for (i=0; i < nBitsPerSym; i++)
|
||||
{
|
||||
dst <<= 1;
|
||||
dst |= (0x01 & (src >> 7));
|
||||
src <<= 1;
|
||||
|
||||
bits_remain--;
|
||||
if (bits_remain == 0)
|
||||
{
|
||||
pSrc++;
|
||||
bits_remain = 8;
|
||||
src = *pSrc;
|
||||
srclen--;
|
||||
}
|
||||
|
||||
}
|
||||
pDst[j++] = dst;
|
||||
}
|
||||
return j;
|
||||
}
|
||||
|
||||
uint32_t FrameDeSerialize(uint8_t *pSrc, uint8_t *pDst, uint32_t nBitsPerSym, uint32_t srclen, uint16_t frame_type_mask)
|
||||
{
|
||||
|
||||
uint32_t size, err, bits_remain, i, j, byte_sync, srcRemain, bitStart, numCorrupt;
|
||||
uint8_t src, dst, *pBitStart;
|
||||
uint16_t dst16, t;
|
||||
uint8_t frame[sizeof(frame_t)], data[FRAME_NUM_BYTES_PER_FRAME];
|
||||
|
||||
if (srclen == 0)
|
||||
return 0;
|
||||
|
||||
if (nBitsPerSym > 8)
|
||||
return (uint32_t)-1;
|
||||
|
||||
src = *pSrc;
|
||||
|
||||
bits_remain = nBitsPerSym;
|
||||
bitStart = bits_remain;
|
||||
pBitStart = pSrc;
|
||||
numCorrupt = 0;
|
||||
|
||||
t = (FRAME_PREAMBLE_IV << 8) | (0xFF & ~FRAME_PREAMBLE_IV);
|
||||
size = 0;
|
||||
do
|
||||
{
|
||||
j = 0;
|
||||
dst16 = 0;
|
||||
byte_sync = 0;
|
||||
do
|
||||
{
|
||||
bits_remain--;
|
||||
dst16 <<= 1;
|
||||
dst16 |= (0x01 & (src >> (bits_remain)));
|
||||
|
||||
if (bits_remain == 0)
|
||||
{
|
||||
pSrc++;
|
||||
bits_remain = nBitsPerSym;
|
||||
src = *pSrc;
|
||||
srclen--;
|
||||
if (!srclen)
|
||||
break;
|
||||
}
|
||||
|
||||
// Find frame boundaries
|
||||
if (dst16 == t)
|
||||
{
|
||||
pBitStart = pSrc;
|
||||
bitStart = bits_remain;
|
||||
srcRemain = srclen;
|
||||
byte_sync = 1;
|
||||
frame[j++] = 0xFF & (t >> 8);
|
||||
frame[j++] = 0xFF & t;
|
||||
|
||||
}
|
||||
|
||||
} while(srclen && !byte_sync);
|
||||
if (!srclen)
|
||||
break;
|
||||
|
||||
for(j; j < sizeof(frame_t); j++)
|
||||
{
|
||||
dst = 0;
|
||||
for (i=0; i < 8; i++)
|
||||
{
|
||||
bits_remain--;
|
||||
dst <<= 1;
|
||||
dst |= (0x01 & (src >> (bits_remain)));
|
||||
|
||||
if (bits_remain == 0)
|
||||
{
|
||||
pSrc++;
|
||||
bits_remain = nBitsPerSym;
|
||||
src = *pSrc;
|
||||
srclen--;
|
||||
if (!srclen)
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
frame[j] = dst;
|
||||
if (!srclen)
|
||||
break;
|
||||
|
||||
}
|
||||
if (!srclen)
|
||||
break;
|
||||
|
||||
err = FrameDeformat(frame, data, sizeof(frame_t), frame_type_mask);
|
||||
if (err > 0)
|
||||
{
|
||||
memcpy(&pDst[size], frame, sizeof(frame_t));
|
||||
size += sizeof(frame_t);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if (size > 0)
|
||||
numCorrupt++;
|
||||
bits_remain = bitStart;
|
||||
pSrc = pBitStart;
|
||||
srclen = srcRemain;
|
||||
}
|
||||
|
||||
} while(srclen);
|
||||
|
||||
// printf("Number of corrupted frames = %d\n", numCorrupt);
|
||||
return size;
|
||||
}
|
||||
|
||||
// Differential M-PSK symbol mapping
|
||||
uint32_t FrameSymbolsMap(uint8_t *pBits, cpx_t *pSym, uint32_t nBitsPerSym, uint32_t num_syms, uint32_t type)
|
||||
{
|
||||
uint32_t i;
|
||||
sym_map_t sym_mapper;
|
||||
|
||||
if (num_syms == 0)
|
||||
return 0;
|
||||
|
||||
SymMapInit(&sym_mapper, nBitsPerSym, type);
|
||||
|
||||
for(i=0; i < num_syms; i++)
|
||||
{
|
||||
pSym[i] = SymMapEncode(&sym_mapper, pBits[i]);
|
||||
}
|
||||
|
||||
return num_syms;
|
||||
}
|
||||
|
||||
// Differential M-PSK symbol de-mapping
|
||||
uint32_t FrameSymbolsDemap(cpx_t *pSym, uint8_t *pBits, uint32_t nBitsPerSym, uint32_t num_syms, uint32_t type)
|
||||
{
|
||||
uint32_t i;
|
||||
sym_map_t sym_demapper;
|
||||
sym_err_t sym_err;
|
||||
|
||||
if (num_syms == 0)
|
||||
return 0;
|
||||
|
||||
memset(&sym_err, 0, sizeof(sym_err_t));
|
||||
|
||||
SymMapInit(&sym_demapper, nBitsPerSym, type);
|
||||
|
||||
for(i=0; i < num_syms; i++)
|
||||
{
|
||||
pBits[i] = SymMapDecode(&sym_demapper, pSym[i], &sym_err);
|
||||
}
|
||||
|
||||
return num_syms;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------
|
||||
@@ -0,0 +1,61 @@
|
||||
// --------------------------------------------------------------
|
||||
#ifndef FRAME_H
|
||||
#define FRAME_H
|
||||
|
||||
#include "radio_types.h"
|
||||
#include "cpx.h"
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// Constants
|
||||
// --------------------------------------------------------------
|
||||
#define FRAME_CRC16_IV 0x0000
|
||||
#define FRAME_CRC16_POLY 0x1021
|
||||
#define FRAME_PREAMBLE_IV 0x55
|
||||
#define FRAME_SCRAMBLER_SEED 0x12345678
|
||||
#define FRAME_SCRAMBLER_POLY 0x80C18601
|
||||
#define FRAME_NUM_BYTES_PER_FRAME 32
|
||||
#define FRAME_TYPE_IDLE 0x01
|
||||
#define FRAME_TYPE_DATA 0x02
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// Types
|
||||
// --------------------------------------------------------------
|
||||
typedef struct _frame_hdr_t
|
||||
{
|
||||
uint8_t preamble[2];
|
||||
uint32_t prn_state;
|
||||
uint16_t crc16;
|
||||
uint16_t type;
|
||||
uint16_t length;
|
||||
|
||||
} frame_hdr_t;
|
||||
|
||||
typedef struct _frame_t
|
||||
{
|
||||
frame_hdr_t hdr;
|
||||
uint8_t data[FRAME_NUM_BYTES_PER_FRAME];
|
||||
|
||||
} frame_t;
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// Functions
|
||||
// --------------------------------------------------------------
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
uint32_t Scramble(uint8_t *pSrcDst, uint32_t state, uint32_t poly, uint32_t len);
|
||||
uint32_t FrameCalcNumStreamBytes(uint32_t len_raw);
|
||||
uint32_t FrameFormat(uint8_t *pRaw, uint8_t *pFormatted, uint32_t len_raw, uint32_t *pPrn_state, uint16_t frame_type);
|
||||
uint32_t FrameDeformat(uint8_t *pFormatted, uint8_t *pRaw, uint32_t len_formatted, uint16_t frame_type);
|
||||
uint32_t FrameSerialize(uint8_t *pSrc, uint8_t *pDst, uint32_t nBitsPerSym, uint32_t srclen);
|
||||
uint32_t FrameDeSerialize(uint8_t *pSrc, uint8_t *pDst, uint32_t nBitsPerSym, uint32_t srclen, uint16_t frame_type);
|
||||
uint32_t FrameSymbolsMap(uint8_t *pBits, cpx_t *pSym, uint32_t nBitsPerSym, uint32_t num_syms, uint32_t type);
|
||||
uint32_t FrameSymbolsDemap(cpx_t *pSym, uint8_t *pBits, uint32_t nBitsPerSym, uint32_t num_syms, uint32_t type);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif // __cplusplus
|
||||
|
||||
// --------------------------------------------------------------
|
||||
#endif // FRAME_H
|
||||
Executable
+830
@@ -0,0 +1,830 @@
|
||||
// --------------------------------------------------------------
|
||||
#include <string.h>
|
||||
#include <malloc.h>
|
||||
#include <math.h>
|
||||
#include "interpolation.h"
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// Complex FIR filtering with downsampling
|
||||
// --------------------------------------------------------------
|
||||
void FirCpxInit(fir_cpx_t *pObj, uint32_t N, uint32_t M_up, uint32_t M_down)
|
||||
{
|
||||
pObj->pX = (cpx_t*)malloc(N*sizeof(cpx_t));
|
||||
memset(pObj->pX, 0, N*sizeof(cpx_t));
|
||||
pObj->N = N;
|
||||
pObj->M_up = M_up;
|
||||
pObj->M_down = M_down;
|
||||
pObj->r = 0;
|
||||
pObj->w = 0;
|
||||
ClockInit(&pObj->clockUp, M_up);
|
||||
ClockInit(&pObj->clockDown, M_down);
|
||||
}
|
||||
|
||||
void FirCpxFree(fir_cpx_t *pObj)
|
||||
{
|
||||
free(pObj->pX);
|
||||
}
|
||||
|
||||
uint32_t FirCpxProcessReal(fir_cpx_t *pObj, radio_float_t *pW, cpx_t *pSrc, cpx_t *pDst, uint32_t len)
|
||||
{
|
||||
|
||||
uint32_t j, w, r, N;
|
||||
uint32_t remain;
|
||||
uint32_t nBytesWritten;
|
||||
uint32_t nBytesRead;
|
||||
const cpx_t zero = Cpx(0,0);
|
||||
|
||||
w = pObj->w;
|
||||
r = pObj->r;
|
||||
N = pObj->N;
|
||||
|
||||
nBytesWritten = 0;
|
||||
nBytesRead = 0;
|
||||
remain = len*pObj->M_up;
|
||||
while(remain--)
|
||||
{
|
||||
if (ClockIsTick(&pObj->clockUp, 1))
|
||||
{
|
||||
pObj->pX[w] = pSrc[nBytesRead];
|
||||
nBytesRead++;
|
||||
}
|
||||
else
|
||||
{
|
||||
pObj->pX[w] = zero;
|
||||
}
|
||||
if (++w >= N)
|
||||
w = 0;
|
||||
|
||||
if (ClockIsTick(&pObj->clockDown, 1))
|
||||
{
|
||||
// fs/downSampleFactor
|
||||
pDst[nBytesWritten] = zero;
|
||||
for (j=0; j < N; j++)
|
||||
{
|
||||
|
||||
pDst[nBytesWritten].real += pObj->pX[r].real * pW[j];
|
||||
pDst[nBytesWritten].imag += pObj->pX[r].imag * pW[j];
|
||||
|
||||
if (--r >= N)
|
||||
r = N-1;
|
||||
|
||||
}
|
||||
nBytesWritten++;
|
||||
}
|
||||
if (++r >= N)
|
||||
r = 0;
|
||||
}
|
||||
pObj->r = r;
|
||||
pObj->w = w;
|
||||
|
||||
return nBytesWritten;
|
||||
}
|
||||
|
||||
void FirCpxMultirateStageDownInit(fir_cpx_multirate_stage_t *pObj, radio_float_t *pW, uint32_t N, uint32_t M, uint32_t k)
|
||||
{
|
||||
uint32_t i;
|
||||
radio_float_t *_pW;
|
||||
|
||||
pObj->N = 0;
|
||||
for (i=k; i < N; i += M)
|
||||
{
|
||||
pObj->N++;
|
||||
}
|
||||
pObj->pW = (radio_float_t*)malloc(pObj->N*sizeof(cpx_t));
|
||||
_pW = pObj->pW;
|
||||
for (i=k; i < N; i += M)
|
||||
{
|
||||
*(_pW++) = pW[i];
|
||||
}
|
||||
|
||||
pObj->k = k;
|
||||
pObj->K = M;
|
||||
pObj->pX = (cpx_t*)malloc(pObj->N*sizeof(cpx_t));
|
||||
memset(pObj->pX, 0, pObj->N*sizeof(cpx_t));
|
||||
}
|
||||
|
||||
void FirCpxMultirateStageUpInit(fir_cpx_multirate_stage_t *pObj, radio_float_t *pW, uint32_t N, uint32_t L, uint32_t k)
|
||||
{
|
||||
uint32_t i;
|
||||
radio_float_t *_pW;
|
||||
|
||||
pObj->N = 0;
|
||||
for (i=L-k-1; i < N; i += L)
|
||||
{
|
||||
pObj->N++;
|
||||
}
|
||||
pObj->pW = (radio_float_t*)malloc(pObj->N*sizeof(cpx_t));
|
||||
_pW = pObj->pW;
|
||||
|
||||
if (pW)
|
||||
{
|
||||
for (i=L-k-1; i < N; i += L)
|
||||
{
|
||||
*(_pW++) = pW[i];
|
||||
}
|
||||
}
|
||||
pObj->k = k;
|
||||
pObj->K = L;
|
||||
pObj->pX = (cpx_t*)malloc(pObj->N*sizeof(cpx_t));
|
||||
memset(pObj->pX, 0, pObj->N*sizeof(cpx_t));
|
||||
}
|
||||
|
||||
void FirCpxMultirateStageFree(fir_cpx_multirate_stage_t *pObj)
|
||||
{
|
||||
if (pObj->pX)
|
||||
free(pObj->pX);
|
||||
|
||||
if (pObj->pW)
|
||||
free(pObj->pW);
|
||||
}
|
||||
|
||||
cpx_t FirCpxMultirateStageProcessDownAccum(fir_cpx_multirate_stage_t *pObj, cpx_t res, cpx_t src)
|
||||
{
|
||||
int32_t i;
|
||||
|
||||
for (i=pObj->N-1; i > 0; i--)
|
||||
{
|
||||
pObj->pX[i] = pObj->pX[i-1];
|
||||
}
|
||||
pObj->pX[i] = src;
|
||||
|
||||
return CpxMulRealAdd(res, pObj->pX, pObj->pW, pObj->N);
|
||||
}
|
||||
|
||||
uint32_t FirCpxMultirateStageProcessUp(fir_cpx_multirate_stage_t *pObj, cpx_t *pSrc, cpx_t *pDst, uint32_t len)
|
||||
{
|
||||
int32_t i;
|
||||
uint32_t num_written;
|
||||
|
||||
num_written = 0;
|
||||
while(len--)
|
||||
{
|
||||
for (i=pObj->N-1; i > 0; i--)
|
||||
{
|
||||
pObj->pX[i] = pObj->pX[i-1];
|
||||
}
|
||||
pObj->pX[i] = *(pSrc++);
|
||||
|
||||
pDst[pObj->K-1 - pObj->k + num_written] = CpxMulRealAdd(Cpx(0,0), pObj->pX, pObj->pW, pObj->N);
|
||||
|
||||
num_written += pObj->K;
|
||||
}
|
||||
return num_written;
|
||||
}
|
||||
|
||||
void FirCpxMultirateDownInit(fir_cpx_multirate_t *pObj, radio_float_t *pW, uint32_t N, uint32_t M)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
pObj->L = 0;
|
||||
pObj->M = M;
|
||||
pObj->N = N;
|
||||
pObj->k = M-1;
|
||||
pObj->res = Cpx(0,0);
|
||||
pObj->pStageUp = 0;
|
||||
pObj->pStageDown = (fir_cpx_multirate_stage_t*)malloc(M*sizeof(fir_cpx_multirate_stage_t));
|
||||
|
||||
for (i=0; i < M; i++)
|
||||
{
|
||||
FirCpxMultirateStageDownInit(&pObj->pStageDown[i], pW, N, M, i);
|
||||
}
|
||||
}
|
||||
|
||||
void FirCpxMultirateUpInit(fir_cpx_multirate_t *pObj, radio_float_t *pW, uint32_t N, uint32_t L)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
pObj->L = L;
|
||||
pObj->M = 0;
|
||||
pObj->N = N;
|
||||
pObj->k = 0;
|
||||
pObj->res = Cpx(0,0);
|
||||
pObj->pStageDown = 0;
|
||||
pObj->pStageUp = (fir_cpx_multirate_stage_t*)malloc(L*sizeof(fir_cpx_multirate_stage_t));
|
||||
|
||||
for (i=0; i < L; i++)
|
||||
{
|
||||
FirCpxMultirateStageUpInit(&pObj->pStageUp[i], pW, N, L, i);
|
||||
}
|
||||
}
|
||||
|
||||
void FirCpxMultirateFree(fir_cpx_multirate_t *pObj)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
if (pObj->pStageDown)
|
||||
{
|
||||
for (i=0; i < pObj->M; i++)
|
||||
{
|
||||
FirCpxMultirateStageFree(&pObj->pStageDown[i]);
|
||||
}
|
||||
free(pObj->pStageDown);
|
||||
}
|
||||
|
||||
if (pObj->pStageUp)
|
||||
{
|
||||
for (i=0; i < pObj->L; i++)
|
||||
{
|
||||
FirCpxMultirateStageFree(&pObj->pStageUp[i]);
|
||||
}
|
||||
free(pObj->pStageUp);
|
||||
}
|
||||
}
|
||||
|
||||
void FirCpxMultirateUpReinit(fir_cpx_multirate_t *pObj, radio_float_t *pW, uint32_t N, uint32_t L)
|
||||
{
|
||||
FirCpxMultirateFree(pObj);
|
||||
FirCpxMultirateUpInit(pObj, pW, N, L);
|
||||
}
|
||||
|
||||
uint32_t FirCpxDownZero(fir_cpx_multirate_t *pObj, cpx_t *pDst, uint32_t len)
|
||||
{
|
||||
uint32_t i;
|
||||
uint32_t num_written;
|
||||
|
||||
num_written = 0;
|
||||
for (i=0; i < len; i += pObj->M)
|
||||
{
|
||||
*(pDst++) = Cpx(0,0);
|
||||
num_written++;
|
||||
}
|
||||
return num_written;
|
||||
}
|
||||
|
||||
uint32_t FirCpxDownProcess(fir_cpx_multirate_t *pObj, cpx_t *pSrc, cpx_t *pDst, uint32_t len)
|
||||
{
|
||||
uint32_t num_written_soll;
|
||||
uint32_t num_written_ist;
|
||||
|
||||
num_written_ist = 0;
|
||||
num_written_soll = FirCpxDownZero(pObj, pDst, len);
|
||||
while(len--)
|
||||
{
|
||||
pObj->res = FirCpxMultirateStageProcessDownAccum(&pObj->pStageDown[pObj->k], pObj->res, *(pSrc++));
|
||||
pObj->k--;
|
||||
if (pObj->k >= pObj->M)
|
||||
{
|
||||
pDst[num_written_ist++] = pObj->res;
|
||||
pObj->res = Cpx(0,0);
|
||||
pObj->k = pObj->M-1;
|
||||
}
|
||||
}
|
||||
return num_written_ist;
|
||||
}
|
||||
|
||||
uint32_t FirCpxUpZero(fir_cpx_multirate_t *pObj, cpx_t *pDst, uint32_t len)
|
||||
{
|
||||
uint32_t i;
|
||||
uint32_t num_written;
|
||||
|
||||
num_written = 0;
|
||||
for (i=0; i < pObj->L*len; i++)
|
||||
{
|
||||
*(pDst++) = Cpx(0,0);
|
||||
num_written++;
|
||||
}
|
||||
return num_written;
|
||||
}
|
||||
|
||||
uint32_t FirCpxUpProcess(fir_cpx_multirate_t *pObj, cpx_t *pSrc, cpx_t *pDst, uint32_t len)
|
||||
{
|
||||
uint32_t k;
|
||||
uint32_t res;
|
||||
uint32_t num_written_ist;
|
||||
|
||||
num_written_ist = 0;
|
||||
for (k=0; k < pObj->L; k++)
|
||||
{
|
||||
res = FirCpxMultirateStageProcessUp(&pObj->pStageUp[k], pSrc, pDst, len);
|
||||
if (num_written_ist < res)
|
||||
num_written_ist = res;
|
||||
|
||||
}
|
||||
return num_written_ist;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// Complex FIR-based polyphase interpolation filter
|
||||
// --------------------------------------------------------------
|
||||
radio_float_t PolyPhaseCpxIpInit(ppip_cpx_t *pObj, radio_float_t fa, radio_float_t tsym, radio_float_t alpha, uint32_t N, uint32_t M)
|
||||
{
|
||||
uint32_t i, j;
|
||||
fir_float_t *pCoeff;
|
||||
radio_float_t k;
|
||||
|
||||
// Calculate polyphase filter
|
||||
pCoeff = (fir_float_t*)malloc((N+1)*M*sizeof(fir_float_t));
|
||||
memset(pCoeff, 0, (N+1)*M*sizeof(fir_float_t));
|
||||
|
||||
k = CalcFirSRRC(pCoeff, M*fa, tsym, alpha, N*M);
|
||||
|
||||
pObj->ppCoeff = (fir_float_t**)malloc(M*sizeof(fir_float_t*));
|
||||
for(i=0; i < M; i++)
|
||||
{
|
||||
pObj->ppCoeff[i] = (fir_float_t*)malloc(N*sizeof(fir_float_t));
|
||||
memset(pObj->ppCoeff[i], 0, N*sizeof(fir_float_t));
|
||||
}
|
||||
for(i=0; i < M; i++)
|
||||
{
|
||||
for(j=0; j < N; j++)
|
||||
{
|
||||
pObj->ppCoeff[i][j] = M*pCoeff[M*j+M/2+i];
|
||||
}
|
||||
}
|
||||
|
||||
// FIFO
|
||||
pObj->L = N; // Influences STR-Loop delay
|
||||
pObj->w = 0;
|
||||
pObj->r = 0;
|
||||
|
||||
pObj->pFifo = (cpx_t*)malloc(pObj->L*sizeof(cpx_t));
|
||||
memset(pObj->pFifo, 0, pObj->L*sizeof(cpx_t));
|
||||
|
||||
pObj->pX = (cpx_t*)malloc(pObj->L*sizeof(cpx_t));
|
||||
memset(pObj->pX, 0, pObj->L*sizeof(cpx_t));
|
||||
|
||||
pObj->M = M;
|
||||
pObj->N = N;
|
||||
|
||||
free(pCoeff);
|
||||
|
||||
return k/M;
|
||||
}
|
||||
|
||||
void PolyPhaseCpxIpFree(ppip_cpx_t *pObj)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
for(i=0; i < pObj->M; i++)
|
||||
{
|
||||
free(pObj->ppCoeff[i]);
|
||||
}
|
||||
free(pObj->ppCoeff);
|
||||
pObj->ppCoeff = NULL;
|
||||
|
||||
free(pObj->pFifo);
|
||||
pObj->pFifo = NULL;
|
||||
|
||||
free(pObj->pX);
|
||||
pObj->pX = NULL;
|
||||
}
|
||||
|
||||
void PolyPhaseCpxIpFeed(ppip_cpx_t *pObj, uint32_t push, cpx_t x)
|
||||
{
|
||||
pObj->w = (pObj->w + push) % pObj->L;
|
||||
pObj->pFifo[pObj->w] = x;
|
||||
}
|
||||
|
||||
cpx_t PolyPhaseCpxIpInterpolate(ppip_cpx_t *pObj, int32_t pop, radio_float_t mu)
|
||||
{
|
||||
uint32_t index, r;
|
||||
int32_t j;
|
||||
cpx_t y;
|
||||
|
||||
index = (uint32_t)dmod(dmax(0, mu*pObj->M), (radio_float_t)pObj->M);
|
||||
|
||||
pObj->r = (pObj->r + pop) % pObj->L;
|
||||
|
||||
if (pop)
|
||||
{
|
||||
r = pObj->r;
|
||||
j = pObj->N-1;
|
||||
while(r < pObj->L)
|
||||
{
|
||||
pObj->pX[j--] = pObj->pFifo[r++];
|
||||
}
|
||||
r = 0;
|
||||
while(j >= 0)
|
||||
{
|
||||
pObj->pX[j--] = pObj->pFifo[r++];
|
||||
}
|
||||
}
|
||||
|
||||
y = CpxMulRealAdd(Cpx(0,0), pObj->pX, pObj->ppCoeff[index], pObj->N);
|
||||
/*
|
||||
pObj->r = (pObj->r + pop) % pObj->L;
|
||||
r = pObj->r;
|
||||
|
||||
y = Cpx(0,0);
|
||||
for (j=0; j < pObj->N; j++)
|
||||
{
|
||||
y.real += pObj->pFifo[r].real * pW[j];
|
||||
y.imag += pObj->pFifo[r].imag * pW[j];
|
||||
|
||||
r = (r + pObj->L-1) % pObj->L;
|
||||
|
||||
}
|
||||
*/
|
||||
return y;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// Complex FIR-based polyphase interpolation filter (Farrow structure)
|
||||
// From:
|
||||
// "PERFORMANCE AND DESIGN OF FARROW FILTER USED FOR ARBITRARY RESAMPLING"
|
||||
// [unknown date], Fred Harris, Signal Processing ChairCommunication Systems and Signal Processing Institute
|
||||
// College of Engineering, San Diego State University, San Diego, CA 92182-0190 USA
|
||||
// --------------------------------------------------------------
|
||||
void FarrowPPIPCpxInit(ppip_farrow_cpx_t *pObj, uint32_t M, uint32_t N)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
pObj->ppCoeff = (fir_float_t**)malloc(M*sizeof(fir_float_t*));
|
||||
for(i=0; i < M; i++)
|
||||
{
|
||||
pObj->ppCoeff[i] = (fir_float_t*)malloc(N*sizeof(fir_float_t));
|
||||
memset(pObj->ppCoeff[i], 0, N*sizeof(fir_float_t));
|
||||
}
|
||||
pObj->M = M;
|
||||
pObj->N = N;
|
||||
|
||||
pObj->pH = (cpx_t*)malloc(M*sizeof(cpx_t));
|
||||
memset(pObj->pH, 0, M*sizeof(cpx_t));
|
||||
|
||||
pObj->pB = (cpx_t*)malloc(M*sizeof(cpx_t));
|
||||
memset(pObj->pB, 0, M*sizeof(cpx_t));
|
||||
|
||||
pObj->L = N; // Influences STR-Loop delay
|
||||
pObj->w = 0;
|
||||
pObj->r = 0;
|
||||
|
||||
pObj->pFifo = (cpx_t*)malloc(pObj->L*sizeof(cpx_t));
|
||||
memset(pObj->pFifo, 0, pObj->L*sizeof(cpx_t));
|
||||
|
||||
pObj->pX = (cpx_t*)malloc(pObj->L*sizeof(cpx_t));
|
||||
memset(pObj->pX, 0, pObj->L*sizeof(cpx_t));
|
||||
|
||||
}
|
||||
|
||||
void FarrowPPIPCpxFree(ppip_farrow_cpx_t *pObj)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
for(i=0; i < pObj->M; i++)
|
||||
{
|
||||
free(pObj->ppCoeff[i]);
|
||||
}
|
||||
free(pObj->ppCoeff);
|
||||
pObj->ppCoeff = NULL;
|
||||
|
||||
free(pObj->pH);
|
||||
pObj->pH = NULL;
|
||||
|
||||
free(pObj->pB);
|
||||
pObj->pB = NULL;
|
||||
|
||||
free(pObj->pFifo);
|
||||
pObj->pFifo = NULL;
|
||||
|
||||
free(pObj->pX);
|
||||
pObj->pX = NULL;
|
||||
}
|
||||
|
||||
cpx_t horner(cpx_t *a, cpx_t *b, uint32_t M, radio_float_t mu)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
b[0] = a[0];
|
||||
for (i=1; i < M; i++)
|
||||
{
|
||||
b[i].real = a[i].real+mu*b[i-1].real;
|
||||
b[i].imag = a[i].imag+mu*b[i-1].imag;
|
||||
}
|
||||
return b[M-1];
|
||||
}
|
||||
|
||||
void FarrowPPIPCpxFeed(ppip_farrow_cpx_t *pObj, uint32_t push, cpx_t x)
|
||||
{
|
||||
pObj->w = (pObj->w + push) % pObj->L;
|
||||
pObj->pFifo[pObj->w] = x;
|
||||
}
|
||||
|
||||
cpx_t FarrowPPIPCpxInterpolate(ppip_farrow_cpx_t *pObj, uint32_t pop, radio_float_t mu)
|
||||
{
|
||||
uint32_t i, r;
|
||||
int32_t j;
|
||||
|
||||
pObj->r = (pObj->r + pop) % pObj->L;
|
||||
|
||||
if (pop)
|
||||
{
|
||||
r = pObj->r;
|
||||
j = pObj->N-1;
|
||||
while(r < pObj->L)
|
||||
{
|
||||
pObj->pX[j--] = pObj->pFifo[r++];
|
||||
}
|
||||
r = 0;
|
||||
while(j >= 0)
|
||||
{
|
||||
pObj->pX[j--] = pObj->pFifo[r++];
|
||||
}
|
||||
}
|
||||
|
||||
// Partial filter responses
|
||||
for (i=0; i < pObj->M; i++)
|
||||
{
|
||||
pObj->pH[i] = CpxMulRealAdd(Cpx(0,0), pObj->pX, pObj->ppCoeff[i], pObj->N);
|
||||
}
|
||||
|
||||
// Combine
|
||||
return horner(pObj->pH, pObj->pB, pObj->M, mu);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// Real First-order interpolation filter
|
||||
// --------------------------------------------------------------
|
||||
void FDly_Init(fdly_t *pObj, int32_t order)
|
||||
{
|
||||
pObj->Nf = order + 1;
|
||||
|
||||
pObj->hf = (radio_float_t*)malloc(pObj->Nf*sizeof(radio_float_t));
|
||||
pObj->statef = (radio_float_t*)malloc(pObj->Nf*sizeof(radio_float_t));
|
||||
memset(pObj->hf, 0, pObj->Nf*sizeof(radio_float_t));
|
||||
memset(pObj->statef, 0, pObj->Nf*sizeof(radio_float_t));
|
||||
}
|
||||
|
||||
void FDly_Free(fdly_t *pObj)
|
||||
{
|
||||
if (pObj->hf)
|
||||
free(pObj->hf);
|
||||
|
||||
pObj->hf = NULL;
|
||||
|
||||
if (pObj->statef)
|
||||
free(pObj->statef);
|
||||
|
||||
pObj->statef = NULL;
|
||||
|
||||
}
|
||||
|
||||
radio_float_t FDly_Process(fdly_t *pObj, radio_float_t x)
|
||||
{
|
||||
radio_float_t y;
|
||||
|
||||
FIR(pObj->hf, pObj->statef, pObj->Nf, &x, &y, 1);
|
||||
|
||||
return y;
|
||||
}
|
||||
|
||||
void FDly_CalcCoeff(fdly_t *pObj, radio_float_t delay)
|
||||
{
|
||||
int32_t n, k;
|
||||
radio_float_t hn;
|
||||
|
||||
for (n=0; n < pObj->Nf; n++)
|
||||
{
|
||||
hn = 1.0;
|
||||
for (k=0; k < pObj->Nf; k++)
|
||||
{
|
||||
if (k == n)
|
||||
continue;
|
||||
|
||||
hn *= ((delay - (radio_float_t)k) / (radio_float_t)(n-k));
|
||||
}
|
||||
pObj->hf[n] = hn;
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// Real Polynomial-based Lagrange interpolation filter
|
||||
// --------------------------------------------------------------
|
||||
void LGIpInit(lgip_t *pObj, int32_t order, int32_t bufsize)
|
||||
{
|
||||
pObj->N = order + 1;
|
||||
pObj->bufsize = bufsize;
|
||||
RBufInit(&pObj->rbuf, bufsize);
|
||||
}
|
||||
|
||||
void LGIpFree(lgip_t *pObj)
|
||||
{
|
||||
RBufFree(&pObj->rbuf);
|
||||
pObj->N = 0;
|
||||
}
|
||||
|
||||
radio_float_t LGIpProcess(lgip_t *pObj, radio_float_t x, int32_t m, radio_float_t mu)
|
||||
{
|
||||
int32_t n, k;
|
||||
radio_float_t hn, y, delay;
|
||||
|
||||
RBufPut(&pObj->rbuf, x);
|
||||
y = 0;
|
||||
delay = 1-mu;
|
||||
for (n=0; n < pObj->N; n++)
|
||||
{
|
||||
hn = 1.0;
|
||||
for (k=0; k < pObj->N; k++)
|
||||
{
|
||||
if (k == n)
|
||||
continue;
|
||||
|
||||
hn *= ((delay - (radio_float_t)k) / (radio_float_t)(n-k));
|
||||
}
|
||||
y += hn*RBufGetAt(&pObj->rbuf, pObj->bufsize/2 + m-n);
|
||||
}
|
||||
return y;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// Complex Polynomial-based Lagrange interpolation filter
|
||||
// --------------------------------------------------------------
|
||||
void LGCpxIpInit(lgip_cpx_t *pObj, int32_t order)
|
||||
{
|
||||
// FIFO
|
||||
pObj->N = order + 1;
|
||||
pObj->w = 0;
|
||||
pObj->r = 0;
|
||||
pObj->L = 64*pObj->N; // Influences STR-Loop delay
|
||||
|
||||
pObj->pFifo = (cpx_t*)malloc(pObj->L*sizeof(cpx_t));
|
||||
memset(pObj->pFifo, 0, pObj->L*sizeof(cpx_t));
|
||||
|
||||
}
|
||||
|
||||
void LGCpxIpFree(lgip_cpx_t *pObj)
|
||||
{
|
||||
free(pObj->pFifo);
|
||||
pObj->pFifo = NULL;
|
||||
pObj->N = 0;
|
||||
}
|
||||
|
||||
cpx_t LGCpxIpProcess(lgip_cpx_t *pObj, cpx_t x, int32_t m, radio_float_t mu)
|
||||
{
|
||||
uint32_t i, j, k, N, L, r;
|
||||
radio_float_t h;
|
||||
cpx_t y;
|
||||
|
||||
L = pObj->L;
|
||||
N = pObj->N;
|
||||
|
||||
pObj->pFifo[pObj->w++] = x;
|
||||
if (pObj->w == L)
|
||||
pObj->w = 0;
|
||||
|
||||
r = (m-N) % L;
|
||||
|
||||
k = 0;
|
||||
|
||||
y.real = 0.0;
|
||||
y.imag = 0.0;
|
||||
for (i=0; i < pObj->N; i++)
|
||||
{
|
||||
h = 1.0;
|
||||
for (j=0; j < pObj->N; j++)
|
||||
{
|
||||
if (i == j)
|
||||
continue;
|
||||
|
||||
h *= (((radio_float_t)pObj->N/2 + mu - (radio_float_t)j - (radio_float_t)0.5) / (radio_float_t)(i-j));
|
||||
}
|
||||
y.real += pObj->pFifo[r].real * h;
|
||||
y.imag += pObj->pFifo[r].imag * h;
|
||||
r = (r+1) % L;
|
||||
}
|
||||
return y;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// Real FIR-based polyphase interpolation SRRC (Square Root Raised Cosine) matched filter #1
|
||||
// --------------------------------------------------------------
|
||||
radio_float_t PolyPhaseSRRCInit(fir_pp_t *pObj, radio_float_t fa, radio_float_t tsym, radio_float_t alpha, uint32_t N, uint32_t M)
|
||||
{
|
||||
uint32_t i, j;
|
||||
fir_float_t *pCoeff;
|
||||
radio_float_t k;
|
||||
|
||||
pCoeff = (fir_float_t*)malloc((N+1)*M*sizeof(fir_float_t));
|
||||
memset(pCoeff, 0, M*(N+1)*sizeof(fir_float_t));
|
||||
|
||||
k = CalcFirSRRC(pCoeff, M*fa, tsym, alpha, M*N);
|
||||
|
||||
pObj->ppCoeff = (fir_float_t**)malloc(M*sizeof(fir_float_t*));
|
||||
for(i=0; i < M; i++)
|
||||
{
|
||||
pObj->ppCoeff[i] = (fir_float_t*)malloc(N*sizeof(fir_float_t));
|
||||
memset(pObj->ppCoeff[i], 0, N*sizeof(fir_float_t));
|
||||
}
|
||||
pObj->pState = (fir_float_t*)malloc(N*sizeof(fir_float_t));
|
||||
memset(pObj->pState, 0, N*sizeof(fir_float_t));
|
||||
|
||||
for(i=0; i < M; i++)
|
||||
{
|
||||
for(j=0; j < N; j++)
|
||||
{
|
||||
pObj->ppCoeff[i][j] = M*pCoeff[M*j+M/2+i];
|
||||
}
|
||||
}
|
||||
|
||||
pObj->M = M;
|
||||
pObj->N = N;
|
||||
|
||||
free(pCoeff);
|
||||
|
||||
return k/M;
|
||||
|
||||
}
|
||||
|
||||
void PolyPhaseSRRCFree(fir_pp_t *pObj)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
for(i=0; i < pObj->M; i++)
|
||||
{
|
||||
free(pObj->ppCoeff[i]);
|
||||
}
|
||||
free(pObj->ppCoeff);
|
||||
pObj->ppCoeff = NULL;
|
||||
|
||||
free(pObj->pState);
|
||||
pObj->pState = NULL;
|
||||
|
||||
}
|
||||
|
||||
uint32_t PolyPhaseSRRCProcess(fir_pp_t *pObj, radio_float_t mu, radio_float_t *pX, radio_float_t *pY, uint32_t len)
|
||||
{
|
||||
uint32_t m;
|
||||
|
||||
// m = (pObj->M/2 + (int32_t)(mu * pObj->M/2)) % pObj->M;
|
||||
m = (int32_t)dmod(mu*pObj->M, (radio_float_t)pObj->M);
|
||||
|
||||
FIR(pObj->ppCoeff[m], pObj->pState, pObj->N, pX, pY, len);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// Real FIR-based polyphase interpolation SRRC (Square Root Raised Cosine) matched filter #2
|
||||
// --------------------------------------------------------------
|
||||
radio_float_t PolyPhaseIpInit(ppip_t *pObj, radio_float_t fa, radio_float_t tsym, radio_float_t alpha, uint32_t N, uint32_t M)
|
||||
{
|
||||
uint32_t i, j;
|
||||
fir_float_t *pCoeff;
|
||||
radio_float_t k;
|
||||
|
||||
pCoeff = (fir_float_t*)malloc((N+1)*M*sizeof(fir_float_t));
|
||||
memset(pCoeff, 0, (N+1)*M*sizeof(fir_float_t));
|
||||
|
||||
k = CalcFirSRRC(pCoeff, M*fa, tsym, alpha, N*M);
|
||||
|
||||
pObj->ppCoeff = (fir_float_t**)malloc(M*sizeof(fir_float_t*));
|
||||
for(i=0; i < M; i++)
|
||||
{
|
||||
pObj->ppCoeff[i] = (fir_float_t*)malloc(N*sizeof(fir_float_t));
|
||||
memset(pObj->ppCoeff[i], 0, N*sizeof(fir_float_t));
|
||||
}
|
||||
for(i=0; i < M; i++)
|
||||
{
|
||||
for(j=0; j < N; j++)
|
||||
{
|
||||
pObj->ppCoeff[i][j] = M*pCoeff[M*j+M/2+i];
|
||||
}
|
||||
}
|
||||
pObj->pState = (fir_float_t*)malloc(N*sizeof(fir_float_t));
|
||||
memset(pObj->pState, 0, N*sizeof(fir_float_t));
|
||||
|
||||
pObj->M = M;
|
||||
pObj->N = N;
|
||||
|
||||
RBufInit(&pObj->rbuf, 2*N); // Influences STR-Loop delay
|
||||
|
||||
free(pCoeff);
|
||||
|
||||
return k/M;
|
||||
|
||||
}
|
||||
|
||||
void PolyPhaseIpFree(ppip_t *pObj)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
for(i=0; i < pObj->M; i++)
|
||||
{
|
||||
free(pObj->ppCoeff[i]);
|
||||
}
|
||||
free(pObj->ppCoeff);
|
||||
pObj->ppCoeff = NULL;
|
||||
|
||||
free(pObj->pState);
|
||||
pObj->pState = NULL;
|
||||
|
||||
RBufFree(&pObj->rbuf);
|
||||
|
||||
}
|
||||
|
||||
radio_float_t PolyPhaseIpProcess(ppip_t *pObj, radio_float_t x, int32_t m, radio_float_t mu)
|
||||
{
|
||||
uint32_t index, i;
|
||||
radio_float_t y;
|
||||
|
||||
index = (int32_t)dmod(mu*pObj->M, (radio_float_t)pObj->M);
|
||||
|
||||
for(i=0; i < pObj->N; i++)
|
||||
{
|
||||
pObj->pState[i] = RBufGetAt(&pObj->rbuf, m-i);
|
||||
}
|
||||
|
||||
FIR(pObj->ppCoeff[index], pObj->pState, pObj->N, &x, &y, 1);
|
||||
RBufPut(&pObj->rbuf, x);
|
||||
|
||||
return y;
|
||||
}
|
||||
Executable
+158
@@ -0,0 +1,158 @@
|
||||
// --------------------------------------------------------------
|
||||
#ifndef INTERPOLATION_H
|
||||
#define INTERPOLATION_H
|
||||
|
||||
#include "radio_types.h"
|
||||
#include "real.h"
|
||||
#include "cpx.h"
|
||||
#include <fir/fir2.h>
|
||||
#include "ringbuf.h"
|
||||
#include "synchronization.h"
|
||||
|
||||
// --------------------------------------------------------------
|
||||
#define CEF_MODE_NOP 0
|
||||
#define CEF_MODE_CMA 1
|
||||
#define CEF_MODE_DD 2
|
||||
#define CEF_MODE_EQ_UPD 3
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// Types
|
||||
// --------------------------------------------------------------
|
||||
typedef struct _fir_cpx_t
|
||||
{
|
||||
uint32_t N, r, w;
|
||||
cpx_t *pX;
|
||||
uint32_t M_up, M_down;
|
||||
clock_t clockUp;
|
||||
clock_t clockDown;
|
||||
} fir_cpx_t;
|
||||
|
||||
typedef struct _fir_cpx_multirate_stage_t
|
||||
{
|
||||
uint32_t N;
|
||||
uint32_t k;
|
||||
uint32_t K;
|
||||
cpx_t *pX;
|
||||
radio_float_t *pW;
|
||||
|
||||
} fir_cpx_multirate_stage_t;
|
||||
|
||||
typedef struct _fir_cpx_multirate_t
|
||||
{
|
||||
uint32_t N;
|
||||
uint32_t L;
|
||||
uint32_t M;
|
||||
fir_cpx_multirate_stage_t *pStageUp;
|
||||
fir_cpx_multirate_stage_t *pStageDown;
|
||||
cpx_t res;
|
||||
uint32_t k;
|
||||
|
||||
} fir_cpx_multirate_t;
|
||||
|
||||
typedef struct _fdly_t
|
||||
{
|
||||
int32_t Nf;
|
||||
radio_float_t *hf, *statef;
|
||||
} fdly_t;
|
||||
|
||||
typedef struct _lgip_t
|
||||
{
|
||||
int32_t N, bufsize;
|
||||
rbuf_t rbuf;
|
||||
} lgip_t;
|
||||
|
||||
typedef struct _lgip_cpx_t
|
||||
{
|
||||
cpx_t *pFifo;
|
||||
uint32_t N, L, w, r;
|
||||
|
||||
} lgip_cpx_t;
|
||||
|
||||
typedef struct _fir_pp_t
|
||||
{
|
||||
uint32_t N, M;
|
||||
radio_float_t **ppCoeff, *pState;
|
||||
|
||||
} fir_pp_t;
|
||||
|
||||
typedef struct _ppip_t
|
||||
{
|
||||
radio_float_t **ppCoeff, *pState;
|
||||
uint32_t N, M;
|
||||
rbuf_t rbuf;
|
||||
|
||||
} ppip_t;
|
||||
|
||||
typedef struct _ppip_cpx_t
|
||||
{
|
||||
cpx_t *pFifo;
|
||||
radio_float_t **ppCoeff;
|
||||
uint32_t N, L, M, w, r;
|
||||
cpx_t *pX;
|
||||
|
||||
} ppip_cpx_t;
|
||||
|
||||
typedef struct _ppip_farrow_cpx_t
|
||||
{
|
||||
cpx_t *pFifo, *pH, *pB;
|
||||
radio_float_t **ppCoeff;
|
||||
uint32_t N, L, M, w, r;
|
||||
cpx_t *pX;
|
||||
|
||||
} ppip_farrow_cpx_t;
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// Functions
|
||||
// --------------------------------------------------------------
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void FDly_Init(fdly_t *pObj, int32_t order);
|
||||
void FDly_Free(fdly_t *pObj);
|
||||
void FDly_CalcCoeff(fdly_t *pObj, radio_float_t delay);
|
||||
radio_float_t FDly_Process(fdly_t *pObj, radio_float_t x);
|
||||
|
||||
void LGIpInit(lgip_t *pObj, int32_t order, int32_t bufsize);
|
||||
void LGIpFree(lgip_t *pObj);
|
||||
radio_float_t LGIpProcess(lgip_t *pObj, radio_float_t x, int32_t m, radio_float_t mu);
|
||||
|
||||
void LGCpxIpInit(lgip_cpx_t *pObj, int32_t order);
|
||||
void LGCpxIpFree(lgip_cpx_t *pObj);
|
||||
cpx_t LGCpxIpProcess(lgip_cpx_t *pObj, cpx_t x, int32_t m, radio_float_t mu);
|
||||
|
||||
radio_float_t PolyPhaseSRRCInit(fir_pp_t *pObj, radio_float_t fa, radio_float_t tsym, radio_float_t alpha, uint32_t N, uint32_t M);
|
||||
void PolyPhaseSRRCFree(fir_pp_t *pObj);
|
||||
uint32_t PolyPhaseSRRCProcess(fir_pp_t *pObj, radio_float_t mu, radio_float_t *pX, radio_float_t *pY, uint32_t len);
|
||||
|
||||
radio_float_t PolyPhaseIpInit(ppip_t *pObj, radio_float_t fa, radio_float_t tsym, radio_float_t alpha, uint32_t N, uint32_t M);
|
||||
void PolyPhaseIpFree(ppip_t *pObj);
|
||||
radio_float_t PolyPhaseIpProcess(ppip_t *pObj, radio_float_t x, int32_t m, radio_float_t mu);
|
||||
|
||||
radio_float_t PolyPhaseCpxIpInit(ppip_cpx_t *pObj, radio_float_t fa, radio_float_t tsym, radio_float_t alpha, uint32_t N, uint32_t M);
|
||||
void PolyPhaseCpxIpFree(ppip_cpx_t *pObj);
|
||||
void PolyPhaseCpxIpFeed(ppip_cpx_t *pObj, uint32_t push, cpx_t x);
|
||||
cpx_t PolyPhaseCpxIpInterpolate(ppip_cpx_t *pObj, int32_t pop, radio_float_t mu);
|
||||
|
||||
void FarrowPPIPCpxInit(ppip_farrow_cpx_t *pObj, uint32_t M, uint32_t N);
|
||||
void FarrowPPIPCpxFree(ppip_farrow_cpx_t *pObj);
|
||||
void FarrowPPIPCpxFeed(ppip_farrow_cpx_t *pObj, uint32_t push, cpx_t x);
|
||||
cpx_t FarrowPPIPCpxInterpolate(ppip_farrow_cpx_t *pObj, uint32_t pop, radio_float_t mu);
|
||||
|
||||
void FirCpxInit(fir_cpx_t *pObj, uint32_t N, uint32_t M_up, uint32_t M_down);
|
||||
void FirCpxFree(fir_cpx_t *pObj);
|
||||
uint32_t FirCpxProcessReal(fir_cpx_t *pObj, radio_float_t *pW, cpx_t *pSrc, cpx_t *pDst, uint32_t len);
|
||||
|
||||
void FirCpxMultirateDownInit(fir_cpx_multirate_t *pObj, radio_float_t *pW, uint32_t N, uint32_t M);
|
||||
void FirCpxMultirateUpInit(fir_cpx_multirate_t *pObj, radio_float_t *pW, uint32_t N, uint32_t L);
|
||||
void FirCpxMultirateUpReinit(fir_cpx_multirate_t *pObj, radio_float_t *pW, uint32_t N, uint32_t L);
|
||||
void FirCpxMultirateFree(fir_cpx_multirate_t *pObj);
|
||||
uint32_t FirCpxDownProcess(fir_cpx_multirate_t *pObj, cpx_t *pSrc, cpx_t *pDst, uint32_t len);
|
||||
uint32_t FirCpxUpProcess(fir_cpx_multirate_t *pObj, cpx_t *pSrc, cpx_t *pDst, uint32_t len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
// --------------------------------------------------------------
|
||||
#endif // INTERPOLATION_H
|
||||
@@ -0,0 +1,118 @@
|
||||
// --------------------------------------------------------------
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include "nco.h"
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// NCO
|
||||
// Scalar version
|
||||
// --------------------------------------------------------------
|
||||
void NCO_Init(nco_t *pObj, radio_float_t omega, radio_float_t phi)
|
||||
{
|
||||
pObj->omega = omega;
|
||||
pObj->phi = phi;
|
||||
memset(&pObj->state,0,sizeof(cpx_t));
|
||||
}
|
||||
|
||||
void NCO_Free(nco_t *pObj)
|
||||
{
|
||||
(void)pObj;
|
||||
}
|
||||
|
||||
void NCO_Reinit(nco_t *pObj, radio_float_t omega, radio_float_t phi)
|
||||
{
|
||||
NCO_Free(pObj);
|
||||
NCO_Init(pObj, omega, phi);
|
||||
}
|
||||
|
||||
void NCO_SetOmega(nco_t *pObj, radio_float_t omega)
|
||||
{
|
||||
pObj->omega = omega;
|
||||
}
|
||||
|
||||
void NCO_SetPhi(nco_t *pObj, radio_float_t phi)
|
||||
{
|
||||
pObj->phi = phi;
|
||||
}
|
||||
|
||||
radio_float_t NCO_GetOmega(nco_t *pObj)
|
||||
{
|
||||
return pObj->omega;
|
||||
}
|
||||
|
||||
radio_float_t NCO_GetPhi(nco_t *pObj)
|
||||
{
|
||||
return pObj->phi;
|
||||
}
|
||||
|
||||
void NCO_Process(nco_t *pObj, radio_float_t dOmega, radio_float_t dPhi)
|
||||
{
|
||||
pObj->phi += (pObj->omega + dOmega);
|
||||
|
||||
if (pObj->phi < -(radio_float_t)0.5)
|
||||
pObj->phi += (radio_float_t)1.0;
|
||||
|
||||
if (pObj->phi >= +(radio_float_t)0.5)
|
||||
pObj->phi -= (radio_float_t)1.0;
|
||||
|
||||
pObj->state.real = +(radio_float_t)cos(2.0*PI*pObj->phi + dPhi);
|
||||
pObj->state.imag = -(radio_float_t)sin(2.0*PI*pObj->phi + dPhi);
|
||||
}
|
||||
|
||||
cpx_t NCO_MixRealComplexS(nco_t *pObj, radio_float_t src, radio_float_t gain)
|
||||
{
|
||||
cpx_t dst;
|
||||
|
||||
dst.real = gain*src;
|
||||
dst.imag = 0;
|
||||
|
||||
return CpxMulS(pObj->state, dst);
|
||||
}
|
||||
|
||||
radio_float_t NCO_MixComplexRealS(nco_t *pObj, cpx_t src, cpx_t gain)
|
||||
{
|
||||
return gain.real*pObj->state.real*src.real + gain.imag*pObj->state.imag*src.imag;
|
||||
}
|
||||
|
||||
cpx_t NCO_MixComplexS(nco_t *pObj, cpx_t src, cpx_t gain)
|
||||
{
|
||||
return CpxMulS(pObj->state, CpxScaleComplexS(src, gain));
|
||||
}
|
||||
|
||||
void NCO_MixRealComplexV(nco_t *pObj, cpx_t *pDst, radio_float_t *pSrc, radio_float_t gain, uint32_t len)
|
||||
{
|
||||
|
||||
while (len--)
|
||||
{
|
||||
|
||||
*(pDst++) = NCO_MixRealComplexS(pObj, *(pSrc++), gain);
|
||||
|
||||
// NCO update
|
||||
NCO_Process(pObj, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void NCO_MixComplexRealV(nco_t *pObj, radio_float_t *pDst, cpx_t *pSrc, cpx_t gain, uint32_t len)
|
||||
{
|
||||
while (len--)
|
||||
{
|
||||
|
||||
*(pDst++) = NCO_MixComplexRealS(pObj, *(pSrc++), gain);
|
||||
|
||||
// NCO update
|
||||
NCO_Process(pObj, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void NCO_MixComplexV(nco_t *pObj, cpx_t *pSrcDst, cpx_t gain, uint32_t len)
|
||||
{
|
||||
while (len--)
|
||||
{
|
||||
*(pSrcDst++) = NCO_MixComplexS(pObj, *(pSrcDst++), gain);
|
||||
|
||||
// NCO update
|
||||
NCO_Process(pObj, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------
|
||||
@@ -0,0 +1,57 @@
|
||||
// --------------------------------------------------------------
|
||||
#ifndef NCO_H
|
||||
#define NCO_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "radio_types.h"
|
||||
#include "real.h"
|
||||
#include "cpx.h"
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// Types
|
||||
// --------------------------------------------------------------
|
||||
typedef struct _nco_t
|
||||
{
|
||||
radio_float_t phi, omega;
|
||||
cpx_t state;
|
||||
} nco_t;
|
||||
|
||||
// --------------------------------------------------------------
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
// --------------------------------------------------------------
|
||||
// NCO
|
||||
// --------------------------------------------------------------
|
||||
// Scalar version
|
||||
void NCO_Init(nco_t *pObj, radio_float_t omega, radio_float_t phi);
|
||||
void NCO_Free(nco_t *pObj);
|
||||
void NCO_Reinit(nco_t *pObj, radio_float_t omega, radio_float_t phi);
|
||||
void NCO_SetOmega(nco_t *pObj, radio_float_t omega);
|
||||
void NCO_SetPhi(nco_t *pObj, radio_float_t phi);
|
||||
radio_float_t NCO_GetOmega(nco_t *pObj);
|
||||
radio_float_t NCO_GetPhi(nco_t *pObj);
|
||||
void NCO_Process(nco_t *pObj, radio_float_t dOmega, radio_float_t dPhi);
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// Mixer
|
||||
// Scalar version
|
||||
// --------------------------------------------------------------
|
||||
cpx_t NCO_MixRealComplexS(nco_t *pObj, radio_float_t src, radio_float_t gain);
|
||||
cpx_t NCO_MixComplexS(nco_t *pObj, cpx_t src, cpx_t gain);
|
||||
radio_float_t NCO_MixComplexRealS(nco_t *pObj, cpx_t src, cpx_t gain);
|
||||
// --------------------------------------------------------------
|
||||
// Mixer
|
||||
// Vector version
|
||||
// --------------------------------------------------------------
|
||||
void NCO_MixRealComplexV(nco_t *pObj, cpx_t *pDst, radio_float_t *pSrc, radio_float_t gain, uint32_t len);
|
||||
void NCO_MixComplexV(nco_t *pObj, cpx_t *pSrcDst, cpx_t gain, uint32_t len);
|
||||
void NCO_MixComplexRealV(nco_t *pObj, radio_float_t *pDst, cpx_t *pSrc, cpx_t gain, uint32_t len);
|
||||
|
||||
// --------------------------------------------------------------
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif // __cplusplus
|
||||
|
||||
// --------------------------------------------------------------
|
||||
#endif // NCO_H
|
||||
@@ -0,0 +1,530 @@
|
||||
// --------------------------------------------------------------
|
||||
#ifndef RADIO_H
|
||||
#define RADIO_H
|
||||
|
||||
#include "radio_types.h"
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// RF Types
|
||||
// --------------------------------------------------------------
|
||||
#define FRAME_CRC16_IV 0x0000
|
||||
#define FRAME_CRC16_POLY 0x1021
|
||||
#define FRAME_PREAMBLE_IV 0x55
|
||||
#define FRAME_SCRAMBLER_SEED 0x12345678
|
||||
#define FRAME_SCRAMBLER_POLY 0x80C18601
|
||||
#define FRAME_NUM_BYTES_PER_FRAME 32
|
||||
#define FRAME_TYPE_IDLE 0x01
|
||||
#define FRAME_TYPE_DATA 0x02
|
||||
|
||||
typedef struct _cpx_t
|
||||
{
|
||||
radio_float_t imag, real;
|
||||
|
||||
} cpx_t;
|
||||
|
||||
typedef struct _cpx_arr_t
|
||||
{
|
||||
radio_float_t *pImag, *pReal;
|
||||
|
||||
} cpx_arr_t;
|
||||
|
||||
typedef struct _nco_t
|
||||
{
|
||||
radio_float_t phi, omega, dPhi, dOmega;
|
||||
cpx_t state;
|
||||
uint32_t tbl_index, tbl_size;
|
||||
cpx_t *pTbl;
|
||||
} nco_t;
|
||||
|
||||
#if 0
|
||||
typedef struct _clkgen_t
|
||||
{
|
||||
nco_t *pNCO;
|
||||
radio_float_t lastPhi;
|
||||
|
||||
} clkgen_t;
|
||||
|
||||
typedef struct _sampler_t
|
||||
{
|
||||
int count, reload;
|
||||
|
||||
} sampler_t;
|
||||
|
||||
typedef struct _lead_lag_filter_t
|
||||
{
|
||||
radio_float_t gain_lead, gain_lag;
|
||||
radio_float_t term_lead, term_lag;
|
||||
|
||||
} lead_lag_filter_t;
|
||||
|
||||
typedef struct _str_t
|
||||
{
|
||||
cpx_t d[2];
|
||||
|
||||
} str_t;
|
||||
|
||||
#endif
|
||||
|
||||
typedef struct _rbuf_t
|
||||
{
|
||||
int size, iw, ir, dist;
|
||||
radio_float_t *pData;
|
||||
|
||||
} rbuf_t;
|
||||
|
||||
typedef struct _fifo_t
|
||||
{
|
||||
uint32_t size_max;
|
||||
uint32_t size;
|
||||
uint32_t ir;
|
||||
uint32_t iw;
|
||||
uint32_t *pData;
|
||||
|
||||
} fifo_t;
|
||||
|
||||
|
||||
typedef struct _sl_mean_t
|
||||
{
|
||||
rbuf_t buf;
|
||||
uint32_t normalize_count;
|
||||
radio_float_t Nr;
|
||||
radio_float_t sum;
|
||||
radio_float_t element_max;
|
||||
radio_float_t mean;
|
||||
|
||||
} sl_mean_t;
|
||||
|
||||
typedef struct _sl_var_t
|
||||
{
|
||||
sl_mean_t sl_mean;
|
||||
rbuf_t buf;
|
||||
uint32_t normalize_count;
|
||||
radio_float_t Nr;
|
||||
radio_float_t sum;
|
||||
radio_float_t var;
|
||||
|
||||
} sl_var_t;
|
||||
|
||||
typedef struct _sl_minmax_t
|
||||
{
|
||||
uint32_t L;
|
||||
uint32_t N;
|
||||
radio_float_t P;
|
||||
radio_float_t *pU;
|
||||
radio_float_t *pU_last;
|
||||
uint32_t *pP;
|
||||
uint32_t *pP_last;
|
||||
radio_float_t max;
|
||||
radio_float_t mode;
|
||||
|
||||
} sl_minmax_t;
|
||||
|
||||
typedef struct _map_t
|
||||
{
|
||||
radio_float_t mag, phi;
|
||||
cpx_t rect;
|
||||
uint32_t sym;
|
||||
|
||||
} map_t;
|
||||
|
||||
typedef struct _sym_map_t
|
||||
{
|
||||
uint32_t nBitsPerSym, num_const, type;
|
||||
uint32_t mask, sym_last;
|
||||
radio_float_t Es, Eb, R2, R4, Pref;
|
||||
map_t **ppMapTbl, *pMapTbl;
|
||||
radio_float_t iq_step, iq_max;
|
||||
uint32_t iq_side_len;
|
||||
|
||||
} sym_map_t;
|
||||
|
||||
typedef struct _per_sym_stat_t
|
||||
{
|
||||
uint32_t count;
|
||||
radio_float_t p, var_err_mag, var_err_phi;
|
||||
sl_var_t sl_err_mag, sl_err_phi;
|
||||
|
||||
} per_sym_stat_t;
|
||||
|
||||
typedef struct _sym_stat_t
|
||||
{
|
||||
uint32_t sym_cnt, num_const;
|
||||
per_sym_stat_t *pPerSymStat;
|
||||
|
||||
|
||||
} sym_stat_t;
|
||||
|
||||
typedef struct _sym_err_t
|
||||
{
|
||||
radio_float_t err_mag, err_phi;
|
||||
radio_float_t mag, phi, hard_mag;
|
||||
cpx_t err, hard_sym, soft_sym;
|
||||
|
||||
} sym_err_t;
|
||||
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// Interpolation
|
||||
// --------------------------------------------------------------
|
||||
typedef struct _fir_cpx_t
|
||||
{
|
||||
uint32_t N, r, w;
|
||||
cpx_t *pX;
|
||||
|
||||
} fir_cpx_t;
|
||||
|
||||
typedef struct _fdly_t
|
||||
{
|
||||
int Nf;
|
||||
radio_float_t *hf, *statef;
|
||||
} fdly_t;
|
||||
|
||||
typedef struct _lgip_t
|
||||
{
|
||||
int N, bufsize;
|
||||
rbuf_t rbuf;
|
||||
} lgip_t;
|
||||
|
||||
typedef struct _lgip_cpx_t
|
||||
{
|
||||
cpx_t *pFifo;
|
||||
uint32_t N, L, w, r;
|
||||
|
||||
} lgip_cpx_t;
|
||||
|
||||
typedef struct _fir_pp_t
|
||||
{
|
||||
uint32_t N, M;
|
||||
radio_float_t **ppCoeff, *pState;
|
||||
|
||||
} fir_pp_t;
|
||||
|
||||
typedef struct _ppip_t
|
||||
{
|
||||
radio_float_t **ppCoeff, *pState;
|
||||
uint32_t N, M;
|
||||
rbuf_t rbuf;
|
||||
|
||||
} ppip_t;
|
||||
|
||||
typedef struct _ppip_cpx_t
|
||||
{
|
||||
cpx_t *pFifo;
|
||||
radio_float_t **ppCoeff;
|
||||
uint32_t N, L, M, w, r;
|
||||
|
||||
} ppip_cpx_t;
|
||||
|
||||
typedef struct _ppip_farrow_cpx_t
|
||||
{
|
||||
cpx_t *pFifo, *pH, *pB;
|
||||
radio_float_t **ppCoeff;
|
||||
uint32_t N, L, M, w, r;
|
||||
|
||||
} ppip_farrow_cpx_t;
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// Equalizer
|
||||
// --------------------------------------------------------------
|
||||
#if 0
|
||||
#define CEF_MODE_NOP 0
|
||||
#define CEF_MODE_CMA 1
|
||||
#define CEF_MODE_DD 2
|
||||
#define CEF_MODE_EQ_UPD 3
|
||||
|
||||
typedef struct _vcma_t
|
||||
{
|
||||
uint32_t L, M, N, m, init_latency_cnt;
|
||||
cpx_t *pZ, **ppY, *pC, *pX, *pU;
|
||||
radio_float_t b;
|
||||
|
||||
} vcma_t;
|
||||
|
||||
typedef struct _eq_cpx_t
|
||||
{
|
||||
uint32_t N;
|
||||
cpx_t *pX, *pW;
|
||||
|
||||
} eq_cpx_t;
|
||||
|
||||
typedef struct _cma_t
|
||||
{
|
||||
uint32_t N, M;
|
||||
eq_cpx_t eq;
|
||||
radio_float_t Px, Px_last;
|
||||
|
||||
} cma_t;
|
||||
|
||||
typedef struct _dfe_cpx_t
|
||||
{
|
||||
uint32_t N, N_ff, N_fb;
|
||||
eq_cpx_t eq;
|
||||
|
||||
} dfe_cpx_t;
|
||||
|
||||
typedef struct _cef_t
|
||||
{
|
||||
uint32_t N, M, mode;
|
||||
vcma_t vcma;
|
||||
eq_cpx_t eq;
|
||||
cpx_t *pW, *pW_offline, *pW_eq, *pX;
|
||||
radio_float_t R2;
|
||||
|
||||
} cef_t;
|
||||
|
||||
typedef struct _rls_t
|
||||
{
|
||||
uint32_t N, M;
|
||||
cpx_t *pX, *pW, *pZ, *pR, *pT;
|
||||
radio_float_t *R, *T, *T2, *z, *w, *x;
|
||||
|
||||
} rls_t;
|
||||
#endif
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// Frame Types
|
||||
// --------------------------------------------------------------
|
||||
typedef struct _frame_hdr_t
|
||||
{
|
||||
uint8_t preamble[2];
|
||||
uint32_t prn_state;
|
||||
uint16_t crc16;
|
||||
uint16_t type;
|
||||
uint16_t length;
|
||||
|
||||
} frame_hdr_t;
|
||||
|
||||
typedef struct _frame_t
|
||||
{
|
||||
frame_hdr_t hdr;
|
||||
uint8_t data[FRAME_NUM_BYTES_PER_FRAME];
|
||||
|
||||
} frame_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
// --------------------------------------------------------------
|
||||
// Real Functions
|
||||
// --------------------------------------------------------------
|
||||
radio_float_t dabs(radio_float_t x);
|
||||
radio_float_t dsign(radio_float_t x);
|
||||
radio_float_t dmod(radio_float_t x, radio_float_t y);
|
||||
radio_float_t dmax(radio_float_t x, radio_float_t y);
|
||||
radio_float_t dmin(radio_float_t x, radio_float_t y);
|
||||
radio_float_t dclamp(radio_float_t x, radio_float_t limit_low, radio_float_t limit_high);
|
||||
radio_float_t powerDB(radio_float_t v1, radio_float_t preScale);
|
||||
float fsum(float *pSrc, int len);
|
||||
float fmean(float *pSrc, int len);
|
||||
radio_float_t dsum(radio_float_t *pSrc, int len);
|
||||
radio_float_t dmean(radio_float_t *pSrc, int len);
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// Complex Functions
|
||||
// --------------------------------------------------------------
|
||||
cpx_t CpxConjS(cpx_t v1);
|
||||
cpx_t CpxAddS(cpx_t v1, cpx_t v2);
|
||||
cpx_t CpxSubS(cpx_t v1, cpx_t v2);
|
||||
cpx_t CpxMulS(cpx_t v1, cpx_t v2);
|
||||
cpx_t CpxScaleRealS(cpx_t v1, radio_float_t v2);
|
||||
cpx_t CpxScaleComplexS(cpx_t x, cpx_t gain);
|
||||
cpx_t CpxFromReal(radio_float_t v1);
|
||||
cpx_t Cpx(radio_float_t real, radio_float_t imag);
|
||||
cpx_t CpxMinS(cpx_t x1, cpx_t x2);
|
||||
cpx_t CpxMaxS(cpx_t x1, cpx_t x2);
|
||||
radio_float_t CpxMagS(cpx_t v1);
|
||||
radio_float_t CpxPhiS(cpx_t v1);
|
||||
radio_float_t cpxPowerDB(cpx_t v1, radio_float_t preScale);
|
||||
void CpxCopy(cpx_t *pSrc, cpx_t *pDst, uint32_t len);
|
||||
void CpxConj(cpx_t *pSrcDst, uint32_t len);
|
||||
void CpxAdd(cpx_t *pSrc, cpx_t *pSrcDst, uint32_t len);
|
||||
void CpxSub(cpx_t *pSrc, cpx_t *pSrcDst, uint32_t len);
|
||||
void CpxMul(cpx_t *pSrc, cpx_t *pSrcDst, uint32_t len);
|
||||
radio_float_t CpxMag(cpx_t *pSrc);
|
||||
radio_float_t CpxPhi(cpx_t *pSrc);
|
||||
cpx_t csum(cpx_t *pSrc, int len);
|
||||
cpx_t cmean(cpx_t *pSrc, int len);
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// NCO
|
||||
// --------------------------------------------------------------
|
||||
void NCO_Init(nco_t *pObj, radio_float_t omega, radio_float_t phi, uint32_t tbl_size);
|
||||
void NCO_Free(nco_t *pObj);
|
||||
void NCO_ModPhi(nco_t *pObj, radio_float_t dPhi);
|
||||
void NCO_ModOmega(nco_t *pObj, radio_float_t dOmega);
|
||||
radio_float_t NCO_GetOmega(nco_t *pObj);
|
||||
void NCO_Process(nco_t *pObj);
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// Mixer
|
||||
// --------------------------------------------------------------
|
||||
cpx_t NCO_MixComplexS(nco_t *pObj, cpx_t *pSrc, cpx_t gain);
|
||||
cpx_t NCO_MixRealS(nco_t *pObj, radio_float_t src, radio_float_t gain);
|
||||
radio_float_t NCO_MixComplexRealS(nco_t *pObj, cpx_t *pSrc, cpx_t gain);
|
||||
void NCO_MixComplex(nco_t *pObj, cpx_t *pSrc, cpx_t *pDst, cpx_t gain);
|
||||
void NCO_MixReal(nco_t *pObj, radio_float_t src, cpx_t *pDst, radio_float_t gain);
|
||||
radio_float_t NCO_MixComplexReal(nco_t *pObj, cpx_t *pSrc, cpx_t gain);
|
||||
void NCO_MixComplexV(nco_t *pObj, cpx_t *pSrc, cpx_t *pDst, cpx_t gain, uint32_t len);
|
||||
void NCO_MixRealV(nco_t *pObj, radio_float_t *pSrc, cpx_t *pDst, radio_float_t gain, uint32_t len);
|
||||
void NCO_MixComplexRealV(nco_t *pObj, cpx_t *pSrc, radio_float_t *pDst, cpx_t gain, uint32_t len);
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// Synchronization
|
||||
// --------------------------------------------------------------
|
||||
#if 0
|
||||
void Clkgen_Init(clkgen_t *pObj);
|
||||
int Clkgen_GetPulse(clkgen_t *pObj, nco_t *pNCO);
|
||||
int Clkgen_GetClock(clkgen_t *pObj);
|
||||
|
||||
void SamplerInit(sampler_t *pObj, int divide);
|
||||
int SamplerIsSample(sampler_t *pObj);
|
||||
void SamplerUpdate(sampler_t *pObj);
|
||||
|
||||
void STRGardnerInit(str_t *pObj);
|
||||
radio_float_t STRGardnerProcess(str_t *pObj, cpx_t x);
|
||||
|
||||
void LeadLagInit(lead_lag_filter_t *pObj, radio_float_t lead_gain, radio_float_t lag_gain, radio_float_t ic_lag);
|
||||
void LeadLagSetGainLead(lead_lag_filter_t *pObj, radio_float_t gain);
|
||||
void LeadLagSetGainLag(lead_lag_filter_t *pObj, radio_float_t gain);
|
||||
radio_float_t LeadLagProcess(lead_lag_filter_t *pObj, radio_float_t x);
|
||||
|
||||
radio_float_t PhaseErrQPSK(cpx_t x);
|
||||
radio_float_t PhaseErr(cpx_t x, radio_float_t pstep, radio_float_t poffset);
|
||||
#endif
|
||||
// --------------------------------------------------------------
|
||||
// Sliding Statistics
|
||||
// --------------------------------------------------------------
|
||||
void SlidingMeanInit(sl_mean_t *pObj, int N);
|
||||
void SlidingMeanFree(sl_mean_t *pObj);
|
||||
radio_float_t SlidingMeanProcess(sl_mean_t *pObj, radio_float_t x);
|
||||
void SlidingMeanProcessV(sl_mean_t *pObj, radio_float_t *pX, uint32_t len);
|
||||
radio_float_t SlidingMeanGet(sl_mean_t *pObj);
|
||||
|
||||
void SlidingVarInit(sl_var_t *pObj, int Npwr, int Nmean);
|
||||
void SlidingVarFree(sl_var_t *pObj);
|
||||
radio_float_t SlidingVarProcess(sl_var_t *pObj, radio_float_t x);
|
||||
void SlidingVarProcessV(sl_var_t *pObj, radio_float_t *pX, uint32_t len);
|
||||
radio_float_t SlidingVarGet(sl_var_t *pObj);
|
||||
radio_float_t SlidingVarGetPowerDB(sl_var_t *pObj, radio_float_t preScale);
|
||||
|
||||
void SlidingMinMaxInit(sl_minmax_t *pObj, uint32_t L, radio_float_t P, radio_float_t mode);
|
||||
void SlidingMinMaxFree(sl_minmax_t *pObj);
|
||||
radio_float_t SlidingMinMaxProcess(sl_minmax_t *pObj, radio_float_t x);
|
||||
void SlidingMinMaxProcessV(sl_minmax_t *pObj, radio_float_t *pX, uint32_t len);
|
||||
radio_float_t SlidingMinMaxGet(sl_minmax_t *pObj);
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// RingBuffer
|
||||
// --------------------------------------------------------------
|
||||
void RBufInit(rbuf_t *pObj, int delay);
|
||||
void RBufFree(rbuf_t *pObj);
|
||||
void RBufPut(rbuf_t *pObj, radio_float_t x);
|
||||
radio_float_t RBufGet(rbuf_t *pObj);
|
||||
radio_float_t RBufGetAfter(rbuf_t *pObj, int delay);
|
||||
radio_float_t RBufGetAt(rbuf_t *pObj, int index);
|
||||
void FifoInit(fifo_t *pObj, uint32_t max_size);
|
||||
void FifoFree(fifo_t *pObj);
|
||||
uint32_t FifoSize(fifo_t *pObj);
|
||||
uint32_t FifoSizeMax(fifo_t *pObj);
|
||||
uint32_t FifoFront(fifo_t *pObj);
|
||||
uint32_t FifoBack(fifo_t *pObj);
|
||||
void FifoPushBack(fifo_t *pObj, uint32_t item);
|
||||
void FifoPushFront(fifo_t *pObj, uint32_t item);
|
||||
void FifoPopBack(fifo_t *pObj);
|
||||
void FifoPopFront(fifo_t *pObj);
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// Interpolation
|
||||
// --------------------------------------------------------------
|
||||
void FDly_Init(fdly_t *pObj, int order);
|
||||
void FDly_Free(fdly_t *pObj);
|
||||
void FDly_CalcCoeff(fdly_t *pObj, radio_float_t delay);
|
||||
radio_float_t FDly_Process(fdly_t *pObj, radio_float_t x);
|
||||
|
||||
void LGIpInit(lgip_t *pObj, int order, int bufsize);
|
||||
void LGIpFree(lgip_t *pObj);
|
||||
radio_float_t LGIpProcess(lgip_t *pObj, radio_float_t x, int m, radio_float_t mu);
|
||||
|
||||
void LGCpxIpInit(lgip_cpx_t *pObj, int order);
|
||||
void LGCpxIpFree(lgip_cpx_t *pObj);
|
||||
cpx_t LGCpxIpProcess(lgip_cpx_t *pObj, cpx_t x, int m, radio_float_t mu);
|
||||
|
||||
radio_float_t PolyPhaseSRRCInit(fir_pp_t *pObj, radio_float_t fa, radio_float_t tsym, radio_float_t alpha, uint32_t N, uint32_t M);
|
||||
void PolyPhaseSRRCFree(fir_pp_t *pObj);
|
||||
uint32_t PolyPhaseSRRCProcess(fir_pp_t *pObj, radio_float_t mu, radio_float_t *pX, radio_float_t *pY, uint32_t len);
|
||||
|
||||
radio_float_t PolyPhaseIpInit(ppip_t *pObj, radio_float_t fa, radio_float_t tsym, radio_float_t alpha, uint32_t N, uint32_t M);
|
||||
void PolyPhaseIpFree(ppip_t *pObj);
|
||||
radio_float_t PolyPhaseIpProcess(ppip_t *pObj, radio_float_t x, int m, radio_float_t mu);
|
||||
|
||||
radio_float_t PolyPhaseCpxIpInit(ppip_cpx_t *pObj, radio_float_t fa, radio_float_t tsym, radio_float_t alpha, uint32_t N, uint32_t M);
|
||||
void PolyPhaseCpxIpFree(ppip_cpx_t *pObj);
|
||||
cpx_t PolyPhaseCpxIpProcess(ppip_cpx_t *pObj, cpx_t x, int32_t m, radio_float_t mu);
|
||||
|
||||
void FarrowPPIPCpxInit(ppip_farrow_cpx_t *pObj, uint32_t M, uint32_t N);
|
||||
void FarrowPPIPCpxFree(ppip_farrow_cpx_t *pObj);
|
||||
cpx_t FarrowPPIPCpxProcess(ppip_farrow_cpx_t *pObj, cpx_t x, int32_t m, radio_float_t mu);
|
||||
|
||||
void FirCpxInit(fir_cpx_t *pObj, uint32_t N);
|
||||
void FirCpxFree(fir_cpx_t *pObj);
|
||||
void FirCpxProcessReal(fir_cpx_t *pObj, radio_float_t *pW, cpx_t *pSrc, cpx_t *pDst, uint32_t downSampleFactor, uint32_t len);
|
||||
void FirCpxProcessComplex(fir_cpx_t *pObj, cpx_t *pW, cpx_t *pSrc, cpx_t *pDst, uint32_t len);
|
||||
|
||||
void SymErrInit(sym_err_t *pObj);
|
||||
void SymStatInit(sym_stat_t *pObj, uint32_t nBitsPerSym);
|
||||
void SymStatFree(sym_stat_t *pObj);
|
||||
void SymStatUpDate(sym_stat_t *pObj, uint8_t sym, sym_err_t *pSym_err);
|
||||
void SymStatPrint(sym_stat_t *pObj);
|
||||
|
||||
void SymMapInit(sym_map_t *pObj, uint32_t nBitsPerSym, uint32_t type);
|
||||
void SymMapFree(sym_map_t *pObj);
|
||||
radio_float_t SymMapGetModulus(sym_map_t *pObj, cpx_t x);
|
||||
map_t SymMapGetSymbol(sym_map_t *pObj, cpx_t x);
|
||||
uint8_t SymMapDecode(sym_map_t *pObj, cpx_t x, sym_err_t *pErr);
|
||||
cpx_t SymMapEncode(sym_map_t *pObj, uint8_t bit);
|
||||
|
||||
#if 0
|
||||
void CMAInit(cma_t *pObj, uint32_t ntaps, uint32_t nSamplesPerSym);
|
||||
void CMAFree(cma_t *pObj);
|
||||
cpx_t CMAProcess(cma_t *pObj, cpx_t x);
|
||||
cpx_t CMAGodard(cpx_t sym_s_eq, radio_float_t mag_h, radio_float_t R2);
|
||||
radio_float_t CMATrain(cma_t *pObj, cpx_t y, cpx_t d, radio_float_t mu);
|
||||
|
||||
void EQComplexInit(eq_cpx_t *pObj, uint32_t N);
|
||||
void EQComplexFree(eq_cpx_t *pObj);
|
||||
cpx_t EQComplexProcess(eq_cpx_t *pObj, cpx_t x);
|
||||
|
||||
void DFEComplexInit(dfe_cpx_t *pObj, uint32_t K);
|
||||
void DFEComplexFree(dfe_cpx_t *pObj);
|
||||
cpx_t DFEComplexProcess(dfe_cpx_t *pObj, cpx_t xs, cpx_t xh);
|
||||
void DFEAdaptLMS(dfe_cpx_t *pObj, cpx_t e, radio_float_t mu);
|
||||
|
||||
void CoeffComplexUnitAt(cpx_t *pW, uint32_t N, uint32_t dly);
|
||||
void CoeffComplexConv(cpx_t *pSrc, cpx_t *pDst, uint32_t N, uint32_t dly);
|
||||
|
||||
void LMSUpdateWeigths(eq_cpx_t *pObj, cpx_t e, radio_float_t mu);
|
||||
|
||||
void RLSInit(rls_t *pObj, uint32_t N, uint32_t M);
|
||||
void RLSFree(rls_t *pObj);
|
||||
cpx_t RLSProcess(rls_t *pObj, radio_float_t i, radio_float_t q);
|
||||
radio_float_t RLSUpdate(rls_t *pObj, radio_float_t rho, radio_float_t mu, radio_float_t y, radio_float_t d);
|
||||
#endif
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// Data Functions
|
||||
// --------------------------------------------------------------
|
||||
uint32_t Scramble(uint8_t *pSrcDst, uint32_t state, uint32_t poly, uint32_t len);
|
||||
uint32_t FrameCalcNumStreamBytes(uint32_t len_raw);
|
||||
uint32_t FrameFormat(uint8_t *pRaw, uint8_t *pFormatted, uint32_t len_raw, uint32_t *pPrn_state, uint16_t frame_type);
|
||||
uint32_t FrameDeformat(uint8_t *pFormatted, uint8_t *pRaw, uint32_t len_formatted, uint16_t frame_type);
|
||||
uint32_t FrameSerialize(uint8_t *pSrc, uint8_t *pDst, uint32_t nBitsPerSym, uint32_t srclen);
|
||||
uint32_t FrameDeSerialize(uint8_t *pSrc, uint8_t *pDst, uint32_t nBitsPerSym, uint32_t srclen, uint16_t frame_type);
|
||||
uint32_t FrameSymbolsMap(uint8_t *pBits, cpx_t *pSym, uint32_t nBitsPerSym, uint32_t num_syms, uint32_t type);
|
||||
uint32_t FrameSymbolsDemap(cpx_t *pSym, uint8_t *pBits, uint32_t nBitsPerSym, uint32_t num_syms, uint32_t type);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
// --------------------------------------------------------------
|
||||
#endif // RADIO_H
|
||||
Executable
+28
@@ -0,0 +1,28 @@
|
||||
// --------------------------------------------------------------
|
||||
#ifndef RADIO_TYPES_H
|
||||
#define RADIO_TYPES_H
|
||||
|
||||
#include <stdint.h>
|
||||
// --------------------------------------------------------------
|
||||
// RF Types
|
||||
// --------------------------------------------------------------
|
||||
#ifndef PI
|
||||
#define PI 3.1415926535897932384626433832795
|
||||
#endif
|
||||
|
||||
#define RADIO_POWER_EPS (1E-12)
|
||||
|
||||
#define MAP_MODE_PSK 0
|
||||
#define MAP_MODE_QAM 1
|
||||
#define MAP_MODE_PIN 2
|
||||
|
||||
#ifndef radio_float_t
|
||||
#define radio_float_t float
|
||||
#endif
|
||||
|
||||
typedef uint32_t symbol_t;
|
||||
typedef uint8_t data_t;
|
||||
|
||||
|
||||
// --------------------------------------------------------------
|
||||
#endif // RADIO_TYPES_H
|
||||
@@ -0,0 +1,83 @@
|
||||
// --------------------------------------------------------------
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include "radio_types.h"
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// Real Functions
|
||||
// --------------------------------------------------------------
|
||||
radio_float_t dabs(radio_float_t x)
|
||||
{
|
||||
if (x < 0)
|
||||
return -x;
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
radio_float_t dsign(radio_float_t x)
|
||||
{
|
||||
if (x < 0)
|
||||
return -1.0;
|
||||
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
radio_float_t dmod(radio_float_t x, radio_float_t y)
|
||||
{
|
||||
int xy;
|
||||
|
||||
if (y == 0)
|
||||
return x;
|
||||
|
||||
xy = (int)floor(x/y);
|
||||
|
||||
return dsign(y)*(radio_float_t)fabs(x - y*(radio_float_t)xy);
|
||||
}
|
||||
|
||||
radio_float_t dmax(radio_float_t x, radio_float_t y)
|
||||
{
|
||||
if (x > y)
|
||||
return x;
|
||||
|
||||
return y;
|
||||
}
|
||||
|
||||
radio_float_t dmin(radio_float_t x, radio_float_t y)
|
||||
{
|
||||
if (x < y)
|
||||
return x;
|
||||
|
||||
return y;
|
||||
}
|
||||
|
||||
radio_float_t dclamp(radio_float_t x, radio_float_t limit_low, radio_float_t limit_high)
|
||||
{
|
||||
return dmin(dmax(x, limit_low), limit_high);
|
||||
}
|
||||
|
||||
radio_float_t powerDB(radio_float_t v1, radio_float_t preScale)
|
||||
{
|
||||
return (radio_float_t)(10*log10(RADIO_POWER_EPS + v1*preScale));
|
||||
}
|
||||
|
||||
radio_float_t dsum(radio_float_t *pSrc, int len)
|
||||
{
|
||||
radio_float_t sum = 0;
|
||||
|
||||
while(len--)
|
||||
sum += *(pSrc++);
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
radio_float_t dmean(radio_float_t *pSrc, int len)
|
||||
{
|
||||
return dsum(pSrc, len)/len;
|
||||
}
|
||||
|
||||
radio_float_t dpow(radio_float_t base, radio_float_t exp)
|
||||
{
|
||||
return (radio_float_t)pow(base, exp);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------
|
||||
@@ -0,0 +1,31 @@
|
||||
// --------------------------------------------------------------
|
||||
#ifndef REAL_H
|
||||
#define REAL_H
|
||||
|
||||
#include "radio_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
// --------------------------------------------------------------
|
||||
// Real Functions
|
||||
// --------------------------------------------------------------
|
||||
// Scalar
|
||||
radio_float_t dabs(radio_float_t x);
|
||||
radio_float_t dsign(radio_float_t x);
|
||||
radio_float_t dmod(radio_float_t x, radio_float_t y);
|
||||
radio_float_t dmax(radio_float_t x, radio_float_t y);
|
||||
radio_float_t dmin(radio_float_t x, radio_float_t y);
|
||||
radio_float_t dclamp(radio_float_t x, radio_float_t limit_low, radio_float_t limit_high);
|
||||
radio_float_t powerDB(radio_float_t v1, radio_float_t preScale);
|
||||
radio_float_t dsum(radio_float_t *pSrc, int len);
|
||||
radio_float_t dmean(radio_float_t *pSrc, int len);
|
||||
radio_float_t dpow(radio_float_t base, radio_float_t exp);
|
||||
|
||||
// --------------------------------------------------------------
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif // __cplusplus
|
||||
|
||||
// --------------------------------------------------------------
|
||||
#endif // REAL_H
|
||||
@@ -0,0 +1,168 @@
|
||||
// --------------------------------------------------------------
|
||||
#include <string.h>
|
||||
#include <malloc.h>
|
||||
#include "ringbuf.h"
|
||||
|
||||
// --------------------------------------------------------------
|
||||
void RBufInit(rbuf_t *pObj, uint32_t size)
|
||||
{
|
||||
pObj->ir = 0;
|
||||
pObj->iw = 0;
|
||||
pObj->dist = 0;
|
||||
|
||||
pObj->size = size;
|
||||
pObj->pData = (radio_float_t*)malloc(size*sizeof(radio_float_t));
|
||||
memset(pObj->pData, 0, size*sizeof(radio_float_t));
|
||||
}
|
||||
|
||||
void RBufFree(rbuf_t *pObj)
|
||||
{
|
||||
if (pObj->pData)
|
||||
free(pObj->pData);
|
||||
|
||||
pObj->pData = NULL;
|
||||
pObj->size = 0;
|
||||
}
|
||||
|
||||
void RBufPut(rbuf_t *pObj, radio_float_t x)
|
||||
{
|
||||
(pObj->iw)++;
|
||||
if (pObj->iw >= pObj->size)
|
||||
pObj->iw = 0;
|
||||
|
||||
pObj->pData[pObj->iw] = x;
|
||||
pObj->dist++;
|
||||
|
||||
}
|
||||
|
||||
radio_float_t RBufGet(rbuf_t *pObj)
|
||||
{
|
||||
radio_float_t y;
|
||||
y = pObj->pData[(pObj->ir)++];
|
||||
|
||||
if (pObj->ir >= pObj->size)
|
||||
pObj->ir = 0;
|
||||
|
||||
pObj->dist--;
|
||||
return y;
|
||||
}
|
||||
|
||||
radio_float_t RBufGetAfter(rbuf_t *pObj, int32_t delay)
|
||||
{
|
||||
pObj->ir = (pObj->iw-delay)%pObj->size;
|
||||
if (pObj->ir < 0)
|
||||
pObj->ir += pObj->size;
|
||||
|
||||
pObj->dist = delay;
|
||||
return pObj->pData[pObj->ir];
|
||||
}
|
||||
|
||||
radio_float_t RBufGetAt(rbuf_t *pObj, uint32_t index)
|
||||
{
|
||||
if (index < 0)
|
||||
index = 0;
|
||||
pObj->ir = (index)%pObj->size;
|
||||
pObj->dist = pObj->iw-pObj->ir;
|
||||
if (pObj->dist < 0)
|
||||
pObj->dist += pObj->size;
|
||||
|
||||
return pObj->pData[pObj->ir];
|
||||
}
|
||||
|
||||
void FifoInit(fifo_t *pObj, uint32_t max_size)
|
||||
{
|
||||
pObj->size_max = max_size;
|
||||
pObj->size = 0;
|
||||
pObj->iw = (uint32_t)0;
|
||||
pObj->ir = (uint32_t)0;
|
||||
|
||||
pObj->pData = (uint32_t*)malloc(max_size*sizeof(uint32_t));
|
||||
memset(pObj->pData, 0, max_size*sizeof(uint32_t));
|
||||
}
|
||||
|
||||
void FifoFree(fifo_t *pObj)
|
||||
{
|
||||
if (pObj->pData)
|
||||
free(pObj->pData);
|
||||
|
||||
pObj->pData = NULL;
|
||||
pObj->size_max = 0;
|
||||
pObj->size = 0;
|
||||
}
|
||||
|
||||
uint32_t FifoSize(fifo_t *pObj)
|
||||
{
|
||||
return pObj->size;
|
||||
}
|
||||
|
||||
uint32_t FifoSizeMax(fifo_t *pObj)
|
||||
{
|
||||
return pObj->size_max;
|
||||
}
|
||||
|
||||
uint32_t FifoFront(fifo_t *pObj)
|
||||
{
|
||||
return pObj->pData[pObj->ir];
|
||||
}
|
||||
|
||||
uint32_t FifoBack(fifo_t *pObj)
|
||||
{
|
||||
return pObj->pData[pObj->iw];
|
||||
}
|
||||
|
||||
void FifoPushBack(fifo_t *pObj, uint32_t item)
|
||||
{
|
||||
pObj->pData[pObj->iw++] = item;
|
||||
if (pObj->iw >= pObj->size_max)
|
||||
pObj->iw = 0;
|
||||
|
||||
if (pObj->size < pObj->size_max)
|
||||
{
|
||||
pObj->size++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (++pObj->ir >= pObj->size_max)
|
||||
pObj->ir = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void FifoPushFront(fifo_t *pObj, uint32_t item)
|
||||
{
|
||||
pObj->ir--;
|
||||
if (pObj->ir >= pObj->size_max)
|
||||
pObj->ir = 0;
|
||||
|
||||
pObj->pData[pObj->ir] = item;
|
||||
if (pObj->size < pObj->size_max)
|
||||
{
|
||||
pObj->size++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (--pObj->iw >= pObj->size_max)
|
||||
pObj->iw = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void FifoPopBack(fifo_t *pObj)
|
||||
{
|
||||
pObj->iw--;
|
||||
if (pObj->iw >= pObj->size_max)
|
||||
pObj->iw = 0;
|
||||
|
||||
if (pObj->size > 0)
|
||||
pObj->size--;
|
||||
}
|
||||
|
||||
void FifoPopFront(fifo_t *pObj)
|
||||
{
|
||||
pObj->ir++;
|
||||
if (pObj->ir >= pObj->size_max)
|
||||
pObj->ir = 0;
|
||||
|
||||
if (pObj->size > 0)
|
||||
pObj->size--;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------
|
||||
@@ -0,0 +1,62 @@
|
||||
// --------------------------------------------------------------
|
||||
#ifndef RINGBUF_H
|
||||
#define RINGBUF_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "radio_types.h"
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// Types
|
||||
// --------------------------------------------------------------
|
||||
typedef struct _rbuf_t
|
||||
{
|
||||
uint32_t size, iw, ir, dist;
|
||||
radio_float_t *pData;
|
||||
|
||||
} rbuf_t;
|
||||
|
||||
typedef struct _fifo_t
|
||||
{
|
||||
uint32_t size_max;
|
||||
uint32_t size;
|
||||
uint32_t ir;
|
||||
uint32_t iw;
|
||||
uint32_t *pData;
|
||||
|
||||
} fifo_t;
|
||||
|
||||
// --------------------------------------------------------------
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// Functions
|
||||
// --------------------------------------------------------------
|
||||
// RingBuffer
|
||||
void RBufInit(rbuf_t *pObj, uint32_t size);
|
||||
void RBufFree(rbuf_t *pObj);
|
||||
void RBufPut(rbuf_t *pObj, radio_float_t x);
|
||||
radio_float_t RBufGet(rbuf_t *pObj);
|
||||
radio_float_t RBufGetAfter(rbuf_t *pObj, int32_t delay);
|
||||
radio_float_t RBufGetAt(rbuf_t *pObj, uint32_t index);
|
||||
|
||||
// Fifo
|
||||
void FifoInit(fifo_t *pObj, uint32_t max_size);
|
||||
void FifoFree(fifo_t *pObj);
|
||||
uint32_t FifoSize(fifo_t *pObj);
|
||||
uint32_t FifoSizeMax(fifo_t *pObj);
|
||||
uint32_t FifoFront(fifo_t *pObj);
|
||||
uint32_t FifoBack(fifo_t *pObj);
|
||||
void FifoPushBack(fifo_t *pObj, uint32_t item);
|
||||
void FifoPushFront(fifo_t *pObj, uint32_t item);
|
||||
void FifoPopBack(fifo_t *pObj);
|
||||
void FifoPopFront(fifo_t *pObj);
|
||||
|
||||
// --------------------------------------------------------------
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif // __cplusplus
|
||||
|
||||
// --------------------------------------------------------------
|
||||
#endif // RINGBUF_H
|
||||
Executable
+245
@@ -0,0 +1,245 @@
|
||||
// --------------------------------------------------------------
|
||||
#include <malloc.h>
|
||||
#include <string.h>
|
||||
#include "statistics.h"
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// Sliding Mean
|
||||
// --------------------------------------------------------------
|
||||
void SlidingMeanInit(sl_mean_t *pObj, int N)
|
||||
{
|
||||
RBufInit(&pObj->buf, N);
|
||||
pObj->Nr = (radio_float_t)1.0/N;
|
||||
pObj->mean = 0.0;
|
||||
pObj->sum = 0.0;
|
||||
pObj->normalize_count = N;
|
||||
}
|
||||
|
||||
void SlidingMeanFree(sl_mean_t *pObj)
|
||||
{
|
||||
RBufFree(&pObj->buf);
|
||||
}
|
||||
|
||||
radio_float_t SlidingMeanProcess(sl_mean_t *pObj, radio_float_t x)
|
||||
{
|
||||
uint32_t i;
|
||||
radio_float_t last;
|
||||
|
||||
last = RBufGetAfter(&pObj->buf, pObj->buf.size-1);
|
||||
RBufPut(&pObj->buf, x);
|
||||
pObj->sum += (x - last);
|
||||
pObj->mean = pObj->sum*pObj->Nr;
|
||||
|
||||
if (--pObj->normalize_count == 0)
|
||||
{
|
||||
pObj->normalize_count = pObj->buf.size;
|
||||
pObj->sum = 0;
|
||||
for (i=0; i < pObj->buf.size; i++)
|
||||
{
|
||||
pObj->sum += pObj->buf.pData[i];
|
||||
}
|
||||
}
|
||||
return pObj->mean;
|
||||
}
|
||||
|
||||
void SlidingMeanProcessV(sl_mean_t *pObj, radio_float_t *pX, uint32_t len)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
for (i=0; i < len; i++)
|
||||
SlidingMeanProcess(pObj, *(pX++));
|
||||
}
|
||||
|
||||
radio_float_t SlidingMeanGet(sl_mean_t *pObj)
|
||||
{
|
||||
return pObj->mean;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// Sliding Variance
|
||||
// --------------------------------------------------------------
|
||||
void SlidingVarInit(sl_var_t *pObj, int Npwr, int Nmean)
|
||||
{
|
||||
RBufInit(&pObj->buf, Npwr);
|
||||
SlidingMeanInit(&pObj->sl_mean, Nmean);
|
||||
pObj->Nr = (radio_float_t)1.0/Npwr;
|
||||
pObj->var = 0.0;
|
||||
pObj->sum = 0.0;
|
||||
pObj->normalize_count = Npwr;
|
||||
}
|
||||
|
||||
void SlidingVarFree(sl_var_t *pObj)
|
||||
{
|
||||
RBufFree(&pObj->buf);
|
||||
SlidingMeanFree(&pObj->sl_mean);
|
||||
}
|
||||
|
||||
radio_float_t SlidingVarProcess(sl_var_t *pObj, radio_float_t x)
|
||||
{
|
||||
uint32_t i;
|
||||
radio_float_t last, xm, mean, var;
|
||||
|
||||
last = RBufGetAfter(&pObj->buf, pObj->buf.size-1);
|
||||
mean = SlidingMeanProcess(&pObj->sl_mean, x);
|
||||
xm = x - mean;
|
||||
xm *= xm;
|
||||
RBufPut(&pObj->buf, xm);
|
||||
pObj->sum += (xm - last);
|
||||
|
||||
var = pObj->sum*pObj->Nr;
|
||||
if (var >= 0)
|
||||
pObj->var = var;
|
||||
|
||||
if (--pObj->normalize_count == 0)
|
||||
{
|
||||
pObj->normalize_count = pObj->buf.size;
|
||||
pObj->sum = 0;
|
||||
for (i=0; i < pObj->buf.size; i++)
|
||||
{
|
||||
pObj->sum += pObj->buf.pData[i];
|
||||
}
|
||||
}
|
||||
return pObj->var;
|
||||
}
|
||||
|
||||
void SlidingVarProcessV(sl_var_t *pObj, radio_float_t *pX, uint32_t len)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
for (i=0; i < len; i++)
|
||||
SlidingVarProcess(pObj, *(pX++));
|
||||
}
|
||||
|
||||
radio_float_t SlidingVarGet(sl_var_t *pObj)
|
||||
{
|
||||
return pObj->var;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// Sliding Min/Max
|
||||
// --------------------------------------------------------------
|
||||
void SlidingMinMaxInit(sl_minmax_t *pObj, uint32_t L, radio_float_t P, radio_float_t mode)
|
||||
{
|
||||
pObj->L = L;
|
||||
pObj->P = P;
|
||||
pObj->N = 0;
|
||||
pObj->max = 0;
|
||||
pObj->mode = mode;
|
||||
pObj->pP = (uint32_t*)malloc(L*sizeof(uint32_t));
|
||||
pObj->pU = (radio_float_t*)malloc(L*sizeof(radio_float_t));
|
||||
pObj->pP_last = (uint32_t*)malloc(L*sizeof(uint32_t));
|
||||
pObj->pU_last = (radio_float_t*)malloc(L*sizeof(radio_float_t));
|
||||
memset(pObj->pP, 0, L*sizeof(uint32_t));
|
||||
memset(pObj->pU, 0, L*sizeof(radio_float_t));
|
||||
memset(pObj->pP_last, 0, L*sizeof(uint32_t));
|
||||
memset(pObj->pU_last, 0, L*sizeof(radio_float_t));
|
||||
pObj->pU_last[1] = P;
|
||||
}
|
||||
|
||||
void SlidingMinMaxFree(sl_minmax_t *pObj)
|
||||
{
|
||||
if (pObj->pP)
|
||||
free(pObj->pP);
|
||||
|
||||
if (pObj->pU)
|
||||
free(pObj->pU);
|
||||
|
||||
if (pObj->pP_last)
|
||||
free(pObj->pP_last);
|
||||
|
||||
if (pObj->pU_last)
|
||||
free(pObj->pU_last);
|
||||
|
||||
pObj->pP = (uint32_t*)0;
|
||||
pObj->pU = (radio_float_t*)0;
|
||||
pObj->pP_last = (uint32_t*)0;
|
||||
pObj->pU_last = (radio_float_t*)0;
|
||||
}
|
||||
|
||||
// Sliding Min/Max based on MAXLIST-Algorithm, based on:
|
||||
// "AN EFFICIENT ALGORITHM FOR RUNNING MAX MIN CALCULATION", 1996, S.C. Douglas, University of Utah
|
||||
// Dependeding on 'mode' this algorithm calculates either minimum (mode = -1) or maximum (mode = +1)
|
||||
radio_float_t SlidingMinMaxProcess(sl_minmax_t *pObj, radio_float_t x)
|
||||
{
|
||||
uint32_t m;
|
||||
uint32_t i;
|
||||
uint32_t j;
|
||||
|
||||
x *= pObj->mode;
|
||||
|
||||
m = 1;
|
||||
if (pObj->pP_last[pObj->N] == pObj->L)
|
||||
{
|
||||
m = 0;
|
||||
pObj->pU_last[pObj->N] = pObj->P;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
while (x >= pObj->pU_last[i+1])
|
||||
{
|
||||
i++;
|
||||
}
|
||||
pObj->N = pObj->N - i + m;
|
||||
|
||||
for (j=1; j < pObj->N; j++)
|
||||
{
|
||||
pObj->pU[j+1] = pObj->pU_last[j+i];
|
||||
pObj->pP[j+1] = pObj->pP_last[j+i] + 1;
|
||||
}
|
||||
pObj->pU[pObj->N+1] = pObj->P;
|
||||
pObj->pU[1] = x;
|
||||
pObj->pP[1] = 1;
|
||||
pObj->max = pObj->pU[pObj->N];
|
||||
|
||||
i=0;
|
||||
while(pObj->pU[i] != pObj->P)
|
||||
{
|
||||
pObj->pU_last[i] = pObj->pU[i];
|
||||
pObj->pP_last[i] = pObj->pP[i];
|
||||
i++;
|
||||
}
|
||||
pObj->pU_last[i] = pObj->pU[i];
|
||||
pObj->pP_last[i] = pObj->pP[i];
|
||||
|
||||
return pObj->mode*pObj->max;
|
||||
}
|
||||
|
||||
radio_float_t SlidingMinMaxGet(sl_minmax_t *pObj)
|
||||
{
|
||||
return pObj->mode*pObj->max;
|
||||
}
|
||||
|
||||
void SlidingMinMaxProcessV(sl_minmax_t *pObj, radio_float_t *pX, uint32_t len)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
for (i=0; i < len; i++)
|
||||
{
|
||||
SlidingMinMaxProcess(pObj, pX[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------
|
||||
void TraceOpen(trace_t *pObj, char *pFilename)
|
||||
{
|
||||
pObj->pFile = fopen(pFilename, "w");
|
||||
}
|
||||
|
||||
void TraceClose(trace_t *pObj)
|
||||
{
|
||||
if (pObj->pFile)
|
||||
fclose(pObj->pFile);
|
||||
}
|
||||
|
||||
void TracePrint(trace_t *pObj, char *fmt, ... )
|
||||
{
|
||||
|
||||
va_list a_list;
|
||||
|
||||
if (!pObj->pFile)
|
||||
return;
|
||||
|
||||
va_start( a_list, fmt );
|
||||
|
||||
vfprintf(pObj->pFile, fmt, a_list);
|
||||
}
|
||||
Executable
+94
@@ -0,0 +1,94 @@
|
||||
// --------------------------------------------------------------
|
||||
#ifndef STATISTICS_H
|
||||
#define STATISTICS_H
|
||||
|
||||
#include <stdio.h> // Trace()
|
||||
#include <stdarg.h> // Trace()
|
||||
|
||||
#include "radio_types.h"
|
||||
#include "real.h"
|
||||
#include "ringbuf.h"
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// Types
|
||||
// --------------------------------------------------------------
|
||||
typedef struct _sl_mean_t
|
||||
{
|
||||
rbuf_t buf;
|
||||
uint32_t normalize_count;
|
||||
radio_float_t Nr;
|
||||
radio_float_t sum;
|
||||
radio_float_t element_max;
|
||||
radio_float_t mean;
|
||||
|
||||
} sl_mean_t;
|
||||
|
||||
typedef struct _sl_var_t
|
||||
{
|
||||
rbuf_t buf;
|
||||
uint32_t normalize_count;
|
||||
radio_float_t Nr;
|
||||
radio_float_t sum;
|
||||
radio_float_t var;
|
||||
sl_mean_t sl_mean;
|
||||
|
||||
} sl_var_t;
|
||||
|
||||
typedef struct _sl_minmax_t
|
||||
{
|
||||
uint32_t L;
|
||||
uint32_t N;
|
||||
radio_float_t P;
|
||||
radio_float_t *pU;
|
||||
radio_float_t *pU_last;
|
||||
uint32_t *pP;
|
||||
uint32_t *pP_last;
|
||||
radio_float_t max;
|
||||
radio_float_t mode;
|
||||
|
||||
} sl_minmax_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// Functions
|
||||
// --------------------------------------------------------------
|
||||
// Sliding Mean
|
||||
void SlidingMeanInit(sl_mean_t *pObj, int N);
|
||||
void SlidingMeanFree(sl_mean_t *pObj);
|
||||
radio_float_t SlidingMeanProcess(sl_mean_t *pObj, radio_float_t x);
|
||||
void SlidingMeanProcessV(sl_mean_t *pObj, radio_float_t *pX, uint32_t len);
|
||||
radio_float_t SlidingMeanGet(sl_mean_t *pObj);
|
||||
|
||||
// Sliding Variance
|
||||
void SlidingVarInit(sl_var_t *pObj, int Npwr, int Nmean);
|
||||
void SlidingVarFree(sl_var_t *pObj);
|
||||
radio_float_t SlidingVarProcess(sl_var_t *pObj, radio_float_t x);
|
||||
void SlidingVarProcessV(sl_var_t *pObj, radio_float_t *pX, uint32_t len);
|
||||
radio_float_t SlidingVarGet(sl_var_t *pObj);
|
||||
|
||||
// Sliding Min/Max
|
||||
void SlidingMinMaxInit(sl_minmax_t *pObj, uint32_t L, radio_float_t P, radio_float_t mode);
|
||||
void SlidingMinMaxFree(sl_minmax_t *pObj);
|
||||
radio_float_t SlidingMinMaxProcess(sl_minmax_t *pObj, radio_float_t x);
|
||||
void SlidingMinMaxProcessV(sl_minmax_t *pObj, radio_float_t *pX, uint32_t len);
|
||||
radio_float_t SlidingMinMaxGet(sl_minmax_t *pObj);
|
||||
|
||||
typedef struct _trace_t
|
||||
{
|
||||
FILE *pFile;
|
||||
} trace_t;
|
||||
|
||||
void TraceOpen(trace_t *pObj, char *pFilename);
|
||||
void TraceClose(trace_t *pObj);
|
||||
void TracePrint(trace_t *pObj, char *fmt, ... );
|
||||
|
||||
// --------------------------------------------------------------
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif // __cplusplus
|
||||
|
||||
// --------------------------------------------------------------
|
||||
#endif // STATISTICS_H
|
||||
@@ -0,0 +1,298 @@
|
||||
// --------------------------------------------------------------
|
||||
#include <stdio.h> // for SymStatPrint() remove later
|
||||
#include <string.h>
|
||||
#include <malloc.h>
|
||||
#include <math.h>
|
||||
#include "radio_types.h"
|
||||
#include "symbol.h"
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// Symbol demapper for receiver works on each symbol
|
||||
// --------------------------------------------------------------
|
||||
void SymMapInit(sym_map_t *pObj, uint32_t nBitsPerSym, uint32_t type)
|
||||
{
|
||||
cpx_t iq;
|
||||
uint32_t i, j, k, m, n, u, Ns, Nq, Nsq, map_idx_i, map_idx_q;
|
||||
radio_float_t phi, dphi, ii, qq, iii, qqq, temp, stepIQ;
|
||||
radio_float_t mag, E_m2, E_m2_c, E_m4;
|
||||
radio_float_t c_smma;
|
||||
cpx_t E_a4;
|
||||
int signI[4] = {+1, -1, -1, +1};
|
||||
int signQ[4] = {+1, +1, -1, -1};
|
||||
int even;
|
||||
pObj->nBitsPerSym = nBitsPerSym;
|
||||
pObj->num_const = 1;
|
||||
pObj->type = type;
|
||||
pObj->iq_step = 0;
|
||||
pObj->iq_max = 0;
|
||||
pObj->Pref = 0;
|
||||
E_a4 = Cpx(0,0);
|
||||
c_smma = (radio_float_t)1; // Tuning constant S-MMA
|
||||
for(k=0; k < nBitsPerSym; k++)
|
||||
{
|
||||
pObj->num_const *= 2;
|
||||
}
|
||||
pObj->pMapTbl = (map_t*)malloc(pObj->num_const*sizeof(map_t));
|
||||
pObj->ppMapTbl = NULL;
|
||||
|
||||
Ns = (uint32_t)sqrt((radio_float_t)pObj->num_const);
|
||||
Nq = pObj->num_const/4;
|
||||
Nsq = (uint32_t)sqrt((radio_float_t)Nq);
|
||||
stepIQ = (radio_float_t)sqrt(2.0)/(Ns-1);
|
||||
E_m2_c = E_m2 = E_m4 = 0;
|
||||
switch(type)
|
||||
{
|
||||
|
||||
case MAP_MODE_PSK:
|
||||
|
||||
pObj->Es = 1.0; // Symbol transmit power
|
||||
pObj->Eb = pObj->Es/nBitsPerSym;
|
||||
pObj->Pref = (radio_float_t)(1.0/sqrt(2.0));
|
||||
|
||||
dphi = 2*(radio_float_t)PI/pObj->num_const;
|
||||
phi = (radio_float_t)PI/pObj->num_const;
|
||||
|
||||
for (k=0; k < pObj->num_const; k++)
|
||||
{
|
||||
iq.real = (radio_float_t)cos(phi);
|
||||
iq.imag = (radio_float_t)sin(phi);
|
||||
pObj->pMapTbl[k].phi = (radio_float_t)CpxPhiS(iq);
|
||||
pObj->pMapTbl[k].mag = (radio_float_t)CpxMagS(iq);
|
||||
pObj->pMapTbl[k].rect = iq;
|
||||
phi += dphi;
|
||||
}
|
||||
break;
|
||||
|
||||
case MAP_MODE_QAM:
|
||||
pObj->Es = (radio_float_t)0.5*stepIQ*stepIQ;
|
||||
pObj->Eb = pObj->Es/nBitsPerSym;
|
||||
pObj->ppMapTbl = (map_t**)malloc(Ns*sizeof(map_t*));
|
||||
for (i=0; i< Ns; i++)
|
||||
pObj->ppMapTbl[i] = (map_t*)malloc(Ns*sizeof(map_t));
|
||||
|
||||
ii = (radio_float_t)(1.0/sqrt(2.0));
|
||||
pObj->iq_max = ii;
|
||||
qq = ii;
|
||||
even = 1;
|
||||
|
||||
k = 0;
|
||||
for (m=0; m < Nsq; m++)
|
||||
{
|
||||
for (n=0; n < Nsq; n++)
|
||||
{
|
||||
iii = ii;
|
||||
qqq = qq;
|
||||
for (j=0; j < 4; j++)
|
||||
{
|
||||
u = Nq*j+k;
|
||||
iq.real = iii*signI[j];
|
||||
iq.imag = qqq*signQ[j];
|
||||
mag = (radio_float_t)CpxMagS(iq);
|
||||
phi = (radio_float_t)CpxPhiS(iq);
|
||||
pObj->pMapTbl[u].mag = mag;
|
||||
pObj->pMapTbl[u].phi = phi;
|
||||
pObj->pMapTbl[u].rect = iq;
|
||||
E_m2_c += (radio_float_t)pow(mag, 2+c_smma);
|
||||
E_m2 += (radio_float_t)pow(mag, 2);
|
||||
E_m4 += (radio_float_t)pow(mag, 4);
|
||||
E_a4.real += (radio_float_t)pow(iq.real, 4);
|
||||
E_a4.imag += (radio_float_t)pow(iq.imag, 4);
|
||||
temp = iii;
|
||||
iii = qqq;
|
||||
qqq = temp;
|
||||
map_idx_i = (int)(0.5 +(0.5*iq.real/pObj->iq_max + 0.5)*(Ns-1));
|
||||
map_idx_q = (int)(0.5 +(0.5*iq.imag/pObj->iq_max + 0.5)*(Ns-1));
|
||||
pObj->ppMapTbl[map_idx_i][map_idx_q].mag = mag;
|
||||
pObj->ppMapTbl[map_idx_i][map_idx_q].phi = phi;
|
||||
pObj->ppMapTbl[map_idx_i][map_idx_q].rect = iq;
|
||||
pObj->ppMapTbl[map_idx_i][map_idx_q].sym = (symbol_t)u;
|
||||
}
|
||||
ii = ii - even*stepIQ;
|
||||
k++;
|
||||
}
|
||||
qq = qq - stepIQ;
|
||||
ii = ii + even*stepIQ;
|
||||
even = -even;
|
||||
}
|
||||
|
||||
switch(pObj->num_const)
|
||||
{
|
||||
// QPSK
|
||||
case 4:
|
||||
pObj->Pref = (radio_float_t)0.707;
|
||||
break;
|
||||
// 16-QAM
|
||||
case 16:
|
||||
pObj->Pref = (radio_float_t)0.385;
|
||||
break;
|
||||
// 64-QAM
|
||||
case 64:
|
||||
pObj->Pref = (radio_float_t)0.31;
|
||||
break;
|
||||
// 256-QAM
|
||||
case 256:
|
||||
pObj->Pref = (radio_float_t)0.27;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
pObj->iq_step = stepIQ;
|
||||
pObj->iq_side_len = Ns;
|
||||
pObj->R2_cma = E_m4/E_m2;
|
||||
pObj->R_mma.real = 2*E_a4.real/E_m2;
|
||||
pObj->R_mma.imag = 2*E_a4.imag/E_m2;
|
||||
pObj->R_smma.real = 2*E_a4.real/E_m2_c;
|
||||
pObj->R_smma.imag = 2*E_a4.imag/E_m2_c;
|
||||
}
|
||||
|
||||
void SymMapFree(sym_map_t *pObj)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
if (pObj->pMapTbl)
|
||||
{
|
||||
free(pObj->pMapTbl);
|
||||
pObj->pMapTbl = NULL;
|
||||
}
|
||||
|
||||
if (pObj->ppMapTbl)
|
||||
{
|
||||
for (i=0; i< (uint32_t)sqrt((float)pObj->num_const); i++)
|
||||
free(pObj->ppMapTbl[i]);
|
||||
|
||||
free(pObj->ppMapTbl);
|
||||
pObj->ppMapTbl = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void SymMapReinit(sym_map_t *pObj, uint32_t nBitsPerSym, uint32_t type)
|
||||
{
|
||||
SymMapFree(pObj);
|
||||
SymMapInit(pObj, nBitsPerSym, type);
|
||||
}
|
||||
|
||||
cpx_t SymMapMap(sym_map_t *pObj, symbol_t symbol)
|
||||
{
|
||||
if (symbol >= pObj->num_const)
|
||||
return Cpx(0,0);
|
||||
|
||||
return pObj->pMapTbl[(uint32_t)symbol].rect;
|
||||
}
|
||||
|
||||
symbol_t SymMapDemap(sym_map_t *pObj, cpx_t x)
|
||||
{
|
||||
uint32_t map_idx_i, map_idx_q;
|
||||
radio_float_t rx_i, rx_q;
|
||||
|
||||
rx_i = dclamp(x.real, -pObj->iq_max, pObj->iq_max);
|
||||
rx_q = dclamp(x.imag, -pObj->iq_max, pObj->iq_max);
|
||||
|
||||
map_idx_i = (int)(0.5 +(0.5*rx_i/pObj->iq_max + 0.5)*(pObj->iq_side_len-1));
|
||||
map_idx_q = (int)(0.5 +(0.5*rx_q/pObj->iq_max + 0.5)*(pObj->iq_side_len-1));
|
||||
|
||||
return pObj->ppMapTbl[map_idx_i][map_idx_q].sym;
|
||||
}
|
||||
|
||||
map_t SymMapGetSymbolInfo(sym_map_t *pObj, symbol_t symbol)
|
||||
{
|
||||
return pObj->pMapTbl[(uint32_t)symbol];
|
||||
}
|
||||
|
||||
sym_err_t SymMapGetError(sym_map_t *pObj, cpx_t x, symbol_t symbol)
|
||||
{
|
||||
map_t map;
|
||||
sym_err_t res;
|
||||
|
||||
map = SymMapGetSymbolInfo(pObj, symbol);
|
||||
|
||||
res.err_mag = map.mag - (radio_float_t)CpxMagS(x);
|
||||
res.err_phi = map.phi - (radio_float_t)CpxPhiS(x);
|
||||
res.err = CpxSubS(map.rect, x);
|
||||
res.mag = CpxMagS(x);
|
||||
res.phi = CpxPhiS(x);
|
||||
res.soft_sym = x;
|
||||
res.hard_sym = map.rect;
|
||||
res.hard_mag = map.mag;
|
||||
res.hard_phi = map.phi;
|
||||
|
||||
return res;
|
||||
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------
|
||||
void SymStatInit(sym_stat_t *pObj, uint32_t nBitsPerSym)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
memset(pObj, 0, sizeof(sym_stat_t));
|
||||
|
||||
pObj->num_const = 1;
|
||||
for(i=0; i < nBitsPerSym; i++)
|
||||
{
|
||||
pObj->num_const *= 2;
|
||||
}
|
||||
|
||||
pObj->pPerSymStat = (per_sym_stat_t*)malloc(pObj->num_const*sizeof(per_sym_stat_t));
|
||||
|
||||
for(i=0; i < pObj->num_const; i++)
|
||||
{
|
||||
pObj->pPerSymStat[i].count = 0;
|
||||
pObj->pPerSymStat[i].var_err_mag = 0;
|
||||
pObj->pPerSymStat[i].var_err_phi = 0;
|
||||
SlidingVarInit(&pObj->pPerSymStat[i].sl_err_mag, 1000, 1000);
|
||||
SlidingVarInit(&pObj->pPerSymStat[i].sl_err_phi, 1000, 1000);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void SymStatFree(sym_stat_t *pObj)
|
||||
{
|
||||
if(pObj->pPerSymStat)
|
||||
free(pObj->pPerSymStat);
|
||||
|
||||
pObj->pPerSymStat = 0;
|
||||
}
|
||||
|
||||
void SymStatReset(sym_stat_t *pObj)
|
||||
{
|
||||
uint32_t i;
|
||||
pObj->sym_cnt = 0;
|
||||
for(i=0; i < pObj->num_const; i++)
|
||||
{
|
||||
pObj->pPerSymStat[i].count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void SymStatUpDate(sym_stat_t *pObj, symbol_t sym, sym_err_t *pSym_err)
|
||||
{
|
||||
// Statistics
|
||||
pObj->sym_cnt++;
|
||||
pObj->pPerSymStat[sym].count++;
|
||||
pObj->pPerSymStat[sym].p = (radio_float_t)pObj->pPerSymStat[sym].count/pObj->sym_cnt;
|
||||
pObj->pPerSymStat[sym].var_err_mag = SlidingVarProcess(&pObj->pPerSymStat[sym].sl_err_mag, pSym_err->err_mag);
|
||||
pObj->pPerSymStat[sym].var_err_phi = SlidingVarProcess(&pObj->pPerSymStat[sym].sl_err_phi, pSym_err->err_phi);
|
||||
|
||||
}
|
||||
|
||||
void SymStatPrint(sym_stat_t *pObj)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
printf("Number of constellations : %d\n", pObj->num_const);
|
||||
printf("Number of total symbols : %d\n", pObj->sym_cnt);
|
||||
printf("Sym#\tOccur.\t\tProb.\t\tVar(MagErr)[dB]\tVar(PhiErr/PI)[dB]\n");
|
||||
for(i=0; i < pObj->num_const; i++)
|
||||
{
|
||||
printf("%4.1d\t%6.d\t\t%1.2g\t\t%.2f\t\t%.2f\n",
|
||||
i,
|
||||
pObj->pPerSymStat[i].count,
|
||||
pObj->pPerSymStat[i].p,
|
||||
10*log10(pObj->pPerSymStat[i].var_err_mag),
|
||||
10*log10(pObj->pPerSymStat[i].var_err_phi/(PI*PI)));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
// --------------------------------------------------------------
|
||||
#ifndef SYMBOL_H
|
||||
#define SYMBOL_H
|
||||
|
||||
#include "radio_types.h"
|
||||
#include "statistics.h"
|
||||
#include "cpx.h"
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// Types
|
||||
// --------------------------------------------------------------
|
||||
typedef struct _map_t
|
||||
{
|
||||
radio_float_t mag, phi;
|
||||
cpx_t rect;
|
||||
symbol_t sym;
|
||||
|
||||
} map_t;
|
||||
|
||||
typedef struct _sym_map_t
|
||||
{
|
||||
uint32_t nBitsPerSym, num_const, type;
|
||||
radio_float_t Es, Eb, Pref;
|
||||
map_t **ppMapTbl, *pMapTbl;
|
||||
radio_float_t iq_step, iq_max;
|
||||
uint32_t iq_side_len;
|
||||
radio_float_t R2_cma; // For CMA
|
||||
cpx_t R_mma; // for MMA
|
||||
cpx_t R_smma; // for S-MMA
|
||||
|
||||
} sym_map_t;
|
||||
|
||||
typedef struct _sym_err_t
|
||||
{
|
||||
radio_float_t err_mag, err_phi;
|
||||
radio_float_t err_mag_norm, err_phi_norm;
|
||||
radio_float_t mag, phi, hard_mag, hard_phi;
|
||||
cpx_t err, hard_sym, soft_sym;
|
||||
|
||||
} sym_err_t;
|
||||
|
||||
typedef struct _per_sym_stat_t
|
||||
{
|
||||
uint32_t count;
|
||||
radio_float_t p, var_err_mag, var_err_phi;
|
||||
sl_var_t sl_err_mag, sl_err_phi;
|
||||
|
||||
} per_sym_stat_t;
|
||||
|
||||
typedef struct _sym_stat_t
|
||||
{
|
||||
uint32_t sym_cnt, num_const;
|
||||
per_sym_stat_t *pPerSymStat;
|
||||
|
||||
|
||||
} sym_stat_t;
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// Functions
|
||||
// --------------------------------------------------------------
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void SymStatInit(sym_stat_t *pObj, uint32_t nBitsPerSym);
|
||||
void SymStatFree(sym_stat_t *pObj);
|
||||
void SymStatReset(sym_stat_t *pObj);
|
||||
void SymStatUpDate(sym_stat_t *pObj, symbol_t sym, sym_err_t *pSym_err);
|
||||
void SymStatPrint(sym_stat_t *pObj);
|
||||
|
||||
void SymMapInit(sym_map_t *pObj, uint32_t nBitsPerSym, uint32_t type);
|
||||
void SymMapFree(sym_map_t *pObj);
|
||||
void SymMapReinit(sym_map_t *pObj, uint32_t nBitsPerSym, uint32_t type);
|
||||
cpx_t SymMapMap(sym_map_t *pObj, symbol_t symbol);
|
||||
symbol_t SymMapDemap(sym_map_t *pObj, cpx_t x);
|
||||
map_t SymMapGetSymbolInfo(sym_map_t *pObj, symbol_t symbol);
|
||||
sym_err_t SymMapGetError(sym_map_t *pObj, cpx_t x, symbol_t symbol);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif // __cplusplus
|
||||
|
||||
// --------------------------------------------------------------
|
||||
#endif // SYMBOL_H
|
||||
Executable
+224
@@ -0,0 +1,224 @@
|
||||
// --------------------------------------------------------------
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include "synchronization.h"
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// Clock generator
|
||||
// --------------------------------------------------------------
|
||||
void ClockInit(clock_t *pObj, uint32_t divide)
|
||||
{
|
||||
if (divide == 0)
|
||||
divide = 1;
|
||||
|
||||
pObj->reload = divide;
|
||||
pObj->count = (int32_t)divide;
|
||||
}
|
||||
|
||||
uint32_t ClockIsTick(clock_t *pObj, uint32_t do_advance)
|
||||
{
|
||||
uint32_t isTick;
|
||||
|
||||
isTick = pObj->count == 0;
|
||||
|
||||
if (do_advance)
|
||||
{
|
||||
if (isTick)
|
||||
{
|
||||
pObj->count = pObj->reload;
|
||||
}
|
||||
pObj->count--;
|
||||
}
|
||||
return isTick;
|
||||
}
|
||||
|
||||
void ClockAdvance(clock_t *pObj)
|
||||
{
|
||||
if (pObj->count == 0)
|
||||
{
|
||||
pObj->count = pObj->reload;
|
||||
}
|
||||
pObj->count--;
|
||||
}
|
||||
|
||||
void ClockSetPhase(clock_t *pObj, int32_t phase)
|
||||
{
|
||||
pObj->count = pObj->count - phase;
|
||||
if (pObj->count <= 0)
|
||||
{
|
||||
pObj->count += pObj->reload;
|
||||
}
|
||||
else if (pObj->count > (int32_t)pObj->reload)
|
||||
{
|
||||
pObj->count -= pObj->reload;
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// Second-order Loop Filter
|
||||
// --------------------------------------------------------------
|
||||
void LeadLagInit(lead_lag_filter_t *pObj, radio_float_t state)
|
||||
{
|
||||
pObj->lag_state = LEAD_LAG_SCALING*state;
|
||||
};
|
||||
|
||||
void LeadLagSetCoeff(lead_lag_coeff_t *pCoeff, radio_float_t lead, radio_float_t lag)
|
||||
{
|
||||
pCoeff->lead = lead;
|
||||
pCoeff->lag = lag;
|
||||
}
|
||||
|
||||
radio_float_t LeadLagProcess(lead_lag_filter_t *pObj, lead_lag_coeff_t *pCoeff, radio_float_t x)
|
||||
{
|
||||
pObj->lag_state += LEAD_LAG_SCALING*pCoeff->lag * x;
|
||||
|
||||
return pObj->lag_state/LEAD_LAG_SCALING + pCoeff->lead * x;
|
||||
}
|
||||
|
||||
radio_float_t LeadLagGetState(lead_lag_filter_t *pObj)
|
||||
{
|
||||
return pObj->lag_state/LEAD_LAG_SCALING;
|
||||
}
|
||||
|
||||
void LeadLagSetState(lead_lag_filter_t *pObj, radio_float_t state)
|
||||
{
|
||||
pObj->lag_state = LEAD_LAG_SCALING*state;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// Gardner Timing Error Detector
|
||||
// --------------------------------------------------------------
|
||||
void STRGardnerInit(str_t *pObj)
|
||||
{
|
||||
memset(pObj->d, 0, sizeof(pObj->d));
|
||||
}
|
||||
|
||||
radio_float_t STRGardnerProcess(str_t *pObj, cpx_t x)
|
||||
{
|
||||
radio_float_t Vd;
|
||||
cpx_t t, *pD;
|
||||
|
||||
pD = pObj->d;
|
||||
|
||||
t.real = (pD[1].real - x.real) * pD[0].real;
|
||||
t.imag = (pD[1].imag - x.imag) * pD[0].imag;
|
||||
Vd = (t.real + t.imag);
|
||||
|
||||
// Adjust delay line
|
||||
pD[1] = pD[0];
|
||||
pD[0] = x;
|
||||
|
||||
return Vd;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// Simple Phase detector for QPSK
|
||||
// --------------------------------------------------------------
|
||||
radio_float_t PhaseErrQPSK(cpx_t x)
|
||||
{
|
||||
radio_float_t perr;
|
||||
perr = x.imag*dsign(x.real) - x.real*dsign(x.imag);
|
||||
|
||||
return perr;
|
||||
}
|
||||
|
||||
radio_float_t PhaseErr(cpx_t x, radio_float_t pstep, radio_float_t poffset)
|
||||
{
|
||||
radio_float_t perr, phi, m;
|
||||
|
||||
phi = (radio_float_t)CpxPhiS(x) + poffset;
|
||||
|
||||
m = dmod(phi/(radio_float_t)PI,(radio_float_t)2.0/pstep);
|
||||
perr = (radio_float_t)1.0/pstep - m;
|
||||
|
||||
return (radio_float_t)(PI*perr);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------
|
||||
void PfdInit(pfd_t *pObj)
|
||||
{
|
||||
pObj->state_up = 0;
|
||||
pObj->state_down = 0;
|
||||
}
|
||||
|
||||
radio_float_t PfdProcess(pfd_t *pObj, radio_float_t x, radio_float_t k)
|
||||
{
|
||||
radio_float_t result;
|
||||
|
||||
result = 0;
|
||||
if (x < 0)
|
||||
{
|
||||
if (pObj->state_down == 0)
|
||||
{
|
||||
pObj->state_up = 0;
|
||||
pObj->state_down = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = -k;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pObj->state_up == 0)
|
||||
{
|
||||
pObj->state_down = 0;
|
||||
pObj->state_up = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = k;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------
|
||||
void TimingCorrectorInit(timing_corrector_t *pObj, radio_float_t wrap_alpha)
|
||||
{
|
||||
pObj->mu = 0;
|
||||
pObj->mu_filtered = 0;
|
||||
pObj->wrap_alpha = wrap_alpha;
|
||||
pObj->wrap_beta = (radio_float_t)1.0 - wrap_alpha;
|
||||
memset(pObj->skip, 0, sizeof(pObj->skip));
|
||||
memset(pObj->stuff, 0, sizeof(pObj->stuff));
|
||||
}
|
||||
|
||||
radio_float_t TimingCorrectorProcess(timing_corrector_t *pObj, radio_float_t dMu)
|
||||
{
|
||||
pObj->mu += dMu;
|
||||
pObj->skip[1] = pObj->skip[0];
|
||||
pObj->stuff[1] = pObj->stuff[0];
|
||||
pObj->skip[0] = 0;
|
||||
pObj->stuff[0] = 0;
|
||||
pObj->mu_filtered = pObj->wrap_beta*pObj->mu_filtered + pObj->wrap_alpha*pObj->mu;
|
||||
|
||||
if (pObj->mu_filtered < 0)
|
||||
{
|
||||
pObj->mu += (radio_float_t)1.0;
|
||||
pObj->stuff[0] = 1;
|
||||
}
|
||||
else if (pObj->mu_filtered >= (radio_float_t)1.0)
|
||||
{
|
||||
pObj->mu -= (radio_float_t)1.0;
|
||||
pObj->skip[0] = 1;
|
||||
}
|
||||
|
||||
return pObj->mu;
|
||||
}
|
||||
|
||||
radio_float_t TimingCorrectorGetMu(timing_corrector_t *pObj)
|
||||
{
|
||||
return pObj->mu;
|
||||
}
|
||||
|
||||
uint32_t TimingCorrectorIsSkip(timing_corrector_t *pObj)
|
||||
{
|
||||
return pObj->skip[0];
|
||||
}
|
||||
|
||||
uint32_t TimingCorrectorIsStuff(timing_corrector_t *pObj)
|
||||
{
|
||||
return pObj->stuff[0];
|
||||
}
|
||||
Executable
+93
@@ -0,0 +1,93 @@
|
||||
// --------------------------------------------------------------
|
||||
#ifndef SYNCHRONIZATION_H
|
||||
#define SYNCHRONIZATION_H
|
||||
|
||||
#include "radio_types.h"
|
||||
#include "nco.h"
|
||||
|
||||
#define LEAD_LAG_SCALING ((radio_float_t)1024*1024)
|
||||
// --------------------------------------------------------------
|
||||
// Types
|
||||
// --------------------------------------------------------------
|
||||
typedef struct _clock_t
|
||||
{
|
||||
uint32_t reload;
|
||||
int32_t count;
|
||||
|
||||
} clock_t;
|
||||
|
||||
typedef struct _lead_lag_filter_t
|
||||
{
|
||||
radio_float_t lag_state;
|
||||
|
||||
} lead_lag_filter_t;
|
||||
|
||||
typedef struct _lead_lag_coeff_t
|
||||
{
|
||||
radio_float_t lead;
|
||||
radio_float_t lag;
|
||||
|
||||
} lead_lag_coeff_t;
|
||||
|
||||
typedef struct _str_t
|
||||
{
|
||||
cpx_t d[2];
|
||||
|
||||
} str_t;
|
||||
|
||||
typedef struct _pfd_t
|
||||
{
|
||||
uint32_t state_up;
|
||||
uint32_t state_down;
|
||||
} pfd_t;
|
||||
|
||||
typedef struct _timing_corrector_t
|
||||
{
|
||||
radio_float_t mu;
|
||||
radio_float_t mu_filtered;
|
||||
radio_float_t wrap_alpha;
|
||||
radio_float_t wrap_beta;
|
||||
uint32_t skip[2];
|
||||
uint32_t stuff[2];
|
||||
|
||||
} timing_corrector_t;
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// Functions
|
||||
// --------------------------------------------------------------
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void ClockInit(clock_t *pObj, uint32_t divide);
|
||||
uint32_t ClockIsTick(clock_t *pObj, uint32_t do_advance);
|
||||
void ClockAdvance(clock_t *pObj);
|
||||
void ClockSetPhase(clock_t *pObj, int32_t phase);
|
||||
|
||||
void STRGardnerInit(str_t *pObj);
|
||||
radio_float_t STRGardnerProcess(str_t *pObj, cpx_t x);
|
||||
|
||||
radio_float_t PhaseErrQPSK(cpx_t x);
|
||||
radio_float_t PhaseErr(cpx_t x, radio_float_t pstep, radio_float_t poffset);
|
||||
|
||||
void PfdInit(pfd_t *pObj);
|
||||
radio_float_t PfdProcess(pfd_t *pObj, radio_float_t x, radio_float_t k);
|
||||
|
||||
void LeadLagInit(lead_lag_filter_t *pObj, radio_float_t state);
|
||||
void LeadLagSetCoeff(lead_lag_coeff_t *pCoeff, radio_float_t lead, radio_float_t lag);
|
||||
radio_float_t LeadLagProcess(lead_lag_filter_t *pObj, lead_lag_coeff_t *pCoeff, radio_float_t x);
|
||||
radio_float_t LeadLagGetState(lead_lag_filter_t *pObj);
|
||||
void LeadLagSetState(lead_lag_filter_t *pObj, radio_float_t state);
|
||||
|
||||
void TimingCorrectorInit(timing_corrector_t *pObj, radio_float_t wrap_alpha);
|
||||
radio_float_t TimingCorrectorProcess(timing_corrector_t *pObj, radio_float_t dMu);
|
||||
radio_float_t TimingCorrectorGetMu(timing_corrector_t *pObj);
|
||||
uint32_t TimingCorrectorIsSkip(timing_corrector_t *pObj);
|
||||
uint32_t TimingCorrectorIsStuff(timing_corrector_t *pObj);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif // __cplusplus
|
||||
|
||||
// --------------------------------------------------------------
|
||||
#endif // SYNCHRONIZATION_H
|
||||
Reference in New Issue
Block a user