mirror of
https://github.com/f4exb/sdrangel.git
synced 2024-12-24 19:00:36 -05:00
364 lines
8.1 KiB
C++
364 lines
8.1 KiB
C++
/*
|
|
Bit interleaver
|
|
|
|
Copyright 2018 Ahmet Inan <xdsopl@gmail.com>
|
|
*/
|
|
|
|
#ifndef INTERLEAVER_HH
|
|
#define INTERLEAVER_HH
|
|
|
|
namespace ldpctool {
|
|
|
|
template <typename TYPE>
|
|
struct Interleaver
|
|
{
|
|
virtual void fwd(TYPE *) = 0;
|
|
virtual void bwd(TYPE *) = 0;
|
|
virtual ~Interleaver() = default;
|
|
};
|
|
|
|
template <typename TYPE>
|
|
struct ITL0 : public Interleaver<TYPE>
|
|
{
|
|
void fwd(TYPE *){}
|
|
void bwd(TYPE *){}
|
|
};
|
|
|
|
template <typename TYPE, typename PITL, typename MUX>
|
|
struct BITL : public Interleaver<TYPE>
|
|
{
|
|
static const int N = PITL::N;
|
|
static const int COLS = MUX::N;
|
|
static const int ROWS = N / COLS;
|
|
TYPE tmp[N];
|
|
void fwd(TYPE *io)
|
|
{
|
|
PITL::fwd(tmp, io);
|
|
for (int row = 0; row < ROWS; ++row)
|
|
MUX::fwd(io+COLS*row, tmp+row, ROWS);
|
|
}
|
|
void bwd(TYPE *io)
|
|
{
|
|
for (int row = 0; row < ROWS; ++row)
|
|
MUX::bwd(tmp+row, io+COLS*row, ROWS);
|
|
PITL::bwd(io, tmp);
|
|
}
|
|
};
|
|
|
|
template <typename TYPE, int NUM>
|
|
struct PITL0
|
|
{
|
|
static const int N = NUM;
|
|
static void fwd(TYPE *out, TYPE *in)
|
|
{
|
|
for (int n = 0; n < N; ++n)
|
|
out[n] = in[n];
|
|
}
|
|
static void bwd(TYPE *out, TYPE *in)
|
|
{
|
|
for (int n = 0; n < N; ++n)
|
|
out[n] = in[n];
|
|
}
|
|
};
|
|
|
|
template <typename TYPE, int NUM, int Q>
|
|
struct PITL
|
|
{
|
|
static const int N = NUM;
|
|
static const int M = 360;
|
|
static const int K = N - M * Q;
|
|
static void fwd(TYPE *out, TYPE *in)
|
|
{
|
|
for (int k = 0; k < K; ++k)
|
|
out[k] = in[k];
|
|
for (int q = 0; q < Q; ++q)
|
|
for (int m = 0; m < M; ++m)
|
|
out[K+M*q+m] = in[K+Q*m+q];
|
|
}
|
|
static void bwd(TYPE *out, TYPE *in)
|
|
{
|
|
for (int k = 0; k < K; ++k)
|
|
out[k] = in[k];
|
|
for (int q = 0; q < Q; ++q)
|
|
for (int m = 0; m < M; ++m)
|
|
out[K+Q*m+q] = in[K+M*q+m];
|
|
}
|
|
};
|
|
|
|
template <typename TYPE, int NUM, int Q, typename CT>
|
|
struct PCTITL
|
|
{
|
|
static const int N = NUM;
|
|
static const int COLS = CT::N;
|
|
static const int ROWS = N / COLS;
|
|
static void fwd(TYPE *out, TYPE *in)
|
|
{
|
|
PITL<TYPE, N, Q>::fwd(out, in);
|
|
for (int n = 0; n < N; ++n)
|
|
in[n] = out[n];
|
|
for (int row = 0; row < ROWS; ++row)
|
|
CT::fwd(out+COLS*row, in, ROWS, row);
|
|
}
|
|
static void bwd(TYPE *out, TYPE *in)
|
|
{
|
|
for (int row = 0; row < ROWS; ++row)
|
|
CT::bwd(out, in+COLS*row, ROWS, row);
|
|
for (int n = 0; n < N; ++n)
|
|
in[n] = out[n];
|
|
PITL<TYPE, N, Q>::bwd(out, in);
|
|
}
|
|
};
|
|
|
|
template <typename TYPE>
|
|
struct MUX0
|
|
{
|
|
static const int N = 1;
|
|
static void fwd(TYPE *out, TYPE *in, int)
|
|
{
|
|
out[0] = in[0];
|
|
}
|
|
static void bwd(TYPE *out, TYPE *in, int)
|
|
{
|
|
out[0] = in[0];
|
|
}
|
|
};
|
|
|
|
template <typename TYPE, int E0, int E1, int E2>
|
|
struct MUX3
|
|
{
|
|
static const int N = 3;
|
|
static void fwd(TYPE *out, TYPE *in, int S)
|
|
{
|
|
out[E0] = in[0*S];
|
|
out[E1] = in[1*S];
|
|
out[E2] = in[2*S];
|
|
}
|
|
static void bwd(TYPE *out, TYPE *in, int S)
|
|
{
|
|
out[0*S] = in[E0];
|
|
out[1*S] = in[E1];
|
|
out[2*S] = in[E2];
|
|
}
|
|
};
|
|
|
|
template <typename TYPE, int E0, int E1, int E2, int E3, int E4, int E5, int E6, int E7>
|
|
struct MUX8
|
|
{
|
|
static const int N = 8;
|
|
static void fwd(TYPE *out, TYPE *in, int S)
|
|
{
|
|
out[E0] = in[0*S];
|
|
out[E1] = in[1*S];
|
|
out[E2] = in[2*S];
|
|
out[E3] = in[3*S];
|
|
out[E4] = in[4*S];
|
|
out[E5] = in[5*S];
|
|
out[E6] = in[6*S];
|
|
out[E7] = in[7*S];
|
|
}
|
|
static void bwd(TYPE *out, TYPE *in, int S)
|
|
{
|
|
out[0*S] = in[E0];
|
|
out[1*S] = in[E1];
|
|
out[2*S] = in[E2];
|
|
out[3*S] = in[E3];
|
|
out[4*S] = in[E4];
|
|
out[5*S] = in[E5];
|
|
out[6*S] = in[E6];
|
|
out[7*S] = in[E7];
|
|
}
|
|
};
|
|
|
|
template <typename TYPE, int E0, int E1, int E2, int E3, int E4, int E5, int E6, int E7, int E8, int E9, int E10, int E11>
|
|
struct MUX12
|
|
{
|
|
static const int N = 12;
|
|
static void fwd(TYPE *out, TYPE *in, int S)
|
|
{
|
|
out[E0] = in[0*S];
|
|
out[E1] = in[1*S];
|
|
out[E2] = in[2*S];
|
|
out[E3] = in[3*S];
|
|
out[E4] = in[4*S];
|
|
out[E5] = in[5*S];
|
|
out[E6] = in[6*S];
|
|
out[E7] = in[7*S];
|
|
out[E8] = in[8*S];
|
|
out[E9] = in[9*S];
|
|
out[E10] = in[10*S];
|
|
out[E11] = in[11*S];
|
|
}
|
|
static void bwd(TYPE *out, TYPE *in, int S)
|
|
{
|
|
out[0*S] = in[E0];
|
|
out[1*S] = in[E1];
|
|
out[2*S] = in[E2];
|
|
out[3*S] = in[E3];
|
|
out[4*S] = in[E4];
|
|
out[5*S] = in[E5];
|
|
out[6*S] = in[E6];
|
|
out[7*S] = in[E7];
|
|
out[8*S] = in[E8];
|
|
out[9*S] = in[E9];
|
|
out[10*S] = in[E10];
|
|
out[11*S] = in[E11];
|
|
}
|
|
};
|
|
|
|
template <typename TYPE, int E0, int E1, int E2, int E3, int E4, int E5, int E6, int E7, int E8, int E9, int E10, int E11, int E12, int E13, int E14, int E15>
|
|
struct MUX16
|
|
{
|
|
static const int N = 16;
|
|
static void fwd(TYPE *out, TYPE *in, int S)
|
|
{
|
|
out[E0] = in[0*S];
|
|
out[E1] = in[1*S];
|
|
out[E2] = in[2*S];
|
|
out[E3] = in[3*S];
|
|
out[E4] = in[4*S];
|
|
out[E5] = in[5*S];
|
|
out[E6] = in[6*S];
|
|
out[E7] = in[7*S];
|
|
out[E8] = in[8*S];
|
|
out[E9] = in[9*S];
|
|
out[E10] = in[10*S];
|
|
out[E11] = in[11*S];
|
|
out[E12] = in[12*S];
|
|
out[E13] = in[13*S];
|
|
out[E14] = in[14*S];
|
|
out[E15] = in[15*S];
|
|
}
|
|
static void bwd(TYPE *out, TYPE *in, int S)
|
|
{
|
|
out[0*S] = in[E0];
|
|
out[1*S] = in[E1];
|
|
out[2*S] = in[E2];
|
|
out[3*S] = in[E3];
|
|
out[4*S] = in[E4];
|
|
out[5*S] = in[E5];
|
|
out[6*S] = in[E6];
|
|
out[7*S] = in[E7];
|
|
out[8*S] = in[E8];
|
|
out[9*S] = in[E9];
|
|
out[10*S] = in[E10];
|
|
out[11*S] = in[E11];
|
|
out[12*S] = in[E12];
|
|
out[13*S] = in[E13];
|
|
out[14*S] = in[E14];
|
|
out[15*S] = in[E15];
|
|
}
|
|
};
|
|
|
|
template <typename TYPE, int T0, int T1, int T2, int T3, int T4, int T5, int T6, int T7>
|
|
struct CT8
|
|
{
|
|
static const int N = 8;
|
|
static void fwd(TYPE *out, TYPE *in, int S, int R)
|
|
{
|
|
out[0] = in[0*S+(R+S-T0)%S];
|
|
out[1] = in[1*S+(R+S-T1)%S];
|
|
out[2] = in[2*S+(R+S-T2)%S];
|
|
out[3] = in[3*S+(R+S-T3)%S];
|
|
out[4] = in[4*S+(R+S-T4)%S];
|
|
out[5] = in[5*S+(R+S-T5)%S];
|
|
out[6] = in[6*S+(R+S-T6)%S];
|
|
out[7] = in[7*S+(R+S-T7)%S];
|
|
}
|
|
static void bwd(TYPE *out, TYPE *in, int S, int R)
|
|
{
|
|
out[0*S+(R+S-T0)%S] = in[0];
|
|
out[1*S+(R+S-T1)%S] = in[1];
|
|
out[2*S+(R+S-T2)%S] = in[2];
|
|
out[3*S+(R+S-T3)%S] = in[3];
|
|
out[4*S+(R+S-T4)%S] = in[4];
|
|
out[5*S+(R+S-T5)%S] = in[5];
|
|
out[6*S+(R+S-T6)%S] = in[6];
|
|
out[7*S+(R+S-T7)%S] = in[7];
|
|
}
|
|
};
|
|
|
|
template <typename TYPE, int T0, int T1, int T2, int T3, int T4, int T5, int T6, int T7, int T8, int T9, int T10, int T11>
|
|
struct CT12
|
|
{
|
|
static const int N = 12;
|
|
static void fwd(TYPE *out, TYPE *in, int S, int R)
|
|
{
|
|
out[0] = in[0*S+(R+S-T0)%S];
|
|
out[1] = in[1*S+(R+S-T1)%S];
|
|
out[2] = in[2*S+(R+S-T2)%S];
|
|
out[3] = in[3*S+(R+S-T3)%S];
|
|
out[4] = in[4*S+(R+S-T4)%S];
|
|
out[5] = in[5*S+(R+S-T5)%S];
|
|
out[6] = in[6*S+(R+S-T6)%S];
|
|
out[7] = in[7*S+(R+S-T7)%S];
|
|
out[8] = in[8*S+(R+S-T8)%S];
|
|
out[9] = in[9*S+(R+S-T9)%S];
|
|
out[10] = in[10*S+(R+S-T10)%S];
|
|
out[11] = in[11*S+(R+S-T11)%S];
|
|
}
|
|
static void bwd(TYPE *out, TYPE *in, int S, int R)
|
|
{
|
|
out[0*S+(R+S-T0)%S] = in[0];
|
|
out[1*S+(R+S-T1)%S] = in[1];
|
|
out[2*S+(R+S-T2)%S] = in[2];
|
|
out[3*S+(R+S-T3)%S] = in[3];
|
|
out[4*S+(R+S-T4)%S] = in[4];
|
|
out[5*S+(R+S-T5)%S] = in[5];
|
|
out[6*S+(R+S-T6)%S] = in[6];
|
|
out[7*S+(R+S-T7)%S] = in[7];
|
|
out[8*S+(R+S-T8)%S] = in[8];
|
|
out[9*S+(R+S-T9)%S] = in[9];
|
|
out[10*S+(R+S-T10)%S] = in[10];
|
|
out[11*S+(R+S-T11)%S] = in[11];
|
|
}
|
|
};
|
|
|
|
template <typename TYPE, int T0, int T1, int T2, int T3, int T4, int T5, int T6, int T7, int T8, int T9, int T10, int T11, int T12, int T13, int T14, int T15>
|
|
struct CT16
|
|
{
|
|
static const int N = 16;
|
|
static void fwd(TYPE *out, TYPE *in, int S, int R)
|
|
{
|
|
out[0] = in[0*S+(R+S-T0)%S];
|
|
out[1] = in[1*S+(R+S-T1)%S];
|
|
out[2] = in[2*S+(R+S-T2)%S];
|
|
out[3] = in[3*S+(R+S-T3)%S];
|
|
out[4] = in[4*S+(R+S-T4)%S];
|
|
out[5] = in[5*S+(R+S-T5)%S];
|
|
out[6] = in[6*S+(R+S-T6)%S];
|
|
out[7] = in[7*S+(R+S-T7)%S];
|
|
out[8] = in[8*S+(R+S-T8)%S];
|
|
out[9] = in[9*S+(R+S-T9)%S];
|
|
out[10] = in[10*S+(R+S-T10)%S];
|
|
out[11] = in[11*S+(R+S-T11)%S];
|
|
out[12] = in[12*S+(R+S-T12)%S];
|
|
out[13] = in[13*S+(R+S-T13)%S];
|
|
out[14] = in[14*S+(R+S-T14)%S];
|
|
out[15] = in[15*S+(R+S-T15)%S];
|
|
}
|
|
static void bwd(TYPE *out, TYPE *in, int S, int R)
|
|
{
|
|
out[0*S+(R+S-T0)%S] = in[0];
|
|
out[1*S+(R+S-T1)%S] = in[1];
|
|
out[2*S+(R+S-T2)%S] = in[2];
|
|
out[3*S+(R+S-T3)%S] = in[3];
|
|
out[4*S+(R+S-T4)%S] = in[4];
|
|
out[5*S+(R+S-T5)%S] = in[5];
|
|
out[6*S+(R+S-T6)%S] = in[6];
|
|
out[7*S+(R+S-T7)%S] = in[7];
|
|
out[8*S+(R+S-T8)%S] = in[8];
|
|
out[9*S+(R+S-T9)%S] = in[9];
|
|
out[10*S+(R+S-T10)%S] = in[10];
|
|
out[11*S+(R+S-T11)%S] = in[11];
|
|
out[12*S+(R+S-T12)%S] = in[12];
|
|
out[13*S+(R+S-T13)%S] = in[13];
|
|
out[14*S+(R+S-T14)%S] = in[14];
|
|
out[15*S+(R+S-T15)%S] = in[15];
|
|
}
|
|
};
|
|
|
|
} // namespace ldpctool
|
|
|
|
#endif
|
|
|