/*************************************************************************** * Copyright (C) 2021 - 2023 by Federico Amedeo Izzo IU2NUO, * * Niccolò Izzo IU2KIN * * Frederik Saraci IU2NRO * * Silvano Seva IU2KWO * * * * 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; either 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 for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, see * ***************************************************************************/ #ifndef M17_MODULATOR_H #define M17_MODULATOR_H #ifndef __cplusplus #error This header is C++ only! #endif #include #include #include #include #include #include #include namespace M17 { /** * Modulator device for M17 protocol. */ class M17Modulator { public: /** * Constructor. */ M17Modulator(); /** * Destructor. */ ~M17Modulator(); /** * Allocate buffers for baseband audio generation and initialise modulator. */ void init(); /** * Forcefully shutdown modulator and deallocate data buffers. */ void terminate(); /** * Start baseband transmission and send an 80ms preamble. */ void start(); /** * Generate and transmit the baseband signal obtained by 4FSK modulation of * a given block of data. * * @param frame: M17 frame to be sent. * @param isLast: flag signalling that current block is the last one being * transmitted. */ void send(const frame_t& frame); /** * Terminate baseband transmission. */ void stop(); /** * Invert baseband signal phase before output. * * @param status: if set to true signal phase is inverted. */ void invertPhase(const bool status); private: /** * Generate baseband stream from symbol stream. */ void symbolsToBaseband(); /** * Emit the baseband stream towards the output stage, platform dependent. */ void sendBaseband(); static constexpr size_t M17_TX_SAMPLE_RATE = 48000; static constexpr size_t M17_SAMPLES_PER_SYMBOL = M17_TX_SAMPLE_RATE / M17_SYMBOL_RATE; static constexpr size_t M17_FRAME_SAMPLES = M17_FRAME_SYMBOLS * M17_SAMPLES_PER_SYMBOL; #ifdef PLATFORM_MOD17 static constexpr float M17_RRC_GAIN = 15000.0f; static constexpr float M17_RRC_OFFSET = 11500.0f; #else static constexpr float M17_RRC_GAIN = 23000.0f; static constexpr float M17_RRC_OFFSET = 0.0f; #endif std::array< int8_t, M17_FRAME_SYMBOLS > symbols; std::unique_ptr< int16_t[] > baseband_buffer; ///< Buffer for baseband audio handling. stream_sample_t *idleBuffer; ///< Half baseband buffer, free for processing. streamId outStream; ///< Baseband output stream ID. pathId outPath; ///< Baseband output path ID. bool txRunning; ///< Transmission running. bool invPhase; ///< Invert signal phase #if defined(PLATFORM_MD3x0) || defined(PLATFORM_MDUV3x0) PwmCompensator pwmComp; #endif }; } /* M17 */ #endif /* M17_MODULATOR_H */