change API for accessing session MIDI ports so that (1) boost::shared_ptr<> is used all the time (2) we avoid using multiple functions to return different subclass versions of some ports

This commit is contained in:
Paul Davis 2015-12-07 12:02:42 -05:00
parent 4bb5278b62
commit 41b2de41d6
9 changed files with 102 additions and 129 deletions

View File

@ -36,7 +36,7 @@ class MIDISceneChanger : public SceneChanger
~MIDISceneChanger ();
void run (framepos_t start, framepos_t end);
void set_input_port (MIDI::Port*);
void set_input_port (boost::shared_ptr<MidiPort>);
void set_output_port (boost::shared_ptr<MidiPort>);
uint8_t bank_at (framepos_t, uint8_t channel);
@ -56,7 +56,7 @@ class MIDISceneChanger : public SceneChanger
private:
typedef std::multimap<framepos_t,boost::shared_ptr<MIDISceneChange> > Scenes;
MIDI::Port* input_port;
boost::shared_ptr<MidiPort> input_port;
boost::shared_ptr<MidiPort> output_port;
Glib::Threads::RWLock scene_lock;
Scenes scenes;

View File

@ -61,7 +61,7 @@ class LIBARDOUR_API MidiControlUI : public AbstractUI<MidiUIRequest>
private:
ARDOUR::Session& _session;
bool midi_input_handler (Glib::IOCondition, AsyncMIDIPort*);
bool midi_input_handler (Glib::IOCondition, boost::shared_ptr<AsyncMIDIPort>);
void reset_ports ();
void clear_ports ();

View File

