Compare commits

..

20 Commits

Author SHA1 Message Date
7bbbdded3b add mark positions completed 2026-04-15 13:12:06 +03:00
70e1aa05b4 fix bad size 2026-04-13 17:48:11 +03:00
03fbd2bbb5 fix graph compression 2026-04-09 18:02:38 +03:00
377b7913bb fix compression 2026-04-07 18:52:29 +03:00
a279cdf3e3 add base change marker position 2026-04-07 15:02:06 +03:00
fc8467086a fix test sshd 2026-04-01 11:17:59 +03:00
5eb3f47194 fix test sshd 2026-03-31 17:21:55 +03:00
faf301b801 fix test sshd 2026-03-31 16:48:04 +03:00
df748a7072 fix sshd 2026-03-31 09:57:37 +03:00
29287712b5 fix player 2026-03-31 09:57:31 +03:00
29ff210adb fix play music then changing tabs 2026-03-28 21:56:42 +03:00
e45b65af23 fix show new opened tab 2026-03-28 21:24:44 +03:00
a5f856b224 add base markers 2026-03-27 16:44:36 +03:00
66e1f70141 add audio player 2026-03-27 15:42:08 +03:00
c049455a88 remove old func for compression 2026-03-27 12:52:23 +03:00
cfa39f850b add intefaces plugins 2026-03-20 14:44:16 +03:00
e59fd990a1 add render base plugins 2026-03-19 16:48:20 +03:00
80d65e116e we started scaling up 2026-03-18 08:48:55 +03:00
64d1011acd fix nfd 2026-03-13 17:46:04 +03:00
05738cb839 add creator 2026-03-13 16:44:31 +03:00
68 changed files with 1344 additions and 753 deletions

1
.gitignore vendored
View File

