forked from SatDump/SatDump
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request SatDump#601 from OK9UWU/master
Add Cluster WBD Decoder
- Loading branch information
Showing
8 changed files
with
403 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
cmake_minimum_required(VERSION 3.0.0) | ||
project(cluster_support) | ||
|
||
file(GLOB_RECURSE cluster_support_CPPS *.cpp) | ||
add_library(cluster_support SHARED ${cluster_support_CPPS}) | ||
target_link_libraries(cluster_support PUBLIC satdump_core) | ||
target_include_directories(cluster_support PUBLIC src) | ||
|
||
install(TARGETS cluster_support DESTINATION lib/satdump/plugins) |
50 changes: 50 additions & 0 deletions
50
plugins/cluster_support/cluster/instruments/wbd_decoder.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
#include "wbd_decoder.h" | ||
|
||
namespace cluster | ||
{ | ||
std::vector<MajorFrame> WBDdecoder::work(uint8_t *frm) | ||
{ | ||
std::vector<MajorFrame> outputframes; | ||
|
||
if (frm[3] % 4 == 0) | ||
{ | ||
if (wbdwip.payload.size() == 1090 * 4 - 8) | ||
outputframes.push_back(wbdwip); | ||
wbdwip = MajorFrame(); | ||
} | ||
else if (frm[3] % 4 == 1) | ||
{ | ||
wbdwip.antennaselect = (frm[5] >> 4) & 0b11; // 0 Ez, 1 Bz, 2 By, 3 Ey | ||
wbdwip.convfreq = (frm[5] >> 2) & 0b11; // conversion freq, 0, 125.454, 250.908, 501.816k | ||
wbdwip.hgagc = frm[5] & 0b11; // Higher AGC select | ||
wbdwip.commands = frm[5] >> 5 & 0b1; // Command Status (0=No cmds; 1=Cmds received) | ||
wbdwip.OBDH = frm[5] >> 6 & 0b1; // OBDH Interface (0=Primary; 1=Redundant) | ||
wbdwip.ADpower = frm[5] >> 4 & 0b1; // seems to be always on | ||
wbdwip.VCXO = frm[5] >> 7; // locked unlocked, 0 is locked | ||
} | ||
else if (frm[3] % 4 == 2) | ||
{ | ||
|
||
wbdwip.AGC = frm[4] >> 5 & 0b1; // AGC MAN/AUTO 0 for Auto, 1 for Manual | ||
wbdwip.gainlevel = frm[4] >> 1 & 0b1111; // Gain, 16steps as per 3.2.2.4-1 | ||
wbdwip.antennaselect = (frm[5] >> 4) & 0b11; // 0 Ez, 1 Bz, 2 By, 3 Ey | ||
wbdwip.convfreq = (frm[5] >> 2) & 0b11; // conversion freq, 0, 125.454, 250.908, 501.816k | ||
wbdwip.hgagc = frm[5] & 0b11; // Higher AGC select | ||
} | ||
else if (frm[3] % 4 == 3) | ||
{ | ||
wbdwip.commands = frm[5] >> 5 & 0b1; // Command Status (0=No cmds; 1=Cmds received) | ||
wbdwip.OBDH = frm[5] >> 6 & 0b1; // OBDH Interface (0=Primary; 1=Redundant) | ||
wbdwip.ADpower = frm[5] >> 4 & 0b1; // seems to be always on | ||
wbdwip.VCXO = frm[5] >> 7; // locked unlocked, 0 is locked | ||
wbdwip.outputmode = frm[4] >> 2 & 0b111; // sampling rate, bit depth, duty cycle as per 3.2.2.5-1 | ||
wbdwip.lwagc = frm[4] & 0b11; // Lower AGC select | ||
} | ||
|
||
for (int i = 6; i < 1096; i++) | ||
if (i != 88 && i != 89) | ||
wbdwip.payload.push_back(frm[i]); | ||
|
||
return outputframes; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
#pragma once | ||
#include <vector> | ||
#include <cstdint> | ||
|
||
namespace cluster | ||
{ | ||
struct MajorFrame | ||
{ | ||
std::vector<uint8_t> payload; | ||
bool VCXO = false; | ||
bool ADpower = false; | ||
bool AGC = false; | ||
bool OBDH = false; | ||
bool commands = false; | ||
int convfreq = 0; | ||
int outputmode = 0; | ||
int antennaselect = 0; | ||
int WBDmodel = 0; | ||
int gainlevel = 0; | ||
int lwagc = 0; | ||
int hgagc = 0; | ||
}; | ||
|
||
class WBDdecoder | ||
{ | ||
private: | ||
MajorFrame wbdwip; | ||
|
||
public: | ||
std::vector<MajorFrame> work(uint8_t *frm); | ||
}; | ||
} |
231 changes: 231 additions & 0 deletions
231
plugins/cluster_support/cluster/module_cluster_instruments.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,231 @@ | ||
#include "module_cluster_instruments.h" | ||
#include <fstream> | ||
#include "common/ccsds/ccsds_standard/vcdu.h" | ||
#include "logger.h" | ||
#include <filesystem> | ||
#include "imgui/imgui.h" | ||
#include "common/utils.h" | ||
#include "common/ccsds/ccsds_standard/demuxer.h" | ||
#include "products/products.h" | ||
#include "products/dataset.h" | ||
#include "common/simple_deframer.h" | ||
#include "instruments/wbd_decoder.h" | ||
#include "common/audio/audio_sink.h" | ||
#include "common/dsp/io/wav_writer.h" | ||
|
||
namespace cluster | ||
{ | ||
namespace instruments | ||
{ | ||
CLUSTERInstrumentsDecoderModule::CLUSTERInstrumentsDecoderModule(std::string input_file, std::string output_file_hint, nlohmann::json parameters) | ||
: ProcessingModule(input_file, output_file_hint, parameters) | ||
{ | ||
} | ||
|
||
void CLUSTERInstrumentsDecoderModule::process() | ||
{ | ||
if (input_data_type == DATA_FILE) | ||
filesize = getFilesize(d_input_file); | ||
std::ifstream data_in; | ||
if (input_data_type == DATA_FILE) | ||
data_in = std::ifstream(d_input_file, std::ios::binary); | ||
|
||
logger->info("Using input frames " + d_input_file); | ||
|
||
time_t lastTime = 0; | ||
uint8_t cadu[1279]; | ||
|
||
// Demuxers | ||
ccsds::ccsds_standard::Demuxer demuxer_vcid1(1101, false); | ||
|
||
std::ofstream output(d_output_file_hint + "_wbd.frm", std::ios::binary); | ||
std::ofstream output_cadu2(d_output_file_hint + "_cadu_bkp.cadu", std::ios::binary); | ||
|
||
def::SimpleDeframer wbddeframer(0xFAF334, 24, 8768, 0); | ||
WBDdecoder wbddecode; | ||
|
||
// Audio stuff | ||
int16_t audio_buffer[4352]; | ||
bool enable_audio = false; | ||
std::shared_ptr<audio::AudioSink> audio_sink; | ||
if (input_data_type != DATA_FILE && audio::has_sink()) | ||
{ | ||
enable_audio = true; | ||
audio_sink = audio::get_default_sink(); | ||
audio_sink->set_samplerate(27443); | ||
audio_sink->start(); | ||
} | ||
|
||
// Buffers to wav...for all the antennas | ||
std::ofstream out_antenna_Ez(d_output_file_hint + "_Ez.wav", std::ios::binary); | ||
int final_data_size_ant_Ez = 0; | ||
dsp::WavWriter wave_writer_Ez(out_antenna_Ez); | ||
wave_writer_Ez.write_header(27443, 1); | ||
|
||
std::ofstream out_antenna_Bx(d_output_file_hint + "_Bx.wav", std::ios::binary); | ||
int final_data_size_ant_Bx = 0; | ||
dsp::WavWriter wave_writer_Bx(out_antenna_Bx); | ||
wave_writer_Bx.write_header(27443, 1); | ||
|
||
std::ofstream out_antenna_By(d_output_file_hint + "_By.wav", std::ios::binary); | ||
int final_data_size_ant_By = 0; | ||
dsp::WavWriter wave_writer_By(out_antenna_By); | ||
wave_writer_By.write_header(27443, 1); | ||
|
||
std::ofstream out_antenna_Ey(d_output_file_hint + "_Ey.wav", std::ios::binary); | ||
int final_data_size_ant_Ey = 0; | ||
dsp::WavWriter wave_writer_Ey(out_antenna_Ey); | ||
wave_writer_Ey.write_header(27443, 1); | ||
|
||
while (input_data_type == DATA_FILE ? !data_in.eof() : input_active.load()) | ||
{ | ||
// Read buffer | ||
if (input_data_type == DATA_FILE) | ||
data_in.read((char *)&cadu, 1279); | ||
else | ||
input_fifo->read((uint8_t *)&cadu, 1279); | ||
|
||
// Save (for now) | ||
output_cadu2.write((char *)cadu, 1279); | ||
|
||
// Parse this transport frame | ||
ccsds::ccsds_standard::VCDU vcdu = ccsds::ccsds_standard::parseVCDU(cadu); | ||
|
||
if (vcdu.vcid == 5) // Parse WBD VCID | ||
{ | ||
std::vector<ccsds::CCSDSPacket> ccsdsFrames = demuxer_vcid1.work(cadu); | ||
for (ccsds::CCSDSPacket &pkt : ccsdsFrames) | ||
{ | ||
std::vector<std::vector<uint8_t>> minorframes = wbddeframer.work(pkt.payload.data(), pkt.payload.size()); | ||
for (auto &frm : minorframes) | ||
{ | ||
std::vector<MajorFrame> majorframes = wbddecode.work(frm.data()); | ||
for (auto &majorframe : majorframes) | ||
{ | ||
for (int i = 0; i < 4352; i++) | ||
audio_buffer[i] = (int(majorframe.payload[i]) - 127) * 255; | ||
|
||
if (enable_audio) | ||
audio_sink->push_samples(audio_buffer, 4352); | ||
|
||
if (majorframe.VCXO == 0) | ||
{ | ||
output.write((char *)majorframe.payload.data(), majorframe.payload.size()); | ||
if (majorframe.antennaselect == 0) | ||
{ | ||
out_antenna_Ez.write((char *)audio_buffer, 4352 * sizeof(int16_t)); | ||
final_data_size_ant_Ez += 4352 * sizeof(int16_t); | ||
} | ||
else if (majorframe.antennaselect == 1) | ||
{ | ||
out_antenna_Bx.write((char *)audio_buffer, 4352 * sizeof(int16_t)); | ||
final_data_size_ant_Bx += 4352 * sizeof(int16_t); | ||
} | ||
else if (majorframe.antennaselect == 2) | ||
{ | ||
out_antenna_By.write((char *)audio_buffer, 4352 * sizeof(int16_t)); | ||
final_data_size_ant_By += 4352 * sizeof(int16_t); | ||
} | ||
else if (majorframe.antennaselect == 3) | ||
{ | ||
out_antenna_Ey.write((char *)audio_buffer, 4352 * sizeof(int16_t)); | ||
final_data_size_ant_Ey += 4352 * sizeof(int16_t); | ||
} | ||
} | ||
|
||
param_antenna = majorframe.antennaselect; | ||
param_convfrq = majorframe.convfreq; | ||
param_band = majorframe.outputmode; | ||
param_VCXO = majorframe.VCXO; | ||
param_OBDH = majorframe.OBDH; | ||
param_commands = majorframe.commands; | ||
} | ||
} | ||
} | ||
} | ||
|
||
progress = data_in.tellg(); | ||
if (time(NULL) % 10 == 0 && lastTime != time(NULL)) | ||
{ | ||
lastTime = time(NULL); | ||
logger->info("Progress " + std::to_string(round(((double)progress / (double)filesize) * 1000.0) / 10.0) + "%%"); | ||
} | ||
} | ||
|
||
wave_writer_Ez.finish_header(final_data_size_ant_Ez); | ||
wave_writer_Bx.finish_header(final_data_size_ant_Bx); | ||
wave_writer_By.finish_header(final_data_size_ant_By); | ||
wave_writer_Ey.finish_header(final_data_size_ant_Ey); | ||
|
||
if (input_data_type == DATA_FILE) | ||
data_in.close(); | ||
output_cadu2.close(); | ||
} | ||
|
||
void CLUSTERInstrumentsDecoderModule::drawUI(bool window) | ||
{ | ||
ImGui::Begin("Cluster Instruments Decoder", NULL, window ? 0 : NOWINDOW_FLAGS); | ||
|
||
ImGui::Text("Antenna :"); | ||
ImGui::SameLine(); | ||
if (param_antenna == 0) | ||
ImGui::Text("Ez"); | ||
else if (param_antenna == 1) | ||
ImGui::Text("Bx"); | ||
else if (param_antenna == 2) | ||
ImGui::Text("By"); | ||
else if (param_antenna == 3) | ||
ImGui::Text("Ey"); | ||
|
||
ImGui::Text("Conversion Freq : "); | ||
ImGui::SameLine(); | ||
if (param_convfrq == 0) | ||
ImGui::Text("Baseband"); | ||
else if (param_convfrq == 1) | ||
ImGui::Text("125.454 kHz"); | ||
else if (param_convfrq == 2) | ||
ImGui::Text("250.908 kHz"); | ||
else if (param_convfrq == 3) | ||
ImGui::Text("501.816 kHz"); | ||
|
||
// ImGui::Text("Freq Band:"); | ||
// ImGui::SameLine(); | ||
// ImGui::Text("%d", param_band); | ||
|
||
ImGui::Text("VCXO : "); | ||
ImGui::SameLine(); | ||
if (param_VCXO == 0) | ||
ImGui::Text("Locked"); | ||
else | ||
ImGui::Text("Unlocked"); | ||
|
||
ImGui::Text("OBDH : "); | ||
ImGui::SameLine(); | ||
ImGui::Text("%d", param_OBDH); | ||
|
||
ImGui::Text("CMD : "); | ||
ImGui::SameLine(); | ||
ImGui::Text("%d", param_commands); | ||
|
||
if (input_data_type == DATA_FILE) | ||
ImGui::ProgressBar((double)progress / (double)filesize, ImVec2(ImGui::GetWindowWidth() - 10, 20 * ui_scale)); | ||
|
||
ImGui::End(); | ||
} | ||
|
||
std::string CLUSTERInstrumentsDecoderModule::getID() | ||
{ | ||
return "cluster_instruments"; | ||
} | ||
|
||
std::vector<std::string> CLUSTERInstrumentsDecoderModule::getParameters() | ||
{ | ||
return {}; | ||
} | ||
|
||
std::shared_ptr<ProcessingModule> CLUSTERInstrumentsDecoderModule::getInstance(std::string input_file, std::string output_file_hint, nlohmann::json parameters) | ||
{ | ||
return std::make_shared<CLUSTERInstrumentsDecoderModule>(input_file, output_file_hint, parameters); | ||
} | ||
} // namespace amsu | ||
} // namespace metop |
Oops, something went wrong.