#include "globals.h" #include "fluxmap.h" #include "decoders/fluxmapreader.h" #include "decoders/fluxdecoder.h" #include "lib/decoders/decoders.pb.h" FluxDecoder::FluxDecoder(FluxmapReader* fmr, nanoseconds_t bitcell, const DecoderProto& config): _fmr(fmr), _pll_phase(config.pll_phase()), _pll_adjust(config.pll_adjust()), _flux_scale(config.flux_scale()), _clock(bitcell), _clock_centre(bitcell), _clock_min(bitcell * (1.0 - _pll_adjust)), _clock_max(bitcell * (1.0 + _pll_adjust)), _flux(0), _leading_zeroes(fmr->tell().zeroes) {} bool FluxDecoder::readBit() { if (_leading_zeroes > 0) { _leading_zeroes--; return false; } else if (_leading_zeroes == 0) { _leading_zeroes--; return true; } while (!_fmr->eof() && (_flux < (_clock/2))) { _flux += nextFlux() * _flux_scale;; _clocked_zeroes = 0; } _flux -= _clock; if (_flux >= (_clock/2)) { _clocked_zeroes++; _goodbits++; return false; } /* PLL adjustment: change the clock frequency according to the phase * mismatch */ if (_clocked_zeroes <= 3) { /* In sync: adjust base clock */ _clock += _flux * _pll_adjust; } else { /* Out of sync: adjust the base clock back towards the centre */ _clock += (_clock_centre - _clock) * _pll_adjust; /* We require 256 good bits before reporting another sync loss event. */ if (_goodbits >= 256) _sync_lost = true; _goodbits = 0; } /* Clamp the clock's adjustment range. */ _clock = std::min(std::max(_clock_min, _clock), _clock_max); _goodbits++; return true; } std::vector FluxDecoder::readBits(unsigned count) { std::vector result; while (!_fmr->eof() && count--) { bool b = readBit(); result.push_back(b); } return result; } std::vector FluxDecoder::readBits(const Fluxmap::Position& until) { std::vector result; while (!_fmr->eof() && (_fmr->tell().bytes < until.bytes)) { bool b = readBit(); result.push_back(b); } return result; } nanoseconds_t FluxDecoder::nextFlux() { return _fmr->readInterval(_clock_centre) * NS_PER_TICK; }