fix monitoring so that MIDI tracks don't work the same way as audio (basically, they are always in "ardour does monitoring" mode

git-svn-id: svn://localhost/ardour2/branches/3.0@9081 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
Paul Davis 2011-03-05 23:16:32 +00:00
parent faeeb29202
commit 5999bd56da
12 changed files with 121 additions and 149 deletions

View File

@ -113,8 +113,10 @@ protected:
XMLNode& state (bool full);
int _set_state (const XMLNode&, int, bool call_base);
bool should_monitor () const;
bool send_silence () const;
private:
private:
boost::shared_ptr<MidiDiskstream> midi_diskstream () const;
void write_out_of_band_data (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, framecnt_t nframes);

View File

@ -480,7 +480,9 @@ class Route : public SessionObject, public Automatable, public RouteGroupMember,
uint32_t pans_required() const;
ChanCount n_process_buffers ();
virtual bool should_monitor () const;
virtual int _set_state (const XMLNode&, int, bool call_base);
boost::shared_ptr<Amp> _amp;

View File

@ -1486,6 +1486,8 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
void start_time_changed (framepos_t);
void end_time_changed (framepos_t);
void set_track_monitor_input_status (bool);
boost::shared_ptr<Speakers> _speakers;
};

View File

@ -202,6 +202,8 @@ class Track : public Route, public PublicDiskstream
XMLNode* pending_state;
bool _destructive;
virtual bool send_silence () const;
boost::shared_ptr<RecEnableControllable> _rec_enable_control;
private:

View File

@ -1200,12 +1200,6 @@ void
MidiDiskstream::disengage_record_enable ()
{
g_atomic_int_set (&_record_enabled, 0);
if (_source_port && Config->get_monitoring_model() == HardwareMonitoring) {
if (_source_port) {
_source_port->request_monitor_input (false);
}
}
RecordEnableChanged (); /* EMIT SIGNAL */
}

View File

@ -655,3 +655,14 @@ MidiTrack::diskstream_data_recorded (boost::shared_ptr<MidiBuffer> buf, boost::w
DataRecorded (buf, src); /* EMIT SIGNAL */
}
bool
MidiTrack::should_monitor () const
{
return true;
}
bool
MidiTrack::send_silence () const
{
return false;
}

View File

@ -166,12 +166,6 @@ Route::init ()
*/
_monitor_control.reset (new MonitorProcessor (_session));
_monitor_control->activate ();
/* no panning on the monitor main outs */
#ifdef PANNER_HACKS
_main_outs->panner()->set_bypassed (true);
#endif
}
if (is_master() || is_monitor() || is_hidden()) {
@ -401,18 +395,14 @@ Route::process_output_buffers (BufferSet& bufs,
bool /*with_processors*/, int declick,
bool gain_automation_ok)
{
bool monitor;
bool monitor = should_monitor ();
cerr << name() << " will monitor ? " << monitor << endl;
bufs.is_silent (false);
switch (Config->get_monitoring_model()) {
case HardwareMonitoring:
case ExternalMonitoring:
monitor = !record_enabled() || (_session.config.get_auto_input() && !_session.actively_recording());
break;
default:
monitor = true;
}
cerr << name() << " POB, should declick ? " << declick << endl;
declick = 0;
if (!declick) {
declick = _pending_declick;
@ -2694,7 +2684,7 @@ void
Route::nonrealtime_handle_transport_stopped (bool /*abort_ignored*/, bool did_locate, bool can_flush_processors)
{
framepos_t now = _session.transport_frame();
{
Glib::RWLock::ReaderLock lm (_processor_lock);
@ -3810,3 +3800,19 @@ Route::setup_invisible_processors ()
DEBUG_TRACE (DEBUG::Processors, string_compose ("\t%1\n", (*i)->name ()));
}
}
bool
Route::should_monitor () const
{
switch (Config->get_monitoring_model()) {
case HardwareMonitoring:
case ExternalMonitoring:
return !record_enabled() || (_session.config.get_auto_input() && !_session.actively_recording());
break;
default:
break;
}
return true;
}

View File

@ -777,30 +777,26 @@ Session::record_enabling_legal () const
return true;
}
void
Session::set_track_monitor_input_status (bool yn)
{
boost::shared_ptr<RouteList> rl = routes.reader ();
for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
boost::shared_ptr<AudioTrack> tr = boost::dynamic_pointer_cast<AudioTrack> (*i);
if (tr && tr->record_enabled ()) {
//cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
tr->monitor_input (yn);
}
}
}
void
Session::reset_input_monitor_state ()
{
if (transport_rolling()) {
boost::shared_ptr<RouteList> rl = routes.reader ();
for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
if (tr && tr->record_enabled ()) {
//cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
tr->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !config.get_auto_input());
}
}
set_track_monitor_input_status (Config->get_monitoring_model() == HardwareMonitoring && !config.get_auto_input());
} else {
boost::shared_ptr<RouteList> rl = routes.reader ();
for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
if (tr && tr->record_enabled ()) {
//cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
tr->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
}
}
set_track_monitor_input_status (Config->get_monitoring_model() == HardwareMonitoring);
}
}
@ -1011,14 +1007,7 @@ Session::enable_record ()
MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdRecordStrobe));
if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
boost::shared_ptr<RouteList> rl = routes.reader ();
for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
if (tr && tr->record_enabled ()) {
tr->monitor_input (true);
}
}
set_track_monitor_input_status (true);
}
RecordStateChanged ();
@ -1044,14 +1033,7 @@ Session::disable_record (bool rt_context, bool force)
}
if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
boost::shared_ptr<RouteList> rl = routes.reader ();
for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
if (tr && tr->record_enabled ()) {
tr->monitor_input (false);
}
}
set_track_monitor_input_status (false);
}
RecordStateChanged (); /* emit signal */
@ -1068,14 +1050,7 @@ Session::step_back_from_record ()
if (g_atomic_int_compare_and_exchange (&_record_status, Recording, Enabled)) {
if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
boost::shared_ptr<RouteList> rl = routes.reader ();
for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
if (tr && tr->record_enabled ()) {
//cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
tr->monitor_input (false);
}
}
set_track_monitor_input_status (false);
}
}
}

