13
0

fix issues with rec-enabling being done in RT context by splitting it into two parts, an RT-safe and RT-unsafe part. along the way, remove "do not record plugins" option which is just so 1999 and creates problems for various (all?) plugin APIs

git-svn-id: svn://localhost/ardour2/branches/3.0@13613 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
Paul Davis 2012-12-07 15:48:38 +00:00
parent eacba74649
commit 8ca9061b30
12 changed files with 111 additions and 121 deletions

View File

@ -1448,14 +1448,6 @@ RCOptionEditor::RCOptionEditor ()
sigc::mem_fun (*_rc_config, &RCConfiguration::set_plugins_stop_with_transport)
));
add_option (_("Audio"),
new BoolOption (
"do-not-record-plugins",
_("Disable plugins during recording"),
sigc::mem_fun (*_rc_config, &RCConfiguration::get_do_not_record_plugins),
sigc::mem_fun (*_rc_config, &RCConfiguration::set_do_not_record_plugins)
));
add_option (_("Audio"),
new BoolOption (
"new-plugins-active",

View File

@ -242,9 +242,9 @@ class AudioDiskstream : public Diskstream
void adjust_playback_buffering ();
void adjust_capture_buffering ();
void engage_record_enable ();
void disengage_record_enable ();
bool prep_record_enable ();
bool prep_record_disable ();
// Working buffers for do_refill (butler thread)
static void allocate_working_buffers();
static void free_working_buffers();

View File

@ -243,6 +243,12 @@ class Diskstream : public SessionObject, public PublicDiskstream
virtual void use_destructive_playlist () {}
virtual void prepare_to_stop (framepos_t pos);
void engage_record_enable ();
void disengage_record_enable ();
virtual bool prep_record_enable () = 0;
virtual bool prep_record_disable () = 0;
void calculate_record_range (
Evoral::OverlapType ot, framepos_t transport_frame, framecnt_t nframes,
framecnt_t& rec_nframes, framecnt_t& rec_offset

View File

@ -184,9 +184,9 @@ class MidiDiskstream : public Diskstream
void adjust_playback_buffering () {}
void adjust_capture_buffering () {}
void engage_record_enable ();
void disengage_record_enable ();
bool prep_record_enable ();
bool prep_record_disable ();
MidiRingBuffer<framepos_t>* _playback_buf;
MidiRingBuffer<framepos_t>* _capture_buf;
boost::weak_ptr<MidiPort> _source_port;

View File

@ -126,7 +126,6 @@ CONFIG_VARIABLE (gain_t, click_gain, "click-gain", 1.0)
* Note that processors are still run when the transport is not moving.
*/
CONFIG_VARIABLE (bool, plugins_stop_with_transport, "plugins-stop-with-transport", false)
CONFIG_VARIABLE (bool, do_not_record_plugins, "do-not-record-plugins", false)
CONFIG_VARIABLE (bool, stop_recording_on_xrun, "stop-recording-on-xrun", false)
CONFIG_VARIABLE (bool, create_xrun_marker, "create-xrun-marker", true)
CONFIG_VARIABLE (bool, stop_at_session_end, "stop-at-session-end", false)

View File

@ -106,6 +106,7 @@ class Track : public Route, public PublicDiskstream
bool record_enabled() const;
void set_record_enabled (bool yn, void *src);
void prep_record_enabled (bool yn, void *src);
bool using_diskstream_id (PBD::ID) const;
@ -170,10 +171,6 @@ class Track : public Route, public PublicDiskstream
boost::shared_ptr<Diskstream> _diskstream;
MeterPoint _saved_meter_point;
/** used to keep track of processors that we are deactivating during record,
if `do-not-record-plugins' is enabled.
*/
std::list<boost::weak_ptr<Processor> > _deactivated_processors;
TrackMode _mode;
bool _needs_butler;
MonitorChoice _monitoring;
@ -230,10 +227,6 @@ private:
void diskstream_record_enable_changed ();
void diskstream_speed_changed ();
void diskstream_alignment_style_changed ();
void parameter_changed (std::string);
void deactivate_visible_processors ();
void activate_deactivated_processors ();
};
}; /* namespace ARDOUR*/

View File

@ -1664,13 +1664,22 @@ AudioDiskstream::set_record_enabled (bool yn)
}
}
void
AudioDiskstream::engage_record_enable ()
bool
AudioDiskstream::prep_record_enable ()
{
if (!recordable() || !_session.record_enabling_legal() || _io->n_ports().n_audio() == 0) {
return false;
}
/* can't rec-enable in destructive mode if transport is before start */
if (destructive() && _session.transport_frame() < _session.current_start_frame()) {
return false;
}
bool rolling = _session.transport_speed() != 0.0f;
boost::shared_ptr<ChannelList> c = channels.reader();
g_atomic_int_set (&_record_enabled, 1);
capturing_sources.clear ();
if (Config->get_monitoring_model() == HardwareMonitoring) {
@ -1689,12 +1698,13 @@ AudioDiskstream::engage_record_enable ()
}
RecordEnableChanged (); /* EMIT SIGNAL */
return true;
}
void
AudioDiskstream::disengage_record_enable ()
bool
AudioDiskstream::prep_record_disable ()
{
g_atomic_int_set (&_record_enabled, 0);
boost::shared_ptr<ChannelList> c = channels.reader();
if (Config->get_monitoring_model() == HardwareMonitoring) {
for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) {
@ -1703,6 +1713,8 @@ AudioDiskstream::disengage_record_enable ()
}
capturing_sources.clear ();
RecordEnableChanged (); /* EMIT SIGNAL */
return true;
}
XMLNode&

