mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-07 15:25:01 +01:00
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:
parent
49b459f8d3
commit
3764eedca0
12 changed files with 272 additions and 41 deletions
|
|
@ -148,6 +148,27 @@ style "mixer_track_rec_enable_button_active" = "track_rec_enable_button_active"
|
||||||
ythickness = 0
|
ythickness = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
style "monitor_input_button" = "small_button"
|
||||||
|
{
|
||||||
|
fg[NORMAL] = darker(@@COLPREFIX@_fg)
|
||||||
|
fg[PRELIGHT] = darker(@@COLPREFIX@_fg)
|
||||||
|
bg[NORMAL] = mix(0.1,@@COLPREFIX@_bright_indicator,darker(@@COLPREFIX@_bg))
|
||||||
|
bg[PRELIGHT] = mix(0.1,@@COLPREFIX@_bright_indicator,darker(@@COLPREFIX@_bg))
|
||||||
|
|
||||||
|
fg[ACTIVE] = @@COLPREFIX@_fg
|
||||||
|
bg[ACTIVE] = @@COLPREFIX@_bright_indicator
|
||||||
|
}
|
||||||
|
|
||||||
|
style "monitor_disk_button" = "small_button"
|
||||||
|
{
|
||||||
|
fg[NORMAL] = darker(@@COLPREFIX@_fg)
|
||||||
|
fg[PRELIGHT] = darker(@@COLPREFIX@_fg)
|
||||||
|
bg[NORMAL] = mix(0.1,@@COLPREFIX@_bright_indicator,darker(@@COLPREFIX@_bg))
|
||||||
|
bg[PRELIGHT] = mix(0.1,@@COLPREFIX@_bright_indicator,darker(@@COLPREFIX@_bg))
|
||||||
|
|
||||||
|
fg[ACTIVE] = @@COLPREFIX@_fg
|
||||||
|
bg[ACTIVE] = @@COLPREFIX@_bright_indicator
|
||||||
|
}
|
||||||
|
|
||||||
style "solo_button" = "small_button"
|
style "solo_button" = "small_button"
|
||||||
{
|
{
|
||||||
|
|
@ -247,6 +268,18 @@ style "mixer_solo_button_active" = "solo_button_active"
|
||||||
ythickness = 0
|
ythickness = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
style "mixer_monitor_input_button" = "monitor_input_button"
|
||||||
|
{
|
||||||
|
xthickness = 0
|
||||||
|
ythickness = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
style "mixer_monitor_disk_button" = "monitor_disk_button"
|
||||||
|
{
|
||||||
|
xthickness = 0
|
||||||
|
ythickness = 0
|
||||||
|
}
|
||||||
|
|
||||||
style "monitor_opt_button" = "small_button"
|
style "monitor_opt_button" = "small_button"
|
||||||
{
|
{
|
||||||
bg[NORMAL] = mix(0.1,@@COLPREFIX@_not_so_bright_indicator,@@COLPREFIX@_bg)
|
bg[NORMAL] = mix(0.1,@@COLPREFIX@_not_so_bright_indicator,@@COLPREFIX@_bg)
|
||||||
|
|
|
||||||
|
|
@ -80,6 +80,8 @@ widget "*MixerSoloButton" style:highest "mixer_solo_button"
|
||||||
widget "*MixerSoloButton-alternate" style:highest "mixer_solo_button_alternate"
|
widget "*MixerSoloButton-alternate" style:highest "mixer_solo_button_alternate"
|
||||||
widget "*MixerSoloButton-alternate2" style:highest "mixer_solo_button_alternate2"
|
widget "*MixerSoloButton-alternate2" style:highest "mixer_solo_button_alternate2"
|
||||||
widget "*MixerSoloButton-active" style:highest "mixer_solo_button_active"
|
widget "*MixerSoloButton-active" style:highest "mixer_solo_button_active"
|
||||||
|
widget "*MixerMonitorInputButton" style:highest "mixer_monitor_input_button"
|
||||||
|
widget "*MixerMonitorDiskButton" style:highest "mixer_monitor_disk_button"
|
||||||
widget "*TrackLoopButton*" style:highest "track_loop_button"
|
widget "*TrackLoopButton*" style:highest "track_loop_button"
|
||||||
widget "*PanAutomationLineSelector*" style:highest "multiline_combo"
|
widget "*PanAutomationLineSelector*" style:highest "multiline_combo"
|
||||||
widget "*EditorTimeButton*" style:highest "time_button"
|
widget "*EditorTimeButton*" style:highest "time_button"
|
||||||
|
|
|
||||||
|
|
@ -87,7 +87,7 @@ MixerStrip::MixerStrip (Mixer_UI& mx, Session* sess, bool in_mixer)
|
||||||
, panners (sess)
|
, panners (sess)
|
||||||
, button_table (3, 1)
|
, button_table (3, 1)
|
||||||
, solo_led_table (2, 2)
|
, solo_led_table (2, 2)
|
||||||
, middle_button_table (1, 2)
|
, middle_button_table (2, 2)
|
||||||
, bottom_button_table (1, 2)
|
, bottom_button_table (1, 2)
|
||||||
, meter_point_label (_("pre"))
|
, meter_point_label (_("pre"))
|
||||||
, midi_input_enable_button (0)
|
, midi_input_enable_button (0)
|
||||||
|
|
@ -112,7 +112,7 @@ MixerStrip::MixerStrip (Mixer_UI& mx, Session* sess, boost::shared_ptr<Route> rt
|
||||||
, gpm (sess, 250)
|
, gpm (sess, 250)
|
||||||
, panners (sess)
|
, panners (sess)
|
||||||
, button_table (3, 1)
|
, button_table (3, 1)
|
||||||
, middle_button_table (1, 2)
|
, middle_button_table (2, 2)
|
||||||
, bottom_button_table (1, 2)
|
, bottom_button_table (1, 2)
|
||||||
, meter_point_label (_("pre"))
|
, meter_point_label (_("pre"))
|
||||||
, midi_input_enable_button (0)
|
, midi_input_enable_button (0)
|
||||||
|
|
@ -184,6 +184,9 @@ MixerStrip::init ()
|
||||||
mute_button->set_name ("MixerMuteButton");
|
mute_button->set_name ("MixerMuteButton");
|
||||||
solo_button->set_name ("MixerSoloButton");
|
solo_button->set_name ("MixerSoloButton");
|
||||||
|
|
||||||
|
monitor_input_button->set_name ("MixerMonitorInputButton");
|
||||||
|
monitor_disk_button->set_name ("MixerMonitorInputButton");
|
||||||
|
|
||||||
solo_isolated_led = manage (new LED);
|
solo_isolated_led = manage (new LED);
|
||||||
solo_isolated_led->show ();
|
solo_isolated_led->show ();
|
||||||
solo_isolated_led->set_diameter (6);
|
solo_isolated_led->set_diameter (6);
|
||||||
|
|
@ -235,6 +238,8 @@ MixerStrip::init ()
|
||||||
middle_button_table.set_spacings (0);
|
middle_button_table.set_spacings (0);
|
||||||
middle_button_table.attach (*mute_button, 0, 1, 0, 1);
|
middle_button_table.attach (*mute_button, 0, 1, 0, 1);
|
||||||
middle_button_table.attach (*solo_button, 1, 2, 0, 1);
|
middle_button_table.attach (*solo_button, 1, 2, 0, 1);
|
||||||
|
middle_button_table.attach (*monitor_input_button, 0, 1, 1, 2);
|
||||||
|
middle_button_table.attach (*monitor_disk_button, 1, 2, 1, 2);
|
||||||
|
|
||||||
bottom_button_table.set_col_spacings (0);
|
bottom_button_table.set_col_spacings (0);
|
||||||
bottom_button_table.set_homogeneous (true);
|
bottom_button_table.set_homogeneous (true);
|
||||||
|
|
@ -396,6 +401,14 @@ MixerStrip::set_route (boost::shared_ptr<Route> rt)
|
||||||
global_vpacker.pack_start (*spacer, false, false);
|
global_vpacker.pack_start (*spacer, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (is_track()) {
|
||||||
|
monitor_input_button->show ();
|
||||||
|
monitor_disk_button->show ();
|
||||||
|
} else {
|
||||||
|
monitor_input_button->hide();
|
||||||
|
monitor_disk_button->hide ();
|
||||||
|
}
|
||||||
|
|
||||||
if (is_midi_track()) {
|
if (is_midi_track()) {
|
||||||
if (midi_input_enable_button == 0) {
|
if (midi_input_enable_button == 0) {
|
||||||
Image* img = manage (new Image (get_icon (X_("midi_socket_small"))));
|
Image* img = manage (new Image (get_icon (X_("midi_socket_small"))));
|
||||||
|
|
@ -1643,6 +1656,8 @@ MixerStrip::drop_send ()
|
||||||
rec_enable_button->set_sensitive (true);
|
rec_enable_button->set_sensitive (true);
|
||||||
solo_isolated_led->set_sensitive (true);
|
solo_isolated_led->set_sensitive (true);
|
||||||
solo_safe_led->set_sensitive (true);
|
solo_safe_led->set_sensitive (true);
|
||||||
|
monitor_input_button->set_sensitive (true);
|
||||||
|
monitor_disk_button->set_sensitive (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -1679,6 +1694,8 @@ MixerStrip::show_send (boost::shared_ptr<Send> send)
|
||||||
rec_enable_button->set_sensitive (false);
|
rec_enable_button->set_sensitive (false);
|
||||||
solo_isolated_led->set_sensitive (false);
|
solo_isolated_led->set_sensitive (false);
|
||||||
solo_safe_led->set_sensitive (false);
|
solo_safe_led->set_sensitive (false);
|
||||||
|
monitor_input_button->set_sensitive (false);
|
||||||
|
monitor_disk_button->set_sensitive (false);
|
||||||
|
|
||||||
if (boost::dynamic_pointer_cast<InternalSend>(send)) {
|
if (boost::dynamic_pointer_cast<InternalSend>(send)) {
|
||||||
output_button.set_sensitive (false);
|
output_button.set_sensitive (false);
|
||||||
|
|
@ -1714,6 +1731,8 @@ MixerStrip::set_button_names ()
|
||||||
case Wide:
|
case Wide:
|
||||||
rec_enable_button_label.set_text (_("Rec"));
|
rec_enable_button_label.set_text (_("Rec"));
|
||||||
mute_button_label.set_text (_("Mute"));
|
mute_button_label.set_text (_("Mute"));
|
||||||
|
monitor_input_button_label.set_text (_("In"));
|
||||||
|
monitor_disk_button_label.set_text (_("Disk"));
|
||||||
if (_route && _route->solo_safe()) {
|
if (_route && _route->solo_safe()) {
|
||||||
solo_button_label.set_text (X_("!"));
|
solo_button_label.set_text (X_("!"));
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -1735,6 +1754,8 @@ MixerStrip::set_button_names ()
|
||||||
default:
|
default:
|
||||||
rec_enable_button_label.set_text (_("R"));
|
rec_enable_button_label.set_text (_("R"));
|
||||||
mute_button_label.set_text (_("M"));
|
mute_button_label.set_text (_("M"));
|
||||||
|
monitor_input_button_label.set_text (_("I"));
|
||||||
|
monitor_disk_button_label.set_text (_("D"));
|
||||||
if (_route && _route->solo_safe()) {
|
if (_route && _route->solo_safe()) {
|
||||||
solo_button_label.set_text (X_("!"));
|
solo_button_label.set_text (X_("!"));
|
||||||
if (!Config->get_solo_control_is_listen_control()) {
|
if (!Config->get_solo_control_is_listen_control()) {
|
||||||
|
|
|
||||||
|
|
@ -137,6 +137,22 @@ RouteUI::init ()
|
||||||
// show_sends_button->set_self_managed (true);
|
// show_sends_button->set_self_managed (true);
|
||||||
UI::instance()->set_tip (show_sends_button, _("make mixer strips show sends to this bus"), "");
|
UI::instance()->set_tip (show_sends_button, _("make mixer strips show sends to this bus"), "");
|
||||||
|
|
||||||
|
monitor_input_button = manage (new BindableToggleButton ());
|
||||||
|
// monitor_input_button->set_self_managed (true);
|
||||||
|
monitor_input_button->set_name ("MonitorInputButton");
|
||||||
|
monitor_input_button->add (monitor_input_button_label);
|
||||||
|
monitor_input_button_label.show ();
|
||||||
|
UI::instance()->set_tip (monitor_input_button, _("Monitor input"), "");
|
||||||
|
monitor_input_button->set_no_show_all (true);
|
||||||
|
|
||||||
|
monitor_disk_button = manage (new BindableToggleButton ());
|
||||||
|
// monitor_disk_button->set_self_managed (true);
|
||||||
|
monitor_disk_button->set_name ("MonitorDiskButton");
|
||||||
|
monitor_disk_button->add (monitor_disk_button_label);
|
||||||
|
monitor_disk_button_label.show ();
|
||||||
|
UI::instance()->set_tip (monitor_disk_button, _("Monitor playback"), "");
|
||||||
|
monitor_disk_button->set_no_show_all (true);
|
||||||
|
|
||||||
_session->SoloChanged.connect (_session_connections, invalidator (*this), boost::bind (&RouteUI::solo_changed_so_update_mute, this), gui_context());
|
_session->SoloChanged.connect (_session_connections, invalidator (*this), boost::bind (&RouteUI::solo_changed_so_update_mute, this), gui_context());
|
||||||
_session->TransportStateChange.connect (_session_connections, invalidator (*this), boost::bind (&RouteUI::check_rec_enable_sensitivity, this), gui_context());
|
_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->RecordStateChanged.connect (_session_connections, invalidator (*this), boost::bind (&RouteUI::session_rec_enable_changed, this), gui_context());
|
||||||
|
|
@ -153,6 +169,12 @@ RouteUI::init ()
|
||||||
solo_button->signal_button_release_event().connect (sigc::mem_fun(*this, &RouteUI::solo_release), false);
|
solo_button->signal_button_release_event().connect (sigc::mem_fun(*this, &RouteUI::solo_release), false);
|
||||||
mute_button->signal_button_press_event().connect (sigc::mem_fun(*this, &RouteUI::mute_press), false);
|
mute_button->signal_button_press_event().connect (sigc::mem_fun(*this, &RouteUI::mute_press), false);
|
||||||
mute_button->signal_button_release_event().connect (sigc::mem_fun(*this, &RouteUI::mute_release), false);
|
mute_button->signal_button_release_event().connect (sigc::mem_fun(*this, &RouteUI::mute_release), false);
|
||||||
|
|
||||||
|
monitor_input_button->signal_button_press_event().connect (sigc::mem_fun(*this, &RouteUI::monitor_input_press), false);
|
||||||
|
monitor_input_button->signal_button_release_event().connect (sigc::mem_fun(*this, &RouteUI::monitor_input_release), false);
|
||||||
|
|
||||||
|
monitor_disk_button->signal_button_press_event().connect (sigc::mem_fun(*this, &RouteUI::monitor_disk_press), false);
|
||||||
|
monitor_disk_button->signal_button_release_event().connect (sigc::mem_fun(*this, &RouteUI::monitor_disk_release), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -224,6 +246,11 @@ RouteUI::set_route (boost::shared_ptr<Route> rp)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (is_track()) {
|
||||||
|
boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(_route);
|
||||||
|
t->MonitoringChanged.connect (route_connections, invalidator (*this), boost::bind (&RouteUI::monitoring_changed, this), gui_context());
|
||||||
|
}
|
||||||
|
|
||||||
mute_button->unset_flags (Gtk::CAN_FOCUS);
|
mute_button->unset_flags (Gtk::CAN_FOCUS);
|
||||||
solo_button->unset_flags (Gtk::CAN_FOCUS);
|
solo_button->unset_flags (Gtk::CAN_FOCUS);
|
||||||
|
|
||||||
|
|
@ -555,6 +582,96 @@ RouteUI::rec_enable_press(GdkEventButton* ev)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
RouteUI::monitoring_changed ()
|
||||||
|
{
|
||||||
|
boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(_route);
|
||||||
|
|
||||||
|
if (!t) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
MonitorChoice mc = t->monitoring();
|
||||||
|
|
||||||
|
if (mc & MonitorInput) {
|
||||||
|
monitor_input_button->set_active (true);
|
||||||
|
} else {
|
||||||
|
monitor_input_button->set_active (false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mc & MonitorDisk) {
|
||||||
|
monitor_disk_button->set_active (true);
|
||||||
|
} else {
|
||||||
|
monitor_disk_button->set_active (false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
RouteUI::monitor_input_press(GdkEventButton* ev)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
RouteUI::monitor_input_release(GdkEventButton* ev)
|
||||||
|
{
|
||||||
|
return monitor_release (ev, MonitorInput);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
RouteUI::monitor_disk_press (GdkEventButton* ev)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
RouteUI::monitor_disk_release (GdkEventButton* ev)
|
||||||
|
{
|
||||||
|
return monitor_release (ev, MonitorDisk);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
RouteUI::monitor_release (GdkEventButton* ev, MonitorChoice monitor_choice)
|
||||||
|
{
|
||||||
|
if (ev->button != 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(_route);
|
||||||
|
|
||||||
|
if (!t) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
MonitorChoice mc;
|
||||||
|
boost::shared_ptr<RouteList> rl;
|
||||||
|
|
||||||
|
/* XXX for now, monitoring choices are orthogonal. cue monitoring
|
||||||
|
will follow in 3.X but requires mixing the input and playback (disk)
|
||||||
|
signal together, which requires yet more buffers.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (t->monitoring() & monitor_choice) {
|
||||||
|
mc = MonitorChoice (t->monitoring() & ~monitor_choice);
|
||||||
|
} else {
|
||||||
|
/* this line will change when the options are non-orthogonal */
|
||||||
|
// mc = MonitorChoice (t->monitoring() | monitor_choice);
|
||||||
|
mc = monitor_choice;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Keyboard::modifier_state_equals (ev->state, Keyboard::ModifierMask (Keyboard::PrimaryModifier|Keyboard::TertiaryModifier))) {
|
||||||
|
rl = _session->get_routes ();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
rl.reset (new RouteList);
|
||||||
|
rl->push_back (route());
|
||||||
|
}
|
||||||
|
|
||||||
|
_session->set_monitoring (rl, mc, Session::rt_cleanup, true);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
RouteUI::build_record_menu ()
|
RouteUI::build_record_menu ()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -94,6 +94,8 @@ class RouteUI : public virtual AxisView
|
||||||
BindableToggleButton* solo_button;
|
BindableToggleButton* solo_button;
|
||||||
BindableToggleButton* rec_enable_button; /* audio tracks */
|
BindableToggleButton* rec_enable_button; /* audio tracks */
|
||||||
BindableToggleButton* show_sends_button; /* busses */
|
BindableToggleButton* show_sends_button; /* busses */
|
||||||
|
BindableToggleButton* monitor_input_button;
|
||||||
|
BindableToggleButton* monitor_disk_button;
|
||||||
|
|
||||||
LED* solo_safe_led;
|
LED* solo_safe_led;
|
||||||
LED* solo_isolated_led;
|
LED* solo_isolated_led;
|
||||||
|
|
@ -101,6 +103,8 @@ class RouteUI : public virtual AxisView
|
||||||
Gtk::Label solo_button_label;
|
Gtk::Label solo_button_label;
|
||||||
Gtk::Label mute_button_label;
|
Gtk::Label mute_button_label;
|
||||||
Gtk::Label rec_enable_button_label;
|
Gtk::Label rec_enable_button_label;
|
||||||
|
Gtk::Label monitor_input_button_label;
|
||||||
|
Gtk::Label monitor_disk_button_label;
|
||||||
|
|
||||||
void send_blink (bool);
|
void send_blink (bool);
|
||||||
sigc::connection send_blink_connection;
|
sigc::connection send_blink_connection;
|
||||||
|
|
@ -121,6 +125,13 @@ class RouteUI : public virtual AxisView
|
||||||
bool show_sends_press(GdkEventButton*);
|
bool show_sends_press(GdkEventButton*);
|
||||||
bool show_sends_release(GdkEventButton*);
|
bool show_sends_release(GdkEventButton*);
|
||||||
|
|
||||||
|
bool monitor_release(GdkEventButton*, ARDOUR::MonitorChoice);
|
||||||
|
bool monitor_input_press(GdkEventButton*);
|
||||||
|
bool monitor_input_release(GdkEventButton*);
|
||||||
|
bool monitor_disk_press(GdkEventButton*);
|
||||||
|
bool monitor_disk_release(GdkEventButton*);
|
||||||
|
void monitoring_changed ();
|
||||||
|
|
||||||
void step_gain_up ();
|
void step_gain_up ();
|
||||||
void step_gain_down ();
|
void step_gain_down ();
|
||||||
void page_gain_up ();
|
void page_gain_up ();
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,7 @@
|
||||||
#include <glibmm/thread.h>
|
#include <glibmm/thread.h>
|
||||||
|
|
||||||
#include "pbd/error.h"
|
#include "pbd/error.h"
|
||||||
|
#include "pbd/event_loop.h"
|
||||||
#include "pbd/rcu.h"
|
#include "pbd/rcu.h"
|
||||||
#include "pbd/statefuldestructible.h"
|
#include "pbd/statefuldestructible.h"
|
||||||
#include "pbd/signals.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_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_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_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::Signal1<void,bool> SoloActive;
|
||||||
PBD::Signal0<void> SoloChanged;
|
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>);
|
static int ask_about_playlist_deletion (boost::shared_ptr<Playlist>);
|
||||||
|
|
||||||
/* realtime "apply to set of routes" operations */
|
/* realtime "apply to set of routes" operations */
|
||||||
SessionEvent* get_rt_event (
|
template<typename T> SessionEvent*
|
||||||
boost::shared_ptr<RouteList> rl, bool yn,
|
get_rt_event (boost::shared_ptr<RouteList> rl, T targ, SessionEvent::RTeventCallback after, bool group_override,
|
||||||
SessionEvent::RTeventCallback after, bool group_override,
|
void (Session::*method) (boost::shared_ptr<RouteList>, T, bool)) {
|
||||||
void (Session::*method) (boost::shared_ptr<RouteList>, bool, 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_solo (boost::shared_ptr<RouteList>, bool yn, bool group_override);
|
||||||
void rt_set_just_one_solo (boost::shared_ptr<RouteList>, bool yn, bool /* ignored*/ );
|
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_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_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_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 */
|
/** temporary list of Diskstreams used only during load of 2.X sessions */
|
||||||
std::list<boost::shared_ptr<Diskstream> > _diskstreams_2X;
|
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; }
|
virtual bool can_use_mode (TrackMode /*m*/, bool& /*bounce_required*/) { return false; }
|
||||||
PBD::Signal0<void> TrackModeChanged;
|
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,
|
virtual int no_roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame,
|
||||||
bool state_changing, bool can_record);
|
bool state_changing, bool can_record);
|
||||||
|
|
||||||
|
|
@ -164,6 +168,7 @@ class Track : public Route, public PublicDiskstream
|
||||||
MeterPoint _saved_meter_point;
|
MeterPoint _saved_meter_point;
|
||||||
TrackMode _mode;
|
TrackMode _mode;
|
||||||
bool _needs_butler;
|
bool _needs_butler;
|
||||||
|
MonitorChoice _monitoring;
|
||||||
|
|
||||||
//private: (FIXME)
|
//private: (FIXME)
|
||||||
struct FreezeRecordProcessorInfo {
|
struct FreezeRecordProcessorInfo {
|
||||||
|
|
|
||||||
|
|
@ -358,6 +358,13 @@ namespace ARDOUR {
|
||||||
ExternalMonitoring
|
ExternalMonitoring
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum MonitorChoice {
|
||||||
|
MonitorAuto = 0,
|
||||||
|
MonitorInput = 0x1,
|
||||||
|
MonitorDisk = 0x2,
|
||||||
|
MonitorCue = 0x4,
|
||||||
|
};
|
||||||
|
|
||||||
enum PFLPosition {
|
enum PFLPosition {
|
||||||
/** PFL signals come from before pre-fader processors */
|
/** PFL signals come from before pre-fader processors */
|
||||||
PFLFromBeforeProcessors,
|
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);
|
_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,
|
/* not actually recording, but we want to hear the input material anyway,
|
||||||
at least potentially (depending on monitoring options)
|
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);
|
passthru (start_frame, end_frame, nframes, false);
|
||||||
|
|
||||||
} else if ((b = diskstream->playback_buffer(0)) != 0) {
|
} else if ((b = diskstream->playback_buffer(0)) != 0) {
|
||||||
|
|
@ -734,3 +738,5 @@ AudioTrack::bounceable () const
|
||||||
{
|
{
|
||||||
return n_inputs().n_audio() >= n_outputs().n_audio();
|
return n_inputs().n_audio() >= n_outputs().n_audio();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -66,6 +66,7 @@ setup_enum_writer ()
|
||||||
RegionPoint _RegionPoint;
|
RegionPoint _RegionPoint;
|
||||||
Placement _Placement;
|
Placement _Placement;
|
||||||
MonitorModel _MonitorModel;
|
MonitorModel _MonitorModel;
|
||||||
|
MonitorChoice _MonitorChoice;
|
||||||
PFLPosition _PFLPosition;
|
PFLPosition _PFLPosition;
|
||||||
AFLPosition _AFLPosition;
|
AFLPosition _AFLPosition;
|
||||||
RemoteModel _RemoteModel;
|
RemoteModel _RemoteModel;
|
||||||
|
|
@ -228,6 +229,12 @@ setup_enum_writer ()
|
||||||
REGISTER_ENUM (ExternalMonitoring);
|
REGISTER_ENUM (ExternalMonitoring);
|
||||||
REGISTER (_MonitorModel);
|
REGISTER (_MonitorModel);
|
||||||
|
|
||||||
|
REGISTER_ENUM (MonitorInput);
|
||||||
|
REGISTER_ENUM (MonitorDisk);
|
||||||
|
REGISTER_ENUM (MonitorAuto);
|
||||||
|
REGISTER_ENUM (MonitorCue);
|
||||||
|
REGISTER_BITS (_MonitorChoice);
|
||||||
|
|
||||||
REGISTER_ENUM (PFLFromBeforeProcessors);
|
REGISTER_ENUM (PFLFromBeforeProcessors);
|
||||||
REGISTER_ENUM (PFLFromAfterProcessors);
|
REGISTER_ENUM (PFLFromAfterProcessors);
|
||||||
REGISTER (_PFLPosition);
|
REGISTER (_PFLPosition);
|
||||||
|
|
|
||||||
|
|
@ -32,16 +32,25 @@ using namespace PBD;
|
||||||
using namespace ARDOUR;
|
using namespace ARDOUR;
|
||||||
using namespace Glib;
|
using namespace Glib;
|
||||||
|
|
||||||
SessionEvent*
|
void
|
||||||
Session::get_rt_event (boost::shared_ptr<RouteList> rl, bool yn, SessionEvent::RTeventCallback after, bool group_override,
|
Session::set_monitoring (boost::shared_ptr<RouteList> rl, MonitorChoice mc, SessionEvent::RTeventCallback after, bool group_override)
|
||||||
void (Session::*method) (boost::shared_ptr<RouteList>, bool, bool))
|
|
||||||
{
|
{
|
||||||
SessionEvent* ev = new SessionEvent (SessionEvent::RealTimeOperation, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
|
queue_event (get_rt_event (rl, mc, after, group_override, &Session::rt_set_monitoring));
|
||||||
ev->rt_slot = boost::bind (method, this, rl, yn, group_override);
|
}
|
||||||
ev->rt_return = after;
|
|
||||||
ev->event_loop = EventLoop::get_event_loop_for_thread ();
|
|
||||||
|
|
||||||
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
|
void
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,7 @@ Track::Track (Session& sess, string name, Route::Flag flag, TrackMode mode, Data
|
||||||
: Route (sess, name, flag, default_type)
|
: Route (sess, name, flag, default_type)
|
||||||
, _saved_meter_point (_meter_point)
|
, _saved_meter_point (_meter_point)
|
||||||
, _mode (mode)
|
, _mode (mode)
|
||||||
|
, _monitoring (MonitorAuto)
|
||||||
, _rec_enable_control (new RecEnableControllable(*this))
|
, _rec_enable_control (new RecEnableControllable(*this))
|
||||||
{
|
{
|
||||||
_freeze_record.state = NoFreeze;
|
_freeze_record.state = NoFreeze;
|
||||||
|
|
@ -640,36 +641,31 @@ Track::adjust_capture_buffering ()
|
||||||
bool
|
bool
|
||||||
Track::send_silence () const
|
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;
|
bool send_silence;
|
||||||
|
|
||||||
if (!Config->get_tape_machine_mode()) {
|
if (Config->get_tape_machine_mode()) {
|
||||||
/*
|
|
||||||
ADATs work in a strange way..
|
/* ADATs work in a strange way..
|
||||||
they monitor input always when stopped.and auto-input is engaged.
|
they monitor input always when stopped.and auto-input is engaged.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if ((Config->get_monitoring_model() == SoftwareMonitoring)
|
if ((Config->get_monitoring_model() == SoftwareMonitoring)
|
||||||
&& (_session.config.get_auto_input () || _diskstream->record_enabled())) {
|
&& ((_monitoring & MonitorInput) || (_diskstream->record_enabled()))) {
|
||||||
send_silence = false;
|
send_silence = false;
|
||||||
} else {
|
} else {
|
||||||
send_silence = true;
|
send_silence = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
/*
|
|
||||||
Other machines switch to input on stop if the track is record enabled,
|
/* Other machines switch to input on stop if the track is record enabled,
|
||||||
regardless of the auto input setting (auto input only changes the
|
regardless of the auto input setting (auto input only changes the
|
||||||
monitoring state when the transport is rolling)
|
monitoring state when the transport is rolling)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if ((Config->get_monitoring_model() == SoftwareMonitoring)
|
if ((Config->get_monitoring_model() == SoftwareMonitoring)
|
||||||
&& _diskstream->record_enabled()) {
|
&& (!(_monitoring & MonitorDisk) && (_session.config.get_auto_input () || _diskstream->record_enabled()))) {
|
||||||
send_silence = false;
|
send_silence = false;
|
||||||
} else {
|
} else {
|
||||||
send_silence = true;
|
send_silence = true;
|
||||||
|
|
@ -735,3 +731,11 @@ 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 */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue