diff options
Diffstat (limited to 'gr-atsc/src/lib')
178 files changed, 41173 insertions, 0 deletions
diff --git a/gr-atsc/src/lib/GrAtscBitTimingLoop.cc b/gr-atsc/src/lib/GrAtscBitTimingLoop.cc new file mode 100644 index 000000000..9577dad2e --- /dev/null +++ b/gr-atsc/src/lib/GrAtscBitTimingLoop.cc @@ -0,0 +1,223 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include <cmath> +#include <GrAtscBitTimingLoop.h> +#include "fpll_btloop_coupling.h" +#include <algorithm> +#include <atsc_consts.h> +#include <stdio.h> +#include <assert.h> + +using std::abs; + +static const int DEC = 2; // nominal decimation factor + +/* + * I strongly suggest that you not mess with these... + */ +static const double DEFAULT_TIMING_RATE = 2.19e-4 / FPLL_BTLOOP_COUPLING_CONST; +static const double DEFAULT_LOOP_TAP = 0.05; + + +GrAtscBitTimingLoop::GrAtscBitTimingLoop () + : VrDecimatingSigProc<float,float> (1, DEC), + next_input(0), w (1.0), mu (0.5), last_right(0), + debug_no_update (false) +{ + d_timing_rate = DEFAULT_TIMING_RATE; + loop.set_taps (DEFAULT_LOOP_TAP); + + history = 1500; // spare input samples in case we need them. + +#ifdef _BT_DIAG_OUTPUT_ + fp_loop = fopen ("loop.out", "w"); + if (fp_loop == 0){ + perror ("loop.out"); + exit (1); + } + + fp_ps = fopen ("ps.out", "w"); + if (fp_ps == 0){ + perror ("ps.out"); + exit (1); + } +#endif +} + +// +// We are nominally a 2x decimator, but our actual rate varies slightly +// depending on the difference between the transmitter and receiver +// sampling clocks. Hence, we need to compute our input ranges +// explictly. + +int +GrAtscBitTimingLoop::forecast(VrSampleRange output, + VrSampleRange inputs[]) { + /* dec:1 ratio with history */ + for(unsigned int i=0;i<numberInputs;i++) { + inputs[i].index=next_input; + inputs[i].size=output.size*decimation + history-1; + } + return 0; +} + +inline double +GrAtscBitTimingLoop::filter_error (double e) +{ + static const double limit = 50 * FPLL_BTLOOP_COUPLING_CONST; + + // first limit + + if (e > limit) + e = limit; + else if (e < -limit) + e = -limit; + + return loop.filter (e); +} + +int +GrAtscBitTimingLoop::work (VrSampleRange output, void *ao[], + VrSampleRange inputs[], void *ai[]) +{ + iType *in = ((iType **)ai)[0]; + oType *out = ((oType **)ao)[0]; + + // Force in-order computation of output stream. + // This is required because of our slightly variable decimation factor + sync (output.index); + + + // We are tasked with producing output.size output samples. + // We will consume approximately 2 * output.size input samples. + + + unsigned int ii = 0; // input index + unsigned int k; // output index + + // We look at a window of 3 samples that we call left (oldest), + // middle, right (newest). Each time through the loop, the previous + // right becomes the new left, and the new samples are middle and + // right. + // + // The basic game plan is to drive the average difference between + // right and left to zero. Given that all transitions are + // equiprobable (the data is white) and that the composite matched + // filter is symmetric (raised cosine) it turns out that in the + // average, if we drive that difference to zero, (implying that the + // average slope at the middle point is zero), we'll be sampling + // middle at the maximum or minimum point in the pulse. + + iType left; + iType middle; + iType right = last_right; + + for (k = 0; k < output.size; k++){ + + left = right; + middle = produce_sample (in, ii); + right = produce_sample (in, ii); + + // assert (ii < inputs[0].size); + if (!(ii < inputs[0].size)){ + fprintf (stderr, "ii < inputs[0].size\n"); + fprintf (stderr, "ii = %d, inputs[0].size = %lu, k = %d, output.size = %lu\n", + ii, inputs[0].size, k, output.size); + assert (0); + } + + + out[k] = middle; // produce our output + + double timing_error = -middle * ((double) right - left); + + // update_timing_control_word + + double filtered_timing_error = filter_error (timing_error); + + if (!debug_no_update){ + mu += filtered_timing_error * d_timing_rate; + } + +#ifdef _BT_DIAG_OUTPUT_ + float iodata[8]; + iodata[0] = left; + iodata[1] = middle; + iodata[2] = right; + iodata[3] = timing_error; + iodata[4] = filtered_timing_error; + iodata[5] = mu; + iodata[6] = w; + iodata[7] = 0; + if (fwrite (iodata, sizeof (iodata), 1, fp_loop) != 1){ + perror ("fwrite: loop"); + exit (1); + } +#endif + + } + + last_right = right; + next_input += ii; // update next_input so forecast can get us what we need + return output.size; +} + +/*! + * Produce samples equally spaced in time that are referenced + * to the transmitter's sample clock, not ours. + * + * See pp 523-527 of "Digital Communication Receivers", Meyr, + * Moeneclaey and Fechtel, Wiley, 1998. + */ + +GrAtscBitTimingLoop::iType +GrAtscBitTimingLoop::produce_sample (const iType *in, unsigned int &index) +{ + // update mu and index as function of control word, w + + double sum = mu + w; + double f = floor (sum); + int incr = (int) f; // mostly 1, rarely 0 or 2 + mu = sum - f; + + assert (0 <= incr && incr <= 2); + assert (0.0 <= mu && mu <= 1.0); + + index += incr; + + iType n = intr.interpolate (&in[index], mu); + +#if defined(_BT_DIAG_OUTPUT_) && 0 + float iodata[4]; + iodata[0] = incr; + iodata[1] = mu; + iodata[2] = w; + iodata[3] = 0; + if (fwrite (iodata, sizeof (iodata), 1, fp_ps) != 1){ + perror ("fwrite: ps"); + exit (1); + } +#endif + + return n; +} diff --git a/gr-atsc/src/lib/GrAtscBitTimingLoop.h b/gr-atsc/src/lib/GrAtscBitTimingLoop.h new file mode 100644 index 000000000..3bb1adec1 --- /dev/null +++ b/gr-atsc/src/lib/GrAtscBitTimingLoop.h @@ -0,0 +1,90 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _GRATSCBITTIMINGLOOP_H_ +#define _GRATSCBITTIMINGLOOP_H_ + +#include <gr_nco.h> +#include <VrSigProc.h> +#include <VrHistoryProc.h> +#include <VrDecimatingSigProc.h> +#include <interleaver_fifo.h> +#include <gr_single_pole_iir.h> +#include <gr_mmse_fir_interpolator.h> +#include <atsci_slicer_agc.h> +#include <stdio.h> +#include <atsci_diag_output.h> + + +/*! + * \brief ATSC BitTimingLoop + * + * This class accepts a single real input and produces a single real output + */ + +class GrAtscBitTimingLoop : public VrDecimatingSigProc<float,float> { + + public: + + GrAtscBitTimingLoop (); + virtual ~GrAtscBitTimingLoop () { }; + + virtual const char *name () { return "GrAtscBitTimingLoop"; } + + virtual int forecast (VrSampleRange output, + VrSampleRange inputs[]); + + virtual int work (VrSampleRange output, void *o[], + VrSampleRange inputs[], void *i[]); + + // debug + void set_mu (double a_mu) { mu = a_mu; } + void set_no_update (bool a_no_update) { debug_no_update = a_no_update; } + void set_loop_filter_tap (double tap) { loop.set_taps (tap); } + void set_timing_rate (double rate) { d_timing_rate = rate; } + + protected: + + typedef float iType; + typedef float oType; + + iType produce_sample (const iType *in, unsigned int &index); + double filter_error (double e); + + VrSampleIndex next_input; + gr_mmse_fir_interpolator intr; + double w; // timing control word + double mu; // fractional delay + iType last_right; // last right hand sample + gr_single_pole_iir<double,double,double> loop; + bool debug_no_update;// debug + + double d_loop_filter_tap; + double d_timing_rate; + +#ifdef _BT_DIAG_OUTPUT_ + FILE *fp_loop; + FILE *fp_ps; +#endif +}; + +#endif // _GRATSCBITTIMINGLOOP_H_ diff --git a/gr-atsc/src/lib/GrAtscBitTimingLoop2.cc b/gr-atsc/src/lib/GrAtscBitTimingLoop2.cc new file mode 100644 index 000000000..25eadd36c --- /dev/null +++ b/gr-atsc/src/lib/GrAtscBitTimingLoop2.cc @@ -0,0 +1,173 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include <GrAtscBitTimingLoop2.h> +#include <algorithm> +#include <atsc_consts.h> +#include <stdio.h> +#include <assert.h> + + +static const int DEC = 2; // nominal decimation factor + +static const unsigned AVG_WINDOW_LEN = 256; +static const float TIMING_RATE_CONST = 1e-5; // FIXME document interaction with AGC + + +GrAtscBitTimingLoop2::GrAtscBitTimingLoop2 () + : VrDecimatingSigProc<float,float> (1, DEC), + next_input(0), dc (0.0002), mu (0.0), last_right(0), use_right_p (true) +{ + history = 100; // spare input samples in case we need them. + +#ifdef _BT_DIAG_OUTPUT_ + fp_loop = fopen ("loop.out", "w"); + if (fp_loop == 0){ + perror ("loop.out"); + exit (1); + } + + fp_ps = fopen ("ps.out", "w"); + if (fp_ps == 0){ + perror ("ps.out"); + exit (1); + } +#endif + +} + +// +// We are nominally a 2x decimator, but our actual rate varies slightly +// depending on the difference between the transmitter and receiver +// sampling clocks. Hence, we need to compute our input ranges +// explictly. + +int +GrAtscBitTimingLoop2::forecast(VrSampleRange output, + VrSampleRange inputs[]) { + /* dec:1 ratio with history */ + for(unsigned int i=0;i<numberInputs;i++) { + inputs[i].index=next_input; + inputs[i].size=output.size*decimation + history-1; + } + return 0; +} + +inline float +GrAtscBitTimingLoop2::filter_error (float e) +{ + return e; // identity function +} + +int +GrAtscBitTimingLoop2::work (VrSampleRange output, void *ao[], + VrSampleRange inputs[], void *ai[]) +{ + iType *in = ((iType **)ai)[0]; + oType *out = ((oType **)ao)[0]; + + // Force in-order computation of output stream. + // This is required because of our slightly variable decimation factor + sync (output.index); + + + // We are tasked with producing output.size output samples. + // We will consume approximately 2 * output.size input samples. + + + unsigned int ii = 0; // input index + unsigned int k; // output index + + // We look at a window of 3 samples that we call left (oldest), + // middle, right (newest). Each time through the loop, the previous + // right becomes the new left, and the new samples are middle and + // right. + // + // The basic game plan is to drive the average difference between + // right and left to zero. Given that all transitions are + // equiprobable (the data is white) and that the composite matched + // filter is symmetric (raised cosine) it turns out that in the + // average, if we drive that difference to zero, (implying that the + // average slope at the middle point is zero), we'll be sampling + // middle at the maximum or minimum point in the pulse. + + iType left; + iType middle; + iType right = last_right; + + for (k = 0; k < output.size; k++){ + + left = right; + + iType middle_raw = produce_sample (in, ii); + iType middle_dc = dc.filter (middle_raw); + middle = middle_raw - middle_dc; + + iType right_raw = produce_sample (in, ii); + iType right_dc = dc.filter (right_raw); + right = right_raw - right_dc; + + if (use_right_p) // produce our output + out[k] = right; + else + out[k] = middle; + } + +#ifdef _BT_DIAG_OUTPUT_ + float iodata[8]; + iodata[0] = 0; + iodata[1] = out[k]; + iodata[2] = 0; + iodata[3] = 0; + iodata[4] = 0; + iodata[5] = mu; + iodata[6] = 0; + iodata[7] = 0; // spare + if (fwrite (iodata, sizeof (iodata), 1, fp_loop) != 1){ + perror ("fwrite: loop"); + exit (1); + } +#endif + + + last_right = right; + next_input += ii; // update next_input so forecast can get us what we need + return output.size; +} + +/*! + * Produce samples equally spaced in time that are referenced + * to the transmitter's sample clock, not ours. + * + * See pp 523-527 of "Digital Communication Receivers", Meyr, + * Moeneclaey and Fechtel, Wiley, 1998. + */ + +GrAtscBitTimingLoop2::iType +GrAtscBitTimingLoop2::produce_sample (const iType *in, unsigned int &index) +{ + iType n = intr.interpolate (&in[index], mu); + + index++; + return n; +} + diff --git a/gr-atsc/src/lib/GrAtscBitTimingLoop2.h b/gr-atsc/src/lib/GrAtscBitTimingLoop2.h new file mode 100644 index 000000000..19422344d --- /dev/null +++ b/gr-atsc/src/lib/GrAtscBitTimingLoop2.h @@ -0,0 +1,80 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _GRATSCBITTIMINGLOOP2_H_ +#define _GRATSCBITTIMINGLOOP2_H_ + +#include <gr_nco.h> +#include <VrSigProc.h> +#include <VrHistoryProc.h> +#include <VrDecimatingSigProc.h> +#include <interleaver_fifo.h> +#include <gr_single_pole_iir.h> +#include <gr_mmse_fir_interpolator.h> + +/*! + * \brief ATSC BitTimingLoop + * + * This class accepts a single real input and produces a single real output + */ + +class GrAtscBitTimingLoop2 : public VrDecimatingSigProc<float,float> { + + public: + + GrAtscBitTimingLoop2 (); + virtual ~GrAtscBitTimingLoop2 () { }; + + virtual const char *name () { return "GrAtscBitTimingLoop2"; } + + virtual int forecast (VrSampleRange output, + VrSampleRange inputs[]); + + virtual int work (VrSampleRange output, void *o[], + VrSampleRange inputs[], void *i[]); + + // debug + void set_mu (float a_mu) { + assert (0 <= a_mu && a_mu <= 1.9); + use_right_p = a_mu < 1.0; + mu = a_mu - floor (a_mu); + cerr << "BTL2: mu: " << mu << " use_right_p: " << use_right_p << endl; + } + + protected: + + typedef float iType; + typedef float oType; + + iType produce_sample (const iType *in, unsigned int &index); + float filter_error (float e); + + VrSampleIndex next_input; + gr_single_pole_iir<float,float,float> dc; // used to estimate DC component + gr_mmse_fir_interpolator intr; + float mu; // fractional delay + iType last_right; // last right hand sample + + bool use_right_p; // ...else middle +}; + +#endif // _GRATSCBITTIMINGLOOP2_H_ diff --git a/gr-atsc/src/lib/GrAtscBitTimingLoop3.cc b/gr-atsc/src/lib/GrAtscBitTimingLoop3.cc new file mode 100644 index 000000000..2b21f2f0a --- /dev/null +++ b/gr-atsc/src/lib/GrAtscBitTimingLoop3.cc @@ -0,0 +1,106 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include <GrAtscBitTimingLoop3.h> +#include <cmath> +#include <cstdio> +#include <assert.h> + +using std::abs; + + +static const int NOUTPUTS = 2; + +GrAtscBitTimingLoop3::GrAtscBitTimingLoop3 (double ratio_of_rx_clock_to_symbol_freq) + : VrDecimatingSigProc<float,float> (NOUTPUTS, (int) rint (ratio_of_rx_clock_to_symbol_freq)), + d_interp (ratio_of_rx_clock_to_symbol_freq), d_next_input(0), + d_rx_clock_to_symbol_freq (ratio_of_rx_clock_to_symbol_freq) + +{ + assert (ratio_of_rx_clock_to_symbol_freq >= 1.8); // sanity check + + history = 1500; // spare input samples in case we need them. +} + +// +// We are nominally a 2x decimator, but our actual rate varies slightly +// depending on the difference between the transmitter and receiver +// sampling clocks. Hence, we need to compute our input ranges +// explictly. + +int +GrAtscBitTimingLoop3::forecast(VrSampleRange output, + VrSampleRange inputs[]) { + assert (numberInputs == 1); + + /* dec:1 ratio with history */ + inputs[0].index = d_next_input; + inputs[0].size = + ((unsigned long) (output.size * d_rx_clock_to_symbol_freq) + history - 1); + + return 0; +} + + +int +GrAtscBitTimingLoop3::work (VrSampleRange output, void *ao[], + VrSampleRange inputs[], void *ai[]) +{ + iType *in = ((iType **)ai)[0]; + oDataType *out_sample = ((oDataType **)ao)[0]; + oTagType *out_tag = ((oTagType **) ao)[1]; + + // Force in-order computation of output stream. + // This is required because of our slightly variable decimation factor + sync (output.index); + + // We are tasked with producing output.size output samples. + // We will consume approximately 2 * output.size input samples. + + int si = 0; // source index + unsigned int k; // output index + + float interp_sample; + int symbol_index; + double timing_adjustment = 0; + bool seg_locked; + oTagType tag; + + memset (&tag, 0, sizeof (tag)); + + for (k = 0; k < output.size; k++){ + + if (!d_interp.update (in, inputs[0].size, &si, timing_adjustment, &interp_sample)){ + fprintf (stderr, "GrAtscBitTimingLoop3: ran short on data...\n"); + break; + } + + d_sssr.update (interp_sample, &seg_locked, &symbol_index, &timing_adjustment); + out_sample[k] = interp_sample; + tag.valid = seg_locked; + tag.symbol_num = symbol_index; + out_tag[k] = tag; + } + + d_next_input += si; // update next_input so forecast can get us what we need + return k; +} diff --git a/gr-atsc/src/lib/GrAtscBitTimingLoop3.h b/gr-atsc/src/lib/GrAtscBitTimingLoop3.h new file mode 100644 index 000000000..299dc79d6 --- /dev/null +++ b/gr-atsc/src/lib/GrAtscBitTimingLoop3.h @@ -0,0 +1,72 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _GRATSCBITTIMINGLOOP3_H_ +#define _GRATSCBITTIMINGLOOP3_H_ + +#include <cstdio> +#include <VrDecimatingSigProc.h> +#include <atsci_diag_output.h> +#include <atsci_sssr.h> +#include <atsci_syminfo.h> + +/*! + * \brief ATSC BitTimingLoop3 + * + * This class accepts a single real input and produces two outputs, + * the raw symbol (float) and the tag (atsc_syminfo) + */ + +class GrAtscBitTimingLoop3 : public VrDecimatingSigProc<float,float> { + + public: + + GrAtscBitTimingLoop3 (double ratio_of_rx_clock_to_symbol_freq); + virtual ~GrAtscBitTimingLoop3 () { }; + + virtual const char *name () { return "GrAtscBitTimingLoop3"; } + + virtual int forecast (VrSampleRange output, + VrSampleRange inputs[]); + + virtual int work (VrSampleRange output, void *o[], + VrSampleRange inputs[], void *i[]); + + // debug (NOPs) + void set_mu (double a_mu) { } + void set_no_update (bool a_no_update) { } + void set_loop_filter_tap (double tap) { } + void set_timing_rate (double rate) { } + + protected: + + typedef float iType; + typedef float oDataType; + typedef atsc::syminfo oTagType; + + atsci_sssr d_sssr; + atsci_interpolator d_interp; + VrSampleIndex d_next_input; + double d_rx_clock_to_symbol_freq; +}; + +#endif // _GRATSCBITTIMINGLOOP3_H_ diff --git a/gr-atsc/src/lib/GrAtscConvert2xTo20.cc b/gr-atsc/src/lib/GrAtscConvert2xTo20.cc new file mode 100644 index 000000000..79811df38 --- /dev/null +++ b/gr-atsc/src/lib/GrAtscConvert2xTo20.cc @@ -0,0 +1,106 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include <GrAtscConvert2xTo20.h> +#include <atsc_consts.h> +#include <cmath> +#include <cstdio> + +static const int N_OUTPUTS = 1; +static const double DEC_RATIO = (2.0 * ATSC_SYMBOL_RATE) / 20e6; // ~ 1.076 + +GrAtscConvert2xTo20::GrAtscConvert2xTo20 () + : VrDecimatingSigProc<float,float> (N_OUTPUTS, (int) rint (DEC_RATIO)) +{ + d_next_input = 0; + d_frac_part = 0; + history = 2 * d_interp.ntaps (); // some slack +} + +GrAtscConvert2xTo20::~GrAtscConvert2xTo20 () +{ + // Nop +} + +void +GrAtscConvert2xTo20::pre_initialize () +{ + fprintf (stderr, + "GrAtscConvert2xTo20: input freq = %g\n", getInputSamplingFrequencyN(0)); + fprintf (stderr, + "GrAtscConvert2xTo20: DEC_RATIO = %g\n", DEC_RATIO); + fprintf (stderr, + "GrAtscConvert2xTo20: argument to setSamplingFrequency = %g\n", + getInputSamplingFrequencyN(0) / DEC_RATIO); + + int r; + r = setSamplingFrequency (getInputSamplingFrequencyN (0) / DEC_RATIO); + + fprintf (stderr, "GrAtscConvert2xTo20: result = %d\n", r); + + fprintf (stderr, "GrAtscConvert2xTo20: getSamplingFrequency = %g\n", + getSamplingFrequency ()); +} + + +int +GrAtscConvert2xTo20::forecast (VrSampleRange output, + VrSampleRange inputs[]) +{ + assert (numberInputs == 1); // I hate these free references to + // superclass's instance variables... + + inputs[0].index = d_next_input; + inputs[0].size = + ((long unsigned int) (output.size * DEC_RATIO) + history - 1); + + return 0; +} + +int +GrAtscConvert2xTo20::work (VrSampleRange output, void *ao[], + VrSampleRange inputs[], void *ai[]) +{ + float *in = ((float **) ai)[0]; + float *out = ((float **) ao)[0]; + + sync (output.index); + + unsigned long si = 0; // source index + unsigned long oi = 0; // output index + double frac_part = d_frac_part; + + for (oi = 0; oi < output.size; oi++){ + assert (si + d_interp.ntaps () < inputs[0].size); + out[oi] = d_interp.interpolate (&in[si], (1. - frac_part)); + + double s = frac_part + DEC_RATIO; + double float_incr = floor (s); + frac_part = s - float_incr; + int incr = (int) float_incr; + si += incr; + } + + d_next_input += si; + d_frac_part = frac_part; + return output.size; +} diff --git a/gr-atsc/src/lib/GrAtscConvert2xTo20.h b/gr-atsc/src/lib/GrAtscConvert2xTo20.h new file mode 100644 index 000000000..a8f802be4 --- /dev/null +++ b/gr-atsc/src/lib/GrAtscConvert2xTo20.h @@ -0,0 +1,50 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ +#ifndef _GRATSCCONVERT2XTO20_H_ +#define _GRATSCCONVERT2XTO20_H_ + +#include <VrDecimatingSigProc.h> +#include <gr_mmse_fir_interpolator.h> + +class GrAtscConvert2xTo20 : public VrDecimatingSigProc<float,float> { + gr_mmse_fir_interpolator d_interp; + double d_frac_part; + VrSampleIndex d_next_input; + +public: + GrAtscConvert2xTo20 (); + ~GrAtscConvert2xTo20 (); + + virtual const char *name () { return "GrAtscConvert2xTo20"; } + + virtual int forecast (VrSampleRange output, + VrSampleRange inputs[]); + + virtual int work (VrSampleRange output, void *o[], + VrSampleRange inputs[], void *i[]); + + void pre_initialize (); + int checkOutputSamplingFrequency(float) { return 0; } // bogus, but required + +}; + +#endif /* _GRATSCCONVERT2XTO20_H_ */ diff --git a/gr-atsc/src/lib/GrAtscDataSegToSoftDataSeg.cc b/gr-atsc/src/lib/GrAtscDataSegToSoftDataSeg.cc new file mode 100644 index 000000000..577330ec2 --- /dev/null +++ b/gr-atsc/src/lib/GrAtscDataSegToSoftDataSeg.cc @@ -0,0 +1,101 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include <GrAtscDataSegToSoftDataSeg.h> + +// typedefs for fundamental i/o types + +typedef atsc_data_segment iType; +typedef atsc_soft_data_segment oType; + +static const int NUMBER_OF_OUTPUTS = 1; // # of output streams (almost always one) + + +#define NELEM(x) (sizeof (x) / sizeof (x[0])) + +static void +map_to_soft_symbols (atsc_soft_data_segment &out, + const atsc_data_segment &in) +{ + for (unsigned int i = 0; i < NELEM (in.data); i++){ + out.data[i] = in.data[i] * 2 - 7; + } +} + + +GrAtscDataSegToSoftDataSeg::GrAtscDataSegToSoftDataSeg () + : VrHistoryProc<iType,oType> (NUMBER_OF_OUTPUTS) +{ + // 1 + number of extra input elements at which we look. This is + // used by the superclass's forecast routine to get us the correct + // range on our inputs. + // We're one-to-one input-to-output so set it to 1. + history = 1; + + // any other init here. +} + +GrAtscDataSegToSoftDataSeg::~GrAtscDataSegToSoftDataSeg () +{ + // Anything that isn't automatically cleaned up... +} + +/* + * This is the real work horse. In general this interface can handle + * multiple streams of input and output, but we almost always + * use a single input and output stream. + */ + +int +GrAtscDataSegToSoftDataSeg::work (VrSampleRange output, void *ao[], + VrSampleRange inputs[], void *ai[]) +{ + // If we have state that persists across invocations (e.g., we have + // instance variables that we modify), we must use the sync method + // to indicate to the scheduler that our output must be computed in + // order. This doesn't keep other things from being run in + // parallel, it just means that at any given time, there is only a + // single thread working this code, and that the scheduler will + // ensure that we are asked to produce output that is contiguous and + // that will be presented to us in order of increasing time. + + // sync (output.index); + + // construct some nicer i/o pointers to work with. + + iType *in = ((iType **) ai)[0]; + oType *out = ((oType **) ao)[0]; + + + // We must produce output.size units of output. + + for (unsigned int i = 0; i < output.size; i++){ + map_to_soft_symbols (out[i], in[i]); + out[i].pli = in[i].pli; + } + + // Return the number of units we produced. + // Note that for all intents and purposes, it is an error to + // produce less than you are asked for. + + return output.size; +} diff --git a/gr-atsc/src/lib/GrAtscDataSegToSoftDataSeg.h b/gr-atsc/src/lib/GrAtscDataSegToSoftDataSeg.h new file mode 100644 index 000000000..0cab046f2 --- /dev/null +++ b/gr-atsc/src/lib/GrAtscDataSegToSoftDataSeg.h @@ -0,0 +1,50 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _GRATSCDATASEGTOSOFTDATASEG_H_ +#define _GRATSCDATASEGTOSOFTDATASEG_H_ + +#include <VrHistoryProc.h> +#include <atsc_types.h> + +/*! + * \brief Debug glue routine (atsc_data_segment --> atsc_soft_data_segment) + */ + +class GrAtscDataSegToSoftDataSeg : public VrHistoryProc<atsc_data_segment, + atsc_soft_data_segment> +{ + +public: + + GrAtscDataSegToSoftDataSeg (); + ~GrAtscDataSegToSoftDataSeg (); + + const char *name () { return "GrAtscDataSegToSoftDataSeg"; } + + int work (VrSampleRange output, void *o[], + VrSampleRange inputs[], void *i[]); + +protected: +}; + +#endif /* _GRATSCDATASEGTOSOFTDATASEG_H_ */ diff --git a/gr-atsc/src/lib/GrAtscDeinterleaver.cc b/gr-atsc/src/lib/GrAtscDeinterleaver.cc new file mode 100644 index 000000000..2148e8aa7 --- /dev/null +++ b/gr-atsc/src/lib/GrAtscDeinterleaver.cc @@ -0,0 +1,92 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include <GrAtscDeinterleaver.h> + +// typedefs for fundamental i/o types + +typedef atsc_mpeg_packet_rs_encoded iType; +typedef atsc_mpeg_packet_rs_encoded oType; + +static const int NUMBER_OF_OUTPUTS = 1; // # of output streams (almost always one) + + +GrAtscDeinterleaver::GrAtscDeinterleaver () + : VrHistoryProc<iType,oType> (NUMBER_OF_OUTPUTS) +{ + // 1 + number of extra input elements at which we look. This is + // used by the superclass's forecast routine to get us the correct + // range on our inputs. + // We're one-to-one input-to-output so set it to 1. + history = 1; + + // any other init here. +} + +GrAtscDeinterleaver::~GrAtscDeinterleaver () +{ + // Anything that isn't automatically cleaned up... +} + +/* + * This is the real work horse. In general this interface can handle + * multiple streams of input and output, but we almost always + * use a single input and output stream. + */ + +int +GrAtscDeinterleaver::work (VrSampleRange output, void *ao[], + VrSampleRange inputs[], void *ai[]) +{ + // If we have state that persists across invocations (e.g., we have + // instance variables that we modify), we must use the sync method + // to indicate to the scheduler that our output must be computed in + // order. This doesn't keep other things from being run in + // parallel, it just means that at any given time, there is only a + // single thread working this code, and that the scheduler will + // ensure that we are asked to produce output that is contiguous and + // that will be presented to us in order of increasing time. + + // We have state, the current contents of the LFSR in the randomizer, hence + // we must use sync. + + sync (output.index); + + // construct some nicer i/o pointers to work with. + + iType *in = ((iType **) ai)[0]; + oType *out = ((oType **) ao)[0]; + + + // We must produce output.size units of output. + + for (unsigned int i = 0; i < output.size; i++){ + // pipeline info is handled in the primitive + deinterleaver.deinterleave (out[i], in[i]); + } + + // Return the number of units we produced. + // Note that for all intents and purposes, it is an error to + // produce less than you are asked for. + + return output.size; +} diff --git a/gr-atsc/src/lib/GrAtscDeinterleaver.h b/gr-atsc/src/lib/GrAtscDeinterleaver.h new file mode 100644 index 000000000..d4cb44e64 --- /dev/null +++ b/gr-atsc/src/lib/GrAtscDeinterleaver.h @@ -0,0 +1,51 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _GRATSCDEINTERLEAVER_H_ +#define _GRATSCDEINTERLEAVER_H_ + +#include <VrHistoryProc.h> +#include <atsc_types.h> +#include <atsci_data_interleaver.h> + +/*! + * \brief Deinterleave RS encoded ATSC data ( atsc_mpeg_packet_rs_encoded --> atsc_mpeg_packet_rs_encoded) + */ + +class GrAtscDeinterleaver : public VrHistoryProc<atsc_mpeg_packet_rs_encoded, atsc_mpeg_packet_rs_encoded> +{ + +public: + + GrAtscDeinterleaver (); + ~GrAtscDeinterleaver (); + + const char *name () { return "GrAtscDeinterleaver"; } + + int work (VrSampleRange output, void *o[], + VrSampleRange inputs[], void *i[]); + +protected: + atsci_data_deinterleaver deinterleaver; +}; + +#endif /* _GRATSCDEINTERLEAVER_H_ */ diff --git a/gr-atsc/src/lib/GrAtscDerandomizer.cc b/gr-atsc/src/lib/GrAtscDerandomizer.cc new file mode 100644 index 000000000..2cd7d39d0 --- /dev/null +++ b/gr-atsc/src/lib/GrAtscDerandomizer.cc @@ -0,0 +1,106 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include <GrAtscDerandomizer.h> + +// typedefs for fundamental i/o types + +typedef atsc_mpeg_packet_no_sync iType; +typedef atsc_mpeg_packet oType; + +static const int NUMBER_OF_OUTPUTS = 1; // # of output streams (almost always one) + + +GrAtscDerandomizer::GrAtscDerandomizer () + : VrHistoryProc<iType,oType> (NUMBER_OF_OUTPUTS) +{ + // 1 + number of extra input elements at which we look. This is + // used by the superclass's forecast routine to get us the correct + // range on our inputs. + // We're one-to-one input-to-output so set it to 1. + history = 1; + + // any other init here. +} + +GrAtscDerandomizer::~GrAtscDerandomizer () +{ + // Anything that isn't automatically cleaned up... +} + +/* + * This is the real work horse. In general this interface can handle + * multiple streams of input and output, but we almost always + * use a single input and output stream. + */ + +int +GrAtscDerandomizer::work (VrSampleRange output, void *ao[], + VrSampleRange inputs[], void *ai[]) +{ + // If we have state that persists across invocations (e.g., we have + // instance variables that we modify), we must use the sync method + // to indicate to the scheduler that our output must be computed in + // order. This doesn't keep other things from being run in + // parallel, it just means that at any given time, there is only a + // single thread working this code, and that the scheduler will + // ensure that we are asked to produce output that is contiguous and + // that will be presented to us in order of increasing time. + + // We have state, the current contents of the LFSR in the randomizer, hence + // we must use sync. + + sync (output.index); + + // construct some nicer i/o pointers to work with. + + iType *in = ((iType **) ai)[0]; + oType *out = ((oType **) ao)[0]; + + + // We must produce output.size units of output. + + for (unsigned int i = 0; i < output.size; i++){ + + assert (in[i].pli.regular_seg_p ()); + + if (in[i].pli.first_regular_seg_p ()) + rand.reset (); + + rand.derandomize (out[i], in[i]); + + // take a look at the transport error bit in the pipeline info + // and set bit as required + + if (in[i].pli.transport_error_p ()) + out[i].data[1] |= MPEG_TRANSPORT_ERROR_BIT; + else + out[i].data[1] &= ~MPEG_TRANSPORT_ERROR_BIT; + + } + + // Return the number of units we produced. + // Note that for all intents and purposes, it is an error to + // produce less than you are asked for. + + return output.size; +} diff --git a/gr-atsc/src/lib/GrAtscDerandomizer.h b/gr-atsc/src/lib/GrAtscDerandomizer.h new file mode 100644 index 000000000..22888c28b --- /dev/null +++ b/gr-atsc/src/lib/GrAtscDerandomizer.h @@ -0,0 +1,51 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _GRATSCDERANDOMIZER_H_ +#define _GRATSCDERANDOMIZER_H_ + +#include <VrHistoryProc.h> +#include <atsc_types.h> +#include <atsci_randomizer.h> + +/*! + * \brief Derandomize ATSC data (atsc_mpeg_packet_no_sync --> atsc_mpeg_packet) + */ + +class GrAtscDerandomizer : public VrHistoryProc<atsc_mpeg_packet_no_sync, atsc_mpeg_packet> +{ + +public: + + GrAtscDerandomizer (); + ~GrAtscDerandomizer (); + + const char *name () { return "GrAtscDerandomizer"; } + + virtual int work (VrSampleRange output, void *o[], + VrSampleRange inputs[], void *i[]); + +protected: + atsci_randomizer rand; +}; + +#endif /* _GRATSCDERANDOMIZER_H_ */ diff --git a/gr-atsc/src/lib/GrAtscEqualizer.cc b/gr-atsc/src/lib/GrAtscEqualizer.cc new file mode 100644 index 000000000..cd930adb8 --- /dev/null +++ b/gr-atsc/src/lib/GrAtscEqualizer.cc @@ -0,0 +1,135 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include <GrAtscEqualizer.h> +#include <atsci_equalizer.h> + +// typedefs for fundamental i/o types + +typedef float dataType; +typedef atsc::syminfo tagType; + +static const int NUMBER_OF_OUTPUTS = 2; // # of output streams + + +GrAtscEqualizer::GrAtscEqualizer (atsci_equalizer *equalizer) + : VrHistoryProc<dataType,dataType> (NUMBER_OF_OUTPUTS) +{ + // due to limitation of runtime, all inputs must be the same size + assert (sizeof (dataType) == sizeof (tagType)); + + d_equalizer = equalizer; + + // 1 + number of extra input elements at which we look. This is + // used by the superclass's forecast routine to get us the correct + // range on our inputs. + // + // Set this to the answer returned by the equalizer primitive we were passed. + history = d_equalizer->ntaps (); +} + +GrAtscEqualizer::~GrAtscEqualizer () +{ + // Anything that isn't automatically cleaned up... + + delete d_equalizer; +} + + +/* + * non-standard forecast routine that handles getting the correct amount of + * history for the data input as well as ensuring correct alignment of + * the data and tags. + */ + +int +GrAtscEqualizer::forecast (VrSampleRange output, + VrSampleRange inputs[]) +{ + assert (numberInputs == 2); + + int ntaps = d_equalizer->ntaps (); + int npretaps = d_equalizer->npretaps (); + + assert (ntaps >= 1); + assert (npretaps >= 0 && npretaps < ntaps); + + inputs[0].index = output.index; // the equalizer data + inputs[0].size = output.size + ntaps - 1; // history on data + + // FIXME if there's a problem, it's probably on the next line... + int offset = ntaps - npretaps - 1; + + assert (offset >= 0 && offset < ntaps); + + inputs[1].index = output.index + offset; // align equalizer tags + inputs[1].size = output.size; // N.B., no extra history on tags + + return 0; +} + +/* + * This is the real work horse. We consume 2 input streams + * and produce 2 output streams. + */ + +int +GrAtscEqualizer::work (VrSampleRange output, void *ao[], + VrSampleRange inputs[], void *ai[]) +{ + // assert (numberInputs == 2); + + // If we have state that persists across invocations (e.g., we have + // instance variables that we modify), we must use the sync method + // to indicate to the scheduler that our output must be computed in + // order. This doesn't keep other things from being run in + // parallel, it just means that at any given time, there is only a + // single thread working this code, and that the scheduler will + // ensure that we are asked to produce output that is contiguous and + // that will be presented to us in order of increasing time. + + // We have state, hence we must use sync. + + sync (output.index); + + // construct some nicer i/o pointers to work with. + + dataType *input_samples = ((dataType **) ai)[0]; + tagType *input_tags = ((tagType **) ai)[1]; + dataType *output_samples = ((dataType **) ao)[0]; + tagType *output_tags = ((tagType **) ao)[1]; + + + // peform the actual equalization + + d_equalizer->filter (input_samples, input_tags, + output_samples, output.size); + + // write the output tags + + for (unsigned int i = 0; i < output.size; i++) + output_tags[i] = input_tags[i]; + + // Return the number of units we produced. + + return output.size; +} diff --git a/gr-atsc/src/lib/GrAtscEqualizer.h b/gr-atsc/src/lib/GrAtscEqualizer.h new file mode 100644 index 000000000..46282bad9 --- /dev/null +++ b/gr-atsc/src/lib/GrAtscEqualizer.h @@ -0,0 +1,59 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _GRATSCEQUALIZER_H_ +#define _GRATSCEQUALIZER_H_ + +#include <VrHistoryProc.h> + +class atsci_equalizer; + +/*! + * \brief ATSC equalizer (float,syminfo --> float,syminfo) + * + * first inputs are data samples, second inputs are tags. + * first outputs are equalized data samples, second outputs are tags. + * + * tag values are defined in atsci_syminfo.h + */ + +class GrAtscEqualizer : public VrHistoryProc<float,float> +{ + +public: + + GrAtscEqualizer (atsci_equalizer *equalizer); + ~GrAtscEqualizer (); + + const char *name () { return "GrAtscEqualizer"; } + + int work (VrSampleRange output, void *o[], + VrSampleRange inputs[], void *i[]); + + // we've got a non-standard forecast routine + int forecast (VrSampleRange output, VrSampleRange inputs[]); + +protected: + atsci_equalizer *d_equalizer; +}; + +#endif /* _GRATSCEQUALIZER_H_ */ diff --git a/gr-atsc/src/lib/GrAtscFPLL.cc b/gr-atsc/src/lib/GrAtscFPLL.cc new file mode 100644 index 000000000..e6a7ff63f --- /dev/null +++ b/gr-atsc/src/lib/GrAtscFPLL.cc @@ -0,0 +1,150 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include <GrAtscFPLL.h> +#include <algorithm> +#include "fpll_btloop_coupling.h" + +/* + * I strongly suggest that you not mess with these... + * + * They are strongly coupled into the symbol timing code and + * their value also sets the level of the symbols going + * into the equalizer and viterbi decoder. + */ +static const float FPLL_AGC_REFERENCE = 2.5 * FPLL_BTLOOP_COUPLING_CONST; +static const float FPLL_AGC_RATE = 0.25e-6; + + +GrAtscFPLL::GrAtscFPLL (double a_initial_freq) + : VrSigProc (1, sizeof (iType), sizeof (oType)), + initial_phase(0), debug_no_update(false) +{ + initial_freq = a_initial_freq; + agc.set_rate (FPLL_AGC_RATE); + agc.set_reference (FPLL_AGC_REFERENCE); + + if (_FPLL_DIAG_OUTPUT_){ + fp = fopen ("fpll.out", "w"); + if (fp == 0){ + perror ("fpll.out"); + exit (1); + } + } + +} + +void +GrAtscFPLL::initialize () +{ + float Fs = getInputSamplingFrequencyN (0); + + float alpha = 1 - exp(-1.0 / Fs / 5e-6); + + afci.set_taps (alpha); + afcq.set_taps (alpha); + + nco.set_freq (initial_freq / Fs * 2 * M_PI); + nco.set_phase (initial_phase); +} + +int +GrAtscFPLL::work (VrSampleRange output, void *ao[], + VrSampleRange inputs[], void *ai[]) +{ + iType *in = ((iType **)ai)[0]; + oType *out = ((oType **)ao)[0]; + + unsigned int k; + + for (k = 0; k < output.size; k++){ + + float a_cos, a_sin; + + float input = agc.scale (in[k]); + + nco.step (); // increment phase + nco.sincos (a_sin, a_cos); // compute cos and sin + + float I = input * a_sin; + float Q = input * a_cos; + + out[k] = I; + + float filtered_I = afci.filter (I); + float filtered_Q = afcq.filter (Q); + + // phase detector + + float x = atan2 (filtered_Q, filtered_I); + + // avoid slamming filter with big transitions + + static const float limit = M_PI / 2; + + if (x > limit) + x = limit; + else if (x < -limit) + x = -limit; + + // static const float alpha = 0.037; // Max value + // static const float alpha = 0.005; // takes about 5k samples to pull in, stddev = 323 + // static const float alpha = 0.002; // takes about 15k samples to pull in, stddev = 69 + // or about 120k samples on noisy data, + static const float alpha = 0.001; + static const float beta = alpha * alpha / 4; + + + if (!debug_no_update){ + nco.adjust_phase (alpha * x); + nco.adjust_freq (beta * x); + } + + if (_FPLL_DIAG_OUTPUT_){ +#if 0 // lots of data... + float iodata[8]; + iodata[0] = nco.get_freq () * getSamplingFrequency () * (1.0 / (2 * M_PI)); + iodata[1] = in[k]; + iodata[2] = input; + iodata[3] = I; + iodata[4] = Q; + iodata[5] = filtered_I; + iodata[6] = filtered_Q; + iodata[7] = x; + if (fwrite (iodata, sizeof (iodata), 1, fp) != 1){ + perror ("fwrite: fpll"); + exit (1); + } +#else // just the frequency + float iodata[1]; + iodata[0] = nco.get_freq () * getSamplingFrequency () * (1.0 / (2 * M_PI)); + if (fwrite (iodata, sizeof (iodata), 1, fp) != 1){ + perror ("fwrite: fpll"); + exit (1); + } +#endif + } + } + + return output.size; +} + diff --git a/gr-atsc/src/lib/GrAtscFPLL.h b/gr-atsc/src/lib/GrAtscFPLL.h new file mode 100644 index 000000000..0868f9a0a --- /dev/null +++ b/gr-atsc/src/lib/GrAtscFPLL.h @@ -0,0 +1,88 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + + +#ifndef _GRATSCFPLL_H_ +#define _GRATSCFPLL_H_ + +#include <gr_nco.h> +#include <gr_iir.h> +#include <gr_single_pole_iir.h> +#include <gr_agc.h> +#include <VrSigProc.h> +#include <stdio.h> +#include <atsci_diag_output.h> + +/*! + * \brief ATSC FPLL (2nd Version) + * + * Used as follows: + * float float + * A/D --> GrFIRfilterFFF ----> GrAtscFPLL ----> + * + * We use GrFIRfilterFFF to bandpass filter the signal of interest. + * + * This class accepts a single real input and produces a single real output + */ + +class GrAtscFPLL : public VrSigProc { + protected: + + typedef float iType; + typedef float oType; + + public: + + GrAtscFPLL (double a_initial_freq); + virtual ~GrAtscFPLL () {} + + virtual const char *name () { return "GrAtscFPLL"; } + + virtual void initialize (); + + virtual int work (VrSampleRange output, void *o[], + VrSampleRange inputs[], void *i[]); + + + // diagnostic routines + void set_initial_phase (double phase) { initial_phase = phase; } // radians + void set_no_update (bool a_no_update) { debug_no_update = a_no_update; } + + + protected: + + double initial_freq; + double initial_phase; + bool debug_no_update; + gr_nco<float,float> nco; + gr_agc agc; // automatic gain control + gr_single_pole_iir<float,float,float> afci; + gr_single_pole_iir<float,float,float> afcq; + +#ifdef _FPLL_DIAG_OUTPUT_ + FILE *fp; +#endif + +}; + + +#endif // _GRATSCFPLL_H_ diff --git a/gr-atsc/src/lib/GrAtscFieldSyncChecker.cc b/gr-atsc/src/lib/GrAtscFieldSyncChecker.cc new file mode 100644 index 000000000..18b81ac20 --- /dev/null +++ b/gr-atsc/src/lib/GrAtscFieldSyncChecker.cc @@ -0,0 +1,101 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include <GrAtscFieldSyncChecker.h> +#include <create_atsci_fs_checker.h> +#include <atsci_fs_checker.h> + +// typedefs for fundamental i/o types + +typedef float iDataType; +typedef atsc::syminfo iTagType; +typedef float oDataType; +typedef atsc::syminfo oTagType; + +static const int NUMBER_OF_OUTPUTS = 2; // # of output streams + + +GrAtscFieldSyncChecker::GrAtscFieldSyncChecker () + : VrHistoryProc<iDataType,oDataType> (NUMBER_OF_OUTPUTS) +{ + // tags and data must be same size due to limitation of runtime + assert (sizeof (iDataType) == sizeof (iTagType)); + assert (sizeof (oDataType) == sizeof (oTagType)); + + // 1 + number of extra input elements at which we look. This is + // used by the superclass's forecast routine to get us the correct + // range on our inputs. + // We're one-to-one input-to-output so set it to 1. + history = 1; + + d_fsc = create_atsci_fs_checker (); +} + +GrAtscFieldSyncChecker::~GrAtscFieldSyncChecker () +{ + // Anything that isn't automatically cleaned up... + + delete d_fsc; +} + +/* + * This is the real work horse. In general this interface can handle + * multiple streams of input and output, but we almost always + * use a single input and output stream. + */ + +int +GrAtscFieldSyncChecker::work (VrSampleRange output, void *ao[], + VrSampleRange inputs[], void *ai[]) +{ + // If we have state that persists across invocations (e.g., we have + // instance variables that we modify), we must use the sync method + // to indicate to the scheduler that our output must be computed in + // order. This doesn't keep other things from being run in + // parallel, it just means that at any given time, there is only a + // single thread working this code, and that the scheduler will + // ensure that we are asked to produce output that is contiguous and + // that will be presented to us in order of increasing time. + + // We have state, hence we must use sync. + + sync (output.index); + + // construct some nicer i/o pointers to work with. + + iDataType *sample_in = ((iDataType **) ai)[0]; + iTagType *tag_in = ((iTagType **) ai)[1]; + oDataType *sample_out = ((oDataType **) ao)[0]; + oTagType *tag_out = ((oTagType **) ao)[1]; + + // We must produce output.size units of output. + + for (unsigned int i = 0; i < output.size; i++){ + d_fsc->filter (sample_in[i], tag_in[i], &sample_out[i], &tag_out[i]); + } + + // Return the number of units we produced. + // Note that for all intents and purposes, it is an error to + // produce less than you are asked for. + + return output.size; +} diff --git a/gr-atsc/src/lib/GrAtscFieldSyncChecker.h b/gr-atsc/src/lib/GrAtscFieldSyncChecker.h new file mode 100644 index 000000000..f64ebcb6a --- /dev/null +++ b/gr-atsc/src/lib/GrAtscFieldSyncChecker.h @@ -0,0 +1,54 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _GRATSCFIELDSYNCCHECKER_H_ +#define _GRATSCFIELDSYNCCHECKER_H_ + +#include <VrHistoryProc.h> + +class atsci_fs_checker; + +/*! + * \brief ATSC field sync checker (float,syminfo --> float,syminfo) + * + * first output is delayed version of input. + * second output is set of tags, one-for-one with first output. + */ + +class GrAtscFieldSyncChecker : public VrHistoryProc<float,float> +{ + +public: + + GrAtscFieldSyncChecker (); + ~GrAtscFieldSyncChecker (); + + const char *name () { return "GrAtscFieldSyncChecker"; } + + int work (VrSampleRange output, void *o[], + VrSampleRange inputs[], void *i[]); + +protected: + atsci_fs_checker *d_fsc; +}; + +#endif /* _GRATSCFIELDSYNCCHECKER_H_ */ diff --git a/gr-atsc/src/lib/GrAtscFieldSyncCorrelator.cc b/gr-atsc/src/lib/GrAtscFieldSyncCorrelator.cc new file mode 100644 index 000000000..23eabe8e7 --- /dev/null +++ b/gr-atsc/src/lib/GrAtscFieldSyncCorrelator.cc @@ -0,0 +1,95 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include <GrAtscFieldSyncCorrelator.h> +#include <create_atsci_fs_correlator.h> +#include <atsci_fs_correlator.h> + +// typedefs for fundamental i/o types + +typedef float iType; +typedef float oType; + +static const int NUMBER_OF_OUTPUTS = 2; // # of output streams + + +GrAtscFieldSyncCorrelator::GrAtscFieldSyncCorrelator () + : VrHistoryProc<iType,oType> (NUMBER_OF_OUTPUTS) +{ + // 1 + number of extra input elements at which we look. This is + // used by the superclass's forecast routine to get us the correct + // range on our inputs. + // We're one-to-one input-to-output so set it to 1. + history = 1; + + d_fsc = create_atsci_fs_correlator (); +} + +GrAtscFieldSyncCorrelator::~GrAtscFieldSyncCorrelator () +{ + // Anything that isn't automatically cleaned up... + + delete d_fsc; +} + +/* + * This is the real work horse. In general this interface can handle + * multiple streams of input and output, but we almost always + * use a single input and output stream. + */ + +int +GrAtscFieldSyncCorrelator::work (VrSampleRange output, void *ao[], + VrSampleRange inputs[], void *ai[]) +{ + // If we have state that persists across invocations (e.g., we have + // instance variables that we modify), we must use the sync method + // to indicate to the scheduler that our output must be computed in + // order. This doesn't keep other things from being run in + // parallel, it just means that at any given time, there is only a + // single thread working this code, and that the scheduler will + // ensure that we are asked to produce output that is contiguous and + // that will be presented to us in order of increasing time. + + // We have state, hence we must use sync. + + sync (output.index); + + // construct some nicer i/o pointers to work with. + + iType *in = ((iType **) ai)[0]; + oType *sample_out = ((oType **) ao)[0]; + oType *tag_out = ((oType **) ao)[1]; + + + // We must produce output.size units of output. + + for (unsigned int i = 0; i < output.size; i++){ + d_fsc->filter (in[i], &sample_out[i], &tag_out[i]); + } + + // Return the number of units we produced. + // Note that for all intents and purposes, it is an error to + // produce less than you are asked for. + + return output.size; +} diff --git a/gr-atsc/src/lib/GrAtscFieldSyncCorrelator.h b/gr-atsc/src/lib/GrAtscFieldSyncCorrelator.h new file mode 100644 index 000000000..78ff9c666 --- /dev/null +++ b/gr-atsc/src/lib/GrAtscFieldSyncCorrelator.h @@ -0,0 +1,56 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _GRATSCFIELDSYNCCORRELATOR_H_ +#define _GRATSCFIELDSYNCCORRELATOR_H_ + +#include <VrHistoryProc.h> + +class atsci_fs_correlator; + +/*! + * \brief ATSC field sync correlator (float --> float,float) + * + * first output is delayed version of input. + * second output is set of tags, one-for-one with first output. + * + * tag values are defined in atsci_sync_tag.h + */ + +class GrAtscFieldSyncCorrelator : public VrHistoryProc<float,float> +{ + +public: + + GrAtscFieldSyncCorrelator (); + ~GrAtscFieldSyncCorrelator (); + + const char *name () { return "GrAtscFieldSyncCorrelator"; } + + int work (VrSampleRange output, void *o[], + VrSampleRange inputs[], void *i[]); + +protected: + atsci_fs_correlator *d_fsc; +}; + +#endif /* _GRATSCFIELDSYNCCORRELATOR_H_ */ diff --git a/gr-atsc/src/lib/GrAtscFieldSyncDemux.cc b/gr-atsc/src/lib/GrAtscFieldSyncDemux.cc new file mode 100644 index 000000000..04a39bd06 --- /dev/null +++ b/gr-atsc/src/lib/GrAtscFieldSyncDemux.cc @@ -0,0 +1,173 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include <cmath> +#include <GrAtscFieldSyncDemux.h> +#include <atsc_consts.h> +#include <atsc_types.h> +#include <atsci_syminfo.h> +#include <stdio.h> +#include <assert.h> + +using std::abs; + +static const int DEC = ATSC_DATA_SEGMENT_LENGTH; // nominal decimation factor + +GrAtscFieldSyncDemux::GrAtscFieldSyncDemux () + : VrDecimatingSigProc<float,atsc_soft_data_segment> (1, DEC), + d_locked (false), d_in_field2(true), d_segment_number(0), d_next_input(0), + d_lost_index (0) +{ + history = 2 * ATSC_DATA_SEGMENT_LENGTH; // spare input samples in case we need them. +} + +GrAtscFieldSyncDemux::~GrAtscFieldSyncDemux () +{ +} + +int +GrAtscFieldSyncDemux::forecast (VrSampleRange output, + VrSampleRange inputs[]) { + /* dec:1 ratio with history */ + + assert (numberInputs == 2); + + for (unsigned int i = 0; i < numberInputs; i++) { + inputs[i].index = d_next_input; + inputs[i].size = output.size * decimation + history - 1; + } + return 0; +} + +inline static bool +tag_is_seg_sync_or_field_sync (atsc::syminfo tag) +{ + return tag.symbol_num == 0 && tag.valid; +} + +int +GrAtscFieldSyncDemux::work (VrSampleRange output, void *ao[], + VrSampleRange inputs[], void *ai[]) +{ + float *input_samples = (float *) ai[0]; + atsc::syminfo *input_tags = (atsc::syminfo *) ai[1]; + atsc_soft_data_segment *out = ((atsc_soft_data_segment **)ao)[0]; + + sync (output.index); + + unsigned int ii = 0; // input index + + // Are we in sync? + if (!tag_is_seg_sync_or_field_sync (input_tags[0])){ // No ... + + if (d_locked){ + d_locked = false; + d_lost_index = inputs[0].index + ii; + cerr << "GrAtscFieldSyncDemux: lost sync at " + << d_lost_index << endl; + } + + // ... search for beginning of a field sync + + // cerr << "GrAtscFieldSyncDemux: searching for sync at " + // << inputs[0].index + ii << endl; + + for (ii = 1; ii < inputs[0].size; ii++){ + if (atsc::tag_is_start_field_sync (input_tags[ii])){ + // found one + d_locked = true; + + const char *str; + if (atsc::tag_is_start_field_sync_1 (input_tags[ii])) + str = "FIELD-1"; + else if (atsc::tag_is_start_field_sync_2 (input_tags[ii])) + str = "FIELD-2"; + else + str = "SEGMENT"; + + cerr << "GrAtscFieldSyncDemux: synced (" << str << ") at " + << inputs[0].index + ii + << " [delta = " << inputs[0].index + ii - d_lost_index + << "]\n"; + + d_next_input += ii; // update for forecast + return 0; // no work completed so far + } + } + // no non-NORMAL tag found + d_next_input += ii; // update for forecast + return 0; // no work completed so far + } + + // We are in sync. Produce output... + + unsigned int k = 0; // output index + + while (k < output.size){ + + if (inputs[0].size - ii < (unsigned) ATSC_DATA_SEGMENT_LENGTH){ + // We're out of input data. + cerr << "GrAtscFieldSyncDemux: ran out of input data\n"; + d_next_input += ii; // update for forecast + return k; // return amount of work completed so far + } + + if (!tag_is_seg_sync_or_field_sync (input_tags[ii])){ + // lost sync... + // cerr << "GrAtscFieldSyncDemux: lost sync at " + // << inputs[0].index + ii << endl; + + d_next_input += ii; // update for forecast + return k; // return amount of work completed so far + } + + if (atsc::tag_is_start_field_sync_1 (input_tags[ii])){ + d_in_field2 = false; + d_segment_number = 0; + ii += ATSC_DATA_SEGMENT_LENGTH; // skip over field sync + continue; + } + + if (atsc::tag_is_start_field_sync_2 (input_tags[ii])){ + d_in_field2 = true; + d_segment_number = 0; + ii += ATSC_DATA_SEGMENT_LENGTH; // skip over field sync + continue; + } + + if (d_segment_number >= ATSC_DSEGS_PER_FIELD){ + // something's wrong... + cerr << "GrAtscFieldSyncDemux: segment number overflow\n"; + d_segment_number = 0; + } + + out[k].pli.set_regular_seg (d_in_field2, d_segment_number++); + for (int jj = 0; jj < ATSC_DATA_SEGMENT_LENGTH; jj++) + out[k].data[jj] = input_samples[ii + jj]; + ii += ATSC_DATA_SEGMENT_LENGTH; + k++; + } + + d_next_input += ii; // update for forecast + return k; // return amount of work completed +} + diff --git a/gr-atsc/src/lib/GrAtscFieldSyncDemux.h b/gr-atsc/src/lib/GrAtscFieldSyncDemux.h new file mode 100644 index 000000000..2eb6084b5 --- /dev/null +++ b/gr-atsc/src/lib/GrAtscFieldSyncDemux.h @@ -0,0 +1,60 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _GRATSCFIELDSYNCDEMUX_H_ +#define _GRATSCFIELDSYNCDEMUX_H_ + +#include <VrDecimatingSigProc.h> +#include <atsc_types.h> + +/*! + * \brief ATSC Field Sync Demux + * + * This class accepts 1 stream of floats (data), and 1 stream of tags (syminfo). + * It outputs one stream of atsc_soft_data_segment packets + */ + +class GrAtscFieldSyncDemux : public VrDecimatingSigProc<float,atsc_soft_data_segment> { + + public: + + GrAtscFieldSyncDemux (); + virtual ~GrAtscFieldSyncDemux (); + + virtual const char *name () { return "GrAtscFieldSyncDemux"; } + + virtual int forecast (VrSampleRange output, + VrSampleRange inputs[]); + + virtual int work (VrSampleRange output, void *o[], + VrSampleRange inputs[], void *i[]); + + protected: + + bool d_locked; + bool d_in_field2; + int d_segment_number; + VrSampleIndex d_next_input; + VrSampleIndex d_lost_index; // diagnostic fluff +}; + +#endif // _GRATSCFIELDSYNCDEMUX_H_ diff --git a/gr-atsc/src/lib/GrAtscFieldSyncMux.cc b/gr-atsc/src/lib/GrAtscFieldSyncMux.cc new file mode 100644 index 000000000..42921952a --- /dev/null +++ b/gr-atsc/src/lib/GrAtscFieldSyncMux.cc @@ -0,0 +1,246 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include <GrAtscFieldSyncMux.h> +#include <atsci_pnXXX.h> + + +// typedefs for fundamental i/o types + +typedef atsc_data_segment iType; +typedef atsc_data_segment oType; + +static const int NUMBER_OF_OUTPUTS = 1; // # of output streams (almost always one) + +static const int N_SAVED_SYMBOLS = GrAtscFieldSyncMux::N_SAVED_SYMBOLS; + +static void +init_field_sync_common (unsigned char *p, int mask, + const unsigned char saved_symbols[N_SAVED_SYMBOLS]) +{ + static const unsigned char bin_map[2] = { 1, 6 }; // map binary values to 1 of 8 levels + + int i = 0; + + p[i++] = bin_map[1]; // data segment sync pulse + p[i++] = bin_map[0]; + p[i++] = bin_map[0]; + p[i++] = bin_map[1]; + + for (int j = 0; j < 511; j++) // PN511 + p[i++] = bin_map[atsc_pn511[j]]; + + for (int j = 0; j < 63; j++) // PN63 + p[i++] = bin_map[atsc_pn63[j]]; + + for (int j = 0; j < 63; j++) // PN63, toggled on field 2 + p[i++] = bin_map[atsc_pn63[j] ^ mask]; + + for (int j = 0; j < 63; j++) // PN63 + p[i++] = bin_map[atsc_pn63[j]]; + + p[i++] = bin_map[0]; // 24 bits of VSB8 mode identifiera + p[i++] = bin_map[0]; + p[i++] = bin_map[0]; + p[i++] = bin_map[0]; + + p[i++] = bin_map[1]; + p[i++] = bin_map[0]; + p[i++] = bin_map[1]; + p[i++] = bin_map[0]; + + p[i++] = bin_map[0]; + p[i++] = bin_map[1]; + p[i++] = bin_map[0]; + p[i++] = bin_map[1]; + + p[i++] = bin_map[1]; + p[i++] = bin_map[1]; + p[i++] = bin_map[1]; + p[i++] = bin_map[1]; + + p[i++] = bin_map[0]; + p[i++] = bin_map[1]; + p[i++] = bin_map[0]; + p[i++] = bin_map[1]; + + p[i++] = bin_map[1]; + p[i++] = bin_map[0]; + p[i++] = bin_map[1]; + p[i++] = bin_map[0]; + + + for (int j = 0; j < 92; j++) // 92 more bits + p[i++] = bin_map[atsc_pn63[j % 63]]; + + // now copy the last 12 symbols of the previous segment + + for (int j = 0; j < N_SAVED_SYMBOLS; j++) + p[i++] = saved_symbols[j]; + + assert (i == ATSC_DATA_SEGMENT_LENGTH); +} + +inline static void +init_field_sync_1 (atsc_data_segment *s, + const unsigned char saved_symbols[N_SAVED_SYMBOLS]) +{ + init_field_sync_common (&s->data[0], 0, saved_symbols); +} + +inline static void +init_field_sync_2 (atsc_data_segment *s, + const unsigned char saved_symbols[N_SAVED_SYMBOLS]) + +{ + init_field_sync_common (&s->data[0], 1, saved_symbols); +} + +static void +save_last_symbols (unsigned char saved_symbols[N_SAVED_SYMBOLS], + const atsc_data_segment &seg) +{ + for (int i = 0; i < N_SAVED_SYMBOLS; i++) + saved_symbols[i] = seg.data[i + ATSC_DATA_SEGMENT_LENGTH - N_SAVED_SYMBOLS]; +} + + +inline static bool +last_regular_seg_p (const plinfo &pli) +{ + return pli.regular_seg_p () && (pli.segno () == ATSC_DSEGS_PER_FIELD - 1); +} + + +GrAtscFieldSyncMux::GrAtscFieldSyncMux () + : VrHistoryProc<iType,oType> (NUMBER_OF_OUTPUTS), + d_current_index (0), d_already_output_field_sync (false) +{ + // 1 + number of extra input elements at which we look. This is + // used by the superclass's forecast routine to get us the correct + // range on our inputs. + history = 1; + + // any other init here. +} + +GrAtscFieldSyncMux::~GrAtscFieldSyncMux () +{ + // Anything that isn't automatically cleaned up... +} + +void +GrAtscFieldSyncMux::pre_initialize () +{ + // we jack our output sampling frequency up to account for inserted field syncs + setSamplingFrequency (getInputSamplingFrequencyN (0) * 313./312.); +} + +/* + * we need a non-standard version of forecast because our output isn't + * exactly 1:1 with our input. + */ + +int +GrAtscFieldSyncMux::forecast (VrSampleRange output, VrSampleRange inputs[]) +{ + for(unsigned int i = 0; i < numberInputs; i++) { + inputs[i].index = d_current_index; + inputs[i].size = output.size; + } + return 0; +} + +/* + * This is the real work horse. In general this interface can handle + * multiple streams of input and output, but we almost always + * use a single input and output stream. + */ +int +GrAtscFieldSyncMux::work (VrSampleRange output, void *ao[], + VrSampleRange inputs[], void *ai[]) +{ + // If we have state that persists across invocations (e.g., we have + // instance variables that we modify), we must use the sync method + // to indicate to the scheduler that our output must be computed in + // order. This doesn't keep other things from being run in + // parallel, it just means that at any given time, there is only a + // single thread working this code, and that the scheduler will + // ensure that we are asked to produce output that is contiguous and + // that will be presented to us in order of increasing time. + + // We have state, hence we must use sync. + + sync (output.index); + + // construct some nicer i/o pointers to work with. + + iType *in = ((iType **) ai)[0]; + oType *out = ((oType **) ao)[0]; + + + // We must produce output.size units of output. + + unsigned int index = 0; + for (unsigned int outdex = 0; outdex < output.size; outdex++){ + + assert (in[index].pli.regular_seg_p ()); + + if (!in[index].pli.first_regular_seg_p ()){ + out[outdex] = in[index]; // just copy in to out + + if (last_regular_seg_p (in[index].pli)) + save_last_symbols (d_saved_symbols, in[index]); + + index++; + } + else { // first_regular_seg_p + if (!d_already_output_field_sync){ + // write out field sync... + atsc_data_segment field_sync; + + if (in[index].pli.in_field1_p ()) + init_field_sync_1 (&field_sync, d_saved_symbols); + else + init_field_sync_2 (&field_sync, d_saved_symbols); + + // note that index doesn't advance in this branch + out[outdex] = field_sync; + d_already_output_field_sync = true; + } + else { + // already output field sync, now output first regular segment + out[outdex] = in[index]; + index++; + d_already_output_field_sync = false; + } + } + } + + d_current_index += index; + + // Return the number of units we produced. + // Note that for all intents and purposes, it is an error to + // produce less than you are asked for. + + return output.size; +} diff --git a/gr-atsc/src/lib/GrAtscFieldSyncMux.h b/gr-atsc/src/lib/GrAtscFieldSyncMux.h new file mode 100644 index 000000000..5235603ce --- /dev/null +++ b/gr-atsc/src/lib/GrAtscFieldSyncMux.h @@ -0,0 +1,58 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _GRATSCFIELDSYNCMUX_H_ +#define _GRATSCFIELDSYNCMUX_H_ + +#include <VrHistoryProc.h> +#include <atsc_types.h> + +/*! + * \brief Insert ATSC Field Syncs as required (atsc_data_segment --> atsc_data_segment) + */ + +class GrAtscFieldSyncMux : public VrHistoryProc<atsc_data_segment, atsc_data_segment> +{ + +public: + + GrAtscFieldSyncMux (); + ~GrAtscFieldSyncMux (); + + const char *name () { return "GrAtscFieldSyncMux"; } + + int work (VrSampleRange output, void *o[], + VrSampleRange inputs[], void *i[]); + + int forecast (VrSampleRange output, VrSampleRange inputs[]); + + void pre_initialize (); + + static const int N_SAVED_SYMBOLS = 12; + +protected: + VrSampleIndex d_current_index; + bool d_already_output_field_sync; + unsigned char d_saved_symbols[N_SAVED_SYMBOLS]; +}; + +#endif /* _GRATSCFIELDSYNCMUX_H_ */ diff --git a/gr-atsc/src/lib/GrAtscInterleaver.cc b/gr-atsc/src/lib/GrAtscInterleaver.cc new file mode 100644 index 000000000..e766dcfca --- /dev/null +++ b/gr-atsc/src/lib/GrAtscInterleaver.cc @@ -0,0 +1,101 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include <GrAtscInterleaver.h> + +// typedefs for fundamental i/o types + +typedef atsc_mpeg_packet_rs_encoded iType; +typedef atsc_mpeg_packet_rs_encoded oType; + +static const int NUMBER_OF_OUTPUTS = 1; // # of output streams (almost always one) + + +GrAtscInterleaver::GrAtscInterleaver () + : VrHistoryProc<iType,oType> (NUMBER_OF_OUTPUTS) +{ + // 1 + number of extra input elements at which we look. This is + // used by the superclass's forecast routine to get us the correct + // range on our inputs. + // We're one-to-one input-to-output so set it to 1. + history = 1; + + // any other init here. +} + +GrAtscInterleaver::~GrAtscInterleaver () +{ + // Anything that isn't automatically cleaned up... +} + +/* + * This is the real work horse. In general this interface can handle + * multiple streams of input and output, but we almost always + * use a single input and output stream. + */ + +int +GrAtscInterleaver::work (VrSampleRange output, void *ao[], + VrSampleRange inputs[], void *ai[]) +{ + // If we have state that persists across invocations (e.g., we have + // instance variables that we modify), we must use the sync method + // to indicate to the scheduler that our output must be computed in + // order. This doesn't keep other things from being run in + // parallel, it just means that at any given time, there is only a + // single thread working this code, and that the scheduler will + // ensure that we are asked to produce output that is contiguous and + // that will be presented to us in order of increasing time. + + // We have state, the current contents of the FIFOs, hence + // we must use sync. + + sync (output.index); + + // construct some nicer i/o pointers to work with. + + iType *in = ((iType **) ai)[0]; + oType *out = ((oType **) ao)[0]; + + +#if 0 + cerr << "@@@ GrAtscInterleaver: output.index = " << output.index + << " output.size = " << output.size + << " sum = " << output.index + output.size + << " \t[out = " << out << "]" + << endl; +#endif + + // We must produce output.size units of output. + + for (unsigned int i = 0; i < output.size; i++){ + // pipeline info is handled in the primitive + interleaver.interleave (out[i], in[i]); + } + + + // Return the number of units we produced. + // Note that for all intents and purposes, it is an error to + // produce less than you are asked for. + + return output.size; +} diff --git a/gr-atsc/src/lib/GrAtscInterleaver.h b/gr-atsc/src/lib/GrAtscInterleaver.h new file mode 100644 index 000000000..26bf64369 --- /dev/null +++ b/gr-atsc/src/lib/GrAtscInterleaver.h @@ -0,0 +1,51 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _GRATSCINTERLEAVER_H_ +#define _GRATSCINTERLEAVER_H_ + +#include <VrHistoryProc.h> +#include <atsc_types.h> +#include <atsci_data_interleaver.h> + +/*! + * \brief Interleave RS encoded ATSC data ( atsc_mpeg_packet_rs_encoded --> atsc_mpeg_packet_rs_encoded) + */ + +class GrAtscInterleaver : public VrHistoryProc<atsc_mpeg_packet_rs_encoded, atsc_mpeg_packet_rs_encoded> +{ + +public: + + GrAtscInterleaver (); + ~GrAtscInterleaver (); + + const char *name () { return "GrAtscInterleaver"; } + + int work (VrSampleRange output, void *o[], + VrSampleRange inputs[], void *i[]); + +protected: + atsci_data_interleaver interleaver; +}; + +#endif /* _GRATSCINTERLEAVER_H_ */ diff --git a/gr-atsc/src/lib/GrAtscRSDecoder.cc b/gr-atsc/src/lib/GrAtscRSDecoder.cc new file mode 100644 index 000000000..58a692975 --- /dev/null +++ b/gr-atsc/src/lib/GrAtscRSDecoder.cc @@ -0,0 +1,81 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include <GrAtscRSDecoder.h> + +// typedefs for fundamental i/o types + +typedef atsc_mpeg_packet_rs_encoded iType; +typedef atsc_mpeg_packet_no_sync oType; + +static const int NUMBER_OF_OUTPUTS = 1; // # of output streams (almost always one) + + +GrAtscRSDecoder::GrAtscRSDecoder () + : VrHistoryProc<iType,oType> (NUMBER_OF_OUTPUTS) +{ + // 1 + number of extra input elements at which we look. This is + // used by the superclass's forecast routine to get us the correct + // range on our inputs. + // We're one-to-one input-to-output so set it to 1. + history = 1; + + // any other init here. +} + +GrAtscRSDecoder::~GrAtscRSDecoder () +{ + // Anything that isn't automatically cleaned up... +} + +/* + * This is the real work horse. In general this interface can handle + * multiple streams of input and output, but we almost always + * use a single input and output stream. + */ + +int +GrAtscRSDecoder::work (VrSampleRange output, void *ao[], + VrSampleRange inputs[], void *ai[]) +{ + // construct some nicer i/o pointers to work with. + + iType *in = ((iType **) ai)[0]; + oType *out = ((oType **) ao)[0]; + + + // We must produce output.size units of output. + + for (unsigned int i = 0; i < output.size; i++){ + assert (in[i].pli.regular_seg_p ()); + out[i].pli = in[i].pli; // copy pipeline info + + int nerrors_not_corrected = rs_decoder.decode (out[i], in[i]); + out[i].pli.set_transport_error (nerrors_not_corrected == -1); + } + + // Return the number of units we produced. + // Note that for all intents and purposes, it is an error to + // produce less than you are asked for. + + return output.size; +} diff --git a/gr-atsc/src/lib/GrAtscRSDecoder.h b/gr-atsc/src/lib/GrAtscRSDecoder.h new file mode 100644 index 000000000..78bc96d08 --- /dev/null +++ b/gr-atsc/src/lib/GrAtscRSDecoder.h @@ -0,0 +1,51 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _GRATSCRSDECODER_H_ +#define _GRATSCRSDECODER_H_ + +#include <VrHistoryProc.h> +#include <atsc_types.h> +#include <atsci_reed_solomon.h> + +/*! + * \brief Pass ATSC data Reed-Solomon decoder( atsc_mpeg_packet_rs_encoded --> atsc_mpeg_rs_no_sync) + */ + +class GrAtscRSDecoder : public VrHistoryProc<atsc_mpeg_packet_rs_encoded, atsc_mpeg_packet_no_sync> +{ + +public: + + GrAtscRSDecoder (); + ~GrAtscRSDecoder (); + + const char *name () { return "GrAtscRSDecoder"; } + + virtual int work (VrSampleRange output, void *o[], + VrSampleRange inputs[], void *i[]); + +protected: + atsci_reed_solomon rs_decoder; +}; + +#endif /* _GRATSCRSDECODER_H_ */ diff --git a/gr-atsc/src/lib/GrAtscRSEncoder.cc b/gr-atsc/src/lib/GrAtscRSEncoder.cc new file mode 100644 index 000000000..7b2a7af5a --- /dev/null +++ b/gr-atsc/src/lib/GrAtscRSEncoder.cc @@ -0,0 +1,84 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include <GrAtscRSEncoder.h> + +// typedefs for fundamental i/o types + +typedef atsc_mpeg_packet_no_sync iType; +typedef atsc_mpeg_packet_rs_encoded oType; + +static const int NUMBER_OF_OUTPUTS = 1; // # of output streams (almost always one) + + +GrAtscRSEncoder::GrAtscRSEncoder () + : VrHistoryProc<iType,oType> (NUMBER_OF_OUTPUTS) +{ + // 1 + number of extra input elements at which we look. This is + // used by the superclass's forecast routine to get us the correct + // range on our inputs. + // We're one-to-one input-to-output so set it to 1. + history = 1; + + // any other init here. +} + +GrAtscRSEncoder::~GrAtscRSEncoder () +{ + // Anything that isn't automatically cleaned up... +} + +/* + * This is the real work horse. In general this interface can handle + * multiple streams of input and output, but we almost always + * use a single input and output stream. + */ + +int +GrAtscRSEncoder::work (VrSampleRange output, void *ao[], + VrSampleRange inputs[], void *ai[]) +{ + // construct some nicer i/o pointers to work with. + + iType *in = ((iType **) ai)[0]; + oType *out = ((oType **) ao)[0]; + + + // We must produce output.size units of output. + + for (unsigned int i = 0; i < output.size; i++){ + + // ensure that on the way in, the error bit is clear + // [assertion is not valid, because the randomizer has already scrambled the bits] + // assert ((in[i].data[0] & MPEG_TRANSPORT_ERROR_BIT) == 0); + + assert (in[i].pli.regular_seg_p ()); + out[i].pli = in[i].pli; // copy pipeline info... + rs_encoder.encode (out[i], in[i]); + } + + // Return the number of units we produced. + // Note that for all intents and purposes, it is an error to + // produce less than you are asked for. + + return output.size; +} diff --git a/gr-atsc/src/lib/GrAtscRSEncoder.h b/gr-atsc/src/lib/GrAtscRSEncoder.h new file mode 100644 index 000000000..f14267d1c --- /dev/null +++ b/gr-atsc/src/lib/GrAtscRSEncoder.h @@ -0,0 +1,51 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _GRATSCRSENCODER_H_ +#define _GRATSCRSENCODER_H_ + +#include <VrHistoryProc.h> +#include <atsc_types.h> +#include <atsci_reed_solomon.h> + +/*! + * \brief Encode using Reed Solomon ATSC data (atsc_mpeg_packet_no_sync --> atsc_mpeg_packet_rs_encoded) + */ + +class GrAtscRSEncoder : public VrHistoryProc<atsc_mpeg_packet_no_sync, atsc_mpeg_packet_rs_encoded> +{ + +public: + + GrAtscRSEncoder (); + ~GrAtscRSEncoder (); + + const char *name () { return "GrAtscRSEncoder"; } + + int work (VrSampleRange output, void *o[], + VrSampleRange inputs[], void *i[]); + +protected: + atsci_reed_solomon rs_encoder; +}; + +#endif /* _GRATSCRSENCODER_H_ */ diff --git a/gr-atsc/src/lib/GrAtscRandomizer.cc b/gr-atsc/src/lib/GrAtscRandomizer.cc new file mode 100644 index 000000000..d2a14de49 --- /dev/null +++ b/gr-atsc/src/lib/GrAtscRandomizer.cc @@ -0,0 +1,110 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include <GrAtscRandomizer.h> + +// typedefs for fundamental i/o types + +typedef atsc_mpeg_packet iType; +typedef atsc_mpeg_packet_no_sync oType; + +static const int NUMBER_OF_OUTPUTS = 1; // # of output streams (almost always one) + + +GrAtscRandomizer::GrAtscRandomizer () + : VrHistoryProc<iType,oType> (NUMBER_OF_OUTPUTS), + field2 (false), segno (0) +{ + // 1 + number of extra input elements at which we look. This is + // used by the superclass's forecast routine to get us the correct + // range on our inputs. + // We're one-to-one input-to-output so set it to 1. + history = 1; + + // any other init here. +} + +GrAtscRandomizer::~GrAtscRandomizer () +{ + // Anything that isn't automatically cleaned up... +} + +/* + * This is the real work horse. In general this interface can handle + * multiple streams of input and output, but we almost always + * use a single input and output stream. + */ + +int +GrAtscRandomizer::work (VrSampleRange output, void *ao[], + VrSampleRange inputs[], void *ai[]) +{ + // If we have state that persists across invocations (e.g., we have + // instance variables that we modify), we must use the sync method + // to indicate to the scheduler that our output must be computed in + // order. This doesn't keep other things from being run in + // parallel, it just means that at any given time, there is only a + // single thread working this code, and that the scheduler will + // ensure that we are asked to produce output that is contiguous and + // that will be presented to us in order of increasing time. + + // We have state, the current contents of the LFSR in the randomizer, hence + // we must use sync. + + sync (output.index); + + // construct some nicer i/o pointers to work with. + + iType *in = ((iType **) ai)[0]; + oType *out = ((oType **) ao)[0]; + + + // We must produce output.size units of output. + + for (unsigned int i = 0; i < output.size; i++){ + + // initialize plinfo for downstream + // + // We do this here because the randomizer is effectively + // the head of the tx processing chain + // + out[i].pli.set_regular_seg (field2, segno); + segno++; + if (segno == 312){ + segno = 0; + field2 = !field2; + } + + assert ((in[i].data[1] & MPEG_TRANSPORT_ERROR_BIT) == 0); + + if (out[i].pli.first_regular_seg_p ()) + rand.reset (); + + rand.randomize (out[i], in[i]); + } + + // Return the number of units we produced. + // Note that for all intents and purposes, it is an error to + // produce less than you are asked for. + + return output.size; +} diff --git a/gr-atsc/src/lib/GrAtscRandomizer.h b/gr-atsc/src/lib/GrAtscRandomizer.h new file mode 100644 index 000000000..39c1b6500 --- /dev/null +++ b/gr-atsc/src/lib/GrAtscRandomizer.h @@ -0,0 +1,55 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _GRATSCRANDOMIZER_H_ +#define _GRATSCRANDOMIZER_H_ + +#include <VrHistoryProc.h> +#include <atsc_types.h> +#include <atsci_randomizer.h> + +/*! + * \brief Randomize ATSC data (atsc_mpeg_packet --> atsc_mpeg_packet_no_sync) + */ + +class GrAtscRandomizer : public VrHistoryProc<atsc_mpeg_packet, atsc_mpeg_packet_no_sync> +{ + +public: + + GrAtscRandomizer (); + ~GrAtscRandomizer (); + + const char *name () { return "GrAtscRandomizer"; } + + int work (VrSampleRange output, void *o[], + VrSampleRange inputs[], void *i[]); + +protected: + atsci_randomizer rand; + + // used to initialize plinfo in output + bool field2; + int segno; +}; + +#endif /* _GRATSCRANDOMIZER_H_ */ diff --git a/gr-atsc/src/lib/GrAtscSegSymSync.cc b/gr-atsc/src/lib/GrAtscSegSymSync.cc new file mode 100644 index 000000000..ad2384b8d --- /dev/null +++ b/gr-atsc/src/lib/GrAtscSegSymSync.cc @@ -0,0 +1,50 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include <GrAtscSegSymSync.h> +#include <GrAtscSegSymSyncImpl_export.h> +#include <iostream> +#include <assert.h> + +static const int DECIMATION = 2; // close enough for super class's use +static const int N_OUTPUTS = 2; + +GrAtscSegSymSync::GrAtscSegSymSync () + : VrDecimatingSigProc<float,float> (N_OUTPUTS, DECIMATION) +{ + if (sizeof (float) != sizeof (atsc::syminfo)){ + cerr << "GrAtscSegSymSync: sizeof (float) != sizeof (atsc::syminfo)\n"; + assert (0); + } +} + +GrAtscSegSymSync::~GrAtscSegSymSync () +{ + // Nop +} + + +GrAtscSegSymSync * +GrAtscSegSymSync::create (double nominal_ratio_of_rx_clock_to_symbol_freq) +{ + return create_GrAtscSegSymSyncImpl (nominal_ratio_of_rx_clock_to_symbol_freq); +} diff --git a/gr-atsc/src/lib/GrAtscSegSymSync.h b/gr-atsc/src/lib/GrAtscSegSymSync.h new file mode 100644 index 000000000..1e32e1698 --- /dev/null +++ b/gr-atsc/src/lib/GrAtscSegSymSync.h @@ -0,0 +1,64 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _GRATSCSEGSYMSYNC_H_ +#define _GRATSCSEGSYMSYNC_H_ + +#include <VrDecimatingSigProc.h> + +/*! + * \brief ATSC SegSymSync + * + * Abstract class that establishes symbol timing and synchronizes + * with data segment boundaries. + * + * Takes a single stream of floats as the input and + * produces two streams as output. The first stream is the data samples + * and is of type float. The second stream is the tags, and is of type syminfo. + * + * The current GNU Radio interface doesn't currently support different + * types on the input ports (or output ports for that matter), but + * since they are the same size, it works. + */ + +#include <atsci_syminfo.h> + +class GrAtscSegSymSync : public VrDecimatingSigProc<float,float> { + +public: + + GrAtscSegSymSync (); + ~GrAtscSegSymSync (); + + /*! + * \brief reset bit timing loop on channel change + */ + virtual void reset () = 0; + + /*! + * \brief create an instance of GrAtscSegSymSync + */ + static GrAtscSegSymSync *create (double nominal_ratio_of_rx_clock_to_symbol_freq); + +}; + +#endif // _GRATSCSEGSYMSYNC_H_ diff --git a/gr-atsc/src/lib/GrAtscSegSymSyncImpl.cc b/gr-atsc/src/lib/GrAtscSegSymSyncImpl.cc new file mode 100644 index 000000000..ce27eb358 --- /dev/null +++ b/gr-atsc/src/lib/GrAtscSegSymSyncImpl.cc @@ -0,0 +1,103 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include <GrAtscSegSymSyncImpl.h> +#include <GrAtscSegSymSyncImpl_export.h> +#include <cmath> +#include <assert.h> + +GrAtscSegSymSyncImpl::GrAtscSegSymSyncImpl ( + double nominal_ratio_of_rx_clock_to_symbol_freq) + : d_interp (nominal_ratio_of_rx_clock_to_symbol_freq) +{ + // set approximate decimation rate for superclass's benefit + decimation = (int) rint (nominal_ratio_of_rx_clock_to_symbol_freq); + + history = 1500; // spare input samples in case we need them. + + d_sssr.reset (); + d_interp.reset (); + d_next_input = 0; + d_rx_clock_to_symbol_freq = nominal_ratio_of_rx_clock_to_symbol_freq; +} + +GrAtscSegSymSyncImpl::~GrAtscSegSymSyncImpl () +{ + // Nop +} + +void +GrAtscSegSymSyncImpl::pre_initialize () +{ + setSamplingFrequency ( + getInputSamplingFrequencyN (0) / d_rx_clock_to_symbol_freq); +} + +int +GrAtscSegSymSyncImpl::forecast (VrSampleRange output, + VrSampleRange inputs[]) +{ + assert (numberInputs == 1); // I hate these free references to + // superclass's instance variables... + + inputs[0].index = d_next_input; + inputs[0].size = + ((long unsigned int) (output.size * d_rx_clock_to_symbol_freq) + + history - 1); + + return 0; +} + +int +GrAtscSegSymSyncImpl::work (VrSampleRange output, void *ao[], + VrSampleRange inputs[], void *ai[]) +{ +#if 0 + float *input_samples = ((float **) ai)[0]; + float *output_samples = ((float **) ao)[0]; + atsc::syminfo *output_info = ((atsc::syminfo **) ao)[1]; + + // FIXME finish... +#endif + assert (0); + + return output.size; +} + +void +GrAtscSegSymSyncImpl::reset () +{ + d_sssr.reset (); + d_interp.reset (); +} + + +/* + * Exported constructor. + * Doesn't expose any of the internals or our compile time dependencies. + */ + +GrAtscSegSymSync * +create_GrAtscSegSymSyncImpl (double nominal_ratio_of_rx_clock_to_symbol_freq) +{ + return new GrAtscSegSymSyncImpl (nominal_ratio_of_rx_clock_to_symbol_freq); +} diff --git a/gr-atsc/src/lib/GrAtscSegSymSyncImpl.h b/gr-atsc/src/lib/GrAtscSegSymSyncImpl.h new file mode 100644 index 000000000..d0387408c --- /dev/null +++ b/gr-atsc/src/lib/GrAtscSegSymSyncImpl.h @@ -0,0 +1,69 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ +#ifndef _GRATSCSEGSYMSYNCIMPL_H_ +#define _GRATSCSEGSYMSYNCIMPL_H_ + +#include <GrAtscSegSymSync.h> +#include <atsci_sssr.h> + + +/*! + * \brief concrete implementation of GrAtscSegSymSync + * + * This class implements data segment sync tracking and symbol timing + * using a variation of the method described in + * "ATSC/VSB Tutorial - Receiver Technology" by Wayne E. Bretl of + * Zenith, pgs 41-45. + */ + +class GrAtscSegSymSyncImpl : public GrAtscSegSymSync { + + atsci_sssr d_sssr; + atsci_interpolator d_interp; + VrSampleIndex d_next_input; + double d_rx_clock_to_symbol_freq; // nominal ratio + +public: + + // the standard methods... + + GrAtscSegSymSyncImpl (double nominal_ratio_of_rx_clock_to_symbol_freq); + virtual ~GrAtscSegSymSyncImpl (); + + virtual const char *name () { return "GrAtscSegSymSyncImpl"; } + + virtual int forecast (VrSampleRange output, + VrSampleRange inputs[]); + + virtual int work (VrSampleRange output, void *o[], + VrSampleRange inputs[], void *i[]); + + void pre_initialize (); + + + // reset on channel change + + virtual void reset (); + +}; + +#endif /* _GRATSCSEGSYMSYNCIMPL_H_ */ diff --git a/gr-atsc/src/lib/GrAtscSegSymSyncImpl_export.h b/gr-atsc/src/lib/GrAtscSegSymSyncImpl_export.h new file mode 100644 index 000000000..b58dceef8 --- /dev/null +++ b/gr-atsc/src/lib/GrAtscSegSymSyncImpl_export.h @@ -0,0 +1,26 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +class GrAtscSegSymSync; + +GrAtscSegSymSync *create_GrAtscSegSymSyncImpl ( + double nominal_ratio_of_rx_clock_to_symbol_freq); diff --git a/gr-atsc/src/lib/GrAtscSymbolMapper.h b/gr-atsc/src/lib/GrAtscSymbolMapper.h new file mode 100644 index 000000000..061f4aa72 --- /dev/null +++ b/gr-atsc/src/lib/GrAtscSymbolMapper.h @@ -0,0 +1,97 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _GRATSCSYMBOLMAPPER_H_ +#define _GRATSCSYMBOLMAPPER_H_ + + +#include <VrInterpolatingSigProcNoWork.h> +#include <atsc_types.h> +#include <gr_nco.h> + +/*! + * \brief take atsc_data_segments and map them to symbols. + * + * Input is a stream of atsc_data_segments. + * Output is a stream of symbols at 1x the symbol rate + * + * This module performs the signal mapping & pilot addition. + */ + +template<class oType> +class GrAtscSymbolMapper + : public VrInterpolatingSigProcNoWork<atsc_data_segment, oType> { + +public: + GrAtscSymbolMapper () + : VrInterpolatingSigProcNoWork<atsc_data_segment, oType>(1, INTERP_FACTOR) {}; + + ~GrAtscSymbolMapper () {}; + + const char *name () { return "GrAtscSymbolMapper"; } + + int work (VrSampleRange output, void *ao[], + VrSampleRange inputs[], void *ai[]); + +protected: + static const int INTERP_FACTOR = ATSC_DATA_SEGMENT_LENGTH; +}; + + +template<class oType> +int +GrAtscSymbolMapper<oType>::work (VrSampleRange output, void *ao[], + VrSampleRange inputs[], void *ai[]) +{ + atsc_data_segment *in = ((atsc_data_segment **) ai)[0]; + oType *out = ((oType **) ao)[0]; + + assert ((output.size % INTERP_FACTOR) == 0); + + static const float pilot_add = 1.25; + static const float map[8] = { + -7 + pilot_add, + -5 + pilot_add, + -3 + pilot_add, + -1 + pilot_add, + 1 + pilot_add, + 3 + pilot_add, + 5 + pilot_add, + 7 + pilot_add + }; + + unsigned int oo = 0; + unsigned int nsegs = output.size / INTERP_FACTOR; + + for (unsigned int n = 0; n < nsegs; n++){ + unsigned char *symbol = in[n].data; + + for (int i = 0; i < ATSC_DATA_SEGMENT_LENGTH; i++){ + out[oo++] = (oType) map[symbol[i] & 0x7]; + } + } + + assert (oo == output.size); + return output.size; +} + +#endif /* _GRATSCSYMBOLMAPPER_H_ */ diff --git a/gr-atsc/src/lib/GrAtscTrellisEncoder.cc b/gr-atsc/src/lib/GrAtscTrellisEncoder.cc new file mode 100644 index 000000000..8c55e1459 --- /dev/null +++ b/gr-atsc/src/lib/GrAtscTrellisEncoder.cc @@ -0,0 +1,144 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include <GrAtscTrellisEncoder.h> + +// typedefs for fundamental i/o types + +typedef atsc_mpeg_packet_rs_encoded iType; +typedef atsc_data_segment oType; + +static const int NUMBER_OF_OUTPUTS = 1; // # of output streams (almost always one) + + +GrAtscTrellisEncoder::GrAtscTrellisEncoder () + : VrHistoryProc<iType,oType> (NUMBER_OF_OUTPUTS), last_start(-1) +{ + // 1 + number of extra input elements at which we look. This is + // used by the superclass's forecast routine to get us the correct + // range on our inputs. + // + // We need our input to be aligned on a 12-segment boundary, + // to ensure satisfaction, ask for 11 more + history = 1 + (atsci_trellis_encoder::NCODERS - 1); + + // any other init here. + + // Let the bottom end know we must produce output in multiples of 12 segments. + setOutputSize (atsci_trellis_encoder::NCODERS); +} + +GrAtscTrellisEncoder::~GrAtscTrellisEncoder () +{ + // Anything that isn't automatically cleaned up... +} + +/* + * This is the real work horse. In general this interface can handle + * multiple streams of input and output, but we almost always + * use a single input and output stream. + */ + +int +GrAtscTrellisEncoder::work (VrSampleRange output, void *ao[], + VrSampleRange inputs[], void *ai[]) +{ + // If we have state that persists across invocations (e.g., we have + // instance variables that we modify), we must use the sync method + // to indicate to the scheduler that our output must be computed in + // order. This doesn't keep other things from being run in + // parallel, it just means that at any given time, there is only a + // single thread working this code, and that the scheduler will + // ensure that we are asked to produce output that is contiguous and + // that will be presented to us in order of increasing time. + + // We have state, the current state of the encoders, hence + // we must use sync. + + sync (output.index); + + // construct some nicer i/o pointers to work with. + + iType *in = ((iType **) ai)[0]; + oType *out = ((oType **) ao)[0]; + + +#if 0 + cerr << "@@@ GrAtscTrellisEncoder: output.index = " << output.index + << " output.size = " << output.size + << " sum = " << output.index + output.size + << " \t[in = " << in << "]" + << endl; +#endif + + assert (output.size % atsci_trellis_encoder::NCODERS == 0); + + + // find the first mod 12 boundary to begin decoding + int start; + for (start = 0; start < atsci_trellis_encoder::NCODERS; start++){ + plinfo::sanity_check (in[start].pli); + assert (in[start].pli.regular_seg_p ()); + if ((in[start].pli.segno () % atsci_trellis_encoder::NCODERS) == 0) + break; + } + + if (start == atsci_trellis_encoder::NCODERS){ + // we didn't find a mod 12 boundary. There's some kind of problem + // upstream of us (not yet sync'd??) + cerr << "!!!GrAtscTrellisEncoder: no mod-12 boundary found\7\n"; + start = 0; + } + else if (start != last_start){ + cerr << "GrAtscTrellisEncoder: new starting offset = " << start + << " output.index = " << output.index << endl; + last_start = start; + } + + + // FIXME paranoid check for problem + for (unsigned int i = 0; i < output.size; i++){ + plinfo::sanity_check (in[i + start].pli); + } + + // We must produce output.size units of output. + + for (unsigned int i = 0; i < output.size; i += atsci_trellis_encoder::NCODERS){ + // primitive does 12 segments at a time. + // pipeline info is handled in the primitive. + encoder.encode (&out[i], &in[i + start]); + } + +#if 0 + // FIXME paranoid check for problem + for (unsigned int i = 0; i < output.size; i++){ + plinfo::sanity_check (out[i].pli); + assert (out[i].pli.regular_seg_p ()); + } +#endif + + // Return the number of units we produced. + // Note that for all intents and purposes, it is an error to + // produce less than you are asked for. + + return output.size; +} diff --git a/gr-atsc/src/lib/GrAtscTrellisEncoder.h b/gr-atsc/src/lib/GrAtscTrellisEncoder.h new file mode 100644 index 000000000..ac17de35c --- /dev/null +++ b/gr-atsc/src/lib/GrAtscTrellisEncoder.h @@ -0,0 +1,50 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _GRATSCTRELLISENCODER_H_ + +#include <VrHistoryProc.h> +#include <atsci_trellis_encoder.h> + +/*! + * \brief ATSC 12-way interleaved trellis encoder (atsc_mpeg_packet_rs_encoded --> atsc_data_segment) + */ + +class GrAtscTrellisEncoder : public VrHistoryProc<atsc_mpeg_packet_rs_encoded,atsc_data_segment> +{ + +public: + + GrAtscTrellisEncoder (); + ~GrAtscTrellisEncoder (); + + const char *name () { return "GrAtscTrellisEncoder"; } + + int work (VrSampleRange output, void *o[], + VrSampleRange inputs[], void *i[]); + +protected: + atsci_trellis_encoder encoder; + int last_start; +}; + +#endif diff --git a/gr-atsc/src/lib/GrAtscViterbiDecoder.cc b/gr-atsc/src/lib/GrAtscViterbiDecoder.cc new file mode 100644 index 000000000..2b7174b8e --- /dev/null +++ b/gr-atsc/src/lib/GrAtscViterbiDecoder.cc @@ -0,0 +1,135 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include <GrAtscViterbiDecoder.h> +#include <iostream> + +// typedefs for fundamental i/o types + +typedef atsc_soft_data_segment iType; +typedef atsc_mpeg_packet_rs_encoded oType; + +static const int NUMBER_OF_OUTPUTS = 1; // # of output streams (almost always one) + + +GrAtscViterbiDecoder::GrAtscViterbiDecoder () + : VrHistoryProc<iType,oType> (NUMBER_OF_OUTPUTS), last_start(-1) +{ + // 1 + number of extra input elements at which we look. This is + // used by the superclass's forecast routine to get us the correct + // range on our inputs. + // + // We need our input to be aligned on a 12-segment boundary, + // to ensure satisfaction, ask for 11 more + history = 1 + (atsci_viterbi_decoder::NCODERS - 1); + + // any other init here. + + // Let the bottom end know we must produce output in multiples of 12 segments. + setOutputSize (atsci_viterbi_decoder::NCODERS); +} + +GrAtscViterbiDecoder::~GrAtscViterbiDecoder () +{ + // Anything that isn't automatically cleaned up... +} + +/* + * This is the real work horse. In general this interface can handle + * multiple streams of input and output, but we almost always + * use a single input and output stream. + */ + +int +GrAtscViterbiDecoder::work (VrSampleRange output, void *ao[], + VrSampleRange inputs[], void *ai[]) +{ + // If we have state that persists across invocations (e.g., we have + // instance variables that we modify), we must use the sync method + // to indicate to the scheduler that our output must be computed in + // order. This doesn't keep other things from being run in + // parallel, it just means that at any given time, there is only a + // single thread working this code, and that the scheduler will + // ensure that we are asked to produce output that is contiguous and + // that will be presented to us in order of increasing time. + + // We have state, the current state of the decoder, hence + // we must use sync. + + sync (output.index); + + // construct some nicer i/o pointers to work with. + + iType *in = ((iType **) ai)[0]; + oType *out = ((oType **) ao)[0]; + + + assert (output.size % atsci_viterbi_decoder::NCODERS == 0); + + // find the first mod 12 boundary to begin decoding + int start; + for (start = 0; start < atsci_viterbi_decoder::NCODERS; start++){ + assert (in[start].pli.regular_seg_p ()); + if ((in[start].pli.segno () % atsci_viterbi_decoder::NCODERS) == 0) + break; + } + + if (start == atsci_viterbi_decoder::NCODERS){ + // we didn't find a mod 12 boundary. There's some kind of problem + // upstream of us (not yet sync'd??) + cerr << "!!!GrAtscViterbiDecoder: no mod-12 boundary found\7\n"; + start = 0; + } + else if (start != last_start){ + cerr << "GrAtscViterbiDecoder: new starting offset = " << start + << " output.index = " << output.index << endl; + last_start = start; + } + + // We must produce output.size units of output. + + for (unsigned int i = 0; i < output.size; i += atsci_viterbi_decoder::NCODERS){ + // primitive does 12 segments at a time. + // pipeline info is handled in the primitive. + decoder.decode (&out[i], &in[i + start]); + } + +#if 0 + // FIXME paranoid check... + for (unsigned int i = 0; i < output.size; i++){ + plinfo::sanity_check (out[i].pli); + assert (out[i].pli.regular_seg_p ()); + } +#endif + +#if 0 + cerr << "@@@ GrAtscViterbiDecoder: output.index = " << output.index + << " output.size = " << output.size + << " sum = " << output.index + output.size << endl; +#endif + + // Return the number of units we produced. + // Note that for all intents and purposes, it is an error to + // produce less than you are asked for. + + return output.size; +} diff --git a/gr-atsc/src/lib/GrAtscViterbiDecoder.h b/gr-atsc/src/lib/GrAtscViterbiDecoder.h new file mode 100644 index 000000000..10e348061 --- /dev/null +++ b/gr-atsc/src/lib/GrAtscViterbiDecoder.h @@ -0,0 +1,51 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _GRATSCVITERBIDECODER_H_ + +#include <VrHistoryProc.h> +#include <atsci_viterbi_decoder.h> + +/*! + * \brief ATSC 12-way interleaved viterbi decoder (atsc_soft_data_segment --> atsc_mpeg_packet_rs_encoded) + */ + +class GrAtscViterbiDecoder : public VrHistoryProc<atsc_soft_data_segment, + atsc_mpeg_packet_rs_encoded> +{ + +public: + + GrAtscViterbiDecoder (); + ~GrAtscViterbiDecoder (); + + const char *name () { return "GrAtscViterbiDecoder"; } + + int work (VrSampleRange output, void *o[], + VrSampleRange inputs[], void *i[]); + +protected: + atsci_viterbi_decoder decoder; + int last_start; +}; + +#endif diff --git a/gr-atsc/src/lib/Makefile.am b/gr-atsc/src/lib/Makefile.am new file mode 100644 index 000000000..d5ae6ed53 --- /dev/null +++ b/gr-atsc/src/lib/Makefile.am @@ -0,0 +1,268 @@ +# +# Copyright 2001,2004,2005,2006 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio 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; either version 2, or (at your option) +# any later version. +# +# GNU Radio 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 for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. +# + +include $(top_srcdir)/Makefile.common + +# Install this stuff so that it ends up as the gnuradio.atsc module +# This usually ends up at: +# ${prefix}/lib/python${python_version}/site-packages/gnuradio + +ourpythondir = $(grpythondir) +ourlibdir = $(grpyexecdir) + +INCLUDES = $(STD_DEFINES_AND_INCLUDES) $(PYTHON_CPPFLAGS) $(CPPUNIT_INCLUDES) + +#LIBS += $(GNURADIO_CORE_LIBS) + +EXTRA_DIST = \ + gen_encoder.py \ + qa_atsci_trellis_encoder_t1_input.dat \ + qa_atsci_trellis_encoder_t1_output.dat \ + qa_atsci_viterbi_decoder_t1_input.dat \ + qa_atsci_viterbi_decoder_t1_output.dat + + +BUILT_SOURCES = \ + atsci_viterbi_mux.cc \ + $(swig_built_sources) + + +TESTS = \ + test_atsci + + +# We build two libtool convenience libraries + +noinst_LTLIBRARIES = libatsc.la libatsc-qa.la + +# FIXME +# atsci_exp2_lp.cc \ +# atsci_root_raised_cosine.cc \ +# atsci_root_raised_cosine_bandpass.cc \ +# atsci_vsbtx_lp.cc \ +# + +libatsc_la_SOURCES = \ + atsc_derandomizer.cc \ + atsc_randomizer.cc \ + atsc_rs_decoder.cc \ + atsc_rs_encoder.cc \ + atsc_interleaver.cc \ + atsc_deinterleaver.cc \ + atsc_trellis_encoder.cc \ + atsc_viterbi_decoder.cc \ + atsc_ds_to_softds.cc \ + atsc_field_sync_mux.cc \ + atsc_field_sync_demux.cc \ + atsc_equalizer.cc \ + atsc_fs_checker.cc \ + atsc_bit_timing_loop.cc \ + atsc_fpll.cc \ + atsc_depad.cc \ + atsci_basic_trellis_encoder.cc \ + atsci_data_interleaver.cc \ + atsci_equalizer.cc \ + atsci_equalizer_lms.cc \ + atsci_equalizer_lms2.cc \ + atsci_equalizer_nop.cc \ + atsci_fake_single_viterbi.cc \ + atsci_fs_checker.cc \ + atsci_fs_checker_naive.cc \ + atsci_fs_correlator.cc \ + atsci_fs_correlator_naive.cc \ + atsci_single_viterbi.cc \ + atsci_sssr.cc \ + atsci_pnXXX.cc \ + atsci_randomizer.cc \ + atsci_reed_solomon.cc \ + atsci_sliding_correlator.cc \ + atsci_trellis_encoder.cc \ + atsci_viterbi_decoder.cc \ + create_atsci_equalizer.cc \ + create_atsci_fs_checker.cc \ + create_atsci_fs_correlator.cc \ + plinfo.cc + +libatsc_qa_la_SOURCES = \ + qa_atsci_basic_trellis_encoder.cc \ + qa_atsci_data_interleaver.cc \ + qa_atsci_equalizer_nop.cc \ + qa_atsci_fake_single_viterbi.cc \ + qa_atsci_fs_correlator.cc \ + qa_atsci_single_viterbi.cc \ + qa_atsci_randomizer.cc \ + qa_atsci_reed_solomon.cc \ + qa_atsci_sliding_correlator.cc \ + qa_atsci_trellis_encoder.cc \ + qa_atsci_viterbi_decoder.cc \ + qa_convolutional_interleaver.cc \ + qa_atsci.cc \ + qa_interleaver_fifo.cc + + +# These headers get installed in ${prefix}/include/gnuradio +grinclude_HEADERS = \ + atsc_consts.h \ + atsc_derandomizer.h \ + atsc_randomizer.h \ + atsc_rs_decoder.h \ + atsc_rs_encoder.h \ + atsc_interleaver.h \ + atsc_deinterleaver.h \ + atsc_trellis_encoder.h \ + atsc_viterbi_decoder.h \ + atsc_ds_to_softds.h \ + atsc_field_sync_mux.h \ + atsc_field_sync_demux.h \ + atsc_equalizer.h \ + atsc_fs_checker.h \ + atsc_bit_timing_loop.h \ + atsc_fpll.h \ + atsc_depad.h \ + atsc_types.h \ + atsci_basic_trellis_encoder.h \ + atsci_data_interleaver.h \ + atsci_diag_output.h \ + atsci_equalizer.h \ + atsci_equalizer_lms.h \ + atsci_equalizer_lms2.h \ + atsci_equalizer_nop.h \ + atsci_exp2_lp.h \ + atsci_fake_single_viterbi.h \ + atsci_fs_checker.h \ + atsci_fs_checker_naive.h \ + atsci_fs_correlator.h \ + atsci_fs_correlator_naive.h \ + atsci_pnXXX.h \ + atsci_randomizer.h \ + atsci_reed_solomon.h \ + atsci_root_raised_cosine.h \ + atsci_root_raised_cosine_bandpass.h \ + atsci_single_viterbi.h \ + atsci_slicer_agc.h \ + atsci_sliding_correlator.h \ + atsci_sssr.h \ + atsci_syminfo.h \ + atsci_sync_tag.h \ + atsci_trellis_encoder.h \ + atsci_viterbi_decoder.h \ + atsci_vsbtx_lp.h \ + convolutional_interleaver.h \ + create_atsci_equalizer.h \ + create_atsci_fs_checker.h \ + create_atsci_fs_correlator.h \ + fpll_btloop_coupling.h \ + interleaver_fifo.h \ + qa_atsci.h \ + qa_atsci_basic_trellis_encoder.h \ + qa_atsci_data_interleaver.h \ + qa_atsci_equalizer_nop.h \ + qa_atsci_fake_single_viterbi.h \ + qa_atsci_fs_correlator.h \ + qa_atsci_randomizer.h \ + qa_atsci_reed_solomon.h \ + qa_atsci_single_viterbi.h \ + qa_atsci_sliding_correlator.h \ + qa_atsci_trellis_encoder.h \ + qa_atsci_viterbi_decoder.h \ + qa_convolutional_interleaver.h \ + qa_interleaver_fifo.h + + +# programs we build but don't install +# FIXME add test_atsc +noinst_PROGRAMS = \ + atsci_viterbi_gen \ + test_atsci + + +atsci_viterbi_gen_SOURCES = atsci_viterbi_gen.cc + +atsci_viterbi_mux.cc: atsci_viterbi_gen$(EXEEXT) + $(MAKE) $(AM_MAKEFLAGS) CXX="$(CXX_FOR_BUILD)" atsci_viterbi_gen$(EXEEXT) + ./atsci_viterbi_gen$(EXEEXT) -o atsci_viterbi_mux.cc + + +test_atsci_SOURCES = test_atsci.cc +test_atsci_LDADD = libatsc-qa.la libatsc.la $(GNURADIO_CORE_LIBS) $(CPPUNIT_LIBS) + + +# ------------------------------------------------------------------------ +# This is the swig-ish part of the Makefile. +# It builds the atsc module which we'll load into python +# ------------------------------------------------------------------------ + +SWIGCPPPYTHONARGS = -fvirtual -python -modern $(PYTHON_CPPFLAGS) \ + $(STD_DEFINES_AND_INCLUDES) + +ALL_IFILES = \ + $(LOCAL_IFILES) \ + $(NON_LOCAL_IFILES) + +NON_LOCAL_IFILES = \ + $(top_srcdir)/gnuradio-core/src/lib/swig/gnuradio.i + +LOCAL_IFILES = \ + atsc.i + +# These files are built by SWIG. The first is the C++ glue. +# The second is the python wrapper that loads the _atsc shared library +# and knows how to call our extensions. + +swig_built_sources = \ + atsc.cc \ + atsc.py + +# This gets atsc.py installed in the right place +ourpython_PYTHON = \ + atsc.py + +ourlib_LTLIBRARIES = _atsc.la + +# These are the source files that go into the shared library +_atsc_la_SOURCES = \ + atsc.cc + +# magic flags +_atsc_la_LDFLAGS = $(NO_UNDEFINED) -module -avoid-version + +# link the library against some comon swig runtime code and the +# c++ standard library +_atsc_la_LIBADD = \ + $(GNURADIO_CORE_LIBS) \ + $(PYTHON_LDFLAGS) \ + libatsc.la \ + -lstdc++ + +atsc.cc atsc.py: atsc.i $(ALL_IFILES) + $(SWIG) $(SWIGCPPPYTHONARGS) -module atsc -o atsc.cc $< + +# These swig headers get installed in ${prefix}/include/gnuradio/swig +swiginclude_HEADERS = \ + $(LOCAL_IFILES) + +# ------------------------------------------------------------------------ +# Cleanup +# ------------------------------------------------------------------------ + +CLEANFILES = atsci_viterbi_mux.cc +MOSTLYCLEANFILES = $(BUILT_SOURCES) *.pyc + diff --git a/gr-atsc/src/lib/atsc.i b/gr-atsc/src/lib/atsc.i new file mode 100644 index 000000000..026332b26 --- /dev/null +++ b/gr-atsc/src/lib/atsc.i @@ -0,0 +1,269 @@ +/* -*- c++ -*- */ + +%feature("autodoc", "1"); // generate python docstrings + +%include "exception.i" +%import "gnuradio.i" // the common stuff + +%{ +#include "gnuradio_swig_bug_workaround.h" // mandatory bug fix +#include <stdexcept> +#include <atsc_randomizer.h> +#include <atsc_derandomizer.h> +#include <atsc_rs_encoder.h> +#include <atsc_rs_decoder.h> +#include <atsc_interleaver.h> +#include <atsc_deinterleaver.h> +#include <atsc_trellis_encoder.h> +#include <atsc_viterbi_decoder.h> +#include <atsc_ds_to_softds.h> +#include <atsc_field_sync_mux.h> +#include <atsc_field_sync_demux.h> +#include <atsc_equalizer.h> +#include <atsc_fs_checker.h> +#include <atsc_bit_timing_loop.h> +#include <atsc_fpll.h> +#include <atsc_depad.h> +%} + +%include "atsc_consts.h" + +%constant int sizeof_atsc_mpeg_packet = sizeof(atsc_mpeg_packet); +%constant int sizeof_atsc_mpeg_packet_no_sync = sizeof(atsc_mpeg_packet_no_sync); +%constant int sizeof_atsc_mpeg_packet_rs_encoded = sizeof(atsc_mpeg_packet_rs_encoded); +%constant int sizeof_atsc_data_segment = sizeof(atsc_data_segment); +%constant int sizeof_atsc_soft_data_segment = sizeof(atsc_soft_data_segment); + +%constant int sizeof_atsc_mpeg_packet_pad = atsc_mpeg_packet::NPAD; +%constant int sizeof_atsc_mpeg_packet_no_sync_pad = atsc_mpeg_packet_no_sync::NPAD; +%constant int sizeof_atsc_mpeg_packet_rs_encoded_pad = atsc_mpeg_packet_rs_encoded::NPAD; +%constant int sizeof_atsc_data_segment_pad = atsc_data_segment::NPAD; +%constant int sizeof_atsc_soft_data_segment_pad = atsc_soft_data_segment::NPAD; + +// ---------------------------------------------------------------- + +GR_SWIG_BLOCK_MAGIC(atsc,randomizer); + +atsc_randomizer_sptr atsc_make_randomizer(); + +class atsc_randomizer : public gr_sync_block +{ + atsc_randomizer(); + +public: + void reset(); +}; + +// ---------------------------------------------------------------- + +GR_SWIG_BLOCK_MAGIC(atsc,derandomizer); + +atsc_derandomizer_sptr atsc_make_derandomizer(); + +class atsc_derandomizer : public gr_sync_block +{ + atsc_derandomizer(); + +public: + void reset(); +}; + +// ---------------------------------------------------------------- + +GR_SWIG_BLOCK_MAGIC(atsc,rs_encoder); + +atsc_rs_encoder_sptr atsc_make_rs_encoder(); + +class atsc_rs_encoder : public gr_sync_block +{ + atsc_rs_encoder(); + +public: + void reset(); +}; + +// ---------------------------------------------------------------- + +GR_SWIG_BLOCK_MAGIC(atsc,rs_decoder); + +atsc_rs_decoder_sptr atsc_make_rs_decoder(); + +class atsc_rs_decoder : public gr_sync_block +{ + atsc_rs_decoder(); + +public: + void reset(); +}; + +// ---------------------------------------------------------------- + +GR_SWIG_BLOCK_MAGIC(atsc,interleaver); + +atsc_interleaver_sptr atsc_make_interleaver(); + +class atsc_interleaver : public gr_sync_block +{ + atsc_interleaver(); + +public: + void reset(); +}; + +// ---------------------------------------------------------------- + +GR_SWIG_BLOCK_MAGIC(atsc,deinterleaver); + +atsc_deinterleaver_sptr atsc_make_deinterleaver(); + +class atsc_deinterleaver : public gr_sync_block +{ + atsc_deinterleaver(); + +public: + void reset(); +}; + +// ---------------------------------------------------------------- + +GR_SWIG_BLOCK_MAGIC(atsc,trellis_encoder); + +atsc_trellis_encoder_sptr atsc_make_trellis_encoder(); + +class atsc_trellis_encoder : public gr_sync_block +{ + atsc_trellis_encoder(); + +public: + void reset(); +}; + +// ---------------------------------------------------------------- + +GR_SWIG_BLOCK_MAGIC(atsc,viterbi_decoder); + +atsc_viterbi_decoder_sptr atsc_make_viterbi_decoder(); + +class atsc_viterbi_decoder : public gr_sync_block +{ + atsc_viterbi_decoder(); + +public: + void reset(); +}; + +// ---------------------------------------------------------------- + +GR_SWIG_BLOCK_MAGIC(atsc,ds_to_softds); + +atsc_ds_to_softds_sptr atsc_make_ds_to_softds(); + +class atsc_ds_to_softds : public gr_sync_block +{ + atsc_ds_to_softds(); + +public: + void reset(); +}; + +// ---------------------------------------------------------------- + +GR_SWIG_BLOCK_MAGIC(atsc,field_sync_mux); + +atsc_field_sync_mux_sptr atsc_make_field_sync_mux(); + +class atsc_field_sync_mux : public gr_sync_block +{ + atsc_field_sync_mux(); + +public: + void reset(); +}; + +// ---------------------------------------------------------------- + +GR_SWIG_BLOCK_MAGIC(atsc,field_sync_demux); + +atsc_field_sync_demux_sptr atsc_make_field_sync_demux(); + +class atsc_field_sync_demux : public gr_sync_decimator +{ + atsc_field_sync_demux(); + +public: + void reset(); +}; + +// ---------------------------------------------------------------- + +GR_SWIG_BLOCK_MAGIC(atsc,equalizer); + +atsc_equalizer_sptr atsc_make_equalizer(); + +class atsc_equalizer : public gr_sync_block +{ + atsc_equalizer(); + +public: + void reset(); +}; + +// ---------------------------------------------------------------- + +GR_SWIG_BLOCK_MAGIC(atsc,fs_checker); + +atsc_fs_checker_sptr atsc_make_fs_checker(); + +class atsc_fs_checker : public gr_sync_block +{ + atsc_fs_checker(); + +public: + void reset(); +}; + +// ---------------------------------------------------------------- + +GR_SWIG_BLOCK_MAGIC(atsc,bit_timing_loop); + +atsc_bit_timing_loop_sptr atsc_make_bit_timing_loop(); + +class atsc_bit_timing_loop : public gr_block +{ + atsc_bit_timing_loop(); + +public: + void reset(); +}; + +// ---------------------------------------------------------------- + +GR_SWIG_BLOCK_MAGIC(atsc,fpll); + +atsc_fpll_sptr atsc_make_fpll(); + +class atsc_fpll : public gr_sync_block +{ + atsc_fpll(); + +public: + void reset(); + +}; + +// ---------------------------------------------------------------- + +GR_SWIG_BLOCK_MAGIC(atsc,depad); + +atsc_depad_sptr atsc_make_depad(); + +class atsc_depad : public gr_sync_interpolator +{ + atsc_depad(); + +public: + void reset(); + +}; + +// ---------------------------------------------------------------- diff --git a/gr-atsc/src/lib/atsc_bit_timing_loop.cc b/gr-atsc/src/lib/atsc_bit_timing_loop.cc new file mode 100644 index 000000000..432ad4c53 --- /dev/null +++ b/gr-atsc/src/lib/atsc_bit_timing_loop.cc @@ -0,0 +1,118 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <atsc_bit_timing_loop.h> +#include <gr_io_signature.h> +#include <atsc_consts.h> + +float input_rate = 20e6; +double ratio_of_rx_clock_to_symbol_freq = input_rate / ATSC_SYMBOL_RATE; + + +atsc_bit_timing_loop_sptr +atsc_make_bit_timing_loop() +{ + return atsc_bit_timing_loop_sptr(new atsc_bit_timing_loop()); +} + + +atsc_bit_timing_loop::atsc_bit_timing_loop() + : gr_block("atsc_bit_timing_loop", + gr_make_io_signature(1, 1, sizeof(float)), + gr_make_io_signature(2, 2, sizeof(float))), + d_interp(ratio_of_rx_clock_to_symbol_freq), d_next_input(0), + d_rx_clock_to_symbol_freq (ratio_of_rx_clock_to_symbol_freq) +{ + reset(); +} + +void +atsc_bit_timing_loop::forecast (int noutput_items, gr_vector_int &ninput_items_required) +{ + unsigned ninputs = ninput_items_required.size(); + for (unsigned i = 0; i < ninputs; i++) + ninput_items_required[i] = noutput_items * d_rx_clock_to_symbol_freq + 1500 - 1; + + inputs0_size = noutput_items * d_rx_clock_to_symbol_freq + 1500 - 1; + inputs0_index = d_next_input; +} + +int +atsc_bit_timing_loop::general_work (int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) +{ + int r = work (noutput_items, input_items, output_items); + if (r > 0) + consume_each (r * d_rx_clock_to_symbol_freq); + return r; +} + + +int +atsc_bit_timing_loop::work (int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) +{ + const float *in = (const float *) input_items[0]; + float *out_sample = (float *) output_items[0]; + atsc::syminfo *out_tag = (atsc::syminfo *) output_items[1]; + + assert(sizeof(float) == sizeof(atsc::syminfo)); + + // We are tasked with producing output.size output samples. + // We will consume approximately 2 * output.size input samples. + + int si = 0; // source index + unsigned int k; // output index + + float interp_sample; + int symbol_index; + double timing_adjustment = 0; + bool seg_locked; + atsc::syminfo tag; + + memset (&tag, 0, sizeof (tag)); + + + for (k = 0; k < noutput_items; k++){ + if (!d_interp.update (in, inputs0_size, &si, timing_adjustment, &interp_sample)){ + fprintf (stderr, "GrAtscBitTimingLoop3: ran short on data...\n"); + break; + } + + d_sssr.update (interp_sample, &seg_locked, &symbol_index, &timing_adjustment); + out_sample[k] = interp_sample; + tag.valid = seg_locked; + tag.symbol_num = symbol_index; + out_tag[k] = tag; + + } + + d_next_input += si; // update next_input so forecast can get us what we need + return k; +} diff --git a/gr-atsc/src/lib/atsc_bit_timing_loop.h b/gr-atsc/src/lib/atsc_bit_timing_loop.h new file mode 100644 index 000000000..582092763 --- /dev/null +++ b/gr-atsc/src/lib/atsc_bit_timing_loop.h @@ -0,0 +1,89 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ +#ifndef INCLUDED_ATSC_BIT_TIMING_LOOP_H +#define INCLUDED_ATSC_BIT_TIMING_LOOP_H + +#include <cstdio> +#include <gr_block.h> +#include <atsci_diag_output.h> +#include <atsci_sssr.h> +#include <atsci_syminfo.h> + +class atsc_bit_timing_loop; +typedef boost::shared_ptr<atsc_bit_timing_loop> atsc_bit_timing_loop_sptr; + +atsc_bit_timing_loop_sptr atsc_make_bit_timing_loop(); + +/*! + * \brief ATSC BitTimingLoop3 + * \ingroup atsc + * + * This class accepts a single real input and produces two outputs, + * the raw symbol (float) and the tag (atsc_syminfo) + */ +class atsc_bit_timing_loop : public gr_block +{ + friend atsc_bit_timing_loop_sptr atsc_make_bit_timing_loop(); + + atsc_bit_timing_loop(); + +public: + int work (int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + + void reset() { /* nop */ } + + ~atsc_bit_timing_loop () { }; + + void forecast (int noutput_items, gr_vector_int &ninput_items_required); + + int general_work (int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + + + // debug (NOPs) + void set_mu (double a_mu) { } + void set_no_update (bool a_no_update) { } + void set_loop_filter_tap (double tap) { } + void set_timing_rate (double rate) { } + + + protected: + + atsci_sssr d_sssr; + atsci_interpolator d_interp; + unsigned long long d_next_input; + double d_rx_clock_to_symbol_freq; + + unsigned long long inputs0_index; // for inputs[0].index + unsigned long inputs0_size; // for inputs[0].size + + +}; + +#endif /* INCLUDED_ATSC_BIT_TIMING_LOOP_H */ + + + diff --git a/gr-atsc/src/lib/atsc_consts.h b/gr-atsc/src/lib/atsc_consts.h new file mode 100644 index 000000000..197ec57b6 --- /dev/null +++ b/gr-atsc/src/lib/atsc_consts.h @@ -0,0 +1,42 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _ATSC_CONSTS_H_ +#define _ATSC_CONSTS_H_ + +static const double ATSC_SYMBOL_RATE = 4.5e6 / 286 * 684; // ~10.76 MHz +static const double ATSC_DATA_SEGMENT_RATE = ATSC_SYMBOL_RATE / 832; // ~12.935 kHz + + +static const int ATSC_MPEG_DATA_LENGTH = 187; +static const int ATSC_MPEG_PKT_LENGTH = 188; // sync + data +static const int ATSC_MPEG_RS_ENCODED_LENGTH = 207; +static const int ATSC_DATA_SEGMENT_LENGTH = 832; // includes 4 sync symbols at beginning +static const int ATSC_DSEGS_PER_FIELD = 312; // regular data segs / field + + +static const int MPEG_SYNC_BYTE = 0x47; + +static const int MPEG_TRANSPORT_ERROR_BIT = 0x80; // top bit of byte after SYNC + + +#endif // _ATSC_CONSTS_H_ diff --git a/gr-atsc/src/lib/atsc_deinterleaver.cc b/gr-atsc/src/lib/atsc_deinterleaver.cc new file mode 100644 index 000000000..f698726ce --- /dev/null +++ b/gr-atsc/src/lib/atsc_deinterleaver.cc @@ -0,0 +1,59 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <atsc_deinterleaver.h> +#include <gr_io_signature.h> +#include <atsc_consts.h> + + +atsc_deinterleaver_sptr +atsc_make_deinterleaver() +{ + return atsc_deinterleaver_sptr(new atsc_deinterleaver()); +} + +atsc_deinterleaver::atsc_deinterleaver() + : gr_sync_block("atsc_deinterleaver", + gr_make_io_signature(1, 1, sizeof(atsc_mpeg_packet_rs_encoded)), + gr_make_io_signature(1, 1, sizeof(atsc_mpeg_packet_rs_encoded))) +{ + reset(); +} + +int +atsc_deinterleaver::work (int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) +{ + const atsc_mpeg_packet_rs_encoded *in = (const atsc_mpeg_packet_rs_encoded *) input_items[0]; + atsc_mpeg_packet_rs_encoded *out = (atsc_mpeg_packet_rs_encoded *) output_items[0]; + + for (int i = 0; i < noutput_items; i++){ + d_deinterleaver.deinterleave (out[i], in[i]); + } + + return noutput_items; +} diff --git a/gr-atsc/src/lib/atsc_deinterleaver.h b/gr-atsc/src/lib/atsc_deinterleaver.h new file mode 100644 index 000000000..17527b5e4 --- /dev/null +++ b/gr-atsc/src/lib/atsc_deinterleaver.h @@ -0,0 +1,56 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ +#ifndef INCLUDED_ATSC_DEINTERLEAVER_H +#define INCLUDED_ATSC_DEINTERLEAVER_H + +#include <gr_sync_block.h> +#include <atsci_data_interleaver.h> + +class atsc_deinterleaver; +typedef boost::shared_ptr<atsc_deinterleaver> atsc_deinterleaver_sptr; + +atsc_deinterleaver_sptr atsc_make_deinterleaver(); + +/*! + * \brief Deinterleave RS encoded ATSC data ( atsc_mpeg_packet_rs_encoded --> atsc_mpeg_packet_rs_encoded) + * \ingroup atsc + * + * input: atsc_mpeg_packet_rs_encoded; output: atsc_mpeg_packet_rs_encoded + */ +class atsc_deinterleaver : public gr_sync_block +{ + friend atsc_deinterleaver_sptr atsc_make_deinterleaver(); + + atsci_data_deinterleaver d_deinterleaver; + + atsc_deinterleaver(); + +public: + int work (int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + + void reset() { /* nop */ } +}; + + +#endif /* INCLUDED_ATSC_DEINTERLEAVER_H */ diff --git a/gr-atsc/src/lib/atsc_depad.cc b/gr-atsc/src/lib/atsc_depad.cc new file mode 100644 index 000000000..e63eebc3a --- /dev/null +++ b/gr-atsc/src/lib/atsc_depad.cc @@ -0,0 +1,80 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <atsc_depad.h> +#include <gr_io_signature.h> +#include <atsc_types.h> + +static const int INTR = ATSC_MPEG_PKT_LENGTH; + +atsc_depad_sptr +atsc_make_depad() +{ + return atsc_depad_sptr(new atsc_depad()); +} + +atsc_depad::atsc_depad() + : gr_sync_interpolator("atsc_depad", + gr_make_io_signature(1, 1, sizeof(atsc_mpeg_packet)), + gr_make_io_signature(1, 1, sizeof(unsigned char)), + INTR) +{ + reset(); +} + +void +atsc_depad::forecast (int noutput_items, gr_vector_int &ninput_items_required) +{ + unsigned ninputs = ninput_items_required.size(); + for (unsigned i = 0; i < ninputs; i++) + ninput_items_required[i] = noutput_items / ATSC_MPEG_PKT_LENGTH; +} + + +int +atsc_depad::work (int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) +{ + const atsc_mpeg_packet *in = (const atsc_mpeg_packet *) input_items[0]; + unsigned char *out = (unsigned char *) output_items[0]; + + // size with padding (256) + unsigned int ATSC_MPEG_PKT = sizeof(atsc_mpeg_packet); + unsigned int i; + + for (i = 0; i < noutput_items/ATSC_MPEG_PKT + 1; i++){ + for (int j = 0; j < ATSC_MPEG_PKT_LENGTH; j++) + out[i * ATSC_MPEG_PKT_LENGTH + j] = in[i * ATSC_MPEG_PKT].data[j]; + + } + + return i * ATSC_MPEG_PKT_LENGTH; +} + + + + diff --git a/gr-atsc/src/lib/atsc_depad.h b/gr-atsc/src/lib/atsc_depad.h new file mode 100644 index 000000000..3db933b57 --- /dev/null +++ b/gr-atsc/src/lib/atsc_depad.h @@ -0,0 +1,55 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ +#ifndef INCLUDED_ATSC_DEPAD_H +#define INCLUDED_ATSC_DEPAD_H + +#include <gr_sync_interpolator.h> + +class atsc_depad; +typedef boost::shared_ptr<atsc_depad> atsc_depad_sptr; + +atsc_depad_sptr atsc_make_depad(); + +/*! + * \brief depad mpeg ts packets from 256 byte atsc_mpeg_packet + * to 188 byte char + * \ingroup atsc + * + * input: atsc_mpeg_packet; output: unsigned char + */ +class atsc_depad : public gr_sync_interpolator +{ + friend atsc_depad_sptr atsc_make_depad(); + + atsc_depad(); + +public: + void forecast (int noutput_items, gr_vector_int &ninput_items_required); + int work (int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + + void reset() { /* nop */ } +}; + + +#endif /* INCLUDED_ATSC_DEPAD_H */ diff --git a/gr-atsc/src/lib/atsc_derandomizer.cc b/gr-atsc/src/lib/atsc_derandomizer.cc new file mode 100644 index 000000000..2a411271a --- /dev/null +++ b/gr-atsc/src/lib/atsc_derandomizer.cc @@ -0,0 +1,79 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <atsc_derandomizer.h> +#include <gr_io_signature.h> +#include <atsc_consts.h> + + +atsc_derandomizer_sptr +atsc_make_derandomizer() +{ + return atsc_derandomizer_sptr(new atsc_derandomizer()); +} + +atsc_derandomizer::atsc_derandomizer() + : gr_sync_block("atsc_derandomizer", + gr_make_io_signature(1, 1, sizeof(atsc_mpeg_packet_no_sync)), + gr_make_io_signature(1, 1, sizeof(atsc_mpeg_packet))) +{ + reset(); +} + +void +atsc_derandomizer::reset() +{ + d_rand.reset(); +} + +int +atsc_derandomizer::work (int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) +{ + const atsc_mpeg_packet_no_sync *in = (const atsc_mpeg_packet_no_sync *) input_items[0]; + atsc_mpeg_packet *out = (atsc_mpeg_packet *) output_items[0]; + + for (int i = 0; i < noutput_items; i++){ + + assert(in[i].pli.regular_seg_p()); + + if (in[i].pli.first_regular_seg_p()) + d_rand.reset(); + + d_rand.derandomize(out[i], in[i]); + + // Check the pipeline info for error status and and set the + // corresponding bit in transport packet header. + + if (in[i].pli.transport_error_p()) + out[i].data[1] |= MPEG_TRANSPORT_ERROR_BIT; + else + out[i].data[1] &= ~MPEG_TRANSPORT_ERROR_BIT; + } + + return noutput_items; +} diff --git a/gr-atsc/src/lib/atsc_derandomizer.h b/gr-atsc/src/lib/atsc_derandomizer.h new file mode 100644 index 000000000..97cb3a2f0 --- /dev/null +++ b/gr-atsc/src/lib/atsc_derandomizer.h @@ -0,0 +1,56 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ +#ifndef INCLUDED_ATSC_DERANDOMIZER_H +#define INCLUDED_ATSC_DERANDOMIZER_H + +#include <gr_sync_block.h> +#include <atsci_randomizer.h> + +class atsc_derandomizer; +typedef boost::shared_ptr<atsc_derandomizer> atsc_derandomizer_sptr; + +atsc_derandomizer_sptr atsc_make_derandomizer(); + +/*! + * \brief "dewhiten" incoming mpeg transport stream packets + * \ingroup atsc + * + * input: atsc_mpeg_packet_no_sync; output: atsc_mpeg_packet; + */ +class atsc_derandomizer : public gr_sync_block +{ + friend atsc_derandomizer_sptr atsc_make_derandomizer(); + + atsci_randomizer d_rand; + + atsc_derandomizer(); + +public: + int work (int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + + void reset(); +}; + + +#endif /* INCLUDED_ATSC_DERANDOMIZER_H */ diff --git a/gr-atsc/src/lib/atsc_ds_to_softds.cc b/gr-atsc/src/lib/atsc_ds_to_softds.cc new file mode 100644 index 000000000..682cea027 --- /dev/null +++ b/gr-atsc/src/lib/atsc_ds_to_softds.cc @@ -0,0 +1,73 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <atsc_ds_to_softds.h> +#include <gr_io_signature.h> +#include <atsc_consts.h> + + +atsc_ds_to_softds_sptr +atsc_make_ds_to_softds() +{ + return atsc_ds_to_softds_sptr(new atsc_ds_to_softds()); +} + +atsc_ds_to_softds::atsc_ds_to_softds() + : gr_sync_block("atsc_ds_to_softds", + gr_make_io_signature(1, 1, sizeof(atsc_data_segment)), + gr_make_io_signature(1, 1, sizeof(atsc_soft_data_segment))) +{ + reset(); +} + +#define NELEM(x) (sizeof (x) / sizeof (x[0])) + +void +atsc_ds_to_softds::map_to_soft_symbols (atsc_soft_data_segment &out, + const atsc_data_segment &in) +{ + for (unsigned int i = 0; i < NELEM (in.data); i++){ + out.data[i] = in.data[i] * 2 - 7; + } +} + + +int +atsc_ds_to_softds::work (int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) +{ + const atsc_data_segment *in = (const atsc_data_segment *) input_items[0]; + atsc_soft_data_segment *out = (atsc_soft_data_segment *) output_items[0]; + + for (int i = 0; i < noutput_items; i++){ + + out[i].pli = in[i].pli; // copy pipeline info... + map_to_soft_symbols(out[i], in[i]); + } + + return noutput_items; +} diff --git a/gr-atsc/src/lib/atsc_ds_to_softds.h b/gr-atsc/src/lib/atsc_ds_to_softds.h new file mode 100644 index 000000000..837da7dbb --- /dev/null +++ b/gr-atsc/src/lib/atsc_ds_to_softds.h @@ -0,0 +1,58 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ +#ifndef INCLUDED_ATSC_DS_TO_SOFTDS_H +#define INCLUDED_ATSC_DS_TO_SOFTDS_H + +#include <gr_sync_block.h> +#include <atsc_types.h> + +class atsc_ds_to_softds; +typedef boost::shared_ptr<atsc_ds_to_softds> atsc_ds_to_softds_sptr; + +atsc_ds_to_softds_sptr atsc_make_ds_to_softds(); + +/*! + * \brief Debug glue routine (atsc_data_segment --> atsc_soft_data_segment) + * \ingroup atsc + * + * input: atsc_data_segment; output: atsc_soft_data_segment + */ +class atsc_ds_to_softds : public gr_sync_block +{ + friend atsc_ds_to_softds_sptr atsc_make_ds_to_softds(); + + atsc_ds_to_softds(); + +public: + int work (int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + + void map_to_soft_symbols (atsc_soft_data_segment &out, + const atsc_data_segment &in); + + + void reset() { /* nop */ } +}; + + +#endif /* INCLUDED_ATSC_DS_TO_SOFTDS_H */ diff --git a/gr-atsc/src/lib/atsc_equalizer.cc b/gr-atsc/src/lib/atsc_equalizer.cc new file mode 100644 index 000000000..168d62209 --- /dev/null +++ b/gr-atsc/src/lib/atsc_equalizer.cc @@ -0,0 +1,97 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <atsc_equalizer.h> +#include <create_atsci_equalizer.h> +#include <gr_io_signature.h> +#include <atsc_consts.h> +#include <atsci_syminfo.h> + + +atsc_equalizer_sptr +atsc_make_equalizer() +{ + return atsc_equalizer_sptr(new atsc_equalizer()); +} + +// had atsc_equalizer(atsci_equalizer *equalizer) +atsc_equalizer::atsc_equalizer() + : gr_sync_block("atsc_equalizer", + gr_make_io_signature(2, 2, sizeof(float)), + gr_make_io_signature(2, 2, sizeof(float))) +{ + d_equalizer = create_atsci_equalizer_lms(); +} + +atsc_equalizer::~atsc_equalizer () +{ + // Anything that isn't automatically cleaned up... + + delete d_equalizer; +} + + +void +atsc_equalizer::forecast (int noutput_items, gr_vector_int &ninput_items_required) +{ + + int ntaps = d_equalizer->ntaps (); + int npretaps = d_equalizer->npretaps (); + + assert (ntaps >= 1); + assert (npretaps >= 0 && npretaps < ntaps); + + unsigned ninputs = ninput_items_required.size(); + for (unsigned i = 0; i < ninputs; i++) + ninput_items_required[i] = fixed_rate_noutput_to_ninput (noutput_items); +} + + +int +atsc_equalizer::work (int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) +{ + const float *in = (const float *) input_items[0]; + const atsc::syminfo *in_tags = (const atsc::syminfo *) input_items[1]; + float *out = (float *) output_items[0]; + atsc::syminfo *out_tags = (atsc::syminfo *) output_items[1]; + + assert(sizeof(float) == sizeof(atsc::syminfo)); + + + // peform the actual equalization + + d_equalizer->filter (in, in_tags, + out, noutput_items); + + // write the output tags + + for (int i = 0; i < noutput_items; i++) + out_tags[i] = in_tags[i]; + + return noutput_items; +} diff --git a/gr-atsc/src/lib/atsc_equalizer.h b/gr-atsc/src/lib/atsc_equalizer.h new file mode 100644 index 000000000..a8f448d7e --- /dev/null +++ b/gr-atsc/src/lib/atsc_equalizer.h @@ -0,0 +1,63 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ +#ifndef INCLUDED_ATSC_EQUALIZER_H +#define INCLUDED_ATSC_EQUALIZER_H + +#include <gr_sync_block.h> +#include <atsci_equalizer.h> + +class atsc_equalizer; +typedef boost::shared_ptr<atsc_equalizer> atsc_equalizer_sptr; + +atsc_equalizer_sptr atsc_make_equalizer(); + +/*! + * \brief ATSC equalizer (float,syminfo --> float,syminfo) + * \ingroup atsc + * + * first inputs are data samples, second inputs are tags. + * first outputs are equalized data samples, second outputs are tags. + */ +class atsc_equalizer : public gr_sync_block +{ + friend atsc_equalizer_sptr atsc_make_equalizer(); + + atsc_equalizer(); + +public: + void forecast (int noutput_items, gr_vector_int &ninput_items_required); + int work (int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + + void reset() { /* nop */ } + + ~atsc_equalizer (); + + +protected: + atsci_equalizer *d_equalizer; + +}; + + +#endif /* INCLUDED_ATSC_EQUALIZER_H */ diff --git a/gr-atsc/src/lib/atsc_field_sync_demux.cc b/gr-atsc/src/lib/atsc_field_sync_demux.cc new file mode 100644 index 000000000..d30947d55 --- /dev/null +++ b/gr-atsc/src/lib/atsc_field_sync_demux.cc @@ -0,0 +1,188 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <cmath> +#include <atsc_field_sync_demux.h> +#include <gr_io_signature.h> +#include <atsc_types.h> +#include <atsc_consts.h> +#include <atsci_syminfo.h> +#include <stdio.h> +#include <assert.h> +#include <iostream.h> + +using std::abs; + +static const int DEC = ATSC_DATA_SEGMENT_LENGTH; // nominal decimation factor + + +atsc_field_sync_demux_sptr +atsc_make_field_sync_demux() +{ + return atsc_field_sync_demux_sptr(new atsc_field_sync_demux()); +} + +atsc_field_sync_demux::atsc_field_sync_demux() + : gr_sync_decimator("atsc_field_sync_demux", + gr_make_io_signature(2, 2, sizeof(float)), + gr_make_io_signature(1, 1, sizeof(atsc_soft_data_segment)),DEC), + d_locked(false), d_in_field2(true), d_segment_number(0), + d_next_input(0), d_lost_index(0) +{ + reset(); +} + +inline static bool +tag_is_seg_sync_or_field_sync (atsc::syminfo tag) +{ + return tag.symbol_num == 0 && tag.valid; +} + +void +atsc_field_sync_demux::forecast (int noutput_items, gr_vector_int &ninput_items_required) +{ + unsigned ninputs = ninput_items_required.size(); + for (unsigned i = 0; i < ninputs; i++) { + ninput_items_required[i] = noutput_items * DEC + 2 * DEC - 1; + + inputs0_index = d_next_input; + inputs0_size = noutput_items * DEC + 2 * DEC - 1; + } +} + + +int +atsc_field_sync_demux::work (int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) +{ + float *in = (float *) input_items[0]; + atsc::syminfo *input_tags = (atsc::syminfo *) input_items[1]; + atsc_soft_data_segment *out = (atsc_soft_data_segment *) output_items[0]; + + assert(sizeof(float) == sizeof(atsc::syminfo)); + + int ii = 0; // input index + + // Are we in sync? + if (!tag_is_seg_sync_or_field_sync (input_tags[0])){ // No ... + + if (d_locked){ + d_locked = false; + d_lost_index = inputs0_index + ii; + cerr << "atsc_field_sync_demux: lost sync at " + << d_lost_index << endl; + } + + // ... search for beginning of a field sync + + // cerr << "atsc_field_sync_demux: searching for sync at " + // << inputs0_index + ii << endl; + + for (ii = 1; ii < inputs0_size; ii++){ + if (atsc::tag_is_start_field_sync (input_tags[ii])){ + // found one + d_locked = true; + + const char *str; + if (atsc::tag_is_start_field_sync_1 (input_tags[ii])) + str = "FIELD-1"; + else if (atsc::tag_is_start_field_sync_2 (input_tags[ii])) + str = "FIELD-2"; + else + str = "SEGMENT"; + + cerr << "atsc_field_sync_demux: synced (" << str << ") at " + << inputs0_index + ii + << " [delta = " << inputs0_index + ii - d_lost_index + << "]\n"; + + d_next_input += ii; // update for forecast + return 0; // no work completed so far + } + } + // no non-NORMAL tag found + d_next_input += ii; // update for forecast + return 0; // no work completed so far + } + + // We are in sync. Produce output... + + int k = 0; // output index + + while (k < noutput_items){ + + if (inputs0_size - ii < ATSC_DATA_SEGMENT_LENGTH){ + // We're out of input data. + cerr << "atsc_field_sync_demux: ran out of input data\n"; + d_next_input += ii; // update for forecast + return k; // return amount of work completed so far + } + + if (!tag_is_seg_sync_or_field_sync (input_tags[ii])){ + // lost sync... + cerr << "atsc_field_sync_demux: lost sync at " + << inputs0_index + ii << endl; + + d_next_input += ii; // update for forecast + return k; // return amount of work completed so far + } + + if (atsc::tag_is_start_field_sync_1 (input_tags[ii])){ + d_in_field2 = false; + d_segment_number = 0; + ii += ATSC_DATA_SEGMENT_LENGTH; // skip over field sync + continue; + } + + if (atsc::tag_is_start_field_sync_2 (input_tags[ii])){ + d_in_field2 = true; + d_segment_number = 0; + ii += ATSC_DATA_SEGMENT_LENGTH; // skip over field sync + continue; + } + + if (d_segment_number >= ATSC_DSEGS_PER_FIELD){ + // something's wrong... + cerr << "atsc_field_sync_demux: segment number overflow\n"; + d_segment_number = 0; + } + + out[k].pli.set_regular_seg (d_in_field2, d_segment_number++); + for (int jj = 0; jj < ATSC_DATA_SEGMENT_LENGTH; jj++) + out[k].data[jj] = in[ii + jj]; + ii += ATSC_DATA_SEGMENT_LENGTH; + k++; + } + + d_next_input += ii; // update for forecast + return k; // return amount of work completed + +} + + + + diff --git a/gr-atsc/src/lib/atsc_field_sync_demux.h b/gr-atsc/src/lib/atsc_field_sync_demux.h new file mode 100644 index 000000000..7ce64b524 --- /dev/null +++ b/gr-atsc/src/lib/atsc_field_sync_demux.h @@ -0,0 +1,68 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ +#ifndef INCLUDED_ATSC_FIELD_SYNC_DEMUX_H +#define INCLUDED_ATSC_FIELD_SYNC_DEMUX_H + +#include <gr_sync_decimator.h> +#include <atsc_types.h> + +class atsc_field_sync_demux; +typedef boost::shared_ptr<atsc_field_sync_demux> atsc_field_sync_demux_sptr; + +atsc_field_sync_demux_sptr atsc_make_field_sync_demux(); + +/*! + * \brief ATSC Field Sync Demux + * + * This class accepts 1 stream of floats (data), and 1 stream of tags (syminfo). * It outputs one stream of atsc_soft_data_segment packets + * \ingroup atsc + * + * input: atsc_data_segment; output: atsc_data_segment + */ +class atsc_field_sync_demux : public gr_sync_decimator +{ + friend atsc_field_sync_demux_sptr atsc_make_field_sync_demux(); + + atsc_field_sync_demux(); + +public: + void forecast (int noutput_items, gr_vector_int &ninput_items_required); + int work (int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + + void reset() { /* nop */ } + +protected: + bool d_locked; + bool d_in_field2; + int d_segment_number; + gr_uint64 d_next_input; + gr_uint64 d_lost_index; // diagnostic fluff + + unsigned long long inputs0_index; // for inputs[0].index + unsigned long inputs0_size; // for inputs[0].size + +}; + + +#endif /* INCLUDED_ATSC_FIELD_SYNC_DEMUX_H */ diff --git a/gr-atsc/src/lib/atsc_field_sync_mux.cc b/gr-atsc/src/lib/atsc_field_sync_mux.cc new file mode 100644 index 000000000..edaa24148 --- /dev/null +++ b/gr-atsc/src/lib/atsc_field_sync_mux.cc @@ -0,0 +1,203 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <atsc_field_sync_mux.h> +#include <gr_io_signature.h> +#include <atsc_consts.h> +#include <atsci_pnXXX.h> + + +atsc_field_sync_mux_sptr +atsc_make_field_sync_mux() +{ + return atsc_field_sync_mux_sptr(new atsc_field_sync_mux()); +} + +atsc_field_sync_mux::atsc_field_sync_mux() + : gr_sync_block("atsc_field_sync_mux", + gr_make_io_signature(1, 1, sizeof(atsc_data_segment)), + gr_make_io_signature(1, 1, sizeof(atsc_data_segment))) +{ + reset(); +} + +static const int NUMBER_OF_OUTPUTS = 1; // # of output streams (almost always one) + +static const int N_SAVED_SYMBOLS = atsc_field_sync_mux::N_SAVED_SYMBOLS; + +static void +init_field_sync_common (unsigned char *p, int mask, + const unsigned char saved_symbols[N_SAVED_SYMBOLS]) +{ + static const unsigned char bin_map[2] = { 1, 6 }; // map binary values to 1 of 8 levels + + int i = 0; + + p[i++] = bin_map[1]; // data segment sync pulse + p[i++] = bin_map[0]; + p[i++] = bin_map[0]; + p[i++] = bin_map[1]; + + for (int j = 0; j < 511; j++) // PN511 + p[i++] = bin_map[atsc_pn511[j]]; + + for (int j = 0; j < 63; j++) // PN63 + p[i++] = bin_map[atsc_pn63[j]]; + + for (int j = 0; j < 63; j++) // PN63, toggled on field 2 + p[i++] = bin_map[atsc_pn63[j] ^ mask]; + + for (int j = 0; j < 63; j++) // PN63 + p[i++] = bin_map[atsc_pn63[j]]; + + p[i++] = bin_map[0]; // 24 bits of VSB8 mode identifiera + p[i++] = bin_map[0]; + p[i++] = bin_map[0]; + p[i++] = bin_map[0]; + + p[i++] = bin_map[1]; + p[i++] = bin_map[0]; + p[i++] = bin_map[1]; + p[i++] = bin_map[0]; + + p[i++] = bin_map[0]; + p[i++] = bin_map[1]; + p[i++] = bin_map[0]; + p[i++] = bin_map[1]; + + p[i++] = bin_map[1]; + p[i++] = bin_map[1]; + p[i++] = bin_map[1]; + p[i++] = bin_map[1]; + + p[i++] = bin_map[0]; + p[i++] = bin_map[1]; + p[i++] = bin_map[0]; + p[i++] = bin_map[1]; + + p[i++] = bin_map[1]; + p[i++] = bin_map[0]; + p[i++] = bin_map[1]; + p[i++] = bin_map[0]; + + + for (int j = 0; j < 92; j++) // 92 more bits + p[i++] = bin_map[atsc_pn63[j % 63]]; + + // now copy the last 12 symbols of the previous segment + + for (int j = 0; j < N_SAVED_SYMBOLS; j++) + p[i++] = saved_symbols[j]; + + assert (i == ATSC_DATA_SEGMENT_LENGTH); +} +inline static void +init_field_sync_1 (atsc_data_segment *s, + const unsigned char saved_symbols[N_SAVED_SYMBOLS]) +{ + init_field_sync_common (&s->data[0], 0, saved_symbols); +} + +inline static void +init_field_sync_2 (atsc_data_segment *s, + const unsigned char saved_symbols[N_SAVED_SYMBOLS]) + +{ + init_field_sync_common (&s->data[0], 1, saved_symbols); +} + +static void +save_last_symbols (unsigned char saved_symbols[N_SAVED_SYMBOLS], + const atsc_data_segment &seg) +{ + for (int i = 0; i < N_SAVED_SYMBOLS; i++) + saved_symbols[i] = seg.data[i + ATSC_DATA_SEGMENT_LENGTH - N_SAVED_SYMBOLS];} + + +inline static bool +last_regular_seg_p (const plinfo &pli) +{ + return pli.regular_seg_p () && (pli.segno () == ATSC_DSEGS_PER_FIELD - 1); +} + +void +atsc_field_sync_mux::forecast (int noutput_items, gr_vector_int &ninput_items_required) +{ + unsigned ninputs = ninput_items_required.size(); + for (unsigned i = 0; i < ninputs; i++) + ninput_items_required[i] = fixed_rate_noutput_to_ninput (noutput_items); + +} + + +int +atsc_field_sync_mux::work (int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) +{ + const atsc_data_segment *in = (const atsc_data_segment *) input_items[0]; + atsc_data_segment *out = (atsc_data_segment *) output_items[0]; + + unsigned int index = 0; + for (unsigned int outdex = 0; outdex < noutput_items; outdex++){ + + assert (in[index].pli.regular_seg_p ()); + + if (!in[index].pli.first_regular_seg_p ()){ + out[outdex] = in[index]; // just copy in to out + + if (last_regular_seg_p (in[index].pli)) + save_last_symbols (d_saved_symbols, in[index]); + + index++; + } + else { // first_regular_seg_p + if (!d_already_output_field_sync){ + // write out field sync... + atsc_data_segment field_sync; + + if (in[index].pli.in_field1_p ()) + init_field_sync_1 (&field_sync, d_saved_symbols); + else + init_field_sync_2 (&field_sync, d_saved_symbols); + + // note that index doesn't advance in this branch + out[outdex] = field_sync; + d_already_output_field_sync = true; + } + else { + // already output field sync, now output first regular segment + out[outdex] = in[index]; + index++; + d_already_output_field_sync = false; + } + } + } + + d_current_index += index; + + return noutput_items; +} diff --git a/gr-atsc/src/lib/atsc_field_sync_mux.h b/gr-atsc/src/lib/atsc_field_sync_mux.h new file mode 100644 index 000000000..91000e169 --- /dev/null +++ b/gr-atsc/src/lib/atsc_field_sync_mux.h @@ -0,0 +1,63 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ +#ifndef INCLUDED_ATSC_FIELD_SYNC_MUX_H +#define INCLUDED_ATSC_FIELD_SYNC_MUX_H + +#include <gr_sync_block.h> +#include <atsc_types.h> + +class atsc_field_sync_mux; +typedef boost::shared_ptr<atsc_field_sync_mux> atsc_field_sync_mux_sptr; + +atsc_field_sync_mux_sptr atsc_make_field_sync_mux(); + +/*! + * \brief Insert ATSC Field Syncs as required (atsc_data_segment --> atsc_data_segment) + * \ingroup atsc + * + * input: atsc_data_segment; output: atsc_data_segment + */ +class atsc_field_sync_mux : public gr_sync_block +{ + friend atsc_field_sync_mux_sptr atsc_make_field_sync_mux(); + + atsc_field_sync_mux(); + +public: + void forecast (int noutput_items, gr_vector_int &ninput_items_required); + int work (int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + + + static const int N_SAVED_SYMBOLS = 12; + + void reset() { /* nop */ } + +protected: + gr_uint64 d_current_index; + bool d_already_output_field_sync; + unsigned char d_saved_symbols[N_SAVED_SYMBOLS]; +}; + + +#endif /* INCLUDED_ATSC_FIELD_SYNC_MUX_H */ diff --git a/gr-atsc/src/lib/atsc_fpll.cc b/gr-atsc/src/lib/atsc_fpll.cc new file mode 100644 index 000000000..087a8080a --- /dev/null +++ b/gr-atsc/src/lib/atsc_fpll.cc @@ -0,0 +1,136 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <atsc_fpll.h> +#include <gr_io_signature.h> +#include <atsc_consts.h> +#include <algorithm> +#include "fpll_btloop_coupling.h" + + +atsc_fpll_sptr +atsc_make_fpll() +{ + return atsc_fpll_sptr(new atsc_fpll()); +} + + +/* + * I strongly suggest that you not mess with these... + * + * They are strongly coupled into the symbol timing code and + * their value also sets the level of the symbols going + * into the equalizer and viterbi decoder. + */ +static const float FPLL_AGC_REFERENCE = 2.5 * FPLL_BTLOOP_COUPLING_CONST; +static const float FPLL_AGC_RATE = 0.25e-6; + + + +atsc_fpll::atsc_fpll() + : gr_sync_block("atsc_fpll", + gr_make_io_signature(1, 1, sizeof(float)), + gr_make_io_signature(1, 1, sizeof(float))), + initial_phase(0) +{ + initial_freq = 5.75e6 - 3e6 + 0.31e6 + 5e3; // a_initial_freq; + agc.set_rate (FPLL_AGC_RATE); + agc.set_reference (FPLL_AGC_REFERENCE); + initialize(); +} + + +void +atsc_fpll::initialize () +{ + float Fs = 20e6; + + float alpha = 1 - exp(-1.0 / Fs / 5e-6); + + afci.set_taps (alpha); + afcq.set_taps (alpha); + + printf("Setting initial_freq: %f\n",initial_freq); + nco.set_freq (initial_freq / Fs * 2 * M_PI); + nco.set_phase (initial_phase); +} + + +int +atsc_fpll::work (int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) +{ + const float *in = (const float *) input_items[0]; + float *out = (float *) output_items[0]; + + for (int k = 0; k < noutput_items; k++){ + + float a_cos, a_sin; + + float input = agc.scale (in[k]); + + nco.step (); // increment phase + nco.sincos (&a_sin, &a_cos); // compute cos and sin + + float I = input * a_sin; + float Q = input * a_cos; + + out[k] = I; + + float filtered_I = afci.filter (I); + float filtered_Q = afcq.filter (Q); + + // phase detector + + float x = atan2 (filtered_Q, filtered_I); + + // avoid slamming filter with big transitions + + static const float limit = M_PI / 2; + + if (x > limit) + x = limit; + else if (x < -limit) + x = -limit; + + // static const float alpha = 0.037; // Max value + // static const float alpha = 0.005; // takes about 5k samples to pull in, stddev = 323 + // static const float alpha = 0.002; // takes about 15k samples to pull in, stddev = 69 + // or about 120k samples on noisy data, + static const float alpha = 0.001; + static const float beta = alpha * alpha / 4; + + nco.adjust_phase (alpha * x); + nco.adjust_freq (beta * x); + + } + + return noutput_items; +} + + + diff --git a/gr-atsc/src/lib/atsc_fpll.h b/gr-atsc/src/lib/atsc_fpll.h new file mode 100644 index 000000000..b6213bac7 --- /dev/null +++ b/gr-atsc/src/lib/atsc_fpll.h @@ -0,0 +1,78 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ +#ifndef INCLUDED_ATSC_FPLL_H +#define INCLUDED_ATSC_FPLL_H + +#include <gr_sync_block.h> +#include <gr_nco.h> +#include <gr_single_pole_iir.h> +#include <gri_agc.h> +#include <stdio.h> +#include <atsci_diag_output.h> + +class atsc_fpll; +typedef boost::shared_ptr<atsc_fpll> atsc_fpll_sptr; + +atsc_fpll_sptr atsc_make_fpll(); + +/*! + * \brief ATSC FPLL (2nd Version) + * \ingroup atsc + * + * A/D --> GrFIRfilterFFF ----> GrAtscFPLL ----> + * + * We use GrFIRfilterFFF to bandpass filter the signal of interest. + * + * This class accepts a single real input and produces a single real output + */ + +class atsc_fpll : public gr_sync_block +{ + friend atsc_fpll_sptr atsc_make_fpll(); + + atsc_fpll(); + +public: + + int work (int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + + void reset() { /* nop */ } + + void initialize () ; + + protected: + + double initial_freq; + double initial_phase; + bool debug_no_update; + gr_nco<float,float> nco; + gri_agc agc; // automatic gain control + gr_single_pole_iir<float,float,float> afci; + gr_single_pole_iir<float,float,float> afcq; + + +}; + + +#endif /* INCLUDED_ATSC_FPLL_H */ diff --git a/gr-atsc/src/lib/atsc_fs_checker.cc b/gr-atsc/src/lib/atsc_fs_checker.cc new file mode 100644 index 000000000..10d8353e8 --- /dev/null +++ b/gr-atsc/src/lib/atsc_fs_checker.cc @@ -0,0 +1,75 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <atsc_fs_checker.h> +#include <create_atsci_fs_checker.h> +#include <atsci_fs_checker.h> +#include <gr_io_signature.h> +#include <atsc_consts.h> +#include <atsci_syminfo.h> + + +atsc_fs_checker_sptr +atsc_make_fs_checker() +{ + return atsc_fs_checker_sptr(new atsc_fs_checker()); +} + +atsc_fs_checker::atsc_fs_checker() + : gr_sync_block("atsc_fs_checker", + gr_make_io_signature(2, 2, sizeof(float)), + gr_make_io_signature(2, 2, sizeof(float))) +{ + d_fsc = create_atsci_fs_checker(); +} + + +atsc_fs_checker::~atsc_fs_checker () +{ + // Anything that isn't automatically cleaned up... + + delete d_fsc; +} + + +int +atsc_fs_checker::work (int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) +{ + const float *in = (const float *) input_items[0]; + const atsc::syminfo *tag_in = (const atsc::syminfo *) input_items[1]; + float *out = (float *) output_items[0]; + atsc::syminfo *tag_out = (atsc::syminfo *) output_items[1]; + + assert(sizeof(float) == sizeof(atsc::syminfo)); + + + for (int i = 0; i < noutput_items; i++) + d_fsc->filter (in[i], tag_in[i], &out[i], &tag_out[i]); + + return noutput_items; +} diff --git a/gr-atsc/src/lib/atsc_fs_checker.h b/gr-atsc/src/lib/atsc_fs_checker.h new file mode 100644 index 000000000..a844cd3b2 --- /dev/null +++ b/gr-atsc/src/lib/atsc_fs_checker.h @@ -0,0 +1,62 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ +#ifndef INCLUDED_ATSC_FS_CHECKER_H +#define INCLUDED_ATSC_FS_CHECKER_H + +#include <atsci_fs_checker.h> +#include <gr_sync_block.h> + +class atsc_fs_checker; +typedef boost::shared_ptr<atsc_fs_checker> atsc_fs_checker_sptr; + +atsc_fs_checker_sptr atsc_make_fs_checker(); + +/*! + * \brief ATSC field sync checker (float,syminfo --> float,syminfo) + * \ingroup atsc + * + * first output is delayed version of input. + * second output is set of tags, one-for-one with first output. + */ + +class atsc_fs_checker : public gr_sync_block +{ + friend atsc_fs_checker_sptr atsc_make_fs_checker(); + + atsc_fs_checker(); + +public: + int work (int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + + void reset() { /* nop */ } + + ~atsc_fs_checker (); + +protected: + atsci_fs_checker *d_fsc; + +}; + + +#endif /* INCLUDED_ATSC_FS_CHECKER_H */ diff --git a/gr-atsc/src/lib/atsc_interleaver.cc b/gr-atsc/src/lib/atsc_interleaver.cc new file mode 100644 index 000000000..567c1b461 --- /dev/null +++ b/gr-atsc/src/lib/atsc_interleaver.cc @@ -0,0 +1,59 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <atsc_interleaver.h> +#include <gr_io_signature.h> +#include <atsc_consts.h> + + +atsc_interleaver_sptr +atsc_make_interleaver() +{ + return atsc_interleaver_sptr(new atsc_interleaver()); +} + +atsc_interleaver::atsc_interleaver() + : gr_sync_block("atsc_interleaver", + gr_make_io_signature(1, 1, sizeof(atsc_mpeg_packet_rs_encoded)), + gr_make_io_signature(1, 1, sizeof(atsc_mpeg_packet_rs_encoded))) +{ + reset(); +} + +int +atsc_interleaver::work (int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) +{ + const atsc_mpeg_packet_rs_encoded *in = (const atsc_mpeg_packet_rs_encoded *) input_items[0]; + atsc_mpeg_packet_rs_encoded *out = (atsc_mpeg_packet_rs_encoded *) output_items[0]; + + for (int i = 0; i < noutput_items; i++){ + d_interleaver.interleave (out[i], in[i]); + } + + return noutput_items; +} diff --git a/gr-atsc/src/lib/atsc_interleaver.h b/gr-atsc/src/lib/atsc_interleaver.h new file mode 100644 index 000000000..18fd8e541 --- /dev/null +++ b/gr-atsc/src/lib/atsc_interleaver.h @@ -0,0 +1,55 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ +#ifndef INCLUDED_ATSC_INTERLEAVER_H +#define INCLUDED_ATSC_INTERLEAVER_H + +#include <gr_sync_block.h> +#include <atsci_data_interleaver.h> + +class atsc_interleaver; +typedef boost::shared_ptr<atsc_interleaver> atsc_interleaver_sptr; + +atsc_interleaver_sptr atsc_make_interleaver(); + +/*! \brief Interleave RS encoded ATSC data ( atsc_mpeg_packet_rs_encoded --> atsc_mpeg_packet_rs_encoded)* + * \ingroup atsc + * + * input: atsc_mpeg_packet_rs_encoded; output: atsc_mpeg_packet_rs_encoded + */ +class atsc_interleaver : public gr_sync_block +{ + friend atsc_interleaver_sptr atsc_make_interleaver(); + + atsci_data_interleaver d_interleaver; + + atsc_interleaver(); + +public: + int work (int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + + void reset() { /* nop */ } +}; + + +#endif /* INCLUDED_ATSC_INTERLEAVER_H */ diff --git a/gr-atsc/src/lib/atsc_randomizer.cc b/gr-atsc/src/lib/atsc_randomizer.cc new file mode 100644 index 000000000..7b9fed0eb --- /dev/null +++ b/gr-atsc/src/lib/atsc_randomizer.cc @@ -0,0 +1,87 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <atsc_randomizer.h> +#include <gr_io_signature.h> +#include <atsc_consts.h> + + +atsc_randomizer_sptr +atsc_make_randomizer() +{ + return atsc_randomizer_sptr(new atsc_randomizer()); +} + +atsc_randomizer::atsc_randomizer() + : gr_sync_block("atsc_randomizer", + gr_make_io_signature(1, 1, sizeof(atsc_mpeg_packet)), + gr_make_io_signature(1, 1, sizeof(atsc_mpeg_packet_no_sync))) +{ + reset(); +} + +void +atsc_randomizer::reset() +{ + d_rand.reset(); + d_field2 = false; + d_segno = 0; +} + +int +atsc_randomizer::work (int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) +{ + const atsc_mpeg_packet *in = (const atsc_mpeg_packet *) input_items[0]; + atsc_mpeg_packet_no_sync *out = (atsc_mpeg_packet_no_sync *) output_items[0]; + + for (int i = 0; i < noutput_items; i++){ + + // sanity check incoming data. + assert((in[i].data[0] == MPEG_SYNC_BYTE)); + assert((in[i].data[1] & MPEG_TRANSPORT_ERROR_BIT) == 0); + + // initialize plinfo for downstream + // + // We do this here because the randomizer is effectively + // the head of the tx processing chain + // + out[i].pli.set_regular_seg(d_field2, d_segno); + d_segno++; + if (d_segno == 312){ + d_segno = 0; + d_field2 = !d_field2; + } + + if (out[i].pli.first_regular_seg_p()) + d_rand.reset(); + + d_rand.randomize(out[i], in[i]); + } + + return noutput_items; +} diff --git a/gr-atsc/src/lib/atsc_randomizer.h b/gr-atsc/src/lib/atsc_randomizer.h new file mode 100644 index 000000000..31f20c83d --- /dev/null +++ b/gr-atsc/src/lib/atsc_randomizer.h @@ -0,0 +1,58 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ +#ifndef INCLUDED_ATSC_RANDOMIZER_H +#define INCLUDED_ATSC_RANDOMIZER_H + +#include <gr_sync_block.h> +#include <atsci_randomizer.h> + +class atsc_randomizer; +typedef boost::shared_ptr<atsc_randomizer> atsc_randomizer_sptr; + +atsc_randomizer_sptr atsc_make_randomizer(); + +/*! + * \brief "Whiten" incoming mpeg transport stream packets + * \ingroup atsc + * + * input: atsc_mpeg_packet; output: atsc_mpeg_packet_no_sync + */ +class atsc_randomizer : public gr_sync_block +{ + friend atsc_randomizer_sptr atsc_make_randomizer(); + + atsci_randomizer d_rand; + bool d_field2; // user to init plinfo in output + int d_segno; // likewise + + atsc_randomizer(); + +public: + int work (int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + + void reset(); +}; + + +#endif /* INCLUDED_ATSC_RANDOMIZER_H */ diff --git a/gr-atsc/src/lib/atsc_rs_decoder.cc b/gr-atsc/src/lib/atsc_rs_decoder.cc new file mode 100644 index 000000000..7885cca42 --- /dev/null +++ b/gr-atsc/src/lib/atsc_rs_decoder.cc @@ -0,0 +1,63 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <atsc_rs_decoder.h> +#include <gr_io_signature.h> +#include <atsc_consts.h> + + +atsc_rs_decoder_sptr +atsc_make_rs_decoder() +{ + return atsc_rs_decoder_sptr(new atsc_rs_decoder()); +} + +atsc_rs_decoder::atsc_rs_decoder() + : gr_sync_block("atsc_rs_decoder", + gr_make_io_signature(1, 1, sizeof(atsc_mpeg_packet_rs_encoded)), + gr_make_io_signature(1, 1, sizeof(atsc_mpeg_packet_no_sync))) +{ + reset(); +} + +int +atsc_rs_decoder::work (int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) +{ + const atsc_mpeg_packet_rs_encoded *in = (const atsc_mpeg_packet_rs_encoded *) input_items[0]; + atsc_mpeg_packet_no_sync *out = (atsc_mpeg_packet_no_sync *) output_items[0]; + + for (int i = 0; i < noutput_items; i++){ + assert(in[i].pli.regular_seg_p()); + out[i].pli = in[i].pli; // copy pipeline info... + + int nerrors_corrrected = d_rs_decoder.decode(out[i], in[i]); + out[i].pli.set_transport_error(nerrors_corrrected == -1); + } + + return noutput_items; +} diff --git a/gr-atsc/src/lib/atsc_rs_decoder.h b/gr-atsc/src/lib/atsc_rs_decoder.h new file mode 100644 index 000000000..7c10a3db7 --- /dev/null +++ b/gr-atsc/src/lib/atsc_rs_decoder.h @@ -0,0 +1,56 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ +#ifndef INCLUDED_ATSC_RS_DECODER_H +#define INCLUDED_ATSC_RS_DECODER_H + +#include <gr_sync_block.h> +#include <atsci_reed_solomon.h> + +class atsc_rs_decoder; +typedef boost::shared_ptr<atsc_rs_decoder> atsc_rs_decoder_sptr; + +atsc_rs_decoder_sptr atsc_make_rs_decoder(); + +/*! + * \brief Reed-Solomon decoder for ATSC + * \ingroup atsc + * + * input: atsc_mpeg_packet_rs_encoded; output: atsc_mpeg_packet_no_sync + */ +class atsc_rs_decoder : public gr_sync_block +{ + friend atsc_rs_decoder_sptr atsc_make_rs_decoder(); + + atsci_reed_solomon d_rs_decoder; + + atsc_rs_decoder(); + +public: + int work (int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + + void reset() { /* nop */ } +}; + + +#endif /* INCLUDED_ATSC_RS_DECODER_H */ diff --git a/gr-atsc/src/lib/atsc_rs_encoder.cc b/gr-atsc/src/lib/atsc_rs_encoder.cc new file mode 100644 index 000000000..53f45d59a --- /dev/null +++ b/gr-atsc/src/lib/atsc_rs_encoder.cc @@ -0,0 +1,62 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <atsc_rs_encoder.h> +#include <gr_io_signature.h> +#include <atsc_consts.h> + + +atsc_rs_encoder_sptr +atsc_make_rs_encoder() +{ + return atsc_rs_encoder_sptr(new atsc_rs_encoder()); +} + +atsc_rs_encoder::atsc_rs_encoder() + : gr_sync_block("atsc_rs_encoder", + gr_make_io_signature(1, 1, sizeof(atsc_mpeg_packet_no_sync)), + gr_make_io_signature(1, 1, sizeof(atsc_mpeg_packet_rs_encoded))) +{ + reset(); +} + +int +atsc_rs_encoder::work (int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) +{ + const atsc_mpeg_packet_no_sync *in = (const atsc_mpeg_packet_no_sync *) input_items[0]; + atsc_mpeg_packet_rs_encoded *out = (atsc_mpeg_packet_rs_encoded *) output_items[0]; + + for (int i = 0; i < noutput_items; i++){ + + assert(in[i].pli.regular_seg_p()); + out[i].pli = in[i].pli; // copy pipeline info... + d_rs_encoder.encode(out[i], in[i]); + } + + return noutput_items; +} diff --git a/gr-atsc/src/lib/atsc_rs_encoder.h b/gr-atsc/src/lib/atsc_rs_encoder.h new file mode 100644 index 000000000..da1fd63ea --- /dev/null +++ b/gr-atsc/src/lib/atsc_rs_encoder.h @@ -0,0 +1,56 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ +#ifndef INCLUDED_ATSC_RS_ENCODER_H +#define INCLUDED_ATSC_RS_ENCODER_H + +#include <gr_sync_block.h> +#include <atsci_reed_solomon.h> + +class atsc_rs_encoder; +typedef boost::shared_ptr<atsc_rs_encoder> atsc_rs_encoder_sptr; + +atsc_rs_encoder_sptr atsc_make_rs_encoder(); + +/*! + * \brief Reed-Solomon encoder for ATSC + * \ingroup atsc + * + * input: atsc_mpeg_packet_no_sync; output: atsc_mpeg_packet_rs_encoded + */ +class atsc_rs_encoder : public gr_sync_block +{ + friend atsc_rs_encoder_sptr atsc_make_rs_encoder(); + + atsci_reed_solomon d_rs_encoder; + + atsc_rs_encoder(); + +public: + int work (int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + + void reset() { /* nop */ } +}; + + +#endif /* INCLUDED_ATSC_RS_ENCODER_H */ diff --git a/gr-atsc/src/lib/atsc_trellis_encoder.cc b/gr-atsc/src/lib/atsc_trellis_encoder.cc new file mode 100644 index 000000000..77cf08af4 --- /dev/null +++ b/gr-atsc/src/lib/atsc_trellis_encoder.cc @@ -0,0 +1,60 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <atsc_trellis_encoder.h> +#include <gr_io_signature.h> +#include <atsc_consts.h> + + +atsc_trellis_encoder_sptr +atsc_make_trellis_encoder() +{ + return atsc_trellis_encoder_sptr(new atsc_trellis_encoder()); +} + +atsc_trellis_encoder::atsc_trellis_encoder() + : gr_sync_block("atsc_trellis_encoder", + gr_make_io_signature(1, 1, sizeof(atsc_mpeg_packet_rs_encoded)), + gr_make_io_signature(1, 1, sizeof(atsc_data_segment))) +{ + set_output_multiple(atsci_trellis_encoder::NCODERS); + reset(); +} + +int +atsc_trellis_encoder::work (int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) +{ + const atsc_mpeg_packet_rs_encoded *in = (const atsc_mpeg_packet_rs_encoded *) input_items[0]; + atsc_data_segment *out = (atsc_data_segment *) output_items[0]; + + for (int i = 0; i < atsci_trellis_encoder::NCODERS; i += atsci_trellis_encoder::NCODERS){ + d_trellis_encoder.encode(&out[i], &in[i]); + } + return atsci_trellis_encoder::NCODERS; +} + diff --git a/gr-atsc/src/lib/atsc_trellis_encoder.h b/gr-atsc/src/lib/atsc_trellis_encoder.h new file mode 100644 index 000000000..98b549ef8 --- /dev/null +++ b/gr-atsc/src/lib/atsc_trellis_encoder.h @@ -0,0 +1,56 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ +#ifndef INCLUDED_ATSC_TRELLIS_ENCODER_H +#define INCLUDED_ATSC_TRELLIS_ENCODER_H + +#include <gr_sync_block.h> +#include <atsci_trellis_encoder.h> + +class atsc_trellis_encoder; +typedef boost::shared_ptr<atsc_trellis_encoder> atsc_trellis_encoder_sptr; + +atsc_trellis_encoder_sptr atsc_make_trellis_encoder(); + +/*! + * \brief ATSC 12-way interleaved trellis encoder (atsc_mpeg_packet_rs_encoded --> atsc_data_segment) + * \ingroup atsc + * + * input: atsc_mpeg_packet_rs_encoded; output: atsc_data_segment + */ +class atsc_trellis_encoder : public gr_sync_block +{ + friend atsc_trellis_encoder_sptr atsc_make_trellis_encoder(); + + atsci_trellis_encoder d_trellis_encoder; + + atsc_trellis_encoder(); + +public: + int work (int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + + void reset() { /* nop */ } +}; + + +#endif /* INCLUDED_ATSC_TRELLIS_ENCODER_H */ diff --git a/gr-atsc/src/lib/atsc_types.h b/gr-atsc/src/lib/atsc_types.h new file mode 100644 index 000000000..1a7708ec3 --- /dev/null +++ b/gr-atsc/src/lib/atsc_types.h @@ -0,0 +1,238 @@ +/* -*- c++ -*- */ +/* + * Copyright 2001,2006 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _ATSC_TYPES_H_ +#define _ATSC_TYPES_H_ + +#include <atsc_consts.h> +#include <cstring> +#include <cassert> + + +/*! + * \brief pipeline info that flows with data + * + * Not all modules need all the info + */ +class plinfo { +public: + plinfo () : _flags (0), _segno (0) { } + + // accessors + + bool field_sync1_p () const { return (_flags & fl_field_sync1) != 0; } + bool field_sync2_p () const { return (_flags & fl_field_sync2) != 0; } + bool field_sync_p () const { return field_sync1_p () || field_sync2_p (); } + + bool regular_seg_p () const { return (_flags & fl_regular_seg) != 0; } + + bool in_field1_p () const { return (_flags & fl_field2) == 0; } + bool in_field2_p () const { return (_flags & fl_field2) != 0; } + + bool first_regular_seg_p () const { return (_flags & fl_first_regular_seg) != 0; } + + bool transport_error_p () const { return (_flags & fl_transport_error) != 0; } + + unsigned int segno () const { return _segno; } + unsigned int flags () const { return _flags; } + + // setters + + void set_field_sync1 () + { + _segno = 0; + _flags = fl_field_sync1; + } + + void set_field_sync2 () + { + _segno = 0; + _flags = fl_field_sync2 | fl_field2; + } + + void set_regular_seg (bool field2, int segno) + { + assert (0 <= segno && segno < ATSC_DSEGS_PER_FIELD); + _segno = segno; + _flags = fl_regular_seg; + if (segno == 0) + _flags |= fl_first_regular_seg; + if (segno >= ATSC_DSEGS_PER_FIELD) + _flags |= fl_transport_error; + if (field2) + _flags |= fl_field2; + } + + void set_transport_error (bool error){ + if (error) + _flags |= fl_transport_error; + else + _flags &= ~fl_transport_error; + } + + // overload equality operator + bool operator== (const plinfo &other) const { + return (_flags == other._flags && _segno == other._segno); + } + + bool operator!= (const plinfo &other) const { + return !(_flags == other._flags && _segno == other._segno); + } + + /*! + * Set \p OUT such that it reflects a \p NSEGS_OF_DELAY + * pipeline delay from \p IN. + */ + static void delay (plinfo &out, const plinfo &in, int nsegs_of_delay); + + /*! + * confirm that \p X is plausible + */ + static void sanity_check (const plinfo &in); + + +protected: + unsigned short _flags; // bitmask + unsigned short _segno; // segment number [0,311] + + // these three are mutually exclusive + // This is a regular data segment. + static const int fl_regular_seg = 0x0001; + // This is a field sync segment, for 1st half of a field. + static const int fl_field_sync1 = 0x0002; + // This is a field sync segment, for 2nd half of a field. + static const int fl_field_sync2 = 0x0004; + + // This bit is on ONLY when fl_regular_seg is set AND when this is + // the first regular data segment AFTER a field sync segment. This + // segment causes various processing modules to reset. + static const int fl_first_regular_seg = 0x0008; + + // which field are we in? + static const int fl_field2 = 0x0010; // else field 1 + + // This bit is set when Reed-Solomon decoding detects an error that it + // can't correct. Note that other error detection (e.g. Viterbi) do not + // set it, since Reed-Solomon will correct many of those. This bit is + // then copied into the final Transport Stream packet so that MPEG + // software can see that the 188-byte data segment has been corrupted. + static const int fl_transport_error = 0x0020; +}; + + + + +class atsc_mpeg_packet { + public: + static const int NPAD = 68; + unsigned char data[ATSC_MPEG_DATA_LENGTH + 1]; // first byte is sync + unsigned char _pad_[NPAD]; // pad to power of 2 (256) + + // overload equality operator + bool operator== (const atsc_mpeg_packet &other) const { + return std::memcmp (data, other.data, sizeof (data)) == 0; + }; + + bool operator!= (const atsc_mpeg_packet &other) const { + return !(std::memcmp (data, other.data, sizeof (data)) == 0); + }; +}; + +class atsc_mpeg_packet_no_sync { + public: + static const int NPAD = 65; + plinfo pli; + unsigned char data[ATSC_MPEG_DATA_LENGTH]; + unsigned char _pad_[NPAD]; // pad to power of 2 (256) + + // overload equality operator + bool operator== (const atsc_mpeg_packet_no_sync &other) const { + return std::memcmp (data, other.data, sizeof (data)) == 0; + } + + bool operator!= (const atsc_mpeg_packet_no_sync &other) const { + return !(std::memcmp (data, other.data, sizeof (data)) == 0); + } +}; + +class atsc_mpeg_packet_rs_encoded { + public: + static const int NPAD = 45; + plinfo pli; + unsigned char data[ATSC_MPEG_RS_ENCODED_LENGTH]; + unsigned char _pad_[NPAD]; // pad to power of 2 (256) + + // overload equality operator + bool operator== (const atsc_mpeg_packet_rs_encoded &other) const { + return std::memcmp (data, other.data, sizeof (data)) == 0; + } + + bool operator!= (const atsc_mpeg_packet_rs_encoded &other) const { + return !(std::memcmp (data, other.data, sizeof (data)) == 0); + } +}; + + +//! contains 832 3 bit symbols. The low 3 bits in the byte hold the symbol. + +class atsc_data_segment { + public: + static const int NPAD = 188; + plinfo pli; + unsigned char data[ATSC_DATA_SEGMENT_LENGTH]; + unsigned char _pad_[NPAD]; // pad to power of 2 (1024) + + // overload equality operator + bool operator== (const atsc_data_segment &other) const { + return std::memcmp (data, other.data, sizeof (data)) == 0; + } + + bool operator!= (const atsc_data_segment &other) const { + return !(std::memcmp (data, other.data, sizeof (data)) == 0); + } +}; + +/*! + * Contains 832 bipolar floating point symbols. + * Nominal values are +/- {1, 3, 5, 7}. + * This data type represents the input to the viterbi decoder. + */ + +class atsc_soft_data_segment { + public: + static const int NPAD = 764; + plinfo pli; + float data[ATSC_DATA_SEGMENT_LENGTH]; + unsigned char _pad_[NPAD]; // pad to power of 2 (4096) + + // overload equality operator + bool operator== (const atsc_data_segment &other) const { + return std::memcmp (data, other.data, sizeof (data)) == 0; + } + + bool operator!= (const atsc_data_segment &other) const { + return !(std::memcmp (data, other.data, sizeof (data)) == 0); + } +}; + + +#endif /* _ATSC_TYPES_H_ */ diff --git a/gr-atsc/src/lib/atsc_viterbi_decoder.cc b/gr-atsc/src/lib/atsc_viterbi_decoder.cc new file mode 100644 index 000000000..394ee5035 --- /dev/null +++ b/gr-atsc/src/lib/atsc_viterbi_decoder.cc @@ -0,0 +1,84 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <atsc_viterbi_decoder.h> +#include <gr_io_signature.h> +#include <atsc_consts.h> +#include <iostream.h> + + +atsc_viterbi_decoder_sptr +atsc_make_viterbi_decoder() +{ + return atsc_viterbi_decoder_sptr(new atsc_viterbi_decoder()); +} + +atsc_viterbi_decoder::atsc_viterbi_decoder() + : gr_sync_block("atsc_viterbi_decoder", + gr_make_io_signature(1, 1, sizeof(atsc_soft_data_segment)), + gr_make_io_signature(1, 1, sizeof(atsc_mpeg_packet_rs_encoded))), + last_start(-1) +{ + set_output_multiple(atsci_viterbi_decoder::NCODERS); + reset(); +} + +int +atsc_viterbi_decoder::work (int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) +{ + const atsc_soft_data_segment *in = (const atsc_soft_data_segment *) input_items[0]; + atsc_mpeg_packet_rs_encoded *out = (atsc_mpeg_packet_rs_encoded *) output_items[0]; + + assert (noutput_items % atsci_viterbi_decoder::NCODERS == 0); + + // find the first mod 12 boundary to begin decoding + int start; + for (start = 0; start < atsci_viterbi_decoder::NCODERS; start++){ + assert (in[start].pli.regular_seg_p ()); + if ((in[start].pli.segno () % atsci_viterbi_decoder::NCODERS) == 0) + break; + } + + if (start == atsci_viterbi_decoder::NCODERS){ + // we didn't find a mod 12 boundary. There's some kind of problem + // upstream of us (not yet sync'd??) + cerr << "!!!atsc_viterbi_decoder: no mod-12 boundary found\7\n"; + start = 0; + } + else if (start != last_start){ + cerr << "atsc_viterbi_decoder: new starting offset = " << start + << endl; + last_start = start; + } + + for (int i = 0; i < atsci_viterbi_decoder::NCODERS; i += atsci_viterbi_decoder::NCODERS){ + d_viterbi_decoder.decode(&out[i], &in[i + start]); + } + return atsci_viterbi_decoder::NCODERS; +} + diff --git a/gr-atsc/src/lib/atsc_viterbi_decoder.h b/gr-atsc/src/lib/atsc_viterbi_decoder.h new file mode 100644 index 000000000..931397eda --- /dev/null +++ b/gr-atsc/src/lib/atsc_viterbi_decoder.h @@ -0,0 +1,60 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ +#ifndef INCLUDED_ATSC_VITERBI_DECODER_H +#define INCLUDED_ATSC_VITERBI_DECODER_H + +#include <gr_sync_block.h> +#include <atsci_viterbi_decoder.h> + +class atsc_viterbi_decoder; +typedef boost::shared_ptr<atsc_viterbi_decoder> atsc_viterbi_decoder_sptr; + +atsc_viterbi_decoder_sptr atsc_make_viterbi_decoder(); + +/*! + * \brief ATSC 12-way interleaved viterbi decoder (atsc_soft_data_segment --> atsc_mpeg_packet_rs_encoded) + * \ingroup atsc + * + * input: atsc_soft_data_segment; output: atsc_mpeg_packet_rs_encoded + */ +class atsc_viterbi_decoder : public gr_sync_block +{ + friend atsc_viterbi_decoder_sptr atsc_make_viterbi_decoder(); + + atsci_viterbi_decoder d_viterbi_decoder; + + atsc_viterbi_decoder(); + +public: + int work (int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + + void reset() { /* nop */ } + +protected: + int last_start; + +}; + + +#endif /* INCLUDED_ATSC_VITERBI_DECODER_H */ diff --git a/gr-atsc/src/lib/atsci_basic_trellis_encoder.cc b/gr-atsc/src/lib/atsci_basic_trellis_encoder.cc new file mode 100644 index 000000000..35081eb8e --- /dev/null +++ b/gr-atsc/src/lib/atsci_basic_trellis_encoder.cc @@ -0,0 +1,62 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include <atsci_basic_trellis_encoder.h> +#include <assert.h> + +const unsigned char atsci_basic_trellis_encoder::next_state[32] = { + 0,1,4,5, + 2,3,6,7, + 1,0,5,4, + 3,2,7,6, + 4,5,0,1, + 6,7,2,3, + 5,4,1,0, + 7,6,3,2 +}; + +const unsigned char atsci_basic_trellis_encoder::out_symbol[32] = { + 0,2,4,6, + 1,3,5,7, + 0,2,4,6, + 1,3,5,7, + 4,6,0,2, + 5,7,1,3, + 4,6,0,2, + 5,7,1,3 +}; + + +/*! + * Encode two bit INPUT into 3 bit return value. Domain is [0,3], + * Range is [0,7]. The mapping to bipolar levels is not done. + */ + +int +atsci_basic_trellis_encoder::encode (unsigned int input) +{ + assert (input < 4); + int index = (state << 2) + input; + state = next_state[index]; + return out_symbol[index]; +} + diff --git a/gr-atsc/src/lib/atsci_basic_trellis_encoder.h b/gr-atsc/src/lib/atsci_basic_trellis_encoder.h new file mode 100644 index 000000000..34c45e471 --- /dev/null +++ b/gr-atsc/src/lib/atsci_basic_trellis_encoder.h @@ -0,0 +1,60 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ +#ifndef _ATSC_BASIC_TRELLIS_ENCODER_H_ +#define _ATSC_BASIC_TRELLIS_ENCODER_H_ + +#include <assert.h> + +/*! + * \brief ATSC trellis encoder building block. + * + * Note this is NOT the 12x interleaved interface. + * + * This implements a single instance of the ATSC trellis encoder. + * This is a rate 2/3 encoder (really a constraint length 3, rate 1/2 + * encoder with the top bit passed through unencoded. This does not + * implement the "precoding" of the top bit, because the NTSC rejection + * filter is not supported. + */ + +class atsci_basic_trellis_encoder { + +private: + int state; // two bit state; + +public: + atsci_basic_trellis_encoder () : state (0) {} + + /*! + * Encode two bit INPUT into 3 bit return value. Domain is [0,3], + * Range is [0,7]. The mapping to bipolar levels is not done. + */ + int encode (unsigned int input); + + //! reset encoder state + void reset () { state = 0; } + + static const unsigned char next_state[32]; + static const unsigned char out_symbol[32]; +}; + +#endif /* _ATSC_BASIC_TRELLIS_ENCODER_H_ */ diff --git a/gr-atsc/src/lib/atsci_data_interleaver.cc b/gr-atsc/src/lib/atsci_data_interleaver.cc new file mode 100644 index 000000000..4826df79d --- /dev/null +++ b/gr-atsc/src/lib/atsci_data_interleaver.cc @@ -0,0 +1,61 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include <atsci_data_interleaver.h> + +void +atsci_data_interleaver::interleave (atsc_mpeg_packet_rs_encoded &out, + const atsc_mpeg_packet_rs_encoded &in) +{ + assert (in.pli.regular_seg_p ()); + plinfo::sanity_check (in.pli); + + out.pli = in.pli; // copy pipeline info + if (in.pli.first_regular_seg_p ()) // reset commutator if required + sync (); + + transform (out.data, in.data, sizeof (in.data)); +} + + +void +atsci_data_deinterleaver::deinterleave (atsc_mpeg_packet_rs_encoded &out, + const atsc_mpeg_packet_rs_encoded &in) +{ + assert (in.pli.regular_seg_p ()); + plinfo::sanity_check (in.pli); + + // reset commutator if required using INPUT pipeline info + if (in.pli.first_regular_seg_p ()) + sync (); + + // remap OUTPUT pipeline info to reflect 52 data segment end-to-end delay + + plinfo::delay (out.pli, in.pli, 52); + + // now do the actual deinterleaving + + for (unsigned int i = 0; i < sizeof (in.data); i++){ + out.data[i] = alignment_fifo.stuff (transform (in.data[i])); + } +} + diff --git a/gr-atsc/src/lib/atsci_data_interleaver.h b/gr-atsc/src/lib/atsci_data_interleaver.h new file mode 100644 index 000000000..26286b5b8 --- /dev/null +++ b/gr-atsc/src/lib/atsci_data_interleaver.h @@ -0,0 +1,64 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _ATSC_DATA_INTERLEAVER_H_ +#define _ATSC_DATA_INTERLEAVER_H_ + +#include <atsc_types.h> +#include <convolutional_interleaver.h> + +/*! + * \brief atsc convolutional data interleaver + */ +class atsci_data_interleaver : public convolutional_interleaver<unsigned char> { + public: + atsci_data_interleaver () : convolutional_interleaver<unsigned char>(true, 52, 4) {} + + void interleave (atsc_mpeg_packet_rs_encoded &out, + const atsc_mpeg_packet_rs_encoded &in); +}; + +/*! + * \brief atsc convolutional data deinterleaver + */ +class atsci_data_deinterleaver : public convolutional_interleaver<unsigned char> { + public: + atsci_data_deinterleaver () : + convolutional_interleaver<unsigned char>(false, 52, 4), alignment_fifo (156) {} + + void deinterleave (atsc_mpeg_packet_rs_encoded &out, + const atsc_mpeg_packet_rs_encoded &in); + +private: + /*! + * Note: The use of the alignment_fifo keeps the encoder and decoder + * aligned if both are synced to a field boundary. There may be other + * ways to implement this function. This is a best guess as to how + * this should behave, as we have no test vectors for either the + * interleaver or deinterleaver. + */ + interleaver_fifo<unsigned char> alignment_fifo; + + static void remap_pli (plinfo &out, const plinfo &in); +}; + +#endif /* _ATSC_DATA_INTERLEAVER_H_ */ diff --git a/gr-atsc/src/lib/atsci_diag_output.h b/gr-atsc/src/lib/atsci_diag_output.h new file mode 100644 index 000000000..163a6f0aa --- /dev/null +++ b/gr-atsc/src/lib/atsci_diag_output.h @@ -0,0 +1,29 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * single place to control all compile time diagnostic output options + */ + +#define _BT_DIAG_OUTPUT_ 0 +#define _FPLL_DIAG_OUTPUT_ 0 +#define _SSSR_DIAG_OUTPUT_ 0 diff --git a/gr-atsc/src/lib/atsci_equalizer.cc b/gr-atsc/src/lib/atsci_equalizer.cc new file mode 100644 index 000000000..29c248cf3 --- /dev/null +++ b/gr-atsc/src/lib/atsci_equalizer.cc @@ -0,0 +1,248 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include <atsci_equalizer.h> +#include <algorithm> +#include <iostream> +#include <atsc_types.h> + +using std::cerr; +using std::endl; +using std::min; + + +// total number of symbols (including field sync) / field +static const int SYMBOLS_PER_FIELD = + (ATSC_DSEGS_PER_FIELD + 1) * ATSC_DATA_SEGMENT_LENGTH; + + +atsci_equalizer::atsci_equalizer () +{ + d_locked_p = false; + d_offset_from_last_field_sync = 0; + d_current_field = 0; +} + +atsci_equalizer::~atsci_equalizer () +{ +} + +void +atsci_equalizer::reset () +{ + d_locked_p = false; + d_offset_from_last_field_sync = 0; + d_current_field = 0; +} + +/* + * Errrr.... Define to 1 if compiler handles tail recursion without pushing + * unnecessary stack frames, else define to 0 for lame compilers. + */ +#define WINNING_COMPILER 0 + + +/* + * divide and conquer... + * + * Note that this could be refactored to take advantage of the + * symbol_num that is contained in the input_tags. Then we wouldn't + * have to be counting here. + * + * Today's strategy: get it working. + */ + +void +atsci_equalizer::filter (const float *input_samples, + const atsc::syminfo *input_tags, + float *output_samples, + int nsamples) +{ + lame_compiler_kludge: + + if (!d_locked_p){ + + // look for a field sync + + int i; + for (i = 0; i < nsamples; i++){ + if (atsc::tag_is_start_field_sync (input_tags[i])) + break; + } + + // whether we found one or not, everything up to it should + // be run through the normal path + + if (i != 0) + filter_normal (input_samples, output_samples, i); + + if (i == nsamples) // no field sync found, still not locked. + return; + + // OK, we've just transitioned to the locked state. + + d_locked_p = true; + d_offset_from_last_field_sync = 0; + + // handle locked case recursively + + if (WINNING_COMPILER) + filter (&input_samples[i], &input_tags[i], + &output_samples[i], nsamples - i); + else { + input_samples += i; + input_tags += i; + output_samples += i; + nsamples -= i; + goto lame_compiler_kludge; + } + + return; + } + + // We're in the locked state. + // + // Figure out where we are with respect to a data segment boundary + // and do the right thing. Note that in the interested of performance, + // we don't scan all the tags looking for trouble. We only check + // them where we expect them to be non-NORMAL. Worst case, it'll take + // us a field to notice that something went wrong... + + if (d_offset_from_last_field_sync % SYMBOLS_PER_FIELD == 0){ // we should be looking + // at a field sync + if (atsc::tag_is_start_field_sync_1 (input_tags[0])) + d_current_field = 0; + + else if (atsc::tag_is_start_field_sync_2 (input_tags[0])) + d_current_field = 1; + + else { // we're lost... no field sync where we expected it + + cerr << "!!! atsci_equalizer: expected field sync, didn't find one\n"; + + d_locked_p = false; + d_offset_from_last_field_sync = 0; + + if (WINNING_COMPILER) + filter (input_samples, input_tags, output_samples, nsamples); + else + goto lame_compiler_kludge; + + return; + } + + // OK, everything's cool. We're looking at a field sync. + + int n = min (ATSC_DATA_SEGMENT_LENGTH, nsamples); + + filter_field_sync (input_samples, output_samples, n, 0, d_current_field); + + d_offset_from_last_field_sync = n; + nsamples -= n; + + if (nsamples > 0){ + if (WINNING_COMPILER) + filter (&input_samples[n], &input_tags[n], + &output_samples[n], nsamples); + else { + input_samples += n; + input_tags += n; + output_samples += n; + goto lame_compiler_kludge; + } + } + return; + } + + if (d_offset_from_last_field_sync < ATSC_DATA_SEGMENT_LENGTH){ // we're in the middle of a field sync + int n = min (ATSC_DATA_SEGMENT_LENGTH - d_offset_from_last_field_sync, nsamples); + + filter_field_sync (input_samples, output_samples, n, + d_offset_from_last_field_sync, d_current_field); + + d_offset_from_last_field_sync += n; + nsamples -= n; + + if (nsamples > 0){ + if (WINNING_COMPILER) + filter (&input_samples[n], &input_tags[n], + &output_samples[n], nsamples); + else { + input_samples += n; + input_tags += n; + output_samples += n; + goto lame_compiler_kludge; + } + } + return; + } + + // OK, we're not in a field sync. We're either in a data segment sync or in the clear... + + int seg_offset = d_offset_from_last_field_sync % ATSC_DATA_SEGMENT_LENGTH; + + assert (seg_offset >= 0); + + if (seg_offset < 4){ // somewhere in a data seg sync. + int n = min (4 - seg_offset, nsamples); + + filter_data_seg_sync (input_samples, output_samples, n, seg_offset); + + d_offset_from_last_field_sync += n; + nsamples -= n; + + if (nsamples > 0){ + if (WINNING_COMPILER) + filter (&input_samples[n], &input_tags[n], + &output_samples[n], nsamples); + else { + input_samples += n; + input_tags += n; + output_samples += n; + goto lame_compiler_kludge; + } + } + return; + } + + // otherwise... we're in the normal zone + + int n = min (ATSC_DATA_SEGMENT_LENGTH - seg_offset, nsamples); + + filter_normal (input_samples, output_samples, n); + + d_offset_from_last_field_sync += n; + nsamples -= n; + + if (nsamples <= 0) + return; + + if (WINNING_COMPILER) + filter (&input_samples[n], &input_tags[n], + &output_samples[n], nsamples); + else { + input_samples += n; + input_tags += n; + output_samples += n; + goto lame_compiler_kludge; + } +} diff --git a/gr-atsc/src/lib/atsci_equalizer.h b/gr-atsc/src/lib/atsci_equalizer.h new file mode 100644 index 000000000..53bc9b6a7 --- /dev/null +++ b/gr-atsc/src/lib/atsci_equalizer.h @@ -0,0 +1,163 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _ATSC_EQUALIZER_H_ +#define _ATSC_EQUALIZER_H_ + +#include <atsci_syminfo.h> + +/*! + * \brief abstract base class for ATSC equalizer + */ +class atsci_equalizer { + +private: + + /* + * have we seen a field sync since the last reset or problem? + */ + bool d_locked_p; + + /* + * sample offset from the beginning of the last field sync we saw + * to the beginning of our current input stream. When we're locked + * this will be in [0, 313*832] i.e., [0, 260416] + */ + int d_offset_from_last_field_sync; + + int d_current_field; // [0,1] + + +public: + + // CREATORS + atsci_equalizer (); + virtual ~atsci_equalizer (); + + // MANIPULATORS + + /*! + * \brief reset state (e.g., on channel change) + * + * Note, subclasses must invoke the superclass's method too! + */ + virtual void reset (); + + /*! + * \brief produce \p nsamples of output from given inputs and tags + * + * This is the main entry point. It examines the input_tags + * and local state and invokes the appropriate virtual function + * to handle each sub-segment of the input data. + * + * \p input_samples must have (nsamples + ntaps() - 1) valid entries. + * input_samples[0] .. input_samples[nsamples - 1 + ntaps() - 1] are + * referenced to compute the output values. + * + * \p input_tags must have nsamples valid entries. + * input_tags[0] .. input_tags[nsamples - 1] are referenced to + * compute the output values. + */ + virtual void filter (const float *input_samples, + const atsc::syminfo *input_tags, + float *output_samples, + int nsamples); + + // ACCESSORS + + /*! + * \brief how much history the input data stream requires. + * + * This must return a value >= 1. Think of this as the number + * of samples you need to look at to compute a single output sample. + */ + virtual int ntaps () const = 0; + + /*! + * \brief how many taps are "in the future". + * + * This allows us to handle what the ATSC folks call "pre-ghosts". + * What it really does is allow the caller to jack with the offset + * between the tags and the data so that everything magically works out. + * + * npretaps () must return a value between 0 and ntaps() - 1. + * + * If npretaps () returns 0, this means that the equalizer will only handle + * multipath "in the past." I suspect that a good value would be something + * like 15% - 20% of ntaps (). + */ + virtual int npretaps () const = 0; + + +protected: + + /*! + * Input range is known NOT TO CONTAIN data segment syncs + * or field syncs. This should be the fast path. In the + * non decicion directed case, this just runs the input + * through the filter without adapting it. + * + * \p input_samples has (nsamples + ntaps() - 1) valid entries. + * input_samples[0] .. input_samples[nsamples - 1 + ntaps() - 1] may be + * referenced to compute the output values. + */ + virtual void filter_normal (const float *input_samples, + float *output_samples, + int nsamples) = 0; + + /*! + * Input range is known to consist of only a data segment sync or a + * portion of a data segment sync. \p nsamples will be in [1,4]. + * \p offset will be in [0,3]. \p offset is the offset of the input + * from the beginning of the data segment sync pattern. + * + * \p input_samples has (nsamples + ntaps() - 1) valid entries. + * input_samples[0] .. input_samples[nsamples - 1 + ntaps() - 1] may be + * referenced to compute the output values. + */ + virtual void filter_data_seg_sync (const float *input_samples, + float *output_samples, + int nsamples, + int offset) = 0; + + /*! + * Input range is known to consist of only a field sync segment or a + * portion of a field sync segment. \p nsamples will be in [1,832]. + * \p offset will be in [0,831]. \p offset is the offset of the input + * from the beginning of the data segment sync pattern. We consider the + * 4 symbols of the immediately preceding data segment sync to be the + * first symbols of the field sync segment. \p which_field is in [0,1] + * and specifies which field (duh). + * + * \p input_samples has (nsamples + ntaps() - 1) valid entries. + * input_samples[0] .. input_samples[nsamples - 1 + ntaps() - 1] may be + * referenced to compute the output values. + */ + virtual void filter_field_sync (const float *input_samples, + float *output_samples, + int nsamples, + int offset, + int which_field) = 0; +}; + + +#endif /* _ATSC_EQUALIZER_H_ */ diff --git a/gr-atsc/src/lib/atsci_equalizer_lms.cc b/gr-atsc/src/lib/atsci_equalizer_lms.cc new file mode 100644 index 000000000..2fc084b36 --- /dev/null +++ b/gr-atsc/src/lib/atsci_equalizer_lms.cc @@ -0,0 +1,306 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include <atsci_equalizer_lms.h> +#include <assert.h> +#include <algorithm> +#include <atsci_pnXXX.h> + +#include <stdio.h> + +using std::min; +using std::max; + +static const int NTAPS = 256; +static const int NPRETAPS = (int) (NTAPS * 0.8); // probably should be either .2 or .8 + + +// the length of the field sync pattern that we know unequivocally +static const int KNOWN_FIELD_SYNC_LENGTH = 4 + 511 + 3 * 63; + +static const float *get_data_seg_sync_training_sequence (int offset); +static int get_field_sync_training_sequence_length (int offset); +static const float *get_field_sync_training_sequence (int which_field, int offset); + + +atsci_equalizer_lms::atsci_equalizer_lms () : d_taps (NTAPS) +{ + for (int i = 0; i < NTAPS; i++) { + d_taps[i] = 0.0; + } + trainingfile=fopen("taps.txt","w"); +} + +atsci_equalizer_lms::~atsci_equalizer_lms () +{ +} + +void +atsci_equalizer_lms::reset () +{ + atsci_equalizer::reset (); // invoke superclass + + for (int i = 0; i < NTAPS; i++) { + d_taps[i] = 0.0; + } +} + +int +atsci_equalizer_lms::ntaps () const +{ + return NTAPS; +} + +int +atsci_equalizer_lms::npretaps () const +{ + return NPRETAPS; +} + +/*! + * Input range is known NOT TO CONTAIN data segment syncs + * or field syncs. This should be the fast path. In the + * non decicion directed case, this just runs the input + * through the filter without adapting it. + * + * \p input_samples has (nsamples + ntaps() - 1) valid entries. + * input_samples[0] .. input_samples[nsamples - 1 + ntaps() - 1] may be + * referenced to compute the output values. + */ +void +atsci_equalizer_lms::filter_normal (const float *input_samples, + float *output_samples, + int nsamples) +{ + // handle data + filterN (input_samples, output_samples, nsamples); +} + + +/*! + * Input range is known to consist of only a data segment sync or a + * portion of a data segment sync. \p nsamples will be in [1,4]. + * \p offset will be in [0,3]. \p offset is the offset of the input + * from the beginning of the data segment sync pattern. + * + * \p input_samples has (nsamples + ntaps() - 1) valid entries. + * input_samples[0] .. input_samples[nsamples - 1 + ntaps() - 1] may be + * referenced to compute the output values. + */ +void +atsci_equalizer_lms::filter_data_seg_sync (const float *input_samples, + float *output_samples, + int nsamples, + int offset) +{ + // handle data + // adaptN (input_samples, get_data_seg_sync_training_sequence (offset), + // output_samples, nsamples); + filterN (input_samples, output_samples, nsamples); + + // cerr << "Seg Sync: offset " << offset << "\tnsamples\t" << nsamples << "\t pre, 5 -5 -5 5\t" << + // output_samples[0] << "\t" << output_samples[1] << "\t" << output_samples[2] << "\t" << output_samples[3] << endl; + +} + + +/*! + * Input range is known to consist of only a field sync segment or a + * portion of a field sync segment. \p nsamples will be in [1,832]. + * \p offset will be in [0,831]. \p offset is the offset of the input + * from the beginning of the data segment sync pattern. We consider the + * 4 symbols of the immediately preceding data segment sync to be the + * first symbols of the field sync segment. \p which_field is in [0,1] + * and specifies which field (duh). + * + * \p input_samples has (nsamples + ntaps() - 1) valid entries. + * input_samples[0] .. input_samples[nsamples - 1 + ntaps() - 1] may be + * referenced to compute the output values. + */ +void +atsci_equalizer_lms::filter_field_sync (const float *input_samples, + float *output_samples, + int nsamples, + int offset, + int which_field) +{ + // Only the first 4 + 511 + 3 * 63 symbols are completely defined. + // Those after that the symbols are bilevel, so we could use decision feedback and use + // that to train, but for now, don't train on them. + + int n = min (nsamples, get_field_sync_training_sequence_length (offset)); + + // handle known training sequence + adaptN (input_samples, get_field_sync_training_sequence (which_field, offset), + output_samples, n); + + // just filter any unknown portion + if (nsamples > n) + filterN (&input_samples[n], &output_samples[n], nsamples - n); + + if (offset == 0 && nsamples > 0){ + for (int i = 0; i < NTAPS; i++) + fprintf(trainingfile,"%f ",d_taps[i]); + + fprintf (trainingfile,"\n"); + } + +} + +// ---------------------------------------------------------------- + +// +// filter a single output +// +float +atsci_equalizer_lms::filter1 (const float input[]) +{ + static const int N_UNROLL = 4; + + float acc0 = 0; + float acc1 = 0; + float acc2 = 0; + float acc3 = 0; + + + unsigned i = 0; + unsigned n = (NTAPS / N_UNROLL) * N_UNROLL; + + for (i = 0; i < n; i += N_UNROLL){ + acc0 += d_taps[i + 0] * input[i + 0]; + acc1 += d_taps[i + 1] * input[i + 1]; + acc2 += d_taps[i + 2] * input[i + 2]; + acc3 += d_taps[i + 3] * input[i + 3]; + } + + for (; i < (unsigned) NTAPS; i++) + acc0 += d_taps[i] * input[i]; + + return (acc0 + acc1 + acc2 + acc3); +} + +// +// filter and adapt a single output +// +float +atsci_equalizer_lms::adapt1 (const float input[], float ideal_output) +{ + static const double BETA = 0.00005; // FIXME figure out what this ought to be + // FIXME add gear-shifting + + double y = filter1 (input); + double e = y - ideal_output; + + // update taps... + for (int i = 0; i < NTAPS; i++){ + d_taps[i] = d_taps[i] - BETA * e * (double)(input[i]); + } + + return y; +} + +void +atsci_equalizer_lms::filterN (const float *input_samples, + float *output_samples, + int nsamples) +{ + for (int i = 0; i < nsamples; i++) + output_samples[i] = filter1 (&input_samples[i]); +} + + +void +atsci_equalizer_lms::adaptN (const float *input_samples, + const float *training_pattern, + float *output_samples, + int nsamples) +{ + for (int i = 0; i < nsamples; i++) + output_samples[i] = adapt1 (&input_samples[i], training_pattern[i]); +} + +// ---------------------------------------------------------------- + +static float +bin_map (int bit) +{ + return bit ? +5 : -5; +} + +static void +init_field_sync_common (float *p, int mask) + +{ + int i = 0; + + p[i++] = bin_map (1); // data segment sync pulse + p[i++] = bin_map (0); + p[i++] = bin_map (0); + p[i++] = bin_map (1); + + for (int j = 0; j < 511; j++) // PN511 + p[i++] = bin_map (atsc_pn511[j]); + + for (int j = 0; j < 63; j++) // PN63 + p[i++] = bin_map (atsc_pn63[j]); + + for (int j = 0; j < 63; j++) // PN63, toggled on field 2 + p[i++] = bin_map (atsc_pn63[j] ^ mask); + + for (int j = 0; j < 63; j++) // PN63 + p[i++] = bin_map (atsc_pn63[j]); + + assert (i == KNOWN_FIELD_SYNC_LENGTH); +} + + +static const float * +get_data_seg_sync_training_sequence (int offset) +{ + static const float training_data[4] = { +5, -5, -5, +5 }; + return &training_data[offset]; +} + +static int +get_field_sync_training_sequence_length (int offset) +{ + return max (0, KNOWN_FIELD_SYNC_LENGTH - offset); +} + +static const float * +get_field_sync_training_sequence (int which_field, int offset) +{ + static float *field_1 = 0; + static float *field_2 = 0; + + if (field_1 == 0){ + field_1 = new float[KNOWN_FIELD_SYNC_LENGTH]; + field_2 = new float[KNOWN_FIELD_SYNC_LENGTH]; + init_field_sync_common (field_1, 0); + init_field_sync_common (field_2, 1); + } + + if (which_field == 0) + return &field_1[offset]; + else + return &field_2[offset]; +} diff --git a/gr-atsc/src/lib/atsci_equalizer_lms.h b/gr-atsc/src/lib/atsci_equalizer_lms.h new file mode 100644 index 000000000..8303647c3 --- /dev/null +++ b/gr-atsc/src/lib/atsci_equalizer_lms.h @@ -0,0 +1,75 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _ATSC_EQUALIZER_LMS_H_ +#define _ATSC_EQUALIZER_LMS_H_ + +#include <atsci_equalizer.h> +#include <vector> +#include <stdio.h> + +class atsci_equalizer_lms : public atsci_equalizer +{ +public: + atsci_equalizer_lms (); + virtual ~atsci_equalizer_lms (); + + virtual void reset (); + virtual int ntaps () const; + virtual int npretaps () const; + +protected: + FILE *trainingfile; + virtual void filter_normal (const float *input_samples, + float *output_samples, + int nsamples); + + virtual void filter_data_seg_sync (const float *input_samples, + float *output_samples, + int nsamples, + int offset); + + virtual void filter_field_sync (const float *input_samples, + float *output_samples, + int nsamples, + int offset, + int which_field); + +private: + std::vector<double> d_taps; + + void filterN (const float *input_samples, + float *output_samples, + int nsamples); + + void adaptN (const float *input_samples, + const float *training_pattern, + float *output_samples, + int nsamples); + + float filter1 (const float input[]); + float adapt1 (const float input[], float ideal_output); + +}; + + +#endif /* _ATSC_EQUALIZER_LMS_H_ */ diff --git a/gr-atsc/src/lib/atsci_equalizer_lms2.cc b/gr-atsc/src/lib/atsci_equalizer_lms2.cc new file mode 100644 index 000000000..d461d6086 --- /dev/null +++ b/gr-atsc/src/lib/atsci_equalizer_lms2.cc @@ -0,0 +1,373 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include <atsci_equalizer_lms2.h> +#include <assert.h> +#include <algorithm> +#include <atsci_pnXXX.h> +#include <cmath> +#include <stdlib.h> +#include <gr_math.h> +#include <stdio.h> + +using std::min; +using std::max; + +static const int NFFTAPS = 64; +static const int NFBTAPS = 192; + +// the length of the field sync pattern that we know unequivocally +static const int KNOWN_FIELD_SYNC_LENGTH = 4 + 511 + 3 * 63; + +static const float *get_data_seg_sync_training_sequence (int offset); +static int get_field_sync_training_sequence_length (int offset); +static const float *get_field_sync_training_sequence (int which_field, int offset); + +static inline int +wrap (int d) +{ + assert (d >= 0 && d <= (2 * NFBTAPS)); + + if(d >= NFBTAPS) + return d - NFBTAPS; + return d; +} + +static inline float +slice (float d) +{ + if (gr_isnan (d)) + return 0.0; + + if (d >= 0.0){ + if (d >= 4.0){ + if (d >= 6.0) + return 7.0; + else + return 5.0; + } + if (d >= 2.0) + return 3.0; + return 1.0; + } + else + return -slice (-d); +} + +atsci_equalizer_lms2::atsci_equalizer_lms2 () + : d_taps_ff (NFFTAPS), d_taps_fb (NFBTAPS), d_old_output (NFBTAPS) +{ + for (int i = 0; i < NFFTAPS; i++) { + d_taps_ff[i] = 0.0; + } + for (int i = 0; i < NFBTAPS; i++) { + d_taps_fb[i] = 0.0; + d_old_output[i] = 0.0; + } + d_output_ptr = 0; + trainingfile=fopen("taps.txt","w"); +} + +atsci_equalizer_lms2::~atsci_equalizer_lms2 () +{ +} + +void +atsci_equalizer_lms2::reset () +{ + atsci_equalizer::reset (); // invoke superclass + for (int i = 0; i < NFFTAPS; i++) { + d_taps_ff[i] = 0.0; + } + for (int i = 0; i < NFBTAPS; i++) { + d_taps_fb[i] = 0.0; + d_old_output[i] = 0.0; + } + d_output_ptr = 0; +} + + +int +atsci_equalizer_lms2::ntaps () const +{ + return NFFTAPS + NFBTAPS; +} + +int +atsci_equalizer_lms2::npretaps () const +{ + return NFFTAPS; +} + +/*! + * Input range is known NOT TO CONTAIN data segment syncs + * or field syncs. This should be the fast path. In the + * non decicion directed case, this just runs the input + * through the filter without adapting it. + * + * \p input_samples has (nsamples + ntaps() - 1) valid entries. + * input_samples[0] .. input_samples[nsamples - 1 + ntaps() - 1] may be + * referenced to compute the output values. + */ +void +atsci_equalizer_lms2::filter_normal (const float *input_samples, + float *output_samples, + int nsamples) +{ + // handle data + filterN (input_samples, output_samples, nsamples); +} + + +/*! + * Input range is known to consist of only a data segment sync or a + * portion of a data segment sync. \p nsamples will be in [1,4]. + * \p offset will be in [0,3]. \p offset is the offset of the input + * from the beginning of the data segment sync pattern. + * + * \p input_samples has (nsamples + ntaps() - 1) valid entries. + * input_samples[0] .. input_samples[nsamples - 1 + ntaps() - 1] may be + * referenced to compute the output values. + */ +void +atsci_equalizer_lms2::filter_data_seg_sync (const float *input_samples, + float *output_samples, + int nsamples, + int offset) +{ + // handle data + // adaptN (input_samples, get_data_seg_sync_training_sequence (offset), + // output_samples, nsamples); + filterN (input_samples, output_samples, nsamples); + + // cerr << "Seg Sync: offset " << offset << "\tnsamples\t" << nsamples << "\t pre, 5 -5 -5 5\t" << + // output_samples[0] << "\t" << output_samples[1] << "\t" << output_samples[2] << "\t" << output_samples[3] << endl; + +} + + +/*! + * Input range is known to consist of only a field sync segment or a + * portion of a field sync segment. \p nsamples will be in [1,832]. + * \p offset will be in [0,831]. \p offset is the offset of the input + * from the beginning of the data segment sync pattern. We consider the + * 4 symbols of the immediately preceding data segment sync to be the + * first symbols of the field sync segment. \p which_field is in [0,1] + * and specifies which field (duh). + * + * \p input_samples has (nsamples + ntaps() - 1) valid entries. + * input_samples[0] .. input_samples[nsamples - 1 + ntaps() - 1] may be + * referenced to compute the output values. + */ +void +atsci_equalizer_lms2::filter_field_sync (const float *input_samples, + float *output_samples, + int nsamples, + int offset, + int which_field) +{ + // Only the first 4 + 511 + 3 * 63 symbols are completely defined. + // Those after that the symbols are bilevel, so we could use decision feedback and use + // that to train, but for now, don't train on them. + + int n = min (nsamples, get_field_sync_training_sequence_length (offset)); + + // handle known training sequence + adaptN (input_samples, get_field_sync_training_sequence (which_field, offset), + output_samples, n); + + // just filter any unknown portion + if (nsamples > n) + filterN (&input_samples[n], &output_samples[n], nsamples - n); + + if (offset == 0 && nsamples > 0){ + for (int i = 0; i < NFFTAPS; i++) + fprintf(trainingfile,"%f ",d_taps_ff[i]); + for (int i = 0; i < NFBTAPS; i++) + fprintf(trainingfile,"%f ",d_taps_fb[i]); + fprintf (trainingfile,"\n"); + } + +} + +// ---------------------------------------------------------------- + +// +// filter a single output +// +float +atsci_equalizer_lms2::filter1 (const float input[]) +{ + static const int N_UNROLL = 4; + + float acc0 = 0; + float acc1 = 0; + float acc2 = 0; + float acc3 = 0; + float acc = 0; + + + unsigned i = 0; + unsigned n = (NFFTAPS / N_UNROLL) * N_UNROLL; + + for (i = 0; i < n; i += N_UNROLL){ + acc0 += d_taps_ff[i + 0] * input[i + 0]; + acc1 += d_taps_ff[i + 1] * input[i + 1]; + acc2 += d_taps_ff[i + 2] * input[i + 2]; + acc3 += d_taps_ff[i + 3] * input[i + 3]; + } + + for (; i < (unsigned) NFFTAPS; i++) + acc0 += d_taps_ff[i] * input[i]; + + acc = (acc0 + acc1 + acc2 + acc3); + + d_output_ptr = wrap (d_output_ptr + 1); + + for (int i = 0; i < NFBTAPS; i++) { + acc -= d_taps_fb[i] * d_old_output[wrap(i + d_output_ptr)]; + } + + if (gr_isnan (acc)){ + abort (); + } + + d_old_output[d_output_ptr] = slice (acc); + return acc; +} + +// +// filter and adapt a single output +// +float kludge () +{ + return 0.0; +} + +float +atsci_equalizer_lms2::adapt1 (const float input[], float ideal_output) +{ + static const double BETA = 0.00005; // FIXME figure out what this ought to be + // FIXME add gear-shifting + + double y = filter1 (input); + double e = y - ideal_output; + + // update taps... + for (int i = 0; i < NFFTAPS; i++){ + d_taps_ff[i] = d_taps_ff[i] - BETA * e * (double)(input[i]); + } + + for (int i = 0; i < NFBTAPS; i++){ + // d_taps_fb[i] = d_taps_fb[i] - BETA * e * (double)d_old_output[wrap(i+d_output_ptr)]; + d_taps_fb[i] = d_taps_fb[i] - kludge() * e * (double)d_old_output[wrap(i+d_output_ptr)]; + } + + return y; +} + +void +atsci_equalizer_lms2::filterN (const float *input_samples, + float *output_samples, + int nsamples) +{ + for (int i = 0; i < nsamples; i++) + output_samples[i] = filter1 (&input_samples[i]); +} + + +void +atsci_equalizer_lms2::adaptN (const float *input_samples, + const float *training_pattern, + float *output_samples, + int nsamples) +{ + for (int i = 0; i < nsamples; i++) + output_samples[i] = adapt1 (&input_samples[i], training_pattern[i]); +} + +// ---------------------------------------------------------------- + +static float +bin_map (int bit) +{ + return bit ? +5 : -5; +} + +static void +init_field_sync_common (float *p, int mask) + +{ + int i = 0; + + p[i++] = bin_map (1); // data segment sync pulse + p[i++] = bin_map (0); + p[i++] = bin_map (0); + p[i++] = bin_map (1); + + for (int j = 0; j < 511; j++) // PN511 + p[i++] = bin_map (atsc_pn511[j]); + + for (int j = 0; j < 63; j++) // PN63 + p[i++] = bin_map (atsc_pn63[j]); + + for (int j = 0; j < 63; j++) // PN63, toggled on field 2 + p[i++] = bin_map (atsc_pn63[j] ^ mask); + + for (int j = 0; j < 63; j++) // PN63 + p[i++] = bin_map (atsc_pn63[j]); + + assert (i == KNOWN_FIELD_SYNC_LENGTH); +} + + +static const float * +get_data_seg_sync_training_sequence (int offset) +{ + static const float training_data[4] = { +5, -5, -5, +5 }; + return &training_data[offset]; +} + +static int +get_field_sync_training_sequence_length (int offset) +{ + return max (0, KNOWN_FIELD_SYNC_LENGTH - offset); +} + +static const float * +get_field_sync_training_sequence (int which_field, int offset) +{ + static float *field_1 = 0; + static float *field_2 = 0; + + if (field_1 == 0){ + field_1 = new float[KNOWN_FIELD_SYNC_LENGTH]; + field_2 = new float[KNOWN_FIELD_SYNC_LENGTH]; + init_field_sync_common (field_1, 0); + init_field_sync_common (field_2, 1); + } + + if (which_field == 0) + return &field_1[offset]; + else + return &field_2[offset]; +} diff --git a/gr-atsc/src/lib/atsci_equalizer_lms2.h b/gr-atsc/src/lib/atsci_equalizer_lms2.h new file mode 100644 index 000000000..60ac8944d --- /dev/null +++ b/gr-atsc/src/lib/atsci_equalizer_lms2.h @@ -0,0 +1,79 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _ATSC_EQUALIZER_LMS2_H_ +#define _ATSC_EQUALIZER_LMS2_H_ + +#include <atsci_equalizer.h> +#include <vector> +#include <stdio.h> + +class atsci_equalizer_lms2 : public atsci_equalizer +{ +public: + atsci_equalizer_lms2 (); + virtual ~atsci_equalizer_lms2 (); + + virtual void reset (); + virtual int ntaps () const; + virtual int npretaps () const; + +protected: + FILE *trainingfile; + virtual void filter_normal (const float *input_samples, + float *output_samples, + int nsamples); + + virtual void filter_data_seg_sync (const float *input_samples, + float *output_samples, + int nsamples, + int offset); + + virtual void filter_field_sync (const float *input_samples, + float *output_samples, + int nsamples, + int offset, + int which_field); + +private: + std::vector<double> d_taps_ff; + std::vector<double> d_taps_fb; + std::vector<float> d_old_output; + + int d_output_ptr; + + void filterN (const float *input_samples, + float *output_samples, + int nsamples); + + void adaptN (const float *input_samples, + const float *training_pattern, + float *output_samples, + int nsamples); + + float filter1 (const float input[]); + float adapt1 (const float input[], float ideal_output); + +}; + + +#endif /* _ATSC_EQUALIZER_LMS2_H_ */ diff --git a/gr-atsc/src/lib/atsci_equalizer_nop.cc b/gr-atsc/src/lib/atsci_equalizer_nop.cc new file mode 100644 index 000000000..681a6b24b --- /dev/null +++ b/gr-atsc/src/lib/atsci_equalizer_nop.cc @@ -0,0 +1,133 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include <atsci_equalizer_nop.h> +#include <atsci_sync_tag.h> +#include <assert.h> + +atsci_equalizer_nop::atsci_equalizer_nop () +{ +} + +atsci_equalizer_nop::~atsci_equalizer_nop () +{ +} + +void +atsci_equalizer_nop::reset () +{ + atsci_equalizer::reset (); // invoke superclass +} + +int +atsci_equalizer_nop::ntaps () const +{ + return 1; +} + +int +atsci_equalizer_nop::npretaps () const +{ + return 0; +} + +/*! + * Input range is known NOT TO CONTAIN data segment syncs + * or field syncs. This should be the fast path. In the + * non decicion directed case, this just runs the input + * through the filter without adapting it. + * + * \p input_samples has (nsamples + ntaps() - 1) valid entries. + * input_samples[0] .. input_samples[nsamples - 1 + ntaps() - 1] may be + * referenced to compute the output values. + */ +void +atsci_equalizer_nop::filter_normal (const float *input_samples, + float *output_samples, + int nsamples) +{ + for (int i = 0; i < nsamples; i++){ + output_samples[i] = scale (input_samples[i]); + } +} + + +/*! + * Input range is known to consist of only a data segment sync or a + * portion of a data segment sync. \p nsamples will be in [1,4]. + * \p offset will be in [0,3]. \p offset is the offset of the input + * from the beginning of the data segment sync pattern. + * + * \p input_samples has (nsamples + ntaps() - 1) valid entries. + * input_samples[0] .. input_samples[nsamples - 1 + ntaps() - 1] may be + * referenced to compute the output values. + */ +void +atsci_equalizer_nop::filter_data_seg_sync (const float *input_samples, + float *output_samples, + int nsamples, + int offset) +{ + for (int i = 0; i < nsamples; i++){ + output_samples[i] = scale_and_train (input_samples[i]); + } +} + + +/*! + * Input range is known to consist of only a field sync segment or a + * portion of a field sync segment. \p nsamples will be in [1,832]. + * \p offset will be in [0,831]. \p offset is the offset of the input + * from the beginning of the data segment sync pattern. We consider the + * 4 symbols of the immediately preceding data segment sync to be the + * first symbols of the field sync segment. \p which_field is in [0,1] + * and specifies which field (duh). + * + * \p input_samples has (nsamples + ntaps() - 1) valid entries. + * input_samples[0] .. input_samples[nsamples - 1 + ntaps() - 1] may be + * referenced to compute the output values. + */ +void +atsci_equalizer_nop::filter_field_sync (const float *input_samples, + float *output_samples, + int nsamples, + int offset, + int which_field) +{ + int i = 0; + + if (offset == 0 && nsamples > 0){ + output_samples[0] = scale_and_train (input_samples[0]); + i++; + } + + for (; i < nsamples; i++){ + output_samples[i] = scale_and_train (input_samples[i]); + } +} + + +float +atsci_equalizer_nop::scale_and_train (float input) +{ + return input; +} diff --git a/gr-atsc/src/lib/atsci_equalizer_nop.h b/gr-atsc/src/lib/atsci_equalizer_nop.h new file mode 100644 index 000000000..b5f5b0cc4 --- /dev/null +++ b/gr-atsc/src/lib/atsci_equalizer_nop.h @@ -0,0 +1,62 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _ATSC_EQUALIZER_NOP_H_ +#define _ATSC_EQUALIZER_NOP_H_ + +#include <atsci_equalizer.h> + +class atsci_equalizer_nop : public atsci_equalizer +{ +private: + float scale (float input) { return input; } + + float scale_and_train (float input); + + +public: + atsci_equalizer_nop (); + virtual ~atsci_equalizer_nop (); + + virtual void reset (); + virtual int ntaps () const; + virtual int npretaps () const; + +protected: + virtual void filter_normal (const float *input_samples, + float *output_samples, + int nsamples); + + virtual void filter_data_seg_sync (const float *input_samples, + float *output_samples, + int nsamples, + int offset); + + virtual void filter_field_sync (const float *input_samples, + float *output_samples, + int nsamples, + int offset, + int which_field); +}; + + +#endif /* _ATSC_EQUALIZER_NOP_H_ */ diff --git a/gr-atsc/src/lib/atsci_exp2_lp.cc b/gr-atsc/src/lib/atsci_exp2_lp.cc new file mode 100644 index 000000000..9c7216db8 --- /dev/null +++ b/gr-atsc/src/lib/atsci_exp2_lp.cc @@ -0,0 +1,84 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include <atsc_consts.h> +#include <atsci_exp2_lp.h> +#include <stdexcept> +#include <cmath> +#include <iostream> + +using std::vector; +using std::cerr; +using std::endl; + +/* + * FILTER SPECIFICATION FILE + * FILTER TYPE:LOW PASS 1H + * PASSBAND RIPPLE IN -dB -.0100 + * STOPBAND RIPPLE IN -dB -66.0000 + * PASSBAND CUTOFF FREQUENCY 5.69000 HERTZ + * STOPBAND CUTOFF FREQUENCY 6.12000 HERTZ + * SAMPLING FREQUENCY 21.5200 HERTZ + */ +static const float atsci_exp2_lp2x[] = { +#include "atsci_exp2_lp2x.dat" +}; + +/* + * FILTER SPECIFICATION FILE + * FILTER TYPE:LOW PASS 1H + * PASSBAND RIPPLE IN -dB -.0100 + * STOPBAND RIPPLE IN -dB -66.0000 + * PASSBAND CUTOFF FREQUENCY 5.69000 HERTZ + * STOPBAND CUTOFF FREQUENCY 6.12000 HERTZ + * SAMPLING FREQUENCY 20.0000 HERTZ + */ +static const float atsci_exp2_lp20[] = { +#include "atsci_exp2_lp20.dat" +}; + + +#define NELEM(x) (sizeof (x) / sizeof ((x)[0])) + +// is A within 5% of TARGET? + +static bool +close_enough_p (double a, double target) +{ + double delta = fabs (target * 0.05); // 5 percent + + return fabs (target - a) <= delta; +} + +vector<float> +atsci_exp2_lp::taps (double sampling_freq) +{ + if (close_enough_p (sampling_freq, 20e6)){ + return vector<float>(&atsci_exp2_lp20[0], &atsci_exp2_lp20[NELEM(atsci_exp2_lp20)]); + } + if (close_enough_p (sampling_freq, 2 * ATSC_SYMBOL_RATE)){ + return vector<float>(&atsci_exp2_lp2x[0], &atsci_exp2_lp2x[NELEM(atsci_exp2_lp2x)]); + } + else + throw std::out_of_range ( + "atsci_exp2_lp: no pre-designed filter close enough"); +} diff --git a/gr-atsc/src/lib/atsci_exp2_lp.h b/gr-atsc/src/lib/atsci_exp2_lp.h new file mode 100644 index 000000000..5370e40ba --- /dev/null +++ b/gr-atsc/src/lib/atsci_exp2_lp.h @@ -0,0 +1,34 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _ATSC_EXP2_LP_H_ +#define _ATSC_EXP2_LP_H_ + +#include <gr_fir_builder.h> + +class atsci_exp2_lp : public gr_fir_builder +{ +public: + virtual std::vector<float> taps (double sampling_freq); +}; + +#endif /* _ATSC_EXP2_LP_H_ */ diff --git a/gr-atsc/src/lib/atsci_exp2_lp20.dat b/gr-atsc/src/lib/atsci_exp2_lp20.dat new file mode 100644 index 000000000..b810fac70 --- /dev/null +++ b/gr-atsc/src/lib/atsci_exp2_lp20.dat @@ -0,0 +1,178 @@ +/* + * FILTER SPECIFICATION FILE + * FILTER TYPE:LOW PASS 1H + * PASSBAND RIPPLE IN -dB -.0100 + * STOPBAND RIPPLE IN -dB -66.0000 + * PASSBAND CUTOFF FREQUENCY 5.69000 HERTZ + * STOPBAND CUTOFF FREQUENCY 6.12000 HERTZ + * SAMPLING FREQUENCY 20.0000 HERTZ + */ + -.3137849271297455e-03, + -.6755953654646874e-04, + .2326252870261669e-03, + -.1614624634385109e-03, + -.1158984377980232e-03, + .2114051021635532e-03, + .6828224286437035e-04, + -.3522797487676144e-03, + .1759170554578304e-03, + .2849949523806572e-03, + -.3568925894796848e-03, + -.1521380618214607e-03, + .5445396527647972e-03, + -.1707794144749641e-03, + -.5257474258542061e-03, + .5062967538833618e-03, + .3262492828071117e-03, + -.8037807419896126e-03, + .1136297360062599e-03, + .8607362397015095e-03, + -.6433278322219849e-03, + -.6174184381961823e-03, + .1120670232921839e-02, + .3442214801907539e-04, + -.1305819023400545e-02, + .7387576624751091e-03, + .1056550536304712e-02, + -.1477979123592377e-02, + -.3192713484168053e-03, + .1870564185082912e-02, + -.7502869702875614e-03, + -.1675266306847334e-02, + .1847642473876476e-02, + .7931739091873169e-03, + -.2555002458393574e-02, + .6227688863873482e-03, + .2505954820662737e-02, + -.2186967991292477e-02, + -.1515555195510387e-02, + .3349546808749437e-02, + -.2860687673091888e-03, + -.3578922711312771e-02, + .2438103780150414e-02, + .2555412705987692e-02, + -.4232846200466156e-02, + -.3483905456960201e-03, + .4926202818751335e-02, + -.2523601986467838e-02, + -.3997647203505039e-02, + .5173782818019390e-02, + .1395780127495527e-02, + -.6588382180780172e-02, + .2339247148483992e-02, + .5959283560514450e-02, + -.6131949834525585e-02, + -.3020572476089001e-02, + .8632841985672712e-02, + -.1736589241772890e-02, + -.8627892937511206e-02, + .7060498464852572e-02, + .5489445291459560e-02, + -.1119629153981805e-01, + .4754690453410149e-03, + .1235919492319226e-01, + -.7909852080047131e-02, + -.9316097479313612e-02, + .1459939032793045e-01, + .1910720951855183e-02, + -.1796151325106621e-01, + .8631225209683180e-02, + .1572139468044043e-01, + -.1972115319222212e-01, + -.6601144559681416e-02, + .2775513892993331e-01, + -.9181375615298748e-02, + -.2863558568060398e-01, + .2976502152159810e-01, + .1806837785989046e-01, + -.5192282795906067e-01, + .9526194538921118e-02, + .7172224065288901e-01, + -.6965141417458654e-01, + -.8541030902415514e-01, + .3052920936606824e+00, + .5900069065392017e+00, + .3052920936606824e+00, + -.8541030902415514e-01, + -.6965141417458654e-01, + .7172224065288901e-01, + .9526194538921118e-02, + -.5192282795906067e-01, + .1806837785989046e-01, + .2976502152159810e-01, + -.2863558568060398e-01, + -.9181375615298748e-02, + .2775513892993331e-01, + -.6601144559681416e-02, + -.1972115319222212e-01, + .1572139468044043e-01, + .8631225209683180e-02, + -.1796151325106621e-01, + .1910720951855183e-02, + .1459939032793045e-01, + -.9316097479313612e-02, + -.7909852080047131e-02, + .1235919492319226e-01, + .4754690453410149e-03, + -.1119629153981805e-01, + .5489445291459560e-02, + .7060498464852572e-02, + -.8627892937511206e-02, + -.1736589241772890e-02, + .8632841985672712e-02, + -.3020572476089001e-02, + -.6131949834525585e-02, + .5959283560514450e-02, + .2339247148483992e-02, + -.6588382180780172e-02, + .1395780127495527e-02, + .5173782818019390e-02, + -.3997647203505039e-02, + -.2523601986467838e-02, + .4926202818751335e-02, + -.3483905456960201e-03, + -.4232846200466156e-02, + .2555412705987692e-02, + .2438103780150414e-02, + -.3578922711312771e-02, + -.2860687673091888e-03, + .3349546808749437e-02, + -.1515555195510387e-02, + -.2186967991292477e-02, + .2505954820662737e-02, + .6227688863873482e-03, + -.2555002458393574e-02, + .7931739091873169e-03, + .1847642473876476e-02, + -.1675266306847334e-02, + -.7502869702875614e-03, + .1870564185082912e-02, + -.3192713484168053e-03, + -.1477979123592377e-02, + .1056550536304712e-02, + .7387576624751091e-03, + -.1305819023400545e-02, + .3442214801907539e-04, + .1120670232921839e-02, + -.6174184381961823e-03, + -.6433278322219849e-03, + .8607362397015095e-03, + .1136297360062599e-03, + -.8037807419896126e-03, + .3262492828071117e-03, + .5062967538833618e-03, + -.5257474258542061e-03, + -.1707794144749641e-03, + .5445396527647972e-03, + -.1521380618214607e-03, + -.3568925894796848e-03, + .2849949523806572e-03, + .1759170554578304e-03, + -.3522797487676144e-03, + .6828224286437035e-04, + .2114051021635532e-03, + -.1158984377980232e-03, + -.1614624634385109e-03, + .2326252870261669e-03, + -.6755953654646874e-04, + -.3137849271297455e-03 diff --git a/gr-atsc/src/lib/atsci_exp2_lp2x.dat b/gr-atsc/src/lib/atsci_exp2_lp2x.dat new file mode 100644 index 000000000..16b2b47df --- /dev/null +++ b/gr-atsc/src/lib/atsci_exp2_lp2x.dat @@ -0,0 +1,196 @@ +/* + * FILTER SPECIFICATION FILE + * FILTER TYPE:LOW PASS 1H + * PASSBAND RIPPLE IN -dB -.0100 + * STOPBAND RIPPLE IN -dB -66.0000 + * PASSBAND CUTOFF FREQUENCY 5.69000 HERTZ + * STOPBAND CUTOFF FREQUENCY 6.12000 HERTZ + * SAMPLING FREQUENCY 21.5200 HERTZ + */ + +/* + * probably total overkill... +*/ + -.8815620094537735E-04, + -.3356961533427239E-03, + .1227599568665028E-03, + .1281457953155041E-03, + -.1479196362197399E-03, + -.1201131381094456E-03, + .2271742559969425E-03, + .6969040259718895E-04, + -.3000237047672272E-03, + .1565506681799889E-04, + .3562141209840775E-03, + -.1368308439850807E-03, + -.3795824013650417E-03, + .2876669168472290E-03, + .3540110774338245E-03, + -.4550744779407978E-03, + -.2659554593265057E-03, + .6190738640725613E-03, + .1072990708053112E-03, + -.7539116777479649E-03, + .1217066310346127E-03, + .8306214585900307E-03, + -.4104166291654110E-03, + -.8203103207051754E-03, + .7365280762314796E-03, + .6983750499784946E-03, + -.1066216267645359E-02, + -.4491899162530899E-03, + .1356074586510658E-02, + .7050111889839172E-04, + -.1556793693453074E-02, + .4230584017932415E-03, + .1618413720279932E-02, + -.9978362359106541E-03, + -.1497142482548952E-02, + .1601643394678831E-02, + .1162088476121426E-02, + -.2165937330573797E-02, + -.6025419570505619E-03, + .2611500211060047E-02, + -.1667905598878861E-03, + -.2855417784303427E-02, + .1101639121770859E-02, + .2821092493832111E-02, + -.2127973828464747E-02, + -.2448682673275471E-02, + .3145063761621714E-02, + .1706911250948906E-02, + -.4030079115182161E-02, + -.5993186496198177E-03, + .4651836119592190E-02, + -.8259965106844902E-03, + -.4880243912339211E-02, + .2475241199135780E-02, + .4603198729455471E-02, + -.4209769889712334E-02, + -.3741886932402849E-02, + .5853117443621159E-02, + .2264967188239098E-02, + -.7202429696917534E-02, + -.2001645043492317E-03, + .8043776731938124E-02, + -.2357403747737408E-02, + -.8171265944838524E-02, + .5242727231234312E-02, + .7407441269606352E-02, + -.8224328979849815E-02, + -.5622585304081440E-02, + .1101253507658839E-01, + .2751644235104322E-02, + -.1327139046043158E-01, + .1191724557429552E-02, + .1463502133265138E-01, + -.6110311951488257E-02, + -.1471871789544821E-01, + .1182264182716608E-01, + .1312375022098422E-01, + -.1807126961648464E-01, + -.9420783724635840E-02, + .2453883877024055E-01, + .3084233496338129E-02, + -.3086851537227631E-01, + .6689148955047131E-02, + .3669126378372312E-01, + -.2150753932073712E-01, + -.4165294021368027E-01, + .4559329804033041E-01, + .4544338863343000E-01, + -.9483475470915437E-01, + -.4782041534781456E-01, + .3143207929097116E+00, + .5483355415053666E+00, + .3143207929097116E+00, + -.4782041534781456E-01, + -.9483475470915437E-01, + .4544338863343000E-01, + .4559329804033041E-01, + -.4165294021368027E-01, + -.2150753932073712E-01, + .3669126378372312E-01, + .6689148955047131E-02, + -.3086851537227631E-01, + .3084233496338129E-02, + .2453883877024055E-01, + -.9420783724635840E-02, + -.1807126961648464E-01, + .1312375022098422E-01, + .1182264182716608E-01, + -.1471871789544821E-01, + -.6110311951488257E-02, + .1463502133265138E-01, + .1191724557429552E-02, + -.1327139046043158E-01, + .2751644235104322E-02, + .1101253507658839E-01, + -.5622585304081440E-02, + -.8224328979849815E-02, + .7407441269606352E-02, + .5242727231234312E-02, + -.8171265944838524E-02, + -.2357403747737408E-02, + .8043776731938124E-02, + -.2001645043492317E-03, + -.7202429696917534E-02, + .2264967188239098E-02, + .5853117443621159E-02, + -.3741886932402849E-02, + -.4209769889712334E-02, + .4603198729455471E-02, + .2475241199135780E-02, + -.4880243912339211E-02, + -.8259965106844902E-03, + .4651836119592190E-02, + -.5993186496198177E-03, + -.4030079115182161E-02, + .1706911250948906E-02, + .3145063761621714E-02, + -.2448682673275471E-02, + -.2127973828464747E-02, + .2821092493832111E-02, + .1101639121770859E-02, + -.2855417784303427E-02, + -.1667905598878861E-03, + .2611500211060047E-02, + -.6025419570505619E-03, + -.2165937330573797E-02, + .1162088476121426E-02, + .1601643394678831E-02, + -.1497142482548952E-02, + -.9978362359106541E-03, + .1618413720279932E-02, + .4230584017932415E-03, + -.1556793693453074E-02, + .7050111889839172E-04, + .1356074586510658E-02, + -.4491899162530899E-03, + -.1066216267645359E-02, + .6983750499784946E-03, + .7365280762314796E-03, + -.8203103207051754E-03, + -.4104166291654110E-03, + .8306214585900307E-03, + .1217066310346127E-03, + -.7539116777479649E-03, + .1072990708053112E-03, + .6190738640725613E-03, + -.2659554593265057E-03, + -.4550744779407978E-03, + .3540110774338245E-03, + .2876669168472290E-03, + -.3795824013650417E-03, + -.1368308439850807E-03, + .3562141209840775E-03, + .1565506681799889E-04, + -.3000237047672272E-03, + .6969040259718895E-04, + .2271742559969425E-03, + -.1201131381094456E-03, + -.1479196362197399E-03, + .1281457953155041E-03, + .1227599568665028E-03, + -.3356961533427239E-03, + -.8815620094537735E-04 diff --git a/gr-atsc/src/lib/atsci_fake_single_viterbi.cc b/gr-atsc/src/lib/atsci_fake_single_viterbi.cc new file mode 100644 index 000000000..365350cc8 --- /dev/null +++ b/gr-atsc/src/lib/atsci_fake_single_viterbi.cc @@ -0,0 +1,72 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include <math.h> +#include <atsci_fake_single_viterbi.h> +#include <iostream> +#include <algorithm> + +using std::cerr; +using std::cout; + +void +atsci_fake_single_viterbi::reset() +{ + post_coder_state = 0; +} + +atsci_fake_single_viterbi::atsci_fake_single_viterbi() +{ + reset(); +} + +/* + * implement simple slicer and post coder + */ +char +atsci_fake_single_viterbi::decode (float input) +{ + int y2, y1; + + if (input < -4){ + y2 = 0; + y1 = 0; + } + else if (input < 0){ + y2 = 0; + y1 = 1; + } + else if (input < 4){ + y2 = 1; + y1 = 0; + } + else { + y2 = 1; + y1 = 1; + } + + int x1 = y1; + int x2 = y2 ^ post_coder_state; + post_coder_state = y2; + + return (x2 << 1) | x1; +} diff --git a/gr-atsc/src/lib/atsci_fake_single_viterbi.h b/gr-atsc/src/lib/atsci_fake_single_viterbi.h new file mode 100644 index 000000000..19f67740b --- /dev/null +++ b/gr-atsc/src/lib/atsci_fake_single_viterbi.h @@ -0,0 +1,50 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _ATSCFAKESINGLEVITERBI_H_ +#define _ATSCFAKESINGLEVITERBI_H_ + +/*! + * \brief single channel viterbi decoder + */ +class atsci_fake_single_viterbi +{ + +public: + atsci_fake_single_viterbi (); + + /*! + * \p INPUT ideally takes on the values +/- 1,3,5,7 + * return is decoded dibit in the range [0, 3] + */ + char decode (float input); + + void reset (); + + //! internal delay of decoder + int delay () { return 0; } + +protected: + int post_coder_state; +}; + +#endif diff --git a/gr-atsc/src/lib/atsci_fs_checker.cc b/gr-atsc/src/lib/atsci_fs_checker.cc new file mode 100644 index 000000000..52b20f84f --- /dev/null +++ b/gr-atsc/src/lib/atsci_fs_checker.cc @@ -0,0 +1,33 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include <atsci_fs_checker.h> + +// empty constructor +atsci_fs_checker::atsci_fs_checker () +{ +} + +// empty virtual destructor +atsci_fs_checker::~atsci_fs_checker () +{ +} diff --git a/gr-atsc/src/lib/atsci_fs_checker.h b/gr-atsc/src/lib/atsci_fs_checker.h new file mode 100644 index 000000000..66e650768 --- /dev/null +++ b/gr-atsc/src/lib/atsci_fs_checker.h @@ -0,0 +1,69 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ +#ifndef _ATSC_FS_CHECKER_H_ +#define _ATSC_FS_CHECKER_H_ + +#include <atsci_syminfo.h> + +/*! + * \brief abstract base class for ATSC field sync checker + * + * Processes input samples one at a time looking for + * an occurence of either the field sync 1 or field sync 2 pattern. + * + * Note that unlike atsci_fs_correlator, this class uses the symbol_num in + * input_tag to avoid having to test each symbol position. + * + * For each sample processed, an output sample and an output tag are produced. + * The output samples are identical to the input samples but are delayed by + * a number of samples given by \p delay(). The output tag associated with + * the the given output sample indicates whether this sample is the beginning + * of one of the field syncs or is an ordinary sample. The tags are defined in + * atsci_sync_tag.h. + * + * For ease of use, the field sync patterns are defined to begin with the + * first symbol of the 4 symbol data segment sync pattern that immediately + * proceeds the actual PN 511 code. This makes it easier for downstream code + * to determine the location of data segment syncs merely by counting. They'll + * occur every 832 samples assuming everything is working. + */ + +class atsci_fs_checker { + +public: + + // CREATORS + atsci_fs_checker (); + virtual ~atsci_fs_checker () = 0; + + // MANIPULATORS + virtual void reset () = 0; + virtual void filter (float input_sample, atsc::syminfo input_tag, + float *output_sample, atsc::syminfo *output_tag) = 0; + + // ACCESSORS + + //! return delay in samples from input to output + virtual int delay () const = 0; +}; + +#endif /* _ATSC_FS_CHECKER_H_ */ diff --git a/gr-atsc/src/lib/atsci_fs_checker_naive.cc b/gr-atsc/src/lib/atsci_fs_checker_naive.cc new file mode 100644 index 000000000..aac4c821a --- /dev/null +++ b/gr-atsc/src/lib/atsci_fs_checker_naive.cc @@ -0,0 +1,140 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include <atsci_fs_checker_naive.h> +#include <atsci_syminfo.h> +#include <atsci_pnXXX.h> +#include <iostream> +#include <cstring> + +using std::cerr; +using std::endl; + +static const int PN511_ERROR_LIMIT = 20; // max number of bits wrong +static const int PN63_ERROR_LIMIT = 5; + +unsigned char atsci_fs_checker_naive::s_511[LENGTH_511]; +unsigned char atsci_fs_checker_naive::s_63[LENGTH_2ND_63]; + +static void +init_s_511 (unsigned char *p) +{ + *p++ = 1; // data segment sync pattern + *p++ = 0; + *p++ = 0; + *p++ = 1; + + for (int i = 0; i < 511; i++){ + p[i] = atsc_pn511[i]; + } +} + +static void +init_s_63 (unsigned char *p) +{ + for (int i = 0; i < 63; i++){ + p[i] = atsc_pn63[i]; + } +} + +atsci_fs_checker_naive::atsci_fs_checker_naive () +{ + init_s_511 (s_511); + init_s_63 (s_63); + reset (); +} + +atsci_fs_checker_naive::~atsci_fs_checker_naive () +{ +} + +void +atsci_fs_checker_naive::reset () +{ + d_index = 0; + memset (d_sample_sr, 0, sizeof (d_sample_sr)); + memset (d_tag_sr, 0, sizeof (d_tag_sr)); + memset (d_bit_sr, 0, sizeof (d_bit_sr)); + d_field_num = 0; + d_segment_num = 0; +} + +void +atsci_fs_checker_naive::filter (float input_sample, atsc::syminfo input_tag, + float *output_sample, atsc::syminfo *output_tag) +{ + atsc::syminfo proto_tag = d_tag_sr[d_index]; // oldest tag in the queue + + if (proto_tag.symbol_num == 0){ // check for field sync pattern + + d_segment_num = (d_segment_num + 1) & atsc::SI_SEGMENT_NUM_MASK; // increment + + // check for a hit on the PN 511 pattern + int errors = 0; + int start = wrap (d_index + OFFSET_511); + + for (int i = 0; i < LENGTH_511 && errors < PN511_ERROR_LIMIT; i++) + errors += d_bit_sr[wrap (start + i)] ^ s_511[i]; + + if (errors < PN511_ERROR_LIMIT){ // 511 pattern is good. + // determine if this is field 1 or field 2 + errors = 0; + start = wrap (d_index + OFFSET_2ND_63); + for (int i = 0; i < LENGTH_2ND_63; i++) + errors += d_bit_sr[wrap (start + i)] ^ s_63[i]; + + // we should have either field 1 (== PN63) or field 2 (== ~PN63) + + if (errors <= PN63_ERROR_LIMIT){ + d_segment_num = atsc::SI_FIELD_SYNC_SEGMENT_NUM; // this is FIELD_SYNC_1 + d_field_num = 0; + } + else if (errors >= (LENGTH_2ND_63 - PN63_ERROR_LIMIT)){ + d_segment_num = atsc::SI_FIELD_SYNC_SEGMENT_NUM; // this is FIELD_SYNC_2 + d_field_num = 1; + } + else { + // should be extremely rare. + cerr << "!!! atsci_fs_checker_naive: PN63 error count = " << errors << endl; + } + } + } + + proto_tag.segment_num = d_segment_num; // fill in segment number and field number + proto_tag.field_num = d_field_num; + + // return oldest sample + *output_sample = d_sample_sr[d_index]; + *output_tag = proto_tag; + + // overwrite with newest sample; + d_sample_sr[d_index] = input_sample; + d_bit_sr[d_index] = input_sample < 0 ? 0 : 1; + d_tag_sr[d_index] = input_tag; + d_index = incr (d_index); +} + +int +atsci_fs_checker_naive::delay () const +{ + return SRSIZE; +} diff --git a/gr-atsc/src/lib/atsci_fs_checker_naive.h b/gr-atsc/src/lib/atsci_fs_checker_naive.h new file mode 100644 index 000000000..b86ab1811 --- /dev/null +++ b/gr-atsc/src/lib/atsci_fs_checker_naive.h @@ -0,0 +1,73 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _ATSC_FS_CHECKER_NAIVE_H_ +#define _ATSC_FS_CHECKER_NAIVE_H_ + +#include <atsci_fs_checker.h> + +/*! + * \brief Naive concrete implementation of field sync checker + */ +class atsci_fs_checker_naive : public atsci_fs_checker { + + private: + static const int SRSIZE = 1024; // must be power of two + int d_index; // points at oldest sample + float d_sample_sr[SRSIZE]; // sample shift register + atsc::syminfo d_tag_sr[SRSIZE]; // tag shift register + unsigned char d_bit_sr[SRSIZE]; // binary decision shift register + int d_field_num; + int d_segment_num; + + static const int OFFSET_511 = 0; // offset to PN 511 pattern + static const int LENGTH_511 = 511 + 4; // length of PN 511 pattern (+ 4 seg sync) + static const int OFFSET_2ND_63 = 578; // offset to second PN 63 pattern + static const int LENGTH_2ND_63 = 63; // length of PN 63 pattern + + static unsigned char s_511[LENGTH_511]; // PN 511 pattern + static unsigned char s_63[LENGTH_2ND_63]; // PN 63 pattern + + inline static int wrap (int index){ return index & (SRSIZE - 1); } + inline static int incr (int index){ return wrap (index + 1); } + inline static int decr (int index){ return wrap (index - 1); } + + public: + + // CREATORS + atsci_fs_checker_naive (); + ~atsci_fs_checker_naive (); + + // MANIPULATORS + virtual void reset (); + void filter (float input_sample, atsc::syminfo input_tag, + float *output_sample, atsc::syminfo *output_tag); + + // ACCESSORS + + //! return delay in samples from input to output + int delay () const; + +}; + + +#endif /* _ATSC_FS_CHECKER_NAIVE_H_ */ diff --git a/gr-atsc/src/lib/atsci_fs_correlator.cc b/gr-atsc/src/lib/atsci_fs_correlator.cc new file mode 100644 index 000000000..29cf2920c --- /dev/null +++ b/gr-atsc/src/lib/atsci_fs_correlator.cc @@ -0,0 +1,33 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include <atsci_fs_correlator.h> + +// empty constructor +atsci_fs_correlator::atsci_fs_correlator () +{ +} + +// empty virtual destructor +atsci_fs_correlator::~atsci_fs_correlator () +{ +} diff --git a/gr-atsc/src/lib/atsci_fs_correlator.h b/gr-atsc/src/lib/atsci_fs_correlator.h new file mode 100644 index 000000000..80622d9a5 --- /dev/null +++ b/gr-atsc/src/lib/atsci_fs_correlator.h @@ -0,0 +1,63 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ +#ifndef _ATSC_FS_CORRELATOR_H_ +#define _ATSC_FS_CORRELATOR_H_ + +/*! + * \brief abstract base class for ATSC field sync correlator + * + * Processes input samples one at a time looking for + * an occurence of either the field sync 1 or field sync 2 pattern. + * + * For each sample processed, an output sample and an output tag are produced. + * The output samples are identical to the input samples but are delayed by + * a number of samples given by \p delay(). The output tag associated with + * the the given output sample indicates whether this sample is the beginning + * of one of the field syncs or is an ordinary sample. The tags are defined in + * atsci_sync_tag.h. + * + * For ease of use, the field sync patterns are defined to begin with the + * first symbol of the 4 symbol data segment sync pattern that immediately + * proceeds the actual PN 511 code. This makes it easier for downstream code + * to determine the location of data segment syncs merely by counting. They'll + * occur every 832 samples assuming everything is working. + */ + +class atsci_fs_correlator { + +public: + + // CREATORS + atsci_fs_correlator (); + virtual ~atsci_fs_correlator () = 0; + + // MANIPULATORS + virtual void reset () = 0; + virtual void filter (float input_sample, float *output_sample, float *output_tag) = 0; + + // ACCESSORS + + //! return delay in samples from input to output + virtual int delay () const = 0; +}; + +#endif /* _ATSC_FS_CORRELATOR_H_ */ diff --git a/gr-atsc/src/lib/atsci_fs_correlator_naive.cc b/gr-atsc/src/lib/atsci_fs_correlator_naive.cc new file mode 100644 index 000000000..7c4946bb7 --- /dev/null +++ b/gr-atsc/src/lib/atsci_fs_correlator_naive.cc @@ -0,0 +1,125 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include <atsci_fs_correlator_naive.h> +#include <atsci_sync_tag.h> +#include <atsci_pnXXX.h> +#include <iostream> +#include <cstring> + +using std::cerr; +using std::endl; + +static const int PN511_ERROR_LIMIT = 20; // max number of bits wrong +static const int PN63_ERROR_LIMIT = 5; + +unsigned char atsci_fs_correlator_naive::s_511[LENGTH_511]; +unsigned char atsci_fs_correlator_naive::s_63[LENGTH_2ND_63]; + +static void +init_s_511 (unsigned char *p) +{ + *p++ = 1; // data segment sync pattern + *p++ = 0; + *p++ = 0; + *p++ = 1; + + for (int i = 0; i < 511; i++){ + p[i] = atsc_pn511[i]; + } +} + +static void +init_s_63 (unsigned char *p) +{ + for (int i = 0; i < 63; i++){ + p[i] = atsc_pn63[i]; + } +} + +atsci_fs_correlator_naive::atsci_fs_correlator_naive () +{ + init_s_511 (s_511); + init_s_63 (s_63); + reset (); +} + +atsci_fs_correlator_naive::~atsci_fs_correlator_naive () +{ +} + +void +atsci_fs_correlator_naive::reset () +{ + d_index = 0; + memset (d_sample_sr, 0, sizeof (d_sample_sr)); + memset (d_bit_sr, 0, sizeof (d_bit_sr)); +} + +void +atsci_fs_correlator_naive::filter (float input_sample, + float *output_sample, float *output_tag) +{ + // check for a hit on the PN 511 pattern + int errors = 0; + int start = wrap (d_index + OFFSET_511); + + for (int i = 0; i < LENGTH_511 && errors < PN511_ERROR_LIMIT; i++) + errors += d_bit_sr[wrap (start + i)] ^ s_511[i]; + + if (errors >= PN511_ERROR_LIMIT) + *output_tag = atsc_sync_tag::NORMAL; + + else { // 511 pattern is good. determine if this is field 1 or field 2 + errors = 0; + start = wrap (d_index + OFFSET_2ND_63); + for (int i = 0; i < LENGTH_2ND_63; i++) + errors += d_bit_sr[wrap (start + i)] ^ s_63[i]; + + // we should have either field 1 (== PN63) or field 2 (== ~PN63) + if (errors <= PN63_ERROR_LIMIT) + *output_tag = atsc_sync_tag::START_FIELD_SYNC_1; + + else if (errors >= (LENGTH_2ND_63 - PN63_ERROR_LIMIT)) + *output_tag = atsc_sync_tag::START_FIELD_SYNC_2; + + else { + // should be extremely rare. + cerr << "!!! atsci_fs_correlator_naive: PN63 error count = " << errors << endl; + *output_tag = atsc_sync_tag::NORMAL; + } + } + + // return oldest sample + *output_sample = d_sample_sr[d_index]; + + // overwrite with newest sample; + d_sample_sr[d_index] = input_sample; + d_bit_sr[d_index] = input_sample < 0 ? 0 : 1; + d_index = incr (d_index); +} + +int +atsci_fs_correlator_naive::delay () const +{ + return SRSIZE; +} diff --git a/gr-atsc/src/lib/atsci_fs_correlator_naive.h b/gr-atsc/src/lib/atsci_fs_correlator_naive.h new file mode 100644 index 000000000..7f9b56271 --- /dev/null +++ b/gr-atsc/src/lib/atsci_fs_correlator_naive.h @@ -0,0 +1,69 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _ATSC_FS_CORRELATOR_NAIVE_H_ +#define _ATSC_FS_CORRELATOR_NAIVE_H_ + +#include <atsci_fs_correlator.h> + +/*! + * \brief Naive concrete implementation of field sync correlator + */ +class atsci_fs_correlator_naive : public atsci_fs_correlator { + + private: + static const int SRSIZE = 1024; // must be power of two + int d_index; // points at oldest sample + float d_sample_sr[SRSIZE]; // sample shift register + unsigned char d_bit_sr[SRSIZE]; // binary decision shift register + + static const int OFFSET_511 = 0; // offset to PN 511 pattern + static const int LENGTH_511 = 511 + 4; // length of PN 511 pattern (+ 4 seg sync) + static const int OFFSET_2ND_63 = 578; // offset to second PN 63 pattern + static const int LENGTH_2ND_63 = 63; // length of PN 63 pattern + + static unsigned char s_511[LENGTH_511]; // PN 511 pattern + static unsigned char s_63[LENGTH_2ND_63]; // PN 63 pattern + + inline static int wrap (int index){ return index & (SRSIZE - 1); } + inline static int incr (int index){ return wrap (index + 1); } + inline static int decr (int index){ return wrap (index - 1); } + + public: + + // CREATORS + atsci_fs_correlator_naive (); + ~atsci_fs_correlator_naive (); + + // MANIPULATORS + virtual void reset (); + void filter (float input_sample, float *output_sample, float *output_tag); + + // ACCESSORS + + //! return delay in samples from input to output + int delay () const; + +}; + + +#endif /* _ATSC_FS_CORRELATOR_NAIVE_H_ */ diff --git a/gr-atsc/src/lib/atsci_pnXXX.cc b/gr-atsc/src/lib/atsci_pnXXX.cc new file mode 100644 index 000000000..efa61e005 --- /dev/null +++ b/gr-atsc/src/lib/atsci_pnXXX.cc @@ -0,0 +1,55 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include <atsci_pnXXX.h> + +const unsigned char atsc_pn511[511] = { + 0,0,0,0, 0,0,0,1, 0,1,1,1, 1,1,1,1, 1,1,0,0, 1,0,1,0, 1,0,1,0, 1,1,1,0, + 0,1,1,0, 0,1,1,0, 1,0,0,0, 1,0,0,0, 1,0,0,1, 1,1,1,0, 0,0,0,1, 1,1,0,1, + + 0,1,1,1, 1,1,0,1, 0,0,1,1, 0,1,0,1, 0,0,1,1, 1,0,1,1, 0,0,1,1, 1,0,1,0, + 0,1,0,0, 0,1,0,1, 1,0,0,0, 1,1,1,1, 0,0,1,0, 0,0,0,1, 0,1,0,0, 0,1,1,1, + + 1,1,0,0, 1,1,1,1, 0,1,0,1, 0,0,0,1, 0,1,0,0, 1,1,0,0, 0,0,1,1, 0,0,0,1, + 0,0,0,0, 0,1,0,0, 0,0,1,1, 1,1,1,1, 0,0,0,0, 0,1,0,1, 0,1,0,0, 0,0,0,0, + + 1,1,0,0, 1,1,1,1, 1,1,1,0, 1,1,1,0, 1,0,1,0, 1,0,0,1, 0,1,1,0, 0,1,1,0, + 0,0,1,1, 0,1,1,1, 0,1,1,1, 1,0,1,1, 0,1,0,0, 1,0,1,0, 0,1,0,0, 1,1,1,0, + + 0,1,1,1, 0,0,0,1, 0,1,1,1, 0,1,0,0, 0,0,1,1, 0,1,0,0, 1,1,1,1, 1,0,1,1, + 0,0,0,1, 0,1,0,1, 1,0,1,1, 1,1,0,0, 1,1,0,1, 1,0,1,0, 1,1,1,0, 1,1,0,1, + + 1,0,0,1, 0,1,1,0, 1,1,0,1, 1,1,0,0, 1,0,0,1, 0,0,1,0, 1,1,1,0, 0,0,1,1, + 1,0,0,1, 0,1,1,1, 1,0,1,0, 0,0,1,1, 0,1,0,1, 1,0,0,0, 0,1,0,0, 1,1,0,1, + + 1,1,1,1, 0,0,0,1, 0,0,1,0, 1,0,1,1, 1,1,0,0, 0,1,1,0, 0,1,0,1, 0,0,0,0, + 1,0,0,0, 1,1,0,0, 0,0,0,1, 1,1,1,0, 1,1,1,1, 1,1,0,1, 0,1,1,0, 1,0,1,0, + + 1,1,0,0, 1,0,0,1, 1,0,0,1, 0,0,0,1, 1,1,0,1, 1,1,0,0, 0,0,1,0, 1,1,0,1, + 0,0,0,0, 0,1,1,0, 1,1,0,0, 0,0,0,0, 1,0,0,1, 0,0,0,0, 0,0,0,1, 1,1,0 +}; + +const unsigned char atsc_pn63[63] = { + 1,1,1,0, 0,1,0,0, 1,0,1,1, 0,1,1,1, 0,1,1,0, 0,1,1,0, 1,0,1,0, 1,1,1,1, + 1,1,0,0, 0,0,0,1, 0,0,0,0, 1,1,0,0, 0,1,0,1, 0,0,1,1, 1,1,0,1, 0,0,0 +}; + diff --git a/gr-atsc/src/lib/atsci_pnXXX.h b/gr-atsc/src/lib/atsci_pnXXX.h new file mode 100644 index 000000000..1cb9b1b85 --- /dev/null +++ b/gr-atsc/src/lib/atsci_pnXXX.h @@ -0,0 +1,24 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +extern const unsigned char atsc_pn511[]; +extern const unsigned char atsc_pn63[]; diff --git a/gr-atsc/src/lib/atsci_randomizer.cc b/gr-atsc/src/lib/atsci_randomizer.cc new file mode 100644 index 000000000..5cdcaa893 --- /dev/null +++ b/gr-atsc/src/lib/atsci_randomizer.cc @@ -0,0 +1,112 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include <atsci_randomizer.h> +#include <assert.h> + +unsigned char atsci_randomizer::s_output_map[1 << 14]; +bool atsci_randomizer::s_output_map_initialized_p = false; + +atsci_randomizer::atsci_randomizer () +{ + d_state = PRELOAD_VALUE; + + if (!s_output_map_initialized_p) + initialize_output_map (); +} + +/*! + * \brief Generate the table used in the fast_output_map function. + * + * The table has 16K byte entries, but because of how is is used, only + * 256 entries end up being resident in the cache. This seems + * like a good use of memory. We can get away with a 16K table + * because the low two bits of the state do not affect the output + * function. By shifting right those two bits we shrink the table, + * and also get better cache line utilization. + */ +void +atsci_randomizer::initialize_output_map () +{ + s_output_map_initialized_p = true; + + for (int i = 0; i < (1 << 14); i++) + s_output_map[i] = slow_output_map (i << 2); +} + + +void +atsci_randomizer::reset () +{ + d_state = PRELOAD_VALUE; +} + +void +atsci_randomizer::randomize (atsc_mpeg_packet_no_sync &out, const atsc_mpeg_packet &in) +{ + assert (in.data[0] == MPEG_SYNC_BYTE); // confirm it's there, then drop + + for (int i = 0; i < ATSC_MPEG_DATA_LENGTH; i++) + out.data[i] = in.data[i + 1] ^ output_and_clk (); +} + +void +atsci_randomizer::derandomize (atsc_mpeg_packet &out, const atsc_mpeg_packet_no_sync &in) +{ + out.data[0] = MPEG_SYNC_BYTE; // add sync byte to beginning of packet + + for (int i = 0; i < ATSC_MPEG_DATA_LENGTH; i++) + out.data[i + 1] = in.data[i] ^ output_and_clk (); +} + + +unsigned char +atsci_randomizer::slow_output_map (int st) +{ + int output = 0; + + if (st & 0x8000) + output |= 0x01; + + if (st & 0x2000) + output |= 0x02; + + if (st & 0x1000) + output |= 0x04; + + if (st & 0x0200) + output |= 0x08; + + if (st & 0x0020) + output |= 0x10; + + if (st & 0x0010) + output |= 0x20; + + if (st & 0x0008) + output |= 0x40; + + if (st & 0x0004) + output |= 0x80; + + return output; +} diff --git a/gr-atsc/src/lib/atsci_randomizer.h b/gr-atsc/src/lib/atsci_randomizer.h new file mode 100644 index 000000000..c9f3b66e5 --- /dev/null +++ b/gr-atsc/src/lib/atsci_randomizer.h @@ -0,0 +1,96 @@ +/* -*- c++ -*- */ +/* + * Copyright 2001 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _ATSC_RANDOMIZER_H_ +#define _ATSC_RANDOMIZER_H_ + +#include <atsc_types.h> + +/*! + * \brief ATSC data "whitener" + * + * The data randomizer described in ATSC standard A/53B. + * See figure D4 on page 54. + */ + +class atsci_randomizer { + friend class qa_atsci_randomizer; + + public: + atsci_randomizer(); + + /*! \brief reset randomizer LFSR + * + * must be called during the Data Segment Sync interval prior to the + * first data segment. I.e., the LFSR is reset prior to the first + * field of each VSB data frame. + */ + void reset (); + + //! randomize (whiten) mpeg packet and remove leading MPEG-2 sync byte + void randomize (atsc_mpeg_packet_no_sync &out, const atsc_mpeg_packet &in); + + //! derandomize (de-whiten) mpeg packet and add leading MPEG-2 sync byte + void derandomize (atsc_mpeg_packet &out, const atsc_mpeg_packet_no_sync &in); + + unsigned int state() const { return d_state; } + + private: + static void initialize_output_map (); + static unsigned char slow_output_map (int st); + + static unsigned char fast_output_map (int st){ + return s_output_map[(st & 0xb23c) >> 2]; // Magic const with 8 bits set improves cache + // utilization. The bits correspond to the taps + // used in output calculation. Others may be + // safely ignored. + } + + //! return current output value + unsigned char output (){ + return fast_output_map (d_state); + } + + //! clock LFSR; advance to next state. + void clk (){ + if (d_state & 0x1) + d_state = ((d_state ^ MASK) >> 1) | 0x8000; + else + d_state = d_state >> 1; + } + + //! return current output value and advance to next state + unsigned char output_and_clk (){ + unsigned char r = output (); + clk (); + return r; + } + + unsigned int d_state; + + static const unsigned int PRELOAD_VALUE = 0x018f; /* 0xf180 bit reversed */ + static const unsigned int MASK = 0xa638; + static unsigned char s_output_map[1 << 14]; + static bool s_output_map_initialized_p; +}; + +#endif /* _ATSC_RANDOMIZER_H_ */ diff --git a/gr-atsc/src/lib/atsci_reed_solomon.cc b/gr-atsc/src/lib/atsci_reed_solomon.cc new file mode 100644 index 000000000..26265d351 --- /dev/null +++ b/gr-atsc/src/lib/atsci_reed_solomon.cc @@ -0,0 +1,93 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include <atsci_reed_solomon.h> +#include <assert.h> + +extern "C" { +#include "rs.h" +} + +static const int rs_init_symsize = 8; +static const int rs_init_gfpoly = 0x11d; +static const int rs_init_fcr = 0; // first consecutive root +static const int rs_init_prim = 1; // primitive is 1 (alpha) +static const int rs_init_nroots = 20; + +static const int N = (1 << rs_init_symsize) - 1; // 255 +static const int K = N - rs_init_nroots; // 235 + +static const int amount_of_pad = N - ATSC_MPEG_RS_ENCODED_LENGTH; // 48 + +atsci_reed_solomon::atsci_reed_solomon () +{ + d_rs = init_rs_char (rs_init_symsize, rs_init_gfpoly, + rs_init_fcr, rs_init_prim, rs_init_nroots); + + assert (d_rs != 0); +} + +atsci_reed_solomon::~atsci_reed_solomon () +{ + if (d_rs) + free_rs_char (d_rs); + d_rs = 0; +} + +void +atsci_reed_solomon::encode (atsc_mpeg_packet_rs_encoded &out, const atsc_mpeg_packet_no_sync &in) +{ + unsigned char tmp[K]; + + assert ((int)(amount_of_pad + sizeof (in.data)) == K); + + // add missing prefix zero padding to message + memset (tmp, 0, amount_of_pad); + memcpy (&tmp[amount_of_pad], in.data, sizeof (in.data)); + + // copy message portion to output packet + memcpy (out.data, in.data, sizeof (in.data)); + + // now compute parity bytes and add them to tail end of output packet + encode_rs_char (d_rs, tmp, &out.data[sizeof (in.data)]); +} + +int +atsci_reed_solomon::decode (atsc_mpeg_packet_no_sync &out, const atsc_mpeg_packet_rs_encoded &in) +{ + unsigned char tmp[N]; + int ncorrections; + + assert ((int)(amount_of_pad + sizeof (in.data)) == N); + + // add missing prefix zero padding to message + memset (tmp, 0, amount_of_pad); + memcpy (&tmp[amount_of_pad], in.data, sizeof (in.data)); + + // correct message... + ncorrections = decode_rs_char (d_rs, tmp, 0, 0); + + // copy corrected message to output, skipping prefix zero padding + memcpy (out.data, &tmp[amount_of_pad], sizeof (out.data)); + + return ncorrections; +} diff --git a/gr-atsc/src/lib/atsci_reed_solomon.h b/gr-atsc/src/lib/atsci_reed_solomon.h new file mode 100644 index 000000000..882741f0b --- /dev/null +++ b/gr-atsc/src/lib/atsci_reed_solomon.h @@ -0,0 +1,56 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _ATSC_REED_SOLOMON_H_ +#define _ATSC_REED_SOLOMON_H_ + +#include <atsc_types.h> + +/*! + * \brief ATSC Reed-Solomon encoder / decoder + * + * The t=10 (207,187) code described in ATSC standard A/53B. + * See figure D5 on page 55. + */ + +class atsci_reed_solomon { + + public: + atsci_reed_solomon(); + ~atsci_reed_solomon(); + + /*! + * \brief Add RS error correction encoding + */ + void encode (atsc_mpeg_packet_rs_encoded &out, const atsc_mpeg_packet_no_sync &in); + + /*! + * Decode RS encoded packet. + * \returns a count of corrected symbols, or -1 if the block was uncorrectible. + */ + int decode (atsc_mpeg_packet_no_sync &out, const atsc_mpeg_packet_rs_encoded &in); + + private: + void *d_rs; +}; + +#endif /* _ATSC_REED_SOLOMON_H_ */ diff --git a/gr-atsc/src/lib/atsci_root_raised_cosine.cc b/gr-atsc/src/lib/atsci_root_raised_cosine.cc new file mode 100644 index 000000000..00912ad53 --- /dev/null +++ b/gr-atsc/src/lib/atsci_root_raised_cosine.cc @@ -0,0 +1,36 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include <atsc_consts.h> +#include <atsci_root_raised_cosine.h> +#include <gr_firdes.h> + +vector<float> +atsc_root_raised_cosine::taps (double sampling_rate) +{ + static const double symbol_rate = ATSC_SYMBOL_RATE/2; // 1/2 as wide because we're designing lp filter + // static const int NTAPS = 93; // good number + // static const int NTAPS = 745; // better number + static const int NTAPS = 279; // better number + + return gr_firdes::root_raised_cosine (1.0, sampling_rate, symbol_rate, .115, NTAPS); +} diff --git a/gr-atsc/src/lib/atsci_root_raised_cosine.h b/gr-atsc/src/lib/atsci_root_raised_cosine.h new file mode 100644 index 000000000..c3f0a9eae --- /dev/null +++ b/gr-atsc/src/lib/atsci_root_raised_cosine.h @@ -0,0 +1,34 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ +#ifndef _ATSC_RRC_H_ +#define _ATSC_RRC_H_ + +#include <gr_fir_builder.h> + +class atsc_root_raised_cosine : public gr_fir_builder +{ +public: + virtual std::vector<float> taps (double sampling_freq); +}; + + +#endif /* _ATSC_RRC_H_ */ diff --git a/gr-atsc/src/lib/atsci_root_raised_cosine_bandpass.cc b/gr-atsc/src/lib/atsci_root_raised_cosine_bandpass.cc new file mode 100644 index 000000000..fbdc4caa5 --- /dev/null +++ b/gr-atsc/src/lib/atsci_root_raised_cosine_bandpass.cc @@ -0,0 +1,51 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include <atsci_root_raised_cosine_bandpass.h> +#include <iostream> +#include <cmath> + +using std::vector; +using std::cerr; +using std::endl; + + +vector<float> +atsc_root_raised_cosine_bandpass::taps (double sampling_freq) +{ + + vector<float> t = atsc_root_raised_cosine::taps (sampling_freq); + + cerr << "atsc_root_raised_cosine_bandpass::taps -- " << t.size () << endl; + + // heterodyne the low pass coefficients up to the specified bandpass + // center frequency. Note that when we do this, the filter bandwidth + // is effectively twice the low pass (2.69 * 2 = 5.38) and hence + // matches the diagram in the ATSC spec. + + double arg = 2 * M_PI * _center_freq / sampling_freq; + for (unsigned int i = 0; i < t.size (); i++) + // the factor of 2 keeps the gain of the passband normalized to 1 + t[i] *= 2 * cos (arg * (double) i); + + return t; +} diff --git a/gr-atsc/src/lib/atsci_root_raised_cosine_bandpass.h b/gr-atsc/src/lib/atsci_root_raised_cosine_bandpass.h new file mode 100644 index 000000000..5de2475fa --- /dev/null +++ b/gr-atsc/src/lib/atsci_root_raised_cosine_bandpass.h @@ -0,0 +1,38 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ +#ifndef _ATSC_RRC_BANDPASS_H_ +#define _ATSC_RRC_BANDPASS_H_ + +#include <atsci_root_raised_cosine.h> + +class atsc_root_raised_cosine_bandpass : public atsc_root_raised_cosine +{ +public: + atsc_root_raised_cosine_bandpass (double center_freq) : _center_freq (center_freq) {} + virtual std::vector<float> taps (double sampling_freq); + +protected: + double _center_freq; +}; + + +#endif /* _ATSC_RRC_BANDPASS_H_ */ diff --git a/gr-atsc/src/lib/atsci_single_viterbi.cc b/gr-atsc/src/lib/atsci_single_viterbi.cc new file mode 100644 index 000000000..edc2cd13b --- /dev/null +++ b/gr-atsc/src/lib/atsci_single_viterbi.cc @@ -0,0 +1,100 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include <math.h> +#include <atsci_single_viterbi.h> +#include <iostream> + +using std::cerr; +using std::cout; + +const float atsci_single_viterbi::was_sent[32] = { + -7,-3,-7,-3,-7,-3,-7,-3, + -5,-1,-5,-1,-5,-1,-5,-1, + 1,5,1,5,1,5,1,5, + 3,7,3,7,3,7,3,7 +}; + +const int atsci_single_viterbi::transition_table[32] = { + 0,2,4,6, + 2,0,6,4, + 1,3,5,7, + 3,1,7,5, + 4,6,0,2, + 6,4,2,0, + 5,7,1,3, + 7,5,3,1 +}; + +void +atsci_single_viterbi::reset() +{ + for (unsigned int i = 0; i<2; i++) + for (unsigned int j = 0; j<8; j++) { + path_metrics[i][j] = 0; + traceback[i][j] = 0; + } + phase = 0; +} + +atsci_single_viterbi::atsci_single_viterbi() +{ + reset(); +} + +char +atsci_single_viterbi::decode(float input) +{ + for (unsigned int next_state = 0; next_state < 8; next_state++) { + unsigned int index = next_state << 2; + int min_metric_symb = 0; + float min_metric = fabs(input - was_sent[index + 0]) + + path_metrics[phase][transition_table[index + 0]]; + + for (unsigned int symbol_sent = 1; symbol_sent < 4; symbol_sent++) + if( (fabs(input-was_sent[index+symbol_sent]) + + path_metrics[phase][transition_table[index+symbol_sent]]) + < min_metric) { + min_metric = fabs(input-was_sent[index+symbol_sent]) + + path_metrics[phase][transition_table[index+symbol_sent]]; + min_metric_symb = symbol_sent; + } + + path_metrics[phase^1][next_state] = min_metric; + traceback[phase^1][next_state] = (((unsigned long long)min_metric_symb) << 62) | + (traceback[phase][transition_table[index+min_metric_symb]] >> 2); + } + unsigned int best_state = 0; + float best_state_metric = path_metrics[phase^1][0]; + for (unsigned int state = 1; state < 8; state++) + if(path_metrics[phase^1][state] < best_state_metric) { + best_state = state; + best_state_metric = path_metrics[phase^1][state]; + } + if(best_state_metric > 10000) { + for(unsigned int state = 0; state < 8; state++) + path_metrics[phase^1][state] -= best_state_metric; + // cerr << "Resetting Path Metrics from " << best_state_metric << " to 0\n"; + } + phase ^= 1; + return (0x3 & traceback[phase][best_state]); +} diff --git a/gr-atsc/src/lib/atsci_single_viterbi.h b/gr-atsc/src/lib/atsci_single_viterbi.h new file mode 100644 index 000000000..907b41c90 --- /dev/null +++ b/gr-atsc/src/lib/atsci_single_viterbi.h @@ -0,0 +1,56 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _ATSCSINGLEVITERBI_H_ +#define _ATSCSINGLEVITERBI_H_ + +/*! + * \brief single channel viterbi decoder + */ +class atsci_single_viterbi +{ + +public: + atsci_single_viterbi (); + + static const unsigned int TB_LEN = 32; + + /*! + * \p INPUT ideally takes on the values +/- 1,3,5,7 + * return is decoded dibit in the range [0, 3] + */ + char decode (float input); + + void reset (); + + //! internal delay of decoder + int delay () { return TB_LEN - 1; } + +protected: + static const int transition_table[32]; + static const float was_sent[32]; + float path_metrics [2][8]; + unsigned long long traceback [2][8]; + unsigned char phase; +}; + +#endif diff --git a/gr-atsc/src/lib/atsci_slicer_agc.h b/gr-atsc/src/lib/atsci_slicer_agc.h new file mode 100644 index 000000000..f1244bd01 --- /dev/null +++ b/gr-atsc/src/lib/atsci_slicer_agc.h @@ -0,0 +1,68 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _ATSC_SLICER_AGC_H_ +#define _ATSC_SLICER_AGC_H_ + +#include <math.h> +#include <gr_single_pole_iir.h> + +/*! + * \brief Automatic Gain Control class for atsc slicer + * + * Given perfect data, output values will be +/- {7, 5, 3, 1} + */ + +class atsci_slicer_agc { + + public: + atsci_slicer_agc () : _gain(1), dc(0.0025) {}; + + + float gain () { return _gain; } + +#if 1 + float scale (float input){ + float t = input * _gain; + float output = t - REFERENCE; + float error = REFERENCE - dc.filter (t); + _gain += error * RATE; + return output; + } +#else + float scale(float input){ + float avg = dc.filter(input); + if(fabs(avg)<.1)avg=.1; + _gain += _gain*.99 + .01* REFERENCE/avg; + return input*_gain - REFERENCE; + } +#endif + + protected: + + static const float REFERENCE = 1.25; // pilot reference value + static const float RATE = 1.0e-5; // adjustment rate + float _gain; // current gain + gr_single_pole_iir<float,float,float> dc; +}; + +#endif /* _ATSC_SLICER_AGC_H_ */ diff --git a/gr-atsc/src/lib/atsci_sliding_correlator.cc b/gr-atsc/src/lib/atsci_sliding_correlator.cc new file mode 100644 index 000000000..dc821db51 --- /dev/null +++ b/gr-atsc/src/lib/atsci_sliding_correlator.cc @@ -0,0 +1,90 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002,2006 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include <atsci_sliding_correlator.h> +#include <atsci_pnXXX.h> + +// #define TRY_BACKWARDS + +/* + * Return the number of 1's in v. + * This magic code is explained wonderfully in the AMD Athlon + * optimization guide, pg 136. + */ +static inline int popcount32 (unsigned long v) +{ + unsigned long w = v - ((v >> 1) & 0x55555555); + unsigned long x = (w & 0x33333333) + ((w >> 2) & 0x33333333); + unsigned long y = (x + (x >> 4)) & 0x0f0f0f0f; + unsigned long z = (y * 0x01010101) >> 24; + + return z; +} + +atsci_sliding_correlator::atsci_sliding_correlator () +{ +#if defined(TRY_BACKWARDS) + for (int i = 511 - 1; i >= 0; i--) + mask.shift_in (atsc_pn511[i]); +#else + for (unsigned i = 0; i < 511; i++) + mask.shift_in (atsc_pn511[i]); +#endif + + and_mask.shift_in (0); + for (int i = 0; i < 511; i++) + and_mask.shift_in (1); +} + +/* + * we shift in from the top of the register towards the bottom + * + * +-- bits enter here... + * | + * v + * block 0 | block 1 | block 2 ... | block N-1 + * | + * +--> ... and drop out here + * + */ +inline void +atsci_sliding_correlator::shift_reg::shift_in (int bit) +{ + for (int i = NSRBLOCKS - 1; i > 0; i--) + d[i] = ((d[i-1] & 0x1) << (srblock_bitsize - 1)) | (d[i] >> 1); + + d[0] = (((srblock) bit) << (srblock_bitsize - 1)) | (d[0] >> 1); +} + +int +atsci_sliding_correlator::input_bit (int bit) +{ + input.shift_in (bit); + + // can probably get a win by unrolling the loop, if we need to. + int count = 0; + for (int i = 0; i < NSRBLOCKS; i++) + count += popcount32 ((input.d[i] ^ mask.d[i]) & and_mask.d[i]); + + return count; +} + diff --git a/gr-atsc/src/lib/atsci_sliding_correlator.h b/gr-atsc/src/lib/atsci_sliding_correlator.h new file mode 100644 index 000000000..9bb14db9d --- /dev/null +++ b/gr-atsc/src/lib/atsci_sliding_correlator.h @@ -0,0 +1,83 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ +#ifndef _ATSC_SLIDING_CORRELATOR_H_ +#define _ATSC_SLIDING_CORRELATOR_H_ + +#include <string> + +extern const unsigned char atsc_pn511[511]; +extern const unsigned char atsc_pn63[63]; + +/*! + * \brief look for the PN 511 field sync pattern + */ +class atsci_sliding_correlator { + public: + + atsci_sliding_correlator (); + ~atsci_sliding_correlator (){}; + + //! input hard decision bit, return correlation (0,511) + // Result is the number of wrong bits. + // E.g., 0 -> perfect match; 511 -> all bits are wrong + + int input_bit (int bit); + + //! input sample, return correlation (0,511) + // Result is the number of wrong bits. + // E.g., 0 -> perfect match; 511 -> all bits are wrong + + int input_int (int sample){ + return input_bit (sample < 0 ? 0 : 1); + } + + //! input sample, return correlation (0,511) + // Result is the number of wrong bits. + // E.g., 0 -> perfect match; 511 -> all bits are wrong + + int input_float (float sample){ + return input_bit (sample < 0 ? 0 : 1); + } + + void reset () { input.reset (); } + + private: + + typedef unsigned long srblock; + static const int bits_per_char = 8; + static const int srblock_bitsize = sizeof (srblock) * bits_per_char; + static const int NSRBLOCKS = (511 + srblock_bitsize - 1) / srblock_bitsize; + + class shift_reg { + public: + shift_reg () { reset (); } + void reset () { memset (d, 0, sizeof (d)); } + void shift_in (int bit); + srblock d[NSRBLOCKS]; + }; + + shift_reg mask; // pattern we're looking for + shift_reg input; // current input window + shift_reg and_mask; // bits to consider +}; + +#endif /* _ATSC_SLIDING_CORRELATOR_H_ */ diff --git a/gr-atsc/src/lib/atsci_sssr.cc b/gr-atsc/src/lib/atsci_sssr.cc new file mode 100644 index 000000000..7790c656c --- /dev/null +++ b/gr-atsc/src/lib/atsci_sssr.cc @@ -0,0 +1,286 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include <atsci_sssr.h> +#include <algorithm> +#include <cmath> +#include <cstdio> +#include <assert.h> +#include <atsci_diag_output.h> +#include <gr_math.h> + +/* + * ---------------------------------------------------------------- + * Segment Integrator Pre-Processor + * + * Compute weight passed to integrator based on + * correlation result and ncorr_gain2 + */ + +inline static int +sipp (bool digcorr_output) +{ + if (digcorr_output) + return +2; // positive correlation + else + return -1; // no correlation +} + +/* + * ---------------------------------------------------------------- + * Segment Sync Integrator... + */ + +static const int SSI_MIN = -16; +static const int SSI_MAX = 15; + +void +sssr::seg_sync_integrator::reset () +{ + for (int i = 0; i < ATSC_DATA_SEGMENT_LENGTH; i++) + d_integrator[i] = SSI_MIN; +} + +int +sssr::seg_sync_integrator::update (int weight, int index) +{ + int t = d_integrator[index] + weight; + t = std::max (t, SSI_MIN); + t = std::min (t, SSI_MAX); + d_integrator[index] = t; + + return t; +} + +int +sssr::seg_sync_integrator::find_max (int *v) +{ + int best_value = d_integrator[0]; + int best_index = 0; + + for (int i = 1; i < ATSC_DATA_SEGMENT_LENGTH; i++) + if (d_integrator[i] > best_value){ + best_value = d_integrator[i]; + best_index = i; + } + + *v = best_value; + return best_index; +} + +/* + * ---------------------------------------------------------------- + * Segment Sync and Symbol recovery + */ + +static const int SYMBOL_INDEX_OFFSET = 3; +static const int MIN_SEG_LOCK_CORRELATION_VALUE = 5; + +atsci_sssr::atsci_sssr () +{ + reset (); + + if (_SSSR_DIAG_OUTPUT_){ + const char *file = "sssr.ssout"; + if ((d_debug_fp = fopen (file, "wb")) == 0){ + perror (file); + exit (1); + } + } +} + +atsci_sssr::~atsci_sssr () +{ + if (d_debug_fp) + fclose (d_debug_fp); +} + +void +atsci_sssr::reset () +{ + d_correlator.reset (); + d_integrator.reset (); + d_quad_filter.reset (); + + for (int i = 0; i < ATSC_DATA_SEGMENT_LENGTH; i++) + d_quad_output[i] = 0; + + d_timing_adjust = 0; + d_counter = 0; + d_symbol_index = 0; + d_seg_locked = false; +} + +void +atsci_sssr::update (sssr::sample_t sample_in, // input + bool *seg_locked, // are we seeing segment syncs? + int *symbol_index, // 0..831 + double *timing_adjust) // how much to adjust timing +{ + double qo = d_quad_filter.update (sample_in); + d_quad_output[d_counter] = qo; + + int bit = gr_signbit (sample_in) ^ 1; // slice on sign: + => 1, - => 0 + int corr_out = d_correlator.update (bit); + int weight = sipp (corr_out); + int corr_value = d_integrator.update (weight, d_counter); + int best_correlation_index = -1; + + incr_symbol_index (); + if (incr_counter ()){ // counter just wrapped... + int best_correlation_value; + best_correlation_index = d_integrator.find_max (&best_correlation_value); + d_seg_locked = best_correlation_value >= MIN_SEG_LOCK_CORRELATION_VALUE; + d_timing_adjust = d_quad_output[best_correlation_index]; + + d_symbol_index = SYMBOL_INDEX_OFFSET - 1 - best_correlation_index; + if (d_symbol_index < 0) + d_symbol_index += ATSC_DATA_SEGMENT_LENGTH; + } + + *seg_locked = d_seg_locked; + *symbol_index = d_symbol_index; + *timing_adjust = d_timing_adjust; + + if (_SSSR_DIAG_OUTPUT_){ + float iodata[7]; + iodata[0] = bit; + iodata[1] = corr_value; + iodata[2] = qo; + iodata[3] = d_counter; + iodata[4] = d_symbol_index; + iodata[5] = best_correlation_index; + iodata[6] = d_timing_adjust; + + if (fwrite (iodata, sizeof (iodata), 1, d_debug_fp) != 1){ + perror ("fwrite: sssr"); + exit (1); + } + } + +} + +/* + * ---------------------------------------------------------------- + * Interpolator control for Seg & Symbol Sync Recovery + */ + +static const double LOOP_FILTER_TAP = 0.00025; // 0.0005 works +static const double ADJUSTMENT_GAIN = 1.0e-5 / (10 * ATSC_DATA_SEGMENT_LENGTH); + +atsci_interpolator::atsci_interpolator (double nominal_ratio_of_rx_clock_to_symbol_freq) +{ + assert (nominal_ratio_of_rx_clock_to_symbol_freq >= 1.8); + d_nominal_ratio_of_rx_clock_to_symbol_freq = + nominal_ratio_of_rx_clock_to_symbol_freq; + + d_loop.set_taps (LOOP_FILTER_TAP); + + reset (); + + if (_SSSR_DIAG_OUTPUT_){ + const char *file = "interp.ssout"; + if ((d_debug_fp = fopen (file, "wb")) == 0){ + perror (file); + exit (1); + } + } + +} + +atsci_interpolator::~atsci_interpolator () +{ + if (d_debug_fp) + fclose (d_debug_fp); +} + +void +atsci_interpolator::reset () +{ + d_w = d_nominal_ratio_of_rx_clock_to_symbol_freq; + d_mu = 0.5; + d_incr = 0; + d_loop.reset (); +} + +bool +atsci_interpolator::update ( + const sssr::sample_t input_samples[], // I: vector of samples + int nsamples, // I: total number of samples + int *index, // I/O: current input index + double timing_adjustment, // I: how much to bump timing + sssr::sample_t *output_sample) +{ + if (*index + (int) ntaps () > nsamples) + return false; + + // FIXME Confirm that this is right. I think it is. It was (1-d_mu) + *output_sample = d_interp.interpolate (&input_samples[*index], d_mu); + + double filter_out = 0; + +#if 0 + + filter_out = d_loop.filter (timing_adjustment); + d_w = d_w + ADJUSTMENT_GAIN * filter_out * 1e-3; + +#elif 1 + + filter_out = d_loop.filter (timing_adjustment); + d_mu = d_mu + ADJUSTMENT_GAIN * 10e3 * filter_out; + +#else + + static const double alpha = 0.01; + static const double beta = alpha * alpha / 16; + + double x = ADJUSTMENT_GAIN * 10e3 * timing_adjustment; + + d_mu = d_mu + alpha * x; // conceptually "phase" + d_w = d_w + beta * x; // conceptually "frequency" + +#endif + + double s = d_mu + d_w; + double float_incr = floor (s); + d_mu = s - float_incr; + d_incr = (int) float_incr; + + assert (d_incr >= 1 && d_incr <= 3); + *index += d_incr; + + if (_SSSR_DIAG_OUTPUT_){ + float iodata[6]; + iodata[0] = timing_adjustment; + iodata[1] = filter_out; + iodata[2] = d_w; + iodata[3] = d_mu; + iodata[4] = d_incr; + iodata[5] = *output_sample; + if (fwrite (iodata, sizeof (iodata), 1, d_debug_fp) != 1){ + perror ("fwrite: interpolate"); + exit (1); + } + } + + return true; +} diff --git a/gr-atsc/src/lib/atsci_sssr.h b/gr-atsc/src/lib/atsci_sssr.h new file mode 100644 index 000000000..0d575cd88 --- /dev/null +++ b/gr-atsc/src/lib/atsci_sssr.h @@ -0,0 +1,240 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * --- ATSC Segment and Symbol Sync Recovery --- + */ + +#ifndef _ATSC_SSSR_H_ +#define _ATSC_SSSR_H_ + +#include <atsc_consts.h> +#include <gri_mmse_fir_interpolator.h> +#include <gr_single_pole_iir.h> +#include <cstdio> + +/* + * --- support classes for atsci_sssr --- + */ + +namespace sssr { + + typedef float sample_t; + + // ---------------------------------------------------------------- + //! digital correlator for 1001 and 0110 patterns + + class digital_correlator { + int d_sr; // 4 bit shift register + + public: + + // Constructor + digital_correlator () { reset (); } + + // Manipulators + + //! called on channel change + void reset () { d_sr = 0; } + + //! clock bit in and return true if we've seen 1001 + + bool update (int bit) { + d_sr = ((bit & 1) << 3) | (d_sr >> 1); + + return (d_sr == 0x9); // 1001 + } + + }; + + + // ---------------------------------------------------------------- + //! segment sync integrator + + class seg_sync_integrator { + signed char d_integrator[ATSC_DATA_SEGMENT_LENGTH]; + + public: + + // Constructor + seg_sync_integrator () { reset (); } + + // Manipulators + + //! called on channel change + void reset (); + + //! update current tap with weight and return integrated correlation value + int update (int weight, int index); + + //! return index of maximum correlation value + int find_max (int *value); + + }; + + // ---------------------------------------------------------------- + //! quad filter (used to compute timing error) + + class quad_filter { + sample_t d_delay[4]; + + public: + // Constructor + quad_filter () { reset (); } + + // Manipulators + + //! called on channel change + void reset () { d_delay[0] = d_delay[1] = d_delay[2] = d_delay[3] = 0; } + + double update (sample_t sample){ + d_delay[3] = d_delay[2]; + d_delay[2] = d_delay[1]; + d_delay[1] = d_delay[0]; + d_delay[0] = sample; + + // the coefficients are -1,-1,+1,+1 + return d_delay[3] + d_delay[2] - d_delay[1] - d_delay[0]; + } + }; +} + +// ---------------------------------------------------------------- + +/*! + * \brief ATSC Segment and Symbol Sync Recovery + * + * This class implements data segment sync tracking and symbol timing + * using the method described in "ATSC/VSB Tutorial - Receiver Technology" + * by Wayne E. Bretl of Zenith, pgs 41-45. + */ + +class atsci_sssr { + sssr::digital_correlator d_correlator; + sssr::seg_sync_integrator d_integrator; + sssr::quad_filter d_quad_filter; + double d_quad_output[ATSC_DATA_SEGMENT_LENGTH]; + double d_timing_adjust; + int d_counter; // free running mod 832 counter + int d_symbol_index; + bool d_seg_locked; + FILE *d_debug_fp; + + + bool incr_counter () { + d_counter++; + if (d_counter >= ATSC_DATA_SEGMENT_LENGTH){ + d_counter = 0; + return true; + } + return false; + } + + void incr_symbol_index () { + d_symbol_index++; + if (d_symbol_index >= ATSC_DATA_SEGMENT_LENGTH) + d_symbol_index = 0; + } + +public: + + // Constructor + atsci_sssr (); + ~atsci_sssr (); + + // Manipulators + + //! call on channel change + void reset (); + + + /*! + * \brief process a single sample at the ATSC symbol rate (~10.76 MSPS) + * + * This block computes an indication of our timing error and keeps + * track of where the segment sync's occur. \p timing_adjust is + * returned to indicate how the interpolator timing needs to be + * adjusted to track the transmitter's symbol timing. If \p seg_locked + * is true, then \p symbol_index is the index of this sample in + * the current segment. The symbols are numbered from 0 to 831, where + * symbols 0, 1, 2 and 3 correspond to the data segment sync pattern, + * nominally +5, -5, -5, +5. + */ + + void update (sssr::sample_t sample_in, // input + bool *seg_locked, // are we seeing segment syncs? + int *symbol_index, // 0..831 + double *timing_adjust); // how much to adjust timing + +}; + +// ---------------------------------------------------------------- + +/*! + * \brief interpolator control for segment and symbol sync recovery + */ + +class atsci_interpolator { + gri_mmse_fir_interpolator d_interp; + gr_single_pole_iir<float,float,float> d_loop; // ``VCO'' loop filter + double d_nominal_ratio_of_rx_clock_to_symbol_freq; // FREQ + double d_w; // ratio of PERIOD of Tx to Rx clocks + double d_mu; // fractional delay [0,1] + int d_incr; // diagnostic only + FILE *d_debug_fp; // diagnostic only + +public: + //! \p nominal_ratio_of_rx_clock_to_symbol_freq must be >= 1.8 + atsci_interpolator (double nominal_ratio_of_rx_clock_to_symbol_freq); + ~atsci_interpolator (); + + // Manipulators + + //! call on channel change + void reset (); + + /*! + * \brief produce next sample referenced to Tx clock + * + * If there aren't enough input_samples left to produce + * an output, return false, else true. + */ + + bool update (const sssr::sample_t input_samples[], // I: vector of samples + int nsamples, // I: total number of samples + int *index, // I/O: current input index + double timing_adjustment, // I: how much to bump timing + sssr::sample_t *output_sample); // O: the output sample + + // Accessors + + // how much history we require on our input + unsigned ntaps () const { return d_interp.ntaps (); } + + // diagnostic accessors + double mu () const { return d_mu; } + double w () const { return d_w; } + int incr () const { return d_incr; } + +}; + +#endif /* _ATSC_SSSR_H_ */ diff --git a/gr-atsc/src/lib/atsci_syminfo.h b/gr-atsc/src/lib/atsci_syminfo.h new file mode 100644 index 000000000..8d421181e --- /dev/null +++ b/gr-atsc/src/lib/atsci_syminfo.h @@ -0,0 +1,58 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ +#ifndef _ATSC_SYMINFO_H_ +#define _ATSC_SYMINFO_H_ + +namespace atsc { + + static const unsigned int SI_SEGMENT_NUM_MASK = 0x1ff; + static const unsigned int SI_FIELD_SYNC_SEGMENT_NUM = SI_SEGMENT_NUM_MASK; // conceptually -1 + + struct syminfo { + unsigned int symbol_num : 10; // 0..831 + unsigned int segment_num : 9; // 0..311 and SI_FIELD_SYNC_SEGMENT_NUM + unsigned int field_num : 1; // 0..1 + unsigned int valid : 1; // contents are valid + }; + + + static inline bool + tag_is_start_field_sync (syminfo tag) + { + return tag.symbol_num == 0 && tag.segment_num == SI_FIELD_SYNC_SEGMENT_NUM && tag.valid; + } + + static inline bool + tag_is_start_field_sync_1 (syminfo tag) + { + return tag_is_start_field_sync (tag) && tag.field_num == 0; + } + + static inline bool + tag_is_start_field_sync_2 (syminfo tag) + { + return tag_is_start_field_sync (tag) && tag.field_num == 1; + } + +} + +#endif /* _ATSC_SYMINFO_H_ */ diff --git a/gr-atsc/src/lib/atsci_sync_tag.h b/gr-atsc/src/lib/atsci_sync_tag.h new file mode 100644 index 000000000..bca8b8646 --- /dev/null +++ b/gr-atsc/src/lib/atsci_sync_tag.h @@ -0,0 +1,56 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ +#ifndef _ATSC_SYNC_TAG_H_ +#define _ATSC_SYNC_TAG_H_ + +/* + * Constants used to communicate in the second stream passed between + * GrAtscFSCorrelator, GrAtscEqualizer and GrAtscFieldSyncMux. The + * second stream is sample-for-sample parallel with the streaming + * floating point in the first stream. The second stream provides + * information about alignment boundaries. + * + * These are in floating point because the current implementation + * requires that for a given module, all input streams share the same + * type and all output streams share the same type. We'd use unsigned + * char otherwise. + */ + +namespace atsc_sync_tag { + + // Nothing special + static const float NORMAL = 0.0; + + // The corresponding symbol is the first symbol of the + // data segment sync sequence { +5, -5, -5, +5 } + static const float START_SEG_SYNC = 1.0; + + // The corresponding symbol is the first symbol of the + // field sync 1 PN511 pattern. + static const float START_FIELD_SYNC_1 = 2.0; + + // The corresponding symbol is the first symbol of the + // field sync 2 PN511 pattern. + static const float START_FIELD_SYNC_2 = 3.0; +}; + +#endif /* _ATSC_SYNC_TAG_H_ */ diff --git a/gr-atsc/src/lib/atsci_trellis_encoder.cc b/gr-atsc/src/lib/atsci_trellis_encoder.cc new file mode 100644 index 000000000..8e09739f2 --- /dev/null +++ b/gr-atsc/src/lib/atsci_trellis_encoder.cc @@ -0,0 +1,207 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002,2006 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include <atsci_trellis_encoder.h> +#include <assert.h> +#include <stdio.h> + +static const int DIBITS_PER_BYTE = 4; + +#define SEGOF(x) ( (x) / ((SEGMENT_SIZE+1) * DIBITS_PER_BYTE)) +#define SYMOF(x) (((x) % ((SEGMENT_SIZE+1) * DIBITS_PER_BYTE))-4) + +/* How many separate Trellis encoders / Viterbi decoders run in parallel */ +static const int NCODERS = 12; + +#define ENCODER_SEG_BUMP 4 + +/* A Segment sync symbol is an 8VSB +5,-5,-5,+5 sequence that occurs at + the start of each 207-byte segment (including field sync segments). */ +#define DSEG_SYNC_SYM1 0x06 /* +5 */ +#define DSEG_SYNC_SYM2 0x01 /* -5 */ +#define DSEG_SYNC_SYM3 0x01 /* -5 */ +#define DSEG_SYNC_SYM4 0x06 /* +5 */ + + +/* Shift counts to bit numbers (high order, low order); 9x entries unused */ +static const int bit1[8] = {1, 99, 3, 98, 5, 97, 7, 96}; +static const int bit2[8] = {0, 99, 2, 98, 4, 97, 6, 96}; + + +atsci_trellis_encoder::atsci_trellis_encoder () +{ + debug = false; + reset (); +} + +atsci_trellis_encoder::~atsci_trellis_encoder () +{ +} + +void +atsci_trellis_encoder::reset () +{ + for (int i = 0; i < NCODERS; i++) + enc[i].reset (); +} + +void +atsci_trellis_encoder::encode (atsc_data_segment out[NCODERS], + const atsc_mpeg_packet_rs_encoded in[NCODERS]) +{ + unsigned char out_copy[OUTPUT_SIZE]; + unsigned char in_copy[INPUT_SIZE]; + + assert (sizeof (in_copy) == sizeof (in[0].data) * NCODERS); + assert (sizeof (out_copy) == sizeof (out[0].data) * NCODERS); + + // copy input into continguous temporary buffer + for (int i = 0; i < NCODERS; i++){ + assert (in[i].pli.regular_seg_p ()); + plinfo::sanity_check (in[i].pli); + memcpy (&in_copy[i * INPUT_SIZE/NCODERS], + &in[i].data[0], + ATSC_MPEG_RS_ENCODED_LENGTH * sizeof (in_copy[0])); + } + + memset (out_copy, 0, sizeof (out_copy)); // FIXME, sanity check + + // do the deed... + encode_helper (out_copy, in_copy); + + // copy output from contiguous temp buffer into final output + for (int i = 0; i < NCODERS; i++){ + memcpy (&out[i].data[0], + &out_copy[i * OUTPUT_SIZE/NCODERS], + ATSC_DATA_SEGMENT_LENGTH * sizeof (out_copy[0])); + + // copy pipeline info + out[i].pli = in[i].pli; + + plinfo::sanity_check (out[i].pli); + assert (out[i].pli.regular_seg_p ()); + } +} + +/* + * This code expects contiguous arrrays. Use it as is, it computes + * the correct answer. Maybe someday, when we've run out of better + * things to do, rework to avoid the copying in encode. + */ +void +atsci_trellis_encoder::encode_helper (unsigned char output[OUTPUT_SIZE], + const unsigned char input[INPUT_SIZE]) +{ + int i; + int encoder; + unsigned char trellis_buffer[NCODERS]; + int trellis_wherefrom[NCODERS]; + unsigned char *out, *next_out_seg; + int chunk; + int shift; + unsigned char dibit; + unsigned char symbol; + int skip_encoder_bump; + + /* FIXME, we may want special processing here + for a flag byte to keep track of which part of the field we're in? */ + + encoder = NCODERS - ENCODER_SEG_BUMP; + skip_encoder_bump = 0; + out = output; + next_out_seg = out; + + for (chunk = 0; + chunk < INPUT_SIZE; + chunk += NCODERS) { + /* Load a new chunk of bytes into the Trellis encoder buffers. + They get loaded in an order that depends on where we are in the + segment sync progress (sigh). + GRR! When the chunk reload happens at the same time as the + segment boundary, we should bump the encoder NOW for the reload, + rather than LATER during the bitshift transition!!! */ + if (out >= next_out_seg) { + encoder = (encoder + ENCODER_SEG_BUMP) % NCODERS; + skip_encoder_bump = 1; + } + + for (i = 0; i < NCODERS; i++) { + /* for debug */ trellis_wherefrom[encoder] = chunk+i; + trellis_buffer[encoder] = input [chunk+i]; + encoder++; + if (encoder >= NCODERS) encoder = 0; + } + + for (shift = 6; shift >= 0; shift -= 2) { + + /* Segment boundaries happen to occur on some bitshift transitions. */ + if (out >= next_out_seg) { + /* Segment transition. Output a data segment sync symbol, and + mess with the trellis encoder mux. */ + *out++ = DSEG_SYNC_SYM1; + *out++ = DSEG_SYNC_SYM2; + *out++ = DSEG_SYNC_SYM3; + *out++ = DSEG_SYNC_SYM4; + if (debug) printf ("SYNC SYNC SYNC SYNC\n"); + next_out_seg = out + (SEGMENT_SIZE * DIBITS_PER_BYTE); + + if (!skip_encoder_bump) + encoder = (encoder + ENCODER_SEG_BUMP) % NCODERS; + skip_encoder_bump = 0; + } + + /* Now run each of the 12 Trellis encoders to spit out 12 symbols. + Each encoder takes input from the same byte of the chunk, but the + outputs of the encoders come out in various orders. + NOPE -- this is false. The encoders take input from various + bytes of the chunk (which changes at segment sync time), AND + they also come out in various orders. You really do have to + keep separate track of: the input bytes, the encoders, and + the output bytes -- because they're all moving with respect to + each other!!! */ + for (i = 0; i < NCODERS; i++) { + dibit = 0x03 & (trellis_buffer[encoder] >> shift); + if (debug) + printf ("Seg %ld Symb %3ld Trell %2d Byte %6d Bits %d-%d = dibit %d ", + (long) SEGOF(out-output), (long) SYMOF(out-output), + encoder, trellis_wherefrom[encoder], + bit1[shift], bit2[shift], dibit); + symbol = enc[encoder].encode (dibit); + *out++ = symbol; + encoder++; if (encoder >= NCODERS) encoder = 0; + if (debug) printf ("sym %d\n", symbol); + } /* Encoders */ + } /* Bit shifts */ + } /* Chunks */ + + /* Check up on ourselves */ +#if 0 + assertIntsEqual (0, (INPUT_SIZE * DIBITS_PER_BYTE) % NCODERS, "not %"); + assertIntsEqual (OUTPUT_SIZE, out - output, "outptr"); + assertIntsEqual (NCODERS - ENCODER_SEG_BUMP, encoder, "mux sync"); +#else + assert (0 == (INPUT_SIZE * DIBITS_PER_BYTE) % NCODERS); + assert (OUTPUT_SIZE == out - output); + assert (NCODERS - ENCODER_SEG_BUMP == encoder); +#endif +} + diff --git a/gr-atsc/src/lib/atsci_trellis_encoder.h b/gr-atsc/src/lib/atsci_trellis_encoder.h new file mode 100644 index 000000000..429d3d105 --- /dev/null +++ b/gr-atsc/src/lib/atsci_trellis_encoder.h @@ -0,0 +1,66 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _ATSC_TRELLIS_ENCODER_H_ +#define _ATSC_TRELLIS_ENCODER_H_ + +#include <atsci_basic_trellis_encoder.h> +#include <atsc_types.h> + +/*! + * \brief fancy, schmancy 12-way interleaved trellis encoder for ATSC + */ + +class atsci_trellis_encoder { + public: + static const int NCODERS = 12; + + atsci_trellis_encoder (); + ~atsci_trellis_encoder (); + + //! reset all encoder states + void reset (); + + /*! + * Take 12 RS encoded, convolutionally interleaved segments and + * produce 12 trellis coded data segments. We work in groups of 12 + * because that's the smallest number of segments that composes a + * single full cycle of the encoder mux. + */ + void encode (atsc_data_segment out[NCODERS], + const atsc_mpeg_packet_rs_encoded in[NCODERS]); + + + protected: + static const int SEGMENT_SIZE = ATSC_MPEG_RS_ENCODED_LENGTH; // 207 + static const int INPUT_SIZE = (SEGMENT_SIZE * 12); + static const int OUTPUT_SIZE = (ATSC_DATA_SEGMENT_LENGTH * 12); + + void encode_helper (unsigned char out[OUTPUT_SIZE], + const unsigned char in[INPUT_SIZE]); + + atsci_basic_trellis_encoder enc[NCODERS]; + bool debug; +}; + + +#endif /* _ATSC_TRELLIS_ENCODER_H_ */ diff --git a/gr-atsc/src/lib/atsci_viterbi_decoder.cc b/gr-atsc/src/lib/atsci_viterbi_decoder.cc new file mode 100644 index 000000000..4e017a98b --- /dev/null +++ b/gr-atsc/src/lib/atsci_viterbi_decoder.cc @@ -0,0 +1,175 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include <atsci_viterbi_decoder.h> +#include <assert.h> +#include <stdio.h> +#include <cmath> +#include "atsci_viterbi_mux.cc" + + +/* How many separate Trellis encoders / Viterbi decoders run in parallel */ +static const int NCODERS = 12; + +static const float DSEG_SYNC_SYM1 = 5; +static const float DSEG_SYNC_SYM2 = -5; +static const float DSEG_SYNC_SYM3 = -5; +static const float DSEG_SYNC_SYM4 = 5; + +atsci_viterbi_decoder::atsci_viterbi_decoder () +{ + debug = true; + + /* + * These fifo's handle the alignment problem caused by the + * inherent decoding delay of the individual viterbi decoders. + * The net result is that this entire block has a pipeline latency + * of 12 complete segments. + * + * If anybody cares, it is possible to do it with less delay, but + * this approach is at least somewhat understandable... + */ + + // the -4 is for the 4 sync symbols + int fifo_size = ATSC_DATA_SEGMENT_LENGTH - 4 - viterbi[0].delay (); + for (int i = 0; i < NCODERS; i++) + fifo[i] = new fifo_t(fifo_size); + + reset (); +} + +atsci_viterbi_decoder::~atsci_viterbi_decoder () +{ + for (int i = 0; i < NCODERS; i++) + delete fifo[i]; +} + +void +atsci_viterbi_decoder::reset () +{ + for (int i = 0; i < NCODERS; i++){ + viterbi[i].reset (); + fifo[i]->reset (); + } +} + + +void +atsci_viterbi_decoder::decode (atsc_mpeg_packet_rs_encoded out[NCODERS], + const atsc_soft_data_segment in[NCODERS]) +{ + unsigned char out_copy[OUTPUT_SIZE]; + float in_copy[INPUT_SIZE]; + + // copy input into continguous temporary buffer + for (int i = 0; i < NCODERS; i++){ + assert (in[i].pli.regular_seg_p ()); + memcpy (&in_copy[i * INPUT_SIZE/NCODERS], + &in[i].data[0], + ATSC_DATA_SEGMENT_LENGTH * sizeof (in_copy[0])); + } + + memset (out_copy, 0, sizeof (out_copy)); // sanity check + + // do the deed... + decode_helper (out_copy, in_copy); + + // copy output from contiguous temp buffer into final output + for (int i = 0; i < NCODERS; i++){ + memcpy (&out[i].data[0], + &out_copy[i * OUTPUT_SIZE/NCODERS], + ATSC_MPEG_RS_ENCODED_LENGTH * sizeof (out_copy[0])); + + + // adjust pipeline info to reflect 12 segment delay + plinfo::delay (out[i].pli, in[i].pli, NCODERS); + } +} + +void +atsci_viterbi_decoder::decode_helper (unsigned char out[OUTPUT_SIZE], + const float symbols_in[INPUT_SIZE]) +{ + int encoder; + unsigned int i; + int dbi; + int dbwhere; + int dbindex; + int shift; + unsigned char dibit; + float symbol; + + /* Memset is not necessary if it's all working... */ + memset (out, 0, OUTPUT_SIZE); + +#define VERBOSE 0 + +#if 1 + /* Check for sync symbols in the incoming data stream */ + /* For now, all we do is complain to stdout. FIXME, pass it back to + caller as an error/quality signal. */ + for (i = 0; i < sync_symbol_indices_max; i++) { + int j = sync_symbol_indices[i]; + if (fabsf (symbols_in[j] - DSEG_SYNC_SYM1) > 1.0) + if (VERBOSE) fprintf (stderr, "** Missing dataseg sync 1 at %d, expect %g, got %g.\n", + j, DSEG_SYNC_SYM1, symbols_in[j]); + j++; + if (fabsf (symbols_in[j] - DSEG_SYNC_SYM2) > 1.0) + if (VERBOSE) fprintf (stderr, "** Missing dataseg sync 2 at %d, expect %g, got %g.\n", + j, DSEG_SYNC_SYM2, symbols_in[j]); + j++; + if (fabsf (symbols_in[j] - DSEG_SYNC_SYM3) > 1.0) + if (VERBOSE) fprintf (stderr, "** Missing dataseg sync 3 at %d, expect %g, got %g.\n", + j, DSEG_SYNC_SYM3, symbols_in[j]); + j++; + if (fabsf (symbols_in[j] - DSEG_SYNC_SYM4) > 1.0) + if (VERBOSE) fprintf (stderr, "** Missing dataseg sync 4 at %d, expect %g, got %g.\n", + j, DSEG_SYNC_SYM4, symbols_in[j]); + } +#endif +#undef VERBOSE + + // printf ("@@@ DIBITS @@@\n"); + + /* Now run each of the 12 Trellis encoders over their subset of + the input symbols */ + for (encoder = 0; encoder < NCODERS; encoder++) { + dbi = 0; /* Reinitialize dibit index for new encoder */ + fifo_t *dibit_fifo = fifo[encoder]; + + /* Feed all the incoming symbols into one encoder; + pump them into the relevant dibits. */ + for (i = 0; i < enco_which_max; i++) { + symbol = symbols_in[enco_which_syms[encoder][i]]; + dibit = dibit_fifo->stuff (viterbi[encoder].decode (symbol)); + // printf ("%d\n", dibit); + /* Store the dibit into the output data segment */ + dbwhere = enco_which_dibits[encoder][dbi++]; + dbindex = dbwhere >> 3; + shift = dbwhere & 0x7; + out[dbindex] = + (out[dbindex] & ~(0x03 << shift)) | (dibit << shift); + } /* Symbols fed into one encoder */ + } /* Encoders */ + + // fflush (stdout); +} diff --git a/gr-atsc/src/lib/atsci_viterbi_decoder.h b/gr-atsc/src/lib/atsci_viterbi_decoder.h new file mode 100644 index 000000000..a804b666c --- /dev/null +++ b/gr-atsc/src/lib/atsci_viterbi_decoder.h @@ -0,0 +1,83 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _ATSC_VITERBI_DECODER_H_ +#define _ATSC_VITERBI_DECODER_H_ + +#define USE_SIMPLE_SLICER 0 + +#include <atsc_types.h> +#include <interleaver_fifo.h> + +#if (USE_SIMPLE_SLICER) +#include <atsci_fake_single_viterbi.h> +typedef atsci_fake_single_viterbi single_viterbi_t; +#else +#include <atsci_single_viterbi.h> +typedef atsci_single_viterbi single_viterbi_t; +#endif + +/*! + * \brief fancy, schmancy 12-way interleaved viterbi decoder for ATSC + */ + +class atsci_viterbi_decoder { +public: + static const int NCODERS = 12; + + atsci_viterbi_decoder (); + ~atsci_viterbi_decoder (); + + //! reset all decoder states + void reset (); + + /*! + * Take 12 data segments of soft decisions (floats) and + * produce 12 RS encoded data segments. We work in groups of 12 + * because that's the smallest number of segments that composes a + * single full cycle of the decoder mux. + */ + void decode (atsc_mpeg_packet_rs_encoded out[NCODERS], + const atsc_soft_data_segment in[NCODERS]); + + + + protected: + typedef interleaver_fifo<unsigned char> fifo_t; + + static const int SEGMENT_SIZE = ATSC_MPEG_RS_ENCODED_LENGTH; // 207 + static const int OUTPUT_SIZE = (SEGMENT_SIZE * 12); + static const int INPUT_SIZE = (ATSC_DATA_SEGMENT_LENGTH * 12); + + void decode_helper (unsigned char out[OUTPUT_SIZE], + const float in[INPUT_SIZE]); + + + single_viterbi_t viterbi[NCODERS]; + fifo_t *fifo[NCODERS]; + bool debug; + +}; + + + +#endif /* _ATSC_VITERBI_DECODER_H_ */ diff --git a/gr-atsc/src/lib/atsci_viterbi_gen.cc b/gr-atsc/src/lib/atsci_viterbi_gen.cc new file mode 100644 index 000000000..2004dbbcb --- /dev/null +++ b/gr-atsc/src/lib/atsci_viterbi_gen.cc @@ -0,0 +1,267 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002,2006 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include <iostream> +#include <stdio.h> + +using std::cerr; + +/* + * Trellis-encode a whole pile of 12 data segments for ATSC. + * This also includes scrambling the data among twelve Trellis encoders. + * + * Input is twelve 207-byte blocks of raw data (Reed-Solomon output that's + * been scrambled up by interleaving with other blocks). + * + * Output is 12 x 208 x 4 bytes, each byte containing a 3-bit symbol. + * The first 4 bytes are the segment sync symbol. + * + Got the first version of Trellis encoder coded. Compiles, but I + didn't realize that each data segment contains an odd number of BITS! + The second data segment in a field starts by pulling bits out of the + middles of the bytes it's encoding. You actually have to read all the + entries in that table on page 59 AND 60 to get it. + + There's a 4-segment asymmetric pattern of bit accesses. + There's a 3-segment asymmetric pattern of muxing encoders. + + The result is there's a 12-segment pattern that repeats throughout + the encoding of a field. So this routine now encodes 12 segments at once. + + This encoding system was either designed by a complete idiot or by + a complete genius. It's highly complex when it could have been very + simple. Now the question is whether + this incredible complexity buys us anything subtle and important. + */ + +#define SEGMENT_SIZE 207 +#define INPUT_SIZE (SEGMENT_SIZE * 12) +#define DIBITS_PER_BYTE 4 +#define EXTRAS (4 * 12) /* FIXME, sync symbols and such */ +#define SYMBOLS_OUT ((INPUT_SIZE * DIBITS_PER_BYTE) + EXTRAS) +#define SEGOF(x) ( (x) / ((SEGMENT_SIZE+1) * DIBITS_PER_BYTE)) +#define SYMOF(x) (((x) % ((SEGMENT_SIZE+1) * DIBITS_PER_BYTE))-4) +#define ENCODERS 12 +#define ENCODER_SEG_BUMP 4 + + +/* Shift counts to bit numbers (high order, low order); 9x entries unused */ +static const int bit1[8] = {1, 99, 3, 98, 5, 97, 7, 96}; +static const int bit2[8] = {0, 99, 2, 98, 4, 97, 6, 96}; + +/* Detailed Debugging */ +int debug_dec = 0; + +/* + * Build indirect data structures to say which symbols go into which + * encoder, and then where the resulting dibits from the encoders go. + */ +int +build_decode_structures (char *fileout) +{ + int retval = 0; + int i; + int encoder; + int trellis_wheredata[ENCODERS]; + unsigned char *symp, *next_sym_seg; + unsigned char symbols[SYMBOLS_OUT]; + int chunk; + int shift; + int skip_encoder_bump; + int *enco_syms[ENCODERS]; + int *enco_dibits[ENCODERS]; + int j; + /* The data structures we'll build and then spit out... */ + int sync_symbol_indices[1000]; + int sync_symbol_indices_max; + int enco_which_syms[ENCODERS][INPUT_SIZE]; + int enco_which_dibits[ENCODERS][INPUT_SIZE]; + int enco_which_max; + #define BIT_PTR(int,shif) (((int) << 3) | ((shif) & 0x7)) + /* Running indices into them as we build 'em... */ + int *syncsyms = sync_symbol_indices; + + /* Start our running pointers at the start of our per-encoder subarrays */ + for (i = 0; i < ENCODERS; i++) { + enco_dibits[i] = enco_which_dibits[i]; + enco_syms[i] = enco_which_syms[i]; + } + + encoder = ENCODERS - ENCODER_SEG_BUMP; + skip_encoder_bump = 0; + symp = symbols; + next_sym_seg = symp; + + for (chunk = 0; + chunk < INPUT_SIZE; + chunk += ENCODERS) { + /* Associate data bytes with the Trellis encoders. + They get loaded or stored in an order that depends on where we are in the + segment sync progress (sigh). + GRR! When the chunk reload happens at the same time as the + segment boundary, we should bump the encoder NOW for the reload, + rather than LATER during the bitshift transition!!! */ + if (symp >= next_sym_seg) { + encoder = (encoder + ENCODER_SEG_BUMP) % ENCODERS; + skip_encoder_bump = 1; + } + + /* Remember where the data bytes are going to go, once we've + accumulated them from the 12 interleaved decoders */ + for (i = 0; i < ENCODERS; i++) { + trellis_wheredata[encoder] = chunk+i; + encoder++; + if (encoder >= ENCODERS) encoder = 0; + } + + for (shift = 6; shift >= 0; shift -= 2) { + + /* Segment boundaries happen to occur on some bitshift transitions. */ + if (symp >= next_sym_seg) { + /* Segment transition. Output a data segment sync symbol, and + mess with the trellis encoder mux. */ + *syncsyms++ = symp - symbols; + symp += 4; + next_sym_seg = symp + (SEGMENT_SIZE * DIBITS_PER_BYTE); + + if (!skip_encoder_bump) + encoder = (encoder + ENCODER_SEG_BUMP) % ENCODERS; + skip_encoder_bump = 0; + } + + /* Now run each of the 12 Trellis encoders to spit out 12 symbols. + Each encoder takes input from the same byte of the chunk, but the + outputs of the encoders come out in various orders. + NOPE -- this is false. The encoders take input from various + bytes of the chunk (which changes at segment sync time), AND + they also come out in various orders. You really do have to + keep separate track of: the datasegs bytes, the encoders, and + the symbol bytes -- because they're all moving with respect to + each other!!! */ + for (i = 0; i < ENCODERS; i++) { + if (debug_dec) + printf ("Seg %ld Symb %3ld Trell %2d Byte %6d Bits %d-%d = ", + (long) SEGOF(symp-symbols), (long) SYMOF(symp-symbols), + encoder, trellis_wheredata[encoder], + bit1[shift], bit2[shift]); + + /* Decoding: Grab symbol, run through decoder, slice dibit into + buffer. */ + /* This symbol goes into this encoder next */ + *(enco_syms[encoder]++) = symp - symbols; + symp++; + /* The next output from this encoder goes into these dibits */ + *(enco_dibits[encoder]++) = BIT_PTR(trellis_wheredata[encoder], shift); + + encoder++; if (encoder >= ENCODERS) encoder = 0; + } /* Encoders */ + } /* Bit shifts */ + +#if 0 + /* Now dump out the chunk of 12 data bytes that the twelve decoders have + accumulated. */ + unsigned char trellis_buffer[ENCODERS]; + unsigned char dibit; + unsigned char symbol; + int save_state; + for (i = 0; i < ENCODERS; i++) { + datasegs [trellis_wheredata[encoder]] = trellis_buffer[encoder]; + encoder++; + if (encoder >= ENCODERS) encoder = 0; + } /* Dumping encoder bytes */ +#endif + } /* Chunks */ + + /* Now print the resulting data structures in C++ */ + + if (!freopen(fileout, "w", stdout)) + return 2; + + printf ("/*\n\ + * atsc_viterbi_mux.cc\n\ + *\n\ + * Data structures for knowing which symbols are fed to which\n\ + * Viterbi decoders, and then where to put the resulting output dibits.\n\ + *\n\ + * Generated by 'atsc_viterbi_gen.cc'.\n\ + */\n\n"); + sync_symbol_indices_max = syncsyms - sync_symbol_indices; + printf ("const unsigned int sync_symbol_indices_max = %d;\n", + sync_symbol_indices_max); + printf ("const unsigned int sync_symbol_indices[%d] = {\n ", + sync_symbol_indices_max); + for (i = 0; i < sync_symbol_indices_max; i++) { + printf ("%d,%s", sync_symbol_indices[i], (7 == i%8)? "\n ": " "); + } + printf ("};\n\n"); + + enco_which_max = enco_dibits[0] - enco_which_dibits[0]; + for (i = 0; i < ENCODERS; i++) + if (enco_which_max != enco_dibits[i] - enco_which_dibits[i]) { + cerr << "Encoder " << i << " has different max_dibits " << + enco_dibits[i] - enco_which_dibits[i] << " than " << enco_which_max; + retval = 3; + } + + printf ("const unsigned int enco_which_max = %d;\n" , enco_which_max); + + printf ("const unsigned int enco_which_syms[%d][%d] = {\n", + ENCODERS, enco_which_max); + for (i = 0; i < ENCODERS; i++) { + printf (" /* %d */\n {", i); + for (j = 0; j < enco_which_max; j++) + printf ("%d,%s", enco_which_syms[i][j], (7 == j%8)? "\n ": " "); + printf ("},\n"); + } + printf ("};\n\n"); + + printf ("const unsigned int enco_which_dibits[%d][%d] = {\n", + ENCODERS, enco_which_max); + for (i = 0; i < ENCODERS; i++) { + printf (" /* %d */\n {", i); + for (j = 0; j < enco_which_max; j++) + printf ("%d,%s", enco_which_dibits[i][j], (7 == j%8)? "\n ": " "); + printf ("},\n"); + } + printf ("};\n\n"); + return retval; +} + +int +usage() +{ + cerr << "atsc_viterbi_gen: Usage:\n"; + cerr << " ./atsc_viterbi_gen -o atsc_viterbi_mux.cc\n"; + cerr << "That's all, folks!\n"; + return 1; +} + + +int +main(int argc, char **argv) +{ + if (argc != 3) return usage(); + if (argv[1][0] != '-' + || argv[1][1] != 'o' + || argv[1][2] != 0 ) return usage(); + return build_decode_structures(argv[2]); +} diff --git a/gr-atsc/src/lib/atsci_vsbtx_lp.cc b/gr-atsc/src/lib/atsci_vsbtx_lp.cc new file mode 100644 index 000000000..d0878dcc3 --- /dev/null +++ b/gr-atsc/src/lib/atsci_vsbtx_lp.cc @@ -0,0 +1,59 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include <atsc_consts.h> +#include <atsci_vsbtx_lp.h> +#include <stdexcept> +#include <cmath> +#include <iostream> + +using std::vector; +using std::cerr; +using std::endl; + +// atsc root raised cosine filter, sampling rate = 21.52 MHz +static const float atsc_vsbtx_lp2x[] = { +#include "atsc_vsbtx_lp.dat" +}; + +#define NELEM(x) (sizeof (x) / sizeof ((x)[0])) + +// is a within 5% of target? + +static bool +close_enough_p (double a, double target) +{ + double delta = fabs (target * 0.05); // 5 percent + + return fabs (target - a) <= delta; +} + +vector<float> +atsc_vsbtx_lp::taps (double sampling_freq) +{ + if (close_enough_p (sampling_freq, 2 * ATSC_SYMBOL_RATE)){ + return vector<float>(&atsc_vsbtx_lp2x[0], &atsc_vsbtx_lp2x[NELEM(atsc_vsbtx_lp2x)]); + } + else + throw std::out_of_range ( + "atsc_vsbtx_lp: no pre-designed filter close enough"); +} diff --git a/gr-atsc/src/lib/atsci_vsbtx_lp.dat b/gr-atsc/src/lib/atsci_vsbtx_lp.dat new file mode 100644 index 000000000..448fda7a2 --- /dev/null +++ b/gr-atsc/src/lib/atsci_vsbtx_lp.dat @@ -0,0 +1,49 @@ +/* + * FILTER SPECIFICATION FILE + * FILTER TYPE:LOW PASS 1H + * PASSBAND RIPPLE IN -dB -.0100 + * STOPBAND RIPPLE IN -dB -76.0000 + * PASSBAND CUTOFF FREQUENCY .250000 HERTZ + * STOPBAND CUTOFF FREQUENCY .360000 HERTZ + * SAMPLING FREQUENCY 1.00000 HERTZ + */ +/* + * gain of 2 + */ + 9.23312269151211e-04, + 8.75200144946575e-04, + -2.89211887866259e-03, + 1.31580047309399e-04, + 6.72745611518621e-03, + -5.82943391054869e-03, + -8.86140950024128e-03, + 1.84674616903067e-02, + 1.27039104700089e-03, + -3.39064113795757e-02, + 2.52537783235312e-02, + 3.74889532104135e-02, + -7.35438484698534e-02, + -3.70154529809952e-03, + 1.33745657280087e-01, + -1.12098718993366e-01, + -1.84760546311736e-01, + 5.98605459555984e-01, + 1.20420956425369e+00, + 5.98605459555984e-01, + -1.84760546311736e-01, + -1.12098718993366e-01, + 1.33745657280087e-01, + -3.70154529809952e-03, + -7.35438484698534e-02, + 3.74889532104135e-02, + 2.52537783235312e-02, + -3.39064113795757e-02, + 1.27039104700089e-03, + 1.84674616903067e-02, + -8.86140950024128e-03, + -5.82943391054869e-03, + 6.72745611518621e-03, + 1.31580047309399e-04, + -2.89211887866259e-03, + 8.75200144946575e-04, + 9.23312269151211e-04 diff --git a/gr-atsc/src/lib/atsci_vsbtx_lp.h b/gr-atsc/src/lib/atsci_vsbtx_lp.h new file mode 100644 index 000000000..112a4bb4a --- /dev/null +++ b/gr-atsc/src/lib/atsci_vsbtx_lp.h @@ -0,0 +1,36 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _ATSC_VSBTX_LP_H_ +#define _ATSC_VSBTX_LP_H_ + +#include <gr_fir_builder.h> + +class atsc_vsbtx_lp : public gr_fir_builder +{ +public: + virtual std::vector<float> taps (double sampling_freq); +}; + + + +#endif /* _ATSC_VSBTX_LP_H_ */ diff --git a/gr-atsc/src/lib/convolutional_interleaver.h b/gr-atsc/src/lib/convolutional_interleaver.h new file mode 100644 index 000000000..bb3362521 --- /dev/null +++ b/gr-atsc/src/lib/convolutional_interleaver.h @@ -0,0 +1,126 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _CONVOLUTIONAL_INTERLEAVER_H_ +#define _CONVOLUTIONAL_INTERLEAVER_H_ + +#include <vector> +#include <interleaver_fifo.h> +#include <assert.h> + +/*! + * \brief template class for generic convolutional interleaver + */ + +template<class symbol_type> +class convolutional_interleaver { + public: + + convolutional_interleaver (bool interleave_p, int nbanks, int fifo_size_incr); + virtual ~convolutional_interleaver (); + + //! reset interleaver (flushes contents and resets commutator) + void reset (); + + //! sync interleaver (resets commutator, but doesn't flush fifos) + void sync () { m_commutator = 0; } + + //! return end to end delay in symbols (delay through concatenated interleaver / deinterleaver) + int end_to_end_delay (); + + //! transform a single symbol + symbol_type transform (symbol_type input){ + symbol_type retval = m_fifo[m_commutator]->stuff (input); + m_commutator++; + if (m_commutator >= m_nbanks) + m_commutator = 0; + return retval; + } + + //! transform a bunch of symbols + void transform (symbol_type *out, const symbol_type *in, int nsymbols); + +protected: + int m_commutator; + int m_nbanks; + int m_fifo_size_incr; + std::vector<interleaver_fifo<symbol_type> *> m_fifo; +}; + +template<class symbol_type> +convolutional_interleaver<symbol_type>::convolutional_interleaver ( + bool interleave_p, + int nbanks, + int fifo_size_incr) +{ + assert (nbanks >= 1); + assert (fifo_size_incr >= 1); + + m_nbanks = nbanks; + m_fifo_size_incr = fifo_size_incr; + + m_fifo.resize (nbanks); + + if (interleave_p){ // configure as interleaver + for (int i = 0; i < nbanks; i++) + m_fifo[i] = new interleaver_fifo<symbol_type>(i * fifo_size_incr); + } + else { // configure as de-interleaver + for (int i = 0; i < nbanks; i++) + m_fifo[nbanks - 1 - i] = new interleaver_fifo<symbol_type>(i * fifo_size_incr); + } + sync (); +} + +template<class symbol_type> +convolutional_interleaver<symbol_type>::~convolutional_interleaver () +{ + for (int i = 0; i < m_nbanks; i++) + delete m_fifo[i]; +} + +template<class symbol_type> void +convolutional_interleaver<symbol_type>::reset () +{ + sync (); + for (int i = 0; i < m_nbanks; i++) + m_fifo[i]->reset (); +} + +template<class symbol_type> int +convolutional_interleaver<symbol_type>::end_to_end_delay () +{ + int m = m_nbanks * m_fifo_size_incr; + return m * (m_nbanks - 1); +} + +template<class symbol_type> void +convolutional_interleaver<symbol_type>::transform (symbol_type *out, + const symbol_type *in, + int nsymbols) +{ + // we may want to unroll this a couple of times... + for (int i = 0; i < nsymbols; i++) + out[i] = transform (in[i]); +} + +#endif /* _CONVOLUTIONAL_INTERLEAVER_H_ */ diff --git a/gr-atsc/src/lib/create_atsci_equalizer.cc b/gr-atsc/src/lib/create_atsci_equalizer.cc new file mode 100644 index 000000000..0f3bdbcb0 --- /dev/null +++ b/gr-atsc/src/lib/create_atsci_equalizer.cc @@ -0,0 +1,44 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include <create_atsci_equalizer.h> +#include <atsci_equalizer_nop.h> +#include <atsci_equalizer_lms.h> +#include <atsci_equalizer_lms2.h> + +atsci_equalizer * +create_atsci_equalizer_nop () +{ + return new atsci_equalizer_nop (); +} + +atsci_equalizer * +create_atsci_equalizer_lms () +{ + return new atsci_equalizer_lms (); +} + +atsci_equalizer * +create_atsci_equalizer_lms2 () +{ + return new atsci_equalizer_lms2 (); +} diff --git a/gr-atsc/src/lib/create_atsci_equalizer.h b/gr-atsc/src/lib/create_atsci_equalizer.h new file mode 100644 index 000000000..5e1023de9 --- /dev/null +++ b/gr-atsc/src/lib/create_atsci_equalizer.h @@ -0,0 +1,31 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ +#ifndef _CREATE_ATSC_EQUALIZER_H_ +#define _CREATE_ATSC_EQUALIZER_H_ + +class atsci_equalizer; + +atsci_equalizer *create_atsci_equalizer_nop (); +atsci_equalizer *create_atsci_equalizer_lms (); +atsci_equalizer *create_atsci_equalizer_lms2 (); + +#endif /* _CREATE_ATSC_EQUALIZER_H_ */ diff --git a/gr-atsc/src/lib/create_atsci_fs_checker.cc b/gr-atsc/src/lib/create_atsci_fs_checker.cc new file mode 100644 index 000000000..a0a0f3d1c --- /dev/null +++ b/gr-atsc/src/lib/create_atsci_fs_checker.cc @@ -0,0 +1,30 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include <create_atsci_fs_checker.h> +#include <atsci_fs_checker_naive.h> + +atsci_fs_checker * +create_atsci_fs_checker () +{ + return new atsci_fs_checker_naive (); +} diff --git a/gr-atsc/src/lib/create_atsci_fs_checker.h b/gr-atsc/src/lib/create_atsci_fs_checker.h new file mode 100644 index 000000000..6b258bcf7 --- /dev/null +++ b/gr-atsc/src/lib/create_atsci_fs_checker.h @@ -0,0 +1,34 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _CREATE_ATSC_FS_CHECKER_H_ +#define _CREATE_ATSC_FS_CHECKER_H_ + +class atsci_fs_checker; + +/*! + * Factory that creates appropriate atsci_fs_checker + */ +atsci_fs_checker *create_atsci_fs_checker (); + + +#endif /* _CREATE_ATSC_FS_CHECKER_H_ */ diff --git a/gr-atsc/src/lib/create_atsci_fs_correlator.cc b/gr-atsc/src/lib/create_atsci_fs_correlator.cc new file mode 100644 index 000000000..6664003e2 --- /dev/null +++ b/gr-atsc/src/lib/create_atsci_fs_correlator.cc @@ -0,0 +1,30 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include <create_atsci_fs_correlator.h> +#include <atsci_fs_correlator_naive.h> + +atsci_fs_correlator * +create_atsci_fs_correlator () +{ + return new atsci_fs_correlator_naive (); +} diff --git a/gr-atsc/src/lib/create_atsci_fs_correlator.h b/gr-atsc/src/lib/create_atsci_fs_correlator.h new file mode 100644 index 000000000..511bce996 --- /dev/null +++ b/gr-atsc/src/lib/create_atsci_fs_correlator.h @@ -0,0 +1,34 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _CREATE_ATSC_FS_CORRELATOR_H_ +#define _CREATE_ATSC_FS_CORRELATOR_H_ + +class atsci_fs_correlator; + +/*! + * Factory that creates appropriate atsci_fs_correlator + */ +atsci_fs_correlator *create_atsci_fs_correlator (); + + +#endif /* _CREATE_ATSC_FS_CORRELATOR_H_ */ diff --git a/gr-atsc/src/lib/fpll_btloop_coupling.h b/gr-atsc/src/lib/fpll_btloop_coupling.h new file mode 100644 index 000000000..f5c90f949 --- /dev/null +++ b/gr-atsc/src/lib/fpll_btloop_coupling.h @@ -0,0 +1,38 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ +#ifndef _FPLL_BTLOOP_COUPLING_H_ +#define _FPLL_BTLOOP_COUPLING_H_ + +/*! + * Magic coupling constant between GrAtscFPLL and GrAtscBitTimingLoop. + * Trust me, you don't want to mess with this. + * + * The agc block buried in the FPLL indirectly sets the level of the input + * to the bit timing loop. The bit timing loop's convergence properties + * depend on the the mean amplitude of it's input. This constant ties + * them together such that you can tweak the input level of the bit timing loop + * (somewhat) without screwing everything. + */ + +static const float FPLL_BTLOOP_COUPLING_CONST = 3.125; + +#endif /* _FPLL_BTLOOP_COUPLING_H_ */ diff --git a/gr-atsc/src/lib/gen_encoder.py b/gr-atsc/src/lib/gen_encoder.py new file mode 100755 index 000000000..0a2a50801 --- /dev/null +++ b/gr-atsc/src/lib/gen_encoder.py @@ -0,0 +1,63 @@ +#!/usr/bin/python +# +# Copyright 2002 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio 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; either version 2, or (at your option) +# any later version. +# +# GNU Radio 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 for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. +# + +def output(input, state): + x2 = (input >> 1) & 0x1 + x1 = (input >> 0) & 0x1 + s = (state >> 2) & 0x1 + t = (state >> 1) & 0x1 + u = (state >> 0) & 0x1 + + z0 = u + z1 = x1 + z2 = x2 ^ s + return (z2 << 2) | (z1 << 1) | z0 + + +def next_state(input, state): + x2 = (input >> 1) & 0x1 + x1 = (input >> 0) & 0x1 + s0 = (state >> 2) & 0x1 + t0 = (state >> 1) & 0x1 + u0 = (state >> 0) & 0x1 + + s1 = x2 ^ s0 + t1 = u0 + u1 = t0 ^ x1 + + return (s1 << 2) | (t1 << 1) | u1 + +print "@@@ NEXT @@@" + +for i in range (32): + state = (i >> 2) & 0x7 + input = i & 0x3 + print next_state (input, state) + + +print "@@@ OUTPUT @@@" + +for i in range (32): + state = (i >> 2) & 0x7 + input = i & 0x3 + print output (input, state) + diff --git a/gr-atsc/src/lib/interleaver_fifo.h b/gr-atsc/src/lib/interleaver_fifo.h new file mode 100644 index 000000000..e20b968ff --- /dev/null +++ b/gr-atsc/src/lib/interleaver_fifo.h @@ -0,0 +1,86 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _INTERLEAVER_FIFO_H_ +#define _INTERLEAVER_FIFO_H_ + + +#include <interleaver_fifo.h> +#include <string.h> + +/*! + * \brief template class for interleaver fifo + */ + +template<class symbol_type> +class interleaver_fifo { + public: + + interleaver_fifo (unsigned int size); + ~interleaver_fifo (); + + //! reset interleaver (flushes contents and resets commutator) + void reset (); + + //! stuff a symbol into the fifo and return the oldest + symbol_type stuff (symbol_type input){ + if (m_size == 0) + return input; + + symbol_type retval = m_fifo[m_position]; + m_fifo[m_position] = input; + m_position++; + if (m_position >= m_size) + m_position = 0; + + return retval; + } + +protected: + unsigned int m_size; + unsigned int m_position; + symbol_type *m_fifo; +}; + +template<class symbol_type> +interleaver_fifo<symbol_type>::interleaver_fifo (unsigned int size) +{ + m_size = size; + m_position = 0; + m_fifo = new symbol_type[size]; + memset (m_fifo, 0, m_size * sizeof (symbol_type)); +} + +template<class symbol_type> +interleaver_fifo<symbol_type>::~interleaver_fifo () +{ + delete [] m_fifo; +} + +template<class symbol_type> void +interleaver_fifo<symbol_type>::reset () +{ + m_position = 0; + memset (m_fifo, 0, m_size * sizeof (symbol_type)); +} + +#endif /* _INTERLEAVER_FIFO_H_ */ diff --git a/gr-atsc/src/lib/plinfo.cc b/gr-atsc/src/lib/plinfo.cc new file mode 100644 index 000000000..b28a13d59 --- /dev/null +++ b/gr-atsc/src/lib/plinfo.cc @@ -0,0 +1,59 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002,2006 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include <atsc_types.h> +#include <assert.h> + +void +plinfo::delay (plinfo &out, const plinfo &in, int nsegs_of_delay) +{ + assert (in.regular_seg_p ()); + assert (nsegs_of_delay >= 0); + + int s = in.segno (); + if (in.in_field2_p ()) + s += ATSC_DSEGS_PER_FIELD; + + s -= nsegs_of_delay; + if (s < 0) + s += 2 * ATSC_DSEGS_PER_FIELD; + + assert (0 <= s && s < 2 * ATSC_DSEGS_PER_FIELD); + + if (s < ATSC_DSEGS_PER_FIELD) + out.set_regular_seg (false, s); // field 1 + else + out.set_regular_seg (true, s - ATSC_DSEGS_PER_FIELD); // field 2 +} + +void +plinfo::sanity_check (const plinfo &x) +{ + // basic sanity checks... + assert (x.segno () >= 0); + assert (x.segno () < (unsigned) ATSC_DSEGS_PER_FIELD); + assert ((x.flags () & ~0x3f) == 0); + + assert (x.regular_seg_p () ^ x.field_sync_p ()); + assert ((x.segno () != 0) ^ x.first_regular_seg_p ()); +} + diff --git a/gr-atsc/src/lib/qa_atsci.cc b/gr-atsc/src/lib/qa_atsci.cc new file mode 100644 index 000000000..bc7fba3a1 --- /dev/null +++ b/gr-atsc/src/lib/qa_atsci.cc @@ -0,0 +1,63 @@ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * This class gathers together all the test cases for the atsc + * directory into a single test suite. As you create new test cases, + * add them here. + */ + +#include <qa_atsci.h> +#include <qa_atsci_randomizer.h> +#include <qa_atsci_reed_solomon.h> +#include <qa_interleaver_fifo.h> +#include <qa_convolutional_interleaver.h> +#include <qa_atsci_data_interleaver.h> +#include <qa_atsci_basic_trellis_encoder.h> +#include <qa_atsci_sliding_correlator.h> +#include <qa_atsci_fake_single_viterbi.h> +#include <qa_atsci_single_viterbi.h> +#include <qa_atsci_trellis_encoder.h> +#include <qa_atsci_viterbi_decoder.h> +#include <qa_atsci_fs_correlator.h> +#include <qa_atsci_equalizer_nop.h> + +CppUnit::TestSuite * +qa_atsc::suite () +{ + CppUnit::TestSuite *s = new CppUnit::TestSuite ("atsc"); + + s->addTest (qa_atsci_randomizer::suite ()); + s->addTest (qa_atsci_reed_solomon::suite ()); + s->addTest (qa_interleaver_fifo::suite ()); + s->addTest (qa_convolutional_interleaver::suite ()); + s->addTest (qa_atsci_data_interleaver::suite ()); + s->addTest (qa_atsci_basic_trellis_encoder::suite ()); + s->addTest (qa_atsci_sliding_correlator::suite ()); + s->addTest (qa_atsci_fake_single_viterbi::suite ()); + s->addTest (qa_atsci_single_viterbi::suite ()); + s->addTest (qa_atsci_trellis_encoder::suite ()); + s->addTest (qa_atsci_viterbi_decoder::suite ()); + s->addTest (qa_atsci_fs_correlator::suite ()); + s->addTest (qa_atsci_equalizer_nop::suite ()); + + return s; +} diff --git a/gr-atsc/src/lib/qa_atsci.h b/gr-atsc/src/lib/qa_atsci.h new file mode 100644 index 000000000..cf861a8be --- /dev/null +++ b/gr-atsc/src/lib/qa_atsci.h @@ -0,0 +1,37 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _QA_ATSC_H_ +#define _QA_ATSC_H_ + +#include <cppunit/TestSuite.h> + +//! collect all the tests for the dtv directory + +class qa_atsc { + public: + //! return suite of tests for all of dtv directory + static CppUnit::TestSuite *suite (); +}; + + +#endif /* _QA_ATSC_H_ */ diff --git a/gr-atsc/src/lib/qa_atsci_basic_trellis_encoder.cc b/gr-atsc/src/lib/qa_atsci_basic_trellis_encoder.cc new file mode 100644 index 000000000..c6212f30d --- /dev/null +++ b/gr-atsc/src/lib/qa_atsci_basic_trellis_encoder.cc @@ -0,0 +1,67 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <cppunit/TestAssert.h> +#include <qa_atsci_basic_trellis_encoder.h> +#include <stdlib.h> +#include <stdio.h> + +void +qa_atsci_basic_trellis_encoder::t0 () +{ + const static unsigned char in[14] = { + 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 2, 3 + }; + + const static unsigned char expected_out[14] = { + 0, 2, 3, 1, 1, 3, 0, 1, 2, 0, 0, 2, 5, 2 + }; + + for (unsigned i = 0; i < sizeof (in); i++) + CPPUNIT_ASSERT_EQUAL ((int) expected_out[i], enc.encode (in[i])); + + // reset encoder and test again. + + enc.reset (); + for (unsigned i = 0; i < sizeof (in); i++) + CPPUNIT_ASSERT_EQUAL ((int) expected_out[i], enc.encode (in[i])); +} + + +void +qa_atsci_basic_trellis_encoder::t1 () +{ + // Print data to externally check distribution. + // looks OK. +#if 0 + srandom (27); + + for (int i = 0; i < 8192; i++){ + int t = (random () >> 10) & 0x3; // 2 random bits + printf ("%d %d\n", t, enc.encode (t)); + } +#endif +} diff --git a/gr-atsc/src/lib/qa_atsci_basic_trellis_encoder.h b/gr-atsc/src/lib/qa_atsci_basic_trellis_encoder.h new file mode 100644 index 000000000..5d76f5ea0 --- /dev/null +++ b/gr-atsc/src/lib/qa_atsci_basic_trellis_encoder.h @@ -0,0 +1,44 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ +#ifndef _QA_ATSC_BASIC_TRELLIS_ENCODER_H_ +#define _QA_ATSC_BASIC_TRELLIS_ENCODER_H_ + +#include <cppunit/extensions/HelperMacros.h> +#include <cppunit/TestCase.h> + +#include <atsci_basic_trellis_encoder.h> + +class qa_atsci_basic_trellis_encoder : public CppUnit::TestCase { + + CPPUNIT_TEST_SUITE (qa_atsci_basic_trellis_encoder); + CPPUNIT_TEST (t0); + CPPUNIT_TEST (t1); + CPPUNIT_TEST_SUITE_END (); + + private: + atsci_basic_trellis_encoder enc; + + void t0 (); + void t1 (); +}; + +#endif /* _QA_ATSC_BASIC_TRELLIS_ENCODER_H_ */ diff --git a/gr-atsc/src/lib/qa_atsci_data_interleaver.cc b/gr-atsc/src/lib/qa_atsci_data_interleaver.cc new file mode 100644 index 000000000..c09d1231c --- /dev/null +++ b/gr-atsc/src/lib/qa_atsci_data_interleaver.cc @@ -0,0 +1,196 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include <cppunit/TestAssert.h> +#include <qa_atsci_data_interleaver.h> + + +/*! + * write an easy to identify pattern into the packet + */ +void +qa_atsci_data_interleaver::init_test_packet (int counter, + atsc_mpeg_packet_rs_encoded &out) +{ + out.data[0] = 0xf0; + out.data[1] = 0xff; + out.data[2] = (counter >> 8) & 0xff; + out.data[3] = counter & 0xff; + + for (int i = 4; i < 205; i++) + out.data[i] = i; + + out.data[205] = 0xa0; + out.data[206] = 0xaf; +} + +void +qa_atsci_data_interleaver::print_packet (FILE *fp, + int frame_number, + int field_number, + int segment_number, + const atsc_mpeg_packet_rs_encoded &in) +{ + fprintf (fp, "%04d:%d:%03d ", frame_number, field_number, segment_number); + + const unsigned char *p = &in.data[0]; + for (int i = 0; i < 8; i++) + fprintf (fp, "%02X", p[i]); + + fprintf (fp, " "); + p = &in.data[8]; + for (int i = 0; i < 8; i++) + fprintf (fp, "%02X", p[i]); + + + fprintf (fp, " ... "); + p = &in.data[191]; + for (int i = 0; i < 8; i++) + fprintf (fp, "%02X", p[i]); + + fprintf (fp, " "); + p = &in.data[199]; + for (int i = 0; i < 8; i++) + fprintf (fp, "%02X", p[i]); + + fprintf (fp, "\n"); +} + +void +qa_atsci_data_interleaver::chk_assert (const atsc_mpeg_packet_rs_encoded &expected, + const atsc_mpeg_packet_rs_encoded &actual) +{ + if (expected == actual) + return; + + FILE *fp = stderr; + + fprintf (fp, "Expected: "); + print_packet (fp, 0, 0, 0, expected); + + fprintf (fp, "Actual: "); + print_packet (fp, 0, 0, 0, actual); + + CPPUNIT_ASSERT (expected == actual); +} + +void +qa_atsci_data_interleaver::t0 () +{ + int counter = 0; + atsc_mpeg_packet_rs_encoded in, enc, out; + atsc_mpeg_packet_rs_encoded zero; + + memset (&zero, 0, sizeof (zero)); + + for (int frame = 0; frame < 4; frame++){ + for (int field = 0; field < 2; field++){ + for (int segment = 0; segment < 312; segment++, counter++){ + + // build test packet + init_test_packet (counter, in); + in.pli.set_regular_seg (field == 1, segment); + + // interleave it + outbound.interleave (enc, in); + + // deinterleave it + inbound.deinterleave (out, enc); + + if (counter < 52) + // CPPUNIT_ASSERT (zero == out); + chk_assert (zero, out); + + else if (counter >= 52){ + atsc_mpeg_packet_rs_encoded expected; + init_test_packet (counter - 52, expected); + // CPPUNIT_ASSERT (expected == out); + chk_assert (expected, out); + } + } + } + } +} + +// +// Note, this assumes that the interleaver and deinterleaver +// have the state left by t0. +// +// This test pushes crap into the interleaver, and then confirms that +// the deinterleaver recovers. This would be part of what you'd see +// on a channel change. +// + +void +qa_atsci_data_interleaver::t1 () +{ + int counter = 0; + atsc_mpeg_packet_rs_encoded in, enc, out; + atsc_mpeg_packet_rs_encoded zero; + + memset (&zero, 0, sizeof (zero)); + + static const int NCRAP = 13; + + // push NCRAP segments of crap into the interleaver, + // but don't change the deinterleaver state + + for (int i = 0; i < NCRAP; i++){ + init_test_packet (i + 2758, in); + in.pli.set_regular_seg (false, i + 5); + + outbound.interleave (enc, in); + } + + // now run the normal test. + // we should get good segments after NCRAP + 52 + + int starting_counter = 3141; + counter = starting_counter; + + for (int frame = 0; frame < 4; frame++){ + for (int field = 0; field < 2; field++){ + for (int segment = 0; segment < 312; segment++, counter++){ + + // build test packet + init_test_packet (counter, in); + in.pli.set_regular_seg (field == 1, segment); + + // interleave it + outbound.interleave (enc, in); + + // deinterleave it + inbound.deinterleave (out, enc); + + if (counter < starting_counter + 52 + NCRAP){ + // don't care... + } + else if (counter >= starting_counter + 52 + NCRAP){ + atsc_mpeg_packet_rs_encoded expected; + init_test_packet (counter - 52, expected); + // CPPUNIT_ASSERT (expected == out); + chk_assert (expected, out); + } + } + } + } +} diff --git a/gr-atsc/src/lib/qa_atsci_data_interleaver.h b/gr-atsc/src/lib/qa_atsci_data_interleaver.h new file mode 100644 index 000000000..9d72f1a99 --- /dev/null +++ b/gr-atsc/src/lib/qa_atsci_data_interleaver.h @@ -0,0 +1,60 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _QA_ATSC_DATA_INTERLEAVER_H_ +#define _QA_ATSC_DATA_INTERLEAVER_H_ + +#include <cppunit/extensions/HelperMacros.h> +#include <cppunit/TestCase.h> +#include <stdio.h> + +#include <atsci_data_interleaver.h> + +class qa_atsci_data_interleaver : public CppUnit::TestCase { + public: + + void setUp (){ + outbound.reset (); + inbound.reset (); + } + + CPPUNIT_TEST_SUITE (qa_atsci_data_interleaver); + CPPUNIT_TEST (t0); + CPPUNIT_TEST (t1); + CPPUNIT_TEST_SUITE_END (); + + private: + atsci_data_interleaver outbound; + atsci_data_deinterleaver inbound; + + void t0 (); + void t1 (); + + void init_test_packet (int counter, atsc_mpeg_packet_rs_encoded &out); + void print_packet (FILE *fp, int frame_number, int field_number, int segment_number, + const atsc_mpeg_packet_rs_encoded &in); + void chk_assert (const atsc_mpeg_packet_rs_encoded &expected, + const atsc_mpeg_packet_rs_encoded &actual); +}; + + +#endif /* _QA_ATSC_DATA_INTERLEAVER_H_ */ diff --git a/gr-atsc/src/lib/qa_atsci_equalizer_nop.cc b/gr-atsc/src/lib/qa_atsci_equalizer_nop.cc new file mode 100644 index 000000000..a12f2536c --- /dev/null +++ b/gr-atsc/src/lib/qa_atsci_equalizer_nop.cc @@ -0,0 +1,246 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include <qa_atsci_equalizer_nop.h> +#include <atsci_equalizer.h> +#include <atsci_equalizer_nop.h> +#include <atsci_pnXXX.h> +#include <atsc_types.h> +#include <cppunit/TestAssert.h> +#include <assert.h> +#include <iostream> + +using std::cerr; +using std::endl; + + +static const int SYMBOLS_PER_FIELD = (ATSC_DSEGS_PER_FIELD + 1) * ATSC_DATA_SEGMENT_LENGTH; +static const int PAD = 500; +static const int NFIELDS = 2; + +static const int INPUT_SIZE = PAD + (NFIELDS * SYMBOLS_PER_FIELD); + +static float +bin_map (int bit) +{ + return bit ? +5 : -5; +} + +static void +init_tags (atsc::syminfo *tags, int segnum, int fieldnum) +{ + int i; + + for (i = 0; i < ATSC_DATA_SEGMENT_LENGTH; i++){ + tags[i].symbol_num = i; + tags[i].segment_num = segnum; + tags[i].field_num = fieldnum; + tags[i].valid = 1; + } +} + +static void +init_data_seg (float *p, atsc::syminfo *tags, int v, int segnum, int fieldnum) +{ + init_tags (tags, segnum, fieldnum); + + int i = 0; + + p[i++] = bin_map (1); // data segment sync pulse + p[i++] = bin_map (0); + p[i++] = bin_map (0); + p[i++] = bin_map (1); + + for (; i < ATSC_DATA_SEGMENT_LENGTH; i++) + p[i] = (float) (i + v); +} + +static void +init_field_sync_tags (atsc::syminfo *tags, int fieldnum) +{ + init_tags (tags, atsc::SI_FIELD_SYNC_SEGMENT_NUM, fieldnum); +} + +static void +init_field_sync_common (float *p, int mask) + +{ + int i = 0; + + p[i++] = bin_map (1); // data segment sync pulse + p[i++] = bin_map (0); + p[i++] = bin_map (0); + p[i++] = bin_map (1); + + for (int j = 0; j < 511; j++) // PN511 + p[i++] = bin_map (atsc_pn511[j]); + + for (int j = 0; j < 63; j++) // PN63 + p[i++] = bin_map (atsc_pn63[j]); + + for (int j = 0; j < 63; j++) // PN63, toggled on field 2 + p[i++] = bin_map (atsc_pn63[j] ^ mask); + + for (int j = 0; j < 63; j++) // PN63 + p[i++] = bin_map (atsc_pn63[j]); + + p[i++] = bin_map (0); // 24 bits of VSB8 mode identifiera + p[i++] = bin_map (0); + p[i++] = bin_map (0); + p[i++] = bin_map (0); + + p[i++] = bin_map (1); + p[i++] = bin_map (0); + p[i++] = bin_map (1); + p[i++] = bin_map (0); + + p[i++] = bin_map (0); + p[i++] = bin_map (1); + p[i++] = bin_map (0); + p[i++] = bin_map (1); + + p[i++] = bin_map (1); + p[i++] = bin_map (1); + p[i++] = bin_map (1); + p[i++] = bin_map (1); + + p[i++] = bin_map (0); + p[i++] = bin_map (1); + p[i++] = bin_map (0); + p[i++] = bin_map (1); + + p[i++] = bin_map (1); + p[i++] = bin_map (0); + p[i++] = bin_map (1); + p[i++] = bin_map (0); + + + for (int j = 0; j < 92; j++) // 92 more bits + p[i++] = bin_map (atsc_pn63[j % 63]); + + // now copy the last 12 symbols of the previous segment + // bogus fill + + for (int j = 0; j < 12; j++) + p[i++] = bin_map (j & 1); + + assert (i == ATSC_DATA_SEGMENT_LENGTH); +} + +void +qa_atsci_equalizer_nop::setUp () +{ + eq = new atsci_equalizer_nop (); +} + +void +qa_atsci_equalizer_nop::tearDown () +{ + delete eq; + eq = 0; +} + +static void +setup_test_data (float *data, atsc::syminfo *tags) +{ + int mask = 0; + int i = 0; + + for (i = 0; i < PAD; i++){ + data[i] = (float) i; + tags[i].symbol_num = 13 + i; + tags[i].segment_num = 17; + tags[i].field_num = 0; + tags[i].valid = 1; + } + + for (int nfields = 0; nfields < NFIELDS; nfields++){ + init_field_sync_common (&data[i], mask); + init_field_sync_tags (&tags[i], mask); + i += ATSC_DATA_SEGMENT_LENGTH; + + for (int segnum = 0; segnum < 312; segnum++){ + init_data_seg (&data[i], &tags[i], i, segnum, mask); + i += ATSC_DATA_SEGMENT_LENGTH; + } + mask ^= 1; + } + assert (i == INPUT_SIZE); +} + +void +qa_atsci_equalizer_nop::t0 () +{ + // these are dynamically allocated because they are bigger + // than the default stack limit. + + float *input_data = new float[INPUT_SIZE]; + atsc::syminfo *input_tags = new atsc::syminfo[INPUT_SIZE]; + float *output_data = new float[INPUT_SIZE]; + + try { + + memset (input_data, 0, sizeof (input_data)); + memset (input_tags, 0, sizeof (input_tags)); + memset (output_data, 0, sizeof (output_data)); + + setup_test_data (input_data, input_tags); + + eq->filter (input_data, input_tags, + output_data, INPUT_SIZE); + + + // now check that data values got copied correctly + + for (int i = 0; i < INPUT_SIZE; i++){ + + if (input_tags[i].segment_num == atsc::SI_FIELD_SYNC_SEGMENT_NUM){ + // ignore entire field sync data segment + } + else if (input_tags[i].symbol_num <= 3){ + // ignore 4 symbols of data segment sync (+5, -5, -5, +5) + } + else { + if (output_data[i] != (float) i){ + cerr << "output_data[" << i << "] == " << output_data[i] << endl; + CPPUNIT_ASSERT_DOUBLES_EQUAL ((float) i, output_data[i], 1e-6); + } + } + } + + delete [] input_data; + delete [] input_tags; + delete [] output_data; + } + + catch ( ... ){ + delete [] input_data; + delete [] input_tags; + delete [] output_data; + } +} + +void +qa_atsci_equalizer_nop::t1 () +{ + // think of another test... +} diff --git a/gr-atsc/src/lib/qa_atsci_equalizer_nop.h b/gr-atsc/src/lib/qa_atsci_equalizer_nop.h new file mode 100644 index 000000000..cfe8920ea --- /dev/null +++ b/gr-atsc/src/lib/qa_atsci_equalizer_nop.h @@ -0,0 +1,51 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _QA_ATSC_EQUALIZER_NOP_H_ +#define _QA_ATSC_EQUALIZER_NOP_H_ + +#include <cppunit/extensions/HelperMacros.h> +#include <cppunit/TestCase.h> + +class atsci_equalizer; + +class qa_atsci_equalizer_nop : public CppUnit::TestCase { +private: + atsci_equalizer *eq; + +public: + void setUp (); + void tearDown (); + + CPPUNIT_TEST_SUITE (qa_atsci_equalizer_nop); + CPPUNIT_TEST (t0); + CPPUNIT_TEST (t1); + CPPUNIT_TEST_SUITE_END (); + +private: + + void t0 (); + void t1 (); + +}; + +#endif /* _QA_ATSC_EQUALIZER_NOP_H_ */ diff --git a/gr-atsc/src/lib/qa_atsci_fake_single_viterbi.cc b/gr-atsc/src/lib/qa_atsci_fake_single_viterbi.cc new file mode 100644 index 000000000..f0ff63560 --- /dev/null +++ b/gr-atsc/src/lib/qa_atsci_fake_single_viterbi.cc @@ -0,0 +1,143 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <cppunit/TestAssert.h> +#include <stdio.h> +#include <atsci_fake_single_viterbi.h> +#include <qa_atsci_fake_single_viterbi.h> +#include <random.h> + + +static const int NTRIALS = 50; +static const int MAXERRORS = 10; +static const int NN = 200; + +static const int MAXDIBIT = 3; + +void +qa_atsci_fake_single_viterbi::encode_block (unsigned char *out, unsigned char *in, + unsigned int n) +{ + for (unsigned int i = 0; i < n; i++) { + out[i] = encoder.encode(in[i]); + } +} + + +void +qa_atsci_fake_single_viterbi::decode_block (unsigned char *out, unsigned char *in, + unsigned int n) +{ + for (unsigned int i = 0; i < n; i++) { + out[i] = decoder.decode ((2*in[i]-7) + noise ()); + } +} + +float +qa_atsci_fake_single_viterbi::noise () +{ +#if 1 + return 2.0 * ((float) random () / RANDOM_MAX - 0.5);; +#else + return 0; +#endif +} + +void +qa_atsci_fake_single_viterbi::t0 () +{ + int blocklen = NN; + unsigned char in[blocklen]; + unsigned char enc[blocklen]; + unsigned char out[blocklen]; + int decoder_errors = 0; + int delay = decoder.delay (); + int i; + + // printf (" Delay is %d.\n", delay); + + srandom (27); // reproducable sequence of "random" values + + for (int nt = 0; nt < NTRIALS; nt++){ + + // load block with random data and encode + + for (i = 0; i < (blocklen-delay); i++) + in[i] = random () & MAXDIBIT; + for ( ; i < blocklen; i++) + in[i] = 0; /* To empty the delay buffers */ + + encoder.reset (); + encode_block (enc, in, blocklen); + + decoder.reset (); + + // decode the block + decode_block (out, enc, blocklen); + + // int offset = delay/4; + int offset = 2; + bool differs = (memcmp (in+offset, + out+delay+offset, blocklen-(delay+offset))); + + // initial values after reset are 0 + for (i = 0; i < delay; i++){ + if (out[i] != 0) + printf (" initial output at %i is %X, not 0\n", + i, out[i]); + } + + if (differs){ + printf (" incorrect data, trial #%d\n", nt); + + printf ("\n Erroneous result dibits:"); + for (int erri = 0; erri < (NN-delay); erri++) { + if (in[erri] != out[erri+delay]) + printf (" %d", erri); + } + printf ("\n In: "); + for (int erri = 0; erri < (NN-delay); erri++) { + printf (" %d", in[erri]); + } + printf ("\n Out: "); + for (int erri = 0; erri < (NN-delay); erri++) { + printf (" %d", out[erri+delay]); + } + printf ("\n Errs:"); + for (int erri = 0; erri < (NN-delay); erri++) { + printf (" %c", (in[erri] != out[erri+delay])? '*': ' '); + } + printf ("\n THIS IS A REAL PROBLEM.\n"); + decoder_errors++; + } + } + + printf (" Summary: %d decoder errors out of %d trials.\n", + decoder_errors, NTRIALS); + + CPPUNIT_ASSERT (decoder_errors == 0); +} + diff --git a/gr-atsc/src/lib/qa_atsci_fake_single_viterbi.h b/gr-atsc/src/lib/qa_atsci_fake_single_viterbi.h new file mode 100644 index 000000000..2161d5d99 --- /dev/null +++ b/gr-atsc/src/lib/qa_atsci_fake_single_viterbi.h @@ -0,0 +1,51 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _QA_ATSC_FAKE_SINGLE_VITERBI_H +#define _QA_ATSC_FAKE_SINGLE_VITERBI_H + +#include <cppunit/extensions/HelperMacros.h> +#include <cppunit/TestCase.h> + +#include <atsci_fake_single_viterbi.h> +#include <atsci_basic_trellis_encoder.h> + +class qa_atsci_fake_single_viterbi : public CppUnit::TestCase { + private: + atsci_fake_single_viterbi decoder; + atsci_basic_trellis_encoder encoder; + + CPPUNIT_TEST_SUITE (qa_atsci_fake_single_viterbi); + CPPUNIT_TEST (t0); + CPPUNIT_TEST_SUITE_END (); + + private: + + void t0 (); + + void encode_block(unsigned char *out, unsigned char *in, unsigned n); + void decode_block(unsigned char *out, unsigned char *in, unsigned n); + float noise (); + +}; + +#endif /* _QA_ATSC_FAKE_SINGLE_VITERBI_H_ */ diff --git a/gr-atsc/src/lib/qa_atsci_fs_correlator.cc b/gr-atsc/src/lib/qa_atsci_fs_correlator.cc new file mode 100644 index 000000000..97d45f5c1 --- /dev/null +++ b/gr-atsc/src/lib/qa_atsci_fs_correlator.cc @@ -0,0 +1,255 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <qa_atsci_fs_correlator.h> +#include <atsci_fs_correlator.h> +#include <create_atsci_fs_correlator.h> +#include <atsci_sync_tag.h> +#include <stdlib.h> +#include <algorithm> +#include <atsci_pnXXX.h> +#include <atsc_types.h> +#include <cppunit/TestAssert.h> +#include <assert.h> +#include <random.h> + + +static float +uniform () +{ + return 2.0 * ((float) random () / RANDOM_MAX - 0.5); // uniformly (-1, 1) +} + + +static float +bin_map (int bit) +{ + return bit ? +5 : -5; +} + +static void +init_field_sync_common (float *p, int mask) + +{ + int i = 0; + + p[i++] = bin_map(1); // data segment sync pulse + p[i++] = bin_map(0); + p[i++] = bin_map(0); + p[i++] = bin_map(1); + + for (int j = 0; j < 511; j++) // PN511 + p[i++] = bin_map(atsc_pn511[j]); + + for (int j = 0; j < 63; j++) // PN63 + p[i++] = bin_map(atsc_pn63[j]); + + for (int j = 0; j < 63; j++) // PN63, toggled on field 2 + p[i++] = bin_map(atsc_pn63[j] ^ mask); + + for (int j = 0; j < 63; j++) // PN63 + p[i++] = bin_map(atsc_pn63[j]); + + p[i++] = bin_map(0); // 24 bits of VSB8 mode identifiera + p[i++] = bin_map(0); + p[i++] = bin_map(0); + p[i++] = bin_map(0); + + p[i++] = bin_map(1); + p[i++] = bin_map(0); + p[i++] = bin_map(1); + p[i++] = bin_map(0); + + p[i++] = bin_map(0); + p[i++] = bin_map(1); + p[i++] = bin_map(0); + p[i++] = bin_map(1); + + p[i++] = bin_map(1); + p[i++] = bin_map(1); + p[i++] = bin_map(1); + p[i++] = bin_map(1); + + p[i++] = bin_map(0); + p[i++] = bin_map(1); + p[i++] = bin_map(0); + p[i++] = bin_map(1); + + p[i++] = bin_map(1); + p[i++] = bin_map(0); + p[i++] = bin_map(1); + p[i++] = bin_map(0); + + + for (int j = 0; j < 92; j++) // 92 more bits + p[i++] = bin_map(atsc_pn63[j % 63]); + + // now copy the last 12 symbols of the previous segment + // bogus pad for this test... + + for (int j = 0; j < 12; j++) + p[i++] = bin_map(j & 1); + + assert (i == ATSC_DATA_SEGMENT_LENGTH); +} + +inline static void +init_field_sync_1 (float *s) +{ + init_field_sync_common (s, 0); +} + +inline static void +init_field_sync_2 (float *s) +{ + init_field_sync_common (s, 1); +} + +static void +cause_errors (float *p, int nerrs1, int nerrs2) +{ + static const int offset1 = 4; // offset to PN 511 + static const int offset2 = 578; // offset to 2nd PN 63 + + for (int i = 0; i < nerrs1; i++){ // flip nerrs1 bits in PN 511 + p[i + offset1] = -p[i + offset1]; + } + + for (int i = 0; i < nerrs2; i++){ // flip nerrs2 bits in PN 63 + p[i + offset2] = -p[i + offset2]; + } +} + + +void +qa_atsci_fs_correlator::setUp () +{ + fsc = create_atsci_fs_correlator (); +} + +void +qa_atsci_fs_correlator::tearDown () +{ + delete fsc; + fsc = 0; +} + + +// check sample fifo + +void +qa_atsci_fs_correlator::t0 () +{ + int delay = fsc->delay (); + int i; + float output_sample, output_tag; + + for (i = 0; i < delay; i++){ + fsc->filter ((float) i, &output_sample, &output_tag); + CPPUNIT_ASSERT_DOUBLES_EQUAL (0.0, output_sample, 1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL (atsc_sync_tag::NORMAL, output_tag, 1e-6); + } + + for (; i < delay + 5000; i++){ + fsc->filter ((float) i, &output_sample, &output_tag); + CPPUNIT_ASSERT_DOUBLES_EQUAL ((float) (i - delay), output_sample, 1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL (atsc_sync_tag::NORMAL, output_tag, 1e-6); + } +} + +void +qa_atsci_fs_correlator::util (int which_field, int nerrs1, int nerrs2) +{ + static const int PAD = 303; + static const int ISIZE = 4096; + int delay = fsc->delay (); + float output_sample, output_tag; + int i; + float input[ISIZE]; + + fsc->reset (); // known starting conditions + + // build input + + for (i = 0; i < PAD; i++) + input[i] = uniform () * 7; + + init_field_sync_common (&input[i], which_field); + cause_errors (&input[i], nerrs1, nerrs2); + i += ATSC_DATA_SEGMENT_LENGTH; + + for (; i < ISIZE; i++) + input[i] = uniform () * 7; + + // run the input and check + + for (i = 0; i < ISIZE; i++){ + fsc->filter (input[i], &output_sample, &output_tag); + if (i == delay + PAD){ // should be field sync + if (which_field == 0) + CPPUNIT_ASSERT_DOUBLES_EQUAL (atsc_sync_tag::START_FIELD_SYNC_1, output_tag, 1e-6); + else + CPPUNIT_ASSERT_DOUBLES_EQUAL (atsc_sync_tag::START_FIELD_SYNC_2, output_tag, 1e-6); + } + else { + CPPUNIT_ASSERT_DOUBLES_EQUAL (atsc_sync_tag::NORMAL, output_tag, 1e-6); + } + } +} + + +void +qa_atsci_fs_correlator::t1 () +{ + util (0, 0, 0); +} + +void +qa_atsci_fs_correlator::t2 () +{ + util (1, 0, 0); +} + +void +qa_atsci_fs_correlator::t3 () +{ + for (int nerrs1 = 0; nerrs1 < 20; nerrs1++){ + for (int nerrs2 = 0; nerrs2 < 5; nerrs2++){ + util (0, nerrs1, nerrs2); + } + } +} + +void +qa_atsci_fs_correlator::t4 () +{ + for (int nerrs1 = 0; nerrs1 < 5; nerrs1++){ + for (int nerrs2 = 0; nerrs2 < 5; nerrs2++){ + util (1, nerrs1, nerrs2); + } + } +} + diff --git a/gr-atsc/src/lib/qa_atsci_fs_correlator.h b/gr-atsc/src/lib/qa_atsci_fs_correlator.h new file mode 100644 index 000000000..a38a5e201 --- /dev/null +++ b/gr-atsc/src/lib/qa_atsci_fs_correlator.h @@ -0,0 +1,58 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ +#ifndef _QA_ATSC_FS_CORRELATOR_H_ +#define _QA_ATSC_FS_CORRELATOR_H_ + +#include <cppunit/extensions/HelperMacros.h> +#include <cppunit/TestCase.h> + +class atsci_fs_correlator; + +class qa_atsci_fs_correlator : public CppUnit::TestCase { +private: + atsci_fs_correlator *fsc; + + public: + + void setUp (); + void tearDown (); + + CPPUNIT_TEST_SUITE (qa_atsci_fs_correlator); + CPPUNIT_TEST (t0); + CPPUNIT_TEST (t1); + CPPUNIT_TEST (t2); + CPPUNIT_TEST (t3); + CPPUNIT_TEST (t4); + CPPUNIT_TEST_SUITE_END (); + + private: + + void util (int which_field, int nerr1, int nerr2); + + void t0 (); + void t1 (); + void t2 (); + void t3 (); + void t4 (); +}; + +#endif /* _QA_ATSC_FS_CORRELATOR_H_ */ diff --git a/gr-atsc/src/lib/qa_atsci_randomizer.cc b/gr-atsc/src/lib/qa_atsci_randomizer.cc new file mode 100644 index 000000000..46b228f0f --- /dev/null +++ b/gr-atsc/src/lib/qa_atsci_randomizer.cc @@ -0,0 +1,144 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include <qa_atsci_randomizer.h> + +#include <cppunit/TestAssert.h> + +static unsigned int expected_initial_states[] = { + 0x018f, + 0xd3db, + 0xbaf1, + 0x8e64, + 0x4732, + 0x2399, + 0xc2d0, + 0x6168 +}; + +static unsigned char expected_initial_values[] = { + 0xc0, + 0x6d, + 0x3f, + 0x99, + 0x38, + 0x6a, + 0x29, + 0x52 +}; + +#define NELEMENTS(ary) ((sizeof (ary)) / sizeof (ary[0])) + +void +qa_atsci_randomizer::t0_compare_output_maps () +{ + for (int i = 0; i < 0x10000; i++){ + unsigned char slow = atsci_randomizer::slow_output_map(i); + unsigned char fast = atsci_randomizer::fast_output_map(i); + CPPUNIT_ASSERT_EQUAL (slow, fast); + } +} + +void +qa_atsci_randomizer::t1_initial_states () +{ + // LFSR should start with expected states + + for (unsigned int i = 0; i < NELEMENTS (expected_initial_values); i++){ + unsigned int got = randomizer.state(); + randomizer.clk (); + CPPUNIT_ASSERT_EQUAL (expected_initial_states[i], got); + } +} + +void +qa_atsci_randomizer::t2_initial_values () +{ + // LFSR should start with expected values + + for (unsigned int i = 0; i < NELEMENTS (expected_initial_values); i++){ + unsigned char got = randomizer.output_and_clk (); + CPPUNIT_ASSERT_EQUAL (expected_initial_values[i], got); + } +} + +void +qa_atsci_randomizer::t3_reset () +{ + // LFSR should start with expected values + + for (unsigned int i = 0; i < NELEMENTS (expected_initial_values); i++){ + unsigned char got = randomizer.output_and_clk (); + CPPUNIT_ASSERT_EQUAL (expected_initial_values[i], got); + } + + randomizer.reset (); // reset LFSR + + // and now should repeat expected values + + for (unsigned int i = 0; i < NELEMENTS (expected_initial_values); i++){ + unsigned char got = randomizer.output_and_clk (); + CPPUNIT_ASSERT_EQUAL (expected_initial_values[i], got); + } +} + +void +qa_atsci_randomizer::t4_high_level () +{ + static const int N = 5; + + atsc_mpeg_packet in[N]; + atsc_mpeg_packet_no_sync middle[N]; + atsc_mpeg_packet out[N]; + + memset (in, 0, sizeof (in)); + memset (middle, 0, sizeof (middle)); + memset (out, 0, sizeof (out)); + + // setup input test data + + int counter = 0xff; + for (int n = 0; n < N; n++){ + in[n].data[0] = MPEG_SYNC_BYTE; + for (int i = 0; i < ATSC_MPEG_DATA_LENGTH; i++) + in[n].data[i + 1] = counter++; + } + + // randomize N packets + + for (int n = 0; n < N; n++) + randomizer.randomize (middle[n], in[n]); + + // reset LFSR and derandomize N packets + + randomizer.reset (); // reset LFSR + + for (int n = 0; n < N; n++) + randomizer.derandomize (out[n], middle[n]); + + // compare packets + + for (int n = 0; n < N; n++){ + CPPUNIT_ASSERT (in[n] == out[n]); + } +} + diff --git a/gr-atsc/src/lib/qa_atsci_randomizer.h b/gr-atsc/src/lib/qa_atsci_randomizer.h new file mode 100644 index 000000000..5a805df8a --- /dev/null +++ b/gr-atsc/src/lib/qa_atsci_randomizer.h @@ -0,0 +1,62 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ +#ifndef _QA_ATSC_RANDOMIZER_H_ +#define _QA_ATSC_RANDOMIZER_H_ + +#include <cppunit/extensions/HelperMacros.h> +#include <cppunit/TestCase.h> + +#include <atsci_randomizer.h> + +class qa_atsci_randomizer : public CppUnit::TestCase { + private: + atsci_randomizer randomizer; + + public: + + void setUp (){ + // nop + } + + void tearDown (){ + // nop + } + + CPPUNIT_TEST_SUITE (qa_atsci_randomizer); + CPPUNIT_TEST (t0_compare_output_maps); + CPPUNIT_TEST (t1_initial_states); + CPPUNIT_TEST (t2_initial_values); + CPPUNIT_TEST (t3_reset); + CPPUNIT_TEST (t4_high_level); + CPPUNIT_TEST_SUITE_END (); + + + private: + void t0_compare_output_maps (); + void t1_initial_states (); + void t2_initial_values (); + void t3_reset (); + void t4_high_level (); + +}; + +#endif /* _QA_ATSC_RANDOMIZER_H_ */ diff --git a/gr-atsc/src/lib/qa_atsci_reed_solomon.cc b/gr-atsc/src/lib/qa_atsci_reed_solomon.cc new file mode 100644 index 000000000..8b52359e2 --- /dev/null +++ b/gr-atsc/src/lib/qa_atsci_reed_solomon.cc @@ -0,0 +1,114 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <cppunit/TestAssert.h> +#include <stdlib.h> +#include <stdio.h> +#include <atsci_reed_solomon.h> +#include <qa_atsci_reed_solomon.h> + + +static const int NROOTS = 20; +static const int NTRIALS = 100; +static const int NN = ATSC_MPEG_RS_ENCODED_LENGTH; + +void +qa_atsci_reed_solomon::t0_reed_solomon () +{ + atsc_mpeg_packet_no_sync in; + atsc_mpeg_packet_rs_encoded enc; + atsc_mpeg_packet_no_sync out; + int derrors; + int errlocs[NN]; + int errval; + int errloc; + int decoder_errors = 0; + + for (int nt = 0; nt < NTRIALS; nt++){ + + // test up to the error correction capacity of the code + for (int errors = 0; errors <= NROOTS*2; errors++){ + + // load block with random data and encode + + for (int i = 0; i < ATSC_MPEG_DATA_LENGTH; i++) + in.data[i] = random () & 0xff; + + rs.encode (enc, in); + + memset (errlocs, 0, sizeof (errlocs)); + + for (int i = 0; i < errors; i++){ + + do { + errval = random () & 0xff; + } while (errval == 0); // error value must be non-zero + + do { + errloc = random () % NN; + } while (errlocs[errloc] != 0); // must not choose the same location twice + + errlocs[errloc] = 1; + + enc.data[errloc] ^= errval; // cause the error + } + + // decode the errored block + derrors = rs.decode (out, enc); + + if (errors <= NROOTS/2) { + // We should have handled all these errors and corrected them. + if (derrors != errors){ + fprintf (stderr, " decoder says %d errors, true number is %d\n", derrors, errors); + decoder_errors++; + } + + if (in != out){ + fprintf (stderr, " uncorrected errors!\n"); + decoder_errors++; + } + } else { + // We have been given more errors than we could cope with. Make + // sure that we detect these errors. Complain if we get incorrect + // block but don't say it's incorrect. + bool differs = (in != out); + + if (differs && (derrors < 0)) { + // Reported uncorrectable error accurately + } else if (differs) { + fprintf (stderr, + " decoder found %d of %d errors, but incorrect block\n", + derrors, errors); + } else { + fprintf (stderr, " decoder corrected %d of %d errors unexpectedly\n", + derrors, errors); + } + } + } + } + + CPPUNIT_ASSERT (decoder_errors == 0); +} diff --git a/gr-atsc/src/lib/qa_atsci_reed_solomon.h b/gr-atsc/src/lib/qa_atsci_reed_solomon.h new file mode 100644 index 000000000..d78aa7474 --- /dev/null +++ b/gr-atsc/src/lib/qa_atsci_reed_solomon.h @@ -0,0 +1,43 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _QA_ATSC_REED_SOLOMON_H_ +#define _QA_ATSC_REED_SOLOMON_H_ + +#include <cppunit/extensions/HelperMacros.h> +#include <cppunit/TestCase.h> + +#include <atsci_reed_solomon.h> + +class qa_atsci_reed_solomon : public CppUnit::TestCase { + + CPPUNIT_TEST_SUITE (qa_atsci_reed_solomon); + CPPUNIT_TEST (t0_reed_solomon); + CPPUNIT_TEST_SUITE_END (); + + private: + atsci_reed_solomon rs; + + void t0_reed_solomon (); +}; + +#endif /* _QA_ATSC_REED_SOLOMON_H_ */ diff --git a/gr-atsc/src/lib/qa_atsci_single_viterbi.cc b/gr-atsc/src/lib/qa_atsci_single_viterbi.cc new file mode 100644 index 000000000..ea94e6939 --- /dev/null +++ b/gr-atsc/src/lib/qa_atsci_single_viterbi.cc @@ -0,0 +1,283 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <cppunit/TestAssert.h> +#include <stdlib.h> +#include <stdio.h> +#include <atsci_single_viterbi.h> +#include <qa_atsci_single_viterbi.h> +#include <random.h> + + +static const int NTRIALS = 50; +static const int MAXERRORS = 10; +static const int NN = 200; + +static const int MAXDIBIT = 3; + +void +qa_atsci_single_viterbi::encode_block (unsigned char *out, unsigned char *in, + unsigned int n) +{ + for (unsigned int i = 0; i < n; i++) { + out[i] = encoder.encode(in[i]); + } +} + + +void +qa_atsci_single_viterbi::decode_block (unsigned char *out, unsigned char *in, + unsigned int n, float noise_factor) +{ + for (unsigned int i = 0; i < n; i++) { + out[i] = decoder.decode((2*in[i]-7) + noise () * noise_factor); + } +} + +float +qa_atsci_single_viterbi::noise () +{ + return 2.0 * ((float) random () / RANDOM_MAX - 0.5); // uniformly (-1, 1) +} + +void +qa_atsci_single_viterbi::t0 () +{ + int blocklen = NN; + unsigned char in[blocklen]; + unsigned char enc[blocklen]; + unsigned char out[blocklen]; + int decoder_errors = 0; + int delay = decoder.delay (); + int i; + + // printf (" Delay is %d.\n", delay); + + srandom (27); // reproducable sequence of "random" values + + for (int nt = 0; nt < NTRIALS; nt++){ + + // load block with random data and encode + + for (i = 0; i < (blocklen-delay); i++) + in[i] = random () & MAXDIBIT; + for ( ; i < blocklen; i++) + in[i] = 0; /* To empty the delay buffers */ + + encoder.reset (); + encode_block (enc, in, blocklen); + + decoder.reset (); + + // decode the block + decode_block (out, enc, blocklen, 1.0); + + // int offset = delay/4; + int offset = 2; + bool differs = (memcmp (in+offset, + out+delay+offset, blocklen-(delay+offset))); + + // initial values after reset are 0 + for (i = 0; i < delay; i++){ + if (out[i] != 0) + printf (" initial output at %i is %X, not 0\n", + i, out[i]); + } + + if (differs){ + printf (" incorrect data\n"); + + printf ("\n Erroneous result dibits:"); + for (int erri = 0; erri < (NN-delay); erri++) { + if (in[erri] != out[erri+delay]) + printf (" %d", erri); + } + printf ("\n In: "); + for (int erri = 0; erri < (NN-delay); erri++) { + printf (" %d", in[erri]); + } + printf ("\n Out: "); + for (int erri = 0; erri < (NN-delay); erri++) { + printf (" %d", out[erri+delay]); + } + printf ("\n Errs:"); + for (int erri = 0; erri < (NN-delay); erri++) { + printf (" %c", (in[erri] != out[erri+delay])? '*': ' '); + } + printf ("\n THIS IS A REAL PROBLEM.\n"); + decoder_errors++; + } + } + + printf (" Summary: %d decoder errors out of %d trials.\n", + decoder_errors, NTRIALS); + + CPPUNIT_ASSERT (decoder_errors == 0); +} + +void +qa_atsci_single_viterbi::t1 () +{ + int blocklen = NN; + unsigned char in[blocklen]; + unsigned char enc[blocklen]; + unsigned char out[blocklen]; + int errlocs[NN]; + int errval; + int errloc; + int decoder_errors = 0; + int delay = decoder.delay (); + int i; + + // printf (" Delay is %d.\n", delay); + + srandom (1); // reproducable sequence of "random" values + + for (int nt = 0; nt < NTRIALS; nt++){ + + // test up to the error correction capacity of the code + for (int errors = 0; errors <= MAXERRORS; errors++){ + + // load block with random data and encode + + for (i = 0; i < (blocklen-delay); i++) + in[i] = random () & MAXDIBIT; + for ( ; i < blocklen; i++) + in[i] = 0; /* To empty the delay buffers */ + + encoder.reset (); + encode_block (enc, in, blocklen); + + // Now generate 0 to N errors in the encoded symbols. + // + // If we restrict ourselves to damaging the low-order bit, + // our decoder finds and fixes the vast majority of errors. + // + // If we munge any or all of the three bits of the symbol, + // our decoder frequently gets the wrong data even with a single + // error. + // + // Let's see what it can do with just the two low-order bits. + // + // ALSO: Don't let any error be within 12 spots of another + // error. This simulates the muxed behavior. + + memset (errlocs, 0, sizeof (errlocs)); + + for (int j = 0; j < errors; j++){ + + do { + // errval = random () & 3; // FIXME: 1; // FIXME: MAXSYM; + errval = random () & 1; // FIXME: 1; // FIXME: MAXSYM; + } while (errval == 0); // error value must be non-zero + + // Don't insert errors in the first delay slot, since we + // don't have valid history to correct them. Also, don't + // insert burst errors (adjacent errors), or errors within 2, + // since we can't reliably correct them. Also we must not choose + // the same location twice when inserting an error. + + do { + errloc = random () % NN; + } while (errloc < delay || errlocs[errloc] != 0 + || (errloc > 0 && errlocs[errloc-1] != 0) + || (errloc > 1 && errlocs[errloc-2] != 0) + || (errloc < (NN-1) && errlocs[errloc+1] != 0) + || (errloc < (NN-2) && errlocs[errloc+2] != 0)); + + errlocs[errloc] = 1; + + enc[errloc] ^= errval; // cause the error + } + + // decode the errored block + decoder.reset (); + decode_block (out, enc, blocklen, 0.5); + + // int offset = delay/4; + int offset = 2; + bool differs = (memcmp (in+offset, + out+delay+offset, blocklen-(delay+offset))); + + // initial values after reset are 0 + for (i = 0; i < delay; i++){ + if (out[i] != 0) + printf (" initial output at %i is %X, not 0\n", + i, out[i]); + } + + if (differs){ + printf (" %2d errors introduced, %scorrect data\n", + errors, differs? "in": ""); + + // FIXME, should we be able to tell how many errs too? + if (differs) { + const int ERRTOL = 12; /* Or relate to delay? */ + int shouldfix = 1; + int lasti = -ERRTOL; + + printf ( " Inserted errors: "); + for (int erri = 0; erri < NN; erri++) { + if (errlocs[erri]) { + printf (" %d", erri); + // if (erri < lasti+ERRTOL) + // shouldfix = 0; + lasti = erri; + } + } + printf ("\n Erroneous result dibits:"); + for (int erri = 0; erri < (NN-delay); erri++) { + if (in[erri] != out[erri+delay]) + printf (" %d", erri); + } + printf ("\n In: "); + for (int erri = 0; erri < (NN-delay); erri++) { + printf (" %d", in[erri]); + } + printf ("\n Out: "); + for (int erri = 0; erri < (NN-delay); erri++) { + printf (" %d", out[erri+delay]); + } + printf ("\n Errs:"); + for (int erri = 0; erri < (NN-delay); erri++) { + printf (" %c", (in[erri] != out[erri+delay])? '*': ' '); + } + if (shouldfix) + printf ("\n THIS IS A REAL PROBLEM.\n"); + else + printf ("\n BUT THAT'S OK since errors are too close.\n"); + if (shouldfix) + decoder_errors++; + } + } + } + } + + printf (" Summary: %d decoder errors out of %d trials.\n", + decoder_errors, (MAXERRORS*NTRIALS)); + + CPPUNIT_ASSERT (decoder_errors <= (MAXERRORS*NTRIALS) * .1); +} diff --git a/gr-atsc/src/lib/qa_atsci_single_viterbi.h b/gr-atsc/src/lib/qa_atsci_single_viterbi.h new file mode 100644 index 000000000..0c0a3349a --- /dev/null +++ b/gr-atsc/src/lib/qa_atsci_single_viterbi.h @@ -0,0 +1,53 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _QA_ATSC_SINGLE_VITERBI_H +#define _QA_ATSC_SINGLE_VITERBI_H + +#include <cppunit/extensions/HelperMacros.h> +#include <cppunit/TestCase.h> + +#include <atsci_single_viterbi.h> +#include <atsci_basic_trellis_encoder.h> + +class qa_atsci_single_viterbi : public CppUnit::TestCase { + private: + atsci_single_viterbi decoder; + atsci_basic_trellis_encoder encoder; + + CPPUNIT_TEST_SUITE (qa_atsci_single_viterbi); + CPPUNIT_TEST (t0); + CPPUNIT_TEST (t1); + CPPUNIT_TEST_SUITE_END (); + + private: + + void t0 (); + void t1 (); + + void encode_block(unsigned char *out, unsigned char *in, unsigned n); + void decode_block(unsigned char *out, unsigned char *in, unsigned n, float noise_factor); + float noise (); + +}; + +#endif /* _QA_ATSC_SINGLE_VITERBI_H_ */ diff --git a/gr-atsc/src/lib/qa_atsci_sliding_correlator.cc b/gr-atsc/src/lib/qa_atsci_sliding_correlator.cc new file mode 100644 index 000000000..e31584717 --- /dev/null +++ b/gr-atsc/src/lib/qa_atsci_sliding_correlator.cc @@ -0,0 +1,51 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include <cppunit/TestAssert.h> +#include <qa_atsci_sliding_correlator.h> +#include <cstdio> + +void +qa_atsci_sliding_correlator::t0 () +{ + +#if 0 + int count = 0; + int i; + for (i = 0; i < 100; i++) + printf ("%6d: %3d\n", count++, corr.input_bit (i & 1)); + + for (i = 0; i < 511; i++) + printf ("%6d: %3d\n", count++, corr.input_bit (atsc_pn511[i])); + + for (i = 0; i < 100; i++) + printf ("%6d: %3d\n", count++, corr.input_bit ((i & 2) != 0)); + + for (i = 0; i < 511; i++) + printf ("%6d: %3d\n", count++, corr.input_bit (atsc_pn511[i] ^ 1)); + + for (i = 0; i < 100; i++) + printf ("%6d: %3d\n", count++, + corr.input_bit (atsc_pn511[i] ^ atsc_pn511[i+31])); +#endif + +} diff --git a/gr-atsc/src/lib/qa_atsci_sliding_correlator.h b/gr-atsc/src/lib/qa_atsci_sliding_correlator.h new file mode 100644 index 000000000..508020c25 --- /dev/null +++ b/gr-atsc/src/lib/qa_atsci_sliding_correlator.h @@ -0,0 +1,52 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _QA_ATSC_SLIDING_CORRELATOR_H_ +#define _QA_ATSC_SLIDING_CORRELATOR_H_ + +#include <cppunit/extensions/HelperMacros.h> +#include <cppunit/TestCase.h> +#include <stdio.h> + +#include <atsci_sliding_correlator.h> + +class qa_atsci_sliding_correlator : public CppUnit::TestCase { + + public: + + void setUp (void) + { + corr.reset (); + } + + CPPUNIT_TEST_SUITE (qa_atsci_sliding_correlator); + CPPUNIT_TEST (t0); + CPPUNIT_TEST_SUITE_END (); + + private: + atsci_sliding_correlator corr; + + void t0 (); +}; + + +#endif /* _QA_ATSC_SLIDING_CORRELATOR_H_ */ diff --git a/gr-atsc/src/lib/qa_atsci_trellis_encoder.cc b/gr-atsc/src/lib/qa_atsci_trellis_encoder.cc new file mode 100644 index 000000000..193f2b310 --- /dev/null +++ b/gr-atsc/src/lib/qa_atsci_trellis_encoder.cc @@ -0,0 +1,115 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <cppunit/TestAssert.h> +#include <qa_atsci_trellis_encoder.h> +#include <cstdio> +#include <string.h> +#include <stdlib.h> +#include <time.h> + +#define NELEM(x) (sizeof (x) / sizeof (x[0])) + + +static const int NCODERS = atsci_trellis_encoder::NCODERS; + +void +qa_atsci_trellis_encoder::t0 () +{ +#if 0 // generate i/o test data for t1 + + atsc_mpeg_packet_rs_encoded in[NCODERS]; + atsc_data_segment out[NCODERS]; + + + memset (in, 0, sizeof (in)); + memset (out, 0, sizeof (out)); + + srandom (1); + + printf ("@@@ INPUT @@@\n"); + for (int i = 0; i < NCODERS; i++){ + for (unsigned int j = 0; j < NELEM (in[i].data); j++){ + int t = (random () >> 8) & 0xff; // 8 random bits + in[i].data[j] = t; + printf ("%d\n", t); + } + } + + enc.reset (); + enc.encode (out, in); + + printf ("@@@ OUTPUT @@@\n"); + for (int i = 0; i < NCODERS; i++){ + for (unsigned int j = 0; j < NELEM (out[i].data); j++){ + printf ("%d\n", out[i].data[j]); + } + } +#endif +} + +void +qa_atsci_trellis_encoder::t1 () +{ + atsc_mpeg_packet_rs_encoded in[NCODERS]; + atsc_data_segment expected_out[NCODERS]; + atsc_data_segment actual_out[NCODERS]; + static const unsigned char raw_input[NCODERS * NELEM (in[0].data)] = { +#include "qa_atsci_trellis_encoder_t1_input.dat" + }; + static const unsigned char raw_output[NCODERS * NELEM (expected_out[0].data)] = { +#include "qa_atsci_trellis_encoder_t1_output.dat" + }; + + + // load up input + const unsigned char *r = &raw_input[0]; + for (int i = 0; i < NCODERS; i++){ + in[i].pli.set_regular_seg (false, i); + for (unsigned int j = 0; j < NELEM (in[i].data); j++){ + in[i].data[j] = *r++; + } + } + + // load up expected output + r = &raw_output[0]; + for (int i = 0; i < NCODERS; i++){ + expected_out[i].pli.set_regular_seg (false, i); + for (unsigned int j = 0; j < NELEM (expected_out[i].data); j++){ + expected_out[i].data[j] = *r++; + } + } + + memset (&actual_out, 0, sizeof (actual_out)); // ensure zero + + enc.reset (); + enc.encode (actual_out, in); // trellis code test data + + for (int i = 0; i < NCODERS; i++){ // check the result + CPPUNIT_ASSERT (expected_out[i] == actual_out[i]); + CPPUNIT_ASSERT (expected_out[i].pli == actual_out[i].pli); + } +} diff --git a/gr-atsc/src/lib/qa_atsci_trellis_encoder.h b/gr-atsc/src/lib/qa_atsci_trellis_encoder.h new file mode 100644 index 000000000..40657169a --- /dev/null +++ b/gr-atsc/src/lib/qa_atsci_trellis_encoder.h @@ -0,0 +1,54 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _QA_ATSC_TRELLIS_ENCODER_H_ +#define _QA_ATSC_TRELLIS_ENCODER_H_ + +#include <cppunit/extensions/HelperMacros.h> +#include <cppunit/TestCase.h> +#include <stdio.h> + +#include <atsci_trellis_encoder.h> + +class qa_atsci_trellis_encoder : public CppUnit::TestCase { + + public: + + void setUp (void) + { + enc.reset (); + } + + CPPUNIT_TEST_SUITE (qa_atsci_trellis_encoder); + CPPUNIT_TEST (t0); + CPPUNIT_TEST (t1); + CPPUNIT_TEST_SUITE_END (); + + private: + atsci_trellis_encoder enc; + + void t0 (); + void t1 (); +}; + + +#endif /* _QA_ATSC_TRELLIS_ENCODER_H_ */ diff --git a/gr-atsc/src/lib/qa_atsci_trellis_encoder_t1_input.dat b/gr-atsc/src/lib/qa_atsci_trellis_encoder_t1_input.dat new file mode 100644 index 000000000..e6109ddfc --- /dev/null +++ b/gr-atsc/src/lib/qa_atsci_trellis_encoder_t1_input.dat @@ -0,0 +1,2484 @@ +69, +35, +152, +72, +220, +92, +148, +88, +31, +124, +88, +215, +65, +30, +169, +225, +0, +98, +8, +39, +35, +233, +205, +67, +15, +37, +249, +114, +194, +215, +196, +7, +251, +93, +80, +215, +186, +228, +48, +217, +97, +137, +177, +163, +168, +90, +132, +168, +189, +140, +208, +224, +118, +158, +36, +134, +196, +29, +248, +134, +245, +189, +141, +240, +26, +221, +200, +212, +194, +248, +173, +35, +130, +95, +198, +42, +185, +74, +211, +119, +215, +164, +88, +78, +66, +124, +212, +6, +154, +204, +141, +143, +137, +27, +127, +164, +249, +72, +120, +187, +64, +38, +222, +195, +133, +165, +237, +63, +240, +193, +183, +199, +101, +15, +21, +168, +140, +233, +175, +38, +182, +60, +182, +64, +87, +53, +228, +80, +126, +93, +11, +191, +132, +234, +130, +10, +143, +112, +74, +127, +49, +2, +71, +150, +18, +93, +63, +158, +71, +238, +197, +253, +43, +123, +62, +130, +177, +35, +211, +47, +129, +223, +238, +6, +202, +112, +17, +89, +224, +91, +217, +17, +94, +33, +168, +112, +126, +231, +14, +197, +214, +212, +195, +1, +79, +1, +132, +1, +36, +87, +48, +165, +55, +30, +172, +1, +143, +189, +90, +112, +24, +52, +130, +119, +85, +42, +231, +211, +18, +246, +153, +232, +202, +92, +234, +26, +93, +110, +27, +130, +197, +75, +40, +253, +106, +212, +254, +250, +145, +89, +106, +170, +141, +236, +33, +227, +23, +9, +183, +41, +255, +80, +18, +201, +172, +252, +227, +10, +107, +255, +141, +49, +74, +181, +46, +181, +138, +44, +175, +27, +133, +26, +198, +19, +6, +232, +246, +29, +241, +174, +71, +240, +254, +90, +185, +171, +87, +157, +182, +194, +157, +67, +243, +232, +248, +34, +157, +130, +78, +77, +158, +212, +103, +100, +231, +110, +76, +222, +140, +61, +140, +211, +46, +138, +46, +232, +54, +133, +133, +236, +72, +35, +47, +59, +11, +40, +94, +168, +171, +172, +246, +74, +128, +93, +174, +104, +204, +251, +70, +88, +57, +210, +44, +103, +93, +90, +79, +148, +223, +213, +129, +39, +248, +177, +99, +4, +217, +193, +172, +133, +110, +162, +207, +239, +0, +126, +87, +205, +121, +158, +37, +179, +113, +81, +27, +207, +171, +107, +99, +139, +65, +228, +178, +58, +149, +22, +62, +111, +216, +234, +244, +70, +141, +195, +54, +142, +66, +141, +91, +187, +44, +129, +111, +157, +210, +138, +108, +126, +245, +208, +9, +55, +180, +188, +113, +74, +211, +175, +185, +171, +154, +174, +242, +40, +114, +40, +183, +180, +182, +19, +112, +226, +148, +223, +128, +103, +106, +237, +229, +96, +189, +239, +151, +114, +172, +8, +189, +127, +184, +118, +43, +83, +37, +29, +123, +151, +70, +50, +76, +252, +69, +188, +223, +218, +156, +96, +65, +6, +77, +39, +102, +11, +23, +254, +125, +195, +7, +59, +67, +191, +178, +111, +18, +215, +141, +142, +111, +211, +192, +187, +208, +6, +119, +176, +225, +19, +16, +34, +26, +94, +74, +128, +105, +97, +127, +231, +37, +134, +35, +104, +69, +213, +215, +88, +172, +101, +230, +27, +56, +167, +214, +9, +174, +78, +185, +143, +98, +202, +178, +124, +40, +253, +253, +146, +94, +124, +122, +131, +2, +157, +236, +72, +114, +196, +161, +31, +41, +136, +58, +98, +47, +17, +107, +222, +96, +37, +110, +194, +239, +32, +63, +24, +29, +60, +170, +124, +185, +37, +0, +188, +195, +237, +4, +53, +178, +165, +84, +219, +45, +143, +62, +93, +161, +169, +60, +1, +206, +170, +196, +190, +203, +4, +214, +232, +65, +129, +101, +250, +166, +102, +182, +105, +83, +186, +159, +5, +96, +244, +225, +142, +132, +31, +236, +37, +201, +40, +39, +152, +210, +236, +86, +157, +240, +44, +134, +49, +173, +235, +44, +83, +81, +226, +189, +165, +157, +93, +170, +254, +81, +140, +141, +213, +171, +121, +251, +117, +161, +35, +13, +116, +16, +99, +17, +0, +144, +152, +50, +61, +132, +95, +145, +214, +66, +79, +123, +223, +172, +38, +222, +254, +178, +107, +211, +94, +229, +207, +212, +134, +242, +225, +251, +2, +69, +12, +3, +214, +164, +54, +20, +40, +149, +165, +254, +215, +245, +122, +183, +162, +160, +150, +160, +83, +1, +116, +177, +230, +67, +133, +109, +54, +103, +104, +56, +173, +117, +60, +131, +26, +115, +151, +67, +9, +61, +65, +224, +50, +188, +152, +212, +92, +46, +116, +175, +48, +232, +97, +23, +44, +231, +132, +98, +78, +237, +155, +251, +98, +215, +126, +124, +74, +22, +191, +83, +83, +1, +52, +133, +189, +205, +90, +26, +252, +207, +202, +45, +183, +43, +68, +228, +19, +201, +70, +98, +182, +225, +93, +25, +185, +220, +150, +4, +243, +86, +88, +70, +88, +141, +203, +21, +90, +38, +48, +87, +245, +250, +132, +173, +38, +200, +145, +57, +145, +215, +156, +72, +185, +250, +98, +114, +215, +248, +119, +202, +78, +207, +16, +166, +92, +220, +188, +183, +2, +237, +14, +247, +231, +146, +164, +14, +91, +53, +72, +237, +13, +228, +53, +199, +222, +151, +57, +181, +144, +177, +127, +222, +128, +143, +133, +220, +107, +66, +147, +109, +47, +162, +101, +23, +52, +9, +37, +143, +63, +110, +125, +77, +82, +179, +20, +49, +75, +78, +230, +219, +255, +102, +186, +127, +246, +64, +92, +98, +130, +240, +208, +177, +146, +53, +200, +198, +63, +238, +86, +127, +92, +212, +204, +175, +135, +224, +224, +210, +47, +199, +173, +46, +45, +104, +174, +36, +168, +10, +134, +42, +250, +86, +220, +141, +139, +165, +83, +203, +148, +170, +74, +241, +126, +22, +160, +6, +247, +128, +216, +38, +72, +134, +85, +117, +238, +3, +153, +151, +13, +32, +194, +8, +118, +158, +149, +2, +68, +233, +205, +217, +148, +23, +202, +19, +46, +106, +25, +38, +235, +241, +76, +51, +120, +162, +169, +103, +165, +66, +254, +179, +98, +192, +188, +217, +95, +82, +219, +164, +59, +169, +125, +208, +193, +71, +227, +239, +177, +252, +22, +157, +238, +98, +208, +102, +5, +121, +206, +170, +188, +204, +94, +31, +141, +26, +248, +237, +108, +212, +146, +168, +125, +15, +120, +62, +87, +91, +46, +9, +88, +68, +166, +70, +167, +118, +173, +172, +240, +124, +87, +172, +72, +181, +203, +214, +207, +196, +196, +59, +152, +86, +228, +21, +102, +92, +84, +190, +183, +131, +199, +16, +199, +110, +86, +110, +229, +4, +27, +213, +128, +114, +129, +201, +39, +77, +160, +247, +17, +100, +51, +169, +187, +23, +191, +33, +115, +20, +223, +43, +151, +167, +59, +94, +21, +146, +205, +251, +150, +233, +208, +23, +91, +82, +224, +131, +159, +129, +122, +177, +229, +173, +91, +160, +196, +27, +194, +56, +47, +162, +99, +198, +74, +159, +37, +95, +49, +243, +91, +200, +220, +43, +223, +55, +126, +192, +187, +29, +65, +53, +207, +39, +226, +42, +200, +167, +69, +138, +223, +116, +45, +67, +59, +119, +226, +97, +215, +20, +84, +50, +221, +48, +94, +188, +104, +220, +125, +35, +249, +191, +89, +200, +230, +60, +243, +175, +227, +56, +57, +195, +173, +103, +7, +233, +222, +234, +74, +181, +254, +158, +232, +219, +207, +70, +152, +56, +34, +22, +92, +28, +213, +181, +229, +188, +241, +216, +107, +213, +17, +165, +153, +190, +12, +160, +167, +235, +139, +242, +161, +138, +144, +137, +101, +96, +208, +254, +152, +242, +20, +244, +14, +234, +170, +243, +167, +155, +204, +19, +113, +221, +184, +11, +156, +197, +171, +68, +177, +55, +54, +82, +193, +199, +220, +39, +39, +172, +37, +192, +158, +58, +180, +173, +37, +94, +161, +204, +250, +109, +224, +108, +75, +153, +119, +232, +94, +35, +45, +15, +90, +99, +98, +27, +43, +62, +66, +83, +234, +104, +20, +137, +162, +201, +54, +200, +39, +215, +149, +34, +69, +117, +142, +144, +14, +6, +121, +109, +41, +166, +125, +131, +10, +223, +159, +53, +29, +225, +137, +8, +74, +157, +145, +237, +102, +200, +181, +142, +159, +74, +177, +229, +192, +64, +118, +207, +70, +239, +60, +111, +149, +185, +243, +160, +153, +146, +214, +182, +116, +95, +191, +190, +253, +80, +171, +99, +25, +97, +242, +185, +172, +163, +158, +108, +228, +20, +59, +42, +4, +120, +154, +154, +49, +141, +58, +202, +32, +16, +129, +149, +112, +65, +83, +109, +146, +255, +209, +171, +96, +196, +100, +13, +103, +2, +121, +76, +23, +181, +118, +28, +45, +17, +183, +95, +158, +241, +42, +191, +2, +172, +84, +115, +237, +168, +224, +127, +168, +178, +42, +8, +118, +142, +22, +222, +145, +143, +42, +169, +69, +160, +197, +114, +177, +124, +210, +80, +110, +252, +16, +113, +168, +101, +228, +149, +13, +197, +20, +181, +119, +63, +190, +237, +206, +212, +203, +95, +100, +245, +9, +169, +150, +207, +28, +72, +76, +238, +153, +186, +234, +169, +44, +146, +14, +17, +40, +28, +214, +61, +209, +77, +125, +144, +59, +75, +100, +6, +171, +200, +252, +180, +114, +147, +131, +142, +219, +207, +124, +117, +138, +102, +31, +183, +249, +45, +200, +34, +74, +158, +96, +27, +236, +221, +172, +39, +40, +16, +46, +212, +217, +43, +136, +75, +190, +11, +217, +154, +219, +85, +15, +102, +188, +46, +29, +182, +92, +229, +217, +166, +131, +57, +194, +112, +22, +110, +151, +63, +127, +197, +19, +88, +241, +156, +163, +175, +168, +125, +73, +131, +211, +88, +233, +143, +135, +7, +70, +227, +236, +31, +138, +112, +88, +77, +224, +111, +187, +120, +174, +59, +62, +194, +147, +47, +94, +55, +222, +6, +180, +40, +138, +135, +129, +116, +23, +8, +123, +93, +236, +103, +125, +118, +216, +213, +195, +184, +69, +127, +49, +244, +187, +111, +182, +78, +158, +21, +134, +125, +27, +59, +165, +165, +195, +38, +25, +218, +47, +149, +56, +27, +252, +181, +146, +213, +139, +86, +142, +208, +213, +191, +196, +145, +46, +123, +223, +205, +144, +102, +75, +171, +161, +240, +81, +101, +23, +107, +64, +70, +0, +120, +98, +253, +46, +244, +210, +185, +74, +96, +138, +32, +32, +78, +177, +79, +201, +145, +28, +89, +248, +103, +5, +154, +88, +87, +255, +112, +195, +63, +183, +196, +184, +25, +193, +230, +14, +148, +160, +89, +245, +42, +122, +21, +121, +43, +100, +67, +189, +129, +157, +182, +233, +162, +80, +65, +250, +80, +178, +190, +143, +105, +130, +72, +131, +67, +47, +145, +216, +208, +235, +205, +251, +101, +227, +116, +145, +71, +183, +78, +201, +84, +4, +178, +247, +85, +244, +242, +165, +166, +176, +53, +16, +50, +126, +147, +118, +173, +37, +78, +125, +16, +28, +120, +117, +0, +237, +6, +71, +164, +85, +17, +249, +90, +195, +240, +175, +184, +227, +85, +94, +147, +138, +110, +197, +8, +2, +60, +182, +39, +139, +51, +55, +167, +172, +173, +167, +153, +179, +239, +62, +9, +1, +55, +99, +196, +40, +19, +124, +12, +104, +219, +159, +243, +74, +101, +251, +76, +161, +178, +115, +44, +230, +171, +212, +146, +88, +124, +44, +12, +108, +107, +21, +109, +163, +121, +50, +204, +140, +175, +216, +244, +138, +119, +232, +213, +221, +228, +33, +127, +150, +149, +172, +124, +64, +129, +15, +153, +253, +59, +166, +105, +167, +187, +215, +74, +53, +9, +22, +193, +184, +238, +182, +67, +102, +158, +24, +68, +130, +58, +195, +24, +207, +111, +149, +16, +240, +164, +170, +238, +224, +80, +88, +135, +12, +47, +209, +65, +57, +232, +2, +242, +215, +185, +53, +62, +87, +78, +130, +218, +136, +69, +243, +87, +181, +136, +104, +166, +44, +18, +148, +13, +99, +237, +148, +111, +28, +102, +176, +86, +79, +179, +72, +38, +109, +125, +100, +197, +203, +231, +159, +83, +44, +146, +171, +226, +27, +20, +137, +72, +39, +29, +85, +138, +10, +234, +249, +39, +81, +170, +125, +160, +94, +197, +198, +203, +67, +43, +145, +15, +18, +48, +98, +63, +195, +14, +34, +222, +35, +171, +39, +74, +201, +125, +212, +212, +103, +206, +251, +185, +121, +121, +89, +215, +63, +32, +163, +130, +75, +52, +145, +94, +101, +244, +158, +40, +3, +192, +7, +38, +107, +47, +113, +52, +172, +69, +8, +20, +20, +4, +205, +141, +126, +38, +101, +189, +71, +9, +64, +147, +62, +210, +241, +163, +198, +143, +204, +202, +80, +212, +241, +187, +4, +98, +240, +176, +168, +249, +197, +188, +254, +146, +73, +124, +185, +175, +57, +1, +184, +122, +148, +246, +76, +134, +154, +19, +21, +102, +222, +102, +59, +207, +33, +63, +49, +18, +240, +218, +11, +181, +150, +9, +72, +224, +134, +2, +143, +192, +3, +71, +58, +151, +62, +135, +29, +216, +154, +51, +63, +120, +153, +123, +72, +187, +187, +122, +206, +171, +84, +218, +97, +234, +228, +169, +203, +106, +172, +90, +42, +175, +162, +101, +71, +224, +236, +101, +185, +135, +153, +248, +0, +51, +116, +72, +238, +47, +194, +189, +218, +22, +151, +60, +1, +123, +230, +204, +230, +146, +38, +17, +66, +200, +118, +137, +169, +99, +239, +98, +234, +136, +91, +234, +187, +208, +51, +170, +255, +245, +103, +218, +11, +255, +22, +12, +123, +252, +217, +97, +142, +255, +115, +208, +200, +234, +90, +114, +77, +73, +212, +56, +209, +48, +35, +141, +0, +86, +55, +0, +75, +159, +218, +87, +159, +240, +100, +26, +237, +61, +124, +124, +61, +239, +77, +6, +218, +167, +120, +39, +241, +77, +96, +195, +125, +132, +80, +126, +218, +136, +126, +38, +40, +88, +126, +199, +73, +226, +225, +55, +32, +94, +179, +94, +78, +1, +100, +40, +168, +220, +80, +154, +41, +177, +93, +167, +53, +173, +37, +16, +54, +164, +55, +94, +253, +181, +37, +70, +152, +7, +126, +184, +102, +50, +22, +180, +51, +123, +221, +220, +87, +46, +118, +129, +223, +211, +41, +20, +129, +78, +37, +183, +243, +92, +21, +240, +17, +59, +55, +169, +67, +181, +98, +170, +231, +121, +94, +27, +244, +60, +247, +76, +106, +109, +206, +73, +64, +247, +94, +193, +70, +131, +121, +57, +223, +143, +41, +241, +203, +97, +155, +14, +23, +253, +184, +255, +119, +23, +26, +108, +83, +17, +184, +190, +127, +135, +7, +191, +126, +102, +129, +196, +233, +251, +254, +200, +138, +40, +186, +85, +137, +85, +100, +160, +83, +29, +159, +202, +53, +185, +54, +137, +203, +239, +71, +74, +119, +79, +10, +245, +181, +140, +186, +158, +135, +184, +103, +18, +224, +33, +103, +106, +118, +204, +10, +201, +234, +170, +147, +31, +99, +202, +168, +47, +186, +239, +121, +50, +62, +131, +39, +243, +15, +225, +146, +151, +154, +249, +169, +123, +26, +17, +229, +145, +221, +239, +90, +199, +153, +238, +230, +253, +185, +142, +44, +116, +126, +166, +166, +189, +41, +206, +176, +57, +176, +67, +208, +74, +60, +121, +197, +87, +138, +170, +232, +104, +154, +67, +48, +52, +50, +22, +49, +236, +165, +94, +96, +36, +4, +7, +225, +46, +213, +146, +104, +133, +213, +57, +207, +18, +178, +149, +105, +61, +63, +82, +166, +218, +150, +214, +14, +200, +237, +64, +180, +147, +159, +21, +183, +164, +28, +152, +210, +241, +42, +59, +118, +0, +116, +70, +18, diff --git a/gr-atsc/src/lib/qa_atsci_trellis_encoder_t1_output.dat b/gr-atsc/src/lib/qa_atsci_trellis_encoder_t1_output.dat new file mode 100644 index 000000000..175d482b4 --- /dev/null +++ b/gr-atsc/src/lib/qa_atsci_trellis_encoder_t1_output.dat @@ -0,0 +1,9984 @@ +6, +1, +1, +6, +2, +0, +4, +2, +6, +2, +4, +2, +0, +2, +2, +6, +1, +4, +6, +1, +7, +3, +6, +3, +2, +7, +3, +7, +2, +4, +1, +4, +3, +7, +7, +5, +7, +3, +5, +7, +2, +2, +0, +5, +0, +4, +5, +5, +3, +0, +5, +2, +3, +1, +5, +2, +1, +7, +5, +5, +0, +7, +3, +2, +1, +2, +0, +4, +0, +1, +5, +1, +5, +1, +0, +1, +1, +6, +5, +4, +1, +1, +1, +3, +4, +5, +7, +0, +3, +1, +6, +6, +0, +5, +1, +6, +3, +7, +7, +7, +0, +0, +2, +7, +7, +3, +7, +4, +7, +6, +6, +3, +1, +5, +7, +3, +5, +2, +4, +4, +2, +6, +6, +2, +6, +6, +1, +0, +5, +2, +7, +6, +4, +3, +5, +2, +2, +6, +3, +5, +1, +7, +5, +3, +2, +3, +4, +7, +5, +3, +0, +2, +3, +1, +1, +5, +5, +2, +1, +1, +2, +5, +7, +2, +4, +1, +7, +1, +0, +2, +0, +5, +4, +7, +5, +5, +5, +5, +4, +1, +5, +5, +3, +1, +0, +4, +5, +6, +6, +7, +7, +7, +4, +0, +1, +1, +4, +1, +3, +2, +6, +0, +5, +0, +3, +1, +7, +5, +2, +0, +2, +5, +3, +3, +1, +1, +1, +2, +2, +5, +7, +7, +0, +4, +3, +7, +3, +2, +3, +6, +4, +7, +7, +5, +0, +5, +4, +0, +0, +4, +0, +7, +4, +0, +2, +1, +4, +2, +5, +7, +7, +2, +7, +3, +0, +1, +6, +7, +4, +6, +6, +7, +5, +3, +5, +6, +4, +4, +7, +2, +2, +5, +0, +2, +1, +3, +5, +0, +2, +5, +7, +2, +3, +4, +4, +2, +1, +0, +1, +0, +3, +2, +0, +3, +7, +5, +0, +3, +7, +3, +7, +4, +3, +2, +1, +3, +4, +0, +6, +1, +6, +7, +6, +0, +2, +1, +0, +6, +7, +5, +1, +5, +4, +6, +6, +2, +4, +6, +5, +2, +1, +0, +2, +1, +2, +2, +3, +1, +4, +0, +6, +3, +7, +1, +4, +7, +5, +5, +5, +0, +6, +4, +4, +7, +6, +0, +6, +4, +4, +4, +5, +3, +3, +0, +4, +2, +6, +3, +1, +3, +3, +3, +1, +5, +7, +2, +0, +0, +5, +5, +4, +1, +3, +7, +3, +3, +2, +1, +6, +2, +6, +1, +7, +1, +6, +2, +4, +4, +6, +0, +3, +1, +2, +7, +5, +5, +6, +0, +5, +1, +1, +7, +5, +4, +5, +0, +5, +7, +3, +0, +6, +2, +6, +3, +7, +5, +4, +7, +5, +0, +5, +6, +6, +2, +6, +6, +2, +2, +1, +3, +7, +1, +5, +1, +1, +7, +1, +4, +6, +0, +6, +0, +0, +0, +7, +4, +0, +1, +4, +0, +5, +0, +6, +3, +3, +7, +6, +1, +7, +5, +3, +2, +4, +2, +3, +7, +3, +3, +6, +0, +5, +7, +7, +5, +1, +1, +5, +6, +2, +0, +3, +3, +7, +6, +4, +0, +6, +6, +3, +4, +2, +7, +5, +3, +2, +6, +5, +7, +6, +2, +2, +4, +3, +7, +7, +0, +6, +3, +0, +3, +1, +1, +4, +4, +7, +6, +4, +1, +1, +3, +7, +6, +4, +6, +0, +4, +0, +6, +7, +2, +0, +0, +7, +0, +5, +0, +0, +4, +1, +3, +5, +6, +7, +1, +4, +2, +6, +4, +0, +0, +6, +1, +1, +3, +5, +0, +7, +3, +4, +0, +4, +4, +2, +1, +5, +7, +7, +5, +3, +5, +4, +2, +4, +0, +3, +7, +3, +2, +4, +6, +0, +1, +6, +3, +2, +2, +1, +0, +0, +6, +1, +2, +7, +1, +5, +7, +7, +7, +3, +7, +3, +3, +4, +5, +3, +1, +0, +6, +3, +1, +6, +1, +3, +3, +3, +2, +4, +5, +5, +4, +6, +1, +0, +7, +6, +0, +7, +2, +5, +7, +2, +0, +6, +5, +0, +6, +0, +1, +4, +7, +6, +6, +0, +0, +5, +3, +0, +2, +6, +2, +1, +5, +4, +0, +2, +6, +2, +6, +2, +7, +1, +4, +4, +5, +6, +2, +7, +7, +6, +4, +3, +5, +4, +6, +7, +3, +5, +7, +1, +7, +7, +6, +3, +1, +1, +3, +3, +4, +4, +5, +1, +0, +1, +5, +6, +1, +4, +1, +6, +7, +3, +7, +1, +7, +3, +6, +0, +3, +5, +1, +0, +3, +5, +6, +7, +3, +6, +4, +2, +0, +0, +1, +0, +2, +5, +0, +6, +2, +4, +4, +1, +1, +1, +1, +4, +2, +3, +4, +6, +2, +4, +4, +6, +0, +2, +1, +6, +3, +0, +6, +1, +1, +2, +6, +2, +3, +0, +3, +5, +7, +1, +7, +0, +0, +5, +5, +5, +5, +2, +2, +4, +4, +4, +7, +7, +3, +0, +4, +4, +3, +3, +6, +7, +3, +5, +2, +7, +7, +7, +5, +3, +6, +5, +5, +1, +3, +4, +2, +2, +0, +5, +6, +7, +6, +1, +4, +1, +0, +1, +7, +2, +1, +3, +2, +4, +3, +5, +3, +7, +3, +6, +5, +6, +1, +1, +6, +7, +7, +7, +5, +4, +3, +0, +7, +3, +4, +4, +3, +5, +6, +0, +1, +1, +6, +4, +0, +3, +1, +7, +1, +1, +0, +3, +1, +4, +4, +0, +5, +2, +4, +3, +7, +3, +2, +1, +5, +3, +6, +0, +2, +2, +3, +6, +2, +2, +5, +3, +5, +1, +5, +4, +6, +5, +3, +2, +6, +6, +2, +4, +5, +3, +0, +0, +3, +0, +2, +7, +1, +7, +4, +3, +1, +2, +7, +0, +3, +5, +0, +1, +4, +1, +6, +3, +5, +4, +3, +0, +6, +4, +0, +5, +5, +3, +7, +4, +1, +4, +4, +4, +0, +7, +0, +3, +0, +0, +1, +1, +5, +2, +3, +4, +0, +7, +4, +2, +5, +3, +3, +4, +1, +3, +1, +6, +6, +2, +6, +6, +6, +7, +2, +5, +7, +5, +7, +3, +5, +2, +3, +1, +4, +2, +2, +6, +4, +1, +2, +5, +4, +5, +7, +0, +2, +6, +1, +4, +1, +7, +6, +5, +1, +0, +2, +7, +1, +3, +0, +0, +2, +4, +5, +3, +4, +7, +6, +7, +2, +3, +5, +0, +4, +1, +4, +4, +5, +1, +5, +2, +0, +0, +2, +4, +2, +0, +1, +1, +6, +1, +6, +0, +2, +5, +2, +2, +3, +5, +6, +6, +0, +3, +0, +2, +1, +0, +3, +5, +3, +0, +4, +2, +6, +2, +4, +5, +6, +1, +7, +2, +0, +7, +0, +3, +3, +6, +6, +0, +0, +0, +0, +6, +3, +3, +4, +1, +7, +3, +7, +7, +4, +3, +5, +7, +7, +0, +2, +3, +4, +7, +1, +1, +0, +5, +4, +1, +6, +3, +5, +6, +5, +0, +5, +3, +6, +7, +1, +5, +2, +5, +6, +2, +2, +7, +5, +4, +1, +6, +2, +3, +1, +7, +4, +7, +4, +3, +1, +7, +0, +6, +6, +2, +0, +2, +4, +5, +0, +4, +1, +3, +1, +3, +7, +4, +5, +2, +2, +3, +0, +5, +5, +2, +4, +3, +7, +0, +2, +3, +3, +6, +2, +6, +3, +4, +5, +0, +4, +2, +2, +5, +5, +0, +5, +4, +2, +4, +2, +7, +3, +7, +3, +7, +7, +2, +2, +2, +6, +2, +6, +1, +3, +1, +1, +2, +4, +7, +4, +1, +1, +1, +7, +5, +6, +1, +5, +0, +3, +5, +0, +4, +6, +2, +5, +5, +6, +5, +5, +4, +5, +3, +0, +5, +0, +0, +1, +3, +5, +3, +1, +2, +1, +2, +2, +6, +6, +4, +1, +0, +2, +4, +5, +5, +1, +4, +3, +6, +5, +4, +7, +1, +0, +5, +5, +6, +5, +0, +5, +3, +6, +0, +6, +4, +6, +4, +1, +6, +1, +4, +1, +7, +4, +0, +6, +3, +1, +1, +5, +3, +5, +0, +7, +6, +0, +0, +3, +7, +6, +6, +5, +5, +5, +6, +4, +0, +4, +0, +3, +0, +6, +2, +3, +7, +7, +5, +3, +0, +6, +2, +2, +5, +1, +1, +6, +4, +6, +2, +3, +4, +1, +3, +2, +2, +4, +6, +0, +7, +0, +4, +0, +2, +2, +7, +5, +4, +5, +4, +6, +1, +0, +6, +5, +1, +6, +6, +0, +6, +0, +2, +3, +5, +0, +3, +0, +2, +5, +2, +7, +5, +3, +3, +3, +5, +4, +7, +7, +4, +4, +3, +5, +2, +3, +7, +2, +5, +6, +0, +5, +4, +7, +5, +5, +6, +0, +2, +2, +7, +3, +1, +7, +2, +5, +7, +7, +1, +5, +2, +5, +2, +7, +0, +6, +3, +3, +6, +0, +4, +4, +5, +0, +0, +0, +1, +2, +3, +0, +2, +3, +3, +7, +2, +1, +6, +7, +0, +7, +2, +7, +5, +7, +1, +7, +4, +4, +3, +3, +1, +1, +6, +7, +6, +0, +1, +0, +6, +7, +1, +6, +4, +3, +7, +0, +6, +7, +5, +7, +3, +7, +3, +4, +1, +4, +1, +1, +5, +1, +7, +5, +1, +4, +4, +2, +4, +1, +1, +4, +4, +3, +6, +3, +3, +7, +3, +7, +3, +6, +7, +3, +7, +0, +0, +0, +4, +5, +1, +7, +7, +2, +2, +3, +1, +7, +6, +7, +7, +7, +7, +0, +6, +5, +6, +0, +1, +5, +5, +1, +7, +6, +2, +7, +0, +0, +7, +3, +7, +5, +0, +5, +6, +0, +4, +3, +0, +5, +5, +5, +6, +3, +1, +1, +6, +4, +6, +4, +0, +0, +7, +1, +2, +4, +6, +1, +5, +4, +7, +3, +4, +1, +0, +3, +3, +5, +6, +7, +4, +2, +1, +5, +2, +0, +7, +6, +1, +0, +1, +0, +1, +3, +7, +3, +1, +3, +3, +6, +5, +5, +2, +3, +6, +7, +4, +0, +4, +5, +2, +7, +3, +0, +4, +7, +2, +6, +5, +7, +3, +3, +6, +5, +2, +5, +2, +2, +3, +4, +0, +7, +3, +6, +5, +1, +0, +2, +1, +4, +3, +4, +3, +2, +0, +4, +6, +5, +6, +6, +4, +0, +4, +0, +7, +0, +3, +4, +0, +1, +1, +5, +3, +4, +7, +4, +2, +4, +7, +0, +6, +7, +6, +6, +6, +1, +1, +6, +0, +0, +4, +4, +7, +6, +6, +4, +5, +0, +1, +2, +4, +0, +1, +4, +3, +4, +1, +2, +7, +6, +5, +5, +6, +6, +4, +2, +4, +6, +2, +7, +2, +7, +1, +2, +3, +1, +7, +3, +5, +1, +4, +1, +4, +1, +7, +4, +1, +0, +7, +7, +4, +2, +0, +7, +6, +1, +2, +2, +1, +5, +4, +2, +5, +6, +4, +6, +7, +1, +2, +7, +5, +6, +1, +0, +0, +7, +0, +6, +5, +3, +1, +5, +7, +2, +4, +0, +7, +3, +6, +3, +1, +2, +4, +7, +6, +1, +3, +4, +3, +6, +1, +3, +5, +0, +7, +2, +2, +4, +1, +4, +2, +2, +0, +4, +3, +6, +7, +2, +3, +1, +3, +4, +2, +7, +3, +1, +6, +3, +0, +3, +7, +2, +0, +2, +1, +3, +1, +6, +6, +3, +3, +5, +0, +2, +3, +1, +6, +6, +3, +2, +3, +4, +7, +5, +7, +7, +5, +4, +4, +4, +2, +1, +7, +1, +4, +5, +7, +5, +7, +5, +6, +4, +0, +6, +6, +6, +5, +5, +4, +5, +4, +0, +1, +4, +2, +2, +2, +4, +4, +3, +5, +7, +3, +3, +2, +0, +3, +7, +7, +4, +7, +4, +6, +0, +3, +7, +4, +6, +7, +1, +7, +2, +3, +3, +6, +5, +4, +6, +4, +3, +0, +5, +6, +7, +6, +5, +5, +2, +3, +0, +6, +3, +1, +5, +0, +7, +4, +3, +4, +6, +1, +6, +5, +2, +6, +3, +6, +4, +4, +4, +3, +3, +5, +3, +0, +6, +6, +4, +3, +3, +4, +3, +7, +1, +7, +5, +7, +5, +5, +5, +1, +3, +6, +5, +6, +1, +2, +3, +1, +6, +6, +0, +3, +2, +5, +5, +4, +3, +2, +0, +1, +4, +4, +1, +4, +6, +0, +5, +4, +4, +7, +1, +3, +2, +4, +4, +1, +1, +5, +5, +6, +7, +7, +6, +0, +5, +4, +7, +2, +6, +2, +7, +1, +1, +2, +0, +5, +4, +0, +1, +0, +6, +2, +6, +4, +1, +6, +2, +6, +7, +0, +5, +2, +7, +3, +0, +7, +3, +3, +7, +6, +1, +6, +5, +3, +7, +7, +0, +1, +2, +7, +5, +5, +5, +3, +5, +5, +6, +0, +4, +5, +4, +0, +7, +2, +1, +3, +5, +1, +4, +7, +4, +3, +6, +3, +0, +4, +3, +2, +1, +7, +2, +1, +2, +0, +7, +5, +7, +4, +6, +4, +3, +0, +5, +3, +7, +3, +3, +1, +7, +4, +2, +2, +4, +3, +6, +2, +1, +5, +0, +7, +2, +0, +7, +7, +7, +3, +2, +6, +1, +5, +5, +4, +6, +4, +3, +3, +5, +6, +7, +1, +1, +1, +0, +1, +5, +4, +2, +2, +1, +0, +5, +4, +7, +1, +5, +6, +6, +6, +6, +4, +1, +0, +1, +5, +6, +1, +6, +0, +4, +3, +5, +0, +3, +4, +1, +2, +0, +1, +2, +6, +0, +1, +6, +0, +6, +0, +5, +4, +0, +5, +3, +5, +0, +5, +4, +2, +2, +2, +5, +0, +4, +5, +1, +6, +6, +7, +4, +3, +7, +7, +5, +0, +4, +1, +3, +0, +7, +0, +0, +5, +5, +1, +1, +6, +6, +7, +0, +4, +3, +1, +2, +3, +5, +7, +1, +3, +1, +2, +3, +2, +4, +0, +3, +4, +1, +2, +1, +7, +0, +0, +1, +5, +7, +5, +1, +5, +5, +6, +7, +4, +1, +2, +7, +0, +3, +2, +5, +4, +3, +5, +0, +5, +6, +7, +2, +5, +6, +4, +7, +5, +6, +4, +7, +6, +6, +7, +0, +0, +4, +6, +6, +4, +4, +3, +7, +4, +7, +0, +4, +3, +2, +5, +0, +5, +6, +5, +0, +4, +5, +7, +0, +3, +3, +0, +0, +2, +7, +1, +5, +2, +5, +5, +2, +2, +5, +7, +6, +6, +3, +1, +0, +7, +5, +1, +3, +0, +3, +7, +3, +1, +2, +3, +3, +5, +7, +7, +5, +6, +4, +2, +1, +6, +6, +2, +5, +7, +2, +4, +1, +5, +3, +0, +1, +6, +1, +0, +5, +0, +6, +3, +5, +6, +7, +4, +3, +7, +4, +0, +5, +3, +1, +5, +1, +4, +0, +2, +0, +1, +5, +2, +7, +3, +4, +1, +3, +0, +3, +3, +5, +5, +4, +3, +2, +6, +1, +5, +4, +6, +5, +3, +2, +7, +5, +5, +6, +0, +0, +7, +7, +7, +1, +0, +4, +2, +6, +5, +7, +0, +7, +0, +1, +1, +3, +7, +0, +6, +6, +5, +5, +2, +1, +5, +1, +7, +0, +3, +0, +5, +1, +3, +3, +3, +5, +4, +3, +0, +5, +0, +4, +0, +2, +2, +4, +3, +7, +7, +6, +7, +6, +5, +0, +3, +4, +0, +3, +2, +2, +5, +2, +5, +6, +6, +0, +7, +4, +4, +1, +4, +2, +3, +1, +1, +5, +0, +6, +4, +6, +6, +7, +0, +5, +6, +4, +1, +2, +4, +1, +1, +7, +7, +0, +6, +0, +4, +3, +3, +0, +2, +4, +6, +5, +5, +1, +3, +3, +6, +1, +1, +6, +3, +3, +4, +3, +7, +4, +3, +3, +4, +1, +4, +2, +5, +3, +0, +6, +6, +1, +4, +6, +0, +3, +3, +3, +7, +2, +4, +2, +6, +0, +5, +6, +4, +6, +7, +7, +2, +6, +0, +7, +5, +7, +2, +7, +0, +0, +0, +6, +2, +7, +4, +1, +6, +5, +2, +7, +6, +2, +7, +6, +5, +5, +4, +3, +4, +7, +1, +4, +1, +5, +5, +5, +0, +1, +4, +6, +6, +0, +2, +5, +2, +6, +3, +2, +1, +1, +2, +6, +5, +1, +0, +4, +0, +0, +0, +6, +2, +7, +3, +5, +4, +6, +2, +5, +0, +0, +5, +7, +4, +6, +5, +2, +7, +6, +3, +2, +4, +0, +2, +3, +4, +6, +7, +2, +5, +5, +7, +2, +0, +4, +2, +6, +6, +3, +4, +3, +5, +2, +0, +7, +6, +6, +7, +2, +5, +7, +7, +5, +1, +6, +7, +3, +5, +1, +1, +5, +0, +6, +3, +7, +7, +3, +3, +4, +2, +6, +7, +4, +7, +0, +2, +6, +0, +1, +2, +5, +6, +0, +2, +5, +5, +4, +0, +2, +3, +7, +2, +6, +5, +0, +4, +4, +1, +2, +6, +5, +3, +2, +1, +0, +0, +2, +2, +1, +3, +1, +5, +2, +4, +0, +0, +0, +5, +5, +7, +6, +0, +0, +4, +2, +1, +6, +3, +4, +6, +0, +3, +6, +3, +7, +5, +3, +2, +7, +3, +0, +6, +3, +6, +7, +3, +5, +2, +5, +0, +1, +0, +0, +7, +3, +0, +3, +6, +7, +4, +1, +4, +5, +5, +2, +5, +2, +4, +6, +2, +2, +2, +5, +0, +7, +0, +3, +5, +6, +2, +0, +3, +4, +3, +5, +0, +6, +1, +1, +5, +7, +1, +2, +3, +0, +7, +1, +0, +0, +0, +7, +7, +5, +2, +5, +2, +4, +6, +1, +2, +2, +1, +0, +6, +5, +4, +4, +0, +4, +0, +7, +5, +5, +6, +5, +2, +3, +4, +7, +0, +6, +6, +6, +6, +0, +0, +2, +3, +6, +4, +1, +6, +7, +7, +0, +2, +1, +0, +2, +3, +4, +2, +5, +7, +1, +7, +0, +1, +2, +6, +1, +4, +0, +7, +7, +3, +3, +4, +0, +6, +0, +1, +6, +3, +2, +7, +6, +0, +2, +5, +4, +2, +0, +0, +4, +7, +5, +6, +2, +7, +6, +2, +6, +3, +2, +1, +0, +4, +4, +4, +1, +5, +7, +4, +5, +7, +3, +0, +0, +3, +1, +6, +2, +1, +3, +0, +2, +0, +5, +3, +4, +5, +0, +1, +0, +7, +2, +6, +0, +5, +5, +3, +2, +7, +3, +0, +6, +0, +0, +3, +0, +4, +7, +6, +1, +2, +1, +5, +1, +7, +4, +7, +2, +3, +6, +6, +2, +0, +5, +6, +2, +1, +6, +2, +5, +3, +2, +3, +0, +2, +3, +6, +2, +7, +1, +4, +4, +2, +7, +7, +4, +3, +6, +5, +1, +6, +6, +2, +1, +6, +1, +4, +0, +5, +2, +2, +6, +4, +4, +5, +4, +3, +3, +5, +6, +3, +7, +0, +0, +4, +2, +4, +3, +1, +2, +6, +3, +0, +5, +4, +6, +4, +3, +7, +7, +7, +4, +0, +7, +7, +1, +2, +7, +6, +1, +7, +6, +6, +0, +4, +4, +3, +5, +3, +3, +5, +3, +2, +4, +2, +2, +6, +1, +6, +7, +1, +4, +0, +0, +4, +6, +1, +1, +1, +6, +0, +6, +3, +3, +5, +3, +6, +5, +4, +2, +0, +6, +0, +2, +4, +5, +2, +1, +5, +2, +7, +4, +5, +1, +2, +3, +7, +7, +6, +5, +4, +6, +7, +6, +6, +2, +5, +7, +5, +6, +7, +7, +5, +3, +6, +7, +4, +2, +4, +4, +7, +6, +3, +6, +6, +1, +6, +1, +6, +5, +3, +1, +6, +1, +0, +0, +4, +7, +1, +1, +1, +4, +3, +6, +6, +4, +1, +0, +6, +2, +6, +5, +4, +5, +6, +0, +5, +1, +4, +6, +7, +6, +2, +5, +1, +0, +4, +2, +2, +2, +7, +5, +7, +7, +5, +7, +6, +3, +0, +1, +4, +0, +1, +4, +2, +7, +0, +4, +6, +5, +0, +2, +6, +2, +7, +1, +2, +0, +7, +7, +7, +3, +6, +2, +3, +3, +6, +2, +1, +7, +3, +1, +3, +2, +3, +7, +1, +1, +6, +6, +4, +1, +4, +1, +0, +2, +5, +7, +5, +7, +3, +5, +5, +3, +1, +5, +5, +7, +5, +2, +1, +0, +7, +4, +0, +2, +6, +1, +0, +5, +3, +0, +7, +7, +4, +7, +5, +2, +6, +7, +7, +5, +4, +0, +2, +1, +3, +5, +6, +7, +3, +2, +7, +5, +3, +6, +2, +3, +7, +5, +0, +5, +1, +0, +2, +1, +3, +1, +7, +6, +0, +1, +0, +7, +1, +2, +6, +1, +6, +0, +3, +2, +3, +5, +0, +6, +7, +1, +1, +1, +0, +7, +0, +3, +1, +7, +6, +0, +6, +4, +6, +7, +2, +7, +3, +7, +5, +4, +1, +6, +6, +5, +6, +6, +1, +6, +7, +0, +6, +1, +1, +6, +1, +4, +1, +0, +4, +6, +2, +5, +1, +1, +6, +7, +2, +3, +6, +2, +3, +3, +2, +4, +1, +0, +6, +1, +2, +5, +6, +1, +1, +7, +7, +5, +7, +3, +3, +5, +7, +7, +7, +0, +3, +2, +1, +4, +2, +3, +1, +3, +7, +0, +7, +1, +4, +2, +1, +5, +0, +0, +5, +0, +4, +3, +0, +4, +1, +5, +3, +2, +0, +5, +5, +7, +5, +1, +7, +3, +0, +6, +2, +2, +4, +6, +3, +3, +0, +7, +7, +7, +5, +6, +6, +1, +6, +6, +6, +6, +3, +6, +6, +6, +0, +5, +5, +2, +7, +3, +2, +2, +5, +2, +4, +6, +7, +6, +2, +0, +5, +5, +3, +7, +3, +7, +2, +5, +5, +6, +0, +4, +3, +7, +5, +3, +4, +7, +3, +0, +3, +5, +2, +2, +4, +0, +3, +6, +7, +0, +3, +7, +2, +6, +3, +5, +3, +7, +4, +0, +1, +7, +6, +3, +0, +6, +5, +4, +7, +7, +3, +2, +3, +1, +2, +2, +0, +3, +5, +5, +4, +4, +1, +1, +4, +5, +7, +4, +0, +1, +1, +0, +5, +5, +3, +4, +5, +3, +3, +4, +6, +3, +3, +3, +2, +2, +4, +1, +2, +0, +0, +2, +1, +2, +6, +3, +2, +0, +1, +0, +2, +5, +3, +7, +6, +2, +2, +6, +3, +6, +6, +3, +3, +4, +5, +3, +0, +5, +7, +4, +1, +5, +2, +7, +7, +3, +3, +0, +6, +0, +5, +4, +3, +0, +1, +0, +0, +5, +2, +5, +5, +5, +1, +0, +4, +5, +4, +5, +1, +5, +0, +2, +6, +2, +7, +6, +1, +2, +7, +0, +0, +5, +4, +6, +2, +2, +0, +7, +0, +4, +5, +1, +1, +1, +4, +3, +3, +7, +5, +1, +5, +6, +3, +4, +0, +1, +0, +7, +3, +7, +4, +1, +0, +7, +0, +7, +5, +3, +4, +0, +2, +2, +3, +5, +3, +5, +5, +7, +0, +4, +0, +5, +4, +0, +3, +3, +3, +3, +2, +4, +5, +7, +6, +6, +4, +4, +0, +6, +4, +6, +0, +7, +0, +5, +3, +2, +6, +0, +1, +2, +5, +6, +4, +5, +5, +1, +1, +7, +7, +0, +2, +3, +4, +1, +6, +1, +0, +5, +3, +1, +1, +0, +4, +7, +5, +0, +1, +1, +5, +7, +2, +7, +1, +4, +0, +4, +4, +7, +0, +3, +4, +6, +6, +0, +1, +6, +2, +5, +1, +5, +1, +6, +7, +6, +7, +7, +1, +1, +3, +2, +0, +5, +4, +6, +1, +7, +7, +1, +7, +2, +7, +2, +1, +1, +5, +1, +5, +1, +4, +3, +2, +6, +2, +5, +0, +7, +4, +0, +7, +3, +5, +0, +4, +5, +2, +6, +3, +4, +7, +5, +2, +2, +4, +3, +0, +2, +5, +6, +3, +1, +5, +2, +4, +2, +1, +1, +2, +2, +6, +5, +6, +4, +3, +4, +6, +1, +0, +7, +7, +3, +4, +6, +0, +1, +2, +0, +1, +2, +5, +0, +3, +1, +2, +2, +4, +4, +4, +4, +4, +4, +6, +5, +0, +7, +1, +5, +4, +1, +6, +6, +1, +6, +0, +2, +3, +4, +6, +4, +0, +2, +3, +7, +2, +3, +4, +2, +7, +1, +2, +7, +2, +6, +5, +5, +0, +7, +2, +5, +4, +6, +3, +7, +3, +7, +1, +3, +0, +2, +1, +4, +5, +2, +5, +2, +1, +1, +3, +4, +4, +4, +6, +1, +4, +1, +7, +6, +5, +7, +0, +3, +0, +6, +2, +6, +7, +6, +2, +1, +3, +4, +5, +7, +4, +3, +3, +4, +5, +0, +4, +6, +6, +7, +6, +0, +0, +7, +1, +4, +7, +0, +2, +4, +2, +7, +2, +7, +2, +6, +1, +6, +2, +6, +7, +6, +1, +0, +3, +1, +3, +2, +3, +5, +2, +3, +1, +1, +6, +3, +1, +5, +5, +3, +4, +4, +7, +1, +5, +6, +4, +3, +3, +5, +5, +1, +7, +7, +1, +7, +1, +2, +2, +6, +6, +3, +1, +1, +1, +7, +3, +0, +5, +1, +1, +0, +2, +2, +1, +7, +7, +6, +6, +5, +1, +2, +0, +2, +1, +2, +3, +2, +0, +0, +6, +6, +5, +6, +1, +7, +6, +3, +4, +4, +7, +6, +7, +4, +1, +3, +6, +1, +2, +3, +1, +4, +7, +5, +5, +0, +1, +3, +2, +1, +5, +6, +2, +4, +4, +6, +7, +4, +3, +4, +3, +5, +0, +2, +2, +0, +5, +6, +4, +0, +0, +1, +7, +1, +5, +7, +5, +6, +0, +1, +7, +2, +3, +2, +6, +7, +2, +5, +2, +1, +3, +0, +5, +5, +5, +6, +0, +6, +0, +5, +2, +2, +5, +3, +1, +2, +3, +3, +6, +2, +0, +1, +7, +2, +1, +1, +7, +0, +2, +1, +5, +1, +6, +3, +3, +3, +7, +5, +6, +4, +2, +7, +6, +2, +1, +4, +0, +7, +4, +5, +6, +2, +5, +2, +4, +0, +6, +5, +3, +2, +5, +7, +7, +3, +0, +4, +0, +6, +4, +2, +6, +1, +1, +6, +7, +3, +7, +2, +0, +5, +6, +0, +3, +4, +6, +0, +2, +2, +3, +3, +0, +6, +5, +2, +2, +6, +6, +3, +0, +0, +4, +7, +6, +2, +4, +7, +4, +5, +7, +5, +2, +2, +7, +2, +5, +1, +3, +1, +6, +0, +3, +5, +5, +3, +1, +4, +4, +2, +3, +1, +3, +1, +0, +1, +2, +3, +7, +6, +7, +4, +2, +1, +1, +0, +5, +3, +4, +4, +0, +7, +5, +2, +2, +1, +5, +3, +6, +6, +6, +1, +7, +5, +7, +1, +5, +5, +5, +5, +4, +6, +5, +4, +3, +7, +0, +6, +0, +3, +7, +3, +0, +3, +2, +5, +2, +4, +3, +4, +5, +4, +6, +6, +0, +1, +2, +4, +6, +7, +1, +2, +6, +3, +2, +2, +2, +7, +1, +3, +5, +1, +5, +1, +6, +1, +5, +7, +7, +0, +2, +3, +0, +3, +1, +6, +7, +3, +6, +5, +3, +3, +2, +6, +5, +2, +3, +0, +3, +2, +4, +3, +4, +3, +1, +2, +2, +6, +6, +6, +4, +2, +0, +2, +3, +4, +6, +7, +0, +7, +6, +3, +1, +5, +4, +2, +5, +3, +0, +7, +2, +7, +7, +5, +0, +6, +4, +7, +3, +5, +4, +4, +3, +0, +5, +5, +1, +2, +4, +1, +0, +7, +6, +5, +7, +7, +1, +5, +6, +7, +6, +5, +3, +6, +1, +6, +0, +3, +1, +3, +4, +5, +1, +7, +7, +6, +4, +6, +5, +0, +3, +0, +2, +1, +4, +0, +4, +5, +3, +1, +4, +3, +4, +1, +5, +7, +5, +1, +7, +0, +3, +6, +5, +1, +3, +4, +4, +2, +0, +6, +1, +5, +4, +4, +6, +1, +7, +7, +3, +6, +1, +2, +1, +6, +7, +0, +6, +7, +2, +7, +1, +7, +4, +3, +7, +2, +3, +2, +3, +4, +0, +0, +5, +3, +1, +7, +6, +7, +6, +3, +7, +7, +6, +7, +5, +0, +6, +2, +2, +1, +2, +5, +4, +7, +5, +3, +5, +7, +4, +6, +5, +3, +1, +3, +7, +4, +2, +0, +1, +1, +0, +5, +0, +0, +0, +4, +3, +5, +2, +7, +3, +1, +4, +0, +3, +3, +1, +3, +2, +6, +3, +3, +6, +5, +0, +1, +7, +3, +4, +7, +2, +4, +3, +0, +6, +3, +2, +6, +4, +2, +5, +6, +7, +0, +0, +7, +3, +4, +5, +6, +7, +2, +0, +2, +7, +6, +1, +1, +3, +5, +4, +7, +7, +3, +5, +7, +4, +7, +6, +7, +6, +0, +7, +3, +4, +1, +4, +3, +5, +7, +0, +6, +2, +3, +5, +6, +1, +3, +3, +2, +2, +6, +6, +0, +3, +7, +1, +2, +6, +2, +1, +6, +0, +2, +3, +4, +7, +2, +1, +5, +2, +4, +5, +7, +0, +5, +1, +4, +4, +2, +7, +6, +7, +6, +3, +3, +0, +2, +5, +2, +5, +1, +2, +0, +7, +5, +0, +4, +6, +6, +1, +5, +2, +6, +0, +4, +0, +4, +5, +7, +3, +5, +7, +4, +4, +0, +0, +2, +3, +7, +4, +1, +1, +2, +2, +3, +4, +2, +6, +3, +7, +3, +3, +7, +7, +2, +4, +7, +0, +7, +3, +7, +6, +4, +5, +6, +0, +1, +2, +2, +2, +1, +3, +4, +4, +7, +1, +2, +5, +4, +3, +6, +7, +5, +4, +3, +6, +1, +3, +5, +0, +1, +3, +1, +1, +5, +3, +7, +1, +1, +0, +4, +1, +2, +0, +6, +5, +3, +5, +2, +6, +3, +7, +1, +2, +2, +3, +6, +3, +4, +3, +6, +6, +4, +1, +0, +2, +7, +7, +7, +2, +7, +6, +5, +1, +1, +1, +5, +5, +5, +4, +7, +2, +7, +4, +6, +0, +6, +7, +4, +0, +1, +1, +4, +5, +0, +2, +0, +7, +0, +6, +7, +5, +3, +6, +5, +0, +5, +5, +0, +3, +4, +6, +5, +6, +4, +2, +2, +1, +6, +0, +4, +0, +4, +7, +7, +6, +7, +5, +0, +0, +2, +7, +2, +5, +6, +1, +0, +1, +7, +6, +6, +7, +5, +3, +1, +2, +5, +1, +3, +0, +0, +0, +7, +3, +6, +6, +2, +6, +4, +5, +1, +5, +3, +0, +5, +6, +0, +4, +2, +7, +3, +1, +1, +6, +3, +0, +5, +0, +0, +0, +1, +5, +5, +7, +5, +2, +4, +4, +3, +0, +2, +6, +4, +5, +1, +0, +1, +7, +1, +6, +0, +2, +7, +7, +3, +5, +3, +5, +5, +5, +2, +1, +7, +1, +5, +3, +5, +1, +6, +0, +1, +3, +6, +6, +5, +6, +7, +2, +5, +7, +4, +7, +5, +2, +1, +4, +5, +6, +2, +6, +3, +4, +4, +5, +1, +0, +6, +2, +3, +7, +0, +5, +2, +1, +0, +7, +5, +2, +4, +3, +2, +5, +0, +6, +6, +2, +2, +6, +3, +1, +6, +7, +4, +1, +2, +2, +5, +6, +7, +0, +0, +6, +1, +4, +0, +5, +1, +3, +0, +3, +3, +4, +5, +4, +2, +3, +6, +1, +4, +3, +5, +1, +6, +6, +1, +1, +6, +5, +7, +7, +7, +6, +4, +7, +0, +2, +6, +4, +6, +1, +5, +6, +7, +0, +7, +4, +4, +1, +6, +4, +1, +3, +3, +6, +6, +4, +7, +3, +6, +0, +5, +4, +2, +4, +4, +1, +4, +6, +2, +5, +7, +5, +0, +4, +2, +3, +5, +6, +0, +1, +2, +1, +3, +4, +7, +2, +5, +3, +4, +4, +6, +2, +7, +1, +4, +3, +7, +7, +0, +2, +7, +4, +5, +0, +7, +3, +3, +3, +4, +1, +5, +4, +1, +6, +0, +6, +4, +2, +5, +4, +7, +1, +0, +4, +1, +1, +5, +3, +5, +0, +1, +1, +7, +5, +1, +2, +5, +6, +2, +5, +0, +6, +5, +0, +4, +7, +4, +7, +5, +2, +0, +3, +5, +5, +7, +3, +1, +0, +5, +5, +3, +1, +4, +2, +6, +0, +4, +7, +0, +3, +4, +1, +2, +4, +6, +2, +6, +1, +7, +6, +7, +1, +3, +3, +4, +5, +3, +7, +7, +4, +7, +6, +1, +1, +5, +0, +6, +6, +1, +1, +7, +1, +4, +3, +5, +1, +5, +1, +3, +0, +5, +5, +2, +0, +5, +3, +7, +7, +7, +2, +5, +6, +1, +7, +6, +1, +0, +6, +2, +6, +2, +4, +7, +7, +3, +0, +7, +6, +5, +2, +6, +6, +2, +2, +0, +5, +2, +5, +1, +2, +6, +7, +1, +1, +5, +5, +1, +5, +0, +6, +3, +5, +0, +5, +6, +0, +6, +4, +4, +1, +4, +2, +0, +2, +2, +1, +6, +7, +2, +7, +7, +1, +0, +3, +3, +2, +5, +1, +7, +1, +7, +7, +1, +7, +6, +3, +3, +7, +6, +7, +5, +3, +1, +4, +7, +0, +5, +0, +6, +5, +4, +0, +3, +4, +3, +1, +4, +3, +4, +1, +6, +3, +6, +7, +6, +3, +2, +4, +7, +3, +5, +0, +1, +6, +1, +3, +4, +7, +2, +1, +3, +4, +0, +5, +6, +0, +2, +2, +0, +0, +7, +6, +6, +1, +3, +6, +6, +6, +6, +2, +6, +7, +3, +0, +4, +0, +5, +4, +7, +7, +7, +7, +3, +3, +6, +2, +2, +1, +7, +0, +1, +1, +5, +3, +7, +4, +6, +3, +5, +2, +4, +2, +7, +5, +1, +4, +0, +7, +3, +3, +0, +4, +7, +5, +2, +3, +5, +1, +3, +1, +5, +0, +5, +4, +1, +4, +0, +4, +3, +0, +7, +7, +7, +1, +2, +2, +3, +7, +4, +7, +0, +7, +0, +4, +4, +0, +0, +1, +0, +7, +0, +1, +1, +1, +1, +3, +5, +3, +6, +4, +1, +2, +2, +3, +6, +1, +6, +1, +0, +3, +1, +1, +2, +4, +5, +4, +4, +7, +0, +5, +1, +0, +6, +4, +0, +4, +0, +1, +6, +6, +4, +1, +0, +1, +0, +1, +2, +6, +3, +2, +1, +2, +2, +5, +3, +2, +0, +2, +7, +5, +3, +4, +2, +7, +3, +1, +5, +0, +0, +2, +5, +4, +0, +2, +0, +3, +1, +5, +5, +0, +2, +3, +5, +7, +7, +3, +4, +6, +3, +3, +5, +6, +3, +1, +7, +5, +7, +3, +4, +0, +2, +0, +5, +5, +5, +1, +0, +5, +2, +0, +6, +6, +6, +3, +1, +6, +7, +7, +3, +5, +4, +7, +7, +7, +7, +7, +7, +4, +4, +6, +7, +1, +6, +5, +3, +7, +1, +4, +6, +4, +1, +6, +0, +7, +5, +1, +0, +0, +3, +7, +2, +6, +6, +7, +3, +2, +0, +7, +1, +5, +2, +3, +5, +5, +6, +3, +7, +0, +5, +2, +0, +2, +2, +0, +2, +6, +3, +6, +0, +2, +0, +6, +5, +0, +1, +7, +2, +0, +7, +6, +5, +5, +1, +5, +6, +4, +0, +3, +5, +4, +0, +3, +0, +2, +4, +4, +2, +4, +3, +2, +6, +0, +1, +7, +5, +0, +1, +1, +3, +2, +3, +6, +4, +0, +0, +2, +4, +4, +4, +0, +5, +5, +4, +1, +6, +4, +1, +4, +7, +0, +3, +3, +1, +6, +3, +2, +7, +4, +4, +0, +5, +4, +1, +7, +7, +2, +3, +2, +1, +2, +1, +4, +7, +4, +3, +4, +4, +7, +0, +1, +7, +7, +4, +6, +6, +4, +2, +1, +7, +5, +5, +0, +0, +3, +5, +7, +0, +6, +6, +4, +5, +3, +4, +5, +3, +6, +6, +3, +4, +1, +1, +7, +5, +0, +7, +2, +7, +2, +4, +0, +0, +2, +2, +7, +3, +3, +7, +2, +6, +1, +4, +3, +0, +2, +0, +6, +2, +3, +4, +3, +2, +0, +0, +7, +6, +7, +6, +6, +2, +6, +5, +5, +5, +7, +6, +0, +5, +7, +5, +7, +5, +2, +4, +1, +6, +3, +3, +7, +2, +6, +0, +3, +6, +3, +1, +5, +6, +6, +5, +7, +4, +4, +7, +6, +4, +3, +2, +7, +1, +2, +5, +6, +6, +2, +1, +0, +2, +4, +0, +0, +0, +1, +7, +4, +5, +5, +3, +6, +5, +1, +4, +3, +1, +6, +2, +0, +2, +2, +4, +1, +0, +4, +2, +1, +6, +6, +1, +1, +6, +4, +7, +4, +5, +7, +1, +5, +0, +2, +0, +0, +0, +4, +5, +5, +2, +5, +6, +7, +2, +5, +0, +2, +2, +6, +1, +6, +2, +3, +6, +4, +7, +6, +6, +1, +5, +5, +5, +2, +3, +6, +5, +3, +3, +4, +1, +4, +6, +6, +5, +1, +5, +6, +6, +3, +2, +4, +6, +3, +4, +4, +1, +6, +3, +1, +6, +4, +4, +0, +2, +7, +6, +4, +5, +4, +6, +6, +3, +7, +4, +0, +3, +4, +3, +6, +1, +0, +2, +6, +1, +5, +4, +6, +5, +3, +7, +1, +7, +0, +1, +5, +5, +3, +2, +1, +3, +7, +4, +2, +0, +2, +0, +0, +3, +0, +7, +0, +2, +0, +7, +6, +1, +5, +3, +7, +6, +5, +5, +5, +0, +3, +1, +7, +4, +6, +7, +7, +0, +2, +1, +4, +4, +7, +1, +7, +1, +0, +2, +2, +2, +2, +1, +1, +0, +0, +1, +4, +6, +6, +4, +0, +1, +1, +1, +6, +6, +1, +5, +7, +0, +7, +0, +4, +4, +2, +5, +6, +7, +4, +5, +1, +6, +3, +6, +6, +1, +0, +3, +7, +1, +1, +1, +7, +5, +2, +5, +3, +0, +0, +4, +5, +3, +6, +1, +6, +0, +0, +2, +5, +7, +2, +5, +7, +4, +4, +1, +4, +7, +0, +2, +7, +7, +3, +4, +0, +3, +0, +3, +0, +3, +4, +5, +0, +0, +3, +3, +3, +7, +6, +6, +6, +4, +2, +6, +5, +7, +2, +7, +5, +4, +1, +6, +1, +7, +7, +2, +0, +1, +0, +2, +7, +5, +2, +1, +6, +7, +1, +3, +5, +1, +6, +0, +2, +6, +4, +2, +6, +2, +3, +5, +6, +1, +1, +0, +0, +6, +2, +2, +1, +0, +2, +7, +0, +7, +2, +4, +0, +1, +5, +7, +0, +2, +6, +4, +2, +2, +4, +0, +4, +4, +6, +7, +7, +7, +5, +7, +3, +6, +6, +4, +0, +1, +2, +4, +3, +3, +6, +5, +5, +5, +3, +4, +6, +4, +7, +1, +6, +6, +6, +3, +5, +6, +1, +2, +3, +5, +7, +2, +0, +2, +7, +6, +1, +0, +1, +3, +7, +2, +4, +4, +0, +3, +7, +0, +1, +0, +1, +1, +0, +4, +7, +4, +0, +1, +0, +4, +7, +2, +3, +3, +1, +2, +3, +0, +6, +7, +1, +6, +2, +7, +6, +4, +6, +1, +6, +4, +7, +6, +2, +3, +2, +1, +6, +1, +4, +0, +2, +0, +3, +6, +0, +5, +5, +7, +3, +4, +2, +7, +1, +2, +0, +1, +6, +5, +2, +0, +5, +3, +5, +3, +0, +1, +1, +0, +7, +5, +6, +7, +5, +5, +2, +4, +5, +6, +0, +3, +5, +3, +5, +1, +5, +1, +4, +1, +6, +4, +5, +3, +3, +2, +4, +7, +1, +1, +4, +0, +2, +6, +2, +6, +2, +6, +7, +6, +5, +5, +6, +1, +3, +7, +6, +0, +6, +1, +1, +4, +5, +1, +3, +2, +1, +3, +5, +2, +7, +6, +3, +6, +7, +7, +7, +6, +5, +2, +4, +7, +7, +0, +4, +3, +2, +6, +6, +5, +3, +0, +1, +1, +2, +6, +7, +7, +2, +0, +6, +4, +4, +2, +0, +7, +2, +5, +3, +6, +5, +0, +7, +3, +5, +3, +3, +4, +7, +0, +2, +0, +6, +4, +5, +5, +6, +1, +7, +3, +3, +7, +4, +6, +4, +6, +7, +5, +2, +3, +2, +1, +2, +1, +2, +7, +2, +3, +6, +7, +7, +4, +6, +3, +0, +7, +7, +1, +5, +5, +6, +0, +7, +3, +5, +4, +4, +2, +5, +1, +2, +5, +1, +1, +4, +7, +2, +1, +0, +0, +1, +3, +2, +1, +2, +6, +7, +2, +4, +2, +2, +0, +3, +4, +5, +7, +2, +0, +1, +6, +2, +2, +3, +6, +4, +7, +0, +2, +3, +0, +7, +5, +5, +5, +7, +1, +7, +1, +7, +6, +5, +6, +0, +4, +2, +6, +6, +0, +7, +1, +7, +7, +3, +5, +3, +1, +2, +4, +6, +5, +6, +7, +4, +7, +6, +6, +1, +6, +3, +0, +7, +2, +0, +0, +5, +6, +2, +4, +3, +0, +3, +6, +3, +4, +2, +3, +0, +0, +7, +6, +2, +0, +6, +7, +0, +6, +5, +1, +5, +4, +3, +7, +4, +2, +0, +3, +7, +5, +6, +5, +0, +4, +0, +5, +6, +3, +6, +6, +7, +4, +0, +3, +7, +6, +1, +7, +7, +7, +7, +6, +6, +5, +2, +2, +3, +5, +6, +2, +1, +6, +1, +5, +4, +4, +7, +4, +6, +0, +2, +2, +7, +4, +5, +4, +6, +5, +1, +4, +2, +7, +3, +1, +0, +0, +3, +5, +1, +4, +1, +0, +3, +1, +1, +4, +3, +4, +2, +0, +0, +5, +3, +4, +3, +7, +5, +5, +3, +2, +4, +1, +5, +0, +0, +2, +0, +4, +7, +6, +2, +7, +4, +4, +4, +1, +7, +1, +7, +1, +4, +2, +4, +1, +4, +1, +5, +0, +1, +2, +3, +2, +7, +1, +6, +1, +6, +1, +1, +6, +3, +0, +4, +2, +7, +6, +7, +7, +4, +4, +2, +5, +4, +0, +7, +3, +6, +2, +3, +4, +2, +3, +0, +2, +7, +2, +1, +5, +6, +7, +0, +5, +7, +3, +2, +4, +3, +3, +5, +5, +3, +3, +1, +2, +3, +6, +1, +4, +0, +7, +3, +5, +5, +4, +2, +6, +0, +6, +0, +6, +3, +4, +4, +5, +7, +1, +2, +3, +5, +3, +3, +3, +5, +5, +7, +3, +6, +0, +5, +3, +0, +5, +3, +5, +7, +6, +1, +4, +4, +1, +6, +2, +5, +1, +2, +7, +4, +6, +3, +1, +0, +4, +0, +6, +0, +3, +2, +2, +1, +1, +0, +6, +0, +7, +6, +1, +5, +2, +1, +6, +4, +2, +1, +2, +0, +3, +7, +4, +4, +0, +0, +1, +3, +0, +6, +3, +2, +2, +1, +7, +1, +0, +3, +4, +3, +4, +0, +5, +3, +4, +3, +1, +2, +0, +5, +3, +2, +2, +6, +5, +5, +4, +0, +1, +0, +4, +7, +3, +0, +1, +3, +3, +1, +4, +5, +1, +0, +2, +4, +4, +0, +4, +5, +6, +3, +0, +4, +7, +6, +7, +7, +5, +6, +3, +3, +2, +2, +6, +7, +0, +7, +1, +7, +2, +7, +5, +0, +7, +4, +1, +3, +3, +5, +7, +4, +0, +5, +1, +7, +1, +6, +0, +2, +1, +7, +6, +3, +4, +5, +7, +7, +7, +7, +7, +0, +3, +2, +2, +5, +6, +7, +4, +0, +2, +7, +3, +6, +4, +4, +5, +5, +5, +6, +5, +7, +6, +6, +6, +3, +1, +0, +2, +3, +6, +6, +6, +5, +7, +6, +6, +1, +2, +2, +0, +2, +4, +5, +4, +1, +3, +7, +5, +5, +2, +5, +0, +2, +4, +4, +6, +5, +2, +1, +4, +7, +3, +4, +0, +3, +6, +3, +3, +7, +6, +5, +1, +4, +7, +7, +2, +7, +3, +1, +7, +4, +7, +3, +2, +3, +2, +5, +7, +0, +3, +5, +0, +3, +1, +2, +2, +5, +2, +5, +5, +1, +2, +5, +7, +1, +3, +4, +3, +5, +7, +7, +3, +6, +4, +5, +1, +1, +0, +0, +3, +7, +3, +6, +0, +2, +0, +5, +7, +3, +3, +2, +2, +4, +4, +0, +1, +1, +6, +5, +6, +4, +7, +1, +2, +7, +7, +4, +6, +0, +3, +1, +2, +7, +6, +4, +5, +7, +3, +4, +4, +1, +5, +7, +5, +7, +6, +7, +4, +0, +0, +4, +4, +6, +3, +0, +4, +6, +3, +5, +1, +7, +3, +0, +4, +2, +2, +1, +3, +6, +5, +3, +4, +1, +3, +0, +0, +1, +4, +0, +5, +5, +5, +4, +1, +5, +4, +4, +4, +6, +4, +5, +5, +2, +3, +1, +4, +1, +1, +6, +2, +0, +2, +6, +1, +0, +2, +2, +3, +7, +2, +1, +1, +6, +7, +2, +7, +6, +6, +6, +1, +6, +6, +2, +6, +3, +1, +1, +4, +5, +7, +3, +1, +4, +7, +0, +6, +7, +5, +0, +5, +2, +1, +1, +5, +6, +3, +0, +1, +6, +7, +5, +4, +2, +1, +3, +1, +5, +6, +6, +4, +0, +2, +6, +7, +7, +7, +0, +1, +2, +4, +5, +5, +6, +6, +2, +7, +7, +2, +3, +5, +4, +6, +4, +2, +1, +3, +7, +4, +0, +6, +1, +1, +2, +3, +1, +4, +4, +3, +5, +1, +3, +1, +7, +1, +1, +1, +6, +6, +1, +2, +3, +4, +3, +6, +4, +3, +4, +7, +4, +1, +6, +0, +4, +7, +2, +4, +5, +2, +7, +4, +6, +4, +6, +0, +7, +7, +6, +0, +4, +4, +1, +7, +1, +1, +3, +6, +5, +0, +3, +6, +3, +2, +5, +7, +6, +0, +5, +5, +1, +1, +1, +5, +1, +1, +3, +6, +6, +7, +7, +0, +7, +4, +5, +2, +7, +4, +2, +2, +3, +3, +2, +1, +4, +5, +1, +2, +2, +5, +6, +5, +3, +2, +4, +4, +3, +2, +7, +5, +2, +0, +7, +0, +2, +6, +6, +5, +1, +0, +2, +4, +1, +5, +3, +1, +2, +7, +5, +6, +3, +4, +4, +1, +2, +6, +4, +0, +5, +3, +4, +0, +6, +6, +6, +4, +6, +4, +5, +1, +6, +6, +3, +4, +2, +7, +7, +3, +3, +4, +4, +6, +0, +2, +5, +6, +7, +1, +7, +1, +1, +4, +7, +2, +2, +3, +3, +1, +7, +5, +0, +7, +3, +4, +5, +1, +7, +5, +6, +4, +0, +1, +7, +6, +0, +2, +5, +2, +5, +3, +0, +3, +5, +3, +1, +6, +5, +3, +1, +2, +5, +4, +6, +3, +6, +6, +7, +3, +0, +3, +3, +5, +7, +5, +1, +4, +6, +6, +0, +1, +3, +4, +0, +2, +4, +2, +2, +1, +5, +1, +3, +3, +1, +5, +7, +0, +7, +0, +4, +2, +4, +2, +7, +4, +3, +4, +1, +0, +1, +6, +2, +2, +3, +4, +0, +5, +0, +1, +5, +6, +1, +3, +7, +3, +1, +2, +5, +0, +7, +6, +7, +7, +5, +1, +5, +7, +6, +1, +1, +6, +1, +0, +6, +7, +5, +1, +1, +6, +3, +7, +0, +5, +7, +0, +4, +0, +7, +7, +7, +4, +0, +5, +3, +0, +0, +0, +4, +1, +2, +4, +2, +6, +1, +5, +1, +5, +3, +0, +2, +0, +6, +3, +4, +5, +0, +7, +3, +0, +1, +6, +5, +1, +3, +3, +2, +2, +7, +6, +0, +1, +1, +1, +0, +0, +1, +2, +5, +2, +3, +6, +7, +0, +3, +2, +1, +5, +5, +6, +6, +3, +4, +3, +1, +5, +6, +4, +2, +2, +7, +1, +0, +3, +1, +1, +1, +0, +6, +4, +0, +6, +6, +6, +0, +4, +4, +5, +3, +3, +1, +0, +2, +5, +6, +6, +4, +1, +7, +3, +0, +3, +4, +0, +3, +2, +3, +7, +4, +0, +1, +0, +5, +0, +5, +2, +7, +4, +3, +5, +6, +5, +3, +3, +0, +3, +4, +5, +0, +6, +4, +7, +1, +2, +2, +1, +7, +1, +3, +4, +7, +7, +3, +2, +2, +0, +2, +7, +5, +5, +3, +3, +7, +5, +7, +0, +4, +0, +5, +2, +3, +5, +0, +3, +6, +7, +2, +6, +2, +4, +6, +0, +4, +1, +5, +4, +2, +0, +0, +5, +5, +6, +6, +4, +7, +5, +6, +3, +7, +3, +2, +0, +6, +3, +5, +2, +5, +1, +0, +3, +7, +1, +3, +7, +2, +7, +2, +1, +1, +7, +6, +0, +4, +5, +3, +5, +1, +6, +4, +0, +7, +2, +1, +3, +7, +5, +0, +1, +2, +6, +4, +1, +0, +6, +0, +5, +7, +1, +5, +3, +6, +7, +0, +4, +5, +1, +5, +3, +4, +3, +4, +6, +7, +7, +4, +1, +0, +2, +4, +2, +1, +2, +1, +6, +3, +2, +2, +2, +1, +4, +1, +2, +4, +6, +4, +7, +0, +0, +1, +0, +4, +6, +2, +1, +1, +3, +5, +3, +3, +2, +4, +0, +1, +5, +6, +2, +4, +3, +4, +4, +3, +5, +3, +6, +6, +6, +5, +0, +5, +2, +5, +3, +0, +4, +7, +5, +0, +4, +4, +2, +2, +4, +2, +1, +1, +1, +6, +0, +4, +0, +3, +1, +0, +4, +6, +1, +6, +0, +2, +1, +0, +2, +7, +4, +0, +0, +3, +7, +0, +5, +5, +6, +6, +7, +6, +3, +2, +6, +7, +6, +6, +2, +0, +6, +7, +7, +4, +1, +7, +7, +6, +0, +5, +6, +7, +3, +3, +6, +0, +5, +3, +7, +6, +2, +2, +1, +1, +5, +4, +0, +4, +7, +2, +4, +5, +7, +4, +6, +3, +7, +7, +2, +2, +4, +0, +1, +0, +7, +4, +0, +2, +6, +3, +5, +3, +3, +4, +4, +1, +4, +2, +2, +2, +0, +6, +6, +3, +7, +4, +5, +0, +1, +3, +1, +7, +2, +6, +2, +6, +2, +4, +2, +5, +6, +1, +2, +1, +3, +5, +5, +4, +0, +2, +0, +4, +6, +1, +2, +1, +5, +6, +4, +0, +0, +1, +0, +1, +1, +5, +7, +7, +1, +4, +5, +4, +0, +0, +2, +2, +4, +3, +5, +6, +7, +6, +0, +4, +6, +1, +7, +4, +3, +6, +7, +4, +4, +7, +1, +4, +5, +0, +3, +0, +3, +4, +6, +0, +7, +5, +2, +6, +6, +1, +0, +0, +6, +0, +0, +6, +5, +5, +0, +7, +6, +2, +7, +6, +2, +2, +2, +3, +7, +1, +0, +5, +5, +0, +7, +7, +5, +5, +3, +3, +2, +3, +0, +1, +4, +6, +2, +1, +2, +0, +7, +6, +2, +6, +6, +3, +3, +7, +6, +5, +0, +1, +4, +4, +3, +6, +3, +0, +7, +5, +5, +5, +2, +6, +3, +0, +1, +7, +1, +7, +0, +1, +6, +3, +5, +2, +1, +4, +1, +5, +3, +1, +1, +3, +2, +4, +0, +7, +7, +0, +7, +1, +2, +7, +0, +4, +7, +3, +5, +3, +4, +6, +2, +3, +0, +0, +3, +5, +5, +1, +0, +4, +7, +3, +6, +0, +4, +7, +1, +0, +5, +1, +1, +7, +7, +1, +1, +5, +6, +7, +5, +5, +5, +1, +4, +7, +0, +7, +2, +0, +1, +2, +3, +0, +3, +1, +3, +2, +3, +2, +0, +1, +2, +6, +4, +7, +4, +1, +5, +4, +3, +2, +6, +2, +4, +5, +7, +3, +7, +3, +5, +0, +0, +5, +5, +4, +0, +4, +5, +2, +3, +2, +5, +6, +1, +4, +4, +4, +6, +7, +7, +4, +2, +4, +3, +5, +4, +3, +3, +6, +3, +5, +6, +6, +6, +6, +4, +2, +5, +7, +1, +5, +1, +3, +6, +1, +1, +1, +3, +6, +6, +2, +3, +0, +1, +6, +5, +4, +4, +0, +3, +3, +0, +0, +4, +7, +1, +6, +4, +3, +7, +1, +0, +5, +0, +0, +5, +5, +1, +1, +1, +3, +7, +4, +5, +5, +2, +0, +2, +5, +1, +4, +6, +2, +0, +7, +4, +5, +5, +4, +6, +5, +7, +7, +4, +4, +1, +1, +5, +3, +0, +4, +5, +7, +0, +5, +2, +6, +6, +1, +6, +2, +3, +2, +2, +2, +3, +6, +1, +1, +6, +3, +2, +4, +5, +1, +6, +4, +5, +7, +5, +7, +2, +6, +3, +4, +1, +6, +3, +4, +7, +2, +0, +3, +5, +6, +3, +0, +5, +6, +7, +0, +6, +6, +3, +6, +2, +3, +0, +6, +3, +3, +4, +4, +6, +7, +5, +0, +4, +5, +5, +1, +4, +5, +3, +0, +7, +1, +5, +4, +6, +3, +4, +6, +3, +1, +5, +6, +5, +5, +7, +0, +5, +4, +3, +6, +5, +3, +5, +1, +1, +7, +6, +6, +2, +1, +1, +1, +1, +2, +1, +4, +5, +0, +4, +1, +4, +4, +5, +4, +7, +4, +5, +3, +5, +3, +6, +0, +2, +7, +3, +1, +4, +0, +1, +7, +1, +3, +3, +1, +1, +7, +4, +4, +1, +6, +1, +4, +3, +2, +7, +0, +6, +0, +3, +5, +2, +3, +1, +3, +6, +0, +0, +5, +4, +3, +5, +6, +4, +5, +1, +1, +6, +4, +7, +2, +4, +3, +7, +2, +6, +5, +1, +7, +5, +4, +1, +6, +0, +4, +2, +1, +1, +5, +1, +6, +2, +2, +7, +1, +0, +3, +2, +2, +2, +3, +1, +2, +4, +1, +0, +2, +4, +7, +5, +2, +2, +6, +1, +5, +6, +6, +3, +0, +6, +6, +0, +5, +7, +4, +3, +2, +1, +4, +5, +4, +1, +4, +3, +2, +7, +0, +4, +2, +6, +6, +3, +0, +2, +6, +1, +0, +2, +0, +1, +5, +0, +1, +4, +0, +2, +5, +1, +4, +2, +4, +4, +4, +6, +0, +1, +4, +5, +6, +5, +4, +5, +6, +7, +3, +3, +5, +4, +4, +2, +2, +1, +2, +4, +1, +3, +7, +3, +2, +5, +2, +0, +5, +7, +3, +3, +4, +6, +2, +4, +2, +4, +7, +2, +0, +0, +1, +1, +1, +2, +2, +7, +5, +1, +3, +3, +5, +7, +1, +7, +4, +7, +3, +3, +0, +6, +6, +5, +4, +7, +7, +2, +7, +1, +7, +2, +7, +2, +2, +7, +5, +2, +2, +2, +1, +1, +2, +6, +7, +1, +5, +6, +2, +4, +6, +5, +1, +7, +6, +5, +4, +4, +0, +0, +0, +2, +5, +6, +3, +0, +3, +2, +5, +5, +5, +4, +2, +3, +6, +2, +0, +7, +1, +0, +0, +4, +6, +4, +7, +1, +4, +3, +7, +7, +7, +4, +1, +5, +6, +2, +5, +7, +0, +3, +1, +4, +4, +4, +6, +4, +7, +3, +1, +6, +2, +0, +1, +7, +5, +2, +6, +5, +1, +7, +1, +6, +5, +7, +3, +1, +2, +3, +5, +2, +1, +6, +1, +5, +6, +7, +2, +3, +6, +5, +6, +4, +7, +2, +1, +0, +2, +0, +2, +6, +5, +7, +0, +2, +2, +7, +1, +7, +7, +5, +7, +2, +4, +4, +4, +3, +2, +5, +3, +5, +3, +6, +5, +7, +1, +7, +4, +7, +3, +7, +6, +3, +4, +4, +5, +7, +4, +3, +0, +2, +1, +0, +2, +6, +3, +2, +7, +0, +7, +4, +2, +0, +7, +1, +1, +6, +7, +3, +0, +5, +3, +5, +7, +2, +6, +0, +6, +7, +0, +3, +3, +2, +4, +6, +5, +1, +6, +3, +4, +3, +1, +2, +7, +2, +5, +2, +1, +4, +7, +7, +4, +6, +2, +0, +2, +5, +0, +7, +3, +1, +1, +2, +2, +6, +0, +0, +4, +0, +1, +1, +4, +0, +1, +4, +7, +7, +6, +6, +4, +1, +2, +5, +7, +3, +1, +6, +5, +5, +1, +1, +2, +4, +2, +3, +7, +1, +1, +1, +7, +1, +0, +0, +3, +5, +7, +0, +2, +7, +1, +2, +2, +3, +5, +3, +7, +4, +1, +7, +4, +0, +3, +0, +0, +4, +2, +3, +0, +5, +5, +7, +0, +1, +4, +0, +4, +1, +2, +2, +3, +0, +3, +6, +4, +6, +1, +4, +0, +4, +7, +0, +5, +5, +0, +2, +6, +6, +6, +6, +0, +5, +5, +0, +1, +6, +3, +3, +3, +7, +6, +7, +0, +4, +1, +0, +3, +2, +5, +1, +3, +1, +5, +7, +2, +3, +5, +6, +2, +7, +3, +5, +0, +3, +4, +2, +1, +3, +7, +7, +6, +3, +2, +7, +3, +4, +7, +6, +0, +4, +4, +3, +1, +2, +2, +6, +5, +5, +3, +1, +5, +7, +5, +0, +4, +0, +3, +2, +3, +6, +0, +2, +2, +1, +2, +3, +3, +6, +7, +3, +2, +6, +5, +6, +4, +3, +0, +3, +3, +5, +0, +7, +6, +7, +2, +7, +4, +4, +4, +4, +0, +2, +7, +6, +5, +3, +4, +1, +0, +3, +2, +5, +1, +4, +7, +4, +0, +6, +6, +1, +0, +3, +3, +0, +2, +4, +4, +0, +7, +2, +7, +3, +0, +6, +1, +5, +2, +4, +3, +2, +7, +1, +3, +2, +2, +2, +7, +6, +1, +6, +5, +3, +2, +6, +0, +2, +7, +1, +4, +4, +4, +7, +1, +3, +4, +2, +3, +3, +3, +2, +3, +2, +1, +5, +7, +4, +0, +5, +7, +3, +0, +0, +5, +3, +4, +5, +6, +5, +4, +6, +0, +6, +6, +1, +1, +6, +7, +3, +6, +0, +0, +2, +3, +0, +1, +2, +3, +7, +5, +6, +5, +7, +2, +3, +3, +6, +2, +3, +6, +6, +7, +2, +2, +3, +1, +5, +4, +5, +0, +1, +2, +6, +0, +3, +6, +2, +6, +1, +3, +2, +4, +1, +3, +3, +7, +1, +5, +6, +4, +5, +3, +4, +6, +1, +7, +5, +3, +3, +0, +7, +4, +3, +4, +4, +3, +7, +6, +1, +0, +0, +1, +3, +2, +2, +5, +0, +7, +4, +0, +3, +1, +3, +0, +4, +5, +6, +2, +4, +4, +1, +0, +4, +2, +5, +7, +7, +6, +3, +6, +6, +7, +6, +2, +3, +0, +5, +3, +1, +2, +3, +5, +5, +7, +6, +1, +5, +0, +7, +6, +7, +7, +6, +6, +6, +0, +7, +2, +3, +6, +6, +2, +0, +3, +6, +6, +0, +7, +5, +0, +4, +1, +2, +3, +1, +6, +3, +3, +4, +5, +3, +2, +5, +4, +3, +5, +0, +0, +3, +3, +0, +3, +6, +7, +2, +3, +7, +5, +1, +6, +6, +4, +0, +0, +0, +3, +6, +7, +2, +7, +2, +3, +2, +7, +0, +3, +4, +4, +3, +0, +6, +2, +6, +7, +5, +1, +2, +1, +6, +3, +5, +7, +1, +0, +1, +6, +0, +3, +3, +5, +7, +1, +1, +5, +0, +4, +6, +6, +1, +2, +5, +1, +7, +3, +3, +1, +5, +0, +0, +7, +4, +2, +7, +1, +4, +6, +6, +1, +0, +0, +4, +7, +7, +3, +4, +1, +3, +6, +2, +7, +1, +4, +4, +0, +3, +7, +7, +3, +3, +7, +1, +4, +6, +2, +2, +1, +0, +0, +5, +0, +6, +5, +0, +1, +6, +5, +3, +4, +5, +7, +7, +5, +6, +3, +5, +4, +7, +6, +5, +7, +2, +3, +2, +0, +3, +6, +0, +3, +1, +0, +1, +1, +4, +4, +2, +1, +7, +4, +3, +7, +7, +0, +7, +3, +4, +3, +5, +2, +0, +0, +5, +6, +6, +6, +0, +6, +6, +5, +6, +0, +1, +0, +7, +6, +6, +5, +5, +0, +3, +5, +2, +4, +0, +2, +2, +7, +7, +2, +4, +6, +7, +1, +5, +4, +3, +7, +4, +1, +3, +0, +5, +5, +0, +5, +6, +6, +5, +5, +0, +5, +2, +6, +0, +0, +5, +1, +4, +3, +5, +1, +4, +1, +4, +5, +5, +3, +0, +5, +2, +7, +3, +5, +4, +1, +0, +2, +6, +1, +1, +1, +1, +2, +0, +3, +0, +5, +6, +4, +2, +7, +6, +1, +4, +6, +1, +4, +2, +3, +1, +2, +5, +4, +2, +1, +7, +5, +6, +5, +1, +6, +4, +7, +6, +1, +5, +7, +3, +2, +2, +6, +4, +0, +1, +3, +0, +2, +4, +4, +6, +4, +7, +2, +7, +2, +2, +6, +4, +6, +7, +7, +0, +6, +7, +5, +7, +3, +4, +0, +0, +1, +1, +5, +2, +5, +2, +2, +0, +7, +0, +2, +2, +6, +5, +7, +3, +6, +2, +6, +5, +2, +4, +7, +7, +2, +1, +0, +1, +6, +3, +1, +0, +0, +6, +1, +1, +7, +7, +1, +5, +3, +7, +4, +5, +2, +1, +7, +3, +3, +0, +6, +3, +3, +2, +7, +6, +7, +2, +0, +4, +2, +3, +0, +0, +0, +4, +1, +0, +1, +0, +7, +1, +0, +5, +2, +7, +3, +4, +3, +6, +7, +4, +5, +6, +6, +3, +1, +7, +1, +2, +6, +5, +2, +0, +3, +4, +1, +0, +0, +4, +5, +7, +0, +6, +2, +2, +4, +4, +2, +1, +7, +5, +1, +5, +2, +6, +3, +5, +1, +2, +2, +4, +7, +4, +1, +5, +1, +5, +3, +4, +4, +5, +5, +7, +4, +3, +7, +3, +2, +2, +2, +1, +1, +0, +0, +1, +5, +1, +6, +0, +2, +0, +6, +4, +4, +1, +1, +5, +2, +1, +4, +5, +5, +2, +3, +1, +7, +2, +0, +5, +0, +7, +4, +2, +0, +3, +5, +4, +7, +4, +5, +5, +0, +0, +0, +2, +3, +5, +3, +7, +2, +4, +6, +7, +2, +1, +6, +3, +1, +1, +0, +7, +4, +4, +4, +4, +7, +2, +1, +3, +5, +1, +5, +2, +4, +2, +4, +1, +1, +2, +0, +0, +7, +5, +4, +2, +2, +1, +6, +6, +3, +5, +7, +7, +6, +1, +7, +3, +5, +6, +5, +4, +2, +0, +3, +3, +4, +3, +7, +3, +6, +2, +0, +0, +2, +3, +2, +6, +0, +4, +2, +4, +2, +1, +7, +6, +3, +5, +4, +0, +0, +1, +2, +7, +3, +0, +5, +1, +1, +3, +6, +2, +2, +6, +5, +7, +3, +7, +1, +6, +1, +2, +5, +7, +3, +6, +0, +0, +4, +1, +1, +6, +1, +0, +2, +3, +3, +3, +5, +1, +1, +7, +7, +5, +1, +2, +0, +2, +2, +1, +0, +2, +2, +6, +2, +0, +7, +7, +0, +6, +0, +3, +3, +6, +4, +4, +0, +5, +0, +7, +0, +7, +2, +0, +1, +5, +4, +0, +2, +0, +7, +0, +0, +5, +5, +5 diff --git a/gr-atsc/src/lib/qa_atsci_viterbi_decoder.cc b/gr-atsc/src/lib/qa_atsci_viterbi_decoder.cc new file mode 100644 index 000000000..5cc329787 --- /dev/null +++ b/gr-atsc/src/lib/qa_atsci_viterbi_decoder.cc @@ -0,0 +1,178 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <cppunit/TestAssert.h> +#include <qa_atsci_viterbi_decoder.h> +#include <qa_atsci_trellis_encoder.h> +#include <cstdio> +#include <string.h> +#include <stdlib.h> +#include <time.h> + +#define NELEM(x) (sizeof (x) / sizeof (x[0])) + + +static const int NCODERS = atsci_viterbi_decoder::NCODERS; + +#if 0 +static void +map_to_soft_symbols (atsc_soft_data_segment &out, + const atsc_data_segment &in) +{ + for (unsigned int i = 0; i < NELEM (in.data); i++){ + out.data[i] = in.data[i] * 2 - 7; + } +} +#endif + +static void +pad_decoder_input (atsc_soft_data_segment out[NCODERS]) +{ + memset (out, 0, sizeof (out)); + + // add data segment sync + for (int i = 0; i < NCODERS; i++){ + out[i].data[0] = 5; + out[i].data[1] = -5; + out[i].data[2] = -5; + out[i].data[3] = 5; + out[i].pli.set_regular_seg (false, i); + } +} + +void +qa_atsci_viterbi_decoder::t0 () +{ +#if 0 + atsci_trellis_encoder enc; + atsc_mpeg_packet_rs_encoded encoder_in[NCODERS]; + atsc_data_segment encoder_out[NCODERS]; + atsc_soft_data_segment decoder_in[NCODERS]; + atsc_soft_data_segment decoder_in_pad[NCODERS]; + atsc_mpeg_packet_rs_encoded decoder_out[NCODERS]; + atsc_mpeg_packet_rs_encoded decoder_out_pad[NCODERS]; + + + memset (encoder_in, 0, sizeof (encoder_in)); + memset (encoder_out, 0, sizeof (encoder_out)); + memset (decoder_out_pad, 0, sizeof (decoder_out_pad)); + + srandom (1); + + for (int i = 0; i < NCODERS; i++){ + for (unsigned int j = 0; j < NELEM (encoder_in[i].data); j++){ + int t = (random () >> 8) & 0xff; // 8 random bits + encoder_in[i].data[j] = t; + } + } + + fflush (stdout); + printf ("@@@ ENCODER INPUT @@@\n"); + for (int i = 0; i < NCODERS; i++){ + for (unsigned int j = 0; j < NELEM (encoder_in[i].data); j++){ + printf ("%d\n", encoder_in[i].data[j]); + } + } + + enc.reset (); + enc.encode (encoder_out, encoder_in); + + printf ("@@@ ENCODER OUTPUT @@@\n"); + for (int i = 0; i < NCODERS; i++){ + for (unsigned int j = 0; j < NELEM (encoder_out[i].data); j++){ + printf ("%d\n", encoder_out[i].data[j]); + } + } + + for (int i = 0; i < NCODERS; i++) + map_to_soft_symbols (decoder_in[i], encoder_out[i]); + + viterbi.reset (); + + // this has only the previous (non-existant) output + viterbi.decode (decoder_out_pad, decoder_in); + + // now we'll see the real output + pad_decoder_input (decoder_in_pad); + viterbi.decode (decoder_out, decoder_in_pad); + + printf ("@@@ DECODER OUTPUT @@@\n"); + for (int i = 0; i < NCODERS; i++){ + for (unsigned int j = 0; j < NELEM (decoder_out[i].data); j++){ + printf ("%d\n", decoder_out[i].data[j]); + } + } + fflush (stdout); +#endif +} + +void +qa_atsci_viterbi_decoder::t1 () +{ + atsc_soft_data_segment decoder_in[NCODERS]; + atsc_soft_data_segment decoder_in_pad[NCODERS]; + atsc_mpeg_packet_rs_encoded decoder_out[NCODERS]; + atsc_mpeg_packet_rs_encoded decoder_out_pad[NCODERS]; + atsc_mpeg_packet_rs_encoded expected_out[NCODERS]; + static const float raw_input[NCODERS * NELEM (decoder_in[0].data)] = { +#include "qa_atsci_viterbi_decoder_t1_input.dat" + }; + static const unsigned char raw_output[NCODERS * NELEM (expected_out[0].data)] = { +#include "qa_atsci_viterbi_decoder_t1_output.dat" + }; + + + // load up input + const float *ri = &raw_input[0]; + for (int i = 0; i < NCODERS; i++){ + for (unsigned int j = 0; j < NELEM (decoder_in[i].data); j++){ + decoder_in[i].data[j] = *ri++; + } + decoder_in[i].pli.set_regular_seg (false, i); + } + + // load up expected output + const unsigned char *ro = &raw_output[0]; + for (int i = 0; i < NCODERS; i++){ + for (unsigned int j = 0; j < NELEM (expected_out[i].data); j++){ + expected_out[i].data[j] = *ro++; + } + expected_out[i].pli.set_regular_seg (false, i); + } + + viterbi.reset (); + + // this has only the previous (non-existant) output + viterbi.decode (decoder_out_pad, decoder_in); + + // now we'll see the real output + pad_decoder_input (decoder_in_pad); + viterbi.decode (decoder_out, decoder_in_pad); + + for (int i = 0; i < NCODERS; i++){ // check the result + CPPUNIT_ASSERT (expected_out[i] == decoder_out[i]); + } +} diff --git a/gr-atsc/src/lib/qa_atsci_viterbi_decoder.h b/gr-atsc/src/lib/qa_atsci_viterbi_decoder.h new file mode 100644 index 000000000..78b57de98 --- /dev/null +++ b/gr-atsc/src/lib/qa_atsci_viterbi_decoder.h @@ -0,0 +1,54 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _QA_ATSC_VITERBI_DECODER_H_ +#define _QA_ATSC_VITERBI_DECODER_H_ + +#include <cppunit/extensions/HelperMacros.h> +#include <cppunit/TestCase.h> + +#include <stdio.h> +#include <atsci_viterbi_decoder.h> + +class qa_atsci_viterbi_decoder : public CppUnit::TestCase { + + public: + + void setUp (void) + { + viterbi.reset (); + } + + CPPUNIT_TEST_SUITE (qa_atsci_viterbi_decoder); + CPPUNIT_TEST (t0); + CPPUNIT_TEST (t1); + CPPUNIT_TEST_SUITE_END (); + + private: + atsci_viterbi_decoder viterbi; + + void t0 (); + void t1 (); +}; + + +#endif /* _QA_ATSC_VITERBI_DECODER_H_ */ diff --git a/gr-atsc/src/lib/qa_atsci_viterbi_decoder_t1_input.dat b/gr-atsc/src/lib/qa_atsci_viterbi_decoder_t1_input.dat new file mode 100644 index 000000000..b2f356c87 --- /dev/null +++ b/gr-atsc/src/lib/qa_atsci_viterbi_decoder_t1_input.dat @@ -0,0 +1,9984 @@ + 5 + -0.863407, + -5 + 0.630254, + -5 + 0.766777, + 5 + -0.587788, + -3 + 0.197374, + -7 + -0.928392, + 1 + 0.846137, + -3 + -0.148515, + 5 + 0.20529, + -3 + 0.957658, + 1 + 0.712777, + -3 + -0.783731, + -7 + -0.649688, + -3 + 0.364183, + -3 + 0.766379, + 5 + -0.254228, + -5 + 0.265344, + 1 + -0.0926997, + 5 + -0.729882, + -5 + -0.946608, + 7 + 0.941424, + -1 + 0.00502258, + 5 + 0.353994, + -1 + -0.431315, + -3 + 0.802947, + 7 + 0.0174765, + -1 + 0.107732, + 7 + -0.426013, + -3 + 0.179269, + 1 + -0.334729, + -5 + 0.363112, + 1 + -0.793512, + -1 + -0.386831, + 7 + -0.469307, + 7 + -0.592471, + 3 + -0.0650877, + 7 + 0.465307, + -1 + 0.0575076, + 3 + 0.804467, + 7 + 0.766673, + -3 + 0.177288, + -3 + 0.254259, + -7 + 0.0933109, + 3 + -0.132741, + -7 + 0.226975, + 1 + 0.805, + 3 + 0.474327, + 3 + -0.147847, + -1 + 0.3179, + -7 + -0.141455, + 3 + 0.322113, + -3 + 0.633945, + -1 + -0.950742, + -5 + -0.39542, + 3 + -0.0594983, + -3 + -0.772717, + -5 + 0.545784, + 7 + 0.398416, + 3 + -0.673597, + 3 + -0.790352, + -7 + -0.544624, + 7 + -0.633903, + -1 + -0.908654, + -3 + -0.311397, + -5 + 0.662512, + -3 + -0.135222, + -7 + 0.366291, + 1 + -0.741085, + -7 + -0.29157, + -5 + -0.673842, + 3 + 0.776452, + -5 + -0.0937042, + 3 + 0.683802, + -5 + -0.722854, + -7 + 0.0347072, + -5 + 0.40685, + -5 + 0.31874, + 5 + -0.947299, + 3 + -0.955457, + 1 + 0.742103, + -5 + -0.535021, + -5 + -0.67394, + -5 + -0.108192, + -1 + -0.968649, + 1 + 0.445698, + 3 + -0.476884, + 7 + 0.566045, + -7 + -0.137864, + -1 + -0.190159, + -5 + -0.0220287, + 5 + 0.307356, + 5 + 0.917233, + -7 + 0.320761, + 3 + -0.789388, + -5 + 0.117822, + 5 + -0.604396, + -1 + 0.552753, + 7 + -0.446649, + 7 + -0.810118, + 7 + -0.658175, + -7 + 0.553164, + -7 + -0.344854, + -3 + 0.280593, + 7 + -0.884303, + 7 + 0.720506, + -1 + -0.987799, + 7 + 0.793155, + 1 + -0.850125, + 7 + 0.115369, + 5 + 0.544406, + 5 + -0.276058, + -1 + -0.231108, + -5 + 0.376881, + 3 + -0.559075, + 7 + -0.915446, + -1 + -0.460641, + 3 + 0.818044, + -3 + -0.991244, + 1 + 0.420497, + 1 + 0.485863, + -3 + -0.376003, + 5 + -0.350986, + 5 + 0.430744, + -3 + 0.463798, + 5 + 0.42518, + 5 + -0.290836, + -5 + -0.691567, + -7 + 0.824346, + 3 + 0.450636, + -3 + 0.043629, + 7 + 0.316293, + 5 + -0.120924, + 1 + 0.726472, + -1 + -0.543775, + 3 + 0.933344, + -3 + 0.132114, + -3 + -0.310619, + 5 + 0.911921, + -1 + -0.497207, + 3 + -0.637383, + -5 + -0.732262, + 7 + 0.107649, + 3 + 0.520015, + -1 + 0.157455, + -3 + -0.894858, + -1 + 0.0945327, + 1 + -0.691426, + 7 + 0.144207, + 3 + 0.445607, + -1 + 0.255407, + -7 + 0.306034, + -3 + -0.371352, + -1 + 0.124452, + -5 + 0.359695, + -5 + -0.888643, + 3 + 0.290357, + 3 + -0.0254667, + -3 + 0.407853, + -5 + 0.679174, + -5 + 0.0575717, + -3 + 0.137283, + 3 + 0.729587, + 7 + 0.31509, + -3 + -0.348804, + 1 + 0.57604, + -5 + 0.345748, + 7 + -0.327496, + -5 + -0.425651, + -7 + 0.140657, + -3 + 0.238764, + -7 + -0.143133, + 3 + 0.337288, + 1 + 0.959842, + 7 + -0.977864, + 3 + -0.317419, + 3 + -0.198654, + 3 + 0.955435, + 3 + -0.23876, + 1 + -0.88292, + -5 + -0.511151, + 3 + 0.779996, + 3 + -0.443377, + -1 + -0.192438, + -5 + 0.811447, + -7 + 0.634155, + 1 + -0.762404, + 3 + 0.731365, + 5 + 0.783236, + 5 + -0.307317, + 7 + 0.482175, + 7 + -0.539608, + 7 + -0.775192, + 1 + -0.560785, + -7 + 0.206625, + -5 + -0.038118, + -5 + -0.228189, + 1 + 0.462362, + -5 + 0.72833, + -1 + 0.622996, + -3 + 0.998274, + 5 + 0.142163, + -7 + 0.618011, + 3 + 0.122273, + -7 + -0.483532, + -1 + -0.854097, + -5 + 0.108088, + 7 + -0.193228, + 3 + 0.648767, + -3 + -0.656924, + -7 + -0.991222, + -3 + -0.25652, + 3 + -0.269033, + -1 + 0.324665, + -1 + 0.107827, + -5 + -0.0475933, + -5 + -0.99274, + -5 + -0.30318, + -3 + -0.747831, + -3 + -0.203781, + 3 + -0.010757, + 7 + 0.0734757, + 7 + -0.761203, + -7 + 0.389509, + 1 + -0.25976, + -1 + 0.965806, + 7 + 0.526324, + -1 + -0.298331, + -3 + 0.410725, + -1 + 0.00752225, + 5 + -0.455632, + 1 + -0.884761, + 7 + 0.602377, + 7 + 0.555917, + 3 + -0.160695, + -7 + -0.567533, + 3 + 0.758232, + 1 + -0.587694, + -7 + 0.414466, + -7 + -0.652491, + 1 + 0.0124494, + -7 + 0.389889, + 7 + 0.227003, + 1 + 0.242753, + -7 + 0.913462, + -3 + 0.691642, + -5 + 0.75989, + 1 + -0.596777, + -3 + -0.752662, + 3 + -0.108642, + 7 + -0.60189, + 7 + 0.511322, + -3 + -0.24478, + 7 + -0.849058, + -1 + -0.845527, + -7 + -0.572068, + -5 + -0.661012, + 5 + -0.701889, + 7 + 0.822228, + 1 + -0.00200901, + 5 + -0.71468, + 5 + 0.691151, + 7 + 0.561903, + 3 + -0.527991, + -1 + -0.867353, + 3 + -0.728324, + 5 + -0.813234, + 1 + -0.966217, + 1 + 0.0669532, + 7 + 0.905965, + -3 + -0.937283, + -3 + 0.774056, + 3 + -0.384885, + -7 + 0.175322, + -3 + 0.309913, + -5 + 0.251167, + -1 + 0.381753, + 3 + 0.00625176, + -7 + 0.56373, + -3 + 0.63392, + 3 + 0.762169, + 7 + 0.0347039, + -3 + -0.935108, + -1 + -0.114944, + 1 + -0.424213, + 1 + 0.0317198, + -3 + 0.2139, + -5 + 0.0530905, + -7 + -0.36603, + -5 + -0.851717, + -7 + 0.414219, + -1 + -0.397429, + -3 + -0.995697, + -7 + -0.328063, + -1 + -0.604664, + 7 + -0.45941, + 3 + 0.718596, + -7 + -0.377836, + -1 + 0.915331, + 7 + -0.730175, + -1 + -0.51083, + 7 + -0.923481, + 1 + 0.102495, + -1 + 0.1293, + -3 + 0.812872, + -5 + 0.066343, + -1 + -0.578684, + 1 + 0.926482, + -7 + 0.10389, + 5 + -0.462554, + -5 + -0.108, + 5 + -0.471902, + 7 + -0.34884, + 5 + 0.719192, + -7 + -0.763765, + -3 + 0.257366, + -5 + -0.623314, + -7 + 0.0467943, + 5 + -0.646451, + 7 + 0.54531, + 3 + -0.955682, + -5 + -0.432122, + 3 + -0.886357, + 1 + 0.088559, + 5 + -0.975894, + 5 + -0.105386, + -3 + 0.0978638, + 1 + -0.199998, + 5 + 0.0380346, + 3 + 0.427315, + -3 + 0.214304, + -5 + -0.566543, + -7 + -0.380715, + -3 + -0.877135, + -5 + 0.267701, + -3 + -0.03107, + -3 + 0.595488, + -1 + 0.322574, + -5 + 0.559362, + 1 + -0.0401364, + -7 + 0.528057, + 5 + -0.319427, + -1 + 0.357237, + 7 + 0.222854, + -5 + -0.432566, + 1 + -0.998243, + 7 + 0.742835, + 3 + -0.182255, + 3 + -0.471161, + 3 + 0.606823, + -7 + 0.974148, + 5 + -0.667598, + 1 + -0.811568, + 1 + -0.936551, + 7 + -0.530943, + 5 + 0.908057, + -7 + 0.895185, + 5 + 0.711135, + 1 + -0.95896, + 1 + 0.83532, + 1 + 0.14732, + 3 + 0.90921, + -1 + -0.30945, + -1 + -0.869543, + -7 + -0.360646, + 1 + 0.357157, + -3 + -0.514692, + 5 + 0.896144, + -1 + -0.196886, + -5 + -0.319624, + -1 + -0.472977, + -1 + -0.784624, + -1 + -0.281646, + -5 + -0.559682, + 3 + 0.391078, + 7 + 0.306199, + -3 + 0.962734, + -7 + -0.11162, + -7 + 0.357581, + 3 + 0.0805047, + 3 + -0.922337, + 1 + 0.232492, + -5 + -0.574144, + -1 + 0.710829, + 7 + -0.284843, + -1 + 0.831973, + -1 + -0.336799, + -3 + -0.745866, + -5 + -0.645711, + 5 + 0.0646029, + -3 + 0.252552, + 5 + -0.48003, + -5 + 0.299438, + 7 + 0.738929, + -5 + 0.40337, + 5 + 0.605547, + -3 + -0.525722, + 1 + -0.326724, + 1 + -0.515053, + 5 + 0.261516, + -7 + 0.320474, + -1 + -0.521487, + -5 + 0.903239, + -3 + -0.403525, + 7 + 0.0639151, + 3 + 0.359482, + 3 + 0.823776, + 5 + 0.0387504, + -7 + 0.109849, + 3 + -0.097467, + -5 + -0.832645, + -5 + 0.526237, + 7 + 0.438123, + 3 + -0.519244, + 1 + -0.0476922, + 3 + 0.191197, + -7 + -0.534928, + 3 + 0.462164, + 7 + -0.895527, + -1 + 0.473474, + -7 + 0.146189, + 5 + -0.179909, + -3 + -0.285322, + 5 + 0.613479, + -1 + -0.0315166, + 7 + 0.698841, + 3 + -0.774282, + 1 + 0.818017, + 7 + -0.932623, + 3 + 0.0664446, + -7 + 0.06308, + 3 + -0.519814, + 5 + -0.576546, + 5 + -0.267179, + -3 + -0.837482, + 5 + -0.255068, + 5 + -0.0568383, + -3 + 0.888405, + -3 + -0.366288, + -5 + -0.552696, + -1 + 0.541689, + 7 + -0.0454361, + -5 + 0.608489, + 3 + -0.922755, + -5 + 0.406846, + -5 + -0.506253, + 7 + -0.688017, + -5 + 0.776949, + 1 + -0.378568, + 5 + -0.727209, + -7 + 0.613322, + 5 + 0.962756, + -7 + -0.893482, + -7 + -0.987528, + -7 + 0.456806, + 7 + 0.786419, + 1 + 0.034181, + -7 + 0.790939, + -5 + -0.0300588, + 1 + 0.1652, + -7 + -0.481907, + 3 + 0.0991387, + -7 + -0.564886, + 5 + 0.85039, + -1 + 0.812973, + -1 + -0.407522, + 7 + -0.952524, + 5 + 0.765642, + -5 + -0.337741, + 7 + 0.957819, + 3 + -0.899041, + -1 + -0.671052, + -3 + 0.983954, + 1 + -0.89124, + -3 + 0.0940522, + -1 + 0.611417, + 7 + -0.937967, + -1 + 0.941416, + -1 + -0.359601, + 5 + 0.747211, + -7 + -0.111301, + 3 + -0.640113, + 7 + 0.0550081, + 7 + -0.189345, + 3 + 0.214366, + -5 + 0.135666, + -5 + 0.226602, + 3 + -0.410662, + 5 + -0.843728, + -3 + -0.371912, + -7 + -0.989917, + -1 + 0.690856, + -1 + 0.0420038, + 7 + 0.00959448, + 5 + -0.815518, + 1 + 0.430825, + -7 + 0.609881, + 5 + -0.688188, + 5 + -0.60674, + -1 + 0.0334734, + 1 + 0.722216, + -3 + 0.285942, + 7 + 0.519757, + 3 + -0.27104, + -1 + 0.509289, + -3 + -0.81976, + 5 + 0.481086, + 3 + -0.974128, + 7 + -0.337838, + 5 + 0.962801, + -3 + -0.798452, + -3 + 0.457351, + 1 + 0.103281, + -1 + -0.0256317, + 7 + 0.802218, + 7 + 0.689228, + -7 + -0.276751, + 5 + 0.404102, + -1 + -0.860859, + -7 + -0.0371287, + -1 + 0.370437, + -5 + -0.616334, + -5 + -0.758392, + 1 + -0.454585, + 1 + -0.137519, + 7 + -0.261276, + 5 + 0.558348, + 1 + -0.948463, + -5 + 0.523879, + -5 + 0.555652, + -1 + 0.840325, + 7 + 0.279812, + 5 + 0.617966, + 1 + 0.192231, + 5 + 0.132018, + -7 + -0.11959, + 1 + -0.894721, + -7 + -0.504819, + 5 + -0.419666, + 7 + -0.391328, + -3 + -0.24103, + -7 + -0.852627, + -7 + 0.990221, + 7 + 0.822151, + -7 + 0.170617, + 3 + 0.614475, + -7 + 0.446277, + -7 + -0.371819, + 1 + 0.831829, + -5 + 0.0787276, + -1 + -0.684313, + 3 + -0.611736, + 5 + 0.472613, + 7 + 0.730033, + -5 + -0.811217, + 1 + -0.760817, + -3 + 0.268843, + 5 + 0.584456, + 1 + 0.823053, + -7 + 0.80804, + -7 + 0.457053, + 5 + -0.577104, + -5 + -0.224893, + -5 + -0.107738, + -1 + -0.51484, + 3 + -0.198893, + -7 + 0.278753, + 7 + 0.502244, + -1 + 0.0510433, + 1 + -0.402208, + -7 + 0.343478, + 1 + -0.901047, + 1 + 0.369701, + -3 + -0.944263, + -5 + 0.386476, + 3 + -0.954781, + 7 + -0.688498, + 7 + -0.365083, + 3 + -0.776885, + -1 + -0.598649, + 3 + -0.87102, + 1 + 0.975515, + -3 + -0.467838, + 1 + 0.466075, + -7 + 0.271324, + -1 + 0.978247, + 7 + 0.112029, + -1 + 0.601593, + -3 + -0.412666, + 1 + -0.601096, + 5 + -0.0684049, + -7 + 0.552019, + -5 + 0.313324, + 5 + -0.836011, + -1 + 0.528016, + -3 + 0.284965, + -3 + 0.700575, + -5 + 0.0874079, + -7 + -0.0126598, + -7 + -0.276119, + 5 + -0.218603, + -5 + -0.0014039, + -3 + 0.189325, + 7 + 0.429569, + -5 + 0.837003, + 3 + 0.703335, + 7 + -0.216503, + 7 + 0.0920741, + 7 + 0.750109, + -1 + -0.322132, + 7 + -0.128556, + -1 + 0.00373274, + -1 + -0.17115, + 1 + 0.264227, + 3 + 0.988822, + -1 + 0.0243255, + -5 + 0.605084, + -7 + 0.295968, + 5 + 0.873413, + -1 + 0.434273, + -5 + -0.781778, + 5 + -0.0426681, + -5 + 0.167692, + -1 + -0.334183, + -1 + 0.07798, + -1 + -0.297114, + -3 + 0.816338, + 1 + -0.611242, + 3 + -0.423656, + 3 + -0.432077, + 1 + -0.145807, + 5 + 0.10632, + -5 + 0.756861, + -7 + -0.931971, + 7 + -0.397063, + 5 + 0.283628, + -7 + 0.721398, + 7 + 0.348194, + -3 + -0.33922, + 3 + 0.412108, + 7 + 0.510752, + -3 + -0.263234, + -7 + 0.485708, + 5 + 0.573377, + 3 + 0.244824, + -7 + 0.756185, + 5 + -0.981843, + -7 + 0.890249, + -5 + -0.785723, + 1 + 0.429159, + 7 + 0.891205, + 5 + -0.310018, + 5 + -0.0331806, + -7 + 0.567766, + -7 + -0.172382, + 3 + -0.0973954, + -1 + -0.726783, + -7 + 0.86626, + -3 + 0.640023, + 5 + -0.104726, + -3 + -0.213919, + -5 + -0.131563, + 3 + 0.108026, + 1 + 0.426832, + -7 + 0.631181, + -3 + -0.911012, + 5 + 0.232769, + -3 + -0.124074, + 5 + -0.263584, + -3 + 0.246066, + 7 + 0.833384, + -5 + -0.798822, + 1 + -0.281957, + 1 + -0.527281, + 3 + 0.918325, + 5 + -0.872591, + -3 + 0.987781, + 7 + -0.724259, + 7 + 0.73749, + 5 + -0.179643, + 1 + -0.480496, + -1 + -0.0747694, + 3 + -0.162109, + 1 + 0.655518, + 5 + 0.815859, + 7 + -0.422858, + -1 + 0.19599, + 3 + -0.601651, + 7 + -0.598413, + -5 + -0.951473, + 7 + 0.684015, + 7 + 0.121945, + 5 + 0.330604, + -1 + 0.800472, + -5 + -0.892743, + -5 + -0.0700532, + -1 + 0.143832, + -1 + 0.713388, + 1 + -0.253503, + 1 + -0.0462767, + 3 + 0.140933, + -5 + 0.94534, + -7 + 0.665662, + -5 + 0.207102, + 3 + -0.327194, + 5 + 0.110171, + -5 + 0.225803, + 1 + -0.900872, + -5 + 0.0169889, + 5 + 0.152721, + 7 + 0.125242, + -1 + 0.63948, + 7 + 0.0639926, + -5 + -0.869524, + 7 + -0.160608, + -1 + -0.465428, + 5 + -0.2185, + -7 + -0.465846, + -1 + 0.0973919, + 3 + 0.450568, + -5 + -0.451587, + -7 + -0.83918, + -1 + 0.709855, + 3 + -0.86862, + 5 + 0.676479, + 7 + -0.125049, + -1 + -0.191198, + 5 + -0.925049, + 1 + -0.521026, + -3 + -0.0364143, + -7 + 0.600769, + -7 + 0.164072, + -5 + 0.416589, + -7 + -0.595857, + -3 + 0.220567, + 3 + 0.0636474, + -7 + 0.644101, + 5 + -0.775524, + -3 + -0.192748, + 1 + 0.0538391, + 1 + 0.29524, + -5 + 0.882538, + -5 + -0.816844, + -5 + 0.862396, + -5 + 0.314402, + 1 + -0.392808, + -3 + 0.651255, + -1 + -0.231968, + 1 + 0.738021, + 5 + 0.84997, + -3 + 0.186296, + 1 + 0.741231, + 1 + -0.177977, + 5 + 0.522434, + -7 + 0.597047, + -3 + 0.0266608, + -5 + -0.152547, + 5 + -0.579447, + -1 + -0.357272, + -7 + -0.497293, + 5 + 0.869424, + -5 + -0.0230876, + -5 + -0.132476, + -3 + 0.936738, + 5 + 0.558816, + -3 + -0.0384813, + -1 + 0.483534, + -7 + 0.867384, + -1 + 0.42158, + 3 + 0.420513, + 7 + -0.0754159, + -5 + -0.379954, + 7 + 0.769618, + -7 + 0.340938, + -7 + -0.869991, + 3 + 0.830734, + 3 + 0.94181, + 3 + -0.130749, + 3 + 0.517635, + -3 + -0.252298, + -3 + -0.0496521, + 1 + 0.684225, + 1 + 0.172965, + 1 + 0.417296, + 7 + -0.466398, + 7 + -0.114508, + -1 + -0.109476, + -7 + 0.00148834, + 1 + 0.0949139, + 1 + 0.432791, + -1 + -0.240929, + -1 + 0.652485, + 5 + -0.217385, + 7 + -0.8724, + -1 + 0.387098, + 3 + -0.444865, + -3 + 0.184706, + 7 + -0.730551, + 7 + 0.754565, + 7 + -0.604301, + 3 + -0.119371, + -1 + -0.28214, + 5 + 0.143776, + 3 + 0.957703, + 3 + -0.104371, + -5 + -0.261664, + -1 + 0.495793, + 1 + -0.734588, + -3 + 0.628134, + -3 + 0.817538, + -7 + 0.361645, + 3 + 0.162489, + 5 + -0.536024, + 7 + -0.486136, + 5 + -0.776124, + -5 + -0.629988, + 1 + -0.0367843, + -5 + -0.493533, + -7 + -0.725222, + -5 + 0.492433, + 7 + 0.288113, + -3 + -0.784857, + -5 + 0.824698, + -1 + -0.545993, + -3 + -0.306256, + 1 + -0.877171, + -1 + 0.567034, + 3 + -0.440337, + -1 + 0.14643, + 7 + -0.755017, + -1 + -0.832763, + 5 + -0.498979, + 3 + 0.763625, + 5 + 0.566975, + -5 + 0.0534092, + -5 + -0.963171, + 5 + 0.0216508, + 7 + 0.597324, + 7 + -0.441571, + 7 + 0.0347587, + 3 + 0.983787, + 1 + 0.188113, + -1 + -0.171194, + -7 + -0.641733, + 7 + 0.36138, + -1 + -0.566453, + 1 + 0.882606, + 1 + 0.61524, + -1 + -0.773541, + 3 + 0.153026, + 5 + -0.621578, + -7 + -0.904904, + -5 + 0.0406272, + -5 + 0.415864, + 5 + -0.60085, + 1 + 0.727596, + -7 + -0.0860673, + -1 + -0.785685, + -5 + -0.889453, + 7 + -0.141489, + -5 + 0.04296, + -5 + 0.564742, + -7 + -0.12966, + -1 + 0.841196, + -5 + 0.71528, + 1 + -0.104704, + 1 + -0.263372, + -7 + 0.680698, + 3 + 0.756433, + -3 + -0.200798, + 1 + 0.027729, + -1 + -0.464512, + 7 + -0.60066, + -1 + 0.104495, + -3 + 0.713626, + -5 + -0.776119, + 3 + 0.168751, + -1 + -0.905566, + 5 + -0.955254, + -7 + -0.407108, + -3 + 0.170629, + -3 + -0.453202, + -1 + -0.907515, + 5 + -0.210368, + -3 + -0.98412, + -3 + -0.798125, + 3 + -0.414919, + -1 + -0.236897, + 3 + -0.491091, + -5 + -0.77713, + 3 + 0.230108, + 1 + -0.796737, + 5 + -0.26121, + 3 + 0.397635, + -1 + 0.85451, + -3 + -0.393889, + 5 + 0.983874, + 5 + 0.942163, + -3 + 0.74394, + 1 + 0.242709, + 3 + -0.779053, + -1 + 0.341856, + -7 + -0.116747, + -7 + -0.640877, + -1 + -0.318128, + -7 + 0.00367009, + -3 + 0.617172, + 7 + -0.204651, + -5 + 0.0780388, + 7 + 0.626396, + 1 + -0.638141, + -1 + -0.882934, + -5 + -0.704026, + -3 + 0.851265, + 7 + 0.0141939, + -7 + 0.611678, + -1 + 0.341055, + 3 + -0.405282, + -7 + 0.993071, + -5 + -0.0799289, + 1 + -0.967094, + -5 + -0.893374, + 5 + -0.606802, + -1 + -0.296088, + 3 + 0.578082, + 1 + 0.630626, + -1 + -0.256433, + -7 + 0.023755, + 5 + -0.565901, + 1 + -0.87536, + -7 + 0.591114, + 3 + -0.0151382, + 3 + -0.218575, + -1 + -0.571426, + 7 + -0.817884, + 1 + -0.105616, + -5 + 0.226052, + 1 + -0.197419, + 1 + -0.804454, + 1 + -0.957871, + -7 + 0.869702, + 7 + -0.118016, + -7 + 0.231177, + -1 + 0.143965, + -7 + -0.544014, + -7 + -0.125394, + -5 + 0.66333, + -5 + 0.0453925, + 3 + -0.445539, + -3 + -0.841133, + -1 + 0.406819, + 1 + 0.066009, + -7 + -0.141267, + 7 + 0.20172, + 1 + -0.397711, + -3 + -0.341991, + 3 + -0.66472, + -1 + 0.1133, + -1 + -0.0874664, + 1 + 0.460378, + -5 + 0.833044, + -1 + 0.694845, + -5 + -0.814154, + 5 + 0.190124, + 5 + 0.90168, + -3 + 0.150333, + 5 + -0.832164, + 5 + -0.623571, + 5 + 0.116979, + 7 + -0.623282, + -3 + 0.724953, + 3 + -0.656996, + 7 + 0.0645319, + 3 + 0.0895726, + 7 + -0.776726, + -1 + 0.318608, + 3 + 0.0496206, + -3 + 0.0368759, + -1 + 0.555521, + -5 + -0.673436, + 1 + 0.0103849, + -3 + 0.0743446, + -3 + -0.259726, + 5 + 0.0216708, + 1 + 0.769972, + -5 + -0.441797, + -3 + 0.719177, + 3 + 0.576816, + 1 + -0.95444, + 3 + 0.385715, + 7 + 0.215961, + -7 + -0.0887377, + -3 + 0.9093, + 5 + 0.231244, + -5 + 0.878044, + 1 + 0.237768, + -5 + -0.224173, + 7 + 0.115184, + 5 + -0.507669, + 3 + -0.4694, + -5 + -0.559494, + -7 + 0.256493, + -3 + 0.691867, + 7 + 0.760056, + -5 + -0.0235437, + -1 + -0.491056, + -7 + -0.632234, + -7 + 0.688073, + -3 + 0.448912, + 1 + 0.806255, + 3 + 0.174302, + -1 + 0.924295, + 1 + -0.0079971, + 7 + 0.585534, + 5 + -0.106368, + 7 + -0.647104, + -3 + -0.232442, + -1 + 0.103303, + 3 + -0.545308, + -7 + 0.171427, + 1 + -0.150061, + -5 + 0.124142, + 1 + 0.609533, + 1 + -0.51341, + 3 + 0.372706, + -5 + 0.406665, + 3 + -0.277069, + -3 + 0.316304, + -7 + -0.233404, + -7 + 0.0158354, + -3 + -0.376876, + 1 + -0.914291, + -3 + -0.819444, + -7 + 0.566109, + -5 + -0.582836, + -5 + -0.839922, + 5 + 0.186932, + -5 + -0.675285, + 5 + -0.957952, + -7 + -0.784832, + -3 + 0.403649, + 3 + 0.798144, + -3 + -0.880645, + -3 + 0.528126, + -1 + -0.657318, + 3 + 0.890482, + 5 + -0.46684, + 5 + -0.566931, + -7 + 0.81062, + -1 + -0.0238388, + -7 + -0.377402, + -3 + -0.21429, + -5 + -0.505753, + -7 + -0.951982, + -1 + -0.515628, + 3 + -0.871026, + -1 + -0.838789, + -7 + -0.725925, + 1 + 0.77047, + -3 + 0.858867, + 5 + 0.600752, + -3 + 0.0665514, + 1 + -0.317725, + 3 + -0.843704, + 5 + 0.219384, + -5 + -0.586559, + 7 + -0.240551, + -3 + -0.209033, + -7 + 0.493641, + 7 + 0.152856, + -7 + -0.597324, + -1 + -0.276392, + -1 + 0.831608, + 5 + 0.470546, + 5 + 0.330143, + -7 + 0.642262, + -7 + 0.977435, + -7 + 0.313444, + -7 + -0.10048, + 5 + 0.563594, + -1 + -0.186187, + -1 + -0.365659, + 1 + -0.837578, + -5 + 0.140403, + 7 + -0.78022, + -1 + 0.844668, + 7 + 0.375148, + 7 + -0.0498808, + 1 + 0.40211, + -1 + 0.744509, + 3 + 0.079077, + 7 + 0.296291, + 7 + -0.27219, + -7 + -0.660157, + -3 + 0.915867, + -1 + 0.102478, + 1 + -0.851214, + 7 + -0.634492, + -5 + -0.253903, + -5 + -0.598679, + -7 + -0.223802, + 3 + 0.0226067, + 1 + 0.696982, + -5 + -0.0351859, + 5 + -0.481739, + -1 + -0.00746336, + 3 + 0.416315, + 5 + 0.321218, + 3 + -0.283638, + -7 + 0.752743, + 3 + -0.774599, + -1 + 0.30598, + 5 + -0.0478183, + 7 + 0.791332, + -5 + -0.235768, + 3 + 0.292966, + -3 + 0.414722, + 3 + -0.665212, + 5 + -0.710929, + -3 + -0.588074, + -3 + 0.331691, + 7 + 0.882629, + 3 + -0.550038, + 1 + -0.957022, + -5 + 0.990136, + 5 + -0.558498, + -3 + -0.842342, + -1 + 0.000248163, + -5 + 0.131952, + 7 + -0.167911, + 1 + -0.425364, + 7 + -0.372087, + 1 + 0.526899, + -1 + -0.638801, + -5 + -0.386877, + 7 + 0.871863, + -7 + 0.459965, + 5 + -0.165079, + 5 + 0.296509, + -3 + 0.833452, + -7 + 0.744527, + -3 + 0.626609, + 1 + -0.814472, + 3 + 0.998261, + -7 + 0.270782, + 1 + -0.904688, + -5 + 0.723069, + -1 + -0.664172, + -5 + -0.019654, + -1 + 0.757106, + 7 + 0.780875, + 1 + -0.898937, + 3 + -0.485577, + -3 + -0.140519, + -3 + -0.240458, + -1 + 0.353802, + -7 + -0.918099, + 3 + -0.32276, + 3 + 0.672086, + -3 + -0.335273, + 1 + -0.999146, + -1 + -0.630338, + 7 + -0.544571, + -7 + 0.470793, + -3 + -0.581126, + -1 + 0.135819, + -1 + 0.0451301, + 5 + 0.479837, + -3 + 0.172697, + 5 + 0.796663, + -1 + -0.566894, + 1 + 0.470888, + 3 + 0.0653015, + -7 + 0.792323, + 1 + -0.867727, + -3 + 0.829587, + -3 + -0.740408, + 3 + -0.830687, + 3 + 0.957641, + -7 + -0.423364, + 3 + -0.893497, + 1 + -0.853771, + -3 + 0.92187, + 1 + -0.929865, + -3 + 0.198643, + 7 + 0.961747, + -1 + -0.431994, + 7 + 0.35683, + -1 + -0.871135, + 7 + 0.727451, + 7 + 0.458093, + -3 + 0.22682, + -3 + -0.827643, + -3 + -0.189953, + 5 + -0.688236, + -3 + -0.294562, + 5 + -0.903106, + -5 + 0.444196, + -1 + 0.2121, + -5 + -0.214493, + -5 + -0.392994, + -3 + 0.665017, + 1 + 0.269187, + 7 + -0.745741, + 1 + -0.185388, + -5 + -0.795616, + -5 + -0.989525, + -5 + -0.0291574, + 7 + 0.577641, + 3 + -0.98546, + 5 + 0.696809, + -5 + 0.649647, + 3 + -0.401609, + -7 + 0.29181, + -1 + -0.336865, + 3 + -0.279985, + -7 + 0.819639, + 1 + -0.69903, + 5 + -0.956345, + -3 + 0.917636, + 3 + -0.539845, + 3 + -0.58337, + 5 + 0.0319712, + 3 + -0.682523, + 3 + -0.160175, + 1 + -0.707552, + 3 + -0.197245, + -1 + 0.583643, + -7 + 0.128135, + 3 + 0.240791, + -7 + -0.289134, + -7 + 0.955084, + -5 + 0.495007, + -1 + 0.955188, + 3 + 0.523281, + -1 + 0.468672, + -5 + -0.467838, + -3 + 0.654833, + -5 + 0.85963, + -3 + 0.532693, + -3 + -0.11304, + 5 + 0.947132, + 5 + 0.395143, + 1 + -0.114501, + -5 + 0.275912, + -7 + -0.816982, + -3 + 0.280537, + 1 + -0.290476, + 3 + 0.753207, + 3 + -0.37078, + -5 + -0.73641, + 1 + 0.720629, + -1 + 0.61751, + 5 + -0.114619, + 3 + -0.509509, + 1 + 0.349672, + 7 + 0.426544, + -5 + -0.567438, + -7 + -0.52387, + 3 + -0.376306, + 3 + -0.49252, + 5 + 0.441628, + 3 + 0.703002, + -7 + 0.62187, + 3 + 0.754402, + -1 + -0.344451, + 5 + -0.0148834, + -7 + 0.449515, + 5 + 0.230859, + 1 + 0.724024, + 5 + 0.190704, + 1 + -0.69348, + -5 + 0.586233, + 5 + 0.0794267, + -5 + -0.631736, + 1 + 0.105417, + -5 + 0.136263, + 7 + -0.642064, + 1 + 0.0430542, + -7 + -0.41497, + 5 + 0.775936, + -1 + 0.687085, + -5 + 0.925474, + -5 + 0.0990985, + 3 + -0.277763, + -1 + 0.299999, + 3 + 0.392572, + -7 + -0.546367, + 7 + 0.403084, + 5 + -0.0418944, + -7 + 0.446579, + -7 + 0.372017, + -1 + 0.459786, + 7 + -0.0032825, + 5 + 0.189248, + 5 + -0.155126, + 3 + 0.53685, + 3 + 0.933272, + 3 + -0.384181, + 5 + 0.204225, + 1 + -0.327539, + -7 + 0.348723, + 1 + -0.685387, + -7 + -0.750799, + -1 + -0.627168, + -7 + 0.610837, + 5 + -0.957175, + -3 + 0.834856, + -1 + 0.528653, + 7 + -0.780567, + 7 + 0.0884855, + 3 + 0.648985, + -1 + 0.218943, + -7 + 0.832075, + 5 + 0.811807, + -3 + -0.685713, + -3 + -0.296578, + 3 + 0.000125931, + -5 + -0.996983, + -5 + -0.193044, + 5 + -0.0545228, + 1 + 0.893854, + 5 + 0.97836, + -3 + -0.748222, + -1 + 0.196022, + 1 + 0.163083, + -5 + -0.180233, + -1 + 0.209452, + -3 + 0.744591, + -3 + -0.1817, + 1 + -0.447565, + 5 + 0.528624, + -7 + -0.692082, + 7 + -0.428345, + -7 + 0.0934917, + 1 + 0.678237, + -7 + -0.298993, + -3 + 0.654322, + -3 + -0.942614, + 7 + 0.783697, + 3 + 0.395035, + 1 + -0.372332, + 3 + -0.859733, + 1 + 0.4468, + 5 + 0.822121, + -5 + 0.201003, + -7 + -0.74061, + 5 + -0.568736, + 3 + 0.904994, + -5 + 0.325172, + 5 + 0.292775, + 5 + 0.511914, + -7 + 0.675604, + 5 + 0.907106, + -7 + 0.676053, + -3 + -0.64883, + -1 + -0.451512, + 3 + -0.841985, + -7 + 0.0817016, + -1 + 0.111568, + -7 + -0.594469, + -3 + -0.844349, + 3 + -0.26745, + -3 + -0.559703, + 7 + 0.53067, + 3 + -0.256771, + -1 + -0.170001, + -1 + -0.775529, + -1 + -0.456536, + 3 + -0.998071, + 1 + 0.941052, + 7 + 0.130878, + 7 + 0.838738, + 1 + 0.856186, + 1 + 0.846151, + -1 + -0.737487, + 3 + -0.76553, + -3 + 0.222, + -1 + -0.387758, + 7 + -0.269319, + -3 + 0.0668951, + 3 + 0.731949, + 5 + -0.741075, + -7 + -0.219907, + 3 + 0.487581, + 1 + -0.973969, + 7 + 0.639967, + 3 + 0.809232, + 3 + -0.642748, + 5 + -0.453162, + -7 + -0.474022, + -3 + -0.631836, + -3 + 0.0981818, + 7 + 0.684498, + -1 + -0.654845, + -5 + -0.612608, + 7 + 0.610862, + -3 + -0.369351, + 3 + -0.261936, + 7 + -0.814926, + 7 + 0.390131, + -5 + 0.531136, + 3 + 0.974289, + -3 + -0.111925, + 3 + 0.376471, + -3 + -0.941562, + 7 + -0.410982, + -7 + 0.875953, + 5 + -0.448872, + -1 + -0.806028, + -1 + -0.814961, + 5 + 0.395374, + -7 + 0.814904, + 1 + 0.383855, + 1 + -0.252184, + 3 + 0.524843, + -7 + -0.233859, + -7 + 0.764495, + -7 + 0.817705, + -5 + 0.641853, + -3 + -0.758414, + -1 + -0.260464, + -7 + -0.240351, + -3 + 0.0476139, + -1 + -0.220685, + -1 + -0.993293, + 7 + 0.627481, + -3 + -0.950516, + -5 + -0.0848613, + 5 + 0.670037, + 7 + 0.825011, + -7 + 0.111405, + 7 + 0.0703245, + -3 + 0.177663, + 7 + -0.739343, + 3 + -0.673892, + 7 + -0.947279, + -5 + 0.732764, + 7 + -0.807932, + 1 + -0.494108, + 1 + 0.611574, + -1 + 0.205265, + -1 + -0.485118, + -5 + 0.0552847, + -5 + -0.176059, + 5 + 0.00244508, + 7 + -0.773636, + 5 + 0.951496, + -7 + 0.525518, + -5 + 0.968101, + -7 + 0.10137, + 5 + -0.4487, + 7 + 0.215142, + -5 + -0.162651, + 5 + -0.520808, + 1 + -0.89087, + -1 + -0.804296, + 7 + -0.341382, + -7 + 0.793131, + 5 + -0.724335, + 7 + 0.0832606, + 3 + -0.819473, + 7 + -0.613928, + -1 + -0.975915, + 7 + 0.555494, + -1 + -0.753698, + 1 + -0.570132, + -5 + -0.00221921, + 1 + 0.010534, + -5 + -0.825051, + -5 + 0.528378, + 3 + 0.559274, + -5 + 0.826081, + 7 + -0.349553, + 3 + 0.36511, + -5 + -0.881283, + 1 + 0.833997, + 1 + 0.00815386, + -3 + -0.820684, + 1 + 0.952573, + -5 + 0.378794, + -5 + 0.465909, + 1 + -0.166333, + 1 + 0.0746185, + -1 + 0.431021, + 5 + 0.266922, + -1 + 0.339902, + -1 + 0.372874, + 7 + -0.0149696, + -1 + 0.0317811, + 7 + -0.691387, + -1 + 0.929823, + 5 + -0.295751, + 7 + -0.851862, + -1 + 0.33382, + 7 + -0.589562, + -7 + -0.217095, + -7 + 0.115214, + -7 + 0.220949, + 1 + 0.800567, + 3 + -0.251049, + -5 + -0.626753, + 7 + -0.450723, + 7 + 0.22979, + -3 + -0.342451, + -3 + 0.997709, + -1 + 0.582385, + -5 + 0.191317, + 7 + -0.873862, + 5 + 0.213097, + 7 + -0.762892, + 7 + 0.954305, + 7 + 0.188828, + 7 + 0.931783, + -7 + -0.839115, + 5 + -0.738813, + 3 + 0.926841, + 5 + 0.399905, + -7 + 0.0123429, + -5 + 0.545699, + 3 + -0.661568, + 3 + -0.261673, + -5 + -0.81428, + 7 + 0.866628, + 5 + -0.048188, + -3 + 0.165017, + 7 + -0.698899, + -7 + 0.0783355, + -7 + 0.693822, + 7 + 0.726706, + -1 + 0.148921, + 7 + -0.685703, + 3 + 0.548864, + -7 + -0.878148, + 3 + 0.205964, + 5 + -0.271077, + -7 + -0.15239, + 1 + -0.949635, + -1 + 0.961041, + -7 + 0.0868696, + 3 + -0.361298, + 3 + 0.624626, + 3 + -0.0838945, + 5 + 0.132301, + -1 + 0.192646, + -5 + -0.579731, + -5 + -0.101051, + 5 + 0.870131, + 1 + 0.535988, + 5 + 0.255953, + 1 + 0.314134, + -7 + 0.762894, + -7 + 0.127185, + 7 + -0.222042, + -5 + -0.529038, + -3 + 0.231572, + 1 + 0.788721, + 5 + -0.891869, + -5 + -0.472732, + 3 + -0.0128941, + 1 + -0.623197, + 7 + -0.490687, + -1 + -0.441505, + 1 + -0.0410075, + -5 + 0.847264, + -7 + -0.371955, + -1 + 0.41401, + -1 + -0.742, + 3 + 0.0546079, + 5 + -0.529726, + 7 + -0.0630406, + 1 + 0.196568, + -3 + 0.488722, + -5 + -0.357116, + 3 + -0.179397, + -3 + 0.358234, + -7 + 0.821111, + 7 + -0.634397, + 5 + -0.490498, + -5 + -0.103393, + -7 + -0.996996, + -5 + 0.358586, + -7 + 0.785637, + -5 + 0.46574, + -1 + -0.714036, + 7 + 0.73281, + -1 + -0.980125, + -5 + 0.152175, + -1 + -0.468575, + -1 + -0.154831, + 5 + -0.257122, + 3 + -0.414745, + 3 + 0.663051, + -3 + 0.787162, + -1 + 0.773088, + 5 + -0.0174988, + 7 + 0.348241, + 1 + 0.856018, + -7 + -0.177525, + 1 + 0.409387, + 3 + 0.0205055, + -3 + 0.212273, + 7 + -0.35314, + -1 + 0.253691, + -7 + 0.988757, + 1 + 0.915514, + 7 + -0.0632796, + -3 + -0.0794022, + 5 + 0.905145, + 3 + -0.678132, + 7 + 0.842035, + -1 + 0.189324, + -1 + 0.431813, + 5 + 0.855323, + 3 + -0.285528, + -3 + -0.740299, + 3 + 0.526598, + -3 + -0.807057, + -3 + -0.907001, + -1 + 0.673215, + 1 + -0.806326, + -7 + -0.0179321, + 7 + 0.0822508, + -1 + 0.850969, + 5 + 0.18839, + 3 + -0.692543, + -5 + 0.064437, + -7 + -0.112983, + -3 + -0.0709171, + -5 + 0.327346, + 1 + -0.595314, + -1 + 0.878245, + 1 + 0.291632, + -1 + -0.922109, + -3 + -0.872261, + -7 + -0.212876, + 1 + -0.348517, + 5 + -0.24286, + 3 + 0.777443, + 5 + 0.00615786, + 5 + 0.834023, + 1 + -0.590069, + -7 + 0.653321, + 1 + -0.234737, + -7 + 0.664936, + 7 + 0.411378, + -7 + -0.88205, + -1 + -0.855369, + 1 + 0.377919, + -7 + -0.456485, + -5 + -0.949986, + -5 + -0.0158651, + 3 + 0.535672, + -1 + -0.687636, + 1 + 0.736756, + 7 + -0.696999, + 1 + 0.847792, + -3 + -0.349274, + 1 + -0.544481, + 7 + 0.608189, + -7 + 0.608384, + 5 + -0.323123, + 7 + -0.947181, + 5 + 0.753829, + 5 + -0.573138, + 5 + -0.485321, + -5 + 0.480423, + -5 + -0.371829, + 5 + -0.853753, + -7 + 0.878959, + -7 + 0.0642654, + 1 + 0.680307, + 1 + 0.291632, + 7 + -0.853807, + 5 + 0.644158, + 5 + -0.355364, + 1 + 0.190966, + 3 + -0.294411, + -7 + -0.67303, + -5 + -0.965702, + -3 + 0.55212, + 1 + -0.804562, + -7 + -0.494127, + -5 + -0.983771, + 1 + -0.133138, + -1 + -0.607814, + 1 + -0.742387, + -5 + -0.411707, + -3 + -0.816862, + 7 + 0.426785, + 5 + -0.089001, + 3 + -0.966127, + 3 + -0.784032, + 5 + -0.356036, + 5 + 0.475987, + 1 + 0.970457, + -3 + 0.678356, + 1 + -0.430618, + 5 + 0.942241, + -3 + -0.913966, + 7 + -0.730373, + -3 + 0.640682, + 7 + -0.024488, + -5 + 0.462632, + -3 + -0.609614, + -1 + -0.482857, + -5 + 0.535506, + 7 + 0.821051, + -1 + 0.793945, + 3 + -0.0835013, + -5 + -0.393026, + 1 + -0.415528, + -5 + 0.182819, + 1 + -0.561988, + -5 + -0.417262, + 7 + 0.708211, + 1 + -0.207354, + -5 + -0.844518, + -7 + 0.604461, + 7 + 0.787027, + 7 + 0.763122, + 1 + 0.300372, + -3 + -0.0203687, + -7 + -0.500432, + 7 + -0.5601, + 5 + -0.682225, + -5 + -0.547398, + -3 + 0.769381, + -3 + 0.750163, + -5 + -0.820679, + 3 + 0.236003, + 1 + -0.316465, + -3 + 0.802262, + 3 + -0.399964, + 5 + -0.166494, + 1 + 0.776745, + 5 + 0.716541, + 7 + -0.251088, + -5 + -0.42548, + -3 + -0.761153, + 7 + -0.0766243, + 3 + -0.180629, + 5 + -0.166458, + -5 + -0.833394, + -7 + 0.0297446, + -7 + -0.362676, + 7 + -0.644897, + -7 + 0.283366, + 5 + -0.665628, + 3 + -0.488068, + -1 + -0.902438, + -5 + -0.355751, + 3 + -0.419479, + 7 + -0.370073, + -3 + 0.480753, + 1 + -0.420338, + -7 + -0.24157, + 7 + 0.207747, + -1 + -0.777488, + 5 + 0.341417, + -1 + -0.33618, + -5 + 0.598459, + -3 + -0.280681, + 1 + -0.0398586, + 7 + 0.717195, + 5 + 0.431427, + -5 + -0.839676, + -1 + -0.74745, + 1 + 0.73193, + -1 + 0.729311, + 5 + 0.561066, + -5 + -0.670177, + -1 + -0.254041, + 3 + 0.0451663, + -7 + -0.160697, + 7 + 0.13319, + -3 + 0.360953, + -3 + 0.264897, + 1 + -0.566809, + -5 + 0.291045, + 1 + -0.573798, + -3 + 0.854987, + -3 + -0.973763, + -7 + -0.958898, + 1 + -0.945093, + -1 + -0.72672, + 5 + 0.814473, + 7 + -0.794704, + -3 + 0.229887, + -1 + 0.801239, + -5 + 0.531782, + -1 + 0.247072, + 1 + -0.179189, + -3 + 0.401884, + 7 + 0.236019, + -1 + 0.725281, + -5 + 0.74655, + 5 + -0.427725, + -1 + 0.967868, + -7 + -0.432802, + -1 + 0.541378, + 7 + -0.555299, + -3 + 0.166895, + -7 + 0.921733, + -3 + 0.840396, + -5 + -0.602658, + -1 + -0.189227, + -5 + 0.605957, + 5 + -0.525512, + 5 + 0.433278, + -1 + 0.554043, + -1 + 0.353735, + 3 + -0.493134, + -7 + 0.86014, + -3 + 0.543759, + -1 + 0.248284, + -5 + -0.502769, + 5 + -0.984136, + 5 + 0.407552, + -1 + 0.869081, + -3 + -0.7676, + -1 + 0.940972, + 1 + -0.511719, + 7 + 0.870979, + 3 + -0.0582847, + 7 + -0.628254, + 7 + -0.780393, + 3 + -0.227097, + 1 + -0.738505, + 1 + 0.364707, + 1 + -0.522339, + -3 + -0.123359, + -5 + 0.911237, + 7 + -0.856169, + -5 + 0.878138, + 1 + -0.761068, + 3 + 0.341228, + 7 + 0.0689835, + 3 + -0.15808, + 7 + -0.138551, + 3 + 0.368672, + 5 + -0.617489, + 1 + 0.404668, + -7 + -0.699522, + 5 + -0.997434, + 5 + 0.36597, + 5 + 0.785275, + 3 + -0.231849, + 3 + -0.0999933, + 1 + -0.109, + 3 + -0.686237, + 1 + -0.902631, + -7 + 0.51259, + -5 + 0.0942837, + 1 + 0.708383, + -3 + -0.861124, + -3 + -0.179481, + -3 + 0.779682, + 1 + -0.493657, + 1 + -0.418592, + -1 + 0.856146, + 3 + -0.0875076, + 7 + -0.483033, + -1 + 0.646554, + -1 + 0.974864, + -3 + -0.841565, + -7 + 0.228352, + -1 + -0.0205758, + 7 + -0.359954, + 7 + 0.314803, + 1 + -0.357785, + 7 + 0.751935, + 1 + 0.215695, + 5 + -0.190122, + -7 + 0.428353, + -1 + -0.890184, + 7 + 0.122886, + 1 + -0.557184, + 5 + -0.556109, + 7 + 0.828952, + -5 + -0.989435, + 7 + 0.830655, + -3 + -0.217279, + -1 + -0.835888, + -1 + 0.254548, + 5 + 0.523081, + 3 + 0.584681, + 1 + -0.0839997, + 5 + -0.186458, + 1 + 0.0540011, + -1 + 0.274899, + -7 + 0.116505, + 3 + 0.723544, + 5 + 0.136319, + 7 + -0.419947, + 5 + 0.476982, + 3 + 0.243726, + 3 + 0.0739162, + -3 + -0.028526, + -1 + -0.915011, + -7 + 0.764662, + 5 + -0.449836, + -1 + 0.54113, + -5 + 0.435229, + 3 + 0.0290581, + -7 + -0.416793, + 7 + 0.733392, + 1 + -0.222058, + -1 + -0.70491, + 1 + -0.738726, + 5 + 0.467214, + -5 + -0.820001, + 5 + -0.100838, + 3 + -0.867579, + -3 + 0.682739, + 5 + -0.418042, + -1 + 0.451298, + 5 + 0.494458, + 1 + -0.849409, + 1 + -0.69703, + 1 + 0.852578, + -1 + -0.781506, + -1 + 0.477606, + 3 + -0.215093, + -1 + 0.741802, + -7 + 0.574622, + 5 + 0.855315, + 5 + 0.655386, + 1 + -0.0553299, + -1 + -0.801709, + -1 + 0.610893, + 1 + -0.996069, + -1 + -0.632696, + 7 + 0.337866, + -5 + -0.444426, + 7 + 0.557502, + 3 + 0.171951, + 7 + 0.0341445, + 3 + 0.332677, + 3 + 0.169284, + 3 + -0.273138, + -5 + 0.31627, + -1 + -0.456444, + 5 + -0.892569, + 3 + 0.936689, + 5 + -0.406369, + -5 + 0.589934, + -3 + -0.20777, + -1 + 0.757187, + -5 + 0.629676, + 5 + 0.365524, + 5 + 0.289739, + -7 + -0.182101, + -1 + 0.784527, + -3 + 0.382947, + 3 + -0.380673, + 3 + -0.748491, + 1 + 0.642036, + -1 + 0.423028, + -3 + -0.740949, + -7 + 0.0430477, + -5 + 0.916659, + 1 + -0.858744, + 1 + 0.354461, + -5 + 0.197777, + 1 + 0.132034, + 5 + -0.935967, + -7 + 0.920792, + 3 + -0.456423, + 1 + -0.288826, + 1 + -0.600615, + 7 + -0.975289, + -5 + -0.259924, + -1 + -0.640925, + -3 + 0.531508, + 1 + 0.560676, + 1 + -0.36099, + -5 + 0.122059, + -5 + -0.701523, + 3 + -0.620508, + 3 + -0.918876, + 5 + -0.716268, + 7 + -0.885677, + 7 + -0.812334, + 5 + -0.427292, + -7 + -0.543744, + 3 + -0.917745, + 1 + 0.285421, + 7 + -0.938258, + -3 + 0.845977, + 5 + -0.817096, + -3 + -0.81931, + 7 + 0.384529, + -5 + 0.923807, + -5 + -0.835286, + -3 + 0.495043, + -7 + 0.610036, + 3 + 0.691557, + 1 + 0.262664, + -7 + 0.312157, + -5 + -0.629477, + -7 + -0.396994, + 5 + -0.749666, + -3 + -0.693143, + 5 + 0.427751, + 1 + 0.18179, + -5 + 0.994096, + 5 + -0.868472, + -3 + -0.000652722, + 5 + -0.826959, + 7 + 0.810413, + -7 + 0.624387, + 3 + -0.0808038, + -3 + 0.766962, + 7 + -0.576073, + -1 + 0.549271, + -7 + -0.831344, + 7 + -0.693934, + -1 + 0.494453, + -1 + 0.201426, + 7 + 0.722833, + 5 + -0.156928, + -5 + 0.470001, + 5 + 0.928162, + 3 + 0.282769, + -1 + 0.914984, + 7 + 0.453746, + 7 + 0.641607, + -7 + -0.00260904, + -5 + -0.1964, + -3 + 0.251894, + 7 + 0.528101, + 3 + 0.110567, + 3 + 0.589285, + 3 + -0.820993, + -1 + 0.933257, + 3 + 0.400226, + 3 + 0.307276, + 5 + -0.485213, + -7 + 0.442066, + 1 + -0.967156, + 3 + 0.725474, + 1 + -0.699786, + -7 + 0.506006, + 7 + 0.513752, + -3 + -0.55039, + -5 + 0.997721, + -1 + 0.875475, + 3 + 0.935239, + -5 + 0.114364, + 1 + -0.956559, + 7 + -0.360408, + 1 + 0.198951, + -1 + -0.202082, + 5 + 0.6909, + -1 + 0.530785, + -7 + 0.117763, + 1 + -0.671653, + -1 + -0.301334, + -3 + -0.0852486, + -5 + 0.24372, + 7 + -0.937574, + -3 + 0.970979, + -5 + -0.307326, + -3 + 0.755383, + -7 + -0.0614709, + 7 + -0.354787, + 3 + -0.195025, + 7 + -0.294593, + 1 + 0.679208, + 5 + 0.876946, + 1 + 0.896838, + -1 + 0.343962, + -7 + -0.0557097, + 3 + 0.335734, + -1 + 0.00658689, + 7 + -0.707898, + -1 + 0.355665, + -1 + -0.598976, + -5 + -0.591982, + 7 + -0.485165, + 1 + -0.624015, + -3 + -0.545053, + -3 + -0.584821, + 1 + -0.748295, + -1 + 0.603633, + 5 + -0.281878, + -3 + 0.887608, + -5 + -0.701604, + 3 + 0.583568, + -7 + -0.987855, + 7 + 0.0166069, + -3 + 0.156798, + -7 + 0.693214, + 7 + 0.197865, + 7 + 0.461644, + 7 + -0.751676, + -1 + 0.989154, + -3 + -0.828416, + 5 + 0.478627, + -5 + -0.225786, + 3 + 0.146553, + 3 + 0.242108, + 1 + -0.991743, + 5 + -0.23658, + 1 + 0.712781, + -1 + -0.320432, + -1 + -0.272036, + 3 + 0.601587, + 5 + -0.176224, + 7 + -0.599448, + -5 + 0.821199, + -5 + -0.650962, + -5 + 0.54749, + -7 + 0.846249, + -5 + 0.895817, + 3 + -0.368985, + 1 + -0.479081, + -3 + 0.780251, + -3 + 0.30783, + -5 + -0.0721856, + -7 + -0.0359803, + 3 + -0.559485, + 1 + 0.296459, + 7 + 0.19517, + -5 + -0.686891, + 3 + 0.126611, + 5 + -0.0218955, + 5 + -0.0897653, + 5 + -0.476869, + 5 + -0.36738, + 1 + -0.905938, + -5 + 0.769578, + -7 + -0.911913, + -5 + 0.243897, + 3 + 0.688956, + 5 + 0.278523, + -5 + 0.119666, + 5 + -0.0967183, + -7 + -0.925501, + 1 + -0.609733, + -1 + 0.538315, + 3 + -0.49403, + -7 + 0.00403903, + -1 + 0.422778, + 1 + -0.676254, + -5 + -0.495082, + -3 + 0.887213, + -7 + -0.210539, + -5 + 0.802399, + -3 + -0.205944, + 5 + -0.684772, + -7 + 0.844196, + -5 + -0.69577, + 5 + -0.822575, + -7 + -0.158769, + 5 + 0.942987, + -7 + -0.739025, + 3 + 0.791325, + 1 + -0.931093, + -7 + -0.8201, + 3 + -0.732275, + -1 + 0.945871, + 3 + -0.891814, + -7 + 0.0258538, + 3 + 0.892123, + 1 + -0.880949, + -3 + -0.633805, + -3 + -0.709181, + -3 + -0.383623, + 3 + -0.150093, + -7 + -0.117931, + 1 + -0.307017, + 3 + 0.380702, + -5 + -0.594801, + 5 + -0.43212, + 5 + 0.920089, + 7 + -0.804395, + 1 + -0.918654, + -1 + -0.904769, + 7 + -0.78175, + 7 + 0.322011, + 3 + -0.294538, + -7 + 0.930585, + 1 + -0.477718, + -5 + -0.989844, + -1 + 0.902946, + -7 + -0.350604, + 7 + 0.126035, + -7 + -0.920143, + -7 + 0.851657, + 3 + -0.136341, + 3 + 0.593154, + -5 + -0.803969, + -5 + 0.503475, + 5 + 0.0188022, + 5 + 0.631931, + 7 + 0.91577, + -7 + -0.549304, + 1 + -0.723671, + -1 + -0.305956, + -5 + 0.74761, + -3 + 0.355676, + -1 + 0.855675, + 3 + 0.613764, + 7 + 0.700543, + -5 + -0.132191, + -1 + -0.0646009, + -5 + 0.590769, + -3 + -0.49326, + -1 + 0.216807, + -3 + -0.946063, + 1 + 0.186966, + -7 + 0.790963, + -1 + 0.45715, + 1 + 0.743977, + -5 + -0.136574, + -3 + -0.888679, + -5 + -0.732167, + 7 + -0.397459, + -7 + -0.0469681, + -7 + 0.615953, + -5 + 0.439568, + 3 + 0.273846, + 7 + 0.314949, + 3 + 0.911291, + -5 + -0.453662, + 3 + 0.80863, + 3 + -0.0106643, + 5 + 0.607597, + 7 + 0.356758, + 1 + -0.6931, + -5 + 0.371134, + -3 + -0.711628, + 7 + 0.944743, + -7 + 0.202408, + -1 + 0.728236, + -3 + 0.684351, + 3 + -0.40255, + 1 + -0.186503, + -1 + 0.0150248, + 3 + 0.185297, + -7 + 0.36002, + 3 + 0.750152, + 5 + -0.381467, + 7 + 0.334737, + -3 + 0.0568684, + 3 + -0.567396, + 5 + -0.995164, + 1 + 0.602424, + 7 + 0.0454783, + 3 + 0.516061, + 5 + -0.199994, + 1 + 0.737877, + 7 + 0.411311, + 5 + -0.853456, + 5 + -0.121685, + 7 + -0.507778, + -7 + 0.152738, + -7 + 0.094981, + 1 + -0.681713, + 5 + 0.442789, + 5 + 0.973592, + 1 + -0.323444, + 1 + 0.863931, + -1 + 0.396984, + 7 + 0.249854, + 1 + 0.807021, + 7 + 0.644638, + -7 + -0.422386, + 1 + 0.0698824, + -1 + 0.24009, + -3 + -0.406826, + 3 + -0.997362, + -7 + -0.410919, + 3 + 0.0102449, + 5 + -0.495212, + 3 + 0.260833, + -7 + -0.397034, + 1 + -0.379961, + 3 + 0.483326, + 7 + -0.909255, + -7 + 0.950334, + -1 + -0.970264, + -1 + 0.276129, + -7 + -0.0553154, + -7 + 0.322334, + -3 + -0.902084, + 7 + 0.29514, + -5 + 0.864139, + 3 + 0.925323, + -3 + 0.338491, + 3 + -0.0651398, + 3 + 0.912289, + -3 + 0.52022, + -3 + -0.709139, + 3 + -0.742856, + 7 + 0.565104, + 5 + 0.894589, + 5 + -0.556394, + -1 + -0.864631, + -5 + 0.794986, + -7 + -0.869075, + 7 + 0.774674, + 3 + 0.428512, + -5 + 0.839244, + -1 + 0.357717, + -7 + 0.199788, + -1 + -0.458671, + 7 + 0.526558, + -1 + -0.318607, + -5 + 0.630471, + -3 + -0.441537, + -1 + -0.580994, + -1 + 0.690485, + 3 + -0.547178, + 7 + 0.0732123, + 7 + -0.552486, + 3 + -0.133145, + 5 + -0.933638, + 1 + 0.255392, + -3 + -0.280157, + -5 + -0.150034, + 5 + -0.122912, + 5 + 0.941452, + -3 + 0.188547, + 3 + -0.211247, + 7 + 0.946076, + -3 + 0.92071, + 1 + 0.972226, + -5 + 0.852144, + 3 + 0.377145, + -1 + 0.413943, + -7 + 0.439598, + -5 + -0.13615, + 5 + 0.171454, + -5 + 0.845844, + -7 + 0.783942, + 3 + -0.618869, + -7 + 0.760145, + 5 + -0.0578561, + -1 + -0.582842, + 3 + -0.155049, + 5 + -0.220217, + 7 + -0.73738, + 1 + -0.767926, + -1 + -0.1484, + 7 + 0.834785, + 1 + 0.101825, + -7 + -0.449194, + 3 + 0.11657, + -1 + 0.904672, + -5 + 0.054498, + 3 + 0.924094, + -5 + -0.0965653, + 1 + -0.613703, + -7 + 0.4126, + -3 + 0.584113, + -7 + 0.159096, + -5 + -0.485646, + 3 + -0.0365765, + -3 + -0.417187, + 7 + 0.916336, + -1 + 0.725319, + 1 + 0.494014, + -5 + -0.532621, + -1 + 0.646111, + -7 + -0.417253, + -1 + -0.0992868, + -1 + 0.654899, + 3 + -0.444689, + 3 + 0.800794, + 1 + -0.112122, + -1 + -0.712385, + -3 + 0.166391, + 5 + 0.314575, + -5 + 0.950806, + 3 + -0.44719, + 1 + -0.175398, + 5 + -0.225897, + 3 + 0.258122, + -1 + -0.571683, + -3 + 0.745108, + 7 + -0.489975, + 3 + 0.869279, + 3 + -0.536627, + 5 + -0.828879, + -7 + -0.62512, + -7 + -0.456803, + 7 + 0.142581, + 7 + -0.220935, + 7 + 0.012534, + -5 + -0.681989, + -7 + 0.622798, + 1 + -0.557702, + -3 + 0.482869, + 5 + 0.197984, + 3 + 0.934018, + 7 + -0.094445, + -7 + 0.325073, + 7 + 0.917923, + -7 + 0.17338, + -5 + -0.354761, + -5 + 0.71292, + -1 + -0.877613, + 7 + -0.857628, + -7 + 0.5547, + 5 + 0.819892, + 5 + 0.550559, + 3 + -0.0277248, + 3 + 0.0711193, + -3 + -0.0491096, + -5 + -0.860672, + 3 + -0.0807872, + -5 + 0.651853, + 7 + 0.104082, + -7 + 0.236164, + -1 + -0.330286, + -7 + -0.480073, + 3 + 0.406925, + -5 + -0.518305, + -1 + -0.605615, + -1 + 0.381587, + -1 + -0.11044, + 3 + -0.160278, + 1 + -0.304637, + -1 + -0.527384, + -7 + 0.882399, + 3 + -0.777911, + -7 + -0.0419154, + 1 + -0.719173, + -7 + 0.936713, + -3 + -0.751213, + -3 + 0.441754, + 1 + -0.0637285, + -1 + 0.375699, + 7 + -0.153902, + 7 + -0.792171, + 5 + 0.655847, + 7 + 0.882999, + 5 + 0.0812634, + 3 + 0.546496, + -7 + -0.223494, + -1 + -0.356427, + 1 + 0.310918, + -7 + 0.571231, + -1 + 0.798337, + -3 + 0.598408, + -3 + 0.72025, + 3 + 0.51356, + -3 + -0.167374, + 3 + 0.240713, + 5 + 0.933577, + 5 + 0.267443, + -7 + 0.853163, + 7 + 0.751923, + 1 + -0.76546, + 1 + -0.464537, + -5 + -0.307334, + 1 + 0.78241, + -3 + -0.998566, + -1 + 0.35207, + -5 + 0.427847, + -5 + 0.110459, + 3 + 0.834955, + -7 + 0.254993, + 5 + 0.368997, + 1 + 0.697111, + 5 + 0.458215, + 5 + 0.0957664, + 7 + -0.97862, + -7 + -0.615026, + 3 + 0.859467, + 5 + -0.306685, + 1 + 0.305295, + -5 + 0.093081, + -3 + 0.673005, + 1 + 0.985715, + -5 + -0.944994, + -5 + 0.817741, + 7 + -0.898887, + 7 + -0.742699, + -7 + 0.298725, + 5 + -0.180113, + -7 + 0.18706, + 1 + 0.185461, + -1 + -0.522394, + -1 + -0.117225, + -7 + -0.143794, + -3 + -0.273471, + 1 + 0.139797, + 5 + -0.265773, + 3 + 0.427259, + 3 + -0.869272, + -5 + -0.144366, + -1 + 0.337665, + -1 + 0.171026, + 5 + -0.79788, + -5 + 0.192947, + -5 + -0.311556, + 5 + 0.785642, + -1 + -0.505434, + -1 + 0.233518, + 1 + 0.420173, + -1 + 0.163412, + 7 + 0.605216, + 1 + -0.593143, + -1 + -0.957213, + -1 + -0.515973, + 1 + 0.525257, + -5 + 0.446536, + 1 + 0.486375, + -3 + -0.5737, + 3 + -0.217493, + -1 + 0.517623, + -7 + 0.920525, + 5 + 0.365421, + 5 + 0.00848039, + -5 + 0.153402, + 1 + 0.13929, + 5 + 0.977456, + -7 + 0.22807, + -1 + -0.119464, + -1 + -0.351284, + -1 + -0.991155, + 7 + 0.889795, + -3 + 0.691846, + 1 + -0.746596, + -3 + 0.586713, + 5 + 0.596188, + -7 + -0.477961, + 3 + -0.620132, + 5 + -0.0775085, + 1 + -0.165338, + 5 + -0.211165, + 7 + -0.0470844, + 7 + -0.748061, + -3 + -0.810057, + 5 + -0.196284, + -7 + 0.0831261, + 7 + 0.823358, + 3 + -0.628647, + 7 + 0.576381, + -3 + -0.347779, + 7 + 0.223497, + -7 + -0.526754, + -7 + 0.806814, + -7 + -0.725776, + 5 + -0.793048, + -3 + -0.678268, + 7 + -0.718848, + 1 + 0.914832, + -5 + 0.808905, + 5 + 0.664148, + 3 + -0.151127, + -3 + -0.289634, + 7 + 0.276275, + 5 + 0.0411116, + -3 + 0.180697, + 7 + -0.957571, + 5 + -0.931349, + 3 + 0.346197, + 3 + 0.855933, + 1 + -0.9529, + -1 + -0.687524, + 1 + 0.393423, + 7 + 0.946512, + -5 + 0.361563, + 1 + 0.197133, + -5 + 0.313557, + 3 + -0.932788, + 3 + -0.342819, + 3 + 0.07439, + -7 + 0.703045, + -5 + -0.37896, + 1 + -0.175719, + 5 + 0.223835, + 5 + -0.516742, + -7 + 0.791386, + -3 + 0.594912, + 3 + 0.917958, + -3 + -0.550284, + 5 + 0.161439, + -1 + 0.308031, + -3 + 0.129603, + -5 + -0.755601, + -5 + -0.0725142, + -3 + 0.900576, + 5 + -0.0439364, + 3 + -0.571107, + -5 + -0.696274, + -7 + -0.101347, + 1 + 0.364593, + -7 + -0.428825, + -7 + 0.723648, + -7 + -0.196055, + 5 + -0.466505, + -3 + 0.906948, + 7 + 0.869376, + -1 + 0.965839, + 3 + -0.279962, + 1 + 0.734883, + 5 + 0.829225, + -3 + 0.931521, + 3 + 0.362365, + -7 + 0.797885, + -7 + 0.497423, + 3 + 0.776487, + 7 + 0.636682, + 1 + 0.285877, + 5 + 0.662518, + 3 + -0.273415, + -3 + -0.609258, + 7 + -0.621225, + 5 + 0.795938, + -1 + 0.330694, + -3 + 0.690014, + 1 + -0.493836, + -7 + 0.308625, + -3 + -0.948984, + -1 + -0.553156, + 1 + -0.561592, + 5 + 0.835248, + 7 + -0.722998, + -3 + -0.147382, + 3 + -0.986829, + 3 + -0.428939, + 7 + -0.486681, + -3 + -0.512164, + -7 + -0.849359, + 1 + 0.169338, + -3 + 0.794093, + 5 + -0.54137, + 5 + -0.526859, + -1 + 0.452928, + 1 + -0.42493, + -1 + 0.121008, + 3 + 0.227603, + -3 + -0.933629, + -7 + -0.176661, + 7 + -0.444884, + 5 + 0.0810715, + 5 + -0.139102, + 7 + -0.726052, + -3 + 0.342913, + 3 + -0.586903, + 7 + 0.619812, + 7 + 0.513767, + 3 + 0.179749, + -5 + 0.28388, + 5 + 0.494988, + 7 + -0.697871, + -1 + 0.320561, + 3 + 0.336703, + -5 + 0.277044, + -5 + 0.637778, + 3 + -0.778878, + -7 + 0.563479, + 5 + 0.933587, + -1 + -0.0155785, + 7 + 0.967945, + 7 + -0.441443, + -1 + 0.476776, + -1 + 0.784109, + 1 + 0.282272, + -3 + 0.120237, + 5 + 0.909491, + 7 + 0.0166548, + 1 + 0.0874624, + 7 + -0.943263, + -7 + 0.404136, + -3 + -0.425458, + 5 + -0.279096, + -7 + 0.297659, + -5 + -0.909941, + -3 + 0.417617, + 3 + 0.541595, + 5 + 0.553146, + -7 + -0.758788, + -3 + 0.810651, + 3 + 0.824127, + 3 + -0.860216, + 1 + -0.301784, + -7 + 0.774392, + -3 + -0.409294, + -1 + -0.233762, + 7 + -0.169785, + -3 + 0.0785076, + 5 + 0.612462, + 3 + -0.436439, + -7 + 0.879343, + 1 + 0.639467, + 1 + 0.052389, + -5 + -0.0166562, + -3 + 0.341038, + 5 + -0.828713, + 3 + 0.794875, + -1 + 0.45125, + -3 + 0.681263, + -5 + 0.420113, + -7 + -0.367513, + -7 + 0.706676, + -3 + -0.494458, + -3 + -0.834332, + -5 + -0.683485, + -1 + -0.0354494, + -5 + -0.604827, + 3 + 0.413222, + -3 + 0.275839, + 1 + 0.456946, + -7 + -0.171177, + -7 + -0.518215, + -7 + 0.0480101, + 3 + -0.543404, + 3 + 0.634555, + 7 + 0.509344, + 5 + 0.032606, + -7 + 0.847702, + -7 + -0.382019, + 1 + -0.893403, + -3 + 0.0839257, + -5 + -0.605519, + 5 + -0.398689, + -1 + 0.777001, + 1 + 0.557634, + 5 + -0.203117, + -7 + 0.388056, + -1 + -0.841352, + 5 + 0.571447, + -1 + 0.540101, + 7 + 0.707744, + 3 + 0.0310338, + -1 + -0.222217, + -3 + 0.878539, + 7 + 0.0656955, + -1 + 0.579365, + -7 + 0.77745, + 5 + -0.330132, + -1 + -0.181327, + 5 + -0.936911, + 7 + -0.28417, + -1 + 0.184943, + 3 + 0.470113, + -3 + -0.668268, + 3 + 0.443922, + -7 + -0.254059, + -5 + -0.998164, + -7 + -0.293805, + -7 + 0.0910158, + 7 + 0.692813, + -1 + -0.0799075, + -7 + 0.721993, + -1 + 0.385094, + 5 + -0.00619203, + 7 + 0.552784, + 1 + -0.596967, + -5 + -0.00704482, + 1 + -0.110811, + 3 + 0.121887, + 3 + 0.674047, + -3 + 0.170743, + 3 + 0.760664, + -3 + 0.42977, + 1 + 0.315997, + 5 + 0.154003, + -3 + 0.369766, + -3 + 0.646692, + -3 + -0.0673465, + 3 + -0.0560396, + -7 + 0.138723, + 7 + -0.0105182, + -7 + -0.742613, + -1 + -0.0661037, + 3 + 0.00532501, + 5 + -0.755478, + -3 + 0.363332, + -7 + -0.299669, + -1 + 0.27668, + 1 + -0.117032, + -1 + -0.0241725, + 3 + 0.0823766, + -7 + -0.207114, + 5 + -0.0581861, + -5 + 0.689536, + -5 + -0.206481, + 3 + -0.457966, + 7 + -0.489086, + -5 + 0.467335, + -3 + -0.360001, + -1 + -0.138445, + -7 + -0.914763, + 7 + 0.588969, + -5 + 0.283839, + -7 + 0.959326, + -7 + -0.67792, + -7 + -0.334574, + 7 + 0.370579, + 7 + -0.171007, + 3 + -0.868796, + -3 + -0.319757, + 3 + -0.879288, + -3 + -0.435152, + 1 + -0.700487, + 5 + -0.313853, + -5 + 0.0436639, + -3 + -0.579779, + -3 + -0.778584, + -5 + -0.789192, + -7 + -0.0165036, + 5 + -0.746662, + 3 + 0.423599, + 1 + -0.896458, + 1 + 0.884175, + -7 + -0.861808, + 1 + 0.0740701, + -7 + 0.338526, + 7 + 0.292062, + 3 + 0.948647, + 3 + -0.473585, + 5 + -0.420246, + 3 + -0.949748, + -3 + -0.593698, + -1 + -0.996076, + 1 + -0.862255, + 7 + 0.137548, + -7 + -0.28388, + 5 + 0.534124, + 5 + 0.434866, + 5 + 0.139012, + 5 + -0.468484, + -7 + 0.740186, + -7 + -0.376626, + -3 + -0.183861, + -1 + 0.669948, + 5 + 0.859722, + 1 + -0.138174, + -5 + -0.573832, + 5 + -0.940617, + 7 + -0.267174, + 7 + -0.3461, + -7 + -0.741914, + -3 + -0.322358, + -5 + 0.718059, + -7 + -0.97611, + -3 + 0.154576, + -1 + -0.183644, + 1 + -0.575116, + -3 + 0.825954, + 3 + -0.751385, + 7 + -0.607166, + -5 + -0.500472, + 7 + 0.882115, + -7 + 0.0493956, + -5 + 0.362625, + -3 + 0.492293, + 5 + 0.389105, + -5 + 0.800949, + 1 + 0.94705, + -7 + -0.377441, + 7 + 0.351678, + 7 + -0.44366, + -1 + 0.320667, + -1 + 0.752543, + 1 + 0.969968, + -7 + 0.0223379, + 5 + -0.91498, + -7 + -0.172866, + -5 + -0.173087, + 5 + 0.996417, + -1 + -0.490241, + -3 + 0.91821, + 7 + -0.563976, + 5 + -0.485962, + -7 + 0.892581, + -3 + -0.460805, + 3 + 0.941525, + 1 + -0.174042, + -3 + 0.838862, + -7 + -0.156077, + -7 + 0.466488, + 1 + -0.724364, + 7 + 0.587571, + 3 + -0.274185, + 5 + -0.514854, + -3 + 0.254629, + 7 + -0.291446, + 5 + -0.0912776, + -3 + -0.54812, + 5 + -0.0964439, + -1 + -0.952324, + -3 + 0.477252, + -5 + -0.75421, + -7 + -0.536212, + 1 + 0.97589, + 1 + -0.534707, + 1 + -0.610279, + -5 + -0.380512, + 3 + -0.213305, + 7 + 0.951862, + 1 + 0.514467, + 3 + -0.52728, + 7 + -0.107415, + -1 + 0.530744, + -7 + -0.780547, + -7 + 0.601507, + -1 + -0.884028, + -5 + 0.295033, + 5 + 0.216542, + -3 + 0.803556, + -5 + 0.408551, + -1 + 0.0640241, + -7 + 0.337687, + -3 + 0.973948, + -7 + -0.112561, + 3 + 0.497891, + -1 + -0.360651, + 1 + 0.429832, + 3 + 0.599578, + -7 + 0.62018, + -5 + 0.00679079, + -7 + 0.214149, + 7 + 0.840447, + -3 + -0.167543, + 5 + 0.0564775, + -7 + 0.824302, + 3 + 0.0793194, + 3 + 0.999321, + -1 + -0.446545, + -3 + 0.703463, + 7 + 0.991686, + -1 + -0.894842, + -7 + -0.011711, + 5 + 0.280148, + -7 + 0.854388, + -7 + -0.187445, + -1 + 0.594443, + -7 + 0.933654, + 1 + 0.297684, + 7 + 0.305794, + 5 + -0.871352, + -5 + -0.415714, + -3 + -0.437484, + -5 + 0.425868, + 3 + 0.413091, + -5 + 0.413299, + 7 + -0.94675, + 1 + 0.403995, + 7 + 0.792962, + -3 + -0.663822, + -1 + 0.782255, + 5 + 0.740358, + 5 + 0.64335, + -3 + -0.677456, + -7 + 0.318753, + 3 + 0.637624, + 5 + 0.716802, + -3 + 0.506525, + -5 + -0.0154431, + 5 + -0.413524, + -3 + -0.97805, + 3 + -0.715193, + -1 + 0.855351, + -3 + -0.547344, + -1 + 0.707832, + -7 + -0.100186, + -3 + 0.1044, + -1 + 0.834975, + 5 + 0.950804, + -3 + -0.146867, + 7 + -0.922332, + -5 + 0.361724, + 1 + -0.376783, + 1 + -0.979652, + -3 + -0.860688, + 7 + -0.0470151, + 7 + -0.29374, + 1 + -0.820914, + -1 + -0.811114, + 5 + -0.585238, + 3 + 0.0997306, + -5 + -0.789875, + 5 + -0.240234, + 5 + -0.795669, + -3 + 0.834812, + -5 + -0.0813862, + 5 + -0.154017, + -5 + 0.414384, + 1 + 0.878358, + -7 + -0.0818945, + 3 + -0.239543, + -3 + -0.203324, + -3 + -0.921207, + 5 + 0.69081, + 1 + -0.727172, + 1 + 0.287061, + 3 + 0.216088, + 1 + -0.47675, + -1 + 0.679726, + -1 + 0.147156, + 3 + 0.785956, + 5 + -0.0128753, + -1 + -0.198679, + 7 + 0.16421, + -7 + -0.41241, + -7 + 0.785757, + 1 + 0.502945, + -3 + -0.611199, + 1 + 0.589565, + -1 + -0.0650551, + -5 + -0.575992, + -3 + -0.744359, + 5 + -0.856259, + -1 + 0.95337, + -7 + 0.285215, + 3 + -0.692112, + 1 + 0.427753, + 5 + -0.771773, + 1 + 0.469569, + -1 + -0.428564, + 7 + 0.465778, + 7 + -0.468184, + 7 + 0.958522, + 1 + -0.129728, + -7 + 0.48096, + 7 + -0.127209, + 7 + -0.725595, + -5 + -0.100204, + -3 + 0.231591, + 7 + 0.54961, + 5 + 0.714396, + -5 + -0.891057, + 7 + 0.0990063, + 5 + -0.0485793, + 5 + 0.350462, + -7 + 0.683771, + 1 + -0.69861, + 1 + 0.0453779, + -1 + -0.609794, + 3 + -0.30366, + -1 + -0.0804034, + -1 + -0.119469, + 3 + 0.0833771, + -1 + 0.365207, + -3 + 0.569098, + 1 + 0.122556, + -3 + 0.383273, + -3 + 0.873332, + 5 + -0.992991, + -5 + -0.888515, + 5 + 0.0792137, + 7 + -0.949043, + -5 + -0.311345, + 1 + 0.129391, + -7 + 0.514229, + -7 + -0.889496, + 1 + -0.188848, + 5 + -0.47186, + -5 + -0.0947434, + -5 + -0.860318, + -5 + 0.240262, + 5 + -0.855161, + -7 + -0.682376, + 5 + -0.268279, + -1 + 0.574063, + -1 + -0.607989, + 3 + 0.563884, + -1 + -0.28172, + 5 + 0.889506, + 3 + 0.961434, + 1 + 0.701135, + -3 + -0.36667, + -7 + -0.665516, + 5 + -0.982884, + -7 + -0.444751, + -3 + -0.0457394, + 1 + 0.686493, + 3 + -0.763344, + -3 + -0.969778, + -5 + 0.557193, + 3 + -0.70817, + -3 + -0.0794386, + 7 + -0.674222, + 1 + 0.776054, + 3 + 0.0315101, + -5 + 0.629314, + -3 + 0.0376186, + -1 + 0.363226, + 7 + -0.829763, + 7 + -0.252856, + 5 + -0.622667, + 3 + -0.409799, + 1 + 0.33154, + 5 + 0.731536, + 7 + 0.702268, + 5 + 0.926338, + 5 + 0.843521, + -3 + -0.505366, + 3 + 0.034738, + 7 + 0.935227, + 3 + -0.633068, + 5 + 0.612473, + 7 + -0.0785781, + 7 + -0.209858, + 3 + -0.519326, + -1 + -0.900059, + 5 + 0.167903, + 7 + -0.237923, + 1 + 0.568017, + -3 + 0.338209, + 1 + -0.262908, + 1 + 0.0486361, + 7 + 0.05413, + 5 + -0.900298, + -1 + 0.13673, + 5 + 0.256166, + 5 + 0.302061, + -5 + 0.399097, + 5 + -0.379186, + -5 + 0.623826, + 5 + -0.436995, + 3 + 0.15716, + -1 + -0.839201, + -5 + -0.0482146, + 5 + -0.580043, + -5 + -0.276397, + -7 + -0.224163, + -7 + 0.569099, + 1 + 0.112961, + 7 + 0.695617, + -5 + -0.985498, + -5 + 0.624633, + -5 + -0.698944, + 1 + 0.290597, + -1 + 0.492301, + 5 + -0.873225, + 5 + 0.517916, + 1 + -0.739614, + -5 + -0.118872, + -7 + 0.429263, + 5 + -0.374059, + -3 + -0.196779, + 5 + 0.845428, + 3 + -0.825515, + 1 + -0.324621, + 3 + -0.321085, + 5 + 0.659568, + -7 + 0.507627, + 3 + -0.762506, + -5 + 0.0177499, + 1 + -0.969493, + 5 + -0.989013, + 7 + 0.639013, + 5 + -0.293451, + -3 + -0.399314, + 3 + -0.164182, + -5 + -0.0115777, + -7 + 0.728109, + 1 + 0.0601385, + -3 + 0.53905, + -3 + 0.557821, + -3 + 0.267226, + 7 + 0.484006, + 3 + -0.462906, + 7 + 0.593879, + 7 + 0.70928, + 3 + 0.783019, + 7 + -0.390819, + 5 + 0.447453, + -1 + -0.327203, + -7 + -0.249398, + -5 + -0.100986, + 1 + -0.155282, + -7 + -0.798511, + -5 + -0.415777, + 1 + 0.971724, + -3 + -0.087326, + 7 + 0.946116, + -7 + -0.681513, + 1 + -0.564743, + 5 + 0.939016, + 3 + -0.437047, + -7 + -0.551414, + -3 + 0.489793, + 5 + -0.535763, + -3 + -0.98994, + 7 + 0.192269, + -5 + 0.802636, + -3 + 0.335588, + -7 + -0.346334, + 7 + 0.710128, + 7 + 0.359396, + 7 + 0.167325, + -1 + -0.359781, + 5 + -0.450043, + -3 + -0.399062, + -1 + 0.220616, + -1 + -0.713507, + 5 + -0.323577, + -3 + -0.324612, + -5 + -0.0478501, + 7 + 0.0652244, + -1 + 0.694262, + -5 + 0.234324, + -1 + 0.684074, + -3 + 0.885926, + -1 + 0.709219, + 7 + -0.403976, + -5 + 0.0613845, + -5 + 0.578585, + 5 + 0.531759, + 5 + -0.823466, + 1 + 0.885001, + -5 + 0.678863, + 1 + 0.235131, + -5 + 0.741793, + -7 + 0.831432, + -3 + 0.524304, + 3 + -0.740704, + 7 + 0.507732, + 3 + -0.0357639, + 7 + 0.863181, + -1 + 0.576264, + 3 + 0.516363, + 3 + -0.764998, + -1 + -0.362159, + -5 + 0.197446, + 3 + -0.446453, + 3 + 0.981725, + 7 + 0.0734841, + 3 + 0.256196, + -3 + -0.77722, + -5 + 0.791577, + -7 + 0.402091, + 7 + 0.553504, + 1 + -0.93853, + -7 + 0.584471, + -3 + -0.437479, + 5 + 0.997935, + -5 + 0.682598, + -7 + 0.641139, + 3 + -0.732735, + -1 + 0.930625, + -7 + -0.488808, + 7 + -0.985779, + 7 + 0.526349, + 1 + 0.412067, + 7 + 0.405549, + 3 + 0.95903, + -3 + 0.304788, + 5 + -0.344784, + 7 + -0.707093, + 7 + 0.508233, + 3 + 0.704947, + 1 + 0.790839, + -7 + -0.789173, + -3 + -0.320104, + -5 + -0.0990607, + -1 + -0.181266, + 3 + 0.413149, + 5 + -0.445842, + 7 + 0.114297, + -1 + -0.0193645, + -3 + -0.630197, + 7 + 0.549956, + 3 + 0.832843, + -1 + 0.709999, + 5 + 0.35154, + -3 + 0.488788, + -1 + -0.367693, + 7 + 0.81898, + 3 + -0.977579, + -7 + 0.677679, + 3 + 0.0798718, + -5 + -0.361776, + -7 + 0.029239, + -3 + 0.752219, + -5 + 0.36909, + -1 + -0.845805, + -5 + 0.552649, + 7 + -0.320622, + 5 + -0.0791636, + -7 + 0.155842, + -5 + -0.383591, + -7 + -0.921708, + 7 + 0.262659, + -5 + -0.311854, + -3 + 0.909658, + 5 + 0.220908, + -5 + -0.24149, + 5 + 0.424055, + -7 + -0.115968, + -1 + -0.837231, + -3 + -0.943953, + -1 + -0.501246, + 3 + -0.30943, + -7 + 0.726022, + 5 + 0.468604, + 7 + -0.536298, + -5 + 0.180367, + -5 + 0.478635, + -5 + -0.983354, + -7 + 0.948823, + 7 + -0.964671, + -7 + 0.83219, + -1 + -0.00482819, + -5 + 0.910779, + 7 + 0.0379913, + 5 + 0.958815, + -7 + 0.37621, + 5 + -0.348852, + 1 + 0.251557, + 5 + 0.421582, + 7 + 0.100173, + -3 + -0.343514, + 7 + 0.866663, + -1 + 0.442026, + 7 + 0.0442502, + 3 + -0.617214, + 1 + -0.743735, + -5 + 0.458965, + 5 + -0.572788, + 5 + 0.040819, + 3 + -0.445056, + 5 + -0.58016, + 5 + 0.386475, + -5 + 0.470098, + 5 + -0.00197146, + 7 + -0.614743, + -7 + 0.632339, + 5 + -0.445174, + -5 + -0.462788, + -5 + 0.994442, + 5 + -0.0414883, + -5 + 0.882532, + 1 + 0.694469, + -5 + -0.36298, + -7 + 0.836014, + 1 + 0.247427, + 5 + -0.623588, + -3 + 0.509161, + 3 + -0.0136789, + -5 + 0.551708, + -5 + 0.714889, + 5 + 0.948555, + 7 + -0.542934, + -3 + 0.284379, + -1 + 0.445103, + 5 + -0.302788, + -3 + 0.782427, + -1 + -0.137974, + -1 + 0.874363, + -3 + -0.450784, + 1 + -0.962429, + -5 + 0.938102, + -7 + -0.879492, + 5 + 0.666352, + -5 + 0.146655, + -3 + 0.505806, + 3 + -0.90168, + 5 + -0.00662362, + -5 + 0.401645, + -5 + 0.516729, + 7 + -0.325518, + 7 + -0.670081, + 3 + -0.898185, + 7 + 0.725776, + -1 + -0.519448, + -1 + 0.101936, + 3 + -0.800607, + 7 + -0.407942, + 7 + -0.249011, + 7 + 0.974777, + -7 + 0.984282, + -1 + 0.177661, + -3 + 0.165499, + -5 + -0.145106, + 1 + 0.092101, + -3 + -0.287475, + -1 + -0.160128, + -5 + 0.20695, + -1 + 0.278086, + 7 + 0.376328, + -7 + 0.854766, + 7 + 0.242705, + -5 + -0.623362, + 1 + -0.755314, + -3 + -0.498729, + -5 + -0.742776, + 3 + -0.17839, + -7 + -0.141452, + -7 + 0.0890251, + 3 + -0.761854, + -7 + 0.316197, + 1 + 0.531921, + -1 + 0.763375, + -7 + 0.398482, + 1 + -0.930327, + -5 + 0.559533, + 3 + -0.782727, + -1 + -0.809251, + -3 + -0.827661, + -7 + -0.790187, + 3 + 0.886559, + 3 + -0.312838, + 7 + -0.205646, + 3 + 0.538917, + -5 + -0.151619, + 7 + -0.498444, + -1 + -0.777891, + -7 + 0.709902, + 5 + -0.842215, + -3 + -0.0873613, + -3 + 0.88423, + 1 + 0.50133, + 5 + 0.87654, + -1 + 0.775389, + -1 + 0.274183, + -7 + -0.1128, + 7 + 0.129837, + 7 + -0.138116, + 7 + 0.697651, + 3 + -0.363404, + 5 + -0.51758, + 5 + 0.276224, + -5 + -0.843988, + 5 + 0.965171, + 5 + -0.433201, + 5 + 0.77057, + 5 + -0.347871, + -1 + -0.337877, + 5 + 0.0192994, + 5 + -0.00149202, + 5 + -0.705596, + -7 + 0.848062, + 3 + -0.780618, + 3 + 0.33526, + -3 + -0.0251735, + 7 + -0.148926, + -1 + -0.655041, + -3 + -0.559493, + -3 + -0.604536, + 3 + -0.0386967, + -3 + 0.830413, + 1 + -0.428, + 5 + -0.0231212, + 7 + -0.199671, + 5 + -0.396984, + -3 + 0.687779, + -7 + -0.126673, + 3 + -0.14281, + 3 + -0.663755, + -1 + 0.590741, + 7 + -0.259138, + -1 + 0.36915, + 7 + -0.193918, + -3 + 0.074994, + 3 + 0.0734893, + 3 + -0.87442, + 5 + -0.277579, + -7 + 0.874191, + 1 + 0.603273, + -1 + -0.933543, + 7 + 0.952655, + 3 + -0.0753299, + -1 + -0.0547395, + 1 + 0.298926, + 7 + 0.89666, + -1 + -0.169361, + -7 + -0.0164988, + -1 + 0.536616, + 3 + 0.123214, + -3 + -0.686119, + -3 + 0.207928, + 1 + 0.690104, + -7 + -0.840309, + -1 + 0.22515, + 5 + -0.848586, + 7 + -0.266778, + -7 + -0.573275, + -1 + 0.792824, + 7 + -0.984161, + -3 + -0.188004, + 5 + -0.461688, + -1 + -0.62303, + 3 + -0.513087, + -1 + -0.0713464, + 7 + -0.4341, + 1 + 0.791935, + -7 + -0.216476, + -5 + -0.472753, + 7 + 0.887405, + 5 + -0.629382, + -1 + 0.960013, + -7 + -0.225607, + 5 + -0.783357, + 3 + 0.238133, + 1 + -0.939504, + 7 + 0.300807, + 7 + 0.714341, + -1 + 0.0662017, + -3 + 0.709742, + -1 + 0.80212, + -5 + 0.78005, + -3 + 0.252241, + -3 + -0.848605, + -7 + -0.928371, + -1 + 0.6205, + 3 + -0.355202, + 3 + -0.884526, + 1 + 0.766157, + 1 + -0.48066, + -5 + 0.148214, + -5 + 0.416083, + 1 + 0.141582, + 3 + 0.954276, + 7 + -0.598539, + 1 + 0.302432, + -7 + -0.302829, + -5 + 0.365095, + -5 + 0.291996, + -7 + -0.853708, + 3 + -0.27352, + 3 + 0.544414, + -1 + -0.459018, + 1 + 0.184556, + 3 + -0.52332, + -1 + -0.191827, + -1 + 0.670293, + 1 + 0.519123, + 5 + 0.841211, + -1 + -0.940759, + -1 + -0.251439, + -1 + 0.695483, + -3 + 0.557767, + -3 + 0.26932, + 1 + 0.0599606, + -5 + -0.731488, + -3 + -0.559606, + -7 + -0.161615, + -7 + -0.269363, + -3 + 0.700813, + -5 + -0.598768, + -3 + 0.805228, + 5 + -0.856961, + -1 + -0.385613, + -3 + -0.323487, + -7 + 0.411967, + -5 + 0.21551, + -7 + 0.010317, + -3 + 0.573196, + 3 + -0.360943, + -1 + 0.564722, + 7 + 0.0449874, + 5 + -0.230872, + -3 + -0.394789, + -3 + 0.992717, + 5 + 0.241152, + -1 + -0.849168, + 5 + 0.828781, + 5 + -0.408953, + -1 + -0.289148, + -1 + 0.222295, + 1 + -0.537086, + 3 + 0.306834, + -1 + -0.585661, + -7 + 0.538775, + 3 + -0.204193, + 7 + -0.77022, + 1 + -0.540422, + -5 + 0.104483, + 3 + 0.0113785, + -3 + 0.358089, + 7 + 0.83108, + 7 + -0.810261, + -1 + 0.0540461, + -1 + 0.87434, + -7 + -0.379698, + 5 + -0.722662, + -7 + -0.587491, + 3 + -0.152501, + 1 + -0.137736, + -1 + 0.137048, + -7 + -0.993715, + -5 + -0.817584, + -7 + 0.192652, + -7 + 0.965716, + 3 + -0.497121, + -3 + -0.583623, + 3 + 0.724106, + 3 + 0.906286, + 3 + 0.369401, + -5 + -0.333858, + -7 + 0.201107, + 1 + -0.481391, + 3 + 0.214079, + 1 + -0.634333, + 3 + 0.32668, + -5 + 0.438198, + 3 + 0.0183425, + -7 + -0.854446, + -3 + -0.749623, + 5 + 0.260525, + -3 + -0.246166, + 7 + -0.256046, + 5 + -0.0506104, + -5 + -0.546944, + -3 + 0.70895, + 7 + 0.671615, + -7 + -0.178744, + -7 + -0.296848, + 3 + -0.786894, + 1 + 0.486466, + 5 + 0.984005, + -3 + 0.755768, + -3 + 0.60431, + -7 + -0.658241, + 7 + -0.99308, + -7 + 0.730603, + 1 + -0.147345, + 3 + -0.914348, + -5 + 0.176437, + -5 + -0.883513, + -5 + -0.746214, + 1 + 0.599807, + -1 + -0.826388, + -1 + -0.231019, + 7 + -0.427187, + 3 + 0.436418, + -5 + -0.0296006, + 3 + 0.342193, + 5 + -0.02255, + -1 + 0.332447, + 1 + 0.627013, + -7 + -0.257934, + -5 + -0.61819, + -7 + 0.660406, + 7 + -0.749068, + -1 + -0.826357, + 7 + 0.259934, + 1 + 0.624619, + -5 + -0.409846, + -7 + 0.175771, + 7 + 0.841248, + -7 + -0.182872, + 7 + 0.728087, + 3 + -0.272224, + -1 + 0.694387, + 1 + 0.87123, + -7 + -0.36121, + -3 + 0.231829, + -3 + -0.288232, + -1 + 0.860921, + 3 + -0.667815, + -1 + -0.9711, + 3 + -0.778314, + 3 + -0.298502, + 7 + 0.460686, + -7 + -0.972103, + 1 + -0.791205, + -7 + -0.527057, + 3 + 0.680872, + 1 + 0.854739, + -7 + -0.673826, + -1 + 0.137268, + -1 + 0.333986, + -1 + 0.901741, + -1 + -0.202348, + -3 + -0.774122, + 1 + 0.589625, + 3 + -0.849021, + 7 + -0.456618, + 5 + 0.567717, + 5 + -0.636284, + 1 + 0.365766, + 1 + -0.511727, + -7 + 0.166757, + 5 + 0.919885, + 1 + -0.642062, + 5 + -0.296797, + -7 + -0.385574, + 7 + 0.591877, + -7 + 0.436025, + 3 + 0.451077, + -1 + -0.716762, + -3 + 0.374155, + 5 + 0.337632, + -7 + 0.723804, + -5 + 0.383933, + -3 + -0.0862489, + 3 + 0.990362, + 5 + 0.133119, + 1 + -0.12971, + 3 + 0.044241, + 3 + -0.964742, + -5 + 0.702827, + -5 + 0.52507, + 7 + 0.813182, + 7 + 0.456129, + -7 + -0.564425, + -3 + 0.681494, + -1 + 0.503007, + 1 + 0.488921, + -5 + -0.978964, + 5 + -0.978504, + -5 + 0.458051, + -7 + 0.0654869, + 3 + -0.245564, + -1 + -0.337528, + -5 + -0.55446, + -5 + 0.273099, + -7 + 0.215733, + 1 + -0.138924, + 7 + -0.219671, + 3 + -0.887201, + -7 + -0.516248, + -5 + -0.396037, + -5 + 0.818756, + 3 + -0.712209, + 7 + -0.282743, + -3 + 0.707385, + 7 + 0.359774, + -5 + -0.845302, + 1 + -0.1686, + -7 + -0.483578, + 1 + 0.720247, + 1 + 0.626128, + 7 + -0.2298, + -7 + -0.491252, + -1 + 0.568972, + 1 + 0.348875, + 5 + -0.21767, + 5 + -0.844788, + -7 + 0.212711, + -5 + -0.728646, + 5 + -0.257998, + -3 + 0.91577, + 3 + -0.356945, + -5 + -0.727851, + 3 + -0.839908, + -5 + -0.87513, + 5 + 0.492427, + 7 + 0.859239, + 5 + 0.63738, + 7 + -0.567552, + 7 + -0.311746, + -5 + -0.293624, + -5 + -0.0892278, + -1 + 0.68692, + -3 + -0.584071, + -7 + -0.368564, + 3 + 0.685985, + 1 + -0.443952, + 5 + -0.799968, + -5 + 0.849293, + 7 + 0.419622, + 7 + -0.719699, + -5 + 0.776349, + 7 + 0.353652, + -3 + -0.957607, + 7 + -0.233657, + -3 + 0.110137, + -5 + -0.825374, + -5 + 0.936229, + 3 + 0.611605, + -5 + 0.598961, + 3 + 0.914424, + -5 + 0.185668, + 1 + -0.506371, + -1 + 0.19368, + -3 + 0.135954, + 5 + 0.0317122, + -3 + 0.926598, + 3 + 0.841409, + -7 + -0.995628, + 7 + -0.516938, + 1 + -0.327213, + -7 + -0.988622, + 7 + 0.0436381, + -1 + -0.736482, + 3 + 0.0252206, + -7 + -0.999107, + 1 + 0.287324, + 3 + -0.710148, + -3 + -0.863982, + 5 + -0.110109, + -1 + -0.382303, + 1 + -0.00955381, + 7 + 0.574434, + 3 + 0.772632, + -3 + 0.427061, + -3 + -0.47615, + 1 + 0.159639, + -1 + 0.0973485, + -7 + 0.670094, + -3 + 0.66009, + 3 + -0.966069, + 5 + 0.729848, + -1 + -0.165828, + -5 + -0.991247, + 3 + -0.796155, + -3 + -0.665567, + 1 + 0.705734, + -3 + -0.0729422, + -5 + 0.569012, + -5 + 0.532164, + -3 + 0.114169, + -3 + -0.79896, + 5 + -0.434429, + 3 + 0.0409003, + 5 + -0.656138, + 1 + 0.80331, + -1 + -0.832592, + 1 + -0.512036, + 5 + 0.821594, + -5 + 0.153262, + -7 + 0.742653, + 7 + 0.775938, + 7 + 0.794682, + -1 + 0.436735, + 1 + 0.232814, + 5 + 0.173647, + -7 + 0.0346826, + -5 + -0.764013, + -3 + 0.414464, + -7 + -0.107918, + -5 + -0.909358, + -3 + -0.855809, + 3 + 0.321112, + -7 + -0.853217, + -1 + 0.240779, + -5 + 0.308181, + -3 + -0.101137, + -3 + 0.0592809, + 1 + -0.475771, + 1 + -0.805118, + 1 + -0.497502, + 1 + 0.0533702, + 1 + 0.256822, + 1 + 0.943496, + 5 + 0.195682, + 3 + 0.84158, + -7 + 0.691885, + 7 + 0.702398, + -5 + -0.0240126, + 3 + 0.0729154, + 1 + 0.683697, + -5 + 0.261411, + 5 + 0.953329, + 5 + -0.728981, + -5 + -0.635009, + 5 + -0.630682, + -7 + 0.122834, + -3 + 0.959923, + -1 + 0.374435, + 1 + 0.720612, + 5 + 0.664998, + 1 + 0.00891615, + -7 + 0.432124, + -3 + 0.0339184, + -1 + -0.257549, + 7 + 0.584476, + -3 + 0.0935045, + -1 + -0.804627, + 1 + -0.992967, + -3 + 0.538947, + 7 + 0.180181, + -5 + -0.90103, + -3 + -0.368599, + 7 + 0.775146, + -3 + -0.990663, + 5 + -0.991429, + 3 + 0.229796, + 3 + 0.933547, + -7 + 0.629628, + 7 + -0.128119, + -3 + 0.993864, + 3 + -0.518632, + 1 + 0.431409, + 5 + 0.162359, + -1 + 0.340156, + 7 + 0.99834, + -1 + -0.37602, + 7 + 0.798388, + -5 + -0.977304, + -1 + -0.714549, + -7 + 0.371461, + -3 + 0.429763, + -5 + -0.176519, + 1 + 0.130875, + 3 + -0.192991, + -3 + 0.926126, + 3 + -0.756796, + -3 + 0.0799201, + -5 + -0.885874, + -5 + -0.922719, + -1 + 0.788957, + 1 + 0.876735, + 1 + 0.505541, + 1 + 0.0568082, + 5 + -0.546276, + -5 + 0.987925, + 1 + 0.559679, + -5 + 0.240393, + 7 + 0.460363, + 5 + 0.194578, + 3 + 0.987203, + 7 + 0.781711, + -7 + -0.0489823, + -1 + -0.776679, + -7 + -0.496617, + 5 + -0.488827, + -3 + -0.501392, + 5 + 0.703741, + 7 + -0.0924905, + 5 + -0.948555, + -3 + -0.508697, + -5 + -0.211705, + -1 + -0.0656021, + 1 + 0.526428, + 3 + 0.977313, + 7 + 0.717488, + 1 + 0.987358, + -1 + -0.492118, + -1 + 0.765235, + 1 + -0.576154, + 3 + 0.52365, + -7 + 0.253303, + 1 + -0.492177, + 5 + 0.865942, + 5 + 0.977195, + 7 + 0.161001, + 5 + -0.907593, + -7 + -0.557902, + -7 + 0.825849, + 7 + -0.120301, + -5 + 0.531996, + 1 + 0.80755, + 7 + 0.969872, + -7 + -0.738685, + -3 + 0.636749, + 1 + -0.655666, + -3 + 0.999979, + 7 + -0.843387, + -3 + 0.693217, + 7 + 0.615595, + -3 + -0.585734, + 5 + -0.349962, + -5 + -0.708827, + 5 + 0.767043, + -3 + -0.561155, + 5 + 0.0547506, + 7 + -0.00058388, + 5 + 0.683614, + -5 + 0.933133, + -7 + -0.705963, + -1 + 0.432718, + -5 + -0.745574, + -1 + 0.578781, + -3 + 0.265256, + -1 + -0.723166, + 3 + -0.609362, + -3 + 0.897704, + -1 + 0.630349, + -5 + 0.582721, + -5 + -0.0955401, + 5 + -0.235266, + -1 + 0.829279, + -5 + -0.824548, + 3 + -0.803079, + 3 + -0.505004, + -1 + -0.492252, + 1 + -0.92866, + 1 + -0.193727, + 7 + 0.855165, + -5 + -0.409258, + 3 + 0.483943, + 5 + -0.711778, + 1 + -0.291856, + -1 + -0.309453, + -1 + -0.961907, + 3 + 0.239915, + 3 + 0.333033, + -5 + -0.520074, + 7 + 0.80808, + 7 + -0.392463, + -5 + -0.268562, + 7 + 0.963694, + -5 + -0.27416, + -3 + 0.136372, + -3 + -0.533467, + 5 + 0.0336407, + 5 + 0.269954, + -1 + 0.481331, + -5 + 0.883264, + -5 + 0.917248, + -5 + 0.841082, + 7 + -0.272449, + -1 + 0.612493, + -7 + -0.0456689, + 3 + -0.468522, + -5 + -0.783857, + -5 + -0.963398, + -7 + 0.0600612, + -3 + 0.80801, + -3 + -0.969476, + -5 + 0.949233, + 7 + -0.954761, + 7 + -0.0774834, + 5 + -0.245508, + 5 + 0.345368, + 3 + -0.476338, + -5 + -0.322511, + -3 + 0.450538, + -7 + -0.678719, + -3 + -0.172123, + -5 + -0.209171, + -3 + -0.420884, + -1 + 0.00383168, + -3 + -0.312955, + -7 + -0.0884187, + -7 + 0.201349, + 5 + -0.601248, + 5 + -0.413319, + 3 + -0.246626, + 5 + 0.977104, + -5 + 0.0133906, + 7 + 0.349431, + 5 + 0.216145, + -1 + -0.529927, + 1 + -0.249291, + 1 + 0.658874, + 7 + 0.43074, + 5 + 0.124815, + 7 + -0.553229, + 1 + 0.116857, + -5 + 0.734356, + -1 + -0.647581, + 5 + -0.323226, + -5 + -0.810003, + -3 + 0.822276, + -1 + -0.591676, + -5 + -0.434047, + 1 + 0.15821, + 7 + 0.165069, + 3 + 0.253866, + 3 + 0.973848, + -7 + 0.713996, + -5 + 0.215808, + -1 + 0.0812883, + -3 + 0.846565, + -5 + -0.947667, + 3 + 0.409641, + 5 + -0.385462, + -3 + 0.787733, + 1 + 0.844418, + 1 + 0.349241, + 5 + -0.586969, + 7 + 0.257519, + 1 + -0.315586, + -1 + -0.327033, + 1 + 0.767669, + -1 + -0.292183, + 3 + 0.389264, + -7 + 0.339534, + -3 + 0.477526, + -3 + 0.11475, + -7 + -0.119439, + 3 + 0.406966, + 5 + 0.419678, + 1 + 0.76062, + -7 + 0.536916, + -7 + -0.510681, + -5 + 0.905296, + 7 + 0.13423, + -5 + 0.748596, + 3 + -0.431882, + 7 + 0.33909, + 3 + 0.341309, + 5 + -0.172616, + -7 + -0.778667, + -5 + -0.984483, + 7 + 0.04289, + -3 + 0.791158, + -1 + -0.606419, + -3 + 0.939034, + 5 + -0.688122, + 7 + -0.0797096, + -3 + -0.176378, + 3 + -0.200208, + -3 + 0.539966, + -5 + 0.55811, + -1 + -0.965644, + -7 + -0.62776, + 3 + -0.327998, + 3 + -0.518732, + 3 + 0.713363, + 5 + 0.082287, + -7 + -0.799949, + 5 + -0.144101, + -7 + -0.416404, + 3 + 0.926589, + -3 + -0.0426248, + -3 + 0.823828, + 3 + -0.899492, + -1 + 0.925421, + -5 + -0.987104, + -3 + -0.667032, + -1 + -0.376583, + -1 + 0.776434, + 5 + 0.838315, + -3 + -0.411202, + -7 + -0.918427, + -5 + 0.627889, + 7 + -0.542975, + -3 + -0.0689918, + -5 + -0.55104, + -5 + 0.829815, + 7 + 0.466128, + -7 + -0.910729, + -3 + 0.587943, + -5 + -0.989778, + 3 + 0.429693, + -5 + 0.363276, + 5 + 0.48865, + -1 + 0.462889, + -1 + 0.933537, + -1 + -0.237365, + 7 + -0.503287, + 3 + 0.898831, + 5 + -0.88925, + 1 + 0.491187, + -3 + 0.819494, + 7 + -0.841093, + 5 + -0.172405, + -3 + 0.296082, + -5 + 0.230588, + 1 + -0.135964, + -7 + -0.24852, + 7 + 0.779819, + 1 + -0.0197039, + 3 + 0.690689, + 5 + 0.201188, + -3 + 0.316178, + 3 + -0.790151, + -3 + 0.353513, + 1 + 0.482168, + -7 + 0.5088, + 5 + -0.619387, + 3 + -0.572638, + -1 + 0.737113, + -3 + -0.330907, + 3 + -0.642647, + 7 + -0.587751, + 7 + 0.705296, + -1 + 0.765705, + -7 + 0.342622, + 1 + -0.443867, + -7 + 0.64285, + 5 + 0.119933, + 1 + 0.146719, + -3 + 0.808331, + 5 + 0.362826, + -5 + 0.649288, + -5 + -0.919914, + 5 + 0.530805, + 7 + 0.836641, + -1 + -0.33567, + 7 + -0.814941, + -3 + 0.521328, + -7 + -0.0633902, + 3 + 0.637973, + 5 + -0.448024, + -7 + 0.529787, + -1 + 0.158647, + 1 + -0.343875, + 5 + 0.862299, + -7 + 0.269423, + -3 + 0.205924, + -3 + 0.543444, + -1 + -0.0442747, + -1 + -0.514346, + -7 + -0.538346, + 5 + -0.134437, + 3 + -0.242908, + -3 + 0.960616, + -3 + 0.613265, + 5 + -0.578398, + 5 + -0.196621, + -1 + 0.99966, + -7 + -0.206926, + -7 + 0.149597, + 1 + -0.618079, + 7 + -0.779085, + 5 + 0.78756, + -3 + -0.461424, + 1 + -0.8271, + 7 + -0.779893, + 1 + -0.034591, + 3 + -0.618594, + 7 + -0.508509, + 3 + 0.858569, + -3 + -0.292217, + -3 + 0.638647, + 7 + 0.429429, + -3 + 0.0850469, + 3 + 0.840684, + -5 + -0.361285, + -1 + -0.0439304, + -5 + -0.464768, + 5 + 0.814776, + -7 + 0.838205, + -1 + 0.932473, + 3 + 0.0800499, + 3 + 0.430625, + -1 + -0.379486, + -5 + 0.566269, + 1 + -0.191075, + 1 + 0.426799, + -3 + -0.865195, + -1 + -0.286844, + -5 + -0.347813, + -1 + 0.254653, + -5 + -0.0217081, + -7 + 0.712565, + -5 + 0.626585, + -3 + 0.407399, + -1 + -0.495544, + 7 + 0.988263, + 5 + 0.752268, + 7 + -0.57751, + 1 + -0.699522, + -3 + -0.559222, + -5 + -0.142211, + -5 + -0.984406, + -7 + 0.478908, + 3 + -0.492842, + -1 + -0.75382, + 1 + 0.00969996, + 1 + -0.893656, + -7 + 0.928332, + 7 + -0.310557, + 3 + -0.203997, + -3 + -0.119623, + -3 + 0.23919, + -5 + 0.89898, + 3 + -0.000236075, + -1 + -0.75715, + 5 + -0.946444, + 5 + 0.830343, + 5 + 0.170209, + -5 + 0.0682683, + 7 + 0.490712, + 3 + 0.0912319, + 7 + -0.939061, + -5 + -0.27871, + 3 + 0.292512, + 3 + 0.7815, + 3 + 0.780423, + 3 + -0.995218, + 1 + -0.971244, + 5 + 0.863878, + 3 + 0.605471, + 1 + 0.615707, + -1 + -0.430001, + 7 + 0.137532, + -7 + 0.420738, + 5 + -0.511889, + -7 + -0.894203, + -1 + -0.442678, + 7 + 0.58245, + -1 + -0.302989, + -7 + 0.046658, + -1 + 0.213312, + -3 + -0.40466, + 3 + 0.119842, + -3 + -0.209236, + 1 + 0.489636, + -1 + 0.0750853, + 1 + -0.138393, + 3 + 0.197677, + 1 + 0.801, + 5 + -0.737093, + 5 + 0.0908536, + -7 + -0.604504, + -5 + 0.56203, + -3 + 0.309546, + 1 + -0.966521, + 5 + 0.977852, + 7 + 0.73063, + -5 + -0.256762, + -3 + -0.431265, + 5 + 0.661912, + -1 + 0.865871, + -3 + 0.10026, + -3 + 0.979883, + -3 + -0.50973, + 7 + -0.387004, + -5 + 0.872216, + -1 + -0.552574, + 3 + -0.00281111, + -5 + -0.433458, + 3 + 0.228333, + -5 + -0.784953, + 5 + 0.571488, + -5 + -0.107047, + 3 + 0.598395, + 7 + -0.209076, + 7 + 0.968037, + -7 + 0.133602, + -3 + 0.197601, + -1 + -0.737348, + -7 + -0.0987225, + -1 + -0.680374, + -5 + 0.902133, + 5 + -0.065214, + 7 + 0.820436, + -1 + -0.994703, + 5 + 0.928257, + 3 + 0.387782, + -1 + -0.867014, + -1 + -0.343716, + -3 + -0.0119044, + 5 + -0.882348, + 3 + -0.349223, + -3 + -0.423901, + -1 + -0.358375, + -7 + 0.877898, + -1 + -0.0346012, + -3 + -0.731243, + 1 + -0.0103546, + -1 + -0.662776, + 1 + 0.486511, + -1 + -0.0129122, + -5 + 0.0121863, + -3 + 0.550817, + -3 + 0.0375324, + 5 + 0.371006, + 5 + -0.111812, + 5 + 0.963243, + 1 + 0.36354, + -3 + -0.0390213, + -7 + -0.512331, + -3 + 0.530897, + -1 + -0.961326, + 1 + -0.128698, + 5 + -0.0345879, + 7 + -0.724934, + -7 + -0.990395, + 7 + -0.0956077, + 5 + 0.998217, + -1 + -0.38503, + -5 + 0.431693, + 3 + -0.322315, + 1 + -0.520076, + -3 + -0.403514, + 3 + -0.638799, + -1 + -0.665616, + -7 + 0.866326, + 7 + -0.314543, + -3 + -0.752403, + 7 + 0.180847, + 7 + -0.924565, + 3 + 0.431162, + -7 + -0.844134, + 5 + -0.621084, + 1 + 0.678683, + 7 + -0.643627, + -1 + 0.464485, + 3 + 0.311484, + 1 + 0.61938, + 1 + -0.362697, + -1 + -0.545854, + -7 + -0.693428, + 3 + -0.162961, + 3 + 0.362332, + -5 + -0.0418496, + -3 + -0.790282, + 1 + -0.362329, + -5 + -0.679632, + -7 + 0.193632, + 7 + 0.169699, + 5 + -0.0276975, + 3 + 0.145423, + 7 + -0.526892, + 7 + 0.23963, + -5 + -0.0191274, + 3 + 0.267953, + 5 + -0.963432, + 7 + 0.72934, + 5 + -0.0415711, + 3 + -0.0615771, + -1 + -0.441843, + 5 + -0.196666, + -5 + 0.656983, + 5 + 0.764159, + -7 + -0.0188419, + -1 + 0.515285, + -5 + 0.77527, + -1 + -0.362528, + 1 + 0.360052, + 3 + 0.134359, + -5 + 0.37625, + 7 + -0.511201, + 7 + -0.846493, + 5 + 0.94168, + 1 + -0.100134, + 5 + -0.157002, + 3 + -0.374631, + -7 + -0.364117, + -1 + -0.142558, + -7 + 0.0265685, + -3 + 0.138828, + -5 + -0.289868, + 1 + 0.664193, + -7 + 0.887828, + 1 + -0.652588, + 3 + -0.527631, + -1 + 0.284251, + -5 + 0.278712, + 1 + -0.105013, + -1 + 0.853542, + 1 + -0.436623, + -5 + -0.867476, + 3 + 0.96232, + 7 + 0.427617, + 3 + -0.501165, + -5 + 0.411637, + 7 + 0.891616, + -7 + 0.664072, + -1 + -0.888475, + 5 + 0.548079, + 3 + 0.503912, + -5 + -0.612317, + -1 + -0.180983, + 1 + -0.239876, + 1 + 0.596635, + -3 + -0.0827705, + -7 + 0.277359, + 5 + -0.941413, + -5 + 0.697875, + 3 + 0.714356, + 1 + -0.558584, + 1 + -0.0174082, + 5 + -0.587225, + -5 + -0.512741, + 7 + -0.434388, + 7 + -0.473811, + -1 + 0.285865, + 5 + 0.988991, + -5 + -0.991867, + -3 + 0.864291, + -5 + 0.661288, + 5 + -0.460111, + 7 + 0.366331, + -7 + 0.784093, + 5 + 0.918848, + 7 + 0.965396, + -3 + -0.161624, + 7 + -0.476323, + -5 + 0.501047, + 7 + 0.964268, + 1 + -0.388995, + -1 + 0.308069, + 7 + 0.449621, + -3 + 0.517261, + -1 + -0.931887, + -3 + -0.314139, + -1 + -0.88269, + 1 + -0.641202, + -7 + 0.426506, + -7 + 0.765908, + 3 + -0.839435, + -1 + 0.85062, + -5 + -0.068266, + 7 + -0.336073, + 5 + -0.552052, + 7 + 0.968225, + 5 + -0.489061, + -1 + 0.549817, + 7 + 0.155363, + 7 + 0.287813, + 5 + -0.0712527, + 7 + -0.539294, + 3 + 0.515963, + -7 + 0.309448, + 5 + -0.400565, + -3 + 0.772515, + -3 + 0.47223, + -5 + -0.377265, + -3 + -0.277457, + 3 + -0.0481647, + 1 + 0.253072, + 7 + -0.701416, + 3 + -0.983524, + -1 + 0.859256, + 3 + 0.684439, + 7 + -0.715583, + 1 + -0.927083, + 5 + -0.820364, + 3 + -0.818987, + -1 + 0.0484889, + -5 + 0.88172, + -1 + 0.642372, + 7 + -0.486761, + 1 + -0.154892, + -3 + 0.620922, + -7 + -0.307461, + -5 + 0.958143, + -5 + -0.945751, + -7 + 0.420205, + 3 + 0.212257, + -7 + 0.343969, + -7 + -0.56883, + -7 + 0.542757, + 1 + 0.338133, + -1 + 0.205287, + 3 + -0.678275, + -3 + 0.162556, + 7 + 0.7356, + -1 + -0.366469, + -5 + 0.818684, + 1 + -0.375059, + -7 + -0.326917, + -1 + 0.21386, + -1 + 0.933421, + -5 + -0.0965871, + -1 + -0.327707, + -3 + -0.293112, + 5 + -0.399372, + -1 + -0.243464, + -1 + -0.477791, + 5 + 0.160018, + 3 + 0.0379489, + -7 + -0.468135, + -5 + -0.924231, + 7 + -0.559268, + -1 + -0.869929, + 1 + 0.644987, + 7 + -0.416144, + -3 + -0.64862, + 1 + 0.0932449, + -1 + -0.941752, + -7 + -0.448205, + 5 + 0.816932, + -1 + -0.010022, + -3 + -0.611324, + 5 + -0.688206, + 1 + 0.868089, + -3 + -0.454031, + 3 + -0.633225, + 5 + -0.11036, + 7 + 0.119173, + -7 + -0.663239, + -7 + 0.86954, + 7 + 0.335132, + -1 + 0.512855, + 1 + -0.130088, + 3 + -0.225548, + 5 + -0.745615, + 7 + 0.963223, + -3 + -0.678778, + -7 + -0.430329, + -3 + 0.964206, + 7 + 0.808534, + 5 + -0.632605, + -5 + -0.728056, + -5 + -0.0283051, + -1 + -0.292853, + 3 + -0.960114, + 1 + 0.266249, + 7 + -0.94076, + 7 + -0.680042, + -1 + 0.678469, + 3 + 0.553279, + 7 + 0.392802, + 1 + -0.308376, + 7 + -0.588163, + 5 + -0.235282, + 7 + -0.490381, + 5 + 0.412499, + -7 + -0.148118, + 7 + -0.20069, + -1 + -0.256974, + 1 + -0.946528, + -5 + -0.190544, + 1 + -0.774484, + -1 + 0.939011, + 3 + 0.401197, + 7 + 0.763682, + -7 + 0.970152, + 5 + -0.471915, + -3 + -0.0230657, + -1 + 0.666549, + 3 + -0.312851, + 5 + 0.909774, + -5 + 0.608703, + -1 + -0.398985, + -1 + -0.579955, + -3 + 0.427466, + -3 + -0.406024, + 5 + -0.923879, + 5 + -0.124516, + -7 + 0.389177, + -1 + 0.978163, + 7 + 0.321733, + -5 + -0.401276, + -3 + -0.669763, + 5 + 0.837051, + -3 + -0.507979, + -5 + 0.650163, + 5 + -0.533125, + -7 + -0.352708, + -3 + 0.975917, + -1 + 0.333199, + 1 + 0.786429, + 7 + 0.588826, + -3 + -0.254794, + -5 + 0.577074, + 3 + -0.445216, + -3 + -0.913091, + 1 + 0.833436, + 3 + 0.879009, + 7 + -0.420452, + -7 + -0.841488, + 3 + 0.941771, + -5 + -0.516194, + 1 + -0.111796, + 1 + 0.913016, + -3 + 0.831405, + 7 + -0.456459, + 5 + 0.52518, + 7 + 0.407003, + 5 + 0.477567, + -1 + 0.420401, + -1 + 0.437449, + -7 + -0.0206778, + -3 + 0.132506, + 3 + -0.0369548, + -3 + -0.66723, + 3 + 0.639026, + -5 + 0.818826, + -3 + 0.521142, + -7 + 0.239988, + 7 + 0.798847, + 3 + 0.568449, + -7 + -0.322325, + 1 + 0.74602, + 5 + -0.820488, + 5 + 0.422569, + -5 + 0.154974, + 3 + -0.598438, + -3 + -0.0493216, + 5 + -0.437171, + -7 + 0.91565, + 1 + -0.76322, + -7 + 0.655683, + 1 + -0.221855, + 3 + 0.499042, + 7 + -0.551781, + -1 + 0.776521, + 3 + 0.364049, + 7 + 0.76778, + 1 + 0.98362, + 1 + 0.901754, + -7 + -0.301171, + -7 + -0.154012, + -3 + -0.967804, + -1 + 0.205987, + 7 + -0.231608, + 1 + 0.577335, + -5 + 0.133768, + -5 + 0.959646, + -3 + -0.0372217, + -3 + 0.404834, + -1 + 0.457923, + 1 + 0.0552233, + -3 + 0.2, + 5 + -0.787169, + -1 + 0.572437, + 7 + -0.18741, + -1 + 0.0523727, + -1 + -0.804208, + 7 + -0.303471, + 7 + 0.73635, + -3 + -0.804122, + 1 + 0.962955, + 7 + 0.065147, + -7 + -0.464851, + 7 + 0.410402, + -1 + -0.213138, + 7 + 0.323269, + 5 + -0.812589, + 1 + -0.924136, + 3 + -0.0515391, + 5 + -0.942719, + -7 + 0.0813437, + -5 + -0.919358, + -3 + 0.09817, + -3 + 0.204768, + -3 + 0.895305, + -5 + 0.426145, + -1 + -0.654514, + 1 + -0.527968, + 1 + -0.93447, + 7 + -0.259295, + -5 + -0.357566, + -3 + 0.820761, + 3 + 0.061946, + 1 + -0.365104, + -1 + -0.484186, + 5 + -0.0747202, + 7 + 0.373292, + 3 + -0.225615, + 1 + 0.387072, + -1 + 0.0964885, + 5 + 0.318965, + -5 + -0.574407, + -1 + -0.5876, + 3 + -0.0651205, + -7 + -0.131517, + -5 + -0.700999, + -1 + 0.431009, + -5 + -0.378572, + -5 + -0.438665, + 3 + -0.0663064, + -1 + 0.303877, + 7 + 0.252822, + -5 + 0.127981, + -5 + -0.979741, + -7 + -0.977809, + 1 + -0.939208, + -5 + -0.619289, + -3 + -0.817288, + -7 + -0.682975, + 5 + 0.945473, + 3 + 0.696275, + -1 + 0.466816, + 3 + -0.632966, + -3 + 0.078222, + 5 + 0.546507, + -1 + 0.977089, + 7 + -0.133295, + -5 + -0.604371, + -3 + 0.365631, + -3 + 0.673212, + -1 + 0.180141, + 5 + 0.223484, + -1 + 0.146777, + 1 + -0.319683, + -1 + 0.857262, + 5 + -0.356152, + 5 + -0.598653, + 1 + 0.975409, + -5 + -0.881246, + -7 + -0.472377, + -3 + 0.0214979, + 7 + -0.788032, + 7 + -0.333508, + 7 + -0.750094, + -3 + -0.814424, + 7 + -0.965833, + 5 + -0.36787, + 3 + -0.612635, + -5 + 0.236003, + -5 + -0.785485, + -5 + 0.745934, + 3 + 0.841095, + 3 + 0.331357, + 3 + -0.341722, + 1 + 0.0449292, + 7 + -0.256584, + -3 + -0.666529, + 7 + -0.203782, + 1 + -0.442113, + 5 + 0.281735, + -7 + -0.600958, + 5 + -0.297631, + 7 + 0.834514, + 1 + -0.965433, + -7 + 0.980322, + -5 + -0.275104, + -5 + 0.501189, + 1 + 0.861033, + 3 + -0.186388, + -7 + -0.783021, + -3 + -0.331772, + -7 + -0.923864, + 7 + 0.981171, + -7 + 0.677146, + 5 + -0.764622, + 7 + 0.544671, + 3 + -0.149741, + -1 + -0.115158, + 5 + 0.315554, + 3 + -0.0435786, + -7 + -0.198421, + 3 + 0.728623, + 3 + 0.917598, + -7 + -0.222429, + -1 + -0.839337, + 1 + -0.837996, + 5 + 0.7184, + 3 + 0.279682, + 5 + 0.89931, + 1 + -0.0903269, + -3 + 0.311248, + -3 + -0.0615842, + -5 + 0.978228, + 5 + -0.0288547, + -7 + -0.319235, + 1 + 0.459872, + -7 + -0.762583, + 1 + 0.430673, + 7 + -0.202576, + 7 + -0.508028, + 5 + -0.563939, + 7 + 0.431253, + 3 + 0.924691, + -7 + -0.929823, + -7 + -0.745149, + -3 + -0.54763, + 7 + -0.233056, + -3 + 0.0728049, + 3 + 0.173541, + 5 + -0.99085, + -5 + -0.509606, + -7 + -0.0573629, + -5 + 0.146235, + 7 + -0.530049, + 5 + -0.92378, + 5 + -0.150627, + 7 + -0.632136, + 3 + -0.544558, + -1 + -0.559563, + -5 + -0.183858, + -3 + -0.0823922, + 3 + -0.845123, + -5 + 0.740183, + -1 + -0.864943, + -7 + -0.517753, + -7 + 0.273158, + -7 + 0.597718, + 7 + -0.960088, + -1 + 0.628689, + 5 + -0.100486, + 5 + -0.28978, + -3 + 0.591832, + 5 + -0.225949, + 1 + 0.434438, + 3 + 0.701275, + -5 + -0.110868, + 3 + -0.993528, + -1 + -0.279674, + -7 + -0.695508, + 3 + 0.208776, + 5 + 0.280286, + -7 + 0.098819, + 1 + -0.270841, + -3 + 0.163315, + 7 + -0.339504, + -1 + 0.503129, + -5 + -0.42331, + -5 + 0.289597, + 5 + -0.48842, + -1 + -0.301035, + -7 + 0.307344, + 3 + 0.149469, + -7 + -0.91815, + -7 + 0.735915, + -7 + 0.651662, + -5 + -0.367747, + 3 + 0.571618, + 3 + -0.0886024, + 7 + -0.287501, + 3 + -0.332199, + -3 + 0.103811, + 1 + 0.281067, + 1 + -0.380718, + -1 + 0.343006, + -7 + -0.940098, + -3 + 0.722196, + 5 + 0.874495, + 1 + 0.990522, + 3 + -0.915597, + -5 + -0.278943, + -7 + 0.203699, + -5 + 0.170043, + 7 + 0.536621, + -5 + 0.824829, + 5 + -0.832656, + -7 + 0.333, + -3 + -0.667407, + 7 + 0.105231, + 7 + -0.905234, + -1 + -0.810245, + 3 + 0.294136, + -1 + -0.514902, + 3 + -0.2467, + 3 + -0.587121, + 3 + 0.60538, + -3 + 0.0694657, + -5 + 0.0962229, + 7 + -0.291999, + -5 + 0.450209, + 3 + -0.147034, + -1 + -0.0838816, + 3 + 0.112086, + -5 + 0.194085, + 5 + -0.0903105, + -7 + -0.919954, + -5 + -0.967825, + -1 + -0.441373, + 5 + 0.768526, + 5 + 0.38484, + 3 + -0.947454, + 5 + -0.262922, + 7 + -0.593716, + -3 + 0.219333, + 3 + 0.076773, + 7 + 0.192425, + 1 + 0.970687, + 7 + -0.00340885, + 3 + -0.199764, + -3 + 0.255666, + -5 + 0.439951, + 1 + 0.505418, + 3 + -0.356007, + 5 + -0.318271, + -3 + 0.788047, + 5 + -0.924415, + -1 + 0.394691, + 1 + 0.972997, + 1 + 0.357046, + 3 + 0.419342, + -5 + -0.774465, + -7 + 0.0996104, + 5 + -0.458399, + -3 + -0.133173, + -1 + -0.671463, + 7 + -0.916153, + -7 + 0.110461, + 3 + 0.409689, + -3 + -0.355372, + -5 + -0.896134, + -7 + -0.950039, + 7 + 0.386037, + 3 + -0.798405, + -3 + -0.744455, + 1 + -0.572819, + -1 + 0.839239, + -3 + 0.570676, + 3 + -0.835377, + -7 + 0.034378, + 5 + 0.724415, + 5 + -0.252927, + -3 + 0.287315, + -3 + 0.334237, + 5 + -0.118203, + -1 + 0.502825, + -5 + -0.154511, + 5 + -0.127665, + 7 + 0.0817964, + 1 + 0.132329, + -5 + -0.546248, + -3 + 0.874254, + -3 + 0.421468, + 3 + -0.928829, + 5 + 0.620968, + 7 + 0.0580643, + -7 + -0.687253, + -7 + -0.628005, + 5 + -0.883083, + -5 + -0.270135, + 1 + -0.623219, + -7 + 0.277921, + 3 + 0.116588, + -5 + 0.264649, + -1 + -0.593871, + -7 + 0.329278, + -1 + -0.0926952, + -1 + 0.64349, + 1 + -0.10689, + 3 + -0.541441, + 1 + 0.499186, + -3 + 0.920398, + -1 + 0.381933, + 5 + -0.518618, + -5 + 0.618314, + 1 + 0.110954, + -1 + 0.576074, + 3 + 0.45385, + -5 + -0.917242, + 5 + -0.451152, + 5 + -0.705703, + -5 + -0.97524, + -5 + -0.732996, + 5 + 0.702813, + 3 + -0.229341, + 7 + -0.13257, + 7 + 0.994484, + 7 + -0.0231948, + 5 + 0.538224, + 1 + -0.838791, + 7 + 0.848763, + -7 + -0.539283, + -3 + 0.321736, + 5 + 0.22943, + 1 + -0.626804, + 5 + 0.209983, + -5 + 0.977037, + 3 + 0.448198, + 5 + -0.419565, + 7 + 0.666147, + -7 + 0.412532, + 7 + -0.0260039, + 1 + 0.545681, + 1 + 0.657399, + -5 + 0.275525, + 5 + 0.563082, + 1 + 0.88785, + -5 + 0.855898, + -1 + -0.758617, + -1 + 0.0505126, + 5 + 0.0387102, + 5 + 0.574784, + 1 + 0.1487, + 7 + -0.234118, + -1 + 0.458783, + 5 + -0.798949, + -7 + -0.300432, + 3 + -0.455072, + 1 + 0.24667, + -3 + 0.034758, + 1 + -0.491485, + 1 + 0.27987, + -5 + -0.92334, + 1 + 0.486993, + 5 + -0.624284, + -3 + 0.259474, + 3 + 0.384827, + 7 + -0.744943, + 3 + 0.669036, + -7 + -0.171024, + 1 + -0.963747, + -3 + -0.457945, + -1 + -0.271542, + 3 + -0.642662, + 5 + 0.867933, + -7 + 0.872486, + -5 + -0.0610653, + -3 + 0.0567537, + -5 + -0.384634, + -1 + -0.810843, + 1 + -0.210336, + 7 + -0.782186, + -3 + 0.206301, + 3 + -0.532726, + -1 + 0.792476, + 1 + -0.0254994, + 1 + -0.38317, + 5 + -0.444631, + -3 + 0.202259, + 7 + 0.906256, + -5 + -0.283238, + 1 + 0.761982, + -1 + 0.456456, + 7 + -0.213898, + 7 + -0.98443, + -7 + -0.984132, + -3 + -0.549083, + 7 + 0.946917, + 1 + -0.817794, + 3 + -0.902041, + -7 + 0.667457, + 7 + 0.476978, + -1 + 0.864841, + -1 + -0.100561, + -1 + 0.589944, + 1 + -0.417731, + -5 + -0.291668, + 3 + -0.341364, + 1 + -0.116372, + -5 + -0.678389, + 5 + -0.621016, + -7 + -0.557662, + 5 + -0.916104, + 1 + 0.416737, + -3 + -0.397013, + 3 + -0.767577, + 1 + 0.340769, + 7 + -0.54333, + -5 + 0.825698, + -7 + -0.0227328, + 1 + 0.688705, + -5 + 0.783876, + -5 + 0.36354, + 3 + -0.405894, + -1 + -0.505203, + 3 + -0.280375, + -7 + -0.0717587, + -5 + 0.254936, + -5 + -0.792482, + 7 + -0.425804, + 3 + 0.295604, + -5 + 0.294844, + -3 + 0.730185, + 3 + 0.0271969, + 5 + -0.303161, + -3 + 0.883759, + 3 + 0.827756, + -7 + 0.450664, + 5 + 0.435759, + 3 + 0.360285, + -7 + 0.409698, + 1 + 0.230758, + 7 + -0.352144, + 1 + -0.389721, + 7 + -0.718911, + 3 + 0.41957, + -3 + 0.620353, + -7 + 0.254944, + -1 + 0.81995, + 3 + -0.280774, + 3 + 0.906947, + 7 + -0.349169, + -1 + -0.00793728, + -5 + -0.64104, + -7 + 0.445183, + 3 + 0.914473, + 3 + -0.570084, + -1 + 0.594879, + -5 + -0.521969, + 1 + 0.0416743, + -3 + -0.799298, + 5 + -0.041766, + -7 + -0.218755, + 1 + 0.173665, + 7 + -0.880771, + -7 + 0.339146, + -1 + 0.961946, + 1 + 0.859441, + -5 + 0.0599979, + -3 + -0.243646, + 1 + 0.642304, + 5 + 0.427633, + -3 + 0.337803, + 5 + -0.876868, + -5 + 0.124084, + 7 + -0.390476, + 5 + -0.889517, + 7 + -0.0881519, + -5 + -0.985327, + -1 + 0.364205, + -1 + 0.481156, + 1 + 0.878136, + 3 + 0.270873, + -1 + -0.133771, + 7 + -0.599314, + 7 + 0.784159, + 1 + 0.555296, + 7 + -0.974226, + 5 + 0.520163, + -5 + 0.046348, + -5 + -0.487602, + 3 + 0.0383354, + -7 + -0.969134, + 5 + -0.00830264, + 5 + 0.582434, + -5 + 0.498667, + -5 + 0.0475678, + 7 + -0.011481, + -5 + 0.0134767, + 1 + 0.897857, + -1 + 0.859261, + 3 + -0.741447, + -5 + 0.61813, + 3 + 0.976057, + -5 + 0.671342, + -1 + -0.480269, + -7 + -0.183415, + 3 + -0.955847, + 3 + 0.770801, + -3 + 0.470981, + -7 + -0.778816, + 3 + -0.906343, + -1 + -0.727997, + 7 + -0.39431, + 7 + 0.80919, + 7 + -0.973433, + -3 + -0.627311, + 3 + 0.373299, + 5 + 0.907636, + -5 + 0.658848, + 7 + 0.681815, + 5 + 0.589045, + -5 + 0.0950571, + -7 + 0.112081, + 5 + 0.34511, + -3 + 0.315859, + 5 + -0.181386, + -3 + -0.714938, + 1 + 0.308135, + 7 + 0.535557, + 7 + -0.0709868, + -1 + 0.552407, + -7 + -0.847801, + 7 + 0.160415, + 5 + -0.51117, + 3 + -0.951139, + -3 + 0.0406191, + 5 + -0.895575, + 5 + 0.0746354, + -3 + 0.915248, + -3 + 0.842174, + -7 + 0.595946, + 3 + 0.700337, + -3 + -0.23779, + 3 + -0.655733, + -5 + -0.894634, + -3 + -0.695807, + 5 + -0.476673, + 7 + -0.279169, + -5 + 0.507948, + -5 + 0.499507, + 3 + 0.0916842, + 3 + -0.837399, + -5 + 0.143527, + 3 + 0.58052, + -7 + 0.378768, + 5 + 0.811361, + -1 + 0.0748057, + 3 + 0.453959, + -7 + 0.990606, + 3 + -0.450379, + 5 + 0.395584, + -7 + -0.114441, + 5 + 0.426232, + 1 + -0.711673, + 1 + 0.077825, + -5 + -0.584918, + 1 + -0.457057, + -3 + -0.366392, + -7 + 0.00484131, + -3 + 0.215838, + -3 + -0.19239, + -5 + 0.300349, + 5 + 0.925702, + 7 + 0.693147, + -3 + -0.771327, + 7 + 0.850479, + 7 + 0.55379, + -5 + -0.622361, + -7 + -0.797468, + -1 + 0.865325, + -1 + 0.594149, + -3 + 0.402537, + 3 + 0.5647, + -5 + 0.408661, + 7 + 0.434393, + -5 + 0.369053, + 7 + 0.193313, + 7 + 0.0768285, + -5 + -0.966767, + 7 + 0.316068, + 5 + 0.393416, + -1 + 0.678055, + -1 + -0.426397, + 7 + -0.0972791, + 5 + 0.863534, + 7 + 0.857534, + 3 + -0.591288, + -1 + -0.978807, + -5 + 0.47735, + 1 + -0.387742, + 7 + 0.418231, + -7 + -0.918646, + 3 + -0.487032, + -7 + 0.169229, + 5 + 0.963037, + 3 + -0.651308, + 1 + -0.963926, + -7 + -0.870113, + -1 + -0.598625, + 1 + 0.578904, + -1 + -0.0948276, + -5 + 0.227649, + 1 + 0.555606, + -1 + -0.668322, + 1 + 0.0749024, + -5 + -0.607571, + 5 + -0.349931, + -1 + -0.898107, + 5 + 0.312465, + 7 + 0.772347, + 5 + 0.0899041, + -1 + -0.741034, + -3 + 0.26158, + 1 + -0.539694, + 7 + -0.115106, + -1 + -0.411724, + 3 + 0.0316011, + -7 + -0.810337, + -5 + 0.181813, + 5 + 0.318575, + -5 + -0.176396, + -1 + -0.639559, + 1 + 0.966577, + 7 + -0.685124, + -3 + -0.036449, + -5 + -0.456288, + -1 + 0.80942, + 1 + -0.842449, + -7 + 0.390273, + 3 + -0.931459, + 5 + 0.693488, + -7 + 0.247743, + -3 + -0.848713, + -3 + 0.137249, + -7 + -0.213185, + -7 + -0.755191, + 7 + -0.639001, + 5 + 0.91416, + 5 + -0.193425, + -5 + 0.80731, + -1 + -0.716912, + 5 + -0.503475, + 5 + -0.0585372, + 5 + -0.0209306, + 5 + -0.150028, + -3 + 0.634776, + 5 + 0.538764, + 7 + 0.704398, + -1 + -0.61061, + -7 + -0.624288, + 1 + -0.926651, + -7 + 0.580724, + 3 + 0.24162, + 1 + 0.447202, + 7 + -0.76537, + 7 + -0.753749, + 7 + -0.93289, + 7 + 0.570568, + -1 + 0.901893, + -1 + -0.297356, + 5 + -0.189813, + -3 + 0.21001, + -3 + 0.541859, + -5 + -0.73421, + 7 + 0.928552, + -7 + -0.355678, + -5 + -0.221657, + -5 + -0.0512875, + 3 + -0.298442, + -1 + -0.820576, + 7 + -0.771328, + 1 + -0.961217, + 5 + -0.161851, + -1 + -0.405209, + 3 + -0.662432, + -3 + 0.528404, + 1 + -0.226934, + -3 + 0.0363932, + 7 + 0.886687, + 3 + 0.393918, + -5 + -0.507128, + 1 + -0.189558, + -7 + -0.823271, + 7 + -0.180617, + -1 + 0.321553, + -1 + 0.989206, + -7 + -0.874277, + 1 + -0.113906, + 7 + 0.161257, + 3 + 0.670416, + -3 + -0.763578, + -1 + 0.424893, + 3 + -0.0447045, + -5 + -0.957789, + -1 + 0.196626, + -5 + 0.00535004, + 3 + 0.254757, + -7 + -0.927024, + 3 + -0.959979, + 1 + -0.949363, + -5 + 0.674222, + 1 + -0.848884, + -7 + 0.0919615, + 1 + -0.58394, + -1 + -0.515551, + -7 + -0.961024, + 7 + -0.978422, + 7 + 0.86705, + 7 + -0.323448, + -5 + -0.916549, + -3 + -0.512443, + -3 + -0.892435, + -1 + 0.0811992, + 7 + -0.1951, + 1 + -0.31832, + 7 + 0.389861, + -7 + -0.429737, + 7 + 0.14079, + -7 + -0.306634, + 1 + -0.0533624, + 1 + -0.438584, + -7 + -0.63111, + -7 + -0.559344, + -5 + 0.783094, + -7 + -0.735777, + 7 + -0.58636, + -7 + -0.116192, + -5 + -0.801831, + -5 + 0.969511, + -5 + 0.144718, + -5 + 0.363059, + -1 + -0.667404, + 3 + -0.134134, + -1 + 0.734085, + 5 + -0.165216, + 1 + 0.149468, + -5 + -0.15301, + -3 + 0.83035, + -3 + -0.27281, + -1 + 0.688733, + 5 + -0.406828, + -5 + -0.018298, + 5 + 0.219722, + -5 + 0.840822, + -7 + 0.256695, + -1 + -0.300632, + -5 + 0.403999, + -5 + 0.574885, + -3 + -0.92988, + 1 + -0.837794, + 3 + 0.510347, + 1 + 0.946242, + 1 + -0.558269, + 7 + -0.945935, + -7 + -0.106771, + 3 + -0.383966, + -5 + 0.370004, + -7 + 0.428693, + 5 + 0.936122, + 1 + -0.782085, + -7 + 0.528864, + 1 + 0.697761, + -7 + -0.681381, + -5 + 0.152231, + 5 + -0.900638, + 5 + -0.334353, + 1 + 0.862458, + -5 + -0.694343, + -7 + -0.938721, + -5 + 0.119729, + -7 + -0.874769, + -5 + -0.120494, + -3 + 0.506938, + 5 + 0.965172, + -1 + -0.888394, + -3 + -0.595798, + -5 + 0.802503, + -3 + -0.789257, + -3 + 0.351862, + 3 + -0.750966, + -1 + 0.584273, + -3 + -0.0831131, + -7 + -0.28384, + -3 + 0.806411, + 7 + -0.200101, + 3 + 0.640918, + -1 + 0.977479, + 1 + 0.865009, + -3 + -0.368203, + 7 + 0.556652, + -1 + -0.991885, + -5 + 0.332904, + 3 + 0.470344, + -7 + 0.205081, + -7 + -0.314842, + -3 + -0.62, + 3 + 0.34363, + 1 + -0.425907, + -7 + -0.702084, + -3 + -0.288143, + -7 + 0.243932, + -1 + 0.0855131, + -5 + -0.139345, + 3 + -0.959163, + 3 + 0.431497, + -7 + 0.261823, + -3 + 0.914225, + -1 + 0.325961, + 3 + -0.359881, + 7 + -0.468639, + 7 + -0.803865, + -1 + 0.343444, + 1 + 0.736499, + 5 + 0.382909, + -1 + -0.721058, + -1 + -0.823382, + 3 + -0.176144, + 5 + 0.251272, + -1 + -0.786581, + -5 + 0.273133, + 7 + -0.41622, + 3 + 0.121719, + 7 + 0.620911, + -1 + 0.237504, + 1 + -0.335624, + -7 + 0.42324, + -3 + 0.729575, + -7 + -0.723781, + 3 + 0.273075, + 3 + -0.229695, + 3 + 0.507748, + -5 + 0.294614, + -7 + -0.490011, + 3 + 0.297713, + -3 + -0.330685, + -7 + 0.441233, + 5 + -0.622061, + 5 + -0.208099, + 5 + -0.710362, + -1 + 0.154774, + -5 + 0.486696, + 5 + -0.168477, + 7 + -0.653855, + 7 + -0.0172002, + -1 + -0.1059, + 3 + 0.654305, + 1 + -0.459053, + 7 + 0.751362, + 7 + 0.407269, + 7 + 0.871658, + 7 + 0.654213, + 7 + 0.0624889, + 7 + -0.583527, + 1 + -0.252231, + 1 + -0.320237, + 5 + -0.0136125, + 7 + -0.729181, + -5 + -0.0353086, + 5 + -0.0951113, + 3 + -0.0836304, + -1 + -0.11923, + 7 + 0.962136, + -5 + -0.830669, + 1 + 0.29644, + 5 + 0.045498, + 1 + 0.76292, + -5 + -0.929796, + 5 + -0.083544, + -7 + 0.472663, + 7 + -0.746787, + 3 + 0.662228, + -5 + -0.41748, + -7 + 0.850784, + -7 + -0.130054, + -1 + 0.432904, + 7 + -0.787268, + -3 + -0.248262, + 5 + 0.406222, + 5 + -0.775207, + 7 + -0.0549824, + -1 + 0.930082, + -3 + 0.651628, + -7 + -0.373963, + 7 + -0.38767, + -5 + -0.199335, + 3 + -0.0845591, + -3 + -0.400573, + -1 + -0.423932, + 3 + 0.496079, + 3 + -0.0049753, + 5 + -0.937373, + -1 + 0.00805519, + 7 + -0.387026, + -7 + 0.379173, + 3 + -0.509631, + -3 + 0.0652572, + -7 + 0.292195, + -3 + -0.0630124, + -3 + 0.210706, + -7 + 0.0474516, + -3 + 0.088253, + 5 + -0.729131, + -1 + -0.118407, + 5 + 0.587638, + -7 + 0.963741, + -3 + 0.912494, + -7 + 0.723939, + 5 + 0.977461, + 3 + 0.230908, + -7 + 0.0875093, + -5 + 0.827526, + 7 + -0.821136, + -3 + 0.402932, + -7 + 0.441547, + 7 + 0.416953, + 5 + 0.70044, + 3 + 0.973559, + 3 + 0.407091, + -5 + -0.826277, + 3 + -0.389221, + 5 + -0.583906, + 1 + -0.0841909, + -7 + 0.530444, + -1 + -0.918261, + 3 + -0.638232, + 1 + -0.776938, + -7 + 0.706762, + -1 + 0.16429, + -7 + -0.306863, + -3 + -0.670615, + 1 + -0.819745, + 1 + -0.014878, + -3 + 0.178679, + 1 + 0.441678, + -1 + -0.193108, + -3 + -0.33399, + 5 + 0.275276, + -7 + 0.167054, + -5 + 0.134306, + 7 + -0.394252, + 3 + 0.941986, + -7 + -0.878877, + -5 + 0.770656, + -5 + 0.730814, + -1 + 0.143592, + -3 + 0.442492, + -1 + -0.712593, + 5 + 0.599122, + 1 + 0.263907, + -7 + 0.47737, + -7 + 0.0559669, + -3 + 0.208639, + 1 + 0.827161, + 1 + 0.886639, + 1 + 0.598246, + -7 + -0.191541, + 3 + 0.511962, + 3 + -0.645528, + 1 + -0.593154, + -5 + 0.52999, + 5 + -0.653963, + 1 + 0.574099, + -5 + -0.0896155, + 1 + -0.636268, + 7 + 0.343794, + -7 + 0.155548, + -1 + -0.121609, + -1 + -0.297629, + -5 + -0.468962, + 5 + -0.555227, + -1 + -0.296793, + -3 + -0.855934, + 7 + -0.739775, + 1 + -0.756048, + 1 + -0.46236, + -7 + -0.179736, + 3 + 0.125628, + 1 + 0.10038, + -5 + -0.380856, + 7 + 0.450066, + 7 + 0.959734, + -3 + 0.796831, + -1 + 0.23315, + -3 + 0.298099, + -5 + -0.383893, + -3 + -0.296636, + -5 + 0.138614, + 1 + -0.114746, + 7 + 0.555051, + 1 + -0.950471, + -1 + 0.124465, + 1 + 0.037862, + 1 + 0.719934, + 7 + -0.0167727, + -7 + -0.983453, + -5 + -0.418557, + 7 + -0.192828, + 7 + -0.0814223, + 1 + 0.224621, + 5 + -0.597524, + 5 + 0.415634, + 1 + -0.954608, + -3 + 0.227498, + -5 + -0.108549, + 7 + 0.0881721, + 3 + 0.845206, + 3 + -0.913562, + -7 + 0.24586, + -7 + 0.289418, + -1 + 0.194941, + 3 + 0.793157, + 7 + -0.434518, + -7 + 0.820917, + 5 + 0.2382, + 5 + -0.946464, + 1 + 0.686291, + 3 + -0.265611, + -1 + -0.215793, + 1 + 0.247293, + 3 + 0.370775, + -1 + -0.1934, + 5 + 0.306202, + 5 + -0.454743, + -1 + -0.529622, + 1 + 0.856026, + -5 + -0.672594, + -5 + -0.429688, + 7 + -0.898493, + 3 + -0.296784, + -7 + -0.839249, + 7 + -0.238149, + -3 + 0.87197, + 7 + -0.985437, + -3 + 0.243879, + 1 + -0.0590569, + -7 + 0.3087, + -7 + -0.415904, + -3 + 0.238146, + -3 + -0.00380364, + 7 + -0.524692, + -1 + 0.715206, + -1 + -0.382632, + 7 + -0.433315, + -3 + 0.671116, + 5 + 0.319951, + -5 + -0.467809, + 1 + -0.914862, + -1 + -0.848039, + -7 + 0.916399, + -3 + 0.158824, + -7 + 0.432194, + 5 + 0.939947, + -3 + -0.938313, + -1 + 0.111712, + 1 + -0.830159, + -1 + 0.269145, + -3 + -0.282773, + -7 + 0.397815, + -7 + 0.312644, + 7 + 0.101858, + 5 + 0.398991, + 7 + 0.931748, + 5 + -0.216404, + 5 + -0.739909, + -3 + 0.837449, + 5 + -0.292918, + 3 + -0.811216, + 3 + -0.54535, + 3 + -0.206546, + 7 + 0.287012, + 5 + 0.416343, + -7 + 0.226965, + 3 + 0.650639, + 7 + -0.513567, + 3 + 0.35494, + 7 + 0.251297, + 3 + 0.222854, + -3 + 0.631017, + 1 + -0.834925, + -5 + 0.302606, + 5 + -0.161238, + -1 + -0.717755, + -1 + 0.163733, + 7 + 0.683634, + -3 + -0.0890416, + 5 + -0.0241376, + -7 + -0.331885, + -1 + -0.566607, + 5 + -0.0680727, + -1 + 0.69374, + -5 + -0.441671, + 3 + -0.917287, + 5 + -0.447226, + 5 + 0.530121, + 3 + -0.393156, + 7 + -0.625747, + 1 + 0.660945, + 1 + 0.0093144, + 7 + -0.198812, + 5 + 0.442133, + 1 + -0.569587, + -1 + 0.969233, + -3 + 0.831887, + 7 + -0.129281, + -5 + 0.790104, + -3 + -0.329582, + 3 + -0.846209, + 5 + 0.921283, + 5 + 0.0625507, + -3 + 0.292014, + -5 + 0.833173, + -7 + -0.674783, + -3 + -0.846611, + 1 + 0.893338, + -7 + 0.983207, + -7 + -0.776993, + -7 + 0.250987, + -5 + 0.0683537, + 7 + -0.183423, + 1 + -0.0923144, + 3 + 0.316882, + 3 + 0.436083, + -1 + 0.561959, + 5 + 0.199397, + 3 + 0.998894, + -5 + -0.762317, + 1 + -0.264652, + -1 + 0.000935957, + -5 + -0.737429, + 5 + -0.449802, + -3 + -0.153005, + -7 + -0.825486, + -3 + 0.381528, + -3 + -0.834704, + 1 + -0.869081, + -5 + 0.658949, + -7 + 0.538412, + 1 + -0.274676, + -3 + -0.131948, + -5 + -0.89239, + 5 + -0.216419, + 5 + 0.0464617, + -5 + -0.202859, + -5 + 0.937449, + 5 + 0.424624, + 1 + 0.22882, + 7 + 0.683182, + 1 + -0.649762, + 3 + -0.764787, + 7 + -0.573145, + -5 + 0.304541, + 3 + 0.3929, + -7 + -0.210616, + -3 + 0.373165, + -7 + -0.21229, + -7 + 0.897832, + -7 + 0.909656, + 1 + 0.948898, + 3 + -0.42523, + 3 + 0.567772, + -3 + -0.527982, + 3 + -0.189502, + 5 + 0.970517, + 7 + 0.282051, + -3 + 0.430664, + 3 + -0.793949, + -7 + 0.545716, + -3 + 0.35154, + -3 + -0.821351, + 5 + -0.395689, + -5 + -0.620034, + 5 + -0.608408, + -3 + 0.94029, + -1 + 0.0666049, + 5 + -0.51607, + 1 + 0.991041, + 7 + 0.172753, + 5 + -0.0221328, + 5 + -0.193889, + -5 + -0.13076, + 3 + 0.138734, + 3 + 0.59089, + 3 + -0.887206, + -3 + 0.845891, + -1 + -0.347074, + 5 + -0.0834612, + 3 + -0.876824, + -1 + -0.810422, + -1 + -0.231434, + 1 + -0.239487, + -5 + 0.0323537, + 1 + -0.581238, + 5 + 0.00602403, + 5 + 0.0905542, + 3 + 0.498012, + -5 + 0.254225, + 3 + 0.314102, + 5 + 0.0299345, + 5 + -0.45939, + -1 + 0.448653, + -3 + 0.647585, + 1 + 0.318478, + 5 + 0.455767, + -1 + 0.133022, + 1 + 0.614847, + 1 + 0.120892, + -5 + 0.224634, + 5 + 0.132055, + -1 + 0.743952, + -5 + 0.425553, + 5 + -0.111105, + 1 + 0.174118, + 1 + 0.221772, + -7 + -0.845315, + -3 + 0.19196, + 7 + -0.840461, + 5 + -0.129635, + 1 + -0.596764, + 3 + -0.955832, + 1 + 0.585824, + 5 + 0.0742671, + 5 + -0.517633, + -1 + 0.48289, + 7 + 0.0644312, + 1 + -0.795109, + -7 + -0.782286, + -1 + 0.0230929, + 1 + -0.718512, + -1 + 0.764088, + 5 + 0.510258, + -5 + 0.657883, + -7 + -0.345766, + -3 + 0.430414, + 5 + 0.0833478, + -5 + -0.264892, + 3 + 0.710985, + 1 + 0.150336, + 5 + -0.861506, + 3 + -0.0429562, + -1 + 0.434927, + 7 + 0.815823, + -5 + -0.824405, + 7 + -0.262346, + -7 + -0.164051, + -5 + -0.646918, + 3 + -0.147091, + 3 + 0.13859, + -1 + -0.575533, + -3 + 0.103353, + -5 + 0.992246, + -1 + -0.611302, + 7 + -0.0318776, + 1 + 0.460203, + -3 + 0.548152, + -7 + 0.0172631, + -3 + -0.485489, + -7 + -0.980713, + -7 + -0.827265, + -1 + -0.864176, + -7 + 0.851271, + 7 + -0.466744, + -7 + 0.436088, + -3 + 0.576107, + -7 + -0.637538, + 7 + 0.655137, + 5 + -0.826798, + -5 + 0.848056, + 3 + 0.666798, + -1 + -0.180115, + 7 + 0.419637, + 5 + -0.0167801, + 3 + -0.68837, + 3 + 0.946745, + 3 + -0.0950071, + -7 + -0.827281, + -1 + 0.78343, + -5 + -0.582113, + 7 + 0.299523, + 1 + -0.488113, + 5 + -0.341736, + 7 + 0.530617, + 7 + -0.326339, + -7 + -0.817531, + -3 + -0.221869, + -5 + 0.416757, + 1 + 0.506333, + 1 + -0.2654, + 7 + 0.763487, + -5 + -0.943085, + 7 + 0.791527, + -5 + 0.0668543, + -7 + 0.938847, + -3 + 0.143887, + -3 + 0.381707, + -3 + 0.19505, + -3 + -0.920517, + -5 + 0.145063, + -5 + 0.237513, + -7 + -0.120207, + -7 + -0.0991134, + -5 + 0.0680013, + 1 + -0.0638738, + 5 + 0.970159, + 5 + 0.213576, + 1 + -0.263613, + -7 + -0.544301, + -5 + -0.828692, + -5 + 0.166918, + -5 + -0.761728, + 5 + 0.120694, + 5 + 0.903705, + -5 + 0.211521, + 3 + 0.290967, + 7 + -0.464751, + -7 + 0.186847, + 7 + 0.32524, + -7 + 0.111797, + 1 + -0.788556, + 1 + -0.14745, + -3 + -0.968889, + 3 + -0.37981, + 5 + 0.00729347, + 7 + 0.504821, + 1 + -0.961113, + 3 + 0.710415, + -5 + -0.613475, + 5 + -0.895771, + -1 + -0.895503, + 5 + -0.461719, + 5 + 0.0161815, + -5 + -0.24625, + -7 + -0.572922, + -1 + -0.459816, + 7 + -0.419624, + -5 + 0.696952, + -5 + 0.927165, + -5 + 0.243638, + 7 + 0.360799, + 3 + 0.347879, + -3 + -0.0232377, + 3 + 0.712201, + -1 + 0.759489, + -7 + 0.438561, + -7 + -0.572822, + 1 + -0.737766, + 3 + 0.0680258, + -1 + 0.686509, + 5 + -0.262713, + -5 + -0.79966, + 5 + -0.236232, + -7 + -0.0260004, + -7 + 0.218216, + -3 + 0.370607, + 3 + 0.816354, + 7 + 0.452291, + -3 + -0.822625, + 3 + 0.848817, + 7 + 0.365835, + 1 + -0.676283, + 1 + -0.0594598, + -5 + 0.521534, + 1 + -0.486592, + 7 + -0.986362, + -7 + 0.0779941, + -3 + -0.08751, + 7 + -0.491647, + 7 + -0.270531, + -1 + -0.204778, + 1 + -0.231377, + -7 + -0.469895, + -1 + -0.844354, + -7 + -0.264911, + -1 + -0.1599, + -7 + -0.44972, + -1 + 0.194789, + 1 + -0.104809, + 3 + -0.228419, + -7 + -0.803297, + -7 + 0.625464, + -1 + -0.352292, + -1 + -0.755153, + -1 + -0.67635, + 7 + 0.297913, + 5 + 0.57017, + 5 + -0.173484, + 5 + 0.668881, + 1 + 0.277459, + -3 + -0.784868, + 5 + -0.499577, + 3 + -0.10745, + 7 + 0.92074, + -3 + -0.987991, + 7 + 0.915782, + 3 + -0.98239, + 1 + -0.781632, + -5 + 0.853114, + 5 + -0.13405, + -5 + 0.870097, + 7 + -0.696323, + 7 + -0.94934, + -3 + -0.398685, + -7 + 0.869119, + -5 + -0.903581, + -7 + 0.131423, + -3 + 0.834563, + 7 + 0.143985, + 3 + 0.145958, + -3 + 0.536994, + -5 + -0.691582, + 5 + 0.556042, + 7 + -0.58014, + -5 + -0.103551, + -1 + 0.15221, + 3 + -0.757364, + -5 + 0.580815, + 5 + 0.852026, + -7 + -0.470408, + -3 + 0.0561844, + 5 + -0.515549, + 1 + 0.173103, + -3 + -0.168945, + 5 + -0.762956, + -3 + 0.793081, + -1 + -0.676991, + 3 + 0.665824, + 5 + 0.121066, + -5 + 0.731384, + -5 + 0.671191, + -7 + -0.175862, + -7 + 0.486734, + 5 + 0.163906, + -3 + -0.529629, + -3 + -0.741516, + -5 + 0.780671, + -7 + -0.230291, + -3 + 0.302234, + 7 + -0.987584, + -7 + 0.429419, + 7 + -0.123349, + -3 + -0.693596, + 1 + 0.156304, + -7 + -0.070418, + -5 + 0.939389, + 3 + -0.282077, + 7 + -0.461724, + -7 + -0.266467, + -3 + 0.973726, + 5 + 0.324534, + 1 + 0.798357, + -3 + -0.225007, + -3 + 0.326469, + 1 + 0.217389, + -7 + 0.771884, + 1 + -0.448262, + 1 + 0.834186, + 5 + -0.8447, + 7 + 0.265382, + 7 + 0.882236, + 7 + 0.951853, + 3 + -0.212489, + 7 + -0.900493, + -1 + 0.827988, + 5 + -0.96957, + 5 + -0.794382, + 1 + -0.360357, + -7 + 0.686111, + -5 + -0.770717, + -3 + 0.777591, + 1 + -0.164214, + -1 + 0.85202, + -1 + -0.838606, + 5 + 0.727194, + 3 + 0.628267, + 3 + 0.94657, + 3 + 0.664833, + -1 + -0.545169, + 1 + -0.791937, + 5 + -0.863989, + 1 + -0.433051, + 7 + 0.604505, + -5 + 0.469176, + 5 + 0.521661, + 5 + -0.652277, + 5 + -0.956757, + -1 + 0.179364, + 3 + 0.0835185, + 5 + 0.379708, + -5 + -0.00418501, + -3 + 0.802623, + -1 + 0.127959, + 3 + 0.740128, + 7 + 0.0877058, + -3 + -0.644691, + -7 + 0.803557, + -3 + 0.35763, + 7 + -0.896354, + 5 + -0.985988, + -5 + -0.475576, + -7 + -0.837911, + -5 + 0.399102, + -1 + 0.180557, + 7 + -0.257409, + -3 + 0.748304, + 1 + 0.488153, + 1 + -0.528074, + -7 + -0.568786, + -1 + -0.209861, + 7 + 0.758874, + -7 + 0.690599, + -5 + 0.29666, + -7 + 0.14263, + -5 + -0.580595, + -5 + 0.436222, + -7 + -0.230854, + 1 + -0.0199466, + 7 + 0.0582533, + 1 + -0.241347, + -7 + 0.120772, + -5 + 0.158568, + -7 + 0.590528, + 1 + 0.26066, + 7 + 0.696681, + -3 + 0.343628, + -1 + -0.341235, + -1 + 0.426748, + -5 + -0.39029, + -3 + 0.0793041, + -1 + 0.240872, + -7 + -0.986816, + 5 + -0.546091, + 7 + -0.435825, + -5 + 0.631116, + 5 + 0.793044, + -3 + -0.219459, + 7 + 0.140597, + 5 + 0.447243, + 1 + -0.968491, + 5 + 0.843524, + -5 + -0.860415, + 5 + -0.620946, + 1 + -0.41902, + 7 + -0.81125, + 5 + 0.753432, + -3 + -0.727435, + -1 + -0.141588, + -3 + -0.551413, + -5 + 0.381663, + 5 + -0.0711982, + -5 + 0.390526, + 1 + 0.783724, + -7 + 0.573399, + -3 + -0.939007, + -7 + 0.238314, + -1 + -0.521158, + 5 + 0.779281, + -7 + -0.53298, + 3 + 0.21555, + 3 + 0.482487, + 7 + -0.514751, + -1 + -0.800237, + 1 + -0.764197, + -3 + 0.647617, + 7 + 0.0499004, + -5 + 0.979748, + -3 + 0.67735, + -7 + 0.183253, + -5 + 0.362151, + 5 + -0.545888, + 3 + 0.771438, + -3 + 0.255733, + -7 + 0.115492, + 3 + 0.469995, + -1 + 0.129762, + 3 + -0.767167, + -1 + 0.59735, + -7 + 0.999858, + -5 + -0.412252, + -5 + -0.240744, + -7 + -0.94988, + 7 + -0.533656, + 3 + 0.842152, + 5 + -0.0103345, + 7 + 0.0454008, + 3 + 0.333439, + 3 + -0.456548, + -3 + -0.295064, + 1 + -0.0291067, + 3 + -0.980701, + 5 + 0.0998633, + -7 + -0.236756, + -1 + -0.209321, + 3 + -0.238139, + -1 + 0.873939, + 3 + -0.723713, + -5 + 0.814455, + 3 + 0.679885, + -5 + -0.309287, + 1 + 0.911921, + -5 + -0.330781, + 5 + 0.780826, + 1 + 0.715838, + 3 + -0.334343, + -1 + 0.986761, + -1 + -0.439617, + -3 + -0.590452, + 1 + -0.263775, + 7 + 0.667562, + -5 + -0.76034, + -5 + 0.362745, + 1 + -0.472352, + -7 + 0.206034, + -3 + 0.376895, + 5 + 0.551758, + -3 + 0.0431443, + 5 + -0.310862, + -3 + -0.430074, + 5 + 0.275111, + 7 + -0.912242, + 5 + -0.535872, + 3 + 0.320622, + 3 + 0.381784, + 5 + 0.39575, + -5 + 0.419947, + -1 + 0.632249, + 7 + 0.699329, + 5 + -0.53677, + -7 + 0.160241, + 5 + -0.293807, + -5 + 0.291076, + -5 + 0.691705, + 1 + 0.759055, + 3 + -0.907042, + -5 + -0.23742, + -1 + -0.718808, + -3 + 0.324324, + -5 + 0.768603, + -1 + -0.765854, + 3 + -0.270759, + -3 + -0.780064, + 7 + 0.530695, + 5 + -0.923683, + -1 + -0.209208, + 5 + -0.3521, + 7 + -0.81082, + 7 + -0.472168, + 7 + 0.56371, + 5 + -0.87698, + 3 + -0.0658053, + -3 + 0.646983, + 1 + -0.603423, + 7 + 0.458566, + 7 + 0.32752, + -7 + 0.852152, + 1 + 0.996179, + -1 + 0.686456, + -3 + -0.484814, + 5 + -0.675017, + 5 + -0.458211, + 3 + -0.984357, + -1 + 0.266912, + -7 + -0.589247, + -5 + 0.082882, + -5 + -0.885084, + -3 + -0.560765, + 5 + -0.942018, + 7 + 0.572901, + 7 + -0.171902, + -3 + 0.895929, + -7 + -0.655681, + 5 + -0.029179, + 1 + -0.978318, + 1 + -0.0494022, + -3 + 0.315903, + -7 + -0.249841, + 7 + -0.960858, + -3 + 0.444645, + 3 + -0.725221, + -1 + -0.250617, + 5 + 0.072717, + 3 + -0.348692, + -7 + 0.465731, + 7 + 0.770554, + -1 + 0.161133, + 3 + 0.0440529, + -1 + -0.245592, + -1 + -0.286838, + 1 + 0.710223, + 7 + -0.744359, + -7 + 0.754745, + -3 + 0.268595, + -7 + -0.952184, + 5 + -0.12754, + 1 + -0.113531, + 3 + -0.965244, + 3 + -0.295564, + 5 + -0.589246, + -5 + 0.901493, + 7 + 0.499927, + -1 + 0.205479, + -1 + 0.799496, + 7 + 0.159986, + 1 + 0.0494691, + 5 + 0.414586, + 1 + 0.160234, + 5 + -0.754135, + 7 + 0.533292, + 3 + 0.20959, + -3 + 0.265984, + -1 + -0.596171, + -3 + 0.59227, + -5 + 0.809165, + -3 + 0.731077, + -5 + 0.77249, + -3 + 0.114624, + 7 + -0.612689, + -3 + -0.226237, + -1 + -0.491637, + 5 + -0.902752, + 7 + -0.340862, + 7 + -0.764615, + 1 + 0.361337, + 5 + 0.907293, + -1 + -0.207671, + -7 + 0.749045, + 7 + -0.736116, + 7 + 0.331618, + -5 + -0.0821605, + 3 + -0.784978, + 3 + -0.962937, + 5 + 0.0240877, + -7 + -0.357058, + 7 + 0.582812, + -1 + 0.300038, + 3 + 0.442207, + 1 + 0.311886, + 1 + -0.0907658, + -3 + -0.190202, + 3 + 0.752307, + -5 + 0.110897, + -3 + -0.130689, + 3 + 0.604778, + -5 + 0.832513, + -5 + 0.20769, + 1 + 0.918947, + 7 + 0.635097, + -3 + -0.250696, + -5 + -0.673562, + -7 + 0.188827, + -7 + 0.859836, + -5 + -0.553663, + -1 + -0.693482, + -3 + -0.0370091, + -5 + -0.945403, + -3 + -0.0942642, + 5 + -0.788987, + 7 + 0.130865, + -3 + -0.0568169, + 1 + 0.469934, + -3 + 0.236228, + -3 + 0.969961, + -7 + 0.777844, + -1 + -0.863909, + 1 + -0.0100366, + 3 + -0.901984, + 7 + -0.188674, + -3 + -0.0859814, + -7 + 0.289988, + -5 + 0.216434, + 5 + 0.373371, + -3 + 0.756403, + -3 + -0.327696, + -1 + 0.500791, + 5 + 0.577182, + 1 + 0.846249, + 7 + -0.851769, + -7 + 0.957447, + -3 + -0.351796, + -1 + -0.985339, + -7 + -0.840053, + 7 + -0.911335, + 3 + 0.856743, + 3 + -0.901107, + 3 + -0.966849, + 7 + -0.885129, + -5 + -0.284155, + 7 + -0.344691, + -5 + 0.355503, + 7 + 0.752017, + 5 + -0.243656, + 3 + -0.928544, + 5 + 0.782105, + -7 + -0.759649, + 1 + -0.0744518, + -3 + 0.609258, + 5 + -0.125631, + 5 + 0.25112, + -7 + -0.339128, + 7 + 0.412046, + -5 + 0.555857, + 7 + -0.635087, + 7 + 0.516426, + -1 + 0.74659, + 3 + 0.969918, + -1 + 0.436694, + -5 + 0.0135384, + -3 + 0.340553, + 1 + -0.333334, + 5 + -0.401135, + 3 + 0.217065, + 5 + -0.585701, + 7 + 0.283774, + 1 + 0.436392, + 7 + 0.636664, + 5 + -0.0233952, + 5 + 0.966634, + -5 + 0.792896, + 5 + 0.946402, + -1 + -0.831078, + -7 + -0.944117, + 7 + 0.832928, + -3 + -0.37542, + -7 + -0.951767, + -7 + -0.414159, + 3 + -0.440777, + 5 + -0.591346, + -3 + -0.942129, + 1 + -0.475855, + -1 + -0.452418, + -7 + 0.0502203, + -1 + -0.715986, + 5 + -0.39207, + -1 + 0.00692897, + 1 + -0.305166, + -3 + -0.469096, + -1 + 0.214434, + -7 + 0.0882326, + -7 + -0.311931, + 7 + 0.289892, + 5 + 0.529032, + -3 + 0.543897, + -7 + 0.734108, + 5 + 0.760244, + 7 + -0.921361, + -7 + -0.499923, + 5 + 0.932586, + 3 + -0.492252, + -5 + 0.29961, + 3 + 0.40997, + 1 + 0.607012, + -1 + 0.0977883, + 7 + -0.666918, + 1 + 0.092606, + -3 + 0.48582, + -7 + -0.413194, + -1 + 0.657655, + 7 + -0.790176, + 3 + -0.79396, + 5 + -0.401432, + 3 + 0.241941, + -7 + -0.0372352, + 1 + -0.422785, + -7 + 0.412112, + 3 + -0.649941, + 5 + -0.885332, + -1 + 0.918587, + 5 + 0.580861, + 5 + -0.56943, + 7 + -0.313623, + 1 + 0.508329, + -7 + -0.311971, + -1 + 0.384163, + 7 + -0.407872, + 5 + 0.252608, + -5 + -0.748733, + 7 + -0.766854, + 7 + 0.963027, + 7 + 0.370056, + 7 + 0.91614, + 5 + -0.10655, + 5 + 0.114024, + 3 + 0.6354, + -3 + 0.526766, + -3 + 0.0656808, + -1 + 0.273656, + 3 + -0.518891, + 5 + 0.602608, + -3 + 0.14799, + -5 + -0.304276, + 5 + 0.282315, + -5 + 0.525241, + 3 + 0.917138, + 1 + -0.407829, + 1 + 0.148744, + 7 + 0.374387, + 1 + 0.719541, + 5 + -0.845279, + -7 + -0.271885, + -3 + 0.498453, + -3 + -0.108517, + 7 + -0.916167, + 1 + -0.00524844, + 3 + 0.230628, + 1 + 0.928817, + 5 + 0.961846, + 3 + -0.970376, + -5 + -0.991187, + 1 + -0.988078, + -3 + -0.321644, + 7 + 0.299365, + -1 + 0.260651, + -5 + 0.901838, + -7 + 0.905185, + -7 + -0.998068, + -1 + -0.717301, + 3 + -0.448447, + -5 + 0.853505, + 1 + 0.691012, + -5 + 0.858187, + -7 + 0.744305, + -1 + -0.546463, + -5 + 0.0513083, + -5 + 0.113148, + 1 + 0.753596, + -1 + 0.453985, + 1 + -0.558975, + -3 + -0.931769, + -7 + -0.421414, + -7 + -0.61578, + 3 + -0.601418, + -1 + 0.384031, + 1 + 0.180447, + -1 + 0.160505, + 7 + -0.14269, + 3 + 0.553436, + 3 + 0.842422, + -1 + -0.298941, + -3 + -0.704512, + 1 + -0.817883, + -5 + 0.689056, + 3 + 0.54275, + -7 + -0.244876, + -7 + 0.497505, + -3 + -0.385801, + -7 + -0.228079, + 1 + 0.607185, + 7 + -0.625709, + 5 + -0.851795, + -3 + 0.657661, + 7 + 0.568546, + 1 + -0.0359739, + 1 + 0.836243, + 1 + -0.747603, + -5 + 0.463366, + 7 + -0.62775, + -5 + -0.129517, + 7 + -0.0784853, + -5 + -0.338617, + 1 + -0.0951821, + -3 + -0.0586496, + 1 + 0.548171, + -5 + -0.142791, + 1 + -0.137619, + -5 + 0.86615, + 3 + 0.337578, + -7 + -0.0597365, + -5 + -0.843939, + -3 + -0.607342, + -1 + -0.630138, + -3 + -0.393534, + 7 + 0.354908, + -5 + 0.184251, + 5 + -0.154522, + -5 + 0.828516, + 5 + 0.817169, + -5 + 0.833938, + -5 + 0.689288, + 5 + -0.995259, + -1 + -0.932191, + -7 + 0.964076, + 1 + -0.85304, + -3 + -0.0782913, + 7 + -0.696813, + 5 + 0.231297, + 7 + 0.688421, + 7 + 0.0322752, + 1 + 0.839409, + 1 + -0.362455, + -3 + 0.561378, + 3 + -0.496498, + 1 + 0.841212, + -7 + -0.299443, + 7 + 0.527505, + -1 + 0.51827, + 5 + -0.348049, + -3 + -0.983604, + -1 + 0.694304, + 1 + -0.31786, + -3 + 0.643969, + -1 + -0.650723, + -7 + -0.14479, + -3 + 0.455813, + 7 + -0.627596, + -3 + -0.245695, + -5 + 0.0893783, + 3 + -0.236629, + 5 + -0.277597, + 7 + 0.481512, + -7 + 0.143052, + 3 + 0.615401, + 7 + -0.975698, + -1 + 0.50143, + -3 + 0.0737497, + 1 + 0.345961, + -1 + 0.944933, + -1 + 0.00710848, + 3 + -0.908855, + 3 + -0.104037, + -1 + -0.0996714, + -1 + 0.480154, + -5 + -0.684452, + -3 + -0.104955, + -1 + -0.972497, + 5 + 0.619405, + -5 + -0.361996, + 1 + -0.780079, + -7 + 0.443635, + 7 + 0.527956, + -1 + 0.927314, + 3 + 0.606136, + 3 + -0.22611, + 1 + -0.288871, + -3 + 0.683856, + 5 + 0.486252, + -7 + -0.781706, + 5 + 0.348522, + -7 + -0.743252, + 5 + 0.790582, + -1 + -0.417564, + 1 + 0.971814, + 1 + -0.394633, + 3 + -0.538042, + 7 + -0.82342, + -5 + 0.46215, + -3 + -0.725289, + -1 + -0.248699, + 3 + 0.194388, + -1 + 0.572686, + -1 + 0.57203, + -1 + -0.73258, + 3 + -0.841193, + 3 + 0.846292, + 7 + -0.106951, + -1 + -0.82125, + 5 + -0.565781, + -7 + -0.178221, + 3 + -0.396988, + -1 + -0.194377, + -7 + -0.184276, + 3 + 0.530178, + -1 + 0.0792818, + 3 + 0.698151, + 7 + 0.540132, + 5 + -0.0324876, + -5 + -0.539282, + 1 + -0.0612176, + 1 + -0.00825787, + -5 + -0.594088, + 5 + -0.720534, + -3 + -0.726017, + 3 + -0.247803, + -5 + -0.0351876, + -3 + -0.485217, + 7 + -0.711281, + 1 + -0.143779, + 5 + 0.830104, + -1 + -0.680937, + -5 + -0.406956, + -7 + -0.572693, + 1 + -0.916711, + -7 + -0.361021, + 5 + -0.669143, + -7 + 0.0977001, + -1 + -0.351618, + -3 + -0.292778, + -3 + 0.94385, + -5 + 0.64688, + -5 + 0.462901, + -7 + 0.139473, + 5 + -0.923586, + -7 + 0.100025, + 7 + 0.762592, + 5 + -0.669251, + -5 + 0.552417, + 3 + 0.578362, + -3 + 0.286511, + -5 + -0.819517, + 5 + -0.174663, + 1 + 0.898405, + -3 + 0.276757, + -5 + -0.860502, + -3 + -0.508774, + -7 + -0.619703, + -1 + -0.576515, + 7 + 0.442863, + 1 + -0.792524, + 1 + -0.967062, + -7 + 0.495375, + -7 + -0.497338, + -5 + -0.649645, + -1 + -0.692724, + -7 + -0.681675, + 5 + 0.80008, + -1 + -0.476369, + -3 + 0.102149, + -3 + -0.595665, + -5 + -0.961165, + 7 + -0.990363, + -5 + 0.716457, + -7 + -0.404208, + -1 + -0.483432, + 1 + 0.236347, + -1 + 0.376305, + 1 + -0.0533286, + -7 + -0.610223, + 3 + 0.843043, + -1 + -0.609047, + 1 + 0.725496, + -1 + -0.31617, + -5 + -0.0189003, + -3 + -0.425178, + -7 + -0.321938, + 3 + 0.0120751, + -1 + 0.315381, + -3 + -0.324733, + -3 + -0.571329, + 5 + -0.30955, + 3 + -0.997293, + 3 + 0.105692, + 1 + 0.0166829, + -7 + 0.295209, + -5 + 0.0396503, + -7 + -0.698527, + 1 + -0.983116, + 7 + 0.659054, + -1 + 0.33142, + -7 + -0.0377453, + -5 + -0.0574753, + -1 + 0.852526, + -1 + 0.983994, + -5 + 0.938022, + 1 + 0.513438, + 3 + 0.0546758, + -5 + 0.0823434, + -7 + 0.166195, + -3 + -0.852176, + 1 + 0.366113, + 1 + -0.397224, + -7 + 0.665549, + 1 + -0.0446258, + 3 + 0.702024, + 5 + -0.733169, + -1 + -0.0454769, + -7 + -0.668073, + 1 + 0.27592, + 7 + -0.323333, + 5 + -0.674522, + 7 + 0.0814798, + 7 + -0.782666, + 3 + -0.0710991, + 5 + 0.773968, + -1 + 0.803732, + -1 + 0.142462, + -3 + -0.243322, + -3 + -0.958958, + 5 + 0.308394, + 7 + -0.500096, + -7 + 0.914925, + 7 + 0.150591, + -5 + 0.58597, + 7 + 0.251341, + -3 + -0.636188, + 7 + 0.909046, + 3 + -0.577617, + -7 + -0.903661, + 7 + -0.275888, + 1 + -0.21705, + -5 + 0.736324, + -1 + -0.820161, + -1 + -0.545268, + 3 + -0.0618935, + 7 + -0.126791, + 1 + -0.792842, + -7 + -0.398747, + 3 + -0.583208, + -5 + -0.325178, + 7 + -0.0370357, + -5 + -0.083306, + 5 + 0.819585, + -7 + 0.0991425, + -3 + -0.130402, + -5 + -0.157376, + 7 + 0.691842, + 5 + -0.748137, + -1 + 0.758925, + 1 + -0.312916, + 3 + -0.820843, + 7 + -0.261816, + 7 + -0.172358, + 7 + 0.536986, + 7 + 0.759576, + 7 + -0.754446, + -7 + 0.567095, + -1 + -0.524981, + -3 + -0.802519, + -3 + 0.3109, + 3 + -0.248219, + 5 + 0.0748601, + 7 + 0.960564, + 1 + 0.667926, + -7 + -0.706296, + -3 + 0.635725, + 7 + 0.978146, + -1 + -0.574543, + 5 + -0.430696, + 1 + 0.0996064, + 1 + -0.00163434, + 3 + 0.14937, + 3 + -0.0844981, + 3 + -0.136261, + 5 + 0.973049, + 3 + 0.282247, + 7 + 0.579739, + 5 + -0.0823847, + 5 + -0.0467881, + 5 + 0.596636, + -1 + -0.297972, + -5 + 0.706257, + -7 + 0.604586, + -3 + 0.0669439, + -1 + -0.453354, + 5 + -0.477196, + 5 + 0.311931, + 5 + 0.166079, + 3 + 0.412152, + 7 + 0.474994, + 5 + -0.771076, + 5 + 0.536177, + -5 + -0.0305953, + -3 + 0.580228, + -3 + 0.284461, + -7 + -0.726361, + -3 + -0.726564, + 1 + -0.345421, + 3 + 0.80056, + 1 + 0.878273, + -5 + 0.654627, + -1 + 0.295187, + 7 + 0.591756, + 3 + 0.260911, + 3 + 0.481528, + -3 + -0.77778, + 3 + -0.683316, + -7 + -0.658198, + -3 + -0.74585, + 1 + 0.938157, + 1 + 0.192402, + 5 + 0.361699, + 3 + -0.163265, + -3 + 0.783476, + -5 + 0.737259, + 1 + -0.569672, + 7 + 0.10586, + -1 + -0.173976, + 1 + 0.935026, + -7 + 0.356488, + -1 + 0.0017309, + 5 + -0.675919, + -1 + 0.0665381, + -1 + -0.307875, + 7 + 0.0983045, + 5 + 0.963101, + 3 + -0.519587, + -5 + 0.899631, + 1 + 0.31666, + 7 + -0.756871, + 7 + 0.333545, + -3 + -0.168074, + 7 + 0.87813, + -1 + 0.779471, + -5 + 0.754198, + 7 + -0.868269, + 1 + 0.333521, + 7 + -0.731973, + -1 + 0.33527, + -3 + -0.467703, + -1 + 0.234056, + -3 + -0.237028, + 3 + 0.74204, + 7 + -0.257894, + -7 + 0.690854, + -1 + 0.652636, + 3 + 0.0301753, + -7 + 0.814373, + -1 + -0.951698, + -5 + 0.976247, + -3 + 0.431324, + -3 + 0.192437, + 3 + 0.31289, + -3 + 0.422132, + 3 + -0.00384281, + 3 + 0.72445, + -5 + 0.920278, + -3 + -0.324996, + 3 + 0.181187, + 7 + 0.658717, + -5 + -0.977313, + -1 + 0.378038, + 1 + 0.615551, + -1 + 0.475454, + 3 + 0.735309, + 7 + -0.398705, + 7 + 0.0674037, + -1 + 0.273941, + 5 + -0.376697, + 1 + -0.934663, + 3 + 0.764279, + -5 + -0.67983, + -5 + -0.951744, + -7 + 0.559239, + -7 + 0.123601, + -1 + 0.279154, + 7 + -0.349745, + -1 + 0.881504, + 5 + 0.743417, + -7 + -0.126299, + -3 + 0.129631, + -7 + -0.248369, + 3 + -0.582388, + 7 + 0.606937, + -1 + -0.766819, + -1 + -0.887898, + -3 + 0.628891, + -3 + 0.797051, + 1 + 0.258235, + 1 + -0.289372, + -7 + -0.689227, + -5 + -0.223412, + -5 + -0.0717334, + 5 + 0.444987, + 3 + -0.47443, + 5 + -0.622907, + 1 + 0.231064, + 7 + 0.0643792, + -5 + -0.545879, + -3 + 0.881704, + 7 + 0.421487, + 7 + -0.163227, + 1 + -0.19334, + 5 + 0.754454, + -7 + -0.173896, + -1 + -0.148776, + -5 + 0.342022, + -3 + 0.00779013, + 7 + -0.959293, + 5 + 0.888742, + 1 + -0.0373372, + 3 + 0.154647, + 7 + 0.522902, + -1 + -0.91692, + 1 + -0.762814, + 1 + -0.308587, + -5 + 0.252501, + 3 + 0.186752, + 7 + -0.897854, + 3 + -0.314141, + 7 + -0.123752, + 5 + -0.986531, + 7 + 0.89791, + 1 + -0.133572, + -7 + -0.828677, + -7 + -0.362269, + 1 + -0.231981, + 1 + 0.6903, + 5 + 0.212784, + -1 + 0.790468, + -7 + -0.822496, + 1 + -0.215268, + 5 + -0.232525, + -1 + -0.479589, + 3 + -0.79679, + -5 + -0.604188, + 7 + -0.201313, + -1 + -0.525663, + -7 + -0.155085, + 1 + -0.820419, + -3 + -0.37499, + -3 + -0.983146, + -5 + -0.793733, + -1 + -0.0931721, + 5 + -0.601751, + 3 + 0.0783009, + -1 + 0.768638, + 1 + 0.492399, + -5 + -0.0098969, + -1 + 0.19191, + -7 + -0.979377, + -7 + -0.0178371, + -5 + -0.329518, + 1 + 0.373382, + -7 + -0.845312, + 3 + -0.922893, + 3 + 0.315986, + 3 + 0.486665, + 1 + -0.263414, + -5 + 0.375741, + 3 + 0.909047, + 1 + -0.905982, + 1 + -0.887325, + 1 + -0.20989, + 5 + -0.476245, + 1 + -0.937806, + 3 + -0.749343, + 3 + -0.786876, + -3 + -0.67605, + -1 + 0.0446474, + -5 + 0.652167, + 1 + 0.543258, + -5 + 0.15279, + -5 + 0.148326, + 5 + 0.254656, + -3 + 0.856795, + -7 + 0.751831, + -3 + 0.630068, + 5 + 0.0417778, + -5 + -0.789099, + -7 + 0.741281, + -3 + 0.391712, + -3 + -0.134653, + -1 + 0.326939, + 7 + -0.0234458, + -3 + -0.23408, + -5 + -0.239154, + -5 + -0.832932, + 5 + -0.305414, + 7 + 0.447744, + -3 + -0.729455, + 7 + 0.48413, + 5 + 0.236162, + 5 + -0.534741, + 5 + 0.00340226, + -5 + -0.92795, + 5 + -0.802271, + 5 + -0.486955, + -3 + -0.958796, + 5 + -0.576444, + -1 + 0.107654, + -5 + -0.759059, + -5 + 0.292163, + 1 + -0.785662, + 3 + -0.374019, + 7 + -0.0159586, + -1 + 0.70116, + -5 + 0.0846993, + 1 + 0.401001, + 7 + 0.0279956, + -7 + -0.394888, + 5 + 0.505212, + 7 + 0.786975, + 3 + 0.532436, + -7 + 0.204459, + 3 + -0.615921, + -3 + 0.0758607, + -5 + 0.130031, + -5 + -0.772899, + 3 + -0.274121, + 5 + 0.056024, + -1 + -0.218418, + -7 + -0.183809, + -5 + 0.109609, + 5 + -0.821093, + 7 + -0.353014, + 3 + 0.228901, + 1 + -0.594237, + -3 + 0.39832, + -5 + 0.575415, + -1 + 0.398899, + -5 + -0.239754, + 3 + -0.535948, + 5 + -0.487767, + 5 + 0.282845, + 1 + -0.720766, + -7 + 0.678491, + -3 + 0.389419, + 5 + -0.862186, + 7 + -0.942864, + 7 + -0.341864, + 7 + -0.332763, + -7 + 0.290539, + -5 + -0.076314, + -3 + 0.14099, + 1 + -0.0547188, + 3 + 0.735025, + 3 + -0.197414, + 5 + 0.690544, + 5 + 0.630046, + -3 + -0.117688, + 7 + 0.656909, + 7 + 0.417193, + -3 + -0.489404, + -1 + 0.66448, + 3 + 0.109689, + 1 + -0.601325, + 5 + 0.930691, + 1 + 0.122041, + -3 + 0.991223, + -5 + -0.700354, + -1 + 0.0347951, + 7 + 0.122125, + 1 + 0.218395, + -7 + -0.177617, + 5 + 0.209456, + -5 + -0.976741, + -5 + -0.41843, + -3 + -0.580374, + -1 + -0.424389, + -5 + -0.183439, + 1 + 0.159905, + 1 + -0.825052, + -1 + -0.783269, + 3 + 0.150836, + -5 + 0.385557, + -1 + -0.657701, + -5 + 0.739214, + 7 + -0.990613, + -5 + 0.787245, + -5 + 0.604144, + -5 + -0.871588, + 5 + 0.721765, + 5 + 0.118939, + -5 + -0.859039, + -3 + 0.111408, + -1 + -0.479201, + 1 + -0.470303, + -1 + -0.136117, + 5 + 0.956995, + 1 + -0.39388, + -1 + 0.614385, + 1 + 0.556813, + 7 + 0.844387, + 1 + -0.436025, + -5 + -0.108634, + 5 + -0.100592, + -7 + -0.723946, + 1 + 0.0688398, + 7 + 0.180889, + -3 + 0.628736, + 1 + 0.112598, + 3 + 0.318029, + -3 + 0.634139, + 7 + -0.691032, + 1 + 0.356673, + 5 + 0.0566803, + 1 + -0.351812, + 5 + 0.531286, + -7 + -0.157417, + 7 + -0.99541, + 7 + -0.681986, + 5 + -0.997084, + -7 + 0.741155, + 1 + -0.622678, + 1 + 0.705248, + -5 + 0.711669, + 7 + 0.377357, + -5 + -0.62871, + -5 + 0.0214289, + -1 + -0.997903, + 5 + 0.0933239, + 3 + -0.526274, + -7 + -0.951203, + -1 + -0.755676, + 5 + 0.339232, + -1 + 0.773219, + -3 + 0.426269, + 3 + -0.396471, + 7 + 0.567064, + 5 + 0.633394, + -7 + 0.791714, + 3 + 0.787449, + 3 + -0.472383, + -5 + -0.155762, + -5 + -0.0783671, + -5 + -0.338965, + 3 + -0.793645, + -5 + 0.876857, + -5 + -0.02886, + -1 + 0.566931, + 5 + 0.623439, + 5 + 0.50836, + 7 + -0.3025, + 7 + -0.714796, + -7 + 0.179475, + 7 + -0.662018, + 1 + -0.348355, + 3 + -0.794334, + -3 + -0.157082, + 7 + 0.149085, + 1 + 0.640906, + -3 + 0.349559, + -3 + 0.857413, + -1 + -0.0283983, + -1 + 0.693171, + -3 + -0.214092, + -5 + -0.98936, + 1 + 0.639767, + 3 + -0.194655, + -5 + 0.940209, + -3 + 0.20604, + -3 + -0.564045, + 3 + -0.590761, + 5 + 0.685986, + 3 + -0.764822, + -1 + 0.42185, + -3 + -0.295677, + 1 + 0.216797, + 1 + -0.814246, + -1 + 0.206404, + -3 + 0.328757, + 7 + -0.566083, + 3 + 0.597134, + -3 + 0.642763, + -7 + -0.395769, + 7 + -0.935252, + -7 + 0.626113, + -3 + -0.849858, + 5 + 0.917923, + 5 + -0.376758, + 3 + 0.849631, + -5 + -0.327594, + -7 + -0.0529906, + -3 + -0.923709, + 1 + 0.0692206, + -5 + 0.056296, + 3 + 0.467438, + -1 + -0.814233, + -5 + -0.302013, + -3 + 0.695497, + 7 + 0.651437, + 3 + 0.168943, + 5 + 0.605341, + -1 + -0.372329, + 1 + 0.765342, + 1 + 0.947534, + -5 + 0.116956, + -3 + 0.577997, + 5 + 0.810715, + 1 + -0.779946, + -7 + -0.370998, + 3 + 0.558406, + -1 + -0.233575, + 1 + 0.77588, + -7 + -0.311882, + 5 + -0.910265, + 5 + -0.992932, + 5 + -0.760745, + 1 + 0.318678, + 5 + -0.210387, + 1 + 0.872963, + 3 + 0.220112, + -5 + -0.811578, + 5 + -0.711665, + 5 + -0.150111, + -1 + 0.641725, + 1 + 0.898414, + -3 + -0.650104, + 7 + -0.14629, + 7 + 0.865109, + -1 + -0.347701, + -1 + 0.921759, + 1 + 0.697452, + 1 + 0.0354798, + 5 + -0.176528, + -7 + 0.664795, + -3 + 0.896781, + 3 + -0.958731, + 5 + -0.141991, + 7 + 0.120368, + -5 + 0.485083, + 7 + -0.376901, + -5 + -0.43829, + -5 + -0.586847, + 1 + -0.959211, + 7 + 0.0708796, + -3 + 0.0492324, + -3 + -0.993246, + -1 + 0.650188, + -1 + -0.865149, + -5 + 0.37034, + 7 + -0.338674, + 3 + 0.623087, + -7 + -0.321175, + 7 + -0.764244, + -1 + 0.378604, + 1 + -0.812146, + 3 + 0.444655, + -5 + 0.253273, + 7 + 0.481744, + 3 + 0.455208, + 5 + 0.908443, + 1 + 0.0686094, + -7 + 0.844868, + -5 + -0.976591, + 7 + -0.72575, + 5 + 0.675135, + -7 + 0.274097, + -3 + 0.409609, + 3 + -0.175133, + -3 + 0.796693, + 3 + -0.247288, + -1 + -0.549564, + -7 + 0.967288, + -1 + -0.839667, + 3 + -0.681989, + -1 + -0.523145, + -5 + 0.396439, + 5 + -0.120618, + 3 + 0.693885, + -1 + -0.816144, + -5 + -0.968818, + -3 + -0.390704, + 3 + -0.448062, + 1 + 0.569756, + 5 + -0.336729, + -1 + 0.136729, + 5 + 0.941006, + 5 + -0.465103, + 7 + 0.468966, + -1 + 0.355103, + -7 + 0.615847, + -1 + -0.692941, + -1 + -0.173114, + 3 + 0.594599, + 7 + 0.557483, + 3 + 0.997697, + -5 + 0.24401, + 1 + -0.00963287, + 5 + 0.0275448, + 5 + 0.659747, + -7 + -0.567272, + -5 + -0.405348, + -1 + -0.614457, + 1 + 0.19472, + -7 + 0.553533, + -3 + -0.612328, + 1 + -0.348393, + -3 + 0.771169, + -3 + 0.354427, + -5 + 0.785281, + 3 + -0.318974, + -5 + -0.170041, + -1 + -0.667593, + -1 + -0.514524, + -5 + -0.76729, + 3 + 0.924267, + 7 + -0.893804, + -7 + -0.250356, + 7 + -0.732358, + -7 + 0.490774, + 1 + -0.437992, + -3 + 0.469562, + 1 + 0.436426, + -3 + -0.400156, + 7 + -0.860264, + 1 + 0.0900252, + -1 + -0.754367, + 1 + -0.838147, + -5 + 0.404529, + -7 + -0.437069, + -5 + -0.496662, + 5 + 0.952867, + -3 + 0.894237, + -3 + -0.555447, + -1 + -0.354976, + 1 + -0.60926, + -7 + 0.759444, + 3 + 0.662752, + -7 + -0.815089, + -5 + 0.98253, + 3 + -0.817391, + 5 + -0.61243, + -5 + -0.456923, + -1 + -0.824931, + 7 + 0.514605, + -1 + 0.828664, + -5 + -0.195044, + -3 + -0.333318, + 3 + 0.164695, + -7 + 0.0349422, + 7 + 0.118845, + 5 + -0.174882, + 7 + -0.872202, + 7 + 0.710986, + 3 + 0.699916, + -5 + 0.066256, + 3 + -0.148756, + 7 + 0.508584, + 5 + 0.825367, + -5 + -0.729841, + -5 + -0.887612, + 5 + -0.758424, + -5 + 0.998181, + -7 + 0.65577, + 5 + -0.474471, + 7 + -0.269234, + 3 + 0.104569, + -5 + -0.102212, + -5 + 0.738547, + 5 + -0.94242, + -1 + 0.15571, + 7 + -0.421775, + -7 + 0.804305, + 3 + 0.770802, + 7 + 0.642568, + -7 + 0.971034, + 1 + -0.144741, + -7 + 0.902049, + 7 + 0.157032, + 7 + -0.710021, + 7 + 0.719006, + 1 + -0.119823, + -7 + 0.156298, + 3 + 0.970851, + -1 + -0.163907, + -7 + -0.353286, + -7 + 0.497258, + -7 + 0.283671, + 1 + 0.0405689, + -5 + -0.962454, + -3 + -0.219818, + 1 + -0.436599, + -3 + -0.651331, + 5 + 0.192501, + -5 + 0.627465, + 3 + -0.0387857, + -5 + 0.235464, + 3 + -0.0781319, + -1 + 0.372664, + -7 + 0.144817, + -3 + -0.981248, + -7 + -0.438408, + 5 + 0.851478, + -1 + -0.473764, + 1 + 0.00188464, + 3 + 0.433134, + -7 + -0.132385, + 7 + -0.0645663, + -1 + -0.202906, + -7 + -0.19273, + -5 + 0.490564, + 5 + -0.986688, + 3 + -0.259055, + -5 + -0.0975989, + -1 + -0.599443, + -1 + 0.313751, + -3 + 0.839625, + -3 + 0.0875769, + 7 + 0.531778, + 5 + 0.78374, + -7 + -0.568377, + -5 + -0.772801, + -5 + -0.0559519, + -5 + 0.945151, + -7 + 0.260123, + -7 + -0.909106, + -5 + 0.0617756, + -3 + -0.0675705, + 3 + 0.425518, + -3 + 0.0981296, + -1 + -0.137702, + 5 + 0.353555, + 7 + 0.895279, + -7 + 0.247132, + -1 + 0.346749, + -3 + 0.748198, + -5 + 0.584672, + 3 + -0.731422, + 3 + 0.0579248, + 5 + 0.212579, + 5 + 0.1419, + -1 + -0.51401, + 1 + -0.844899, + -1 + -0.478985, + -5 + 0.918879, + 3 + -0.0802303, + 5 + 0.995209, + 1 + 0.228169, + -3 + 0.580333, + -3 + -0.866062, + 7 + -0.978268, + -5 + 0.501526, + -7 + 0.334392, + -1 + 0.442487, + -5 + 0.0704108, + -5 + -0.711541, + -5 + 0.982968, + -7 + 0.722414, + 5 + -0.799889, + 1 + -0.853645, + -7 + 0.997917, + 5 + -0.513696, + 5 + 0.0364606, + 5 + -0.248071, + -7 + -0.387232, + 1 + -0.811699, + 1 + 0.732048, + 3 + -0.679307, + -1 + -0.978209, + -1 + -0.964028, + -5 + -0.611812, + -7 + -0.902063, + -3 + 0.398009, + 3 + 0.00542146, + 5 + 0.601782, + 5 + -0.104203, + 1 + 0.506752, + -5 + 0.436524, + 7 + 0.982469, + -1 + -0.0633421, + -7 + 0.446072, + -1 + 0.927761, + 1 + 0.658156, + -7 + 0.785148, + -1 + -0.591183, + -3 + 0.0137029, + -1 + -0.388246, + 7 + -0.675978, + 1 + 0.0143937, + -7 + 0.690042, + -5 + -0.693171, + -7 + -0.352858, + 3 + -0.970363, + -7 + -0.723423, + 3 + 0.724452, + -3 + 0.158585, + 7 + -0.175004, + 1 + -0.19285, + -1 + 0.992788, + 3 + -0.851952, + 5 + 0.81, + 3 + -0.0435364, + -1 + -0.0813053, + -1 + -0.765415, + -7 + -0.0372974, + -1 + 0.694064, + 1 + -0.136753, + 3 + 0.826244, + -7 + 0.140024, + 5 + -0.0882701, + 1 + 0.295136, + 7 + -0.5227, + -5 + -0.237363, + -3 + 0.709084, + -3 + 0.629578, + -5 + 0.643857, + 7 + -0.668263, + -5 + 0.249376, + -1 + -0.760648, + 1 + -0.927984, + 7 + -0.659877, + 7 + -0.567002, + -1 + 0.0565217, + -3 + 0.805679, + -3 + -0.528236, + -7 + -0.13752, + -3 + 0.887507, + 7 + 0.63262, + 3 + -0.119278, + 3 + 0.890306, + -1 + -0.274285, + -1 + 0.369489, + 7 + 0.0317755, + 3 + -0.856605, + 7 + 0.912634, + -7 + 0.0492215, + 1 + -0.276292, + -7 + -0.177337, + 3 + -0.787517, + -3 + -0.53, + -1 + -0.186417, + 3 + -0.949098, + -7 + -0.517213, + -1 + -0.986841, + 5 + 0.600896, + 7 + 0.48168, + -3 + -0.458465, + 5 + 0.321443, + -3 + -0.234238, + 1 + -0.954936, + 5 + -0.0275234, + -7 + 0.924262, + 1 + 0.977532, + -5 + -0.669258, + 3 + 0.364021, + 1 + 0.135028, + -3 + -0.473695, + -7 + -0.185051, + -7 + -0.232574, + 3 + -0.944187, + 3 + -0.0543526, + 5 + 0.673031, + 5 + 0.195805, + 1 + -0.45507, + 7 + 0.404971, + 3 + -0.610784, + 5 + 0.0659073, + -1 + -0.207704, + 7 + 0.644995, + -1 + 0.121214, + -3 + -0.483027, + -7 + 0.711033, + 5 + -0.673219, + -1 + -0.895776, + 3 + 0.951024, + -3 + 0.56215, + 3 + -0.329154, + -5 + -0.577541, + -7 + -0.309147, + -1 + -0.511309, + 7 + 0.499812, + -5 + -0.681876, + -1 + -0.801156, + 7 + 0.151605, + -3 + 0.241685, + 7 + 0.992835, + -3 + 0.982038, + -5 + 0.0631867, + -5 + 0.950436, + 7 + 0.31088, + 5 + -0.708879, + -7 + 0.460315, + 1 + 0.397522, + 3 + -0.830289, + -1 + -0.146992, + 3 + 0.667571, + -5 + 0.870575, + 5 + -0.692335, + 1 + -0.399896, + -7 + -0.421033, + 7 + -0.740574, + -3 + 0.0441913, + -5 + 0.000759854, + -1 + -0.526559, + 7 + -0.50311, + 3 + -0.00944866, + -7 + 0.250031, + -5 + 0.579793, + -3 + 0.554107, + 5 + 0.737397, + 1 + 0.434328, + -5 + -0.698991, + -7 + 0.0322755, + 5 + -0.995791, + -7 + 0.233862, + 3 + -0.201264, + 7 + -0.297969, + -5 + 0.377501, + 3 + -0.571389, + -1 + 0.530284, + 5 + -0.179379, + 7 + -0.356844, + -7 + 0.941165, + 1 + 0.339271, + 3 + -0.66842, + -5 + -0.423012, + 3 + 0.316588, + -1 + -0.984114, + 1 + -0.5428, + -1 + 0.766658, + 1 + -0.960606, + 5 + -0.620487, + 7 + 0.266202, + 7 + 0.901102, + 1 + -0.268669, + -5 + -0.607472, + -7 + -0.52709, + -3 + 0.0705389, + 1 + -0.608374, + -3 + -0.288577, + -5 + 0.843351, + -3 + 0.612135, + -5 + 0.230486, + 5 + -0.244291, + -1 + 0.576229, + -3 + 0.446377, + -3 + -0.106511, + -3 + 0.889909, + -5 + -0.918941, + 1 + 0.848997, + -5 + 0.10993, + -3 + 0.256356, + 1 + 0.504098, + 5 + -0.170462, + 1 + 0.835316, + 7 + 0.644516, + -7 + 0.90372, + -7 + 0.463742, + -5 + 0.349377, + -7 + -0.553437, + 1 + 0.330349, + 5 + 0.710921, + -3 + 0.654504, + -5 + -0.447801, + -5 + 0.0517276, + -1 + 0.975718, + 3 + 0.874352, + -1 + 0.678769, + -1 + -0.264881, + -3 + -0.0680661, + 1 + -0.824504, + -7 + -0.0992408, + -5 + -0.862084, + 3 + -0.805812, + 5 + 0.237566, + -3 + 0.888929, + 1 + -0.476846, + -1 + 0.621217, + 1 + 0.65046, + 1 + -0.177248, + -1 + 0.0533044, + 3 + -0.176522, + -1 + 0.676266, + 5 + 0.0818662, + 5 + -0.0801649, + 5 + -0.430938, + 3 + -0.763183, + -7 + -0.453813, + 3 + 0.555379, + -3 + 0.858594, + 3 + 0.227172, + -1 + -0.632746, + -7 + 0.627382, + 1 + -0.0489046, + 7 + -0.828429, + 3 + 0.555978, + -7 + -0.130752, + 1 + 0.978551, + 1 + 0.985192, + -3 + -0.601231, + -3 + 0.3876, + 1 + 0.907771, + -3 + -0.183183, + -5 + -0.297217, + -5 + 0.579173, + -5 + 0.751301, + 5 + 0.675477, + -7 + -0.700691, + 1 + 0.947316, + -7 + -0.635739, + -1 + -0.1091, + -5 + -0.655627, + -7 + -0.74121, + 1 + 0.334598, + 5 + -0.133385, + -5 + 0.364959, + 5 + -0.692856, + -7 + -0.432334, + -3 + 0.0911902, + -5 + 0.670209, + -7 + -0.0777559, + -3 + 0.769741, + 7 + 0.0235715, + 1 + 0.181115, + -7 + -0.688748, + -7 + -0.641734, + -1 + 0.972104, + 7 + -0.474228, + -7 + -0.984007, + 3 + 0.25339, + 3 + 0.87889, + 5 + 0.624509, + 5 + -0.896409, + 7 + -0.146804, + 5 + 0.79753, + -1 + 0.0419583, + -3 + -0.978575, + 5 + -0.799147, + 7 + -0.100029, + 5 + 0.34877, + 5 + 0.726533, + -3 + 0.902539, + -7 + -0.0300989, + 5 + 0.843366, + 7 + 0.98872, + 7 + -0.428589, + 1 + 0.644193, + -5 + 0.0228081, + 7 + -0.754224, + 7 + 0.805301, + 5 + 0.695254, + -7 + -0.188701, + 3 + -0.581044, + 5 + 0.799149, + 7 + 0.353339, + -1 + -0.9622, + -1 + -0.230887, + 5 + -0.787056, + -7 + -0.706222, + 3 + 0.0197935, + -1 + 0.805143, + 7 + 0.951379, + 5 + -0.333186, + -3 + -0.0693998, + -3 + 0.993613, + -5 + -0.548791, + -5 + -0.964111, + 3 + -0.584394, + 1 + 0.867385, + -7 + -0.480054, + 1 + -0.994699, + 7 + 0.090273, + -3 + 0.901709, + 1 + 0.715806, + 3 + 0.304813, + 7 + 0.403796, + 1 + -0.473723, + 5 + 0.475125, + -1 + 0.0271961, + 7 + -0.487227, + 7 + 0.229468, + -3 + -0.189796, + -3 + -0.625003, + 1 + -0.401116, + -7 + 0.67123, + -5 + -0.927091, + -7 + 0.270972, + 7 + -0.617139, + 1 + -0.91671, + -7 + -0.712691, + -3 + -0.840406, + 5 + -0.406998, + -1 + -0.849947, + 3 + -0.158653, + -1 + 0.0696663, + -1 + 0.758415, + 1 + 0.0694559, + 1 + 0.462296, + -5 + 0.217909, + 1 + 0.473663, + -3 + 0.473242, + -3 + -0.890317, + -3 + -0.397198, + -7 + -0.508332, + 5 + 0.990104, + 5 + -0.32464, + -1 + -0.869012, + 7 + 0.567209, + 1 + -0.495974, + 3 + -0.101183, + -7 + -0.74694, + -5 + -0.675854, + -1 + 0.110992, + -5 + 0.247456, + 7 + 0.840274, + -3 + 0.395728, + 5 + -0.362192, + -3 + -0.680363, + 5 + -0.602484, + -3 + 0.738772, + 1 + -0.644167, + -3 + 0.634913, + 3 + -0.384876, + 5 + -0.916855, + -5 + -0.227988, + -3 + -0.625356, + -5 + -0.740278, + -1 + -0.41118, + 3 + 0.443345, + 3 + 0.736942, + 1 + -0.354426, + -7 + -0.870946, + -3 + -0.546137, + -7 + 0.272889, + 1 + 0.0801028, + 5 + -0.274639, + -5 + -0.154875, + -3 + -0.580005, + -5 + -0.398665, + 3 + -0.385197, + 5 + -0.285359, + 1 + 0.362706, + -7 + -0.855772, + -7 + 0.0454971, + -5 + -0.424857, + -7 + -0.504577, + -5 + -0.00591926, + -5 + 0.149346, + 3 + -0.328489, + 7 + 0.015029, + 7 + 0.747577, + -5 + -0.714686, + 1 + -0.101717, + 3 + 0.656319, + 1 + 0.5271, + -7 + -0.64961, + -7 + -0.359428, + -3 + -0.298523, + -3 + -0.0788614, + 1 + 0.621573, + -1 + 0.0175043, + 3 + -0.579268, + 5 + 0.710546, + 7 + -0.511833, + 5 + 0.162637, + -7 + -0.226472, + 1 + 0.0095225, + 5 + 0.21144, + -5 + -0.582375, + 7 + 0.231257, + 1 + 0.248058, + -1 + 0.922646, + 5 + 0.00967738, + 7 + -0.00782117, + 1 + 0.930862, + 1 + 0.920455, + 7 + -0.994076, + -5 + -0.462763, + 1 + 0.627409, + 3 + 0.936991, + -7 + 0.800793, + -1 + 0.193107, + -7 + 0.703299, + -1 + 0.132479, + 1 + -0.152733, + 5 + -0.953622, + -7 + -0.997253, + 7 + 0.556477, + 3 + 0.272056, + -3 + -0.51489, + 5 + 0.398802, + 5 + 0.602265, + -5 + 0.274229, + -7 + -0.700344, + -7 + 0.0901991, + 5 + 0.0552389, + -7 + -0.536972, + -7 + -0.0797897, + 5 + 0.291342, + 3 + -0.846983, + 3 + 0.700542, + -7 + 0.192372, + 7 + -0.362972, + 5 + 0.180049, + -3 + 0.792655, + 7 + -0.662956, + 5 + -0.142891, + -3 + 0.244501, + -3 + -0.510171, + -3 + 0.321085, + -1 + 0.664982, + 7 + -0.905902, + -5 + 0.966882, + -7 + 0.735439, + 3 + 0.261407, + 3 + 0.963571, + -7 + -0.475502, + 7 + 0.78978, + 7 + 0.365208, + 3 + 0.820723, + 3 + -0.594815, + -1 + -0.942558, + -1 + -0.304459, + -3 + 0.391556, + -1 + -0.795303, + -7 + 0.136453, + -5 + -0.955505, + 1 + -0.534127, + 5 + -0.981382, + -3 + 0.557188, + -5 + -0.118641, + -3 + -0.621408, + -7 + -0.74375, + 7 + 0.0227463, + 5 + 0.112073, + -3 + 0.950711, + 5 + 0.643199, + 5 + -0.351889, + -1 + -0.221595, + -1 + 0.00700172, + 7 + 0.928086, + 5 + 0.0356548, + 3 + -0.370036, + -7 + -0.830755, + -5 + -0.222917, + 1 + -0.782772, + 1 + 0.237148, + -1 + 0.86974, + 5 + -0.537617, + -1 + -0.434889, + -7 + -0.0111739, + 7 + -0.715952, + 3 + -0.40804, + 3 + -0.360795, + 3 + 0.653046, + -3 + 0.706949, + 5 + -0.554727, + -1 + 0.183029, + -7 + -0.239732, + -5 + -0.658072, + 7 + -0.752212, + -5 + 0.293207, + 7 + -0.34722, + -7 + -0.326367, + -5 + -0.0589863, + 5 + -0.927616, + -1 + -0.866135, + 3 + 0.00235856, + -3 + -0.0437649, + -5 + -0.585851, + 1 + -0.481841, + -5 + 0.632601, + 3 + -0.874934, + -1 + -0.230124, + -5 + 0.403241, + -5 + -0.986698, + -1 + 0.968435, + -3 + -0.530127, + 1 + 0.919559, + -7 + 0.425743, + 7 + 0.123378, + 7 + -0.142707, + -7 + -0.494815, + 7 + 0.440976, + -5 + 0.890096, + -3 + -0.708126, + 7 + 0.943091, + -7 + -0.0667361, + 1 + 0.417654, + 7 + 0.25984, + -1 + 0.846645, + 3 + -0.416033, + -1 + -0.149707, + 1 + 0.889424, + 5 + 0.866725, + -3 + 0.625568, + -1 + -0.376365, + -7 + 0.362419, + -7 + 0.212156, + -1 + 0.898672, + 3 + -0.684527, + 3 + 0.350536, + -5 + -0.10858, + -7 + 0.363887, + 1 + 0.431342, + 7 + -0.426099, + -1 + -0.0357183, + 5 + 0.969688, + -7 + 0.436647, + 1 + 0.144824, + 7 + -0.689202, + -5 + -0.369132, + -7 + 0.447801, + 3 + 0.991838, + -5 + -0.95315, + -5 + -0.486236, + 7 + 0.635678, + 7 + -0.672488, + -5 + -0.134572, + -5 + -0.698523, + 3 + 0.0914014, + 5 + 0.826151, + 7 + 0.179363, + 3 + 0.905552, + 3 + 0.460779, + 3 + -0.195297, + -5 + 0.965511, + 1 + -0.98716, + 7 + 0.142015, + -7 + -0.156042, + 7 + 0.338355, + -3 + 0.630815, + -7 + -0.716086, + -5 + 0.30445, + -3 + -0.0663283, + -1 + 0.954605, + -7 + -0.516684, + -1 + 0.739518, + -5 + 0.0926331, + -1 + -0.964479, + -3 + 0.738004, + -1 + -0.0623072, + -3 + 0.994729, + -7 + -0.483703, + -5 + -0.116232, + -3 + 0.608111, + 5 + -0.169533, + 1 + 0.700974, + 7 + 0.344404, + 1 + -0.234486, + -5 + 0.753821, + 3 + 0.264031, + 1 + 0.365123, + -1 + 0.735946, + -3 + 0.075701, + 5 + 0.0457206, + -3 + 0.594172, + 1 + 0.144428, + 3 + -0.945545, + 7 + -0.49231, + -1 + 0.196516, + 7 + 0.397096, + -1 + 0.68979, + 3 + -0.283773, + -7 + -0.891651, + -7 + 0.0992016, + 3 + 0.364927, + 3 + 0.692215, + 1 + 0.902593, + -7 + 0.511356, + 1 + -0.329667, + 3 + 0.151807, + -3 + -0.469367, + -1 + 0.839886, + -3 + 0.990307, + 3 + 0.318869, + 5 + -0.74034, + -5 + -0.339204, + 1 + -0.452787, + 1 + -0.736788, + 1 + -0.248248, + 5 + 0.785201, + 7 + -0.243082, + 7 + -0.107551, + 1 + -0.729608, + -3 + -0.358678, + 1 + -0.786071, + -1 + 0.370913, + 3 + -0.398804, + 1 + 0.0692376, + -1 + -0.103113, + -1 + 0.153375, + 5 + 0.548651, + -1 + -0.306503, + 3 + -0.96292, + 5 + -0.221047, + 5 + 0.567843, + 5 + 0.41284, + 5 + 0.88284, + 1 + -0.629206, + -3 + -0.494796, + 3 + 0.424972, + 7 + 0.365256, + -5 + -0.739219, + 3 + 0.640667, + -5 + 0.633005, + -1 + 0.759701, + 5 + -0.0691017, + -5 + -0.0647394, + -5 + -0.348828, + -5 + 0.665346, + -1 + -0.135857, + 5 + 0.437672, + 5 + 0.381016, + -3 + -0.842788, + -1 + -0.85829, + -7 + 0.19863, + -5 + -0.877027, + 5 + -0.776832, + 3 + -0.591161, + 1 + 0.272311, + 1 + 0.729332, + -7 + -0.085479, + -1 + 0.867551, + -1 + 0.850484, + -7 + 0.688455, + -7 + 0.657501, + 1 + -0.781022, + 7 + -0.853813, + -5 + 0.963325, + 5 + -0.61377, + 1 + -0.946282, + -1 + -0.398061, + 7 + -0.618336, + -5 + 0.210241, + -7 + 0.245468, + 3 + -0.503244, + -7 + -0.991443, + -7 + -0.832428, + 3 + 0.633537, + 3 + -0.0513143, + -5 + -0.740331, + -5 + -0.571087, + -5 + 0.932409, + -1 + 0.310949, + 7 + 0.803959, + 1 + -0.37293, + 3 + 0.625741, + 3 + 0.335055, + -3 + -0.0665732, + -7 + -0.546747, + -3 + -0.824097, + 3 + 0.185571, + -5 + -0.963157, + 1 + -0.575186, + 5 + -0.380057, + -3 + -0.0146486, + -7 + 0.548562, + 7 + -0.294831, + 1 + 0.190966, + 3 + -0.200531, + 3 + 0.769514, + 1 + -0.758442, + 5 + -0.563297, + 3 + -0.268245, + 7 + 0.115331, + 7 + 0.635215, + 1 + -0.393521, + 1 + -0.618453, + -5 + 0.766947, + -5 + -0.89702, + 3 + -0.290726, + -1 + -0.146228, + -7 + -0.671038, + 1 + -0.598244, + 3 + -0.56863, + 7 + -0.501319, + -7 + 0.627518, + 3 + -0.389303, + -3 + 0.0746856, + 5 + -0.0666037, + 5 + -0.275337, + -5 + 0.132165, + 5 + -0.379456, + -3 + -0.232648, + -1 + -0.722393, + -3 + -0.848371, + -3 + -0.894514, + -3 + -0.52825, + -1 + 0.868408, + 5 + 0.305525, + -5 + -0.274425, + -5 + 0.22874, + 5 + 0.71816, + -1 + -0.744417, + -3 + 0.874223, + 1 + -0.0454682, + 3 + 0.998097, + -5 + 0.393407, + 5 + 0.187479, + 1 + 0.85875, + 3 + -0.930842, + 7 + -0.683711, + 3 + -0.625096, + 7 + -0.363623, + -3 + -0.478099, + 5 + 0.0397175, + -1 + 0.772844, + 1 + 0.0351828, + -5 + -0.450596, + 5 + -0.747949, + -1 + -0.901913, + 1 + -0.396489, + 7 + 0.266602, + -3 + -0.144345, + -7 + 0.357022, + -1 + 0.17734, + 3 + -0.490206, + 5 + -0.0589478, + -1 + 0.0215372, + -7 + 0.626992, + 3 + 0.805443, + 5 + -0.774861, + 7 + 0.548483, + -7 + -0.659366, + 5 + -0.399126, + 5 + 0.280639, + -1 + 0.382537, + 5 + 0.253533, + -3 + 0.484453, + -1 + -0.182041, + -7 + 0.403929, + 5 + 0.799799, + -1 + 0.872509, + -1 + 0.446505, + 1 + 0.072863, + 1 + 0.511757, + 5 + -0.0447141, + 7 + 0.418114, + 3 + -0.412815, + -7 + 0.270519, + 1 + -0.691355, + 3 + -0.197421, + 3 + -0.86134, + -5 + -0.0102158, + 1 + 0.35777, + 3 + 0.447566, + -1 + 0.0185418, + -7 + 0.78905, + 7 + 0.691196, + -5 + -0.980607, + 3 + 0.307422, + 1 + 0.612522, + 5 + -0.199466, + -1 + -0.459671, + 1 + 0.170203, + 5 + 0.345741, + -1 + 0.442178, + -5 + 0.431563, + 3 + -0.534043, + 5 + -0.76423, + 3 + 0.121284, + 3 + 0.645713, + 7 + 0.96808, + -7 + 0.488072, + 3 + -0.00669708, + 1 + -0.971889, + -1 + -0.315525, + 5 + 0.541525, + 3 + -0.787017, + -1 + 0.544075, + 3 + -0.0730717, + -5 + 0.522401, + -5 + -0.323174, + 7 + 0.526918, + 5 + -0.385761, + 5 + -0.895487, + -3 + 0.0897052, + -5 + -0.670281, + -5 + -0.182219, + -5 + 0.303178, + -5 + -0.947146, + -3 + -0.721791, + -5 + -0.626817, + 1 + -0.583032, + 3 + 0.641241, + -7 + -0.520007, + 1 + -0.425207, + -5 + 0.0712658, + 1 + 0.812682, + 1 + -0.143148, + 3 + 0.0762144, + 1 + 0.0785892, + 7 + -0.568785, + 1 + -0.59096, + 3 + 0.756584, + -1 + 0.128497, + 3 + -0.975302, + -1 + -0.757146, + 5 + 0.448678, + -7 + 0.00292395, + -3 + -0.0190117, + 7 + -0.211027, + -1 + -0.668733, + -5 + -0.447823, + 1 + -0.502645, + -7 + 0.47152, + -5 + -0.364533, + 7 + 0.745433, + -5 + 0.753726, + -1 + -0.307681, + -1 + 0.791775, + -5 + -0.151863, + -5 + 0.815651, + 7 + -0.0787568, + 1 + 0.901984, + 1 + 0.446558, + -5 + 0.035328, + 5 + -0.461488, + -5 + 0.702664, + 1 + 0.477797, + -1 + -0.0921929, + -3 + -0.231008, + 7 + 0.369765, + -7 + 0.0220315, + 5 + -0.0497525, + -7 + -0.0740606, + -1 + 0.885344, + 3 + 0.332343, + -3 + 0.220104, + -1 + 0.384649, + -5 + -0.196536, + -1 + 0.442901, + 5 + 0.226845, + -7 + 0.378706, + -7 + 0.165296, + 3 + 0.201761, + 1 + -0.666372, + -1 + -0.0523257, + 3 + 0.636851, + 5 + -0.717434, + 1 + -0.354993, + 3 + -0.720888, + -5 + -0.133448, + -5 + -0.12999, + 5 + -0.64646, + 1 + 0.66513, + 7 + 0.38796, + -3 + 0.983196, + 1 + 0.156689, + -1 + -0.598867, + 7 + 0.0891009, + -3 + 0.564803, + 5 + 0.647083, + 3 + 0.28552, + -5 + -0.550295, + 7 + -0.535946, + 3 + -0.323109, + 1 + 0.968116, + -5 + 0.670887, + 5 + 0.723851, + -7 + 0.14941, + 1 + 0.751713, + -3 + 0.379236, + -5 + 0.339108, + -5 + -0.301987, + 3 + -0.683341, + -5 + -0.359829, + 5 + -0.84713, + -3 + 0.304565, + -3 + 0.861481, + 7 + -0.877059, + -5 + 0.289428, + -7 + -0.434084, + -1 + -0.481805, + -3 + 0.932735, + -3 + -0.309733, + -3 + -0.656653, + -1 + 0.858222, + -5 + -0.945002, + -3 + -0.379574, + 1 + -0.329053, + -5 + -0.965912, + -7 + -0.0862743, + -3 + 0.564742, + 1 + 0.430712, + 7 + -0.134825, + 3 + -0.0142276, + -3 + 0.461407, + -3 + 0.237931, + 5 + 0.189721, + -5 + -0.164975, + 3 + 0.158177, + 5 + 0.761349, + 5 + -0.603701, + -1 + 0.343416, + -7 + 0.479708, + 5 + -0.54804, + 5 + 0.0522417, + -7 + -0.975275, + 3 + 0.908053, + 7 + -0.324028, + 1 + 0.20481, + -1 + 0.501097, + -3 + -0.562607, + -5 + 0.555231, + 1 + -0.158267, + 3 + -0.0687857, + 1 + 0.511831, + -5 + -0.607408, + 1 + 0.360143, + -1 + 0.437194, + -3 + -0.092719, + 7 + 0.66663, + -7 + 0.610324, + 1 + 0.477642, + -3 + -0.690053, + 5 + -0.239834, + 5 + 0.430824, + -1 + -0.74709, + -7 + 0.666542, + -3 + 0.787307, + 5 + 0.12119, + -5 + 0.468506, + -7 + -0.655536, + -3 + -0.362963, + -7 + -0.444575, + -5 + -0.813438, + 3 + -0.658917, + -7 + -0.846612, + -5 + 0.47478, + 1 + -0.486082, + -7 + 0.325601, + -3 + 0.10135, + 3 + 0.616988, + -5 + 0.030061, + 1 + 0.546106, + -3 + -0.107568, + 1 + -0.526698, + 1 + -0.402568, + 1 + 0.476488, + 5 + -0.876816, + -7 + -0.814004, + -5 + -0.742022, + 1 + 0.396799, + 3 + 0.302924, + 5 + -0.330856, + 3 + -0.20346, + 1 + -0.0134361, + 3 + 0.603609, + 5 + -0.531407, + 7 + 0.711484, + -1 + 0.520469, + -1 + 0.148813, + 3 + 0.0432309, + 1 + 0.669779, + 1 + -0.428549, + -3 + 0.260938, + -3 + 0.941317, + -5 + -0.780941, + -3 + -0.747831, + 1 + -0.998692, + -5 + 0.892504, + -1 + 0.62686, + 7 + 0.940684, + -1 + -0.157277, + -3 + -0.215904, + 3 + -0.149222, + -3 + -0.876603, + -7 + -0.20916, + 3 + -0.984649, + 7 + -0.60173, + -1 + -0.806134, + -1 + 0.209397, + 1 + 0.310198, + 5 + -0.348507, + -3 + 0.966827, + 1 + -0.781644, + -3 + -0.417686, + 1 + -0.618801, + 7 + 0.862017, + -3 + -0.405402, + -7 + 0.125069, + -7 + 0.815787, + -5 + 0.135567, + -5 + 0.652664, + -5 + 0.509215, + -3 + -0.247757, + -3 + -0.697007, + 7 + -0.760593, + 3 + -0.772638, + -5 + 0.870941, + -1 + 0.864873, + -1 + -0.695855, + 3 + -0.952328, + 7 + -0.984213, + -5 + -0.825547, + 7 + -0.937066, + 1 + -0.030252, + 7 + -0.370309, + -1 + 0.976445, + -1 + 0.105839, + -7 + -0.151788, + 5 + 0.329837, + 5 + 0.484323, + 3 + -0.185114, + 1 + -0.450171, + 7 + -0.174316, + 7 + -0.840168, + -3 + -0.188744, + 7 + 0.4487, + -5 + 0.0857224, + 7 + 0.836002, + -3 + -0.180574, + 7 + 0.933189, + -3 + 0.850465, + -3 + 0.217683, + 7 + -0.504985, + 3 + -0.244207, + -3 + 0.827852, + -3 + 0.231895, + -3 + -0.210397, + -5 + 0.225256, + -5 + -0.424323, + -3 + 0.584223, + 5 + -0.21417, + 7 + 0.0492111, + -5 + 0.717212, + 3 + 0.127463, + 5 + -0.412335, + -3 + -0.235105, + 1 + -0.142685, + 5 + -0.499895, + 3 + -0.081105, + -5 + -0.145618, + 7 + -0.823428, + 5 + -0.860577, + 3 + -0.433851, + 1 + -0.917788, + 1 + 0.0316082, + -7 + 0.825787, + -7 + -0.453454, + -7 + 0.00504467, + -3 + 0.495271, + 3 + 0.0318126, + 5 + -0.344928, + -1 + -0.550629, + -7 + -0.352606, + -1 + -0.122732, + -3 + 0.159171, + 3 + 0.261004, + 3 + -0.691171, + 3 + -0.746879, + 1 + 0.626657, + -3 + 0.0388675, + -1 + 0.51117, + 5 + -0.673213, + -3 + 0.864677, + -7 + -0.726019, + 7 + -0.729394, + -5 + 0.330155, + -7 + -0.0177368, + -7 + -0.300845, + 1 + 0.615713, + 5 + 0.00178831, + 1 + 0.0232089, + 7 + 0.0501066, + -5 + -0.620755, + 1 + -0.446627, + -1 + -0.417687, + 7 + 0.871591, + 7 + -0.750383, + 7 + 0.402812, + 1 + -0.147176, + -5 + 0.443187, + 3 + 0.286959, + 5 + 0.608735, + -3 + 0.380043, + 3 + -0.175819, + 7 + -0.829562, + -7 + -0.79598, + -1 + -0.192267, + -5 + -0.110678, + 1 + 0.6394, + 1 + -0.0846046, + 1 + 0.714054, + 5 + 0.811509, + 1 + -0.398193, + 7 + 0.760568, + -1 + -0.452345, + -5 + 0.687367, + 5 + -0.318674, + -3 + 0.324117, + -7 + 0.236211, + -5 + 0.649759, + 7 + -0.548562, + 3 + 0.0579074, + -3 + 0.967526, + 5 + 0.205966, + 3 + -0.575908, + -5 + -0.137605, + 7 + 0.927195, + -5 + 0.454236, + 5 + -0.445633, + 3 + 0.770301, + 7 + -0.281772, + -1 + -0.810031, + -5 + 0.104421, + -3 + 0.920684, + -1 + 0.868938, + 3 + -0.0053164, + -3 + -0.718631, + -5 + 0.455326, + 5 + -0.820026, + -5 + -0.768273, + 3 + 0.0752762, + 5 + 0.714693, + 7 + -0.17771, + -3 + 0.42292, + -1 + -0.0175617, + 5 + 0.528179, + 3 + 0.568353, + 5 + -0.587159, + 1 + 0.801071, + 7 + 0.0826319, + -3 + 0.0275306, + -5 + 0.676104, + -7 + 0.583124, + -3 + 0.218791, + -7 + 0.227567, + -3 + -0.430536, + 5 + 0.654163, + 3 + -0.467692, + 7 + -0.155845, + -7 + 0.089255, + -3 + 0.938383, + -3 + 0.906627, + 7 + 0.950595, + -5 + -0.489709, + 7 + 0.671718, + 7 + 0.164742, + 3 + -0.852821, + 7 + 0.582895, + -3 + -0.742699, + 1 + -0.0381558, + 1 + 0.752823, + 1 + 0.749102, + -1 + 0.403834, + -3 + -0.442988, + 3 + 0.769955, + -1 + 0.729227, + 3 + -0.464394, + -1 + 0.982971, + 5 + 0.32225, + 3 + 0.707018, + 7 + 0.284523, + -5 + -0.390641, + 7 + 0.838552, + 1 + -0.261646, + 7 + 0.763129, + -1 + 0.26582, + 7 + 0.47961, + 5 + 0.195016, + -1 + 0.442942, + 1 + -0.566928, + 1 + -0.885894, + 3 + 0.809517, + 7 + -0.794782, + 1 + 0.396051, + -1 + -0.717371, + -7 + -0.372855, + -3 + -0.435502, + -5 + 0.486243, + -7 + 0.226385, + -3 + -0.674962, + 5 + -0.818546, + -1 + 0.662066, + -3 + 0.371445, + 7 + -0.181262, + -7 + -0.96998, + 7 + -0.243668, + 1 + -0.622788, + -3 + -0.934349, + -7 + -0.531977, + 7 + 0.913129, + -5 + 0.0873188, + -5 + -0.802866, + 5 + 0.176445, + 7 + 0.931233, + -1 + -0.345816, + -7 + -0.698489, + 3 + -0.0641756, + -1 + 0.20042, + 3 + -0.225253, + 7 + 0.611709, + -3 + -0.526143, + 5 + -0.494852, + -7 + -0.543889, + 5 + -0.865676, + 7 + -0.361067, + -7 + 0.157247, + -1 + -0.148807, + -1 + 0.754306, + -3 + -0.232635, + 1 + 0.285416, + 5 + 0.977439, + 3 + -0.545843, + -5 + -0.684446, + 5 + 0.00538877, + -1 + -0.416723, + 1 + 0.455052, + -1 + -0.694408, + -5 + 0.5697, + -3 + 0.239728, + 7 + -0.157425, + -3 + 0.307093, + 3 + 0.598074, + -3 + -0.192316, + -5 + 0.683009, + 1 + -0.276813, + 7 + -0.0605859, + 7 + -0.160651, + 1 + 0.745574, + 5 + -0.595225, + -3 + 0.679057, + -7 + 0.681067, + -3 + 0.254237, + 3 + -0.309311, + -7 + 0.537294, + 7 + -0.527087, + -1 + -0.914636, + -5 + 0.3696, + -5 + 0.758544, + -3 + 0.615554, + -3 + -0.800559, + 5 + 0.857245, + -7 + 0.911095, + -7 + -0.476043, + 1 + 0.286482, + -7 + -0.106087, + -5 + 0.396264, + -5 + -0.897017, + 1 + -0.963821, + -7 + -0.566173, + -5 + 0.578676, + 1 + 0.813064, + 7 + 0.491473, + 7 + -0.270985, + 5 + 0.132949, + 5 + 0.0161494, + 1 + 0.474008, + -5 + 0.796655, + -3 + -0.63918, + 3 + -0.967985, + 7 + 0.879643, + -1 + 0.214509, + -5 + 0.00227151, + 5 + 0.0762274, + 3 + 0.59941, + 3 + 0.340686, + -5 + -0.518312, + -5 + -0.6534, + -3 + -0.133582, + 1 + 0.772737, + -3 + -0.796512, + -1 + -0.232784, + 7 + -0.567475, + -5 + -0.612535, + -5 + -0.743451, + -5 + 0.922795, + 7 + -0.360325, + -5 + 0.664416, + -7 + 0.537588, + -7 + 0.090611, + -1 + -0.411909, + 3 + -0.926915, + 7 + 0.395344, + -7 + -0.661518, + -3 + -0.170838, + 7 + -0.357837, + -5 + 0.471491, + -3 + -0.382249, + -3 + -0.52305, + -1 + -0.97666, + 3 + 0.0582765, + -1 + -0.0656394, + 7 + -0.406727, + 1 + 0.00918714, + -5 + -0.137935, + 7 + -0.614004, + 1 + -0.979364, + -7 + 0.416733, + -1 + -0.759126, + -7 + -0.370293, + -7 + -0.100497, + 1 + 0.869131, + -3 + 0.164885, + -1 + -0.0975662, + -7 + 0.186475, + 3 + -0.918565, + 3 + -0.0801415, + 7 + -0.100654, + -7 + -0.0564053, + -5 + -0.266266, + 1 + -0.250558, + -7 + 0.00064827, + 1 + 0.0900851, + -5 + -0.598895, + -3 + -0.300177, + -3 + -0.733429, + -1 + 0.644141, + -7 + 0.473614, + -1 + -0.641922, + 5 + -0.771156, + 1 + -0.408759, + 5 + 0.12316, + -5 + 0.293248, + 1 + -0.878825, + -7 + -0.414203, + 1 + -0.158712, + 7 + 0.739709, + -7 + -0.86936, + 3 + 0.642115, + 3 + -0.385535, + -7 + 0.143439, + -3 + 0.698413, + 5 + -0.678345, + 5 + 0.565038, + 5 + 0.815733, + 5 + -0.707831, + -7 + -0.849665, + 3 + -0.293231, + 3 + 0.511878, + -7 + 0.0476101, + -5 + -0.612903, + 5 + 0.912856, + -1 + -0.229084, + -1 + -0.228542, + -1 + 0.543728, + 7 + -0.254476, + 5 + -0.538093, + 7 + 0.873386, + -7 + -0.797387, + 1 + 0.472407, + -5 + 0.952256, + -7 + 0.795923, + -1 + -0.0898826, + -3 + 0.851045, + 3 + 0.649821, + -5 + -0.623912, + -1 + -0.232825, + -5 + -0.293336, + 3 + -0.175406, + 7 + -0.126623, + -3 + -0.458458, + -1 + -0.716308, + 3 + -0.442831, + 5 + -0.240306, + -3 + 0.62798, + 7 + -0.901771, + -1 + 0.980463, + 3 + -0.502372, + -7 + -0.861722, + -1 + 0.827093, + 1 + 0.12554, + -3 + 0.270311, + -5 + 0.348095, + -1 + 0.913085, + 7 + 0.957399, + 7 + 0.340458, + 5 + 0.0422461, + -1 + -0.369125, + -3 + 0.43044, + 7 + -0.632377, + -1 + -0.90659, + 1 + -0.89239, + 7 + 0.828316, + 5 + 0.824523, + -7 + -0.0536567, + 1 + -0.0399239, + 1 + 0.197041, + -1 + -0.554157, + -5 + 0.0431199, + -3 + -0.304071, + -3 + -0.331796, + 5 + 0.822257, + 3 + -0.638709, + 3 + 0.639501, + -1 + -0.549931, + -5 + 0.893208, + 3 + 0.791099, + 7 + 0.153618, + 3 + -0.838246, + -7 + 0.475597, + 1 + -0.354901, + -7 + -0.761264, + -1 + 0.106035, + -3 + -0.481434, + -1 + 0.234136, + 5 + 0.375285, + -7 + -0.539323, + -3 + -0.671027, + -3 + 0.212608, + -5 + 0.992672, + -3 + -0.655146, + -1 + -0.675066, + -1 + 0.944776, + 5 + 0.653261, + 7 + 0.703227, + -1 + -0.329846, + -3 + -0.29662, + 5 + 0.0306179, + 3 + 0.308382, + 5 + -0.37852, + 1 + 0.569875, + -1 + 0.262195, + -7 + 0.65172, + -1 + -0.324076, + -1 + -0.592955, + 3 + 0.330534, + -7 + 0.236835, + 7 + -0.16363, + 5 + -0.350766, + 7 + 0.33076, + -3 + 0.713702, + 7 + 0.986953, + 1 + -0.484957, + 1 + 0.232317, + 1 + -0.241183, + 1 + -0.652168, + -7 + -0.969083, + -3 + -0.00466762, + 7 + -0.643621, + 5 + -0.512406, + 3 + 0.559345, + -1 + 0.876841, + 1 + 0.0247327, + -5 + 0.579806, + -7 + -0.45585, + -1 + -0.978404, + -3 + -0.211921, + 3 + 0.0595151, + -5 + -0.772737, + 1 + 0.701463, + 7 + -0.055659, + 1 + -0.434081, + -7 + -0.748698, + 5 + -0.742137, + 5 + -0.0588123, + -5 + 0.446934, + -7 + -0.9576, + -1 + -0.910423, + -1 + -0.798973, + -7 + 0.643822, + -3 + -0.240149, + 1 + -0.366265, + 1 + -0.168219, + -7 + -0.030838, + 7 + -0.591915, + -3 + -0.92018, + 7 + 0.57597, + -1 + 0.351344, + -7 + 0.647625, + 5 + -0.537432, + -5 + -0.69753, + 3 + 0.489766, + -3 + -0.263308, + 1 + 0.40383, + -1 + 0.0716793, + -3 + 0.0739884, + 7 + -0.543397, + -5 + 0.313842, + -1 + -0.290457, + -3 + -0.84267, + -3 + -0.568324, + -3 + -0.18694, + 7 + 0.544842, + 5 + 0.340199, + -5 + -0.465435, + 5 + 0.386054, + 3 + -0.248471, + -1 + -0.536871, + -3 + -0.00456425, + 5 + 0.30784, + -7 + 0.567282, + -3 + -0.689596, + 7 + -0.973479, + -5 + -0.292588, + 1 + -0.0853992, + 1 + 0.54008, + 1 + 0.933126, + 7 + 0.308498, + -5 + 0.933511, + -1 + -0.616556, + 1 + 0.5256, + -3 + 0.11786, + -1 + 0.742156, + -1 + 0.169955, + -1 + -0.96657, + -3 + 0.556796, + -1 + -0.865691, + -3 + -0.238262, + -5 + 0.647911, + 3 + 0.359834, + 7 + 0.613736, + 1 + 0.507745, + -7 + -0.892512, + 3 + 0.444704, + 7 + -0.939748, + -1 + 0.672554, + -7 + 0.136662, + -7 + 0.565658, + 3 + 0.942443, + -1 + 0.0449975, + 1 + 0.92684, + 3 + -0.297685, + 5 + 0.568496, + 3 + -0.144333, + 1 + -0.166059, + 5 + 0.245617, + -7 + 0.0561295, + 5 + -0.053852, + 5 + 0.796947, + -5 + 0.352517, + -5 + 0.967329, + 5 + -0.892274, + 7 + -0.335576, + -1 + -0.545664, + 5 + 0.768217, + -7 + -0.188918, + -7 + 0.285642, + -3 + -0.467917, + -1 + 0.356141, + -7 + -0.382192, + -5 + 0.0410403, + -3 + 0.593099, + -1 + -0.407076, + 7 + 0.399012, + 3 + -0.215368, + 5 + 0.00567285, + 3 + 0.833758, + 7 + -0.469107, + -3 + 0.84339, + -1 + -0.648244, + -1 + 0.45709, + 5 + 0.221697, + -3 + 0.2979, + -1 + -0.801441, + 5 + 0.358525, + 5 + 0.0155232, + 7 + -0.613239, + -3 + 0.770038, + -3 + 0.386763, + -1 + -0.977012, + -5 + 0.0247041, + 3 + -0.774763, + 1 + -0.269862, + 3 + 0.598317, + -7 + -0.604919, + -5 + -0.295425, + -3 + -0.501016, + 5 + 0.893051, + -7 + 0.592268, + -1 + -0.135156, + 5 + -0.766252, + -3 + 0.445672, + 5 + 0.612924, + -5 + 0.107889, + -1 + 0.306333, + -3 + -0.720024, + 1 + -0.256542, + -5 + -0.644907, + -1 + -0.198375, + -1 + 0.530318, + 7 + 0.865427, + -5 + -0.186188, + 3 + 0.15118, + 5 + 0.652307, + 1 + 0.908472, + 3 + 0.747761, + -1 + -0.654492, + 1 + -0.454527, + 5 + 0.682724, + -5 + 0.372245, + 7 + 0.871819, + 3 + -0.80367, + -1 + 0.448117, + -1 + 0.948526, + -7 + -0.348271, + 7 + -0.927127, + 1 + 0.449701, + -1 + -0.680563, + 1 + 0.892784, + 1 + -0.0924386, + -1 + -0.959661, + 7 + -0.081394, + 5 + -0.963336, + -5 + 0.805157, + -7 + -0.285785, + -7 + -0.592211, + -5 + 0.413432, + -1 + -0.723101, + -3 + -0.0432179, + -3 + 0.357774, + 3 + -0.969629, + -7 + 0.840992, + 7 + -0.0670359, + 1 + -0.230027, + -7 + 0.00539775, + -1 + 0.992222, + -5 + 0.508197, + -1 + -0.0701932, + -7 + -0.916136, + 1 + 0.121754, + 3 + 0.979212, + 5 + 0.710977, + -3 + -0.444553, + 1 + 0.775755, + 1 + -0.731095, + -5 + -0.962054, + -7 + -0.137716, + 1 + 0.0744596, + -3 + -0.298853, + 3 + -0.287877, + 7 + -0.537653, + 7 + -0.370057, + 5 + 0.558642, + -1 + -0.306097, + 5 + 0.298301, + 5 + 0.890951, + 7 + 0.461226, + 5 + -0.273165, + -3 + 0.767864, + -1 + -0.427128, + -7 + 0.0742497, + 3 + -0.628171, + -1 + -0.383706, + -5 + 0.926895, + -3 + -0.111893, + -1 + -0.568481, + 3 + 0.982367, + 3 + -0.746265, + 7 + 0.602531, + 5 + 0.639663, + -5 + 0.640932, + 3 + -0.339199, + -7 + -0.872224, + 7 + 0.493771, + 5 + -0.0426846, + 7 + -0.222289, + 7 + -0.802753, + 5 + -0.998975, + 5 + 0.739618, + 5 + -0.949418, + -7 + -0.348646, + 7 + -0.122117, + -3 + -0.786274, + -1 + -0.910026, + 5 + -0.521515, + 5 + 0.786492, + -3 + -0.956601, + -7 + -0.935189, + -1 + 0.816024, + 5 + 0.675236, + 5 + 0.0495799, + -7 + 0.738648, + 7 + 0.424409, + 3 + -0.438266, + -7 + -0.491474, + 1 + 0.22495, + -5 + -0.0235629, + -3 + 0.479672, + -1 + 0.84058, + -5 + -0.166951, + 5 + -0.0577841, + -1 + -0.642721, + -1 + 0.723607, + 1 + -0.873909, + 3 + -0.888751, + -1 + -0.370589, + -3 + -0.0403842, + 3 + 0.564038, + 1 + -0.590923, + -1 + -0.301823, + 3 + -0.525907, + -7 + -0.700129, + -7 + -0.286343, + -1 + -0.746766, + -1 + 0.510312, + -7 + 0.68781, + -1 + -0.071507, + 5 + 0.20512, + 7 + 0.193939, + -3 + 0.0940258, + -1 + -0.815724, + 7 + 0.914182, + 3 + 0.582396, + -5 + 0.182791, + 5 + -0.169328, + 5 + -0.539398, + 1 + -0.544711, + -7 + -0.29523, + -7 + -0.220718, + -7 + -0.424836, + -1 + -0.583509, + 5 + -0.998364, + 7 + -0.624936, + -3 + 0.682019, + 7 + -0.0926723, + -3 + -0.596477, + -1 + -0.380871, + -3 + -0.215605, + 7 + -0.0981703, + -7 + -0.181927, + -1 + 0.668344, + 1 + 0.550972, + 1 + -0.362117, + -1 + 0.434212, + -7 + 0.529025, + 5 + -0.166071, + -3 + 0.473601, + 5 + 0.555215, + 7 + 0.878004, + 3 + 0.90408, + -5 + 0.504969, + -3 + -0.667642, + -5 + -0.538538, + 5 + 0.188161, + -1 + 0.914107, + 3 + 0.472097, + 7 + 0.510842, + -5 + 0.985461, + -7 + -0.394255, + -5 + 0.890095, + 5 + 0.634067, + -7 + -0.944812, + -1 + -0.199624, + -1 + -0.447444, + 3 + -0.228946, + 7 + 0.22322, + -5 + 0.654362, + -5 + -0.200935, + 3 + -0.833657, + -7 + 0.802499, + 1 + -0.704644, + 5 + -0.415231, + 5 + -0.488818, + -5 + -0.405574, + -3 + -0.551587, + 3 + -0.143344, + -5 + 0.992058, + 7 + 0.973004, + -1 + 0.899068, + -1 + -0.201666, + -5 + -0.327868, + 3 + -0.727053, + -7 + 0.268601, + -7 + 0.109424, + 7 + -0.950672, + 1 + 0.76586, + -3 + 0.875399, + 7 + 0.0168127, + -5 + -0.751942, + 1 + 0.455423, + 5 + -0.133098, + 5 + 0.576325, + -5 + -0.760309, + -7 + -0.273288, + -7 + -0.766843, + 1 + -0.862775, + 7 + -0.885211, + 7 + 0.696724, + -1 + 0.0780369, + 1 + 0.275855, + -5 + 0.21323, + -1 + 0.30191, + 5 + -0.129398, + -3 + -0.659394, + 7 + -0.537345, + -5 + 0.726379, + 1 + -0.351187, + 1 + 0.413273, + -7 + -0.460414, + -1 + 0.780082, + 7 + -0.750839, + 7 + 0.140123, + -1 + 0.431409, + -1 + 0.467309, + 7 + -0.189717, + -5 + -0.619566, + 1 + -0.664491, + 5 + -0.259023, + -3 + 0.956683, + -3 + -0.749516, + -5 + 0.131912, + -7 + 0.20736, + -7 + -0.370862, + 3 + -0.38448, + -7 + -0.0683076, + 5 + -0.0808511, + 3 + -0.716107, + -7 + 0.282494, + -5 + 0.690208, + 5 + -0.0140297, + 3 + -0.0253589, + -1 + -0.286539, + 1 + 0.632755, + 3 + 0.678366, + 7 + -0.298717, + 7 + 0.931446, + 3 + -0.000155271, + 5 + 0.593412, + -1 + -0.237465, + 3 + 0.495449, + 1 + 0.854041, + 7 + 0.417438, + 5 + 0.130533, + 3 + 0.11828, + 7 + -0.492641, + -3 + 0.31251, + -1 + -0.746348, + -3 + 0.00667295, + -7 + -0.849606, + -1 + -0.621633, + 5 + -0.780689, + -7 + 0.325068, + -1 + 0.14253, + -5 + -0.467373, + -7 + -0.215694, + -5 + 0.473324, + -5 + -0.0749665, + 1 + 0.0177372, + 1 + 0.874646, + -3 + -0.548775, + -5 + -0.644173, + 7 + 0.890543, + 1 + -0.258939, + -1 + -0.381203, + 7 + -0.989668, + 7 + -0.370075, + -7 + 0.0443089, + 7 + -0.655745, + -1 + 0.576317, + 1 + -0.867409, + -1 + -0.242211, + 3 + -0.414673, + -3 + -0.668824, + -7 + -0.880169, + -7 + -0.337623, + 3 + 0.421604, + 5 + 0.213655, + 5 + -0.797275, + 5 + 0.0784746, + -7 + 0.29279, + 5 + -0.266808, + 5 + -0.847968, + 3 + 0.627592, + 5 + 0.100925, + -7 + -0.836569, + -5 + -0.484448, + -7 + -0.260665, + 7 + 0.98659, + 5 + 0.811925, + 5 + -0.263092, + 3 + -0.423208, + 3 + -0.219005, + -7 + -0.0725037, + -1 + -0.814871, + 3 + 0.181891, + -3 + 0.309198, + 1 + 0.951535, + -7 + 0.694465, + -3 + 0.851734, + -3 + 0.240617, + 7 + -0.545582, + 7 + -0.582447, + -3 + -0.895393, + 1 + -0.607017, + 5 + 0.575812, + 7 + 0.0485804, + -5 + -0.609581, + 3 + -0.991071, + 1 + -0.69817, + -1 + 0.612983, + 7 + 0.124632, + 1 + -0.934992, + -5 + 0.629333, + -1 + -0.479678, + -7 + -0.690851, + 3 + 0.0123024, + 3 + 0.579883, + -7 + -0.797862, + 3 + 0.930494, + 5 + 0.0959856, + 5 + 0.799511, + 3 + -0.702544, + 3 + 0.863534, + -7 + 0.723902, + 3 + -0.925485, + -3 + 0.0838314, + 5 + -0.539124, + -7 + 0.795782, + -7 + -0.508871, + 3 + -0.666186, + -5 + -0.437818, + 1 + 0.430824, + -1 + 0.890288, + 3 + 0.0323077, + -5 + -0.451717, + 1 + -0.994217, + -5 + -0.889329, + 1 + -0.154296, + 3 + -0.139546, + 3 + 0.783946, + -1 + 0.843542, + -7 + 0.742655, + 3 + 0.0644047, + -3 + 0.707173, + 7 + -0.292937, + -1 + 0.978045, + 3 + -0.495493, + 1 + 0.576421, + -5 + 0.830068, + -7 + -0.7389, + -3 + 0.545496, + 5 + 0.525718, + -5 + 0.491613, + -5 + 0.0724149, + -5 + -0.581892, + -5 + 0.148299, + -3 + -0.0143521, + -7 + 0.224096, + -1 + -0.58379, + -7 + -0.746189, + 3 + 0.678161, + 5 + -0.60352, + 1 + -0.0123151, + -3 + 0.935789, + 7 + 0.146463, + 5 + 0.0833464, + -5 + 0.0973773, + 1 + -0.634221, + 5 + -0.199689, + -5 + -0.977316, + 1 + -0.468532, + -3 + 0.912407, + -1 + 0.618525, + -5 + 0.641828, + -3 + 0.161639, + 3 + -0.521444, + 1 + 0.217545, + -3 + 0.776886, + -5 + -0.0861521, + 7 + -0.684462, + 3 + 0.025459, + 5 + -0.588791, + 3 + -0.968869, + -5 + 0.936218, + 5 + -0.962381, + 1 + 0.102731, + 7 + 0.487412, + 5 + -0.586347, + -5 + 0.483033, + 3 + 0.147303, + 7 + 0.545176, + -1 + -0.346122, + -3 + -0.550012, + -3 + 0.175068, + 5 + -0.32015, + 1 + 0.524341, + -7 + 0.645118, + -5 + -0.940018, + -1 + -0.97908, + -7 + -0.515108, + -3 + 0.367395, + 1 + 0.545659, + 1 + -0.286328, + 5 + -0.58779, + 1 + 0.337098, + 7 + -0.330973, + -3 + 0.374149, + 7 + -0.0352384, + -3 + 0.100802, + -3 + -0.496571, + 5 + -0.780307, + 1 + -0.478443, + 5 + 0.67526, + 7 + -0.425565, + 7 + 0.754558, + -7 + -0.775828, + 5 + 0.655701, + 7 + -0.438407, + 3 + -0.775985, + 7 + -0.666725, + -1 + 0.797674, + 1 + -0.749333, + -7 + 0.194764, + -7 + 0.625181, + -5 + -0.060977, + -5 + 0.643178, + 3 + -0.933005, + -3 + -0.998434, + 3 + 0.713815, + -3 + -0.574046, + -3 + -0.0416154, + -7 + 0.296629, + 7 + 0.191779, + -7 + 0.833033, + -3 + 0.487987, + -3 + -0.575328, + 5 + 0.496461, + 3 + 0.589905, + 7 + -0.924183, + -1 + 0.696718, + 5 + -0.875373, + -3 + 0.0319824, + 5 + -0.207871, + 3 + 0.177233, + -3 + -0.761711, + 1 + 0.401589, + 7 + 0.538526, + 7 + -0.320289, + -3 + -0.281917, + -5 + -0.547839, + -7 + -0.322797, + -5 + -0.605992, + 5 + 0.785395, + -1 + 0.0550308, + -5 + 0.511285, + -7 + 0.402531, + -7 + -0.464181, + 5 + -0.160938, + -5 + -0.735561, + -5 + 0.0996571, + 7 + 0.593118, + 7 + -0.0328994, + -5 + -0.98964, + 3 + 0.205471, + -1 + 0.200857, + 7 + -0.771514, + 1 + -0.587245, + 3 + 0.26805, + -3 + 0.784424, + -5 + -0.963779, + 7 + -0.505932, + -1 + -0.171588, + -1 + 0.670593, + -7 + 0.301767, + 5 + 0.0138393, + -1 + -0.984387, + -1 + 0.0391519, + -3 + -0.222087, + 7 + 0.0864488, + 5 + -0.4927, + 7 + 0.257574, + -3 + 0.232144, + -7 + 0.327466, + 1 + -0.464061, + -3 + -0.275329, + -1 + -0.0648923, + -7 + 0.674159, + -7 + -0.413218, + -7 + -0.692417, + 1 + -0.762459, + -5 + -0.913253, + -7 + 0.36255, + -5 + 0.917413, + -7 + 0.556944, + 7 + 0.869794, + -5 + 0.599393, + -7 + -0.957509, + 3 + -0.0653876, + -3 + 0.542317, + 7 + -0.919778, + -1 + 0.389195, + 1 + -0.694826, + -1 + -0.684451, + 5 + -0.232338, + 7 + 0.107159, + 1 + -0.408376, + 3 + -0.669585, + 5 + 0.257082, + 5 + 0.831891, + -1 + 0.211606, + -5 + -0.384855, + 7 + 0.020007, + -5 + -0.428625, + -3 + -0.0360878, + 5 + -0.848203, + 3 + 0.0254734, + -3 + 0.749542, + -7 + -0.804563, + -1 + -0.0972806, + 1 + -0.248763, + -5 + -0.480906, + -7 + 0.494774, + -7 + 0.809284, + 1 + 0.892301, + 3 + -0.866702, + 7 + 0.549121, + -7 + -0.807113, + 5 + 0.817796, + -3 + -0.258985, + -3 + -0.652257, + 1 + 0.857754, + 1 + 0.602559, + -3 + 0.459551, + -5 + 0.12109, + 7 + 0.228169, + 3 + 0.268535, + -5 + -0.511365, + 3 + 0.473797, + -3 + 0.789188, + 5 + -0.233201, + -1 + 0.337202, + 3 + 0.0872898, + -5 + -0.577231, + -3 + -0.794605, + -3 + 0.948282, + 1 + 0.86739, + 7 + -0.853303, + 1 + 0.585277, + -5 + -0.0480538, + 3 + 0.131517, + -5 + 0.256086, + 3 + -0.220017, + -1 + 0.968746, + 1 + -0.866085, + 1 + -0.75045, + 3 + 0.103057, + 3 + -0.280213, + 7 + -0.915525, + 1 + 0.910469, + -1 + 0.122471, + 7 + 0.756213, + -1 + -0.979998, + -3 + -0.526045, + -3 + -0.515105, + -3 + 0.191857, + -5 + 0.861293, + -5 + 0.557644, + -7 + 0.955665, + -7 + -0.218954, + -5 + 0.843849, + 3 + 0.700339, + -5 + 0.308848, + 5 + -0.671504, + -7 + -0.977673, + -3 + -0.243973, + -7 + -0.21181, + 5 + -0.722984, + 1 + -0.679969, + 1 + -0.943541, + -5 + 0.705531, + -5 + -0.327772, + 3 + -0.462895, + -3 + 0.0536484, + -5 + -0.181505, + 1 + -0.89014, + 3 + -0.24572, + 3 + -0.890222, + -3 + 0.668824, + -1 + -0.785433, + -5 + -0.835302, + 7 + -0.464588, + -3 + -0.970526, + -7 + -0.881556, + 3 + -0.690873, + -7 + 0.627452, + 7 + 0.162041, + 1 + 0.574909, + -3 + -0.436167, + -7 + -0.415736, + -1 + -0.330565, + 3 + -0.0637465, + 1 + -0.952135, + 7 + 0.820211, + 1 + 0.670167, + 3 + -0.227245, + 3 + 0.784935, + -7 + -0.114356, + -7 + -0.79073, + -7 + -0.0845568, + -3 + 0.0352457, + -1 + 0.23913, + 3 + -0.319363, + -1 + -0.784674, + 7 + 0.182406, + -3 + -0.208943, + 1 + -0.0539068, + 5 + -0.793545, + 7 + -0.926668, + -3 + -0.327488, + -5 + 0.286006, + 5 + 0.755716, + -1 + 0.396711, + -5 + 0.50953, + -5 + 0.0396668, + -7 + 0.294158, + 7 + 0.191498, + 1 + -0.157408, + 1 + -0.341843, + 1 + 0.34502, + 1 + 0.892611, + 7 + 0.205394, + -3 + 0.558871, + -5 + 0.209696, + -1 + 0.119176, + 3 + -0.0071817, + -5 + -0.177535, + 3 + 0.909066, + -3 + -0.741923, + 1 + -0.539941, + -3 + -0.037078, + 1 + 0.791042, + -5 + 0.482362, + -5 + -0.0119576, + -3 + 0.52501, + -7 + 0.76094, + -7 + 0.813217, + 7 + 0.985842, + 3 + -0.529906, + 1 + -0.423377, + -3 + 0.0981717, + -3 + -0.223135, + -5 + -0.61793, + 5 + -0.559953, + 5 + -0.469591, + -1 + 0.342377, + 3 + -0.0782716, + 7 + -0.684588, + 7 + 0.389739, + 5 + 0.10658, + -5 + 0.922608, + 7 + 0.602939, + -1 + 0.464956, + 3 + -0.789037, + 5 + 0.429394, + 3 + -0.550469, + 1 + -0.900731, + -3 + -0.623247, + -7 + -0.650424, + -1 + 0.131661, + -1 + -0.806985, + 1 + 0.960326, + -1 + -0.193632, + 7 + 0.582939, + -1 + -0.468436, + 5 + 0.0584084, + -3 + 0.989501, + -7 + -0.836051, + -7 + 0.494241, + -3 + 0.338635, + -1 + -0.648491, + -3 + 0.319444, + 5 + -0.976509, + -7 + -0.560152, + 1 + 0.968145, + -3 + 0.506876, + 1 + -0.446687, + -3 + -0.557403, + -5 + 0.386343, + 7 + -0.26601, + 5 + 0.768097, + -1 + -0.862516, + 3 + 0.092811, + 1 + 0.688699, + -7 + 0.437148, + -7 + 0.819611, + -5 + 0.433439, + -3 + 0.0525214, + 7 + -0.875873, + -1 + -0.318693, + -7 + 0.941041, + 3 + -0.938497, + -5 + -0.700787, + -5 + -0.208713, + -1 + -0.926069, + 5 + 0.763435, + -3 + -0.753673, + -3 + -0.436892, + 5 + 0.25309, + 3 + 0.376517, + 7 + 0.234089, + -1 + 0.602584, + 7 + -0.729457, + -5 + 0.528713, + 5 + -0.0616122, + -5 + 0.485624, + -3 + 0.341517, + 3 + -0.364478, + 7 + 0.124957, + -1 + -0.27282, + 5 + 0.606241, + -7 + 0.409408, + -7 + 0.326685, + 1 + -0.778263, + -5 + -0.479604, + -5 + 0.454517, + 5 + -0.236371, + -5 + -0.208087, + -7 + -0.336902, + -3 + 0.704184, + -1 + -0.607403, + -1 + 0.790341, + -1 + -0.458402, + 3 + 0.29028, + -5 + 0.608615, + -5 + 0.064577, + 7 + -0.440438, + 7 + 0.518133, + 3 + -0.400959, + -5 + 0.957821, + -3 + 0.832433, + -7 + -0.941491, + -3 + -0.158894, + -3 + 0.735858, + -5 + -0.942659, + -7 + 0.362461, + -3 + 0.175003, + -3 + 0.756938, + 5 + -0.586989, + -3 + -0.867437, + -7 + 0.204605, + 7 + -0.447344, + 7 + 0.37656, + -7 + 0.548076, + 5 + -0.720016, + -7 + -0.533887, + -1 + 0.0948688, + -1 + 0.921622, + 5 + -0.363181, + 1 + 0.875163, + 1 + -0.975703, + -7 + -0.991177, + 3 + 0.142339, + -7 + -0.670125, + 7 + 0.835181, + -7 + -0.176508, + 7 + -0.391808, + -3 + 0.659639, + -7 + 0.311382, + -5 + 0.965804, + 3 + 0.127325, + 1 + -0.000208556, + -7 + -0.777168, + -3 + 0.467445, + -7 + -0.274472, + 7 + -0.125423, + -7 + -0.341567, + -7 + -0.152778, + 3 + 0.328462, + 3 + 0.96799, + 3 + -0.863599, diff --git a/gr-atsc/src/lib/qa_atsci_viterbi_decoder_t1_output.dat b/gr-atsc/src/lib/qa_atsci_viterbi_decoder_t1_output.dat new file mode 100644 index 000000000..462b664b5 --- /dev/null +++ b/gr-atsc/src/lib/qa_atsci_viterbi_decoder_t1_output.dat @@ -0,0 +1,2484 @@ +69, +35, +24, +72, +92, +92, +20, +88, +31, +124, +88, +87, +65, +30, +169, +225, +0, +98, +8, +39, +35, +233, +205, +67, +15, +37, +249, +114, +194, +215, +196, +7, +251, +93, +80, +215, +186, +228, +48, +217, +97, +137, +177, +163, +168, +90, +132, +168, +189, +140, +208, +224, +118, +158, +36, +134, +196, +29, +248, +134, +245, +189, +141, +240, +26, +221, +200, +212, +194, +248, +173, +35, +130, +95, +198, +42, +185, +74, +211, +119, +215, +164, +88, +78, +66, +124, +212, +6, +154, +204, +141, +143, +137, +27, +127, +164, +249, +72, +120, +187, +64, +38, +222, +195, +133, +165, +237, +63, +240, +193, +183, +199, +101, +15, +21, +168, +140, +233, +175, +38, +182, +60, +182, +64, +87, +53, +228, +80, +126, +93, +11, +191, +132, +234, +130, +10, +143, +112, +74, +127, +49, +2, +71, +150, +18, +93, +63, +158, +71, +238, +197, +253, +43, +123, +62, +130, +177, +35, +211, +47, +129, +223, +238, +6, +202, +112, +17, +89, +224, +91, +217, +17, +94, +33, +168, +112, +126, +231, +14, +197, +214, +212, +195, +1, +79, +1, +132, +1, +36, +87, +48, +165, +55, +30, +172, +1, +143, +189, +90, +112, +24, +52, +130, +119, +85, +42, +231, +211, +18, +246, +153, +232, +202, +92, +234, +26, +93, +110, +27, +130, +197, +75, +40, +253, +106, +212, +254, +250, +145, +89, +106, +170, +141, +236, +33, +227, +23, +9, +183, +41, +255, +80, +18, +201, +172, +252, +227, +10, +107, +255, +141, +49, +74, +181, +46, +181, +138, +44, +175, +27, +133, +26, +198, +19, +6, +232, +246, +29, +241, +174, +71, +240, +254, +90, +185, +171, +87, +157, +182, +194, +157, +67, +243, +232, +248, +34, +157, +130, +78, +77, +158, +212, +103, +100, +231, +110, +76, +222, +140, +61, +140, +211, +46, +138, +46, +232, +54, +133, +133, +236, +72, +35, +47, +59, +11, +40, +94, +168, +171, +172, +246, +74, +128, +93, +174, +104, +204, +251, +70, +88, +57, +210, +44, +103, +93, +90, +79, +148, +223, +213, +129, +39, +248, +177, +99, +4, +217, +193, +172, +133, +110, +162, +207, +239, +0, +126, +87, +205, +121, +158, +37, +179, +113, +81, +27, +207, +171, +107, +99, +139, +65, +228, +178, +58, +149, +22, +62, +111, +216, +234, +244, +70, +141, +195, +54, +142, +66, +141, +91, +187, +44, +129, +111, +157, +210, +138, +108, +126, +245, +208, +9, +55, +180, +188, +113, +74, +211, +175, +185, +171, +154, +174, +242, +40, +114, +40, +183, +180, +182, +19, +112, +226, +148, +223, +128, +103, +106, +237, +229, +96, +189, +239, +151, +114, +172, +8, +189, +127, +184, +118, +43, +83, +37, +29, +123, +151, +70, +50, +76, +252, +69, +188, +223, +218, +156, +96, +65, +6, +77, +39, +102, +11, +23, +254, +125, +195, +7, +59, +67, +191, +178, +111, +18, +215, +141, +142, +111, +211, +192, +187, +208, +6, +119, +176, +225, +19, +16, +34, +26, +94, +74, +128, +105, +97, +127, +231, +37, +134, +35, +104, +69, +213, +215, +88, +172, +101, +230, +27, +56, +167, +214, +9, +174, +78, +185, +143, +98, +202, +178, +124, +40, +253, +253, +146, +94, +124, +122, +131, +2, +157, +236, +72, +114, +196, +161, +31, +41, +136, +58, +98, +47, +17, +107, +222, +96, +37, +110, +194, +239, +32, +63, +24, +29, +60, +170, +124, +185, +37, +0, +188, +195, +237, +4, +53, +178, +165, +84, +219, +45, +143, +62, +93, +161, +169, +60, +1, +206, +170, +196, +190, +203, +4, +214, +232, +65, +129, +101, +250, +166, +102, +182, +105, +83, +186, +159, +5, +96, +244, +225, +142, +132, +31, +236, +37, +201, +40, +39, +152, +210, +236, +86, +157, +240, +44, +134, +49, +173, +235, +44, +83, +81, +226, +189, +165, +157, +93, +170, +254, +81, +140, +141, +213, +171, +121, +251, +117, +161, +35, +13, +116, +16, +99, +17, +0, +144, +152, +50, +61, +132, +95, +145, +214, +66, +79, +123, +223, +172, +38, +222, +254, +178, +107, +211, +94, +229, +207, +212, +134, +242, +225, +251, +2, +69, +12, +3, +214, +164, +54, +20, +40, +149, +165, +254, +215, +245, +122, +183, +162, +160, +150, +160, +83, +1, +116, +177, +230, +67, +133, +109, +54, +103, +104, +56, +173, +117, +60, +131, +26, +115, +151, +67, +9, +61, +65, +224, +50, +188, +152, +212, +92, +46, +116, +175, +48, +232, +97, +23, +44, +231, +132, +98, +78, +237, +155, +251, +98, +215, +126, +124, +74, +22, +191, +83, +83, +1, +52, +133, +189, +205, +90, +26, +252, +207, +202, +45, +183, +43, +68, +228, +19, +201, +70, +98, +182, +225, +93, +25, +185, +220, +150, +4, +243, +86, +88, +70, +88, +141, +203, +21, +90, +38, +48, +87, +245, +250, +132, +173, +38, +200, +145, +57, +145, +215, +156, +72, +185, +250, +98, +114, +215, +248, +119, +202, +78, +207, +16, +166, +92, +220, +188, +183, +2, +237, +14, +247, +231, +146, +164, +14, +91, +53, +72, +237, +13, +228, +53, +199, +222, +151, +57, +181, +144, +177, +127, +222, +128, +143, +133, +220, +107, +66, +147, +109, +47, +162, +101, +23, +52, +9, +37, +143, +63, +110, +125, +77, +82, +179, +20, +49, +75, +78, +230, +219, +255, +102, +186, +127, +246, +64, +92, +98, +130, +240, +208, +177, +146, +53, +200, +198, +63, +238, +86, +127, +92, +212, +204, +175, +135, +224, +224, +210, +47, +199, +173, +46, +45, +104, +174, +36, +168, +10, +134, +42, +250, +86, +220, +141, +139, +165, +83, +203, +148, +170, +74, +241, +126, +22, +160, +6, +247, +128, +216, +38, +72, +134, +85, +117, +238, +3, +153, +151, +13, +32, +194, +8, +118, +158, +149, +2, +68, +233, +205, +217, +148, +23, +202, +19, +46, +106, +25, +38, +235, +241, +76, +51, +120, +162, +169, +103, +165, +66, +254, +179, +98, +192, +188, +217, +95, +82, +219, +164, +59, +169, +125, +208, +193, +71, +227, +239, +177, +252, +22, +157, +238, +98, +208, +102, +5, +121, +206, +170, +188, +204, +94, +31, +141, +26, +248, +237, +108, +212, +146, +168, +125, +15, +120, +62, +87, +91, +46, +9, +88, +68, +166, +70, +167, +118, +173, +172, +240, +124, +87, +172, +72, +181, +203, +214, +207, +196, +196, +59, +152, +86, +228, +21, +102, +92, +84, +190, +183, +131, +199, +16, +199, +110, +86, +110, +229, +4, +27, +213, +128, +114, +129, +201, +39, +77, +160, +247, +17, +100, +51, +169, +187, +23, +191, +33, +115, +20, +223, +43, +151, +167, +59, +94, +21, +146, +205, +251, +150, +233, +208, +23, +91, +82, +224, +131, +159, +129, +122, +177, +229, +173, +91, +160, +196, +27, +194, +56, +47, +162, +99, +198, +74, +159, +37, +95, +49, +243, +91, +200, +220, +43, +223, +55, +126, +192, +187, +29, +65, +53, +207, +39, +226, +42, +200, +167, +69, +138, +223, +116, +45, +67, +59, +119, +226, +97, +215, +20, +84, +50, +221, +48, +94, +188, +104, +220, +125, +35, +249, +191, +89, +200, +230, +60, +243, +175, +227, +56, +57, +195, +173, +103, +7, +233, +222, +234, +74, +181, +254, +158, +232, +219, +207, +70, +152, +56, +34, +22, +92, +28, +213, +181, +229, +188, +241, +216, +107, +213, +17, +165, +153, +190, +12, +160, +167, +235, +139, +242, +161, +138, +144, +137, +101, +96, +208, +254, +152, +242, +20, +244, +14, +234, +170, +243, +167, +155, +204, +19, +113, +221, +184, +11, +156, +197, +171, +68, +177, +55, +54, +82, +193, +199, +220, +39, +39, +172, +37, +192, +158, +58, +180, +173, +37, +94, +161, +204, +250, +109, +224, +108, +75, +153, +119, +232, +94, +35, +45, +15, +90, +99, +98, +27, +43, +62, +66, +83, +234, +104, +20, +137, +162, +201, +54, +200, +39, +215, +149, +34, +69, +117, +142, +144, +14, +6, +121, +109, +41, +166, +125, +131, +10, +223, +159, +53, +29, +225, +137, +8, +74, +157, +145, +237, +102, +200, +181, +142, +159, +74, +177, +229, +192, +64, +118, +207, +70, +239, +60, +111, +149, +185, +243, +160, +153, +146, +214, +182, +116, +95, +191, +190, +253, +80, +171, +99, +25, +97, +242, +185, +172, +163, +158, +108, +228, +20, +59, +42, +4, +120, +154, +154, +49, +141, +58, +202, +32, +16, +129, +149, +112, +65, +83, +109, +146, +255, +209, +171, +96, +196, +100, +13, +103, +2, +121, +76, +23, +181, +118, +28, +45, +17, +183, +95, +158, +241, +42, +191, +2, +172, +84, +115, +237, +168, +224, +127, +168, +178, +42, +8, +118, +142, +22, +222, +145, +143, +42, +169, +69, +160, +197, +114, +177, +124, +210, +80, +110, +252, +16, +113, +168, +101, +228, +149, +13, +197, +20, +181, +119, +63, +190, +237, +206, +212, +203, +95, +100, +245, +9, +169, +150, +207, +28, +72, +76, +238, +153, +186, +234, +169, +44, +146, +14, +17, +40, +28, +214, +61, +209, +77, +125, +144, +59, +75, +100, +6, +171, +200, +252, +180, +114, +147, +131, +142, +219, +207, +124, +117, +138, +102, +31, +183, +249, +45, +200, +34, +74, +158, +96, +27, +236, +221, +172, +39, +40, +16, +46, +212, +217, +43, +136, +75, +190, +11, +217, +154, +219, +85, +15, +102, +188, +46, +29, +182, +92, +229, +217, +166, +131, +57, +194, +112, +22, +110, +151, +63, +127, +197, +19, +88, +241, +156, +163, +175, +168, +125, +73, +131, +211, +88, +233, +143, +135, +7, +70, +227, +236, +31, +138, +112, +88, +77, +224, +111, +187, +120, +174, +59, +62, +194, +147, +47, +94, +55, +222, +6, +180, +40, +138, +135, +129, +116, +23, +8, +123, +93, +236, +103, +125, +118, +216, +213, +195, +184, +69, +127, +49, +244, +187, +111, +182, +78, +158, +21, +134, +125, +27, +59, +165, +165, +195, +38, +25, +218, +47, +149, +56, +27, +252, +181, +146, +213, +139, +86, +142, +208, +213, +191, +196, +145, +46, +123, +223, +205, +144, +102, +75, +171, +161, +240, +81, +101, +23, +107, +64, +70, +0, +120, +98, +253, +46, +244, +210, +185, +74, +96, +138, +32, +32, +78, +177, +79, +201, +145, +28, +89, +248, +103, +5, +154, +88, +87, +255, +112, +195, +63, +183, +196, +184, +25, +193, +230, +14, +148, +160, +89, +245, +42, +122, +21, +121, +43, +100, +67, +189, +129, +157, +182, +233, +162, +80, +65, +250, +80, +178, +190, +143, +105, +130, +72, +131, +67, +47, +145, +216, +208, +235, +205, +251, +101, +227, +116, +145, +71, +183, +78, +201, +84, +4, +178, +247, +85, +244, +242, +165, +166, +176, +53, +16, +50, +126, +147, +118, +173, +37, +78, +125, +16, +28, +120, +117, +0, +237, +6, +71, +164, +85, +17, +249, +90, +195, +240, +175, +184, +227, +85, +94, +147, +138, +110, +197, +8, +2, +60, +182, +39, +139, +51, +55, +167, +172, +173, +167, +153, +179, +239, +62, +9, +1, +55, +99, +196, +40, +19, +124, +12, +104, +219, +159, +243, +74, +101, +251, +76, +161, +178, +115, +44, +230, +171, +212, +146, +88, +124, +44, +12, +108, +107, +21, +109, +163, +121, +50, +204, +140, +175, +216, +244, +138, +119, +232, +213, +221, +228, +33, +127, +150, +149, +172, +124, +64, +129, +15, +153, +253, +59, +166, +105, +167, +187, +215, +74, +53, +9, +22, +193, +184, +238, +182, +67, +102, +158, +24, +68, +130, +58, +195, +24, +207, +111, +149, +16, +240, +164, +170, +238, +224, +80, +88, +135, +12, +47, +209, +65, +57, +232, +2, +242, +215, +185, +53, +62, +87, +78, +130, +218, +136, +69, +243, +87, +181, +136, +104, +166, +44, +18, +148, +13, +99, +237, +148, +111, +28, +102, +176, +86, +79, +179, +72, +38, +109, +125, +100, +197, +203, +231, +159, +83, +44, +146, +171, +226, +27, +20, +137, +72, +39, +29, +85, +138, +10, +234, +249, +39, +81, +170, +125, +160, +94, +197, +198, +203, +67, +43, +145, +15, +18, +48, +98, +63, +195, +14, +34, +222, +35, +171, +39, +74, +201, +125, +212, +212, +103, +206, +251, +185, +121, +121, +89, +215, +63, +32, +163, +130, +75, +52, +145, +94, +101, +244, +158, +40, +3, +192, +7, +38, +107, +47, +113, +52, +172, +69, +8, +20, +20, +4, +205, +141, +126, +38, +101, +189, +71, +9, +64, +147, +62, +210, +241, +163, +198, +143, +204, +202, +80, +212, +241, +187, +4, +98, +240, +176, +168, +249, +197, +188, +254, +146, +73, +124, +185, +175, +57, +1, +184, +122, +148, +246, +76, +134, +154, +19, +21, +102, +222, +102, +59, +207, +33, +63, +49, +18, +240, +218, +11, +181, +150, +9, +72, +224, +134, +2, +143, +192, +3, +71, +58, +151, +62, +135, +29, +216, +154, +51, +63, +120, +153, +123, +72, +187, +187, +122, +206, +171, +84, +218, +97, +234, +228, +169, +203, +106, +172, +90, +42, +175, +162, +101, +71, +224, +236, +101, +185, +135, +153, +248, +0, +51, +116, +72, +238, +47, +194, +189, +218, +22, +151, +60, +1, +123, +230, +204, +230, +146, +38, +17, +66, +200, +118, +137, +169, +99, +239, +98, +234, +136, +91, +234, +187, +208, +51, +170, +255, +245, +103, +218, +11, +255, +22, +12, +123, +252, +217, +97, +142, +255, +115, +208, +200, +234, +90, +114, +77, +73, +212, +56, +209, +48, +35, +141, +0, +86, +55, +0, +75, +159, +218, +87, +159, +240, +100, +26, +237, +61, +124, +124, +61, +239, +77, +6, +218, +167, +120, +39, +241, +77, +96, +195, +125, +132, +80, +126, +218, +136, +126, +38, +40, +88, +126, +199, +73, +226, +225, +55, +32, +94, +179, +94, +78, +1, +100, +40, +168, +220, +80, +154, +41, +177, +93, +167, +53, +173, +37, +16, +54, +164, +55, +94, +253, +181, +37, +70, +152, +7, +126, +184, +102, +50, +22, +180, +51, +123, +221, +220, +87, +46, +118, +129, +223, +211, +41, +20, +129, +78, +37, +183, +243, +92, +21, +240, +17, +59, +55, +169, +67, +181, +98, +170, +231, +121, +94, +27, +244, +60, +247, +76, +106, +109, +206, +73, +64, +247, +94, +193, +70, +131, +121, +57, +223, +143, +41, +241, +203, +97, +155, +14, +23, +253, +184, +255, +119, +23, +26, +108, +83, +17, +184, +190, +127, +135, +7, +191, +126, +102, +129, +196, +233, +251, +254, +200, +138, +40, +186, +85, +137, +85, +100, +160, +83, +29, +159, +202, +53, +185, +54, +137, +203, +239, +71, +74, +119, +79, +10, +245, +181, +140, +186, +158, +135, +184, +103, +18, +224, +33, +103, +106, +118, +204, +10, +201, +234, +170, +147, +31, +99, +202, +168, +47, +186, +239, +121, +50, +62, +131, +39, +243, +15, +225, +146, +151, +154, +249, +169, +123, +26, +17, +229, +145, +221, +239, +90, +199, +153, +238, +230, +253, +185, +142, +44, +116, +126, +166, +166, +189, +41, +206, +176, +57, +176, +67, +208, +74, +60, +121, +197, +87, +138, +170, +232, +104, +154, +67, +48, +52, +50, +22, +49, +236, +165, +94, +96, +36, +4, +7, +225, +46, +213, +146, +104, +133, +213, +57, +207, +18, +178, +149, +105, +61, +63, +82, +166, +218, +150, +214, +14, +200, +237, +64, +180, +147, +159, +21, +183, +164, +28, +152, +210, +241, +42, +59, +118, +0, +116, +70, +18, diff --git a/gr-atsc/src/lib/qa_convolutional_interleaver.cc b/gr-atsc/src/lib/qa_convolutional_interleaver.cc new file mode 100644 index 000000000..2850549b0 --- /dev/null +++ b/gr-atsc/src/lib/qa_convolutional_interleaver.cc @@ -0,0 +1,131 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include <cppunit/TestAssert.h> +#include <qa_convolutional_interleaver.h> + +void +qa_convolutional_interleaver::t0 () +{ + static int input[16] = { + 1, 2, 3, 4, + 5, 6, 7, 8, + 9, 10, 11, 12, + 13, 14, 15, 16 + }; + + static int output[16] = { + 1, 0, 0, 0, + 5, 2, 0, 0, + 9, 6, 3, 0, + 13, 10, 7, 4 + }; + + // test interleaver + intl = new convolutional_interleaver<int>(true, 4, 1); + + for (int i = 0; i < 16; i++) + CPPUNIT_ASSERT_EQUAL (output[i], intl->transform (input[i])); +} + +void +qa_convolutional_interleaver::t1 () +{ + static int input[16] = { + 1, 0, 0, 0, + 5, 2, 0, 0, + 9, 6, 3, 0, + 13, 10, 7, 4 + }; + + static int output[16] = { + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 1, 2, 3, 4 + }; + + // test deinterleaver + intl = new convolutional_interleaver<int>(false, 4, 1); + + for (int i = 0; i < 16; i++) + CPPUNIT_ASSERT_EQUAL (output[i], intl->transform (input[i])); +} + +void +qa_convolutional_interleaver::t2 () +{ + intl = new convolutional_interleaver<int>(true, 4, 1); + deintl = new convolutional_interleaver<int>(false, 4, 1); + + int icount = 6000; + int dcount = 6000; + + int end_to_end_delay = intl->end_to_end_delay (); + for (int i = 0; i < end_to_end_delay; i++){ + CPPUNIT_ASSERT_EQUAL (0, deintl->transform (intl->transform (icount++))); + } + + for (int i = 0; i < 3 * end_to_end_delay; i++){ + CPPUNIT_ASSERT_EQUAL (dcount++, deintl->transform (intl->transform (icount++))); + } +} + +void +qa_convolutional_interleaver::t3 () +{ + intl = new convolutional_interleaver<int>(true, 4, 2); + deintl = new convolutional_interleaver<int>(false, 4, 2); + + int icount = 6000; + int dcount = 6000; + + int end_to_end_delay = intl->end_to_end_delay (); + for (int i = 0; i < end_to_end_delay; i++){ + CPPUNIT_ASSERT_EQUAL (0, deintl->transform (intl->transform (icount++))); + } + + for (int i = 0; i < 3 * end_to_end_delay; i++){ + CPPUNIT_ASSERT_EQUAL (dcount++, deintl->transform (intl->transform (icount++))); + } +} + +void +qa_convolutional_interleaver::t4 () +{ + intl = new convolutional_interleaver<int>(true, 52, 4); + deintl = new convolutional_interleaver<int>(false, 52, 4); + + int icount = 6000; + int dcount = 6000; + + int end_to_end_delay = intl->end_to_end_delay (); + CPPUNIT_ASSERT_EQUAL (10608, end_to_end_delay); + + for (int i = 0; i < end_to_end_delay; i++){ + CPPUNIT_ASSERT_EQUAL (0, deintl->transform (intl->transform (icount++))); + } + + for (int i = 0; i < 3 * end_to_end_delay; i++){ + CPPUNIT_ASSERT_EQUAL (dcount++, deintl->transform (intl->transform (icount++))); + } +} diff --git a/gr-atsc/src/lib/qa_convolutional_interleaver.h b/gr-atsc/src/lib/qa_convolutional_interleaver.h new file mode 100644 index 000000000..54f3b1e1a --- /dev/null +++ b/gr-atsc/src/lib/qa_convolutional_interleaver.h @@ -0,0 +1,69 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _QA_CONVOLUTIONAL_INTERLEAVER_H_ +#define _QA_CONVOLUTIONAL_INTERLEAVER_H_ + +#include <cppunit/extensions/HelperMacros.h> +#include <cppunit/TestCase.h> + +#include <convolutional_interleaver.h> + +class qa_convolutional_interleaver : public CppUnit::TestCase { + private: + convolutional_interleaver<int> *intl; + convolutional_interleaver<int> *deintl; + + CPPUNIT_TEST_SUITE (qa_convolutional_interleaver); + CPPUNIT_TEST (t0); + CPPUNIT_TEST (t1); + CPPUNIT_TEST (t2); + CPPUNIT_TEST (t3); + CPPUNIT_TEST (t4); + CPPUNIT_TEST_SUITE_END (); + + public: + + void setUp (){ + intl = 0; + deintl = 0; + } + + void tearDown (){ + delete intl; + intl = 0; + delete deintl; + deintl = 0; + } + + private: + + void t0 (); + void t1 (); + void t2 (); + void t3 (); + void t4 (); + +}; + + +#endif /* _QA_CONVOLUTIONAL_INTERLEAVER_H_ */ diff --git a/gr-atsc/src/lib/qa_interleaver_fifo.cc b/gr-atsc/src/lib/qa_interleaver_fifo.cc new file mode 100644 index 000000000..920e68bc8 --- /dev/null +++ b/gr-atsc/src/lib/qa_interleaver_fifo.cc @@ -0,0 +1,58 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include <cppunit/TestAssert.h> +#include <qa_interleaver_fifo.h> + +void +qa_interleaver_fifo::t0 () +{ + fifo = new interleaver_fifo<int>(0); + + for (int i = 10; i < 20; i++) + CPPUNIT_ASSERT_EQUAL (i, fifo->stuff (i)); +} + +void +qa_interleaver_fifo::t1 () +{ + fifo = new interleaver_fifo<int>(1); + + CPPUNIT_ASSERT_EQUAL (0, fifo->stuff (2)); + + for (int i = 1; i < 10; i++) + CPPUNIT_ASSERT_EQUAL (i * 2, fifo->stuff ((i + 1) * 2)); +} + +void +qa_interleaver_fifo::t2 () +{ + fifo = new interleaver_fifo<int>(4); + + CPPUNIT_ASSERT_EQUAL (0, fifo->stuff (1)); + CPPUNIT_ASSERT_EQUAL (0, fifo->stuff (2)); + CPPUNIT_ASSERT_EQUAL (0, fifo->stuff (3)); + CPPUNIT_ASSERT_EQUAL (0, fifo->stuff (4)); + + for (int i = 5; i < 20; i++) + CPPUNIT_ASSERT_EQUAL (i - 4, fifo->stuff (i)); +} diff --git a/gr-atsc/src/lib/qa_interleaver_fifo.h b/gr-atsc/src/lib/qa_interleaver_fifo.h new file mode 100644 index 000000000..3002e8cdf --- /dev/null +++ b/gr-atsc/src/lib/qa_interleaver_fifo.h @@ -0,0 +1,57 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _QA_INTERLEAVER_FIFO_H_ +#define _QA_INTERLEAVER_FIFO_H_ + +#include <cppunit/extensions/HelperMacros.h> +#include <cppunit/TestCase.h> + +#include <interleaver_fifo.h> + +class qa_interleaver_fifo : public CppUnit::TestCase { + private: + interleaver_fifo<int> *fifo; + + public: + + void tearDown (){ + delete fifo; + fifo = 0; + } + + CPPUNIT_TEST_SUITE (qa_interleaver_fifo); + CPPUNIT_TEST (t0); + CPPUNIT_TEST (t1); + CPPUNIT_TEST (t2); + CPPUNIT_TEST_SUITE_END (); + + private: + + void t0 (); + void t1 (); + void t2 (); + +}; + + +#endif /* _QA_INTERLEAVER_FIFO_H_ */ diff --git a/gr-atsc/src/lib/test_atsci.cc b/gr-atsc/src/lib/test_atsci.cc new file mode 100644 index 000000000..655c3aa11 --- /dev/null +++ b/gr-atsc/src/lib/test_atsci.cc @@ -0,0 +1,37 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002,2006 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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; either version 2, or (at your option) + * any later version. + * + * GNU Radio 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include <cppunit/TextTestRunner.h> +#include <qa_atsci.h> + +int +main (int argc, char **argv) +{ + + CppUnit::TextTestRunner runner; + + runner.addTest (qa_atsc::suite ()); + + bool was_successful = runner.run ("", false); + + return was_successful ? 0 : 1; +} |