Initial import

git-svn-id: http://moon:8086/svn/software/trunk/libsrc/radio@1 b431acfa-c32f-4a4a-93f1-934dc6c82436
This commit is contained in:
2014-07-19 07:44:42 +00:00
commit 290fd5f5e0
36 changed files with 13976 additions and 0 deletions
+1027
View File
File diff suppressed because it is too large Load Diff
Executable
+274
View File
@@ -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_
+550
View File
@@ -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_
+445
View File
@@ -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);
}
+192
View File
@@ -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
View File
File diff suppressed because it is too large Load Diff
+1089
View File
File diff suppressed because it is too large Load Diff
Executable
+234
View File
@@ -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_
+403
View File
@@ -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_
+785
View File
@@ -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);
}
}
+271
View File
@@ -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_
Executable
+41
View File
@@ -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;
}
// --------------------------------------------------------------
Executable
+39
View File
@@ -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
Executable
+591
View File
@@ -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];
}
}
Executable
+80
View File
@@ -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
View File
@@ -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
View File
@@ -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
Executable
+356
View File
@@ -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;
}
// --------------------------------------------------------------
Executable
+61
View File
@@ -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
+830
View File
@@ -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;
}
+158
View File
@@ -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
Executable
+118
View File
@@ -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);
}
}
// --------------------------------------------------------------
Executable
+57
View File
@@ -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
Executable
+2660
View File
File diff suppressed because it is too large Load Diff
Executable
+530
View File
@@ -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
View File
@@ -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
Executable
+83
View File
@@ -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);
}
// --------------------------------------------------------------
Executable
+31
View File
@@ -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
Executable
+168
View File
@@ -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--;
}
// --------------------------------------------------------------
Executable
+62
View File
@@ -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
View File
@@ -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
View File
@@ -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
Executable
+298
View File
@@ -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)));
}
}
Executable
+83
View File
@@ -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
+224
View File
@@ -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];
}
+93
View File
@@ -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