summaryrefslogtreecommitdiffstats
path: root/src/server/ControlBindings.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/ControlBindings.hpp')
-rw-r--r--src/server/ControlBindings.hpp148
1 files changed, 148 insertions, 0 deletions
diff --git a/src/server/ControlBindings.hpp b/src/server/ControlBindings.hpp
new file mode 100644
index 00000000..ea170f81
--- /dev/null
+++ b/src/server/ControlBindings.hpp
@@ -0,0 +1,148 @@
+/*
+ This file is part of Ingen.
+ Copyright 2007-2015 David Robillard <http://drobilla.net/>
+
+ Ingen is free software: you can redistribute it and/or modify it under the
+ terms of the GNU Affero General Public License as published by the Free
+ Software Foundation, either version 3 of the License, or any later version.
+
+ Ingen is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU Affero General Public License for details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with Ingen. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef INGEN_ENGINE_CONTROLBINDINGS_HPP
+#define INGEN_ENGINE_CONTROLBINDINGS_HPP
+
+#include <atomic>
+#include <cstdint>
+#include <vector>
+
+#include <boost/intrusive/options.hpp>
+#include <boost/intrusive/set.hpp>
+
+#include "ingen/Atom.hpp"
+#include "ingen/types.hpp"
+#include "lv2/atom/forge.h"
+#include "raul/Maid.hpp"
+#include "raul/Path.hpp"
+
+#include "BufferFactory.hpp"
+
+namespace ingen {
+namespace server {
+
+class Engine;
+class RunContext;
+class PortImpl;
+
+class ControlBindings {
+public:
+ enum class Type : uint16_t {
+ NULL_CONTROL,
+ MIDI_BENDER,
+ MIDI_CC,
+ MIDI_RPN,
+ MIDI_NRPN,
+ MIDI_CHANNEL_PRESSURE,
+ MIDI_NOTE
+ };
+
+ struct Key {
+ Key(Type t=Type::NULL_CONTROL, int16_t n=0) : type(t), num(n) {}
+ inline bool operator<(const Key& other) const {
+ return ((type < other.type) ||
+ (type == other.type && num < other.num));
+ }
+ inline bool operator==(const Key& other) const {
+ return type == other.type && num == other.num;
+ }
+ inline bool operator!() const { return type == Type::NULL_CONTROL; }
+ Type type;
+ int16_t num;
+ };
+
+ /** One binding of a controller to a port. */
+ struct Binding : public boost::intrusive::set_base_hook<>,
+ public Raul::Maid::Disposable {
+ Binding(Key k=Key(), PortImpl* p=nullptr) : key(std::move(k)), port(p) {}
+
+ inline bool operator<(const Binding& rhs) const { return key < rhs.key; }
+
+ Key key;
+ PortImpl* port;
+ };
+
+ /** Comparator for bindings by key. */
+ struct BindingLess {
+ bool operator()(const Binding& lhs, const Binding& rhs) const {
+ return lhs.key < rhs.key;
+ }
+ };
+
+ explicit ControlBindings(Engine& engine);
+ ~ControlBindings();
+
+ Key port_binding(PortImpl* port) const;
+ Key binding_key(const Atom& binding) const;
+
+ void start_learn(PortImpl* port);
+
+ /** Set the binding for `port` to `binding` and take ownership of it. */
+ bool set_port_binding(RunContext& ctx,
+ PortImpl* port,
+ Binding* binding,
+ const Atom& value);
+
+ void port_value_changed(RunContext& ctx,
+ PortImpl* port,
+ Key key,
+ const Atom& value_atom);
+
+ void pre_process(RunContext& ctx, Buffer* buffer);
+ void post_process(RunContext& ctx, Buffer* buffer);
+
+ /** Get all bindings for `path` or children of `path`. */
+ void get_all(const Raul::Path& path, std::vector<Binding*>& bindings);
+
+ /** Remove a set of bindings from an earlier call to get_all(). */
+ void remove(RunContext& ctx, const std::vector<Binding*>& bindings);
+
+private:
+ typedef boost::intrusive::multiset<
+ Binding,
+ boost::intrusive::compare<BindingLess> > Bindings;
+
+ Key midi_event_key(uint16_t size, const uint8_t* buf, uint16_t& value);
+
+ void set_port_value(RunContext& context,
+ PortImpl* port,
+ Type type,
+ int16_t value);
+
+ bool finish_learn(RunContext& context, Key key);
+
+ float control_to_port_value(RunContext& context,
+ const PortImpl* port,
+ Type type,
+ int16_t value) const;
+
+ int16_t port_value_to_control(RunContext& context,
+ PortImpl* port,
+ Type type,
+ const Atom& value_atom) const;
+
+ Engine& _engine;
+ std::atomic<Binding*> _learn_binding;
+ SPtr<Bindings> _bindings;
+ BufferRef _feedback;
+ LV2_Atom_Forge _forge;
+};
+
+} // namespace server
+} // namespace ingen
+
+#endif // INGEN_ENGINE_CONTROLBINDINGS_HPP