Skip to content

Commit

Permalink
feat(midi): Add MIDI filtering option per input node
Browse files Browse the repository at this point in the history
  • Loading branch information
mfep committed May 14, 2024
1 parent d278837 commit 63724dc
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 39 deletions.
23 changes: 2 additions & 21 deletions src/Application.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ Application::Application(SDL_Window* window,
SDL_Renderer* renderer,
const std::filesystem::path& path_to_preset)
: m_theme_control(m_config, window), m_node_factory(m_theme_control, m_port_name_display),
m_preset{NodeEditor(m_node_factory, m_port_name_display, m_theme_control), {}},
m_preset{NodeEditor(m_node_factory, m_port_name_display, m_theme_control)},
m_preset_manager(m_preset, m_node_factory, m_config, m_port_name_display, m_theme_control),
m_port_name_display(m_config.get_show_full_port_names()),
m_welcome_enabled(m_config.get_show_welcome() && path_to_preset.empty()),
Expand Down Expand Up @@ -109,8 +109,7 @@ void Application::new_preset(bool create_nodes)
}
if (new_preset)
{
m_preset = {NodeEditor(m_node_factory, m_port_name_display, m_theme_control, create_nodes),
{}};
m_preset = {NodeEditor(m_node_factory, m_port_name_display, m_theme_control, create_nodes)};
m_preset_manager =
PresetManager(m_preset, m_node_factory, m_config, m_port_name_display, m_theme_control);
}
Expand Down Expand Up @@ -180,24 +179,6 @@ void Application::render_main_menu()
save_preset_as();
}
ImGui::Separator();
if (ImGui::BeginMenu("MIDI message filter"))
{
bool changed = ImGui::MenuItem(
"SysEx", nullptr, &m_preset.m_message_type_mask.m_sysex_enabled);
changed = ImGui::MenuItem(
"Clock", nullptr, &m_preset.m_message_type_mask.m_time_enabled) ||
changed;
changed = ImGui::MenuItem("Active Sensing",
nullptr,
&m_preset.m_message_type_mask.m_sensing_enabled) ||
changed;
if (changed)
{
// TODO
}
ImGui::EndMenu();
}
ImGui::Separator();
if (ImGui::MenuItem(" " ICON_FK_TIMES " Exit", "Alt+F4"))
{
exit();
Expand Down
33 changes: 32 additions & 1 deletion src/MidiInNode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ MidiInNode::MidiInNode(const midi::InputInfo& input_info,
: m_input_info(input_info), m_midi_input_node(midi_input_node),
m_port_name_display(&port_name_display)
{
m_midi_input_node->enable_message_types(m_message_type_mask);
m_midi_input_node->add_observer(this);
}

Expand Down Expand Up @@ -46,14 +47,44 @@ void MidiInNode::render_internal()
ImNodes::BeginOutputAttribute(out_id());
m_midi_activity.render();
ImGui::SameLine();

ImGui::TextUnformatted("all channels");
ImNodes::EndOutputAttribute();

ImGui::PushStyleColor(ImGuiCol_HeaderHovered, ImVec4{});
ImGui::PushStyleColor(ImGuiCol_HeaderActive, ImVec4{});
if (ImGui::TreeNode("Advanced"))
{
bool message_type_mask_changed = false;
if (ImGui::Checkbox("Receive SysEx", &m_message_type_mask.m_sysex_enabled))
{
message_type_mask_changed = true;
}
if (ImGui::Checkbox("Receive MIDI Clock", &m_message_type_mask.m_time_enabled))
{
message_type_mask_changed = true;
}
if (ImGui::Checkbox("Receive Active Sensing", &m_message_type_mask.m_sensing_enabled))
{
message_type_mask_changed = true;
}
if (message_type_mask_changed)
{
m_midi_input_node->enable_message_types(m_message_type_mask);
}
ImGui::TreePop();
}
ImGui::PopStyleColor(2);
}

void MidiInNode::message_processed(std::span<const unsigned char> /*message_bytes*/)
{
m_midi_activity.trigger();
}

void MidiInNode::set_message_type_mask(midi::MessageTypeMask new_value)
{
m_message_type_mask = new_value;
m_midi_input_node->enable_message_types(new_value);
}

} // namespace mc
4 changes: 4 additions & 0 deletions src/MidiInNode.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "ActivityIndicator.hpp"
#include "Node.hpp"
#include "midi/GraphObserver.hpp"
#include "midi/MessageTypeMask.hpp"
#include "midi/MidiInfo.hpp"

