diff --git a/pd/ssrclient-help.pd b/pd/ssrclient-help.pd index 464ea4af..c3150b65 100644 --- a/pd/ssrclient-help.pd +++ b/pd/ssrclient-help.pd @@ -1,4 +1,4 @@ -#N canvas 1034 376 572 592 10; +#N canvas 1153 446 572 592 10; #X obj 98 174 ssrclient; #X obj 183 174 iemnet/tcpclient; #X msg 183 71 connect localhost 4711; @@ -34,7 +34,8 @@ #X text 14 30 Remote-control the SoundScape Renderer via network interface ; #X text 288 173 alternatively \, [mrpeach/tcpclient] can be used; -#X obj 98 375 route pos azi model vol mute level weights; +#X obj 98 375 route pos azi model vol mute level weights selected; +#X floatatom 441 496 5 0 0 0 selected - -; #X connect 0 0 24 0; #X connect 0 1 1 0; #X connect 1 0 0 1; @@ -60,4 +61,5 @@ #X connect 33 3 15 0; #X connect 33 4 14 0; #X connect 33 5 23 0; -#X connect 33 7 11 0; +#X connect 33 7 34 0; +#X connect 33 8 11 0; diff --git a/pd/ssrclient.pd_lua b/pd/ssrclient.pd_lua index 29e932ca..84f028fc 100644 --- a/pd/ssrclient.pd_lua +++ b/pd/ssrclient.pd_lua @@ -85,7 +85,7 @@ function SsrClient:initialize(name, atoms) table.insert(self.command, name) table.insert(self.command, value) self:output_command() - elseif name == "mute" or name == "fixed" then + elseif name == "mute" or name == "fixed" or name == "selected" then self:restore_command() table.insert(self.command, name) if value == "true" or value == "1" then diff --git a/src/boostnetwork/networksubscriber.cpp b/src/boostnetwork/networksubscriber.cpp index 88c3183e..266f3720 100644 --- a/src/boostnetwork/networksubscriber.cpp +++ b/src/boostnetwork/networksubscriber.cpp @@ -144,6 +144,15 @@ ssr::NetworkSubscriber::set_source_mute(id_t id, const bool& mute) return true; } +bool +ssr::NetworkSubscriber::set_source_selected(id_t id, const bool& mute) +{ + std::string ms = ""; + update_all_clients(ms); + return true; +} + bool ssr::NetworkSubscriber::set_source_name(id_t id, const std::string& name) { diff --git a/src/boostnetwork/networksubscriber.h b/src/boostnetwork/networksubscriber.h index bd6479d9..b27fbc12 100644 --- a/src/boostnetwork/networksubscriber.h +++ b/src/boostnetwork/networksubscriber.h @@ -67,6 +67,7 @@ class NetworkSubscriber : public Subscriber virtual bool set_source_orientation(id_t id, const Orientation& orientation); virtual bool set_source_gain(id_t id, const float& gain); virtual bool set_source_mute(id_t id, const bool& mute); + virtual bool set_source_selected(id_t id, const bool& mute); virtual bool set_source_name(id_t id, const std::string& name); virtual bool set_source_properties_file(id_t id, const std::string& name); virtual bool set_source_model(id_t id, const Source::model_t& model); diff --git a/src/controller.h b/src/controller.h index 1757a496..e4d8646c 100644 --- a/src/controller.h +++ b/src/controller.h @@ -153,6 +153,7 @@ class Controller : public Publisher virtual void set_source_signal_level(const id_t id , const float level); virtual void set_source_mute(id_t id, bool mute); + virtual void set_source_selected(id_t id, bool selected); virtual void set_source_name(id_t id, const std::string& name); virtual void set_source_properties_file(id_t id, const std::string& name); virtual void set_source_model(id_t id, Source::model_t model); @@ -1472,6 +1473,13 @@ Controller::set_source_mute(const id_t id, const bool mute) _publish(&Subscriber::set_source_mute, id, mute); } +template +void +Controller::set_source_selected(const id_t id, const bool selected) +{ + _publish(&Subscriber::set_source_selected, id, selected); +} + template void Controller::set_source_name(const id_t id, const std::string& name) @@ -1804,6 +1812,8 @@ Controller::_add_sources(Node& node source_node.new_attribute("volume", apf::str::A2S(apf::math::linear2dB(source.gain))); // TODO: information about mirror sources + source_node.new_attribute("selected", apf::str::A2S(source.selected)); + if (source.properties_file != "") { source_node.new_attribute("properties_file" diff --git a/src/gui/qopenglplotter.cpp b/src/gui/qopenglplotter.cpp index 061caf28..9951f4c6 100644 --- a/src/gui/qopenglplotter.cpp +++ b/src/gui/qopenglplotter.cpp @@ -1033,6 +1033,8 @@ void ssr::QOpenGLPlotter::_select_source(int source, bool add_to_selection) // make its id directly available _id_of_last_clicked_source = i->id; + + _controller.set_source_selected(i->id, true); } else if (!_alt_pressed) { @@ -1064,6 +1066,8 @@ void ssr::QOpenGLPlotter::_select_all_sources() // make valid id available _id_of_last_clicked_source = i->id; + _controller.set_source_selected(i->id, true); + n++; } } @@ -1074,6 +1078,8 @@ void ssr::QOpenGLPlotter::_deselect_source(int source) // and that id_of_last_clicked_source has a valid value if (_selected_sources_map.size() > 1) { + _controller.set_source_selected(_selected_sources_map[source], false); + _selected_sources_map.erase(source); _id_of_last_clicked_source = _selected_sources_map.begin()->second; } @@ -1081,6 +1087,10 @@ void ssr::QOpenGLPlotter::_deselect_source(int source) void ssr::QOpenGLPlotter::_deselect_all_sources() { + for (const auto& src: _selected_sources_map) + { + _controller.set_source_selected(src.second, false); + } _selected_sources_map.clear(); _id_of_last_clicked_source = 0; } diff --git a/src/publisher.h b/src/publisher.h index 6839cb95..9ad8bdf4 100644 --- a/src/publisher.h +++ b/src/publisher.h @@ -100,6 +100,7 @@ struct Publisher virtual void set_source_gain(id_t id, float gain) = 0; /// mute/unmute source virtual void set_source_mute(id_t id, bool mute) = 0; + virtual void set_source_selected(id_t id, bool mute) = 0; /// instantaneous level of audio stream virtual void set_source_signal_level(const id_t id, const float level) = 0; diff --git a/src/rendersubscriber.h b/src/rendersubscriber.h index 06c11e07..8a4debc1 100644 --- a/src/rendersubscriber.h +++ b/src/rendersubscriber.h @@ -100,6 +100,11 @@ class RenderSubscriber : public Subscriber return true; } + virtual bool set_source_selected(id_t, const bool&) + { + return true; + } + virtual bool set_source_name(id_t id, const std::string& name) { (void) id; diff --git a/src/scene.cpp b/src/scene.cpp index cdba5f7d..84f6c8d6 100644 --- a/src/scene.cpp +++ b/src/scene.cpp @@ -121,6 +121,11 @@ bool ssr::Scene::set_source_mute(id_t id, const bool& mute) return _set_source_member(id, &Source::mute, mute); } +bool ssr::Scene::set_source_selected(id_t id, const bool& selected) +{ + return _set_source_member(id, &Source::selected, selected); +} + bool ssr::Scene::set_source_name(id_t id, const std::string& name) { return _set_source_member(id, &Source::name, name); diff --git a/src/scene.h b/src/scene.h index 0cf8f556..2d374669 100644 --- a/src/scene.h +++ b/src/scene.h @@ -69,6 +69,7 @@ class Scene : public Subscriber virtual bool set_source_signal_level(id_t id, const float& level); virtual bool set_source_mute(id_t id, const bool& mute); + virtual bool set_source_selected(id_t id, const bool& mute); virtual bool set_source_name(id_t id, const std::string& name); virtual bool set_source_properties_file(id_t id, const std::string& name); virtual bool set_source_model(id_t id, const Source::model_t& model); diff --git a/src/source.h b/src/source.h index 8c20e3fc..403786aa 100644 --- a/src/source.h +++ b/src/source.h @@ -64,6 +64,7 @@ struct Source : DirectionalPoint file_length(0), model(Source::point), mute(0), + selected(0), gain(1.0), signal_level(0.0), output_levels(outputs), @@ -82,6 +83,7 @@ struct Source : DirectionalPoint file_length(0), model(Source::point), mute(0), + selected(0), gain(1.0), signal_level(0.0), has_mirror_sources(false), @@ -97,6 +99,7 @@ struct Source : DirectionalPoint long int file_length; ///< length of audio file, 0 if no file exists model_t model; ///< source model (=type) bool mute; ///< mute/unmute + bool selected; float gain; ///< source gain (volume) float signal_level; ///< instantaneous level of audio stream (linear scale, between 0 and 1) std::vector output_levels; diff --git a/src/subscriber.h b/src/subscriber.h index 7821a756..de5ee293 100644 --- a/src/subscriber.h +++ b/src/subscriber.h @@ -94,6 +94,8 @@ struct Subscriber /// _publish() function in the Controller class. virtual bool set_source_mute(id_t id, const bool& mute) = 0; + virtual bool set_source_selected(id_t id, const bool& mute) = 0; + /// Set source name. /// @param id ID of the source /// @param name new name