// // Created by bruno on 13. 7. 2026. // #ifndef AUDIOCODER_DECODER_H #define AUDIOCODER_DECODER_H #define MAX_BITS 16 #define PREAMBLE_SYMBOLS 128 #define DECODER_SAMPLE_HISTORY 262144 #include #include #include #include "goertzel.h" typedef enum { RX_SEARCH, RX_ALIGN, RX_SYNC, RX_LOCKED } RxState; typedef struct { uint8_t bitCount; uint16_t startFreq; uint16_t endFreq; uint16_t dataSpacing; uint16_t clock0; uint16_t clock1; uint32_t symbolSamples; uint32_t sampleCount; float sampleHistory[DECODER_SAMPLE_HISTORY]; uint32_t sampleHistoryWrite; uint32_t sampleHistoryCount; uint64_t totalSamples; Goertzel tones[MAX_BITS * 2 + 2]; uint8_t currentByte; uint8_t bitIndex; uint8_t buffer[1024*1024*8]; uint32_t bufferSize; bool lastClock; float energies[MAX_BITS * 2 + 2]; float maxEnergy; float clockEnergy0; float clockEnergy1; float clockRatio; uint8_t lastDecodedByte; int bestSyncScore; int bestSyncPhase; RxState rxState; bool expectedClock; float lastClockEnergy; uint32_t goodClocks; uint32_t syncIndex; uint32_t badClocks; uint64_t phaseSearchStart; uint32_t phaseWait; int phaseOffset; bool phaseSearchReady; uint32_t searchOffset; uint32_t syncOffset; uint8_t clockHistory; uint8_t clockCount; bool locked; SDL_Renderer *renderer; } Decoder; void decoder_init( Decoder *dec ); void decoder_process( Decoder *dec, float *samples, uint32_t count ); void decoder_rebuild_tones( Decoder *dec ); extern Decoder decoder; extern SDL_AudioDeviceID inputDev; extern const uint8_t syncBytes[4]; // Internal audio bus for loopback #define INTERNAL_BUFFER_SIZE 262144 extern float internalBusSamples[INTERNAL_BUFFER_SIZE]; extern volatile uint32_t internalBusWrite; extern volatile uint32_t internalBusRead; void initAudioDecoder(SDL_Renderer *renderer); #endif //AUDIOCODER_DECODER_H