View File

@ -727,3 +727,16 @@ Diskstream::prepare_to_stop (framepos_t pos)
{
last_recordable_frame = pos + _capture_offset;
}
void
Diskstream::engage_record_enable ()
{
g_atomic_int_set (&_record_enabled, 1);
}
void
Diskstream::disengage_record_enable ()
{
g_atomic_int_set (&_record_enabled, 0);
}

View File

@ -1021,7 +1021,7 @@ MidiDiskstream::finish_capture ()
void
MidiDiskstream::set_record_enabled (bool yn)
{
if (!recordable() || !_session.record_enabling_legal()) {
if (!recordable() || !_session.record_enabling_legal() || _io->n_ports().n_midi() == 0) {
return;
}
@ -1040,12 +1040,14 @@ MidiDiskstream::set_record_enabled (bool yn)
}
}
void
MidiDiskstream::engage_record_enable ()
bool
MidiDiskstream::prep_record_enable ()
{
bool const rolling = _session.transport_speed() != 0.0f;
if (!recordable() || !_session.record_enabling_legal() || _io->n_ports().n_midi() == 0) {
return false;
}
g_atomic_int_set (&_record_enabled, 1);
bool const rolling = _session.transport_speed() != 0.0f;
boost::shared_ptr<MidiPort> sp = _source_port.lock ();
@ -1054,13 +1056,17 @@ MidiDiskstream::engage_record_enable ()
}
RecordEnableChanged (); /* EMIT SIGNAL */
return true;
}
void
MidiDiskstream::disengage_record_enable ()
bool
MidiDiskstream::prep_record_disable ()
{
g_atomic_int_set (&_record_enabled, 0);
RecordEnableChanged (); /* EMIT SIGNAL */
return true;
}
XMLNode&

View File

@ -3072,8 +3072,6 @@ Route::flush_processors ()
void
Route::set_meter_point (MeterPoint p, bool force)
{
/* CAN BE CALLED FROM PROCESS CONTEXT */
if (_meter_point == p && !force) {
return;
}

View File

@ -183,6 +183,25 @@ Session::set_record_enabled (boost::shared_ptr<RouteList> rl, bool yn, SessionEv
return;
}
/* do the non-RT part of rec-enabling first - the RT part will be done
* on the next process cycle. This does mean that theoretically we are
* doing things provisionally on the assumption that the rec-enable
* change will work, but this had better be a solid assumption for
* other reasons.
*/
for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
if ((*i)->is_hidden()) {
continue;
}
boost::shared_ptr<Track> t;
if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
t->prep_record_enabled (yn, (group_override ? (void*) t->route_group() : (void *) this));
}
}
queue_event (get_rt_event (rl, yn, after, group_override, &Session::rt_set_record_enabled));
}

View File