@ -53,18 +53,14 @@ class LIBARDOUR_API MidiPortManager {
* callback.
*/
MIDI::Port* midi_input_port () const { return _midi_input_port; }
MIDI::Port* midi_output_port () const { return _midi_output_port; }
MIDI::Port* mmc_input_port () const { return _mmc_input_port; }
MIDI::Port* mmc_output_port () const { return _mmc_output_port; }
MIDI::Port* scene_input_port () const { return _scene_input_port; }
MIDI::Port* scene_output_port () const { return _scene_output_port; }
boost::shared_ptr<ARDOUR::Port> midi_input_port () const { return _midi_in; }
boost::shared_ptr<ARDOUR::Port> midi_output_port () const { return _midi_out; }
boost::shared_ptr<MidiPort> mmc_in() const { return boost::dynamic_pointer_cast<MidiPort>(_mmc_in); }
boost::shared_ptr<MidiPort> mmc_out() const { return boost::dynamic_pointer_cast<MidiPort>(_mmc_out); }
boost::shared_ptr<ARDOUR::Port> mmc_input_port() const { return boost::dynamic_pointer_cast<MidiPort>(_mmc_in); }
boost::shared_ptr<ARDOUR::Port> mmc_output_port() const { return boost::dynamic_pointer_cast<MidiPort>(_mmc_out); }
boost::shared_ptr<MidiPort> scene_in() const { return boost::dynamic_pointer_cast<MidiPort>(_scene_in); }
boost::shared_ptr<MidiPort> scene_out() const { return boost::dynamic_pointer_cast<MidiPort>(_scene_out); }
boost::shared_ptr<ARDOUR::Port> scene_input_port() const { return boost::dynamic_pointer_cast<MidiPort>(_scene_in); }
boost::shared_ptr<ARDOUR::Port> scene_output_port() const { return boost::dynamic_pointer_cast<MidiPort>(_scene_out); }
/* Ports used for synchronization. These have their I/O handled inside the
* process callback.
@ -81,16 +77,7 @@ class LIBARDOUR_API MidiPortManager {
PBD::Signal0<void> PortsChanged;
protected:
/* asynchronously handled ports: MIDI::Port */
MIDI::Port* _midi_input_port;
MIDI::Port* _midi_output_port;
MIDI::Port* _mmc_input_port;
MIDI::Port* _mmc_output_port;
MIDI::Port* _scene_input_port;
MIDI::Port* _scene_output_port;
/* these point to the same objects as the members above,
but cast to their ARDOUR::Port base class
*/
/* asynchronously handled ports: ARDOUR::AsyncMIDIPort */
boost::shared_ptr<Port> _midi_in;
boost::shared_ptr<Port> _midi_out;
boost::shared_ptr<Port> _mmc_in;

View File

@ -1009,27 +1009,26 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
SceneChanger* scene_changer() const { return _scene_changer; }
boost::shared_ptr<Port> ltc_input_port() const;
boost::shared_ptr<Port> ltc_output_port() const;
/* asynchronous MIDI control ports */
boost::shared_ptr<IO> ltc_input_io() { return _ltc_input; }
boost::shared_ptr<IO> ltc_output_io() { return _ltc_output; }
boost::shared_ptr<Port> midi_input_port () const;
boost::shared_ptr<Port> midi_output_port () const;
boost::shared_ptr<Port> mmc_output_port () const;
boost::shared_ptr<Port> mmc_input_port () const;
boost::shared_ptr<Port> scene_input_port () const;
boost::shared_ptr<Port> scene_output_port () const;
MIDI::Port* midi_input_port () const;
MIDI::Port* midi_output_port () const;
MIDI::Port* mmc_output_port () const;
MIDI::Port* mmc_input_port () const;
MIDI::Port* scene_input_port () const;
MIDI::Port* scene_output_port () const;
boost::shared_ptr<MidiPort> scene_in () const;
boost::shared_ptr<MidiPort> scene_out () const;
/* synchronous MIDI ports used for synchronization */
boost::shared_ptr<MidiPort> midi_clock_output_port () const;
boost::shared_ptr<MidiPort> midi_clock_input_port () const;
boost::shared_ptr<MidiPort> mtc_output_port () const;
boost::shared_ptr<MidiPort> mtc_input_port () const;
boost::shared_ptr<Port> ltc_input_port() const;
boost::shared_ptr<Port> ltc_output_port() const;
boost::shared_ptr<IO> ltc_input_io() { return _ltc_input; }
boost::shared_ptr<IO> ltc_output_io() { return _ltc_output; }
MIDI::MachineControl& mmc() { return *_mmc; }

View File

@ -226,13 +226,16 @@ MIDISceneChanger::locate (framepos_t pos)
}
void
MIDISceneChanger::set_input_port (MIDI::Port* mp)
MIDISceneChanger::set_input_port (boost::shared_ptr<MidiPort> mp)
{
input_port = mp;
incoming_connections.drop_connections();
input_port.reset ();
if (input_port) {
boost::shared_ptr<AsyncMIDIPort> async = boost::dynamic_pointer_cast<AsyncMIDIPort> (mp);
if (async) {
input_port = mp;
/* midi port is asynchronous. MIDI parsing will be carried out
* by the MIDI UI thread which will emit the relevant signals
@ -240,8 +243,8 @@ MIDISceneChanger::set_input_port (MIDI::Port* mp)
*/
for (int channel = 0; channel < 16; ++channel) {
input_port->parser()->channel_bank_change[channel].connect_same_thread (incoming_connections, boost::bind (&MIDISceneChanger::bank_change_input, this, _1, _2, channel));
input_port->parser()->channel_program_change[channel].connect_same_thread (incoming_connections, boost::bind (&MIDISceneChanger::program_change_input, this, _1, _2, channel));
async->parser()->channel_bank_change[channel].connect_same_thread (incoming_connections, boost::bind (&MIDISceneChanger::bank_change_input, this, _1, _2, channel));
async->parser()->channel_program_change[channel].connect_same_thread (incoming_connections, boost::bind (&MIDISceneChanger::program_change_input, this, _1, _2, channel));
}
}
}
@ -286,7 +289,7 @@ MIDISceneChanger::program_change_input (MIDI::Parser& parser, MIDI::byte program
int bank = -1;
if (have_seen_bank_changes) {
bank = input_port->channel (channel)->bank();
bank = boost::dynamic_pointer_cast<AsyncMIDIPort>(input_port)->channel (channel)->bank();
}
jump_to (bank, program);
@ -317,7 +320,7 @@ MIDISceneChanger::program_change_input (MIDI::Parser& parser, MIDI::byte program
int bank = -1;
if (have_seen_bank_changes) {
bank = input_port->channel (channel)->bank();
bank = boost::dynamic_pointer_cast<AsyncMIDIPort>(input_port)->channel (channel)->bank();
}
MIDISceneChange* msc =new MIDISceneChange (channel, bank, program & 0x7f);

View File

@ -71,9 +71,9 @@ MidiControlUI::do_request (MidiUIRequest* req)
}
bool
MidiControlUI::midi_input_handler (IOCondition ioc, AsyncMIDIPort* port)
MidiControlUI::midi_input_handler (IOCondition ioc, boost::shared_ptr<AsyncMIDIPort> port)
{
DEBUG_TRACE (DEBUG::MidiIO, string_compose ("something happend on %1\n", ((ARDOUR::Port*)port)->name()));
DEBUG_TRACE (DEBUG::MidiIO, string_compose ("something happend on %1\n", boost::shared_ptr<ARDOUR::Port> (port)->name()));
if (ioc & ~IO_IN) {
return false;
@ -81,12 +81,8 @@ MidiControlUI::midi_input_handler (IOCondition ioc, AsyncMIDIPort* port)
if (ioc & IO_IN) {
AsyncMIDIPort* asp = dynamic_cast<AsyncMIDIPort*> (port);
if (asp) {
asp->clear ();
}
DEBUG_TRACE (DEBUG::MidiIO, string_compose ("data available on %1\n", ((ARDOUR::Port*)port)->name()));
port->clear ();
DEBUG_TRACE (DEBUG::MidiIO, string_compose ("data available on %1\n", boost::shared_ptr<ARDOUR::Port>(port)->name()));
framepos_t now = _session.engine().sample_time();
port->parse (now);
}
@ -102,19 +98,19 @@ MidiControlUI::clear_ports ()
void
MidiControlUI::reset_ports ()
{
vector<AsyncMIDIPort*> ports;
AsyncMIDIPort* p;
vector<boost::shared_ptr<AsyncMIDIPort> > ports;
boost::shared_ptr<AsyncMIDIPort> p;
if ((p = dynamic_cast<AsyncMIDIPort*> (_session.midi_input_port()))) {
if ((p = boost::dynamic_pointer_cast<AsyncMIDIPort> (_session.midi_input_port()))) {
ports.push_back (p);
}
if ((p = dynamic_cast<AsyncMIDIPort*> (_session.mmc_input_port()))) {
if ((p = boost::dynamic_pointer_cast<AsyncMIDIPort> (_session.mmc_input_port()))) {
ports.push_back (p);
}
if ((p = dynamic_cast<AsyncMIDIPort*> (_session.scene_input_port()))) {
if ((p = boost::dynamic_pointer_cast<AsyncMIDIPort> (_session.scene_input_port()))) {
ports.push_back (p);
}
@ -122,7 +118,7 @@ MidiControlUI::reset_ports ()
return;
}
for (vector<AsyncMIDIPort*>::const_iterator pi = ports.begin(); pi != ports.end(); ++pi) {
for (vector<boost::shared_ptr<AsyncMIDIPort> >::const_iterator pi = ports.begin(); pi != ports.end(); ++pi) {
(*pi)->xthread().set_receive_handler (sigc::bind (sigc::mem_fun (this, &MidiControlUI::midi_input_handler), *pi));
(*pi)->xthread().attach (_main_loop->get_context());
}

View File

@ -83,23 +83,6 @@ MidiPortManager::create_ports ()
_scene_in = AudioEngine::instance()->register_input_port (DataType::MIDI, X_("Scene in"), true);
_scene_out = AudioEngine::instance()->register_output_port (DataType::MIDI, X_("Scene out"), true);
/* XXX nasty type conversion needed because of the mixed inheritance
* required to integrate MIDI::IPMidiPort and ARDOUR::AsyncMIDIPort.
*
* At some point, we'll move IPMidiPort into Ardour and make it
* inherit from ARDOUR::MidiPort not MIDI::Port, and then this
* mess can go away
*/
_midi_input_port = boost::dynamic_pointer_cast<AsyncMIDIPort>(_midi_in).get();
_midi_output_port = boost::dynamic_pointer_cast<AsyncMIDIPort>(_midi_out).get();
_mmc_input_port = boost::dynamic_pointer_cast<AsyncMIDIPort>(_mmc_in).get();
_mmc_output_port = boost::dynamic_pointer_cast<AsyncMIDIPort>(_mmc_out).get();
_scene_input_port = boost::dynamic_pointer_cast<AsyncMIDIPort>(_scene_in).get();
_scene_output_port = boost::dynamic_pointer_cast<AsyncMIDIPort>(_scene_out).get();
/* Now register ports used for sync (MTC and MIDI Clock)
*/
@ -137,12 +120,12 @@ MidiPortManager::set_midi_port_states (const XMLNodeList&nodes)
ports.insert (make_pair (_mtc_output_port->name(), _mtc_output_port));
ports.insert (make_pair (_midi_clock_input_port->name(), _midi_clock_input_port));
ports.insert (make_pair (_midi_clock_output_port->name(), _midi_clock_output_port));
ports.insert (make_pair (_midi_input_port->name(), _midi_in));
ports.insert (make_pair (_midi_output_port->name(), _midi_out));
ports.insert (make_pair (_mmc_input_port->name(), _mmc_in));
ports.insert (make_pair (_mmc_output_port->name(), _mmc_out));
ports.insert (make_pair (_scene_output_port->name(), _scene_out));
ports.insert (make_pair (_scene_input_port->name(), _scene_in));
ports.insert (make_pair (_midi_in->name(), _midi_in));
ports.insert (make_pair (_midi_out->name(), _midi_out));
ports.insert (make_pair (_mmc_in->name(), _mmc_in));
ports.insert (make_pair (_mmc_out->name(), _mmc_out));
ports.insert (make_pair (_scene_out->name(), _scene_out));
ports.insert (make_pair (_scene_in->name(), _scene_in));
for (XMLNodeList::const_iterator n = nodes.begin(); n != nodes.end(); ++n) {
if ((prop = (*n)->property (X_("name"))) == 0) {
@ -169,12 +152,12 @@ MidiPortManager::get_midi_port_states () const
ports.insert (make_pair (_mtc_output_port->name(), _mtc_output_port));
ports.insert (make_pair (_midi_clock_input_port->name(), _midi_clock_input_port));
ports.insert (make_pair (_midi_clock_output_port->name(), _midi_clock_output_port));
ports.insert (make_pair (_midi_input_port->name(), _midi_in));
ports.insert (make_pair (_midi_output_port->name(), _midi_out));
ports.insert (make_pair (_mmc_input_port->name(), _mmc_in));
ports.insert (make_pair (_mmc_output_port->name(), _mmc_out));
ports.insert (make_pair (_scene_output_port->name(), _scene_out));
ports.insert (make_pair (_scene_input_port->name(), _scene_in));
ports.insert (make_pair (_midi_in->name(), _midi_in));
ports.insert (make_pair (_midi_out->name(), _midi_out));
ports.insert (make_pair (_mmc_in->name(), _mmc_in));
ports.insert (make_pair (_mmc_out->name(), _mmc_out));
ports.insert (make_pair (_scene_out->name(), _scene_out));
ports.insert (make_pair (_scene_in->name(), _scene_in));
for (PortMap::const_iterator p = ports.begin(); p != ports.end(); ++p) {
s.push_back (&p->second->get_state());

View File

@ -630,21 +630,48 @@ Session::start_midi_thread ()
return 0;
}
MIDI::Port*
boost::shared_ptr<ARDOUR::Port>
Session::midi_input_port () const
{
return _midi_ports->midi_input_port ();
}
MIDI::Port*
boost::shared_ptr<ARDOUR::Port>
Session::midi_output_port () const
{
return _midi_ports->midi_output_port ();
}
boost::shared_ptr<ARDOUR::Port>
Session::mmc_output_port () const
{
return _midi_ports->mmc_output_port ();
}
boost::shared_ptr<ARDOUR::Port>
Session::mmc_input_port () const
{
return _midi_ports->mmc_input_port ();
}
boost::shared_ptr<ARDOUR::Port>
Session::scene_output_port () const
{
return _midi_ports->scene_output_port ();
}
boost::shared_ptr<ARDOUR::Port>
Session::scene_input_port () const
{
return _midi_ports->scene_input_port ();
}
boost::shared_ptr<MidiPort>
Session::midi_clock_output_port () const
{
return _midi_ports->midi_clock_output_port ();
}
boost::shared_ptr<MidiPort>
Session::midi_clock_input_port () const
{
@ -661,38 +688,3 @@ Session::mtc_input_port () const
return _midi_ports->mtc_input_port ();
}
MIDI::Port*
Session::mmc_output_port () const
{
return _midi_ports->mmc_output_port ();
}
MIDI::Port*
Session::mmc_input_port () const
{
return _midi_ports->mmc_input_port ();
}
MIDI::Port*
Session::scene_output_port () const
{
return _midi_ports->scene_output_port ();
}
MIDI::Port*
Session::scene_input_port () const
{
return _midi_ports->scene_input_port ();
}
boost::shared_ptr<MidiPort>
Session::scene_in () const
{
return _midi_ports->scene_in ();
}
boost::shared_ptr<MidiPort>
Session::scene_out () const
{
return _midi_ports->scene_out ();
}

View File

@ -217,11 +217,11 @@ Session::post_engine_init ()
MIDISceneChanger* msc;
_scene_changer = msc = new MIDISceneChanger (*this);
msc->set_input_port (scene_input_port());
msc->set_output_port (scene_out());
msc->set_input_port (boost::dynamic_pointer_cast<MidiPort>(scene_input_port()));
msc->set_output_port (boost::dynamic_pointer_cast<MidiPort>(scene_output_port()));
boost::function<framecnt_t(void)> timer_func (boost::bind (&Session::audible_frame, this));
boost::dynamic_pointer_cast<AsyncMIDIPort>(scene_in())->set_timer (timer_func);
boost::dynamic_pointer_cast<AsyncMIDIPort>(scene_input_port())->set_timer (timer_func);
setup_midi_machine_control ();
@ -3875,7 +3875,20 @@ void
Session::setup_midi_machine_control ()
{
_mmc = new MIDI::MachineControl;
_mmc->set_ports (_midi_ports->mmc_input_port(), _midi_ports->mmc_output_port());
boost::shared_ptr<AsyncMIDIPort> async_in = boost::dynamic_pointer_cast<AsyncMIDIPort> (_midi_ports->mmc_input_port());
boost::shared_ptr<AsyncMIDIPort> async_out = boost::dynamic_pointer_cast<AsyncMIDIPort> (_midi_ports->mmc_output_port());
if (!async_out || !async_out) {
return;
}
/* XXXX argh, passing raw pointers back into libmidi++ */
MIDI::Port* mmc_in = async_in.get();
MIDI::Port* mmc_out = async_out.get();
_mmc->set_ports (mmc_in, mmc_out);
_mmc->Play.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
_mmc->DeferredPlay.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));