1 /* 2 * Copyright (C) 2006-2018 Paul Davis <paul@linuxaudiosystems.com> 3 * Copyright (C) 2007-2016 Tim Mayberry <mojofunk@gmail.com> 4 * Copyright (C) 2009-2012 Carl Hetherington <carl@carlh.net> 5 * Copyright (C) 2009 David Robillard <d@drobilla.net> 6 * Copyright (C) 2015-2019 Robin Gareus <robin@gareus.org> 7 * Copyright (C) 2015 Len Ovens <len@ovenwerks.net> 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License as published by 11 * the Free Software Foundation; either version 2 of the License, or 12 * (at your option) any later version. 13 * 14 * This program is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License along 20 * with this program; if not, write to the Free Software Foundation, Inc., 21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 22 */ 23 24 #ifndef __gm_midicontrollable_h__ 25 #define __gm_midicontrollable_h__ 26 27 #include <string> 28 29 #include "midi++/types.h" 30 31 #include "pbd/controllable.h" 32 #include "pbd/signals.h" 33 #include "pbd/stateful.h" 34 35 #include "ardour/types.h" 36 37 namespace MIDI { 38 class Channel; 39 class Parser; 40 } 41 42 class GenericMidiControlProtocol; 43 44 namespace ARDOUR { 45 class AsyncMIDIPort; 46 } 47 48 class MIDIControllable : public PBD::Stateful 49 { 50 public: 51 MIDIControllable (GenericMidiControlProtocol*, MIDI::Parser&, boost::shared_ptr<PBD::Controllable>, bool momentary); 52 MIDIControllable (GenericMidiControlProtocol*, MIDI::Parser&, bool momentary = false); 53 virtual ~MIDIControllable (); 54 55 int init (const std::string&); 56 57 void rediscover_controllable (); bank_relative()58 bool bank_relative() const { return _bank_relative; } rid()59 uint32_t rid() const { return _rid; } what()60 std::string what() const { return _what; } 61 62 enum CtlType { 63 Ctl_Momentary, 64 Ctl_Toggle, 65 Ctl_Dial, 66 }; 67 68 enum Encoder { 69 No_enc, 70 Enc_R, 71 Enc_L, 72 Enc_2, 73 Enc_B, 74 }; 75 76 MIDI::byte* write_feedback (MIDI::byte* buf, int32_t& bufsize, bool force = false); 77 78 void midi_rebind (MIDI::channel_t channel=-1); 79 void midi_forget (); 80 void learn_about_external_control (); 81 void stop_learning (); 82 void drop_external_control (); 83 84 int control_to_midi(float val); 85 float midi_to_control(int val); 86 learned()87 bool learned() const { return _learned; } 88 get_ctltype()89 CtlType get_ctltype() const { return _ctltype; } set_ctltype(CtlType val)90 void set_ctltype (CtlType val) { _ctltype = val; } 91 get_encoder()92 Encoder get_encoder() const { return _encoder; } set_encoder(Encoder val)93 void set_encoder (Encoder val) { _encoder = val; } 94 get_parser()95 MIDI::Parser& get_parser() { return _parser; } 96 void set_controllable (boost::shared_ptr<PBD::Controllable>); 97 boost::shared_ptr<PBD::Controllable> get_controllable () const; current_uri()98 const std::string& current_uri() const { return _current_uri; } 99 control_description()100 std::string control_description() const { return _control_description; } 101 102 XMLNode& get_state (void); 103 int set_state (const XMLNode&, int version); 104 105 void bind_midi (MIDI::channel_t, MIDI::eventType, MIDI::byte); 106 void bind_rpn_value (MIDI::channel_t, uint16_t rpn); 107 void bind_nrpn_value (MIDI::channel_t, uint16_t rpn); 108 void bind_rpn_change (MIDI::channel_t, uint16_t rpn); 109 void bind_nrpn_change (MIDI::channel_t, uint16_t rpn); 110 get_control_channel()111 MIDI::channel_t get_control_channel () { return control_channel; } get_control_type()112 MIDI::eventType get_control_type () { return control_type; } get_control_additional()113 MIDI::byte get_control_additional () { return control_additional; } 114 115 int lookup_controllable(); 116 117 private: 118 119 int max_value_for_type () const; 120 121 GenericMidiControlProtocol* _surface; 122 boost::shared_ptr<PBD::Controllable> _controllable; 123 std::string _current_uri; 124 MIDI::Parser& _parser; 125 bool setting; 126 int last_value; 127 int last_incoming; 128 float last_controllable_value; 129 bool _momentary; 130 bool _is_gain_controller; 131 bool _learned; 132 CtlType _ctltype; 133 Encoder _encoder; 134 int midi_msg_id; /* controller ID or note number */ 135 PBD::ScopedConnection midi_sense_connection[2]; 136 PBD::ScopedConnection midi_learn_connection; 137 PBD::ScopedConnection controllable_death_connection; 138 /** the type of MIDI message that is used for this control */ 139 MIDI::eventType control_type; 140 MIDI::byte control_additional; 141 MIDI::channel_t control_channel; 142 std::string _control_description; 143 int16_t control_rpn; 144 int16_t control_nrpn; 145 uint32_t _rid; 146 std::string _what; 147 bool _bank_relative; 148 149 void drop_controllable (); 150 Glib::Threads::Mutex controllable_lock; 151 152 void midi_receiver (MIDI::Parser &p, MIDI::byte *, size_t); 153 void midi_sense_note (MIDI::Parser &, MIDI::EventTwoBytes *, bool is_on); 154 void midi_sense_note_on (MIDI::Parser &p, MIDI::EventTwoBytes *tb); 155 void midi_sense_note_off (MIDI::Parser &p, MIDI::EventTwoBytes *tb); 156 void midi_sense_controller (MIDI::Parser &, MIDI::EventTwoBytes *); 157 void midi_sense_program_change (MIDI::Parser &, MIDI::byte); 158 void midi_sense_pitchbend (MIDI::Parser &, MIDI::pitchbend_t); 159 160 void nrpn_value_change (MIDI::Parser&, uint16_t nrpn, float val); 161 void rpn_value_change (MIDI::Parser&, uint16_t nrpn, float val); 162 void rpn_change (MIDI::Parser&, uint16_t nrpn, int direction); 163 void nrpn_change (MIDI::Parser&, uint16_t nrpn, int direction); 164 }; 165 166 #endif // __gm_midicontrollable_h__ 167