View File

@ -436,7 +436,6 @@ Session::process_with_events (pframes_t nframes)
/* this is necessary to handle the case of seamless looping */
end_frame = _transport_frame + floor (nframes * _transport_speed);
}
set_next_event ();

View File

@ -3300,14 +3300,7 @@ Session::config_changed (std::string p, bool ours)
if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
/* auto-input only makes a difference if we're rolling */
boost::shared_ptr<RouteList> rl = routes.reader ();
for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
if (tr && tr->record_enabled ()) {
tr->monitor_input (!config.get_auto_input());
}
}
set_track_monitor_input_status (!config.get_auto_input());
}
} else if (p == "punch-in") {

View File

@ -819,13 +819,6 @@ Session::locate (framepos_t target_frame, bool with_roll, bool with_flush, bool
return;
}
// Update Timecode time
// [DR] FIXME: find out exactly where this should go below
_transport_frame = target_frame;
timecode_time(_transport_frame, transmitting_timecode_time);
outbound_mtc_timecode_frame = _transport_frame;
next_quarter_frame_to_send = 0;
if (_transport_speed && (!with_loop || loop_changing)) {
/* schedule a declick. we'll be called again when its done */
@ -838,6 +831,13 @@ Session::locate (framepos_t target_frame, bool with_roll, bool with_flush, bool
}
}
// Update Timecode time
// [DR] FIXME: find out exactly where this should go below
_transport_frame = target_frame;
timecode_time(_transport_frame, transmitting_timecode_time);
outbound_mtc_timecode_frame = _transport_frame;
next_quarter_frame_to_send = 0;
if (transport_rolling() && (!auto_play_legal || !config.get_auto_play()) && !with_roll && !(synced_to_jack() && play_loop)) {
realtime_stop (false, true); // XXX paul - check if the 2nd arg is really correct
}
@ -872,28 +872,12 @@ Session::locate (framepos_t target_frame, bool with_roll, bool with_flush, bool
if (with_roll) {
/* switch from input if we're going to roll */
if (Config->get_monitoring_model() == HardwareMonitoring) {
boost::shared_ptr<RouteList> rl = routes.reader();
for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
if (tr && tr->record_enabled ()) {
//cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
tr->monitor_input (!config.get_auto_input());
}
}
set_track_monitor_input_status (!config.get_auto_input());
}
} else {
/* otherwise we're going to stop, so do the opposite */
if (Config->get_monitoring_model() == HardwareMonitoring) {
boost::shared_ptr<RouteList> rl = routes.reader();
for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
if (tr && tr->record_enabled ()) {
//cerr << "switching to input" << __FILE__ << __LINE__ << endl << endl;
tr->monitor_input (true);
}
}
set_track_monitor_input_status (true);
}
}
@ -963,17 +947,8 @@ Session::set_transport_speed (double speed, bool abort, bool clear_state)
/* we are rolling and we want to stop */
if (Config->get_monitoring_model() == HardwareMonitoring)
{
boost::shared_ptr<RouteList> rl = routes.reader();
for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
if (tr && tr->record_enabled ()) {
//cerr << "switching to input" << __FILE__ << __LINE__ << endl << endl;
tr->monitor_input (true);
}
}
if (Config->get_monitoring_model() == HardwareMonitoring) {
set_track_monitor_input_status (true);
}
if (synced_to_jack ()) {
@ -995,16 +970,8 @@ Session::set_transport_speed (double speed, bool abort, bool clear_state)
/* we are stopped and we want to start rolling at speed 1 */
if (Config->get_monitoring_model() == HardwareMonitoring) {
boost::shared_ptr<RouteList> rl = routes.reader();
for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
if (config.get_auto_input() && tr && tr->record_enabled ()) {
//cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
tr->monitor_input (false);
}
}
if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
set_track_monitor_input_status (false);
}
if (synced_to_jack()) {

View File

@ -270,44 +270,21 @@ Track::no_roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame,
_diskstream->check_record_status (start_frame, can_record);
bool send_silence;
bool be_silent;
if (_have_internal_generator) {
/* since the instrument has no input streams,
there is no reason to send any signal
into the route.
*/
send_silence = true;
be_silent = true;
} else {
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;
} 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)
*/
if ((Config->get_monitoring_model() == SoftwareMonitoring)
&& _diskstream->record_enabled()) {
send_silence = false;
} else {
send_silence = true;
}
}
be_silent = send_silence ();
}
_amp->apply_gain_automation(false);
if (send_silence) {
if (be_silent) {
/* if we're sending silence, but we want the meters to show levels for the signal,
meter right here.
@ -671,3 +648,45 @@ Track::adjust_capture_buffering ()
_diskstream->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_monitoring_model() == SoftwareMonitoring)
&& (_session.config.get_auto_input () || _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)
*/
if ((Config->get_monitoring_model() == SoftwareMonitoring)
&& _diskstream->record_enabled()) {
send_silence = false;
} else {
send_silence = true;
}
}
return send_silence;
}