diff options
Diffstat (limited to 'src/server/ControlBindings.hpp')
-rw-r--r-- | src/server/ControlBindings.hpp | 148 |
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 |