summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2012-01-27 13:22:55 +0000
committerPaul Davis <paul@linuxaudiosystems.com>2012-01-27 13:22:55 +0000
commit98ade9348a803996529758d782e1595f916122e3 (patch)
treecea55d938f10e6046e9cea8b7a3f5e6a6fbd412b
parent5e8403ff69b12353c9d71d72690a261bf5b7b059 (diff)
rework design of midi clock ticker to avoid expensive generalization that has turned out to have no particular use, and fix bug that caused incorrect ticks to be sent (or attempted) as the transport starts up
git-svn-id: svn://localhost/ardour2/branches/3.0@11359 d708f5d6-7413-0410-9779-e7cbd77b26cf
-rw-r--r--libs/ardour/ardour/session.h6
-rw-r--r--libs/ardour/ardour/ticker.h36
-rw-r--r--libs/ardour/session_process.cc30
-rw-r--r--libs/ardour/session_state.cc4
-rw-r--r--libs/ardour/ticker.cc34
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;
}
}