diff options
-rw-r--r-- | libs/ardour/ardour/session.h | 6 | ||||
-rw-r--r-- | libs/ardour/ardour/ticker.h | 36 | ||||
-rw-r--r-- | libs/ardour/session_process.cc | 30 | ||||
-rw-r--r-- | libs/ardour/session_state.cc | 4 | ||||
-rw-r--r-- | libs/ardour/ticker.cc | 34 |
5 files changed, 53 insertions, 57 deletions
diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h index ee9c457ca4..fef6b7232e 100644 --- a/libs/ardour/ardour/session.h +++ b/libs/ardour/ardour/session.h @@ -104,6 +104,7 @@ class Graph; class IO; class IOProcessor; class ImportStatus; +class MidiClockTicker; class MidiControlUI; class MidiRegion; class MidiSource; @@ -513,9 +514,6 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi TempoMap& tempo_map() { return *_tempo_map; } - /// signals the current transport position in frames, bbt and timecode time (in that order) - PBD::Signal3<void, const framepos_t &, const Timecode::BBT_Time&, const Timecode::Time&> tick; - /* region info */ boost::shared_ptr<Region> find_whole_file_parent (boost::shared_ptr<Region const>) const; @@ -1520,6 +1518,8 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi uint32_t next_control_id () const; bool ignore_route_processor_changes; + + MidiClockTicker* midi_clock; }; } // namespace ARDOUR diff --git a/libs/ardour/ardour/ticker.h b/libs/ardour/ardour/ticker.h index 07aa1cc522..144d85f601 100644 --- a/libs/ardour/ardour/ticker.h +++ b/libs/ardour/ardour/ticker.h @@ -18,6 +18,7 @@ $Id$ */ +#include <boost/noncopyable.hpp> #include "pbd/signals.h" @@ -37,40 +38,17 @@ namespace ARDOUR class Session; -class Ticker : public SessionHandlePtr +class MidiClockTicker : public SessionHandlePtr, boost::noncopyable { public: - Ticker() {}; - virtual ~Ticker() {} - - virtual void tick ( - const framepos_t& transport_frames, - const Timecode::BBT_Time& transport_bbt, - const Timecode::Time& transport_timecode) = 0; - - void set_session (Session* s); -}; - -class MidiClockTicker : public Ticker -{ - /// Singleton -private: - MidiClockTicker() : _midi_port(0), _ppqn(24), _last_tick(0.0) {}; - MidiClockTicker( const MidiClockTicker& ); - MidiClockTicker& operator= (const MidiClockTicker&); - -public: + MidiClockTicker (); virtual ~MidiClockTicker() {}; - static MidiClockTicker& instance() { - static MidiClockTicker _instance; - return _instance; - } + void tick (const framepos_t& transport_frames, + const Timecode::BBT_Time& transport_bbt, + const Timecode::Time& transport_timecode); - void tick( - const framepos_t& transport_frames, - const Timecode::BBT_Time& transport_bbt, - const Timecode::Time& transport_timecode); + bool has_midi_port() const { return _midi_port != 0; } void set_session (Session* s); void session_going_away(); diff --git a/libs/ardour/session_process.cc b/libs/ardour/session_process.cc index 897b58ec8e..29f815d608 100644 --- a/libs/ardour/session_process.cc +++ b/libs/ardour/session_process.cc @@ -39,6 +39,7 @@ #include "ardour/graph.h" #include "ardour/audio_port.h" #include "ardour/tempo.h" +#include "ardour/ticker.h" #include "ardour/cycle_timer.h" #include "midi++/manager.h" @@ -57,6 +58,8 @@ using namespace std; void Session::process (pframes_t nframes) { + framepos_t transport_at_start = _transport_frame; + MIDI::Manager::instance()->cycle_start(nframes); _silent = false; @@ -78,14 +81,27 @@ Session::process (pframes_t nframes) _engine.main_thread()->drop_buffers (); - // the ticker is for sending time information like MidiClock - framepos_t transport_frames = transport_frame(); - Timecode::BBT_Time transport_bbt; + /* deliver MIDI clock. Note that we need to use the transport frame + * position at the start of process(), not the value at the end of + * it. We may already have ticked() because of a transport state + * change, for example. + */ + try { - _tempo_map->bbt_time_rt (transport_frames, transport_bbt); - Timecode::Time transport_timecode; - timecode_time(transport_frames, transport_timecode); - tick (transport_frames, transport_bbt, transport_timecode); /* EMIT SIGNAL */ + if (Config->get_send_midi_clock() && transport_speed() == 1.0f && midi_clock->has_midi_port()) { + + /* As of january 26th 2012, MidiClockTicker::tick() + * doesn't actually these variables, so don't waste + * cycles computing them. + */ + + Timecode::BBT_Time transport_bbt; + Timecode::Time transport_timecode; + // _tempo_map->bbt_time_rt (transport_at_start, transport_bbt); + // timecode_time (transport_at_start, transport_timecode); + + midi_clock->tick (transport_at_start, transport_bbt, transport_timecode); + } } catch (...) { /* don't bother with a message */ } diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc index bcc37dde51..e4107649b5 100644 --- a/libs/ardour/session_state.cc +++ b/libs/ardour/session_state.cc @@ -348,6 +348,9 @@ Session::second_stage_init () _engine.Halted.connect_same_thread (*this, boost::bind (&Session::engine_halted, this)); _engine.Xrun.connect_same_thread (*this, boost::bind (&Session::xrun_recovery, this)); + midi_clock = new MidiClockTicker (); + midi_clock->set_session (this); + try { when_engine_running (); } @@ -371,7 +374,6 @@ Session::second_stage_init () MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdMmcReset)); MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (Timecode::Time ())); - MidiClockTicker::instance().set_session (this); MIDI::Name::MidiPatchManager::instance().set_session (this); /* initial program change will be delivered later; see ::config_changed() */ diff --git a/libs/ardour/ticker.cc b/libs/ardour/ticker.cc index e53d31bff8..a53f6ceda2 100644 --- a/libs/ardour/ticker.cc +++ b/libs/ardour/ticker.cc @@ -14,14 +14,16 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - $Id$ */ #include "pbd/compose.h" +#include "pbd/stacktrace.h" + #include "midi++/port.h" #include "midi++/manager.h" + #include "evoral/midi_events.h" + #include "ardour/ticker.h" #include "ardour/session.h" #include "ardour/tempo.h" @@ -29,19 +31,17 @@ using namespace ARDOUR; -void Ticker::set_session (Session* s) +MidiClockTicker::MidiClockTicker () + : _midi_port (0) + , _ppqn (24) + , _last_tick (0.0) { - SessionHandlePtr::set_session (s); - - if (_session) { - _session->tick.connect_same_thread (_session_connections, boost::bind (&Ticker::tick, this, _1, _2, _3)); - } } void MidiClockTicker::set_session (Session* s) { - Ticker::set_session (s); - + SessionHandlePtr::set_session (s); + if (_session) { _session->TransportStateChange.connect_same_thread (_session_connections, boost::bind (&MidiClockTicker::transport_state_changed, this)); _session->PositionChanged.connect_same_thread (_session_connections, boost::bind (&MidiClockTicker::position_changed, this, _1)); @@ -73,7 +73,7 @@ void MidiClockTicker::transport_state_changed() framepos_t position = _session->transport_frame(); DEBUG_TRACE (PBD::DEBUG::MidiClock, - string_compose ("Transport state change, speed: %1 position: %2 play loop: %3\n", speed, position, _session->get_play_loop()) + 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) { @@ -104,7 +104,7 @@ void MidiClockTicker::transport_state_changed() send_stop_event(0); } - tick(position, *((Timecode::BBT_Time *) 0), *((Timecode::Time *)0)); + tick (position, *((Timecode::BBT_Time *) 0), *((Timecode::Time *)0)); } void MidiClockTicker::position_changed (framepos_t position) @@ -137,7 +137,7 @@ void MidiClockTicker::tick (const framepos_t& transport_frames, const Timecode:: while (true) { double next_tick = _last_tick + one_ppqn_in_frames(transport_frames); - framecnt_t next_tick_offset = framecnt_t(next_tick) - transport_frames; + frameoffset_t next_tick_offset = llrint (next_tick) - transport_frames; DEBUG_TRACE (PBD::DEBUG::MidiClock, string_compose ("Transport: %1, last tick time: %2, next tick time: %3, offset: %4, cycle length: %5\n", @@ -145,11 +145,11 @@ void MidiClockTicker::tick (const framepos_t& transport_frames, const Timecode:: ) ); - if (next_tick_offset >= _midi_port->nframes_this_cycle()) - return; - - send_midi_clock_event(next_tick_offset); + if (next_tick_offset >= _midi_port->nframes_this_cycle()) { + break; + } + send_midi_clock_event (next_tick_offset); _last_tick = next_tick; } } |