mirror of
https://github.com/davidgiven/fluxengine.git
synced 2025-10-31 11:17:01 -07:00
Replace the Error() object with an error() function which takes fmt
formatspecs, making for much cleaner code. Reformatted everything. This actually happened in multiple steps but then I corrupted my local repository and I had to recover from the working tree.
This commit is contained in:
@@ -29,7 +29,6 @@
|
||||
#include "image.h"
|
||||
#include "lib/decoders/decoders.pb.h"
|
||||
#include "lib/layout.h"
|
||||
#include "fmt/format.h"
|
||||
#include <numeric>
|
||||
|
||||
std::unique_ptr<Decoder> Decoder::create(const DecoderProto& config)
|
||||
@@ -59,7 +58,7 @@ std::unique_ptr<Decoder> Decoder::create(const DecoderProto& config)
|
||||
|
||||
auto decoder = decoders.find(config.format_case());
|
||||
if (decoder == decoders.end())
|
||||
Error() << "no decoder specified";
|
||||
error("no decoder specified");
|
||||
|
||||
return (decoder->second)(config);
|
||||
}
|
||||
|
||||
@@ -12,81 +12,82 @@
|
||||
* than my code.
|
||||
*/
|
||||
|
||||
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)
|
||||
{}
|
||||
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
while (!_fmr->eof() && (_flux < (_clock / 2)))
|
||||
{
|
||||
_flux += nextFlux() * _flux_scale;
|
||||
;
|
||||
_clocked_zeroes = 0;
|
||||
}
|
||||
|
||||
_flux -= _clock;
|
||||
if (_flux >= (_clock/2))
|
||||
{
|
||||
_clocked_zeroes++;
|
||||
_goodbits++;
|
||||
return false;
|
||||
}
|
||||
_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 */
|
||||
/* PLL adjustment: change the clock frequency according to the phase
|
||||
* mismatch */
|
||||
if (_clocked_zeroes <= 3)
|
||||
{
|
||||
/* In sync: adjust base clock */
|
||||
|
||||
_clock += (_clock_centre - _clock) * _pll_adjust;
|
||||
_clock += _flux * _pll_adjust;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Out of sync: adjust the base clock back towards the centre */
|
||||
|
||||
/* We require 256 good bits before reporting another sync loss event. */
|
||||
_clock += (_clock_centre - _clock) * _pll_adjust;
|
||||
|
||||
if (_goodbits >= 256)
|
||||
_sync_lost = true;
|
||||
_goodbits = 0;
|
||||
}
|
||||
/* We require 256 good bits before reporting another sync loss event. */
|
||||
|
||||
/* Clamp the clock's adjustment range. */
|
||||
if (_goodbits >= 256)
|
||||
_sync_lost = true;
|
||||
_goodbits = 0;
|
||||
}
|
||||
|
||||
_clock = std::min(std::max(_clock_min, _clock), _clock_max);
|
||||
/* Clamp the clock's adjustment range. */
|
||||
|
||||
/* I'm not sure what this does, but the original comment is:
|
||||
_clock = std::min(std::max(_clock_min, _clock), _clock_max);
|
||||
|
||||
/* I'm not sure what this does, but the original comment is:
|
||||
* Authentic PLL: Do not snap the timing window to each flux transition
|
||||
*/
|
||||
*/
|
||||
|
||||
_flux = _flux * (1.0 - _pll_phase);
|
||||
|
||||
_goodbits++;
|
||||
return true;
|
||||
_goodbits++;
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<bool> FluxDecoder::readBits(unsigned count)
|
||||
@@ -113,5 +114,5 @@ std::vector<bool> FluxDecoder::readBits(const Fluxmap::Position& until)
|
||||
|
||||
nanoseconds_t FluxDecoder::nextFlux()
|
||||
{
|
||||
return _fmr->readInterval(_clock_centre) * NS_PER_TICK;
|
||||
return _fmr->readInterval(_clock_centre) * NS_PER_TICK;
|
||||
}
|
||||
|
||||
@@ -4,18 +4,17 @@
|
||||
#include "flags.h"
|
||||
#include "protocol.h"
|
||||
#include "proto.h"
|
||||
#include "fmt/format.h"
|
||||
#include <numeric>
|
||||
#include <math.h>
|
||||
#include <strings.h>
|
||||
|
||||
FluxmapReader::FluxmapReader(const Fluxmap& fluxmap):
|
||||
_fluxmap(fluxmap),
|
||||
_bytes(fluxmap.ptr()),
|
||||
_size(fluxmap.bytes()),
|
||||
_config(config.decoder())
|
||||
_fluxmap(fluxmap),
|
||||
_bytes(fluxmap.ptr()),
|
||||
_size(fluxmap.bytes()),
|
||||
_config(config.decoder())
|
||||
{
|
||||
rewind();
|
||||
rewind();
|
||||
}
|
||||
|
||||
void FluxmapReader::getNextEvent(int& event, unsigned& ticks)
|
||||
@@ -25,23 +24,23 @@ void FluxmapReader::getNextEvent(int& event, unsigned& ticks)
|
||||
while (!eof())
|
||||
{
|
||||
uint8_t b = _bytes[_pos.bytes++];
|
||||
ticks += b & 0x3f;
|
||||
if (!b || (b & (F_BIT_PULSE|F_BIT_INDEX)))
|
||||
ticks += b & 0x3f;
|
||||
if (!b || (b & (F_BIT_PULSE | F_BIT_INDEX)))
|
||||
{
|
||||
_pos.ticks += ticks;
|
||||
event = b & 0xc0;
|
||||
event = b & 0xc0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
_pos.ticks += ticks;
|
||||
event = F_EOF;
|
||||
event = F_EOF;
|
||||
}
|
||||
|
||||
void FluxmapReader::skipToEvent(int event)
|
||||
{
|
||||
unsigned ticks;
|
||||
findEvent(event, ticks);
|
||||
unsigned ticks;
|
||||
findEvent(event, ticks);
|
||||
}
|
||||
|
||||
bool FluxmapReader::findEvent(int event, unsigned& ticks)
|
||||
@@ -51,29 +50,30 @@ bool FluxmapReader::findEvent(int event, unsigned& ticks)
|
||||
for (;;)
|
||||
{
|
||||
unsigned thisTicks;
|
||||
int thisEvent;
|
||||
getNextEvent(thisEvent, thisTicks);
|
||||
ticks += thisTicks;
|
||||
int thisEvent;
|
||||
getNextEvent(thisEvent, thisTicks);
|
||||
ticks += thisTicks;
|
||||
|
||||
if (thisEvent == F_EOF)
|
||||
return false;
|
||||
if (thisEvent == F_EOF)
|
||||
return false;
|
||||
|
||||
if (eof())
|
||||
return false;
|
||||
if ((event == thisEvent) || (event & thisEvent))
|
||||
return true;
|
||||
if ((event == thisEvent) || (event & thisEvent))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned FluxmapReader::readInterval(nanoseconds_t clock)
|
||||
{
|
||||
unsigned thresholdTicks = (clock * _config.pulse_debounce_threshold()) / NS_PER_TICK;
|
||||
unsigned thresholdTicks =
|
||||
(clock * _config.pulse_debounce_threshold()) / NS_PER_TICK;
|
||||
unsigned ticks = 0;
|
||||
|
||||
while (ticks <= thresholdTicks)
|
||||
{
|
||||
unsigned thisTicks;
|
||||
if (!findEvent(F_BIT_PULSE, thisTicks))
|
||||
if (!findEvent(F_BIT_PULSE, thisTicks))
|
||||
break;
|
||||
ticks += thisTicks;
|
||||
}
|
||||
@@ -93,14 +93,13 @@ static int findLowestSetBit(uint64_t value)
|
||||
return bit;
|
||||
}
|
||||
|
||||
FluxPattern::FluxPattern(unsigned bits, uint64_t pattern):
|
||||
_bits(bits)
|
||||
FluxPattern::FluxPattern(unsigned bits, uint64_t pattern): _bits(bits)
|
||||
{
|
||||
const uint64_t TOPBIT = 1ULL << 63;
|
||||
|
||||
assert(pattern != 0);
|
||||
|
||||
unsigned lowbit = findLowestSetBit(pattern)-1;
|
||||
unsigned lowbit = findLowestSetBit(pattern) - 1;
|
||||
|
||||
pattern <<= 64 - bits;
|
||||
_highzeroes = 0;
|
||||
@@ -118,8 +117,7 @@ FluxPattern::FluxPattern(unsigned bits, uint64_t pattern):
|
||||
{
|
||||
pattern <<= 1;
|
||||
interval++;
|
||||
}
|
||||
while (!(pattern & TOPBIT));
|
||||
} while (!(pattern & TOPBIT));
|
||||
_intervals.push_back(interval);
|
||||
_length += interval;
|
||||
}
|
||||
@@ -134,7 +132,7 @@ FluxPattern::FluxPattern(unsigned bits, uint64_t pattern):
|
||||
|
||||
bool FluxPattern::matches(const unsigned* end, FluxMatch& match) const
|
||||
{
|
||||
const double clockDecodeThreshold = config.decoder().bit_error_threshold();
|
||||
const double clockDecodeThreshold = config.decoder().bit_error_threshold();
|
||||
const unsigned* start = end - _intervals.size();
|
||||
unsigned candidatelength = std::accumulate(start, end - _lowzero, 0);
|
||||
if (!candidatelength)
|
||||
@@ -142,7 +140,7 @@ bool FluxPattern::matches(const unsigned* end, FluxMatch& match) const
|
||||
match.clock = (double)candidatelength / (double)_length;
|
||||
|
||||
unsigned exactIntervals = _intervals.size() - _lowzero;
|
||||
for (unsigned i=0; i<exactIntervals; i++)
|
||||
for (unsigned i = 0; i < exactIntervals; i++)
|
||||
{
|
||||
double ii = match.clock * (double)_intervals[i];
|
||||
double ci = (double)start[i];
|
||||
@@ -166,7 +164,8 @@ bool FluxPattern::matches(const unsigned* end, FluxMatch& match) const
|
||||
return true;
|
||||
}
|
||||
|
||||
FluxMatchers::FluxMatchers(const std::initializer_list<const FluxMatcher*> matchers):
|
||||
FluxMatchers::FluxMatchers(
|
||||
const std::initializer_list<const FluxMatcher*> matchers):
|
||||
_matchers(matchers)
|
||||
{
|
||||
_intervals = 0;
|
||||
@@ -195,7 +194,7 @@ void FluxmapReader::seek(nanoseconds_t ns)
|
||||
|
||||
while (!eof() && (_pos.ticks < ticks))
|
||||
{
|
||||
int e;
|
||||
int e;
|
||||
unsigned t;
|
||||
getNextEvent(e, t);
|
||||
}
|
||||
@@ -204,7 +203,7 @@ void FluxmapReader::seek(nanoseconds_t ns)
|
||||
|
||||
void FluxmapReader::seekToByte(unsigned b)
|
||||
{
|
||||
if (b < _pos.bytes)
|
||||
if (b < _pos.bytes)
|
||||
{
|
||||
_pos.ticks = 0;
|
||||
_pos.bytes = 0;
|
||||
@@ -212,7 +211,7 @@ void FluxmapReader::seekToByte(unsigned b)
|
||||
|
||||
while (!eof() && (_pos.bytes < b))
|
||||
{
|
||||
int e;
|
||||
int e;
|
||||
unsigned t;
|
||||
getNextEvent(e, t);
|
||||
}
|
||||
@@ -225,13 +224,14 @@ nanoseconds_t FluxmapReader::seekToPattern(const FluxMatcher& pattern)
|
||||
return seekToPattern(pattern, unused);
|
||||
}
|
||||
|
||||
nanoseconds_t FluxmapReader::seekToPattern(const FluxMatcher& pattern, const FluxMatcher*& matching)
|
||||
nanoseconds_t FluxmapReader::seekToPattern(
|
||||
const FluxMatcher& pattern, const FluxMatcher*& matching)
|
||||
{
|
||||
unsigned intervalCount = pattern.intervals();
|
||||
std::vector<unsigned> candidates(intervalCount+1);
|
||||
std::vector<Fluxmap::Position> positions(intervalCount+1);
|
||||
std::vector<unsigned> candidates(intervalCount + 1);
|
||||
std::vector<Fluxmap::Position> positions(intervalCount + 1);
|
||||
|
||||
for (unsigned i=0; i<=intervalCount; i++)
|
||||
for (unsigned i = 0; i <= intervalCount; i++)
|
||||
{
|
||||
positions[i] = tell();
|
||||
candidates[i] = 0;
|
||||
@@ -242,22 +242,21 @@ nanoseconds_t FluxmapReader::seekToPattern(const FluxMatcher& pattern, const Flu
|
||||
FluxMatch match;
|
||||
if (pattern.matches(&*candidates.end(), match))
|
||||
{
|
||||
seek(positions[intervalCount-match.intervals]);
|
||||
seek(positions[intervalCount - match.intervals]);
|
||||
_pos.zeroes = match.zeroes;
|
||||
matching = match.matcher;
|
||||
nanoseconds_t detectedClock = match.clock * NS_PER_TICK;
|
||||
if (detectedClock > (_config.minimum_clock_us()*1000))
|
||||
if (detectedClock > (_config.minimum_clock_us() * 1000))
|
||||
return match.clock * NS_PER_TICK;
|
||||
}
|
||||
|
||||
for (unsigned i=0; i<intervalCount; i++)
|
||||
for (unsigned i = 0; i < intervalCount; i++)
|
||||
{
|
||||
positions[i] = positions[i+1];
|
||||
candidates[i] = candidates[i+1];
|
||||
positions[i] = positions[i + 1];
|
||||
candidates[i] = candidates[i + 1];
|
||||
}
|
||||
findEvent(F_BIT_PULSE, candidates[intervalCount]);
|
||||
findEvent(F_BIT_PULSE, candidates[intervalCount]);
|
||||
positions[intervalCount] = tell();
|
||||
|
||||
}
|
||||
|
||||
matching = NULL;
|
||||
@@ -269,4 +268,3 @@ void FluxmapReader::seekToIndexMark()
|
||||
skipToEvent(F_BIT_INDEX);
|
||||
_pos.zeroes = 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,20 +2,20 @@
|
||||
#include "decoders/decoders.h"
|
||||
|
||||
Bytes decodeFmMfm(
|
||||
std::vector<bool>::const_iterator ii, std::vector<bool>::const_iterator end)
|
||||
std::vector<bool>::const_iterator ii, std::vector<bool>::const_iterator end)
|
||||
{
|
||||
/*
|
||||
* FM is dumb as rocks, consisting on regular clock pulses with data pulses in
|
||||
* the gaps. 0x00 is:
|
||||
*
|
||||
/*
|
||||
* FM is dumb as rocks, consisting on regular clock pulses with data pulses
|
||||
* in the gaps. 0x00 is:
|
||||
*
|
||||
* X-X-X-X-X-X-X-X-
|
||||
*
|
||||
*
|
||||
* 0xff is:
|
||||
*
|
||||
*
|
||||
* XXXXXXXXXXXXXXXX
|
||||
*
|
||||
* So we just need to extract all the odd bits.
|
||||
*
|
||||
*
|
||||
* MFM and M2FM are slightly more complicated, where the first bit of each
|
||||
* pair can be either 0 or 1... but the second bit is always the data bit,
|
||||
* and at this point we simply don't care what the first bit is, so
|
||||
@@ -33,7 +33,7 @@ Bytes decodeFmMfm(
|
||||
ii++; /* skip clock bit */
|
||||
if (ii == end)
|
||||
break;
|
||||
fifo = (fifo<<1) | *ii++;
|
||||
fifo = (fifo << 1) | *ii++;
|
||||
|
||||
bitcount++;
|
||||
if (bitcount == 8)
|
||||
@@ -45,7 +45,7 @@ Bytes decodeFmMfm(
|
||||
|
||||
if (bitcount != 0)
|
||||
{
|
||||
fifo <<= 8-bitcount;
|
||||
fifo <<= 8 - bitcount;
|
||||
bw.write_8(fifo);
|
||||
}
|
||||
|
||||
@@ -54,42 +54,45 @@ Bytes decodeFmMfm(
|
||||
|
||||
void encodeFm(std::vector<bool>& bits, unsigned& cursor, const Bytes& input)
|
||||
{
|
||||
if (bits.size() == 0)
|
||||
return;
|
||||
unsigned len = bits.size()-1;
|
||||
if (bits.size() == 0)
|
||||
return;
|
||||
unsigned len = bits.size() - 1;
|
||||
|
||||
for (uint8_t b : input)
|
||||
{
|
||||
for (int i=0; i<8; i++)
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
bool bit = b & 0x80;
|
||||
b <<= 1;
|
||||
|
||||
if (cursor >= len)
|
||||
return;
|
||||
|
||||
|
||||
bits[cursor++] = true;
|
||||
bits[cursor++] = bit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void encodeMfm(std::vector<bool>& bits, unsigned& cursor, const Bytes& input, bool& lastBit)
|
||||
void encodeMfm(std::vector<bool>& bits,
|
||||
unsigned& cursor,
|
||||
const Bytes& input,
|
||||
bool& lastBit)
|
||||
{
|
||||
if (bits.size() == 0)
|
||||
return;
|
||||
unsigned len = bits.size()-1;
|
||||
if (bits.size() == 0)
|
||||
return;
|
||||
unsigned len = bits.size() - 1;
|
||||
|
||||
for (uint8_t b : input)
|
||||
{
|
||||
for (int i=0; i<8; i++)
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
bool bit = b & 0x80;
|
||||
b <<= 1;
|
||||
|
||||
if (cursor >= len)
|
||||
return;
|
||||
|
||||
|
||||
bits[cursor++] = !lastBit && !bit;
|
||||
bits[cursor++] = bit;
|
||||
lastBit = bit;
|
||||
@@ -99,22 +102,21 @@ void encodeMfm(std::vector<bool>& bits, unsigned& cursor, const Bytes& input, bo
|
||||
|
||||
Bytes encodeMfm(const Bytes& input, bool& lastBit)
|
||||
{
|
||||
ByteReader br(input);
|
||||
BitReader bitr(br);
|
||||
Bytes b;
|
||||
ByteWriter bw(b);
|
||||
BitWriter bitw(bw);
|
||||
ByteReader br(input);
|
||||
BitReader bitr(br);
|
||||
Bytes b;
|
||||
ByteWriter bw(b);
|
||||
BitWriter bitw(bw);
|
||||
|
||||
while (!bitr.eof())
|
||||
{
|
||||
uint8_t bit = bitr.get();
|
||||
|
||||
bitw.push(!lastBit && !bit);
|
||||
bitw.push(bit);
|
||||
lastBit = bit;
|
||||
while (!bitr.eof())
|
||||
{
|
||||
uint8_t bit = bitr.get();
|
||||
|
||||
bitw.push(!lastBit && !bit);
|
||||
bitw.push(bit);
|
||||
lastBit = bit;
|
||||
}
|
||||
|
||||
bitw.flush();
|
||||
return b;
|
||||
bitw.flush();
|
||||
return b;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user