summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2011-03-18 20:21:51 +0000
committerPaul Davis <paul@linuxaudiosystems.com>2011-03-18 20:21:51 +0000
commitca84e02b48e0c36755963a35713d272c409d9317 (patch)
tree90f637b7a67431a75fe587fc8ddfee6d04b24de4
parent065b5ce8e7c0328153d087aa0209dbe6cb744d54 (diff)
fix (?) capture alignment by making sure we use non-public latency information for playback latency, thus avoiding counting plugin latency twice
git-svn-id: svn://localhost/ardour2/branches/3.0@9168 d708f5d6-7413-0410-9779-e7cbd77b26cf
-rw-r--r--libs/ardour/ardour/audioengine.h5
-rw-r--r--libs/ardour/ardour/delivery.h1
-rw-r--r--libs/ardour/audio_diskstream.cc31
-rw-r--r--libs/ardour/audioengine.cc25
-rw-r--r--libs/ardour/delivery.cc17
-rw-r--r--libs/ardour/diskstream.cc37
-rw-r--r--libs/ardour/graph.cc6
-rw-r--r--libs/ardour/io.cc4
-rw-r--r--libs/ardour/port.cc59
-rw-r--r--libs/ardour/session.cc27
10 files changed, 141 insertions, 71 deletions
diff --git a/libs/ardour/ardour/audioengine.h b/libs/ardour/ardour/audioengine.h
index 8e68581e12..fa13fa827c 100644
--- a/libs/ardour/ardour/audioengine.h
+++ b/libs/ardour/ardour/audioengine.h
@@ -253,8 +253,9 @@ _ the regular process() call to session->process() is not made.
*/
PBD::Signal3<void, Port *, Port *, bool> PortConnectedOrDisconnected;
- std::string make_port_name_relative (std::string);
- std::string make_port_name_non_relative (std::string);
+ std::string make_port_name_relative (std::string) const;
+ std::string make_port_name_non_relative (std::string) const;
+ bool port_is_mine (const std::string&) const;
static AudioEngine* instance() { return _instance; }
void died ();
diff --git a/libs/ardour/ardour/delivery.h b/libs/ardour/ardour/delivery.h
index cf6b0fe9ea..309eff8511 100644
--- a/libs/ardour/ardour/delivery.h
+++ b/libs/ardour/ardour/delivery.h
@@ -108,6 +108,7 @@ public:
boost::shared_ptr<MuteMaster> _mute_master;
bool no_panner_reset;
boost::shared_ptr<PannerShell> _panshell;
+ framecnt_t scnt;
static bool panners_legal;
static PBD::Signal0<int> PannersLegal;
diff --git a/libs/ardour/audio_diskstream.cc b/libs/ardour/audio_diskstream.cc
index abe75b6ea2..335e263898 100644
--- a/libs/ardour/audio_diskstream.cc
+++ b/libs/ardour/audio_diskstream.cc
@@ -441,16 +441,6 @@ AudioDiskstream::process (framepos_t transport_frame, pframes_t nframes, bool ca
(*chan)->current_playback_buffer = 0;
}
- /* two conditions to test for here:
-
- A: this track is rec-enabled, and the session has confirmed that we can record
- B: this track is rec-enabled, has been recording, and we are set up for auto-punch-in
-
- The second test is necessary to capture the extra material that arrives AFTER the transport
- frame has left the punch range (which will cause the "can_record" argument to be false).
- */
-
-
// Safeguard against situations where process() goes haywire when autopunching
// and last_recordable_frame < first_recordable_frame
@@ -458,14 +448,16 @@ AudioDiskstream::process (framepos_t transport_frame, pframes_t nframes, bool ca
last_recordable_frame = max_framepos;
}
- OverlapType ot = coverage (first_recordable_frame, last_recordable_frame, transport_frame, transport_frame + nframes);
-
- calculate_record_range (ot, transport_frame, nframes, rec_nframes, rec_offset);
+ if (record_enabled()) {
- if (rec_nframes && !was_recording) {
- capture_captured = 0;
- was_recording = true;
- }
+ OverlapType ot = coverage (first_recordable_frame, last_recordable_frame, transport_frame, transport_frame + nframes);
+ calculate_record_range (ot, transport_frame, nframes, rec_nframes, rec_offset);
+
+ if (rec_nframes && !was_recording) {
+ capture_captured = 0;
+ was_recording = true;
+ }
+ }
if (can_record && !_last_capture_sources.empty()) {
_last_capture_sources.clear ();
@@ -1479,8 +1471,9 @@ AudioDiskstream::transport_stopped_wallclock (struct tm& when, time_t twhen, boo
string region_name;
RegionFactory::region_name (region_name, whole_file_region_name, false);
-
- // cerr << _name << ": based on ci of " << (*ci)->start << " for " << (*ci)->frames << " add region " << region_name << endl;
+
+ DEBUG_TRACE (DEBUG::CaptureAlignment, string_compose ("%1 capture start @ %2 length %3 add new region %4\n",
+ _name, (*ci)->start, (*ci)->frames, region_name));
try {
diff --git a/libs/ardour/audioengine.cc b/libs/ardour/audioengine.cc
index 6067da55b7..1c74dd13c7 100644
--- a/libs/ardour/audioengine.cc
+++ b/libs/ardour/audioengine.cc
@@ -993,12 +993,10 @@ AudioEngine::get_port_by_name (const string& portname)
}
}
- if (portname.find_first_of (':') != string::npos) {
- if (portname.substr (0, jack_client_name.length ()) != jack_client_name) {
- /* not an ardour: port */
- return 0;
- }
- }
+ if (!port_is_mine (portname)) {
+ /* not an ardour port */
+ return 0;
+ }
std::string const rel = make_port_name_relative (portname);
@@ -1416,7 +1414,7 @@ AudioEngine::update_total_latencies ()
}
string
-AudioEngine::make_port_name_relative (string portname)
+AudioEngine::make_port_name_relative (string portname) const
{
string::size_type len;
string::size_type n;
@@ -1437,7 +1435,7 @@ AudioEngine::make_port_name_relative (string portname)
}
string
-AudioEngine::make_port_name_non_relative (string portname)
+AudioEngine::make_port_name_non_relative (string portname) const
{
string str;
@@ -1453,6 +1451,17 @@ AudioEngine::make_port_name_non_relative (string portname)
}
bool
+AudioEngine::port_is_mine (const string& portname) const
+{
+ if (portname.find_first_of (':') != string::npos) {
+ if (portname.substr (0, jack_client_name.length ()) != jack_client_name) {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool
AudioEngine::is_realtime () const
{
GET_PRIVATE_JACK_POINTER_RET (_jack,false);
diff --git a/libs/ardour/delivery.cc b/libs/ardour/delivery.cc
index dfc38d761d..efdb4d9ad0 100644
--- a/libs/ardour/delivery.cc
+++ b/libs/ardour/delivery.cc
@@ -62,6 +62,7 @@ Delivery::Delivery (Session& s, boost::shared_ptr<IO> io, boost::shared_ptr<Pann
, _no_outs_cuz_we_no_monitor (false)
, _mute_master (mm)
, no_panner_reset (false)
+ , scnt (0)
{
_panshell = boost::shared_ptr<PannerShell>(new PannerShell (_name, _session, pannable));
_display_to_user = false;
@@ -83,6 +84,7 @@ Delivery::Delivery (Session& s, boost::shared_ptr<Pannable> pannable, boost::sha
, _no_outs_cuz_we_no_monitor (false)
, _mute_master (mm)
, no_panner_reset (false)
+ , scnt (0)
{
_panshell = boost::shared_ptr<PannerShell>(new PannerShell (_name, _session, pannable));
_display_to_user = false;
@@ -280,6 +282,21 @@ Delivery::run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, pf
panner = _panshell->panner();
+#if 0
+ if (_session.transport_rolling()) {
+ cerr << name() << " first value written : " << scnt << endl;
+ for (BufferSet::audio_iterator b = bufs.audio_begin(); b != bufs.audio_end(); ++b) {
+ Sample* p = b->data ();
+ float s = (float) scnt;
+ for (pframes_t n = 0; n < nframes; ++n) {
+ p[n] = s * 0.001;
+ s += 1.0;
+ }
+ }
+ scnt += nframes;
+ }
+#endif
+
if (panner && !panner->bypassed()) {
// Use the panner to distribute audio to output port buffers
diff --git a/libs/ardour/diskstream.cc b/libs/ardour/diskstream.cc
index affda7b56a..bba28eeacd 100644
--- a/libs/ardour/diskstream.cc
+++ b/libs/ardour/diskstream.cc
@@ -655,35 +655,26 @@ Diskstream::check_record_status (framepos_t transport_frame, bool can_record)
return;
}
- /* we transitioned to recording. lets see if its transport based or a punch */
-
- first_recordable_frame = transport_frame + _capture_offset;
- last_recordable_frame = max_framepos;
capture_start_frame = _session.transport_frame();
+ first_recordable_frame = capture_start_frame + _capture_offset;
+ last_recordable_frame = max_framepos;
- /* in theory, we should be offsetting by _session.worst_playback_latency() when we adjust
- for ExistingMaterial alignment. But that number includes the worst processor latency
- across all routes, and each track will already be roll-delay adjusted to handle that.
- so don't use worst_playback_latency(), just worst_output_latency() which covers
- only downstream latency from IO ports.
- */
-
- DEBUG_TRACE (DEBUG::CaptureAlignment, string_compose ("%1: @ %7 basic FRF = %2 CSF = %4 CO = %5, EMO = %6 RD = %8\n",
+ DEBUG_TRACE (DEBUG::CaptureAlignment, string_compose ("%1: @ %7 (%9) FRF = %2 CSF = %4 CO = %5, EMO = %6 RD = %8 WOL %10 WTL %11\n",
name(), first_recordable_frame, last_recordable_frame, capture_start_frame,
_capture_offset,
existing_material_offset,
transport_frame,
- _roll_delay));
+ _roll_delay,
+ _session.transport_frame(),
+ _session.worst_output_latency(),
+ _session.worst_track_latency()));
+
if (_alignment_style == ExistingMaterial) {
first_recordable_frame += existing_material_offset;
DEBUG_TRACE (DEBUG::CaptureAlignment, string_compose ("\tshift FRF by EMO %1\n",
first_recordable_frame));
- } else {
- capture_start_frame += _roll_delay;
- DEBUG_TRACE (DEBUG::CaptureAlignment, string_compose ("\tshift CFS by roll delay of %1 to %2\n",
- _roll_delay, capture_start_frame));
- }
+ }
prepare_record_status (capture_start_frame);
@@ -703,13 +694,11 @@ Diskstream::check_record_status (framepos_t transport_frame, bool can_record)
} else {
/* punch out */
- last_recordable_frame = transport_frame + _capture_offset;
+ last_recordable_frame = _session.transport_frame() + _capture_offset;
if (_alignment_style == ExistingMaterial) {
last_recordable_frame += existing_material_offset;
- } else {
- last_recordable_frame += _roll_delay;
- }
+ }
}
}
}
@@ -766,6 +755,10 @@ Diskstream::calculate_record_range(OverlapType ot, framepos_t transport_frame, f
rec_offset = first_recordable_frame - transport_frame;
break;
}
+
+ DEBUG_TRACE (DEBUG::CaptureAlignment, string_compose ("%1 rec? %2 @ %3 (for %4) FRF %5 LRF %6 : rf %7 @ %8\n",
+ _name, enum_2_string (ot), transport_frame, nframes,
+ first_recordable_frame, last_recordable_frame, rec_nframes, rec_offset));
}
void
diff --git a/libs/ardour/graph.cc b/libs/ardour/graph.cc
index f52180f98e..0403053bab 100644
--- a/libs/ardour/graph.cc
+++ b/libs/ardour/graph.cc
@@ -113,12 +113,16 @@ Graph::reset_thread_list ()
drop_threads ();
}
+#if 0
+ /* XXX this only makes sense when we can use just the AudioEngine thread
+ and still keep the graph current with the route list
+ */
if (num_threads <= 1) {
/* no point creating 1 thread - the AudioEngine already gives us one
*/
return;
}
-
+#endif
if (AudioEngine::instance()->create_process_thread (boost::bind (&Graph::main_thread, this), &a_thread, 100000) == 0) {
_thread_list.push_back (a_thread);
}
diff --git a/libs/ardour/io.cc b/libs/ardour/io.cc
index 27f8ca819d..55eaeb7a32 100644
--- a/libs/ardour/io.cc
+++ b/libs/ardour/io.cc
@@ -1156,6 +1156,10 @@ IO::latency () const
for (PortSet::const_iterator i = _ports.begin(); i != _ports.end(); ++i) {
if ((latency = i->private_latency_range (_direction == Output).max) > max_latency) {
+ DEBUG_TRACE (DEBUG::Latency, string_compose ("port %1 has %2 latency of %3 - use\n",
+ name(),
+ ((_direction == Output) ? "PLAYBACK" : "CAPTURE"),
+ latency));
max_latency = latency;
}
}
diff --git a/libs/ardour/port.cc b/libs/ardour/port.cc
index df1690da37..bc802aa81e 100644
--- a/libs/ardour/port.cc
+++ b/libs/ardour/port.cc
@@ -346,21 +346,50 @@ Port::get_connected_latency_range (jack_latency_range_t& range, bool playback) c
for (vector<string>::const_iterator c = connections.begin();
c != connections.end(); ++c) {
- jack_port_t* remote_port = jack_port_by_name (_engine->jack(), (*c).c_str());
- jack_latency_range_t lr;
-
- if (remote_port) {
- jack_port_get_latency_range (
- remote_port,
- (playback ? JackPlaybackLatency : JackCaptureLatency),
- &lr);
-
- DEBUG_TRACE (DEBUG::Latency, string_compose (
- "\t%1 <-> %2 : latter has latency range %3 .. %4\n",
- name(), *c, lr.min, lr.max));
- range.min = min (range.min, lr.min);
- range.max = max (range.max, lr.max);
- }
+ jack_latency_range_t lr;
+
+ if (!AudioEngine::instance()->port_is_mine (*c)) {
+
+ /* port belongs to some other JACK client, use
+ * JACK to lookup its latency information.
+ */
+
+ jack_port_t* remote_port = jack_port_by_name (_engine->jack(), (*c).c_str());
+
+ if (remote_port) {
+ jack_port_get_latency_range (
+ remote_port,
+ (playback ? JackPlaybackLatency : JackCaptureLatency),
+ &lr);
+
+ DEBUG_TRACE (DEBUG::Latency, string_compose (
+ "\t%1 <-> %2 : latter has latency range %3 .. %4\n",
+ name(), *c, lr.min, lr.max));
+
+ range.min = min (range.min, lr.min);
+ range.max = max (range.max, lr.max);
+ }
+
+ } else {
+
+ /* port belongs to this instance of ardour,
+ so look up its latency information
+ internally, because our published/public
+ values already contain our plugin
+ latency compensation.
+ */
+
+ Port* remote_port = AudioEngine::instance()->get_port_by_name (*c);
+ if (remote_port) {
+ lr = remote_port->private_latency_range ((playback ? JackPlaybackLatency : JackCaptureLatency));
+ DEBUG_TRACE (DEBUG::Latency, string_compose (
+ "\t%1 <-LOCAL-> %2 : latter has latency range %3 .. %4\n",
+ name(), *c, lr.min, lr.max));
+
+ range.min = min (range.min, lr.min);
+ range.max = max (range.max, lr.max);
+ }
+ }
}
} else {
diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc
index 19c7f5638f..84eb2bc2f2 100644
--- a/libs/ardour/session.cc
+++ b/libs/ardour/session.cc
@@ -1200,6 +1200,26 @@ Session::set_block_size (pframes_t nframes)
struct RouteSorter {
/** @return true to run r1 before r2, otherwise false */
+ bool sort_by_rec_enabled (const boost::shared_ptr<Route>& r1, const boost::shared_ptr<Route>& r2) {
+ if (r1->record_enabled()) {
+ if (r2->record_enabled()) {
+ /* both rec-enabled, just use signal order */
+ return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
+ } else {
+ /* r1 rec-enabled, r2 not rec-enabled, run r2 early */
+ return false;
+ }
+ } else {
+ if (r2->record_enabled()) {
+ /* r2 rec-enabled, r1 not rec-enabled, run r1 early */
+ return true;
+ } else {
+ /* neither rec-enabled, use signal order */
+ return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
+ }
+ }
+ }
+
bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
if (r2->feeds (r1)) {
/* r1 fed by r2; run r2 early */
@@ -1210,8 +1230,8 @@ struct RouteSorter {
} else {
if (r1->not_fed ()) {
if (r2->not_fed ()) {
- /* no ardour-based connections inbound to either route. just use signal order */
- return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
+ /* no ardour-based connections inbound to either route. */
+ return sort_by_rec_enabled (r1, r2);
} else {
/* r2 has connections, r1 does not; run r1 early */
return true;
@@ -1497,8 +1517,7 @@ Session::new_midi_track (TrackMode mode, RouteGroup* route_group, uint32_t how_m
failed:
if (!new_routes.empty()) {
- add_routes (new_routes, true, false);
- save_state (_current_snapshot_name);
+ add_routes (new_routes, true, true);
}
return ret;