libpromeki 1.0.0-alpha
PROfessional MEdia toolKIt
 
Loading...
Searching...
No Matches
audiodatadecoder.h
Go to the documentation of this file.
1
8#pragma once
9
10
11#include <promeki/config.h>
12#if PROMEKI_ENABLE_PROAV
13#include <cstdint>
14#include <cstddef>
15#include <promeki/namespace.h>
16#include <promeki/list.h>
17#include <promeki/error.h>
18#include <promeki/audiodesc.h>
20
21PROMEKI_NAMESPACE_BEGIN
22
23class PcmAudioPayload;
24
85class AudioDataDecoder {
86 public:
88 static constexpr uint32_t BitsPerPacket = AudioDataEncoder::BitsPerPacket;
90 static constexpr uint32_t SyncBits = AudioDataEncoder::SyncBits;
92 static constexpr uint32_t PayloadBits = AudioDataEncoder::PayloadBits;
94 static constexpr uint32_t CrcBits = AudioDataEncoder::CrcBits;
96 static constexpr uint8_t SyncNibble = AudioDataEncoder::SyncNibble;
97
102 struct Band {
104 uint64_t firstSample = 0;
106 uint64_t sampleCount = 0;
108 uint32_t channel = 0;
109 };
110
121 struct DecodedItem {
123 Error error = Error::Ok;
125 uint8_t decodedSync = 0;
127 uint8_t decodedCrc = 0;
129 uint8_t expectedCrc = 0;
131 uint64_t payload = 0;
133 double samplesPerBit = 0.0;
137 uint64_t syncStartSample = 0;
149 int64_t streamSampleStart = -1;
161 int64_t packetSampleCount = 0;
162 };
163
165 using DecodedList = List<DecodedItem>;
166
168 AudioDataDecoder() = default;
169
200 explicit AudioDataDecoder(const AudioDesc &desc,
201 uint32_t expectedSamplesPerBit = AudioDataEncoder::DefaultSamplesPerBit,
202 float expectedAmplitude = AudioDataEncoder::DefaultAmplitude);
203
205 bool isValid() const { return _valid; }
206
208 uint32_t expectedSamplesPerBit() const { return _expectedSamplesPerBit; }
209
211 float expectedAmplitude() const { return _expectedAmplitude; }
212
214 const AudioDesc &desc() const { return _desc; }
215
228 Error decode(const PcmAudioPayload &payload, const List<Band> &bands, DecodedList &out) const;
229
231 DecodedItem decode(const PcmAudioPayload &payload, const Band &band) const;
232
257 DecodedItem decode(const float *samples, size_t count) const;
258
276 struct StreamState {
281 List<float> buffer;
289 int64_t sampleAnchor = 0;
290 };
291
301 static constexpr size_t kStreamBufferMaxSamples = 8192;
302
352 void decodeAll(StreamState &state, const float *newSamples, size_t count, DecodedList &out) const;
353
354 private:
355 AudioDesc _desc;
356 uint32_t _expectedSamplesPerBit = 0;
357 uint32_t _samplesPerBitMin = 0;
358 uint32_t _samplesPerBitMax = 0;
359 float _expectedAmplitude = 0.0f;
364 float _positiveThreshold = 0.0f;
365 bool _valid = false;
366
367 DecodedItem decodeOne(const PcmAudioPayload &payload, const Band &band) const;
368 DecodedItem decodeSamples(const float *samples, size_t count) const;
369 // Shared bandwidth-check + demod helper. Given a
370 // pre-measured sync (@p syncStart sub-sample-accurate
371 // codeword leading edge, @p samplesPerBit measured
372 // pitch, @p syncStartSampleInt integer first-positive
373 // sample), runs the 76-bit integrate-and-compare
374 // demod across @p samples and verifies the sync
375 // nibble + CRC. Used by both the per-band decode
376 // path and the streaming decodeAll loop.
377 DecodedItem demodulate(const float *samples, size_t count, double syncStart, double samplesPerBit,
378 uint64_t syncStartSampleInt) const;
379};
380
381PROMEKI_NAMESPACE_END
382
383#endif // PROMEKI_ENABLE_PROAV