major redesign of MIDI port heirarchy and management (part 2)
This commit is contained in:
@@ -32,13 +32,14 @@
|
||||
#include "pbd/xml++.h"
|
||||
|
||||
#include "midi++/port.h"
|
||||
#include "midi++/manager.h"
|
||||
|
||||
#include "ardour/audioengine.h"
|
||||
#include "ardour/filesystem_paths.h"
|
||||
#include "ardour/session.h"
|
||||
#include "ardour/route.h"
|
||||
#include "ardour/midi_ui.h"
|
||||
#include "ardour/rc_configuration.h"
|
||||
#include "ardour/midiport_manager.h"
|
||||
|
||||
#include "generic_midi_control_protocol.h"
|
||||
#include "midicontrollable.h"
|
||||
@@ -59,8 +60,8 @@ GenericMidiControlProtocol::GenericMidiControlProtocol (Session& s)
|
||||
, _threshold (10)
|
||||
, gui (0)
|
||||
{
|
||||
_input_port = MIDI::Manager::instance()->midi_input_port ();
|
||||
_output_port = MIDI::Manager::instance()->midi_output_port ();
|
||||
_input_port = AudioEngine::instance()->midi_input_port ();
|
||||
_output_port = AudioEngine::instance()->midi_output_port ();
|
||||
|
||||
do_feedback = false;
|
||||
_feedback_interval = 10000; // microseconds
|
||||
@@ -338,7 +339,7 @@ GenericMidiControlProtocol::start_learning (Controllable* c)
|
||||
}
|
||||
|
||||
if (!mc) {
|
||||
mc = new MIDIControllable (this, *_input_port, *c, false);
|
||||
mc = new MIDIControllable (this, *_input_port->parser(), *c, false);
|
||||
}
|
||||
|
||||
{
|
||||
@@ -435,7 +436,7 @@ GenericMidiControlProtocol::create_binding (PBD::Controllable* control, int pos,
|
||||
MIDI::byte value = control_number;
|
||||
|
||||
// Create a MIDIControllable
|
||||
MIDIControllable* mc = new MIDIControllable (this, *_input_port, *control, false);
|
||||
MIDIControllable* mc = new MIDIControllable (this, *_input_port->parser(), *control, false);
|
||||
|
||||
// Remove any old binding for this midi channel/type/value pair
|
||||
// Note: can't use delete_binding() here because we don't know the specific controllable we want to remove, only the midi information
|
||||
@@ -559,7 +560,7 @@ GenericMidiControlProtocol::set_state (const XMLNode& node, int version)
|
||||
Controllable* c = Controllable::by_id (id);
|
||||
|
||||
if (c) {
|
||||
MIDIControllable* mc = new MIDIControllable (this, *_input_port, *c, false);
|
||||
MIDIControllable* mc = new MIDIControllable (this, *_input_port->parser(), *c, false);
|
||||
|
||||
if (mc->set_state (**niter, version) == 0) {
|
||||
controllables.push_back (mc);
|
||||
@@ -754,7 +755,7 @@ GenericMidiControlProtocol::create_binding (const XMLNode& node)
|
||||
prop = node.property (X_("uri"));
|
||||
uri = prop->value();
|
||||
|
||||
MIDIControllable* mc = new MIDIControllable (this, *_input_port, momentary);
|
||||
MIDIControllable* mc = new MIDIControllable (this, *_input_port->parser(), momentary);
|
||||
|
||||
if (mc->init (uri)) {
|
||||
delete mc;
|
||||
@@ -892,7 +893,7 @@ GenericMidiControlProtocol::create_function (const XMLNode& node)
|
||||
|
||||
prop = node.property (X_("function"));
|
||||
|
||||
MIDIFunction* mf = new MIDIFunction (*_input_port);
|
||||
MIDIFunction* mf = new MIDIFunction (*_input_port->parser());
|
||||
|
||||
if (mf->setup (*this, prop->value(), argument, data, data_size)) {
|
||||
delete mf;
|
||||
@@ -988,7 +989,7 @@ GenericMidiControlProtocol::create_action (const XMLNode& node)
|
||||
|
||||
prop = node.property (X_("action"));
|
||||
|
||||
MIDIAction* ma = new MIDIAction (*_input_port);
|
||||
MIDIAction* ma = new MIDIAction (*_input_port->parser());
|
||||
|
||||
if (ma->init (*this, prop->value(), data, data_size)) {
|
||||
delete ma;
|
||||
|
||||
@@ -22,14 +22,11 @@
|
||||
|
||||
#include <list>
|
||||
#include <glibmm/threads.h>
|
||||
|
||||
#include "ardour/types.h"
|
||||
|
||||
#include "control_protocol/control_protocol.h"
|
||||
|
||||
namespace MIDI {
|
||||
class Port;
|
||||
}
|
||||
|
||||
namespace PBD {
|
||||
class Controllable;
|
||||
class ControllableDescriptor;
|
||||
@@ -37,6 +34,11 @@ namespace PBD {
|
||||
|
||||
namespace ARDOUR {
|
||||
class Session;
|
||||
class MidiPort;
|
||||
}
|
||||
|
||||
namespace MIDI {
|
||||
class Port;
|
||||
}
|
||||
|
||||
class MIDIControllable;
|
||||
@@ -51,8 +53,8 @@ class GenericMidiControlProtocol : public ARDOUR::ControlProtocol {
|
||||
int set_active (bool yn);
|
||||
static bool probe() { return true; }
|
||||
|
||||
MIDI::Port* input_port () const { return _input_port; }
|
||||
MIDI::Port* output_port () const { return _output_port; }
|
||||
MIDI::Port* input_port () const { return _input_port; }
|
||||
MIDI::Port* output_port () const { return _output_port; }
|
||||
void set_feedback_interval (ARDOUR::microseconds_t);
|
||||
|
||||
int set_feedback (bool yn);
|
||||
@@ -97,8 +99,8 @@ class GenericMidiControlProtocol : public ARDOUR::ControlProtocol {
|
||||
}
|
||||
|
||||
private:
|
||||
MIDI::Port* _input_port;
|
||||
MIDI::Port* _output_port;
|
||||
MIDI::Port* _input_port;
|
||||
MIDI::Port* _output_port;
|
||||
ARDOUR::microseconds_t _feedback_interval;
|
||||
ARDOUR::microseconds_t last_feedback_time;
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
using namespace MIDI;
|
||||
|
||||
MIDIAction::MIDIAction (MIDI::Port& p)
|
||||
MIDIAction::MIDIAction (MIDI::Parser& p)
|
||||
: MIDIInvokable (p)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -36,8 +36,6 @@ namespace Gtk {
|
||||
}
|
||||
|
||||
namespace MIDI {
|
||||
class Channel;
|
||||
class Port;
|
||||
class Parser;
|
||||
}
|
||||
|
||||
@@ -46,7 +44,7 @@ class GenericMidiControlProtocol;
|
||||
class MIDIAction : public MIDIInvokable
|
||||
{
|
||||
public:
|
||||
MIDIAction (MIDI::Port&);
|
||||
MIDIAction (MIDI::Parser&);
|
||||
virtual ~MIDIAction ();
|
||||
|
||||
int init (GenericMidiControlProtocol&, const std::string& action_name, MIDI::byte* sysex = 0, size_t ssize = 0);
|
||||
|
||||
@@ -27,9 +27,9 @@
|
||||
#include "pbd/xml++.h"
|
||||
#include "pbd/stacktrace.h"
|
||||
|
||||
#include "midi++/port.h"
|
||||
#include "midi++/channel.h"
|
||||
|
||||
#include "ardour/async_midi_port.h"
|
||||
#include "ardour/automation_control.h"
|
||||
#include "ardour/midi_ui.h"
|
||||
#include "ardour/utils.h"
|
||||
@@ -42,11 +42,11 @@ using namespace MIDI;
|
||||
using namespace PBD;
|
||||
using namespace ARDOUR;
|
||||
|
||||
MIDIControllable::MIDIControllable (GenericMidiControlProtocol* s, Port& p, bool m)
|
||||
MIDIControllable::MIDIControllable (GenericMidiControlProtocol* s, MIDI::Parser& p, bool m)
|
||||
: _surface (s)
|
||||
, controllable (0)
|
||||
, _descriptor (0)
|
||||
, _port (p)
|
||||
, _parser (p)
|
||||
, _momentary (m)
|
||||
{
|
||||
_learned = false; /* from URI */
|
||||
@@ -59,10 +59,10 @@ MIDIControllable::MIDIControllable (GenericMidiControlProtocol* s, Port& p, bool
|
||||
feedback = true; // for now
|
||||
}
|
||||
|
||||
MIDIControllable::MIDIControllable (GenericMidiControlProtocol* s, Port& p, Controllable& c, bool m)
|
||||
MIDIControllable::MIDIControllable (GenericMidiControlProtocol* s, MIDI::Parser& p, Controllable& c, bool m)
|
||||
: _surface (s)
|
||||
, _descriptor (0)
|
||||
, _port (p)
|
||||
, _parser (p)
|
||||
, _momentary (m)
|
||||
{
|
||||
set_controllable (&c);
|
||||
@@ -149,7 +149,7 @@ void
|
||||
MIDIControllable::learn_about_external_control ()
|
||||
{
|
||||
drop_external_control ();
|
||||
_port.parser()->any.connect_same_thread (midi_learn_connection, boost::bind (&MIDIControllable::midi_receiver, this, _1, _2, _3));
|
||||
_parser.any.connect_same_thread (midi_learn_connection, boost::bind (&MIDIControllable::midi_receiver, this, _1, _2, _3));
|
||||
}
|
||||
|
||||
void
|
||||
@@ -357,12 +357,6 @@ MIDIControllable::midi_receiver (Parser &, byte *msg, size_t /*len*/)
|
||||
return;
|
||||
}
|
||||
|
||||
/* if the our port doesn't do input anymore, forget it ... */
|
||||
|
||||
if (!_port.parser()) {
|
||||
return;
|
||||
}
|
||||
|
||||
bind_midi ((channel_t) (msg[0] & 0xf), eventType (msg[0] & 0xF0), msg[1]);
|
||||
|
||||
if (controllable) {
|
||||
@@ -381,49 +375,43 @@ MIDIControllable::bind_midi (channel_t chn, eventType ev, MIDI::byte additional)
|
||||
control_channel = chn;
|
||||
control_additional = additional;
|
||||
|
||||
if (_port.parser() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
Parser& p = *_port.parser();
|
||||
|
||||
int chn_i = chn;
|
||||
switch (ev) {
|
||||
case MIDI::off:
|
||||
p.channel_note_off[chn_i].connect_same_thread (midi_sense_connection[0], boost::bind (&MIDIControllable::midi_sense_note_off, this, _1, _2));
|
||||
_parser.channel_note_off[chn_i].connect_same_thread (midi_sense_connection[0], boost::bind (&MIDIControllable::midi_sense_note_off, this, _1, _2));
|
||||
|
||||
/* if this is a togglee, connect to noteOn as well,
|
||||
and we'll toggle back and forth between the two.
|
||||
*/
|
||||
|
||||
if (_momentary) {
|
||||
p.channel_note_on[chn_i].connect_same_thread (midi_sense_connection[1], boost::bind (&MIDIControllable::midi_sense_note_on, this, _1, _2));
|
||||
_parser.channel_note_on[chn_i].connect_same_thread (midi_sense_connection[1], boost::bind (&MIDIControllable::midi_sense_note_on, this, _1, _2));
|
||||
}
|
||||
|
||||
_control_description = "MIDI control: NoteOff";
|
||||
break;
|
||||
|
||||
case MIDI::on:
|
||||
p.channel_note_on[chn_i].connect_same_thread (midi_sense_connection[0], boost::bind (&MIDIControllable::midi_sense_note_on, this, _1, _2));
|
||||
_parser.channel_note_on[chn_i].connect_same_thread (midi_sense_connection[0], boost::bind (&MIDIControllable::midi_sense_note_on, this, _1, _2));
|
||||
if (_momentary) {
|
||||
p.channel_note_off[chn_i].connect_same_thread (midi_sense_connection[1], boost::bind (&MIDIControllable::midi_sense_note_off, this, _1, _2));
|
||||
_parser.channel_note_off[chn_i].connect_same_thread (midi_sense_connection[1], boost::bind (&MIDIControllable::midi_sense_note_off, this, _1, _2));
|
||||
}
|
||||
_control_description = "MIDI control: NoteOn";
|
||||
break;
|
||||
|
||||
case MIDI::controller:
|
||||
p.channel_controller[chn_i].connect_same_thread (midi_sense_connection[0], boost::bind (&MIDIControllable::midi_sense_controller, this, _1, _2));
|
||||
_parser.channel_controller[chn_i].connect_same_thread (midi_sense_connection[0], boost::bind (&MIDIControllable::midi_sense_controller, this, _1, _2));
|
||||
snprintf (buf, sizeof (buf), "MIDI control: Controller %d", control_additional);
|
||||
_control_description = buf;
|
||||
break;
|
||||
|
||||
case MIDI::program:
|
||||
p.channel_program_change[chn_i].connect_same_thread (midi_sense_connection[0], boost::bind (&MIDIControllable::midi_sense_program_change, this, _1, _2));
|
||||
_parser.channel_program_change[chn_i].connect_same_thread (midi_sense_connection[0], boost::bind (&MIDIControllable::midi_sense_program_change, this, _1, _2));
|
||||
_control_description = "MIDI control: ProgramChange";
|
||||
break;
|
||||
|
||||
case MIDI::pitchbend:
|
||||
p.channel_pitchbend[chn_i].connect_same_thread (midi_sense_connection[0], boost::bind (&MIDIControllable::midi_sense_pitchbend, this, _1, _2));
|
||||
_parser.channel_pitchbend[chn_i].connect_same_thread (midi_sense_connection[0], boost::bind (&MIDIControllable::midi_sense_pitchbend, this, _1, _2));
|
||||
_control_description = "MIDI control: Pitchbend";
|
||||
break;
|
||||
|
||||
|
||||
@@ -36,17 +36,20 @@ namespace PBD {
|
||||
|
||||
namespace MIDI {
|
||||
class Channel;
|
||||
class Port;
|
||||
class Parser;
|
||||
}
|
||||
|
||||
class GenericMidiControlProtocol;
|
||||
|
||||
namespace ARDOUR {
|
||||
class AsyncMIDIPort;
|
||||
}
|
||||
|
||||
class MIDIControllable : public PBD::Stateful
|
||||
{
|
||||
public:
|
||||
MIDIControllable (GenericMidiControlProtocol *, MIDI::Port&, PBD::Controllable&, bool momentary);
|
||||
MIDIControllable (GenericMidiControlProtocol *, MIDI::Port&, bool momentary = false);
|
||||
MIDIControllable (GenericMidiControlProtocol *, MIDI::Parser&, PBD::Controllable&, bool momentary);
|
||||
MIDIControllable (GenericMidiControlProtocol *, MIDI::Parser&, bool momentary = false);
|
||||
virtual ~MIDIControllable ();
|
||||
|
||||
int init (const std::string&);
|
||||
@@ -72,7 +75,7 @@ class MIDIControllable : public PBD::Stateful
|
||||
|
||||
bool learned() const { return _learned; }
|
||||
|
||||
MIDI::Port& get_port() const { return _port; }
|
||||
MIDI::Parser& get_parser() { return _parser; }
|
||||
PBD::Controllable* get_controllable() const { return controllable; }
|
||||
void set_controllable (PBD::Controllable*);
|
||||
const std::string& current_uri() const { return _current_uri; }
|
||||
@@ -98,8 +101,8 @@ class MIDIControllable : public PBD::Stateful
|
||||
GenericMidiControlProtocol* _surface;
|
||||
PBD::Controllable* controllable;
|
||||
PBD::ControllableDescriptor* _descriptor;
|
||||
std::string _current_uri;
|
||||
MIDI::Port& _port;
|
||||
std::string _current_uri;
|
||||
MIDI::Parser& _parser;
|
||||
bool setting;
|
||||
int last_value;
|
||||
float last_controllable_value;
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
using namespace MIDI;
|
||||
|
||||
MIDIFunction::MIDIFunction (MIDI::Port& p)
|
||||
MIDIFunction::MIDIFunction (MIDI::Parser& p)
|
||||
: MIDIInvokable (p)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -33,7 +33,6 @@
|
||||
|
||||
namespace MIDI {
|
||||
class Channel;
|
||||
class Port;
|
||||
class Parser;
|
||||
}
|
||||
|
||||
@@ -64,7 +63,7 @@ class MIDIFunction : public MIDIInvokable
|
||||
TrackSetSoloIsolate,
|
||||
};
|
||||
|
||||
MIDIFunction (MIDI::Port&);
|
||||
MIDIFunction (MIDI::Parser&);
|
||||
virtual ~MIDIFunction ();
|
||||
|
||||
int setup (GenericMidiControlProtocol&, const std::string& function_name, const std::string& argument, MIDI::byte* sysex = 0, size_t ssize = 0);
|
||||
|
||||
@@ -25,8 +25,8 @@
|
||||
|
||||
using namespace MIDI;
|
||||
|
||||
MIDIInvokable::MIDIInvokable (MIDI::Port& p)
|
||||
: _port (p)
|
||||
MIDIInvokable::MIDIInvokable (MIDI::Parser& p)
|
||||
: _parser (p)
|
||||
{
|
||||
data_size = 0;
|
||||
data = 0;
|
||||
@@ -127,12 +127,6 @@ MIDIInvokable::bind_midi (channel_t chn, eventType ev, MIDI::byte additional)
|
||||
control_channel = chn;
|
||||
control_additional = additional;
|
||||
|
||||
if (_port.parser() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
Parser& p = *_port.parser();
|
||||
|
||||
int chn_i = chn;
|
||||
|
||||
/* incoming MIDI is parsed by Ardour' MidiUI event loop/thread, and we want our handlers to execute in that context, so we use
|
||||
@@ -141,27 +135,27 @@ MIDIInvokable::bind_midi (channel_t chn, eventType ev, MIDI::byte additional)
|
||||
|
||||
switch (ev) {
|
||||
case MIDI::off:
|
||||
p.channel_note_off[chn_i].connect_same_thread (midi_sense_connection[0], boost::bind (&MIDIInvokable::midi_sense_note_off, this, _1, _2));
|
||||
_parser.channel_note_off[chn_i].connect_same_thread (midi_sense_connection[0], boost::bind (&MIDIInvokable::midi_sense_note_off, this, _1, _2));
|
||||
break;
|
||||
|
||||
case MIDI::on:
|
||||
p.channel_note_on[chn_i].connect_same_thread (midi_sense_connection[0], boost::bind (&MIDIInvokable::midi_sense_note_on, this, _1, _2));
|
||||
_parser.channel_note_on[chn_i].connect_same_thread (midi_sense_connection[0], boost::bind (&MIDIInvokable::midi_sense_note_on, this, _1, _2));
|
||||
break;
|
||||
|
||||
case MIDI::controller:
|
||||
p.channel_controller[chn_i].connect_same_thread (midi_sense_connection[0], boost::bind (&MIDIInvokable::midi_sense_controller, this, _1, _2));
|
||||
_parser.channel_controller[chn_i].connect_same_thread (midi_sense_connection[0], boost::bind (&MIDIInvokable::midi_sense_controller, this, _1, _2));
|
||||
break;
|
||||
|
||||
case MIDI::program:
|
||||
p.channel_program_change[chn_i].connect_same_thread (midi_sense_connection[0], boost::bind (&MIDIInvokable::midi_sense_program_change, this, _1, _2));
|
||||
_parser.channel_program_change[chn_i].connect_same_thread (midi_sense_connection[0], boost::bind (&MIDIInvokable::midi_sense_program_change, this, _1, _2));
|
||||
break;
|
||||
|
||||
case MIDI::sysex:
|
||||
p.sysex.connect_same_thread (midi_sense_connection[0], boost::bind (&MIDIInvokable::midi_sense_sysex, this, _1, _2, _3));
|
||||
_parser.sysex.connect_same_thread (midi_sense_connection[0], boost::bind (&MIDIInvokable::midi_sense_sysex, this, _1, _2, _3));
|
||||
break;
|
||||
|
||||
case MIDI::any:
|
||||
p.any.connect_same_thread (midi_sense_connection[0], boost::bind (&MIDIInvokable::midi_sense_any, this, _1, _2, _3));
|
||||
_parser.any.connect_same_thread (midi_sense_connection[0], boost::bind (&MIDIInvokable::midi_sense_any, this, _1, _2, _3));
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
@@ -31,7 +31,6 @@
|
||||
|
||||
namespace MIDI {
|
||||
class Channel;
|
||||
class Port;
|
||||
class Parser;
|
||||
}
|
||||
|
||||
@@ -40,12 +39,12 @@ class GenericMidiControlProtocol;
|
||||
class MIDIInvokable : public PBD::Stateful
|
||||
{
|
||||
public:
|
||||
MIDIInvokable (MIDI::Port&);
|
||||
MIDIInvokable (MIDI::Parser&);
|
||||
virtual ~MIDIInvokable ();
|
||||
|
||||
virtual int init (GenericMidiControlProtocol&, const std::string&, MIDI::byte* data = 0, size_t dsize = 0);
|
||||
|
||||
MIDI::Port& get_port() const { return _port; }
|
||||
MIDI::Parser& get_parser() { return _parser; }
|
||||
|
||||
void bind_midi (MIDI::channel_t, MIDI::eventType, MIDI::byte);
|
||||
MIDI::channel_t get_control_channel () { return control_channel; }
|
||||
@@ -55,7 +54,7 @@ class MIDIInvokable : public PBD::Stateful
|
||||
protected:
|
||||
GenericMidiControlProtocol* _ui;
|
||||
std::string _invokable_name;
|
||||
MIDI::Port& _port;
|
||||
MIDI::Parser& _parser;
|
||||
PBD::ScopedConnection midi_sense_connection[2];
|
||||
MIDI::eventType control_type;
|
||||
MIDI::byte control_additional;
|
||||
|
||||
Reference in New Issue
Block a user