| 
									
										
										
										
											2022-06-10 17:54:18 +02:00
										 |  |  | ///////////////////////////////////////////////////////////////////////////////////
 | 
					
						
							|  |  |  | // 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 <http://www.gnu.org/licenses/>.          //
 | 
					
						
							|  |  |  | ///////////////////////////////////////////////////////////////////////////////////
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifndef INCLUDE_M17MODPROCESSOR_H
 | 
					
						
							|  |  |  | #define INCLUDE_M17MODPROCESSOR_H
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <QObject>
 | 
					
						
							|  |  |  | #include <QByteArray>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-20 05:47:48 +02:00
										 |  |  | #include "M17Modulator.h"
 | 
					
						
							| 
									
										
										
										
											2022-06-29 08:45:44 +02:00
										 |  |  | #include "dsp/dsptypes.h"
 | 
					
						
							| 
									
										
										
										
											2022-06-10 17:54:18 +02:00
										 |  |  | #include "util/message.h"
 | 
					
						
							|  |  |  | #include "util/messagequeue.h"
 | 
					
						
							| 
									
										
										
										
											2022-06-18 06:15:54 +02:00
										 |  |  | #include "m17modfifo.h"
 | 
					
						
							| 
									
										
										
										
											2022-06-29 08:45:44 +02:00
										 |  |  | #include "m17moddecimator.h"
 | 
					
						
							| 
									
										
										
										
											2022-06-10 17:54:18 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | class M17ModProcessor : public QObject | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     Q_OBJECT | 
					
						
							|  |  |  | public: | 
					
						
							| 
									
										
										
										
											2022-06-12 22:51:18 +02:00
										 |  |  |     class MsgSendSMS : public Message { | 
					
						
							| 
									
										
										
										
											2022-06-10 17:54:18 +02:00
										 |  |  |         MESSAGE_CLASS_DECLARATION | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     public: | 
					
						
							| 
									
										
										
										
											2022-06-12 22:51:18 +02:00
										 |  |  |         const QString& getSourceCall() const { return m_sourceCall; } | 
					
						
							|  |  |  |         const QString& getDestCall() const { return m_destCall; } | 
					
						
							| 
									
										
										
										
											2022-06-30 00:17:31 +02:00
										 |  |  |         uint8_t getCAN() const { return m_can; } | 
					
						
							| 
									
										
										
										
											2022-06-12 22:51:18 +02:00
										 |  |  |         const QString& getSMSText() const { return m_smsText; } | 
					
						
							| 
									
										
										
										
											2022-06-10 17:54:18 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-30 00:17:31 +02:00
										 |  |  |         static MsgSendSMS* create(const QString& sourceCall, const QString& destCall, uint8_t can, const QString& smsText) { | 
					
						
							|  |  |  |             return new MsgSendSMS(sourceCall, destCall, can, smsText); | 
					
						
							| 
									
										
										
										
											2022-06-10 17:54:18 +02:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     private: | 
					
						
							| 
									
										
										
										
											2022-06-12 22:51:18 +02:00
										 |  |  |         QString m_sourceCall; | 
					
						
							|  |  |  |         QString m_destCall; | 
					
						
							| 
									
										
										
										
											2022-06-30 00:17:31 +02:00
										 |  |  |         uint8_t m_can; | 
					
						
							| 
									
										
										
										
											2022-06-12 22:51:18 +02:00
										 |  |  |         QString m_smsText; | 
					
						
							| 
									
										
										
										
											2022-06-10 17:54:18 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-30 00:17:31 +02:00
										 |  |  |         MsgSendSMS(const QString& sourceCall, const QString& destCall, uint8_t can, const QString& smsText) : | 
					
						
							| 
									
										
										
										
											2022-06-10 17:54:18 +02:00
										 |  |  |             Message(), | 
					
						
							| 
									
										
										
										
											2022-06-12 22:51:18 +02:00
										 |  |  |             m_sourceCall(sourceCall), | 
					
						
							|  |  |  |             m_destCall(destCall), | 
					
						
							| 
									
										
										
										
											2022-06-30 00:17:31 +02:00
										 |  |  |             m_can(can), | 
					
						
							| 
									
										
										
										
											2022-06-12 22:51:18 +02:00
										 |  |  |             m_smsText(smsText) | 
					
						
							| 
									
										
										
										
											2022-06-10 17:54:18 +02:00
										 |  |  |         { } | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-03 10:06:12 +02:00
										 |  |  |     class MsgSendAPRS : public Message { | 
					
						
							|  |  |  |         MESSAGE_CLASS_DECLARATION | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     public: | 
					
						
							|  |  |  |         const QString& getSourceCall() const { return m_sourceCall; } | 
					
						
							|  |  |  |         const QString& getDestCall() const { return m_destCall; } | 
					
						
							|  |  |  |         uint8_t getCAN() const { return m_can; } | 
					
						
							|  |  |  |         const QString& getCall() const { return m_call; } | 
					
						
							|  |  |  |         const QString& getTo() const { return m_to; } | 
					
						
							|  |  |  |         const QString& getVia() const { return m_via; } | 
					
						
							|  |  |  |         const QString& getData() const { return m_data; } | 
					
						
							|  |  |  |         bool getInsertPosition() const { return m_insertPosition; } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         static MsgSendAPRS* create( | 
					
						
							|  |  |  |             const QString& sourceCall, | 
					
						
							|  |  |  |             const QString& destCall, | 
					
						
							|  |  |  |             uint8_t can, | 
					
						
							|  |  |  |             const QString& call, | 
					
						
							|  |  |  |             const QString& to, | 
					
						
							|  |  |  |             const QString& via, | 
					
						
							|  |  |  |             const QString& data, | 
					
						
							|  |  |  |             bool insertPosition | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             return new MsgSendAPRS(sourceCall, destCall, can, call, to, via, data, insertPosition); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     private: | 
					
						
							|  |  |  |         QString m_sourceCall; | 
					
						
							|  |  |  |         QString m_destCall; | 
					
						
							|  |  |  |         uint8_t m_can; | 
					
						
							|  |  |  |         QString m_call; | 
					
						
							|  |  |  |         QString m_to; | 
					
						
							|  |  |  |         QString m_via; | 
					
						
							|  |  |  |         QString m_data; | 
					
						
							|  |  |  |         bool m_insertPosition; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         MsgSendAPRS( | 
					
						
							|  |  |  |             const QString& sourceCall, | 
					
						
							|  |  |  |             const QString& destCall, | 
					
						
							|  |  |  |             uint8_t can, | 
					
						
							|  |  |  |             const QString& call, | 
					
						
							|  |  |  |             const QString& to, | 
					
						
							|  |  |  |             const QString& via, | 
					
						
							|  |  |  |             const QString& data, | 
					
						
							|  |  |  |             bool insertPosition | 
					
						
							|  |  |  |         ) : | 
					
						
							|  |  |  |             Message(), | 
					
						
							|  |  |  |             m_sourceCall(sourceCall), | 
					
						
							|  |  |  |             m_destCall(destCall), | 
					
						
							|  |  |  |             m_can(can), | 
					
						
							|  |  |  |             m_call(call), | 
					
						
							|  |  |  |             m_to(to), | 
					
						
							|  |  |  |             m_via(via), | 
					
						
							|  |  |  |             m_data(data), | 
					
						
							|  |  |  |             m_insertPosition(insertPosition) | 
					
						
							|  |  |  |         { } | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-29 08:45:44 +02:00
										 |  |  |     class MsgSendAudioFrame : public Message { | 
					
						
							|  |  |  |         MESSAGE_CLASS_DECLARATION | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     public: | 
					
						
							|  |  |  |         const QString& getSourceCall() const { return m_sourceCall; } | 
					
						
							|  |  |  |         const QString& getDestCall() const { return m_destCall; } | 
					
						
							|  |  |  |         std::array<int16_t, 1920>& getAudioFrame() { return m_audioFrame; } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         static MsgSendAudioFrame* create(const QString& sourceCall, const QString& destCall) { | 
					
						
							|  |  |  |             return new MsgSendAudioFrame(sourceCall, destCall); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     private: | 
					
						
							|  |  |  |         QString m_sourceCall; | 
					
						
							|  |  |  |         QString m_destCall; | 
					
						
							|  |  |  |         std::array<int16_t, 1920> m_audioFrame; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         MsgSendAudioFrame(const QString& sourceCall, const QString& destCall) : | 
					
						
							|  |  |  |             Message(), | 
					
						
							|  |  |  |             m_sourceCall(sourceCall), | 
					
						
							|  |  |  |             m_destCall(destCall) | 
					
						
							|  |  |  |         { } | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     class MsgStartAudio : public Message { | 
					
						
							|  |  |  |         MESSAGE_CLASS_DECLARATION | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     public: | 
					
						
							|  |  |  |         const QString& getSourceCall() const { return m_sourceCall; } | 
					
						
							|  |  |  |         const QString& getDestCall() const { return m_destCall; } | 
					
						
							| 
									
										
										
										
											2022-06-30 00:17:31 +02:00
										 |  |  |         uint8_t getCAN() const { return m_can; } | 
					
						
							| 
									
										
										
										
											2022-06-29 08:45:44 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-30 00:17:31 +02:00
										 |  |  |         static MsgStartAudio* create(const QString& sourceCall, const QString& destCall, uint8_t can) { | 
					
						
							|  |  |  |             return new MsgStartAudio(sourceCall, destCall, can); | 
					
						
							| 
									
										
										
										
											2022-06-29 08:45:44 +02:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     private: | 
					
						
							|  |  |  |         QString m_sourceCall; | 
					
						
							|  |  |  |         QString m_destCall; | 
					
						
							| 
									
										
										
										
											2022-06-30 00:17:31 +02:00
										 |  |  |         uint8_t m_can; | 
					
						
							| 
									
										
										
										
											2022-06-29 08:45:44 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-30 00:17:31 +02:00
										 |  |  |         MsgStartAudio(const QString& sourceCall, const QString& destCall, uint8_t can) : | 
					
						
							| 
									
										
										
										
											2022-06-29 08:45:44 +02:00
										 |  |  |             Message(), | 
					
						
							|  |  |  |             m_sourceCall(sourceCall), | 
					
						
							| 
									
										
										
										
											2022-06-30 00:17:31 +02:00
										 |  |  |             m_destCall(destCall), | 
					
						
							|  |  |  |             m_can(can) | 
					
						
							| 
									
										
										
										
											2022-06-29 08:45:44 +02:00
										 |  |  |         { } | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     class MsgStopAudio : public Message { | 
					
						
							|  |  |  |         MESSAGE_CLASS_DECLARATION | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     public: | 
					
						
							|  |  |  |         static MsgStopAudio* create() { | 
					
						
							|  |  |  |             return new MsgStopAudio(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     private: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         MsgStopAudio() : | 
					
						
							|  |  |  |             Message() | 
					
						
							|  |  |  |         { } | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-04 22:45:16 +02:00
										 |  |  |     class MsgStartBERT : public Message { | 
					
						
							|  |  |  |         MESSAGE_CLASS_DECLARATION | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     public: | 
					
						
							|  |  |  |         static MsgStartBERT* create() { | 
					
						
							|  |  |  |             return new MsgStartBERT(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     private: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         MsgStartBERT() : | 
					
						
							|  |  |  |             Message() | 
					
						
							|  |  |  |         { } | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     class MsgSendBERTFrame : public Message { | 
					
						
							|  |  |  |         MESSAGE_CLASS_DECLARATION | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     public: | 
					
						
							|  |  |  |         static MsgSendBERTFrame* create() { | 
					
						
							|  |  |  |             return new MsgSendBERTFrame(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     private: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         MsgSendBERTFrame() : | 
					
						
							|  |  |  |             Message() | 
					
						
							|  |  |  |         { } | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     class MsgStopBERT : public Message { | 
					
						
							|  |  |  |         MESSAGE_CLASS_DECLARATION | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     public: | 
					
						
							|  |  |  |         static MsgStopBERT* create() { | 
					
						
							|  |  |  |             return new MsgStopBERT(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     private: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         MsgStopBERT() : | 
					
						
							|  |  |  |             Message() | 
					
						
							|  |  |  |         { } | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-16 03:48:33 +02:00
										 |  |  |     class MsgSetGNSS : public Message { | 
					
						
							|  |  |  |         MESSAGE_CLASS_DECLARATION | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     public: | 
					
						
							|  |  |  |         float getLat() const { return m_lat; } | 
					
						
							|  |  |  |         float getLon() const { return m_lon; } | 
					
						
							|  |  |  |         float getAlt() const { return m_alt; } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         static MsgSetGNSS* create(float lat, float lon, float alt) { | 
					
						
							|  |  |  |             return new MsgSetGNSS(lat, lon, alt); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     private: | 
					
						
							|  |  |  |         float m_lat; | 
					
						
							|  |  |  |         float m_lon; | 
					
						
							|  |  |  |         float m_alt; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         MsgSetGNSS(float lat, float lon, float alt) : | 
					
						
							|  |  |  |             Message(), | 
					
						
							|  |  |  |             m_lat(lat), | 
					
						
							|  |  |  |             m_lon(lon), | 
					
						
							|  |  |  |             m_alt(alt) | 
					
						
							|  |  |  |         { } | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     class MsgStopGNSS : public Message { | 
					
						
							|  |  |  |         MESSAGE_CLASS_DECLARATION | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     public: | 
					
						
							|  |  |  |         static MsgStopGNSS* create() { | 
					
						
							|  |  |  |             return new MsgStopGNSS(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     private: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         MsgStopGNSS() : | 
					
						
							|  |  |  |             Message() | 
					
						
							|  |  |  |         { } | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-10 17:54:18 +02:00
										 |  |  |     M17ModProcessor(); | 
					
						
							|  |  |  |     ~M17ModProcessor(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     MessageQueue *getInputMessageQueue() { return &m_inputMessageQueue; } | 
					
						
							| 
									
										
										
										
											2022-06-18 06:15:54 +02:00
										 |  |  |     M17ModFIFO *getBasebandFifo() { return &m_basebandFifo; } | 
					
						
							| 
									
										
										
										
											2022-06-10 17:54:18 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | private: | 
					
						
							|  |  |  |     MessageQueue m_inputMessageQueue; | 
					
						
							| 
									
										
										
										
											2022-06-18 06:15:54 +02:00
										 |  |  |     M17ModFIFO m_basebandFifo; //!< Samples are 16 bit integer baseband 48 kS/s samples
 | 
					
						
							| 
									
										
										
										
											2022-06-29 08:45:44 +02:00
										 |  |  |     int m_basebandFifoHigh; | 
					
						
							|  |  |  |     int m_basebandFifoLow; | 
					
						
							|  |  |  |     M17ModDecimator m_decimator; //!< 48k -> 8k decimator
 | 
					
						
							| 
									
										
										
										
											2022-07-04 23:03:07 +02:00
										 |  |  |     modemm17::M17Modulator m_m17Modulator; | 
					
						
							|  |  |  |     std::array<modemm17::M17Modulator::lich_segment_t, 6> m_lich; //!< LICH bits
 | 
					
						
							| 
									
										
										
										
											2022-06-29 08:45:44 +02:00
										 |  |  |     int m_lichSegmentIndex; | 
					
						
							|  |  |  |     std::array<int16_t, 320*6> m_audioFrame; | 
					
						
							|  |  |  |     int m_audioFrameIndex; | 
					
						
							|  |  |  |     uint16_t m_audioFrameNumber; | 
					
						
							|  |  |  |     struct CODEC2 *m_codec2; | 
					
						
							| 
									
										
										
										
											2022-07-04 23:03:07 +02:00
										 |  |  |     modemm17::PRBS9 m_prbs; | 
					
						
							| 
									
										
										
										
											2022-07-03 21:55:16 +02:00
										 |  |  |     bool m_insertPositionToggle; | 
					
						
							| 
									
										
										
										
											2022-06-10 17:54:18 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     bool handleMessage(const Message& cmd); | 
					
						
							| 
									
										
										
										
											2022-06-30 00:17:31 +02:00
										 |  |  |     void processPacket(const QString& sourceCall, const QString& destCall, uint8_t can, const QByteArray& packetBytes); | 
					
						
							|  |  |  |     void audioStart(const QString& sourceCall, const QString& destCall, uint8_t can); | 
					
						
							| 
									
										
										
										
											2022-06-29 08:45:44 +02:00
										 |  |  |     void audioStop(); | 
					
						
							|  |  |  |     void processAudioFrame(); | 
					
						
							|  |  |  |     std::array<uint8_t, 16> encodeAudio(std::array<int16_t, 320*6>& audioFrame); | 
					
						
							| 
									
										
										
										
											2022-07-04 22:45:16 +02:00
										 |  |  |     void processBERTFrame(); | 
					
						
							| 
									
										
										
										
											2022-06-17 02:25:34 +02:00
										 |  |  |     void test(const QString& sourceCall, const QString& destCall); | 
					
						
							|  |  |  |     void send_preamble(); | 
					
						
							|  |  |  |     void send_eot(); | 
					
						
							|  |  |  |     void output_baseband(std::array<uint8_t, 2> sync_word, const std::array<int8_t, 368>& frame); | 
					
						
							| 
									
										
										
										
											2022-07-03 10:06:12 +02:00
										 |  |  |     QString formatAPRSPosition(); | 
					
						
							| 
									
										
										
										
											2022-06-10 17:54:18 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | private slots: | 
					
						
							|  |  |  |     void handleInputMessages(); | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif // INCLUDE_M17MODPROCESSOR_H
 |