Initial import
git-svn-id: http://moon:8086/svn/software/trunk/libsrc/radio@1 b431acfa-c32f-4a4a-93f1-934dc6c82436
This commit is contained in:
Executable
+1027
File diff suppressed because it is too large
Load Diff
Executable
+274
@@ -0,0 +1,274 @@
|
|||||||
|
#ifndef _REAL_HPP_
|
||||||
|
#define _REAL_HPP_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <memory.h>
|
||||||
|
#include <radio/radio_types.h>
|
||||||
|
|
||||||
|
void RealDebug(char *fmtstr, ...);
|
||||||
|
|
||||||
|
class RealException
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RealException (std::string s)
|
||||||
|
{
|
||||||
|
m_what = s;
|
||||||
|
}
|
||||||
|
~RealException()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
std::string& what()
|
||||||
|
{
|
||||||
|
return m_what;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
std::string m_what;
|
||||||
|
};
|
||||||
|
|
||||||
|
class RealVector
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
struct OpBinary
|
||||||
|
{
|
||||||
|
enum OpType
|
||||||
|
{
|
||||||
|
ADD = 0,
|
||||||
|
SUB,
|
||||||
|
MUL,
|
||||||
|
DIV
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct _attributes_t
|
||||||
|
{
|
||||||
|
bool negative;
|
||||||
|
} attributes_t;
|
||||||
|
|
||||||
|
OpBinary(const RealVector &a, const RealVector &b, OpType op)
|
||||||
|
: a(a)
|
||||||
|
, b(b)
|
||||||
|
, op(op)
|
||||||
|
, m_attributes(defaultAttributes())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
OpBinary operator-()
|
||||||
|
{
|
||||||
|
attributes_t attributes = this->m_attributes;
|
||||||
|
attributes.negative = !attributes.negative;
|
||||||
|
|
||||||
|
return OpBinary(*this, attributes);
|
||||||
|
}
|
||||||
|
~OpBinary()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isNegative() const
|
||||||
|
{
|
||||||
|
return m_attributes.negative;
|
||||||
|
}
|
||||||
|
const RealVector &a;
|
||||||
|
const RealVector &b;
|
||||||
|
const OpType op;
|
||||||
|
attributes_t m_attributes;
|
||||||
|
|
||||||
|
private:
|
||||||
|
OpBinary& operator=(const OpBinary&);
|
||||||
|
OpBinary(const OpBinary &src, attributes_t attributes)
|
||||||
|
: a(src.a)
|
||||||
|
, b(src.b)
|
||||||
|
, op(src.op)
|
||||||
|
, m_attributes(attributes)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
static const attributes_t defaultAttributes()
|
||||||
|
{
|
||||||
|
attributes_t attributes;
|
||||||
|
attributes.negative = false;
|
||||||
|
return attributes;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct _attributes_t
|
||||||
|
{
|
||||||
|
bool negative;
|
||||||
|
} attributes_t;
|
||||||
|
|
||||||
|
// Standard constructor
|
||||||
|
RealVector(uint32_t size, radio_float_t *real=0)
|
||||||
|
: m_size(size)
|
||||||
|
, m_real(0)
|
||||||
|
, m_pBufReal(0)
|
||||||
|
, m_pPtrReal(real)
|
||||||
|
, m_attributes(defaultAttributes())
|
||||||
|
{
|
||||||
|
if (!real)
|
||||||
|
{
|
||||||
|
m_pBufReal = new radio_float_t[m_size];
|
||||||
|
memset(m_pBufReal, 0, m_size*sizeof(radio_float_t));
|
||||||
|
m_pPtrReal = m_pBufReal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// OpBinary resolver copy constructor
|
||||||
|
RealVector(const OpBinary &src)
|
||||||
|
: m_size(src.a.m_size)
|
||||||
|
, m_real(0)
|
||||||
|
, m_pBufReal(0)
|
||||||
|
, m_pPtrReal(0)
|
||||||
|
, m_attributes(defaultAttributes())
|
||||||
|
{
|
||||||
|
m_pBufReal = new radio_float_t[m_size];
|
||||||
|
m_pPtrReal = m_pBufReal;
|
||||||
|
|
||||||
|
*this = src;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Scalar constructor
|
||||||
|
RealVector(radio_float_t real)
|
||||||
|
: m_size(1)
|
||||||
|
, m_real(real)
|
||||||
|
, m_pBufReal(0)
|
||||||
|
, m_pPtrReal(&m_real)
|
||||||
|
, m_attributes(defaultAttributes())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
~RealVector(void)
|
||||||
|
{
|
||||||
|
if (m_pBufReal)
|
||||||
|
delete(m_pBufReal);
|
||||||
|
|
||||||
|
m_pBufReal = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isNegative() const
|
||||||
|
{
|
||||||
|
return m_attributes.negative;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t getSize()
|
||||||
|
{
|
||||||
|
return m_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
RealVector at(uint32_t const &i)
|
||||||
|
{
|
||||||
|
return RealVector(*this, i, 1, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
void print(char *pPrefix)
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
|
RealDebug("%s:\n", pPrefix);
|
||||||
|
for (i=0; i < m_size; i++)
|
||||||
|
{
|
||||||
|
RealDebug("%d: %.6f\n", i, m_pPtrReal[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RealVector operator-()
|
||||||
|
{
|
||||||
|
attributes_t attributes = this->m_attributes;
|
||||||
|
attributes.negative = !attributes.negative;
|
||||||
|
|
||||||
|
return RealVector(*this, attributes);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assignments
|
||||||
|
RealVector& operator=(const RealVector &src);
|
||||||
|
RealVector& operator+=(const RealVector &src);
|
||||||
|
RealVector& operator-=(const RealVector &src);
|
||||||
|
RealVector& operator*=(const RealVector &src);
|
||||||
|
RealVector& operator/=(const RealVector &src);
|
||||||
|
RealVector& operator=(const OpBinary &src);
|
||||||
|
RealVector& operator+=(const OpBinary &src);
|
||||||
|
RealVector& operator-=(const OpBinary &src);
|
||||||
|
RealVector& operator*=(const OpBinary &src);
|
||||||
|
RealVector& operator/=(const OpBinary &src);
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint32_t m_size;
|
||||||
|
radio_float_t m_real;
|
||||||
|
radio_float_t *m_pBufReal;
|
||||||
|
radio_float_t *m_pPtrReal;
|
||||||
|
attributes_t m_attributes;
|
||||||
|
|
||||||
|
// Attribute default
|
||||||
|
const attributes_t defaultAttributes()
|
||||||
|
{
|
||||||
|
attributes_t attributes;
|
||||||
|
|
||||||
|
attributes.negative = 0;
|
||||||
|
|
||||||
|
return attributes;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy constructor
|
||||||
|
RealVector(const RealVector &src)
|
||||||
|
: m_size(src.m_size)
|
||||||
|
, m_real(0)
|
||||||
|
, m_pBufReal(0)
|
||||||
|
, m_pPtrReal(0)
|
||||||
|
, m_attributes(src.m_attributes)
|
||||||
|
{
|
||||||
|
m_pBufReal = new radio_float_t[m_size];
|
||||||
|
m_pPtrReal = m_pBufReal;
|
||||||
|
|
||||||
|
*this = src;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Re-attribute constructor
|
||||||
|
// Copies no data, just pointers and attributes
|
||||||
|
RealVector(const RealVector &src, attributes_t attributes)
|
||||||
|
: m_size(src.m_size)
|
||||||
|
, m_real(src.m_real)
|
||||||
|
, m_pBufReal(0)
|
||||||
|
, m_pPtrReal(src.m_pPtrReal)
|
||||||
|
, m_attributes(attributes)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// Slicing constructor
|
||||||
|
RealVector(RealVector &src, uint32_t from, uint32_t step, uint32_t to)
|
||||||
|
: m_size(0)
|
||||||
|
, m_real(src.m_real)
|
||||||
|
, m_pBufReal(0)
|
||||||
|
, m_pPtrReal(&src.m_pPtrReal[from])
|
||||||
|
, m_attributes(src.m_attributes)
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
|
for (i=from; i < to; i+=step)
|
||||||
|
{
|
||||||
|
m_size++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
_inline void checkSize(uint32_t size1, uint32_t size2)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if ((size1 != size2) && (size2 != 1))
|
||||||
|
{
|
||||||
|
throw(RealException("Size mismatch"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(RealException &exc)
|
||||||
|
{
|
||||||
|
RealDebug("Problem: %s\n", exc.what().c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
// Non-Member
|
||||||
|
// Binary Operators
|
||||||
|
// Returning RealVector::OpBinary
|
||||||
|
RealVector::OpBinary operator+(const RealVector &a, const RealVector &b);
|
||||||
|
RealVector::OpBinary operator-(const RealVector &a, const RealVector &b);
|
||||||
|
RealVector::OpBinary operator*(const RealVector &a, const RealVector &b);
|
||||||
|
RealVector::OpBinary operator/(const RealVector &a, const RealVector &b);
|
||||||
|
|
||||||
|
#endif // _REAL_HPP_
|
||||||
Executable
+550
@@ -0,0 +1,550 @@
|
|||||||
|
#ifndef _COMPLEX_HPP_
|
||||||
|
#define _COMPLEX_HPP_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <memory.h>
|
||||||
|
#include <radio/radio_types.h>
|
||||||
|
#include <radio/cpx.h>
|
||||||
|
|
||||||
|
void ComplexDebug(char *fmtstr, ...);
|
||||||
|
|
||||||
|
class ComplexException
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ComplexException (std::string s)
|
||||||
|
{
|
||||||
|
m_what = s;
|
||||||
|
}
|
||||||
|
~ComplexException()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
std::string& what()
|
||||||
|
{
|
||||||
|
return m_what;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
std::string m_what;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ComplexVector
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
struct Negate
|
||||||
|
{
|
||||||
|
Negate(const ComplexVector &src)
|
||||||
|
: src(src)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
const ComplexVector &src;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Negate& operator=(const Negate&);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ConjugateNegate;
|
||||||
|
struct Conjugate
|
||||||
|
{
|
||||||
|
Conjugate(const ComplexVector &src)
|
||||||
|
: src(src)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
const ComplexVector &src;
|
||||||
|
const ConjugateNegate operator-()
|
||||||
|
{
|
||||||
|
const ConjugateNegate neg(src);
|
||||||
|
return neg;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Conjugate& operator=(const Conjugate&);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ConjugateNegate
|
||||||
|
{
|
||||||
|
ConjugateNegate(const Conjugate &src)
|
||||||
|
: src(src.src)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
const ComplexVector &src;
|
||||||
|
|
||||||
|
private:
|
||||||
|
ConjugateNegate& operator=(const ConjugateNegate&);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct NegMul_A_B;
|
||||||
|
struct Mul_A_B
|
||||||
|
{
|
||||||
|
Mul_A_B(const ComplexVector &a, const ComplexVector &b)
|
||||||
|
: a(a)
|
||||||
|
, b(b)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
const ComplexVector &a;
|
||||||
|
const ComplexVector &b;
|
||||||
|
const NegMul_A_B operator-()
|
||||||
|
{
|
||||||
|
const NegMul_A_B neg(a, b);
|
||||||
|
return neg;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
Mul_A_B& operator=(const Mul_A_B&);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct NegMul_A_B
|
||||||
|
{
|
||||||
|
NegMul_A_B(const ComplexVector &a, const ComplexVector &b)
|
||||||
|
: a(a)
|
||||||
|
, b(b)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
const ComplexVector &a;
|
||||||
|
const ComplexVector &b;
|
||||||
|
|
||||||
|
private:
|
||||||
|
NegMul_A_B& operator=(const NegMul_A_B&);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ConjNegMul_A_B
|
||||||
|
{
|
||||||
|
ConjNegMul_A_B(const ComplexVector &a, const ComplexVector &b)
|
||||||
|
: a(a)
|
||||||
|
, b(b)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
const ComplexVector &a;
|
||||||
|
const ComplexVector &b;
|
||||||
|
|
||||||
|
private:
|
||||||
|
ConjNegMul_A_B& operator=(const ConjNegMul_A_B&);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ConjMul_A_B
|
||||||
|
{
|
||||||
|
ConjMul_A_B(const ComplexVector &a, const ComplexVector &b)
|
||||||
|
: a(a)
|
||||||
|
, b(b)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
const ConjNegMul_A_B operator-()
|
||||||
|
{
|
||||||
|
const ConjNegMul_A_B neg(a, b);
|
||||||
|
return neg;
|
||||||
|
}
|
||||||
|
const ComplexVector &a;
|
||||||
|
const ComplexVector &b;
|
||||||
|
|
||||||
|
private:
|
||||||
|
ConjMul_A_B& operator=(const ConjMul_A_B&);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct NegMul_A_ConjB;
|
||||||
|
struct Mul_A_ConjB
|
||||||
|
{
|
||||||
|
Mul_A_ConjB(const ComplexVector &a, const Conjugate &b)
|
||||||
|
: a(a)
|
||||||
|
, b(b.src)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
const NegMul_A_ConjB operator-()
|
||||||
|
{
|
||||||
|
const NegMul_A_ConjB neg(a, b);
|
||||||
|
return neg;
|
||||||
|
}
|
||||||
|
const ComplexVector &a;
|
||||||
|
const ComplexVector &b;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Mul_A_ConjB& operator=(const Mul_A_ConjB&);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct NegMul_A_ConjB
|
||||||
|
{
|
||||||
|
NegMul_A_ConjB(const ComplexVector &a, const Conjugate &b)
|
||||||
|
: a(a)
|
||||||
|
, b(b.src)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
const ComplexVector &a;
|
||||||
|
const ComplexVector &b;
|
||||||
|
|
||||||
|
private:
|
||||||
|
NegMul_A_ConjB& operator=(const NegMul_A_ConjB&);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct NegAdd_A_B;
|
||||||
|
struct Add_A_B
|
||||||
|
{
|
||||||
|
Add_A_B(const ComplexVector &a, const ComplexVector &b)
|
||||||
|
: a(a)
|
||||||
|
, b(b)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
const ComplexVector &a;
|
||||||
|
const ComplexVector &b;
|
||||||
|
const NegAdd_A_B operator-()
|
||||||
|
{
|
||||||
|
const NegAdd_A_B neg(a, b);
|
||||||
|
return neg;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Add_A_B& operator=(const Add_A_B&);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct NegAdd_A_B
|
||||||
|
{
|
||||||
|
NegAdd_A_B(const ComplexVector &a, const ComplexVector &b)
|
||||||
|
: a(a)
|
||||||
|
, b(b)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
const ComplexVector &a;
|
||||||
|
const ComplexVector &b;
|
||||||
|
|
||||||
|
private:
|
||||||
|
NegAdd_A_B& operator=(const NegAdd_A_B&);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ConjNegAdd_A_B;
|
||||||
|
struct ConjAdd_A_B
|
||||||
|
{
|
||||||
|
ConjAdd_A_B(const ComplexVector &a, const ComplexVector &b)
|
||||||
|
: a(a)
|
||||||
|
, b(b)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
const ComplexVector &a;
|
||||||
|
const ComplexVector &b;
|
||||||
|
const ConjNegAdd_A_B operator-()
|
||||||
|
{
|
||||||
|
const ConjNegAdd_A_B neg(a, b);
|
||||||
|
return neg;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
ConjAdd_A_B& operator=(const ConjAdd_A_B&);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ConjNegAdd_A_B
|
||||||
|
{
|
||||||
|
ConjNegAdd_A_B(const ComplexVector &a, const ComplexVector &b)
|
||||||
|
: a(a)
|
||||||
|
, b(b)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
const ComplexVector &a;
|
||||||
|
const ComplexVector &b;
|
||||||
|
|
||||||
|
private:
|
||||||
|
ConjNegAdd_A_B& operator=(const ConjNegAdd_A_B&);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Add_A_NegB
|
||||||
|
{
|
||||||
|
Add_A_NegB(const ComplexVector &a, const Negate &b)
|
||||||
|
: a(a)
|
||||||
|
, b(b.src)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
const ComplexVector &a;
|
||||||
|
const ComplexVector &b;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Add_A_NegB& operator=(const Add_A_NegB&);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Add_A_ConjB
|
||||||
|
{
|
||||||
|
Add_A_ConjB(const ComplexVector &a, const Conjugate &b)
|
||||||
|
: a(a)
|
||||||
|
, b(b.src)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
const ComplexVector &a;
|
||||||
|
const ComplexVector &b;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Add_A_ConjB& operator=(const Add_A_ConjB&);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct NegAdd_A_ConjB
|
||||||
|
{
|
||||||
|
NegAdd_A_ConjB(const ComplexVector &a, const Conjugate &b)
|
||||||
|
: a(a)
|
||||||
|
, b(b.src)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
const ComplexVector &a;
|
||||||
|
const ComplexVector &b;
|
||||||
|
|
||||||
|
private:
|
||||||
|
NegAdd_A_ConjB& operator=(const NegAdd_A_ConjB&);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Add_A_ConjNegB
|
||||||
|
{
|
||||||
|
Add_A_ConjNegB(const ComplexVector &a, const ConjugateNegate &b)
|
||||||
|
: a(a)
|
||||||
|
, b(b.src)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
const ComplexVector &a;
|
||||||
|
const ComplexVector &b;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Add_A_ConjNegB& operator=(const Add_A_ConjNegB&);
|
||||||
|
};
|
||||||
|
|
||||||
|
ComplexVector(uint32_t size, radio_float_t *real=0, radio_float_t *imag=0)
|
||||||
|
: m_size(size)
|
||||||
|
, m_real(0)
|
||||||
|
, m_imag(0)
|
||||||
|
, m_pBufReal(0)
|
||||||
|
, m_pBufImag(0)
|
||||||
|
, m_pPtrReal(real)
|
||||||
|
, m_pPtrImag(imag)
|
||||||
|
{
|
||||||
|
if (!real)
|
||||||
|
{
|
||||||
|
m_pBufReal = new radio_float_t[m_size];
|
||||||
|
memset(m_pBufReal, 0, m_size*sizeof(radio_float_t));
|
||||||
|
m_pPtrReal = m_pBufReal;
|
||||||
|
}
|
||||||
|
if (!imag)
|
||||||
|
{
|
||||||
|
m_pBufImag = new radio_float_t[m_size];
|
||||||
|
memset(m_pBufImag, 0, m_size*sizeof(radio_float_t));
|
||||||
|
m_pPtrImag = m_pBufImag;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ComplexVector(radio_float_t real, radio_float_t imag)
|
||||||
|
: m_size(1)
|
||||||
|
, m_real(real)
|
||||||
|
, m_imag(imag)
|
||||||
|
, m_pBufReal(0)
|
||||||
|
, m_pBufImag(0)
|
||||||
|
, m_pPtrReal(&m_real)
|
||||||
|
, m_pPtrImag(&m_imag)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
~ComplexVector(void)
|
||||||
|
{
|
||||||
|
if (m_pBufReal)
|
||||||
|
delete(m_pBufReal);
|
||||||
|
|
||||||
|
if (m_pBufImag)
|
||||||
|
delete(m_pBufImag);
|
||||||
|
|
||||||
|
m_pBufReal = nullptr;
|
||||||
|
m_pBufImag = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
radio_float_t* getReal()
|
||||||
|
{
|
||||||
|
return m_pPtrReal;
|
||||||
|
}
|
||||||
|
|
||||||
|
radio_float_t* getImag()
|
||||||
|
{
|
||||||
|
return m_pPtrImag;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t getSize()
|
||||||
|
{
|
||||||
|
return m_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
ComplexVector at(uint32_t const &i)
|
||||||
|
{
|
||||||
|
return ComplexVector(*this, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
Conjugate conj()
|
||||||
|
{
|
||||||
|
const ComplexVector::Conjugate src_conj(*this);
|
||||||
|
|
||||||
|
return src_conj;
|
||||||
|
}
|
||||||
|
|
||||||
|
void print(char *pPrefix)
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
|
ComplexDebug("%s:\n", pPrefix);
|
||||||
|
for (i=0; i < m_size; i++)
|
||||||
|
{
|
||||||
|
if (m_pPtrImag[i] < 0)
|
||||||
|
{
|
||||||
|
ComplexDebug("%d: %.6f - j%.6f\n", i, m_pPtrReal[i], -m_pPtrImag[i]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ComplexDebug("%d: %.6f + j%.6f\n", i, m_pPtrReal[i], m_pPtrImag[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Operators
|
||||||
|
const Negate operator-()
|
||||||
|
{
|
||||||
|
const Negate neg(*this);
|
||||||
|
return neg;
|
||||||
|
}
|
||||||
|
|
||||||
|
ComplexVector& operator=(const radio_float_t &b);
|
||||||
|
ComplexVector& operator*=(const radio_float_t &b);
|
||||||
|
ComplexVector& operator+=(const radio_float_t &b);
|
||||||
|
ComplexVector& operator-=(const radio_float_t &b);
|
||||||
|
|
||||||
|
ComplexVector& operator=(const ComplexVector &src);
|
||||||
|
ComplexVector& operator*=(const ComplexVector &src);
|
||||||
|
ComplexVector& operator+=(const ComplexVector &src);
|
||||||
|
ComplexVector& operator-=(const ComplexVector &src);
|
||||||
|
|
||||||
|
ComplexVector& operator=(const Negate &src);
|
||||||
|
ComplexVector& operator*=(const Negate &src);
|
||||||
|
ComplexVector& operator+=(const Negate &src);
|
||||||
|
ComplexVector& operator-=(const Negate &src);
|
||||||
|
|
||||||
|
ComplexVector& operator=(const Conjugate &src);
|
||||||
|
ComplexVector& operator*=(const Conjugate &src);
|
||||||
|
ComplexVector& operator+=(const Conjugate &src);
|
||||||
|
ComplexVector& operator-=(const Conjugate &src);
|
||||||
|
|
||||||
|
ComplexVector& operator=(const ConjugateNegate &src);
|
||||||
|
ComplexVector& operator*=(const ConjugateNegate &src);
|
||||||
|
ComplexVector& operator+=(const ConjugateNegate &src);
|
||||||
|
ComplexVector& operator-=(const ConjugateNegate &src);
|
||||||
|
|
||||||
|
ComplexVector& operator=(const Mul_A_B &src);
|
||||||
|
ComplexVector& operator+=(const Mul_A_B &src);
|
||||||
|
ComplexVector& operator-=(const Mul_A_B &src);
|
||||||
|
|
||||||
|
ComplexVector& operator=(const NegMul_A_B &src);
|
||||||
|
ComplexVector& operator+=(const NegMul_A_B &src);
|
||||||
|
ComplexVector& operator-=(const NegMul_A_B &src);
|
||||||
|
|
||||||
|
ComplexVector& operator=(const Mul_A_ConjB &src);
|
||||||
|
ComplexVector& operator+=(const Mul_A_ConjB &src);
|
||||||
|
ComplexVector& operator-=(const Mul_A_ConjB &src);
|
||||||
|
|
||||||
|
ComplexVector& operator=(const ConjMul_A_B &src);
|
||||||
|
ComplexVector& operator+=(const ConjMul_A_B &src);
|
||||||
|
ComplexVector& operator-=(const ConjMul_A_B &src);
|
||||||
|
|
||||||
|
ComplexVector& operator=(const ConjNegMul_A_B &src);
|
||||||
|
ComplexVector& operator+=(const ConjNegMul_A_B &src);
|
||||||
|
ComplexVector& operator-=(const ConjNegMul_A_B &src);
|
||||||
|
|
||||||
|
ComplexVector& operator=(const NegMul_A_ConjB &src);
|
||||||
|
ComplexVector& operator+=(const NegMul_A_ConjB &src);
|
||||||
|
ComplexVector& operator-=(const NegMul_A_ConjB &src);
|
||||||
|
|
||||||
|
ComplexVector& operator=(const Add_A_B &src);
|
||||||
|
ComplexVector& operator=(const NegAdd_A_B &src);
|
||||||
|
ComplexVector& operator=(const ConjAdd_A_B &src);
|
||||||
|
ComplexVector& operator=(const ConjNegAdd_A_B &src);
|
||||||
|
ComplexVector& operator=(const Add_A_NegB &src);
|
||||||
|
ComplexVector& operator=(const Add_A_ConjB &src);
|
||||||
|
ComplexVector& operator=(const NegAdd_A_ConjB &src);
|
||||||
|
ComplexVector& operator=(const Add_A_ConjNegB &src);
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint32_t m_size;
|
||||||
|
radio_float_t m_real;
|
||||||
|
radio_float_t m_imag;
|
||||||
|
radio_float_t *m_pBufReal;
|
||||||
|
radio_float_t *m_pBufImag;
|
||||||
|
radio_float_t *m_pPtrReal;
|
||||||
|
radio_float_t *m_pPtrImag;
|
||||||
|
|
||||||
|
ComplexVector(ComplexVector &src, uint32_t index)
|
||||||
|
: m_size(1)
|
||||||
|
, m_pBufReal(0)
|
||||||
|
, m_pBufImag(0)
|
||||||
|
, m_pPtrReal(&src.m_pPtrReal[index])
|
||||||
|
, m_pPtrImag(&src.m_pPtrImag[index])
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
_inline void checkSize(uint32_t size1, uint32_t size2)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if ((size1 != size2) && (size2 != 1))
|
||||||
|
{
|
||||||
|
throw(ComplexException("Size mismatch"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(ComplexException &exc)
|
||||||
|
{
|
||||||
|
ComplexDebug("Problem: %s\n", exc.what().c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
ComplexVector::Mul_A_B operator*(const ComplexVector &a, radio_float_t b);
|
||||||
|
ComplexVector::Mul_A_B operator*(const ComplexVector &a, const ComplexVector &b);
|
||||||
|
|
||||||
|
ComplexVector::Mul_A_B operator*(const ComplexVector::Negate &a, const ComplexVector::Negate &b);
|
||||||
|
ComplexVector::NegMul_A_B operator*(const ComplexVector::Negate &a, const ComplexVector &b);
|
||||||
|
ComplexVector::NegMul_A_B operator*(const ComplexVector &a, const ComplexVector::Negate &b);
|
||||||
|
|
||||||
|
ComplexVector::ConjMul_A_B operator*(const ComplexVector::Conjugate &a, const ComplexVector::Conjugate &b);
|
||||||
|
ComplexVector::Mul_A_ConjB operator*(const ComplexVector::Conjugate &a, const ComplexVector &b);
|
||||||
|
ComplexVector::Mul_A_ConjB operator*(const ComplexVector &a, const ComplexVector::Conjugate &b);
|
||||||
|
|
||||||
|
ComplexVector::ConjMul_A_B operator*(const ComplexVector::ConjugateNegate &a, const ComplexVector::ConjugateNegate &b);
|
||||||
|
ComplexVector::NegMul_A_ConjB operator*(const ComplexVector &a, const ComplexVector::ConjugateNegate &b);
|
||||||
|
ComplexVector::NegMul_A_ConjB operator*(const ComplexVector::ConjugateNegate &a, const ComplexVector &b);
|
||||||
|
|
||||||
|
ComplexVector::Mul_A_ConjB operator*(const ComplexVector::Negate &a, const ComplexVector::ConjugateNegate &b);
|
||||||
|
ComplexVector::Mul_A_ConjB operator*(const ComplexVector::ConjugateNegate &a, const ComplexVector::Negate &b);
|
||||||
|
|
||||||
|
ComplexVector::NegMul_A_ConjB operator*(const ComplexVector::Negate &a, const ComplexVector::Conjugate &b);
|
||||||
|
ComplexVector::NegMul_A_ConjB operator*(const ComplexVector::Conjugate &a, const ComplexVector::Negate &b);
|
||||||
|
|
||||||
|
ComplexVector::Add_A_B operator+(const ComplexVector &a, radio_float_t b);
|
||||||
|
ComplexVector::Add_A_B operator+(const ComplexVector &a, const ComplexVector &b);
|
||||||
|
ComplexVector::NegAdd_A_B operator+(ComplexVector::Negate &a, ComplexVector::Negate &b);
|
||||||
|
|
||||||
|
ComplexVector::Add_A_NegB operator+(const ComplexVector::Negate &a, const ComplexVector &b);
|
||||||
|
ComplexVector::Add_A_NegB operator+(const ComplexVector &a, const ComplexVector::Negate &b);
|
||||||
|
|
||||||
|
ComplexVector::Add_A_ConjB operator+(const ComplexVector::Conjugate &a, const ComplexVector &b);
|
||||||
|
ComplexVector::Add_A_ConjB operator+(const ComplexVector &a, const ComplexVector::Conjugate &b);
|
||||||
|
ComplexVector::ConjAdd_A_B operator+(const ComplexVector::Conjugate &a, const ComplexVector::Conjugate &b);
|
||||||
|
|
||||||
|
|
||||||
|
ComplexVector::Add_A_ConjNegB operator+(const ComplexVector::ConjugateNegate &a, const ComplexVector &b);
|
||||||
|
ComplexVector::Add_A_ConjNegB operator+(const ComplexVector &a, const ComplexVector::ConjugateNegate &b);
|
||||||
|
|
||||||
|
ComplexVector::Add_A_ConjB operator+(const ComplexVector::Conjugate &a, const ComplexVector::Negate &b);
|
||||||
|
ComplexVector::Add_A_ConjB operator+(const ComplexVector::Negate &a, const ComplexVector::Conjugate &b);
|
||||||
|
|
||||||
|
ComplexVector::Add_A_ConjB operator+(const ComplexVector::ConjugateNegate &a, const ComplexVector::Negate &b);
|
||||||
|
ComplexVector::Add_A_ConjB operator+(const ComplexVector::Negate &a, const ComplexVector::ConjugateNegate &b);
|
||||||
|
|
||||||
|
ComplexVector::Add_A_B operator-(const ComplexVector &a, radio_float_t b);
|
||||||
|
ComplexVector::Add_A_NegB operator-(const ComplexVector &a, const ComplexVector &b);
|
||||||
|
ComplexVector::Add_A_NegB operator-(const ComplexVector::Negate &a, const ComplexVector::Negate &b);
|
||||||
|
|
||||||
|
ComplexVector::NegAdd_A_B operator-(const ComplexVector::Negate &a, const ComplexVector &b);
|
||||||
|
ComplexVector::Add_A_B operator-(const ComplexVector &a, const ComplexVector::Negate &b);
|
||||||
|
|
||||||
|
ComplexVector::Add_A_ConjNegB operator-(const ComplexVector::Conjugate &a, const ComplexVector &b);
|
||||||
|
ComplexVector::Add_A_ConjNegB operator-(const ComplexVector &a, const ComplexVector::Conjugate &b);
|
||||||
|
|
||||||
|
ComplexVector::NegAdd_A_ConjB operator-(const ComplexVector::ConjugateNegate &a, const ComplexVector &b);
|
||||||
|
ComplexVector::Add_A_ConjB operator-(const ComplexVector &a, const ComplexVector::ConjugateNegate &b);
|
||||||
|
|
||||||
|
ComplexVector::Add_A_ConjB operator-(const ComplexVector::Conjugate &a, const ComplexVector::Negate &b);
|
||||||
|
ComplexVector::Add_A_ConjB operator-(const ComplexVector::Negate &a, const ComplexVector::Conjugate &b);
|
||||||
|
|
||||||
|
ComplexVector::Add_A_ConjB operator-(const ComplexVector::ConjugateNegate &a, const ComplexVector::Negate &b);
|
||||||
|
ComplexVector::Add_A_ConjB operator-(const ComplexVector::Negate &a, const ComplexVector::ConjugateNegate &b);
|
||||||
|
|
||||||
|
#endif // _COMPLEX_HPP_
|
||||||
Executable
+445
@@ -0,0 +1,445 @@
|
|||||||
|
#include <windows.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "ComplexVector.hpp"
|
||||||
|
|
||||||
|
void ComplexDebug(char *fmtstr, ...)
|
||||||
|
{
|
||||||
|
char buf[1024];
|
||||||
|
va_list args;
|
||||||
|
|
||||||
|
va_start(args, fmtstr);
|
||||||
|
vsprintf(buf, fmtstr, args);
|
||||||
|
va_end(args);
|
||||||
|
OutputDebugString(buf);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Class Methods
|
||||||
|
// Standard constructor
|
||||||
|
ComplexVector::ComplexVector(uint32_t size, radio_float_t *real, radio_float_t *imag)
|
||||||
|
: m_size(size)
|
||||||
|
, m_real(size, real)
|
||||||
|
, m_imag(size, imag)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// Constructor from RealVector
|
||||||
|
ComplexVector::ComplexVector(const RealVector &real, const RealVector &imag)
|
||||||
|
: m_size(real.getSize())
|
||||||
|
, m_real(real, real.m_unary_modifier)
|
||||||
|
, m_imag(imag, imag.m_unary_modifier)
|
||||||
|
{
|
||||||
|
// Check if real and imag have same length
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Constructor from RealVector pointer
|
||||||
|
ComplexVector::ComplexVector(RealVector *real, RealVector *imag)
|
||||||
|
: m_size(real->getSize())
|
||||||
|
, m_real(*real)
|
||||||
|
, m_imag(*imag)
|
||||||
|
{
|
||||||
|
// Check if real and imag have same length
|
||||||
|
}
|
||||||
|
|
||||||
|
// Scalar constructor
|
||||||
|
ComplexVector::ComplexVector(radio_float_t real, radio_float_t imag)
|
||||||
|
: m_size(1)
|
||||||
|
, m_real(real)
|
||||||
|
, m_imag(imag)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
ComplexVector::ComplexVector(const _ComplexVector &src)
|
||||||
|
: m_size(src.m_size)
|
||||||
|
, m_real(src.m_real)
|
||||||
|
, m_imag(src.m_imag)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
_ComplexVector::_ComplexVector(const ComplexVector &src)
|
||||||
|
: m_size(src.m_size)
|
||||||
|
, m_real(src.m_real)
|
||||||
|
, m_imag(src.m_imag)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
_ComplexVector::_ComplexVector(const _RealVector &real, const _RealVector &imag)
|
||||||
|
: m_size(real.m_size)
|
||||||
|
, m_real(real)
|
||||||
|
, m_imag(imag)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ComplexVector::~ComplexVector(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
_ComplexVector _ComplexVector::operator-() const
|
||||||
|
{
|
||||||
|
return _ComplexVector(-this->m_real, -this->m_imag);
|
||||||
|
}
|
||||||
|
|
||||||
|
_ComplexVector _ComplexVector::conj() const
|
||||||
|
{
|
||||||
|
return _ComplexVector(this->m_real, -this->m_imag);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t ComplexVector::getSize()
|
||||||
|
{
|
||||||
|
return m_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
ComplexVector ComplexVector::at(uint32_t const &i)
|
||||||
|
{
|
||||||
|
return ComplexVector(*this, i, 1, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ComplexVector::print(char *pPrefix)
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
|
ComplexDebug("%s:\n", pPrefix);
|
||||||
|
for (i=0; i < m_size; i++)
|
||||||
|
{
|
||||||
|
if (m_imag.at(i).getValue() < 0)
|
||||||
|
{
|
||||||
|
ComplexDebug("%d: %.6f - %.6fj\n", i, m_real.at(i).getValue(), -m_imag.at(i).getValue());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ComplexDebug("%d: %.6f + %.6fj\n", i, m_real.at(i).getValue(), m_imag.at(i).getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ComplexVector ComplexVector::operator-() const
|
||||||
|
{
|
||||||
|
return ComplexVector(-this->m_real, -this->m_imag);
|
||||||
|
}
|
||||||
|
|
||||||
|
const ComplexVector& ComplexVector::operator+() const
|
||||||
|
{
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
ComplexVector ComplexVector::conj() const
|
||||||
|
{
|
||||||
|
return ComplexVector(this->m_real, -this->m_imag);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------------
|
||||||
|
// Assignments
|
||||||
|
// -------------------------------------------------
|
||||||
|
// = ComplexVector
|
||||||
|
ComplexVector& ComplexVector::operator=(const ComplexVector &src)
|
||||||
|
{
|
||||||
|
this->m_real = src.m_real;
|
||||||
|
this->m_imag = src.m_imag;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// += ComplexVector
|
||||||
|
ComplexVector& ComplexVector::operator+=(const ComplexVector &src)
|
||||||
|
{
|
||||||
|
this->m_real += src.m_real;
|
||||||
|
this->m_imag += src.m_imag;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -= ComplexVector
|
||||||
|
ComplexVector& ComplexVector::operator-=(const ComplexVector &src)
|
||||||
|
{
|
||||||
|
this->m_real -= src.m_real;
|
||||||
|
this->m_imag -= src.m_imag;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// *= ComplexVector
|
||||||
|
ComplexVector& ComplexVector::operator*=(const ComplexVector &src)
|
||||||
|
{
|
||||||
|
this->m_real = (this->m_real*src.m_real - this->m_imag*src.m_imag);
|
||||||
|
this->m_imag = (this->m_real*src.m_imag + this->m_imag*src.m_real);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// /= ComplexVector
|
||||||
|
ComplexVector& ComplexVector::operator/=(const ComplexVector &src)
|
||||||
|
{
|
||||||
|
// ToDo: Das ist falsch
|
||||||
|
this->m_real = (this->m_real*src.m_real - this->m_imag*src.m_imag);
|
||||||
|
this->m_imag = (this->m_real*src.m_imag + this->m_imag*src.m_real);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Binary operators
|
||||||
|
// = ComplexVector::OpBinaryAdd
|
||||||
|
ComplexVector& ComplexVector::operator=(OpBinary<ComplexVector::Add> src)
|
||||||
|
{
|
||||||
|
this->m_real = (src.a.m_real + src.b.m_real);
|
||||||
|
this->m_imag = (src.a.m_imag + src.b.m_imag);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// = ComplexVector::OpBinaryAdd
|
||||||
|
ComplexVector& ComplexVector::operator+=(OpBinary<ComplexVector::Add> src)
|
||||||
|
{
|
||||||
|
this->m_real += (src.a.m_real + src.b.m_real);
|
||||||
|
this->m_imag += (src.a.m_imag + src.b.m_imag);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// = ComplexVector::OpBinaryAdd
|
||||||
|
ComplexVector& ComplexVector::operator-=(OpBinary<ComplexVector::Add> src)
|
||||||
|
{
|
||||||
|
this->m_real -= (src.a.m_real + src.b.m_real);
|
||||||
|
this->m_imag -= (src.a.m_imag + src.b.m_imag);
|
||||||
|
return *this;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// = ComplexVector::OpBinaryAdd
|
||||||
|
ComplexVector& ComplexVector::operator*=(OpBinary<ComplexVector::Add> src)
|
||||||
|
{
|
||||||
|
// ToDo: this wird über schrieben
|
||||||
|
this->m_real = ((src.a.m_real + src.b.m_real)*this->m_real - (src.a.m_imag + src.b.m_imag)*this->m_imag);
|
||||||
|
this->m_imag = ((src.a.m_imag + src.b.m_imag)*this->m_real + (src.a.m_real + src.b.m_real)*this->m_imag);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// = ComplexVector::OpBinaryAdd
|
||||||
|
ComplexVector& ComplexVector::operator/=(OpBinary<ComplexVector::Add> src)
|
||||||
|
{
|
||||||
|
// ToDo: this wird über schrieben
|
||||||
|
// ToDo: Das ist falsch
|
||||||
|
this->m_real = ((src.a.m_real + src.b.m_real)*this->m_real - (src.a.m_imag + src.b.m_imag)*this->m_imag);
|
||||||
|
this->m_imag = ((src.a.m_imag + src.b.m_imag)*this->m_real + (src.a.m_real + src.b.m_real)*this->m_imag);
|
||||||
|
return *this;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// = ComplexVector::OpBinarySub
|
||||||
|
ComplexVector& ComplexVector::operator=(OpBinary<ComplexVector::Sub> src)
|
||||||
|
{
|
||||||
|
this->m_real = (src.a.m_real - src.b.m_real);
|
||||||
|
this->m_imag = (src.a.m_imag - src.b.m_imag);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// = ComplexVector::OpBinarySub
|
||||||
|
ComplexVector& ComplexVector::operator+=(OpBinary<ComplexVector::Sub> src)
|
||||||
|
{
|
||||||
|
this->m_real += (src.a.m_real - src.b.m_real);
|
||||||
|
this->m_imag += (src.a.m_imag - src.b.m_imag);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// = ComplexVector::OpBinarySub
|
||||||
|
ComplexVector& ComplexVector::operator-=(OpBinary<ComplexVector::Sub> src)
|
||||||
|
{
|
||||||
|
this->m_real -= (src.a.m_real - src.b.m_real);
|
||||||
|
this->m_imag -= (src.a.m_imag - src.b.m_imag);
|
||||||
|
return *this;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// = ComplexVector::OpBinarySub
|
||||||
|
ComplexVector& ComplexVector::operator*=(OpBinary<ComplexVector::Sub> src)
|
||||||
|
{
|
||||||
|
// ToDo: this wird über schrieben
|
||||||
|
this->m_real = ((src.a.m_real - src.b.m_real)*this->m_real - (src.a.m_imag - src.b.m_imag)*this->m_imag);
|
||||||
|
this->m_imag = ((src.a.m_imag - src.b.m_imag)*this->m_real + (src.a.m_real - src.b.m_real)*this->m_imag);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// = ComplexVector::OpBinarySub
|
||||||
|
ComplexVector& ComplexVector::operator/=(OpBinary<ComplexVector::Sub> src)
|
||||||
|
{
|
||||||
|
// ToDo: this wird über schrieben
|
||||||
|
// ToDo: Das ist falsch
|
||||||
|
this->m_real = ((src.a.m_real - src.b.m_real)*this->m_real - (src.a.m_imag - src.b.m_imag)*this->m_imag);
|
||||||
|
this->m_imag = ((src.a.m_imag - src.b.m_imag)*this->m_real + (src.a.m_real - src.b.m_real)*this->m_imag);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// = ComplexVector::OpBinaryMul
|
||||||
|
ComplexVector& ComplexVector::operator=(OpBinary<ComplexVector::Mul> src)
|
||||||
|
{
|
||||||
|
if ((this != &reinterpret_cast<ComplexVector&>(src.a)) && (this != &reinterpret_cast<ComplexVector&>(src.b)))
|
||||||
|
{
|
||||||
|
this->m_real = (src.a.m_real * src.b.m_real);
|
||||||
|
this->m_real -= (src.a.m_imag * src.b.m_imag);
|
||||||
|
|
||||||
|
this->m_imag = (src.a.m_real * src.b.m_imag);
|
||||||
|
this->m_imag += (src.a.m_imag * src.b.m_real);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ComplexVector result((src.a.m_real * src.b.m_real) - (src.a.m_imag * src.b.m_imag), (src.a.m_real * src.b.m_imag) + (src.a.m_imag * src.b.m_real));
|
||||||
|
*this = result;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// += ComplexVector::OpBinaryMul
|
||||||
|
ComplexVector& ComplexVector::operator+=(OpBinary<ComplexVector::Mul> src)
|
||||||
|
{
|
||||||
|
if ((this != &reinterpret_cast<ComplexVector&>(src.a)) && (this != &reinterpret_cast<ComplexVector&>(src.b)))
|
||||||
|
{
|
||||||
|
this->m_real += (src.a.m_real * src.b.m_real);
|
||||||
|
this->m_real -= (src.a.m_imag * src.b.m_imag);
|
||||||
|
|
||||||
|
this->m_imag += (src.a.m_real * src.b.m_imag);
|
||||||
|
this->m_imag += (src.a.m_imag * src.b.m_real);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ComplexVector result((src.a.m_real * src.b.m_real) - (src.a.m_imag * src.b.m_imag), (src.a.m_real * src.b.m_imag) + (src.a.m_imag * src.b.m_real));
|
||||||
|
*this = *this + result;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -= ComplexVector::OpBinaryMul
|
||||||
|
ComplexVector& ComplexVector::operator-=(OpBinary<ComplexVector::Mul> src)
|
||||||
|
{
|
||||||
|
if ((this != &reinterpret_cast<ComplexVector&>(src.a)) && (this != &reinterpret_cast<ComplexVector&>(src.b)))
|
||||||
|
{
|
||||||
|
this->m_real -= (src.a.m_real * src.b.m_real);
|
||||||
|
this->m_real += (src.a.m_imag * src.b.m_imag);
|
||||||
|
|
||||||
|
this->m_imag -= (src.a.m_real * src.b.m_imag);
|
||||||
|
this->m_imag -= (src.a.m_imag * src.b.m_real);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ComplexVector result((src.a.m_real * src.b.m_real) - (src.a.m_imag * src.b.m_imag), (src.a.m_real * src.b.m_imag) + (src.a.m_imag * src.b.m_real));
|
||||||
|
*this = *this - result;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// *= ComplexVector::OpBinaryMul
|
||||||
|
ComplexVector& ComplexVector::operator*=(OpBinary<ComplexVector::Mul> src)
|
||||||
|
{
|
||||||
|
ComplexVector result((src.a.m_real * src.b.m_real) - (src.a.m_imag * src.b.m_imag), (src.a.m_real * src.b.m_imag) + (src.a.m_imag * src.b.m_real));
|
||||||
|
*this = *this * result;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// /= ComplexVector::OpBinaryMul
|
||||||
|
ComplexVector& ComplexVector::operator/=(OpBinary<ComplexVector::Mul> src)
|
||||||
|
{
|
||||||
|
ComplexVector result((src.a.m_real * src.b.m_real) - (src.a.m_imag * src.b.m_imag), (src.a.m_real * src.b.m_imag) + (src.a.m_imag * src.b.m_real));
|
||||||
|
*this = *this / result;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Div
|
||||||
|
// = ComplexVector::OpBinaryDiv
|
||||||
|
ComplexVector& ComplexVector::operator=(OpBinary<ComplexVector::Div> src)
|
||||||
|
{
|
||||||
|
if ((this != &reinterpret_cast<ComplexVector&>(src.a)) && (this != &reinterpret_cast<ComplexVector&>(src.b)))
|
||||||
|
{
|
||||||
|
this->m_real = (src.a.m_real * src.b.m_real);
|
||||||
|
this->m_real -= (src.a.m_imag * src.b.m_imag);
|
||||||
|
|
||||||
|
this->m_imag = (src.a.m_real * src.b.m_imag);
|
||||||
|
this->m_imag += (src.a.m_imag * src.b.m_real);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ComplexVector result((src.a.m_real * src.b.m_real) - (src.a.m_imag * src.b.m_imag), (src.a.m_real * src.b.m_imag) + (src.a.m_imag * src.b.m_real));
|
||||||
|
*this = result;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// += ComplexVector::OpBinaryDiv
|
||||||
|
ComplexVector& ComplexVector::operator+=(OpBinary<ComplexVector::Div> src)
|
||||||
|
{
|
||||||
|
if ((this != &reinterpret_cast<ComplexVector&>(src.a)) && (this != &reinterpret_cast<ComplexVector&>(src.b)))
|
||||||
|
{
|
||||||
|
this->m_real += (src.a.m_real * src.b.m_real);
|
||||||
|
this->m_real -= (src.a.m_imag * src.b.m_imag);
|
||||||
|
|
||||||
|
this->m_imag += (src.a.m_real * src.b.m_imag);
|
||||||
|
this->m_imag += (src.a.m_imag * src.b.m_real);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ComplexVector result((src.a.m_real * src.b.m_real) - (src.a.m_imag * src.b.m_imag), (src.a.m_real * src.b.m_imag) + (src.a.m_imag * src.b.m_real));
|
||||||
|
*this = *this + result;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -= ComplexVector::OpBinaryDiv
|
||||||
|
ComplexVector& ComplexVector::operator-=(OpBinary<ComplexVector::Div> src)
|
||||||
|
{
|
||||||
|
if ((this != &reinterpret_cast<ComplexVector&>(src.a)) && (this != &reinterpret_cast<ComplexVector&>(src.b)))
|
||||||
|
{
|
||||||
|
this->m_real -= (src.a.m_real * src.b.m_real);
|
||||||
|
this->m_real += (src.a.m_imag * src.b.m_imag);
|
||||||
|
|
||||||
|
this->m_imag -= (src.a.m_real * src.b.m_imag);
|
||||||
|
this->m_imag -= (src.a.m_imag * src.b.m_real);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ComplexVector result((src.a.m_real * src.b.m_real) - (src.a.m_imag * src.b.m_imag), (src.a.m_real * src.b.m_imag) + (src.a.m_imag * src.b.m_real));
|
||||||
|
*this = *this - result;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// *= ComplexVector::OpBinaryDiv
|
||||||
|
ComplexVector& ComplexVector::operator*=(OpBinary<ComplexVector::Div> src)
|
||||||
|
{
|
||||||
|
ComplexVector result((src.a.m_real * src.b.m_real) - (src.a.m_imag * src.b.m_imag), (src.a.m_real * src.b.m_imag) + (src.a.m_imag * src.b.m_real));
|
||||||
|
*this = *this * result;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// /= ComplexVector::OpBinaryDiv
|
||||||
|
ComplexVector& ComplexVector::operator/=(OpBinary<ComplexVector::Div> src)
|
||||||
|
{
|
||||||
|
ComplexVector result((src.a.m_real * src.b.m_real) - (src.a.m_imag * src.b.m_imag), (src.a.m_real * src.b.m_imag) + (src.a.m_imag * src.b.m_real));
|
||||||
|
*this = *this / result;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------------
|
||||||
|
// Binary Operators
|
||||||
|
// -------------------------------------------------
|
||||||
|
// Add
|
||||||
|
// ComplexVector + ComplexVector*
|
||||||
|
ComplexVector::OpBinary<ComplexVector::Add> operator+(const ComplexVector &a, const ComplexVector &b)
|
||||||
|
{
|
||||||
|
return ComplexVector::OpBinary<ComplexVector::Add> (a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sub
|
||||||
|
// ComplexVector - ComplexVector*
|
||||||
|
ComplexVector::OpBinary<ComplexVector::Sub> operator-(const ComplexVector &a, const ComplexVector &b)
|
||||||
|
{
|
||||||
|
return ComplexVector::OpBinary<ComplexVector::Sub> (a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mul
|
||||||
|
// ComplexVector * ComplexVector*
|
||||||
|
ComplexVector::OpBinary<ComplexVector::Mul> operator*(const ComplexVector &a, const ComplexVector &b)
|
||||||
|
{
|
||||||
|
return ComplexVector::OpBinary<ComplexVector::Mul> (a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Div
|
||||||
|
// ComplexVector / ComplexVector*
|
||||||
|
ComplexVector::OpBinary<ComplexVector::Div> operator/(const ComplexVector &a, const ComplexVector &b)
|
||||||
|
{
|
||||||
|
return ComplexVector::OpBinary<ComplexVector::Div> (a, b);
|
||||||
|
}
|
||||||
Executable
+192
@@ -0,0 +1,192 @@
|
|||||||
|
#ifndef _COMPLEX_HPP_
|
||||||
|
#define _COMPLEX_HPP_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <memory.h>
|
||||||
|
#include <radio/radio_types.h>
|
||||||
|
#include <radio/RealVector.hpp>
|
||||||
|
|
||||||
|
void ComplexDebug(char *fmtstr, ...);
|
||||||
|
|
||||||
|
class ComplexException
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ComplexException (std::string s)
|
||||||
|
{
|
||||||
|
m_what = s;
|
||||||
|
}
|
||||||
|
~ComplexException()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
std::string& what()
|
||||||
|
{
|
||||||
|
return m_what;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
std::string m_what;
|
||||||
|
};
|
||||||
|
|
||||||
|
class _ComplexVector;
|
||||||
|
class ComplexVector
|
||||||
|
{
|
||||||
|
friend class _ComplexVector;
|
||||||
|
public:
|
||||||
|
|
||||||
|
enum OpType
|
||||||
|
{
|
||||||
|
Add = 0,
|
||||||
|
Sub,
|
||||||
|
Mul,
|
||||||
|
Div
|
||||||
|
};
|
||||||
|
|
||||||
|
template <OpType op>
|
||||||
|
struct OpBinary
|
||||||
|
{
|
||||||
|
_ComplexVector a;
|
||||||
|
_ComplexVector b;
|
||||||
|
|
||||||
|
OpBinary(const _ComplexVector a_, const _ComplexVector b_)
|
||||||
|
: a(a_)
|
||||||
|
, b(b_)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
~OpBinary()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
OpBinary& operator=(const OpBinary&);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Standard constructor
|
||||||
|
ComplexVector(uint32_t size, radio_float_t *real=0, radio_float_t *imag=0);
|
||||||
|
|
||||||
|
// Constructor from RealVector
|
||||||
|
ComplexVector(const RealVector &real, const RealVector &imag);
|
||||||
|
|
||||||
|
// Constructeur de RealVector de la pointe
|
||||||
|
ComplexVector(RealVector *real, RealVector *imag);
|
||||||
|
|
||||||
|
// Scalar constructor
|
||||||
|
ComplexVector(radio_float_t real, radio_float_t imag);
|
||||||
|
|
||||||
|
// Unary resolver constructor (no data copy)
|
||||||
|
ComplexVector(const _ComplexVector &src);
|
||||||
|
|
||||||
|
~ComplexVector(void);
|
||||||
|
|
||||||
|
uint32_t getSize();
|
||||||
|
ComplexVector at(uint32_t const &i);
|
||||||
|
void print(char *pPrefix);
|
||||||
|
bool isNegative() const;
|
||||||
|
bool isPositive() const;
|
||||||
|
bool isConjugate() const;
|
||||||
|
ComplexVector operator-() const;
|
||||||
|
const ComplexVector& operator+() const;
|
||||||
|
ComplexVector conj() const;
|
||||||
|
|
||||||
|
// Assignments
|
||||||
|
ComplexVector& operator=(const ComplexVector &src);
|
||||||
|
ComplexVector& operator+=(const ComplexVector &src);
|
||||||
|
ComplexVector& operator-=(const ComplexVector &src);
|
||||||
|
ComplexVector& operator*=(const ComplexVector &src);
|
||||||
|
ComplexVector& operator/=(const ComplexVector &src);
|
||||||
|
|
||||||
|
ComplexVector& operator=(OpBinary<ComplexVector::Add> src);
|
||||||
|
ComplexVector& operator+=(OpBinary<ComplexVector::Add> src);
|
||||||
|
ComplexVector& operator-=(OpBinary<ComplexVector::Add> src);
|
||||||
|
ComplexVector& operator*=(OpBinary<ComplexVector::Add> src);
|
||||||
|
ComplexVector& operator/=(OpBinary<ComplexVector::Add> src);
|
||||||
|
|
||||||
|
ComplexVector& operator=(OpBinary<ComplexVector::Sub> src);
|
||||||
|
ComplexVector& operator+=(OpBinary<ComplexVector::Sub> src);
|
||||||
|
ComplexVector& operator-=(OpBinary<ComplexVector::Sub> src);
|
||||||
|
ComplexVector& operator*=(OpBinary<ComplexVector::Sub> src);
|
||||||
|
ComplexVector& operator/=(OpBinary<ComplexVector::Sub> src);
|
||||||
|
|
||||||
|
ComplexVector& operator=(OpBinary<ComplexVector::Mul> src);
|
||||||
|
ComplexVector& operator+=(OpBinary<ComplexVector::Mul> src);
|
||||||
|
ComplexVector& operator-=(OpBinary<ComplexVector::Mul> src);
|
||||||
|
ComplexVector& operator*=(OpBinary<ComplexVector::Mul> src);
|
||||||
|
ComplexVector& operator/=(OpBinary<ComplexVector::Mul> src);
|
||||||
|
|
||||||
|
ComplexVector& operator=(OpBinary<ComplexVector::Div> src);
|
||||||
|
ComplexVector& operator+=(OpBinary<ComplexVector::Div> src);
|
||||||
|
ComplexVector& operator-=(OpBinary<ComplexVector::Div> src);
|
||||||
|
ComplexVector& operator*=(OpBinary<ComplexVector::Div> src);
|
||||||
|
ComplexVector& operator/=(OpBinary<ComplexVector::Div> src);
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint32_t m_size;
|
||||||
|
RealVector m_real;
|
||||||
|
RealVector m_imag;
|
||||||
|
|
||||||
|
// Slicing constructor
|
||||||
|
ComplexVector(const ComplexVector &src, uint32_t from, uint32_t step, uint32_t to)
|
||||||
|
: m_size(0)
|
||||||
|
, m_real(src.m_real, from, step, to)
|
||||||
|
, m_imag(src.m_imag, from, step, to)
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
|
for (i=from; i <= to; i+=step)
|
||||||
|
{
|
||||||
|
m_size++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_inline void checkSize(uint32_t size1, uint32_t size2)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if ((size1 != size2) && (size2 != 1))
|
||||||
|
{
|
||||||
|
throw(ComplexException("Size mismatch"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(ComplexException &exc)
|
||||||
|
{
|
||||||
|
ComplexDebug("Problem: %s\n", exc.what().c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class _ComplexVector
|
||||||
|
{
|
||||||
|
friend class ComplexVector;
|
||||||
|
public:
|
||||||
|
_ComplexVector(const ComplexVector &src);
|
||||||
|
_ComplexVector(const _RealVector &real, const _RealVector &imag);
|
||||||
|
_ComplexVector _ComplexVector::operator-() const;
|
||||||
|
_ComplexVector _ComplexVector::conj() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint32_t m_size;
|
||||||
|
_RealVector m_real;
|
||||||
|
_RealVector m_imag;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
// Non-Member
|
||||||
|
// Binary Operators
|
||||||
|
|
||||||
|
// Add
|
||||||
|
// ComplexVector + ComplexVector*
|
||||||
|
ComplexVector::OpBinary<ComplexVector::Add> operator+(const ComplexVector &a, const ComplexVector &b);
|
||||||
|
|
||||||
|
// Sub
|
||||||
|
// ComplexVector - ComplexVector*
|
||||||
|
ComplexVector::OpBinary<ComplexVector::Sub> operator-(const ComplexVector &a, const ComplexVector &b);
|
||||||
|
|
||||||
|
// Mul
|
||||||
|
// ComplexVector * ComplexVector*
|
||||||
|
ComplexVector::OpBinary<ComplexVector::Mul> operator*(const ComplexVector &a, const ComplexVector &b);
|
||||||
|
|
||||||
|
// Div
|
||||||
|
// ComplexVector / ComplexVector*
|
||||||
|
ComplexVector::OpBinary<ComplexVector::Div> operator/(const ComplexVector &a, const ComplexVector &b);
|
||||||
|
|
||||||
|
#endif // _COMPLEX_HPP_
|
||||||
Executable
+1182
File diff suppressed because it is too large
Load Diff
Executable
+1089
File diff suppressed because it is too large
Load Diff
Executable
+234
@@ -0,0 +1,234 @@
|
|||||||
|
#ifndef _REAL_HPP_
|
||||||
|
#define _REAL_HPP_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <memory.h>
|
||||||
|
#include <radio/radio_types.h>
|
||||||
|
|
||||||
|
void RealDebug(char *fmtstr, ...);
|
||||||
|
|
||||||
|
class RealException
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RealException (std::string s)
|
||||||
|
{
|
||||||
|
m_what = s;
|
||||||
|
}
|
||||||
|
~RealException()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
std::string& what()
|
||||||
|
{
|
||||||
|
return m_what;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
std::string m_what;
|
||||||
|
};
|
||||||
|
|
||||||
|
class _RealVector;
|
||||||
|
|
||||||
|
class RealVector
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
friend class _RealVector;
|
||||||
|
struct unary_t
|
||||||
|
{
|
||||||
|
bool negative;
|
||||||
|
|
||||||
|
unary_t()
|
||||||
|
: negative(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
struct unary_t neg(bool doNegative)
|
||||||
|
{
|
||||||
|
negative = doNegative;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
enum OpType
|
||||||
|
{
|
||||||
|
Add = 0,
|
||||||
|
Sub,
|
||||||
|
Mul,
|
||||||
|
Div
|
||||||
|
};
|
||||||
|
|
||||||
|
template <OpType op>
|
||||||
|
class OpBinary
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
const RealVector &a;
|
||||||
|
const RealVector &b;
|
||||||
|
unary_t m_unary_modifier;
|
||||||
|
|
||||||
|
OpBinary(const RealVector &a, const RealVector &b)
|
||||||
|
: a(a)
|
||||||
|
, b(b)
|
||||||
|
, m_unary_modifier()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
OpBinary(const OpBinary &src, unary_t unary_modifier)
|
||||||
|
: a(src.a)
|
||||||
|
, b(src.b)
|
||||||
|
, m_unary_modifier(unary_modifier)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isNegative() const
|
||||||
|
{
|
||||||
|
return m_unary_modifier.negative;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isPositive() const
|
||||||
|
{
|
||||||
|
return !m_unary_modifier.negative;
|
||||||
|
}
|
||||||
|
|
||||||
|
OpBinary operator-() const
|
||||||
|
{
|
||||||
|
unary_t unary = m_unary_modifier;
|
||||||
|
unary.negative = !unary.negative;
|
||||||
|
|
||||||
|
return OpBinary(*this, unary);
|
||||||
|
}
|
||||||
|
|
||||||
|
const OpBinary& operator+() const
|
||||||
|
{
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
~OpBinary()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
OpBinary& operator=(const OpBinary&);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Construct from float array
|
||||||
|
RealVector(uint32_t size, radio_float_t *real=0);
|
||||||
|
|
||||||
|
// Copy constructor
|
||||||
|
RealVector(const RealVector &src);
|
||||||
|
|
||||||
|
// Slicing constructor
|
||||||
|
RealVector(const RealVector &src, uint32_t from, uint32_t step, uint32_t to);
|
||||||
|
|
||||||
|
// Unary resolver constructor (no data copy)
|
||||||
|
RealVector(const RealVector &src, unary_t unary_modifier);
|
||||||
|
|
||||||
|
// OpBinaryAdd resolver copy constructor
|
||||||
|
RealVector(const OpBinary<Add> &src);
|
||||||
|
|
||||||
|
// OpBinarySub resolver copy constructor
|
||||||
|
RealVector(const OpBinary<Sub> &src);
|
||||||
|
|
||||||
|
// OpBinaryMul resolver copy constructor
|
||||||
|
RealVector(const OpBinary<Mul> &src);
|
||||||
|
|
||||||
|
// OpBinaryDiv resolver copy constructor
|
||||||
|
RealVector(const OpBinary<Div> &src);
|
||||||
|
|
||||||
|
// Scalar constructor
|
||||||
|
RealVector(radio_float_t real);
|
||||||
|
|
||||||
|
RealVector(const _RealVector &src);
|
||||||
|
|
||||||
|
~RealVector(void);
|
||||||
|
|
||||||
|
uint32_t getSize() const;
|
||||||
|
radio_float_t getValue() const;
|
||||||
|
RealVector at(uint32_t const &i);
|
||||||
|
RealVector slice(uint32_t from, uint32_t step, uint32_t to);
|
||||||
|
void print(char *pPrefix) const;
|
||||||
|
bool isNegative() const;
|
||||||
|
bool isPositive() const;
|
||||||
|
RealVector operator-() const;
|
||||||
|
const RealVector& operator+() const;
|
||||||
|
|
||||||
|
// Assignments
|
||||||
|
RealVector& operator=(const RealVector &src);
|
||||||
|
RealVector& operator+=(const RealVector &src);
|
||||||
|
RealVector& operator-=(const RealVector &src);
|
||||||
|
RealVector& operator*=(const RealVector &src);
|
||||||
|
RealVector& operator/=(const RealVector &src);
|
||||||
|
|
||||||
|
RealVector& operator=(const OpBinary<Add> &src);
|
||||||
|
RealVector& operator+=(const OpBinary<Add> &src);
|
||||||
|
RealVector& operator-=(const OpBinary<Add> &src);
|
||||||
|
RealVector& operator*=(const OpBinary<Add> &src);
|
||||||
|
RealVector& operator/=(const OpBinary<Add> &src);
|
||||||
|
|
||||||
|
RealVector& operator=(const OpBinary<Sub> &src);
|
||||||
|
RealVector& operator+=(const OpBinary<Sub> &src);
|
||||||
|
RealVector& operator-=(const OpBinary<Sub> &src);
|
||||||
|
RealVector& operator*=(const OpBinary<Sub> &src);
|
||||||
|
RealVector& operator/=(const OpBinary<Sub> &src);
|
||||||
|
|
||||||
|
RealVector& operator=(const OpBinary<Mul> &src);
|
||||||
|
RealVector& operator+=(const OpBinary<Mul> &src);
|
||||||
|
RealVector& operator-=(const OpBinary<Mul> &src);
|
||||||
|
RealVector& operator*=(const OpBinary<Mul> &src);
|
||||||
|
RealVector& operator/=(const OpBinary<Mul> &src);
|
||||||
|
|
||||||
|
RealVector& operator=(const OpBinary<Div> &src);
|
||||||
|
RealVector& operator+=(const OpBinary<Div> &src);
|
||||||
|
RealVector& operator-=(const OpBinary<Div> &src);
|
||||||
|
RealVector& operator*=(const OpBinary<Div> &src);
|
||||||
|
RealVector& operator/=(const OpBinary<Div> &src);
|
||||||
|
|
||||||
|
unary_t m_unary_modifier;
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint32_t m_size;
|
||||||
|
radio_float_t m_real;
|
||||||
|
radio_float_t *m_pBufReal;
|
||||||
|
radio_float_t *m_pPtrReal;
|
||||||
|
|
||||||
|
_inline void checkSize(uint32_t size1, uint32_t size2)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if ((size1 != size2) && (size2 != 1))
|
||||||
|
{
|
||||||
|
throw(RealException("Size mismatch"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(RealException &exc)
|
||||||
|
{
|
||||||
|
RealDebug("Problem: %s\n", exc.what().c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class _RealVector
|
||||||
|
{
|
||||||
|
friend class RealVector;
|
||||||
|
public:
|
||||||
|
_RealVector(const RealVector &src);
|
||||||
|
_RealVector(const _RealVector &src, RealVector::unary_t unary_modifier);
|
||||||
|
_RealVector operator-() const;
|
||||||
|
uint32_t m_size;
|
||||||
|
|
||||||
|
private:
|
||||||
|
radio_float_t m_real;
|
||||||
|
radio_float_t *m_pBufReal;
|
||||||
|
radio_float_t *m_pPtrReal;
|
||||||
|
RealVector::unary_t m_unary_modifier;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
// Non-Member
|
||||||
|
// Binary Operators
|
||||||
|
// Returning RealVector::OpBinary
|
||||||
|
RealVector::OpBinary<RealVector::Add> operator+(const RealVector &a, const RealVector &b);
|
||||||
|
RealVector::OpBinary<RealVector::Sub> operator-(const RealVector &a, const RealVector &b);
|
||||||
|
RealVector::OpBinary<RealVector::Mul> operator*(const RealVector &a, const RealVector &b);
|
||||||
|
RealVector::OpBinary<RealVector::Div> operator/(const RealVector &a, const RealVector &b);
|
||||||
|
|
||||||
|
#endif // _REAL_HPP_
|
||||||
Executable
+403
@@ -0,0 +1,403 @@
|
|||||||
|
#ifndef _REAL_HPP_
|
||||||
|
#define _REAL_HPP_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <memory.h>
|
||||||
|
#include <radio/radio_types.h>
|
||||||
|
|
||||||
|
void RealDebug(char *fmtstr, ...);
|
||||||
|
|
||||||
|
class RealException
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RealException (std::string s)
|
||||||
|
{
|
||||||
|
m_what = s;
|
||||||
|
}
|
||||||
|
~RealException()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
std::string& what()
|
||||||
|
{
|
||||||
|
return m_what;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
std::string m_what;
|
||||||
|
};
|
||||||
|
|
||||||
|
class RealVectorNegative;
|
||||||
|
|
||||||
|
class RealVector
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
struct OpBinaryAdd
|
||||||
|
{
|
||||||
|
struct Negative
|
||||||
|
{
|
||||||
|
Negative(const OpBinaryAdd src)
|
||||||
|
: a(src.a)
|
||||||
|
, b(src.b)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
OpBinaryAdd operator-() const
|
||||||
|
{
|
||||||
|
return OpBinaryAdd(a, b);
|
||||||
|
}
|
||||||
|
const RealVector &a;
|
||||||
|
const RealVector &b;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Negative& operator=(const Negative&);
|
||||||
|
};
|
||||||
|
|
||||||
|
OpBinaryAdd(const RealVector &a, const RealVector &b)
|
||||||
|
: a(a)
|
||||||
|
, b(b)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Negative operator-() const
|
||||||
|
{
|
||||||
|
return Negative(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
const OpBinaryAdd& operator+() const
|
||||||
|
{
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
~OpBinaryAdd()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
const RealVector &a;
|
||||||
|
const RealVector &b;
|
||||||
|
|
||||||
|
private:
|
||||||
|
OpBinaryAdd& operator=(const OpBinaryAdd&);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct OpBinarySub
|
||||||
|
{
|
||||||
|
struct Negative
|
||||||
|
{
|
||||||
|
Negative(const OpBinarySub src)
|
||||||
|
: a(src.a)
|
||||||
|
, b(src.b)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
OpBinarySub operator-() const
|
||||||
|
{
|
||||||
|
return OpBinarySub(a, b);
|
||||||
|
}
|
||||||
|
const RealVector &a;
|
||||||
|
const RealVector &b;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Negative& operator=(const Negative&);
|
||||||
|
};
|
||||||
|
|
||||||
|
OpBinarySub(const RealVector &a, const RealVector &b)
|
||||||
|
: a(a)
|
||||||
|
, b(b)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
~OpBinarySub()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Negative operator-() const
|
||||||
|
{
|
||||||
|
return Negative(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
const OpBinarySub& operator+() const
|
||||||
|
{
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
const RealVector &a;
|
||||||
|
const RealVector &b;
|
||||||
|
|
||||||
|
private:
|
||||||
|
OpBinarySub& operator=(const OpBinarySub&);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct OpBinaryMul
|
||||||
|
{
|
||||||
|
struct Negative
|
||||||
|
{
|
||||||
|
Negative(const OpBinaryMul src)
|
||||||
|
: a(src.a)
|
||||||
|
, b(src.b)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
OpBinaryMul operator-() const
|
||||||
|
{
|
||||||
|
return OpBinaryMul(a, b);
|
||||||
|
}
|
||||||
|
const RealVector &a;
|
||||||
|
const RealVector &b;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Negative& operator=(const Negative&);
|
||||||
|
};
|
||||||
|
|
||||||
|
OpBinaryMul(const RealVector &a, const RealVector &b)
|
||||||
|
: a(a)
|
||||||
|
, b(b)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Negative operator-() const
|
||||||
|
{
|
||||||
|
return Negative(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
const OpBinaryMul& operator+() const
|
||||||
|
{
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
~OpBinaryMul()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
const RealVector &a;
|
||||||
|
const RealVector &b;
|
||||||
|
|
||||||
|
private:
|
||||||
|
OpBinaryMul& operator=(const OpBinaryMul&);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct OpBinaryDiv
|
||||||
|
{
|
||||||
|
struct Negative
|
||||||
|
{
|
||||||
|
Negative(const OpBinaryDiv src)
|
||||||
|
: a(src.a)
|
||||||
|
, b(src.b)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
OpBinaryDiv operator-() const
|
||||||
|
{
|
||||||
|
return OpBinaryDiv(a, b);
|
||||||
|
}
|
||||||
|
const RealVector &a;
|
||||||
|
const RealVector &b;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Negative& operator=(const Negative&);
|
||||||
|
};
|
||||||
|
|
||||||
|
OpBinaryDiv(const RealVector &a, const RealVector &b)
|
||||||
|
: a(a)
|
||||||
|
, b(b)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Negative operator-() const
|
||||||
|
{
|
||||||
|
return Negative(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
const OpBinaryDiv& operator+() const
|
||||||
|
{
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
~OpBinaryDiv()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
const RealVector &a;
|
||||||
|
const RealVector &b;
|
||||||
|
|
||||||
|
private:
|
||||||
|
OpBinaryDiv& operator=(const OpBinaryDiv&);
|
||||||
|
};
|
||||||
|
|
||||||
|
~RealVector(void);
|
||||||
|
|
||||||
|
// Standard constructor
|
||||||
|
RealVector(uint32_t size, radio_float_t *real=0);
|
||||||
|
|
||||||
|
// Copy constructor
|
||||||
|
RealVector(const RealVector &src);
|
||||||
|
|
||||||
|
// Slicing constructor
|
||||||
|
RealVector(RealVector &src, uint32_t from, uint32_t step, uint32_t to);
|
||||||
|
|
||||||
|
// Negative resolver copy constructor
|
||||||
|
RealVector(const RealVectorNegative &src);
|
||||||
|
|
||||||
|
// OpBinaryAdd resolver copy constructor
|
||||||
|
RealVector(const OpBinaryAdd &src);
|
||||||
|
|
||||||
|
// OpBinaryAdd::Negative resolver copy constructor
|
||||||
|
RealVector(const OpBinaryAdd::Negative &src);
|
||||||
|
|
||||||
|
// OpBinarySub resolver copy constructor
|
||||||
|
RealVector(const OpBinarySub &src);
|
||||||
|
|
||||||
|
// OpBinaryMul resolver copy constructor
|
||||||
|
RealVector(const OpBinaryMul &src);
|
||||||
|
|
||||||
|
// OpBinaryMul::Negative resolver copy constructor
|
||||||
|
RealVector(const OpBinaryMul::Negative &src);
|
||||||
|
|
||||||
|
// OpBinaryDiv resolver copy constructor
|
||||||
|
RealVector(const OpBinaryDiv &src);
|
||||||
|
|
||||||
|
// OpBinaryDiv::Negative resolver copy constructor
|
||||||
|
RealVector(const OpBinaryDiv::Negative &src);
|
||||||
|
|
||||||
|
// Scalar constructor
|
||||||
|
RealVector(radio_float_t real);
|
||||||
|
|
||||||
|
uint32_t getSize() const;
|
||||||
|
|
||||||
|
radio_float_t getValue() const;
|
||||||
|
|
||||||
|
RealVector at(uint32_t const &i);
|
||||||
|
void print(char *pPrefix) const;
|
||||||
|
|
||||||
|
RealVectorNegative operator-() const;
|
||||||
|
const RealVector& operator+() const;
|
||||||
|
|
||||||
|
// Assignments
|
||||||
|
RealVector& operator=(const RealVector &src);
|
||||||
|
RealVector& operator+=(const RealVector &src);
|
||||||
|
RealVector& operator-=(const RealVector &src);
|
||||||
|
RealVector& operator*=(const RealVector &src);
|
||||||
|
RealVector& operator/=(const RealVector &src);
|
||||||
|
|
||||||
|
RealVector& operator=(const RealVectorNegative &src);
|
||||||
|
RealVector& operator+=(const RealVectorNegative &src);
|
||||||
|
RealVector& operator-=(const RealVectorNegative &src);
|
||||||
|
RealVector& operator*=(const RealVectorNegative &src);
|
||||||
|
RealVector& operator/=(const RealVectorNegative &src);
|
||||||
|
|
||||||
|
RealVector& operator=(const OpBinaryAdd &src);
|
||||||
|
RealVector& operator+=(const OpBinaryAdd &src);
|
||||||
|
RealVector& operator-=(const OpBinaryAdd &src);
|
||||||
|
RealVector& operator*=(const OpBinaryAdd &src);
|
||||||
|
RealVector& operator/=(const OpBinaryAdd &src);
|
||||||
|
|
||||||
|
RealVector& operator=(const OpBinaryAdd::Negative &src);
|
||||||
|
RealVector& operator+=(const OpBinaryAdd::Negative &src);
|
||||||
|
RealVector& operator-=(const OpBinaryAdd::Negative &src);
|
||||||
|
RealVector& operator*=(const OpBinaryAdd::Negative &src);
|
||||||
|
RealVector& operator/=(const OpBinaryAdd::Negative &src);
|
||||||
|
|
||||||
|
RealVector& operator=(const OpBinarySub &src);
|
||||||
|
RealVector& operator+=(const OpBinarySub &src);
|
||||||
|
RealVector& operator-=(const OpBinarySub &src);
|
||||||
|
RealVector& operator*=(const OpBinarySub &src);
|
||||||
|
RealVector& operator/=(const OpBinarySub &src);
|
||||||
|
|
||||||
|
RealVector& operator=(const OpBinaryMul &src);
|
||||||
|
RealVector& operator+=(const OpBinaryMul &src);
|
||||||
|
RealVector& operator-=(const OpBinaryMul &src);
|
||||||
|
RealVector& operator*=(const OpBinaryMul &src);
|
||||||
|
RealVector& operator/=(const OpBinaryMul &src);
|
||||||
|
|
||||||
|
RealVector& operator=(const OpBinaryMul::Negative &src);
|
||||||
|
RealVector& operator+=(const OpBinaryMul::Negative &src);
|
||||||
|
RealVector& operator-=(const OpBinaryMul::Negative &src);
|
||||||
|
RealVector& operator*=(const OpBinaryMul::Negative &src);
|
||||||
|
RealVector& operator/=(const OpBinaryMul::Negative &src);
|
||||||
|
|
||||||
|
RealVector& operator=(const OpBinaryDiv &src);
|
||||||
|
RealVector& operator+=(const OpBinaryDiv &src);
|
||||||
|
RealVector& operator-=(const OpBinaryDiv &src);
|
||||||
|
RealVector& operator*=(const OpBinaryDiv &src);
|
||||||
|
RealVector& operator/=(const OpBinaryDiv &src);
|
||||||
|
|
||||||
|
RealVector& operator=(const OpBinaryDiv::Negative &src);
|
||||||
|
RealVector& operator+=(const OpBinaryDiv::Negative &src);
|
||||||
|
RealVector& operator-=(const OpBinaryDiv::Negative &src);
|
||||||
|
RealVector& operator*=(const OpBinaryDiv::Negative &src);
|
||||||
|
RealVector& operator/=(const OpBinaryDiv::Negative &src);
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint32_t m_size;
|
||||||
|
radio_float_t m_real;
|
||||||
|
radio_float_t *m_pBufReal;
|
||||||
|
radio_float_t *m_pPtrReal;
|
||||||
|
|
||||||
|
_inline void checkSize(uint32_t size1, uint32_t size2)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if ((size1 != size2) && (size2 != 1))
|
||||||
|
{
|
||||||
|
throw(RealException("Size mismatch"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(RealException &exc)
|
||||||
|
{
|
||||||
|
RealDebug("Problem: %s\n", exc.what().c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class RealVectorNegative : public RealVector
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RealVectorNegative(const RealVector &src)
|
||||||
|
: RealVector(src)
|
||||||
|
, m_iamNegative(true)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
const RealVector& operator-() const
|
||||||
|
{
|
||||||
|
return (RealVector&)*this;
|
||||||
|
}
|
||||||
|
|
||||||
|
const RealVectorNegative& operator+() const
|
||||||
|
{
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool m_iamNegative;
|
||||||
|
RealVectorNegative& operator=(const RealVectorNegative&);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Non-Member
|
||||||
|
// Binary Operators
|
||||||
|
// Returning RealVector::OpBinary
|
||||||
|
RealVector::OpBinaryAdd operator+(const RealVector &a, const RealVector &b);
|
||||||
|
#if 0
|
||||||
|
RealVector::OpBinarySub operator+(const RealVectorNegative &a, const RealVector &b);
|
||||||
|
RealVector::OpBinarySub operator+(const RealVector &a, const RealVectorNegative &b);
|
||||||
|
RealVector::OpBinaryAdd::Negative operator+(const RealVectorNegative &a, const RealVectorNegative &b);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
RealVector::OpBinarySub operator-(const RealVector &a, const RealVector &b);
|
||||||
|
#if 0
|
||||||
|
RealVector::OpBinaryAdd::Negative operator-(const RealVectorNegative &a, const RealVector &b);
|
||||||
|
RealVector::OpBinaryAdd operator-(const RealVector &a, const RealVectorNegative &b);
|
||||||
|
RealVector::OpBinarySub operator-(const RealVectorNegative &a, const RealVectorNegative &b);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
RealVector::OpBinaryMul operator*(const RealVector &a, const RealVector &b);
|
||||||
|
#if 0
|
||||||
|
RealVector::OpBinaryMul::Negative operator*(const RealVectorNegative &a, const RealVector &b);
|
||||||
|
RealVector::OpBinaryMul::Negative operator*(const RealVector &a, const RealVectorNegative &b);
|
||||||
|
RealVector::OpBinaryMul operator*(const RealVectorNegative &a, const RealVectorNegative &b);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
RealVector::OpBinaryDiv operator/(const RealVector &a, const RealVector &b);
|
||||||
|
RealVector::OpBinaryDiv::Negative operator/(const RealVectorNegative &a, const RealVector &b);
|
||||||
|
RealVector::OpBinaryDiv::Negative operator/(const RealVector &a, const RealVectorNegative &b);
|
||||||
|
RealVector::OpBinaryDiv operator/(const RealVectorNegative &a, const RealVectorNegative &b);
|
||||||
|
|
||||||
|
#endif // _REAL_HPP_
|
||||||
Executable
+785
@@ -0,0 +1,785 @@
|
|||||||
|
#include <windows.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "RealVector.hpp"
|
||||||
|
|
||||||
|
void RealDebug(char *fmtstr, ...)
|
||||||
|
{
|
||||||
|
char buf[1024];
|
||||||
|
va_list args;
|
||||||
|
|
||||||
|
va_start(args, fmtstr);
|
||||||
|
vsprintf(buf, fmtstr, args);
|
||||||
|
va_end(args);
|
||||||
|
OutputDebugString(buf);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------------
|
||||||
|
// Assignments
|
||||||
|
// -------------------------------------------------
|
||||||
|
// = RealVector
|
||||||
|
RealVector& RealVector::operator=(const RealVector &src)
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
uint32_t j;
|
||||||
|
uint32_t dj;
|
||||||
|
|
||||||
|
checkSize(m_size, src.m_size);
|
||||||
|
|
||||||
|
j = 0;
|
||||||
|
dj = src.m_size > 1;
|
||||||
|
if (src.isNegative())
|
||||||
|
{
|
||||||
|
for (i=0; i < m_size; i++)
|
||||||
|
{
|
||||||
|
m_pPtrReal[i] = -src.m_pPtrReal[j];
|
||||||
|
j += dj;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (i=0; i < m_size; i++)
|
||||||
|
{
|
||||||
|
m_pPtrReal[i] = src.m_pPtrReal[j];
|
||||||
|
j += dj;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// += RealVector
|
||||||
|
RealVector& RealVector::operator+=(const RealVector &src)
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
uint32_t j;
|
||||||
|
uint32_t dj;
|
||||||
|
|
||||||
|
checkSize(m_size, src.m_size);
|
||||||
|
|
||||||
|
j = 0;
|
||||||
|
dj = src.m_size > 1;
|
||||||
|
if (src.isNegative())
|
||||||
|
{
|
||||||
|
for (i=0; i < m_size; i++)
|
||||||
|
{
|
||||||
|
m_pPtrReal[i] -= src.m_pPtrReal[j];
|
||||||
|
j += dj;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (i=0; i < m_size; i++)
|
||||||
|
{
|
||||||
|
m_pPtrReal[i] += src.m_pPtrReal[j];
|
||||||
|
j += dj;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -= RealVector
|
||||||
|
RealVector& RealVector::operator-=(const RealVector &src)
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
uint32_t j;
|
||||||
|
uint32_t dj;
|
||||||
|
|
||||||
|
checkSize(m_size, src.m_size);
|
||||||
|
|
||||||
|
j = 0;
|
||||||
|
dj = src.m_size > 1;
|
||||||
|
if (src.isNegative())
|
||||||
|
{
|
||||||
|
for (i=0; i < m_size; i++)
|
||||||
|
{
|
||||||
|
m_pPtrReal[i] += src.m_pPtrReal[j];
|
||||||
|
j += dj;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (i=0; i < m_size; i++)
|
||||||
|
{
|
||||||
|
m_pPtrReal[i] -= src.m_pPtrReal[j];
|
||||||
|
j += dj;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// *= RealVector
|
||||||
|
RealVector& RealVector::operator*=(const RealVector &src)
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
uint32_t j;
|
||||||
|
uint32_t dj;
|
||||||
|
|
||||||
|
checkSize(m_size, src.m_size);
|
||||||
|
|
||||||
|
j = 0;
|
||||||
|
dj = src.m_size > 1;
|
||||||
|
if (src.isNegative())
|
||||||
|
{
|
||||||
|
for (i=0; i < m_size; i++)
|
||||||
|
{
|
||||||
|
m_pPtrReal[i] *= -src.m_pPtrReal[j];
|
||||||
|
j += dj;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (i=0; i < m_size; i++)
|
||||||
|
{
|
||||||
|
m_pPtrReal[i] *= src.m_pPtrReal[j];
|
||||||
|
j += dj;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// /= RealVector
|
||||||
|
RealVector& RealVector::operator/=(const RealVector &src)
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
uint32_t j;
|
||||||
|
uint32_t dj;
|
||||||
|
|
||||||
|
checkSize(m_size, src.m_size);
|
||||||
|
|
||||||
|
j = 0;
|
||||||
|
dj = src.m_size > 1;
|
||||||
|
if (src.isNegative())
|
||||||
|
{
|
||||||
|
for (i=0; i < m_size; i++)
|
||||||
|
{
|
||||||
|
m_pPtrReal[i] /= -src.m_pPtrReal[j];
|
||||||
|
j += dj;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (i=0; i < m_size; i++)
|
||||||
|
{
|
||||||
|
m_pPtrReal[i] /= src.m_pPtrReal[j];
|
||||||
|
j += dj;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// = RealVector::OpBinary
|
||||||
|
RealVector& RealVector::operator=(const OpBinary &src)
|
||||||
|
{
|
||||||
|
uint32_t i, j, k;
|
||||||
|
uint32_t dj, dk;
|
||||||
|
|
||||||
|
dj = src.a.m_size > 1;
|
||||||
|
dk = src.b.m_size > 1;
|
||||||
|
|
||||||
|
j = 0;
|
||||||
|
k = 0;
|
||||||
|
switch (src.op)
|
||||||
|
{
|
||||||
|
case OpBinary::ADD:
|
||||||
|
if (!src.isNegative())
|
||||||
|
{
|
||||||
|
for (i=0; i < m_size; i++)
|
||||||
|
{
|
||||||
|
m_pPtrReal[i] = + src.a.m_pPtrReal[j] + src.b.m_pPtrReal[k];
|
||||||
|
j += dj;
|
||||||
|
k += dk;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (i=0; i < m_size; i++)
|
||||||
|
{
|
||||||
|
m_pPtrReal[i] = - src.a.m_pPtrReal[j] - src.b.m_pPtrReal[k];
|
||||||
|
j += dj;
|
||||||
|
k += dk;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OpBinary::SUB:
|
||||||
|
if (!src.isNegative())
|
||||||
|
{
|
||||||
|
for (i=0; i < m_size; i++)
|
||||||
|
{
|
||||||
|
m_pPtrReal[i] = + src.a.m_pPtrReal[j] - src.b.m_pPtrReal[k];
|
||||||
|
j += dj;
|
||||||
|
k += dk;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (i=0; i < m_size; i++)
|
||||||
|
{
|
||||||
|
m_pPtrReal[i] = - src.a.m_pPtrReal[j] + src.b.m_pPtrReal[k];
|
||||||
|
j += dj;
|
||||||
|
k += dk;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OpBinary::MUL:
|
||||||
|
if (!src.isNegative())
|
||||||
|
{
|
||||||
|
for (i=0; i < m_size; i++)
|
||||||
|
{
|
||||||
|
m_pPtrReal[i] = + src.a.m_pPtrReal[j] * src.b.m_pPtrReal[k];
|
||||||
|
j += dj;
|
||||||
|
k += dk;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (i=0; i < m_size; i++)
|
||||||
|
{
|
||||||
|
m_pPtrReal[i] = - src.a.m_pPtrReal[j] * src.b.m_pPtrReal[k];
|
||||||
|
j += dj;
|
||||||
|
k += dk;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OpBinary::DIV:
|
||||||
|
if (!src.isNegative())
|
||||||
|
{
|
||||||
|
for (i=0; i < m_size; i++)
|
||||||
|
{
|
||||||
|
m_pPtrReal[i] = + src.a.m_pPtrReal[j] / src.b.m_pPtrReal[k];
|
||||||
|
j += dj;
|
||||||
|
k += dk;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (i=0; i < m_size; i++)
|
||||||
|
{
|
||||||
|
m_pPtrReal[i] = - (src.a.m_pPtrReal[j] / src.b.m_pPtrReal[k]);
|
||||||
|
j += dj;
|
||||||
|
k += dk;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// += RealVector::OpBinary
|
||||||
|
RealVector& RealVector::operator+=(const OpBinary &src)
|
||||||
|
{
|
||||||
|
uint32_t i, j, k;
|
||||||
|
uint32_t dj, dk;
|
||||||
|
|
||||||
|
dj = src.a.m_size > 1;
|
||||||
|
dk = src.b.m_size > 1;
|
||||||
|
|
||||||
|
j = 0;
|
||||||
|
k = 0;
|
||||||
|
switch (src.op)
|
||||||
|
{
|
||||||
|
case OpBinary::ADD:
|
||||||
|
if (!src.isNegative())
|
||||||
|
{
|
||||||
|
for (i=0; i < m_size; i++)
|
||||||
|
{
|
||||||
|
m_pPtrReal[i] += + src.a.m_pPtrReal[j] + src.b.m_pPtrReal[k];
|
||||||
|
j += dj;
|
||||||
|
k += dk;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (i=0; i < m_size; i++)
|
||||||
|
{
|
||||||
|
m_pPtrReal[i] += - src.a.m_pPtrReal[j] - src.b.m_pPtrReal[k];
|
||||||
|
j += dj;
|
||||||
|
k += dk;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OpBinary::SUB:
|
||||||
|
if (!src.isNegative())
|
||||||
|
{
|
||||||
|
for (i=0; i < m_size; i++)
|
||||||
|
{
|
||||||
|
m_pPtrReal[i] += + src.a.m_pPtrReal[j] - src.b.m_pPtrReal[k];
|
||||||
|
j += dj;
|
||||||
|
k += dk;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (i=0; i < m_size; i++)
|
||||||
|
{
|
||||||
|
m_pPtrReal[i] += - src.a.m_pPtrReal[j] + src.b.m_pPtrReal[k];
|
||||||
|
j += dj;
|
||||||
|
k += dk;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OpBinary::MUL:
|
||||||
|
if (!src.isNegative())
|
||||||
|
{
|
||||||
|
for (i=0; i < m_size; i++)
|
||||||
|
{
|
||||||
|
m_pPtrReal[i] += + src.a.m_pPtrReal[j] * src.b.m_pPtrReal[k];
|
||||||
|
j += dj;
|
||||||
|
k += dk;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (i=0; i < m_size; i++)
|
||||||
|
{
|
||||||
|
m_pPtrReal[i] += - src.a.m_pPtrReal[j] * src.b.m_pPtrReal[k];
|
||||||
|
j += dj;
|
||||||
|
k += dk;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OpBinary::DIV:
|
||||||
|
if (!src.isNegative())
|
||||||
|
{
|
||||||
|
for (i=0; i < m_size; i++)
|
||||||
|
{
|
||||||
|
m_pPtrReal[i] += + src.a.m_pPtrReal[j] / src.b.m_pPtrReal[k];
|
||||||
|
j += dj;
|
||||||
|
k += dk;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (i=0; i < m_size; i++)
|
||||||
|
{
|
||||||
|
m_pPtrReal[i] += - (src.a.m_pPtrReal[j] / src.b.m_pPtrReal[k]);
|
||||||
|
j += dj;
|
||||||
|
k += dk;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -= RealVector::OpBinary
|
||||||
|
RealVector& RealVector::operator-=(const OpBinary &src)
|
||||||
|
{
|
||||||
|
uint32_t i, j, k;
|
||||||
|
uint32_t dj, dk;
|
||||||
|
|
||||||
|
dj = src.a.m_size > 1;
|
||||||
|
dk = src.b.m_size > 1;
|
||||||
|
|
||||||
|
j = 0;
|
||||||
|
k = 0;
|
||||||
|
switch (src.op)
|
||||||
|
{
|
||||||
|
case OpBinary::ADD:
|
||||||
|
if (!src.isNegative())
|
||||||
|
{
|
||||||
|
for (i=0; i < m_size; i++)
|
||||||
|
{
|
||||||
|
m_pPtrReal[i] -= + src.a.m_pPtrReal[j] + src.b.m_pPtrReal[k];
|
||||||
|
j += dj;
|
||||||
|
k += dk;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (i=0; i < m_size; i++)
|
||||||
|
{
|
||||||
|
m_pPtrReal[i] -= - src.a.m_pPtrReal[j] - src.b.m_pPtrReal[k];
|
||||||
|
j += dj;
|
||||||
|
k += dk;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OpBinary::SUB:
|
||||||
|
if (!src.isNegative())
|
||||||
|
{
|
||||||
|
for (i=0; i < m_size; i++)
|
||||||
|
{
|
||||||
|
m_pPtrReal[i] -= + src.a.m_pPtrReal[j] - src.b.m_pPtrReal[k];
|
||||||
|
j += dj;
|
||||||
|
k += dk;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (i=0; i < m_size; i++)
|
||||||
|
{
|
||||||
|
m_pPtrReal[i] -= - src.a.m_pPtrReal[j] + src.b.m_pPtrReal[k];
|
||||||
|
j += dj;
|
||||||
|
k += dk;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OpBinary::MUL:
|
||||||
|
if (!src.isNegative())
|
||||||
|
{
|
||||||
|
for (i=0; i < m_size; i++)
|
||||||
|
{
|
||||||
|
m_pPtrReal[i] -= + src.a.m_pPtrReal[j] * src.b.m_pPtrReal[k];
|
||||||
|
j += dj;
|
||||||
|
k += dk;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (i=0; i < m_size; i++)
|
||||||
|
{
|
||||||
|
m_pPtrReal[i] -= - src.a.m_pPtrReal[j] * src.b.m_pPtrReal[k];
|
||||||
|
j += dj;
|
||||||
|
k += dk;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OpBinary::DIV:
|
||||||
|
if (!src.isNegative())
|
||||||
|
{
|
||||||
|
for (i=0; i < m_size; i++)
|
||||||
|
{
|
||||||
|
m_pPtrReal[i] -= + src.a.m_pPtrReal[j] / src.b.m_pPtrReal[k];
|
||||||
|
j += dj;
|
||||||
|
k += dk;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (i=0; i < m_size; i++)
|
||||||
|
{
|
||||||
|
m_pPtrReal[i] -= - (src.a.m_pPtrReal[j] / src.b.m_pPtrReal[k]);
|
||||||
|
j += dj;
|
||||||
|
k += dk;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// *= RealVector::OpBinary
|
||||||
|
RealVector& RealVector::operator*=(const OpBinary &src)
|
||||||
|
{
|
||||||
|
uint32_t i, j, k;
|
||||||
|
uint32_t dj, dk;
|
||||||
|
|
||||||
|
dj = src.a.m_size > 1;
|
||||||
|
dk = src.b.m_size > 1;
|
||||||
|
|
||||||
|
j = 0;
|
||||||
|
k = 0;
|
||||||
|
switch (src.op)
|
||||||
|
{
|
||||||
|
case OpBinary::ADD:
|
||||||
|
if (!src.isNegative())
|
||||||
|
{
|
||||||
|
for (i=0; i < m_size; i++)
|
||||||
|
{
|
||||||
|
m_pPtrReal[i] *= + src.a.m_pPtrReal[j] + src.b.m_pPtrReal[k];
|
||||||
|
j += dj;
|
||||||
|
k += dk;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (i=0; i < m_size; i++)
|
||||||
|
{
|
||||||
|
m_pPtrReal[i] *= - src.a.m_pPtrReal[j] - src.b.m_pPtrReal[k];
|
||||||
|
j += dj;
|
||||||
|
k += dk;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OpBinary::SUB:
|
||||||
|
if (!src.isNegative())
|
||||||
|
{
|
||||||
|
for (i=0; i < m_size; i++)
|
||||||
|
{
|
||||||
|
m_pPtrReal[i] *= + src.a.m_pPtrReal[j] - src.b.m_pPtrReal[k];
|
||||||
|
j += dj;
|
||||||
|
k += dk;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (i=0; i < m_size; i++)
|
||||||
|
{
|
||||||
|
m_pPtrReal[i] *= - src.a.m_pPtrReal[j] + src.b.m_pPtrReal[k];
|
||||||
|
j += dj;
|
||||||
|
k += dk;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OpBinary::MUL:
|
||||||
|
if (!src.isNegative())
|
||||||
|
{
|
||||||
|
for (i=0; i < m_size; i++)
|
||||||
|
{
|
||||||
|
m_pPtrReal[i] *= + src.a.m_pPtrReal[j] * src.b.m_pPtrReal[k];
|
||||||
|
j += dj;
|
||||||
|
k += dk;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (i=0; i < m_size; i++)
|
||||||
|
{
|
||||||
|
m_pPtrReal[i] *= - src.a.m_pPtrReal[j] * src.b.m_pPtrReal[k];
|
||||||
|
j += dj;
|
||||||
|
k += dk;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OpBinary::DIV:
|
||||||
|
if (!src.isNegative())
|
||||||
|
{
|
||||||
|
for (i=0; i < m_size; i++)
|
||||||
|
{
|
||||||
|
m_pPtrReal[i] *= + src.a.m_pPtrReal[j] / src.b.m_pPtrReal[k];
|
||||||
|
j += dj;
|
||||||
|
k += dk;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (i=0; i < m_size; i++)
|
||||||
|
{
|
||||||
|
m_pPtrReal[i] *= - (src.a.m_pPtrReal[j] / src.b.m_pPtrReal[k]);
|
||||||
|
j += dj;
|
||||||
|
k += dk;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// /= RealVector::OpBinary
|
||||||
|
RealVector& RealVector::operator/=(const OpBinary &src)
|
||||||
|
{
|
||||||
|
uint32_t i, j, k;
|
||||||
|
uint32_t dj, dk;
|
||||||
|
|
||||||
|
dj = src.a.m_size > 1;
|
||||||
|
dk = src.b.m_size > 1;
|
||||||
|
|
||||||
|
j = 0;
|
||||||
|
k = 0;
|
||||||
|
switch (src.op)
|
||||||
|
{
|
||||||
|
case OpBinary::ADD:
|
||||||
|
if (!src.isNegative())
|
||||||
|
{
|
||||||
|
for (i=0; i < m_size; i++)
|
||||||
|
{
|
||||||
|
m_pPtrReal[i] /= + src.a.m_pPtrReal[j] + src.b.m_pPtrReal[k];
|
||||||
|
j += dj;
|
||||||
|
k += dk;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (i=0; i < m_size; i++)
|
||||||
|
{
|
||||||
|
m_pPtrReal[i] /= - src.a.m_pPtrReal[j] - src.b.m_pPtrReal[k];
|
||||||
|
j += dj;
|
||||||
|
k += dk;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OpBinary::SUB:
|
||||||
|
if (!src.isNegative())
|
||||||
|
{
|
||||||
|
for (i=0; i < m_size; i++)
|
||||||
|
{
|
||||||
|
m_pPtrReal[i] /= + src.a.m_pPtrReal[j] - src.b.m_pPtrReal[k];
|
||||||
|
j += dj;
|
||||||
|
k += dk;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (i=0; i < m_size; i++)
|
||||||
|
{
|
||||||
|
m_pPtrReal[i] /= - src.a.m_pPtrReal[j] + src.b.m_pPtrReal[k];
|
||||||
|
j += dj;
|
||||||
|
k += dk;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OpBinary::MUL:
|
||||||
|
if (!src.isNegative())
|
||||||
|
{
|
||||||
|
for (i=0; i < m_size; i++)
|
||||||
|
{
|
||||||
|
m_pPtrReal[i] /= + src.a.m_pPtrReal[j] * src.b.m_pPtrReal[k];
|
||||||
|
j += dj;
|
||||||
|
k += dk;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (i=0; i < m_size; i++)
|
||||||
|
{
|
||||||
|
m_pPtrReal[i] /= - src.a.m_pPtrReal[j] * src.b.m_pPtrReal[k];
|
||||||
|
j += dj;
|
||||||
|
k += dk;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OpBinary::DIV:
|
||||||
|
if (!src.isNegative())
|
||||||
|
{
|
||||||
|
for (i=0; i < m_size; i++)
|
||||||
|
{
|
||||||
|
m_pPtrReal[i] /= + src.a.m_pPtrReal[j] / src.b.m_pPtrReal[k];
|
||||||
|
j += dj;
|
||||||
|
k += dk;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (i=0; i < m_size; i++)
|
||||||
|
{
|
||||||
|
m_pPtrReal[i] /= - (src.a.m_pPtrReal[j] / src.b.m_pPtrReal[k]);
|
||||||
|
j += dj;
|
||||||
|
k += dk;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------------
|
||||||
|
// Binary Operators
|
||||||
|
// -------------------------------------------------
|
||||||
|
// Returning RealVector::OpBinary
|
||||||
|
RealVector::OpBinary operator+(const RealVector &a, const RealVector &b)
|
||||||
|
{
|
||||||
|
if (a.isNegative())
|
||||||
|
{
|
||||||
|
if (b.isNegative())
|
||||||
|
{
|
||||||
|
return -RealVector::OpBinary (a, b, RealVector::OpBinary::ADD);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return RealVector::OpBinary (b, a, RealVector::OpBinary::SUB);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (b.isNegative())
|
||||||
|
{
|
||||||
|
return RealVector::OpBinary (a, b, RealVector::OpBinary::SUB);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return RealVector::OpBinary (a, b, RealVector::OpBinary::ADD);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RealVector::OpBinary operator-(const RealVector &a, const RealVector &b)
|
||||||
|
{
|
||||||
|
if (a.isNegative())
|
||||||
|
{
|
||||||
|
if (b.isNegative())
|
||||||
|
{
|
||||||
|
return RealVector::OpBinary (b, a, RealVector::OpBinary::SUB);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return -RealVector::OpBinary (a, b, RealVector::OpBinary::ADD);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (b.isNegative())
|
||||||
|
{
|
||||||
|
return RealVector::OpBinary (a, b, RealVector::OpBinary::SUB);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return RealVector::OpBinary (a, b, RealVector::OpBinary::ADD);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RealVector::OpBinary operator*(const RealVector &a, const RealVector &b)
|
||||||
|
{
|
||||||
|
if (a.isNegative())
|
||||||
|
{
|
||||||
|
if (b.isNegative())
|
||||||
|
{
|
||||||
|
return RealVector::OpBinary (a, b, RealVector::OpBinary::MUL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return -RealVector::OpBinary (a, b, RealVector::OpBinary::MUL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (b.isNegative())
|
||||||
|
{
|
||||||
|
return -RealVector::OpBinary (a, b, RealVector::OpBinary::MUL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return RealVector::OpBinary (a, b, RealVector::OpBinary::MUL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RealVector::OpBinary operator/(const RealVector &a, const RealVector &b)
|
||||||
|
{
|
||||||
|
if (a.isNegative())
|
||||||
|
{
|
||||||
|
if (b.isNegative())
|
||||||
|
{
|
||||||
|
return RealVector::OpBinary (a, b, RealVector::OpBinary::DIV);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return -RealVector::OpBinary (a, b, RealVector::OpBinary::DIV);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (b.isNegative())
|
||||||
|
{
|
||||||
|
return -RealVector::OpBinary (a, b, RealVector::OpBinary::DIV);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return RealVector::OpBinary (a, b, RealVector::OpBinary::DIV);
|
||||||
|
}
|
||||||
|
}
|
||||||
Executable
+271
@@ -0,0 +1,271 @@
|
|||||||
|
#ifndef _REAL_HPP_
|
||||||
|
#define _REAL_HPP_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <memory.h>
|
||||||
|
#include <radio/radio_types.h>
|
||||||
|
|
||||||
|
void RealDebug(char *fmtstr, ...);
|
||||||
|
|
||||||
|
class RealException
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RealException (std::string s)
|
||||||
|
{
|
||||||
|
m_what = s;
|
||||||
|
}
|
||||||
|
~RealException()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
std::string& what()
|
||||||
|
{
|
||||||
|
return m_what;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
std::string m_what;
|
||||||
|
};
|
||||||
|
|
||||||
|
class RealVector
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
struct OpBinary
|
||||||
|
{
|
||||||
|
enum OpType
|
||||||
|
{
|
||||||
|
ADD = 0,
|
||||||
|
SUB,
|
||||||
|
MUL,
|
||||||
|
DIV
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct _attributes_t
|
||||||
|
{
|
||||||
|
bool negative;
|
||||||
|
} attributes_t;
|
||||||
|
|
||||||
|
OpBinary(const RealVector &a, const RealVector &b, OpType op)
|
||||||
|
: a(a)
|
||||||
|
, b(b)
|
||||||
|
, op(op)
|
||||||
|
, m_attributes(defaultAttributes())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
OpBinary operator-()
|
||||||
|
{
|
||||||
|
attributes_t attributes = this->m_attributes;
|
||||||
|
attributes.negative = !attributes.negative;
|
||||||
|
|
||||||
|
return OpBinary(*this, attributes);
|
||||||
|
}
|
||||||
|
~OpBinary()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isNegative() const
|
||||||
|
{
|
||||||
|
return m_attributes.negative;
|
||||||
|
}
|
||||||
|
const RealVector &a;
|
||||||
|
const RealVector &b;
|
||||||
|
const OpType op;
|
||||||
|
attributes_t m_attributes;
|
||||||
|
|
||||||
|
private:
|
||||||
|
OpBinary& operator=(const OpBinary&);
|
||||||
|
OpBinary(const OpBinary &src, attributes_t attributes)
|
||||||
|
: a(src.a)
|
||||||
|
, b(src.b)
|
||||||
|
, op(src.op)
|
||||||
|
, m_attributes(attributes)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
static const attributes_t defaultAttributes()
|
||||||
|
{
|
||||||
|
attributes_t attributes;
|
||||||
|
attributes.negative = false;
|
||||||
|
return attributes;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct _attributes_t
|
||||||
|
{
|
||||||
|
bool negative;
|
||||||
|
} attributes_t;
|
||||||
|
|
||||||
|
// Standard constructor
|
||||||
|
RealVector(uint32_t size, radio_float_t *real=0)
|
||||||
|
: m_size(size)
|
||||||
|
, m_real(0)
|
||||||
|
, m_pBufReal(0)
|
||||||
|
, m_pPtrReal(real)
|
||||||
|
, m_attributes(defaultAttributes())
|
||||||
|
{
|
||||||
|
if (!real)
|
||||||
|
{
|
||||||
|
m_pBufReal = new radio_float_t[m_size];
|
||||||
|
memset(m_pBufReal, 0, m_size*sizeof(radio_float_t));
|
||||||
|
m_pPtrReal = m_pBufReal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// OpBinary resolver copy constructor
|
||||||
|
RealVector(const OpBinary &src)
|
||||||
|
: m_size(src.a.m_size)
|
||||||
|
, m_real(0)
|
||||||
|
, m_pBufReal(0)
|
||||||
|
, m_pPtrReal(0)
|
||||||
|
, m_attributes(defaultAttributes())
|
||||||
|
{
|
||||||
|
m_pBufReal = new radio_float_t[m_size];
|
||||||
|
m_pPtrReal = m_pBufReal;
|
||||||
|
|
||||||
|
*this = src;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Scalar constructor
|
||||||
|
RealVector(radio_float_t real)
|
||||||
|
: m_size(1)
|
||||||
|
, m_real(real)
|
||||||
|
, m_pBufReal(0)
|
||||||
|
, m_pPtrReal(&m_real)
|
||||||
|
, m_attributes(defaultAttributes())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
~RealVector(void)
|
||||||
|
{
|
||||||
|
if (m_pBufReal)
|
||||||
|
delete(m_pBufReal);
|
||||||
|
|
||||||
|
m_pBufReal = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isNegative() const
|
||||||
|
{
|
||||||
|
return m_attributes.negative;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t getSize()
|
||||||
|
{
|
||||||
|
return m_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
RealVector at(uint32_t const &i)
|
||||||
|
{
|
||||||
|
return RealVector(*this, i, 1, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
void print(char *pPrefix)
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
|
RealDebug("%s:\n", pPrefix);
|
||||||
|
for (i=0; i < m_size; i++)
|
||||||
|
{
|
||||||
|
RealDebug("%d: %.6f\n", i, m_pPtrReal[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RealVector operator-()
|
||||||
|
{
|
||||||
|
attributes_t attributes = this->m_attributes;
|
||||||
|
attributes.negative = !attributes.negative;
|
||||||
|
|
||||||
|
return RealVector(*this, attributes);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assignments
|
||||||
|
RealVector& operator=(const RealVector &src);
|
||||||
|
RealVector& operator+=(const RealVector &src);
|
||||||
|
RealVector& operator-=(const RealVector &src);
|
||||||
|
RealVector& operator*=(const RealVector &src);
|
||||||
|
RealVector& operator/=(const RealVector &src);
|
||||||
|
RealVector& operator=(const OpBinary &src);
|
||||||
|
RealVector& operator+=(const OpBinary &src);
|
||||||
|
RealVector& operator-=(const OpBinary &src);
|
||||||
|
RealVector& operator*=(const OpBinary &src);
|
||||||
|
RealVector& operator/=(const OpBinary &src);
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint32_t m_size;
|
||||||
|
radio_float_t m_real;
|
||||||
|
radio_float_t *m_pBufReal;
|
||||||
|
radio_float_t *m_pPtrReal;
|
||||||
|
attributes_t m_attributes;
|
||||||
|
|
||||||
|
// Attribute default
|
||||||
|
const attributes_t defaultAttributes()
|
||||||
|
{
|
||||||
|
attributes_t attributes;
|
||||||
|
|
||||||
|
attributes.negative = 0;
|
||||||
|
|
||||||
|
return attributes;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy constructor
|
||||||
|
RealVector(const RealVector &src)
|
||||||
|
: m_size(src.m_size)
|
||||||
|
, m_real(0)
|
||||||
|
, m_pBufReal(0)
|
||||||
|
, m_pPtrReal(0)
|
||||||
|
{
|
||||||
|
m_pBufReal = new radio_float_t[m_size];
|
||||||
|
m_pPtrReal = m_pBufReal;
|
||||||
|
|
||||||
|
*this = src;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Re-attribute constructor
|
||||||
|
// Copies no data, just pointers and attributes
|
||||||
|
RealVector(const RealVector &src, attributes_t attributes)
|
||||||
|
: m_size(src.m_size)
|
||||||
|
, m_real(src.m_real)
|
||||||
|
, m_pBufReal(0)
|
||||||
|
, m_pPtrReal(src.m_pPtrReal)
|
||||||
|
, m_attributes(attributes)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// Slicing constructor
|
||||||
|
RealVector(RealVector &src, uint32_t from, uint32_t step, uint32_t to)
|
||||||
|
: m_size(0)
|
||||||
|
, m_pBufReal(0)
|
||||||
|
, m_pPtrReal(&src.m_pPtrReal[from])
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
|
for (i=from; i < to; i+=step)
|
||||||
|
{
|
||||||
|
m_size++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
_inline void checkSize(uint32_t size1, uint32_t size2)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if ((size1 != size2) && (size2 != 1))
|
||||||
|
{
|
||||||
|
throw(RealException("Size mismatch"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(RealException &exc)
|
||||||
|
{
|
||||||
|
RealDebug("Problem: %s\n", exc.what().c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
// Non-Member
|
||||||
|
// Binary Operators
|
||||||
|
// Returning RealVector::OpBinary
|
||||||
|
RealVector::OpBinary operator+(const RealVector &a, const RealVector &b);
|
||||||
|
RealVector::OpBinary operator-(const RealVector &a, const RealVector &b);
|
||||||
|
RealVector::OpBinary operator*(const RealVector &a, const RealVector &b);
|
||||||
|
RealVector::OpBinary operator/(const RealVector &a, const RealVector &b);
|
||||||
|
|
||||||
|
#endif // _REAL_HPP_
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
// --------------------------------------------------------------
|
||||||
|
#include <string.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include "agc.h"
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
// AGC
|
||||||
|
// Scalar version
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
void AGC_Init(agc_t *pObj, uint32_t windowLength, radio_float_t w_init)
|
||||||
|
{
|
||||||
|
pObj->w = w_init;
|
||||||
|
SlidingMinMaxInit(&pObj->slMax, windowLength, (radio_float_t)1E12, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AGC_Free(agc_t *pObj)
|
||||||
|
{
|
||||||
|
SlidingMinMaxFree(&pObj->slMax);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AGC_Process(agc_t *pObj, radio_float_t x, radio_float_t mu, radio_float_t target)
|
||||||
|
{
|
||||||
|
radio_float_t d2;
|
||||||
|
radio_float_t e;
|
||||||
|
|
||||||
|
d2 = SlidingMinMaxProcess(&pObj->slMax, x);
|
||||||
|
e = target - d2;
|
||||||
|
pObj->w += mu*e*dabs(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AGC_Train(agc_t *pObj, radio_float_t e, radio_float_t mu)
|
||||||
|
{
|
||||||
|
pObj->w += mu*e;
|
||||||
|
}
|
||||||
|
|
||||||
|
radio_float_t AGC_GetWeight(agc_t *pObj)
|
||||||
|
{
|
||||||
|
return pObj->w;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
// --------------------------------------------------------------
|
||||||
|
#ifndef AGC_H
|
||||||
|
#define AGC_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "radio_types.h"
|
||||||
|
#include "statistics.h"
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
// Types
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
typedef struct _agc_t
|
||||||
|
{
|
||||||
|
radio_float_t w;
|
||||||
|
sl_minmax_t slMax;
|
||||||
|
} agc_t;
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
// AGC
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
// Scalar version
|
||||||
|
void AGC_Init(agc_t *pObj, uint32_t windowLength, radio_float_t w_init);
|
||||||
|
void AGC_Free(agc_t *pObj);
|
||||||
|
void AGC_Train(agc_t *pObj, radio_float_t e, radio_float_t mu);
|
||||||
|
void AGC_Process(agc_t *pObj, radio_float_t x, radio_float_t mu, radio_float_t target);
|
||||||
|
radio_float_t AGC_GetWeight(agc_t *pObj);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif // __cplusplus
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
#endif // AGC_H
|
||||||
@@ -0,0 +1,591 @@
|
|||||||
|
// --------------------------------------------------------------
|
||||||
|
#include <string.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include "radio_types.h"
|
||||||
|
#include "real.h"
|
||||||
|
#include "cpx.h"
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
// Basic Functions
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
|
||||||
|
cpx_t CpxConjS(cpx_t v1)
|
||||||
|
{
|
||||||
|
register cpx_t temp;
|
||||||
|
|
||||||
|
temp.real = v1.real;
|
||||||
|
temp.imag = -v1.imag;
|
||||||
|
|
||||||
|
return temp;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
cpx_t CpxAddS(cpx_t v1, cpx_t v2)
|
||||||
|
{
|
||||||
|
register cpx_t temp;
|
||||||
|
|
||||||
|
temp.real = v1.real + v2.real;
|
||||||
|
temp.imag = v1.imag + v2.imag;
|
||||||
|
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
cpx_t CpxSubS(cpx_t v1, cpx_t v2)
|
||||||
|
{
|
||||||
|
register cpx_t temp;
|
||||||
|
|
||||||
|
temp.real = v1.real - v2.real;
|
||||||
|
temp.imag = v1.imag - v2.imag;
|
||||||
|
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
cpx_t CpxMulS(cpx_t v1, cpx_t v2)
|
||||||
|
{
|
||||||
|
register cpx_t t_0;
|
||||||
|
register cpx_t t_1;
|
||||||
|
|
||||||
|
t_0.real = v1.real*v2.real;
|
||||||
|
t_1.real = v1.imag*v2.imag;
|
||||||
|
t_0.imag = v1.real*v2.imag;
|
||||||
|
t_1.imag = v1.imag*v2.real;
|
||||||
|
|
||||||
|
t_0.real -= t_1.real;
|
||||||
|
t_0.imag += t_1.imag;
|
||||||
|
|
||||||
|
return t_0;
|
||||||
|
}
|
||||||
|
|
||||||
|
cpx_t CpxScaleRealS(cpx_t v1, radio_float_t v2)
|
||||||
|
{
|
||||||
|
register cpx_t temp;
|
||||||
|
|
||||||
|
temp.real = v1.real*v2;
|
||||||
|
temp.imag = v1.imag*v2;
|
||||||
|
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
cpx_t CpxScaleComplexS(cpx_t x, cpx_t gain)
|
||||||
|
{
|
||||||
|
register cpx_t temp;
|
||||||
|
|
||||||
|
temp.real = x.real*gain.real;
|
||||||
|
temp.imag = x.imag*gain.imag;
|
||||||
|
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
cpx_t CpxFromReal(radio_float_t v1)
|
||||||
|
{
|
||||||
|
return Cpx(v1, v1);
|
||||||
|
}
|
||||||
|
|
||||||
|
cpx_t Cpx(radio_float_t real, radio_float_t imag)
|
||||||
|
{
|
||||||
|
cpx_t res;
|
||||||
|
|
||||||
|
res.real = real;
|
||||||
|
res.imag = imag;
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
radio_float_t CpxMagS(cpx_t v1)
|
||||||
|
{
|
||||||
|
radio_float_t mag;
|
||||||
|
|
||||||
|
mag = (radio_float_t)sqrt(v1.real*v1.real + v1.imag*v1.imag);
|
||||||
|
|
||||||
|
return mag;
|
||||||
|
}
|
||||||
|
|
||||||
|
radio_float_t CpxPhiS(cpx_t v1)
|
||||||
|
{
|
||||||
|
return (radio_float_t)atan2(v1.real, v1.imag);
|
||||||
|
}
|
||||||
|
|
||||||
|
cpx_t CpxMinS(cpx_t x1, cpx_t x2)
|
||||||
|
{
|
||||||
|
return Cpx(dmin(x1.real, x2.real), dmin(x1.imag, x2.imag));
|
||||||
|
}
|
||||||
|
|
||||||
|
cpx_t CpxMaxS(cpx_t x1, cpx_t x2)
|
||||||
|
{
|
||||||
|
return Cpx(dmax(x1.real, x2.real), dmax(x1.imag, x2.imag));
|
||||||
|
}
|
||||||
|
|
||||||
|
radio_float_t cpxPowerDB(cpx_t v1, radio_float_t preScale)
|
||||||
|
{
|
||||||
|
return powerDB(CpxMagS(v1), preScale);
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
// Complex Functions
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
void CpxCopy(cpx_t *pSrc, cpx_t *pDst, uint32_t len)
|
||||||
|
{
|
||||||
|
memcpy(pDst, pSrc, len*sizeof(cpx_t));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CpxConj(cpx_t *pSrcDst, uint32_t len)
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
for(i=0; i < len; i++)
|
||||||
|
pSrcDst[i] = CpxConjS(pSrcDst[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CpxAddB8(cpx_t *pV1, cpx_t *pV2, cpx_t *pRes)
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
|
radio_float_t r0[8];
|
||||||
|
radio_float_t i0[8];
|
||||||
|
|
||||||
|
radio_float_t vr0[8];
|
||||||
|
radio_float_t vr1[8];
|
||||||
|
radio_float_t vi0[8];
|
||||||
|
radio_float_t vi1[8];
|
||||||
|
|
||||||
|
for (i=0; i < 8; i++)
|
||||||
|
{
|
||||||
|
vr0[i] = pV1[i].real;
|
||||||
|
vr1[i] = pV2[i].real;
|
||||||
|
vi0[i] = pV1[i].imag;
|
||||||
|
vi1[i] = pV2[i].imag;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i=0; i < 8; i++)
|
||||||
|
{
|
||||||
|
r0[i] = vr0[i] + vr1[i];
|
||||||
|
i0[i] = vi0[i] + vi1[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i=0; i < 8; i++)
|
||||||
|
{
|
||||||
|
pRes[i].real = r0[i];
|
||||||
|
pRes[i].imag = i0[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void CpxAdd(cpx_t *pSrc, cpx_t *pSrcDst, uint32_t len)
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
|
for(i=0; i < len-8; i += 8)
|
||||||
|
{
|
||||||
|
CpxAddB8(&pSrc[i], &pSrcDst[i], &pSrcDst[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(i=i; i < len; i++)
|
||||||
|
{
|
||||||
|
pSrcDst[i].real += pSrc[i].real;
|
||||||
|
pSrcDst[i].imag += pSrc[i].imag;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CpxSub(cpx_t *pSrc, cpx_t *pSrcDst, uint32_t len)
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
for(i=0; i < len; i++)
|
||||||
|
pSrcDst[i] = CpxSubS(pSrc[i], pSrcDst[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CpxMulB8(cpx_t *pV1, cpx_t *pV2, cpx_t *pRes)
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
radio_float_t r0[8];
|
||||||
|
radio_float_t r1[8];
|
||||||
|
|
||||||
|
radio_float_t vr0[8];
|
||||||
|
radio_float_t vr1[8];
|
||||||
|
radio_float_t vi0[8];
|
||||||
|
radio_float_t vi1[8];
|
||||||
|
|
||||||
|
for (i=0; i < 8; i++)
|
||||||
|
{
|
||||||
|
vr0[i] = pV1[i].real;
|
||||||
|
vr1[i] = pV2[i].real;
|
||||||
|
vi0[i] = pV1[i].imag;
|
||||||
|
vi1[i] = pV2[i].imag;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i=0; i < 8; i++)
|
||||||
|
{
|
||||||
|
r0[i] = vr0[i]*vr1[i];
|
||||||
|
}
|
||||||
|
for (i=0; i < 8; i++)
|
||||||
|
{
|
||||||
|
r1[i] = vi0[i]*vi1[i];
|
||||||
|
}
|
||||||
|
for (i=0; i < 8; i++)
|
||||||
|
{
|
||||||
|
pRes[i].real = r0[i] - r1[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i=0; i < 8; i++)
|
||||||
|
{
|
||||||
|
r0[i] = vr0[i]*vi1[i];
|
||||||
|
}
|
||||||
|
for (i=0; i < 8; i++)
|
||||||
|
{
|
||||||
|
r1[i] = vi0[i]*vr1[i];
|
||||||
|
}
|
||||||
|
for (i=0; i < 8; i++)
|
||||||
|
{
|
||||||
|
pRes[i].imag = r0[i] + r1[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void CpxMulAddB8(cpx_t *pV1, cpx_t *pV2, cpx_t *pRes)
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
radio_float_t r0[8];
|
||||||
|
radio_float_t r1[8];
|
||||||
|
|
||||||
|
radio_float_t vr0[8];
|
||||||
|
radio_float_t vr1[8];
|
||||||
|
radio_float_t vi0[8];
|
||||||
|
radio_float_t vi1[8];
|
||||||
|
|
||||||
|
for (i=0; i < 8; i++)
|
||||||
|
{
|
||||||
|
vr0[i] = pV1[i].real;
|
||||||
|
vr1[i] = pV2[i].real;
|
||||||
|
vi0[i] = pV1[i].imag;
|
||||||
|
vi1[i] = pV2[i].imag;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i=0; i < 8; i++)
|
||||||
|
{
|
||||||
|
r0[i] = vr0[i]*vr1[i];
|
||||||
|
}
|
||||||
|
for (i=0; i < 8; i++)
|
||||||
|
{
|
||||||
|
r1[i] = vi0[i]*vi1[i];
|
||||||
|
}
|
||||||
|
for (i=0; i < 8; i++)
|
||||||
|
{
|
||||||
|
r0[i] -= r1[i];
|
||||||
|
}
|
||||||
|
for (i=0; i < 8; i++)
|
||||||
|
{
|
||||||
|
pRes->real += r0[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i=0; i < 8; i++)
|
||||||
|
{
|
||||||
|
r0[i] = vr0[i]*vi1[i];
|
||||||
|
}
|
||||||
|
for (i=0; i < 8; i++)
|
||||||
|
{
|
||||||
|
r1[i] = vi0[i]*vr1[i];
|
||||||
|
}
|
||||||
|
for (i=0; i < 8; i++)
|
||||||
|
{
|
||||||
|
r0[i] += r1[i];
|
||||||
|
}
|
||||||
|
for (i=0; i < 8; i++)
|
||||||
|
{
|
||||||
|
pRes->imag += r0[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
void CpxScaleB8(cpx_t *v1, cpx_t v2, cpx_t *pRes)
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
radio_float_t r0[8];
|
||||||
|
radio_float_t r1[8];
|
||||||
|
|
||||||
|
radio_float_t vr0[8];
|
||||||
|
radio_float_t vi0[8];
|
||||||
|
|
||||||
|
for (i=0; i < 8; i++)
|
||||||
|
{
|
||||||
|
vr0[i] = v1[i].real;
|
||||||
|
vi0[i] = v1[i].imag;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i=0; i < 8; i++)
|
||||||
|
{
|
||||||
|
r0[i] = vr0[i]*v2.real;
|
||||||
|
}
|
||||||
|
for (i=0; i < 8; i++)
|
||||||
|
{
|
||||||
|
r1[i] = vi0[i]*v2.imag;
|
||||||
|
}
|
||||||
|
for (i=0; i < 8; i++)
|
||||||
|
{
|
||||||
|
r0[i] -= r1[i];
|
||||||
|
}
|
||||||
|
for (i=0; i < 8; i++)
|
||||||
|
{
|
||||||
|
pRes[i].real = r0[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i=0; i < 8; i++)
|
||||||
|
{
|
||||||
|
r0[i] = vr0[i]*v2.imag;
|
||||||
|
}
|
||||||
|
for (i=0; i < 8; i++)
|
||||||
|
{
|
||||||
|
r1[i] = vi0[i]*v2.real;
|
||||||
|
}
|
||||||
|
for (i=0; i < 8; i++)
|
||||||
|
{
|
||||||
|
r0[i] += r1[i];
|
||||||
|
}
|
||||||
|
for (i=0; i < 8; i++)
|
||||||
|
{
|
||||||
|
pRes[i].imag = r0[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CpxMulRealB8(cpx_t *v1, radio_float_t *v2, cpx_t *pRes)
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
|
radio_float_t r0[8];
|
||||||
|
radio_float_t i0[8];
|
||||||
|
|
||||||
|
radio_float_t vr0[8];
|
||||||
|
radio_float_t vi0[8];
|
||||||
|
|
||||||
|
for (i=0; i < 8; i++)
|
||||||
|
{
|
||||||
|
vr0[i] = v1[i].real;
|
||||||
|
vi0[i] = v1[i].imag;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i=0; i < 8; i++)
|
||||||
|
{
|
||||||
|
r0[i] = vr0[i]*v2[i];
|
||||||
|
i0[i] = vi0[i]*v2[i];
|
||||||
|
}
|
||||||
|
for (i=0; i < 8; i++)
|
||||||
|
{
|
||||||
|
pRes[i].real = r0[i];
|
||||||
|
pRes[i].imag = i0[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CpxMulRealAddB8(cpx_t *v1, radio_float_t *v2, cpx_t *pRes)
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
|
radio_float_t r0[8];
|
||||||
|
radio_float_t i0[8];
|
||||||
|
|
||||||
|
radio_float_t vr0[8];
|
||||||
|
radio_float_t vi0[8];
|
||||||
|
|
||||||
|
for (i=0; i < 8; i++)
|
||||||
|
{
|
||||||
|
vr0[i] = v1[i].real;
|
||||||
|
vi0[i] = v1[i].imag;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i=0; i < 8; i++)
|
||||||
|
{
|
||||||
|
r0[i] = vr0[i]*v2[i];
|
||||||
|
i0[i] = vi0[i]*v2[i];
|
||||||
|
}
|
||||||
|
for (i=0; i < 8; i++)
|
||||||
|
{
|
||||||
|
pRes->real += r0[i];
|
||||||
|
pRes->imag += i0[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CpxAccumB8(cpx_t *pV1, cpx_t *pRes)
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
|
radio_float_t vr0[8];
|
||||||
|
radio_float_t vi0[8];
|
||||||
|
|
||||||
|
for (i=0; i < 8; i++)
|
||||||
|
{
|
||||||
|
vr0[i] = pV1[i].real;
|
||||||
|
vi0[i] = pV1[i].imag;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i=0; i < 8; i++)
|
||||||
|
{
|
||||||
|
pRes->real += vr0[i];
|
||||||
|
pRes->imag += vi0[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
cpx_t CpxMulAdd(cpx_t sum, cpx_t *pSrc1, cpx_t *pSrc2, uint32_t len)
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
|
for (i=0; i < (len-8); i += 8)
|
||||||
|
{
|
||||||
|
CpxMulAddB8(&pSrc1[i], &pSrc2[i], &sum);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i=i; i < len; i++)
|
||||||
|
{
|
||||||
|
sum = CpxAddS(sum, CpxMulS(pSrc1[i], pSrc2[i]));
|
||||||
|
}
|
||||||
|
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
cpx_t CpxMulRealAdd(cpx_t sum, cpx_t *pSrc1, radio_float_t *pSrc2, uint32_t len)
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
|
for (i=0; i < (len-8); i += 8)
|
||||||
|
{
|
||||||
|
CpxMulRealAddB8(&pSrc1[i], &pSrc2[i], &sum);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i=i; i < len; i++)
|
||||||
|
{
|
||||||
|
sum = CpxAddS(sum, CpxScaleRealS(pSrc1[i], pSrc2[i]));
|
||||||
|
}
|
||||||
|
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CpxMul(cpx_t *pSrc1, cpx_t *pSrc2, cpx_t *pDst, uint32_t len)
|
||||||
|
{
|
||||||
|
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
|
for (i=0; i < (len-8); i += 8)
|
||||||
|
{
|
||||||
|
CpxMulB8(&pSrc1[i], &pSrc2[i], &pDst[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i=i; i < len; i++)
|
||||||
|
{
|
||||||
|
pDst[i] = CpxMulS(pSrc1[i], pSrc2[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CpxScale(cpx_t *pSrc1, cpx_t src2, cpx_t *pDst, uint32_t len)
|
||||||
|
{
|
||||||
|
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
|
for (i=0; i < (len-8); i += 8)
|
||||||
|
{
|
||||||
|
CpxScaleB8(&pSrc1[i], src2, &pDst[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i=i; i < len; i++)
|
||||||
|
{
|
||||||
|
pDst[i] = CpxMulS(pSrc1[i], src2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cpx_t csum(cpx_t *pSrc, int len)
|
||||||
|
{
|
||||||
|
cpx_t sum = Cpx(0,0);
|
||||||
|
|
||||||
|
while(len--)
|
||||||
|
{
|
||||||
|
sum.real += (*(pSrc)).real;
|
||||||
|
sum.imag += (*(pSrc++)).imag;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
cpx_t cmean(cpx_t *pSrc, int len)
|
||||||
|
{
|
||||||
|
cpx_t y;
|
||||||
|
|
||||||
|
y = csum(pSrc, len);
|
||||||
|
y.real /= len;
|
||||||
|
y.imag /= len;
|
||||||
|
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
#include <xmmintrin.h>
|
||||||
|
|
||||||
|
void _cpxMulB4
|
||||||
|
(
|
||||||
|
radio_float_t pV1_real[_cpxMulB4_blockSize], radio_float_t pV1_imag[_cpxMulB4_blockSize],
|
||||||
|
radio_float_t pV2_real[_cpxMulB4_blockSize], radio_float_t pV2_imag[_cpxMulB4_blockSize],
|
||||||
|
radio_float_t pRes_real[_cpxMulB4_blockSize], radio_float_t pRes_imag[_cpxMulB4_blockSize])
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
radio_float_t r0[_cpxMulB4_blockSize];
|
||||||
|
radio_float_t r1[_cpxMulB4_blockSize];
|
||||||
|
radio_float_t r2[_cpxMulB4_blockSize];
|
||||||
|
radio_float_t r3[_cpxMulB4_blockSize];
|
||||||
|
|
||||||
|
for (i=0; i < _cpxMulB4_blockSize; i++)
|
||||||
|
{
|
||||||
|
r0[i] = pV1_real[i]*pV2_real[i];
|
||||||
|
}
|
||||||
|
for (i=0; i < _cpxMulB4_blockSize; i++)
|
||||||
|
{
|
||||||
|
r1[i] = pV1_imag[i]*pV2_imag[i];
|
||||||
|
}
|
||||||
|
for (i=0; i < _cpxMulB4_blockSize; i++)
|
||||||
|
{
|
||||||
|
r2[i] = pV1_real[i]*pV2_imag[i];
|
||||||
|
}
|
||||||
|
for (i=0; i < _cpxMulB4_blockSize; i++)
|
||||||
|
{
|
||||||
|
r3[i] = pV1_imag[i]*pV2_real[i];
|
||||||
|
}
|
||||||
|
for (i=0; i < _cpxMulB4_blockSize; i++)
|
||||||
|
{
|
||||||
|
pRes_real[i] = r0[i] - r1[i];
|
||||||
|
}
|
||||||
|
for (i=0; i < _cpxMulB4_blockSize; i++)
|
||||||
|
{
|
||||||
|
pRes_imag[i] = r2[i] + r3[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _cpxMulB1
|
||||||
|
(
|
||||||
|
radio_float_t *pV1_real, radio_float_t *pV1_imag,
|
||||||
|
radio_float_t *pV2_real, radio_float_t *pV2_imag,
|
||||||
|
radio_float_t *pRes_real, radio_float_t *pRes_imag)
|
||||||
|
{
|
||||||
|
|
||||||
|
uint32_t i;
|
||||||
|
radio_float_t r0[_cpxMulB1_blockSize];
|
||||||
|
radio_float_t r1[_cpxMulB1_blockSize];
|
||||||
|
radio_float_t r2[_cpxMulB1_blockSize];
|
||||||
|
radio_float_t r3[_cpxMulB1_blockSize];
|
||||||
|
|
||||||
|
for (i=0; i < _cpxMulB1_blockSize; i++)
|
||||||
|
{
|
||||||
|
r0[i] = pV1_real[i]*pV2_real[i];
|
||||||
|
}
|
||||||
|
for (i=0; i < _cpxMulB1_blockSize; i++)
|
||||||
|
{
|
||||||
|
r1[i] = pV1_imag[i]*pV2_imag[i];
|
||||||
|
}
|
||||||
|
for (i=0; i < _cpxMulB1_blockSize; i++)
|
||||||
|
{
|
||||||
|
r2[i] = pV1_real[i]*pV2_imag[i];
|
||||||
|
}
|
||||||
|
for (i=0; i < _cpxMulB1_blockSize; i++)
|
||||||
|
{
|
||||||
|
r3[i] = pV1_imag[i]*pV2_real[i];
|
||||||
|
}
|
||||||
|
for (i=0; i < _cpxMulB1_blockSize; i++)
|
||||||
|
{
|
||||||
|
pRes_real[i] = r0[i] - r1[i];
|
||||||
|
}
|
||||||
|
for (i=0; i < _cpxMulB1_blockSize; i++)
|
||||||
|
{
|
||||||
|
pRes_imag[i] = r2[i] + r3[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,80 @@
|
|||||||
|
// --------------------------------------------------------------
|
||||||
|
#ifndef CPX_H
|
||||||
|
#define CPX_H
|
||||||
|
|
||||||
|
#include "radio_types.h"
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
// Types
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
typedef struct _cpx_t
|
||||||
|
{
|
||||||
|
radio_float_t imag, real;
|
||||||
|
|
||||||
|
} cpx_t;
|
||||||
|
|
||||||
|
typedef struct _cpx_arr_t
|
||||||
|
{
|
||||||
|
uint32_t size;
|
||||||
|
radio_float_t *imag, *real;
|
||||||
|
|
||||||
|
} cpx_arr_t;
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
// Complex Functions
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
// Scalar
|
||||||
|
cpx_t CpxConjS(cpx_t v1);
|
||||||
|
cpx_t CpxAddS(cpx_t v1, cpx_t v2);
|
||||||
|
cpx_t CpxSubS(cpx_t v1, cpx_t v2);
|
||||||
|
cpx_t CpxMulS(cpx_t v1, cpx_t v2);
|
||||||
|
cpx_t CpxScaleRealS(cpx_t v1, radio_float_t v2);
|
||||||
|
cpx_t CpxScaleComplexS(cpx_t x, cpx_t gain);
|
||||||
|
cpx_t CpxFromReal(radio_float_t v1);
|
||||||
|
cpx_t Cpx(radio_float_t real, radio_float_t imag);
|
||||||
|
cpx_t CpxMinS(cpx_t x1, cpx_t x2);
|
||||||
|
cpx_t CpxMaxS(cpx_t x1, cpx_t x2);
|
||||||
|
radio_float_t CpxMagS(cpx_t v1);
|
||||||
|
radio_float_t CpxPhiS(cpx_t v1);
|
||||||
|
radio_float_t cpxPowerDB(cpx_t v1, radio_float_t preScale);
|
||||||
|
|
||||||
|
// Vector
|
||||||
|
void CpxCopy(cpx_t *pSrc, cpx_t *pDst, uint32_t len);
|
||||||
|
void CpxConj(cpx_t *pSrcDst, uint32_t len);
|
||||||
|
void CpxAdd(cpx_t *pSrc, cpx_t *pSrcDst, uint32_t len);
|
||||||
|
void CpxSub(cpx_t *pSrc, cpx_t *pSrcDst, uint32_t len);
|
||||||
|
void CpxMul(cpx_t *pSrc1, cpx_t *pSrc2, cpx_t *pDst, uint32_t len);
|
||||||
|
void CpxScale(cpx_t *pSrc1, cpx_t src2, cpx_t *pDst, uint32_t len);
|
||||||
|
cpx_t CpxMulAdd(cpx_t sum, cpx_t *pSrc1, cpx_t *pSrc2, uint32_t len);
|
||||||
|
cpx_t CpxMulRealAdd(cpx_t sum, cpx_t *pSrc1, radio_float_t *pSrc2, uint32_t len);
|
||||||
|
radio_float_t CpxMag(cpx_t *pSrc);
|
||||||
|
radio_float_t CpxPhi(cpx_t *pSrc);
|
||||||
|
|
||||||
|
cpx_t csum(cpx_t *pSrc, int len);
|
||||||
|
cpx_t cmean(cpx_t *pSrc, int len);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
#define _cpxMulB4_blockSize 4
|
||||||
|
#define _cpxMulB1_blockSize 1
|
||||||
|
void _cpxMulB4
|
||||||
|
(
|
||||||
|
radio_float_t pV1_real[_cpxMulB4_blockSize], radio_float_t pV1_imag[_cpxMulB4_blockSize],
|
||||||
|
radio_float_t pV2_real[_cpxMulB4_blockSize], radio_float_t pV2_imag[_cpxMulB4_blockSize],
|
||||||
|
radio_float_t pRes_real[_cpxMulB4_blockSize], radio_float_t pRes_imag[_cpxMulB4_blockSize]
|
||||||
|
);
|
||||||
|
void _cpxMulB1
|
||||||
|
(
|
||||||
|
radio_float_t *pV1_real, radio_float_t *pV1_imag,
|
||||||
|
radio_float_t *pV2_real, radio_float_t *pV2_imag,
|
||||||
|
radio_float_t *pRes_real, radio_float_t *pRes_imag
|
||||||
|
);
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif // __cplusplus
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
#endif // CPX_H
|
||||||
Executable
+498
@@ -0,0 +1,498 @@
|
|||||||
|
// --------------------------------------------------------------
|
||||||
|
#include <string.h>
|
||||||
|
#include <malloc.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include "equalizer.h"
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
// Helpers
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
void CoeffComplexUnitAt(cpx_t *pW, uint32_t N, uint32_t dly)
|
||||||
|
{
|
||||||
|
if (dly >= N)
|
||||||
|
dly = 0;
|
||||||
|
|
||||||
|
memset(pW, 0, N*sizeof(cpx_t));
|
||||||
|
pW[dly].real = 1.0;
|
||||||
|
pW[dly].imag = 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CoeffComplexConv(cpx_t *pSrc, cpx_t *pSrcDst, uint32_t N, uint32_t dly)
|
||||||
|
{
|
||||||
|
uint32_t i, j, N2;
|
||||||
|
cpx_t *pX, *pW, t, energy = {0};
|
||||||
|
radio_float_t energy_correct;
|
||||||
|
|
||||||
|
N2 = N+dly;
|
||||||
|
|
||||||
|
pX = (cpx_t*)malloc(N2*sizeof(cpx_t));
|
||||||
|
memset(pX, 0, N2*sizeof(cpx_t));
|
||||||
|
pW = (cpx_t*)malloc(N2*sizeof(cpx_t));
|
||||||
|
memset(pW, 0, N2*sizeof(cpx_t));
|
||||||
|
|
||||||
|
CpxCopy(pSrc, pX, N);
|
||||||
|
|
||||||
|
for(j=0; j < N; j++)
|
||||||
|
energy = CpxAddS(energy, pSrcDst[j]);
|
||||||
|
|
||||||
|
energy_correct = (radio_float_t)(1.0/CpxMagS(energy));
|
||||||
|
|
||||||
|
for(i=0; i < N2; i++)
|
||||||
|
{
|
||||||
|
for(j=0; j < N; j++)
|
||||||
|
{
|
||||||
|
t = CpxMulS(pX[N-j+i-1], pSrcDst[j]);
|
||||||
|
pW[i] = CpxScaleRealS(CpxAddS(pW[i], t), energy_correct);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CpxCopy(&pW[N/2], pSrcDst, N);
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
// Equalizer
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
void EQComplexInit(eq_cpx_t *pObj, uint32_t N)
|
||||||
|
{
|
||||||
|
pObj->N = N;
|
||||||
|
pObj->pX = (cpx_t*)malloc(pObj->N*sizeof(cpx_t));
|
||||||
|
pObj->pW = (cpx_t*)malloc(pObj->N*sizeof(cpx_t));
|
||||||
|
pObj->pW_conj = (cpx_t*)malloc(pObj->N*sizeof(cpx_t));
|
||||||
|
memset(pObj->pX, 0, pObj->N*sizeof(cpx_t));
|
||||||
|
memset(pObj->pW, 0, pObj->N*sizeof(cpx_t));
|
||||||
|
memset(pObj->pW_conj, 0, pObj->N*sizeof(cpx_t));
|
||||||
|
}
|
||||||
|
|
||||||
|
void EQComplexFree(eq_cpx_t *pObj)
|
||||||
|
{
|
||||||
|
free(pObj->pX);
|
||||||
|
free(pObj->pW);
|
||||||
|
free(pObj->pW_conj);
|
||||||
|
}
|
||||||
|
|
||||||
|
cpx_t EQComplexProcess(eq_cpx_t *pObj, cpx_t x)
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
cpx_t y;
|
||||||
|
|
||||||
|
for(i=pObj->N-1; (int)i > 0; i--)
|
||||||
|
{
|
||||||
|
pObj->pX[i] = pObj->pX[i-1];
|
||||||
|
}
|
||||||
|
|
||||||
|
// fill M top positions with M new data
|
||||||
|
pObj->pX[i] = x;
|
||||||
|
|
||||||
|
y = CpxMulAdd(Cpx(0, 0), pObj->pX, pObj->pW_conj, pObj->N);
|
||||||
|
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
// CMA
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
void CMAInit(cma_t *pObj, uint32_t ntaps)
|
||||||
|
{
|
||||||
|
pObj->N = ntaps;
|
||||||
|
pObj->Px = 0;
|
||||||
|
pObj->Px_last = 0;
|
||||||
|
|
||||||
|
EQComplexInit(&pObj->eq, pObj->N);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMAFree(cma_t *pObj)
|
||||||
|
{
|
||||||
|
EQComplexFree(&pObj->eq);
|
||||||
|
}
|
||||||
|
|
||||||
|
cpx_t CMAProcess(cma_t *pObj, cpx_t x)
|
||||||
|
{
|
||||||
|
cpx_t y;
|
||||||
|
radio_float_t x2, x1;
|
||||||
|
|
||||||
|
y = EQComplexProcess(&pObj->eq, x);
|
||||||
|
x1 = CpxMagS(x);
|
||||||
|
x2 = CpxMagS(pObj->eq.pX[pObj->eq.N-1]);
|
||||||
|
|
||||||
|
pObj->Px = dmax(0, pObj->Px + (x1*x1 - pObj->Px_last));
|
||||||
|
pObj->Px_last = x2*x2;
|
||||||
|
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Proakis: page 698
|
||||||
|
void CMATrainGodard(cma_t *pObj, cpx_t sym_s_eq, radio_float_t mag_h, radio_float_t R2, radio_float_t mu)
|
||||||
|
{
|
||||||
|
cpx_t d;
|
||||||
|
cpx_t e;
|
||||||
|
radio_float_t mag_s, t;
|
||||||
|
|
||||||
|
mag_s = CpxMagS(sym_s_eq);
|
||||||
|
|
||||||
|
t = (radio_float_t)((mag_h + R2*mag_s - mag_s*mag_s*mag_s)/(1E-4+mag_h));
|
||||||
|
d = CpxScaleRealS(sym_s_eq, t);
|
||||||
|
|
||||||
|
e = CpxSubS(d, sym_s_eq);
|
||||||
|
|
||||||
|
LMSUpdateWeigths(&pObj->eq, e, mu/((radio_float_t)1+pObj->Px));
|
||||||
|
}
|
||||||
|
|
||||||
|
// "Sliced Multi-modulus Blind Equalization Algorithm",
|
||||||
|
// ETRI Journal, Volume 27, Number 3, June 2005,
|
||||||
|
// Shafayat Abrar and Roy A. Axford Jr.
|
||||||
|
void MMATrain(cma_t *pObj, cpx_t sym_s_eq, cpx_t R, radio_float_t mu)
|
||||||
|
{
|
||||||
|
cpx_t e;
|
||||||
|
|
||||||
|
e.real = sym_s_eq.real*(R.real - sym_s_eq.real*sym_s_eq.real);
|
||||||
|
e.imag = sym_s_eq.imag*(R.imag - sym_s_eq.imag*sym_s_eq.imag);
|
||||||
|
|
||||||
|
LMSUpdateWeigths(&pObj->eq, e, mu/((radio_float_t)1+pObj->Px));
|
||||||
|
}
|
||||||
|
|
||||||
|
// "Sliced Multi-modulus Blind Equalization Algorithm",
|
||||||
|
// ETRI Journal, Volume 27, Number 3, June 2005,
|
||||||
|
// Shafayat Abrar and Roy A. Axford Jr.
|
||||||
|
void SMMATrain(cma_t *pObj, cpx_t sym_s_eq, radio_float_t mag_h, cpx_t R, radio_float_t mu)
|
||||||
|
{
|
||||||
|
cpx_t e;
|
||||||
|
|
||||||
|
e.real = sym_s_eq.real*(mag_h*R.real - sym_s_eq.real*sym_s_eq.real);
|
||||||
|
e.imag = sym_s_eq.imag*(mag_h*R.imag - sym_s_eq.imag*sym_s_eq.imag);
|
||||||
|
|
||||||
|
LMSUpdateWeigths(&pObj->eq, e, mu/((radio_float_t)1+pObj->Px));
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
// DFE
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
void DFEComplexInit(dfe_cpx_t *pObj, uint32_t K)
|
||||||
|
{
|
||||||
|
pObj->N = 2*K+1;
|
||||||
|
pObj->N_ff = K+1;
|
||||||
|
pObj->N_fb = K;
|
||||||
|
|
||||||
|
EQComplexInit(&pObj->eq, pObj->N);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void DFEComplexFree(dfe_cpx_t *pObj)
|
||||||
|
{
|
||||||
|
EQComplexFree(&pObj->eq);
|
||||||
|
}
|
||||||
|
|
||||||
|
cpx_t DFEComplexProcess(dfe_cpx_t *pObj, cpx_t xs, cpx_t xh)
|
||||||
|
{
|
||||||
|
int32_t i;
|
||||||
|
cpx_t y, *pW_conj, *pX;
|
||||||
|
|
||||||
|
pX = pObj->eq.pX;
|
||||||
|
pW_conj = pObj->eq.pW_conj;
|
||||||
|
|
||||||
|
// Shift Feedback part
|
||||||
|
for(i=pObj->N-1; i > (int32_t)pObj->N_ff; i--)
|
||||||
|
{
|
||||||
|
pX[i] = pX[i-1];
|
||||||
|
}
|
||||||
|
|
||||||
|
// put last x into buffer
|
||||||
|
pX[i] = xh;
|
||||||
|
|
||||||
|
// Shift Feed forward part
|
||||||
|
for(i=pObj->N_ff-1; i > 0; i--)
|
||||||
|
{
|
||||||
|
pX[i] = pX[i-1];
|
||||||
|
}
|
||||||
|
|
||||||
|
// put current x into buffer
|
||||||
|
pX[i] = xs;
|
||||||
|
|
||||||
|
y = CpxMulAdd(Cpx(0, 0), pX, pW_conj, pObj->N);
|
||||||
|
|
||||||
|
return y;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void DFEAdaptLMS(dfe_cpx_t *pObj, cpx_t e, radio_float_t mu)
|
||||||
|
{
|
||||||
|
LMSUpdateWeigths(&pObj->eq, e, mu);
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
// LMS
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
void LMSUpdateWeigths(eq_cpx_t *pObj, cpx_t e, radio_float_t mu)
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
|
e = CpxScaleRealS(CpxConjS(e), mu);
|
||||||
|
|
||||||
|
CpxScale(pObj->pX, e, pObj->pW_conj, pObj->N);
|
||||||
|
CpxAdd(pObj->pW_conj, pObj->pW, pObj->N);
|
||||||
|
|
||||||
|
for(i=0; i < pObj->N; i++)
|
||||||
|
{
|
||||||
|
pObj->pW_conj[i] = CpxConjS(pObj->pW[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
// RLS
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
void RLSInit(rls_t *pObj, uint32_t N, uint32_t M)
|
||||||
|
{
|
||||||
|
uint32_t i, j;
|
||||||
|
radio_float_t *pR;
|
||||||
|
|
||||||
|
pObj->w = (radio_float_t*)malloc(N*sizeof(radio_float_t));
|
||||||
|
memset(pObj->w, 0, N*sizeof(radio_float_t));
|
||||||
|
pObj->w[0] = 1.0f;
|
||||||
|
|
||||||
|
pObj->pW = (cpx_t*)malloc(N*sizeof(cpx_t));
|
||||||
|
memset(pObj->pW, 0, N*sizeof(cpx_t));
|
||||||
|
|
||||||
|
pObj->z = (radio_float_t*)malloc(N*sizeof(radio_float_t));
|
||||||
|
memset(pObj->z, 0, N*sizeof(radio_float_t));
|
||||||
|
|
||||||
|
pObj->x = (radio_float_t*)malloc(N*sizeof(radio_float_t));
|
||||||
|
memset(pObj->x, 0, N*sizeof(radio_float_t));
|
||||||
|
|
||||||
|
pObj->pX = (cpx_t*)malloc(N*M*sizeof(cpx_t));
|
||||||
|
memset(pObj->pX, 0, N*M*sizeof(cpx_t));
|
||||||
|
|
||||||
|
pObj->R = (radio_float_t*)malloc(N*N*sizeof(radio_float_t));
|
||||||
|
memset(pObj->R, 0, N*N*sizeof(radio_float_t));
|
||||||
|
|
||||||
|
pObj->T = (radio_float_t*)malloc(N*N*sizeof(radio_float_t));
|
||||||
|
memset(pObj->T, 0, N*N*sizeof(radio_float_t));
|
||||||
|
|
||||||
|
pObj->T2 = (radio_float_t*)malloc(N*N*sizeof(radio_float_t));
|
||||||
|
memset(pObj->T2, 0, N*N*sizeof(radio_float_t));
|
||||||
|
|
||||||
|
pR = pObj->R;
|
||||||
|
for(i=0; i < N; i++)
|
||||||
|
for(j=0; j < N; j++)
|
||||||
|
pR[i+j*N] = (radio_float_t)1E6*(i==j);
|
||||||
|
|
||||||
|
pObj->N = N;
|
||||||
|
pObj->M = M;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RLSFree(rls_t *pObj)
|
||||||
|
{
|
||||||
|
if(pObj->w)
|
||||||
|
free(pObj->w);
|
||||||
|
|
||||||
|
if(pObj->z)
|
||||||
|
free(pObj->z);
|
||||||
|
|
||||||
|
if(pObj->x)
|
||||||
|
free(pObj->x);
|
||||||
|
|
||||||
|
if(pObj->R)
|
||||||
|
free(pObj->R);
|
||||||
|
|
||||||
|
if(pObj->T)
|
||||||
|
free(pObj->T);
|
||||||
|
|
||||||
|
if(pObj->T2)
|
||||||
|
free(pObj->T2);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
void RLSProcess(rls_t *pObj, radio_float_t rho, radio_float_t mu, radio_float_t x, radio_float_t d, radio_float_t *pE, radio_float_t *pDD)
|
||||||
|
{
|
||||||
|
int i, j, k, N;
|
||||||
|
radio_float_t *pR, *pX, *pZ, *pT, *pT2, v, t, rho_i;
|
||||||
|
|
||||||
|
N = pObj->N;
|
||||||
|
|
||||||
|
FIR(pObj->w, pObj->x, N, &x, pDD, 1);
|
||||||
|
|
||||||
|
*pE = d - *pDD;
|
||||||
|
|
||||||
|
// Whitening
|
||||||
|
pR = pObj->R;
|
||||||
|
pX = pObj->x;
|
||||||
|
for(i=0; i < N; i++)
|
||||||
|
{
|
||||||
|
t = 0;
|
||||||
|
for(j=0; j < N; j++)
|
||||||
|
t += pR[j*N+i] * pX[j];
|
||||||
|
|
||||||
|
pObj->z[i] = t;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Berechnunng der Normierungskonstante
|
||||||
|
v = rho;
|
||||||
|
for(i=0; i < N; i++)
|
||||||
|
v += pObj->x[i] * pObj->z[i];
|
||||||
|
|
||||||
|
v = (radio_float_t)1.0/v;
|
||||||
|
|
||||||
|
// Normierung
|
||||||
|
for(i=0; i < N; i++)
|
||||||
|
pObj->z[i] *= v;
|
||||||
|
|
||||||
|
|
||||||
|
// Filter update
|
||||||
|
for(i=0; i < N; i++)
|
||||||
|
pObj->w[i] += (mu * (*pE)*pObj->z[i]);
|
||||||
|
|
||||||
|
|
||||||
|
// Matrix update
|
||||||
|
pZ = pObj->z;
|
||||||
|
pX = pObj->x;
|
||||||
|
pT = pObj->T;
|
||||||
|
for(i=0; i < N; i++)
|
||||||
|
{
|
||||||
|
for(j=0; j < N; j++)
|
||||||
|
pT[j*N+i] = pZ[i] * pX[j];
|
||||||
|
}
|
||||||
|
|
||||||
|
pT = pObj->T;
|
||||||
|
pT2 = pObj->T2;
|
||||||
|
pR = pObj->R;
|
||||||
|
|
||||||
|
for (i=0;i<N;i++)
|
||||||
|
{
|
||||||
|
for (j=0;j<N;j++)
|
||||||
|
{
|
||||||
|
pT2[j*N+i] = 0;
|
||||||
|
for (k=0;k<N;k++)
|
||||||
|
{
|
||||||
|
pT2[j*N+i] += pT[k*N+i] * pR[j*N+k];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(i=0; i < N*N; i++)
|
||||||
|
pR[i] -= pT2[i];
|
||||||
|
|
||||||
|
rho_i = (radio_float_t)1.0/rho;
|
||||||
|
for(i=0; i < N*N; i++)
|
||||||
|
pR[i] *= rho_i;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
cpx_t RLSProcess(rls_t *pObj, radio_float_t i, radio_float_t q)
|
||||||
|
{
|
||||||
|
uint32_t j;
|
||||||
|
cpx_t y, t;
|
||||||
|
|
||||||
|
y.real = 0;
|
||||||
|
y.imag = 0;
|
||||||
|
for(j=pObj->N-1; j != 0; j--)
|
||||||
|
{
|
||||||
|
pObj->pX[j] = pObj->pX[j-1];
|
||||||
|
}
|
||||||
|
pObj->pX[j].real = i;
|
||||||
|
pObj->pX[j].imag = q;
|
||||||
|
|
||||||
|
for(j=0; j < pObj->N; j++)
|
||||||
|
{
|
||||||
|
pObj->pW[j].real = pObj->w[j];
|
||||||
|
pObj->pW[j].imag = pObj->w[j];
|
||||||
|
}
|
||||||
|
|
||||||
|
/// for(j=0; j < pObj->N; j++)
|
||||||
|
// {
|
||||||
|
// t = CpxMuls(pObj->pX[M*j], CpxConjs(pObj->pW[j]));
|
||||||
|
// y = CpxAdds(y, t);
|
||||||
|
// }
|
||||||
|
|
||||||
|
for(j=0; j < pObj->N; j++)
|
||||||
|
{
|
||||||
|
t.real = pObj->pX[j].real * pObj->pW[j].real;
|
||||||
|
t.imag = pObj->pX[j].imag * pObj->pW[j].imag;
|
||||||
|
|
||||||
|
y = CpxAddS(y, t);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(j=0; j < pObj->N; j++)
|
||||||
|
{
|
||||||
|
pObj->x[j] = pObj->pX[j].real;
|
||||||
|
}
|
||||||
|
|
||||||
|
return y;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
radio_float_t RLSUpdate(rls_t *pObj, radio_float_t rho, radio_float_t mu, radio_float_t y, radio_float_t d)
|
||||||
|
{
|
||||||
|
int i, j, k, N;
|
||||||
|
radio_float_t *pR, *pX, *pZ, *pT, *pT2, v, t, rho_i, e;
|
||||||
|
|
||||||
|
N = pObj->N;
|
||||||
|
|
||||||
|
e = d - y;
|
||||||
|
|
||||||
|
pR = pObj->R;
|
||||||
|
pX = pObj->x;
|
||||||
|
|
||||||
|
// for(j=0; j < pObj->N; j++)
|
||||||
|
// {
|
||||||
|
// pObj->x[j] = pObj->pX[j*pObj->M].real;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// Whitening
|
||||||
|
for(i=0; i < N; i++)
|
||||||
|
{
|
||||||
|
t = 0;
|
||||||
|
for(j=0; j < N; j++)
|
||||||
|
t += pR[j*N+i] * pX[j];
|
||||||
|
|
||||||
|
pObj->z[i] = t;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Berechnunng der Normierungskonstante
|
||||||
|
v = rho;
|
||||||
|
for(i=0; i < N; i++)
|
||||||
|
v += pObj->x[i] * pObj->z[i];
|
||||||
|
|
||||||
|
v = (radio_float_t)1.0/v;
|
||||||
|
|
||||||
|
// Normierung
|
||||||
|
for(i=0; i < N; i++)
|
||||||
|
pObj->z[i] *= v;
|
||||||
|
|
||||||
|
|
||||||
|
// Filter update
|
||||||
|
for(i=0; i < N; i++)
|
||||||
|
pObj->w[i] += (mu * e * pObj->z[i]);
|
||||||
|
|
||||||
|
|
||||||
|
// Matrix update
|
||||||
|
pZ = pObj->z;
|
||||||
|
pX = pObj->x;
|
||||||
|
pT = pObj->T;
|
||||||
|
for(i=0; i < N; i++)
|
||||||
|
{
|
||||||
|
for(j=0; j < N; j++)
|
||||||
|
pT[j*N+i] = pZ[i] * pX[j];
|
||||||
|
}
|
||||||
|
|
||||||
|
pT = pObj->T;
|
||||||
|
pT2 = pObj->T2;
|
||||||
|
pR = pObj->R;
|
||||||
|
|
||||||
|
for (i=0;i<N;i++)
|
||||||
|
{
|
||||||
|
for (j=0;j<N;j++)
|
||||||
|
{
|
||||||
|
pT2[j*N+i] = 0;
|
||||||
|
for (k=0;k<N;k++)
|
||||||
|
{
|
||||||
|
pT2[j*N+i] += pT[k*N+i] * pR[j*N+k];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(i=0; i < N*N; i++)
|
||||||
|
pR[i] -= pT2[i];
|
||||||
|
|
||||||
|
rho_i = (radio_float_t)1.0/rho;
|
||||||
|
for(i=0; i < N*N; i++)
|
||||||
|
pR[i] *= rho_i;
|
||||||
|
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
Executable
+96
@@ -0,0 +1,96 @@
|
|||||||
|
// --------------------------------------------------------------
|
||||||
|
#ifndef EQUALIZER_H
|
||||||
|
#define EQUALIZER_H
|
||||||
|
|
||||||
|
#include "radio_types.h"
|
||||||
|
#include "real.h"
|
||||||
|
#include "cpx.h"
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
#define CEF_MODE_NOP 0
|
||||||
|
#define CEF_MODE_CMA 1
|
||||||
|
#define CEF_MODE_DD 2
|
||||||
|
#define CEF_MODE_EQ_UPD 3
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
// Types
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
typedef struct _eq_cpx_t
|
||||||
|
{
|
||||||
|
uint32_t N;
|
||||||
|
cpx_t *pX, *pW;
|
||||||
|
cpx_t *pW_conj;
|
||||||
|
|
||||||
|
} eq_cpx_t;
|
||||||
|
|
||||||
|
typedef struct _cma_t
|
||||||
|
{
|
||||||
|
uint32_t N, M;
|
||||||
|
eq_cpx_t eq;
|
||||||
|
radio_float_t Px, Px_last;
|
||||||
|
|
||||||
|
} cma_t;
|
||||||
|
|
||||||
|
typedef struct _dfe_cpx_t
|
||||||
|
{
|
||||||
|
uint32_t N, N_ff, N_fb;
|
||||||
|
eq_cpx_t eq;
|
||||||
|
|
||||||
|
} dfe_cpx_t;
|
||||||
|
|
||||||
|
typedef struct _rls_t
|
||||||
|
{
|
||||||
|
uint32_t N, M;
|
||||||
|
cpx_t *pX, *pW, *pZ, *pR, *pT;
|
||||||
|
radio_float_t *R, *T, *T2, *z, *w, *x;
|
||||||
|
|
||||||
|
} rls_t;
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
// Functions
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
// Helpers
|
||||||
|
void CoeffComplexUnitAt(cpx_t *pW, uint32_t N, uint32_t dly);
|
||||||
|
void CoeffComplexConv(cpx_t *pSrc, cpx_t *pDst, uint32_t N, uint32_t dly);
|
||||||
|
|
||||||
|
// General Equalizer
|
||||||
|
void EQComplexInit(eq_cpx_t *pObj, uint32_t N);
|
||||||
|
void EQComplexFree(eq_cpx_t *pObj);
|
||||||
|
cpx_t EQComplexProcess(eq_cpx_t *pObj, cpx_t x);
|
||||||
|
|
||||||
|
// CMA Blind Adaption (uses EQComplex and LMSUpdate)
|
||||||
|
void CMAInit(cma_t *pObj, uint32_t ntaps);
|
||||||
|
void CMAFree(cma_t *pObj);
|
||||||
|
cpx_t CMAProcess(cma_t *pObj, cpx_t x);
|
||||||
|
void CMATrainGodard(cma_t *pObj, cpx_t sym_s_eq, radio_float_t mag_h, radio_float_t R2, radio_float_t mu);
|
||||||
|
|
||||||
|
// MMA
|
||||||
|
void MMATrain(cma_t *pObj, cpx_t sym_s_eq, cpx_t R, radio_float_t mu);
|
||||||
|
void SMMATrain(cma_t *pObj, cpx_t sym_s_eq, radio_float_t mag_h, cpx_t R, radio_float_t mu);
|
||||||
|
|
||||||
|
// DFE Decision Directed Adaption (uses EQComplex and LMSUpdate)
|
||||||
|
void DFEComplexInit(dfe_cpx_t *pObj, uint32_t K);
|
||||||
|
void DFEComplexFree(dfe_cpx_t *pObj);
|
||||||
|
cpx_t DFEComplexProcess(dfe_cpx_t *pObj, cpx_t xs, cpx_t xh);
|
||||||
|
void DFEAdaptLMS(dfe_cpx_t *pObj, cpx_t e, radio_float_t mu);
|
||||||
|
|
||||||
|
// LMS Adaption
|
||||||
|
void LMSUpdateWeigths(eq_cpx_t *pObj, cpx_t e, radio_float_t mu);
|
||||||
|
|
||||||
|
// RLS Adaption
|
||||||
|
void RLSInit(rls_t *pObj, uint32_t N, uint32_t M);
|
||||||
|
void RLSFree(rls_t *pObj);
|
||||||
|
cpx_t RLSProcess(rls_t *pObj, radio_float_t i, radio_float_t q);
|
||||||
|
radio_float_t RLSUpdate(rls_t *pObj, radio_float_t rho, radio_float_t mu, radio_float_t y, radio_float_t d);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
#endif // EQUALIZER_H
|
||||||
@@ -0,0 +1,356 @@
|
|||||||
|
// --------------------------------------------------------------
|
||||||
|
#include <string.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <crc/crc.h>
|
||||||
|
#include "symbol.h"
|
||||||
|
#include "frame.h"
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
uint32_t Scramble(uint8_t *pSrcDst, uint32_t state, uint32_t poly, uint32_t len)
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
|
while(len)
|
||||||
|
{
|
||||||
|
*pSrcDst ^= (uint8_t)state;
|
||||||
|
pSrcDst++;
|
||||||
|
len--;
|
||||||
|
|
||||||
|
for (i=0; i < 8; i++)
|
||||||
|
{
|
||||||
|
if (state & 0x0001)
|
||||||
|
state = (state >> 1) ^ poly;
|
||||||
|
else
|
||||||
|
state = (state >> 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t FrameCalcNumStreamBytes(uint32_t len_raw)
|
||||||
|
{
|
||||||
|
uint32_t len, num_frames;
|
||||||
|
num_frames = (uint32_t)ceil((float)len_raw / FRAME_NUM_BYTES_PER_FRAME);
|
||||||
|
len = num_frames*sizeof(frame_t);
|
||||||
|
|
||||||
|
if (len < sizeof(frame_t))
|
||||||
|
len = sizeof(frame_t);
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t FrameFormat(uint8_t *pRaw, uint8_t *pFormatted, uint32_t len_raw, uint32_t *pPrn_state, uint16_t frame_type)
|
||||||
|
{
|
||||||
|
frame_t frame;
|
||||||
|
|
||||||
|
uint32_t bytes_remain, len_formatted, len;
|
||||||
|
uint32_t prn_state;
|
||||||
|
|
||||||
|
if (len_raw == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
prn_state = *pPrn_state;
|
||||||
|
|
||||||
|
// Set preamble
|
||||||
|
frame.hdr.preamble[0] = FRAME_PREAMBLE_IV;
|
||||||
|
frame.hdr.preamble[1] = ~(frame.hdr.preamble[0]);
|
||||||
|
|
||||||
|
bytes_remain = len_raw;
|
||||||
|
len_formatted = 0;
|
||||||
|
while(bytes_remain)
|
||||||
|
{
|
||||||
|
len = FRAME_NUM_BYTES_PER_FRAME;
|
||||||
|
if (bytes_remain < FRAME_NUM_BYTES_PER_FRAME)
|
||||||
|
len = bytes_remain;
|
||||||
|
|
||||||
|
memset(frame.data, 0, FRAME_NUM_BYTES_PER_FRAME);
|
||||||
|
memcpy(frame.data, pRaw, len);
|
||||||
|
frame.hdr.crc16 = Crc16(FRAME_CRC16_POLY, FRAME_CRC16_IV, frame.data, FRAME_NUM_BYTES_PER_FRAME);
|
||||||
|
frame.hdr.type = frame_type;
|
||||||
|
frame.hdr.prn_state = prn_state;
|
||||||
|
frame.hdr.length = (uint16_t)len;
|
||||||
|
prn_state = Scramble(frame.data, prn_state, FRAME_SCRAMBLER_POLY, FRAME_NUM_BYTES_PER_FRAME);
|
||||||
|
prn_state = Scramble((uint8_t*)&frame.hdr.crc16, prn_state, FRAME_SCRAMBLER_POLY, sizeof(frame.hdr.crc16));
|
||||||
|
prn_state = Scramble((uint8_t*)&frame.hdr.type, prn_state, FRAME_SCRAMBLER_POLY, sizeof(frame.hdr.type));
|
||||||
|
prn_state = Scramble((uint8_t*)&frame.hdr.length, prn_state, FRAME_SCRAMBLER_POLY, sizeof(frame.hdr.length));
|
||||||
|
|
||||||
|
pRaw += len;
|
||||||
|
bytes_remain -= len;
|
||||||
|
|
||||||
|
memcpy(pFormatted, &frame, sizeof(frame_t));
|
||||||
|
pFormatted += sizeof(frame_t);
|
||||||
|
len_formatted += sizeof(frame_t);
|
||||||
|
|
||||||
|
}
|
||||||
|
*pPrn_state = prn_state;
|
||||||
|
return len_formatted;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t FrameDeformat(uint8_t *pFormatted, uint8_t *pRaw, uint32_t len_formatted, uint16_t frame_type_mask)
|
||||||
|
{
|
||||||
|
frame_hdr_t hdr;
|
||||||
|
uint32_t bytes_remain, len_raw, sync_state, frame_sync, i;
|
||||||
|
uint16_t crc16_ist;
|
||||||
|
uint8_t temp[FRAME_NUM_BYTES_PER_FRAME];
|
||||||
|
uint32_t prn_state;
|
||||||
|
|
||||||
|
if (len_formatted == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
bytes_remain = len_formatted;
|
||||||
|
len_raw = 0;
|
||||||
|
while(bytes_remain)
|
||||||
|
{
|
||||||
|
|
||||||
|
sync_state = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
// Find frame boundaries
|
||||||
|
switch(sync_state)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
if (pFormatted[i] == FRAME_PREAMBLE_IV)
|
||||||
|
{
|
||||||
|
sync_state = 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
if ((uint8_t)(~pFormatted[i]) == pFormatted[i-1])
|
||||||
|
{
|
||||||
|
sync_state = 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sync_state = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
bytes_remain--;
|
||||||
|
frame_sync = (sync_state == 2);
|
||||||
|
|
||||||
|
} while(bytes_remain && !frame_sync);
|
||||||
|
|
||||||
|
memcpy(&hdr, &pFormatted[i-2], sizeof(frame_hdr_t));
|
||||||
|
memcpy(temp, &pFormatted[i-2+sizeof(frame_hdr_t)], FRAME_NUM_BYTES_PER_FRAME);
|
||||||
|
|
||||||
|
prn_state = Scramble(temp, hdr.prn_state, FRAME_SCRAMBLER_POLY, FRAME_NUM_BYTES_PER_FRAME);
|
||||||
|
prn_state = Scramble((uint8_t*)&hdr.crc16, prn_state, FRAME_SCRAMBLER_POLY, sizeof(hdr.crc16));
|
||||||
|
prn_state = Scramble((uint8_t*)&hdr.type, prn_state, FRAME_SCRAMBLER_POLY, sizeof(hdr.type));
|
||||||
|
Scramble((uint8_t*)&hdr.length, prn_state, FRAME_SCRAMBLER_POLY, sizeof(hdr.length));
|
||||||
|
|
||||||
|
crc16_ist = Crc16(FRAME_CRC16_POLY, FRAME_CRC16_IV, temp, FRAME_NUM_BYTES_PER_FRAME);
|
||||||
|
|
||||||
|
if (crc16_ist == hdr.crc16)
|
||||||
|
{
|
||||||
|
|
||||||
|
if ((hdr.type & frame_type_mask) == frame_type_mask)
|
||||||
|
{
|
||||||
|
memcpy(&pRaw[len_raw], temp, hdr.length);
|
||||||
|
len_raw += hdr.length;
|
||||||
|
}
|
||||||
|
i += FRAME_NUM_BYTES_PER_FRAME + sizeof(frame_hdr_t) - 2;
|
||||||
|
bytes_remain -= (FRAME_NUM_BYTES_PER_FRAME + sizeof(frame_hdr_t) - 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((int32_t)bytes_remain < sizeof(frame_t))
|
||||||
|
bytes_remain = 0;
|
||||||
|
}
|
||||||
|
return len_raw;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Transmission order MSB first
|
||||||
|
uint32_t FrameSerialize(uint8_t *pSrc, uint8_t *pDst, uint32_t nBitsPerSym, uint32_t srclen)
|
||||||
|
{
|
||||||
|
|
||||||
|
uint32_t bits_remain, i, j;
|
||||||
|
uint8_t src, dst;
|
||||||
|
|
||||||
|
if (srclen == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (nBitsPerSym > 8)
|
||||||
|
return (uint32_t)-1;
|
||||||
|
|
||||||
|
j = 0;
|
||||||
|
src = *pSrc;
|
||||||
|
bits_remain = 8;
|
||||||
|
while(srclen)
|
||||||
|
{
|
||||||
|
dst = 0;
|
||||||
|
for (i=0; i < nBitsPerSym; i++)
|
||||||
|
{
|
||||||
|
dst <<= 1;
|
||||||
|
dst |= (0x01 & (src >> 7));
|
||||||
|
src <<= 1;
|
||||||
|
|
||||||
|
bits_remain--;
|
||||||
|
if (bits_remain == 0)
|
||||||
|
{
|
||||||
|
pSrc++;
|
||||||
|
bits_remain = 8;
|
||||||
|
src = *pSrc;
|
||||||
|
srclen--;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
pDst[j++] = dst;
|
||||||
|
}
|
||||||
|
return j;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t FrameDeSerialize(uint8_t *pSrc, uint8_t *pDst, uint32_t nBitsPerSym, uint32_t srclen, uint16_t frame_type_mask)
|
||||||
|
{
|
||||||
|
|
||||||
|
uint32_t size, err, bits_remain, i, j, byte_sync, srcRemain, bitStart, numCorrupt;
|
||||||
|
uint8_t src, dst, *pBitStart;
|
||||||
|
uint16_t dst16, t;
|
||||||
|
uint8_t frame[sizeof(frame_t)], data[FRAME_NUM_BYTES_PER_FRAME];
|
||||||
|
|
||||||
|
if (srclen == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (nBitsPerSym > 8)
|
||||||
|
return (uint32_t)-1;
|
||||||
|
|
||||||
|
src = *pSrc;
|
||||||
|
|
||||||
|
bits_remain = nBitsPerSym;
|
||||||
|
bitStart = bits_remain;
|
||||||
|
pBitStart = pSrc;
|
||||||
|
numCorrupt = 0;
|
||||||
|
|
||||||
|
t = (FRAME_PREAMBLE_IV << 8) | (0xFF & ~FRAME_PREAMBLE_IV);
|
||||||
|
size = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
j = 0;
|
||||||
|
dst16 = 0;
|
||||||
|
byte_sync = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
bits_remain--;
|
||||||
|
dst16 <<= 1;
|
||||||
|
dst16 |= (0x01 & (src >> (bits_remain)));
|
||||||
|
|
||||||
|
if (bits_remain == 0)
|
||||||
|
{
|
||||||
|
pSrc++;
|
||||||
|
bits_remain = nBitsPerSym;
|
||||||
|
src = *pSrc;
|
||||||
|
srclen--;
|
||||||
|
if (!srclen)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find frame boundaries
|
||||||
|
if (dst16 == t)
|
||||||
|
{
|
||||||
|
pBitStart = pSrc;
|
||||||
|
bitStart = bits_remain;
|
||||||
|
srcRemain = srclen;
|
||||||
|
byte_sync = 1;
|
||||||
|
frame[j++] = 0xFF & (t >> 8);
|
||||||
|
frame[j++] = 0xFF & t;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} while(srclen && !byte_sync);
|
||||||
|
if (!srclen)
|
||||||
|
break;
|
||||||
|
|
||||||
|
for(j; j < sizeof(frame_t); j++)
|
||||||
|
{
|
||||||
|
dst = 0;
|
||||||
|
for (i=0; i < 8; i++)
|
||||||
|
{
|
||||||
|
bits_remain--;
|
||||||
|
dst <<= 1;
|
||||||
|
dst |= (0x01 & (src >> (bits_remain)));
|
||||||
|
|
||||||
|
if (bits_remain == 0)
|
||||||
|
{
|
||||||
|
pSrc++;
|
||||||
|
bits_remain = nBitsPerSym;
|
||||||
|
src = *pSrc;
|
||||||
|
srclen--;
|
||||||
|
if (!srclen)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
frame[j] = dst;
|
||||||
|
if (!srclen)
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
if (!srclen)
|
||||||
|
break;
|
||||||
|
|
||||||
|
err = FrameDeformat(frame, data, sizeof(frame_t), frame_type_mask);
|
||||||
|
if (err > 0)
|
||||||
|
{
|
||||||
|
memcpy(&pDst[size], frame, sizeof(frame_t));
|
||||||
|
size += sizeof(frame_t);
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (size > 0)
|
||||||
|
numCorrupt++;
|
||||||
|
bits_remain = bitStart;
|
||||||
|
pSrc = pBitStart;
|
||||||
|
srclen = srcRemain;
|
||||||
|
}
|
||||||
|
|
||||||
|
} while(srclen);
|
||||||
|
|
||||||
|
// printf("Number of corrupted frames = %d\n", numCorrupt);
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Differential M-PSK symbol mapping
|
||||||
|
uint32_t FrameSymbolsMap(uint8_t *pBits, cpx_t *pSym, uint32_t nBitsPerSym, uint32_t num_syms, uint32_t type)
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
sym_map_t sym_mapper;
|
||||||
|
|
||||||
|
if (num_syms == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
SymMapInit(&sym_mapper, nBitsPerSym, type);
|
||||||
|
|
||||||
|
for(i=0; i < num_syms; i++)
|
||||||
|
{
|
||||||
|
pSym[i] = SymMapEncode(&sym_mapper, pBits[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return num_syms;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Differential M-PSK symbol de-mapping
|
||||||
|
uint32_t FrameSymbolsDemap(cpx_t *pSym, uint8_t *pBits, uint32_t nBitsPerSym, uint32_t num_syms, uint32_t type)
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
sym_map_t sym_demapper;
|
||||||
|
sym_err_t sym_err;
|
||||||
|
|
||||||
|
if (num_syms == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
memset(&sym_err, 0, sizeof(sym_err_t));
|
||||||
|
|
||||||
|
SymMapInit(&sym_demapper, nBitsPerSym, type);
|
||||||
|
|
||||||
|
for(i=0; i < num_syms; i++)
|
||||||
|
{
|
||||||
|
pBits[i] = SymMapDecode(&sym_demapper, pSym[i], &sym_err);
|
||||||
|
}
|
||||||
|
|
||||||
|
return num_syms;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
// --------------------------------------------------------------
|
||||||
|
#ifndef FRAME_H
|
||||||
|
#define FRAME_H
|
||||||
|
|
||||||
|
#include "radio_types.h"
|
||||||
|
#include "cpx.h"
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
// Constants
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
#define FRAME_CRC16_IV 0x0000
|
||||||
|
#define FRAME_CRC16_POLY 0x1021
|
||||||
|
#define FRAME_PREAMBLE_IV 0x55
|
||||||
|
#define FRAME_SCRAMBLER_SEED 0x12345678
|
||||||
|
#define FRAME_SCRAMBLER_POLY 0x80C18601
|
||||||
|
#define FRAME_NUM_BYTES_PER_FRAME 32
|
||||||
|
#define FRAME_TYPE_IDLE 0x01
|
||||||
|
#define FRAME_TYPE_DATA 0x02
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
// Types
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
typedef struct _frame_hdr_t
|
||||||
|
{
|
||||||
|
uint8_t preamble[2];
|
||||||
|
uint32_t prn_state;
|
||||||
|
uint16_t crc16;
|
||||||
|
uint16_t type;
|
||||||
|
uint16_t length;
|
||||||
|
|
||||||
|
} frame_hdr_t;
|
||||||
|
|
||||||
|
typedef struct _frame_t
|
||||||
|
{
|
||||||
|
frame_hdr_t hdr;
|
||||||
|
uint8_t data[FRAME_NUM_BYTES_PER_FRAME];
|
||||||
|
|
||||||
|
} frame_t;
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
// Functions
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
uint32_t Scramble(uint8_t *pSrcDst, uint32_t state, uint32_t poly, uint32_t len);
|
||||||
|
uint32_t FrameCalcNumStreamBytes(uint32_t len_raw);
|
||||||
|
uint32_t FrameFormat(uint8_t *pRaw, uint8_t *pFormatted, uint32_t len_raw, uint32_t *pPrn_state, uint16_t frame_type);
|
||||||
|
uint32_t FrameDeformat(uint8_t *pFormatted, uint8_t *pRaw, uint32_t len_formatted, uint16_t frame_type);
|
||||||
|
uint32_t FrameSerialize(uint8_t *pSrc, uint8_t *pDst, uint32_t nBitsPerSym, uint32_t srclen);
|
||||||
|
uint32_t FrameDeSerialize(uint8_t *pSrc, uint8_t *pDst, uint32_t nBitsPerSym, uint32_t srclen, uint16_t frame_type);
|
||||||
|
uint32_t FrameSymbolsMap(uint8_t *pBits, cpx_t *pSym, uint32_t nBitsPerSym, uint32_t num_syms, uint32_t type);
|
||||||
|
uint32_t FrameSymbolsDemap(cpx_t *pSym, uint8_t *pBits, uint32_t nBitsPerSym, uint32_t num_syms, uint32_t type);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif // __cplusplus
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
#endif // FRAME_H
|
||||||
Executable
+830
@@ -0,0 +1,830 @@
|
|||||||
|
// --------------------------------------------------------------
|
||||||
|
#include <string.h>
|
||||||
|
#include <malloc.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include "interpolation.h"
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
// Complex FIR filtering with downsampling
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
void FirCpxInit(fir_cpx_t *pObj, uint32_t N, uint32_t M_up, uint32_t M_down)
|
||||||
|
{
|
||||||
|
pObj->pX = (cpx_t*)malloc(N*sizeof(cpx_t));
|
||||||
|
memset(pObj->pX, 0, N*sizeof(cpx_t));
|
||||||
|
pObj->N = N;
|
||||||
|
pObj->M_up = M_up;
|
||||||
|
pObj->M_down = M_down;
|
||||||
|
pObj->r = 0;
|
||||||
|
pObj->w = 0;
|
||||||
|
ClockInit(&pObj->clockUp, M_up);
|
||||||
|
ClockInit(&pObj->clockDown, M_down);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FirCpxFree(fir_cpx_t *pObj)
|
||||||
|
{
|
||||||
|
free(pObj->pX);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t FirCpxProcessReal(fir_cpx_t *pObj, radio_float_t *pW, cpx_t *pSrc, cpx_t *pDst, uint32_t len)
|
||||||
|
{
|
||||||
|
|
||||||
|
uint32_t j, w, r, N;
|
||||||
|
uint32_t remain;
|
||||||
|
uint32_t nBytesWritten;
|
||||||
|
uint32_t nBytesRead;
|
||||||
|
const cpx_t zero = Cpx(0,0);
|
||||||
|
|
||||||
|
w = pObj->w;
|
||||||
|
r = pObj->r;
|
||||||
|
N = pObj->N;
|
||||||
|
|
||||||
|
nBytesWritten = 0;
|
||||||
|
nBytesRead = 0;
|
||||||
|
remain = len*pObj->M_up;
|
||||||
|
while(remain--)
|
||||||
|
{
|
||||||
|
if (ClockIsTick(&pObj->clockUp, 1))
|
||||||
|
{
|
||||||
|
pObj->pX[w] = pSrc[nBytesRead];
|
||||||
|
nBytesRead++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pObj->pX[w] = zero;
|
||||||
|
}
|
||||||
|
if (++w >= N)
|
||||||
|
w = 0;
|
||||||
|
|
||||||
|
if (ClockIsTick(&pObj->clockDown, 1))
|
||||||
|
{
|
||||||
|
// fs/downSampleFactor
|
||||||
|
pDst[nBytesWritten] = zero;
|
||||||
|
for (j=0; j < N; j++)
|
||||||
|
{
|
||||||
|
|
||||||
|
pDst[nBytesWritten].real += pObj->pX[r].real * pW[j];
|
||||||
|
pDst[nBytesWritten].imag += pObj->pX[r].imag * pW[j];
|
||||||
|
|
||||||
|
if (--r >= N)
|
||||||
|
r = N-1;
|
||||||
|
|
||||||
|
}
|
||||||
|
nBytesWritten++;
|
||||||
|
}
|
||||||
|
if (++r >= N)
|
||||||
|
r = 0;
|
||||||
|
}
|
||||||
|
pObj->r = r;
|
||||||
|
pObj->w = w;
|
||||||
|
|
||||||
|
return nBytesWritten;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FirCpxMultirateStageDownInit(fir_cpx_multirate_stage_t *pObj, radio_float_t *pW, uint32_t N, uint32_t M, uint32_t k)
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
radio_float_t *_pW;
|
||||||
|
|
||||||
|
pObj->N = 0;
|
||||||
|
for (i=k; i < N; i += M)
|
||||||
|
{
|
||||||
|
pObj->N++;
|
||||||
|
}
|
||||||
|
pObj->pW = (radio_float_t*)malloc(pObj->N*sizeof(cpx_t));
|
||||||
|
_pW = pObj->pW;
|
||||||
|
for (i=k; i < N; i += M)
|
||||||
|
{
|
||||||
|
*(_pW++) = pW[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
pObj->k = k;
|
||||||
|
pObj->K = M;
|
||||||
|
pObj->pX = (cpx_t*)malloc(pObj->N*sizeof(cpx_t));
|
||||||
|
memset(pObj->pX, 0, pObj->N*sizeof(cpx_t));
|
||||||
|
}
|
||||||
|
|
||||||
|
void FirCpxMultirateStageUpInit(fir_cpx_multirate_stage_t *pObj, radio_float_t *pW, uint32_t N, uint32_t L, uint32_t k)
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
radio_float_t *_pW;
|
||||||
|
|
||||||
|
pObj->N = 0;
|
||||||
|
for (i=L-k-1; i < N; i += L)
|
||||||
|
{
|
||||||
|
pObj->N++;
|
||||||
|
}
|
||||||
|
pObj->pW = (radio_float_t*)malloc(pObj->N*sizeof(cpx_t));
|
||||||
|
_pW = pObj->pW;
|
||||||
|
|
||||||
|
if (pW)
|
||||||
|
{
|
||||||
|
for (i=L-k-1; i < N; i += L)
|
||||||
|
{
|
||||||
|
*(_pW++) = pW[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pObj->k = k;
|
||||||
|
pObj->K = L;
|
||||||
|
pObj->pX = (cpx_t*)malloc(pObj->N*sizeof(cpx_t));
|
||||||
|
memset(pObj->pX, 0, pObj->N*sizeof(cpx_t));
|
||||||
|
}
|
||||||
|
|
||||||
|
void FirCpxMultirateStageFree(fir_cpx_multirate_stage_t *pObj)
|
||||||
|
{
|
||||||
|
if (pObj->pX)
|
||||||
|
free(pObj->pX);
|
||||||
|
|
||||||
|
if (pObj->pW)
|
||||||
|
free(pObj->pW);
|
||||||
|
}
|
||||||
|
|
||||||
|
cpx_t FirCpxMultirateStageProcessDownAccum(fir_cpx_multirate_stage_t *pObj, cpx_t res, cpx_t src)
|
||||||
|
{
|
||||||
|
int32_t i;
|
||||||
|
|
||||||
|
for (i=pObj->N-1; i > 0; i--)
|
||||||
|
{
|
||||||
|
pObj->pX[i] = pObj->pX[i-1];
|
||||||
|
}
|
||||||
|
pObj->pX[i] = src;
|
||||||
|
|
||||||
|
return CpxMulRealAdd(res, pObj->pX, pObj->pW, pObj->N);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t FirCpxMultirateStageProcessUp(fir_cpx_multirate_stage_t *pObj, cpx_t *pSrc, cpx_t *pDst, uint32_t len)
|
||||||
|
{
|
||||||
|
int32_t i;
|
||||||
|
uint32_t num_written;
|
||||||
|
|
||||||
|
num_written = 0;
|
||||||
|
while(len--)
|
||||||
|
{
|
||||||
|
for (i=pObj->N-1; i > 0; i--)
|
||||||
|
{
|
||||||
|
pObj->pX[i] = pObj->pX[i-1];
|
||||||
|
}
|
||||||
|
pObj->pX[i] = *(pSrc++);
|
||||||
|
|
||||||
|
pDst[pObj->K-1 - pObj->k + num_written] = CpxMulRealAdd(Cpx(0,0), pObj->pX, pObj->pW, pObj->N);
|
||||||
|
|
||||||
|
num_written += pObj->K;
|
||||||
|
}
|
||||||
|
return num_written;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FirCpxMultirateDownInit(fir_cpx_multirate_t *pObj, radio_float_t *pW, uint32_t N, uint32_t M)
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
|
pObj->L = 0;
|
||||||
|
pObj->M = M;
|
||||||
|
pObj->N = N;
|
||||||
|
pObj->k = M-1;
|
||||||
|
pObj->res = Cpx(0,0);
|
||||||
|
pObj->pStageUp = 0;
|
||||||
|
pObj->pStageDown = (fir_cpx_multirate_stage_t*)malloc(M*sizeof(fir_cpx_multirate_stage_t));
|
||||||
|
|
||||||
|
for (i=0; i < M; i++)
|
||||||
|
{
|
||||||
|
FirCpxMultirateStageDownInit(&pObj->pStageDown[i], pW, N, M, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FirCpxMultirateUpInit(fir_cpx_multirate_t *pObj, radio_float_t *pW, uint32_t N, uint32_t L)
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
|
pObj->L = L;
|
||||||
|
pObj->M = 0;
|
||||||
|
pObj->N = N;
|
||||||
|
pObj->k = 0;
|
||||||
|
pObj->res = Cpx(0,0);
|
||||||
|
pObj->pStageDown = 0;
|
||||||
|
pObj->pStageUp = (fir_cpx_multirate_stage_t*)malloc(L*sizeof(fir_cpx_multirate_stage_t));
|
||||||
|
|
||||||
|
for (i=0; i < L; i++)
|
||||||
|
{
|
||||||
|
FirCpxMultirateStageUpInit(&pObj->pStageUp[i], pW, N, L, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FirCpxMultirateFree(fir_cpx_multirate_t *pObj)
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
|
if (pObj->pStageDown)
|
||||||
|
{
|
||||||
|
for (i=0; i < pObj->M; i++)
|
||||||
|
{
|
||||||
|
FirCpxMultirateStageFree(&pObj->pStageDown[i]);
|
||||||
|
}
|
||||||
|
free(pObj->pStageDown);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pObj->pStageUp)
|
||||||
|
{
|
||||||
|
for (i=0; i < pObj->L; i++)
|
||||||
|
{
|
||||||
|
FirCpxMultirateStageFree(&pObj->pStageUp[i]);
|
||||||
|
}
|
||||||
|
free(pObj->pStageUp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FirCpxMultirateUpReinit(fir_cpx_multirate_t *pObj, radio_float_t *pW, uint32_t N, uint32_t L)
|
||||||
|
{
|
||||||
|
FirCpxMultirateFree(pObj);
|
||||||
|
FirCpxMultirateUpInit(pObj, pW, N, L);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t FirCpxDownZero(fir_cpx_multirate_t *pObj, cpx_t *pDst, uint32_t len)
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
uint32_t num_written;
|
||||||
|
|
||||||
|
num_written = 0;
|
||||||
|
for (i=0; i < len; i += pObj->M)
|
||||||
|
{
|
||||||
|
*(pDst++) = Cpx(0,0);
|
||||||
|
num_written++;
|
||||||
|
}
|
||||||
|
return num_written;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t FirCpxDownProcess(fir_cpx_multirate_t *pObj, cpx_t *pSrc, cpx_t *pDst, uint32_t len)
|
||||||
|
{
|
||||||
|
uint32_t num_written_soll;
|
||||||
|
uint32_t num_written_ist;
|
||||||
|
|
||||||
|
num_written_ist = 0;
|
||||||
|
num_written_soll = FirCpxDownZero(pObj, pDst, len);
|
||||||
|
while(len--)
|
||||||
|
{
|
||||||
|
pObj->res = FirCpxMultirateStageProcessDownAccum(&pObj->pStageDown[pObj->k], pObj->res, *(pSrc++));
|
||||||
|
pObj->k--;
|
||||||
|
if (pObj->k >= pObj->M)
|
||||||
|
{
|
||||||
|
pDst[num_written_ist++] = pObj->res;
|
||||||
|
pObj->res = Cpx(0,0);
|
||||||
|
pObj->k = pObj->M-1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return num_written_ist;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t FirCpxUpZero(fir_cpx_multirate_t *pObj, cpx_t *pDst, uint32_t len)
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
uint32_t num_written;
|
||||||
|
|
||||||
|
num_written = 0;
|
||||||
|
for (i=0; i < pObj->L*len; i++)
|
||||||
|
{
|
||||||
|
*(pDst++) = Cpx(0,0);
|
||||||
|
num_written++;
|
||||||
|
}
|
||||||
|
return num_written;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t FirCpxUpProcess(fir_cpx_multirate_t *pObj, cpx_t *pSrc, cpx_t *pDst, uint32_t len)
|
||||||
|
{
|
||||||
|
uint32_t k;
|
||||||
|
uint32_t res;
|
||||||
|
uint32_t num_written_ist;
|
||||||
|
|
||||||
|
num_written_ist = 0;
|
||||||
|
for (k=0; k < pObj->L; k++)
|
||||||
|
{
|
||||||
|
res = FirCpxMultirateStageProcessUp(&pObj->pStageUp[k], pSrc, pDst, len);
|
||||||
|
if (num_written_ist < res)
|
||||||
|
num_written_ist = res;
|
||||||
|
|
||||||
|
}
|
||||||
|
return num_written_ist;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
// Complex FIR-based polyphase interpolation filter
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
radio_float_t PolyPhaseCpxIpInit(ppip_cpx_t *pObj, radio_float_t fa, radio_float_t tsym, radio_float_t alpha, uint32_t N, uint32_t M)
|
||||||
|
{
|
||||||
|
uint32_t i, j;
|
||||||
|
fir_float_t *pCoeff;
|
||||||
|
radio_float_t k;
|
||||||
|
|
||||||
|
// Calculate polyphase filter
|
||||||
|
pCoeff = (fir_float_t*)malloc((N+1)*M*sizeof(fir_float_t));
|
||||||
|
memset(pCoeff, 0, (N+1)*M*sizeof(fir_float_t));
|
||||||
|
|
||||||
|
k = CalcFirSRRC(pCoeff, M*fa, tsym, alpha, N*M);
|
||||||
|
|
||||||
|
pObj->ppCoeff = (fir_float_t**)malloc(M*sizeof(fir_float_t*));
|
||||||
|
for(i=0; i < M; i++)
|
||||||
|
{
|
||||||
|
pObj->ppCoeff[i] = (fir_float_t*)malloc(N*sizeof(fir_float_t));
|
||||||
|
memset(pObj->ppCoeff[i], 0, N*sizeof(fir_float_t));
|
||||||
|
}
|
||||||
|
for(i=0; i < M; i++)
|
||||||
|
{
|
||||||
|
for(j=0; j < N; j++)
|
||||||
|
{
|
||||||
|
pObj->ppCoeff[i][j] = M*pCoeff[M*j+M/2+i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIFO
|
||||||
|
pObj->L = N; // Influences STR-Loop delay
|
||||||
|
pObj->w = 0;
|
||||||
|
pObj->r = 0;
|
||||||
|
|
||||||
|
pObj->pFifo = (cpx_t*)malloc(pObj->L*sizeof(cpx_t));
|
||||||
|
memset(pObj->pFifo, 0, pObj->L*sizeof(cpx_t));
|
||||||
|
|
||||||
|
pObj->pX = (cpx_t*)malloc(pObj->L*sizeof(cpx_t));
|
||||||
|
memset(pObj->pX, 0, pObj->L*sizeof(cpx_t));
|
||||||
|
|
||||||
|
pObj->M = M;
|
||||||
|
pObj->N = N;
|
||||||
|
|
||||||
|
free(pCoeff);
|
||||||
|
|
||||||
|
return k/M;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PolyPhaseCpxIpFree(ppip_cpx_t *pObj)
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
|
for(i=0; i < pObj->M; i++)
|
||||||
|
{
|
||||||
|
free(pObj->ppCoeff[i]);
|
||||||
|
}
|
||||||
|
free(pObj->ppCoeff);
|
||||||
|
pObj->ppCoeff = NULL;
|
||||||
|
|
||||||
|
free(pObj->pFifo);
|
||||||
|
pObj->pFifo = NULL;
|
||||||
|
|
||||||
|
free(pObj->pX);
|
||||||
|
pObj->pX = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PolyPhaseCpxIpFeed(ppip_cpx_t *pObj, uint32_t push, cpx_t x)
|
||||||
|
{
|
||||||
|
pObj->w = (pObj->w + push) % pObj->L;
|
||||||
|
pObj->pFifo[pObj->w] = x;
|
||||||
|
}
|
||||||
|
|
||||||
|
cpx_t PolyPhaseCpxIpInterpolate(ppip_cpx_t *pObj, int32_t pop, radio_float_t mu)
|
||||||
|
{
|
||||||
|
uint32_t index, r;
|
||||||
|
int32_t j;
|
||||||
|
cpx_t y;
|
||||||
|
|
||||||
|
index = (uint32_t)dmod(dmax(0, mu*pObj->M), (radio_float_t)pObj->M);
|
||||||
|
|
||||||
|
pObj->r = (pObj->r + pop) % pObj->L;
|
||||||
|
|
||||||
|
if (pop)
|
||||||
|
{
|
||||||
|
r = pObj->r;
|
||||||
|
j = pObj->N-1;
|
||||||
|
while(r < pObj->L)
|
||||||
|
{
|
||||||
|
pObj->pX[j--] = pObj->pFifo[r++];
|
||||||
|
}
|
||||||
|
r = 0;
|
||||||
|
while(j >= 0)
|
||||||
|
{
|
||||||
|
pObj->pX[j--] = pObj->pFifo[r++];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
y = CpxMulRealAdd(Cpx(0,0), pObj->pX, pObj->ppCoeff[index], pObj->N);
|
||||||
|
/*
|
||||||
|
pObj->r = (pObj->r + pop) % pObj->L;
|
||||||
|
r = pObj->r;
|
||||||
|
|
||||||
|
y = Cpx(0,0);
|
||||||
|
for (j=0; j < pObj->N; j++)
|
||||||
|
{
|
||||||
|
y.real += pObj->pFifo[r].real * pW[j];
|
||||||
|
y.imag += pObj->pFifo[r].imag * pW[j];
|
||||||
|
|
||||||
|
r = (r + pObj->L-1) % pObj->L;
|
||||||
|
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
// Complex FIR-based polyphase interpolation filter (Farrow structure)
|
||||||
|
// From:
|
||||||
|
// "PERFORMANCE AND DESIGN OF FARROW FILTER USED FOR ARBITRARY RESAMPLING"
|
||||||
|
// [unknown date], Fred Harris, Signal Processing ChairCommunication Systems and Signal Processing Institute
|
||||||
|
// College of Engineering, San Diego State University, San Diego, CA 92182-0190 USA
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
void FarrowPPIPCpxInit(ppip_farrow_cpx_t *pObj, uint32_t M, uint32_t N)
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
|
pObj->ppCoeff = (fir_float_t**)malloc(M*sizeof(fir_float_t*));
|
||||||
|
for(i=0; i < M; i++)
|
||||||
|
{
|
||||||
|
pObj->ppCoeff[i] = (fir_float_t*)malloc(N*sizeof(fir_float_t));
|
||||||
|
memset(pObj->ppCoeff[i], 0, N*sizeof(fir_float_t));
|
||||||
|
}
|
||||||
|
pObj->M = M;
|
||||||
|
pObj->N = N;
|
||||||
|
|
||||||
|
pObj->pH = (cpx_t*)malloc(M*sizeof(cpx_t));
|
||||||
|
memset(pObj->pH, 0, M*sizeof(cpx_t));
|
||||||
|
|
||||||
|
pObj->pB = (cpx_t*)malloc(M*sizeof(cpx_t));
|
||||||
|
memset(pObj->pB, 0, M*sizeof(cpx_t));
|
||||||
|
|
||||||
|
pObj->L = N; // Influences STR-Loop delay
|
||||||
|
pObj->w = 0;
|
||||||
|
pObj->r = 0;
|
||||||
|
|
||||||
|
pObj->pFifo = (cpx_t*)malloc(pObj->L*sizeof(cpx_t));
|
||||||
|
memset(pObj->pFifo, 0, pObj->L*sizeof(cpx_t));
|
||||||
|
|
||||||
|
pObj->pX = (cpx_t*)malloc(pObj->L*sizeof(cpx_t));
|
||||||
|
memset(pObj->pX, 0, pObj->L*sizeof(cpx_t));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void FarrowPPIPCpxFree(ppip_farrow_cpx_t *pObj)
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
|
for(i=0; i < pObj->M; i++)
|
||||||
|
{
|
||||||
|
free(pObj->ppCoeff[i]);
|
||||||
|
}
|
||||||
|
free(pObj->ppCoeff);
|
||||||
|
pObj->ppCoeff = NULL;
|
||||||
|
|
||||||
|
free(pObj->pH);
|
||||||
|
pObj->pH = NULL;
|
||||||
|
|
||||||
|
free(pObj->pB);
|
||||||
|
pObj->pB = NULL;
|
||||||
|
|
||||||
|
free(pObj->pFifo);
|
||||||
|
pObj->pFifo = NULL;
|
||||||
|
|
||||||
|
free(pObj->pX);
|
||||||
|
pObj->pX = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
cpx_t horner(cpx_t *a, cpx_t *b, uint32_t M, radio_float_t mu)
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
|
b[0] = a[0];
|
||||||
|
for (i=1; i < M; i++)
|
||||||
|
{
|
||||||
|
b[i].real = a[i].real+mu*b[i-1].real;
|
||||||
|
b[i].imag = a[i].imag+mu*b[i-1].imag;
|
||||||
|
}
|
||||||
|
return b[M-1];
|
||||||
|
}
|
||||||
|
|
||||||
|
void FarrowPPIPCpxFeed(ppip_farrow_cpx_t *pObj, uint32_t push, cpx_t x)
|
||||||
|
{
|
||||||
|
pObj->w = (pObj->w + push) % pObj->L;
|
||||||
|
pObj->pFifo[pObj->w] = x;
|
||||||
|
}
|
||||||
|
|
||||||
|
cpx_t FarrowPPIPCpxInterpolate(ppip_farrow_cpx_t *pObj, uint32_t pop, radio_float_t mu)
|
||||||
|
{
|
||||||
|
uint32_t i, r;
|
||||||
|
int32_t j;
|
||||||
|
|
||||||
|
pObj->r = (pObj->r + pop) % pObj->L;
|
||||||
|
|
||||||
|
if (pop)
|
||||||
|
{
|
||||||
|
r = pObj->r;
|
||||||
|
j = pObj->N-1;
|
||||||
|
while(r < pObj->L)
|
||||||
|
{
|
||||||
|
pObj->pX[j--] = pObj->pFifo[r++];
|
||||||
|
}
|
||||||
|
r = 0;
|
||||||
|
while(j >= 0)
|
||||||
|
{
|
||||||
|
pObj->pX[j--] = pObj->pFifo[r++];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Partial filter responses
|
||||||
|
for (i=0; i < pObj->M; i++)
|
||||||
|
{
|
||||||
|
pObj->pH[i] = CpxMulRealAdd(Cpx(0,0), pObj->pX, pObj->ppCoeff[i], pObj->N);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Combine
|
||||||
|
return horner(pObj->pH, pObj->pB, pObj->M, mu);
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
// Real First-order interpolation filter
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
void FDly_Init(fdly_t *pObj, int32_t order)
|
||||||
|
{
|
||||||
|
pObj->Nf = order + 1;
|
||||||
|
|
||||||
|
pObj->hf = (radio_float_t*)malloc(pObj->Nf*sizeof(radio_float_t));
|
||||||
|
pObj->statef = (radio_float_t*)malloc(pObj->Nf*sizeof(radio_float_t));
|
||||||
|
memset(pObj->hf, 0, pObj->Nf*sizeof(radio_float_t));
|
||||||
|
memset(pObj->statef, 0, pObj->Nf*sizeof(radio_float_t));
|
||||||
|
}
|
||||||
|
|
||||||
|
void FDly_Free(fdly_t *pObj)
|
||||||
|
{
|
||||||
|
if (pObj->hf)
|
||||||
|
free(pObj->hf);
|
||||||
|
|
||||||
|
pObj->hf = NULL;
|
||||||
|
|
||||||
|
if (pObj->statef)
|
||||||
|
free(pObj->statef);
|
||||||
|
|
||||||
|
pObj->statef = NULL;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
radio_float_t FDly_Process(fdly_t *pObj, radio_float_t x)
|
||||||
|
{
|
||||||
|
radio_float_t y;
|
||||||
|
|
||||||
|
FIR(pObj->hf, pObj->statef, pObj->Nf, &x, &y, 1);
|
||||||
|
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FDly_CalcCoeff(fdly_t *pObj, radio_float_t delay)
|
||||||
|
{
|
||||||
|
int32_t n, k;
|
||||||
|
radio_float_t hn;
|
||||||
|
|
||||||
|
for (n=0; n < pObj->Nf; n++)
|
||||||
|
{
|
||||||
|
hn = 1.0;
|
||||||
|
for (k=0; k < pObj->Nf; k++)
|
||||||
|
{
|
||||||
|
if (k == n)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
hn *= ((delay - (radio_float_t)k) / (radio_float_t)(n-k));
|
||||||
|
}
|
||||||
|
pObj->hf[n] = hn;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
// Real Polynomial-based Lagrange interpolation filter
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
void LGIpInit(lgip_t *pObj, int32_t order, int32_t bufsize)
|
||||||
|
{
|
||||||
|
pObj->N = order + 1;
|
||||||
|
pObj->bufsize = bufsize;
|
||||||
|
RBufInit(&pObj->rbuf, bufsize);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LGIpFree(lgip_t *pObj)
|
||||||
|
{
|
||||||
|
RBufFree(&pObj->rbuf);
|
||||||
|
pObj->N = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
radio_float_t LGIpProcess(lgip_t *pObj, radio_float_t x, int32_t m, radio_float_t mu)
|
||||||
|
{
|
||||||
|
int32_t n, k;
|
||||||
|
radio_float_t hn, y, delay;
|
||||||
|
|
||||||
|
RBufPut(&pObj->rbuf, x);
|
||||||
|
y = 0;
|
||||||
|
delay = 1-mu;
|
||||||
|
for (n=0; n < pObj->N; n++)
|
||||||
|
{
|
||||||
|
hn = 1.0;
|
||||||
|
for (k=0; k < pObj->N; k++)
|
||||||
|
{
|
||||||
|
if (k == n)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
hn *= ((delay - (radio_float_t)k) / (radio_float_t)(n-k));
|
||||||
|
}
|
||||||
|
y += hn*RBufGetAt(&pObj->rbuf, pObj->bufsize/2 + m-n);
|
||||||
|
}
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
// Complex Polynomial-based Lagrange interpolation filter
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
void LGCpxIpInit(lgip_cpx_t *pObj, int32_t order)
|
||||||
|
{
|
||||||
|
// FIFO
|
||||||
|
pObj->N = order + 1;
|
||||||
|
pObj->w = 0;
|
||||||
|
pObj->r = 0;
|
||||||
|
pObj->L = 64*pObj->N; // Influences STR-Loop delay
|
||||||
|
|
||||||
|
pObj->pFifo = (cpx_t*)malloc(pObj->L*sizeof(cpx_t));
|
||||||
|
memset(pObj->pFifo, 0, pObj->L*sizeof(cpx_t));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void LGCpxIpFree(lgip_cpx_t *pObj)
|
||||||
|
{
|
||||||
|
free(pObj->pFifo);
|
||||||
|
pObj->pFifo = NULL;
|
||||||
|
pObj->N = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
cpx_t LGCpxIpProcess(lgip_cpx_t *pObj, cpx_t x, int32_t m, radio_float_t mu)
|
||||||
|
{
|
||||||
|
uint32_t i, j, k, N, L, r;
|
||||||
|
radio_float_t h;
|
||||||
|
cpx_t y;
|
||||||
|
|
||||||
|
L = pObj->L;
|
||||||
|
N = pObj->N;
|
||||||
|
|
||||||
|
pObj->pFifo[pObj->w++] = x;
|
||||||
|
if (pObj->w == L)
|
||||||
|
pObj->w = 0;
|
||||||
|
|
||||||
|
r = (m-N) % L;
|
||||||
|
|
||||||
|
k = 0;
|
||||||
|
|
||||||
|
y.real = 0.0;
|
||||||
|
y.imag = 0.0;
|
||||||
|
for (i=0; i < pObj->N; i++)
|
||||||
|
{
|
||||||
|
h = 1.0;
|
||||||
|
for (j=0; j < pObj->N; j++)
|
||||||
|
{
|
||||||
|
if (i == j)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
h *= (((radio_float_t)pObj->N/2 + mu - (radio_float_t)j - (radio_float_t)0.5) / (radio_float_t)(i-j));
|
||||||
|
}
|
||||||
|
y.real += pObj->pFifo[r].real * h;
|
||||||
|
y.imag += pObj->pFifo[r].imag * h;
|
||||||
|
r = (r+1) % L;
|
||||||
|
}
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
// Real FIR-based polyphase interpolation SRRC (Square Root Raised Cosine) matched filter #1
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
radio_float_t PolyPhaseSRRCInit(fir_pp_t *pObj, radio_float_t fa, radio_float_t tsym, radio_float_t alpha, uint32_t N, uint32_t M)
|
||||||
|
{
|
||||||
|
uint32_t i, j;
|
||||||
|
fir_float_t *pCoeff;
|
||||||
|
radio_float_t k;
|
||||||
|
|
||||||
|
pCoeff = (fir_float_t*)malloc((N+1)*M*sizeof(fir_float_t));
|
||||||
|
memset(pCoeff, 0, M*(N+1)*sizeof(fir_float_t));
|
||||||
|
|
||||||
|
k = CalcFirSRRC(pCoeff, M*fa, tsym, alpha, M*N);
|
||||||
|
|
||||||
|
pObj->ppCoeff = (fir_float_t**)malloc(M*sizeof(fir_float_t*));
|
||||||
|
for(i=0; i < M; i++)
|
||||||
|
{
|
||||||
|
pObj->ppCoeff[i] = (fir_float_t*)malloc(N*sizeof(fir_float_t));
|
||||||
|
memset(pObj->ppCoeff[i], 0, N*sizeof(fir_float_t));
|
||||||
|
}
|
||||||
|
pObj->pState = (fir_float_t*)malloc(N*sizeof(fir_float_t));
|
||||||
|
memset(pObj->pState, 0, N*sizeof(fir_float_t));
|
||||||
|
|
||||||
|
for(i=0; i < M; i++)
|
||||||
|
{
|
||||||
|
for(j=0; j < N; j++)
|
||||||
|
{
|
||||||
|
pObj->ppCoeff[i][j] = M*pCoeff[M*j+M/2+i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pObj->M = M;
|
||||||
|
pObj->N = N;
|
||||||
|
|
||||||
|
free(pCoeff);
|
||||||
|
|
||||||
|
return k/M;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void PolyPhaseSRRCFree(fir_pp_t *pObj)
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
|
for(i=0; i < pObj->M; i++)
|
||||||
|
{
|
||||||
|
free(pObj->ppCoeff[i]);
|
||||||
|
}
|
||||||
|
free(pObj->ppCoeff);
|
||||||
|
pObj->ppCoeff = NULL;
|
||||||
|
|
||||||
|
free(pObj->pState);
|
||||||
|
pObj->pState = NULL;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t PolyPhaseSRRCProcess(fir_pp_t *pObj, radio_float_t mu, radio_float_t *pX, radio_float_t *pY, uint32_t len)
|
||||||
|
{
|
||||||
|
uint32_t m;
|
||||||
|
|
||||||
|
// m = (pObj->M/2 + (int32_t)(mu * pObj->M/2)) % pObj->M;
|
||||||
|
m = (int32_t)dmod(mu*pObj->M, (radio_float_t)pObj->M);
|
||||||
|
|
||||||
|
FIR(pObj->ppCoeff[m], pObj->pState, pObj->N, pX, pY, len);
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
// Real FIR-based polyphase interpolation SRRC (Square Root Raised Cosine) matched filter #2
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
radio_float_t PolyPhaseIpInit(ppip_t *pObj, radio_float_t fa, radio_float_t tsym, radio_float_t alpha, uint32_t N, uint32_t M)
|
||||||
|
{
|
||||||
|
uint32_t i, j;
|
||||||
|
fir_float_t *pCoeff;
|
||||||
|
radio_float_t k;
|
||||||
|
|
||||||
|
pCoeff = (fir_float_t*)malloc((N+1)*M*sizeof(fir_float_t));
|
||||||
|
memset(pCoeff, 0, (N+1)*M*sizeof(fir_float_t));
|
||||||
|
|
||||||
|
k = CalcFirSRRC(pCoeff, M*fa, tsym, alpha, N*M);
|
||||||
|
|
||||||
|
pObj->ppCoeff = (fir_float_t**)malloc(M*sizeof(fir_float_t*));
|
||||||
|
for(i=0; i < M; i++)
|
||||||
|
{
|
||||||
|
pObj->ppCoeff[i] = (fir_float_t*)malloc(N*sizeof(fir_float_t));
|
||||||
|
memset(pObj->ppCoeff[i], 0, N*sizeof(fir_float_t));
|
||||||
|
}
|
||||||
|
for(i=0; i < M; i++)
|
||||||
|
{
|
||||||
|
for(j=0; j < N; j++)
|
||||||
|
{
|
||||||
|
pObj->ppCoeff[i][j] = M*pCoeff[M*j+M/2+i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pObj->pState = (fir_float_t*)malloc(N*sizeof(fir_float_t));
|
||||||
|
memset(pObj->pState, 0, N*sizeof(fir_float_t));
|
||||||
|
|
||||||
|
pObj->M = M;
|
||||||
|
pObj->N = N;
|
||||||
|
|
||||||
|
RBufInit(&pObj->rbuf, 2*N); // Influences STR-Loop delay
|
||||||
|
|
||||||
|
free(pCoeff);
|
||||||
|
|
||||||
|
return k/M;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void PolyPhaseIpFree(ppip_t *pObj)
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
|
for(i=0; i < pObj->M; i++)
|
||||||
|
{
|
||||||
|
free(pObj->ppCoeff[i]);
|
||||||
|
}
|
||||||
|
free(pObj->ppCoeff);
|
||||||
|
pObj->ppCoeff = NULL;
|
||||||
|
|
||||||
|
free(pObj->pState);
|
||||||
|
pObj->pState = NULL;
|
||||||
|
|
||||||
|
RBufFree(&pObj->rbuf);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
radio_float_t PolyPhaseIpProcess(ppip_t *pObj, radio_float_t x, int32_t m, radio_float_t mu)
|
||||||
|
{
|
||||||
|
uint32_t index, i;
|
||||||
|
radio_float_t y;
|
||||||
|
|
||||||
|
index = (int32_t)dmod(mu*pObj->M, (radio_float_t)pObj->M);
|
||||||
|
|
||||||
|
for(i=0; i < pObj->N; i++)
|
||||||
|
{
|
||||||
|
pObj->pState[i] = RBufGetAt(&pObj->rbuf, m-i);
|
||||||
|
}
|
||||||
|
|
||||||
|
FIR(pObj->ppCoeff[index], pObj->pState, pObj->N, &x, &y, 1);
|
||||||
|
RBufPut(&pObj->rbuf, x);
|
||||||
|
|
||||||
|
return y;
|
||||||
|
}
|
||||||
Executable
+158
@@ -0,0 +1,158 @@
|
|||||||
|
// --------------------------------------------------------------
|
||||||
|
#ifndef INTERPOLATION_H
|
||||||
|
#define INTERPOLATION_H
|
||||||
|
|
||||||
|
#include "radio_types.h"
|
||||||
|
#include "real.h"
|
||||||
|
#include "cpx.h"
|
||||||
|
#include <fir/fir2.h>
|
||||||
|
#include "ringbuf.h"
|
||||||
|
#include "synchronization.h"
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
#define CEF_MODE_NOP 0
|
||||||
|
#define CEF_MODE_CMA 1
|
||||||
|
#define CEF_MODE_DD 2
|
||||||
|
#define CEF_MODE_EQ_UPD 3
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
// Types
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
typedef struct _fir_cpx_t
|
||||||
|
{
|
||||||
|
uint32_t N, r, w;
|
||||||
|
cpx_t *pX;
|
||||||
|
uint32_t M_up, M_down;
|
||||||
|
clock_t clockUp;
|
||||||
|
clock_t clockDown;
|
||||||
|
} fir_cpx_t;
|
||||||
|
|
||||||
|
typedef struct _fir_cpx_multirate_stage_t
|
||||||
|
{
|
||||||
|
uint32_t N;
|
||||||
|
uint32_t k;
|
||||||
|
uint32_t K;
|
||||||
|
cpx_t *pX;
|
||||||
|
radio_float_t *pW;
|
||||||
|
|
||||||
|
} fir_cpx_multirate_stage_t;
|
||||||
|
|
||||||
|
typedef struct _fir_cpx_multirate_t
|
||||||
|
{
|
||||||
|
uint32_t N;
|
||||||
|
uint32_t L;
|
||||||
|
uint32_t M;
|
||||||
|
fir_cpx_multirate_stage_t *pStageUp;
|
||||||
|
fir_cpx_multirate_stage_t *pStageDown;
|
||||||
|
cpx_t res;
|
||||||
|
uint32_t k;
|
||||||
|
|
||||||
|
} fir_cpx_multirate_t;
|
||||||
|
|
||||||
|
typedef struct _fdly_t
|
||||||
|
{
|
||||||
|
int32_t Nf;
|
||||||
|
radio_float_t *hf, *statef;
|
||||||
|
} fdly_t;
|
||||||
|
|
||||||
|
typedef struct _lgip_t
|
||||||
|
{
|
||||||
|
int32_t N, bufsize;
|
||||||
|
rbuf_t rbuf;
|
||||||
|
} lgip_t;
|
||||||
|
|
||||||
|
typedef struct _lgip_cpx_t
|
||||||
|
{
|
||||||
|
cpx_t *pFifo;
|
||||||
|
uint32_t N, L, w, r;
|
||||||
|
|
||||||
|
} lgip_cpx_t;
|
||||||
|
|
||||||
|
typedef struct _fir_pp_t
|
||||||
|
{
|
||||||
|
uint32_t N, M;
|
||||||
|
radio_float_t **ppCoeff, *pState;
|
||||||
|
|
||||||
|
} fir_pp_t;
|
||||||
|
|
||||||
|
typedef struct _ppip_t
|
||||||
|
{
|
||||||
|
radio_float_t **ppCoeff, *pState;
|
||||||
|
uint32_t N, M;
|
||||||
|
rbuf_t rbuf;
|
||||||
|
|
||||||
|
} ppip_t;
|
||||||
|
|
||||||
|
typedef struct _ppip_cpx_t
|
||||||
|
{
|
||||||
|
cpx_t *pFifo;
|
||||||
|
radio_float_t **ppCoeff;
|
||||||
|
uint32_t N, L, M, w, r;
|
||||||
|
cpx_t *pX;
|
||||||
|
|
||||||
|
} ppip_cpx_t;
|
||||||
|
|
||||||
|
typedef struct _ppip_farrow_cpx_t
|
||||||
|
{
|
||||||
|
cpx_t *pFifo, *pH, *pB;
|
||||||
|
radio_float_t **ppCoeff;
|
||||||
|
uint32_t N, L, M, w, r;
|
||||||
|
cpx_t *pX;
|
||||||
|
|
||||||
|
} ppip_farrow_cpx_t;
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
// Functions
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void FDly_Init(fdly_t *pObj, int32_t order);
|
||||||
|
void FDly_Free(fdly_t *pObj);
|
||||||
|
void FDly_CalcCoeff(fdly_t *pObj, radio_float_t delay);
|
||||||
|
radio_float_t FDly_Process(fdly_t *pObj, radio_float_t x);
|
||||||
|
|
||||||
|
void LGIpInit(lgip_t *pObj, int32_t order, int32_t bufsize);
|
||||||
|
void LGIpFree(lgip_t *pObj);
|
||||||
|
radio_float_t LGIpProcess(lgip_t *pObj, radio_float_t x, int32_t m, radio_float_t mu);
|
||||||
|
|
||||||
|
void LGCpxIpInit(lgip_cpx_t *pObj, int32_t order);
|
||||||
|
void LGCpxIpFree(lgip_cpx_t *pObj);
|
||||||
|
cpx_t LGCpxIpProcess(lgip_cpx_t *pObj, cpx_t x, int32_t m, radio_float_t mu);
|
||||||
|
|
||||||
|
radio_float_t PolyPhaseSRRCInit(fir_pp_t *pObj, radio_float_t fa, radio_float_t tsym, radio_float_t alpha, uint32_t N, uint32_t M);
|
||||||
|
void PolyPhaseSRRCFree(fir_pp_t *pObj);
|
||||||
|
uint32_t PolyPhaseSRRCProcess(fir_pp_t *pObj, radio_float_t mu, radio_float_t *pX, radio_float_t *pY, uint32_t len);
|
||||||
|
|
||||||
|
radio_float_t PolyPhaseIpInit(ppip_t *pObj, radio_float_t fa, radio_float_t tsym, radio_float_t alpha, uint32_t N, uint32_t M);
|
||||||
|
void PolyPhaseIpFree(ppip_t *pObj);
|
||||||
|
radio_float_t PolyPhaseIpProcess(ppip_t *pObj, radio_float_t x, int32_t m, radio_float_t mu);
|
||||||
|
|
||||||
|
radio_float_t PolyPhaseCpxIpInit(ppip_cpx_t *pObj, radio_float_t fa, radio_float_t tsym, radio_float_t alpha, uint32_t N, uint32_t M);
|
||||||
|
void PolyPhaseCpxIpFree(ppip_cpx_t *pObj);
|
||||||
|
void PolyPhaseCpxIpFeed(ppip_cpx_t *pObj, uint32_t push, cpx_t x);
|
||||||
|
cpx_t PolyPhaseCpxIpInterpolate(ppip_cpx_t *pObj, int32_t pop, radio_float_t mu);
|
||||||
|
|
||||||
|
void FarrowPPIPCpxInit(ppip_farrow_cpx_t *pObj, uint32_t M, uint32_t N);
|
||||||
|
void FarrowPPIPCpxFree(ppip_farrow_cpx_t *pObj);
|
||||||
|
void FarrowPPIPCpxFeed(ppip_farrow_cpx_t *pObj, uint32_t push, cpx_t x);
|
||||||
|
cpx_t FarrowPPIPCpxInterpolate(ppip_farrow_cpx_t *pObj, uint32_t pop, radio_float_t mu);
|
||||||
|
|
||||||
|
void FirCpxInit(fir_cpx_t *pObj, uint32_t N, uint32_t M_up, uint32_t M_down);
|
||||||
|
void FirCpxFree(fir_cpx_t *pObj);
|
||||||
|
uint32_t FirCpxProcessReal(fir_cpx_t *pObj, radio_float_t *pW, cpx_t *pSrc, cpx_t *pDst, uint32_t len);
|
||||||
|
|
||||||
|
void FirCpxMultirateDownInit(fir_cpx_multirate_t *pObj, radio_float_t *pW, uint32_t N, uint32_t M);
|
||||||
|
void FirCpxMultirateUpInit(fir_cpx_multirate_t *pObj, radio_float_t *pW, uint32_t N, uint32_t L);
|
||||||
|
void FirCpxMultirateUpReinit(fir_cpx_multirate_t *pObj, radio_float_t *pW, uint32_t N, uint32_t L);
|
||||||
|
void FirCpxMultirateFree(fir_cpx_multirate_t *pObj);
|
||||||
|
uint32_t FirCpxDownProcess(fir_cpx_multirate_t *pObj, cpx_t *pSrc, cpx_t *pDst, uint32_t len);
|
||||||
|
uint32_t FirCpxUpProcess(fir_cpx_multirate_t *pObj, cpx_t *pSrc, cpx_t *pDst, uint32_t len);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
#endif // INTERPOLATION_H
|
||||||
@@ -0,0 +1,118 @@
|
|||||||
|
// --------------------------------------------------------------
|
||||||
|
#include <string.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include "nco.h"
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
// NCO
|
||||||
|
// Scalar version
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
void NCO_Init(nco_t *pObj, radio_float_t omega, radio_float_t phi)
|
||||||
|
{
|
||||||
|
pObj->omega = omega;
|
||||||
|
pObj->phi = phi;
|
||||||
|
memset(&pObj->state,0,sizeof(cpx_t));
|
||||||
|
}
|
||||||
|
|
||||||
|
void NCO_Free(nco_t *pObj)
|
||||||
|
{
|
||||||
|
(void)pObj;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NCO_Reinit(nco_t *pObj, radio_float_t omega, radio_float_t phi)
|
||||||
|
{
|
||||||
|
NCO_Free(pObj);
|
||||||
|
NCO_Init(pObj, omega, phi);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NCO_SetOmega(nco_t *pObj, radio_float_t omega)
|
||||||
|
{
|
||||||
|
pObj->omega = omega;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NCO_SetPhi(nco_t *pObj, radio_float_t phi)
|
||||||
|
{
|
||||||
|
pObj->phi = phi;
|
||||||
|
}
|
||||||
|
|
||||||
|
radio_float_t NCO_GetOmega(nco_t *pObj)
|
||||||
|
{
|
||||||
|
return pObj->omega;
|
||||||
|
}
|
||||||
|
|
||||||
|
radio_float_t NCO_GetPhi(nco_t *pObj)
|
||||||
|
{
|
||||||
|
return pObj->phi;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NCO_Process(nco_t *pObj, radio_float_t dOmega, radio_float_t dPhi)
|
||||||
|
{
|
||||||
|
pObj->phi += (pObj->omega + dOmega);
|
||||||
|
|
||||||
|
if (pObj->phi < -(radio_float_t)0.5)
|
||||||
|
pObj->phi += (radio_float_t)1.0;
|
||||||
|
|
||||||
|
if (pObj->phi >= +(radio_float_t)0.5)
|
||||||
|
pObj->phi -= (radio_float_t)1.0;
|
||||||
|
|
||||||
|
pObj->state.real = +(radio_float_t)cos(2.0*PI*pObj->phi + dPhi);
|
||||||
|
pObj->state.imag = -(radio_float_t)sin(2.0*PI*pObj->phi + dPhi);
|
||||||
|
}
|
||||||
|
|
||||||
|
cpx_t NCO_MixRealComplexS(nco_t *pObj, radio_float_t src, radio_float_t gain)
|
||||||
|
{
|
||||||
|
cpx_t dst;
|
||||||
|
|
||||||
|
dst.real = gain*src;
|
||||||
|
dst.imag = 0;
|
||||||
|
|
||||||
|
return CpxMulS(pObj->state, dst);
|
||||||
|
}
|
||||||
|
|
||||||
|
radio_float_t NCO_MixComplexRealS(nco_t *pObj, cpx_t src, cpx_t gain)
|
||||||
|
{
|
||||||
|
return gain.real*pObj->state.real*src.real + gain.imag*pObj->state.imag*src.imag;
|
||||||
|
}
|
||||||
|
|
||||||
|
cpx_t NCO_MixComplexS(nco_t *pObj, cpx_t src, cpx_t gain)
|
||||||
|
{
|
||||||
|
return CpxMulS(pObj->state, CpxScaleComplexS(src, gain));
|
||||||
|
}
|
||||||
|
|
||||||
|
void NCO_MixRealComplexV(nco_t *pObj, cpx_t *pDst, radio_float_t *pSrc, radio_float_t gain, uint32_t len)
|
||||||
|
{
|
||||||
|
|
||||||
|
while (len--)
|
||||||
|
{
|
||||||
|
|
||||||
|
*(pDst++) = NCO_MixRealComplexS(pObj, *(pSrc++), gain);
|
||||||
|
|
||||||
|
// NCO update
|
||||||
|
NCO_Process(pObj, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NCO_MixComplexRealV(nco_t *pObj, radio_float_t *pDst, cpx_t *pSrc, cpx_t gain, uint32_t len)
|
||||||
|
{
|
||||||
|
while (len--)
|
||||||
|
{
|
||||||
|
|
||||||
|
*(pDst++) = NCO_MixComplexRealS(pObj, *(pSrc++), gain);
|
||||||
|
|
||||||
|
// NCO update
|
||||||
|
NCO_Process(pObj, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NCO_MixComplexV(nco_t *pObj, cpx_t *pSrcDst, cpx_t gain, uint32_t len)
|
||||||
|
{
|
||||||
|
while (len--)
|
||||||
|
{
|
||||||
|
*(pSrcDst++) = NCO_MixComplexS(pObj, *(pSrcDst++), gain);
|
||||||
|
|
||||||
|
// NCO update
|
||||||
|
NCO_Process(pObj, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
// --------------------------------------------------------------
|
||||||
|
#ifndef NCO_H
|
||||||
|
#define NCO_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "radio_types.h"
|
||||||
|
#include "real.h"
|
||||||
|
#include "cpx.h"
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
// Types
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
typedef struct _nco_t
|
||||||
|
{
|
||||||
|
radio_float_t phi, omega;
|
||||||
|
cpx_t state;
|
||||||
|
} nco_t;
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
// NCO
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
// Scalar version
|
||||||
|
void NCO_Init(nco_t *pObj, radio_float_t omega, radio_float_t phi);
|
||||||
|
void NCO_Free(nco_t *pObj);
|
||||||
|
void NCO_Reinit(nco_t *pObj, radio_float_t omega, radio_float_t phi);
|
||||||
|
void NCO_SetOmega(nco_t *pObj, radio_float_t omega);
|
||||||
|
void NCO_SetPhi(nco_t *pObj, radio_float_t phi);
|
||||||
|
radio_float_t NCO_GetOmega(nco_t *pObj);
|
||||||
|
radio_float_t NCO_GetPhi(nco_t *pObj);
|
||||||
|
void NCO_Process(nco_t *pObj, radio_float_t dOmega, radio_float_t dPhi);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
// Mixer
|
||||||
|
// Scalar version
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
cpx_t NCO_MixRealComplexS(nco_t *pObj, radio_float_t src, radio_float_t gain);
|
||||||
|
cpx_t NCO_MixComplexS(nco_t *pObj, cpx_t src, cpx_t gain);
|
||||||
|
radio_float_t NCO_MixComplexRealS(nco_t *pObj, cpx_t src, cpx_t gain);
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
// Mixer
|
||||||
|
// Vector version
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
void NCO_MixRealComplexV(nco_t *pObj, cpx_t *pDst, radio_float_t *pSrc, radio_float_t gain, uint32_t len);
|
||||||
|
void NCO_MixComplexV(nco_t *pObj, cpx_t *pSrcDst, cpx_t gain, uint32_t len);
|
||||||
|
void NCO_MixComplexRealV(nco_t *pObj, radio_float_t *pDst, cpx_t *pSrc, cpx_t gain, uint32_t len);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif // __cplusplus
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
#endif // NCO_H
|
||||||
@@ -0,0 +1,530 @@
|
|||||||
|
// --------------------------------------------------------------
|
||||||
|
#ifndef RADIO_H
|
||||||
|
#define RADIO_H
|
||||||
|
|
||||||
|
#include "radio_types.h"
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
// RF Types
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
#define FRAME_CRC16_IV 0x0000
|
||||||
|
#define FRAME_CRC16_POLY 0x1021
|
||||||
|
#define FRAME_PREAMBLE_IV 0x55
|
||||||
|
#define FRAME_SCRAMBLER_SEED 0x12345678
|
||||||
|
#define FRAME_SCRAMBLER_POLY 0x80C18601
|
||||||
|
#define FRAME_NUM_BYTES_PER_FRAME 32
|
||||||
|
#define FRAME_TYPE_IDLE 0x01
|
||||||
|
#define FRAME_TYPE_DATA 0x02
|
||||||
|
|
||||||
|
typedef struct _cpx_t
|
||||||
|
{
|
||||||
|
radio_float_t imag, real;
|
||||||
|
|
||||||
|
} cpx_t;
|
||||||
|
|
||||||
|
typedef struct _cpx_arr_t
|
||||||
|
{
|
||||||
|
radio_float_t *pImag, *pReal;
|
||||||
|
|
||||||
|
} cpx_arr_t;
|
||||||
|
|
||||||
|
typedef struct _nco_t
|
||||||
|
{
|
||||||
|
radio_float_t phi, omega, dPhi, dOmega;
|
||||||
|
cpx_t state;
|
||||||
|
uint32_t tbl_index, tbl_size;
|
||||||
|
cpx_t *pTbl;
|
||||||
|
} nco_t;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
typedef struct _clkgen_t
|
||||||
|
{
|
||||||
|
nco_t *pNCO;
|
||||||
|
radio_float_t lastPhi;
|
||||||
|
|
||||||
|
} clkgen_t;
|
||||||
|
|
||||||
|
typedef struct _sampler_t
|
||||||
|
{
|
||||||
|
int count, reload;
|
||||||
|
|
||||||
|
} sampler_t;
|
||||||
|
|
||||||
|
typedef struct _lead_lag_filter_t
|
||||||
|
{
|
||||||
|
radio_float_t gain_lead, gain_lag;
|
||||||
|
radio_float_t term_lead, term_lag;
|
||||||
|
|
||||||
|
} lead_lag_filter_t;
|
||||||
|
|
||||||
|
typedef struct _str_t
|
||||||
|
{
|
||||||
|
cpx_t d[2];
|
||||||
|
|
||||||
|
} str_t;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct _rbuf_t
|
||||||
|
{
|
||||||
|
int size, iw, ir, dist;
|
||||||
|
radio_float_t *pData;
|
||||||
|
|
||||||
|
} rbuf_t;
|
||||||
|
|
||||||
|
typedef struct _fifo_t
|
||||||
|
{
|
||||||
|
uint32_t size_max;
|
||||||
|
uint32_t size;
|
||||||
|
uint32_t ir;
|
||||||
|
uint32_t iw;
|
||||||
|
uint32_t *pData;
|
||||||
|
|
||||||
|
} fifo_t;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct _sl_mean_t
|
||||||
|
{
|
||||||
|
rbuf_t buf;
|
||||||
|
uint32_t normalize_count;
|
||||||
|
radio_float_t Nr;
|
||||||
|
radio_float_t sum;
|
||||||
|
radio_float_t element_max;
|
||||||
|
radio_float_t mean;
|
||||||
|
|
||||||
|
} sl_mean_t;
|
||||||
|
|
||||||
|
typedef struct _sl_var_t
|
||||||
|
{
|
||||||
|
sl_mean_t sl_mean;
|
||||||
|
rbuf_t buf;
|
||||||
|
uint32_t normalize_count;
|
||||||
|
radio_float_t Nr;
|
||||||
|
radio_float_t sum;
|
||||||
|
radio_float_t var;
|
||||||
|
|
||||||
|
} sl_var_t;
|
||||||
|
|
||||||
|
typedef struct _sl_minmax_t
|
||||||
|
{
|
||||||
|
uint32_t L;
|
||||||
|
uint32_t N;
|
||||||
|
radio_float_t P;
|
||||||
|
radio_float_t *pU;
|
||||||
|
radio_float_t *pU_last;
|
||||||
|
uint32_t *pP;
|
||||||
|
uint32_t *pP_last;
|
||||||
|
radio_float_t max;
|
||||||
|
radio_float_t mode;
|
||||||
|
|
||||||
|
} sl_minmax_t;
|
||||||
|
|
||||||
|
typedef struct _map_t
|
||||||
|
{
|
||||||
|
radio_float_t mag, phi;
|
||||||
|
cpx_t rect;
|
||||||
|
uint32_t sym;
|
||||||
|
|
||||||
|
} map_t;
|
||||||
|
|
||||||
|
typedef struct _sym_map_t
|
||||||
|
{
|
||||||
|
uint32_t nBitsPerSym, num_const, type;
|
||||||
|
uint32_t mask, sym_last;
|
||||||
|
radio_float_t Es, Eb, R2, R4, Pref;
|
||||||
|
map_t **ppMapTbl, *pMapTbl;
|
||||||
|
radio_float_t iq_step, iq_max;
|
||||||
|
uint32_t iq_side_len;
|
||||||
|
|
||||||
|
} sym_map_t;
|
||||||
|
|
||||||
|
typedef struct _per_sym_stat_t
|
||||||
|
{
|
||||||
|
uint32_t count;
|
||||||
|
radio_float_t p, var_err_mag, var_err_phi;
|
||||||
|
sl_var_t sl_err_mag, sl_err_phi;
|
||||||
|
|
||||||
|
} per_sym_stat_t;
|
||||||
|
|
||||||
|
typedef struct _sym_stat_t
|
||||||
|
{
|
||||||
|
uint32_t sym_cnt, num_const;
|
||||||
|
per_sym_stat_t *pPerSymStat;
|
||||||
|
|
||||||
|
|
||||||
|
} sym_stat_t;
|
||||||
|
|
||||||
|
typedef struct _sym_err_t
|
||||||
|
{
|
||||||
|
radio_float_t err_mag, err_phi;
|
||||||
|
radio_float_t mag, phi, hard_mag;
|
||||||
|
cpx_t err, hard_sym, soft_sym;
|
||||||
|
|
||||||
|
} sym_err_t;
|
||||||
|
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
// Interpolation
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
typedef struct _fir_cpx_t
|
||||||
|
{
|
||||||
|
uint32_t N, r, w;
|
||||||
|
cpx_t *pX;
|
||||||
|
|
||||||
|
} fir_cpx_t;
|
||||||
|
|
||||||
|
typedef struct _fdly_t
|
||||||
|
{
|
||||||
|
int Nf;
|
||||||
|
radio_float_t *hf, *statef;
|
||||||
|
} fdly_t;
|
||||||
|
|
||||||
|
typedef struct _lgip_t
|
||||||
|
{
|
||||||
|
int N, bufsize;
|
||||||
|
rbuf_t rbuf;
|
||||||
|
} lgip_t;
|
||||||
|
|
||||||
|
typedef struct _lgip_cpx_t
|
||||||
|
{
|
||||||
|
cpx_t *pFifo;
|
||||||
|
uint32_t N, L, w, r;
|
||||||
|
|
||||||
|
} lgip_cpx_t;
|
||||||
|
|
||||||
|
typedef struct _fir_pp_t
|
||||||
|
{
|
||||||
|
uint32_t N, M;
|
||||||
|
radio_float_t **ppCoeff, *pState;
|
||||||
|
|
||||||
|
} fir_pp_t;
|
||||||
|
|
||||||
|
typedef struct _ppip_t
|
||||||
|
{
|
||||||
|
radio_float_t **ppCoeff, *pState;
|
||||||
|
uint32_t N, M;
|
||||||
|
rbuf_t rbuf;
|
||||||
|
|
||||||
|
} ppip_t;
|
||||||
|
|
||||||
|
typedef struct _ppip_cpx_t
|
||||||
|
{
|
||||||
|
cpx_t *pFifo;
|
||||||
|
radio_float_t **ppCoeff;
|
||||||
|
uint32_t N, L, M, w, r;
|
||||||
|
|
||||||
|
} ppip_cpx_t;
|
||||||
|
|
||||||
|
typedef struct _ppip_farrow_cpx_t
|
||||||
|
{
|
||||||
|
cpx_t *pFifo, *pH, *pB;
|
||||||
|
radio_float_t **ppCoeff;
|
||||||
|
uint32_t N, L, M, w, r;
|
||||||
|
|
||||||
|
} ppip_farrow_cpx_t;
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
// Equalizer
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
#if 0
|
||||||
|
#define CEF_MODE_NOP 0
|
||||||
|
#define CEF_MODE_CMA 1
|
||||||
|
#define CEF_MODE_DD 2
|
||||||
|
#define CEF_MODE_EQ_UPD 3
|
||||||
|
|
||||||
|
typedef struct _vcma_t
|
||||||
|
{
|
||||||
|
uint32_t L, M, N, m, init_latency_cnt;
|
||||||
|
cpx_t *pZ, **ppY, *pC, *pX, *pU;
|
||||||
|
radio_float_t b;
|
||||||
|
|
||||||
|
} vcma_t;
|
||||||
|
|
||||||
|
typedef struct _eq_cpx_t
|
||||||
|
{
|
||||||
|
uint32_t N;
|
||||||
|
cpx_t *pX, *pW;
|
||||||
|
|
||||||
|
} eq_cpx_t;
|
||||||
|
|
||||||
|
typedef struct _cma_t
|
||||||
|
{
|
||||||
|
uint32_t N, M;
|
||||||
|
eq_cpx_t eq;
|
||||||
|
radio_float_t Px, Px_last;
|
||||||
|
|
||||||
|
} cma_t;
|
||||||
|
|
||||||
|
typedef struct _dfe_cpx_t
|
||||||
|
{
|
||||||
|
uint32_t N, N_ff, N_fb;
|
||||||
|
eq_cpx_t eq;
|
||||||
|
|
||||||
|
} dfe_cpx_t;
|
||||||
|
|
||||||
|
typedef struct _cef_t
|
||||||
|
{
|
||||||
|
uint32_t N, M, mode;
|
||||||
|
vcma_t vcma;
|
||||||
|
eq_cpx_t eq;
|
||||||
|
cpx_t *pW, *pW_offline, *pW_eq, *pX;
|
||||||
|
radio_float_t R2;
|
||||||
|
|
||||||
|
} cef_t;
|
||||||
|
|
||||||
|
typedef struct _rls_t
|
||||||
|
{
|
||||||
|
uint32_t N, M;
|
||||||
|
cpx_t *pX, *pW, *pZ, *pR, *pT;
|
||||||
|
radio_float_t *R, *T, *T2, *z, *w, *x;
|
||||||
|
|
||||||
|
} rls_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
// Frame Types
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
typedef struct _frame_hdr_t
|
||||||
|
{
|
||||||
|
uint8_t preamble[2];
|
||||||
|
uint32_t prn_state;
|
||||||
|
uint16_t crc16;
|
||||||
|
uint16_t type;
|
||||||
|
uint16_t length;
|
||||||
|
|
||||||
|
} frame_hdr_t;
|
||||||
|
|
||||||
|
typedef struct _frame_t
|
||||||
|
{
|
||||||
|
frame_hdr_t hdr;
|
||||||
|
uint8_t data[FRAME_NUM_BYTES_PER_FRAME];
|
||||||
|
|
||||||
|
} frame_t;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
// Real Functions
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
radio_float_t dabs(radio_float_t x);
|
||||||
|
radio_float_t dsign(radio_float_t x);
|
||||||
|
radio_float_t dmod(radio_float_t x, radio_float_t y);
|
||||||
|
radio_float_t dmax(radio_float_t x, radio_float_t y);
|
||||||
|
radio_float_t dmin(radio_float_t x, radio_float_t y);
|
||||||
|
radio_float_t dclamp(radio_float_t x, radio_float_t limit_low, radio_float_t limit_high);
|
||||||
|
radio_float_t powerDB(radio_float_t v1, radio_float_t preScale);
|
||||||
|
float fsum(float *pSrc, int len);
|
||||||
|
float fmean(float *pSrc, int len);
|
||||||
|
radio_float_t dsum(radio_float_t *pSrc, int len);
|
||||||
|
radio_float_t dmean(radio_float_t *pSrc, int len);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
// Complex Functions
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
cpx_t CpxConjS(cpx_t v1);
|
||||||
|
cpx_t CpxAddS(cpx_t v1, cpx_t v2);
|
||||||
|
cpx_t CpxSubS(cpx_t v1, cpx_t v2);
|
||||||
|
cpx_t CpxMulS(cpx_t v1, cpx_t v2);
|
||||||
|
cpx_t CpxScaleRealS(cpx_t v1, radio_float_t v2);
|
||||||
|
cpx_t CpxScaleComplexS(cpx_t x, cpx_t gain);
|
||||||
|
cpx_t CpxFromReal(radio_float_t v1);
|
||||||
|
cpx_t Cpx(radio_float_t real, radio_float_t imag);
|
||||||
|
cpx_t CpxMinS(cpx_t x1, cpx_t x2);
|
||||||
|
cpx_t CpxMaxS(cpx_t x1, cpx_t x2);
|
||||||
|
radio_float_t CpxMagS(cpx_t v1);
|
||||||
|
radio_float_t CpxPhiS(cpx_t v1);
|
||||||
|
radio_float_t cpxPowerDB(cpx_t v1, radio_float_t preScale);
|
||||||
|
void CpxCopy(cpx_t *pSrc, cpx_t *pDst, uint32_t len);
|
||||||
|
void CpxConj(cpx_t *pSrcDst, uint32_t len);
|
||||||
|
void CpxAdd(cpx_t *pSrc, cpx_t *pSrcDst, uint32_t len);
|
||||||
|
void CpxSub(cpx_t *pSrc, cpx_t *pSrcDst, uint32_t len);
|
||||||
|
void CpxMul(cpx_t *pSrc, cpx_t *pSrcDst, uint32_t len);
|
||||||
|
radio_float_t CpxMag(cpx_t *pSrc);
|
||||||
|
radio_float_t CpxPhi(cpx_t *pSrc);
|
||||||
|
cpx_t csum(cpx_t *pSrc, int len);
|
||||||
|
cpx_t cmean(cpx_t *pSrc, int len);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
// NCO
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
void NCO_Init(nco_t *pObj, radio_float_t omega, radio_float_t phi, uint32_t tbl_size);
|
||||||
|
void NCO_Free(nco_t *pObj);
|
||||||
|
void NCO_ModPhi(nco_t *pObj, radio_float_t dPhi);
|
||||||
|
void NCO_ModOmega(nco_t *pObj, radio_float_t dOmega);
|
||||||
|
radio_float_t NCO_GetOmega(nco_t *pObj);
|
||||||
|
void NCO_Process(nco_t *pObj);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
// Mixer
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
cpx_t NCO_MixComplexS(nco_t *pObj, cpx_t *pSrc, cpx_t gain);
|
||||||
|
cpx_t NCO_MixRealS(nco_t *pObj, radio_float_t src, radio_float_t gain);
|
||||||
|
radio_float_t NCO_MixComplexRealS(nco_t *pObj, cpx_t *pSrc, cpx_t gain);
|
||||||
|
void NCO_MixComplex(nco_t *pObj, cpx_t *pSrc, cpx_t *pDst, cpx_t gain);
|
||||||
|
void NCO_MixReal(nco_t *pObj, radio_float_t src, cpx_t *pDst, radio_float_t gain);
|
||||||
|
radio_float_t NCO_MixComplexReal(nco_t *pObj, cpx_t *pSrc, cpx_t gain);
|
||||||
|
void NCO_MixComplexV(nco_t *pObj, cpx_t *pSrc, cpx_t *pDst, cpx_t gain, uint32_t len);
|
||||||
|
void NCO_MixRealV(nco_t *pObj, radio_float_t *pSrc, cpx_t *pDst, radio_float_t gain, uint32_t len);
|
||||||
|
void NCO_MixComplexRealV(nco_t *pObj, cpx_t *pSrc, radio_float_t *pDst, cpx_t gain, uint32_t len);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
// Synchronization
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
#if 0
|
||||||
|
void Clkgen_Init(clkgen_t *pObj);
|
||||||
|
int Clkgen_GetPulse(clkgen_t *pObj, nco_t *pNCO);
|
||||||
|
int Clkgen_GetClock(clkgen_t *pObj);
|
||||||
|
|
||||||
|
void SamplerInit(sampler_t *pObj, int divide);
|
||||||
|
int SamplerIsSample(sampler_t *pObj);
|
||||||
|
void SamplerUpdate(sampler_t *pObj);
|
||||||
|
|
||||||
|
void STRGardnerInit(str_t *pObj);
|
||||||
|
radio_float_t STRGardnerProcess(str_t *pObj, cpx_t x);
|
||||||
|
|
||||||
|
void LeadLagInit(lead_lag_filter_t *pObj, radio_float_t lead_gain, radio_float_t lag_gain, radio_float_t ic_lag);
|
||||||
|
void LeadLagSetGainLead(lead_lag_filter_t *pObj, radio_float_t gain);
|
||||||
|
void LeadLagSetGainLag(lead_lag_filter_t *pObj, radio_float_t gain);
|
||||||
|
radio_float_t LeadLagProcess(lead_lag_filter_t *pObj, radio_float_t x);
|
||||||
|
|
||||||
|
radio_float_t PhaseErrQPSK(cpx_t x);
|
||||||
|
radio_float_t PhaseErr(cpx_t x, radio_float_t pstep, radio_float_t poffset);
|
||||||
|
#endif
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
// Sliding Statistics
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
void SlidingMeanInit(sl_mean_t *pObj, int N);
|
||||||
|
void SlidingMeanFree(sl_mean_t *pObj);
|
||||||
|
radio_float_t SlidingMeanProcess(sl_mean_t *pObj, radio_float_t x);
|
||||||
|
void SlidingMeanProcessV(sl_mean_t *pObj, radio_float_t *pX, uint32_t len);
|
||||||
|
radio_float_t SlidingMeanGet(sl_mean_t *pObj);
|
||||||
|
|
||||||
|
void SlidingVarInit(sl_var_t *pObj, int Npwr, int Nmean);
|
||||||
|
void SlidingVarFree(sl_var_t *pObj);
|
||||||
|
radio_float_t SlidingVarProcess(sl_var_t *pObj, radio_float_t x);
|
||||||
|
void SlidingVarProcessV(sl_var_t *pObj, radio_float_t *pX, uint32_t len);
|
||||||
|
radio_float_t SlidingVarGet(sl_var_t *pObj);
|
||||||
|
radio_float_t SlidingVarGetPowerDB(sl_var_t *pObj, radio_float_t preScale);
|
||||||
|
|
||||||
|
void SlidingMinMaxInit(sl_minmax_t *pObj, uint32_t L, radio_float_t P, radio_float_t mode);
|
||||||
|
void SlidingMinMaxFree(sl_minmax_t *pObj);
|
||||||
|
radio_float_t SlidingMinMaxProcess(sl_minmax_t *pObj, radio_float_t x);
|
||||||
|
void SlidingMinMaxProcessV(sl_minmax_t *pObj, radio_float_t *pX, uint32_t len);
|
||||||
|
radio_float_t SlidingMinMaxGet(sl_minmax_t *pObj);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
// RingBuffer
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
void RBufInit(rbuf_t *pObj, int delay);
|
||||||
|
void RBufFree(rbuf_t *pObj);
|
||||||
|
void RBufPut(rbuf_t *pObj, radio_float_t x);
|
||||||
|
radio_float_t RBufGet(rbuf_t *pObj);
|
||||||
|
radio_float_t RBufGetAfter(rbuf_t *pObj, int delay);
|
||||||
|
radio_float_t RBufGetAt(rbuf_t *pObj, int index);
|
||||||
|
void FifoInit(fifo_t *pObj, uint32_t max_size);
|
||||||
|
void FifoFree(fifo_t *pObj);
|
||||||
|
uint32_t FifoSize(fifo_t *pObj);
|
||||||
|
uint32_t FifoSizeMax(fifo_t *pObj);
|
||||||
|
uint32_t FifoFront(fifo_t *pObj);
|
||||||
|
uint32_t FifoBack(fifo_t *pObj);
|
||||||
|
void FifoPushBack(fifo_t *pObj, uint32_t item);
|
||||||
|
void FifoPushFront(fifo_t *pObj, uint32_t item);
|
||||||
|
void FifoPopBack(fifo_t *pObj);
|
||||||
|
void FifoPopFront(fifo_t *pObj);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
// Interpolation
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
void FDly_Init(fdly_t *pObj, int order);
|
||||||
|
void FDly_Free(fdly_t *pObj);
|
||||||
|
void FDly_CalcCoeff(fdly_t *pObj, radio_float_t delay);
|
||||||
|
radio_float_t FDly_Process(fdly_t *pObj, radio_float_t x);
|
||||||
|
|
||||||
|
void LGIpInit(lgip_t *pObj, int order, int bufsize);
|
||||||
|
void LGIpFree(lgip_t *pObj);
|
||||||
|
radio_float_t LGIpProcess(lgip_t *pObj, radio_float_t x, int m, radio_float_t mu);
|
||||||
|
|
||||||
|
void LGCpxIpInit(lgip_cpx_t *pObj, int order);
|
||||||
|
void LGCpxIpFree(lgip_cpx_t *pObj);
|
||||||
|
cpx_t LGCpxIpProcess(lgip_cpx_t *pObj, cpx_t x, int m, radio_float_t mu);
|
||||||
|
|
||||||
|
radio_float_t PolyPhaseSRRCInit(fir_pp_t *pObj, radio_float_t fa, radio_float_t tsym, radio_float_t alpha, uint32_t N, uint32_t M);
|
||||||
|
void PolyPhaseSRRCFree(fir_pp_t *pObj);
|
||||||
|
uint32_t PolyPhaseSRRCProcess(fir_pp_t *pObj, radio_float_t mu, radio_float_t *pX, radio_float_t *pY, uint32_t len);
|
||||||
|
|
||||||
|
radio_float_t PolyPhaseIpInit(ppip_t *pObj, radio_float_t fa, radio_float_t tsym, radio_float_t alpha, uint32_t N, uint32_t M);
|
||||||
|
void PolyPhaseIpFree(ppip_t *pObj);
|
||||||
|
radio_float_t PolyPhaseIpProcess(ppip_t *pObj, radio_float_t x, int m, radio_float_t mu);
|
||||||
|
|
||||||
|
radio_float_t PolyPhaseCpxIpInit(ppip_cpx_t *pObj, radio_float_t fa, radio_float_t tsym, radio_float_t alpha, uint32_t N, uint32_t M);
|
||||||
|
void PolyPhaseCpxIpFree(ppip_cpx_t *pObj);
|
||||||
|
cpx_t PolyPhaseCpxIpProcess(ppip_cpx_t *pObj, cpx_t x, int32_t m, radio_float_t mu);
|
||||||
|
|
||||||
|
void FarrowPPIPCpxInit(ppip_farrow_cpx_t *pObj, uint32_t M, uint32_t N);
|
||||||
|
void FarrowPPIPCpxFree(ppip_farrow_cpx_t *pObj);
|
||||||
|
cpx_t FarrowPPIPCpxProcess(ppip_farrow_cpx_t *pObj, cpx_t x, int32_t m, radio_float_t mu);
|
||||||
|
|
||||||
|
void FirCpxInit(fir_cpx_t *pObj, uint32_t N);
|
||||||
|
void FirCpxFree(fir_cpx_t *pObj);
|
||||||
|
void FirCpxProcessReal(fir_cpx_t *pObj, radio_float_t *pW, cpx_t *pSrc, cpx_t *pDst, uint32_t downSampleFactor, uint32_t len);
|
||||||
|
void FirCpxProcessComplex(fir_cpx_t *pObj, cpx_t *pW, cpx_t *pSrc, cpx_t *pDst, uint32_t len);
|
||||||
|
|
||||||
|
void SymErrInit(sym_err_t *pObj);
|
||||||
|
void SymStatInit(sym_stat_t *pObj, uint32_t nBitsPerSym);
|
||||||
|
void SymStatFree(sym_stat_t *pObj);
|
||||||
|
void SymStatUpDate(sym_stat_t *pObj, uint8_t sym, sym_err_t *pSym_err);
|
||||||
|
void SymStatPrint(sym_stat_t *pObj);
|
||||||
|
|
||||||
|
void SymMapInit(sym_map_t *pObj, uint32_t nBitsPerSym, uint32_t type);
|
||||||
|
void SymMapFree(sym_map_t *pObj);
|
||||||
|
radio_float_t SymMapGetModulus(sym_map_t *pObj, cpx_t x);
|
||||||
|
map_t SymMapGetSymbol(sym_map_t *pObj, cpx_t x);
|
||||||
|
uint8_t SymMapDecode(sym_map_t *pObj, cpx_t x, sym_err_t *pErr);
|
||||||
|
cpx_t SymMapEncode(sym_map_t *pObj, uint8_t bit);
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
void CMAInit(cma_t *pObj, uint32_t ntaps, uint32_t nSamplesPerSym);
|
||||||
|
void CMAFree(cma_t *pObj);
|
||||||
|
cpx_t CMAProcess(cma_t *pObj, cpx_t x);
|
||||||
|
cpx_t CMAGodard(cpx_t sym_s_eq, radio_float_t mag_h, radio_float_t R2);
|
||||||
|
radio_float_t CMATrain(cma_t *pObj, cpx_t y, cpx_t d, radio_float_t mu);
|
||||||
|
|
||||||
|
void EQComplexInit(eq_cpx_t *pObj, uint32_t N);
|
||||||
|
void EQComplexFree(eq_cpx_t *pObj);
|
||||||
|
cpx_t EQComplexProcess(eq_cpx_t *pObj, cpx_t x);
|
||||||
|
|
||||||
|
void DFEComplexInit(dfe_cpx_t *pObj, uint32_t K);
|
||||||
|
void DFEComplexFree(dfe_cpx_t *pObj);
|
||||||
|
cpx_t DFEComplexProcess(dfe_cpx_t *pObj, cpx_t xs, cpx_t xh);
|
||||||
|
void DFEAdaptLMS(dfe_cpx_t *pObj, cpx_t e, radio_float_t mu);
|
||||||
|
|
||||||
|
void CoeffComplexUnitAt(cpx_t *pW, uint32_t N, uint32_t dly);
|
||||||
|
void CoeffComplexConv(cpx_t *pSrc, cpx_t *pDst, uint32_t N, uint32_t dly);
|
||||||
|
|
||||||
|
void LMSUpdateWeigths(eq_cpx_t *pObj, cpx_t e, radio_float_t mu);
|
||||||
|
|
||||||
|
void RLSInit(rls_t *pObj, uint32_t N, uint32_t M);
|
||||||
|
void RLSFree(rls_t *pObj);
|
||||||
|
cpx_t RLSProcess(rls_t *pObj, radio_float_t i, radio_float_t q);
|
||||||
|
radio_float_t RLSUpdate(rls_t *pObj, radio_float_t rho, radio_float_t mu, radio_float_t y, radio_float_t d);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
// Data Functions
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
uint32_t Scramble(uint8_t *pSrcDst, uint32_t state, uint32_t poly, uint32_t len);
|
||||||
|
uint32_t FrameCalcNumStreamBytes(uint32_t len_raw);
|
||||||
|
uint32_t FrameFormat(uint8_t *pRaw, uint8_t *pFormatted, uint32_t len_raw, uint32_t *pPrn_state, uint16_t frame_type);
|
||||||
|
uint32_t FrameDeformat(uint8_t *pFormatted, uint8_t *pRaw, uint32_t len_formatted, uint16_t frame_type);
|
||||||
|
uint32_t FrameSerialize(uint8_t *pSrc, uint8_t *pDst, uint32_t nBitsPerSym, uint32_t srclen);
|
||||||
|
uint32_t FrameDeSerialize(uint8_t *pSrc, uint8_t *pDst, uint32_t nBitsPerSym, uint32_t srclen, uint16_t frame_type);
|
||||||
|
uint32_t FrameSymbolsMap(uint8_t *pBits, cpx_t *pSym, uint32_t nBitsPerSym, uint32_t num_syms, uint32_t type);
|
||||||
|
uint32_t FrameSymbolsDemap(cpx_t *pSym, uint8_t *pBits, uint32_t nBitsPerSym, uint32_t num_syms, uint32_t type);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
#endif // RADIO_H
|
||||||
Executable
+28
@@ -0,0 +1,28 @@
|
|||||||
|
// --------------------------------------------------------------
|
||||||
|
#ifndef RADIO_TYPES_H
|
||||||
|
#define RADIO_TYPES_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
// RF Types
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
#ifndef PI
|
||||||
|
#define PI 3.1415926535897932384626433832795
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define RADIO_POWER_EPS (1E-12)
|
||||||
|
|
||||||
|
#define MAP_MODE_PSK 0
|
||||||
|
#define MAP_MODE_QAM 1
|
||||||
|
#define MAP_MODE_PIN 2
|
||||||
|
|
||||||
|
#ifndef radio_float_t
|
||||||
|
#define radio_float_t float
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef uint32_t symbol_t;
|
||||||
|
typedef uint8_t data_t;
|
||||||
|
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
#endif // RADIO_TYPES_H
|
||||||
@@ -0,0 +1,83 @@
|
|||||||
|
// --------------------------------------------------------------
|
||||||
|
#include <string.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include "radio_types.h"
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
// Real Functions
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
radio_float_t dabs(radio_float_t x)
|
||||||
|
{
|
||||||
|
if (x < 0)
|
||||||
|
return -x;
|
||||||
|
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
radio_float_t dsign(radio_float_t x)
|
||||||
|
{
|
||||||
|
if (x < 0)
|
||||||
|
return -1.0;
|
||||||
|
|
||||||
|
return 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
radio_float_t dmod(radio_float_t x, radio_float_t y)
|
||||||
|
{
|
||||||
|
int xy;
|
||||||
|
|
||||||
|
if (y == 0)
|
||||||
|
return x;
|
||||||
|
|
||||||
|
xy = (int)floor(x/y);
|
||||||
|
|
||||||
|
return dsign(y)*(radio_float_t)fabs(x - y*(radio_float_t)xy);
|
||||||
|
}
|
||||||
|
|
||||||
|
radio_float_t dmax(radio_float_t x, radio_float_t y)
|
||||||
|
{
|
||||||
|
if (x > y)
|
||||||
|
return x;
|
||||||
|
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
|
radio_float_t dmin(radio_float_t x, radio_float_t y)
|
||||||
|
{
|
||||||
|
if (x < y)
|
||||||
|
return x;
|
||||||
|
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
|
radio_float_t dclamp(radio_float_t x, radio_float_t limit_low, radio_float_t limit_high)
|
||||||
|
{
|
||||||
|
return dmin(dmax(x, limit_low), limit_high);
|
||||||
|
}
|
||||||
|
|
||||||
|
radio_float_t powerDB(radio_float_t v1, radio_float_t preScale)
|
||||||
|
{
|
||||||
|
return (radio_float_t)(10*log10(RADIO_POWER_EPS + v1*preScale));
|
||||||
|
}
|
||||||
|
|
||||||
|
radio_float_t dsum(radio_float_t *pSrc, int len)
|
||||||
|
{
|
||||||
|
radio_float_t sum = 0;
|
||||||
|
|
||||||
|
while(len--)
|
||||||
|
sum += *(pSrc++);
|
||||||
|
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
radio_float_t dmean(radio_float_t *pSrc, int len)
|
||||||
|
{
|
||||||
|
return dsum(pSrc, len)/len;
|
||||||
|
}
|
||||||
|
|
||||||
|
radio_float_t dpow(radio_float_t base, radio_float_t exp)
|
||||||
|
{
|
||||||
|
return (radio_float_t)pow(base, exp);
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
// --------------------------------------------------------------
|
||||||
|
#ifndef REAL_H
|
||||||
|
#define REAL_H
|
||||||
|
|
||||||
|
#include "radio_types.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
// Real Functions
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
// Scalar
|
||||||
|
radio_float_t dabs(radio_float_t x);
|
||||||
|
radio_float_t dsign(radio_float_t x);
|
||||||
|
radio_float_t dmod(radio_float_t x, radio_float_t y);
|
||||||
|
radio_float_t dmax(radio_float_t x, radio_float_t y);
|
||||||
|
radio_float_t dmin(radio_float_t x, radio_float_t y);
|
||||||
|
radio_float_t dclamp(radio_float_t x, radio_float_t limit_low, radio_float_t limit_high);
|
||||||
|
radio_float_t powerDB(radio_float_t v1, radio_float_t preScale);
|
||||||
|
radio_float_t dsum(radio_float_t *pSrc, int len);
|
||||||
|
radio_float_t dmean(radio_float_t *pSrc, int len);
|
||||||
|
radio_float_t dpow(radio_float_t base, radio_float_t exp);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif // __cplusplus
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
#endif // REAL_H
|
||||||
@@ -0,0 +1,168 @@
|
|||||||
|
// --------------------------------------------------------------
|
||||||
|
#include <string.h>
|
||||||
|
#include <malloc.h>
|
||||||
|
#include "ringbuf.h"
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
void RBufInit(rbuf_t *pObj, uint32_t size)
|
||||||
|
{
|
||||||
|
pObj->ir = 0;
|
||||||
|
pObj->iw = 0;
|
||||||
|
pObj->dist = 0;
|
||||||
|
|
||||||
|
pObj->size = size;
|
||||||
|
pObj->pData = (radio_float_t*)malloc(size*sizeof(radio_float_t));
|
||||||
|
memset(pObj->pData, 0, size*sizeof(radio_float_t));
|
||||||
|
}
|
||||||
|
|
||||||
|
void RBufFree(rbuf_t *pObj)
|
||||||
|
{
|
||||||
|
if (pObj->pData)
|
||||||
|
free(pObj->pData);
|
||||||
|
|
||||||
|
pObj->pData = NULL;
|
||||||
|
pObj->size = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RBufPut(rbuf_t *pObj, radio_float_t x)
|
||||||
|
{
|
||||||
|
(pObj->iw)++;
|
||||||
|
if (pObj->iw >= pObj->size)
|
||||||
|
pObj->iw = 0;
|
||||||
|
|
||||||
|
pObj->pData[pObj->iw] = x;
|
||||||
|
pObj->dist++;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
radio_float_t RBufGet(rbuf_t *pObj)
|
||||||
|
{
|
||||||
|
radio_float_t y;
|
||||||
|
y = pObj->pData[(pObj->ir)++];
|
||||||
|
|
||||||
|
if (pObj->ir >= pObj->size)
|
||||||
|
pObj->ir = 0;
|
||||||
|
|
||||||
|
pObj->dist--;
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
|
radio_float_t RBufGetAfter(rbuf_t *pObj, int32_t delay)
|
||||||
|
{
|
||||||
|
pObj->ir = (pObj->iw-delay)%pObj->size;
|
||||||
|
if (pObj->ir < 0)
|
||||||
|
pObj->ir += pObj->size;
|
||||||
|
|
||||||
|
pObj->dist = delay;
|
||||||
|
return pObj->pData[pObj->ir];
|
||||||
|
}
|
||||||
|
|
||||||
|
radio_float_t RBufGetAt(rbuf_t *pObj, uint32_t index)
|
||||||
|
{
|
||||||
|
if (index < 0)
|
||||||
|
index = 0;
|
||||||
|
pObj->ir = (index)%pObj->size;
|
||||||
|
pObj->dist = pObj->iw-pObj->ir;
|
||||||
|
if (pObj->dist < 0)
|
||||||
|
pObj->dist += pObj->size;
|
||||||
|
|
||||||
|
return pObj->pData[pObj->ir];
|
||||||
|
}
|
||||||
|
|
||||||
|
void FifoInit(fifo_t *pObj, uint32_t max_size)
|
||||||
|
{
|
||||||
|
pObj->size_max = max_size;
|
||||||
|
pObj->size = 0;
|
||||||
|
pObj->iw = (uint32_t)0;
|
||||||
|
pObj->ir = (uint32_t)0;
|
||||||
|
|
||||||
|
pObj->pData = (uint32_t*)malloc(max_size*sizeof(uint32_t));
|
||||||
|
memset(pObj->pData, 0, max_size*sizeof(uint32_t));
|
||||||
|
}
|
||||||
|
|
||||||
|
void FifoFree(fifo_t *pObj)
|
||||||
|
{
|
||||||
|
if (pObj->pData)
|
||||||
|
free(pObj->pData);
|
||||||
|
|
||||||
|
pObj->pData = NULL;
|
||||||
|
pObj->size_max = 0;
|
||||||
|
pObj->size = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t FifoSize(fifo_t *pObj)
|
||||||
|
{
|
||||||
|
return pObj->size;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t FifoSizeMax(fifo_t *pObj)
|
||||||
|
{
|
||||||
|
return pObj->size_max;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t FifoFront(fifo_t *pObj)
|
||||||
|
{
|
||||||
|
return pObj->pData[pObj->ir];
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t FifoBack(fifo_t *pObj)
|
||||||
|
{
|
||||||
|
return pObj->pData[pObj->iw];
|
||||||
|
}
|
||||||
|
|
||||||
|
void FifoPushBack(fifo_t *pObj, uint32_t item)
|
||||||
|
{
|
||||||
|
pObj->pData[pObj->iw++] = item;
|
||||||
|
if (pObj->iw >= pObj->size_max)
|
||||||
|
pObj->iw = 0;
|
||||||
|
|
||||||
|
if (pObj->size < pObj->size_max)
|
||||||
|
{
|
||||||
|
pObj->size++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (++pObj->ir >= pObj->size_max)
|
||||||
|
pObj->ir = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FifoPushFront(fifo_t *pObj, uint32_t item)
|
||||||
|
{
|
||||||
|
pObj->ir--;
|
||||||
|
if (pObj->ir >= pObj->size_max)
|
||||||
|
pObj->ir = 0;
|
||||||
|
|
||||||
|
pObj->pData[pObj->ir] = item;
|
||||||
|
if (pObj->size < pObj->size_max)
|
||||||
|
{
|
||||||
|
pObj->size++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (--pObj->iw >= pObj->size_max)
|
||||||
|
pObj->iw = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FifoPopBack(fifo_t *pObj)
|
||||||
|
{
|
||||||
|
pObj->iw--;
|
||||||
|
if (pObj->iw >= pObj->size_max)
|
||||||
|
pObj->iw = 0;
|
||||||
|
|
||||||
|
if (pObj->size > 0)
|
||||||
|
pObj->size--;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FifoPopFront(fifo_t *pObj)
|
||||||
|
{
|
||||||
|
pObj->ir++;
|
||||||
|
if (pObj->ir >= pObj->size_max)
|
||||||
|
pObj->ir = 0;
|
||||||
|
|
||||||
|
if (pObj->size > 0)
|
||||||
|
pObj->size--;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
// --------------------------------------------------------------
|
||||||
|
#ifndef RINGBUF_H
|
||||||
|
#define RINGBUF_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "radio_types.h"
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
// Types
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
typedef struct _rbuf_t
|
||||||
|
{
|
||||||
|
uint32_t size, iw, ir, dist;
|
||||||
|
radio_float_t *pData;
|
||||||
|
|
||||||
|
} rbuf_t;
|
||||||
|
|
||||||
|
typedef struct _fifo_t
|
||||||
|
{
|
||||||
|
uint32_t size_max;
|
||||||
|
uint32_t size;
|
||||||
|
uint32_t ir;
|
||||||
|
uint32_t iw;
|
||||||
|
uint32_t *pData;
|
||||||
|
|
||||||
|
} fifo_t;
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
// Functions
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
// RingBuffer
|
||||||
|
void RBufInit(rbuf_t *pObj, uint32_t size);
|
||||||
|
void RBufFree(rbuf_t *pObj);
|
||||||
|
void RBufPut(rbuf_t *pObj, radio_float_t x);
|
||||||
|
radio_float_t RBufGet(rbuf_t *pObj);
|
||||||
|
radio_float_t RBufGetAfter(rbuf_t *pObj, int32_t delay);
|
||||||
|
radio_float_t RBufGetAt(rbuf_t *pObj, uint32_t index);
|
||||||
|
|
||||||
|
// Fifo
|
||||||
|
void FifoInit(fifo_t *pObj, uint32_t max_size);
|
||||||
|
void FifoFree(fifo_t *pObj);
|
||||||
|
uint32_t FifoSize(fifo_t *pObj);
|
||||||
|
uint32_t FifoSizeMax(fifo_t *pObj);
|
||||||
|
uint32_t FifoFront(fifo_t *pObj);
|
||||||
|
uint32_t FifoBack(fifo_t *pObj);
|
||||||
|
void FifoPushBack(fifo_t *pObj, uint32_t item);
|
||||||
|
void FifoPushFront(fifo_t *pObj, uint32_t item);
|
||||||
|
void FifoPopBack(fifo_t *pObj);
|
||||||
|
void FifoPopFront(fifo_t *pObj);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif // __cplusplus
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
#endif // RINGBUF_H
|
||||||
Executable
+245
@@ -0,0 +1,245 @@
|
|||||||
|
// --------------------------------------------------------------
|
||||||
|
#include <malloc.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "statistics.h"
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
// Sliding Mean
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
void SlidingMeanInit(sl_mean_t *pObj, int N)
|
||||||
|
{
|
||||||
|
RBufInit(&pObj->buf, N);
|
||||||
|
pObj->Nr = (radio_float_t)1.0/N;
|
||||||
|
pObj->mean = 0.0;
|
||||||
|
pObj->sum = 0.0;
|
||||||
|
pObj->normalize_count = N;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SlidingMeanFree(sl_mean_t *pObj)
|
||||||
|
{
|
||||||
|
RBufFree(&pObj->buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
radio_float_t SlidingMeanProcess(sl_mean_t *pObj, radio_float_t x)
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
radio_float_t last;
|
||||||
|
|
||||||
|
last = RBufGetAfter(&pObj->buf, pObj->buf.size-1);
|
||||||
|
RBufPut(&pObj->buf, x);
|
||||||
|
pObj->sum += (x - last);
|
||||||
|
pObj->mean = pObj->sum*pObj->Nr;
|
||||||
|
|
||||||
|
if (--pObj->normalize_count == 0)
|
||||||
|
{
|
||||||
|
pObj->normalize_count = pObj->buf.size;
|
||||||
|
pObj->sum = 0;
|
||||||
|
for (i=0; i < pObj->buf.size; i++)
|
||||||
|
{
|
||||||
|
pObj->sum += pObj->buf.pData[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return pObj->mean;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SlidingMeanProcessV(sl_mean_t *pObj, radio_float_t *pX, uint32_t len)
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
|
for (i=0; i < len; i++)
|
||||||
|
SlidingMeanProcess(pObj, *(pX++));
|
||||||
|
}
|
||||||
|
|
||||||
|
radio_float_t SlidingMeanGet(sl_mean_t *pObj)
|
||||||
|
{
|
||||||
|
return pObj->mean;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
// Sliding Variance
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
void SlidingVarInit(sl_var_t *pObj, int Npwr, int Nmean)
|
||||||
|
{
|
||||||
|
RBufInit(&pObj->buf, Npwr);
|
||||||
|
SlidingMeanInit(&pObj->sl_mean, Nmean);
|
||||||
|
pObj->Nr = (radio_float_t)1.0/Npwr;
|
||||||
|
pObj->var = 0.0;
|
||||||
|
pObj->sum = 0.0;
|
||||||
|
pObj->normalize_count = Npwr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SlidingVarFree(sl_var_t *pObj)
|
||||||
|
{
|
||||||
|
RBufFree(&pObj->buf);
|
||||||
|
SlidingMeanFree(&pObj->sl_mean);
|
||||||
|
}
|
||||||
|
|
||||||
|
radio_float_t SlidingVarProcess(sl_var_t *pObj, radio_float_t x)
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
radio_float_t last, xm, mean, var;
|
||||||
|
|
||||||
|
last = RBufGetAfter(&pObj->buf, pObj->buf.size-1);
|
||||||
|
mean = SlidingMeanProcess(&pObj->sl_mean, x);
|
||||||
|
xm = x - mean;
|
||||||
|
xm *= xm;
|
||||||
|
RBufPut(&pObj->buf, xm);
|
||||||
|
pObj->sum += (xm - last);
|
||||||
|
|
||||||
|
var = pObj->sum*pObj->Nr;
|
||||||
|
if (var >= 0)
|
||||||
|
pObj->var = var;
|
||||||
|
|
||||||
|
if (--pObj->normalize_count == 0)
|
||||||
|
{
|
||||||
|
pObj->normalize_count = pObj->buf.size;
|
||||||
|
pObj->sum = 0;
|
||||||
|
for (i=0; i < pObj->buf.size; i++)
|
||||||
|
{
|
||||||
|
pObj->sum += pObj->buf.pData[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return pObj->var;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SlidingVarProcessV(sl_var_t *pObj, radio_float_t *pX, uint32_t len)
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
|
for (i=0; i < len; i++)
|
||||||
|
SlidingVarProcess(pObj, *(pX++));
|
||||||
|
}
|
||||||
|
|
||||||
|
radio_float_t SlidingVarGet(sl_var_t *pObj)
|
||||||
|
{
|
||||||
|
return pObj->var;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
// Sliding Min/Max
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
void SlidingMinMaxInit(sl_minmax_t *pObj, uint32_t L, radio_float_t P, radio_float_t mode)
|
||||||
|
{
|
||||||
|
pObj->L = L;
|
||||||
|
pObj->P = P;
|
||||||
|
pObj->N = 0;
|
||||||
|
pObj->max = 0;
|
||||||
|
pObj->mode = mode;
|
||||||
|
pObj->pP = (uint32_t*)malloc(L*sizeof(uint32_t));
|
||||||
|
pObj->pU = (radio_float_t*)malloc(L*sizeof(radio_float_t));
|
||||||
|
pObj->pP_last = (uint32_t*)malloc(L*sizeof(uint32_t));
|
||||||
|
pObj->pU_last = (radio_float_t*)malloc(L*sizeof(radio_float_t));
|
||||||
|
memset(pObj->pP, 0, L*sizeof(uint32_t));
|
||||||
|
memset(pObj->pU, 0, L*sizeof(radio_float_t));
|
||||||
|
memset(pObj->pP_last, 0, L*sizeof(uint32_t));
|
||||||
|
memset(pObj->pU_last, 0, L*sizeof(radio_float_t));
|
||||||
|
pObj->pU_last[1] = P;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SlidingMinMaxFree(sl_minmax_t *pObj)
|
||||||
|
{
|
||||||
|
if (pObj->pP)
|
||||||
|
free(pObj->pP);
|
||||||
|
|
||||||
|
if (pObj->pU)
|
||||||
|
free(pObj->pU);
|
||||||
|
|
||||||
|
if (pObj->pP_last)
|
||||||
|
free(pObj->pP_last);
|
||||||
|
|
||||||
|
if (pObj->pU_last)
|
||||||
|
free(pObj->pU_last);
|
||||||
|
|
||||||
|
pObj->pP = (uint32_t*)0;
|
||||||
|
pObj->pU = (radio_float_t*)0;
|
||||||
|
pObj->pP_last = (uint32_t*)0;
|
||||||
|
pObj->pU_last = (radio_float_t*)0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sliding Min/Max based on MAXLIST-Algorithm, based on:
|
||||||
|
// "AN EFFICIENT ALGORITHM FOR RUNNING MAX MIN CALCULATION", 1996, S.C. Douglas, University of Utah
|
||||||
|
// Dependeding on 'mode' this algorithm calculates either minimum (mode = -1) or maximum (mode = +1)
|
||||||
|
radio_float_t SlidingMinMaxProcess(sl_minmax_t *pObj, radio_float_t x)
|
||||||
|
{
|
||||||
|
uint32_t m;
|
||||||
|
uint32_t i;
|
||||||
|
uint32_t j;
|
||||||
|
|
||||||
|
x *= pObj->mode;
|
||||||
|
|
||||||
|
m = 1;
|
||||||
|
if (pObj->pP_last[pObj->N] == pObj->L)
|
||||||
|
{
|
||||||
|
m = 0;
|
||||||
|
pObj->pU_last[pObj->N] = pObj->P;
|
||||||
|
}
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
while (x >= pObj->pU_last[i+1])
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
pObj->N = pObj->N - i + m;
|
||||||
|
|
||||||
|
for (j=1; j < pObj->N; j++)
|
||||||
|
{
|
||||||
|
pObj->pU[j+1] = pObj->pU_last[j+i];
|
||||||
|
pObj->pP[j+1] = pObj->pP_last[j+i] + 1;
|
||||||
|
}
|
||||||
|
pObj->pU[pObj->N+1] = pObj->P;
|
||||||
|
pObj->pU[1] = x;
|
||||||
|
pObj->pP[1] = 1;
|
||||||
|
pObj->max = pObj->pU[pObj->N];
|
||||||
|
|
||||||
|
i=0;
|
||||||
|
while(pObj->pU[i] != pObj->P)
|
||||||
|
{
|
||||||
|
pObj->pU_last[i] = pObj->pU[i];
|
||||||
|
pObj->pP_last[i] = pObj->pP[i];
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
pObj->pU_last[i] = pObj->pU[i];
|
||||||
|
pObj->pP_last[i] = pObj->pP[i];
|
||||||
|
|
||||||
|
return pObj->mode*pObj->max;
|
||||||
|
}
|
||||||
|
|
||||||
|
radio_float_t SlidingMinMaxGet(sl_minmax_t *pObj)
|
||||||
|
{
|
||||||
|
return pObj->mode*pObj->max;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SlidingMinMaxProcessV(sl_minmax_t *pObj, radio_float_t *pX, uint32_t len)
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
|
for (i=0; i < len; i++)
|
||||||
|
{
|
||||||
|
SlidingMinMaxProcess(pObj, pX[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
void TraceOpen(trace_t *pObj, char *pFilename)
|
||||||
|
{
|
||||||
|
pObj->pFile = fopen(pFilename, "w");
|
||||||
|
}
|
||||||
|
|
||||||
|
void TraceClose(trace_t *pObj)
|
||||||
|
{
|
||||||
|
if (pObj->pFile)
|
||||||
|
fclose(pObj->pFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TracePrint(trace_t *pObj, char *fmt, ... )
|
||||||
|
{
|
||||||
|
|
||||||
|
va_list a_list;
|
||||||
|
|
||||||
|
if (!pObj->pFile)
|
||||||
|
return;
|
||||||
|
|
||||||
|
va_start( a_list, fmt );
|
||||||
|
|
||||||
|
vfprintf(pObj->pFile, fmt, a_list);
|
||||||
|
}
|
||||||
Executable
+94
@@ -0,0 +1,94 @@
|
|||||||
|
// --------------------------------------------------------------
|
||||||
|
#ifndef STATISTICS_H
|
||||||
|
#define STATISTICS_H
|
||||||
|
|
||||||
|
#include <stdio.h> // Trace()
|
||||||
|
#include <stdarg.h> // Trace()
|
||||||
|
|
||||||
|
#include "radio_types.h"
|
||||||
|
#include "real.h"
|
||||||
|
#include "ringbuf.h"
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
// Types
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
typedef struct _sl_mean_t
|
||||||
|
{
|
||||||
|
rbuf_t buf;
|
||||||
|
uint32_t normalize_count;
|
||||||
|
radio_float_t Nr;
|
||||||
|
radio_float_t sum;
|
||||||
|
radio_float_t element_max;
|
||||||
|
radio_float_t mean;
|
||||||
|
|
||||||
|
} sl_mean_t;
|
||||||
|
|
||||||
|
typedef struct _sl_var_t
|
||||||
|
{
|
||||||
|
rbuf_t buf;
|
||||||
|
uint32_t normalize_count;
|
||||||
|
radio_float_t Nr;
|
||||||
|
radio_float_t sum;
|
||||||
|
radio_float_t var;
|
||||||
|
sl_mean_t sl_mean;
|
||||||
|
|
||||||
|
} sl_var_t;
|
||||||
|
|
||||||
|
typedef struct _sl_minmax_t
|
||||||
|
{
|
||||||
|
uint32_t L;
|
||||||
|
uint32_t N;
|
||||||
|
radio_float_t P;
|
||||||
|
radio_float_t *pU;
|
||||||
|
radio_float_t *pU_last;
|
||||||
|
uint32_t *pP;
|
||||||
|
uint32_t *pP_last;
|
||||||
|
radio_float_t max;
|
||||||
|
radio_float_t mode;
|
||||||
|
|
||||||
|
} sl_minmax_t;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
// Functions
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
// Sliding Mean
|
||||||
|
void SlidingMeanInit(sl_mean_t *pObj, int N);
|
||||||
|
void SlidingMeanFree(sl_mean_t *pObj);
|
||||||
|
radio_float_t SlidingMeanProcess(sl_mean_t *pObj, radio_float_t x);
|
||||||
|
void SlidingMeanProcessV(sl_mean_t *pObj, radio_float_t *pX, uint32_t len);
|
||||||
|
radio_float_t SlidingMeanGet(sl_mean_t *pObj);
|
||||||
|
|
||||||
|
// Sliding Variance
|
||||||
|
void SlidingVarInit(sl_var_t *pObj, int Npwr, int Nmean);
|
||||||
|
void SlidingVarFree(sl_var_t *pObj);
|
||||||
|
radio_float_t SlidingVarProcess(sl_var_t *pObj, radio_float_t x);
|
||||||
|
void SlidingVarProcessV(sl_var_t *pObj, radio_float_t *pX, uint32_t len);
|
||||||
|
radio_float_t SlidingVarGet(sl_var_t *pObj);
|
||||||
|
|
||||||
|
// Sliding Min/Max
|
||||||
|
void SlidingMinMaxInit(sl_minmax_t *pObj, uint32_t L, radio_float_t P, radio_float_t mode);
|
||||||
|
void SlidingMinMaxFree(sl_minmax_t *pObj);
|
||||||
|
radio_float_t SlidingMinMaxProcess(sl_minmax_t *pObj, radio_float_t x);
|
||||||
|
void SlidingMinMaxProcessV(sl_minmax_t *pObj, radio_float_t *pX, uint32_t len);
|
||||||
|
radio_float_t SlidingMinMaxGet(sl_minmax_t *pObj);
|
||||||
|
|
||||||
|
typedef struct _trace_t
|
||||||
|
{
|
||||||
|
FILE *pFile;
|
||||||
|
} trace_t;
|
||||||
|
|
||||||
|
void TraceOpen(trace_t *pObj, char *pFilename);
|
||||||
|
void TraceClose(trace_t *pObj);
|
||||||
|
void TracePrint(trace_t *pObj, char *fmt, ... );
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif // __cplusplus
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
#endif // STATISTICS_H
|
||||||
@@ -0,0 +1,298 @@
|
|||||||
|
// --------------------------------------------------------------
|
||||||
|
#include <stdio.h> // for SymStatPrint() remove later
|
||||||
|
#include <string.h>
|
||||||
|
#include <malloc.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include "radio_types.h"
|
||||||
|
#include "symbol.h"
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
// Symbol demapper for receiver works on each symbol
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
void SymMapInit(sym_map_t *pObj, uint32_t nBitsPerSym, uint32_t type)
|
||||||
|
{
|
||||||
|
cpx_t iq;
|
||||||
|
uint32_t i, j, k, m, n, u, Ns, Nq, Nsq, map_idx_i, map_idx_q;
|
||||||
|
radio_float_t phi, dphi, ii, qq, iii, qqq, temp, stepIQ;
|
||||||
|
radio_float_t mag, E_m2, E_m2_c, E_m4;
|
||||||
|
radio_float_t c_smma;
|
||||||
|
cpx_t E_a4;
|
||||||
|
int signI[4] = {+1, -1, -1, +1};
|
||||||
|
int signQ[4] = {+1, +1, -1, -1};
|
||||||
|
int even;
|
||||||
|
pObj->nBitsPerSym = nBitsPerSym;
|
||||||
|
pObj->num_const = 1;
|
||||||
|
pObj->type = type;
|
||||||
|
pObj->iq_step = 0;
|
||||||
|
pObj->iq_max = 0;
|
||||||
|
pObj->Pref = 0;
|
||||||
|
E_a4 = Cpx(0,0);
|
||||||
|
c_smma = (radio_float_t)1; // Tuning constant S-MMA
|
||||||
|
for(k=0; k < nBitsPerSym; k++)
|
||||||
|
{
|
||||||
|
pObj->num_const *= 2;
|
||||||
|
}
|
||||||
|
pObj->pMapTbl = (map_t*)malloc(pObj->num_const*sizeof(map_t));
|
||||||
|
pObj->ppMapTbl = NULL;
|
||||||
|
|
||||||
|
Ns = (uint32_t)sqrt((radio_float_t)pObj->num_const);
|
||||||
|
Nq = pObj->num_const/4;
|
||||||
|
Nsq = (uint32_t)sqrt((radio_float_t)Nq);
|
||||||
|
stepIQ = (radio_float_t)sqrt(2.0)/(Ns-1);
|
||||||
|
E_m2_c = E_m2 = E_m4 = 0;
|
||||||
|
switch(type)
|
||||||
|
{
|
||||||
|
|
||||||
|
case MAP_MODE_PSK:
|
||||||
|
|
||||||
|
pObj->Es = 1.0; // Symbol transmit power
|
||||||
|
pObj->Eb = pObj->Es/nBitsPerSym;
|
||||||
|
pObj->Pref = (radio_float_t)(1.0/sqrt(2.0));
|
||||||
|
|
||||||
|
dphi = 2*(radio_float_t)PI/pObj->num_const;
|
||||||
|
phi = (radio_float_t)PI/pObj->num_const;
|
||||||
|
|
||||||
|
for (k=0; k < pObj->num_const; k++)
|
||||||
|
{
|
||||||
|
iq.real = (radio_float_t)cos(phi);
|
||||||
|
iq.imag = (radio_float_t)sin(phi);
|
||||||
|
pObj->pMapTbl[k].phi = (radio_float_t)CpxPhiS(iq);
|
||||||
|
pObj->pMapTbl[k].mag = (radio_float_t)CpxMagS(iq);
|
||||||
|
pObj->pMapTbl[k].rect = iq;
|
||||||
|
phi += dphi;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MAP_MODE_QAM:
|
||||||
|
pObj->Es = (radio_float_t)0.5*stepIQ*stepIQ;
|
||||||
|
pObj->Eb = pObj->Es/nBitsPerSym;
|
||||||
|
pObj->ppMapTbl = (map_t**)malloc(Ns*sizeof(map_t*));
|
||||||
|
for (i=0; i< Ns; i++)
|
||||||
|
pObj->ppMapTbl[i] = (map_t*)malloc(Ns*sizeof(map_t));
|
||||||
|
|
||||||
|
ii = (radio_float_t)(1.0/sqrt(2.0));
|
||||||
|
pObj->iq_max = ii;
|
||||||
|
qq = ii;
|
||||||
|
even = 1;
|
||||||
|
|
||||||
|
k = 0;
|
||||||
|
for (m=0; m < Nsq; m++)
|
||||||
|
{
|
||||||
|
for (n=0; n < Nsq; n++)
|
||||||
|
{
|
||||||
|
iii = ii;
|
||||||
|
qqq = qq;
|
||||||
|
for (j=0; j < 4; j++)
|
||||||
|
{
|
||||||
|
u = Nq*j+k;
|
||||||
|
iq.real = iii*signI[j];
|
||||||
|
iq.imag = qqq*signQ[j];
|
||||||
|
mag = (radio_float_t)CpxMagS(iq);
|
||||||
|
phi = (radio_float_t)CpxPhiS(iq);
|
||||||
|
pObj->pMapTbl[u].mag = mag;
|
||||||
|
pObj->pMapTbl[u].phi = phi;
|
||||||
|
pObj->pMapTbl[u].rect = iq;
|
||||||
|
E_m2_c += (radio_float_t)pow(mag, 2+c_smma);
|
||||||
|
E_m2 += (radio_float_t)pow(mag, 2);
|
||||||
|
E_m4 += (radio_float_t)pow(mag, 4);
|
||||||
|
E_a4.real += (radio_float_t)pow(iq.real, 4);
|
||||||
|
E_a4.imag += (radio_float_t)pow(iq.imag, 4);
|
||||||
|
temp = iii;
|
||||||
|
iii = qqq;
|
||||||
|
qqq = temp;
|
||||||
|
map_idx_i = (int)(0.5 +(0.5*iq.real/pObj->iq_max + 0.5)*(Ns-1));
|
||||||
|
map_idx_q = (int)(0.5 +(0.5*iq.imag/pObj->iq_max + 0.5)*(Ns-1));
|
||||||
|
pObj->ppMapTbl[map_idx_i][map_idx_q].mag = mag;
|
||||||
|
pObj->ppMapTbl[map_idx_i][map_idx_q].phi = phi;
|
||||||
|
pObj->ppMapTbl[map_idx_i][map_idx_q].rect = iq;
|
||||||
|
pObj->ppMapTbl[map_idx_i][map_idx_q].sym = (symbol_t)u;
|
||||||
|
}
|
||||||
|
ii = ii - even*stepIQ;
|
||||||
|
k++;
|
||||||
|
}
|
||||||
|
qq = qq - stepIQ;
|
||||||
|
ii = ii + even*stepIQ;
|
||||||
|
even = -even;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(pObj->num_const)
|
||||||
|
{
|
||||||
|
// QPSK
|
||||||
|
case 4:
|
||||||
|
pObj->Pref = (radio_float_t)0.707;
|
||||||
|
break;
|
||||||
|
// 16-QAM
|
||||||
|
case 16:
|
||||||
|
pObj->Pref = (radio_float_t)0.385;
|
||||||
|
break;
|
||||||
|
// 64-QAM
|
||||||
|
case 64:
|
||||||
|
pObj->Pref = (radio_float_t)0.31;
|
||||||
|
break;
|
||||||
|
// 256-QAM
|
||||||
|
case 256:
|
||||||
|
pObj->Pref = (radio_float_t)0.27;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pObj->iq_step = stepIQ;
|
||||||
|
pObj->iq_side_len = Ns;
|
||||||
|
pObj->R2_cma = E_m4/E_m2;
|
||||||
|
pObj->R_mma.real = 2*E_a4.real/E_m2;
|
||||||
|
pObj->R_mma.imag = 2*E_a4.imag/E_m2;
|
||||||
|
pObj->R_smma.real = 2*E_a4.real/E_m2_c;
|
||||||
|
pObj->R_smma.imag = 2*E_a4.imag/E_m2_c;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SymMapFree(sym_map_t *pObj)
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
|
if (pObj->pMapTbl)
|
||||||
|
{
|
||||||
|
free(pObj->pMapTbl);
|
||||||
|
pObj->pMapTbl = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pObj->ppMapTbl)
|
||||||
|
{
|
||||||
|
for (i=0; i< (uint32_t)sqrt((float)pObj->num_const); i++)
|
||||||
|
free(pObj->ppMapTbl[i]);
|
||||||
|
|
||||||
|
free(pObj->ppMapTbl);
|
||||||
|
pObj->ppMapTbl = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SymMapReinit(sym_map_t *pObj, uint32_t nBitsPerSym, uint32_t type)
|
||||||
|
{
|
||||||
|
SymMapFree(pObj);
|
||||||
|
SymMapInit(pObj, nBitsPerSym, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
cpx_t SymMapMap(sym_map_t *pObj, symbol_t symbol)
|
||||||
|
{
|
||||||
|
if (symbol >= pObj->num_const)
|
||||||
|
return Cpx(0,0);
|
||||||
|
|
||||||
|
return pObj->pMapTbl[(uint32_t)symbol].rect;
|
||||||
|
}
|
||||||
|
|
||||||
|
symbol_t SymMapDemap(sym_map_t *pObj, cpx_t x)
|
||||||
|
{
|
||||||
|
uint32_t map_idx_i, map_idx_q;
|
||||||
|
radio_float_t rx_i, rx_q;
|
||||||
|
|
||||||
|
rx_i = dclamp(x.real, -pObj->iq_max, pObj->iq_max);
|
||||||
|
rx_q = dclamp(x.imag, -pObj->iq_max, pObj->iq_max);
|
||||||
|
|
||||||
|
map_idx_i = (int)(0.5 +(0.5*rx_i/pObj->iq_max + 0.5)*(pObj->iq_side_len-1));
|
||||||
|
map_idx_q = (int)(0.5 +(0.5*rx_q/pObj->iq_max + 0.5)*(pObj->iq_side_len-1));
|
||||||
|
|
||||||
|
return pObj->ppMapTbl[map_idx_i][map_idx_q].sym;
|
||||||
|
}
|
||||||
|
|
||||||
|
map_t SymMapGetSymbolInfo(sym_map_t *pObj, symbol_t symbol)
|
||||||
|
{
|
||||||
|
return pObj->pMapTbl[(uint32_t)symbol];
|
||||||
|
}
|
||||||
|
|
||||||
|
sym_err_t SymMapGetError(sym_map_t *pObj, cpx_t x, symbol_t symbol)
|
||||||
|
{
|
||||||
|
map_t map;
|
||||||
|
sym_err_t res;
|
||||||
|
|
||||||
|
map = SymMapGetSymbolInfo(pObj, symbol);
|
||||||
|
|
||||||
|
res.err_mag = map.mag - (radio_float_t)CpxMagS(x);
|
||||||
|
res.err_phi = map.phi - (radio_float_t)CpxPhiS(x);
|
||||||
|
res.err = CpxSubS(map.rect, x);
|
||||||
|
res.mag = CpxMagS(x);
|
||||||
|
res.phi = CpxPhiS(x);
|
||||||
|
res.soft_sym = x;
|
||||||
|
res.hard_sym = map.rect;
|
||||||
|
res.hard_mag = map.mag;
|
||||||
|
res.hard_phi = map.phi;
|
||||||
|
|
||||||
|
return res;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
void SymStatInit(sym_stat_t *pObj, uint32_t nBitsPerSym)
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
|
memset(pObj, 0, sizeof(sym_stat_t));
|
||||||
|
|
||||||
|
pObj->num_const = 1;
|
||||||
|
for(i=0; i < nBitsPerSym; i++)
|
||||||
|
{
|
||||||
|
pObj->num_const *= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
pObj->pPerSymStat = (per_sym_stat_t*)malloc(pObj->num_const*sizeof(per_sym_stat_t));
|
||||||
|
|
||||||
|
for(i=0; i < pObj->num_const; i++)
|
||||||
|
{
|
||||||
|
pObj->pPerSymStat[i].count = 0;
|
||||||
|
pObj->pPerSymStat[i].var_err_mag = 0;
|
||||||
|
pObj->pPerSymStat[i].var_err_phi = 0;
|
||||||
|
SlidingVarInit(&pObj->pPerSymStat[i].sl_err_mag, 1000, 1000);
|
||||||
|
SlidingVarInit(&pObj->pPerSymStat[i].sl_err_phi, 1000, 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void SymStatFree(sym_stat_t *pObj)
|
||||||
|
{
|
||||||
|
if(pObj->pPerSymStat)
|
||||||
|
free(pObj->pPerSymStat);
|
||||||
|
|
||||||
|
pObj->pPerSymStat = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SymStatReset(sym_stat_t *pObj)
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
pObj->sym_cnt = 0;
|
||||||
|
for(i=0; i < pObj->num_const; i++)
|
||||||
|
{
|
||||||
|
pObj->pPerSymStat[i].count = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SymStatUpDate(sym_stat_t *pObj, symbol_t sym, sym_err_t *pSym_err)
|
||||||
|
{
|
||||||
|
// Statistics
|
||||||
|
pObj->sym_cnt++;
|
||||||
|
pObj->pPerSymStat[sym].count++;
|
||||||
|
pObj->pPerSymStat[sym].p = (radio_float_t)pObj->pPerSymStat[sym].count/pObj->sym_cnt;
|
||||||
|
pObj->pPerSymStat[sym].var_err_mag = SlidingVarProcess(&pObj->pPerSymStat[sym].sl_err_mag, pSym_err->err_mag);
|
||||||
|
pObj->pPerSymStat[sym].var_err_phi = SlidingVarProcess(&pObj->pPerSymStat[sym].sl_err_phi, pSym_err->err_phi);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void SymStatPrint(sym_stat_t *pObj)
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
|
printf("Number of constellations : %d\n", pObj->num_const);
|
||||||
|
printf("Number of total symbols : %d\n", pObj->sym_cnt);
|
||||||
|
printf("Sym#\tOccur.\t\tProb.\t\tVar(MagErr)[dB]\tVar(PhiErr/PI)[dB]\n");
|
||||||
|
for(i=0; i < pObj->num_const; i++)
|
||||||
|
{
|
||||||
|
printf("%4.1d\t%6.d\t\t%1.2g\t\t%.2f\t\t%.2f\n",
|
||||||
|
i,
|
||||||
|
pObj->pPerSymStat[i].count,
|
||||||
|
pObj->pPerSymStat[i].p,
|
||||||
|
10*log10(pObj->pPerSymStat[i].var_err_mag),
|
||||||
|
10*log10(pObj->pPerSymStat[i].var_err_phi/(PI*PI)));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,83 @@
|
|||||||
|
// --------------------------------------------------------------
|
||||||
|
#ifndef SYMBOL_H
|
||||||
|
#define SYMBOL_H
|
||||||
|
|
||||||
|
#include "radio_types.h"
|
||||||
|
#include "statistics.h"
|
||||||
|
#include "cpx.h"
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
// Types
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
typedef struct _map_t
|
||||||
|
{
|
||||||
|
radio_float_t mag, phi;
|
||||||
|
cpx_t rect;
|
||||||
|
symbol_t sym;
|
||||||
|
|
||||||
|
} map_t;
|
||||||
|
|
||||||
|
typedef struct _sym_map_t
|
||||||
|
{
|
||||||
|
uint32_t nBitsPerSym, num_const, type;
|
||||||
|
radio_float_t Es, Eb, Pref;
|
||||||
|
map_t **ppMapTbl, *pMapTbl;
|
||||||
|
radio_float_t iq_step, iq_max;
|
||||||
|
uint32_t iq_side_len;
|
||||||
|
radio_float_t R2_cma; // For CMA
|
||||||
|
cpx_t R_mma; // for MMA
|
||||||
|
cpx_t R_smma; // for S-MMA
|
||||||
|
|
||||||
|
} sym_map_t;
|
||||||
|
|
||||||
|
typedef struct _sym_err_t
|
||||||
|
{
|
||||||
|
radio_float_t err_mag, err_phi;
|
||||||
|
radio_float_t err_mag_norm, err_phi_norm;
|
||||||
|
radio_float_t mag, phi, hard_mag, hard_phi;
|
||||||
|
cpx_t err, hard_sym, soft_sym;
|
||||||
|
|
||||||
|
} sym_err_t;
|
||||||
|
|
||||||
|
typedef struct _per_sym_stat_t
|
||||||
|
{
|
||||||
|
uint32_t count;
|
||||||
|
radio_float_t p, var_err_mag, var_err_phi;
|
||||||
|
sl_var_t sl_err_mag, sl_err_phi;
|
||||||
|
|
||||||
|
} per_sym_stat_t;
|
||||||
|
|
||||||
|
typedef struct _sym_stat_t
|
||||||
|
{
|
||||||
|
uint32_t sym_cnt, num_const;
|
||||||
|
per_sym_stat_t *pPerSymStat;
|
||||||
|
|
||||||
|
|
||||||
|
} sym_stat_t;
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
// Functions
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void SymStatInit(sym_stat_t *pObj, uint32_t nBitsPerSym);
|
||||||
|
void SymStatFree(sym_stat_t *pObj);
|
||||||
|
void SymStatReset(sym_stat_t *pObj);
|
||||||
|
void SymStatUpDate(sym_stat_t *pObj, symbol_t sym, sym_err_t *pSym_err);
|
||||||
|
void SymStatPrint(sym_stat_t *pObj);
|
||||||
|
|
||||||
|
void SymMapInit(sym_map_t *pObj, uint32_t nBitsPerSym, uint32_t type);
|
||||||
|
void SymMapFree(sym_map_t *pObj);
|
||||||
|
void SymMapReinit(sym_map_t *pObj, uint32_t nBitsPerSym, uint32_t type);
|
||||||
|
cpx_t SymMapMap(sym_map_t *pObj, symbol_t symbol);
|
||||||
|
symbol_t SymMapDemap(sym_map_t *pObj, cpx_t x);
|
||||||
|
map_t SymMapGetSymbolInfo(sym_map_t *pObj, symbol_t symbol);
|
||||||
|
sym_err_t SymMapGetError(sym_map_t *pObj, cpx_t x, symbol_t symbol);
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif // __cplusplus
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
#endif // SYMBOL_H
|
||||||
Executable
+224
@@ -0,0 +1,224 @@
|
|||||||
|
// --------------------------------------------------------------
|
||||||
|
#include <string.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include "synchronization.h"
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
// Clock generator
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
void ClockInit(clock_t *pObj, uint32_t divide)
|
||||||
|
{
|
||||||
|
if (divide == 0)
|
||||||
|
divide = 1;
|
||||||
|
|
||||||
|
pObj->reload = divide;
|
||||||
|
pObj->count = (int32_t)divide;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t ClockIsTick(clock_t *pObj, uint32_t do_advance)
|
||||||
|
{
|
||||||
|
uint32_t isTick;
|
||||||
|
|
||||||
|
isTick = pObj->count == 0;
|
||||||
|
|
||||||
|
if (do_advance)
|
||||||
|
{
|
||||||
|
if (isTick)
|
||||||
|
{
|
||||||
|
pObj->count = pObj->reload;
|
||||||
|
}
|
||||||
|
pObj->count--;
|
||||||
|
}
|
||||||
|
return isTick;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClockAdvance(clock_t *pObj)
|
||||||
|
{
|
||||||
|
if (pObj->count == 0)
|
||||||
|
{
|
||||||
|
pObj->count = pObj->reload;
|
||||||
|
}
|
||||||
|
pObj->count--;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClockSetPhase(clock_t *pObj, int32_t phase)
|
||||||
|
{
|
||||||
|
pObj->count = pObj->count - phase;
|
||||||
|
if (pObj->count <= 0)
|
||||||
|
{
|
||||||
|
pObj->count += pObj->reload;
|
||||||
|
}
|
||||||
|
else if (pObj->count > (int32_t)pObj->reload)
|
||||||
|
{
|
||||||
|
pObj->count -= pObj->reload;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
// Second-order Loop Filter
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
void LeadLagInit(lead_lag_filter_t *pObj, radio_float_t state)
|
||||||
|
{
|
||||||
|
pObj->lag_state = LEAD_LAG_SCALING*state;
|
||||||
|
};
|
||||||
|
|
||||||
|
void LeadLagSetCoeff(lead_lag_coeff_t *pCoeff, radio_float_t lead, radio_float_t lag)
|
||||||
|
{
|
||||||
|
pCoeff->lead = lead;
|
||||||
|
pCoeff->lag = lag;
|
||||||
|
}
|
||||||
|
|
||||||
|
radio_float_t LeadLagProcess(lead_lag_filter_t *pObj, lead_lag_coeff_t *pCoeff, radio_float_t x)
|
||||||
|
{
|
||||||
|
pObj->lag_state += LEAD_LAG_SCALING*pCoeff->lag * x;
|
||||||
|
|
||||||
|
return pObj->lag_state/LEAD_LAG_SCALING + pCoeff->lead * x;
|
||||||
|
}
|
||||||
|
|
||||||
|
radio_float_t LeadLagGetState(lead_lag_filter_t *pObj)
|
||||||
|
{
|
||||||
|
return pObj->lag_state/LEAD_LAG_SCALING;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LeadLagSetState(lead_lag_filter_t *pObj, radio_float_t state)
|
||||||
|
{
|
||||||
|
pObj->lag_state = LEAD_LAG_SCALING*state;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
// Gardner Timing Error Detector
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
void STRGardnerInit(str_t *pObj)
|
||||||
|
{
|
||||||
|
memset(pObj->d, 0, sizeof(pObj->d));
|
||||||
|
}
|
||||||
|
|
||||||
|
radio_float_t STRGardnerProcess(str_t *pObj, cpx_t x)
|
||||||
|
{
|
||||||
|
radio_float_t Vd;
|
||||||
|
cpx_t t, *pD;
|
||||||
|
|
||||||
|
pD = pObj->d;
|
||||||
|
|
||||||
|
t.real = (pD[1].real - x.real) * pD[0].real;
|
||||||
|
t.imag = (pD[1].imag - x.imag) * pD[0].imag;
|
||||||
|
Vd = (t.real + t.imag);
|
||||||
|
|
||||||
|
// Adjust delay line
|
||||||
|
pD[1] = pD[0];
|
||||||
|
pD[0] = x;
|
||||||
|
|
||||||
|
return Vd;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
// Simple Phase detector for QPSK
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
radio_float_t PhaseErrQPSK(cpx_t x)
|
||||||
|
{
|
||||||
|
radio_float_t perr;
|
||||||
|
perr = x.imag*dsign(x.real) - x.real*dsign(x.imag);
|
||||||
|
|
||||||
|
return perr;
|
||||||
|
}
|
||||||
|
|
||||||
|
radio_float_t PhaseErr(cpx_t x, radio_float_t pstep, radio_float_t poffset)
|
||||||
|
{
|
||||||
|
radio_float_t perr, phi, m;
|
||||||
|
|
||||||
|
phi = (radio_float_t)CpxPhiS(x) + poffset;
|
||||||
|
|
||||||
|
m = dmod(phi/(radio_float_t)PI,(radio_float_t)2.0/pstep);
|
||||||
|
perr = (radio_float_t)1.0/pstep - m;
|
||||||
|
|
||||||
|
return (radio_float_t)(PI*perr);
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
void PfdInit(pfd_t *pObj)
|
||||||
|
{
|
||||||
|
pObj->state_up = 0;
|
||||||
|
pObj->state_down = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
radio_float_t PfdProcess(pfd_t *pObj, radio_float_t x, radio_float_t k)
|
||||||
|
{
|
||||||
|
radio_float_t result;
|
||||||
|
|
||||||
|
result = 0;
|
||||||
|
if (x < 0)
|
||||||
|
{
|
||||||
|
if (pObj->state_down == 0)
|
||||||
|
{
|
||||||
|
pObj->state_up = 0;
|
||||||
|
pObj->state_down = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result = -k;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (pObj->state_up == 0)
|
||||||
|
{
|
||||||
|
pObj->state_down = 0;
|
||||||
|
pObj->state_up = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result = k;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
void TimingCorrectorInit(timing_corrector_t *pObj, radio_float_t wrap_alpha)
|
||||||
|
{
|
||||||
|
pObj->mu = 0;
|
||||||
|
pObj->mu_filtered = 0;
|
||||||
|
pObj->wrap_alpha = wrap_alpha;
|
||||||
|
pObj->wrap_beta = (radio_float_t)1.0 - wrap_alpha;
|
||||||
|
memset(pObj->skip, 0, sizeof(pObj->skip));
|
||||||
|
memset(pObj->stuff, 0, sizeof(pObj->stuff));
|
||||||
|
}
|
||||||
|
|
||||||
|
radio_float_t TimingCorrectorProcess(timing_corrector_t *pObj, radio_float_t dMu)
|
||||||
|
{
|
||||||
|
pObj->mu += dMu;
|
||||||
|
pObj->skip[1] = pObj->skip[0];
|
||||||
|
pObj->stuff[1] = pObj->stuff[0];
|
||||||
|
pObj->skip[0] = 0;
|
||||||
|
pObj->stuff[0] = 0;
|
||||||
|
pObj->mu_filtered = pObj->wrap_beta*pObj->mu_filtered + pObj->wrap_alpha*pObj->mu;
|
||||||
|
|
||||||
|
if (pObj->mu_filtered < 0)
|
||||||
|
{
|
||||||
|
pObj->mu += (radio_float_t)1.0;
|
||||||
|
pObj->stuff[0] = 1;
|
||||||
|
}
|
||||||
|
else if (pObj->mu_filtered >= (radio_float_t)1.0)
|
||||||
|
{
|
||||||
|
pObj->mu -= (radio_float_t)1.0;
|
||||||
|
pObj->skip[0] = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pObj->mu;
|
||||||
|
}
|
||||||
|
|
||||||
|
radio_float_t TimingCorrectorGetMu(timing_corrector_t *pObj)
|
||||||
|
{
|
||||||
|
return pObj->mu;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t TimingCorrectorIsSkip(timing_corrector_t *pObj)
|
||||||
|
{
|
||||||
|
return pObj->skip[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t TimingCorrectorIsStuff(timing_corrector_t *pObj)
|
||||||
|
{
|
||||||
|
return pObj->stuff[0];
|
||||||
|
}
|
||||||
Executable
+93
@@ -0,0 +1,93 @@
|
|||||||
|
// --------------------------------------------------------------
|
||||||
|
#ifndef SYNCHRONIZATION_H
|
||||||
|
#define SYNCHRONIZATION_H
|
||||||
|
|
||||||
|
#include "radio_types.h"
|
||||||
|
#include "nco.h"
|
||||||
|
|
||||||
|
#define LEAD_LAG_SCALING ((radio_float_t)1024*1024)
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
// Types
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
typedef struct _clock_t
|
||||||
|
{
|
||||||
|
uint32_t reload;
|
||||||
|
int32_t count;
|
||||||
|
|
||||||
|
} clock_t;
|
||||||
|
|
||||||
|
typedef struct _lead_lag_filter_t
|
||||||
|
{
|
||||||
|
radio_float_t lag_state;
|
||||||
|
|
||||||
|
} lead_lag_filter_t;
|
||||||
|
|
||||||
|
typedef struct _lead_lag_coeff_t
|
||||||
|
{
|
||||||
|
radio_float_t lead;
|
||||||
|
radio_float_t lag;
|
||||||
|
|
||||||
|
} lead_lag_coeff_t;
|
||||||
|
|
||||||
|
typedef struct _str_t
|
||||||
|
{
|
||||||
|
cpx_t d[2];
|
||||||
|
|
||||||
|
} str_t;
|
||||||
|
|
||||||
|
typedef struct _pfd_t
|
||||||
|
{
|
||||||
|
uint32_t state_up;
|
||||||
|
uint32_t state_down;
|
||||||
|
} pfd_t;
|
||||||
|
|
||||||
|
typedef struct _timing_corrector_t
|
||||||
|
{
|
||||||
|
radio_float_t mu;
|
||||||
|
radio_float_t mu_filtered;
|
||||||
|
radio_float_t wrap_alpha;
|
||||||
|
radio_float_t wrap_beta;
|
||||||
|
uint32_t skip[2];
|
||||||
|
uint32_t stuff[2];
|
||||||
|
|
||||||
|
} timing_corrector_t;
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
// Functions
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void ClockInit(clock_t *pObj, uint32_t divide);
|
||||||
|
uint32_t ClockIsTick(clock_t *pObj, uint32_t do_advance);
|
||||||
|
void ClockAdvance(clock_t *pObj);
|
||||||
|
void ClockSetPhase(clock_t *pObj, int32_t phase);
|
||||||
|
|
||||||
|
void STRGardnerInit(str_t *pObj);
|
||||||
|
radio_float_t STRGardnerProcess(str_t *pObj, cpx_t x);
|
||||||
|
|
||||||
|
radio_float_t PhaseErrQPSK(cpx_t x);
|
||||||
|
radio_float_t PhaseErr(cpx_t x, radio_float_t pstep, radio_float_t poffset);
|
||||||
|
|
||||||
|
void PfdInit(pfd_t *pObj);
|
||||||
|
radio_float_t PfdProcess(pfd_t *pObj, radio_float_t x, radio_float_t k);
|
||||||
|
|
||||||
|
void LeadLagInit(lead_lag_filter_t *pObj, radio_float_t state);
|
||||||
|
void LeadLagSetCoeff(lead_lag_coeff_t *pCoeff, radio_float_t lead, radio_float_t lag);
|
||||||
|
radio_float_t LeadLagProcess(lead_lag_filter_t *pObj, lead_lag_coeff_t *pCoeff, radio_float_t x);
|
||||||
|
radio_float_t LeadLagGetState(lead_lag_filter_t *pObj);
|
||||||
|
void LeadLagSetState(lead_lag_filter_t *pObj, radio_float_t state);
|
||||||
|
|
||||||
|
void TimingCorrectorInit(timing_corrector_t *pObj, radio_float_t wrap_alpha);
|
||||||
|
radio_float_t TimingCorrectorProcess(timing_corrector_t *pObj, radio_float_t dMu);
|
||||||
|
radio_float_t TimingCorrectorGetMu(timing_corrector_t *pObj);
|
||||||
|
uint32_t TimingCorrectorIsSkip(timing_corrector_t *pObj);
|
||||||
|
uint32_t TimingCorrectorIsStuff(timing_corrector_t *pObj);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif // __cplusplus
|
||||||
|
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
#endif // SYNCHRONIZATION_H
|
||||||
Reference in New Issue
Block a user