Consolidate TansportMaster implementation

* share port_latency latency query for MTC and MIDIClock slaves
* propagate set_session()
* share session_connections for MasterViaMIDI

This is in preparation to allow MClk slave to access midi-port-latency
This commit is contained in:
Robin Gareus 2020-05-27 23:39:28 +02:00
parent b46a7d43c2
commit 16f6e62249
Signed by: rgareus
GPG Key ID: A090BCE02CF57F04
5 changed files with 86 additions and 49 deletions

View File

@ -455,17 +455,29 @@ protected:
class LIBARDOUR_API TransportMasterViaMIDI
{
public:
virtual ~TransportMasterViaMIDI ();
boost::shared_ptr<MidiPort> midi_port () const
{
return _midi_port;
}
boost::shared_ptr<Port> create_midi_port (std::string const& port_name);
protected:
TransportMasterViaMIDI (){};
virtual void set_session (Session*);
protected:
TransportMasterViaMIDI () {};
void resync_latency (bool);
MIDI::Parser parser;
boost::shared_ptr<MidiPort> _midi_port;
virtual void parameter_changed (std::string const& p) {}
LatencyRange midi_port_latency;
private:
PBD::ScopedConnectionList session_connections;
};
class LIBARDOUR_API TimecodeTransportMaster : public TransportMaster
@ -530,7 +542,6 @@ public:
private:
PBD::ScopedConnectionList port_connections;
PBD::ScopedConnectionList session_connections;
bool can_notify_on_unknown_rate;
static const int sample_tolerance;
@ -567,9 +578,6 @@ private:
void parameter_changed (std::string const& p);
void connection_handler (boost::weak_ptr<ARDOUR::Port>, std::string, boost::weak_ptr<ARDOUR::Port>, std::string, bool);
void resync_latency (bool);
LatencyRange mtc_slave_latency;
};
class LIBARDOUR_API LTC_TransportMaster : public TimecodeTransportMaster
@ -703,14 +711,16 @@ protected:
double _bpm;
void start (MIDI::Parser& parser, samplepos_t timestamp);
void contineu (MIDI::Parser& parser, samplepos_t timestamp);
void contineu (MIDI::Parser& parser, samplepos_t timestamp); // we can't use continue because it is a C++ keyword
void stop (MIDI::Parser& parser, samplepos_t timestamp);
void position (MIDI::Parser& parser, MIDI::byte* message, size_t size, samplepos_t timestamp);
// we can't use continue because it is a C++ keyword
void calculate_one_ppqn_in_samples_at (samplepos_t time);
samplepos_t calculate_song_position (uint16_t song_position_in_sixteenth_notes);
void calculate_filter_coefficients (double qpm);
void update_midi_clock (MIDI::Parser& parser, samplepos_t timestamp);
void connection_handler (boost::weak_ptr<ARDOUR::Port>, std::string, boost::weak_ptr<ARDOUR::Port>, std::string, bool);
};
class LIBARDOUR_API Engine_TransportMaster : public TransportMaster

View File

