Use a timeout to reset faders' in_use flags when in BCF mode (ie with faders that...
[ardour2.git] / libs / surfaces / mackie / mackie_port.h
blobd12de3a099ff639701d71e5f72e9d0ac6e85e24d
1 /*
2 Copyright (C) 2006,2007 John Anderson
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 #ifndef mackie_port_h
19 #define mackie_port_h
21 #include <midi++/types.h>
22 #include <glibmm/thread.h>
24 #include "pbd/signals.h"
26 #include "surface_port.h"
27 #include "midi_byte_array.h"
28 #include "types.h"
30 namespace MIDI {
31 class Port;
32 class Parser;
35 class MackieControlProtocol;
37 namespace Mackie
40 class MackiePort : public SurfacePort
42 public:
43 enum port_type_t { mcu, ext };
44 enum emulation_t { none, mackie, bcf2000 };
46 MackiePort (MackieControlProtocol & mcp, MIDI::Port & input_port, MIDI::Port & output_port, int number, port_type_t = mcu);
47 ~MackiePort();
49 virtual void open();
50 virtual void close();
52 /// MCU and extenders have different sysex headers
53 virtual const MidiByteArray & sysex_hdr() const;
55 /// Handle device initialisation
56 void handle_midi_sysex( MIDI::Parser &, MIDI::byte *, size_t count );
58 /// Handle all control messags
59 void handle_midi_any( MIDI::Parser &, MIDI::byte *, size_t count );
61 Control & lookup_control( MIDI::byte *, size_t count );
63 /// return the number of strips associated with this port
64 virtual int strips() const;
66 /// Block until the port has finished initialising, and then return
67 /// whether the intialisation succeeded
68 bool wait_for_init();
70 emulation_t emulation() const { return _emulation; }
72 /// Connect the any signal from the parser to handle_midi_any
73 /// unless it's already connected
74 void connect_any();
76 protected:
77 /**
78 The initialisation sequence is fairly complex. First a lock is acquired
79 so that a condition can be used to signal the end of the init process.
80 Then a sysex is sent to the device. The response to the sysex
81 is handled by a switch in handle_midi_sysex which calls one of the
82 other methods.
84 However, windows DAWs ignore the documented init sequence and so we
85 do too. Thanks to Essox for helping with this.
87 So we use the version firmware to figure out what device is on
88 the other end of the cable.
90 void init();
92 /**
93 Once the device is initialised, finalise_init(true) is called, which
94 releases the lock and signals the condition, and starts handling incoming
95 messages. finalise_init(false) will also release the lock but doesn't
96 start handling messages.
98 void finalise_init( bool yn );
100 MidiByteArray host_connection_query( MidiByteArray & bytes );
101 MidiByteArray host_connection_confirmation( const MidiByteArray & bytes );
104 Will set _emulation to what it thinks is correct, based
105 on responses from the device. Or get/set parameters. Or
106 environment variables. Or existence of a file.
108 void probe_emulation( const MidiByteArray & bytes );
110 private:
111 MackieControlProtocol & _mcp;
112 port_type_t _port_type;
113 PBD::ScopedConnection any_connection;
114 PBD::ScopedConnection sysex_connection;
115 emulation_t _emulation;
117 bool _initialising;
118 Glib::Cond init_cond;
119 Glib::Mutex init_mutex;
124 #endif