#include <glibmm/thread.h>
-#include "ardour/ardour.h"
#include "ardour/audioengine.h"
#include "ardour/auditioner.h"
#include "ardour/butler.h"
+#include "ardour/cycle_timer.h"
#include "ardour/debug.h"
+#include "ardour/graph.h"
+#include "ardour/port.h"
#include "ardour/process_thread.h"
#include "ardour/session.h"
#include "ardour/slave.h"
-#include "ardour/timestamps.h"
-#include "ardour/graph.h"
-#include "ardour/audio_port.h"
-#include "ardour/tempo.h"
+#include "ardour/ticker.h"
+#include "ardour/types.h"
#include "midi++/manager.h"
#include "midi++/mmc.h"
#include "i18n.h"
+#include <xmmintrin.h>
+
using namespace ARDOUR;
using namespace PBD;
using namespace std;
void
Session::process (pframes_t nframes)
{
- MIDI::Manager::instance()->cycle_start(nframes);
+ framepos_t transport_at_start = _transport_frame;
_silent = false;
_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 (!_engine.freewheeling() && Config->get_send_midi_clock() && transport_speed() == 1.0f && midi_clock->has_midi_port()) {
+ midi_clock->tick (transport_at_start);
+ }
} catch (...) {
- warning << _("Missed MIDI Clock tick due to problems with tempo map") << endmsg;
+ /* don't bother with a message */
}
SendFeedback (); /* EMIT SIGNAL */
-
- MIDI::Manager::instance()->cycle_end();
}
int
int
Session::no_roll (pframes_t nframes)
{
+ PT_TIMING_CHECK (4);
+
framepos_t end_frame = _transport_frame + nframes; // FIXME: varispeed + no_roll ??
int ret = 0;
- bool declick = get_transport_declick_required();
+ int declick = get_transport_declick_required();
boost::shared_ptr<RouteList> r = routes.reader ();
if (_click_io) {
_click_io->silence (nframes);
}
- if (_process_graph->threads_in_use() > 0) {
+ if (_process_graph) {
DEBUG_TRACE(DEBUG::ProcessThreads,"calling graph/no-roll\n");
_process_graph->routes_no_roll( nframes, _transport_frame, end_frame, non_realtime_work_pending(), declick);
} else {
+ PT_TIMING_CHECK (10);
for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
if ((*i)->is_hidden()) {
break;
}
}
+ PT_TIMING_CHECK (11);
}
+ PT_TIMING_CHECK (5);
return ret;
}
+/** @param need_butler to be set to true by this method if it needs the butler,
+ * otherwise it must be left alone.
+ */
int
Session::process_routes (pframes_t nframes, bool& need_butler)
{
const framepos_t start_frame = _transport_frame;
const framepos_t end_frame = _transport_frame + floor (nframes * _transport_speed);
-
- /* XXX this is hack to force use of the graph even if we are only
- using 1 thread. its needed because otherwise when we remove
- tracks, the graph never gets updated.
- */
- if (1 || _process_graph->threads_in_use() > 0) {
+
+ if (_process_graph) {
DEBUG_TRACE(DEBUG::ProcessThreads,"calling graph/process-routes\n");
_process_graph->process_routes (nframes, start_frame, end_frame, declick, need_butler);
} else {
(*i)->set_pending_declick (declick);
- if ((ret = (*i)->roll (nframes, start_frame, end_frame, declick, need_butler)) < 0) {
+ bool b = false;
+
+ if ((ret = (*i)->roll (nframes, start_frame, end_frame, declick, b)) < 0) {
stop_transport ();
return -1;
}
+
+ if (b) {
+ need_butler = true;
+ }
}
}
return 0;
}
+/** @param need_butler to be set to true by this method if it needs the butler,
+ * otherwise it must be left alone.
+ */
int
Session::silent_process_routes (pframes_t nframes, bool& need_butler)
{
const framepos_t start_frame = _transport_frame;
const framepos_t end_frame = _transport_frame + lrintf(nframes * _transport_speed);
- /* XXX this is hack to force use of the graph even if we are only
- using 1 thread. its needed because otherwise when we remove
- tracks, the graph never gets updated.
- */
- if (1 || _process_graph->threads_in_use() > 0) {
+ if (_process_graph) {
_process_graph->silent_process_routes (nframes, start_frame, end_frame, need_butler);
} else {
for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
continue;
}
- if ((ret = (*i)->silent_roll (nframes, start_frame, end_frame, need_butler)) < 0) {
+ bool b = false;
+
+ if ((ret = (*i)->silent_roll (nframes, start_frame, end_frame, b)) < 0) {
stop_transport ();
return -1;
}
+
+ if (b) {
+ need_butler = true;
+ }
}
}
void
Session::process_with_events (pframes_t nframes)
{
+ PT_TIMING_CHECK (3);
+
SessionEvent* ev;
pframes_t this_nframes;
framepos_t end_frame;
del = false;
break;
+ case SessionEvent::AutoLoopDeclick:
+ if (play_loop) {
+ /* Request a declick fade-out and a fade-in; the fade-out will happen
+ at the end of the loop, and the fade-in at the start.
+ */
+ transport_sub_state |= (PendingLoopDeclickOut | PendingLoopDeclickIn);
+ }
+ remove = false;
+ del = false;
+ break;
+
case SessionEvent::Locate:
if (ev->yes_or_no) {
// cerr << "forced locate to " << ev->target_frame << endl;