From 9a99f038176a7fadc59bbeaa3d3d57f16e4abb74 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Fri, 23 Sep 2011 18:11:49 +0000 Subject: Animate audio port colours based on levels. git-svn-id: http://svn.drobilla.net/lad/trunk/ingen@3475 a436a847-0d15-0410-975c-d299462d15a1 --- src/server/AudioBuffer.cpp | 11 +++++++++++ src/server/AudioBuffer.hpp | 11 ++++++++--- src/server/ClientBroadcaster.hpp | 6 +++++- src/server/HTTPClientSender.cpp | 18 ++++++++++++++---- src/server/HTTPClientSender.hpp | 3 ++- src/server/InputPort.cpp | 15 +++++++++++---- src/server/Notification.cpp | 2 +- src/server/OSCClientSender.cpp | 7 +++++-- src/server/OSCClientSender.hpp | 3 ++- src/server/OutputPort.cpp | 3 +-- src/server/PortImpl.cpp | 10 +++++++--- 11 files changed, 67 insertions(+), 22 deletions(-) (limited to 'src/server') diff --git a/src/server/AudioBuffer.cpp b/src/server/AudioBuffer.cpp index 27b78cfb..7a8e7c48 100644 --- a/src/server/AudioBuffer.cpp +++ b/src/server/AudioBuffer.cpp @@ -184,6 +184,17 @@ AudioBuffer::copy(Context& context, const Buffer* src) } } +float +AudioBuffer::peak(Context& context) const +{ + float peak = 0.0f; + // FIXME: use context time range? + for (FrameTime i = 0; i < nframes(); ++i) { + peak = fmaxf(peak, value_at(i)); + } + return peak; +} + void AudioBuffer::prepare_read(Context& context) { diff --git a/src/server/AudioBuffer.hpp b/src/server/AudioBuffer.hpp index 4a7869e2..5ecbcea5 100644 --- a/src/server/AudioBuffer.hpp +++ b/src/server/AudioBuffer.hpp @@ -18,12 +18,15 @@ #ifndef INGEN_ENGINE_AUDIOBUFFER_HPP #define INGEN_ENGINE_AUDIOBUFFER_HPP -#include #include +#include +#include + #include -#include "types.hpp" -#include "ObjectBuffer.hpp" + #include "Context.hpp" +#include "ObjectBuffer.hpp" +#include "types.hpp" using namespace std; @@ -43,6 +46,8 @@ public: void copy(Context& context, const Buffer* src); void accumulate(Context& context, const AudioBuffer* src); + float peak(Context& context) const; + inline bool is_control() const { return _type.symbol() == PortType::CONTROL; } inline Sample* data() const { diff --git a/src/server/ClientBroadcaster.hpp b/src/server/ClientBroadcaster.hpp index c34bb34b..3d49dc4a 100644 --- a/src/server/ClientBroadcaster.hpp +++ b/src/server/ClientBroadcaster.hpp @@ -119,7 +119,11 @@ public: void response_error(int32_t id, const std::string& msg) {} ///< N/A void error(const std::string& msg) { BROADCAST(error, msg); } - void activity(const Raul::Path& path) { BROADCAST(activity, path); } + + void activity(const Raul::Path& path, + const Raul::Atom& value) { + BROADCAST(activity, path, value); + } private: typedef std::map Clients; diff --git a/src/server/HTTPClientSender.cpp b/src/server/HTTPClientSender.cpp index a71701eb..990b28e5 100644 --- a/src/server/HTTPClientSender.cpp +++ b/src/server/HTTPClientSender.cpp @@ -124,12 +124,22 @@ HTTPClientSender::set_property(const URI& subject, const URI& key, const Atom& v } void -HTTPClientSender::activity(const Path& path) +HTTPClientSender::activity(const Path& path, const Raul::Atom& value) { - const string msg = string( + if (value.type() == Atom::BOOL) { + const string msg = string( "@prefix ingen: .\n\n<").append( - path.str()).append("> ingen:activity true .\n"); - send_chunk(msg); + path.str()).append("> ingen:activity true .\n"); + send_chunk(msg); + } else if (value.type() == Atom::FLOAT) { + const string msg = string( + "@prefix ingen: .\n\n<").append( + path.str()).append("> ingen:activity ").append( + value.get_bool() ? "true" : "false").append(" .\n"); + send_chunk(msg); + } else { + warn << "Unknown activity type at " << path << endl; + } } void diff --git a/src/server/HTTPClientSender.hpp b/src/server/HTTPClientSender.hpp index 71f705da..ae286af1 100644 --- a/src/server/HTTPClientSender.hpp +++ b/src/server/HTTPClientSender.hpp @@ -93,7 +93,8 @@ public: const Raul::URI& predicate, const Raul::Atom& value); - virtual void activity(const Raul::Path& path); + virtual void activity(const Raul::Path& path, + const Raul::Atom& value); private: Engine& _engine; diff --git a/src/server/InputPort.cpp b/src/server/InputPort.cpp index 2f871e44..b0866fde 100644 --- a/src/server/InputPort.cpp +++ b/src/server/InputPort.cpp @@ -25,6 +25,7 @@ #include "ConnectionImpl.hpp" #include "EventBuffer.hpp" #include "NodeImpl.hpp" +#include "Notification.hpp" #include "OutputPort.hpp" #include "ProcessContext.hpp" #include "ThreadManager.hpp" @@ -122,9 +123,8 @@ InputPort::add_connection(Connections::Node* const c) _connections.push_back(c); - // Automatically broadcast connected control inputs - if (is_a(PortType::CONTROL)) - _broadcast = true; + // Broadcast value/activity of connected input + _broadcast = true; } /** Remove a connection. Realtime safe. @@ -156,8 +156,15 @@ InputPort::remove_connection(ProcessContext& context, const OutputPort* src_port } // Turn off broadcasting if we're no longer connected - if (is_a(PortType::CONTROL) && _connections.size() == 0) + if (_connections.size() == 0) { + if (is_a(PortType::AUDIO)) { + // Send an update peak of 0.0 to reset to silence + const Notification note = Notification::make( + Notification::PORT_ACTIVITY, context.start(), this, 0.0f); + context.event_sink().write(sizeof(note), ¬e); + } _broadcast = false; + } return connection; } diff --git a/src/server/Notification.cpp b/src/server/Notification.cpp index 9181147f..0808c00e 100644 --- a/src/server/Notification.cpp +++ b/src/server/Notification.cpp @@ -35,7 +35,7 @@ Notification::post_process(Notification& note, engine.world()->uris()->ingen_value, note.value); break; case PORT_ACTIVITY: - engine.broadcaster()->activity(note.port->path()); + engine.broadcaster()->activity(note.port->path(), note.value); break; case PORT_BINDING: { const Ingen::Shared::LV2URIMap& uris = *engine.world()->uris().get(); diff --git a/src/server/OSCClientSender.cpp b/src/server/OSCClientSender.cpp index ad2e179c..5e9c01f0 100644 --- a/src/server/OSCClientSender.cpp +++ b/src/server/OSCClientSender.cpp @@ -261,12 +261,15 @@ OSCClientSender::set_property(const URI& path, * Notification of "activity" (e.g. port message blinkenlights). */ void -OSCClientSender::activity(const Path& path) +OSCClientSender::activity(const Path& path, const Raul::Atom& value) { if (!_enabled) return; - lo_send(_address, "/activity", "s", path.c_str(), LO_ARGS_END); + lo_message m = lo_message_new(); + lo_message_add_string(m, path.c_str()); + AtomLiblo::lo_message_add_atom(m, value); + send_message("/activity", m); } } // namespace Server diff --git a/src/server/OSCClientSender.hpp b/src/server/OSCClientSender.hpp index 208497b1..95f3ea4f 100644 --- a/src/server/OSCClientSender.hpp +++ b/src/server/OSCClientSender.hpp @@ -96,7 +96,8 @@ public: const Raul::URI& predicate, const Raul::Atom& value); - virtual void activity(const Raul::Path& path); + virtual void activity(const Raul::Path& path, + const Raul::Atom& value); private: Raul::URI _url; diff --git a/src/server/OutputPort.cpp b/src/server/OutputPort.cpp index 487832c3..c96c6b04 100644 --- a/src/server/OutputPort.cpp +++ b/src/server/OutputPort.cpp @@ -40,8 +40,7 @@ OutputPort::OutputPort(BufferFactory& bufs, if (!dynamic_cast(parent)) add_property(bufs.uris().rdf_type, bufs.uris().lv2_OutputPort); - if (type == PortType::CONTROL) - _broadcast = true; + _broadcast = true; setup_buffers(bufs, poly); } diff --git a/src/server/PortImpl.cpp b/src/server/PortImpl.cpp index 2e1ad61e..73953b5c 100644 --- a/src/server/PortImpl.cpp +++ b/src/server/PortImpl.cpp @@ -76,9 +76,6 @@ PortImpl::PortImpl(BufferFactory& bufs, add_property(uris.rdf_type, type.uri()); set_property(uris.lv2_index, Atom((int32_t)index)); set_context(_context); - - if (type == PortType::EVENTS) - _broadcast = true; // send activity blips } PortImpl::~PortImpl() @@ -208,6 +205,13 @@ PortImpl::broadcast_value(Context& context, bool force) case PortType::UNKNOWN: break; case PortType::AUDIO: + val = ((AudioBuffer*)buffer(0).get())->peak(context); + { + const Notification note = Notification::make( + Notification::PORT_ACTIVITY, context.start(), this, val); + context.event_sink().write(sizeof(note), ¬e); + } + return; case PortType::CONTROL: val = ((AudioBuffer*)buffer(0).get())->value_at(0); break; -- cgit v1.2.1