/////////////////////////////////////////////////////////////////////////////////////// // Copyright (C) 2021 Edouard Griffiths, F4EXB // // // // This program is free software; you can redistribute it and/or modify // // it under the terms of the GNU General Public License as published by // // the Free Software Foundation as version 3 of the License, or // // (at your option) any later version. // // // // This program is distributed in the hope that it will be useful, // // but WITHOUT ANY WARRANTY; without even the implied warranty of // // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // // GNU General Public License V3 for more details. // // // // You should have received a copy of the GNU General Public License // // along with this program. If not, see . // /////////////////////////////////////////////////////////////////////////////////////// /* Bit interleaver Copyright 2018 Ahmet Inan */ #ifndef INTERLEAVER_HH #define INTERLEAVER_HH namespace ldpctool { template struct Interleaver { virtual void fwd(TYPE *) = 0; virtual void bwd(TYPE *) = 0; virtual ~Interleaver() = default; }; template struct ITL0 : public Interleaver { void fwd(TYPE *){} void bwd(TYPE *){} }; template struct BITL : public Interleaver { 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 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 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 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::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::bwd(out, in); } }; template 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 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 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 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 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 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 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 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