@@ -2,4 +2,3 @@ build
.cache
subprojects/*
!subprojects/*.wrap
src/noinc.hpp

View File

@@ -37,6 +37,7 @@ deps = [
dependency('libpqxx'),
dependency('uuid'),
dependency('threads'),
dependency('gtk+-3.0'),
dependency('OpenGL'),
dependency('sndfile'),
subproject('vertex_engine').get_variable('vertex_engine_dep'),
@@ -52,5 +53,3 @@ deps = [
subdir('src')
subdir('bin')
#############################################################

21
run.sh
View File

@@ -1,21 +0,0 @@
#!/bin/zsh
PROJECT_NAME=$(basename $PWD)
run() {
command meson compile -C build
if [[ -z "$1" ]]; then
cd build
./bin/$PROJECT_NAME
cd ..
else
meson test $1 -C build
fi
}
if [ -d "build" ]; then
run
else
command meson setup build
run
fi

View File

@@ -1,22 +1,33 @@
inc += include_directories('.')
headers = [
############ GUI/COMPONENTS
'monitor/gui/components/audio/audio.hpp',
'monitor/gui/components/file_dialog/file_dialog.hpp',
'monitor/gui/components/markers/markers.hpp',
'monitor/gui/components/spinner/spinner.hpp',
'monitor/gui/win/win.hpp',
'monitor/gui/components/panel/panel.hpp',
'monitor/gui/components/creator/creator.hpp',
'monitor/gui/components/snapshot/snapshot.hpp',
'monitor/gui/components/tabs/tabs.hpp',
'monitor/gui/components/audio/audio.hpp',
'monitor/gui/components/markers/markers.hpp',
'monitor/gui/components/helpers/helpers.hpp',
############ GUI/WIN
'monitor/gui/win/win.hpp',
'monitor/gui/components/tabs/tabs.hpp',
'monitor/gui/components/snapshot/snapshot.hpp',
'monitor/gui/components/base_plugins/base_plugins.hpp',
'monitor/gui/components/base_controls/base_controls.hpp',
'monitor/gui/components/graph/graph.hpp',
'monitor/gui/components/fft_scaled/fft_scaled.hpp',
############ UTILS
'monitor/utils/var.hpp',
'monitor/utils/func.hpp',
'monitor/utils/plugin.hpp',
'monitor/utils/plugins/raw_data/raw_data.hpp',
'monitor/utils/plugins/magnitude/magnitude.hpp',
'monitor/utils/plugins/fft/fft.hpp',
############ LIBS
'monitor/libs/audio/audio.hpp',
'monitor/libs/gtkfd/gtkfd.hpp',
############
# RUN
@@ -25,39 +36,72 @@ headers = [
sources = [
############ GUI/COMPONENTS
'monitor/gui/components/panel/cpp/base.cpp',
'monitor/gui/components/panel/cpp/on_event.cpp',
'monitor/gui/components/panel/cpp/render.cpp',
'monitor/gui/components/creator/cpp/base.cpp',
'monitor/gui/components/creator/cpp/on_event.cpp',
'monitor/gui/components/creator/cpp/render/render.cpp',
'monitor/gui/components/creator/cpp/render/buttons.cpp',
'monitor/gui/components/creator/cpp/render/combo.cpp',
'monitor/gui/components/creator/cpp/render/setup.cpp',
'monitor/gui/components/creator/cpp/render/spinner.cpp',
'monitor/gui/components/snapshot/cpp/base.cpp',
'monitor/gui/components/snapshot/cpp/on_event.cpp',
'monitor/gui/components/snapshot/cpp/render.cpp',
'monitor/gui/components/tabs/cpp/base.cpp',
'monitor/gui/components/tabs/cpp/on_event.cpp',
'monitor/gui/components/tabs/cpp/render.cpp',
'monitor/gui/components/audio/cpp/base.cpp',
'monitor/gui/components/audio/cpp/on_event.cpp',
'monitor/gui/components/audio/cpp/render.cpp',
'monitor/gui/components/file_dialog/file_dialog.cpp',
'monitor/gui/components/markers/cpp/base.cpp',
'monitor/gui/components/markers/cpp/on_event.cpp',
'monitor/gui/components/markers/cpp/render.cpp',
# win
'monitor/gui/win/cpp/base.cpp',
'monitor/gui/win/cpp/on_event.cpp',
'monitor/gui/win/cpp/render.cpp',
# win/panel
'monitor/gui/components/panel/cpp/base.cpp',
'monitor/gui/components/panel/cpp/on_event.cpp',
'monitor/gui/components/panel/cpp/render.cpp',
# win/panel/creator
'monitor/gui/components/creator/cpp/base.cpp',
'monitor/gui/components/creator/cpp/on_event.cpp',
'monitor/gui/components/creator/cpp/render/render.cpp',
'monitor/gui/components/creator/cpp/render/spinner.cpp',
'monitor/gui/components/creator/cpp/render/setup.cpp',
# win/panel/helpers
'monitor/gui/components/helpers/cpp/base.cpp',
'monitor/gui/components/helpers/cpp/on_event.cpp',
'monitor/gui/components/helpers/cpp/render.cpp',
# win/tabs
'monitor/gui/components/tabs/cpp/base.cpp',
'monitor/gui/components/tabs/cpp/on_event.cpp',
'monitor/gui/components/tabs/cpp/render.cpp',
# win/tabs/snapshot
'monitor/gui/components/snapshot/cpp/base.cpp',
'monitor/gui/components/snapshot/cpp/on_event.cpp',
'monitor/gui/components/snapshot/cpp/render.cpp',
# win/tabs/snapshot/base_plugins
'monitor/gui/components/base_plugins/cpp/base.cpp',
'monitor/gui/components/base_plugins/cpp/on_event.cpp',
'monitor/gui/components/base_plugins/cpp/render.cpp',
# win/tabs/snapshot/base_plugins/graph
'monitor/gui/components/graph/cpp/base.cpp',
'monitor/gui/components/graph/cpp/on_event.cpp',
'monitor/gui/components/graph/cpp/render.cpp',
# win/tabs/snapshot/base_plugins/fft_scaled
'monitor/gui/components/fft_scaled/cpp/base.cpp',
'monitor/gui/components/fft_scaled/cpp/on_event.cpp',
'monitor/gui/components/fft_scaled/cpp/render.cpp',
# win/tabs/snapshot/base_controls
'monitor/gui/components/base_controls/cpp/base.cpp',
'monitor/gui/components/base_controls/cpp/on_event.cpp',
'monitor/gui/components/base_controls/cpp/render.cpp',
############ UTILS
'monitor/libs/audio/audio.cpp',
############ GUI/WIN
'monitor/gui/win/cpp/base.cpp',
'monitor/gui/win/cpp/on_event.cpp',
'monitor/gui/win/cpp/render.cpp'
'monitor/libs/gtkfd/gtkfd.cpp',
'monitor/utils/plugins/raw_data/raw_data.cpp',
'monitor/utils/plugins/magnitude/magnitude.cpp',
'monitor/utils/plugins/fft/fft.cpp',
]
lib = library(

View File

@@ -1,8 +1,10 @@
#pragma once
#include <VE.hpp>
#include <harmonica.hpp>
#include "monitor/libs/audio/audio.hpp"
#include "monitor/utils/var.hpp"
#include "monitor/utils/setup.hpp"
namespace monitor::components
{
@@ -11,23 +13,35 @@ namespace monitor::components
VE_OVERIDE();
VE_EVENT_OVERIDE();
public:
void init(std::filesystem::path file);
void set_step(std::size_t step);
void set_pos(double pos);
void set_bs(std::string type, std::size_t bs);
void toggle();
void pause();
void drop();
void set_status(utils::var::STATUS s);
private:
utils::var::STATUS m_status;
utils::var::STATUS m_status = utils::var::STATUS::EMPTY;
libs::audio m_player;
std::filesystem::path m_file;
struct music
{
std::string m_id;
sf::Time m_current_time;
utils::setup m_setup;
} m_current_audio;
std::map<std::string, music> m_audio_data;
std::size_t m_compression = 0;
std::vector<std::string> m_domains = { "time", "frequensy"};
public:
void toggle();
void pause();
// делать
void drop();
void set_pos(double pos);
private:
void callback(sf::Time time, double pos);
void init(std::string snapshot_id, utils::setup& setup);
void change(std::string snapshot_id);
void callback(sf::Time time);
};
}

View File

@@ -6,7 +6,7 @@ namespace monitor::components
void audio::on_attach()
{
CONNECT(this);
m_player.set_callback(std::bind(&audio::callback, this, std::placeholders::_1, std::placeholders::_2));
m_player.set_callback(std::bind(&audio::callback, this, std::placeholders::_1));
m_player.set_device();
}
@@ -31,29 +31,39 @@ namespace monitor::components
m_player.pause();
}
void audio::init(std::filesystem::path file)
void audio::init(std::string snapshot_id, utils::setup& setup)
{
m_file = file;
m_player.set_file(m_file);
m_player.stop();
m_audio_data[snapshot_id] = music{ .m_id = snapshot_id, .m_current_time = sf::Time(), .m_setup = setup };
m_status = utils::var::STATUS::ACTIVE;
}
void audio::set_status(utils::var::STATUS s)
void audio::change(std::string snapshot_id)
{
m_status = s;
m_audio_data[m_current_audio.m_id].m_current_time = m_current_audio.m_current_time;
m_player.stop();
m_current_audio = m_audio_data[snapshot_id];
m_player.set_file(m_current_audio.m_setup.m_file);
m_player.set_audio_pos(m_current_audio.m_current_time);
callback(m_current_audio.m_current_time);
}
// step - шаг отправки сигнала на смещение маркера. он же кол-во block_size-ов на все произведение
void audio::set_step(std::size_t step)
void audio::callback(sf::Time time)
{
m_player.set_step(step);
}
m_current_audio.m_current_time = time;
double seconds = time.asSeconds();
double current_sample_index = seconds * m_current_audio.m_setup.m_sample_rate / m_compression;
void audio::callback(sf::Time time, double pos)
{
VE::event e { utils::event_type::INCREMENT_MARKER_AUDIO_POSITION, pos };
// send to:: components/markers
VE::event e { utils::event_type::SET_MARKER_AUDIO_POSITION, current_sample_index };
EMIT(e);
}
// HERE
// делать нужно, но надо разобраться зачем?
void audio::drop()
{
m_player.stop();

View File

@@ -5,8 +5,6 @@ namespace monitor::components
{
void audio::on_event(VE::event& e)
{
if (m_status != utils::var::STATUS::ACTIVE) return;
if (e.m_type.type() == typeid(VE::event_type))
{
auto type = std::any_cast<VE::event_type>(e.m_type);
@@ -28,12 +26,32 @@ namespace monitor::components
switch (type)
{
case utils::event_type::INIT_AUDIO:
{
auto [snapshot_id, setup] = std::any_cast<std::pair<std::string, utils::setup>>(e.m_data);
init(snapshot_id, setup);
break;
}
case utils::event_type::CHANGE_AUDIO:
{
auto snapshot_id = std::any_cast<std::string>(e.m_data);
change(snapshot_id);
break;
}
case utils::event_type::AUDIO_PAUSE:
{
pause();
break;
}
case utils::event_type::SET_COMPRESSION:
{
m_compression = std::any_cast<std::size_t>(e.m_data);
break;
}
case utils::event_type::SET_AUDIO_POSITION:
{
auto d = std::any_cast<double>(e.m_data);

View File

@@ -5,18 +5,16 @@ namespace monitor::components
{
void audio::render()
{
if (m_status != utils::var::STATUS::ACTIVE) return;
ImGui::SameLine( ImGui::GetWindowSize().x / 2.2f );
bool is_play = m_player.is_playing();
if (is_play)
{
ImGui::PushStyleColor(ImGuiCol_Button, VE_COLOR("#298FD4", 180));
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, VE_COLOR("#298FD4", 255));
ImGui::PushStyleColor(ImGuiCol_ButtonActive, VE_COLOR("#298FD4", 200));
}
else
{
ImGui::PushStyleColor(ImGuiCol_Button, VE_COLOR("#125C25", 180));
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, VE_COLOR("#125C25", 255));
ImGui::PushStyleColor(ImGuiCol_ButtonActive, VE_COLOR("#125C25", 200));
ImGui::PushStyleColor(ImGuiCol_Button, VE_COLOR("#4D4DA2", 180));
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, VE_COLOR("#4D4DA2", 255));
ImGui::PushStyleColor(ImGuiCol_ButtonActive, VE_COLOR("#4D4DA2", 200));
}
if (ImGui::Button(is_play ? "pause" : "play", ImVec2{70.f, 26.f} ))
@@ -25,9 +23,9 @@ namespace monitor::components
std::thread t(f);
t.detach();
}
ImGui::PopStyleColor(3);
if (is_play) ImGui::PopStyleColor(3);
ImGui::SameLine(80.f);
ImGui::SameLine();
if (ImGui::Button("<<<"))
{
@@ -47,8 +45,7 @@ namespace monitor::components
for (std::size_t i = 0; i < m_domains.size(); ++i)
{
const bool is_selected = (domain_id == i);
if (ImGui::Selectable(m_domains[i].c_str(), is_selected))
domain_id = i;
if (ImGui::Selectable(m_domains[i].c_str(), is_selected)) domain_id = i;
if (is_selected) ImGui::SetItemDefaultFocus();
}
ImGui::EndCombo();

View File

@@ -0,0 +1,18 @@
#pragma once
#include <VE.hpp>
namespace monitor::components
{
class base_controls : public VE::layer, public VE::connector
{
VE_OVERIDE();
VE_EVENT_OVERIDE();
private:
ImVec2 m_size = { 0.f, 0.f };
ImVec2 m_past_win_pos;
ImVec2 m_past_win_size;
};
}

View File

@@ -0,0 +1,22 @@
#include "monitor/gui/components/base_controls/base_controls.hpp"
#include "monitor/utils/var.hpp"
using namespace monitor::utils;
namespace monitor::components
{
void base_controls::on_attach()
{
CONNECT(this);
m_size.x = VE::application::get()->get_glfw()->width() / 4.f - var::WIN_PADDING * 3.f;
m_size.y = 300.f;
m_past_win_size.x = VE::application::get()->get_glfw()->width() - VE::application::get()->get_glfw()->width() / 4.f;
}
void base_controls::on_detach()
{
DISCONNECT();
}
void base_controls::update() { }
}

View File

@@ -0,0 +1,23 @@
#include "monitor/gui/components/base_controls/base_controls.hpp"
#include "monitor/utils/event_type.hpp"
namespace monitor::components
{
void base_controls::on_event(VE::event& e)
{
if (e.m_type.type() == typeid(utils::event_type))
{
auto type = std::any_cast<utils::event_type>(e.m_type);
switch (type)
{
// case utils::event_type::CREATE_SNAPSHOT_COMPLETED:
// {
// clear();
// break;
// }
}
}
}
}

View File

@@ -0,0 +1,19 @@
#include "monitor/gui/components/base_controls/base_controls.hpp"
#include "monitor/utils/func.hpp"
#include "monitor/utils/var.hpp"
using namespace monitor::utils;
namespace monitor::components
{
void base_controls::render()
{
ImGui::SetNextWindowPos({ m_past_win_size.x + var::WIN_PADDING * 2.f, 70.f });
ImGui::SetNextWindowSize(m_size);
if (!ImGui::BeginChild("scale")) ImGui::EndChild();
func::draw_border(m_size);
ImGui::EndChild();
}
}

View File

@@ -0,0 +1,39 @@
#pragma once
#include <VE.hpp>
#include "monitor/utils/setup.hpp"
#include "monitor/gui/components/graph/graph.hpp"
#include "monitor/gui/components/fft_scaled/fft_scaled.hpp"
namespace monitor::components
{
// сектор отрисовывающий базовые плагины, по табам
class base_plugins : public VE::layer, public VE::connector
{
VE_OVERIDE();
VE_EVENT_OVERIDE();
private:
ImVec2 m_size = { 0.f, 0.f };
ImVec2 m_pos = { 4.f, 70.f };
ImGuiTabBarFlags m_tab_bar_flags { ImGuiTabBarFlags_None };
std::size_t m_current_open_index = 0;
std::string m_snapshot_id;
private:
graph m_graph;
fft_scaled m_fft_scaled;
private:
utils::setup m_setup;
std::vector<std::shared_ptr<utils::plugin>> m_base_plugins;
public:
void init(std::string snapshot_id, utils::setup setup);
private:
void calculate_plugin(std::shared_ptr<utils::plugin> plugin);
void change_tab(std::size_t index);
};
}

View File

@@ -0,0 +1,91 @@
#include "monitor/gui/components/base_plugins/base_plugins.hpp"
#include "monitor/utils/plugins/raw_data/raw_data.hpp"
#include "monitor/utils/plugins/magnitude/magnitude.hpp"
#include "monitor/utils/event_type.hpp"
namespace monitor::components
{
void base_plugins::on_attach()
{
CONNECT(this);
m_graph.on_attach();
m_fft_scaled.on_attach();
m_base_plugins.push_back(std::make_shared<utils::plugins::raw_data>());
m_base_plugins.push_back(std::make_shared<utils::plugins::magnitude>());
m_size.x = VE::application::get()->get_glfw()->width() - VE::application::get()->get_glfw()->width() / 4.f;
m_size.y = VE::application::get()->get_glfw()->height() / 2.f;
}
void base_plugins::on_detach()
{
DISCONNECT();
m_graph.on_detach();
m_fft_scaled.on_detach();
}
void base_plugins::update()
{
m_graph.update();
m_fft_scaled.update();
}
void base_plugins::init(std::string snapshot_id, utils::setup setup)
{
m_snapshot_id = snapshot_id;
m_setup = setup;
m_graph.init(m_snapshot_id, m_setup);
// m_fft_scaled.init(m_snapshot_id, m_setup);
change_tab(0);
// send to: components/audio
VE::event e { utils::event_type::INIT_AUDIO, std::pair<std::string, utils::setup>(m_snapshot_id, m_setup) };
EMIT(e);
}
void base_plugins::change_tab(std::size_t index)
{
m_current_open_index = index;
calculate_plugin(m_base_plugins[index]);
m_graph.set_plugin(m_base_plugins[index]);
// send to: components/audio
VE::event e { utils::event_type::SET_COMPRESSION, m_base_plugins[index]->m_compression_step };
EMIT(e);
}
void base_plugins::calculate_plugin(std::shared_ptr<utils::plugin> plugin)
{
if (!plugin->empty()) return;
switch (plugin->m_type)
{
case utils::plugin::TYPE::RAW_DATA:
{
m_setup.m_domain = hr::DOMAIN_PLUGIN::TIME;
plugin->m_result = hr::run<hr::plugins::raw_data>(m_setup);
break;
}
case utils::plugin::TYPE::MAGNITUDE:
{
m_setup.m_domain = hr::DOMAIN_PLUGIN::FREQUENSY;
plugin->m_result = hr::run<hr::plugins::magnitude>(m_setup);
break;
}
}
if (!plugin->empty())
{
plugin->init(m_setup);
plugin->fill();
}
else
{
hack::error()("NOT SET DATA!");
}
}
}

View File

@@ -0,0 +1,28 @@
#include "monitor/gui/components/base_plugins/base_plugins.hpp"
#include "monitor/utils/event_type.hpp"
namespace monitor::components
{
void base_plugins::on_event(VE::event& e)
{
if (e.m_type.type() == typeid(utils::event_type))
{
auto type = std::any_cast<utils::event_type>(e.m_type);
switch (type)
{
case utils::event_type::PREPARE_BASE_PLUGIN_COMPRESSION:
{
auto snapshot_id = std::any_cast<std::string>(e.m_data);
if (m_snapshot_id != snapshot_id) return;
// send to: components/audio
VE::event e { utils::event_type::SET_COMPRESSION, m_base_plugins[m_current_open_index]->m_compression_step };
EMIT(e);
break;
}
}
}
}
}

View File

@@ -0,0 +1,36 @@
#include "monitor/gui/components/base_plugins/base_plugins.hpp"
#include "monitor/utils/func.hpp"
namespace monitor::components
{
void base_plugins::render()
{
ImGui::SetNextWindowPos(m_pos);
ImGui::SetNextWindowSize(m_size);
if (!ImGui::BeginChild(VE_NO_NAME("line" + m_snapshot_id))) ImGui::EndChild();
if (ImGui::BeginTabBar(VE_NO_NAME("tabs_line" + m_snapshot_id), m_tab_bar_flags))
{
for (std::size_t i = 0; i < m_base_plugins.size(); ++i)
{
ImGuiTabItemFlags flags = ImGuiTabItemFlags_NoCloseButton;
if (m_current_open_index == i) flags |= ImGuiTabItemFlags_SetSelected; // Добавляем флаг выделения если нужно
bool open = true;
if (ImGui::BeginTabItem(("[ " + std::to_string(i + 1) + " ] " + utils::func::string_cut(m_base_plugins[i]->m_display_name, 30)).c_str(), &open, flags))
{
m_graph.render();
ImGui::EndTabItem();
}
if (ImGui::IsItemClicked()) change_tab(i);
}
ImGui::EndTabBar();
}
m_fft_scaled.render();
utils::func::draw_border(m_size);
ImGui::EndChild();
}
}

View File

@@ -1,15 +1,11 @@
#include "monitor/gui/components/creator/creator.hpp"
#include "monitor/utils/event_type.hpp"
#include "monitor/utils/var.hpp"
namespace monitor::components
{
void creator::on_attach()
{
CONNECT(this);
for (const auto& entry : std::filesystem::directory_iterator(utils::var::DIR))
if (entry.is_directory()) m_dirs.push_back(entry.path().filename().string());
}
void creator::on_detach()
@@ -22,33 +18,26 @@ namespace monitor::components
void creator::create()
{
m_status = utils::var::STATUS::PROCESS;
m_setup.m_file = utils::var::DIR / m_dir.m_name / m_file.m_name;
auto f = [this]() {
m_setup.m_file = m_file_path;
// send to: tabs
VE::event e { utils::event_type::CREATE_SNAPSHOT, m_setup };
EMIT(e);
clear();
};
std::thread th(f);
th.detach();
}
void creator::clear()
{
m_dir.clear();
m_file.clear();
m_files.clear();
m_status = utils::var::STATUS::COMPLETED;
auto future = std::async(std::launch::async, [this]() {
auto f = [this]() {
std::this_thread::sleep_for(std::chrono::seconds(3));
m_file_path.clear();
m_status = utils::var::STATUS::EMPTY;
});
}
void creator::set_domain(std::string name)
{
if (name == "frequensy")
m_setup.m_domain = hr::DOMAIN_PLUGIN::FREQUENSY;
else
m_setup.m_domain = hr::DOMAIN_PLUGIN::TIME;
};
std::thread th(f);
th.detach();
}
}

View File

@@ -11,11 +11,21 @@ namespace monitor::components
switch (type)
{
// case utils::event_type::CREATE_WORKSPACE_COMPLETE:
// {
// clear();
// break;
// }
case utils::event_type::CREATE_SNAPSHOT_COMPLETED:
{
clear();
break;
}
case utils::event_type::STATUS_PROCESS:
{
m_status = utils::var::STATUS::PROCESS;
break;
}
case utils::event_type::STATUS_COMPLETED:
{
m_status = utils::var::STATUS::COMPLETED;
break;
}
}
}
}

View File

@@ -1,18 +0,0 @@
#include "monitor/gui/components/creator/creator.hpp"
#include "monitor/utils/var.hpp"
namespace monitor::components
{
void creator::render_buttons()
{
ImGui::BeginDisabled(m_status == utils::var::STATUS::EMPTY);
ImGui::BeginDisabled(m_status == utils::var::STATUS::PROCESS);
ImGui::BeginDisabled(m_status == utils::var::STATUS::COMPLETED);
if (ImGui::Button("create", ImVec2{ 94.f, 27.f })) create();
ImGui::EndDisabled();
ImGui::EndDisabled();
ImGui::EndDisabled();
}
}

View File

@@ -1,52 +0,0 @@
#include "monitor/gui/components/creator/creator.hpp"
#include "monitor/utils/var.hpp"
namespace monitor::components
{
void creator::render_combo()
{
auto ctx = ImGui::GetCurrentContext();
ImGui::SameLine(0.f, ctx->Style.FramePadding.x);
ImGui::SetNextItemWidth(400.f);
if (ImGui::BeginCombo(VE_NO_NAME("select_dir"), m_dir.m_id < 0 ? "---" : m_dirs[m_dir.m_id].c_str()))
{
for (std::size_t i = 0; i < m_dirs.size(); ++i)
{
const bool is_selected = (m_dir.m_id == static_cast<int>(i));
if (ImGui::Selectable(m_dirs[i].c_str(), is_selected))
{
m_files.clear();
m_dir.init(i, m_dirs[i]);
for (const auto& entry : std::filesystem::directory_iterator(utils::var::DIR/m_dir.m_name))
if (entry.is_regular_file()) m_files.push_back(entry.path().filename().string());
}
if (is_selected) ImGui::SetItemDefaultFocus();
}
ImGui::EndCombo();
}
ctx = ImGui::GetCurrentContext();
ImGui::SameLine(0.f, ctx->Style.FramePadding.x);
ImGui::SetNextItemWidth(400.f);
if (ImGui::BeginCombo(VE_NO_NAME("select_file"), m_file.m_id < 0 ? "---" : m_files[m_file.m_id].c_str()))
{
if (!m_files.empty())
{
for (std::size_t i = 0; i < m_files.size(); ++i)
{
const bool is_selected = (m_file.m_id == static_cast<int>(i));
if (ImGui::Selectable(m_files[i].c_str(), is_selected))
{
m_file.init(i, m_files[i]);
m_status = utils::var::STATUS::READY;
}
if (is_selected) ImGui::SetItemDefaultFocus();
}
}
ImGui::EndCombo();
}
}
}

View File

@@ -1,16 +1,42 @@
#include "monitor/gui/components/creator/creator.hpp"
#include "monitor/gui/components/file_dialog/file_dialog.hpp"
namespace monitor::components
{
void creator::render()
{
auto ctx = ImGui::GetCurrentContext();
render_combo();
render_spinner();
ImGui::SameLine(0.f, 9.f * ctx->Style.FramePadding.x);
float spacing = ImGui::GetStyle().ItemInnerSpacing.x;
ImGui::SameLine(0.0f, 30.f);
ImGui::BeginDisabled(m_status == utils::var::STATUS::PROCESS);
if (ImGui::Button("open file", ImVec2{ 94.f, 27.f }))
{
m_file_path = m_fd.open();
if (!m_file_path.empty()) m_status = utils::var::STATUS::READY;
else m_status = utils::var::STATUS::EMPTY;
}
ImGui::EndDisabled();
ImGui::SameLine();
if (!m_file_path.empty())
{
render_setup();
ImGui::SameLine(0.f, 2.f * ctx->Style.FramePadding.x);
render_buttons();
float spacing = ImGui::GetStyle().ItemInnerSpacing.x;
ImGui::SameLine(0.f, 3.f * spacing);
ImGui::Text(m_file_path.filename().c_str());
ImGui::SameLine();
ImGui::BeginDisabled(m_status == utils::var::STATUS::EMPTY);
ImGui::BeginDisabled(m_status == utils::var::STATUS::PROCESS);
ImGui::BeginDisabled(m_status == utils::var::STATUS::COMPLETED);
if (ImGui::Button("create", ImVec2{ 94.f, 27.f })) create();
ImGui::EndDisabled();
ImGui::EndDisabled();
ImGui::EndDisabled();
}
}
}

View File

@@ -5,34 +5,21 @@ namespace monitor::components
{
void creator::render_setup()
{
ImGui::PushItemFlag(ImGuiItemFlags_ButtonRepeat, true);
float spacing = ImGui::GetStyle().ItemInnerSpacing.x;
std::size_t step = 256;
// BLOCK SIZE
ImGui::Text("block size:");
ImGui::SameLine(0.0f, spacing);
render_block_size_setup(spacing);
ImGui::SameLine();
ImGui::Text(" | ");
ImGui::SameLine(0.f, spacing);
render_step_size_setup(spacing);
ImGui::SameLine();
ImGui::Text(" | ");
ImGui::PopItemFlag();
}
void creator::render_block_size_setup(float spacing)
{
ImGui::SetCursorPosY(8.f);
ImGui::PushItemFlag(ImGuiItemFlags_ButtonRepeat, true);
ImGui::SetCursorPosY(spacing);
VE_PUSH_FONT(ICON, 12);
ImGui::PushID(VE_NO_NAME("block_size minus"));
ImGui::PushID(VE_NO_NAME("1"));
if (ImGui::Button(VE::style::icon::ICON_MINUS, ImVec2{24, 20}))
{
m_setup.m_block_size -= m_step;
m_setup.m_block_size = std::max(m_step, m_setup.m_block_size);
m_setup.m_block_size -= step;
m_setup.m_block_size = std::max(step, m_setup.m_block_size);
}
ImGui::PopID();
VE_POP_FONT();
@@ -40,31 +27,32 @@ namespace monitor::components
ImGui::SameLine(0.0f, spacing);
ImGui::Text("%zu", m_setup.m_block_size);
// тут нужно жестко, а то при изменении циферек прагает в сторону поле
ImGui::SameLine(1000.0f);
ImGui::SameLine(0.f, spacing);
ImGui::SetCursorPosY(8.f);
ImGui::SetCursorPosY(spacing);
VE_PUSH_FONT(ICON, 12);
ImGui::PushID(VE_NO_NAME("block_size plus"));
ImGui::PushID(VE_NO_NAME("2"));
if (ImGui::Button(VE::style::icon::ICON_PLUS, ImVec2{24, 20}))
m_setup.m_block_size += m_step;
m_setup.m_block_size += step;
ImGui::PopID();
VE_POP_FONT();
ImGui::PopItemFlag();
}
// end BLOCK SIZE
void creator::render_step_size_setup(float spacing)
{
ImGui::SameLine(0.f, 3.f * spacing);
// STEP SIZE
ImGui::Text("step size:");
ImGui::SameLine(0.0f, spacing);
ImGui::PushItemFlag(ImGuiItemFlags_ButtonRepeat, true);
ImGui::SetCursorPosY(8.f);
ImGui::SetCursorPosY(spacing);
VE_PUSH_FONT(ICON, 12);
ImGui::PushID(VE_NO_NAME("step_size_minus"));
ImGui::PushID(VE_NO_NAME("3"));
if (ImGui::Button(VE::style::icon::ICON_MINUS, ImVec2{24, 20}))
{
m_setup.m_step_size -= m_step;
m_setup.m_step_size = std::max(m_step, m_setup.m_step_size);
m_setup.m_step_size -= step;
m_setup.m_step_size = std::max(step, m_setup.m_step_size);
}
ImGui::PopID();
VE_POP_FONT();
@@ -72,14 +60,16 @@ namespace monitor::components
ImGui::SameLine(0.0f, spacing);
ImGui::Text("%zu", m_setup.m_step_size);
// тут нужно жестко, а то при изменении циферек прагает в сторону поле
ImGui::SameLine(1195.0f);
ImGui::SameLine(0.f, spacing);
ImGui::SetCursorPosY(8.f);
ImGui::SetCursorPosY(spacing);
VE_PUSH_FONT(ICON, 12);
ImGui::PushID(VE_NO_NAME("step_size_plus"));
ImGui::PushID(VE_NO_NAME("4"));
if (ImGui::Button(VE::style::icon::ICON_PLUS, ImVec2{24, 20}))
m_setup.m_step_size += m_step;
m_setup.m_step_size += step;
ImGui::PopID();
VE_POP_FONT();
ImGui::PopItemFlag();
// end STEP SIZE
}
}

View File

@@ -5,9 +5,12 @@ extern ImRect g_ComboSize;
namespace monitor::components
{
void creator::render_spinner()
void creator::render_spinner(ImVec2 pos)
{
ImVec2 pos{ 830.f, 12.f };
// float spacing = 10.f;
// float size = 30.f;
// ImVec2 pos = ImVec2(pos.x + size + spacing, pos.y);
if (m_status == utils::var::STATUS::COMPLETED) m_spinner.render(pos);
else if (m_status == utils::var::STATUS::READY) m_spinner.render(pos, "#B4CF16");
else if (m_status == utils::var::STATUS::PROCESS) m_spinner.render(pos, "#B82C5C", true);

View File

@@ -3,7 +3,9 @@
#include <VE.hpp>
#include <harmonica.hpp>
#include "monitor/gui/components/spinner/spinner.hpp"
#include "monitor/gui/components/file_dialog/file_dialog.hpp"
#include "monitor/utils/var.hpp"
#include "monitor/utils/setup.hpp"
namespace monitor::components
{
@@ -13,42 +15,21 @@ namespace monitor::components
VE_EVENT_OVERIDE();
private:
struct combo
{
std::string m_name = "no selected";
int m_id = -1;
void init(int id, std::string name) { m_id = id; m_name = name; }
void clear()
{
m_name.clear();
m_id = -1;
}
};
private:
std::vector<std::string> m_dirs;
std::vector<std::string> m_files;
combo m_dir;
combo m_file;
utils::var::STATUS m_status = utils::var::STATUS::EMPTY;
components::spinner m_spinner;
hr::setup m_setup;
std::size_t m_step = 256;
private:
void set_domain(std::string name);
utils::setup m_setup;
file_dialog m_fd;
std::filesystem::path m_file_path;
private:
void render_setup();
void render_spinner(ImVec2 pos = { 10.f, 8.f });
private:
void create();
void clear();
void render_combo();
void render_spinner();
void render_buttons();
void render_setup();
void render_combo_signals();
private:
void render_block_size_setup(float spacing);
void render_step_size_setup(float spacing);
};
}

View File

@@ -0,0 +1,32 @@
#include "monitor/gui/components/fft_scaled/fft_scaled.hpp"
namespace monitor::components
{
void fft_scaled::on_attach()
{
CONNECT(this);
m_size.x = VE::application::get()->get_glfw()->width() - VE::application::get()->get_glfw()->width() / 4.f;
m_fft_size = ImVec2(m_size.x / 3.f - 6.f, 0.f);
}
void fft_scaled::on_detach()
{
DISCONNECT();
}
void fft_scaled::update()
{
}
void fft_scaled::init(std::string snapshot_id, hr::setup setup)
{
m_snapshot_id = snapshot_id;
m_setup = setup;
m_setup.m_domain = hr::DOMAIN_PLUGIN::FREQUENSY;
m_plugin.m_result = hr::run<hr::plugins::fft>(m_setup);
// m_plugin.init();
// m_plugin.fill();
}
}

View File

@@ -0,0 +1,8 @@
#include "monitor/gui/components/fft_scaled/fft_scaled.hpp"
namespace monitor::components
{
void fft_scaled::on_event(VE::event& e)
{
}
}

View File

@@ -0,0 +1,86 @@
#include "monitor/gui/components/fft_scaled/fft_scaled.hpp"
namespace monitor::components
{
void fft_scaled::render()
{
if (ImPlot::BeginPlot(VE_NO_NAME(m_plugin.m_display_name + m_snapshot_id + "0"), m_fft_size, ImPlotFlags_NoMenus))
{
// по оси X
ImPlot::SetupAxes(nullptr, nullptr, ImPlotAxisFlags_Opposite | // смена полюсов у надписей оси x. они вверху
ImPlotAxisFlags_NoSideSwitch | // нельзя перетаскивать оси по сторонам
(m_is_first_render ? ImPlotAxisFlags_AutoFit : ImPlotAxisFlags_None) | // авто подстройка размера по горизонтале
ImPlotAxisFlags_NoHighlight, // не разобрался что это там подсвечивается, что-то с фоном оси
// по оси Y
ImPlotAxisFlags_AutoFit | // авто подстройка размера по вертикале
ImPlotAxisFlags_NoSideSwitch |
ImPlotAxisFlags_NoHighlight |
ImPlotAxisFlags_NoTickLabels // текстовые надписи отображаться не будут
);
// ImPlot::SetupAxisLimits(ImAxis_X1, 0.f, m_plugin.m_graph.m_size);
// ImPlot::SetupAxisLimits(ImAxis_Y1, 0.f, m_plugin.m_graph.m_max_element + 2.f);
// ImPlot::SetupAxisLimitsConstraints(ImAxis_X1, 0, INFINITY);
// ImPlot::SetupLegend(ImPlotLocation_NorthEast);
//
// ImPlot::PlotStems(VE_NAME("fft_scaled" + m_snapshot_id), m_plugin.m_graph.m_ox.data(), m_plugin.m_graph.m_data[0].data(), m_plugin.m_graph.m_data[0].size());
m_is_first_render = false;
ImPlot::EndPlot();
}
ImGui::SameLine();
if (ImPlot::BeginPlot(VE_NO_NAME(m_plugin.m_display_name + m_snapshot_id + "1"), m_fft_size, ImPlotFlags_NoMenus))
{
// по оси X
ImPlot::SetupAxes(nullptr, nullptr, ImPlotAxisFlags_Opposite | // смена полюсов у надписей оси x. они вверху
ImPlotAxisFlags_NoSideSwitch | // нельзя перетаскивать оси по сторонам
(m_is_first_render ? ImPlotAxisFlags_AutoFit : ImPlotAxisFlags_None) | // авто подстройка размера по горизонтале
ImPlotAxisFlags_NoHighlight, // не разобрался что это там подсвечивается, что-то с фоном оси
// по оси Y
ImPlotAxisFlags_AutoFit | // авто подстройка размера по вертикале
ImPlotAxisFlags_NoSideSwitch |
ImPlotAxisFlags_NoHighlight |
ImPlotAxisFlags_NoTickLabels // текстовые надписи отображаться не будут
);
// ImPlot::SetupAxisLimits(ImAxis_X1, 0.f, m_plugin.m_graph.m_size);
// ImPlot::SetupAxisLimits(ImAxis_Y1, 0.f, m_plugin.m_graph.m_max_element + 2.f);
// ImPlot::SetupAxisLimitsConstraints(ImAxis_X1, 0, INFINITY);
// ImPlot::SetupLegend(ImPlotLocation_NorthEast);
//
// ImPlot::PlotStems(VE_NAME("fft_scaled" + m_snapshot_id), m_plugin.m_graph.m_ox.data(), m_plugin.m_graph.m_data[0].data(), m_plugin.m_graph.m_data[0].size());
m_is_first_render = false;
ImPlot::EndPlot();
}
ImGui::SameLine();
if (ImPlot::BeginPlot(VE_NO_NAME(m_plugin.m_display_name + m_snapshot_id + "2"), m_fft_size, ImPlotFlags_NoMenus))
{
// по оси X
ImPlot::SetupAxes(nullptr, nullptr, ImPlotAxisFlags_Opposite | // смена полюсов у надписей оси x. они вверху
ImPlotAxisFlags_NoSideSwitch | // нельзя перетаскивать оси по сторонам
(m_is_first_render ? ImPlotAxisFlags_AutoFit : ImPlotAxisFlags_None) | // авто подстройка размера по горизонтале
ImPlotAxisFlags_NoHighlight, // не разобрался что это там подсвечивается, что-то с фоном оси
// по оси Y
ImPlotAxisFlags_AutoFit | // авто подстройка размера по вертикале
ImPlotAxisFlags_NoSideSwitch |
ImPlotAxisFlags_NoHighlight |
ImPlotAxisFlags_NoTickLabels // текстовые надписи отображаться не будут
);
// ImPlot::SetupAxisLimits(ImAxis_X1, 0.f, m_plugin.m_graph.m_size);
// ImPlot::SetupAxisLimits(ImAxis_Y1, 0.f, m_plugin.m_graph.m_max_element + 2.f);
// ImPlot::SetupAxisLimitsConstraints(ImAxis_X1, 0, INFINITY);
// ImPlot::SetupLegend(ImPlotLocation_NorthEast);
//
// ImPlot::PlotStems(VE_NAME("fft_scaled" + m_snapshot_id), m_plugin.m_graph.m_ox.data(), m_plugin.m_graph.m_data[0].data(), m_plugin.m_graph.m_data[0].size());
m_is_first_render = false;
ImPlot::EndPlot();
}
}
}

View File

@@ -0,0 +1,29 @@
#pragma once
#include <VE.hpp>
#include <harmonica.hpp>
#include "monitor/utils/plugins/fft/fft.hpp"
namespace monitor::components
{
class fft_scaled : public VE::layer, public VE::flags, public VE::connector
{
VE_OVERIDE();
VE_EVENT_OVERIDE();
private:
ImVec2 m_size = { 0.f, 0.f };
ImVec2 m_fft_size;
ImGuiTabBarFlags m_tab_bar_flags { ImGuiTabBarFlags_None };
ImPlotRect m_current_limits;
bool m_is_first_render = true;
public:
void init(std::string snapshot_id, hr::setup setup);
private:
utils::plugins::fft m_plugin;
hr::setup m_setup;
std::string m_snapshot_id;
};
}

View File

@@ -0,0 +1,9 @@
#include "file_dialog.hpp"
namespace monitor::components
{
std::filesystem::path file_dialog::open(const std::filesystem::path& default_path)
{
return m_nfd.open(default_path);
}
}

View File

@@ -0,0 +1,19 @@
#pragma once
#include "monitor/libs/gtkfd/gtkfd.hpp"
namespace monitor::components
{
class file_dialog
{
public:
file_dialog() = default;
~file_dialog() = default;
public:
std::filesystem::path open(const std::filesystem::path& default_path = "/mnt/raid/projects/dsp/songs");
private:
libs::gtkfd m_nfd;
};
}

View File

@@ -0,0 +1,39 @@
#include "monitor/gui/components/graph/graph.hpp"
namespace monitor::components
{
void graph::on_attach()
{
CONNECT(this);
m_markers.on_attach();
}
void graph::on_detach()
{
DISCONNECT();
m_markers.on_detach();
}
void graph::update()
{
m_markers.update();
}
void graph::init(std::string snapshot_id, hr::setup setup)
{
m_snapshot_id = snapshot_id;
m_setup = setup;
m_markers.init();
}
void graph::set_plugin(std::shared_ptr<utils::plugin> plugin) noexcept
{
m_plugin = std::move(plugin);
if (!m_plugin) hack::error()("The object is not installed");
}
std::size_t graph::get_plugin_size() noexcept
{
return m_plugin->m_size;
}
}

View File

@@ -0,0 +1,8 @@
#include "monitor/gui/components/graph/graph.hpp"
namespace monitor::components
{
void graph::on_event(VE::event& e)
{
}
}

View File

@@ -0,0 +1,39 @@
#include "monitor/gui/components/graph/graph.hpp"
namespace monitor::components
{
void graph::render()
{
if (ImPlot::BeginPlot(VE_NO_NAME(m_plugin->m_display_name + m_snapshot_id), ImVec2(-1, 0), ImPlotFlags_NoMenus))
{
// по оси X
ImPlot::SetupAxes(nullptr, nullptr, ImPlotAxisFlags_Opposite | // смена полюсов у надписей оси x. они вверху
ImPlotAxisFlags_NoSideSwitch | // нельзя перетаскивать оси по сторонам
(m_is_first_render ? ImPlotAxisFlags_AutoFit : ImPlotAxisFlags_None) | // авто подстройка размера по горизонтале
ImPlotAxisFlags_NoHighlight, // не разобрался что это там подсвечивается, что-то с фоном оси
// по оси Y
ImPlotAxisFlags_AutoFit | // авто подстройка размера по вертикале
ImPlotAxisFlags_NoSideSwitch |
ImPlotAxisFlags_NoHighlight |
ImPlotAxisFlags_NoTickLabels // текстовые надписи отображаться не будут
);
ImPlot::SetupAxisLimits(ImAxis_X1, 0.f, m_plugin->m_size);
ImPlot::SetupAxisLimits(ImAxis_Y1, 0.f, m_plugin->m_result.m_max + m_plugin->m_result.m_max * 0.1);
ImPlot::SetupAxisLimitsConstraints(ImAxis_X1, 0, INFINITY);
ImPlot::SetupLegend(ImPlotLocation_NorthEast);
for (std::size_t i = 0; i < m_plugin->m_line_count; ++i)
{
if (m_plugin->m_type == utils::plugin::TYPE::ENERGY)
ImPlot::PlotStems(VE_NAME(std::to_string(i)), m_plugin->m_ox.data(), m_plugin->m_line_data[i].data(), m_plugin->m_line_data[i].size());
else
ImPlot::PlotLine(VE_NAME(std::to_string(i)), m_plugin->m_ox.data(), m_plugin->m_line_data[i].data(), m_plugin->m_line_data[i].size());
}
m_markers.render();
m_is_first_render = false;
ImPlot::EndPlot();
}
}
}

View File

@@ -0,0 +1,32 @@
#pragma once
#include <VE.hpp>
#include <harmonica.hpp>
#include "monitor/utils/plugin.hpp"
#include "monitor/gui/components/markers/markers.hpp"
namespace monitor::components
{
class graph : public VE::layer, public VE::flags, public VE::connector
{
VE_OVERIDE();
VE_EVENT_OVERIDE();
private:
ImVec2 m_size = { 0.f, 0.f };
ImGuiTabBarFlags m_tab_bar_flags { ImGuiTabBarFlags_None };
ImPlotRect m_current_limits;
bool m_is_first_render = true;
public:
void init(std::string snapshot_id, hr::setup setup);
void set_plugin(std::shared_ptr<utils::plugin> plugin) noexcept;
std::size_t get_plugin_size() noexcept;
private:
std::shared_ptr<utils::plugin> m_plugin;
hr::setup m_setup;
std::string m_snapshot_id;
markers m_markers;
};
}

View File

@@ -17,20 +17,9 @@ namespace monitor::components
{
}
void markers::set_status(utils::var::STATUS s)
{
m_status = s;
}
void markers::set_tag_show(bool v)
{
m_tag_show = v;
}
void markers::init()
{
m_marker_audio_color = ImGui::ColorConvertU32ToFloat4(VE_COLOR("#00FC7C", 180));
m_marker_mouse_color = ImGui::ColorConvertU32ToFloat4(VE_COLOR("#414243", 180));
m_marker_fixed_color = ImGui::ColorConvertU32ToFloat4(VE_COLOR("#B4CF16", 180));
m_marker_audio_color = ImGui::ColorConvertU32ToFloat4(VE_COLOR("#7DEFAC", 180));
m_marker_mouse_color = ImGui::ColorConvertU32ToFloat4(VE_COLOR("#8CA9C6", 180));
}
}

View File

@@ -1,12 +1,11 @@
#include "monitor/gui/components/markers/markers.hpp"
#include "monitor/utils/event_type.hpp"
#include <SFML/Audio.hpp>
namespace monitor::components
{
void markers::on_event(VE::event& e)
{
if (m_status != utils::var::STATUS::ACTIVE) return;
if (e.m_type.type() == typeid(VE::event_type))
{
auto type = std::any_cast<VE::event_type>(e.m_type);
@@ -35,13 +34,6 @@ namespace monitor::components
auto type = std::any_cast<utils::event_type>(e.m_type);
switch (type)
{
case utils::event_type::INCREMENT_MARKER_AUDIO_POSITION:
{
auto pos = std::any_cast<double>(e.m_data);
m_marker_audio_position += pos;
break;
}
case utils::event_type::SET_MARKER_AUDIO_POSITION:
{
auto pos = std::any_cast<double>(e.m_data);
@@ -54,20 +46,6 @@ namespace monitor::components
m_marker_audio_position = 0.0;
break;
}
case utils::event_type::SET_MARKER_MOUSE_POSITION:
{
auto pos = std::any_cast<double>(e.m_data);
m_marker_mouse_position = pos;
break;
}
// case utils::event_type::REMOVE_LAST_MARKER_SEGMENT:
// {
// if (m_marker_segment.size() > 0)
// m_marker_segment.pop_back();
// break;
// }
}
}
}

View File

@@ -5,9 +5,9 @@ namespace monitor::components
{
void markers::render()
{
// -1 это индекс т.к. там внизу тоже они индексируются
// 0 это индекс т.к. там внизу тоже они индексируются
// ImPlotDragToolFlags_NoInputs - не дает передвинуть маркер
ImPlot::DragLineX(-1, &m_marker_audio_position, m_marker_audio_color, 0.1f, ImPlotDragToolFlags_NoCursors | ImPlotDragToolFlags_NoInputs);
ImPlot::DragLineX(0, &m_marker_audio_position, m_marker_audio_color, 0.1f, ImPlotDragToolFlags_NoCursors | ImPlotDragToolFlags_NoInputs);
// кликаем для установки маркера аудио (зеленый)
if (ImGui::IsMouseClicked(ImGuiMouseButton_Middle))
@@ -21,37 +21,7 @@ namespace monitor::components
if (m_shift_press && ImPlot::IsPlotHovered())
{
m_marker_mouse_position = ImPlot::GetPlotMousePos().x;
ImPlot::DragLineX(1000, &m_marker_mouse_position, m_marker_mouse_color, 0.1f, ImPlotDragToolFlags_NoCursors | ImPlotDragToolFlags_NoInputs);
ImPlot::DragLineX(1, &m_marker_mouse_position, m_marker_mouse_color, 0.1f, ImPlotDragToolFlags_NoCursors | ImPlotDragToolFlags_NoInputs);
}
// кликаем для установки тэгов
if (m_shift_press && ImGui::IsMouseClicked(ImGuiMouseButton_Right) && ImPlot::IsPlotHovered())
m_marker_fixed.push_back(ImPlot::GetPlotMousePos().x);
for (std::size_t i = 0; i < m_marker_fixed.size(); ++i)
{
ImPlot::DragLineX(i, &m_marker_fixed[i], m_marker_fixed_color, 0.1f, ImPlotDragToolFlags_NoCursors | ImPlotDragToolFlags_NoInputs);
if (m_tag_show) ImPlot::TagX(m_marker_fixed[i], m_marker_fixed_color, std::to_string(i).c_str());
}
if (m_shift_press)
{
auto p = ImPlot::GetPlotMousePos().x;
for (std::size_t i = 0; i < m_marker_fixed.size(); ++i)
{
if (std::abs(p - m_marker_fixed[i]) < m_tolerance)
{
ImPlot::DragLineX(i, &m_marker_fixed[i], m_marker_fixed_color, 2.7f, ImPlotDragToolFlags_NoCursors | ImPlotDragToolFlags_NoInputs);
if (ImGui::IsMouseClicked(ImGuiMouseButton_Left) && ImPlot::IsPlotHovered())
m_marker_fixed.erase(m_marker_fixed.begin() + i);
}
}
}
// показываем позицию при наведении мыши
auto p = ImPlot::GetPlotMousePos().x;
for (std::size_t i = 0; i < m_marker_fixed.size(); ++i)
if (std::abs(p - m_marker_fixed[i]) < m_tolerance * 4.0)
ImPlot::TagX(m_marker_fixed[i], m_marker_fixed_color, std::to_string(static_cast<int>(ImPlot::GetPlotMousePos().x)).c_str());
}
}

View File

@@ -1,7 +1,6 @@
#pragma once
#include <VE.hpp>
#include "monitor/utils/var.hpp"
namespace monitor::components
{
@@ -12,19 +11,12 @@ namespace monitor::components
public:
void init();
void set_status(utils::var::STATUS s);
void set_tag_show(bool v);
private:
utils::var::STATUS m_status;
ImVec4 m_marker_audio_color;
ImVec4 m_marker_mouse_color;
double m_marker_audio_position = 0.0;
double m_marker_mouse_position = 0.0;
double m_marker_mouse_position = 100.0;
bool m_shift_press = false;
double m_tolerance = 2.7; // Настройте чувствительность приближения мыши к тэгу
bool m_tag_show = false; // эта штука не ставит тэг на графике наже первого(Magnitude)
ImVec4 m_marker_fixed_color;
std::vector<double> m_marker_fixed;
};
}

View File

@@ -1,5 +1,4 @@
#include "monitor/gui/components/panel/panel.hpp"
#include <hack/math/math.hpp>
namespace monitor::components
{
@@ -7,6 +6,7 @@ namespace monitor::components
{
CONNECT(this);
m_creator.on_attach();
m_audio.on_attach();
m_helpers.on_attach();
}
@@ -14,16 +14,16 @@ namespace monitor::components
{
DISCONNECT();
m_creator.on_detach();
m_audio.on_detach();
m_helpers.on_detach();
}
void panel::update()
{
m_size.x = VE::application::get()->get_glfw()->width();
auto ctx = ImGui::GetCurrentContext();
// m_size.x -= ctx->Style.FramePadding.x * 2.f;
m_creator.update();
m_audio.update();
m_helpers.update();
}
}

View File

@@ -9,6 +9,7 @@ namespace monitor::components
ImGui::SetNextWindowSize(m_size);
if (!ImGui::Begin(VE_NO_NAME("panel"), &m_open, m_win_flags)) ImGui::End();
m_creator.render();
m_audio.render();
m_helpers.render();
ImGui::End();
}

View File

@@ -4,6 +4,7 @@
#include <harmonica.hpp>
#include "monitor/gui/components/creator/creator.hpp"
#include "monitor/gui/components/helpers/helpers.hpp"
#include "monitor/gui/components/audio/audio.hpp"
namespace monitor::components
{
@@ -14,7 +15,8 @@ namespace monitor::components
private:
ImVec2 m_size = { 950.f, 37.f };
components::creator m_creator;
components::helpers m_helpers;
creator m_creator;
audio m_audio;
helpers m_helpers;
};
}

View File

@@ -1,167 +1,35 @@
#include "monitor/gui/components/snapshot/snapshot.hpp"
#include "monitor/utils/var.hpp"
#include <hack/math/math.hpp>
namespace monitor::components
{
void snapshot::on_attach()
{
CONNECT(this);
m_audio.on_attach();
m_markers.on_attach();
m_plugins.emplace_back(combo{ .m_id = 0, .m_name = "Magnitude", .m_type = utils::var::PLUGIN_TYPE::MAGNITUDE });
m_plugins.emplace_back(combo{ .m_id = 1, .m_name = "Energy", .m_type = utils::var::PLUGIN_TYPE::ENERGY });
m_base_plugins.on_attach();
m_base_controls.on_attach();
}
void snapshot::on_detach()
{
DISCONNECT();
m_audio.on_detach();
m_markers.on_detach();
m_base_plugins.on_detach();
}
void snapshot::update()
{
m_size.x = VE::application::get()->get_glfw()->width();
m_size.y = VE::application::get()->get_glfw()->height();
m_audio.update();
m_markers.update();
m_base_plugins.update();
}
void snapshot::set_status(utils::var::STATUS s)
{
m_status = s;
m_markers.set_status(m_status);
m_audio.set_status(m_status);
}
void snapshot::init(hr::setup setup)
void snapshot::init(utils::setup setup)
{
m_snapshot_id = hack::security::generate_uuid();
m_setup = setup;
auto r = hr::run<hr::plugins::raw_data>(m_setup);
if (fill_raw_data(r))
{
m_audio.init(m_setup.m_file);
m_audio.set_step(r.m_data.size());
m_markers.init();
set_status(utils::var::STATUS::ACTIVE);
}
}
bool snapshot::fill_raw_data(hr::result& r)
{
bool ok = true;
// Общая длинна всех данных
auto total_size = r.m_data.size();
hack::log()(total_size);
// if (total_size > utils::var::MAX_RENDER_SIZE)
// {
// hack::warn()("Данный файл превышает максимально допустимый размер рендеринга");
// hack::log()("Возможно пришло время чтобы написать тут код... см. dspv.v3");
// hack::log()("но там есть tmp, которая может ту быть сомнительной...");
// }
// else if (total_size == 0)
if (total_size == 0)
{
hack::error()("Пусто в расчетах!");
hack::warn()("Нет данных для отрисовки, возможно что-то не так с плагином...");
return !ok;
}
else
{
utils::types::graph_data data;
data.m_render_data.push_back(hr::fvec_t());
// тут резирвируем именно длинну по оси X всех линий
data.m_ox.reserve(total_size);
// заполняем данными все линии графиков
for (auto el : r.m_data)
{
data.m_max_element = hack::math::max(el.m_value[0], data.m_max_element);
data.m_render_data[0].push_back(el.m_value[0]);
}
for (std::size_t i = 0; i < total_size; ++i) data.m_ox.push_back(i);
data.m_name = m_plugin.m_name;
data.m_type = m_plugin.m_type;
m_graphs.push_back(data);
}
return ok;
}
bool snapshot::fill(hr::result& r)
{
bool is_ok = false;
auto base_size = r.m_data.size();
utils::types::graph_data data;
if (base_size > utils::var::MAX_RENDER_SIZE)
{
hack::warn()("Данный файл превышает максимально допустимый размер рендеринга");
hack::log()("Возможно пришло время чтобы написать тут код... см. dspv.v3");
hack::log()("но там есть tmp, которая может ту быть сомнительной...");
}
else if (base_size == 0)
{
hack::error()("Пусто в расчетах!");
hack::warn()("Нет данных для отрисовки, возможно что-то не так с плагином...");
}
else
{
// резервируем кол-во линий графиков исходя из того сколько данных нужно отрисовать в каждом бине из dsp
auto graph_count = r.m_data[0].m_value.size();
data.m_render_data.reserve(graph_count);
for (std::size_t i = 0; i < graph_count; ++i) data.m_render_data.push_back(hr::fvec_t());
// тут резирвируем именно длинну по оси X всех линий
data.m_ox.reserve(base_size);
// заполняем данными все линии графиков
for (auto el : r.m_data)
{
for (std::size_t i = 0; i < graph_count; ++i)
{
data.m_max_element = hack::math::max(el.m_value[i], data.m_max_element);
data.m_render_data[i].push_back(el.m_value[i]);
}
}
for (std::size_t i = 0; i < data.m_render_data[0].size(); ++i) data.m_ox.push_back(i);
data.m_name = m_plugin.m_name;
data.m_type = m_plugin.m_type;
m_graphs.push_back(data);
is_ok = true;
}
return is_ok;
}
void snapshot::add_plugin()
{
hr::result r;
switch (m_plugin.m_type)
{
case utils::var::PLUGIN_TYPE::MAGNITUDE:
{
// HERE
// это нужно устанавливать в combo
m_setup.m_domain = hr::DOMAIN_PLUGIN::FREQUENSY;
r = hr::run<hr::plugins::magnitude>(m_setup);
hack::log()("asdf");
break;
}
// case utils::var::PLUGIN_TYPE::ENERGY:
// {
// r = hr::run<hr::plugins::energy>(m_setup);
// break;
// }
}
fill(r);
m_plugin.clear();
m_base_plugins.init(m_snapshot_id, m_setup);
}
}

View File

@@ -4,92 +4,12 @@ namespace monitor::components
{
void snapshot::render()
{
m_audio.render();
ImGui::PushID("line");
m_base_plugins.render();
ImGui::PopID();
ImGui::SameLine();
// HERE
// выбор домена для плагина
auto ctx = ImGui::GetCurrentContext();
ImGui::SameLine(0.f, ctx->Style.FramePadding.x);
ImGui::SetNextItemWidth(120.f);
static std::size_t domain_id = 0;
if (ImGui::BeginCombo(VE_NO_NAME("select_domain"), m_domains[domain_id].c_str()))
{
for (std::size_t i = 0; i < m_domains.size(); ++i)
{
const bool is_selected = (domain_id == i);
if (ImGui::Selectable(m_domains[i].c_str(), is_selected))
domain_id = i;
if (is_selected) ImGui::SetItemDefaultFocus();
}
ImGui::EndCombo();
}
ImGui::SameLine();
ImGui::SetNextItemWidth(400.f);
if (ImGui::BeginCombo(VE_NO_NAME("select_plugin"), m_plugin.m_id < 0 ? "---" : m_plugins[m_plugin.m_id].m_name.c_str()))
{
for (std::size_t i = 0; i < m_plugins.size(); ++i)
{
const bool is_selected = (m_plugin.m_id == static_cast<int>(i));
if (ImGui::Selectable(m_plugins[i].m_name.c_str(), is_selected))
m_plugin = m_plugins[i];
if (is_selected) ImGui::SetItemDefaultFocus();
}
ImGui::EndCombo();
}
ImGui::SameLine();
if (ImGui::Button("add plugin", ImVec2{ 94.f, 27.f })) add_plugin();
if (ImPlot::BeginSubplots(VE_NO_NAME("graph" + m_snapshot_id), m_rows, m_cols, ImVec2(-1, -1), ImPlotSubplotFlags_LinkRows | ImPlotSubplotFlags_LinkCols))
{
for (const auto& graph : m_graphs)
{
if (ImPlot::BeginPlot(VE_NAME(graph.m_name), ImVec2(-1, 0), ImPlotFlags_NoMenus))
{
// по оси X
ImPlot::SetupAxes(nullptr, nullptr, ImPlotAxisFlags_Opposite | // смена полюсов у надписей оси x. они вверху
ImPlotAxisFlags_NoSideSwitch | // нельзя перетаскивать оси по сторонам
(is_first_render ? ImPlotAxisFlags_AutoFit : ImPlotAxisFlags_None) | // авто подстройка размера по горизонтале
ImPlotAxisFlags_NoHighlight, // не разобрался что это там подсвечивается, что-то с фоном оси
// по оси Y
ImPlotAxisFlags_AutoFit | // авто подстройка размера по вертикале
ImPlotAxisFlags_NoSideSwitch |
ImPlotAxisFlags_NoHighlight |
ImPlotAxisFlags_NoTickLabels // текстовые надписи отображаться не будут
);
ImPlot::SetupAxisLimits(ImAxis_X1, 0.f, graph.m_render_data[0].size());
ImPlot::SetupAxisLimits(ImAxis_Y1, 0.f, graph.m_max_element);
ImPlot::SetupAxisLimitsConstraints(ImAxis_X1, 0, INFINITY);
ImPlot::SetupLegend(ImPlotLocation_NorthEast);
std::size_t index = 0;
for (auto& line : graph.m_render_data)
{
if (graph.m_type == utils::var::PLUGIN_TYPE::SEGMENTER)
ImPlot::PlotStems(VE_NAME(std::to_string(index)), graph.m_ox.data(), line.data(), line.size());
else
ImPlot::PlotLine(VE_NAME(std::to_string(index)), graph.m_ox.data(), line.data(), line.size());
++index;
}
if (graph.m_type != utils::var::PLUGIN_TYPE::MAGNITUDE) m_markers.set_tag_show(false);
else m_markers.set_tag_show(true);
m_markers.render();
ImPlot::EndPlot();
}
}
ImPlot::EndSubplots();
}
is_first_render = false;
ImGui::PushID("scale");
m_base_controls.render();
ImGui::PopID();
}
}

View File

@@ -1,11 +1,10 @@
#pragma once
#include <VE.hpp>
#include <harmonica.hpp>
#include "monitor/utils/var.hpp"
#include "monitor/utils/types/graph_data.hpp"
#include "monitor/gui/components/audio/audio.hpp"
#include "monitor/gui/components/markers/markers.hpp"
#include "monitor/utils/setup.hpp"
#include "monitor/gui/components/base_plugins/base_plugins.hpp"
#include "monitor/gui/components/base_controls/base_controls.hpp"
namespace monitor::components
{
@@ -14,17 +13,20 @@ namespace monitor::components
VE_OVERIDE();
VE_EVENT_OVERIDE();
public:
base_plugins m_base_plugins;
base_controls m_base_controls;
public:
std::string m_snapshot_id;
utils::var::STATUS m_status;
audio m_audio;
hr::setup m_setup;
utils::setup m_setup;
private:
ImVec2 m_size = { 0.f, 0.f };
private:
std::vector<utils::types::graph_data> m_graphs;
// std::vector<utils::types::graph_data> m_graphs;
ImGuiTabBarFlags m_tab_bar_flags { ImGuiTabBarFlags_None };
int m_rows = 7;
int m_cols = 1;
@@ -32,14 +34,13 @@ namespace monitor::components
// то нужно при первом рендеренге разрешить его, чтобы он установли график как нужно, а потом
// снять чтобы можно было манипулировать мышкой.
bool is_first_render = true;
components::markers m_markers;
private:
struct combo
{
int m_id = -1;
std::string m_name;
utils::var::PLUGIN_TYPE m_type;
// utils::var::PLUGIN_TYPE m_type;
void clear() { m_id = -1; m_name.clear(); }
} m_plugin;
@@ -48,12 +49,6 @@ namespace monitor::components
public:
void set_status(utils::var::STATUS s);
void init(hr::setup setup);
private:
bool fill(hr::result& r);
bool fill_raw_data(hr::result& r);
void add_plugin();
void init(utils::setup setup);
};
}

View File

@@ -6,7 +6,9 @@ namespace monitor::components
void tabs::on_attach()
{
CONNECT(this);
for (auto & s : m_snapshots) s->on_attach();
hack::log().on_full_path();
hack::log().set_devider(" = ");
}
void tabs::on_detach()
@@ -23,33 +25,31 @@ namespace monitor::components
for (auto & s : m_snapshots) s->update();
}
void tabs::create_snapshot(hr::setup setup)
void tabs::create_snapshot(utils::setup setup)
{
auto s = std::make_shared<snapshot>();
s->init(setup);
s->on_attach();
s->init(setup);
m_snapshots.push_back(s);
}
std::string tabs::string_cut(std::filesystem::path p, int n)
{
std::string s_cut = p.filename();
if (static_cast<int>(s_cut.size()) > n)
{
s_cut.resize(n);
s_cut += " ...";
}
VE::event e { utils::event_type::CREATE_SNAPSHOT_COMPLETED, nullptr };
EMIT(e);
return s_cut;
change_tab(m_snapshots.size() - 1);
}
void tabs::change_tab(std::size_t i)
{
VE::event e { utils::event_type::AUDIO_PAUSE, m_current_open_index };
EMIT(e);
m_snapshots[m_current_open_index]->set_status(utils::var::STATUS::INACTIVE);
m_snapshots[i]->set_status(utils::var::STATUS::ACTIVE);
m_current_open_index = i;
// send to: components/base_plugins
VE::event e0 { utils::event_type::PREPARE_BASE_PLUGIN_COMPRESSION, m_snapshots[i]->m_snapshot_id };
EMIT(e0);
// send to: components/audio
VE::event e1 { utils::event_type::CHANGE_AUDIO, m_snapshots[i]->m_snapshot_id };
EMIT(e1);
};
}

View File

@@ -13,7 +13,7 @@ namespace monitor::components
{
case utils::event_type::CREATE_SNAPSHOT:
{
auto data = std::any_cast<hr::setup>(e.m_data);
auto data = std::any_cast<utils::setup>(e.m_data);
create_snapshot(data);
break;
}

View File

@@ -1,4 +1,7 @@
#include "monitor/gui/components/tabs/tabs.hpp"
#include "monitor/utils/func.hpp"
using namespace monitor::utils;
namespace monitor::components
{
@@ -23,7 +26,7 @@ namespace monitor::components
{
ImGuiTabItemFlags flags = (m_current_open_index == i) ? ImGuiTabItemFlags_SetSelected : 0;
bool open = true;
if (ImGui::BeginTabItem(("[" + std::to_string(i) + "] " + string_cut(m_snapshots[i]->m_setup.m_file, 30)).c_str(), &open, flags))
if (ImGui::BeginTabItem(("[" + std::to_string(i) + "] " + func::string_cut(m_snapshots[i]->m_setup.m_file, 30)).c_str(), &open, flags))
{
m_snapshots[i]->render();
ImGui::EndTabItem();

View File

@@ -3,6 +3,7 @@
#include <VE.hpp>
#include <harmonica.hpp>
#include "monitor/gui/components/snapshot/snapshot.hpp"
#include "monitor/utils/setup.hpp"
namespace monitor::components
{
@@ -18,8 +19,7 @@ namespace monitor::components
std::size_t m_current_open_index = 0;
private:
void create_snapshot(hr::setup setup);
std::string string_cut(std::filesystem::path p, int n);
void create_snapshot(utils::setup setup);
void change_tab(std::size_t i);
};
}

View File

@@ -17,10 +17,5 @@ namespace monitor
private:
components::panel m_panel;
components::tabs m_tabs;
private:
bool m_imgui_help_render = false;
bool m_plot_2d_help_render = false;
bool m_plot_3d_help_render = false;
};
}

View File

@@ -15,7 +15,7 @@ namespace monitor::libs
// сделать выбор устройства из интерфейса
// поставь, то которое есть в списке устройств
for (auto& d : devices) std::cout << d << std::endl;
std::string target_device = devices[2];
std::string target_device = devices[1];
if (sf::PlaybackDevice::setDevice(target_device))
hack::log()("Устройство успешно установлено: ", target_device);
else
@@ -25,25 +25,22 @@ namespace monitor::libs
void audio::set_file(std::filesystem::path p)
{
if (!m_music.openFromFile(p)) hack::error()("dont open file:", p.string());
std::vector<std::string> devices = sf::PlaybackDevice::getAvailableDevices();
std::string targetDevice = devices[1];
}
void audio::set_callback(std::function<void(sf::Time, float)> c)
void audio::set_callback(std::function<void(sf::Time)> c)
{
m_callback = c;
}
void audio::set_step(std::size_t step)
void audio::set_audio_pos(sf::Time t)
{
m_step = sf::microseconds(m_music.getDuration().asMicroseconds() / step);
m_music.setPlayingOffset(t);
}
void audio::set_audio_pos(double s)
{
m_ct = sf::microseconds(s * m_step.asMicroseconds());
m_music.setPlayingOffset(m_ct);
// m_ct = sf::microseconds(s * m_step.asMicroseconds());
// m_music.setPlayingOffset(m_ct);
}
void audio::toggle_play()
@@ -55,12 +52,6 @@ namespace monitor::libs
void audio::play()
{
m_music.play();
// ATTENTION: это нужно делать тут именно ПОСЛЕ начала воспроизведения
// а НЕ перед воспроизведением. т.к. установка времени перед проигрыванием не работает
// см. https://www.sfml-dev.org/documentation/2.6.1/classsf_1_1SoundStream.php#af416a5f84c8750d2acb9821d78bc8646
m_music.setPlayingOffset(m_ct);
emit();
}
@@ -68,9 +59,8 @@ namespace monitor::libs
{
while (is_playing())
{
m_ct = m_music.getPlayingOffset();
m_callback(sf::Time(), 1.0);
sf::sleep(m_step);
m_callback(m_music.getPlayingOffset());
sf::sleep(sf::milliseconds(20));
}
}

View File

@@ -20,9 +20,9 @@ namespace monitor::libs
void pause();
void toggle_play();
bool is_playing();
void set_callback(std::function<void(sf::Time, float)> c);
void set_step(std::size_t step);
void set_callback(std::function<void(sf::Time)> c);
void set_audio_pos(double s);
void set_audio_pos(sf::Time t);
private:
void emit();
@@ -31,8 +31,8 @@ namespace monitor::libs
std::filesystem::path m_file;
sf::Music m_music;
sf::Time m_ct = sf::Time::Zero;
sf::Time m_step;
std::function<void(sf::Time, float)> m_callback;
sf::Time m_step = sf::Time::Zero;
std::function<void(sf::Time)> m_callback;
};
}

View File

@@ -0,0 +1,42 @@
#include "gtkfd.hpp"
#include <hack/logger/logger.hpp>
namespace monitor::libs
{
void WaitForCleanup()
{
while (gtk_events_pending()) gtk_main_iteration();
}
struct widget_guard
{
GtkWidget* m_widget;
widget_guard(GtkWidget* w) : m_widget(w) {}
~widget_guard()
{
WaitForCleanup();
gtk_widget_destroy(m_widget);
WaitForCleanup();
}
};
std::filesystem::path gtkfd::open(const std::filesystem::path& default_path) noexcept
{
std::filesystem::path out_path;
if (!gtk_init_check(NULL, NULL))
{
hack::error()("Failed init gtk");
return out_path;
}
GtkWidget* widget = gtk_file_chooser_dialog_new("Open File", nullptr, GTK_FILE_CHOOSER_ACTION_OPEN, "_Cancel", GTK_RESPONSE_CANCEL, "_Open", GTK_RESPONSE_ACCEPT, nullptr);
widget_guard wg(widget);
// set the default path
gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(widget), default_path.c_str());
if (gtk_dialog_run(GTK_DIALOG(widget)) == GTK_RESPONSE_ACCEPT)
out_path = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(widget));
return out_path;
}
}

View File

@@ -0,0 +1,19 @@
#pragma once
#include <filesystem>
#include <gtk/gtk.h>
namespace monitor::libs
{
class gtkfd
{
public:
gtkfd() = default;
~gtkfd() = default;
public:
std::filesystem::path open(const std::filesystem::path& default_path) noexcept;
std::filesystem::path save(const std::filesystem::path& default_path, const std::string& default_name) noexcept;
};
}

View File

@@ -5,12 +5,21 @@ namespace monitor::utils
enum class event_type
{
CREATE_SNAPSHOT,
CREATE_SNAPSHOT_COMPLETED,
STATUS_PROCESS,
STATUS_COMPLETED,
INIT_AUDIO,
CHANGE_AUDIO,
SET_COMPRESSION,
SET_MARKER_AUDIO_POSITION,
PREPARE_BASE_PLUGIN_COMPRESSION,
/// делать
SET_AUDIO_POSITION,
AUDIO_PAUSE,
AUDIO_STOP,
INCREMENT_MARKER_AUDIO_POSITION,
SET_MARKER_AUDIO_POSITION,
SET_MARKER_MOUSE_POSITION
};
}

View File

@@ -0,0 +1,34 @@
#pragma once
#include <VE.hpp>
namespace monitor::utils::func
{
// бордюрчики у окна рисует нужного цвета и толщины
inline void draw_border(ImVec2 win_size)
{
ImDrawList* draw_list = ImGui::GetWindowDrawList();
ImVec2 win_pos = ImGui::GetWindowPos();
draw_list->AddRect(
win_pos,
ImVec2{ win_pos.x + win_size.x, win_pos.y + win_size.y },
VE::func::colorU32("#606373"),
0.f,
0,
1.f
);
}
// обрезает строку до нужного размера если борльше заявленного
inline std::string string_cut(std::filesystem::path p, int n)
{
std::string s_cut = p.filename();
if (static_cast<int>(s_cut.size()) > n)
{
s_cut.resize(n);
s_cut += " ...";
}
return s_cut;
}
}

View File

@@ -0,0 +1,58 @@
#pragma once
#include <VE.hpp>
#include <harmonica.hpp>
#include <math.h>
#include "monitor/utils/var.hpp"
namespace monitor::utils
{
struct plugin
{
public:
plugin() = default;
virtual ~plugin() = default;
public:
enum class TYPE
{
RAW_DATA,
FFT,
MAGNITUDE,
ENERGY
};
public:
hr::result m_result;
TYPE m_type;
std::string m_display_name;
public:
// градуировка осьи X
hr::fvec_t m_ox;
// размер данных для отрисовки. устанавливает размер графика
// и он меняется в зависимости от компересии
std::size_t m_size = utils::var::MAX_RENDER_SIZE;
// кол-во линий графика
std::size_t m_line_count = 0;
// тут кол-во графиков на массив данных из этих графиков т.е.:
// [1] = [1, 2, ..., 1'000'000'000]
// [2] = [1, 2, ..., 1'000'000'000]
std::vector<hr::fvec_t> m_line_data;
// говорит нужно ли делать сжатие графика ли нет
bool m_compression = false;
// шаг сжатия
std::size_t m_compression_step = 0;
public:
virtual bool empty() = 0;
virtual void init(hr::setup setup) = 0;
virtual void fill() = 0;
virtual void set_ox(std::size_t start_pos = 0) = 0;
};
}

View File

@@ -0,0 +1,61 @@
#include "fft.hpp"
namespace monitor::utils::plugins
{
fft::fft()
{
m_type = plugin::TYPE::FFT;
m_display_name = "FFT";
}
void fft::init(hr::setup setup)
{
try
{
// тут просто берем из первой линии, первые данные, т.к это fft см. реализацию самого плагина в harmonica
auto raw_size = m_result.m_data[0][0].m_values.size();
if (raw_size == 0) throw std::invalid_argument("Error set data in plugin: empty data");
// m_is_scale = raw_size > var::MAX_RENDER_SIZE;
// m_size = std::min(raw_size, var::MAX_RENDER_SIZE);
m_line_count = m_result.m_data.size();
m_line_data.reserve(m_line_count);
m_ox.reserve(m_result.m_grad.size());
for (std::size_t i = 0; i < m_line_count; ++i) m_line_data.push_back(hr::fvec_t(m_size, 0.f));
set_ox();
}
catch(std::exception& e)
{
hack::error()(e.what());
}
}
void fft::set_ox(std::size_t start_pos)
{
for (auto x : m_result.m_grad) m_ox.push_back(x);
}
void fft::fill()
{
if (m_compression) hack::error()("Данных больше чем можем отрисовать на экране, см. что-то с масштабированием...");
std::size_t line_count = 0;
for (auto el : m_result.m_data)
{
std::size_t index = 0;
for (auto e : el)
{
m_line_data[line_count][index] = e.m_value;
++index;
}
++line_count;
}
}
bool fft::empty()
{
return m_result.empty();
}
}

View File

@@ -0,0 +1,19 @@
#pragma once
#include "monitor/utils/plugin.hpp"
namespace monitor::utils::plugins
{
struct fft : public plugin
{
fft();
~fft() = default;
void init(hr::setup setup) override;
void set_ox(std::size_t start_pos = 0) override;
void fill() override;
bool empty() override;
};
}

View File

@@ -0,0 +1,56 @@
#include "magnitude.hpp"
namespace monitor::utils::plugins
{
magnitude::magnitude()
{
m_type = plugin::TYPE::MAGNITUDE;
m_display_name = "Magnitude";
}
void magnitude::init(hr::setup setup)
{
try
{
m_size = m_result.m_size;
m_compression_step = setup.m_step_size;
m_line_count = m_result.m_data.size();
m_line_data.reserve(m_line_count);
for (std::size_t i = 0; i < m_line_count; ++i) m_line_data.push_back(hr::fvec_t(m_size, 0.f));
set_ox();
}
catch(std::exception& e)
{
hack::error()(e.what());
}
}
void magnitude::fill()
{
std::size_t line_count = 0;
for (auto el : m_result.m_data)
{
std::size_t bin_index = 0;
for (auto e : el)
{
m_line_data[line_count][bin_index] = e.m_value;
++bin_index;
}
++line_count;
}
}
void magnitude::set_ox(std::size_t start_pos)
{
m_ox.reserve(m_size);
for (std::size_t i = start_pos; i < m_size + start_pos; ++i) m_ox.push_back(i);
}
bool magnitude::empty()
{
return m_result.empty();
}
}

View File

@@ -0,0 +1,19 @@
#pragma once
#include "monitor/utils/plugin.hpp"
namespace monitor::utils::plugins
{
struct magnitude : public plugin
{
magnitude();
~magnitude() = default;
void init(hr::setup setup) override;
void fill() override;
void set_ox(std::size_t start_pos = 0) override;
bool empty() override;
};
}

View File

@@ -0,0 +1,82 @@
#include "raw_data.hpp"
namespace monitor::utils::plugins
{
raw_data::raw_data()
{
m_type = plugin::TYPE::RAW_DATA;
m_display_name = "Raw Data";
}
void raw_data::init(hr::setup setup)
{
try
{
m_compression = m_result.m_size > m_size;
if (!m_compression) m_size = m_result.m_size;
m_line_count = m_result.m_data.size();
m_line_data.reserve(m_line_count);
for (std::size_t i = 0; i < m_line_count; ++i) m_line_data.push_back(hr::fvec_t(m_size, 0.f));
set_ox();
}
catch(std::exception& e)
{
hack::error()(e.what());
}
}
void raw_data::fill()
{
if (m_compression)
{
m_compression_step = m_result.m_size / m_size + 1;
std::size_t line_count = 0;
for (auto& gd : m_line_data)
{
std::size_t bin_index = 0;
for (auto& g : gd)
{
float tmp_e = 0.f;
for (std::size_t j = bin_index - m_compression_step; j < bin_index; ++j)
{
auto e = m_result.m_data[line_count][j].m_value;
tmp_e = hack::math::max_abs(e, tmp_e);
}
g = tmp_e;
bin_index += m_compression_step;
if (bin_index > m_result.m_size) bin_index = m_result.m_size;
}
m_size = bin_index / m_compression_step;
++line_count;
}
}
else
{
std::size_t line_count = 0;
for (auto el : m_result.m_data)
{
std::size_t bin_index = 0;
for (auto e : el)
{
m_line_data[line_count][bin_index] = e.m_value;
++bin_index;
}
++line_count;
}
}
}
void raw_data::set_ox(std::size_t start_pos)
{
m_ox.reserve(m_size);
for (std::size_t i = start_pos; i < m_size + start_pos; ++i) m_ox.push_back(i);
}
bool raw_data::empty()
{
return m_result.empty();
}
}

View File

@@ -0,0 +1,19 @@
#pragma once
#include "monitor/utils/plugin.hpp"
namespace monitor::utils::plugins
{
struct raw_data : public plugin
{
raw_data();
~raw_data() = default;
void init(hr::setup setup) override;
void fill() override;
void set_ox(std::size_t start_pos = 0) override;
bool empty() override;
};
}

View File

@@ -0,0 +1,14 @@
#pragma once
#include <harmonica.hpp>
namespace monitor::utils
{
struct setup : public hr::setup
{
// // это меняющеесе значение в зависимости от плагина, а не
// // как может показаться от аудио файла
// std::size_t m_graph_compression = 0;
};
}

View File

@@ -1,26 +0,0 @@
#pragma once
#include <harmonica.hpp>
#include "monitor/utils/var.hpp"
namespace monitor::utils::types
{
struct graph_data
{
// Это не массив как в dsp, а массив графиков
// в dsp там массив массивов где нa второй массив это данные
// а тут эти данные нужно обединить сразу в график линий и каждую линию сложить в этот массив
// обединение происходит в методе fill у spanshot
// т.е. в dsp как бы матрица, а тут она же но поднятая
std::vector<hr::fvec_t> m_render_data;
// ось X
hr::fvec_t m_ox;
// максимальное значение по оси Y
double m_max_element = 0.0;
std::string m_name = "default name";
var::PLUGIN_TYPE m_type;
};
}

View File

@@ -1,16 +0,0 @@
#pragma once
#include <hack/security/uuid.hpp>
#include "plugin_params.hpp"
namespace monitor::utils::types
{
struct leaner_system
{
std::string m_systaem_id = hack::security::generate_uuid();
std::string m_name;
std::string m_graph_type;
std::vector<utils::types::plugin_params> m_als;
utils::types::plugin_params m_base;
};
}

View File

@@ -1,28 +0,0 @@
#pragma once
#include <hack/security/uuid.hpp>
namespace monitor::utils::types
{
struct plugin_params
{
std::string m_plugin_id = hack::security::generate_uuid();
std::string m_type;
std::string m_name;
std::size_t m_block_size;
bool m_available = true;
// вся эта штука нужна для отрисовки бордюрчика когда данный фильтр
// выбран мышкой. Будь-то отдельная кнопка или массив кнопок.
bool m_selected = false;
bool m_on = false;
void clear() { m_name.clear(); m_selected = false; m_on = false; }
bool empty() { return m_name.empty(); }
void set(std::string n) { m_name = n; m_selected = true; on(); }
void off() { m_selected = false; m_on = false; }
void on() { m_on = true; }
bool operator==(const plugin_params& sf) { return sf.m_name == m_name; }
bool operator!=(const plugin_params& sf) { return sf.m_name != m_name; }
};
}

View File

@@ -1,31 +0,0 @@
#pragma once
#include <vector>
#include "monitor/libs/real_time/real_time.hpp"
#include "monitor/utils/using.hpp"
#include "monitor/utils/types/plugin_params.hpp"
namespace monitor::utils::types
{
class plugin_result
{
public:
struct bit
{
utils::real_time m_timestamp;
MATRIX m_value;
};
public:
plugin_params m_plugin_params;
std::vector<bit> m_data;
public:
void set_bit(bit& b) { m_data.push_back(b); }
std::size_t get_data_size() { return m_data.size(); }
std::size_t get_first_element_matrix_size(std::size_t i = 0) { return m_data[0].m_value[i].size(); }
void reserve(std::size_t s) { m_data.reserve(s); }
};
}

View File

@@ -1,13 +1,11 @@
#pragma once
#include <string>
#include <hack/logger/logger.hpp>
#include "noinc.hpp"
#include <cstddef>
namespace monitor::utils::var
{
const std::size_t MAX_RENDER_SIZE = 1'200'000;
const std::size_t MAX_RENDER_SIZE = 1'000'000;
const float WIN_PADDING = 4.f;
enum class STATUS
{
@@ -18,11 +16,4 @@ namespace monitor::utils::var
ACTIVE,
INACTIVE
};
enum class PLUGIN_TYPE
{
MAGNITUDE,
SEGMENTER,
ENERGY
};
}