X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Fdiskstream.cc;h=6501998171887ab2e7246351690214223f50d8a4;hb=723ab60b39aed9a9190e047fc5803c1f4e1adac3;hp=647d62e00f3d548ffb98a82dea44e243c0ee1f2c;hpb=8849cb428741d7d60261d1e44ceec665912281f5;p=ardour.git diff --git a/libs/ardour/diskstream.cc b/libs/ardour/diskstream.cc index 647d62e00f..6501998171 100644 --- a/libs/ardour/diskstream.cc +++ b/libs/ardour/diskstream.cc @@ -38,6 +38,7 @@ #include "pbd/basename.h" #include "pbd/memento_command.h" #include "pbd/xml++.h" +#include "pbd/stacktrace.h" #include "ardour/ardour.h" #include "ardour/audioengine.h" @@ -69,7 +70,7 @@ using namespace PBD; * default from configuration_vars.h). 0 is not a good value for * allocating buffer sizes.. */ -ARDOUR::framecnt_t Diskstream::disk_io_chunk_frames = 1024 * 256; +ARDOUR::framecnt_t Diskstream::disk_io_chunk_frames = 1024 * 256 / sizeof (Sample); PBD::Signal0 Diskstream::DiskOverrun; PBD::Signal0 Diskstream::DiskUnderrun; @@ -180,9 +181,10 @@ Diskstream::set_track (Track* t) ic_connection.disconnect(); _io->changed.connect_same_thread (ic_connection, boost::bind (&Diskstream::handle_input_change, this, _1, _2)); - input_change_pending = IOChange::ConfigurationChanged; - non_realtime_input_change (); - set_align_style_from_io (); + if (_io->n_ports() != ChanCount::ZERO) { + input_change_pending.type = IOChange::Type (IOChange::ConfigurationChanged|IOChange::ConnectionsChanged); + non_realtime_input_change (); + } _track->Destroyed.connect_same_thread (*this, boost::bind (&Diskstream::route_going_away, this)); } @@ -192,7 +194,14 @@ Diskstream::handle_input_change (IOChange change, void * /*src*/) { Glib::Mutex::Lock lm (state_lock); - if (change.type & IOChange::ConfigurationChanged) { + if (change.type & (IOChange::ConfigurationChanged|IOChange::ConnectionsChanged)) { + + /* rather than handle this here on a DS-by-DS basis we defer to the + session transport/butler thread, and let it tackle + as many diskstreams as need it in one shot. this avoids many repeated + takings of the audioengine process lock. + */ + if (!(input_change_pending.type & change.type)) { input_change_pending.type = IOChange::Type (input_change_pending.type | change.type); _session.request_input_change_handling (); @@ -271,26 +280,26 @@ Diskstream::set_capture_offset () void -Diskstream::set_align_style (AlignStyle a) +Diskstream::set_align_style (AlignStyle a, bool force) { if (record_enabled() && _session.actively_recording()) { return; } - if (a != _alignment_style) { + if ((a != _alignment_style) || force) { _alignment_style = a; AlignmentStyleChanged (); } } void -Diskstream::set_align_choice (AlignChoice a) +Diskstream::set_align_choice (AlignChoice a, bool force) { if (record_enabled() && _session.actively_recording()) { return; } - if (a != _alignment_choice) { + if ((a != _alignment_choice) || force) { _alignment_choice = a; switch (_alignment_choice) { @@ -346,7 +355,7 @@ Diskstream::get_captured_frames (uint32_t n) const if (capture_info.size() > n) { /* this is a completed capture */ return capture_info[n]->frames; - } else { + } else { /* this is the currently in-progress capture */ return capture_captured; } @@ -448,18 +457,9 @@ Diskstream::set_name (const string& str) if (_name != str) { assert(playlist()); playlist()->set_name (str); - SessionObject::set_name(str); - - if (!in_set_state && recordable()) { - /* rename existing capture files so that they have the correct name */ - return rename_write_sources (); - } else { - return false; - } } - - return true; + return true; } XMLNode& @@ -481,7 +481,7 @@ Diskstream::get_state () if (_extra_xml) { node->add_child_copy (*_extra_xml); } - + return *node; } @@ -509,9 +509,9 @@ Diskstream::set_state (const XMLNode& node, int /*version*/) } if ((prop = node.property (X_("capture-alignment"))) != 0) { - _alignment_choice = AlignChoice (string_2_enum (prop->value(), _alignment_choice)); + set_align_choice (AlignChoice (string_2_enum (prop->value(), _alignment_choice)), true); } else { - _alignment_choice = Automatic; + set_align_choice (Automatic, true); } if ((prop = node.property ("playlist")) == 0) { @@ -548,11 +548,11 @@ Diskstream::playlist_ranges_moved (list< Evoral::RangeMove > const & automation undo (it must, since automation-follows-regions can lose automation data). Hence we can do nothing here. */ - + if (from_undo) { return; } - + if (!_track || Config->get_automation_follows_regions () == false) { return; } @@ -569,14 +569,14 @@ Diskstream::playlist_ranges_moved (list< Evoral::RangeMove > const & /* move panner automation */ boost::shared_ptr pannable = _track->pannable(); Evoral::ControlSet::Controls& c (pannable->controls()); - + for (Evoral::ControlSet::Controls::iterator ci = c.begin(); ci != c.end(); ++ci) { boost::shared_ptr ac = boost::dynamic_pointer_cast(ci->second); if (!ac) { continue; } boost::shared_ptr alist = ac->alist(); - + XMLNode & before = alist->get_state (); bool const things_moved = alist->move_ranges (movements); if (things_moved) { @@ -640,64 +640,36 @@ Diskstream::check_record_status (framepos_t transport_frame, bool can_record) if (possibly_recording == last_possibly_recording) { return; } + + framecnt_t existing_material_offset = _session.worst_playback_latency(); + if (possibly_recording == fully_rec_enabled) { if (last_possibly_recording == fully_rec_enabled) { return; } - /* we transitioned to recording. lets see if its transport based or a punch */ - - first_recordable_frame = transport_frame + _capture_offset; + capture_start_frame = _session.transport_frame(); + first_recordable_frame = capture_start_frame + _capture_offset; last_recordable_frame = max_framepos; - capture_start_frame = transport_frame; - DEBUG_TRACE (DEBUG::CaptureAlignment, string_compose ("%1: @ %7 basic FRF = %2 LRF = %3 CSF = %4 CO = %5, WPL = %6\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, - _session.worst_playback_latency(), - transport_frame)); - - - - if (change & transport_rolling) { - - /* transport-change (started rolling) */ - - if (_alignment_style == ExistingMaterial) { - - /* audio played by ardour will take (up to) _session.worst_playback_latency() ("WOL") to - appear at the speakers; audio played at the time when it does appear at - the speakers will take _capture_offset to arrive back here. we've - already added _capture_offset, so now add WOL. - */ - - first_recordable_frame += _session.worst_playback_latency(); - DEBUG_TRACE (DEBUG::CaptureAlignment, string_compose ("\tROLL: shift FRF by delta between WOL %1\n", - first_recordable_frame)); - } else { - first_recordable_frame += _roll_delay; - DEBUG_TRACE (DEBUG::CaptureAlignment, string_compose ("\tROLL: shift FRF by roll delay of %1 to %2\n", - _roll_delay, first_recordable_frame)); - } - - } else { - - /* punch in */ - - if (_alignment_style == ExistingMaterial) { - - /* see comment in ExistingMaterial block above */ - first_recordable_frame += _session.worst_playback_latency(); - DEBUG_TRACE (DEBUG::CaptureAlignment, string_compose ("\tMANUAL PUNCH: shift FRF by delta between WOL and CO to %1\n", - first_recordable_frame)); - } else { - capture_start_frame -= _roll_delay; - DEBUG_TRACE (DEBUG::CaptureAlignment, string_compose ("\tPUNCH: shift CSF by roll delay of %1 to %2\n", - _roll_delay, capture_start_frame)); - } + existing_material_offset, + transport_frame, + _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)); } - + prepare_record_status (capture_start_frame); } else { @@ -705,19 +677,21 @@ Diskstream::check_record_status (framepos_t transport_frame, bool can_record) if (last_possibly_recording == fully_rec_enabled) { /* we were recording last time */ - + if (change & transport_rolling) { - /* transport-change (stopped rolling): last_recordable_frame was set in ::prepare_to_stop() */ - + + /* transport-change (stopped rolling): last_recordable_frame was set in ::prepare_to_stop(). We + had to set it there because we likely rolled past the stopping point to declick out, + and then backed up. + */ + } 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 += _session.worst_input_latency(); - } else { - last_recordable_frame += _roll_delay; + last_recordable_frame += existing_material_offset; } } } @@ -775,6 +749,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