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:
dg
2023-05-09 20:59:44 +00:00
parent bfa0846ad0
commit 466c3c34e5
168 changed files with 5722 additions and 5135 deletions

View File

@@ -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);
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}