diff --git a/libs/ardour/ardour/ticker.h b/libs/ardour/ardour/ticker.h index 23d2ef2fe6..da728a5d54 100644 --- a/libs/ardour/ardour/ticker.h +++ b/libs/ardour/ardour/ticker.h @@ -42,7 +42,7 @@ class MidiClockTicker : public SessionHandlePtr, boost::noncopyable { public: MidiClockTicker (); - virtual ~MidiClockTicker() {}; + virtual ~MidiClockTicker() {} void tick (const framepos_t& transport_frames); @@ -77,6 +77,7 @@ private: void send_start_event (pframes_t offset); void send_continue_event (pframes_t offset); void send_stop_event (pframes_t offset); + void send_position_event (framepos_t transport_position, pframes_t offset); }; } diff --git a/libs/ardour/session_midi.cc b/libs/ardour/session_midi.cc index 66ad0ccc2a..bc7e12a729 100644 --- a/libs/ardour/session_midi.cc +++ b/libs/ardour/session_midi.cc @@ -45,7 +45,7 @@ #include "ardour/midi_ui.h" #include "ardour/session.h" #include "ardour/slave.h" -#include "ardour/tempo.h" +#include "ardour/ticker.h" #include "i18n.h" @@ -590,33 +590,8 @@ Session::mmc_step_timeout () void Session::send_song_position_pointer (framepos_t t) { - /* This doesn't account for the Meter's note divisor */ - if (!_engine.freewheeling()) { - - Timecode::BBT_Time time; - bbt_time (t, time); - - const double beats_per_bar = tempo_map().meter_at(t).divisions_per_bar(); - - /* Midi Beats in terms of Song Position Pointer is equivalent to total - sixteenth notes at 'time' */ - const uint32_t midi_beats = 4 * (((time.bars - 1) * beats_per_bar) + time.beats - 1); - - /* can only use 14bits worth */ - if (midi_beats > 0x3fff) { - return; - } - - /* split midi beats into a 14bit value */ - MIDI::byte msg[3] = { - 0xf2, /* MIDI System Common - Song Position Pointer status */ - midi_beats & 0x7f, - midi_beats & 0x3f80 - }; - - if (MIDI::Port* port = MIDI::Manager::instance()->midi_clock_output_port()) { - port->midimsg (msg, sizeof (msg), 0); - } + if (midi_clock) { + midi_clock->position_changed (t); } } diff --git a/libs/ardour/ticker.cc b/libs/ardour/ticker.cc index 5d078952a1..75da935239 100644 --- a/libs/ardour/ticker.cc +++ b/libs/ardour/ticker.cc @@ -80,8 +80,8 @@ void MidiClockTicker::transport_state_changed() framepos_t position = _session->transport_frame(); DEBUG_TRACE (PBD::DEBUG::MidiClock, - string_compose ("Transport state change @ %4, speed: %1 position: %2 play loop: %3\n", speed, position, _session->get_play_loop(), position) - ); + string_compose ("Transport state change @ %4, speed: %1 position: %2 play loop: %3\n", speed, position, _session->get_play_loop(), position) + ); if (speed == 1.0f) { _last_tick = position; @@ -109,6 +109,7 @@ void MidiClockTicker::transport_state_changed() return; send_stop_event(0); + send_position_event (position, 0); } tick (position); @@ -116,7 +117,12 @@ void MidiClockTicker::transport_state_changed() void MidiClockTicker::position_changed (framepos_t position) { - DEBUG_TRACE (PBD::DEBUG::MidiClock, string_compose ("Position change: %1\n", position)); + const double speed = _session->transport_speed(); + DEBUG_TRACE (PBD::DEBUG::MidiClock, string_compose ("Transport Position Change: %1, speed: %2\n", position, speed)); + + if (speed == 0.0f && Config->get_send_midi_clock()) { + send_position_event (position, 0); + } _last_tick = position; } @@ -155,9 +161,11 @@ void MidiClockTicker::tick (const framepos_t& transport_frame) MIDI::JackMIDIPort* mp = dynamic_cast (_midi_port); + /* DEBUG_TRACE (PBD::DEBUG::MidiClock, string_compose ("Transport: %1, last tick time: %2, next tick time: %3, offset: %4, cycle length: %5\n", transport_frame, _last_tick, next_tick, next_tick_offset, mp ? mp->nframes_this_cycle() : 0)); + */ if (!mp || (next_tick_offset >= mp->nframes_this_cycle())) { break; @@ -188,7 +196,7 @@ void MidiClockTicker::send_midi_clock_event (pframes_t offset) return; } - DEBUG_TRACE (PBD::DEBUG::MidiClock, string_compose ("Tick with offset %1\n", offset)); + // DEBUG_TRACE (PBD::DEBUG::MidiClock, string_compose ("Tick with offset %1\n", offset)); static uint8_t _midi_clock_tick[1] = { MIDI_CMD_COMMON_CLOCK }; _midi_port->write (_midi_clock_tick, 1, offset); @@ -200,6 +208,8 @@ void MidiClockTicker::send_start_event (pframes_t offset) return; } + DEBUG_TRACE (PBD::DEBUG::MidiClock, string_compose ("Start %1\n", _last_tick)); + static uint8_t _midi_clock_tick[1] = { MIDI_CMD_COMMON_START }; _midi_port->write (_midi_clock_tick, 1, offset); } @@ -210,6 +220,8 @@ void MidiClockTicker::send_continue_event (pframes_t offset) return; } + DEBUG_TRACE (PBD::DEBUG::MidiClock, string_compose ("Continue %1\n", _last_tick)); + static uint8_t _midi_clock_tick[1] = { MIDI_CMD_COMMON_CONTINUE }; _midi_port->write (_midi_clock_tick, 1, offset); } @@ -220,9 +232,42 @@ void MidiClockTicker::send_stop_event (pframes_t offset) return; } + DEBUG_TRACE (PBD::DEBUG::MidiClock, string_compose ("Stop %1\n", _last_tick)); + static uint8_t _midi_clock_tick[1] = { MIDI_CMD_COMMON_STOP }; _midi_port->write (_midi_clock_tick, 1, offset); } +void +MidiClockTicker::send_position_event (framepos_t transport_position, pframes_t offset) +{ + if (_midi_port == 0 || _session == 0 || _session->engine().freewheeling()) { + return; + } + const TempoMap& tempo = _session->tempo_map(); + Timecode::BBT_Time time; + _session->bbt_time (transport_position, time); + const double beats_per_bar = tempo.meter_at(transport_position).divisions_per_bar(); + + /* Midi Beats in terms of Song Position Pointer is equivalent to total + sixteenth notes at 'time' */ + const uint32_t midi_beats = 4 * (((time.bars - 1) * beats_per_bar) + time.beats - 1); + + /* can only use 14bits worth */ + if (midi_beats > 0x3fff) { + return; + } + + /* split midi beats into a 14bit value */ + MIDI::byte msg[3] = { + MIDI_CMD_COMMON_SONG_POS, + midi_beats & 0x007f, + midi_beats & 0x3f80 + }; + + DEBUG_TRACE (PBD::DEBUG::MidiClock, string_compose ("Song Position: %1\n", midi_beats)); + + _midi_port->midimsg (msg, sizeof (msg), offset); +}