namespace mc
Expand Down Expand Up @@ -33,10 +34,13 @@ class MidiInNode final : public Node, private midi::GraphObserver
void render_internal() override;
void message_processed(std::span<const unsigned char> message_bytes) override;

void set_message_type_mask(midi::MessageTypeMask new_value);

midi::InputInfo m_input_info;
std::shared_ptr<midi::InputNode> m_midi_input_node;
ActivityIndicator m_midi_activity;
const PortNameDisplay* m_port_name_display;
midi::MessageTypeMask m_message_type_mask;

friend class NodeSerializer;
};
Expand Down
22 changes: 19 additions & 3 deletions src/NodeSerializer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,20 @@
#include "MidiInNode.hpp"
#include "MidiOutNode.hpp"
#include "NodeFactory.hpp"
#include "midi/MessageTypeMask.hpp"
#include "midi/MidiInfo.hpp"
#include "midi/MidiProbe.hpp"

NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(ImVec2, x, y);

namespace mc::midi
{
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(MessageTypeMask,
m_sysex_enabled,
m_time_enabled,
m_sensing_enabled);
}

namespace mc
{

Expand All @@ -43,8 +52,9 @@ void NodeSerializer::serialize_node(json& j, const Node& node) const
void NodeSerializer::serialize_node(json& j, const MidiInNode& node) const
{
j = json{
{"type", "midi_in" },
{"input_name", node.m_input_info.m_name}
{"type", "midi_in" },
{"input_name", node.m_input_info.m_name},
{"message_type_mask", node.m_message_type_mask},
};
}

Expand Down Expand Up @@ -98,7 +108,13 @@ std::shared_ptr<Node> NodeSerializer::deserialize_node(const json& j) const
const auto input_info_opt = midi::MidiProbe::get_valid_input(input_name);
if (input_info_opt.has_value())
{
node = m_node_factory->build_midi_node(input_info_opt.value());
auto midi_in_node = m_node_factory->build_midi_node(input_info_opt.value());
if (j.contains("message_type_mask"))
{
midi_in_node->set_message_type_mask(
j.at("message_type_mask").get<midi::MessageTypeMask>());
}
node = midi_in_node;
}
else
{
Expand Down
12 changes: 1 addition & 11 deletions src/PresetManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,30 +11,20 @@
#include "Utils.hpp"
#include "Version.hpp"

namespace mc::midi
{
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(MessageTypeMask,
m_sysex_enabled,
m_time_enabled,
m_sensing_enabled);
}

namespace mc
{

void Preset::to_json(nlohmann::json& j) const
{
m_node_editor.to_json(j["editor"]);
j["enabled_message_types"] = m_message_type_mask;
}

Preset Preset::from_json(NodeFactory& node_factory,
const PortNameDisplay& port_name_display,
const ThemeControl& theme_control,
const nlohmann::json& j)
{
return {NodeEditor::from_json(node_factory, port_name_display, theme_control, j.at("editor")),
j.at("enabled_message_types")};
return {NodeEditor::from_json(node_factory, port_name_display, theme_control, j.at("editor"))};
}

PresetManager::PresetManager(const Preset& preset,
Expand Down
4 changes: 1 addition & 3 deletions src/PresetManager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
#include "nlohmann/json.hpp"

#include "NodeEditor.hpp"
#include "midi/MessageTypeMask.hpp"

namespace mc
{
Expand All @@ -16,8 +15,7 @@ class ThemeControl;

struct Preset
{
NodeEditor m_node_editor;
midi::MessageTypeMask m_message_type_mask;
NodeEditor m_node_editor;

void to_json(nlohmann::json& j) const;
static Preset from_json(NodeFactory& node_factory,
Expand Down

0 comments on commit 63724dc

Please sign in to comment.