From 445d9a6076324e2b68d130bbac978ad6d32335a4 Mon Sep 17 00:00:00 2001 From: RecklessAndFeckless Date: Wed, 9 Oct 2024 00:30:31 -0400 Subject: [PATCH] Better?? PSK Modulator?? --- include/encoder/ModemController.h | 4 +- include/modulation/PSKModulator.h | 112 +++++++++++++----------------- main.cpp | 4 +- 3 files changed, 52 insertions(+), 68 deletions(-) diff --git a/include/encoder/ModemController.h b/include/encoder/ModemController.h index a57974a..259468e 100644 --- a/include/encoder/ModemController.h +++ b/include/encoder/ModemController.h @@ -51,7 +51,7 @@ public: interleaver(baud_rate, interleave_setting, is_frequency_hopping), input_data(std::move(_data)), mgd_decoder(baud_rate, is_frequency_hopping), - modulator(PSKModulatorConfig(1500, 48000, baud_rate)) {} + modulator(48000) {} /** * @brief Transmits the input data by processing it through different phases like FEC encoding, interleaving, symbol formation, scrambling, and modulation. @@ -101,7 +101,7 @@ private: Scrambler scrambler; ///< Scrambler instance for scrambling the data. FECEncoder fec_encoder; ///< FEC encoder instance for encoding the data. Interleaver interleaver; ///< Interleaver instance for interleaving the data. - milstd::PSKModulator modulator; ///< PSK modulator instance for modulating the data. + PSKModulator modulator; ///< PSK modulator instance for modulating the data. MGDDecoder mgd_decoder; ///< MGD decoder /** diff --git a/include/modulation/PSKModulator.h b/include/modulation/PSKModulator.h index 6e80b04..5299dbd 100644 --- a/include/modulation/PSKModulator.h +++ b/include/modulation/PSKModulator.h @@ -1,74 +1,58 @@ #ifndef PSK_MODULATOR_H #define PSK_MODULATOR_H -#include +#include #include #include -#include +#include - -class PSKModulatorConfig { +class PSKModulator { public: - int carrier_frequency; - int sample_rate; - int baud_rate; - int bits_per_symbol; + PSKModulator(double sample_rate) : sample_rate(sample_rate), carrier_freq(1800), phase(0.0) { + initializeSymbolMap(); + } - PSKModulatorConfig(int cf, int sr, int br) : carrier_frequency(cf), sample_rate(sr), baud_rate(br) {} + std::vector modulate(const std::vector& symbols) { + std::vector modulated_signal; + + const double phase_increment = 2 * M_PI * carrier_freq / sample_rate; + for (auto symbol : symbols) { + if (symbol >= symbolMap.size()) { + throw std::out_of_range("Invalid symbol value for 8-PSK modulation"); + } + double target_phase = symbolMap[symbol]; + + for (size_t i = 0; i < samples_per_symbol; ++i) { + double value = std::sin(phase + target_phase); + modulated_signal.push_back(static_cast(value * std::numeric_limits::max())); + phase += phase_increment; + if (phase >= 2 * M_PI) { + phase -= 2 * M_PI; + } + } + } + return modulated_signal; + } + +private: + double sample_rate; ///< The sample rate of the system. + double carrier_freq; ///< The frequency of the carrier, set to 1800 Hz as per standard. + double phase; ///< Current phase of the carrier waveform. + size_t samples_per_symbol = 40; ///< Number of samples per symbol, calculated to match symbol duration with cycle. + std::vector symbolMap; ///< The mapping of tribit symbols to phase shifts. + + void initializeSymbolMap() { + symbolMap = { + 0.0, // 0 (000) corresponds to 0 degrees + M_PI / 4, // 1 (001) corresponds to 45 degrees + M_PI / 2, // 2 (010) corresponds to 90 degrees + 3 * M_PI / 4, // 3 (011) corresponds to 135 degrees + M_PI, // 4 (100) corresponds to 180 degrees + 5 * M_PI / 4, // 5 (101) corresponds to 225 degrees + 3 * M_PI / 2, // 6 (110) corresponds to 270 degrees + 7 * M_PI / 4 // 7 (111) corresponds to 315 degrees + }; + } }; -namespace milstd { - class PSKModulator { - public: - PSKModulator(const PSKModulatorConfig& config) : carrier_frequency(config.carrier_frequency), sample_rate(config.sample_rate), baud_rate(config.baud_rate) { - omega = 2.0 * M_PI * carrier_frequency / sample_rate; - baud_incr = static_cast(baud_rate) / sample_rate; - phase = 0.0; - baud_frac = 0.0; - initializeSymbolMap(); - } - - std::vector modulate(const std::vector& symbol_stream) { - std::vector modulated_signal; - modulated_signal.reserve(static_cast(symbol_stream.size() / baud_incr)); - - for (uint8_t symbol : symbol_stream) { - double symbol_phase = symbolMap[symbol]; - - while (baud_frac < 1.0) { - double sample = std::sin(omega * phase + symbol_phase); - int16_t output_sample = static_cast(sample * 32767); - modulated_signal.push_back(output_sample); - - phase = std::fmod(phase + omega, 2.0 * M_PI); - baud_frac += baud_incr; - } - - baud_frac -= 1.0; - } - - return modulated_signal; - } - - private: - int carrier_frequency; - int sample_rate; - int baud_rate; - - double phase; - double baud_frac; - double baud_incr; - double omega; - - std::array symbolMap; - - void initializeSymbolMap() { - double phase_increment = 2.0 * M_PI / 8.0; - for (int symbol = 0; symbol < 8; ++symbol) { - symbolMap[symbol] = symbol * phase_increment; - } - } - }; -} - -#endif /* PSK_MODULATOR_H */ \ No newline at end of file +#endif \ No newline at end of file diff --git a/main.cpp b/main.cpp index 321daca..40c3d1f 100644 --- a/main.cpp +++ b/main.cpp @@ -19,12 +19,12 @@ int main() { size_t baud_rate = 150; bool is_voice = false; // False indicates data mode bool is_frequency_hopping = false; // Fixed frequency operation - size_t interleave_setting = 1; // Short interleave + size_t interleave_setting = 2; // Short interleave // Create ModemController instance ModemController modem(baud_rate, is_voice, is_frequency_hopping, interleave_setting, bitstream); - const char* file_name = "modulated_signal_150bps_shortinterleave.wav"; + const char* file_name = "modulated_signal_150bps_longinterleave.wav"; // Perform transmit operation to generate modulated signal std::vector modulated_signal = modem.transmit();