diff --git a/plugins/bitview_app/CMakeLists.txt b/plugins/bitview_app/CMakeLists.txt index 7e6dd31a6..2ee2404bf 100644 --- a/plugins/bitview_app/CMakeLists.txt +++ b/plugins/bitview_app/CMakeLists.txt @@ -4,7 +4,7 @@ project(bitview_app) file(GLOB_RECURSE bitview_app_CPPS *.cpp) add_library(bitview_app SHARED ${bitview_app_CPPS}) -target_link_libraries(bitview_app PUBLIC satdump_core satdump_interface) -target_include_directories(bitview_app PUBLIC . ../../src-interface) +target_link_libraries(bitview_app PUBLIC satdump_core) +target_include_directories(bitview_app PUBLIC .) install(TARGETS bitview_app DESTINATION ${CMAKE_INSTALL_LIBDIR}/satdump/plugins) \ No newline at end of file diff --git a/plugins/bitview_app/bitview.cpp b/plugins/bitview_app/bitview.cpp index 0550097c8..85a4a9e9a 100644 --- a/plugins/bitview_app/bitview.cpp +++ b/plugins/bitview_app/bitview.cpp @@ -7,11 +7,12 @@ #include #include -#include "tools/ccsds_apid_demux.h" -#include "tools/ccsds_vcid_splitter.h" -#include "tools/deframer.h" -#include "tools/diff_decode.h" -#include "tools/soft2hard.h" +#include "logger.h" +#include "tools/ccsds_apid_demux/ccsds_apid_demux.h" +#include "tools/ccsds_vcid_splitter/ccsds_vcid_splitter.h" +#include "tools/deframer/deframer.h" +#include "tools/diff_decode/diff_decode.h" +#include "tools/soft2hard/soft2hard.h" namespace satdump { @@ -81,13 +82,12 @@ namespace satdump { if (ImGui::CollapsingHeader((tool->getName()).c_str())) { - tool->renderMenu(bc, is_busy); if (tool->needToProcess()) { tool->setProcessed(); - auto func = [this, tool](int) + auto func = [this, tool]() { try { @@ -100,7 +100,7 @@ namespace satdump is_busy = false; }; is_busy = true; - process_threadp.push(func); + process_task.push(func); } } } @@ -113,7 +113,7 @@ namespace satdump if (ImGui::Button("Find Sync")) { - auto func = [this](int) + auto func = [this]() { auto ptr = bc->get_ptr(); auto sz = bc->get_ptr_size(); @@ -129,7 +129,7 @@ namespace satdump is_busy = false; }; is_busy = true; - process_threadp.push(func); + process_task.push(func); } } diff --git a/plugins/bitview_app/bitview.h b/plugins/bitview_app/bitview.h index 49b55da27..7d1c64cd9 100644 --- a/plugins/bitview_app/bitview.h +++ b/plugins/bitview_app/bitview.h @@ -2,20 +2,16 @@ #include "handlers/handler.h" #include "imgui/imgui.h" -#include "imgui/imgui_internal.h" -#include #include -#include "imgui/dialogs/widget.h" - #include "bit_container.h" -#include "libs/ctpl/ctpl_stl.h" - -#include "tool.h" +#include "utils/task_queue.h" namespace satdump { + class BitViewTool; + class BitViewHandler : public handlers::Handler { protected: @@ -31,7 +27,7 @@ namespace satdump private: float process_progress = 0; - ctpl::thread_pool process_threadp = ctpl::thread_pool(4); + TaskQueue process_task; std::vector> all_tools; diff --git a/plugins/bitview_app/cli/cmd.cpp b/plugins/bitview_app/cli/cmd.cpp index 4d00ba4d9..c1c8ef221 100644 --- a/plugins/bitview_app/cli/cmd.cpp +++ b/plugins/bitview_app/cli/cmd.cpp @@ -13,7 +13,7 @@ namespace satdump sub_module->add_flag("--period", period, "Bit period to use")->default_val(256); } - void BitViewCmdHandler::run(CLI::App *app, CLI::App *subcom, bool is_gui) + void BitViewCmdHandler::run(CLI::App *, CLI::App *subcom, bool) { std::string file = subcom->get_option("file")->as(); diff --git a/plugins/bitview_app/tool.h b/plugins/bitview_app/tool.h index 33afb1fe9..d9938013f 100644 --- a/plugins/bitview_app/tool.h +++ b/plugins/bitview_app/tool.h @@ -1,7 +1,6 @@ #pragma once #include "bitview.h" -#include "libs/ctpl/ctpl_stl.h" namespace satdump { diff --git a/plugins/bitview_app/tools/ccsds_apid_demux.h b/plugins/bitview_app/tools/ccsds_apid_demux.h deleted file mode 100644 index 7d3208452..000000000 --- a/plugins/bitview_app/tools/ccsds_apid_demux.h +++ /dev/null @@ -1,210 +0,0 @@ -#pragma once - -#include "bit_container.h" -#include "common/ccsds/ccsds_aos/demuxer.h" -#include "common/ccsds/ccsds_aos/vcdu.h" -#include "common/ccsds/ccsds_tm/vcdu.h" -#include "core/style.h" -#include "imgui/imgui.h" -#include "imgui/imgui_stdlib.h" -#include "logger.h" -#include "tool.h" -#include -#include -#include - -namespace satdump -{ - class CCSDSAPIDDemuxTool : public BitViewTool - { - private: - bool should_process = false; - - int mpdu_data_size = 884; - int insert_zone_size = 0; - bool split_apid = true; - - public: - std::string getName() { return "CCSDS APID Demux"; } - - void renderMenu(std::shared_ptr &container, bool is_busy) - { - if (is_busy) - style::beginDisabled(); - - ImGui::InputInt("MPDU Data Size", &mpdu_data_size); - ImGui::InputInt("MPDU Insert Zone Size", &insert_zone_size); - ImGui::Checkbox("Split APIDs", &split_apid); - - if (ImGui::Button("Perform###2")) - should_process = true; - - if (is_busy) - style::endDisabled(); - } - - bool needToProcess() { return should_process; } - - void setProcessed() { should_process = false; } - - void process(std::shared_ptr &container, float &process_progress) - { - logger->critical("Demux!!!!"); - - uint8_t *ptr = container->get_ptr(); - size_t size = container->get_ptr_size(); - - if (split_apid) - { - struct APIDOut - { - APIDOut(std::string f) : tmpfile(f), fileout(f, std::ios::binary) {} - - std::string tmpfile; - std::ofstream fileout; - std::vector frms; - size_t pos = 0; - }; - std::map> apids_outs; - - ccsds::ccsds_aos::Demuxer demuxer_vcid(mpdu_data_size, insert_zone_size, insert_zone_size); - - for (int i = 0; i < size; i += 1024) - { - auto frm = demuxer_vcid.work(ptr + i); - - for (auto &f : frm) - { - if (apids_outs.count(f.header.apid) == 0) - { - char name[1000]; - tmpnam(name); - std::string tmpfile = name; - apids_outs.emplace(f.header.apid, std::make_shared(tmpfile)); - } - - auto &v = apids_outs[f.header.apid]; - - v->fileout.write((char *)f.header.raw, 6); - v->fileout.write((char *)f.payload.data(), f.payload.size()); - - v->frms.push_back({v->pos * 8, (f.payload.size() + 6) * 8}); - v->pos += f.payload.size() + 6; - } - - process_progress = double(i) / double(size); - } - - for (auto &v : apids_outs) - { - if (v.second->frms.size()) - { - std::shared_ptr newbitc = std::make_shared("APID " + std::to_string(v.first), v.second->tmpfile, v.second->frms); - newbitc->d_bitperiod = 8192; - newbitc->init_bitperiod(); - newbitc->d_is_temporary = true; - - if (container->bitview != nullptr) - ((BitViewHandler *)container->bitview)->addSubHandler(std::make_shared(newbitc)); - else - logger->error("Can't add container!"); - } - } - } - else - { - char name[1000]; - tmpnam(name); - std::string tmpfile = name; - std::ofstream fileout = std::ofstream(tmpfile, std::ios::binary); - std::vector frms; - - ccsds::ccsds_aos::Demuxer demuxer_vcid(mpdu_data_size, insert_zone_size, insert_zone_size); - - size_t pos = 0; - for (int i = 0; i < size; i += 1024) - { - auto frm = demuxer_vcid.work(ptr + i); - - for (auto &f : frm) - { - fileout.write((char *)f.header.raw, 6); - fileout.write((char *)f.payload.data(), f.payload.size()); - - frms.push_back({pos * 8, (f.payload.size() + 6) * 8}); - pos += f.payload.size() + 6; - } - - process_progress = double(i) / double(size); - } - - if (frms.size()) - { - std::shared_ptr newbitc = std::make_shared("APIDs", tmpfile, frms); - newbitc->d_bitperiod = 8192; - newbitc->init_bitperiod(); - newbitc->d_is_temporary = true; - - if (container->bitview != nullptr) - ((BitViewHandler *)container->bitview)->addSubHandler(std::make_shared(newbitc)); - else - logger->error("Can't add container!"); - } - } - -#if 0 - std::map vcid_counts; - std::map> output_files; - - size_t current_ptr = 0; - while (current_ptr < size) - { - size_t csize = std::min(cadu_size / 8, size - current_ptr); - if (cadu_size / 8 != csize) - break; - - uint8_t *ptr_pos = ptr + current_ptr; - - int vcid = 0; - if (cadu_mode == 0) - vcid = ccsds::ccsds_aos::parseVCDU(ptr_pos).vcid; - else if (cadu_mode == 1) - vcid = ccsds::ccsds_tm::parseVCDU(ptr_pos).vcid; - - if (output_files.count(vcid) == 0) - { - output_files.emplace(vcid, std::pair{"", std::ofstream()}); - vcid_counts.emplace(vcid, 0); - - char name[1000]; - tmpnam(name); - std::string tmpfile = name; - output_files[vcid].first = tmpfile; - output_files[vcid].second = std::ofstream(tmpfile, std::ios::binary); - } - - output_files[vcid].second.write((char *)ptr_pos, cadu_size / 8); - vcid_counts[vcid]++; - - current_ptr += csize; - - process_progress = double(current_ptr) / double(size); - } - - for (auto &f : output_files) - { - f.second.second.close(); - std::shared_ptr newbitc = std::make_shared(container->getName() + " VCID " + std::to_string(f.first) + " (" + std::to_string(vcid_counts[f.first]) + ")", f.second.first); - newbitc->d_bitperiod = cadu_size; - newbitc->init_bitperiod(); - newbitc->d_is_temporary = true; - - if (container->bitview != nullptr) - ((BitViewHandler *)container->bitview)->addSubHandler(std::make_shared(newbitc)); - else - logger->error("Can't add container!"); - } -#endif - } - }; -} // namespace satdump \ No newline at end of file diff --git a/plugins/bitview_app/tools/ccsds_apid_demux/ccsds_apid_demux.cpp b/plugins/bitview_app/tools/ccsds_apid_demux/ccsds_apid_demux.cpp new file mode 100644 index 000000000..7cc8d687c --- /dev/null +++ b/plugins/bitview_app/tools/ccsds_apid_demux/ccsds_apid_demux.cpp @@ -0,0 +1,141 @@ +#include "ccsds_apid_demux.h" +#include "bit_container.h" +#include "common/ccsds/ccsds_aos/demuxer.h" +#include "core/style.h" +#include "imgui/imgui.h" +#include "logger.h" +#include +#include +#include + +namespace satdump +{ + std::string CCSDSAPIDDemuxTool::getName() { return "CCSDS APID Demux"; } + + void CCSDSAPIDDemuxTool::renderMenu(std::shared_ptr &container, bool is_busy) + { + if (is_busy) + style::beginDisabled(); + + ImGui::InputInt("MPDU Data Size", &mpdu_data_size); + ImGui::InputInt("MPDU Insert Zone Size", &insert_zone_size); + ImGui::Checkbox("Split APIDs", &split_apid); + + if (ImGui::Button("Perform###2")) + should_process = true; + + if (is_busy) + style::endDisabled(); + } + + bool CCSDSAPIDDemuxTool::needToProcess() { return should_process; } + + void CCSDSAPIDDemuxTool::setProcessed() { should_process = false; } + + void CCSDSAPIDDemuxTool::process(std::shared_ptr &container, float &process_progress) + { + logger->critical("Demux!!!!"); + + uint8_t *ptr = container->get_ptr(); + size_t size = container->get_ptr_size(); + + if (split_apid) + { + struct APIDOut + { + APIDOut(std::string f) : tmpfile(f), fileout(f, std::ios::binary) {} + + std::string tmpfile; + std::ofstream fileout; + std::vector frms; + size_t pos = 0; + }; + std::map> apids_outs; + + ccsds::ccsds_aos::Demuxer demuxer_vcid(mpdu_data_size, insert_zone_size, insert_zone_size); + + for (int i = 0; i < size; i += 1024) + { + auto frm = demuxer_vcid.work(ptr + i); + + for (auto &f : frm) + { + if (apids_outs.count(f.header.apid) == 0) + { + char name[1000]; + tmpnam(name); + std::string tmpfile = name; + apids_outs.emplace(f.header.apid, std::make_shared(tmpfile)); + } + + auto &v = apids_outs[f.header.apid]; + + v->fileout.write((char *)f.header.raw, 6); + v->fileout.write((char *)f.payload.data(), f.payload.size()); + + v->frms.push_back({v->pos * 8, (f.payload.size() + 6) * 8}); + v->pos += f.payload.size() + 6; + } + + process_progress = double(i) / double(size); + } + + for (auto &v : apids_outs) + { + if (v.second->frms.size()) + { + std::shared_ptr newbitc = std::make_shared("APID " + std::to_string(v.first), v.second->tmpfile, v.second->frms); + newbitc->d_bitperiod = 8192; + newbitc->init_bitperiod(); + newbitc->d_is_temporary = true; + + if (container->bitview != nullptr) + ((BitViewHandler *)container->bitview)->addSubHandler(std::make_shared(newbitc)); + else + logger->error("Can't add container!"); + } + } + } + else + { + char name[1000]; + tmpnam(name); + std::string tmpfile = name; + std::ofstream fileout = std::ofstream(tmpfile, std::ios::binary); + std::vector frms; + + ccsds::ccsds_aos::Demuxer demuxer_vcid(mpdu_data_size, insert_zone_size, insert_zone_size); + + size_t pos = 0; + for (int i = 0; i < size; i += 1024) + { + auto frm = demuxer_vcid.work(ptr + i); + + for (auto &f : frm) + { + fileout.write((char *)f.header.raw, 6); + fileout.write((char *)f.payload.data(), f.payload.size()); + + frms.push_back({pos * 8, (f.payload.size() + 6) * 8}); + pos += f.payload.size() + 6; + } + + process_progress = double(i) / double(size); + } + + if (frms.size()) + { + std::shared_ptr newbitc = std::make_shared("APIDs", tmpfile, frms); + newbitc->d_bitperiod = 8192; + newbitc->init_bitperiod(); + newbitc->d_is_temporary = true; + + if (container->bitview != nullptr) + ((BitViewHandler *)container->bitview)->addSubHandler(std::make_shared(newbitc)); + else + logger->error("Can't add container!"); + } + } + } + +} // namespace satdump \ No newline at end of file diff --git a/plugins/bitview_app/tools/ccsds_apid_demux/ccsds_apid_demux.h b/plugins/bitview_app/tools/ccsds_apid_demux/ccsds_apid_demux.h new file mode 100644 index 000000000..a52a673f9 --- /dev/null +++ b/plugins/bitview_app/tools/ccsds_apid_demux/ccsds_apid_demux.h @@ -0,0 +1,23 @@ +#pragma once + +#include "tool.h" + +namespace satdump +{ + class CCSDSAPIDDemuxTool : public BitViewTool + { + private: + bool should_process = false; + + int mpdu_data_size = 884; + int insert_zone_size = 0; + bool split_apid = true; + + public: + std::string getName(); + void renderMenu(std::shared_ptr &container, bool is_busy); + bool needToProcess(); + void setProcessed(); + void process(std::shared_ptr &container, float &process_progress); + }; +} // namespace satdump \ No newline at end of file diff --git a/plugins/bitview_app/tools/ccsds_vcid_splitter.h b/plugins/bitview_app/tools/ccsds_vcid_splitter.h deleted file mode 100644 index 5bcc546b2..000000000 --- a/plugins/bitview_app/tools/ccsds_vcid_splitter.h +++ /dev/null @@ -1,111 +0,0 @@ -#pragma once - -#include "tool.h" -#include "imgui/imgui_stdlib.h" -#include -#include "core/style.h" -#include "common/ccsds/ccsds_aos/vcdu.h" -#include "common/ccsds/ccsds_tm/vcdu.h" -#include - -namespace satdump -{ - class CCSDSVcidSplitterTool : public BitViewTool - { - private: - int cadu_mode = 0; - int cadu_size = 8192; - - bool should_process = false; - - public: - std::string getName() { return "CCSDS VCID Splitter"; } - - void renderMenu(std::shared_ptr &container, bool is_busy) - { - if (is_busy) - style::beginDisabled(); - - if (ImGui::RadioButton("AOS", cadu_mode == 0)) - cadu_mode = 0; - if (ImGui::RadioButton("TM", cadu_mode == 1)) - cadu_mode = 1; - - ImGui::InputInt("CADU Width (bits)", &cadu_size); - - if (ImGui::Button("Perform")) - should_process = true; - - if (is_busy) - style::endDisabled(); - } - - bool needToProcess() - { - return should_process; - } - - void setProcessed() - { - should_process = false; - } - - void process(std::shared_ptr &container, float &process_progress) - { - uint8_t *ptr = container->get_ptr(); - size_t size = container->get_ptr_size(); - - std::map vcid_counts; - std::map> output_files; - - size_t current_ptr = 0; - while (current_ptr < size) - { - size_t csize = std::min(cadu_size / 8, size - current_ptr); - if (cadu_size / 8 != csize) - break; - - uint8_t *ptr_pos = ptr + current_ptr; - - int vcid = 0; - if (cadu_mode == 0) - vcid = ccsds::ccsds_aos::parseVCDU(ptr_pos).vcid; - else if (cadu_mode == 1) - vcid = ccsds::ccsds_tm::parseVCDU(ptr_pos).vcid; - - if (output_files.count(vcid) == 0) - { - output_files.emplace(vcid, std::pair{"", std::ofstream()}); - vcid_counts.emplace(vcid, 0); - - char name[1000]; - tmpnam(name); - std::string tmpfile = name; - output_files[vcid].first = tmpfile; - output_files[vcid].second = std::ofstream(tmpfile, std::ios::binary); - } - - output_files[vcid].second.write((char *)ptr_pos, cadu_size / 8); - vcid_counts[vcid]++; - - current_ptr += csize; - - process_progress = double(current_ptr) / double(size); - } - - for (auto &f : output_files) - { - f.second.second.close(); - std::shared_ptr newbitc = std::make_shared("VCID " + std::to_string(f.first) + " (" + std::to_string(vcid_counts[f.first]) + ")", f.second.first); - newbitc->d_bitperiod = cadu_size; - newbitc->init_bitperiod(); - newbitc->d_is_temporary = true; - - if (container->bitview != nullptr) - ((BitViewHandler *)container->bitview)->addSubHandler(std::make_shared(newbitc)); - else - logger->error("Can't add container!"); - } - } - }; -} \ No newline at end of file diff --git a/plugins/bitview_app/tools/ccsds_vcid_splitter/ccsds_vcid_splitter.cpp b/plugins/bitview_app/tools/ccsds_vcid_splitter/ccsds_vcid_splitter.cpp new file mode 100644 index 000000000..9b5ad706c --- /dev/null +++ b/plugins/bitview_app/tools/ccsds_vcid_splitter/ccsds_vcid_splitter.cpp @@ -0,0 +1,94 @@ +#include "ccsds_vcid_splitter.h" +#include "common/ccsds/ccsds_aos/vcdu.h" +#include "common/ccsds/ccsds_tm/vcdu.h" +#include "core/style.h" +#include "logger.h" +#include +#include + +namespace satdump +{ + std::string CCSDSVcidSplitterTool::getName() { return "CCSDS VCID Splitter"; } + + void CCSDSVcidSplitterTool::renderMenu(std::shared_ptr &container, bool is_busy) + { + if (is_busy) + style::beginDisabled(); + + if (ImGui::RadioButton("AOS", cadu_mode == 0)) + cadu_mode = 0; + if (ImGui::RadioButton("TM", cadu_mode == 1)) + cadu_mode = 1; + + ImGui::InputInt("CADU Width (bits)", &cadu_size); + + if (ImGui::Button("Perform")) + should_process = true; + + if (is_busy) + style::endDisabled(); + } + + bool CCSDSVcidSplitterTool::needToProcess() { return should_process; } + + void CCSDSVcidSplitterTool::setProcessed() { should_process = false; } + + void CCSDSVcidSplitterTool::process(std::shared_ptr &container, float &process_progress) + { + uint8_t *ptr = container->get_ptr(); + size_t size = container->get_ptr_size(); + + std::map vcid_counts; + std::map> output_files; + + size_t current_ptr = 0; + while (current_ptr < size) + { + size_t csize = std::min(cadu_size / 8, size - current_ptr); + if (cadu_size / 8 != csize) + break; + + uint8_t *ptr_pos = ptr + current_ptr; + + int vcid = 0; + if (cadu_mode == 0) + vcid = ccsds::ccsds_aos::parseVCDU(ptr_pos).vcid; + else if (cadu_mode == 1) + vcid = ccsds::ccsds_tm::parseVCDU(ptr_pos).vcid; + + if (output_files.count(vcid) == 0) + { + output_files.emplace(vcid, std::pair{"", std::ofstream()}); + vcid_counts.emplace(vcid, 0); + + char name[1000]; + tmpnam(name); + std::string tmpfile = name; + output_files[vcid].first = tmpfile; + output_files[vcid].second = std::ofstream(tmpfile, std::ios::binary); + } + + output_files[vcid].second.write((char *)ptr_pos, cadu_size / 8); + vcid_counts[vcid]++; + + current_ptr += csize; + + process_progress = double(current_ptr) / double(size); + } + + for (auto &f : output_files) + { + f.second.second.close(); + std::shared_ptr newbitc = + std::make_shared("VCID " + std::to_string(f.first) + " (" + std::to_string(vcid_counts[f.first]) + ")", f.second.first); + newbitc->d_bitperiod = cadu_size; + newbitc->init_bitperiod(); + newbitc->d_is_temporary = true; + + if (container->bitview != nullptr) + ((BitViewHandler *)container->bitview)->addSubHandler(std::make_shared(newbitc)); + else + logger->error("Can't add container!"); + } + } +} // namespace satdump \ No newline at end of file diff --git a/plugins/bitview_app/tools/ccsds_vcid_splitter/ccsds_vcid_splitter.h b/plugins/bitview_app/tools/ccsds_vcid_splitter/ccsds_vcid_splitter.h new file mode 100644 index 000000000..2f3c6ed2a --- /dev/null +++ b/plugins/bitview_app/tools/ccsds_vcid_splitter/ccsds_vcid_splitter.h @@ -0,0 +1,22 @@ +#pragma once + +#include "tool.h" + +namespace satdump +{ + class CCSDSVcidSplitterTool : public BitViewTool + { + private: + int cadu_mode = 0; + int cadu_size = 8192; + + bool should_process = false; + + public: + std::string getName(); + void renderMenu(std::shared_ptr &container, bool is_busy); + bool needToProcess(); + void setProcessed(); + void process(std::shared_ptr &container, float &process_progress); + }; +} // namespace satdump \ No newline at end of file diff --git a/plugins/bitview_app/tools/deframer.h b/plugins/bitview_app/tools/deframer.h deleted file mode 100644 index 8d746aa97..000000000 --- a/plugins/bitview_app/tools/deframer.h +++ /dev/null @@ -1,111 +0,0 @@ -#pragma once - -#include "common/simple_deframer.h" -#include "core/style.h" -#include "imgui/imgui_stdlib.h" -#include "tool.h" -#include -#include - -namespace satdump -{ - class DeframerTool : public BitViewTool - { - private: - std::string deframer_syncword = "0x1acffc1d"; - int deframer_syncword_size = 32; - int deframer_syncword_framesize = 8192; - int deframer_current_frames = 0; - int deframer_threshold = 0; - bool deframer_byte_aligned = false; - bool deframer_soft_bits_in = false; - - bool should_process = false; - - public: - std::string getName() { return "Deframer"; } - - void renderMenu(std::shared_ptr &container, bool is_busy) - { - if (is_busy) - style::beginDisabled(); - - ImGui::InputText("Syncword", &deframer_syncword); - ImGui::InputInt("Syncword Size", &deframer_syncword_size); - ImGui::InputInt("Frame Size (Bits)", &deframer_syncword_framesize); - ImGui::InputInt("Threshold", &deframer_threshold); - ImGui::Checkbox("Byte Aligned", &deframer_byte_aligned); - ImGui::Checkbox("Soft Bits In", &deframer_soft_bits_in); - - if (ImGui::Button("DeframeTest")) - should_process = true; - - ImGui::Text("Frames : %d", deframer_current_frames); - - if (is_busy) - style::endDisabled(); - } - - bool needToProcess() { return should_process; } - - void setProcessed() { should_process = false; } - - void process(std::shared_ptr &container, float &process_progress) - { - uint8_t *ptr = container->get_ptr(); - size_t size = container->get_ptr_size(); - - char name[1000]; - tmpnam(name); - std::string tmpfile = name; - std::ofstream file_out(tmpfile, std::ios::binary); - - char *syncword_endptr; - uint64_t syncword = strtoull(deframer_syncword.c_str(), &syncword_endptr, 16); - if (*syncword_endptr != 0) - { - logger->error("Cannot parse syncword!"); - return; - } - - def::SimpleDeframer def_test(syncword, deframer_syncword_size, deframer_syncword_framesize, deframer_threshold, deframer_byte_aligned, deframer_soft_bits_in); - deframer_current_frames = 0; - size_t current_ptr = 0; - - while (current_ptr < size) - { - size_t csize = std::min(8192, size - current_ptr); - auto vf = def_test.work(ptr + current_ptr, csize); - current_ptr += csize; - - for (auto &f : vf) - file_out.write((char *)f.data(), f.size()); - deframer_current_frames += vf.size(); - - process_progress = double(current_ptr) / double(size); - } - - file_out.close(); - std::shared_ptr newbitc; - - try - { - newbitc = std::make_shared("Deframed (" + deframer_syncword + " , " + std::to_string(deframer_syncword_framesize) + ")", tmpfile); - } - catch (std::exception &e) - { - logger->error("Error loading deframed data: %s", e.what()); - return; - } - - newbitc->d_bitperiod = deframer_syncword_framesize; - newbitc->init_bitperiod(); - newbitc->d_is_temporary = true; - - if (container->bitview != nullptr) - ((BitViewHandler *)container->bitview)->addSubHandler(std::make_shared(newbitc)); - else - logger->error("Can't add container!"); - } - }; -} // namespace satdump \ No newline at end of file diff --git a/plugins/bitview_app/tools/deframer/deframer.cpp b/plugins/bitview_app/tools/deframer/deframer.cpp new file mode 100644 index 000000000..48b67e1e2 --- /dev/null +++ b/plugins/bitview_app/tools/deframer/deframer.cpp @@ -0,0 +1,95 @@ +#include "deframer.h" +#include "common/simple_deframer.h" +#include "core/style.h" +#include "imgui/imgui_stdlib.h" +#include "logger.h" +#include +#include + +namespace satdump +{ + std::string DeframerTool::getName() { return "Deframer"; } + + void DeframerTool::renderMenu(std::shared_ptr &container, bool is_busy) + { + if (is_busy) + style::beginDisabled(); + + ImGui::InputText("Syncword", &deframer_syncword); + ImGui::InputInt("Syncword Size", &deframer_syncword_size); + ImGui::InputInt("Frame Size (Bits)", &deframer_syncword_framesize); + ImGui::InputInt("Threshold", &deframer_threshold); + ImGui::Checkbox("Byte Aligned", &deframer_byte_aligned); + ImGui::Checkbox("Soft Bits In", &deframer_soft_bits_in); + + if (ImGui::Button("DeframeTest")) + should_process = true; + + ImGui::Text("Frames : %d", deframer_current_frames); + + if (is_busy) + style::endDisabled(); + } + + bool DeframerTool::needToProcess() { return should_process; } + + void DeframerTool::setProcessed() { should_process = false; } + + void DeframerTool::process(std::shared_ptr &container, float &process_progress) + { + uint8_t *ptr = container->get_ptr(); + size_t size = container->get_ptr_size(); + + char name[1000]; + tmpnam(name); + std::string tmpfile = name; + std::ofstream file_out(tmpfile, std::ios::binary); + + char *syncword_endptr; + uint64_t syncword = strtoull(deframer_syncword.c_str(), &syncword_endptr, 16); + if (*syncword_endptr != 0) + { + logger->error("Cannot parse syncword!"); + return; + } + + def::SimpleDeframer def_test(syncword, deframer_syncword_size, deframer_syncword_framesize, deframer_threshold, deframer_byte_aligned, deframer_soft_bits_in); + deframer_current_frames = 0; + size_t current_ptr = 0; + + while (current_ptr < size) + { + size_t csize = std::min(8192, size - current_ptr); + auto vf = def_test.work(ptr + current_ptr, csize); + current_ptr += csize; + + for (auto &f : vf) + file_out.write((char *)f.data(), f.size()); + deframer_current_frames += vf.size(); + + process_progress = double(current_ptr) / double(size); + } + + file_out.close(); + std::shared_ptr newbitc; + + try + { + newbitc = std::make_shared("Deframed (" + deframer_syncword + " , " + std::to_string(deframer_syncword_framesize) + ")", tmpfile); + } + catch (std::exception &e) + { + logger->error("Error loading deframed data: %s", e.what()); + return; + } + + newbitc->d_bitperiod = deframer_syncword_framesize; + newbitc->init_bitperiod(); + newbitc->d_is_temporary = true; + + if (container->bitview != nullptr) + ((BitViewHandler *)container->bitview)->addSubHandler(std::make_shared(newbitc)); + else + logger->error("Can't add container!"); + } +} // namespace satdump \ No newline at end of file diff --git a/plugins/bitview_app/tools/deframer/deframer.h b/plugins/bitview_app/tools/deframer/deframer.h new file mode 100644 index 000000000..f312c0b20 --- /dev/null +++ b/plugins/bitview_app/tools/deframer/deframer.h @@ -0,0 +1,27 @@ +#pragma once + +#include "tool.h" + +namespace satdump +{ + class DeframerTool : public BitViewTool + { + private: + std::string deframer_syncword = "0x1acffc1d"; + int deframer_syncword_size = 32; + int deframer_syncword_framesize = 8192; + int deframer_current_frames = 0; + int deframer_threshold = 0; + bool deframer_byte_aligned = false; + bool deframer_soft_bits_in = false; + + bool should_process = false; + + public: + std::string getName(); + void renderMenu(std::shared_ptr &container, bool is_busy); + bool needToProcess(); + void setProcessed(); + void process(std::shared_ptr &container, float &process_progress); + }; +} // namespace satdump \ No newline at end of file diff --git a/plugins/bitview_app/tools/diff_decode.h b/plugins/bitview_app/tools/diff_decode.h deleted file mode 100644 index 6748eeafa..000000000 --- a/plugins/bitview_app/tools/diff_decode.h +++ /dev/null @@ -1,94 +0,0 @@ -#pragma once - -#include "tool.h" -#include "imgui/imgui_stdlib.h" -#include -#include "common/codings/differential/nrzm.h" -#include "core/style.h" - -namespace satdump -{ - class DifferentialTool : public BitViewTool - { - private: - int diff_mode = 0; - - bool should_process = false; - - public: - std::string getName() { return "Differential Decoder"; } - - void renderMenu(std::shared_ptr &container, bool is_busy) - { - if (is_busy) - style::beginDisabled(); - - if (ImGui::RadioButton("NRZ-M", diff_mode == 0)) - diff_mode = 0; - ImGui::SameLine(); - if (ImGui::RadioButton("NRZ-S", diff_mode == 1)) - diff_mode = 1; - - if (ImGui::Button("Differential Decode")) - should_process = true; - - if (is_busy) - style::endDisabled(); - } - - bool needToProcess() - { - return should_process; - } - - void setProcessed() - { - should_process = false; - } - - void process(std::shared_ptr &container, float &process_progress) - { - uint8_t *ptr = container->get_ptr(); - size_t size = container->get_ptr_size(); - - char name[1000]; - tmpnam(name); - std::string tmpfile = name; - std::ofstream file_out(tmpfile, std::ios::binary); - diff::NRZMDiff nrzm_decoder; - - uint8_t tmp_buf[8192]; - - size_t current_ptr = 0; - while (current_ptr < size) - { - size_t csize = std::min(8192, size - current_ptr); - - memcpy(tmp_buf, ptr + current_ptr, csize); - current_ptr += csize; - - nrzm_decoder.decode(tmp_buf, csize); - - if (diff_mode == 1) - for (int i = 0; i < csize; i++) - tmp_buf[i] ^= 0xFF; - - file_out.write((char *)tmp_buf, csize); - - process_progress = double(current_ptr) / double(size); - } - - file_out.close(); - - std::shared_ptr newbitc = std::make_shared(container->getName() + (diff_mode == 1 ? " NRZ-S" : " NRZ-M"), tmpfile); - newbitc->d_bitperiod = container->d_bitperiod; - newbitc->init_bitperiod(); - newbitc->d_is_temporary = true; - - if (container->bitview != nullptr) - ((BitViewHandler *)container->bitview)->addSubHandler(std::make_shared(newbitc)); - else - logger->error("Can't add container!"); - } - }; -} \ No newline at end of file diff --git a/plugins/bitview_app/tools/diff_decode/diff_decode.cpp b/plugins/bitview_app/tools/diff_decode/diff_decode.cpp new file mode 100644 index 000000000..cb13556e9 --- /dev/null +++ b/plugins/bitview_app/tools/diff_decode/diff_decode.cpp @@ -0,0 +1,78 @@ +#include "diff_decode.h" +#include "common/codings/differential/nrzm.h" +#include "core/style.h" +#include "imgui/imgui_stdlib.h" +#include "logger.h" +#include + +namespace satdump +{ + std::string DifferentialTool::getName() { return "Differential Decoder"; } + + void DifferentialTool::renderMenu(std::shared_ptr &container, bool is_busy) + { + if (is_busy) + style::beginDisabled(); + + if (ImGui::RadioButton("NRZ-M", diff_mode == 0)) + diff_mode = 0; + ImGui::SameLine(); + if (ImGui::RadioButton("NRZ-S", diff_mode == 1)) + diff_mode = 1; + + if (ImGui::Button("Differential Decode")) + should_process = true; + + if (is_busy) + style::endDisabled(); + } + + bool DifferentialTool::needToProcess() { return should_process; } + + void DifferentialTool::setProcessed() { should_process = false; } + + void DifferentialTool::process(std::shared_ptr &container, float &process_progress) + { + uint8_t *ptr = container->get_ptr(); + size_t size = container->get_ptr_size(); + + char name[1000]; + tmpnam(name); + std::string tmpfile = name; + std::ofstream file_out(tmpfile, std::ios::binary); + diff::NRZMDiff nrzm_decoder; + + uint8_t tmp_buf[8192]; + + size_t current_ptr = 0; + while (current_ptr < size) + { + size_t csize = std::min(8192, size - current_ptr); + + memcpy(tmp_buf, ptr + current_ptr, csize); + current_ptr += csize; + + nrzm_decoder.decode(tmp_buf, csize); + + if (diff_mode == 1) + for (int i = 0; i < csize; i++) + tmp_buf[i] ^= 0xFF; + + file_out.write((char *)tmp_buf, csize); + + process_progress = double(current_ptr) / double(size); + } + + file_out.close(); + + std::shared_ptr newbitc = std::make_shared(container->getName() + (diff_mode == 1 ? " NRZ-S" : " NRZ-M"), tmpfile); + newbitc->d_bitperiod = container->d_bitperiod; + newbitc->init_bitperiod(); + newbitc->d_is_temporary = true; + + if (container->bitview != nullptr) + ((BitViewHandler *)container->bitview)->addSubHandler(std::make_shared(newbitc)); + else + logger->error("Can't add container!"); + } +} // namespace satdump \ No newline at end of file diff --git a/plugins/bitview_app/tools/diff_decode/diff_decode.h b/plugins/bitview_app/tools/diff_decode/diff_decode.h new file mode 100644 index 000000000..31d6b2c22 --- /dev/null +++ b/plugins/bitview_app/tools/diff_decode/diff_decode.h @@ -0,0 +1,20 @@ +#pragma once + +#include "tool.h" + +namespace satdump +{ + class DifferentialTool : public BitViewTool + { + private: + int diff_mode = 0; + bool should_process = false; + + public: + std::string getName(); + void renderMenu(std::shared_ptr &container, bool is_busy); + bool needToProcess(); + void setProcessed(); + void process(std::shared_ptr &container, float &process_progress); + }; +} // namespace satdump \ No newline at end of file diff --git a/plugins/bitview_app/tools/soft2hard.h b/plugins/bitview_app/tools/soft2hard.h deleted file mode 100644 index 95a649824..000000000 --- a/plugins/bitview_app/tools/soft2hard.h +++ /dev/null @@ -1,92 +0,0 @@ -#pragma once - -#include "tool.h" -#include "imgui/imgui_stdlib.h" -#include -#include "core/style.h" - -namespace satdump -{ - class Soft2HardTool : public BitViewTool - { - private: - int diff_mode = 0; - - bool should_process = false; - - public: - std::string getName() { return "Soft To Hard"; } - - void renderMenu(std::shared_ptr &container, bool is_busy) - { - if (is_busy) - style::beginDisabled(); - - if (ImGui::Button("Soft To Hard")) - should_process = true; - - if (is_busy) - style::endDisabled(); - } - - bool needToProcess() - { - return should_process; - } - - void setProcessed() - { - should_process = false; - } - - void process(std::shared_ptr &container, float &process_progress) - { - uint8_t *ptr = container->get_ptr(); - size_t size = container->get_ptr_size(); - - char name[1000]; - tmpnam(name); - std::string tmpfile = name; - std::ofstream file_out(tmpfile, std::ios::binary); - - int bitpos = 0; - uint8_t tmp_buf = 0; - - size_t current_ptr = 0; - while (current_ptr < size) - { - size_t csize = std::min(8192, size - current_ptr); - - int8_t *ptr_pos = (int8_t *)ptr + current_ptr; - - for (int i = 0; i < csize; i++) - { - tmp_buf = tmp_buf << 1 | (ptr_pos[i] >= 0); - bitpos++; - - if (bitpos == 8) - { - file_out.write((char *)&tmp_buf, 1); - bitpos = 0; - } - } - - current_ptr += csize; - - process_progress = double(current_ptr) / double(size); - } - - file_out.close(); - - std::shared_ptr newbitc = std::make_shared(container->getName() + " Hard", tmpfile); - newbitc->d_bitperiod = container->d_bitperiod / 8; - newbitc->init_bitperiod(); - newbitc->d_is_temporary = true; - - if (container->bitview != nullptr) - ((BitViewHandler *)container->bitview)->addSubHandler(std::make_shared(newbitc)); - else - logger->error("Can't add container!"); - } - }; -} \ No newline at end of file diff --git a/plugins/bitview_app/tools/soft2hard/soft2.hard.cpp b/plugins/bitview_app/tools/soft2hard/soft2.hard.cpp new file mode 100644 index 000000000..09c539bdf --- /dev/null +++ b/plugins/bitview_app/tools/soft2hard/soft2.hard.cpp @@ -0,0 +1,75 @@ +#include "core/style.h" +#include "logger.h" +#include "soft2hard.h" +#include + +namespace satdump +{ + std::string Soft2HardTool::getName() { return "Soft To Hard"; } + + void Soft2HardTool::renderMenu(std::shared_ptr &container, bool is_busy) + { + if (is_busy) + style::beginDisabled(); + + if (ImGui::Button("Soft To Hard")) + should_process = true; + + if (is_busy) + style::endDisabled(); + } + + bool Soft2HardTool::needToProcess() { return should_process; } + + void Soft2HardTool::setProcessed() { should_process = false; } + + void Soft2HardTool::process(std::shared_ptr &container, float &process_progress) + { + uint8_t *ptr = container->get_ptr(); + size_t size = container->get_ptr_size(); + + char name[1000]; + tmpnam(name); + std::string tmpfile = name; + std::ofstream file_out(tmpfile, std::ios::binary); + + int bitpos = 0; + uint8_t tmp_buf = 0; + + size_t current_ptr = 0; + while (current_ptr < size) + { + size_t csize = std::min(8192, size - current_ptr); + + int8_t *ptr_pos = (int8_t *)ptr + current_ptr; + + for (int i = 0; i < csize; i++) + { + tmp_buf = tmp_buf << 1 | (ptr_pos[i] >= 0); + bitpos++; + + if (bitpos == 8) + { + file_out.write((char *)&tmp_buf, 1); + bitpos = 0; + } + } + + current_ptr += csize; + + process_progress = double(current_ptr) / double(size); + } + + file_out.close(); + + std::shared_ptr newbitc = std::make_shared(container->getName() + " Hard", tmpfile); + newbitc->d_bitperiod = container->d_bitperiod / 8; + newbitc->init_bitperiod(); + newbitc->d_is_temporary = true; + + if (container->bitview != nullptr) + ((BitViewHandler *)container->bitview)->addSubHandler(std::make_shared(newbitc)); + else + logger->error("Can't add container!"); + } +} // namespace satdump \ No newline at end of file diff --git a/plugins/bitview_app/tools/soft2hard/soft2hard.h b/plugins/bitview_app/tools/soft2hard/soft2hard.h new file mode 100644 index 000000000..0ba52e872 --- /dev/null +++ b/plugins/bitview_app/tools/soft2hard/soft2hard.h @@ -0,0 +1,20 @@ +#pragma once + +#include "tool.h" + +namespace satdump +{ + class Soft2HardTool : public BitViewTool + { + private: + int diff_mode = 0; + bool should_process = false; + + public: + std::string getName(); + void renderMenu(std::shared_ptr &container, bool is_busy); + bool needToProcess(); + void setProcessed(); + void process(std::shared_ptr &container, float &process_progress); + }; +} // namespace satdump \ No newline at end of file diff --git a/src-core/explorer/dsp/newrec.h b/src-core/explorer/dsp/newrec.h index d7587d036..d682014d3 100644 --- a/src-core/explorer/dsp/newrec.h +++ b/src-core/explorer/dsp/newrec.h @@ -13,7 +13,7 @@ #include "common/widgets/waterfall_plot.h" #include -#include "task_queue.h" +#include "utils/task_queue.h" // TODOREWORK, move into plugin? Or Core? namespace satdump diff --git a/src-core/explorer/dsp/task_queue.h b/src-core/explorer/dsp/task_queue.h deleted file mode 100644 index f0965f1d8..000000000 --- a/src-core/explorer/dsp/task_queue.h +++ /dev/null @@ -1,76 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include - -namespace satdump -{ - class TaskQueue - { - private: - std::thread task_thread; - std::mutex queue_mtx; - std::queue> task_queue; - - bool thread_exited = true; - - private: - void threadFunc() - { - recheck: - queue_mtx.lock(); - bool queue_has_data = task_queue.size() > 0; - queue_mtx.unlock(); - - if (queue_has_data) - { - queue_mtx.lock(); - auto task = task_queue.front(); - task_queue.pop(); - queue_mtx.unlock(); - - try - { - task(); - } - catch (std::exception &e) - { - // TODOREWORK? - } - - goto recheck; - } - - thread_exited = true; - } - - public: - TaskQueue() {} - - ~TaskQueue() - { - if (task_thread.joinable()) - task_thread.join(); - } - - void push(std::function task) - { - queue_mtx.lock(); - - task_queue.push(task); - - if (thread_exited) - { - if (task_thread.joinable()) - task_thread.join(); - thread_exited = false; - task_thread = std::thread(&TaskQueue::threadFunc, this); - } - - queue_mtx.unlock(); - } - }; -} // namespace satdump \ No newline at end of file diff --git a/src-core/explorer/explorer.h b/src-core/explorer/explorer.h index 6902b7383..e9ff9d366 100644 --- a/src-core/explorer/explorer.h +++ b/src-core/explorer/explorer.h @@ -1,10 +1,9 @@ #pragma once #include "common/widgets/menuitem_fileopen.h" -#include "dsp/task_queue.h" #include "handlers/handler.h" +#include "utils/task_queue.h" -#include "imgui/dialogs/widget.h" #include #include diff --git a/src-core/utils/binary.h b/src-core/utils/binary.h index bac3466d9..ab1148f78 100644 --- a/src-core/utils/binary.h +++ b/src-core/utils/binary.h @@ -7,7 +7,7 @@ namespace satdump { template - inline bool getBit(T &data, int &bit) + inline bool getBit(T &data, int bit) { return (data >> bit) & 1; } diff --git a/src-core/utils/task_queue.cpp b/src-core/utils/task_queue.cpp new file mode 100644 index 000000000..499b9f12d --- /dev/null +++ b/src-core/utils/task_queue.cpp @@ -0,0 +1,58 @@ +#include "task_queue.h" + +namespace satdump +{ + TaskQueue::TaskQueue() {} + + TaskQueue::~TaskQueue() + { + if (task_thread.joinable()) + task_thread.join(); + } + + void TaskQueue::threadFunc() + { + recheck: + queue_mtx.lock(); + bool queue_has_data = task_queue.size() > 0; + queue_mtx.unlock(); + + if (queue_has_data) + { + queue_mtx.lock(); + auto task = task_queue.front(); + task_queue.pop(); + queue_mtx.unlock(); + + try + { + task(); + } + catch (std::exception &e) + { + // TODOREWORK? + } + + goto recheck; + } + + thread_exited = true; + } + + void TaskQueue::push(std::function task) + { + queue_mtx.lock(); + + task_queue.push(task); + + if (thread_exited) + { + if (task_thread.joinable()) + task_thread.join(); + thread_exited = false; + task_thread = std::thread(&TaskQueue::threadFunc, this); + } + + queue_mtx.unlock(); + } +} // namespace satdump \ No newline at end of file diff --git a/src-core/utils/task_queue.h b/src-core/utils/task_queue.h new file mode 100644 index 000000000..b492c149a --- /dev/null +++ b/src-core/utils/task_queue.h @@ -0,0 +1,53 @@ +#pragma once + +/** + * @file task_queue.h + * @brief A simple single-thread thread pool. + */ + +#include +#include +#include +#include + +namespace satdump +{ + /** + * @brief A simple thread pool running tasks sequentially + * in a single thread. + * + * This was mostly intended to act as a much more lightweight + * replacement for ctp_stl, as keeping threads lingering is not + * really that useful to simply run some small background jobs. + */ + class TaskQueue + { + private: + std::thread task_thread; + std::mutex queue_mtx; + std::queue> task_queue; + + bool thread_exited = true; + + private: + void threadFunc(); + + public: + /** + * @brief Constructor, starts the internal thread + */ + TaskQueue(); + + /** + * @brief Destructor. Waits for remaining tasks + * before exiting. + */ + ~TaskQueue(); + + /** + * @brief Push a task in the queue. + * @param task the function to push + */ + void push(std::function task); + }; +} // namespace satdump \ No newline at end of file diff --git a/src-core/utils/unit_parser.h b/src-core/utils/unit_parser.h index 29b423c80..360237de7 100644 --- a/src-core/utils/unit_parser.h +++ b/src-core/utils/unit_parser.h @@ -1,16 +1,30 @@ #pragma once +/** + * @file unit_parser.h + * @brief Utilities to help parse physical units + */ + #include #include namespace satdump { + /** + * @brief Unit information struct, that must be provided + * in a vector with all possible options and their corresponding + * power. + */ struct UnitInfo { std::string name; double scale; }; + /** + * @brief Unit declaration (to be used in parseUnitFromString) for + * Meters + */ const std::vector UNIT_METER = { {"Tm", 1e12}, // {"Gm", 1e9}, // @@ -27,6 +41,10 @@ namespace satdump {"pm", 1e-12}, // }; + /** + * @brief Unit declaration (to be used in parseUnitFromString) for + * Hertz + */ const std::vector UNIT_HERTZ = { {"THz", 1e12}, // {"GHz", 1e9}, // @@ -43,5 +61,14 @@ namespace satdump {"pHz", 1e-12}, // }; + /** + * @brief Parse an unit down to its SI base (eg, Hz) + * from a string, for user-friendly input + * + * @param str input string + * @param out output value + * @param unit unit to parse (must contain all expected representations) + * @return true if parsing was sucessful + */ bool parseUnitFromString(std::string str, double &out, std::vector unit); } // namespace satdump \ No newline at end of file