From f280d3b64cb7b7eeed1524a67afea0461a21f1e4 Mon Sep 17 00:00:00 2001 From: Bruno Herbelin Date: Sat, 9 Mar 2024 00:05:56 +0100 Subject: [PATCH] New OSC Target for Alias and renaming source Allow creating temporary OSC aliases to link to a target by ID or name. Allow renaming a source from OSC. --- src/ControlManager.cpp | 75 +++++++++++++++++++++++++++++++----------- src/ControlManager.h | 9 +++-- 2 files changed, 62 insertions(+), 22 deletions(-) diff --git a/src/ControlManager.cpp b/src/ControlManager.cpp index f7dee83..dd46d5d 100644 --- a/src/ControlManager.cpp +++ b/src/ControlManager.cpp @@ -81,8 +81,8 @@ void Control::RequestListener::ProcessMessage( const osc::ReceivedMessage& m, if (address.size() > 2 && address.front().compare(OSC_PREFIX) == 0 ){ // done with the first part of the OSC address address.pop_front(); - // next part of the OSC message is the target - std::string target = address.front(); + // next part of the OSC message is the target, after alias correction + std::string target = Control::manager().alias( address.front() ); // next part of the OSC message is the attribute address.pop_front(); std::string attribute = address.front(); @@ -201,7 +201,42 @@ void Control::RequestListener::ProcessMessage( const osc::ReceivedMessage& m, int i = 0; std::string num = target.substr( target.find("#") == std::string::npos ? 1 : 2 ); if ( BaseToolkit::is_a_number(num, &i)){ - Source *s = Mixer::manager().sourceAtIndex(i); + // special case of creating an alias for given source target + if (attribute.compare(OSC_SOURCE_ALIAS) == 0) { + const char *label = nullptr; + m.ArgumentStream() >> label >> osc::EndMessage; + Control::manager().aliases_[std::string("/").append(label)] = target; + Log::Info(CONTROL_OSC_MSG "New alias /%s for target %s.", label, target.c_str()); + + } + // usual case, addressing the source by '#n' + else { + Source *s = Mixer::manager().sourceAtIndex(i); + if (s) { + // apply attributes to source + if ( Control::manager().receiveSourceAttribute(s, attribute, m.ArgumentStream()) ) + // and send back feedback if needed + Control::manager().sendSourceAttibutes(remoteEndpoint, target, s); + } + else + Log::Info(CONTROL_OSC_MSG "No source at ID %s targetted by %s.", num.c_str(), sender); + } + } + } + // General case: try to identify the target by name + else { + // special case of creating an alias for given source target + if (attribute.compare(OSC_SOURCE_ALIAS) == 0) { + const char *label = nullptr; + m.ArgumentStream() >> label >> osc::EndMessage; + Control::manager().aliases_[std::string("/").append(label)] = target; + Log::Info(CONTROL_OSC_MSG "New alias /%s for target %s.", label, target.c_str()); + } + // usual case, addressing the source by its name + else { + // try to find source by given name + Source *s = Mixer::manager().findSource(target.substr(1)); + // if a source with the given target name or index was found if (s) { // apply attributes to source if ( Control::manager().receiveSourceAttribute(s, attribute, m.ArgumentStream()) ) @@ -209,24 +244,9 @@ void Control::RequestListener::ProcessMessage( const osc::ReceivedMessage& m, Control::manager().sendSourceAttibutes(remoteEndpoint, target, s); } else - Log::Info(CONTROL_OSC_MSG "No source at ID %s targetted by %s.", num.c_str(), sender); + Log::Info(CONTROL_OSC_MSG "Unknown target '%s' requested by %s.", target.c_str(), sender); } } - // General case: try to identify the target by name - else { - // try to find source by given name - Source *s = Mixer::manager().findSource(target.substr(1)); - - // if a source with the given target name or index was found - if (s) { - // apply attributes to source - if ( Control::manager().receiveSourceAttribute(s, attribute, m.ArgumentStream()) ) - // and send back feedback if needed - Control::manager().sendSourceAttibutes(remoteEndpoint, target, s); - } - else - Log::Info(CONTROL_OSC_MSG "Unknown target '%s' requested by %s.", target.c_str(), sender); - } } else { Log::Info(CONTROL_OSC_MSG "Unknown osc message '%s' sent by %s.", m.AddressPattern(), sender); @@ -309,6 +329,15 @@ Control::~Control() terminate(); } +std::string Control::alias (std::string target) +{ + auto it_alias = aliases_.find(target); + if ( it_alias != aliases_.end() ) + return it_alias->second; + else + return target; +} + std::string Control::translate (std::string addresspattern) { auto it_translation = translation_.find(addresspattern); @@ -597,8 +626,14 @@ bool Control::receiveSourceAttribute(Source *target, const std::string &attribut return send_feedback; try { + /// e.g. '/vimix/#0/rename s toto' + if (attribute.compare(OSC_SOURCE_RENAME) == 0) { + const char *label = nullptr; + arguments >> label >> osc::EndMessage; + Mixer::manager().renameSource(target, label); + } /// e.g. '/vimix/current/play' or '/vimix/current/play T' or '/vimix/current/play F' - if ( attribute.compare(OSC_SOURCE_PLAY) == 0) { + else if ( attribute.compare(OSC_SOURCE_PLAY) == 0) { float on = 1.f; if ( !arguments.Eos()) { arguments >> on >> osc::EndMessage; diff --git a/src/ControlManager.h b/src/ControlManager.h index 1634838..743a720 100644 --- a/src/ControlManager.h +++ b/src/ControlManager.h @@ -34,6 +34,8 @@ #define OSC_PREVIOUS "/previous" #define OSC_SOURCE_NAME "/name" +#define OSC_SOURCE_RENAME "/rename" +#define OSC_SOURCE_ALIAS "/alias" #define OSC_SOURCE_LOCK "/lock" #define OSC_SOURCE_PLAY "/play" #define OSC_SOURCE_PAUSE "/pause" @@ -129,8 +131,6 @@ public: void update(); void terminate(); - // OSC translation - std::string translate (std::string addresspqattern); bool inputActive (uint id); float inputValue (uint id); @@ -170,6 +170,10 @@ protected: static void keyboardCalback(GLFWwindow*, int, int, int, int); + // OSC translation + std::string translate (std::string addresspqattern); + std::string alias (std::string target); + private: static void listen(); @@ -177,6 +181,7 @@ private: std::condition_variable receiver_end_; UdpListeningReceiveSocket *receiver_; + std::map aliases_; std::map translation_; void loadOscConfig(); void resetOscConfig();