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:
@@ -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;
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user