Better?? PSK Modulator??
This commit is contained in:
parent
d4cbd9daad
commit
445d9a6076
@ -51,7 +51,7 @@ public:
|
|||||||
interleaver(baud_rate, interleave_setting, is_frequency_hopping),
|
interleaver(baud_rate, interleave_setting, is_frequency_hopping),
|
||||||
input_data(std::move(_data)),
|
input_data(std::move(_data)),
|
||||||
mgd_decoder(baud_rate, is_frequency_hopping),
|
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.
|
* @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.
|
Scrambler scrambler; ///< Scrambler instance for scrambling the data.
|
||||||
FECEncoder fec_encoder; ///< FEC encoder instance for encoding the data.
|
FECEncoder fec_encoder; ///< FEC encoder instance for encoding the data.
|
||||||
Interleaver interleaver; ///< Interleaver instance for interleaving 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
|
MGDDecoder mgd_decoder; ///< MGD decoder
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,74 +1,58 @@
|
|||||||
#ifndef PSK_MODULATOR_H
|
#ifndef PSK_MODULATOR_H
|
||||||
#define PSK_MODULATOR_H
|
#define PSK_MODULATOR_H
|
||||||
|
|
||||||
#include <array>
|
#include <vector>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <vector>
|
#include <stdexcept>
|
||||||
|
|
||||||
|
|
||||||
class PSKModulatorConfig {
|
|
||||||
public:
|
|
||||||
int carrier_frequency;
|
|
||||||
int sample_rate;
|
|
||||||
int baud_rate;
|
|
||||||
int bits_per_symbol;
|
|
||||||
|
|
||||||
PSKModulatorConfig(int cf, int sr, int br) : carrier_frequency(cf), sample_rate(sr), baud_rate(br) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace milstd {
|
|
||||||
class PSKModulator {
|
class PSKModulator {
|
||||||
public:
|
public:
|
||||||
PSKModulator(const PSKModulatorConfig& config) : carrier_frequency(config.carrier_frequency), sample_rate(config.sample_rate), baud_rate(config.baud_rate) {
|
PSKModulator(double sample_rate) : sample_rate(sample_rate), carrier_freq(1800), phase(0.0) {
|
||||||
omega = 2.0 * M_PI * carrier_frequency / sample_rate;
|
|
||||||
baud_incr = static_cast<double>(baud_rate) / sample_rate;
|
|
||||||
phase = 0.0;
|
|
||||||
baud_frac = 0.0;
|
|
||||||
initializeSymbolMap();
|
initializeSymbolMap();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<int16_t> modulate(const std::vector<uint8_t>& symbol_stream) {
|
std::vector<int16_t> modulate(const std::vector<uint8_t>& symbols) {
|
||||||
std::vector<int16_t> modulated_signal;
|
std::vector<int16_t> modulated_signal;
|
||||||
modulated_signal.reserve(static_cast<size_t>(symbol_stream.size() / baud_incr));
|
|
||||||
|
|
||||||
for (uint8_t symbol : symbol_stream) {
|
const double phase_increment = 2 * M_PI * carrier_freq / sample_rate;
|
||||||
double symbol_phase = symbolMap[symbol];
|
for (auto symbol : symbols) {
|
||||||
|
if (symbol >= symbolMap.size()) {
|
||||||
while (baud_frac < 1.0) {
|
throw std::out_of_range("Invalid symbol value for 8-PSK modulation");
|
||||||
double sample = std::sin(omega * phase + symbol_phase);
|
|
||||||
int16_t output_sample = static_cast<int16_t>(sample * 32767);
|
|
||||||
modulated_signal.push_back(output_sample);
|
|
||||||
|
|
||||||
phase = std::fmod(phase + omega, 2.0 * M_PI);
|
|
||||||
baud_frac += baud_incr;
|
|
||||||
}
|
}
|
||||||
|
double target_phase = symbolMap[symbol];
|
||||||
|
|
||||||
baud_frac -= 1.0;
|
for (size_t i = 0; i < samples_per_symbol; ++i) {
|
||||||
|
double value = std::sin(phase + target_phase);
|
||||||
|
modulated_signal.push_back(static_cast<int16_t>(value * std::numeric_limits<int16_t>::max()));
|
||||||
|
phase += phase_increment;
|
||||||
|
if (phase >= 2 * M_PI) {
|
||||||
|
phase -= 2 * M_PI;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return modulated_signal;
|
return modulated_signal;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int carrier_frequency;
|
double sample_rate; ///< The sample rate of the system.
|
||||||
int sample_rate;
|
double carrier_freq; ///< The frequency of the carrier, set to 1800 Hz as per standard.
|
||||||
int baud_rate;
|
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.
|
||||||
double phase;
|
std::vector<double> symbolMap; ///< The mapping of tribit symbols to phase shifts.
|
||||||
double baud_frac;
|
|
||||||
double baud_incr;
|
|
||||||
double omega;
|
|
||||||
|
|
||||||
std::array<double, 8> symbolMap;
|
|
||||||
|
|
||||||
void initializeSymbolMap() {
|
void initializeSymbolMap() {
|
||||||
double phase_increment = 2.0 * M_PI / 8.0;
|
symbolMap = {
|
||||||
for (int symbol = 0; symbol < 8; ++symbol) {
|
0.0, // 0 (000) corresponds to 0 degrees
|
||||||
symbolMap[symbol] = symbol * phase_increment;
|
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
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
#endif /* PSK_MODULATOR_H */
|
#endif
|
4
main.cpp
4
main.cpp
@ -19,12 +19,12 @@ int main() {
|
|||||||
size_t baud_rate = 150;
|
size_t baud_rate = 150;
|
||||||
bool is_voice = false; // False indicates data mode
|
bool is_voice = false; // False indicates data mode
|
||||||
bool is_frequency_hopping = false; // Fixed frequency operation
|
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
|
// Create ModemController instance
|
||||||
ModemController modem(baud_rate, is_voice, is_frequency_hopping, interleave_setting, bitstream);
|
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
|
// Perform transmit operation to generate modulated signal
|
||||||
std::vector<int16_t> modulated_signal = modem.transmit();
|
std::vector<int16_t> modulated_signal = modem.transmit();
|
||||||
|
Loading…
Reference in New Issue
Block a user