/////////////////////////////////////////////////////////////////////////////////// // Copyright (C) 2022 Edouard Griffiths, F4EXB // // // // This program is free software; you can redistribute it and/or modify // // it under the terms of the GNU General Public License as published by // // the Free Software Foundation as version 3 of the License, or // // (at your option) any later version. // // // // This program is distributed in the hope that it will be useful, // // but WITHOUT ANY WARRANTY; without even the implied warranty of // // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // // GNU General Public License V3 for more details. // // // // You should have received a copy of the GNU General Public License // // along with this program. If not, see . // /////////////////////////////////////////////////////////////////////////////////// #ifndef INCLUDE_M17DEMODPROCESSOR_H #define INCLUDE_M17DEMODPROCESSOR_H #include #include "audio/audiocompressor.h" #include "M17Demodulator.h" #include "m17demodfilters.h" class AudioFifo; class MessageQueue; class M17DemodProcessor : public QObject { Q_OBJECT public: enum StdPacketProtocol { StdPacketRaw, StdPacketAX25, StdPacketAPRS, StdPacket6LoWPAN, StdPacketIPv4, StdPacketSMS, StdPacketWinlink, StdPacketUnknown }; M17DemodProcessor(); ~M17DemodProcessor(); void setDemodInputMessageQueue(MessageQueue *messageQueue) { m_demodInputMessageQueue = messageQueue; } void pushSample(qint16 sample); void setDisplayLSF(bool displayLSF) { m_displayLSF = displayLSF; } void setNoiseBlanker(bool noiseBlanker) { m_noiseBlanker = noiseBlanker; } void setAudioFifo(AudioFifo *fifo) { m_audioFifo = fifo; } void setAudioMute(bool mute) { m_audioMute = mute; } void setUpsampling(int upsampling); void setVolume(float volume); void setHP(bool useHP) { m_upsamplingFilter.useHP(useHP); } void resetInfo(); void setDCDOff(); uint32_t getLSFCount() const { return m_lsfCount; } const QString& getSrcCall() const { return m_srcCall; } const QString& getDestcCall() const { return m_destCall; } const QString& getTypeInfo() const { return m_typeInfo; } const std::array& getMeta() const { return m_metadata; } bool getHasGNSS() const { return m_hasGNSS; } bool getStreamElsePacket() const { return m_streamElsePacket; } uint16_t getCRC() const { return m_crc; } StdPacketProtocol getStdPacketProtocol() const; void getDiagnostics( bool& dcd, float& evm, float& deviation, float& offset, int& status, int& sync_word_type, float& clock, int& sampleIndex, int& syncIndex, int& clockIndex, int& viterbiCost ) const { dcd = m_dcd; evm = m_evm; deviation = m_deviation; offset = m_offset; status = m_status; sync_word_type = m_syncWordType; clock = m_clock; sampleIndex = m_sampleIndex; syncIndex = m_syncIndex; clockIndex = m_clockIndex; viterbiCost = m_viterbiCost; } void getBERT(uint32_t& bertErrors, uint32_t& bertBits) { bertErrors = m_prbs.errors(); bertBits = m_prbs.bits(); } void resetPRBS() { m_prbs.reset(); } private: std::vector m_currentPacket; size_t m_packetFrameCounter; modemm17::PRBS9 m_prbs; bool m_displayLSF; bool m_noiseBlanker; struct CODEC2 *m_codec2; static M17DemodProcessor *m_this; modemm17::M17Demodulator m_demod; AudioFifo *m_audioFifo; bool m_audioMute; AudioVector m_audioBuffer; uint m_audioBufferFill; float m_volume; int m_upsampling; //!< upsampling factor float m_upsamplingFactors[7]; AudioCompressor m_compressor; float m_upsamplerLastValue; M17DemodAudioInterpolatorFilter m_upsamplingFilter; // Diagnostics bool m_dcd; //!< Data Carrier Detect float m_evm; //!< Error Vector Magnitude in percent float m_deviation; //!< Estimated deviation. Ideal = 1.0 float m_offset; //!< Estimated frequency offset. Ideal = 0.0 practically limited to ~[-0.18, 0.18] int m_status; //!< Status int m_syncWordType; //!< Sync word type float m_clock; int m_sampleIndex; int m_syncIndex; int m_clockIndex; int m_viterbiCost; //!< [-1:128] ideally 0 QString m_srcCall; QString m_destCall; QString m_typeInfo; bool m_streamElsePacket; std::array m_metadata; bool m_hasGNSS; uint16_t m_crc; uint32_t m_lsfCount; // Incremented each time a new LSF is decoded. Reset when lock is lost. StdPacketProtocol m_stdPacketProtocol; MessageQueue *m_demodInputMessageQueue; static bool handle_frame(modemm17::M17FrameDecoder::output_buffer_t const& frame, int viterbi_cost); static void diagnostic_callback( bool dcd, float evm, float deviation, float offset, int status, int sync_word_type, float clock, int sample_index, int sync_index, int clock_index, int viterbi_cost ); bool decode_lsf(modemm17::M17FrameDecoder::lsf_buffer_t const& lsf); bool decode_lich(modemm17::M17FrameDecoder::lich_buffer_t const& lich); bool decode_packet(modemm17::M17FrameDecoder::packet_buffer_t const& packet_segment); bool decode_bert(modemm17::M17FrameDecoder::bert_buffer_t const& bert); bool demodulate_audio(modemm17::M17FrameDecoder::audio_buffer_t const& audio, int viterbi_cost); void decode_type(uint16_t type); void append_packet(std::vector& result, modemm17::M17FrameDecoder::lsf_buffer_t in); void processAudio(const std::array& in); void upsample(int upsampling, const int16_t *in, int nbSamplesIn); void noUpsample(const int16_t *in, int nbSamplesIn); void setVolumeFactors(); }; #endif // INCLUDE_M17PROCESSOR_H