X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Fsession_midi.cc;h=fa23880b87bef6504618295f4529d8b72a738ceb;hb=6946bdc0830c9f0971d2cd0d54b27e343c54d96a;hp=c7bced83463cd7ecee0a85ce64e430dabde6bd5c;hpb=41b2de41d69c2ecc381867e502e4760267275425;p=ardour.git diff --git a/libs/ardour/session_midi.cc b/libs/ardour/session_midi.cc index c7bced8346..fa23880b87 100644 --- a/libs/ardour/session_midi.cc +++ b/libs/ardour/session_midi.cc @@ -48,7 +48,7 @@ #include "ardour/slave.h" #include "ardour/ticker.h" -#include "i18n.h" +#include "pbd/i18n.h" using namespace std; using namespace ARDOUR; @@ -335,6 +335,36 @@ Session::mmc_shuttle (MIDI::MachineControl &/*mmc*/, float speed, bool forw) } } +boost::shared_ptr +Session::get_midi_nth_route_by_id (PresentationInfo::order_t n) const +{ + PresentationInfo::Flag f; + + /* These numbers are defined by the MMC specification. + */ + + if (n == 318) { + f = PresentationInfo::MasterOut; + } else if (n == 319) { + f = PresentationInfo::MonitorOut; + } else { + f = PresentationInfo::Route; + } + + boost::shared_ptr r = routes.reader (); + PresentationInfo::order_t match_cnt = 0; + + for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { + if ((*i)->presentation_info().flag_match (f)) { + if (match_cnt++ == n) { + return *i; + } + } + } + + return boost::shared_ptr(); +} + void Session::mmc_record_enable (MIDI::MachineControl &mmc, size_t trk, bool enabled) { @@ -342,17 +372,13 @@ Session::mmc_record_enable (MIDI::MachineControl &mmc, size_t trk, bool enabled) return; } - RouteList::iterator i; - boost::shared_ptr r = routes.reader(); + boost::shared_ptr r = get_midi_nth_route_by_id (trk); - for (i = r->begin(); i != r->end(); ++i) { - AudioTrack *at; + if (r) { + boost::shared_ptr at; - if ((at = dynamic_cast((*i).get())) != 0) { - if (trk == at->remote_control_id()) { - at->set_record_enabled (enabled, &mmc); - break; - } + if ((at = boost::dynamic_pointer_cast (r))) { + at->rec_enable_control()->set_value (enabled, Controllable::UseGroup); } } } @@ -387,16 +413,29 @@ Session::send_full_time_code (framepos_t const t, MIDI::pframes_t nframes) framepos_t mtc_tc; timecode_to_sample(timecode, mtc_tc, true, false); outbound_mtc_timecode_frame = mtc_tc; - transmitting_timecode_time = timecode; + LatencyRange mtc_out_latency = {0, 0}; // TODO cache this, update on engine().GraphReordered() + _midi_ports->mtc_output_port ()->get_connected_latency_range (ltc_out_latency, true); + frameoffset_t mtc_offset = worst_playback_latency() - mtc_out_latency.max; + + // only if rolling.. ? + outbound_mtc_timecode_frame += mtc_offset; + + // outbound_mtc_timecode_frame needs to be >= _transport_frame + // or a new full timecode will be queued next cycle. + while (outbound_mtc_timecode_frame < t) { + Timecode::increment (transmitting_timecode_time, config.get_subframes_per_frame()); + outbound_mtc_timecode_frame += _frames_per_timecode_frame; + } + double const quarter_frame_duration = ((framecnt_t) _frames_per_timecode_frame) / 4.0; if (ceil((t - mtc_tc) / quarter_frame_duration) > 0) { Timecode::increment (transmitting_timecode_time, config.get_subframes_per_frame()); outbound_mtc_timecode_frame += _frames_per_timecode_frame; } - DEBUG_TRACE (DEBUG::MTC, string_compose ("Full MTC TC %1\n", outbound_mtc_timecode_frame)); + DEBUG_TRACE (DEBUG::MTC, string_compose ("Full MTC TC %1 (off %2)\n", outbound_mtc_timecode_frame, mtc_offset)); // I don't understand this bit yet.. [DR] // I do [rg]: @@ -407,21 +446,6 @@ Session::send_full_time_code (framepos_t const t, MIDI::pframes_t nframes) outbound_mtc_timecode_frame += _frames_per_timecode_frame; } -#if 0 // compensate for audio latency -- disabled [rg] - /* this needs more thought and work. - * the proper solution will be to just offset MTC by the MIDI port's latency. - * - * using worst_playback_latency() is wrong when the generated MTC is used to sync - * clients which send audio to Ardour for recording. - * worst_capture_latency() vs. worst_playback_latency() - * - * NB. similarly to session_ltc, the offset should be subtracted from the timecode to send, - * instead of being added to timestamp when to send the timecode. - * Otherwise the timestamp may not fall into the jack-cycle of the current _transport frame. - * and no MTC QF will be sent. - */ - outbound_mtc_timecode_frame += worst_playback_latency(); -#endif next_quarter_frame_to_send = 0; // Sync slave to the same Timecode time as we are on @@ -456,6 +480,8 @@ Session::send_full_time_code (framepos_t const t, MIDI::pframes_t nframes) int Session::send_midi_time_code_for_cycle (framepos_t start_frame, framepos_t end_frame, ARDOUR::pframes_t nframes) { + // start_frame == start_frame for normal cycles + // start_frame > _transport_frame for split cycles if (_engine.freewheeling() || !_send_qf_mtc || transmitting_timecode_time.negative || (next_quarter_frame_to_send < 0)) { // cerr << "(MTC) Not sending MTC\n"; return 0; @@ -464,6 +490,11 @@ Session::send_midi_time_code_for_cycle (framepos_t start_frame, framepos_t end_f return 0; } + if (_transport_speed < 0) { + // we don't support rolling backwards + return 0; + } + /* MTC is max. 30 fps - assert() below will fail * TODO actually limit it to 24,25,29df,30fps * talk to oofus, first. @@ -483,7 +514,12 @@ Session::send_midi_time_code_for_cycle (framepos_t start_frame, framepos_t end_f next_quarter_frame_to_send, quarter_frame_duration)); if (rint(outbound_mtc_timecode_frame + (next_quarter_frame_to_send * quarter_frame_duration)) < _transport_frame) { + // send full timecode and set outbound_mtc_timecode_frame, next_quarter_frame_to_send send_full_time_code (_transport_frame, nframes); + } + + if (rint(outbound_mtc_timecode_frame + (next_quarter_frame_to_send * quarter_frame_duration)) < start_frame) { + // no QF for this cycle return 0; } @@ -555,8 +591,7 @@ Session::send_midi_time_code_for_cycle (framepos_t start_frame, framepos_t end_f // Increment timecode time twice Timecode::increment (transmitting_timecode_time, config.get_subframes_per_frame()); Timecode::increment (transmitting_timecode_time, config.get_subframes_per_frame()); - // Re-calculate timing of first quarter frame - //timecode_to_sample( transmitting_timecode_time, outbound_mtc_timecode_frame, true /* use_offset */, false ); + // Increment timing of first quarter frame outbound_mtc_timecode_frame += 2.0 * _frames_per_timecode_frame; } } @@ -687,4 +722,3 @@ Session::mtc_input_port () const { return _midi_ports->mtc_input_port (); } -