Start adding live back

This commit is contained in:
Aang23 2021-03-22 22:26:21 +01:00
parent ffb3cf3101
commit cd22ff265d
9 changed files with 237 additions and 16 deletions

View file

@ -24,6 +24,10 @@ void ProcessingModule::setOutputType(ModuleDataType type)
output_data_type = type;
}
void ProcessingModule::init()
{
}
void ProcessingModule::drawUI()
{
}

View file

@ -8,6 +8,7 @@
#include <atomic>
#include "imgui/imgui_flags.h"
#include "dll_export.h"
#include "modules/buffer.h"
#define WRITE_IMAGE(image, path) \
image.save_png(std::string(path).c_str()); \
@ -15,9 +16,9 @@
enum ModuleDataType
{
DATA_STREAM, // Generic data, for which a circular buffer will be used
DATA_STREAM, // Generic data, for which a circular buffer will be used
DATA_DSP_STREAM, // DSP Data using the specialized buffer and complex floats
DATA_FILE, // Just generic data from a file
DATA_FILE, // Just generic data from a file
};
class ProcessingModule
@ -26,7 +27,7 @@ protected:
const std::string d_input_file;
const std::string d_output_file_hint;
std::vector<std::string> d_output_files;
const std::map<std::string, std::string> d_parameters;
std::map<std::string, std::string> d_parameters;
ModuleDataType input_data_type, output_data_type;
public:
@ -35,6 +36,7 @@ public:
virtual std::vector<ModuleDataType> getOutputTypes() { return {DATA_FILE}; }
void setInputType(ModuleDataType type);
void setOutputType(ModuleDataType type);
virtual void init();
virtual void process() = 0;
virtual void drawUI() = 0;
std::vector<std::string> getOutputs();
@ -42,6 +44,8 @@ public:
public:
//std::shared_ptr<satdump::Pipe> input_fifo;
//std::shared_ptr<satdump::Pipe> output_fifo;
std::shared_ptr<dsp::stream<std::complex<float>>> input_stream;
std::shared_ptr<dsp::stream<std::complex<float>>> output_stream;
std::atomic<bool> input_active;
public:

View file

