Arduino PulseWire Transceiver Library
Loading...
Searching...
No Matches
Codec.h
1#pragma once
2#include <assert.h>
3#include <stddef.h>
4#include <stdint.h>
5
6#include "pulse/Preamble.h"
7#include "pulse/SignalBase.h"
8#include "pulse/tools/Logger.h"
9#include "pulse/tools/Vector.h"
10
11namespace pulsewire {
12
14enum class CodecEnum {
15 PulseDistance,
16 PulseWidth,
17 Manchester,
18 DifferentialManchester,
19 NRZ,
20 RZ,
21 Miller
22};
23
24const char* toStr(CodecEnum codec) {
25 switch (codec) {
26 case CodecEnum::PulseDistance:
27 return "PulseDistance";
28 case CodecEnum::PulseWidth:
29 return "PulseWidth";
30 case CodecEnum::Manchester:
31 return "Manchester";
32 case CodecEnum::DifferentialManchester:
33 return "DifferentialManchester";
34 case CodecEnum::NRZ:
35 return "NRZ";
36 case CodecEnum::RZ:
37 return "RZ";
38 case CodecEnum::Miller:
39 return "Miller";
40 default:
41 return "Unknown";
42 }
43}
44
53class Codec {
54 friend class RecorderCodec;
55
56 public:
57 Codec() = default;
58
59 Codec(Preamble& preambleDetector) : _preamble(&preambleDetector) {}
60
63 virtual void init(Preamble& detector, uint32_t shortPulseUs = 600,
64 uint32_t longPulseUs = 1200, uint32_t toleranceUs = 200) {}
65
70 virtual bool begin(uint32_t bitFrequencyHz) {
71 TRACE();
72 assert(_preamble != nullptr);
73 _inFrame = false;
74 _bitFrequencyHz = bitFrequencyHz;
75 _bitPeriodUs = 1000000UL / bitFrequencyHz; // Bit period in microseconds
76 _preamble->begin(bitFrequencyHz);
77 _decodeEdgeStream.reserve(getEdgeCount());
78 return true;
79 }
80
84 virtual void reset() {
85 _decodeEdgeStream.clear(); // clear() keeps capacity, no realloc
86 _inFrame = false;
87 _preamble->reset();
88 }
94 void setPreamble(Preamble& preamble) { _preamble = &preamble; }
95
100 Preamble& getPreamble() { return *_preamble; }
101
107 virtual size_t getEdgeCount() const = 0;
108
114 void setFrameSize(uint16_t size) {
115 _frameSize = size;
116 _decodeEdgeStream.reserve(size * getEdgeCount());
117 }
118
120 uint16_t getFrameSize() const { return _frameSize; }
121
124 virtual int getEndOfFrameDelayUs() = 0;
125
127 virtual bool getIdleLevel() const { return false; }
128
131 virtual CodecEnum getCodecType() const = 0;
132
135 const char* name() const { return toStr(getCodecType()); }
136
151 virtual bool decodeEdge(uint32_t durationUs, bool level, uint8_t& result) = 0;
152
153 /***
154 * @brief Fill output vector with protocol-specific preamble for the
155 * preamble.
156 */
157 size_t encodePreamble(Vector<OutputEdge>& output) {
158 if (_preamble == nullptr) return 0;
159 return _preamble->getEdges(output);
160 }
161
173 virtual size_t encode(uint8_t byte, Vector<OutputEdge>& output) = 0;
174
185 virtual size_t flushEncoder(Vector<OutputEdge>& output) { return 0; }
186
187 protected:
188 CustomPreambleUs _defaultPreamble;
189 Preamble* _preamble = &_defaultPreamble;
190 uint16_t _bitFrequencyHz = 0;
191 uint32_t _bitPeriodUs = 0;
192 Vector<OutputEdge> _decodeEdgeStream;
193 volatile bool _inFrame = false;
194 uint16_t _frameSize = 0;
195
204 virtual void encodeByte(uint8_t byte, std::vector<bool>& bits) const {
205 for (int i = 7; i >= 0; --i) {
206 bool bit = (byte >> i) & 0x01;
207 bits[7 - i] = bit ? 1 : 0;
208 }
209 }
210};
211
212} // namespace pulsewire
Abstract base class for IR protocol encoding and decoding.
Definition Codec.h:53
virtual size_t encode(uint8_t byte, Vector< OutputEdge > &output)=0
Fill output vector with protocol-specific OutputSpec(s) for a byte.
virtual int getEndOfFrameDelayUs()=0
virtual bool decodeEdge(uint32_t durationUs, bool level, uint8_t &result)=0
Edge-based decoding for protocol-agnostic RX drivers.
virtual void init(Preamble &detector, uint32_t shortPulseUs=600, uint32_t longPulseUs=1200, uint32_t toleranceUs=200)
Definition Codec.h:63
void setPreamble(Preamble &preamble)
Set the Preamble Detector object.
Definition Codec.h:94
const char * name() const
Get the name of the codec type as a string (e.g., "PulseDistance", "Manchester").
Definition Codec.h:135
virtual bool getIdleLevel() const
Provides the initial ldle state (low or hith)
Definition Codec.h:127
virtual CodecEnum getCodecType() const =0
Preamble & getPreamble()
Get the preamble detector associated with this codec.
Definition Codec.h:100
uint16_t getFrameSize() const
Get the configured frame size.
Definition Codec.h:120
virtual size_t getEdgeCount() const =0
Get the number of protocol symbols (bits, pulses, etc.) per encoded byte.
virtual void encodeByte(uint8_t byte, std::vector< bool > &bits) const
Encode a byte to protocol bitstream. Default implementation encodes to raw bits (MSB first),...
Definition Codec.h:204
virtual size_t flushEncoder(Vector< OutputEdge > &output)
Flush any pending encoder state at end of frame.
Definition Codec.h:185
virtual bool begin(uint32_t bitFrequencyHz)
initialization method for codecs that require setup before use (e.g., loading PIO programs,...
Definition Codec.h:70
void setFrameSize(uint16_t size)
Set the Frame Size.
Definition Codec.h:114
virtual void reset()
Reset the internal state of the codec.
Definition Codec.h:84
CustomPreambleUs: Allows users to define their own preamble by setting expected edges....
Definition Preamble.h:127
Abstract base class for preamble detection and generation.
Definition Preamble.h:40
virtual int getEdges(pulsewire::Vector< pulsewire::OutputEdge > &output) const =0
Returns the expected preamble edges for this protocol.
Codec Wrapper that records all edges passed to decodeEdge() for later analysis or testing.
Small, header-only vector replacement for non-STL environments.
Definition Vector.h:29