展示优化
This commit is contained in:
@@ -1,2 +1,31 @@
|
||||
#include "BackEnd.h"
|
||||
|
||||
#include <QMetaObject>
|
||||
Back_End::~Back_End() {
|
||||
stop_mock_thread();
|
||||
}
|
||||
void Back_End::stop_mock_thread() {
|
||||
++mock_generation;
|
||||
QTimer* timer = mock_timer;
|
||||
mock_timer = nullptr;
|
||||
if (timer) {
|
||||
if (timer->thread() == QThread::currentThread()) {
|
||||
timer->stop();
|
||||
delete timer;
|
||||
}
|
||||
else if (mock_thread && mock_thread->isRunning()) {
|
||||
QMetaObject::invokeMethod(timer, [timer]() {
|
||||
timer->stop();
|
||||
delete timer;
|
||||
}, Qt::BlockingQueuedConnection);
|
||||
}
|
||||
else {
|
||||
delete timer;
|
||||
}
|
||||
}
|
||||
if (!mock_thread)
|
||||
return;
|
||||
mock_thread->quit();
|
||||
mock_thread->wait();
|
||||
delete mock_thread;
|
||||
mock_thread = nullptr;
|
||||
}
|
||||
|
||||
@@ -25,28 +25,13 @@ public:
|
||||
QString get_screenshot_save_dir_path();
|
||||
QString get_screenshot_save_file_name();
|
||||
QString get_audio_file_location();
|
||||
void stop_mock_thread() {
|
||||
++mock_generation;
|
||||
if (mock_timer) {
|
||||
mock_timer->stop();
|
||||
mock_timer->disconnect(this);
|
||||
mock_timer->deleteLater();
|
||||
mock_timer = nullptr;
|
||||
}
|
||||
if (mock_thread) {
|
||||
mock_thread->quit();
|
||||
mock_thread->wait();
|
||||
mock_thread = nullptr;
|
||||
}
|
||||
}
|
||||
void stop_mock_thread();
|
||||
Back_End(const Back_End&) = delete;
|
||||
Back_End& operator=(const Back_End&) = delete;
|
||||
void call_back_data_func(int channel, void *pData, int i_length);
|
||||
protected:
|
||||
Back_End();
|
||||
~Back_End() override {
|
||||
stop_mock_thread();
|
||||
}
|
||||
~Back_End() override;
|
||||
QTimer* mock_timer{};
|
||||
std::uint64_t mock_generation{};
|
||||
QThread* mock_thread{};
|
||||
|
||||
@@ -8,9 +8,12 @@
|
||||
#include "SweepFrequencyWidget.h"
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <memory>
|
||||
#include <memory_resource>
|
||||
#include <mutex>
|
||||
#include <QByteArray>
|
||||
#include <QDebug>
|
||||
#include <QMetaObject>
|
||||
#include <QPointer>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
@@ -99,26 +102,59 @@ void push_radio_data(Radio_Widget* rw, Trace_Mode trace_mode) {
|
||||
}
|
||||
rw->progress_bar2->setValue(make_random_value({1, 5}));
|
||||
}
|
||||
void push_radio_data_perf(Radio_Widget* rw, Trace_Mode trace_mode) {
|
||||
struct Mock_Performance_Frame {
|
||||
std::pmr::vector<double> spectrum;
|
||||
double spectrum_middle_power{};
|
||||
renderive::Time_Of_Day waterfall_time;
|
||||
std::pmr::vector<double> waterfall;
|
||||
renderive::Time_Of_Day trace_time;
|
||||
double trace_value{};
|
||||
std::pmr::vector<double> audio;
|
||||
double progress_value{};
|
||||
};
|
||||
struct Mock_Performance_Batch {
|
||||
std::vector<Mock_Performance_Frame> frames;
|
||||
};
|
||||
struct Mock_Delivery_State {
|
||||
std::mutex mutex;
|
||||
std::shared_ptr<Mock_Performance_Batch> latest;
|
||||
bool delivery_posted{};
|
||||
};
|
||||
std::shared_ptr<Mock_Performance_Batch> make_performance_batch(const Mock_Config& config) {
|
||||
auto batch = std::make_shared<Mock_Performance_Batch>();
|
||||
batch->frames.reserve(static_cast<std::size_t>(config.batch_count));
|
||||
for (int i = 0; i < config.batch_count; ++i) {
|
||||
auto spectrum = make_random_data({40, 120}, 1024, renderive::Memory_Domain::Spectrum);
|
||||
double middle_power = spectrum.empty() ? 80.0 : spectrum[spectrum.size() / 2];
|
||||
auto waterfall_time = current_render_time();
|
||||
auto waterfall = make_random_data({0, 160}, 1024, renderive::Memory_Domain::Waterfall);
|
||||
auto trace_time = current_render_time();
|
||||
double trace_value = make_trace_value({-6000, 6000}, config.trace_mode);
|
||||
auto audio = make_random_data({-6000, 6000}, 512, renderive::Memory_Domain::Spectrum);
|
||||
batch->frames.push_back(Mock_Performance_Frame{
|
||||
std::move(spectrum),
|
||||
middle_power,
|
||||
waterfall_time,
|
||||
std::move(waterfall),
|
||||
trace_time,
|
||||
trace_value,
|
||||
std::move(audio),
|
||||
make_random_value({1, 5})
|
||||
});
|
||||
}
|
||||
return batch;
|
||||
}
|
||||
void apply_performance_batch(Radio_Widget* rw, Mock_Performance_Batch& batch) {
|
||||
if (!rw || !rw->spectrogram_line || !rw->water_fall || !rw->time_power || !rw->audio_spectrogram_plot || !rw->progress_bar1 || !rw->progress_bar2)
|
||||
return;
|
||||
{
|
||||
renderive::Range nr = {40, 120};
|
||||
auto data = make_random_data(nr, 1024, renderive::Memory_Domain::Spectrum);
|
||||
double middle_power = data.empty() ? nr.center() : data[data.size() / 2];
|
||||
rw->spectrogram_line->update_samples(std::move(data));
|
||||
rw->progress_bar1->setValue(middle_power);
|
||||
for (auto& frame : batch.frames) {
|
||||
rw->spectrogram_line->update_samples(std::move(frame.spectrum));
|
||||
rw->progress_bar1->setValue(frame.spectrum_middle_power);
|
||||
rw->water_fall->append_row(frame.waterfall_time, std::move(frame.waterfall));
|
||||
rw->time_power->append_sample(frame.trace_time, frame.trace_value);
|
||||
rw->audio_spectrogram_plot->update_samples(std::move(frame.audio));
|
||||
rw->progress_bar2->setValue(frame.progress_value);
|
||||
}
|
||||
{
|
||||
rw->water_fall->append_row(current_render_time(), make_random_data({0, 160}, 1024, renderive::Memory_Domain::Waterfall));
|
||||
}
|
||||
{
|
||||
rw->time_power->append_sample(current_render_time(), make_trace_value({-6000, 6000}, trace_mode));
|
||||
}
|
||||
{
|
||||
rw->audio_spectrogram_plot->update_samples(make_random_data({-6000, 6000}, 512, renderive::Memory_Domain::Spectrum));
|
||||
}
|
||||
rw->progress_bar2->setValue(make_random_value({1, 5}));
|
||||
}
|
||||
}
|
||||
void Back_End::play(const QString& fileName) {
|
||||
@@ -194,16 +230,55 @@ Back_End::Back_End() {
|
||||
QPointer<Radio_Widget> rw = Main_Widget::instance()->radio_widget;
|
||||
if (!rw)
|
||||
return;
|
||||
mock_timer = new QTimer(this);
|
||||
if (!config.performance) {
|
||||
mock_timer = new QTimer(this);
|
||||
mock_timer->setTimerType(Qt::PreciseTimer);
|
||||
QObject::connect(mock_timer, &QTimer::timeout, this, [config, rw]() {
|
||||
for (int i = 0; i < config.batch_count; ++i) {
|
||||
if (!rw)
|
||||
return;
|
||||
push_radio_data(rw.data(), config.trace_mode);
|
||||
}
|
||||
});
|
||||
mock_timer->start(config.interval_ms);
|
||||
return;
|
||||
}
|
||||
auto delivery_state = std::make_shared<Mock_Delivery_State>();
|
||||
mock_thread = new QThread(this);
|
||||
mock_timer = new QTimer;
|
||||
mock_timer->setTimerType(Qt::PreciseTimer);
|
||||
QObject::connect(mock_timer, &QTimer::timeout, this, [config, rw]() {
|
||||
for (int i = 0; i < config.batch_count; ++i) {
|
||||
if (!rw)
|
||||
return;
|
||||
config.performance ? push_radio_data_perf(rw.data(), config.trace_mode) : push_radio_data(rw.data(), config.trace_mode);
|
||||
}
|
||||
mock_timer->setInterval(config.interval_ms);
|
||||
mock_timer->moveToThread(mock_thread);
|
||||
QTimer* timer = mock_timer;
|
||||
QObject::connect(mock_thread, &QThread::started, timer, [timer]() {
|
||||
timer->start();
|
||||
});
|
||||
mock_timer->start(config.interval_ms);
|
||||
QObject::connect(timer, &QTimer::timeout, timer, [this, config, rw, delivery_state, start_generation]() {
|
||||
auto batch = make_performance_batch(config);
|
||||
bool post_delivery = false;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(delivery_state->mutex);
|
||||
delivery_state->latest = std::move(batch);
|
||||
if (!delivery_state->delivery_posted) {
|
||||
delivery_state->delivery_posted = true;
|
||||
post_delivery = true;
|
||||
}
|
||||
}
|
||||
if (!post_delivery)
|
||||
return;
|
||||
QMetaObject::invokeMethod(this, [this, rw, delivery_state, start_generation]() {
|
||||
std::shared_ptr<Mock_Performance_Batch> latest;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(delivery_state->mutex);
|
||||
latest = std::move(delivery_state->latest);
|
||||
delivery_state->delivery_posted = false;
|
||||
}
|
||||
if (start_generation != mock_generation || !rw || !latest)
|
||||
return;
|
||||
apply_performance_batch(rw.data(), *latest);
|
||||
}, Qt::QueuedConnection);
|
||||
});
|
||||
mock_thread->start();
|
||||
});
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user