@ -21,18 +21,22 @@ QPSKDemodModule::QPSKDemodModule(std::string input_file, std::string output_file
d_loop_bw(std::stof(parameters["costas_bw"])),
d_buffer_size(std::stoi(parameters["buffer_size"])),
d_dc_block(parameters.count("dc_block") > 0 ? std::stoi(parameters["dc_block"]) : 0)
{
// Buffers
sym_buffer = new int8_t[d_buffer_size * 2];
}
void QPSKDemodModule::init()
{
// Init DSP blocks
file_source = std::make_shared<dsp::FileSourceBlock>(d_input_file, dsp::BasebandTypeFromString(parameters["baseband_format"]), d_buffer_size);
if (input_data_type == DATA_FILE)
file_source = std::make_shared<dsp::FileSourceBlock>(d_input_file, dsp::BasebandTypeFromString(d_parameters["baseband_format"]), d_buffer_size);
if (d_dc_block)
dcb = std::make_shared<dsp::DCBlockerBlock>(file_source->output_stream, 1024, true);
agc = std::make_shared<dsp::AGCBlock>(d_dc_block ? dcb->output_stream : file_source->output_stream, d_agc_rate, 1.0f, 1.0f, 65536);
dcb = std::make_shared<dsp::DCBlockerBlock>(input_data_type == DATA_DSP_STREAM ? input_stream : file_source->output_stream, 1024, true);
agc = std::make_shared<dsp::AGCBlock>(d_dc_block ? dcb->output_stream : (input_data_type == DATA_DSP_STREAM ? input_stream : file_source->output_stream), d_agc_rate, 1.0f, 1.0f, 65536);
rrc = std::make_shared<dsp::CCFIRBlock>(agc->output_stream, 1, libdsp::firgen::root_raised_cosine(1, d_samplerate, d_symbolrate, d_rrc_alpha, d_rrc_taps));
pll = std::make_shared<dsp::CostasLoopBlock>(rrc->output_stream, d_loop_bw, 4);
rec = std::make_shared<dsp::CCMMClockRecoveryBlock>(pll->output_stream, (float)d_samplerate / (float)d_symbolrate, pow(8.7e-3, 2) / 4.0, 0.5f, 8.7e-3, 0.005f);
// Buffers
sym_buffer = new int8_t[d_buffer_size * 2];
}
std::vector<ModuleDataType> QPSKDemodModule::getInputTypes()
@ -57,9 +61,6 @@ void QPSKDemodModule::process()
else
filesize = 0;
//if (input_data_type == DATA_FILE)
// data_in = std::ifstream(d_input_file, std::ios::binary);
data_out = std::ofstream(d_output_file_hint + ".soft", std::ios::binary);
d_output_files.push_back(d_output_file_hint + ".soft");
@ -70,7 +71,8 @@ void QPSKDemodModule::process()
time_t lastTime = 0;
// Start
file_source->start();
if (input_data_type == DATA_FILE)
file_source->start();
if (d_dc_block)
dcb->start();
agc->start();
@ -79,7 +81,7 @@ void QPSKDemodModule::process()
rec->start();
int dat_size = 0;
while (/*input_data_type == DATA_STREAM ? input_active.load() : */ !file_source->eof())
while (input_data_type == DATA_FILE ? !file_source->eof() : input_active.load())
{
dat_size = rec->output_stream->read();
@ -96,7 +98,8 @@ void QPSKDemodModule::process()
data_out.write((char *)sym_buffer, dat_size * 2);
progress = file_source->getPosition();
if (input_data_type == DATA_FILE)
progress = file_source->getPosition();
if (time(NULL) % 10 == 0 && lastTime != time(NULL))
{
lastTime = time(NULL);
@ -107,7 +110,8 @@ void QPSKDemodModule::process()
logger->info("Demodulation finished");
// Stop
file_source->stop();
if (input_data_type == DATA_FILE)
file_source->stop();
if (d_dc_block)
dcb->stop();
agc->stop();

View file

@ -50,6 +50,7 @@ protected:
public:
QPSKDemodModule(std::string input_file, std::string output_file_hint, std::map<std::string, std::string> parameters);
~QPSKDemodModule();
void init();
void process();
void drawUI();
std::vector<ModuleDataType> getInputTypes();

View file

@ -54,6 +54,8 @@ void Pipeline::run(std::string input_file,
module->setInputType(DATA_FILE);
module->setOutputType(DATA_FILE);
module->init();
if (ui)
{
uiCallListMutex->lock();

194
src-ui/live.cpp Normal file
View file

@ -0,0 +1,194 @@
#include "live.h"
#include "imgui/imgui.h"
#include "global.h"
#include "pipeline.h"
#include <cstring>
#include "logger.h"
#include "portable-file-dialogs.h"
#include "processing.h"
#include <filesystem>
#ifdef BUILD_LIVE
int device_id = 0;
void renderLiveProcessing()
{
ImGui::BeginGroup();
{
std::string names;
std::map<int, std::string> id_table;
for (int i = 0, y = 0; i < pipelines.size(); i++)
{
if (pipelines[i].live)
{
names += pipelines[i].readable_name + '\0';
id_table.insert({y++, pipelines[i].name});
}
}
ImGui::Text("Pipeline : ");
ImGui::SameLine();
if (ImGui::Combo("##pipeline", &pipeline_id, names.c_str()))
{
downlink_pipeline = id_table[pipeline_id];
std::vector<Pipeline>::iterator it = std::find_if(pipelines.begin(),
pipelines.end(),
[](const Pipeline &e) {
return e.name == downlink_pipeline;
});
std::memcpy(samplerate, std::to_string(it->default_samplerate).c_str(), std::to_string(it->default_samplerate).length());
frequency = it->frequencies[frequency_id];
}
// ImGui::EndCombo();
}
ImGui::EndGroup();
ImGui::BeginGroup();
{
ImGui::Text("Output dir : ");
ImGui::SameLine();
if (ImGui::Button("Select Output"))
{
logger->debug("Opening file dialog");
auto result = pfd::select_folder("Open output directory", ".");
while (result.ready(1000))
{
}
if (result.result().size() > 0)
output_file = result.result();
logger->debug("Dir " + output_file);
}
ImGui::SameLine();
ImGui::Text(output_file.c_str());
}
ImGui::EndGroup();
ImGui::Separator();
ImGui::BeginGroup();
{
ImGui::Text("Device : ");
ImGui::SameLine();
{
std::string names = ""; // = "baseband\0";
//std::vector<Pipeline>::iterator it = std::find_if(pipelines.begin(),
// pipelines.end(),
/// [](const Pipeline &e) {
// return e.name == downlink_pipeline;
// });
//if (it != pipelines.end())
// for (int i = 0; i < it->frequencies.size(); i++)
// {
// names += std::to_string(it->frequencies[i]) + " Mhz" + '\0';
// }
if (ImGui::Combo("##device", &device_id, names.c_str()))
{
//frequency = it->frequencies[frequency_id];
}
}
ImGui::Text("Frequency : ");
ImGui::SameLine();
{
std::string names; // = "baseband\0";
std::vector<Pipeline>::iterator it = std::find_if(pipelines.begin(),
pipelines.end(),
[](const Pipeline &e) {
return e.name == downlink_pipeline;
});
if (it != pipelines.end())
for (int i = 0; i < it->frequencies.size(); i++)
{
names += std::to_string(it->frequencies[i]) + " Mhz" + '\0';
}
if (ImGui::Combo("##frequency", &frequency_id, names.c_str()))
{
frequency = it->frequencies[frequency_id];
}
}
ImGui::Checkbox("DC Block", &dc_block);
ImGui::Text("Samplerate (Hz / SPS)");
ImGui::SameLine();
ImGui::InputText("##samplerate", samplerate, 100);
if (ImGui::Button("Start"))
{
logger->debug("Starting livedemod...");
if (output_file == "")
{
sprintf(error_message, "Please select an output file!");
}
else if (downlink_pipeline == "")
{
sprintf(error_message, "Please select a pipeline!");
}
else if (frequency <= 0)
{
sprintf(error_message, "Please select a frequency!");
}
else if (std::stoi(samplerate) <= 0)
{
sprintf(error_message, "Please select a samplerate!");
}
else
{
if (!std::filesystem::exists(output_file))
std::filesystem::create_directory(output_file);
logger->info(downlink_pipeline);
std::vector<Pipeline>::iterator it = std::find_if(pipelines.begin(),
pipelines.end(),
[](const Pipeline &e) {
return e.name == downlink_pipeline;
});
if (it != pipelines.end())
{
parameters.emplace("samplerate", std::string(samplerate));
parameters.emplace("baseband_format", "f32");
parameters.emplace("dc_block", dc_block ? "1" : "0");
std::map<std::string, std::string> final_parameters = it->steps[1].modules[0].parameters;
for (const std::pair<std::string, std::string> &param : parameters)
if (final_parameters.count(param.first) > 0)
final_parameters[param.first] = param.second;
else
final_parameters.emplace(param.first, param.second);
logger->debug("Parameters :");
for (const std::pair<std::string, std::string> &param : final_parameters)
logger->debug(" - " + param.first + " : " + param.second);
}
else
{
logger->critical("Pipeline " + downlink_pipeline + " does not exist!");
}
}
}
ImGui::SameLine();
ImGui::TextColored(ImColor::HSV(0 / 360.0, 1, 1, 1.0), error_message);
}
ImGui::EndGroup();
}
#endif

6
src-ui/live.h Normal file
View file

@ -0,0 +1,6 @@
#pragma once
//#define BUILD_LIVE
#ifdef BUILD_LIVE
void renderLiveProcessing();
#endif

View file

@ -10,6 +10,7 @@
#include "init.h"
#include "processing.h"
#include "offline.h"
#include "live.h"
static void glfw_error_callback(int error, const char *description)
{
@ -163,7 +164,11 @@ int main(int argc, char *argv[])
}
if (ImGui::BeginTabItem("Live processing"))
{
#ifdef BUILD_LIVE
renderLiveProcessing();
#else
ImGui::Text("Live support is currently being rewritten, and does not work on Windows yet. If you really need it, please stick to an older version.");
#endif
ImGui::EndTabItem();
}
if (ImGui::BeginTabItem("Credits"))

View file

@ -1,3 +1,4 @@
#include "offline.h"
#include "imgui/imgui.h"
#include "global.h"
#include "pipeline.h"