@ -46,8 +46,6 @@ Track::Track (Session& sess, string name, Route::Flag flag, TrackMode mode, Data
{
_freeze_record.state = NoFreeze;
_declickable = true;
Config->ParameterChanged.connect_same_thread (*this, boost::bind (&Track::parameter_changed, this, _1));
}
Track::~Track ()
@ -100,19 +98,6 @@ Track::state (bool full)
root.add_property (X_("saved-meter-point"), enum_2_string (_saved_meter_point));
root.add_child_nocopy (_rec_enable_control->get_state());
root.add_child_nocopy (_diskstream->get_state ());
if (!_deactivated_processors.empty ()) {
XMLNode* node = new XMLNode (X_("DeactivatedProcessors"));
for (list<boost::weak_ptr<Processor> >::iterator i = _deactivated_processors.begin(); i != _deactivated_processors.end(); ++i) {
boost::shared_ptr<Processor> p = i->lock ();
if (p) {
XMLNode* c = new XMLNode (X_("Processor"));
c->add_property (X_("id"), p->id().to_s());
node->add_child_nocopy (*c);
}
}
root.add_child_nocopy (*node);
}
return root;
}
@ -152,18 +137,6 @@ Track::set_state (const XMLNode& node, int version)
_rec_enable_control->set_state (*child, version);
}
}
if (child->name() == X_("DeactivatedProcessors")) {
XMLNodeList dp = child->children ();
for (XMLNodeConstIterator i = dp.begin(); i != dp.end(); ++i) {
assert ((*i)->name() == X_("Processor"));
XMLProperty* prop = (*i)->property (X_("id"));
boost::shared_ptr<Processor> p = processor_by_id (PBD::ID (prop->value ()));
if (p) {
_deactivated_processors.push_back (p);
}
}
}
}
const XMLProperty* prop;
@ -250,29 +223,42 @@ Track::can_record()
return will_record;
}
/* Turn off visible processors (except Fader), keeping track of the old states */
void
Track::deactivate_visible_processors ()
Track::prep_record_enabled (bool yn, void *src)
{
_deactivated_processors.clear ();
Glib::Threads::RWLock::ReaderLock lm (_processor_lock);
for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
if ((*i)->active() && (*i)->display_to_user() && boost::dynamic_pointer_cast<Amp> (*i) == 0) {
(*i)->deactivate ();
_deactivated_processors.push_back (*i);
}
if (!_session.writable()) {
return;
}
}
/* Turn deactivated processors back on again */
void
Track::activate_deactivated_processors ()
{
for (list<boost::weak_ptr<Processor> >::iterator i = _deactivated_processors.begin(); i != _deactivated_processors.end(); ++i) {
boost::shared_ptr<Processor> p = i->lock ();
if (p) {
p->activate ();
if (_freeze_record.state == Frozen) {
return;
}
if (_route_group && src != _route_group && _route_group->is_active() && _route_group->is_recenable()) {
_route_group->apply (&Track::prep_record_enabled, yn, _route_group);
return;
}
/* keep track of the meter point as it was before we rec-enabled */
if (!_diskstream->record_enabled()) {
_saved_meter_point = _meter_point;
}
bool will_follow;
if (yn) {
will_follow = _diskstream->prep_record_enable ();
} else {
will_follow = _diskstream->prep_record_disable ();
}
if (will_follow) {
if (yn) {
if (_meter_point != MeterCustom) {
set_meter_point (MeterInput);
}
} else {
set_meter_point (_saved_meter_point);
}
}
}
@ -293,33 +279,15 @@ Track::set_record_enabled (bool yn, void *src)
return;
}
/* keep track of the meter point as it was before we rec-enabled */
if (!_diskstream->record_enabled()) {
_saved_meter_point = _meter_point;
}
if (Config->get_do_not_record_plugins ()) {
if (yn) {
deactivate_visible_processors ();
} else {
activate_deactivated_processors ();
}
}
_diskstream->set_record_enabled (yn);
if (_diskstream->record_enabled()) {
if (_meter_point != MeterCustom) {
set_meter_point (MeterInput);
}
if (yn) {
_diskstream->engage_record_enable();
} else {
set_meter_point (_saved_meter_point);
_diskstream->disengage_record_enable();
}
_rec_enable_control->Changed ();
}
bool
Track::set_name (const string& str)
{
@ -950,22 +918,6 @@ Track::set_monitoring (MonitorChoice mc)
}
}
void
Track::parameter_changed (string p)
{
if (p != "do-not-record-plugins") {
return;
}
if (record_enabled ()) {
if (Config->get_do_not_record_plugins ()) {
deactivate_visible_processors ();
} else {
activate_deactivated_processors ();
}
}
}
MeterState
Track::metering_state () const
{