{
fg[NORMAL] = @@COLPREFIX@_fg
fg[PRELIGHT] = @@COLPREFIX@_fg
- bg[NORMAL] = mix(0.3,@@COLPREFIX@_bright_indicator,darker(@@COLPREFIX@_bg))
- bg[PRELIGHT] = mix(0.3,@@COLPREFIX@_bright_indicator,darker(@@COLPREFIX@_bg))
+ bg[NORMAL] = mix(0.5,@@COLPREFIX@_bright_indicator,darker(@@COLPREFIX@_bg))
+ bg[PRELIGHT] = mix(0.5,@@COLPREFIX@_bright_indicator,darker(@@COLPREFIX@_bg))
}
style "monitor_disk_button" = "small_button"
{
fg[NORMAL] = @@COLPREFIX@_fg
fg[PRELIGHT] = @@COLPREFIX@_fg
- bg[NORMAL] = mix(0.3,@@COLPREFIX@_bright_indicator,darker(@@COLPREFIX@_bg))
- bg[PRELIGHT] = mix(0.3,@@COLPREFIX@_bright_indicator,darker(@@COLPREFIX@_bg))
+ bg[NORMAL] = mix(0.5,@@COLPREFIX@_bright_indicator,darker(@@COLPREFIX@_bg))
+ bg[PRELIGHT] = mix(0.5,@@COLPREFIX@_bright_indicator,darker(@@COLPREFIX@_bg))
}
style "solo_button" = "small_button"
_session->TransportStateChange.connect (_session_connections, invalidator (*this), boost::bind (&RouteUI::check_rec_enable_sensitivity, this), gui_context());
_session->RecordStateChanged.connect (_session_connections, invalidator (*this), boost::bind (&RouteUI::session_rec_enable_changed, this), gui_context());
+ _session->config.ParameterChanged.connect (*this, invalidator (*this), ui_bind (&RouteUI::parameter_changed, this, _1), gui_context());
Config->ParameterChanged.connect (*this, invalidator (*this), ui_bind (&RouteUI::parameter_changed, this, _1), gui_context());
rec_enable_button->signal_button_press_event().connect (sigc::mem_fun(*this, &RouteUI::rec_enable_press), false);
void
RouteUI::update_monitoring_display ()
{
+ if (!_route) {
+ return;
+ }
+
boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(_route);
if (!t) {
return;
}
- MonitorChoice mc = t->monitoring();
+ MonitorState ms = t->monitoring_state();
- if (mc & MonitorInput) {
- monitor_input_button->set_visual_state (1);
+ if (ms & MonitoringInput) {
+ if (t->monitoring_choice() & MonitorInput) {
+ monitor_input_button->set_visual_state (1);
+ } else {
+ monitor_input_button->set_visual_state (2);
+ }
} else {
monitor_input_button->set_visual_state (0);
}
- if (mc & MonitorDisk) {
- monitor_disk_button->set_visual_state (1);
+ if (ms & MonitoringDisk) {
+ if (t->monitoring_choice() & MonitorDisk) {
+ monitor_disk_button->set_visual_state (1);
+ } else {
+ monitor_disk_button->set_visual_state (2);
+ }
} else {
monitor_disk_button->set_visual_state (0);
}
signal together, which requires yet more buffers.
*/
- if (t->monitoring() & monitor_choice) {
- mc = MonitorChoice (t->monitoring() & ~monitor_choice);
+ if (t->monitoring_choice() & monitor_choice) {
+ mc = MonitorChoice (t->monitoring_choice() & ~monitor_choice);
} else {
/* this line will change when the options are non-orthogonal */
- // mc = MonitorChoice (t->monitoring() | monitor_choice);
+ // mc = MonitorChoice (t->monitoring_choice() | monitor_choice);
mc = monitor_choice;
}
RouteUI::route_rec_enable_changed ()
{
update_rec_display ();
+ update_monitoring_display ();
}
void
RouteUI::session_rec_enable_changed ()
{
update_rec_display ();
+ update_monitoring_display ();
}
void
} else {
rec_enable_button->set_sensitive (true);
}
+
+ update_monitoring_display ();
}
void
RouteUI::parameter_changed (string const & p)
{
+ /* this handles RC and per-session parameter changes */
+
if (p == "disable-disarm-during-roll") {
check_rec_enable_sensitivity ();
} else if (p == "use-monitor-bus" || p == "solo-control-is-listen-control" || p == "listen-position") {
set_button_names ();
+ } else if (p == "auto-input") {
+ update_monitoring_display ();
}
}
protected:
friend class AudioTrack;
- int process (framepos_t transport_frame, pframes_t nframes, bool can_record, bool& need_butler);
+ int process (framepos_t transport_frame, pframes_t nframes, bool& need_butler);
bool commit (framecnt_t nframes);
private:
bool can_use_mode (TrackMode m, bool& bounce_required);
int roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame,
- int declick, bool can_record, bool& need_butler);
+ int declick, bool& need_butler);
void use_new_diskstream ();
void set_diskstream (boost::shared_ptr<Diskstream>);
protected:
friend class Track;
- virtual int process (framepos_t transport_frame, pframes_t nframes, bool can_record, bool& need_butler) = 0;
+ virtual int process (framepos_t transport_frame, pframes_t nframes, bool& need_butler) = 0;
virtual bool commit (framecnt_t nframes) = 0;
//private:
void main_thread();
int silent_process_routes (pframes_t nframes, framepos_t start_frame, framepos_t end_frame,
- bool can_record, bool& need_butler);
+ bool& need_butler);
int process_routes (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, int declick,
- bool can_record, bool& need_butler);
+ bool& need_butler);
int routes_no_roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame,
- bool non_rt_pending, bool can_record, int declick);
+ bool non_rt_pending, int declick);
void process_one_route (Route * route);
protected:
friend class MidiTrack;
- int process (framepos_t transport_frame, pframes_t nframes, bool can_record, bool& need_butler);
+ int process (framepos_t transport_frame, pframes_t nframes, bool& need_butler);
bool commit (framecnt_t nframes);
static framecnt_t midi_readahead;
int init ();
- int roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame,
- int declick, bool can_record, bool& need_butler);
+ int roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, int declick, bool& need_butler);
void realtime_handle_transport_stopped ();
void realtime_locate ();
bool _midi_thru;
bool _input_active;
- int no_roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame,
- bool state_changing, bool can_record);
+ int no_roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, bool state_changing);
void push_midi_input_to_step_edit_ringbuffer (framecnt_t nframes);
void diskstream_data_recorded (boost::shared_ptr<MidiBuffer>, boost::weak_ptr<MidiSource>);
/* these are the core of the API of a Route. see the protected sections as well */
virtual int roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame,
- int declick, bool can_record, bool& need_butler);
+ int declick, bool& need_butler);
virtual int no_roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame,
- bool state_changing, bool can_record);
+ bool state_changing);
virtual int silent_roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame,
- bool can_record, bool& need_butler);
+ bool& need_butler);
virtual void toggle_monitor_input ();
virtual bool can_record() { return false; }
PBD::Signal0<void> TrackModeChanged;
virtual void set_monitoring (MonitorChoice);
- MonitorChoice monitoring() const { return _monitoring; }
+ MonitorChoice monitoring_choice() const { return _monitoring; }
+ MonitorState monitoring_state();
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);
+ bool state_changing);
int silent_roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame,
- bool can_record, bool& need_butler);
+ bool& need_butler);
virtual int roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame,
- int declick, bool can_record, bool& need_butler) = 0;
+ int declick, bool& need_butler) = 0;
bool needs_butler() const { return _needs_butler; }
void toggle_monitor_input ();
MonitorCue = 0x4,
};
+ enum MonitorState {
+ MonitoringSilence = 0x1,
+ MonitoringInput = 0x2,
+ MonitoringDisk = 0x4,
+ };
+
enum PFLPosition {
/** PFL signals come from before pre-fader processors */
PFLFromBeforeProcessors,
}
int
-AudioDiskstream::process (framepos_t transport_frame, pframes_t nframes, bool can_record, bool& need_butler)
+AudioDiskstream::process (framepos_t transport_frame, pframes_t nframes, bool& need_butler)
{
uint32_t n;
boost::shared_ptr<ChannelList> c = channels.reader();
framecnt_t rec_offset = 0;
framecnt_t rec_nframes = 0;
bool collect_playback = false;
+ bool can_record = _session.actively_recording ();
playback_distance = 0;
collect_playback = true;
}
- if ((_track->monitoring() & MonitorDisk) || collect_playback) {
-
+ if ((_track->monitoring_state () & MonitoringDisk) || collect_playback) {
+
/* we're doing playback */
framecnt_t necessary_samples;
}
int
-AudioTrack::roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, int declick,
- bool can_record, bool& need_butler)
+AudioTrack::roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, int declick, bool& need_butler)
{
Glib::RWLock::ReaderLock lm (_processor_lock, Glib::TRY_LOCK);
+
if (!lm.locked()) {
return 0;
}
playback distance to zero, thus causing diskstream::commit
to do nothing.
*/
- return diskstream->process (transport_frame, 0, can_record, need_butler);
+ return diskstream->process (transport_frame, 0, need_butler);
}
_silent = false;
_amp->apply_gain_automation(false);
- if ((dret = diskstream->process (transport_frame, nframes, can_record, need_butler)) != 0) {
+ if ((dret = diskstream->process (transport_frame, nframes, need_butler)) != 0) {
silence (nframes);
return dret;
}
_input->process_input (_meter, start_frame, end_frame, nframes);
}
- 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)
- */
+ if (monitoring_state() == MonitoringInput) {
passthru (start_frame, end_frame, nframes, false);
this_nframes = min (nframes, length - current_frame);
- if ((ret = roll (this_nframes, current_frame, current_frame + nframes, false, false, need_butler)) != 0) {
+ if ((ret = roll (this_nframes, current_frame, current_frame + nframes, false, need_butler)) != 0) {
silence (nframes);
return ret;
}
}
int
-Graph::silent_process_routes (pframes_t nframes, framepos_t start_frame, framepos_t end_frame,
- bool can_record, bool& need_butler)
+Graph::silent_process_routes (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, bool& need_butler)
{
_process_nframes = nframes;
_process_start_frame = start_frame;
_process_end_frame = end_frame;
- _process_can_record = can_record;
_process_silent = true;
_process_noroll = false;
}
int
-Graph::process_routes (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, int declick,
- bool can_record, bool& need_butler)
+Graph::process_routes (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, int declick, bool& need_butler)
{
DEBUG_TRACE (DEBUG::ProcessThreads, string_compose ("graph execution from %1 to %2 = %3\n", start_frame, end_frame, nframes));
_process_nframes = nframes;
_process_start_frame = start_frame;
_process_end_frame = end_frame;
- _process_can_record = can_record;
_process_declick = declick;
_process_silent = false;
int
Graph::routes_no_roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame,
- bool non_rt_pending, bool can_record, int declick)
+ bool non_rt_pending, int declick)
{
DEBUG_TRACE (DEBUG::ProcessThreads, string_compose ("no-roll graph execution from %1 to %2 = %3\n", start_frame, end_frame, nframes));
_process_nframes = nframes;
_process_start_frame = start_frame;
_process_end_frame = end_frame;
- _process_can_record = can_record;
_process_declick = declick;
_process_non_rt_pending = non_rt_pending;
DEBUG_TRACE (DEBUG::ProcessThreads, string_compose ("%1 runs route %2\n", pthread_self(), route->name()));
if (_process_silent) {
- retval = route->silent_roll (_process_nframes, _process_start_frame, _process_end_frame, _process_can_record, need_butler);
+ retval = route->silent_roll (_process_nframes, _process_start_frame, _process_end_frame, need_butler);
} else if (_process_noroll) {
route->set_pending_declick (_process_declick);
- retval = route->no_roll (_process_nframes, _process_start_frame, _process_end_frame, _process_non_rt_pending, _process_can_record);
+ retval = route->no_roll (_process_nframes, _process_start_frame, _process_end_frame, _process_non_rt_pending);
} else {
route->set_pending_declick (_process_declick);
- retval = route->roll (_process_nframes, _process_start_frame, _process_end_frame, _process_declick, _process_can_record, need_butler);
+ retval = route->roll (_process_nframes, _process_start_frame, _process_end_frame, _process_declick, need_butler);
}
if (retval) {
#endif
int
-MidiDiskstream::process (framepos_t transport_frame, pframes_t nframes, bool can_record, bool& need_butler)
+MidiDiskstream::process (framepos_t transport_frame, pframes_t nframes, bool& need_butler)
{
int ret = -1;
framecnt_t rec_offset = 0;
framecnt_t rec_nframes = 0;
bool nominally_recording;
bool re = record_enabled ();
+ bool can_record = _session.actively_recording ();
playback_distance = 0;
}
int
-MidiTrack::roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, int declick,
- bool can_record, bool& needs_butler)
+MidiTrack::roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, int declick, bool& needs_butler)
{
Glib::RWLock::ReaderLock lm (_processor_lock, Glib::TRY_LOCK);
if (!lm.locked()) {
playback distance to zero, thus causing diskstream::commit
to do nothing.
*/
- return diskstream->process (transport_frame, 0, can_record, needs_butler);
+ return diskstream->process (transport_frame, 0, needs_butler);
}
_silent = false;
- if ((dret = diskstream->process (transport_frame, nframes, can_record, needs_butler)) != 0) {
+ if ((dret = diskstream->process (transport_frame, nframes, needs_butler)) != 0) {
silence (nframes);
return dret;
}
_input->process_input (_meter, start_frame, end_frame, nframes);
}
- if (should_monitor_input ()) {
+ if (monitoring_state() == MonitoringInput) {
/* not actually recording, but we want to hear the input material anyway,
at least potentially (depending on monitoring options)
}
int
-MidiTrack::no_roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame,
- bool state_changing, bool can_record)
+MidiTrack::no_roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, bool state_changing)
{
- int ret = Track::no_roll (nframes, start_frame, end_frame, state_changing, can_record);
+ int ret = Track::no_roll (nframes, start_frame, end_frame, state_changing);
if (ret == 0 && _step_editing) {
push_midi_input_to_step_edit_ringbuffer (nframes);
}
int
-Route::no_roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame,
- bool session_state_changing, bool /*can_record*/)
+Route::no_roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, bool session_state_changing)
{
Glib::RWLock::ReaderLock lm (_processor_lock, Glib::TRY_LOCK);
if (!lm.locked()) {
}
int
-Route::roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, int declick,
- bool /*can_record*/, bool& /* need_butler */)
+Route::roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, int declick, bool& /* need_butler */)
{
Glib::RWLock::ReaderLock lm (_processor_lock, Glib::TRY_LOCK);
if (!lm.locked()) {
}
int
-Route::silent_roll (pframes_t nframes, framepos_t /*start_frame*/, framepos_t /*end_frame*/,
- bool /*can_record*/, bool& /* need_butler */)
+Route::silent_roll (pframes_t nframes, framepos_t /*start_frame*/, framepos_t /*end_frame*/, bool& /* need_butler */)
{
silence (nframes);
return 0;
if (route_graph->threads_in_use() > 0) {
DEBUG_TRACE(DEBUG::ProcessThreads,"calling graph/no-roll\n");
- route_graph->routes_no_roll( nframes, _transport_frame, end_frame, non_realtime_work_pending(), actively_recording(), declick);
+ route_graph->routes_no_roll( nframes, _transport_frame, end_frame, non_realtime_work_pending(), declick);
} else {
for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
(*i)->set_pending_declick (declick);
- if ((*i)->no_roll (nframes, _transport_frame, end_frame, non_realtime_work_pending(),
- actively_recording())) {
+ if ((*i)->no_roll (nframes, _transport_frame, end_frame, non_realtime_work_pending())) {
error << string_compose(_("Session: error in no roll for %1"), (*i)->name()) << endmsg;
ret = -1;
break;
int
Session::process_routes (pframes_t nframes, bool& need_butler)
{
- bool record_active;
int declick = get_transport_declick_required();
boost::shared_ptr<RouteList> r = routes.reader ();
declick = -1;
}
- record_active = actively_recording(); // || (get_record_enabled() && get_punch_in());
-
const framepos_t start_frame = _transport_frame;
const framepos_t end_frame = _transport_frame + floor (nframes * _transport_speed);
*/
if (1 || route_graph->threads_in_use() > 0) {
DEBUG_TRACE(DEBUG::ProcessThreads,"calling graph/process-routes\n");
- route_graph->process_routes (nframes, start_frame, end_frame, declick, record_active, need_butler);
+ route_graph->process_routes (nframes, start_frame, end_frame, declick, need_butler);
} else {
for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
(*i)->set_pending_declick (declick);
- if ((ret = (*i)->roll (nframes, start_frame, end_frame, declick, record_active, need_butler)) < 0) {
+ if ((ret = (*i)->roll (nframes, start_frame, end_frame, declick, need_butler)) < 0) {
stop_transport ();
return -1;
}
int
Session::silent_process_routes (pframes_t nframes, bool& need_butler)
{
- bool record_active = actively_recording();
boost::shared_ptr<RouteList> r = routes.reader ();
const framepos_t start_frame = _transport_frame;
tracks, the graph never gets updated.
*/
if (1 || route_graph->threads_in_use() > 0) {
- route_graph->silent_process_routes (nframes, start_frame, end_frame, record_active, need_butler);
+ route_graph->silent_process_routes (nframes, start_frame, end_frame, need_butler);
} else {
for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
continue;
}
- if ((ret = (*i)->silent_roll (nframes, start_frame, end_frame, record_active, need_butler)) < 0) {
+ if ((ret = (*i)->silent_roll (nframes, start_frame, end_frame, need_butler)) < 0) {
stop_transport ();
return -1;
}
}
int
-Track::no_roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame,
- bool session_state_changing, bool can_record)
+Track::no_roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, bool session_state_changing)
{
Glib::RWLock::ReaderLock lm (_processor_lock, Glib::TRY_LOCK);
if (!lm.locked()) {
return 0;
}
+ bool can_record = _session.actively_recording ();
+
if (n_outputs().n_total() == 0) {
return 0;
}
}
int
-Track::silent_roll (pframes_t nframes, framepos_t /*start_frame*/, framepos_t /*end_frame*/,
- bool can_record, bool& need_butler)
+Track::silent_roll (pframes_t nframes, framepos_t /*start_frame*/, framepos_t /*end_frame*/, bool& need_butler)
{
Glib::RWLock::ReaderLock lm (_processor_lock, Glib::TRY_LOCK);
if (!lm.locked()) {
silence (nframes);
- return _diskstream->process (_session.transport_frame(), nframes, can_record, need_butler);
+ return _diskstream->process (_session.transport_frame(), nframes, need_butler);
}
void
}
}
-bool
-Track::should_monitor_input ()
+MonitorState
+Track::monitoring_state ()
{
- return (_monitoring & MonitorInput) ||
- (!(_monitoring & MonitorDisk) &&
- (diskstream->record_enabled() &&
- !can_record &&
- !_session.config.get_auto_input()));
+ MonitorState ms = MonitoringSilence;
+
+ if (_session.transport_rolling()) {
+
+ /* roll case */
+
+ if ((_monitoring & MonitorInput) || // explicitly requested input monitoring
+ (!(_monitoring & MonitorDisk) && // disk monitoring not requested
+ (_diskstream->record_enabled() && // record-enabled BUT
+ !_session.actively_recording() && // session NOT rec-armed
+ !_session.config.get_auto_input()))) { // and auto-input is off
+
+ ms = MonitoringInput;
+
+ } else {
+
+ ms = MonitorState (0);
+ }
+
+ if ((_monitoring & MonitorDisk) || // explicitly requested disk monitoring
+ (!(_monitoring & MonitorInput) && // input monitoring not requested
+ (_diskstream->record_enabled() && // record-enabled BUT
+ (_session.actively_recording() || // session rec-armed OR
+ _session.config.get_auto_input())))) { // auto-input is ON (mon-input while rec-rolling
+
+ ms = MonitorState (ms | MonitoringDisk);
+ }
+
+ } else {
+
+ /* no-roll case */
+
+ if (send_silence()) {
+ ms = MonitoringSilence;
+ } else {
+ ms = MonitoringInput;
+ }
+ }
+
+ return ms;
}