@ -82,8 +82,9 @@ LTC_TransportMaster::create_port ()
void
LTC_TransportMaster::set_session (Session *s)
{
TransportMaster::set_session (s);
session_connections.drop_connections();
_session = s;
if (_session) {

View File

@ -70,6 +70,18 @@ MIDIClock_TransportMaster::init ()
{
midi_clock_count = 0;
current.reset ();
resync_latency (false);
}
void
MIDIClock_TransportMaster::connection_handler (boost::weak_ptr<ARDOUR::Port> w0, std::string n0, boost::weak_ptr<ARDOUR::Port> w1, std::string n1, bool con)
{
TransportMaster::connection_handler(w0, n0, w1, n1, con);
boost::shared_ptr<Port> p = w1.lock ();
if (p == _port) {
resync_latency (false);
}
}
void
@ -81,10 +93,12 @@ MIDIClock_TransportMaster::create_port ()
}
void
MIDIClock_TransportMaster::set_session (Session *session)
MIDIClock_TransportMaster::set_session (Session* s)
{
TransportMaster::set_session (s);
TransportMasterViaMIDI::set_session (s);
port_connections.drop_connections();
_session = session;
/* only connect to signals if we have a proxy, because otherwise we
* cannot interpet incoming data (no tempo map etc.)

View File

@ -73,7 +73,6 @@ MTC_TransportMaster::MTC_TransportMaster (std::string const & name)
MTC_TransportMaster::~MTC_TransportMaster()
{
port_connections.drop_connections();
session_connections.drop_connections();
}
void
@ -94,20 +93,6 @@ MTC_TransportMaster::connection_handler (boost::weak_ptr<ARDOUR::Port> w0, std::
}
}
void
MTC_TransportMaster::resync_latency (bool playback)
{
if (playback) {
return;
}
DEBUG_TRACE (DEBUG::MTC, "MTC resync_latency()\n");
if (_port) {
_port->get_connected_latency_range (mtc_slave_latency, false);
}
}
void
MTC_TransportMaster::create_port ()
{
@ -117,12 +102,12 @@ MTC_TransportMaster::create_port ()
}
void
MTC_TransportMaster::set_session (Session *s)
MTC_TransportMaster::set_session (Session* s)
{
port_connections.drop_connections();
session_connections.drop_connections();
TransportMaster::set_session (s);
TransportMasterViaMIDI::set_session (s);
_session = s;
port_connections.drop_connections();
if (_session) {
@ -136,9 +121,6 @@ MTC_TransportMaster::set_session (Session *s)
parser.mtc_time.connect_same_thread (port_connections, boost::bind (&MTC_TransportMaster::update_mtc_time, this, _1, _2, _3));
parser.mtc_qtr.connect_same_thread (port_connections, boost::bind (&MTC_TransportMaster::update_mtc_qtr, this, _1, _2, _3));
parser.mtc_status.connect_same_thread (port_connections, boost::bind (&MTC_TransportMaster::update_mtc_status, this, _1));
_session->config.ParameterChanged.connect_same_thread (session_connections, boost::bind (&MTC_TransportMaster::parameter_changed, this, _1));
_session->LatencyUpdated.connect_same_thread (session_connections, boost::bind (&MTC_TransportMaster::resync_latency, this, _1));
}
}
@ -461,9 +443,9 @@ MTC_TransportMaster::update_mtc_time (const MIDI::byte *msg, bool was_full, samp
if (first_mtc_timestamp == 0 || current.timestamp == 0) {
first_mtc_timestamp = now;
init_mtc_dll(mtc_frame, qtr);
mtc_frame_dll = mtc_frame + mtc_slave_latency.max;
mtc_frame_dll = mtc_frame + midi_port_latency.max;
}
current.update (mtc_frame + mtc_slave_latency.max, now, current.speed);
current.update (mtc_frame + midi_port_latency.max, now, current.speed);
reset_window (mtc_frame);
}
}

View File

@ -459,20 +459,6 @@ TransportMaster::unregister_port ()
}
}
boost::shared_ptr<Port>
TransportMasterViaMIDI::create_midi_port (std::string const & port_name)
{
boost::shared_ptr<Port> p;
if ((p = AudioEngine::instance()->register_input_port (DataType::MIDI, port_name, false, TransportMasterPort)) == 0) {
return boost::shared_ptr<Port> ();
}
_midi_port = boost::dynamic_pointer_cast<MidiPort> (p);
return p;
}
bool
TransportMaster::allow_request (TransportRequestSource src, TransportRequestType type) const
{
@ -557,3 +543,47 @@ TransportMaster::format_delta_time (sampleoffset_t delta) const
buf[63] = '\0';
return std::string(buf);
}
TransportMasterViaMIDI::~TransportMasterViaMIDI ()
{
session_connections.drop_connections();
}
boost::shared_ptr<Port>
TransportMasterViaMIDI::create_midi_port (std::string const & port_name)
{
boost::shared_ptr<Port> p;
if ((p = AudioEngine::instance()->register_input_port (DataType::MIDI, port_name, false, TransportMasterPort)) == 0) {
return boost::shared_ptr<Port> ();
}
_midi_port = boost::dynamic_pointer_cast<MidiPort> (p);
return p;
}
void
TransportMasterViaMIDI::set_session (Session* s)
{
session_connections.drop_connections();
if (!s) {
return;
}
s->config.ParameterChanged.connect_same_thread (session_connections, boost::bind (&TransportMasterViaMIDI::parameter_changed, this, _1));
s->LatencyUpdated.connect_same_thread (session_connections, boost::bind (&TransportMasterViaMIDI::resync_latency, this, _1));
}
void
TransportMasterViaMIDI::resync_latency (bool playback)
{
if (playback) {
return;
}
if (_midi_port) {
_midi_port->get_connected_latency_range (midi_port_latency, false);
}
}