Files
fluxengine/lib/decoders/fluxmapreader.cc
2024-10-02 00:42:06 +02:00

169 lines
3.8 KiB
C++

#include "lib/core/globals.h"
#include "lib/config.h"
#include "lib/fluxmap.h"
#include "lib/decoders/fluxmapreader.h"
#include "lib/decoders/fluxpattern.h"
#include "lib/proto.h"
#include "protocol.h"
#include <numeric>
#include <math.h>
#include <strings.h>
FluxmapReader::FluxmapReader(const Fluxmap& fluxmap):
_fluxmap(fluxmap),
_bytes(fluxmap.ptr()),
_size(fluxmap.bytes()),
_config(globalConfig()->decoder())
{
rewind();
}
void FluxmapReader::getNextEvent(int& event, unsigned& ticks)
{
ticks = 0;
while (!eof())
{
uint8_t b = _bytes[_pos.bytes++];
ticks += b & 0x3f;
if (!b || (b & (F_BIT_PULSE | F_BIT_INDEX)))
{
_pos.ticks += ticks;
event = b & 0xc0;
return;
}
}
_pos.ticks += ticks;
event = F_EOF;
}
void FluxmapReader::skipToEvent(int event)
{
unsigned ticks;
findEvent(event, ticks);
}
bool FluxmapReader::findEvent(int event, unsigned& ticks)
{
ticks = 0;
while (!eof())
{
unsigned thisTicks;
int thisEvent;
getNextEvent(thisEvent, thisTicks);
ticks += thisTicks;
if (thisEvent == F_EOF)
return false;
if ((event == thisEvent) || (event & thisEvent))
return true;
}
return false;
}
unsigned FluxmapReader::readInterval(nanoseconds_t clock)
{
unsigned thresholdTicks =
(clock * _config.pulse_debounce_threshold()) / NS_PER_TICK;
unsigned ticks = 0;
while (ticks <= thresholdTicks)
{
unsigned thisTicks;
if (!findEvent(F_BIT_PULSE, thisTicks))
break;
ticks += thisTicks;
}
return ticks;
}
void FluxmapReader::seek(nanoseconds_t ns)
{
unsigned ticks = ns / NS_PER_TICK;
if (ticks < _pos.ticks)
{
_pos.ticks = 0;
_pos.bytes = 0;
}
while (!eof() && (_pos.ticks < ticks))
{
int e;
unsigned t;
getNextEvent(e, t);
}
_pos.zeroes = 0;
}
void FluxmapReader::seekToByte(unsigned b)
{
if (b < _pos.bytes)
{
_pos.ticks = 0;
_pos.bytes = 0;
}
while (!eof() && (_pos.bytes < b))
{
int e;
unsigned t;
getNextEvent(e, t);
}
_pos.zeroes = 0;
}
nanoseconds_t FluxmapReader::seekToPattern(const FluxMatcher& pattern)
{
const FluxMatcher* unused;
return seekToPattern(pattern, unused);
}
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);
for (unsigned i = 0; i <= intervalCount; i++)
{
positions[i] = tell();
candidates[i] = 0;
}
while (!eof())
{
FluxMatch match;
if (pattern.matches(&*candidates.end(), match))
{
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))
return match.clock * NS_PER_TICK;
}
for (unsigned i = 0; i < intervalCount; i++)
{
positions[i] = positions[i + 1];
candidates[i] = candidates[i + 1];
}
findEvent(F_BIT_PULSE, candidates[intervalCount]);
positions[intervalCount] = tell();
}
matching = NULL;
return 0;
}
void FluxmapReader::seekToIndexMark()
{
skipToEvent(F_BIT_INDEX);
_pos.zeroes = 0;
}