mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-09 00:04:56 +01:00
move MidiPortManager from AudioEngine to Session
This makes the responsibilities and ownership of non-Route related MIDI ports more clear, and removes a few wierd bits of code. It also ensures that open/close/open on the same session will retain connections for those MIDI ports
This commit is contained in:
parent
fee626c386
commit
1c49138e00
17 changed files with 134 additions and 108 deletions
|
|
@ -457,33 +457,32 @@ PortGroupList::gather (ARDOUR::Session* session, ARDOUR::DataType type, bool inp
|
||||||
if ((type == DataType::MIDI || type == DataType::NIL)) {
|
if ((type == DataType::MIDI || type == DataType::NIL)) {
|
||||||
boost::shared_ptr<Bundle> sync (new Bundle (_("Sync"), inputs));
|
boost::shared_ptr<Bundle> sync (new Bundle (_("Sync"), inputs));
|
||||||
AudioEngine* ae = AudioEngine::instance();
|
AudioEngine* ae = AudioEngine::instance();
|
||||||
MIDI::MachineControl& mmc (ae->mmc());
|
|
||||||
|
|
||||||
if (inputs) {
|
if (inputs) {
|
||||||
sync->add_channel (
|
sync->add_channel (
|
||||||
_("MTC in"), DataType::MIDI, ae->make_port_name_non_relative (ae->mtc_input_port()->name())
|
_("MTC in"), DataType::MIDI, ae->make_port_name_non_relative (session->mtc_input_port()->name())
|
||||||
);
|
);
|
||||||
sync->add_channel (
|
sync->add_channel (
|
||||||
_("MIDI control in"), DataType::MIDI, ae->make_port_name_non_relative (ae->midi_input_port()->name())
|
_("MIDI control in"), DataType::MIDI, ae->make_port_name_non_relative (session->midi_input_port()->name())
|
||||||
);
|
);
|
||||||
sync->add_channel (
|
sync->add_channel (
|
||||||
_("MIDI clock in"), DataType::MIDI, ae->make_port_name_non_relative (ae->midi_clock_input_port()->name())
|
_("MIDI clock in"), DataType::MIDI, ae->make_port_name_non_relative (session->midi_clock_input_port()->name())
|
||||||
);
|
);
|
||||||
sync->add_channel (
|
sync->add_channel (
|
||||||
_("MMC in"), DataType::MIDI, ae->make_port_name_non_relative (mmc.input_port()->name())
|
_("MMC in"), DataType::MIDI, ae->make_port_name_non_relative (session->mmc_input_port()->name())
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
sync->add_channel (
|
sync->add_channel (
|
||||||
_("MTC out"), DataType::MIDI, ae->make_port_name_non_relative (ae->mtc_output_port()->name())
|
_("MTC out"), DataType::MIDI, ae->make_port_name_non_relative (session->mtc_output_port()->name())
|
||||||
);
|
);
|
||||||
sync->add_channel (
|
sync->add_channel (
|
||||||
_("MIDI control out"), DataType::MIDI, ae->make_port_name_non_relative (ae->midi_output_port()->name())
|
_("MIDI control out"), DataType::MIDI, ae->make_port_name_non_relative (session->midi_output_port()->name())
|
||||||
);
|
);
|
||||||
sync->add_channel (
|
sync->add_channel (
|
||||||
_("MIDI clock out"), DataType::MIDI, ae->make_port_name_non_relative (ae->midi_clock_output_port()->name())
|
_("MIDI clock out"), DataType::MIDI, ae->make_port_name_non_relative (session->midi_clock_output_port()->name())
|
||||||
);
|
);
|
||||||
sync->add_channel (
|
sync->add_channel (
|
||||||
_("MMC out"), DataType::MIDI, ae->make_port_name_non_relative (mmc.output_port()->name())
|
_("MMC out"), DataType::MIDI, ae->make_port_name_non_relative (session->mmc_output_port()->name())
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -36,8 +36,6 @@
|
||||||
#include "pbd/signals.h"
|
#include "pbd/signals.h"
|
||||||
#include "pbd/stacktrace.h"
|
#include "pbd/stacktrace.h"
|
||||||
|
|
||||||
#include "midi++/mmc.h"
|
|
||||||
|
|
||||||
#include "ardour/ardour.h"
|
#include "ardour/ardour.h"
|
||||||
#include "ardour/data_type.h"
|
#include "ardour/data_type.h"
|
||||||
#include "ardour/session_handle.h"
|
#include "ardour/session_handle.h"
|
||||||
|
|
@ -184,8 +182,6 @@ public:
|
||||||
/* sets up the process callback thread */
|
/* sets up the process callback thread */
|
||||||
static void thread_init_callback (void *);
|
static void thread_init_callback (void *);
|
||||||
|
|
||||||
MIDI::MachineControl& mmc() { return _mmc; }
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
AudioEngine ();
|
AudioEngine ();
|
||||||
|
|
||||||
|
|
@ -207,10 +203,8 @@ public:
|
||||||
framecnt_t last_monitor_check;
|
framecnt_t last_monitor_check;
|
||||||
/// the number of frames processed since start() was called
|
/// the number of frames processed since start() was called
|
||||||
framecnt_t _processed_frames;
|
framecnt_t _processed_frames;
|
||||||
bool _pre_freewheel_mmc_enabled;
|
|
||||||
Glib::Threads::Thread* m_meter_thread;
|
Glib::Threads::Thread* m_meter_thread;
|
||||||
ProcessThread* _main_thread;
|
ProcessThread* _main_thread;
|
||||||
MIDI::MachineControl _mmc;
|
|
||||||
|
|
||||||
void meter_thread ();
|
void meter_thread ();
|
||||||
void start_metering_thread ();
|
void start_metering_thread ();
|
||||||
|
|
|
||||||
|
|
@ -65,7 +65,7 @@ class MidiPortManager {
|
||||||
boost::shared_ptr<MidiPort> midi_clock_input_port() const { return _midi_clock_input_port; }
|
boost::shared_ptr<MidiPort> midi_clock_input_port() const { return _midi_clock_input_port; }
|
||||||
boost::shared_ptr<MidiPort> midi_clock_output_port() const { return _midi_clock_output_port; }
|
boost::shared_ptr<MidiPort> midi_clock_output_port() const { return _midi_clock_output_port; }
|
||||||
|
|
||||||
void set_midi_port_states ();
|
void set_midi_port_states (const XMLNodeList&);
|
||||||
std::list<XMLNode*> get_midi_port_states () const;
|
std::list<XMLNode*> get_midi_port_states () const;
|
||||||
|
|
||||||
PBD::Signal0<void> PortsChanged;
|
PBD::Signal0<void> PortsChanged;
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@
|
||||||
|
|
||||||
namespace ARDOUR {
|
namespace ARDOUR {
|
||||||
|
|
||||||
class PortManager : public MidiPortManager
|
class PortManager
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef std::map<std::string,boost::shared_ptr<Port> > Ports;
|
typedef std::map<std::string,boost::shared_ptr<Port> > Ports;
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,6 @@ class RCConfiguration : public Configuration
|
||||||
XMLNode * instant_xml (const std::string& str);
|
XMLNode * instant_xml (const std::string& str);
|
||||||
|
|
||||||
XMLNode* control_protocol_state () { return _control_protocol_state; }
|
XMLNode* control_protocol_state () { return _control_protocol_state; }
|
||||||
std::list<XMLNode*> midi_port_states () { return _midi_port_states; }
|
|
||||||
|
|
||||||
/* define accessor methods */
|
/* define accessor methods */
|
||||||
|
|
||||||
|
|
@ -81,11 +80,6 @@ class RCConfiguration : public Configuration
|
||||||
#undef CONFIG_VARIABLE_SPECIAL
|
#undef CONFIG_VARIABLE_SPECIAL
|
||||||
|
|
||||||
XMLNode* _control_protocol_state;
|
XMLNode* _control_protocol_state;
|
||||||
|
|
||||||
/** MIDI port nodes from the RC configuration. We store them so that we can set their
|
|
||||||
state once the audio engine and hence ports are up.
|
|
||||||
*/
|
|
||||||
std::list<XMLNode*> _midi_port_states;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* XXX: rename this */
|
/* XXX: rename this */
|
||||||
|
|
|
||||||
|
|
@ -110,6 +110,8 @@ class IOProcessor;
|
||||||
class ImportStatus;
|
class ImportStatus;
|
||||||
class MidiClockTicker;
|
class MidiClockTicker;
|
||||||
class MidiControlUI;
|
class MidiControlUI;
|
||||||
|
class MidiPortManager;
|
||||||
|
class MidiPort;
|
||||||
class MidiRegion;
|
class MidiRegion;
|
||||||
class MidiSource;
|
class MidiSource;
|
||||||
class MidiTrack;
|
class MidiTrack;
|
||||||
|
|
@ -860,6 +862,18 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
|
||||||
boost::shared_ptr<IO> ltc_input_io() { return _ltc_input; }
|
boost::shared_ptr<IO> ltc_input_io() { return _ltc_input; }
|
||||||
boost::shared_ptr<IO> ltc_output_io() { return _ltc_output; }
|
boost::shared_ptr<IO> ltc_output_io() { return _ltc_output; }
|
||||||
|
|
||||||
|
MIDI::Port* midi_input_port () const;
|
||||||
|
MIDI::Port* midi_output_port () const;
|
||||||
|
MIDI::Port* mmc_output_port () const;
|
||||||
|
MIDI::Port* mmc_input_port () const;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
MIDI::MachineControl& mmc() { return *_mmc; }
|
||||||
|
|
||||||
/* Callbacks specifically related to JACK, and called directly
|
/* Callbacks specifically related to JACK, and called directly
|
||||||
* from the JACK audio backend.
|
* from the JACK audio backend.
|
||||||
*/
|
*/
|
||||||
|
|
@ -1597,6 +1611,10 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
|
||||||
|
|
||||||
void reconnect_ltc_input ();
|
void reconnect_ltc_input ();
|
||||||
void reconnect_ltc_output ();
|
void reconnect_ltc_output ();
|
||||||
|
|
||||||
|
/* persistent, non-track related MIDI ports */
|
||||||
|
MidiPortManager* _midi_ports;
|
||||||
|
MIDI::MachineControl* _mmc;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ARDOUR
|
} // namespace ARDOUR
|
||||||
|
|
|
||||||
|
|
@ -71,7 +71,6 @@ AudioEngine::AudioEngine ()
|
||||||
, monitor_check_interval (INT32_MAX)
|
, monitor_check_interval (INT32_MAX)
|
||||||
, last_monitor_check (0)
|
, last_monitor_check (0)
|
||||||
, _processed_frames (0)
|
, _processed_frames (0)
|
||||||
, _pre_freewheel_mmc_enabled (false)
|
|
||||||
, m_meter_thread (0)
|
, m_meter_thread (0)
|
||||||
, _main_thread (0)
|
, _main_thread (0)
|
||||||
{
|
{
|
||||||
|
|
@ -543,12 +542,6 @@ AudioEngine::start ()
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if we're still connected (i.e. previously paused), no need to
|
|
||||||
* re-register ports.
|
|
||||||
*/
|
|
||||||
|
|
||||||
bool have_ports = (!ports.reader()->empty());
|
|
||||||
|
|
||||||
_processed_frames = 0;
|
_processed_frames = 0;
|
||||||
last_monitor_check = 0;
|
last_monitor_check = 0;
|
||||||
|
|
||||||
|
|
@ -566,11 +559,6 @@ AudioEngine::start ()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!have_ports) {
|
|
||||||
PortManager::create_ports ();
|
|
||||||
_mmc.set_ports (mmc_input_port(), mmc_output_port());
|
|
||||||
}
|
|
||||||
|
|
||||||
start_metering_thread ();
|
start_metering_thread ();
|
||||||
|
|
||||||
Running(); /* EMIT SIGNAL */
|
Running(); /* EMIT SIGNAL */
|
||||||
|
|
@ -903,13 +891,6 @@ AudioEngine::sync_callback (TransportState state, framepos_t position)
|
||||||
void
|
void
|
||||||
AudioEngine::freewheel_callback (bool onoff)
|
AudioEngine::freewheel_callback (bool onoff)
|
||||||
{
|
{
|
||||||
if (onoff) {
|
|
||||||
_pre_freewheel_mmc_enabled = _mmc.send_enabled ();
|
|
||||||
_mmc.enable_send (false);
|
|
||||||
} else {
|
|
||||||
_mmc.enable_send (_pre_freewheel_mmc_enabled);
|
|
||||||
}
|
|
||||||
|
|
||||||
_freewheeling = onoff;
|
_freewheeling = onoff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -118,7 +118,7 @@ void
|
||||||
MidiControlUI::reset_ports ()
|
MidiControlUI::reset_ports ()
|
||||||
{
|
{
|
||||||
if (port_sources.empty()) {
|
if (port_sources.empty()) {
|
||||||
AsyncMIDIPort* async = dynamic_cast<AsyncMIDIPort*> (AudioEngine::instance()->midi_input_port());
|
AsyncMIDIPort* async = dynamic_cast<AsyncMIDIPort*> (_session.midi_input_port());
|
||||||
|
|
||||||
if (!async) {
|
if (!async) {
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@ using namespace PBD;
|
||||||
|
|
||||||
MidiPortManager::MidiPortManager ()
|
MidiPortManager::MidiPortManager ()
|
||||||
{
|
{
|
||||||
|
create_ports ();
|
||||||
}
|
}
|
||||||
|
|
||||||
MidiPortManager::~MidiPortManager ()
|
MidiPortManager::~MidiPortManager ()
|
||||||
|
|
@ -110,21 +111,16 @@ MidiPortManager::create_ports ()
|
||||||
_mtc_output_port->set_always_parse (true);
|
_mtc_output_port->set_always_parse (true);
|
||||||
_midi_clock_input_port->set_always_parse (true);
|
_midi_clock_input_port->set_always_parse (true);
|
||||||
_midi_clock_output_port->set_always_parse (true);
|
_midi_clock_output_port->set_always_parse (true);
|
||||||
|
|
||||||
set_midi_port_states ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
MidiPortManager::set_midi_port_states ()
|
MidiPortManager::set_midi_port_states (const XMLNodeList&nodes)
|
||||||
{
|
{
|
||||||
list<XMLNode*> nodes;
|
|
||||||
XMLProperty* prop;
|
XMLProperty* prop;
|
||||||
typedef map<std::string,boost::shared_ptr<Port> > PortMap;
|
typedef map<std::string,boost::shared_ptr<Port> > PortMap;
|
||||||
PortMap ports;
|
PortMap ports;
|
||||||
const int version = 0;
|
const int version = 0;
|
||||||
|
|
||||||
nodes = Config->midi_port_states ();
|
|
||||||
|
|
||||||
ports.insert (make_pair (_mtc_input_port->name(), _mtc_input_port));
|
ports.insert (make_pair (_mtc_input_port->name(), _mtc_input_port));
|
||||||
ports.insert (make_pair (_mtc_output_port->name(), _mtc_output_port));
|
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_input_port->name(), _midi_clock_input_port));
|
||||||
|
|
@ -134,7 +130,7 @@ MidiPortManager::set_midi_port_states ()
|
||||||
ports.insert (make_pair (_mmc_input_port->name(), _mmc_in));
|
ports.insert (make_pair (_mmc_input_port->name(), _mmc_in));
|
||||||
ports.insert (make_pair (_mmc_output_port->name(), _mmc_out));
|
ports.insert (make_pair (_mmc_output_port->name(), _mmc_out));
|
||||||
|
|
||||||
for (list<XMLNode*>::iterator n = nodes.begin(); n != nodes.end(); ++n) {
|
for (XMLNodeList::const_iterator n = nodes.begin(); n != nodes.end(); ++n) {
|
||||||
if ((prop = (*n)->property (X_("name"))) == 0) {
|
if ((prop = (*n)->property (X_("name"))) == 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -65,10 +65,6 @@ RCConfiguration::RCConfiguration ()
|
||||||
|
|
||||||
RCConfiguration::~RCConfiguration ()
|
RCConfiguration::~RCConfiguration ()
|
||||||
{
|
{
|
||||||
for (list<XMLNode*>::iterator i = _midi_port_states.begin(); i != _midi_port_states.end(); ++i) {
|
|
||||||
delete *i;
|
|
||||||
}
|
|
||||||
|
|
||||||
delete _control_protocol_state;
|
delete _control_protocol_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -176,11 +172,6 @@ RCConfiguration::get_state ()
|
||||||
|
|
||||||
root = new XMLNode("Ardour");
|
root = new XMLNode("Ardour");
|
||||||
|
|
||||||
list<XMLNode*> midi_port_nodes = AudioEngine::instance()->get_midi_port_states();
|
|
||||||
for (list<XMLNode*>::const_iterator n = midi_port_nodes.begin(); n != midi_port_nodes.end(); ++n) {
|
|
||||||
root->add_child_nocopy (**n);
|
|
||||||
}
|
|
||||||
|
|
||||||
root->add_child_nocopy (get_variables ());
|
root->add_child_nocopy (get_variables ());
|
||||||
|
|
||||||
root->add_child_nocopy (SessionMetadata::Metadata()->get_user_state());
|
root->add_child_nocopy (SessionMetadata::Metadata()->get_user_state());
|
||||||
|
|
@ -226,12 +217,6 @@ RCConfiguration::set_state (const XMLNode& root, int version)
|
||||||
XMLNodeConstIterator niter;
|
XMLNodeConstIterator niter;
|
||||||
XMLNode *node;
|
XMLNode *node;
|
||||||
|
|
||||||
for (list<XMLNode*>::iterator i = _midi_port_states.begin(); i != _midi_port_states.end(); ++i) {
|
|
||||||
delete *i;
|
|
||||||
}
|
|
||||||
|
|
||||||
_midi_port_states.clear ();
|
|
||||||
|
|
||||||
Stateful::save_extra_xml (root);
|
Stateful::save_extra_xml (root);
|
||||||
|
|
||||||
for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
|
for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
|
||||||
|
|
@ -244,8 +229,6 @@ RCConfiguration::set_state (const XMLNode& root, int version)
|
||||||
SessionMetadata::Metadata()->set_state (*node, version);
|
SessionMetadata::Metadata()->set_state (*node, version);
|
||||||
} else if (node->name() == ControlProtocolManager::state_node_name) {
|
} else if (node->name() == ControlProtocolManager::state_node_name) {
|
||||||
_control_protocol_state = new XMLNode (*node);
|
_control_protocol_state = new XMLNode (*node);
|
||||||
} else if (node->name() == ARDOUR::Port::state_node_name) {
|
|
||||||
_midi_port_states.push_back (new XMLNode (*node));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -157,6 +157,11 @@ Session::Session (AudioEngine &eng,
|
||||||
_locations = new Locations (*this);
|
_locations = new Locations (*this);
|
||||||
ltc_encoder = NULL;
|
ltc_encoder = NULL;
|
||||||
|
|
||||||
|
_midi_ports = new MidiPortManager;
|
||||||
|
_mmc = new MIDI::MachineControl;
|
||||||
|
|
||||||
|
_mmc->set_ports (_midi_ports->mmc_input_port(), _midi_ports->mmc_output_port());
|
||||||
|
|
||||||
if (how_many_dsp_threads () > 1) {
|
if (how_many_dsp_threads () > 1) {
|
||||||
/* For now, only create the graph if we are using >1 DSP threads, as
|
/* For now, only create the graph if we are using >1 DSP threads, as
|
||||||
it is a bit slower than the old code with 1 thread.
|
it is a bit slower than the old code with 1 thread.
|
||||||
|
|
@ -330,6 +335,8 @@ Session::destroy ()
|
||||||
/* not strictly necessary, but doing it here allows the shared_ptr debugging to work */
|
/* not strictly necessary, but doing it here allows the shared_ptr debugging to work */
|
||||||
playlists.reset ();
|
playlists.reset ();
|
||||||
|
|
||||||
|
delete _mmc;
|
||||||
|
delete _midi_ports;
|
||||||
delete _locations;
|
delete _locations;
|
||||||
|
|
||||||
DEBUG_TRACE (DEBUG::Destruction, "Session::destroy() done\n");
|
DEBUG_TRACE (DEBUG::Destruction, "Session::destroy() done\n");
|
||||||
|
|
@ -1175,7 +1182,7 @@ Session::enable_record ()
|
||||||
if (g_atomic_int_compare_and_exchange (&_record_status, rs, Recording)) {
|
if (g_atomic_int_compare_and_exchange (&_record_status, rs, Recording)) {
|
||||||
|
|
||||||
_last_record_location = _transport_frame;
|
_last_record_location = _transport_frame;
|
||||||
AudioEngine::instance()->mmc().send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdRecordStrobe));
|
_mmc->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdRecordStrobe));
|
||||||
|
|
||||||
if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
|
if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
|
||||||
set_track_monitor_input_status (true);
|
set_track_monitor_input_status (true);
|
||||||
|
|
@ -1196,7 +1203,7 @@ Session::disable_record (bool rt_context, bool force)
|
||||||
|
|
||||||
if ((!Config->get_latched_record_enable () && !play_loop) || force) {
|
if ((!Config->get_latched_record_enable () && !play_loop) || force) {
|
||||||
g_atomic_int_set (&_record_status, Disabled);
|
g_atomic_int_set (&_record_status, Disabled);
|
||||||
AudioEngine::instance()->mmc().send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdRecordExit));
|
_mmc->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdRecordExit));
|
||||||
} else {
|
} else {
|
||||||
if (rs == Recording) {
|
if (rs == Recording) {
|
||||||
g_atomic_int_set (&_record_status, Enabled);
|
g_atomic_int_set (&_record_status, Enabled);
|
||||||
|
|
@ -1250,7 +1257,7 @@ Session::maybe_enable_record ()
|
||||||
enable_record ();
|
enable_record ();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
AudioEngine::instance()->mmc().send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdRecordPause));
|
_mmc->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdRecordPause));
|
||||||
RecordStateChanged (); /* EMIT SIGNAL */
|
RecordStateChanged (); /* EMIT SIGNAL */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -92,8 +92,8 @@ Session::pre_export ()
|
||||||
|
|
||||||
/* disable MMC output early */
|
/* disable MMC output early */
|
||||||
|
|
||||||
_pre_export_mmc_enabled = AudioEngine::instance()->mmc().send_enabled ();
|
_pre_export_mmc_enabled = _mmc->send_enabled ();
|
||||||
AudioEngine::instance()->mmc().enable_send (false);
|
_mmc->enable_send (false);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -236,7 +236,7 @@ Session::finalize_audio_export ()
|
||||||
|
|
||||||
export_freewheel_connection.disconnect();
|
export_freewheel_connection.disconnect();
|
||||||
|
|
||||||
AudioEngine::instance()->mmc().enable_send (_pre_export_mmc_enabled);
|
_mmc->enable_send (_pre_export_mmc_enabled);
|
||||||
|
|
||||||
/* maybe write CUE/TOC */
|
/* maybe write CUE/TOC */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -425,7 +425,7 @@ Session::send_full_time_code (framepos_t const t, pframes_t nframes)
|
||||||
|
|
||||||
// Send message at offset 0, sent time is for the start of this cycle
|
// Send message at offset 0, sent time is for the start of this cycle
|
||||||
|
|
||||||
MidiBuffer& mb (AudioEngine::instance()->mtc_output_port()->get_midi_buffer (nframes));
|
MidiBuffer& mb (_midi_ports->mtc_output_port()->get_midi_buffer (nframes));
|
||||||
mb.push_back (0, sizeof (msg), msg);
|
mb.push_back (0, sizeof (msg), msg);
|
||||||
|
|
||||||
_pframes_since_last_mtc = 0;
|
_pframes_since_last_mtc = 0;
|
||||||
|
|
@ -515,7 +515,7 @@ Session::send_midi_time_code_for_cycle (framepos_t start_frame, framepos_t end_f
|
||||||
pframes_t const out_stamp = (msg_time - start_frame) / _transport_speed;
|
pframes_t const out_stamp = (msg_time - start_frame) / _transport_speed;
|
||||||
assert (out_stamp < nframes);
|
assert (out_stamp < nframes);
|
||||||
|
|
||||||
MidiBuffer& mb (AudioEngine::instance()->mtc_output_port()->get_midi_buffer(nframes));
|
MidiBuffer& mb (_midi_ports->mtc_output_port()->get_midi_buffer(nframes));
|
||||||
if (!mb.push_back (out_stamp, 2, mtc_msg)) {
|
if (!mb.push_back (out_stamp, 2, mtc_msg)) {
|
||||||
error << string_compose(_("Session: cannot send quarter-frame MTC message (%1)"), strerror (errno))
|
error << string_compose(_("Session: cannot send quarter-frame MTC message (%1)"), strerror (errno))
|
||||||
<< endmsg;
|
<< endmsg;
|
||||||
|
|
@ -603,3 +603,45 @@ Session::start_midi_thread ()
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MIDI::Port*
|
||||||
|
Session::midi_input_port () const
|
||||||
|
{
|
||||||
|
return _midi_ports->midi_input_port ();
|
||||||
|
}
|
||||||
|
MIDI::Port*
|
||||||
|
Session::midi_output_port () const
|
||||||
|
{
|
||||||
|
return _midi_ports->midi_output_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
|
||||||
|
{
|
||||||
|
return _midi_ports->midi_clock_input_port ();
|
||||||
|
}
|
||||||
|
boost::shared_ptr<MidiPort>
|
||||||
|
Session::mtc_output_port () const
|
||||||
|
{
|
||||||
|
return _midi_ports->mtc_output_port ();
|
||||||
|
}
|
||||||
|
boost::shared_ptr<MidiPort>
|
||||||
|
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 ();
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -361,8 +361,8 @@ Session::second_stage_init ()
|
||||||
// send_full_time_code (0);
|
// send_full_time_code (0);
|
||||||
_engine.transport_locate (0);
|
_engine.transport_locate (0);
|
||||||
|
|
||||||
AudioEngine::instance()->mmc().send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdMmcReset));
|
_mmc->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdMmcReset));
|
||||||
AudioEngine::instance()->mmc().send (MIDI::MachineControlCommand (Timecode::Time ()));
|
_mmc->send (MIDI::MachineControlCommand (Timecode::Time ()));
|
||||||
|
|
||||||
MIDI::Name::MidiPatchManager::instance().set_session (this);
|
MIDI::Name::MidiPatchManager::instance().set_session (this);
|
||||||
|
|
||||||
|
|
@ -983,6 +983,15 @@ Session::state (bool full_state)
|
||||||
|
|
||||||
/* various options */
|
/* various options */
|
||||||
|
|
||||||
|
list<XMLNode*> midi_port_nodes = _midi_ports->get_midi_port_states();
|
||||||
|
if (!midi_port_nodes.empty()) {
|
||||||
|
XMLNode* midi_port_stuff = new XMLNode ("MIDIPorts");
|
||||||
|
for (list<XMLNode*>::const_iterator n = midi_port_nodes.begin(); n != midi_port_nodes.end(); ++n) {
|
||||||
|
midi_port_stuff->add_child_nocopy (**n);
|
||||||
|
}
|
||||||
|
node->add_child_nocopy (*midi_port_stuff);
|
||||||
|
}
|
||||||
|
|
||||||
node->add_child_nocopy (config.get_variables ());
|
node->add_child_nocopy (config.get_variables ());
|
||||||
|
|
||||||
node->add_child_nocopy (ARDOUR::SessionMetadata::Metadata()->get_state());
|
node->add_child_nocopy (ARDOUR::SessionMetadata::Metadata()->get_state());
|
||||||
|
|
@ -1188,6 +1197,11 @@ Session::set_state (const XMLNode& node, int version)
|
||||||
Evoral::init_event_id_counter (atoi (prop->value()));
|
Evoral::init_event_id_counter (atoi (prop->value()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if ((child = find_named_node (node, "MIDIPorts")) != 0) {
|
||||||
|
_midi_ports->set_midi_port_states (child->children());
|
||||||
|
}
|
||||||
|
|
||||||
IO::disable_connecting ();
|
IO::disable_connecting ();
|
||||||
|
|
||||||
Stateful::save_extra_xml (node);
|
Stateful::save_extra_xml (node);
|
||||||
|
|
@ -3364,11 +3378,11 @@ Session::config_changed (std::string p, bool ours)
|
||||||
|
|
||||||
} else if (p == "mmc-device-id" || p == "mmc-receive-id" || p == "mmc-receive-device-id") {
|
} else if (p == "mmc-device-id" || p == "mmc-receive-id" || p == "mmc-receive-device-id") {
|
||||||
|
|
||||||
AudioEngine::instance()->mmc().set_receive_device_id (Config->get_mmc_receive_device_id());
|
_mmc->set_receive_device_id (Config->get_mmc_receive_device_id());
|
||||||
|
|
||||||
} else if (p == "mmc-send-id" || p == "mmc-send-device-id") {
|
} else if (p == "mmc-send-id" || p == "mmc-send-device-id") {
|
||||||
|
|
||||||
AudioEngine::instance()->mmc().set_send_device_id (Config->get_mmc_send_device_id());
|
_mmc->set_send_device_id (Config->get_mmc_send_device_id());
|
||||||
|
|
||||||
} else if (p == "midi-control") {
|
} else if (p == "midi-control") {
|
||||||
|
|
||||||
|
|
@ -3431,7 +3445,7 @@ Session::config_changed (std::string p, bool ours)
|
||||||
|
|
||||||
} else if (p == "send-mmc") {
|
} else if (p == "send-mmc") {
|
||||||
|
|
||||||
AudioEngine::instance()->mmc().enable_send (Config->get_send_mmc ());
|
_mmc->enable_send (Config->get_send_mmc ());
|
||||||
|
|
||||||
} else if (p == "midi-feedback") {
|
} else if (p == "midi-feedback") {
|
||||||
|
|
||||||
|
|
@ -3489,13 +3503,13 @@ Session::config_changed (std::string p, bool ours)
|
||||||
|
|
||||||
} else if (p == "initial-program-change") {
|
} else if (p == "initial-program-change") {
|
||||||
|
|
||||||
if (AudioEngine::instance()->mmc().output_port() && Config->get_initial_program_change() >= 0) {
|
if (_mmc->output_port() && Config->get_initial_program_change() >= 0) {
|
||||||
MIDI::byte buf[2];
|
MIDI::byte buf[2];
|
||||||
|
|
||||||
buf[0] = MIDI::program; // channel zero by default
|
buf[0] = MIDI::program; // channel zero by default
|
||||||
buf[1] = (Config->get_initial_program_change() & 0x7f);
|
buf[1] = (Config->get_initial_program_change() & 0x7f);
|
||||||
|
|
||||||
AudioEngine::instance()->mmc().output_port()->midimsg (buf, sizeof (buf), 0);
|
_mmc->output_port()->midimsg (buf, sizeof (buf), 0);
|
||||||
}
|
}
|
||||||
} else if (p == "solo-mute-override") {
|
} else if (p == "solo-mute-override") {
|
||||||
// catch_up_on_solo_mute_override ();
|
// catch_up_on_solo_mute_override ();
|
||||||
|
|
@ -3559,27 +3573,25 @@ Session::load_diskstreams_2X (XMLNode const & node, int)
|
||||||
void
|
void
|
||||||
Session::setup_midi_machine_control ()
|
Session::setup_midi_machine_control ()
|
||||||
{
|
{
|
||||||
MIDI::MachineControl& mmc (AudioEngine::instance()->mmc ());
|
_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));
|
||||||
mmc.Play.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
|
_mmc->Stop.connect_same_thread (*this, boost::bind (&Session::mmc_stop, this, _1));
|
||||||
mmc.DeferredPlay.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
|
_mmc->FastForward.connect_same_thread (*this, boost::bind (&Session::mmc_fast_forward, this, _1));
|
||||||
mmc.Stop.connect_same_thread (*this, boost::bind (&Session::mmc_stop, this, _1));
|
_mmc->Rewind.connect_same_thread (*this, boost::bind (&Session::mmc_rewind, this, _1));
|
||||||
mmc.FastForward.connect_same_thread (*this, boost::bind (&Session::mmc_fast_forward, this, _1));
|
_mmc->Pause.connect_same_thread (*this, boost::bind (&Session::mmc_pause, this, _1));
|
||||||
mmc.Rewind.connect_same_thread (*this, boost::bind (&Session::mmc_rewind, this, _1));
|
_mmc->RecordPause.connect_same_thread (*this, boost::bind (&Session::mmc_record_pause, this, _1));
|
||||||
mmc.Pause.connect_same_thread (*this, boost::bind (&Session::mmc_pause, this, _1));
|
_mmc->RecordStrobe.connect_same_thread (*this, boost::bind (&Session::mmc_record_strobe, this, _1));
|
||||||
mmc.RecordPause.connect_same_thread (*this, boost::bind (&Session::mmc_record_pause, this, _1));
|
_mmc->RecordExit.connect_same_thread (*this, boost::bind (&Session::mmc_record_exit, this, _1));
|
||||||
mmc.RecordStrobe.connect_same_thread (*this, boost::bind (&Session::mmc_record_strobe, this, _1));
|
_mmc->Locate.connect_same_thread (*this, boost::bind (&Session::mmc_locate, this, _1, _2));
|
||||||
mmc.RecordExit.connect_same_thread (*this, boost::bind (&Session::mmc_record_exit, this, _1));
|
_mmc->Step.connect_same_thread (*this, boost::bind (&Session::mmc_step, this, _1, _2));
|
||||||
mmc.Locate.connect_same_thread (*this, boost::bind (&Session::mmc_locate, this, _1, _2));
|
_mmc->Shuttle.connect_same_thread (*this, boost::bind (&Session::mmc_shuttle, this, _1, _2, _3));
|
||||||
mmc.Step.connect_same_thread (*this, boost::bind (&Session::mmc_step, this, _1, _2));
|
_mmc->TrackRecordStatusChange.connect_same_thread (*this, boost::bind (&Session::mmc_record_enable, this, _1, _2, _3));
|
||||||
mmc.Shuttle.connect_same_thread (*this, boost::bind (&Session::mmc_shuttle, this, _1, _2, _3));
|
|
||||||
mmc.TrackRecordStatusChange.connect_same_thread (*this, boost::bind (&Session::mmc_record_enable, this, _1, _2, _3));
|
|
||||||
|
|
||||||
/* also handle MIDI SPP because its so common */
|
/* also handle MIDI SPP because its so common */
|
||||||
|
|
||||||
mmc.SPPStart.connect_same_thread (*this, boost::bind (&Session::spp_start, this));
|
_mmc->SPPStart.connect_same_thread (*this, boost::bind (&Session::spp_start, this));
|
||||||
mmc.SPPContinue.connect_same_thread (*this, boost::bind (&Session::spp_continue, this));
|
_mmc->SPPContinue.connect_same_thread (*this, boost::bind (&Session::spp_continue, this));
|
||||||
mmc.SPPStop.connect_same_thread (*this, boost::bind (&Session::spp_stop, this));
|
_mmc->SPPStop.connect_same_thread (*this, boost::bind (&Session::spp_stop, this));
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::shared_ptr<Controllable>
|
boost::shared_ptr<Controllable>
|
||||||
|
|
|
||||||
|
|
@ -618,7 +618,7 @@ Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
|
||||||
_send_timecode_update = true;
|
_send_timecode_update = true;
|
||||||
|
|
||||||
if (!dynamic_cast<MTC_Slave*>(_slave)) {
|
if (!dynamic_cast<MTC_Slave*>(_slave)) {
|
||||||
AudioEngine::instance()->mmc().send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdStop));
|
_mmc->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdStop));
|
||||||
|
|
||||||
/* This (::non_realtime_stop()) gets called by main
|
/* This (::non_realtime_stop()) gets called by main
|
||||||
process thread, which will lead to confusion
|
process thread, which will lead to confusion
|
||||||
|
|
@ -1271,7 +1271,7 @@ Session::start_transport ()
|
||||||
Timecode::Time time;
|
Timecode::Time time;
|
||||||
timecode_time_subframes (_transport_frame, time);
|
timecode_time_subframes (_transport_frame, time);
|
||||||
if (!dynamic_cast<MTC_Slave*>(_slave)) {
|
if (!dynamic_cast<MTC_Slave*>(_slave)) {
|
||||||
AudioEngine::instance()->mmc().send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdDeferredPlay));
|
_mmc->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdDeferredPlay));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1392,7 +1392,7 @@ Session::switch_to_sync_source (SyncSource src)
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
new_slave = new MTC_Slave (*this, *AudioEngine::instance()->mtc_input_port());
|
new_slave = new MTC_Slave (*this, *_midi_ports->mtc_input_port());
|
||||||
}
|
}
|
||||||
|
|
||||||
catch (failed_constructor& err) {
|
catch (failed_constructor& err) {
|
||||||
|
|
@ -1421,7 +1421,7 @@ Session::switch_to_sync_source (SyncSource src)
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
new_slave = new MIDIClock_Slave (*this, *AudioEngine::instance()->midi_clock_input_port(), 24);
|
new_slave = new MIDIClock_Slave (*this, *_midi_ports->midi_clock_input_port(), 24);
|
||||||
}
|
}
|
||||||
|
|
||||||
catch (failed_constructor& err) {
|
catch (failed_constructor& err) {
|
||||||
|
|
@ -1648,7 +1648,7 @@ Session::send_mmc_locate (framepos_t t)
|
||||||
if (!_engine.freewheeling()) {
|
if (!_engine.freewheeling()) {
|
||||||
Timecode::Time time;
|
Timecode::Time time;
|
||||||
timecode_time_subframes (t, time);
|
timecode_time_subframes (t, time);
|
||||||
AudioEngine::instance()->mmc().send (MIDI::MachineControlCommand (time));
|
_mmc->send (MIDI::MachineControlCommand (time));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -150,7 +150,7 @@ MidiClockTicker::session_going_away ()
|
||||||
void
|
void
|
||||||
MidiClockTicker::update_midi_clock_port()
|
MidiClockTicker::update_midi_clock_port()
|
||||||
{
|
{
|
||||||
_midi_port = AudioEngine::instance()->midi_clock_output_port();
|
_midi_port = _session->midi_clock_output_port();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
||||||
|
|
@ -60,8 +60,8 @@ GenericMidiControlProtocol::GenericMidiControlProtocol (Session& s)
|
||||||
, _threshold (10)
|
, _threshold (10)
|
||||||
, gui (0)
|
, gui (0)
|
||||||
{
|
{
|
||||||
_input_port = AudioEngine::instance()->midi_input_port ();
|
_input_port = s.midi_input_port ();
|
||||||
_output_port = AudioEngine::instance()->midi_output_port ();
|
_output_port = s.midi_output_port ();
|
||||||
|
|
||||||
do_feedback = false;
|
do_feedback = false;
|
||||||
_feedback_interval = 10000; // microseconds
|
_feedback_interval = 10000; // microseconds
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue