add initial implementation of explicit monitor (input|disk) control. some behaviour to be worked out, still

git-svn-id: svn://localhost/ardour2/branches/3.0@10256 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
Paul Davis
2011-10-20 18:50:29 +00:00
parent 49b459f8d3
commit 3764eedca0
12 changed files with 272 additions and 41 deletions

View File

@@ -37,6 +37,7 @@
#include <glibmm/thread.h>
#include "pbd/error.h"
#include "pbd/event_loop.h"
#include "pbd/rcu.h"
#include "pbd/statefuldestructible.h"
#include "pbd/signals.h"
@@ -622,6 +623,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
void set_record_enabled (boost::shared_ptr<RouteList>, bool, SessionEvent::RTeventCallback after = rt_cleanup, bool group_override = false);
void set_solo_isolated (boost::shared_ptr<RouteList>, bool, SessionEvent::RTeventCallback after = rt_cleanup, bool group_override = false);
void set_exclusive_input_active (boost::shared_ptr<Route> rt, bool others_on);
void set_monitoring (boost::shared_ptr<RouteList>, MonitorChoice, SessionEvent::RTeventCallback after = rt_cleanup, bool group_override = false);
PBD::Signal1<void,bool> SoloActive;
PBD::Signal0<void> SoloChanged;
@@ -1454,10 +1456,16 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
static int ask_about_playlist_deletion (boost::shared_ptr<Playlist>);
/* realtime "apply to set of routes" operations */
SessionEvent* get_rt_event (
boost::shared_ptr<RouteList> rl, bool yn,
SessionEvent::RTeventCallback after, bool group_override,
void (Session::*method) (boost::shared_ptr<RouteList>, bool, bool));
template<typename T> SessionEvent*
get_rt_event (boost::shared_ptr<RouteList> rl, T targ, SessionEvent::RTeventCallback after, bool group_override,
void (Session::*method) (boost::shared_ptr<RouteList>, T, bool)) {
SessionEvent* ev = new SessionEvent (SessionEvent::RealTimeOperation, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
ev->rt_slot = boost::bind (method, this, rl, targ, group_override);
ev->rt_return = after;
ev->event_loop = PBD::EventLoop::get_event_loop_for_thread ();
return ev;
}
void rt_set_solo (boost::shared_ptr<RouteList>, bool yn, bool group_override);
void rt_set_just_one_solo (boost::shared_ptr<RouteList>, bool yn, bool /* ignored*/ );
@@ -1465,6 +1473,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
void rt_set_listen (boost::shared_ptr<RouteList>, bool yn, bool group_override);
void rt_set_solo_isolated (boost::shared_ptr<RouteList>, bool yn, bool group_override);
void rt_set_record_enabled (boost::shared_ptr<RouteList>, bool yn, bool group_override);
void rt_set_monitoring (boost::shared_ptr<RouteList>, MonitorChoice, bool group_override);
/** temporary list of Diskstreams used only during load of 2.X sessions */
std::list<boost::shared_ptr<Diskstream> > _diskstreams_2X;

View File

@@ -48,6 +48,10 @@ class Track : public Route, public PublicDiskstream
virtual bool can_use_mode (TrackMode /*m*/, bool& /*bounce_required*/) { return false; }
PBD::Signal0<void> TrackModeChanged;
virtual void set_monitoring (MonitorChoice);
MonitorChoice monitoring() const { return _monitoring; }
PBD::Signal0<void> MonitoringChanged;
virtual int no_roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame,
bool state_changing, bool can_record);
@@ -161,9 +165,10 @@ class Track : public Route, public PublicDiskstream
virtual XMLNode& state (bool full) = 0;
boost::shared_ptr<Diskstream> _diskstream;
MeterPoint _saved_meter_point;
TrackMode _mode;
bool _needs_butler;
MeterPoint _saved_meter_point;
TrackMode _mode;
bool _needs_butler;
MonitorChoice _monitoring;
//private: (FIXME)
struct FreezeRecordProcessorInfo {

View File

@@ -358,6 +358,13 @@ namespace ARDOUR {
ExternalMonitoring
};
enum MonitorChoice {
MonitorAuto = 0,
MonitorInput = 0x1,
MonitorDisk = 0x2,
MonitorCue = 0x4,
};
enum PFLPosition {
/** PFL signals come from before pre-fader processors */
PFLFromBeforeProcessors,

View File

@@ -403,12 +403,16 @@ AudioTrack::roll (pframes_t nframes, framepos_t start_frame, framepos_t end_fram
_input->process_input (_meter, start_frame, end_frame, nframes);
}
if (diskstream->record_enabled() && !can_record && !_session.config.get_auto_input()) {
if ((_monitoring & MonitorInput) ||
(!(_monitoring & MonitorDisk) &&
(diskstream->record_enabled() && !can_record && !_session.config.get_auto_input()))) {
/* not actually recording, but we want to hear the input material anyway,
at least potentially (depending on monitoring options)
*/
cerr << name() << " do the passthru thing with monitoring = " << enum_2_string (_monitoring) << endl;
passthru (start_frame, end_frame, nframes, false);
} else if ((b = diskstream->playback_buffer(0)) != 0) {
@@ -734,3 +738,5 @@ AudioTrack::bounceable () const
{
return n_inputs().n_audio() >= n_outputs().n_audio();
}

View File

@@ -66,6 +66,7 @@ setup_enum_writer ()
RegionPoint _RegionPoint;
Placement _Placement;
MonitorModel _MonitorModel;
MonitorChoice _MonitorChoice;
PFLPosition _PFLPosition;
AFLPosition _AFLPosition;
RemoteModel _RemoteModel;
@@ -228,6 +229,12 @@ setup_enum_writer ()
REGISTER_ENUM (ExternalMonitoring);
REGISTER (_MonitorModel);
REGISTER_ENUM (MonitorInput);
REGISTER_ENUM (MonitorDisk);
REGISTER_ENUM (MonitorAuto);
REGISTER_ENUM (MonitorCue);
REGISTER_BITS (_MonitorChoice);
REGISTER_ENUM (PFLFromBeforeProcessors);
REGISTER_ENUM (PFLFromAfterProcessors);
REGISTER (_PFLPosition);

View File

@@ -32,16 +32,25 @@ using namespace PBD;
using namespace ARDOUR;
using namespace Glib;
SessionEvent*
Session::get_rt_event (boost::shared_ptr<RouteList> rl, bool yn, SessionEvent::RTeventCallback after, bool group_override,
void (Session::*method) (boost::shared_ptr<RouteList>, bool, bool))
void
Session::set_monitoring (boost::shared_ptr<RouteList> rl, MonitorChoice mc, SessionEvent::RTeventCallback after, bool group_override)
{
SessionEvent* ev = new SessionEvent (SessionEvent::RealTimeOperation, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
ev->rt_slot = boost::bind (method, this, rl, yn, group_override);
ev->rt_return = after;
ev->event_loop = EventLoop::get_event_loop_for_thread ();
queue_event (get_rt_event (rl, mc, after, group_override, &Session::rt_set_monitoring));
}
return ev;
void
Session::rt_set_monitoring (boost::shared_ptr<RouteList> rl, MonitorChoice mc, bool /* group_override */)
{
for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
if (!(*i)->is_hidden()) {
boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track> (*i);
if (t) {
t->set_monitoring (mc);
}
}
}
set_dirty();
}
void

View File

@@ -43,6 +43,7 @@ Track::Track (Session& sess, string name, Route::Flag flag, TrackMode mode, Data
: Route (sess, name, flag, default_type)
, _saved_meter_point (_meter_point)
, _mode (mode)
, _monitoring (MonitorAuto)
, _rec_enable_control (new RecEnableControllable(*this))
{
_freeze_record.state = NoFreeze;
@@ -640,36 +641,31 @@ Track::adjust_capture_buffering ()
bool
Track::send_silence () const
{
/*
ADATs work in a strange way..
they monitor input always when stopped.and auto-input is engaged.
Other machines switch to input on stop if the track is record enabled,
regardless of the auto input setting (auto input only changes the
monitoring state when the transport is rolling)
*/
bool send_silence;
if (!Config->get_tape_machine_mode()) {
/*
ADATs work in a strange way..
they monitor input always when stopped.and auto-input is engaged.
if (Config->get_tape_machine_mode()) {
/* ADATs work in a strange way..
they monitor input always when stopped.and auto-input is engaged.
*/
if ((Config->get_monitoring_model() == SoftwareMonitoring)
&& (_session.config.get_auto_input () || _diskstream->record_enabled())) {
send_silence = false;
&& ((_monitoring & MonitorInput) || (_diskstream->record_enabled()))) {
send_silence = false;
} else {
send_silence = true;
}
} else {
/*
Other machines switch to input on stop if the track is record enabled,
regardless of the auto input setting (auto input only changes the
monitoring state when the transport is rolling)
/* Other machines switch to input on stop if the track is record enabled,
regardless of the auto input setting (auto input only changes the
monitoring state when the transport is rolling)
*/
if ((Config->get_monitoring_model() == SoftwareMonitoring)
&& _diskstream->record_enabled()) {
&& (!(_monitoring & MonitorDisk) && (_session.config.get_auto_input () || _diskstream->record_enabled()))) {
send_silence = false;
} else {
send_silence = true;
@@ -732,6 +728,14 @@ Track::check_initial_delay (framecnt_t nframes, framecnt_t& transport_frame)
}
return nframes;
return nframes;
}
void
Track::set_monitoring (MonitorChoice mc)
{
if (mc != _monitoring) {
_monitoring = mc;
MonitoringChanged (); /* EMIT SIGNAL */
}
}